eric-6.0.8/0000755000175000017500000000000012557365406011540 5ustar piotrpiotreric-6.0.8/patch_modpython.py0000644000175000017500000001103312557365403015305 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003-2015 Detlev Offenbach # # This is a script to patch mod_python for eric6. """ Script to patch mod_python for usage with the eric6 IDE. """ from __future__ import unicode_literals import sys import os import shutil import py_compile import distutils.sysconfig # Define the globals. progName = None modDir = None def usage(rcode=2): """ Display a usage message and exit. @param rcode return code passed back to the calling process (integer) """ global progName, modDir print("Usage:") print(" {0} [-h] [-d dir]".format(progName)) print("where:") print(" -h display this help message") print(" -d dir where Mod_python files are installed" " [default {0}]".format(modDir)) print() print("This script patches the file apache.py of the Mod_python" " distribution") print("so that it will work with the eric6 debugger instead of pdb.") print("Please see mod_python.html for more details.") print() sys.exit(rcode) def initGlobals(): """ Module function to set the values of globals that need more than a simple assignment. """ global modDir modDir = os.path.join(distutils.sysconfig.get_python_lib(True), "mod_python") def main(argv): """ The main function of the script. @param argv list of command line arguments (list of strings) """ import getopt # Parse the command line. global progName, modDir progName = os.path.basename(argv[0]) initGlobals() try: optlist, args = getopt.getopt(argv[1:], "hd:") except getopt.GetoptError: usage() for opt, arg in optlist: if opt == "-h": usage(0) elif opt == "-d": global modDir modDir = arg try: filename = os.path.join(modDir, "apache.py") f = open(filename, "r", encoding="utf-8") except EnvironmentError: print("The file {0} does not exist. Aborting.".format(filename)) sys.exit(1) lines = f.readlines() f.close() pdbFound = False ericFound = False sn = "apache.py" s = open(sn, "w", encoding="utf-8") for line in lines: if not pdbFound and line.startswith("import pdb"): s.write("import eric6.DebugClients.Python.eric6dbgstub as pdb\n") pdbFound = True else: s.write(line) if line.startswith("import eric6"): ericFound = True if not ericFound: s.write("\n") s.write('def initDebugger(name):\n') s.write(' """\n') s.write(' Initialize the debugger and set the script name to be' ' reported \n') s.write(' by the debugger. This is a patch for eric6.\n') s.write(' """\n') s.write(' if not pdb.initDebugger("standard"):\n') s.write(' raise ImportError("Could not initialize debugger")\n') s.write(' pdb.setScriptname(name)\n') s.write("\n") s.close() if ericFound: print("Mod_python is already patched for eric6.") os.remove(sn) else: try: py_compile.compile(sn) except py_compile.PyCompileError as e: print("Error compiling {0}. Aborting".format(sn)) print(e) os.remove(sn) sys.exit(1) except SyntaxError as e: print("Error compiling {0}. Aborting".format(sn)) print(e) os.remove(sn) sys.exit(1) shutil.copy(os.path.join(modDir, "apache.py"), os.path.join(modDir, "apache.py.orig")) shutil.copy(sn, modDir) os.remove(sn) if os.path.exists("{0}c".format(sn)): shutil.copy("{0}c".format(sn), modDir) os.remove("{0}c".format(sn)) if os.path.exists("{0}o".format(sn)): shutil.copy("{0}o".format(sn), modDir) os.remove("{0}o".format(sn)) print("Mod_python patched successfully.") print("Unpatched file copied to {0}.".format( os.path.join(modDir, "apache.py.orig"))) if __name__ == "__main__": try: main(sys.argv) except SystemExit: raise except: print("""An internal error occured. Please report all the output of""" """ the program,\nincluding the following traceback, to""" """ eric-bugs@die-offenbachs.de.\n""") raise eric-6.0.8/eric/0000755000175000017500000000000012557365404012460 5ustar piotrpiotreric-6.0.8/eric/ViewManager/0000755000175000017500000000000012557365404014665 5ustar piotrpiotreric-6.0.8/eric/ViewManager/BookmarkedFilesDialog.py0000644000175000017500000001423512451233370021412 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a configuration dialog for the bookmarked files menu. """ from __future__ import unicode_literals from PyQt5.QtCore import QFileInfo, Qt, pyqtSlot from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QListWidgetItem, QDialog from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .Ui_BookmarkedFilesDialog import Ui_BookmarkedFilesDialog import Utilities import UI.PixmapCache class BookmarkedFilesDialog(QDialog, Ui_BookmarkedFilesDialog): """ Class implementing a configuration dialog for the bookmarked files menu. """ def __init__(self, bookmarks, parent=None): """ Constructor @param bookmarks list of bookmarked files (list of strings) @param parent parent widget (QWidget) """ super(BookmarkedFilesDialog, self).__init__(parent) self.setupUi(self) self.fileButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.fileCompleter = E5FileCompleter(self.fileEdit) self.bookmarks = bookmarks[:] for bookmark in self.bookmarks: itm = QListWidgetItem(bookmark, self.filesList) if not QFileInfo(bookmark).exists(): itm.setBackground(QColor(Qt.red)) if len(self.bookmarks): self.filesList.setCurrentRow(0) def on_fileEdit_textChanged(self, txt): """ Private slot to handle the textChanged signal of the file edit. @param txt the text of the file edit (string) """ self.addButton.setEnabled(txt != "") self.changeButton.setEnabled( txt != "" and self.filesList.currentRow() != -1) def on_filesList_currentRowChanged(self, row): """ Private slot to set the lineedit depending on the selected entry. @param row the current row (integer) """ if row == -1: self.fileEdit.clear() self.downButton.setEnabled(False) self.upButton.setEnabled(False) self.deleteButton.setEnabled(False) self.changeButton.setEnabled(False) else: maxIndex = len(self.bookmarks) - 1 self.upButton.setEnabled(row != 0) self.downButton.setEnabled(row != maxIndex) self.deleteButton.setEnabled(True) self.changeButton.setEnabled(True) bookmark = self.bookmarks[row] self.fileEdit.setText(bookmark) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add a new entry. """ bookmark = self.fileEdit.text() if bookmark: bookmark = Utilities.toNativeSeparators(bookmark) itm = QListWidgetItem(bookmark, self.filesList) if not QFileInfo(bookmark).exists(): itm.setBackground(QColor(Qt.red)) self.fileEdit.clear() self.bookmarks.append(bookmark) row = self.filesList.currentRow() self.on_filesList_currentRowChanged(row) @pyqtSlot() def on_changeButton_clicked(self): """ Private slot to change an entry. """ row = self.filesList.currentRow() bookmark = self.fileEdit.text() bookmark = Utilities.toNativeSeparators(bookmark) self.bookmarks[row] = bookmark itm = self.filesList.item(row) itm.setText(bookmark) if not QFileInfo(bookmark).exists(): itm.setBackground(QColor(Qt.red)) else: itm.setBackground(QColor()) @pyqtSlot() def on_deleteButton_clicked(self): """ Private slot to delete the selected entry. """ row = self.filesList.currentRow() itm = self.filesList.takeItem(row) del itm del self.bookmarks[row] row = self.filesList.currentRow() self.on_filesList_currentRowChanged(row) @pyqtSlot() def on_downButton_clicked(self): """ Private slot to move an entry down in the list. """ rows = self.filesList.count() row = self.filesList.currentRow() if row == rows - 1: # we're already at the end return self.__swap(row, row + 1) itm = self.filesList.takeItem(row) self.filesList.insertItem(row + 1, itm) self.filesList.setCurrentItem(itm) self.upButton.setEnabled(True) if row == rows - 2: self.downButton.setEnabled(False) else: self.downButton.setEnabled(True) @pyqtSlot() def on_upButton_clicked(self): """ Private slot to move an entry up in the list. """ row = self.filesList.currentRow() if row == 0: # we're already at the top return self.__swap(row - 1, row) itm = self.filesList.takeItem(row) self.filesList.insertItem(row - 1, itm) self.filesList.setCurrentItem(itm) if row == 1: self.upButton.setEnabled(False) else: self.upButton.setEnabled(True) self.downButton.setEnabled(True) @pyqtSlot() def on_fileButton_clicked(self): """ Private slot to handle the file selection via a file selection dialog. """ bookmark = E5FileDialog.getOpenFileName() if bookmark: bookmark = Utilities.toNativeSeparators(bookmark) self.fileEdit.setText(bookmark) def getBookmarkedFiles(self): """ Public method to retrieve the tools list. @return a list of filenames (list of strings) """ return self.bookmarks def __swap(self, itm1, itm2): """ Private method used two swap two list entries given by their index. @param itm1 index of first entry (int) @param itm2 index of second entry (int) """ tmp = self.bookmarks[itm1] self.bookmarks[itm1] = self.bookmarks[itm2] self.bookmarks[itm2] = tmp eric-6.0.8/eric/ViewManager/ViewManager.py0000644000175000017500000104703312475652460017454 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the viewmanager base class. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal, QSignalMapper, QTimer, \ QFileInfo, QRegExp, QObject, Qt, QCoreApplication from PyQt5.QtGui import QColor, QKeySequence, QPalette, QPixmap from PyQt5.QtWidgets import QLineEdit, QToolBar, QWidgetAction, QDialog, \ QApplication, QMenu, QComboBox from PyQt5.Qsci import QsciScintilla from E5Gui.E5Application import e5App from E5Gui import E5FileDialog, E5MessageBox from Globals import recentNameFiles, isMacPlatform import Preferences from QScintilla.Editor import Editor import Utilities import UI.PixmapCache import UI.Config from E5Gui.E5Action import E5Action, createActionGroup class QuickSearchLineEdit(QLineEdit): """ Class implementing a line edit that reacts to newline and cancel commands. @signal escPressed() emitted after the cancel command was activated @signal returnPressed() emitted after a newline command was activated @signal gotFocus() emitted when the focus is changed to this widget """ escPressed = pyqtSignal() gotFocus = pyqtSignal() def editorCommand(self, cmd): """ Public method to perform an editor command. @param cmd the scintilla command to be performed """ if cmd == QsciScintilla.SCI_NEWLINE: cb = self.parent() hasEntry = cb.findText(self.text()) != -1 if not hasEntry: if cb.insertPolicy() == QComboBox.InsertAtTop: cb.insertItem(0, self.text()) else: cb.addItem(self.text()) self.returnPressed.emit() elif cmd == QsciScintilla.SCI_CANCEL: self.escPressed.emit() def keyPressEvent(self, evt): """ Protected method to handle the press of the ESC key. @param evt key event (QKeyPressEvent) """ if evt.key() == Qt.Key_Escape: self.escPressed.emit() else: super(QuickSearchLineEdit, self).keyPressEvent(evt) # pass it on def focusInEvent(self, evt): """ Protected method to record the current editor widget. @param evt focus event (QFocusEvent) """ self.gotFocus.emit() super(QuickSearchLineEdit, self).focusInEvent(evt) # pass it on class ViewManager(QObject): """ Base class inherited by all specific viewmanager classes. It defines the interface to be implemented by specific viewmanager classes and all common methods. @signal changeCaption(str) emitted if a change of the caption is necessary @signal editorChanged(str) emitted when the current editor has changed @signal editorChangedEd(Editor) emitted when the current editor has changed @signal lastEditorClosed() emitted after the last editor window was closed @signal editorOpened(str) emitted after an editor window was opened @signal editorOpenedEd(Editor) emitted after an editor window was opened @signal editorClosed(str) emitted just before an editor window gets closed @signal editorClosedEd(Editor) emitted just before an editor window gets closed @signal editorRenamed(str) emitted after an editor was renamed @signal editorRenamedEd(Editor) emitted after an editor was renamed @signal editorSaved(str) emitted after an editor window was saved @signal editorSavedEd(Editor) emitted after an editor window was saved @signal checkActions(Editor) emitted when some actions should be checked for their status @signal cursorChanged(Editor) emitted after the cursor position of the active window has changed @signal breakpointToggled(Editor) emitted when a breakpoint is toggled @signal bookmarkToggled(Editor) emitted when a bookmark is toggled @signal syntaxerrorToggled(Editor) emitted when a syntax error is toggled @signal previewStateChanged(bool) emitted to signal a change in the preview state @signal editorLanguageChanged(Editor) emitted to signal a change of an editor's language @signal editorTextChanged(Editor) emitted to signal a change of an editor's text @signal editorLineChanged(str,int) emitted to signal a change of an editor's current line (line is given one based) """ changeCaption = pyqtSignal(str) editorChanged = pyqtSignal(str) editorChangedEd = pyqtSignal(Editor) lastEditorClosed = pyqtSignal() editorOpened = pyqtSignal(str) editorOpenedEd = pyqtSignal(Editor) editorClosed = pyqtSignal(str) editorClosedEd = pyqtSignal(Editor) editorRenamed = pyqtSignal(str) editorRenamedEd = pyqtSignal(Editor) editorSaved = pyqtSignal(str) editorSavedEd = pyqtSignal(Editor) checkActions = pyqtSignal(Editor) cursorChanged = pyqtSignal(Editor) breakpointToggled = pyqtSignal(Editor) bookmarkToggled = pyqtSignal(Editor) syntaxerrorToggled = pyqtSignal(Editor) previewStateChanged = pyqtSignal(bool) editorLanguageChanged = pyqtSignal(Editor) editorTextChanged = pyqtSignal(Editor) editorLineChanged = pyqtSignal(str, int) def __init__(self): """ Constructor """ super(ViewManager, self).__init__() # initialize the instance variables self.editors = [] self.currentEditor = None self.untitledCount = 0 self.srHistory = { "search": [], "replace": [] } self.editorsCheckFocusIn = True self.recent = [] self.__loadRecent() self.bookmarked = [] bs = Preferences.Prefs.settings.value("Bookmarked/Sources") if bs is not None: self.bookmarked = bs # initialize the autosave timer self.autosaveInterval = Preferences.getEditor("AutosaveInterval") self.autosaveTimer = QTimer(self) self.autosaveTimer.setObjectName("AutosaveTimer") self.autosaveTimer.setSingleShot(True) self.autosaveTimer.timeout.connect(self.__autosave) # initialize the APIs manager from QScintilla.APIsManager import APIsManager self.apisManager = APIsManager(parent=self) self.__cooperationClient = None self.__lastFocusWidget = None def setReferences(self, ui, dbs): """ Public method to set some references needed later on. @param ui reference to the main user interface @param dbs reference to the debug server object """ from QScintilla.SearchReplaceWidget import SearchReplaceSlidingWidget self.ui = ui self.dbs = dbs self.__searchWidget = SearchReplaceSlidingWidget(False, self, ui) self.__replaceWidget = SearchReplaceSlidingWidget(True, self, ui) self.checkActions.connect(self.__searchWidget.updateSelectionCheckBox) self.checkActions.connect(self.__replaceWidget.updateSelectionCheckBox) def searchWidget(self): """ Public method to get a reference to the search widget. @return reference to the search widget (SearchReplaceSlidingWidget) """ return self.__searchWidget def replaceWidget(self): """ Public method to get a reference to the replace widget. @return reference to the replace widget (SearchReplaceSlidingWidget) """ return self.__replaceWidget def __loadRecent(self): """ Private method to load the recently opened filenames. """ self.recent = [] Preferences.Prefs.rsettings.sync() rs = Preferences.Prefs.rsettings.value(recentNameFiles) if rs is not None: for f in Preferences.toList(rs): if QFileInfo(f).exists(): self.recent.append(f) def __saveRecent(self): """ Private method to save the list of recently opened filenames. """ Preferences.Prefs.rsettings.setValue(recentNameFiles, self.recent) Preferences.Prefs.rsettings.sync() def getMostRecent(self): """ Public method to get the most recently opened file. @return path of the most recently opened file (string) """ if len(self.recent): return self.recent[0] else: return None def setSbInfo(self, sbLine, sbPos, sbWritable, sbEncoding, sbLanguage, sbEol, sbZoom): """ Public method to transfer statusbar info from the user interface to viewmanager. @param sbLine reference to the line number part of the statusbar (QLabel) @param sbPos reference to the character position part of the statusbar (QLabel) @param sbWritable reference to the writability indicator part of the statusbar (QLabel) @param sbEncoding reference to the encoding indicator part of the statusbar (QLabel) @param sbLanguage reference to the language indicator part of the statusbar (QLabel) @param sbEol reference to the eol indicator part of the statusbar (QLabel) @param sbZoom reference to the zoom widget (E5ZoomWidget) """ self.sbLine = sbLine self.sbPos = sbPos self.sbWritable = sbWritable self.sbEnc = sbEncoding self.sbLang = sbLanguage self.sbEol = sbEol self.sbZoom = sbZoom self.sbZoom.valueChanged.connect(self.__zoomTo) self.__setSbFile(zoom=0) self.sbLang.clicked.connect(self.__showLanguagesMenu) self.sbEol.clicked.connect(self.__showEolMenu) self.sbEnc.clicked.connect(self.__showEncodingsMenu) ################################################################## ## Below are menu handling methods for status bar labels ################################################################## def __showLanguagesMenu(self, pos): """ Private slot to show the Languages menu of the current editor. @param pos position the menu should be shown at (QPoint) """ aw = self.activeWindow() if aw is not None: menu = aw.getMenu("Languages") if menu is not None: menu.exec_(pos) def __showEolMenu(self, pos): """ Private slot to show the EOL menu of the current editor. @param pos position the menu should be shown at (QPoint) """ aw = self.activeWindow() if aw is not None: menu = aw.getMenu("Eol") if menu is not None: menu.exec_(pos) def __showEncodingsMenu(self, pos): """ Private slot to show the Encodings menu of the current editor. @param pos position the menu should be shown at (QPoint) """ aw = self.activeWindow() if aw is not None: menu = aw.getMenu("Encodings") if menu is not None: menu.exec_(pos) ########################################################################### ## methods below need to be implemented by a subclass ########################################################################### def canCascade(self): """ Public method to signal if cascading of managed windows is available. @ireturn flag indicating cascading of windows is available @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def canTile(self): """ Public method to signal if tiling of managed windows is available. @ireturn flag indicating tiling of windows is available @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def tile(self): """ Public method to tile the managed windows. @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def cascade(self): """ Public method to cascade the managed windows. @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def activeWindow(self): """ Public method to return the active (i.e. current) window. @ireturn reference to the active editor @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def _removeAllViews(self): """ Protected method to remove all views (i.e. windows). @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def _removeView(self, win): """ Protected method to remove a view (i.e. window). @param win editor window to be removed @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def _addView(self, win, fn=None, noName=""): """ Protected method to add a view (i.e. window). @param win editor assembly to be added @param fn filename of this editor @param noName name to be used for an unnamed editor (string) @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def _showView(self, win, fn=None): """ Protected method to show a view (i.e. window). @param win editor assembly to be shown @param fn filename of this editor @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def showWindowMenu(self, windowMenu): """ Public method to set up the viewmanager part of the Window menu. @param windowMenu reference to the window menu @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def _initWindowActions(self): """ Protected method to define the user interface actions for window handling. @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def setEditorName(self, editor, newName): """ Public method to change the displayed name of the editor. @param editor editor window to be changed @param newName new name to be shown (string) @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') def _modificationStatusChanged(self, m, editor): """ Protected slot to handle the modificationStatusChanged signal. @param m flag indicating the modification status (boolean) @param editor editor window changed @exception RuntimeError Not implemented """ raise RuntimeError('Not implemented') ##################################################################### ## methods above need to be implemented by a subclass ##################################################################### def canSplit(self): """ Public method to signal if splitting of the view is available. @return flag indicating splitting of the view is available. """ return False def addSplit(self): """ Public method used to split the current view. """ pass def removeSplit(self): """ Public method used to remove the current split view. @return Flag indicating successful deletion """ return False def getSplitOrientation(self): """ Public method to get the orientation of the split view. @return orientation of the split (Qt.Horizontal or Qt.Vertical) """ return Qt.Vertical def setSplitOrientation(self, orientation): """ Public method used to set the orientation of the split view. @param orientation orientation of the split (Qt.Horizontal or Qt.Vertical) """ pass def nextSplit(self): """ Public slot used to move to the next split. """ pass def prevSplit(self): """ Public slot used to move to the previous split. """ pass def eventFilter(self, object, event): """ Public method called to filter an event. @param object object, that generated the event (QObject) @param event the event, that was generated by object (QEvent) @return flag indicating if event was filtered out """ return False ##################################################################### ## methods above need to be implemented by a subclass, that supports ## splitting of the viewmanager area. ##################################################################### def initActions(self): """ Public method defining the user interface actions. """ # list containing all edit actions self.editActions = [] # list containing all file actions self.fileActions = [] # list containing all search actions self.searchActions = [] # list containing all view actions self.viewActions = [] # list containing all window actions self.windowActions = [] # list containing all macro actions self.macroActions = [] # list containing all bookmark actions self.bookmarkActions = [] # list containing all spell checking actions self.spellingActions = [] self.__actions = { "bookmark": self.bookmarkActions, "edit": self.editActions, "file": self.fileActions, "macro": self.macroActions, "search": self.searchActions, "spelling": self.spellingActions, "view": self.viewActions, "window": self.windowActions, } self._initWindowActions() self.__initFileActions() self.__initEditActions() self.__initSearchActions() self.__initViewActions() self.__initMacroActions() self.__initBookmarkActions() self.__initSpellingActions() ################################################################## ## Initialize the file related actions, file menu and toolbar ################################################################## def __initFileActions(self): """ Private method defining the user interface actions for file handling. """ self.newAct = E5Action( QCoreApplication.translate('ViewManager', 'New'), UI.PixmapCache.getIcon("new.png"), QCoreApplication.translate('ViewManager', '&New'), QKeySequence( QCoreApplication.translate('ViewManager', "Ctrl+N", "File|New")), 0, self, 'vm_file_new') self.newAct.setStatusTip( QCoreApplication.translate( 'ViewManager', 'Open an empty editor window')) self.newAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """New""" """

An empty editor window will be created.

""" )) self.newAct.triggered.connect(self.newEditor) self.fileActions.append(self.newAct) self.openAct = E5Action( QCoreApplication.translate('ViewManager', 'Open'), UI.PixmapCache.getIcon("open.png"), QCoreApplication.translate('ViewManager', '&Open...'), QKeySequence( QCoreApplication.translate('ViewManager', "Ctrl+O", "File|Open")), 0, self, 'vm_file_open') self.openAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Open a file')) self.openAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Open a file""" """

You will be asked for the name of a file to be opened""" """ in an editor window.

""" )) self.openAct.triggered.connect(self.__openFiles) self.fileActions.append(self.openAct) self.closeActGrp = createActionGroup(self) self.closeAct = E5Action( QCoreApplication.translate('ViewManager', 'Close'), UI.PixmapCache.getIcon("close.png"), QCoreApplication.translate('ViewManager', '&Close'), QKeySequence( QCoreApplication.translate('ViewManager', "Ctrl+W", "File|Close")), 0, self.closeActGrp, 'vm_file_close') self.closeAct.setStatusTip( QCoreApplication.translate('ViewManager', 'Close the current window')) self.closeAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Close Window""" """

Close the current window.

""" )) self.closeAct.triggered.connect(self.closeCurrentWindow) self.fileActions.append(self.closeAct) self.closeAllAct = E5Action( QCoreApplication.translate('ViewManager', 'Close All'), QCoreApplication.translate('ViewManager', 'Clos&e All'), 0, 0, self.closeActGrp, 'vm_file_close_all') self.closeAllAct.setStatusTip( QCoreApplication.translate('ViewManager', 'Close all editor windows')) self.closeAllAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Close All Windows""" """

Close all editor windows.

""" )) self.closeAllAct.triggered.connect(self.closeAllWindows) self.fileActions.append(self.closeAllAct) self.closeActGrp.setEnabled(False) self.saveActGrp = createActionGroup(self) self.saveAct = E5Action( QCoreApplication.translate('ViewManager', 'Save'), UI.PixmapCache.getIcon("fileSave.png"), QCoreApplication.translate('ViewManager', '&Save'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+S", "File|Save")), 0, self.saveActGrp, 'vm_file_save') self.saveAct.setStatusTip( QCoreApplication.translate('ViewManager', 'Save the current file')) self.saveAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Save File""" """

Save the contents of current editor window.

""" )) self.saveAct.triggered.connect(self.saveCurrentEditor) self.fileActions.append(self.saveAct) self.saveAsAct = E5Action( QCoreApplication.translate('ViewManager', 'Save as'), UI.PixmapCache.getIcon("fileSaveAs.png"), QCoreApplication.translate('ViewManager', 'Save &as...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Shift+Ctrl+S", "File|Save As")), 0, self.saveActGrp, 'vm_file_save_as') self.saveAsAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Save the current file to a new one')) self.saveAsAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Save File as""" """

Save the contents of current editor window to a new file.""" """ The file can be entered in a file selection dialog.

""" )) self.saveAsAct.triggered.connect(self.saveAsCurrentEditor) self.fileActions.append(self.saveAsAct) self.saveAllAct = E5Action( QCoreApplication.translate('ViewManager', 'Save all'), UI.PixmapCache.getIcon("fileSaveAll.png"), QCoreApplication.translate('ViewManager', 'Save a&ll'), 0, 0, self.saveActGrp, 'vm_file_save_all') self.saveAllAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Save all files')) self.saveAllAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Save All Files""" """

Save the contents of all editor windows.

""" )) self.saveAllAct.triggered.connect(self.saveAllEditors) self.fileActions.append(self.saveAllAct) self.saveActGrp.setEnabled(False) self.printAct = E5Action( QCoreApplication.translate('ViewManager', 'Print'), UI.PixmapCache.getIcon("print.png"), QCoreApplication.translate('ViewManager', '&Print'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+P", "File|Print")), 0, self, 'vm_file_print') self.printAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Print the current file')) self.printAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Print File""" """

Print the contents of current editor window.

""" )) self.printAct.triggered.connect(self.printCurrentEditor) self.printAct.setEnabled(False) self.fileActions.append(self.printAct) self.printPreviewAct = E5Action( QCoreApplication.translate('ViewManager', 'Print Preview'), UI.PixmapCache.getIcon("printPreview.png"), QCoreApplication.translate('ViewManager', 'Print Preview'), 0, 0, self, 'vm_file_print_preview') self.printPreviewAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Print preview of the current file')) self.printPreviewAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Print Preview""" """

Print preview of the current editor window.

""" )) self.printPreviewAct.triggered.connect( self.printPreviewCurrentEditor) self.printPreviewAct.setEnabled(False) self.fileActions.append(self.printPreviewAct) self.findFileNameAct = E5Action( QCoreApplication.translate('ViewManager', 'Search File'), QCoreApplication.translate('ViewManager', 'Search &File...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Alt+Ctrl+F", "File|Search File")), 0, self, 'vm_file_search_file') self.findFileNameAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search for a file')) self.findFileNameAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Search File""" """

Search for a file.

""" )) self.findFileNameAct.triggered.connect(self.__findFileName) self.fileActions.append(self.findFileNameAct) def initFileMenu(self): """ Public method to create the File menu. @return the generated menu """ menu = QMenu(QCoreApplication.translate('ViewManager', '&File'), self.ui) self.recentMenu = QMenu( QCoreApplication.translate('ViewManager', 'Open &Recent Files'), menu) self.bookmarkedMenu = QMenu( QCoreApplication.translate('ViewManager', 'Open &Bookmarked Files'), menu) self.exportersMenu = self.__initContextMenuExporters() menu.setTearOffEnabled(True) menu.addAction(self.newAct) menu.addAction(self.openAct) self.menuRecentAct = menu.addMenu(self.recentMenu) menu.addMenu(self.bookmarkedMenu) menu.addSeparator() menu.addAction(self.closeAct) menu.addAction(self.closeAllAct) menu.addSeparator() menu.addAction(self.findFileNameAct) menu.addSeparator() menu.addAction(self.saveAct) menu.addAction(self.saveAsAct) menu.addAction(self.saveAllAct) self.exportersMenuAct = menu.addMenu(self.exportersMenu) menu.addSeparator() menu.addAction(self.printPreviewAct) menu.addAction(self.printAct) self.recentMenu.aboutToShow.connect(self.__showRecentMenu) self.recentMenu.triggered.connect(self.__openSourceFile) self.bookmarkedMenu.aboutToShow.connect(self.__showBookmarkedMenu) self.bookmarkedMenu.triggered.connect(self.__openSourceFile) menu.aboutToShow.connect(self.__showFileMenu) self.exportersMenuAct.setEnabled(False) return menu def initFileToolbar(self, toolbarManager): """ Public method to create the File toolbar. @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) @return the generated toolbar """ tb = QToolBar(QCoreApplication.translate('ViewManager', 'File'), self.ui) tb.setIconSize(UI.Config.ToolBarIconSize) tb.setObjectName("FileToolbar") tb.setToolTip(QCoreApplication.translate('ViewManager', 'File')) tb.addAction(self.newAct) tb.addAction(self.openAct) tb.addAction(self.closeAct) tb.addSeparator() tb.addAction(self.saveAct) tb.addAction(self.saveAsAct) tb.addAction(self.saveAllAct) toolbarManager.addToolBar(tb, tb.windowTitle()) toolbarManager.addAction(self.printPreviewAct, tb.windowTitle()) toolbarManager.addAction(self.printAct, tb.windowTitle()) return tb def __initContextMenuExporters(self): """ Private method used to setup the Exporters sub menu. @return reference to the generated menu (QMenu) """ menu = QMenu(QCoreApplication.translate('ViewManager', "Export as")) import QScintilla.Exporters supportedExporters = QScintilla.Exporters.getSupportedFormats() exporters = sorted(list(supportedExporters.keys())) for exporter in exporters: act = menu.addAction(supportedExporters[exporter]) act.setData(exporter) menu.triggered.connect(self.__exportMenuTriggered) return menu ################################################################## ## Initialize the edit related actions, edit menu and toolbar ################################################################## def __initEditActions(self): """ Private method defining the user interface actions for the edit commands. """ self.editActGrp = createActionGroup(self) self.undoAct = E5Action( QCoreApplication.translate('ViewManager', 'Undo'), UI.PixmapCache.getIcon("editUndo.png"), QCoreApplication.translate('ViewManager', '&Undo'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Z", "Edit|Undo")), QKeySequence(QCoreApplication.translate( 'ViewManager', "Alt+Backspace", "Edit|Undo")), self.editActGrp, 'vm_edit_undo') self.undoAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Undo the last change')) self.undoAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Undo""" """

Undo the last change done in the current editor.

""" )) self.undoAct.triggered.connect(self.__editUndo) self.editActions.append(self.undoAct) self.redoAct = E5Action( QCoreApplication.translate('ViewManager', 'Redo'), UI.PixmapCache.getIcon("editRedo.png"), QCoreApplication.translate('ViewManager', '&Redo'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+Z", "Edit|Redo")), 0, self.editActGrp, 'vm_edit_redo') self.redoAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Redo the last change')) self.redoAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Redo""" """

Redo the last change done in the current editor.

""" )) self.redoAct.triggered.connect(self.__editRedo) self.editActions.append(self.redoAct) self.revertAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Revert to last saved state'), QCoreApplication.translate( 'ViewManager', 'Re&vert to last saved state'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Y", "Edit|Revert")), 0, self.editActGrp, 'vm_edit_revert') self.revertAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Revert to last saved state')) self.revertAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Revert to last saved state""" """

Undo all changes up to the last saved state""" """ of the current editor.

""" )) self.revertAct.triggered.connect(self.__editRevert) self.editActions.append(self.revertAct) self.copyActGrp = createActionGroup(self.editActGrp) self.cutAct = E5Action( QCoreApplication.translate('ViewManager', 'Cut'), UI.PixmapCache.getIcon("editCut.png"), QCoreApplication.translate('ViewManager', 'Cu&t'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+X", "Edit|Cut")), QKeySequence(QCoreApplication.translate( 'ViewManager', "Shift+Del", "Edit|Cut")), self.copyActGrp, 'vm_edit_cut') self.cutAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Cut the selection')) self.cutAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Cut""" """

Cut the selected text of the current editor to the""" """ clipboard.

""" )) self.cutAct.triggered.connect(self.__editCut) self.editActions.append(self.cutAct) self.copyAct = E5Action( QCoreApplication.translate('ViewManager', 'Copy'), UI.PixmapCache.getIcon("editCopy.png"), QCoreApplication.translate('ViewManager', '&Copy'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+C", "Edit|Copy")), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Ins", "Edit|Copy")), self.copyActGrp, 'vm_edit_copy') self.copyAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Copy the selection')) self.copyAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Copy""" """

Copy the selected text of the current editor to the""" """ clipboard.

""" )) self.copyAct.triggered.connect(self.__editCopy) self.editActions.append(self.copyAct) self.pasteAct = E5Action( QCoreApplication.translate('ViewManager', 'Paste'), UI.PixmapCache.getIcon("editPaste.png"), QCoreApplication.translate('ViewManager', '&Paste'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+V", "Edit|Paste")), QKeySequence(QCoreApplication.translate( 'ViewManager', "Shift+Ins", "Edit|Paste")), self.copyActGrp, 'vm_edit_paste') self.pasteAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Paste the last cut/copied text')) self.pasteAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Paste""" """

Paste the last cut/copied text from the clipboard to""" """ the current editor.

""" )) self.pasteAct.triggered.connect(self.__editPaste) self.editActions.append(self.pasteAct) self.deleteAct = E5Action( QCoreApplication.translate('ViewManager', 'Clear'), UI.PixmapCache.getIcon("editDelete.png"), QCoreApplication.translate('ViewManager', 'Clear'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Alt+Shift+C", "Edit|Clear")), 0, self.copyActGrp, 'vm_edit_clear') self.deleteAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Clear all text')) self.deleteAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Clear""" """

Delete all text of the current editor.

""" )) self.deleteAct.triggered.connect(self.__editDelete) self.editActions.append(self.deleteAct) self.joinAct = E5Action( QCoreApplication.translate('ViewManager', 'Join Lines'), QCoreApplication.translate('ViewManager', 'Join Lines'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+J", "Edit|Join Lines")), 0, self.copyActGrp, 'vm_edit_join_lines') self.joinAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Join Lines')) self.joinAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Join Lines""" """

Join the current and the next lines.

""" )) self.joinAct.triggered.connect(self.__editJoin) self.editActions.append(self.joinAct) self.indentAct = E5Action( QCoreApplication.translate('ViewManager', 'Indent'), UI.PixmapCache.getIcon("editIndent.png"), QCoreApplication.translate('ViewManager', '&Indent'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+I", "Edit|Indent")), 0, self.editActGrp, 'vm_edit_indent') self.indentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Indent line')) self.indentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Indent""" """

Indents the current line or the lines of the""" """ selection by one level.

""" )) self.indentAct.triggered.connect(self.__editIndent) self.editActions.append(self.indentAct) self.unindentAct = E5Action( QCoreApplication.translate('ViewManager', 'Unindent'), UI.PixmapCache.getIcon("editUnindent.png"), QCoreApplication.translate('ViewManager', 'U&nindent'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+I", "Edit|Unindent")), 0, self.editActGrp, 'vm_edit_unindent') self.unindentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Unindent line')) self.unindentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Unindent""" """

Unindents the current line or the lines of the""" """ selection by one level.

""" )) self.unindentAct.triggered.connect(self.__editUnindent) self.editActions.append(self.unindentAct) self.smartIndentAct = E5Action( QCoreApplication.translate('ViewManager', 'Smart indent'), UI.PixmapCache.getIcon("editSmartIndent.png"), QCoreApplication.translate('ViewManager', 'Smart indent'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Alt+I", "Edit|Smart indent")), 0, self.editActGrp, 'vm_edit_smart_indent') self.smartIndentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Smart indent Line or Selection')) self.smartIndentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Smart indent""" """

Indents the current line or the lines of the""" """ current selection smartly.

""" )) self.smartIndentAct.triggered.connect(self.__editSmartIndent) self.editActions.append(self.smartIndentAct) self.commentAct = E5Action( QCoreApplication.translate('ViewManager', 'Comment'), UI.PixmapCache.getIcon("editComment.png"), QCoreApplication.translate('ViewManager', 'C&omment'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+M", "Edit|Comment")), 0, self.editActGrp, 'vm_edit_comment') self.commentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Comment Line or Selection')) self.commentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Comment""" """

Comments the current line or the lines of the""" """ current selection.

""" )) self.commentAct.triggered.connect(self.__editComment) self.editActions.append(self.commentAct) self.uncommentAct = E5Action( QCoreApplication.translate('ViewManager', 'Uncomment'), UI.PixmapCache.getIcon("editUncomment.png"), QCoreApplication.translate('ViewManager', 'Unco&mment'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Alt+Ctrl+M", "Edit|Uncomment")), 0, self.editActGrp, 'vm_edit_uncomment') self.uncommentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Uncomment Line or Selection')) self.uncommentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Uncomment""" """

Uncomments the current line or the lines of the""" """ current selection.

""" )) self.uncommentAct.triggered.connect(self.__editUncomment) self.editActions.append(self.uncommentAct) self.toggleCommentAct = E5Action( QCoreApplication.translate('ViewManager', 'Toggle Comment'), UI.PixmapCache.getIcon("editToggleComment.png"), QCoreApplication.translate('ViewManager', 'Toggle Comment'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+M", "Edit|Toggle Comment")), 0, self.editActGrp, 'vm_edit_toggle_comment') self.toggleCommentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Toggle the comment of the current line, selection or' ' comment block')) self.toggleCommentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Toggle Comment""" """

If the current line does not start with a block comment,""" """ the current line or selection is commented. If it is already""" """ commented, this comment block is uncommented.

""" )) self.toggleCommentAct.triggered.connect(self.__editToggleComment) self.editActions.append(self.toggleCommentAct) self.streamCommentAct = E5Action( QCoreApplication.translate('ViewManager', 'Stream Comment'), QCoreApplication.translate('ViewManager', 'Stream Comment'), 0, 0, self.editActGrp, 'vm_edit_stream_comment') self.streamCommentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Stream Comment Line or Selection')) self.streamCommentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Stream Comment""" """

Stream comments the current line or the current""" """ selection.

""" )) self.streamCommentAct.triggered.connect(self.__editStreamComment) self.editActions.append(self.streamCommentAct) self.boxCommentAct = E5Action( QCoreApplication.translate('ViewManager', 'Box Comment'), QCoreApplication.translate('ViewManager', 'Box Comment'), 0, 0, self.editActGrp, 'vm_edit_box_comment') self.boxCommentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Box Comment Line or Selection')) self.boxCommentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Box Comment""" """

Box comments the current line or the lines of the""" """ current selection.

""" )) self.boxCommentAct.triggered.connect(self.__editBoxComment) self.editActions.append(self.boxCommentAct) self.selectBraceAct = E5Action( QCoreApplication.translate('ViewManager', 'Select to brace'), QCoreApplication.translate('ViewManager', 'Select to &brace'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+E", "Edit|Select to brace")), 0, self.editActGrp, 'vm_edit_select_to_brace') self.selectBraceAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Select text to the matching brace')) self.selectBraceAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Select to brace""" """

Select text of the current editor to the matching""" """ brace.

""" )) self.selectBraceAct.triggered.connect(self.__editSelectBrace) self.editActions.append(self.selectBraceAct) self.selectAllAct = E5Action( QCoreApplication.translate('ViewManager', 'Select all'), UI.PixmapCache.getIcon("editSelectAll.png"), QCoreApplication.translate('ViewManager', '&Select all'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+A", "Edit|Select all")), 0, self.editActGrp, 'vm_edit_select_all') self.selectAllAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Select all text')) self.selectAllAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Select All""" """

Select all text of the current editor.

""" )) self.selectAllAct.triggered.connect(self.__editSelectAll) self.editActions.append(self.selectAllAct) self.deselectAllAct = E5Action( QCoreApplication.translate('ViewManager', 'Deselect all'), QCoreApplication.translate('ViewManager', '&Deselect all'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Alt+Ctrl+A", "Edit|Deselect all")), 0, self.editActGrp, 'vm_edit_deselect_all') self.deselectAllAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Deselect all text')) self.deselectAllAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Deselect All""" """

Deselect all text of the current editor.

""" )) self.deselectAllAct.triggered.connect(self.__editDeselectAll) self.editActions.append(self.deselectAllAct) self.convertEOLAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Convert Line End Characters'), QCoreApplication.translate( 'ViewManager', 'Convert &Line End Characters'), 0, 0, self.editActGrp, 'vm_edit_convert_eol') self.convertEOLAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Convert Line End Characters')) self.convertEOLAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Convert Line End Characters""" """

Convert the line end characters to the currently set""" """ type.

""" )) self.convertEOLAct.triggered.connect(self.__convertEOL) self.editActions.append(self.convertEOLAct) self.shortenEmptyAct = E5Action( QCoreApplication.translate('ViewManager', 'Shorten empty lines'), QCoreApplication.translate('ViewManager', 'Shorten empty lines'), 0, 0, self.editActGrp, 'vm_edit_shorten_empty_lines') self.shortenEmptyAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Shorten empty lines')) self.shortenEmptyAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Shorten empty lines""" """

Shorten lines consisting solely of whitespace""" """ characters.

""" )) self.shortenEmptyAct.triggered.connect(self.__shortenEmptyLines) self.editActions.append(self.shortenEmptyAct) self.autoCompleteAct = E5Action( QCoreApplication.translate('ViewManager', 'Autocomplete'), QCoreApplication.translate('ViewManager', '&Autocomplete'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Space", "Edit|Autocomplete")), 0, self.editActGrp, 'vm_edit_autocomplete') self.autoCompleteAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Autocomplete current word')) self.autoCompleteAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Autocomplete""" """

Performs an autocompletion of the word containing""" """ the cursor.

""" )) self.autoCompleteAct.triggered.connect(self.__editAutoComplete) self.editActions.append(self.autoCompleteAct) self.autoCompleteFromDocAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Autocomplete from Document'), QCoreApplication.translate( 'ViewManager', 'Autocomplete from Document'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+Space", "Edit|Autocomplete from Document")), 0, self.editActGrp, 'vm_edit_autocomplete_from_document') self.autoCompleteFromDocAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Autocomplete current word from Document')) self.autoCompleteFromDocAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Autocomplete from Document""" """

Performs an autocompletion from document of the word""" """ containing the cursor.

""" )) self.autoCompleteFromDocAct.triggered.connect( self.__editAutoCompleteFromDoc) self.editActions.append(self.autoCompleteFromDocAct) self.autoCompleteFromAPIsAct = E5Action( QCoreApplication.translate('ViewManager', 'Autocomplete from APIs'), QCoreApplication.translate('ViewManager', 'Autocomplete from APIs'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Alt+Space", "Edit|Autocomplete from APIs")), 0, self.editActGrp, 'vm_edit_autocomplete_from_api') self.autoCompleteFromAPIsAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Autocomplete current word from APIs')) self.autoCompleteFromAPIsAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Autocomplete from APIs""" """

Performs an autocompletion from APIs of the word""" """ containing the cursor.

""" )) self.autoCompleteFromAPIsAct.triggered.connect( self.__editAutoCompleteFromAPIs) self.editActions.append(self.autoCompleteFromAPIsAct) self.autoCompleteFromAllAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Autocomplete from Document and APIs'), QCoreApplication.translate( 'ViewManager', 'Autocomplete from Document and APIs'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Alt+Shift+Space", "Edit|Autocomplete from Document and APIs")), 0, self.editActGrp, 'vm_edit_autocomplete_from_all') self.autoCompleteFromAllAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Autocomplete current word from Document and APIs')) self.autoCompleteFromAllAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Autocomplete from Document and APIs""" """

Performs an autocompletion from document and APIs""" """ of the word containing the cursor.

""" )) self.autoCompleteFromAllAct.triggered.connect( self.__editAutoCompleteFromAll) self.editActions.append(self.autoCompleteFromAllAct) self.calltipsAct = E5Action( QCoreApplication.translate('ViewManager', 'Calltip'), QCoreApplication.translate('ViewManager', '&Calltip'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Meta+Alt+Space", "Edit|Calltip")), 0, self.editActGrp, 'vm_edit_calltip') self.calltipsAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Show Calltips')) self.calltipsAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Calltip""" """

Show calltips based on the characters immediately to the""" """ left of the cursor.

""" )) self.calltipsAct.triggered.connect(self.__editShowCallTips) self.editActions.append(self.calltipsAct) self.sortAct = E5Action( QCoreApplication.translate('ViewManager', 'Sort'), QCoreApplication.translate('ViewManager', 'Sort'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Alt+S", "Edit|Sort")), 0, self.editActGrp, 'vm_edit_sort') self.sortAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Sort the lines containing the rectangular selection')) self.sortAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Sort""" """

Sort the lines spanned by a rectangular selection based on""" """ the selection ignoring leading and trailing whitespace.

""" )) self.sortAct.triggered.connect(self.__editSortSelectedLines) self.editActions.append(self.sortAct) self.editActGrp.setEnabled(False) self.copyActGrp.setEnabled(False) #################################################################### ## Below follow the actions for QScintilla standard commands. #################################################################### self.esm = QSignalMapper(self) self.esm.mapped[int].connect(self.__editorCommand) self.editorActGrp = createActionGroup(self.editActGrp) act = E5Action( QCoreApplication.translate('ViewManager', 'Move left one character'), QCoreApplication.translate('ViewManager', 'Move left one character'), QKeySequence(QCoreApplication.translate('ViewManager', 'Left')), 0, self.editorActGrp, 'vm_edit_move_left_char') self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFT) if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+B'))) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move right one character'), QCoreApplication.translate('ViewManager', 'Move right one character'), QKeySequence(QCoreApplication.translate('ViewManager', 'Right')), 0, self.editorActGrp, 'vm_edit_move_right_char') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+F'))) self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move up one line'), QCoreApplication.translate('ViewManager', 'Move up one line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Up')), 0, self.editorActGrp, 'vm_edit_move_up_line') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+P'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEUP) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move down one line'), QCoreApplication.translate('ViewManager', 'Move down one line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Down')), 0, self.editorActGrp, 'vm_edit_move_down_line') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+N'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEDOWN) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move left one word part'), QCoreApplication.translate('ViewManager', 'Move left one word part'), 0, 0, self.editorActGrp, 'vm_edit_move_left_word_part') if not isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Left'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDPARTLEFT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move right one word part'), QCoreApplication.translate('ViewManager', 'Move right one word part'), 0, 0, self.editorActGrp, 'vm_edit_move_right_word_part') if not isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Right'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDPARTRIGHT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move left one word'), QCoreApplication.translate('ViewManager', 'Move left one word'), 0, 0, self.editorActGrp, 'vm_edit_move_left_word') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Left'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Left'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move right one word'), QCoreApplication.translate('ViewManager', 'Move right one word'), 0, 0, self.editorActGrp, 'vm_edit_move_right_word') if not isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Right'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to first visible character in document line'), QCoreApplication.translate( 'ViewManager', 'Move to first visible character in document line'), 0, 0, self.editorActGrp, 'vm_edit_move_first_visible_char') if not isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Home'))) self.esm.setMapping(act, QsciScintilla.SCI_VCHOME) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to start of display line'), QCoreApplication.translate( 'ViewManager', 'Move to start of display line'), 0, 0, self.editorActGrp, 'vm_edit_move_start_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Left'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Home'))) self.esm.setMapping(act, QsciScintilla.SCI_HOMEDISPLAY) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to end of document line'), QCoreApplication.translate( 'ViewManager', 'Move to end of document line'), 0, 0, self.editorActGrp, 'vm_edit_move_end_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+E'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'End'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Scroll view down one line'), QCoreApplication.translate('ViewManager', 'Scroll view down one line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+Down')), 0, self.editorActGrp, 'vm_edit_scroll_down_line') self.esm.setMapping(act, QsciScintilla.SCI_LINESCROLLDOWN) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Scroll view up one line'), QCoreApplication.translate('ViewManager', 'Scroll view up one line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+Up')), 0, self.editorActGrp, 'vm_edit_scroll_up_line') self.esm.setMapping(act, QsciScintilla.SCI_LINESCROLLUP) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move up one paragraph'), QCoreApplication.translate('ViewManager', 'Move up one paragraph'), QKeySequence(QCoreApplication.translate('ViewManager', 'Alt+Up')), 0, self.editorActGrp, 'vm_edit_move_up_para') self.esm.setMapping(act, QsciScintilla.SCI_PARAUP) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move down one paragraph'), QCoreApplication.translate('ViewManager', 'Move down one paragraph'), QKeySequence(QCoreApplication.translate('ViewManager', 'Alt+Down')), 0, self.editorActGrp, 'vm_edit_move_down_para') self.esm.setMapping(act, QsciScintilla.SCI_PARADOWN) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move up one page'), QCoreApplication.translate('ViewManager', 'Move up one page'), QKeySequence(QCoreApplication.translate('ViewManager', 'PgUp')), 0, self.editorActGrp, 'vm_edit_move_up_page') self.esm.setMapping(act, QsciScintilla.SCI_PAGEUP) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move down one page'), QCoreApplication.translate('ViewManager', 'Move down one page'), QKeySequence(QCoreApplication.translate('ViewManager', 'PgDown')), 0, self.editorActGrp, 'vm_edit_move_down_page') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+V'))) self.esm.setMapping(act, QsciScintilla.SCI_PAGEDOWN) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move to start of document'), QCoreApplication.translate('ViewManager', 'Move to start of document'), 0, 0, self.editorActGrp, 'vm_edit_move_start_text') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Up'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Home'))) self.esm.setMapping(act, QsciScintilla.SCI_DOCUMENTSTART) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Move to end of document'), QCoreApplication.translate('ViewManager', 'Move to end of document'), 0, 0, self.editorActGrp, 'vm_edit_move_end_text') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Down'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+End'))) self.esm.setMapping(act, QsciScintilla.SCI_DOCUMENTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Indent one level'), QCoreApplication.translate('ViewManager', 'Indent one level'), QKeySequence(QCoreApplication.translate('ViewManager', 'Tab')), 0, self.editorActGrp, 'vm_edit_indent_one_level') self.esm.setMapping(act, QsciScintilla.SCI_TAB) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Unindent one level'), QCoreApplication.translate('ViewManager', 'Unindent one level'), QKeySequence(QCoreApplication.translate('ViewManager', 'Shift+Tab')), 0, self.editorActGrp, 'vm_edit_unindent_one_level') self.esm.setMapping(act, QsciScintilla.SCI_BACKTAB) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection left one character'), QCoreApplication.translate( 'ViewManager', 'Extend selection left one character'), QKeySequence(QCoreApplication.translate('ViewManager', 'Shift+Left')), 0, self.editorActGrp, 'vm_edit_extend_selection_left_char') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Shift+B'))) self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection right one character'), QCoreApplication.translate( 'ViewManager', 'Extend selection right one character'), QKeySequence(QCoreApplication.translate('ViewManager', 'Shift+Right')), 0, self.editorActGrp, 'vm_edit_extend_selection_right_char') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Shift+F'))) self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection up one line'), QCoreApplication.translate( 'ViewManager', 'Extend selection up one line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Shift+Up')), 0, self.editorActGrp, 'vm_edit_extend_selection_up_line') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Shift+P'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEUPEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection down one line'), QCoreApplication.translate( 'ViewManager', 'Extend selection down one line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Shift+Down')), 0, self.editorActGrp, 'vm_edit_extend_selection_down_line') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Shift+N'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEDOWNEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection left one word part'), QCoreApplication.translate( 'ViewManager', 'Extend selection left one word part'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_left_word_part') if not isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Shift+Left'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDPARTLEFTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection right one word part'), QCoreApplication.translate( 'ViewManager', 'Extend selection right one word part'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_right_word_part') if not isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Shift+Right'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDPARTRIGHTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection left one word'), QCoreApplication.translate( 'ViewManager', 'Extend selection left one word'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_left_word') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Shift+Left'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Left'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection right one word'), QCoreApplication.translate( 'ViewManager', 'Extend selection right one word'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_right_word') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Shift+Right'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Right'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to first visible character in document' ' line'), QCoreApplication.translate( 'ViewManager', 'Extend selection to first visible character in document' ' line'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_first_visible_char') if not isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Shift+Home'))) self.esm.setMapping(act, QsciScintilla.SCI_VCHOMEEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to end of document line'), QCoreApplication.translate( 'ViewManager', 'Extend selection to end of document line'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_end_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Shift+E'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Shift+End'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEENDEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection up one paragraph'), QCoreApplication.translate( 'ViewManager', 'Extend selection up one paragraph'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Alt+Shift+Up')), 0, self.editorActGrp, 'vm_edit_extend_selection_up_para') self.esm.setMapping(act, QsciScintilla.SCI_PARAUPEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection down one paragraph'), QCoreApplication.translate( 'ViewManager', 'Extend selection down one paragraph'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Alt+Shift+Down')), 0, self.editorActGrp, 'vm_edit_extend_selection_down_para') self.esm.setMapping(act, QsciScintilla.SCI_PARADOWNEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection up one page'), QCoreApplication.translate( 'ViewManager', 'Extend selection up one page'), QKeySequence(QCoreApplication.translate('ViewManager', 'Shift+PgUp')), 0, self.editorActGrp, 'vm_edit_extend_selection_up_page') self.esm.setMapping(act, QsciScintilla.SCI_PAGEUPEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection down one page'), QCoreApplication.translate( 'ViewManager', 'Extend selection down one page'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Shift+PgDown')), 0, self.editorActGrp, 'vm_edit_extend_selection_down_page') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Shift+V'))) self.esm.setMapping(act, QsciScintilla.SCI_PAGEDOWNEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to start of document'), QCoreApplication.translate( 'ViewManager', 'Extend selection to start of document'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_start_text') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Up'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Home'))) self.esm.setMapping(act, QsciScintilla.SCI_DOCUMENTSTARTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to end of document'), QCoreApplication.translate( 'ViewManager', 'Extend selection to end of document'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_end_text') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Down'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+End'))) self.esm.setMapping(act, QsciScintilla.SCI_DOCUMENTENDEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Delete previous character'), QCoreApplication.translate('ViewManager', 'Delete previous character'), QKeySequence(QCoreApplication.translate('ViewManager', 'Backspace')), 0, self.editorActGrp, 'vm_edit_delete_previous_char') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+H'))) else: act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Shift+Backspace'))) self.esm.setMapping(act, QsciScintilla.SCI_DELETEBACK) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Delete previous character if not at start of line'), QCoreApplication.translate( 'ViewManager', 'Delete previous character if not at start of line'), 0, 0, self.editorActGrp, 'vm_edit_delet_previous_char_not_line_start') self.esm.setMapping(act, QsciScintilla.SCI_DELETEBACKNOTLINE) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Delete current character'), QCoreApplication.translate('ViewManager', 'Delete current character'), QKeySequence(QCoreApplication.translate('ViewManager', 'Del')), 0, self.editorActGrp, 'vm_edit_delete_current_char') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+D'))) self.esm.setMapping(act, QsciScintilla.SCI_CLEAR) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Delete word to left'), QCoreApplication.translate('ViewManager', 'Delete word to left'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Ctrl+Backspace')), 0, self.editorActGrp, 'vm_edit_delete_word_left') self.esm.setMapping(act, QsciScintilla.SCI_DELWORDLEFT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Delete word to right'), QCoreApplication.translate('ViewManager', 'Delete word to right'), QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+Del')), 0, self.editorActGrp, 'vm_edit_delete_word_right') self.esm.setMapping(act, QsciScintilla.SCI_DELWORDRIGHT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Delete line to left'), QCoreApplication.translate('ViewManager', 'Delete line to left'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Ctrl+Shift+Backspace')), 0, self.editorActGrp, 'vm_edit_delete_line_left') self.esm.setMapping(act, QsciScintilla.SCI_DELLINELEFT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Delete line to right'), QCoreApplication.translate('ViewManager', 'Delete line to right'), 0, 0, self.editorActGrp, 'vm_edit_delete_line_right') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+K'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Del'))) self.esm.setMapping(act, QsciScintilla.SCI_DELLINERIGHT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Insert new line'), QCoreApplication.translate('ViewManager', 'Insert new line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Return')), QKeySequence(QCoreApplication.translate('ViewManager', 'Enter')), self.editorActGrp, 'vm_edit_insert_line') self.esm.setMapping(act, QsciScintilla.SCI_NEWLINE) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Insert new line below current line'), QCoreApplication.translate( 'ViewManager', 'Insert new line below current line'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Shift+Return')), QKeySequence(QCoreApplication.translate('ViewManager', 'Shift+Enter')), self.editorActGrp, 'vm_edit_insert_line_below') act.triggered.connect(self.__newLineBelow) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Delete current line'), QCoreApplication.translate('ViewManager', 'Delete current line'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Ctrl+Shift+L')), 0, self.editorActGrp, 'vm_edit_delete_current_line') self.esm.setMapping(act, QsciScintilla.SCI_LINEDELETE) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Duplicate current line'), QCoreApplication.translate( 'ViewManager', 'Duplicate current line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+D')), 0, self.editorActGrp, 'vm_edit_duplicate_current_line') self.esm.setMapping(act, QsciScintilla.SCI_LINEDUPLICATE) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Swap current and previous lines'), QCoreApplication.translate( 'ViewManager', 'Swap current and previous lines'), QKeySequence(QCoreApplication.translate('ViewManager', 'Ctrl+T')), 0, self.editorActGrp, 'vm_edit_swap_current_previous_line') self.esm.setMapping(act, QsciScintilla.SCI_LINETRANSPOSE) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Cut current line'), QCoreApplication.translate('ViewManager', 'Cut current line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Alt+Shift+L')), 0, self.editorActGrp, 'vm_edit_cut_current_line') self.esm.setMapping(act, QsciScintilla.SCI_LINECUT) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Copy current line'), QCoreApplication.translate('ViewManager', 'Copy current line'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Ctrl+Shift+T')), 0, self.editorActGrp, 'vm_edit_copy_current_line') self.esm.setMapping(act, QsciScintilla.SCI_LINECOPY) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Toggle insert/overtype'), QCoreApplication.translate( 'ViewManager', 'Toggle insert/overtype'), QKeySequence(QCoreApplication.translate('ViewManager', 'Ins')), 0, self.editorActGrp, 'vm_edit_toggle_insert_overtype') self.esm.setMapping(act, QsciScintilla.SCI_EDITTOGGLEOVERTYPE) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to end of display line'), QCoreApplication.translate( 'ViewManager', 'Move to end of display line'), 0, 0, self.editorActGrp, 'vm_edit_move_end_displayed_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Right'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+End'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEENDDISPLAY) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to end of display line'), QCoreApplication.translate( 'ViewManager', 'Extend selection to end of display line'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_end_displayed_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Right'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEENDDISPLAYEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Formfeed'), QCoreApplication.translate('ViewManager', 'Formfeed'), 0, 0, self.editorActGrp, 'vm_edit_formfeed') self.esm.setMapping(act, QsciScintilla.SCI_FORMFEED) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate('ViewManager', 'Escape'), QCoreApplication.translate('ViewManager', 'Escape'), QKeySequence(QCoreApplication.translate('ViewManager', 'Esc')), 0, self.editorActGrp, 'vm_edit_escape') self.esm.setMapping(act, QsciScintilla.SCI_CANCEL) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection down one line'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection down one line'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Alt+Ctrl+Down')), 0, self.editorActGrp, 'vm_edit_extend_rect_selection_down_line') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+N'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEDOWNRECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection up one line'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection up one line'), QKeySequence(QCoreApplication.translate('ViewManager', 'Alt+Ctrl+Up')), 0, self.editorActGrp, 'vm_edit_extend_rect_selection_up_line') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+P'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEUPRECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection left one character'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection left one character'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Alt+Ctrl+Left')), 0, self.editorActGrp, 'vm_edit_extend_rect_selection_left_char') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+B'))) self.esm.setMapping(act, QsciScintilla.SCI_CHARLEFTRECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection right one character'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection right one character'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Alt+Ctrl+Right')), 0, self.editorActGrp, 'vm_edit_extend_rect_selection_right_char') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+F'))) self.esm.setMapping(act, QsciScintilla.SCI_CHARRIGHTRECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection to first visible character in' ' document line'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection to first visible character in' ' document line'), 0, 0, self.editorActGrp, 'vm_edit_extend_rect_selection_first_visible_char') if not isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Shift+Home'))) self.esm.setMapping(act, QsciScintilla.SCI_VCHOMERECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection to end of document line'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection to end of document line'), 0, 0, self.editorActGrp, 'vm_edit_extend_rect_selection_end_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+E'))) else: act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Shift+End'))) self.esm.setMapping(act, QsciScintilla.SCI_LINEENDRECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection up one page'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection up one page'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Alt+Shift+PgUp')), 0, self.editorActGrp, 'vm_edit_extend_rect_selection_up_page') self.esm.setMapping(act, QsciScintilla.SCI_PAGEUPRECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection down one page'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection down one page'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Alt+Shift+PgDown')), 0, self.editorActGrp, 'vm_edit_extend_rect_selection_down_page') if isMacPlatform(): act.setAlternateShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+V'))) self.esm.setMapping(act, QsciScintilla.SCI_PAGEDOWNRECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) act = E5Action( QCoreApplication.translate( 'ViewManager', 'Duplicate current selection'), QCoreApplication.translate( 'ViewManager', 'Duplicate current selection'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Ctrl+Shift+D')), 0, self.editorActGrp, 'vm_edit_duplicate_current_selection') self.esm.setMapping(act, QsciScintilla.SCI_SELECTIONDUPLICATE) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_SCROLLTOSTART"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Scroll to start of document'), QCoreApplication.translate( 'ViewManager', 'Scroll to start of document'), 0, 0, self.editorActGrp, 'vm_edit_scroll_start_text') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Home'))) self.esm.setMapping(act, QsciScintilla.SCI_SCROLLTOSTART) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_SCROLLTOEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Scroll to end of document'), QCoreApplication.translate( 'ViewManager', 'Scroll to end of document'), 0, 0, self.editorActGrp, 'vm_edit_scroll_end_text') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'End'))) self.esm.setMapping(act, QsciScintilla.SCI_SCROLLTOEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_VERTICALCENTRECARET"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Scroll vertically to center current line'), QCoreApplication.translate( 'ViewManager', 'Scroll vertically to center current line'), 0, 0, self.editorActGrp, 'vm_edit_scroll_vertically_center') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+L'))) self.esm.setMapping(act, QsciScintilla.SCI_VERTICALCENTRECARET) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_WORDRIGHTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to end of next word'), QCoreApplication.translate( 'ViewManager', 'Move to end of next word'), 0, 0, self.editorActGrp, 'vm_edit_move_end_next_word') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Right'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_WORDRIGHTENDEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to end of next word'), QCoreApplication.translate( 'ViewManager', 'Extend selection to end of next word'), 0, 0, self.editorActGrp, 'vm_edit_select_end_next_word') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Shift+Right'))) self.esm.setMapping(act, QsciScintilla.SCI_WORDRIGHTENDEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_WORDLEFTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to end of previous word'), QCoreApplication.translate( 'ViewManager', 'Move to end of previous word'), 0, 0, self.editorActGrp, 'vm_edit_move_end_previous_word') self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_WORDLEFTENDEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to end of previous word'), QCoreApplication.translate( 'ViewManager', 'Extend selection to end of previous word'), 0, 0, self.editorActGrp, 'vm_edit_select_end_previous_word') self.esm.setMapping(act, QsciScintilla.SCI_WORDLEFTENDEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_HOME"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to start of document line'), QCoreApplication.translate( 'ViewManager', 'Move to start of document line'), 0, 0, self.editorActGrp, 'vm_edit_move_start_document_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+A'))) self.esm.setMapping(act, QsciScintilla.SCI_HOME) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_HOMEEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to start of document line'), QCoreApplication.translate( 'ViewManager', 'Extend selection to start of document line'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_start_document_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Shift+A'))) self.esm.setMapping(act, QsciScintilla.SCI_HOME) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_HOMERECTEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection to start of document line'), QCoreApplication.translate( 'ViewManager', 'Extend rectangular selection to start of document line'), 0, 0, self.editorActGrp, 'vm_edit_select_rect_start_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Meta+Alt+Shift+A'))) self.esm.setMapping(act, QsciScintilla.SCI_HOMERECTEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_HOMEDISPLAYEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to start of display line'), QCoreApplication.translate( 'ViewManager', 'Extend selection to start of display line'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_start_display_line') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Ctrl+Shift+Left'))) self.esm.setMapping(act, QsciScintilla.SCI_HOMEDISPLAYEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_HOMEWRAP"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to start of display or document line'), QCoreApplication.translate( 'ViewManager', 'Move to start of display or document line'), 0, 0, self.editorActGrp, 'vm_edit_move_start_display_document_line') self.esm.setMapping(act, QsciScintilla.SCI_HOMEWRAP) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_HOMEWRAPEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to start of display or document line'), QCoreApplication.translate( 'ViewManager', 'Extend selection to start of display or document line'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_start_display_document_line') self.esm.setMapping(act, QsciScintilla.SCI_HOMEWRAPEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_VCHOMEWRAP"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to first visible character in display or document' ' line'), QCoreApplication.translate( 'ViewManager', 'Move to first visible character in display or document' ' line'), 0, 0, self.editorActGrp, 'vm_edit_move_first_visible_char_document_line') self.esm.setMapping(act, QsciScintilla.SCI_VCHOMEWRAP) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_VCHOMEWRAPEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to first visible character in' ' display or document line'), QCoreApplication.translate( 'ViewManager', 'Extend selection to first visible character in' ' display or document line'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_first_visible_char_document_line') self.esm.setMapping(act, QsciScintilla.SCI_VCHOMEWRAPEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_LINEENDWRAP"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move to end of display or document line'), QCoreApplication.translate( 'ViewManager', 'Move to end of display or document line'), 0, 0, self.editorActGrp, 'vm_edit_end_start_display_document_line') self.esm.setMapping(act, QsciScintilla.SCI_LINEENDWRAP) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_LINEENDWRAPEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Extend selection to end of display or document line'), QCoreApplication.translate( 'ViewManager', 'Extend selection to end of display or document line'), 0, 0, self.editorActGrp, 'vm_edit_extend_selection_end_display_document_line') self.esm.setMapping(act, QsciScintilla.SCI_LINEENDWRAPEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_STUTTEREDPAGEUP"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Stuttered move up one page'), QCoreApplication.translate( 'ViewManager', 'Stuttered move up one page'), 0, 0, self.editorActGrp, 'vm_edit_stuttered_move_up_page') self.esm.setMapping(act, QsciScintilla.SCI_STUTTEREDPAGEUP) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_STUTTEREDPAGEUPEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Stuttered extend selection up one page'), QCoreApplication.translate( 'ViewManager', 'Stuttered extend selection up one page'), 0, 0, self.editorActGrp, 'vm_edit_stuttered_extend_selection_up_page') self.esm.setMapping(act, QsciScintilla.SCI_STUTTEREDPAGEUPEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_STUTTEREDPAGEDOWN"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Stuttered move down one page'), QCoreApplication.translate( 'ViewManager', 'Stuttered move down one page'), 0, 0, self.editorActGrp, 'vm_edit_stuttered_move_down_page') self.esm.setMapping(act, QsciScintilla.SCI_STUTTEREDPAGEDOWN) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_STUTTEREDPAGEDOWNEXTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Stuttered extend selection down one page'), QCoreApplication.translate( 'ViewManager', 'Stuttered extend selection down one page'), 0, 0, self.editorActGrp, 'vm_edit_stuttered_extend_selection_down_page') self.esm.setMapping(act, QsciScintilla.SCI_STUTTEREDPAGEDOWNEXTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_DELWORDRIGHTEND"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Delete right to end of next word'), QCoreApplication.translate( 'ViewManager', 'Delete right to end of next word'), 0, 0, self.editorActGrp, 'vm_edit_delete_right_end_next_word') if isMacPlatform(): act.setShortcut(QKeySequence( QCoreApplication.translate('ViewManager', 'Alt+Del'))) self.esm.setMapping(act, QsciScintilla.SCI_DELWORDRIGHTEND) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_MOVESELECTEDLINESUP"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move selected lines up one line'), QCoreApplication.translate( 'ViewManager', 'Move selected lines up one line'), 0, 0, self.editorActGrp, 'vm_edit_move_selection_up_one_line') self.esm.setMapping(act, QsciScintilla.SCI_MOVESELECTEDLINESUP) act.triggered.connect(self.esm.map) self.editActions.append(act) if hasattr(QsciScintilla, "SCI_MOVESELECTEDLINESDOWN"): act = E5Action( QCoreApplication.translate( 'ViewManager', 'Move selected lines down one line'), QCoreApplication.translate( 'ViewManager', 'Move selected lines down one line'), 0, 0, self.editorActGrp, 'vm_edit_move_selection_down_one_line') self.esm.setMapping(act, QsciScintilla.SCI_MOVESELECTEDLINESDOWN) act.triggered.connect(self.esm.map) self.editActions.append(act) self.editorActGrp.setEnabled(False) self.editLowerCaseAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Convert selection to lower case'), QCoreApplication.translate( 'ViewManager', 'Convert selection to lower case'), QKeySequence(QCoreApplication.translate('ViewManager', 'Alt+Shift+U')), 0, self.editActGrp, 'vm_edit_convert_selection_lower') self.esm.setMapping(self.editLowerCaseAct, QsciScintilla.SCI_LOWERCASE) self.editLowerCaseAct.triggered.connect(self.esm.map) self.editActions.append(self.editLowerCaseAct) self.editUpperCaseAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Convert selection to upper case'), QCoreApplication.translate( 'ViewManager', 'Convert selection to upper case'), QKeySequence(QCoreApplication.translate( 'ViewManager', 'Ctrl+Shift+U')), 0, self.editActGrp, 'vm_edit_convert_selection_upper') self.esm.setMapping(self.editUpperCaseAct, QsciScintilla.SCI_UPPERCASE) self.editUpperCaseAct.triggered.connect(self.esm.map) self.editActions.append(self.editUpperCaseAct) def initEditMenu(self): """ Public method to create the Edit menu. @return the generated menu """ autocompletionMenu = QMenu( QCoreApplication.translate('ViewManager', '&Autocomplete'), self.ui) autocompletionMenu.setTearOffEnabled(True) autocompletionMenu.addAction(self.autoCompleteAct) autocompletionMenu.addAction(self.autoCompleteFromDocAct) autocompletionMenu.addAction(self.autoCompleteFromAPIsAct) autocompletionMenu.addAction(self.autoCompleteFromAllAct) autocompletionMenu.addSeparator() autocompletionMenu.addAction(self.calltipsAct) searchMenu = QMenu( QCoreApplication.translate('ViewManager', '&Search'), self.ui) searchMenu.setTearOffEnabled(True) searchMenu.addAction(self.quickSearchAct) searchMenu.addAction(self.quickSearchBackAct) searchMenu.addAction(self.searchAct) searchMenu.addAction(self.searchNextAct) searchMenu.addAction(self.searchPrevAct) searchMenu.addAction(self.searchNextWordAct) searchMenu.addAction(self.searchPrevWordAct) searchMenu.addAction(self.replaceAct) searchMenu.addSeparator() searchMenu.addAction(self.searchClearMarkersAct) searchMenu.addSeparator() searchMenu.addAction(self.searchFilesAct) searchMenu.addAction(self.replaceFilesAct) searchMenu.addSeparator() searchMenu.addAction(self.searchOpenFilesAct) searchMenu.addAction(self.replaceOpenFilesAct) menu = QMenu(QCoreApplication.translate('ViewManager', '&Edit'), self.ui) menu.setTearOffEnabled(True) menu.addAction(self.undoAct) menu.addAction(self.redoAct) menu.addAction(self.revertAct) menu.addSeparator() menu.addAction(self.cutAct) menu.addAction(self.copyAct) menu.addAction(self.pasteAct) menu.addAction(self.deleteAct) menu.addSeparator() menu.addAction(self.indentAct) menu.addAction(self.unindentAct) menu.addAction(self.smartIndentAct) menu.addSeparator() menu.addAction(self.commentAct) menu.addAction(self.uncommentAct) menu.addAction(self.toggleCommentAct) menu.addAction(self.streamCommentAct) menu.addAction(self.boxCommentAct) menu.addSeparator() menu.addAction(self.editUpperCaseAct) menu.addAction(self.editLowerCaseAct) menu.addAction(self.sortAct) menu.addSeparator() menu.addMenu(autocompletionMenu) menu.addSeparator() menu.addMenu(searchMenu) menu.addSeparator() menu.addAction(self.gotoAct) menu.addAction(self.gotoBraceAct) menu.addAction(self.gotoLastEditAct) menu.addAction(self.gotoPreviousDefAct) menu.addAction(self.gotoNextDefAct) menu.addSeparator() menu.addAction(self.selectBraceAct) menu.addAction(self.selectAllAct) menu.addAction(self.deselectAllAct) menu.addSeparator() menu.addAction(self.shortenEmptyAct) menu.addAction(self.convertEOLAct) return menu def initEditToolbar(self, toolbarManager): """ Public method to create the Edit toolbar. @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) @return the generated toolbar """ tb = QToolBar(QCoreApplication.translate('ViewManager', 'Edit'), self.ui) tb.setIconSize(UI.Config.ToolBarIconSize) tb.setObjectName("EditToolbar") tb.setToolTip(QCoreApplication.translate('ViewManager', 'Edit')) tb.addAction(self.undoAct) tb.addAction(self.redoAct) tb.addSeparator() tb.addAction(self.cutAct) tb.addAction(self.copyAct) tb.addAction(self.pasteAct) tb.addAction(self.deleteAct) tb.addSeparator() tb.addAction(self.commentAct) tb.addAction(self.uncommentAct) tb.addAction(self.toggleCommentAct) toolbarManager.addToolBar(tb, tb.windowTitle()) toolbarManager.addAction(self.smartIndentAct, tb.windowTitle()) toolbarManager.addAction(self.indentAct, tb.windowTitle()) toolbarManager.addAction(self.unindentAct, tb.windowTitle()) return tb ################################################################## ## Initialize the search related actions and the search toolbar ################################################################## def __initSearchActions(self): """ Private method defining the user interface actions for the search commands. """ self.searchActGrp = createActionGroup(self) self.searchAct = E5Action( QCoreApplication.translate('ViewManager', 'Search'), UI.PixmapCache.getIcon("find.png"), QCoreApplication.translate('ViewManager', '&Search...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+F", "Search|Search")), 0, self.searchActGrp, 'vm_search') self.searchAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search for a text')) self.searchAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Search""" """

Search for some text in the current editor. A""" """ dialog is shown to enter the searchtext and options""" """ for the search.

""" )) self.searchAct.triggered.connect(self.__search) self.searchActions.append(self.searchAct) self.searchNextAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Search next'), UI.PixmapCache.getIcon("findNext.png"), QCoreApplication.translate('ViewManager', 'Search &next'), QKeySequence(QCoreApplication.translate( 'ViewManager', "F3", "Search|Search next")), 0, self.searchActGrp, 'vm_search_next') self.searchNextAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search next occurrence of text')) self.searchNextAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Search next""" """

Search the next occurrence of some text in the current""" """ editor. The previously entered searchtext and options are""" """ reused.

""" )) self.searchNextAct.triggered.connect(self.__searchWidget.findNext) self.searchActions.append(self.searchNextAct) self.searchPrevAct = E5Action( QCoreApplication.translate('ViewManager', 'Search previous'), UI.PixmapCache.getIcon("findPrev.png"), QCoreApplication.translate('ViewManager', 'Search &previous'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Shift+F3", "Search|Search previous")), 0, self.searchActGrp, 'vm_search_previous') self.searchPrevAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search previous occurrence of text')) self.searchPrevAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Search previous""" """

Search the previous occurrence of some text in the current""" """ editor. The previously entered searchtext and options are""" """ reused.

""" )) self.searchPrevAct.triggered.connect(self.__searchWidget.findPrev) self.searchActions.append(self.searchPrevAct) self.searchClearMarkersAct = E5Action( QCoreApplication.translate('ViewManager', 'Clear search markers'), UI.PixmapCache.getIcon("findClear.png"), QCoreApplication.translate('ViewManager', 'Clear search markers'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+3", "Search|Clear search markers")), 0, self.searchActGrp, 'vm_clear_search_markers') self.searchClearMarkersAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Clear all displayed search markers')) self.searchClearMarkersAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Clear search markers""" """

Clear all displayed search markers.

""" )) self.searchClearMarkersAct.triggered.connect( self.__searchClearMarkers) self.searchActions.append(self.searchClearMarkersAct) self.searchNextWordAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Search current word forward'), UI.PixmapCache.getIcon("findWordNext.png"), QCoreApplication.translate( 'ViewManager', 'Search current word forward'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+.", "Search|Search current word forward")), 0, self.searchActGrp, 'vm_search_word_next') self.searchNextWordAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search next occurrence of the current word')) self.searchNextWordAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Search current word forward""" """

Search the next occurrence of the current word of the""" """ current editor.

""" )) self.searchNextWordAct.triggered.connect(self.__findNextWord) self.searchActions.append(self.searchNextWordAct) self.searchPrevWordAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Search current word backward'), UI.PixmapCache.getIcon("findWordPrev.png"), QCoreApplication.translate( 'ViewManager', 'Search current word backward'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+,", "Search|Search current word backward")), 0, self.searchActGrp, 'vm_search_word_previous') self.searchPrevWordAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search previous occurrence of the current word')) self.searchPrevWordAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Search current word backward""" """

Search the previous occurrence of the current word of the""" """ current editor.

""" )) self.searchPrevWordAct.triggered.connect(self.__findPrevWord) self.searchActions.append(self.searchPrevWordAct) self.replaceAct = E5Action( QCoreApplication.translate('ViewManager', 'Replace'), QCoreApplication.translate('ViewManager', '&Replace...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+R", "Search|Replace")), 0, self.searchActGrp, 'vm_search_replace') self.replaceAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Replace some text')) self.replaceAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Replace""" """

Search for some text in the current editor and replace it.""" """ A dialog is shown to enter the searchtext, the replacement""" """ text and options for the search and replace.

""" )) self.replaceAct.triggered.connect(self.__replace) self.searchActions.append(self.replaceAct) self.quickSearchAct = E5Action( QCoreApplication.translate('ViewManager', 'Quicksearch'), UI.PixmapCache.getIcon("quickFindNext.png"), QCoreApplication.translate('ViewManager', '&Quicksearch'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+K", "Search|Quicksearch")), 0, self.searchActGrp, 'vm_quicksearch') self.quickSearchAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Perform a quicksearch')) self.quickSearchAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Quicksearch""" """

This activates the quicksearch function of the IDE by""" """ giving focus to the quicksearch entry field. If this field""" """ is already active and contains text, it searches for the""" """ next occurrence of this text.

""" )) self.quickSearchAct.triggered.connect(self.__quickSearch) self.searchActions.append(self.quickSearchAct) self.quickSearchBackAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Quicksearch backwards'), UI.PixmapCache.getIcon("quickFindPrev.png"), QCoreApplication.translate( 'ViewManager', 'Quicksearch &backwards'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+J", "Search|Quicksearch backwards")), 0, self.searchActGrp, 'vm_quicksearch_backwards') self.quickSearchBackAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Perform a quicksearch backwards')) self.quickSearchBackAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Quicksearch backwards""" """

This searches the previous occurrence of the quicksearch""" """ text.

""" )) self.quickSearchBackAct.triggered.connect(self.__quickSearchPrev) self.searchActions.append(self.quickSearchBackAct) self.quickSearchExtendAct = E5Action( QCoreApplication.translate('ViewManager', 'Quicksearch extend'), UI.PixmapCache.getIcon("quickFindExtend.png"), QCoreApplication.translate('ViewManager', 'Quicksearch e&xtend'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+H", "Search|Quicksearch extend")), 0, self.searchActGrp, 'vm_quicksearch_extend') self.quickSearchExtendAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Extend the quicksearch to the end of the current word')) self.quickSearchExtendAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Quicksearch extend""" """

This extends the quicksearch text to the end of the word""" """ currently found.

""" )) self.quickSearchExtendAct.triggered.connect( self.__quickSearchExtend) self.searchActions.append(self.quickSearchExtendAct) self.gotoAct = E5Action( QCoreApplication.translate('ViewManager', 'Goto Line'), UI.PixmapCache.getIcon("goto.png"), QCoreApplication.translate('ViewManager', '&Goto Line...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+G", "Search|Goto Line")), 0, self.searchActGrp, 'vm_search_goto_line') self.gotoAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Goto Line')) self.gotoAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Goto Line""" """

Go to a specific line of text in the current editor.""" """ A dialog is shown to enter the linenumber.

""" )) self.gotoAct.triggered.connect(self.__goto) self.searchActions.append(self.gotoAct) self.gotoBraceAct = E5Action( QCoreApplication.translate('ViewManager', 'Goto Brace'), UI.PixmapCache.getIcon("gotoBrace.png"), QCoreApplication.translate('ViewManager', 'Goto &Brace'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+L", "Search|Goto Brace")), 0, self.searchActGrp, 'vm_search_goto_brace') self.gotoBraceAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Goto Brace')) self.gotoBraceAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Goto Brace""" """

Go to the matching brace in the current editor.

""" )) self.gotoBraceAct.triggered.connect(self.__gotoBrace) self.searchActions.append(self.gotoBraceAct) self.gotoLastEditAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Goto Last Edit Location'), UI.PixmapCache.getIcon("gotoLastEditPosition.png"), QCoreApplication.translate( 'ViewManager', 'Goto Last &Edit Location'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+G", "Search|Goto Last Edit Location")), 0, self.searchActGrp, 'vm_search_goto_last_edit_location') self.gotoLastEditAct.setStatusTip( QCoreApplication.translate( 'ViewManager', 'Goto Last Edit Location')) self.gotoLastEditAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Goto Last Edit Location""" """

Go to the location of the last edit in the current""" """ editor.

""" )) self.gotoLastEditAct.triggered.connect(self.__gotoLastEditPosition) self.searchActions.append(self.gotoLastEditAct) self.gotoPreviousDefAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Goto Previous Method or Class'), QCoreApplication.translate( 'ViewManager', 'Goto Previous Method or Class'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+Up", "Search|Goto Previous Method or Class")), 0, self.searchActGrp, 'vm_search_goto_previous_method_or_class') self.gotoPreviousDefAct.setStatusTip( QCoreApplication.translate( 'ViewManager', 'Go to the previous method or class definition')) self.gotoPreviousDefAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Goto Previous Method or Class""" """

Goes to the line of the previous method or class""" """ definition and highlights the name.

""" )) self.gotoPreviousDefAct.triggered.connect( self.__gotoPreviousMethodClass) self.searchActions.append(self.gotoPreviousDefAct) self.gotoNextDefAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Goto Next Method or Class'), QCoreApplication.translate( 'ViewManager', 'Goto Next Method or Class'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Shift+Down", "Search|Goto Next Method or Class")), 0, self.searchActGrp, 'vm_search_goto_next_method_or_class') self.gotoNextDefAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Go to the next method or class definition')) self.gotoNextDefAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Goto Next Method or Class""" """

Goes to the line of the next method or class definition""" """ and highlights the name.

""" )) self.gotoNextDefAct.triggered.connect(self.__gotoNextMethodClass) self.searchActions.append(self.gotoNextDefAct) self.searchActGrp.setEnabled(False) self.searchFilesAct = E5Action( QCoreApplication.translate('ViewManager', 'Search in Files'), UI.PixmapCache.getIcon("projectFind.png"), QCoreApplication.translate('ViewManager', 'Search in &Files...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Shift+Ctrl+F", "Search|Search Files")), 0, self, 'vm_search_in_files') self.searchFilesAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search for a text in files')) self.searchFilesAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Search in Files""" """

Search for some text in the files of a directory tree""" """ or the project. A dialog is shown to enter the searchtext""" """ and options for the search and to display the result.

""" )) self.searchFilesAct.triggered.connect(self.__searchFiles) self.searchActions.append(self.searchFilesAct) self.replaceFilesAct = E5Action( QCoreApplication.translate('ViewManager', 'Replace in Files'), QCoreApplication.translate('ViewManager', 'Replace in F&iles...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Shift+Ctrl+R", "Search|Replace in Files")), 0, self, 'vm_replace_in_files') self.replaceFilesAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search for a text in files and replace it')) self.replaceFilesAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Replace in Files""" """

Search for some text in the files of a directory tree""" """ or the project and replace it. A dialog is shown to enter""" """ the searchtext, the replacement text and options for the""" """ search and to display the result.

""" )) self.replaceFilesAct.triggered.connect(self.__replaceFiles) self.searchActions.append(self.replaceFilesAct) self.searchOpenFilesAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Search in Open Files'), UI.PixmapCache.getIcon("documentFind.png"), QCoreApplication.translate( 'ViewManager', 'Search in Open Files...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Meta+Ctrl+Alt+F", "Search|Search Open Files")), 0, self.searchActGrp, 'vm_search_in_open_files') self.searchOpenFilesAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search for a text in open files')) self.searchOpenFilesAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Search in Open Files""" """

Search for some text in the currently opened files.""" """ A dialog is shown to enter the searchtext""" """ and options for the search and to display the result.

""" )) self.searchOpenFilesAct.triggered.connect(self.__searchOpenFiles) self.searchActions.append(self.searchOpenFilesAct) self.replaceOpenFilesAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Replace in Open Files'), QCoreApplication.translate( 'ViewManager', 'Replace in Open Files...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Meta+Ctrl+Alt+R", "Search|Replace in Open Files")), 0, self.searchActGrp, 'vm_replace_in_open_files') self.replaceOpenFilesAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Search for a text in open files and replace it')) self.replaceOpenFilesAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Replace in Open Files""" """

Search for some text in the currently opened files""" """ and replace it. A dialog is shown to enter""" """ the searchtext, the replacement text and options for the""" """ search and to display the result.

""" )) self.replaceOpenFilesAct.triggered.connect(self.__replaceOpenFiles) self.searchActions.append(self.replaceOpenFilesAct) def initSearchToolbars(self, toolbarManager): """ Public method to create the Search toolbars. @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) @return a tuple of the generated toolbar (search, quicksearch) """ qtb = QToolBar(QCoreApplication.translate( 'ViewManager', 'Quicksearch'), self.ui) qtb.setIconSize(UI.Config.ToolBarIconSize) qtb.setObjectName("QuicksearchToolbar") qtb.setToolTip(QCoreApplication.translate( 'ViewManager', 'Quicksearch')) self.quickFindLineEdit = QuickSearchLineEdit(self) self.quickFindtextCombo = QComboBox(self) self.quickFindtextCombo.setEditable(True) self.quickFindtextCombo.setLineEdit(self.quickFindLineEdit) self.quickFindtextCombo.setDuplicatesEnabled(False) self.quickFindtextCombo.setInsertPolicy(QComboBox.InsertAtTop) self.quickFindtextCombo.lastActive = None self.quickFindtextCombo.lastCursorPos = None self.quickFindtextCombo.leForegroundColor = \ self.quickFindtextCombo.lineEdit().palette().color(QPalette.Text) self.quickFindtextCombo.leBackgroundColor = \ self.quickFindtextCombo.lineEdit().palette().color(QPalette.Base) self.quickFindtextCombo.lastSearchText = "" self.quickFindtextCombo._editor = self.quickFindtextCombo.lineEdit() # this allows us not to jump across searched text # just because of autocompletion enabled self.quickFindtextCombo.setMinimumWidth(250) self.quickFindtextCombo.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) self.quickFindtextCombo.addItem("") self.quickFindtextCombo.setWhatsThis(QCoreApplication.translate( 'ViewManager', """

Enter the searchtext directly into this field.""" """ The search will be performed case insensitive.""" """ The quicksearch function is activated upon activation""" """ of the quicksearch next action (default key Ctrl+Shift+K),""" """ if this entry field does not have the input focus.""" """ Otherwise it searches for the next occurrence of the""" """ text entered. The quicksearch backwards action""" """ (default key Ctrl+Shift+J) searches backward.""" """ Activating the 'quicksearch extend' action""" """ (default key Ctrl+Shift+H) extends the current""" """ searchtext to the end of the currently found word.""" """ The quicksearch can be ended by pressing the Return key""" """ while the quicksearch entry has the the input focus.

""" )) self.quickFindtextCombo._editor.returnPressed.connect( self.__quickSearchEnter) self.quickFindtextCombo._editor.textChanged.connect( self.__quickSearchText) self.quickFindtextCombo._editor.escPressed.connect( self.__quickSearchEscape) self.quickFindtextCombo._editor.gotFocus.connect( self.__quickSearchFocusIn) self.quickFindtextAction = QWidgetAction(self) self.quickFindtextAction.setDefaultWidget(self.quickFindtextCombo) self.quickFindtextAction.setObjectName("vm_quickfindtext_action") self.quickFindtextAction.setText(self.tr("Quicksearch Textedit")) qtb.addAction(self.quickFindtextAction) qtb.addAction(self.quickSearchAct) qtb.addAction(self.quickSearchBackAct) qtb.addAction(self.quickSearchExtendAct) self.quickFindtextCombo.setEnabled(False) self.__quickSearchToolbar = qtb self.__quickSearchToolbarVisibility = None tb = QToolBar(QCoreApplication.translate('ViewManager', 'Search'), self.ui) tb.setIconSize(UI.Config.ToolBarIconSize) tb.setObjectName("SearchToolbar") tb.setToolTip(QCoreApplication.translate('ViewManager', 'Search')) tb.addAction(self.searchAct) tb.addAction(self.searchNextAct) tb.addAction(self.searchPrevAct) tb.addAction(self.searchNextWordAct) tb.addAction(self.searchPrevWordAct) tb.addSeparator() tb.addAction(self.searchClearMarkersAct) tb.addSeparator() tb.addAction(self.searchFilesAct) tb.addAction(self.searchOpenFilesAct) tb.addSeparator() tb.addAction(self.gotoLastEditAct) tb.setAllowedAreas( Qt.ToolBarAreas(Qt.TopToolBarArea | Qt.BottomToolBarArea)) toolbarManager.addToolBar(qtb, qtb.windowTitle()) toolbarManager.addToolBar(tb, tb.windowTitle()) toolbarManager.addAction(self.gotoAct, tb.windowTitle()) toolbarManager.addAction(self.gotoBraceAct, tb.windowTitle()) return tb, qtb ################################################################## ## Initialize the view related actions, view menu and toolbar ################################################################## def __initViewActions(self): """ Private method defining the user interface actions for the view commands. """ self.viewActGrp = createActionGroup(self) self.viewFoldActGrp = createActionGroup(self) self.zoomInAct = E5Action( QCoreApplication.translate('ViewManager', 'Zoom in'), UI.PixmapCache.getIcon("zoomIn.png"), QCoreApplication.translate('ViewManager', 'Zoom &in'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl++", "View|Zoom in")), QKeySequence(QCoreApplication.translate( 'ViewManager', "Zoom In", "View|Zoom in")), self.viewActGrp, 'vm_view_zoom_in') self.zoomInAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Zoom in on the text')) self.zoomInAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Zoom in""" """

Zoom in on the text. This makes the text bigger.

""" )) self.zoomInAct.triggered.connect(self.__zoomIn) self.viewActions.append(self.zoomInAct) self.zoomOutAct = E5Action( QCoreApplication.translate('ViewManager', 'Zoom out'), UI.PixmapCache.getIcon("zoomOut.png"), QCoreApplication.translate('ViewManager', 'Zoom &out'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+-", "View|Zoom out")), QKeySequence(QCoreApplication.translate( 'ViewManager', "Zoom Out", "View|Zoom out")), self.viewActGrp, 'vm_view_zoom_out') self.zoomOutAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Zoom out on the text')) self.zoomOutAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Zoom out""" """

Zoom out on the text. This makes the text smaller.

""" )) self.zoomOutAct.triggered.connect(self.__zoomOut) self.viewActions.append(self.zoomOutAct) self.zoomResetAct = E5Action( QCoreApplication.translate('ViewManager', 'Zoom reset'), UI.PixmapCache.getIcon("zoomReset.png"), QCoreApplication.translate('ViewManager', 'Zoom &reset'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+0", "View|Zoom reset")), 0, self.viewActGrp, 'vm_view_zoom_reset') self.zoomResetAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Reset the zoom of the text')) self.zoomResetAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Zoom reset""" """

Reset the zoom of the text. """ """This sets the zoom factor to 100%.

""" )) self.zoomResetAct.triggered.connect(self.__zoomReset) self.viewActions.append(self.zoomResetAct) self.zoomToAct = E5Action( QCoreApplication.translate('ViewManager', 'Zoom'), UI.PixmapCache.getIcon("zoomTo.png"), QCoreApplication.translate('ViewManager', '&Zoom'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+#", "View|Zoom")), 0, self.viewActGrp, 'vm_view_zoom') self.zoomToAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Zoom the text')) self.zoomToAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Zoom""" """

Zoom the text. This opens a dialog where the""" """ desired size can be entered.

""" )) self.zoomToAct.triggered.connect(self.__zoom) self.viewActions.append(self.zoomToAct) self.toggleAllAct = E5Action( QCoreApplication.translate('ViewManager', 'Toggle all folds'), QCoreApplication.translate('ViewManager', 'Toggle &all folds'), 0, 0, self.viewFoldActGrp, 'vm_view_toggle_all_folds') self.toggleAllAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Toggle all folds')) self.toggleAllAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Toggle all folds""" """

Toggle all folds of the current editor.

""" )) self.toggleAllAct.triggered.connect(self.__toggleAll) self.viewActions.append(self.toggleAllAct) self.toggleAllChildrenAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Toggle all folds (including children)'), QCoreApplication.translate( 'ViewManager', 'Toggle all &folds (including children)'), 0, 0, self.viewFoldActGrp, 'vm_view_toggle_all_folds_children') self.toggleAllChildrenAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Toggle all folds (including children)')) self.toggleAllChildrenAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Toggle all folds (including children)""" """

Toggle all folds of the current editor including""" """ all children.

""" )) self.toggleAllChildrenAct.triggered.connect( self.__toggleAllChildren) self.viewActions.append(self.toggleAllChildrenAct) self.toggleCurrentAct = E5Action( QCoreApplication.translate('ViewManager', 'Toggle current fold'), QCoreApplication.translate('ViewManager', 'Toggle ¤t fold'), 0, 0, self.viewFoldActGrp, 'vm_view_toggle_current_fold') self.toggleCurrentAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Toggle current fold')) self.toggleCurrentAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Toggle current fold""" """

Toggle the folds of the current line of the current""" """ editor.

""" )) self.toggleCurrentAct.triggered.connect(self.__toggleCurrent) self.viewActions.append(self.toggleCurrentAct) self.unhighlightAct = E5Action( QCoreApplication.translate('ViewManager', 'Remove all highlights'), UI.PixmapCache.getIcon("unhighlight.png"), QCoreApplication.translate('ViewManager', 'Remove all highlights'), 0, 0, self, 'vm_view_unhighlight') self.unhighlightAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Remove all highlights')) self.unhighlightAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Remove all highlights""" """

Remove the highlights of all editors.

""" )) self.unhighlightAct.triggered.connect(self.__unhighlight) self.viewActions.append(self.unhighlightAct) self.newDocumentViewAct = E5Action( QCoreApplication.translate('ViewManager', 'New Document View'), UI.PixmapCache.getIcon("documentNewView.png"), QCoreApplication.translate('ViewManager', 'New &Document View'), 0, 0, self, 'vm_view_new_document_view') self.newDocumentViewAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Open a new view of the current document')) self.newDocumentViewAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """New Document View""" """

Opens a new view of the current document. Both views show""" """ the same document. However, the cursors may be positioned""" """ independently.

""" )) self.newDocumentViewAct.triggered.connect(self.__newDocumentView) self.viewActions.append(self.newDocumentViewAct) self.newDocumentSplitViewAct = E5Action( QCoreApplication.translate( 'ViewManager', 'New Document View (with new split)'), UI.PixmapCache.getIcon("splitVertical.png"), QCoreApplication.translate( 'ViewManager', 'New Document View (with new split)'), 0, 0, self, 'vm_view_new_document_split_view') self.newDocumentSplitViewAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Open a new view of the current document in a new split')) self.newDocumentSplitViewAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """New Document View""" """

Opens a new view of the current document in a new split.""" """ Both views show the same document. However, the cursors may""" """ be positioned independently.

""" )) self.newDocumentSplitViewAct.triggered.connect( self.__newDocumentSplitView) self.viewActions.append(self.newDocumentSplitViewAct) self.splitViewAct = E5Action( QCoreApplication.translate('ViewManager', 'Split view'), UI.PixmapCache.getIcon("splitVertical.png"), QCoreApplication.translate('ViewManager', '&Split view'), 0, 0, self, 'vm_view_split_view') self.splitViewAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Add a split to the view')) self.splitViewAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Split view""" """

Add a split to the view.

""" )) self.splitViewAct.triggered.connect(self.__splitView) self.viewActions.append(self.splitViewAct) self.splitOrientationAct = E5Action( QCoreApplication.translate('ViewManager', 'Arrange horizontally'), QCoreApplication.translate('ViewManager', 'Arrange &horizontally'), 0, 0, self, 'vm_view_arrange_horizontally', True) self.splitOrientationAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Arrange the splitted views horizontally')) self.splitOrientationAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Arrange horizontally""" """

Arrange the splitted views horizontally.

""" )) self.splitOrientationAct.setChecked(False) self.splitOrientationAct.toggled[bool].connect(self.__splitOrientation) self.viewActions.append(self.splitOrientationAct) self.splitRemoveAct = E5Action( QCoreApplication.translate('ViewManager', 'Remove split'), UI.PixmapCache.getIcon("remsplitVertical.png"), QCoreApplication.translate('ViewManager', '&Remove split'), 0, 0, self, 'vm_view_remove_split') self.splitRemoveAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Remove the current split')) self.splitRemoveAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Remove split""" """

Remove the current split.

""" )) self.splitRemoveAct.triggered.connect(self.removeSplit) self.viewActions.append(self.splitRemoveAct) self.nextSplitAct = E5Action( QCoreApplication.translate('ViewManager', 'Next split'), QCoreApplication.translate('ViewManager', '&Next split'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Alt+N", "View|Next split")), 0, self, 'vm_next_split') self.nextSplitAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Move to the next split')) self.nextSplitAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Next split""" """

Move to the next split.

""" )) self.nextSplitAct.triggered.connect(self.nextSplit) self.viewActions.append(self.nextSplitAct) self.prevSplitAct = E5Action( QCoreApplication.translate('ViewManager', 'Previous split'), QCoreApplication.translate('ViewManager', '&Previous split'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+Alt+P", "View|Previous split")), 0, self, 'vm_previous_split') self.prevSplitAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Move to the previous split')) self.prevSplitAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Previous split""" """

Move to the previous split.

""" )) self.prevSplitAct.triggered.connect(self.prevSplit) self.viewActions.append(self.prevSplitAct) self.previewAct = E5Action( QCoreApplication.translate('ViewManager', 'Preview'), UI.PixmapCache.getIcon("previewer.png"), QCoreApplication.translate('ViewManager', 'Preview'), 0, 0, self, 'vm_preview', True) self.previewAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Preview the current file in the web browser')) self.previewAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Preview""" """

This opens the web browser with a preview of""" """ the current file.

""" )) self.previewAct.setChecked(Preferences.getUI("ShowFilePreview")) self.previewAct.toggled[bool].connect(self.__previewEditor) self.viewActions.append(self.previewAct) self.viewActGrp.setEnabled(False) self.viewFoldActGrp.setEnabled(False) self.unhighlightAct.setEnabled(False) self.splitViewAct.setEnabled(False) self.splitOrientationAct.setEnabled(False) self.splitRemoveAct.setEnabled(False) self.nextSplitAct.setEnabled(False) self.prevSplitAct.setEnabled(False) self.previewAct.setEnabled(True) self.splitOrientationAct.setChecked( Preferences.getUI("SplitOrientationVertical")) def initViewMenu(self): """ Public method to create the View menu. @return the generated menu """ menu = QMenu(QCoreApplication.translate('ViewManager', '&View'), self.ui) menu.setTearOffEnabled(True) menu.addActions(self.viewActGrp.actions()) menu.addSeparator() menu.addActions(self.viewFoldActGrp.actions()) menu.addSeparator() menu.addAction(self.previewAct) menu.addSeparator() menu.addAction(self.unhighlightAct) menu.addSeparator() menu.addAction(self.newDocumentViewAct) if self.canSplit(): menu.addAction(self.newDocumentSplitViewAct) menu.addSeparator() menu.addAction(self.splitViewAct) menu.addAction(self.splitOrientationAct) menu.addAction(self.splitRemoveAct) menu.addAction(self.nextSplitAct) menu.addAction(self.prevSplitAct) return menu def initViewToolbar(self, toolbarManager): """ Public method to create the View toolbar. @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) @return the generated toolbar """ tb = QToolBar(QCoreApplication.translate('ViewManager', 'View'), self.ui) tb.setIconSize(UI.Config.ToolBarIconSize) tb.setObjectName("ViewToolbar") tb.setToolTip(QCoreApplication.translate('ViewManager', 'View')) tb.addActions(self.viewActGrp.actions()) tb.addSeparator() tb.addAction(self.previewAct) tb.addSeparator() tb.addAction(self.newDocumentViewAct) if self.canSplit(): tb.addAction(self.newDocumentSplitViewAct) toolbarManager.addToolBar(tb, tb.windowTitle()) toolbarManager.addAction(self.unhighlightAct, tb.windowTitle()) toolbarManager.addAction(self.splitViewAct, tb.windowTitle()) toolbarManager.addAction(self.splitRemoveAct, tb.windowTitle()) return tb ################################################################## ## Initialize the macro related actions and macro menu ################################################################## def __initMacroActions(self): """ Private method defining the user interface actions for the macro commands. """ self.macroActGrp = createActionGroup(self) self.macroStartRecAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Start Macro Recording'), QCoreApplication.translate( 'ViewManager', 'S&tart Macro Recording'), 0, 0, self.macroActGrp, 'vm_macro_start_recording') self.macroStartRecAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Start Macro Recording')) self.macroStartRecAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Start Macro Recording""" """

Start recording editor commands into a new macro.

""" )) self.macroStartRecAct.triggered.connect(self.__macroStartRecording) self.macroActions.append(self.macroStartRecAct) self.macroStopRecAct = E5Action( QCoreApplication.translate('ViewManager', 'Stop Macro Recording'), QCoreApplication.translate('ViewManager', 'Sto&p Macro Recording'), 0, 0, self.macroActGrp, 'vm_macro_stop_recording') self.macroStopRecAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Stop Macro Recording')) self.macroStopRecAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Stop Macro Recording""" """

Stop recording editor commands into a new macro.

""" )) self.macroStopRecAct.triggered.connect(self.__macroStopRecording) self.macroActions.append(self.macroStopRecAct) self.macroRunAct = E5Action( QCoreApplication.translate('ViewManager', 'Run Macro'), QCoreApplication.translate('ViewManager', '&Run Macro'), 0, 0, self.macroActGrp, 'vm_macro_run') self.macroRunAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Run Macro')) self.macroRunAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Run Macro""" """

Run a previously recorded editor macro.

""" )) self.macroRunAct.triggered.connect(self.__macroRun) self.macroActions.append(self.macroRunAct) self.macroDeleteAct = E5Action( QCoreApplication.translate('ViewManager', 'Delete Macro'), QCoreApplication.translate('ViewManager', '&Delete Macro'), 0, 0, self.macroActGrp, 'vm_macro_delete') self.macroDeleteAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Delete Macro')) self.macroDeleteAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Delete Macro""" """

Delete a previously recorded editor macro.

""" )) self.macroDeleteAct.triggered.connect(self.__macroDelete) self.macroActions.append(self.macroDeleteAct) self.macroLoadAct = E5Action( QCoreApplication.translate('ViewManager', 'Load Macro'), QCoreApplication.translate('ViewManager', '&Load Macro'), 0, 0, self.macroActGrp, 'vm_macro_load') self.macroLoadAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Load Macro')) self.macroLoadAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Load Macro""" """

Load an editor macro from a file.

""" )) self.macroLoadAct.triggered.connect(self.__macroLoad) self.macroActions.append(self.macroLoadAct) self.macroSaveAct = E5Action( QCoreApplication.translate('ViewManager', 'Save Macro'), QCoreApplication.translate('ViewManager', '&Save Macro'), 0, 0, self.macroActGrp, 'vm_macro_save') self.macroSaveAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Save Macro')) self.macroSaveAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Save Macro""" """

Save a previously recorded editor macro to a file.

""" )) self.macroSaveAct.triggered.connect(self.__macroSave) self.macroActions.append(self.macroSaveAct) self.macroActGrp.setEnabled(False) def initMacroMenu(self): """ Public method to create the Macro menu. @return the generated menu """ menu = QMenu(QCoreApplication.translate('ViewManager', "&Macros"), self.ui) menu.setTearOffEnabled(True) menu.addActions(self.macroActGrp.actions()) return menu ##################################################################### ## Initialize the bookmark related actions, bookmark menu and toolbar ##################################################################### def __initBookmarkActions(self): """ Private method defining the user interface actions for the bookmarks commands. """ self.bookmarkActGrp = createActionGroup(self) self.bookmarkToggleAct = E5Action( QCoreApplication.translate('ViewManager', 'Toggle Bookmark'), UI.PixmapCache.getIcon("bookmarkToggle.png"), QCoreApplication.translate('ViewManager', '&Toggle Bookmark'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Alt+Ctrl+T", "Bookmark|Toggle")), 0, self.bookmarkActGrp, 'vm_bookmark_toggle') self.bookmarkToggleAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Toggle Bookmark')) self.bookmarkToggleAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Toggle Bookmark""" """

Toggle a bookmark at the current line of the current""" """ editor.

""" )) self.bookmarkToggleAct.triggered.connect(self.__toggleBookmark) self.bookmarkActions.append(self.bookmarkToggleAct) self.bookmarkNextAct = E5Action( QCoreApplication.translate('ViewManager', 'Next Bookmark'), UI.PixmapCache.getIcon("bookmarkNext.png"), QCoreApplication.translate('ViewManager', '&Next Bookmark'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+PgDown", "Bookmark|Next")), 0, self.bookmarkActGrp, 'vm_bookmark_next') self.bookmarkNextAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Next Bookmark')) self.bookmarkNextAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Next Bookmark""" """

Go to next bookmark of the current editor.

""" )) self.bookmarkNextAct.triggered.connect(self.__nextBookmark) self.bookmarkActions.append(self.bookmarkNextAct) self.bookmarkPreviousAct = E5Action( QCoreApplication.translate('ViewManager', 'Previous Bookmark'), UI.PixmapCache.getIcon("bookmarkPrevious.png"), QCoreApplication.translate('ViewManager', '&Previous Bookmark'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Ctrl+PgUp", "Bookmark|Previous")), 0, self.bookmarkActGrp, 'vm_bookmark_previous') self.bookmarkPreviousAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Previous Bookmark')) self.bookmarkPreviousAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Previous Bookmark""" """

Go to previous bookmark of the current editor.

""" )) self.bookmarkPreviousAct.triggered.connect(self.__previousBookmark) self.bookmarkActions.append(self.bookmarkPreviousAct) self.bookmarkClearAct = E5Action( QCoreApplication.translate('ViewManager', 'Clear Bookmarks'), QCoreApplication.translate('ViewManager', '&Clear Bookmarks'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Alt+Ctrl+C", "Bookmark|Clear")), 0, self.bookmarkActGrp, 'vm_bookmark_clear') self.bookmarkClearAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Clear Bookmarks')) self.bookmarkClearAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Clear Bookmarks""" """

Clear bookmarks of all editors.

""" )) self.bookmarkClearAct.triggered.connect(self.__clearAllBookmarks) self.bookmarkActions.append(self.bookmarkClearAct) self.syntaxErrorGotoAct = E5Action( QCoreApplication.translate('ViewManager', 'Goto Syntax Error'), UI.PixmapCache.getIcon("syntaxErrorGoto.png"), QCoreApplication.translate('ViewManager', '&Goto Syntax Error'), 0, 0, self.bookmarkActGrp, 'vm_syntaxerror_goto') self.syntaxErrorGotoAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Goto Syntax Error')) self.syntaxErrorGotoAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Goto Syntax Error""" """

Go to next syntax error of the current editor.

""" )) self.syntaxErrorGotoAct.triggered.connect(self.__gotoSyntaxError) self.bookmarkActions.append(self.syntaxErrorGotoAct) self.syntaxErrorClearAct = E5Action( QCoreApplication.translate('ViewManager', 'Clear Syntax Errors'), QCoreApplication.translate('ViewManager', 'Clear &Syntax Errors'), 0, 0, self.bookmarkActGrp, 'vm_syntaxerror_clear') self.syntaxErrorClearAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Clear Syntax Errors')) self.syntaxErrorClearAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Clear Syntax Errors""" """

Clear syntax errors of all editors.

""" )) self.syntaxErrorClearAct.triggered.connect( self.__clearAllSyntaxErrors) self.bookmarkActions.append(self.syntaxErrorClearAct) self.warningsNextAct = E5Action( QCoreApplication.translate('ViewManager', 'Next warning message'), UI.PixmapCache.getIcon("warningNext.png"), QCoreApplication.translate('ViewManager', '&Next warning message'), 0, 0, self.bookmarkActGrp, 'vm_warning_next') self.warningsNextAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Next warning message')) self.warningsNextAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Next warning message""" """

Go to next line of the current editor""" """ having a pyflakes warning.

""" )) self.warningsNextAct.triggered.connect(self.__nextWarning) self.bookmarkActions.append(self.warningsNextAct) self.warningsPreviousAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Previous warning message'), UI.PixmapCache.getIcon("warningPrev.png"), QCoreApplication.translate( 'ViewManager', '&Previous warning message'), 0, 0, self.bookmarkActGrp, 'vm_warning_previous') self.warningsPreviousAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Previous warning message')) self.warningsPreviousAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Previous warning message""" """

Go to previous line of the current editor""" """ having a pyflakes warning.

""" )) self.warningsPreviousAct.triggered.connect(self.__previousWarning) self.bookmarkActions.append(self.warningsPreviousAct) self.warningsClearAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Clear Warning Messages'), QCoreApplication.translate( 'ViewManager', 'Clear &Warning Messages'), 0, 0, self.bookmarkActGrp, 'vm_warnings_clear') self.warningsClearAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Clear Warning Messages')) self.warningsClearAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Clear Warning Messages""" """

Clear pyflakes warning messages of all editors.

""" )) self.warningsClearAct.triggered.connect(self.__clearAllWarnings) self.bookmarkActions.append(self.warningsClearAct) self.notcoveredNextAct = E5Action( QCoreApplication.translate('ViewManager', 'Next uncovered line'), UI.PixmapCache.getIcon("notcoveredNext.png"), QCoreApplication.translate('ViewManager', '&Next uncovered line'), 0, 0, self.bookmarkActGrp, 'vm_uncovered_next') self.notcoveredNextAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Next uncovered line')) self.notcoveredNextAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Next uncovered line""" """

Go to next line of the current editor marked as not""" """ covered.

""" )) self.notcoveredNextAct.triggered.connect(self.__nextUncovered) self.bookmarkActions.append(self.notcoveredNextAct) self.notcoveredPreviousAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Previous uncovered line'), UI.PixmapCache.getIcon("notcoveredPrev.png"), QCoreApplication.translate( 'ViewManager', '&Previous uncovered line'), 0, 0, self.bookmarkActGrp, 'vm_uncovered_previous') self.notcoveredPreviousAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Previous uncovered line')) self.notcoveredPreviousAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Previous uncovered line""" """

Go to previous line of the current editor marked""" """ as not covered.

""" )) self.notcoveredPreviousAct.triggered.connect( self.__previousUncovered) self.bookmarkActions.append(self.notcoveredPreviousAct) self.taskNextAct = E5Action( QCoreApplication.translate('ViewManager', 'Next Task'), UI.PixmapCache.getIcon("taskNext.png"), QCoreApplication.translate('ViewManager', '&Next Task'), 0, 0, self.bookmarkActGrp, 'vm_task_next') self.taskNextAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Next Task')) self.taskNextAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Next Task""" """

Go to next line of the current editor having a task.

""" )) self.taskNextAct.triggered.connect(self.__nextTask) self.bookmarkActions.append(self.taskNextAct) self.taskPreviousAct = E5Action( QCoreApplication.translate('ViewManager', 'Previous Task'), UI.PixmapCache.getIcon("taskPrev.png"), QCoreApplication.translate( 'ViewManager', '&Previous Task'), 0, 0, self.bookmarkActGrp, 'vm_task_previous') self.taskPreviousAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Previous Task')) self.taskPreviousAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Previous Task""" """

Go to previous line of the current editor having a""" """ task.

""" )) self.taskPreviousAct.triggered.connect(self.__previousTask) self.bookmarkActions.append(self.taskPreviousAct) self.changeNextAct = E5Action( QCoreApplication.translate('ViewManager', 'Next Change'), UI.PixmapCache.getIcon("changeNext.png"), QCoreApplication.translate('ViewManager', '&Next Change'), 0, 0, self.bookmarkActGrp, 'vm_change_next') self.changeNextAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Next Change')) self.changeNextAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Next Change""" """

Go to next line of the current editor having a change""" """ marker.

""" )) self.changeNextAct.triggered.connect(self.__nextChange) self.bookmarkActions.append(self.changeNextAct) self.changePreviousAct = E5Action( QCoreApplication.translate('ViewManager', 'Previous Change'), UI.PixmapCache.getIcon("changePrev.png"), QCoreApplication.translate( 'ViewManager', '&Previous Change'), 0, 0, self.bookmarkActGrp, 'vm_change_previous') self.changePreviousAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Previous Change')) self.changePreviousAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Previous Change""" """

Go to previous line of the current editor having""" """ a change marker.

""" )) self.changePreviousAct.triggered.connect(self.__previousChange) self.bookmarkActions.append(self.changePreviousAct) self.bookmarkActGrp.setEnabled(False) def initBookmarkMenu(self): """ Public method to create the Bookmark menu. @return the generated menu """ menu = QMenu(QCoreApplication.translate('ViewManager', '&Bookmarks'), self.ui) self.bookmarksMenu = QMenu( QCoreApplication.translate('ViewManager', '&Bookmarks'), menu) menu.setTearOffEnabled(True) menu.addAction(self.bookmarkToggleAct) menu.addAction(self.bookmarkNextAct) menu.addAction(self.bookmarkPreviousAct) menu.addAction(self.bookmarkClearAct) menu.addSeparator() self.menuBookmarksAct = menu.addMenu(self.bookmarksMenu) menu.addSeparator() menu.addAction(self.syntaxErrorGotoAct) menu.addAction(self.syntaxErrorClearAct) menu.addSeparator() menu.addAction(self.warningsNextAct) menu.addAction(self.warningsPreviousAct) menu.addAction(self.warningsClearAct) menu.addSeparator() menu.addAction(self.notcoveredNextAct) menu.addAction(self.notcoveredPreviousAct) menu.addSeparator() menu.addAction(self.taskNextAct) menu.addAction(self.taskPreviousAct) menu.addSeparator() menu.addAction(self.changeNextAct) menu.addAction(self.changePreviousAct) self.bookmarksMenu.aboutToShow.connect(self.__showBookmarksMenu) self.bookmarksMenu.triggered.connect(self.__bookmarkSelected) menu.aboutToShow.connect(self.__showBookmarkMenu) return menu def initBookmarkToolbar(self, toolbarManager): """ Public method to create the Bookmark toolbar. @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) @return the generated toolbar """ tb = QToolBar(QCoreApplication.translate('ViewManager', 'Bookmarks'), self.ui) tb.setIconSize(UI.Config.ToolBarIconSize) tb.setObjectName("BookmarksToolbar") tb.setToolTip(QCoreApplication.translate('ViewManager', 'Bookmarks')) tb.addAction(self.bookmarkToggleAct) tb.addAction(self.bookmarkNextAct) tb.addAction(self.bookmarkPreviousAct) tb.addSeparator() tb.addAction(self.syntaxErrorGotoAct) tb.addSeparator() tb.addAction(self.warningsNextAct) tb.addAction(self.warningsPreviousAct) tb.addSeparator() tb.addAction(self.taskNextAct) tb.addAction(self.taskPreviousAct) tb.addSeparator() tb.addAction(self.changeNextAct) tb.addAction(self.changePreviousAct) toolbarManager.addToolBar(tb, tb.windowTitle()) toolbarManager.addAction(self.notcoveredNextAct, tb.windowTitle()) toolbarManager.addAction(self.notcoveredPreviousAct, tb.windowTitle()) return tb ################################################################## ## Initialize the spell checking related actions ################################################################## def __initSpellingActions(self): """ Private method to initialize the spell checking actions. """ self.spellingActGrp = createActionGroup(self) self.spellCheckAct = E5Action( QCoreApplication.translate('ViewManager', 'Check spelling'), UI.PixmapCache.getIcon("spellchecking.png"), QCoreApplication.translate( 'ViewManager', 'Check &spelling...'), QKeySequence(QCoreApplication.translate( 'ViewManager', "Shift+F7", "Spelling|Spell Check")), 0, self.spellingActGrp, 'vm_spelling_spellcheck') self.spellCheckAct.setStatusTip(QCoreApplication.translate( 'ViewManager', 'Perform spell check of current editor')) self.spellCheckAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Check spelling""" """

Perform a spell check of the current editor.

""" )) self.spellCheckAct.triggered.connect(self.__spellCheck) self.spellingActions.append(self.spellCheckAct) self.autoSpellCheckAct = E5Action( QCoreApplication.translate( 'ViewManager', 'Automatic spell checking'), UI.PixmapCache.getIcon("autospellchecking.png"), QCoreApplication.translate( 'ViewManager', '&Automatic spell checking'), 0, 0, self.spellingActGrp, 'vm_spelling_autospellcheck', True) self.autoSpellCheckAct.setStatusTip(QCoreApplication.translate( 'ViewManager', '(De-)Activate automatic spell checking')) self.autoSpellCheckAct.setWhatsThis(QCoreApplication.translate( 'ViewManager', """Automatic spell checking""" """

Activate or deactivate the automatic spell checking""" """ function of all editors.

""" )) self.autoSpellCheckAct.setChecked( Preferences.getEditor("AutoSpellCheckingEnabled")) self.autoSpellCheckAct.triggered.connect( self.__setAutoSpellChecking) self.spellingActions.append(self.autoSpellCheckAct) self.__enableSpellingActions() def __enableSpellingActions(self): """ Private method to set the enabled state of the spelling actions. """ from QScintilla.SpellChecker import SpellChecker spellingAvailable = SpellChecker.isAvailable() self.spellCheckAct.setEnabled( len(self.editors) != 0 and spellingAvailable) self.autoSpellCheckAct.setEnabled(spellingAvailable) def addToExtrasMenu(self, menu): """ Public method to add some actions to the extras menu. @param menu reference to the menu to add actions to (QMenu) """ self.__editSpellingMenu = QMenu(QCoreApplication.translate( 'ViewManager', "Edit Dictionary")) self.__editProjectPwlAct = self.__editSpellingMenu.addAction( QCoreApplication.translate('ViewManager', "Project Word List"), self.__editProjectPWL) self.__editProjectPelAct = self.__editSpellingMenu.addAction( QCoreApplication.translate( 'ViewManager', "Project Exception List"), self.__editProjectPEL) self.__editSpellingMenu.addSeparator() self.__editUserPwlAct = self.__editSpellingMenu.addAction( QCoreApplication.translate('ViewManager', "User Word List"), self.__editUserPWL) self.__editUserPelAct = self.__editSpellingMenu.addAction( QCoreApplication.translate('ViewManager', "User Exception List"), self.__editUserPEL) self.__editSpellingMenu.aboutToShow.connect( self.__showEditSpellingMenu) menu.addAction(self.spellCheckAct) menu.addAction(self.autoSpellCheckAct) menu.addMenu(self.__editSpellingMenu) menu.addSeparator() def initSpellingToolbar(self, toolbarManager): """ Public method to create the Spelling toolbar. @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) @return the generated toolbar """ tb = QToolBar(QCoreApplication.translate('ViewManager', 'Spelling'), self.ui) tb.setIconSize(UI.Config.ToolBarIconSize) tb.setObjectName("SpellingToolbar") tb.setToolTip(QCoreApplication.translate('ViewManager', 'Spelling')) tb.addAction(self.spellCheckAct) tb.addAction(self.autoSpellCheckAct) toolbarManager.addToolBar(tb, tb.windowTitle()) return tb ################################################################## ## Methods and slots that deal with file and window handling ################################################################## def __openFiles(self): """ Private slot to open some files. """ # set the cwd of the dialog based on the following search criteria: # 1: Directory of currently active editor # 2: Directory of currently active project # 3: CWD import QScintilla.Lexers filter = self._getOpenFileFilter() progs = E5FileDialog.getOpenFileNamesAndFilter( self.ui, QCoreApplication.translate('ViewManager', "Open files"), self._getOpenStartDir(), QScintilla.Lexers.getOpenFileFiltersList(True, True), filter)[0] for prog in progs: self.openFiles(prog) def openFiles(self, prog): """ Public slot to open some files. @param prog name of file to be opened (string) """ prog = Utilities.normabspath(prog) # Open up the new files. self.openSourceFile(prog) def checkDirty(self, editor, autosave=False): """ Public method to check dirty status and open a message window. @param editor editor window to check @param autosave flag indicating that the file should be saved automatically (boolean) @return flag indicating successful reset of the dirty flag (boolean) """ if editor.isModified(): fn = editor.getFileName() # ignore the dirty status, if there is more than one open editor # for the same file if fn and self.getOpenEditorCount(fn) > 1: return True if fn is None: fn = editor.getNoName() autosave = False if autosave: res = editor.saveFile() else: res = E5MessageBox.okToClearData( self.ui, QCoreApplication.translate('ViewManager', "File Modified"), QCoreApplication.translate( 'ViewManager', """

The file {0} has unsaved changes.

""") .format(fn), editor.saveFile) if res: self.setEditorName(editor, editor.getFileName()) return res return True def checkAllDirty(self): """ Public method to check the dirty status of all editors. @return flag indicating successful reset of all dirty flags (boolean) """ for editor in self.editors: if not self.checkDirty(editor): return False return True def closeEditor(self, editor): """ Public method to close an editor window. @param editor editor window to be closed @return flag indicating success (boolean) """ # save file if necessary if not self.checkDirty(editor): return False # get the filename of the editor for later use fn = editor.getFileName() # remove the window editor.parent().shutdownTimer() self._removeView(editor) self.editors.remove(editor) # send a signal, if it was the last editor for this filename if fn and self.getOpenEditor(fn) is None: self.editorClosed.emit(fn) self.editorClosedEd.emit(editor) # send a signal, if it was the very last editor if not len(self.editors): self.__lastEditorClosed() self.lastEditorClosed.emit() editor.deleteLater() return True def closeCurrentWindow(self): """ Public method to close the current window. @return flag indicating success (boolean) """ aw = self.activeWindow() if aw is None: return False res = self.closeEditor(aw) if res and aw == self.currentEditor: self.currentEditor = None return res def closeAllWindows(self): """ Public method to close all editor windows via file menu. """ savedEditors = self.editors[:] for editor in savedEditors: self.closeEditor(editor) def closeWindow(self, fn): """ Public method to close an arbitrary source editor. @param fn filename of editor to be closed @return flag indicating success (boolean) """ for editor in self.editors: if Utilities.samepath(fn, editor.getFileName()): break else: return True res = self.closeEditor(editor) if res and editor == self.currentEditor: self.currentEditor = None return res def closeEditorWindow(self, editor): """ Public method to close an arbitrary source editor. @param editor editor to be closed """ if editor is None: return res = self.closeEditor(editor) if res and editor == self.currentEditor: self.currentEditor = None def exit(self): """ Public method to handle the debugged program terminating. """ if self.currentEditor is not None: self.currentEditor.highlight() self.currentEditor = None for editor in self.editors: editor.refreshCoverageAnnotations() self.__setSbFile() def openSourceFile(self, fn, lineno=-1, filetype="", selStart=0, selEnd=0, pos=0): """ Public slot to display a file in an editor. @param fn name of file to be opened (string) @param lineno line number to place the cursor at (integer) @param filetype type of the source file (string) @param selStart start of an area to be selected (integer) @param selEnd end of an area to be selected (integer) @param pos position within the line to place the cursor at (integer) """ try: newWin, editor = self.getEditor(fn, filetype=filetype) except (IOError, UnicodeDecodeError): return if newWin: self._modificationStatusChanged(editor.isModified(), editor) self._checkActions(editor) if lineno >= 0: editor.ensureVisibleTop(lineno) editor.gotoLine(lineno, pos) if selStart != selEnd: editor.setSelection(lineno - 1, selStart, lineno - 1, selEnd) # insert filename into list of recently opened files self.addToRecentList(fn) def __connectEditor(self, editor): """ Private method to establish all editor connections. @param editor reference to the editor object to be connected """ editor.modificationStatusChanged.connect( self._modificationStatusChanged) editor.cursorChanged.connect(self.__cursorChanged) editor.editorSaved.connect(self.__editorSaved) editor.editorRenamed.connect(self.__editorRenamed) editor.breakpointToggled.connect(self.__breakpointToggled) editor.bookmarkToggled.connect(self.__bookmarkToggled) editor.syntaxerrorToggled.connect(self._syntaxErrorToggled) editor.coverageMarkersShown.connect(self.__coverageMarkersShown) editor.autoCompletionAPIsAvailable.connect( self.__editorAutoCompletionAPIsAvailable) editor.undoAvailable.connect(self.undoAct.setEnabled) editor.redoAvailable.connect(self.redoAct.setEnabled) editor.taskMarkersUpdated.connect(self.__taskMarkersUpdated) editor.changeMarkersUpdated.connect(self.__changeMarkersUpdated) editor.languageChanged.connect(self.__editorConfigChanged) editor.eolChanged.connect(self.__editorConfigChanged) editor.encodingChanged.connect(self.__editorConfigChanged) editor.selectionChanged.connect(self.__searchWidget.selectionChanged) editor.selectionChanged.connect(self.__replaceWidget.selectionChanged) editor.selectionChanged.connect(self.__editorSelectionChanged) editor.lastEditPositionAvailable.connect( self.__lastEditPositionAvailable) editor.zoomValueChanged.connect(self.zoomValueChanged) editor.languageChanged.connect( lambda: self.editorLanguageChanged.emit(editor)) editor.textChanged.connect(lambda: self.editorTextChanged.emit(editor)) def newEditorView(self, fn, caller, filetype=""): """ Public method to create a new editor displaying the given document. @param fn filename of this view @param caller reference to the editor calling this method @param filetype type of the source file (string) """ editor, assembly = self.cloneEditor(caller, filetype, fn) self._addView(assembly, fn, caller.getNoName()) self._modificationStatusChanged(editor.isModified(), editor) self._checkActions(editor) def cloneEditor(self, caller, filetype, fn): """ Public method to clone an editor displaying the given document. @param caller reference to the editor calling this method @param filetype type of the source file (string) @param fn filename of this view @return reference to the new editor object (Editor.Editor) and the new edito assembly object (EditorAssembly.EditorAssembly) """ from QScintilla.EditorAssembly import EditorAssembly assembly = EditorAssembly(self.dbs, fn, self, filetype=filetype, editor=caller, tv=e5App().getObject("TaskViewer")) editor = assembly.getEditor() self.editors.append(editor) self.__connectEditor(editor) self.__editorOpened() self.editorOpened.emit(fn) self.editorOpenedEd.emit(editor) return editor, assembly def addToRecentList(self, fn): """ Public slot to add a filename to the list of recently opened files. @param fn name of the file to be added """ for recent in self.recent[:]: if Utilities.samepath(fn, recent): self.recent.remove(recent) self.recent.insert(0, fn) maxRecent = Preferences.getUI("RecentNumber") if len(self.recent) > maxRecent: self.recent = self.recent[:maxRecent] self.__saveRecent() def showDebugSource(self, fn, line): """ Public method to open the given file and highlight the given line in it. @param fn filename of editor to update (string) @param line line number to highlight (int) """ self.openSourceFile(fn, line) self.setFileLine(fn, line) def setFileLine(self, fn, line, error=False, syntaxError=False): """ Public method to update the user interface when the current program or line changes. @param fn filename of editor to update (string) @param line line number to highlight (int) @param error flag indicating an error highlight (boolean) @param syntaxError flag indicating a syntax error """ try: newWin, self.currentEditor = self.getEditor(fn) except (IOError, UnicodeDecodeError): return enc = self.currentEditor.getEncoding() lang = self.currentEditor.getLanguage() eol = self.currentEditor.getEolIndicator() zoom = self.currentEditor.getZoom() self.__setSbFile(fn, line, encoding=enc, language=lang, eol=eol, zoom=zoom) # Change the highlighted line. self.currentEditor.highlight(line, error, syntaxError) self.currentEditor.highlightVisible() self._checkActions(self.currentEditor, False) def __setSbFile(self, fn=None, line=None, pos=None, encoding=None, language=None, eol=None, zoom=None): """ Private method to set the file info in the status bar. @param fn filename to display (string) @param line line number to display (int) @param pos character position to display (int) @param encoding encoding name to display (string) @param language language to display (string) @param eol eol indicator to display (string) @param zoom zoom value (integer) """ if not fn: fn = '' writ = ' ' else: if QFileInfo(fn).isWritable(): writ = 'rw' else: writ = 'ro' self.sbWritable.setText(writ) if line is None: line = '' self.sbLine.setText( QCoreApplication.translate('ViewManager', 'Line: {0:5}') .format(line)) if pos is None: pos = '' self.sbPos.setText( QCoreApplication.translate('ViewManager', 'Pos: {0:5}') .format(pos)) if encoding is None: encoding = '' self.sbEnc.setText(encoding) if language is None: language = '' import QScintilla.Lexers pixmap = QScintilla.Lexers.getLanguageIcon(language, True) self.sbLang.setPixmap(pixmap) if pixmap.isNull(): self.sbLang.setText(language) self.sbLang.setToolTip("") else: self.sbLang.setText("") self.sbLang.setToolTip( QCoreApplication.translate('ViewManager', 'Language: {0}') .format(language)) if eol is None: eol = '' self.sbEol.setPixmap(self.__eolPixmap(eol)) self.sbEol.setToolTip( QCoreApplication.translate('ViewManager', 'EOL Mode: {0}') .format(eol)) if zoom is None: if QApplication.focusWidget() == e5App().getObject("Shell"): aw = e5App().getObject("Shell") else: aw = self.activeWindow() if aw: self.sbZoom.setValue(aw.getZoom()) else: self.sbZoom.setValue(zoom) def __eolPixmap(self, eolIndicator): """ Private method to get an EOL pixmap for an EOL string. @param eolIndicator eol indicator string (string) @return pixmap for the eol indicator (QPixmap) """ if eolIndicator == "LF": pixmap = UI.PixmapCache.getPixmap("eolLinux.png") elif eolIndicator == "CR": pixmap = UI.PixmapCache.getPixmap("eolMac.png") elif eolIndicator == "CRLF": pixmap = UI.PixmapCache.getPixmap("eolWindows.png") else: pixmap = QPixmap() return pixmap def __unhighlight(self): """ Private slot to switch of all highlights. """ self.unhighlight() def unhighlight(self, current=False): """ Public method to switch off all highlights or the highlight of the current editor. @param current flag indicating only the current editor should be unhighlighted (boolean) """ if current: if self.currentEditor is not None: self.currentEditor.highlight() else: for editor in self.editors: editor.highlight() def getOpenFilenames(self): """ Public method returning a list of the filenames of all editors. @return list of all opened filenames (list of strings) """ filenames = [] for editor in self.editors: fn = editor.getFileName() if fn is not None and fn not in filenames and os.path.exists(fn): # only return names of existing files filenames.append(fn) return filenames def getEditor(self, fn, filetype=""): """ Public method to return the editor displaying the given file. If there is no editor with the given file, a new editor window is created. @param fn filename to look for @param filetype type of the source file (string) @return tuple of two values giving a flag indicating a new window creation and a reference to the editor displaying this file """ newWin = False editor = self.activeWindow() if editor is None or not Utilities.samepath(fn, editor.getFileName()): for editor in self.editors: if Utilities.samepath(fn, editor.getFileName()): break else: from QScintilla.EditorAssembly import EditorAssembly assembly = EditorAssembly(self.dbs, fn, self, filetype=filetype, tv=e5App().getObject("TaskViewer")) editor = assembly.getEditor() self.editors.append(editor) self.__connectEditor(editor) self.__editorOpened() self.editorOpened.emit(fn) self.editorOpenedEd.emit(editor) newWin = True if newWin: self._addView(assembly, fn) else: self._showView(editor.parent(), fn) return (newWin, editor) def getOpenEditors(self): """ Public method to get references to all open editors. @return list of references to all open editors (list of QScintilla.editor) """ return self.editors def getOpenEditorsCount(self): """ Public method to get the number of open editors. @return number of open editors (integer) """ return len(self.editors) def getOpenEditor(self, fn): """ Public method to return the editor displaying the given file. @param fn filename to look for @return a reference to the editor displaying this file or None, if no editor was found """ for editor in self.editors: if Utilities.samepath(fn, editor.getFileName()): return editor return None def getOpenEditorCount(self, fn): """ Public method to return the count of editors displaying the given file. @param fn filename to look for @return count of editors displaying this file (integer) """ count = 0 for editor in self.editors: if Utilities.samepath(fn, editor.getFileName()): count += 1 return count def getActiveName(self): """ Public method to retrieve the filename of the active window. @return filename of active window (string) """ aw = self.activeWindow() if aw: return aw.getFileName() else: return None def saveEditor(self, fn): """ Public method to save a named editor file. @param fn filename of editor to be saved (string) @return flag indicating success (boolean) """ for editor in self.editors: if Utilities.samepath(fn, editor.getFileName()): break else: return True if not editor.isModified(): return True else: ok = editor.saveFile() return ok def saveEditorEd(self, ed): """ Public slot to save the contents of an editor. @param ed editor to be saved @return flag indicating success (boolean) """ if ed: if not ed.isModified(): return True else: ok = ed.saveFile() if ok: self.setEditorName(ed, ed.getFileName()) return ok else: return False def saveCurrentEditor(self): """ Public slot to save the contents of the current editor. """ aw = self.activeWindow() self.saveEditorEd(aw) def saveAsEditorEd(self, ed): """ Public slot to save the contents of an editor to a new file. @param ed editor to be saved """ if ed: ok = ed.saveFileAs() if ok: self.setEditorName(ed, ed.getFileName()) else: return def saveAsCurrentEditor(self): """ Public slot to save the contents of the current editor to a new file. """ aw = self.activeWindow() self.saveAsEditorEd(aw) def saveEditorsList(self, editors): """ Public slot to save a list of editors. @param editors list of editors to be saved """ for editor in editors: ok = editor.saveFile() if ok: self.setEditorName(editor, editor.getFileName()) def saveAllEditors(self): """ Public slot to save the contents of all editors. """ for editor in self.editors: ok = editor.saveFile() if ok: self.setEditorName(editor, editor.getFileName()) # restart autosave timer if self.autosaveInterval > 0: self.autosaveTimer.start(self.autosaveInterval * 60000) def __exportMenuTriggered(self, act): """ Private method to handle the selection of an export format. @param act reference to the action that was triggered (QAction) """ aw = self.activeWindow() if aw: exporterFormat = act.data() aw.exportFile(exporterFormat) def newEditor(self): """ Public slot to generate a new empty editor. """ from QScintilla.EditorAssembly import EditorAssembly assembly = EditorAssembly(self.dbs, None, self, tv=e5App().getObject("TaskViewer")) editor = assembly.getEditor() self.editors.append(editor) self.__connectEditor(editor) self._addView(assembly, None) self.__editorOpened() self._checkActions(editor) self.editorOpened.emit("") self.editorOpenedEd.emit(editor) def printEditor(self, editor): """ Public slot to print an editor. @param editor editor to be printed """ if editor: editor.printFile() else: return def printCurrentEditor(self): """ Public slot to print the contents of the current editor. """ aw = self.activeWindow() self.printEditor(aw) def printPreviewCurrentEditor(self): """ Public slot to show a print preview of the current editor. """ aw = self.activeWindow() if aw: aw.printPreviewFile() def __showFileMenu(self): """ Private method to set up the file menu. """ self.menuRecentAct.setEnabled(len(self.recent) > 0) def __showRecentMenu(self): """ Private method to set up recent files menu. """ self.__loadRecent() self.recentMenu.clear() idx = 1 for rs in self.recent: if idx < 10: formatStr = '&{0:d}. {1}' else: formatStr = '{0:d}. {1}' act = self.recentMenu.addAction( formatStr.format( idx, Utilities.compactPath(rs, self.ui.maxMenuFilePathLen))) act.setData(rs) act.setEnabled(QFileInfo(rs).exists()) idx += 1 self.recentMenu.addSeparator() self.recentMenu.addAction( QCoreApplication.translate('ViewManager', '&Clear'), self.__clearRecent) def __openSourceFile(self, act): """ Private method to open a file from the list of recently opened files. @param act reference to the action that triggered (QAction) """ file = act.data() if file: self.openSourceFile(file) def __clearRecent(self): """ Private method to clear the recent files menu. """ self.recent = [] def __showBookmarkedMenu(self): """ Private method to set up bookmarked files menu. """ self.bookmarkedMenu.clear() for rp in self.bookmarked: act = self.bookmarkedMenu.addAction( Utilities.compactPath(rp, self.ui.maxMenuFilePathLen)) act.setData(rp) act.setEnabled(QFileInfo(rp).exists()) if len(self.bookmarked): self.bookmarkedMenu.addSeparator() self.bookmarkedMenu.addAction( QCoreApplication.translate('ViewManager', '&Add'), self.__addBookmarked) self.bookmarkedMenu.addAction( QCoreApplication.translate('ViewManager', '&Edit...'), self.__editBookmarked) self.bookmarkedMenu.addAction( QCoreApplication.translate('ViewManager', '&Clear'), self.__clearBookmarked) def __addBookmarked(self): """ Private method to add the current file to the list of bookmarked files. """ an = self.getActiveName() if an is not None and an not in self.bookmarked: self.bookmarked.append(an) def __editBookmarked(self): """ Private method to edit the list of bookmarked files. """ from .BookmarkedFilesDialog import BookmarkedFilesDialog dlg = BookmarkedFilesDialog(self.bookmarked, self.ui) if dlg.exec_() == QDialog.Accepted: self.bookmarked = dlg.getBookmarkedFiles() def __clearBookmarked(self): """ Private method to clear the bookmarked files menu. """ self.bookmarked = [] def projectOpened(self): """ Public slot to handle the projectOpened signal. """ for editor in self.editors: editor.projectOpened() self.__editProjectPwlAct.setEnabled(True) self.__editProjectPelAct.setEnabled(True) def projectClosed(self): """ Public slot to handle the projectClosed signal. """ for editor in self.editors: editor.projectClosed() self.__editProjectPwlAct.setEnabled(False) self.__editProjectPelAct.setEnabled(False) def projectFileRenamed(self, oldfn, newfn): """ Public slot to handle the projectFileRenamed signal. @param oldfn old filename of the file (string) @param newfn new filename of the file (string) """ editor = self.getOpenEditor(oldfn) if editor: editor.fileRenamed(newfn) def projectLexerAssociationsChanged(self): """ Public slot to handle changes of the project lexer associations. """ for editor in self.editors: editor.projectLexerAssociationsChanged() def enableEditorsCheckFocusIn(self, enabled): """ Public method to set a flag enabling the editors to perform focus in checks. @param enabled flag indicating focus in checks should be performed (boolean) """ self.editorsCheckFocusIn = enabled def editorsCheckFocusInEnabled(self): """ Public method returning the flag indicating editors should perform focus in checks. @return flag indicating focus in checks should be performed (boolean) """ return self.editorsCheckFocusIn def __findFileName(self): """ Private method to handle the search for file action. """ self.ui.showFindFileByNameDialog() def appFocusChanged(self, old, now): """ Public method to handle the global change of focus. @param old reference to the widget loosing focus (QWidget) @param now reference to the widget gaining focus (QWidget) """ from QScintilla.Shell import Shell if not isinstance(now, (Editor, Shell)): self.editActGrp.setEnabled(False) self.copyActGrp.setEnabled(False) self.viewActGrp.setEnabled(False) self.sbZoom.setEnabled(False) else: self.sbZoom.setEnabled(True) self.sbZoom.setValue(now.getZoom()) if not isinstance(now, (Editor, Shell)) and \ now is not self.quickFindtextCombo: self.searchActGrp.setEnabled(False) if now is self.quickFindtextCombo: self.searchActGrp.setEnabled(True) if not isinstance(now, (Editor, Shell)): self.__lastFocusWidget = old ################################################################## ## Below are the action methods for the edit menu ################################################################## def __editUndo(self): """ Private method to handle the undo action. """ self.activeWindow().undo() def __editRedo(self): """ Private method to handle the redo action. """ self.activeWindow().redo() def __editRevert(self): """ Private method to handle the revert action. """ self.activeWindow().revertToUnmodified() def __editCut(self): """ Private method to handle the cut action. """ if QApplication.focusWidget() == e5App().getObject("Shell"): e5App().getObject("Shell").cut() else: self.activeWindow().cut() def __editCopy(self): """ Private method to handle the copy action. """ if QApplication.focusWidget() == e5App().getObject("Shell"): e5App().getObject("Shell").copy() else: self.activeWindow().copy() def __editPaste(self): """ Private method to handle the paste action. """ if QApplication.focusWidget() == e5App().getObject("Shell"): e5App().getObject("Shell").paste() else: self.activeWindow().paste() def __editDelete(self): """ Private method to handle the delete action. """ if QApplication.focusWidget() == e5App().getObject("Shell"): e5App().getObject("Shell").clear() else: self.activeWindow().clear() def __editJoin(self): """ Private method to handle the join action. """ self.activeWindow().joinLines() def __editIndent(self): """ Private method to handle the indent action. """ self.activeWindow().indentLineOrSelection() def __editUnindent(self): """ Private method to handle the unindent action. """ self.activeWindow().unindentLineOrSelection() def __editSmartIndent(self): """ Private method to handle the smart indent action. """ self.activeWindow().smartIndentLineOrSelection() def __editToggleComment(self): """ Private method to handle the toggle comment action. """ self.activeWindow().toggleCommentBlock() def __editComment(self): """ Private method to handle the comment action. """ self.activeWindow().commentLineOrSelection() def __editUncomment(self): """ Private method to handle the uncomment action. """ self.activeWindow().uncommentLineOrSelection() def __editStreamComment(self): """ Private method to handle the stream comment action. """ self.activeWindow().streamCommentLineOrSelection() def __editBoxComment(self): """ Private method to handle the box comment action. """ self.activeWindow().boxCommentLineOrSelection() def __editSelectBrace(self): """ Private method to handle the select to brace action. """ self.activeWindow().selectToMatchingBrace() def __editSelectAll(self): """ Private method to handle the select all action. """ self.activeWindow().selectAll(True) def __editDeselectAll(self): """ Private method to handle the select all action. """ self.activeWindow().selectAll(False) def __convertEOL(self): """ Private method to handle the convert line end characters action. """ aw = self.activeWindow() aw.convertEols(aw.eolMode()) def __shortenEmptyLines(self): """ Private method to handle the shorten empty lines action. """ self.activeWindow().shortenEmptyLines() def __editAutoComplete(self): """ Private method to handle the autocomplete action. """ self.activeWindow().autoComplete() def __editAutoCompleteFromDoc(self): """ Private method to handle the autocomplete from document action. """ self.activeWindow().autoCompleteFromDocument() def __editAutoCompleteFromAPIs(self): """ Private method to handle the autocomplete from APIs action. """ self.activeWindow().autoCompleteFromAPIs() def __editAutoCompleteFromAll(self): """ Private method to handle the autocomplete from All action. """ self.activeWindow().autoCompleteFromAll() def __editorAutoCompletionAPIsAvailable(self, available): """ Private method to handle the availability of API autocompletion signal. @param available flag indicating the availability of API autocompletion (boolean) """ editor = self.sender() self.autoCompleteAct.setEnabled( editor.canProvideDynamicAutoCompletion()) self.autoCompleteFromAPIsAct.setEnabled(available) self.autoCompleteFromAllAct.setEnabled(available) self.calltipsAct.setEnabled(editor.canProvideCallTipps()) def __editShowCallTips(self): """ Private method to handle the calltips action. """ self.activeWindow().callTip() ################################################################## ## Below are the action and utility methods for the search menu ################################################################## def textForFind(self, getCurrentWord=True): """ Public method to determine the selection or the current word for the next find operation. @param getCurrentWord flag indicating to return the current word, if no selected text was found (boolean) @return selection or current word (string) """ aw = self.activeWindow() if aw is None: return "" return aw.getSearchText(not getCurrentWord) def getSRHistory(self, key): """ Public method to get the search or replace history list. @param key list to return (must be 'search' or 'replace') @return the requested history list (list of strings) """ return self.srHistory[key] def __quickSearch(self): """ Private slot to handle the incremental quick search. """ # first we have to check if quick search is active # and try to activate it if not if self.__quickSearchToolbarVisibility is None: self.__quickSearchToolbarVisibility = \ self.__quickSearchToolbar.isVisible() if not self.__quickSearchToolbar.isVisible(): self.__quickSearchToolbar.show() if not self.quickFindtextCombo.lineEdit().hasFocus(): aw = self.activeWindow() self.quickFindtextCombo.lastActive = aw if aw: self.quickFindtextCombo.lastCursorPos = aw.getCursorPosition() else: self.quickFindtextCombo.lastCursorPos = None tff = self.textForFind(False) if tff: self.quickFindtextCombo.lineEdit().setText(tff) self.quickFindtextCombo.lineEdit().setFocus() self.quickFindtextCombo.lineEdit().selectAll() self.__quickSearchSetEditColors(False) else: self.__quickSearchInEditor(True, False) def __quickSearchFocusIn(self): """ Private method to handle a focus in signal of the quicksearch lineedit. """ self.quickFindtextCombo.lastActive = self.activeWindow() def __quickSearchEnter(self): """ Private slot to handle the incremental quick search return pressed (jump back to text). """ if self.quickFindtextCombo.lastActive: self.quickFindtextCombo.lastActive.setFocus() if self.__quickSearchToolbarVisibility is not None: self.__quickSearchToolbar.setVisible( self.__quickSearchToolbarVisibility) self.__quickSearchToolbarVisibility = None def __quickSearchEscape(self): """ Private slot to handle the incremental quick search escape pressed (jump back to text). """ if self.quickFindtextCombo.lastActive: self.quickFindtextCombo.lastActive.setFocus() aw = self.activeWindow() if aw: aw.hideFindIndicator() if self.quickFindtextCombo.lastCursorPos: aw.setCursorPosition( self.quickFindtextCombo.lastCursorPos[0], self.quickFindtextCombo.lastCursorPos[1]) if self.__quickSearchToolbarVisibility is not None: self.__quickSearchToolbar.setVisible( self.__quickSearchToolbarVisibility) self.__quickSearchToolbarVisibility = None def __quickSearchText(self): """ Private slot to handle the textChanged signal of the quicksearch edit. """ self.__quickSearchInEditor(False, False) def __quickSearchPrev(self): """ Private slot to handle the quickFindPrev toolbutton action. """ # first we have to check if quick search is active # and try to activate it if not if self.__quickSearchToolbarVisibility is None: self.__quickSearchToolbarVisibility = \ self.__quickSearchToolbar.isVisible() if not self.__quickSearchToolbar.isVisible(): self.__quickSearchToolbar.show() if not self.quickFindtextCombo.lineEdit().hasFocus(): aw = self.activeWindow() self.quickFindtextCombo.lastActive = aw if aw: self.quickFindtextCombo.lastCursorPos = aw.getCursorPosition() else: self.quickFindtextCombo.lastCursorPos = None tff = self.textForFind(False) if tff: self.quickFindtextCombo.lineEdit().setText(tff) self.quickFindtextCombo.lineEdit().setFocus() self.quickFindtextCombo.lineEdit().selectAll() self.__quickSearchSetEditColors(False) else: self.__quickSearchInEditor(True, True) def __quickSearchMarkOccurrences(self, txt): """ Private method to mark all occurrences of the search text. @param txt text to search for (string) """ aw = self.activeWindow() lineFrom = 0 indexFrom = 0 lineTo = -1 indexTo = -1 aw.clearSearchIndicators() ok = aw.findFirstTarget(txt, False, False, False, lineFrom, indexFrom, lineTo, indexTo) while ok: tgtPos, tgtLen = aw.getFoundTarget() aw.setSearchIndicator(tgtPos, tgtLen) ok = aw.findNextTarget() def __quickSearchInEditor(self, again, back): """ Private slot to perform a quick search. @param again flag indicating a repeat of the last search (boolean) @param back flag indicating a backwards search operation (boolean) """ aw = self.activeWindow() if not aw: return aw.hideFindIndicator() text = self.quickFindtextCombo.lineEdit().text() if not text and again: text = self.quickFindtextCombo.lastSearchText if not text: if Preferences.getEditor("QuickSearchMarkersEnabled"): aw.clearSearchIndicators() return else: self.quickFindtextCombo.lastSearchText = text if Preferences.getEditor("QuickSearchMarkersEnabled"): self.__quickSearchMarkOccurrences(text) lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() cline, cindex = aw.getCursorPosition() if again: if back: if indexFrom != 0: index = indexFrom - 1 line = lineFrom elif lineFrom == 0: return else: line = lineFrom - 1 index = aw.lineLength(line) ok = aw.findFirst(text, False, False, False, True, False, line, index) else: ok = aw.findFirst(text, False, False, False, True, not back, cline, cindex) else: ok = aw.findFirst(text, False, False, False, True, not back, lineFrom, indexFrom) if ok: sline, sindex, eline, eindex = aw.getSelection() aw.showFindIndicator(sline, sindex, eline, eindex) self.__quickSearchSetEditColors(not ok) def __quickSearchSetEditColors(self, error): """ Private method to set the quick search edit colors. @param error flag indicating an error (boolean) """ if error: palette = self.quickFindtextCombo.lineEdit().palette() palette.setColor(QPalette.Base, QColor("red")) palette.setColor(QPalette.Text, QColor("white")) self.quickFindtextCombo.lineEdit().setPalette(palette) else: palette = self.quickFindtextCombo.lineEdit().palette() palette.setColor( QPalette.Base, self.quickFindtextCombo.palette().color(QPalette.Base)) palette.setColor( QPalette.Text, self.quickFindtextCombo.palette().color(QPalette.Text)) self.quickFindtextCombo.lineEdit().setPalette(palette) def __quickSearchExtend(self): """ Private method to handle the quicksearch extend action. """ aw = self.activeWindow() if aw is None: return txt = self.quickFindtextCombo.lineEdit().text() if not txt: return line, index = aw.getCursorPosition() text = aw.text(line) reg = QRegExp('[^\w_]') end = reg.indexIn(text, index) if end > index: ext = text[index:end] txt += ext self.quickFindtextCombo.lineEdit().setText(txt) def __search(self): """ Private method to handle the search action. """ self.__replaceWidget.hide() self.__searchWidget.show() self.__searchWidget.show(self.textForFind()) def __replace(self): """ Private method to handle the replace action. """ self.__searchWidget.hide() self.__replaceWidget.show(self.textForFind()) def __findNextWord(self): """ Private slot to find the next occurrence of the current word of the current editor. """ self.activeWindow().searchCurrentWordForward() def __findPrevWord(self): """ Private slot to find the previous occurrence of the current word of the current editor. """ self.activeWindow().searchCurrentWordBackward() def __searchClearMarkers(self): """ Private method to clear the search markers of the active window. """ self.activeWindow().clearSearchIndicators() def __goto(self): """ Private method to handle the goto action. """ from QScintilla.GotoDialog import GotoDialog aw = self.activeWindow() lines = aw.lines() curLine = aw.getCursorPosition()[0] + 1 dlg = GotoDialog(lines, curLine, self.ui, None, True) if dlg.exec_() == QDialog.Accepted: aw.gotoLine(dlg.getLinenumber()) def __gotoBrace(self): """ Private method to handle the goto brace action. """ self.activeWindow().moveToMatchingBrace() def __gotoLastEditPosition(self): """ Private method to move the cursor to the last edit position. """ self.activeWindow().gotoLastEditPosition() def __lastEditPositionAvailable(self): """ Private slot to handle the lastEditPositionAvailable signal of an editor. """ self.gotoLastEditAct.setEnabled(True) def __gotoNextMethodClass(self): """ Private slot to go to the next Python/Ruby method or class definition. """ self.activeWindow().gotoMethodClass(False) def __gotoPreviousMethodClass(self): """ Private slot to go to the previous Python/Ruby method or class definition. """ self.activeWindow().gotoMethodClass(True) def __searchFiles(self): """ Private method to handle the search in files action. """ self.ui.showFindFilesDialog(self.textForFind()) def __replaceFiles(self): """ Private method to handle the replace in files action. """ self.ui.showReplaceFilesDialog(self.textForFind()) def __searchOpenFiles(self): """ Private method to handle the search in open files action. """ self.ui.showFindFilesDialog(self.textForFind(), openFiles=True) def __replaceOpenFiles(self): """ Private method to handle the replace in open files action. """ self.ui.showReplaceFilesDialog(self.textForFind(), openFiles=True) ################################################################## ## Below are the action methods for the view menu ################################################################## def __zoomIn(self): """ Private method to handle the zoom in action. """ if QApplication.focusWidget() == e5App().getObject("Shell"): e5App().getObject("Shell").zoomIn() else: aw = self.activeWindow() if aw: aw.zoomIn() self.sbZoom.setValue(aw.getZoom()) def __zoomOut(self): """ Private method to handle the zoom out action. """ if QApplication.focusWidget() == e5App().getObject("Shell"): e5App().getObject("Shell").zoomOut() else: aw = self.activeWindow() if aw: aw.zoomOut() self.sbZoom.setValue(aw.getZoom()) def __zoomReset(self): """ Private method to reset the zoom factor. """ if QApplication.focusWidget() == e5App().getObject("Shell"): e5App().getObject("Shell").zoomTo(0) else: aw = self.activeWindow() if aw: aw.zoomTo(0) self.sbZoom.setValue(aw.getZoom()) def __zoom(self): """ Private method to handle the zoom action. """ if QApplication.focusWidget() == e5App().getObject("Shell"): aw = e5App().getObject("Shell") else: aw = self.activeWindow() if aw: from QScintilla.ZoomDialog import ZoomDialog dlg = ZoomDialog(aw.getZoom(), self.ui, None, True) if dlg.exec_() == QDialog.Accepted: value = dlg.getZoomSize() self.__zoomTo(value) def __zoomTo(self, value): """ Private slot to zoom to a given value. @param value zoom value to be set (integer) """ if QApplication.focusWidget() == e5App().getObject("Shell"): aw = e5App().getObject("Shell") else: aw = self.activeWindow() if aw: aw.zoomTo(value) self.sbZoom.setValue(aw.getZoom()) def zoomValueChanged(self, value): """ Public slot to handle changes of the zoom value. @param value new zoom value (integer) """ if QApplication.focusWidget() == e5App().getObject("Shell"): aw = e5App().getObject("Shell") else: aw = self.activeWindow() if aw and aw == self.sender(): self.sbZoom.setValue(value) def __toggleAll(self): """ Private method to handle the toggle all folds action. """ aw = self.activeWindow() if aw: aw.foldAll() def __toggleAllChildren(self): """ Private method to handle the toggle all folds (including children) action. """ aw = self.activeWindow() if aw: aw.foldAll(True) def __toggleCurrent(self): """ Private method to handle the toggle current fold action. """ aw = self.activeWindow() if aw: line, index = aw.getCursorPosition() aw.foldLine(line) def __newDocumentView(self): """ Private method to open a new view of the current editor. """ aw = self.activeWindow() if aw: self.newEditorView(aw.getFileName(), aw, aw.getFileType()) def __newDocumentSplitView(self): """ Private method to open a new view of the current editor in a new split. """ aw = self.activeWindow() if aw: self.addSplit() self.newEditorView(aw.getFileName(), aw, aw.getFileType()) def __splitView(self): """ Private method to handle the split view action. """ self.addSplit() def __splitOrientation(self, checked): """ Private method to handle the split orientation action. @param checked flag indicating the checked state of the action (boolean). True means splitting horizontally. """ if checked: self.setSplitOrientation(Qt.Horizontal) self.splitViewAct.setIcon( UI.PixmapCache.getIcon("splitHorizontal.png")) self.splitRemoveAct.setIcon( UI.PixmapCache.getIcon("remsplitHorizontal.png")) self.newDocumentSplitViewAct.setIcon( UI.PixmapCache.getIcon("splitHorizontal.png")) else: self.setSplitOrientation(Qt.Vertical) self.splitViewAct.setIcon( UI.PixmapCache.getIcon("splitVertical.png")) self.splitRemoveAct.setIcon( UI.PixmapCache.getIcon("remsplitVertical.png")) self.newDocumentSplitViewAct.setIcon( UI.PixmapCache.getIcon("splitVertical.png")) Preferences.setUI("SplitOrientationVertical", checked) def __previewEditor(self, checked): """ Private slot to handle a change of the preview selection state. @param checked state of the action (boolean) """ Preferences.setUI("ShowFilePreview", checked) self.previewStateChanged.emit(checked) ################################################################## ## Below are the action methods for the macro menu ################################################################## def __macroStartRecording(self): """ Private method to handle the start macro recording action. """ self.activeWindow().macroRecordingStart() def __macroStopRecording(self): """ Private method to handle the stop macro recording action. """ self.activeWindow().macroRecordingStop() def __macroRun(self): """ Private method to handle the run macro action. """ self.activeWindow().macroRun() def __macroDelete(self): """ Private method to handle the delete macro action. """ self.activeWindow().macroDelete() def __macroLoad(self): """ Private method to handle the load macro action. """ self.activeWindow().macroLoad() def __macroSave(self): """ Private method to handle the save macro action. """ self.activeWindow().macroSave() ################################################################## ## Below are the action methods for the bookmarks menu ################################################################## def __toggleBookmark(self): """ Private method to handle the toggle bookmark action. """ self.activeWindow().menuToggleBookmark() def __nextBookmark(self): """ Private method to handle the next bookmark action. """ self.activeWindow().nextBookmark() def __previousBookmark(self): """ Private method to handle the previous bookmark action. """ self.activeWindow().previousBookmark() def __clearAllBookmarks(self): """ Private method to handle the clear all bookmarks action. """ for editor in self.editors: editor.clearBookmarks() self.bookmarkNextAct.setEnabled(False) self.bookmarkPreviousAct.setEnabled(False) self.bookmarkClearAct.setEnabled(False) def __showBookmarkMenu(self): """ Private method to set up the bookmark menu. """ bookmarksFound = 0 filenames = self.getOpenFilenames() for filename in filenames: editor = self.getOpenEditor(filename) bookmarksFound = len(editor.getBookmarks()) > 0 if bookmarksFound: self.menuBookmarksAct.setEnabled(True) return self.menuBookmarksAct.setEnabled(False) def __showBookmarksMenu(self): """ Private method to handle the show bookmarks menu signal. """ self.bookmarksMenu.clear() filenames = self.getOpenFilenames() for filename in sorted(filenames): editor = self.getOpenEditor(filename) for bookmark in editor.getBookmarks(): bmSuffix = " : {0:d}".format(bookmark) act = self.bookmarksMenu.addAction( "{0}{1}".format( Utilities.compactPath( filename, self.ui.maxMenuFilePathLen - len(bmSuffix)), bmSuffix)) act.setData([filename, bookmark]) def __bookmarkSelected(self, act): """ Private method to handle the bookmark selected signal. @param act reference to the action that triggered (QAction) """ bmList = act.data() filename = bmList[0] line = bmList[1] self.openSourceFile(filename, line) def __bookmarkToggled(self, editor): """ Private slot to handle the bookmarkToggled signal. It checks some bookmark actions and reemits the signal. @param editor editor that sent the signal """ if editor.hasBookmarks(): self.bookmarkNextAct.setEnabled(True) self.bookmarkPreviousAct.setEnabled(True) self.bookmarkClearAct.setEnabled(True) else: self.bookmarkNextAct.setEnabled(False) self.bookmarkPreviousAct.setEnabled(False) self.bookmarkClearAct.setEnabled(False) self.bookmarkToggled.emit(editor) def __gotoSyntaxError(self): """ Private method to handle the goto syntax error action. """ self.activeWindow().gotoSyntaxError() def __clearAllSyntaxErrors(self): """ Private method to handle the clear all syntax errors action. """ for editor in self.editors: editor.clearSyntaxError() def _syntaxErrorToggled(self, editor): """ Protected slot to handle the syntaxerrorToggled signal. It checks some syntax error actions and reemits the signal. @param editor editor that sent the signal """ if editor.hasSyntaxErrors(): self.syntaxErrorGotoAct.setEnabled(True) self.syntaxErrorClearAct.setEnabled(True) else: self.syntaxErrorGotoAct.setEnabled(False) self.syntaxErrorClearAct.setEnabled(False) if editor.hasWarnings(): self.warningsNextAct.setEnabled(True) self.warningsPreviousAct.setEnabled(True) self.warningsClearAct.setEnabled(True) else: self.warningsNextAct.setEnabled(False) self.warningsPreviousAct.setEnabled(False) self.warningsClearAct.setEnabled(False) self.syntaxerrorToggled.emit(editor) def __nextWarning(self): """ Private method to handle the next warning action. """ self.activeWindow().nextWarning() def __previousWarning(self): """ Private method to handle the previous warning action. """ self.activeWindow().previousWarning() def __clearAllWarnings(self): """ Private method to handle the clear all warnings action. """ for editor in self.editors: editor.clearWarnings() def __nextUncovered(self): """ Private method to handle the next uncovered action. """ self.activeWindow().nextUncovered() def __previousUncovered(self): """ Private method to handle the previous uncovered action. """ self.activeWindow().previousUncovered() def __coverageMarkersShown(self, shown): """ Private slot to handle the coverageMarkersShown signal. @param shown flag indicating whether the markers were shown or cleared """ if shown: self.notcoveredNextAct.setEnabled(True) self.notcoveredPreviousAct.setEnabled(True) else: self.notcoveredNextAct.setEnabled(False) self.notcoveredPreviousAct.setEnabled(False) def __taskMarkersUpdated(self, editor): """ Private slot to handle the taskMarkersUpdated signal. @param editor editor that sent the signal """ if editor.hasTaskMarkers(): self.taskNextAct.setEnabled(True) self.taskPreviousAct.setEnabled(True) else: self.taskNextAct.setEnabled(False) self.taskPreviousAct.setEnabled(False) def __nextTask(self): """ Private method to handle the next task action. """ self.activeWindow().nextTask() def __previousTask(self): """ Private method to handle the previous task action. """ self.activeWindow().previousTask() def __changeMarkersUpdated(self, editor): """ Private slot to handle the changeMarkersUpdated signal. @param editor editor that sent the signal """ if editor.hasChangeMarkers(): self.changeNextAct.setEnabled(True) self.changePreviousAct.setEnabled(True) else: self.changeNextAct.setEnabled(False) self.changePreviousAct.setEnabled(False) def __nextChange(self): """ Private method to handle the next change action. """ self.activeWindow().nextChange() def __previousChange(self): """ Private method to handle the previous change action. """ self.activeWindow().previousChange() ################################################################## ## Below are the action methods for the spell checking functions ################################################################## def __showEditSpellingMenu(self): """ Private method to set up the edit dictionaries menu. """ proj = e5App().getObject("Project") projetOpen = proj.isOpen() pwl = e5App().getObject("Project").getProjectDictionaries()[0] self.__editProjectPwlAct.setEnabled(projetOpen and bool(pwl)) pel = e5App().getObject("Project").getProjectDictionaries()[1] self.__editProjectPelAct.setEnabled(projetOpen and bool(pel)) from QScintilla.SpellChecker import SpellChecker pwl = SpellChecker.getUserDictionaryPath() self.__editUserPwlAct.setEnabled(bool(pwl)) pel = SpellChecker.getUserDictionaryPath(True) self.__editUserPelAct.setEnabled(bool(pel)) def __setAutoSpellChecking(self): """ Private slot to set the automatic spell checking of all editors. """ enabled = self.autoSpellCheckAct.isChecked() Preferences.setEditor("AutoSpellCheckingEnabled", enabled) for editor in self.editors: editor.setAutoSpellChecking() def __spellCheck(self): """ Private slot to perform a spell check of the current editor. """ aw = self.activeWindow() if aw: aw.checkSpelling() def __editProjectPWL(self): """ Private slot to edit the project word list. """ pwl = e5App().getObject("Project").getProjectDictionaries()[0] self.__editSpellingDictionary(pwl) def __editProjectPEL(self): """ Private slot to edit the project exception list. """ pel = e5App().getObject("Project").getProjectDictionaries()[1] self.__editSpellingDictionary(pel) def __editUserPWL(self): """ Private slot to edit the user word list. """ from QScintilla.SpellChecker import SpellChecker pwl = SpellChecker.getUserDictionaryPath() self.__editSpellingDictionary(pwl) def __editUserPEL(self): """ Private slot to edit the user exception list. """ from QScintilla.SpellChecker import SpellChecker pel = SpellChecker.getUserDictionaryPath(True) self.__editSpellingDictionary(pel) def __editSpellingDictionary(self, dictionaryFile): """ Private slot to edit the given spelling dictionary. @param dictionaryFile file name of the dictionary to edit (string) """ if os.path.exists(dictionaryFile): try: f = open(dictionaryFile, "r", encoding="utf-8") data = f.read() f.close() except (IOError, OSError) as err: E5MessageBox.critical( self.ui, QCoreApplication.translate( 'ViewManager', "Edit Spelling Dictionary"), QCoreApplication.translate( 'ViewManager', """

The spelling dictionary file {0} could""" """ not be read.

Reason: {1}

""").format( dictionaryFile, str(err))) return fileInfo = dictionaryFile if len(dictionaryFile) < 40 \ else "...{0}".format(dictionaryFile[-40:]) from QScintilla.SpellingDictionaryEditDialog import \ SpellingDictionaryEditDialog dlg = SpellingDictionaryEditDialog( data, QCoreApplication.translate('ViewManager', "Editing {0}") .format(fileInfo), self.ui) if dlg.exec_() == QDialog.Accepted: data = dlg.getData() try: f = open(dictionaryFile, "w", encoding="utf-8") f.write(data) f.close() except (IOError, OSError) as err: E5MessageBox.critical( self.ui, QCoreApplication.translate( 'ViewManager', "Edit Spelling Dictionary"), QCoreApplication.translate( 'ViewManager', """

The spelling dictionary file {0}""" """ could not be written.

""" """

Reason: {1}

""").format( dictionaryFile, str(err))) return if self.ui.notificationsEnabled(): self.ui.showNotification( UI.PixmapCache.getPixmap("spellchecking48.png"), QCoreApplication.translate( 'ViewManager', "Edit Spelling Dictionary"), QCoreApplication.translate( 'ViewManager', "The spelling dictionary was saved successfully.")) ################################################################## ## Below are general utility methods ################################################################## def handleResetUI(self): """ Public slot to handle the resetUI signal. """ editor = self.activeWindow() if editor is None: self.__setSbFile() else: line, pos = editor.getCursorPosition() enc = editor.getEncoding() lang = editor.getLanguage() eol = editor.getEolIndicator() zoom = editor.getZoom() self.__setSbFile(editor.getFileName(), line + 1, pos, enc, lang, eol, zoom) def closeViewManager(self): """ Public method to shutdown the viewmanager. If it cannot close all editor windows, it aborts the shutdown process. @return flag indicating success (boolean) """ e5App().focusChanged.disconnect(self.appFocusChanged) self.closeAllWindows() # save the list of recently opened projects self.__saveRecent() # save the list of recently opened projects Preferences.Prefs.settings.setValue( 'Bookmarked/Sources', self.bookmarked) if len(self.editors): res = False else: res = True if not res: e5App().focusChanged.connect(self.appFocusChanged) return res def __lastEditorClosed(self): """ Private slot to handle the lastEditorClosed signal. """ self.closeActGrp.setEnabled(False) self.saveActGrp.setEnabled(False) self.exportersMenuAct.setEnabled(False) self.printAct.setEnabled(False) if self.printPreviewAct: self.printPreviewAct.setEnabled(False) self.editActGrp.setEnabled(False) self.searchActGrp.setEnabled(False) self.quickFindtextCombo.setEnabled(False) self.viewActGrp.setEnabled(False) self.viewFoldActGrp.setEnabled(False) self.unhighlightAct.setEnabled(False) self.newDocumentViewAct.setEnabled(False) self.newDocumentSplitViewAct.setEnabled(False) self.splitViewAct.setEnabled(False) self.splitOrientationAct.setEnabled(False) self.previewAct.setEnabled(True) self.macroActGrp.setEnabled(False) self.bookmarkActGrp.setEnabled(False) self.__enableSpellingActions() self.__setSbFile(zoom=0) # remove all split views, if this is supported if self.canSplit(): while self.removeSplit(): pass # stop the autosave timer if self.autosaveTimer.isActive(): self.autosaveTimer.stop() # hide search and replace widgets self.__searchWidget.hide() self.__replaceWidget.hide() def __editorOpened(self): """ Private slot to handle the editorOpened signal. """ self.closeActGrp.setEnabled(True) self.saveActGrp.setEnabled(True) self.exportersMenuAct.setEnabled(True) self.printAct.setEnabled(True) if self.printPreviewAct: self.printPreviewAct.setEnabled(True) self.editActGrp.setEnabled(True) self.searchActGrp.setEnabled(True) self.quickFindtextCombo.setEnabled(True) self.viewActGrp.setEnabled(True) self.viewFoldActGrp.setEnabled(True) self.unhighlightAct.setEnabled(True) self.newDocumentViewAct.setEnabled(True) if self.canSplit(): self.newDocumentSplitViewAct.setEnabled(True) self.splitViewAct.setEnabled(True) self.splitOrientationAct.setEnabled(True) self.macroActGrp.setEnabled(True) self.bookmarkActGrp.setEnabled(True) self.__enableSpellingActions() # activate the autosave timer if not self.autosaveTimer.isActive() and \ self.autosaveInterval > 0: self.autosaveTimer.start(self.autosaveInterval * 60000) def __autosave(self): """ Private slot to save the contents of all editors automatically. Only named editors will be saved by the autosave timer. """ for editor in self.editors: if editor.shouldAutosave(): ok = editor.saveFile() if ok: self.setEditorName(editor, editor.getFileName()) # restart autosave timer if self.autosaveInterval > 0: self.autosaveTimer.start(self.autosaveInterval * 60000) def _checkActions(self, editor, setSb=True): """ Protected slot to check some actions for their enable/disable status and set the statusbar info. @param editor editor window @param setSb flag indicating an update of the status bar is wanted (boolean) """ if editor is not None: self.saveAct.setEnabled(editor.isModified()) self.revertAct.setEnabled(editor.isModified()) self.undoAct.setEnabled(editor.isUndoAvailable()) self.redoAct.setEnabled(editor.isRedoAvailable()) self.gotoLastEditAct.setEnabled( editor.isLastEditPositionAvailable()) lex = editor.getLexer() if lex is not None: self.commentAct.setEnabled(lex.canBlockComment()) self.uncommentAct.setEnabled(lex.canBlockComment()) self.streamCommentAct.setEnabled(lex.canStreamComment()) self.boxCommentAct.setEnabled(lex.canBoxComment()) else: self.commentAct.setEnabled(False) self.uncommentAct.setEnabled(False) self.streamCommentAct.setEnabled(False) self.boxCommentAct.setEnabled(False) if editor.hasBookmarks(): self.bookmarkNextAct.setEnabled(True) self.bookmarkPreviousAct.setEnabled(True) self.bookmarkClearAct.setEnabled(True) else: self.bookmarkNextAct.setEnabled(False) self.bookmarkPreviousAct.setEnabled(False) self.bookmarkClearAct.setEnabled(False) if editor.hasSyntaxErrors(): self.syntaxErrorGotoAct.setEnabled(True) self.syntaxErrorClearAct.setEnabled(True) else: self.syntaxErrorGotoAct.setEnabled(False) self.syntaxErrorClearAct.setEnabled(False) if editor.hasWarnings(): self.warningsNextAct.setEnabled(True) self.warningsPreviousAct.setEnabled(True) self.warningsClearAct.setEnabled(True) else: self.warningsNextAct.setEnabled(False) self.warningsPreviousAct.setEnabled(False) self.warningsClearAct.setEnabled(False) if editor.hasCoverageMarkers(): self.notcoveredNextAct.setEnabled(True) self.notcoveredPreviousAct.setEnabled(True) else: self.notcoveredNextAct.setEnabled(False) self.notcoveredPreviousAct.setEnabled(False) if editor.hasTaskMarkers(): self.taskNextAct.setEnabled(True) self.taskPreviousAct.setEnabled(True) else: self.taskNextAct.setEnabled(False) self.taskPreviousAct.setEnabled(False) if editor.hasChangeMarkers(): self.changeNextAct.setEnabled(True) self.changePreviousAct.setEnabled(True) else: self.changeNextAct.setEnabled(False) self.changePreviousAct.setEnabled(False) if editor.canAutoCompleteFromAPIs(): self.autoCompleteFromAPIsAct.setEnabled(True) self.autoCompleteFromAllAct.setEnabled(True) else: self.autoCompleteFromAPIsAct.setEnabled(False) self.autoCompleteFromAllAct.setEnabled(False) self.autoCompleteAct.setEnabled( editor.canProvideDynamicAutoCompletion()) self.calltipsAct.setEnabled(editor.canProvideCallTipps()) if editor.isPyFile() or editor.isRubyFile(): self.gotoPreviousDefAct.setEnabled(True) self.gotoNextDefAct.setEnabled(True) else: self.gotoPreviousDefAct.setEnabled(False) self.gotoNextDefAct.setEnabled(False) self.sortAct.setEnabled(editor.selectionIsRectangle()) enable = editor.hasSelection() self.editUpperCaseAct.setEnabled(enable) self.editLowerCaseAct.setEnabled(enable) if setSb: line, pos = editor.getCursorPosition() enc = editor.getEncoding() lang = editor.getLanguage() eol = editor.getEolIndicator() zoom = editor.getZoom() self.__setSbFile( editor.getFileName(), line + 1, pos, enc, lang, eol, zoom) self.checkActions.emit(editor) saveAllEnable = False for editor in self.editors: if editor.isModified(): saveAllEnable = True self.saveAllAct.setEnabled(saveAllEnable) def preferencesChanged(self): """ Public slot to handle the preferencesChanged signal. This method performs the following actions
  • reread the colours for the syntax highlighting
  • reloads the already created API objetcs
  • starts or stops the autosave timer
  • Note: changes in viewmanager type are activated on an application restart.
""" # reload the APIs self.apisManager.reloadAPIs() # reload editor settings for editor in self.editors: zoom = editor.getZoom() editor.readSettings() editor.zoomTo(zoom) # reload the autosave timer setting self.autosaveInterval = Preferences.getEditor("AutosaveInterval") if len(self.editors): if self.autosaveTimer.isActive() and \ self.autosaveInterval == 0: self.autosaveTimer.stop() elif not self.autosaveTimer.isActive() and \ self.autosaveInterval > 0: self.autosaveTimer.start(self.autosaveInterval * 60000) self.__enableSpellingActions() def __editorSaved(self, fn): """ Private slot to handle the editorSaved signal. It simply reemits the signal. @param fn filename of the saved editor (string) """ self.editorSaved.emit(fn) editor = self.sender() if editor: self.editorSavedEd.emit(editor) def __editorRenamed(self, fn): """ Private slot to handle the editorRenamed signal. It simply reemits the signal. @param fn filename of the renamed editor (string) """ self.editorRenamed.emit(fn) editor = self.sender() if editor: self.editorRenamedEd.emit(editor) def __cursorChanged(self, fn, line, pos): """ Private slot to handle the cursorChanged signal. It emits the signal cursorChanged with parameter editor. @param fn filename (string) @param line line number of the cursor (int) @param pos position in line of the cursor (int) """ editor = self.getOpenEditor(fn) if editor is None: editor = self.sender() if editor is not None: enc = editor.getEncoding() lang = editor.getLanguage() eol = editor.getEolIndicator() else: enc = None lang = None eol = None self.__setSbFile(fn, line, pos, enc, lang, eol) self.cursorChanged.emit(editor) def __breakpointToggled(self, editor): """ Private slot to handle the breakpointToggled signal. It simply reemits the signal. @param editor editor that sent the signal """ self.breakpointToggled.emit(editor) def getActions(self, type): """ Public method to get a list of all actions. @param type string denoting the action set to get. It must be one of "edit", "file", "search", "view", "window", "macro", "bookmark" or "spelling". @return list of all actions (list of E5Action) """ try: return self.__actions[type][:] except KeyError: return [] def __editorCommand(self, cmd): """ Private method to send an editor command to the active window. @param cmd the scintilla command to be sent """ focusWidget = QApplication.focusWidget() if focusWidget == e5App().getObject("Shell"): e5App().getObject("Shell").editorCommand(cmd) elif focusWidget == self.quickFindtextCombo: self.quickFindtextCombo._editor.editorCommand(cmd) else: aw = self.activeWindow() if aw: aw.editorCommand(cmd) def __newLineBelow(self): """ Private method to insert a new line below the current one even if cursor is not at the end of the line. """ focusWidget = QApplication.focusWidget() if focusWidget == e5App().getObject("Shell") or \ focusWidget == self.quickFindtextCombo: return else: aw = self.activeWindow() if aw: aw.newLineBelow() def __editorConfigChanged(self): """ Private slot to handle changes of an editor's configuration. """ editor = self.sender() fn = editor.getFileName() line, pos = editor.getCursorPosition() enc = editor.getEncoding() lang = editor.getLanguage() eol = editor.getEolIndicator() zoom = editor.getZoom() self.__setSbFile( fn, line + 1, pos, encoding=enc, language=lang, eol=eol, zoom=zoom) self._checkActions(editor, False) def __editorSelectionChanged(self): """ Private slot to handle changes of the current editors selection. """ editor = self.sender() if editor: self.sortAct.setEnabled(editor.selectionIsRectangle()) enable = editor.hasSelection() self.editUpperCaseAct.setEnabled(enable) self.editLowerCaseAct.setEnabled(enable) else: self.sortAct.setEnabled(False) def __editSortSelectedLines(self): """ Private slot to sort the selected lines. """ editor = self.activeWindow() if editor: editor.sortLines() ################################################################## ## Below are protected utility methods ################################################################## def _getOpenStartDir(self): """ Protected method to return the starting directory for a file open dialog. The appropriate starting directory is calculated using the following search order, until a match is found:
1: Directory of currently active editor
2: Directory of currently active Project
3: CWD @return name of directory to start (string) """ # if we have an active source, return its path if self.activeWindow() is not None and \ self.activeWindow().getFileName(): return os.path.dirname(self.activeWindow().getFileName()) # check, if there is an active project and return its path elif e5App().getObject("Project").isOpen(): return e5App().getObject("Project").ppath else: return Preferences.getMultiProject("Workspace") or \ Utilities.getHomeDir() def _getOpenFileFilter(self): """ Protected method to return the active filename filter for a file open dialog. The appropriate filename filter is determined by file extension of the currently active editor. @return name of the filename filter (string) or None """ if self.activeWindow() is not None and \ self.activeWindow().getFileName(): ext = os.path.splitext(self.activeWindow().getFileName())[1] rx = QRegExp(".*\*\.{0}[ )].*".format(ext[1:])) import QScintilla.Lexers filters = QScintilla.Lexers.getOpenFileFiltersList() index = -1 for i in range(len(filters)): if rx.exactMatch(filters[i]): index = i break if index == -1: return Preferences.getEditor("DefaultOpenFilter") else: return filters[index] else: return Preferences.getEditor("DefaultOpenFilter") ################################################################## ## Below are API handling methods ################################################################## def getAPIsManager(self): """ Public method to get a reference to the APIs manager. @return the APIs manager object (eric6.QScintilla.APIsManager) """ return self.apisManager ####################################################################### ## Cooperation related methods ####################################################################### def setCooperationClient(self, client): """ Public method to set a reference to the cooperation client. @param client reference to the cooperation client (CooperationClient) """ self.__cooperationClient = client def isConnected(self): """ Public method to check the connection status of the IDE. @return flag indicating the connection status (boolean) """ return self.__cooperationClient.hasConnections() def send(self, fileName, message): """ Public method to send an editor command to remote editors. @param fileName file name of the editor (string) @param message command message to be sent (string) """ project = e5App().getObject("Project") if project.isProjectFile(fileName): self.__cooperationClient.sendEditorCommand( project.getHash(), project.getRelativeUniversalPath(fileName), message ) def receive(self, hash, fileName, command): """ Public slot to handle received editor commands. @param hash hash of the project (string) @param fileName project relative file name of the editor (string) @param command command string (string) """ project = e5App().getObject("Project") if hash == project.getHash(): fn = project.getAbsoluteUniversalPath(fileName) editor = self.getOpenEditor(fn) if editor: editor.receive(command) def shareConnected(self, connected): """ Public slot to handle a change of the connected state. @param connected flag indicating the connected state (boolean) """ for editor in self.getOpenEditors(): editor.shareConnected(connected) def shareEditor(self, share): """ Public slot to set the shared status of the current editor. @param share flag indicating the share status (boolean) """ aw = self.activeWindow() if aw is not None: fn = aw.getFileName() if fn and e5App().getObject("Project").isProjectFile(fn): aw.shareEditor(share) def startSharedEdit(self): """ Public slot to start a shared edit session for the current editor. """ aw = self.activeWindow() if aw is not None: fn = aw.getFileName() if fn and e5App().getObject("Project").isProjectFile(fn): aw.startSharedEdit() def sendSharedEdit(self): """ Public slot to end a shared edit session for the current editor and send the changes. """ aw = self.activeWindow() if aw is not None: fn = aw.getFileName() if fn and e5App().getObject("Project").isProjectFile(fn): aw.sendSharedEdit() def cancelSharedEdit(self): """ Public slot to cancel a shared edit session for the current editor. """ aw = self.activeWindow() if aw is not None: fn = aw.getFileName() if fn and e5App().getObject("Project").isProjectFile(fn): aw.cancelSharedEdit() ####################################################################### ## Symbols viewer related methods ####################################################################### def insertSymbol(self, txt): """ Public slot to insert a symbol text into the active window. @param txt text to be inserted (string) """ if self.__lastFocusWidget == e5App().getObject("Shell"): e5App().getObject("Shell").insert(txt) else: aw = self.activeWindow() if aw is not None: curline, curindex = aw.getCursorPosition() aw.insert(txt) aw.setCursorPosition(curline, curindex + len(txt)) ####################################################################### ## Numbers viewer related methods ####################################################################### def insertNumber(self, txt): """ Public slot to insert a number text into the active window. @param txt text to be inserted (string) """ if self.__lastFocusWidget == e5App().getObject("Shell"): aw = e5App().getObject("Shell") if aw.hasSelectedText(): aw.removeSelectedText() aw.insert(txt) else: aw = self.activeWindow() if aw is not None: if aw.hasSelectedText(): aw.removeSelectedText() curline, curindex = aw.getCursorPosition() aw.insert(txt) aw.setCursorPosition(curline, curindex + len(txt)) def getNumber(self): """ Public method to get a number from the active window. @return selected text of the active window (string) """ txt = "" if self.__lastFocusWidget == e5App().getObject("Shell"): aw = e5App().getObject("Shell") if aw.hasSelectedText(): txt = aw.selectedText() else: aw = self.activeWindow() if aw is not None: if aw.hasSelectedText(): txt = aw.selectedText() return txt eric-6.0.8/eric/ViewManager/__init__.py0000644000175000017500000000345612451233370016773 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Package implementing the viewmanager of the eric6 IDE. The viewmanager is responsible for the layout of the editor windows. This is the central part of the IDE. In additon to this, the viewmanager provides all editor related actions, menus and toolbars. View managers are provided as plugins and loaded via the factory function. If the requested view manager type is not available, tabview will be used by default. """ from __future__ import unicode_literals import Preferences ###################################################################### ## Below is the factory function to instantiate the appropriate ## viewmanager depending on the configuration settings ###################################################################### def factory(parent, ui, dbs, pluginManager): """ Modul factory function to generate the right viewmanager type. The viewmanager is instantiated depending on the data set in the current preferences. @param parent parent widget (QWidget) @param ui reference to the main UI object @param dbs reference to the debug server object @param pluginManager reference to the plugin manager object @return the instantiated viewmanager @exception RuntimeError raised if no view manager could be created """ viewManagerStr = Preferences.getViewManager() vm = pluginManager.getPluginObject("viewmanager", viewManagerStr) if vm is None: # load tabview view manager as default vm = pluginManager.getPluginObject("viewmanager", "tabview") if vm is None: raise RuntimeError("Could not create a viemanager object.") Preferences.setViewManager("tabview") vm.setReferences(ui, dbs) return vm eric-6.0.8/eric/ViewManager/BookmarkedFilesDialog.ui0000644000175000017500000001521412263310456021377 0ustar piotrpiotr BookmarkedFilesDialog 0 0 475 391 Configure Bookmarked Files Menu true true false Delete the selected entry <b>Delete</b> <p>Delete the selected entry.</p> &Delete Alt+D Qt::Vertical QSizePolicy::Expanding 87 130 false Move up <b>Move Up</b> <p>Move the selected entry up.</p> &Up Alt+U false Move down <b>Move Down</b> <p>Move the selected entry down.</p> &Down Alt+D false Add a new bookmarked file <b>Add</b> <p>Add a new bookmarked file with the value entered below.</p> &Add Alt+A &File: fileEdit false Change the value of the selected entry <b>Change</b> <p>Change the value of the selected entry.</p> C&hange Alt+H Enter the filename of the file <b>File</b> <p>Enter the filename of the bookmarked file.</p> Select the file via a file selection dialog <b>File</b> <p>Select the file to be bookmarked via a file selection dialog.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource filesList addButton changeButton deleteButton upButton downButton fileEdit fileButton buttonBox accepted() BookmarkedFilesDialog accept() 25 373 25 388 buttonBox rejected() BookmarkedFilesDialog reject() 105 370 105 389 eric-6.0.8/eric/Templates/0000755000175000017500000000000012557365404014416 5ustar piotrpiotreric-6.0.8/eric/Templates/TemplateSingleVariableDialog.ui0000644000175000017500000000447512060166053022456 0ustar piotrpiotr TemplateSingleVariableDialog 0 0 403 218 Enter Template Variable true Enter the value for the variable. QTextEdit::NoWrap false Variable: Qt::AlignTop Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource variableEdit buttonBox accepted() TemplateSingleVariableDialog accept() 40 195 40 217 buttonBox rejected() TemplateSingleVariableDialog reject() 96 197 96 217 eric-6.0.8/eric/Templates/TemplateSingleVariableDialog.py0000644000175000017500000000210212451233370022453 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing a dialog for entering a single template variable. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_TemplateSingleVariableDialog import Ui_TemplateSingleVariableDialog class TemplateSingleVariableDialog(QDialog, Ui_TemplateSingleVariableDialog): """ Class implementing a dialog for entering a single template variable. """ def __init__(self, variable, parent=None): """ Constructor @param variable template variable name (string) @param parent parent widget of this dialog (QWidget) """ super(TemplateSingleVariableDialog, self).__init__(parent) self.setupUi(self) self.variableLabel.setText(variable) def getVariable(self): """ Public method to get the value for the variable. @return value for the template variable (string) """ return self.variableEdit.toPlainText() eric-6.0.8/eric/Templates/__init__.py0000644000175000017500000000024212451233370016512 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Package containing modules for the templating system. """ eric-6.0.8/eric/Templates/TemplatePropertiesDialog.py0000644000175000017500000002211712451233370021730 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the templates properties dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import QRegExp, Qt, pyqtSlot from PyQt5.QtGui import QRegExpValidator from PyQt5.QtWidgets import QDialog from .Ui_TemplatePropertiesDialog import Ui_TemplatePropertiesDialog from E5Gui import E5MessageBox import Preferences class TemplatePropertiesDialog(QDialog, Ui_TemplatePropertiesDialog): """ Class implementing the templates properties dialog. """ def __init__(self, parent, groupMode=False, itm=None): """ Constructor @param parent the parent widget (QWidget) @param groupMode flag indicating group mode (boolean) @param itm item (TemplateEntry or TemplateGroup) to read the data from """ super(TemplatePropertiesDialog, self).__init__(parent) self.setupUi(self) self.templateEdit.setFont(Preferences.getTemplates("EditorFont")) if not groupMode: self.nameEdit.setWhatsThis(self.tr( """Template name

Enter the name of the template.""" """ Templates may be autocompleted upon this name.""" """ In order to support autocompletion. the template name""" """ must only consist of letters (a-z and A-Z),""" """ digits (0-9) and underscores (_).

""" )) self.__nameValidator = QRegExpValidator(QRegExp("[a-zA-Z0-9_]+"), self.nameEdit) self.nameEdit.setValidator(self.__nameValidator) import QScintilla.Lexers self.languages = [("All", self.tr("All"))] supportedLanguages = QScintilla.Lexers.getSupportedLanguages() languages = sorted(supportedLanguages.keys()) for language in languages: self.languages.append((language, supportedLanguages[language][0])) self.groupMode = groupMode if groupMode: langList = [] for lang, langDisp in self.languages: langList.append(langDisp) self.groupLabel.setText(self.tr("Language:")) self.groupCombo.addItems(langList) self.templateLabel.setEnabled(False) self.templateEdit.setEnabled(False) self.templateEdit.setPlainText(self.tr("GROUP")) self.helpButton.setEnabled(False) self.descriptionLabel.hide() self.descriptionEdit.hide() else: groups = [] for group in parent.getGroupNames(): groups.append(group) self.groupCombo.addItems(groups) if itm is not None: self.nameEdit.setText(itm.getName()) if groupMode: lang = itm.getLanguage() for l, d in self.languages: if l == lang: self.setSelectedGroup(d) break else: self.setSelectedGroup(itm.getGroupName()) self.templateEdit.setPlainText(itm.getTemplateText()) self.descriptionEdit.setText(itm.getDescription()) self.nameEdit.selectAll() def keyPressEvent(self, ev): """ Protected method to handle the user pressing the escape key. @param ev key event (QKeyEvent) """ if ev.key() == Qt.Key_Escape: res = E5MessageBox.yesNo( self, self.tr("Close dialog"), self.tr("""Do you really want to close the dialog?""")) if not res: self.reject() @pyqtSlot() def on_helpButton_clicked(self): """ Private slot to show some help. """ E5MessageBox.information( self, self.tr("Template Help"), self.tr( """

To use variables in a template, you just have to""" """ enclose the variablename with $-characters. When you""" """ use the template, you will then be asked for a value""" """ for this variable.

""" """

Example template: This is a $VAR$

""" """

When you use this template you will be prompted for""" """ a value for the variable $VAR$. Any occurrences of $VAR$""" """ will then be replaced with whatever you've entered.

""" """

If you need a single $-character in a template, which""" """ is not used to enclose a variable, type $$(two dollar""" """ characters) instead. They will automatically be replaced""" """ with a single $-character when you use the template.

""" """

If you want a variables contents to be treated""" """ specially, the variablename must be followed by a ':'""" """ and one formatting specifier (e.g. $VAR:ml$). The""" """ supported specifiers are:""" """""" """""" """""" """
mlSpecifies a multiline formatting.""" """ The first line of the variable contents is prefixed with""" """ the string occurring before the variable on the same""" """ line of the template. All other lines are prefixed by""" """ the same amount of whitespace as the line containing""" """ the variable.""" """
rlSpecifies a repeated line formatting.""" """ Each line of the variable contents is prefixed with the""" """ string occuring before the variable on the same line of""" """ the template.""" """

""" """

The following predefined variables may be used in a""" """ template:""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """
datetoday's date in ISO format (YYYY-MM-DD)
yearthe current year
project_namethe name of the project (if any)
project_paththe path of the project (if any)
path_namefull path of the current file
dir_namefull path of the parent directory
file_namethe current file name (without directory)
base_namelike file_name, but without extension""" """
extthe extension of the current file
cur_selectthe currently selected text
insertionSets insertion point for cursor after template is""" """ inserted.
select_startSets span of selected text in template after template""" """ is inserted (used together with 'select_end').
select_endSets span of selected text in template after template""" """ is inserted (used together with 'select_start').""" """
clipboardthe text of the clipboard

""" """

If you want to change the default delimiter to""" """ anything different, please use the configuration""" """ dialog to do so.

""")) def setSelectedGroup(self, name): """ Public method to select a group. @param name name of the group to be selected (string) """ index = self.groupCombo.findText(name) self.groupCombo.setCurrentIndex(index) def getData(self): """ Public method to get the data entered into the dialog. @return a tuple of two strings (name, language), if the dialog is in group mode, and a tuple of four strings (name, description, group name, template) otherwise. """ if self.groupMode: return (self.nameEdit.text(), self.languages[self.groupCombo.currentIndex()][0] ) else: return (self.nameEdit.text(), self.descriptionEdit.text(), self.groupCombo.currentText(), self.templateEdit.toPlainText() ) eric-6.0.8/eric/Templates/TemplatePropertiesDialog.ui0000644000175000017500000001212312320552722021711 0ustar piotrpiotr TemplatePropertiesDialog 0 0 448 323 Template Properties true Name: Enter the name of the template/group. Templates are autocompleted upon this name. Description: Enter a description for the template Group: Template: Qt::AlignTop Monospace 9 Enter the text of the template <b>Template Text</b> <p>Enter the template text in this area. Every occurrence of $VAR$ will be replaced by the associated text when the template is applied. Predefined variables may be used in the template. The separator character might be changed via the preferences dialog.</p> <p>Press the help button for more information.</p> QTextEdit::NoWrap false &Help Alt+H Qt::Vertical QSizePolicy::Expanding 84 98 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource nameEdit descriptionEdit groupCombo templateEdit helpButton buttonBox buttonBox rejected() TemplatePropertiesDialog reject() 80 307 80 319 buttonBox accepted() TemplatePropertiesDialog accept() 45 300 41 324 eric-6.0.8/eric/Templates/TemplateMultipleVariablesDialog.py0000644000175000017500000001106112451233370023214 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing a dialog for entering multiple template variables. """ from __future__ import unicode_literals from PyQt5.QtCore import QSize, Qt from PyQt5.QtWidgets import QSizePolicy, QSpacerItem, QWidget, QHBoxLayout, \ QLineEdit, QPushButton, QTextEdit, QDialog, QScrollArea, QFrame, \ QGridLayout, QVBoxLayout, QLabel class TemplateMultipleVariablesDialog(QDialog): """ Class implementing a dialog for entering multiple template variables. """ def __init__(self, variables, parent=None): """ Constructor @param variables list of template variable names (list of strings) @param parent parent widget of this dialog (QWidget) """ super(TemplateMultipleVariablesDialog, self).__init__(parent) self.TemplateMultipleVariablesDialogLayout = QVBoxLayout(self) self.TemplateMultipleVariablesDialogLayout.setContentsMargins( 6, 6, 6, 6) self.TemplateMultipleVariablesDialogLayout.setSpacing(6) self.TemplateMultipleVariablesDialogLayout.setObjectName( "TemplateMultipleVariablesDialogLayout") self.setLayout(self.TemplateMultipleVariablesDialogLayout) # generate the scrollarea self.variablesView = QScrollArea(self) self.variablesView.setObjectName("variablesView") self.TemplateMultipleVariablesDialogLayout.addWidget( self.variablesView) self.variablesView.setWidgetResizable(True) self.variablesView.setFrameStyle(QFrame.NoFrame) self.top = QWidget(self) self.variablesView.setWidget(self.top) self.grid = QGridLayout(self.top) self.grid.setContentsMargins(0, 0, 0, 0) self.grid.setSpacing(6) self.top.setLayout(self.grid) # populate the scrollarea with labels and text edits self.variablesEntries = {} row = 0 for var in variables: label = QLabel("{0}:".format(var), self.top) self.grid.addWidget(label, row, 0, Qt.Alignment(Qt.AlignTop)) if var.find(":") >= 0: formatStr = var[1:-1].split(":")[1] if formatStr in ["ml", "rl"]: t = QTextEdit(self.top) t.setTabChangesFocus(True) else: t = QLineEdit(self.top) else: t = QLineEdit(self.top) self.grid.addWidget(t, row, 1) self.variablesEntries[var] = t row += 1 # add a spacer to make the entries aligned at the top spacer = QSpacerItem( 20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.grid.addItem(spacer, row, 1) self.variablesEntries[variables[0]].setFocus() self.top.adjustSize() # generate the buttons layout1 = QHBoxLayout() layout1.setContentsMargins(0, 0, 0, 0) layout1.setSpacing(6) layout1.setObjectName("layout1") spacer1 = QSpacerItem( 40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout1.addItem(spacer1) self.okButton = QPushButton(self) self.okButton.setObjectName("okButton") self.okButton.setDefault(True) layout1.addWidget(self.okButton) self.cancelButton = QPushButton(self) self.cancelButton.setObjectName("cancelButton") layout1.addWidget(self.cancelButton) spacer2 = QSpacerItem( 40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout1.addItem(spacer2) self.TemplateMultipleVariablesDialogLayout.addLayout(layout1) # set the texts of the standard widgets self.setWindowTitle(self.tr("Enter Template Variables")) self.okButton.setText(self.tr("&OK")) self.cancelButton.setText(self.tr("&Cancel")) # polish up the dialog self.resize(QSize(400, 480).expandedTo(self.minimumSizeHint())) self.okButton.clicked.connect(self.accept) self.cancelButton.clicked.connect(self.reject) def getVariables(self): """ Public method to get the values for all variables. @return dictionary with the variable as a key and its value (string) """ values = {} for var, textEdit in list(self.variablesEntries.items()): try: values[var] = textEdit.text() except AttributeError: values[var] = textEdit.toPlainText() return values eric-6.0.8/eric/Templates/TemplateViewer.py0000644000175000017500000010621712451233370017721 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing a template viewer and associated classes. """ from __future__ import unicode_literals import datetime import os import re from PyQt5.QtCore import QFile, QFileInfo, QIODevice, Qt, QCoreApplication from PyQt5.QtWidgets import QTreeWidget, QDialog, QApplication, QMenu, \ QTreeWidgetItem from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog import Preferences import UI.PixmapCache import Utilities class TemplateGroup(QTreeWidgetItem): """ Class implementing a template group. """ def __init__(self, parent, name, language="All"): """ Constructor @param parent parent widget of the template group (QWidget) @param name name of the group (string) @param language programming language for the group (string) """ self.name = name self.language = language self.entries = {} super(TemplateGroup, self).__init__(parent, [name]) if Preferences.getTemplates("ShowTooltip"): self.setToolTip(0, language) def setName(self, name): """ Public method to update the name of the group. @param name name of the group (string) """ self.name = name self.setText(0, name) def getName(self): """ Public method to get the name of the group. @return name of the group (string) """ return self.name def setLanguage(self, language): """ Public method to update the name of the group. @param language programming language for the group (string) """ self.language = language if Preferences.getTemplates("ShowTooltip"): self.setToolTip(0, language) def getLanguage(self): """ Public method to get the name of the group. @return language of the group (string) """ return self.language def addEntry(self, name, description, template, quiet=False): """ Public method to add a template entry to this group. @param name name of the entry (string) @param description description of the entry to add (string) @param template template text of the entry (string) @param quiet flag indicating quiet operation (boolean) """ if name in self.entries: if not quiet: E5MessageBox.critical( None, QCoreApplication.translate("TemplateGroup", "Add Template"), QCoreApplication.translate( "TemplateGroup", """

The group {0} already contains a""" """ template named {1}.

""") .format(self.name, name)) return self.entries[name] = TemplateEntry(self, name, description, template) if Preferences.getTemplates("AutoOpenGroups") and \ not self.isExpanded(): self.setExpanded(True) def removeEntry(self, name): """ Public method to remove a template entry from this group. @param name name of the entry to be removed (string) """ if name in self.entries: index = self.indexOfChild(self.entries[name]) self.takeChild(index) del self.entries[name] if len(self.entries) == 0: if Preferences.getTemplates("AutoOpenGroups") and \ self.isExpanded(): self.setExpanded(False) def removeAllEntries(self): """ Public method to remove all template entries of this group. """ for name in list(self.entries.keys())[:]: self.removeEntry(name) def hasEntry(self, name): """ Public method to check, if the group has an entry with the given name. @param name name of the entry to check for (string) @return flag indicating existence (boolean) """ return name in self.entries def getEntry(self, name): """ Public method to get an entry. @param name name of the entry to retrieve (string) @return reference to the entry (TemplateEntry) """ try: return self.entries[name] except KeyError: return None def getEntryNames(self, beginning): """ Public method to get the names of all entries, who's name starts with the given string. @param beginning string denoting the beginning of the template name (string) @return list of entry names found (list of strings) """ names = [] for name in self.entries: if name.startswith(beginning): names.append(name) return names def getAllEntries(self): """ Public method to retrieve all entries. @return list of all entries (list of TemplateEntry) """ return list(self.entries.values()) class TemplateEntry(QTreeWidgetItem): """ Class immplementing a template entry. """ def __init__(self, parent, name, description, templateText): """ Constructor @param parent parent widget of the template entry (QWidget) @param name name of the entry (string) @param description descriptive text for the template (string) @param templateText text of the template entry (string) """ self.name = name self.description = description self.template = templateText self.__extractVariables() super(TemplateEntry, self).__init__(parent, [self.__displayText()]) if Preferences.getTemplates("ShowTooltip"): self.setToolTip(0, self.template) def __displayText(self): """ Private method to generate the display text. @return display text (string) """ if self.description: txt = "{0} - {1}".format(self.name, self.description) else: txt = self.name return txt def setName(self, name): """ Public method to update the name of the entry. @param name name of the entry (string) """ self.name = name self.setText(0, self.__displayText()) def getName(self): """ Public method to get the name of the entry. @return name of the entry (string) """ return self.name def setDescription(self, description): """ Public method to update the description of the entry. @param description description of the entry (string) """ self.description = description self.setText(0, self.__displayText()) def getDescription(self): """ Public method to get the description of the entry. @return description of the entry (string) """ return self.description def getGroupName(self): """ Public method to get the name of the group this entry belongs to. @return name of the group containing this entry (string) """ return self.parent().getName() def setTemplateText(self, templateText): """ Public method to update the template text. @param templateText text of the template entry (string) """ self.template = templateText self.__extractVariables() if Preferences.getTemplates("ShowTooltip"): self.setToolTip(0, self.template) def getTemplateText(self): """ Public method to get the template text. @return the template text (string) """ return self.template def getExpandedText(self, varDict, indent): """ Public method to get the template text with all variables expanded. @param varDict dictionary containing the texts of each variable with the variable name as key. @param indent indentation of the line receiving he expanded template text (string) @return a tuple of the expanded template text (string), the number of lines (integer) and the length of the last line (integer) """ txt = self.template for var, val in list(varDict.items()): if var in self.formatedVariables: txt = self.__expandFormattedVariable(var, val, txt) else: txt = txt.replace(var, val) sepchar = Preferences.getTemplates("SeparatorChar") txt = txt.replace("{0}{1}".format(sepchar, sepchar), sepchar) prefix = "{0}{1}".format(os.linesep, indent) trailingEol = txt.endswith(os.linesep) lines = txt.splitlines() lineCount = len(lines) lineLen = len(lines[-1]) txt = prefix.join(lines).lstrip() if trailingEol: txt = "{0}{1}".format(txt, os.linesep) lineCount += 1 lineLen = 0 return txt, lineCount, lineLen def __expandFormattedVariable(self, var, val, txt): """ Private method to expand a template variable with special formatting. @param var template variable name (string) @param val value of the template variable (string) @param txt template text (string) @return expanded and formatted variable (string) """ t = "" for line in txt.splitlines(): ind = line.find(var) if ind >= 0: format = var[1:-1].split(':', 1)[1] if format == 'rl': prefix = line[:ind] postfix = line[ind + len(var):] for v in val.splitlines(): t = "{0}{1}{2}{3}{4}".format( t, os.linesep, prefix, v, postfix) elif format == 'ml': indent = line.replace(line.lstrip(), "") prefix = line[:ind] postfix = line[ind + len(var):] count = 0 for v in val.splitlines(): if count: t = "{0}{1}{2}{3}".format(t, os.linesep, indent, v) else: t = "{0}{1}{2}{3}".format(t, os.linesep, prefix, v) count += 1 t = "{0}{1}".format(t, postfix) else: t = "{0}{1}{2}".format(t, os.linesep, line) else: t = "{0}{1}{2}".format(t, os.linesep, line) return "".join(t.splitlines(1)[1:]) def getVariables(self): """ Public method to get the list of variables. @return list of variables (list of strings) """ return self.variables def __extractVariables(self): """ Private method to retrieve the list of variables. """ sepchar = Preferences.getTemplates("SeparatorChar") variablesPattern = \ re.compile( r"""\{0}[a-zA-Z][a-zA-Z0-9_]*(?::(?:ml|rl))?\{1}""".format( sepchar, sepchar)) variables = variablesPattern.findall(self.template) self.variables = [] self.formatedVariables = [] for var in variables: if var not in self.variables: self.variables.append(var) if var.find(':') >= 0 and var not in self.formatedVariables: self.formatedVariables.append(var) class TemplateViewer(QTreeWidget): """ Class implementing the template viewer. """ def __init__(self, parent, viewmanager): """ Constructor @param parent the parent (QWidget) @param viewmanager reference to the viewmanager object """ super(TemplateViewer, self).__init__(parent) self.viewmanager = viewmanager self.groups = {} self.setHeaderLabels(["Template"]) self.header().hide() self.header().setSortIndicator(0, Qt.AscendingOrder) self.setRootIsDecorated(True) self.setAlternatingRowColors(True) self.__menu = QMenu(self) self.applyAct = self.__menu.addAction( self.tr("Apply"), self.__templateItemActivated) self.__menu.addSeparator() self.__menu.addAction(self.tr("Add entry..."), self.__addEntry) self.__menu.addAction(self.tr("Add group..."), self.__addGroup) self.__menu.addAction(self.tr("Edit..."), self.__edit) self.__menu.addAction(self.tr("Remove"), self.__remove) self.__menu.addSeparator() self.__menu.addAction(self.tr("Save"), self.save) self.__menu.addAction(self.tr("Import..."), self.__import) self.__menu.addAction(self.tr("Export..."), self.__export) self.__menu.addAction(self.tr("Reload"), self.__reload) self.__menu.addSeparator() self.__menu.addAction( self.tr("Help about Templates..."), self.__showHelp) self.__menu.addSeparator() self.__menu.addAction(self.tr("Configure..."), self.__configure) self.__backMenu = QMenu(self) self.__backMenu.addAction(self.tr("Add group..."), self.__addGroup) self.__backMenu.addSeparator() self.__backMenu.addAction(self.tr("Save"), self.save) self.__backMenu.addAction(self.tr("Import..."), self.__import) self.__backMenu.addAction(self.tr("Export..."), self.__export) self.__backMenu.addAction(self.tr("Reload"), self.__reload) self.__backMenu.addSeparator() self.__backMenu.addAction( self.tr("Help about Templates..."), self.__showHelp) self.__backMenu.addSeparator() self.__backMenu.addAction( self.tr("Configure..."), self.__configure) self.__activating = False self.__dirty = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.itemActivated.connect(self.__templateItemActivated) self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) def __resort(self): """ Private method to resort the tree. """ self.sortItems(self.sortColumn(), self.header().sortIndicatorOrder()) def __templateItemActivated(self, itm=None, col=0): """ Private slot to handle the activation of an item. @param itm reference to the activated item (QTreeWidgetItem) @param col column the item was activated in (integer) """ if not self.__activating: self.__activating = True itm = self.currentItem() if isinstance(itm, TemplateEntry): self.applyTemplate(itm) self.__activating = False def __showContextMenu(self, coord): """ Private slot to show the context menu of the list. @param coord the position of the mouse pointer (QPoint) """ itm = self.itemAt(coord) coord = self.mapToGlobal(coord) if itm is None: self.__backMenu.popup(coord) else: self.applyAct.setEnabled( self.viewmanager.activeWindow() is not None) self.__menu.popup(coord) def __addEntry(self): """ Private slot to handle the Add Entry context menu action. """ itm = self.currentItem() if isinstance(itm, TemplateGroup): groupName = itm.getName() else: groupName = itm.getGroupName() from .TemplatePropertiesDialog import TemplatePropertiesDialog dlg = TemplatePropertiesDialog(self) dlg.setSelectedGroup(groupName) if dlg.exec_() == QDialog.Accepted: name, description, groupName, template = dlg.getData() self.addEntry(groupName, name, description, template) self.__dirty = True def __addGroup(self): """ Private slot to handle the Add Group context menu action. """ from .TemplatePropertiesDialog import TemplatePropertiesDialog dlg = TemplatePropertiesDialog(self, True) if dlg.exec_() == QDialog.Accepted: name, language = dlg.getData() self.addGroup(name, language) self.__dirty = True def __edit(self): """ Private slot to handle the Edit context menu action. """ itm = self.currentItem() if isinstance(itm, TemplateEntry): editGroup = False else: editGroup = True from .TemplatePropertiesDialog import TemplatePropertiesDialog dlg = TemplatePropertiesDialog(self, editGroup, itm) if dlg.exec_() == QDialog.Accepted: if editGroup: name, language = dlg.getData() self.changeGroup(itm.getName(), name, language) else: name, description, groupName, template = dlg.getData() self.changeEntry(itm, name, groupName, description, template) self.__dirty = True def __remove(self): """ Private slot to handle the Remove context menu action. """ itm = self.currentItem() res = E5MessageBox.yesNo( self, self.tr("Remove Template"), self.tr("""

Do you really want to remove {0}?

""") .format(itm.getName())) if not res: return if isinstance(itm, TemplateGroup): self.removeGroup(itm) else: self.removeEntry(itm) self.__dirty = True def save(self): """ Public slot to save the templates. """ if self.__dirty: ok = self.writeTemplates() if ok: self.__dirty = False def __import(self): """ Private slot to handle the Import context menu action. """ fn = E5FileDialog.getOpenFileName( self, self.tr("Import Templates"), "", self.tr("Templates Files (*.e4c);; All Files (*)")) if fn: self.readTemplates(fn) self.__dirty = True def __export(self): """ Private slot to handle the Export context menu action. """ fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Export Templates"), "", self.tr("Templates Files (*.e4c);; All Files (*)"), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fn: ext = QFileInfo(fn).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fn += ex self.writeTemplates(fn) def __reload(self): """ Private slot to reload the templates. """ if self.__dirty: res = E5MessageBox.yesNo( self, self.tr("Reload Templates"), self.tr( """The templates contain unsaved changes. Shall these""" """ changes be discarded?"""), icon=E5MessageBox.Warning) if not res: return self.clear() self.groups = {} self.readTemplates() def __showHelp(self): """ Private method to show some help. """ E5MessageBox.information( self, self.tr("Template Help"), self.tr( """

Template groups are a means of grouping""" """ individual templates. Groups have an attribute that""" """ specifies, which programming language they apply for.""" """ In order to add template entries, at least one group""" """ has to be defined.

""" """

Template entries are the actual templates.""" """ They are grouped by the template groups. Help about""" """ how to define them is available in the template edit""" """ dialog.

""")) def __getPredefinedVars(self): """ Private method to return predefined variables. @return dictionary of predefined variables and their values """ project = e5App().getObject("Project") editor = self.viewmanager.activeWindow() today = datetime.datetime.now().date() sepchar = Preferences.getTemplates("SeparatorChar") keyfmt = sepchar + "{0}" + sepchar varValues = {keyfmt.format('date'): today.isoformat(), keyfmt.format('year'): str(today.year)} if project.name: varValues[keyfmt.format('project_name')] = project.name if project.ppath: varValues[keyfmt.format('project_path')] = project.ppath path_name = editor.getFileName() if path_name: dir_name, file_name = os.path.split(path_name) base_name, ext = os.path.splitext(file_name) if ext: ext = ext[1:] varValues.update({ keyfmt.format('path_name'): path_name, keyfmt.format('dir_name'): dir_name, keyfmt.format('file_name'): file_name, keyfmt.format('base_name'): base_name, keyfmt.format('ext'): ext }) varValues[keyfmt.format('clipboard:ml')] = \ QApplication.clipboard().text() varValues[keyfmt.format('clipboard')] = \ QApplication.clipboard().text() if editor.hasSelectedText(): varValues[keyfmt.format('cur_select:ml')] = editor.selectedText() varValues[keyfmt.format('cur_select')] = editor.selectedText() else: varValues[keyfmt.format('cur_select:ml')] = os.linesep varValues[keyfmt.format('cur_select')] = "" varValues[keyfmt.format('insertion')] = "i_n_s_e_r_t_i_o_n" varValues[keyfmt.format('select_start')] = "s_e_l_e_c_t_s_t_a_r_t" varValues[keyfmt.format('select_end')] = "s_e_l_e_c_t_e_n_d" return varValues def applyTemplate(self, itm): """ Public method to apply the template. @param itm reference to the template item to apply (TemplateEntry) """ editor = self.viewmanager.activeWindow() if editor is None: return ok = False vars = itm.getVariables() varValues = self.__getPredefinedVars() # Remove predefined variables from list so user doesn't have to fill # these values out in the dialog. for v in list(varValues.keys()): if v in vars: vars.remove(v) if vars: if Preferences.getTemplates("SingleDialog"): from .TemplateMultipleVariablesDialog import \ TemplateMultipleVariablesDialog dlg = TemplateMultipleVariablesDialog(vars, self) if dlg.exec_() == QDialog.Accepted: varValues.update(dlg.getVariables()) ok = True else: from .TemplateSingleVariableDialog import \ TemplateSingleVariableDialog for var in vars: dlg = TemplateSingleVariableDialog(var, self) if dlg.exec_() == QDialog.Accepted: varValues[var] = dlg.getVariable() else: return del dlg ok = True else: ok = True if ok: line = editor.text(editor.getCursorPosition()[0])\ .replace(os.linesep, "") indent = line.replace(line.lstrip(), "") txt, lines, count = itm.getExpandedText(varValues, indent) # It should be done in this way to allow undo editor.beginUndoAction() if editor.hasSelectedText(): line, index = editor.getSelection()[0:2] editor.removeSelectedText() else: line, index = editor.getCursorPosition() if lines == 1: count += index else: if len(indent) > 0: count += len(indent) if "i_n_s_e_r_t_i_o_n" in txt and "s_e_l_e_c_t" in txt: txt = "'Insertion and selection can not be in" \ " template together'" if "i_n_s_e_r_t_i_o_n" in txt: lines = 1 for aline in txt.splitlines(): count = aline.find("i_n_s_e_r_t_i_o_n") if count >= 0: txt = txt.replace("i_n_s_e_r_t_i_o_n", "") if lines == 1: count += index else: if len(indent) > 0: count += len(indent) break else: lines += 1 setselect = False if "s_e_l_e_c_t_s_t_a_r_t" in txt and "s_e_l_e_c_t_e_n_d" in txt: setselect = True linea = 1 for aline in txt.splitlines(): posa = aline.find("s_e_l_e_c_t_s_t_a_r_t") if posa >= 0: txt = txt.replace("s_e_l_e_c_t_s_t_a_r_t", "") break else: linea += 1 lineb = 1 for aline in txt.splitlines(): posb = aline.find("s_e_l_e_c_t_e_n_d") if posb >= 0: txt = txt.replace("s_e_l_e_c_t_e_n_d", "") break else: lineb += 1 editor.insert(txt) if setselect: editor.setSelection(line + linea - 1, posa, line + lineb - 1, posb) else: editor.setCursorPosition(line + lines - 1, count) editor.endUndoAction() editor.setFocus() def applyNamedTemplate(self, templateName, groupName=None): """ Public method to apply a template given a template name. @param templateName name of the template item to apply (string) @param groupName name of the group to get the entry from (string). None or empty means to apply the first template found with the given name. """ if groupName: if self.hasGroup(groupName): groups = [self.groups[groupName]] else: return else: groups = list(self.groups.values()) for group in groups: template = group.getEntry(templateName) if template is not None: self.applyTemplate(template) break def addEntry(self, groupName, name, description, template, quiet=False): """ Public method to add a template entry. @param groupName name of the group to add to (string) @param name name of the entry to add (string) @param description description of the entry to add (string) @param template template text of the entry (string) @param quiet flag indicating quiet operation (boolean) """ self.groups[groupName].addEntry( name, description, template, quiet=quiet) self.__resort() def hasGroup(self, name): """ Public method to check, if a group with the given name exists. @param name name of the group to be checked for (string) @return flag indicating an existing group (boolean) """ return name in self.groups def addGroup(self, name, language="All"): """ Public method to add a group. @param name name of the group to be added (string) @param language programming language for the group (string) """ if name not in self.groups: self.groups[name] = TemplateGroup(self, name, language) self.__resort() def changeGroup(self, oldname, newname, language="All"): """ Public method to rename a group. @param oldname old name of the group (string) @param newname new name of the group (string) @param language programming language for the group (string) """ if oldname != newname: if newname in self.groups: E5MessageBox.warning( self, self.tr("Edit Template Group"), self.tr("""

A template group with the name""" """ {0} already exists.

""") .format(newname)) return self.groups[newname] = self.groups[oldname] del self.groups[oldname] self.groups[newname].setName(newname) self.groups[newname].setLanguage(language) self.__resort() def getAllGroups(self): """ Public method to get all groups. @return list of all groups (list of TemplateGroup) """ return list(self.groups.values()) def getGroupNames(self): """ Public method to get all group names. @return list of all group names (list of strings) """ groups = sorted(list(self.groups.keys())[:]) return groups def removeGroup(self, itm): """ Public method to remove a group. @param itm template group to be removed (TemplateGroup) """ name = itm.getName() itm.removeAllEntries() index = self.indexOfTopLevelItem(itm) self.takeTopLevelItem(index) del self.groups[name] def removeEntry(self, itm): """ Public method to remove a template entry. @param itm template entry to be removed (TemplateEntry) """ groupName = itm.getGroupName() self.groups[groupName].removeEntry(itm.getName()) def changeEntry(self, itm, name, groupName, description, template): """ Public method to change a template entry. @param itm template entry to be changed (TemplateEntry) @param name new name for the entry (string) @param groupName name of the group the entry should belong to (string) @param description description of the entry (string) @param template template text of the entry (string) """ if itm.getGroupName() != groupName: # move entry to another group self.groups[itm.getGroupName()].removeEntry(itm.getName()) self.groups[groupName].addEntry(name, description, template) return if itm.getName() != name: # entry was renamed self.groups[groupName].removeEntry(itm.getName()) self.groups[groupName].addEntry(name, description, template) return tmpl = self.groups[groupName].getEntry(name) tmpl.setDescription(description) tmpl.setTemplateText(template) self.__resort() def writeTemplates(self, filename=None): """ Public method to write the templates data to an XML file (.e4c). @param filename name of a templates file to read (string) @return flag indicating success (boolean) """ if filename is None: filename = os.path.join( Utilities.getConfigDir(), "eric6templates.e4c") f = QFile(filename) ok = f.open(QIODevice.WriteOnly) if not ok: E5MessageBox.critical( self, self.tr("Save templates"), self.tr( "

The templates file {0} could not be" " written.

") .format(filename)) return False from E5XML.TemplatesWriter import TemplatesWriter TemplatesWriter(f, self).writeXML() f.close() return True def readTemplates(self, filename=None): """ Public method to read in the templates file (.e4c). @param filename name of a templates file to read (string) """ if filename is None: filename = os.path.join( Utilities.getConfigDir(), "eric6templates.e4c") if not os.path.exists(filename): return f = QFile(filename) if f.open(QIODevice.ReadOnly): from E5XML.TemplatesReader import TemplatesReader reader = TemplatesReader(f, viewer=self) reader.readXML() f.close() else: E5MessageBox.critical( self, self.tr("Read templates"), self.tr( "

The templates file {0} could not be read.

") .format(filename)) def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences("templatesPage") def hasTemplate(self, entryName, groupName=None): """ Public method to check, if an entry of the given name exists. @param entryName name of the entry to check for (string) @param groupName name of the group to check for the entry (string). None or empty means to check all groups. @return flag indicating the existence (boolean) """ if groupName: if self.hasGroup(groupName): groups = [self.groups[groupName]] else: groups = [] else: groups = list(self.groups.values()) for group in groups: if group.hasEntry(entryName): return True return False def getTemplateNames(self, start, groupName=None): """ Public method to get the names of templates starting with the given string. @param start start string of the name (string) @param groupName name of the group to get the entry from (string). None or empty means to look in all groups. @return sorted list of matching template names (list of strings) """ names = [] if groupName: if self.hasGroup(groupName): groups = [self.groups[groupName]] else: groups = [] else: groups = list(self.groups.values()) for group in groups: names.extend(group.getEntryNames(start)) return sorted(names) eric-6.0.8/eric/pylint.rc0000644000175000017500000004120212355773516014327 0ustar piotrpiotr# lint Python modules using external checkers. # # This is the main checker controling the other ones and the reports # generation. It is itself both a raw checker and an astng checker in order # to: # * handle message activation / deactivation at the module level # * handle some basic but necessary stats'data (number of classes, methods...) # # This checker also defines the following reports: # * R0001: Total errors / warnings # * R0002: % errors / warnings by module # * R0003: Messages # * R0004: Global evaluation # [MASTER] # Add to the black list. It should be a base name, not a # path. You may set this option multiple times. ignore=CVS, .svn, .hg, .ropeproject, .eric4project, .eric5project, .eric6project, ThirdParty, Examples, Ruby, # ignore autogenerated files for Qt designer forms # Checks Ui_PyLintConfigDialog.py, Ui_PyLintExecDialog.py, Ui_SyntaxCheckerDialog.py, Ui_TabnannyDialog.py, Tabnanny.py, # DataViews Ui_CodeMetricsDialog.py, Ui_PyCoverageDialog.py, Ui_PyProfileDialog.py, # Debugger Ui_EditBreakpointDialog.py, Ui_EditWatchpointDialog.py, Ui_ExceptionsFilterDialog.py, Ui_StartCoverageDialog.py, Ui_StartDebugDialog.py, Ui_StartProfileDialog.py, Ui_StartRunDialog.py, Ui_VariableDetailDialog.py, Ui_VariablesFilterDialog.py, # DocumentationTools Ui_DocGeneratorExecDialog.py, Ui_EricapiConfigDialog.py, Ui_EricdocConfigDialog.py, # Graphics Ui_UMLSceneSizeDialog.py, Ui_ZoomDialog, # Helpviewer Ui_BookmarkDialog.py, Ui_SearchDialog.py, # Packagers Ui_CxfreezeConfigDialog.py, Ui_PackagersExecDialog.py, # Preferences Ui_ConfigurationDialog.py, Ui_ShortcutDialog.py, Ui_ShortcutsDialog.py, Ui_ToolConfigurationDialog.py, Ui_ToolGroupConfigurationDialog.py, Ui_ViewProfileDialog.py, # Preferences - ConfigurationPages Ui_ApplicationPage.py, Ui_CorbaPage.py, Ui_DebuggerGeneral1Page.py, Ui_DebuggerGeneral2Page.py, Ui_DebuggerPythonPage.py, Ui_DebuggerRubyPage.py, Ui_EditorAPIsPage.py, Ui_EditorAutocompletionPage.py, Ui_EditorCalltipsPage.py, Ui_EditorColoursPage.py, Ui_EditorGeneralPage.py, Ui_EditorHighlightersPage.py, Ui_EditorHighlightingStylesPage.py, Ui_EditorProperties1Page.py, Ui_EditorProperties2Page.py, Ui_EditorStylesPage.py, Ui_EmailPage.py, Ui_GraphicsPage.py, Ui_HelpDocumentationPage.py, Ui_HelpViewersPage.py, Ui_IconsPage.py, Ui_IconsPreviewDialog.py, Ui_InterfacePage.py, Ui_PrinterPage.py, Ui_ProgramsPage.py, Ui_ProjectPage.py, Ui_ProjectBrowserPage.py, Ui_PythonPage.py, Ui_QtPage.py, Ui_RefactoringPage.py, Ui_ShellPage.py, Ui_TasksPage.py, Ui_TemplatesPage.py, Ui_VcsPage.py, Ui_ViewmanagerPage.py, # Project Ui_AddDirectoryDialog.py, Ui_AddFileDialog.py, Ui_AddFoundFilesDialog.py, Ui_AddLanguageDialog.py, Ui_DebuggerPropertiesDialog.py, Ui_FiletypeAssociationsDialog.py, Ui_PropertiesDialog.py, Ui_TranslationPropertiesDialog.py, Ui_UserPropertiesDialog.py, # PyUnit Ui_UnittestDialog.py, Ui_UnittestStacktraceDialog.py, # QScintilla Ui_GotoDialog.py, Ui_ReplaceDialog.py, Ui_SearchDialog.py, Ui_ZoomDialog.py, # Refactoring Ui_MatchesDialog.py, # Scripting Ui_LoadScriptDialog.py, # Tasks Ui_TaskFilterConfigDialog.py, Ui_TaskPropertiesDialog.py, # Templates Ui_TemplatePropertiesDialog.py, Ui_TemplateSingleVariableDialog.py, # UI Ui_AboutDialog.py, Ui_CompareDialog.py, Ui_DeleteFilesConfirmationDialog.py, Ui_DiffDialog.py, Ui_EmailDialog.py, Ui_FindFileDialog.py, Ui_FindFileNameDialog.py, # VCS Ui_CommandOptionsDialog.py, Ui_RepositoryInfoDialog.py, # VCS - vcsCVS Ui_CvsCommandDialog.py, Ui_CvsCommitDialog.py, Ui_CvsDialog.py, Ui_CvsHistoryDialog.py, Ui_CvsLogDialog.py, Ui_CvsLoginDialog.py, Ui_CvsLogoutDialog.py, Ui_CvsMergeDialog.py, Ui_CvsNewProjectOptionsDialog.py, Ui_CvsOptionsDialog.py, Ui_CvsSwitchDialog.py, Ui_CvsTagDialog.py, # VCS - vcsPySvn, vcsSubversion Ui_SvnBlameDialog.py, Ui_SvnCommandDialog.py, Ui_SvnCommitDialog.py, Ui_SvnCopyDialog.py, Ui_SvnDialog.py, Ui_SvnDiffDialog.py, Ui_SvnLogDialog.py, Ui_SvnLoginDialog.py, Ui_SvnMergeDialog.py, Ui_SvnNewProjectOptionsDialog.py, Ui_SvnOptionsDialog.py, Ui_SvnPropDelDialog.py, Ui_SvnPropListDialog.py, Ui_SvnPropSetDialog.py, Ui_SvnRelocateDialog.py, Ui_SvnRevisionSelectionDialog.py, Ui_SvnStatusDialog.py, Ui_SvnSwitchDialog.py, Ui_SvnTagBranchListDialog.py, Ui_SvnTagDialog.py, Ui_SvnUrlSelectionDialog.py, # ViewManager Ui_BookmarkedFilesDialog.py, # Wizards Ui_ColorDialogWizardDialog.py, Ui_FileDialogWizardDialog.py, Ui_FontDialogWizardDialog.py, Ui_InputDialogWizardDialog.py, Ui_MessageBoxWizardDialog.py, Ui_PyRegExpWizardCharactersDialog.py, Ui_PyRegExpWizardDialog.py, Ui_PyRegExpWizardRepeatDialog.py, Ui_QRegExpWizardCharactersDialog.py, Ui_QRegExpWizardDialog.py, Ui_QRegExpWizardRepeatDialog.py, # XML Ui_XMLMessageDialog.py # Pickle collected data for later comparisons. persistent=yes # Set the cache size for astng objects. cache-size=500 [REPORTS] # Tells wether to display a full report or only the messages reports=yes # Use HTML as output format instead of text html=no # Use a parseable text output format, so your favorite text editor will be able # to jump to the line corresponding to a message. parseable=no # Colorizes text output using ansi escape codes color=no # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be # written in a file name "pylint_global.[txt|html]". files-output=no # Python expression which should return a note less than 10 (10 is the highest # note).You have access to the variables errors warning, statement which # respectivly contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (R0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Add a comment according to your evaluation note. This is used by the global # evaluation report (R0004). comment=no # Include message's id in output include-ids=no # checks for # * unused variables / imports # * undefined variables # * redefinition of variable from builtins or from an outer scope # * use of variable before assigment # [VARIABLES] # Enable / disable this checker enable-variables=yes # Tells wether we should check for unused import in __init__ files. init-import=no # List of variable names used for dummy variables (i.e. not used). dummy-variables=_,dummy # List of additional names supposed to be defined in builtins. Remember that you # should avoid to define new builtins when possible. additional-builtins= # checks for : # * doc strings # * modules / classes / functions / methods / arguments / variables name # * number of arguments, local variables, branchs, returns and statements in # functions, methods # * required module attributes # * dangerous default values as arguments # * redefinition of function / method / class # * uses of the global statement # # This checker also defines the following reports: # * R0101: Statistics by type # [BASIC] # Enable / disable this checker enable-basic=yes # Required attributes for module, separated by a comma #required-attributes=__revision__ required-attributes= # Regular expression which should only match functions or classes name which do # not require a docstring no-docstring-rgx=__.*__ # Minimal length for module / class / function / method / argument / variable # names min-name-length=2 # Regular expression which should only match correct module names module-rgx=(([a-z_][a-z0-9_\-]*)|([A-Z][a-zA-Z0-9_\-]+))$ # Regular expression which should only match correct module level names const-rgx=(([a-z_][a-zA-Z0-9_]*)|(__.*__))$ # Regular expression which should only match correct class names class-rgx=(([A-Z_][a-zA-Z0-9]+)|(__qt[A-Z][a-zA-Z0-9]+)|(__kde[A-Z][a-zA-Z0-9]+))$ # Regular expression which should only match correct function names function-rgx=[a-z_][a-zA-Z0-9_]*$ # Regular expression which should only match correct method names method-rgx=[a-z_][a-zA-Z0-9_]*$ # Regular expression which should only match correct instance attribute names attr-rgx=[a-z_][a-zA-Z0-9_]*$ # Regular expression which should only match correct argument names argument-rgx=[a-z_][a-zA-Z0-9_]*$ # Regular expression which should only match correct variable names variable-rgx=[a-z_][a-zA-Z0-9_]*$ # Regular expression which should only match correct list comprehension / # generator expression variable names inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Good variable names which should always be accepted, separated by a comma good-names=i,j,k,_,s,f # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata # List of builtins function names that should not be used, separated by a comma bad-functions=map,filter,apply,input # checks for sign of poor/misdesign: # * number of methods, attributes, local variables... # * size, complexity of functions, methods # [DESIGN] # Enable / disable this checker enable-design=yes # Maximum number of arguments for function / method max-args=5 # Maximum number of locals for function / method body max-locals=15 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of branch for function / method body max-branchs=12 # Maximum number of statements in function / method body max-statements=100 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of attributes for a class (see R0902). max-attributes=20 # Minimum number of public methods for a class (see R0903). min-public-methods=2 # Maximum number of public methods for a class (see R0904). max-public-methods=20 # checks for # * external modules dependencies # * relative / wildcard imports # * cyclic imports # * uses of deprecated modules # # This checker also defines the following reports: # * R0401: External dependencies # * R0402: Modules dependencies graph # [IMPORTS] # Enable / disable this checker enable-imports=yes # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub,string,TERMIOS,Bastion,rexec # Create a graph of every (i.e. internal and external) dependencies in the given # file (report R0402 must not be disabled) import-graph= # Create a graph of external dependencies in the given file (report R0402 must # not be disabled) ext-import-graph= # Create a graph of internal dependencies in the given file (report R0402 must # not be disabled) int-import-graph= # checks for : # * methods without self as first argument # * overriden methods signature # * access only to existant members via self # * attributes not defined in the __init__ method # * supported interfaces implementation # * unreachable code # [CLASSES] # Enable / disable this checker enable-classes=yes # List of interface methods to ignore, separated by a comma. This is used for # instance to not check methods defines in Zope's Interface base class. ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by # Tells wether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # checks for # * excepts without exception filter # * string exceptions # [EXCEPTIONS] # Enable / disable this checker enable-exceptions=yes # does not check anything but gives some raw metrics : # * total number of lines # * total number of code lines # * total number of docstring lines # * total number of comments lines # * total number of empty lines # # This checker also defines the following reports: # * R0701: Raw metrics # [METRICS] # Enable / disable this checker enable-metrics=yes # checks for similarities and duplicated code. This computation may be # memory / CPU intensive, so you should disable it if you experiments some # problems. # # This checker also defines the following reports: # * R0801: Duplication # [SIMILARITIES] # Enable / disable this checker enable-similarities=yes # Minimum lines number of a similarity. min-similarity-lines=4 # Ignore comments when computing similarities. ignore-comments=yes # checks for: # * warning notes in the code like FIXME, XXX # * PEP 263: source code with non ascii character but no encoding declaration # [MISCELLANEOUS] # Enable / disable this checker enable-miscellaneous=yes # List of note tags to take in consideration, separated by a comma. Default to # FIXME, XXX, TODO notes=FIXME,XXX,TODO # checks for : # * unauthorized constructions # * strict indentation # * line length # * use of <> instead of != # [FORMAT] # Enable / disable this checker enable-format=yes # Maximum number of characters on a single line. max-line-length=90 # Maximum number of lines in a module max-module-lines=1000 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 tab). indent-string=' ' eric-6.0.8/eric/pixmaps/0000755000175000017500000000000012557365404014141 5ustar piotrpiotreric-6.0.8/eric/pixmaps/ericSplash.png0000644000175000017500000040572712342634027016753 0ustar piotrpiotr‰PNG  IHDRÂæÉ0†sRGB®Îé pHYs.#.#x¥?v |IDATxÚŒ½k¸­WQ&ZoÕø¾9×Ú;;@¶n^€GT0ÀI r‚\ —VÅ4`s9¶"ˆ¨€€€€x°in^h/}úð*rGT8È%( IØdg¯5ç7ªêü¨ãûæÚÁ§·>age®ysŒUo½ï[øìGÿðÔ¿ZÝȰKY.DäVËxö@ìdà¹k){›ƒ«u:½=ýÕÃë¾²=ýÕk¯þÔíïõëÌ °Ä3¸›»Ì@<íääf:m«š33À€¸ÀD°“Ç_v'"'""wS°ÛT'S­UE ""€»9&€äæä "0ÀDˆç!09y<óÎ'wS3%2æ‘¿ÛàæVk­jB)p{ñoQ¼ ¹Ç/T#"0 …†à¦mŰÁ­º«;MÓ¶ª £f ;Q¾+ä{1˜ÁÃ+ù²›ÓþYLJaËxlÜ;gOq¬°°Ä{c0ì¦èt?Æós²Â2ºkü.1ƒÄÄ̲’²fXV,¹—ul!"`et7w³zhºÝ\ –ÃS_rSN×é:Óíµÿöîzâ¼ vW‘• û\Vm=ãÇ:“[uˆÙu"€Üéÿoשÿ®Ù»4·´UjÛËm2«äæîîjºm_¹»Ûöð€§ƒ¯™MV7ñÌRÖ± NÎ2ÆÓN‡_SÝèt@D–/mZããEÁân›Mu's'"aLÕˆH-_SjNDª.7ÃÍÕÈÜóžŒg0sf˜yžª‰@Õ݉™˜Á@ü†¶“Q<ƒ0õh5ò4ÙÞºôç$¢ªNDëQÌ};ÙþZÌèç|“ {eu±¬âôɰ×ÏÀ̤ÄʰŒÌ,c€ {D(ãñø Óá×ܵ/IY›MDT·§ˆÈµº«[-«`AœP‚»õ½!²Ž,ýüF`1Ý’Ûò% Cºø'—5Åv­BD_ÿ"mNÿ›”=°ÝždÜ»annÂâ³qâ5L§Ú„¥½†¬d:m:±ŒRÖãþ†ë¾€¨¯ˆn±5áyØÍÔ¬º€Õȱ?Ü­EÉ€Ý@_<2> ›MuÚn·UÈ voGºÇ9Ï(€ò\_'ˆdl_”ò¿fdw'7€™c›!ž*Bç2ì"{Ó=‚pD7´˜ '‹533AΰK Xy G["À…@î¦:Á‰V£hœn'òJŠÛ˜·;s³µƒíïù¸*RöDVeuVÝ\ëVÝ”yp.€D Xéne<zy©˜nYÆP ’_ \È=o:¹[„ )kr—²GnqóEÔÈ L’LÆX4–‘Ü´nÜÕÝŽŸó­DÎ<˜UÓ x 7°¸i„N–âî "7”•Nî†"ñƹ2HÿŠ)W†À…ÈpW×ÉüÐÝëtå}Ó-¯–öu›U€‡ÕÙ¯önä®fSlK@ÜÕMëö”ÕC³¿%²"3"bÀEdOU§ëÈ]ë¡ÖÃ2»öÔ5©#w®ym'"%rssRs‘øÄ‘a/îõØ©æÎ "ŠŠ€.ù0iß*žŸáæ¥@D´^Éz%Ã0æÒ-ŽIŽÅ—È2‚xÜ»¡é¤ÓA|;q?€ 2PRd®æZ!ÅtŠD!"Q„ˆºùºYe#û1\Ö”“}:ˆ[“e$b´OÔîQõ¼ì#\0óà®^Õê†"MœƒÆ÷e: … Ddõet›Ài[ÒØöJ2ì2¬Ï&° û‘Ü'·ºq×2ì‘“—¹GTu7wG»ëXÆÈF#fÓâĬFž’ÙPBwÄÆ€»‘Mœ#ÂF\ž¹|y€#j¢§}MÚ®Ó´™ªa(ÄÌÌ)ËwD‚·GêDDÄää^ÛÓ2À„È‚dæëêDfJ‚C"Vy¿ïÀ‹Dô8<‘Bî†!@ãnd*Å”Øè=ãnWˆIüݽ’“jU½BTrwòx¡¸9úïºÅ©v7r*ãÀãÙ±Î) #"ë\¾Õùïhº}ûšé[¬‚œ»ÜœŽùeŽ×uWWuS€©6ð2Æ -/§‘ ºÍ”3~…h ±{Ü a$nsqwp‰« `çY/rO+“y ¶I"޹鶝 D5cVÍ&o¹L„ ÓêÞb®»Ù”ßx¦Í?t723ÝšV"Ó:¹ÕÍÖJÙ))¤N,ljæ"QT4cNˆ€{f5•9&çm—Ï9ïHsméüü„ ™—"óî%,ªww0‹¬ã ˜¶×Â<¸)x™Æx+.=n ó 6ErçZçâÌRÖQCôMÀ‰çúÁúçT"9òy£$sQÝF=A`änœ–›"€”qt7W㨞Ý#”»MD¤ÅÅ.àÝFAÖ>luò"²¶qÈF/0Dïî,ËGˆ£¬+k°;Ë(eU§Ó\Ö/0×Ý‘ë¹õ<ËÝÕªV«UÍ f2·¨>zD^,©dæW`8œ'SݪeàRò{57(;)säN‹"2Mf€È=Ê|"qžM.Žó@ñÏx/¦>'1LÄ`{ù‰\‰˜yhg5>÷À„œß¶šÅý1¿M·ˆƒÈ33Uµ©ª΀i_1Ì+æùiÞKñÖÜâüLÕX&ÓIëáöôW!¹* nFdž+X­‚‹ {,£«µàN@FÏ^òÄ>@n®q‘CAdV™,Z™K83Ð!²]W‹T$€8<4SV|nZÀ,ƒéN$5QÅu«‘óæ!ƒÄ3œpöT·¹jÜ”Q'yfÖ›¶IcÝ”ÜЫ Ó¹L‰¥Ì ˜"O'"ŽJßh”QR[Âs™»qYE:a"jRÓjº9<Ül'k¥ ÇU7'7½Q¯—ó;±ƒAêË+oYãGîÙŸ¡§œýIÖ# FCasÏ€ÕÒ—Øîʲá"P›nÁeYùBÓ 81KAVŠÒ×2˜)Y•²—@ÔUñ¢¦˜n=·1{K`~$²†G-ÒÌøB­Z\“ñœí¿E‘Þ¾™jVEVq=»‹eÔé\˜…Á¤FB^+qõ«y¨YȽdlˆ<ňy æ<~ÈÊKdE½vƒ€Å]ƒSfÚ=…l‡r2«3efæÁLÍ´ªiõ}Ja†093˜UriÄ¥£W-h¹D†(¶c£©šSüŸºyFFñ–AÄF‚±§(ÅÝ\·Dî‘ ÌûÞˆ(îRÏÐÖö‘É[ÎK ˆÚØEE"Ÿu_œ«E}r2wÉÓ«‡¦ÌàâæfUÕªz­nîE¸³Pa,VL‰ÌLÝMÕˆHD$˶LÕv•–¸EÎeºÉ\Ãjà˜}²,hå•»eÔÉ;ݶ"±yÈ]3º‚³ *j5*#öb±Ý"Ë‹°g÷pf:9ªÕC){RötºŽd <‘e•Y¤u\‘?j  nDLDZݽ´^úiCræc·û€ž zÖòyöƒº„ÞñÝé6øE¦’h£+ ¦›@?¢ÅMé(¥s½­‚8;Šó[ wÒzà:EÑܨBnsŸÈ‰Áœ½è¾ý{'†ÞÀ )«^õ`ã¦ÃjÊ%âÂeU¦Í×u:-²î85d b.ÀŒFQÆ\ÀC ¤Ñ@P!)ëÊË–ífëN,LDª&âEØ ãXÖëlš«™¹MÑósŠÄ“ÈEÐ NóÂ- Ä0â‡ÆW¢Óf³U•Â{ëôÄn¤á8Ø.Z Ðn?¹»:skáhÝ6¢¹:óVíy¡Ö‰ÈDJË×8o׏ТÌXœØBÄ=‹Î¯Yô‡„AäÛÍ¡9D‚ª}(lFRd]¤ Ù©´Zd""¦"Z{ªq$â0 ½Ó¦æ…,Þ^´XÆÈ‰úã7^fÍ}:™kfg‘¢¬ðüêª=èè5õ<‚Lî:jÝHY¸ “ê¤u“F$DŠš¿^§«nOÁ\Ȳ r"×m|(·:¬ÎnL w÷HHM‰À²JÙ€8“ ûfS@¨-aŒÈà:A†t¸ íŠÒe²“mìH¯âm·ŒÕlŠç%þgoÿxtZjm(¹ÎÐh@=ãÀædjÄ$Œ­zito•ë³eSËK•%7| IË*¾GÕøÅÕªtЏÔíA¾è ®Å®Ž ̃/à¦ZO»Y”q¢0Ä¥hVyØ[ÜÐŽrp@ß^ždwu­ÎBäus20øGv³Î¬@å춨ÛÐ|Æñ{ ’ÜÜÈÙ‚ÓKê¦EÞ¬êº5›òüZm×a>rÚœYC2ÄE·änÕ•KÏê˜ñ¥ ±åX>cÞÑþçÂe•áFfê‰ÖCÓíz=,r4 F‘ˆªÖZ3Ò«Z´˜b€€~I·¦|§þèN˨Ud¦ÕÌ£œ.E%s¢(«‰Ýk¼óDÁD–©¤)ÀÁÔa§š_Cà¡`ÌÐõN7?«N°0;±;™+‘‚¤ÁsH Ç3ÆînªÕÌTÝŒ¼aXCÖëqwÅ@3«µN- [´˜2×b©Ü="_®˜«yeÇv":Øè8°éäÅ"¢EÛÝÉ@»6Î?g>ˆ @ÍU-„àNg@HÐÚÙÖ;ÙÔf ¥Ì´ž(…À`©Óé¾J¦ÛˆžxÄÙÅŠô‡¤™OÑ sWZ`aÚšEî>¬ÏŽí¡ÓA,=‘Å]ÂRˆ e]§Ó-Ô Äɬ’Ã\áqŸˆxØ p-Þg–¨^{λ ‰öª ;H <>ÈY-Åž"ú™Kò˜L&w+C02XdÜ›­Æ×môq(Á…ˆÂLDÇŽŸ]¨ñ/o¿ÈcLmYÅ #¨”5³”º½ÎmbÞén5ªâiiOJ:Î+ØÏå€qÿFnÓtx2‘Ùéc­2jÉKT勦9—•™×¦`Ùœ1$#š÷›Œ²®×ƒÌ´buË*îNrça/“\W@âžÈΰÃ]}šw-ÿT?€n¤¬pW÷ 0m˰:+0‚Ü1@¬l#´¬ ƒÈ˜U^Ö5…Ëj„J4eÓzȲ2›(ËØݧIÁp#óï8FÂâ•ÂíêöH{-Ú¹wCïÿÜëP$¹DZ7λ€G-Ìed‰{ÂÝäZ™ºWõüORÖÞB…»‚ØIÜœÈ4ÉÄf‰xJÁ¢À@ª¦ê¥ð0H)Žv [ÓF<®µyň¬fªž¥˜1 À,‘å݃¹’g6Ë Å\6=} Q9›2jäähD`qÕF”+;0¢7«ÛÓw€¤uCDÌšnšÓYÕ(“Åh""˜k„z;˪D»’A–ö­PÆãăÈè`»+[V‘,‡fɰg:õ¶;µïdè04ËYI”ÞÑäéÈ/ Ô²_tº+—àÖ¸MYö+|:$f9šÎnà"\¬n¢â ÖcI$±”}"RÝdØÕmì+b&3³É½¸Ûj Ñj5¡ŒÇ‚Pʦ_l¦[7Sóí”Ý `/MÕ:k*LA;%¢"‰g$Ä”µÖ$”HÊ>KÏKâ8~ŭʰçn ˜Bà¼`‰ï\2mw-Àu: ²Øc¥ìGBåh¤¥6m—„ƒØu…ö³ruÕݶüfÙÇ‹k,nM×ÉãVë=¥9ËFÔïj“k%æíá˜ÙmÒ,FÑ@X®:Å zN§Ý­¸VÓ:S©¥4PÏ"îJY'=Ln,#x° Ÿ—‹éT·§¦Ã“:®ÛS‘Çó, .æ²à½'¸Nî¤Z;‰ZU™#c2H¿ ­­D²b‹›Õù7ü¡¥NR$™VkW‚Do×l«jœSIØiA0Èþ¨{­['7%'2u57w£DGD( ž{§ù݈à gF)¥dfôà$ÿ:‘%ºÐVÌlró Q1XøÌ‹’ªfáæ}Å:ɹÅ‚àÞLvú°N•÷Ör|¿˜n­æŽ6«›æá€ÖC€-ÏùLÎw3ÇóG>U°ewE„ Å„©u  3b^"S€˜wÏpÆÔÓ)Ø V#ËÏ[ÎM-ÊÆvyG?xÔ–u¢1 Á¬2«YK2»UP ­Z€ùÒwomÕ£ì!Hr¸¸˜M ´‰úíÎe%!âh͆($¥E[n€d’©n‚…¹ÞvúZTБ»;ëÄn¯Oã¨ös׈¨º=@U.ýÐù`(‰@ëõ^ Jòñ]GMSÊþ2ª¶BÃê„›FW=¶NÎ<J˜—ä™å:Xvù KT-ºÞýu‚iå†PIYõ"Æ«¡å1$¥ƒ¶ÁÕr‡´õô¶ß2?µèv öFÅŒ¦hìO2s²sˆ£…)DnºaY%õ5Ø#4/ÄæLBz‘äùl§6¦4Ð{ «Õú=pÕ©ÕºaP¢ 4÷"e°ÝNÎ&eHŒÑˆKYEŠ-ºÛѺ‘@»šJ'àh1EWY7›­h½.²¸nêhOh¼t7õä_¯ê¦®¶I;ÅR˜a yBÚ!.7Ì<òhŽ>xç vU¸V7F ö%'`à~ï¹Öº =R¼U/E†ÂS­µN¥ ›™»:¡”sa1jlÜv®¤C·‘á9¸l¶vúPOãƒC­Ç|EDÌ 9˜MYÆ;¼=Þ¢•Ipòqïœ.pšºM–u'T7¨Ë\ÍýPÊ:áu°ÖÓ=ÓÌì†Bºã3ysèü-&஡ ‹¨&šQ7ƒh6¹NI þ‹YÆíˆFo­ÙeQI" @¦œEKÓŒ¸a™[i°d<Ú ýöíPcëà/šf“9JÙêJÙÝYuˆN§ÁË,ŒÈ ã’‹šiÜ»aÝž6ÝH˰Ô* Ìš="Fp•T]ÛOÔ¼V‹˜n{z(eí¬‰ãâé4¦Ôt@’ Ûx¡)™rY·d ZÉ\m²ÌŸdæð°3—Ø!)u,r†ä=PÔÀŽ—e=B XuÃÙßGr±]°ÅzAÀˆpqRRí=À¼IÐâ&r7ŸâŒô§²ˆæ;¢›l?×)vÿÜk”®èµuùT4dãagˆ[&×É´F!S†uSjºI{gÃ0ÐÌÈKqeA7ìîé42sjM€j^Ýlš&0Æa4Þl4‡‡43˜ê"Ë«UµV¯Õ¢/9 < TÕÝ£¯êÑ"*´¢8J’M67 =ë|.MÝS~'RÆqÄj'‘Œž vyí¤t’;saNä¨H!r"WÜ™%•¸‹ÆN‹£¹b +3<à¨õV#Û+Ìwƒê†¹$²V;»~è’38Ë‘½åVžiašäó”ý•5¹»V.«®åÍgËw¢æ‡½­MD¾Q·š¥3¹%I£Õ€Ae!Ó lr¢’… "«Î uCnË$ÚÝ`ÚÕœ–;|yU¾Ÿ.®Óêd!èj„- ÑÑ’þ Ó­×ÉÝCâ0¢¶ èÐhå®dÖ¨ˆ¾hS°Q—¼ŠEXû‘Îs|ÞL·Û¥ jvô¬£È(ã¾Û*Xýe<ÎÓhº5d)‹^ët]ÕŒž¥ðPB!‚Þt>λÈ^R"ˆê!sîR Ôå6ñ‹ÒàE@XŠÖÖCN_‡ÙTÆã Èx̵êtºÃ5`ÑzÐYý9#kéróFÀ¬TN¹@¿Ñ§åžØ}Cõ4óÐà ‘­X:Œ® 0m{ػʳNÔ"º­95k£adÃë°È°UË*‚µÞË"S“Öà³DúMëöTòàZ·ÔÌs+kíô«5õ?,Ë5Êøã<[ô÷ׄ±ʺÏpZ@Öæ^«¯×½¾‹‡¶¯%8 ÔZ·›)\„‡2;]oŒ_ tŸñÚN ‚Hq×Z'3*q‹„4\âÎxak’ƒÊ®Z°`/®GoZ#wÒ  ¶d±b UK †E˜À-õóhþγ.j¥CP€ÈD°9˜‰f4i){îF¶(¥Ä‹æ.!„O–uãEf"PŽ%ý' ¹¬²Ùºä0oÞ7Y-™ƒ üë–¹DÒâ:,º€ ƒ•6]I RÊȲRM¥öf«äÄfæZ'"GÖtƒÈ0xÿ°Ìµ‰ñM­áùä‘Cz6ÄG³qX7AwéœÞÎ!m”Æ Tβ‘ÿ­K±p‹;VÝk£ƒ¤ŽÖ[ÚNîà2ªúfk§TÃÀû™åm³–,ÈêÓu)lѰ:+š¡!ÑétϬ»ˆ3tÍD)ŸÄ\T•˪S;[.¾”nžž[ùÞÌAÂÿbŒãêd etµ ²öµí ñ—q}ÃÀ‹Ü&ÓI†=¢=÷“é)#ŵªº·6•£÷\ |êFÖ²Tx}‚Ñ[ó®4ð"0 "0«Ñâ÷¼†üWX’Át²íaPâ .ËÕ–—IÞ—ÑhY«fÕ (n 1Ê*˜¯“QkÄB›M-cé¡|)5t3ö¸‡ô%éÌ%ªºÔ•ù°´àÐéÀ­&1vÖãy~ãVÃ7R,­ÛSfS‘I3)ëh͇Ô2"¬Œû­_(G×`H§$n4ò@4<´ŠÍI¶@,Hd'´ÉÄå2÷¹ïžlåû6Êù8%Z×Ñ‘o|&ß©¯›þ §(*ÄfSF½PßÇÇ`æðÑ»ÖIä‹ðYdNæpÜ8àצUˆRÕZg vÄM`ÌCô‰\à(““ªnÝ]$0GcHþöÖÖÕâfSv‹ˆÌâœÃhb.Óºaæ9}FªL=HË, ݘægô´¦²ž¼´Ljnbî¬í¬Xb©¡‚5#RÊ„Ý{^“ÔE·àæÅNÈñý2^|âX9q¬HY‡O€÷ùår‰&8“›T›(v{úªv$È@®U­±ÍòT3KYà:‘”ŒL' õé>ºi´h[ÚåËë9Šz­§;5mO± ²¨µA0Ù&o·‚˰:+Õ¥V•³Ã Ã^1˜‹‹Úá‘ ”‡AIÖÂqæ"Dý´ã>Ã’!µ]­4~œ])ÀuRÝ€Ž., K Á¸Ym¦*5]©§éQŒbS?Éñø‚˜å–~XßÀ=X´F'n•¨8[tüXÆÃS_"b×D4¬KN®›SMYmd‹ï;n)pð{jwN\ƒWЭ³š”ÞÌ”\Í•y`³#G ¢ï¿ý97>ÿæÃêìqÿÜÕÞ9Ãú†Ãú;ª…&¯À–g¡wQw”9Gš0iÅBËJ∜aѺլ{ˆÄõo¿NNœ¡sìv qò>k.‹³3–ñ˜¯o`6­öo”gÞ*íý-GÔ£^Óe=¸s4:µv± Xª{RkÀ…7âJtH­]r°A2© %ô.+cÑ-˜_b¡1Û½{–Jë}-qÃYÁÙXËUÝnQÿ¯Ë§=ãkB‡¤Î¾ÉíᄎôNf\ÂôÈ[ÊJ‰ÎÔ¥Yb~}’\:sý“6·ˆtرSùŸb×úrùMaî•™QwFQ^‚S½p¯9Ó/åhC)À¦fcã!ÃzGtßZ`²Ö&ÛÆöÝluixGD¥È0¬B^²H™)!Ôàºç Y% ~R4s×q Š»¶œÑ¾î^#¿ÜßY2㎫’!ÖeèÔq5¤¬ƒi¦é'âU«MS îúМ=ãýpzn&PK '!7fw·Õ*Mç2ƒNÓ ·Ðî e ‰7l®˜›šmU'"š&SsF“D8‰`W"ë…èáUÃX'»+]2L“M‡'›w™çzödª^‹ùh0[ö%Ó¢ô|-z"]~3ò–¸Ÿéð»sð£¾^:]zÈZᲚܽw£:IJmØ}Bu:M³ó¯ÏŸÎlÜ´*éV͸$Ÿy'·Úq‘+`ç†s_HFe·QÚ½G©éµ–æ#½¤X^š®iÁWq6º¾?G“]’uð¸§!½ÕjäÐv¦’ÒÉ;AIäTÓm€_qíG.Z¤¸8ZK®áw>KCihøŒ Ç NNdf“Ù¶ùé–PÂ@àHóVtcD$B<æ-0®¥HI†xwÍ85z8Lᄤ`ËS$ÐàvjËa,·i¸Ì–…Cs7ð NŽp2Ø35Ýj=Ì«²•í"‹ƒ‚&åªru³È›\ÈIöd^ÝsÌwŽ973uÆ™á2 ý‡Ä´ÛÀD8ëÇõh¨êöºÑƒÓ7ò¿ æypq0`GðuSš-º=X÷‹lkÖ#xS ‚fU"§EH3¿XX¦§õTjѽّÌßmã¥Ã™¨;î”J¦®D]Öûs5 ¡÷ÏѲ4«N9âŸX!q³ '@‚.Úm²'n8æŒz÷@yk7FÄiéÔ’!ß»5ÍóhUR;‚µ=¿×f¥¶£:[JŒ¼³Ä¤×Ê!ÕßÝASl³# ¡4øòzîû#»1í—‚–ïì†Ázæ3”3¿ª3÷},Oר-TÅŽú¿õŒÕó»Ùé ¦ÝƒBb$®! ؘyXêÍ¿•ØŸílHŸ˜ ór"˜mÍk6Ô€PÝ™n‰ C #·(B;òì7HȱöR—BBDjªuÃŒ¨Ü·®û#̃IFDóvj×s‰»š¼=xaê“e5™ªMÕ ©’§ó z1¼IÛÁàPÚØËÆ æ!}URט¾MÑ,ËÓÕbDŒ!¿Âe'¡ÇÍ]‡’Ù‹à(¤8ÿÊ2ÙtwKS3‡7gkùFÁ”–èUó9Ÿ{£pìØÈqrŒÕ Ë@Ù}öåiôtñ0÷eÂÐozÓ© ‚­}ÀD<|Q~5ø¯/ 1äö™df̹[zª•[²ô> JÃ.Úˆ,ê˜#KM¾„’~}Ë^Ç^Að…“1úø‰% tËæ¡?ÞÀ»”Hç d ’FéW©×Mú9ç b3£æ³{&…þHÍ Õ"ï`îè_·5—KÓm3`w­Ôˆˆ}l*Xë~kÿîÅ;( ™.Ë‘ÿOé÷Ñ<´g.íîTÄæÓ‚#’Yj+ýÒ§RÊ*6J³ðælæDìK–Á]L'æàÐ -ì&’…|±¹§0£Ì¯ pSæÑ½² á­W11°!°‚|c&K}ï$³Ùk–&ÄÎj“ª‹Ä7×:täÛÌXwjä`odÀí»'¬ºÐ‡€<" ´ÎËc›IŠ5{Ž£¹EîL(f[渊†E£?xî.A¤«ªAyšó;iÏ«¬ÒŽQÉ—ÌóaqçÛ"¼òŽ*÷xAnj¾/f¼yË/ßK*‰“6ثǛÝ~NN(ØpYù,_¨g÷ó#aìév¬Ô=<×+$J[?oІÈ9h>š»M¢uÒÉO ‹»)A· JH4¼hi*Œ®]|îλžÄq<ÝB+É„¤`/J¢¢Ý¼Œ )¼5ÛÁ4²ló ú,  Ôsòö¿y>ÒÔÔ‡ >Œ“=lD¦iµH+Õ¡¦ ªÛmL7 pPÆ aÞl’Ð,J(æÜ•"ez–Ò .v·á7·AfföFÉ[͵9[u·1bBœ7ãAÊÚû7‹ Ç„ËÚÚËì®êv¹‘hYºø×ƒU\Û"WN/´RÒR<ݹÅej®LÏè´ìÐIÊjÙh&6XÜý5,¦fç‘4ê.˜Û ýð8íGŠ[wc[ê;;Ê#ŸÏAêœ}|xM³D²6I¥4[6v³ö÷ªíNHHJo#“. 7)UÞí†ù!’SÌÖSš÷bks€¤”Â94×a™¯9(þi`8‡ÍÍN =V©A÷°–³[ҷɉœY¢8§4„‚h$Æ Y8^F®‰Í~:ž¶Ñ5?—Á9`YOæžÃvG–tÒ–8ƒ–~’4™ ÑNjæÿF!¿$8—EZ´·–=¸Þvì=»6%É;¥fV—{ôvÒ},>XdಊÍÝ’K ÀTJ¶»c†÷’Ï!ßcü »{lÍODÓÀÙmšQ“æ>¼Á¦°ðJÅÔŽ:¨MCÊNÜh ¼Y€‰˜f³€AK ©‘çdb÷Žj¥ ²¥«ÕH£Ôܶ“1QjüÁç ‘AdÕLªÌÝÂ3Ñ¬Ž’×u?Éh1ÀEFæÂ ,fÀtO¦¬¶ˆ(h@õ°Ýç…ˆB pôUû škÙC”ªgj“},’$Ëí²g¥{ǘû0¥áƒ²È:ÕI–7zPk—Z½E!ld”¹Þ™ XB%³Õ)VÍÔˆB¨ŠÞ~¬Ûèx£s÷ïb1Á¢Ö?”yTHFfà’†ÞÈÉqÍfš½a¹Ó¢lnûëiÓÅ‘$Çb2`'ŠE Ñ©ÊDð„h<7 K&‚1¬–˜Ò.@qXþ[#avÝC;CÁ“@‚ÁÉÁa‘†ð÷ óSƒ¹³“3Ü=ð›˜Ä–Ä}Á,Î6.*2.‡»CŒ(Áø̶hSº9¨aÒÞ¼mU“ìg“-NµhàêáuDg©3 Bs[8Åc¥«,Îh“v·¶ˆi;Ém´¸ûzoµƒm È´ng]`«ÍÔlË>Ú»Vš{ÿw©§à™O~w¡Ÿ8~GJi_XÌ™n`¼8O_Xt“xž ½P:õœqþOØ™Gí¦jÊ\‚ºˆ ºôÊ<’ŠMâVßþ½Í~¸œ}â¬oýÖ[ýÐ=/¹üò‡íí­{°KÄÄêÓÑ’Oä³4µ…A-ñJ'^ÎpÍ•OWñÿÛGx‘P\ #‘²v™¡³¦Þmjj4ß-¥»†˜L»aŠ5{M4WI#×Ûßÿþýo z#†!G‹Éo÷ý¾Þ;écïýCoþ¨-ššÏ®­@"7GX¤;\ôc~ÏkCô?,23Ïð¸0âh,FòM$`™ØÍûOãù`ï¦3³¥›ù †n€ ÉðÅ®v‡‹óÁw¾:ù-ˆðÌDFæ½R?be;!š!h¹%&ÙµÝyF£)›<ÔE Íè7˜ÏfÔ‹éçmN»lÛ¤¨j…\'µ¨8„YÊ9Ë܉™ÆRÔö4¹WPº ÍQ€(!¬¤$3鬹¤E1Z{nÄUgÁbÐ[d UÚ$ÂViK RJ‘b@„ç¨ô,£ºÊ ‚uTÖ<léÜli†‚©­˜´ë®Õꪊ 2H³`$n }´ÞXŸÐ4š¹.ëg0«Ûk¯è™1¸^¾íÒúiD"rŒlGØ&1pY†Š]ä´ëRBz&cd®f°;&w6´Å¤rÌCL‰>ó©›Ùf³ùÊ—¯úà‡?úoüï¿÷º?ø½×üÎ-oq»!èÀžó«ûikU-"{bfäDlj“D<KŽNèã[fÎ â¿¶¾]TÎѶqwâÈ0zéÊ)ì "¯‰0›QºÃâsNês$FµázMvI³´OÕürÆSéaùcûfpØØ6þ.°Ü òÙúqr"Éùä9ø§åáð.P&wbsç•\G0SG ÌèjDì\§¾­úˆŸçÏò®C‹NñòºP aN@ NÈÚ ]Lsˆ¬È‚ŦìÜ0ƒ¦'óæë˜¤x;¤`a.©ëäÛnº÷hVI÷%¨NgŠ®b²îjL+Œ·Ã;îŸÚ|JïúF¶àn 9imbPëƒîœšÚJ ï%ˆÒ˜ÃTU“[h/~ܳéÄÉyê®zX€Šf¾5[sNŠÆÚ ‘ÙÔAØ~Óè&2¸°š;‘3!FÒ‹ˆ´ÞNUÝÔVÌsçDÉÙ’¥å_î6YóPßï|Vóæ `ê(ñ¸ß±¶KSÛ5rßµäèB‘Y[‚r¦bxW†Ÿþ ùOð,ê¤ÈY:-Ä|½,ýåYj©ÐBƒØ2Ð¥†u¦=šX¯×ÜüfÜüf|àý_ñÊß{ôOüôŸ¿ã-«ÕÐ jÛ, ï$Zy0ÞÏ¥99‹Ï±,w3õ¡³ ¤â–W©e3jÞ„ ²;I}þL·Ÿ!'ñ¹æ¢( ™(.ÑPŒ¬Ÿ¼uÐQ¦p o)ˆyNâs7ÇRŒ² À>•Ö„ÿÆ92}Æ,#(sÄQ•ô¯ß‹@NN9Ü9Ø^žƒq ÓA³&ntnxÊkˆº s.^t)Nò¤dÍÍ|²¼o¸Qm=Ÿ& ÌA(hb"2u8yFަ&á›…˜“”beĈ°¤F•n¢ÜÀŽLª¥1‰Ÿ"–Rc͘š´)öÃáfÃÙ/r°‡ ž˜h;¹;•Òfcá^N Ç6$=8¬uÑnÕóˆjûSæ)3á¾+8iav× ‡¨ 3š“:¨”KuâX&ŒL,dÕëaÊr¸‹hCF|9”³ÍUF£hª›ºŠÄ-¢µjVqàÞn³$¢ÂDµº™È,d0ÝzNi•–,xòöSOÝܱlš éZµˆî…÷‰ͬl¦¾/X ‹TkG%’ÎF3HÇÝœ´Ï7Îîî"ëˆïÖdãî6K»Ü3oe¸«ðz1V×+Y0xæ´±¬Ñ{ôûß÷7þ·7?ê‘#ÓÏ~îÊß|ñËÿþãŸ<ûĉG<üÁ¸ÿ½>û¹/\þÈǽû\„ãh­w¹û¿ñ÷_yó þÃç?ÿÅß|ñ+?ö‰¸Á‰³qùƒð€{eþñÜáNŸüä?ýÚo¼üƒú¨»ßá»o÷³Oºâ6·¹5ÀßváEoÓï¾üU¯ÿ›¿ýàÁÁæ;¾ý–O~âOÞùNß%Þ·]x×?xí‹éy/þÿþùsßu»Û¼àWžñ/ÿòå_~þK?õéþ®ÛçóÿËÏßôüG ô¹/üëK_þºO|òS'NœuùÃîwÿûÞÃÝn{‡ú‹?~Í«ïMÿï»Þ{Í5_¿éù7zÔÃ/{øCïK„ ¿ïät»;>0sÏ÷½…a„Á¡¿ê ýV G ½Ýôgo}ù}ýÛÞùî÷]s͵çŸî#ö×?ä‡>÷…/=ú§ŸóôŠ"A¢ðZqéeW¼æϹÙ7Ÿÿ]w¾ü£ówù?îòðwþWüîëþèÏÿòo®ºúäûßõZ'üã§?û’W¼é#÷Oî~ûÛÞú‰?õ€o¿õ·8üŽ_ñö7<÷uoü‹wýõǾvòÔMλáÃ~äî¹ì¢xGwú¡'½ü…ÑËÞú¹/|å¶ßq³_ü¹‡é+×¼èåoûÌg¿támnþܧ?êü›œô _üÊ+_ûŽO~ê 'Žï?ä²»ÞûÒ;ºû/yÂÛþàÿzÝÿòÝýw×|íÔù79çò]üÐ\äDßwñã‰è{/¾"¶ÇÞùJï{»±¢z†”J‘$ijWQÒ¸¬Ø†%/ÄcÎHBëÌ$!°÷ysm;`àždѰâÃU"bK¯×Îá­ÂJròää“;Òî5q¢™–ìÝ$°0‘œ¾RÊH6¤oJÞ%—€ØƒÔAëDC=ªXÆ µkÕt‚%~†)–£Mäâ˜&H$Ä€šjÐÓº‰Z¼h¸ÌAà2¬ßn·ÒhÆAoÎ2Yr†¸1˜µ¥/Lô1ÚmiãöîŸ{%ºgkcøZjõÜ»[Ýn{êD9´…GÓ´öôÌppÍ]#ËÙW¢ö¡gBˆù =ûRúADL2ô­¸ˆ¶3i4a»ðåjæ1F«M?Š‹<ô!—ýßo|ó£þ+¯üâ?æñÏzæSŸÿ¼gþsW>åçž=Œã}ï}[ÝòïzÏß^òÞ-´w¾ëÝßvë[Þâæ\yå•?þØŸyÖ3žò‚_}öç?ÿÅ'?íÙ«õê>÷¾dvêSŸù‰Ç=åéO{âoýú/ðÿ¼óÝ?õø§½æ•/úÖ[ß‚Ïù//ú±G>ø¹ÏzòÞþþû>ð‘g>ûù¿ùÂçÞá»/$b=ë¹/ü¥gÿìí.¼Íkßð¦Ç=þ™föœg=éöÞæuoxóó~íå/ùç’ù•_ü—Ÿzü3Ÿþ´+ž÷KOû•_zÚ3Ÿ·Z÷ºç]‰ð¤§ýʃ~ä‡~òѽÉy7úêUW¿à7^MŽGüè}?öþ·_ø½—ýýûßù¨8Z§u4 U$•Hýä§ÿÚƒ.»Ç£q¿óÎ;窫O¾è%¯w¢‡?ä>·¸à?üÕß|ôî}O´bþê½ï¿Õ-¿å‚o¾i+ˆòÛÿÅ_yÕƒ/»øŠŸxàþÞÁ?ý™+ŸøÔ=ù ?ú‚ç>žÜÞùWzÒ3~û·_øŸoyó›‚èçñÕ—ÝçNzØ¥7>÷¬«®úú‹_õvrÈewkêWóM?ÿ3úÎoÿ–7½ý=Où…W›ùÏ=ñA·ýŽ þðmïyÑËÞòüç<„/~ùßžøô—=åŠ>ûiøâ¿^õ Ï{í0È%w¿ƒ“ÿüs^yÙ}îüc?zŸ{ë®>ù[¿óVÓúÐ\ô¾¿üÍ;ÞóIïÿË瑘êÙ‹ƒÙZå*†UvÔsΦ»N‡¥ÉW郖^„ãR0êìt&7á"yCþ¼··"£È™^ñ`" #wïÆ5YV ‰†…QJòs¤xÓ]P \[äËÚgîfZC”†ôP¶¨À’Qì ê¾¢ÛF\†ij#E}^y7kƒhXFjÝÆa²M5¬L5pø~“‰ ]îÀDˆq$‰95X6¼·$ ѯÙTqÓœ“‡Ñsňà¹bÔ\/sp3–ÕB™ÒþPI4³;ª‡[JHuJ™)ciÞG±MI’EŠžþ/ˆ8 3 °‚ùzÌJ:…`×5œg.$–m.Z& ®NôO–qÑ j,Ü”¶àÖ·ºà W^é®/~é«®xÜ£/¹ø®ät«[ßâYÏxê ~ý%÷»ï½.¿üÁo~ËŸ\zKˆ@¤ÿý-|ùÃø‹ûÕÿéq¾äâ»t«[ßòYÏ|ê ^ø’ûÞûž]p㎗¼ìÕ?󄟼ÿýîlÆûß÷ž×ºî·_ñÚßzás‰èÿíj±‹î|ÇŸ}òã^ñª×¿êå¿+öúÿúâón|®»?ôÁ÷ÿßzÕ»þç›o|ãs졺ß+÷ ¦—½ê ?õØG\r÷»8Ñ-ou‹güÜúõßxÕ½.½ý·7¼´OG¾éMÏê~ì|ÌÏ>âòFà˜Ä`_’q£/á–¨6¯pÑÇÞÿVþðõ/JHšü¦çßøIOøþég=òa÷}È/}ÛŸþ¯»_ô½qa½õÿ׃pÚ-8¿þËOɱíNô;¯yÛO?æGî}Ï;‡ôöÞ÷¸Óu§^ýº?ý•_x¬½öe?‡VƒŸ“>þ±?|ÅS^òË~0vãKõ§otî "¿ÿ½~àå¯ùô†_¸Ñ9gƒè÷þ×¾ñFäzõëÿüÑ—ßó¢;Ý–ˆ.¸ÙyO¾âG^úª?ºänßMD¯ýí§¦÷éyç{Âcî󸧾ôÁ—Ý)j}sC·Åà Òä 5¯‰XÍ–²9“8æyHÜùÊŸ˜åÌ©fô–ΡóÉa@¢¸f¸¬!¥×ta\bZkÝhݘVO¸Z0öÃ^ÏÕt3sL7–“HZ™»—ÙÌ ÅÅ.ˆy„é=1«³†ñ,){,+–‘˪ ûeÜ—²—£LydEÖ9j¥ G[±ŒYæ‡t•Ò=/íyF–„:m«N‚´>‰9£5å…"ã¸ÇqµZ ÃXÊà­V§Z§i;m¦i3M[Õm †Š_—ˆtÛLµnT715ȬFm:Ù<¦eަÓ[í8O¨´AGº³ÉcëöZ×)ÿÆU§YÁ%F<¦µxì°nRg–ƒµËZ†ý2/ãqöeØY‰¬˜3ùMIa!¥CãÄÜgtïÄФ©Éõ1š: šv|g bÏÆŽàñBòkäóh'{×{Þ{é=ïÖ`¾ýíoûÿôi@î}é=>ò‘}õ«×ÑUW]ów÷ñKïy±;¿û=ï½ôÒ‹vb·¿Ýwþã?}šˆ=i“ Ð{ß÷¡{\|:%|ÉÅýíû?ø)牨–îrç;~ðÃKñÑyçÝ8–àgŸ0·óλQüëÙgŸ¸öÚSQx½ç¯?péÅ…N‰ ·ûÎoÿÇO}~qghø›nz“/}ùß@eɆ”°ŽJ˜ƒèï?ð¶ðíÿà}üòñ¾ãúÓO|èàDÒ&yƒˆoz“s¿ô嫜蒻ÿÀß}ìSWí$ˆ®¾æäßâÓ—ÜýN1ø·#hD(Þ¹Däôâî?x‡Öî@w¿Ëwà#ÿØ%ÍÓì&7ºÁ—ÿík‘?÷œ³bžu|mæçžs"xgß;uÝAD‡÷~à“w»Ë…QæºÛwÜú›?ýÏÿÒš¥æ:Å95·ŸsüË_¹ÆÕfàØ›Ú51‹fG ”Ý«{ ÂSwuR·Ú~±–˜PŸJ—ÎÝõ à”$7#™¥}dJ N'¤…¤u˜†´J!„.h_$ƒrs¦0…ëC#Ôãy)øi. {ž“¦:Ê&q=Ñb*ÄX5A}s²!#³Þ)Pvfq¯h†üqƒ¦uHÌ ¶)J•RV”z|9sÔÚuš*@C)ÌcØ*·ñÔÙ4Kcù0½p]±ÄÙf@=çÅŸÖù´äg4âK„ĘbØçš0¤Ü>üÍì#1bה̂™Wm¨êŽ]ºçÜ{óæX•5PUPÅÜ‚‚4‚2=ZqÀÖnÑVTÚ§>‡µEm”QQ[ĹU[d¡qŠ*¨9+3oÞé {¯ñþˆˆµ×9÷Vi¿ÏçÕ!ÍÊ{óÜ}ö‰+â÷ûþþúé_ùø&ÃsÛ[oó „ì‹\ØÙÙ?~tÙg"›G×vv¦¾U ¥©ˆtæ l-›s |)gç’[…¶÷¾âk~ô€I!ÿ‹¸,-ºÂíÂÀʃב(²ÆŽè1OT}bò/$C;€Ý„ÒUmŽƒ£W "Qc£CW®"…Öv`©¯„„ËÛM³aXû&˜‰ˆÀ"lô^ä5\?óv…ج;E„›ä.×pH‘¼¦‡8VÜ_!Ǽ®Â¢é™¦H¯ýÅ|ǻޫ¼DÕ$¿ãÝï}ô¿yá0/&RýÉ[ßþä'=Ð?ƒhËŒ1XWPPùˆë>ð¡T²$uù–®L\8L¨‘š&¦”ÌïˆP‚$U-k³5“ú+64-G˜XYdÓ3Üûª{mYÿƒÿùŽãÇ7¯¼ìbÁì Å ªÏnAàG>ìï~ßǰüH"ï»þãxÈý\ ë]g`«˜¹ÌôdÉ`i+X«ÓœAòCtïôŸmÆ ñ±-8š.Áõ÷hšØu½üÊNû- À¢J^'é‰{Íÿ]P#ƒAÞëi™Ôk¨R¸(¥ Š&46j,1sÜKjU>RÔ¡jIlÖœ5,Mb–”ŠTÒ8\>ɪc?f²Õ~h…sî8-tn¨H¿F<éT1§9ç.çyê÷´‰VJiîgzð·Q©ˆ·U¾›\ÞÈè‘ŀœ)͵؇”¢&3ûƒÑg1Â’Õ–:²YÞêdЉ7dõB] š%©W 뇟íá0L¤e£»’3±b(«§¢j²še(ˆ[Ý šñ[§ò05!´D1ÆIˆ#­†ZCÔiucßg b¡/‚ÉAÜ:â²a×ù2z†XÌg·ÞzÛÛþ×ÛÿýüÎßø¿óú×½b4#žðù?õ3/}×{Þß'è:þë÷è›þãwF­tÏýú¯}ñOýü7>÷9ˆ:C¤ÿò=ÿùÅ?õ’w¾û½‹E7_,Þû¾>÷›ÿ“Jß´ê†ïù®oå«õOÞò»ûÓý½Å[þìí¯|Í_ðŸ¿Uç úgy癳™åì¹óoxão¿íÏßù]/ø¶2s@ ‹÷.„ªbÖÒÿ»Ÿÿ¼Ÿù¹W½ë¯®ŸÏ»ùlñÞë?üþÓ÷aB"Ò«°ï_ôÀû¾õÏßsr>™”§Rý<:8¼¥FÁ›ß\¤*cüœg?ùç^þÆç<ûÉJÁê¬M‰t‡,j+Âïø–g½þ×ÿømù½½Ùt:ýów|èW~óϾõ›¾ÊSjñ+ßßšD/²~â·æTÏËbgvÎÌéyßðÄWüò[Þ÷ÁœÏ³ÙôƒûÏßýC¿2¼ðl ;#rí5—ýÅ»?–R*"©þO'µE_̹çÔ3'æ§…bÏ„YD¢¯tRQãüä‹T›ú3Ǥ“\e&}¿ßwYs–AD£Ä‚U%Ýw{—¢Y»m™Æ*7S$‹ô>Ð-'\U¹wŒ:–EI’³­ìêWE8Å&»‰ÙÏ”@ ã!STk T^p^ N3·èmE# ;AÀ@˜™3s !Ù(?˜ËV)4Ï·§…=$9e¦¾[¤¨iG„Q›ÐÊ&V…T— $–¯‹t,YÑ¢ŽZ«Xnm¡fPÆ:ÁbPŒ@l(Ò\Wöæâ¨¦œ+|&©“‡«¸›JBOþLŒµIÔC/šÚëi°e£Çr™Æ• mˆÔB8²±qõÕW=í+ŸòÏ}ÎÚÚ†¶l{èÃ^ûê_|Ù+^õ}?ð£óÙì~×Þ÷YÏøª’ó´¯zÊk^÷«OùŠ'§ ñ!×=øµ¯~ùË^ñêïûþÿ:›Í®½ö¾ÏzæÓ–A“Ðîíõ•?ÿÒW½è'þ»ˆ<âáùµ×ÿÒx­¾¶ýÍGþ%¯:wþü‰“ÇŸòä'¾ù·~ùØÑ£h6žf@M¬ âóI)p¼îA|å+^ü‹¯zÃþן™Íæ÷»ï}žþUOrá'º¯J<ìKïCþ±zþüøË^ôâ_Ü<²~ý;ßdÀ¿h.)]:üÓßþiÑ´û²ÒÍ„JÚxòó«¿þ?Ÿøeòñ{㘡h®JWwÍÕWüÒÏÿ«^ÿ{?óÒß‘ëtÍ+þûwßïêK+'1øü°’NIA?«ö—ˆÒú1ã (÷¿ï¥?õÃßð†7½óÅ/ýýù¢¿úª‹Ÿüo²ô@)3ƒj û/xÖO½ì~î—þðÈÆäí¿ÿ“‚L„,źå£;æ¡ÍP·€ˆ ¸Ã³ŸR¿(V¢D—\"Xò#Kä@7;ßMÏ.¦çºéÙÅôìÞùÏÞÿË~¨ïçMÓš]…Šœ¬BU°N])lXŒ¡IÅÒ¶Xµcš0©u£šš[cNó(©Éù"ÉI®%n* ßyJF£SÕÄ"©Û…2Þ2ð„<­„Èò/ÉB¨8YÉ3c’&¡tøÙ€0vÝ4ÆÆ 1…_1ª«JöóÔ zF3ù­…<ÛÑŒBûǯûú+.Ýl'ÇÛɉvr¢­ZÊÀYݜĺTi„úÊYL%”bI5…Y÷"<5¯ÆâÅq)g®§ÐSÅ ¯î@‡LÓ¥˜Y–áŸ>£3 ¢T3JJÇðê˼@êl~`2^,´‹Š´‡rõµüÜg>fUðˆ´á þdsH'K•& Jæ¶8OixˆˆáÊÁQʉ'ÁÐf–(”´ê£†p°Ã€ArË‹-¹Pfþ!õK§Ú‰¨*ƒê®v:"ÒUŒÈ X²þt¢;ÿ+Ý`=ÙJÎl!¿Xßèñ6­S꣰rò O Wšw¿IÇ"#žÆÆv:0ߢ†# 'ÕÒ#…JþRõ+Mß è€í1Ä1…!AkWŒíÊqµ˜ÕìžöЖ,e‚«ÞÁB“*QéÞÎ'„`³yaæžB ÊpZ:¥"Q j¤LpÌòKö¯x¥Ö=TRyœøKuY;.÷@D¤1}¥sLäÏ3Å1²"œíÓ¢8¿ˆ€£1­\1ÕÀR½POt,¬ÿ8'¯›8€ 8/çïê3ÒŸ+i±ÂšbjÅÿ8ðiɒǹ¤¤|ëWð"Þí¨"— n©#”K A]1‹õ ~1P%ñ–oe!.N]¨¶Òú‰#Gá•UUa«9|õŒCëç»,!Î\qFÔïFªµâ+@@‚•Ó,nF5÷¾jòÝšAHpˆ8sþ¼µØ9ö…ŒUÒêƒ|X-™"À,U†JÇù\´‚ *ˆZ? ʰn­A „®¯6è—÷À#Bö=ÌãözTØâr ÿÕ}c ÛYšóØ“¾Bý•bhü@[ÈG]Ïë«øÎq¨ï¨j÷•`ÔÍûÑXÅÌ–“Q#¸GC.æ†Tf©¦Bï„ûaá|¢VR’%ƒæàïæ Dj@ÖP#NâÁŸžTå3nñ ! †¨‘205à¢:=ª¨rгé"AùÛšŸÅ%’ÍáÚ=eöb-Åðkäòìu ¥0%(‹û¨õ0%¥'µm»¤`ð­ûk–QÛêH3:K?(ö­›€RA ÂÛºïî…Sîg˱:øˆ 3ÅÉê¾gˆúÊhf\ÿH*$ðg¨9˜×îCË94ࡤà.…§ ÑÕôÊ"ý«ºuX~º{¶G%» gøŽ2HÏñšŸžJªŸ)pX`€g„ C_š— þ?þóŸ4 ¡Ž€µO­~…)¨Ðüé¶§¶Œ«@ ¥ÜØ'2ƒu£C$½wëýТYoÎêBF0ŠÃ󇻢„<ªJZ¥x"ì² *ƒ)®´“âû&•å˜&¬Ô ê>”s€WÏA¥¥WžíwJ1ñ®ÿà+²BW,N|¬Ðè8!S[ÚXÉU¥í­sÈJØ(‹‡ˆÀò²ÈÈû~/ڼú"Y›qPñÂJK³CŠÞY”e•¬•šs—ó‘BiF¦ºN5/ž1ìntJID$jEzËq6½bVP­¯zq5‰$—|ÄR4ÌÎ?Q¬;_ŸÙ‹o_HÔÚÏ—{‘”sWç—é;Fí¤øñ "ƒèéU €(D½_­…ÔS„ëmí´.¬WL;hƒHqîsš `ˆcTk™ÆopRC¨Ù*(Z]¦Ã —‡ýÚ䨚¬kbC(aÅZw{›¬èçaÔb™h°‡«t%wkÓã7OÙ«ZaUÍf€Â‡í‡Ã ˆ f.¨ôO­ÑX˜4•†´’ðwF5bÓke9 ª*ˆ}ïÏ}úce`†ö„°KvóùVdfĪ9o¶ø3y¦»g†*oW/Š©Ób1õ*kÓ¸Õ@`ã#t†I… öŸÇeÑ~‡¢†¹'šÈR Ý?éD<³Y—‡‰å±h³½Zûp¸nRÞ¨2CQÄMå_.-HµRÞÆÚ˜ìEÚ8ª¥òb±’©3ÑÇ& U®¨ìJ†jDXü£qñP…*Wiˆ‚Ë(ò·F…ÆH‚HDpÏ ˆÄÜû&*Ü·À†ïFaDÁGcÇõDÓCÙPâÃGôÛZ5ð,­÷¥¢ãÛ*¨D²’u<öWÈb¢ú8ƒÄ1—ÚR5èmÙà¹2u*Ü?oµ,ºG¢Çè»b€ê:gî• hrïûÚh‡âêŠQ¡Õál(‡°¨ÑÜ$“jU3P}¢˜î–‘KÃL“~Ö‡gǰ[¶¢n=2$Ö”&›´»§e)‡C†žaWîçe¶Ô÷ªÍ¦‡t†Âj×­…%\ _¼v°ŽüEÎíÁ!ÆÇ2—óÒp¶â¶œHû¬f)¼`é15• AH„`J^Êl‚© @eì fe;¶$Yt)ã\cEÀq‹`Mìh«ø&­„Ái“R®jÕÎëGˆ)åó-wSŽ*h…²©Äáúì«ZM} è…¹>̳qí°A€ƒh9`¸¡GR%¥X»½$ðPÅ«³«&¡Ÿ"î&¢ "çŽÓœâÈwuÉXbôêrÃò' ”¡ñ\vâÂIr2š%®õƒdÞÞÊÜY¡ alÐcÕ;Á‰-ü:ê0C)ë®- µÆ"Å‘¬Ѹj"O@+)žè&tß“ uFÌ=ç…Në4äm)T±!@N\¤Ýv†²Ý¤|ØUz–Æ.h`Ö¤‚gñ¸s0¿ÿ …öá&ã¶X.tÙ ªS‹³uµœ{T}åàW±;LržC½O·@(ÛùÂÄZå%ªá00h1Èãàh¡'Zä‹nëéç,]‹~<ÝqÀ£àa`½B )Ï!³Œ¥äSÙÐÄ,¥ð¡åÊ%5=Oá™USïø—”ƒ>Ùç²j­ABv1]6‰ÕÉ*nøêóÃ}Màw%ÉÛz–È8ÊVw|µ TOÃußž ó ¨ûXðTdmÙX&‹}¢³û ND`i¯Z£¹ü¼†ôtºÓ]Ç^–6\üZE"5÷Q/³ù`ÒD :r4ZÜã£ïíÝþáá¯A¨ü=PŒTê’'˜s= ÔaB°¥ê!"I©2Zu=š­4éqRrÉg.3&;€[/\D¾ÐGQšÁÑv T¶öHÆz* zH#«VWÌÔÁ¼ò‡ëÌ–‚–÷E¥Z¨¬f(SÛ{(£ƒÈü ¼†p7#‚HRú½††—¡ƒp*NÏã¤j܆‚‚í¸7Œ,º/„‘ë+ÙîNU;i×F””\ûR¨Ìì°^P(\¹Û8÷Ì¡æ¨ÒxH„‚{#z4<"i*œs^„0’¼0M’Ø| 9ÊW¼Ðøh@6‘@ÓØ ShBƒe1aá-)Œ–¥×t@I÷ÕYëˆý(ŒKM”2jð$ 8ä̰¨¥s+¢µg$ç$*&–  à^É‹])ÄCÚ’áJ›e™ZxÕuGîŽÙ¬oÙ2CzåeèêÀ„e ‚ëñNJ«õb˜²ÉÒê }ËCÕI¼Z³{Ÿ‚¶Z°·¯¬¨qÉâ9gYy.•EûnšV'E£âóú%éãbé ªâuú—Q½RQ -…Ö4ûFy ¯aY¿Kaûiƾ.­[ê]êy†½v*— ¶v²OKŸ5­ö”2ÙbQ Ia·{ÞçrZ•TÙ+ƒsåàæàÅKkº0Ì•܆ÿrJhä´Èi^Å=/E†ÚT¸¤vQcðZÅbÉŽš`Uh{²éMÑ‹ …Ìœúéuǽ•`Îue´T’Ôµìó 9T:pt ›aÈœ;&eî™{¬~PÛS™ç-—ûšB£ Ý ²dC£c1ÂÀ¸5ªÊuVf ß?¤n«>͵CèSÏ,M ""!6ÂÙ䫯¤)ÒQéË’„Ì…%.A,§Å’Äg_ÈI„ƒ)qx‹ŒG·í:$É}8­@‘m¡ âürú®Æ Ë$üåKÈÕ£zIî5š — kmóÄCWü+¯¤¦™ ±ÍIéyH­‡ÒkJÕBãó››ÅÒ‰‡]”ýÈ\}^‚ºYlaä‹áã X!*¥¬üb(·ÕÄP«ÙÉwPs`IBËPyäòQT·0U'Ø"Ù.B_ «‹ÉÃ|þÂöÿØ+>ò±Š1~ø=oÞ‚eßzÙÙ×"¨ºu²œ¥å%‘Žõ¼žêʨ¼a!¢Ç>ãÇßÿÖŸî:YõéU”÷˜, %ÈÆ2T4‘ËQÛܺr*æX-çmYÖë,CAGú¤]jWQÙqx 7q»dæÞˆ&è/M…ÎFpçäf*”ýäëTýêV*žÑjq„f…,¥ÜYás…+¼†Ö0”ý8Qˆ Ây¡>ËbJ3ù½"H€É„ò M´fD%t¨•PhNR·§ù©ï•˜­Y#J™‘&¢gNóé×ÖFz(«®˜[¼¸·¸s >DÄ Ñ·F‰yH‘0ˆ <ôX K¾U×l"ª¢¾¸PT4 ÌԎˤò`8ÇRß§¢¥;!àáǪ,уíƒëñHò!…a¹€¥‰óÁÀ›J1+~n¬ZÃáMúS;[ˆh¹¡¡°™tÉj(–X¦1(1ä™Ýþ±ïÁ—:_k,}Y°ŒT+gÏõdfõHÑTs ¯ƒÌ,É•$ÆçÞ;kEeåÒ!•ó[?èV:æôòWþæƒxÍ«^úÃMSð¥õ”Cµù9Õ¼ÅUðožð¶1 tìèÆCtõ·|ãW\{Íe€$\5€˜+=î/zß[~/‹ˆÃÒ„‰°rÎ^Iê$$ëÐ+ãœíWª'år»ìQBBÀ¸J'³bˆ sA –ÏYRR†RæLwbEgHUÌ̈¨É]Ê=KŽ¡¡0"Š€pŠºÀ­ô’¶cñ½!–(4]gôDQô±`éçÁãaKqg¤ÚL-Ü:êµnx$Â:ÊÑŽ{H @2™”ÒIìUIÖ .e‹ˆDÂÛ#h‰C¤‡)æ”sb‘bˆ id4…Æz .וëÙòBÐ+ÖgÎ9÷!„ÇH‘°ñ—îõÊÃܯ˜‹Ü‡>Ñ!ÇôTUG 3ôqù'дPé}H+º•^F.å `aUq—9QhVG¦¶y‚Xªë! ÿ2øsÁƒ§{æô¥”4d¢,)f¼M5%§& áP¿Êeóáf5$µ¶dË <¤¡ÊÔãÛʉT3± áÉGÄCJ0VÊGTƒ•W÷×À0ž ƒžÔ<¸å„kADÕÞ©)W5>©\ÿ¡ÿÁo½´m›Ò©!"K‘ 2¾ä­~["|äÝ¿ ˆ]×ßqç¹÷^ÿñïù¡×üÂOþ§‡~ѽťPÆ/÷ŸÑ¤²ê‚ò~f¡…¥Ÿ®üañ±Gi-¥R Ë FVÚO‚ e…›WœÚ>Ê€¤A†%Œ³ºc³Åÿ£ÑP¸Š!a¢‘{Š’‚éBl"FÑÌ%ë,(hZQš %¤&§YÎÙÓa4Ü- R¶A$úzÒðˆšA¯ƒ@BB} ÷>ò¾d·]ß0lÕºƒî7U´¢õ5dî~ÔÍú4Ëæ *€.CÏB5Ôªš“âS#RâH`¤®¢&çN×…‹~–Ú&6#‘œS› @R>M'"!ÄØXËi2ü–·*«ƒ?X2•Us6W­ÌÝ–¿@*ÊÒç…_þò[TÍñ¼Ö>[8ªƒÕº ÅdÉG¬Ü\Ëè«~ÈCë)ž6R$jÔ_t¤9w""9§™ö8œ•,IB•­ôÒH¤ï¶õžqdÇ.DÄŒ=\ž…å§@¼œ2´MÔA„=® [–N)Õmjú p”æ9»F/4í: Jîc@¢180„œç¶ŽåœR¨cA(b/¢H!lë+†ÔFÃÐM}_>ôðôˆš› ƒ U4÷E%žÕ\&ß•F Š®dɉX^|uÞQ©–‡5 Sc¨®žß—ô ´aÈIÆUP^Í@©6Z¹”Î"5³Ùë•‘|Õ‡Õ°Ë6Pú’ 'x‰mº<2®RËØÐÚS +–ªÃt8è®hð ê½kËb—ï³iN G2ùZ¦´¨â-k[}XYñDä CÐ&ï€øÇ|<ôK¾þþC¿‡ˆÿüééµoþØß}RDþû¿ðùßðÀû߀ú¥Ï}î×~ë­ñŽž;¿ýÑ÷ý†=°2¹ðæ‡~é7þÝÞ¬¯ó³ŸûÂó¿÷¿ÿÀ ¿ù~ú¿Â{þúo¿ç^òº_ü‘kîs/ø‰Ÿ}ÃsžýåÏÿ¶¯^›Œl|lO…¢–e{‰$À2ŸwãQsÅe§®¾ê’ë?ôÉ'<öÁzý?ø‘OÝ窋¯¸üÔõoûÙÇ>ýG®ÛO«$÷qOÑ‹~ö÷žù”G~ó×>þäñõs[{¯ýõ¿dç<ãÑŸûÂßÿßÞôÝßöÔÿÐ×!ÊõþÔ¾øw^ñâÿpõUÀþìï=ã+ñï¿æ±§N9¿µûš_§|í³S3—E¦rÏÚ)+£’ûœ;R­¢Ð>ö š§R¼.´z¿JQ‰V¿ËeÅgî7fï2_C3Åø'Ü%Ïäª;°Ü)õÕÄ€óÜVRÔ¢®õE/༒A$,Ì}J)eiÄf¤Ù^ÂÝ@qöžÔ¡Ð¶k—T¦Ršœ{}f„8R[QãkPHä7½þ>™s̲[ôÜ€ Û7V¹1K€Yõa¢W,”¶H 2$‘Ø% ÎJÄXÙ¶WfðTu‹¼ê¬/Z›½Î aluýR= ¥pØç‡üˆKªÕÕ³íЊ®¸|VÌ w£ºž¾UáÎÃÒÆ»ÁýÜíë¯ÄúËGBPæ)ð@c±°[\6sÉš.Õˆ>*j¬AY¯¹Q…— ¦ìù¯24×Us4øeËép[½¬xÀ¸zI"ˆÈ_~þàۿò¥úžþÔ/ÛߟþʯÿñK~ê…øòŸý>"%UéÌÚò߇Gšà‚3 ¼å/>ðoû`yöÓó–¿øÐ¾ôAú÷¾õ/?òì§=––æö~õåßAdX—Ó}Áóžò]?üƯ}Æ£ãwßóm߸ħ<á!ª9}òã¯ÛŸÎãwßó“?øøÕ—};Y„œ¾èèw}ëS_ðC¿öµÏzÌ=ʫފ™ a`tè2zÊ<œÑn6­z–´»ªÆÏi¾·7Í÷9-ÌãÄ=s 1RÓ4±iôGòƒ?3»pÁ>±›—tGTƒÅS_ô‘J`!cbqÔ4#m{ËÈÓñjщpÏižÓ\õ˜ˆ$Üw‹Ýùlw>ßåÜ£â¦Ìedê΋ÔOÍÀªs0°qˆkFFþ¢€þtBÏ%ÉœçûûûÓé~îçZy3÷Ì ‡@MÓ4MKjý¥à£w¶%Ø !3K¾ç'»TF‡8ŽÍ:…Qˆ[[…6Ä1[>Ú)ž"/ÁܱV!ŸóÊžWê²"²9 é€å¦²Ö0 ¸<{ÆÖ¡Íþ¾RÁ—ØüÇEf¸Ô~Š°Ç™{hÎ ýçÎ˸ӛւÏ#ƒ &–dt˜y‡î†5¡H.ih¥Ä›£ì0!W) œÓÂU™âúpX½'ShÔXQV–bm~“¥†txã˜J»”hyÈ®©Âh™ >ò±|—=½]'>þßüíÇ>¡×!‘î€D…RkÛ*½³î¦Ïßù+¿ù¶¿x×G_ð¼§ È—}é}æs·Ýq×–€œ;¿óén{Üc0ôôÃ3 ˆ¨r$Âŧ6ÏœÝáýýûâûû¢^àq~Àÿþ‡›|’»´½èä‘3g·¥,<è=îáŸRcÁß ç2+“¥5(…“*7Þ²×lõâ:Á&F‰ÑŽŸÂ¬<%¡šWÖÓñ´j€†¨‘Ùñ–¥€îMß M.ŒÞÇDÝiú¼•ʘoÍ`$„`"߬¦]‘BÏø¦§ódiA &“žÈ¶ÒœÅ Åœ‰Ì8€*NdCkÍÀÓk¡Øô”£èw¦ÐèÆ¬„´”‚_7ÐÙq ÆSTt§’}k‚‚\BSj2½*Ñ+h¹ÙKùÓë)ýžZ•­ÿêݦó{ÿëJD+c„ƒª¦ý5¹Õäžîõʨ6Xí‘ãl²mef3Ùk"¹,Ëe` âe¬QdâK« –Ú¾Cúè"Ù1Žz}¥Ø©Ea ˆBβÏÊ=ÉÆ•Îc$ |UNýqöOÖàP𙦅 âöÎÞ‰ãÇêÎñcÇwv÷+’w(ÀªÀÔ ¾øIß%ãQsåå=ù Ã/}ïh4²ìiO~ä[ßþ‘oý÷Oú_ïþß_ùåoôQè8tåRù–J¹³7;º¹V_°ÍñÎÞìÐ~“<<êžE¦+à›•Bt‘< dPX‰p\†¤•yŠHú¯ôØ»ôüÎ= 3²"ÚñˆÂàʱs·52à>µñ$teœ+ÌíØKâÛ$aI•Ζ‘[Œ@H8¬Á×ÄŽJÂ2„BìP’Á@‡¦Ô•øt†• „E˜³t]ÏÒÒ(e¦¤Hž›" ö,9éÆf€Ê¸F 4ÀLa45PÚ1ÑáoMqžU±¸ŽŒÚƒzÅ¢@ÐØ ­žH †HÔˆѪËó|JÊR¸[.É=”Ôá|šk’žá$$Û×r> & x7cÓ{p=--…+½ªÖÊb!/CÎ囼WQt‘ýKN‚ye>ëpÒƒîÕ/c°Õ/ëìWlõuï¼´œHCk2Œ`aÈû9àè•T¾$©NÑ2fãÜ—C‰MD$÷ŸSÞÙüï~◑ÿê}yÔÿ¨z¸*Í€ÝÜæN&’"“²Í­aƒõóA—]zâÊ{]ôÆ7¿û’‹_zÑ1GJCÎ)Z9EùSÙ.åÃ|Õ{?øÉ÷´G•ÇðûÿæS{ð½ë¯ZÚhB—r‡-ßV*iŒízubÂLJÞô"°…¼6¼R|àðU¥=ôDLqz¦£? ›@‘HÅ™'¢á£ ˆºtܧɜA„ˆ–ÖÕ1Ð3žwèd6г€ÁëÊ•2_ÓR~oõñϯbÎ!Pˆ-snš Ç¶Xº8‹sgÜA3ï‹}¢i¶!”¾eH]—ÞÅ fö·­—ê•[dóbà 6„$’1´>5f‘œÓ"ô³Z«;E™½™"õ©Cb„#̈}¡Ô\á ïà¹ÞgÊ8ü©üÙòvÆŠ$߭zÄKplH]](ÿ3€¡©$MŠþ©|ZXÔ‡6^ÚY Èáïòì¬q¹n!¨k0+ ,ÔŽeVŠlU+É›PçÿV„ïòª|ê…">»psNs³ rfIžé²”S‡hYJƒ5G|ÇóþÝw|ÏÏL&Í—?þ1€ðž÷}äuoøƒ×¿òE+–!¢€zCªÅ2Z³.Èê¶ð; žýô/ù‘ÿæÏý·ÿª|àkï{éÛßóO}ÂC‚R/¤ùßòõÿÞ{ÓúZû¸G?@Þÿ7Ÿzãï¼÷å?ùMu"µï M_TîƒöÕlÔP@HTÛT£s­œ -¬Ä\õÿ`°å‰1`)€R™‹¾R‡>µfXbrN Œ–ð‹¢U´g" 5D©ÐƒÛçk9Èuàѵ¬±T©°  Gd7PôÌ ,Š?›<°ÆÀ§œ“õ_ʹ±TΙL'“1ÄQÑBÙ÷ 24JeoJ)ظ 3„PºÌ„ų¸|Å8gõ9]4º!!…”2¥èÅ,º<ŸïBO9# 3ëµûüÍŸÞÞ¿“¯¥>Y?zâøÅÇ6OnnkPˆ(6ñp®ÒÝoáàQ½,гø˜4—y^]¸w@(^÷€¸<Ä?à5(%yy¢Êh[Ó a%ìñÐÙÊ1ˆ%õñ¼ú5bÈ´”ßgÏË•6§ÊÆ0ëoË®ß>õxTõnâ^—vçqÛ  Щn¾ª*ï/»Œ†² Ñý®¹òÕ/ûÁ_zÝïþôK~Mvݵ¯yùßïšËu-ÁÖò£1ôDe‹©rU±[Ȥ¦5#@¾ß}.¹èäæcuï2…¾ïùÏüé—ÿÑϽòOŽlŒë«MHÌœÙh1W_uñK~üù¼ó^ûg"òàÜë~ü¹×Üûb8…›˜C ‡úDÿÅÒ¹ô›wÝô¾ÔíÛ¬•šýJq1é¸Ú£†+"ÅÅþ]–j7;×ÍÎïÿìCžòóE¬eÔïƒ|ð éo[ãImED„³ +dŸS/ AµŽêò$%›ä¢ H«‰‰H]eâv­ÚŒLZš\§Þ•Põeå¼Ð!š(9û:P¢c1üpÔÆD[ÝAì)ô={ž%"Åbë@“ì‹o0€†Œ)ì1pîD‰ú¾ ‘Ðwóétog{k6Ûûì'ÿªi'Hqy|t£ïÒÖÞt:›†öç}!Nµ©šQ;wÝþ|ò¨G77ÖNœ:yɱͧ/¾lcc3€a¡)¹4x©:¡Ò´Y:Œ»Ñ¾š suÆ<`!]j9ñ Å3ÃuP“ª&Ž—dÿ•èµÎȣ嬽åA0&×*-—’#ÊȈW”¡Ž»]=6ô'ÿ˜ ¤Ê0t¥vÛ ŒsYÜUc®¾5|GÏËè\™ï–£@5Á$£æ@µ|:°)ÖÅ‹¶”ÞäöUÂà®ÈY³ʢ̣ámƒ§¿zõþl‹†lW &ÛáË©¦¶ÔbDhl-K×qF…@1sNú®u]ˆ‹EÞ›íÝqî̹­³ón:í¦‹EÞÙß[ô³ÌЧnÑwœÒúd<¡„2?ßO¹O}—p²6‘@HF# ҈ĴÀÅ6œíöá’qs´…µóç·6ÂÚñÝf2kÖâ“ çòlqîÜv¡k÷oºñÎ[î·±yù}îóˆ&å¦iš&¾£W Aî)Ž+pL%²¿­¿™…ÆáÁ\akbe‘w£ŽvjýÝoZ×µh-#=Ó”œ(YmN‡bЇÚ(«ÆpP¶œƒ]4>PF[{:Ϭ°b«Nß×ñÙYy™3ÂÆÍÑÔEÅ[IE4 '+Èr²¦ÊNq°W9PÅkš—ZëæpÈ•SEŸmæÙ‡Å à[Ëmf©¥€oûË¿}ȃî}Ñ©cæÏ‘K¥ÿ‹–l’  ”x‰£ð¯Â’*Úô¿ ½‡;§®–Qr¯7·Ù—F–~–÷w޹'½3j˜Š¶Šb2ĉéB¼jsJ}Ê, í(ÆHf)ÂHMœsï9³âØHÔÈ`^vš½dÉY¹èžKÉÀž÷M¡<‚$©MU½E¬¡LÌ™9 眓ª‚‚Ðà.µ#‚¤ÌÀÌ„c`Cv6‹Å”[Œ ñÓ}"Zý±iBjÙ‘~6Dx±˜÷]êz^,fÓÙî]¶ÎíœÛÛÛ½õÌ)çÅbÁ ]Î)sN…ØBJ‚„'ŽHÛçwÏݹ#‘Ž;²¶ÞÑd}cwg†õ³L$GŽ5£–#ÏçÛëttctó­ýöVüôÅ'7±'Üõãºæ3ÙÚžßqþï9â¦ÏÝðˆG>ñä©KDúvDjµO{¥,V JIQ^ªYXˆ %þÄ‚YCÕmq5*ÕSV8üÕÊž€° ­2דLù„¤>­L V‰“X¯¤|äš±¶TCa)Nb¹%·3¸UNs¯¹â#>ÄwdÿO€^š£S‡†•PuPÙÉKÅÓɾâOȆfžŽiü#¦Äå諵cU‰TØNâŸ9¥v2 ðÀšÂ ¯,UP¼]jRêÊsžõ¸ç<ë±%ÏÂ¥åètÍòm Òä –>T€ˆXj¡2IÑGírGøÍ0te–)´¬ï[Ùu®rÏÐP¡+ËV -V„žÇ9ÍuÿÜû~¡¦‰ÌCÎ1ƒ0 $Dî5ã)õìKÚQÃ’™©A,æwR!¤ @˜;ßZèW"焃Hfá:Q‡Óœ¹Cl(´’™¹ND-…€hÌ'3ç,9 ‹ÄhyDÙÐ÷]×3óhÔŒGãœû®›÷IF£Ö£8¯yø ½JZ ¢¥œ…ì? !†Ð0KŸºù|1MÏm¿õ–›wöwd:›Ûíõ¹ëºE׳dÀ€a!€ Ãdsm<Öר¡­óçîºëL·X»äA÷aH››ë³½Åtoš°Á4MjÆ2K3‚µõ‚8â“öÇ'n¸09~û‘[aëöÍþ“ ×Ü|ãM)wÇO7ëáÂ…Ù¹Ùö»[·îœ½u>Ë{ÛÛi>äcžzñé˰OMá€eû`•)%¬Ðl‡c{©¼¥Å°¢Œ5 _$yXìOG ûeèæ¸hP‚¦º?ÌQ´Š–h(C¬§+EsÙé9 \ÜS'SïëýÀëz’A+šÔ¦UÎõçR)ѹ7=/'ä°TjµrY.¯+w‰€’ªTRÏäB"Hú‘âÞ!oUpÈ\©U[¨ùŸbE¬É"ÀJˆŠ"Гdç€~„ªÅ5¢ê½[ÜtÃ1lÞ÷þW$žNÖÖvvÏÆ¶½ô^ëwÝyçÆ(îíí5aw<ñ¤oGÐs—Ö›Bl÷wÒ|oz¯Ë¯ºæÒKæ»Û{ÛŸOæ£QÜúüÍ7œß:ߎòå—ŽzÿûÞ|ÓÎM7ŸûÈG?¸·ßÅSŸ}ìÄ)nšÑ’¬xUꬡÜE3„ƒœ^<¦Q$«›aØt«o½šm–®žý‡iæaËúU$‡JÊônQÕö¿ ¸w¾-®Dª^®ç¤«©º>² ä¢[ôì2ƒ׳NÝj§~ø]=cÔÜ£ÛõØ®IâÜKN2vÌsãQœŒ-ˆ‰9Ù¢9´ª½Ï,EK~|S' 3΋»î¼ãæ›n¸áÆRæE$ÜìÏGŽ9}ù¥Û;{óÝÙÚæ‰µpd-F͸m›¦Çã¶ŒN_rÑ¥W\:nÆbNÙÙÛ¾hít8ö µÛÎ|ú^WÞ«ë¶þùÿÐBšœ¾¼_Üut-Ù<ŸdOxk<áv=u{‹1\ ßtÃ4Êñ‡=øÁÇž¾áŸÏŸÝþ;îÒ¹´=^džÛ4Ÿö7mÁ™Ñd¶Ÿ!g‚þ£}ß©cG¿ä ÏÔSŒQI`~l?@3ºx3R(íË ŒÎ&KÅdµºo•Úe ÝhÝVŸPIßí\vÐÁ24§Hþ_ Çp°’ŠòÒògYRŠÈËòïì{ùå ’ÈÒùݳè<‚fPû«PއŸQ·jnÀ:w*¿ÅŠôgƒ Ïÿ“Z ;xAMh¹*ÜÀ'1m†ø7E¡ %³@¦$‹@ƒZV¯’%QúD(ª‘F%IiÞÐS_W²=`x©@E« u°VÞý.Ç÷K‘¢¤QX•OƒâÙÝÙõœ%K ˜\ëÖC %E!bÎý‘5õƒçÜMgÝÎîbÔÒÚdÔ´“£1 gÀ &qq1Dîg:õ ¡ adiyÎ9§œ!%Ñh ]Ç9‹ÒNì~è}Ï™¥i0†Ð4ãUÄyÁÌú'Û&ŠHßçÌ} ŒMÔ0n ‹±FÀ¹S&À¢ÏÌÒD‰‘@iœ˜³Þê!NfeSå4Ï9SííÏo¿ý¶­ógo¿ãÖ>áöÎîwž¹°»“r:vâØ‰‹ŽOެ^ß` íúx4šœ¼ø²K.¿Wf˜„#WœºÏxÆ1(#¨OóYžÏÒ Ïú9ôȹGÊmì4M·Þ®éÜÆé#—ŸzÄ‘8€[Ï~fo«ïnÚÙ¿s6缿s~÷ÜþîçR®¾÷}/¾èôÖùý]ÿ¡ÔËñãq4ÂqC C7“'ØŸÝYܶ5E “8:vt¼³½ý‘_íƒuêôåšÄKD²róÜÜfÜ:­6üu¥¥ÆÌgœ†Xf¤í‰áàí®›eaå’0Hê¡©ûÿ´ZÈ(”y1p^<‰¨þïºvÎtȾo苈U¡æ×Þ‡fá’îî)@ÐçÚ‚y ‡jÈvå|©ò€+ƒ U$=›z)ÏÛNw›\„%Ä¥øZ ”žk ¨ÑËùÇš ƒÊÊ@ÄF$&ˆŽ;DŒ¦ÍR¼†fŽyVrîPG6倥Ši†ï:ÀJi“aÅiö¤ ½‡…ä°bÒ‰§qjMèÁntYK<À,(à§)ŽˆÉŽ*cÎÀœ?rdss3¢bè‘2è¢ÆA>N(D$ã8Âùt–ÓT¥8G‰qš±¾È±Ÿ%5v)ç.eá,HÐ6®“E€Øóå¥ï9KÊÒ4Ä쑽ìâË®¼ä’Ó—@îÏݺäÔe“£ë7Üð™EŸ®¹úÚÑz„1D­s€Äœ30àt¶?ë§D0j÷|þÃïÿÀ£®½òÒS›{’'pìäúúÞnÓõ=]è`ïÂ|oçìgn?sËîþö<ß9&<ÙòÚÆ±k¯¼|ûÝ|ÓÙØÌÆÇ8´yÞ-F]a\‡¼+»;`±¿ÞŽˆãlÖOç9B`6½ãÖÏ9vQ± Ú–p§¥L¶£@ɪ´[f7§ÚÝ¥S¦4¯yzêz*-QÈá E u¿¤Î !ÁŠw˜à´´{ ënÜØžmDàí¶¤ºúè¾.ú¥·àœaèC\á’ T.‡áåQ¨¥Qyø¡,GZ„9×ã‹ìLn‚*»Z8ãÆ¡BA­¢"Ë0ü\Û@Ù¸7½&KÁðsùa²µç8>bÊ…`AÀ€ígÑñ€Ë¿*=õÝlÎæ9ÿ'ÿT¾&YÙ,­ü~\•‹r¶weR]í„»¯ÜïÓ´mS2ÙõKˆ²ËDC‰DV·Ò“;Â@8Û²°xÔS—R" ˜BÛ´kÇZ¥Š0çNïÌ]žwº±Í(„‘(Nb³Ñ‚p^ìììN§óшƣÈÌHã(ĉHÎ1†ql¾àà\¾¤?PÓhž°t}—ÒyâÄ¥§&SN‹íúY×ͧ{»ë›ãS'ÖOŸØ¼äÈŸ|OwÉøþ¾¼ïûÛnÈ_èsÞßïn¹e¾»w¡Ïû)ï§kãñæ‘cGbs’ÚÙßuû9ˆ#»)/r1@A$Í¥_¬¯a”v§ëºœr‚HˆÖ'ÍÖÖì 7~úªû^×¶ ˈ…1wè±ì*Í{ÃZJè^µkNõžs¶xQ“”“@F!v¸øj’nmÇ\­˜•¢]m™Øú‰Ê1‡ŸTGom˜Sm¨¯M@4œß‡'Š¥FÊ€Y*ô0ø³ó#×Eß%SI8ór^˜ÜûED›uá©«+i‰ÿ„aàõ ݱá Ð”9èúËê÷A¢:E¸Ž65KÉŪÚp5"¢;ý@@‡BS ‘sÒ½‚°=n14ûòÍqù0-^X„RƒÂj²°è”íÙƒ‘­ôœ»U¦×ò}ûùVN ݳ†Ã ’&RÖ@@HƒÙmUîÈœ-®Y߯ùu÷Ô_¿­mk”ôvDæ#YÔ°êÁpM¡i(† FcÎå4G§ºàßøx±™Ph=©&q^QÓ¥=½ÉŽY×hŸæ!DIýÌ¢Ñ?ä–ÔÔ/fóEî{Ç#jÛ Rà¶Aæ”RN™‰ ííï}ê“ÿðOŸüäÙ­ ãµÍÑÚøô½¯½ä^—ÜïºG\yúÞ·nŸ=ak}|”Z¹…g·Üzûbº×†€9ÉbÒË,mL&_4¹öÌçg¦—l^ÖwyÑϰÓÄ$¸ïg³ùÎ|šy Ó| -È8ììÜW<ìâIsû]ŸùÌ;?“7ŽŒ¶÷Ãm·o?úq¿úšËâå§>ñO»Û¦£uYo0„,Ó<_[ì­5M?iÓïÓh 2u}„Ô@æ¶IúÜísæf.ÇdÔG™6)Ž@ún‘3 È™Ûoìf;‹È1dà6„ê7X *À±<Ê)÷³C¬JC4é r`/ÍÎÇiŠ%Dá„€ˆD*‡2qT††Ù'’ú\׬”œæÆñ+âìÜQh­ÚÑuùìå<—¥O’ U”$[ÛR+(— ©Ã.ûR›Ô…µÔ ÆV>D:>L|WÑM@óiJÜ@bD¤¾ õõÃÄÖ»Aj-j$þÝýùz×"Ü{jok{×ÕÄMBȼäCS#Vî³þ J×Èݧ%/Up M;‡ÿÿÿ‰;w}"õSÕ"…Ðn(Ï•âˆÂXq¸LPG Š#ÎHŽíÆbÿ.Î]7ÛêçúÙV7ÛéûEŒ¶ÒÑ…n«¿T pÐ(ØÝ¦YTB’²ä…aN‘ˆ,úqÚ5‘Æã‰Ç["™¿ÍiÖw{"c›õGúƒˆ0…1"r^,{)1‚.÷mRî{‰1„ЈŢàxDëkåÙÀ©W:Ql îÚÚþë½ësŸ»1†Ñ±]qï+ñÅ|øu_2øü¹/ŒýýwÿÉMwÞrñéK`C3:¿X¤n¾6¦õ µ0'莭&ÇG'noßM7íßçÂh<Ç0s#Û Ø›v:˜Ï»Ýýó{Óí<•5oNF—]vš`þ…ÏöÂþÙÝí[OÝ[pܺ-ß¼½õ…3=~íwÜïªûÞ놟ËÇÆ 1ÌóÊd-¬Âbg7 MyrÛ™n§kbPè9ͤÛëš–×!@î÷ç ×(;ó~>'æ07ç¶ÎÜyË?®y2ÆQ £v¬{d , ÍD÷Ë*œÐ÷:ÄQU.Q—‡…ñQ>¤ÖÃØnX‚X³®ChÄÛ K‹¢(ÂÍèh9*1'Ns@Êý¾~a7=—úýÐLP寥!è‚n½Õµ©äÜ陃Ù2½­d礄FÛópF¤¾Û+a°Þû8X8ånÏŽçyaOÄÜOõÁ“Ó¢ÔDË'÷>¦Þ¨P3Éý8-˜S7Ûîg³Ùl‘Kß ‰´±y 1„fR6ûèŸqK„vM»9}IZ ízîöD·¾9Íô!c»¡k±—±4èd@(q*u{D‘âX{”~±}èÊTbâ8-vq¶{;Ý~fšYRZ–UyJ!æÌ +ÉšMä`æœÍʦâÂú_Ñá“ú¥áå=„Ûóʦ~´~:ôûîG?袃Ï(ÍóÑåih"ä.Äqˆ“ЬÅfÔ¶kz+µ¤PìÞ’[‰˜s—úyŸ8\,˜YÖ&‘sæ×Sý,ç^DB!6¦ÖÔÜ]æ.õ="pî)6kfì㤇œûœ{­Ù)3!‚¨m )bå ¡¤hØÕÖ©°æÂ'Dê÷}FÚÝßýÄ'?ú®|<¬o?uåî{äÆäÒ3wžm>à¿0;çÎÜqæS7¾óÝoÛŸú¨žÏ-:î·æãöðT(wÝþF\Œc×5h’Ãñ¿ûÌöíwÍ6/½â¦þsãõËy|â$ìoÀÞ…ùÍwnaŸ·;èxÎhmmã8Œ/=:9Þ¥oü§þÜ-9ŸÝ¾å [goß9NÇ¢Œö¹ï˜7/½l'wNæ{ǰ훜º¦‡&И@³LÝÚ‘£ç§y/50Ù˜MSž§8Ïcµ í^fè9/bÌIº¸ I˜SÂî^¾°»»èy›sÄCˆ1©~«:rŠ_PÃ…O~òãÿûÝÞ¾úþ×]{ÝÃ?ý‰[Þñ–?¿ýöÝý½éææ‰fmýÔ§Ž]|êÍ¿ýškø€ëðEÿëwþø²^%æã3@ laúÐdh±šïÌÇM<ûùs‹œ¸f­ß?¿uËYˆ›ûãÙúhïï^ØÞ›CN„”h­Èz˜í6ñÂÖwÍç[ópó­<ŸnŒe,‹9æpnÁ—^v¯›î¸sëÌþ•§6ÖÖóZ‡“>ïwš€mìfÀÜŽR˜™‹9@n›©[Ì9÷©è…IÁ`sDMCyo1›îŽ‚Dˆm#mãè@—V…âH {i±[„ŸÚâùf9G»ß£+FUl„sæLÁµ÷ š2+ãNM3GÅ’pš+‡!4ëZ+ßÁ•C¢ßáP4U ƒA 4&wWÿ™/y@’œr^¸ey°«5=Å9!r±–«J$Í·µXsîËz­|[eÍâ‘ÊâHÏà¥òæ¾ó²µ›ÒÔPm %Û#Ä5ˆÍÄ>#ÍD8wó­ÏÉzð¯üBB«¥06k€”ú}(IŽÕÒEþqqµ¨–â‘ržë@œ¼žÓ\8å<a\FÚ9Í8ws¾c>Û€³[‹ÿ—·÷ ¶,»ÎÃÖZ{ïsnz¹_ç0 1ƒ@Ð ")€IQ0-û‡].«T¤]–«lÉ*«¤*ɦdI.IVQÁ”l1HŠ@ ˆ!"Mf¦'÷LçÜýò½÷¤½×Zþ±÷9ï¾îpH©Ü55õ^÷½/Ü»Ï:k­/9K±fÅÿÇ s¬¡·”ÎÛ[Å(µŽ•t¶ Ý}@+Äš­ž]Ý­¶3Å4ÌÙ¯i ZE²&F°µŽqÃØñõ¢aûÌê[ã%$›Íq¨C3Ž'cz-ªžìAÓ¶†£SMòîÆÑ¨Šrƒ{La%‘ÆûP7 Šþ—®]fEõªKØb OÙÎ%““õû9¦Làˆ\‰p“Lb0©?cfg¯ï°s:_æ¸; Ý6‡(žN¬ÊêùgŸ|öä3›;̳|èýÿôgíW¿øñŸ9täÇÿôO'f<¾zþÂö×~ûß/¬®Ü¸xæcêÇ-ë\)!A×5Tu5{ÎUú™ ¼iê¡€7šb{{rs ½ñ$¿êæÖí`F–k*&ªU=Áf.·ÞRUoV›å¾åÛcXßÚ”zL€3“ßýØ#§¿¼Yš™þ°7(ó 2àŠ€Hˆš •‡ÜúÃAS7YæØshšzRah}#€OjïCð¢Á0™3¾i&;ã¹~ƌܜ»¸šŒSöl¤u¡­*ÜYG©¨‚MjÎdΦ³¦ñ¤ÊÔù7·f:qäŒrd2H}bˆ(‘Œ¤kƒ¦cƒm²Èc›xöb¦1Ö€e7t}jüE¢{CâÀ§jS´’ö):–ÍŽöQ¤|çìÕ&H²†²ÝWjªƒÏdËðo¡$U§ÊïúÁ¨Ðµ>°'w'¡Ve.ëV¸LÝt¸ûbv®ZdPR!Ü´)ž ì»Jj²¡ª€Hä-¤ÍFŒ(ç&ö•­=q˜eø&w»VòÃP“q ÍT•ë:°¨!´†¬%iµ¼±ŽBWCùNDÏ®»œ]šä»ÜF1ºÃ³f¼qö‘]¯ Öº!ÎøÓ¤Èõã'nLb7:cI‹G’aÛ3®olÏf#_ï(Èx21D€`Mk§†Dѳm$CðˆÁEº°³N%$Õ.gÀ’i„½ˆˆª÷9̆%Eß@k3$K¸{†¢"Jid †${hC¤†'ãPa´%ˆL¦•˜©¨¢*³¨°–U¹víÒ ÏŸ|íÌiµ´¸zð£ŸþØÜÒÒ/þíôÿü‹Ï=r÷?ú'ÿ×Ö&½ëm÷í]/ás?ù3Ï=ý­áÊÒS_yâC¿ûÿØë§^0&ì¨ÅWê˲hL“eÚo ¦žnÞ¨n\ÞÊç>𱎜Y_Ûëûõ6fd@l]ÕxšåV°£Æ›7s€W/`Ø™›s†jm1é÷G=úöâ ßijidâ±i˜=€¸Ü¢ã<÷lÄ4•+¢¾Ñª µg‹Æ‘d!ï© $uM³R)v„aØwD*Ü„ºöÆùR;#.%c9c(ɸ˜ö: [“«r´W *hQ©¨ÓWá¸XDréFÞŠ)¢®œ} *ñ¬ x2ÀíIàÆ®RWË,ìMnè$ìªmËÖÔY#¶Ú&`&Ÿa× cï7ž»í(p¨âª,â…iŒ™“ \'aKÛìqÉSñÍx÷/#_L‹×§ð2™£D“P_¨tÈR–¶»pqTc¬rhq?âP¥82$"3{ãñåVëCÈÑì5ͪ\¥Ôç #›/Dü™¹Ra™U‚€†f7ª ê,å†ÈäÇ&ò±ô±ÞIñ7ÎêÍ åÿsKûùVÙjêmî’RZHÅ£±”¸ÈÓA˜ªÌ¾–P…f¾ Í44U/·ÑR=q§¹‰·½¢bfÈf™Ë²,"’„ ,ãIÙëYg3UáЀ¤ŒÈõ;*\sD5ˆx‘Ä7 “!Bd"ìÒ˜S6\ÜÄ™¼µ4EUU²H ¾"²q"A EÒ°*ˆjU1"XƒH|8úõ7ÞxéÚ›…ç¹ý«w¿í^0ù—¾øo?ñôÙ3§V÷-þâßý»;ïÿø7ÿõó—ªúQ“Ã/üÕÿó¯ü¾S\9÷Ò©_ù;ÿôËÿáw~;ûõí–â•Ë—×&—œå~Pýú•¢š†j®¹÷Þûì/ž}úäÎÕŸúÌÝ×ßšðÖ3ë²Å••ýûzÅx£.§†Ç™©N~÷ÅíëÛ¼ÇWõú`d‚¯rtýBÝþ}K+‡ßn´´¸:À9)*ôJ"`ÜT^EM¿?ª½-w$Ô8öêº×½¢$>¯‚¨'R²Æ‚X—™<ë}©ÎªPbV"’É(^áì ¤6b€;â·S JN¸é£Ì­äѨÉïÈbŽ'3Aöd”SEKH­ _ã'k ¶¤BÄ»öÁulª®XtËÓ”1À¡Þ‡Õ5V)ÜÅu¡OˆO­Y(Eb_«×ŒÃ{4æØ±ÆÝTC9(î¡f 7*A9ÜÎÐLuK¶OÀT¿„2²ÚJJÉî25Œ]H"w*ÕÝÕvJÒVb_’͹)T9øiDÉÅ,¯¸¡æÀ{dc”CÐ)ˆ®…›ÈŠW¥r¼Y¶KEß4 °$‘Ò-ËÍԓʶ¢·C@w,©·L÷ÿ±H}LÖÝ¥DìÚ‘ìµÕh ŸÒyb=i .×}µÝ”u±æËͪØáÆK«bòšŒ ß,ѬÝXBM™ÔY¢äº„๮Œôó~/ø ñ œ Xkš*LÆÂ^¬µƒ2™vólK”¨!cm_A³î÷ÚÌšZ¸îºÑ®®[ã.n¹“»2¤LAb_vÎd@$¡FƒÂ 5Ù SÞÕ}Æñ¼åT¥µ²±¹²‚ú¤:¯€*¡n¸jÊ~NçˆdÍfKƒŸÎd™D¦‹„ÀMâQ4“îb"5zÅ2¶—n]Ú¦ŠEncµ½+ùGT >x/9j¼°è[” ÿÚ•Kjmüº&2–à?^Óz‡2Šd)ñ'R©ß{xXQ—j–P%£L®ã±ðÕ‡Ò×ÛÜL|½3-Ùe#2¡õfÏ,¢ÐÔ ‘Zk£ã8‘%"i|ÅAãKc-ôú£X(¹.‚¨‡Ð¨ŠÄ9ÐYD´­Ï±sl)vûv=䀢×rS7Å9GD1õÝtÖ˜(÷ɬ®}1™œ>õÂ+¯<;O ŸgóÍqQzàÁGç—·/_ßêÍÕhìÁóÁÒOæñ_ùµ¯Ž· ›/-¯5vð?ýµÿÊ™ëÿáó¿¶°¼ð+¿ôk½€ãÿ…c};ž›®ßØ ÚTUäößu×уœ;S^:sua~ù“ÿ¹{<ü¯é_ü«oq>7C¶g„* ¶gæ—çN;úð#÷}à±w^=¿þïóëçOžyôí¾ëЋk¥jþÀêÃýl”Í-ßó¶û¥â3WÏÕãMc¬ƒ¡n*ïr?×Ï 6W¯ÙK€¬X{½Ï YqÔˆfÏje£¤à|hÄZ÷µì;°Là–¥a;·¶öÞ‰àÙ36›çDñ]žMû!Ò8D#è…ò´'3ˆu a[+“¯£íá,¥¤›è!F©E–xR$#2 ìUün+,¡ž)÷𠍙XI#A=uO×JE nK%T»ùzmÈ®iWk¨òH¤ÊÀ‰oTEƒp4¶3þ r3à&%'KHtׄäˆäâ‚"öuÃï…B<ÏU‡2ÒÑÛ`íVrÖ:lAÄom6Jt«™F5Þ$f“rÚðJCäB3QZ‰8pÄf™ëº!JV±€F&–¢ —nŠ„ï¡{ µ‚$çvÆ¿ã–Óš[yM¢pKu~+méíþ-£½5&×Yô-éšef/®-…E|h¦‰HÏ>2¸™4åFh¦Mµåëí² ÂÑB)ª•"àU×TUcÉY›&/Ek1ÊFƒ¯DQ¤aVï¹—Ûøƒ"FØ #sʈàm"Æ]UûMÃnjÎ8­’qyÏ9UB ÌÁW¢ÖD…R’|‰Â¥ çž}ú[—¯_gM¿W°–EãÁ7^ÿ±{ÿ‡?òù_ùBÿé^]ׯ\¾ûáÏ]¼~íüïáÅWn<öÞà£?{×Ý'¾óÍ/þ³_zvayåÄ='Fùá'¿ýÔ¿ü—¿zyíüw¾rýêêÑå¥ý nØË²þ¤Ú|åõ§C#}”#ùr½]½tñ»‹ÇÏÝûžáJ–ß<}ss§T‚FasÝ?~×§ÿôc÷>ôÐÊâ±y»rß‘9râÁ“/¼|ùÜåú†Ç^Ø¿|ö™Í§¾÷Ôù•söç>ãàµõf2å•‹kXnnAUŽŒÜÜQ7USWEMÀ—¢ B>8»9‘A>Zœ[2ÓPV×ÇÕD@òåh3EÕ ‡£à kÄ «¯2YôÐB²Y¾Ãnf®í§¢N¥ëògr¨$*y\;Û’°7ÖÄ©0²·Q‰lÊD¨Šá´+èXV»®¸yœ®bG¸KަWùx?`O‰I¾Ï» H¬~nЏÁPuÒ—.5¯³ï#²Ì¡½Ê:ÜiO·1½ƒqO¯šZÄbÄ‹ÒtÜÆö‘ËZcù®ÙÍ%T"j öé÷Œ5X\>ßn<[û`J¤´ˆìíâo¡VÔÐLâÊ¡jEÚÊðÓ~÷Ÿ€ã@[jm\{ï;CBº/Æ 7L´‡–4[õbm7¢À¢ÜšåÇÒw{L8ûm‰!©ìÊúÖYnÓ-{Oiw²4 t˜Ù)ØH¾eÄu‚_ØiÛÝJAØé@´bÌ•„:î…CãEÅÅ YÛCBeñ"ŒÐ>TÔ9ë\f  !ŠŽÜDHFcTÄ-‘MwrDUñ>:;tq€* 3§HB2¨” /€ªFÉ’ª‚È bÈ #³ QãRog{ëäSß}ýÔK[ÓsK™ ‚xåÈ~5Yæ½áèÛßúî¥ ·'…|äȱÏýôÏýÅŸÿk_ÿò~þ¯ÿýÇÿä_øƒ'žûÊ+ߟl_¾zåÜÍkÏVEAû³‡÷·¶¾ú…ï,¿²üÉŸþØ¡ã‡Ô°›3Xת¸~ö¶‡W‹µ/üÆ×|uãñŸ>þÐ#ýUÈò­£Åõ²Ë×Ê/|éû<ø©<¼]çk×wª<[š[¾çÈ;ï9òž—N>ÿì‹/þÖ¿ûÆÚúæŸú±ŸüПøð7þÃïLê*÷;Z×\Nlðã¢1ÊŒ^¡ð 44/=gÊ š²ñ¾†¦,kuÎùÚqKsƒ‹×§'_y}iiù+ˆns:™”•gXXÈp47Ta4 ×^Øå€ÆY"ש›‰¬ “ÍM6¸S"ˆÄ­_„7Í[ëkjí)[´&TÆõ“@miCÍ@reäT@ÄÒ–|WUe A&Ü íŠgnäpdþI:á¾cþ%ýqû°g÷©ýlŸÒ6‰»þ#êÈR˜IdÚ½™ëÈHw nÝÑFKyaþÇD¶ø*Ù|.j½„›Xg5„Æs¬)dTm6²ˆù`E“Oyü¥šôc G¼>Vj@Œ­Rd¹ªªp5ó3çݨ±×3Á@hÊÀRT ƒžIèÐÞÆ†}ÛxUkÐ6^¢­Ph·¢¢Q“šS›Iz§[+àñŸØ{ÎbSwl÷ý_|îϘ‡\»q¹ÜY[Z^ºûcé/ÿüoñwÜw_/ïÿÊ¿økÅÆúµ›g×nÞ¨ËkYn{YŸ,‘ƒÞ¼¹çm>ö“VÕtR–U¨†ss›^kóÎÇÞwæäÉï}íPóÉÿ‘Ç~d¹,¯]k¶a8u°°4¿8°`4yízøÊ‹—k`ɰ}?¿OŽìï=ôŽ»‹%øæ ßxè¾cŸüøãƒåÅNÝò“—¿õYl‡vvv¤ærk:VÔÞ]Û8c ¤ÞMËа™TrpÿQ—åßzæÂ3ÏÝ,jžË'W×̃nÿÊp07•i …Gër ªÔe•‘s¹Í@," ù%#Ò1]@´Qáˆî¡qê4ØZcw©Q Ì @„\_X¢¤-v=i¿ß"Vcò.¾I•cQNÝ+7©ªÂÞØñ]±‡%ʰ&º¨ª°´Êw‰¿—±’w?ë±?ëØßØ8·›1¯­ùNwM“§}ˆJÚ°!&˜&,ÈtÈp4'å"—C¥ÊÂB†l–uóœ#²‘Öí›ÉÞdfN£½Ip–„šC'÷Š.PH&®AUBÕøhÕâ$§ e͆0Ïêºéºl ¬±H±¤kW"©60û ‘Ä3ã6Þ6±GIÇ꯻|£;¢êíJ4õ³·ÐŽÛ¿Îl§y; µ+¯"ú&¶Íq½Òý-¾¬¡™t¤â(‰M›æd»ëg=b+Ú95¤Õç »«Æ K¬“É(Dc-F¶¤½Râ6sh+ÀèÑ­Ñ•DÛ}+ÆåÉ.Wô4%ƒP”)JÜv%À¢\‹xêB¥0FˆŽvˆk7o<ûô·^{õd>Ðqåóá ?ØáÐô{÷¿ãÝn0:wþ•K×|ôцýõK7Œ5 £ÑÂòü×¾ð;æ¡Çûê—¾°¼rdãææÅK—D¦*Íp4šNÆ[ÛþÈ‘ÃÛÛ`˜\3?r6§Rš¦œÖÍ`¸üÀ{yíäOüÛߟŸÏüg?zà ¿zå¦ËXÏúUăk¼Ù*ÊIÐÁþÁØïÀ€$Ôaê&¥Œ{Ù˜Ã=÷ùħßW›æêÅÓï¾ïþ³k>ûÙÇß8õ²ŒëóWvŽ]¼|q½ØÚ,Ö7§'Þ6(ÆãºjFÖ ˆ‚XSL}xyinaqøg®}û7Ux”S?7“‚Ã5¿SÖû–ó…a>-jtÃ~¿ÊI𚦳˜ΡD ELKÉÙ*H¶G¶×rDÈvÃû®±ÅîÚÚP—>¡ìHˆdÇ6VAµåÔD Ýö[sœ–¶¬  t äÝzs‡ÎÇP¸Ù}„:Z· ²igvž ¼¼“ý]K ŠK³X……k“Èä¡ÚAcc %²DÍž5H}&»e2Ùì(ÃèãrŸH‰™¬s ˆÅ7uE¡º%O¸UT7eGѪán:Žo ‘-‹)‹Šh,‹¢»Ã¯!…0 ¬2+·€{W°˜œ%°`'E Ûö˜·|°GúæÕó–¯p ·ôŽÔú·Ho²f÷¨ìêãý°s‹ðÕ6¨?mý:öC"E‡z¬-1-¡™?åP†f\5Üx©k¶ Åê1œÉpð!Ô€dL øTнc SUT‘6€;rTâ±&2Í “Sºtvâ1°£yj!ÙÑÏDÚ929"‰4íwé\gøü¹ ßùæãÍmGKWnn5.¬îsÑéÄöæWWGGøí?xêÊOýÌŸ}ï»ßþÿÆß¾yãü÷îgÙÕ³gYêþÀüÁ—¿xøÐ+£á¥SÏ;g··¯-/ïO·€Ëb º²ù⹫kçócýO‡ù‰+_{ø¹³îà‘/}é·¿ý;ß{÷»ïþÀÇî[8PÔõ…iu¹„­Þ(÷:èõç*žŸ„a᳋ç7ΞÞ~ôîÑx§™Ê.„I¹^Vg¶6OZéò°qmkRž¿xþÆµÉ ïùí ×çïZØ9ù‚]=8/¤«£¥óþÒ¥óãµ+Ó© ÖËóªöÚˆuy–÷F«s›“âÿú³®ÖÞËÀÁÑ£ù'–½åµí×ËqQÌÍÕ;þýz`kír–[cÐ*±ª°aTd °v ám¿ Éš‘ÈjR¯[D"›w[4͉¦í¢š˜@Pw ðÖïÆ!¹XzRhX”NI9'i $žlofSɳ¡Ø.ÄO}µ«R¤p¨báøcp(»U¦37Ðbñ{ñJ‰ß éBIm¯G²±M&×GÌ5)KH¿ *C;þs7Ë·íœ_’ÐLè@ì=ÑD"-7ŠŠâC3‰[DT¥Î‡T¸ Í$ÖÍ7Oóª(8‹"M݈1UYq·g´6½Þ댘=µ-,®:D˜>eQDT/·”×[DJ·,þH¸úìƒo•{ÞZpÿpˆ)ºsï ¢ÚN¬„JÄ# ûR¸ ¾ˆ~±‰?_âµ\^[ W²lUæPI¨ƒŸ6åÆÖNU”<-C¼Df—­¹l$²¨´©ŠÉ…7Ƥ$)'wæÍ’4&20l:I{ýe#ÕF[¶Lñ1ÿ9ÂS)؃'ƒÆäÖf¾®Ã+/Ÿ|ýÕ“¡©ÍÆÆ–88râȾÇLoà1«ëFžýþ³/=ùÔÅÓg>õÙOÿâ_ÿ;_ûÕ/<¾êª á¾GNlln½úÂÙÁÜ\YL®_½è}¡šøÃ½tñ›§ €Ön¬e³´º¼~sò¯~é×?þÙ®î;þúËÏŸ~õôsO¾pþ̹O}æOþ¹ÿì“Ε®=Ó@5·äÄ¡Ûë|C¾‘~6äðáS¯_¾|~íød߯úæth@·½¡‰]rË"üä·O®<Šeμqa´8|þÜ ŠÛy?þ…‹VM¯ÉGýž¥ìÜ¥q¾jç.PphJíÙ‹¬5ÛWÖÆ£Qóþ÷ î?ql{kß¿Ñc³²¸º²S7DërËF¼!2–T”ÌL)Q 0í¸MÔÚ^¸l4c7N„f·qS芀h%Dr)ˆ 2"² µ³0R*4ŒMµÑd5NHZ¯9PÅ4¶uÙãÂA•;§¢´—Üí@“Ô§\Üu¼§£ ­ÚÎì!šƒh+´® öÒä”bTT9$ªHp:{ l…[±jÇ &îM¥ŽËº;´Ã‘>±Û,#Šp¡’he’9BL}¥¹-?¥åÕ ! ApoOK¤$W,˜ý×0³gDƒé‘·©‘÷4³³+ÎX¼n‡ËgÍJÞLÚ”jâ[, w,©Ý3¢Z¬J`_¶ØQ"š°/Uû"Î_Ì5¢ñõNB-[|\%{ˆU¡¨˜’º#ò¥ºä)@C؆/îÆÅtžiI1›lhE!ò@¥õ%"JÑ{Ê’›wkë­ïüˆ¦ ßF’¨Q ­5ªXÕ "£Á7Å+Ï?}ãÚåb»>waíâå›Ü5_½-Ë~ï½\Áµ7®Œ'Ó}‡OdÙè¹'¾ó—¾ÿ|(Æó+ƒÜñdçæÑCû¯œ>ÿêso8tG7¯\œ¬Ý°àÊɯɧ6릙ô'“i]ëÎöL騉#›;;¿üÿ_ÿåüȉ|4¢Õ«RŒ?ò£wÿìO?L|öúׇͫsuÛÆm;Q×ä9 j„‡½ÕÚÍ­sýQùÈ XqV +”+¾¯UÎëUÉ[[Þy¿6×RóÖÚCs\ÅP‚€½º] MŸ×‚­a±7ûÐ1›Æ‰Ý)ý椎{‡îYŽzÖù€ý¸&»n{ÃIÅ,Ìçzy–YÊúKÚÜ`Ö~nú=“Ü £F¥õé°ÙH•³½¡ @qïÖ}!P*"dQc¦7u–*Ç`¢˜¶­’LTÙfs-Õ”½Ëç÷Ö‘ ˜\ìZ{*ê4kw%5Mß<ã÷,‰25ãÚË¡ö¡“驲u– w³6A…#o)eBò$e_v5ŽÈª”"!. ¢Ç¾ÒÞ†J5n.vMÓi7ç9žmáf6_ƒm¬ÙuTDï=³6¾1{™!CdráJƒG³u@„~ÏÄÒS7¡•Ø6ƒ+>ö­â¥—›™6UÒ[à: TRã[—À"Øm? wÒŽ4¬ ¬{”ï·˜†¼Ù\Çó?]4ÍYÿ§XCUÁ*¤£ÐÂDÝEêL£ó¦°h¼E#’UáÎc&®«}3aiã\£9UÊÅŒ¿vÜhK#Ì1›ÞŠÄw‹÷v‰±K‘ó( ¶†  Â^$ã’7ÊlhA¤Ò³OùäQß‚†ŒI4ƒ6>DqD´Ãçrg§xíäwÇ›7_yõÒ^xmcs‡”e½ãðõ/}ëÞG¿ñøÏüÔþ÷ì37ãªþ_ùŸßÿà][_ÿò¯þÚɧ¾ ¡É\æ³>l¯o×U•¹ Šj27Z¨ªmcÜÎd =çd´¹µ¹~cûžÿƒúWVäëåE—¹WNžã:ñÆÆf]WlY+Ÿ9ŸõM‚L¶ëº¥ÅìèÁ¥ºqÎl\:{EûŽkúÚ ‡à ^àÐÁƒÏ^ØÜغôÆåÕûr%›[“~Ï¢…íquðÐ’ñxáÂF³1± ÏÜhHލÜñÛ•¯)‚ ±s£ô‹¢)?È ê:C­›º ÔõûÕeÖåsn”ÊXjSa²¤Ado&ŸC ,_ˆê81YÔ&AgýÕ¶P|gP €Vc0o [mm•‘¸ VKŠLëq¸£­ýz1´‘¾¹:íIÍ!öShsI PÚ¸' 2™ˆ7»[U%$cv½LŒÎN4LUfI)öÅŒtêbÈ2W»2*MÅñ¹Iðn\òÊ pÓ:*é¬ùdëŒÆZÀ!A`a,u]s®™Õ ÎJÕpg\äÃl¸4¤üZJu“TfB‘‹ÕÙPµÏÒ;xÎ~«dü²¢é "#­¿Å-%ODßLÿþ–H ,¾½5{›;zV|Ñl±})4;H6m»“§\“DÌ»’µè8ׯu±/U9ª?ÙO'EØû¨@è÷{(ì1m:EY|$“ÆJÊíÚ€YX¢‚2Æ”imQKD1‰Ð!´,A„IÓ}WC[ÎS É$ŒI’­+ÐeVD-ˆ5‚ãqõÆÉ§žþþ‹Ïž|ýúÚdÙ{8|âîCw8tøðÀÚW_>õä“O~í_ÿÖâÒÒüê2õ`qeîý9P¯Ìí,ô,¢kÂüÜò‚êUB$û÷ï¿zùº`˜÷'ÓÂõóºnŠI½ï@nrÙÞ.—çþÜùaÜ÷½gÎ^™Û?Èpxyzq®(ô×6®—åÅ¥ev«=^©Ô6Á… ®ï5_è£q;“ÉÆæ$s«\+æyésðMŰ2ôû=_põÌÛØ“ 0 Ь·TîCÏ›ëÛÇû°3 W·wt`67]žì4åTçÜâ⨗;ÓsuÃYÏ ×ì2Ôo5JèU|í¹—;°X×\3“És¢Ì@Ôhì‰KB² â›q’EFþS4Ùlyï©’5 L§.ü'9yCôàÈvÃkÑ qè,™LÑ@kóزÁnv€"¨7HNߨí©2ª°²²·°7vЮPÃ-~%Ê•ª9E6­kgü.Æ f©?‰DÊ™3Šóx$c*áZBª¡»Løb$"k¡™ì::‹p(BàÙîL5Äé»ÛH2kœ»­Ak)6V±â°hS†˜;Ùx AX`GÙ3\ß^»¿LÃûLô[ÂÛúÛ}p˳ººÙQAYß´äýpë[ o;zë" ÔAö±†v¯e? Í$î˜ 1ÞC#˜Ø àÑb–Û+$~ÍkÏ—ø_U%h,µ £Ý@žà½÷ž ÕÑÀÞZVc”ˆˆ,†¤3 *  @”‘±dŒŠ@„€wEu6¢ÀDF“.”’SIòîV&Ê¢*_Ø«Òx\}õK_xâOmmOŽÝs×gþüçöŸ8a† ƒÕ}s+‡ö/Îç ¿ïG6ÿø¹té¥çŸ?{ö5oªû::ž^»øú¹……~6ÌòA¿Ü¬6Öv—œ{msÒfyÏí[]¹|隀6>`]× ÚåYîª0öß¿ôàÛ÷¯_,Âf.~ee0\6[×wΜ¹`Û«lØ ³Aæ¤â¦Qבּ¦œÈåK;{‹+æÆVqåÜöÑ••õ듹CK£Ñ\¹1&Æ-/«ý^xî¥{8ÑlTƒafè+™TlÀAåûhö éú¥zs[rìlÞw+«ƒ5[L|" z9ˆrK# AƒT"!#HÊÂHÂ,5Kæ°nØtJN…^Ï´W€€°F«´²#’²²'›KþªvÀvZuæg:@) Rˆ0/¬,‘S™Tó3b' 5’…ÓC¶QÉä*>Öbâzבa¦” !œI˜Pa¹-YO“]»<åP·›_QØ“HÑ.R Ù¼‹!éxû)rƒˆDiªÄímæKš¬»Ú;»¬l“ÉÁ"F±P\}FŸ~g’.ô ‹îºÒů¿Çpøv â¶ìr÷¥R:ôî·â½j"¸MtË„~ÇÊx otÖô?ÕŸÛ¿ï-_߆fÂMwXª’ &aá†ý4ZÎÄ÷¸GGŠFhÙΡ¨ÂÎÄO‹PÖÜxñ!®´ó¾N1”¥$5Ö 5C@19’ªÖêƒQ\ÇwN5t7$ ! ¦È‡¤¬oÓ@„ïUãÒ¶(‰‹ChLÚ”âæVùùÏÿ›o¿ðâðØòŸø êè½÷ÙÁ`ìpqŸÛwx,º¶v®odß¾Õ‘9øÀ±¥·à±íÍO|õ·žúÙw~øA <…’µõTW~gçÊ#ï9VÕÕ•Ë›“­ÓƒÑ`aaq:-(†Š-¬,Q¯OÆMSÒï<Ž}³v“z£%!Xä½¼qsrÓ q€s[•‚ɬh32¤l – KGN¬œ:½vþ•Íãï&[;*°4Æ‘Ÿzè÷ßè[ßýÁÎÎt™éZ±°4\ZìSãI¹4ZØÚ„ßzîµ­íÚìwÃ¥>öòeæØ±…­É¤®{ìF™ëQkhâQg\Dþ\µ  ˆb–9iT/™#u¶]’'DŒí‰„Î#8¡™DƒŒÖ¿ƒÉ¸ÐLÚTèÁn…ƒuý˜!¯H@ Š1® Á¨% *Ñp¾ã'®(†(vŠ‹!ãú*ÈF*tËóo#M«1o¦­]wlô’Q¨Œ…>2XŒ°/¢>ØW±øE™‡:¶Ø³±}jšIìÊwsk@ã.5ÁñƲ/)„zoIb¥cx'ä¿¥õƒ¡„ªªeÍ‘s¶J¾ÝŽÝVWLC‹Î~—®åŒÖú™#Vd-µ“ïX÷]Ù¥öèäÞcÞ®/²†ä¶èùØœý±»Ñ?†ÐÞ†zÜÔÛÆæÂÅ—-µÂ‡f‚Æ‘qÉaQ%Ä3ÑZ%BQ…¢âiÊZÊŠËŠëFâMU…€Z-H™Œ»£ñ*BÔwÆ+Ñô{6r˜fäÆ\–^¡užDEPÀäl,©RÔŠ„Éz@„Ö"j=ˆ€€jTÅYŒÖAã­éçÿíÿ½ÃüÞÇß?wô..n„©”°´ÿ ò+k×pØ· Àé«g›‰?¸ïp>È÷,./_ýúå7^8õÐÛ8ÿêë—N_É]?[n®­¯ml]¹H‡Ž.7u¹½Á£»~u@–™Þp4·0ÄÌôswåúµ^>ú‘-GçÆH¦kmÈ“}-’ÓN'žÈ$¥^òsB@£$ÑàBÙwayÑ÷s6±.Bçšö¹ÉíX»ÐºhºL–}oÖ qf¢l§ñ‘Tß93u­¨!ô­5ŸéøF {!½¥ AM‹é’!a™-giåG»Ÿ­Ó:b×?vhÆ #žœ1Õ7!®ßÑ}ùŽUì––óvòæìÃþÓNôhÁµÕôz]¬Ùl ²¢09iNŒ®C3Žu­*w˜µjb1Ò„ … !( ø !UNö%ŠH„–œÔ%5 Z‚‚D7-kÐZkl A´ Ïªr¿Ÿì¶€$úŠ0KðB4ÐCcP9š-+ †ÄZMž¾eJ‘µ:Þ)þýoþÚ ®—NËÀ}+ìú,€S¯g²ÜVÁAŽ}ÃN-âëêü3+óËû——~ôc~áûOþ«¿÷ËGï:VNv,¸Å…•õ›ë½~O°8ñÆÜ`püîåp¨±Î­mÖ™cK07—£!֨ɷ›ºØæGÞµzâÁÅÍéºêP‚3¦)ÇÃ+gÇ;E1\Úì;€Á°?ÊaXL¡OvØ få:×5²£»ºûà¡‹Ï<ýòæ•íáü‚‡Þœs¡dg²J‹ô~û¿û¿zæ• Ç2¡×/ß|íÌù›Ó‡W¶y¦yÆÀv«Wi\† °ÿÐèæÍ­rii9kŒD£ãÌ8$8‘–ÀÀL±Ã°íõ“ç™ÎJ$©£ÚMômÕìËHG²dœuCæZ%çì‹÷K¨Œ´DU0$b˜Bq¥˜2 u7Ò#MÓdDB£iH,ŽÖ ‚‰öì E²¨ÜÉã>ŠC¥@HÐYG‡PC2läø_\SĈ§¿¨ÝuU–P¥®¢ õЉâ "…€@šŠrš}½“Ì–À¤uªpݤV£ñÒÁ%óŒŒ2öÖñÓ8øÇ!êÓÓR’EHî\è(ïi–®ßm3g «B3!H±>&rèLæÇ-ôø[ fh…žwÔeÞóy3eѵ!½#Mê‡ÃVÝ_ÚPC3Þ½‹ú2N[ÂA¸ªë&Ú®toCkV˜ÞU,Ñ]^$ñ<9Th¡HÆ‚€j`– b>DTcуhAEÕÇþ\%êLÎ"ˆú²ÇS"¢ª˜ç¶×‹ |Ø{Ϫ` 8ˆ¨-¼ß镉Ìv¾üÅÏoùâžw=Ôß¿º D&§¼Ÿ™,ÏçœÉp0åfÐØf}k§ZÛ†nvŠìþƒK|×{»tñìþƒï%¥s/Ÿ­ƒï‡b«ÀÅÍ›d$¿ûÞ¾gO€“IM £Q¯˜Êt»L ó ƒ¾¹º>ÝO– ?®jSCy5öã­2ŸË™Œ%ç‚8—“Í|LH¹­ ?¿DGï›{òéòõg/}ôÇŽ· ?®•pinÀ¾¡†A—WV®½v9£ìÒÖBà­­r~ixøÈálqXÕM6B¨ÀøáBÏPøÚ‡Pæç²É¤,ËÚ°ŽˆÀc¦º¬#u$¨¨1½Üúz§7´& ‰Š:¾Y†šÆËê>¹¾]Ïel¯©¶âÛÍ1I‚pÕ‡d¨ Yo±Å1B[=»1NÓâùñuÌ!i1Àq–³©mÓšì‹n­¡Jí ´­’Úq?÷:îE;D+‰A "™)Öñ®zvìË;V«®í*Z§þ¼½˜¾•ùGîÿH[Ñîç´ì ïð¾éú±ÈÁ 7¾OAvïBÝË!ªÎRÝH`U¢,ݽU¢>y:´±‹mg§:BVõCw»î¸ª8æb–‘¥”i H14.¹¢.™¬×&?ǵ@z‹É Òx2ý7¿û…rˆ‡Žžhjîå ½ÁBÕPîæ,ä¥TÖ œë0¿³¾uccûê°7Úwษ|qeý^:ùï{õ•Ó¯¾1¿2wåÊUê¯Í‘ù Ôœ~éx%C¾ÍM??ï f<ñÆÚ^/ßÞÞ™Nx{ÃùÄ{ï{øÀž>uäî}÷?rˆûý¹P„Ó¯½úÚ+g–÷³Çö9j€'Â,ÖpZM8cdÇ ,î›ìƒ÷|õ7¿ûÒÓ¯ø#oŽzÌd}›–{ƒµk/½qú•ËÇŽÏ?þ‰9théÚõ í ó~Ñ7ÅkW¼çþ|y©ï}S”ÓÌ™À2‹M]C†ˆYL`cI|ÄdH•!™"ŒƒÌ¢xTÀÚ `Ô§5YšŠ*¾‘¸Rï,sŒAk(Ëì.«<¹ÄBôÙKá"âg ÝÕ©¢‰KÒ$oçÐz¹“AUPa¬gºÔ›èà™4 ‰Ï1âA‘‚ŸFyÚTj<ÀÑ$a»ÌXÄ'5=¤¬e6^)> †Ä©p*Ü­qI¤ÄX7pqSÜYÌÅÇÄšIߺKµ(Ãì´³AÝÓNÞR@no;?yhCÇ2KÝcn!ÃÏÖÜ®-åV°¤ ·ï=géM?ÜhyV´¾g¬¦=Eó‡™Þ ÎþŸp7Úž¸.+n|Õx‰e±ɦ7ÜÁ°{{êî€ñˆ¬ÔY7­Y¿/ÐÖ£;6—ž%Þ£T›F1ËÈi٦ȩƒÆ1¶‹lœ¢:p¤ïEdb Œ%ÌgÄ@u2|åë¿IÃÞ‰ãw[Óï[ìöÏGƒù¬·,äò°1¥@ÍÕN9KÓTÖÏœzæÆ©3Åúf±5•Q¿OHuUolmôLß.fu(Äø>~*¿ñâébêó¼šÞÎfÞh-Âäú“©/‹ð±O¿ïoýãϽöêëO<ñÆsßyù쫯--¨¦=4à¡‘ÉßGè÷|³jpÚ€Æ pð\6žk!´XV“÷|ðîK§®^xõì=‡–ï¹ïW ÒXrÍõæÔ3çN¾òú±ý Ÿø³?zàðʦÅ€øÚöZ|äÞ…kç¯Þ¸¾ 6¸äœñGdB1¾ö JýŒ|Ðà%wàÇÔkMy®Nņ†³Á<‡:J AHX[#p’vèñ\5SBˆ·çè $¢è,´ñ²”ÓŒ,ìÅ4€UWg•=G\Û¸~Lü‚6/ÉAëf/ܨ/£a»ÍF‰­áua Ù©w7H‘F*Ü ŠqCRöÕ¶°³ÌuJ^’˜Dä£6)ÖÁØœÆR˜¢ÈÑ’É¢ÛHÜÄ:Ýþ­’ë×ÓëÚ²¾Œ2'ÇŸµÄÑ}™ÛtÌ;²2g+äl8ÛŠîY¶KÎLŽq”iî’™Ú )¶‚úÄÌ,«Ù¿%ÏÏ&¼VÓ[lßzeüÿk² Z7ïiE}Û&xö^Äoö[‹¶ýstúJ·bU m²3s]‹8‹Æ µ¤ª"˜çh(qƒ1.Žùh\4&#íà­ßEYqì<)F»Ä†4ŽEH¶öá«¿÷ÅÆL½¿`²ƒ>’ƒÞ°f,®`oÀÞ“s¡idçÒùWŸ{úü˯Ü<{öêÕ À‘ù•ÕÕ•O~âc=ôàÊÊÊSO?õÕ¯mRÃÃsÖ¸¦Ší“{ß'Þý¡?öÝß{þå—O9Éd¼‡ZØ“xüO?úWþÖO=õÔ·ÏŸ»±r`4\0ÓÉv9l¯¿ã®¿üs?ú¿üþìÙ‹×ßXxàýsìÅosNP—Sï«ÜIclD¤ª­x®7øÑÇúÊí§¾õ¢†pâÄJ¿ŸyõêÉo¼vùâ¦3øÀ;[¹xym¦½ÛØÞ MÀrj÷­ôGýåÉÚööú†ÍÜh”YKÍ´n‚·D懽±/J¼ôò~æ¬1„@Âj0蜓P)%‹˜®ëѤ˜&C@@C°!Ë’*<¦Æ ×ÂM1F#V d@Y…k—ÏGË÷(ÿñÉ)*º…¡‰™Iþ;{hvÇO¤˜ìÔmfÛ‰Û´0½íl¥f=“¢$rTV.ÒòRC²_JÕB;Ëób )iïUm\ÚÆ¶õ7þ¥ˆ‰úØþe†d‰\Sm¶Ñ¡Íá[6Ä=[Üg-âg?íèŸÑdzÅîU÷º²›Äš3$ÐVjÖŽùˆ™£è‰w ÿÍ¡wšcXüi¸þáKÏÛÕ¢o½{ý#èëÛuªn·óë-¢…ÙW¤” Áüœ(Ðqˆ°ÅRɪøÎÕ‘Á{ŽÁ®í&E‰(Ë£TfuÖÉ‚!ÍM)¥+úìEãQ‘†C¡ Ööãä%a2­‰4Ï¡E¤Æ‡?xêw·tóà]Ç·Lo8õlûvŽF£mGÐT\ÎPmlyæ©g¿þ»§žv{}maeñÄázüC?ñéO‚òêò 7`YþÈkÎ|ÿ~ð™ÿÌ¡£—_½ V8T…/î=zä¿ý«Ÿû{óŸ_yãÆá»Vv¶Ç‚Úë úý¬¬ÆUYýüßüðw¿÷»ç/žË{yÞì_]û‰Ñ\î«Ét{<7âGn0ï2:~ωçžyöôs§ßÿé÷î?rp²µ6új:ýÎ7ŸûägV.¬,Ͻ÷Cïºzæ²çpäøÒÜÒp2¾ú¥ßøÖ Ï¿~æÌUEÝ¿:Ÿ {uÙlìx ÅÁ•eŠçÏœþ3þѯéÌ©—N­ì=òž{šàCØTÎÄBÈ %‚ 2Ý(YzÇ;î~öÙSÏ;ôÆpàäB$„Ø®8¡«¼m`¬îÎjñ\ 9“Ê®QPDÊMíÖ)×7¯>óʨ­Û,ªq/ì”[ƒÅñA¦ã%ã–†s믜úƒ/~ñ¥§ž,67?òØ£?ñ©>püðèÈR=_ïì\ uÑïåÎi­Þ{Ý)ÂÊþƒŸþÙϾþêëOüÆ×ýèƒÇ»z.àݱÁÍ›7×®<ðè1ί{#Ë×­Ù¸çÞAõo§Ï}ÿÔÑ»…0°®Àô—\í§úcôÿñö¦A–d×yØ9çÞ›Ë{¯¶®ê}îÙ1 À` ARI\4I“´MR¤õÃáp8²8ì_ ;ì…WFHr0,ÑÚLË”LÒ ƒË`0kO÷ôLï[uumoͼyï=Ç?nfVVU÷Ì´wìüo¼{á•ñ#¦Á‚¨TØ2‚'ðÌH) N§¥”|öô¡õÉ·_¾ J?õì©“++q…ý¥K—¯Ü¿õÌsgífå'…IÄÎ)‚èi<±^}`Î }]•8&"@p&T ‘ú¹I59!@@“ÒmoÙ3§zÀV%‘„»¤ÓÞ3"Š­1ÞüEéç·4E‰QMxu?"l«`Ü Qq:H¡ˆÛUK j탘­N-îT *QI4Ö«µÅ¥Q‹­©;ÎïÐÝ}›DW[Û³¶-ˆjýx}Fi_´C !”ulF÷‰(Óê–.‘eH{³äH%qˤd_Š„è*W¢‘6ÉCûEèñI´¦Ê±øà»…‚#Ih÷÷À’J¸žÚ™ëQ"d‰ŠÛ˜] ÔXÄï¯ïßxÂC²•ö“ö?Xº¦ïDý+jbÝ=¯º’†Ú¨é{rC !(Uß Ü‚÷°˜Íƒ WUYU,iB]œ¼°³Ö’ZñIb*Ì^j5E”ˆÚÓÎø!£Éöko~Û)’Älg M’'žHA8°´<— ¶¯ßúÎWçüŸÿùtk+KõÓÏ?û#?ô¹';þÈÇ!÷ÖoÛbÓô}Þ猸d6FóÛ¯¿õê[—õ?úÛ¯žzãϾü¥ó_}ëè‰ù4×ó‹ Kål}s4F£É´ßcERZïƒ_>¼”æúòùõG;WYžÍ4&¨RØhò¿mTϘô½+wþúÏ=ñ¯\}ëͯ~ãöSÏÕ=È„ À£T •h<‡Õh} Ê¢ZX4=óĹ'Ž¢Àþ@ªV7×.¾s^»~øxŠÂÀ)ììÌHfLp•OØ $lg¶—¦I¼½‚g™ÒÄ0€sÁ³×©6s}ÊÓ~ži¯óT'µÆö–ÆR¶¾ñ4Å[½½ð|àDª4ï¥Êôj;»vÒ'Èqu Mêä8D€Æ-?Ƹí‘û"i±¼ÖQò*‰4RŒfp±¨q¨LlQã$ $£¥"qð‘4Â-% ÉÐ…¸—ØA½š…©NÑD”J€è«)’%*âÖwDšqjnS‰„Q“øÖRâK×Ò­.…БÕÙõÔ8‡ìF¨pW³‡zd<ó?dÚ-Ò­ïûkèÃrèö‚x‰;Àýÿµ>uQdiOQþÀªú>5pGÅ$"!ˆGiW*qý×1Ñâ]ÍÚK¶Î¸oת™  ÍŒk£‰jzGOÆ–øR«SvéXT™‚x_Åéžx2žlkðå?ýø}ßh{<0=†P$ô]½så׿råõ‹Û«ý<ÿâþø‹/½8¬wðÔÒ¶ ß(®9e³A9 «’@Ä ¢S0vZ½ýöÛï¿ÉÖ¼ø‰Ï?rìôŸ~é_¿÷ú ®2Ó;ë×îØ’zs‡i:) ÑÜ\ZU¥ø•AoéÚ{[w‘°Ÿr/3?óƒ^?ËËÊ­—SÊ·îo- ’ïÿ‘'ïÝ*ßøÎÍl^9;gäJO™@ÐL ï‡e1­n_½¿që©'ûÄ‹ÏTF~Rgýø¹$UÎßÝß8rh>]RI/ETU%s^iBìªT%!ðpÄé¼6Ú(!DT‚γ00CY:õL™‚¹•#ÁϲDiIBÚP-Œ]€Ö*®¹{™êKD¥S·UQ¤wÖ”H"¬H+™d3c¢ÏwcW¬£F³ b LÚeÝ×F ã;ªÝæÅõˆì×$¦Û•56ûíÀ—xöѹÎA²¡š*ƒÑ,•Tà"ÂH-Ó¾½þI'1ƒ‘"%€Ùy?kL›¼4«-­$®D»›Gi2Üwº~Ü©­„]¿%ˆ¤ÝˆìGåR·÷DÜwç6c(!hMa÷®³nÉÛÉvx,ÐU1|ïà{—ÌÔÒWÛ‰¾{ÙDí<<$×óatÑý”þ¿<ç)¢@;ÓAû*Ûþÿkˆ=/±±¸ï\À3HkQSß!5@T[š²&¦F®÷P²ãÇŒ( m H“š,1Í.x[¹*xñµ&¥l’äãét{ºù_ý7¿ywuÍÌ]žÍf…+UïÈro0xãÆ½ë—®ƒõÇÿÙçg?ö‰§8Ø[H·¦÷îL®•É4(ˉ‰/ª*è)Å윺yåÎ¥ o$ùÜ­»¯-.:xzðC?ýÒ¹'.¼qþÖêdbݵ+×Ë¡]˜øÊÚ‘VIêÇ.O²Ñ:O†¶· ÒA ! €J’TœëyG%•àÅKw>ýýÏn¯«þO¾tåü­¹ùGx˜”%IQ˜¤BœØaaÇvmmxåæ|¾wòɣܫÆãÑÌÏ\–bQ–§Ïæýþ¡w^¹¹zw«›¬¯Ì¥yb*¤àY€SDã_1x@fÜ,°"šŸlÏʲ H` ‹šó~Âè)­<š¾ÖDˆYBi¢h÷¼Xw ‡T\ð9Ï>HLìÉB„,Ÿ_.¢¡mb]9jG`“) MM)Á¡Ò)³ ×@ì*—j5jRIsÕÔúÔ6H®æC£† DZTÑ´c)Ý•âÿÖd~e„C­YñÕš‹T Žó‹Šx$âàH³#჊£7I%€ÑÁ8X[…ÀÒ€v]”¸üm0¢ý;K÷g:âÃÞQFÉï|j-Í!zî¶eÚ-‡Øò±?÷Y²ÞÙêî°¦ö!KËýÊ¥÷A=°ñ|ØFB#êT¼A`_ ÝcEUJ ñ kúÐvƒ‰µ Mê8¼ZB-à$ÓîPò>&ßÅ9Lb+ýë;ÁŠ;pi4L ¾t¾òŽkóT…J©ÑltåîÝ×Þº¸q?Œ¶Ô7÷»JëÉpÃ$ Œa„ñdôijO¿ô“Ÿÿä‹/{äÊÝýâ”ò"Ð  @°@ñÑ®ªÂÔ’Ôì•osõîµúé4½{Õí»8XJÏ|fñèsŸnç¹9ü•ÇŽýæßýG¯üÑ˧]9±p¦—ôî£òêÚêp£xégžš;†Û~êuÕc­A«ÊËD¥a‰½”Þ‘eÜÝ{ñ çß<~á­›7ßY?uæXžP.O9¡)3 gåжgwîÞÿî›7DÁŸ=AÔ:¯Îô+‹!TÞÙrª9×_H–oÝØ®ÁÖzYËù…,^ö¥bDN•¢åS×-@P E€”>(…̱å¬a DÈ Õú·rLŠ´J"lHu&(GO[Î!Ò4­¥°‡ˆÉÔˆSM}ÛiEo:A­Da҅£~)&nFê~«ÁôÌÈÙ„Ö·”ŒHhʃÌB ÌÍæIHĵ k¥Òz&eÒü›Ø8G…2b÷;º¬º•ƨÊ)&Uå B‡Å¹ŸÚJ9ƒìšÐcEÇ{yØÔX—?C±b²ìú7y7ìܪ÷”ãÜ—Âôþà{·E‹/›$ˆv3â»!òÝ_ùÊ¥þnêß÷º‘' %íé[Ì+¾giö)Hø/ C[EXÄ‹pMd@`ާQK×WmG@ Ò¡ 4I'¡²•Aj3ZœUöÂê[øÇo<þÄG~æ—åó—n¾÷n®_ ·˜ƒsÕd6áÇéoÿÚc/>­Œž†‘¯f8EÁ 3° !yñ!5ÀEYBpôÎ…kßúÆËóýüéçÏ„0™%Ø0© UÒ[ÌóÅÊí_û•_>ÿÕ ¯û›ÃíûëK65¹¨QY–£YyüÄÒG?}úÎmì)ÔdMÀU"™€E‰Q‚WÞ[;uäà§>uæ½ wo^ß<²rp¶]˜Llu]^w×ë\ëíý§\k§¶ìNHÞùº&Q½'©]6FSþüeœñþ¢¬ýßÑíòh¿½G¸Ê»iOM@H}HÆïúÐ&/Åˬ ì#-¾ö¼ñžãø·ˆ¹.Ô™ý™‘ sæo%òPK´ÀiZat:`ëüñ­¯}û;K§Nœ{þ) O¾ð{·¸´äÆ^6é¥Ë—þåïý™º €0¤Ñˆø2˜rÏ\Ð:hE€*`ߺùÞ¥ÛŸûkŸH5l¬®q®@p¾„ÒZ“’ÝÞ˜bæ,‰ÁÊU;oCPÄ(…eáÁÓê½Ññ³sÏE=¾íÆÌ©û6(¦ FÄ:Ð&®Ÿ°NË‘à}!JNY@+LÙÂQZo3æÈ† Ì샣ˆve õˆdj¾ !8Þ»åѵtyéð¹S÷ìPÕËçó¹,éÒP/í-›ÅþÆkׯ>²vó0€f gPZŽXˆ«X$€¯&,~<Év£ÉÍY6xî…3Û[ÃYUeÔ#¥ÃJ¡"6 æû[“Ûo|û­'|ä¹ÓGW¿{ã>öîLF³ÿåús(FöàÁ[8Ê•RàDÀ ¨:)]˜] ¢ˉ˜Þg_:»ugõÖõ»iO’¤7u+[[Ãõû«ÃíIááÌãnÝ.†“ÑÚÚ((`Á J¥#[¶Õö$oXQš'˜LØàÄy_:‚xd­(x¶–‰@ÌõŒWÎâhÆŠôÑÃG€+¥I+J éxv9†‘¥ÆA™"ÕYÛ]¶,«vîëåµd^™Ñè¤?bWl£ÒQÙ˜(  tÍe÷§ ½˜E$Öµ¶\*•4ÁÅ\{;ERÑ:$ íþ&6Âö[ÅÈmBRÑ»š£I+“‡j†È"Ld”ÉcÚnóë6:í6õBµøL»6õ¡ÖÅ¿uôìÝf°ÛKîró”hµ÷ìòDZõCw”ñW"?4tTßá-µÍS,7";KƒnƒÙ­G´*ÿ@t2Ž"B t[¦÷·¦oû Ãàßs Ý#Çj…a‰!-ì 6©èw·ÿeÅÛ•J›ôò@9Ai°ŬNPÄJQUymtšjšŽÂ"À;×ÍtHHD$ZÕèç*c-5‘\Œ§‘Ëw¯]Ü.0?rîñ*W C€±žOôâbZ oÙog̰„‚”™p™xPP‰­ t¼â Bp^¼…l¥ë/õ¿ñ'ο~áì£OŸ=ôî{ë˜`𠌞0+ KKƒ¥ñÆúÆÚ݃GŽV†à|ð• €¸5ݼ:¼¹U…aðGIçÈXUæIÖS¤€ {v£ÙpXŽ€ÁBå”x(+(-Ø}D*Ï%’ë;WÈÅ7îmlŒŸyþôÝ뛊0ÏR$cHØVÖ:WT4VùüÒ0ÜRÚe½"íÏfvÍ9ºrÃ~âÅgŽ?øî;÷öÀ ë÷¶5X“$•UÁÒ"Ä‹w5«eHW–×ïmŸ{dyóÙs.\º}m£×ƒàÇ£Éj@; _XÖ.,ʽӿqùþêÉâÒ\QÌœ Ž­'‘$Sa4 Âb4¸’5"ðÑñD|àÀLŒš”ç ¨¼÷l´V𕆢pD`+Øžø³§ŽÍ/,:;Õ3ѤÅêÐÂA3øD("¬S²Y¢×bb(K(Muî¥÷#»àfH&Ú}Eit䌄¶fÉJ§ ëµ{`Wét®6²SI¤²Sƒ>Å`w$¥tJ%Í.²U± .3xË¡ ¾é"‰â´¦sÚ1 Æd\öekã[]f-ß[a¼ógeHLÙ¢-,BÑQÚ¥5ª—¡²—q¹?:x ³Ûåí YGî`;Fho‡Øxðµ´}þ¸ˆ‹t÷˜uªÇÃíø3m‰óøþ*Ù­­;ä§Ýµ²ûš¦¿¨Äó¯°»qîJ¿ö?BÍkvžÑVZ¢t·ùTˆ/½ÿ–z¾U’¦ÐfÓ+$aƨ> q#QôÒâû‰iç!Z:·,B޹¡PSðZé}!&©)«êëßýú•éðЉǒ¹ Ò¾šcU?7¾r:8ÓO ‚0•+ƒ8 fcg…uä€RÅ ÁQØ(*ÁJ¬5÷Ë­áp4èõŽ_ÙXÝ^>¾¢HS øÊ*åÁåÌW^{íÕÌøÞbP½I¶P§n¦‡#ûùþáÿíïÿÓk×ú*‹5£–<¤"ŒHâ-ǘ‰‚€–4!_TëÅæòJÿäñ×/ß½yíŽJÔâsüìáå”8ë›tÞ>ùüÑ‹o¯]yw}q1Kz¥Vˆ)00C…X1H`Ï ¥ 01ë„z·'nZ„,“@å|ðdEŠPï‘ÀûPy<~xyåà²÷e¬¡ZQ½Ú¦öƃècŒÝ ³ã™¢yf¾ÓÅÄ*Vsì:NãÆ °®#FüL8&n2“k§if§ ¶¤„$ˆ ™dÀì£x”Ù'ù|[X‘LÝÏ6ëNáP»)×2PßXÛÔdGæ_[ì€HTÖ‡¦ŒÖ?Fº *çàAIy–h«ÜªÝ}„€pǦ~ÿôÚjPïüÀt—˜'hæ]-gÛ™vÅòwy¿ÅV”¨uÝåW¯ºee×ò¡- {üîBx@ª!F7÷.@¿çgö?þ½õ§íƹÅôv9cuUAÑNÀÄN÷0¼$ñ”vgÑö¡ïóI#FGHiØÔÛO¥aïØœ®Ü ïu¾nmå;)ä×â ™¥ÍÏ©ñ…·®^ø½?þÃS}>ŸŸWËs@dIRA1Èz}ì[¨ 0°sJO]Âý¹Ü•ÖÙ²â \•+R‚«‚uàráÀÀÕÔgƒdcmhg³A/ËÓÌTÄ•3kCÎU© P—Õâ¼¹|ñŽ&m özz:’ù¥Ì—xçÆÚ‹/}ò·ëõ›^úÂG4(ï‚°€ª]0â+z¸*2N&Ó*Ër[êápvê‘ùG=~ú‰ƒ˜”Z“€@qòÑC‡ŽÌ_y{õîÍí£§çU@"ñ¡˜8ò>pà”{®\Hf¶§®´¼0 cpj„˜”ïÙ6†ª ’4;zìh]C5MIBF“RˆûlÕ›‹J!^Rí%XVG!˜ŽYGÞ…ä™j#Eµ¢87tK-ì•ï5¡íòVO¨fvJ§ÂŒ¤8¸Pç>ö³qrW¦ß¤+¶Ü£ÊÛ¡GÙ%4©œ17úœ »‚Ù3»h1åí+;DTÑ ŠècÎRtÂ÷e¼If¥õ§½7s¸¥ÊGâg»Žìކ ·èô›ÝúØ-F{~µýnË´ÙÓl¶i‹y/¡‘5² °DZ¬ž!£D„£¾s ˜%àƒããw­VÓéÖã¸ûKqÀW wÞȦg[‹÷¯\Hoÿp]êƒ[Clt%±úå™­UüÃé®Ìc??§Îk­Uv{lº[ðUŒG®¹ ŠHkC£iHS Q)€!¬(q•wHÑÙ>:î@›"q7Ê >øëk×/L.<ùÂÇôü²^Ì\ÈsÌReŒ6àYfh^e*vPPÂ"2of[•(·‡¤)AÅÃ|k!'šg(‰¹smK+ Wtÿwº±u3šXDëZi#oëäaÌÕ6šªó"v½ù°Ûó‰D˜(¦, ’!ï#¡£í(%Öñ¸´ªMÌj2“jr¾ÂÎ×µº.:EKak<ùꥯ<ñ‰LÊ›·×§e1é-/&™! Œ jC$âÀ[%hH“&œnŽìh~<ç‹ÙÒÂ@ÊÒ9ï ³ Þ•^) •›N ±eJ¸¶ºÕŸëŸ;w €Ø´P€Àñ œ^»ua2:Ôר+Ƥ!¯¦2m÷çÒµµË?ÿ+?ðo|ëÛ_¿üÙOަV;Ë•$‰ñâ™zyB60B(g~:™ ·†ë³ÍÍɽ5G¤Žž\8rvàl¡Yã•>¹éöÖ¹ss¯/¥ë÷F[‡ÕƒšˆC$øà@'õ=XXÈlM½!Mk#·µÅ K´r@ÉÔ230VàE s`(+Y˜ï?rútE–ªØ„f©J4&†h·¦s7ýSºm{LÛ¼çÀuea„Pê.ÜE ª¼ˆïë šØŒ6œšÁ<^91°¾IjB"•ÄJ:È]VSUlˆ·£šæÑ$…Dm_ÄB|ùðQÐY‡…´—% Å„çz,uEtž„ŽéQ¤‚vËeh”EmHÏ~VüÃzÒýõ´-=mõiËeÛf6I¬;ÝOwƒ«3„ÀJ‘÷u¨Z”xÆæ4ÖJEÈ YX)”†·¥º{X©Õ fµnêTæ,¾¶_ÜX‘½Ä&†š>KP×Å*v¦{ò–[RêžbM߇ Ú5º¨¿Ž®ÕÝB·‘´ŽABø@ñ4^Î{È]T.Þ«Ï%ª؈DŸŒcøYm\ÖaMC£S’Vé‰õfµ æq^$„œsßxû[ƒ‡`~îîæÖ£ÇzKf2Û`UÍÁ<(Ö™JSPΕ₦Ô¥FÑxsk²še©Òãb¼=é)4\ùeQU.ˆ“ù¹ù­õÍ{7×W–“$)gNQœABÏ …òñõ;å¬è÷B5˜ÜÓËGÛ’.Lm1.gÓ…áæÏÿâGþáÿü]ãÍâÁþá“Ú0„Yš(2 öCÞ•Å´ØÚÞ½µµ¹m,¥<º|õ=/è‚ÞLô¼A%U"IUU9á°qìÈ‘Ã+½;[«·ü\tB¨8Ñ lYS—|똈<Ãx伇ã'ôÒ¼!CB\ÎüÔJ?¡,3eé†3 L+K ÇŽ%¥8¦†C©!­k·îœä­+{ü:€ž%ÚÅŽ¦ÍøÍR€-™éf¡Ýœê¸Š•Þ¤óˆÊd ©©¡„Hª±dò@Cû­zUÅŒåh*‹(u/Qö:î¸Ùxv,$H“W»óÂqaÃb+rln¬^ûúk/=óã÷¯o±ÓK”f•@¾€RÎC*@PlC€‚ÑâÖúÖ­‹7Vúú@ßï€c1  0—Î`ð4ȳc'–o¾wMÕp<"¡Š›)ìwŒJ‘ê H=\01¤уVÔnù˜Es|5u4š*f¢º˜61;Ä€=K‰¶§n÷ªû›Çnê’¢æ´òþMè~¿®H©µ¥w„0-|ç‚"âv×}š=u·µî—t«;âÓ­Z²Ùj<›'ÖÅÛf¢ŽlW¢Ø¥GÏ´Z·m%EA‘¹rë»7Vßzúù[ê ÇÅìd¬ç3`[”xV>¨ -+qeåm±dáâÅ‹>úÈÉC'ß»réÛòÖ틎í=¼pøÐbš«­éD ö˜¢¥uxëõ+ëwï8uÔ{ï]åY´AáàH`¯Àéà$_:ØÜŽ·§“áâÒÜt6&·eMª§#I´±ÁæÔÏý»ŸùÖ7Îo¬ßÓj P(IÌØUÎûûë“Û«k¤øäéù§Ÿ=|øÔˆ—ö´JUéÃdjS€„”T:ØBÕ¦[@Èiòøãƒûë³[wm>§²,©‚çÀ©!¥°ªÄ3ôrU¸0+‚187—úÓÂz†^?Ë23ž“Â/Í%G/ôò¥àfyJ‰¦$¡…¹Ì(i=/¢v¥—«X7c›Y“š£ŠWicLJJ·¤wi¬žÚô‰4?î6­3&,QL‹!•΢Ýrd˜Æž4îÐI¥¨¢·ŽFÒ¨ŒÑ¶iPQ˜I«^lÐVÀUžÞŽ¢ý]h0÷V,óÄZÎS|”áàÄÙ!F“‘è Ú2+£ÚYt\İ»zJ'a·]/¶Ä[Úm[׺‹ò÷à$ߘæuëT ‹@üìÚMhlÚ&4îIãæ”HXP X¤Èhä¦ëŒÃK$u5M˜g¥}c­ÅÞ« ® >@ƒßÒ¡¶èÜ3ï﯒m}Jä}8¤1P`]´‹Ý·Ž®EÞs`л”,{ºî.¾´ïydf}€ S=õaÓl ÷®ÑUÇT/&$ÜaGc¼Ô:ôÔqcJËRA@Ô6ðëþäÀË  ùâõwßûä>;<Ëú©—ÊÚHA¥fUð¹W„…+ØÍú!ù³/}ãø©ƒ¿ðÿäù×ÞúÊÿõò•K.mܹ}©×ë÷–VÒù¥,[îÍœ• çòþötëÆ»·Œ¡C‡ç³žÊÊÖòÕ$T!HY¤é`¦j<š•³1HÊj¥ÄW!OæËY僛$å©s+ó‹O¿ò5·~oóöÍ­~vøðñ´\½?ÏìÜœ~ö“‡{òð`A®|½éë$K|˜Ú<[¬K_±w¡4›Z†ÍsgŽl¯‡7/Þ_»²žï§À$E IB™I¬g¬¼ÖÚ˜tVØÀ0?ÈóÞÂh6áðr~úØÊ _â࣌B"L ¥uø hM,ÐË5dYKU妨 Š•NéœÈ 2Ò&°C놤k> €JúMŽk_ú:CcÀAÍÙ¨Ml…tZó;Ûžšò©È"{«tw©ÑOس¯£>êÌD$fÙ£m*gV$°·ñerR£WÙ!x®@ªãLb/Q RD*M4¨:ë[ÂdÂ,qÚ¿uÝí`91†vì 8ÚSIˆ>u·Ì»œ–Õ¥SÑT¿D}ïÅvŽ] §;´$£‰Iˆ˜½‡hKªÖ¤!¢Z§„µ+Rfwè¥Ýò»3ë÷ëëC÷/1öƒKñ]?Øÿ>4²èkû²©ëóL$ ¢ÄO3Ôë­AïïÛÒ¾ç¸ØoUK»xÿ:¼1 EЇ¤‘ÚŠãLßx†‚RdLF*ERPÓšY@@ˆT¤µJã‘#ÌôíÕ—ïóH-?·Ñ[|ÛÝ_zìøínÿÛÿÖßüâJ:¿±5ÒƒJ%II× ÐŸÛÞ¹¡&0¯¿õÊx²vò©Ç_û;ÇÏ.þ­ÿìo^:óÎ[·ß{ëîêÝ{·o­­mèäzO%8·”ºÒÏrç¼÷ ♌ö ÑÍ7°Â TQ9z~É”ÞZ;›L²^ƪ—¦£át©'N*$ÐÞ]½ôî\/ýØS'ßMðîÚðÖÝñõ;~6øè Ÿ<»”÷Ñó•#¥æ4ƒÄàè>l]É–ôl˜1¸àËb:UÒD%ªiI³µ³gR„Þí;3»åú!SDI‹1è¼X†Å…’0- ÖÄ ®ŸçÁ͆[“ù^rîÔéÅ……ª“ÆÔPšÐ g²„òÞœ&§T=RDc·èË?ó$«OÄhö‹i›%C&­\»£DRÁ³¯f’At!‰ègí<²ûßéÚG6JsÛÔXé,ºÐGÍ%6† ‘̛ͽ©0’Fö,!ý®š¢°Õ,† ©Ú7TÑ‚ÄÙÄê±– µ"•Vvæ¬/¬íâ×ݪá;´›É±KG‹©¥Ë3íúÝá÷õ´+sbØ¥°l‡tê)>®Aã,—×Î1K]^gEØ_Õ!΢òQ"XÏŽÉCh‹i€ˆDÅï‚g­ ‚€…Øš%îù³´¥ð{³¶ûð~{ª¸Ti5KÝ=iL Ñð q¨ Oí"6„½ï¤ÝSì¡âï,Cºùh<Û‡h´#LRýt;VD ên‚ƒw68Š´JD¦¶ Ò•7Ö¿*s+áÈ'7{ƒÛûÂ󿼈¿ñŸÿwÿà¿ø_à‹_üØs7G}>§Ç²ÀŽ·ç‡›#Ø:tpåøŸ¿úv%››WÛ›÷×ïÞXXHYxáûÏ|ôcK›'G[Ó­ÕéÝ[íõÍ»†7ÞÏfUo`úIo¸UPlrQ Ž{ie¯Ÿ<³´5yvEQ.ôõt24:é鼚Nû3©fež„ÍûÛ=œ²ríÛ`”¥T}ªšVy–°÷EåÙËh8F­ÕæöÆÚú¤pœ (Íä©fÏÿ•Å¥sbÁ1bˆSž?…ÍqÕÏqn!+-ß_ßš›wýœ”˜Â{vŒì Càà‚%t§çΦUZã¤÷WýÒ2=¹X”UU…¬g¶G–-<óè²1ðÎå!°<÷‘§ççœdY/Ñ”&”¥:KU–&J ‚ARIÕ»Çw´ïDe"‰Z„&‰«. D†›ÔX¦N¬QmÇY‡Ç4«Òfõ{Rˆ‰óÁ]í‚5…®v&m¸PÐz‰ s¨B¨ê*ÙxR»Ð%5?µ¤q…Úf#c³ªÞƒ˾tøv–54Âô±€F};ÈWŽKË›`ËùßþF÷<ûŸøü/ýÐKÅïÿñ¿¸pa‡tùOˆÂ ‰AHˆQ4Pm¢Ð(¼C,Òb|`™‹´Öï- î{SÓ·‹ÑPóƒvIÚµu\¹ î‡1\ vxÚ¿}ŸC û2xD„PF`IÈÔŽdµ9“°pHÊC@Òe$"BD­Î¯ÙP$ EhËjzíö ,:xbùÈñ;¯^ž«üðÒ­û·>þÜÿí?ø¯ÿàwþèŸÿãöÊ7_]ùí?{ò³‡ì—>³¼´¼vkýÐÉcü»_LƇ¯TEÉÄ9¯4‰‡íÍÙd8›-äYªÅ³2ø_8sö±•[·×¼° >€6Êp%Žkbi„$•Fÿ¿ Rð00ÉÊ|ãþ çiÒKÓéÔÏÚ°wH zÙlb76†·®o;'O=wR§ÅÆúðÈñƒ½9]< ³"^BvVeó.Ï€ËYUpDÁ2{@!­@B`ÏQá+œ œmô Ÿ^½½}ç¶?q"?s"W ïoÍV¤ÎÛÀî ß÷¤·îwÿŸ+ƒ¾~á“Ïçy?¸Qš˜<ï§ e fY’&Jk¥µfÉÊäØ(Çu2Ã6ÚrÖ†F“¤,‘‰Yžë`¬Â109ækFˆÈ "©´5!€"5¦ŸÔ.Ck)éè€INm}DÄN x;Ú€ú2FÔu6Šˆ›5Þ m‹à˜³Ã¬04éLR—cëÝ4Z@ùše)!H4j™ëEýUkÀ{V{ÎKôè® QaÍ— šÀ¥ý#k3Xßkñ–ÚGÔßã'ÒšÝyÏ.Èþ,ãó:Ïw«RüÉ=þ̹ŸðÞW N’ü§þÚ¯þÄfÿçü“wß@ó¥)¦,܆ÇDò“ÖŠö×Éî×qýÿö_ä¡Ãµj{Êól¨Iø… ­Ï!èý•qO°ÒþÚú!N¬%Ï*EÒµIBí3†éM"1bA£(WïÂÐD~(‚ &ñ†ˆ"ÂÃÙ­‹wÂÖìØíó·V쟪ž ™z ß}åõ“KG~ü_:õôàå?üÎù7/¼ü¥×Îõú§?õÄ_ýÑç•Ýüî—_Q)׆ !Í8€0(ÈúÙÜRÌ ÀIľ o]^MÓ¼¿0·=ç#àCU™Ô¤ U¡BÐ ¼B2¤4`ñàÁWI€詳G¾uÿºÈt²µ9î ’~ž¦CXœOîÜÚ¼ti«¬ÜÊAõùÏ=}ìôÑÿñï}SuøØ¢ÒÖ[àÅz €Á¶ Ktä—–9Ëi2t³I´âDM„Á‡ 8€h@£(Ï5Ì {íšÝÚö'Ž^xö”èòõó7s´5²i Ï~dñÎêæëoo,/ÏúSŸDŸæ}c(Ͳ<Õ½5ñ’›x‡=4ʈDx6ªcƒ«¡—Æ‚r<|8Ë’ý Q–ZâYoB½tkh\ Ä5hb+^uűcù¯ÿò¯sP¥-AD)"¤ØïXk³,ýÅŸþµÊÍþñoÿ£7f ð ¤`„ŠÑ>"øÔŠ…B`ErÙú’ÂÙEþå›Ó‡UçØ{vë^<ÆZˆI2î[jKí­ßÇeo¿àìÃüd³%Œ>7Ed?)D [¦j”›_Ûè6çsö6`ÍèwÖ‡W¯¼œ N{ôs_ýò¿|û_ýÞÑOY|v\§ÙÌ]ŸÞ¹ðæ•cG~ê×>ù‘óK³5ùöŸ\ýú—¾ùõß{£ŸêÑpúÜ=5ŽzƒLc’Í'¾’àµÑ\NJ0?È“E5Üœ<’=½´ñÆýI9ÌõˆAš•wÕü E$¥€ ˆ+âÝdè‚÷'Í_šËÖÖ'‹s“à|°8ž”if†Ãé×þôîpÛž=·ôÑçN}¦ÿÙïüKÿ÷æå«Å`Ð+l9ÜšåiƒxàY¼¯Š¡JÆv²²’..šû÷ìhCÒƒh' Šô gÄ– ôzxË޻㴢>}xeqñþF9œ¬k¥&¡³gÒiY¼üòú£çŽ=ÿ±O1 e’ &Hêçy–R–&F©º€’ÎÚd0é|wl¯F%µ‰*ªæ„n~&ÎàP©võÙÎïuhûö\í š’ÒˆIÕhã}Ñ$ƒ»Û¸Jª!x Á"\³DÙGYOmqyNqq_/ëÝ.ûÆ\9ÚåÅçöñÙE‚°FR1BJ$X;­i1ûÄ)ÄÀ²s¶}«EÄ3{c’#@— õþt-å¾kDßZÄZ9ÞÓ‡ºÎ€?™ù ±/¾¸üùÏþ{³™/‹©sžÓ,ÑŠœ•uˆˆ™øàE’_úÙ_·vô[ÿÇoݹS$HËÆO‘±(Œã|—¹ßÊóuæßhOºkªÆ]öNûåL;î¹ÁаÖëí&<½ÿkna¨Vñ0ˆÉV¡a<Ô$ ¥ÑeiBJ5ìA@@E¤CpιVîŠJÕ‡5 ŒV¤tõÞ¥—¯m<öÉÓ••/üä¸Ùí«öêÆÆõ‰]î«CHf2.Uâ¯ßº|ëÖh6=zîçÿæÇ¿ï…'ß~óλ/&S_Î ,)W”i’¦¹¤+ë‹¢ .q9ÓaYZ×/g'N§Wßõ£Í¹^bKÖÍÏ ô ¥5† 1V^À%!QýbZ”6¤ :rxm£¼µºqä芤´5ß¾¼qÍ­Âþ«O|úûN.ÌçÁðÚ¨zëÍ!{X:J +('.UÁϬŸdë Çη›(—Íçù}o½eÌÖY®§É(²…Ëslåàp«<~ÛV|èpzìàâ\?ÛšmN&•äù¹|~ Æ9aò©?vöÜ3ål+K{&OµÂ4¡4QynR£Ò4Õ&V¨$®#›8:!A+(Šåµ®’¤YíŒÌ5ÿI«^lú]ÕÀQW¿ÑAdºR%$m’A»Ï‚d”É#”YP-  ¦ˆú’CÃâ]5öÑM™ƒ¬¦¸s54Wöíö íõ¡Þ8yÔ½m«Eb_[â×ÔÜÎÑVÁÄ|°k -§iÈ"u:©Åˆ×&Sñ+ͤã÷€ŠÓíѺF$]…Rôö‰lÐnêsƒ,Ýó%hø…Ÿ9}úÐÇ3ï|MN$âÀŽ%ñµQ,RÍl`é÷Ò<ŸûÕ_øµíâ»ÿì_|ûîz±( QÍ"$±î×Y°ñOÑ*ƒÞ/Üiz¶Ÿìùà æŽEÖ‡Ö=E¹voA`¶2v¹hm%ED£kI)B½;F¬vxÚCý06£ïWæãÒ]!uì£"v¯TÖÑ&Õw’IRNMš˜4ÐÇŽ  øÝ«_îT¤ ( Y¢™«²‚ƒ }öôÚ›÷‡áÀ’9~Ü,Î¥Yf†ãÉæx–Õ﫲ïü»W‹ÑˆþʧŸ;~ô_y>ȲT+0û½4It–åFSšG¥f …ØQïÆÊ…­]];{›¦ÙŽêumúºqŸ¡h„¬’^=¦ 3»šÒ„´Ã ª#é•®Q#¤º5nâæ[ߦȷ Á {_ƒ›Eë娇Bœë]Áq©,BÕ€]!ªB1Âñ;Æ­V¯fMƒp\bú›d'ODS£K‘%ÞݲÕ@yÍH’¸?UåKÄ{+Ç•‹nèµÃÞŽ®¦I[zؽ¹gÚ*廳<3DfhìC+ÇkÁÀø·þFbJÁü\æ=›Dk­„ÅùkQ)!5²oaá…üùÿàßáÎÖïþëß¼Q9V¤‹÷ŒZãžØzêÐþ¢cú‡ìO÷ÿØNVîRˆ±ìUlªÝûè8:„PŸ…1™1K³$‰¶Ö;Ïúÿ®»_—׺©ïõòx¶Þ·ˆÿ/koþ%Yvœ‡EÄ]Þ{™Y™U]ÕÕËtOÏ`öìpA"‚ H˜´˦e‰Ò‘múGÿ²-Y-š"-R‚E“)Q>¦¹ˆ2)‚€I„°‚³ôÌôôR{Væ[î½áîËWÙ5ƒe»Îœ>5UÝ•Y/óÅøâ[9©vÆZ5/k˜}7 þˆ¤ "1;ne5 ¨Þ<|vöèã/<°8`¼}ý굨qsÒ]tÆÂüøÞ¡³Ó“eÝF®*#cznïùI[]+·?öŸ}çOÿƒó…÷Gïxïã¾ðÕ¤@eXV@\‰A æÔÔ¢]Ayýòø…¯†0ï®<8[žvÎQvb°@Hê¼ePh>9Ʋ(êŽ[Úxåæ_ûôŸ>ÿB(O¾½zü;ó;;»£$õ½î(q<Ḡ;M3>™s·à½½ãK'ž¬ãEŒvN 0Åötɱ…)ˆ‘ÔÆ¸5M³ …:Æ–J묊VÆGf~Ò}õOº¶“·¾yzå´ ¨Ö휷¶d¹ŒwÓ¤r)W/î|÷ßoP”›²°Öf’•Î;ã½ñÎ HÎÏ5teždVHÙ0¶_‹¯Š©QI+—™LÓlÑkÝ8ÇpbNÄ\1êW+‘ëå¡}Û—òæÝØ ÉZWåê ¬ì{ßaæRXdk;5s› h–*åšuñYÐ#Ê"1¯¡86™rh\¹™ýîTYAR»èËbjG42tá©ñ>@ÍPöT2â3?&Ä3S¾-`¿Ö?×QŠ‚³hˆê&½FEóM:¸a¨’)˜3Á¾§ˆfåR®¡‰õwÆàÿØ_'ô"†È{·ªÝÙÚôH‰*CÌœ‹ˆµÆy‡HŸùÌÝ“EœŽ]ok)Ë@­9[E¯›x½öÉŸ/pC²Æë¦’¼¾óu­ Öí Ï™ã _LI‡g’O;$R^¼ÃÞiÑ^í9’ÓŸ³}c×bÑäKEaŒ±ˆD%Ià Ñ"‚®\ÊqEpQaDBã•C´w°ßÜK£ #r|º<Ü™ÒPhºzÿ`c²±±5«Ó½[ûÆAÓiâªrìL²bô`~òØ›/ÿ'Þû+?ÿ™È_yç·<)ÊÓYåªÂ:dê’ÔM d° \öô¸¾öÀÖc^~éù;Fy2T;Û(8…()&é8µË¦›/ì{ËgŸ=ìs/†ù\Ÿ~÷ôïyüê£ö›—eqÚµmkœ1#HˆZŸ.–y‘X»:&ÂV:iX£€FoXbà˜ˆ„¦“êòn#ϦhŠI·7 gàÙg篼šžxdüÄÙé¢kC*¼/—Š‘…÷ï¤mzÛSÛ¡ç.]¿ñæ”"@ðÞ´¥••¯ cå>Ôú‰JžTdNRŽßÈ%µ¥!' +×®³(CIm6É‚÷a›Ô/7É!ÙkDÔœ“h|>Ys«›mFs °‚ÉÛd\Þ˯ð*1ÔûÖ™Â"‹âóTž™ö),³ÃÓ ÞWeŽœ5 yïêýþD—Ä©EÄL&iÛ.Ã!ÊÎ…‘(ÚÇÞ˜yÕ×$ÖS>/[¼Þ¡ÙÐëì0ø*',‰Å;•´¨#³Þ°ü ¶LgÄ{СÍ54«3—~¨¡ù‹ù Ø“Î{úñ¿ñ·ˆl­1}.@H)/5‹¡¬'NY¡¤ªÖ"lšBœjø»ÿè'»+“ªð”•o9Áö6ÌxàêÂ×RŽDïKÜìík_¯4ýùC:ò,kµRô Fï{èû}ó ƒeÑ[W¹b*²"Úu‹”sõô\_<Ä‚~Óñ¸,!V.æCc’Ă֠µ.Sµ‡=©`wö’É(ê­åÁèÆû¯V{/µ_8>|yº[£½úòËËîèÖ›ŽŠÐžÞ¶å–3®K.v‚bÔÓ4` EkN?úýŽMø×¿úYî¾ðþ¾M ©Õå²ÐjâfU±¬›ÅAC†Œ·§Gµ%ó胗‹ãÃ#«2º`Û¦«Û9 ( ’.êúààdï œž€óþÚ#×/^Úúê­/¢‹O¼÷ƃoÝ^Móæ{ ã@NÚ® ýÈÒþ­x|·±H[DŒs&‚†Ô&JØ ŠJ—êEgà´,ü•]"(&n£²lëú _¹Ç"ï{×xsÃÔá`4±Ævó¹vIîíwÆÀ¾}»éº?þâñÝØmÖ'¯Vã™3jP $gBUN,IaÁÄ1f(†ŒS ¡íIçnãÁ¼£Ça$„ñ“,FêýdÉåŠ6t‘C$Ã]ïO¬bÊåRUrêgÎPÊÿ6û³²(7‰ÂºúÉplòV=Å¥J䨿­—R¬† ˜ÕJÙÞ‰¹C ² )ÙB8 RŠ U¶@Þ‘w„䬕ª\M‚„™TŸ/„!ô… ±—«ßwOê}9—¹òÞ¬cMË)Ŭ»}Ý€åuÛÐsórVЬ08ö¹¶&–ÜXåÿÝ“Žÿ›¿ù7‰§ˆ}¿ jú:k2S*?ñœw "ªà W–ÅaýG?ñ?üž1xµ¨¼£lÍ•íKú¨.„s|õ×®z䌥VL×ù°Üy.©ô\nè}p*êp´ô£ó ‘E\!Ô Iש£™4jqèš• Ñ*µTP‰0vóÁ¦.ûž'9½ÖtúµŒ¨oö‘TViK=üj3O‰Èˆï}iû¶Q "Ås /•H§þÞÑ|ö…?úÂK/=¿sÕ•#Û6]Ø;5)lmV¡ñûwæäÝŒ™q<®ŒI¥¾pÂ6´)$>Ü?ýÊúÃ}êúCÓŸýéßþå_øƒ÷¼ï¡k×w¼3ãiá *ËEºH!$^vc,Œ¹réÂóÏŸÞ|þÞÓO‡íMWú.4wïî,5O6ðÒ•êé7?T–[ùoýÿÝ?k÷ø¡·Oyê²ÌOZBmbQš6² Ø"Ä w^=Y.[àx\¦½ ˆR޲h"$ÕéÔq®M£ÂŨP•£^¼÷õç=P¼åéͦ]Í›7]ß8:YþÙ t°µ]¼÷vwG_ùÓ;‡Çæo» í|2‘.-yg¨,|YGÑûÂ9—eãÆUªÚ›t¬"ÚÉ q°àªpXféOf}ž™!X'ûVNÒ™ü €²Âͽ3‡uð5qȱò«Õ–pj ‚Ë??…EoP/D˜LÆß €"]¶3~” p!?€ð²çc‡@¹…·±AU95œÚ”xÿ¨+ 3l2S›¥*œ.ÓkïaCÀu“^ëç4(ë³P}<…Èί[Æio Çr¶'Îvs™†ùÚ-ÊÃi%‰éLÓ¹r_>›å›–èûãË»QŒ-"‘µ&×è$«#ÁP.Éyi–±Â“±ÖZóûô¿þúoÜÝônê\ŸÐE½aÈé¨ìƒÏ÷°ðRäèþ•µ¬™ÜÇC‚ûbÖ21Μ‡’•øŒÃOˆÀ ™AÁ ëúÌ›ºþdt¥[•µ÷ål¦Ä„²*îÁ¾–oÿÿýcYGg1}ˆÉ¬¶±Öb¢ÞåWË’p` hÈ ^ =*ª*·æÇzùÝ/Þ>Ü_´>MÒÝtRIe¡¥ãe³jE –MKšp²uµJ/Iê*;ŸVÉ{»X¦ù±]Ö ’ýãÏ~i÷âì¯ÿè·ýʯ|þ?ýüé“GO=ù Ôát¾LÂUULÆEi 9Û=:lºv%ŒÊâ]ï¹öÒKw_º{xëè¸ RwNw/•O¼íúöÕͲ*7ËKW/?0¹6ýú×;ËÛ¿ãñFBw|z¡€¢4ÝRæû‹î0„h ¨Ìárqûæ]I0š9,"jAˆ‘#¥@¨`À€U@Cu•éàôäùçïˆÊÛß\mÏÜýƒÉ¯_.Xº½£8Û€'Þ|ñÚµ‹‡‡Ë›¯ŽëEýÔOíݽµ³é7f…wê­xeaªª*‹¢(+kúJÆ.GùÏ\U‡Xã¾—M¹à g2U–Ï#¢uc‘¸jÅúñú4-ˆŒ=ð½‚S‘†x;ÖTY9gͧ°@@4T!öwI¯5’”O‘È„»ì`/W Lñ8¡ªÂ±Î‚ö_d|ìæ Û$ÓµËÜõtADÁYâ•ü<'dÀ*a­Ô½_ØÎ’³Î,ïZâPêĉe\Ù¡ª†˜óæü@mÕ074›g"%¢³ù!«cðmBB΢)^·‘$eÖ=î~äG®;[©$B’>¢g €±=*"Hèœéº$ýyiuÿøS?ñÒKõ®-FÞfC¼\C%D Ä!2öÜ–%ÚÞQJržó”t0½ÖZô¾øhÑ×6v|¿nnH‡žt8f†Ô“û\¢¥ÇgóêEJS~¸ìVfWÖZ³îðø:&}çtŸ÷uà«_ïuëoYºœjë5kQdÅb±ÆåÙ¿VÙ´Ì&Ÿ&§0eSŸ—1-÷OîÝ{ïG¾ëÞ+[/}é '{sÍ-NšÅÁñL–“É•æÖí‹r¶5%¤ÍíIlIEšE¼WVã­Áea_xáÞ…­O~ò[ÿàžûÒ—^l—í‡.FŨ(ôd¾Œ1‰ 28Ch 4ñöî‹]J4¸íiµ{yçÒÍË¡îAíƒ]þ¥ŸýíƒÃ£Ÿœì\™Þ=ܹ:k›E×AlÝiÀHX/£D%\ÜyuÏZ;Ûœ0GHjP¢‰ƒvŠŒÎ€÷d€P¡i‚"€söÞa÷ÂÍtm·xôMïÈòÈ+Šá•»‡{Ñ:xâ¡ÉÉióùßüÚî•§¾ó»>òÛ¿ùk˓ۓ‘ñŽœÃÂÓ¨*«ªp–Fã©3@¨¹Z© Çf)­ˆ¢Dfe;²¶ïWê«òjÈQïòi‘ g2¢jl†“Y³zFU†¿¾4ÎãöÐó"`¬ö>wˆ&'¬ÓéÉøØa¦÷ç¿™7BÜj´f%Ȫ¡ŽÝÑu¹¶†ÐÂʰ} ¬Ì5sG"Ð2¯Á#f±ÄltVCåuI<¹¹ƒ®ã VÍ¥5“¬û3!fßÏ8ƒÍ™/I~Úr¶hê;Ó 2äÿvh>ð‹Ï¼éGX’%‚l%š˜AUŠÂ"³ ^–¢À" P–¥bú;ÿðï-ñZUe×Qg‰ŠÂä>ÔÌVʽÝœÖAg5ëÒÏÞ¹y­t±u>l~nëäùoº3´^Ê©±{S¾ìh¼[Û®íót–ŒCcm¶é±¯[C7éüËœ#¬›B½®sª³^UsC€9D ɪr~Žª"Ì€ˆØ+üT9¬)2ÑÞ>Þçñ›¿þÜ 'ܤ—_‡¹™Íp¬‹z1nºškoy ‘ÿâoú’wÆ—NOuãÂÔ”%„çSê 5It&|±¬ÛÛwæ[[ÓùÑÑ|ïøéÇ/§¶ûÊ—o}íôæ;Óé8tÑL'ãEHÇÇ‹“eÛ4]SG@)Fv¶=y÷¯“²ÚÕMl€ÕZ;.}YlËlûbù;¿õ'q.W˜Y'VåôøÈú€ –Áƒ÷0ŠMJÇ Žºƒ»wæÎMfÓÇ{,Šá6²%`B…ì´=ñ%1«wæ'Géo©®]1†ÚéÕ[{G]„ÝíêÚ¥^\þþÿ½xÓ~ËûÞýÖoùa´Õbþ©«ÛeAÖ’s4*mU‚³bh¤Ï²D2’zR‘Šñ“<\g™9B®¤+Á;š3Rý@o2öŒLŠFû ^+ÂY¹”ë/§–ÈeQᘩïiEÌÌ(yŒ£þ3E©9ȤNËÕÓ l[“!$Ãb%äWIHÌ[#DZY41§F…{ݧªJdI9S>ß«eYÇe“ò8œW·ÃÝ;4w¹IÌѶyNìïÖ\J bM½*œA{™ú1ÊY›³*µ¹†æïw>Q–ÍèŸ:¬+rk<˜€ä*ß÷Ú³š­ç«]sãÆøCßö£¢<¸þ" d ¨z‘¾1$C"’“1ÖËðòßù»?ˆW‹*§ÃBk©p”½GséÌ(§3} ]¯øYA›Š¨¯kô7\ê!ª¿8÷Gxò7X•¯£¨q´ÉOu=ï3¯Årþà@Xhù½‘AÞ¢°ÃI/ÜÙAD|ÎZ”Yùõb"^»©GBÉ¡ƒ„Ö¬¼¾A•#"²¤¬°Î•ÞÑ9Ûô’í-ñ†·> å{UE€ÎœÞ¾{ëdïö•w>°¸ýœ)\èbsong´qvvÇñÕ} 2ºPj’ƒ{‡˜þ¬,fÏ}}¯ô¸µ™&•‰!¶ul‹—VMU˜¶i9Ahåð`ñø#×/LgŸÿÂ׿øï_- šmU¢éø8¦$ÖCQÙYuýêl:›ì^ݼxeÃvÞD%p•CKåtÜFŸÖ'{§Öã /ÜéZ€ºw^Ú›\$fáTÔ*€ÀrÎmµsde¾ŸNîå[Kc§`!j수@K⨄PZ4äAdïh‘R|ËÓ“Ë»cceQ×ϽT³Ê¸¢Ý ®°æËÏ/OåýßúÄãïþøhëq"ç‹Ò9Z6©p¾ôT¦ªŠÑhl-„Ü€rHÆ”Ì]Æ9ÖDŽ%£0@÷‹,.ðð^SIf²VÒ¸¼F–ˆ°R¦ DP…¤"q åg„4Kã{’üJŒ”E’rêµÙ; É*Ç\{ sÛ»D«"YM­hè¸RËa‘ÍÆ)´Çy™ÆÜ©H½\vQ29/¦&Fébo·®­ ÙÖkœÙ‘å"KC²NNÓÉÖœçjîðÓb”•òy+£…{¶|¯ %É*õ׺¯¶4j ”ltÏ ½§j$ûжï„öMoÿè_ú/™³Óc¯%B”­ø9IiuwKNJ¬†ð³Ÿÿ¹_ÿ»ÓÊn’·+;ÚŒŠA:\¯¡Ùc%û¹Óºž¹².u½Ïåoeß7ÔÐÕ[`-pøûë&ÍçP©OQÊp¯õÄ•óaDD í-©2 !+8•EO!Wa5”ÎBD¾}l?7¿v¢'êY0ÙU$7½UÚ<¤«JN'rÙE4g.!ÑŠ*AU_™¿üåýç?û{ŸÞ¼<¡ùöòöÍ+ßxâñ§ÿí¿ú?.$ÙôÉ%»e§{_™GnßúàÎÁ‚¿ò'ŸW‚æA3Û*ËÀÅÈ›ãÖ7ÝF¨OŽºS,ü¨ BGºt{wÂÉü`ÿèôå›pç|!no9¾à·/mïìlT»ÆnG_R9òÕæ„§å>qб! ZÕpÔ8[4Ë(šö—?ý‡G÷æÀm;úÊñ•«[æxï4‘óÎ-ÚvZ5ßz–âF㺛 ÔFˆÁŸ‚¦ÔEqžÆMÇ®ô$Ì»v‘¤…‡ÉÄÊËwëE›JïÊ1lÌ@_|ñx†î{>ü±+oÿXG¥u¶,¼sά ãU¥© c)¡, M²-Y]ù€'Wm G2…p'ÜåúJÍéˆ,f}=P؉œ¤n•n¹N wÆp0—]çW̓ö9ÛÂÂ-æ*Qó&#§³‘*gI{æK©$4I a1ű2lT•S=dyÆnž£=3¿•S+ˆà»(Ò³,5!Ä$mרCVRÆÎ†T>YÙâ‘@í‚T!¡É p/ÓYÇørBgþ]a+5<Äjý¢C,ÒÐ= þÇUiÑ;J« ¥<2ŸÍõ,ë « &}æ™ÙüñQ¦>­zc DPàÄ!&csÆ…È„HÆJˆÿü—úæÍå®-FÆæAÞZrýØŽ†p¨¡¹ÍEjåã‰kÇIï¨?¬Î†èÌ¡åwGÔuÛª×]Ê]í,À×u’D¨ˆ‘ÕfgcpQ'ï¨@Å*¼É4aM2 %´šœ%gɪ²ˆ¾1ot~S’©ô'gê•­\í{fÌ™HI’ô$me΢ºѳê¯æ×ÿô¥;J‘)º:ÀéâÈ”|éê…úôÎórgØœž‚_ºvU}µsqüø3ß½}G/í΋Žf*£ÊÀRYàDºù+u껆ꥀX †‹.=0¾ôÀ?-Çéå­­«'Á9´ÞªHsUÔ8’ ËºSÆ<ªÕíb9_p¤ƒ“î…g_îÑ”4@±Ù»3/=  ²ŸœÜ­çó&Emk9ÞOEE³ Ó´ñ¤ÞѸ„ñFS7®la‘@™¥n“3–”àÊåb4‡ ² >âÁlO¥(/ìÌöò;>GØ¥‡ØØ¿Õtuf²¬»£káôD|A ù6Pk™Ì¶ 0ãñl±h_<ýz5¦ñ•ÑøÆlvujKã&Æù¢äYÞ (8M)-çËnÙ¥eXœ¶¡M)hj°^.OæõâÕÑÞ­–p…»ûup]4‡‡ãTeÁç'Ë®H0®ŠË—6ªkÅr¹X.Û¶ —¶‹Ùf ¨w†@¨OU5ªÄà‰™éÑIÝvݤ¢r,whJæó°*‘W"Ÿê©·¼o›¹eëeôë~ˆ|]»åsž­(¹ñW"‚¹CW=Ë5Ó.Hî¬35*&2Ôƒ§ÎRQøA„™ÍÆÈøû’Aß \žëCÏE+Ÿk¤…Sb!³ò?Ï̾Uc’ÅKf=ì›Èç͆‚d¶Œ¯ì\ܧpxx{/ž¤–½»‰U7ö•_ÎOÛ¶Vî0ÈÄNÛÓvZ¸¼}zÚ¨­§j'^¸¸q\û ´¬ ªr `vv/<ÿì~Ç2žºÉfi¼aa›½=8¢2´'íͯîݺy÷ÞþIÛ†¢€`yHvëbõÈ×¾j_|ùëÇGóÛ·ïïml@Œ±.a:uâ-]¾6 $rÖât2IRÅ®³ªÌL–XRRP©¬)K¯œN›Br’µÇËæðdéP.oû+—]âîàØ>üä‡~æã€ÎYS”…·Î¶(ËÒ»jTJ[DH’:×OßgL‰±iÊž-O´ª’+6…ŠpHY¸Ê$¾oÄÊOÌŽJ¢+âT®kYÞ.©ãÔfenT´çÌ÷1œ13ÞóÏ5+·Cr/"± d’5¶Ì=rÍÐ.pLƒí|Ƈy²oqÞ,äèëìn'C]LYz»å|ïYƒY*úúa’ñ¾õÁöœã²1Øv¼þ-k@‰ ±ZƒyÀ_ù{’Éys+¹z 2«uÅ`“T…±7Ô6ûüK¿ôrQüý'žØøø‡?éÜXDD Xcœ3!0üÞ~îw~go‡ŠQÙòÃošç"t³ˆk}¢Ïmòúþ}€D×¾áªÖ€öèÇPvR’³Rs«ü×õ ¹quóûÉ#ÑæŸþâOݼ¹¼ìªìΖËtÎÐ΃|^s… Q2àp¹|íÅT«K—öAæ?€¼¯¯çÉ‘¥ °ºnçð®g>™œ%çsXxïŠbTUEaœµEáœ5v…d9w6yXWåü"@$We±CŸFG6Tö$ã\5˜(gbïªÚÒjOù¼ìy´+V|n9,²QH.¦Â)/å0ô˜D„¥‹½·[i‡ð~öß™—G¾iË”^¬ Ö1¶P-ˆWDÔì}dh3%öíí`ù>TðõqPÑ “ã€xÞ·î \Ñ’( |ïŒWž­§îKÅÈ?3/µ†ïÂÚ.ë¼Ðsõ­|ó…ÉM X  I²ùüJ, Œ›Ïž¬aÍ´§®c³’cÂKR ©ÌáÙÏž~îs‡Îý£‹‹Ç›|ùËóƒƒnCîä²I…'QQkHHµCqy_Ç43¥!c×üÎ9Ÿ6¬çªÍzŠÔб®×èõ~Nä<9hE3]¬i9÷‚¢Ýuœa™lBNˆ‘Õôi ¢Xƒv%çC2®¯¡½#=Ûô÷:Ú¿6ãôŒ©@]1¸öªâjlŽ …ÞšÏ0ÓÕçÏ?w¯u›m8JéüÃ×gæä°‹cäH©[wÎ-ÁÉd«º°=« —!<"¨OReN‰³Â¯í’!ð¡#Ià:霋“‘DWÌTÙ˜RW &‘Ec•­ ›W;ÕͰDí-@R›Mà™[å¨ÊÌ!³”†šÂ’cb­Û6„˜;"ªMËë#[û4Ê®ã[±QÆc[tÆ7L*AÛVàZQMF– O,à‰$)(C€˜š²%!¤6pÛqv)€6ÈPì]JýûýÁpëtëÈCe\ÙÂçÛ²†=ÿ«¡:¬‡yœEó)ÒåeˆúæYØÆbx fuÎX€$}=µ u{–;Ÿ hoða!Ä~¥&¢†À±@å¨ Ì¤,šm*UacâVMØô0zgcæ|r!$Y=1`Qd陳¢ÃiEº:+ ¹ýL÷÷§¯ë䔯aÆdjŸM p{Û_ºPl]ð—/—»߉`ªÊ“qª½í˜° ¢ó6±´]ܹ¸á¬ ±ùã¯þÒWÿdþò+Í~Ý!âE.8oAX *ÈzcV›±LiŠI !§³œŽ ?úêB6½µþ&týhH¦ÙÈk ß¯d^:ì"­já> ²§ß÷T§ŒeërU¯Ýzîù»ÍOŒulïÅ[¯œ¼x²¸mG®,6Ç2š=`ýxÿx:žÍvKw\Ý[„.Ü[v–Ø8¦P›¦…Í튌îÝYÔ½¤Â5Ð0GC` •DÅÔ]ÙžíîÌ@a>6¡ÍžÎëzíÆxri[@Rà)ffT±ÖH"á[/„†Ôq'0ˆp’8„ŽRå­HRk@T$D ê:ae²†¡q`-g·$Öº ]RkdgÆ“¢^êîßöèc_¸¢°Eá|áFeQEQ8ï¬s}œ®$ƒD8»ñÈÎ&θ*gɉÄb| @Èà ˆÆV`ËËwãFÂqÅUɲ˜_¯žœ¤ÙÇ3dR¤¸äXçmRìN…Û¦ 1ɲI!JŒ’ Yúb¢ìA—’U•ÙØryæòSÿEP¢¡³&«€9·¿ùxïÅ—–m+7ªQ.d1‘¨à¦Ek(Äåd».µAÚŽC”ºåÜ–o׺Më¨å0ÝzÍa}œÅ6¹ˆtAN(Ádâ®?6ºö@ùë¿q÷ªT‰•HâÎ4°gÔ@}íR’ÝÝòúÕÉhdÞõΧ§Å[T$„Ô´AX¬5]Uá¸ûÝOzÿÕW›|ççê&ª)¡w䔄r­$÷6….áȸ’º7+`úpUˆI²Ñr.|ƒ@b]Ô)O£²¿Ácê ^ëÄÕ”4¥ûx¯ƒG_Ž~BÄ¡ýqããÂÙM9q©®a¥fÙ‚ªµFœåÄØÄĘb4„†ü;žøäÛÓ¶ëDÚûÙñì³§Ý1oL9j'î ¡k¬^"BPEcWýD’Ô‚*¹Ê~Ó>tÝ”ý»ƒ3JÓq–@ :2³ShPÔ>™.ïx¡7ãê~óâžY^ìNÆ»W¤&¾tp÷¥›êåbo2Þ7'›ÓÓý}oƒwºµQÎ`ëtÑ.òÆt\·]âW®Žn\Ÿ-ê6.Ú““è%Ú„­‚óU5rãÊ•¥©JôŽöOO¸ûÉ”BÇ&‰“?•:µËæ@•BSdà$Êb5ˆœ˜#ƒ‚qHH(SPU`ÉŒXÈ„–­5$…*drd„*µdD•ÌYˆ1¥ÄQÄYšÍ`:wãÆûŸ|úcÌ\V•w®,‹²,'“ ï¬ó¾,+k}¶1P$ €“‘½0óÓ‰WÖ•›¾Úråf†Ì‹ÑvOŸù6©uãÌôÌÌvÄœ-Ì«Déwô½%¨Ä¾ åNR—›PŽMìNRXv]·¬Sž©ë–ÛŽ_<­ƒ "llØéÔílù­-éÒħo /^Üʶ HÚˆ*’”A€‹ªµöÂø{?úAc üéË¿ôû¿¿ó Þ±~³ò£ÊˆhYï¨ ”{±ºál&ß´Ütú]ÿé[ßú/ÿÅO½²žd%ŠÙ½ß­ûs—YgS/¡9vyÑX?~#k’s¬¦! uøúº!ÂýF¥Ù‹ ³$ôLšãé{2©ôªQB›ËnKí•ëÏÜ].íȾ|óϾþìçëEÃI›òÄËÞ‰ïvfÛ¸zxûÏš®cŒÝI½ƒÖŽ'a©AÅ» S,¬Ž6:SÁ½ƒc"¸¾;ÚY:Uw§±B†Õ´‰ ‚,Ú4:-uÐŨŤ‚ Rq},‹½…1ÄITÈfÆ@à¹-•”Dò97Ù‰ t\x"4]””Ä;gÈ"¹Œ/eû‰’ºØž¢¤Ð1Cb†k—Š‹;ÕÑ|¾lý3oÿðƒ<¥à‹²(ÊÂÛñh4žL¼sÞkQ¥efP‰YBFdË”ÞlLJë7¬Ÿ8?µ~r–5¿’CœSD$gÝ83~sߺò´—òÚÛÅK?ÈHh N ‡:†y×.— ×Mê‚|îö!xO»»åûÞ~áñëõ®4Ɖ"ˆ !s 1¥Ó:†.:Tá$1#¢14{Lˆ9A°7.ýà‚yûï~õ_õOOoÄqU–Þ˜Á³’¥ Ü´<_¦ãÓî²ÄŠHĸ¾Þ]¸³{x2qÓ‹vwVîîú·!â•Êï|÷o~ôã*þ`ù¾Ö®h"³!tïÍ’V2¤!³d@Erƒ“œ¦Ø¢]¼R¼ó±Ío{ç'¬±1ñrÙzW4 âÆFÀmˆÌR¨5Ù3EÄyKØ{!€õÖB@cÖ<ý ÇÔ0‹ˆ @ )¿¯¬1‘ÛO}ꥱ±y{F&SëÑt×ý ²í¡(/±ôAº(…#ƒý¦¼úõµWfó®VYyК•co¾™Ò„ ÜU€fïéõ o¶ €”–Ⱦ³êOnߺõ¹çŽïÎv¦¯îÞ|þæÁK·hWGn{!~ksc:Ý:=:—lYnÏO”\”"/–@MXU×qR"Ÿ kŒM×rB#ä:†Ð²!°Š™u¹lUpÒRx † ¤”R^ÔQæÙü©P¦<« ¨·` 8`†˜´ C^„c„ÂùÒ™$T{-Pâ Æ0»$‘e:±»ÛÅdâ|A~ãÂC~è¡G¾ŠbTFޤ(LY¹¢ðeYZctźí=çW^ËY×[C€õ6Ì«$Ì@O:´¶Œ:ón•“HT‰<쑆›),꺙/ãé"þûý“ÉÄ~Ë·\x×3ŸP1Yèh-d?‘ÞúS3<ˆØ48oEÄer;õ67¹¿“d™rÕÙoûä'¾ãk/üÒoýÖÝ-v©˜/c•LLd å0ךqe?ñÉg |{+_8]œ«,ÞÓåͨ"¨ú¢B°9f.13'–ò°i­ÉžrDP–&‹ bvi;ÉÙ9ÚÚõ_¿ã›W·¾Ð….ÅBL…wƘ¦^XCÎyÈ@jbðÎQJÌ,„èÍó­É¤MÞM>ùƒÿÅg¾ðÏçwö¤†Q•i…½¢4qoz’•”Ë&5÷óOßà£q)ß·£‘ÝÜt×wGï|çæÅÉGŒ)A•P—m·¬ÛuæÁÓþ¬_ÁÙŽoy¥YÈ%¾ëø£÷ôàã~ä‰ ÷­U5J‰§”„™ì²îbHÞ[BrÎøÂþù¯•(kö“;÷¾²®<\~ögÿég`cl3÷ÃY´+öºöµð(Â>¦‰`¸¤‰ÅZc¿Q+šwŽëʪ7~D¥$MYT¬«mÒJßµŸÛ;¦³(#™B…¡ ÝéþÞ|ïö…éìégÞ:šNŽ÷æ¯îÝ ã;õ¼IÇPy³{ùÒÑí{‹vQ*µ‹šœõQ8.Ù†’Â9RÏ ´ RÝ5‹&úr,Ê¡€*‚Rx‰$„ÕæH$Ë™½3›3KˆË¥„V@XA5Cù¹oc‹ žÄ8 ˆÄ „¨ê)À„˜T€œ3¤,á”i}áRb@m˜‹Š­-Ÿ’,—úèS}葉sTÖ§“IUx_xkEÓ*ÖM‡¬Já¨ÐU¥WÉRé·yò«cr¨9ã*°~¢ÂÔ¯•24åÛë5ATbŠMÎØPIœš\Cc7ÝÉböÂçïÍfîc»ryóœu,‘9‚‚±`•…û….fGËl”B2† oAûs!ÒìË™“{Sk ³°ˆ1øîgþÊS¾ò?õ‹5¦«±bÖ.Pá©*Mݰ5dHöñÓŸyþ/¼ÿÛ'æÛ'›BdDäô´©FÅÎÎtqZg3܆Ø:kY„ú,OUa!BcÈZõJyë°ÍÕávhœ£GߺñÔS_ùˆAoŒÏŽ¥!vͲiÚÀ,£Q1ž¸²°,â½cæ¦ Ø·uÔçЉ D"a¾ÿZµø¶Ç>±³ó¿ÿÂ/¼|5U„(¤]¶à,†(, ¢1IÓñGþÒåéÔÅ(ß”Ë8™íé{-n•ÎZamCaÕbÔ¶ ]'îë™ÖD™ôš“!|tÏæ’ÚÙ—n²a?ö]W¾ô=›³+°¤År!¬Î™”¤mÃp­&“²*ýÿÛkõ:ï+çK–ögþÉg¸ÓKE™kè`׿²è­F³gJjXÌêwOˆík hî+×RÞ †Rßóä²+g"…¤ÂÐë>e5*Â@uÂ>I\O¹EëÑïlM|èí×®¼©˜îL_{ôæ—žÝ{å =lM&ãQeÔeÙÎO—#ˆ5¦œ°ŒuÝÆÓÎYã=Ž7JÆ„&&M~LÛÌrÑw1AîëšE¼³Â ©(¨ðä ±H䑌Í:2U„Â’$Ь8³y2' $*€JÞxKÔçôIñŽˆT´Ë B†8qÛu£‘™m8²°XxðÑ>ôÈ¡(láµTfTo©ð†°Õ@é/lÖª«¬t“€k\úÕ ”·®6×P"׿L4çô/YÔî±7‘”•ï*)Å%‡§.×ÐÓEøüþq]§|äòÕ 'C(Ò…È1iå‰)}, fI²ªµV5eº ‹ƒµDÙµ †ˆóÞÈÒpQͧQâX¹þ«¿ñcÿãOþämß<€£<­+ë]ïÝ9û/}é¤(>õ÷ü@I‹EÓ¶áê•YÛ4„#'%çLˆiØ—fHØ̲œœ„GY©£úäSÓ[_i÷¹‹¬ïyÏöûßõ eD4™t]ºdiÛcÄ­­ÉhTxo­³bÛ†¶‹@9(0±|ÓkªDüÀÖ÷½ï}¿øû¿¿G½<‘…œ5„ 47CÎàïþîÞßþÏÿë|Þ¨ª³Ö:Ê".kIUCHÖš¦í2Å83ï%¥€= °nÚ81+ñ‚;Çz\qDà\€³ ñy©ÝØp?ò=×½úÂÐ4M½¬EÁ–YB—RúÿùZ{_ÙƒågæŸ|&F¹ZVy~Ï6©gÚ¼/Sdú¶¶.ÕüUµß(ûóÏÓ®G—äǦ>~+Š‚VOЈ͡çù&Gò9T2ትåŽ#¸¶³±Η‘M)îM—ùÒtãå›_‹Im ·6ÖXÚM¦*ÑŽœ3`K7-ÉZ^ìwVH“YÎ9P>⊠pQ=žÀát!1" CbŠ ¡±…Ï&5 ŒPªC^ ©ŠQƒ€ÙkKA£&bƒjÅ ›ùž ‰Õ·)BQHP 牉X”­!K]ˆ1&cLQXchT:kd²ý¶'ßö […³T”EU&Þ™²°„ÊÜÙ>ÓQ³0ÙÌ>§0ëaëAn‹‚h²2‘ˆŒYA¥ùUÍ™E™Ø¤Â9¾˜S-±áÔ…ö(…Åé"üÁê2?ô}Ÿ6D’AB‰ŠˆÖš²ˆƒ·öF‹rÞˆ‹´]c²Z{BaîCïrDEÌ2íÀ ‚ýÛíGÿûŸøÇ)NF6§~ñJ÷Yô¨|îsGŸúзÿUæ”"B$´Ö°ˆŠ:k²Wqæc®í^teýIªÚ†n4²Ç.o–ÿÉ||\\iÛÈc @hmVǧ.Ä”x²QM7*cŒ/œˆtm`–’ˆd»5FTÿ¼×Ê™ÒûßõÃÏ?ÿ¿ÜÞo®b…HŒØ´©(26HQecâ^Ù¯íÿú™¿ðU$©jÞ¢0³ˆCÞYæÄTDÅäÌÊšCšýF5E&CmËo°›ZE¥Bf¶ Áy"p'6Îч¿ûÒ;ŸùþÞÞôÙ²ìª\ÃÞûœ{ï{ùr®ª¬A¥’ÐT²#aaa30ÁÐ’@¦™1¸‘;ìhG÷‡þ:¢£;ìvƒ Hb²-JŒ02ÂFH¨,!µ&IU%Õœóî½çì½×ZýaísÞË”„GtGTddå«zyß¾÷¬½ÖúMl*"•s®@-üxVÓçªT‡ƒŸ}çuD—Ò"b‚®ãÙè/LÖ¨Elh&&GÝMNT'÷p›³?Gê&AûbtÖ‘&S}­ªyj@Õ˜ÝRE©ÅL˜#‡yè2_¡õ ÈÛMH£ã³^ñõo,é0¥Žȧ}—ìês"eHiGeØ®7«ŽOŸÛÀe(¤„¬ÅSÇ1GP…à ô»E‡ ¦H¹€)H…õ&W-DJcQP4ÄÚÀô†()€TõL&äò;„@h®*`bÊD  CL¹TU#cÕÊA€¡(c±QRÔÝÞN/àÒ}qufo°‡_øâï6…”0†.ÂjÕw1.W+&‡×]$&dž­Äè )Èmž fBœ˜;·Gj†ó ê §Gƒh1_žzÈGÕ:LDúAÊFÊv®¡yþúÞ^üöoüQ3hÞ£`ˆÝx’ÈÌüémr˰·1 +‹Šn·#³Ï1|™B ÌÇ)5Q"B´ã¸‘’Òò{¾çÒoýÖ3À2Er%~ŠÔ%‚ zwì?ò‘7o¾ó»¿õGC­äŠˆµHLD´ëûq,hàc¡/¬*ˆg7‘ŠŠ¨®Vüàƒ«|ËO aÉEJ13],ú’k­âG‹EwîünŒáèhËBPŠ ‡Æuýo9«"¦ðƒoúþöó¿âä$%CC P €Pôž´øà¯îú×_÷šÉ'¼0À jg/ú4æJŒ¿Tï͈‰s­°èÒÁA!<.7ÍØ˜ñ+…ŠÚzS÷¹¼êU§¿ù oíûNÕD2#j•ÿÿΊößþ‹¿Ôu|V32Aäú¯¡³ÉÜh»@ƒš´öóvæÒ­Cý šnÒš»î¹çÉeÆÉ´ŠŒ@ÜGÉD„¹ÿ®Ô±àx6[Ó'øZ‰tŠÎÒ¦ëSLq Ï<øÚ{‡­Ê°Z”’r>zþÆÁÕõÕË›8Ä@Ðçí`±Ä”­ô½–­+IÅ ¬( ¸áàòäZ+„@Ȭ`¨X”‹*ƒ#U¤&1Ru®«ˆKƪh` $àÄ$RÅÕExªÄŒÈF€Hbp8ªx|{Ô=†ÂtPG+YlÐòé^:«½¢Ó¾\±>ô·€A꺾ïº.®–‹¾ïR€•PkÙÖZ`bÆ#"#’i™I -äËåÀÌÇ…Î× D(ôÍ2†â1¡J%„ÄदJD²ÔAêVòºæ£2HÙå|ñê]wõßö·~Ô̼rÎcŒcl&fþ„ßꀾ%$L]‘q( šsE$@àÍ÷ïþ¨ˆø\Ù”(@L¯|ñ÷?öÊ_øô§÷_€+M“ VÍœ«7ôŸûÜÑ/^}ç›þî÷.O 1 CögÏà’«ó¾g›b/8p­âÕ'Äpnõ?þý @%b'i´±,ךbèúTk)Är®‹Eç–ôjJŠ`Ά¿ÂY€! ¦DUmçå/Ûýó¿8¼m]Øøäþ|$¸Ï–¿û¾çþå׾╠ÛYV]-»ÙƱô}óN‘Kq„ÚòXÌ,&þâ7!ÐÉ9W'iìñð~¢†>µÝtKþá·¾à¡{ÞRª0©U"üªgµ\-‚ª8àdÄfªÿ gÕõˆ¾ý]¿#ÕDLHL>È»³×ÜúžÔ%Ô_6æä¶aýËçÔŸ´;¼“Ѿ‰”¦¾WÊÆZÀƒÔš™ ÌDe0Ä)t#`c+¬íBxx¸¾|…!ŽRT¯ŽGOQêvN5¼¡0^yúéÃ¥ÝsÏéZqQÎÝ»¼q½®÷;QŠÀ–ÇR‚!3lÇ>Fæ¸=Üæ¬)!1Cd6th­¦¢fnÒ¨!@×ѲhP‚¨Œ •½ßQUTkÞ¦`jãXæXG'‡ªè c`¦ZkŒñ{¾í'>÷¹¾ÞÖeU\GHˆL¾Ñ£K¸¸ºù=üäO|ÍY|sˆRrué ›˜;8Š 8 ½jëUB`Uõ ˆVmñ¢H$"C®±O.ì™Ú0–ãÜõÉÔüIU°* €¥Šoîð¬TTÕbd@`Bc L±£ïü–¿÷©O¿ÓâÄðPªë”PЈ°Kt?.çwž áW_ýÒJng%˜±Ã1—\j`îR”ªˆXEÈs jfªUbä+WÆ ©sÖã1?‡Ð1¥™Ø4×ÐÓ§Óÿø÷ÿc§ªŒ S8Ê_~V8Öºy使|ó¦Ç Áï8õúW¿5ð¢ë¸J½ó³ Uñ—~í_ä¬wÇžb .Q`JÑËè±Ú8r³š'˜Ý';ÐcÕ©B~y“ÿwž}øë&z¾6 ùØR001ÇÕÌCäP½3RÍĽ4–¼­b¦í ¢£~3@ÌÙôp}óæÍƒˆ{g÷±Úz½³ÉRóáXŽ.îêppcgQIÇx*ïœ µ”õvÍØ1Ä¥zþtèv— iÌ4ÛÍ(¥Ô±ÀÙ3Ç èˆs5"X.¸ïB˜ôÅ @B§È`¦r¸=i&ˆÌF@H0f!€™‘Ä•®ò`ÖÀ”"'Š" ªf ´5Ï÷%Hövö¤†ðäMHçzÍK(uçº.¥”úÄ)X-yXÐX*2¢ˆ}Ünmöbê¦  ·Øpyº†Û†ÎÌ3l~1͆9Z•i‹jóZÀ°·x`ù7ßðÊS;½VجÆ\vwýN¢Eê4£j8«TÍÀl"i½éM—yäÉ®ºÜYE¡‹³4Eà‚t‡¥þÜÏÿÅÛÞö›÷}“°R#77 ÿuºìq>ÆšÛz›LŠf¶ÝŒªcX.»~‘˜è`½-¥v)ö}TÕ±H‡a=<Ípš¹!*|Õ³Bo½­õ7^>DUDÑlµÚÛÛ‹ÃZNÅè @! ?¿s4[4º+ö¿ýÛÏ>üâuà%˜;y3"‚º¥€A!"‚ˆ kõM*z6½…qTXÌ3èqAqn“×Ð*­†îîÆü“o#N5gs<䫞U—VË•Hýß}çÇ>vÃU°Þb¿ÿ™çÿ?üÌ,ßú¦ïN|7s$¼ƒ³bŠ1üê{þÙg‡{ûv‘<¾Ô[Q_Pø•c$³ã­Åm)„'ýeæ N&ˆœ—TMÁ¾R+:×Mw6½½ÈÊ`êIŸ¦R&5"äÐs\õμ°ËÃÑõ2’î$>;\O7žöN…›ÃµØƒT¸|å ;{ç_ô¢×&ÞýÈç?øÄ•gîºgA0”õÁ0ânJœGTCJªSàÀag'ö]•rå®H-|¢ ¦„Æ)±Rl[ªˆ&tQY•¦NcVBH Í€üÚÑ\•˜"RÇ+ ‰"ºÛژ݇¦r”>¢T]îÒ™3¨Iž9ª§Nßÿª×¿e±¸Ð¥RXôi¹\­vwÝ"¥ÈÁíаñä[6Ä€ñFÚM1]{®Jrˆ¯…OÅñ± )½í“Õ#=dtPê R¼ ÍÃãáã×nƒüè[ ˆ@„ˆ<LUgš€:49Â!¢á{ßÿ ŸûÜхؽ`é«^¨UK¶Ï~âèŸø£½½G¿áοìÁï;:ÚŽ¹Žë1Ž)ªÚ˜ –\™)¥è•‡m¨Z ­Þõæ½½±­¬Á¥~•Zl@#–ì®máç~î/þá?|ïÝ{oAUU}]àÍgiSm•¢Óñ¢©mƱVµÕª?{f§Tñ…Ëf–«>Å`Èõ]ïþéÇ_«ÚéÓé[¾åâk_þH¡ŽÛ¿ä¬D<"|§á¶Ly,DÄ‘ª¨T}ÙËv?õáý¾p—HÔÂr§f (…‹ž»Jÿ×Ͼóý'ÿ!ÌgÖ~>5Cç8 ÄÀ9W& Ç\ÌŒå’oI…À^:¤9ª4L鲌]ÇÿÓOý@·Ãž‡°ÚY~öé÷¼ç=O–¢wÇÅÜ*ªÙBØ žyrû¿ÿÓG.^ì^ÿú³¯{å[SXšGº}…³Š!}â³|úÓû—º…Ãñ!M¸ülº8»M»Ùʼ¶œÕFóÍû3’Ä?ñ½/Þ?Üž`ÒΙ_~œŸ¯ ž\Ǭ¥Zó_‡Q¾õ»~Äu©ùðhP­ÌDÜmÊ"ožxªå±õ•çì(Ñ…%_nا/›#-Û—Ÿ¿üôeS~ø5¯záK_×÷;Wž=|þ‰'Ç£mËúæ~ÝBןÙ9µK¡“RA1r !0‘Š–<€ißSêx±€Ý½hjä™…l!´…¢C%k©’‹‚)Es¬z‹¬s”Ì€±IlK-¹¨˜Å€16y‚º?'¡Lns‡ª(â+$©0ªT,ƒí®$-q£euþÒ‹^þ–Ýå‹E×/ú>ÅÅ¢[ô±‹S @µ˜ÖÉë¼5Œ­]2Ñ)¡Ú´¨d3ùÓüƹÓ]L;zŽKnÏÌh0%ÁQ"ˆÈ¡7h’fÕ ZGÓêhR-ÉGeÜÏÃív¼~Ÿ¸¶þ‰üIæ4gDL“¯âi±Ù$†ˆ@ÌLq“ŸyÇ/ÿÊ•+ùÁåjÕ¹½êä: ÐÞ¡ kûÄg÷Ÿ|ö“/ºÿe§Nê;ιä±l‡,U™˜µ !•©qô¤93@zዯþÑŸ\Ù¡àƒ'"Æ.²óGBaF®ð\ù›_÷j¢(*n³dˆèÊ–[ô^fŒ(MŒXÆ!{Qˆ1ìžZ.Î¥¦\jÎuwwÑõ‰)–ºý?æg®^/u‹½a ÿó|ôÃç.~áìÞùÓɳ¢y®l]bkŽpêA&òÀ¹»žûÀ£WÎt±ÁÅS¤å¬‘ñ2·¾9æ/<ý©W?üz_+·T¾fpçY>gOÇDLªÔª1áþø£gú„زCÜ@ϱø1«×ÐÍ %èÿò~Šq&wxV¥Ú©ÝÕoüî;ï÷ž»ú½=d”¦¿ÈõEK;ê¡}òs7ÿËýóÇþäÂ=_Ü[½"Ä΃POž è;~ñ÷ï ½»:…€1P“*…­Šè¿o-'k(4èÿØÃߦµ'":ü¾¬îóÎINÇÿ;¢ã¡)’™ 1Ä´ÚÛKNä&Ž*Ù)çN95´@érÞ÷¹ÄÓ{g^ùª¯·ë?ýô‡/?ö|ÎÝuîë¿á —ºÿòÍ'«ôÊW½(ß|êÆ³OõöNŸ•’(ô ã°­¦1‹‚!DT]¨¥*X PƒHˆªHkÍ-°ùÖ0 BŒ¤`¥((Ð@À ͪÐÍÝ'ãE3(µÖjÀ™Œ(І¢Í“У‰'bŸH.ÀR„RtI²Ó‡rp¤Ö‡»î}Ý—^Õu}ߥÅbµZ­˴躮sÛ™h*M¦éåI‹™ÇÉÑ X­Z³GD•œbá‰cê[†{ aÇL‰;âਸ਼ð瘤™ª–†,å£2äáæÑz³X}úú7~ãÄ^jiZl3CR[øð4q" s é³O=òîwñü©îîe?§œ;]fn[v›-ž~zûÞ÷?òÃoùûËå©mËv“cäåªË¹ŠˆªÎ©v¦ê°“Ó:ïÚû®½½Ç‡›J„DF¢¢ˆÒÂuIM*ªû¹þ»á§~äYc9™™6ê¨Aã?™ˆEƱøú.­vz& ‘`½ŽÖÛÅ"b)Bˆ]ŸÂcÏ=ò®w=¹}§Û²õBè¿ökOž?ÿö·ýØÛ˜{‘áø¬ˆˆÐÌB ZµI‹‘ˆ†ÀsCijüwEþt̺èYÝ@ÍúÈN2I‘D„/†þóŸ?*uBçÒa'–™Y«>ÀÆVJMÑýâj <`Œ·óíCâÙ—Óá¸1ëUßö£Zå¼-wvV¢Hˆ?ý®Ÿ¾zu¼o± 'còpvÌCQBdÆ%,kµÍÓòŽw<¾·÷Ï¿ã;î~ø¡ï]óØÎªjŒñ]ÿúí̸è8N.‹s­ôY~æÒû]~[ cm}®y Ã÷·t£4aí“-Îû—P¥a´<ä’Åñ?³ÊëͺäZKÎ¥H­cÖq¨µ"õ).©ëÕQWìRm_†*ÞÈ¡q€ˆ@MÜlÓ³ÔzØZ4çK216Š!ŠgJ$d‘f{S²ˆVBAQØäR«u«øàË^óÊW¼5rêb\ô]ßwË>¤)5½YÛ]:°î 9½É¦ñÜ/bt'fÄÏ~ìßžÚ]„n7¤vc·gÜ–°[] aÒŠ8'“²EbÓê¿zú±–­”#)›ZÖy{=76ëÃõF>üôµK—oxõ«UUƒH€CÞêÎÓ²Íwø!ÄÏ<þ«ïyÏ“÷/–gú4‡£µpó)SÈÿ\Ôˆp…áòÑðäsŸùÚWýªŠËe·Xt*êËÁæ¥{ÌÑ™™À@!~îÏ?Ü Mðç/$bOÄœª|§üìþöþ‡ž9³óðLµn¢ßÁ¦"*UÍ,0u]Z.»Uß9·q¬µÖa,"º··ƒ\ª¨-—«}ì—~íמ< Ý™.y‡?œÞ­(\>ÿðC~ãßøëD5ˆÇ£¡ƒZ3¦¡(îHC$¢¢ø±O~4 µxNnÔý6¯^A6V6Ÿ}é‹__Jng5Ñš@ÈfD5µ1×<Ö”â“Wß÷©OíŸí;ŸµÝßµ§u2¸ªã›ß|ß‹ï}K.ùÏŠ(l‡£Ÿ~×;ŽŽJs8˜Râ.QäÅ„î©yü3"ÆH»!à~òúG?ñ‘³w}ñì©Wú…‡È=ûúе{ÒÂßýå" `ŠÇ+Q" „8CLôeÆùyÏé…q^•25gÕpöt‡=éè Çz)³)$ÀZDIK¼Àæ@êÂ0S4õÎ詃gŸüâcayÏ™³«x1¸ÖïéKÞð’s/ìY·¥l>õg3«qE¡lÇe_î½Ç.×zxõ`[q+¦9HH d5e`51 D(…DB }C³ AŒ!E7Ö«Êä³6v©9×øç]UK0ˆT¡>$˜PQ™ ‘ÜÂ=b bj )F&Ül%Y| SÈ[E­)Þ;}÷K_ò¦È«.9ý^û)…”bA­úÌÄÇíæ-bèò0CC›Övæ‘î€ýSáþ[Äï˜ÝÕкZx="™™J•²®e-’k>*ÃÍ2”á`³­ëR«}÷·ü¸LÒx—穘j+ŸnÒÓî}0$^Oýú¯?õ’Ó»>¸´êIC3(ʤAQļܸ÷ÏCÝê±gÖðá_øæ7üƒŠãä¾l`F+Óž‰1;Hb`jòª—}ÓïýÞ¯ÖjLÆnêh6A $j¬(Š1Ðé1½ï}ÏýÃkÿ™ íEËûÐZÄaëE—‚¨•RK™ˆÇ\ýf­ÕÓJ1þöïÿü?xÕ;,Oøi£(TÐDt/-ž¯ÃÛáçþç·ý±:Íím`¯UmíC`¿Ð‘QDK©Ê ‘Ã,/ÿÙ0stæGÕ;}3#.jÿñßü®oÛ¤”Ðã×ÁNȦcsñÍf3¨Øù3§>ÿLÝ©¡Š¦©Ü˜A©¦S€óå:ÜwßòU_óßç2Ö\ïä¬D¡–áŸýì;j5oÕýíRówYÖjDrisN³Ù' L÷VÊkýWÿê ÷Ý÷3?öý¿K}©òÈ#Ož§Ž}¿Á4c9Þu6\žÛ'”諚“md³èÿ RÏ0o<½e½è±¢~¹ô“9)wövB n!|­åCQ²Ë7oÀeÉ›SÝN´~»=Ì} w¿àâÓ?öÄãO­×Ï…¤¸Þ‚ÔºÙò¨—övÏ¿dï37÷·‡UUj!óÈ6!5]®ªU³y²–03¬] ¦À*"ª4¥9Ä@IT‹¹YR "¦j>;*˜AÚ,@þØ©kȘPÁŒ€™€ó¨šs1ƒ±d†ªªE iµâU'!rÝ zãrqO`K)ö]·ÚY¦.ÆRJíÄ&eDg N‚Z•©2…,U1Óà= KOõt’©‡å9-ÖTÀù’U'ÛKÙJm¶#ëm²þÉs7¾é›.‡˜œóh³‰‰S‘xò ·Vˆ€ßõ+¿qéübØó|– ž³Ã6CöÊä½f}j!9p)-þèƒ×¾þ5›c`@Ä1—RDDb ÄÔäÓêP‰ 4 „Žqr}5—KÎûn}3E[öüÌÕm®G)¹U` Ÿ÷­*Z«”Rwww».¨šŠë0@ÍÆ±B L1òf;æ~æWÿø¯Ý¿\¦ØRÞÜ-¿u72;%ëꞺ¾ýôã¼ò¡¨’§(i@DU¥É@–·CÄÐ2§…Ã]wõO~r³è'ì×|÷s¼Ùwèј>ðè{þö~¼”ÑÏŠ©qrkQõ §Zˆ\€šRG=Y¦ª“‹h.Šˆ?ñ?¥¦ZåNÎ*ÆRü¿ßñÓpo¿ð”æ0EòSj‘|Sì‡{rˬͶŠzÙí„._ÿ·úöoÿö»|.chsº°=·Ž¼†ÎáQ~Èó¿ž4N<¹Àt1ÑIŸ¦0G’ô"¼sèÔܶZìû4çl8ýÛ .³ñ1© ÅLq¾èÁ+_Ø\?Ø_p¯’·#Äå*Ô¤àæ ª Åöëóá~2Ü é¾sgv–«p¸AQÍ¢* $YA•€úžK±nÇ"10 hFcpNº6J½ÛB›ePI+‚¡76À¨„ .•­`L$&ÖÅ&øUƵ1¢Up]³™îŽ%WF)@Q-b8ÂéEZ¬Æ£îyð•¼øëc)õ]ê‹åb¹³è»išŠLÅPÍFuuWPDR·M­Nÿt'7"Ði áy™f:·®ªUÊ)0'äèaà2|"ÐDxlàT¶R·¥äaÔëûùÔ©øÚ—ý°hÍyšè k•Ƥ <3NÚžâ»óíà—BôgÉ)â'uu-ܵbVñ0w,[}ôS¼ñµ?F ãX|ÎM)@ÉÕ…Ç®§fj†»]ŠU¨ïY·FxL¥V3dFoE½¿0£èÑÿç7ÿöëHÍŒÀÉäâæ‡Pª„À‹eç†Á®¤ L.WGÄÕª‡ ˆ‹~ùÁýÊüÁ•{ûã`wç øÖOÄúkµõ¶úß~žºG½þʇ`â9 3•R}èsU7¶ < %çÚ5@‰J»ûî~õ4¤Ûz_’ˆšÿÔCÿÑÞxãë ñtV]ÇâíN­ÂÌ*¶ÝæÔ…¾‹n-pxXéÖÍK³WçòðßyŠ”;<+{ä½?{íÚxßb¸¥rö‰çÌQŸOÔ25“F®LT¥ÑòJÕDt‰õC¿s î9µð?ðq å¶Q!5àãÙúË4‘sôáI¹üm±žÎ5oEgW§y™ú—+—˜@íöD¦f[í«×¦šoI“.•œ„öÎs4Xíô¯ûÚ×>s÷ö¹g·¨y}t(¥Œ²Xðùûîy1(Þ¼þì³W‹h—J¡Çþüéƒ#PÜÛ=%Ûu4®ÙHÁP¹‹)°”MJ9n6ºÝ”±Žè ­R™D4Š!#Ï.¦– @ÿo™ÜÔ`³•!;sb¤Ð G *XU @Ä,¢ÈÔœ6GÅ')&R©*ÖuØ/)®óZêb§{èáo Ý©”º¾ï«årgÕ¥Î.k*a/¥sⱜH¯Br¢(˜jE$¤Ô6¤ÆŒ!,Û,Ä ‘9.ü×¹E$ÀU+ªÔ&šÐZó¦lo”q?oomêf¨Ÿ¾~ðC?ð×j­¥UD'î!ºD3µË¹"1qè>þgÿòɧ¶/ÙÛíR æõe¿¨¹í˜g9ÉÑ}Ác  EÚ²ÙÖ3–}ôú_ Ãs®)ÀÖ$:aÅGy"ç]7W=ØÙ eíéx·0WR$Ø@B€S5þ×ÿzãë_[Ì407©˜/÷s)Šû¹r¬‘7pžrÓG>ý‹ÿþß?w©_8±ÆùÞs(ñÜ[5ÅÊôz®]ËH”ÖÆLÇ:óõÊK÷™Ä2Y¨èÝøâ—Nr²Ã#â鯄GGõhü£ÓË¿¶³2%DS+ER2"û;Bη DØâ~N›AΟï^õ5ß[¥˜¿)_í¬ˆÂf{óOþäÆýË¥%~ÍWº™á?QZ3h¦ Fªh ÍêŸ&9<"…ç+Ä+²Ãý4)î½'óºo3N=Y(çºÙÚÿ/©¶‘çï2Oûw¦\òØ5œy£ÞP˜ÊèÉhª…‰[gê3‰V,Å šÀšoââÜ…‹ç¶Ãõ+O=ypõZ$èãV—Ë w_b¾ôÅÏŸyö‰gTV¥„u)²Í76Ûƒ$ ljŠ‹´£2fC6›dØÛëW;‹tj›í¶š)™zL9xú/)˜‚©¨kU%@fÕ ҪèØ tM Å„HäÒz¤B• €ÎÁÉ¥–b`­r[{ëv b€¨5&âÅݾjïÌ ˜,¦]CèºDHâQU@D˜@´u!ÄÉýº­¨ÕZ·jnCúä7j .=& z/¦` ¦MƒOs w S)RÖ’×eÜ—²®u#u³æ¢GõÂùt~÷›UŠ7MS¨¯¡{Fx-H1Tñ ¹ú¾÷=÷‚åj*kµlzRAWk“æ¢PnI*WƒEÇOl¯ß¼BZtݘyBNf†‰("Šˆ;Ü2c¶[] uÊqóÅ*Y—èúf4¢é̾h\w€.m_ò¼•¢µJ©!pˆÉlûþ÷?wêûÄ!`d N»¢'šÜ¦p)EU<ÁDtr,)Ç3Ž1DïMc`¦œkkúaΪÀÛ›<Œ!B2ü£}þMßñwªŸ•©AËÔ³ýýu×ÅZDES !°JG½e­§­L›ÁuË?ùæ2±iÕ;9+$ýÅw¿{Ùó\æ¦|@œÜê`Þ]¶e5/zw†5Wyõ%L¹§sßDEg‰²ÿ:Õè[G³!ýÃEªvœSçtrimΦ''ÿ=QjMRÃ=Ô@¤–*""1°™"1!oJ9Ú…å’¹+ãÍ+Ï|¡®vwúpfqt/W÷׋¾¿ôÀ×nÜ6ë¼Þr— `”ƒk7ó C­[‘:ŒˆC)c•-± Ú/™XUH›s1Tµª¨jâ8a³L&wtPÓfªŠËUX­À7JDDN ÁÓk€ˆŠ` TÄ RADÑ 5C5Eƒ>BLPªä¬©‡>…lýÙ‹/íúÝ®K)öËU».Æ@d"c­UDÉ!f0¢dV‘œa(ˆ&ª•89D@©¾>ù½€Ès(HˆK·&±cµ¨ÿCfjXU²I0ÉëZ·RÇ:jkY—ªÃ(zóà-o¹WU‘‰àDdó2Õ†#û$0ò³¿z›ËïÕS%<â‚ =•Þ¿ÏIù㎠ Û!&ìRHÄc)DT?;BèUÒ%FêhrŠäVók˜’*àVb|ìé÷Їþ^ÉÊDÁb.µ!®O®Æ)¹šƒmL‹E2Àa[þŸþë{&BtÜÙkÄÌß>“wÛÖ:¸‰¦Rpw>Ghkò’**ªÄÈÊæ$Rt›y›ÃhNHò¿t‡âóÏä±H¢Ž¡É´Ä(EÜSU¤•ÁRÊmÈ¥hU³1ë… Ý ÎoÕBïä¬vV;Ÿzì‘££rßbéõnž»½†ºý’{÷9+®ŠQhÁX«±5wýx"jÇ¢$êIÔÇÄ)jɶ^I'Gðãžtæù¥:KäOòðÛPïa~I =9ΟœåO2¢Tm~5S–¤R­£göÔ*NrÖ‹¯¾F)×nìî-BªdÒ- —‡í°¯Ãáª_ñv”mEZX/0,SÄ‚²ÙîßàSùô)ÈG›ÍÁXª @4-`R‹lóbd€Ž0!EJ4 %5m’Ù6ƒy”)O±×D¦@ÌAªª*QS H3Y˜ €TÚÆ€8€©‚Anb"ÃVŠ(ˆÂѶªñÅ»^Cè»År¹ìûÄhDšóP«˜G¶``ffÄ€Œ@@VË -ñÉb‹*ôáŸÉÙ GS´g[›"ÇæèAÍŸØefdDb­y­ZµŽu¸)2JÝŽc]oë0*3¾à®·æ1W5„™/Þ<åšé¸²ˆžzjs‘:wwÉF3 ñ„‰j‚6ç¦}¥|]ÿx§.æ±^¿~xöìnóûiŒk4Có¥ª/æÁfe3~)üêÖŽÍ…Ò¯pª†'ŸÜ¼ü…H„*JH“騃XÀLµˆ¯! 2…ÀÄHD!°)}æÙ_¿y3_ê^ì¸)žaB0ð¶€õy¥Pª®Î‘&@vœó®ªŠˆÆLÄ(rˆ\‹xb‡wßO=ó\„(²õžçS_ÏÈ„‡‡U¤4Íœž©¾hŽ‘Cd Ñ®‹‹E ·²F8Õ®êøýß|ÿ±­öW=+æù}ï{îî¸pþY&ÄÜûй†Î:5²ÉIGôLS?ýròß×IþäV#„~æs$~©­ž©Oº‹|YSf:!„u‹üË™OPwÒ?æTO/"0©O.UFö6OÄbütRìµV³"B`e8Ún`ÿp×PõÔ^¿ ðYìêbIH¹G<Úô€´=Ê„#ؾÙöâ wî?»sõóÏ}ñ‰±–(Z)¹PÝY- ŒLI•J$ŒÆZ«0ÕäW\  P™˜âHHÄ@Ì5ƒ%˜M7 ù£9‰@¨&DµdAƒÀ%æq,RÍP¬Ö*ÐGˆ‘ªh©öÀ}/ÞÝ»ˆ(­Kµ–êƒdH‘ Ed;T3 ÌÎ""æhP½c©h*b>Î3#¢5œ¹½]m¡ä$üƈtè¿¥ ²¡™V0;vrªƒjMŠ”m.ZÅ>qõæk_s:rmtô§¬$S5AòÌ2SÕŠtùò¸èâcUÈEܼÎÛµ ?›þúÔ?'kžìI!†Î´æ\ö÷×/žö3“ˆšZÓwaó íûÔîV‘@E&Öšh´èsŸ;úöo$Q•*J6eLze˜áÀLÄLìÒ233ÇbŠÿù?_9 Ý\:ƒ•BŽá÷5v¢ÁY.¹”âÆþ‡Æ\¼PÎah!°»¾›Y)5•ƒ=ÿüŒ¾´ÒÍ=!е,5¢ €²¿†EŸÌ æZªœ;·"ç±æ\} (2cè‹l3oáE÷¼i,¹ær'gHŸ}ê=›M=ÝÅÉ7„ÐZцÂÑüÊýKU”=¨õ¤Úkµ V6€j8»ˆzùÂI&7¿'w£³{ÓÉê ü-M½L!¦`¡E†¢C_Ý oäý]otQµÔqŠT*‰BšìvÄTÜËÀ›Vf$âRµ”’³@ßGéh¬Û­_<ºqåæ…‹§_öš¿qíÁ×?ùÄŸ•gþLóµëëeÌË8¢ðΠDÄC×Ä£AI‹úu§ %žƒj´Y/€q#`É¥ÔºD Ù¦P\ïnµ‚!¹‹‘J›Ëº  BÇé €0Óôî"Rƒ–«P (**¨AŒDˆ8†‡P Ëð• aÍaµ»¸ç…/K±!„@DÆŒÌa²ÏaÜ5ç¢ ]¸KÌ fª5Sµš° Ìœ8¹hxLŠ˜•Ù°‘` õô•(qš—híõ"Šd•*uÐ:HÙ˜J-ë\Z¾¦*üõ—¿5—<Ë‚‰P ½3m>Î^01$dÆýýry½­UZ|¹ó®\2ƒ-ÔõË&{»´ÌäϬ±ë3 ¥TwímCZçÒøÿ6ošnIsÀÆ7š£ê'¶»9Ër=6ûQ«("&HѹGĘ8ÌAQ•ª¢šbÿùËÿææÍ|OZ¸‹%OKƒFöFìå¢Î²œdš ZÈE_x÷Šˆj-ÞG33"”\}¾v¼»ë¢ˆŠ8ü-D/W«§žÚv‘N0œnCH¨ë+Žiõj‚@SÖZ£¾OfP²¨5åxõ šÙ–È¥ô¥ê~x‘´Ö;<+üÿñòiKó­6{{+=sü‡H‘=«º ¶ö‰<£[Õ‚S˜¶)»¢g”65‡Þ×Ï2ÿ¦uëS ½ š?'"ûÅŒ³®)LK·Oô·ÕP:Î4b2³Àh¾¿`ŒªX` ܼEЩ7Úrlb×E"A„qÔõf8¸±9¸zx´°·“.ÜuwïKâ¹K÷¿ü!ªÏ>óù?ýç_8xæ¹a I²àшe4ʪãèZ=¼ym³Pàj€=sèr)ƒ Ñ"‚V8(–*Õ,pˆDDÚX=fĆ‘€÷Д€X] É“c›Þ2Y%¤j€LÔUƒZUÄ èJ`0ÖZ‹Å¨IJ¡€RXììì;·sêœkQˆC!Æ@Äó‰"§Ä„Jd9+1D6D6ÍŒ§d@d†ÐVœíi è?‘é±)1˜rÚqÞî aŸ˜‰ÖTUF•,2JÙº™S+UÇQ/År.1p6bò܆V‡¦©…È0œ?—Œ¬ bßñ…À )Rˆ#­VaµâUúÚew¾ù®1›A \‰Ð5¯µj%®¹¨ZŠáð`³{j™RȹV•)OTŒ™˜±V=Zsp"¸—!rÀ>ÑvTÜpYp˜ €TõÔEtöOÌ´Xuþ“ªå*¦æò|"ÐÿôŸ.ïÖÈ œÂÆiÖú€?Kæý ²êüÜîSyðÁ˜¿xz(¥ö}BÄa7¶9&N)%oÊõ‰'ÖwÅþ6¸ùKÿÕt~Ì­ùBí¬Ž†œ«Š^¼ët­¢¦LCTõE¶~yþ¸Ø·ÿíï+µ‚éœ6µ§žÚ\êˆàø[c#1ù8ß*¤H„0ßyfPÚ²ëxÆG„fªàø’xSr"0j†ªüÏ¿^ä%rnB½ùûГˆè¬ ŽäÎ=íÉzJ:¹ %˜® bê{ò"Oú*oI”<¤4x<¯Jí»Þ)¥¦2f…ëƒëWo]Ó×nì]=xãùJ‡Û_ìbÝÛYv÷¿ÀöËþž;ª—´ ¹dR&îö×å¤"ê°-H¤u,þã•q4Ð@žz¬ŠD¢æ*`ÊDD€ª³èÏõÀ¿DhdJ@¤h€¨ŒDLÁ(%B„1Kਪ&LD¥€¨¡ˆ‡Ì¹/¬(ŒTaµŒ;ËeöÂj÷t¤H(†€è 7 ¦HŠ©ï‚›E”*5"``"^.{Ó ÈnÇ0ÉØ—xàŠƒ90rèy6§~ÞB¹w¼ž#h1•Z·*cÞ^w‹ûZ7*ãv1ë§o¼ñçs.)árÙÉVU%‹bŠìDιV)Yº>ª8u |ßwýÌ€˜ŽŽ6ªjдŒì®ˆ°ŒUÍj©Ì4Žâ·W).R 7pC"U³ÍvÜÙíUµ”BHÈþ(3û‚¯ä*¢¥hŸØ=zg|ÖæO.ÔÚçO‘û’0“Sœwæ+Q#¦qÌnlfHÈjŸyf{Ïòx+ꈰwŽ9Ž$™mœææî¡{þ;aDŸŠC õz€qÈy±hñ ËUÇL5‹š‰hˆq³=òŠã¡l4n$qr;ÿÔÌTK€’kÎOŸYi[xƒ{ìVáÀˆhÓ‚U¦ÿˆB\™¾“³bŠøØ/϶ù8aôˆmôö7ÚÕº.úòoëÊzœÜ¶ˆ€`RgR+pÚ¤hlþ¡òZ|rÊ„·µ™'M–zš«¤Ï1þÍço"bí•ÌH½Û…¹¾É{§.fÂ] DL!®B=ˆ‘b%fò.Ïûh± Ö `0Uñ/†Å‚ÉD®ݸ¼Ýãááøäº¾qýzè° Q‡®‹—î»°ãÆúÆs€$jˆfz´?Þ—=(2€B©"¢B‹ªÔF$@óÆŒ42‚(#(¹¥N–Ê Okþ“UW;ß!B®NRÓ\êz ¦€`! Ò ²Q].™€Ž6ÎaäÝn¹³{æÌ…´Ø-5#ZdŽ)L€@âÕ=°».õ}ËT­hlj‚mcÛ¬6ÎOž)ÀˆÇÉ ì¹Xì{Räfã$E=#$¯Qëè¶xãX=Z§V»ÿüßÍ9o·¶\v]¶[ÅIþX«ã\²Û¡©IõhI3$Œû>”bªÆ¤„hîa‚X6¢jLäYÖ<11Ølæ€Y©A>ÃVŽŽ¶)†¸ë‚¨–\  …JTS;8¨÷¤¾! ,¢3{f¶Ú™¨&®d¥XDBŠà~n!P)o·Ù‘DÀþÇÞ=í”qÜŠâ-ôšù Ô =³ž:Ei‡“gµ\v¥ˆªqð7´`Ê|VÂû?üob<î~žA­r¢‡:-9WÄ`ªþf-1Æ0[ ˜™Ìt%ïdÂñÊÒw2÷Ý·Œ!Q¨wxVˆøéÏœ…ŽNÐ%ýâÁ[øIt[VÇÔG·LÃù«ª–˜ÝÐí¢Õƒ*\€ë»øclmR—¢¯Y½JÖ¶¡kËÓ¹PÞF=9Ú·¬ÃÛøö'¾¹hžd98qÄûP_ÒµõíÌ Œ1M-Ò¼•›öu`ZÁt¹ZÂþÍûî¿÷k^ójƒÃÍþSQÙÈåç7–‡Õ2¼úõ÷í_Ûùè‡n^~ö˜ªÐ8 d€ e@ S@C+‚ ]G‚@C·T‡¹T¤T•Mí–!‡•Dmâ6ù›Ià“ªê„¸€Çˆ c@F­6ŽÕ ˜cGR- ŠÚÖr¤J˜©d`²ª ñÔn·ÚÙ[íœ[õ§wvÏ.ç²éº³}×õ}GÓö„ÚÛ @?)¼­S3A›_»™‰aãÄL>Ej%÷½çŽ8'Ój>Xv>qrû€ö—ó5Õ|xtt´DÔ¶£2ãj¹Ša¬U†!/ˆÎ=B×EDsÉ£{ž 2{6h[S0Sóñ‰ý³ÐÍ óÉ”þاü6–œê?Q®êHZ×E_ÂΉ~S#æ²c»Í¾ý:äo}ÙEW ÜÉY…ÈUò3ÏlïI‹“6tmÓB-)Þ ¶>È«3˜‘¦Jªíê3à€)–Æ“ó}£×zW= Âj®ïgWÊù&5­õ¸VÎ÷œch·oOö¤µÚÜä¶ÝèŒÔŸåýB35Ç23:1øaÎ:*þ­çDfÔHÆE¢A‡õf3ELÖ^«”1«‘©B•êƒ:¤B5(Å=Õ“‘}ééF¡à‘ˆ›ÚÊÛò€€& Ö˜¡ÉÆÑP•˜¸ÖPU i p´Uè:è;6Œb!ÆeŠË~±J±“2ZêzÉLÁdÑN'Ö|ñØb3S$RP@g²ºã½Ö#2JŒè| H‘¸#îØŒÛ˜?™ÞËf#u[ËzîLM…&€XÍ.\è}—"®7cÎÕ×~]ŠˆàpG©²Ýfè)VƒÝ#µ!>“íñDׂ)ΑˆbDÓ©^̎¶ií»bJÁùöu‚‡Ç±,—ÝD¢k›?páÙ<Š6Âc=îu\¼r¾;–c!TQé:šÝÔ‡!Çqs !ÅPĆüôáaÙíÂì?4_‚‡ž;°æ…i¶òñVÔá7¼æ‡9þ•Î ÖÓeo[O‡MSàmÍÉÆí6Š·w—è×!#y8JEW7[3©†ˆµªW™)‚É^ûð›Õ×ï_õ¬úÔü/þU  !$ò)¡²™5<—°FlS›ëMDߎ£Âlp3ãïs×¼¥ußEÈ8ˆ˜šèq‹:#oˆÜÔí_ÊÀUµùròEªÇ"Ý.ôÔ[3EOÆW!¢(ÔI'`–·£ä¢G›zpT×u̪*Œèk8廬3‰æƒññ9Xük¯~Í7}Ûôì êÎÎé¾ôë7 Œe<Û”½Õ©å¹ía}ö‰á´”œÓ’Ó‚k9PdR-eÜÖÐu1o·ÉLKV1„.¥Ðu|&©æ,C®nã˜@'ú¸Õ¹‘[62‚™‡¼ûþTÀ cˆLN7UML¬€¬Û†(‹ÖÚ>ù ësW1b܉]ßuqÑ-úÅbÙ‡Z²ãID¡e}b‹<„Iê¢ÉµOÕŽ' B%"0°fê‹G¿9ÇÇeˆ+ }ˆ‹´8»=/Þ‡€J–²)ù° û*Yµ¨Œn”7kµ ÷v~IÇÈRu 1æ }ŸJ©ãX ÆÐ÷1vxì8¦Ñ ÞjÖ÷±Á`ÞMy>¦PLLTçµ—Mêéy…í,U—ð'Ï×õû_DDZˆÆR}D]~ê§JôZªÚ¶ÉùûÄLŠLV¦¡ožÚQ. ±ˆ"rcͯÞo¨@lð_þø÷pVIù?'4ýÍòÆyÖkùöíù:|Ý×õeË_õ¬è×ë·c‹Ej¤Ë¹|7ª¢—Ι¦:ƒÔR«ªu)†ÈÎê0ôå£ Õ¬zú|céü¿”½û³mÙUß7^s®µöÞçœ{o?Õ­'êF X€ƒP( âiƒz L c’øñƒ«’Ê_à_œrå  ”È…í$!Û¢ŒeAÈ<ŒD?¤~÷½÷œ½×ZsŽ1òØk}o·ä+•ªëöí¾§÷™gï¹Æãûý|i€ÖêI6€žßÙYÉþá3M/n–WeÑ:4ˆ>ý22~Å/V)_¨ÊÌÔB«`K©Ó’øR¡ 9^U…ªÍ^×[Û×7l¶(‚ËëñM¤—CEoÙëcF—‰€BFDÅ:M¯Ï¤9µ1Á’GÏ 7ñC 8PÙ¦ê U©½þüžódu"š/nú§þ´˜ñaœTÁ5–ÃaÜŠãD3ø¨ÂÜõŽ–2ÝsõôüÆ~,¹c&òDTÀÌ­ÌÎnDÔg²n¼ëK@óXâ38C7”GÞ/ ÀT´K"Ž6N g§ÁR¦©(Œ³1 ƒ(ânÃ]'îÔånØl¶9oRÞ¤¼éºmßoÀâH€RëÜcœ¸\ÜÕ¬hJuaœg‹v™ˆÑÌ…E„‰Qɲt,}xê‘I8 Mö´îèM#n^ëa -nÕ#WÕAÍçb/»ÖÇÆ\„ ©”ZŠŸ›MEÄ®Oa>e!U+U»œb)í#ˆ@A•'Z5¡¡Ž$&5]ÉÑEº›U_àFL‘±ÂL„)Ç‚ÐrÎép˜ÍŒˆº.}æ3‡ˆš/ùwÖwÌ„}GIè0)@SÞþA€†V ¿- Ä]Nj–0lK1+çO~òæUÌÇ~ó¶!Œ6pQÅxÓ‘YTÕ«º»ç7ÿ€Æ çÎÏ ˆTç?ýÓóºa؆<6$“|$½þ^î;`¿Ÿ³Ùu)ç(<(ÎëçÝÁK©µ/³ï úTõ”ˆÂMçwtVµ–'Ÿ‡^¢…§#ÀçÏs?~Ý2Õ5_/Ws˜Vá“»·M½ú*C^Õ«Fb¡^ ÂV}>S@+±¸a‹­}©š1’–$¤Î·Y;š[y¹IcÒt|·bŒëçÒ^I^ˆÜbÈï>/07p-KœºJÀF{áÃÓ7ož<{}?¾pxŽÎ/¾øÕÈáÙÇ¿PÇyc¶“Ý QKå J2` "æ”ê\Ê\EÈ«½ðüõM×!Vuƒ â!šSÜ••À­ªUz¤`Т7œ«"’*Íb, µF„(6!R3ëz›g;”)[Cqp“ ÌL‚)³:}HÕ9çÝÕ«w ›+œ¶¹Ût]—%Çó¶”Y$5œ † ´’ƒÅ`„(|ܘ“$Aä” íÇøvÀ½CŒû(@½¤-qféYºØ·‡bû…jÙ›Õ:ÝÐrp-œ}§¹Wµ òžœH)ÅÜ„ĹT­U/.¦«W·¹K¥TS×¹`Ÿ ‡&¿Mó¼ABª™"}1*aó£ÅÖ7LJ+uÏ8ð#쀦ªæI˜ë’pWK•$}ŸêÅE=Ëi]æDÛžE¨ïš¤éa£ÎÒãõ‹kÄ©º$©ÕJÑ.'@@káª]§ë×Ë}Ò¯4¼µ¯?†N„X5houAX>UÇoû¶—唪ξü§ïð¬˜Ò¯ÿæÏ„¥•zì¸âíS‰—Á\Çj¨¥v]ê:a!DŒàèÀ6›YÈW`.Õs¦Ë1 º™_»–£ø»Ã³*u~öÙùe¹W˜¤­Î—mé%hq•|_G·,l ÛR¡–zvu¾Eàózòºä`i˜PÕ­iZ6ƒcKaAÇã9CüDnáVµP´ä@Gûµ„>ùÓ¤×f=æ) „¹£EFŒ:¸{„^@&tœA‘φž.ûixþɧñð̃Cõ®+O?ýÔùùùþbšG=\SbØ $¤ÄÌê¥Lª>)€Öö|Rƒ9,@Œ^cˆFÈMjsq3„,Žf>;ÄŒ1Bk‘ƒoL@팀’ÃI!?€jõ0.IÆÈP&³ƉRÆÄ’7©ï:DCîÒæÚ•{6›mλ~{µß^IÝ.u½¤N$×xpû 8¸Öºu¡Ö ‘ãe¸)˜—`Ø r+Ó\jÕê5Ö2‚”̬¸«ÖQËÈiü]ä5…OÔMµ^¢;YŸØ{ÕݶwvðÈŒŒ÷é8ͪ›ˆ·Œahx½§¹@ó7g!Áaœ#hˆaÙïªj}‘Ö-Äüöä&$bw"t³RêÞÝ»ŽÏoŽÓŒÈ""ä`ó\¹ëÒfÓ?öì?‰ÏdÄF ßbì+ÕæbñhÙœ‹Ú?Èg”¤ÖÜ¿p 1Sp7ú!OS™çÊLŒùßú—Ý–]ëz/Ľ…§-5ó5¶è³e|àáëþÒìÇ,ç;«¡4Ç€ƒ=éæÕ4\÷ZÎ?ö±gïOCŒ×R4öKñ„¶[9ÄH·DEÍ>ôIUUµV mLã—ħU`×Ѳ‘ŽÔ&8=w"ò;:+a¯Í˜ê3g¹…mÔJøé´6Wåæz±®iÈÆŽVâí‚kpÒeªÚ]q‡®«¢Ç2*.S¦¦|°ê±ô¶ýúÅWls›‡Æ.ÿø‘µðí='2»t_­ •PeÇ#ý|_§Ùö’K‚Ì)ÊWaqoŠ÷ªfÚ =÷ÄŸýìSÏž?í.¬»¹ìd{Z®4Ìn:×½Á0!zÈWšYìÌÚMkÙ‹‹C×I¼U$Iu?ÍSÑœ,¢'DZFA™„jÎéüüâÚ]§µÌû‹Ú÷bã8 }‡Ähîûý4 ©Víß_=ì‰'öŸúÔþúõĶVcfÁíV^÷º“‡zp—¾*%I©3óÏ|æ|W$fgÍÓña² Þϵ:Š E0à¢qÉ)MÓÌL¬ZX|´p|½H UcÖ~ôÙ+žW”ïêÉq‡)¨þ¥3JõÚ:J«Šàßß:ßïÇÃ4 9öZÓT¢×•Ä"ÜuéæÍÃéÙ¶§Ò÷Ù̦¹î6»üêO¯Ó؆"¾•f„„^ýÅéë­š3£†4MÍÜ€y‰FÄý~B€~“S"óK,€ªž¦œdšËœ•YË;žŠ.HQ䣄ŽwÝk½^MQÛ™®eLÓä7VH[Š6-}$÷DˆÀú<‹¦> àÑ@ÌÅZ ˜zDWµX€áÖ@ã´ÄmÝ)Þ^ö«z—?uýcñ¶x)ÖÀfÓ™5#;¨ÎP;ŒªêI°ër’ÞÁwÄÛÔæù’x~v|ò™'íÙë®EÕ„Óf˾éÁëxHeÞ×RÊ4™×$ ¡#¹‹Öª^\«%7H4£†wÇ{nµcb„RÝ Ì‚Jcó¢• E§±‚ƒ$"5[Œ±c%H2SÊÝfèR?qΩï7,i—7Hyw²;=»k³===½²ÙnONÏúÍ–9÷›~·=ADcb"RãA7ÍVŠ C×%‘>„b1n»y>ö=§$.0S–Œ€Ä€#p NáSB¤¨IÀ´¬w¨Õ±ÍF[½@-{××ñm¼i* %Þåó\Ý=%é‡|8Lñ ék™k©J„YÒ?ûŸyì±}k0•b/ÞÛ­ï7{Q‡Ù¨såʈaµ_…%ß*\¼üÛÇžýð‡Ÿø½aàøÿsÏÍ»NŽ™«½º‰Õc\³¶6ŠSdÒ­а·šGSBl-¶@ ^x¡ìr›Ž^Ú‡¢Ú]InU/ûʹØ3eþÑÿêuªŽà e4¹L0 %Vµœ% Ô!›1µív÷ÌÿÑ]¿Wúˆ`‚”VC ¹•Ü?—ç{žkÎ lˆÌ¼˜…‹L«•R@’˜Y4õkX©9ˆ !gU—«Ï(%RõÄÍâ]¦ZmU ½U —Ú¡µ¾n]65¾bë«ÅeÕä<Ë_j.¶Z ¹•æb9‘PóD£mŽÅOm[ÝtT0ßÖÅ3@ĬX³•'Ó\³ãMTˆªê4ëò¯E±D¾ÛíÀë\æýaVCj+†õâæ«¿è•óôÜú¹}yݧ±h+-ñc¡;ÕR¦iž›/¸„Æb+dÀnÕ‰€€„A À4f €¡ª åµè%äXÍ›)!tÅØLµZ"ƒØ³Vu-†D}'"bT(qJÃvw2lv±á€~ئÔõ›ÝvsrvõžÓ³«W¯Ýszvíôì ¢u¹Ë]ç^§Éc4àˆÖ÷Ãvƒ¥LÓTÏ/fDL‚}/Dùìt·j)EÍâç’Ü­ºWÄU¯åP§,ƒ¥QË…¥ÁêÖO­Skêµ”ù<¢Ù›¬¸¬}&ªEç©0S„YH˜ç©Ncé‡ÌLÕ4š»°K½jØô·Ëq¸t×Åvn%MÔjѦّép¼¯ì6±|™»BmƒD8ÜÔÃsz–ÒvË]Ç9QT¡=:•ê²~‰‚0†@·]»Ø‡ ÑLMÝ Ñ4Ø+–RÒº¿¸¨§YZUÈ-W..͸@Õ :ʨ†öc}Ʀw¾ó/»ò×ÇyL‰ƒð¶¢âk_dšJÎÊ·”ØÌØíð¿ÿäïžB •å ^Ywôíc«vkVð²"¶FZ·Çª-µ1¾ßX„®1w©±âÖý*ÚläÎÏŠ·ÞQØÆ¸ÀÔ@–Ñæ :¶*,êÑK‡ûš› íNl8›bëZÔ#]1®¯ÐHTµRLmá9!B1‘Øã%¬Õs:¢).*޵‹¿Mg*¬[·þ/ž‡›ÕÖ ´ÉK„Ú4×Võ?@ןänÝ ªi©UÍýâüœS’ÝV0ð—÷^»ûâÿè©Çž8=9½ví®ç®LûRÔÕk©Z ˜"ÏE«Vu0CÅ£•jÕЄ)å„dˆJˆŒ¬æV«V‹ÏdÈ®DDKÕ)¥0ˆš›14e­Ê¼œØǹ¨VBJ™@K-¦^!%Ì̉1Qaæ®O]Ÿd6Û®Ûˆ³°`ÊÃnszzõÍv{×Ý×NNv]OB•ErÇDÈršr½ B·RkUƒÃá€9Éf“ NÌÝæé0ÏÛù.Óf³kzÒÑÙaE×RͬjµNTµ8mbËhõÝŠÕÑtC},90ÞI»“®“Ó¨¯BÉ‚ÍücnËz@^mÑaž‹©µÈ‡õní2­w¥;@ºå¢„åAÞ$„|‹Æ¹,òO&;&˜u™Ô€"Ð Ç.±ÄØ(Ç‚Åσpáè‚@Ì‹HÀ…)' s'·ÂÛ›kj`×;:+wŸ´-f/ó¢Aù‹•¤/žçÞÖM_šŽîb @㽿@øVËÒݯ Æ–ÅàÒ®ÔH4‹iç‹°ÍÔd Ë¢ŒPLK¤¯›b§¹F.]‰#bÌõr÷‡f+ y3AµÌCjA‘~—ÜTg÷`èչ̦>dyø•¯yî…§Ÿzþéq¼Ñ1v›!;wÖñ{S%Ÿ‘ „+®Vf`#BÈìU½– ´$Õ)¥žBviÕJ5FJ)\1ÅÂ#è`FÄfæ`\µªgɹs7á™ ¡Njß5h—7C×§Ô K'½ô݆%™§Ôõý°=†ÝnwrõÚµ«wÝ; ÛÍvÓu¹ëz‡ŠöÙ¬NóŒ"H„ÄÝf;€»ÙŽ[3«õPª§D]×:¥¼É€ÇÞ( [5«@L$S èìVU'¶j:™'î›?H'«c,ô­NÑC˜Ns±¢^«‡ìQ«07ÇWCæ ª‘»ë\¢ ÛX”3ggòÔãS({ã¦çãPɘUE)ºþm\‚ÇQ91û_?3¡œvü‹ xû€eˆÏI©6Ív¾¯°d­js"<šy‰`JTÕy¹[MÉ´ÎS=æ fÄpl·=!ŽSQUfyâ‰C×µ°&˜‹M“Ú‚IÏj­þ,L]Ïý›øÒW}ï8M¦°ž•¯Ò}¦uß h(‰£Ÿ‘§®ô}?ýoÖ;Œ#¶¹Ø8Û§÷×®e3ß_¯I’šgŒ†ÂhˆØVÛj-@¸V›¦2—RæZKáͶ=`æRê4–Rj×-ºiF$,Ë-ѬJîµú“udÆ/ÿò³oÿ†÷ˆäižÌ€Ï –°6XÒß<âʈjQ —?úó_ú…_ø‹Œø²<¬aÄ”ñrGOmZJëÂãH4ê— kÂÈ ¥Ä$íå:ßs—¼ú5ÿ‡O}òîe‡ýps>æ®öû¾ÌSJ=ñEûy>Ô¹TRÄ®j«Ü1³WLIØ [ƒäŽÀ)!#{d1P؃™&pâÌñÄœ9±b –+R’Ä]7Ô¾€Yî6)I—‡ÔuV­ßlR8§äàÃf»Ùnûa“R—ò°=¹ÖýÐ÷›Ý&Iê2›Îæ¶Ñ]tllËLà%æÝyùI!“iloÀ#ôP`l.^j‚» k€“ª/Yö5¼ó‹7;ž‚§ÈltÓ>Å„a•Ž3‚Ïs%˜ƒ¤jÓŒK§­–½UÜ}šk?Ðkün€k¶ñEóïˡ貭‹£ÛÁ›)^«˜xð qÐ DÚ'í0YÛV³•jûC}t:¼þõ§oyó{~âý?±‘K«I|¢bèJ $”j p8Lç7÷HÈL»~Ó÷)%‰•‡"‰OóÆÍe{måh­´õ:ü’/9ýÎo~צߚû›W×ñFîØ;[Òò%ƒ¦L7ãÆ\ Ô5.ñ˜í´òþŽ•¤Í‡~¤ÆÝÖžæl˜Aw@N„\ÊXë AgŽ/ë—Ý{ßsÏ>zýæÔo:$Îiž§I8ãê´;ÇÃá0ÕRK)ZJ)»™`jŽ]–„L„ŒänˆàjfuÉûŽÄ˜¸³¦DE›]»M%%¹8?”Rï»÷J×I™å–Ÿáå 8+4ÞídÉd¸D­+&~©zð¸»_ð.¶Ž¢ê< ­ÞÙà9­*£Ï–~àݯúÒW½k*s­ú™ÏŒ÷o{:1_f™Ü ÇZç /žÞÊ‹§»!­G„œ8 9«g. %ÌÈQ“†ûÃìr7ô²lâÛ¹˜Øìà©ësXBÃ$NÞ8;Ù¾úUÿñŸü’V@ˆ…˜k·íº-80u9«™Õ¹ÔZÍü º§CŒY‘­9ÝUk)`.LI2³' †¸™[Éý¡fæiê&î7§ªJ,žû¡Ì‰;Úu¹s`¦ÝÐk,ßSÊHxzrÆ’EºÜu"üðî_=ñôF… Õ@üö|PøhÜV¯ÿµ ]¡ë&<$ejP–ú´ªïúTßð†+oy󻈺ç_¸>Íu»~û·Ÿ»†y Ñ;²ð®OÜ[ ¢ŸKð ˆ´úQkµ! =i0-1ûŽ*-‹{^|`}ßÀÛÓ:A› S×eDt+ˆh±üöâVÜÔÔ %J,ænªŽÈDnuèåî«÷«NˆÒ%Ûm¼¦rØï÷û)åM—:D§q<RNÓþbž†µTӺߟ/é®jfLB«OÄ)G`‹H­eAÎ)‰0s×›”òxØ3'‘œûÞRJˆÜ¬sÌœsçîÄÜå~{rš$±ˆˆ°äœ;éû$a¢œ³ÄwCôZç2Ž@èÌ$) é\«ö}B$·½ƒ¹›•Áݽ¨ SÎìŽjÕ˜ÄMÝkÓK/óx$L’n©¿9dÕ—·$î¿@4ÈÄ<ÔrÀ¶’ ˃# À5Î4é.¥'Ÿ_}Ä:%Ž˜ $œ/JQTÆH”“`F&6Ý×¼þí¿ñ?V/‰;‹ÕŪ(@:¢ä¤îÆÒ!2I¯õw}Pûbëåf-3Ê<ʸLcV0»8è§÷¯{ÝÉwË#jªµ$Nþ­Ÿ1h|/¡$íåD+éjåÞ S8ÇÝ\r`É/ºÝ`Úš 1‚_Ý|õ›ÞøU) ¸Û<ïÝÛ'å ;«¡úLBeª€øûöÞ8öoí tT{FZѺs[µ q™y›¯ñÔ«üþ¶**36†'áR51™B¸¢¦qŽÛVÕ•Z~¢ª›U" néç?+"r°¿òoýÿâ'××°‚8Ì]œcï‰ìGJ{ó¸Ù²œÔ[›÷•ç´jžâ×s±gm;ýÛîÿÚ7~Ÿªk-ÓTäÿá—§ÉîîyÍ£¤Ë±êvIFh7û*xz‘h,Ÿl7Ï­o£ÜmÜ*’pKX‹‘°w rß·ve`©;C|Žh´æ]õ¾£”:€†%bFw$7Cp«µÖÃXˆPæYÕ"€ÛÝéÙ|(WU3›çaD§”{pD>Œ{I)lOæùÐ%Äyoªæ~¤îÔ‰ *`"w ª»j=¸ÖxÍàY&mŸV5pS5Î󝹨£ó~šìmo{ð•÷|wÕ˜3ÿøÇ_x iYú·¤3&aœÖðÞ¥¯¯j"Xª Ã(n™0B)Ú&ìLDXŠ"‚YA¯G qüâÎÏêp˜`»ë«š«ŸœÈºiГ£È6-ÀõV£‘´kÎШ=’_ÔÔƒz\LAåã+Zqu# âœ9¸‹05Ú"á©ÿïýW¿óÎϪËÛ³³¤/Õ¢Œ‹8€ ÎÅ0 v÷cªHžˆPj35ø‘Uiíë?3ñøûß—ùA³9L·ÛÝ€€¿ñsO]Ãsä6$Y´·-šô(ùX4z{íŒ (/.òœB¿K1&céãƒtÔÒåßRûãHÌ„k˜Ÿ,ÎØ@á¹W$A¤c‘ ³V-àŠè"ÀŽOàíöš—2—:ƒc:‘Ò7°¹ª#QÎiè{@`·SaFD­µj­eV-Z+8 SN›Aˆ€[Ú"#¡–'ÖovAxr/à÷”º”óeޱ¤$’D$ò_´jî:D6Ó”º®rîEZ®'‹dNÂ$’Â_Ua ûœÐIsŠ7sœODÑ­u«ˆŒDHÛÔT+ku«ˆÎ a˜çRkdþp'r‡f.^ÂÃ’ç¦ÕêäRÁÍêd2ƒ"‚®­½jm9 Ñû3÷Æ3k‰Ò&~¾Ï>3¢WÓHÄ)¶ÄÄ#ƺ)$alÉ]:ì§Ãa~è¡Ý³M[“˜ Mźl5!µé:’`“ h¼O\k­{oI¥EÍÇI«zkç'-ês±Zýæ¾>6í¯]ËÿÍÿM¢t±ß " ¥ßùÄÏ©z×G‚m‰,[Í2EiöDs3ØnYLMÉ"ï~Í׌ƒå¦°¶°–¤¢æÌ±ìjêŽa½ó³Úï'b*U‰éµ¼óî»ÿ§Ïk==ݬ@åuréþ¿gï*ÜéY §¿úŸ\ûõ=ù1âÔ›mnWõ$¤Eƒ)cMt©¥_wñMáTÃ1ÐÈùñy²Œ¯|åæßùH—úÃa*.@èºüÔ ÿòùçç—›Á¸XÐ5Ev¯û#:zŒÝ2MyGóûbîZGD"Îa]þQ·JD1Z0’‘R>‰©ÖY®»Íá…›óaT’ÎÝУsÓ €ŒJ$d-)#¦áx²ºCîÈSNx÷ªµïæi*Ä…J‡øbÕ¢áðAJ"Ó4j­aópÓ¹ÌZ«ˆäÔ@­s4㈠’Œ…IB;*’BY9M³: ]'Ò²C„ ‹t$‚€ÌTµ"RJ=8¤œ$%Idz Bµ'K€bõ%à ÑÝÓ¦=¢—BôÎm,Œb+hVÀJläÝ!L–ñŽD’Àúf´P˺: ó¿š*0·`A"kâAÎfu²Tb™ oŽ£¢uôeŠº~à¼i ‡ž?ýÌž‚‰êó)ñˆN“"ºÃÍ£@‹¯3•ò–7¿ýÇþ÷Ý?˜ÎÅ£š ºéˆžˆÜÀ©MYjÔï¦%,î:ϵ.7f Ž*¶n“¦ÉÞò–û¾â¡w“jnßšƒ}ìcÏÝ/}ô¼±}ý¦Ä`l‡ÂïÒW: ÂLîXKE¦È• âd»>„C± ÷5:Ñ£ÿ öP„¾ ³ªÕjÕ”$ ›Û#ïù‘ú¡÷ÿÁ\¿»v›ƒØ¨¶ºceM¦@µ‚D×_ëåRû¨R„cù="Æjà) }f¡Ð?Ij{ÕËr,ÞWƒðŸÿù¾™kïð¬Ìê_yÃ;ýCÿsUOÒÜý¨6—0€ú-q/ªkÊ®m?©µöŒ}ý1þî3ó¾õ[ïÓW¿ÇÝÇq$¢$Ò¸Cæ¿òÁOôÄëHd•74º ÓeЏòO?á^T§¥ZL®±ögéÍŠ»kK#äIRÞ¥uÒ::T¿L‹Et@¢ä(ˬ <"àfêaªp$6fbN‰!;uý¶ÌS­eL‡¾–Z5†2D›‡ÚBü(ç®ï‹jM’ªSsp-³¹21µY1¶Ç·F&å!R‹%9"Î¥ÔZE—"!Nyè… £êŽp÷”ClBÄD7x³ë¥KóE³Ń¥¨7cþ¾ÌŽÚšty܉7w¼5~]ôçnÞ¸ HdÌÈœ$eD ïftPîæ0Epmë`.–ë‰M§‡µh§¢¹Õ=qGÒ›ND©iøE’èDélf ñI%sU#¢ª–Ó%ÁÁcÝâj¬ÖMíôT-û‡ònšTé }öœM‘´ÂMNh,6C;3PˆµÒaÒ§ÊøÜyyè¡Ý[¿õ¿p#µ èî´sÇ'nÞ¬÷öa1ŠüáVe0Ís­Õ«z$„¯oò®£ªµª: `«û†Ôào¸_#ÆœÄ̘™™Ô¼”¾ò͆-:Ó;?+3a†\«–Rº.½ý;yè¡|ðƒÓ^–64Ã2€²DÎb3Ç ‘t*—ÊÊÛ YvôûLlDrBb& œ‹ªš·Pk3ËyÈ™æb̘…Â7ñè£û¹ŒÀv§g•»íßxõ÷~ïùx@¤ZÛÕ±ºÈha³ƒú×:t}à­CÒÕk;{F§ûîëÿëG~Dd[뤵FŠA­Š„"RÊøè£ûûsËÆÓd¬(EW ÙqËçŠOÓr+S2jÔÁÝ‘8»©¤í²yhëÔuÁŠHnZ¦ë¦Vª³ÍÅ´\¬¥+`¨u}êÆˆ$¾"Gd„˜x¤E°pO[á\k!Õj1 q\‡R-YPH‘S…¹”—÷¥sww"‰|½¸Ë˜±M»×=`dp’Ä„„”k-Ìì¦"‚„k#"l>S¤‹"²¤Uý¸êmݵjEt$)u^Ò›i©õ<–ì²kª¤¥l·ZÕÁÀZÍ«:a”3«ê…JÇ +ÂÊwTµR­L7â½MÒ#rêNàpþ$‘çhAÂÅDÜ9³"²1-9••ÿÆŒ¿û‡¿øU¯7 ªGø¹û\´AéM½)ó˜éæ=1å^~äÿæ?ü_~\Wƒi6÷Z+ƒQXéˆ2Û¹è\‰§ª…¡n](“ýÙùy×Ñ#ï~ÏÕ«÷Ôic“SJ ›|×u¿ø«ÿ¬K4ô!%ŒýÒ¦—y®‡©V×êf1k±;4Á?Âê$·%‰(%Þï'ÌLBLfŽ’" 0‡™Kb(E#ù :«~Èñoš9¡ã_ÿý_öÐÍôã?ñ™ýáþ4„ð‹ s¢qV&LND.@^ÔLU/IÆD8—v y øÔCyÀj–’0S­êèµjJœZ¤šÙvÛÝ<÷ûéž{6»Àu82Ôüñ_|ðõ¯y§yý|gÅ(Ìj¡9¬ßóí|üãÿ0üK†HU =&ñ =ò_ï”VøËÊm*ÕžÖ©ëè?ÿîW¾þ‹Þ¡îµŒ!€ µ¹ 0’üÊÿý^Ì ôö-D„/¥øÇ”ÛêÐàó!¡,m;HqÆl´Ñ׉»eT®…¤m K×oîUx>¿°?4f{d„ÄP9õG~÷ M`[F(&‚Gi LµªZk­µÆìI„ÝRêÀKëšKÕNKLˆÀC8)kåe¦ˆän"»EPs€¢Xæ~ ÷CiÎ}ß]ANZFDvD÷‚‘sŽˆ’À‘ˆ#/>J(°5Ë28ê^ܼ‰U]ÁÑÁ/eÏ—OÛvr«ŸAcÑʤ@#È •½±|¶Ñ‘ÜLUU] ÆÙ¦Ùvo<1"ÍãóëO¶aÚ fNCnªNfEut+³‹øšÍöãá+¾Øæ¹Ö¢Öîqz ¤l+Ê©eó֪Ĕ×¹$Ù~ã7Þû‘<ýåwÅ~–÷£FW%BÊÇ=£šGÛÁdªMÒôã¾Vÿú¯¿û+~{× ø<Ï5¶Ôª°Î®ïê\?ûÙñÝp¬}޵IüF)Æ·TDj|ȼ";§Þ"’ B_Á±Ë¢fˆðÔŇÞûÞ?yÓ›îú¦¯ûf®K³¹®¥.w럕V‹ÍL×%­fÕÔI6ÿoÿ{ïÿúØg÷÷ç>'r'kz€[| ¨œ<°Qˆ˜æRÍÛ,2Š»a`bÉdZ)™V¦HyH‰¢ u&º¸£îv²AKÚ{¥ÿ×ÿú™/û"4ý|g `ê^«ºÑÛßþò|àÑpˆ¼xµK¥Ô— R­öÓcG\,lŸ± ¾õ[îû«oü~B4P ;©:R £ÖªŸøÄõ{¥£…9ÛTŒÑ²4šâ(øÜ¤ÖËÌ!’¶yç†bkZ™¶œJ°Øä0ј8¯Âi×b¹úlÄÉ}RânÉXsH£‚B_Ô²^¶ô!÷ê"W@'r5rg&ËÑZ 3Ä.™MKU'´x­ Ñ6_NëDÜ`g"¸?B N]´ý¦aÆô”)w9DÖoŠ$t53õyž‘£w‡%°Z´Zd“ÅŠ™š)!²¥ä6SÜηŸ˜!‘¯I‰ ËÚ¨XÀ” R ô²®ê¹5„§9ì=J22wuº±®qHz0sJ«Óê <«Ó¢Ü$nc¶gŸ‡›HCC`D{¢Cð†¶ YŸ»×Z[¶—/}Í;æùý賟íT9¢““Æš—n.Ê–óQ//Ðy¶7}Ý]oøâ· q¿7¯jq2¥DׯQp}äw~ºŽ×ÈVª6xÝ\ì0Ö²|, ÑT«ZJTªb„Ô—Úv”¸‰SG“Äe_Íñjÿ ˆò[¿õìG>ò?~ñûïùŽïÏÒ;€Zõ¶€¶/ô¬`šf‡ s‡:§œþÎüÝþ??ù±=wŸõ95“ªÕ%l. :A5$ îZ“¯Û"027ƒÍ†Ð2ˆ¯¾û%_º E(g©¥œœ¤ëµD.gÓ‡exôѽcE$Õú¹ÎJÕ˜©ª»™Ò—¼ê]ßôMïÿЇž¼¯ö]¦xÙñß­à¸x#q¡`㲎/P3øª¯ºú×þ³Dઅb M¸Ø¬#Ö‚\õçOþr3㪴¿lÛc²|\r¦—B߇?€w’¶€H”¢^#N_Žd¤d:»;Á")mçwcxеhWóÙ"ÇSoÕVüœ‚n®nMꈀµ*¸£°#º5…€›VÈ)#ÑV„($Ò*¸%î"nR”ãÇ 2Í_€Sì¦JÈ,Ćm <¢ôv[+hÉ=gw­eT‘“YÐ&H„8‹ªÇËMMuVuwff‘¶é\¬²ËöŒã×"ÆÐýÛåKžX UŽ\=  x|þP«š+Š8âB°¨ÅÌL„Y$Åðv±?‚›ê6©€ ‚»iA$³²”¥µLPCd¢Šm6 ]¢ÝNþé‡>ð]ßòCÂá©§V¼,»³(ͼºOÓŒˆ¥Ôóóƒªå.}í_z÷ë~ìý?ÿkõ‡NvAôˆÍOˆ«Ã /0f j~ã¢|z¿Ï™¾áîùÊ×½kžj©Å¼ uãÈD"]…÷‘¿â楪6T„K­‘¤S«ææz ¢““¡VZÙõk_/‚¿úk?ý]oyÄL?ÏY•ªKè)"‚A}ó×¼ûÁ?ø¾÷}*9Þ]º`V…’è28þxÅ´êí?[ÆÃA_÷º“÷|ïuÝvœö„†îH Ü퉂Â]Õ˜ùÃ~êf"ˆÚ³òbŠhJÄÏ'l¸­»'„¦Xj™ºVsw®¦8ñ%,¼m†ŽSy VŒqB$aJÜd’pGdo§6ª«jnž°ÏÚ–3±Y¡R! X×§0Ì x4ëá2¡14Ó¸ú£¸›ƒ³jíåHBÆn!½ Qz¬W[ì3¶È#h?­ îD<À\º[­R¤ŽÅ]UÁÜju­î®Dà@HnHL”½Á“ˆXµº7¸·Ë5íníÄâÇ´D²¸WKV×s÷y6D¤ÜN,ZqRˆ‘¢è­Kw¬¶'û+ólÁÜùèÓ0Ûm¤ëXºªmŽ[Ô‰MxçA$BDFS«jàÍ’TUss,¥DyÒwtOéJ—ž~zúÿè'ï¿¿ÿwþ@×m¼ hð =+"ú¬ªÀo-U¿ôÕïøïÿÞùOýìûîp¯tKër™î£Rr$‘ÛaEKp ÌÅ®ôI×ýwˆžΞZì:X¬g£f¹z5—ÀQÙÝ+ýïüÎsßùÍcp„_ò¬XØÍR .Tµp-¿âî·þwïð³¿ôþÇ?l˜ÏJ¦Ph.‹?F:™ÁE©Ï•ùÁ‡wüµw!&wr›ûœŽÏ*.+‹_äôZ)±\¢[£ãC`<œÿþo-–Ý\¦‹§ËxÓL6Cþf˜[VébËħ«ÝG1@b–¸ú™(9 …lQQ8¸ÎµÎ³-¬¸ ‘E€–TXDjqꮈÆ‹µf‚VcE Æ›Rfwcjëïõ Nœk6®¢Šxo"a‚èñ½6ÖI؃P˜Ýmž ²Æ¢L#t6X¼½Æ ´'.`ð'aıÄÄÍLÑȹ€”É[œœ‡ø3âé#‘Å „‘e‘2ßvb ‘‰ãy@ÍÊåÚ¼¼ÄœE'Á2„ûr6¡|"J« …XRwpSÕK¥vÿê¯ýü{Þö£j¥®H²#‰wU›æ2Žóùùáìls÷ݧ0ϵV}á…s3?9ݼúþ·ý·tÓ´ÿ·¿ÿßýÝç÷{ÁÛRwÎÎÒ×ýÝ_ñð;rî¦y<¦•öèñ0§$‘œbùÿÙ{×X˶¬ªêœ½×šsŒ‘c̹ÖÙçÔåŠN¤DJý¸ªª[gŸ}æ^k¬1¾ñ=JEBTý©ŸúÄ“0D²#bßK8é’f¸:VÀ„£®ñbO]ü±”H{ä.Æ€+A"µœª¢³1àÎYš¥á >þÒñoýíøæ7ŸË7þ¥q8S-¥”ßÏYÝÙ¥ÄLhâŒNS]DèÛ¿å;Þñ®ïý¹Ÿûô32îFhâ%çE±ö}´‘Çqɽ{YÕˆd² –"Îs2ƒq7‹µ‹¹,uƳ³´… ™PÉcÎôÝßûþ“oû/j]n=«P–JHµJS!XÍyú+ñ?[ÊÕ?ÿ_ßþîýjJø9“÷‰UÔ#çÔì“õXŠ=ÿüôW¿á ÞøÔ׋ê{:{ßÇæ‡CÞ£·*¾YCòã’ªó\ŽÇe¿žyú‚Ç||tD€œÙÌ>¼âG8N‚ Äô¶/üæ/ùü¢µ.»ý@„Œ ()íTJ]‡G»ç¶C{‘Ÿîîˆm´aȵ./¾8ÿiG»³ZíÁe=Ìê¢ÉËC€©ùœöyvµ,µª¶ÍÀïÉ6Œ"2b©Â‰SÚ玂9‘ß~jöÜÒ}èê¿ý[û‹¾èî7}ýw$Nj ž:þúÏŠpœÚ ^zÊR]·>œå¯ûw¾íÍoþ¡ïû¾½²Às¶KiåBõµR1uÎc@¢Ò§mx”ê /\t›' TZQbÍ"ˆ™ó·81ì÷ü .ÍŽc7±À žÕéCºz߇¾ÿsžÿ3ªå–³bBò”¡xúEj¥M˜óþÏþ©ÿô›ÿ}yÏoýÀÏÿü§?ðK›.4? b9ã—|ɽ?ò–¯»svöÌ3÷hàòðð{ž€MÓH„yßõ®—<ÀÕ} ÌÜ07zp5ó @¢® Å×X.ashK.X23­3"9EÜ ö<œãªý²FcÌÞ@¥áÜñ\&Õ¸jš¤ˆP¥FŸÙ‚@) 9ÇC¸–,©D ̼÷Dg§kU·§÷ x ¹ €±Ò!œzÚÜ3Qö»‘8»| çYàíE°u£ÍGÁD¤:&M”ªÐö­Â&)”šHÜvA1§·ðw4iÀµÓY@7áä‘Õg'Fd½_1õü¨¶©¥ˆE°me@pâçzb¢¦þðèåuÛùˆX] ŒTÁz0Ï»OcÛM)€dREf·÷¹–˜ë4°©ïÒ÷ý‹úÿüîŒåe®Iˆ(ªîøûÌ3wẏGGXúŒ¬º{ôð`æ)@\ë2o †aˆ<5#•„p]ñ·8µft[‹ð`)’眪à¯üÆ?O w#çLž[çfû¾Åº8ËUôÎÙä\Ñã¬WZ“o?†Á§ Ëž· RÕ €¾#V&º:,ã†aš%„ã¬LÀ “u¿Œì=ïyðß¼ç¿ûãüþ×|Õ|8Må÷wVnHêgåüüÞøMÿõ_¯ÿÃ?øÎ¾z¸/ãÉ XCqŽ‘FNVU»¶ò€Ï~îO"š¨îÆÁoöÌ\EÆ1‹èå¥g>“3.î쯎峞þÿ°û×iƒ›SÂûizûÛ?ø_ý—ÄlVož3‰…@)H¡ºk!Â"G†ôÅŸÿç¾ô«Ë¿üë?ìÊÞŸ®5?zxxøèj·)ÓáááužÕ0$3º|üãÇç†i£VÂ.¨uk’wâÖÜþ¦r©±V›ýè_ûŽ?©²gÎ;Ncž.ˆržî!R+a†Èľ wÜ®ÍIíæõh&WWóú⯠˜)nró.ÝDÒßRU ñ q" ¯ÄVÆAÛoc'¶û8ì‹C N9åwšŽ!4‹"²T©n$ŠM$SË,µ¨5 Œ•Ð3‘\_ä7­oRRbæä­Q _Ð]¢[(7/&ñªÒ†8c³éß^X+©·~³zîú°…D뉩:™É—¹uwÑ®iFüùwüÀ³44Ž|gŸ¦ÝŰ{"w8ï8ï‘L9í8í‚Än9j±™™TçŠÞËÃ_º:Ö÷~Îü7j-ˆ- àòòX‹”EñÙçŸ8\Έ˜‡Èõm0\^ÍCN¥Ê2—««Yª‹©Ý½ØiP¹9l‰í¦æA•œ–<$S-Eæã2í†ù¸øGì„ÊØ)+þʯý«òP Â1$gr{3jè{äð¯ýÖ«¿ôî_øÊ·}ÓHŒfö•ÙÝ‹]­ÿíó«^~ôë¿ñ¡‡“q§Ðù=䉛ÚìLøn/õýѯô) "Ò†UÔ—f0äätob𦢾ðOÿì»î™©5t\{f|(õ=ïû×_ñåd™‹ˆœžUÕ¾_æÒY»ÝþÅôq¨µ&ßpÿ-oz×=ÿÌ®Ê2/ó¼ Úï㬞xâîÏ¿ûíïÿ£{ÃàbYoHSB&bÆ!s·ÑBÄ›­¨]÷fÝXüB"†Ý±&n+)—œ½ÞQT–æ›´§äõ´·Q¥8 Œ(ÍÙˆ|ƒÜÓÓbÞD"ÊH¢*ó¢ˆ0HZBÆh-T,òf×MQûÄ䈘¼ ¸†‘‰úž¾‘^‘1°Û¿ûNPTKñv‡4 a£O9%Ó³ÜqÝ:ˆÈ€jâµÕ‹™ (‘¬¶˜ÝãÆË††QKDlRÕ¬Và‰€ƒŠ-/À @É­w€‡Ä z˜5³q`Äâ”) ^F»ÝUa.9d:Ûqž.òx×hÝ.9#%N“Ô£?Í„xðÁ°g€ÝH Àr¾O®ªüá{¿ôK/ß¿ÿöÞøM „¥ˆˆÅ‹Ýn7"Q’Y–Р ç¦åÄ—Wóñ°0“›¥LWWó£GÇœ><øéyÎ~aJÄD¥ÔRùhþóú÷þÝgÿè—ý…Rÿï9+{øðêk¿úÛ>çs~ððw©Àó¸óV´µ¥ â8iÐ*º}úéqÈãRfù€kÜÇZ f¬BÕÄLDó0t]©š1 …'ÓsyúØK‡ïþ¾ÿùÏý©ÿh6I­Û³2€“³iü¥D4$H̪¶ÌrNH¨E‘Œçy‘ÃaþLÎêòòòïxѽH¼Ít<Ô%ó €rŠ&ß¶uê‚[o|8;ó†ÒH<?·%"áœF¤ìt(ŸF×ìÓêª[ì_ÒŠ‰DsÀ¢¸ï™n7 €j‚àöõáèÜð‡8£ÕB3¥póõýu)•YÈOöih=£´÷hDÃ8¦qpÕ{ÿ‘[™VÇ10åÑTDŠYmÏ"dÀͧ[³¦&R<ýi–9ÈÿŠê’v[gu‚|˜¢£qbªíÄR¼§@™¶‹Ûrdê’©Å'Øa.oÏýñãcñ¼h­¦RܤÙß#!¯‘fT!‚ð/g "Ȧ)#ªÎ’îFúÂ'/~â'>>õ÷½õó¿e^ŽZõx\¼Ò•Ež}öžV)E\Ùˆ{Z‹ CÚí8Žy¿{~½üò#¸ÿîn7¸K¼ %\„^ŠÌKmÑ "Ud™ ¦œR"ú©Ÿþñ‹]ö+ªÛâM#™¦ÆûÊ^6‰¡‰ÉcåïÞÍ»‰WsøÁƒ«Ä|¶=GÞóY¯®æ!'În_ ˆô w~áw^Š PN„ˆ›;½wWZÿ÷ŸüÄ/ÿÊßý–oøÖqÍ`™ËgxVÓ˜–R_xãŸùëõá?þþïùð'¯žÍÓ))™Ù8ò²yl,Eßô왓qì圛Ùôþ‰Ùºk Æ>ú:»×Dpà:=»~ôðC?öOÿÒ·ü•R$ö³r·EÂaÌ^†ê":cè>¶|#ÀRªŠ}†×§ô⋯¾ôÒòÙw΂ÑÔâ'|¨÷‰ž7T'ºÍiTÃÅ'‘£waœwÄ#ñÈyßøóØê]K=“‚ÄHÉÌT©s]™z—GáääÅÖ»×Ó8 ñ& ‰ÍLdq§ÂqàÖ?›i1­ÞHnËÝòWŽ“2˜J=çãáPçEKµZ+ÒòŽÓÄ<2D Ú›A·ª &‹’VA¥qj›—•4½}åDÄ­”;Ë¡xœ§j5«¦b@`Ô÷ifB”“àGa3 ¨ADk¸ßG2]“íQˆÐÎSÜãÁO,]«îƒçu£7îAÐîÌL‹Èq™_]ޝ,Ç—U–º\ªÖ–‘Ò€Ôã–mŒ”(æ@Â!SÎt6ñÜ»óŽw¼øKïyû8îÇâþ’ó\ž¹—rººš­©¶}‘¢fØCr—xsßæB„»i¨U^~ù²I‰K©‡Ãüê«—¯¼òèÕW/<¸|õ•ˇÇc)K]–ºßؙـÌüÞ÷>|:´ÅÔXˆ>ÚsÞ©,Rk˜]®¡oyݽ›wû3Nôèá±yê©‹;wv-.—MmÈn»´‚½ñûË¡zz®ƒ¶~=w<ÁÕ¨®><Û¥ÏÚí_}µ|çw}÷Oýì÷ÎK}îù§iÈŸéY1—Ë þOÿßð Ÿõ,9.ã¾PQ˜géz-3xÀåK¾ä^n1VÞ¢“ ]§ç³…ÒòbÏ??Ñ ZfFf2=?ì>øÁË¿ûþÎyFjs²³ŽˆÉÙï¢ê…X{4‘ÂÊÿWK‰¯ógx]%ÎïÿÈOÓJZ \£Vš2"ô7Eô=óøqä'þkùëÝ„‚x@ÊH ‰Ü<œÉ‹¥a+^rHŽ8›Tó²"‹Êñòêø¹oýzç!…{_l¨Z*ºÛøHÕ¦ÉK‰zÎ 6mbäÅùbs~ó—j1,2—RÜ";eÊ sÊØœbÈuÀ‘¨ß„”Só¦Ãè=¢oU¥úÂÇvÏZÝ[ÐiaãÏ„H‰yÌiÈã.g§ˆ¡#!ä„Ja„ÜÔô𬂶ºM뉹T¿ç…ˆÔZ}ÅCNÁÅ2k[/¦€P±õNL|ÇÏù>çŒ9ó˜…°y$cœ19±îsD;¬ bt0BóîØ]ǘñ‚ó¿zïËï}ââóEáÁÃã˜ùþsO,ÇÅu;áÞ- ˆ‰927AŠ‘Ý­º,õâbŸs:fê]æè2gJ‰‡aØïÇÝnd&GÄîß¿ëΰÆ)}ì•þÕ_}õ™Ý8ñí•€‘#k Ó‰Ø)²Ï8ïk¹:Yèo»]ù6nCN@•°ïò`" òl hØ´…·€Q[Ì€HçEUÍùex•¥·†Z5,,•}o£ZL‹Ïò®u±9R´¥*‹Ù© È g_ìta+vŸE ´•0#å€)ƒ5Æœî .ÞQn>žÆÒDr¯“ W©¢±m-Uú¶'LI¨i³¯X̘Îq©U«h&1UÑC¯Ýwƪ(Ì"3§I¥¤áÌ´¡Ø<ÄéÁˆ”F8¤„‡£ ™Þ‚wùW^ùµÿó{¾ú«ïßòkŸ|ò¢a"$\–2Ï%„^„€ "f ªÌ”ròTtïARN®œ¹{wùèhf»ýxçή±Rú#K©X«ãp<ÌÞ)¿ÿýŸÁ15‘Ÿû÷ôV´ñ%P-¬KÝl·žñâ"€ª‹Ê“TµaÈ~íšš¨úæ(- rÚçÜ-ým)êNû”ËŽÓÄúBÄ:`úYiÿè²~×wýΛÞôßþ­Yk:ÌGùÌÏŠøì¿öÛßò–øþðawóìRÑ**jO>9pÇyõæðá]TD˜È©Qˆ«)†¸Ù¾ü-ßðcÿÛwöNÍ u+¹ªž‡ÝÕUý®ïú¯øŠò'þ­oÍÌj€¸‚~%+0BDXŠ€UBª"ŸúÔfRÑ'îíŸxê¢I)3ó2—¹ˆ) C&ÊjU I¤¼røyh´¯¨æç~Û¹YÍÿ´ó¯а½`3ecF˜…Qôâ,ï…?ò‘Ãßø›ÿãW}ÕÓ_ù¥!1ø3˜ÑÝò½Îx.7µLÐ*n2É»ý´?ŸrJ‰Ó²,j´/ßûÁù¡úÝ‹!yÖ¾ Dx¸¬Ÿõy{‡äâ7¿ÂEµzt‚[4¡Ëò`3Ú¡‰yòÏÝçbmPµg;#Š56NNGz×»>ýîwÿ¯øŠ'¿êmß8ûœÆ”ITÐ-¢Å ÙÀ †q`¢Ë«e™%g;–”"\Ü=úé 0›çË¿ô/_}õðÒK˧>5úÓËá Ë¢‡ƒôùeQF ‰å6’áö;o9{Åt;ÇC]Žì‹Á>¿÷ Ò‰góÖߟˆJ#ZÒ:›i›ÙqkBkÎHi2“öxR°5wœÓ¤2'F/š±ðm!”¥©A.A€œi8qü¨°‰ˆ©ÕýЬT›Æœr«ì°Ñ¹Œ>VL¥ÔRuéwÎi¹™{nˆ“]±£ÕPÉbÝ”¤ͪ#3Á{'çf1PºÖ'šn–WÔ|íhÍ^QëÂYB7ÝêQªÔ¨»×N  ªqc1H Çsâ6³¯úEQ•–B“3ç<„“"îFÞïx9§XÙ¥´OãÓkCüÓOù§]ÉŠÈHy˜žr0ÁLÆð£B<§„Ç(F_˜.Ž‹üâ/¾ô ¿ð÷¦‰îÞž}v|òÉaùîÝ)ó³ŸÃåb“CcªøÒåÿñëï}éýï´,Ú…Þ÷ïO÷ï»ßâNFîÆÇ~õšñ²è¸#õÌpÂ!SJèÆQDHiâ4޲ô8ߥ¨—oÖS)vyùj‘WŒæO=zço}¤À‹/ÎùÈÁ½TáÞ½áþýqš8%¼w/¿áɯÝŸ¨ §Áu®¤dª°¨9) ÅIÔˆè9šGùÉŸüÄ{Þó÷¾ækžýßýgU±”ÙÌæp®b&5$ŽàL÷’’”G¼¼|õC/þÄÏü̧>õ©åò²ŠØÓ4îÏ9JE±»´¼õ­w—RÇ‘óË2§ÄÃ0G5L‰Ý·Øá«€|‰ kEÅ—_xáÎ+¿]¶Sïè#'ÊÀÈ|´=Û¥¡Ò²è;ßùâ;ßù÷ïߟ¾üËŸø¼7Þ»· "¾”¦”ýÉ¢ó'üèƒå7~ãáË//¯¼Rz:¼ªÍ³ªÚ™¦ÜngSœcB„0ž~}lgŠTÚ¾‹§Ë}Ï;‹ïít=M$ù¸a÷àF2­³g—ÇfìÒK’©¸}‰J¥¸ \]Ým DŒYr¦²è8 ÓÔ}6 [ bH-¨+À0xrè°q²Á(£^ëqYÄo­iJ^²{fsù‹½cé£s t.çÔTO]q„–ö~3"’T¬–#€9ÉÔñ '½‡:´§«#zá3ƒ+ fs’šÁÕÕÑ!!O #¬9S)šrº37OÌo†¸)Hi8 ޱ+}1'ÚO<Ì„œw¾ï’z0S››ê52EzQS¤LiÔ:j5‚¬î>•`žf7±»}Áp¡fKÑúŠ}âÅùãv±ªða5Ó¢´gÒi|ÃnÇgÁDYŠÖO؇÷àÏÔ~±–ª§I8j[GwDxÓþl‚çäPOfôòAùÉùpGêá p!yèNž ƒcž˜rCŽçŸþÀÇ?õ±>ðË«+ñ¶îö #î÷< ôôÓãýûcNXªºÏS?ÿæËé^…PŠzs‡H9ÑP ®>Vÿå~ìÇðcÌï:¡¸‹˜÷•ç59X9a·0…Äã5Iëu…+zÿÈtšb¶:ÃÉ+iðûNéq|×ø÷ýáö¥¶ÏÁ¾;j{ž”6'êsv™S+=Ly×î@€iâžå«*H„€Ì®‹÷âb"nT“‚¨»5Ï'×yaZç­¯ju”†9”þ…Rº±¼™bã ùn€\M@œC©ß´§€î$•À¤Z˜ts:qÂö{ª°K¼/Õq€{k5· J‰r¢±U‡^¼¼’ŠTuf‘Oô„X)F`"Ÿ÷ó^R)zùáúÞ<|> €µi„o¨ÍëõJOŒCŠÚˆÚ™’E™‘ÇL?ü¿|Dõw‰Í³-q :K©ÃÄ×¼ŠJÕå¡Î*¯üNùMxä‘ê¼ÑìAF*U½[Lµj˜ñ ™ÁÙ>í-uba-× wbzb<­’'e«WI³ø7þjÝn‚V'ßõòðÄ{g{jÞÌ]”å/xSzóo:CKÕÂ?ÃM®WÒØÆ“†³SJ1 > 1Í>èlȈ·Ð®ÌóýWΩý$ÞâyES,€“lt£ê³|N”SöïRëB$Ž<˜³|dñ »jm‚+_˜»öG·ÄÚÌ^U ˜(ÈÌS³¶S 8Ù@Ô]‡œÔ€#‰ºà½(¨ß{9S² 4i“‹DÃR üµ¸ŒßÂlͱpßN"â4¥¾ÖsRD?1CAô«ÓS¿ÔDM¥¸ ˜§D 5uâ°ÊÜt\ýrddr —Û_ÅB?* p‡Š6€ûÚ-EE¨{ëö47ÁëC“*lç2jžÍn3ê õûDDoøø‚Wjõ:·ëÊ#”¥]ë~=t¼w(jâ]É4p!õüz3Ø‘TÑ‘ÿMÀÒÒw¸QfGÞÜ“âƒ@“¢ÅEÓ0Ð$¿c—âåFÙó ‰LȘqùä™ñZQé!gÄ“Šß#ì“û¨ÖªLxç<÷I™y ¼ô/o›fS£Fu\eÈ^• ·•·Wð*š“Ÿ|ü79J¾¥~5nãªNˆîþ)=VÕÞK^cæba¦'7Šo7· tóä~=–N[7a¢4Q¹<ñ¾Ü‰ºe\¸=!sšt›»›&©G)ÕÂi⼋mI¨ïsd‘{ÎÁÆ¡*òºEÄÎ Ì 5Õ£S/C׫·X¤Æ7Ñf–œBŠÌi Á¨‰¯k¬Ð¢R|ƒ`áVµnÁ¬š¸¸ÓjYl]ÐLÅlÈÞ# pHÇZV±jä+¡¹—]Eªbµy AórŠ–Ÿ´¡ Ž8¸ ë‰\?1µÊ*†íŽ S§Z 8ß'gM2Oi8ýÖð50Hž±L”TJDÛ›!¥Æ GšA"'•…x1Ó¡Ÿ9Þ¯iï({ïyb8OñëÞFùæÊÇy/‘ýrëDlj‰TÚt{ }·5'±™™Èl®g€ýÄUÌ÷KÁyËäïÎõé½£A\Ûa3 ¦1¯ÝaoB·IñhÆ‚±¨ ™j²Ä¤ê› Ø6ø·…>ö¦LõÔ¢éfÝva^=¡ÅG#BFJ*š¡èÉÆë Ýís}Ã-̼0å6;ùÁ{mÿF¢6DI]1~Í 8­t£Õ®Ç-5¨ÿ~½À¸§1®½ª;Šzêôµ’5ÑDŸÜ_ç£Ëý_§ÑÆ‹n¡ë'Ñf=$Ïê þƒÛª!Ì£xb(a­of=®CRâœs)•XS°gDUˆÓ€HF7‚=ÖÂ@Ý8£é‹l]1˜”yY¼C™F&º¨©x¤6:½·ÄmSŽ„dX«TsJ€SRœœågÈD¢Ùbi=¸£¨ÓÊèêë#‘jF( ‰›±4 Û°6O&5#‘ºøf©˜1sN¹V©V'§"8,šx@JDµ=ù×30 ã?1 ºÏÙ.y‚©þ°{Ê! 'ixªÝz¶*¾n !–)‡±˜X™(wá†; %0S®®Í²vP7f÷ßxÃÒÁ&ïÓ‰Ð5š8Žâβ޷ª­Å«'šù°/jW^‘âÝÄÓÀÓHC&ä‰27'^ÀT)®l™HÌ"”ø0k3¤Xwþž³l+5@%Âó}Úb .Çv(°W:µ@T&ö‡.T±”P Ý¿=%T`¬âòhì<Ö~hýÕz•¼Ù…ÅF$è!ØSá¶5ÝÏ-g‚¢}{r³ ;iþz¿fj1§µÀùjž¯Ç»ûã-±s1¨mü‘ÍÄÓj¤öúècÜÒ!„@—Þ\6vùæ­ÛÑÞqíeT³!Q‡>^gCzRëýcm¬ûvTÛ¥6Q‹¡O»kp”+ÍD‰ÓT¸FˆÌ£™ºÚ(yP³¾™;‡zÄ¥Óà™R¾Ž(´AÔMí,ÔâæOµ3k]:÷s@J`ØŒñ• t¥nä\k­bµªGÑ2ù7ùöÆs–DMj8’ppqY“” 1%ŽfuKq:W“~3§ Ö}=œ¬é{lbPV=§“̘Ȉ ¤äx®‰wN!L¡Û¶oÔÝ[ÜÖ*¢2fË3Ýíã«d¹ [R0/¦a)Ÿá†ÝÓuyÜ-k¦aûi‰28žn¦Z‘sgÎ97ˆ‹)‘ƒª¾’ÈOvN¡np'énî|NÔš"ž@â=˜Á8'žnqÃ*zqžcNA‚î6HÔyÐBdZ‰©³iÙTêRÔF„FÝŸ#‡Y¼:ø`èb¤ Ð\›NŒ6ùhþóŠìÑÄ)ÔdlþÑhôA¦lñãÔ]°ÙÉfb{›ö*ãe”p-.Ô ºíïU×< »µ¹»¶î?#aºž‰Ä2m^Ö¹DH©J«¨ÃÌ¥jF®u{„[ôÂóâ×ññ±Æ›bº¢·"ÈÛNÓAÒþÃÒÆª™Éúu–Ñ΋Š^ÒÅÚ€LœV~(%P5pr~§ß×¾£'jK|JȾòµ’pÒª¡Jç¨ÞH­›õÙyß#5Âê ˆ 1uÆv;ž`¥è82› óàx@°@|Àˆµ–²ÌN ”23ä¬^4 ÌåPJTn`\ŠaN@<$‡‰rh"‘ó*gBUÿHœøiâ„!_ÓãÚïo‘¾­rôÖ!ËJªÊb‘iÎÝzœX991¿!9ÁÑ[—*É\ôp”ó}‹7C¤4†‚ø8 ómÙyË–– a ,|ÄóWü7•…`t«=ÿ{Dvˆ@C ‘‡~‹—8vå…ûªª$2ÿ€8ƒO¥ªf2q<#‡¬»)ï)8%¤ ¶2¼†e‘Ù@污™‡©.qÈd¦¹¡ŠJ&b`°V3O~±f/mÛ=Œ©j‘Æè÷§—Œ¹0¡Ú5@FUŠ#%ˆ@•ª&ô¥Y?-Õu<)«CíÉÝ–†ÈQoúˆÈz„'œóm¥8)O-›/äí˜ÔˆD~ C¦¥Nê Q •‘N*•nD}·VÉ[KäÖSfs §Uumï6[«Þ{ö“­ÑvsÕ£íùo5F©uŸÑRsÚ5÷¦Ýw'޾t&Ö6Ê© 1¹J=ÖPazšVMw´H}« 닇3qù³Ú_¼ÿ³Nºlê̪*f2 Ý º»Šºß©E*nwˆhD‰Ó Z®Š| ºÂ@£«ÅÌÌœÔç,3óÇ7ÆO½çÈ€:^m=n^Sp=Õ>¿ûù5jBtIíúƒ*ž´iZí´=ÇõÐ4šU÷‡Sìú½ŽPBäœðl—öÓYï %ìóxÛ Å±Û\mWdÄ8_Ÿõ¼€’™˜Ôä }SñÁÙ™–Èm$¹]3¥SÐ`­û„” ]ËH±Î‚Þ¾®½«ÿ“ÚÀ‡Ê¡k ¯ø[n\tµ”‰2¡r×›V5S™ö öm0ƒS,çE|é"Ò«Õª(eòJTªöº9eößw’¦ ½úô×GÚ>‹0ƒˆ1Ó("ÞWÑ©­_â¾í¯pâƒ¹Š‚pÛXõ¾˜ÙÁhŽ–°Ôèý'ˆúóàF/Ö«ÒÆßºÉÏ{—·íLÛzDâ‘à¤.mŽ*½Ó?)NzÏÛ¶Láû~éq~"ÜöòÚ„pžzùÚ#wVr©½’Z˛鼕Õà­Ÿ³‹|°SâÁëQÓP¶• ò°„Ïȵ^‚œ>IÜò£wÑ$4e½[Åx{k?½Èr³6áæ¸ì!E±N`Çpïo¬ÅÚbrÝcôS:ײ¨Yv¶XˆD ‘sæÍxêö6@žðáÔ("°Z–&¸ìþ§Q[C§ßÓ:ջߧ™" ùi‹¥n`ò‹n'vÍ8Ô I-´ù« +œº]/ò“ ’­ ³¥è(‹Ô#çAXöùD!Ûþ ’QšBŠ!mïmõÇd³•B"œ ™Ø¤yž€±Y3|QŒN5wÕnïm‰œ´Û}Òê ² š3 À 7Í* ˜$_–6²‚óh”Í”Óä;TDžð¨R“¢K9kµ1Ç C„Äùç˜E5Ö͵5¾×ò‘)ºUQŸè½;óØ 0¨ N`Î "ºmbðØhû¿1z,r·å\Ç³Š©ŸÕD¬¡·ÔW!ˆë‹¸çÛkpÎ m©H7Ç來b·#UC$n\ A^Ý¡¢|œ¯Ó5ˆöÖ¿ƒÂ×NF ¯÷§|}/¿E<Ì®BGᥑ^£Ð"VQ¸bMÎ;N U¹¸ž—o„üŠï£eïd=µ8’J]?Ó=6[23 SÙa5m2 ‘xûŒ¾Äµf+¥•x@Jr†Õ`æÖmD4t9}?™,µÔy"rØ'z…)U”wMˆ9l@['à—²/¦²7€ž ß[HÕ@ ,œç ÀÍôÜvl‹Y2³År L »˜]Áyð þª ¨ÌªÍvD†¶=1'4hwï7­Íxeݧ©šˆU±R âó¨²øÇ”ò™b!Ê*3˜"dL¹šÜ Y8N0SïÛ@”ÌÌH"oU+0pê.0'¿´ˆóuxŠø$î"c­³¿Nç„ô ˆ¤ñ`I«¶Id¦•ŠGDYµZ5Ü…Ö­›È ‘Â’€A‰dö|†œ‚ff†=I Ä`²C¢Ó°÷üˆµ™9$ªj‡9q×rf"ãëþèÑ” 1"d¡ÅëFÏ­» ­èà¤nöŠÖ×e ä´·vvá(xøõ ¦Q^ëòœù jh(›‰Â멈v¢˜7¶ÛŸl–èZ\‡wÖÛŠ¹%Û·LÖ—[L7aǸ[ Ù)êÖ»àÞ„ºY7‰þ² ‰¸wëðn§=â µ]—=ü·ÀYû¡½lybN5U@pÅÑÆ:Ř)¥hhœY\ÓÝ u’µ(AÊ®Ñ6d#Zú"&@[æK³‚ªÖœ˜«íú‰8a ñ/ ™ø’ÍÀ¢?vhS«ë‹û#£’#zü_k}µäTM¿²‚¿zVIƒ6ü©ÜßÄ´2‚Ɖ™­Š¥ªªF·~N”RvòÙõ3‚ iêƒm3÷’m&móÛóOewæ { éšÔ‘gƒ±Ÿ3P¨²üÉ‚0"'“êS¼™¨,]Fl­l¼®ëwoÎ}n <¡IãØLBàͦ™Èc1šüqíúÔ‘M ";ÇêÓPq/²¦Õ»u•‚ümsšDf¦3Óšò™ó¢¼2º+„’rpòp¦3Û[QÊ•©T1UÛOÜûÊÚ6þœ0v¦ Ö–òŽ™&»v?;¯ßÒ[‚×µå _ÛölˆÔöB¤v‹Vg«ŒÜÆPŒ„0ൿßn·r¢íw\í¬|"Ú›;J®2¢›¹Fý³¥tÔ²ÛƒnùL«½HC‡·ÈDz÷Úó†·]çMêØ-ÏÏbHtM'z=¿Ë×¾n,(Û†¼mÙêpº²‰crG"'<¥‰ÓXÖO©iŠÀH¡€)s MZÿk›ªíÏÿ*µª¹7Z ZïÍ»˜HÐôÛÀ¨v;NÓbZŽÇ‚Ãóè:%/ýF”ÀÔGZtb¥™š”öQ«ÓÀ#}™ÜÆžÚlj-üN`5yr¸ÀÌ4E°Hê¡Ížç°Ò?£¸¶ÌL«¯~=~–W@Xt¿.Œ2dŠ$¦U¤ª“#*ÙWLnv§fµj¿÷RÊgy¼»ý¸Ù¯¼n6móíFJ†€˜MŠ™êrEiB#J9Ršy@d©GÓj*œŒj(+÷ÃÔPiÅ[‡@u ÌYëÜ×hÖ—Ô1(÷ª‘aà šV³5怈‡Z.1âK{6,i8wÄ ”iZ‘X–Ë€‰|om6ä³.KájÖP• ˆ"YÚ™i/Ì4ç"s7ÃŽpY­*E%ˆtî›çË–œ`)ªɾݔF íõeKPGîÈf@é=¼¹¼¾ÙyUQ't÷’Ý©»>žö€g¤w|ãqßwC †þüðVÎyN@k-;Y9¬‹¶4û[!Ñõ˃KŽªÖ!¯}¯A†½F±º.¢ëÓÛÒ®õò}ª©GÎ(Ü•â:“Îl½ úR)]ãêSBÊDÉcD)F™ÉA@2òÅî˜Üñ;üoZU+hl¨ºòˆcH~]×-šæ‚N§ˆ†B)%¯ˆf: #¶ö^ƒWP×pXÐ*¨zBJó|ò…)<›½¡dÓÒîíŽÕ÷øÚ\v[þ½IµFu•ˆuk‰½~gªëG}÷Ý|© É´:WÎܨ4¶mÅL¤J;1ëÔ.0E³ã݇~†¥™ÒˆÄi8W)HIÊe¯¡qDÀŽE#¯ª €æ·¾C·~IH›{¡6–»ºf4 çþ¿D澦P`$nn NW ÜÖëñ Ž>7Áqæ}Z6yÚõ¹õu“p6½[CTa»AŠâ»‘<¬þ{¸À­¿òõ þ–vRßcàkWÄøÂÖÞoö5Jÿo"¼ÕféqèíM³»×€zûû–ÕC›ªj]ˆqê:1@²ŠºÛ¼»d¡›|5ó*ïNÇZÒIU])¥t-¸W·mµíˆÁ­µ©WºRû¾1ô]½< ×Çá“&÷dfV›–¶ÕB í5Ü@¶ ˆ­Óré›ô­X³Þpcè6i'XÿÚ“÷¶=±[ßXr%Ò5røÖíIO§âÑ´lX‡Øã—›I~{(: IÝçÓÇ̦ùql«'Öáo`‰•­±2ÜIT…L"-ÊÔùO?×¶ü¾pd‡ÕWá.Ê·FïçŽ]¨ã¡NùJvÊ1~:ë(6ç¼Ù®ûSꢀø_…´´ÈÕ€S}¶'fÖyï'fjêtífÃæÆª}Z†8iRW NA;±õnË“0ìópÎÃY³”­›Ç ”Nª—z0Y¬E20™(CÌ(Ô& §²Iu†üÖæÆäÉÙ [®h{ìÉÍçô¢—¥ÑÖe”jñ&`Ëu±ÇÖo ¤\)çÞÉâÊQ¾&n°ýó9TH„¦´4¾š0˜·uyˆ€i8ëý2Ty„@ns-¡g9>@R*(PLÍ¡)T1uÞ6d†龯ó×–¬ÓÇm¯§½®õ>1$^[<³¾ܰòn–­þ…'Àbÿ7-äkOî×L»ï †¿Z¯¡ó]îÕöäù´}“zÃ]lûÇDœµqv®³—a{ƒù§ý1‘+g¢Ü =$Î¥ª‚jÇ ¾2{¶¹™k ÷p—9w›FUñÖͽÐK†ÏÚZæ)”²i…ÀàXµ0»ÍpÀ#TŽá0.yëeÙÚIó›9‘©˜C·Öô¾dçÄQ¥s:WƒrjÚ4T†#9¡Ð7ú-j{tz¯NHqb„ÀìÚä¶©k¤zÅÆŸEUÖî% †/†pV ñè±3)‘™I=ª”SI•ë©(!g„¬õè[{SEbÄ(qEaÝíø³)ÄiÈHŠHª³i[ g÷$Ü>‹ƒê/º©¡Øž:[ýE¯Œ®‚Ÿ°Ûi‚,ŽKÆ_>`@@0¶ñë€ÀÒ,há}å`Zâ[ä ´ÅùyŒȈ’T5]âaÌ?vôS%|aœ b(Î]Eð¸zbʪ•8{ ¤Ö£Í%xc1?˜[®¤ä KÐḛ̈›ÝÙk ~«e½ ÛÖ¾“ªñ{VÉ.0ÛU}ó»ºáqEêq?K¯ø½a<Á+VoªÍ_n{ÏÇÜmÀ[Á[Ôbí[ÜT‘¥”ÏêÊRŠû³³Üo44Ôi ÍhÀüÔ²Y2R¢G#(ECnžªêí›&ÂÛÂÔ“—UP©¢‚±H ©CPÙ±ÆÍ4Q {hRwúÛšNa#±#eƒ-\ˆ†Ö–Z[vÁúï1Ì"l05‹Qćq0P-^ƒ‘ëí4o‘ÅŸdnÂd"Þ=a¬j°Ãó(HXJÅ&„0§ *™³ Ṵ̀mº‰’ªˆT/-)ÈO,h¹è@*QÚMì)4ĉÓä>/.:Ú¢èø&2˜ªÕJ<N&‰ÒäÏ•j …¦´á •™x bÀ MI{×ýÃt¹¢5æË¶©ÚmÎɾ sž|sr0‡|¨7©ë Þq@gÚãZ²ÉM €dyä_bZK¹2“*®ÂZÄã[(ïº[`ûg¯¶Í];×pÆg©Çæ7ØÞ§[‘-WîUèö»)™é¼±Ìd9¹ÌK 0ÉŸð mìK›[¥G·Îæ7{ÙHEÝTÃk¼K8]¼ô9ý5^üqe}Ë«?ÁyOJÛ‰X¨ƒ’'µò„®¿íç­×_ä„Nr†7Kso–u­Ú‰ª¨§WÁx“zì|Û‰«Ç[úè´•-ö‰ÌîüJB œ¸‡o6ÙM÷él0v><’ yjˆ·š[ÔyËfÆwÄ„ ÄÉ"ƒÏ³jñ¥6^ÓSâÕ<“Šf˜) £©65TÇ:¡3ð n"$Z‘Y@ótè0ÚPÇ%\Gà4rN“¯Çck¯ÅCõRN„$n)ïBƒ¥¢9sW†’;Á ÁêÆ¬ÃpZþnJêrUSëΪšŠ™TJ“¨ø· ý:$b¦¨Gl.·²\…vC0ð!9b‹{ÀÌŒäÆÆàÌn&äìÃV-Ძ›u›ySFyÓÐúdi¾íìNÊAïL·Èæ¶~uù£oÛ_{ŠÜø–n·Ò[ ²·ÌA6ºŽŸ®Ù9Mµ¹}囫¤Çùþùëßzný[?®¹fÆZדLm/¬…4ÜéƒÕ*¯>ô »„9¯C ŽÓØâØ<X‰Èýß,UòÌ'¸ØBÌ*‘‘ëS¼Êâ¨G„¼÷ÒÐ’?вû·ÇÔFw/‚Ö%’?Ì,”È€(åÒ×#ª‹™ºQE´œ~ÁZ‹lB»6„"l¶ †”ÍÄd‘x´PKÜk±Ì¶u‘©°xV39RID9!¡KlÁ7ìÖÆ7Ïúb.Üüb ÙüÔz ZÚ‰±7ÈnçÌì\q1E€ZíêXSÂiRh…Þ;PÎ;ßt›VäVøÌ yÐzTR‡`ˆ¬1ºì IÕâVªÎuKù¬]B«¼½ËŸÂÖáÚñÂLµÎ±|§u´w «`޶4@ÀNž #@î|#ï^€)qKcµØ›™Tèà2ˆ%-Wˆ„”ASÅLŠ˜Tk­Gä¤R“KH‡sï!T–Z<œÎàì1d@¬Ë#sC,bDâá¼…ªÊrxÓÄiBDäÈ]ÇD:çWk9ªÚ8dƒ´M¬X¡ßÛ·d¬2JÆ?‘0RëFy x-cc«ê<'÷²ÚVêk_bñ·¹õ¹•lÔ MújþÚ—Ã6n NLOôþ'Ä,Q뺩°:LØ)™ï©"IùÖrœzš&øà×+/¿¢ÁÅq`æäZ¦ÀîC‰hÍ‚ÛFÂCå2 ‡JÑ º˜Š™ÔeºôSÝ`X¸–‡P–—Íô¸è˜)çp“kÕÍ«k7}¯‹YÕçDêC¥5L X³Íޤ‹ÜãÄ<¸ƒ™°ª©EU:­Òñ‡àÆ"2$2°f›/ÕLèêÁU%ÆRò`o¨S‹ p6kB$¢x«€0!afFäÁLÌ-îMÌÄ‹Úïë— ,*3Z4ûø{j>þ¿ù«ËêB÷…Mv´íæ¾õ3üvñü¢4œ©ÖarÀ§6¬¬3óþÿ_ÿïþ•šQPPj¤\]ê[ŠÑµ†ÔÔzör§m»µ˜íbi lÕ"¢ÄDŠî¹Ú)sï#Ì̖펵ɺÝhNV_w矂ÿ/$¢<Œ yón¸”¶´z ‹‹q»ídãΩÍ*0Þ²5å¨k½ãl‘jfªKk º7 5“!wÔ GwèàsÃ̬f<ÛsËm>GV¥*!-U´ô„’ä,?j'l®'VÐŒï\Kf`ž2´¹yZ‡n|»âj¢no*Î]×:;­RД0ùš®u‹`&a#<úP_}µÍã5›ˆ6Ô:° H\æ „ Pì­GC—~Ç”VÃÍêC}£vH‰îƒ™õàð¥[ úP?)¨iud@eñg Ôƒkö»ÖìxqñÅ=ç3ê½Ó”zð¡Þ!c¢ì+¾:?€²ý¿*ﮤ¬ÒËäZ»O(þ#íÓ[ÁþÖ’üî%Óx~ßUIEND®B`‚eric-6.0.8/eric/pixmaps/eric_3.ico0000644000175000017500000022174612307350756016012 0ustar piotrpiotr€€(ÈF@@(2nÈ00¨–ú ¨ >(€nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúúúúúúúúúúùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüúúúúúúúúúÿÿÿÿÿÿÿÿÿÿÿÿúúúúúúþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúÿÿÿÿÿÿÿÿÿÿÿÿóóóÝÝÝÝÝÝíííûûûúúúúúúúúúúúúúúúúúúùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýúúúúúúúúúúúúúúúúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþëëëÜÜÜÝÝÝÐÐв²²³³³³³³³³³±±±ÔÔÔÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüÏÏϲ²²³³³¶¶¶ÔÔÔÜÜÜÞÞÞËË˳³³±±±ÙÙÙýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùùááá···³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³ÓÓÓáááûûûøøø···ˆˆˆŠŠŠ   µµµ³³³³³³³³³³³³³³³³³³²²²òòòÿÿÿÿÿÿÿÿÿÿÿÿøøøááá´´´³³³³³³³³³³³³²²²ÊÊÊÞÞÞÜÜÜÜÜÜÛÛÛìììûûûùùùùùùùùùùùùùùùüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîîîÄÄÄœœœ‡‡‡………€€€kkk`````````lll‚‚‚………………………………………………………………………„„„ŠŠŠÉÉÉýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæææ”””eee```kkk‚‚‚………………€€€iiifff›››íííÿÿÿÿÿÿÿÿÿÿÿÿüüüëëë···rrrbbb````````````````````````mmm‚‚‚ŒŒŒËËËðð𬬬[[[JJJ```aaa``````````````````tttºººüüüÿÿÿüüüååå²²²ŽŽŽ|||bbb````````````hhh………………………‡‡‡žžž­­­«««««««««««««««¸¸¸ðððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿççç©©©|||```LLLIIIFFF:DH6AC6?B9?@FFFIIIHHHHHHHHHHHHHHHHHHHHHHHHHHHEEEeee©©©òòòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçççˆ?IJ:@?FFFIIIHHHIIIEEE:CCMOO›››îîîÿÿÿÿÿÿÿÿÿòòòÆÆÆ¡¡¡wwwWWW=DC7GF7PP9RQ9PP8PP6NN6DC6>>;;;FFFGGG]]]¨¨¨ìì쌡¤2Ya1FG7?>6==6==6==6==6@?7IH=6>=6>=9<;DDDIIIHHHHHHHHHLLLWWWWWWWWWWWWWWWWWWXXXxxx»»»ûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéé飣£uuuLPP3YY>wwBˆ‡Aš›H ¨`¥­c¦­IŸ¡:vu8lm=zzE““GššH˜˜F˜™F™™E”–G™™H™š;hhPPPˆˆˆÕÕÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëëëf§§T™ ?–™EŽ‘=xy=yyCŒD››FŒFUUœœœîîîÿÿÿÿÿÿÛÛÛ©©©ƒƒƒeeeBKK/^^O˜›k¯´p»Äp¼Äo¹Àoº¾n¹¾i«°e¥©?ŽŽ:de2SSWXXªªªîîî„ÁÁ{×Ûp¸¾k«°e¡§h¥«i¦ªg¥ªi©­s»¿F‚ƒgii¾¾¾úúúÊÊÊŠŠŠddd>JJ0\\7ƒ…Z¤¨i§¬g¥«i¨­MœŸ>ƒƒ6gg7fg8df(Y\;NOwy>BCrrr¶¶¶úúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÕÕÕU{|›ÚãŠÉÔˆÇшÇЋÊÔ‹ÉÓ†ÄÍŠÅÐQ™ Mfg¹¹¹ûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìó󗺺SœžŠÍÖÌÕˆÈÑ5ggCCCvvv¹¹¹úúúÿÿÿÿÿÿ§¼½wºÁŒÊÓ‰ÉÓ‹ËÔˆÇχÆÑˆÉÓ‡ÇчÆÏŠÊÔŠÊÕ‹ÌÖ‰ÉÓˆÇЉÉÒ‹ÊÕŠÈшÅÎ~¶ÂŠÈÑ—ÔßB„…Pji…‡‡¯¯¯òòòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷u~¿ÆŠÇЋÉÒ†ÅÏ‹ÊӼřÙãBsu```~ŠS˜›™×áŠÊÓŠËÔ‡ÇЉÈÒ‰ÉÓÔÞ5xyuxxÏÏÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¸¸X›œ†ÇÏŽËÖ“ÑÝf´¸*HIXXXÛÛÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÒÒÒW’‘˜ÓÞ†ÇЇÆÏ„ÁÊ…Ä͉ÈÒ†ÄÍ‹ÇÓ9rrÊÊÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÞÞb››f·¼ØâWœ 9GF]]]®®®úúúÿÿÿÿÿÿ¥¸¸u¶½‘ÑÚ‹ÌÓ‰ÉÒ†Å΄ÁËŒËÖ‡ÊÒŠËÕÎ×ÍØ‹ÊÓ‡ÇЈÇÐ…ÁɆÅ͉ÉÒ„ÁË„ÁÌ“ÓÞY´¸"?>DDDRRR‚‚‚ªªªãããÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷tŽŽ¾ÆŠÉÒ‹ËÔ‡ÆÎˆÇЀ½Æ”ÒÝBpraaa\~rÄÊ—ÕߊÉÒ‰ÉÒ†Å΃ÀÊÍØu¹À7WWåååÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿàââ[‘rÁÅ“ÏÛŒÐÚ8lmDDD|||ÓÓÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÇÍÎS¤¦’ÏٿȆÆÎ…ẪÀɇÆÐ~¹Âu·À?eeŽŽŽäääÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõööy©©_§¬ÕÞ7on___­­­úúúÿÿÿÿÿÿ¤´´t±·ŽÑÚŽÎ׊ÉÒ‡ÈЈÆÏ’ÏÚ<ŠŒGƒ…m«¯i±¶ŒÎ×ÉÒ‰ÈуÀÉ„ÁʆÆÎ|µÀ‚ÀˆÄσÄÎ?z}-KK>>>RRRnnnÛÛÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷sŽŽ¿ÆŠÉÒŠÊÓ‰ÈцÃÎ}¹Ã™ÙäDruaaad‡…ŽËÖ‘ÓÛŒÌÕŠÊÒ‰ÇÐ…ÅÎŽÍ×U˜œRXX°°°øøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêíí„©©T•™™Úåg¬²;PO}}}ÒÒÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÅÌÎg«²’ÏØƒ¿ÉˆÈчÄ΂¾ÇŒÍׇÅÏr°¶Wff¢¢¢ÆÆÆÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÝÝÝëëëëëëâââÅÅÅÃÃÄ¥¨b¦ª]•›™ššÌÌÌýýýÿÿÿÿÿÿ£²²m¤­¼Ç…ÄÏÍ׌ËÕŒÊÔ—Öá6ggfffœŸŸ˜´³V[ž¤ÒÜ‹ÆÑƒ¿ÊÍÖ†Ä̇ÅЀ»Å…ÄÍ‘ÎÙkª°3[[??OOOCKK+WWv³º•ÑÛ‹ËÔŒÍÖ‰ÈЇÈчÅΈÈÑÍÖ}·ÀHWW‘‘‘äääüüüÂÂÂzzz3ddÐØŽÍÕ‰ÆÐ‰ÈÒ‡ÆÑ†ÅφÂÌÇÏ0ll]]]³³³ýýýïóòc––rÂLjÂÌ‚¿È‡ÄΉËÕ‡ÆÐ‹ÇÑ…ÅÏ2ce5AAFFF\\\wwwdddPPP;AA4SS@ƒ}¿Ç’×ß:kl>AA^^^‡‡‡ËËËûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûŠ´³o¸¾–ÓÜ‹ËÔ‰ÉшÆÎ‰ÈÑŽÌÖŒÐØR–š.ZZ8AB???7EE3SS=‚‰ÅÏ‘ÑÚ…ÁʆÄÍŠÇÑ‹ÌÓ‰ÊÑÌÔqºÁSpr¥¥¥ÙÙÙ™™™jjj3QQ]¤¨’Ò܆ÆÎ‡ÆÎˆÈЈÇψÇσÀÊ~¹Ä~ºÄ¼Æ‰ÉÒŒÍÖŠÄÌ‹ÑÜl¯²)RR0RQC…ˆx»Á’ÑÛ‰ÈÒ‰ÊÓ‹ËÔ‰ÉÒ‡ÆÏˆÇЈÇÑÌÖX§«Rab¨¨¨ìììÁÁÁ‰‰‰Eaa^ £˜×ÞˆÇЇÆÏˆÇЇÄ·ÅχÇÑÊÔAru\\\³³³üüüÿÿÿæççV‘‹ÊÔ…ÃÍ|¸Â~¹Å½Ç‰ÊÔ“Óß¹Á=/II>??JJJFHI1JI4hhPu¿ÇÒÛÌÖŽÍÖo¸½(SRAAAbbb‹‹‹ÅÅÅûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôùùq¤£m³¸ÌÔŠÊÒ†ÆÎŒÌ×ÏØ‹ÊÔ˜ÓÜi»¿F‡‹9}~R–™u½ÄŠÅ͇ÅÏ“ÓÞ‹ÊÓ†ÆÎ‡ÄΆÅ΋ËÓžÛäNŠŽ~…„Ëˢ˜˜jjj4RRMšœ”ÒÛŠÊÓŠÊÔˆÇÎ…Å̈ÇЊÉÔ‡ÆÏ‰ÇшÄЀ¼Ç~¶Â‚¾È‡Ä΀»Ä—Øâ†ÊчÅÍ’ÓÚËÕ‡ÄÎÎ׌ÌÕŠÊÒˆÆÏ…Ã̇ÇЇÇјÕßPƒqtt¼¼¼ììì™™™U\[=xyÎ×ÍÖ‹ÊÔ†ÅΉÈÓˆÈчÆÐ…ÃÌŽÇÒGwy\\\³³³üüüÿÿÿÿÿÿ¿ÑÑK‚„‘ÐÙŽÊÕ†ÄιÄ}¶ÀˆÆÏ‰ÄÍÉÑg«±,ef,VV4vug¬±ÐÙšÙäÏ׉ÉшÅφÃÌ—Õß\¡£-IH???]]]‰‰‰ÎÎÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûu«¬x»À‘ÍÖŒÉÑ‹ÌÓŽÍ׊ÊÒ‰ÇÏ‘ÌÔ•ÔÜÔÝÈÔ‡Á̈ÇчÅ·Ä͈ÅΈÆÏ‡Å̉ÈЖÒÜX«¬Urq»»»ÝÝ݃ƒƒ2^]]œ¡‹ËÕŠÉÒ‰ÉÓŒÌÕŒÌÕ…Å·Å͈ÉÒŠÇÏ~ÊÑ^£§Ì׃»É{´Á€»Ä{´¾ŽÏÙ“ÓÝŒËÔ†Å͈ÇΉÉÑÍÕÍÖŠÉщÈψÇχÆÎÉÓx·ÂAkkšššéééîî‹;wy„ÅÍ‘ÍÖ‹ÇÑŠÇÑŽÊÕŠÈщÊÓˆÉÒ†ÅÏ‹ÁÍI‡‰VVV™™™éééÿÿÿÿÿÿÿÿÿÂÎÎl¥¥f²·ŒËÔŒÇÔ}µÂ}¹Ã€ºÄ€ºÄžÞèÕ܇ÆÎ‘ÒÛ”ÒÚŒÊÒŒÌÔŒÌÕŠÉÒˆÇψÆÎ‰ÆÏ“ÎÛI‚‡1HI@@@```‹‹‹ÙÙÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïõõ~­­Zª¬†ÍÓ”ÎØ‹ÊÓ‹ËÓ†Ä͇ÅΆÅÍ€ºÅ‚¾È‡ÅΈÈÓˆÅІÃ̆ÃˈÆÏˆÃ͘ÖÞv¸¿Esr£££îîîèèèZ~uµ»˜Ë׎ÁÌ–ÏÚÊÕŒÌÖŽÎØ‰ÇчÇЇÇÐÍ×sÅÍ!SRN‘w·ÁŒÊÕ’ÉÕ†»Æ|µ¿ˆÆÏÓÛ‰ÈцÄˈÇЇÅΉÈÑ‹Ê҇ŷÆÎŠÆÐ}ÀÊ=xz…ßßßýýýööölš›ƒÉшÈІÈІÈφÉЂÉÑ“×ßÙã•ÎØŠÆÐŒÀÊJ˜™IKKãããÿÿÿÿÿÿÿÿÿÿÿÿòõõ›¹¹Z›œiµ¼ÈÕŒÃÏ€»Åy±¼{´½ŠÉÓ‘Ô܉ÆÏ†ÃˈÇЈÅÍŠÊÒŠÉÒˆÅ̈Ç΄ÃÌ~¹Ä‹ÎØF‘”*BBEEE}}}ÓÓÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÙÙf©ªg³¸ŠÅÏŽÐÙ‘ÐÚÌÖŒÉÒ}¶Â‡ÅωÇшÆÐˆÇчÂ̇ÂÌÈÒÌÓc®²G|~³¶¶çççÿÿÿŽ·¶z½ÀkÁÇg¾¾eº»bº¾„ÃËŠÈÐÎÖŽÓÝÍÕŽËÔ’ÐÜk­±MVV€‰‰„°°S“’e £i·¾†½Æx°ºŒÈÓ“ÓÜ‹ÌÓ†ÄΈÉÒˆÅЊÊÓ‹ÌÕÍØÍÕL‘‡ÚÚÚÿÿÿÿÿÿÿÿÿÇìì­ææªäãªäãªãâ«ããˆÇÇJ]“–]­±{¿Æ›ÐÜR¯²cps———äääÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíññƒ¥¦N‘”lºÀŠÉÒ•Ó݆ÀÈ€¸ÀŒÈÒÎ׉ÉÒ‡ÅΉÊÓ‡ÄωÊÔŠÉÒ‰ÉÓ„¿É}·ÀÉÔ˜Öà=ƒ„:ON~~~ÓÓÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüÀØØ«ËË´¶x­°u³¶_¬°u¨®{ÁÈ‹ËÔŠÇÑÊÔÉÑy¿Èg®³a——‚¢¦ÒÒÒûûûÿÿÿÿÿÿ¬ÈɱÉÊÂÕÔ°ÈɰÈÉÄÖÖ­ÄűËË—¿À‰´¶†²µ{´··½]¡‹••ÂÂÂÿÿÿ÷÷÷òóó»ÐϲÍͦÌËc™™j³¸r·½ÇЈÆÏ‡ÅÎ…ÃÌx¾Æ^ž¤V…†˜¦¦ãããÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööö××ׯ¯¯ššš‚‚‚nnnYfeLhhX†‡nº¼¥²¶áááýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜãä³Èȸ·y¦¨m§®\œ¢j¨­t¼Ã‹ÍÖŽÊÕˆÈÒËÔŠÈÒ‹ÇÒ‰ÅÑ…¿ÊÌ×—Úä’ÎØ‚ÈÐdŽ¢¢¢èèèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúðõõíóóÞèè¬ÏÔŸÇ̾¿~³³€³µ¯°‹¶·¿ÍÍêìì÷øøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüøùøåìëÖããÕææñòòúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñóóÒää¬ÈÉv¥¦|§§y¥¦y¢¥Š®¯¶ÅÅæèèúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÛÛÛ¥¥¥†††iiiLLLFFFACC@@@EEE`aaƒ‡‡­­­ìììÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýý÷÷÷ëóóáëë×ãã¥ÆÅ|¥§P¥§JššV“X“š^›¡`¥^œ¢e¢§Y £f›q˜˜ÀÌÌêêêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþýýýüýýýþþþþþþþþýþþþþþýþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûû±±±lllMOO8JJ8WX6vvR’–C„„.JJ@@@OOO|||¢¢¢ÛÛÛýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáæèÞääÞääÞççÞçæÞçæÞååÜäãûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùûûôøøñôôîññíðñïòóìññîïïïññðóóïòôðôõîñòîòóïóôíòóìñòëñòìðóìñòîòóïóõñõöòôöòö÷ö÷ø÷úúúûüüýýýýýýýýþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûª­­Fed=vwb§«†ÅÍ‰ÏØ”ÑÜ’ÑÛTŸ£/TU=@@NNNjjjÑÑÑõõõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùûûëðñãééÚäãÔÝßÖÞÝØÞßÓÛÚÓÛÛÖÝÝÖÞÞÕÜßÏØÚÉÓÔÈÑÕÊÔÕËÕØÍÖÚÏØÛÎØÜÑÛÞÕÞáØáäÖàãÖßàÖÞàÙßäÜãæåëìêîïíòóðóôôöööùùùúúúûûýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýý ´µt½Â¤ÛäÎØŠÉÓ‰ÉһċËÓ“ÓÛh©®%^]9@@AAAddd²²²óóóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúüüâêëÐÝÞÅÔÕºÊʳÂõÃijÁ­¼¿¯¾À±À¬¼¿¬¼À¤µ¹Ÿ°µ¢³¹¢³¸¢³¸¦µ½ª»Á®¾Ä°ÀƲÂÈ·ÆÌ·Å̵ÄɺÇ̸ÆÍ¼ÉÎÈÓÕÎÖÙÓÛÞÖÝàÜâäãèêêîïïòóôõ÷úúûþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛää[’”„ÆÎ’ÏÙ‰ÆÏ‡ÅΉÈÐŒÍÖ‹ÌÔ—ÔÞ|ÅË=z|4EEBBBWWW~~~¹¹¹ùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþáììºÐЮÄÄ¡··˜®®“©©”§¨‰ŸŸ‡œž„›žˆž¢—œv–p‰l‡tŒ•u•tŽ—z“œ~—¢{•Ÿ€›£~—¢š¤‡ž¨Œ¤­¥°”©±™®´¤µ¼«»À«º¿±À÷ÅÈÀÊÎÐØÙÙàâàçéëîðôõöûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜââM‡‰ŒÍÕŠÉÓ‰ÈÑ‹ËÔ‹ËÔ‹ËÔŠÉÒÍÖÏ×E†‰0PQ;@A\\\ªªªôôôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó÷ø±ÌÌ”´³‘®­„ŸŸumˆˆpˆ‹h€_x{RpuNpuIjpAbh=]c:Yb;Yb=[e?\jGdrLjyLmzMn{HjyPp}[z†b€ŒcŒm‡’s—z“œ}•›}•œˆœ£¢©­²°¼ÁºÇËÄÐÒÓÛÜàäæíðñùùúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²ÆÆQŽ’–Ó܈ÆÏ‡ÇЉÇЊÉÒˆÇЉÊÓŽÎ׋ÏÙ\¤¨+SRY[[«««ôôôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýýÍÜ܃©¨qš˜jŒ[|}NopEfi@_c;Y\4RU,MT!IOCJCH DJ!DL?I=H@M#FV#JY$JY$JZ%M^*Q`/Ve6[j?bqHixJlxPqzTr{[v€d}†n†ŽtŠ‘…˜ ’¥­¢²¸­¼Á½ÉÍÒÙÜâèêñôõþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”°°Nˆ‹ŠÌÕŒËÔŠÉÓ‰ÊÒˆÇχÆÏ†ÄÍÊÓÞéf®²w¸¸¸øøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëð𛵲m–•]‡„RywAgf0XX'OPBE9<05,4 ,5 .6 /3 17 39 18 /9 1= 4C 7G7H6G:K;L:K@Q!I[(M_,S_-Q]1T^:Ze=[gIeqQmwZv~h‹w—‚•ž”¥¬ª¹¼ÂËÏÛáâïòóüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýý´ÈÇg¢£}¼ÄŒÅÏ€¼Ç‚¾È¾È˜Öá~ÀÈIŽ’b‹‹ÀÃÃðððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÁÎËhˆƒKro>jg1]Z%POAA79 14(. (/)2%/ '/&,(.+/-3193>.:+<.>,<1A2C1D 2D 4G6I=K@M?LAMB45.10++ (*12 .1 '+ ,- /03043.2*2(3%3$5%6%5*<.? /@ 0@ 1A 0@ /<+9 .= 0? /? /A2B9K#CT/O\E7@5>6:4 0, ., -. '( %' (**,.0/2,1,1)3)4)9(8)9*;+<+=->0@/@ -> *: )9 ): (9$8$8 $7,A7F!CO4S_C^jKfpZs}u‹“•¤«ºÆÊÚàãìðòùúûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçîîáëêòóóþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÎÛÏ¥i‡Y@c2sb%SG J@E;<3 5-5/7252 32 02*.*1.7/816.2).)8,;,<*9+9,:.>3C1C2A3E/>+;,=*<&7#2"4!2 '97G!AQ+M[9XdJdof~‡‡™ ¬»¿ËÕØâèêïôô÷ùûýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüýÀÒ¼ªÀމ¤lh¦„:ygK< ;/;/9/809/:, 8/ 53 35-3092>.6-11013/=.=0?.=+:,<.@1B2D3B4C6F5C3B2B->+:'7!30%7 0B=NDR'IU=[g[v— ª»ÂÆÓÙÜåçñö÷ýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ù÷·Ò®Óè«Åßškw)`LT>VAcOL?A6@2C2 A4 :801,3 4?.;+50363866F4C-;+9*9*9);,=+=.?->->,>,?+?.A*<):(@!8!5&;,> 1B7I>O9Yhb~‹¥®°ÄÈÛæèúûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõúõ­Ë¥½Ð˜Ýøµ`–j/lM'lO)|`5”y eSJ=L<S@QE B>10+- /3(-'+'(+(324?2>)5)6*7(6(9,<+;)> +? /D 0E 0E .A *= '9#4#9&=(<&9&8%6*: 1C$HYKox• ¬ÁÅèïïþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóøóz–vFX6®|f¨pL’aLfK–sBœ€dO A2 I=@8?7D>B= =4<2:- 8- 2-1003,21628.408/9.9-8,7-<.@.?0A0A1C4F8H6D/>/<,;)8$4#5%8';3 .EL]Lz€Ñàâýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöûö”·”hŠ`ˆ±ƒÙð¨ªÅ}n¯s7|S![B'YK"MGB>KD#ibNJE:C5D1H6@5 53*/'.*.&($')-'--419/9,8+=*<);+=-A/A 2C 2A 1A3@0<+9)9(;$7%9#9&=5C._bÐàáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùüú¤Ó¬“БŒ»f”j3nM$qP%yS1|P0@2D3E4F 2F 2A 1?+9(9 ,?*>'<'<'<(@ :J¦¼ÁýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþýÁìʶö±¢Æ…[XUˆbn°…tºŒW“cFxH:h=-_>T=I:=32,1/ ,,** <: 97/-,,/--/(0$1"1%2'2(/)-)2*6,90>/?0A/A3F4I 6C 5@ 2?'7&6'9(=*?)>*C3Mm‘›ñø÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿäÆù¶´ÉˆŒ³tŠ·{µà¦©Ú¤NU%Z3W4O;"WOODJ9B8>7;6 <: DC00##$$$%#& ( +#1$2%/&/(0+6*7 -)$1*:*=,=0D5B3? 4A.<(7#3$5%6+<,D2M7gsÔãåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàýã„°t– e§Õˆ¤Ý‘¬áŸv¬v9{L'xGmE({b5…THC,=+7-4075 /0 '* '+ *--/,1+3)4(4(4*70:.5+9/=,:(7(6(6*9,@.@2?5?2? 5A 1?(5$2#2$0!40H CX†¦±ùüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝñÞ{¢h°ºxÒî¦Ãòªœ×™xº…[§qU¯rP¨rC”r.tfM>G/C09- 0* *)'' (+ (+ .3 7; 9> 7@ 4@1?-9+8/9,4*7+9*8)7*9(6*8+<->1>5@1>6C 2A 4C 5C ,;(5#1&:+A%Se¹ÐÓýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñúï«Ò›Ôç ó󻦵‰OrN`“l•Õ›­çž•Á†NtP/\E2[E4V> C12'1* ,*++.0../1 49 9@07*3*4&0&0)3(1'5*9+:+8,;-<,;*8-:2?5C7E6D3B 6D 7F 5C,9+7);)C9NTˆˆÞëêþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúýù¼äºÆï©¸Ç˜b~[E|T;zQrªuÀçžzX.G&$R1H1%J5=. 5*;3<:>B?@ >B8;/1.2*.)0-5/9.8/9.9,:-=-=-=0?1@2B1?-;.=3D3B2B3E4C 7F 8F 3@2>0>-C?SOUx ¡íõôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþßüâºø¶‡Â‚aŸgnº|r½x·t{«fEm8BzJ<…YU; 7'1%5+ 6098>B ,1&)#&'-+0).*/29>G?I0>&:+@-A/B0B/=4C 8E 6A1>.;)93EE[Xm‘µ¼ôøúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿó¹øÄ˜Þ•Ó¶Þ’ÎåžÍè™…ªdk^p­wTj!F6:/@4D; ?: 98 27.067;; =C @E=F;F5A.@1B.@.>+<*8)4)4,9)>'?+B-B/@0@2@1?/: .< +:/:'70OLv%™¦ÏÕûýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿüÊù߹켪ݦÉî¶éó¼²Ä‘EuH:rI/;,;+;+<*;,>*;&?(B-H/I.E0B1C4H4E5C 3<9A4?*<4KZp5€Œ¦ÅÉûýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþáüòÀâÇ–À™±Þ²Òô¿r‘g([4@|UArTH3=. 9-A6 2- )*/25: 9=:;EF IP7=/505/30526 7; =A KM IK @E9 E? LELEIAD=@8FAD?87784639392<1:1=6D2@.;/=0?1C); /D 1B 2@ 1>.<3@2A/=@QRd7t~±ÊÌýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÔêŵӎ™Ç{f WaJ¦·q§É‰9kC[<\PKR8;?<C9 QDm_ [W FM-aN H2V3gMh\hiY_>=C6K5T:ZJ]OUNIE@A>@04 &()* 2-@8H@UM`X_XXR SN JDED?B?D;C 9D1A-?-B,C.A0>3?1?/>5D9J 9J7H 3D4=GP,nxªÅËüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿá÷ëÊæÃ÷ó«°vm†R3g>D-*RF+Y>!i;qNiYWXMWEGJ;dBqF'~W'~Z+|^'nT 0# 4&U<%bB)hG$ZKQE?51( ;2MC[Nqb"ƒs"’ˆxr YVKKGJFMBJ=H8D3>4<2;1:1<4A3D2C/B3A :A2>7J,mŒ•³Äðö÷þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿüÉîØçöÍ¡¥qdS]¤i9vS0cO%fK qKkO\KZSLKUQVKaNjOlK_B"bJ/rY6' ("a=.L7VE‘nJ•x@o,kR6&-"&GC))#$)*36 >ADIAF 8> 8@ 8@7B5B9J7K2B:F 4G!8EdRol—¥ÑßäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÎåÙŠ¯Š†•^{°gxºwX”g&dG[K\V$pa,vbcN O; RDPNNUHNB;86 6689  <+#[=.yN3‘]5šd7žg4œf*‹Y#yM!nFa>I,/!  H:E9H<A6 ,## !**52?5E4H3I/H 7R4I.<>N OaH|­ÄÏöùýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõûù¯Ïµ–¢h•Ãn„ÀzS„Z3{P*“|(Ž5']G%Q8 lQ‹uˆz‚jwej_gS^MX %- !6&S2kD"ˆ[/£q0 n/šg0•`5•_/‡QB†f% bFqOnOhMYGG:5, ##$(%)%.+:2C4J%>$7 AV =L2=@MD[Jc›°áìðýýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿîÚÔ”µÉm†ÁsP\Sc0’n+¢Ž6›u8eC`†fP˜ƒ$›ŠœŠ“€&…u vqpn+~~WV 23ABQSKPAF 25+-,,QI#sa+†h3˜j>§l>¨ghÇ7cT &uO"‚SƒV~WrYdS[J 7-51 8324 2: 4? 5E 4H!1!2 TDYPB GAA?=A9>7A-:1B-?--5HE\5G2E=NTdX|…ÄÒÖüüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôûø¯Þ¾z¤dz²b’èŸb×–8 fZ•b]ŠZ;‰X#ˆX)ˆb6ŠhG›}Ds:0E89ƒpC—Cš>—|9”z1ˆo.ˆn3‡\Z;;LP#[_$bh!gkgiUX <=31 K8,‘o3Á'»‰±€)¬:s 7&bFaJVH PHMKCD =C!") 0> 9F'2-);?X 9O/?8G° B,€X‚^rYeU [QSR>A /52::E2?,#5 5HBW8J1@8HFSx’˜Þèìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïöô·›œ½„ pTŸW[²Wx®hv¦tZ¬€F§~Ar/YO 23,]E@€cEpC‘s;q8Œp6‘s6’x8™'hV 8*[K'dT(iZ'la#tj yrxrnrnxX` 38<@FH 531,c[.¢‘GÑ·)!9(™j'˜n'‡h}er`odC>$' 25185>=I ;J-="0 /B=U ;P5EBRLZe‚‹ÓÝàüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼Þ×`›€r—iu«\x¿aÌ©ã°b™w$I626eK]Žx.D:.aGC‡f>…f:„h4…k4ˆq6Œx6‘~J¯žG<<0'eS*kY'mX$o\"sc#{pvnvs!~BE 68OSTV[[KK 33-,!rj?80#§t-¤u-™p"˜qŠk&ˆq4,  40 98;=8=4=7CF @)%f1­€"³‚µ†,ž| 9,^O `TWNRNHK ER ,9%*73@2@3F :P 3I9N@S ;L)MY›µ¼ñøùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçóñf¡•Ž¿¨µÂ¨R€Zzш“솤傩펗éŽÞ”Z†gUhLr_2*+'?= UK,rY8‹c=€eB4+k^2zm1xj2xg,ve%sj!sr.Ž~;13,,cX1d[m[l] n^3xkDC"% 36>? ((+'`T$–$®“,“z  hF }_ka \[SR PS8B ,/288B4D6I,> 8 98XV#b`"b_B<+% E;}j%{i }YŒlvhoeg[a_ ! *,47296B/@0E+>6I>O6D9G,80Ueœ³½ðöøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôø÷›Â«ŠÎ™cžfÊ€œÝ‡®öš«÷¤±ù¸ªí··÷ɕå"<&T‘]_¨r^§yZ£}X£€U |O˜qXš{H†qI@;ym?}lB€m@…n7q/}t,‰~ ,'$TG9}gA~e!„c2‹r!gV<6!f[)rf-vk.zo$qe\S924,@7 ˆf$’t,†p…j„jXP47;?7=4B.A-C(?(=@VAS8H7I8J%L]Œ£¯êñóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖèߑҫ]“f‘¾}¨Ù‡¯÷š¡ú£¨ø°¶õ»ËþÏ–À£3U4s¸psÁqrÃzp¾€h¯b¨€_¥}U˜vN•z"TE.fZD‡sG‹qFŒp<Šr2…qL—!=<UB.–qAŽj9j]–}>1RJ l^,{e.‚l.k0ƒq.r){nh_D>$ t]3‘v2q”l˜r<170A@@CR4I4K2I@S{”žâêîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½ÖÊT{_ˆ°w§Ñ„©ð£øœ¬ö¤Âû®×ÿÄ—¹¢>^<”Û…ŒØx‰Ú…Ôˆv¾†m²…j±…[¬€V­‰/mYC6G”{P¡~MŸxDŸy<|o°¢Dia I3&˜nA–oY¨€I`P8+%†o'ˆn3Žj2‘n-‰j*ƒj,‚n.‚s1v*tkOI .&&hT%‡e–m(‘m  ( R@ TNMMFM:F6I9Q8R:R*</B>X3J2J8P7LAU‚™¦ñõøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõø÷ ¾¬|¦}“À~¢ãŠ éŽ¯í—Äô¢ßÿÀ¢»©?Z:¤âŽžåƒ›ë‹ÞŽËŽuÂm½Œ^¼‰Y½“Cv ,!B“yU¬„X¶†S»‰Gµ…g±–\“ <'-‹fIŽmZ²‰%4(*sZ1’u2—r6–k5™n.’k*‹k*ˆm/…p5…w8‚yIB *%(" 2& R;~\"dLWCaI YNTPOP?I˜oB¢s; p6žq/q,—r.•r1‘uA›…*bV4+XH1\SD;0$ >0,"3%'|ZsPeQ ZLXPLOFR@R >P ?R CS0E7T:T;T7K1‘iSmP cM dS \Z[cP^ AP6B6A,C ;[?XCY?Q1A

Db[5dY"?2"iD6–];c<¥o>´|2³|4¶‚4¶‡G¹“M=- .qW5Šk5‘w8„yQ 4F/A'F\F{_H‹m:oT (=}Y@”_=ªf8½y&½|5ÁCÍ¡;g% fG2‹f=r=–o>–mB“r:‚q#UT//.aUE‘v3„b-`\I 0*$% 8;AG AC ED DN:J0A ;SA_Ea-A >O FS CT=f|ÆÓÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýýÒåâu¢‰p§|´w”Çn®×€³Æ…ˆ]<8,562q|u¯ÐÅ»ëà§íÍ”çÀ™çÉ®ðÒ—º’¦}–©}VzQP‡ZXŠ^K|SL09ˆ^1Že5œr+~[ ;$3„_:ši8­k.¬q+»„=Ô£E½˜0""WA8˜n7 v>œz=o=Ÿi?pB—~:‚!QS)(/`U9yk)cU -$<.J>UJLG HK LQ PWBL nU8oVBˆk(aK$wW €\*•j2¨v3±ƒDÀ—XóË8‚k 9$6˜p@§x:®z=¯}>±x>­s>¥tF§‰Gœ“KK-67<#TI)oSfDbEYHSTR^ MS CG HS ET CWUl4E @ONY EW=R2XhÒßäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñõôŸ»µr¥ž½‡®Ç‰ÇÖäè—ù÷¡ôð ¼¼~_c=&**5 \lX‰›‹ÀÖª¨JaBs¢jf«eL˜TOˆ_Pw_   8zbF¨†(Šf!‡a&‹i>•wSÁ£8)&Š_>¾†LĈEÄ…?Ä…=»{?²vD®}Q¸”1sd;6+ia OH (1F†~:…g*{SpKfO_Y LU ADKK MR EO FS Qa8F >LHV EV CVL^Ÿ¶½úûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëð𣾱}£u¾‹¯Ä“ËÕšåé¥êì ûÿ§ã펳ÂnƒœVfyJEP8GP@+4(CX>z¨u_”^G{J8%     J}j>‰nbD"qQ3wX)P;2?½|@ÔˆSä“Vá‘GÝ‘@ÄB·|UÅ‘B•s=0:vhNœF„0Y`(,)TPO˜‰BŽx8…n'l\KBB=QNPNMP JPGPEPBN HU BN DRGW IY`†’íõöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñõò »¡rvޏ†¨Ì½Ù”ÈÛ’æõ¥éó¥×ã–ªÔt¨Ìz«ÁŠÀÕ©of_w[„§€SoR'9(  )" *" $  /^L?§}I»‰cÑ—DeD%^6D»rAá†Qõ˜\ë•Kâ–JÑRÈ’aÉ™ L5)X>P™zQ™Q™ƒKŽ~5j`"KN$NV*W\#QP#SJ'_M"b[WXNP NQ IN@H JTNXFQ BOFT GU8fr×ãæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçì쥤a‰uƒ´}žÑ€¨Ò}Æè‘×íÜë¥È|°ÅèúÊv‚k,;):P:*4*  )2).&    @o[^È›BÀ†TܘM|P7‚NC¼q=â‹Gú¢X÷£Lï¤LØžYУR¥€&F‹]S›kSžuS¢|Kšw;~g4-GQDT %1 (. LI%XP#``Z`Y^NR>B CJ MTIRKU CO GU GT#V`¼ÏÔþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâç슠¢Lq]x¤rŸÌˆºß‘Öíž×éÎì¥Ñá«Þæ·ÏÕ°N]Es›sk‘o * .&5+    )E6aÇœ9ÏLó©N¦oHe>Àz2Û;ö®Iô²Cî«EبRÏ©-kR;#O¥gT©eS«lO¥sK›y"XETH-ki7zƒ$`nCT*7 3?FQ?FJR =D >EJRHP EM JT GR FQ KWLZ¤¹¾þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíòó‚’:HKZi_Š—€ÀÆ çí¾ëñÓÁ½ª‹„r`_MLaB¦â¦ŽÇ—2#3+    M«‰.Ò—;í¨:¸~X³7ÆŠ.æ¦7ùÃ:ô½<î°AܳLǪ6&'e>O¯dV»fO·iQ¶xFy!TF+nY+ub2‰|(}€!t‰Hj;'7 /9)1 +2DMEMGOIO JO FO ALJVMYž±·ýÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêðò•¥­'@ 5GAKKPMU HYIZDMFSM]¥µ»ýÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíòô²ÃË`u„=KZ,7?A\N}ž{›´ƒ–£pdjBAG//;* 4..C;      /,![u_>jRC2U‘x‚ïÉK௠í­÷³,÷¿KöËK³›?+S½FÍw>Ú5΃;Æ<~of—gf—YPl.–‚Šzoar ,W/IA_ @i 6] 2K 8CDIP]D_QjGS;JU G\HmDlFi7K  .0H#2!0 (9ž®´ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúûÍ×Ú˜ŸRouDcaMna]|g©Æ¦v‘o¤¿˜]oV@Q@ &J?2aPH)!  k½ˆbÃW¶rmÀ{z½}H€V=•jHã¯4øÁ(ôÅLÿá9¦:•seà¥_Ý—z侀ÿÑ¥Ó¸Qˆs°áÁ¼âLjɽ>™¢#ƒŽqxUgDh^n]iVqKp AePsIh! %'= 7P \j‡—óöùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþýýÓÝâ‹£ªOrzBigEeZk„qYfS &/*ÛàÖ}wc5,¦eXÆžŠZSGZaa¨àÇÔa²zWg|µ{®ÍÊÝ·¦½£DCAD:WF:‚pk´ªZ<}v@ˆ|Pvi’}ˆŸ¢„¯³zÉÁPª—D”ˆ,€€|)€y,zvmqfq ^v Nq?e ?dBg 7[ 8^>_9V?eyáêíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþòöø¼ÉÏx“šZyz[xs\rg8C;……§“½”Œèº«~^QJOHÄÒÆ³Ý´„¶}d˜fTŽaP‰_rª‚„¹˜P‚dW˜yuË¥x×®Û¥‹ä¡tˉT«r=e,tQC‹f;uT%lK4^Zs“¦dšîÑbµŒP—ƒ7ƒŒx,‰3Žˆxprp `kRmHlJpIjAd?fBd A\"MeÄÓÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþêîñºÆËm…‰\zx}£™k„z;<;†~{»­©œ‰ €šnv–jZUDM:‡P9’^>nI¥yDŠdm¶…ŽÒ™wÇ`Ï„mÑ{sÆkhµamÂslĆl·†a”jBiEmVR`GnL}€úÑj»ƒV–}6ˆ~’{"ƒ}/—Ž#Šu|jgbdwf‹\ƒTvOrHjB_ C\BT³ÃÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýþãê릷¹g†„}Ÿivgnf_jTNi]qkQ?H-lŒQ_†B`”JVœPO£_H­qK¼‡]ÒžR¨uÏŠ§Ú­Û’åŸt×~lÏmpÊo€Ï„–×§ŽÊ©a|5uSi^Ml4_Hƒˆ•ÿÍb·wR’z1{’‚~(”Š#‹p"…fwjn|fŠ dŽa‰^‚StGaE[N>[kÜæëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøùùèìíÒÙÙ°»¸œ˜}†o~sz‹t†˜ž¸œ¬Ç­¹Ñ¸»Ö¸»Ô´åøÚðùàÿÿîÿÿîÿÿïÿÿìôýåáõÖÑíËÒïÌž¶›ŸÁ´®ÞζðÛÆüäÆïØÊ³g°–+s†d {h‘†B¯¤/u%†u&„!‡‡}‡ q‚[h MULY9IjñöùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýýéìîÖÛÝ·¾Â|‰fwy^vsVtkWtgf†snvvŒx˜œ“¦ª °¶ª»ÆµÐÝËå÷ßéúäèýãÍÛ¼åݵåß°Øß°¾Í ©¿˜ˆ³Œf·?º'½©ˆ˜}5©“P®¡M•BŠ….„€}ypnilbkLY*N\«½ÆüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþõöøîñòÔÝ߸ÆÇ™­«‚˜•n‰‚^wmWj[LcQLcOSmT[wYa}`o‹kƒ¤s•mb‚XX~R]Œ\[^UƒWM}UA†^4i-žs-ž{$£€#±5ª–`”•›¦–n“”Jw2xw hr,^g¥­ïóöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþúûûïóóéïï×áà¼ËƱ©t„`oRtcGhUAcPBgNAjP5uZ(gN$^C,gG7nM:nN8rP0qQ1}[(Žk-‘vM¡’=‹ƒ'…3¼«(´&¤Š"—{'„zH~… »Àðö÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿñõõâëèÛåâËÙÓ®Á»“­§{™—c’X‹†JwAtg>n][[¡¡¡ÿÿÿÿÿÿýøøh³·j·½g¦«o¼ÂPz}ÍÌÌôôô Ÿ QVUGy||ÂÊ…ÌÖ‚ÈÏ€ÅÍt»ÂX“˜†‡‡¹ÒÑŠÕÜÃË‚ÃË€ÂÉi­±›˜˜ÒÒÒV\\J}€r½ÄƒÅÍzÂÉ`ž£c›¡PŒNruDnp>oq>FF···ÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿþþþýýý^¦ª†¾ÈŠÉÑ‹ÊÓ¿Ç‚ÀɿɂÀÊ€¾È~»Æ‡ÃÍS“nkjôôôþþþýùùp®´»Å…ÄÎ’ÏÚIml²²²lhh7YYp­µ’ÒÚŠÊҽǂ¿Ê†ÂÍhª°„ø÷÷ßààp¶¼‰ÉщÇЊÈÐZˆ‹½¼¼`kji«²‹ÊÓ…ÂÌ…Ä͉ÇÑ‘ÐÚ€¸Â’ÑÙÎ׆ÄÍÊÖHwy‚€€üüüÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÞÛÛQ‡‰’ÑÚŒÍÕ~¸ÁˆÅÎ}ÄÌi£§Ž¾Âp°µƒÉÑŠÇÑ…ÄÍ~ÇÏ>GF¿¿¿ÿÿÿÿüüm«°‹ÊÒ…ÃÌ–Øã?NM6JI\”˜ÐØ‹ËӺąÄ͆ÆÏÌÖa—šºÁÀÿÿÿþþþÿûûi§¬ŠÉÓŠÊÒ‘ÎÖL|}®¬«_¡ŠÇЉÉÒ‡ÈÒ‰ÉÑ`œ ½¾¢ÇÈ[ŸÎ؈ÉÒ¾Æp¯µSQQÛÛÛÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿµ¾½yÀƆÅ͉ÉÑ‚¾ÇwºÀ‡•”ÿÿÿÿÿÿÿÿÿÀÕÕv¯²ˆÉÓ•ÑÛBik„„„üüüÿÿÿ¸»‹ÈшÈÑŒÍÖMŽ‘ÏØ‡Å·ÆÏ‰ÉÑ€»ÄÌÕ‡ÊÒb‘ãããÿÿÿþþþÿÿÿÿÿÿs¤¨‹ÉÓˆÇГÑÛIghq††ŒÐ؈ÈÑ…ÂÌ‘ÒÜTyyöóóÿÿÿÿÿÿüûû•¶¶p´º’ÑÙŠÍ×4II   ÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿŒ£¢–Õà†ÅΉÈÒÊÔIpræææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÈÈo¶¼o¯µMKKÙÙÙÿÿÿ†³·ÍÖˆÈЇÆÐŒÍÖŽÍØ‰ÉÒ‡ÅΉÈÒ‚¾È‡ÐÙ3ML„ƒƒæææÿÿÿÿÿÿÿÿÿÿÿÿpŸ¢‹ÉÒˆÇÐÎØK``c˜›”Ò܇ÈшÇÒS“—¶³³ÿÿÿÿÿÿÿÿÿþþþÿÿÿðòòy«­ŽÐÛO‘daaïïïÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿŠ´·ŒÈчÅφÄÍ|½Æmwwåååæææææææææäää÷÷÷úúúÊÑÑu·½XvwÞÞÞÿÿÿ‚§«ŠÉÔ‹ËÔ–ÓÞ;ii«­gª°ŽÌ׆Ä;ȅÂÍX‘–9@@kjjÛÛÛÿÿÿÿÿÿÿÿÿpŸ¢ˆÈцÄΔÓÞPdey­±‰ÈÑŒÌÕŽÎÙJhjÚÚÚÿÿÿÿÿÿÿÿÿÿÿÿþþþþþþÿÿÿ–´´vÁÈfqqñññÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿ¶ºÊÕ…Ã͆ÄÎo³¸MHHPLLPMLPMMPMMUQQjhhjhhTPPSSS±¹¹ÿÿÿÿÿÿ†«¯„ÂË}¹ÃÌÙ8[[º¹¹ö÷÷Œ³µÆÎŠÈÒ†ÆÎŠÉÒq¸¾4EG‡‡‡þþþþþþÿÿÿož¢„ÂË‚ÀÉÒÚYss‚ÀżÈºÄŒËÕGccØØØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿàíìöüüÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿ—¿Ã‹ÇÐ{µ¾‹ÌÕ~¿Æl­³j«²q²¹n®µo­²]¥©U‡‹U‹g«±M~€Žÿÿÿÿÿÿ…ª­ŒÌÕŠÊÒËÔSƒ†ûûûÿÿÿ“±²ˆÇÐ…ÃÌ…ÃÌŒËÒ]Ÿ£RQP×××ÿÿÿÿÿÿl›ŸŒÌÖ‡ÇЄÃÍ_po~·»ŠËÓŠÊÒ‘ÐÚHccÃÃÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿªÁÀÊÖŠÈÓ‚¿É‡ÆÎˆÆÐ‡ÅÎŒËÓ‰ÇЉÈÑ‹Êӄ¡ÆÐ‚ÁÊ^›¡vssþþþÿÿÿ„©¬ŠÉÒŠÉÒ†ÄÍtµ»TRRáááÿÿÿÿÿÿm¨ª‹ÈчÆÏ‹ËÓ•Õà4ONºººÿÿÿÿÿÿo¢„ÁˉÉÒˆÉÓ]lkt©¬‹ÉÒ‰ÈÑŽÌÕFpq†……ÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÖßßv½Å†ÆÏŠÉÑŽËÕP€ƒ€¬®ÉÌx±µ{³¸q®³„¿ÈŒÍÖŠÊÓq±¸trrþþþùùùt™›„À˃ÀËŒË×ÐÛ5KKŠ‹‹ýýýÿÿÿ ¹¹‹ÌÕ…ÄÍ…Å͇ÆÏS}~’‘‘ÿÿÿù÷÷kšž†ẨÉÒ‰ÍÖSddŠ¥¥‹ÉÔ…ÃÍŠÊÕe«±URRÎÎÎÿÿÿÿÿÿÿÿÿÿÿÿùùùñññûûûþþþÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿx³µËÕŠÊÒ“ÒÛAtta]]ÑÏÏÿÿÿ÷ôôg~€’ÑÛ‡ÆÏ‹ËÓq²ºtqqÿÿÿÒÏÏ`œŸˆÆÐ€¼Æ…Â̈ÆÏ\ž£GGGšššååå}ˆ†ˆÈчÇχÆÏ‰ÈÒU˜žššÿÿÿËÇÇ^œ¡ˆÅлŇÇÑN_^ÛÜÜq¶½¾Ç‚¿ÉÍ×6TTmllÜÜÜÿÿÿöööÖÖÖˆ‡‡^\\¡¡¡ÿÿÿþþþÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿþþþÒÞÞġÆÏˆÇЋÌÔ1MMYXWŽkjj[–šÊÕ†Å͇ÅÍhª¯˜••ÝÝÝjoozÁɈÈЀ¼Æ‡ÇшÇÒŒÉÒH…ˆ>>>geeWVàßß²±…ÆÏˆÇцÆÏr³º1AAgff   vssINNBorN€‚URRÈÈÈÿÿÿþþþÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿººŠÊÒ‡Ç΋ËÕ‡ÉÑ=rs7\\X•š’ÑÛ…Ä̈ÆÐ–ÓÜX„‡ÂÁÁbddW˜œŒÌÖ†ÆÍ‰ÈуÀʼDžÃÍŠÇÑl¬±`œ ÌÖŠÊÓ‰ÉцÅÎ’ÐÚOvw××׊‡‡TŽ‘ÏØ†ÆÏ‡ÅÏÌÖF]^ÞÞÞÿÿÿjž¡ÊԺʼnÈÒy¹À7]^2KKRŠÄÌÎ׌Î×1UT^]]ÉÉÉÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿþþþÿÿÿŒº»|ÃÊÍÖ‡ÆÎÍÖ‹ÉÔ‡ÅφÃ̇ÅÍŽÊÓb¨¬©¬¬­±±e ¦”Ì׋ÊÕŠÉÓ†ÆÏ†Î×N‘‚¾Ë†½È‰ÈÒŠÊÓ‡ÆÎŠÉÒ‰ÇχÅÎm¯¸‰””ÿýý[‹ËÕ…ÅÎÏØ•ÒÜÅÐBgg½½½ÿÿÿùøøŽº»p¶¾ˆÀÍz³¾“ÒÜ’ÓÜŒÊÒŠÉшÇφÅ̽È.LLdccîîîÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿËßÞÂÆ}»ÂtºÀz¶¿‰ÉÓ‹ÉÓy½Æi¥©²¼¼ÿÿÿ‹¹ºŠÄŇÀÁ–ÂÆ‡ÁÆ»Áo³ºƒ‚‚³ÏÍ™ÃÅ’¾Ãq´»Ä̈ÈÒ…ÈÑm«²Œ¡¡ýüüÿÿÿß÷öÙõô¾ÙÙ{œœ^ƒ„p¡§m¤§Ø××ÿÿÿþþþÿÿÿãè舷¹„»Ài¨¯x¼ÄÌÖŒËÕËÖ‰ÅÐŽÌÖÇÏcrqòòòÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿûúúÓåèÅÙÙ¾ÖÖÔààÿÿÿÿÿÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþýüïõôÿÿÿÿÿÿÿÿÿÿÿÿùúúÇÙÙ¼ÐоÐÑîïïÿÿÿþþþÿÿÿÿÿÿ£¢¢VWW4KK?abBCB€~~àààÿÿÿþþþÿÿÿþþþÿÿÿÿÿÿúüûäìì¯Ïе·—¹¼™½À—½¾°ÆÆñòòÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøúúéïîáççâèèâææäéêßåæÝãåÝäæÝåçáçéäëíäêëéíðóõö÷ùùûüüýýýÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿw™šv¶½ŽÑÚ‘ÎØ^ ¤2?>baaÄÄÄÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿùûûÅÖ×­ÀÀ¤µ¶›­¯œ¯±“¨­‡¢Œ¡¨¢ª•ª²™®µž±¹£µ½§¹¿ºÇËÂÍÐÎÖÙâçèïñóüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆÕÕv¹À‡Å΋ËÔÎ×{ÀÆ1LMUTTÕÕÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½ÒÒ~¡ g…†XtwMhj9\b/RX,MU(IS/O^6Yh5Yi?cqMn{\y†f‚Špˆƒ—¡°·ºÇÊØÞáôö÷ÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡»»|¼Ä‰ÈщÈчÇÐÓÝMmmÕÕÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþðôôhŒŠGqo*SS/?.=)8+;(;0D'HUF`maxœ¬²ÞäæúûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìðïšÁÃºÇÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯Â¤d’h*cU?47.7. 51.2.8.5./,;-<+90A2B4D0?,=%401B$IWB_j‚—žÈÓØìñóþþþÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿ¾Ø¥£Ê‘\D"v]M@J8E=,..7)-405D)6)7);*< ,? -A +?&7$<$8(9 1C@aq•®µñõöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLdD¯yk­vEŽp K<;0 <7 81 5-20*-/609-9+7,=.A1C3E/?):%6%8#6FZ«¯ÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ†µ†›ÁŠW^$mI2`GS=h\<2<1 62'+&)%+'0-6+7)8->1C 2C1?)8)<%:'0D 5@.=$5&:*@ Ocüÿþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¦Ê °Å²ë£Zœi3ŽY5‰wF3<, 0- ') )-371;,8-9+6,:)7(6,?3>3@ />)8"0,B›µ½ÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓëÏÜë¬\zWdŸq°Ô-P2.R<8* 50 686837*0*3)3(4+;,;/?,:2A5C4C 7F.;*? LWÝéçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÿøŸäž„Ã{¦Öi”RWšj>. 9. :6 16+-28169@>I6G2D.?*7.9'=,A/>3A0<+81H'oŠòùúþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈò׮ܭÃÖ¥+e>1[C@0D9 +0 17DAHT8A/91::B:B3@0@.A*B.E2H0D4F7?4@;M9x…÷úúþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿçõㆩj_’Rš»{*`>JH65H= ^X @K?8QJ YSWPE>:5542607/:-9-;,?.@ 1A 0@0>;J;vóøøþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿòøôÄ㧪Ê~¹ÐŽ!^CG3SFQQ D<?1 JCKLU]7B57MESMMK B@6;3;/=-@-A/?0A:K8H2@4t|öùùÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖòáÕÕ£OL&VC%hChOPSNGlI$vQ-y[ )'mE5}X/mZ;. 1'NAhc/./27=>E :A6>4B4F7B(;)h‡Öãæÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþôúùˆ¡u…Âu?yRtl-veV= odZh LN@H."e>([2¤l*‹Y%sF."5']FK:,$ "(11B-F6M3? L^’ªºÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñõÖ˜»iTžc,œ9|VY“r †$Žs(~yURJI^_MQ7;<7bJ0^\§‹:#$\ƒ]rY ;2 973:6E,/CI_1EMv„èíïÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþùÿü“»ƒvÈx?µ‚W‰\.…U*Žf?œvIA0ue=’~3Št,ƒwORFLUX A@?9 1‘j*Àˆ¦v6,L7 RDFD!/;Q1DGV±ÅËÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Æ¯¨É‰S´csŸfA¡t=m#;;3kRCs:Žq5‘s1ŠrB6&bX$lfvsisIO&'OB.¨’*p^hG$†djZTQ 06:E'7 2D 8L4DnŽ–þÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþòúûc |Æf”É”0M98=:G6J.>;LG\Hkyôöøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾®¶Ó¡BvM哿‚Š×…H{_J‡pHBI>&\H QH-uf*ud qk"kZErMV ƒPž~Sžy+_R=r=k.zqXN1bU.|d&‚m ]W*qkKCD:2*’n{job 584>-A*>?Q2A3ZjåíðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍèÚi•e­æ£ù¥ÌÿÃ_€f†Ó{}Í€k°‚^¥}<€h4p_K•u7rN|wtTF™q6TE xg0ˆj-ƒk-r"kb#kW$”mcJ+"IH;F4I2J*;9P2KGYàçìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨Ç±Æ­è“ßÿ¹mo³ð˜ì•Ñ–jÈ‘Y¾˜"VDW´„QÊo½›ZA\ªˆ N::št7›n+“m,‹o:ˆy:192 N8/#oQ ZNLM=PR7Xjõøùþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþþÿÿ’²ž„~noifKLIÎì¹¶ÿ¾ˆö±ó«ïÂ0fSpÉ‘rãš™ä©, (B=R91,uZ4‚r RV #+’cmQ i[ GP0;,< >[AS1Ba=/fE=‘kK3?Žc7±l-Ê8sY?9–t=šjA•u"TU/_T5€f 4)=9 EG KO7D ?[ †hKI N]2:NRQX @E IQHR EQ ERßçéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßäæHW_Z_U˜š†mkZ\bB²å® !    I·‘DÑ™YÉ™,ê²0ó¸IßÁF-S¾mG¾{7o^5zW*Œg{ ?)9 1@FN JR CN ES×Þàÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðö÷lŽ9QQ…¤–¤tYhJ$+#   ‚˜yW†eg§‡@è¯ó°UÖ°;‰Y>ä~CÖbu¶€.£"{+N Eg ‘…)ˆ‚vz [c =LÇÒØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿøúû×ßß±À¾Œž–\vfHhQEeKU{X9nJ9rI@rL5{W,‘k/£†<“Šc¬§B•„%qs“­²ÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿ÷úùäìéÂÑС½½ƒ¥£wœ_ˆ{]Œ~K‹†3†O™”¿¹Þïîÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿûýþÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn(0`nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿüüüëêêãããöööúúúúúúúúúúúúÿÿÿÿÿÿþþþäääöööôôôíííÿÿÿÿÿÿÿÿÿéééæååæåååååðððûûûÆÅÅáààçççåääóóóÿÿÿÿÿÿçççæååêééûûûþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿùùù¦§§`ggNYZEOQX_^\cd\cc\dejlkðððÿÿÿâääLWXX^^V^`€ƒƒûûûîîí›NZZFYZEWWCMNY^^´¶¶McfFOPDNO?MN¡  êéé~‚‚JSTCNNOVV[`achhpttnss­®®þþþþþþÿÿÿnnnnnnÿÿÿÿÿÿ£§§Xˆ‹xºÁ~ÈÐÄÍr¶¾w¿Çu½Æ~ÇÐIopÅÁÁÿÿÿæíîkµ½xºÂx¿Ç‰››·±±_pp^Ž‘‚ÇÎ…ÊÔ†ÌÖoºÂsšœÎÏΈËшÌÖ‹Î×d¤©¬©¨uˆ‰d¢ÇψÎ×y¾Æo¬µp«±cšŸ]“™epqôóóÿÿÿÿÿÿnnnnnnÿÿÿëççY‹ŽÐÙ‚½ÆˆÉÒp³º†º¿r´»ƒÇщÇÑmª±€€ýýýèîîv¸¾‡Ä͈ÃÌ>IFV‚€ÁɆÅ͆Ä͇ÆÏr±¹ž´µøùùÿÿÿ³·ŒËÔÐÙXŠ¥¦¦o«±ŠÊÓ‡ÇÓs´º‘º½’¾Ás·¿‰ËÕ¿ÈWtvÍÌÌÿÿÿÿÿÿnnnnnnÿÿÿ»ÃÂ{ÂɉÉÒ†ÄÍp©¬ÑÑÐÿÿÿÿÿÿªÊˈÄ̆ÃÌVjkåääôúú€½Ä‰ÈÑ‚ÃÌq´»ŒÍ׉ÈÐ…ÂËŒËÔu°µ§··ÿÿÿÿÿÿÿÿÿˆ°³‹ÊÕÑÛVuwt’“‹Ð؆ÄϽĬ·¶ÿÿÿÿÿÿÓÞÞ‡½ÁŒÌÔ[Œ“ƒ……ÿÿÿÿÿÿnnnnnnÿÿÿœ·¸Ì؇ÅÏ…ÅÐq„„ÿüüûûûüûûÿÿÿèðð˜ÇÊUƒ‡ÃÄÄöúú‚¹ÀŠËÔ‡ÆÐv¬²w¹Á‰ÈÒ…Â̇ÊÔ@_`}}éééÿÿÿÿÿÿ†¬¯ŠËÔŽÐÚVoqtª¯ÏØŽÎÚ\‚„îééÿÿÿÿÿÿÿÿÿÿýý¶ÑÓqµ»Vddöööÿÿÿnnnnnnÿÿÿ¡ÁĉÈÓ‡ÅÏt¸¿PJJd`^b^]c^]qml€|zb^^x„„óóóó÷ø²»€¼Ç‚½Çp€Þææ…¶»‚ÇφÇÐÀÈIorƒƒƒÿÿÿÿÿÿ…«¯„ÄΊÍ×^}}…¿Å‚¾È‹Í×ZpqõòòÿÿÿÿÿÿþþþÿÿÿÿÿÿáïïÝæçÿÿÿÿÿÿnnnnnnÿÿÿªÊÌ…Ã΄ÀʃÃËp³¹qµ¼rµ»q²·^¢Z‘—gª°cz{ñðïóö÷‚¸¾ŠÌÔ†ÄÌ]uwéççþþý޼À„Ã͇ÆÏ{ÀÇGTTÞÞÞÿÿÿƒª­ŠÌÖ‡ÈÓcxy‚»À‹ÌÕ‘ÓÜTklãââÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿnnnnnnÿÿÿË×Õ~Á͇ÆÐ‹ÊÒrª°ŒÈ΀¿ÆÀÈ„ÄÌŒÍÕ†ÅÏd‚…íëëïòò|®´‡ÅωÉÔY€…¤¤¤ÿÿÿÊÝ݈ÆÎ†ÅΑÒÜJqs´±±ÿÿÿƒ©¬…ÅÏ‹ÏØ_uv¬¯‰ÈÔÎÙS‚…«¦¦ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿvµºŒËÔ”ÔÞBkk™™™ôùùÖÝÞv¤«‰ÈÑŠÉÒg‡ŠòñðÇÌÌo®´‚¾È‡ÇÐp®¶IQRº¸¸¾ÂÀ…½Å‡ÆÏ‹ËÖX𠬦¦÷òòmŸ£‰ÆÒ…ÇÑUmmÄÑÒwºÄ„ÁÍz¶¿QZY×ÖÖÿÿÿóó󥢡xutÝÝÝÿÿÿþþþÿÿÿnnnnnnÿÿÿÿÿÿÍÞÞ~ÂɉÉѾÆ@QQwzz`opw·¿‡ÆÏ…ÅÌ~›žÊÆÆbyz„ÉуÀɇÅÏÌÖ\œ¡BJIPjk…ÄωÉÒ‹ÌÕ[ŒËÆÆ §§~¼Â‰ÈÒˆÌÖCceßßߎ½Á†ÅÏ„ÅÎT‚†SYY‰‹‹YbbKx|Q€‚}|{óóóÿÿÿÿÿÿnnnnnnÿÿÿÿþþýþý¦ÌÏ|ÁÈŽÎØy¹À^’˜u´½ŒÊÔŒËÔw¶» §§e‚v¸ÂŒÍÖˆÈÑ€ÂËp±ºˆÅÑ{½Æ‚ÂÊŒÌÕ‰ÈЃÆÐf…‡ÝÝÝa”„ÇÐ‹ÎØ“ÔßIjmÚ×Öâë쌿Ät¸Â…ÂÎgž¥_‘”{½ÄÐÙ…ÅÎBacƒ‚‚ýýýÿÿÿnnnnnnÿÿÿþþþÿÿÿþþþÆÞ߉ÁÆx»Âw·Á†ÇÒ~ÁËk«°±ÀÀÈÚÚ„½¿ˆÂÄŒÂȽÃmª±‘¤£˜Ãʼn½Âv¼Ä‚ÄÏ}ÁËr¡¦ÞâáüþþËîî¿àáz ¡lœ e ßÛÛÿÿÿøúúÃØÙ€·¼n®¶|ÁɈÉÕˆÉÓ†ÄÐ{ÀÉ[opø÷÷ÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿþþÿÿÿÿÿÿÿÿýâíïÌÞÝÎÞÞüùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýüõøøÿÿÿÿÿÿÿÿÿçîíÈÙÙÐÜÜÿüüÿÿÿÿÿÿÔÓÓ_ggB_`D[\jjjÚØØÿÿÿÿÿÿÿÿÿÿÿÿÿÿþäìë­ËË§ÃÆªÈʱËËîññÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëðñÑÛÛÈÑÒÅÏпËηÄȹÆË½ËÑÃÐÕÈÓ×ÏÙÝßäæçëíõö÷ÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÐÛÛw¸¾’ÔÞ‡ËÔU…ˆHOO¼¹¹þþþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéññ’±°p‹_x{Jjn<^d6V_NBN+JWGdpi‰¥²·çìíÿÿÿÿÿÿþÿÿÿÿÿÿÿÿ¾ÔÔ€»Ã„¿È€§§îïïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøù÷‚Ÿ€'ZH6-1, ---0/4*1(8+:/?/?,<'9(::I;YfxŽ–ÍÖÚô÷øÿþþÿÿÿÿÿÿÿÿÿäîíÞããÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöúó±Ñ˜-hNgSH9E;,0+41/3B)7*;,> .A ,@%8#:*<=Mr˜åìíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåëådˆZr¯w8eA5C< 90 50+-.4-7,7,=/B4F/?(8&8%9Hp}ó÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõüöœÉp£qH†]&V:YK82 :5*+&(#.)2)3)8.?2D 0='8$9CUíñóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿþþþöû÷§ÅбãžXœi0…cQ>9, -- ',15,8,8+5)8(6.@4?/='6 4‘«µÿÿÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûþûÙïÀpew®yq•a+Q98, 644616+3-6+8-<.=-;2B3C 6D*:.?`vÖåèÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöýö˜º„pœ][ˆYJC65 NH DKA=QM SOC>7517/9.;.<-@ 1A 1@1@(boåîïÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÒ쾵΄dŽbL7WJJHE4SGSSAEA>PHKG EC:?1<.B0A1@:K/?Ydäíðÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿíû÷¡³HP!kUkXULbX`O80D*.zP+YbA\C81 @7 <8 (+'./;2E+@Rh¢»Äÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×â·q§^-˜|<|[7”xŒv"sqEEPQLJG>dJ7’a3eM SxX:. /(564A$42EAVZŒøúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíøï†¿{L»€VŠZ,Š_>§p3«x5 } SB1xhCEY=sS aZ:G-< =Z7I7Mœ±»ÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÃÐÏc’m‡ªdus^—²›™â½˜ßÀŸ²Š]‰`3^=<‰e!W=8 i4É1}c.]=Ÿn?’u$RP0o\>0G@ KP;I ?Z CQ"Shíñòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹Òʘ¹|Þ虨©nu„X£ˆg„`P‹U4')!:.,ˆgFž~&qHKØŽCÀF¡|-bY€f<…a"…)I,?;H FP ANmŒ–þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾ÉÑYsukŠowŽk*7,B?6C,$  7Q:aŸk`«}(Þ©:Ç­Qµˆyð´n©‹¾¢#†Œ HdPk@_ !4 .Feýþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿðóô§¬Xzo=F9}oj»‰z),)‹½š^h™½—IpHtG–tN’H€eƒª®S§˜!{"tu Tn ?b6Z?h~õøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛá䂞šw{sqg^YpG_˜RJªq\³ƒ›Ý™Ú}{Êyr¯^_>s€g¹‘‡|&}rsc‰Oq)Wiðòóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿþþÿÿÿÿÿÿ×ÝÛÙàڻǵ§¸’‘±Œ¡Â¢ÒÛºäïÇ×ìÃËíă¹®„¹ªk¯–w)œ(‡zv‰RaJnzøøùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿùúúòôõåêêÀÎË›­¦n„vZx__€cQ}YMWA}W&g.¢ˆN—:‘ƒ&nr¿ÌÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúýüÜää¶ÌÌ•±¯ƒ£˜xœ’c›—Xžš˜ÆÀïù÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn( @nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnõõõy™œ._e%Y_2bh2ciCouÉÒÓÿÿÿ¦©1bhj‘ìì웯±Alr'[b#U[¯°°¿Á)[a+[`ºÈÉ•«­6ej&Y_6ci;io?kpž°³ÿÿÿnnnnnn¥Áà V^OVm”–‘­°p–š*\e¯²ÿÿÿ•¸ºU]3bgX~‚T[T[/dk–²µùùùÑÚÛ0aj,af–¢¤,[aU\v™¦¹¼|Ÿ¤0fmT{€ÿÿÿnnnnnny¢§S\Eptìììÿÿÿüüüª½¿t–—çéꤿÂW]!W]8goS\NWh‘ÿÿÿÿÿÿØáâ/^e*[ap‰Š V^Jtzìììÿÿÿþþþ·ËÌ\}€ÿÿÿnnnlllg”œOYHtxª¿À­ÂĶÉ˺ÇÈ¢²³ûûû¡¶¹T[Qz€ÔÖÕ|™OV"\d–µ·ÿÿÿØßà+\e2ciqŽ‘T]`ˆúúúÿÿÿÿÿÿÿÿÿåççÿÿÿnnnnnn¦ªQ[OV5fm-`g&Za%Za\‚ˆõõõ µ·T\2cjÖÜÛööö^ˆU^Gu{èéêØÝÞ+^e7fm‚˜šU\Szôöõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnn°ÉË%Yb6ek¬¶¶ÎÔÔ]ƒR[Juzòóó‚Ÿ¢NUOZƒ£§ÿÿÿu˜›T\+`eÓÚÛÁÉÉ'Xa6ek³»½/`f&Ya¥¼¾ÿÿÿýýýØæçþþþÿÿÿnnnnnn÷øøu›Ÿ)\dT}‚q‹1_e$Yas”˜¼ÃÄAntS\LVSYZ„ˆ2gm"Xa7ciààát“—$Zc+[eÖÛÜ‹§ª!Zc;jq‚¤¨u¢:sy’©«ÿÿÿnnnnnnÿÿÿåè葲·Z‡Œ;gp6fngŽ”ÂÉʧ¿Àr–X†d‹Ÿ£_ˆ;hp:ms“­±îòò˜¹»x™aƒ…Ôßàÿÿÿ«ÅÈk•Kt{3dk+[e-[aÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿõööåìëÜæçôôôÿÿÿüüüüüüõööóôôÿÿÿùùùßçèâêéÿÿÿÿÿÿÀÎÏ\‚†jŒØÙÙÿÿÿÿÿÿüüüðòòÕààÉÖÙÏØØÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÀÓÓ„›œoˆ‹[x~Zue‚Žs˜‰Ÿ§¡±¶ÎÖÙö÷øÿÿÿþþþÿÿÿÄÕÖO}‚+aj[‡Œßèéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿþþþïòð?h\;9&,+-+4*:0B6E9H8Vdx”ßäæÿÿÿþþþÿÿÿÀÐÑw›Ÿ—´¸øøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿàéÖP…bN?@5-4.0.=+;/A-?"5 /A?]kÐÜÞÿÿÿÿÿÿÿÿÿøøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿ°Â¯|¯x(hOMA 9/./+0+6+<2C/?'8'<ÆÕ×þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿþþþßõߞŅJ\![J5/ ,-+2(4*5(72A.;%6l‹™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿõûõ‘¾½|0\? 8/ 35053<.?-<,<1B 4@-?ÆÜâÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿ¸Û´x kP>95 FI DF DF>>1:-=.@/C 4@@OÓâäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿåõ㦾~T<YQM;ePH?#\M@:NK/63B5@7H9FÆØáÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¦Å†2‰j8vYvWZ33]H#wT6zUX:[D09-A9Ku“ ÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿþÿËàÍlÂzO”b3xa1lX:“x"j^ YYVX?6$£}R?dS .3.9/B(Veçìíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‰»†f—im´oA€d&j^#RG'sa!wlLHYV 2,&¨|H9KJ/;5E ?RÍØÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓçÝŠÇy¸ÿºW…Zd±ƒFˆk@m0ui0}`UI+zj\SQ@€g''3D1E6JÀÌÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯Î³¦·ŠŽ¨‚šô«rà©AˆfxÜ¡,UE-wR4¢r/ƒk#YK4-yXPT3D:b®rl¤}7ŸŒ`·˜e™ƒv³±!vycq :\0Q×ßãÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùú ²­‹‰‚œivºw˜Ñ ³îž•Ò6‚qOšŽ(€t!‹vm‹Hb»ÇÌÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿßâã¼Å¢·¬š§œ•¬•ªˆ‚ªƒ+•o5œŒ7ˆ'ckùúûÿÿÿÿÿÿÿÿÿnnnnnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿûýýÜæçÃÓѳÆÁÂÀ¹ØÕÿÿÿþþþÿÿÿÿÿÿÿÿÿnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnneric-6.0.8/eric/pixmaps/eric_1.icns0000644000175000017500000064525512310131042016152 0ustar piotrpiotricnsJ­TOC hics#Hics8is32Üs8mkICN#icl8il32ol8mkit326tt8mk@ic08¬#ic09ãics#Høøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøics8úÿÿÿÿÿÿÿÿúúÿÿÿÿÿÿÿÿúúÿÿÿÿÿÿõÿúúÿÿõ÷PPXWúúÿõPü||ƒ^úúÿP{|‚§­+úúö|‚‚­‚÷ÿúúP­­­‚öÿÿúú{­­­øÿÿÿúú+VV+ÿöÿÿúúõ,ö++,++úú,V,3,,,öúúö+ö++++öúúÿÿÿÿÿÿÿÿúúÿÿÿÿÿÿÿÿúúÿÿÿÿÿÿÿÿúis32Ü€‡ÿƒ‡ÿƒƒÿ÷ìùÿƒ€ÿ÷·ž¢‡øƒ ÿÿñŸ<^~X‚ÿƒ ÿÿ¥}h^HJÐüƒ ÿÛaVN@[Ìÿÿƒü¢9>:_é€ÿƒóv)3<»ÿƒÿÉ›ªÎüé€ÿƒ üó×àØÕºÏÛüƒ ÿÓ¯Á·Å¾Êåúƒ ÿäÏÛÏÓÏÎßüƒ‡ÿƒ‡ÿƒ‡ÿ€€‡ÿƒ‡ÿƒƒÿ÷ðûÿƒ€ÿõ»¹Ã”’öƒ ÿÿôÀP…ªWsÿƒ ÿÿΨyW>Éüƒ úî…e\HRÆÿÿƒÿÊC;0Qæ€ÿƒü“+$*´ÿƒÿÉ–¢Êûè€ÿƒ üñÓÞÔÒµÌÙüƒ ÿΫ¼°Á·Çäüƒ ÿãÌÚÍÑÍÌÞÿƒ‡ÿƒ‡ÿƒ‡ÿ€€‡ÿƒ‡ÿƒƒÿøçôÿƒ€ÿô»œG[øƒ ÿÿò«>3BIÿƒ ÿÿªh=( ¹ÿƒ ÿÝ;" &¸ÿÿƒÿ§ +Þ€ÿƒøe¤ÿƒÿ¼ƒÁúÛ€ÿƒ ÿݲ´´’³Èÿƒ ü¡‡—~ …«Ùüƒ ÿԼκÁ¼¸Òÿƒ‡ÿƒ‡ÿƒ‡ÿ€s8mksÿÿÿÿÿÿÿÿssÿÿÿÿÿÿÿÿssÿÿÿÿÿÿÿÿtsÿÿÿÿÿÿÿÿssÿÿÿÿÿÿÿÿtsÿÿÿÿÿÿÿÿyxÿÿÿÿÿÿÿÿsvÿÿÿÿÿÿÿÿssÿÿÿÿÿÿÿÿstÿÿÿÿÿÿÿÿsuÿÿÿÿÿÿÿÿtsÿÿÿÿÿÿÿÿstÿÿÿÿÿÿÿÿtsÿÿÿÿÿÿÿÿssÿÿÿÿÿÿÿÿssÿÿÿÿÿÿÿÿsICN#ÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿÿÀicl8¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿõö+÷,,öÿ¬¬ÿÿÿÿÿÿÿõ+÷POPW|X‚õ¬¬ÿÿÿÿÿÿ÷úûûQQWW‚ƒ‚õ¬¬ÿÿÿÿÿ÷zûþ¬QR{|‰­‚ÿ¬¬ÿÿÿÿøtP{¬‚||‚‚ƒ­Wÿ¬¬ÿÿÿ+PPQW‚||‚¦ƒ­‰öÿ¬¬ÿÿötP|‚‚‚‚‚ƒ­­ˆ+ÿÿ¬¬ÿÿP{‚‚‚‚‚‚§­­‚öÿÿÿ¬¬ÿõ{‚ƒ­¦¦§­­­Wõÿÿÿÿ¬¬ÿ+{­­­­­­­­øÿÿÿÿÿÿ¬¬ÿP{­­­­­­­Wÿÿÿÿÿÿÿ¬¬õ{‚­­­­­­ˆõÿÿÿÿÿÿÿ¬¬õ{­­­­­­­Wÿÿÿÿÿÿÿÿ¬¬ÿWü¬¬ˆ‚øõÿÿÿÿÿÿÿÿ¬¬ÿõöö+öõõÿÿÿö+ÿÿÿÿÿ¬¬ÿÿÿõõÿõõõõõWVõõöõÿ¬¬ÿö,W,ø,3W,÷-÷,WWVÿ¬¬ÿ,WVW÷,V,-÷,2W+öõÿ¬¬ÿ,V÷V÷,,,Wõ,3,ÿÿ+ÿ¬¬ÿ,-,W+,W3,+,W3,WVÿ¬¬ÿõ÷÷+ÿ+öö÷+÷++÷+õÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬il32oƒ‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰ˆÿ÷æÓ¼¶Äèÿÿ‰…ÿ ó˧¢§•‡z€~óú‰ƒÿ ýÄsLJŽŠ–}eiòú‰‚ÿû«uG 4žrrYIkûþ‰ÿþ¨“j1Ws}]MNLÿÿ‰ÿ†‘—^boMGMG[ßÿÿ‰€ÿ â„h^iZOXNC:YЀÿ‰€ÿ ¦g_lY[OXK=:nÝÿ‰ÿÿêlZ^BLI?<4Ežõ‚ÿ‰ ÿÿ½W’ü…ÿ‰ þú’NDKYezµõ†ÿ‰ÿÿ÷ßÚÙàéöÿÿþèÔù‚ÿ‰€ÿý÷ùü÷øôóð¦¡ôõïìýÿ‰ÿÿ캪͹˺²ÌźÁÓ ©¥ûÿ‰úýÖ®±²ÆÐ¦Ê¼Ã˶°Îáòÿÿ‰úùЯ¿¨ÅÓ¼Ó êγ¿÷üÒúÿ‰ÿüĻɪÑÀžµºØÂ£¹À²©ýÿ‰ÿÿíÃÃÍøÇßÛ¾ÎÃÔÑ¿Èêÿÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿƒƒ‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰ˆÿöæÙÈÁÉéÿÿ‰…ÿ òÏÂÁѹœ”nòú‰ƒÿ úÄTj³º°¡{MNñÿ‰‚ÿúÀœ_ BÈÒ§‚H;`ûþ‰ÿü¿¹¿Dw£²mXN>„ÿÿ‰ÿÞµÍÁª{‰\[M3FÛÿÿ‰€ÿ êÀÁ‡rxfVjbG*GÊ€ÿ‰€ÿ Ñxcb[oa<*_Ùÿ‰ÿÿöžpkKbcOD+2‘ô‚ÿ‰ ÿÿã…BFKE:1.8­„ÿ‰ úýÑ‹;11/,1+ž…ÿ‰ öñ±j?.)+0(Dõ…ÿ‰ úð„@1-*,(,‡ü…ÿ‰ þû—M>?IXo¯ô†ÿ‰ÿÿ÷ߨÖÝçöÿÿþäÑù‚ÿ‰€ÿüõøüö÷òòð¡Ÿôóìëýÿ‰ÿÿ괤Ʒò¬Äó¿Í›££ûÿ‰úýΨ¬«ÅǣȴÂıªÎáòÿÿ‰úùÈ«¾¦ÄË·ÊêÇ­¹øûÐúÿ‰ÿüÀ´Ã¤Ð¹š®´×»Ÿ²¼¬§ýÿ‰ÿÿíÃÂÍ÷ÇßÛ½ÎÂÔѾÇêÿÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿƒƒ‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰ˆÿöãÏ´šœÛÿÿ‰…ÿ ð̯ž·`+1ðÿ‰ƒÿ ú·kePfTb]% "íÿ‰‚ÿù¯ŒK $M;M<5úþ‰ÿüª¦ši$+8C2!]ÿÿ‰ÿÄ”‘i[@3/" Ñÿÿ‰€ÿ Ý…‚F4,$ ½€ÿ‰€ÿ ¥Q23" 7Îÿ‰ÿÿñk!! pð‚ÿ‰ÿÿÊZ  €„ÿ‰ þù§U ~…ÿ‰ úè,  ñ…ÿ‰ úëS mú…ÿ‰ þúx+#6U ò†ÿ‰ÿÿó×ÐÍÔâôÿÿýÈ´ù‚ÿ‰€ÿôãñõìñãèéqŠôæÕÝþÿ‰ÿÿÑ€x˜†~zŒ­|ª sqŽüÿ‰þú™t‚s¹ˆ®v·ƒxÏâôÿÿ‰þõ‰µŒ·•ˆ~é’x‹úñºûÿ‰ÿý›}˜wÈ„w{‚Ç…}}“y’þÿ‰ÿÿ컺É÷Àߨ³ÈºÒ̵Âêÿÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿ‰‘ÿƒl8mk7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ97ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ97ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ87ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ78ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ7:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ7:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ78ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ78ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ78ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ7it326t—Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±µÿ ýùõðîåÕÙéù‡ÿ±®ÿøñæÔƺª™Žx~‰‚‚ ¹âý„ÿ±©ÿüòåÌ®Šve]Z]NKMOSbxŒ„œ’†§ìƒÿ±¥ÿüäɳ˜‰tiio€”¡•xxtinx‚ƒ’œ˜Ž|rfë‚ÿ±¡ÿ"öãи†~–³ÈÖÚÝÙÖº¹ÊÍ·›‚v‚•‚„i\M®‚ÿ±žÿ&þá·©¨¦›“¡©½ÀÝÏż­¦®›˜–¥­|lr“q{Œ‘v^O‡ûÿ±ÿ'á¯ztœ gdbfz— •«²˜‚¦£ur\’¯vzˆvjyiSoñÿ±›ÿ)î°……O‚Ž*2mUTbyw‚’kvŽR]p›³~†ugwŠ€vhZníÿ±™ÿ"ô†n])‘Œ_°xdo’~|†ƒ|rudb]…­¶ˆ‚|‚t€oneeY€ôÿ±—ÿ-þÖj]zR'ˆSad*#bjku’…c{o]¤Ñ½z‡¼¬‰{sqspd[]]Y¡þÿ±–ÿ-î³tar…I23?>"}€no®ÆË{¢­É´‡¶º¤‡pplomlM5HR¶‚ÿ±•ÿ.æ™`fz|cd-6 $ˆŽf€­«³ÁfkŠ“‡š tV]leL/:N><½‚ÿ±”ÿ/ÕwA>K[YY^$+ [|q±­µ¼ÉtQx{ŠmVe~wkOQQJIV^^PVÅ‚ÿ±“ÿ0Ãad‚£¬ƒVw, +¡‰Š¢¾µ·~9ekyfMf}`??8COPRQRX‚ÿ±’ÿ1Èsr†›¢ž¥§VQ&& R–—km¬¬§’<_mwpG`fIBPVVFMQSRTYÊ‚ÿ±‘ÿ2Ë€†Ž’¡š{~šX`@"Y……K]‰›œ——NPyz@FSGLU]UOJUVQTdá‚ÿ±ÿ3ц‡–¢¤‘\EQjMk^@  WdXdESˆƒ…{Bq|GIsi]KIQPQRQSST‡÷‚ÿ±ÿ3Þ“€‚’•r=t{vŠu=3*U]KLXTKTT_JVWT·ƒÿ±Žÿ4ò™}s{uNL‡¾ÇÇÉŒ|`[Q?btBKjr†¨XApyro}z9@^=5BIMVNP[cOVUmãƒÿ±ÿ5ó–@ABJb•ÆÃµ¿Ë¶Z¨•l>2\i7Fcr‡3KnqtoEElaV;4?@FNMXXJSX®þƒÿ±Œÿ5÷£tsej²»¹±«±Á‚\‘•ž˜.<46_luy…_/\okDT[ST]VE=?UZUFPRyî„ÿ±‹ÿ5ü¹’¨½ºr  ¡¢ž¡Tn…Œ•”>jW8nsqrtv{H@O72%BTOQRUURLPVQNQ]Î…ÿ±‹ÿ4Àu†‘¯¬b†‡‹‹x?}„„‘s@px7jqnmlqwg-#>^I%GOPKOSTFOQOON±†ÿ±Šÿ5ä‚m­½«Zu{„ƒ€|`Twut†QKouWDdjmppfCFond.GGFHMBARLKO¢ù†ÿ±‰ÿ5ö©|w¡²½¨A_yuzUhnnrx;Ngem57_kkV:;$Wtke.9?CCBCSJGS¯û‡ÿ±‰ÿ4Ü|~Žš‹MCBCIJCX]fpsyRDNDBje%jpkjL.;@FF;DWGQsÕŒÿ±‡ÿ1Ìt”bghls_0avxwuva>V`krncN$1Z†œS"X_XTJ);C::JPDL†âÿ±†ÿ1ü°]Šg^XakyZ?j}toyKF^^Q@;5q‡|{6EHFGB0;=3APIE_µùŽÿ±†ÿ/å‹Ww†nY`p|o{c?]iljfS134=Ul Uonca"%:?=>C>13HXKY€Îÿ±…ÿ/ý¯sja{‰R_€Š}src<=EA:=O]ceyL QXWS>(149BE6@RZTW¥ï‘ÿ±…ÿ-ÓrkqRhw]CXoq^SK+&:JZgaWLDFIB2 )3?IGHNCUyΓÿ±„ÿ-ú̈[bNIQUQHHMHAJ-CVlmS0'+:-&/24:54;BIHFGGg›ç”ÿ±„ÿ,ä™bAD>DY^N?BOYW2-;CGA7AKYgaKDFDEB?>@EFEBBfÅù•ÿ±ƒÿð¨¦{‹_H;;KSH<3?GN^XE:@EINIDA€> ?BDB@BELLDEe—ÿ±ƒÿÜŽwVum@MB9;PSF:DVae]K@;€9:8979=B@BBDFFBKeÁþ—ÿ±ƒÿ)Û„‚kUk=5717DMKA:;@B??E?==>??C?@ECBDBACANpÈ™ÿ±‚ÿ)úÏ©»˜JPF39925:@ULC>;>AEC@A?@ACFIHFFD@CAUtÄšÿ±‚ÿ 駉—˜d^e;1€927AFB@BHDCC@;88=@CCAB@=;;T€Í›ÿ±ÿ)ýÌšjostBG:++4@91.116BCEECA?>?>;>CDDEF?;@K÷œÿ±ÿ'Út¥umokA/-+*+.7==<8979;:9:>?@@CB>75@eàÿ±ÿ&â’|Š h>FbG3369.'),03545:816<@B@@=656?M´žÿ±ÿ&Ø©ohsB;?>53/76*+-/1300568>AEFA?7:2053.-*/14558:?BEEC?;==<>>‰ýžÿ±€ÿ þžPЇ{QE@>I>40212489;?@ACEB?<988:>P¨Ÿÿ±€ÿ þ™U{hjvO4377€01.2<;:9:=?CFGC?9<:8:8Ku­ôžÿ±€ÿ'ý¹¢‰PMcO::=6382//>?887<>@BDB?9;=:::42>@=;=@€B€A <959FMVpžÉãùÿ±ÿ'Ö~`\A:3/001037627==;=BCCA>>:66;MZeyÆåôûÿ±ÿ%è†[E;31-0-*.133488;=?@@=;=;BDEGHIJIRcpx…Ÿ½Üõ¡ÿ±‚ÿ!袉wbUH?;:9<==BJKMOQZcddiq{‡™¤¶Îèú¢ÿ±‚ÿ ýϧš‡ysje`ZWWX_hkkoy~†Š˜£µÂÐßðü£ÿ±ƒÿôÒ²¨¥ž•“–žŸ¡¢©­°¶¾¿ÅÌÜåïøþ¤ÿ±„ÿóâÖÍÍÈÊËÊÄÀÃÄÈÍÐÕÔÓÔÙâåèîôøýŠÿüàÍáù”ÿ±…ÿøòîíìëííìêëìëëí€ðóõùûûýþþŠÿóÎÃÉ»½àþ’ÿ±…ÿþýþ ÿ í»ÈÒÏÔϨÐþ‘ÿ±ªÿ øÈÉÕÓ×БT£ý‘ÿ±ªÿ ×ÍÜÑÙÅ{E\¸ý‘ÿ±ÿþ‘ÿþ„ÿ ʇ¤ÀµdEq¼ñ„ÿþü÷€øý„ÿ±‡ÿþ÷òîáÖÖÙåôÿÿüûüúøïéçöÿÿûôãÖÎÏÚïÿÚ~X\RQ‰Ñùÿ úñëâØÑÅÊÍÑÒçü‚ÿ±†ÿ+îÖÎÎÏÉÐÎÎÉ¿ÓûàÍÏÍÏÉËÊ©ÌÕÌÄÊÏÌÎɹÔýþòêѬ¬µà€ÿó×ÇžÌÒÎÏÏÊÖ¿ŽÑ‚ÿ±„ÿþâÇÏÕÕÔÏÓÑÎÐЫÅÛŸÅØ×ÔÓ̼ÃÇØ×ЀÒÌ¢Íö¼ÌÖÔÔׯz´ÿüßÃÅÅÊÒÓÔÖÓÏѾjL¼‚ÿ±„ÿ?åÄÑÓÙÇ“ÊÖÍÒͣɆÌÓÎÐÍËÊÍÏ­¶Ô×ÒÏÔ¸”樔ÕÒÒÓºjÁÿÖÀÍÊÏÁl޽ÕÖËpE}Ù‚ÿ±ƒÿ@óÆÒÐÕÈoERUˆÔÐÏÖ¯¬Ç~—ÓÐËÊÎÐʆGVœÖÔÐÑËÎЃ¹ÕÑÑ·iÌëÀÌÎѾiD\_X}¼”H}Òü‚ÿ±‚ÿ@þÜÏÒÓÓ}JÀ¸‚·ÓÎÖ¹ˆçדÉÐÇÐÏËFm~ÆÓÎÐÓ†½ýº ØÎ˳lÉÍÆÏÒÅnH…ÉÉ udNpÏýƒÿ±‚ÿ?óÉÓÐ׸Y…Íàà°«ÒÔØ¸|åÿ½¼ÏÊÑÖ§KwÍð·ÅÒÍÑÎz¦ÿë«ÒÊϵ}¾ÄÌÐÕœJ„Úÿÿúߍ޽ù„ÿ±‚ÿ7áÅÕÐѯÅÑËÌÌÉÈÑÕ°zåÿØ»ÏÏÔÔwdÄýÿÉÉÏÍÔÆc§ÿü¿ÊÎÖµ€´ËÎÕÑojÎþÿùöú…ÿ±‚ÿßÌ€Î1ÖÙÖÚÛÙÜÖÎÒÕŸqåÿåÃÔÒÕ¾Y›ôÿêÃÒÏÏÛ¥W¿ÿÿÇÉÒÕ²|¶ÒÒÕ¿[ž÷ÿ±‚ÿ5ÓÌÆËÓ³¥¥¨¨¦¤‘†‘¨|wéÿçÅÕÑ×›[ÈÿôÁÊÐÍÔÎkfØÿþÆÎÑбÂÔÒÕ²dÈŽÿ±ÿþÊÎÌÊÔ}IKJ)OTUQOš÷ÿçÄÌÇÐ~ráçÅËÓÎÔуJ–ñÿþÈÌËϼ„ÅÎÆÐ¯qà†ÿ÷þƒÿ±ÿþËÎÎËÒ”‡‚®)»ÏË¥›®àÿçÁÏÑÑ{‹ÈÃËÑÌμzElÍÿÿþÉÏÐÍÃ{³ÎÏÕ±sä„ÿûÙÈÄæ‚ÿ±‚ÿÎÎÏÍЪš÷ƒÿ'æÉÀj¬ÿëÊØÑÐÃÈÓÑÎÌËÌlFzÂøÿÿþÉÏÒνk ÚÒÐÄÙƒÿôÇȳa¼‚ÿ±‚ÿÍÉÒÒÑ•ڀÿþîÌÈÙ”U¼ÿîÍÔÒÐÍÙ×ÐÑÑÊÕ­…Êý€ÿþÊÏÑÑÀp•ÏÔÏÔœ·þ€ÿúâÆÈÙ‚YÊ‚ÿ±‚ÿ$×°ÓÓÎȼ·ßìçÕÅË×Ëe|äÿãËÓÐÎ}†¾ÕÕÒÅÍÙDZ߀ÿþÏÑÑÔÆ{”µÖÏÓÊ¥ÍóøàÃÅÕÖ¿Y€ê‚ÿ±‚ÿAåœÊÙÆÏÒÈÁÊÎÎÓÍÕ¨T«úÿÙËÐÍÑtVc•ÌÑÊÒÊÏÄ²ÍøÿúÈÔÑÒÍ…©•ÆÔÐÑÍÂÅüÒÏÍΜWµû‚ÿ±‚ÿ@ú¬ŒÀÎÛÔÑÓÑÐÎÍÊÔ|jÝÿÿàÆÒÖÚŽš—fo¤ÖÙÏÎÐϸÂòñÇØÖÕÖŒ¬¤ƒÈ×ÓÔÚÚÌÖÛÒÐÏppáƒÿ±ƒÿ?áp—«¶½­£ª¨¨£Zöÿÿ㮪£°†žíʆ_†µÃ¾¸±­æÇ¾ººÀ”žÙ„nœ»½·Ÿ•š†}zsN˜öƒÿ±„ÿß–bTWRKOT€UR`À€ÿÞhJPTPúÿçµsXYZYSJKŒå€OQQ‹õÙ‘_ROMKONV``_rÇ„ÿ±…ÿîͽ§›ž´‚¿Äê€ÿ ê§¢º½©¿ùÿÿúÖ«š€›®Ó𢈚œ››¸øÿìÄ¢››¦¼ÀÈÜßßáõ„ÿ±ˆÿýüüˆÿþüüÿÿýü‚ÿƒüýÿýóóûüÿüŒÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ——Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±´ÿ þüùõðíäÖÙèø‡ÿ±®ÿùòéØÈº¬Ÿš†“ˆˆ”¦Àäü„ÿ±©ÿûòæÐµ–†xtrugimos…“œª¥•Œ êƒÿ±¥ÿûàÆ²œ‘ww˜®¾¸¢§¢’–¢ª¢¬¥•Žp[wè‚ÿ±¡ÿ"õãѺ¢‘žª·ÍÛéîô÷ö×ÓçêÓº¥—“¤Ž„v`Q>¥‚ÿ±žÿ&þá·«²¹´ÅÐÛØâßøþÿ÷åÜçÇ–ª¹ˆ‚…“›†‡r_P=yúÿ±œÿ(þà³…|¦º¥®²ºÍÒÎìôëÜÉÓÉ›o9Ø’†Œƒuoi`O=_ïÿ±›ÿ)쫇T‡–2J ‘“˜©¢¶ÏÔ×ÅÄǨufRšã¡Œ‹ŠtheZSH@]ëÿ±™ÿ+ó½‚ri/„•—k"‰Õ®•›·›˜¦¯´¤—€v~­Ó ŽˆˆyiUJJ@A;nóÿ±—ÿ-þщkk’h1“]sv3$uœ¦±Æ«{€rg·ÞÁ˜–”»®ŒzvseYL?98::’þÿ±–ÿ-í­ohˆ¥¤_>;LK2µ¿Â£šáñç’ÎéøÎ ÕÀ^V`UIJ3 /9¬‚ÿ±•ÿ.ãŽXt›©Š…9@!0­¼‰¤ßéõðƒ©äèͬ»½§Ž`4EFA9&(8/,·‚ÿ±”ÿ/Îk9>Y|„}-0  oØßó÷îˆzÆÈ½ˆ‰’V+711>NMMDE¿‚ÿ±’ÿ1þÀdu¥ÎÉšn¤À:"" 5»áÁÁà÷ñã–[¬¹´}az…sD'3-9FHJGFL¾‚ÿ±‘ÿ2þÅ…«ÔëïéÛÍpm//&gÈÚ¢®ÝøóܶX–¦¥V\Y;;JNO@FIJGHMÆ‚ÿ±‘ÿ2Ô›¹ÖâóíÔ»Ãp~W$&("q³»t›ßôëÕÈlq››H@JET`]SKCLJEGXß‚ÿ±ÿ3Óª¼Òèñâ¢ypc˜”f,h€x„]ÑÞÙÆ½¢S†DIƒ€oTLQMJGEFEC{ö‚ÿ±ÿ3â§¶Êçæ­UD‡¾âª{ª“‚8:EH“Ÿ²³U¢¸º·®®€A8#WzpbZLHKFM;HFA®ƒÿ±Žÿ4òª¥¾Ì±l[’Îëêæ®§Žˆv]ˆ›]j®¼ÕoYœ¡¢¢š~9IjHESRKOE@CI=JBX߃ÿ±ÿ5õ™MWfht¨ãùøôôÕvÛÅ•]JvƒNk›³½ÀªDiŽ•‘|FOŠ‚mA29Fj’=dj_D'253/8:6F´ýˆÿ±ˆÿ3õ¬Î~ÀÞàÍ„•£pONQ>[ruusU;aikkX)E’®®F=dZQG.!2396:;E¶Šÿ±ˆÿ2׬ÊÒœ\v·¦aŽŽ‡r0Vjqrwzq;S\aV=6%­¥ŸOEG@;;8,5<;GV½‹ÿ±‡ÿ2ø½˜¨»½¥nUCJ„‹Œ“—MSimszvrL@LEEvs4•˜ŠV.77:7,0B8BeÑŒÿ±‡ÿ1Û±×Ç©œ–‘†h?z‘”“’‘pG]cmsk[I%9p£»f3||j\I%36,)6<3<|ßÿ±†ÿ1þÖ¦ÖȘˆŒœkK}””Œ„~JCZ[PA@I™»®¤D+[XNF<(-/%.:54Q®÷Žÿ±†ÿ/øÌšº°Š•¢”ŠiFerupdO/6=Rn,~¤ ‹*0ED;77/""3B7DqÊÿ±…ÿ/þÛɪ•š¤r~˜Œwsb;=DA?F]vŠœ«^2{ƒygM.52052%.>F>A›í‘ÿ±…ÿ.ॶ«wx~pZmudYNB&1Vvœ•ˆ{f *_`T>$#(05-0<6EcÁþ’ÿ±„ÿ-ü溘•gamg\MP]aW\:/j‡‘rG;=F/ *12370-247563/Nã”ÿ±„ÿ,ñíÔ›eU\kkZJKcrwn?;S\VLAJUfqeKA=97653465485P·ø•ÿ±ƒÿôÓìÇÓbNLUUKEBJNPYP<5GLORLF?973/114;;47[¾—ÿ±ƒÿ+îÌ»¡_W?DFCCIA;843241140.34353>aÅ™ÿ±‚ÿ)ýïÙïËvu]EG@1/6BNB:6247=:430/,+.23136882Ae½šÿ±‚ÿ(ûèÒÛÞ¥•‹M?B<5075.,++/:98421/02..022872-5J¥û›ÿ±ÿ(õÛê°|µß”ZWL6413436-,*+**,,/.,0474581-+5Œøœÿ±ÿè­ÕêȪ§š}RD;1+)*4740,--+,€*,1€530(%*TÞÿ±ÿ&÷ÐÀÐÜ™ienTD=::-&))&'(*,-*$(+-254/'%')7¬žÿ±ÿð즒½£paXN?6098,,)%#%()€* ./1551(()+*Vçžÿ±ÿÙ¾´‘€wm\]mF:8:4+*'('(,-*+/2€32,+*'(*ýžÿ±€ÿþ¹vÄ̱mRGEOEB@<3€-,-/..--/2541.*'%%'B¦Ÿÿ±ÿ&²±š’”aB@?<5421-,3/.+,-,0241.()(&'%7d¦ôžÿ±€ÿ'ýÖß¾mg|_HLI9/0+.362+*)+,-/0/,('%&(+0Ez«âžÿ±€ÿ(þÚŬyMGB<=<5.20/431.,-.022110,& &5>He”Âàøÿ±ÿ'Ý£ƒoND;6620,-/1-+-,+-1331.-(%%*=MYo•Ááóúÿ±ÿ%éuTI>6-.*(-10+(('*-/00.,-*)/cÊù„ÿ±©ÿúïßÅ£{gWPI8,/671-.E23.*9yãƒÿ±¥ÿúݾ¤‡wfefo–¥’ŽjU9)#.PiX;"Vá‚ÿ±¡ÿ"óß˰–x„›¹×èêêãÝ¿¼Âůu6:9/"  ’‚ÿ±žÿ&þÛ¬£«§´¹¾ºÉÏóûôáɹ»>7VqO)$( ^÷ÿ±œÿ(þÙ ty¯ºƒ…{nr–ÎÊ¡‰ˆ M HwP0""  ;ëÿ±›ÿ)è›ioN’¦MN18;F9%NRO:(//"  ­‚ÿ±’ÿ1¹_~ªÏÙÊËÃ[O%  9QJLC:GLLN)KUSD!'&  ¶‚ÿ±‘ÿ2Çv²ÇâÚ­¡±_cA  7GQ?:DTRLY17RSH!$&   #Ô‚ÿ±ÿ3ĆÂáîÜ”eaqRq^; 92!7-,BRKCJG">B!$@6(   Oò‚ÿ±ÿ)Öxޱܿ®T=qŸÂYgNR"$%4)+AJ6D??@I9*2"€   —ƒÿ±Žÿ4ëƒoŒ©¦mW~£§Ÿ«‘‘cQG+:> $951F,"8<>?B9"1    ,؃ÿ±ÿ)ïŠ:@LVk”¸¬—†R¯‹^?'CF#,?=/5@%9;?8!:, €     ‡ýƒÿ±Œÿ5󔌉isÆÁ¦ŒQ@rqy‰%, 7@=628.-4/ *%   ?æ„ÿ±‹ÿ5ú°§ÇßÁ|¹¯›†wkb/F[[_p(N7;A:2.0: )  º…ÿ±‹ÿ4·w ¤¯Í¯gœ˜‹zn]F KULYP?V'+15/+.4-  •†ÿ±Šÿ5Ýp{«§¬Á¤Z{{vjcV6+II=F/9K>&0/.,% 0!  õ†ÿ±‰ÿ5ó™s€£®±¯™]m4F@:840$*%€"  2#!  (­þŠÿ±‡ÿ)ó“sey…\0.,$BA;88<)($! & +! € 9ÅŒÿ±‡ÿ1¼…¢f`f@3D::C@;74&#&$ )6&   XØÿ±†ÿ1ù¬tWHW7'5C05?<4-*!  /- ,     “õŽÿ±†ÿ0í°b_B1HJ,&*2%$**&! *E+,""    Eºþÿ±…ÿ$úÒ¬oL459M0 "$-7L3" € €è‘ÿ±…ÿ$ʉ‰s7 ).   (.-*)+ €0°ý’ÿ±„ÿ-õǬnT0!"(5A>,     aØ”ÿ±„ÿÝÚÎ~0') %%%!€€ •ö•ÿ±ƒÿî²Ð©Á['  € €  Ÿ—ÿ±ƒÿ+á­’n£w$   œþ—ÿ±‚ÿýÚ“z]e& €€  «þ˜ÿ±‚ÿõĪεF@2   €€¡šÿ±‚ÿ䣔³¾{^P"   € Ÿ›ÿ±ÿýΩk`o‹N6   € ù›ÿ±ÿî´ÝŸOzªp0/(   [ôœÿ±ÿ'ÙÁ¿eTI6!  %Îÿ±ÿß© œ¬`%* €  žÿ±ÿѶ`~e<-! € (Ýžÿ±ÿ¸ŠŒa808. €  ^üžÿ±€ÿ&þŸW £n0 ‡Ÿÿ±€ÿ þhWMA   €;‰ïžÿ±€ÿ ýÁÇ”2!(   € !X‘Öþÿ±€ÿþË­€<    %G|°Õõÿ±ÿ'ÖŒU2!  ,:T€´Úïùÿ±ÿ%ç‡P&   ,CTl•ÅíüŸÿ±ÿ#ý¤V>+   "3ERe„«Óò¡ÿ±‚ÿ!à€aR<,   !.24>IUcy‰¡Àáù¢ÿ±‚ÿ ü¹…{hZVL>5/.,+/787G‚Ñùÿ øéàʳ£’•—›¨×ý‚ÿ±†ÿ+à®–Ž‰ƒ‡†…‚‡ÃüÀ”–œŠ‰…·¯†…„„‚…ÆþüÛζŽkdlá€ÿí¼•Š‚…ˆ…††‚ŒvqÒ‚ÿ±„ÿþȆ…‹‹…Љ†‰ˆq¼Òh|Œ‹ŠŠZx}ŽŽˆ€ŠoÉô„‹‰ZµÿûÊŒ~~ƒŠ‰‹‹ˆŠw@H¼‚ÿ±„ÿ?΃ˆŠ~XQ_ƒ†ŒƒzÊ}P‹‡ˆ…ƒƒˆ†lr‹Š‡Œté\Œ‰ŠŠxTÂÿ½~‚ƒˆzXGYwŠ‚EA~Ù‚ÿ±ƒÿ@뎈‰}Dn“d€Š†‡†X¾ý¶j‡„pZÉ ~†‰~EE†ÉÊ¢sO?qÏýƒÿ±‚ÿ?싊‰t?y»ÎϘp‰‹vmçÿ¯y†‚‡‹g>yÍò¢€‰…‰ƒP§ÿì…ˆƒ‡rn°„‡‹_A†Úÿÿúß©½ù„ÿ±‚ÿ7ÊŒˆ‰~p…Œ‡Š‡‚‚ˆ‹plæÿЇ†‹ŠLcÅýÿ¤†…‹K¨ÿýœ†Œqp–„†Š‡IjÎþÿùöú…ÿ±‚ÿ6¾ƒ…††ŒŒ…ˆ‹cjæÿ݉‹‰ŒzDôÿᇉ†ˆ’gMÀÿÿ¤€‰Œqj‹Š‰ŒzG ÷ÿ±‚ÿ5¨€…‰qjjnnmd\WYjPwéÿߊŒ‰ŽbTÉÿˆ„Œ„DgØÿÿ£„ˆ‰pk’‹‰ŒtXÉŽÿ±ÿþŸƒ…„‹OA€D+CCLSQKG“öÿ߉„‡Qsá×”‹†Š†P@—ñÿÿ¥‚ƒˆtj“…€‡pfá†ÿîõƒÿ±ÿþžƒ†…‰_…°¯»ÐÍ›kŠàÿß…†‡‡Ms›‚Š…†vK;mÍ€ÿ¦„‡‡}c€†Špfå„ÿûÂŽ¤ç‚ÿ±‚ÿ¨‚†…ˆjŒù‚ÿþÑxT®ÿß‹Žˆ‡yˆˆ‡……€=C|Âø€ÿ ¥†Š†zWtŽŠˆ|eÛƒÿð¤ƒmP½‚ÿ±‚ÿ³€‰‰Š|mÚÿ䥃]Q½ÿà‰Œ‰†‚Žˆ‰‰„‹kgÉþÿ ¦…‰‰|\v†‹‡Šf°ÿùÏ•PWÊ‚ÿ±‚ÿ$ÌrŒ‹‡‚v‹ËßÕ­‡‚C}äÿÍ‹ˆ„GRyŒŠ€†€ˆØÿ§‡‰‹_ˆuŒ†‰s¼ðöΗ‚ŠyB‚ê‚ÿ±‚ÿAåt€‚‡‰~ŠŠƒˆ…ŒgH¬úÿÃ…ˆ†‡QQG\ƒŠ…ˆƒ‡{|¾ùÿù—ЉЄ_©o}‹‡‰…|‡ˆ…‡aO¶û‚ÿ±‚ÿû§[xˆ’Œ‰Š€‡4…„ŠLiÝÿÿÅŠ^š™_Jeˆ‡ˆ…vŸð뎌Ž_¬ŸW}‹‹…Ž‘‰…‚Ipâƒÿ±ƒÿ?âŠN_mpxmfhmllgC‘öÿÿÇmlkpXœíˆNTr}|zwo]©Ùƒ{zz~^™ÛKau|teb_WSIAA™öƒÿ±„ÿà—^LFAAKNL_À€ÿ+ÙZBLLFûÿç¶pKEFFC?Hßs?BBCCŠõÚ’XCB@EKJU`a`sÇ„ÿ±…ÿîξ¨œŸµ‚ÀÄê€ÿ 먣»¾ª¿ùÿÿú׬œ€ž®Óñ¤‰›œ¸øÿìŤœœ§½ÀÈÜàßáõ„ÿ±ˆÿýüüˆÿþüüÿÿýü‚ÿƒüýÿýóóûüÿüŒÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ±Éÿ—t8mk@¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥ic08¬#‰PNG  IHDR\r¨f$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½i“d÷uæwrß3kß{©ÞèF£»±A$HŠ )Ž,™CQ#ÉÖLx<ö û?Â8ž‡ÃoòÌ„%9$q¨á.ì ô¾Uwuí[îûžþ=ÿ$†BbD¡î²«*óæÍ{ÿyÏöœçœã³OÙ6 þ%—ô/>e—å]Î'cþŸÏ÷_}2Neoο7‡ñŽâ­€·ûq<°¿5Ø£ðÀ-¤woöã x `?~kÞ9{+°G+à)€=ZHï0Þ ìÇðÀ~üÖ¼söV`VÀS{´Þa¼Ø+à)€ýø­yçì­À­€§öh!½Ãx+°WÀSûñ[óÎÙ[=ZOìÑBz‡ñV`?®€§öã·æ³·{´žØ£…ôã­À~\OìÇoÍ;goöh<°G éÆ[ý¸žØßšwÎÞ ìÑ x `Ò;Œ·ûq<°¿5Ø£ðÀ-¤woöã x `?~kÞ9{+°G+à)€=ZHï0Þ ìÇðÀ~üÖ¼söV`VÀS{´Þa¼Ø+à)€ýø­yçì­À­€§öh!½Ãx+°WÀSûñ[óÎÙ[=ZOìÑBz‡ñV`?®€§öã·æ³·{´žØ£…ôã­À~\OìÇoÍ;goöh<°G éÆ[ý¸žØßšwÎÞ ìÑ x `Ò;Œ·ûq<°¿5Ø£ðÀ-¤woöã x `?~kÞ9{+°G+à)€=ZHï0Þ ìÇðÀ~üÖ¼söV`VÀS{´Þa~µ ¦‡¶÷þjGôÞýaV øavòöñVà£^ŸÏç_ÂïãþûÈ]e°«œ~xOQèùn¯eívÍýôû Ä,MX 4ŸÏo~€Ÿ:š·ý¢ðÀ/Zïùlg$\‡ç·~Ïz]ý.?;üì[еF³j½AÛº<§ß[¦u;=ë÷ºî=ú™Í>²íìCëôÊ Fx¤,•³É‰c61qĆGæ,MZ8µ`0ä”ÂGvQûôÀžا_Ü~;í>‚Þê4¬ÕlXµR°N»iÍzÕŠUk«×ËXóºU5k÷úÖìÔ­ƒR¨7ëV«×¬Óéìê þF£<º:^gêæ÷uP} øC¶ð0cÑȸe2Ó–š²Éé#65yÜÆGŽZ"1ºß–î#=_O|¤Ë{0Þëu,_ÌòرZ£ì„·†`Ëy«#ð•JÁ¯[»Y±~¿bÝ~ AnYåP®#Ô܃€Ïú]G¿Çß¾¾ ü8ϧÒJu,L[(·@?‚÷Páõ ÆêÖ®Z EP*EÌÊ){T³ñõY›:gsÓOÛØÄIKg¦æ—ó«öÀÄûóï€âp¹íÍV ^µjá®–-›ß´UÛÉnY¥^š·±âXþš„½ƒËÞ³6ÏÉj'’]óùy½ÚF9`åý`´P$ŒËàd|ˆøø]Cð`¿0±?ûÅÂ1‹úÖàýí–Ï2£qKõ ÀJ…–UjMËÖPF…‡¶Ú¾c#±vèðe;ñe<ƒc(”Ї¿àOážžø~©Å%õˆ¹[¸ãív aÆm¯”œ{^oT­ˆµßÎó(æ,—ßq:î|¿?°>‚Û“è‚éù> ÇÃI¤,îò,1¿¿Žå¯âÄówÌgÑdØÅì½.Š©W¬ ôÔ ^ß’é¾E‚ƒ]Áå½þDߢ1B‹¯ž¶„µd'm¥ZÍRƒžùœçجԭQ.ÚzéGvçÖ ÛÞ\³Ï½øm;4ÿø@ø£X²}qLO싯éã?É‚.!oµpÉ[M+— ¶½³Ž`-›Ûvn|¹VÆÂ×póVoõr¡ï>5 Ÿ²p,b‘xÄbI¬t,fa€ºH"fÉL¹øÙ\Áv Þ_·‘Hß<ßj•ñö{V.”ÌG( 4,nX8Z'®o[(ÚÄåX ï ×¯;bѶN [24iƒÚ¼óÃVªä-œDìd­UÄë ¼£rÑe·×í‡õo­\jØW¿þ]›?ù¤ âæ)€ƒø­àš]J W^Ö]N»m›ëËvïÎuÛÀR6ìêíªÕZ ñò°ÎãÃfáˆ}Ôb íá´%ÃCt~yQ@2•°±©1™µ(îz1Àš×À–ÖsÖŒZ³‡{ïk„±Ì¬ƒ‡Ql–þVlñ;Ÿ‰«Þ#ÇßÃ=û{–´‹Æ“(’ Å NÍžÂR‡8·–mfW¬R~®–‡7ÒhuÇQÉÖ­•k¦må2èúìÖÍUb~)³‚€¯n²á~ ÅѶJ£k…RŸ0†ó,ñÛN¹lWÞøk{ò©—Pó¬'{À6O/¼¯ü:i5¹òù\€nÓvr;ù&YÞÚäâ#Xì*h|w=y⸻ü¤¥GÒ6<œ²X(lVÛ2É Üo…bÁ†‡FmbdÚB¸ü>6.>âe]„Û€èøD—Óï´{x ktj(ž #b¹JÎîÞ¹bÉ^ÅŽÁsHò¾ A&i­~ÒjµŽÕ·J¸é:¿ÛFA«yŽ]50C˜"dH†"\KQ5_´‹ôƒ,p-a0a¾î€t#¡Š.‚BêâtÛ:¯€…ñú‹ùœÃÚÍaÚã€mžø”ábÔ•Ky[\¼g‹X°®D¾BHŽŽÚôÜ›åÒp€.O‚¿Øuûîu'ü¬~˜œ™¶‹—ž³>i¶àP ±2[Ûܰ" `Qs`mâæ0ÂöµÝp£¨d! §¬F\«f-’Œ˜¿ǽ÷»´6ÞÚ½™‡¼| ·½’/Z¯Îû±¼‰HÈÒC1«V±ØÒ‡«6hoXa‰¿ËU×jÝ }ý»Ã66=fë傸†Üú°ùI&ú%ã3úV¯6¬ÒjaÙ1ùý Š…%ÅÄ ŠeÈ~#(€×Ô’"@¡õ{>롘v6—¬\ÌÛèä‘t‡ì^ªç|ʾrQg‹p––ïÛ­û·ìÞÒC«×Z–ŠãâÂŽ;eãs¬Mn}³¼e¯_ù©Ý}t×s#ªG{ßA–ü~<,¡oY"Ô²d”||8›²ÕÍŽí @®‰5öR¹úNÅÊíUË7¶­kß õÖ©v,ÜÄj‡3äàaèþWï‘*\¶âö#ógóæ/÷¬º>°5è¾pù‡¦§,63nÍ\Ûú;(ª2!Ùˆ +E KÐAàÉ@X¥MøèÄ`Á&ÂÞ"mˆ‡£D#1 @\)#MˆžaR‰x:¨¥1«U4ÊÜ<ð)ùÒw¹ñë¶ôèVÿVý!15–¹DÃÕnàBZÞûáOïšÅÍ6¶ØÒÊ}K²#G2–ÝÄ"Ì…£XÎ`Û:þ¦õþbë6‚‡»ïóglq©h¡ô¤•zkVÞ!?ÏÁRÑ!ñt{DzU¨½¤ðú-,·_©¿„CQëûþ,q}¾`¹µŸW1žÑÔÞ@ÄÒ1BŽXŠsˆYrO7…‡1„ð·;|>€HAÔ¯ö%ä\[Wž‚,Æ x¤',Ä#À~¼€ ¤ßa"âÄøð \ÃK!A­&JrãSr'üý.ÃS¿õúÄí-W¿ Áemå½ýæíÎý¸ÍM;tì01ýˆ½ùÚ]»~å¾<ñ˜O¥¦’å³»yãŠ-/Þ¶áÙQ›ì¨MDR¸æ› g€w½<¶¥Dˆ}QœX;2_Ãò6üVÞ¬Ú°¥-2}·²nE¸R¼b¡TÉÚ€…íNеµÙ?äÃNÇú„Mk ÄZ×J]¿­o‡pß㨎¸Õ ÷âú‰¤ùB1Ðü¶ÍƒT£Uë„ÈùKò•û§Ê¯Þ<òÎ/ !›è£äúm„¸ÿ]Ö¦­˜ˆEˆ¢àމÛÀïÂüÃV^@ÏiˆOÜ×û‘Ÿ§>ò%þh>@Å5M4ùìº-Ü»fï¾ó†=Xºk~òï]:ÛþâU{õGWíòåÏØïÿÁŽELØãgXAùïÿÛÿÎïß±üƶeï/ÛSO?a‘ÃG¬T/À£"(€k­ ‚AÑãkQ,k@¯Å‹ç±eCéQêv6Ò|üÛ`)bu1ù+ÝÉ<^kaµŠ´JÐ~KðûQDá8akr&“C6¢ €p  ˜r‘ !»BXyP ;€~R“Ý"Œw@È~ëê(ß/°QB <@Bïšä:¤ä,È@ƒ€MÄâ&­y7Oì·o!lCÌÉg7ìÎÍ7íÚµ×Y§Íó‰±q€¹´ýà×ìÚ›·lkmݾôòWìÛßù={°ðÈ®Ýܲ­ÜËO'Iñ½b[»öö÷lùÚ}[9|Ã~ë;ß´d›•Z‰Ðà–x aÄ5FÀ›•¶±Àé);vqÜÜ~hï|ïª||ÒæÏNa]ýŽ”òWÇB66š´¬¿bvÅPunÿúý ²<“”¥S<€>•Ü‚,|Ì’3¬B2Ê€GàE¨ òÙØgÂÉ«P¬;ç ¤hÂWhÞí¢ þ}b‚ZápX† Š$ødx¯þê9^›s ’YI¦ƒ¸y `}ë"ï”pÓܽj7¯¿FZï–•àçù_SýèVZ/ÙÕ+·Èõçûîäc§lþÔI,ê²=ü³·máÑ[<9jO<}Áž~þEâß [Z¸eßÿÿ¾gs“Sö;¿ÿ%ágb¶¹³ÜT],v23j‡Ÿ±éôQ8Ã6:tÁn½uÅÞýáköÆ_ܶ±‘l¼ˆI!6|øÖ­>>µ†Å!ͼ4wÌ.lX'×´‘6|€ÍZßÂp &†ç-™Ã×Á–_Y7?ÅC©™õ’ú¤€A”M!o#ì]TB>~Ï HˆÐñ¯é9ÕФ­ô ¼ ž:@øwkÚx€¶‘±‰}t'ìÝ©z `ïÖò#=R Ûý;oÛ[¯}ßð—áä׺V¬• ÃÆ{ú…ÏÂßïÙÇ›VÈ—,=œ¶øp”Ñþõÿ±mn—íÜS¿i'NŸG °îtÌ™>tnÀ:hzÕþÕÿø?CϽi‰Óq+´ŠÄã îäçÀqÁx¢š<黚 !¸“ðûG7©Ê[³5ù­zÀ–ÖZ0»¤@ÐùÑ©¸=õü¼=ùôãvdö„„Çm{½aWoÞ´­M„¹gž<ŽUNÛÎýºU6²öÌùS–„\ßÚ².U…}ºV RÕoºú™ô²Ÿj@â~øA0Ÿš…4ú|p\}?J±®Øe" rp³AR›‰p`úQ(„XšÔèqúŒ}¤ßß'õàžø¤~3ï—býùüëoÿˆ8ÿǶ¶7Ÿ›¸‡Û#g¢ü5‚0F!å¤SVaß&¯H5'ÏœEÈüöÇÿûÿF¸pǾúíÿ·xÎV 7×ï`ÝoYvë.n5¨?@ÛvvÛþõÿõïlâ̸~nÞÆcÑCÐ_GÉ”jÛ¸ËÔßg‚öîõ[_X°ù§ZváüˆM P¾<ˆL6ˆ¹ü“‹¥’öÂsGlv~ŠXœ[ó<~æ¸Í͹pCÉCò+¯V¦+qsœRÞé¶fËêè²]R‡Tñ!<¥ubçìˆ+.N¥\*°¾Ù²…+¬ÍÙ3σ;.X£À'KÊ­x‡!ïøb„†@öKÐksªÚ£§­AÃ%Ô õW«Aª/bµ¹ýQr…œm´nÓ1¨e#Ã!; )”¡Ì·ŠW‚ˆÁûÏÔ#Ö/ö-¿L‚-Âêú“\ƒBôÊŒ/’}­#ô÷V»Ðœ}6ŠòwÖíX‘ uêQ:\«:Da'J©ÐÍSŸ˜/ž;îöÚò‚½û„ž[×ls“î:… ÐW߆ÓqK Yrj’NÄ¥¹–Wwláú-«îàVOMØþøOlsq™Š=òèwBx a¬ºX/=„°J |‹›_-³ ù-Rg È:ÊŒ·¥dÅB˜ñ5ÜûýÙ«öìK°¨U[¸{Ûn­Âb˜e7è/sÏ7Ñ¡d·cY2…Ö#\ûªE)&*Sݯø‘ Š‘Â¥Q!ƒÎYÂß$öoàÉPLf¤kãã~²Xv&ÐlD,C2ÉÌÈr›rd°”£À@‚ªOÌ]ðqŸˆ§>îÿ¹ŸÇÍ Ú}ÿö[v嵨­[7íáâùý"•pzXôE5›¥–Í_•ÏŒÃz%ÝEÜ…_ß°¢Ý»zŸ€=—Š!äTàÕ}€i¤wÈã#} zê”ä:– îp~÷^„)UðvÞ(†²N7;oþ àmÑÆfÜèÙwä(€ÙÈaûÌg&Á Z¥¹bþHÜ A ‚Q#ÎÎ`–IQVV ælÓ3¦¡´~ÙG~”ò¡ŒÂZ†×Ð¥6?_$Œð…š¸öx äõÉšÀþùþF´Ÿ”^„\^T‚I¨FF@®¿:UØÏ‡µý8D¬ÏEÁð“Tbr‘øð”`-)N„Ÿßêvp¯üô«jîE9ßÿÞŸÚÛo_³Gë[Fÿ —{Ÿ™?i£4Ýb©ÖÖ6ìµ?ýkR{qÇÉ[d±—¾ù;6Jò~ùÚMû7ÿÓÿmk÷Ôj››^1½BµêRŒß‚Ö§Á®?€|¹×Ä­'²À+hÒw/f_ü­#vîÙa‹Ž@©ÅuÏoC³m&­ ‘¾P^Gd)ð¡Æ~@?"I5ôhö"Nñ„°´Ãx¡p„&#TîPLÚ°'vÞ‹jô;¾ctóinéBT‡ÍGžŸÓG¸€"è©Iê)@‘–{<ˆ<ä÷ « ¹µX×Фá'`¢Öº~ÏQÞCƒE„§Áÿ\?J@ É[¸Pét;|¬§â)€u¹ÿÃÒÿúÏþŠ<ýÿa –¨…Ÿ°/~óiž;bÉÉœzýÑq‹tm­Bû]Xd¿EŠ~XúPÔâ™6 :ˆÅ#rÇU'4¿GwœVÁ$!&•„?¯’àãl¿r…ìí$ ‘PÕ¼oaj*ms§G²ÖŒ@ä!üˆóžµ{U[\ÛvŸü‹ÀæK€EˆVK8 7»'tŠ!Îë ÊŠ 4ìˆÄ7!ñ$'¨(¤ŠPÂh->“ .Ý{G&â„ „Ôp8C ¨½QJ|Cœ«‚•áCWÕ<¼7 YÂQO@Ý„£„=$ü¦ágÿ>â¾0Þ'…Ç…»/Àâè¯Ì"âÿðK9@Ïx à×øeçs›öÃü©}ÿ‡n; Ú'¾ñ›ƒµ—Ÿ´øÐ„%FfB]Áî`Á2éÃvš:ùù˨³ÏÙ?û!¨ÿŠí,m€øÚßã ‹ÜQnœ´×È:yóáD97.«‹«5˜¶ L¸0JBå²=ñîÒæÏM’m•ï“G€úXkóQ,DCMº›áZ‡,¢xaVG žös…XwŠÕ}6>›´àÕ¬U²ÄÜdíðo"îa1‡úÿ'Yü(§ÊjÅ!óà>äøªí¯”ñ~VÚ¤0U.LíaŠÛV .a«ßæ<ôh²Fd]6B²®+ì¢PDÿåt€Bä°(=å¬íûcÈxéÀmžø5}åÒu?ýéŸÛëWb=êCOž·¡cGÌŸ²fZ·J DO¾ï©c}ýXö$–8€É/W)äQ‰¬O€‚’. Œ¿Á -5·“ONC t#N‡×ß¡ 8· =7GNzø °ònÄ*Hµ@Œ >YZõì#Yj¢bžC§¦läÍ¢Õ©îë6IcÊPvù¼ «D| Ë<XW&þÏoWlf,…RÚåí(<ÊîTà9Ðu˜8¾O?5 Á‡ØãÏÚ´¸§¡!%2-Xˆ-ÀÀx\Ÿ¿[ $- B"é;yàŸ¬¯ñ¹R18ê2tP7Oü¾ùR!kï¼ý{÷ökÖ ØÔÑSÄÈ4·¤§…ðúaÌù™g§»UÕj~ÚtU\‡r÷Ù¦UøèS3vèÄ!{zðO­¸Ã¸-XrnV<ÿ^ ?ËX~¹÷ñtМ[ŒÓÛFHdɘq|„kØE9È+Ï 'mæ0©F&ö¨êo€°u³¸ß;€sCÄÕ˜ÙHZÕ¢Þ¿ßq Ò€îA>æWÊdlzÅ4Dµ"mÄ7k6y4á÷… !Q€IÀÒCéŒO Ù­å‚•ˆû-²ãµ|¾JÏ‚H(B‹rÀUÀ[àOR€âzü:áŽ+žçü•ÍÑU(Bh k/„_{u©£Ð|Ÿ²"` AÈM#c4Q'Q­;O8H›§>æo»Óí­[¯Û›Þ´&®ìØÑ£ÄÚ#4â%§'?D¼€œBë­Êj¹Që ëºÑ*á àÚûàv‡Fš ZZYfdØfrB¸“‚ä#°FÎ\M@Ûd ZXÊ(Ø@”.@4òŪú¶ ¤ tÏËzöp·C fšÓ×g³ˆ™À¸Nî;[ê &Æ€g´÷Ó(”Ž@Ýç)ë* NŠÍ"…¥óîÔÑÙuÛ¼Ÿ³¹¹1gùU¾ã||H,ÙAÒ‡„„-uþÍ*C<":Ê©‡À ƒèdžh5Îõ38/Hc¨äÈð¹h72"0ÉïwÀ9Âtü à•èÃÃCî¿„EÅEKÐ#‘¸ŽÍà1ìšðëÖ÷€VácÚ4ïíÛoØëËïX9 -}„8#Ã8àÝæ W¡‡°à è®ÄµÄÝE~Tp‘…´©ãM­Y´%€½ ùÿ‡÷¿sÏ^°<ôY ·6i»jü‹k4ãD dÙ$ݘ¬'Ò.a Ü‹ AWØÄô¥´{7ØØœØ†딨42_lZn¹h©ñ ÉÚ !à­ ‚æÃCPIî7½C.n€‚RÙ/A¼Í§]øL 3oÅåm›Á+"øñV|#¨ôôãü*#Ä(›Æ’zA r{ìP Táz5†L¿²M8 m2=hÊ)®QÖ]J  h¨²à¬#ù]£<”¬¿4žÈqº  SB"8¨›§>†o^¨žso¿û{õá;Ö&_?4ýW>ªXjDP0wPܲT¯‘¬£B¯+pÅŠ<Å-kãæ7¨˜ë@Rû+M»Ég³®ZoumÍüInl€¿±ÓÃæK«µ®ûƒsó`û! *öÔ[w 'FFå%È ˜˜¶¯}û"…ݽw‹¹Y¸ÿX_úÊÅÏmA$¢“PyðoÝ9ꕃÒ€l&#½eZ¥´U?”Cï#=…2ÁŒýŸÿ*gÞÞÁ=#„ »©¼þq?€€@Œ°³¸BÜÄçq”ë{œÔb‡0âê[4ÌØX¦— ©=ñýã¤1å¨`éØÁµï@J¢o`—>‰¢m¿€ÑÀ{àjÈ@àÚcñû„!”@š%¬¡4j„Á­Àñ„œì+­è¸~挢˜.8JôG| |¢ï)€ðë‘‹º•]¶W¯ýÕqL®ˆSÂ¥íAØ à‚†`¸ù¹©#JÃÑ•víî‚=xãM[|ë \÷Ka®>wá¬=öÔãvâ…'}°qnD.·RYRpiPûÃÇØúÔá…-”@ÚÆÆÆ Óîz‹i½Æ|=rý#Ó1„x AÓ<¿®‹õ3#!»{uæ!e{ð`QÚ ¦ÄW @Ü„¤&†ùÈ)ÿ¥g&ìǙƕÏA NðZòZ0Õ–ëÀÖºèBÔš4_.Ï•êŠÅ—à\çØÖrÙQMX¡('BÒj&I:Âër‡nA‰i< ŽW)ÁD-ªÃ¯/CxA¯Býâõ Hl‚9¨ L ” ž‚\…A§ ä¡ð:á•èÃxÓs¸ÿsŒ!#Ü:È›§>Âo?_X·[ ¯ÛòÎVUTXPjRÎ=Ú\E`À¥è¶àÆß¾~Ö߾i o_±•G68õÜSçíÙKgìì™CLÁâS§^ªq|ñ" ÝR<³MÉ­Ÿ<öK¿ù5»÷®mÜÝ‚¿;rŽt‚<êHCšµNÃ&Lм¼±™ moqûk´+ÁB¤7@ä`¯„ _E9AÞlEl Åðù¯¶ÿõ_ìáuFt¤§”§€ð!Ùˆ  K úÕ¢ EÐY£BŸÁõ‡‡„ ±£Ç™L4†ÁMßÎVmy%oñjƧðލX_î„„V`%2ï ¹úªxlÁvìRâëºûÈÉçu?Ÿ7Àðñ3J*0&¤ây½_Ù~]{$5b§{ÖÒÃü8 ›§>Š/ËÙjWèÏÅ^}×Ò Ä—–»ŸRåM,I”×—Vlõ>í¹¯Òçአã*Ÿ»|ÉÎ\8iÇ›µ‰ÃiR_ô¾kÆ-î=7´RfÊo—‹ڄݳµõ²ýöýgXþCv2âìX@\gˆ7eZõn/ —DÂ*Ëå°ÝaÒ]…ÚŒÓÚZꂈ“yhÓ“¡‹°gtƒ5*ì #Õp†“çñ8ŽŒØòƒ"fÁŽRÿOcù iáAZAUhΊ\à#VþBq«f%JuÓÔ93m“‡ sŠ?D9q$OËñlÁ8œþtÂëêòÓáü䫇¨bù0Ú§ƒrfØ‹(ƒ$!…ÈÌA”¬†… ø ñ¼Òb:%…¢Šø?egÏ? Vpðf~ðv÷ÀWäWý››³J©ëí;oÙŸüÙŸÚ×Þµù'OÓK¦–Ep¼@üMÌ_¦ü¬ËDÛ$Ópž{ö »xù< 2Ž[|‚.úÔÏçzÐh{EnÔ.Ýt~$JFQ9;ÕÁá,Ü¡(}Ûí¢>‚žp|µN|½ê&âîl•mõ6ʃÿ‚þ8}óP¸Ü!`ü~•ÆœÌØîÓ€£ y¦ý¶Gh"Æ`w:H‹q?•~* ´õît† >ûÅÃðû•j$¼ D˜>Â0Ц0Pî]U{AŽ¡N=õbËÊzÖWJô7¨Øôü¨{|OCõù„2xA‘LÏæŽÃÊÃØY¥%y•÷®$!ûåËË“@â;ü”%ר/¹@xœ™M°}®Ëǹ¢päò;¥Az7±jhtÆ.<ó’Í9…‚8¸èÿû·¹§Þ_‰=ø)d]}óî,ܰÿô§ví:y–K½yÇ!âÊcûpïU¤¢žu3wžxþ);éœÍŸžTã$‚ @.Ú{uŠÜðt½ rï’õsùnñõ!Òÿ·iÍ}~ü¢Mœ£ïÝ;Öð'-~(`—GŽ1u'EÛ/³Ü*Í?HsÝzõše·é‹7DáœAÆ{‘fÜYª`ÉiÂq!e1Ñm[ ÿéõEÅ”û„ü~ˆ‚ ÷Õøèccvþ™Q{ýU[¿SetXÌXè‚̵Qï‡iFpQ*mòüE&-÷¯ã$)Õ™g¾`佂Ì$ʯºÖ£'™+@O‚bj/•~ª£ þ!ÜyT–óØ54DÆ$Œà‹Ô$fa\Ã8¡ ªÐŽÕåHë$TRŠÄˆÄÆìèÙgìÉÏ|Í‘­öà+ß÷‡ðÀ~…uzܽ»ð3{óêU«Â½¿ø¹—8¹M—6] ÒbR9 yÆÏØ¿ýu{ìù €hs`˜¦¦ß’þ ïÓ“_‚®z÷Á@àØhZ†ìAn“Ú;wP u›|˜›Ÿ.;¥ óa©åº§ÓÃû RkÇh"òàê]{pmÅšS(@ŸÏ©Ñk¯B½Àä<€Þñ$|{< ɨ€4d­‹ iJ°ræm¬¯ meZKt ž?•´G·’¶²D?~Uu(W^݃}Xý~•lÖ¹yùaž Fo?|nÌb£¤ózXyÎ}@ú°K¯?L;ö[U{>››2v<`%Ú•ò þ¸ùj\¢,ƒ…1M †ÞŽñ9(‚6¾¾C œA}„ D`>ª°„_ôçÙ#GìÉg¿„õ?3 2”·y `îv§i+ù{õÝ¿¶ 7âá O‡?fOS4#Ð.&² Hz7ô×_³¥5‹Ð·¯ƒËÜFÈñ¹]¾ZizUÀ‰¥'ðªM¬®á–A?y±Äöì‚àmÙ2¹ý8ùø®rq{ ¬–^ åLã¢ëuóT†ml_í»¾hëº5¹ÖT2N1‚—ÑdèGl!,ƾ8DD7H¤ÆÈ°ÜVÅ6hJÒÀs Òm½ˆ2ÃZ£lºráì G)Éd‹¢ùóÞ‘¡,8ƒù®ó™¼ñù¥ ¡PYB‹µÂÀ{Àc·è³V”A8%(€Ò~-ÒÉô´=þäìÜÅ8ï¶ßý6óþ¯ÞÏè ¨eöòöüþ׬ %12jmÜù|¤@Ëëa„* å¦NÑ “Þ7ƒVZÌãÞæl2pˆ ÀŽ? Eú=àáÃÒÊrua´©¡G—{*î !H ƒ{·W¸úvhŽÞ€XQ ¾ˆòxË0Ê„œÜd_¿nÙì¦e×¶ì$Ö÷4­Â[e„$Y²ko=‚ŒC…š&‚bRé¯wá2ÇvD;y.²Ììƒl¹tË¥íŽBóUÇ¡w¶ïJB>}ø•þ@™£‹Q¹LšrÏÍ>KôÈÓ`¸@šw_t]Zô¸"¥Â-ËîG©¤Y`¥FŸ~®ABœü =8Â#UYu~ò²B{žE1‚‰…ŽÃ‹á9°­ŸÏ—´ó—_²Ï~áÔMLó5£I½Í­€§ ÅA¿™_±+¤ûÑW?B-h,cí(k˜N¾¸¡²PºäÆHÍÕ‰£k´ë®2w¯Ò…ÓN/r J×=|XYV¸¯Ã>±©¸ÖmKQ¬³|k›¿k¸¼]‡>ŒÂË«ÑX¨?[  –>Lj0µ Qô¤ÁGpŠ·òu¤êˆÝz;gy ЦJšq"¼h}^ŸnÀ*  »Ô^ÂŽòúÊ)ŠÂ ®Ê†2@©ÃªP©t&JKµ *R‰/Ëàö‘‚C°èùôs_°/ý÷íØiZ{®¿óo6OüÍRüÃ~)ÑkÿÕw~h76ïY‹ÚòLr„š~MÒ!*Д]âb*ÜT¿&_º‡`(ÇÞ!ίt¡ÖRy br}Äå4¸³|>s09¹z Á‡¬>*Rš[%oÇÕGX•É Hë"T}|ðX@¸Ÿq-Á××!ÝP!—ÄïS0„¥®¶26<1AÁœH#vˆÃ{ÔÿŠ]×%=(™“5U>MU‚š«`ãb›P©¸6çf§I:ùT‹5J†'.ÏIf|“XI?Aä„mg;NÚÏ`Ìǰ<–Ü Ž¯ã PÖ 'O@á L£¾Ð™î˜þ.J¡ƒ‡ µuÍJðDof \öÁÏó:yÕ 49Ö‘cçíÅßøm;ýÄ3t.>¸E?¿èîöÀ/Z™ñ|³]³ oÛ÷~òšž@ gtjù±ŒÁ8‡ÅŠ 0Qnæ Ä•ËJ°Ds`âTM,sCÃ/0þâÛ B,ý€Ù˜qîd,$Nx_R þ+æÔÏŸöZTë…p‹eø»4Ôˆ0ŽŽÔû0¹ ù÷ÕÛÄÄôHr¤5ýôê«Öê¤ÄèÉ?;mw¯mÚê³Gy]ÇC¨<˜ÁéÂU÷)å¦s×?„+ð^ÍB‹ø]Œ=u®ÑÁ·…ï>>c< I°Üu…ú©_)`×ͧÀu‚Àçç5yÂMäH!¸ GÖ\y¥ü>ÿòoÚŧ¿@Å¥R,ÞöÁðÀWäCþ­æ™K;wíöÖ[Vì–m<2ËÍN+l€.u« ê –-%‘†uW“ nXþ£ŽF`ëlèßÂp”U„Dà®@('‹+—¾‹«Üãæo4••‚•7Dµ^WSŠ…Òc?Ad8Ä„’›ªp¹7V ”ÉÒI… A “³o·–ì›?5a;ë#vïêŽ]|f˜ãbj“¢éóåòûñbTE'ëã^wx´P:%x Û ÍnÈp.£“aø”É€3°/ Ç áŒÒ4‘ â½>ıú»ÆR*‚?䲫i —óžÛ¯—ä  êd*ÊrÀ êÑ{yÈYQ¨ ¬¢ 609sÔ>÷¥oÙ _þ->wöC~«o7Oü¿óõ“{¶ß±ÎpÛåáýô¶ëiB­»Ôú*Jž_•*øÂiÐäÖ*Ì87yÛJ ÷‘„ Q P«¯V–VÜw ¿bdŲêpÛ¥Wz­DIn“ø{ m&§×’£ƒ#Ø.M†bé+làX¥þ&†"ZªÛ4Ó{]ñÞAê1™Ý>D#†sŒM3ÞkÖ^ýÞ¶­Ü­‘ZSó Qu/Jweé94îµ*•NÄ+iâäw¶ëtým[Ž”bi3ó.¢ùï—€vPbvIiªiÊžüuþo–åצi¿>}è„}éëß±¿üŸÐ[à4+ãm?o<ðóVå—¢~ùÜè=µ½æù6fO‚ڢ̵»Ò¡æžÎ·XäN §˜›Z#¬ýºûù9 þV_ ðGÁŠ èŠÇ“IpÈÍ÷4îq¹ÄrÏ‘8'¬5ºÀ(ä&‡É>´ 0íHóµdÑãTÜõ œQ ±O9n‚Qd´íšŽÚ!P²ÆäØ}¸ö:/‘p: õ-y Ôû‹²üÌìC1Eô×g<9]ˆ ¬6¾N@­M áŽà†{LŒ…ìËS-R D¨DbÐyÄt|®[œ ½S@í :Ë@?½@)P ýZdTàùsKñháÿßüŽ}é•ß%½9ç^ÿ%_ç~ÙSϯ_–õþâ{´rÃl³›ºâ&†R‰†"J~ÕDW”UŹÚf)Fî’kSÚªF]F¯=6‰K<2ÊÔ1ݸەr“¸)öm·ºÀa úp²M 0ȧH.¿L¤ǧ!!õ+§Ò7bµÊRxÑçÚµ… ­|»àÜÙgfí°ª;|Œ¡Ÿ7D×­ã¥ôl`ÏÒ¸ã\“  ,C’Æw u+ä ìé¹^DÚÖ–|.í×F(û„;ÊÏk™º‰ùØFQõèê“ÀJ…hö)rX~¼óß9m„^¡ <$W0è( "Ö®Ö*–ÑÂů 8Ñ—à·ÐÚŸ?a¯üæwí¹—ÿ1é¾YOø?Ľí)€±H»Ë€Q]+výέÎ`Íéé˶‘ݱ ^tÄr ð-Úp· µðäÖGi”ø;”=^WÁ ”Yêß7ï•ízá­¸ÒäóS°ßbÄÆaíÉ4] /P Û.aÄ£›V¤sΡÙ‚ƒ² ŒP; ¼~YZÜ\}„ž½Zg…u ^­’oÕx¦÷ U‹”âb®ÖàgÏO¢²¶µ"üA§ QCC˜ÎEÓ‘¦í‚ÔÈP ©“ññ”=èÉ„ÝòNæ¢N[ð8é@¢Èz :mP3D·à‰ÑÛ¿ZemÐ3ÊÛK'IÜÕ©X1}Ož§®¸^€:‹TçOÍ <ƒ¤fæBO»l¯|ã»vñ³¯ÐØ”\¿boû¥+à)€_ºD»ƒ,Þ»7¾o›;·iÐqÁÒ¡Q»ºt— ºÛvüȬ«`×Õ— +w¾Ž Å(¥ë“×o‘ûO•Æ[³“§çìù/œ·w_¿e÷o,ÚÂA؆2eCX|úù‡©" “‡(éU…›+HŒ:¾µ.Ö]Unˆ¡A’õö“§!ùðt‰šôûáP_ßahg³¡š9L,û*¥èƒI£Fž²°gÏÙ0@îÒº«Ôƒ7BÐ J(ÖPà¡tå‰Ç26= Õä” ±€šH©hu|Jo¥Îsrÿ/]|Ò¾ñ­b—žý š—Ð^Í~ÖàÃožøkÕò®l]±üúÎÈQÛŠ¤1nU¿xÄ.VŸ±ëÿþMû÷ÙŸÚ‰ÇÏØø}N㸆(€¡¯]¯Ì4_#á³Å;>€Bø;;›–uxØg§hœ9I# ñê[ÄÊ5&ØVh¡U#Ö^^naÁ¡ïâö‹«N8áå#VÐXıö$ ’¬¤PuÙ@µæN2àCÀÞêb LÈ0ˆ`ñÉT $Ô0 .(5ðÿ¿ò¦:ú$íÀ²¢îâÚÓ{Äf Øù— UæG`BV¤˜(‘§'Á2¼< t*xù2@KAŽ+ ‚ÏÃ1Q_Â.EÂdI&1Ö1¤^®¼Ó›ÜjUŽZsÍùëQÇÏHù‘U ^à™g>o¯|ë»öÄ¥/#ü²üÞö÷]O|¨S&v¾ Pç·Ñ™ÃVíf×mr(jþ „;h·_»coüåk–~7a£'6ùxÌ&(}õÁ‚S—ŒV.oÙå,9j¹æX?Z}—pñÖÃÄæB·Ç§i S¯ ºÞ ’NóëÖ×[öÖ›¼ÎÍÕo"P²Ü~^E1~,­H šsˆ:!‚žFÁÌLD\}ªo+ {×_dIšu"ÍôQêôð+æ”y€¾ àÆ•Ó)xþ ZŠ¢žJ›ŠD1zÏ ‡õóù!žƒê— =® †ÔÛ€kÿ#4A€%Õú L€÷ù #¸õct1²vRB<Å÷ÃIÆxÃYÃO¢FxÅ9—qZ˜•`,v{Q{öùí7¾ù{pü_ÄCò„ÿCÝÆ?g'OüœEùàS**Ù)>´‡ëë”Ïbls3®S¼‚ 'SvéK—mvvÌ~ü?²ÅÛx«¿±3—Øá™¥ý÷ë´ýªÒYw !—À©¶_~l·ÓëYmâ¸þ!xiˆÃÑ?ܳè¿MÜé¾Ê[±˜.î—µ—€!P‚ Õ8C-±¼®¸^ÂÃÒN€#ŒÓè³ZÁרa\k—:G‰ˆ|£ÿ$¨9·ˆ×QGg1׆¯eÆýäÖ¡3áZ¨F¿ '‡œpOŸÏû¹5ìTơӬÑä“ €<–ÀgÊ5ó6p ÞêÒ{Ž”äÈF”ñV( âXÙ(MOhJØÐ"©”©Ö$ÃUûõ|#öÌ _²oþÎ?µ§/^ò¡Þö^O|ˆ¥s}áú—zÃnHÅ6ÝsãÜÒ°K5ž:A¥G}û,í¯¿üí§ìî;1»÷ÎC[·×@ú·æ7íøñ#vûg·qo  × Gȶ#؆S›.Õ¯ËTvúz•¬yôÌhÔšôæ×D¥ÿ4K'@g× TBë<I3‚¦¼,t”ýŽÎ$ìÖí²K[vᨄ™t¬9ÉÚæ ¢ôììÙ„¿8mo¾Z`F@Ãõïê®!#>èÆ=®W¬Æ>^B…(š²èÂøý+h–&M@šx$?v’ p8%ýÍ祠§ÜµËÓ(—P*Ù%µy€0¡»Až ®I-ÐRê¦Ì*íQ{ús_¶ßýÃBz å ÄÀÛ~•ðÀ/Y½.¼ýµGvcõ%¸éFÃE¨µ·!Õ”×è¬CL[¥]ŽŠor« ä¹[vš#']jØòí¢-^ËÚ7Öܬ»¹sôîçæWjLÄž$Ÿ^Ý3ô<ç#º­È-z äѧ?`”²Þ–Q£¾±¬»Ž#òrò?®4ïF0õÐLuÒmÔPcêpT½@òÕaGì:BÛÀÒ–ñ ¤pŽŸÎØ¹ #vâ w0ôÇ?*ãup< õõ D98×6"»ñé@IDATžÁ%Ò‹èó@«PÑ G€†vñ1 ÝG>åˆˆÓ Q"°(ÊNŸ®Ò_…2¸ò,&2†õ—÷Qà ÑÅ);f± ÁЬ=ó™ß²ßùî?³‰É£¼Î{Û¯¼žø%KX®îØwÿÒÖðT$iG/LÙOOØJáºÝY€àcHܸÄì $›ß†~›£À…:ž?qzÄ.œ<îè»ö'o€£†X;BÌÜ—…“ÁÐØ*±øD‡ ðZ7¾‹§ ß\ýÿæpÁ7—áƒoËcÀí¢(ÄsP´Z™WË£2˜©œVñwt^‹˜ÿ(@î?*¸Bö{s’”ã±³idì0x…Ò|x¡ E£Ääjªá'½!^¯ã)H¨ú°‡éV ÚžP„*hj"¸š¼>Æy-Rn~3!A R.ã5qN º!BF[Ôäî‡YÇ](ÃégÊöµoþûÂË¿MŽÊþ_rÏþ}^öÀdµZ­šm–—¬g,]£ôˆñÔã&ÀyÁÜ!µ§Ù}¾f™ÖÛ´ëÒ0 P;bå‰üÒÄ]ïCõ¥‡þsß8nßûoÙÆƒ-RYäØÇ©ÏWHŒàª —âú4¼Wô]¼c‡xGpûGè’{ˆÖàèÁ†gÅbûÞKíÖ`¨êz8žg´èË׆~Ka¬¼Üê¥UJv F¡.Ÿ¾˜±³O1ÅŸ^üMJ—kLæM…Gaê|VPB„uæýUv`†ýMfò<ŠH¬FµìîÓUXY‰ ˜Ñ„8Z”ÀBõæSwe¶¶{–+ö°ödèe€D6ƒµ¢ˆ#áêÓT¯"F1Rœ ¾§?ûU{ù•?°Ó?K1“”·íå x à?²šPz¬bÓtÏ ­5¯)oàT“Ê 0›¯•WM|Kìgvš`èb‘1¿Xy\snèuÿEâÐÙ!{º0o7Þ\v%¸gΓ+ŸIûúa9ÌËdJø]·ÕÅÚüÝ¡ìvn2åjé+¥;Sza ÊUV?uR‹lU6™ ÑXŒ×ƒq‡ ã’÷ñÖ¨×OGìì¥q¡úKÑ_3*ò6ˆå‘k’ù}*öè â®ãö¸æÊ@±AíãQÄOqÞ owM=ú¬Ó0CO{(4ƒ¼5ìÐ:¨SïÙ…+'f#„7êÛï Açö‹ÎËU[ öâøXÔŽÌŸ·ç_úŽ=ùÔWmrvžõ%÷èm{¾žøKª™yu5ìÀò·úC°Ýv˜;¯æ4õ¤ò­_ÊQÎŽŠ@ke5ÙHï"ûðö€^~räH2(·]¸%„²KSg“ »œ±Û7·an!,] X˜„µ4¯²`‡âcáU3 ºJ AÄžÚ4£¹ïÑŽ{£PÃuFà({‡||…ã«SO­AÔ†›44b#Ôç/Þßf³#4=zq”‘bx R¼™¥û°úDà°À©n¼Šë;ŠûEÔç5GÆ=ø'ô_m+©­—Rš£CAj`ò‰G„"OŠÌFa˜jC)›¡ƒÂ…1BÍú Á\„ ÊÀÏûTàb…N=(ÉF ˜Ä#ÀúÈEÃ4À'«ÌØ{òþu(¯1;|(JKë!»~}îýåº5;DÚMž€Üsùñ»½õzåùp jx dA‡‡QJVŽZüºˆ ª Ôï¾>0kô"<{þ„Ãn\Ý"±qºÿ¢XtB5V!%T§’¯M^ØBŠma§î†q([ °¢eWñŠæ='ÌB¯«ÔwwóÑ•gx¾y©ª´# #Ëž"tÉ0ì#JŒ_¦¨{ CyN§€Áâ™{üâ vñÙoع'? PÚÁÛ>²ðÀ/XÚäõ…RÙ6p¥ñ¸«ÀCR­AgÝê{±è l4».‚`Ôü„Ê“XدР õ!Vîžø¸_Ã[àxø”Åì‰sÃvã&ýò—ФØZ]âxÄÓÜóª¾ÓC  ZrµQmµ…W W9D›!qó«°÷‚x!ˆEÓi¢ Wz’ƣ̘š²©É)»{}alÛÑ'2(R/F¸ °'ª.1~Whsf˜ú+íÑ2 3·˜Ìƒ (g®\¿X~m0QU€Qrí™!ræSqšnÒ…ÑlFï6g­9¾•lo”IV]¦A1ºÀÀD&\éC¿¬8 ¡Ç(.õ PWâf×ñœ‚ë¹8Lá— º™*•1)GôàšŠ}P@Çèìãþ«]·Üý:Íð‹*#@ õÜásöù¯þ#ûé½ñ©cø&¼??ŽðÀV¹Ò(ØÂÎ=»z÷ªm”ÌF¨€kV³ðÍ3¸º»ìä©·¯“ÇF0²ðù[ØÌ2äci•þøõH3ªS§ýÕ()•ÓÎSPˆÖ'Öoa™»¶æÙ·)(h¼Õ‘ÜrYeØnTÇi–]„Ø; …7AŽ<>´Ôµóäã5È#M™p‚^û:Në þ'yt?)Ãiº>!Ç­Å®­Ü  j.d@7I· ÇcpØÂò‹' ׿¯…[Þ"[EØùŠÂ»¯“žåÁ`Ä~»’Ü«ýwa¦XÏÑzh®;)K†…¦2x( b/ˆÏNQ‘¨¡zúû){á3/Øëíø…YK¡‚ÞöëXOüU—õ°vÏ^½òxy³¡ ëˆûNÌÜ­MdhɵåcÞ_ÅÊ´øŠ"y!\ý!æD™Ç53§Gž„¨j[0¿p}“ úaРS/ÏO¥Îøê.WaGB,÷X%³Éᨠ)Ž–àwÆ}‡3jÚg@x óT7µ S‹luæÕ”)•ØExŸÄƒ5sEú ¨ ð.<~Fëöi‘eü!—bTˆQÓ RÈ=R:¯6±»Üu) …*2ê#ð1"˜xCœÌˆ‹ýeõßßTÃ?g_MG›€|eŠšt¦˜ð“¢\XÝ€†gÙ3Ï~®=h³'Qv„JÞök[Oü¥o2a7Hc‹Ç/]¶ôQ¿]´bÕí´Ó&ÅÆ¤ÍN“×Ò>™îp~|K½£ ·Œ÷ÃØ‡YWÈ"ØXN?¤ÒÝ–1ÄVÂ[Çj#Àlw :åf¦Ùw[õ¬…©mIP¾›>Jω¨ÅR¢ cñý`öˆFëãx]PübŽ®¿¸øe²êÍ'% ¾¾¬¸¨¶ýFòWiB¼’»ôàøm˜A˜©²_uøí‘]PMB’P&NˆápTAŽ@¾JLlE¹ö ¤‚t­ûþ;Þ¡í¹f>"(½!òüã I±¦ÑxÒfŽ^´ç_þ=Êw_¦e·Zv¡a¼í׺žxoù•÷/7³ÞУoì”U™ÒS¦zo{c±ÕŒÑ®lZîÁ:Ý,‰q{ º@xZXq ÛAüïm¶ý²Â(*äÃ Š€ãÔa—<·ŸìÓÀ“>téÂŒÀQºÀçœ0À8¼O–|7ÍçG0; õŽ¥!—_sw·©HI ‚ròÊŒë—b@#àá;:¯:b(Èhº‹#uÌN_fêå¯2ýåšïHÞ_÷ x à½o@7xŽ85MñÔ3×à0Ë.nÙUºë®¬X};M6†;Oü;ÞAXEÖ¡½ŸÅ™Tëƒ9×GA„AÈ5 H€Z m€ÛFÈyVœPq†xâ«.^¥1"Ü4I# )Wì¬vÉ´‘¼–»GìСîV㹚0ö*ð 4s¯ ¨8$®>aBk«þz)ÎcˆÂ¹êé”d¸J+¦‰ÉÕôCn~'„Üë~rˆ=¸œË.h¸fWše£ž’uW•è¬>Þ‡^q a7‡ÎØUz(ƒ)Uñ%锹{âÌ%{ì³ßµ3—¾FVb%ëámŸ˜ð_…¬ÿzyÙ65úXN»¹AêØà[„¸ÿŽå°Æ¸ÂÄ·íŠt’BpshMÞÑD Õã@Æ ¤ºÊe*ç–ÔᎠsâkµ¿2z†ñ§]W[bÿ)·.ôÞ‘$Àï RyW%ÍXõC9HzÎU`³k‰ULä³±H4J°Ӽ$™ìZ†} Û´óBY¨‡¿ðt•cÚ òÇ¡Šq7v€7ñ]³P$ÔƒsÛ½Gåâk“ÐËc—· Y ýûì«ç•èó‹›èÚ 1ë ágæäE{ê+ÿ¥=ñì·=< ow%?Yÿx :k±Z°+ËW¬ÍÀJ£â®_²õ¢•â9{ì¬>>cµì¢­Þ!HI­›Ú jße y>ëÎk|u˜Ü¶\jüR«,—6#¶n—wü(,ÁÂJÚÝ‘f "˜< ¥cÄçXi”DO¢µ¦Ã>7 èšìWPÝA˜ÞR>´†mG! ‚Þ…/ ×[„!ɯªïz¸€>Ë :l>Yoý¾kïå‘è)÷¤³üœºÛÐ+ÎÕ×AÕ”C,E}4MÁÞÃøEu0yim·ùãìùÿÈFÂ/FŸ·}WàÀ+€6­µn?²‡ù¬Åg†±|Ævg¡ÿÞµ*í­bÑq†Q„aضÕ{×]ÕZˆx>E,]/"äBÐK ÞÜüšÿÇŠkÔÉM €ú×òØTÜj€m”öÜ ‹\q*Q:tì!5§i·u¼ Ñ|GÀªƒuÜü8@ ·^ïWo=U¶ šbäqWÉMï¹Ò_Ýbâ€)°Ÿ^‹/ÀoXþ]¥£˜^ÏÈÅwã¾l ´£!óŠOƒ x»< ý×O‚/B€ÿV1 üا-R‘Ab ä¼`_üêmO\ü ©'üZíOêvà@‹ê¶ÕzÞ¸¨]Ü×laÕ6·ä¯b=ã”Ñî`õ‡i7MÇY÷âŽq³»¼6ùÿZ™Ô ¾>©1êhÈ X(ƒ±qúÝÑÿ^4äö·æ 9w‘tì‰æ›¤ÄWõðšu×FQhÔxˆ:3†Œ¼1ZrŽòéè ®:ƒ×Íq$ܲòh='w—J,t_Ö~OˆÅÌÃÙaÛ`½GJjw<„X¯»¿9¦öSe¢„]쯺" ö“Ç¡.BzB¤Çd’"j¦ÅõâËÿÔÎ=ñEOø?©RÿwÎë€+Ry¸äÉÑI m+­¦¶Ü-ŸÛ„³O"¶Þ¥ÐŠEÁâtÿId†-˨­^À¸<‚PÆ0á-jzÍš A¸#Äñ~² 4ìr.|:lÂO¿` hk@À ·X(fž³°*­sÊ€c"`-‚ð:ÇhâiH`ÕÃO^ºjë‰5°À¼WÂJ¾]¹O #?•šÓßAÐz °[ 6%°:ŽÛøáÞËñºÀøœú{û¾w[°¿ÀǑסßÅ ¸©–ä* RSÏ$Å<ºRãŽoýtúxƒóÿ9ûÄþz €’v}¦ô hiUX^¶G ù‚ÎÏÍÎZ%V³Gw—¬Ü£ÍW°èâÝá¡$ärùt×U í n8éx„@˜Á•GTñÞ8QÖ uyõ>©áïâÜËmobUõºÚ_ùð@ò!ú»8ïU\Ï᪯ü{‹×ê©g·ƒ³Õ‘pÅfË- žçw„UàŸ<äÕ…²òï[§8¶S"œo¦ BH>ºÅ)‹]‚3æ˜û¤}´nšÓ7ŠðkŽ@8–²c¿`/}åììcŸCø=·Ÿ…ÚÛVúyÕÛy¼ä:å¹];27FËîYêçgmeeâÌŠ×Éûç˜g—ØMáAÒ¯‹ÜCNqªE…Ôc­Ûpì]g^ öÖ^H¿˜2Ž­R^ ɶù½Xõù’3'³²Æü! ͵ÓB0e¨zÆÉ0¸>þRìã´ B-± L$äN½ð„úði“Ì õ‹vJAÍGô¼<)ªû@~¨ ·Î‰«p!†;í̦ÌAV_œÐE<TmÏž³/~åŸÙ)'üÞ¶oVà@+€.dŸN¿Jƒ³ÃÓÃÖŒXzxΨ+ŽËŒÚÖ£ë µÌZ ¨»šc"—­µç!,¢¾ªÚ®^D.±Ø Ä$‚ Æ†¦ ˆ$=Þ“eöáì+×_äMÝQ_y<í6!þÚ_J©£ðƒÏM8ÿ@{»dŸýüïÚ<€H ÀÛöÕ X ÖÚµAÕJAÊpÃôäg&žŸòÜ63ªº€‘äœÍ8o[ÙGXÈ*.¹úßQÜ3<ì²Z¦RˆŽ?®>Á‰“÷FÆ)ˆ‘¯àñC#ùS°kN:Oå²è cÄäo 3â©*½ÇW鯄Ue¶N€Q)`|R(–]ê°”ç¡sA1úï9ò „ðó¼;—Ý¿”þ* PÇaØ |T§¢QÒ‘S0ü’ð»Ì€Ž?²s—¾â ÿ¾û¿=Ù«Zý&r¶Ý/Ú<þ 0{´"O[œ¿Šå¦çø1›k§ÅY<ðII`-2mO=ñÛÌø }éHêmûz¤(6Šö¨¼jEuîµ ‹tèõ·¹N©nÅñ‚F·_„udæ˜?uÉRÑiÛy=xaâÂÛ£²ŽÆ„ÇhÌÑnRˆ™÷!mÙ$tú]Ä™Ø@ŒÅú¤·MÁ¹åìã¤NBŽ ë!T?=ambåi 4úÁ)"© ½GÖZ›¬·”ƒØyüàï]ÀNJ‚C¹ úÄ‹³ð¼]àR|®’ýw9(®÷ Ö L„š|öHmF8vB>Š«Ë@„ ŸûßL0˓޶ßWà@*€B³dk•œ5q‰Ï؉ã£VÙªÙûoÚæÒ6R×±#§æqq[rRÍ>vêÜ»õ×9:ä-‚¯$èLg²J± oŸR[¬6¥÷ÎÒŠ($ÙÅŽÀa¡IÕÔ;¢¦Xn¹¦øt2¹ñbê tÏw‘yÞÍó%ë äHصé5Y ³Yn~‹cêXR@j."%!d_‰œ =܉!ðìᔆþV(¢ÏWXÐo2Q>+N$W ²;÷ô‹ö•Wþ¹OÌóyÐÛöý 8ÐA0sôîË7è“LY¦ÌÐÈ”=öôç¨c/ZïaÓÆÀqúÜIXt4ÈÜZÁ:‡ln.nÓÓ–]¤<óŠd!÷ ¿ûBô amðê¿'9•7 ÁX'á "‘1\ý(áƒ,,ƒÂœåwyxdMé@YGP|?f×±$øR%.žÿÖãàò>a·és¤`Þgÿé %® œ*‘ðë¤x£S <+ïÃ}6ç)%à ‰écHXÄÉž<ñ˜}í7þȦ§q=žðï®ôþÿ÷À)€½²6r¶øhÉàÝ3PVG!Möíôs§mòxË\eV}ž¶^\~_ˆ|»U·ñÑš…é_Ül1P³æg¶‰= ud=0X*Æ"æ„N.¹Z0í'Áº.‰Ž@ð‘:\–í¢ Òn^ ÖW–^ `÷‡>‡÷p§”DÜÝËú× ¿Û9ÿ: RÊDÙ}ž2œŽû½KØ!¥£Ô¥;W)8Ž-\C±ÇÈøŒ]ºD3:úÔ°ÐÛ>5+pà@×Ç4À"-¾*å5\e\yšÝEàÄGc€w“„u[]XýÏ"°bñµ 5lÎî¡™0õú+åË ûjÃ…´H¹%šI hĶsÝÉéK’œ*Uæwõè $ç«OïCÆvR­c`ÓTžGñH 5ÈS¸Ÿzn·‚Ý󻟋l»œÿûn¿îPŽËðSÂ-…"Ë/,Aç§>‡»Y>„¿ÝgBȃH€]H¤¨xüÜ3vé©W<~¿õS¶8 ïuœ~ùGó–ÛVšŽÁžZhÓ­#Œß“ dì ™Ô†#Чݗz6ôãÃc`tõ© üªÀCvœý¢î§[fX–3ÛÆ¬+®V¾¬oËÞF²É¢kJ°S’TÄÛ¬gÙ—÷¸ß8Œ^bg ²S»‡v4â]/€cñ¹’vô;çMèÞ#Ká_Þ\}Õ/h8‡\~§Xøí£ÿERŠ¢d$ü~ŠœŽ~Ìž{ñ19øç 3ð¶OÓ 8€¸ógìLâ´­-Ó¹w;g¥íÖWž©>©‰)›™9LG-[[|dåσðK0ºŒ½mçóÁ½”ÕóQÕ§4ž\¥{(¼a|ì*iÂ:Í=deÛeâ5îËÉ'&WÕ‚N¸yÉ)öRÃPW¾Ë{dÙ®»üü¡Ð¡AE¡ÊƒõYêÎë ~xMûʃЦú}vpÙé3¤!Ä[pñ>ŠIÂ/pp÷M  þRnròÿÿöÞC»,Íó¼$$AoE9ʦ”¦³zw{fÎÌž™Ø'™} Ý‡Ù³g§OwMWVuz#KQôÞ=÷÷û‚˜J¥²2»šÅ"$’@ Ì‹ûÿ¼QB(“ãûÁ§ÿ)=øô¿bÀ¤ÒG¾½w3Ð`ÀPÛÝ´{´Å‚¦lU}ÿ(¬¹IV|óͽ”ë ©e']vøé ’M•¾¨ ‡ü¥òÎ!Ñ|ÍH¶ÍVoÁb¦eßÐb9¨IB']g&̘UgÖŸ1âØ¶œ8ØŒ; D­ðG\æ NÇýë1ž¥ ¥;8Ä^«§ÀÎ=æë‘?ã¥ID'êûq‰ ± ÜãBåΠ1ïçñ ‰ Å=|OŽÿØû43ý‘Œrd¾½3ÐP@cÙÖÎfÚ8XIûdÙÜrwc1íÌOa§…×…;w'Ðû›ÓæÎM8ZR÷I/E;É ónŽ@DþPi°“á×1°à‡¥¸ÍP»ŽÒ\¹ìu÷¢•|”žmÂ9§™ `Î@3û^%ó¸Â8D]]azV>˜ )_Ž à;Ah!ŒÎ}eîcÜ¿œŸS³Md{AÇÅqºC§ðXv{žR„×vLf4zˆY~6 ¹—†¯Ü9»Xþç}œÆ"¬þê~•‚ÔÜ#%ÝŸš©V´OÞjZÜÜ¡ °}DmX÷ýüöw! ÕÚz'dž=Ø9„ã€67‡k‡i†ÆÖõSü?A*´X³bûÁDrÿcv¨À£ªŽJƒÀµŠÛ‘û*xœdÎÙÕ,‚¹¶Ò@F2¢ Ú°fà%gg¿"„Ø‚Ÿó%eц-ÿ¨/à9!Mð8x'ÊéÚØG9`NÞç­¡€ ~‡dž•Åí´¼¶ [èD{+ ]ÿ$MO>K«³(Ý5‹w`úù$öÖŒzrîÍ=Ä~r|é“U’؆APk½[z­ᨌÀT/œXSƒUÂPhÒ½N+Ü$êÙª¯nŒ ñÝ}Æð7 åî¾–>41ž8—ƒãŽƒó<¯Íñ«½ÃMÉt|=Ò„ˆ÷—0oÒ€áÍìúØí4zã.QŒdåÛ{; F(·]ÝM ³«ifj =¿-ݸ{?õŒ~ŽÛÛÒÀõ.Ü}“iiâyšún<í,o¥V#ÞäÞ$ aàÖýuè¯m«¥Ø,7ÍÕA"c -þÈÂGoßšÿæð+{[ T}Þà ÌåŒÈ=%ÕNæ‡sx)‡/Àö¹$û«¿8?~»åÂ^ÀGîW¼×h(íñ^*þz9?cÕð(E qåÌhJÒÓžGGRgO/’ŒT!ßÞ×h(p‚ßÙª¦åÙ•´8½”vYèvþé¿_ÝX˜5býéºÛ?6»–S ïÀ>Æ?»èž óHQ¥À线üöH½¬Êuܘb|øàƒfÌÿÞGœ>³í_ýì²\~Q™7x²ð ,L€ ^3€s¼‡#dGTΊ?ÒYw\Ž{`.diÈžïu²kI3›À÷µ—×êï+= ޽—B¥«‚Š3zº?ÄïêѮͷ÷mŠEÞ­u"ý¶vSïÈ ÖùZšŸø WÝv=Û~aÜcßÈhGê*¥éñÅ´¶¼‹(oÜ>XÐrË&X-­30Âeå®'Xú‹°p}ïŠrs[|‹¶X='¸ð¨ uý-.Øíõ?¾÷@ tU Ï÷8Á-z æ‰ö{ý8„×™_ŸcÕ÷%JžâtYhlôPA‘ûû, 8vêîn§²oÕŒG)vÚÁœl¦Ýê&E?{¸G. 0MïÝÖP@°T:;o¯¤R×`º÷éC:û6§ñÇÏRmk#Þ!%¼÷ÈÅ?NWhnÑs­3mc+ØX݃p`8¦à±Ì—1ýÍXÙŽñ$ã[×=§U¤ŠQ@Ì swH‚šÿFñÉK%$6Þ ·žçð/¸¾ç ~R=XúKcA's4ÄK~ûÏ8¥¯ÅBB$á 2wÁ{ÑðÆå¦zà°,HZ&°©DçÐJgoêîÀ8ZI5ÀÖÖ v€J6ã¤ü×{5 Eüæ*t¯øðw‡KoˆÜýikc*Pr{sv ‘þ‚á¯DÜVë~¢÷[eÛè³.²‚¹õìW´ÇsHs‘Ü?Ú„±;¸=ಪŽ5ùįr<ùBtùå¯hä¿a¸âTb!¼ƒF°_ІØïaœÿ‚Óg¯ãöÆe¼' fÇáëõ¹¦ÒC†u/šž¸÷sL\#‚¨@R MwS¡Ò^t÷éJ•nÆs‚§d#í÷з°‚»$ßÞ»h8 >;xe$µ ßÄrÇ_C”çß!=÷iÿ-ª ìg _'ð>^GTä±Õ—?@uîj4]€W.K¥ ²üdùQLDTK) D lêS^ Ìó±UKƒ÷Wtà¿[@]ÐJlx_÷îÇÇ,±ðXÿJHTÌû¯Íã·@‰†GË–;jU00z} Õ†‹á²lE%iOåŽ F@j´ûÓÉg­Ä2ì¥áÒ¾Ï ‚LÜ{¶5hA-DPÏÊÉBÚ€»Õ6ÓP?iÁÔüŸ›æ}í0UQö·—IÙµØ-¯É´P‡ÿìû5ò(e#Xa@pÔFÐx,Þ#k´ ˆ~Ž‘`Äæn€¬¥^›+ è÷—;CÎŽå/;¬Ï— ¹ŸÀ÷ÏmèFzýî[@ɤ‚LÇ?àÂ! ppD¢lw¢ 6“ÝW@ßïêî¡2¢;]è’T©ôÒ ¥›c²æ¤‡‚±¹- ûÞ—ßE°àw¡Û6ñ,-¥å•ÅtPKCÅÃÔ×מVéÇ·EÐ.ÀÁ‡¿sJ¥ŸˆÞà /Ú%àc0zŒhr]8¾€m\Yö 賄Ÿ°ÂËÏ9Oð L›{Ƚ½¤†ÂØÏuܤþDN?ߎ÷ ‚ÀqˆÌ0ðX/“Õ†,?æ>7%ŒðDx_®'à ¾„®ßÖAÖ£ÝHšèDLñS|¶Bïéé‹Ôß®¾aº¦.líp~¥…ÃÃ=ˆ eÎp6Ù}òßÛ3ÐX  ‹.6&óì,.¦åy ] ©ØN!ct8~¹Ô~_JG4ú<†RìÏ@„ÑÊa›)þa„ê&Kÿ n¦ùM°Û/ÀVÙìÊ@ wV}p )D!EȽE°`ÕP ÐcSôcØ×Îv—g‡ÈZïÝM  ú&˜='·†Ã׳õÏËÉÕïãÜ ÜÓ<C Àé9¯±PÑ߈@ƒ2[Asˆû%¤œ""~±­œJ„8—)`Ú á+ÑÁ·­ÍŸ œ¿±¿ÀPa0õÑ!¹) ³+Á ¦Ajbù¯÷tŽÈq¯_Mc#WÓÒâx*ì¤ >ð2€ØÃuVÌ{ °¦¾®²]gÃ[®¢7¹¿E¸¨å¹ô¿+Ë+¥ƒÅð XTSÀ÷vâ-'fçÊ­µüküËðÅAŒ)Äy €»¹{!¢<{ÝÄ eÊ>à(¼6ÌXŽîs!f!Ö+¶ÃùåàE8¹:| c_ÐI„¿Ó€@ÿàHêí Ð.ÀÜÝÇä7ÈÖpÀﵫ÷½ëcieîQZ]=&±‡ÿrþ±²í5µòS£>@-í6íâÚ£ „@‚L‰Àñ€ã}3ºž7£ôbÄñ7ÃêC=àdÊBK87$Ú<FBéíëŒógj®63ûšQUZ·nÀ&­øˆ$• Z0ÊyO•tåµ¢Û—ÑëËò.Ž%Ž#Ÿú~B °ËXô{BäWìð4?ííëè¿vb,žƒ?ûåwC€V¸ãëwÒÊÊÇèÌÇ© c`uw‡¸w@ßfÏ¿E1ªÄì·¦ýòU~¢PPa]katÃä.¸U ¤&ö¸h”%û(ëÜàØ|À ÷äöðéà/» êò@ñ!s·é³ÇXG0N%N‘6$‡aþç3@œŸ{”‚ËÃí1Ö yÂàׯµŠìoM]ݽ;"ü:Iôéí„ã÷bì£ï÷RŠÈ·Æš†$~ÅÝp¿±±Oë6öd¥úro@±X ¶Ó è`Ÿ°à²é¿ü ê«ÀÐác)pm¢ÑœÉñ™>Á®ðª?Ÿ©«Ûó/#¤‡Ðçáî•üþz]’Ñ]HîD¬Äå)²ßðÝýÉäú-™I@Ë~¦ó·ÁÕ}&‰EÀv,ûH?Füuçß Q0ÎßçÌ·Æœ†ýæ ˆÇƒ£éí¿N øÙ-ï^„Ë .aL+§=Š‚Àýkµܓо& Aý©ÆÂ#Š„’A•uäÞ±†t ê–¨¸åŒ§×®_‚»j•·i¨Æ>%“vÜôÕ+9W720«ȕ˄èú9òDèðŠÿJröÒb~fô“Ó—°ôwv€ñ°ªOö×ÿöêiÇÐF,D¹Ldöå௠a5,€úÀGGï“ó¿Ö7×S;]~º:é ˆa°JáêöŸYDh7Óþ«è‰  Õ”¢…7D s"Á¸xœ©ØÏ‹"–up;·?Ûäýªru,÷T߸\$ìrôðÃÇç†âžñ^㞺¾Á>»€kô>J Zþ•$»û[ùÇ z‘ëûõï qÿ6,ð+/Âåûú¯(–fáðTûà{4ûìØ©¦Z¥Æ{Î,îÕê¸VüG_§2°|Y@ìS.ŒüЇX@C!D{¹=÷©­H ¾ö%€#¤QÚ8¶‚‡DPÊÅ­Ÿ±‹}v–hð¢|æžÓ‰­ˆø%mÒŽÄ}%Ž€’€®Aö ×EHœˆ|kØhh ô‰ ŒfªíÒí—I.—*AŽ´ºëê`ÌkXèÁ§:»œúˆò`–×:Œrá 9Fi|««òmãè¡÷=åºÚ 4Úy‹|¨ûK,|íùºúÜ<¾â  åêžn@.ª§@n®„"Žà%&þ¨ê(yø£·@é#ßò¨Ï@C'AU*ýÁQ‹pÓ}¸ÿ@ÞkÇ€Èh¾?–yL&†@Eö‚¾wˆ‚‘yºæ®¯ G“÷ˆúìx/À'µ¶+òëâ 6/ù €ò«þ1Ç{mïô§™×¯€çn …DÈÏ<6 ~!1t?ãúî ?÷u,µ1oÛt`Þ­®ÇwTp;vö]è.êYÿ–ïÓðÀ/OÎÛÑÑ@:€â6»! ȱ—P ø‡Jp¢ø¸Ì¨sŸ^ B”Þ6ŠpŒêà&ØCœ×rw÷L~2c`ô Õ| x@~œË 4fª²¨Ûs…Hìw3pF\ºRÊ+I‚1\äV«Qz}}šJË_¥õ)ÆÖšºûn¦«WbLH<ª4ùöןœÄw€•ÑZàè¨PVœ×ÂØväwZçÊòS™ªÜºžäg‰„’‚q5åÙîIìŒx~P=G‚#¨Y.®'@‘ùÿ4 —Ë t®ç5|ûƒÑ{|FÎîúïþç ©J Á—ÿš–—¾¥aÊrê§ÎÂÞA5MŽSiùå >ºîÞý‡48x=\“>[¾ýõf Ÿýss¯¾,Ç>bQž ¿ ÄŒÃ{P ŠßB”4À& ŸF¥^uŸŸ»3ÀÎYÙ%HÎožë–ùì/ÀÍNΈ‹â~ãÞs Ž»Æõ!þ8ì¯òë€zëk3pý?¤åÅoSW{‘(ÞP?Z‘\*7ÛÒÆÒ9Ã?{JÆXzøáK׮݋cêóðW|ß4'ç¾üà¤aTË8ú)Ù}nrÞ3œ½ú{î´Øwþ}ö:öëýÙµ|靖<û0ÞûúÕ)¯^Ä¿Ž3"rv¹ ÿ³O·¥ÉÉoÓ“'ÿˆ)u% öQN¬©„$¤‡„nJ? ”J÷o!z½´ò,=Jk¶Ý½týú}Št^ø¸ó¢žo?šÁ¦¾-»®C¶À:Îêtâ/¾y êxõúíkÜÿâ5.߇G5Dþ¯Ò“Gÿ„±t9 _í§¢0Ò“ªâ¨dT:g&5vi½¶¸¼œÆ_ ÉPâV ‡¶Ñ°Žßý§ï´ðû|--ƒTVZKós;¸ø¶RoÏ Ý…;8¡ à串E½mÔ^  Ü^àß¹s'¥¡¡¡_þ×s€{‘gñ}•\ƒCR³ON÷É=XD"™çÞ„fSßÑ ÌFCj–àP^xF*!wß qʺ ½Œ¿±C’sðÓµý“=.4\mw ]×9D mù6ð7Y\;iks•œ’p@eØÁhÔÚÖJ8\ëPêï# v8\coÞÀÅ)÷z͉="-E¶áÎö eÇL5®²ÐØ[€%ñ ²ï1&‹^oŽÙ9âÎÎ2PŸ”³Æë98öºº±:7ñúÑJq¥sÝü65>ˆÄ£×Wûé+‰N___zøð#ÆPIóósÔW\ðÛt]²hÊ Ä†…¸oÞNc7ÆpÞ%úïã •J%¼?½ò÷dÏáµvûFÌ“±ÛÛ³Djn¥@HÝFS­Ó)%ÝHãn!Åúñù=Õó0¬—˜(øº¼YK3SŸCºÓÍ[ÿ/Äõ£„¢·œ¼ã[7õwkk>­­¾¤&àfÚ¡ù9ø–súGw˜L¥©™lÂÒ Äb1M<_J3ÓÏÓÝûÿ øxŽv¶XÔ㩇}ÕÝUîp@ºoìã"C}°pi{ D%x[t8Z[ÛLß=šLß}?°z³áræ&NVã>•ŠÈ,,Ðæ¬¿R"HÇœÛ|ûÃH!.Ö'”ûɱKµ¦íí4;ù€o>ݹû_ÒØÍŒ“ ElÇH?ÛÛã˜Uˆ•’8¿µt˜F†w(¬zš®])2g†ð^$#ÒA¡ˆŠ´{!]J/ÆÇã^ŠÿƼ¹9Þõõ™´¶þ‚f­!bK4oAÝø@?Õ”jð<ð<Ñݘæ¥]I†§@ êŸ]4¤öR·1Ó¸¢U¤,ÛÔÜlúêë¸-÷xÆÃè‰ØÓÓù?–¢ÞÛûø>'o|«;p'i~ö‹T«ÎÃÅ€ ¢¤á­ÍÍ•ï#ÛÅßÌ¢klV ŽŒAôN7_Û¢Ë =-â•vºíR~¬TXOÏ›ÝÚÙ…+×ÒýûŸ”jÞBtþ'9jC‹-¼ 6±- Š(©È´0ÇÕæ½žuNN«ikûiÚ«M§+¨{d2Úþ[=^.hï‚68b;ÒB‰NA‚à‚ó*DàÇåÎæÀjAƒ,¡â‹é/‘:¬ttŠÈþAHµ½jÿ"ìNÐ_{ƒ´’O]i=Må~JªQa¸H·a»k'h†Øln¯¥…ùÙô|â»4zí4Š‘ œÝ5ûãsmm#Ì|‡ºòу¨Vµ„p—§B@`ó©»„º'g(à’=“¯åàŠü–Q·j“À­™B,-4BÝÝÝMÓ ³éŸÿð8=}.1?Fí¹Æ¼ì¿:6Nh _98÷e þ…DàÙ?¥½êlê¤b®Ýqõm›éwˆJpBK ,ÍÖ ?òRŠ‚œ•ðöîQæc; ›Ñ7DÛ­}ÒŒÇ_>O~háÚÝixxPö¦É©c X3éÆèhº~u8@Èâ¶ß÷1÷<‚ØHXܰ_#êq»Þ gìN7®ts?Ãm ¼¡x)Ç·£ªtvJh+F5c˽ „E?}ÐÀç¸Ox>4Ð;„º³Ÿ^Î>Mß}‡Ú€pllŒcš å%Žf9]ÅØ‡/2óªöA˜þnÄr.ÒÍÏ»µµ›ææ×ÓÔÌ1åÈoÇ3œÿ¥*µ¶6E ñ£´´ðm¨N]½•T)tNŠ¬Øšý„zŒœÔMzq@ï¡x}õÕ Á€÷9ÐmÀ¯M¶Zˆ‡ÌÉÄÔlúÓ×OÒã§Û¨He‘ÁJí È ÀÙJ´;ðâÒizê•–S5ô‹pT‹‚Y$ŠâBOã—õ¶16íP8TÎ%wi+S‘—…¦ŽêOXŸù,*«l#ڌёAΫ¦Ù|ã/~@¼¶eW–ùÞôâå$zéûNq§ çÒZï=ì˜ ¶á:G,ÚÜþŽØ qØ£IuÃe툻âòAÀ}B †2d ^k%Ïj¨k ,àÇØÕÈ.DW¯ “°3ŽÊòù:„¤ Û…eÅÇÒç ¿Oë[Óß=¼›û‡Ò -˼N¶ Š[ˆßÜT]ü¸‹½‚0&üº&¡s93ý}ššúŒê‹©BWûH¸½] ²d%Û››-¥æ•Óäô=³˜>ÿz<ýððØöˆÁÁA¥Û²‹{ƒ†ÚrÀ×íbY_'©åå¿þ%ºc¤"¨ÅÅ©.¯M/ÄjÓa|b‚——if¶ÊbÓ'^HÃí4!ºíêÍ44ØÞn Ì~f#–÷“Ë–šÊitx®8ƒáì[8ÚoG¾•–q§=~ö>Nÿñ9MWhÖ©Ëf +ë$XÝ• ¸&Öütb¯ÝZ¶,­ÍM®¸ƒ>ÿbz o`_€‹ß¤ Í@ ¨཮Àäâ\ñ Ï\±w`w)Í-/’ê;Xn~ÁÛQNϞϠ!%h9¬sè½Cüö‚Ì›¸R:@•h‚PV° œÿ]¤=ÛÄÄ¿¤ã½9æ¥?¤› ZöàØ‚²½ÝÊÆÅ¨Õ¸¸²”ž¿˜Iß?^J Ë”aC÷èmMׯu¥›7ÓÍëô7ìíæù(† ‘QeÒ;°º¾”¾þ~<=zŠ!w«¥Óïܹq$õöê «¡ÀïÃæ€…º·G‹ð‰Ï°4/§^hƒÞ;âÚYÇaÕg²¶««,¾—鋯§áXô¨’ö†§&¸÷vŸ\OŸ<ÜIÿéû4õ±¨¹åÖJêòðqŠbìc0CôØHžÏ§Ù™q|ãGdÜ}ÄÔ#rê[Òó\û~'šIDATñ×øÁ…ÖU霯3ëä¬!Zcز¶ˆªFUJa±YÈ.æ5²î¾{4‘þõ«9$›}€ÚœîÞžMŸ<¸žÜÇ͇”bÕ¢ÐÓ]û\ÌV„R¥ÛÕMO‚¦µ´¸8C/ ?¨'rË«Wo¥ÕµB{Ó•áµt{ì*ÏÉ ± |Á.þUV <÷1}T˜›= ”¤ŒX\üÀ®Ð§°‚DaUì-ØZ[•¢P“:Úö°L§/¿}‘ž<Û†xºliƒÆu–N©-°àœÂÝØ•îݾ–n\»Ò•nÛ“ éñsܶ–~ëĦq7}øá‡Aîß¿„Ã7èÖð@—Ò,®¯õå穟oí|9Ç1?rZ¦¸,˜?{™~ÿ#ÛÐm¬·ÎÛM§Î9À`µ±A¶Û÷ ÃTÒßò€î;x+ €FØèõî³Ba Ýx?ùý‹u z¯—/Ëpí)>[M=HtV˜áô’µ/— áŒJ…èf¬üà¦æ'Ó7? î>ÚHó ÀïÅQ!}÷C KüSˆQSºwç6Ϫç=ÀK¨Ü2ï…òÃeki9-®¬#!­‡˜oäÞýûxÞƒôìÙ?aQ_" ‹?%Õly. ±ˆ²„ÄêÈz.ŽUA,}î§JØ4®&^~žV–¾KE›­"âó™PU„m'¸]Ô—ç/§ÒgŸ?OÏÆß!ºv;î§§áðÈßO3öƒ•øA‚Ò4RÂÄzúøÁRzxÿ6RX5}ÿh#ëÒDºukìU¢à×٨ܟéÎ%#ã6Ö¥ž s¡~œñŒk—0Þ¹0ŸM¾ ¡e†¦dÐNM»üß×ø¹¤Š^¿°°§'ß}z%ݾ‰+ã!I –‡ž wÔ˜×^Ƹ†Å}Žs±áÌ„Ævu©gw¢bì§¥Õjº²ÆÿÒÁ ÈR%F%8¤­ÆBE ÄùÖ’æ—çÒŸ¾xºîêªÄ«#\b¼C6¢å¶¦Ó“ñňÂây½¦×Pl÷A£!××èXF¥è(Ë•7áÖöD8ñÃo—¤õõ9Œ‚OÓææF꽞’‹_¹3"ÀE‘–ÜT;VW§ÓâìwÔ8„xt2†“Pa²Ïµw@~™«—33é_¿OOŸmá¶+C\"è!ÅæÞ•••˜ÃÕUb6Vx¿ž~ÿÙ„z—1!QírÙ ÇþÁýHìïGUÓ§ÚÀ[C?ý>!¤kkÏñ5ϧ>ô~Ö à´F&²ËY‰iqu1ýñKJXc%o&ž}øöí[¯’Yôiëbša±>~<ˆËëó4¿¸ƒx¼Ÿ‰þ,Rùæ=P®N}F¿ |çêì ž¥Çn°·û=ÛÄ{0’Š Gh_˜Öz “Pã—7Ñù¿þn<}ûý6ÏÕ̵ú‚Hݺu+ŒÇ¾xñ„±þF9AðûºY5‚ŸßçnÅÿN|c¥L:©¾>£Sylì& þ(={2ƒh½ Á»RŽ„ã1…­‚´`Õñ‰L VÒE1ƒû/.~ÁÚÀÇßáàó&$îé3%âyVBwŸHOžnpD퀞Á>úøãƒ‹+¨JlóÜkkkA$ÂÓÓÔ–‰©U\‹5ˆZÒÈÈpD |ó×i^CÃHæ¾N¬QŸÜCŒ0º÷õc}ÄSóéùs:Á®ÁEþø#ÄÉ[D’õ…¨/áè$*.\T{³l=|ýÑhˆ¸ÍˆëJü÷‘Þ™ÚÅlÝ<¥ÕµO¨™·1#¸Ì¼„¦ •XÙÅH`Fžž½x øWàÌ8»û"éF]WC—ÜRwv¶!º¯2Ú‹Ÿq}ïuÝBüFæCë¾)½[[Ûpú­¸†\SëùíÛ÷Èû„)£æÈµ5@ªŽè{÷y¼^<ΩtÚ¸¢G*ñÒ“ÔY¦s ˜ X2v_å3• §„RObÀaîB‘zÃAt?ùäæþãäÜK,3uâ(RØ*EG$Ä“““»‰ ®>·ˆJ.ccc9ø³¯:~7,P÷ÝÜ\H[DѰLUp¡°bXÛÖ7HžÁº=z¥‚þ+°p= °@ÐÊ uqZ¡eë¹ÁC…XÌŠÊå6ô[bÁrYn“!Nq¾þºþ½tw§~ãVZ\fñO„QNÃ\æ”@ , B0A¶³µ…„Âx–ñÿ“€$@>|˜>úè£à|º20×È[øéÿÎKÄ@ šÓ ñòFÐ"¤ÀÜÚ&@g‹¿\Ÿª¾õ±j€»råj”÷>"äX7¥&?àx$(pwûÚPçööVˆ.~¨^Íp âs‘~ ŸÊNÍk[+€u"çôÜ›¯ wÖPUªo$$žÎ9 þc¡t ðxÏSZkt±¿>oþmX°·GÛ˜¦¥bºÜ0ëÏÇZe“è¾R"À%F©«‡zY<ƒpš2 k‡Eû8-ÍãVÚ$ô–`Õ[é‰C}„¶"Ê£Bìà £+0¯e¸H?}]ô>c¼q×ú/­qÑf%;„ÅÂÃB®;­~Õ“à°Ø(©gç—ÓôœYqÄÞ_͸6…;wî„®`äœn m™4á8ä¼À&Àÿ$*Jmïµ>AstSàÙß.B—­°¾ŒÑNc"ËI¢ÙŠ R©'$ ÞG®éøWžJC¸ïÌÎÓ¶QW=´aÔ»'Ï.,ãfµ7cïÃPH3J2rpAþs›^ AnnD]êñX%÷™„”o¯g a @­Jf 6á/†Kkp ÕWv*#å–Æ«?¸'}pW¸•=èµiãU É5miÀűP†nBo•ÛCð 4 CÄ ì“­†¥+f=LX.ˆýüˆ¶c’Ž77k'ÁHµ:ÿÂíåŠÍ¨):Õ¸QØ” t™íÁ©_N.§­õ¦0’ ûöíwÃøÈ ÓDÏðe+ñâ›Ïˆœlh£·h%ž`‘zcc›cÍ:ìø çtLêõ;Æä0 B4[±ä‡[ÐGãGweü…‘Éwz²›ÚÉÆ+)™÷U@{ˆxcçÌìÒGây†BšñY´‘h¨?'¿uósþ6°ÿÒ¹o½à{¼³a À1_‘ºñ2+g…˜ÊâW”U‡•h3Þ]=¾‰êûcö Þ±°"qóŠÖn™¾ëZwÕ{=«PýVN«;“Yø{ÄÕoïlo J~ºé¢ëD_Þ‚›f‚9—ÛÈU‚"º¡Çžˆ,\܈ =·FFÃPvëÖ­Ÿ€EWåââ÷¸÷Šág?EÖ»„„…aùüÁ¥%3Üdeu|Ÿà¢L¤–(ùy}Ó¨ÙnCRA¸¹Nt/vŒ€Ýçv“>Bÿ!v‘%¿ øÉ%`šQ­"~ŸÃ•¶ H!»µm}6ùš‘¶2«¿DMÎ~þþqñŸù•ýg&æÝ Kš _m'ä¶•è4-ÏÖ±sɆ¥žl¯?ý:*øÏÕQc]ó>D\ø÷dVºœ,ösž}E<Þ^€5¨‘LâQÛ?IèÖûû™dðÆ÷\Qâ#·÷*‚ˆ?þ_jËr`¹åÜÁ:Ë{€z Ü}7nÜ ýW=½¾eñÒþî|º>LÇ®} á..ÌQraþeهܓs1Ø¡O·†þ®èý&}ÖPg NåpMf FPZW·]ddÃg?…袿3· é‰Çzïz{³­Í}ˆA$õáªÓÚ¯ËîmÙƒõçËÿþ¶hH Nª pDÞ|*,^©µ¢@ö\kkƵ]À±Y¥E©\ÄH$ätAÃYÌnZÁOHVº¨ÕŽp›Ù*¿çÃçÐݨ#ëŠüúŽù«¿Ì 4$p¬rÇ7gþ¤…àTaø¢H‰Â‡üšY!Í@,8(ôû³•ëâ\ż  Åu|HÅl‹0CyšSD6³m“k³$Ÿ£ÖtçvOèê·Ës½nDrAÇî8­ãWh¡bÑöbzköþ ¬æ¼–e´––^¤ÙéÏ1è§«„ì¶¶f™ƒ8.* :¿cò³%¢ê¾øú)I7;ÆrºÊ5Í kýÉÆ%"ZÛÉA–LœáE€ßJ!’t{'B)@õŇŠ$!žÉ9wÓ{`<@“Ræs(ú×ýýqPþë/: IQ€H£™fñNpͱü ÈG±P µ5µ·Zmfa±ÆÒsßúd‹ÚU.÷²dVOO–ôR?ÜûÔHlÙÚ6Ëð(õô¶#®·EpNé¬o“¤&æ%ì#/9 ›.´CÞk¥ß­bÌ$‰InÙß?ÀqUb¦ ŠyA§ÞGÔ6˜' м…^²êLÊñù|’ÌÄÅòÚáÎO‰&$œ6" {пGÂ&ßF ¼–ûãé%v¼ÎÒBçWµ@®ß„SÕ+Ø=÷ÖîbÝ›‡z°âÿ ’‚‰W™Ý[)ïUeþ’Ü_u¨V[ ¢ÔŠq3‘ÙÈ[ƒ€ì+¯sóø Ö"™g‹8¸¬bh[¹B¼ÅA~ç‘ _Ž®«ûL`«kJ»±{ks ‚bÀÐAº:J%ôr†J¥ãXô篕qI"á¬Åt¡wÁºMŒt{ûÍèÿº½”b¶…µ¸ÆcR›©hDI²êtwfÞ¹­Ü_€Êe ŠAPÇè¶”>ûêûô%Ò΂1æ; ÷!éFà­êì:-Pm-¸ñ,“jœÜʼÖâSHØÇ QÃ%ÚB­@ƒŽ ev>•œ3ÝŽO J"ì÷üsæüüœ½íµeÞªÕ æ Õï Y–ÅÔÝ÷÷‚î_ŽyxÛyïû¾†%êû†› ÌCbDÖq2Ñ!à\€=D nQÌó>1äíß.ª¿¹P\Ђß4õqiŒ¦[^YH«T¾i:ga¯ fP8tk-M¾|™®¬Ÿ»´*ã“ë·SaØhÂ,P"%XÝ‘ÊÛ+TÚéq¼ÓˆûË$ïP¡˜à`S’[‹%Ýl!áÁ¸&ØÄضEq’EÒi§Ó×?¬¤Íµ÷hƒë_‹X‚±±±,~ž ƒlz®6’ø«õD­¦oBR3¥Á÷Èì[]ÙLMÝ&!¨ð`z-è¹ãÎŒ‰zOÃ8øæÄþ†÷ºžcÛøcéD*PJíåøQ*wQá‚·yF µ2øÛ”$¸(ÅdßzæãÏ,ýÇêÚv,ö•Šîº*âu_dì)–f:ô»W‹œ«ÎÁÿ»ºZ?Ÿ¤½v*Á­)Q5—¾þö3‚vv¢ZÎyW[±Ø„—B Pwcš¹fdî%âÿMòßOR CMôèÛ¥žEAz3½ÀЗÏrâé5†1G‚؆­µôÅ·ÐùM—µßŸ•…;ÃífÔywïfsþI3iâ‚d[uÌ)A8u8ÆÆª .Ï}²"MZ¥i/óiNB3ßõ$ÀJ ‹&¤Ëu£à~ܳRâ߸o1=óCšœøŸx}æIùÆ>rZfÞŸ‘ªV[*´ó¹ ²½}q{#$¹ûŸ¿)êî#zÎRtä¦Uq{;စôÅ‹ñôõ7Óˆ¦›,Àkqíó×Åü€ôÀH Pà#ƪt¢Ô"ÊŠ„]£µ•ƒJˆY†¡ ás”ã žÀ)Ák…ÃùdÆ$qunïG ÁÌM=ûPYúÈu¸—nݺ?}ð?Ïýíõt`âôl|J(*‰¼~©õ0ŒZ›¯J™ï“&8.,ÀÍ—`¡±¢ûH¦!;‹RS­Vƒ’–ø+6ç`—š†ÿøÿ‚{˜nŽr…¦ôÕß§¯¾™âÚˆîhØ€~ť߫CR3Åw¸uS¡»PcpŒbà×EæâôØ~Œu+k‹ÕCÿ9·Ý›+ÃE¿¹¹HXëWi{cîKAÜ€¸–(«5•~±£af0<ÏíÔ÷Õ­£@É'WìqZð3o€z@†ÿ >$ã š¸N ’L‘¹, UíÔÈá¯î`€#Þ‚g²xHå³±é’üà)ѫϩ‡@I3 ¦è…Цò®MuanMsóߦÕgØ!Ö©ÏØ–:Zia†±aŸ¼Œy’ŒÆ_؉¤®¡‘°oԉﻮý¾~Ö@7Z¥B5˜b/1çˆÑYji$°ð™|FN{ªnŠÞÜEÿîí^Š|˜gþG@Ä”ûÁ©Î/ cíkµ5òñ ¢áºÛ[“o›¤¡DF7¢\±¿ýj”®ZßÀBßÓùÿŠÚú»ëzè9ø‡€ÛÈÂÔÜ“LV”8)Ö» ˜FµÇÏŸ§e*Ý»EøïPê6MÑÀ$iEÃÚ d&qè8;ÊÔÐc]dÚ¾û+Q ºÿ'ÌÑë”Û¸é[~ÉÅv¸½ž>‰€Õˆý,T*ö—ˆ’V ùÿ‡‡Ô)Ü Ç¢- ŠF"‘ÏÅmÎÁ@oºs"¹0ž?ûŒ±´b„ýˆÏx76Ü×è"´´ü ÿD:¨-Á‰ý¤‡/YÂÈdlQÕh|‚ªM«&yQˆ•ˆÉk×®ñì=¯æýK¿÷o’ˆp“€ Å~Za}KÎ=€ÐË"C$…ë*zëžSgfS–jÿyšz‰ë­6ÎLwjá¹øå¾;;ó„/¦*kOÜ;‹Ðò_#Ù…øý¥e É;%¬í}áj3Øæ|¤] žm {šê ; -uFZpz<7·•þðùDš˜Ü†H ¤Ûc£T(]ˆ/B ²£ øJºµ+(þ¶"_@œ¤™¹GéûïÑwñüà|§$í·š•9¿bXJãÿ³¬úŒµÜ¦ "†a£‚Þ½ˆ'd°èˆá™ËÐó<Ù`,Ý¡Íôáí%È©åÿÈB#HKéGz°d»µ Tž#m=aÞ *”-£þBOa—\Ïþ Ú´—l^85kÇRîï ©«ž:ìqkLÀ7­!°XìA¿¤¨äúZê¢Á†é¶º¯dFß´1G诬æ"M*® NVÉT«í½HS/¦?ú<d+òØ4äp¶^ô,—[RW—V+‹t»A-€æ¢Ö>=·Š4A¾B‹°?ÄPU€:÷w!îíí’0´Ï>Äh€nXËïÍl-÷pl'éÀǸgÓË©•ôÑWÓ÷nR8S1Þà™Mãâ&>—½ Ã@q¨ˆ2nÆ¡þat‡æ´´¶ ×ýÿ hëÿ »ÎXÊyµC ¥Pô³‰¸Ì;‘ÁÈ1«ph(1íäA´Ð¢L öõÝLOŸî2 ¥±ÕI Þc_¹Ä"£ÖÞnÂ]~Ч‘ÜÒ†xÛŒÁG\”Â6ªínkQÁ¸²¼º?4!|ÏÛêa¶ç\êðÍèö--x*ˆ.5ó \ÌêÔa,d|.;©gØÕ}bs€ákŽø’d‹‘ôà.UpúáöºÜðr ÍtĈ œ]:íB$GtáQZùàN;FJ:ùLü¤ÊÇÿ oÀpfðÎ~Kܶ·±èCü4°É¹MY%öçO×j±@=U ¦­ rW(«~j¿ß…;òÖµëAN½'iÐ4RðˆùÓSpƒrfׯžr/$°Ú£ôrù‹°)Ø1É2â#ƒ=A¤ø èÄUÐzMÛ‚}%­û*ž„¹‚°¶N!:½Ýh… Fî à·Ø°@ëöàà"èîQ#o:ž¦ã²9ν?Æt4òÖ°@Ý·§§Îv“¾¤GOþ¨cL»‹Ìâž%Äû,ûÍè9¹› +J]±¬4h)ŽëRÛƒ“Ú^)Aà‡6ÄkAŽ¢9%zýüœ¥«‘Ê]Ü{$¡bèyîï¼~‰ ¤Úµù ,–¯§)+^ËKXíèL-RDìrúÝï~‡ˆ¼)´stÀ] æ÷Oà|ߥûwÓÝ;ØFí¾CX® MIÕ5éÉçj†º@Åøáhsi 3ݼ҂J°Fû®ÿ÷]Jÿ»ÿ#§ÑÕê  Ûd\Ú'ÜÞ,I¯¥_À0fvñü¨+ÐÑ&2%×Q·ŒÌ¹B'¥OÓ?l¥Ï¨¸Ü„á Fœ'+ GÞ@H<™M@rx‚xÑŒ Ã܈ZõÕŠlEš„– ´‡ï…ƒû…´¯$Ä{í(K+ˆÿ5Þgº¿RW½³óݨ[ÿðvjýi^\¼ƒx¹I‰ˆ‰ÿãE5o^g!õG8«U2 pû,¥•U‹ PÓ¢¸/˜©ú¤’E•@Œ…(˜åæ"]'Ùfn‰taêÜ ½‡úçtP9^¥µöÑÍ:â7z;à ƒ™|M€ƒ:‡ðg[­W‰¥5*æšC?77å±'^ŽS¦ü%5¨±·H4Ú•=¸C^ÖÿÀ¯ªÄG zä¿mmšå¹úzi;ŽQq—Ÿ“³ãHK_Pè!àƒ#Ò3–25$Q#Á‰…è‰>ðèˆ]™gÅÖÑ×7ß…øìá»sç>ê RÆË/ úWë*:ÿ Ž„fFN EÇ'¢Ž‚Kµ[˜ÿNɱ 6ãÎ6æA—äeÇŽñÀ´@Xvvé…°LDJŒ¥ëV|kv£Cn ­¡ €\LÞ½{/ÄÌ'OŽq½À6ÃÏ&uýYˆ$ë´Ól“Œ¶2ú±M*{7·«¸ž,éMjn¤¼’ö Ç6®Õ/Ž$g´·½>ü•ÕuBn-]Á¯mõžÁÈx“ûgëšcÎ/àQ@iš£KN•rY»Ð`(¤]¸WV·;†¸0£Nëuo%úó'è8==Ÿ(O0œ-£WîîÈ1ÐË aq¬ª‚Ö†žºäìÂk+ó½´´¾×ìÈ”9× =PÁ]¹»É8ªŒu‡ë¸É}¥‚×’j–ùjk/`‰¯ED¥Q†Öø[]} kHFÏÒÿóÿN2îåtëÆ]K.w3YÓÉ©IO;Œ‡|ìÕ£pS‘ö윿 øw‰/°½˜DÍðg{&*@CpýA°;# Èù1È©‘€âKâWC§x÷î਺ÍNO[ÑŸ§/¿YK_’Y‡t¢v¥¬ïص™k­JµŸÍmmêÒŠ¸Z¹ „~Ƴøã¡Óm}€c$&ùëûŸÓAÍÆÛÝíI?<ÙN^#rNbƒ: ‘á‹#°¦LuÓŠ¨j|*!PWÎ’ n1bQ ÃjÆCtžžž"i"ý‰Œ¿ïm3¥’Á,¾@5@Â…ƒ ­¹-^ZEÜÞ¡BÏé)’Ëà„e,ÒxOO¨°°‡ÿ»i¶Œ¯^(™§÷zJFråm8qjÞ TÙßÒ—Öz‰O©ÔÎøìýg„äKˆ›’UøNœ;®ÆÔ]*-UI¶˜j¸6Ù¯JpBdç ÍG¼V!%ÁP = 1’½Uù®ÌÅ×dƒ'À…hŽUtÝ5üi˜žž&Lw}Ø…ð7#vâš“»¸X̲…6Óˆ¡fåÕö2ÎòËw²=õ÷ø ‡Í±è¶ŸsAµpíÔÜÇì¢>>êeËÊ´7ôWÎÊš ‚•¼7j1<gø\¥%-ïOž bûée9sŽŽÖ!P,°cŽëÃý³kêÓ7‚¯5â›Ã]É--½Œo&¤ÇHLkÐ>¢þ<ÙkÄïl"˜{èÌì)ŽÕȾ±±±¸ž­ÇM?gl Ô#\ZÙ"Öâõ|{=ó2ì0\F}qÞüî$-Ø4¢Jð|Þ×w?4š©Ô¡d”‹ÿÙÜ4´ðzyà¼#‚ÎÅh0Ž äÚµ«è§ËpatIXâ6ÖëMrù è©oroEÉW ¨ðŽ¿‚G”5ëåBïÚJpÀ~<7ÇŒhŠ1Vpùi´sñkôªRkœ™Šª4onŽM5Çç«×'ðXm‹‹Kèó;oà ×}%ÁÓÁ¼ø¬ŠÏrQ^ƒÒÆJÚŽ÷*y´¿u õ+9f‰«còµç Ú1æ]bàõ‹˜eîWP;Ö4ß^§NØœ»:p¿Ïî3*ñ¼ ÜÞO"á\ø“‹ÿÎZ.d³pöû5@²J´ê¦r|Ek»ãêªKžâ¢ó~Í‚òX{Æ­~4„Wo$.æß}úiºw÷npI‰“û<ÏÏ5¦e{ *ÊÚu½m.~‰•DÇs€ÄÍâ$0óê®oὕ÷>OH$Ž=dî}øáC®s÷Œ@ØÃóýÜæ8%°çÝž>—csÛ­[·¢×Ÿ×??ß^Óg‘XœŸ‡ú½ü>$ ~îqoÛ<æ|ÄåÛŽi¤}oŸ¥¿á€«ü_ ÿ¿ÿ[AÎ䛕êÄàÍ뺠— ù5› ôç©×ñ¾6 õ§¾y¼÷òžÞOÂ$¨oîsq¿k,çŸç¼4S¿ÆÏýõÞ‚GâkïáœHH$ŒnŽK!¸ßõlž+H=þüæØü‘(ym_¿móÚŽÃñ¼yß¿¹ïm×øûþo®ýþÆs/åi?þ.å/~Po."9š‹íç¶ç5» ýüvþ^rå:Øê`9ÿùùóê¯ý\à)zÿšÍó¼Çùë;69÷ù{¿‹øœ¿ßùëÔ÷»ÏŸúsÕ÷¿íïÛÎÛqù¾wÏ@NÞ=?¯>ýk-¸_ºoýóúßWþ…¿öx/÷æ9¾—¸ÿ CxçÇoÞëçþæøurëo¾M~b>ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \ÆÈ ÀeüVò1å3pA3€ šèü6ù \Æøÿ[-Å 3>'IEND®B`‚ic09ã‰PNG  IHDRôxÔú$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½W“-Yzž·¶7嫎m3=cHÄb@¨`bèFºÐBºÐOõk¡Pƒ!O1¤1f=¦{ÚwÊ×öVÏóeÕÌA¦T]õåé¬Ü;ÍʵÞÜïçW­är£X¯×ÿü7º“Ù¹D HþmþA­VûïÿíÝ¹ç¦ P¿)É~$‰@"$‰Àõ!ÀõawJD Hn )ܘG‘ID H®®ë¼S"$‰@"pcHàÆ<ŠìH"$‰@"p}¤p}XçD Hƒ@ 7æQdGD HëC €ëÃ:ï”$‰@"ÜR¸1";’$‰@"\)\Öy§D HDàÆ ÀyÙ‘D HDàúHàú°Î;%‰@"$7ṇȎ$‰@"$ׇ@ ׇuÞ)HD ¸1¤pcEv$HD ¸>R¸>¬óN‰@"$‰ÀA €ó(²#‰@"$‰Àõ!ÀõawJD Hn )ܘG‘ID H®®ë¼S"$‰@"pcHàÆ<ŠìH"$‰@"p}¤p}XçD Hƒ@ 7æQdGD HëC €ëÃ:ï”$‰@"ÜR¸1";’$‰@"\)\Öy§D HDàÆ ÀyÙ‘D HDàúHàú°Î;%‰@"$7ṇȎ$‰@"$ׇ@ ׇuÞ)HD ¸1¤pcEv$HD ¸>R¸>¬óN‰@"$‰ÀA €ó(²#‰@"$‰Àõ!ÀõawJD Hn )ܘG‘ID H®®ë¼S"$‰@"pcHàÆ<ŠìH"$‰@"p}¤p}XçD Hƒ@ 7æQdGD HëC €ëÃ:ï”$‰@"ÜR¸1";’$‰@"\)\Öy§D HDàÆ ÀyÙ‘D HDàúHàú°Î;%‰@"$7ṇȎ$‰@"$ׇ@ ׇuÞ)HD ¸1¤pcEv$HD ¸>R¸>¬óN‰@"$‰ÀA €ó(²#‰@"$‰Àõ!ÀõawJD Hn )ܘG‘ID H®®ë¼S"$‰@"pcHàÆ<ŠìH"$‰@"p}¤p}XçD Hƒ@ 7æQdGD HëC €ëÃ:ï”$‰@"ÜR¸1";’$‰@"\)\Öy§D HDàÆ ÀyÙ‘D HDàúHàú°Î;%‰@"$7ṇȎ$‰@"$ׇ@ ׇuÞ)HD ¸1¤pcEv$HD ¸>R¸>¬óN‰@"$‰ÀA €ó(²#‰@"$‰Àõ!ÀõawJD Hn )ܘG‘ID H®®ë¼S"$‰@"pcHàÆ<ŠìH"$‰@"p}¤p}XçD Hƒ@ 7æQdGD HëC €ëÃ:ï”$‰@"ÜR¸1";’$‰@"\)\Öy§D HDàÆ ÀyÙ‘D HDàúHàú°Î;%‰@"$7æéIv$H€Àz½þY/jµZ|¾Úwõýg'ä‡DàKŒ@Z¾Ä/»ž$‰@"üyH ÀŸ¹¼.H?7ëRYÖeµZ]¶RY*+C¥›Õë?÷òÂDà߇@ ÿ>„òx"Ü)~ÑÌÿ5ý_]Û†Wß×ëeY¹®–e1sxU®Ä€z­QêµV‘ü»½Í;…}özHàzñλ%‰ÀCà_'gÉZ¾–¬ÑÏ£·µRÅ,W öUçWçùyç.!ó ø«kã´êüÎb»|`ÿ|1)³ù¤,—Ó2›^„0ísШ5Ú¥Ñh–NgA ^Úí~l›­NF«4›-Ú¤g—q i-ã\þCHà?­<7Hn—Z¹Z¸¬¼\Vdí÷õ%™/É@"p-,ÐÐç‹YøbÎRŽ/ðµÏÐΗ5Ä ±Gƒ8g>…æ>sÎ<~E H}8BÝjò5H]¦ËqY*$°ú]4Ñ”¿,óÙ”kÙÏ¿«ÅOZèÛmüú{«}ƒíšö ¤¯æ¿nÎ8 KAC¡c…KkDYÔÊhª‰¿^NÏ?(5bšŸì„… ƒ  Õì”Í­„¬ß®¶»o–v«Ïñ½ÒëíÆõWýÉm"ð‹¤ð‹häçD ¸¡T¤ª ]â­ÖJ»¿âÛ+âÍð¯/¦3‚¤¼XÌËàü¸ú¬ ¹CôãÁI“©¦ûyÎ q>/—³ØwBºÌâžp2ÇÂZQ/èÒáb2q>ߺØi?¤¿6l€?šõ{hæl7;¥ Ì—–dŽö^Sh\Ž£ÆjZ B&^Œ°¡¡`)8‰¶Öë×|k"Pl”ŽÖ´ÿíѶ4Ü^†5 /¡±ÍÒláJ¨7ªl‚´œùçò§$7u™CØšåÇíx2 RW;×·>[¡ÙC¼+X!Î™Žƒ¬3·hé£ê……Ööͧ\Á®ë“ØN'h÷´§?ÎCXÑÎj…æÛËí¹cÐ÷~|u»¼$þ£»÷rëùœ«Æ¹]µ„¿®÷ ÷Ä\ƒÎ{r}i\ƬêC®›aÞ_Aì+šà`sQ…!Öµ4÷”~ Ê r?Ÿ–úªY–G‡í2~Z:^ÙÛz§ìl` Ž`kç!n„Né7Ðl¶éX.‰€¢d.‰@"Ü`$wI{ÆzvqTŽN^¡ËëÃhÞûÌ(úU™N+!á|p^hîsÈ~N¤½‚ÃDÓ>„®`6ŸB¸hÖ˜àëhÜÞ óú:¸®ç^šóu L°Õ¨?›ú·VZ]¢ó±å¯Uï]!ðZS;š¾ŸÕúi“Vü@»ZJYbÞ/ „†ÖˆµjS"GmÇÐçLNÂ+€d‚pÀq„€fk]úÛËRSèsÐ>¶tE`­ËhH{¸&Χô‡Ÿ-ÛÜ¿^^­¶y±·Êƒ­o—ý¯ã"xX½ù+¤î l¤Ì¹T¤¿„D ¸`-É+Ìä~æŸՠ݆f骱_ùé°—ä‡Ãó2Åœ>8-'çGeÆçÓÓ£ðÓÏhé‚ñ,ª£¶?c–LJïê¾¹š=fú0Õ« KØÐî  ›<4?_`~çœùÂ7Šß^]šñk-RóøRÃl/£óéò`Õ–_%{Çå%þ„í>úã{È ´1hü¥ŽfÏŠƒ Ô%wÆ?ŸhñX±ß¶[ˆ ˜õRV4¦(Ò¨#ð]äšœ €äÀ·z5Æ{qqQÊÌLŠ•1»vËÆæ>é…½Òénp¾ ׿r'HàN>öt"p½H¼R£Ú¸š¸$é6ÌúC"ë!ù³ üôhèg§åÂ×”rvŒ¶?AëQÆúâ÷{:Z½D;‡ü]§ß½×2×ü^#j^²â–<9îéuöw:¤Ï©„£ÁKȃÑÁbY¦±°¿Û‡x!Ø*Ò^m>X™6Ý2"Ú[q¯fú:–õÐöQÖuGh°Ž1nuÌãŠ=Ë5–ˆõ€íÒïà & ÝÀO߯Sž3Ò 7©ÐÜà P/{›¢ÏcÆöt"ð—€d(½)¢uW„ïw5oMðÕÖÀ9Ï™a¢×‡?‚ìõÉŸŸ y#Œw>º€ÐÆghþRæ†ã(®ñoAwÜo%óOŒ f¯+õÒD[‡€ø½â8]“økMHúR«ŽÊ|àYñJ<ð²ÄH][Í›€=sía︞‘!R„à8Ö͹²@ÜÇö8=–Äì2ûüRm9EI¤ Áõ¸ì'¹ÞÏÖ¹gÙ`åó’T?þ­€Ìd@‚`¯ú?ÂAƒ5ÇÆÖ ˆš~WØÒ‚"þ ÆÂ Ï †´ŽÀÖö}Ýi”FïÊPõ;ÿÞR¸;Ï:Gšü! -BȳQ÷úØÏ0Ï«Íë«7 îôì(}€þR×Ì?$˜Ïr¸šö5ùŸžÔaÍШ§æÒCb ±åx¤Zsz×8hϘΥdëâ¹Tæ}oõ:p³llõK³]‘¸ý|6~HgÃ!÷ÁUМoìµË>×Ñ$B‚Ú}­´#p¿û9Á„háq-îk‹ˆý~ÿV‡€=Îoò¹Ï¿é·z u@DäøCòq¯i|Ƚçz3ˆ~Õ(½y»,öJ·µS6çßEFè–Åø!\_'›á´ÌÈP ø¿ôXK2F¯ƒüƒãG4Âñ ­Æ´túÄ3ð.Î&e„`õ/çAØ)ßúÎTÎNŽ <(ßþk¿AéH˜CÂüsGHàŽ<èf"ð—@h¼žÛj4MÈM-?ÈŠ€Æ>Ĭo.þ­]:ǬoºÜ`pÄk!•ó$~5zÛ:‡ˆçà¡Ò/YmWíUµ[í7þªÑ«™£IÍ~÷Ö¥–ªve¦¯cдÝìVEt667*s¾×ÌZ³œCÔ¦áë‡_Qo_»Û-Ý £ôg  %A²ÔÑöëôM¾vÅךµçxŠM˜î×ÒŠ@ðž| Æ^Ôç¹ßkX عÂw_3¾—Ch²m· $¢ßLõºM‘"’5:?[ Ãê(¡å›€e‚>­æ¬lç=é¿BˆÝ¬\/¤* Ž$Æáâ⤜ã^#c/\Ü—^Åçüs7¨~Õwc¬9ÊD øs" †,#_ ªÅ òÏŸ„¶¯6½€È§3|ô>„rŽ–?G{Ÿ ýëëןï9íN‚…ÄØ7Œ}"íÇúô!ªf¹Z2ú¼fðÚ¾Ax’:Ú|s¼æùDí¶·vÏþƒûh·'•óZÔÉWHhhF—)ÄC£X ~,£É¬<{y‡²¿uO‹z _Ó¯iÙØÆD¾»…€@ ÂáSܘÒ)dÙßvAhÁj€-Ò¶ßœXMéFïé£%}N0íGœAÿrî2$å.‚C$ƀ̃ýàÞé)ýcLûo=* ,H×[lvIS\—Ó£OÑî!ðÅÇÀO:âü áhN #íOÉjãKAj:4eQ—€BÙ $º#¸® cüÃ`8+Ë‹AùÁÿ^ùèƒOÊ›o}µôˆ…ØØÜ)o}ýo ° härgHàÎ<êh"ð@ò€æ3´z¢ì/Ðè_= ³þ‹‚8#sô!¥ üúšù'‰¿Â*€šÛoJ®qø¥!)·šû~o£Éë§nR ¿YÃt{© Kä-|ñu*è4 ö&û‚ø±K¶[;[aÞãÑ# îô)Ó¡­.mé=¯´ZäîoZߘ>ŽK`8n±!cóë!´Ï ]&éÙÚÙ,;{;d‡0B8Aˆ™q^T$6`¹òð]›¨ýÝžš¶DSCîö͸:#ÿ;]5jtqÕÆØ 8N iÿCkGÂÇÏØ }onFªá FeJŽÁ‘`I²´HÌ×çlõõs/ýûà;C81{ÁÏâˆÞN“>êžóƒ=äÙðIk<,§ÇúY+ƒ³C{V‚¿À/$/ý"À—ð¡e—¿¹KÌL[¹I~•#¯/_‚7=ÏÀ<ÍÇæÅ«]ž²ï+À ¼|ñ<Ì÷jö¶©ù[­w ÙÕð··!±NKN‚ƒ$Çn¿ËD6ýø²†Ø¦ovœüÆR¹lù·Ùf¢ªÜ©íw°¨Á;óAx¶oý{}æjýnÍÍH{´f‚°pn¯, ñYµOÀqr‰q~}OÊö–Ä%¡‰¯"îS¯w£»,Û”×Ýn¿ 8hÕ.ä:C€‡ñ—uüËzÌ ÿ Hö¸……¸˜N XäüÉ9ûtÎdžꓩOÏvše{ æþÑp^¦ãA™ Ie¼ ¯œ7U:¸Ä–Šh{=D®% ö-\ kÒëdhI™Ì ú[—!i‘CÜ ÎM 5SÃÂ"2S2 tÉœ•ŸüøÝ²·ÿ ¼ýÍïU˜*¹ø°r¹õ¤pëq0ø9õÕ*±ÿâgÓìôÝ©°÷òÅçÄ´<}úyñM#Ç~]Ž!Œó³p\N/ÎÔ¯n*IollPtffûí.ædˆ´¿a㣖ìY¯4xµùn¯æüƒûÐD+BÔ¾¿ù ìö¨XÇõŽ.€KS>d-/é?wñ«‹ås%÷‰e|µ—C†Fã;6 ß± ™ïf÷{™~úÁƒ {¶Ù%²nIE½6ûÕÔkô©~ÿaXºº$¸n‰ÙßvOÎ_‘­p6.b X.ˆo)@a–Ÿ5Ù¢S#tLL  l„¨ñ¥‰)*´µÙCÐ@Àé7ÊV‘:ùþãÁ"ˆùüxRŽ&AÖýÍ*.@s>#„5–Ë* ZJ¸IŸ\T Ô0AàXBúºÔö¹ ÁAÑ ‘Ü[ŒyŽ0#mðâôWÀOpŸœ"|Œp¡P”(¬•à çŸ[‹@ ·öÑæÀ­Äúž)2§ ^íÞ yúà-¦cjžQûž§/~ù»ÿŒ¨ýÑîæyÌXv}È ¤¾IzÌﻘÛ%Þ:þy×ú|ßäXøÜa¬Az[»¥pU½ IÓþ Ï{sg74û½½ƒÊWœË&ë:Ô²WÐôo€i}F æôh¥ú)||_r¼w%ÜPX1 ñöuA½‚Íd<.积¸o½l›‡ÏQ§AraÍû÷B@\ˆû¯1»‹Ã wÇZr;Ü Q©p¨€öÁÏ{,‰Ä7«Á‚šÔ € ¥VcºŒ­Í=JÜrJ;“±é‘´[c3„'½ŽØ¿8 ÀÁ A¦!ôEAˆMXÔöÑù#Ô#øPkÄ•è³ßh ¡©Ž ¤ 1ްÊðÜé³V –LïÛ¿¤pûŸqŽðN"À+MÐ z’ýšžäFßA|æØŸœ¡õE‘׿ézVhî¹ËB+ÚúZÒ>Ø/ûhùmLü=´û[MØmÉ:õ0Ù/˜Vw„à`äüVíŸ?d¥ö=„ltôhïñÃ7+z+A¼Ô¨µ€×9ùr‰y±ÅQ±cÒî15ÉÌ™ûÜ:‘Ä?#oѸ¸`Ÿ¹±ALdzNŒÂ)ã¨ù¾û'â!·÷J¿K_÷p[t¸?çÓ8 €,záK.7À¡^†#…¥Ác´zîƒÿ}<5åqRNH}œÐþprL°®Èz±…ÐÒ†lu;l ²…} v±–`n¯1ëßÿÅ91÷­!øîæ"†®#5xÑÀCb 8ãFZ¨(„8…’á˜g…ÐT bYêŽ!fA¡@+…B† šQ”"±:ÏÀùùϱÏýÌ3UëÞ<—[@>å[ÿˆs€·ê…oaœÈg‡$ÕH%þsªë wª fOtþ3¿šª“阂'¹˜Ž·ð:ÖºZ%>wÍömÌÁ–Ÿ]bÞ_ãsono—&ë6Ž©lv+  Ñ}_ÃrÐàÞÎB×À¬® Ÿh·Än£1CóGX  ~ÐnP’~q(Ypë±Õs‘£óïÕ§J@ãÇÜ Z¬~v§ïÕ?>E PØÑ\/'@Û2ÒjåX̸‡–>½ µÿ½ÁƒDøUw‚çjß+öÑÇåz›ýÔ ò^óúbLº#Õ%þ  œAÀjО³Ào—) ÖðW÷¶lo‹-ÆØ`«]Ã1Hàö=Lû¤êÆP‘µcÜŒO…_|Ü­=ÃU"w·m7˜ó£¼Vƒ®Ó.Wñ™Cq¯Ëf4Èp½š•ÅbF͆iL~$ò¹ÜR¸ O9Çx‹€Œ \£» Ð;:z‰–:,OŸ=œˆÆGÛ”;Hßè|MékX¡Ýc¶¸{÷Ê&©t_ÿî¯â÷&ê2bÖßµN< ± 2ßÙìÎ 082ˆ$f§ƒ:¦»ödX›LKM´Q­D昳-oÛoOÂÌ¿»ÙsþxHð„Ûâ¼Â\÷²”ˆ¤4'¥Ný”(ÿÙeÔþ"„¶‚ÅÂ×Iò+¶1ÑO¸5,(¤ß›*y´0'PoŽi>mZï÷!G`Δ¹«â8|ðUn¢;àå÷cFÁÁ ‹&yªöl8'îl ©¼Qöî? ËÈ&Bî‚ñù’èy‚±Ÿ\bK Îóüû;®H½[šÈ0{X$ü.A†-&ð©Í¬Æ<ª®;˜ûùWZvLª ÉF˜"8—á+Ô`ðâ‹dof@xsþÛbÉvK±ƒoæ `} mUòoòGë?+8ù°ä»¿›‹ÓÃèãÑËgXe÷à ²* Ðå^•Ë-D €[øPsH·µFµ}ýúšóC»§ÌëááKHÿ¢ñ–ªî¼N ^³º×A°>'b VÔwîÚDØYc«× éR?ƒešZ:B{gÎè·TpªÓpÖÕ`A/$,!`ª­%yöœP­|vT•% ²4yNÊÀ/€±hÌš¸ÔöÉÅ糤pÓœgoIæ.‚¡e™s¹¤p7žsŽòKŽ€„ï"á¹ZXç5doäþKòñ‡TxBüƒ3Êì¢ P3xîþã7ÐÀ)’CšWò7˜O|`ã`&¨•WÃÓ2?y]ÿíÐCcW-¬‘¢'¡)ª§G fsÍÌføiBnD4: ƒ¸g›ü÷6÷ío t ¯`£*çhI%ÀÅY¤Õ¯‡œÏ<ö ´‡rŠe]»×ðo±&}!`Nν¤¿ ß>vg0€¬CúÅ}H$6ƒã¢tPM\Áe19§ Ìý“Ieæ3ÇÀù!óêR†¡eM–È(|I½*AÌ!rõ_µß%~à›­_6vúeçþ6BS§œš{ö¿Ò'OüÀšmÚþ°{íŠÀ¥l„ FNiݘUtÕó(±¼8>„4H~sgk6p4¾·XøTšŒÕb€¶ÉEŒ_c—B™W›Ì×aì4 š\˹†xÏ%ý )!~W–[žRfø$‚3uŸT¿7ž¿ årkHàÖ>ÚØmD@s¾~mëéøÉûxö“Ÿ¼[N¨ëÌÁK^ÿúÖö>Z}·Ø*ûw©š×+ÏGè9¦{ˆ¼1¤~ÌZ•Ý¥ÿL¼ƒ¼äi1¢Ì±v›~Î`zFàŸ3ü .T Ëãˆ!›yü 8+vò7îEòmÊêìckp¢Z¾ÖŒ(h"Ÿµr Ò/­A Ø ¸W”F0â W@Ì“p)TäïMr¹­¤p[ŸlŽëV peæWÓWó·@Ï™òN‰æ?<~ ™A‚¼ò°5È%oRò.Êß6¨eÏÜïs|ͨ9£­£²DM]áë×Ü>„k¨ŽÎ4'yLѸ—Ec ’ »B#%:!4ûÔ^­m¿ÄL¾¤A‹9ÁÍbBbcüýK&©YÔéÇŠJt+ëÝK2ܨ¡Ú¾÷)hÿó±0LæÄ0°5oYIüs„‰oæmͨ¦§åÍ—Ø…6Ägø»V‹%‚Í`i¥Â)Ÿ)ó;%í±f¬¤¨]£,°{5ë–u÷!ÈŒ ¢XE¨>Hl a&ˆ¹bŽŠwƒ¸ûÁÛ ®ñ¶õË­D,‘ê"‘ÐÅ-j€T¤UržÓs{È]ã”°Hî´ [QµË3à$Û²àÒ%àC¤Hjtà˜ñâé¹±^> v÷ÒÃÀå?çê&2fÄ F?ÛOZ±7¹ÜbR¸Å7‡öåF@³öÒrr§O>!ØnP>úä'åó/>*#4ò3êË«“·˜Ý­½û l÷wËÎÖ>~vëÚ3v‚ÂÎ}ûZåôݧ¶½$¸m“ mœœç³B ØIyÿý! Êãï¼]ÞüÕ¯Óæ¤¼F»–¢î=ŸŒú¯jë1cºAKM¶}&ÖiašÖ·Nt_˜ô-lƒž[Ú‹Muùô ÙhÕ5òûë½-fÞ[”g‹Ï *òë IÜ+©–z“ô‚?Ÿ±‚ž&ª!²»? Ñ@¼‹–ûOÊÑá!¤ŒoówõÂÇŸŠ¨x34Á}€ÑøkÕYÌñ¡žB’+LòKXlI𚪱KÕNé_ú‚Ïë%1—Í0´@š0™Z¾9úq_ªè™÷_#'¾‰Y¼Ñ€±LWN D€ãÏòú«I‡2'ÿÉ`’uöõœ›%`Ðà’¾Ÿù†ªåJÀ ú2ƒŒçQ.·Šr‹Ê´Çc ¿½øH B¾uqqlá×K …Ï_µÚ•ÿbF®¾bà{hÕ´fuþ(¸Dž¸©Ôl8Ó•~WÑP‘z|·±z.ÿÉêîrll%õØ^^^µ=—ê[õù²ob¨—}r|®Üïg@\ÛÛŠ@ ·õÉæ¸¾thî_¢¾_Pj÷“ˆv~Z>þè½ ÿg/Ÿ3‰Í¨<Ø/{;å`s»Ü{ü,óòÏþ¯ßÇBðò²¼+-)|÷¼Ã‹½†À@j/õSªÔÍÑ*kª”ç r‡/° `*ëW¿E°à£²¿·_¶˜‰oŒ&{üäÊ`ö» ‰bïà‹'8OÂW;–p Ó3ànÕ®üÿ‹6~eV)oŒõ¡ßs.RÓ ÎÙ)~ûáÿüºìuµ›At1Ör^Á¶z9ö÷vÇÂ4øqß²‹æñc˜‡ ÃÁ6Ú\Câjß)zš\§C€Þ@Û<篣.Z´Åz9"­ïéÒí$»ÙÝÀűTG\Ã’:hü+úÐè· š\—]„ë\œ!ø´&ÄF<Ù¤äqwP¶7p« ­9˜Z|Ȩz­•ÂBÁR{;ý_àÑîÞ!ÅÒ xœ¯ ŽÐcJ¥ÁƒÒó -\Â'w¯2 HðFíAÈ WsdL ˜iâ´8¶ Ghúþð=Œ$Öè´˜xzuIHÊj| ‹€ýãiájr'Ýî£÷¹ÜbR¸Å7‡öå@ ò¹ò®'øÊt>5þAkÌ×~FjŸfú„m‰YI¹‰9ÞH}IO昒‡?¨ù£ñJä–Ç‹›c5 ‰u¹~Á, »%&uï1"c i‘yÈPÍ»…¦kõ¾9Ûº H4®æÝãõ†Ã4zÓ¾û*gs”¸Õ_¾D³7’?t^ØgN?æ1‡"V KᆆöhÚ•‘øl¾Ú¬ujÜ·Ôðí× ìã㿸£1-ÎËì“is™ý–¤È¬Ãè®îoß®ãœ:¬g÷¼ß L¸{ˆ- ôæ3I™3YÂâW$ ›Ô7nõ#}ì΋ãì~vUW†ÉxÕÄE@"t„ ÍujÒ\êœÂ×¥j{«ÉøèIñÇ"WT{èwàmOø\MÖd¯øjXª«âpu»=4!h¹åÒX¼gúÙV\yy :mïÊ€áuW×þÂ)ùñ#À-~¸9´›€/x×SŠ÷èçöŧåÅ‹'Dô¿.}ü^¤ú%}ÞÐßýÞ/Ù¿Ålz½ÈÑùâ¸üÃÿñ/LJgåÓŸ!<¬ÊoýöRþþßÿÏà ÚXg¿QÞ|àd<µòü”’µíÿñ?ÿ£òÏÿÉÿ‰e€ :LòÐiyýñçervNiÚ^y|p¿ M<µ€&w5dÈg®)ŸÀ¸Ÿ¹*,¼£›`‹hÖ_÷øÀä6²*åAÊ#säK9|>¤bÑüXûGhÓÛû»åÛ¿öˆñC¢óSú¢Ckñu±6HÊ5µ)t`ئìŒO|nˆ}†UC+G£#Fˆ%L$Y/ÀËý+Tâ“ðX•oHñ¡édA!"©ã_Ç=Ò!Šßˆå~éä”ïP>–‹3âëÇy>:c¶½B¾ú1í1.†ê¸9ê ]— ¬¯_25(°ÞE  /J¬ù`©d+$*i,©Ë« Cêl#…!ÃIƒVÄw˜Ù0£Ïáû¯` œ‘MÀ]â§ ›ŸH(sÚ”À¯ú³Pð¡m¿hè5ÞÏç£<Þ>7é´uúXŽú=ËK œ+›\n-)ÜÚG›û2 à [òŸ¥~JÖËçO˜qïuäö[!¯)µÉÙßÝÛ-÷ÞÃI uýü¤|ñ)Ñû¯ŽËÉádßfV¹òíï|2 òÞ#p¯Q¾û{˜›ëeÿbù½ßýg¸ œvÖÀ¿mAšñéx&õCÂ=óþñÿ÷r3Êßœ19õÓð7»CB¹Ì%‡§‚L, ³”8O³³¦B«ÄSü”ÙçdÔL>C¡!'ÃÑ Ýá:µuS×d8Åm ÖrÀ`-‰2R£õ<}Û­è 4eE»0†X¾˜3%¹°¸Óž¥ŽµŒçà”ÆK‹Ù9Û¤ý˜$ˆmE¨šåÁÒÀB‹YÖה¥„å!HÔ»òÁP­Áº>HþsQø°m¥»ë×yœŽ:.šûÙe·]ŠñàWVrŒ—º;}Œ³¢fp¥mnýóËïn‘¥{»ǹOÞðj¡ º[ RÄ4\‘¿ûr¹ý¤pûŸqŽð U¼•Yo4<Ã?-/ž}äÿüé'øò‡””} ù‡©¿»µÅüsD};e.þâ?}Y>ýâˆùÛ)¤s6*G¯Ë«¯‚~ë·ÿvyððQyûí¯”Ï-´,Ï_NÈO¯ÿZb!˜Ã{ß(¿ü½¿KàÓòùgïÒ‚톤Ãq¯£Ož—§ô!õtʯ~õÛp˺œ2±©|çÌ{?§–ƒ «ð,k\Á›‘î Ùƒ ÂDL=‹ïÝ º·ÞÚ‰ý#î5¼ uRÞý¹¬:$Ct\Hk–…¾UnÙE•¤hïÇ…Ø8€õ„Ýí=Èëõ š=&AÚØ*=j´9·É”ÁÈÑGÁµa¤Ìªö/'kqQ°°øQÖ‰‡‡`@ c‰RÆ9 '+în Îm°¯-SóYa@Ák1ÒÁÂn“C»$v³>#8¶¿ßy4v+¾šw€ï—2U4%.¬ nQéëD‡Š!¼xB.·ný#ÎÞÂÜQ¨íŸ¿¢ØÌ üðÿOê+ù©pó¾Ótwk'|ýý­m¥üðݰ\”Ï>ü¢ÿiyùò´â)óÐ »I9¤Ý'”·ßy³üêoý-úÑ(Ï/ˆÆŸ—WäÌOШ^¿*'óCÌ׿aª—eê– ¶7æ‘ÇŒt¦²a’ß@“n‘ZöøÑ}¶Íòä“§åäùy™žMÊ+Žþf§ü½ÿâ{eû˜ÌÕž­€ñ嚀?Íû…¢>ZC¬`ØÄDoµº!ñ ƒS\ºBX•s²^~þ …åˆõÕ7J²ÇM,Z·™Ä0²Æ)r¥_šÙ§ LRÔÙÙ/5¬m&úi÷)eÜߊ>†@° ¥êX ,$IÇJ<ã´V8ó :ûRòG¯öü‡ü ¨E@`&ÖŒ9®…+¿m5 ®„ )Ì8ÇÇ·C•<xÃ3äîC» œë˜8­< yûã ßQÓdœ¬UA€“Iþ,@Æ6x]\Ë6—Û‹@ ·÷ÙæÈnšœÕî&8¿%}óú_<û4LþÎÔg0Þ ò2•Í´¤‚Àb“Tæ”Ëõe}z6(g¬3Sö|ac–î`Bߤd¯õÛ;Tý ²Ñ¤u†éÞº§OžEÜ@Ý”A^ìc&ééml–­Ý²·R¬…oAüãäÆ¿~õжZåõóCJàv¨ä×Å­a‘:(Í ËŸC€ÎñÏGPž±ª›xêv —C‡9,=¼½}@E@òëûûL8Ô,Û;‹rÿ‚u Ž^Ctõòô“îIM@ÜÖÑ=˜°€¼ÀhŤBا£O …“U%@¬3Šq CƒÑaËcÔï>£Ê^HUĬ`D0j 8€6Vûî d qlS— ‰ ‰‹ÂÒà &2VÀìœ 1ɑʼnWÜß@æª6Lk‰Þ…¬«E‚¶4Ë‚@àyl5Ç›ŠÁ‰<ØHåó—2ˆ&ÜW¹[ÐÎÙíïÂÃ.^ïmÂÍ ­Uƒß ?c,Ä0£]›NO¦ ·¶Åmе -Œ¯Ë3ó·á¤MÕ6¹ÜjR¸Õ7÷ÿ'š˜‡˜û§ü‹§Ÿ•§_|yýþô¡yŸSŽÖ)m1øÉ]ÍÔg´ùø‹Ûáè5ñ¢|ðÞÇ1o{øÕñÏ÷Ѭßz|P>zT¼ýf¹÷Æ£[bN.§X ¾dÿÅÓÿw<þíM€fùîßønùæw¾Q6¶û!Ï"ñ½ÿ œž–§O_`ø´¼ýÖ[åÞî½òàÁAù¯þ›¿G ü^ù|õY!7¡<¿ß+;'}Ú&}ï”ù6Ž_±E°h`BnÒ¯Úòã·¾ÆL€”Îí>¦2‚„ÁeÜwsLû#Èÿ¨üèþ È üãÿá]ÈzZ¶·(á‹°³Ù.[¤6øÜ¦Ü°ZõH¤b¿n‰!V ‰t2ÄôÏ¿ƒ „¢V¹¿¿S¾õÎCÊùNʧRHˆ˜‡%ý[Õ§eo¯_îÝëÚ€5£kp#AC®Fp9Ø}T6[[´³_6÷ïdHíŠü´Â=Ñ-úþúþtþ3fö£®…‰–ñk”K^‰[eɺ6c‚ÂHšõ‹¸A}K´mËöšXŒ—î€NtWð(bÙñWö;/3-1–¶Æ…HìS|ÜŠûW‚…Eˆ4ù»(`ÒÚ þgÜX¼í;gC£Eè›ï`!zÄó#p —Û@ ·ÿç¯͹VÉÓ<=¤f¿³¬™ÊgßÖ€9ÇfZÐ W¡qùbFSãÅo¿6•ì,P3' ߢ6¡Å…éY*mXÐL#—µ{ Ô/>`)€Pç0Eƒ™ÿ´ý7(ekp›Ÿ2„Ðé`9 Æ ¥if5'_+Â+ÃÑá$@ À1ú”àÖ±^Ô(Ÿ‹IÜ ut´§æ­ÿ_ëB¶£†=)Ùx¯:Qz*ŠÉjÑ”[±oàËoÀp–ü5bŽE`aW¡µwK%¿$¯PœPÂ8*ßÑv }žïÒ"š»Q÷à±Á$=Î?°µµQ¶™¶·…¿~oÇ”GK #,€d“¼>‹ð„PĘé.é ‚ŠñA¦`àä:MÚk#˜»/ΰ„µµÐ„­AB­?4>keÕúÀãÁ‚™.¶éï#|ÿœ¾ÕzpGœÿªt@.ð™óßÏVz*—»xh‘êä5â%*]_+ÄåqÛó³?Ö<7þñ˜üÇï­.ÆŒtX#ø2®Ê?·nûÎñ];Ê}þ)evÉã_Ž^” ¦åµn˜œkñ0¥Kdsœ¶+Èlùøvððaùõ¿õ›óF¤¯ š;!óî3ý ¼õlìl–þöfÌÒwŒ&ýÇ¿ÿå_þß¿ƒi|^ž>? ­ÿ×ëïâgß%@ð«Ýf99þŒ¾} _ÊöÞ=ȸUvˆA˜CòL™u|›”øÿQ̤÷éÓsni¿I@!%v‡+:iP“ ƒ>³ã5¬2È[¤‰Û ªO€5¢<9}YŽa›/fŸ9orëóooµI7l•U÷¤”­O8FFÀÞIiB¬[{Mˆ<ýsç¸0 Ïû5U+Ix|E@Á¿Ù*ou»l`5øÍ¿óm¶½ò&l¯·Yvº{e»³ ?3ûàÖfí{ïðŠ0ÂÑàø"Rõ¶ì³ßßýëƒ<Ï?Cð8g à£ayÿÃe¬Šï}÷;¤Ç5ÊÞ& ‰u„9¦tð|t\VãˆñLw šù˜ ³ ¬\ÐTµgë<vÜúšéGT9DJ}'5Ä1«6p#u)!½±yPî?z‡ ÑGÕ„±t!æ6ãÞÝCÃ%wîÔÇþà)Åy˜–ø„L…öºüíÿr¿s½¼¹G´¾®!dEÁ H' Ä2©M ÿ~zQ~üãs‚{åkߺ¹¿W¾û-ýÖÝrAúãùÅ0æA2Žv½_úX¶XýWîGA c\¯t<Å5ó£Þgìãò¯þøŸ1æfù¥oýrL¦´÷à^ÙÙ;@~h1ÑÚC”>£Öþþ“$-°À¬òð‡P‰²Ê²ÒaçÜ@ P›—¹kºpË8Ž%©ƒì¡@–0C\@’¤ù„_á !!ÂúR²‹ÉõV”´%l*$>×pm¬ËËC„„‘1¢bÍÃVÔXè‚¥‚Ó’6'´­c@ ¬šXZ ¼lóÛÛ»wßÿƒ²IìÃÆÖn¸Aþ þwÉ&o )ÜÀ‡’]úò àËY‚t4¢é_¿|&ÿ×Tô› ñó~®t0MåhØ|å]/Yò2¿Ôœ;T÷S ­­mD¿×ñâ¶–ÿô>ÓÞ´0„VIm|úûiÿ£}\ž=}Iÿ˘Üç>¤òæWÞ¸û r Ü9Vˆ#±J È<1Áæëã×VÄ$-qÀ6Æ 2+›T$ÅýÎ0—»£¶Õ`Ö¼N¹÷ν )x(ÎaZŽÉ†øÜÙ©K:F¾7˜’®V߯ªÜD˜L/ÀèçàKgf>¯}øö&ÙÍJ@˜è]ØsOq‚î ,\é7"ÀÑj~/^ŒÐø›Ì]Piþ»Ûø®ÁìœëÌN^5½¯‰àïC˜ ¦EÞaÆÄºÓýÖ:ÃJ毰507Àǯ¢o¿õí²»CPÄh²–Ÿ`L“kÀŸŸC<~;´u=€‹é„‹º÷`Ó×:‚´h,.µºbŒ‡ý1{A÷A“ßd‹,6«ÚËX‘´T˜ß¿)܇œCüËC@­ß¹š_ àa&gªÞHï{úYy…0]”!/~½ÁN c»ÑÖ°|t¤†I¹ÅÜòo~ã›±]»mîÕ‹CJû3©K½<€@%?ï³ àN³¼Ûd::vùáßåå^'Cà=Èü’¤ÐÏÃÇn§|ô“¢éµH9$ bxõâ³0ýO!þÉ䜶,Ík¹_"èMGÕÅPŸãÁVs…<Ô4­"X'Èn÷A¿lìwËïl”Gïl„}BŸ Ì[0}¯®æÊô É¢ñ› Ð&¸Ðüy$™òé{OÑ”X†´‹‰~³W}k—- œ2Â#ÒgDìÇÄ<س5k· lýÞFŸ™ é[A¨5.ãu«|~4/}÷^ŸCÚ“r‚@eº]W[‡Ð–ÝòŠBF-€í&ñ5+Jô6Px¨‰[àñ~il·Ë7Î߈ø…_úö×ȪxkcPº‘, H¬Ù?ÁžL+Ìœ 3b$œÖQUP¡@Ðö#¸ÏŠƒfc€c>#š?¬?Ñ ÁÆ¡ñ×¹OeÒC„㌶Jc‡Á-”äLm\Pw9>›•ÃS‚>`žóÙàBC tSP/ªtùu¼ºXXêb Zsäw]S Eí]!ºXãÄ¿¼ÿe²¥Œ@ 7øád×n¾èÕÆ’÷å³Ï Ñ‹òþ{L”?÷8¦eóúÇú„ãÍÏÿbŠ€éZÕ[‚ÁWýÆW¿¡÷«45Þö¯_ž£©ë‡ày1£¼†`-Ð2¹ïnƒMÈs…ýþÇï³ÁÌŸ–!¦ìûÊþƒ7"Wþ³~ Õ ˜î—sNDœB\óé9B 3í­LWã^ª…¨™’ƒfpÝæáÃ5¡±6±hÊß¾‡ýp£<î—ûoô£rÞ)d*ÙR‹Üý:Y‹Ó÷éc»I 4ï Õÿž|pZŽ_¼†ÈÖÄ$tð÷C¼ßÞ&ΡÆxˆ€ð'ΠÏTÀuº )uÃGOA!"ôWÓšâFëf¯LÛÅ)îüíÃsˆs ˜!ÈèÓnZÜg¡M_# Ð&m¯Ž¥¡û€TÄGdÌÊæý½ÒÀ­ñ•éC„ªNùê×ß*¿ AaCª ÷·=·@IDATX*^¿O‘#‚ÿFSê6€£Â¶{Æm! Wœ£6Ní)k !°Á|xTÊæ½ø ­s?ë¤ßá¥_6?‹ìg·å¹#V°Žx6Ì À¬#˜ìÝNO©öÈ3Ÿ  ¼¾@û…6̼ðž=D­n A ªžØBµ™˜ò™ûøìÈ`¬,OÐ"åVŽçrûHàö?ãá_W^SÌú‡‡ä–C‡/¾?ÿéé1¦÷34ÿ!/xC+« ªæO„¶©qØV£’‚@4ȯAĺ>á13ùM m_AÀ]'ü¡¸Z>ìBûáâ Óµi{øl‰¾·x‰pÃþn Á@ð¿»ä´Æ\~Ña:_´É©‡ SLï¦îÍ5ù³5³\ò sµ&kû ‹Ä8ù¬ïØô;>²ªÛ[-¯F‰O}ã>wÇœ¯ž²@dXAÏ‘FG<þ긆…3!PiÑJ$0±ï´Êö.ꄆ†:WÁ”Qëi¸ã3T¢­‚ö, Ll=ØrGTi-ó#‚g`4…)õ³O)V´Â¾Æì½"À1÷˜¦·@Õ^µÑÓí‡d[cºàsb24°€lG` œ×M!u  åß6•ÄÌÐhB¦>»ÞŒôÌ£Ÿ` Ú¡øô7˜7àB3Lkô°¢š¡³Z¸ÉŸBÁ@kÐLEÞÅpI~—äí½â‘ó,¸€¯üEvä¾Hgz€°L‰7˜Óî!™g3Æ®Ààb–…?µN¤Xò !{ !bˆ¥ Áï¦vÎq Ààøêm‹6‘q¦¸kÕ^þ½ý¤pûŸqŽð/Œ/QÌÝ’ëñáËò‡¿÷O!fŠâ|þ)i“rN`Ø ’Áx#T7úŒÐš—k﨤•é Mßã…Û+µ}&²!Uîå‡hè'˜ÍÛåoý&qRÙ˜-o Á¿zú¼|þÁÇ¼Ü l¬ú‡ð€9Ø`ÀÁ1Ú¨édƒë„*ƒG/(_‹Ã}M°ÜX.NNãÜ9k1Ù„‡š "‚l!±\¦£™¾çÄ:ªišÑ0¢¬ æ–d¬.ȯ¯µ¼µó=8Açâ#ÊèÎD(A0Ù€D6{ÛT<œ–çO^—×ÇGåÝß{/ƒ{­rï«{åw6ËÛß@ðiN¸Ç+n?+'ç¯Ù’f×e¢ «ùI~~ÆJÍ¿t±ÄSpÞ*c2ÆT#´ Î!€† &sÉrŽ0±"3`ÝETÀÒ@˜¾«(ù#,E«œL?/¯e>$[ƒDJRðˆ"EX+Îf”&mp`A‘X6¶7¢ØÏ)AÌ=6À‹ÌÙ«EéY³ì‰¡¿‹{a<œ—1±c²FŒûÖbŸ®”1-„[Hѱê> À/hñ\ÏÇZrÌi0ç™øŒ€P¯sR=O´Ü¨Ø«Ýß#Ž¢Í=67*!qFS~—júf5ôÜM~;Öþ·B˦8î?Š À&î‹Eårwȧ}wžuŽôÏ@& kjßÔ¾ 4Ús4þ1š¹Z¿Ú·…fL13]­ÒúyCô¦µN«à§ù i¡üÿ~Ÿ™>FÛggd œœ#”í ,X ”ý0Eï!`BñL!a‡aû¬øf{ÙÅ,jtº êhËš«ÕêM勲³&jøq=&ýÐøC?Œ+½šÔL«KM«ÂyTûƒ4T¢§Dû£U·ˆ²7MªCR”âGSÅÚpA¶Áþþ“•ô´H,0óo—}b¶wH)¤€„¯ÚñÓjõ]íù C­'tVÙu…æºv:b„‚º®RçNëK|‡¿_Ó9ÚºÖ$Ÿj \ã!‹€±×H¦¯Ü)1B¨¡eÇ·B¸PýV˜Ó¦1¤Ïd`Xd )„FîÑ?ú%›¹F%=ªëq¥å‡eò*Ö 7оvŸ—B˜XϰVXÝo‰€âïÄ>Zâ9p7Žèÿ yg±Y¿{XM ‘ùÍôç4À-úæót*æ6¡¹k1éçÀVn ¡/°bøìlP« P¨k© q§¡ær÷Hàî=óñŸƒýÔ€˜Ðª×ûž~úS"é/˜çI˜v'ÌKoŽþ0¶ &é…9¹Ã¬q;÷™†¢¯áãçíŠÆ¬——²þ[ˆÒª}?þñ{a¶ÿé~TN_’Ãþëåí¯½Zû¿ü_ÿi9?:.Ÿÿôê \”]£´!@Õ}ÊÖú‚ßÞC“….H}›A A¦ŒÁ‚ÃÁiE<ô=æ™gÌš›ûÌùŽûa“ŸR¬g¡³šñŸæË›€’Í‚y˜1(Ô¿Bø!Øìƒ~A½ø}Rë½L΋rôä îwAYásÎ;)Cª~öÓ/ðïwÊ›_}Lq™Íòÿæ7ËÇ-:ÁÔ Í¢¦¹s̽ÃdjÈ’”šw³¡×›˜$–ô§ƒ?6Žš÷ö¢0ÒGC& Ó!#$‰o`^ “?Aƒ¾ØN“2¸ì­PŸáçžâΠH®ÍýŸ}¤Ò*½ DHq 1™cž©ézXNšnϾ r^ Gß?XHI„^hå£#­+4™}­­žÏjäm€.–¿‘×Ç¡÷—: •lÝ8 3¬îuÆ'åPéãUØ1S$J#yÙäë3Mÿâ´ÆSÊ£X’˜«!žq>ÛmSû¸V4÷ÏùÌù{ÿ \þ0±Å5äôÌÖ2@ò·^¥´ÒH.w îÔãÎÁþÙ¨Èßü+MÿÓÿ‹çýun‘ýêc´O-SÒìæic…/™—¾T-LèMȳÙ¢ÒÇËÕ/4¯Ù7ƒs„ k蟒nw é ­ó²£~ññç匌­N|³Â| #Êðµ.VįWA[’¸‹šþ‚¼~Þëøá!7>D¢W!Œ˜BêâdÛ»¼Žm j‰?F8‰$1a–?ÓðŽ_•—˜÷ç³4yú„Æ=:Å B¼×O_—gŸ=à)³<Ü/ßþë_Eóß,÷îPin³œ1MïÉ…B Ú4š rm©Žfl&Ðh+ò4MÏÒÈ—CØ)†û”IÑâÁßó%kÓ×]¾Óîs€36c‘ƒE9­Ž»cÉ$F gôã°ãœCà«ý!¨Ro€qŽþ‡D§uüÿô³Ë§A¬BdL€o ÉÁYûÔÌÏþx<¶ùûšÔÌÅ­‰§å$Ljíd;èšÓk¶ôðÙ±šÍA³aaPq÷ûĶ’ ÌÜÅír×'êrÑZЃݵÆt0ë+xo"Â]² mƒ¾xÝ ! ZAìn.wîÞ3Ïÿ)øb6Xîâüb–§Ÿ}DIß#,øŽ_¼D˜’‡~„iÈz"ö-3Vû” ðÆI¿ôFy€¾ƒ9÷1Âshu 42MÑsV_Â+fžsÆ»V›<ìv¿œ¾:-üÉ{˜ÎOeöôQÁ #SÌë¾°[˜˜W , ø©µ, +µNµCÍê+„é˜Ï´aí€ xîïËÂ\k´Øñ V¯ â‰?œïVÍb[ !£øÙDÑïú¢_}ñVñE9$arŽ•à|ðA:&ù­>¾p£ð¿±Wî?Þ+¿ôK{e @}Má!§Éä¶éS 7›æõZÃÊ|¶æ{˜¬á$:˜ûÕÜ©¸Ãg§Kº kS4ê ÀA‹˜ „€†³žUù¶-L„û£61`QgÄŽÑqáC7*ßÃk1j’×hÅ„§øX9 mg5¬1@€›jèDÖ¸¾Í³èˆ3ÒJïÒ¤=½¦.i”-Ú±Šb‡óÿ¯INÌåŽ ÀyÐ9Ì?;úÍO(’3Àßÿéß§°ÏËrHžýËW‡ÿÍÊ“çÅáÑEX¼}ý·:ÆWM¶€EY6v¶Ëz{¯lAîKÔ<§Õ´;|¢ éiæÞ·)ØÓeºÛãgGåúÊÜ|ÞÞæÑ;5ïBÔ ` \0s+¤¬‰ À‹@¯…óÿjºçŸ‹óÏ/LUã«Z|ü…\<:¢Nî)¦´x î¨Ww£~.oW"áa*üΘØÑ gC¬ #‚âêD™×ÔÊà9é2‚UvïïRÚ¶‹–Wþ Äøø\òQy‚Vm !&€ÐÀ ^›ãËÅ^µÅ¿Rx Óoì7#ù%ò˜>Ø=‘/xSÌ"õïò6q½¢€küåQÚ¡ÛÇø!øÙgÆÆçÇÇøŠÀ &o‚—ǪÀâ͵4Ti—C>2n]õË=>ƒè×Ò76.nã³@{çZ¾¹*áì÷\î)Ü¥§cýS8E³}ýâs|ý_”ßÿýß âÿàÃÏ 8»(gƒQ9¦’S§6™lFÿûþýG˜ï[¹Q—hM©æï‰ÚN ÿS"û?û€r»À&õý·¸®U6÷öâM=Å/q}ï·¿GŸ½rð`›t¬­27ýï“O£pÎ?þŸ.ØB˜@Æ®d®õ¥ÍbÐOm4û‚—x”Þ—=Qà´+™L½€ ‚ê¬hÁžÈõ‡ iåÙ¶`µD5͵ùÝ;A‘1zÄ4(TüÊßz\þæßy‹ºñäÄo#a ¾}!_ø€Ô´99ðƒ#‚Õ¶ûe®ož¾ŽN°V ùcº¯3#^¦lCftoÝ‹¾KÊÞk‰@0ðÆÍ±áφÍ#Õ커¸Üï2]±ÖŽ3¶W/.JËLç-:B_x›±ÉtŽ÷’0•&:˜Â§àׯU°Óê—:éy5 yl~rTÖdv¬°Ôqõˆ­“ IîÓq`Ö¹L±#?‚EhaÝÆTaV†Aus4÷6ÂZ“ê²9%âSaÈ@ k„7ÿ‰ÑL¿>Ç,Gìãìvp7€½ÂV?¾Á‚º5Ú—û‘ Âº8“dÞàcÙ"„ÍŸï<^…//S¸Ò2 ËFYŽGRáĘÊÂ%grr.wîÌ£Îþ»°Î»þTñ;99d=Fû'ê"¶Æ»Îðf·]úe+ü:”·•Èô·¤ï.ø:ÔR×ÐáûÍ}ŒVjPŸ&ÿ1-ß¼4¥F>‡\|c;ŸýÏ&f¡’]“(ÿ:š4Áé|–ÄÕRMõòõÍå´¥F¬™X½/¨DÒv`žà‡ËÕÙB?dŸÄ YÄÂÖÓ]]ª¶øày¶Ç6DNP3—)ŒÐ7 ¡M[ê}Öö¯qc!†kèw“`>ÒöC8q¢µÊ>xZ€`pc(‰YÞÒ´Ž[BÒmШí›ÌZ°F{ÀxYÕÄ%QMÝZ0tM¸jZ7ˆÏ@8Ýž£Ö-FÄFsž#Uj-àòЊôÍëÍ.Pxòs}–òµ ÑŠ>×iÄÔÆˆàX”굋~¸o®´kn¤à%˜¶¯öïP¸-¾}úaÿXƒüùî³£¹°h•ñRPŒEc‹«ñ6‚bcnè §Æ}®>iju'x,ŽûÍFÿÍ岟ï¾:‡­¯¾þü„ütHà<äâÿ7’…QüŸ}òã ÿßû¿[þèÿ€ô¸Óòœºü¼sËÃ7—ƒ·¿BDû#LßoÏ„);”Eزî>„pÿ>õíya£'ÁŸRØg‚ðKÀù9¥dIó{ùâBÁY?å-6‰_·F*W»9¤(A€˜ý_>%MrINúpî¼õhÄLh¶ô×|r Ñ4:øp[8ž‡˜‰¨úw­X§œõïÕôÇ›I¤.’1_ƒx~þÖg‡½®‰o8|È—¬`Z›d}@Êáå}÷ï7KïþôÖ´_qѲl‘êØÄò±ÂÐAH˜ŸO Ä‚m==¢Mú½>áçøðÑÂ{Lbèï0ñ LÙU%» špä§#ÌYeMÞ¬¨wD¼ƒ~ý5Å€jÄN(Oõ¶8ŽãôhXZ£V¹Oqœe…'ç@ G¨êßGˇP QÿÒ.@Ìjß&ê±™}ý-j3Ê÷ɧd0`IØÂ³»O1¥¸ŸÂBûj©ßå ˆGË@E~?Ä3® °2­0ævòùéíŸc«–ÌÏž‘æŸUS× ûP÷ B!baË ¿x^g°§—sElÙüœ³ÝÉbº_µÈæœíW?² 㱂\õy¶sîi%E$˜ªáêÔü{‡ðÿŠ\;‰€3ø-ÑøÌa¿8?eŠXÒñX/HùòŨØt¾.A}{Ûe›Úñu ùtvÚÔ’ßT?MúΦF<>o‚Ô|+QÞä\óþ/ˆ‚—ŠÕ¤áÎàZ²sÌ›–·€Øgæ²£:³œî{\BæÌjåƒî;ÿ’7ƒà$'å -®^×òÒ÷Z£ë låßT9%ȃ~ˆsââ8Wí²C°èô0‡CÜ jø * "B1" Ü6‚/!Â&ÌDˆ4X?4pˆVÃM ÆÚðå=ëqs®‰Ó;:g­kT‹Ÿ9YÕY7ƒçoô×t8#ï%Øætµm¯ÜxÏguŠe­ kÌñ¡EÓVuNe=þƒŒcŠ^â;f¤Ô-'rð2èOò¼´ „ºÎw1´'ZZ°½m]­öÓ.xÈõj¹ì=ý·_\K»¦,úd®„´j€Žñêª+~ö꫌•Ã~³}·~wùù?ÿ~uîÕ±êl÷ÚNõ¯:;ÿÞ%R¸KO;ÇZ!ÀÛÛYüÞÿÉ÷cŠÜßùÿ¤¼zý¼“—?ßavºÇÊWÞ~³´IãÛô¿sŸŠ~ø³)uÛаµÙ¶Êlg«, ¼—ëÉûÌ@ÇÛß43óÁ[D¯!’n!œù½¯¿Q¾³øµ('|zø ‹ÃyùÝþ£‡OŽ0?/¢p·Ûƒ8æh¢S´~Ò ‰(7­LBgDÃ4õla5K‡i_Õn—ÔèŸLH $èpLúš.ƒ9>hÉ"æ‘Ç<~„ ‰ëµÂBíDLçJ 4ø 9ÈÓZ¾FZß;¥¿GŒ•õ·»Tµ1ú?.”4™%p½ 2'Á‚Äï S7‰hâ:¨7ðÀŠkRò,ß['MÇ–þnî³ä¸\_&¤Ä‡JïeÚ¶ut‹ÐÆúñøm„·9©š£2Á¿`âRõÑʱdx.j”Í5 Æ,‡ šÇ†TÏ‘M0ÄP:÷þ&ó2`aù)¸!x71Äâ"?[A ŽÀ#F=]5J^XôÇÑSžX7Ä1¥‰Ç£%î#j;œàþaŒ jíÃôTBÔrÀ€ð'³+Ä)°XÍï©xb=]NºFhü²@ŸÏˆG §ñtØW}ëýOù-ºhñqQô‹çÍõ>"6?¿ÐÏ @°° ž±V-³ÉåÎ ÀyÔ9Ð_D@B4¿ÿœT¿çLêóìÅSêÚC°¬-&‡ÙýÊ‚ܘ=îÞý°8üR m~ÉLv krôW’-éJhàÓ×wl€Ù†fknàèaÆ9ÞAxpZßí âgÐäíîüÌÎ#ÒìÚƒç£Ò‘΋™µò9óB—¼øW$ ™G*æâަd„ëX½Pý²úgª!×Ú¿°(°÷ç,P}ŒéoÃô¡Atá2€|Õ ƒ‘a޳æmîP¢{A†5°2/¡µC—4X1U6B‹’ óž†óYÌÆÉlŒpŸò Z¨E Ÿ;£œ®"€ÌuÙÕJ(PswWõO!ÀIxTÔºEè£æ÷ ?»±Kîሞ+~c—„jcž/e6È­lÌdZå“Êdo}­*ˆ&a>÷úHKdüQÜ¢^s_5xãG¬®g'Ã;ÎDIÔìÞÆUãÖ`O…œ*›ó;ŽǺ@ŽÍ`Qö„d?‚Ï£¿±›?,ì¯þU²—XéJˆ¡ùÜX®þÒDŒYÆÏ¿¸TÏØqø«Éå®!À]{âw|¼cÌû/Ÿ}ÄÿÃ÷þˆü.ÊŠtµí7ï—:¿ÔÔö77KkM³þˆ×qWsÜ;Ím ßÝ´?^¶‹ßÄ[“?jR¼Ì©¯Ñßóyë¼ä«yá!9&ZYF(cµ º‹>“ûÜ+ÚzõÙ‹òò³EÙ»·Ë$@dà.8}Iú ™#¦z•„ ê‹ 2ÜÐ`@ÍÞçL«f·2²œûw(³#˘¼ê5O™ô&êûCìxÇy DÁo°‚‚DM-™[Hz¦î!˰_4šq‡ôÄûon—ÇLæÓÙ&¦€ƒÖå¯×°@îáÀŒ>7ʘFçL¨s~‚€¢æß'ߟ6Â_AÚVà[Ð/£çµRØÕQÿQ—:ÿª®ƒ%‚C˜×é†.€9«ãæL€„qͼõõ‡RÓòᨨÏœ‹`…ûFÂ^SŒÇ|zµö3Ô°#Àáq\l,䤿ÿ G±N†Lös<Šx†ÎN¯U€ þ +Éd@eDª#α” Ô# Ý‘ßPÈK»AŠ- ö€c ¹¬Á‚ßÉ ߉œZ!Àapœ<›6íÌü¦Fû³oj™ß*r¿š@ÎçŠxŽ>kÛráò.´ø»ŒgÍ#Zü×ó§ÁCß ¨µÏ¤U ¬¹Ü-R¸[ÏûÎVÒþâóÊÑñ«òÞ‡‚žÝ”ÍýƒÒ&¿µ·ƒ ±mlBšú~à6df€[MMA@æš0¯/Ò6$.™b]pþ„‰gÖšf)éf$yäYó~mr^߸‚U—YØöƒ$~úÊþž1É©€;Ô××¢pL¢e‚'˜ô6¼‹IX _S²¥]ÂQ.h“¡ )½íd0ô¥z¹+X&ô¥©>&ơ҄æìãÐï$7¶)ù»J¸üDaÛ]f)`5; *H€wvXÝHÍ[¢±j]öÝïûÜ5Îó¤ËÏnù±mI0 MËáoÅ?WëäÌ£ô0Ä 7‚9ó4ý¨Ÿƒœã|Wsuf>+&*4 ãš¹ý²÷Õœ}Ÿ‹uhpïßéqô'jpîÆ÷Ÿu’ëLGìD½ŠMî3”1õZψAL)P-:;^#pâX ½oJ ¾ãï{˜ !Vúð'XW#|þ°ÈqzAШ.MñÛ“îIŒ†ÄÚ£J_D÷Û˜)dÕÁ/,.V9ä:ë&˜·ß Ghš¢š¿ØYƒcTäZ]Z&ª¾Ðaãü s»\´0øOâ¶ä³Ù Õ³®Ò9âA¡'âªÔl:ÁÓLãâ¾\î)Ü­ç}çF{¥ÍXÙïù³Ï(çû¤húŸPw÷í¢AÞû;1EïŠb>K£­0óíqaþÆ,íémßMõkàû—ì}á:³žÛ$íËô¼ ŠKN‡Ò &¼+ãSã¶Ç¤Òm6¸Í x­òõoÿšòEùÑþˆí*!`ˆVo–À.™úÿ/H¢ÁÚ0Çip&Û#l¬Ñê¶wzßëjÜ´O Å’~¯©0¡rP—„ây –:Áé¿÷S(pzX«é-(Œ'°ØÑ$»‰¼§+€ª§ø¶u=ðPºÛiµkóæ¦ƒj \ÀFLä”ó¨/ÃÄ@jÍ 8[[ßX ~:X]+n3ü&’Ý“ùþ¡!ÃX+‰PÎb_T¤ËkúVã«'JÒ›{Äb0iÏñó³rÆ4Ä_ûë]&"Nƒ1M¨ÉïxW’§nœÏKlWT'Do§€dɽº¸|œ¢·M¬†Ö§@>yÍ”Ã|(ÙàåbI艓@Ñ΄²Ì¦enàBÚ0>„ì„:˜b_çwÅ–¶EŒ¡A¤Ó÷öÀB·@f2æC¡KË I·N·TÔ7 P‹ŒE†@ú\µ $ýXªN1½ƒw©¬´ç¸Ã:C·¯Ý7+Â¥AÀ¥åû»²zHêã~ü®=–Z¿(Ü%€»ñœïì(-£+IˆÒ?`f—1Qô3eƒ:÷uLÉ5ˆ½¦¦Í‹FÄÛâ{hÚ˜“!|+éÅj"5dåÛTòr%xù´äE>Cã_`·ñÂŽ2º˜ìyóâ%šmÎ}UÙU54 ’Ð¿ï ‚L×Z MÕü]ÔÄšÓ}ó^‘‘á/UwŽÛ^üt …›ÓÔâé¡ç{™ûXá³Ë?ž¥@Ãþè§DT‘G 趈Xºu² [\-ÀÁ ˆç<ÝB(WXO-_kZ¯1.Ñ. J¤]ƒ(kAJ܃*PIxáqlÃÙßcb§.…œ$ª¶Þ%bF$¾V”ëb¶¡-{Gˆ€@>ZJØž8I7€`ãâ=Ýï£ä.û§\ëùˆ'!$‘{÷76 ´u†Ý  QćçYç»4¨±5-ÛÿËoÜ*„.¿‹·¿Ñ++ÌË0¹Ç5ô50ðËå¢Ð&^lq»zvWçTwôÏŠ.į,Iaeâ÷ï„TIüÑú“ÀzÜwh°äû9¥}ãAyÿ‹•Ÿ1“&÷•û¤ç¡™n ùC¼ýÞnU׿… @°žšÿš7Þàl+í´[ß ÒŸ5oyÉ£öú²5àKBš“R¨&gÊÛÉä4üÑáûçߦ}Ð’=ŒƒV:BH˜•/>ý?2å…!‹­Ýíòµï~½¼ýÍw8§ªJ8£Œì)Ú÷hÈh‡ã!SS¡px6¤VÂ@ïv5?ˆaBœ²þ) ¬„Æt­»AJ@Pã½æßJû¯È¯"ÆH€Ü”2ÄϾxF@=Å| P-š×£iÊõ6çQŒ¯EIß.•új\†‡|ñµÙ—êÑЙn×>ès_â¤^ i[îd`8¦¯ß<»Dß,°cIÛ%Aw µ%ýVV0ÎàÃ&ùó5*~õ[ˆ;—÷¿ÿœ ÀQ¼FÈ{µA?q Øé—oØ&Í;iP]Ÿ Û…‡j°nƒ™…ÅX$œ2Ó•À ƒšÖ;<;…Œ½‚C8$|º€PH› HR&Ä#•!Ït^],]¬H6)±GãJì™óŒœÀ A3 ÔøxÉAú ã"þ8>[¨Su‘#7bvà錠ª`Æ^ q™†ešxvì³ ã.ENRh ã·h@¢1#[[»X¦v¢={™ËÝA €»ó¬ïÔH"W[=½8Aóg"´ÿã1ÓÐò¶Ü€lÕ¸qøqÕ$-L¢M€&ö¬1/× ~^¿Ðux… À'ÿŸ 75ïe˜ªÕDy5£ROy鯰¿N!ì9ùûjù È•÷/š¨4]甾F³ÏÎ"Ðïôøs9®ÚÐܾµ½…éúdBêœóÙ31Ñ„¸5÷ÞËD'<¹í¡­Cü¾ù}éóîâŒêvŒQå® vp# [Ó]^/ãðŸ“Ø˜`å;ø)NkaqÐ5 ùIvCfÇkͨ¾‡Ï÷…¢¡Aª«HuƒŒ°íoütDPš©ÈG.¼~èè·ŒûèPÓ‡`ÕNY¯¬QÀü bTXppöѾ:XIµ†ã~éX ±ý.ϳŸQùS'ǸL gLí^°žäñŽ•Ž)`8=°Ÿ‘DOø8¬8 ¬.1Ų¶u~'Æ\´ „-ûº œ¦¹Å1»®0£­ñ‘ÙôÙn²”é«fñæ|¿*Wl0a”™Žs8vù,Üri´«¤á¸fÌ8çøìl¯¢u>Åâ.´OWG^˜=Ñp\‚ŒÏÖ@PÝ[i¸òŽmR¸cü. Wòþò ÈrR>~þa9º8F3QÑȬÙdò´üvg‹—;/ò)PhõF?V}þDoñ¦T?實…°bŸ¯çL& Í`,'„“Ûo?µ3 Ųè 3´5ågL>k"Ôkcg”“ÇѶ1§?ûøÓ˜}ðèøÓõ´œž•c„û8C°f½óÇ6Д7îó’fjZ}ÝÌ6C‘ i¼„Ÿ8rß}ùK ´i‚‘ˆðr©FèÖ¥" »(!ñUß±Ÿø²fXßú×¾õˆzÿ͈ü·Öÿx|^&O†QÀT9}ém](º/(½[÷?$eñ‚˜†ã—gepŒÀ@ Þô¼Ä©Üf\ ÿ—½7ý•$;ïôNîÛÍ»oµWõÞMöBšÊ”dcah`Ø0lÀ€¿ù4ì¶ ¶% %QÔpH6Ùkuw­wßr_ýÙ%¯´çsþiа˜‘Ò·vý̤ÿ øˆËnñlœm\謥… Göñ·Ì§ÕòÈŸÄ!è&$YãÇ¥›¿ý¾üxÌSuÔþ«d´ôÓl®†#`huloÏ rà¹yÔÏÏDMñûøñýt…JþŸþ,´··Hç«£‹4R§À_k ö”¨dŒ@¹D¦¿’Ψ‘ŠÔÄ¢ìŠãÝLÕ?+©*hK·ö‘õ,ès…Ûû÷w}Šz³ÃLû)Ya®žÁPpï_¶„’2)=4‘œÇ•œ{œŸ¦ÕÃÕÈaOÝY0CÅ]BõÜ®¶h‹y¢ øp¬ƒŠýŠð³)anJÊKPd?G#ÕÃ@iæMáàâ¯ZXÕ³×øG•´LDÆÌ𠯧7ÿÕ½Ô ÑÎö5ã˜ç|D‘¤sBÆP«“ ¯ÆguS† `Ã!q“ryŽÆålœÎÛ¥“ëÃ*ó¦Ö<š +êÕˆHÐ_5»$¿gFEí~Ÿ#d“Þª ˜ ­éo|£ Ðô3à&•ˆ(¤­kdiDjßÜ®G*ߦ’'0#ãvºu àFCQ ªˆ†¡ 7PǯC‰|†¥á–Ÿ}rH*h8Ñ®Ù^©§W^Ýc®„AîãðÉŽ¯¸f„ù(š‡ÓÌ•V…9JÌÑðÌ+%Ýd4`|VjxÙ³Ÿßï;%äµn>2·H±ìCá´xVÜÓ½¯ˆ§B{Â#$‘Çäåâ2»sX\ã¹gI*¹c£o×ÏæÆvÚ€XÁP«3¿àíòÝsAœx.óó1É!¿!~ýA'=xünê‘Bµ´Qß%ù•üu_~m…Å’ßeÔþ¬ElüeÒýº‚ÎlHíB|â’–eSôÑÙïɧ"¹ÒÉã‡a†˜†0–“tI¤Noñ‹} ›ðÚ vdö«/Þ‹E]©ßZ÷?ý$uˆp•×ÛÛûTȉYÔ/ÇjκÍâ]GÊ-TW)`SOm² ÷~„Ä-€…ó!¬#TÇ=†J§LAŸ7 %¤^÷°)ª§•þ6÷ÛûYI»€æ¡ÀÜ#QÒíøÖÌ*H7sßÄ;Ç"Ú | ôÊoãÿÊ+é„"?O.3íÈ…‹¸×äªE `Tþd,’E†9ÆC_ /RÈái KôLÈf"%eRÂiÏy‰aÐh€¤­û¢ŽöVQ¼yg#­’V÷àáe:F;Ò½¤ÇŸœàXYK;Ì«nL>ý[0iLÚÝÃCJÃ8|úÁidc<¹ R€^ßh¦;·WÈ|XÕâ˜ç)è÷¹ç”9ŒÕ$ÀÌéK0ÓÑÔñAÏ"Å}êØí‹„:xlH™›!L‰šx€xQõP „Aà–!ð ÿi>’Öî½B&ʯ˜ ™€1í"Ä‘F¦{ö²Ð@H.‹WzÜM'HïkCROk»Ðëõ´³‡ß>×%‡µÏÿ>È€çã9?³4¿ÿSœþº½‹ôøðCBý©¼w'­âä7_xø‡³ZØüX¤ ,Á޶}L˜cÓ­”æÚjQVÔXGYŸM,Ó¿¼B%ÞKÝ'÷{'~Ƚ(ôÓ=9N½ó³9›!eº·ˆû¯¾³·›VÈ4×^]M/½úR8Šz#4—¨×§†©aKæwé_FAéX™5¡Pª«UÔÉ,Ø8Á­m¦Ò+0ŠÄÍý17˜VØûºðû8³Ás-R+Úq8ÿ9O†{nl·ÒKoRýp·™®ßÆäÊ~øžï0@Íä;JÏf°S‹Þ¿ÒßÁ„HÚÙËT l¦î­¦6Ùïž|¼J¬<Ìayº³OMh4dð­T}­–Â:ÕãP.Êñb¿( ÆUÆ™À "µî™,ÇÌ9˜1õª>;ö×o­¦mœõÌpðÙUêMx§BóV“õÖ×ßbŽÏq¬¥Ï>…€°?Ã,[7jÌc'F´CØþÕøœQ'BŸkG˜}0šyæ˜{rÃ2¨s¯:ŒåÄl~œ—qq™°*”Ùœ1E‰ØÌGÕ½ûÐ6ÑÏïóãþ6×Û&iÂ8‚&ÐÞy›¥Ò6¡ä`o·ËwÀgýyÚÒšvUÞÃtýæKi}ëcÖQ2g Ðs·å Às÷È¿~VBUíßé§“ JîX¬‰‘wÁ›³à³ª¨GÈ`1 À@ŒWHúŠºØdÊà“…–¥’µ3scQ–¹ã”×GR?øä>@ÛMÇ~„äÝKWž¦qŸ8}4 ) ²µŽÔVI[kHë$Ú±»¿ƒ·õJÚÇÑ/Rû²2«IØäœaƒn§”Ì¥¨ÎÊ~ Hž#Ò ºè«>Î<KmÐJ¯ôë··‘èV|_Ÿ‘ƒªÊýÆeÎ#cg¹‰8C!R07ÕÑe¦vaÿ¶öôR–"3Å5±äÉ¡U Û¾ 6ÅÌ`v¿ fZUðëÆäOªŒ©ÀÒ)f ÃóºxÕ_àO†<µ/¡Bw$<žY™ùñ¬ŒÕÐIŸ*Œ|€?Ÿóð¯@*X1µÈü oAR¦oèQãy¯o4H³Œv³i}­®x~FNGæ©_&À| §ØúMô3BccîßíúÞþt~´–a‡ch Y!›€ ~F„:B¦D`feï£V†Þ/æ¡YA žñ\‘½Éœ‚£ôÐwÃÍ¿:r(65óÆææS ¦1¡°/Átdc÷¤×Ûvqq|Ï®õŒy,*0à Òÿ®®o‡÷¿´Ï·ç“9ð|>÷¯Í¬•Œ»Ý‹Èìwtú›ÿм£²ÞÄk§¾øÄÐQœ²È‡ÄCÌ¿™ý aŸå8À€"…—ó¨p•êÐóLä†ò8> †ÀÑazÿ/ÿ`é¦gú·]³†¶)¼àono¤×ßy=­¯¯¥—ïÝNëT ¬!b7@ƒ0`Žpѡ֒3àÁñ£ÔÞ]K}ðqúäÝÓÆµtãµ›HÝ5lÉÅ{sþ£|΀d¯ã]ß@åýÚ[oc³®¤¿ùÿ~’NÎ.7Cõ;1 Øöæâ?%IÁ-S-h»'‘ ¾ U ÒÜzµ‘Þù/×°åwÓÏÿÃ{áÓ0׸Íܪ¨ÏËÐjíC³•I¯SîªRc^!Jbg¯†³\ ¯|sì§û~zˆæ’H!Ü`¯GË‚z=ä\éËÜÔÔHIÔˆùo~™ƒvšBØÉ¬È|œ“Q¦!™i ÇÉ™4µL_Ä€óäÑA7ýìs¥p>: .06«"ø1æUê˜#VKWH©ì >ašÀ<5!pò„ú†– ô2œ¦f0QÊýØ´Ã O Bø”µ‰B ’SŒÀfßÇd p‡Æ@_¦UÁ|÷ãù5"øû‰-;•V˜8"":™LÏ“w—LúçýµÍ f†!£±œ°Ì…Ú‚:É®Ìý¿±¹Ÿöo¼¶Mùö|R gžÏçþµ˜µ ±Ø |—„ùuPýÇݰm׋«`>ªg€Dðs P9üÎÇs:õé¤eRÁA N‘mÎb®u¢ê·?H—‡Géüñ€£øhóŸ÷5£Mg1Õ°ë„ñ­‘ÏsiŸúkëÚÔ#ª VYé«,Ðe´Ur¿»RGMŽ7¨;Ðj÷`µw›Úw„Ô_Ò«æ%<í 9sfHŽYA~!Î9®C^ †:ç• É€`6”—yÆÒŠf ¬ãÕH·Œ~œ™ QðC}úh;,=\m)©8"úÑ¡® @V˜K½&”ŠÌ*oËa¬Ð€`ãßÜ©!ý:Ç\Gxî[<§sf„ŽwCîÍsp<†’š½^ >><ƒŸØø"èûÓLU3ä4r®Ò4@Žùé Ð'W¿ÿU¼¦ý-ât4 ¿ÀH ŒÝ9g{ï5ÔÁ˜4°¸×!3Þ%ž‹÷ S ýèßQô¥ql"<ýù|8Ã?Í1¬èŸ&üVÒÏæà½~’£¯ŽÏïŸo4 †ŽvL/zõœ}ù±q&Á3wûzfËúá/ ƒiâkdäAéôWoPôŠ@ÿ†ÏtýÚS g¾öøë9A—Ø1’ã`Ô#ÙÏGé'ïý jZìç,þ†p @sØ.â9Tô¤W]®WÕœL€2T¸E2Ë Ð Û_™E}ˆt‚Z¿]ÿé{>Ig8úà¬7Å>8>ÁF]H¯Þ»’ýö-üö_»“v^¼ŽŠ¼†“^-ú¤¶j~ÔϬÎS€Põ÷t’å˜7šHóó`Lp³}°CàYdý;üè0Õ¶Û×(#ŒˆW.¯1cTé$ê3¯ vçÓ“.æ†!š‡c$»ˆúT¡àñZß¿¾6æ*!|‡¹¤Y‹>ØÄá`D¨`‡Šü‡ÿ/ň¨~wttAZâ‡á宄©ÿƒUí"€ ŒÒ õ|©ys0À_¡à¯¶†÷]âð68œ’a±‘^zqǼÖÒÑ!ô|Ü%<а=æÔ°Ú2áŒ*gÀç`Šô%c•s†f2eK°8•du $·9_çÏ6}Ò.OÉ»¬9`¢>3Bo߯_…ãÃ^:1¾Ÿq[¸'<óaFôöß„v¡‘I€/1£|pÿ)>¥ÔĬ¡€Eb=O‡÷?Τ~~Ÿ?~Ä‹ͽë˜öò[º{÷NU+éÚË·Óî+7±Ý£Î†É0n}H bCÿLwÒ<¦CÙ5~ÇÔ³§/¥j%öf»É¢¼Çú8Í)7¶)Ç*‹ÔÄ#lðc)Љœü7 V€è¢zZßÕùmÔðªúMæ 8(hTá«æVó@‚ŸKâùñZŸŸì$1:Æf/`%‚£ñþ‘âV³  b²¥[{4Ÿ¡⡵0J¢JÛ&qïíu 5Bš>?ëàq?&ô‘( òèS  ŠUåð× {4jÜÜ|ѯû… ¤¦ضÀ;t€«a˜zÇŸ’¼ ÛÆ?AõÿS^ˆɉLØ#`DÀþ j2Ú002ì@W³õ /Ç©2B3 G?ÏÓŠ†Úé§:@¢ ³c/:%h¦6Àp9š™Ìèä|ÊÐΉ8çœhÃÁЈ÷ü÷Ë͆qÄëdü·Mg—Çéøü)ߤøå_ú°'»&3½)ðéß"/ª¶Õèðfô:ঠ{xzž†¬žC2ó«ßÅŽþ䣪N:§ˆêþ&}lܽ½7lü- ¿ñÆ]l¼„n´XLQ(iàËO(Œ'{© øpÚƒMÀÉŠ-<Œ„¢ò?:@Ãp~`n¤7¿·…M~Žr ÈÀye°RšÇì\±*!¶êò®aÌš{ËÞèH(3 ŠÞû«uÅpŠ¡fˆ©C8#W(~SF YA-%Ò‹¤ú`ê¥iz§Ø¦‹š- ]ΑÔ{ªÅ‡sÊÿá$9X®£‹K|/ÆéÕ·6IÔSgŽD)þWçÓtð V£’v¯ãC ³„TB+}EÿŽ”éË(¤ù,ý¸ù›¦<ÜÅ~qp0›˜iФ?%ͯþ†·éøæ;á§AHà Ï¿‰wÿ>åÕn¬0_Ï‘éðŸãAÕHöñŒ clSøHMÀœD?2(â·ãˆl‚?R}0ŒG³¾C4ƒ]È Æ~è&è—1j†œ´å¦K[¹y!cò¾9l B(õ뤌…͸>"¶ÉÆc_2öeÉaR^cjÚÙ»‰vè €6cÎv™oÏ/ràù}ö¿—3×þ«¤«ÝÿÑ“Òáñƒtx~˜ºü.þÅB¨Ä†|LS;çcIÜ‚ñ刞eÀÌ4®V…Sº:§Dðˆ,p~ö‹ôäýSçäÉÿSœº¬éIIzãö­ôâ‹wÓ&i„¿ýÖ˨ÒéÍ·îE©Üင>€/Á©3¿d±ˆJx–±£(ˆEÝÄ3ÈҬ߰!€Œjë*óžêG`fÎÒëßy›0¼×ñX¿H?úëDçéøñ1&*ÒÝY¼2’¸’Ã5e…QOs@&ÃDDÆ¥÷‰FP°›Âi0WrUxùsS@8«á”Xdþ¥º €²¸Ì GÃ0´ñ_П`Jr1'òÎ &òOæñ•AÂÁ´LBíD•ϳËáE€÷Íïn§“§Ãô·ñ8=F[sqú¢=¢/‚‡£±;/³à?ãÅæZ:«1Ÿ…ÅKâ½â[É1q@fÂzÎÛT×m#Pn¼Hüÿ«˜0Ñ,Ff¿ùö|R gžÏçþ{8ëÅ"‹T<’䇿#òžòébû6FÝ…N‡/E¦ ‹¾‹ª`<)0ÿXÜçx££ÈMç§PûÏÓÉ'Oa(`stœ&Hýezg ‰Å´…-Yûúþ §\Ç~M˜ÜV 5{5uŠC¼½ÉÿÎ~ |᢭ä/:± »P»gËw .؆–óßG-núÜ‹3¼ä‘À‘éÐ*´Òîî5´ $ÏÁÏ¡Gr¡9 q”¯ ûF"5üËmÆ|HHÔÃÑ圚 4!ÜY­t #M!›hA$ûùŒÔÆ:Ñ-ÀQR~V©ÑJSîa†?™ 5Ý‚Êb\˜!IkN1R@sÀN#ÔÍÐÔ¸zM ´%第Õ;³œ2Œà,˜vqÒÓã¾.@Û?ã-)k.YèÄ•l¥?ÝÇæœø8&?Ó¼sœúcsøÈôÌò¹×I²M¥-¢2,«‹æDšxÿéâý*˜PVÖ)5  ;V„>é‚eTo¯Q+ ”Ÿ=ãllZd «8ô¶½ƒ^ Þ ~22a¾XŒß"L^¯`ns.©HW@IDAT‹Mzû-7çëÇ-û.C¼øî,<·8¸VmW£Þ†XCýo)Ôÿ5‹]åÛóNœxÞ߀ߓùk·˜Î`x•NÎ?!ãßAúËüEúôágiû…kiÿÕÛaƒ>#í.ë!b2¯6 A¡A€ÌŠ[QÕLØÝ‡° ^á?ù„-$‹ùðÅcº¡ÚµèÌÆÆFúÎ;ß"Tj=½öækx´¯§&a…mìÙSmTpÑ&|2: ûw¡¦ Þð¯1jdÀE¾RÆÁu[p/¤ŠâêæHÉúÉéE$ËùðýÒÃÏÒ ¯½CÀÖnÚû£ðè¥÷ú×8°ÞøïÑœq?ì ŠFç3Ô &úéÐÏÕßìƒôP´pQ ‡€Ô»¾Ò}ä’ñÄt^›Oj84nšªü Û3‰™{3$äDæ·Yæ3ÀÆ"¢pþ{BM€1ŒŽ‘mòÜ|a—êû<7*ÌF2.WVs9¡%pšV÷ꩾ¶¹ >ûùi0G÷ÉñÀÙöºE€ä†¾=5#„@¥~õ2I¶å+ï̉ÀÌ»‘rJÞðï†È\Ë ®á™é`ÊÛÂ?šðÝÈ.³y0;~ÆØ±çøs‡çd^ܤ weãZ˜½VÉÿ΋D§ÜL÷^|#]'`Õ|{î)3Ïý+ðU'@¶¨ |#R®ö©ŽgNz½å/.»éŠÒºM$߀c†: ÒxEa¤ÞÐ#Ö¿PÃBZÌJäpÇN;&g½¹ú‡€þ˜ÕWÉ/ÂÚMÞ³‰#ÞÆâúWÉn·BQ™ŽsÚÖUç0:ïéq®_AÕÙ^õ~Tªc!ÉÆH²¥8VÿÏ\žéƒ•Û¹ôySøÎvœÉt8‘íà`è¤à%‹j롆“¹îÉ;017 0x k×ë™®7º«¿ÒåRTÂôèRĈø ec ˆ Û Xò'9l?Ü'n"Qãc£¿˜·ß5 ØLIì6h·ä­`eÁö:@| ƒbÿ´¡²·«È˜G¯3˜;äÅ°ã–œÊÆì7.SQ¦ŽÆÎY'@i /ÀwÁ÷a Z:–*þ ìà¡Îd³á|™ç<ûLDYž£ ’6ö2íªV2d¼ã®cæ¹ÓŸc›’—aÂq|:!×-æíð|ÎË19w¾fôõœãf‹[-æd^·A\ÇE>/Ÿ‰× ú2ü—}üÍ'!Ñm$]Ýññ›N§ú@”IüÓlÂÄò©Âµ˜ÏAß‘|Ë)3ù;𕦀vmíͧ8ú_¥Ï>û,ýùŸÿäq?Nï’4çýãÃYzð!…v€¡ås]¨cQd_'ß? ÂÇG¤²íP¨Æ…XIß=¯¿õ±ú«éÖ½ëéÆÍ]<ØÉh·iŒ4  T(&ó«t…­{j“/«oÙ’³td~{V\UÆ#Äd¸¿K¬Yá2õ6í¸DÙèE“1Lþäï°÷wý ìîªøÍðw©;&o=É‚´ïî¿N´Aº‰–ƒ±›}ðà˜¢ATºCjì(¶ƒ£Ûé_&¦¼L ýÈ"X£ÒŽs¯áƒ…˜Á¹>NG&BÅÝ= 5OBòÝ øO“Hêü“«C 1<¥Rº:4~ðEBLsî5 ÁÞ up|øô’ù–Ó+ïl¦^Çíd$ÌNΓ/XB ñgP%_X3Iqû0> §ÅH–#¸BÛªÚßT€wŽg $Ž*‰ùˆ9 Ì]²ýYOÀ¿óSBD1tTÿ3èk7ÈѰ…9g‹È‡ŠŠ“tE͈ˆé×Ã"•å*ØËlÎpj$J Õ1)<þÐŒ…Ô#Íp3ɰSL—,ÃÂT£šÝ;hwVåñìýó}“A ½Lw“ÛðЃžjˆ2³×ÀèG( w5 m¢Cìï4¢B0­ ÍÐl £#óZ´¶à2%˜^Á¸W™´ÖÕj;­_{!½ùŠ&ëFÚ@ P#þ_³N¾åÈ€üøJS`fˆÙÂé¯GªÝ¹÷/¯H¿‹ÍÞD.áô…í¼GªY½Ò-êX¾»Èé_¨ZJV©›öÄÐZñؽKÛHG0+k+Húki}{=­ï¡ªF]Ül#%± ¦2à" s#3 Ò‰…TðÒŸ:hö±Â³‡}W‘/ÎfddE.ø|hg—)êç@ØCm¯Ä©-Ü8Síù¨ÑÇØã!cÑ‹šÖ n¾?D 0®áÁÞ)±³·š˜2ÈO€öÃû¨°êß³òLâuDŒ’q"ôÆ”jhSúšè§ Š”ÉeoØ[¡B[q ò&ðÕŸÎÃýûáJ¾¨Gæwü¢¡”°Z¡ŽhåU>ZMJ°áøÖ½d t0ÁRfL¡‘`®‚§ÏÐÍ]ÜS2ûÛ½<÷áf¡½€ñ2ûÝTÛ?÷ÓößçPúW….Âjb¡ÓûE=OѸ~s#p-a 2JöPŠ{ú\yh®@¼ŒŠ÷Ç1-Uj{dî¦ôéÅj†Â9nþ ú=»We´ãºà7h“ї㜰­[¶gN‹:'ÊàÅqâÇî­ÃTàP8îý­Ï`¢ŸZ­Å;‚isg`È£O(ßr °¼åDÈ)ðU¤Àu¿ëŽÞ£ªßEúèãÏÒ'˜£ÔÞ¹™JÍ$L’¼\t‘ú©ÄGúÚl!ä•fõ+ ‚H¿ß‰E8rº#ÙµIÏûÍ·¿EB”õôÍ?þ6ªéfÚÙÝF*2áò˜gøTèÑGòW~€A—÷ãôlHjèQæ_p»M2#úÝ&ŸÂ:u *£tF•HM0Ó¢þ!Hü˜ƒ2æšó¬‚aà gÁÍùïÖuÞ+Îõvar´ÛwÔ@C¾a8Çñ]~ãï}X;Râ§?Uòæõ—)ãGIQÑK#Øï)c! ¹¹oØôÐÍ\èÞM‡Æ2´A±÷’O•ñµƒ;…©ƒYàúµ›ûQñïæÝ×Ó‹¯|+µ)ý[o®ØE¾å ä @þ"|%) x+=w‡—é²wB‘ŸãtHµ½)S©áÉŒJ»¹‚ýœœ÷ÆQ÷Æ63±š›R:Þ˜—vuÕ¼cí늘í‘®wo'Ýz‘8~JضHÀSFe=+b×£?äC=îñüÆÎ¯ÌX°~­Þî0&ø‰ºö&báfùŽ{ñƒo °«1µ2#J¿"™éhuÖëmpyÑIyø‘òWqP‹2²ú) -1Ë?ÁO'<°,£.³òÏ焎(„'k·Æ¨¦ßû»'÷çž—'¦&/?`S+Ø¡U(á¸7A t é¸pYþVúO^'6¿½‰†°1.?R4âé.ñ¬èÜv@µ€ ¾3bÎ €’_só˜ô/"Y“±óJ=’ò¨©Pª"­ë?€‚%Í8 ¦DËÝ2òz/Ú«­G)Ù=ÎyÚYlH‡Qÿºì»VEıŠZ^NYM R¼ìÛȱæN'2´C2L:•ÙüGæÐ{ê—á˜eîŒ !Nx\.sD‰ÇÀ.mŠºöÛY ý63·‚Çùe^µ;feŒhú󟯔BºdVò—Nš–üÂÈ éïm$‘ßÝgÿÏHéªV©vkà÷CîŠöZÖqŒ(ÿ“S ×äïÀWŒ.bfí»#öÒŸ¼‡]üIºêÏR0²J¥Eqë,’å´yýfHØVéÓc^;¨ùöícvi€…VÀz|ð„XûƒTì7÷6ðoáèê+¦ ’g7IW²H²ò*š±Lgr_ʼn L[²Ðºè‡yÁ…;>ä࣠Wò“ÀØÌµo9ÝŸRW€D3Ã`Ì}›Ä÷·×A>æÝ%Ž+úý°  Éfñú•…°·ÏðC ²R$¬m­΂ø-ìÜØ‚ÉÀ)òê<$vcõ7i+òLfØßñ˜ .ïP ¡¦æ¾$È©ÖÑwà©ôˆò8˜‰á•JþUÆ.ÐHI t~jÍÝ+±êá®éŶÙs 3T°`ì¡ }­RupЯ§íýVŒCµ½44b!"(Ú c-–‚ó¥'V“ÀiëLqœ rá÷0KÇTõ3ìïmJÏê~0\"¨Î{:ýȩ́_†Ñ;œ%µ%ðŸó@˜0#Èd„MÞÇï9ƦeÀýœªsñ97è³Ô¢;Œt FFÉ{A›%#¤W?Í}ÌCm΢.AÛvúJøOàö•1TÒ4¿^3`¾¾gŽÉs2 2 jG" P\)cG_0>ÐF“Vr0\¿õJzùõo“üç64 dÁ‡o9ž¡@®x†ù×ß=4°;CÔ¹¤Ñ½ÿà£ôèàAjnì¦ÆÚ6ñkiçæu@®1‹jeþ¸’†tTWDc›?ïÊÛ^¨\úîÏÒ{½‡ýIwk-ÕV›Yv;T±#L»¯"+kd¤Y]0‘{žuUÀñcŸ.¶±à.ö¦–U[¡ìo¾MÂQj—¶ZŠ’0’ý“‡§éâ³à⢯„ºB|ºc0û «ýŒXtÃÅ_Có0Ì çüƒÀΘý: Qeë.h ÒÃÜì¯Ã¡æŸô˜ À ™Ýn@A#'äLЗA`»º $9º¶‰ƒÒ2Îrcœæ€BÑpd.U€C@*ã<(Œóh¢Ï ¥Y¦óY é6æLr:’Üpÿù” ë¨L<ÔÒÖn+4'G8B"”kºÜd¾Âƒ¹NÌiRrûxÌú è·`tAß €ÿZê¨×Á¢£8 í O?j„âíetŒÒ¿<@áÐ1Na®"Á*|é-ÃÀCô]”N¾E4(2e˜ÛRUÇń缃2r渙C²d@|odâd˜œŸÌ‘÷v“Y&ðákœF–g1gN¦§ö]“yð"I:gÚù x0 ìâ¾2_+kkHÿÍ´wí^zá¥o"ýocrPµ²¼«å[Ný|Ë)ð¡€Òp/«1ç§WÇxp_|Hf¬z%QìôÆ÷OPeI´6UÚ¦ù+ð²¯àäIJй~ê2H·œ«#á ¡Æ¯€é`¦ã™’¶«°[è´‘‘û9×gN|¬®,â¬Æ‚œ ®¶`¿Ìq@Ó!Ìãa`pš©ÊQù«.r}îâ€xyÑCU=ø5âò?!;0˜jßdpÀÀõ²_‘¨àXAûD©š†9EŸxöy æôÓd¾J2Zj\ЄMâcÒ ½Ùéq:bƒ Ã0bSÃ.Pé¥Çú±Ÿb»mîl“P©µý©ðl~FXJà6`IqZ'ιV6/> 'vzKî@õ y ˜4ÍëpŒs‰o&äë¯O[ÈÔYº\£ùcv`Žö¢þ®üHìÚüC-˜s.ì¿.àfñÕþë¾`RúÐä0Y€t€27ûлdQ?xrŽà,œÖv÷I·‹ YOó9†í(TC[°F’Ÿ(ÁË\¬ §Ôš D6¦Àüªˆ¡Æ·'$µ¡âÞÑÓôøãG,þ•tçåuŒzzéå—‘ZÉZHµ¿ [iõ¨>7H‡/ÐáÀæóÎÔâ0#(Ÿ¹Ò3€(cRÁž P„.Ò& ý|ƒKÂä!qJU8“âð+s—nˆ5 ´³ÂCzã›$ÛÁ^ôèF×Ê ’ul_ã¹¢ÉI@o}“tçØc¢èR­Q`ׇ"œ iô¦ø5ýñÅ9Ü×%†©c…@î¹²…V…— ü@x†š0Ì Úƒ j'|"W„úwæ`©ßÀlsþÃKè:c¤O(þÊ(YöÙq®êŸÿä l?#T/ö’Í›Ñwð4¡g6UúÜ š£,É´5Òš»~éû­æ!4Lô¡-âýóúRÙ •Mœ,ÿõÿ½tï•·qvÝçù®™1:ËÿäXP gòWáwNžY”e®öêžý=$ZŒ¡¨öw4R· JñÈ‘™ƒ î„ÅͲ´af¯úX[²Ðáê:¬Ä5ÈÇa ª,ÄóPxž%•†Hÿ,ú–¦U%ªÚ€"¬Ü“9 hM;×òÖø•ìè+bËqzS\qçZ£L>diÚž’+Ú€µív8©…Ôh_ „ §™":ö¾®ð|‚ñ`oˆwâ R4§5kÑŸÏÕé€GÔ}à]nµ¿*á|54&*š’3`Br¤Æ íbäý¯©/pŽ1š-B"Žú†¸K€vPPMÿ9ßllX¦=È,£…Ò,$G=ZB~/`¼É2*3vŸQ 3ÇlB„‚û8æÜUéû«–ÇásÎ$CZçÑh.1¶¨ÓQg۵ÇaöZ%²‚‰g„)@FÆè*&Ó'ïíM ä¿øÏg¨Ìùš}w¼lÙKزy îÎ]žÁÇ’1BˆŒ úí˜kC˜_ìýî'{¬¼i4ñš•è‚“±±­@Æ,„é Îg×f}dÏÅyûñvj[ „ü­ í[åo}k?´ÍÖ Œdþ úæ»_¥@Îü*Eòß_*\Œ¨ýû€þÙÕIzïÑÏ~²ýQw]ɼ‚÷r ±§€J{J¨˜«hQ[.ÒҘж9)we&#°Ÿj3<³X)«äÂ7uLŸÞt¨}lâCüF€åĘ{äÿR³à=Áœ à…w?íµ—ù„¤¨Jj¤Fàê_T#`ûˆµ×y À0ôÎuúƒA( ñz§UQU6€qôä*=¹F"ŸNzŠÄk¥½Û¤ÇmR”FÉÎì~„<{GÆ” —Á-Q‡{dV30³¤-Éi¦çK?¸$䑱©M(Ñ  'çÌœÿ »v )ym›¼T\ß<äž}B)q„9Ù¹ÞH;hY,Uk‚ Á¯,H2‰þ>IŽ)øŠA‚;­Dh¦.“”³¹ú ¯·Ç ï3¯ `é„)^~i/îÿƒC¤Aêœë£`-sx=Éô— o+%ö{„ïÁÌIÀ¤¼½…¶­ÉîõÕð§˜}ØAS€_´‹¾†„_’)’ô 1cúâ9ú¬¡í¦Âyù.xÜB>j?äóF¤ÙurÖIˆyÑÄyI IÀùÅWHÎÚ€aäªt "ÙˆwïþŽÚ0³jH–Œ€÷°Kû pç»Ìat·è/”ô#3¤jÊ;2‘Li¥•¾ûýÿš—ôÆ[ßOÛ{7 Q"9øCÅ|û‡(3ÿeòã_X G¨å;=ÃýÎ ÷;BMOÊ_$<  ™Ô¥¨²ç€¶%l%]1ùÌn“°DŽ}T÷zÞ|T’«òDJÓ)^þJ÷´›GѤHÕý¸—‡ @pôQã+mÓ{¶×£K1Yµ’i‡Ò²‹:ã>¼·iÏ7úPË9‹5“ ý™¿àg7íÝCÀ¶‚N·6Е•~ÃöÏ|Š07‚…Ÿ`B¸°cÂp ƒß OekŽ„Xþ#¿À˜ìŽ!¼ÝËŒ—ESþ”çÆò¥3U3G?þ–Æ¢™œjK§/°Š›yd)ˆ~lè£;hes”BÚgÑAúpîKP㫽€)òÚ–Q6×bI˜6¤Ñ©ŽÐâû¶5BAj–É}0“颕þQ©½¹ÿ‹\[CË¡/A}ßèÙ"š¡A“ UÐ~ÌÌØ‡‡¿@¬“ Œš™© ¹crÜŽyùÝ=óôejŒ$"ÇØ$Ì~{Œ>üç±{ϳ…ƒ`ˆýüˆv6ÉÚFÞ~;ò?=¾Øe6 ÚÄ8¸/ãð¬ÝÂõÒ4cì–˜Á*dý»vë…´µ½—6ðX]ßfœÐ3Ëù–Sà?Bœø%?ôåP@§?kÞŸ>M?ü¡Wéè’Â6,ÒSìÖs=žtêÓ†I<5nGÖ;AŸ…­¬# £’¿k!¶V2ìÑLC6 XÄð)€ïÇŒu.ÔcJæê 7Dº¬®‡`J_˜‡t"K®L€ €à!Sà  „äÏw—u3† çPS Ñf0@Ÿ5WH¯0Žß”·†q `áy97Ç#€ZP~$úÐ#ë ó2ÔkŽ“›N ¥‘$:¿¼Â.ŽÉ„ÉaÊРÒÀI°ƒT0A’±ÿ:G‘…z $Œ’\ÚÏZ˜K‰ ˜È|©ùpƒé’Ös|æ #`P™ÚñŠŸÚ÷ÃTÂLËp9g ¿ýé¹(HÄÞ¬¡Â§¡Ní4ÐÎ ‰fò¢Éè¶èUYÎ~ýæ$-"BJæ!Ú àÇL=IA%¿)RÚê4Rçbœž~FNœ»|wERÒ ;“ +0£` ¯cgzšrdTóû œ‡ÎƒŽ=æÆ>æ§ê¯j!ÜìÆ¶ñ㥓.2¼>¼;¾š¦xìèq÷% û`Žìƒ-j7øëàŽ{jù±­ÎiHÿ„ºU`l*HÚUü*zü;.sen½è•X¹’±8BÆù8†G;C06Ñ‹ññ§O.É~wxwј v®#É7pøãû˜lw‘pW}1”è™BøŠŒx„µíߨ#|°—>ü1qœëú‰”ÊxÕ›ó†ÊZ ÝÑ›ÏJ”L9›·ÚP.óšçm=váDçÞ¬}ÎS‰Ö07†¡eð¢*w|"¬AÀ³=<˜§sùŒavÄõÛ$ø@εÑ`DZdüÖ¯Ë@BUÁЬ2oÞ“5R<“N0ª!>¾/£æ)Ì [­‰æ€ïQ1ü è=TÿË'£Ì@WÆÌÇ<ï“óå²OÆ´1#Þ¹%à8yµx†|—40S`¼ÌÅ߆ã‡'?ÏØ}…3€ad¯ãÊÞeµYQ©Ï_縻÷ñ•4]ôe~_{ãí´Éÿ//½öNj¯®s=Ï,T4Ì·œÿrà!N~ê·G“ýtûz¢^dù;:=F¥ÏЇJ¼È Yxü¸R»à .¶JqêBÝ/óÜ—Yu+7—›ÝÍ „x`…µ[û>{D0ñ÷„”êô~ ãƒ:Ý«\å]ÈmZÄ-%¹X©]ÅCTËÎÇ"}/¯‹,q›2UÞªØÍX(Ó£´ª@¯~mÍq5×jŸ.€JŦA¶Ïó §D‘ˆb8ñÁþ Ò? ö;01ªÆ!‚s3‘Ì2QŒôÒç@•°}ZìF ‚5L—eiohÝ €’±%Y¦ÒgpÙ0™_L6èOWtÇ>‹Ãñ3;î%\”5ÿåwé'W— €2ÌÃgA?v$fª’܆’HgF5ÑX±,“ƒ6@M$úq¼ÐÚëÍû_£ú`HéÕ1‘Š©äO;#o²è~Á fCušòs‚òâÄ Çô˹dß$‰ñ:FŸ?ÆÎÈÞðD€àGiã\|Í޲níþW·¸eôKúÊ~CþU«dޤZÑúævÚ¥ÀÏÚ¦Úˆá3~¶ó_í4ÿSà ä À3ÄÈ¿~yÐsýÓÃ÷ÒÓ“GéG¿ø›ôï~ôƒ´BŠÞ;o¿ÅBOùÒM<˜žÿš_]¸#Þ_© Ç?ß*êrÿU³jfä6F€Õ;ÃjÁ!çcCÆp®ç¸Rz‹ïŒñ˜·0΄¬ú˜d&ÀR !R¸,±zÆ7C¥?G5íj>ÇÁÏ•¾è Ïf)_—g–úø+øÏp æñÎÖ>©uû$ª‘h4«|°Ã#Öê¬hܹ]8KärEh$bÕŒ¶pJd_4Q<\F”Ò'ÒêpG„>xtœ.Ñ0dš3ûeLF–—€97-…Kž}Æ6 N½²šnÞº–®V$Ži¥³ãÓt‰Âýw)=\J·ï!ACG¥gi2%*ÂÙêt(ã ‰¯> OºW-¾8n›ež}·Íü#ðËG ÑA;¢ÃÞÈÌ~7"GCC¸}k·NB›eši뎞FiTñoP]_ÓéQ&I…yZYo¥v­÷«5Ïã—T<ì_M)ø¤ù…™ÑÞâM%KdiŒÙç-!CŒc ÓÇd<·T¬Ç»±h¿xüÁÀØ(t6Ü{ê_a~pê¡,¢} gLùÚ …ýò5CölçÏÏ7ÎÛ·÷Íü,²ö25Û;ûiÿæ‹äú)ýáŸü[˜9jPð§¨J$ßr ü)¿-ÿDBå; ¸@qLÓ#HVºá4SQ”ˆiC‚ɤã…D#æDvV^œÈ<ǘ¥ž ?¨ú6Û–6[³Ìž±Ê‡&`¤ñ?˜!Qgå_A£@.Zs‰WÅ•S}Hý´Q ÑÔF|·‘\¥—;›„ÈǵA8Ø©BæŸZ +Ëé´Wr]fAàb®S:–FO{çÇHqö“ÈÚè4æo9heXܦD|ÕÑ~"{Þ³’ ×.ú2Fªýj*Öq®`ªAéã-o<º€™Ù¸Î0.ÍŽC9~'ÎINeM=Ä9¯ë½œMòø'ÛÑ“c€¶ŽÅP=¿[Ý1œõ<Îóñš¾†4Öq´2¢Z5(Áä>Wíåî3í„^üŒŽ9˜?A-Hh{xf¡i°v}û.ÍÑİc Ï=÷|ö?;‡8çd›sq[î??O§L+$Õú¾OñÎ~þîfñjÄö,é–}¹÷ôòw¼“ü(cã1«Ÿyýõø_%Ï M@sг晬çüoNœ9ðÓ'?ûS O%¶GG÷£Âßg÷ÒÙô0Õ©°öÆwÞ`uÃÙÏúç˜HõRx‰…¿€#Z§/U¾%$vN /Z†MÕ Ë)q÷¬²üŽd>îmÉê«Ä'phWî^‘aìyÝÓTÉ´)¡V Tóô©:^•´va5atUŒó8šƒX™ù[†n ¬Z>óÃu]¼ØÇH¶œÿ“Òÿµk,âd4d,ú=Ä\ƒÑ¡·%P‹|¶ØˆáÏü¹¥óíW¯ÒE¤Iöñã“tüè°œ  ÄÂ4¿cM\éoab¬E0¦úŸµN§ÀÍbúÞxófúðç÷Ó»?þOòZÚÝòzh§3ŸHÔ`Çs1ÜÎd;ÁœáoáމÐ@Œ΂2‚o¨÷ušŒXØÄxÍ:E*ù_œSœˆv‡ G„fWTÝ#1P¸þ÷,hcb£fÔK(1¯È¯½æ¦Pø§ÜŒÃ|ÁDaX¸¨Ì¸«•1ñh>`Žp,„ÑÐ>_á]p|&&ÆÌcéð'S¢iH¦Ó(DŸ56ø‰s§¾%œtž’È }r&æ!蔩úWi$²¾‚I†wZõöÖøÃÈѤò0¬ls¿üN—ÞkÀxŒõ¿{ïhC®ó¼¾›ÞùÎ!õ¯¥Ý;ÜÃg’1•‹^ò]Nÿ$rà?I¢¼ÁIë>Ž~VïQ™N9ú{üüôú§È «¥Xøù¦„àÈr¹X|]˜]j]Ý»”fß•P³åUUyt«:ßlÈN)1’» š{¯!ÝØùHD#ãM3ðvulèµÍÇŠªlî·ÌîÈÀo¥Ú¥¢@é8TܬîSý ƒ€#ø›Ï_`Œk\ùÀãtNÒÅ•?@ñ'í½%ãRÚ>©Ý>*ÂtÅ`ÅÀÿr"~¢C\àñz¤^>ÌfeIðÀ

èå̘Ì’oŒ3.r¢úZdΓX=˜W´Ìhô¯F&ÆÏ}$QÄøûlœƒãdï˜ýùù¶8înù¨âÜ3í¤±äö þ>r7©$6ózeï6äï¼Ç¢I´[¶õ¾ññß™_ð/Ó\¡e}W×7ùlA›&ýúü|Öù–Sà7£@ÎüfôÊ[ÿ3)`3ñuNÒûOßMÝÉe*îáܵ¶š¦W½t‰#[…E~u‹öHy3BôD_q¥oªÎ¬ gòúR²¯!Ð(zr%Ñ~EpXl)“k„¾`pš {ºíSp§H"œþÑ9÷Ôé@ éñ̸á¤Åî‡JÀ2æÙr­I Ôô"çFŒG[õÉÏÂ2!9ÚÇ.Žû©Çü ¯“%)#µ¶W,Ú8§Á„Z´T]ÃÝ;•øƒ¤(Ì}%÷ Óç&TJ<'´°cNÿ.Ì¢f­@3¡ XŒ/šQCa^lÒ[ Õ>ãqÊØÍ˦Ðí90@:.§­ íÇ…´=¥Ûw±¯só÷~Ò‰1®oSJÍÉ*©tÕX£ñš.•œ†ÌÀî1cÕíâ±Ù÷Ô¤è!Ó2‚>Mø:¨˜34LOÿ¥þ ~JÜ%Ì$%†_j¢õiB¿†Ïç*3FsÒi$„Û ‚'À|-¸¹š5 h}ú˜ Œ0ý^&Ùã^Ñ‚òˆçï3ÓãÞG €ËX8n.‰yùläÉ|TKàöÕp[ìHR$ãÂÜ8«0ëÐÌ÷‰ªÌÁÐH/Ïù8evìËš 21ËðV}L í›0¥ÐP\o}ëmüÖÒÿéíÿ^ÚØÜK[;7xg¼ÖQç[Nßœ9ð›Ó,¿âŸA½ÚGØýÍúwÑ%dmÖIkE Õ( ³BŽUUªt)…Õxˆ••À–G–Cþ±`.—ÜPbñóŒŸX˜E’hƒÈ¢Ò. »ÿai4Æ^®}Ò°§¼.` JÛ¼3>‚ÝÅ éµH‹ñÉÇ-´¿{ÏPýƒJ·¨ J¾= ¦]»sŒ•sš õ£î¦5 x Nôìm=æýC®µ?ÿs/2É pΤE#ÓÿZNB“…WèEîmÚ_l)€ª,RV®6LHþ¥þ47áŽZ]éõ ¯´Vê’Gô '‡ L™ôi®h[§K€QRh:ˆ1SĘ·[ 5C×dŽL£º_ðï“I tAò‡6ŽM­Hu2”s)-kóà;Þ˜¡­ ç„Ðlpÿpˆ¤­´á¦2\æe°¨’Ï× u¼±~öG}?Ì0­ƒ vŽ5\7™›3Ô#ñßÝsß9çÎ%vÏÜ;J‡€ÞÅ15Jý¶“2:ã S‹cÒ={OaUh/ð‹ß¾s2ш©JO‘ú+µVÚÛ¿•Ö‘øuúÛ»q‡y‘Fš"?ù–Sà_Bœø—P/¿öŸL ªûœ=MGWO±‹SÌÅR<]ÛÞ&ÚËY]9•6e¹°+™í [´‚.¬.¼zͳ:^² ™ÒŸ5“ïJ_ôéâɦ\:ä»þVÂ3Þ{‚¤Ü9¾bµMľ÷ðG«ÀÇûÆBìJÌf,¾½Ø•Å}25wÖ9Ç×±ö{¾èÀ&Ð)áb(5q¬›R/ mœúêj=5ñˆÅ$ð~ná©ÈÂéÀ–‚›HQc‰Áûó{2BT6‡ @0 ^âTUá0ÆÏGg °‹f3m.ϯB Õ¿bû‹Óqz|ŸÂÜöòÜg‚–…øõ1)g Ç3ƒaThd¡—–Oïtý3‡ôÖ¬bä…!~†*ŽÐû”Ìíâ·áq´ñºMâöÃq‘ y!Y2ÙÄ=ÒI? ç“Ñ:›Ì y.øãCá?CJƒpÒÆis>4N¸T0‹Ôð©ñNéH‹Çy>\©™£ ¥tñW°Žnøã3–7ãpvŽwÆÇÏÍsq&û_¹V­‘šŒÅ„n5´¶ÇI®±\°óšú2sÜë=§âCÀåx‡Ú鯭‘ü×Ó7¿ýÄøo¦ òü×ÿRÄ2zQ¾åøçS gþù´Ë¯ü (pvq˜>yøn:ïŸ!¢‚lTºãÄÂ-‘›^ß‘Ç)PÕ| ªÌ"Z mAKæì;.]¬ŸÂ; :+µ ö84¶tYec±˜§†îi{&±ÌùÁ9Ò>ªç“-¼ªS“bC‚Ðbqç2ÅM`µ€Ì<Æ‘8Åhø¶T —E4ĬN…¿rü™[¦ö¦6 A»Õ@𳝠@GŠ–îƒLÓ`ïl€‚m8Ší\ôã#úp× z¥•õ4­xE8Òqo DêœÁNú„ˆj_ñ¡Ú^œ€”l5´×o›?¾#›öyîj˜À  Íœ8ü"æ•Àj=5'1`v³´þPGCΫ¥Pò·Ò_ˆî¹È8˜m˜ex®;{,‚þd%ÔÑíâ¼ÐËH,>P9@ ßXÕpÎ~jš_þ• •b’“Ï„ãS毯G&‘á¦Α}ìDL#4>O5¡‘Þ€{pý‚4An_#§Èðb/åcðEŒ½³¸çbÚê (ͬc`ä‡p4õBCÆÄ``›ï‚Ï;/¿Ã€lmc=½ó­wðößNÿÙ÷þ-Ì[Œ™ å[N/€9ð1ï⦀Žjªe»½³tquHŽÿ~ªW›xp«ºg!üJ¸aW m*£†. á¹P²Œ.:UtxX¡g¤¯u©4EëŒ\ pS:WJ×d`bÛ ‘<]^‹ˆ§: âJç±X»ÈÃ\uÒøü"àY˜ÍG_GjÓ‘N3„×+¹ .ná<ÈA]è<’óŒ:ˆüb±ïQ°f@Õ?¥ÆreÝÐYñ3ó†=³ÑL ðï;@†g€pd¤•Rf|è;âÚ¡³NuJ쪗c¢‹›;é~ê°÷øâ3‡á’Yj+"!s”YN}VPÅ[y±R57Av…YX©VšÉ4™SaŒ„¯Ê_m@Ÿ ˆ¯šû^«j'oãå¯fÆsâI2'‡”ý“vQø†>eV4Axî ¹¿LL6078E—(oŒ˜ÚŽ™ØH-@Öm ƒór“Aðµñ˜ãwo—~ÛÝ»y;Ϲ×lq"†-²Ÿƒ;?eÂÜFމ¯á´èsó]á|ô©ÝÀùÿ ‹Uý”öwv÷Óε۔wÞ„N–:&U²å[N/ˆËUö ê.ï&§À/) ð_\±ð÷Ó'~’Þ}ÿ/Èж–î~ãp¾kaÆ €J¾Yî§µ^*!-Í( lA^ÑÔ"6æÁgýPâ @4J¼e4 Ó6qSòZÚ'òónèj]Q ~R‰”±eŠÄ`§:Ü(}ðWÅ}¶öW‘p+i{»•67Øm‘FIK›Iq0% ’> –Ö40R/Ì+d›€uÔÎÍ Í"NmBíN©Hפó3öølnÔè2ÉmnH ~ÆXj‚ Ó]°|)þÅÑ1¤}Ãm§ \, Ú6µl5óŸ gÑ!A’ª€,R©`ãG°õfhCÂVN)^°` ØO‰yœ@Ïiv_ýÆ Ì4ýâgÇÔ dð`át£uè°: €&ƒÔ»:3FX&÷Ÿðœ—ÌG¯OÈ!…N1³¨ú7\qÂDWÚe¼×ѹ´Ké&!~‚òö¾Ž}…tzZå]áa³î<‡0 4}Ôýe7K𑬧˜€ Ý_çìû –…d'LUæ=Z_¥=s<>¦‹KèÀÖå‘1}²ï¼ZhìÓ®<¦4ï[·d¢ðçÞ9ÏÊ|A[ÚÙZšÈäxއޫÛÉÆ§Óided~ŽOíHÏdK´^áaÖ­ôâ«o!ùuÿµôÖ÷þ àO(ä Å} %Èh•o_rà‹¢dÞϯQÀEy÷)ò3“ðDz¹,|Uì—eŒÓs~»j“µøMQ`gÕtá I/‚¤×<(²° ü›¨ree.Zæ’Ïþ tHŸ|ÌŠúy¥HÀ[g=ûo“)®JÈ[`¡º@=>&¿ÿðì!=ÏHCPbš ‘Í(ª£sVf  ½^ðŒmºÈ99Ÿe÷õÞQ¶–\ö>žã×÷¸w…hâ¼b1÷;[4Ê€‡SŸ f†‹ÓÑ4;ï5rÐC‚ñ‘=°b^RŒÆÄg ý´ËÇ”Hµ«g¿¢¿‡z¦­€¶ Ò J}}ÆTÄ›F:ò¼´ßë h…>5s47>Š‹ŠRï&Ã?zº{¦ž*c­Ã\5›|`ö}„ùÁÀdjo¦Áã’©ò_ ªãb`ð_N'søóup^±;¿D[ÎqÞ¹,çîqÕÐ2TCʦ÷x~ôÇmÀåéгn¢¯x‹g#=ùä$‚ö˜À§ie»‘ÖïÞ@Äóœp°ÈÙ¯—`Hߤ¥u±ÅPÐÀ¢Z ü­‹g…ÔÀ5²º)‰Ï¹§qýÃQGQ4Mº0úÑ““ôð£G8â­¤ÿáþ7HÇ¥ôчŸ"¥÷ÓÏþö£t9àâàŠ>GD‚k7ñ ,ZØò«˜ªHÅJÆE®«R® ©`Dâ"…2 Ä.—`ÛAêýäƒÇH¦ØÖgM^à29Jƒ:í)xGcöú³ñ+ÚÚƒ×, ÐU[ b\çFà=Øè°R&äy[°§F 5 ˜åÐkK§~±!—òáÞ›aà*QrLsˆ}ZZ!›~IüÒz0›u˜¸IúøçOèßü5†Ð]Éx…ÔºÚð۔ᕞ}¤~%3úcç€Fó šÿö‹¤çEò_G ²µC¨'ô¨S½Ï!ÔÂ'vú¡I~ ïBJfÒ¢dnߥÌ´)ÊTQ±€óhdEä¼@Œ${Cyàû+Œ§ïÌæj3­Q&X©{Ø—!Ô,Eh!÷¨‘“;_`|)6ÁšþËH2̨Þȵ š@d†ÔøÈ¤…ÚXMš$Ó8 %4Ć‚<¾hNŒñÞ .r¬_E»½š¾ÿ‡ÿ:ݼy/½ðò;éå×ÿU0ÉÍ•ÍxV>Ã|Ë)ðES g¾hŠæýBjCb ;¨úÏY@A; ý´õ[^–ESµðIrئÚÀ4­„Ÿi»eÙuÑ hœh¬š<á:V`/ö$úp 叨›üÅ¢>v¦¸È"?2þ<$QBåpH3䮵Žê™Œƒkì+yƒ$D}f¥VíÂö5 TM €‹vh)¼ y‰Ðº¹ñðªPqGn|¾jƒvYTä1Œ§^àö¡Ä™IÝJ®Ž›IŠb.vàYºy3ÀÍ9ñK[÷³g£Iüá:èý*Lœ)gtŠÄF^bó¢_Æ¿iRh` }xÚ{8§¸7@0 fuÀQ–NjBh=u0JøJÙã±Ëˆ´†nÒFDïn‚„ð3Ú¢#Ô„hŠ8êG Èã÷—Ñ„û,ÃÿBÍÏp~Hÿ1/Þ ö¡õ‰w롟һÇÔP0å˜BLÃc\/åÍüG÷07€1@-[å»ä÷‹ßŸï=)IžÙ˜’Ó -䉽¿ÝÜÅùÅÞc>7ÿ“vj6¢'ؤaµZw…ä>[;Øü7 Ñ*ïŒïŽ£Î·œ¿ ä Ào‡®Ïu¯†j]^=Æ“¼“žt¦‡GiZ[KÓWReõZz¤­‡³éî ªÙAº"!Ì'Hã̓Zêt/)÷ÚJßú×ßIU¤ðêd×ü"Ü4f;ÿƺ ¬‹¤qì&áé’éÇ °o+q}ðq!_\œ"¹³è×GéøêIjLkéækx§VºûÒ[Á?9K'$ê^ÒÉ1 ô®©gaŸ.rÊž…ÜôÁ®ü!Õ¼+©Ñ‹}†TJ6¡(üsyÐ@X¿ÞôÐ"P¸^©4†(eh_ …H²<–PmTì³4v(¿à>lúš6œçS½MYcÆ8dÎú*ô1gLÐT( ”åÊÏ€¤S&Çï-¥£àÏGD,§Tâ9?:‰› øÆ-ÜÙo¥ÉF›þ¿œûSªíyÙ!ta„0sHÿÜÛÜý+$ZAâ¿ýÂrÚ½YO-À¿TAŠàç –3“Œ ˜è€ãÐØù@^%m…îá9Ã"qÿGA|Ìó›à]†3ðþÀÞ¤CŽ7ÊB39#dz†ø–$RG· Õø }—á6´ˆ0è`ô;•¼Ç>d?5mÄ1Ÿßá;ØA'M hJàí‚ù“ùP £¨ ¯7”eƒ#‘ùÃ’ö£-0 ‘€‹·¶¶Ò·¿ým*ú]KßûþŸ¥½k÷x_Öy·òÉ—o¿] ä Ào—¾Ïgï¬Êc2ò'<|&¨¥¨XWÓ¨ÒJ}q>3T½EmÌ,¨]²åMÐÝêŒgWBsÎRª§ùé"¬Žú¬ÈbÌf€œZQJw,ôcÀKI¶<«ÂϺip~Ň"ç;jî!c+³’7ɬ¦Ú¶¾m–AòôêV­£¾>.§yêÕbt.‘lÕ)³¸{Oµ%C zR( i;žÁLПO«êê± ЬЧ”.X "±¯|CŠå¯'à_6j²ßKEAF‰¬ðzç´Òº ™ ‹Ù5ª¸3\õË>¹÷ 3³äyOCÜS ¾ó[¿…1j~ÏÄn-4sæØ‡)ºB}mðÿ:€¹A÷°gó &0u溊†¥FUÁµ= ×T"ãu Ô“èäéÍ ÅŒ} %˜Çç@3BþhJ ÌOhh_ÆOs™@Ç­I ÑÒC†'ü‚©bðÜ&rÒÏEhßyö†2NâÚ¬s ú06‡s¯Bx^úÓûØúñ.Ð]Œ[çPN™57N!èG†î˜ç„'ªq;ð Ô°ïïn綠½k8¡^Ç¿R ÓRö0£¯üONßrà·EÙç´_As2¦£óRwðÎq µThï§Q£±Ï î³¶±Ò­tû­{!Ý÷/»éñ{Ÿ¦ñÕEúÛÿëÇ„‰ÕÒæÞ.{lݤ¤­b?6í¼i*7€„zªý'€ÿ`XгákØ|«rÈÆç‡éâéQ8µYõ® é›`ÚÖ§‡¡šÅ`i…Â:ÒêFÑ„4k¡ÂïušH˜,숣S¼Ù•Ü¢d/ c6;Ax„-œYFšÙöåeèšêÝP_£',>$Eá!¤{à(ÏPc.K@:ºq:6¯Ë eñ7€H“ÃŒ q00Í Çz¤Öt 4ŒO% †àevn”öuïOA"ιg‹ßîùâÇvn^î°üS°=…%ÄÂaà¥êß<ÿJ§:0.ã•H\–1„3ÚÕò¾KIÚþãÃ¥šdx¬0\øÀ „Ê‚Âg%@ÚqÔȱ°²^F’¥€!~<[Ç.«``š¶ÎTü’Ú0A‰`>‡H®Äi“âh6‘ùr|3æc•ÂàC`ù.¹Ù‡¿ÍãöEˆI²{ÒÇhãÍF-ˆK|Æ-#ÁɲÏX½?ã0[Ÿ €{7óx[ÃÕøÌB¢§m–—€®~ï¡ãg&R>+44dTýËÞu¢\0ƒÝºórº~르MAŸÌq™wHQ¾åø2)3_&µ¿æ÷šâéßí¤Nï$=9ú&àœs—пÕT_DZis%uýtúð˜Å•RÀÃf¨“[,ª+xÖoÜÙIÿÍÿòß’¯Ÿ~øç?LWä¨ÿÉßþ,Ÿ\„C`ÿ€Æj5mÞmâdVOoüá´ŠsZ•}µÔr-OC<ÌÇ€ðáÇOqФ.!yãÑ^Û"¯ç4ˆ²¢Ç@_=€¹ªrAØ3ÖûXÌÃsæAUvÅ¿º‹³àzýæJô[‹,m¥ôW?x @‚#aÆ>bÂ.ŽWÈläC¨œÒ÷L¬ø~ùrøU[¸p Dª”¾”ÿ3å"Ž™ÁP Ó¬Ñd^ìF(p®oâÂ#{´êpVDM—¬–ÙðEÛZ¢9k1„%ˆ ØF4ÈDZÀG>$]îeDÄ Ï¢ãc9bÕáTÞ»q—Š„„ê'&©a” iŒY¥!ÍGb%ïAbÁ´‚ÿ…EŠ\g"ü&a2z™\©Ä”¶ Ï”ScÙðí‹M6»Òׂ±ñ…`S÷œÏ]P–€·Nmhæ÷Š„æ¹^‘.ú²Ã¼¹–W($ûM Ñ4I´ë£ñéCŸ_ šØ¥õ¼Ëú*Î7êü¿0MŸ=·òƆ“6Òþ_üYºqó.ާo¦›·_Åç¤Ö íXþ>|û’)3_2Á¿Î·SÍ:TÀ§Ç‚ÝWmÎ ä‘9@1¦~`&d}‹Êu,ÏSVû*:ñ2¡UQ³nbpÁ5 ­ŒZFûá×§L_x›_’mO©­! „èá+‹|ÿ¢ƒæ€äC²b¬ùß½mö…=@"øø;+àÓÙ%êR«ä¡˜Üã:>} ñÀ³ß+ßøþ˨œ'iíF9]ž§Ç¤ƒÏŽp´¦S}’ÒÑGg,ªÕ´»¿Ž4¾™VÛ+éÕ—^ ÿê(}öã):CÕAròë{>5¤›¿€0 4îE´Ha%2¨.êky,ò®ìtqÑ7å0ÍÃî/x”t.dá/| éŸ0€’PÒV’Õ MGBqÁA£ŒÍÙ=Ø÷{=ˆîñUÄv§mÙö޹H ØÚÍCò„Yº} š“¬çéJ¨JÛÊÜ}Óåra™’?d°n€ŒÉt¡:Hî'è?yÊsƒië.R 7±—ëÕûÞjº†æãâlœþýÎ(iŒÄ&PoëV  fø_8ÿ¹HÊÍ+ÞŸo1 £~›2†!|%Д¡ûÊ Ò7sÆô0Aû`I”ŸKóeýØ*LFÚ˜P&Çè¹Yi/XKsiyø¢Ö$|!<Èfõ@•N—{ð}]ûР‰måîu“-Hå¬öaŽf‹dH¼K†£J;o oÊs* Î¯ iAËÂ{ò)’ÿ”RÓ¥ÊfZ#®ÿÏþ»ÿ)mÀ¼ü?Àgc š+3ü9¸|Ë)ð;¢@ÎüŽÿu»­ úÕz§šŸÔ¿8å_ÞÃ+ÞÌw³‹+¤|$"VðY•‚5€)ns0•X¬{ä¼Wp}“…zžnvwRw»Î"; N=¾§ÊÕfÎx½sãÈwîªÒã&Ç÷?´¬øwEüÿ´è¢%p7o€ºumä"ů.½áÌÅõÏ×fÅ;AŸöJÄþËTÈ,üœ3œÎø÷’ ‰¸Vïuád¥j¹ s»²}Ð>+H$ùŸ}/Þ±Äù›½ØäÇCa·}ø[æ¢_0wks·ê ©ýâ|\-“ãd1í"ôŽí“3v™1ô—Ý”¡ ‚» €s´÷z³˜6Éâ·ê‰eãôÞ4˜î/ƒ¥†$âܽƒýº£O÷ÎѱưZ€ª|ýdGœ‹Ž†Uëèß‘M/¤~È̘d\œ{ÖOôÅý—}ú\­/“Œ‡7rãÙÐ{Ì׸|ÿÉsMXcåL4#“_{}7½ôê71‘ìRùðàO¸D¾åø P g¾á÷}c<¼­úwÙ¹HOž €Ssëz*ÃCÒë’1oˆäÞ‘ã'ÒÑ~zÿ! 4öy@F(áæRvm“0·fÚFÊ"ÑvBÇ„ó¹üŸ<„ñ8ÂæDÝyLGOÏCÃ` ÞªyíYÌ ãã–©„„6_Ôºb@> MD2x ÌòD ‚jfƒvõhBÕËx9A»w›8&ž®HÊ£ öö1ÒhÆtp3AÏ-Lìí“3ŒÃñ`g§ïJf°e#>ü±î<Œ·GÒU 3¹·êkÿg^¨#d¼O¤Ð•°Ù-RTúòAt€æžÿç³tÿégäˆaQ¼ñ­Ô,VÓåà>¶è+ªâ=A%˜Š«EœÄXÉÊ3cuwqŸó±Òáý Ú$?:(¦i} ©šv;8UÝ|q'Âï®Ãâ`uð)Ñdþ{òÉyzøþ à3M?:ûPÓntÎâ¼q«™øTûZš—e[®ê}ú5ǹs€ƒÅ‚f€3¤ˆ}ì0ü(é£hTÕéÛSæ&h*êø¶Ž#wO…'c ¦Ä!áªÊψ±¼{¾:žâ€cµÀÕð½L(ÏL^ŸIÄÔ΀¦!AÓ ZS"×Ñ>¬à€¦JÛÐ;ÇÔíªtdý%Ôb,cÔg -Œ¡‹‚a§3"ƒ#Õ±ñß¼»É¾ùÖfdò»ýj3µpîQÿ`4‚;$ŒrP ÊÚ2,W/Ýõ(ƒšæ¬$_A}‡1ˆy3¦9t‘sÏ@n~;~+.Æ\b õ¦-m<1és¤kD.Lùmß° A£%9¥¥È_b,>W°îKr 0ôð=‘ÙY#v›ÐJ™ýÔ8˜üHfôϸ`ªL/lÁú7c;½ðy'¿Mn†;鯗ÒõoÿÇþõÍ›hˆòå6•ÿùÊP #¿2â÷w ýÁ%iaÒy÷Í7Np€XXü^\͵<Çqä#/‰÷H ŒíŸµ¡ðè]x‹ø°Ú²(k.@úe¥ô¸d¸ dS\½ÍÕ?äÍ´§“›6tÎ66›i~Á ÞX˪Ð=%ö_á2@€H[FšŒp¾ µ€ÂAþ éœcàÅâO`mœsL!¥rÊ".‚²vxÁØsJè2 ™-ž<ÆÓè›Ì:ÈÌ0“òFsPIÉSð³o(t˜¤F‰Üïò·ÁÀ8Ò.ç¼O6 ¾óÕOˆ¹‹ïšÎzzêÓ=‘$F’±mLÝ+mÙ¶GoÜg%”¡9çe–V==ø›h®ÝhÓP'ŸAæÁK.íß‚~¯Ç³`þΡŒŠÜü zÔÞsíöÚÉcÆ>WÜ98:ÒÑ0´ü,0¨ 1Àî`±`pÞ9 ÜA†Åü³¹H Çï5|ù±óÛç;çlå~™+™›Úƒ@ºôò¸ÅŸ¼‘ZM$:ñ öö¯Dïsvž2qo;ŠH;æÑE“!ÃUo¬¦y™÷öîâ'ñI~nA»L >.ñ`½0ßr |u(3_gñ{;’GGï§w?þA:í÷Ò)ŽOsÂò*ÕfÄ6ßzíåpk¥;„Y]¥ÓÞqúéãŸ%€‡>ªg½ºUÕ–‹¤îe¡µjð61åž8?=ìñÀå|>XV¸‡ÎmÍF ›w-ÝÞÛJ·Û¦c½ºì¥ÿíý+$Ú~‘ÉeonµhõÖÏ’¿¸¸OpÔ '>Lª±]ä3û0·ÉXíÃîÏ÷ˆÿ†‘1Ü­oZ?±&P˜¡r.ð&j^cîØ®•1_J¦zž1Íkh4=€ö&þ1æ[M‚×E:”å4 ú7¶<À°vo4y` çõ?èÆ§Ò±ªüsÕ/â¥7ô?üì4lÖWWJ»|¸N©Wó„Ì•Béö9z¯Ýi»¿€[wÚA›1"­÷›a“pÍÁÉ(>œ¦º¡î—~Æý·ÖOž™L†LN‚I(9ìàÆç÷ÉP8…is^KÀ,\í’¸¢õ€YòŠ<_#:ŠèþÍ×ožë‚I°ïØhÚó]Õ¿Gejöƒ9 þ:rG"Sˆlø­ÐelAoÚë¼h² ­ºç÷MTäw.:OÚi³™ÑÇ4÷uQo4 rtB ëz5½ýÖ[‘Ùï­o}?}çþ”w÷sm'{Æ1—o9¾:È€¯Î³ø½É Þ…tLhÑïH›ø°ìºôNBÌbiaЍqPCÈj¾À6c—o@,Ô¾J\ “vmmÿ‚ˆöx*E5î§Z¶ˆñÝ%ÜVª‚EMÈÅ¿HÈ;ÛjSÐd Öþñýò^í ®ˆhG‹×‡Äh?¢žcsŒöìoØv¹yŠ-.g¬ªØýdyPÁ3¥G×FJ!E†DÉ®±K·ØÛ†>ƒ¯ŒnvþÌ}ý)â° wSRvÞB©54(ÐÃûê› êÜÏHç6ˆ¡¶Â>|L3 "½7VÕÔ˜À‡?ìü:û‘t1¦¬ÝÞþc8\Z†EŸŽ#úŠ?އ¶Jùþ§Ï8&cÀ1@%md¤ ã¡­ÇB#À^MÌ‚b¹ÏØMu~&‘s­ýÚ~1™5¢xNM2Ýû¼ø•1ph@¸—ü†Ï§Œ׆/« Y}%â±s\æ"c8¼a )ÎÅíìyÑ¿E¨VÛµþ7¶öÓæö^þ[0 +¡òdCŸ*ºÊÿäøÊPàÿgïÍž,I²û<ϻ瞵dUuWïûì ¶`Àˆ„IizУÌô ÉL§^$Ó"iF£Š3š™^ªkËõî7õ}?È®i ô —ªîðê¸ởȎß9Çï€çæU¼Xñùøä7ÙózuRl“Zp¬©gœóù.X‹×óÞdç^ûP-±îßf}™­~·vVe‡ÅþK@yÍúð–[9½OׯÙ¾pŒPïkð6Eí¿äV´W™‚U$G¥/u¹½rÎá@ã­iõÜ>ÞÇb½”?ý—of Ûÿù¿ý¼|ÊÉ~;œŠ7ÀÂГùnÜä`Æ6êG_ñ™ ˜nÈÚ¿@À¶@aNؘ=çgÐ¥°y1Æ#Ÿ.1+HÂ÷ïLÊùY¯|òkìP»^|ˆ@‹{#ÙWƒÃ Zœ!ð‚z”§¯`LàŠ{ž *2}€r¹„rL*ÙÏq©ëµÀ˜îé)ÚTë¿þ Œ™ŒHEÎrÈÁG7‡åˆø­¢ôïÞßÅZÆ ÷]žÁmÞiï0fíŒU‡·B¯‹ó Û21À(Âü<9‘.¼ÏzP[Aá¶M† ×%¢Ý†àŸ·ú{B¡4>ÁæÄà6?ûòïçνWËýÙß”[Ç/—þäg0/¡ `ù5´,IóØEž# t Àsô2^¤¡ø‰Ô¿ÿðÙŒkÙH—|,ý`®ø€o ~ÈdA¦§»Z¹«PzS8T"Tên"­FUœ±)\|KÍ hRmuzÚ à_@•¬R¿ ºsÀ‰j¬kí”òªåMik|(Yf HÑi¶¼S­îŠ÷„ú˜"ÍO-î€ê¨BmK¶–ÚUÊ^ö~$JsÅQß­á½ÁúÍÕ–mÓ·ùJñž?°fÜÇég¥æ„Ø-y^J»ni“üÕ ¨êWju¾ªúÉ.N—8\iÏ5ÿ#,Þ‘ú¯¢Y¡'ÆãˆÌŽ[8%ºÚ™ V3VžyÍ´3iP×õ‰AeÁ_?+èìô¼O¾cm4#j¶’AòP&1îðo"Ëó´%¸ûjü›Q3$èWø'Ï4š0NÎx?ý¨‰°/™Kû¸oÄåë/H¨Ào¹:÷ü)PžGÞ£éÎKF m^ý&ýÞÞr||à%œý£ò¿Åû‡©íTþ•¨ÝïsMŽx®_Ïó98?„^ó>NQçeÊ o3Žj½Ä@ìLß©|TY¾â#8[–-òÆHY#>¢ËÅ%F¬óc5?cÍÏGÀ²c@`³eÏðùÓâU˜ ]û5Æ|~äÙéΙ0R½±»Üé¶aûÝ“ |ð¾É)tëÕ¤ü䧯–×ßž–GNË/~~Â5h*XkÞÞaùe¶¸a‚¿Í:µÖýàjÛJ󀓴?ƒªdù˜.0 Ôª®E M×mî9 ÍÛ ÷Y>g}x ­Ç{ƒO>ÄÉ à³ÍÞr™„àžsg»™Nˆì+jtÚÜ  r eUE/ØZ©•½ÖúsÈ€§S™šá4BA?;hÏ­y?à=ð"¶xÛãý#ÖéGåÆTÖ·™3'1ß¹Dó†E?c—¡s'„ +{ºŸ¢.»Œ`(Ü=p~²ÀÔ˜³ýÐà„añ)«QŸ'ûY?¨ 3ÖËZy±øgFaÔ¡@7‰è ð»…PžhËSŒ„uhº¿ƒ¤#uÅ®%ú=Œ,`^ìB¦@¦Æ%—Œ°6>9sGƒFŠR€¿ ¾‰m†žÕNXOú ðtϼ*à/dNxÏÑòð7èƒ>dBîàäG#Ò;/½‰t¿_Þ}ÿOËëoý„­~wËko|?Ž}v±r•A°×.tx(Ð1/Â[z.Ç ¢Æ_!y{»†Sz”ËirQ>‚ü·A°fÝ?d>þnõâCMÕÁ~õˆ”ºxHú¸£SšÁLäØX êÀÆ|˜«E¼n>Û|ìÝ)àö.¾Óô¸– L·¼#¤3¿î7nï îísrßy¹8e,|ìõ&¨“!=áYwë*»Å¹HlLTúm¢ FYófÜÞ{jiÆÂ6ÕÛŸ.yù_ „²Æ®Íƒ« .gÈp¸¿\µøÆešÉ•Iж\¿ƒ fúUš·}OœÁ,|·á Š'œBè¿Ú­ØõxS?÷£ŒÄÄùGœŸpt½%óäÚ?ã`lsÞƒR²Ú…%}8'Ç,3²jPR-ƒL…%Ë j!Z͇t0();O54k'E‹wÍ}xo=Ûʉ~$§¦nêSÌ¿i,Ã$)”Øy Ø'ÍÆÍ [&пß©iÒäâRZ à2,Í áØg§‚ÚçêkV/e›yŸ2x¤WM¼7ÿÆèÛƒ–<¥ððà€e$=O¾QÞ~÷Gl»¼s¤Wè£n ͰºŸŽ/:àyQÏÏ0Q1¯‘þÎYÝå(ÕZ¶QðJú)ŸU ôY‰åË<àpÀ^yð|†1à²ìûQeýz‰Ô¼À‰Ÿy0“-}||ý@GJ#ß5n·YõÑc‹}ö‚WñÃÏG_¬J?é0K| â–~‹3¤×Ë3˜:é;ò`ÁÙ¼ "”Ð\4,Xži>ÌŒúï@˜±Ö¢9œgɼu„s…ô{îYÏß*''ËòKøà­†@­Á®'37ªJß^mO£Ç4Q]ÄNBà‡~´ Gñ «Ûµ–òŒùõwn#ÉX—¿,§'xBT?Cá¡=ǯî!í³îÌѼGãÒÚ}ýèñ *úü#ÎvKúTӠžcYÍ¡1óYºdxN/°Ó8Eãƒïó ny”Ž–ôHfçcYA<îøƒƒyI‚‰pZþKOÁ_&´,“P]¾H |&ç’9&x¢Ë¨…7 Œ^ Ë›‚ýÑÆ!¾ ‡|Œ2‡Jô•ñÐÕ°t<ÇÂ_6Á% i öÇ]Ch‰éGú°ó¬õ¿ü6Z£½ò£ö/`¤î•û¯~Pqv5ã1†uªÝoG‰ð"½­ç`¬~(Wøë_ÁÌùXÎíQk€?h|ˆcU÷€r=‚•¯*n~§lôpž­Õè‹uZ7Dê?Dzm  l!EiÅoœ]BX`v üùð»C@i/~ãý¨çÈ]C¼QÈ{Ë©XíÀÝýÔàœ"8:(Ç·¶ËƒÏË¿ù×Oc,§ÒÝÃsv°†/ìØþ(Šu9~Af ÐQ’ÓL׊ApSj]èe 5Êã®kׂÙ[ÝŠv‰»â9@E“ñcà‰v»Þ¹¡Qõ}–ðUÕ~Æ>{UÓ—Ÿ)ÑÆ}YÎSý‹’í„{ùÛìzØ.ýêZ†EPÞ{rßMÜöî±+`‚o€þVû Á”Ôc.j)BÇL÷ëò‚†}4ë /•®y5s$ëKNÊ« k=µÒf†Ée¿ÄdÕxk;áZw›•~Ìe)ì£É˳åL'Ò&Ã÷°ƒôaY*rk ª|€¨`xÊr‰c¾€ÆÒìÃÆNïÓkàfG cߣމdu–4U«B_22 ;¼“œø‡¶@GD¾UtD07;¬ñ¿[ööo”÷~øWæó:ïîMÀ!cóïÄ¿Ž.txñ(Ð1/Þ;ûFG,Èz(Ž.ngM°s>¦®ý_r­<Á…5å-@MÁh…$ð@ͬˆ×ã‹;b¡—Op„-¿ÜÙÇ·^0ík®&¡"@æáJÉß †œ¬ÖgÙ¡ïÚ2È2Ô›,_ïxm8P‘Çè¬×Ô_Sn(o³µmßµïۘø\‚AN_²£/z{%¾ô²€À¯B\Âï¼À¥¯ÄÚãžfrÀ¦Ù¡+[«V7øÚÈ8è±p ² @i†µ{˜ ÄÒº•e‡CîíJèÑf#Õ« qGƒ>êñr¸3)wîßÀ[ߤx6xoœ"hKR~¤µ÷ÑNð÷áRŽz€jY— dŽ|}IäXaîe”rÑ.Š,ŸXÏŽ|×GüM¸œ4†‘‰qà˜õ~Î#޶ËÁ»ûí•WÞü>Gåðèn–ÌëÅ`¤¬Íu¡£À FŽxÁ^Ø7=\U¦Oñû?G‚2^ËGœ²÷«àvöq™ê½¼q¶¼÷‹sÁ‚g¤U—*†,CèñíøÖ üÅŸÝ‘Øÿþ螘íˆ,î÷Ùw÷Þ6Æb¬Ót‡g=€X(”5XÜ&Ïòñ ç÷_p¢È àu‹š{áW€eU‘WàÚæ4½û¯lÇYÏN”“Áùè!'ÆXÝ6¸à VËÃ`Lzµ½gá¬G×ÅڌВŒ‡€ÓÎ-–òÁ¾FÞ°üò'åÃ_yâ! Æ¡=ÛxñÛ¾9Ư?Ù’»&±ŒàøäôêO¬ó~(-y ¤è€ô Ô$¨¡=8Ã`SuÀÙ“i¹ä~ú\ðÏ–8Æ®‚à tÕÀ2GÚ–qº‚ùrq#’¿Ì’ Ãz1ÃË’Í{­Ë½ žt©E¨mdžä½TpèÆ÷É)4N=þ.èó–»ø[S#”õ"™%—X 0Ã@ð׿j˜&.]p½ýšÆ ,©„c is£p”­}þ³‰vå°|ð£¿Èö¾Ý½C˜„êJš‘Ó{: ¼¸ȧàÅ~7ò¯›‚Ú„ª4ô—íx|½=JwˆøÕ㣯4¬ÛÞ {Õ•÷#Jî~d‘Þô¯! [ýüØ+¡åÄ=ÚV©î§UÅ;¶È—ø¸ôrg.ß{bÛ¥4h,(Í"È} 0nƒ³]?üÛJÄô»‹„,eT™³&>½`í=þªêy ¨¹ö.øÇ7­XzȘE(þ˺3H”ífj¸4¦°ò>,#ÓàeçªAšÿV.ÈgUÑUãÐhÂ8·q63bÜ#4c/¼Ììï¢UÀùíéy!ˆ3Þï@÷½^YžVå-ârÉyÙ¯ô3m…&Ä­y+ì\ÃO²ëòëYÕ傸úgÙ£ž}à|xÍØÓ¢ÍѶȭÆ!óõ‘t¹hKfŠû¤…ó!½ &ZÖP»o#Ê7ã ¾‰^¶ÁC˜”úµò×XO{ µ@¦)ÑˤdɆ²L“|+ÉÀÁrEÃÃÏLl"ç ÜÂÿÃ]öô¿\nßyàç>7Y pûh þöÜ…Ž/6:àÅ~_Ûè Õå3ÖöÍ }çh>:?+Hº#?yãÇßcûiyòŸ~¥Í'#Q®,Ñnèëû%êösì\,ÆHµ¢÷°šcpöéSײœœ¦ŠµÏ¡AÀ;kÀc®=ìá,H¶Bµ´_sÁ™6âF–z³švfiaɉ„ªUWçœâÏ~z/êàŸÿü[éÐjPæÿ§BØÜÂ^@fFã6$šl¦¢%þAª€’àØ \‘RÉáÁýójfHʪü]ÇŸ£õ0- Ê8rä0 :FR×Ò|Ìö@顤¿Ïî…*Ò»†~p?\f&hG3÷nßd\½òÿí/Ë“‡çåûmsî‚h3Tÿ/¦nÔâ_µ¶K+0o¼!úŠûHÕHþÙ“ïø¡Wh$ì0¼&ç6§‡ó§Sìd 1ã²M%|_C¤{¹0ÊÛƒ.ŽW.ýaø|^Ö ýå¹¹d ¢m±Cþ3XÖñ¸ëÁU$Ï"¸@q"¸hCA·Ç>:b’!ѧ¿û7ëRÊ)¶ 2h¶ÃŸ # ´2†ÿW­ *ýW_›m}÷Ê[ï}¿|ðƒ?€¹:(/½ú=˜Žõåßv¹#•ºŸŽß t À·à%~-Sà£ìimKPà þS$ës«_bÀ7ÑÈlÿ {Å—³î`õÿd}ßm5|½·"½  èRÀC+ùÖ?û Ášõå R°çÌ ØJ”Àéºýªm¥Þ+TÚˆÚXèÏË¿ÿ7øØóAgµºÏZ«À¯5ù¶R6͈¸ȇ¾cáÁ:žê§+€õæüIN#%WbÝÉÆ8D, Ô­ò1G¼Ê\ÜfýÖá¸<Ú•Ç/<§Î×ç)~Ês€“½èA¨JâHË€Ì`¼©ø¾'[`óGëz™Uúûl{p›áÁMÀð߻Ͷ<â>̆^ ¯('†Ê,‘ÞWÄ‘þa†Ð@°R"ƒs%ƒÂخФ<øè¢üÿ餜>š³BñªqoÛ‡Xj0¦hΘR[ ädŒk´¹Å{’©b;ïŒsƒƒ¦ ¼{)—',¢þŸi'qmŽa<ôH'Mh+›t€Ùª4§6®Ð…|ƒ›€vŽú?‡JÅ.­·Ù ÆrŠñÿ¬ }¹·Òd=³ž/¾Æ`\}QD€Tßê.W)·ç>üÑ"ûÝÝ÷ï)z D­ÇGݳ…Ü-àš¶ÒŸŸeàXàåƒ|™ÀC«q²èªJãJº2JÈ2f/œ #ÙG’ÖyÐ 5±ÇéÊ0v‘žA]ìtZòCÚ«Gð"åÓ\Ë0Ä”S Wê••8]Çßg[¢÷Gh Ü«_”ò¡…žè¬¿¦ò NGÍÆé2ñ±~³&ßC–$„*}9‹¤s„ŒÁ2´Éœh¤20Ù^—IpæAr@¿,eÈ@QÅÖè2s0:2Q.¨jP;9/ªòŸDæÙf¹¡\‚iæsYÅ:Þ0OÇ+ ƒ±¡¾š5µ,»xªî5Ä>”’2 ¾O.û#¨æWëâClRhWCÀüݨíplÒƒÓÁp¯ÜýÍü½ñö»Y` &mu?¾Íè€oóÛýæ¦OÿRæÙâ¤|rùq9C¥ý«ÿüK´ø|læ8ëÛó韽^»“Cäk$ëÍ@›sãqNã°í]®íu#{ï¶±.gËÚl>àøÈ³s`… þø`’}ÙÓ“'|¤ý¼ó'Šæ‚ÛöFÃ*_v`ˆ·Ç@?ê €=>ì‚×}ðÖ (àÃ䃯Šœ]ÁDi×2xÒ³ýÐçOh3`t.]»ÌÙ ç>|¸Š€‰+ „ú‚PâÆ[HãâE¤m=z”êñê|×òcȇ@MÀøˆóá)?ßfb¢<êéAO?üK¬éÅe³Û@¸zRÊ~z¶U~~ú ÌÎ8ø‡mŒsvTèš7· =dŽæOv0".=Tõ½4Ðm›×¨'=;ã´e\sÁ(ÌÙhžÒ·ÏçªÃ ΨËI”‰ƒK¸‚+Û8nêèªW̓>¬èú™¼Å,Ï#YÐä46ÜCÆZÄpw Ø…KÒAU>^•3þ]Ü?{°“}œ5€ÜÝ ³â® †-‘K*2:Ry°ÀmòK'7vo–WïÞŒÄÿ½?þ+–]Ë{ßûiâÉöíÚ6t¡£Àw€ü/Ó…ŽeÀŽóž‹åiy8ý”SÑfåã_?ÊÚê1>ѵH_áï=;ÜPÜc¸Dݯ§:O½Óó߆­{TÒC¬ë'€ýŽëù‚ €Ò;ÅâF+ôÛ8«Qÿë`*4žÅÉ®!„â´§, ÂP(0ml)Íóß@­¾À×=Ÿý  ò±' lÃÙêgÝÓËÌh(w Ó0ð=½o1ëEµ?ƒépÇ€UU¥+ù°]°½$QUøcœÎètg°»²CY$óHþäí2¥ý kû;XôÛ†[ùœ[ê#¹ ìJ°A|¥^˜–9s7iUÙë~WÉÛ–¶H‹PRàô šŒãÜoÃÖÓöB)z`ËìÂtóÒ÷BûÒÈÓ 222úñ_0w/ÚÈ$`ë ¾xS/·tË&ýºT‘† ­­„‰ˆÆA-uIuNql>W`•ù³©#ˆÌLC pëÀÉñ;O·tʸCðæD‡EÛd¤q#ó;9©L‘ €õþÙÞÎDÓãqb¾S¶7jgòòíÃòî[o•Û÷ß,þ/þ;Ú:ÀàòÕ,7¹½¯©Ý…ï :à»ò¦y*yMg°ó <¾x\>ùôS ÿ8؆3•Ðr¬+z(åâãk¾Å¨VÝÊÖÏÖ2÷˜/Ö.g…†àÐ\TëkÌwåzµÒ/j ßbÅÓv"ùS„ÜÀ%,ðq/Ú ..õkÜå±Á}@»§¤.þÙ&ñ pX§4 d¦_Ç¥$ºf­[[^b$G¢Ò®eg×*nË4UËÔaŒ[ˆ®}$yÈŽ¥û>kð±Þܨñû¨w+àŽðŒgÙh`úйp2#žØçX´à¿hJsaD”¸ðÐFÚRǹç=¤c—B$Ö%i3üÌui›ò””!"Ûe¯ßч̕€×,]{oŸnÉtžú˜”Òb ýL³žãñ Õÿ¦…¢“œš=MÔø?ü±³Ôݮ˄P"Àì½Ë>ZðÃs$=-š±X64ŠdkŸóñä¾öÐÇ¢ª_úÅm0emÓuÛ÷’=Œ=ÄgûÎÚ£Ýrÿ­÷Ëëïý¸²Ö¿tÌNŒì¶¡[ÕæÔλߎß t Àwã=ÿ^³Ô'ýÇ>*ÿñ—ÿßúOÊ¿ýÛÿ­XË­»HÀHþzù4´Ü¿rŸ8ÿæ3$~DÌÔÜJd3@Vp:Á¨îäc¶[.ïÜæ6ÑJ7¶{‡|ÉÑOF“ØÜ{i€Ú”‡lo›³ìpµ\”KTô¸Ð)çŸ"Í#m hbB[ð |î³`52æ‡3úÓàO-¿[ñd ¢äVìV³ ´És Õ(«Q_l 0PMéVëü½OÏãž]ª›ûžê0áѸr#£0ñ‘†ø)жÆzŽÁX‡.*#B ÙÒ~@±ºÅð&Æ{Ö1í967égÁ#†¶¶»Ô¯=©v1«p é6® ÙÂ÷ýïÿ)»>^åTÄ?-ïüðg0n ’.Ñt4Õ…ŽßE tùßÅ·þ˜ó•ªwt§ú³ôD?>Õ>¨%1|ÿëžWPSÍï~r‘ÌgÏ´ZW¬Jx^Jm2ÄÎ-$NÁÚÿz Á¹Nlüúo¡%Qƒ¾Ù•ðT[ë:€¬€3øÀ* lˆzöZð_؈XrÍ}¾×l#2ÄØÎ€^lÊ6CoˆÖù‚„@®¯‚º7O€J²¨š«FÆä ZŒÃ<êU#9ë3wú’Ò¦ ë8êžw¥mè}¢uˆ4^ÎñÇ"Ÿòs$ýÊ Á`½]uý°V³"Hû Á,çSOÉ]f'ʊ¼!@š±YŽa…F´å%|—ÂüØ€ÐL!ò•ᕾ5hC˜ Û1Á˜*{Cí#ŒõˆÄ^Ã22Tµ•üÙxëD›À«ªÚ&—–ØyØ!½I#5(2&™*ãa¿¼¢æªRÿfrgï8.|oÝ}¥Ü¾ûZ¹¡•?’ ÖîBGï.Úïåw—ÝÌÿ€ÖýÏ0›–ÇÆ¿r»mî”[¯¿w²ÿχÄ+œ«ü’5èsÖfב¼<ûýüô ÐH¦§¬±×ýþ¾äýÞ(ëÆ¼-¸Þ1v •ÅåNÖØøYWl|Èzoã¹3¶žaÈÀè ÜPl§Ò’5rÕéžý¬GåNF»!¨ŸãÒÖ] ¤ø%±*x9Vv_Ü=HH&ÁõìjÜp‰ƒ%µØ4hA¨Á›–ðóS´,ÿiV—'°™p;^N¤M÷Í{I$AÓùj\)S"Ýb, qµSÐ.`‚}C EyÊ®àÄÔÌXÞ£ #ÊÙ–€CI òªüÕø.¥FH )Ã8Âä1§pÄ¡¥4¤ô¢¾Úœí‰.YÄ! 7û@D‡ûöøÑ ÑßöÎÒý`¿üàþºÞ¸SÞ|çñã'kþ™|ÆÑýtønS c¾ÛïÿwÏT¨ÖÿxîC›ào~‚Ô¿?>.S$Ä_ã€Eöò˜½á³)Ûÿø'¨èÖw…ù¼ö‹je ¸%¥Ã¨û³qyNñ£k@Sƒ0Õíq¦8®[Ã4ÀT™ Þ©â½dlÇj,+Á û: qÂ{å\qc 2 Z© 楒¸eÞpFäÒQM„‚Ì€q\¡F=§‡ñYrð÷ÒP¦`ÈÖÅ,–± ÀȬïEþ#ÎV|š19.AΓën@w‰…¾Vî3è(ð{îÀ¢cA^¹.””U¿;&µÄ庮Îj?âoTê2B\S4‚¤íدnŽ5È[cǰbN‘Ö޳&êÄß7´ÑQ’sÓ¡ŽÏÒG›b5†¿—_29œÖöÔ¤ È54Lc”ú¢»ã«/Á1UÁ,-cÈn÷eÓB¸çëŸR—rìY·¿Jÿ»¬ÿhœ©Z?cÆš²Ì–¾WÊ˯¾Åÿ½rüÒÛdÞ¨Cë~; t: ûCø- ø‘ví¾DÊGŸ#åyÔo=ÓÃîy‘×u™ëѾ§O8tçi)·Yïç >Íeyq†ä¿(§Ÿ> Èá*⃭•r±~W0+>ðî4ÓйFv@—h'è åèiñN5pö÷#©ëp&Ð0S0ŒÄ(^Ȉ»/~ìàðE <”ž¢*íº”ðÓ¶ûüe4 ŒOM_ò­Ïز@›ú ¨P:@/$s¥u®Ï€<ñÐ̬n‚ap°“ð¼zþŒÃ“T»ô›s$ ï\ƒ×ÈÎ%¤>ÿg ’:ö˜'x»“ÉØa[á„-cƼ‹&D§±ÀUï”#„/Ï=ŽY:‚ÒAÚvv¶=8» ŽÅuYE ¬Ò:ÀÊØ¥ã5}ŽÍÍ qK}cÊG†èy/­Kó :zWik éùe&¤›eùßšw½ŸF¤öæ˜](j—iдjyHåoGoLJj–sePŽ_~/ŠûüòûåÆÝ·²§ÿÞ+ïÇ¥ïˆå€.tè(ðÛè€ß¦G÷”Ï0ûlß»\žÒ€ÌÕ.e|Ó÷ùàÎË _øÓ³‹ròà)`öP9˜P|ý_>eû{ñø©c@Ü©ØMÁ–ptÇ ѵ°°/€hå-F {¨ îž?À · Ú¿õ½¾ÒuBC9¤utïY¯”î×É:=¸äØÖ†Y0ca/`»öÀÌZ ðÎß±4ÿ|¤ý> éú¿±F‚b¶í \´ÓØ3f{ŽÃEïDÖ5Iðª)ÑøyÛðDZÈÀøš“ñùt›tïͯA:S†q:}×õ¹ £ã’Œ/k.—5–20H±i@µâØïÞÀK!ïM£Ô—_ǺÿÖ+åÍ÷ÿ¤¼úöOÊ„mª;HýõØÞ¦Ë.ê(ÐQàšpMŠîF T) ‰ÝñÜ®_k¥ht¬KÀµôÉî6ÆuKöµ€Ñòƒ$ía;kôÕH·k6¸»Vìö² H‘µwê r:¹Ù ½E~䣯ôé*¯»É”¨]»Š^‘½#É[£APv„n ”Œ• S™j»—\„Ê=Œ†êa×¶#YRÑr®Y»¼á¿ìÕ:è{À] J™,‘z©Ÿ¡0ǽBUïX¶¶FigÕsŸëÔ"YPÈ|•úU½O‘ò/¹h¤’î.L“ I\ÎR³WŸ±³3-køÛ¬s»ƒxD!=9Xi«åsŒ]÷Ïxa]”è'&F"fŽÒHu½aŒç$ •ÖÕåʰ¹w¹ õhVR3>â¨DÁЊtÛö}KKËzß¶™˜ãgƒõ}e¦CN«QÏ_Ò €Må=Y"Éüï2†ýøCÆ®O9½ÜÒí—_bý7jþƒ›ù܆išðÞ´íøüÒU÷ÓQ £è€îÏàš~œUÿ/‘ÌOWçåßþWHÐe|ÀÖsNësi9~õnÙçПùòQ¹8»…·¿ËÓO>%~Rþòc€Ä:M N£8‘i£ó¬×¯¢+¶k©$ÖøKÐÏz/hà m‡æ›>ªln@§5â̈ ƒÒ€›Ù®—“õ·‚Vÿâ‚(¢æ€xÂ8T[Aެk“ÌJqpÛ½iÍ@×°mÅáFO8 €#ÇHÝÖÙÃëœ{ú‡ ôŠeˆ•š ÊWG@¼×Zâ1æsÀ]¿úªýW0A.5¸¦Ÿµw¤rÕÿÒ^pÚ*÷_©'ôŒòz T=ïø=+A)]§7j20®÷ïë P#ÅÁK·ÊŸý·ÿ+ÛHï–7?ø+âcÊj PGÕ1!q÷ÓQàwR c~'Y¾›‰ñ÷ÏúÙzOsb¨râÈ£ä LæGë°è©sºœ–ûÔYcø§U¼Àî7\0PR4üÖg=œ›j­Î‡½€P[,á’!Èå÷¨ßq.íÈšÀ½€P€ÌªÜÄqŽíÛ …Ü*GC&ZX€ÞhûJ-óRE {I¦CD)ÚâCʽ‘êYo·æ ЫÚb£ÂI·lKÀ-Ä‚·“•aðø¿N­ÂÉ>j~¤Ù!¼ˆîƒ£m€‘xí+ç- åp·€m»õRÚ;ÈhD¸U›:ÐSú !ò“vœOˆcœ÷@ù Kb’^ËK—ë4³H6çÙ«)QË=ókúçóZ ¶¾yY2±o$®qòëû­¡ÒÂ틆¸ø•^øžìß*“ƒ[ø‘8Fu‹¿Ç]©n­¿Ò­ûí(ðS cþa}7JðÁ=Ÿ–¿}ðïYwŸ•§ì­¶öq®²[vù¨®A½ó)NyÐ)ŸÌã_}…Wµw‘ªQƒo]„—åÑG¿,ÿzÃöÁ)ƃX¦€{Ò>ñNqD³ÄHmÅÚ·>ÿUÑâßp½ëÑØbZõYw½wwÿù|üWˆö|ó_ ýŸ}ê» X&8‰ÁžjhWÑSI̲4!Gáá: 2L‰·Bÿí l Öå£à0 >–‰\&¨Ü…ª¸É%ÖqÊÝmhç,]ŒØa'r,„ g\¹î@ûzA” R–™d-¿n{œè%°a,×ÇC4:ß‘9µSppšà ê+–b GWvæFãCË0eçar‚Àæ F¦%F"e)O èe猑Ë ô¦A9,ûͱ~Èpo#vD¢ÙcæÖöIjÆeîózÈÔ¾C𷜱L¡!ÍÐHM¯1POÌ¿‡/]]8ï>@IDAT>’aºy[«w„p "ÜÒñ·Êÿìæ`¥[åÝŸü׬÷wà/]»ÐQà‹P c¾µ¾¥e«ô È æ½Äúÿ’Íç«þ>Ûõ”ܽø(óÅ^à‰G§@KÖ •l·<Ç~ˆúZé•õÖËý2š`}‡}À€~À£(òáçó®JWt =¼´æƒ²ÊPâ)‚u@"¤+%¶@wÃ"HÚ´<÷€F„e ƒT‡åé…tA0QÐÔñUƱý¬WÐÏv„?52 éÀ6h^t˜{ѤUZF ·½æÚà™P@Ë}µ&Î9|qÚ„2­só„Æv>20U[@Œ·¿0Äþgì0Ïe¾\‰¡#uPL¤Œt³O_˜ªþ—{³Êï³Kµ€Å͵¢mƒÏÔËä­_¯$zOB.¬F?–a8IOµÚ„%H“&Ÿ%ä¶é.¤nêZ/u›¼ví_&RɈc£Ç¸ïÝæŸ½Ã;‘ü'Û{,Ó°TՅ޾:à ‘ëÛYø|z†tVœ?(ûño°ü_—ƒ;û¨Y'e:@jßzLÚ´<ºü„õ÷Yù蓟Ç"{ÃmNÿÛÓM.X|£Ü|ùüÓŸr~üC$¹ºd h±\[¶9Ë}©§9×Ç´Ù LȱA"¾BBÖÂ|¡ aˆT,\œs`x§ÚÛ9˜öÍ«Š'Ï5}Ae…Ú}ÉÉ~"n<Ô,Oú0\Ó&Ç‘¬Œ (ûC®± ñ_9ÂáÐÎmöñÓá6À[¶ÕyÈ kᾂÁØaÓ@Ýé‚U˜šR°3ŽÖ`ÀœzNÇnè;ŒÏª#c£³¾dr_ÇCŸ8.ŠT/Cc>ºr›Øp–½þL“2VÑï‚Ï®dÈ,˜(£f§1þ³œAÚ²T‘º§Ó‚<0b]éÚ¨chÇm¡^™!Ók^«º´N5ÛR#‘ڿKÆmº…Ì7H_ÛÓC£LP Ñ´ ¥‡=Ũ{ív÷ÑDíî•7Þú£òÎûSŸ»åƒü%eÙž SÐ…Ž¾8:à‹Óì[WCuþ|1+—œ÷z6e«Ãñ(|¼Ù¯’éŸíKòpB?e)À-Y ¶ûõû0ë!0 à±0F  5}à…¹|¥nUÞn¡,Tõgï<Îiüð«X Ò°ˆÔØ‚¾À¶d]ð4¬n».Ì &âQÊI¢õh‰ôä1MïDHZ§Òg €`h3Õg€žé¶X²Ð,K0‚üjy÷ {¸ »³±ZjÀ ¥Œ­Ú߈¥Œ†…ì’FBÀÙ¥ í*°f«™jUì?Ã#rn^6Ö‚ª$cß@z€ž2ÒJŠ¥.4b¢/¤²¬í8gËÙ^šlnŒšy×êi?å²´“Þñ²hÑdpC°?ÉÍs¢æ¶M2?MËTU௠–•ÍK#M9¢ôZ2.ÇmVM˜ié5€öû½tÿ˜NŽôųŸ£]è(ÐQà÷£@÷ÏïG·oU­³ÅEùðüÓò€«1Vø|¥]^¡Ê_êŠ^^–“§hpÙëv?·ßÍçHœÓ ™#©©¢OvcÌÙ«¿(=ÇèHP_» ±±¿áLÐt ÐÈHz Ö×·Þ üëæ/Sc71FÐ5š»qÈÞÊi.Øõq}»Æú^pTŠtüÖ÷moC[ÖŽ_~¤Ø¬½Ó†ÀT î°´gë˜ x#aÛ7 €îGºŒJ|ÐLjòΈÖÙ4%9‡¾îke7ÈÚûè:'è‘'°96Ó¬“ ŸDh¥cËxEJ§AçëDDCTû–Éíd¤]G†,§NÑªË †4ÇOm˜›¨ÿ›´ôOcÕNÚþÓ!e즭]Û€ŽvDAé®¶&mònŒ¥»A£?ƒt”crŒqìÃcŒ‰•ø­ƒÙHŽz–‘r²Ï6*þ·ÞkóApï¥wX пCÓhmºûí(ÐQà R c¾ Á¾ÅÏ—åÇýž"Ý_vIõ^Øý¯VÓ\——çœÂö Rÿ#A-ýXÿo-lu A@ ÚȬÐé^!»w_£9Q Çuh \Õܤûæõ„7ÅïROôy¥äLÙ¾’?aP}Oþƒ‰!¡ÞDÂÖÈO Lµ˜SÏモºO}E,&л‡ÜµømŒÊd&ª™e((+´ ~µñ¸åO$­?Zœêx?À QðíM©Ã®†€¿mðãyöbçÙKuìzD4ÍG‘T{Á šuÌa ¨†©0TÛÇÆ T–ö-ÈÛdH{²Z¶oÛIãV™Ý$m*˜N½Zøp§PÒÛqY×1ÔŠ¶PËÙb½Ú_5*a! %4æŠvÀ¢Œ(µÚŸ–‘2–ù3·eˆtÞ$©Yybi‰{¾N=Ö¶w÷ËoüA¹ÿê÷ÊKxû;¾óFè¦ÿ„.tè(ðûS c~Ú½ð5ù×9ðÕícÌ'ÀöØÊ&ˆ¹,°YL9Dæ”ë¾dO9®k4¶û¹Ön¼â€Þå|Ä<§‚zC4ãÒ{ÚúK×ÊyEð‰‡<@°ï3-Æ2K® Ø‚GóQÇ¢Þp€…`õduÃA FOº@¨sôå—Zòi¯iÆ“SÞØ,zØÀœˆ}ŽÂ`¬P.æ©o€Ñ®1Q\ øö%p92Íí…bîe>Ö. PÞšóôôglãåÜÖ1Aî¦ó–y¡Œš„ ÄÊ:—LnAfA`®ËŸµ'm Îéó¡ÍsHM±Ï‘ÈÉËüì¶éׂqR”Šô·[hŸÒf¸Ò'Å$„5X¦1d^M,Óf'mÚ˜wg·AªÕQÝïáJÛ;{åÆí×ÊëýÇw_Çâý²³{ƒ¿ƒî³¢v?þ‰èþOú'ðE®î?2CÄ­½[wðà7-ã“'øß_¢òìÉòø“òøÑo~¤ô‹ >Ú8´a]\`˜Ø8š³a§?›R4[èö÷ÈÛàÀf ügçÄl³,W\}¤¾1nr•HGzîáC…º^•€.:dÕÁ ÿ¹Ï^dçXM€ç×##a»Þ-ÑìÞ@°Ì/LAŒ%&F‡Á JkH·…zC Ú¢-üú0OÚIwT°÷ºã5îa¬F ®zŸ6`‚š F}´#ã0gþB•Áº}9yï®™»#¬‘èSÜg´XƒŽõ Û¨Òò5“@f˜zUê¦LÛ)Õ¥¦=¢,3lÞt¬t«6jHêHáÍ·?¼ ´oíÚBÛ ï?ý'ĉ÷Jõæ«Ö7,Ð9¥ Änæùª}ÏG7µ»€¹I»j‘p;ÍöÓÛwß(þ³ÿ¾Üº}¿¼ùÖŸ•ýƒ»0‚w¿JÑî·£À?Íÿžÿô†º^< ðIöS»R•jf øÖ¨ðçü-Pÿ»§5Ç,¶{âUö.š­iqü ®Pÿ/Y#@€½Ú+6ú_¢—ÐiÍ0w@]AQ@Õ²½…$ ¥¹m×¼+ø8D{¨”´‡À@3çP 0¸ÈˆíᶆàýÒAÔÛ¤º>/™0£QËëqŽM¤wƒ6aWŽŸŽÁöTñ“M»õ9ÚÊgN4|-¡{SÿKì Îï3¢4÷i»–ñ6²>‘öµMj‘h^ê×¢uHÜÛŸyÒ"š bŸ 2,‰Ió¶}×Ò;N`Þ4¾tk¤î¦-½Ã¿}Œüpë{ëö+åÆÍ—X8‚ 䀄.tè(ð¥Q c¾4R¾h ñ©uZ=6ÄÇ¿@¿,?ÿ?G °Äc২ïqÎRÎq¯{Š`À«åì;,ƒ+Ú§ãhGë~X ¤g¶äqx‹"xö¤3 ‚¨óI^5Æ{k@]ãàÀ Ž~q\ëÇОãy…($q=â‰>¦Ôb¥Þ bµ‚òzS9‚¸”åY5ÃÊ}{ü‡;"@KiW@"”¼WµŒkúhË0QÏ1eÜU#àz¿R°¶ÛR fª–qGEƒôMA)ÙaÛEbÓr1b¯Ú§&ãÃh°0ÄΡ-†‹ŽUæG ?Mò#ƒ“­V¨ f<Yžë«V@ºÑ>‰úžúÿH†‹²§lˆ¡ž7>Ö¤ Þñ7o.£M‘ü‘þB?Þ±MéîØ¿‹v‡ÌŽw7Ñžƒ›ÑîM–ŽÆå}¶÷½õÞŸ”[·^.o½ó‡Øìa§±—ö»ŸŽ¾< t À—GË®%>ùüÄdNlµÿüü¼ÌNO`æ|¨ð»¾ƒáÛ¸Ü8º‰åÿ°ï¢Xúà ˆ…Ëm´žÈ†Õöõpš1_ù­ VHø®Y«"*p• ¨gûª ¨ !¹Ž.Àhé¿䨴>ž=à×Ö´´WÂ\þÌ m) €+Ð?ÆwH—B"*å§2±Êoú ¨DfóqÚ¶0i%0›ï˜Ó?ëûÞ87Óûž’§4K›1(¤œ‰ä[Û&è(R2wy$v4Tá’°eƒ÷- Â˜˜B'¶+-£+(Æú1°M ‡m=GlK.«X&®”“éC-ã8-$[“^›º&ˤiæµíqûLhúH¯%S_d'„v&§9Ö÷¡‡}<Îw—ÝM±0»û‡¨þ÷Ê{o”×Þø~9ÄÑÏÁá=˜ þŽºÐQ £À—NŽøÒIúü7i˜Ïþb…ÿÕ 0Ÿñ¡^ðÑ_óa°qf3~å¹*7n–£Û°‚…Öäp§Ì80go÷ ÏÉÂ9åŽÓðÊæ‚}ðýáÁEf"çØ£Òu?ý@Õ. ï>~QJp ã/éSõïÐ}xrŠíôë)vŠR¿[ÉŒ]OV5?‡IðÂ,Ÿl$È2C˜ê :ñrK“Û®åƒt˜Óªêu*d°¼`O„D2l V¢i(€Ž6ù\Ö!ÈXøŸgøŸçŒ˜·Ð+–Ò¦uÅÃÚmü *-؄܊Öm2B×yŒÃ{’l"câ^û:1]ÆÉÒÑ44õS›Ÿ`>y±¨· Ó¼¼çjû3Nšy\¥°¡yNä* Y%±>]Fjûð‡ c|:÷Q_ üù.á¡§;0ª3Ÿ7ßùì^*¯¿ñc¤ÿWü¨ÇÐ…Ž¾ t ÀWBÖç»Ñ€P2gßbs÷¾@.nŒ÷ÜìÇÚ?Üãp•!Ø1'ôÝÀ0ÔCBÖðpŸ3ÖAاŸüOy'|ɱ˜a0Ðb¹ mú|éˆ}ÇéÌG{ŽœóËŸmqòõÑÁ÷‘ƒ sàRƒA¯|‹çl`d,t¡ ¦}­Ì=bxó" k«d1JÜUí|ŸÿêN—îa.è¶ðc'Ïšé>¶ ¦ÄêRDÑ—@‘ä+ÉÚ‡eùãf¼d ¢ºÏÂ÷a‚´uŒ:;Ê£íq©)QïVþð_TêÜ0Õ”q$ç¡vÆ–t2œ~“19>+²ã14³Nêñ#s`7‚t›æŽ çÒôRë8Vëx5ÙµœEi„DßI4æÒ¶ªF¼´/ £§úß²ÚRô`Fl=Ž÷Ëßû‹rÿµïã÷ÿU—;ð¯dì~; |e耯Œ´ÏoÃ@oó@æŸ £ëÛ1h·Í)kZ¥ïàÖv„– ®–ÓóH°â¿•öší‚~Ä•öW,¦÷±–ïaí?eÚ$g?~ÀÞ<èáúxŸÅj%Ä+ÿÅZA¨@«ÚP´¾O6Vü­„^ ‘9àaMǪÁ•'ZJëÚgrBK«¤ ‘œî-›tëY†œZ«Ò8š Ëq)ýûª´WÐÎÂç!oCÖüï½ÎßÛQÙÛ¿ÍÖ¿þÆÔ©-¦Ùî§£@G¯„ð•õùn(1Èc/ÝrkHrê(ÙG⿺w¸nÊî~í·0¾Ú•AëÁŠu}<ü½rçµr±sZ~ý·ÿW9Å@o+¼ñ]òÑ>õ» £°ö0 ßæbD8⣟ÝãºêÜבò¦gíd±Õï Á™„´hIIZöÙó<Áˆ1|”p7¶ËüüE‹M°°G  î p2¤á þýáR¢ˆà¾–½0fù’†7‘ 2³eRûªÀTý4® štÚô¼·X¶iY°œÛKšÈÈdâ™s¸æLoB”…VÛŠ„Ÿ.LÏâC[#+ œïÔÐþ.‘Ò®ùË µÝ@Bè“F}5Dªç¥c¶7Ž Ó€Ÿ¶[zD;Aa·þ©Mp:K2|¯zìúJþjv°q׉Ûývqéû—ý? qºSÞ~ÿ§ìù¿»ë£ : |µh¿_m/]ëÏ€jü·€¬zññFZö@¥ý Rÿ&{¿ý‹ Jî8û¡î *[öåã³uÄGxÈ¥ª7¸Cñ¨ª h_@Òаz× Z•³ÖÜ 8”Ë/UÃ,ˆº¢^%I§x€LñÓšæÖé¥Í'É5æHüâ9L‚é\˜ÀÜÛ÷9s ö^)ö™")ªýÕ¯CË$¨±°²y¶m8c/ÒWyïc[ö·Ú³¬ M‹ø½1-•SÝ”Ïu¬–¶š›¶l¥Eª_åºb*4yܧù¦vܶZGë_@ÓG-™9ÙVÊÊh„A¡ m±J’õþ1n’'0ÿ`,à³p›C~n²c¤ÆêÓ­ù_¿•ÀWNŽøÊIü|u Ì7åÈ_Ýü>Ý:/ÓÞYyÊ^»S®9*ü34‚æÎl‰{€~?GÁ`à7Ø.Û÷ß,zí‰íÉH{´‡ßEÛ΃D¿-õ³îoüøãGåäác¶ºã@dW…¯$äLÚ Uµðµ° Ã7Êa™€‹à8•HȬéÂúêàÅ)©¤pýYc7íúÑQŸÃË”ù„q-À –%aµïc:4jàÓ~5tÀŒ¾Ü¦è8+²ZœF Ø?ÖúÜÛNeGô³@å*¼ÏÚ‰=ƒåH§ˆ¥ a&ˆ]“OhûOŒTMoRÑǶŽcŒÀDGCÆ¢e@äÑHg&õ†ßj“@T4U&Áb¶§™†7î Wœß°%Ó¸Í ãmÆ–-‡$6 TÔããÛ 0o¡yñ¬…ã—ûe² C¸ÃßN¢n¾Y>øñÿ À;ïýUŽøŽ(܅޾6 t À×Fêç¤#PÅ?€»H¼äc>çП)fös¾à‹l¨\@#UÄîÝìJ½ë *[nñC­?äC>øQ©+颻X& P½ ½zvo0ÆÑΆhÍ~ÀY> Õ¬jZ’(î[ °Æg, 4jy=øùXm£Ö ÀEÔ%O4¥¢ª|}çû`VÐÍŽŸ)À)Kð÷ºHQÓ#ñ“!Þ ²×šƒp$MÅ4²gB>4!hß¶Ú´×d9þχÌë™D—*¬ÝîTð>ÏÄmí6–¯hó¸Mþ³íµåÚØ2ÏÓ½þ$Y.ªq"­Cí.ì§ŽŸw³%½CsÇ ]”ü=‘™Ãsé­Ñ&£íí2>¸UŽãÚw²sÄa?ûY÷OGÝOGŽ_:àk#õóÑ‘Êÿ³ÍSÙ™—‹Güî§3´gÙ¦‡mweK,÷ÉïQ®‡£ ùúN ýzž¿ŽÓýÑþ¸p@+» 8.˜ú®ÛNv&‘(÷(">n.`ظ{9á¼€I¹<+åâ ÿ¸ŽäŽ(Þs™€8€¢8 õö»ÞAÒɺ<÷îWÍ~ý¸=C¥ï^ùÒœ @Ÿõÿ«¨‰YûÚÁ}3°…mÀh¸WÁ‘¿ž빪’ݶ&žDx6]{Y0 }@`ˆHØŸ+‘»'_Aí/øÈ0.á·¶°çYà«€*ЛïuvhÛŒ=jgÒíXÉÜ  ƒõ`QWL÷ÞOÍ?l‰ÍdÔ¥MãÏšNnŠšSÇncµŽQhB’ã6§m³òll+¹øiø “kh3ˆÃÙ€=S6L»RÛ =ýéÝ—Ùúç±¾œ©ÌN<úíÝc›ß»¬ý—} {}–Ú¾º¸£@G¯•ðµ’û›ïLúç*ûùÚ¯ö5žtÖ¨êsÒ/g|ܱˆŸxìÈ¥'6Θó…ç?_ìŒç³§¬ÿÏ‘æg8¼Áé-žçg³e™ +`’§Ÿ¶½m–Ýá6èèk5ï‘°¢‰>±œH ‹ !ÐA ¼.¨Óÿ€„LÒ¢_ë EFŠlšöä/JÏôí/ã ðšŠiæ¡A»Ôo³ˆ-'˜Y€ñ€qÒDoÀO·ÅUÝb¡eÈn†Ç”âÇØ¬gƒÏ‚¿ír„MË*¨Í0´M療L%í©nW›c©06 2ÿžíˆ{ÇžBDŽÃÐ ¿I†ÝË\¥¾cjò›~B¢¤ùž¼>_ßùûþ\öÞØU U‘°CcxÊö!àïÆ»åàö½rëÞ8äç=v{ì1îª×H£ÝOGŽ_;:àk'ù7Û¡ Àø÷Ò!f{•¸„!À ðù“'ãšuYø´ú˜°« x ª¥Ü=3œëè©Qá ¶‚ýugžT ]r¼0à9ìéaP¨‚1ØfK 4Ú± Eîl D,æy$¬ˆ%´ùOTþö,Eè›ÀÔÎ‚â‡Æ;Â0kÚ´ô#DTvw«ûÙ*;·XhN^ãꦸ¦¥/€kpRÕží‰< ÒæÙ躑€›¡†)1+ùÞ„JöPM¬]\-Sµ!¿ß2ÒD—ñ±ƒºÖnS.‰D/&Åò#…í&]¥žóLBújîmËiÈÄdIÁö öAzVbxÔÁgÏX¨küT#DQÛ Œ ÚžXúón}‡eb9R¦ Œÿ†;eçö÷Ë­WÞ)·ïÿA¹óÒ÷©ËÛÕÀ£ : |cè€oŒô_oÇj3GJWõ?-çˆÌW|€‘§öéë·yk@]=2»zýº¶Î³€­+ßjO€ÃÁ>× ,wa Põ_b^òàðÙ”éÙ `ân(°Sã‚+šã0Hé\øÝBô¤H=“ÈX4º,‚½Ï<&‰g€GÀJ?9;^éµù§ú]»ÇÇEÄjÚ ¹«Í×´Ïý”Hkºm@“öAÓù ðÒn-åzœ¢¾kᆌÁ¸©-CPÛ²L­MLc-à§Ϧ]_µ°¿GGÁC[N\nó® š`[M,ùrl°i<į 43jŠ=óĈ,Ë¥¦Áà!A½!] BvYð5Ñ>Cn h†œêw£ìbôwóØ“ýîãðç öùLíBGŽß:à ú7Ñ¥àÿáɇXûÏÊëS>Ы²=ÆÇ?~Ø·ÈóÜûÍÅV¹øä¤iv àÿÇ3X8ð¹àÙÍX"dç+<ú‘ùÎ^+{G·Ë4 hýæAùÍÿý ÇÏ?eš8ÂM€[óÖsÎðXa5¸ ¾Ú ä±3@eœm€©'p“Ÿ¥½ .´B$»€”‰A^$aaX§Ah P7W5lìEpZ‘(ø®u¡y¶chï«ä_û0=M+ItUõ ø£]ˆº] ÷žÆãnØòlÛ´¾à_ùÊ„´µ`i¿†kÀ¶ þm^òýA¤Î¼ýár.­6Û€÷°ñžØÓ³š_ÇMÜ€µ‹7†k³ “yË,CÛnï«7l.û% ªI0Vν‡QfŒéH#JÛÙæpò36¼4î8aûäÑÎayõƒ?)·_-ø§ÿª¼ôò;”ÛaèŒþ*u»ßŽß,:à›¥ÿ×Ö{4kVþ1è[&9V¶Â*’ú'-Ûœä· Àmœö`È/ÈÖ>î£L ¸TÿCÖ{u &°F?šL0üÂgáú¼H¬*Y¨@Jš*OÈ´\ÔX´ÉÛµðŠˆä熘ÿ”»Óëµ{@¨Ö¥!¥-ÊåZyúµžüÏþx´-óq¤|1.€±Õ,#£a•€,ñõz|ÓN+ý[(íÛFªõÚ~L¶Še MõZÇD.™‘„6¶P[°Í"ϱ¥b[®›~¯;iÒS¾©ÿ÷EéªéKú^wkyÈ›ÈçõÈN·0þŒvvëYGÇxýÛãoG?rƒ]è(ÐQ๠@÷ãsñ¾úAÌñžóáÅöú/Êoý ]íöhIr¯ÜºyXní¾]žî?(³“y9?}R?úe™NO‘òpõË^¥Ô!{ù'»Ûå'þã²³·[ïßÄî\9Ö×£}Çœ#ðä‡ï²Õï¼üòß"éÏÊÍÂZç0H™†‘'0²ÕxŽ]3–%8eЭëÙeÀ–*°'0§ñA@ùꇥVŒìZ„,7¬* ¡¤cÕÓŸ©º/™ÊÂפ¯¸¯¥tÑhÅJ&´joMì.x.Ürèp )cÌ÷Òí󠛢þ8"9”º&^µ&eé€25¶Ë _Ûk/j§Ÿ¦³ó9oêµã±6˜&½Ò'uânׇæJûTºÇ•¯Ï’ÊlOŠ”I»âŒ·?H‚‘ÖþÑøŽìëÝÿöÞN¹ÿÖ»å×Tþúoþ—rãÆKåˆC¥Fqôck]è(ÐQày @Ç<oákƒrœLÀœm}uºÒ´Fh3È1˜`\‡[ß1NôXösH¼ìÐÉ_ƒ@Cãm¤»í .²VÓZ^{€ Z€+ÄOÜ=ôæi@κŠ|êU ò%œ@£ºPr|RÒqZ f€tác«EµÜ–*ïÔ´œ 6rß,Í ´fLzŠ[Ö¶š:&&ŸVÚ·,I-’ÌÚŸ}Y&ËM–¥ègíyÿ;‚cðÏÛxÚ±/ûàrXm9›°]³ Yï·õ׌6óÙô/z︨ª3<ùÖ®ƒjÂowÇ“°<´·çá>\{·ÊÎ~ªÚÿ·K·mtqGŽß :à›¡û×Öëþ%ëë§xày2cí@^à¾Ç…ù)böÄÙÍyìÛeÿV¯¼óã?ÆQÏ>ú«òäѤ̭3åƒ~°[Þxÿ5˜„Q9Øß-}Ø}òPVÂvËû¹×³r|<,s´«·ï–RýÅ£O³UpH™À»†X¬XfX–0 WHÑk´º–Qèq7̘®Xzv¶âл8Έ†׆‚‚' "‰Ê((-‹U‘’ÉëGºÆš‡aŽ¡e¼Be¦ÆŒ#Ý€âi‹:dåÇXÛ‡´KªËîFl— ~ËpA9®vl­æÀºmxæ6IÑJp'Cf°/¹ Ë ü†Z§ÕbÔy‰ò #Ë8Æm.Ix™PÓZضThmjÄô8eCúå9ó„ñ“±©ÚÆÄ¥Ïï«G†ÌØ%ù¦-y@ßí›;åðÖnykÿ¿ùoþ'Œþ^-7oÜiÖý›I¦§î§£@Gçð<¼…¯p [ãV\s ÀÚuz€1[æMÜË JŸ#ónÜÈÇ|²»[Æç0 Ø löííró&*ÿ‰Ûù³áË¿Duï™îÃX ª–_âÓ]©€÷q¢^œöô%ƒ€d¨a[ú­À€{Œ#c 0"Šžæ¤ c7Ý\Õì+¬Î|®”²Û{«xYGu¾¡ªýI×PÂ^ZN'=‚]õ–VÓ¡AÐ Iç'ÛîL°Ó$rkÇ^H½÷ÑÐÆõ©þÚ—×ßÌs>¾«lµ£`3ŒÛVÍÏeþç@‰ iÚŸßÑGuLTëWµAmú׺'sJÜ>[¨‰k—¾ÆHYi¡] 7=œGùRú饷q÷+øcWÒ­ûKÁ.txî(Ð1ÏÝ+ùò$ ,Qû_²Oÿœõü±Д}ˆg?Öá×·ù@ó)WºÞ™0ˆ}#Öû÷–åÞ;Çåàî)þ¬Ì.ŸbÀÕçì€ëúWåé‡Á>M±° T÷÷Qãk88›^àW`Uv&çÃËÖ¿¬þ1\âhh5£ Â-ƒõ’5Ïȱ´Ž‹5æ>.†H£åe4¼æ I%ÁÜ`«·Uæ¾à'ÖB°”pÉÞñŠW6ë{Ú'PÊ–4MR°‚œ[ÕõâçÁ7gÊÚž¡í7`Mƒ©ë˜½¹nÈ’DA»&ðÛ˜„&)жÝ2$mzX"iÐM7üX>8¬hnhú—>¨U¹f*¨+íœ[u|/a·í×IÕ{ Ř“¸é6ýÙ´í(ýë/â6[ýÞ|çýòÒ}œþ¼„êÿ0ï¬vÒývè(ð¼Q cž·7ò%ŽG°Xá…o¶šbœu^ž<þU:0Ñ\¯?æÃ}^&Û_V®¸à5o4Â} {÷o¿y É}/ Àüb;€Æ?|ü1 /ýý#å{ö¼ûíU篦ˆûÄÛc¶ "a—}4¨ÞOpú³À(PÏÜÆ›Þ’›Ve/´¸Öl{à­&A´+ ì„/ˆã­H׋ªU0¸„Ðò<°ˆf8å°Ò\ŽnlK½Ø4b !¨'Ú†qPÒ@8Ó„Qï ÙŠ˜;;d v3ë:B«ÞÏ?¶ÙÛölÉ’ÆÕ‘¾y¨²:}n¨iµ\ž“úÙ³j;l+ª{:I´åû±´5¬]8¶¶o;n™%KA.kú2cÛ“ ŽÛþ c•¶ïøì×6hFˆÞ¸y¯¼öÆÊñ7"ýëç¿sö#5»ÐQàù¤@Ç<ŸïåK• º1³íu,¼gúôg_?žû\Ü ÖbnïGŸEw>ô¨ó>ì=¤û*ÿ+–f—xä Üî‚×èõˆé@Ê£ ¸r©aŠç?e‚ëÑÛ»ÅVÁÅ9–þ †ëÅ%T°Q*õYÌ!ªÁ› :5MØh*b Rè¦ôgùþ—ñTì”ÞU'ðûwÂ@p#Õñªæ¡öß ß5VU:ek7éË’MÏŒßDB2‰S­iè™ÐŽéïÆ-À¼ké7Um‚ mߎ§mÕ¸½o(p]Åód$¹*{Ï~È«ݯò’íWÞq{d°»+tù+_! Ÿÿݽ= þö9èç.àÿZ9<ºCž XfMC]è(ÐQày¤@ÇgO/»Ûú•é_ýìÏîãľ%€óåã¤ÇÏwÌg¨ï?bk;.NÎ$ýÛîôà2¢ðêü2`qkŸ0/ÝÜ/;¨‡¯hwÁ9q);Õ.ðÇ_o ßœ¯€CÐh/ÀCŸIÓêŽÞ OÞ[ Õ Öjj=á®M8’Ô0Ÿ]ˉ„0ÀÄî­.}Å亥fÀ:‡íVuA}¦ *T[‚´PL¼.Oõ¯CÒ+ãb=Ï#0É«O|Ý… _WkoÚùä¶›Ô¯ ×ßZ¯íÖfªÀoz›×Ð… •!²–_`ŠV¼‡h&jc z8žüÜê¸ÉÐGÍßÐwÐú°ó³Ò¬!ûý_¾ÿF¹uç^yÿý?*?øáÏX.rÝßC~êÒ@÷ÓQ £ÀsGŽxî^É—7 WŒÝ²·³‡Q z1xch§ŽQ ÷öD@l*øÁwí-ü=öðWun?à-€_q °öà®ý_É`Õ¿œ-Ro ø«7ÎQ¹ˆœ‚AqMúŒÅ¯ezôcÑ.5 ^Âø¯‹ü *?6!Že)ÂfšvÔ€$“ò&Ù] ’œ{Ýÿo¢ÓO^ýáá³`"Ë´‚mÊVä¿x׎/±ý®§Ý¤&ÿÎßë"ÜX/Ï×Drü†rÍmj•îˆÓ7?ÎE€o×ý­i 6ž¦)kºÏmœ÷ÚnµÿØ?¼úÿñ­²íº¿àߪջߎžC t ÀsøR¾Ì!mü=¤ùý£ýòÁ÷ÞçØßUùÍáI¿œîWíPï_  pq]€l»øìÁª›u܃Ý} åvPïNcä÷øÓ8ïYâþ‡Â0z Ä8€zÚÀTPÿñà êÐ÷tS&èŒgçKÖ=J˜e40ªõ+#AÄO—A£A{€x D"WRw=ߣ…·±uv4j~4 ×{ë@3ʼ0 ’ìv¶0¤·YÞˆ]lJL¢ù£ö@ “ÖTjŠÈ«0ÿ ÂM €Kaíb+@áVº¶˹;ÂñÚ4ÛÕi‘i¹·€í[ÖÀ8}7ëûfÛb²›xÅú¾À/èË­èWjNjÜör$d44„Öæù‘Ò†cŠæ` ÌÛŽ!¾žßÿÉO1þû!Æ” €c¨Q: txn)Ð1Ïí«ù’Ö|‹Ýºwtã°Ì1¼;g_ÿb¾)'OXÓç(à ÞUíÇÜ/ƒ5ÞúÛ [üƸ¾b·ÀÎÞ~9`óx`À†"YéÛ³à…9΃È)§WØ ôAwx„ !™îPÕßïŠhÜ‚$~fʱ^ð@Kü“ÉØr)€vB5‘XE].w ñZHo€&R(8¿PëÐàšÑÝRMHîSsœCúä>Õ¤èg•€-qm¿Ö¨ KS–BmÓN]áÚçh-¬Ç|­kº¸kH»Äj@R–ÿ ÙkøöÞŒ„zSók»íöÅÍg…(Yk[Î`W^úi û\&8?÷ Æ·œqŽSém6¶¤Ák%¿2(ÜÈ€Mö¶Ëí{÷Êí»÷a^)‡7^fG b: txa(Ð1/Ì«ú} €¢J_àÈg…d &ö÷w">|ðˆ¯?Gc¸7=;!oƒÊ_•4n}ù–&€8v#™‚+¼ª®Ö)R`oë¼¢G\ k =nù@œõEe–œ?ò¡^ä€#˜€ZMM€&{Ùþд{Ï#QÇxái~ÔõT:}Ñ»­mìöCÊ÷aJ”ª]o6€=w@” ´ŠvA?’Aiå f%47±”c¬~*0› yM“Ô (×ó Èlæ%ãIl(c—)ñr|‚«}øÓ°KΧ‚wF^ Z®c ì™7Ú@˜U³ÓbmÛ‚é·ŽÙ-†ŽÝÕ6¤_ûär<IжÁ±Ë¼\Ÿ4hc”A@šoqíïï•W^{³ß{&àMv¼J[Nº : ¼(è€åM}áqòáæÃ¿F ;àþr×[hòhøð³v¿æ(àûóWÂ#ÐWTEÂ[Âôð8½è±ÿßµúU¹œ^æÐž‚@çn´¾b©ÀÍ\Wþ‰* Ý–ÛÿèßÇ`’›ÿyÎ6>A…ÿܷȼ[cÁµKž[ ý'ø_Ñlei¿½K\ „7ó)¯Aá'NçxjÙcèOÉk’¦ úi¨åkœ‡üøœiµI&xÙqšä§y¬Ï–mÊi·À¦¸ Ð&3ÛËÖ:bçâøþN -ì€qîe˜š>Óeè™´ÚHž I¥‹´id‘Ûâ =H0¶˜qú!/[-IŒ†ÇçdšÎ÷¡×¿Ýƒ\§?×…Ž/ :à|iÿ˜!«:WúŸÎÎËÓ³Ge1@°s‰ª/¹Gþ‚§ÓË'œÜwV.Ÿ<(ÓÇù²£ pË €µ¾àÀTíËóQ9ŒªŸöfl!Œäß_r*`¯ìßÞ/ãŶØÌç1[ÏEóMìcS@|…ßý,§\l%ŒŸÓéƒ!b$c¤öHîLL³ð¦ZÚƒ6ÕK *tv+„™AÚ§=× •RŽà51hn47H T\Õp§Ñ´+ñuY"A˜´0'¤lÙ„¦’ †’º5²3ÑLÇ—8·éæ­"€·ÛøzÙF×0¢¿™a€c[§¶ŸydhôI§Î¡Áßô'í¬q¥(Ÿ`aŸ´f2W¾cw3V:PÆ~¸Ú¶Ü"jh÷ø›z:/^Œõ\¶p¨Qÿ.ôA}ŒDï½ò½rç¥×1ê< ôïBGŽ/:à…z]_l°~Þ³þ `®Ñ œQ³àÜ •újÅñ+JqÏÚ1~=,éçØôûÿ&†}1¼³è"˜ <Ù?¨Å;Ä šÐAx²å¶í½ÿÒñÐFZmž y$©J²ôèø¯uš ÀYåsU›Vš¾ŸióúÖ®Ú‹Û”ô§½Ú4âšIüÌðœÚ³!YŸKkóÛ¼4ÍO2øÜ2òm¸žK› ¢gºo‹&~¦jÚ´¾ôô½Ë×Ô±ZÊ«2%ŸÕù­šÄÕD<Ô`»õ¢6* ¥þÉd‹ƒ¡:ðoÉÔÅ^( t À õºþñƒU6ÕéÎl9+g³3–VålyŽD‡½™†@Çáëì0Ãi¸ ^â2XFàâ)kù0 £1~Þ·]6´AãÆ{J——hPÉëS ’¼ ŽT-¨¯aq7W¸&Þ½¹…™aaù¸ì&k >ýÕ´\ž³‘±º½,¯«9Á†µÿ€?ÆJ¦†úJµJ·KÆgúsÒ‡õ«ÎšØÅollÃŒ´ 2RSÈHM }ŽQýœ©ÿé,¨©œfÍ©®†(Ä2I¬¯?êSÀ‡TO÷òIk4eóŽ?Àl%C‹ùZÛ_'xgA‡`2¡S‡v ±£ Aæ.Œ™ýi Á+Mx~“m¥_2d¬r £… ‘óÕ±R”"”wœ^îêà1šVr&Ä`4*;ìùã­cð[ÿ(Ñ…Ž^4 t À‹öƾÀx‹|è‘î× Žû” =ŒGõ£¯*}À>ý>u>ó¬¯W°o%}׫½-ý׬h{¿^³”•0À‡¶ à§jA¤å@¾Hðtpö@•6~£vîiQNÛY•e§ Pöç๨(«]Hžé^³ó“›æÖ{Ë›÷¹a‘ׯ)äó3m¶U~WýôõLF{ÛŽ¹Û6ŒN‚7öÕ<yŸ6Ú†L¼¾÷æúÁœÏê6dÜMºLF;/¨ºC±4‘8-´­´í>;šÚm¤çZµ¾²ü»Iàeõù{ò÷2ïæ¨_iêBGŽ/:àÅ{gÿàˆùüGe¿Â4~:_–3œüÌ1ø{ÂI}ºö½8ó €­róøV9Âû›waFù]”‡ŸüºÌgåòé‡,\ŽáßÍ[÷朠fa¤’™ú¤ôAÌÑ=ÝœâPð_³öŸrh¸Ó©+#€¾”ø‡lZoâyò”dl‚âeeq{»r†¬O3K*DêUÚeÉ‚_žÑ·å¬ZPMFÄö¸8â!ž[Ž+Ò1qú³áyØí:Ý·kç–18]ƒKê×ÚÚLú3O‡>u`DV|ö‚œ tTuö)MeÉjCYÏO ?$ùŽ7œÛÐtSÓLoÆ?h´U£P»K½ ¹ô íp µÑv.×âû¤ñãÐWŒÇm‡7ï”;wï–{¯¾UŽŽ9à¦îUH;Æ.î(ÐQ๧@Ç<÷¯è÷`‚/¾†sî»÷èÝù%»þ±Æ¿<Ñâuóc¶Ôáègt“ÓJïⲜršßÕà /€¿­ÙF¨jÝSãDü¦~´ü ™v Ôúýô£J}1ýW×¼ä«â_ %P¥L»[,€oaZî¿ì5=³ÕqßÖt,¸i/`g} ÞÔVØ¿Z}±K†C`To­BòÌ4Í`Þ×j½V#avÄÄÖX°Pó¨ÿÔçAA7mÆçBÅ]iñ;2)ëðfS$^M4ïºÚõMŠ·Ùí”R–DÙì0Á*¶k;[?×­5yæ‡ÎeJ )Ëq{µy‡¼æÅõ±Üf à_#þvôTi×–ìâŽ^ t À‹ò¦¾È8óm‡µ—¸s °_b©ÿäÁ Ž'À“³Äâ•ÜìóßåhàýöwÊáì6{ï·‘î\#¾@Ê¡1O`¦åÁ¯?â™ã…?e¿?–þØ òd¸ä+ΈdŽÆ!ø‚“ÑɃgf¸é]³…p£´êºÇ¿*V¬6Nø!Ýï ö"}=š×yUðŠ¥:í(õ[[&@3·¬mY†R‡XÉÜö´X)ª'»ÊÛž“Ðð)C14÷îl”a‘‘±~*&~æ– Ë(mÇ™N›O,eHÿÍ=ÅÒ–IâÇú¦ûë}£ -ã³ô¬c±=g\ëdúÍs˜ʵmÅAyMmH¯¦¦Aö-iéç,Í@PiÚßžÀ²óoûü­ìîî‘^χè©Ø…Ž/:àÅ{gÿ¨û¡w!0• Ô÷Ož¡ `?ÿéy$êåBë~¶Ô¡ßa)@énoy ßf•ŸûÕ´l¦{eu¹QàY™=9-ó­Y9½ÈuÌ©Ûú0cãÉ÷5*C¶zVƒç/ÄqÓuOMý.ê(ÐQà… @Ǽ¯é‹ÒÏ¿ç9§ö\”sÜýž=:Á-~€;õ‡žD¿ÃA@Ûg—ÅjYNŸ<¤ÞÛÜ Öø!†öV=ÎØcËà ìOÊ’ý|3Út­?@** W¨üÅv&P^ œ³d°š¡¢'O@ Þð“XâN§AÆìPä·jŒí£jþi?Ú@‹4Û£©úcCMê­ -H»û ®‹W‹ÁîÊíŒüó«]7B^3ÊX‚ Í}SÒJV“ŸHœ6RúZ+'Ò§€ë³^ íØ¼¯)ä¥!Ÿ¼¡?ë0™,y.ÈçÔiÚQKÑ—e} .¡Ã¥–ÆØ8^û6ØvØ¶Æ )Â@Çã~\Bï"é»Kd÷à&g0ŒÊîÎ>F“zéaOÂñÏx™t€~dŸ-v¡£@Gç˜ð¿œ/eh€D]“¯Ë2[|°½Ä?ø+|ÌõÔç?2=öÖ×uÕ`Ô—=` rlïq@ëøëGÓˆýÖ¤s‘*`é+@ ^pÕƒ ;”â·Ø€õ3uÅ.q¬½D"ÇtÀ‚Š)¶5¹)‘v­_¥îZ5€%Òpm7·SörßÿÿÏÞ›vGréš 3±U¨*n¢$²ïÕí>ÓwÎÌœ3_æÏ÷ù3sGÝêÖBJÜj/öLäÌó¼‘)6EIl©X¯ŠŒÍÃÝÜ"௙¹¹y¦5¦®2WÜo“Ϙ¤+é¦Úö».S{Å,Ý%«ó¸;€QRÆòZp+‡•(¨«6|èêÎ^¾Öý®¹^N=me^wóºMîxÑV_™}ýä7O68·?¢Bâðw%Éþ!þ"½oć¬ûàvÍõ>õè9ðãã@/üøÞÙ÷¢8óæ5㲚ßúcøç—ÍÉÉy€ïÝ?hÖqêzðÁûÍÞý]|ž7§GÏéÌ1Ò_^´‹f|„ |„ùuÜyƒ%Ž÷ÏÿË»ÀuóÙoŸdJáËçgÍáKÁÓ¾sÀHe•U¼ZÔÂÑ61﫪9ª•Ghè€_ ò¹6Í:6ˆ‚j ä_5ì/Ï[¢?Ëážs¦BŠPSæ`Á,5èu,5râAÊl­Y‡ •òŒ…ò\®Ù[`jk+m‘|¬”ûfÚDeí¦/:ä`RÔY¥ð¶øº–•ï\@IDATʸGAcYlÇã‰m¨g´UH®ÓÝRª #É˔˩¼LÃÙ{­%µIÌ.ÔsðÔëϾv†VBË:fÿ­ÿ6zúßÛy€U`ƒå¡7%‚°Îø”=cÚæ¬üV·yOZZ¦JXŸzôx£9Ð oôëùˉ64ɺŠßã÷Žá¯¢Í‰뛛ͺÞÿŒéÐe…°Whø®ä禠—ÿcíW Ì®yÔÅ~,F¬¯&?Ä@M1fß å°Az{)Œ–ˆD-ö‘§þ%“ÏÄÈZØV~<,ŽZn—R'Ý;Eêîj•Žo¦›šê©Ä °\)íò·õ~óÙÛç]·¯uÇãÖå¹9öJwµË]çu§Ž‹ (B˜°½]xåç±Êáá7KëJ]f#Cò¸Wã÷w¸ßå·Dï),Ä0ÄÞñ/¿ÍûjþkXäµ+@М!£¹ßKK¹¡­+»ß÷è9ðær ÞÜwóWQ&(먵É|íÌ÷ߨÝG Þ ðîGe÷þƒ ûÖ˜ð¢MXÔç¼™â˜iuvêjóhxŒþ„6†ûÉ…cïh˜¨‘B÷nl ñÅį™_°Rÿtïü}DˆÉ/YC0eϘ # Z»N‚æWðFóϸnê_•mŽ`Pö÷†©Õ¸Fätƒ½ŠºŒ ysŸ5¨‹z{£­îÌç3žt·â×^ï´iZf.hÍŽüu¥žO+«Ü*­Ídž”þµ«Þì )´`)AÆ*Øbðºç$Œ,N±$Û”ÚÚ{Þ—FO3½Öÿ+ÌyÝWaË›µ…Ê+óûB@?_Y'C=£í‰ëÄýaIÚØÜá›Ú!ߨŸáÖ‚¢ NÐwœ¿*Ëz8¦0÷¹Øî:¿}Í,ïJ±€–„[eww;úÜ{;m…îÈTßÈ¿¤jr«»ÏÞç<5TXžSþL zýgƒ l×ìÝVÕüùvº}¬|C ˜jÿs†\*º|@Ú«Øþ·ç@Ï7œ½ð†¿ ¿†<Ý4ýtÞÚ` ×Ã8G[¿ÿ€=@Þ\€3:s»ôø/Ï&= çôZî+¬©%‚ª3€â(^àDý}=f–!‚q \ èUܲÔ¢ {§óËE\/`UÕ›½+ ª½›OùÁg”=¨ò(Ë€Àða{ÌßÊÖ`n‡ÞHò ÇÎðÒ:?÷8ÉÇ}޺ؤ­8 =îCsÎóTêH¼˶R†>Ø›ßÅùõnw/Yë4ÔsÝyŽ…Ÿhÿ´?×ÍÊ -­†íõºÜÕêâ»Ñ™1™lˆG–‘*8o«ÊŽŸ äéèqVD¬$ÜSóWHÜý>ÜC¾„ÄÚãÈùÐ)€#†Ž†<ËБT@ôôrÌ9ÏQƈû•ZÚ³~×s çÀ›Ç^xóÞÉC‘ÀæîGÀÁæv³ùÞψúF'O'-dœŸ—ã° Þ³ÀSï¦g\›` ` ©žYØÌ€ˆ˜ŠWLg§Æ`ª!~\e00Ëìoº¢ éÊH€”ãÄÑî5éã˜õ]à’ÊÇ;® Rø´F G ¦¦Å±7U˜`ê%ÍXðš78§\ËY£ ~ät®QT6ë%(aÒÒ’ÏCþ3åןvs:žà*ôD¹¥µÁÄå$ïI`w^WëLe¢üD;tvs@^MòV½€²©@ð*@늌áÞ³½æ/Ê"8³N+êöÝ1 ¬uø“&ýó}ðø;ÛCðøÝê|s‡ ¬Ñ)£Óé8Ï*,ä[eÇ$ëìSÏžo$zà|-?QvúmÇ_àׂ0 ¡SŸ@qI„ÀÙœ©| Òû‚Nþ Pµ3&ŸÅb„]À\ó¿H¬™xârÆ”AÁ¿×óuÊ_4v¡¤´Ä̤ˆ- ISý‚Z!¡@;ù, p˜:  Г߲MX×YýeÝq2Õ‰õq¤ŸçÛs‹rJ¢)üŠ Sç ¡Ñ=n·Ê%A×äíJ^¸îÒX)’xí…nãÁBûðö§þ2-wÀe{ÉdžÎé®Þ«í©<Öl9¦€-Ë‚R&¹._ÙêÊš¡-AgQœü¥ù¯©ýó=$Üo®·N€¿ãÿ™Èxÿ*—ô¸ô´Â€›êûѧž=ÞlôÀ›ý~þbêÐÕóÏÀ|Æà]€ÐG'ÀÓJsÆ † >¿x‘1ÜþჽfsmÞÌŽ¶ˆÙß4Ç'c¦ÐáBFÇ®™WÍîÓ½2ÝF@f—Œ£k0˜Mèûçz© H"gPžsö‰¥/AΰՒ$'^Fp78Ö v;eͪh6ð!XE(1Ž€FvÙÈ‚PD,ó¿ÈG~‡=R‰‘¬Â¼^¶<³-9ñ^¬ÜQwÍ£æm =´Åú€Ï˜ŒHh²\“þV°xxÚfá@ÞÙÆÚÌ×ÝsBÓJ –NÒžn6Ý ‚•ΔӶEÚdí5|´lX! (çYÚÐ-Ñ«†åÕzPFƒŒáûëfp\]«ÍcY`šßúúVæüï_³þ%‡˜û×qÜàÞ&΀[læ­oÆ:@ЦC§‹MMÛò©Ô¶-¥·œö?=z¼Aè€7èeüP¤ÜhhbtÀ@h€Â…ÄÙ)s¸çhjZæX† 78ÛŒÚsì3@õ7Êœà%ø:S‰UTèËv €+Âý @1]“'1NÿƒPìdÌ@µÐ{=y´œt{N;Ú-+cûff‹,!~qj¼L¹ÀÚü4:ÇÍö¶·$o™§¥ÉÛ.·î<û¶ÎîZ¬œtÅx=)x•ä±ÉS †ýÝe÷&‘ÝvpóP÷|{ß<ÉÇ^®&¸’„Õö™¬J>'ŸÚòªQ€=NqÆT¢ü3ESUæü}ÍþN ÅàQÆüÙGãÇ2Кý5ýëHš)H,:ÈK߀Ç¡HBúÔs çÀ›Ê^xSßÌ_IWpa`|ímw´Eþëæl|ÁÔ¯+Vè鳂¼û®‰Îy{Ý2dös2òO¿.äñš€QCœ?µjËßi¡0‘šÝk%0>øM¦ùm&ôïпLõèwï=Œ–¿½w?€¶¶÷›íMÂcØÚÜC`Ù(…ü´èLùžœ Êö;4u‚]NúŸž=ÞôÀñ~x"Åvîhhëk#:çcÿcLÉ8mM.VøXâw:ÃÔ¿²3V ¸Ž0,Ø´Ä ÀtªxœF!ÂË™¿Î ’«Vj‘+cèæ"­Nv¿ê…Üa'‚¦¬@)‡œðßñm‹ÊtE²Òz@êꪳúí4â¶<ŸÍ–ò81yM€JuAîœèº;Ù{»{ˆãäæG3º)dä"u±·XX”do™U@––.¥ùÝ {Q(üç"- ’Ã2LÉcd–T&3MTP!žk@?Ѩ# ”ÆŽUʽo@(ÁÞOë[›É;±"$×(G@bFà<ê6ü ^_NdÌÂrå¡â––€’꤭£>Tö?=z¼!è€7äEüÐd¬ÒÛáÿ-:ñ9žÚ‹ñ8ñþ'gXˆû?>=‹p†Ö¶F\ÿkógFDmWƒÓÜ%x¯p¸VôqÔ’¹0wáQÌ>^äbo ŸeÐSŒð¾xŒXçc\¯ÕvD ³snIÆå-žûZ—ç;pTÓ« ‘6öyí8Çæò_%¸Ž¹i¢ yÆS*ñžynRnÜ<¿<ª¶&©­ËãV6Xæì¦óYÏ7_RMÞËq·÷´-Üöt4Š­ÉÛ6$CÔT‘5õóî5ϳ÷fÏÔÍšî§VÞN• xV€-@‡¿Íífk«4ÿý<»µƒ¶Ðonïá°N |6*¿B€S]%²"24ÀyY:~‘6³O=z¼!è€7äEüÐdˆ÷.Ž\3œóægDúÃŽ?99á|Fö€ÿ€€+ëÍ*Ã×Ü¿"¯Âƒs¿›`Á´3gÀ¼¹,÷ÝO  ²é±ï^ê"Î9EO?‚#f- ½«à|C’f É4í×a¦𩧦äÜL‚'œpPžæ\𔡄¥ÕÙ¦Vd‰–¾& ·‹h,p®2;Ñ ÕXfêÐÛãˆ3m9ºûdrí}¶s‚·=¡‡ƒ,‹@æXNÌÓþõEˆâ<äx¿}&ezÎ&ÞèÊ3{—†TV`ï¢=øŽÙKŸïÐoA3ÂùbÝÑé°âö“a`G€“ß¶€é“†öî!ŒÈ³Ožu†v#0xoˆ À¿ŽU ³bq(K@LA2»O=z¼±è€7öÕü„©… ¾À–@2c`œ!€-ƃg¸¬#Ä'`Ƭ€‹Ë yp¥ä›íÏ}‚õ€:‚P…¥+YæPíë[©{/ÅL&§ÁÕp™ÚrÏ2ؒؗɿ¯é/ ø†~/˜ßs~â ç‰É2 ²;YžKÉÛîÙ%XsÔåno¸kèHÊhï N5]ö6Sxõ*×¼XLZ5_Š2M6'ß­‚»Ú—¶pª¸ êsìÂMPw_š¸!¸X£A Ñò•oî¹æT¾XÊ`¼kL?ðÞêjiîjðë †ú]׳Ÿg6°¸ °¡&¹­'AÍÿNÌØÿ:eP^‚•塆ƒ ÖäÖ§ž=ÞXôÀûjþJÂì{ÙtôëtÐC@ev~ÆÅ«æÝ÷ø½nN¿âÚgÀ“æÕé!·0ýk橦c¦t©E‹×È¢‚$µbSMœó€s/±µÕ&~¿® ú#Þ;“ ›¾VcÐísæññ<j(¨T •‚3ºº+E=ù- ­§³.tâ¦8èê’’$Áßçäƒ÷=¥@ví}vfÎÜÀñÒr§dô’Ázä—3%¢Ås­HœwC2Êzäÿ•Ë1ûÏá ²è›¡%ázÕàU"¹¶†£§¦÷ ø6·r¼Ž©^€¡s C¬„cÜäGPGsw¨` ­~„°µ»Ûl³f„‘#ïß{Íÿþƒw“_‹@ùð<ÏX߈¡¥Xê.¹b«úÔs çÀή¿|ÃÉìÉû‹8@ìò¬ÑÐ\¤¥CÚÖž, hêWÇV›vl?óß96:Р¥BiòsÝĹGÙøYÞ®›ùí~µÚ±dllw)1ô~D–è}“?5æÛslj¯wVšXIúÚÃå®»·¼ð]ß's属®þr*ìjþfu½øbÝÜO5èö­7P.ÐwÓøÔÞm—y<îYí^“þªZ> ­åÇãXª`®;Nï4>¦ý9åOS¾{6‡ †Þ!0(`h]РÉßalÒß~IßÅÃþ^ÏžozàMz?0-vü.t¯¹‰ÿ¢Yɪ{Óæåã§àúfßQspÿ~³Ê½ës§²"àô a£û)p\QÞÔb• Ò`?&…wì×Ö9ÍeÌcÞ)‡ ¸Fè¨%@?ÁÛh¬3Ÿc悉L1וORNòœÚ±ÏKOvhÙÜäÿí$$™ô·|c(Ü,³Y§ÐȾ۔Kl³ç G¦Î"‹Ëü•ÇjM`p’¦{‰¶ŒY»*b‚q5«ío‡ÔÑ6sÎ)¿”ÕÕëýZÍú`L@žyú¥í·àn»ÖѼx²À]ãñe ðžZ{žã¾û€;×F˜òwötôÃITÇ¿ì±àà0Àš?€oµýMòDhˆP݆Â@Ÿzôøñr ~¼ïîOR@ÁÊ3»Ötwþ¿±þ ó ò>@Ñý ‰¼j Á@Q±¶>+­Y $cR'Kе3™K×àì+'û¶hïùH’„˜!›ºã¯ï;¥xù¤ùºBº=—¾–¼N>w6Ã$àúhýxP)׺cN<·9‘RNåȹùÚò–åt7ÈVlè2°O9Šd]*!"êýâ“C"\á¿Âi ÆÎ5éO>nzGÀìÕôç÷]j†Wˆv(kˆFϾ–òm5ò*ÄKk€ÓA5óàGó† Zƒý¬ÇYíØ¿¡€­[Òz-§O=z¼]耷ë}þ‡­ï<"(Шy´³ÕœÏš½€{ ˆP.Ø ^£Œì‚„œ¶Z9º¬·’¸Xô¤òê;ÀsdÐl^ÿÄ@ŸáZr×±€ÚÃÓ U§i63%™)÷¬£žp“ÅFŽ ò®´d·îÔ—»ØœœZéÞšùM].G¬`⺦+¦Eä“Árà'{hj[°Š‡Êi ÔC9CæÖË{µv#øÕœýÒü33@!C€úx(‚€f~ø|ÇôµÈG^…½ù䇼›í5­:ý) ÄçÁÁï¥O=z¼Ý耷ûý.[§V·¿Î½ùé‡ÿµ¹Àp…©zçÇ8ˆò³MàÖ`©àE šr~•Á ù àÇ—Ñh55+ Y?àŠ¼s¦.ØfkžÖ§ ²'à`Àù¡„ÖÊà•$¥ @×Tkä‚-{5òö8`™ãÊá¤{Ô¼l>“! Çï”ÀhÛìW ÄãùhÅp»5./èÇ·!¸É×mël^Z¾ñÜÔ¨wÓþJ‰óìcîç¸Çz´Ø”µÀºÞºEzé8úQŽóù¹É7õÁ¹0ðz-›îw´P¦ÚþŽ~Ö©@¨°°á4@…Ž6,³òŠúŸžo5zà­~½_o\Ɔéà|0›>œ5£" @\@ü[a…@J¼è®ðÌצä°Y,°€ºgçŸáž¹¨ÛçW¸že}5 ¬­Û)d•Š‚Ÿd 2r]š;§¹ÒêmSr…FϼNÖ$ °Ž-“+‰ÿï5èLµ[¼›Ö‡T% ü =<¤ g?—¨É\ˆUÇjÈ-Ðz/{¾v“ ŸìeœæzË[ è`çsƒUøËjí¶S ]óÞ“eól9òaQ0j÷ôÚWKO~­ ÐE´D@Pè5õKgÆòÙg(Aƒº¬_ EY ¨×À@äq³}ê9Ðsànp îÆ{^¶R-ïÝwÚ\²4ðÑÑã€ÞxrÒL&j¶hâj÷«„Zý‚5fÎ@ÄÜ;®­¶/‰`sÔv­^Ÿñ@µÖš %@-·•œ‚?à ØØŽÔÔæ¾yð?D«æGxt<Ý}¤AÎ3áÕ2xÖ-S¼fd[ f?Ès®cÄ5Ž=­Ÿ<ž'´Px½€ÏÒµ ´å©ÎßJ‚©&u5ã‘xàÅP¤³ù¤åIG´s(–'šü (Cà°y 4m(Pž‚„À^CÕžå€Óù !áx‰Åo„?µ}é¹±,àä­ž{Z(kmßçF,•!ø0ÎϻۯÀ{å8h9aÒ­V÷‡=z¼Í耷ùí~KÛ ç{«õmažpAÀùBS ¼ef Ìôj¨´ ‡³Î M2>É­¶K.LÿsV¼vÆˆçøµÀ7§ ¿Äá@€†ý/ø+Êö¾Â€ø“U¡{…:*( Ïn–iùâ´Ë;àuS€Ðó‰UV0cܧÎ\H°M$„"Á™ÒÛ›póÜUh¡ÄŒÍ–æ-õš/ Y±p•ÞÌ}N!#ÅBDòB_ç`Gc¡m…€<ÎÕ/ \@Ò\+îÙ¯óñýmFPk‡~¦,èKA§Ÿ²6x×–=äyßIÖ€·Ò× ÞªýoÏžw„½pG^ôM3+¬C»»Ï†®ñèŸâ3»ÀS@y8¨Ö˜¸Cœy\6X­NJ` '(ÇèK,‚ßB'8ö‰0tÀ”<”å^ÿï)EK’u@Q€0žú¹§°P‚ªkê"¹êß @ ¶£!—@P€*Æœ¤ªBBsº xš7å¤:ž¡ìE/è™ÏPJ‹íÌCwï¹×nm ™?Ž‘Ò–b¤…r|ÏÉ•ç4Ïkü­C뀛åªÑÇ pS!àÇüïyÆëñç¸# ”&_Ž|{†(kƒÅJ`h€óô#¨2J€˜>õè9pç8Ð wì• j†}Dîß{ˆwùðÅáoqÁÀŒíOÑÊ÷<Ó5÷h-×Ö ˜ê,÷ÓKÍý À’aÐ 2Êßu3šµÀO™ž;³À=õ™¾WÍ” ‚9wR~¡#IaÁÔ <ë3dÅ:PØíŒ„\Jä€jޱ¢%¸\. ¶Ü¯%kÖ’!˜Û§Ó ®”ªu€‡ÕžTîä7ÛÕðl³y\7A&Qú" 8ÌÁ3êRi9 Z(,›s´ú-ÝX¼„Ç®ð' Ç¹/À_Þÿ¶Ka@à2$ @ÐEôxSòŒ6~‰s¿Ë§^òõ©ç@ϻ˾¸»ïA`£¹ZŸG“5BœZ÷õ•žþ€öñšˆyàwºß*ѽ>{”ü :’¹èLfï’`A‚> %p^X€lˆ0¸âØ7×V9/Ë÷)‡ðŒcËÏ»)S¼÷Èÿ,’¢o ®ùGݼ~ìÖPæý Ü•¾– Å$¨G`pÍ9àî¹Ú9eÚöB‘u.ÚÁ3_·-Ø3ȯ¦­–OM ƒ`!^SÛÏÞ苜ÇZ  `­¢CŸç((´•–ß=u°ïIcÈrrk ¶£"Ôøž¤­O=zÜiôÀ|ýš@³·ÿÓÂÉ‹¹pàxz~ öªÉ¢½ŠÉw3ÆãÒø/Fg±\N=W0Ð|-P»ùÜÓ Ï#=¾S;`‚‚ #Ï™›épÄP«Ž¥ÀuÒCžw)ÓöÝ•ªÍ3ÇÑn“³ T \×™rÐX[ÐËTÁÝ‚ UèÔ¥(æwÚ#ŸF:ÜѾ £»ÞÌi‡¯ÐG¡gDtEÁ™²YŸŽuÙ¯mÕg³|n¸®3 ‚cø‚2ÏY×ømMø %È”`]æSóÏÞ˜\ìµ\XN'œt‚Hhäzê‘Î>õè9pç9Ð wöб­´ÛõÑ@³ ’®eþ~–V)¨2ýOMÝñz¦ÆeÀFù è|v#8fo* æp´ß€* 8 hÊ WóKÊfÊ_´tê@ Ð!PÀï™CœwB€õ¨M[¢Xo¹×ÍAÛ«Ò,ð:Ÿ^ÀwνÚyLðÞ¦L S7¦oÛò`®Öó]y¤ÆîÔ;½÷ÊðšIP¦²hð%d”iÝãÄë§Þä‰ÄÐî)õCÿ|àî€YÚx 5åW$@4ûag¶gß|cD€¯ lŒ€+(Hw9/¯Zþ´mìw=zôè€;ü <"ÓÎî}€ìš©€ñÿdW­[ÀwU@÷+¾Ñ¬?XÛÈ~Ë1|¹Þ‚ÕŠ¨Ðò%G@/€®Å ‘¿³È‹>õè9Ðsà6zà67îØqBi #¬byižX0Åëdo|€Ä™£Q `%÷ãD¹Ã|jµJ54  «)_áÀM¼U“ prÎ~ÍFä^øj·>ËC®{ÏaA­5¯óp€´jXþZvÑ:Rž±lgh˜C·m×S^Ë@ Üã¾ô…ÖÖ‡@@…ð®åøœSÕm%u]^©‰›O ‚ûµ¶þ4˜'øn-C[^7¾/á«æýv1öúR°<ë`_Ö‰¬Kþz=ô“Çäõ>õè9ÐsàÛ8Ð ßÆ•;rM-Ò´±áŠq‘s¦F>5@³¼š¿|‚ï³´šòø¢¦ñÍZ³½­X/ðFÛå¶D@o¥>5Z‹I“>¿ÔQfxOr%S=v( ‚„uP‰à'`Fx¡BËñº[¥V(P#ænqÕ–Ê̤£€÷Ð’Ý+¬ø|À³åLÇËc7ê©íË@Ö Nв4SÀVp&OÊ·é A´ek·ÞbÏÁ{­^ó×÷¢ åäù´¹, ^àmæÿ³×GÀsiî,:ýõ©ç@Ïžßž—ø.îÜ‘{z÷™6'u‘äJÛ¾H5Q5èþs¿ÓÚÊ—˜F i³vÅð{… 5kJó_€RÞ¶ ^q°6„ÑE5Ëɯu4,!Ã!À³~@Àó!"*U)Þ"–… ïîPzÖÑÁ0Gè lµjÿX5é^OJL¬Ô_C'!3mŒB¶9¶S Ö Ÿr¢¹+Œ´«lŸWhˆå½ãõôðG ó±­údØ‹À² „ä'jcñS­ÞC³m0yþ6&ß)Â%ÃCíIíÃcÛ¿óÔåþ·ç@Ïoç@/|;_îÔUÁ" ¹RÜb¡o@Í ìZ¹i똧Ÿ€p|Ø'þ?ãó)§ šï´¾Ò®[¸ÄÔTKcux ãî°E »}^@·«Ÿá øk!p×¢©“»fètHÎXn@/@n+(Oºn6W~®YϦ¤Ü”Í=ÁÖ<-Þ„>…ËÔëëõ ð –ÃK€»Ú±{ëáQ6î3¼sŸ³=ítÀ¢!¡2Ìë~5úÛmà ù:à¿}ïÆbA%o]R œ1 c:7ÇGOómÎfZ®¾ÚØ‹0µ³sŸõ.öóMwÂÚ[Lj¾A=~ôÀÀÄ{°ØY:P@çÜÿi\'@z8Ò9ð:æm€å€à¤áJÜͳX8Æ® ß©u:´™WΕõ êTc®O2Q¹WÂG [¤äYÁ1åxjyjaj«Áw×ˌ㗞ÈUyÊéæåßhÐ%0P`+‡˜Ì—T¸_ÇüV›x`Î0ôÕ€‚DkAÔ[“=yÆòp€ž B[!©R¤“ÿÒïÿòºâ ÇËò–”¼ùæW²YÌö–&¿µÉä"ÃIãñëæüì°Oˆ+qÂÐÏŒÙò–u'8_,´ ¸HÕ§ÕÍXl·6Y Éá „³î}KÙÕ7«çÀ÷æ@/|oV½ýW¸ àÒQÖx¿~í4¹ìÕü ä£&®yß±l† pþ˜q­´˜×2õ7ÀP0Ì3¯åT€«N¼–&Ï)0”i¿³ˆ¸uϷᙿuÞÁTËËÍ›Ÿ\¨:¤#·{/¹Õø(„}¾ÀYð±¢ C(ôXâ7 ï¯W5–HÙ ·óò#|´Ï‘#í÷g àõíð­—{ŒïWƶLŸ¯Ú—Õß óqJè³gŸ4gg¯šÓ“¯šããÏy!|ƒ³3|$V›÷Þ{ž¬4¿ÿì7ÍÙùEóä1*SV£fwç'Íææ~óñ?üÏÍþÞƒ qm" ô©ç@Ïb™ôLè9ðM€0-‚ŒðuÂ÷º÷šÐ+° R‚© %°{­VZ:±B‚yÐzÖgªü\öNž ðQ,£ý¹Q‚C¬óÕò%hñ8×ΕV_5rª–u””@µ v´ H3 «@»kÒY÷hó•†ÂŒä^IžÎ_Ö†¶LÊUˆˆU}ž±HŸh‰ëE/Už6Ó×ê¨çîÎo}+NCüïŸ^ž°3¤tÁû˜2‘Ã5(°žû9Vض†Ð4p9k>’+V¹œ!$h±_Å¡R¡ÕoÎïZa×Ô½œô?=îzà½ìïßÔŠ¤§|è¼üE–ùÌý\@ãwç;ŽJÛ/ ‚×Èâÿ@OsÂ3œ×yhkulÆOH×7ÿ¹ÈµeA­ön¶\ó žIù[p½­ÚjܾrÕCšõsÞ"G,)…£7 ÒÖ·i¯“§žloæÜˆ€Fâ«»)]Þn˜bI#Úœ\j$Ø’­£ Ú¢ïäNÐ×ÑoÌØþ³gÿÞLÆGÍ‹çÿÞ\N›V@<Ø!òŠ Zí…g«WÄy€•?yô^sõÀ/­bPL.gÍ‹WŸ5GgWÍ«—¿†—ÃfgçfwïƒfkÀ?þãÿž@IF[ì…€;ù©ÝùF÷Àÿþ#t0¥v*@©©w@U¿ÜÒ᯴èhÐæª£iµÅ{¿œWÙøÚë+A^k+G»ª³ÊF;Ò„Òî:"^„Ä,²(rlfÀ¶k‡fúºT¦ýÐÓ‚r:W¬"?fí*ëö!¯~yÔµ4EÖ ë¯–ç,ËiëZÞüæùòÆÝ8кdrvÉ ç¾éô‚±ÿcÖ¨@óŸ]4× !Å* -!pé`é›p°ÈÿN™¼æ•æ[c©CWk«¬3á¤Ò©³JÖšË Ë+Žã¤©a2Z¢©†þçq îÐËþsšÚu†5¾^ãõ]<©’:Í•Îø6~[=•µÕÞ—@Jίcé·=Úf*p¸Ÿ7Ïv·è◇˒¸âÅÔÃO2´¹–€û<Ëgy¬{îÖµo~[Û—ÍZÖñͧnŸ<·²¿‡×xö¿´gÍW_ýºyþüÓf6ÕÑïÚþ‚ñû fŸàÈç0“‚CKsbD´/4ûL)åH“¿3=6YJùç?ù)–+¦°^Í({ÑŒq&¼ÿº9=~Þüö7.ò´Ù¼ûî/2°··Ç¾¡òv2¹oUϯq ¾ÆŽþä88 f †öM˜ÍXwoºþ#Öõ¾?µò³³×ÍË—îSVJ}ÐþÛ”±”y½_À&þ¿©Ö€Ðès ù_¾~sŸ ½"ðQstŒ§ÿ‹)þüX˜C¨ÃŸîß¿ßlmme[__ç^EŸüûò¨¯½çÀߎ½ð·ãu_SÏ;ÍšòøŸóÿ9Öq¯üü±P–‹þ¸ ÕÉÉ)ÃóæÕ«Óæèä뜅„V±6Ç A<ç‚?««Cþl3ç7€oè_¯¹iÐ Ð §¤¯öoÎ^ø›³¼¯°çÀÝ倚úd2ÁT÷½«Mþ÷Ù‹/1˯6ûû Íë*Dþcž+À}:ce?l÷± D@ãgºß•Kü\±X(ÿÿýëgñôÿ—{ÂT¿1N~Cýa8cq…(…`oïZ¿SþûÿÝï¿ÿ>Á†Ö›?ü0ƒƒƒì{‡À»û}Þµ–÷À]{ã}{{ü9°‚óšøÊÊí-/§êé°¶v¾` Îy®Ð§–?GË×tà?œ<\ ¸°ÏärÜ\àðwvÆÔ¾3–ž8ÖÏÌŒ ‹…ùYŸ} Ö×7öjüÝ@§õ{ÞùôÇ£¯úoÎ^ø›³¼¯°çÀÝ䀀<íb‚ÿ V€5¦é=bœþ¤ùôÓÿО4ï<5ë«Í½ýVÿÛÂ<¿ÞÜg? ÑÌwä³N}¬èwtzÒüÛo>iÎ/¦Í¿þê„ò®° )g„€¡‡ÿj@ÿ¿ïx¿¦ÿG5ï½÷^Lþ}ôQÌþ^×ôoøß^û¿›ßæ]mu/ÜÕ7ÿ†¶»¦‰ý)ânOÿúSyïú}µç{ÿSœ¨™pÅÛåxüŸzèϼ/8»œ´V€««²œ_,2†¿¹nÈ^,YÌGǽ+âhÆg°€E{®‡Ä`¬_OÿñxÚœœ±´ïÅŒå}Kó×_@³¿V†55]ß­óöw¯@ÐmZûïâü™ÍùA²ÿñ7_ïLs‡C”ºWôG7º 7ºwªðeºpnòtOõû»Ç^¸{ïüïÞâÛÞÝcèfÈ×É„…`´ý’ì¼nGwÂW—ìä76ÔÜjýö›Ž­Ëñfí¿ÙæÛÔýgÐn}n®´'ˆL‰Ÿ :-¸Ü"@¾ÊkÙñòU‚䬯o‘Ãë7<¿õÈ_}èû7ÙæþCFôÇÍã§§ Ìûs6ãó_£µ7YX‹€–ÝÎϦ„÷½@ àÍÿŠ‚®È,{„ÖÁOïþn|ßq5}§þiôÍcûþ–Óÿºï ÛÏ W<ÓnÖD¨Dôß™±l±ë½€'†AfZ¤ïHgïÈ5&%±Ë[u¢º7ÝmôÀÝ~ÿoLë °Ô/# tS²ÿX°ÓsU8–w½Þycè3 Lt¢+¾^ÅÓ¾ƒ‡ŠK N´Í?¾“ó‡=ˆ|++ë|ðwÎûçèÚ(€Whð Ìú3Àj%cý#VÔ@çÀ ¬GG ršŸß„QýʃßñüÎÛ_Wëßßß_^S0(߀ ôöêÏ+ÍvúÍûn]H:>ʇ3œ/–ô GɘºÓLÿ.Œ”hôC[^?úFÔIþf˜ù Å`manØoÓæ<××e}1wŸî6zàn¿ÿ¬õFS@N§†æiçÖuq…6;8¿¨å/˜rþ¥“×ÊŒ>lŽÖƒC×É] «´ ìC$ÿ5*A_VVÍ*=áæÖL½®§Vã²®#"Éݬoì¯Ìžß¿‘Ô,Â$¥kM‡ùÍçm—i™µÍ0›Mh÷„3´Tn/¦ìçhâjtá!híµíˆÕ„÷ö~B½•ºþô´«~ÍÄ‚<:4 ꜟÃ?´Écê^›L^¯Ñ&å¹ìœLG&!%{5L[ÀÀl¾†&½±q;öãEÿj(ÿ+¬>ki½î5ÏôÑGLÙ»lw²|θ¾žî—Ð ­ ^!Åö6¤À_Ý×ÎŽßÀZóî;„ÆoÀÙ»»Í.௧¿Â@7î¯éß:H“ÿÍ÷à·ƒµ…oÀ­R½/£ú^&“cÚ3åï‚ïbÎ7svö* Ÿ%‹á"Lö[š5WÓ×™ê¸Â»àÏðcÿ–¼ÿÞð^N‰©À¦‚Åâ‚ò©ãrØœŸ¾Løã!ïv¿“½ý›{÷´h ЂÒÃAøx‡~ú7~‡^öVS;Я½ ðŒO²Ÿ:tt.šZ×c¾}’òèè˜B'4ŤIg™úäìu:¹š‹@ÕA8ý>„} Æ Ð–(k}ë> µI¹8ˆ­í*;Í굤 ñÞÛ~ñOµ»};ò:Öômgn}ߌ'}»p‰sÚøâ˜û¬` fy[…ž‹‹×D¾{í+Íö Œpru½EÛGÐ Ø®V$ºŽ–ÿd½oýþ°Š5HMÉÇÇ/˜ ÿYÌè³)ü@lj¶g |Þóyï{ùI3ª<ƒëf ð®3>@µ¹õ>â„wð1;Ü¢€õÑf}ŸNÐáN­\0Nè_Æõ þ££#æöóÈ·sx¸ˆÆ/­üH éËìím#û ›>¸ðcî†ö ‡öqþ{ÄýLýÓ ðÿ°&ÿî{è®(ÈŸêG-7ꛚ3ÝÑ{§§_Ð^c# \óÞ‰|~þ’wÃwÝ ˜ð] úŽ(‹k×S‚ðW°rÍß÷‚M>Z˜oÁÈ{Çë«jûƒæbÎ: XœJyv}<´ÊŒˆ!þò|0Ü'Ÿ‚…Ã>Å—¿öý†þçGÃ^øÑ¼ª7Pµ3;=㺫ý@éäÔ4ÏÏ0]º ‹dÓq;ÏÛ©^W‹K4ÿWûfNçkÞ\YÓºh6Y ·²è ¶}[ÀŸªìåèÄÔ"9à:ÓQΚKh8IY×PØÜÔO@§³2KÎí$Íg§_E0¹¾ÖÄLgkgˆfBÐÆnÆg½¤SZýÙ”ÉzVµJ`¦à' ”i»|Ôbמ]ž2¥í”öP.KÑŠagj‰§9Ž6k§-8©•éÅn²n7ÁÃz·ð"åkmqÌØUîž!€èÜFôÆfKÆ‚‡˜m¦` H©ÝØÑ©­FñãdÒ¤f³P»ž¦'ÔÝü~Œ@6½ï¿£Em7}ü¿á vlSG™Ùó0?Ñ(¡ù“ßýŸÍñÑ'\¹Ç¶¨Ô²fÚóóÏ(WÇÄ.mBø{вÚÌ&%à8uMð´s¿œÒñC÷^îùqXA}H»Âîi+õLúøâOn‡‹]ÖéjÎUߘíîj–¥Ã†Ÿþ”r¨.Î_7“ócxk¼Ò8.VWWÒ„©tÍ{ßIG¾¿e›D éçÚä½e‡¿\ëxœ,Üœb6~MHÝÙŸý¯4O¾ú-ãZö?cNÿoá¥ãë‚Åwj9·uþZ‚*ï(ÚºàþâŃêƒ÷"œžžÂ÷óhÒÇGÏ344ôä·ÚóËDɆG#L©Áf£Á¹žksK à¶³ ì‡Ã)‚VËÀ§æ^bQàÍG° Þ@¾ÊsÜÞYò¿¾ýËK†)Økw˜g¥ÆTbyñ]„§¼3ŸÃE/{…­øÃ ûŽêÉ›â>ߎÉì©6_™üŸŸÜ¾ýã÷§…ÇÜåQ„ù§ŸL´y*q†3AÆN:¿`èçWþÍ2ù’| ¥ÒÛÅ÷Ço9zà-Á?TóAÇ*5÷?}úK: öG`Î\ð47în3µ -÷`ÿÝT]Ý]“Kþ×4.Í•™Sºè™Ø[þó.ùÔnÍÌâq5¡k€KÜ0€JoèÍ=Æ}÷Óñ_=ÀÜŽvýøÉ'ÍSľúêÓ˜ì?ÆðáOÿ'LÄ»h…[a@\Å!ê…û´ï+LèOé˜ÕØ`þmâø¶À!QìSm`°>×VˆV!ƒhÁvÒ¹þ EscK“ù‘f£c§,íäÀ,Œ©˜@6¿ýäÿ¼¾Êô´æÁƒm€mµ¹Opã1:sŸÛØÀ9Oð‚Glvú3¢ÞYöæ¦N_ëhÄ8íqÀæ) ˜^"a$|¬é¿£‰<ɶÒÜcüÜcµ|ßÑWOCëEóé'‡ÐûKÆïßkþÛ/þø¹Ÿðº ·…AX€|ýúß¼Ú/_ÁÞwx#8ÞVA©ks“! Ì÷{Û=Fú;Ü~g†hõk«xïîa2WÐ#¨S@® ,×|4§Ïx÷<ózˆÕµqóÅãY†/>þøãøèw ©ûû$ù¨©_ðñâÓ|û''¿çÛ?kN_òý¿†¦†o~µÙàeíìÔ˜úõô\߇oÅÿ„46à]ÛÆ²˜8Îîsæ`ƒöÌ–ñ»ó=Ù 6Ýì9“Ü·©(üúeóš,ÃÍéƒ †˜lûù¹³ p8Dû7zâ*Vù³±¡ïŒÛ% T ýï]á@/Ü•7ý´ÓNu<~Ív@½nž<þ4̇—xêÓuíãq=ÀijKçG$M¿éÚ¸Ì-ûÓº‹ŠôT׌ÕVZîQFŠ¡ó¨ÒÑ»·ƒl²G¬CöÔF¹ôxm§)ø‹(jØz9ôÓèÔ®šO?ÿ’Xóhp¿m^¡>j>úè¿£¹î5?ýéOÓ_]£åBäáñgͳ'Œ#3”0ydÆëÑ< ¨2€N©±cU#–’+;uZzZ}´TTçËwÍoò~õϘ§¡sÎxýêÚN^cÆÂT@íƒw¶›ßcÞ6·A –€iû Ú¤ü™# Ì9ˆ™ÿ‚̆XwXCA?:s5AµJ¹Tõw O¡CÞ 2 m^ß%’;Ò/Ï]}×¼²Ü2ð.›Ý{„ù=(>Æå;¶åËüóÍ‘x 8¾‡Ï¡½|u“=7bÈ!4áO`RƒwXìÕëCB&5/OÑü¿`½„YóüECût²$ÓÚãý¡U \÷­¦þçNp îÄkþK)Øé€FP’Ë#4ˆ'9 Y«Á x„ÓtãÑÑâxvRÂH™îÓaÙCÚ“¹KVƒJµÚc×ùX†aÛ»yÐvxuxó[§]å u jé*i;Ü-LÒÒåœû‹ÄØ¡_âÔ&hk²…þ¯ŸºVç^k—Í.Oº§êN;¼ÄÕÎÇàò’©¡''8+ž2,ÂÝ9Êxz±.ÁûÁ 4yÙýýuÕôû»Á^¸ïùÏj¥§öã8ÿññÍá+ÆÑ1w®âkt`[#MžtWtÜs::û,;9;¥¼qîN²3²Cˈª/í´‰£ L öj¼jIÑ|sUÀ¢ã¶§£ïå0=÷*¸‘Sê·OÕì©ùßèpvj»h_£æÅ«K4"†.¦¬_Ò¾‹eHX…Ñh‹ç·¶›3ƬÏΞÄ«Í{¦Œín6÷,gŸŽÓŽžj«jêÐSÅÛ·ìPÛ<éØ9Nîëäæ\ü‡÷ßcÌzÖÜß!Ä-ôìïE ’‰³Ö$»‚@#?¨• þ+`9(Û8¿d°6ËCð'~æ_Ê‘N•é_JQ$ßIñ®®‘±=àùîÐ}}ì5qûwv¶›w°œ_\5Ïõ0ižã ?‚ ¢¹CÎé×Ûk‹‹aóìÕãæ’a>èT;' ü”Ö QŸ§®z ²jßiÕï‡\Xò×y@θŽÀ‚ªxW‡ÇC„?épûSŽ:)>A;VóÉ4Öç|Ûxò7GXÍΣƒ|ó›ÌV‘‡Èlø®@€oZåoCÌ¡šEXE H¥‡?`Ëû9=«ÐÌ R_,> ­C„…¼ï´Œ¨Vk‘iÿ Ú a ?u*™ÿO9–zxx˜YŸ}ñ¼ùòéËæèøÏ§U‡ƒ5'¬¯oBÛ^¬6¾³Î'! éî zàμêïßPÇ>/bú×g1Ÿ;¾¹Î&çÇonÖ´*핎iñ O‚•X`a'Vš3ÀÎ=;·ŸÚnú7é4šÐ[à·"ÿÓ‰&š,ÏTäò¢…Y6›§Õ•zÂ}´c} æt¨vÂ÷÷vȰŸÑ€k‚å<åœ9îLu³#”ØBÍ5c¹ÓéfœÝNÏc XEH™.vp®Ó²PŽqoÆçψéð%ß4Ö Ñ8C?öÞË·?CPPț󺰵yK_ç]û>/ÊÔ»uø°CB…““} ˜^y„O Ã3+¼WÿF8nÞísŒð€ÀiÌ"óê§>§bvß@*“7-"ŒS– ®¯+%ž0•òË'/™ê÷š)²§®£ KÑè´?" ‹Ü ßÅŸþÞÛÉ^x;ßë_Ø*µ[¥XgqÞóóhUס³‹†’…b:”*<šªow²æ·ƒ”M"šéÏùï:$ ršZíÔ üËDª³—ã&€ly‚BD:9­F‡ë¿t‘U‰W¿–º¡„ŒÓÙ®3öº½=Äü©—4m¢ì3´1ýjz ÀŠÖê¼éUB/ÖƒÖöúÈ)w˜’1oß¿gtAéTh°C®NÚfÚX;îj´$Ò.ê½Å‚¢ë¥Í+L9ôàÓ‚5ÀAqjÑ‚ŠÓïL¶[-yvQ‘wàœnù»@Ö–2ÆÓ_~JŽyäß@>¦Ë&I[êÊYýäÚ­óo;li/:Á6,›×Ä+9 d([ÆúYÌfu@  ‹šÇo1VòTív„F®éy„ÌcϳÝB÷^\!^ažlíó^Wšã{™ƒ”Þ–_·—Âóå싼ø µäÖ€®Çòë;cêwÜÿììA¡X|gq ]Z[ðA+d˜(Ÿ]¾…* š©žÄjU™ï*Ó_¹ï÷­é»yòòU† ^¾º@gx€lZi·¿dˆÊH†»D*t½y¬3§ïÞ÷-s¼ÃSè€PÔç³M°gWt]#á¬y}|Š0 ø3óoÊÌVøŠ~gx¸9t£À¦QoæíÓ]à@/Ü…·ü=Û¨ÔµÆ+úä—‰‡ÎÀ4+Í“Ƨkõ4üT§«-¼úät†tºvlÂÞ€q^{%5~Áãèø°yùò9pÑ|õä5 Av8èd«uÙÜî‡Nð½÷¦CRK¶séÍ|‚œÃå5_ 7 LÿÛÖëÅ !vY!nWíMìtŠæú9íÜÂÁëc´èÝ„‰­ñ;8³áýGG©µà‡²?|NøÞ5ÂøÒ‹^£íîVöç?ý/à)ƒõ/Hä^Rà X¢ÉÙ~­­½÷äŸÉåp9Å”l9x ‚áš Ïfd Æè|´Y^l Y .'hz—VŸ½ªÅr´ Љo!çÝw<ôѰ~µU˧èðAb¿¼Ü×­d‰x¥h&¸”ö)í#¦En°Rà%föÍu¾œ ˆã¢=sÚß¿pyð€˜Ì$=õ]«a±ØƒŸDþcm‚x¢=<¸lÞyø(軉Y:ãxJk—ÊÒ#½aiöaœ7Hi´ÍxnŠé ¤5]×2Ø =Ý2À‚Üí$_?þ ß"N®_þ ßÅËæþþVóa/Ìwo…Sƒ>ÑV,Â*^Å"³¡3¦BWÞ•^÷äc&Šß̰’Œyö7¿%hû—‡Xw°P¬9«!oƒX²Dñƈ‹X×à`—è†÷òýßÛSèäýã‡:øVüN"ð9„À¬3†y~qøŒ¿ÝËæw¿ܼxɸÿaÃßš?Z¿š¿aÂsÁß]!Ñc×I? Zn ò·yÕ¿}耷ïþÅ-ÒËÙéNNuÒñoƸÿ à¯&¢çyÀDM“öÑ|\M/ÌOúdïV;C;̳³s´æOŸŽWµ ã»LtÚ:ê þ#"êÑuä6·ôPfqŸu° Å›º4æ*ÛfvGRHDèðØûm"›Z  Å8FLM‡¸Â86Pè5ÿÚóln:½mBÝÛäÑ“Ý0½hRçÓæõ ã·tý®IM‰â[HmùÀ¹$É%ÀIªrš\%XO„ŸmÉoa˜²‹oï°Šš]´;¡³'ßㆆ3„)Aæðè<ŽoΪØ@@¸Ä̱߂ï #s•A]]Ç^4÷¤¶KÅÃ:«v˜§ÍÝZrôÃPCÞð,ãÐ\2Mnq=溎Á˶€XA°Z†+À%éxc@ƒê\E8K¾ŽŸÍE­%æ¼Þeb/ú™ZÂaK‡ŽöªÛw8Ëoj·u)ôú½+ôIQk—oÊ6æy:ÊÍ;ƒV“´ÍwC¹NË”ÎÀ0ùÍLù^Æ|C8#¾:ôï ÿf(LÐôQÌá‘å׿°Å` ‡C…½KÞ«¡šµœ¬3<`Ì­ kY1‘:hœUiq[…¶Dqä[ã«È7 Ó¥ÂXþ¦kí˜?|†Bˆ¶ïâHn‚¿›ào‡Ž?¶»Owƒ½p7Þów¶RíÓÎP-èñã¡£zÍt³ãfÄøï&&ʽ-¦ú‘Ô:LÝ4¸œðS &ÀÐ9!$8¢|9#: ëï?J¹“æó/ ÎòñAT蘈v7#Ú_"–Ù™±irýŠ1×!Sãž<;Pð‹/+Þj>üÉt^ïÒÑéDW^î1S?}1u×fgi÷% deÌŸ! nª¥m0Ummå´y¶õœ0výu1Uì!‹ ¡ÙÖêq8ÒÙŸ@åÉ“&âÓFÓíùùs4³1ôìÄYïàþ#ênÇÓ­,4TçéoA~ýfNv4[ÔŠ6!Ý\¬l?½BƒsËs Ý®e¥8r BsÁô.@ÿןOýÒ °u®Ïû-9ÄãØÿåå!ÃJçÍ6÷ÐàBNSäqßÙœöYv‚>R“í¯ØS(32ª\¿³ Î}Ú9b âó—Ǽ§9ïHç?ÞÛD!A‹N¨¥$|#¨Kz§:¦ ~¹ÞK]¨çô?† ždH­W±l3 cÍ)…Шo‚1!ü6/ñ¯9:¾ˆp>v ?.ëãïF WëwÌ_ç¿në,ò¦¿Œ»•zàn½ïom­«—ŸbžgûÓà6™b¶®–‚ÔœÎÍŽê àªN½€Á.¶:×ê`ég£EÚ¡?}^ãÒŸq†¶:A ƒ» ¬®1öÕ ÔœðÀw2µ!Á×:D€m:MVÏ£~þB¡dBð:-¹ŠÜéeÖ›%Vò&˜‹”i¥ÔÙi6V¤Þ4}£¾>>!Ç”òOé$7ÓI&Vs¨±£¡` ârq1¬*í«Íóç€ÅÖ¬ùà]‡ Š5Nkç2ª2ÐI`¶’È¿u†<ØÑ‰·{UXÎå­‚V€Vˆû a6áðÄi™¥]Ðèèˆãg˜šéì5«__¡í JèòÈ2hâ q ¯šO¯"ìù’iñupN?YAËö½I0µç׳º(o=‘ðj[{`Ùb‘§U6×G¼¯¤ä›uèø&¨t³>4ü²©sÏñáXœ1|ñï‹% ñX×ùTMᆱ« .Õ¶BG @aRè‘Wá-g /ŒéÞè‰à¢å…Ûדmv¦C;OŸþúÖqŠ+ß^(ì‰ùàË Í~cú˜gÏå%x/È£ ’ç hyüä9 |ŠöÜ©…qNyŸ¬Rð` °8mÞ}„׫"",ù–]"F«]K6ü r\C)Þó“½Ýäÿ6KÏ>šÃJ—Xä™À&0¹—§~? ¾ãÒ2Ðÿ‚oãSÆË™¶v¬•â'4là¾+é m¾ÎTZTú›Sî; Õ§1.\Çqük§LdPCš‹n’"ô÷â∡“_"ì" Ïd/Ϻ"¹nÀ¦3³3뛀YÓAðg¤?߹߼B¥ß¼À¯ `¤0`òývB€|*€áþž&Ê¿®˜¨Pâœ~jÅ0FXÒ‡aJ€+§í²î‘,ç|›§."¸ø-t&~µÿnóš4Èk·>Ý]ôÀÝ}÷tzk;öø -ø´Ÿ)"k¼Óê6CM˜_µû¿t0ŒÎÑ~à% ñ çš^õ¿ùôwñôÿÕ¯ S:>Þ¢ss s“m=&PíìœÞyçeeg(p¨AÚ¾zżi@÷éÓÏ Ç7®úùóæ]ÀâÃ÷ÞÇKÍ×!:uh“>“禮c ÐÚeûŸ{º»í°ràóügÓ¯è`]Ûˆvª‰µ¥³”‚†¶4ÐaïÒ¶Íï>ù* pŒ6fLÿ½ÝûÑíȯØB‹?lS­€Çþ¸¢ ÂÄÙú ­Né ÃЬµ@][0×aÍèoO°7ÿú«Ï±Òœ#h±0”«·–—tß ÍÒª£vùøäÉ(wŠƒÄ)¾ ÛZ9 Ç yÖ Ñf)-‚ƒ@gëZ`È5®¨ùÊÓ…²^ Ë‚ë!^ì+×̨`ˆAIJÞ™Ô.}NÍSK”5NU|ñâçT…3æ!‘÷0¶¼‡u"–¤6VÒ×ѲJ˜’æøPE¸€P¨0tE”»ùLW(³^÷7ɶœàéøø Ö®çÍ%ÑþÔ®ï¿û3êÕ¼~Eâ2ÁyÖ˜M‘oÆúù¿È4MÊjßf¹é³æW¿û=ïå¢ùÝoÙ; ¸5ß~ßèŽ ¹üüç?ôÁ:³nüdSþÇÇ.X¥Ÿ³:Øä×Ñ‘Vª94k%™±ÎÁ x{Þü~{Âwg&Çû JÄjˆ§7Œx¿÷#úwææwaýÖçw­à{è5ÿ°ÿNÿôÀ}ýjCΧ´Ø_þŽ=®­j¦E›²£K§ëOáAÿ½R½/;0 ˆ1¹À9c,R'&ú.:65ãΩ„;¿n³Cê4׎N­Û½aæ¼c®LV+æ2¼ó¼þ¶'.J2-fåJ«Þê¡DK“Úžæ`Ǒ瀛u*€.ÉE‚‚š’×ÕÌb4¯:¿ÜHnÎFpì[„X G©1ðpÃ?A$BSË3ë`³&7iLµÄrÀ¹m6¾À0=ñl̲ cʳ {؆rîê4½NûWxé’Àb¤C‡ 0ÓË †Å@ž:%ÀÔÓѹ•àƒ‡Å3/‘ƒÿxUX*ê{ÐÊ †p–v*³ žûNÝGžº%ü2ô¸ðL/~>ºâ¿T˜ª¼”I9Áb«÷v·I]Èõún½ÐÕéÞwc–_ή+‹ Yå³…iå²Ì*2§Væ³–Á?v$!ß=;N¹¼`Ú[½‡Vê›·½‚¿mõ½øÝ»wë¾{éò=ùýÉ/?¿;éVÞWÓ¯=‹÷D¨$¸߃ÂÛ4û¢«ø\ýÖëwÑí=–&Ë—'}ê9Ð wô°³9<ü =Æ„ù9šë Ã*zõ æQ²º™$ $vúvºŒ¶¦o5ÔÓ œªž¿n~ù«'17¾"X Ù.A^4Û«‰è€$è;öh'ØKvžÉÒd§çöì™AM&äßEÂàÕoãL¨ÿ!&OçRë=Â#zZEhD h˜n@™ã®ÙqcQ czOã¹}‚æ5½\‰Ø všÕ×r·vÌòÅøû/_þ nèíÍüñ13X~cˆcb¨´Sþ t לQa #øç­PðRÿˆ}¾¤òëCtÍ 49n§ÝòÄ÷XVÞ73SNO¿j^¾ø%ßù¢yÿƒ l%°NùLù¶åg¢^gÈÛÈäoÄ㣓C,/ó?i~ý»ç¼¾£WÖ«aß ¯Æ-ðþâ¿È¾ÓÄå‹÷C7õû.ô“ðÛwo”Jë/}Ož°(ç¯_ûFÔ*à½cƒ 6ä­ß…å»Ú¥còüã z~/ }ê9 zàÎ~j°Ž{« ± c®Ñâä=^:;öB}ërû:»ÌU±ëÊdˆSÇs'ŒV(]…½üÕ„*I§ýÜhCZÔTÖÓ ä‚Ž•ãÖË®jºšv¯°48Ýí ‡­I¤Zì©ë'ç¹&…’©&—}{L>ÍËv¼±Æ`“c™ºÎR@šìd1`q7ÄŒŸ¢-¼ª¨#NBO»o«÷Z„ƒ[·»üi Ä 9Æ/˜àÈg˜ßñ„Uîð&×ï@zäOG|è:@‘¿¶Û|š¢½^!äáÛÁø°÷¤Ý-Éý’/í5Ï[¢„{ÿEåϾÍsk×e¯rå©ßVYTneËa' t–€«Å:­-š|NÓ¾ÖëT0ñ¿ÄvS?Ë¡ˆË{•´ö_åÕ"QSóüîÜä…ïÙ1õ.Ôµ.i]Êay÷Ð5¦ªm¯·'ÖÕnsÊ2 ã„÷cP+R‡!´”øÍÛ>ß‘üwóÛ¹}ì¹›©£ÏcŸ«wä ‚:Îúî]·â4`ïð -ÌßÚ*!«åçê*C0f~7ÿÖܺo¤‚º²­§O=ä@/ÜÁïÀ©FsÆ:_¾øíáKâîÏ›¦t9–¯I<nöÕá¥cµclSçu¥Y›§8—9ïÙ){¯_€ß½!±ÑÌÔú%Ç>ÝGÿÉO>¤ó[ov˜Ögô3çV«¥šDTP>Ü£‡rs®ûc<­WECVؘ`p¢k:xæ:‘AK«T§C¬ò |éT¹ öLáØU¨N¾™|ÎZ€u¿½½‰Æ2¸ÑÃ~ÆÔ3­ÆÏzÍÊJM‚u êžFs‰¹xúsM«„l]¥ ©Ç¨o<q1i~ÿåc‚¹œ7_~O¯¢ãàà~Æüµš¨á þî¥OÇ2µ½®½ä£1žCΗðñйûÌGMm[¹/ÿsÍ6”Q"F’G^÷Ýt¼/ Å;Ïy÷.¬t²‚/@³zÂ;qý< t›§Ò%è D×ûïÿŒ|Gø¼‡Iý‚:r0o+òI§Q„5x:€i.šã‹Ìl‰¼…&Þ±Ìæ¹!ã÷[Äð»“O[[Ì xÊ÷Ãì’Cøpúªfƒ0Ó>pÊʶ«ê¥n®É… ÄÃäqöˆß:¢M¾µî/2ƒ•öÐü§,¼Á¬ˆS}µë£> ðüqiàZkäß’<0É“Šüò]úM þú%¸×²ÓY¼fÀ¥—/_æžÖŸð-×ïAë‡~k€ßˆ¼°ü®ÎTØÿÜyôÀüì,ÕzÌt¨uÁbN~J;å¾= `ýuHÿZ)7ë¾cèÆ9ש<‘ÁŒî¶æ¯dÇ´»»M'ˆ†ÂŒ;,ëP 7Ù' ZÎ÷WÓ5ˆ‘ íÜ<¬–SëÐÀã-AÄÎÀ‡M¡9÷„ÍvÑÑw©4M/;ø/óQ†´è”‚;;{ÍdpW¾Åñ¬ùI-mñ9öÇ”v”0kŸ ¨rOà1¤«ÃNG“ž‹sâœêTçÒÌÖ¡S!]¥C>Ú±wÚ¿@×m©’º¼/‹å·š]‘-}-‰9ÍOw¿kCw'Âwø(HeÃzî;é´UÊcïÙ–ÛÉ÷í&j&¿fJžkø=ÒzÊ•Og½>ÚnyGr—¦0•׉„%OÜóÏì~wÖá;«ïf=.@Ål†\”jöo_ ’DË÷}DP mÝ–˜ê |7Ø Æøº”ž7åi~çÝ»qßû·`»¥évê¾YúvÒjáµN¯t×:>{.ýîm»ß†uZ—›õÊüos·?–_ÿâzž¼õ¸LǮˎǶóÂçDÿ[¹&¢B€=¯aK— nØ¥V©ÆÕÛ+¢—òˆ±ôËNíGz:£•æÞ}§y ÑF†„{eÁ“GSîßmñÂ5× ×ñ©:^ºmûÙ¬zgYðPpœýÿoïL»ÛH²ôœ$î¢v•JUÝ==ÓmûÌ/Ç?Á¿ÛßüÑÇ>Þ»gª—Úµq'€?Ï bQ¤’Ô*覔ÈD"2–7‚w‹74‡wö˜k'ÊóÍÎýKh#<-ŒÇй°_ f7íG©ñå“ÒšËïþ~5Í寗wP§ôkp¢+ ôŽ7¼ë íp3÷į˜¬Ki2ÍÒÁè­'ÌG¬ƒ]q5œ¬LÀ9ûáðÁâ0¢&îìGÍòœþÙ`ïöñ¨YêCáŠçw%öuS‰½¸\çaX!ÎüƺÚu)>fñXæª0CÚ‘A¹j*—AP-¹˜¹I›Ú p@un8¢ `Ò齸Àe]^¼“Yi±àV‰çà)äH(6õ(ãW…@wË‹±èO¾C‹!ïZYO¢‘ŽA—+ì=gœºÔuØÜ$šÞ2Î$ãX£jrˤ½S1-Ê “~ä£Cñߨe9¦ëþ·ÙÏâùöÓ¼¤2ͰI°*¾}Tý[¼Ú/ göMGÖïu‡õ¯ïˆU¨êŠ…zØ?Ž ß³–«À‘Ì¿"”×iR˜Fã¸7vøóµÚÿ ¡POÙB´i6ÑØ‹VrÎ÷Ði¥øqñ#(my$õçô;žÂ4ðˆ‡Aè_8R}ñÚZü£G„]U 8!e-Áä(¢µ»}ˆ€™9t!v¤ŒPË!Ä r üâÂ>Û¥ªÉ–MƒÜ$Å9x5ÏEÚä6ArµÐ©]TÑZ¶õÈõ|Öž6)N¾æ€z*H䨕M‡ºˆ €öé~íÖÇ •ù‡ÞN™ëœ0s¾tëò´ÖfÛÉ’jÈœsýAlœ4ÄÑŒ9æ1BÆ9BÎFuÓ,a—È{µ.>S¸ªåé´©³€ÖÙãN“m]¨G+ÏQï‚S±¬ìôH±¤Ž–€q@Im_™çÄyrÄúóã Œ™yðšÚÿËŽªíÊ dN.Ãs‡Á3´sq fì2@¿XÇ(ÌZTMñž>¯¿yS„€öÚ.ÞN1y=êoã°¹Ý`|bó!wúÃI’©$GpYj.ŽÒjeн ÚB ¾bp4bOˆÑ-÷éŸ=¼ÿÒN](”hº—1;0yOl[íŸÚþ—á3ý¼ >/Û¨à¤eGYOŸO¦õ]LjãÃqû&åNç•÷ó@ óÝ¿?iÄÂO$h…=AÐ+±ã uéÂêëRã–WVZã•wd"jY7ˆ:¶£?ÔÔˆÆ×MLÐ\‰KoLÿ±é$òjLcˆ-f}˜‘;ŸY‡(Á ¿¼P†š„å‰+KnG[‚œHÔÊ6ºü ÓÕ !_h5õKšX*¬… tZ¾êç æÄÿ8k“Jɯþ´\ïL&ßY`…ÿE|·mK½C ‰zñqQN½±’mà 4Æz`,ù#v²'‚þ^‹¨àâX½Ê%èž2™ŠÓü눼}mt<ßìQå ‹¶X¤`|q†vxüH•ÄÑfõó‹Ë¡!ËPø78Íýâo/aÄëòºC†$33Ò^—úwYM`Yæ¢%bAAŠJVaJaÆ\CÀ£ käi¡n UÛâ£éöŠÃ)cÎsqk‡GýM¦yE{˽ïx^Ö¾]êªß–`=g¥Ë2ËC—Ù"Ù¾ð¬}TMñ/럋¼g¸©˜Væîwñ»î¨‚Æ»(÷ºüóÙü pýšŸöeK® p†ÓÚÞÎwD+Û‡zô‡ª8á)ÚDY"Û*ßAÐ/4  ôP‚ÚæY"©iÜ€ºïøY󻿗ᇜ¹{™šs¶R×ÞfÊI?˜i=žšŸÝ!3‹IZÙ2Lçƒ%ÊÅ´«¦O  ð0˸5}²Ñ ×êÐG¢¸„¶[ÞãY¼—‹̾N=ã´ë©QV§éüEÂ+75J—Öièa ÀðO¹ZR`R òRØWä`«ÄÔÀJçX ,+-y5¤²KÔÛ%€†s}üx‡%8 Ù(p«8g.-¯_hûšû5+«i~ñÅà^–¹U…¶úNôÑ|Ýñ6v‡Ñ -\?„„¶®ÑŸ‚Çé†3¶Y¡ÁkOü$Ãv›á! ]Švp€IS€V…ÍÝÕä\1³Ì«‡¿…óת¢PhÑѯä¥uIæʲBÓÆ8àk ¨v¤µ9âI3Ëéõô6~Wàäò1 ’QÿÖVºÑ£^¦¾@Ÿ:j2,Ërõk1+äžY¦ÏzŒé‹-~÷‰È8" ²þ ·ÙÍp}}#îÔþí#O…¿Û7×õÙ¿ñ!¾?P®äd;<ßU¹W²Ï¯s‚@ sÒ‘37CBÆ OÈ]Dó“øIàdT°„ ®òm—Ã{ŽBtâ΄Á6Lâ²'öÈ"ò”ðTMÅuÜ2q•«P3I£˜aš¢ÕÁhÚü£tž{( ^sXo—$zJ\ È$Ïý-ÂýRéÂ0ã¿ã¤m™ö)’†q#\êªðèS°«Î}ö‰§ýc½ç»WazHÞ$3"ÀŒ@ÍK2Yâæï¢j–Ë0˜E°íÔö%|мJhÂÛ[æÊó¢ûs!Šðý`Ä2–Žû¥¶4Sbjlw¨*ÿÑÚ‚Pzï›2ÂvWÎóË”GɺõV'‹öqeÖߦámÈ äíSý¬žk¾=ª«t£ÐpJô¶!Öö•0X.‰}¼òÊ™œÞò+˜æœÿ… (”Xhom?Ê-m¿˜lçç¶M.cŒº*$ÃñäŸo°ñkËÝËsõÍ›eÙŸÁ]ªãŸsÿš—Õ´5÷^wˆ—Ë=··ÿ ÃÚé–åÖRCMŠÎ_Š¿ÄšŒD±8ÂYkòBí’YÊ]й³G€&¶ôuå‡þÄËŒ'§%œžVK@dsåñàïnåF9¸ÒEX æÜއEpµ>Ó™ `‘*£ßŠ]ñs[–ñ-Üårâ–¾ ›ét¼œ´‰ñ鸩YEW´xÔ±fÓútbÌ üVtÐÜÞ=S~a hyi kÌèµ~ý1\êç9ëtÈhòk"ðÁHàƒAýñä4€çŠÚ£D‚(–’UO’l¥%•éÊà·á$æ#~w$àÜh-0}8®Is Çæ.móò¢†ê‹gÄ p.×ú脨C×`h¾C”+c’X¶€‚ÀúåX˾tÖrf@‹{—hu§±6?˜ÑÞhÞ„ùת ›õö|Ó<œÓž:â[$lzOí—#Âþ[ÞùêÜnXíRf"ӯ竘‹Ì0˜ÿÁ6y=iž=ý3Ù›û·Ý‡`BôF01CÓ.}#ÈT#!žÑö‚ŒR\Ú‰4Õ§B@翽ƒ!±zv£Ì×zVÍf<­LT¨Å‘þ3âŸÇ™+>Jeã»hGrÚ.E£ÞS0(“‡åë#‰Ë†æŽÒOt’­,B)é̬„øÞö“}ZÊs§ANËòoÄ• ¶W¡§2~¯¶]‘<_9R ½ôê(ÑÓ^ǰc™&œgë0Xˆ_˜C5‰JMeÄAø¤Œ>" L*hbëqî/>±ÜõÒ<ï'±‘aT¢âîîbZ—^¹NÜßÕÔ$ÇUð=Óx¨€Æª¾ûˆÙWž†ÁW8`ïõˆH¹Uˆ2‚ ésÅÖ¥Žëôa¨Ä;è--½í€yvL¹ÌåjÆí@¬{í\®„;êWˆú¼êã"màe›ÊYZò⛥yüÂÛ‰m,ÌÊ鈣̟6Ó! ˜*\¯)Y†âYë®Ttøs¹Û1–>›Þ [äËNqO½î§\õíM1ÿ-¶m]/kµŠzÙüÚ6Íçü\YqÈþ‡0ÿ}S't¦›ÿX¿Z×ÊôÌçmë~[_DÔ<7îøî°­uUT˜.RÃ’§SJ¡õsËkqøÝ£~PxV“7w!ú’ÀÑ6øQÁâr¯¿}¥æÿsÛ\j”Ÿ‰À‡A €ƒóß¼5ÍçŒc¯öÀ³åí`–Fr; mZF­–.a•YH€‰H‡¦6½ì’,ZrÒnÉûã“'0®>;öYuƒ‘—4®÷(¤S" f"Ó+ (hi¡¶üfbž[¨‡Ìу¥[Nœoâ^lmË<¬€šXPïJÁyE& œrsó”ëB³¼JVêäþËÄs°sÝ÷‚Øu°KÌt˜ÿ±á«g½<ê…¿êF£ &çV+5y[íÚ,ÝûK;+³*iàSü„f cÚ'äïÖ6Súóoqæf,-s^Ù³j×WªL0¬:ìí°½ýuóÝ·ÿ¾±·KÞèËU–æ)Ø($gÀ)w#´žbU–ARI­3NYØþØÌ‰ßÝYOðùÖSpï7ß~ÿ¤ùî»]¬ôÇ©{Ë—0ÅG.=@IDATuþ».T3~ùtEû“b{ 2ÔÅñjÛ´ú£‹¯Pe1pœLLã#:ÂqÛ]RÈ[ŒñiÓº.y?’¦©-KÌõô?C{ò7ÿI4ƒÂN?‡Blùéâˆ42/–‚®÷úÎîú¨Þ!… ·()òV“ô ÂÛÚJo#c à„?Ž6}ÞçîQÀ Äù×þZ =.L¢$¯õ“èÇF=ä£ °LìöˆP·lHÝ.õՑ˹\Îv0¦ dV2J™Ÿçëˆx-Ïҧ€«škå220Ÿ+ۈŖdjîXHœ[6ÀŒBÌL¦j}d&Uó¯u+­5k µðS,1}òp|;¸Âš‰ïPÚæ´‹í‰-ˆ)? ®™L]£ |D»¹Êè¼·_ÐwšâÀ­™K˜â ±ÿK]µV”éŠiKÅÏÒ„… °lãåµTVüxÚ6#FbZ•铤&ŽÛøªüéЂû—·ù´_üfy–÷aÇ*ï“gIbºé£ŒûijöS7¯;Ó9å}"ð·D €¿%ú¸ly«URJ‰”fqµbÍœžAæ‚’ÆÝîäXüw®=øºõå½.ï`…µ³&ëýÃEœÎ\ǮƄùÙä!:HE«š¥”QJòçŽRƒ–zÇÄ4?‡ ¡àPˆñå•\®É«2~!ÄN_0 {¸ @'®Â¼67_ôâÖ™«jró×` Ö8ÌÉ´Óüc‡@w”‰ùæ— ò]F×ÓÆ+08‚Á*@•}ܺ÷ªv9­MˬÔú÷˜ëwO‡çO¾"¬;ÏéÇ}±kàGô½ÊÁøÀ<*Zj˯-“Cãõ‘ÌÛÈŽNïüøä)ÆqóÏz‚wØ<}Æ4ÀÀXún{«ã[ wkÃÞªkM¿™0´fÔËÓ˜ žŠŒ:݉;,Fí¸gò K’>EHñΩ;øé¯b´¿ð ÜãM^n Š¿Çþ R”HÚsÚë+ö‘Žªþ e1\Å/—Ú6ûDÓuœî#KÌ#øØHàcï¡wV¿Kâ%ó‘9:W®†x5ðŒTPÚ)ßOvÊ͈ïH9]a°jnøjN˜æÝ$E¦¤Y¸VØ_ë1}oF/;¦ÓÕûr-̼.•±”g?Í˺ê/àQ·PúË­=` î&(Ávu@¬tàê½ÏÔê^Ôvp°`*\¸/N”j÷:.R~ŽUYyOæf|zÏ S,:;+sÈ.T«œžS·Âzƒ`¤Ö?ÆÃ8Üã<@ø‘9ùmúsˆï¡S ,û[£L–íá§}xMƒ¦ö>Ìÿ0§¢~Ôÿ€ .ýÛ%þÎ;á±tÒÿ°šXG`u†óêwŸ¿¬o®©FŒ£‹ô0ÚZÆ×œ‹„Ek¤s˜<üKd!Ücó´ßc¤ræ|’ø»}ì:-b–V%óçÀ´åÝR¦9–\Màô@qf-¤b ¸hCIò}:vÊØ/âÛ1ƒ[’ççœ"0 ¥›Ó¦ºÍªÄÊ ±'ä,&öPeùT ¢*q•PrÊÐ|Xÿù¾Ôq‰ùÖÕ¢¸ÛŸ±ÐÖ׺xßI…ßñQˆ½Œ»l8S °×뉻õtËT…CKm‘qù½{n¶ÓA‹5,­Þâ2ZY©äuO=3™- f‚åc‚F9‰Øø.Q,L¥dUòŒÕ0e碵^Œ\[Ž3æ`€Å´Æ9»).-­„Wùô’:7ô™L[¦¿ÀÐÇ!ïG„¯!Æ•ƒf¥wŒWí_æóÙ2Oêç=‡¾FmŒC š‚H€eÇi0Hè1ëüGøKüåë'Ôÿ„Eâ  ,vp¬TÓw›b5àzj¹P(ýÕ–SJ{Å§é¬ õó¤.Õ?áÜñé?1ã_¤"aàj;øNŽàZÞ#/¦Gôyˆi/‡fpzF9ýä†PúÔ>rHx%ЌͶ–oO­áDIÚÈJP9+ ?kÊ£dõÎ?ó'ø„mÅ [t¡¿Û½A³ HDY%“ǧ‰@ Ÿf¿G«%^j{Ť Õk ¬„6¢þAg_€ˆøk|Ä÷8Ø1pÂÖ~+Ë:_AX`Îkk jf5¡/þüCÆ_LÓËÁlÔÔeŒ>»zÈøëÜõÁóâ¿iOÄêÆ.ˆÔ÷Á}ÌØÔ}ÍxFß«Z¥Dqöúc€ALb.¦„·pˆ` à(CÑ)1°æÞŽ!Ë]ú7À©‘0ᨸ‚æ^·þƒgòc´ð¿ åà°9oÓôSB:c²ŸõUñºD]Ï^l¹OjsŠe‡¶ñ øeÀøCÔñ{Îáð¸ùþ‡ï¨Ó°ù—?a]`…³ç=Ù³ böÃæ SF*ô|æ?r˜Þ<áÀž4 ¬TÊ›À«b~yˆ)iW¬9Nb‰o&^BÁË(…†D&-„@‹ 8:½á®âÕh»åF=ć_ãä}ã'Ī„x«TÅqb{ߤÍåÍ÷ÿ) B£Ñ!c毌‰ãfó†·üí¬Î~yoµ*4Tæ ¡äg1³Ba½o)²—iz[+䳚^SµKÀÂìBû…2w­ÓÌ9ŒÊyjoy•‘z*¨yVK€×iâk›<‡CæÔ!ò ÅYÑÀ5¨Ùø(3ß`eÙßYásÇ0¬Z xý"ÏëŒÚÓy €Úi™?C ²Å–©Èør ƒ¿ d`["=µŽ‡ÁÔÔD›c¶fþ-êê²;Vq×?–øÁÜWŘ÷ŒÐhþ–§Ö¹E"îD%yÔö¦}*,¿»‚ÏÀÉùï²Á >‡hüƒÐüëC‰ (³‡Iâ L¯}×ìï)Ö•ZâÛ¥VµÆ%—`Ç´³ö¯.%áÈ*æíçÞAqɧmªcTË%¬SÝð/ÚíØ4z¡ýÀ0.ß>Ä¥ö“i¸?³ŒÈ¿ µ~oÛ¾÷ýžñ ÔüµYâÖߣÑn´¸ã ;ž¬!ÐÜ¢½N_0vÁ°Nݼ‰ðû¾Û’ù¿_Rx¿ø~„¹«–S¦#A ³(šŽ„­ö`I¨ß¼^ÅéŠ U¦·Š¶j™››Cœ¿†0ýÛÍßýö_q]=ë+s¾ÌáçÝÑn…óÖáL¦ãéwÛ¢c—ŒßèzÞ÷ûý¸Ž\ÿœö IE˜Lv!|ÚqŠ×ƒæþá1 ä¼9Ø^O µ6Öo€Í­ÀçÑ£GapwBCWÊ·îe¹±' ·ZྑÝ"y6,Ìñ07›Ú‚á&>®œÀ¬ÝëžðºË ŒÄ´Å~¿9Åga¥sŒ¥c‚ŒªÐ*Cgºjµø*ô°`ÙW1æ TUXHgÉ.‡ì2}5‰j}t2þ­­ï`økÚû†=!~`œâü€!pÚ<¥ gì µ¶±ß¬ß@ø%4òêêíør7CǼOâ‘Çü#Àü÷qÛÂË?hÿ¶Ã)­°> s¸Šà%üàµh_^avN„ò´ILÇò=O5%˜´ŒSÂ{Ÿ½«Ã¼$Pæ«ÓY½÷ªö+ó÷*ó÷œûÀõÜLÃ$eºM³ 1·ö}˜‹z»»6ç#4A, Æ ’ ëØ_[ï$XòMtgEMÑ …??< dåÊ}x¯c!p:b™¹Yï±J°t‘éˆÎ¢ŒÌ÷I³ë,`®ÆWCs}]ÚWLøbÛ–CZÙ{ûJ|si¡ÿ¬£‡Ö†IL¶§±+¤‘G0Ëc„¦Qœ}–úa;­"ZègCÑ]9ñÓ Eµ¯K)ïæ3Z…@u[ë^Ûa[ÀÅí«íï2‚}ƒ>¥m2³Î TÅïÙùüW«'I´Ç k_ÅÃZu21§ï„‡NfØ1.¬Süu¸|¥<«ß?ìU'\÷xpinÿ §¾Žó˜pˆ|iL…vM#¶Â‘rÃwE‡BÞrÁQðòødHà“éêò‡-íô`$2q˜Êšghˆà0ý§ª™fVŸÂc¼ª]J‡Ì[kb•.¢M­¬ž67Æ0ÁŒã(ç½{÷‚‰ªÊ0ÞåQ ¶B@ÕTêÕrlϽ{wÆÍ×ß<Ç °‡¸Õœ?‰9ÿ/=ˆ4_ý…5í8âýáßrý ö)óÚwÙÓý^óOÿôO1Õ`Ý-çêayËk0´ÍU4IÍñú°Õ§ceIY0` v"ÀÁƒÔÊ1ᯕ)ßÿn…2ך„/¾±†EbmÔܹuÔM)œúîÜx ¯ ³wìØÈ—´v˜ë† º ³B –ËW Æ.M_Åì«éÛ¶šñÇF;{O >4lþÀ<ÿÎnŸsÂ.Î/2ÿïþú¡ãλ1­£–hŸj}ùÕ¯~þ^k ¥¨Ð[~(xy*M ÑŠ/"À”£eÚŒÅLÖî 1ÆB¡sžý. uzÚe "̰K¡íÞÙ9`Ü2ç}+R€}uóÖF0»cƇ‰œã÷ˆ}+¸ÊÛû.'e|`Î6kXvVWÏš•5§|Ç¥¦¾YŽé1XŸ½ï«cÝy~7€úîû?„æÿäÇÿÁôÍ}îR_}KºÍíw`þ'Í÷¿Ž ]Ç;?ãotƒ~üm\ý›õÐ pݘóc®H`®ºóU¹Ôt à¢6Ò’ÝŸ¾,qƒ"'!–2¶„’÷BCåÇp¾‚GÊäbiÓ¹l‰ˆ¾ïZ¨½NC— zâய÷ +Çï2ׯ“Û’KaŽF4œ` ð’X_ƒ¹¬mvK‚y]w¿:¢y‘À@Æy&hí»‘ƒÐqÊ\\èáÜõ­®,5ëK8#Ê`0Wc pÞz‰‹l‡‚–ËÕBO˜üÆï›o´—R¹»8}Vtb°(I#½ÅZÏ3E+v{=þ æ4 <òph»e¤ŽÛ./íÇö¶ÞÛ¿Z_d×õGü3>*SµuqС xyí¤/Ãé1 {Ú{EЇʼnÏþÖ2bÍÿ"Q¬W5ß¶«F“š¶üedËž43ÎjÔ üMÛž¼ùAI@DGÃ~hÿ5–‰žãŸÓYÄGÇqJ{{:ªŽà‡˜x¤w¬±)è…%åˆÚŒ,ìo„@ #à?t±á˜·²‰–Ã\q÷"Ï\à š”„Þ5ðAê Aú ‚Ò ‡¶}™=žoÌýk«æª Ï7VöšMæ†'½fx¤“ZÙáN"«^âX˜%Œç=jBG”?aiÜãÇÿ;L ;[BS°ž¦ÿç¿>#ÏqóÍ7Å ÿË/ezKáÝn_y|Ϧg:qã–w¢Â=¼ð[Dµã>ØéWØMNÛÈ?þîD&äG俘Þ`ߊ‚™/ð.šnXeÌG¶Ç•Ú–+DV‚Ì]{…sHB ìø]- eø&8>"PÑÞá{øJü@hägÏൃX¥›ËŽLAí^&¯æ/óWK4àóýþ¦ à@…€Ê¬£À·ú˜Œ ¦ºàB;¼Yã!ÉwǘÌ˱­Æ©“Óq`ª wBéŽp‹X¼6nPÏîmgSšSv•,ý\ÊUë/ýTž»\raÈŽï•¥“æî¶T†Ù®°üÕýÆl°åJÛ®äÝàðzð´=Øü髯þkŒõ½í¯¨ÿ¸¹³ÙkîÑ?úè¬ÐwÖññöc|;Žšþêqóä¡À'+à²}ùùç¥ ¯/;SÌ)ÌO_¾²%(CÌêôaý0]Ë ‚‘À`Ô =‚æú!¡«7|ç÷ ð<3N¼/wC(sòK05êa¶9†¸h–4¸Mˬ(ÿ}jC§§”pp`”<Âãw¨Ç él²c L¢¹wxÄoãÐzûp˜á‘S:Ã'Â×À$´óOi[i£°©Y3™j´¬»¦´? n÷ßùÙªej÷Ÿ©u´]2@1oEŒÈÆçöaôU|”>ò‘+,ÿ ž;ÊAx£Ð°XØ×üŸh@{tJçh@9hÒnE\CüÊÌô…ñËðõ¹¨QïJ €L÷>´ÿh¤-l1ù*Cöa8Zœ©{€!FœeܵŒ<Æ…Z²S^Jl¶ß<®T 3ˆ×ÀËS²O——‰þ‡#¡–¤èÆ·B†§ï|¨Ã²,_—ÝÝǹ„iî?£¦'ÍgwààˆŸ‚úòc“È€PGÃ#VxA’UþZyVW/­]ªîYÎǃ@ O_|šH£êÆ:tѳJýQ«°DÅÝû<:†àÅqÈåUAh¡—$‘ìòŠ„ ‚ZO ª³yƒ=àq¶Û;Ø Í«ß'&=yè˜$qôx·L¹[ž ¤³Ç<ÿ6ß!rýÇ\ þsüímÒܾyƒrÙ¯³¾š­óÃÛ»û¡ =>Ä †ìŽ{˜ÞÑf«I»0—¨öõà¡Gþ)ÌTBlù Ssa•Ïĵ~;Px䡂ᓞ¾Ð”M®qm jµ‘Dðƒ)…_|ñe§˜Ò1)u‘ÑûSatöc|E(²4e㇠x÷6^ßæ·¿9†Ñaî"Ôi¹¹uó3°X‰Õâòå—_†0Pµÿ: ÐòZ¬¬ÛKš|q85b[ s‹;¾ûïòð^}ͦz(ìøÐ؆ð¤Ðêµt|NðkzBÔJ†mœ¥0_5·6¿¶°"0•ç¥0þNø[¸yk• ›6"~ƒÁu7ýþ}ÀÒ:ƺX9Îkž‘ñ;ú—~_–q~´ƒÃæs–‡î2Öã yÒ|~ÿnŒIÃ3×~Ñ"rŒ`kkq€ 'ú‚¬‚õ­sþï£Îï¨é™Í{B €÷ìǜ턽ž 2˜Ë‡yÈ| ³†ØiG"*A-¬_†O¹x§–åv}}íût¿Y€Ù Ø%Ð5ÙZÔ¼Þ5q‘ê§´·÷¸yöìO6¬›?úžŠáAß0Ÿa¿uë3"bÖ&ëfBXƒîì!í&±ÎYB۪;Όk[Ì»Γ2Ý`¼Ó,«å!2(‰âV0=îÕú0ø¿ËêìƒÕ G !ìÕ/ü×$Ýæ£ðe]bNÛß#wû•—Ñî≉ùj”BóîáW@5!úK˜Šqì#̯¾ ’àj¯ÙÝc Ù…0ß»‡ó&¸éð'³wÉŸÖýh i¼§¨Àk>J-K¢ºóž³°ýúy™‰øùNùŒ›è‹s$oa¾"j çìé{„7rüŽ”qCÎm¡<ù8G+>çþÔazÌò”rÎCÐŶ?5fÄ6Ö“%˜rŸñ³c  /Óï^ÖþíïÌ׿·~7Þoaêf¨³%÷ñ3úµÛ|v÷ï˜BbɦÎáÔžŽùÜÝÆÉs爥°g*XíÖÜËa5^ûÒ3OìõO®Ï%pÅ£Ysø'¸^L è½î¿àO5ÑJf A ‰¡½¶``&!aOØe€…Ew¸ƒØ Q‰q+¡‘ þ\†Qˆ sº†÷4ýípz:ÄÜ?@s¾»ã®ÐÿÂGD9D ”ù‡—8¦P—A¹ñNÿˆƒ9œcòw `-˜¿@µ¼K-W¨â „.¾”Š_6åÅ;’Y_Œ6Ò6û=Κ¿ip¼O&2C äøRèàØ•Ù—£\ýŠ¿åFñ[¤ãŽ«¿oàK²€#æÁÓJÄÐÁtt¬õd`ãDZuksÛK1ñŠ-¹‰ á˜?8xÌß”¡ wéC–¸÷ ËÔŒV —•–¡&´Ã• 'üñw9è;åÅ@Æ<=ÏßbÙÁÑ1ïY—q¾Ë~}Ûvç{>Öó’df2ÅNà6Á#—bcýæe<Ð=¨ƒÙÀØøë¬#Ž:÷jЕBc¸‰õÄpçƒo¹gýê~³½‡)ž<ÔÊŽÑR¾ ÍÓÝâ$4/e¨¯AÇuÝ!°Ùl†oxÓ§ÿ€6´MçúwÙg¥yôÙ]„M°V”öruª@KÄ‚¸ËÔÄ“'»h»C´b¹7fÝÍ[,½+Q´q‰[^EÈ¡ó¡MGYäJË(d°åà*5ŽúxU €¡†ONð–¸ãŒæœìæ Ê¥ &¶®Ñ0,1>ù„ÑEMµí ‹qò!pµ/qÏM{/côKZxS\âÔÙðßüþb5À“§;Íw·žÑ¯,¥ÃCÎw`þ7›îÇêˆ÷¡-ŠqaëãZöÔ5 yh"öÔ n«rx¹£%êßÑe­ûÙ™!•—¢?'-"2ÖwK6´ˆxÖî²êž¯7]„¾æÉ2S&k¬`4 ÈéTº„Š©ï8+÷Y2ýƈBM/N´„€f¬ãGÀuîÿŒi.ÃD/²¼Ï¿¹š¿…ÇSüÙ(ìQ¬­.ñÓ¹Õí±cú ü´ëõt̬f¯ï¬íÊt/ïö/ùãmç'_3ÿ¸ý#?;[mnßú¢p£Ù~®§¼Ë£0ñ®Ü€f =µËK¯røu .Ä3m®>­-5i×Ùw #üë/ïAh9úÌØãûXþ/»ÈÝà½ß“ßF»†}bór!@æï6·2ÚÁPç>»ì´G¿ðv>z ¡›@ÄNX;ïzy–;-±´KªGÓÔÝ9QËCw§ÙÞÞkžoñ®ÏŽ€]ö­G*aloŒÇ @wC+ªænq›> ðë­GDZ£Ž“1ˆ ÉÁä ÿjÂ/>åyeY2*5þ­­ýXý¿ÿß×X$ŽšÏÜÃíŒ%‹÷n#¹EØÝ ð¤Û4y—27ûÈ+-÷F ÑOÖ‘‰{ÜapúŒa ‹Ç¦+/û–B¡ßïÞºÖã|÷üsÔüõ¯ÿ…ü—™?þG¬"7›/¾ø-Ž¿ :‹ W[þ²«õí¢±º£Ÿ‚dOÕ{Q9ÍCl+¾íM]¹R¾¢ Ó¤xµßÔ„Å„Éò¿æ´ÿÓæÇÇX‹°øüúKbá“îÁ0|/ÀÇY‡·o_sÎX>¥’ºŠšÖtÌûî­5|Nn2>Ϛ݃?ÁlW›o¿=Ç#ÿ~Xg-Ò{–ñÞï;¥uÔìí>oð'„ïpèX×§…[4ôÖm—ºá’VGX·„&–A ¨6—ƒÃÖ®íæé“ƒæçÎáˆi-¦û–Ø1Òi}9´vÕ%žuzçM„–YÚ–i>^Røxûæ×¬E=£7`ªhÁaËW™‚óÐ:“I?¤qõž³HŒ¥4-Q6»ïÉ\Ô $JΑªyì-P†É൬wþàS7ƒ9J|ÔÀ.Êá. ŠkѰ#Œ)ÓC4 ßï÷Ÿ"<†ábErvsƒ h hk,ËZg9“Z¹OPBþ«ŠS_бÚ'<°åÞ1܆wŒÙÝøñ]„bÿ»Äͳ.{SCªžÔQ­ö#˜)>ᇀECmMNaSò¤Õ¬,TVAFRuIoaLîFw̼'O÷šgVýx|ÚÜdÞ]F³¶æü,;¶‘9Ùq™9Daõ»?û<’•{¿’> @C ÞW›-ýeß/0Ù]„0ý¦°„×ÿ:åºÌs}ë uÙ†¡=÷Ø:vy¹Ó¸…Àt/òZ`ó'Ë®åG%ÞâC8ZHlùÅ¥àWš-ŸÎÚ&z–CTeˆœ::`ž‘ßa” 1jñ'ì¢xØ×A!Œì q ¡ÍŽŠ³V ~wC€:~N_ì£Möè×qøÜ¿÷üœ>¹~Ã$«òúÃö­Q-Ö1§•©ÔßJnfÒ6ÎK <ò7•· mw LYý lYvxlSÀìõcœ1ÿï³çÁN¢c¦Žó"sôe‡T‘¯æSX.%ž8ž£=úî&áu{=–¹ž9EFç‡`4iž?åïAcyy½¹wÿËëw¨g‰ŒéÕù}§¤œßﳜO3¿÷´Ê8þg§{ôþ.c¥ð%¶àyW!”*P›bÕ1ˆTü-FGò7„Ì¿‰ŒÿÀ(.Åõï×íº7Âa×9ÿ*ìÖi¯hh~|R¤ðIu·„Ì©€u˜xY4`Y„B‡¡fMí\Bsær)5 ihpµò®ßÃÙæB¼: cV¯·Ñ0Ú¬Ü_ƒHBÔ˜ÃDƒö÷›ý]æQÑÄ:˜cõA¸qCó¶šG1×JØœ>áuvBèÀôLp™Ú²;¹¡µ‡¹Ÿv¸‰O0xê 1•J!® ™ÿç±ÓÞBh}OŸíav7 *»ñ3Þ¥[2¯J eþN¨ Uíêð¸ ØfßõbªöN | +„ïZ¿ä THb®y5Ê6xÒÉ)óî0ŽíN„œÞ)”~_l>ÿ|œVšõ÷¿FãÔ ‹…«*È­ b.ñ‹~²ÀöùËè# ×.’“z•òè÷ ÐRl½‚™(pÂDô(pï³x·øNŒ›ÇL GÎMGa›i’‡$ZMŒX6}ªe¿éUOú8eþü£æ«¸Åac9¬ªÌ¿öqý=¶ï‘%B(Ÿ"Ø8%Þ ‡ýB›—++L pûPᨙ™S??Çâ%ƒ\£lË·wÂÊB^gŽ£ø5.Œ›2îmûêòfm}Â8ê5#Æß“§hð[ÍãÁÓæûþȸºÓüÝè?ÐgkÍg]-£ÅÄ%”=þæ8cZëÇáÏ÷ïùÛ꓎±I#z,a|póm¦Ñ`!¶Õ¿·:®¼7ƃ¿¹ŒÑã<,Ûë¼÷" °ƒÏÇ™;á™#_"DòæŒ9ÞC-6—%—„¶­ƒð60vܱeºwæÌ‡Ú‰Bù»ŠB Êá`ÿ;ÒãXœ\‹‡>V7}]Ôú]ϯe§ÁGÆ%™n%Sv©¢ãgì|W7{Š¿³R ÚÂŒ}mÜ´ÉDZÎbÌ3Ýeð#Ç»õt¬W³¿W¿×é.^ÎãC €O¬Ã%†ÎuCg!!:ç0ÆæÙSÌ7›ûÄz×,¯iÔ8è•ÊJèÆÌ ;ß?FļäMˆšå’Ì%ˆ¢Ó0¨ Ú¢ß×pSÃW@èquwº=ÖPëôÔ=#‚+$L=Ì“R:Ü8n­•%Z<¾Ë`Ô¶!ê8-ÖKÆî5ñî–yôh_% ÃÖLÃ\¶1ÿ?ßÖjözú¯äæA˜An§V¤I´Dqºîˆ6ªùÓÆ•¥[0€ã`’&>a•8©lÔM†RU›`*ßÍŒ°¦}´È¥å[à¸Iz±&Ø Xíï±·B3j?9¢Î,C{¸Éò­u4¸uø<Œeƒw6-´SS(ZGäÔʾ^ƒÉ-ÓO2ŠÚ†cvÑ3ýê15 ƒ³ÿðO0­ûØwØ­Ð)ƒ'ÏöÁñ›f›€K?~ÿU³¼r³ùwÿþ?8èK,›Xn“šR§Ú®|Øg‹¢ ÜfŒÜaÚÁe–ëGà¦YÛÇS§¿…ÆK}­©?9…µˆ˰ԋ*Æ£ðPØÕoAÍzŸeu“Ó¬‹?kþå/?àÉ¿ÔüÛÄáü5íŸi1ïÈÑ‘W2ìw-!šKŸ®¢á¯­.`5)‚„ÂôpP¦ˆFÃ?6#Þùþ[<øyu«ŽÂÙqâU ~LÝ:Ío¾ü¬YǯÀÛ]/ûfD?êl{Ä–BµY…°Èß“‚—®ãD¼—™2â«BBÇÎî ÙÚÇt—–.§$ÜÕÑý\¨ó_µ¼lÊ«¶>¯ó‰@ óÙ¯/m•„¢h›FISú'‚ZåhŒÓs¾:ù»G<´KF=8[Ì?–o¡‰ÈÜ5i£@¡3N…N–Þ·G!£åÇzZ´štM×ú­hd~S*7µN<fu-!Šy¯**`€xfêô‚ÂùaEP#RÃòTó÷Z¬"¯ÖþKùå³´¢-ŸJ±V¨ð‘éä$ä«õæêéG[UévBú`„½…:†&w¾ “pYe¨ åºÀt‚Q“ß`.kËlÅL?y˜ŸŒ¦!|ç¹?…§?ýóÜ$’ù¨iGY$VVˆú·ÂÌÇ*†6lݨ]fÚÅ ²A!£s—z²ëêŽ6Kj½eÕ… çu‡c© qÔ(Ê ÁÁúÛÙÔÉöXX›Êžþèïò>}j¿V‹LŒÛÀ»ÌŸ«é:æ;êÆŠ”#‚TYê3r LJ™¯ÿ´ˆDeÂ2byå—2ÂJé¦(W†ÙõoËz€Öë®UGáQ–>0µÏ9i§¸†#¦Lwµd˜Wm¢åÅûÈnvðÐ?ÑgqÏw³Štoñw¬ÙŸ4 ”S-Žõz:æÅäuÂšÙæ1Ÿ¤0ŸýúÒVùÇ®³›šîýû¿l²ThŒ‰ùÞÂ, ìý žüÄ~øk–²Q„^Æ ™Ñ8úÞlÅ2+µ ÊgZÎÐ¥jšæ‡,)“`I”%°…1‘÷Ò2XÄ Rª²FFj5îÑ õ®ï´a„-#¨`!tAÜ©‹TPSõ €„n‰èu¦Ðt­ÃÞ³­,j­‡hFö¥ÐR»V RúüóÏcéŸanÅ¥ @–xõ°­a¢GÃá28çf5»Kl$€^ƒðrc‘ÄOB[Hd$‚.£ñâ/$ßóN~í!‰Œd~´‡„,¶ß sTP€È¡%q!'I®Ga Eƒä=ß­gû¾©=%®2h 'ü4êSSšPÕˆÞ„š»eVÚ3 ´½*°Öù¢‰¥:Q-1ò«,OS Pcª$¬ežV /«Å¢Û%j#3Ng¸zCŠ£#¯Cú‘%bl.ƒ ¿Þ•AþÉ»h£¥6bèûÖÀÚyO¸³=<ª§?ÛiÔMÁÍz/2U£Ó_ñ±D™®ô8é3g8€²BCS»Ak,£š–-cú(¸Éda~‘oýu*õà(õò9ugÜûµ&m¯eLŠªmòMÇ1Ìœ3~dýF#V^°)ŽÂ†[B«uhêì´,±‹÷kþ‘ÕEe̶=ŠÀðÄé1Kž%…¿Ú~ççmóKoOé»ÀUlIã¡P¬8¼ï¸â·ú7a]lSÛ2Ž¿‰¨¿YN”ë«díßñŸ—ÊréŸ{!ë‡}W¬]õ{­_T"?>9RøÄº\B¨×¯„@w A¿ÿëp6sÍþWþIhÝQƒF¹˧6×ïSqA Ö:s®I®fÎÐh$Xœ e„2#¯¹ÿ¼G!^…fë¨'ñ2*43˜ô˜{ëv"¡ä7™„Ž Û–àúų~rå«$Øÿ2Ð8a–Ë!Ëôdþ[[̃åíöóõ*ÚÁu6Ù‚WmH @õÐ$j^uXFm]cng‰¶MXRˆf~‚öš6õ_ÄB¢%üJ%Ò…Ù‹€äÚ½æ7o1/OPž[· Q{Îü·¦jCÉn4ÿð¿‹¾ÙÞÞ†ÁE][><ÜSoüv¡3¾û>ÛÀ./£?o~ö#÷KÌóbåáúY,Uë‚u™BÐ:à*†Ds—‰Þ¸Ä4P´¼m~X.ì‚ï˜wÄÓsÈ2JE;츹~Ò¬t˜gFÐ:Ýbýº»Ô­ãyþ#A…4¿ýûÿH»Ê’3ÇZÅ÷ ÷ðð)ïí3wOP'ö°ª`Ï7*,*J‰€P'ãxSÿÙ÷¦ñ·sµk®Z•è~pcõHÄéV.3úŸãT+À矻±Ñ*Žy;X<Í_¾þ cž¥w`p÷ÎæþÍæ³û·clŽqܳ':Ö‰GeÌT 0i~£¥] T"jîŠ>¸{ÄXåcÄXÑš¦ßÅ1ó÷ }nÝ«¨öqB¬´ÜòÎb 4üÍz¬ÓPŸ;L‹µ!OkÏNh£[2#ÍšRZÍÝAÐx„¯%´Òx¿—Oîü/õó*Uå°N¥K)¿@¢=FìH:\"–¹ÛîY—@U€Èð•`ó.[!ÄÖÝ) סwá@¡ÕC”ChÛ@efQ[™@H2žòýR _‰´u2o…5˜ßm³¹ÉR¿o˜^¦YÆ„B¦Ïd]ÌúëLáܼGäÍ ÜÈ'êïÛŸ0-ѲO)—Ïøî‡Ï‹e§`l™ç0þ‹÷YN§ÅídO lxe5é1ag‘'â>°Û¤u{„§» ¨öU…Vë’V*-ê¬Gm§Òµü£ÿ㻕ᨌ겟MS~‹W#Q©»–ót ¨Z½c¼Ö]le|ÆÐZ!ƒTˆêv¤ÜÕ¯in±ìÒ­žÏW–aUf­W0uʲL«um+8§57BÒÅt…óñüàò[ë¢Uâ!`UŽûj}ŠÝý{ªjËYÔ§À¤-O¾ã-‚mÿˆhÈõÒN¸Z8,Sß­6ŽÏjñ‹<>mr|‚ý/1•à¨ýjÔ –ÙížÃX¾„@ X‡NHÒý=иó&RšžÒe4:‰GÐ(©7݈.'“ã¨Ì¬˜5yàïñK!ž% Mb î¸M­[‚×cY•‡Ä«¾'ß÷°\ÏS4(ßržÚö”80I˜Û ‚FôeÂ|¨Úk€æŽ%âŸZئYM¡Ö!–KÒÀ4ç5Ä,0ˆXÁþð%"]áæ±DQÂÍ{jþ…ˆ£ñ/°BbQS:Û÷XÇTŒÓ•YÙ&çk®TœØß7RœkÈhqë0Ü!ßW`(F[â.´\®b¤wz0r°/¾ ösaeךÛp›Ih·'„Çí#tl5[Ï¿EPÑBÀöÂD5”ùº Å6LÉ=#\SxÑ~*V°rbž¾ Å?jäx ‚ô·õ(V§‚"йŒrËsý·Œ­ à!³½d€ ~ÖûÞ½à¸ÆrƇÔgØüðxëæûL­ †mó&›ætØŸÁØ qü pˆ]È­1ÃÁS5x+ã“4mmM¸(¸¹¡‚¯L{üºY&~+,N†&¼ì¾.Wµúø¾Ö ol)™SËË2)Ïq¯åÍ Õ°Cð¨ƒC—‘–õý5Ö…ãÝ•.â/U¨"£<>QRøD;Þ?~‰„@@ó² gâáÚä'ÏþÂyÐìÞ&Ë´VY.õð3vÍs™Õò—h•X`2á€a*ì[ÍKfQÒQk!2R/¨Ì^â¨f(q3;­Åo\d–—¤A:—x—2­° D^¦ä)iÕF;—QuÐŽœr°þ®ŸÖÄ="ÂÚô@9Äpr¢¿ƒZÿJ0}¿gÅ@†0Ëa{4ïË¨ÜøåM“]ÀMžº®0-Èìm+ó½¶0Zcü|fâÚtœWp^[ê© ã@ Å·vQ'÷&°dœU8<< @B® `¼ãÃÀ=‚Ñl“çÁƒ-Þq¾—0É„þýonÆ‚—aˆchµâÞ6¼2,ûÅ¡[Ž%¬þ®Ãå‚W1àÙÖkQæèÕ1ÇuÁ.’M¦un®ǺÔ8,§Cë¶¿e„ÖõÞ½û'Füxà/´ïg}궇3ìZóÛß°ò~r¬(]”åg8‚Õ9ã­âäs{<4xóW5«ë¼¼ÀÊŠ­ðÂÇâ°ºb{ðåÀav‚æhd´IrA rê%ÚXrB 8"oÿîXx6ˆºˆ½yn±ÇňȞ;;FO­K%RcïõªTþ6#ûüøDHàíx›]M€j—eÍ¢ÇN€£Ñ&¢¬}¼ç MÛeëÓ•å´¢`´2‰[°éáéÐÀÂܼ@&ËÐZ`–0l œ‚Cøð~¼bZ¨¨ù™L=˜-Ä-•MÈ¡`:c ¸´ª0Ÿbz×ÉKî="  ±¸Õ®{ÁËJl¯Ìôê©àð&‡õ´þCÖÑÀæÄÕÐé6›aú& ×?i$Ìò.™~ÌñzE“ª™O`¦Çä!C”A¹<-¶.Æ‘K-ÙºYoûÇ«í®Ïdþ2<çwe‚[2Šâ"3)Øî­,Äm¸ycÁî+Z!æ`óPæ)Ì”úTxÅÖÞ¢n£]bcšF«‹}(Ëu~ÛgøÐµ]£™œmkXßoDCæ}T´bÔÓ6‡%‡vøN‰@ Ÿè`ÊT<$Êç}~tÔçÊÜ(g»»Ï›¯¿ya…x®nA›¿ü•8åZ×,KG\òBÁ3òDs—¸,-Á”BÕEƒ‡|MX.wr궤œò tª&k5"x,…ƒ°®¬I¸ û+s êµôK{@H%Üê]þ‹9÷HlÙE‹Þ#ºZçÖ¶ATŒ¯æ_v?s¹ŸVÛ[kÍúuWŠ¥eÓžgìxhÜv7q9…é[ƒcÙ&âÀÄõMN%¹«‰í÷ÂD6Ö´4nv9D¶!,­^êjù•p+”yÚf-5ZÔReü ¶Ç)œw;ÜŠ4OŸ>nÄ€ÿï;OÁä¬yòã–€.¸l°Lm‰è~LÑŸÎQ ±m­ Ç›àG†?Ñ—ÜÃÄ\fiœ…¬®¥¡Å²Ë¢BÐt:Œ ŽÕÕMÆØ2Ö çÝ‹ÅIAåÆNŸÄf8:3;>ye{–%ê*S;áŒjY9ú˜j–qaÏ3W£Ì·ì™`{ú„ØEYF}ʲ;§Äs• £ìsqS˜rù§xŠxvXêxÀ’уýçÍ7Œù^·ßlÜxF›/â“Áô΃ϘBBXvÚ†=5‚5ÛñÖ„qì€ÕAó„ñ.3? \Ý­âñÓÖc4tÛeù ¹ˆŒâ)0ÆXÔ;c˜÷çRGññ(–!¦h·xN‚@@P8ôç0µ–C]¯­–°¿ŽzÖö+ô瑤𠉦‡Ä¨:ÄIÔ<¯=†¨((vRCC³üL-FGÁNç4Mø|ŽÐhœ[†`á!¯ÐäwÐh%’ z~»Ö¼Ïf,x­×jȦ×s^ÍêDotêÕÓAÊúúõŒ¿Ç3™C¹•þ…(9Dè0vÁ€y\ËùÊ(¦—þMkB³šþ/+ ¢¡˜ýUØÅDAÆU j~4'ˆøp # †ŸÖ:mÐC8R8!.{´!_ó•‰iZ×Y¯µ¬ð£ÔÓ:ØW ö—Ó 12ÍÛ  AnC«Eb<ÆÆÌ¼ñ‘ŒfÓ["ÐÓÂÆ²e(Äßû1`%?€ª]WÀg4ó¥<÷BP8<ÄÒ‚`7 HÑQßgàO»;]ûÞÀRe^ÍÜ|Ë¡À¡æ ÃǺäþ‡DçÓpìÞõàpßsHxÖ1à­ÄHmÛþ<0Îh¯ñ}d¾j÷–[Ë6­éÄÐv‰ãå˜Ç!MªÜ³‚P5w5x„dÆ$3H )ÖíX­Ÿ4EȲÈK¬¹úÜÃKÜùÿ¶?ðˆ_ýà •ðï Œ•þBð íbG"À'<*P+Ð ª6$QT#òªÃ™šƒš³qËŸ={ZÍ¿:‚(IÜ[-ú'=é ‰­â¼çýBg‡ß%2…ÐHhý§öÌÔ|eÕ’4‰¢BÕfÊk<¿<‚ðñµþtõûeJó¯¿êµ…¶{ã6O>9u—ýÙ.§Ï›š±{½Í1û(ìÜ£nóÕŸ¢9~BïËxÏÚ>iµÍª47|hs7%úÅÌ»¶6SùƆ›ãÔú—VÕ¾²¾öMËÖzchWûl°Á[[î)Ú­&ïüf:Æï χÍ_ÑÊ´.æ·ø+,!œ˜ÿ‹%ÖrËUÁÏÆS0΀ ÉædÒú¸ÂÂøú'˜ð=l·{ÌØy öƒæ‹/¾+FLsø;éFC|Ž&Íÿù_û1mð×o¶cM¾eXÌÛ9‚kkVÇ¿3eå·e$P-Rá¸Hœ‚8EÈÑâ2dЉC-_ó›ß0žÇLc€ŸÏìǽ½û,»|ØŽù#ÍþåT„m^>¢ Æ8Bm8¸Ú¯‘¥é‰¶è~bá5þÄ‘Ca qï†D¶1º¼eÞ±ÐeÎñ{$žþlQ|IIDAT Ù/öY©ÉRu†äïÚ±á©/Iµx9~ÞdÌO™÷ó…@ óÕŸoÕ5p@Õ,Õ†ÔŠ$ŽzÌk:•™uÙì,´µyˆL³2¶àÝ-§ ù ‡Ìßÿ§ÅÑXͧ0üB>/×¼^xù­¾”<Õ¼mŸ€ª=W €DÐßÞì°ÞNž3Oð$熙*§--(ÂíQÛT®×µ«‹° ð£¿‹i=® õ¹ýTOÛaýí+ÓËàäìG-¶w3ð—ÁžÚN©£iÝ FÍT+ÂІ„r•¡ðZÛŒ"ÐhP€ùÜ/´Ó\º¦F_j*s,~Ѽ-óÅ6ÉÁo‚ê Ù•R‡=5f\;BP ®Õ|Eª"Zïëw]ä­ç1¾¶Çѧ°TíÿÅòÅP|ÏL1¿¤0¿}ûF-“(H,\v&”€8/ªÖà|¹ EMÂßž={„rÀDwÕ¨¢0Mଽ×>èãáÍõE¢_ª´„s’n/k³eWFü}|£ü4±ùš¿yôGÍßÓ6:§.aTx3‚h]™¿5ß{µÃ`ºh¡0̹°Ù`,2ó®í»®].-/âØÃôlúYêd+a·m20û§ú<}ú4úLáÀ¾[kàß¡÷½›Å¨õê ÷S¶ÿS,듳³²é“L¸zÆ+ܹUs­¿åZ?qÖZ¡`âøªLw‘Ø«ël9|ÆšüóGÍðD¯ý~,_SÀ²}êÙWYd-ÓëEd¶|?‘ë·‡w:„ºoÁux–±QÀGŸÖ"$&»»»áO¡…õvÌë[¡pp„Ÿ‚N‹ZY|^›¶Ð¶BQ äJ¯Z{ Ò^+n߈K …h·cÇS¬¬Ó›Ï2Mä;þÝêïPǼýPÇ囿9]ß¼ŸR˜Ÿ¾üÙ-‘@UÂ#±ðèyJ¼½Jød(•øÉ¸*“÷j™Ñù‚ÄQ3왾¨ŸåH”]^%“ðûû"H•àVMÈ«môúöåJÚ©3‚€'$—S¦ÅS¿LÐ冶Ñò_Õ61ÓYQm¹2ÏW¥¿‘ÓyÚ˲]Uð¾ :26½ÿí5TW œáQ^-9‘Á[|Øfõ·ÅòP¶šU°~W…-@µëxÎÜð¯ö Žozà‡Sh+˜‰O´³SÊšºŸ¾­Ö‡úl6VMº>›¾Vüëb娶îZ Š@Ö !ر^¾Ó Œm†=GµLçZî/p‰1Q´ñ2æËxÿéå‰cRÌdüb)·ž³¦­ãº _u¼¿ï¿µYë˜é>Røxú⣩‰Dâ!áðô^(¡”ú]© ³¯ÎU>Ójà3Nª5W‰”İj…:‰“‡e¿Ë£C ©å9÷_5¡7!¬µN¾S‰¬ùyüêW¿ -«âP`Õà¼Öwj>…ñç/1« Ç´jn2$1z“:Vã;ZÆÌ×>3?ûË9n=⽯–ëòsË´|ë_—}ZûØ­g7~÷÷Š•ïY7Ç™õ‘ñùžgÍïM0˜n‡}o>2TË­yN§ñ¾Ö½Žyëç;bä;uÌ{ _®þæ9 vÖÃòmcOŒê¸¼®m–i<­“ï‰Ñui¯¶¥¶Ç´¾ãi™Ž{óµì<Š@ކŠD^/¨Ë•xHì$&2‰Reü@ï=ýMÇA™N.2mo$L¾#Q3‰RÕxLâó÷qTâ'!¶¼7!¨×ÕGŒªyÖåd2‡zLúÊx$¼µm¶_X1ªWßóµ~¾3 ѯiLïi[}ß~°œi Fô™&nûí]ÖÁöÕò¸d`ޝ2 ™¼m3uóð=ëëošªýÝÓï¾çµ¶ïMëYß3û¡bz5û²ŽyûÆ2›Up\Û¯:ZŠ]µ˜þuG+¶Û)5Ûå½çu‡õöÓYÓyõÙ¬GÍ£æcxÿ&yÌZV¦ûå"pýüå¶'kþލ„¢) ŠDH†á3KÕâ|VÄÓ{™Úˈc%N•ÈWÀçõ|G͸ÈFæäi™U¸øñ n¬ŸùL35ó“9ÔÃß+³‘qø»xŠ›˜˜‡©‰{•8O3bßkq1¯7=j}Ofjù2\ï­·ùZ_§ ^ÖGoS¦m´¾¶S†kY–é÷Z¶Ïë3ËöcË4O™É›ôѬeÕt¶ÓÓ²m¿eÖ£Þ×zø¼Z–jjÇ[ ¬}^óšõZßójžõûËÞ÷÷š¦ö™×Š_ç/{ÿeÏͳ FbSó~Yúéçµ>ÓÏò>ø¹¤ðsü„Þ’˜I+ÑSH|ïMˆá›æÿ®Ó×úÊœ^w˜VÜ®bçwˆ×•¿.Ýë~¯øÊeBïó˜nk-÷jy¶KíÞq#•ùO§ó]Ó™ßËò™N?Ëý›æSÛR5ð:Ög)ëº4–_ó¬×ëÒå³DàC À‡@ù(Cbæù¦ö— Me oÛ†wÅÜg)¿2›Yæ«êe}*~õz]úZïë~ûÏj=>ü>dÛ³¬ùE €ùíÛlY"ð‹@ 2×_De³’‰À!ž!sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜fE*Ó%‰@"$s„@ sÔ™Ù”D HD`VR˜©L—$‰@"Ì)ÌQgfSD HYH`V¤2]"$‰@"0G¤0G™MID HfE €Y‘Êt‰@"$‰À!Àuf6%HD ˜ÿÉvn«åÙ(IEND®B`‚eric-6.0.8/eric/pixmaps/eric_3.icns0000644000175000017500000127706412310131042016154 0ustar piotrpiotricns~4TOC hics#Hics8is32çs8mkICN#icl8il32 ,l8mkit32uKt8mk@ic081™ic09~Uics#Hÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿics8úVVVVVVVVVVVVVVúVÿÿÿÿÿÿÿöö÷WWõÿVVÿÿÿÿÿ÷{QW|‰÷ÿVVÿÿÿÿ÷zý‚R|ƒ‰öÿVVÿÿÿ+PQ||‚§­]ÿÿVVÿÿö{|‚‚‚§­]õÿÿVVÿÿP‚ƒ¦§­­øÿÿÿÿVVÿõ{­­­­­÷ÿÿÿÿÿVVÿö|­­­­]ÿÿÿÿÿÿVVÿö‚­­ˆ‚+ÿöõÿÿÿVVÿõ,÷,+öõ+WöõöõVVõ,,,,,2,,2,VV+VV,WøV,2,V+33öÿÿVV,,,ø,W-,öW3+,+VVõ,,+ö÷+,÷÷+ø÷õVúVVVVVVVVVVVVVVúis32çzƒ˜ šœœš˜›š˜z™ƒÿ úàÏ´ž¬îÿ™˜ÿ ûºa`‘Š}[Íÿ˜˜€ÿ7ú¬u&P‹gUNÞÿ˜˜ÿÿþ½‚‹cb[HAŠûÿ˜˜ÿÿßvj^[QG9†ôÿÿ˜˜ÿÿTPKD;F°ý€ÿ ˜˜ÿðt6>>=FÅ‚ÿ ˜˜ÿÑW1092ƒÿ ˜˜ÿÛO7CPpÙüãò€ÿR˜˜ÿöÍÁÈÓêõÕžáñé홚ð¹ºÃÄÀ¶Ä¿¶Ì«ªÓœ˜Û¯±¬Ó¶Î±Õ·¶à÷ø™™Ò½Ñ°Ô±½¾â±¶ÛÌÊœ›íÁÀ×ÜÅпǿ˼½ñ›zš€›š›œ€š››šzzƒ˜ š›š™˜›š˜z™ƒÿ ûê߯°¬ëÿ™˜ÿ ùÀi„ì€EÅÿ˜˜€ÿ7ùÊŸ5nÃ…Q@Ûÿ˜˜ÿÿýÛ¸³ƒ‚sT4|ûÿ˜˜ÿÿí¯‰lebV/yóÿÿ˜˜ÿÿÃlZ\R?8¦ý€ÿ ˜˜ÿû¥=:6-4¿‚ÿ ˜˜ÿç€7') uƒÿ ˜˜ÿäX25@dÕûàò€ÿR˜˜ÿôʾÂÏèõÓ™áðæí™šî³´¾À¸±¾¼±È¦¦Óœ™Õª­©Î±Ê­Ó°¯à÷ø™™Î·Î­Ïª´»ß«°ØÈÈœ›í¾½×ÚÄμƾʹ»ñ›zš€› šœœšš›œ›šzzƒ˜ šœ›š™›˜z™ƒÿ úáÕ­rnäÿ™˜ÿ ø³k_gb-¶ÿ˜˜€ÿ7ø»†#+?< Ñÿ˜˜ÿÿþ‰iD-'Xúÿ˜˜ÿÿÞmD(Yðÿÿ˜˜ÿÿ£ ü€ÿ ˜˜ÿóy ©‚ÿ ˜˜ÿ×E Yƒÿ ˜˜ÿÚ/ LÍ÷Èî€ÿV˜˜ÿ鯬«¾Öí¼oÞáÏ嚜ك•”‚„›ˆ¡‚Ë›©zŠ‹¯‡¦„Ày|áúô™›§ˆ±‘­swÈu{¾¡ºžœè¦£Î͸Á¤·¬¼¡©ð›z›žœ›€›œžšzs8mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿICN#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿicl8úúúúúúúúúúúúúúúúúúúúúúúùùúúúúúúúúõõõõõõõõõõõõõõõÿÿÿÿÿõõõöõÿõõõõúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõö÷øV{|XW+ÿÿÿÿúúõÿÿÿÿÿÿÿÿÿÿÿÿö÷øPPOPWW|Xƒ‚õÿÿõúúõÿÿÿÿÿÿÿÿÿÿõø€û{W{W|W|ƒ‰‚õÿÿõúúõÿÿÿÿÿÿÿÿÿ÷ú{¬ýý{RRQQX‰‰­‚ÿÿÿõúúõÿÿÿÿÿÿÿÿ+PP{ýêý|RR||‚‰­‰]ÿÿÿõúúõÿÿÿÿÿÿÿ+ttVVû¬‚||R‚ü¦ƒ‰­VÿÿÿõúúõÿÿÿÿÿÿöVzPQWQ‚‚|‚‚¦ƒ­­‰‚õÿÿÿõúúõÿÿÿÿÿõPIVu{||‚‚‚‚§§­­­ˆ+ÿÿÿÿõúúõÿÿÿÿÿ÷{u{‚‚‚‚‚ƒ­|§§­­‚+ÿÿÿÿÿõúúõÿÿÿÿõP{‚‚|‚‚ƒ­|§ƒ­­­‚öÿÿÿÿÿÿõúúõÿÿÿÿ+{‚|‚­‚‚¦¦ƒ­­­‰WõÿÿÿÿÿÿÿõúúõÿÿÿÿP¦§§§­¦§­­­­­‚+ÿÿÿÿÿÿÿÿÿõúúõÿÿÿöt¦­­­­­­­­­­‚+ÿÿÿÿÿÿÿÿÿÿõúúõÿÿÿOt‚­­­­­­­­­‰+ÿÿÿÿÿÿÿÿÿÿÿõúúõÿÿÿP{¦­­­­­­­­­Wÿÿÿÿÿÿÿÿÿÿÿÿõúúõÿÿõz|­­­­­­­­­­+ÿÿÿÿÿÿÿÿÿÿÿÿõúúõÿÿõ{§­­­­­­­­­öÿÿÿÿÿÿÿÿÿÿÿÿõúúõÿÿÿVü­­­­­ˆˆ‚Vöÿÿÿ,,öÿÿÿÿÿÿÿõúúõÿÿÿõøVWWWVø÷öÿÿÿÿ,,WùÿÿÿÿÿÿÿõúúõÿÿõõööõõõõöõõööÿÿVWúöÿõõö++õÿúúõÿö,--,,ø-,3,,,-,+,-Wõ+,3-,Wøÿúúÿö,3úV,-VV,,Wú3,W÷3,W,,WúVWùõÿúúõ,,W,,,-øö-,úö,,W+,,W,-ùõÿöõÿõúúõ,,WWWWWøõ,Wøö,,úõ,,W,3÷ÿÿÿÿÿõúúõ,,W+++øVö,-,,,ú÷ÿ,,W,-÷ÿÿõ,÷ÿúúõ,,-+ö,Wøö,3W,,3öÿ,,WW,,ö+,W÷ÿúúÿ+W-33-Wöö-WVW3-W÷,-WVW-3WWúõÿúúÿÿ÷VVøø÷ÿöVVöõøVVøøùVö÷VVøø+ÿÿúúõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿÿÿÿÿÿÿÿÿõõúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúil32 ,p}~€€~}p}î‹ö ÷ùûûøóíèæôú€öî}~÷‹ÿ þíØ¿«•|~•›Ò€ÿ÷~~ö‰ÿນ¥¬¤‘“{€{röÿÿö~~ö‡ÿì¦daOq‚~‡x›|rhqôÿÿö~~ö†ÿÉte2tš ‡ŒŽdY?w€ÿö~~ö…ÿʃ…i& $x›^e[MIM…€ÿö~~ö„ÿÍ|}‰‡L0MtjfKLNTL®€ÿö~~öƒÿß‚t¢°…OX}bUDRHIMiî€ÿö~~ö‚ÿò‘¨‚|vis_WfWEL8ID[Òÿö~~ö‚ÿ¸q|edRbdRQ=eEL4@aÕ‚ÿö~~öÿï„g^Zz^S_CjGY18Awãƒÿö~~öÿ¼gcn`CONH@M&;AB>bÚ‡ÿö~~öÿÿý¯{O/49:?<=C=OÙˆÿö~~öÿÿõ’mL3..349A=4 ‰ÿö~~öÿÿåz]>6/15;B?5CÓ‰ÿö~~öÿÿðy@1229:><6D}å€ÿü…ÿö~~öÿÿý˜I406>GNSo£èÿÿøÕËÛýƒÿö~~ö€ÿð¹¢—“ ©·ÅáüÿÿûÎÒ­‡÷ƒÿö~~öÿÿöïåàñôðîçöòäãøù¡ˆ~ÞÿõíâÚßë÷~~öÿàÒ¿¿ÍÁ²ÁÔ¹ÄÇÍɾÌ˽¤ìÛÉ´¿Ò–ªû~~ùëϵ~˜ÈÆ¥¬ÌÑ­|µ×±¶´ÔŸËÌ¡‚šˆðø~~õÓÒ¯ÆÒËɯÜňàÆÕ¥ÐÊÍÁɈðþ×ìÿö~ðÍͪ™˜’‹±ḛ̈¯æÌË„ëÒ͟˶·‚ÿö~îËΛÅÍÑ­¥åÌ»ÀÍ˶ÿÐÎÆ¼ÂÿÿôǼù~òÀÓ¾ÚìÙ²¥éѸ¨ÐγßÿÓÓž°Ô¼êÞÔ›»û~~úÈ£Á¸¶½‹Ý⻢”•·Æ°¿ÉŦš­Ã´­§„ðø~~øþß™§§´ÿàœŸäè§–³®“›â¶–›¥«Éÿ÷~}î÷ûùø€ú÷÷ùù÷ùú÷øúô÷øøúøùûýûöî}p}Ž~‡~}pp}~€€~}p}î‹ö ÷ùúú÷òíèæôú€öî}~÷‹ÿ üìÚĹ«—˜Ÿ¢Ï€ÿ÷~~ö‰ÿῸ¸ÊàÖ¢©’hbõÿÿö~~ö‡ÿêªnkl«®®°‚¥„hBWóÿÿö~~ö†ÿÃ|‡@!ŸËÂÁ¶˜K>-h€ÿö~~ö…ÿÕ¸Á‹3 ,¥ÖÒŒƒ\EBC{€ÿö~~ö„ÿÓ´´¯¨v@i™»yP]OF<¥€ÿö~~öƒÿꤚÜâ«¶f²zhRkE85Xë€ÿö~~ö‚ÿôÇù²¹˜‹ym{bVa;7/GÍÿö~~ö‚ÿÒ®À‡uaqnYTE…WM*.QÑ‚ÿö~~öÿöÀ yo’jWaKƒ_o/,.jàƒÿö~~öÿÞž…eI_gd]i+3*=™õ„ÿö~~ö€ÿûÊoXPYG^VJ40/.Mʆÿö~~ö€ÿï¸j;ABF=5/.0/Sׇÿö~~öÿÿþÞ·v:2310,,1/>Óˆÿö~~öÿÿüË¡g  Á‰ÿö~~öÿÿôxUÙ€ÿü…ÿö~~öÿÿý…$ %GŠáÿÿõ¯–Êýƒÿö~~ö€ÿé¦{u~Šž´Ùýÿÿú¤ƒktøƒÿö~~öÿÿðßÊËîëæáÝôçÌÐø÷ˆ\jàÿïÝÅ»Àåø~~öÿÄxw„•šŽzŠ‚ƒŸ¹~}rv„\¤ü~~úÚ†toƒƒ™‰‚‡ng}‹yµ†}¯€gwŠd~òø~~÷¤†tš¡„~¡Ñpç–ˆnÓ©€x‡uóÿÚíÿö~qgfg_ªà…r®Ï†gï±€qˆu²ÿýö~푃zÌÑÓŽ‘Ú…z†€\¸ÿ°‚m„x»ÿÿú~ô”†ÂÔ£q ×‡vk……~Õÿ°†t{†Ý“cºü~~û¿kyqprcâÌrksu{p±š{w‹ozrlfjòø~~øÿÀ’œ›°ÿÛ•åêž‹ˆ¯ †‘㱉‘ ¨È$ÿ÷~}î÷ûûùüüû÷÷úû÷ùûùùúõøùøûùúüýûöî}p}Ž~‡~}pl8mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿit32uKÿnm÷lm€nm¦ÊõÈʦmnnlË÷ÿËlnnlÈ÷ÿÈlnnlÈÖÿþúö÷ùý•ÿÈlnnlÈÍÿþüü÷ïèåáØÏÉÆÃ¹®±¹ÉÝïúþ‘ÿÈlnnlÈÉÿùñìáÑù°¥—‹ƒ{qnr‡„‚†˜¦¿ÜõÿÈlnnlÈÃÿ"üøôêÙĪ˜Œ~rifg]QNONLOZm~‹‚‰™Žƒ…•³àûŽÿÈlnnlÈ¿ÿ'ûöêÙÆ´¥‘|j]YWY`i_UORTRSZbmw—¥˜Šxuw•ÕûÿÈlnnlÈ»ÿ+ýôèÔ³¡•‡|zus|ƒŠ•¦µ¾½¡•‘’‰€{„†‚ƒ”›’ކ~qog`áÿÈlnnlÈ·ÿ0ûóåк§–‹ƒ–›› ·ÁÑ×ÛÝßÜØÎ®¹ÈÏ陋|svŠ—ƒƒ„€vf[Sa¹üŒÿÈlnnlÈ´ÿ3ýðØ½¯§«¡¢™”¦¬¹ÀÃßÜÕÑÏÇ»±²²—£°®··yji}”‘ru€Š†lZTT˜ôŒÿÈlnnlȲÿ5ýìÁ¤¡¿¹ ‰†}„Ž›®ª«ÆÅ½ªœ ¬œ„„xf”²zpsx„Ž€ln{”ydXOéŒÿÈlnnlȰÿ7þñЧpkm„yUXSTVcuŒœ†Ž› £‰wu‡¥§€bhg_”¹{w{ƒ…qgm}ŒŠ~l]RtÞŒÿÈlnnlÈ®ÿ9þõÛ«ŽŽ}Rn‡q(Z]QOUdv~n…’‹‰zkh{‹iLXi~”¼‚|}}‚‡qgh}Š„{uj_VtÚŒÿÈlnnlÈ­ÿ:ùß·”ykV:eˆ˜—@U¡–p`_f~ƒs…šž—{qkbaOOj—¿‹z‚„qmjrvslgf`ZàŒÿÈlnnlÈ«ÿ<ýêÄ—vemV-¤ƒRos4#¹–ugu–ª‰WXd`[^v|rni|¢°º“…€{|ypqrmfge^a]]•îŒÿÈlnnlȪÿ=öÙ¨~gec…gM’YVd]7!Mcjjr†‘zf{ƒz^¾ØÔ´‹o‚˜¼±‘€}toopqmgWT[^Zg¬øŒÿÈlnnlȨÿ?üæ¼nbh‰vŽb!@=7R9 kyrwwdož¸Âˆˆ³µÅÍ£}«¶»¤ŒwnonlpmjpZ+"8JQl¿ýŒÿÈlnnlȧÿ?üݬ}ijo}vy?(6) #‹©•~ix𫰾ŀ]Œ‰“¢œŽ¥¨´¯‰q\\cnldM()958`ÇÿÈlnnlȦÿ@÷ÚžkNSr}uZE=+6 EviQv°²¬°¾Â„D||‡Œyrm‚‘Š{oTP`g^PA=HWZG@fÏÿÈlnnlÈ¥ÿBôÅJ58@DRVRri%!'  IŒ‹sš°«³º¾Æ–7guv‰nTRe{}sgPLPIGHJRY]ZPPtÏþŒÿÈlnnlȤÿCô´n\ez•¤‰gPO—0$ vŸ¥‡Œ”¨½¼´¹–2Igjp~nLVf{a@=<3:KNPQRPOTsÌþŒÿÈlnnlÈ£ÿ:ñ½vey ª³¯¦‘Uvt+$$ 7—Ÿwm~˜²´­¬™F4aflvoHPl}p\C@FDEAI€ORPQUtÏþŒÿÈlnnlÈ¢ÿDñ¾‡u{‚œž“‹œ¸nAC+!$ T“‘]WsŽ£¦¥£žf*\ktztV568;HRSSRIDSWo½÷ÿÈlnnlÈšÿIþð·‘‹Ž“€cŸ¸·µ³­§ª´¼|C|–›819/%Talrux|\*DbleS,@cVQPV\[RG?@HYYWLDOTZ“åÿÈlnnlÈšÿIóÇ„–¤²Å±f”¤¡££¡¤žOW€ƒˆ›–=Uh^+]mrpqrtsyxJ5LS@.*2XQONPSVUPOLIUUSLNUT{ÌûÿÈlnnlÈ™ÿ-÷Å‘€‡Ž˜¥¼«V~‹‘‘’“z8iƒ„ˆ‰•}9`uz7Wrqlnllnrzk>€,:P< DKOONKOPQSLFSRNNPQn¾ö‘ÿÈlnnlȘÿIþÚ…t€— «¿¥St~€‡‡†…ƒ†a>p||•g=dryL=iokmjknrtiA*K^kX)BMNLGKPRM@GTLKNMd­ñ’ÿÈlnnlȘÿHê¹tu…”¡¬¸È¦Mety€‚€~zxQTptrrv‡LCimol;M_fkloqn`D%Rnooe)3BDEDFKH<:LPJJKb¥è“ÿÈlnnlÈ—ÿIøÃŸsx‡–¢²¹Å¦BQnx~}uynKdmmopuv7EeffoN*56[ccddfnpE-M[_bbcX=.Zwƒˆk1PUPNMI0'6>@HLIOOMkºó—ÿÈlnnlÈ•ÿFø½„tzdCLd‚aIhtwuw|re,1SY\^afkq`5DY]`]VH8Xzyxxj>EDBCGFFE7ANMO`\x¾õ˜ÿÈlnnlÈ•ÿEâšpac~—sB3QnIEahims|ŒF1MWY\clotvHTNJYgƒÊ÷™ÿÈlnnlÈ”ÿõ·ˆt`Yh|rbSD;_m€p1sy€Y3GTZ`iqrsv\7COOIPd–ÖúšÿÈlnnlÈ“ÿEþÞ‹w—Œf`ejhjsxF4[pvvttrrn@BR]blppleX5+Jp‘›…,W_[WTR8"5?d{~|yqp}\AM\eheYE:$4`€‡†…h'FM€JF="*=?42>NKEHTƒ½íþœÿÈlnnlÈ“ÿ/ï¹i[|dZWZemlrnIB`uxvoktlF8HNB718J$^wvmqK *>B€A@?8;;13ESKIPgÐ÷žÿÈlnnlÈ’ÿBûÖ–aZq€gV\jt~vn|oN>Qafgec\F,+28CQol :`jib]\.,5;<;=@C:+,9NVPL`€²àúŸÿÈlnnlÈ’ÿAð®ymabp‡wO[w…‰usrrU;@NOI=65DU]aej‹XEUXYXSE+025:?EC35JV]\NZŒÈóþ ÿÈlnnlÈ‘ÿ@ùÉ€lucTm†~TBSo€uidaV1&,3@Shmgb^W`)@OOME;+ #)+1;CH?æ§ldsiOP\c]NAIU[UG?=>%#6FU`ggZME>2( 29<7)$""+4=DGHGLIBNg’Èó¤ÿÈlnnlÈÿ>üàÅ‚ZaXNJJPQQKLKMNIBGO,4ITgqjR1+<*).4;A=9:<<=ADEC€ASÂíü¦ÿÈlnnlÈÿ/öι®ˆ‡oEF;3FWa\E85:HOPJB@91/3:>EPTQQLMJGDDBACC?>€? DJIFBASÊö¨ÿÈlnnlÈÿ,ߥŸŒg~‚MFD:7?BBH@36:@HXih]NDEIECDD@><;:878<@A@ BEKMIACSÇö©ÿÈlnnlÈÿ*Ô˜fPh‚V>IK=:9@VUKB9?LX_b`XK@;776877658759;€? @CBCCD@>HW‚Å÷ªÿÈlnnlÈŽÿ:ýІjuYTsb;8:525?JPPD;:<>@A>BB@?>@?@Nc‡É÷«ÿÈlnnlÈŽÿ9õÑ¡¡²|DPV;0041-2:>?ELA88778;?HHCAAB@ABBCACGIEAFC@@BAAMc‡Ë÷¬ÿÈlnnlÈÿ!ýç讹˜XIPI85<=7446;GUTLID=>?=>@>=€<==@BFHECCEDA=??@Qp’Èö­ÿÈlnnlÈÿ+öÒ ‡—nYgfA02997725;BEBAA@EEA@A@><8569>?BCA€@ =<::;;FZ{Àõ¯ÿÈlnnlÈŒÿ"úÍ®pXXqi6343/*/7>><822//499::<>>=?<=€B DCFE@=>COb§ë°ÿÈlnnlÈŒÿ7󱙯”ce‰™†ZGB=2)*+-0028=845213359:8;;<9:?CDDBDFB:7;CU‘áý°ÿÈlnnlÈŒÿ6éŽt𦖄uqpngI3/-+*(*,09=>==97856987878;>>?@BABA;53;EtÎû±ÿÈlnnlÈŒÿ'ë—l€‡\IGZqR2-.032+*,.034545858;85679>@€? @>73217Fa±ö²ÿÈlnnlÈŒÿê½vx˜žh=5=MF95547=3&%''*-01€0560-2:=?CB@?;7456;BO~Ýþ²ÿÈlnnlÈ‹ÿþÙµf^x‡jK=<>?80/-,77.+,-.0€1//158<>@AEGC@>869<>>BT ð³ÿÈlnnlÈ‹ÿ5ûÕ…u\WXRJA@CDEEA?:9==;;AWN<30232/..+).03€8<;<>?ACA@?<98:899>FpØþ³ÿÈlnnlÈ‹ÿôHY…ƒwYE=87=>62€/!01136468987:>?@@CFFC>;;8568:7F^ˆÚü³ÿÈlnnlÈ‹ÿöŸQnxedoxZ:21483/0-+1::9€8:;=?CDGE@?:8;978:8=Tr•Îö³ÿÈlnnlÈ‹ÿøº•¥UNYoZ?9;?=2/21-+*0?BDD@>:6:<:998>??@?;9<76<@CISk°Ëèú²ÿÈlnnlÈ‹ÿ7ýКuxlH5310/-/2437<8301;=><:;?ACACCAA@=97329CMSYj„£ÃÚêøþ±ÿÈlnnlÈŒÿ ݘf^^J>:4../€0'.0575207;;:9:>BC@B?<=;7355;HS\fsФÂÚëôûýˆÿþý¤ÿÈlnnlÈŒÿ é£rQC;653-,.+()-/22133778;;=>@@>;€:99:AGQ_jr€•¯Ìãòû‰ÿþñãáæóþ¡ÿÈlnnlÈŒÿõ³w[PD:31-*/0,,//12244€6;?@@A@><>A@ADMV^gq}Œ »Óêøþ‰ÿ úḲ³¤´ØôþŸÿÈlnnlÈŒÿ0þÛ›xl`SF>70/100..037<;<>=@CDEIKMNMOMRZfqx€‹š°ÆÝïûŠÿ ôÔ¥»ÖÓã´ßøþÿÈlnnlÈÿ.ôÆœ‰{l]TJA:98857::;>DHIILNOS[aa`agjqx‚Ž™¢¯¿Ñãóü‰ÿþ꿳ÃÍÌÊÍÔ½¡ ÄëþœÿÈlnnlÈÿ-þ纟“…wnhb[WTPLLNKJOW\]]`cgmsyz}~‚‰•¢¯ºÃÏÞëöýŠÿ쯦ÍÓÒÑÏÏÒØÎ˜‰ÅøœÿÈlnnlÈŽÿ*úÚ¼°¤–…{yvojgijou}~‚‰Ž‘•šž  ¦¬µÂÌÔÞçñú‹ÿò»©Ð€Ñ ÒÑÔ×ÅWk¸ôœÿÈlnnlÈŽÿ)þòÚɾ³­«¦¢¢¤¡›•’—˜šž¤¤¦¦¨¬°²´·¾ÂÂÆËÒÛãêñ÷ü‹ÿ÷Í¥ÍÓÑÓÔÔÖÕ¼{PHn¹õœÿÈlnnlÈÿ'ýñãÙÏÈÆÅÂÂÄÄþ¹»»¼ÀÃÆÈËÍÎÌÍÐÑ×Üàâæëðô÷ûþ‹ÿûÕ®ÎÙÐÏÏÕ×Ò­pHKeÌúœÿÈlnnlÈÿ üôìæâàáÞÝßàâÞ€ÙÛÝÞßáãæåããæèíñóõ÷ùúüýÿò¹³ÍÒÔÓÍÖË—[DLpÆóÿÈlnnlÈ‘ÿ ýú÷õôõôòòôõõó€ô óóôóôö÷÷øùûü€ýþ‘ÿñ¨oxœ¸ÇÏÃŒSEYw¥Ûõÿƒüûý†ÿÈlnnlÈŽÿþüùõñ€îïôúþÿ€þ‡ÿþüûüþ…ÿûõî€íïõü„ÿó³tYS\s†sMH_‰¶ãüˆÿþüùòíç×ÔÖÚÙÙØÜèîùþ‚ÿÈlnnlÈŠÿ-ûõïèæàÒÍÈ¿¾»½Ç×åõþÿÿ÷õöõõ÷ôôóîêâÜÚáïþÿþ÷õóãÚɵ€²·ÁÔêû‚ÿûݱq[RMHNk’¹ëþ…ÿ úóìæãÜÔµ±¨¥ª€¯´±«±ÌèýÿÈlnnlȈÿ8ûïÙÏļ¾»µÃÐÐÑÏɽ¬ª½åúýÓÊÑËÉÏËÍÈ¿À©“µæäàÑÎǰ¾ÃÌÍÌËů©Ô÷€ÿýûøíÓ¶›rr~œ³±ØøƒÿúçÑǽ·³®»ÊÒÐÏÏÐÐÌÊÔÜÑªŠµîÿÈlnnlȇÿ/óÙ½¼ËÔÕÓÐÅÊÐÑÑÎÌÏϽ™£ÒôεÂÅÀÃÌÐÔØÓÒ×´g…¯©°¿ÃÁÏ×Ñ€ÐÓÓÔÊŸ–Ì÷ÿùàãáàÞÛ¢§·È΢v¥çÿüîÓ¬¬ÅÏÏÂÆÓÓÐÐÑÒÓÒÐÇÉÙ¶i\›ãÿÈlnnlȆÿlîôÈÔÔÓÐÐÒÎÌÎÑÐÍÌÎÏׯޕÖ☟ÅÏÕÕÖ×ÒÐÑÖÇx–¾ÌÍÅÆÑØÑÍÏÐÒÑÏÏÐÂŽ’Òøè§¾ÑÒÑÑÓÙÜÕÑÊ\æÿÿþóÚ¸±ÃÍËÄÂÌÙÚÓÐÏÐÒÐÎÎË˵pCY›ãÿÈlnnlÈ…ÿ ï»ÏÒÓ×ÔÓÒÍÊÉÌÐ[ÏÍÐ×¼†¥Ð—iŠÀÔÔÕÓÏÎÑÑζÊÉÄÅÃ×ÜÖÒÐÐÕÕÑÏÎÐÒ»{›Þà€ºÕÒÒÓÓÔÑÑÁeªîÿþë½µÁÐÍÃÅÆÎÖ¿¹ÉÔרÔÑÏÏÕ·kFNu±ìÿÈlnnlÈ„ÿnñ¿·ÎÓÐÓ××Ñ´‰u‚¢ºÍÚÔÎÏÐÓÚ§‡´¬z_…ÅÖÓÏÍÏÒÏÍÌÈÆÊÍÍÕº´ÇÑÓÕÕÒÏÍÏÔÑ|¼ßi‚É×ÒÐÑÐÏÐÁvl½úÿñº§ÑÏËÅÈÑ˹^[y¤ÆÔÖÔÐÓÅ{FNsªäþÿÈlnnlȃÿnøÈ¼ÒÖÑÏÐ×Ì›dJGMTp®ÖÐÎÏÒÑÓņ–ɯzaÍÒÎÏÏÍÊÇÈÉÎÕÐÈœZUz©ÐÕÓÔÑÐÐÒÒ§n§âÈnžØÒÐÐÏÏÒÁql¾û÷Ê«ÌËÇÈÌ×Ó¡kIHRSVkŒµÌØÏLOv©ßý‚ÿÈlnnlȃÿÞ¹ÌÕÐÏÐÔÒ–VEUmyl]s¿×Ò΀ÐTÕ¹Ù´‡j«ÒÑÏÏÅÊÏÓÏÈÕÀ„PEVWa¥ÖÕÕÑÐÎÐÔµh–âôÄ€wÇÕÒÒÐÎμkl¾÷Ö©ÇËÌÐÑÏ̤[ESm†„jWO`†·©YKq¨âýƒÿÈlnnlÈ‚ÿmùÂÂÔÒÐÑÕÚ§aJ_…­À´iœÖÔÊÎÎÑØ™kžèî¾~ŒÍÔÏËÃÒÓÐÊËÈKKd‰‹ktÊÕÒÐÏÌÎÓ¿p“Ýýé¨x ×ÖÓÏÊʸepÀê¶¼ÎÊÕÑÎ˨]GX‚¬ÊÈ®—~fU]]I`Ýý„ÿÈlnnlÈ‚ÿlÛ¼ÎÔÏÒÔÙÄqFc“ÅíúõÎ’†ÇÖÏÐÑÔÙž_–çþæ©„ÀÒÍÆÇÐÍÎÎË“QOpŸÅËw¿ÒÐÎÏÐÑÔÅv„ËúüØ“‡ÒÕÎÈÆÊ¶e‚É×±ÐÈÍÎÌÐÃ{HY‚ºéûúíÜÆ¥aS^‰Ç÷…ÿÈlnnlÈÿú¾ÁÖÑÏÓÕÙ TX…Âçéèè希¼€ÒFÓÖמ_•çÿü̵ÏÏÆÍÑÌÏÕ«ZMr¥Û÷ùÓ—ÀÑÔÏÎÐÑѽirÁøÿð±‡ÉÒÌÆÌηf“а¼ÐÇÐËÎÔ¨RR¸ìÿþùå¿•š»í†ÿÈlnnlÈÿÞ±ËØÏЀÒU™n…¬ÔÉ´±³µ®¤ÃÉÑÕÔÔן_•çÿÿ㟫ÈÉÆÏÖÖ×ÐJbœÜüÿÿè¤ÇÓÓËÌÏÏͰYoÀøÿûÌÆÑÍÎÓÓµf“À•ËÊÊÓÔÚÎzLo«é„ÿþôäáãïþ†ÿÈlnnlÈ€ÿýÀ³ÏÔÒÑÑÏÏÀ»ÀÁÆÎ€ÓLÕÔÒÎÄÌÑÑÒÑ—]–çÿÿò²°ÉÌÌÒÔÑÔ»aU†ÊùÿÿüÏ¢ÎÑÎÉÎÐÒÔŸS}Èùÿþà›ÃÉÊÒÒÔ³hŽ«§ÕÌÎÔÓÖ·Y[–×ü”ÿÈlnnlÈ€ÿùµ½ÒÏÔÑËÊÎÎÏÑÍÏÓÓÑÒ€ÔÑÉÌÎÊÏË‹Z–çÿÿû¿µÍÐÐÒÐÑÕžSl¯î€ÿô²»ÒÐÐÎÒÓÖÒ{S’ÝýÿÿæŸÀÆÐ€Ó±i‰ŸÂÕÏÑÑÒКLm·ô•ÿÈlnnlÈ€ÿ^öÁÈÔËËÌÎÑÕ××ÕÓÖÚÛØÖÙÙØÓÍÑÓÑÐÊ{W—æÿÿû¿µÍÏÐÒÑÓÖQÍúÿÿþÖ¦ÓÔÏÏÎÑÕÚµ[Z›äþÿÿæž½ÎÔÒÓÓ°j‡œÓÓÏÒÐÔË…O„Îþ•ÿÈlnnlÈ€ÿïÂÅÑÇ¿ÌÔÒÌÇÈÇÄÈÌÉÉ€Ç.½®§§¯¾Â¾na¡éÿÿûÀ¶ÏÓÓÒÓÕÆe]šâþÿÿ誺ÒÐÎÌÌÏ×Ï€Kl°ñ€ÿæÀÕÓÑÐΰmŠ¥ÔÔÓÓÒÖÇ|_¡å–ÿÈlnnlÈ€ÿCâ¹ÂÌÊÄÈÒÑ«{npprqoomlkaRNOVgqqTqºóÿÿûÀ¸ÏÓÒÎÏÔ¬Vm±ðÿýé¹®ÍÐÍÌÎÏÔÓ¥VQ…Éù€ÿæžÀÒÎÍÍ˶r¯ÕÔÒÏÎÓÄ|l»ö–ÿÈlnnlÈ€ÿ á¹ÆÑÏÊÇÑÕ¦\IK„J#KOW[[ZRKLUÌúÿÿûÀ¸ÍÊÇÆÍÓ’V€ÐûñعµÔÔÑ€ÎÔÕ®jKf¦êþ€ÿæžÀÌÉÉÌÒ¾w޳ÕÐÇÆÇÑÂ{m¿øŒÿýö÷üþ‚ÿÈlnnlÈ€ÿ àºÌÔÏÏÊÒÕ³qr†ƒ-‡›©«¥‘†€€˜ÆëýÿûÁ´ÆÅÇÊÑÑz[“ÕÚ½°»ÍØÒÑÍÏÔϤbET„ÉúÿæŸÃÎÎÌÌÖËx†®ÐÈÄÉÍÓÀxm¿ø‹ÿûàÎ×׿ûÿÈlnnlÈ€ÿ à¸ÉÏÍÏÉÑϾ~ŠÁ†Ó,áîðëÙ¿¬´˜ŒºòÿûÀ±ÇÑÕÓÔÕoœ±¨³ÒÐÌÑËÍÉ;‘WFTz±êþÿåžÂÑÐÏÉÑÓxtŸËÎÒÖÔÕÇmÀùŠÿöÓ°¼°†±íÿÈlnnlÈ€ÿ á¯ÅÑÍÌÊÎÉÅ…~Æ÷ˆÿ(ù߸¹Æz_ ìÿüøÔ×ÒÏÏÓ©ž¶ÁÑÒÐÊËÎÅÌÓ¿pIE_²äý‚ÿåžÃÒÓÐÍÌÌuf‘ÒÛÔÑÏÑÍ’k»õ‰ÿíÇ®ÀÎY™ãÿÈlnnlÈ€ÿ â¢ÀÙÐÍÎÑÏјx°ñ†ÿ)þïг¿ÖŸS]¤ìÿüƽÓÕÒÏÎÓÓÒÕ×ÔÑÏÌÏÑÌË×¹\MdÀêþƒÿåžÃÑÒÐÎÍÉtfŒÃÜÓÑÎÏÖ®l¤æ‡ÿ û⾯ÏÜ®XYœäÿÈlnnlÈ€ÿ蟺ÚÐÏÒÒÏκ~•ßþ„ÿ(ôÜÀ³ÍÖÊvLt¹òÿüËÁÐÓÔÑÐÑÏÕ×ÔÕÒÏÑÓÐÎÄÓÕ¡}†µï…ÿæŸÃ€ÑÐÐÌxiŒ¢ÚÕÓÐÑ×̇…Ñý„ÿ üîÕ²¹ÑÙÏ…Lq³îÿÈlnnlÈ€ÿô¯©ÎÐÏÒÑÏÈÔ£ƒ´î‚ÿ+óßɱ¾ÒÖØ±^[•ÛüÿüÉÄÐÒÓÑÑͨ¸ÏØÔÎÍÑÒÐÎÂÓ×Ôµ–£×ù„ÿæ¢ÇÔÐÐÑÔÌ€m‘‰ÑÕÓÐÎÑÙ·§é‚ÿþéϽ³ÅÖÓÕµ^RŽÔýÿÈlnnlÈ€ÿ@ø»Ž¹ÔÒÓÓÐÃËʧž½ÜéíéÚǹ»ËÕÒÒÖ‹Npµðÿÿø¸ÅÓÑÐÏÓÏk`ЏÌÑÒÒÔÒË¿ËÐÒØÄš™Íòƒÿ*è©ÈÔÐÐÒṎq „¶ÕÐÐÏÍÔөޱÜóüýïЮ¥ÃÕØÓÐË“Lc¨ê‚ÿÈlnnlÈ€ÿBúˉžÐÕÒÔÉÃÈÎÏÁª§¹Æ¾°¼ÓÖÐÏÐÙÀeS‡Ðùÿÿî§ÉÕÒÏÍÓÕnKLa’¼ÑÖÖÐÃÇËÎÍÕ×É š»éþ€ÿ+þá¦ËÕÑÑÓÔЙt«‹”ÏÑÏÑÒÓÔеœ¤ÅØÚ»š²ÑÖÓÕËÍÁtMÇø‚ÿÈlnnlÈ€ÿpþá·ÙÖÍ¿ËÙÔÈÎÎÀÂÌÎÓÖÒÓÍÉÐÚœSg§èþÿÿéªËÓÍËÌÒÓvfo[SkšÈÛËÂÖØÏÃÊÆÇδ—¦ÙûÿÿûÏœÔ×ÐÐÑÑÓªo¤žw¢ÐÒÏÏÐÏÐ×Óú¹¶¯ÆÞÖÊÆÌÃͶ]] ãƒÿÈlnnlÈÿôº{…ÀÕÅÂÓ×ÓÌÆÅÇÊÍÏÊÌËÍÇÆÐÌ}T€Êø€ÿ(ë±ÄÈÈËÎÑчs ”sYZ~µÁÏØÖÐÈÅÅÈÌÔ¿™Íñÿ÷À§ÕÔÑ€Ð!Ô³eœÁk§ÓÓÌÍÌÎÐÑÕ×ÕÈÃÕÚ×ÑÊÉÌÌ—Pr¸óƒÿÈlnnlÈÿýÜ›m‚­½ÔÜÕÔÔÖÙÚÔÌÎÌÍËËÇÐÖ²`[˜ãþ€ÿMì¿ÇÈÙÚÙÛÞ©t°Ï¸–pVbŽÃÖÖÓÓÔÖÔËËÔË®žºçí²Â×רØÕÔØÁn˜Ðªpl¢ÌÖØ×ÔÕÖØÖÍÈÔÛÏËÊÊÉѽqRŒÑüƒÿÈlnnlÈ‚ÿøÑ•jkŒµÃÄÉÎÐͽ´·»ÁÅÆÅ¿ÇÇ“TlµòÿLìÂÁÁÇ¿½ÄÌ®l›æòÚ¬‚`Wx¦ÇÐÔÔÑÐÐÊÈȸ¼â¹ÕÓÑÏÐÏÍÔˇË×™h^†®ÇÓÒÑÏÇ·¨®¶©–‹‰……uO_£ç„ÿÈlnnlȃÿöÌ•hYbmyƒˆˆk_es|{||z{{bX‡Ðúÿ(ë«…zuigr{r\–äÿþèÚwZ\yŽ›œ™˜–‹‚oYMa­á»®•‡‚€„ ŠŽnxÈôјnV\q‚……ƒxh[ZXQKIGGFGFMu»õ„ÿÈlnnlÈ„ÿ õС{cZXSKJHNW…ZYXl§é‚ÿ'çœYHOXZZVNW•ãþÿÿöÛºiQMQSRRPJFFPZs·à ]FGE HLQwÅüøÖ¬‚cQF€EGPY€Zanrqy Ýþ„ÿÈlnnlÈ…ÿ ùáÁ©¢‰|{{€–¢£…¢§Ï÷‚ÿ zƒ™¢£™„­êþ€ÿýñЬŠ}„z {†œ¯Ýè¨jas{{z{”ÔüÿûèŦŽ|zz{{†›££¢©¾ÈÇÉÜù…ÿÈlnnlȇÿ ÷ìêäÒÌÍÍÌÝéê…éêöþ‚ÿ üäÏÌÏáéêßÏÍäûƒÿûëÒ…Í ÌÐâîüôɧª½ƒÍÌÔ÷ÿøèÖÍÌÑáêééëöýüýþ†ÿÈlnnlÈ‹ÿýü‘ÿþ€ýÿýý‡ÿˆýÿöëìõ…ý„ÿþ‚ýþ“ÿÈlnnlÈ÷ÿÈlnnlÈ÷ÿÈlnnlË÷ÿËlnnm¦ÊõÈʦm€nm÷lmÿnÿnm÷lm€nm¦ÊõÈʦmnnlË÷ÿËlnnlÈ÷ÿÈlnnlÈÖÿ€þýúööùý•ÿÈlnnlÈÍÿþüüöíæäãÝÒËÉÆ¹¯²¸ÈÝîû’ÿÈlnnlÈÉÿùóîåÕÆ»²¨›”Š‚~ƒ‘‘Œˆ— ®ÇÞôÿÈlnnlÈÃÿ"üøôëÜʲ£™Œ{xzoghkjkly‹”—Š•ª¢šš™®ÝûŽÿÈlnnlȾÿ(þúõèØÇ¶©™ˆzoprs}Š„{v|zy€ˆ”š¡©œ˜¥•„voÐùÿÈlnnlÈ»ÿ+ýóçѯŸ—†‰‡‚ˆ™©½ÏØÛÅ¿Áø©£¨¯±¤ ­¨”†€sk\T…ÝÿÈlnnlÈ·ÿ0ûòåÒ½«˜’ž©¯´½Ò×àåêðöøöíÈÐãîìܰŸ–™¦Œ‹„yk]RES°úŒÿÈlnnlÈ´ÿ3ýï×½°­µ¯¶½ÈÐ×ÖÜàß÷úÿÿýõëãçæ¹¤±´ÁÃœŠƒ„„˜Ÿ„‡‰ƒyjZOFDŒðŒÿÈlnnlȲÿ5ýìÇ«£¨ÉÑÀµÃÊÊÌÍÓßÖ×ôøüöíÙÌÒÜÏ©bT–Ê“‚Ї”–†{xrg^QE>räŒÿÈlnnlȰÿ7ýðΩst’”y‘˜Ÿ£©³ÃѺÏâçêàÖÌËÓË¥‚iF<—欋„‡‘ƒwnjgb]PE=eØŒÿÈlnnlÈ®ÿ9þóש•‡YrŒy2-‡’‘𧬛½ÑÍÔÒǾÆÈ·meS`™é·’‰ˆ“ˆ{kgd]WRIC?eÔŒÿÈlnnlÈ­ÿ:øÛ²‘{r_?iŒ ¢He¹Ã©“Ž’¦¦—«ÇÓØÖ°œŠ‡rhe„ â³–Œ‹Œ|p_VQOKDBA@pÜŒÿÈlnnlÈ«ÿ<ýè¾ul{g(3¬‰[}ƒ=$ƒÖ˪›©Ã΢femrv~’ ‡…Šˆœ°Êª’…ƒ‚|og[LBCA9;=B„ëŒÿÈlnnlȪÿ=ôÔ yhqw£+XœbfvnB!]¡¨²Àߌ‚ydŽÏ䨶–—žº¯”€vrsl`XPHA526:9LŸöŒÿÈlnnlȨÿ?ûä¶Šljy¤–´|.NHDcG( *š¶µºµ”›ÎæâÖš¦ãëö츖ÈÊÀœƒoZSa_VKFL< /6UµüŒÿÈlnnlȧÿ?ûÚ£skxˆ¢ºŸŸR2C&1 0´áϲ–¡ÌåïûðŸ†×çñëÊ©ÎÒͰ™„Z9GLKEC8 %$%PÃÿÈlnnlȦÿ@õÔ“]E^¨¦…cS$2> X•ˆk“×äëòøíŸcÀØßÔ½’¢¦¬ ‘~X.5A@9766:=E:1XÊÿÈlnnlÈ¥ÿAò¿w?/9JYv‚}œ‰0%. X­²”¾ÜÞïøòë«J›ÂÆÃ¶‚{„‰tN)15+,5ALNIJEBfÊÿÈlnnlȤÿBó³l_s•·¾œ|hr;A+ $”Ôã¼½Ìãõõíà¯Ev±»¹±„ar}‰€mB!*.'.@EIIHECGhÈÿÈlnnlÈ£ÿD‡­ÌäïðÝͰq ™9+- F¶Öå°¦ÂàõôëÚ»_V¢®­§ŒZ]pxcJ11==?:BIGGIFFHiËþŒÿÈlnnlÈ¢ÿEñ¾•ŸÂÓåííéÔÔåˆXZ6 ++&h¿ËÓŽ½á÷öìÙɆCŒŸ¡¢•jAOK42DRXTSG@FKHIEGHtØþŒÿÈlnnlÈ¡ÿEöÎ¥©ÄÖÛîòèÚÊÃÑ‹j…d5"*'"dª¿ÁppºâôîãÓË«Oj–›šŒ_*HKHHT_`WQLDCKKFCFK…çÿÈlnnlÈ ÿFôÒ¯³ÁÒãêøí˪snRdžj5 \zw…‡UNµÙæãÛÆ¿»{P˜‰^;Q€~vbMLTPMJGDEGCDFUŸôÿÈlnnlÈŸÿG÷а³ÃÑâñíË‹WQl‡ª›l˜¦“wY^—Œ„‘’M“ÁËËȼ´´¤dSnT%6z‰€tfWHFLKFII]„ƒsL20>ACFD:5>B?3BEHzÕþŽÿÈlnnlÈ›ÿIþì»m90/2B„¾ãöûúùôñîÊe—ÝãÒÁŠ;28;<9;>?jÅúÿÈlnnlÈ™ÿIøÒ³ºØæîõúÅtÇêìâÑÈÃÁ¿–G‚«µ¼º¶•O˜Hq’™˜™“Šˆ‰uE329QlP,[c[UMB=;:>:3:748;<]µô‘ÿÈlnnlÈ™ÿHâ¤ÈèôõùúÂtÁÝÜÕõ²°«wK‡¢£¤¤§sS‹™Ÿ_M€‹‘Š„ƒ‚€qG3_’v%4RSME:7897.3;3378R¡î’ÿÈlnnlȘÿIðÕ°Ôðúø÷úÅn©ÆÆÂ´«¦ž”b`„ŽŒ‘QV’”ƒHYp~„‚‚ziJ*fˆ–‡3:DA<4130))9;325Pšãþ’ÿÈlnnlÈ—ÿIøÔ˪½ÚñøøòõÆ[‚¨¬©¥¡›š†Xo‚…‚€>R}‚†‰^/Cfsxzq]C:3)€‰ˆG $6:73/-)+:>85:Z¤æý“ÿÈlnnlÈ–ÿ:þݵëÂâñòõðé·G?h†““˜™šs^z~}}{{:Flt|{w< ?[daH9Jo`*yŠyrkR+€4 0.,5=956d±ì•ÿÈlnnlÈ–ÿGõ»µÁ•¹æîéìêÝ›reGAO^t‡€Scyzywtw‚C9_gnorg<*8@47[‰£})f{l^WN--363209798`¶ð–ÿÈlnnlÈ–ÿFæ°ÃЇt©ÓßáÔ¸wަ–uZNHK=`´ñ—ÿÈlnnlÈ•ÿFù˲Ç×Á‚Xp¤ÊÁg‹–•‰ˆyj.5^hnqqtu}i:I[_c_WD4$‚®¬ª¤†%!FMHB=;744*/:9;IGl·ó˜ÿÈlnnlÈ•ÿEç°ž­ÀÌÊ“ZMqŠY\‚‡…‡‹“›P=]jmosywxvF;NUXK<=^:=š¨œ˜|13<<868:4)-?=:ETwÅô™ÿÈlnnlÈ”ÿE÷˶§£°´³¬—aI!N|ŒŽŽŒ“˜kAVeilsywqnU8;C=>`’¨;C’˜‰€vk: %236:6.(/9<8AVŒÒøšÿÈlnnlÈ”ÿDè´»ÛÓ´¤šš’Š…MErŠ‘“’‚KL[aenspf]R2 2[Нº¡'B}‚tg^T7 /370$'3<846?A<7553+':A<9LqªÝúŸÿÈlnnlÈ’ÿüß˽€™:—s|’š•†zsqU;@MMF<77MfxŠš£³j'gƒ†€sgW!25722440#%6@GG9G€Ãòþ ÿÈlnnlÈ‘ÿ@ûݳ»À•ŠŽk[m…Œ~ne_YM+*:Oby“™—–•Œ4[pogYI4#&'(-21((:;8BHZœÝ÷¢ÿÈlnnlÈ‘ÿ?îÅŸ©¸™pdfqpbUYZWPJB>>%2Rn†“›šŠynbQ9AIIC4*##*0232/343?V‚¼íþ£ÿÈlnnlÈ‘ÿ=ñéµ–fbjld\OPS\df^^d;)Sv‰Ž‘‰oG0-.8C,!*/29<83345575381*B_›×ø¥ÿÈlnnlÈÿ1ùìðÕyURYfni[PHK^mxxvk<3Oag`YL>=EQ`q}iNA>><:866422€41483?t²éü¦ÿÈlnnlÈÿ<ûèêíÎÌ¥f[PSbebWEBKU\_ZPD?9239BFMW[XWSPIC=:410./0200498537JwÂô¨ÿÈlnnlÈÿ;íÕæÚ´ÉÂvcVEAFGGPG9;>DIVc]SE@FKLKFBEC;754320030./0/+.1221322>R~Æö«ÿÈlnnlÈŽÿ9ýéÇÎåªnywS@;?7.15:=CF<443347986320//-/120.1467853>RyÆ÷¬ÿÈlnnlÈŽÿ8ûîÞçñΈurcJFKF7/,2=IMHA?91221332.,,+,+'(,./01233472-9[†Ãõ­ÿÈlnnlÈÿ8þúåÓÙâಕœŒV=?B?83/5:=><::8;9400/.+*)*+('+-/0121/-.+2M…Ëö®ÿÈlnnlÈŒÿ8þûøÓª±º»´…y]=468:<1+(*-,,1:=;:6410/-./.(*-/004751.+3Cg·ò¯ÿÈlnnlÈŒÿ7ýíìÕ™€ƒ¦Ô¤_UOI?689;;:50.+),//0/-.--/010..132237731..=[¤ë°ÿÈlnnlÈŒÿûÛÜëÅ‹½ÞÂ`XTE51.-//1371,+(')('€*+-,+-14664673-*)*Câý°ÿÈlnnlÈŒÿö¾´àìÕºª­¨”yXIC:1,(''-4852/,*-,€*)*(**-0325332,'#'0dÊú±ÿÈlnnlÈŒÿ5ü˪ÇÜàÀŒyrw|]F?9552*'),,*)('*--+-*&'(*+.2433/)%#$#/M§ó²ÿÈlnnlÈŒÿ5ýõѵ´ÑÕ—g[VZQH@<99>3'$%%"!"$%'(**# $)*,0343.)$#%)+6sÚþ²ÿÈlnnlÈ‹ÿ/þññÓ—†¢´™zi_XQD71.-88/*,+&#"%''))**,.//23540('&'€)<–ð³ÿÈlnnlÈ‹ÿýßÌÀ¦„|{sg_aqY>52352,()&#&&'*++€* ./123230,(+)€&*Jºù³ÿÈlnnlÈ‹ÿ5üÉ•¡Õɯ‹fYRGJ_TE@@C>5-(*(%))+..,++*+.03312/*(($$"'7jÖþ³ÿÈlnnlÈ‹ÿ5ø´iÁý¢sTIA?DB><;951/+-0//.--,--../12540.+($#%%"1NØü³ÿÈlnnlÈ‹ÿ5ú¸u®—“•oI?>>=833110,')10.,**++*,.032.-)&%&%&'&*Ac‹Ëõ³ÿÈlnnlÈ‹ÿ6û×Èä±vjv‰nMHMMC3-/+(*-232,)*((+*)*-//.+'##$&&''+3Kp—Äíý²ÿÈlnnlÈ‹ÿûÞÝݯrWT]QB@BA<2-1/+.4753.*,+../..,-*(&!"'.28C]¦Çæú²ÿÈlnnlÈ‹ÿ7ýßÄ« WB?<99:963-.0/-00/..-++.01334210-)&!'1=EL^y›½Õè÷þ±ÿÈlnnlÈ‹ÿþæµ’€qWHC=64531/++.//.+)++**+.€12/,+*&##$*9DOZh¾×éôúýˆÿþý¤ÿÈlnnlÈŒÿ í¶“mTJB>:1..*&(+.0-,)(('(**+-//.*€)&&'.8DR^gwލÈáðú‰ÿþñâáæóþ¡ÿÈlnnlÈŒÿö¿o^SF:2-(,-()-01.,)'$&&*.//€0./1004;FQ\fsƒ™¶Ðé÷þ‰ÿ ûḮ®£´ØôþŸÿÈlnnlÈŒÿ0þÝ {odVF<4+))&'(),-/1/,.-031369>@AB@DMYemvƒ”ªÂÚîúŠÿ õÔ¤µÌÊ»ŸŽ³ßøþÿÈlnnlÈÿ.ôÈŸ‹}m]RH>61/01242125898;==BJOTUW\_goy„‘š¨»Îâòû‰ÿþê¿°»ÃÂÁÄ˶ ÄëþœÿÈlnnlÈÿ þç» ”„vle_WQMI€FB@BGMNNPSY_djosvyˆŽ›¨´¿ËÛéõýŠÿ쮡ÅÊÈÈÆÆÈÎÆ–‰ÅøœÿÈlnnlÈŽÿ*ùÚ½±¥–Š„}vupic__acinqrpt|‚„Š–™š ¦°¾ÉÒÜåðù‹ÿò»¥Ç€È ÉÈÌνŒWk¸ôœÿÈlnnlÈŽÿ)þòÚɾ³­ª¥ Ÿ¡œ–‹‘‘•™šžŸ¢§©¬±¸½¾ÂÈÎÙáèïöû‹ÿ÷Ì¡ÅÊÈ€ËÌ͵xOHn¹õœÿÈlnnlÈÿ'ýðâØÏÇÆÄÁÁÃÁÀºµµ··¹½ÀÂÅÈÈÇÈÉÌÔÙÝàäéïóöúþ‹ÿûÕªÆÏÇÅÆÍÏÉ©nGKeÌúœÿÈlnnlÈÿ$üóìçáààÞÝßàßÜØÖ×ÙÙÛÛÞàãââáâæìðòô÷ùúüýÿò¸®ÆÉÊÊÄÍÓ[DMpÆóÿÈlnnlÈ‘ÿþú÷õóôôòòôóôóóôóòòñòóôöõ÷øúû€ýþ‘ÿñ¨ow˜±¿Æ»‰SEYw¥Ûõÿƒüûý†ÿÈlnnlÈŽÿ þýøôñïïîïôúþÿ€þ‡ÿþýûüþ…ÿûõîííìïõü„ÿó³tYS\rƒrMH_‰¶ãüˆÿþýùòíçÖÓÕØÙÙ×Üèîùþ‚ÿÈlnnlÈŠÿ5ûöîçæßÎÈŽ»¹»Æ×åõþÿÿ÷ô÷õõ÷ôôòîêãÛÙáïþÿþ÷õôãÙdz°¯­µÀÔêû‚ÿûݱq[RMHNk’¸ëþ…ÿúóíæáÛÓÁ²®¤ž£¨¨©¯­¨°ÌèýÿÈlnnlȈÿ8ûîØÍÁ¹º·¯»ÈÆÇÆÀ¶©§¼åúýÒÈÑÊÈÏÉËÆ¿»»¼¥’µæåàÐÌÅ­¸½ÃÄþ©›¨Ô÷€ÿýûøíÔ¶œrq|𱝨ùƒÿ ûçÐż³­¨´ÃÉ€Æ ÅÅÁ¿ÊÒÈ¥ŠµîÿÈlnnlȇÿ2óÙ¼·ÂËÌÊǺ¿ÆÇÇÃÂÅǹ–£Òõϳ½Â½¿ÄÈÍÎËÊ̯f„­§«·º·ÆÎÊÆÇǀʜ•Ì÷ÿùàáàßÞÙÀ £³¿Å u¥çÿüîÓ©§½ÆÅº½ÉËÇÇÈÇÊÉÆ½¿Î¯h[›ãÿÈlnnlȆÿ4î²ÃÍËËÇÇÊÄÂÃÇÆÃÃÅÅο–Öâ—›¼ÄËÊÌÍÈÇÈÌ¿v’µÂ»»ÇÏÉÅÇÇÉÉ€Ç%¹Š’Òøç¥¸ÉÊÉÊËÑÒËÆºˆ\æÿÿþóÚ·¬ºÁ¿º¶ÃÏÑÊ€Ç ÊÈÆÆÁÀ®nCY›ãÿÈlnnlÈ…ÿðÁ·ÇÊËÍËÊÊÆÂ¿ÁÇÆZÅÈ͸†¦Ð—i†¹ËÊËËÆÅÈÈǰ¿¼¸¼¹ÍÓÎÊÈÈÍÍÉÇÆÇȲz›Þà‘}´ÌÈÈÉÉËÈÆ·}eªîÿþë½³»ÇÀ¸¼¼Åι³ÂÌÏÏÌÈÆÇË®hENu±ìÿÈlnnlÈ„ÿnñ¿²ÆËÇÉÍÎɯ†sž³ÃÏËÆÄÆËÒ¡†´¬z^ƒ¾ÍÊÇÆÇÈÆÄÁ½»ÀÂÄÌ´®ÀÉÈÌÌÊÇÄÇÊÈŠ{¼ßj€ÁÎÉÆÇÇÆÆ¹tl½úÿð¹¢ÈÅÀº¾ÇÁ²‰][x ¾ËÎËÆÊ¾zFNsªäþÿÈlnnlȃÿnøÈ¸ÊÍÉÇÇÍÅ—cIGLTo§ÌÇÄÇÊÊ˾ƒ–ɯz`ŒÄÉÆÈÇÅÀ¼¾¿ÅËÇÀ™YTw¤ÇËÊËÉÆÇÉÉ¢m§âÈn›ÐÊÆÇÄÅȹol¾û÷ɨÃÁ¼¾ÁÌÈœjIHRSVk‰®ÄÏÇLOv©ßý‚ÿÈlnnlȃÿÞ·ÄÍ€ÇfËÉ“VFUmyl]q¸ÍÈÄÇÈÉ̹ٴ‡i¦ÊÉÈÆ½ÀÄÉÄÀÌ·PFVXa ÌÍËÉÈÄÈË­g–âôÄ€vÀÍÈÈÆÃĵkl¾ø×§ÀÁÃÅÈÅÞYESm†„jXO_ƒ°¥YKq¨âýƒÿÈlnnlÈ‚ÿmùÁ½ÌÉÇÊÍУ_J_…­À´j˜ÌÉÂÅÇÉÏ•kžèî¾~ŠÅËÆÁ¹ÉÉÆÁÂÀKKd‰‹kuÂÌÊÇÇÃÄÊ·p“Ýýé©xÎÌÈÄ¿À±fpÀê¶¶ÄÁËÅÄÁ£]GY‚¬ÊÈ®—~fU[]I`Ýý„ÿÈlnnlÈ‚ÿlÛ¹ÆÊÇÊÌнpGc“ÅíúõÎ’‚½ÌÅÆÉÌÏ™_–çþ橃ºÈý¾ÆÃÄÄÃPNpŸÅËw·ÉÈÅÆÇÇ˽s„ËúüØ’„ÉËý½À¯e‚É֭ƾÃÄÂÆ»yGY‚ºéûúíÜÆ¥`S^‰Ç÷…ÿÈlnnlÈÿ_ú½ºÍÈÇËÍÏœUX…Âçéèè帉´ÉÈÊËÎÍš^•çÿü̯ÅÅ»ÃÆÂÆÌ¥ZMr¥Û÷ùÔ—¹ÉËÆÅÆÈǵerÁøÿð±†ÁÈÁ¼Âűf“Ñ®µÄ¾ÆÁÄʤSR¸ìÿþùå¿•š»í†ÿÈlnnlÈÿÞ¯ÃÍÆÆÉÉÊ–l„«ÓƱ®°²«¡»ÀÈÍ€ÌB›_•çÿÿ㞨¾¾»ÅËËÌÆ}JcœÜüÿÿ裿ÊÊÂÃÇÆÃ«XpÀøÿûÌŽ¾ÇÄÄÊʯg“À’À¿¿ÉÊÏÅyLo«é„ÿþôäáãïþ†ÿÈlnnlÈ€ÿ_ýÀ­ÆËÉÈÈÆÇ¹´º»ÁÇËÊÊÌËÉÅ»ÄÉÈÉÈ’\–çÿÿò²«ÀÃÂÈÊÈÊ´_U‡ÊùÿÿüÏŸÆÇÅÁÅÈÉËœT}Èùÿþàš»¿¿ÉÉˬhŽ«¢ÊÂÄÊḚ́Y[–×ü”ÿÈlnnlÈ€ÿù¶¶ÆÅÊÇÁ€Æ%ÈÄÇËËÈÈËËÊÈÀÂÄÁÆÂ‡Z–çÿÿû¾¯ÅÈÈÊÇÇÌ™Ql¯î€ÿô²¶ÉÇÈÅÊËÍÈzS’Ýýÿÿ渽ŀÉ«i‰ž¼ÌÅÈÇÉÈ—Mm·ô•ÿÈlnnlÈ€ÿ^öÁÀÈÀÀÃÄÇÍÏÍÌÊÍÓÓÏÌÏÐÏÊÄÈÊÈÆÂyW—æÿÿû¿°ÅÇÈÉÈÊÍ}QÍúÿÿþÕ¤ËËÅÆÅÉÎЭ[[›äþÿÿ朶ÅËÉËÉ©j‡šËËÆÉÈÌÄ‚P„Îþ•ÿÈlnnlÈ€ÿCǽ¶ÃËÉÅÀ¿¿¼ÀÅÂÁÀÁÀ·¨¡¡¨¸»¹ma¡éÿÿû¿°ÆËËÊÊÌÀd]šâþÿÿ訴ÊÅÄÄÃÈÐÇKl°ñ€ÿ朸ÌÉÈÇĪmФËÌËËÉοz_¡å–ÿÈlnnlÈ€ÿCá³¹ÁÀº¾ÉȦymnnoolmkkj`SMOVfopTqºóÿÿûÀ²ÇËÈÅÇ̨Vm±ðÿý鹍įÃÃÅÆÍÌ¡TQ…Éù€ÿ朹ÈÄÄïrŽ®ÌÊÉÆÅ˽zl»ö–ÿÈlnnlÈ€ÿ ßµ¾ÆÄÁ½ÇÍ¢[IK„J#KOX[[ZRLLUÌúÿÿûÀ±ÄÁ½¼ÂÈW€Ðûñض±ËËÈ€ÅËÍ©hIf¦êþ€ÿ朹ÃÁÀÂȹv޲ÌĽ½¾Ç»xm¿øŒÿþöøüþ‚ÿÈlnnlÈ€ÿ ßµÂÉÅÅÁÈ̬pr†ƒ-‡›©«¥‘†€€—ÆëýÿûÀ®¼º¼ÀÅÆw[“ÕÚ»¬´ÄÎÉÈÅÇËÇ aFT„Éúÿæ¼ÅÅÂÂÍÄw†­Å½¹¿Ãȸvm¿ø‹ÿûáÍÕ׿ûÿÈlnnlÈ€ÿ Þ´ÁÆÄÄÀÇŶ|‰Á†Ó,áîðëÙ¿©¯”‹ºòÿüÀª½ÇËÊËË~o›°¥¬ÉÅÁÉÁ¿¶WFTz±êþÿæ¼ÈÆÆ¿ÆÊvtžÁÄÈÌÊ˾{mÀùŠÿöÔ¯¸«†±íÿÈlnnlÈ€ÿ ாÈÄÃÁÅÀ¼Æ÷ˆÿ(ùß·´¿y_ ìÿüóËÏÊÇÆÉ¤š±ºÉÈÇÁÂÅ»ÀȶnJE_²äý‚ÿæ¼ÉÊǀ rg‘ÊÒËÉÅÆÅŽk»õ‰ÿíǬ¸Æ~Y™ãÿÈlnnlÈ€ÿ ã¢¹ÎÆÄÅÈÆÆ’x¯ñ†ÿþïб¹Í›T^¤ìÿüÆ·ÊÌÉÆÃ€ÉÌÌËÈÇÄÆÈÂÀÍ´\NdÀêþƒÿæ¼ÈÉÇÅÄÀrfмÒÊÈÅÅÌ©l£æ‡ÿ û⽫ÇШWYœäÿÈlnnlÈ€ÿèžµÐÇÇÉÈÆÃ²|•ßþ„ÿ(õܾ®ÅÍÂtLt¹òÿüʼÇÊËÈÇÈÆËÍÊËÈÆÉÊÈĺÉÌ|†µð…ÿæž¼ÈÈÇÇÆÄviŠžÒÌÊÇÈÍÃ……Ñý„ÿ üîÔ°´ÈÎÆƒLq³îÿÈlnnlÈ€ÿô¯¦ÈÈÇÊÈÆ¿Ê ƒ´î‚ÿ+óßÈ®¶ÈÍΫ\[•ÛüÿüÉ¿ÇÊÊÈÈÅ¢²ÆÏÌÄÄÉÊÈŹÊÎ̯”£×ù„ÿ桾ʀÈËÂ}m‡ÉÍÊÇÅÇϱ~¨ê‚ÿþêл¯¿ÎÊ˯]RŽÔýÿÈlnnlÈ€ÿ@ø¼Ž´ËÉËÌȺ¤¾ÜéíéÚŵµÃËÉÉΈNpµðÿÿø¶¿ÊÈÇÅÉÆk`‡±ÅÈÊÊÌÊÁµÂÇÊн˜˜Íòƒÿ*è¨ÀËÇÇÊÌćq ƒ±ÌÇÆÅÃËÉ¥±ÜóýýïÑ­¢¼ÌÏËÇÂMc¨ê‚ÿÈlnnlÈ€ÿBúˉ›ÉÌÊÌÀº¿ÅǺ§¥·Ã¼¬¶ÊÍÅÄÇϹeT‡Ðùÿÿî§ÂÍÊÅÄÊËnLLa¶ÊÎÎȺ½ÃÄÅÍÍÁ›™»éþ€ÿ+þâ¤ÃÌÈÈËËÈ—u«‹‘ÆÇÆÈÈÉÊȰ™£ÄØÙ¹™­ÇËÉÌÃĹqMÇø‚ÿÈlnnlÈ€ÿpþဲÑÎÆ¶ÃÐËÀÃÆ¶ºÃÅÉÌÉÊÿÇЗSh§èþÿÿé©ÃÊÄÂÄÉÉufo\Ri–ÁÒºÍÐÆ»À¼¼Å®–¦ÚûÿÿûÏšËÎÇÇÉÉ˦o¤žvÇÉÆÅÆÅÇÎË»´´²¨¿ÖÍÀ½Â¹Ã°]] ãƒÿÈlnnlÈÿôº{„»Ì¼¹ÊÐËý»½¿ÃÆÀÂÁü»ÆÄzT€Êø€ÿM민¾¿ÂÅÈÆ…s ”sYZ}®¸ÈÐÎÉ¿»»½ÁÈ·™Íñÿ÷¿¤ÍÍÇÇÈÈÌ­eœÁj¢ÉÉÃÃÂÅÈÈËÎ˾¹ÌÒÏÇÀ¿ÁÃ’Qr¸óƒÿÈlnnlÈÿýÜ›o§´ÊÓÍÉËÎÐÐÊÂÃÂÃÀÀ¼ÅÌ­_[˜ãþ€ÿMì¾¾½ÎÏÏÑÓ¦t±Ï¸–pWbмÎÍÊÉÊÍÊÁÁÊ©›ºçî±¼ÎÏÍÏÌÌѺm˜ÐªpkÄÍÏÌÊÌÌÎÍýÊÓÈÂÂÃÃÉ·oRŒÑüƒÿÈlnnlÈ‚ÿøÑ•jj‰¯¼½ÁÅÇÅ·®°µ»¿¿¾·¿ÀTlµòÿLí¹¸À·µ½Å©l›æòÚ¬‚aXw¡¿ÈËËÉÈÇÂÀ¿±Š¼ã¸ÏËÈÆÇÆÅÍÄ}‡Ë×™h^ƒ¨ÀÉÉÈÇÀ±¡§¯¤’‡„ƒ€‚rO_£ç„ÿÈlnnlȃÿöÌ•gYbny~‚~k_ds|€{y{{bX‡Ðúÿ(ë«‚xtifr{q[–äÿþèÚw[\x‹•—••“ˆ€oYNa­áº¨‘„~€ ˆŒmxÈôјnW\p€‚‚wgZZVOJIGGFGELu»õ„ÿÈlnnlÈ„ÿ õС{c[XPJGGNW†ZXl§é‚ÿ'çœZHOXZZVOW•ãþÿÿöÛºiRNQSRRPKFFPZs·ßžYEGF IMQwÅüøÖ¬‚cR€GFGPY€Zanrqx Ýþ„ÿÈlnnlÈ…ÿ ùáÁ©¢‰|zz€–¢£…¢§Ï÷‚ÿ zƒ™¢£™„­êþ€ÿýñЬŠ}‚z{z{†œ¯Ýè¨jas{{zz{z{”ÔüÿûèŦŽ|€z{†›££¢©¾ÈÇÉÜù…ÿÈlnnlȇÿ ÷ìêäÒÌÍÍÌÝéê…éêöþ‚ÿ üäÏÌÏáéêßÏÍäûƒÿûëÒ…Í ÌÐâîüôɧª½ƒÍÌÔ÷ÿøèÖÍÌÑáêééëöýüýþ†ÿÈlnnlÈ‹ÿýü‘ÿþ€ýÿýý‡ÿˆýÿöëìõ…ý„ÿþ‚ýþ“ÿÈlnnlÈ÷ÿÈlnnlÈ÷ÿÈlnnlË÷ÿËlnnm¦ÊõÈʦm€nm÷lmÿnÿnm÷lm€nm¦ÊõÈʦmnnlË÷ÿËlnnlÈ÷ÿÈlnnlÈÕÿ þýüüúôíðõû•ÿÈlnnlÈÍÿýüúóçÞÙÕË¿¹¶±šƒ“¯Îæöþ‘ÿÈlnnlÈÈÿþöíçÛȵ¤‘ƒulhaVSRSND603-0562..+8G5#$#'4RŠÏùŽÿÈlnnlȾÿ(ýùóâϹ¦–…ucVRST^g]OFHIID;1-)(1;VmaO7*2jÄøÿÈlnnlÈ»ÿ,üñã˦’ƒtkkjl~…™ª¹Ãô¹·®œ‰pT8'2IX[I6%"jÓþŒÿÈlnnlÈ·ÿ0úðàʳ ‘‹‡•˜¢¼ËÞåéìëåÞÔµ¼ÅÆÆ¸^.#=90+  0 ÷ŒÿÈlnnlÈ´ÿ3üìв£Ÿ©¤ª®¶¼½¾ÇÎÒïøÿüôèÔľ‡XY^tƒiE$&.  vêŒÿÈlnnlȲÿ5ý缞š ÄDz «°¬¤™—¥©¸åðçÌ·¥ ª«WCmS@($"  VÙŒÿÈlnnlȰÿ0ýëÂ’ouƒ¢–mtrpg`X\jj¸¾¦ˆzx…™d6Q‚^I,%"  €EÌŒÿÈlnnlÈ®ÿ9þñÏ–trlSz‰:'mmYH??FazTB**)   eãŒÿÈlnnlȪÿ=ñʉZELV‡r&M˜r•´“LARY\l„ƒ[* 6o™£‡bSsƒZ;.!   ‡óŒÿÈlnnlȨÿ?ûÝ¥pMHX…y˜j%@BO†n<V_\joO<9.+<1Bl{™¯Ša£}A&    *¢úŒÿÈlnnlȧÿ@úÑZNYk‰¤ˆ†@!1-C'  …›ƒtc\S9&1PD9YMTmoe˜œwB)#   3µþŒÿÈlnnlȦÿ4òÈ€M5Cp–{YD* NqW>XrP%0LC(OE=@KK=*€  ?¾þŒÿÈlnnlȤÿCð¨]Oh³¹gažŒ+ @@CDY?0249BA0NQKL?,00.&  =ºþŒÿÈlnnlÈ£ÿDê¬ecˆ­ÐßÛÑɬ`vn*  &Q@IG)"/$>>/#  €   5®ùÿÈlnnlÈžÿ:üɆx“ªÇæØŸX4H|ž«Â¼nbkVHN*0/2$')*-2DP/6A<=>>AG; ** €   WÖŽÿÈlnnlÈÿ)üÞ’py¨³ŸjK\…¡§ ¢°£‹…dSPH)667)+7613C<'78€=?A9%.!    $ŽóŽÿÈlnnlÈœÿIýä“SQZklabw𝱥•’›j}»‘YH0$=BB26><4)7A/%4<=?@9$+<4)    VÊþŽÿÈlnnlÈ›ÿ;ýáªg:/+,:w§¸·¦‘ˆˆ‡†u7^–y}e$.@8'!5=<;03:=-66:9&0* €  €-òÿÈlnnlÈšÿ<þ먊¤¥¢ ƒl³Ë½ª•„|~|xM'Ymjj}Š/!*,8@<83029+-4,  - € eØÿÈlnnlÈšÿ@𾉎®ÄÖáµm¬¼¯¡Žwoh^-2U\[Yku+:M8/=A;60-/3:#!- %  ‚HµøÿÈlnnlÈ™ÿAö¼Œœ¢±ÆÛ¬Y’¦ž“ƒxobZE9SWSMdZ0OQ)*3573.*+071  €;¦ñ‘ÿÈlnnlȘÿ4ýÑy|§£«¿Ò¡S‚’Œ‡yoj^S5?PNFCcE%BU@$*22-*+/0+ €  *Žê’ÿÈlnnlȘÿ9ã¦h‚£­¤¨¶ÇœIiyvsld`WM*+@IF=8J*,>BN !,/..-)! /,ƒ +‚Ûþ’ÿÈlnnlÈ—ÿ:ô·Žmƒœ««­®¶—:941,!%$"€ !,38‚ )~Óû›ÿÈlnnlÈ“ÿD÷Á„}‘oDS^C((7G?"3@A>92//!" %,&#,1     LŸåüœÿÈlnnlÈ“ÿ9îÄ‚cmV6@QE.%*084*464-(&# )/1*&&  € "c¼òžÿÈlnnlÈ’ÿ7ýèÁX[F-2FPA(!$)0(#%$"  "AF.(  €DÓùŸÿÈlnnlÈ’ÿAöÝ»[P:,29RM*#""% $-7>Z; #    ^´îý ÿÈlnnlÈ‘ÿ@öǤšˆ^<,'0,,(  *./034?  0Ñö¢ÿÈlnnlÈÿ@þߤ‹€x]2"(    ).153+#   R¦çý£ÿÈlnnlÈÿ1ùÖÓ­s]C0$' ,5>C<+      ‚ "rÅõ¥ÿÈlnnlÈÿ)éÒé¿H &*"#$'% #(&"€ :“ßú¦ÿÈlnnlÈÿôÎÓÞ¼º-&$€ €€  =¦î¨ÿÈlnnlÈÿ/á¶Å²Ž¹¤A&"   €:¥ñ©ÿÈlnnlÈŽÿ!ýݶŸzf•¤S"    €   <¡ðªÿÈlnnlÈŽÿ÷Õ™zhe|Y#  F«ñ«ÿÈlnnlÈÿþêÉŸ£Â‹A@B%  ‚ƒ€€B¬ó¬ÿÈlnnlÈÿûØ»«¾Þ¼`?A6    €€  B¥ñ­ÿÈlnnlÈÿôÉ¡”©ÄÄfcS* €€€€ 7£ð®ÿÈlnnlÈŒÿ þçÄ™onuƒ]G>$   ƒ€ )’é¯ÿÈlnnlÈŒÿûÐü}OEj¦ˆB(""  ƒ€€€€ ~áþ¯ÿÈlnnlÈŒÿó¼Âã¶iZ¡’X2,/" € †€ `Òü°ÿÈlnnlÈŒÿ蜠ÊÄŸ|cZSE3"  €„€ 9´÷±ÿÈlnnlÈŒÿ袕¦§«ŠM-"&.! „  ‰í²ÿÈlnnlÈŒÿçÆ²’‡¢¢b0 ! ‡€ FÊý²ÿÈlnnlÈ‹ÿýÒ·¦qUeoZE9-!  ƒ uç³ÿÈlnnlÈ‹ÿú¾•{Q6.198* €  ƒ  £÷³ÿÈlnnlÈ‹ÿø¯pzµ©vD'$# €€‚ >Åü³ÿÈlnnlÈ‹ÿôžQc–‘~]1 €‚  WÈú³ÿÈlnnlÈ‹ÿö¢`‚xTKI@"    €  ‚9h¸ñ³ÿÈlnnlÈ‹ÿ÷À²Ë‚:''/$  € € € &Nz°åý²ÿÈlnnlÈ‹ÿùËÅÂ:  ‚€  L\n‡¨Çãõý‰ÿ úÕ‘tsyŸÒóþŸÿÈlnnlÈŒÿýÔ†VD7+  €€€€ $-9GR\lš·ÒêùŠÿ ñÁps‹|deŸÚ÷þÿÈlnnlÈÿ.ñµzaVG6+#  #*/147Nu±ìÿÈlnnlÈ„ÿê–r†ŒˆŠŠjJ>H`u†Œ€‡X‹“eq³­yHG|Šˆ†ˆŠ‡†„€„††Švs‹‹Œ‹Šˆ†‡ŠŠYr¼ß\M‚‰‡ˆˆ‡ˆ€Lj½úÿíšj‰ˆ„€‚ІtR45Bc}ŠŒŒ‰Œ|G7NsªäþÿÈlnnlȃÿn÷©x‰‰ˆ‰‚Z99DC=?jŒ‰‡‰Š‰zYʯxJS‚‰‡ˆˆ‡ƒ‚†‹‹{`77Ef‰ŒŠŠ‰‡ˆŠ‰a\¦âÈS_Їˆ‡‡‰{Ej¾üõ³k„„€ƒŒŠc<7FQJMri;Ir¨âýƒÿÈlnnlÈ‚ÿmøž}‹‹ˆ‰Ž‘cX‚¬ÊÈ®—~dG<>@`Ýý„ÿÈlnnlÈ‚ÿ9Í~‰Š‹‘v@=d”ÆîûöÐYއ‡ŠŒ^P—çþæ§Zx‰…€ˆ††‡ƒS9MpŸÅÌ›Y|Šˆ†€ˆ/ŠxD€ÌúüÙ‰M†Œ†„qDÊÇtˆ‚…†…‰{H=X‚ºéûúíÜÆ¦`R]‰Ç÷…ÿÈlnnlÈÿ_ù—vŒŠˆ‹‘[>W‚¾ßßÝÞÛ¬`z‹Š‰‹Ž^P–çÿüËvq…‡…‡„ˆŒc7Is¥Û÷ùÑv}Š‹†‡†ˆ‡t>nÁøÿñ¬b‚‰„…†rF’ÌŒr‡ˆ…‡Šb8R¸ìÿþùå¿•š»í†ÿÈlnnlÈÿ^Ôw‡ˆŠ‹]Kj±™~ye~…‰‹‹Ž_P–çÿÿã‘s€ƒ€†‹‹ŒƒFAcœÜüÿÿäv~Љ……††„qBnÀøÿüÉo€ˆ††ŠŠpF“µ_ƒ‚‰Š‚AEo«é„ÿþôäáãïþ†ÿÈlnnlÈ€ÿþªu†Œ€‰Wˆˆzuzy|ˆ‹ŒŽŠ‡…ˆ‡‰ŠXN–çÿÿò¥xƒ†…‰‹Š‹t@R‡ÊùÿÿüÄe…‰…ƒ…ˆŠŒdE}ÈùÿÿÜ{}ƒŠŠ‹oHŒ˜fŽ…†ŠŠŒp7Z–×ü”ÿÈlnnlÈ€ÿùšЇ‹ˆ„„€‡ˆ†ˆ‹‹‰‰€‹‰‚„…‚…ƒML—çÿÿû±|†‰‰Šˆ‰_Cl¯î€ÿñ“sЉˆ…‰‹Ž‰IL’Ýýÿÿâ~|‡€ŠnJƒzxˆŠ‰‹†\>m·ô•ÿÈlnnlÈ€ÿ^ö˜‚Œ‚„……ˆŒŽ‹Ž’“Ž‹„‡‰‡‰‚KO˜æÿÿû²}…ˆ‰Šˆ‹ŒIG‚ÍúÿÿþÉp‰Œ‡††Š‘o7W›äþÿÿâ}{…Šˆ‹ŠmKuŠˆŠ‰Œ‚RM„Îþ•ÿÈlnnlÈ€ÿCì|Š|„Šˆ„€~|„ƒ‚wrnhhkr{tI]¢éÿÿû²|†ŠŠ‰Š~@Y›âþÿÿãvŒˆ†……ˆ†H?l°ñ€ÿâ|{‹Šˆ‰‡mL€xŠŠ‹‰€O^¡å–ÿÈlnnlÈ€ÿCÝ…z†ƒ‰‰gGABABCBDBB8997758CFCqºóÿÿû³~‡Šˆ†‰iBl±ðÿýâšcƒ‰…„†‡‹_5O†Éù€ÿâ||‡†…†…pN‚{Љ‡†Œ~Nj»ö–ÿÈlnnlÈ€ÿÛ„}Ї„‰eFIJIJ‚I/JOWZ[YQKLQzÊúÿÿû³}„ƒ€€…‹NGÑýìÆ‘o…Œ‰††…‹ˆl>@f¦êþ€ÿâ~}ƒ‚‚†ŠrJ}‡‚‰|Mk¿øŒÿþñíøþ‚ÿÈlnnlÈ€ÿ Ú†‹‡‡ƒ‰‹jTq„„„ƒ-‡›©«¥‘‡ycr½ëýÿû²|€ƒ‰ŠFT•ÏÊ™tv†ŽŠ‰…‡Œ…]8:S„Éúÿâ~~†…„…{Fyy‰‚ƒ…‰zMk¿ø‹ÿûÔ¨«ÅæûÿÈlnnlÈ€ÿ Û‚~‰…‡ƒˆ†wZ„†Ó,áîðìÚµƒoZ»òÿû²x‡‹‹HW‡‰llˆˆ…Š„…‚„xX:@T{±êþÿâ~€‡‰ŠOjq†‡‰Œ‹‹QkÀùŠÿô€qvt²íÿÈlnnlÈ€ÿ Þ|zŠ……„‡ƒ|PsÇ÷ˆÿ(ùцqzHV¡ìÿû³|‰ŽŠ‡ˆŠ\Zsw‡Š‰„„†€ƒˆq<4D_²äý‚ÿâ~‰Š‰…†…M^iˆ‘‹Š‡‡ƒX`ºõ‰ÿê¬uw‚NP™ãÿÈlnnlÈ€ÿ ã€~‡††‰‡ˆU`¯ñ†ÿ)þç¶|qŒ^>]¤ìÿû´~‰‹‰‡…ŠˆˆŒŠˆˆ†‡‰…„‹i3EdÀêþƒÿâ~‰Šˆ‡†ƒL_es“‹ˆ†‡ŠiK¢æ‡ÿ úØm‚g8YäÿÈlnnlÈ€ÿé†{‰‡‰‰‡ˆoOŒáþ„ÿ(ðÉ–n‚FDu¹òÿû¶‡ŠŠˆˆ‡ƒ‹ŠŠˆ‡‰Š‰‡€Œ^Vyµð…ÿ≉ˆˆ‰†Mfv^‘Œ‰ˆˆŒ~NzÑþ„ÿ üç¾s‰ƒJ>q³îÿÈlnnlÈ€ÿôk„ЇЉˆ„Œbd®ï‚ÿ+îΧxwˆŽ’mAY•Ûüÿû¯}†ŠŠˆ‰‚]p…ŽŒ††‰‹‰‡~‹ŠpdÓù„ÿ⊉‰ˆŒ†Pk‡S‡Œ‰ˆ‡‰qW êƒÿ ä¼–ty‹‹o;PŽÔýÿÈlnnlÈ€ÿ0ø¶_rŒ‰‹‹ˆ†fq¦ÑáæßÆžysƒŒ‰‹P?pµðÿÿö’xˆ‰ˆ†Š„68Rs„€Š ‹Œ…|„ˆ‹y\~Éóƒÿ*ã‚‚Œ‰ˆ‰†Pnœcqˆ‡‡…‹ˆdfžÖóýü鿈j|ŠŒˆW;c¨ê‚ÿÈlnnlÈ€ÿBúËp_‡ŠŒ„€‚‰…qcuœŽnm†Žˆ†ˆp;MˆÐùÿÿì~~‹Š‡†‹ŒDD<[ ãƒÿÈlnnlÈÿô»nOu‚€‹Œ…€€‚„†‚„ƒ„€€‰‚FJÊø€ÿMè‚€‚ƒ†‰‰Ki¡”sV>Gr}Љ‚ƒŠuY}Åðÿ÷¯fŽˆˆŠŠŒuPœÁuBcŠŠ…†…‡‰‰Œ„ˆ„ƒ†„\?r¸óƒÿÈlnnlÈÿýÜœ]Jex‹“Ž‘‹…€‡ †…‚Šk@W™ãþ€ÿM臂…‘’“ab°Ï¸—oH>TzŒŒŒŽŒ……Œ‚is²çê’wŽ‘~N–ѪfDb€Ž‹ˆ„‹†‚ƒ€xpBLŒÑüƒÿÈlnnlÈ‚ÿøÑ•]DPpzvx…uqrrvyxxtzzSEmµòÿLé†vszxvy|hWšçòÚ¬‚\CHd|†‰ˆ††…€{sUt½Ü‡‰‰‡†‡‡†Š‚S„Ë×™bBNiy†ˆˆ„{rjno`]YZRDGA;_¤ç„ÿÈlnnlȃÿöÌ•fG?BAALRG>;>BEFEDCEE?Q‡ÐúÿEè†O>A@?BB@L•åÿþèÛwS=GW[\[[YWP>;;_®ÙˆbZWTVVUXVIuÈôјmK:=NVVRC=;;74@B@@€AMu»õ„ÿÈlnnlÈ„ÿ õС|c[XMCBCMX†ZXl§é‚ÿ(ç˜SEOXZ[VJU•ãþÿÿöÛºŽiNCBDCBAABFQZs·ÞB8BBABKwÅüøÖ¬‚cPCAABFPYZZ[bnrqy Ýþ„ÿÈlnnlÈ…ÿ ùâ©£‰|{{€–†£¢§Ï÷‚ÿ {ƒš££™„­êþ€ÿýñЬŠ}…{ †œ¯Ýè©jat|‚{ |”ÔüÿûèŦŽ}€{|†›££¢©¾ÈÇÉÜù…ÿÈlnnlȇÿ ÷ìêäÒÌÍÍÌÝéê…éêöþ‚ÿ üäÏÌÏáéêßÏÍäûƒÿûëÒ…Í ÌÐâîüôɧª½ƒÍÌÔ÷ÿøèÖÍÌÑáêééëöýüýþ†ÿÈlnnlÈ‹ÿýü‘ÿþ€ýÿýý‡ÿˆýÿöëìõ…ý„ÿþ‚ýþ“ÿÈlnnlÈ÷ÿÈlnnlÈ÷ÿÈlnnlË÷ÿËlnnm¦ÊõÈʦm€nm÷lmÿnt8mk@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿic081™‰PNG  IHDR\r¨f$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½g—dÙu¦wÂûô®lWµÐ Hˆg8ÐŒ–~›¾é›f- ‹¢†#†@íÊf¥ÏŒÈð^ϳoMŠ£& ‚YÕÝQq͹7ÎÞûÝï6'÷ñË´z¬îÀê|+ï@þ[yÕ«‹^ÝÕˆ;Püû÷a¹\‚¿OV¯îÀÛrr¹Ü×.åk À/+•J*¿öñ×vXý±º«;ðfÞÙl–&“Iú]#ÿ[I÷C…ÿÇ?þqzüøñ×6z3/w5êÕXÝ×w@ãþäÉ“ô“Ÿü$F£ô üV¸¡–_áÿþ÷¿ÿz¿Õëê¬îÀ[tþê¯þêkWóHÀß…_ÛrõÇê¬îÀ}þ¿dû(€7ú Wƒ_ÝÕø'Ý•ø'Ý®ÕÆ«;ðvݯqo×¥­®fu¾éXþ–ô~%[.³pÙk²ì›éMÛn¥Þ´_l5ÞopÌeÉòY‹×y-¯__ïÎßD¾ËyZ,fi>û' çs%˜ò|*@ŒÇk¡Àw*…¯ÇÑÝãM~¬À›üë}ëÆ®Ðf¢½\.âê¿Nl)Á™5÷{Þ¥Å<{ýív¿Mtãs¶™Ï&i¾˜ïÇß ¡Ï¡ ùrÊç ©Xªò¾”JåJÊó]>ÈT Zx³ÂJ|ë„èv_°Bëc‰åVh3Á]"lÙû9É,‹¹ -£4›OӔĖÅB+>WÜÓ‚í|?™ãûñhÈöó4Î8&Ï3Ó*Ôå»~ ÏØ– „;új*«©^ß ?¦™Zkû©Zi¤VkePKµz“mË … á9Üî»ûG·Rÿðž¬>ùƒÜšùF4„]Öró™B«ÀÎxÍ6Ì„|>§élš†Ã~šñ~4 Ô³4ãé¾lg£4™NÒ°ßMfÀÍ&SƒÇCpB­÷r>IÓQ%ÒKýÁ §™"Ô*@®’Êåzj6¶R­¶žÖm”ÁZOvSµÖä; Ê(…B„¯xT„®Â›óX)€7ç·z‹FºÄ‚H,9B‚‹ ÏµìµŸõû×aåô)ÛŽG¼V}Š@#¸“éE0KÃÑ ^GÓ)Ÿ/ÒÔã @æ¼Î@cB „‘OK$¿TJ©ÕÌ¥"Â^ëÒ)NQ3Ž5d»)J`”†è¦á²˜ ƒr:î® j ‚µT©6ÓÆænª×ÖÒÖÚÔ¬m§íõÇ|¾2Ø ×áMá V à-«Ûp)dw$7P>3ó!Âç¥Â9 ž¦Á¸Ÿ +¯¥ð¹BÛí\¥Ñxº½v¦z×|?B@ÛX_,7¾ûL$0ÆÒ«Æ¢n§žóÏ‚sOP2 Tƒì“ÑÏò©ZMi‚µ®– ©Q.§R¡p?\\Š´¥e¾Íö 9„E>ÍÇ%D‰cÖR¹ÔHáNjÔ6Ó¨žÖ›wRn^NÍæ(Ü‚"®ƒ®Á›AX)€Û 5oø¾#l’j33 ¼‚®/®€bÕû@õÑd˜z½nÀ÷óö9éC>ן"ô7Ð~ì+žý„ÿSº`êñ×SnJºúeÂö#Ђ?ÚÏÕ5yØûðaFòâ¹ÌóEQ`ÎwXw¿.—©XA¨Ë( ¾›äÆÀöjªQ“æ…´˜(äsWN•Z)mí`÷ñŒ± K†ŒOäÒáZºã“tuþ"Urëé«Ògi4ððÑÒþÁ»©\©1Þ2ƒ»½DáJ¼áÂ÷‡¾Bî}ÍžúÕ>õõìS¬·¯sV’®?ècɇ©Ým#øƒtÙ¹Þ÷ÒÉÅQüÝÇâëÓÙfŠh"¹)!}yhPÎ`!=Û%ù$ûÜvK®Åusw̬/¯E}zƒ{¨ ±ºL…ˆ Ä~l»È£ P…ø›m8@EËIæS£^Eq,S~ĺõåUÀênoƽ°øÃ×ì=²àèœËÕTF`Š¥2Ïbª5ëøíKŽ¡ÅŸð @9äŠãTâó B*ïftn¹È%¿P~‰rÈsìRi,Ÿ!ÌsÀ ¤:ß¿R„éÏŠ3žý´¨²ÿÕ%¦øÃ©b¾Dàsý”›Ó‚û±˜¡U"¿'œx>ºNÆØhlóýWàä!ª…HÁmäV àßZânÉùµî?Ç·HŽ—©ïv»Lèn::|¿N¼< ;$ÜBˆ?’Ç"kí±»SH-`ç œ.6› š-í•Ö‚bXõ<¦u/ ì•Z…pZ)Õ[ „¹¯*€b±„€³¥È±§éì„1]¦ñ¼Š "ž ž/Þ›€> ÓA”,œ´Á¥r…"èñÊæ¹!ŸŒ?Æ»²ßÎbl¸˜^l¦",9¿[PNS¢ãù)Pÿ*Ü‘ ¡Â `¾Ðeá|($‘°„ãA8‚ø89ÿ9Çýùßþeºº¼HïàaºóÎ*ÌàÎ-ùÑÆJÜžßâ2’×ÞW}ù`烼Ë|ö!0vÑ%”—¤k·¯R÷º“ž=ÿŠÏPø¾sˆ;$Bà8sà­‚])I| 剋cùò0ç•B-mÔvø®ŠÀWCøË½J ¬@ð[k(€j%,~¤ßjŸo\g‰7}òÉ4O·ÎÙ ë ðpÖÙŠhÀ|”FŒmÿ0Å5™a‰‡ƒ"‚ÝCÞc¬î£Í_ŠóÍ–H+®‚ ¢‰?ù9 Uµ$X‹?ê¿F, ÂŽ³9nŠf>CÑ€‚–À.Áç9×õÈ£ $AåÚiÐÃý(VÒÙéK®«–öï?xñù¿éIV à›Þ©7|;Iµ°ðúÒÐÙ†átɹôŽ>¼l=>|(âëøÑ3à²qõ)þtn½™6ïn#Ü:\@à ±‰3K`6oÚp»š¶¶H”A 9ì?µU"ŽŽVI˜9'1¦ >æ•]!ëôõɸÉâÃU+Ÿ`UOÓ Žb)sþõ5Hº2 ½*Ù·Ð.PÃ×VNcHÆ.H÷c«Âuͺû:-AK†äðä8°ý ×l’O'øðS¬ù|1æ[HCƒG áÇÜóÎ'<‚#Eô'æ4万lEÎÒøɰ“.ÎOÒÓ/>ãZ+鸀"n€¨ç6=V à6ý¿Ç±éÇg’ÊÒGê,–k4²–ëa%ê.;—í/Î/ðÝG@|ÃvøîC|~ºFº+B^©×°dåÔØnT¯aÉËLè2©"ÈAƉ)0€|_Mw÷ï¡$j“>WLÕR“÷bŽ×ì]–À+7™&”Ÿðž×ét AE1à}ZÂ9”ÜRE×€¤ݬ[Õ.‘‘§•Ÿ¢MJºÏɦòüó ïšk‡›âªà+¤"L~NîTZHBô)Ð=9 ÌzaŸçºä ò  vä â\QÇÏaõI tba§aDS‡ ’óóSB‰(—,|ˆzä8Ü×[òX)€[òCü¾†!¤×ÒÃ’ÃÀÄ_\žK¯µð™æ áª7׀ŸÆ&S3—¶€á8ÃiÄw3^gUÈ+}qþæ%•Þy… ú,Øí³ûû eoŽÀ<2û€îÀê±,?´”œÃ²«hÆùa•{i>ÍñA;yˆEyŒ)n‡‚žçz‹(Õ"ccà\÷ƒ-T8¢ú1Û›|¤["°A·€Féòü(]]ÜÅ\ãþÔg-C>¿¯ü_xœ•øÞÀÛ²»V^«o×WIªk2éøñgg'‘|s~vŒÔ¯5SŽÉŠpj+PÔ’–.ôy|÷êz+å°êE‰7Âúkºñ¨³l:œÞ%t>#$|-éç“J>Ñ× |8å³)ßAÍ…N°çòøàæ Œ©Â›AÞMHR̰Ð9É=Ž‹Ã€áS/qW<Y€‹Î{„õ´ÀõFˆ© ¬¾žjµ´s÷.Ù…¹Ô¹º&ß`üGqpÎ9¾ÿ%T@©>9”qWJ°£6²1á\Ë®ß;v^Ø—Ãkéy“çÞ|Ïyµö>Ë¾×§Äæª¶°ï" ‹ú½ãн2~ÝšìûÛ2oV à¶üÿÌqhôïÀMcò_½|’:ÝNº¼º€ —¡ÂR"H9ˆ¸ÆÖVºÿà~s-Mð¹ÇLÈs\€.!¬óÁ5Ô¸:e±#˜÷¡0&ëÈÀ:YF€ŠùYª¤+0U Ù‘XàRàƒÏø9ÂXY㜠|ÿFšß×’.à)~õõìAâÏɈ2ÌI²Yô‰Ç#PÍD!–¹Ñ PÇøû(²!ð¿×~’æÝã”ïQ´ÓÃJ·A9ýy:>Å—oÔÒýKi÷!Õzw(Îñ²/|PK²€`—– ,»¡F-9!W‰ ¸\÷ˆ1ŒøÃ` `_h¼³êŒíóXþxÂú«–¸ y¹]ÀñÔ‹‚+µ€äd—0i—{<$o`¼¾‘+ ƒç¸•¸?Â?gYØÒ !Ö§ïagLþÕñ³t svqÉç òÝ[ÀvÊZ›­TÀªWêÛ$× $$ÅÌ!{UmÂ{WB`&y¸mfÜË(_.D×÷­'(€yjäÇ((¢ÂlÇ÷ž-× ó© á6Ÿø:ÊÒ çXS2éô¡*€>¤HF½grц%$]nŽùõëÀoˆCØù™ŠâúÅv™¼Îz—)ÏXD*Æçs”Ã<N59içÙ‡XdÈASv—5ÐÃ0ÙÀPLF%ŠXfãñÈg˜ì™>;29æ^M<'×VáÖí_@ò©Ár .ÊVøÏ‰"ô§òÀ£p3x‡}AS¸8ò*Zÿ O:õV=V àVýß`0L¸ðñ wY)wzüÁ¿L/^~™ú1Á©4Ärva·$Åà`‘ Ǧ§ø¥ÕôÙgXí2>>ð˜pًï˜ô°ë÷°Ú$ÕŒy/ÎWà­dXÁÐsåV8:3ˆ3\ðÿv_Á;9ås¬lmçB0I/;’ƒ€(‰<æ¶R†]G œÎðlj6û#e2®€©×m¸o]†}‡U› PLnŸ…b;>¹J3N¹‹’À=L!ðÞ3¸ZmTj þh"‰|±ŽâÑo‡“°¨'?q9(7YØÿñ7y…Ü3Ø|®ÙŽý%÷|–x´ø|á}ŸÝps>7:ü§+r èŸLÆáäƸ5 þPr•ßBÅ}›+p›~ÿÎXœhZŸ¨mÇê[-g¥ÜÑÑótEaÍË£'X±q*ãÃkÍÀö™l˜¤%{4£âßöGXJüzG0î¦ÓÓg)G(íÁÚ{“eÜ—˜>"x¸Ö@ßÁW ,M§­’"ój rŽ˜:DY÷ßž¢šâFxŒP /P 5"QÈËKÀ„/)vÔ7f [nfþ™u˜PC‰Ë<Çq¼°ý#ÈË־ߦë6 c4K5BnEŽ_Gù(Ò 2÷*Öäãjä|¢äÂZ“@¤BËÃÆ¡0ŒL\e0ãz—(Ÿe„)™ê„#'ã}ÖÞËâiKÙ} G³ûf †ÉÐk‡ç@+(BoðªrÕ²OøN…Áæñ*Ý2CêÈIr|”€C$¥÷8·í±R·íy=­ ÓrÍ<“M6%×̲˫³ôüù—}„º›å°œ[åm,OKÙãIé-Å7xÄÀã Í/ZiwoK^Nå˜\€1ñîéµ#@¹ÌDEЪËÍ-€ôˆd—d˜13vŒP®[(¬ª–7A€Í H¾³c.)6ëÁä'šj¶s\œ(„p‘ï‚€È9BaF™Ú\Ä¡Á*Šl€ÉcµCÕ>âܸ$n¦¯nhÒœzÎϱshÖö&‰IåÔÅÂ/ŽmT%Ž_à~(ð6q,Z}Óˆý­ø÷† ÕjsY²ûy,}žd†%ç5×_BO}¤l+Á³à&2²/zð¥ÛÈ újAR¦.8 çµ!ªÕœó¶=V à–ý"õ“!#}Ç‹³£Ôë^¥—øø×Xü3À€|ó6 2Ì‘1I'ýizv@Øëðù®”¾÷ÑÒæÖ^ÚÚ¾KŒuB4½ 1g}{þ }ðÉ îòçéÓ_ü$õ.p>}¼NéÏüïRs³@]§á¶ÃËWœ(Á¸„É_" æå/ #¶*äλ‰56ƒî_½{ ±ÑMÕz9mïÕ³Ä2ùXî1–z75ßží»0hS2‡D.¦Ô!\ÁðÏF4 ò#¹Œ¹®TÁ!¨X@¢ ­7éùêFjnßÁ]1}wLÎRƒ– 7ÉB —2Šs*§ûbœN:EˆµÐöó3|Ä%Ò;Å]2Ÿ?)—7ÐuÊÁO˜Ðct$”„ÑËŸ¢æ»€áq_xåEµ‚ÓË7˜Ý ·¢N€koª|nÓc¥nÓ¯ÁX†bqm5„!¿8{I2>þóσ ;Ç÷7SmÎäe.c¡Ézcvž§ÎåuzuxœÖHîÙúñN:8¸Ï„Ì2ä:]&6þz™¢›ð}gÿ1°z’ž|öS&q/uŽ/R¤@ ^Ú˜jÛ7Aâ”ÝbužS ô”û¸œõÍw%é L#mè>@t]œPîk'òág¸%- ½.AÆ … Æè$Iã•(!pK@Þ"À%6Ãv¨ºã¿Òš„SÉZÈï£!ç£+ÃmÉÒ!8 ñµlóª"7 ÌØ|3&K7= nÓ”[)€[òkÄÜd&ö:„½°î‡/¿Hm þ‹g™à_v/`ªaÏ‘x-`m}›)W 8g”Ú €Ã#mï^ƒMß¿»›~ðÃ?N;;wÓ/ñ4žœ¦ÏŸÀ¢CßߨÁw®§ÝýûTÞUP2‡(™éùWϨe¿L;këéÑ÷Ó'ÿñÝ´Ñ"¼¶nÞMò=al‰cl¦=ð67¤F¥•6TÑ¡$J¹]PÀiúåßü-Ûž§Oÿò B¿Lu‰8ôÀœ÷¢d"†Xf¬,nD™ÔÞu4E“æw·öÓ2ÿ*Y«`•Ÿ™3 –µQN³Ú>–­¥&|©A•a¹˜¶É°«4( ²jeP$JR‚¿°ß¿ÏÊi ·QàX!øº<'üí¸Õ¤²þܤ,z ”‡¾ÐÒ ñõãUI’©\ 3×-(ìF0¢s±×ÇŽº5Õ› ”µíÔâ÷²“p.\[2éÆJüÿ¯ÃBBMcÅ6–Á?|ùUº„¤{AbOTá1‰§LØ! x¾¤$ß^¨¿ F¿¶? = º¶»žÖÖ×ÒÆÖfj`ím¤Ñî^Cø]‚ˆ¯×è\Ãdnn­“t³ž6wvA×é+8Y÷/~ó7J÷>j¦:ÖvA軋Ä?ÆrO/#¬e`mÉf°ðÅ PÆMPD¿}ͱHú!oF7]Dˆü÷C8ø9×1ÆBçÿµµ‚ðÖöé•ÒÁú&"Æg ”pW×D,¹S°ÈLãjPm€UyäinË-Szº8Xü :z)iZÐlGÕn‹ÈÄ!€Ä2"ŽÇ8<´ÊMŽ#÷&¸„;üùPòl'yÉÝ`0ü›)#÷ƒDP7¨(Dr¢…Í@Z¤37yå^Qx¤ ¹M•ø7ý5€–LTE.Ï^…ðõùÏ!ùNÓ¾ŸØõ!2EN|Î|¼ßOÏ_ ;pj(Øx—=~Ÿ® ¿áí’ÿÈ~®?ì¿Øˆðõ-'n ì³Ø} G^ý¯Hã½À ™ŸŽ•RPÂGüÉ™YmL¬ÆÆ¥ññ2$“Í3Lsmå')vtt̶ËtF5š–4YsåµL*œ3 ©µ×7Q9ÿÖ´Ÿã¤Ë%‚ÕNk{­ô¸ò0µöhƒ L/1ŽJŒáü2¶¤›“^¸>£)G§{„õÒÚþˆˆÂ"=¼‹Ä:æÚ ÐaívÙk_$´µ]Ea5ÒÁƒ •$ô%È·Rµ°ƒBAÙUÌñ‡$$8Òï&­VB¯Lè¯LÞÁÅÃN¸œÚ°îdÁ낾sx!þ®!‡‹• (£sB˜*sBè‰f÷Ïò&ø…¸w\ÊE‰EÈá\#>—ôU!Çã€xCØÌðš½å÷ ÑI?R‚0}½ª[ßšÇ ü I>ÛY õe÷_<û  äËßNg¼·_ÞS±2 ŽªfzôÑǼ¯¤¯0¿#Æ=ÁR]]^¦ö«Ú`ÝàÔ!\8áý—Ÿ?‰ÐÔtQß¾zÖóäÕ1Cxþ£H£NÚZ/4{æ™éV¡üw‰?k;í\y™L$,Á|˜Œ ¤½y-ás»|V‘Tß)¬ýÙ ¢öˆá5›¥ôî‡@úµ9q†*p4á§YØ$‰ —¥H¸²OØ_zI‚ÏWŒ»‚«1]ÒXDc¯ý2µ­= –ªicq/ÍÎhv}Œð×Òû>F)2®9×G§žÂâ &ŸÚj†kî‚! ”)Ò:åøczô-xŸG)„ä6A/ ªJÅ"Cp€/‘DEä#ü‚\ËlQ!}yžž_ôSw@2Ç”å_kÐf/¤U§À®´‚¢ä°qŠ‘†ÆÚ&J@¢’Â+¿X¹`‰»E§ÓßvRÀ~ý|ÙýC:í˜s¬EfÒöñ[Ašd±2Ââ—€ûUˆ¹&‚PÄ÷¯vlª‰EÃ2™Ðÿ·Õ¶^­M0 ª`Ž^œD‚ÎÚÖ½TEPûˆ3|rø9ïüÞ)Ðk‰¿¬ž£š%‹†(ýc³ç6·ÖÒöî&þ7‘‡t4‘Ç®?¤b=´1QÓe×6!(›y o1µ6ÈÜkPC€ßŸF»7ÕÈÓ‡3$¹hF2Yâ\ÑK ›N¹Ù{ÒÔTëŒÕAÎo™¼þ2=«4ðX#ã0ê(;^ڥDŽ$³%õ,Ð'—!GÊ¢ŒÚzwúý‚óÙ|¤^A8ƒ(clíeñ›‡ka Üò ä9t¹Î6Âß PzE8 ‰>vã5î¢9Á¨9©Bî!ÊÍÕ…Êð5ò&‘‰x‹æ£CY!€?ТðÛ”ãôè9ÖøœN1¿òCò=„êeå²`Êòæ&!/òç™øy&NÎ:Uàÿ˜¼zæošbÍ8ë/óÚ‚ÈÃrññM(rRc¿R-wø'mN„€hãcP×—Ä—GvÇ-h µtðhAt°^å˜Ïy)óU”)Dš!ÅR—X~è¿¿ôPH?„Tò/ÕG©bJ4í€ÈÆíáplO`NDKL¡( ²JrŽÐâÖó¹×Œ"Ô­Òøs(¢D¡ÜFŸ_{\ (P29È}PœkÔÔ¨¡hv<ÏÔjHB†­ ÷¶hÆ{ +ð¯ø£(XSV1¼wA oÈÿ«_ü „ßqzñÔ*¾ët~Etsywa­$^uØ6ñcÙý!–k|Ee¾}ØðëãcüÓ!rNê,BpøÕÓø{‹ì½<“m 'ƒ]r²£L±µm5¢¤VˆÍüòU':ŸÊt1ù]£:,—š`Ì1N/Óþ_’vîl§÷?¹KØÆp6=}u†É¥;vÓÞN3}÷còðùgùCŽÓEiщ7OšrÉ7 ÷Ép®¼|xŸ¹‹à¯T(´û8çškN E¬À… 1nzô‰P3ú|]™ HLR‡È£;×wX9T©_hŒ(B¢ iNHs‚‚èJòæ‘VÌÃÞCoë{€\V~]Ä7âý äÙœ{Ùǘ‹ä ?ÃnSƒ° ^ߤQh}ŒÂ! ï’[@ì¢|øÂöÊ‹j9¬»¶°ncQ$iJÖß E9é²èF]«ËØdôOXRø}óÜxN¤2šnŒsÜ `5Q9Žr(uSÍÎAôPÉä€ê ãë òÇ·—3ñ²±ô<µÖìæm wÇa8Uî? €ÏFŒ‰ Ht6_¡Qªk\‹¤!¢À .Ãgx»'Fa<¯ìŠý'jÂuD¿Dˆ[úX)€…&ü}¬¾Å;O?ÿe:9>L?ûéMÇ0ø_}%ÛO# +Î-Ü/àóϻԤÃZ_^~F˜ü` $f}{Ixäw÷Óý?ûÖYXûûð—ÿ«Ñœû6£8¦ÌZÛS[l¿~—­öaò“—€ý#‘ÿEo{þ©KÍV±!ÑÄôðJº÷¸šþèG¤õn2ÎÂ6@#½zŠ `Bßy¼GKï2MDOaÉñùç„é`øÉÁ7uÀ¬¹î„ç.ë lÍda !ƒP›bÆÛG¸*œ·€Ÿwáq–l“v;îª :¯úèÒtib:Ḷ-+‚$ŠŠŸpª¸) ;üpQ·ÜUƒç§>Ã}áþXLäqÑ?Œ‹ûÆýC®A/¡Q@.Ùý(ɉHöÅAE¸X*'x ûLú‰s8<Ư«Ï¸J¼©rãs| B\@Ü}ÞÞ’ÇJüža¿ÖÓtÞñü—„÷ŸÓWÿþþyºÄw֪ϩ[ÏCÚÕ7‰}G®8“žiÒúڕ7•û©„•)#ÿÆ“™SXÜjºóè€x9W§†Ñx‹~ú=2P?‡Ó5ë¡^˜™Îr„ÆÇ¯^³¸5ÎÈ«Êg(^Ý…}ÐKis·”vŠiëÎ"­mcõ°€£!…< Œ¾ coÓ¾þËvçì_€à[!p‡¹Èk–z ôÖòšdƒ¤I²ù4ÙF†¾ß!”Gí@cÝ ŸÃÆŽ‚`,85q-ÑœàþÈ'$J s  ™ÿ9«û¼ÈÞ¬ßñj›1¯ÙuçVƒ¨Td* “}"噫ãŒ(‘…WêÆ·ï±R¿§ß$Ö–çÇöê*{ñêYzöâI:†øë“Ó¾¾¿‡àR¥wŸâ™í´sÿQ$‰lð9í¬Í•· fký˜ª¾“™âÇ‚˜~ŸðÓ˜ÐÛ+5ÇÇ]Ä:õv:±NDf©m9MÍ0U)ÖÌç¦z/æŸ9c"Ç5»ŸÏìßð'*—Ù¿JºíúE:[ĺ ôôCÊ0*¸4¦7D×&®G„!)ÉŬ.¸–ØØ·Ù…ÂjYq9ˆ… I_YËÌ@ËT&$ëàRZBih;öEàF} Á{>—PãÜòæäÈPàsqýl?)pN®Û„ ýÿ%÷mŠpU_£!ÀÜ;ÇåSâQòf€p§ãç6„ðóêm «ï ôÁ>|èÖñ¹·Ì¯|å]UµÁ«¸¹ßÝÒÇJü~…ä·÷ûç_ü‚Nµ‡é󗟦KìæwȈcQõƒ;©Ú"-tsâˆÖÛdˆÍ¦KRj¯±R˜ìfd¾!™¶‘ÞÛmAbщ‡HÁÕÅyú/ÿ×ÿŽc¾/ŽÒ5ùñsÈÃ6µ÷|è…]Aa¦Í©x³ùE½™…¼úŒ-ì¾ß3‘µš®€Œ†¢p•-5‘ÆØl‚ ˆbû`#íÝßö“– ˜Bºq&“Õz±Ñ®„3è!È0øyÝl Ès|†©r(ñM9Ó!`ÚCˆÀ"{f•¨/8xHñÏ)µä,! Ö; o:FÿC€t\|l,,cv­}úA¿½Þ¤B…Q¤.!‡åÐ0Ô Å®ÅÞ9‹ŒÓ/q3ªì[áþx?ºæDØâK%¡Àg¹@yË–ýŸ1¨_m¿î÷*Y^"|ߣwT*9"/~îÆÞc9[‘ëÎd{øåíy¬À¿ð·PË›x£ðw:çÿK yé¹G"‚ÑÜ_OUüüÆ>‚OJo‰¸Ùa÷Ì {éNÍYŒ»…01É™ .Ø! ¶¹Cx›ÆÏ”º’G€Ð®ÍÀcÙ«+Ûvaù/cø™ Â[ଓθ‘°çäå:™þLÒÌBéŸêß†Ï ÔÕgn‡8ƒ­:p—W¢€¼Ãj#Æ@n“oX”–]ŒÆ%y,qxŸ'Ág‚€kLÇ@ë%‚Ž÷¬\™¿ô¡…l‹É]Ûn@~¦t| ’ hIk¿B™AjĆãÙ‡0ó\r-Ï&äEXÿ@ù2 ÕCŽ5@9¶Û(Q ¿Ctõß’ˆ† !õþq스bÌÑ@$ÖKd´¢†)ð tÿäìñwÜSÞ)ßn—}Ê/ÂVºÐiDn¾‰nÑ?+ð/ø1ôù£[Ž–ÿ«¿£ðæUzzþUê_¸KÙþ.þq=Í0±®Àãbf©Ø3Îé¢%sõ‰ÃÇ"—]\ômé$BxrØfÅÚƒƒˆ¾Qzòóg„ÀmºíhÑø¬øû4ëT™XA7C øÖ 7§æ‰"D`eD ú© €„•37à9`ÈM`ŽÝ|Ì Ô÷MˆwSÄ?$ ·ß¥hèhžz¤Õ.á&J ²w˜ìº"´éš# c®qŽ·²S(œÖd@Ôa¿~’iî>Üalåô›¿#¿€å»ÆXô’‹vÀ#è‚szüz^9†ìªA.*º½·žº—ýôòŒÚ Æ\F‰ ¸—]ú‹A!g¬ ËŒ¡]Þ«Jsƒ‚_âœÆï´5ÂG/¬b”¼õ÷0R0†ßз{Æ=Š\því†Ãu¹·÷KÌOŠ>Qņ+Æý+ÃŒ–ÉælÂóÔQüÜä–=V àŸùƒøã_w¹ìÅ5'—Çé´}‚¥aš1Gym¾Åª;äñ»ÒÞ3“‹ü~’WLØ14¦«-qR‹F,$aW^ËÍ\‘6ºÛjÍ™´U«ß˜…:äÚœ%4bâ¹´ö¢Æ„¥êÍ × 0TUbÒ`¬*H–Þù)leuíP¿½lÍ+æKß\’PawŠW€ôx›qà¡ l+Axn:$?öÜÃkц¡7…ÇL=Žƒ’“˜‘é§ØÜ]ƒuçàœ‚Ï8gQ›~M¬´é³  »íÍf(3ë$á¸üP’{ŽS¥ëøª´BŽáGdG¤)Û`ÄõýT=ú$LECœÆDœ"mËÌt¹ñ -).ø7†}ü ÔTžSe©BÐè ùvÔi(2…ݧ^Ï;¼Ÿµ®zlI°Ý€‚sp§[öX)€Æâì‚}„ÿ³£ÏÓÉÕqz:8¦² ÁÜÛIM~ø9ýæó(gµ*ëKƒÎŠ«ëR函4þ<&oدC)íá×®h±œ&õèÿÏÀÈ.0a3Ž»î2ái÷þnL¼£'¸d.ŸƒFH£ï]Ú>A@(DÓ›pVij™¡†ìœ÷Èu¼=Àˆ!ØÄ¸}eL Σn·@Ý|ˆËçµÈf ’·àøÑ㢊ÁôÚ…š…k6»àd†bB ,Ø×cTÕpúwÞ7„ ›”oö'ië NÒ4]uXÌc–6“d‚°fGÕƒNQ©*ä\Xûùý£k: s½¸ÝiAq‘ %Ç1«ùÜ&Cv±Üˆra¾·™^HPÌ*4QP¾çÆ‹ŽÌøS,kxõ¼×U04êýó^ùÊÏÿ8'üAÔSÞ'›€4Y®¬ÁZ…¶L+ȲÞÂÇJü­XdøÙ÷‰;¹>ãyž®¡›m}W'•7ºä°ÂM_,µDˆ0,Z ^.1@̵°®¬•心AH¶!¥i])g}ÉL³±E¤¢ „[™0\‰Š¸ šh º¸sbÿµ®¿¡µÏ€YogÂØˆI«XPæ¼k±Â 2i‡ D&Ëè–ØR¬¡–Çôºv_ŸÞ|Ž£BîŒ~i›PÏ?¥†O;©°4í*/å cûEZun0ç°ÊNbo*Êà5kÞ ÒÀU©’2»¾I-›Ž{ÔL€d÷ƒÇ`Ìa6÷‹Š?|û1Ný”åÄÎàL\âÛJAFü‚d¡ Àñ…Rc`þ'jsœ® ÐFW ¶sÁT%ÚïGa—³ 1þVYû¹µŠz|3ngìÇÇ<@{Å: €¯vŠžmp«þ])€ÂÏáîêºC¬õ³£/ÒÂÿœ¦`™¢^¢?ž+ÀK¶«f ëÚF@~›xÆrÔ¬›Ç Ibû#B|.Ï= –n‘ИHÂôª‹u£~à´µE°±‚s¢'/_‚&D\ã&œÓM2™dçÕKuzâm§ê~7$Ö€ÚÞ9–Ž@vªKã ¡lfO™Â¼•0œèë:¹_‹cò?¼“6vkslJÏ—ON±˜ ƒ×¤ò¹&òÒ8£…†6í¾±ö6á,£(X9,Žmç_•Ö53¥"  :Ö½‚·&–ªËô.µ—Gýôô×ôD”Ý?k¦âº× Šbü6Bã\½¢ÀÕÄ*Ë›çéî½-”G=}ð]2'9Ö8*q58W¬H5ßE5l£(8Zº¡¤‚Ê‚ãfƒQk1n• fßßYñ÷v¡GxpÿPÊ^‘šhÆe±!ÛdVßC¾~TÈaض#3ÏMKU+àõÝyc_±X«Ózýv:o‡ŸŸIQv½úH~±(Çô^Ê@Ì"kóY ¦Ïo[l[P¹ºO—¼~kùÏŽYÑJû̆}ýík7:ë ð‡:{Ö©´^,Zi\„3°,ᡎ¿ ¨›|KJló’2b…AœþÙ‡‰mŽ}ø±1ÓÙ˜«¥vU¡m e²¾QK÷mû·œÎVeìÌw¼ö)€4¬ž³•¶xå2ãB É&.„fQòs3å‚Ð'VÛEX%`&^däq,ß Š§(6i?¶ý¼Ò„s¾!U†Fà ÍúD!îÒgðŒÔg€ ¤ÞÎ} ÷hB4Aia!Æ‹s¢«>ì ³¸Hâ”ÏDò2yÞ(^Í¥ð™)¯™oQ¢$cÿ&ñ5Ë®S%¢¢ð‘½Þä7³»QƒF ö0“““ÜÊÇ |ƒŸÅÉ`9ïáñŠu:'Ô‡?!ÔŽŸ—Çâç+Mâà¬ýNï·–Á¿@!,ˆù3S3À‚_=}A-ýyúò›.èswôåø¾×È#e±Uwv·Óz£‘>xÿ1E6ÍtïÁ= d‰:ü«µÓÏ~õKì ÔÁrº<å¨EÒs‹ÀfûÏ?.ÝMKbé3ºHà7?¥Š•‚r–CàðõhBÜP (¥Æz)}ògûôç£5×»L`²í®PN œíõóÙ³Š¶`ç¹Æ*Z`ó“*Õ£ôŸ¯í¼‹B;¼&ü‡‹²DñY CvŸ…2rMÓê…*2ž¸Öè²ôá=ŠŒmct±Ù{w“qS„tȪGgŽ -­g—è@ïjœ^}FÇ#P D3Ñ +Ñ”ôá6.™Ýz¾2 †ʼn¸Ó¥ ®â¡ÿ¿…@&©)Ã=B8KÆùõû8ÊIw‡ð \€(ªËöΕ#Ô’¸™²ýatcÓ–z}+ÜÿÎËP¸|üþÞëÛøX)€oð«ð³ g–ßEç”%µ™¬°#,²">ÞB-ùãb¶òZ¢ù’LŠ˜pTñY¾{þœµüŽ_¥ã_}Ê+._¾@(Æp4± ö¾FÉ6ùýwïî¤-ˆÄGï=Œ@›}OHþâù³4¥ºPKZÀÒ¹®_ó–P"‚2ùùªöòÛàÏ¿üê4¬-S]„ËZŸ™ðÈò£•&;k—Éõ§åa˺$ÛÀî“̓R*ÃÚ2ÐãwZÑ«àv+ÃBWèc'#ÝkS> Üù«_Sñv”žýôoRŸ*¾ å´®G÷ñ.p·7Ò£~6ö·Ò.µ÷ BV5²Ûªskƒð•É$ø’¶ÔÞ¤Ý÷Xˉÿí²Yë÷"”‹*ËO#TÊ„s$Ò¬Ó/¯¢`ßoàGca·à&°ZKÎ9ÝZ‡ˆdF_Ó¶›I'Þ§q~Âä±ò”l,‘¤•”·)h‹ÏZ(—ƒwPT~çû[éè°›¿ ‘éñö›°Þê†z!¸ÅIJ”ÅAZP£7²¯aæøGë=DŽîìÒ…Ñê“ôÔÿõ¯N¹ÿ¢­²® a<Í<C”/X¥ˆ›ka©9àÀÒhÀ%`w_ë+T:.öáRÞe„ÚëQèqëC‘òQ¦eü<_ø§‹r›ÎÅc¬ZzCº*‡äžªkPr(`û/Ö›ÛiïÎC:ÃK`üü¶>Vàÿç—™ã0NI{»êžcùOÉ}g>œÞ~þ Iš0 Àwƒ ç½qx›€äfdtçíž]¤“Ï?ƒÀÂâ?Âç@Î5”Ä£»4Ô¸»GóÍwÒÚÁ&„Q„ß*8'<ÔŠ„ÉH¨­ˆ•¬²¨GmØ øÏüÇïÎænäÃct·K,ž‚lÆ[bó€ÞûXË’ÓS/S–ãvýÁ)ÖÓðÞ\«‡pUA0–ĺਖ¶HQ‰ ,ÙüÒ'MBkÍ\Ú常†/¾€lÃõè]àÓƒ6* øKÆWž6ÇÖTM ò¶ÀkÊVPf5”L…s+ˆ×wöH(ƒŒª¢`IK‹6ì×é + ˆd¥×"ïç–›}Uºχã1ÞoÒ“h@!£(¦ˆ{6:1”ÀÁÏ~÷}ŒH¤â³ß}ØöËu²Å@ …mZÊX_ïó»ÛÞ–÷+ðüa­°–=:à´i¨ùüôK}ˆõãO˜<†· ûͨiÇñÅ !XâB’t&í~:{õYêc]þ)BAí:þ;v:}çúëm~¾óá}VîYKû¦ “Ÿ£™¦+ïÎóté[F›A¥§œèø¸OÄ`DÓÍ­è3çlb5/OA \˜müÙñŒðµÇvŵüÅÆMê ÈØËQ2kßÀ>q¨ma½à ^=§‹þÎûô „´DâÙT[Î#ì©QJ9¬ëîãø+K¾ÿöƒ"}ð@)Ms2¾¤±)-ÀåÊuT¦ ”2+ µùè³4“•¬l’s»!B!Z ñ ÁËø ¢M„hÿ¾u µý @:„Fû(žÓS”üWí˜soJ/Y¡ü°ÒO@¿Ý0Ÿ(]ȯåö§RàuT˜€©øú"Þvdž9 ÐZ*÷ Î ±ši çEø×Ió~çÑÇðÁiÜe¼„jþ³í-}¬À?òÃ,œð8È.DŒ? < û‘µ©®Q ggfΦ"áA!)ý„ñHìy¢žíô^¼HctÒV¸Jk©½tpo'}øƒ÷€ˆM 8>;Öµo± u²£Ùy…ˆ6D,q3ìïuE|`ýÏ:B*…SR‚»Œifö ×™ÇÂÿvÑ1Ýy$°Œéç8‡,yäþ3§…çÌ`P…ä>4>¶‚ }G¤<¿Rjø‹ÙÎÛ¯¶/sUŸîd€Õ­µ îÖíÔKSoüîkò–Ö÷TOÂ9]¥×C(32ï ¢OþgȨ-þ°‹Ñ‚0ݘ{'¢ðoËÀÖ#lQÕhÑ…EJt],42á ’¡öJ4¢!²Á—ѹd.æ» DCâÒ–,.Ÿóó=ó>y¹îþ¿g瘢ƒlà¼:f6ò? ‡T\>¼>¹’klïÞK›,Ån#×Ò-ÎŒóÏJ¼¾7¯òÑǦyfÿý¯ÿúÿÆÏ|ž~íê¼,u]"IÆj´Öi ´Îµ`©!áίñ@ÉÃi‘ ÅJ$ÍTùü‡ß}ŸÎ± Âk4òÞ¯ß!1„J´™k}Ëus4Ò vŸ§Ì7ž/‘ÖËÔ…Ì3•'%¶ö»úÅgX;½ºIŽ­ô|/zøoÁžwh+~øô3”I=: #ø—(Ÿ©ëá‘qWƒ \L %'%ÇÕ¨ÙÿObkÒ'›¯O?­"œL©+`!‘%,=µ=‘N¬Õ+«×ÂÎéº3a¿BjsÌ÷ará~°—N_ÓW¿9O]`;ùNÑAhROK^B™)`ú*0ކJzsDÔ`Jœÿú¨ÍAŽYaXÛjEbc½šö­‘ÆK rÄù Aµ4p ö&5¢(d^Ì1¬õ·²Ï6eÆû‘ç\“’8aXrUœÿ¡)#¹È° ‘-<)P4çM²ÇMMô]Ø¥gî*ÿ*ºllì£ØßM|çDÞ‹Ø^²Åë»Å•ø{?ŽÝh%ýº0í,Þñòå+’N^¦ãT-•aë󸢯ô­T)®™ùBØ“õÓ[@IDAT‹²SÀK*tlPÒÂJ߸G8h h}Á%©eêwò,bIùë„…,Å©ežx±É >‡d²jæÔŒéÉwAÑËÊ¥¹Oc¢þõ&i´ëuúö!Äì;U¬ëbÉ‚XCÊíê»=˜ÆÏWᶉh˜ÃçŸ)-¹g®®Ã‡[@ æ4û)  #:ë0ÑÌf¾Ÿ#7Q6ë:eeV‘l¾}8nÅ—Ÿâ~©×¥¶Ê¦&ôSÐgv{P­¨¾u@qýYyrúäöåüÒ¬¹—¶¯ÃU4É”S×XxA ’% z4GQ™ŒqclÊixOÂpj³@f·Ù„žÓ¸¼2xч„`Xð¸*¾ç†.Kæ²¾ Á–€ü_!"Ñăk‰¸ÿúNXþÝ;,q¶¢hq¢[þX)€›È\?·ƒ¿ß%Ñçó/?K¯ ð¾x†u}ɲÛ/®c­>ýlg€>¥V$‡uËîWñU[,ÊùþLþ~zðîý(§ÝÜ¡/?É:9ºÝŽJÔñÓXcŽàdü韛 ÇÄž 7|X°XšÚ¿ŒA»ML¼ÍòàOÉ¥-Öꫲ æÕðï8ù›tÂ¥ÿ;;¸ [$*U¤E:û’$£Ã‹ô·ÿÇ!Dð’ÎB¸ ä)èÛ÷é±?!?ÇÒŽ!Îvß!š€UvPBM aBÝ…Ñ–!„äBÓ-5'\¸p ƒvd-Îî<©³Rõý‡\c›>äB$úõZ(8# È„–?çrá_ä!ûñ]Ÿ³îñÿç_¹$á;PK¸ß¸Á×¢ò°@sÝ2Y“ˆæ$ IãWê"‘ ‰˜{@Eàú2S%d»ú¤çZ”G€ô¢‚\Bx«üv ¸\~Y³ÕI8tœáG9ÎD J¼º„ÏDEæ‹.“\# ôч?Hßý„îc¢#ð4aýo&×-~Y)€›ÇœðV¸ô¿"·ÿ ëNŠ®\|žÞ[eÂ;s3ݨ¶[2ó0VBè¨Ç7Ô…0°F;ÿ=b÷wµøÄÄK¬Œã¶Ê–›Î{>±j:ØÚ2 ÛvBŸÛš—]brjhæd×Ùè’õúzDFdÃaíKU„kÁ‚,ÇsAá ûëçÓõ°ê5PB…IøwX¢Â2ª:̪KiaŠYÂh Ò!YhAeÜæ ö~½Q‡ ҄С›bÂ+ÑZ )PñÍQ Œ‰>–3 핼\”v_qŸ°ÔCH½"ùÅl@L2FÁ{c]çøýf,öÛd÷¡ÚäH®ç/ „Š,½•ƒhÓixÁ½w©o«UZpS$À æ(WŽmç`Õ´ßÈÞcGšÓåQ„`ül/80¤§nÐ]°\ÙÜÁ€ê@$AnÛòÁ;f-ò6έ2q}Æ!Úm–[ßܹ2#ûï§þ2ô¯=¾õ @ËoϘ†ø¾|õi¬Ïw4_l”Òþ—ÏN² 1i'~¯F¹ÀU¸fq{÷\_´WÓ{?ø(í>Ül¸1鲨YfÂ`ÓËÜø(‹eRÙgßà î4&)“»ÈxæéÕv¿üüˆåÃXÚ¾Dl½éVàš‹Àd7r ÉWà\v£ÍSŸ_Ì‘Òû~LÖ-V¢¿B)É6ìd f<3™ˆ(¤›ˆâ°µ¹ì1Gd£P$6‘–ÐÚ„H‚áJ–(<-¡ŠÁ0ÞŒ†&fÞ¹KÍ‚qq‚‚ã~õ@h%|vú‘eEò¼†=úF×ÃhöŠ®ÀÎŒD+–úï~¬’žìµqƒ?êÒº”Å‚ÐÒgË¥%LC¡p/tWÖ {JÔ®òD_Î,ZËÜ"‡ë#Œy(†ðâ¸f~Kþó!BÑESéÒUkÔ!KUˆD'URjhËÍGéÎ½èŽ ò;xH¸’¼ÿˆûs7àñ­W¡é±èCšxôFX[\—©ÞaÛ7încÝÖ)ÉeF0bù-„·—I8Z³àGû*_0qÀ’ nªëtïA§ø©x¥lÈ3âÒJ Áרø´…7Ĭdn‘;€À1á]t‰w~ÖNç×a¹ìfcÂaá‹TW™kÑyÅš™¾šY5Œ‹Vв<¶X ¬óo˜Ñÿìðcí|ÂÒŽ8æ È”› c}>ÿLg¾cuo,©R¯"@8Byri¼åZôÍi´S?! ÆXǸ9ü”.ð ðö2‰jH"XØ3¥‡ATâ>åÀ]Ö  àa™9^\0/Yõ%£Å-ˆÒ\î—ÝTÞ·À!¼•ˆÔ ÎW"úÀeqN\Ç̶2÷a¾ùÔkü͵(²îîéÝ4^ùÎ{D(¯ÙC“è„Û„u·Y>mkŸÌ?JÀA\{òzÛÛýú­VN® !´!ùãÏ/hÛÝ=M§“ët-V¶™,s›ê·V¶BN‘É;GÒ\V«LçKV ù‚ µU}ø¼æ\ņ0á2*Qð‘ú9j 0‰ÑìlÉC`P ¶¯òý.ÀJ³"V¹€ ï:¾<ùâ  GŒx¸i²2‚3a¿žˆDa ƒå.Ë“ ײú0•…S[‰¶Ù? ?ш 5 v*tH²é¦ÿçÿDsqóÝ þeÆ(P¢”ÆvóªêྙXRb¬œmt‰P?äÜSAøàÑãM¢(V âòÀ5¨¸ªàô ÷Îkî"ø*¸6‘ +íòøüuLl4e€]ú ä*ó´EtÂ3ø`;û HªԠѦ۷7ý ¦šouEI “MT|(CL{Tóù5Êlıqûx;B7ð ÈKæãxÔ c¢™+¸Ij„)ûZíÙ‚ô»ÛÿýþO ­éî|—Äê@T²oÐã[­œÈøýϱü=„‹ê*/Ö—Ûs~̪¸ þ.K%üæ iºèõ¢d“k 6€±ÇB¹Ï Ù|z{ЪP*Zw¬b˜« ›Ù‚‰,Œµ¯½Û¹Ì·e® ˆ¼þy‡>€}„áàÆÎ2œ_á$cÂâ+Äg*Ù{¼j&*КØÞöb Êó°õ Ü™5zø×k &0ã˜%X!Ù^òS¡Q¹ê8¬™tZø ^—¬JŽ7~θ%ó”?ƒ9¿œ„hš¿ëзPè>bõàD­þ“ē闃Y¬ƒÌ4¨/(!¬šÛ(avPÂXȯP*°<£Y(Ê'§ IåÜ +JÁKW™ÒÐü{%ŒÍÛôº¿¿CÖw ¥É.Ây/Çê«o=¬?;¡D <nѪmï5ï¦Ý½ûp”/S"áø&=¾¥ ßa´®ÿ«WŸ§3Š{ž^¼J×  BKs·°¶ø 9(ð%‹]¸ MT¶1;lÇ ½[o|˜Ì@WÄAèÇvM/úz¦È(™Õò$ a>\mÒPSn]  <îb‰ÅcÛ;È*¶.µñçĨ„Ò5„ªÉxtœ6á4Öž±ø'ä˜ËX—X;À>Ñcà´Ãuf$L¸(¶A (F‰L?³+SÈMÒU—Xâ) gZžÀˆÃØ#ˆØô_8›ÐNp\ATB°„¾ª4pÂUàΠxD:,+N‚S .¢Û®À3PujŽ>é!—Àkr°N?ƒ*Û6!«°]„ œ¥ç_PˆwNèhqŠCwÇâšiŒxnÙ|…Ì$ù °Ã¸´þüÍÙ2Í…Çã.ÇB¤@^ZH€ÛsÍ‚c¸§Û¿e•Á„sÚØ¥L‡§íýGéôŸÒ²þôC3‹»˜óÿ†Y.3»|ß|›þÐ6ÖìX€ƒ^~G—G„Õ®áÅaò •婿ËcñóæÎƒ…­%_"ûy:¾:Ke»÷6qøqy”€5í²îÖƒën+ööÂŽ“¥Ç$.\½Ö>üÒ(ö„Ÿ¹Ç">‹vStfž•dË\—ZH`ïrL2ÙÍEïù›Y<%Ùåê¼>Ào…0S‹øÎÖô/`¿*œ˜´œ¥$wY„´³‚oAí@›ø~ò° [Om@¹j?}íþc9ñ’ãíìmÓŸ ›Î_†åmq ¦ +ôHê’cºHš.“¬m( „N¨Ò¶7˜!¶ñRôûÍ3ÈÂl(šˆš¨S[#C’ßþCÒ™xßÜáÞHX¶8#ðÙõ Œ6HHŽPJ¯Xl„¬BíâÞ[AÂïxX¿µt¬à‹ i}òƨ|Eà\¾jÉLËžìw£DQ­ÆÌtIo—Üâÿº³Ô×6ØQNËi‚4âºp…Û.7H'‚ <†­Z‚X85–“ÅIi-‚ɼöeƳýD"AÖ¤í–<ÄÕ%ûA@ÊΗdÍCø94¨àƤÆuÜœ.¬­óYˆWa7W~øß}ˆ"3Ê!q6VPù¯Ìz†u¬þú|ÄÍ3ÉŒ,B£¦‚Sq£Í(Q™ ô÷÷6™ñg¹°kXªË-Ë”R($ÏÍߌÁm}Ø(^ã_„œí]†*ý†,îLp½Çî¾Ù.7;ò¼ÂoaÏÆæ~ºûà1a¿G°ÿ¬èÄÚ †MÿÞ¯w|#^¿U @Ö½Cu_ot•Χ/ÒÕò8-¼%²ÛŠøÄE}lY_&‡PÔIR‚É/"àö5ÀSÆw·¦Üp ‚/Á¦f°÷xHHëâ’c šÌV‰&ËFcÊéCê?#`šsôÃOu2sì©«õê60ƒ%¾z0è Ñé¾:I…/…æaµœéœCEÄþ¶_`íósgI5℺t%&K%’ËU8>vÑäÿ£ T`Ú§§IŒ¤º„I¿xIƒÒ:œù¶Ñ¶°%­÷Cà¹\í}ø8ÅoÌ¦× 7Bè]›à’ž„=:÷^œMX(Õòh­h]€Ynl›Ôa›y,Ýé^‘èÃQº(X²&7XŽ|I¶àù±9þ¤üRYÈ èB±Lqß$ƒ dL*½0ú¼€B¶ÙÆHƘëFÏ…"â§åd%òÍAÙÐàòï¾¾‰â RwpÁÿð»’î¿óAú£?ýDdHøÁïÏZ}y–7÷ñ­RZÿþbmx…vé背çIP‘É÷ ]+Ãïjݸ©¯ž×Ô+àWÛÂK{ðA—TTˆÇTNºÀu”€©´f—e,9³ÊSøþ¼bmÃbªøÜê7_ÝÆTÖXî›[¥Æ~}Z¸¨˜ãfá,§«Ð_H¬õ}ˆÊ„×ðû½.ÉBÔ.àÆ˜—e­¤ì²i(k „úuBms”`AŸã:ô¨84¥VXÌ܇Ãàz¹Gê¹ìbyõá â!RÍóCÐ !ü¬æë’¶<À‚à3&Xicð¢ªÖ&Ù‚4(‘ØÓ=˜r¯$,8×cÊ­‰9u~Àسkæ~ Øžc”ØÞßÁ³³h€7ŒÝB°I¦üÌø[·`‚å×kpءϘùþÖîÆÇÿíáNîÉ—¶ooÖ»¥Ïÿ·,bò>É>÷Iõe93]²7ôûoš½û–(HJ5ßáÅ‹tÞ;NmÖ°`Áçâ{&ް˜)°©ˆîÌBäs–®±––Üj¶"fÂB{ñMõ‹µèÆú™FSªêFW$?`˪Xîfz™á—Y|öa¶»¢Œ+×úyÆïÛN‚Œ¡3}[‹ij N®AŒMÅ„¥ŒE(Ý*%ƒ‚3D¹õ†d(:QPS™Ó,“ê¾YÏ*?[eãpÝ‹<ÕvHψýÇö.–—Kzù¥lý2mQ\cRÏÎ>D1ú{"9aùÕŠ Òf§b•ßÁòkùG •‘ •p¿<:”½ù‹MÆÚÀ\Y‘Lµ©‚nI†“ü—Ôi(• ê¦ðyŽ¡ÒŠ\?¿¬Âàܺ4þJ*4ßðg¼B?û¹×¢P‰[‹Ðä˜Æõ1î±¿î §ç^¸Cö™˜*µ5ʵïàóÿ)qþ÷Ó÷~øÂXß:ÈÂ}þþoÁã[¡ôÅ'˜µ!‹k^ãó_÷(•¥!†ýîÕôfÖ…‰ŠÚ/zâ1=œ8K¾÷uÁ+/L&¯s –[ØVÛ¶ÕT±]t™œX»)aD ®$S „˜eÁÙÆ¿H´‚í¦µ¶ÎJt‘!<9Oªµ²;OÔALf‰F· "Îc…I϶×zJpNqGlâ2è40 Ï1¼þTB–H™ë Ì(GÖo¦p‘l= .ÏØ.«õso‹Oí3JÁ "s;0O͹G´÷ž ´Œë ÿû¸8JEz²‘$þ Õ‘GiÉ£¥¸&ZeÂòïqsX[…B+оëž˧ZeÄ!‚—âoãëïŠcüN|w›ÓùjäAÈ_ÆÅó½ŠÂ}}5¸Q¬ Ä5VXÈc‚okÿÎãÓÝûï¦ýƒw"çßîÏoƒåçŠãñ­Pv²99{Jyï5õÏèãßeõ’7 MüùËHÙÍ˦ç‡À]“Ñ`2b-Éj“î3Vwc² ìtÛY@ÒuhÖÙíÑã蓹÷ô¿>Å.§;¬z»¾Fû6-¼ì­Çþ ;Öjïæ(‰ß2ù|a—YIÿdBøÎdš–¿ f;.=ãq¾Ê Àâ, `áÝÐãÒ,D¾ >a6pF*®ÿE¢ ãÈA¼M¸ÌPv ÿ¼O°³ß$÷€g£W›ã4(=ÞdÍ€ eÐ&eI5öÀâƒz„ü ¿ç«0Þ5röî“-Œ«ÍÓ‹§($\ÑÍWTÑr-‹!­É@A¢Š‹š(ðUL4¥$UpgÈÙX„k@á×ï3”€ú €Í4¯¯ßÆvÜ[£(Z³U€7#²¼ÄNs4€®ŠmÐ6ÖööûéþäÏüÇéãOþUÛdþm£8ÞØ—}óÏ[¯„—V]wÏè¨Ãâ¤ÆZ“Ú€jɥƌ÷Kê‰BЙ.gØ`ɉ`9#•¤BpÑyÇ”ÖhTI\}îª5¯W¥ÑP¼¦àFV!Škf+ìèI 0ÿ™ &éëÉ? {ð†Z©LØà8ï§Öʉ­Bƒ0ÇÀ(‚.…Å+™xhÍ2A˜ãûZç‚¡¥p®q‰%1HFº’M…£ÒiÑr˵:Ô囑( ¯Ÿoã%J£Œ`@(Fܺçê»pü{ÖÉ.lQU¸³Gy1ÜÊ ô0!-W!ŽG;l<è¢à½¡ç˜eÏQáÇ}sI3¥Ôv^¶.¯SJmß>–7ˆâ×kÓWÒ}‰ûñZê½7¼?ýÂ÷<íuà~¡DùÜuüÚßÕ,à)aÝ·¶÷QÒÃGYœ{ÿÞM–Ÿ­È<êÛõx«€Â¯À÷(îyuòk’~^RžK«ö”X˹MÃËy÷×iãAÖŸRÙˆ9Å:2£ ¾9OW¨Ašü^w`²ûNNhÚî¤G`õ7ðW…ðä¥ëhËu¨aµXØø2+õºroËf¹k´`?) /V­9=¾ŠO@ö߇˜ã\Ñ—™“7&¡ï‘"®/gê*#¢@˜íæ BqMA²1}ìZêLŽÂаLV é‰ý¹Æ»šX{¢( “wš×\“À'–ÕF¨eÕ{Œ5,:èÊÅBî°8‚÷! ßI@*ÀVz½.Þ©Ûaóßon·¨d¼ŸþÇ?ÿŸéé÷Aúø{ÿ«¿˺ú0qßyyËo·@ÇOIÊù;¶ø"ÐZßÀ25 Á°NQ@RßQœ lPi¯Âi¾šúȹ@¦ö•”_cd·q:Ôé¸U:íÒv e/¾>JaNʯ‘cö¶¨†VÆ™¨pì"®A¤ ãÿç€ÆÐÃWÂTàËj[”#¬ŽºvtÞ‰vë©Ð‡õg"£xÏL=˜?@ÓŒˆ@ôɇ@¾27€}‘ªä<Ž'¼Îc"õ»Ù“®6w(ŽIÔfP×_@xFå™(ÏZ`û2ÄÚÆ.á2²ù6è+P'µ·¾>ÁÊNâ¢~7B§àŽ QQ€UÎïõDõ#·x†  xMÊÁ­è‚UAJS\W9V©¸¸ý™’P–Uþ@WÀ,ÍE¥À½÷Y§EÐáØ#,é5E1³) b‚ì°ô•Ý–Ýüœ¤›«ì˜>«¥Ö¬iÃRKžÅÌv²#B¬Ð#þËWXH,å¨ïú–O€×mBÂí9©Ï ²e¾ …}òŒî‘s#(˜âéL‰zz4²§a¤ÔÇÚŸÃ Øi˜Æ`õ×ÉÌkmÓGàÃ5Âz•hnóŸR|rüG‘„Ê”!ÄòÞÄõ¯_1dZ”½ÇÈ–k ™™Çà AYŠTz–òŠ‚r”wwH)Fy¸>‘X‰ë–“1ˆ¢®Rà 2ëÏÝÒ.\†ÛƒrãØ*‹"Ê$Ô%sÃì¾*~˜ÿ§öãô¶ÿãïý¿#‘iï·¯:G|›o±Ð"’Ô2fÝ=2þ\ÅgÌ„À3ÅW/!P;ß@´YÅ5"ívFAL{£1EY+QÄ’ÍêüMe_Î@¸r7*…°ŽÛS`Ã>-¾Èü3ß¾ ¬UnV«4À 59Ãk¬6c1¡ÅÞùDΰxÂpDKªE³FT^%äØaÆÐò™‚ïÔÖ’ùÊŸ7»ÿùȶP/8È,®_%ÙÅmƒYW‰f„ÂîÏat@ìí>FKŒ"X×oCRïQ‰í…Ófбþ”@™¿K„éêåÖý*±}²ú(ê±»±1<‰HŽŠIrNÁÓ"kÑG„óÄR\!s%æÈ„ä~‡Fä…Ÿ ……Ð2¥èBÕ¹ºW+š@G2.¯•Ï<‡—áC½É_þçÿ–Åo$ʹ¹WÌ×rlÙÌóàazçÑG”÷’ÛOÒ•}Æùç¨ô­|¼¥ À¸¿a¿6ìÿçé¨ý“Cá í›ì9Ä„—K_ôÊÿàG¥éåtôSVü9i§ßüäÓ€ìøóu:äl¼ÇDß.½ÆJ;òþqŸ6ݬ…×£‹b:Ùì®3•’€c§᳦Ôb!ªGÓÁâñ´ó´Ø¶Ÿp„×”²Õ.]y~þ7ç0òøÓä$h%Ø<&.|¹r›Y2ßpl%ùÈK&n* Øu‡VÝðëTÓ16 û=ϸJ´‹ØºÊGa@qù Ë Ê‘0ìÓåx‚À÷!‡¼) Ç #ðùôî“Íw¯–váNJ˜r•˜)Å1HW8Ï´).¡ ì7O¡sÁqA; ƒ3¬±D Vé„0#øñÊñL ‚iàoÞp(Öb¿¸nÞËEtˆ@°Y ó1F•JNžCåÀ—r"ë”CëªÌÑË¡ÜÚ‹rÞO~ðcØþ÷Ò'ÛOC}þ7©£¿Ý¿äñV*t;äJ^÷÷tøåš¸Ç0Ò˜_s.•ÙLÒ•xšÌœñ> tR­vvtA؉:z,Ù€Œ¾9ÄàxPN5&iΜÙ!³+>¢ÕÕ`‚Œ´–Úþô®I§ŸZf;1gÆÄ+g¶ØrÉ/uƒÕr²Ûæ"”)Ã- u9޾Î|%T«ÏD²ZÙàÚ2Ù'w‰UjÜIûˆbð³:~÷&¯Âä—e—`Sy-0lÅžlè½ò?8òt!¸CøóøÉòãÇ#X%®GQƽX߆'Ø!]šŒ=­¬k(p>|•+5½Â²]Ï…Á %2äÞ±9J K}"E!t†zÎÝp›p&^ãâcœ¹J~Fæñ]ûöù(æãÀþqDt7Ry¢d,êâ[¶·`ªÅŠÂ÷ðõEœÿî;Äýï€ÚÐÔ¯„8êÛÿÏ[©$ïÚ½SVÒ9L'W €‹A2ó}ÄŒ# óh6‰Õ@]ÂÛþòüèôüäQZ¿[¥ÿ4½xòŠš|ÚqÑÝÖ ¶«G{(‹VÚ#A$‡Õ¾ú’%¿:=¬;dpvó?AJ‚;‘QN`h<ž;9eΣ5w¾ˆRئ}XÖ}ÿ È¡‚;Áĵà%‹çkyÙ‰ÿõôE¯Ó“£ýs_bQ‹(ªˆÜxØm\ijÀ¸ÖY7OÙ™±VÆÔ>…Kcù(?Qÿ\K:´§>ˆ¤KÕžKqMá+\@ôá#º#/m˜ŠbC€[VôQ+ Ò²·Ú¼r$–›|Dž¦2€„äxp«i„þì{|”ƒŠÀLÁXæ‹qÄ=Aen€öÞ1>”¦aØè ¨Bà˜‚‹!î”ïó„-;Þ!Qàš¦üöF &(/]—:÷ –4ç‹þÖ[YRüaú“ý‡Pï¿ÿHK—ñfpq#ß~¡ÿÝ+| ‚§G}‡tX þ?p¡ej¤))À1‰˜sŠcưæZãÒ+¹ ¶˜ð©O Œ5ÐwDœ{sÝc±Ê¯µ1Ë|}Bª-þKÜÉñü ®Ø[yd6)öüÇ×<‘Ï0ºš;;ÙF˜JÿZ)^§1gmP"©Æ¦f!˜¨ƒâ¼j»â ¾Uxtª‡óêÙb#&ºÛfã²¢‘ÈŒ7=|wä0„1öU„bñ~ÉîÍÙÀšÜôß&cÚæ[5xr‰ï£_`1“"JG¤Àè«›WĨûŠ(L@˜oŽm?höãp^¼”ÇŒä@(q/8–×7ÉkË.8Š_°[\žã“ʈVÝ(È¿0ì‰2òº"š›ÆAb¬EPWÎÎU–í^Û~,¿Íß6Ëï­öñV)Åm ÎíÑèãùù¾ÿiÕ÷!å¶S k=#x19% „P3rIjVz.O]ß¿Šº¾µLþÉV°Jg,;ÖªÎ+Ìý—/žŸ¤çO93ýñúÖ˾t"ÒG@™¹½ÎZf¥p”§ËTÉ-rƒXa§MÉ®>zu ÿ–„™!‚(ôžMQZþ:"j걄aýý›}K(“lÝ¥«!B-(ûê&2#… µðùµÊC2i<ÈIËm…ÿ=Îgop´è&ð´6ʿԣd÷áû[4%¦Ÿþœeȸn’cÖ˜\4Uèâh­m<¤ G¹2¯. ëRàû÷ODR³úå% ×,({Bn×§‹¡K¡CîŠLåjz²zDK9‘Õ˜ºT„u­¸O*¯È|TËácY@)»„Ì+Õ6ÓÞ½ï¥ý;úúÿ‰k¼ÇmïAöÑ-„Ÿ“~Ko—ˆ‰?$­³—.±þBoHVèWaIªMôåIˆ™"8¦Nõ°X® SDbª¥L9,õçU„GòiJßý%kÑc#" ”7ÇÔ¸.½û#ŸßyÇ&¢Hïð´L||+ë²!ÍÌçØ0,ÛÏý­ÆkHÐcçZT ƒ¡¹ÈÖS[h!}Ah´ör¯W³qî ÿ9Æ+O…LÿX!)/3î­€X¨#œvé1•†­®TMÎï&[ûŸÛå´ÿ FArxO$1xKz+YÐ•á ”.DZeBt 4,ñܸºV`Ê ¿ÂGW¡© " @#Þ?g›¸F>ɨMö×Ðâ‹D€‚Çö;tvù¼¥G#Ÿ‹ÿζ8© g*%¸ˆR…î¾r}ÅÞÂ5ò\ rý'¥¼'´Ý™w¨<:ò("hÓå¿Öoéă~Ï8þÊuç xŽIäÑ]Ùa<Ýp§´›á¼œÈ<²fêÍkb„pq¬ À­ sø>þ„8›/.¾H ì†Êá5騉 ÎÒc¼•mãè€M¯äá°$¯GWÇ'F ½Ôö” HŸC@%2djCd•XæXzlemþ7˜Íw¿ºÿð¬üoÄ˯Ï>»º%\¥×[àO„Ðqì9ÁÊw×? ÆŸÖm§êjÔÓŠ¬Û;³™2D8£‹i0Q(úªçN;ÜU!A-ð%Ÿ#&½eCvÃkuè‘ÝÕYbÅ­~{±úâl_~üƒÞ\uëÞ2óè &É::¯è”bÿËœ}:ïNéðY ~ÿ˜ŸÎ/®A7³ÈŠDD&r©ë}Ö$t˜l2v6!`<Üa‰àŸ¢k«OücªHÍÀ~ËöÖká¤{GÏ ,C¢Ù âþû?^g!P\w‰ÆëŠÅ'At¡0'äœ0÷^ `*¦ïÀöÓÖùs¡x*~»Àç)@Ü46Nˆú!æœü´’”™âEÏ[a¡O-¡íÌ­Gò QJìóÜL|â[)8-¡ëK,–Ç—Ð qpr‘¿BH¨’ÑÒ²!ÓV˜Í÷ŽÿFõgèú[,ØñÆ›?Ĉ‹÷¦"¿F“+ð¿ŽûóýKOĬà)`f;Nz y„!Iï·)^CC_Jm&ÿœ!>:ä׿çgHZëí˜ní0€Œ×K"Ðf‚ =™¨è­ebB¾$ ãÕôI†ñtñea]Ãs[>6:ªÀUµyoÑ‘ ‘ãÉ­å¤ÖA§˜èûäÕ9GÂdˆòz„znDe„rl~Ö¬x½kezçà†+±UDïá¹ Œé/±roß<ÑxgÏçQK©‡²àèzó 0ºÉý %>BÄ?f1Q‡=Á3íâ÷àŸt#ØÆP˜z«B‘Ç!A äÀ-ù³ï!íÅOQßó‘ˆÈÂ'Ò<]ßïè¤!CÌãÜ#óËñ¨7ަ8™Ic`·×Åsif}éÇ› ó½ÎK¿qûWÖ®gˆ/6y•þå¸ô@ýw„Lº‡â¸7Þ|ß««Ò™Ñ”)».ûÍ>º;=ÓmgtEÃ#pVeA½uìp.9ÆPWœƆ밴·fó ¨i€è:èã¸ÊÂ¥óQ÷«»LŠYÇBþ”•lÔcŸ~±—çon.f¡ÌŽsÿã €¡ŸŽmç'Ô!:3ïᘶ×0ßF3rÎzŸ±øøã£ÇÏR‡RF ébu…Õx){ž)¹]±¹Ž_“\üíë`fö ˆ¾ð7ÐùùMð‘?ècì³@ä…NEžp^ Iñ[Cä®üŒe¾wðÝCÈèGÖÓ…Dl_õúx B <¯z £”£2]Άc.„{£Žq혒êúÓ5u}F&ýÄI±¿Ã±"~†)%$´W¬ÿWé2Ñje} ÿþëÕ›ÿ Ÿþ»Õýwþ<Ç[7Þ@Õ¡M‚®ÀOÃÿ–té €\ÃXG€æ1ôß1qËRÛ (ˆ—gttÅéSÎ3>†Ï?†<‡‹GŸ}¸ Ü:óéñ_è܈Ü_qW‡›2véà ­p,:öp:6}’Dœ}gó†DˆíшçõFª ñ?[Jg®Œît`Eù8Êð>±¨z£ oIÄ(‰¢£+.`qƒ‰- ç錴Лg8#$s^ n¨/qh…]YX¿}m‰?ƒ*ÙÂcí‡Ö`ä#3÷8´èbý}‚}2X«»ÒG.R¨kZ.ÚP!Ô]n@.ÕiœyøB©(e“¯ø)ðZœrÔNð/à´€8%×oó¾JJ%‘>¸×–y|Š—–W«­­;Œ^Üe\ÿ}Âtß%VÿCâ2æO¸î?¥˜}4Ýwš.5°à@'tà/÷¦Õtâ—¼8¿¸±×fù¯Ç»Ìág–ÓÒFpµ!a€:˜¬×!- n§kèÜܰ÷Èá¼ Ãp+t@Äe:`—Þ9GàÙBtÉ¡!Œ]ÎP·cžVˆÎ¯+žnß /óäˆ]ç¸ù:Ú#–ht9žwt èý9´¦í˜gøŠôœ×È'×]ÛD*¼KLbakÐG!æˆ$4cŒ¾%8垢yV©¹¶µN¥f«_üݳêé£=F0r: ªO<qè\¸ñ¬³âxG—X:!Æ™.©­dÀˆÊ3÷¶Y`5 M;è,EqCƒ¤h6ö@$€À\ÈUDyÉ͘œž÷}U1tãu`C½Î¼‚~‡ñàòÄ/ ±áºê£ :án=Ç·Ù¸ñcù÷ªþøÄ7ãê­·Ìxÿ „ƒU‘˜®ÀO£ƒt‰ pT7Df=&ìÕ.+áîœq_ï³9 f-†²\r3«Í"òN]~›.Œºú¦",Çž Kw(p„ÊÀ€n¸ŒPÎ ú¿N*‰½âõ&œ…p P6Ò…œ[ë´º±¢>XÉx¾CfNùÕ:/¸µV}WU@ƒ—€ˆ€ æ Ì3I·0ÄøÒµyìn{ÌrÚAŠòœY§"­gŠûŠÖ{÷X’¸¼«R‡]DÀs€€-@›Á9 —‰¨JNZ:9@jB’q¢â´êKbJ0¨$5¥Ê@ª°}º’’v7ŸgÓªR˜_A úQ8¾3ôœ Ç?÷Ë‘Šz…XNK{ ÙE9WÖ7«·âÒû&FÖ÷ v·‘n!ò+~ù´«ôM[à’€ƒjÀpޣ翬žìTŸ±_=dzïlß +°3g§áÚ—‰)§ø´`õ+‹¬6+¨1p™\ó¯ —i믊ôðü‹~tÛfèõ˜é·±ÆÜ€î¨êA<Œ½?ƒAŒA&ѵ™£K«Ltê°œêdÂ@‡t ŽzÊPÚsu^?/ˆëˆ*瘭gâ# úÅ öŽÃu+Ø!ÐwW·œo¬(–o ¦LÒVÁSÜvA"o‰hoR}òá3¦6"a`줪Câ qgžƒÈ8º¡Ó”(N<zâì:ÞË€%5×åsæÞ1’•Óƒç v¢ºãõ‰ª‘ÄP|%(“¢$¨g²|ò‚Á9™Ï_~žm\ƒèúk¥ 1~B=öp6rNf é[5Ï9H3£(Ë„'ÛªÞûá_²ŠÑƒê½¿ø·8o¼ÏNt}G<®Ào#ÿ~éRº/ÜÇ xûÄùßÙß®‰þsŠ˜L'×0GZ;ÝÃ~Î8½Kp;\82d•àŒ ÇsÑÉ6ãpC¼h†°ªCŒ}uP´Ø[ˆËOÕ•„+Õ8áfØ3<…1KýW[Ã$Ä€qxˆƒCeŽm3¤V8<ÝZéΧ­kκéýw#˜Óp—˜3ÏŠ@óm1˜ =ã¢"Z)‚ó'Öˆ?ÓÉ3qèÙ&\9“—×ÛÔÇ:;¬g[Li¨;H/ê8Ä@}ûÔzbGÑÐø}¡Ê¹3™‰m!xăs€ÎI“ ç­PÎS|Ú^¢À¾…˜_bäH@æçþS߉gŒü1X¦NQBfðõnáØs‡yûïãËÿϾ· ÝFàŽ…Už©ÈïS®ÒïÛ—’B{ïØ…=wªÇ;.ï½¾ÍP–@uí=Çב\¾Ë¥±¦ªÿk:SmŸì!Ú£Óç[=Ä|{à²kˆÐí6Vx¸æ  ç†È ¿ké&Üg¼ð²¾6àöq¨#8¿C€EÄ…}Á*5Ã¥ä—Ó9|µ¸É0C‡ŒËg‘xznÖ èÄFÒo ~ïÐ!ø…€èŠ A¢,× ÔÞ0¬ºü*¸5¸Ï’^c–BÝŸ|¶Ï=¾?õÁÖ1<ÀB §¤u+‹–ÒT¨&•#îÉ;iŒä½ðÖáàÖ ÖÅB]íH¬K,1Õ*¯g¥¡Ë5š2“:j†FS^5Ò@Muú6–} „#++UûàDÕŒŒêÑö8W9 ™Šo\.»zøÎÿÀì=týwþ’eº>.¾Féõ›]¥?¼.a+ÊÿKñÙ"þªÿ:«+oàˆrz­Y:WVŸ‘½ [Îø°•ÃWTfQˆÎú×ÊÑ艂}ªGN€àä¸äåñU ÐèHQ97ìd P p‘ôpõ} åSê§Îyï3ðÏqWÐAü_Њ¯5ŸómTø`á¥ßzš]ìõ3(–|m:pEöÇpr]vã‘뵺ZއÚC·h®ilŒñÎïBž•yˆ ª(=ˆö ï¨:éx§àòZˆë€šsîûóšÏTÈ0Éüýëfî'ƒ>uR˼¥uéþy†6W‰Ë°Â"7o½Å"%o²÷û±ö¯cøë2´cAʼúóm´À¥#tW:†<8uËúƒ·T­¡ÏýÓÇÕè±ø‘ ¦pÁ× #ßá˸ßQ†;LfŸbe>CŸÑ\ c[›AÔŸžâ „:«( °æâ›âÄCÀXÂ@~§¯Ú™éÈ:ìÌãy¨ˆíäU€6=}Žß<“†¿ûg„#c(}îYd¾ý"â}rÛèøçu‰{ºx vW“ÓÊÛcG¬ÎsDL‚gŸ “3“‘YyJ:É#Æ—z¸|XT®÷À7žw:Áðé<… ŽO/Áõ}8¹¢¶º¶ÀshÏ÷c€ÑêïÚy°ð¶yÕ‰#´‰Cš>S"(ÂåâEÜ¥f ð†°¸oõÊDþ,’‚rÑjªäÒG½pšò&ñ»H>®¸´ºÎêÁŒëßD×ÿÑÿÄ´ä;Õõ[oÓ–¬à”ˆ=<ô*}«-pÉ\ñ½øýÃAè¨óóëDåQt~Wb¦sS ½=8Ãá‡I?}lCbþÏÂqdÉ® ×œ#²)uhƒeB\K¶qìÀz¦©GhÜöø ÷(úzÌCØ9°kc ˆ Щ €Ëb)²»ó’¸ìn©ÁŸÎ<ñ$rf¹9µ v!ÇœÓqŠÏBÇ"È „`€rˆsŽ–üÌ€ µžØÆt6â:Ú­Eeû}udˆ‰"Šc}ëë©É­ ¤!‘uôÆ§ð›ø‹]Äûâ Þba‘2Ó·ÞÛo# \g‡MÔ%ë¦_o„ ||©ZVáß龂ó1¼vä;"¼:Agç—Dwq%ÜãVõüÙ †´öªcVè™À —:Ktj£ìÀÑxkÅ|ìÚ—ö/ÉŠ©³Óè©€˜§Ó ø"OùµàT 5¼+ˆºâ>3ƒb`ó>Áe°‘1–ù1ÄHGE\ÇÑdžÅ} 'áþC3<%& àÐ'@€÷ñ]"òŸÈÁ9¦tÖÊ›©6b´¾…˜¸x§+9ïÀõ1HNæ0ƒÏ¸{/wðu@:qÉñ2W`«®ø:Rbâ¡"…ïÏH›Ðr¬J‘$5 yo†êD1 ¡"÷«*™ ©I~")ƒäÄ; n¬„Þò„ºvõ7«Má¸÷ο çðÁ¿EØÂ¡gÕ KÃ%Wé;kKC¢ùÓyLâ9&ä÷€^ilû¯Q~@!œœB´ ÇXæ0˜+ôLåÐp|Årï1Ü–}Ó%g‹K7eßß”­.ìh4\TË>í¼ˆÒˆ²0Ç í–%*”&´d²uöŠ»,ÔEÑÃÒ6 €.1#‰È±O©§ˆ#N ùyDÓ FÜzŒHH4j/èIàüz"vPoæt¤¡º¬ ¤¡‚uJx>åÑÍŒ;ß+?ªª”*Óž]o>ÛGuFðkǸ¹˜­ûü÷]Ù-öö96…Xx=7•sþµ,oŒñ{|«¥Õ^µ¾u“ oV·ßü'ŸÑû»XøÝ—­ËµŒ«ôí·À%!‚‘xrR=e¿}æò»LvÁoˆ¨ï¢3‹,eÍ2›÷þtŸV_þ33êžZ=u}€}·„3Ók‰—ÓG …@Qô Î>˵6ÈwÒÍ,bðˆ©©Xßîsj±ãüã#>^ssøÌ«ïεß tjû*ØŽŽ«M@cÝ*Ã.¸å*ïAô .¡S“d~:—]-W Ä!ÂxÄA€º€}•Å:³ÐHfÖÏáAÎ"<èه a÷ã¸Ø©B‚XົN=<ÎJ¼ÃŒœ]€B€|UŽåàIl%8þQ¤ç­¿ÂéËKr‹÷Mþœ-;eH®H c,ÅHªÑOuHÿƒùE"ãó»µy KÿÝ꽿ú?ª[èù÷‘—7xçeÚ+¿¿Jßy \ `L°ýjÏ9þ]¢÷ÒT‚>цèûSз°´ g^fñŠMèÁ?`Cua@nÇNì<‘Çp—ú¨ºý˜Ž9–ãó [Ãør#‰ƒ@:èØ }Â8¿ìWúôþ‘’y´„§Ë"!È= ‹å„˜%¸³,Xè0t `ó6zN&Ï(nðŠë°÷[GG#”2ô̼y¾’q$2VN»…ãñÙb╟çeê­¢:×­ƒÀ.ÜžÝæ˜§øúg81yc ÓçùÜž”g{€W2Âaîm’‡r~ë艔_ÞE"¡Zã?W !SçgÓÖÍ[øî£ë¿ ç'ZÏÆM$ô—ÔÂr®Ò÷Ñ—‚ÈMvˆï÷þÑC€ËˆúŽe??">ÿá~õøÅS\VédVôÁjÜE‡\bÉ®Ym}ßcæZ‹ž©gœëðî#Ðq» bEóGLH=·‹Tp†·`\eñ—¹ÿ{֪Ö 2,ÆV1ß*œÔe,ߨuÕtÄÑ™G·`§ñdÃá7ì|!d-F4fáòº0Ë-ŽÜ/@IDATý2a€ åÅO§SˆÐ’.À Ùóì R(YM žó·ÑƒÆqÇ6 w9f’–c½ürSt!.02!ñÊÉzãû†nQÏ [òȨCœ/aδþ{))uUïá µÀÅæækñÝ«þü/áü€ÿáþ÷è $âò§l®Ò÷Ö—ƒÐ# Øy‚)ºõ7«@@ïƒc¼ òq|¸‹˜ ÀæXô±…zÐ^`¡N IÈô²tx:¤C`±+Ñ©µwÍí9¹˜Üœ^`hpNº¢«Ü[Ö‰€ЂÓkùVü”P+Åú§¸˜…ÜÎYm1ÖQð„Ì.ø¡Ì<§”@q#¸ðŒs 8pë@qk>KI"!§¿Þä¾€ŒHï¹×“וL|!ˆAò±+~Å¢÷k¯ðþx=êÓ¢°oF­ŸùÌÑ (÷ä^Ê‘P`ΗgP/þI;SŒ—)_â¸à„¦¥^uíÚÍDê¹u÷]ÁCÂumÆãïJäO3~ï.°ãÁ5O±rŸuðÉ4Ûxž2èéã_~é8E·±~?§Xý_ÎÔ^‚y¶Ú ÙðÀÙ}ÉÀãüÐzä¼~Е©®ôÚ:õ¡À 9½„Ϻ®«óׯrc@êØgùkA\=H#]‰!¾þ,<ªjqÄ0B8&ûêøSýqwd§*‘óêUôuŒ€7N9b1ÃlÝ'E±$ AÑ›ó™\dý)Û¼ª2Ò2þ—TïD%àL§‚Ý€6™Íçùš¥+½„Ý7÷—ìd•ò\m \ó¹ÚS†r|nqU_Õ¢ŽÃ“êܺu%¸ïTüùÿŠÎÿNõλAü äOE(í*}ß-p €]ÍÎg¡ƒiÕ?eÒO¸GÄ[&»œ#^cˆcÀE÷”µOAE/¬ <¾mÆø„3Ôv—Φ—š<.ÓX¥/ Ç¢#;©'Ò}²€ ÈyèOôrâ'Þ/7…óË+3Û­sÄ`$ ®£ù0X¾‹@ÉûpÍ%Àt0ÒBv ×϶k6">•¡Ì$·ü|†[ÁgRÜŽ¨Î ë¢#®êëSA֜紗ò‡ó%‹5ã”’L™¥ Îûަº¸rijòúJ€¬“„@ÂH?§?/áÝ·ÉœýŒïß¾óÀ[pþ-ˆ%‘•ó¬}õçОÀG Ãx åXEgûó/XïoŽ~·U‹«ó,«Õe…ßgŒ{3D8ûÎ@/ðª[ËðÛ2Üg‚où Í„™YdÔ3=÷P  t^AN/†½†nØÑÑ¥ï™X“!BØX-˜ó0ÇœÍýÚTA\ùVÂ1Ç0œÖ| yöq#ñ.A.P:ÉC{@ÍCJÄ Žy–‘p´‚9/zÎÙóDîo&Î8¡)çjhúLŸ'Árë»Y¾*„ÄBnë=zóhÎ'€*e9_Áó¾—Iw]nË‘÷+â{%Ä“‰9¨mÞ{•ÐhNïuÚóÖþDþk[÷ªÿåÿ–•y¾û×Ñù;ºõ–ù˜«ôGj NìZòJœiD«–/äï†ù‡Óà;ÎÂŽ.±×ÞCüd‰¯CôÀ©fyc(ÀD®k.…ÄJžp[(ôZéÕ“íΊýá¨þQ?g£8î=Øì" ÃÔ~­Ú‚8)>óß…€Åñh"D€ÇPÆ£#âŠÂÆò›P•ìpìB8’‡œs9ù¼Íòùg¹hå/Ö»œö-Ê1Ï‘ûŸKÖÅû¸*­ ÊÁd@üñ?¯’mΕzXZhK]o³•Tž#ò³Ç·J9µPä‡ó믰áÝd¨o‹ñý›ü6oÜ'†âuì"€ÿ*]ˆ¸° ty ÏðÞh|L‡f?±ëo_cÑy\Z%âqà{¸Šêo~òŒØ~Lˆyúô—XÍYÞûˆ™c°¢‘óà‘ 4ŽÍ0ÃÍiı¤Óüé´ºåÒûÇHÒ9²iñpœ_ŸxÕá& Eo–*ÐÙ£ßÂéTÖçþ ÖÒ`‹(VÃ…gÔBtÎDˆ’ ·ŸÃ$Àb#fñˆs`bXÁ$G'“Ï Ð½P—[nây¼v̹ˆn©ç-OL¾~/WÏó×xE /§}…l¹àã¼î¹x>z̉: öz2×[ïSªñebo`ë9U$£øjí-2щﲆ_ÿæ–1úFXâ;]q~òb¥ K잘ý˜ÃΪ>gÌqg]¿ñ<ÀcÁÊîï8DÿÎ@ÓYC°><‹?b·'8Ècz¥)¦ÈâKï¢ Îƒ™gHЉ3}:ö{œŽ7\rFšÜP‡›,ÄÁ9l²r%Ürär^ç „`¸e„@ÐÅ¢¨­»­ž‚.š)Ç ( Ô.àq‚[RFf°P~q öù&ŠIЇ¢§¢¼³-—_í(x$ÝzŸ+ ÇáûI¨ ‘ ?×U"Y$³wr‚ÿÖß ªCuQÓ&:ósnV+¦÷+áP'ç,x a*Fø2«o‘hFk›×3‹ïáþ=ÀX=xç¯ððcuæ+Îo_¸t €æ&̰pgöà‰s‚$0„ûŠ]uM¹t†i/.3Ç~ƒ u MÒå© ú1ÃЛ hc30(hôsñIcŒ–kÿMáÌŽh™cš 8¯–úHâÁŸù¸*ÑðgÒ¦Ž»DñI%ïç”×½Q¨ÝGnšá;N¼^6Ïh<øÜ/©ì4‡¤8OP¦„Ê2¬Ÿ‹q¥^ËC}–õªË÷´…ò' —°«1ÏŽfXÿ8Q „+ÿPs|ŽÒŽœ_𻘉Ë/¯ô°ðßÄ¿Ÿyn¿C´ÞûŒ\C2Xäþº|ÞUº0-p! €m,ðù·ÏJ»¬Ë÷åp§Ú0½k»ãï,Õi ›Ìw5œj•H;­je÷íêlï?†gPü—Q®ç@òéËæâº]À¹öÊÜÖ–‹›*¨wáŠbß)îc|@LŠá|N øÓà¡#:v xõ'5¬w3G®8Qæv ù-D jÀ(³ô ƒS³s-×ÎRµÊ›xö#ÇÑ<9ï»ÑN†'Kò)D·g×6Nò¥:9SÚ”*Áè“ pÉ 1õ½äü6Ï„ǾêúòÀoáÔ³Z­ß¸[½õ¯þ—jãú;Õ½ƒç¾ýü®ÆùKS_Ä¿–ÛЩý3%¹³OäßcÀ1F=Em}{G»ÄôkAô€#)Ì1î<Çrà§“²Lµ¬Ù`š-dUÐÐÇ^Pgf?ËeÉnW vÇ~×+ãð”-½‚…In®„\$øïœØÈk1e€m]ž®ÂyØ4ej;¨÷Å™ÙLÖ&˜¥¡*0SžX4ƒ¯¥à˜kE¼ç²7ñǺ–Æ/œg=‚%æî¯lÜEï‹>÷ÐÉÇe¹š7¢˜«táZà€t@:ÜþîB‡Ã8wÅ8 ÂÏ6Î@8þ¬%+‹9þ²Ö!HtLHH°3f î`ptX0âÔEÏïÊwb̬ÎO@l ¬­7Æd?Ei×Ü5ˆ ŽÁl9цp8ÄgD^g¨-W¹5D˜ Òñ%ùà챜KXV{ß!€ä”‹zhC—`ãdJ0åG´]ÄgA•H l¢ûs]×cÏ×ø+„‹ëJ#>·ü`øX%ÞQ“X„ÐpJàJ` -¹|Û¼RŽSm1ꎉ|†*I\œÕiüèoû8Ư‡ä|Ïy´;þl‘±þ{ÿ®ºI¨î›wþ ±Ÿ¡>X¹âü¥I/òß GÒéÆôûŽëÓ™‡®Åç~–«ëtp„ˆÌè€à©‘6] Ÿ²xF{1?Wæu,ÿ˜È¸†z]8=*‘tEŒRA¦âÒá•8îé5ñ¸—,¢; oæÉDþ…º©Ãyn¸7ÀbÓŸ³ ­bìäÉœËT¦ókÜL6ò¥4J8ÒÏó%?•3Ÿ÷¹NŸ >»œË¡€÷º/c^“Çe¯z\×Ï÷ô¹€ŠnM>+R[=üt–Ò1Pçú-—¿EDŸÕÂ"œãìÕ‚œ¥í.úß G4ý \¹ÍŸ—£½êˆá¥Ñd¡Z˜½˜¿X=ßA„߃ªÿb‡‹û/*‚kè­ß¼K¬½MÖ‡¿`ˆ¸Ç<®ž}üs†›&ž?†¿1úÏð˜Ã µ…qpŠZq¥˜FÆÇ`çæ«eNࢠ.æ™Ó¯¸î(ópÆ ÜÆ@’ìx̉ÄÓcg ‡ å˜ÇtÜúŒ6I.çO¶d<Ïëy"ŸX¡dbÃÖ焱c”£bðyÔ¡Î×ìœßZŸJÄÉŸÉ/*Œ£’J}?}Œ%H Öj¬D³º\Ý}ﯪ»oü zøþ¿Kß…¥5$*ხ҅o G_Çpiuþ£ÓAu:ÓƒA¶Ócjm·½Šx~DœýÆôµ±ý Ë…ŒÛE6íá4‹°¼²\gnÛ%gàòôàð WŸ…•É­ Ý%WTÜEgfëIþŸµ§?0%QRsV­ä ‚Ûü ãnùã9Ž}¯<#^Çe‘šqG,ªŸ½šc3‘Î÷ërÜÔE䙹ŸL©§™Ml#Ôû)£¾Vžq« Vœ¤(T鯂%k«î±ü” ‹e‘è½[ðܺ ÷_¿ÁøS÷<ûêÏ…n E„è1ý”Y{{pæ&ýÌ´VàÔ8–l®V«ËđNJßí-WŸ}<`"w¯½ÄÀÍ[7«eæšwõ§³‚M°BîÜF5ÚÛª°ìYÈ¥Â< cãçÍÀ¨:.É•…<œ–‹ϰ\QX½ÕèüóÕ¨£:ã€þ¬O€ÄÐyÇï“Ø‡¸†^TO;„&0¥3Þ©Ã ¤pé:3·&I`ÄlDz¯ÕÅûwsyTY’‘ó‡2•ëT¿yr‘3¥"ž*D®¸lÌ~Áߢ‚æ(¯Ç»¡VÍgìνVwÞ|O¿_]¿~Ÿø Œõ—ñ ü¶òåIŒÈ)û'àÇÑIŸ¹þGpö5"þtV¿Ã pqc•ë ÷± , ô-²H¦&à½sxºF_Ÿí£‹2 ¸ w´ñ' þËté®›PY  ¬ÁRÐ¥=°*‘ÉOG ŽX1°q&AÅ'ý5œ{Ža3´çüŠ$P(û÷n ({ydNÕ§½ô:‘hò½¾µ~&ëh a{®ë7ï“«¯ê[vþxk Ä^^•rµOdÕ!ß›ŸÀ¡QS ‚Þ…'T—€+›Lð¹NÜþÛø÷o2Úå¸-ó*]¦¸X€ÎæbŸ‡ˆ÷_<ù²ú‹5óXÏoöÞ„ùãjén·š¿~½ê]ÿ€Å0vY½gYxýêåÞÓjº÷eÆñEÇ+ÿ”€šËKèÿØ ÈØ§¬?·½Ýg:1£ugŸf¡ †)gï<æ>}_=_Î`ˆ¬!LG‡àb'wÅ2éÀ“$Cw…]6¬™ûÅӂ݆žOâ6±üèR„ÅH;’rO½ïå&ëçYŒ‰Úä_ˆŽå"•¤88¶;Žx‹ü\q?ª[Ÿ#Q1ði£’ýÆX©¤b»¸~‚a×—X–k GŸˆÞ{÷ è\¿6:íS×Éú\¥ËÑŠ\ºÿ0Ö1<çÒÖ üá:x÷áþK|¿–+ùàܳ¸¾Ä0”•ÉBH }ÿû ïLÆ]úº…Ž?‡`!Æço鿇š‘ÎHÏômá¤ô_:|æø7ÌŒÞïU$¹!Y‰!W›"|…¤ÜU_jÎy¡ÁH¶"Ôç¯ñ0ô¼§Ëó΋åLIÍù&_$NJLõ#KõqóüÂÓͧƒ9ÍL²L||ÕŸi&Ÿ¡!ñp(s¾Û©Ö6¶²*ïõÍ{ÕÆúíø÷g(¶~~)ñêïei Eìš³X—[èç.—e<¾Óc"cÀ{¹ A âO[Ç@ܡ˷°öðõ?f±Œí§¬€DpvƬ@†§Û3D÷× ôàUˆÄÝÛ…œÈíõ%½ ;»`H°f'Å-0àˆêócWæX  ˜¿‹6Ÿú[–_ßLÙpÂýrxNdj sƒ£Ò‚pj¶S„Û”jºwžò<ŽJda qŸ[¹¶©6 ZQsOò“ø³O"à»)dÖ!ùõ}°VíØW1À2Ãyþ›kÕþ쯫{,×õæƒW«¬Ò«ÞŸû°«téZàB€´Pñzq¹W-– õÕŽÝ~³,’1fèÎqè6+ÇÎ2#ÇI&mbÈsÄäý!Rƒ?SbzÏÒ³ç0 ž1ÀÙj]ë÷RÀQŽš?™­=cücʾjNƒ<‡Z‚‘€†[H¤¿%ùŒlkƒ×ºEÔdîgæ{6è¹ –Ÿù¼`ÕL©¢Ûú—sõ¯ÕÏuO‡,™Ùò¨omUOŸœõ‡ “êyý.²a´Ý¥­ƨùêÆ;ÿXÄóïyu´ÇìÃcÆÜéá€Uð©*ô|zvŸkgxûµ èÈ~Gö³Ìv"xöÁÉ‹õŸësH$êÝ(",h‰Â¸Ï`ìSˆ·_¹¿®«àÍä$Ä ÷ƒq É}ä>þdKæ±bÙp2÷“ß_‡ÿ–W6°ú3£weÈ›«t©[à€€N¾ßþN½™€øè»$öF=}ЧpãƒmÖ ègÿ+? oa¡C–ü£—‡tNçè¢óÊ%]XÅ|¶7Aﯪu¢Öà\í?Aµ8œTþŒeºD—>Á`‚ïxc¦‡&"®O‰Õç±–tÓ¬s¸išøÜW¨Ñýµ¦›_Ëÿcmí|tøä,Ôb/àÍ,T l9âÜ+i Eå.çî[#m !]>—}Çó%¥ºÐF‡±Œ¬ÒË %¿u6)„Â} ãASÀßZÀñçæ}~o ’ᙉjv5æok]þta€Z·Ü÷ô”Õÿ}ÀB'Hc†ùŒ>³´ZJŽX¸bùïjJœ¢\€ë†Ï ¤‰qk0›µ÷èø¨FžÁÈ—é¬H¶4vÅà…4¨BBDnÊ/hPb`·Á‚j‚˜!á¤y¢f›e£äP ê}rg‰†©€™-åZhslÉ[N—gxƒ)å—ëÉÄ©¦>å~‰CI‰ìS‘²¥‰ØQµJÝÌ–çšóµóuM=sѬ´‘£1­.ó0°·,2ëo‘‰>ÆU¼¿ù§‘. Ðè¦ðC}/·‰ôìÑÕÚú*C‚+ÕÍ÷ÿ @KÕòãϪ£ƒjtü)‘}¶«½'ˆô³_ ÷ú¸ú2J€×ßàŒE<åÎ}fX©giáŒiÂg°ç™d8Æ­j0FçgJ/„AZH p{gRA„ Ô þ¸¹WePM¦G !aÇ9<Ž.ÏNÑéÍÀÄ+èÀ*§Ä£?‰L’Üãšp ÅÔ Ç‡x±ßäÏ-µA¢X®ÕqŸ{YëéB¢n}÷$ëÇÏ¥Íf6#ÐÇòõjõæ †þnÇ (†ÖB}Ê}W/u \ ®SzôOªýCœOÞAì\@Ôgî9“Pæ‰ý7£·çÖð Wƒ½ÝjB” ÁÓz|:¶ R$׉€3:»ÜPaاãóÖ.Ý1^Ù×ÿ‚!ˆÿê÷$™øn3 2/pÎ9ÞÑŸS즬èæxì?ÉÊ6§½½N×Å´'[vÊ~)¼‰’áÿ§& =5*¦zÜUNd›êr[¼ü8ßHÁr޹H’óß¿ÍHKÏ¿mÞc•uÿ9Ô+ã_i§?•¿‚ÈE‘ßýýÃj÷ù^õôóg,úyl—Ä«—ˆ>›ŸU½1 €ž¾ýježÙÁýðZµ@gïWS† GC¶€¿±ìkŽGt1fªˆàt„ *Œ½ˆÊlyZðãÖpâ(º=;Ü«>÷Æ(,9-·DŒ¼*+œÔÚ˹ݒÙ_S¾j‡ÉÐ ϨɻõÑ%G)ß)F!dÎóy^^ë/Ç÷¦ý²-Ô¬,Æu‰¢ùø™$d< uÒ-Àrçñ²rv…Ÿ=–ôÚXGX!3¢‹õ±Í|V_Jºús™[àB€4 ‘c¸øBpÊdž!î¼Y®5èŽüƒ˜u–QÁÓÁº·H<ú3ü<Âe×±ÿ±".ÄñÛÝtp"Å0ƒì.H¯' n*RXitbÁÂóãÍç¾?SÊôEÖ„œQ€˜W@ ¿æØ[ʽ¾$Iä]PÜ\çFá‘ÿ•!8:<áyá@Ë„û>>D"8è3é€^ï 5®q?ÇÄžVþ[o,¡ïÏU5®v )¶3Às.Ò\.Ó-÷c 0Ùëy‡‚Hd¦káK瘹¥×cU'oÖà„ŽƒŽÅÏ!ÈÙ†ÕÚȼd¿ŒÏà‚œ×$!HýÊ!Ï*$l‘º6¨†Çtè2+pÂZtf Î-·nÑ"0^·ŽLˆpôS¹s \ Dp3‹8ž€N ’›7À‘Ózƒ6‰¨õ—•ÚåÏ‚vÆÓ™’ìXÿ犾o~Ô„ÿ:4¸S´’[~± °WN‡ yþ•òƒB¨ØM(tò: `Q¼ÛšdfT¤p~žA=ý¹æ>$R?ÎeÄ~¤~® ¬…¿Õîò[`ž…ÁU—ñ„\EXDíb‘6FY†8j…@@$|“+) |§Ëú÷ÂÐÎԅ㸪l›0` ¬š_ZXô1vv–û`Ñc €Åy,ûŠÃœSĦËtgNÎÛAÉoy›[9]¦½rIDð ‡d[ß•{šC²pIШ8œ‡ QŒx^ “Ħéuy¹Á»_¥º˜œp¿”n¹ÍJ~ÿúüœ›/9¹HŽ×ߥÜRÊ´~Ù#÷yéµË¥t¼|LÒ£n‚0k\~Vö9Å]x aè3$g´Úþ¾³ûZÕáƒ„' ïvil»@Febà„ u³š½9%ço@/&\¥Wpà9Å?tôS<ÇÑÐP‚ê¹ÁUeâ6 Ò°€ð~‰‚O¼"ÏsIÞKª‡é9ß 3’/bg£ Ô OBïµdÁüϤ$* m ù^¦9O°›é¾¶&€:=™/cü,ù©rÍAÉ´ðÏѶÚÛè> Ä\ìñs/À ³4²õÐÐÖ%»K Y ûj 9¾J—¥. “ø›ƒÓÓ1N±Ü6:ç1³„S†í ¦º\w›­ wÕ_ƒw¹oÊÈ€€ìŒñ º&à–ÿGöé¨ÁgØmÁIõnà@ ¦th%X¼—¼Á–÷z¢þÙíóãbÁ¬ËýJ"Mʵ怭 3EdGbTjâÂuEv“e›b«`+7O±rþÐäH¶B8åYÖÙŸd&B•@1 ðhÃxiø3¢Ïb¿úþSsÒû¼HRG÷Þ$–ó<¼³<ÔüVÙTUÜ6D$Gü‘$c¹Ì V¦H MÝ|ܸë>wèö¬˜oô9@?Ïÿ,Dt–ñ~ À¬àÜ=¸}°¯ml0 °Œëõ&î¿xaºåx±·–¡AU1‰é*kŠcÄ%Ò'®Ò¥j Cl5áÐFÅ…[/+aõ?>ØÇ'à±¼O|?ô~àæŒ>;"ü   ð ǧŒ‚c9kÍ™$‚À‚1 絨ÕûLÈŸL8x+§s_Ï€ÙQ=ZDžëŸäÉn4O}ÿ¯mÈ Þz½!9_JÊm·ÕjŽÏ·ÔÕ:çØz×û¨De íš´™gìlÉ`ŽÞj¡ï£ó ú8ÿÂÒJö{lrn)RÒ@)A)@•AÕÔ9½ús)[àÂ9ˆ"j]t‘ßßß}YïnÅgÝó)bû!Ö{<ý@{›‚.c׳g]¸,RCSz© ’}­øPý2ŽÎ±çø#p¿>“˜W`CKbWh:x¸q låŒdU… /®J+í…³›TßþÚVÉC€J¿Lõ&ey,Aª%ˆâTêgÙú#Xg^3ï)³Š…åv ¤žqýâÜ£+/N>óCëòkX¯.†¾•µõ}m}+ße¾% «ë›9¿Ah3Öêj¿! ´Kñ¨4ã1ð£]Âta€m'P5J©ç·DCOééŠøÌ ¨N øiÌ?<Çñà«ï¢Ã¿úW€ *2 ¶Q®kˆéè¿<¢éÀ‚ÊToŠ$ÀqûW×ê œ`Ë•¯eä°)çë—=ŸkM¶e·””Ù„œh¤‘&ë)~›?F© ªJEÔWBÊÏ ¾» çÆ½ýÞã6þýXq_Ñ¡> À’kü¡ÿ¯¬ª,•cæH:- !pÈpSؼ᷿•»z³/éûòŠü$·ê‘Ý«?@ \ÀÇUŸœG$íivžN̵‚[êì¨Íš€#,ýÇHXÿ2\ÝŸqªv˜ûè,êê,²PÊP˜3PŽ&Ÿ:¹(N¨-vÏÌÈq¸Úa08§£Do×øÅq};tÊØA=kyÙœÿ‰½£²Nx@µtnÊSÏ—£[_ @:}]B—‚Ÿ¥ d¢¼DG(¶³lѵãúNäèºö†sÃõuöÑÍ·G_ÂãOÃߺ¾–ÿM¯$kë×! H É2:à~K©‚2Ë;–lÞ7Uù–ÿ8á䩉OB §è܈#EÔý»|ö·ü*¶¸‹Ch"ùi[±”«W_ @èÊq]QÐèw\Áèì2v3pN Šy¹£¾\3';ùÅ0§“Gaº2Ò¡¹¼"ÿ\—ñüpzÌ©pl+ã7^~¹½zýò9ç_X&îÂBo _ 9ÿü«û(#S¾K*öªJßêží8!Ì #?Ãá !ßwr\3‰Ü" H.[Îó^3Uk®Ò7o‹Õj ÃNgçTÇoøÉ î§'§ 2Ù‡x#€1a.?ã€Äþ”ãýß}¾ ¼\ðGP• SÀ€ ³Lv‘LèÈÎÈËžG¬µoŸ‰ð 4(<çØ…óÖ ì%~–+§Nj^ŠO¥ ]lË%N4y,¿¹¯Î¯‡aª‰ ³“¿¹¥ÎGo·pótj£œ\Zß&Rr£ã·äüý!ª‚†>Õ€E{ÚΛ׮gÜå³*ó_ß@çGÏï-®D‚è`4T¥ûþzeÎkõ­íHXíégþG÷¼§êU÷nÜ`?žT3}D\À?äÚï1Î+§€`D$à!³ÒF-DÆ)áÃðÏÔË~A\’[‡";šz{ølñœ«A%°JŒ?oú¹bñÌc ÒíúzÒ‰Y»•Ç,¸Fç|¶³¸z¯£ ¦Ä üJæo¼B8r¡g£ãŸ–gxMžÒ™­¾«Y’äŽhÌÑñõçµæ#Òχ¨ß´C‚@[¹/aó÷˜Õ°å§£ÏÊÚF¤µµkåU@cŸÄ ¶ˆ‡À?W9¬Ôw”ÔïŽöY·ñQõw÷2ì»Í‚£¬¹0_ݺófÞÏ5GxwÝd>‚bž<û¸zòå‡ÕOöx·kÕ[oýeµ¹y›íûÅX“ôû¨ûwÔ$ß[±ŠøÖ~4MËpªSQÖ˜pÚçcBíOYdÇÌHÓqHàÏâ>Üš1zqfé$‚#„bÐ SÀ­%€_ÀF‚¼U@ºç¡ĦÏR é•rNœrì9oÌðœÛ’)õÏu]oÙñ|•‡x\HH†%y¶ÖôH¨&_×|R“_` äæÞ[®5ß•‘ŠU_¿xìA âÏϤ(E~9?Ž>|¹&Ù"a©ëk'(ù”\[cM |Íï* üªÜéà®ÿ¤ÚÛû"àŸŽ!t¼„^"çÈØ¤¾SÞuÊzeK=¶Ø ööûxŒÎTû{ŸÓ:CìNeÞ€`Â@~c¡RÁUúõ¸pˆÄȳ¶²IGoW{·Ÿb®ÚeÞïIŸhÀŒ¸pèqÿG9fñPEÇn·œâ=¨À)†ôµËôÕQfüÁýU`©3±æ±­;­ ,À%[ˆAd}:_ùc·dé0º¦ƒ’}k>S|ï-£îw#€õ©W<Õ@«ºb¶S‘•: h„„H®CÀbìSÄçžÌÜã;¹:‘4ö€“yb,# §j@o™¥¼¸¶¼ˆ!pØ/V~Ç÷©K¬ü”gÙßç4ÆÀ£Gâ§ÕógÿȈÎquóîÇsÌE`øR»ÃáÁ!­A£æû¨ÒM ä·Þ #¸wg¿:dù'Ï~JÞª/ÿ#*Á­êÁƒ¿®ÖÖ®W7oÕ`ò¾¯÷ʼ$. 8² §öÆÕ*ºêˆ˜ÿ£a™,¾Zp~ ÷9,Ìó‚JàãKHqÙo ” ,ÅQȸ*ð(¥cù¡ÀÜ$lÚR œW¸ªsR°£FvÆÛ9j'h(ù nK!œ¯³Qî·‘,2zE´\½ãx<7ÏAäTÎ ìp{y>r| ê£î=€9†¿B8ïýåI$æïõîóØ™|Jóˆô‰^mÕ_¸C+ú¿[¯…ø?ŸÿÝ&gjè;<Ø®ž?ÿ”/0äîñ>S\Ž}¨ë¯ê6& tT8?Ǩ†â¿â{"!Õ¢DD~óò ;º\<àçžøùHÞë±ú¼^ˆ®¯-  ÷ ìŒpÝ}gøe«1PBdàõF¤ ^äõ7ð¾«dd¡Ÿþô?V;/Uÿ$±Þ}xñÝ)ÝÖÚˆxˆ:ut/û9](Á1ž¢iWlx/Þ¾y pR}þå£jµ$?ùä#ÚâEúÆÖ> ô'‰ÁÕpašõüÏ…$Ö®t~YðTsâÉ"«ÑŽ˜ñ'‡lµŒ`d`â¸Ð'b¾ Ò60®E~Á_âØ7á1eh88q`êâ„ w†$O—ã°ØèxzhÎze¶"€Î¸û¿D 5€HP?­õ ˜º 7:¶3ð¶>ú)yÌç{„px,èæ‹î/á@ŸÏ±{3dÎ_$âá‡p.€’@¢)àuæq?â>åçy¾Üwœ¢óÒƒýíj÷å#†ùž ë0übÃÀ¨Ù¦M$ÆI…*+Bå[$¼ƒhÓò$×J}JG¹ƒïO88Éîí±œüË ‚‚ qx˜aÂÆU\iÂ÷½J¥.8ÀÈ’T‚¤ß™N²OH°SbŒñ˜ð;Y"<zÿ +kAœ0‹®o:­CXM˜Z,ø (PkVBP]È‚äƒhÔ£†O«;d“¯99(À…kk¨ÊµºFŸçÁ¹Ÿ6vÒDÀÀšáü‰[@·3O8纄A£àû&‹5¿F½ˆþÊ3P‡¿ÀÖ ‡k†}N€ÈkX¯¨ŸvÔC0åpOS<è{øsŠ+÷§Ÿþ´ÚÙþ¬zöô‘’ÆÕ~øYžÌçà[(­½J€”ÿÆ(Ÿ€¿ž¢m”¾©…ÓÖ å~þåì»Õþ/Ÿ2Jàµ;ÕµksÄ’0ŠÑ0ÄÁo{•¾Ú–XMA¢¨¬õz‘ÐTN2Ú¯zŒóû3,ô ]Z H´{ }¦­QPNÏy¯4‘@Ãâ ÈŠÄ\WU ÈñÝ?¢8eÙñdŠÿªsp­ppˆ@,æ\ó‘»JR AÀ*’ÓiõÖ+×-÷z=¾èùåXbè§ó›O±Ý|ËI¤ExÆíé§MAñVI!@ Sv‡‰U…0ÔÀ÷:eŸà—ëª÷÷1âîì|‡~Œž?EQÂÃÁ»9 Áþ:s®›5¡ÐÜW²2“m(W?fÆèþáQõÅã—ÕÓgûÕÎK"G³<Ü<Kì¯s~n¿J_k MDT:1{mý\'#Ôe 1?p{î$º×c’A5 3üâ[Ïl=8~DÀŸ&gÇb(˜¤c ©Q,SNáÏ'¨$áÅé{ŒÐ³-:<œ9`ðÅ̰§ûR±æ;œ%Á@¤¯%‰ˆeJâ3×¶N‘Øêôd'—ÐÝkBQî7_ £‹N£"´„A7jË<—2@~9¾ÏWä÷¾Ç$øwYÙùù³Ïª_|ô·أ꽷ïAÔ‰äÊ ÕŽ÷ä}Oxžxw›ÉÍ,:€×3 ÉÓÞã£Ãê§~T=±_ýòW'<Ç÷_€ø}1®rsŒˆ]¥_o N¬°Ž(뇠C*ÎΪ ûsMОž¶CÔ3#Æ;Ü—Î¥x WÑÿÒèt 5vå p~ „ÀP‹èpè€T%ضdÅhEǨ-'):Kàj7àô{9½ ¶+1pÜpàpz¯[•cËÁsl>þùPÁm–ï6õÌõ9W†ýÜ*%øCµ ëgYÞc9ß'ø çgœÿåöçŒÕÁ»³|[W/8ÿ<+¾ÚÞ‚Ô?””Q«ê{—óî x“ßÅïÝ?Àí÷ªÇOö«;ÇÕ.¡à ÀÒrtÃ_‘ŠJÛ’B®þœ·À…'ùøèÊÝ.º.ÜLP.àœøÝòln,mñ=ÿ• î!ª³~ãxŸ¶0ç€ÉG YZÏ|ë”úE†JÛ;1J#n±»è…äGˆÆß»/àø{Õ“'‡Õ6‹¿©B`šÃ[Ñêê†ãeœ€ÖÎ_ ÿýËÿRÐeF`;†-ÄG8̨6òà–a¾p}‰„}?žuγ‡ÓÓ‘„B~rG;žÀ÷œ[~.+&G’˜¸uBQ)ÈMM<(¡ˆñžjÎÕ弯q¹ÑÕ­eûOŽ–S/†àåˆ huÛ-àU"hž¸#Q¸-?¯ÂàÝäã¸l=¶,¯{î“lkÕµÇ_~‚cΓêúó °á¬­m!½Ìa™?J,‡Ô“*êªíwÓ§Ãz{^Ÿ ‚HwOž?¯žooW?ùéGÕöËaõüié¯Å¨Fb˜Â³xûöm\WðÙŠðÎ;ï„ d®D¤®?N{\Ô§^`Ú11n®ózak¬ÏC hŘàóŸâã9Ç¡¬F$n@R†ù€©CRrëæ<7XX8jU]rÐ뙚¸Ôù ‡/Ï1góì3Þ!¤¢&,Ž*4ÀäJ2‰w(Ð%‚˜_©'Ûœxó˜ÎßÃü¯çàðÇ÷U’½©ÏêÍâ9JT/±s`ˆÄo߉…*Ûl¶ƒ ÷]ü>r~]¿qúyòt§zöb±Ÿ•£þÌÓ¦:>éà³𯳄œ¢ÿêêjÀNUó½}ÊUzÕ—ŠXí"n{FGšLXý K™ý„`£DPÛ)›èºW+ø*l™ò•—|Î$´œ'Ï›QNåù"®–f,uq¼ÚT ò`oª97¼ß”ìå¹J(,Ø•‹,?ÜŸÔÛS¹Ï{ý5Çæ+ÇÍù\¼ J;Óâ4ÆdÒe˜n¦úðçˆê¸îþ‚ùêîm86àÜX¿†' n½Ì†ôàæìð~!áªÏÂðÞnõ_òCߨÚÙíQ&ÆO¤ š¬0aLëó¯Îÿƒü jž^ü ¼ Mtaªqé@i¹Â!0gÞ?@²ã•Uº HÍÛ|x €IQÓTðø Ž¬WÉ]²Ÿã+ù-¶ Ø‚ÌHª·¯ÎRÃ\õ>žBu¾”\›Ï÷iÞÜ—‹¹åõ?ÍûœWìõ‹rŸ™|“œ|g-œvNð\У³!pÝ–WcvŸ^{Ú5:èò¾£êÀÃ|ßöÿÄ~W‹Ÿ°t ƒ áË4ð]CôWäoŒ~Õûúüc‚ßþèZŠ¥‡4ýåwûHæVúÓÆczõÝsø­ý¹¤À)¢¢Ž@„¥¬4OTÓRáÜ|ŠB4¼¿ù pç@Œ%5×›~Ó¶É×Ü÷›ò}õzóA›íoºërŸ/’Œ¾ÝÎulmF^BN«O?{àüóˆQŠHDûjãmÒǃooPýâ»ú¦õ@䇫/âýxóÖ­ýq#õ>|ί$ Õ_ð›þ˜íëèÔáÐØ•š~b·•{ÕëRY%K„LÆþê|=aùyÕ¯“ó[ûsá@* k£•†‹a/ƹâÊ›ñ~òdio·ùd;ùëööØNqq¼‹O½ÄãuNk{~ ¿~lž?<5ïWl¨%5°äñJŨé¸Íöw}ri'ÛÃÉN®®¤ƒ’ƒpÕ¦¼¦–[$ÛÉáDg):W #£’P·æ¾ß¥æõ§½F1ÜÀ¢ËËØUˆÙÀ ½SfwXÐźiô;>ž²Ô3÷æßg&ŸŸâpx<®öÐ÷OOíÐ¥Y@XÖr@¯¥ÿ„@‘_Îïyõ}-þߤ¾¿Ë;•@/v*UIûg£Rú ™vŽC ëPæ$3«y׎XÍÚÐuçÖ_¿±¶Õ'ç[Ë.û…0ƒpr°O0ú£Ã—ªßÇ}¥ÛøIŽ/>­ðxð½ÖÈ®Jk'>&T”3³T5 nÇqðt(¥uá›±Ž®ËVÀ·‰2¼¸tθNg¹£Q3=´m$žÜõ‡4ão¿W`šân ‡ƒ~:ˈ@'v U bíî*VrêjÍÿÝõWAm;Ù O˜;ÄWboÿ ÂE\ƒlêOÿI¶'ÛWy›¹v¯Zb.ý‚F´;€‰aL¶“}ÓŽ&åÄrdÛú”a¼ý}êXÉ··÷ã >r„¡ðà‰]‘Ê¢+ídÌÆ³3‡ðÚöÖ!$‹Ôk3F¾[·îôï¾ûn€/1°ŽßöpŸmjŸ,~!º;‰L7ãwB.ÂÂ5{{_¦÷^>'Ï>mü”<>!pc–ŒÅï!ÓÈù¦Y™‰ÎªksMVxý;0fã 1!ÂÕÙ™û=p@ð žËË׫{÷>À®±‘XNý¶Mþb÷G&pƒø€7>Ûzâ h@'õNž†˜Ð™̈(±‡/?qâ°"‡ÃMXkód¸G£1K°³x‹85ne™q;ýhHˆéIŸñâ3М a`–¡n³vÒ¯ƒÍò¢œ+Pˆ„Ô[@êWP8r­á”¥£(‰HЍ;÷ZNå~\ÞgÈ'¼§ïi& @ì0LFèk'ù8}W#–ÛŽØpmËèÅ[±ºiôÍÃÃ]Ú焹ûtÀ“ªÏü€ÐÚãáÃnXÞ£2Itæ¿Þ‰åUÃú Þ;Ïëò2ABÓÑ gý&ÜÕzËým+‡ç‹üÑÑQÚ[B Äád „m$a/„ßÅGú‘ä»D:^Zj!ò·ª­ÍÙì/hENð×èû~ß7Ù¾z†oÃp¯?ƒÃÍ =˜~·¡.æ|Gßm8b›ãg‰l4ìѦG4* ¾i–±ÇÞ¡é‰Þ½Þ¾aŒ#{H³ö£KÖÇñKWõÖœi Kéë pK¼A ê‹ØQÆ„¸["˜‹ßÃwÿ¦ºi£?HcÓ!_¾üŽ·C:îÑÁ3ûˆwÜžùþÆÚKpCB12ü1㌅ˆ‰Ë§ÃfS|¿ÏÎʾ=Çòý8cp<á>«öˆx„!jÌÈA¯K,¼ùubÎýˆøx7ªÆÃG}šÚ¿üòg¯ØåúÐË¡{É#—˜$ <¥àÎu·Ã´>LýOO"h$¡£Ã¯CEÄïҦ®˜}¦ÈžÚ½tï@IDATá“» DÛ7V®Uo¿ývÄh‡%Ï;œ|›u§!"§9t ˆGÕçŸˆŽªuÚ'Ò :¥ÏØZ×enbW<'&´Q¾{È}»;ŸÁјVKÿ%úîÖæ»ÕêÚMtì÷`q®ù]:›í(QU4/"ú·$²ƒX|P=}ú4’€û¢;¹u–ç–>¹«ïpÆ”íÙÙSüúgçWëkƒêÁý#Ó†iS"Cä e¯§QT^ð÷Jº–ïá¹èZ{ûÏa:‡´Å6[)îÌ3º5#@‚!i¤ómç…Ö´Àˆ¹~Ãþqï¼Á¢ÂÔg´I@qµ_’k¢›¦Oèb»ÎCÔÚC)S|SËÐ3õ´Ú=TŸ}úŸé‡ë€iè6í3Ã~Q‹^ﻥôßþ÷{&¯DÔÁ`Ÿ†=Â?üà TUÎ?CA§R=;¦ÜñýΦD†@ÒMtäXIéünm9~˜íßœ7¸¿9¢ÆL˜~j`ƳëNˆÓÃBM :Zb8$Rn4B±Óç÷‰O|¼ƒx^€>Æñ„bœ û%£±ž.Ió¨1H&~ð ‹šÊyÏø€v¯±C^˸8\Î2¦ÃŸœLprÁ>1[8£„dmÈHLš1|–íõ†²¾ —Noò9´"ÿî33u¾ „1ŽFt¬¬œÆû[ŠRj`»1Ã.c;Òÿ(")MÏŽÍ¿¤ìaÀ/§–ãØFr¯w8Ë™òl ßYⳗή×îh !QØ^Ìߘ(}í¹{ ¸Jþv[8@Ûça†€¯ÆQpbÏÆÆ"ùqëÚnG‰(4Â÷£·¬Q±Dþùæú¿}@&Á2óÇ{þîÞ“ôËn¤ q– 6g¬JÅwˆ€)×äØœÌpaôôNÚY"CòûÏñÞ5Á%3õ&ÑFÙ”ÆÏýö‰8ºí™ïEûèêmP—œÀlŽ{vU~öl¢F>‚¸"Å:ª¢ª%ÿú÷ȃ~ËŸï•È‘wwÃížUOÿÀzÌKÕg¦ZF?w"̲v‰†e¤"Âã&«ùX'Ljd4Ø<ˆu5áxÑŽÆ#Ò±íÄ‚sæŒNDcv0Éù¶®¹žž³Ó^Ш{ÕÏ?ún¡z¹óï«k›oVwîÜ‹Néø²ZBuÜ7.á" Ò΀Oêóùx<&A½Ÿžã=°zÏN•Ôƒ9¿pÆ;ZW<×êzQ/ßÐ%Ï5†ž.á4ôÖG :zÊ áòKX¿?tCêûõ´êñÑ;pœå%ŒDpŠÖ쥴x>€XÞÛ"~BÛõü BDl÷c§ól"šÐQØÚ6lœ0äV©Ê`"˽õ´›&Õ#Dô_þêˆägè¸ÇÛÕ<Œ×âh#1x=òM?ç;Q×}ʱxãc¸;Ûš`a*ðBñú{ùR;Å.÷ý ÂXÔ1Ãe¶AL™¾Àú…«K›|·ãjçàçÌ8¬>þ¥áŸU/^ö¼¤Pc x½^¿ißvQÝÙy\}ø³¿…¨>¡½?eÄâŒ2W †óÕ*ögpvø®JaGØ-œo2â~N,ˆE¤F—\owhEÞ/FiX·sOlØYç4H‡}¾ïf‹ä"ÇüO’TZ~Ÿ¹-:JMè“Y%Œc$§bÖã“gýê“OÇ´Ý€~ºÆµõ=Lßû÷I_ý‚¿O ¿å¹¢k¿/…EÄÜý¾áωwh¤ãpƒ9,œ3pyZG娂7-ÇÏ>C@²­9£ÑP4-íj ’ÑVlZ²®!÷Ñê”H¹rVö!Ä.8²Èl4;h§}ÈéX; 8Éä ;Š•³H .ãÉê\t»%DMB¤Žr|„³TT?žYu7ßA)ƒzI‘.¬tÂŽí r\û„õ‚ÂC$b]¸œèçÉ s°'‚«Ÿ@A:<ö¢¾3J@’3,êêýÓF3€±óm»yæØ/¯X™áNêi›ÂylSm^SøRþÔõAu1‡dA]wQTIçððqÚåùóëùžŽÁûkl¶·"üÎÎlû'íñz4%ŸWׂçÂ7g‡€lDøï3‚X–%à:-m3Ø ~‹Vo}u ¾¤,#þø={KFüYIÝôoKæQ’RÌ×®tD ™ý½§ø(<áù/ùvH9|× åÍiúß*}så›Á¤æ‹ß‚õŠ`E£ HÉÕ´…Ë·¶‹²›_Óîé›ue_»Ìs¸_ÂÖ`·'¨uÛ¼ìã§{Õ‹í’ýE’†H$GújÃüêâ¾Ñæ;&NÔ(Ë<ýüçÿÎñ "ñSÀpÂZtëÕµõU{F^îÈ‹óOŽ1aßh?lêdCÚ°ä°5ùðcˆ ¤AWN+ ù44²} kƒ§Ä²•2û!Å«ÀÝÚ¸Éó§t°e¸ëQõóO~R}ú¹ú~îöF¨ïÊê ¶è¤[ÕßþòS:Ênõöƒ•j}N GRLs6¢ìÂq¬Hi=íÖG‘ÎúœfÚk!JéÖ‡ “)27u_ÅÈuŠ«ìL…H·[¨$pÅ^uëÚœ“PòÉ,/³iˆ¡tqQC˜:¤º¾×W•Pøñ,'%%…#³Ç±M$qˆ]Âzs\‚£š"ÀwyóÖ8ôQõ“>¡m¾¨~Æý››÷B ×¼W¿Wwñ~ûÌÒûÇŸü¾ñnuÿ®FLÕ›ú¹)'äåS<»:n «Uê¾ùÃÐ Î0#¥Ñ¹e ÐB%û€þˆõöFÕËÝÓêé‹ÓpÞ­e6èïûPY|d»úÕ¯þ¢öBòÏ}P-Íó Ö»pô‡¥©·Òç)#SÄþ1ÜúJÀÛØž– ÇŽ®Þ-.˧ØMÒÖv@Ú.žìM‘¼ì3mâõy7?nÒ¶=Ÿ9åÚ‡K×–)Ðöí3<(÷À~Q}öh¸2P=_W`ŒPÆïòÎTá¿™¾3å`Ô;Är‚•tÄP](,/«n— GäМg#çå2-Õø¾—á+œ#¸(u´‘MBÆüì”Μ³z’\¶þk[_êƒn)Vê =ó) =¡³³ ÛÝÅÀwt­V¿K'lA…Šl]{X¡Kèê’OÕ®ÉÂ$)?OMµòGU!D¨®W©€Ë»@¤qkNèÇßX[¨ÖV˜3¯xI¹ FJÛªÜ"°P-`Øv¶DÉ¥“ù¶¶[ü¼¯=”¦°Ç‘$˜¯5æbÚo` yÕ¶S ×À¶¼ÈwêãÇ÷”âno?O>튩¹óÑá0:ë|ûâ÷k©FͰ@Ë,ß.·òGðFHg]$.¿I‹¶ÏûñnÖzð]d Æs4§ñ4öﳎJXEn¾u ~í£ †#sùˆµŸ#Ñ=FmÚ†)ô©ß4â~Wµ¢^txû¡Ï—©ØžöÚ#ÒàŸåÛ„)Ñp±àç%ëv­7ifö}ϼ:kºDiï:Ÿ”@©¨ƒ(áÙEÍÙ&ÞÁ÷˜Á”çc‚ú¨ÔÑ¥èÍ»¿öºßh÷;#¾¢ãοúä?U/^üÑî´ZYÄb¹@dDT æiÅe^Þrv5âºçý |àŽ žä&hˆÅ\5«p ¾RMAÓª›æ&ÿ×;EYÄé¥ÊS‡#Z.cî¬âg~@œúÿNÆšûļvmƒŽ£˜¾_ýäg?ã¾~õþ»ûXÈW«;·n"EàŸ.·2[„\êOÙÖ!"ëÖMÁÒ×´¼Æ0o²þø„ýèƒp½³êÁÝûUqø±ÃOØ8úGA½v0N‹º´¼fÐÏøÃçiMƒ ÓPIij>«üì´y>ÇV+I”—vòBC™hc¿ÁE–±ËüàáCÚç°ú‡?ÇEw›ŽºZݸ±Äá2cË3€€ª½Jy¶‚g›Z˜á¼¦M ×â|ƒz8‚¡ta½Æèz±ªŸß_J±C P£K-&:¨ð€NñëÝB²Ë}Þü›RSŸúºyåà«+Ë% £¨ûûÌêà éðP‡!9æ *ݵfw_"=©žÃÅÆ4Àê‚åÂè;ø“Û¹µÊÍW*×þ&›ê:32‹4æë§ ¿†˜µIöCí±>þ \ô„ñˆïÄb£ã4¶ÙU=Î"–Ø(‘ùX Že}Ýi¨áËF«—û{ؘéx¢íEFâ´dg'–X‘(Ãk–gËwi*×lyïHAˆr2‹Œ’Æ8|B|ÃgÛ¬˜t qPc £A¬åÈú;u–4Oþ›ß´yÖ¿°ýÖ €.¹.íü³Ÿý?Lâø%ñ£j‘v‰)›®Hã‡×sÏÆ¶Aürâ|_Ø‚ÃSèmÚ?z‚~¿zôÅ6­˜^8Ä \g‘˜÷×ñ [DGž:ïë8,¨óˆ†0†å0’È-h'kfí•aF¸ F¹â­ëo¡ÛŸV;Ï‚èÕ'jíg<«;e/`—Û¸ æÞÞýêhò²úÅÇ_TŸ?ÚÆ^q\ݺ±V=|ãH <Ž]l_%¢¸µ²¤K’+©ùÑá¨k^AæªÍ5ÄÐìTçTáô›Ì– GöáÞŒ«6$<9Û¤- Òã ¡K}m^?„Ó¨È&›ÈórØ&YÔz(Ê[±b3˜+iÌb³Yã™m¶K€{̨É6@œ­®qb•¾Sž —jµ–QûÖûg¿¬n^_­þú/þ¬ê,)©ÁÆ_ˆ•¶ŸQ–z¤^TÍ&±†!¼–vÕ<„yžï ÊäZ‡+„cárÅ×¹¡àüøc¸þ'Õ?üýÿ Ç?«þìýôô±QRa”“;œèw’yhLü1ÖÒ`×*I|þÅg$Ù­~›ÇH$Ú66æ r+Õƒ7îUk¬Â´um“>,ÃëäYÚJýõ ð½ä¶¹ïgäèÿÉOŸ>ù[Ô‹ê£whC$¦=Ëùõ„ø:Té]ùÞ{ï!ÝH»Kü^o‹ÿ]Ó·FòÁ°NRqDÄ“þ‹ƒ:K„®†*&.> ‘˜&H#ÔÛt>{)½³Ìw(ìéöTp¿úâË=¶†x4äòàž.ÀxD-ž°VKˆÓ˸Fc>¶©/²³5©<…¿îð³3jjœ—ûçõ3Ýšô_ó°¦MÎÏÔ;v Ö?†MQšcÚÅ6¯ |7%L-ý;86â>Þųnã™ï ASÜ—ØLɧ¡mS\G¢2ì»A5pˆ>ì°è³çHÛûÄ"ìGm ËèŒf€§^«Ú­VuPr¨sÆs‚ ø­têHÁ?™QâMÐKF¬€tD{>}ºÊ|À³`Nø98Ôgäg ßÙ:Wù“ ¨4ïí¾iú €tþOÿž¸ïŸð¥vªÍU¨âªw 4²\_q¶|òRÑY¸–ú2¢eÝñù–4ú¸zô%”ðÿó'ÏÙ2V¼Û¢á—Œ¯Ë Ú­c>Òú¿YV†A?ÛXª>xï}(½žXRsu1‡KÐ#¹ÇNDkEtf“Ndm /~Bô¥„ë[¬•×™¥ƒ³t#/žß„Ke¾æpÖ{{{‘¿g\ß­>ùÕgp™>ë3¼÷«»7îF|7„U¤{*ÉäžÜ¤¸n›$„Y©CJ¯ <;Žbe~Ϻơinj›¾Ø¥ÃÐ!ÿÓÿ÷ícîRWmWoÝc®=Î3÷ß|3óîW¥³Ê\UI" IŠè(˜!¡ÒO¹R”…’Çzià£E«ë›ª^#:*º)Fº²ðÆJˆ£z¸Ó2õóßÛë±÷Ž9s>pœTÞ¼­ž”´AžO‰!lgìlÁF¶rc Xc3‰7¨¤nG²þZÒèwxx€Øÿ?ÿõ«¾{—~Á*C~kT¸ÁÿßÞ™vÉu$‡õõ¾/èÆB,$!qdY¶åsdÿ(ý:}õÛÇÇ–F g4ÜAì赺ªºªz_|oÄËF±§tà ‡î¼®ª·dFFÆ–‘‘‘yÛ½"m°¿€Â{Í?ê”tw©Ò® -_jñ¬®±,´Å.²Ûø ð‚Æª¾ð¬¨!Ô#l”Ž¥Cñè®_e9´ùÂ"›aBjOÿ¥“Ѩœÿ…ðµÖåÊbª+µ-oh°ƒaâ¡áÆÇs*¥­ØtºÐO]QïZƒ©;ˆõêÜÕpH…˜“ˬË?þ âæÛ‰©×%ú|&Ÿ>Ç?q¢·LBMéÅïÎlB…nzñô…Yr:œ[˜Ü»<ÇFŸ±Æ ·|hx-Bh‡nâdÄdÎresǺ” ñç0ˆ‡üÉsyœÀÌ=UƒàCd"ãaa(qüZ`% ¥Õjóü³*ó´•8 ¬ÃÅܽCŒ4!þsŠ´nwàáeuõ6=î…EäT›!â £|¯<—ŸâZqîœPéfóí`íq­êÐ*f^h‹Ìñbš:p.Ìf´‹6nÒ·У1,.Qve¥BÐU‡¹ãKá.-b½Ù¸¾á>â†tåáÖjeú{Â1ŸH/æ@ØÂ‚[]Mzo·Ò’f[f:Êü†æ;PxŠc™_Þz×ãÝK™§Õ"Öž€ŠsŇûk˜‚äfÃlVÃï`Ê;æ÷Šf}'1ñ? ä‹cï?bs4-¸±žþºt (4¦ŒòŒÂ)á,–Šè´L>”'Ä™«Ô6;mœpŽAÁ„¹ÑO[2oâ)V7Ræ||¼ƒKm%fwß…è\IÅ+ñ³†Ðšý,Æ­ >ø!’¸&öA×gDl¼ÓŸF{&S*œ=Ä“ 1Ë6älûÝé²{/³¾ÏŒ1¶µÍ:ƬÏ6Z[Š#ëË3Ææ@£pøP3åŒÃ]Ÿ67ñÛt\ÀCÌ<ô0ÁòêpĬe=Z Z[Æá¡ÐUam2„x±Ò€Ê´ÓËpjü™ C_zÐ"LAaÎpIË#lV«P<Æ*Öa»¥ã„ú†‡¶QX›ô;V2rn~;¶43Ãñ&4„38W©æ¸¿Œ÷e~qZ4ÿû`~Qø^€¡•ËËßâ9ÿºº±ˆ#ˆÌ¯ÆOëqÌÅðІQóÐ`²Np‹jÇÊO^É:ëô‹ËZ<0V~x[t8»ß¬±”ŸcíöØ~‹#´—Èø 2 ÞoœDÒþcyƒJbXË}e¥ÏïG ~–ø‚YvfùæÑ—Ì7ªßá :5ž‹“ȇN<õk©„•Át]cýeuª¯¾ûžÕdÌv(HC¤DËÎ>ó¡ÔóC¿‰•Ó{XbÎé3cåGX”ã°®„<óJö‰õ«¹Ä—x$Ö£Õ¾ìÞ»ôœ‹nuïÖ'à¦B¨…‚°©Q¿õÁäàHæÜÑO‡Àqˆv> ë€)»ìµºR>|×PóG ¥0 ;¾¥ T=¹Fã4C<ÅŒeXÏŸÖ#mX½²pyø_ýæ·À.sÍêÔY¡Ãk×n„CN†Ô1§in{…l¯Œ¯ÂP´™.Ìá1«]I„òèɳG›Õ7ß4 k9]bÈ{ˆ“{ûðJS«RÆWÉÜ¿?>?—Sßûb~±÷N@¦ömÇ\ÿñ!ã¼!W)1wŽ”Vë¦t¥&¹LÔC ’ŸÒ_çŽÂ#¾˜ë}yBqnÕ!™ç]D_½z-´¿H)ëÊ-à MK%¯Õí15ív œÙÄ“??{­t¡†ê<ê·›éèøËo%p~Éá—éöèÔc:ÎRã®…_Â&?Ôp0<ÎNWîî­ÓwØ®!^ÀQ2X 5LüÙ¡Éì<Îúð ;oÇg¡N!æx•̸Ƅïí¥—X|«Ä‹„#¡ˆ››;¦d“ÌÝu´/‹˜p::]èúƒ€Ôõõ#|jÜÄÉkÔ¸âxrÃŽa„€ñ.ŽÒú/ö¡aß¶Mó^„Çùj¦–af<äíy4ÿMp‰µ•Ïxß?2¤ßùg>“ßcìö·L—t¤ÐÐáË*I¢ü¶wˆ;Á™7Ž3W§†¢ËVžåpÛÔ_¾m_ -EºYǺj¶\÷¯À@ó3í솚_\›‰HkTA Ä·ßZ¦ …²ô©¢r¸SXD®@ÝÃ*Ù?ÄOÀhlÙÔÂÙMf‚¾¬KüYÏûÖüTÇ; Ç·ëh˜6›=®$;²ÀÜ?`@¦÷E½L¦ƒEĆ‹Žã¦‹„ZhÏoýôÓ C®íͲuü™îì¥ñÅÍú:¡Ðh,b°UÚùxÎa\X;4×öܸÁúÔ~”¶œ}RÉYG0‘òwJãü›¤CbQ+0ßÑ$cI>RÌâ!ðõ׸&*í;xÙÓ¶ñ®n¢Õ”‚#'QO©AgijÙJE™¯™ÐS“Ók2¢IDŽŽèS+9Ï+ÑÔ Na|¯9ñÊ@00¿Œ 5„)ö>k§Øi2¨ÂjŒCÝîÄåÔ£§SMVhñ(QÍjZ‡–åºu„Ó:¼.ž4=$ìm„Ú ^âeÖ‚cP^äNšBSäXÛ/nÄ“Ì'NÛ0çK®76fjúÀ;Ì^—õÀƒöXNÚu0»¥Ó„?ˆ~Õ²s¼ªÈn¼õY,q%C¨¡µÔ„&1"´ËÐn_ˆG8†™O™¡‘ÅCàú¤Úè«Àõó‹GâÓÕšÎØH ÎíwY­Ù%nÃU“Ãw…o«ïˆD'±ßŒ.Ì!Lêþ4ü\|›s ®õôÌzSY¥£6Vã{ú]Æì§E„4¨Pÿ ûÂဿâdsÓÔæùŒšSÀáZ ;i©ôg¿æ÷Ýëx'`ƒWW¿&|ö‹êÖuæ=g1ƒñ|G,º„"å@ì2A`šK~§3Lx±Ä¸ÿÙ‹e<·dÓéç<Sij±ZÆwì£$¼Ëç\mv—rDЦ qŸ}6ˆ¶–^ÌTϯwÏ §@ 2qx¼±D’®éò¿cĘ~“@ Œœ&JØd§™¿t†uÉtvÐãFǺÍ&ëÖ!p£øvYfBÚG–-Ì2¿ h¹£˜úOž|…³ ¾±zYHvusâ‡ÎfãB,C¦SÈŽDÐ0“é§‹2ú.âNc…ºåu2EÙÇÒ Bö³Ï^î;P4¡GGß1ü‘™­Ç¶k=j6ýâÅ ¬€F „³àK:²MÖóñÇŸË-uD#Þ㟷J~çÈIãÄxkŸ¹ðáÁ댹Ð~¨‰šV%£IMôF˜½}€§Ö;‚iuf9¾V+ªQ'Iᢷ‘šB³<Á‰<§ÝŽ[×N£$Ó âº»™Aäƒh=¬HØñ¶]4«¡Ý<2%ÇÉ/ªÐç Œ ‡+ÎO«%Ûx£X5í¶³"ÞÓâ!Qf¿„)ÃO±ZJ8Ô2–-£øŒ^x·â>Àgyl[©Ÿþ¢ñekëf{]xµŠœ…FƒX˜\ }\'ÁGÌôDÛâa_89$^5¢Ù|»]ƒ‘\;Ẏ´¬j›#…3œn€ <Èð)‡(÷Ý ìΞ¸ÀéÏ]Lì§ÐÈz5Á ˆÃ7~4L\Ç?ª¥ŒômdaZ«c<+üí.‰=‰òÜdÎ~›€3óD¸£#^4âZ+T&-þ‡“†Ö_úñêwá(‚BZÑ2”^¼.ó+ÊásZ ögéKß±œëx+ TÛ`\Ùl:õµ^Û ’ȤÑùÈ^¢Ùš€KÍŒ+ñ¤ÞP»X¤Õ"Û ;¾ ¢!§XíšS+óŒùµ$p×h3~ô+L(ÂŒ“[>¨*9„Õ(Pº”»] ã„ ï ¢uìÈ}ÓK…ù  \˜èÂciAgÉŠÌ¢?àu‡õÛIv˜sГ“Ä™CPn‰Õe¡öPи³ =Oªã„0Ñl±}7eãQBpàÔzŠud°O«­—yœ +©¤I‚QCI<2}!?=& v~–´bŒÿÍÅ?“åDG§CÏ„-Ú |±úNü„eÂ}ú\Ëa!ÐÛaèFúnó+βÎ#¾M²úË(Â¥u²K޽<ó¬¦ €p¦Tkž©ß âňBÉAO¼\z÷[8òv§¦&Š2kJ@ßQI”ÇÉ3ǘptØtÖLž¦˜"-‘ •T"‘ùÿZíQÛRË+íò ¿)±¿IFÜa#C͵RÌfìðE ªœZoË”ÒHéë‚+©g9Š (>„ò\¹ÿc|^XØi:·ÖVðJ/}C <⤎–D¤Lh'JT*O½ì)…¹®×™{‘„[w?¼#úo¯eŒŽå‡é<Œeq´J–Ú§h J¤[ OÜðóÿŒ©õëÙÁ9FÍŽ¶žðîrãðè*÷‘þŠ à2‡[D=0ÄL6ÛHŒI›¤bEŸ„®U!.rLýÜ¡~\„7œ¨¶Ñm‚š–WˆH[#™éàL˜Ñæ'Ðu6ıb™UÐ>$.óï7X¹·E Ö!è‘‘»„ãRÖȼý÷]aE Ò$<:Ǿ£…wœëäÛdœ¬éêÇl?…X­[øÏ:„MßÎÖÖ|˜ÔZH­(„¨qvDÜèûÓ|È´ZHÜŠ{…Wx5hÅö560?y 0¦x×tê.‚2wŸÌmV£˜‚N£Rûš;úyÄûù2~ò„À*Rn 1=11M^ üêõÇâ¼XXgµñ<×Ä«¸P Š·³ðå3žÒÔãøCªyC­-â·ºp:cŠtÓîí¦)­I£†õH"ª ã’Ú&‰½Ö4v}2ãÄ’Ö` xäø®ž{ ó×ÿâØXæÐãë}Me«ò{üã}÷–·‹õE„CêqŠM>”c:f—}A8âH„;uéé¸P5;íy5ƒùÆ`~Jt²*:3ª´.;˜¨N\$ EÿÙÓNmÇÚ ¼øÄõÇ|=&-Z©ÌˆHHg1¿0ÛO¼ã½-211oY…Äøã~Bã“^‹ÿÁì¡%ó±xHüG/>LËÕ%ÊRfŒD¢rÉZ š¯¶Õ6ôþÆ<µßJþ‚¤ ;Ó7¢yÖçÅ…G`$åo‘•×Å«ëýÍæ{|Ü”Ù+@3?=ûàrbú—gM*â›õëQ—C §k{ ¹Óu m2ž$÷c×âÙOÛv–…@^ðí{_e]°ê?xüÂ@/jÄ:Ãüœ€wn°#ᥚ\»dSÂ#ˆé4T"”éöHåäg’™¦y»ë 'Íç_ŽÆ‹hL8˜ÂÜÿ^Ó:ðºf'7èÐ$ëðPÓûv^ö®·¤ò°óÚ …È1‡PÈ·|ž'ùÒàY~#ÄÜÂå™{i›Ãàõ‡õJ š¸F-îîLÁl&˜4s,DIœø`í@³2ëV8xDF š2m£mÕØ Oáj³³îÞÞ„hÊâÉzp-‰Óz_u˜µfuõ!VÀSfP ìawÊÕA&8^ß>aa¥= XQc—Ù7 6¿K„Çš¬bÏíºˆ°T³ ‡cV?Ï2‘ÅBÞ{f2Ž.¨=ü"ô‘ÓvöQ`Gð¢z-9z Rä ˳.Öj¶¡ý·©Ÿñõ„LšÂCsÓ¤+Û‘ïúáû*’=ðÓ%v£¥Ð…eÄ`EèHux¥Ö7þDpV»Ê?ï¿jÏ;b:C8%·ß!ÌZ[íJ‡Ñmáì©ßSüÊdr¦AGÅáeþâS’Ûé±®?ž¥Ð¸_ëÊâöÉ¡yï}¯ñ–ßê#ë±Ü4g%ŠZÃø¬¯Ù&aä{ O»8(=¡¿f-%žõ™D)a¦ô·ðDµ‚EùQk\HûÁïY†ø@Ó²i³C;­\‰.OuÎÙñ¿éwµ®õ>J¹<»Kæí­F5?¦všÏ÷áÍaZVLÀxUx´ Ú¯Ù¾‹ÇºM‚P³ Ra¶Ìî$s <ÂeGÛ£†Àsé2ûFÆu}/ø§®_iTàÌËW˜í2þ&"Ñä0“€Lùf§rD;â#~F³­¾¾®°…öïm†kÓÔþ%¾@kÝhe½ª]QðŸñŸ Û)qyL±³[5iþ2ãVIÌ‚þrC:6¦í@t7¢~IL‚@“¼¦G˜Î²õ4{ÈÐö•ÕÉ„ƒ8礟`d*ˆ,?2Uý¼jD¶ìb­YPÚÚñž8ãîN”$ÇX4–¿ñå ‹ÓwŽÉ?4£qP‡Œ²ÜsQyý|pÖO4T(Z¸—Í bŒ¯\sbÂ=wñW¬½B’€N©ÉÚ)¥¦Õ-q¾Jû+ ·˜ Ù$­ÙúÚw‘‚ýþÝ_`©Cè¶I±VðU÷§‹cDZ‚¥ FSóÏÐ_;a‹IŒk_Z2Ê’]˜ö5`«0¶÷›ÃÞå&ðŸÔßù)S[ºœ_Þóe oÂwåvŸ«_Ìyw…Œpa² çºñyQ·„}a4 ÂÉ%œ`[w9²F.ŵúxs?ºNÏ%¤+cŠù%B™^óT­ôªq¿e»¾¢±±T57^€wƒœnÓ´×Wct¢=–GÁCÁ£Ÿcž°Ä¿kèÛHÃ&ñÝ+kBëïȈ7‘gôU6¦.ýÕQMvÅd™ µòä_£÷ø ë¬0Š|‰·|^š² }D‘x†7CQD& ¾2ú^^³Èœ½OCLçú~ñ[,¬‹´éÕ­ýéÞ¹0e›Á­§‡Èò;Bh)þjÒWÁ)*´Å¡ÞsV²éy·³¦MMÅø¯Apܰ³tø9W_:Äg"â Æ>Yµ^S5DG›C.´it>D’4uÉb„(»šNÏ2Àð¼SBžšö¼@ýFšY÷ˆãF>÷I¥¥Ð¤]»Lq©ù]WŸÙgÏŸyEÚ4‰³fù€*€-Í\ÛY¯˜–èºxqsÛDn—°IŒÄÈÈ" ÿr:J­ä0 ¼gY§S`õÕ¯ˆ½Êê7<ëc³<˜+'ñW[WÀ£¶ôÑ bŸVhÒ0‰‘”ž?#/#3 MóòM2æf:rÚ@­¹8 ü®¨(J·†š{Ïñ|óša}Ž.ó®«Ñ³ÏÒÀP8(€‘ïZtcääãk¼`ÉúW†ê项ë÷|BšŒ“ïâ¢×u Â脘‡WNûéÏÏ €Ÿóñ’3ÏÑJ‰ÖרSoŒ*3jú‡éÆ÷è_ÊòÙøW&·õ ¸G|8xè`ŸÅ‡ïHeÖ@ C:ÂŽS¸Äóþà°þèt;–oG„›jþ™;Þ°Róå¹ôS¶ïù”âöS曚bkêpé±÷É`N-θ«ûò™T ¬Æ;—F4á©Ï(—KY;_8D•G4£n€àÉl=6ÁØ&ÈfTSã(ëî?…#;‹8ù+3;3ãâŸ^‡ŽvW«yÚçØØ#û(ñ—X㢰–î¼6H?B©¿’¬'@žºAâ×]Æmv#?@–vž¿Yq Qô PÅgM?àCÁ ͈(^Í^Þwfò,í$×í =Ï»¢·”›ϾðNrH¿´°œï—ùmÛÏý¸ `ÌÅ‚†æ»ùn™Å:‹}eûx»34³ê˜tᘩ»`vEøÑà2žÌo"Ë¥µUmMg8±¦®0‰B¤‡€žËi½õÙiežßX§vú÷€­`d2Õ`÷zFΑ³“UýO=yŽŒ0ÄÜñÂãîé|æÙ݃@g”fázƒ¼q$y¼zu&<Âz…Õ 2¢æ÷Ùšøi£g qÐlI™þvL­ P5< #Ú­5¢£­Ùv]r âýßÞ%ŽŸ<‡j% RÂ, w–f2pèÁƒ/Èð°ê¶¾¢®Zú—$L!Î!-¢$ø`‰äåœ}À)³iím²sóÒZƒÕ–+Ì“(ÃjÏQ¤^²*L2BI¼œ%˜ê÷}dù>+cªåOúõIJSP9ÿŸ³H:õ¨Ùk:Fäðˆrà¶Yµd-³,Áø\·|ÛÿxTšô’–¡¯ŽPˆíп¢ŸÅþ¶m?ÀO_ ~._/$D°c,7× Ä‚¸@ºŸ`2Ç^NoAì`¥,ÞÛþ£Óüæ”R§c*/–ïv˜žÑu™È}ž¢cùgÙ¯ÄuȪÅ <*4.ܰU°­¶M~6FqHP¥šüfV8Œ" †ÈÔ2H¾x‰Ê±¿ HÑ/žáïžÛÈêøK…q(| h¿ƇúüÚ á ãp`5nZæ™·Þz5±=…¥ü/ÕuNGÝcÊX‚˜ÍrìF¢ÎÍ36v$­&*ŽêžøV3G8ß§; ­“XÅÔc®±ë>Ö"˜Ž;sÔgœ|a”ó1Ö+žaÁE¿%ÃÇø)î©DòYiJ«2`daÊÞ±>Êž/l`”K;ShQfÛšI‹öCœõ‹Q…ÇTe߬ÆËržß.&ov=£W¢Õaæ9Ìd»+»ô®Êè"ܱ›ÌŒW]Fò9¾`î@¤…þÃê…þ±âWàÄÈPár7Ý8Ôúšüaâ+=ìÄ €àÕÆ!©ÿ ¯ñ5¶RÛC ‹o…¬~›øÎÚètmHœàý„Fûý |wui£á¶ìì°tÔe65u¸/ÅmsqØ»Å(\XœÆ‹hõŸLcL{WLiÕÙ÷RxtyV¦t)æ(ùüÕ¶N'M⬒q‹)ù¶‚@‘ ezËÕ<µ¾R®à”¥˜-¶´ŽÅ- üõo2 G@ÚÀR^bƘê`û¯ÍMöñ–ëÐ@‡Ñ+‰žöél3ü×uŒ z°¤‡èchq‹ª03ýÎ)Üþh1'­õbžC‰×ÔãmÒ7I5½·×«šl¾²µÍþ…;„_³æ±Ó­šÌL®&ƒSðx<üPù%V%ÒQ'&§ØàÌ„»ºÆ¾t+fÞg€µë #Ü­¬“éËt¤8.eD%ü“QšF5á”–\jÁ!†—NÇŽ@ð:j}ÎtSx9+ätoLùÆÐŠ÷h_Ä…ðÜ0Ê)€B ðôª@Œ:Uÿ”sjṓñ\Õñ6V¨³o£Ð¡{?˜qÚ¥ç3ÐL†_Ë7os\ü-û)é)êS¿8zSŠjzÉjÑä‚XžÇíc:‡)첃smíºÛÛ¯¾ÀÊljVä„3èíÛ¬;Çþ!ñ'rr‡hȲÚÏä—ã0²3 Ã!ˆ´j<†`0ç©§µàÎ0ããÓÀMx+ééÓ/ª§¬w__û¸YüºþI6¤¼{›±>ÎÜ a=3Ç¿zËE¸Q™IFós—6[õXí<3#Î>–Ð Y‡Ö0ûÿåóoÁ VÈ:û4ì¹vŸ)P’³:Þw}¼š¿¬BÔ*9-XßÔ_¥ÙØB©dx>€“7ýÆNû&¶í‚¹Á\“ã{øLf¹o.IMcvÐAÓ1dhx\=|ºESœ¢¼MŸ¸_Àý˜­P(Û®‹Ô`':×îF‡Èè¼ÀE¯ûód0D.÷@¼Èw¼K?1{M‚a¾:£ï|Ñí"cý¹x䇈,åI¤žý X^Ó¤v7ã4ý(9†È)gžšÏ_gâ:$ÙçK‰R¨õ|ÿÌCb²Á¡q°D`´?Fµ­#\ä"&X¥j†;WäY@ê»ýÙ^rñÆÜ C+\ñ{ÂÎ0lÇ…–­)ÌT¢¸¶#´tRdÛ'‚gݶ¡ÓÛ`Öa›´lšþd^3ºÂœuhÛq4¿S´£ ñŃ‚õmˆÎêË!,b#fD\œ~ ¼¢):’µx0–Œ;aêí¿‹oÀ ž½ñœpȦ>ïÆ²kú à‹‹cþ‹këdx ¢ß#œiÔ÷xÿ]Û•œó09T4‘y666^p>Bù¬³‹Clœ²ìvÔf‚gÏÀf°’Öá8´ËPPèýœUž„#Â6.ÁçÚ޽j†Üñt´«õ$·~q#ÐÙbVMjn=·á•erCæv|ì¶ê ßq¦:…kañŸ˜ÿ7_|&ÿ£'nɦöÑâÈ=œîˈ¸ÙÈ? ã›G«JA ÞVH {´z ¿K8jÁ° ¿ùôÜGÛ0÷wi£û:¶Ñ‚tm‚[Åm/ᦟÂ2AÐ“Í |b9ø™qàÉr%HL ë;b­ŠÃ©ðKnC0Æíê¾çùÇ:´œÍÔh<©¾þúÿ°¯ÁRÕi?"ÿÅ{Þ§Ý»Õ2{O¼`»¼¯¿ZÂz™Ã5ea½y"ÞÞ È›þÁ…±I1Š#Ríß﫱ôw=jRIÅAa!L¥nØN}áµ·ÍÜaŽÑ¸Pø™ýWá«°…&Áià—«ÁËüñ·ï ùë¦Ø„cb\E¤£Mšphˆ’‚¢¶ó,åÁëï|8d³§q×VÑKÔ)n±·&S®“øÈðë¸qíŽY-4ׇŒ1¬F­iñ]†ÊÙ)ŒSÙ‰f‡ Î–!´ÆóçlÞ.RweðІ2=éû6èÍ?„—Úl¹XÚ˜½2~æ÷W¢X¢æqÜþc"¬Ý^ç\©¾úú¿ÇÚÜÔKf‡ÙGàÀ9R}ÏÞ{/تù){ì™±˜d?˜¼µ ]·å,Ø‚ùëC¼z¹ƒ€y0â!Iz\P#qƸ†å²z]Á*^™½€qáë8|ßv5[P±W¥f+òƒzCðǼ~ã8%zo«­Å©S}-6PÙß±ÃÚ:VÜñU"½ÊšüfÖ sž_ÿÉ'ŸD$¤Ö™‚¹XVQé…þ'§0{rÄþ„¬fèL¢ñ2yìª$Îêgø¸ˆÜ {M,K·†¿ÁË –ž†5a%>¾üˆä0 ¸ -ŽT‹´MwÂÐÀÌäæ¹ œY|e~Íë÷)Šâ°L™¸Õ"Òréëêóßüý¿]ݺIÌ‘]jì~,pÒ‡³±Ñ®¾þæYµÄŽYÝ-´RPŠèà_úA¢./rÑçá;þ)„*c\+Ó¢n Bü µ©- øÉ}çg¦ÆI§Í”š_¡<=mÚ®™À2¾@aìwg>ÞùúÔA»J¼S7ó‡ÙPZB;ÄC´­ÁðÁ½õÕtàbý-“iÅeâ4PON¹(ÝYŽuJ¯SX9ÓS[X;à••“&•ív;ÐH¦ì_o;Ì)`žþt\c7¤ÅFc‰eÛOavÒ™3Õi~M‡Œ1lDHmïöš±wFk‹wP±C£1"zJ¯A§+9çï €¬Œq'=öX3ï\÷ k†0WbЉüŽ9ÞDr¼cG÷¥F´{®²‡=9û¥5ª‰z½O`º«a½/ä«5SÝf;¦Gþ•©´gUcí §[ÝÀ§&îÐÉš¿)•;]濟­WŸâ cMAÅ:qS~—9o™àUH׬4‡¡»)ù&Ž·s®ÌÔÒ06'UX:/t6´VkÁú\f¿$dÝJŠ+Ñȼ®ðˆ²øTƒ2dŸ8_ù74²ÀŹ˜B\¨~ù—ëø\XëÏfL/-.ÜÁü¿‚p;Lþ_þò—a ”iÏweñ Æ´) N¿g,Ûå¨GQJÊÒû ÚÃ=.G»‡a”~˜©h§Ù!Š)æÚò²ë C9þsŠ%šLÄ:®Ñh‡Ä¢×®ºýÚ6Úv•!Ðckò þ¨ðhòùÅÿçÏXWóŒ?X}üáBÙ°s˜¦Vˆmí³Ý}{µZa¦j…íàvXR’Â: sˆ¦CZAð¶Ç…ß´²Œ®ƒ 0á È8 e˜¶:5_Áxl¹P%AÚaö§‡BóLY=Gø{™ovq*v»æÀw——^4°ú.ß>ßß0­e êx·ÍX ww“Í2wuô™™Îàsù™[žá 0î]·Ã˜Ëüð½žÒßé»\‹ïÐÄSfg [+áɧòº­,*òÄHþªÙ¿~ÎSžõfh-„T/%û.ñ¼24Á¢¸‘¤åf½q9à)ø÷}ëŒ|~8oßt'¡ }œip¦ÚH”!¶X#:‹Öwæ6€VÚ•gÂXßñFœÂé‘'¿²Ñ(XCÄrè{†Y-§Ó!ïþ |õ¶GÙ?‰³xÁw,‡Cy~„€AP7®-`õ™ ¤M¿“ñš¡¨qŽÑßEËJ‡æg0¢ÏD¯¦Fo·—©ãŽ[6a s‚TõãN3´BÈéÙFƒtehÿÆ:2<}¸r¿iQ!ð:…}ÍŸ À ÷öfðnϰ–Úïn‰ Ábš 0mdN½ÍmgÒšî2<È/‚Á™oÞºy DÞÿ•aW÷×1¢^f™ì¢Ù¸èaÇ9­²¶öæ_bר_ar­WW¦YXÃôk8µŒ{×l '& ª­Ý Ð "Úm³Í8É™÷N'˜sàÎ…Ÿý´KÇiLȸcm³è00¤ü“ƒïÞ¯3*¡h¥x,’ýØá€È“ÑÝkQ¦Žÿâô)°<-5Ÿ®ró¡bqDÅZ fabþ[&:`Œ$nûS_RÞ·0ñ@aÖÁéwû#Ë·.2˜Æº—Ðç_ƒ¢ËË¿€þFb$Ý¿ “Y—1=LýÕ•G0òRõüٿѲ3oÆTóîã*ߘã¾@)õ˜~þîá*SÑ(¥]SÀåžÇtÊ–hL•äÛ ç gg¸nzÔýÝ‘¾fˆAcÌÍzÍ(­úÿœªÂjñ£¾ÆåÔÐ:µ(««Wf@–LÐE¯`Š-Á|Ã0Ÿ³Î³5n©.Ë#0„lÅûz¸‘â;Ìn²@FÍ?È^ñÆÉ3¯ª'}$–þêL‘0„CAp `Lµ]ç˜"–ßéBÍ®"uÏB¸Lvxˆÿ‚Ù…a, ›œZ(0a)²•Ôè·üís  +ìmÏlHßÃëí=MÔ9„©'„5ê‰Ï(¥aau}ø¦ìšèyœ#…‘¸Š—¸­Ö™ ŽÅÅœv=$ˆȭ­ç •Z™Nû}Lð*ËÇÒßt’ü­0T‹nB› gðF9\â?Lª€¨™—ß‘;ÉšŒìÔ,ñ ö‡Ð’¬¦äÓ¥¹ûq)6ñT×h§¾X4¾¦!œ¼F7±Š±îǰ\M4ÆÀÓÁGáÿÙŸ¯o©Þy‰;XŸíÖnÕ·ÊgA½|‡¼•‘°ô«ÌO(­²ÅÁ;‘‡a¡ÁÚvu¦§h»3BiJ‹Å'cŸ¼íqá7]Œ`l ¹ÈôÄ4G¯º?:ƒ3q° rÒÉv%½Šqmz™¾0(Èûä·ªk‹3Õ·Ùý‡TÖOŸâüh1åáL€ù3çU UÒš çÅ‹/ÑÞKh„/ª]BeÝáWsöÚâ,ðŒä4_Î-‹pµÎ–ÍΤåµ&u“« ã¼³y¹òíúõk!qÍ  8 éÊ)¸MÂ91‹–ÐsÛ¹j­Ì¸C/."¯÷eÄsù¿þü›˜òY$ðÜÜLõéÇŒÅÙ èηb¨²çØá“ÂBFvZ¯˜Ég(x.LšSë&‡®¾‹!š}!DhIaºóÁíjï*3!óka}ûàÑ‚ÌI7°Ð>¬þæoþŽ{é<«íQØþ§Â>Ö?è'QPw‰žÀI‚&Íx;þ ”db\•nM®[¸õoL2§â8:ža9~ R›!‹’¸HaGáµ€Ñõš™w ž¢x•Ú,–ÄñÂ@uÿ“™ÈÄ´²ò;¶Bÿƒî„Åg”óX£nTòìÙÆí™×ÿßPï.}ˆ³›ˆ¾[×Y›22[iî×m×a£áâû¤„ë2E»Þ܈åòmrS†îPE \_”Ö¨ŸöÅYÊè ]qrûœF…£hÿQöÁëÅ:qwgA Oej°H(És5ΩL"ÃPùÕQÊ,²¦:öŒ©ºª®-°£*!ŸšHû{/˜ýçNfpÉ©N >±Ñ–oz2™ßXù=ÇW¤ÁRÒ#i+¦ÀF!’X°„©Ÿ¹ç ¸—ôÄ/ƒ05fö›Ú¿ÙR òñçJÜwepLŸ`°þ"¡%4ÔTÍAàÔ-¾¢ÂøLÍEõqÉ/ûLÄ `Òš²¬Óƒ8Mj‚u54¸NxòVÁ¦ª!Í9SÎÆ¾ÈôY’妩<›v<‘>“ø0ˆâ‹×økßX¿ÂQsX¼.^aFÚë.sÿ˜©ªôñvXšœokvÊóžg P ů}?ãqá4jO! ï(Pr-‚™{ç“üþì©£oz"Ó¦_ÕeYž oÉE9…%JZ™‹„y²àÈ™‡ÝŠý;ú‚Ä£ÌM13³uêK%§éžCé§M"Ö.[Ø­¬~¿i•éàøÄÐwŽØ–Ìõ&1,T@R¦‡S@;˜ÑaK„&íèt™gŠòàС¨t˜c…€§} NÞ帰ÈÊ W5ô c›Ac·êÜ$ûŒŠ“BóÚFÈ)å!p%=ÀÊðŽÿc â·Hí8Üñî ï~v‰~ÄXt}3~‰È§/!`îÍÞ¥¾y† 4áÃü¬‡Ó)Nnl<À ÜÄ«‹¤%×MvvÃC|¹þ°ÔyÌÑ}KÊ fGøa—›vÌý/­v¸vrfCÛkn9¦öw^X-Ðx‰H³Ýh® vóíl®©¥ÉÌêFëç¾ZÏ:C+c÷h÷o*܆Hâa@ÊÊ‹p`ÞÇOÓÞãêέ'ÕÕÅéêß}v"C‰Ãj®Gˆ5^~ªô't>Æuýš¤…á‚:Äá9fPp£í7¬ÛïsSX8ôí<ëþ[­NõÛ/žV+KËØýêÊüÍê/?û÷à"÷"¼È¸X굤ÐÎÑfPð’´ ê¡¢°A²†³+SÄjLôlO M…3‘$(ˆÛ`‚šÖ ¦ÙÅ©w#„Ú>8‰ƒA~”C¹2™æ¼åæ¬ –¾w¶þðÖ½ja~}…a³AOþgõìéDõýCöaX¸]}úéb+»…Ä?C^ûmçÞ&}¾¼ü¨úÍçÿ´àÕ,üðñí;ÐQæ K…åD¿9;“ý§™¯²Â^@™®Bƒëk;W±²}¬4X‚±¤E…À»há¸è­P³#%’+â¦i¦"ŒÜbÅÜ5¦ÈÌa?ñjnÙ›¾ÄZRG‡‹†Ò¥´IÊïèt<¸°%ÂO»½ÌøŽu;Xhe£¾ˆ><`¾z€jqé<@Àq$´©¢Â«/#á[p\¯Èwþ[‘(²yŒ‹æÓûï:2/c5<ÿ¦‹d —A1޵æVi:E3¶CZgq™s÷ݤ©žÀ*(ÏÀ¤@”'®£/N*Κj9C¹Œ\¨UÛÊ!Ä+CÖ™fêî˜=*×Ã0iªŽÇÎ&3Ì4³twtØ} Èá@ÒÔ°Úœ6¦^žKm‡VL´ Ü(èÝ fÄÄ0ð-…s¿³Uë[sFBE¤Ùï§ŠHëç] +³³­\§ØÜÜòÕßÄLAb±šlg· €sì—{ÂKI©atp¹ÈuÚì+ÑÍÌcÂÔ!®vzšªìªËâ·[D¢/2B3¹çàf˜Á;0z:ì†xƹðé1¬ Ü7? -›”Ämn?ûY‚–Ƀàk0¨ ÁlÏBey¥ÅB‹ œ>,½Ý™ˆéI¥lÿYÆ\…H òíH} ž–;‚³fdKÀôì#ë³î€R/J/þGR£ ÀaŠA SãW¸f~„«!X:X:íH¡öƨ>úh6,‚û€FbLx…5+å:yÈ ´ŽùÁŒê¶á.N!¸OîìM«¹§Zç˜Cµaêÿ«¿¼‡°q – û ~ùåCü2 !‡·ˆüâtÕ` Ô‚“þÏL`B@ S¼œkC˜êc£Î¤°ˆ¾´_—†—ƒ-¹›C©õgÄÝ)h`h“çY‚PcµâôôxÚA@!0™r[½±†Å2KhõÕ  óPRS>aSØY‹}±‘AõÁ˜[áÞÝ; Ëvczp¿KŒþçUaüü éã4&GUðï =®±UÞÌôÕí[øÈä®Ù0rs‹™?æI~I7†¾C.çù)³66#kkÓÜ 7w…ÎÝ—œ…2S!ð'v´Ò^ç‹@851‚SC­ éÚ&ièãÔ`ÒÝ‚ÂÄÁôMgMJy ]$(e•Ž ´ó€GAŠÏ©y”Ø9Ff;µ•fB?ˆN«!Î.~e¡@¾OGës£0;Ù6ÔÚì;°‹ÄÝdÜQhÓ²æ_¦÷t¼•ãÍ,?*éûc9ž–íDM}ѹv0p\h˜‡RÀ0ð Ïó*xqhâX?çx}Gœ›Iù_€‚Í CwH>2ÌÔæ•„;,Vïù¬øÓ Pë‹0{,µµr $×Alºá/®…f‡‘º 8Œ®SËaâÚâ+hÄ‘acå]¼ÅªÁ•o©ß…(ærX€(¯Ÿæ+´&áw;9ÏXßO?:$ÔWtèJPêwl´;F˜ì÷ì%>¸àïÑQÖÞñQ XÜ;‘!$ý¥%rÄÐqhHg`\P6.eŽamClD¿ØOâÚƒËqxÍê¢&,1žC7ÂÅÅ„W¼{ …çÝþMÓ¹•‰k <ÓGÀž *èX¾«Aƒæ0psVa(C€„àIKi—\òdÚÏ.øQÀIZ ¶ÓaÏë,®lÑùþ^ذbÍ™ß޽‚æ‘y–WÖ’½êêÒ °ØÁ«üÕ ¶˜×6•¸«ÒÊží"JæWŠwðò…±á0iâ#[lt”æ›±õŒ¹Ô’ "a‹D;M„V œ.ãzp¼ E¼+á9ãà´ýAÝö6š c“´Ñd̵ѱÌûO˜÷Îqvî ïœk§µAsÑ€Cîr]wrü휺‹XL’*H±Ã\®Øs#S}!¶»ˆg÷a"ÂAÉî3¡Ç3‘'A|5óø;ˆQh5‚èÍÓ·´Låïmß@£úàúbõËû…(2Ó¢+´†175ý¥Xé.d —¡¿†°BC±È$$°x8¬8&‡–‚ë>ºu†Ã0·ÊP©[ýþ›ÿÅó“Äm,3;r·úÛ¿ý¯XKWb¨tGZÂî~!a] FRIu2gÆ(Ø/Áˆ|ÚßñÁgü.•Åø8~Â#žâK2r=)ïÞ½{0È8Þ÷ÛàèYõ¯¿û .ÓŒ¡ÍÉóÙ2K˜¹ý.,Øü!ˆehh’Ë(.}+’ˆõëTdo,/©‡W‹ß…ö:CÐ8žFƒ2}­åJÙ˜ùB1“”µ¼P†nûÆMÚ‘ÂAáì,›(Ð hqu­‡3Y‹À©çÙÀ«Û4;»H=[xã§ñWÏ—Àkf'µ²NVi‰¾×äæ´›÷­V|¼”O™œ.âýÖOðð~$\á‹Â)”š}зÌnùQŽõ;Ï8ž÷Z87y$f4ì{ êM!оƒßåßÃBͶiÝù©5c;Þ×ñÖ@“ÄC‰¤ÖhÜÄûY‘±äQõ”$°\uóÆ`Swó Bò˜"/Ó\!ñ@„Ú'B'ù)’$œ1’qŠ6pã5qºG:qÇÚ[DIñ8Á@ LW:Ô)sÙû¦;©Ñ’XRÒZÀχ_‚Uó´;6Þú:+äZ>O|9májýâý×êyý‘ÂHí}Äâ!süí£võiPï<óÀÎÙkšûÛ¡I °¶Íˆ7§‰®_§sws3gˈHqìØOíµ¼Ìòeˆd}}=B«5±t«¯¾]‚8;ÕSF\™Ÿ¨þâã;¼7Wݘʔhâ#ƒhŸ´šïÎ$ˆ/©_ÐÓî§„¯åâ’h­€¦Xu¶™†Ê…D.HÑJ{¶ü¤Úh<¯þùŸV«™9g þŽq÷u"ènX.¥n·_PÖ*NE¦Ãðýä̃°ØOêI‘"^D (BX•ƒ;A+"þåôY,>Ä™× Ìcãöí;0"1ĦìîlT¿ý·ÇÕõkëàv ¸ G¬ëØe3Pñaè°åFˆ0Å*P!ùaÝGâZñÊ!C#™×Õ‰jò-¸ŠÏàö¡m3ÒÒ~—-žRø¯€Õ|á‡eøÎôfÿ«t6šÍêÑóï‰Æl"¼´Š](gêõ¤Ã~eà;ïãxU¿²%±—Iô¾:5¤¹»3™×ÎÌ2ûäÛà ›šHgF1ûÇÐJH¾ôsv<@»$À`R¾(D˜] ­7®`ÊK¤ñ÷¼¬yšË§ òˆŽÉޤã½H¥ùKgHÛ,é¢YùÀd'" B1ÑbŒ§ ¥îynŸèrȸX8õ(1^µ=ŽÕÄŒym»×“OÛ˜šmfѺ垈¹B@E "™ÅrµÔÌEw:c£~€-šK«÷p°¶ ¢ƒ˜‘™!)‰yjÖÛ뎽…CÊ_\ôzZ&\H‡(újdV 6Þeà`¢Í9ÖGÛîc¸å˜+joßÀ³ŽIZ‡óósÀfV¦Ù©æ&Is~ J½NÒiT˜-Sxè2i$ñ¤Õ˜ý?Žópr‚_X€&ÆÔ2泸p¢‚X^^¤7²i!|ªGO×Ѭî`M4(ý9LŒ‡ÊfÀ¡'G ?¨ÑiãøMYqP¿ÅJP8eø¦ZµÀí£æp°ïÍX,]:œ+W:´c‡VÚTä/ß›Â5‡1M¶*7c«½M÷ƒgà,cÍ} TÛù¾Ž·ƒìøXÀ.§µ¿šÍÕêᣧÕ÷Ì…Þ¾ÙÁK=ʪ»ÐLó ³¦rG!5 ½tLNó5E+E±…jÂûË\œü%U74 ‚% aJ –RÚW-Àѱ"lÓ2Ìïµ-´³Û€5š.¹Äì&Þzâznv¡Ö-ã­ó aŽi9ò øÎ0yì+‰Úøà „CØJ;m7ãl'‹®^a>›x†j` ¡ä²å5ð<¹%—çj ¬­±GBS Ä5åzŠ{ ¹šÍñåÙd§§ªv·Y]¿:[}r÷#¼Ó:muÂ8à3˜+È[<‰i­¨üîO§%DZJÀ4øJM ªC\!? ø¾së&[™uÉ+Àš ¦Â¾ÿþ÷´}÷c®|xøchƒ­ÖX‡qˆ}æÞÆÈæ‚ ùád”ÑÄ¡3ÐÃú=SÈK I†8Øl‹W¦:ìéXç‘Ð*rllé±ÙÔª¥^¦PYàó¿ÿé!t8TýÍ_]'*t®úðö‡·gJYÁˆ`‹vâŽú…—ðHSjtOéNús(ì >òEÌL$CV˜*:Xú¼vØAËçsóYÛãi6­´’„ Aϵuöaøv ¥RÀ:¼ž‰a þ(g¤ìï7[£Ñ„sýykPJOI?SšOv„šÊÄ•Žcš-Í`Í5çØ5›2 ‹ï‹ðF¬*Óü‡ @†Ì”„—s½[ òÄcÊ»‘UHÂá] Èxy 24XV¸_NI‰,Aíæ>vÄ6B«‰Ck“•dÆŽ;§«ÇµŒ¹$$‘­Äž7–¯‡×ôU01ÐP¦0î8ngE5j‹³LÇýŽ+Måíx²Ó#ý ;h#S©ÑòÙá r‰ÀÃO‡_«u“%½&ÍpÙè®ù Àå•]úX‰j­Ý‰a«®”èdª@À~ôŸ¶Åë€Î÷œæDdÑ{½ÇŽKÙÞH-¶´ÌîA¤k¶`Rœe7ntaDWÓÉPDz·…{f¡¯™ØƒIàjuË‘fâèó×Ss KZ#ߴ˵Zxѱ:ˆâÉC!àáÐI«e“…]Ýî}ÜE1´ÒçCìõ8Ît¯­Æ¸ª\X'ï[·‡X±­éÛe.;v7+p¼31e^>ƒÜ:À£“Ï:xž5%¶3šÇã¶Rí¿Ïšo(ØD´Ÿ­Í}¢>Ý‘É!Ce#QÓ (ãÿóСpŸ÷x' 0¡fÉÝ»wCRI¬ ï5‰en4XÍ>#šlllÏì3ÌkÆÙ8ƒFÉó>5ifˆÙe·œÃÃÄp“Ö‰?ø]VN™®zi‰M0 îóÇÿ1=å¬ 3³ð(&¥ ó›ŸÀÌ1h¿üÖ‚à#MZ©ŽfÒ}úŒxqbW裖u¬åé𦴅ÞpP#Ñ%|³P9$²ð¢ÙgFÄd$†sBóßñÎ —Œ?5E\^ú ´µPm›—Õ•«ZC§2ˆ8•tÂ'áKðZ?­§ÐR7›Î¸Ê$’U‹ €¼ÿÉuˆÞýȸâ'Ð^ Ó@`…–óS`<à}+²8ÜGx©uÛ—´îaj³‚’Ðå6S¨æèľrËàNæOþAÆì &î°ß5o™h˸2”CÊEXy„@²ZÚLâ7MðœkÓøºXmÃä50çÄf›0]r5*Å‘ZRœøÛaœ‚¿Ù4>ÎU,¤ß½N{»ôís,¢êæ ‚Îf&ˆ©`“)·AƒJ¬Qæö¸9 zow·…`ÆO„yîЪIÊtû;f•òI¸³>=ð3ŒÐem‰œf…Õ ie‘], ¿)òÅ62µ¸»çòkR²!˜Œ¯°?=¥Kûþ'%l·©!Ά)y=R"»B ª§yvŽA@ $Ü&Œ¬/Äé© Ly7…%/ 0ƒxñ+Lhß±¼ý#×ó“¾›•iÛ;0…¦w‘1„«÷\£v¨­†ì7žðËɈÎÎá0@ÂuŒ­o˜`Òz3˪ÄãYÆ\ñ<%½é(ºCŽóÍͱªµÿCMθÜ)ÈCˆßñ¥Œ­ *œIY,XB3Jóû´qÀîŽþƒšxÀå{Šï“ÚA!%þ5;%x… ¾-—náíí1ƒÑ|GÕ“gd¿™8 ®¿Ài…ðL”hqY_¶4±,¤Ùkf$§2CàcpèäÔn‹À)×/3E¿äøX¡•  £]øWv°º­uhb¡ŠóÜÐë ´š´\ Œµ£ƒ”ÚZ¢]¡i'Ýôuóžé[6,IçfÖãã¶ÛS“Ù£ù¯‚²£;#PŠ>qå¨á<ÑÄdÈ ÓM:H²ö‘Ž?»tèb¸»Ð]žÄó©åT& ¨ *±<ëÎöfVH³¸z…è¾™™„þ¶ŽÓ‡8ÖO¡Ð"pzÐO‰^§¡Ÿ4)66ÖùÜ®~‹“é˜Ðéá! >Ó‡ð‡Ó¶yÔýÀe¶¸÷SHHèšÌ:7m§q1+S—•xÑb8®Ú#X ûÕ·_~¯ ËîÇšÈXahKñsÂLuíý–n‘47|HþV^Œ21?ŸðZ—§´!³Ü¹s'ðâoc¤O͈™cƒU§DV®­÷B@æ%E2Â3ÛWZ©á¿PzG?fýÞƒÓ´¡kk¸ÜÓ§bTXíWi±?òÏvÙž÷y¼™ºÏY›€Ù`Í—yDˆ×ÏH j§L©¦e’•TNá¡ x'‰/ Ñšf‘ˆ×ÑX˜&î÷ý¡ªWoýÏxM&ÜþiÛ/q_U׫*r -§0¨ L³E”˜’]¯3žÞôâ&³eÙ¡j5¹ Ä™Ól2×›:\ø,S¢ñ»ÂËï^³=–Õnª;ÈØ×¤.Èrë1MX¬P.s•z^â'‘éû*/¯—{>ëL@ö‡írí„ΰ‘èk’Öˆë½C†?ÕÀŸ0ß¶Ó‡;áCÐDv¸'lb¤®1ÑÒ÷70ÄëOgšcfëO߇uØ|-á3—„Yƒů0É´úJhu †·ŒkȈBé°Ö<Ów@Û )qùøb*›ko}Ç5ŸU ÚjuaôŸ¯;,OËNn_–í×䥳êz]Yç¹÷Þ€•  H·„B@-êÕùk™¿ìÅ'"<Ól2ý–ÚÒÅ"uBÐ<©i@ ÄTŽe\þ>" –#¼ˆHù)´^-lN#7Û#¬ú1&(Ä 3ž4Þ^©.N„[¦´.ë,ð÷ã¡Óa4ö£Ì)…Õ@eYþ R~P½åX¶åúŽ–³3úl“ø·^olä´­QyâÞ0Ö IÊøÁ S¾¼S_æ‚Ñ¡ßûE8´Bì{µ˜„ëÆ¢#c¤;C Ýâd,ËâÓ¯ —ÌÄEÒÄËÚú¾Õང2ûÌÙ¢hÄYÁ“ (.œPاâAáî§BÊ™+qâ2çV« œZ¦gã8Û›3_¶Ñ÷­·0v¤'}[pa¿(lã«ËY‚å »pôÑG³ezyùä»{¯@pR¤$ñ¦Fò»Ùž¨‡Èð»§‚A¯¼ávdÿa™"ѳL…XÇû@Hé³H—€­ë¼åøl§„¦…£ói{Ûñ¶Å´Lï+ |G"õ†|Ç]yr³Rßó¹" _“×=Ås)×OBÀºÀ–£ƒLb8Fû­­~¤Ÿã»åÛ.Oû¥9™¬ÁЏ0ÐÅX„)í°kŒä1Âê¢2µ©ðy”þ8Gõ't¦ ñLaòr޼àÃOûÔ>–Ö|N†4ž"è|‡ÎÖ×Õ_ʳ €Òv¯Ÿ>¼æ}ëòyñ^ž{]–#œå]qéû?ÖñÞ€€ÚPöT“ªiœ¿–ð<Ë´–D.!zºGŸ¹ étƒ}VĨY,S‚ñ÷›yºœ×ý¶<€Ä!쯂åt2‚0ù¾[b³Ûeå”àehË~ßó?Z@¶_í$‘Ú^‰@ &sY¦Däó¯;J™ÂâóÂ¥pÿ ßçÏŸGXþûÂpÚ.ë+§í·¶ÝöøŒ‚Hd{¼îýÂŒziÛEàòYËÓ÷dYÖSÊOeX"íý#â¼Ð¸·ÞtXŸuX§mµMâZ|ö>gûÄ¿ý],€ÓÏõ¿S¾‹Ëô,8,÷Þ÷ç"ÒFxHô6¤0­H Ó“û"Iâ”@¼î÷ò^¼Ü÷GÄYNA|Ñt–ñ¾‰¥ÀÙODç)¿t–ðÙi¶Çv•öXžÏHˆ„ß½çi$$Û/#MdÕlÂtš°ß“åZg©KüY†uÉ~¾/ÜÙ^Ëò=Kû­ß:¼¦å#Lö½íôží+Òv‹“ó0HÛ-_ÜMig^·>ûÅO¿ «ý$NÎS·õùŽõÙ.˰ì³piK}öƒÇYÏž?–×öÝzï_4ЩQzŠ€ÓHð·ðºðËé"Öï§Ëé¯óm¾¿ Ò lš¾2­°õ·ÇûÂ_¾ýí³¥]^—Øü,D[Þ9ϧïÉTž–c¹2b?\ç)çMÏXOi—ß=ì£rÈ,ZFjÏ¢i…Ë{¦ó‹Âf›,G믳Ô}úS‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½Y›Éq¦g?¹¨dSbSÝ­îž¹Ÿ ý+ýÌyÝÎÍ<3=jj(®µ‰\ξÌû~‘HV‰*rP,D‹ðððÅ<àŸ™¹¹ûèÿñÏ];~Pÿ jÛ*Û8Ð8Ð8Ð8Ð8Ð84 }?@4àØè­ÊMhß@ã@ã@ã@ã@ãÀMø6z«rã@ã@ã@ã@ãÀô},Fçl6 õº6Îçsç¹ßïC½~×ñ^`<wóù¼ûä“OB'“É»ÞoaŽÇc·Ûíº—/_†zÿ®ã½Àt: øÿÃ?üC÷ÙgŸu‹Åâ]ï·°ÆÆÆÆÆÆˆÛí¶ûòË/»ú§ ý7 Z}Áÿ§?ýiwqqñU¯¥q q q q q qà]X¯× ÃÅò÷ïµøÂ þMx [xã@ã@ã@ã@ãÀ‡ÅoKû~ÑàêK+Mã@ã@ã@ã@ã@ãÀwÈ&|‡ÌlI54444|_8ЀïKKµr64444|‡hÀwÈÌ–Tã@ã@ã@ã@ãÀ÷…Mø¾´T+gã@ã@ã@ã@ãÀwÈ&|‡ÌlI54444|_8ЀïKKµr64444|‡ø£ë|‡ù´¤>p|}ÍøoÞ¦íó7é-^þ({ÚÃÆÆÆ‰ïÞÔå[—ðk›Â°eÌ㫵Ì)›Ç(øým!à©ÑxÄbq o„€ÑèéóǤÛÅÊ&|  ÓŠÕ8Ð8Ð8¿Å„óùôäþÜN‚ïÓ8O¯úõû7¯›Öpït:qîBë½Ü à³Cl7Éî°‚¾÷ãÉôÉý8«Ç>ž^¿É¹]}(hÀ‡Ò­”˜ÔÈOïŸ>ûÚý Î?ZÐÿOÞð·=vÇãÀã {[ð~2ž=†gy…€¬5_BB[\ö|Ž&|«µq qàûÆ·ùëcì_¿»vûE+®@=„wö›m^rôr¡¼’‘ŒøyëA`¨tŽ ¤W–€ûÇo¸®°±ÿ— ¿+?րѤ›LçXÊ*PÚþ‰{‡ÊB @`ÜáøÃiÞ<â4ú—ã@þr¼n954|ï9ðMÁÓ·o©ÝÓ€5x[aí -{ð/f÷á^Ö¼1ñ÷ï<âcöð¾ù÷tÌøÅØÒÞ“Ï+¬hó¤|Ñø÷;âY&Íÿ‡UhÊpû‚“P]Çþòã±À2tœûi7_x¯PÀ?›.J Áßgo„€?ô!ˆÐQÅn¿4à/Àä–Eã@ãÀ÷“Àâ[? €½.`"Ô¸ûC=Ô¦ äϘÖwû=BAîð?ÀÒ!-þišÄRëŽIojüÚÿ]:äqØ÷yùqL[š¢šÒP>ŸÝq÷aà´íÖëÞÙ&=q<ƪР! t“ÉøWãwÓɬ[,Ÿ…Nð˜ö×WŸ†z?κ«KžC~ס%@ LžnWKʤۄ€¾Éÿ¤ &·,þ8ðŒ‡Úð>ÞõÆSû×±p†Fàú¸À¡:Ü)lw€­qä“‚‚Ï ¼ÕìüÄOÝöXàìûø–}ߥ¦"Ÿãþ:¼ãi%OÂI\ëÿö.TíÿxÜtëÍËPÓøG“JëG &ÿI€ÿâòãG`:»À%aÔIýÙlŽÏÀ¸h‚y7û¾Ö*Éx2X}ÀcÛÅ_‚MøKp¹åÑ8Ð8ðAr 4ï§E{•ˆ>§Zs¯QûFiáo´÷J¥ï°Mì{iÜÛÝæ `«ÁoKƒø ø þ´y DîóìÔíâ­Ošÿf(xç€:q‹‚4‡€î?I‡?-ç8þ!0`«EªE@o¬ü¡5Ž?Žà¸¾æÿ#ãÿšó¥:žHg³¸èfç}w8ÎHgøOÉ-ŠE€t'¹ßç}Ó8caŸ±(ø_2í……vüù8Ѐ?o[ÊÞŒ‘÷ (8–u¨…{U÷'A‡8iª†]ׂº€Ì½B0 Wã®4¥ÇƒNujçž¾^qÔÎK ´ôÀ©0¼“_®“z, …Ë D,t dˆÁâ[fS¢Bþ¯À6'=~A*¡ŽýÖEµ<œ˜0"lDþù£^ä5Ì4`ÄžëIy‡ëÓ¦Û1$rth€„ãÿ›S79,s?E08œ° (`˜aØîBã?!„k†"ô&XN¯BËJ€ÀÁ»M€í¦£ &ƶd>˜[A8*Xú¸eL:ü';Á€gŒþƽïV+ÇÌkªœ¾Ù¬¸4Px·íMò¼«ðp<âT!‚¹øŽá÷ nÛ] G„€ N‚R\ÀWˆ‹ë¹>'E Ê«ˆàCO çºgÒ¡¦‡L=à¤E^wüÞ¸Œ³ã–øÚqÐã™<#©¬*šÇW]'’ù9³@a‚Øò_Êà>ñã7¡ÌàZþìñ 8/Ð구h¹#„˜ã.Ém7dà ƒ©‚Ø©[̯-Ū™ã‰ÂŠi·ã»à@¾ .¶4¾Ä„ý˜’€.€xòœ¨sk`©¦XqâôhdÜ›HêÈGMäÐ<€Ö[4th7„É>@®fühÙIG¡Áè@Zk†¤|‡v5à½çŽ!© ì‚:ÇN:~‚§i8ïÞ´)Ÿùî2 w¹·ª;¦ñI#ðV¹âU…ýzë®§šø‡žåZm¼?½øÅvLûg„‚3ŒHå·¯ àÆ1œóìBpó´_ŸaAŒç ©/þ¼s"ai¬P…ÛËé‘ "û³ü<é´ ’ÈÃêU·Ÿ®°H,ºùlËèÃ5ôŽ™ÜÏ/ywši†,¯ÈoFzæ¡ ÓÌaÄŸøÓ€?‘qíµÆÆ?þà e’/ØHjÑ©€Ù;ÕA«0ð€)\jÇ쥆í01ßÜÝ„&޾­ø% QÇ$_š®i®¹¯rX5øº/€æž0Á]€LXLæ‚¥€wd |ª8r 5ùK4õïÔø¡ÖM¬MDfùê×tÑjåyôگѨ>=Ê@ÞýëÓÚ=BÂHÓÿ”|fð '}òÚ¦Œ»/qÔ›R•zd¡î4`µøæ¦yÎø>¯#DÌæãîÅGŒíC-–<Ô"!…¤^ÛC¤wü7L5<,39ž&Ýíá·¡x&ÿ²»ýK¨€ãÿ?ý›ÿ:Ÿ_tKÀÿ³ÿ‹Å%i Ôé“3¡ùË&Ó|¬ûPïF¿5šð­YÕ"64üÛ9@ýäô†CP-0¯°üaš]üÞ•óŸIµÔ}iüëLƒ+¯‰'<©Bô1ùÜLN¹{à¹TÐ7ΦÐGàm€V0ïÊ_g@óÏ!ò çP©'ÔZ‰¹UK5d°Ž3ØÓ#9 Ô¸Q«Oº"¸×%T$¯ êÏXr—„Ž<1G’øÑÔCHXt§Š«…À8¹ï›·ü#@-_¡àMöú d$:cûc¬šáMWDÄN)ïqŽIsl^<ñðSà%íÒaŽë×k(mƒ 2ÆÔ¿YÝqÏPm¥‚í3í:Ê7™öõ7ƒíoù£hÀeO{Ø8Ð8ðoá@¼¶_¨qí‚@5DAT ‘Þ›Î^@Ø?Ϋ/“¾cöšö $0™»9Mºe‚/m]VËߢAJËKßÝk@þþ @À^ü]wÿ°äMo«S^Ò7 €O¥t~€&ô€¥f„Û'<<¹ŸkŠö¾zÒÍs~ךHEØõ4©“Ÿ÷#ΑMÛ÷FSÁÔ3ÁLÀ-X7d=¼œÒ'Í-ïDTHZ\sÃ4úPA\ÏÿéˆÖÒÀ;ƒœ¡¥"×€îhÂ4¿‰6ÊB&sžáéŸ2’úˆE}˜Z¬¿«"®oCƒëi„<ÛŒi•‚?œïÖw¯ºÛ—·”…%„gËîúÙ'ÝNª?ÀÕÕ³îoÿî uéá¬5àRÅ}û‘H;¾MøµÇß’-µ75jNÇ/²Pc¸Î“ÜV·à+”†~Ë<{5õ)”ñŠïõìã®ßÄ&|‡ÚóÆ0Êôû†OïsMÇ^”.se=©aeð¹B;€Ÿ•ó j€{A ^*X:V¿Á‹ÀàK^ ×°n¦ã»zÒ{ þåUoy, Ðk=às h˜Ò˜ßAÇ1@3Ê\ó Ÿa2ÏsA”œ6Ñþ¹ž²®ýÅÅ2TE IÊc}rðt—FÇyÀ1e!Íù‚¼¡ú€1€ÈþÎù -“&q© g\ Þ/3þtÊ:ûÖ3€,3X®Bl|6bº‡Ö!ø{=Ü÷ÁOˆÂÄ(súI¡{A%.%Ü!“Q,Zñï1UJ^~|=çZI̪*yMòäÛáš0Ûo¿3]…:*Ù÷`µ¾ChAªá™ZÿA@‹Q9N’ éX®ž¡OjÒ.ßÅ&¼‹+-¬qàË7` è `.;r팼x;ß¡ãàWnN­0Çø÷m|€Ï@™‰Õìòê¾×ø5ÉxáC#@FþÐx£æ‰tj§Ð˜ê &ußZPú*†€ ®èèékhüx±K¢Ül® @ ™€fŒ? È;jþ>€gòž_°¨eàpU¾ùJF‹†‚ Ù,Ë?!<;º&´Lö¦Q@ž,çÈñ÷^€ôö3âCHypf)a©qÆÄu–€Ô€\ôÇ!Á¿ "ˆ€é’ùN¤uHAl¹e’‘B„˜Ã©™POÖ€§œ¥%ùU0Ø3íÝ;µqæüƒî{¦ùÕê&ˆà6§@ʳ,‚t$~¾%}jÝäB¯Gˆ塈;Ö\x¸{!Bg@ËûððŒÅ…ˆ7eJàÔöaaKߎoæ@¾™G-FãÀ†~€À»w­úôÕÂõ —jÚW3¯yö¬ŠG§®CÞŸÿ¾wÌs¥<ã;Í®\!@m_PÈÚ÷Ð6ÜFBxqš“z€1 ä-ZúYõœ"Ï(¨l&3{ZN` Æ.À ³ØÄ\3þÂ}ê}^q/¯.òŽŽrî\·¸dc¨š³ ZóÏMËä¸Ç¤/àµ~¼|}*fŸN8œæ¡¦µr |ÕŽÊ“1fp¨üp†ƒ>ÃL Û K Ë#øë¹®’'õÞår÷{øE” kÁݳ7Ë þ‚µ€Ÿ«ÃQï0qÝ'ü¶%‚¶1é{5#~jÑ:êôˆ»b»éUb•±\ÔÝ6ðG—>®údÆÇÙÝÍS‡SPéÈ6æŸÂž4§Á¬ ÀçA}!”7Ë'à Ðûãkʱî¶Ëu„¹‡‡[†a.“€ßI„§$FP;¾‘MøFµß_LŸÿéýpý”–öig.Ð0fïöµP?ý¦œî\ÖvÃîwRçë;§Þ1yÜÑ" Ø»Ôm@? £ñXÈ¡wç×~?¢@´bB@ÿÑÆ±x÷‘ À€¯sÃ3ÞësÆzV󽚡t‚@à{sö|?&}îcQ0= -õ¼€Iw‰EAç>ÁdBÞË%Ë@ü”i(›<ÌEE¨æ~ÙCp@Ñ‘ÇZ(Ì÷,@°©¯–‹þ]ÃŒW\à¹gšÝé(¢Ð©`Úß»¢ÞèèxGÌ pršNNóXÃÛžö÷†Ç´>P-F¡ÜU „‡¼R|­òR:[Ož À  ¸/+NMÛ±ü.ñ«@3œ'->½JOˆŠÏoŽúøñÕ°|½E!ß åLYHºlA,Õ"ã΋ZüýNf{œëSÉ·ß?Î&üqþ´§ß+ `n¡½¶“¤Ñ.î3ôÈŒ××µ SN|t´¼'ÈoÓ‡€N| žcýjýRÓqx º)˜Ä5hˆ÷6^ãîøV¨!V=TK…xÍ{– ªÆ/(O–޹€=eL^ÀôvÄÁLí š¬g׳ç¡5®OØ¢¦‡Uzº h ýXX¼ð6&À×ÊvnTc~ Ú„ €BWPJȦŒ9,§èi¹á‡»îà[ü –1?Öe†XIkf¹¡$B¸§š¼é¬˜í§K5ex‡:V̧®gœìt°Ón}ÂñM͘WJ³¦^›ïíq8Ì8ºcé€í™ô¥$@:´ÙŠçÐ|¤©ƒþHª@%h  e”‚ÿ!ŽF!>e ßóúK37ŒSΤüД’’È-… ò %¿þoʽ¡)/?Ák^õÉ÷y€ç¦KžÊ “ä8òM*ñÞxŒÐ‰ éÞ ë‡òÒ‚³ÀÂÁeö›±a²´² ÔŽwr  ïdK løþq (ŸÔ®SP²“”€.H èµt.KåÞ3a.Ê“…s4ÓÑ–ÍsÀ‡nÖåuM~5Û¾5_½ÎhÐ#ÌçèÕÕÇ= .tÊ3œêj!šœ€9Àã_€Ÿ8Òê³½¨ŽÜ}ÎÂ/ÏÙO^ZÛÖ V:ªØ–×36‹1L@Sˆè©­9„I+}“7}Žä)²pÐÂAàŒq÷ À =é”FSæ˜Ø:€WaéõÍW¡úH8…p©%¾\]³ý®²%8ˆ×‚/Lyu¸K ¢ù»{žkØîepû !c?å X{¿f˜Ð<"$ìYƒaý°"”éK“ÞŽÝ¥$Bc‘*.µÖSŸKx9¥qpDØX²)ÏLÏA¬+;Ò»yµB¨ñ[Š©w„оþy¿R~yÈw¦¢4(~•0@ ~‘ðSD^’i*_8Æï+ÖƒSh>a’Ôúáá½¾»õ±®X–´Ìüþ7¿ÊÚWø|”Пþì¿tËË«¾­ä´Âظíxšð.®´°Æï)¢=Ñ[ŒéUò:ËiO Um½ß•ñnÓ™Æ\°pûú–N V ÷8~ïÂ;šôÕÂè‘xÐ"t× &vÁÌm[Çh×3Êô5· üË%æyÀVËž¹™ ´@Y„ñO:lÏ<óe÷ÉGŸ†–§· †¯À©ù}9Á‰ÏN? ™ÔÛÿ[÷<ƒ*OH‡:©šg<×áUÀ'§d–Ažð7eμ~õ)1<˜Ë x£€«ƒëÜ‹¬”_PœãôöŽ,ð³Å¢AI»ƒ‚ úº5µªÀ¾ß ’%¼9ãÀ½ŽšÿGD³Û`¨Y8¡$`[ùÇZþ–ÕÛ‰*@’Þº,>g} м¥Æ(Á†÷­ŸG‰Cù€ìPWNô^Ð÷T´ñÏ÷k„š>g|´tPN«c:cahK¿9-X >Ý3Ü´f;æ) ie¹¼ÔE]‚ù~©RI}ñ|«os  oó£Ý5|Ðð>–PpH7šµz—R•ÏNÐ1ù8q1|T¬˜ðé$3>O‡é¼ûƒsÖ;ÎÙ›¿ Vi–ö›©mtÛêt5ö-hÑ» ^@6Ð Ðd½ç—h¼Rµa®<óíÔæß#æÝ€bÍ\ê>PŸòî‚yø‹,ÆSš|§X f`©}¾ï ”Ëþ:Ðæmÿ¼€(„ˆ',‚UxÐÓX6¨y„Ÿ±ë ð;œh¶ ‰‹ãÞ >áÕ.ÕQñŒ¦~ÒDO}Ï€î ôuQœPxXŽ‹ÆíÇõ©€Æë@l®Õ®) íBAž§^˜3]¯uÀ?¡¹×0‚QTÓEàÕGÆp‰NäMžõPÎ`ÇDžò¢Æ LÀ“1Õø†ïYÆâ›´B¥U~©¢€á¦,U†¡­r'’מ•–W0<³N%té‚Õc?çû-KÖPßJÄ÷<«Œ¦ÔŽ7hÀ^´«Æš¥9ï¾:µ2ñk®ð °·h vŒ†Ùyïtâƒz¯V¯SŸ4÷ÄsŒ÷Hz(^œ€‹«D¹$þˆ9êKÌÂvØÉ›NwŒ°Pî¼hx© -ÈÏcW l àO/³×äM˜§éAòšºy¦³œ÷üC¼¥vØTsLÙ¬®B©N:z©Gu%=A”¸þe¼ž¸¾or©€,ü‚^ TEÝηîMyä4¶âç ÀÝdÞ½Z/!e€„"ô(l¡6=ð‘1÷SûNL—°÷˜¬3V¯PÁ”Á&öc¶è¥Äðh·.^Å ¢Ã¶·YÊÖJXÇø8hâgcÚnÍÕ+ßv3¼áÛû®šð>δðÆ€‚¹G?Žv˜—íàî˜êïn_—Éž0ÇEo^¿ „çÝ pt˜{Áj/:ì/XS]êýIºº¦Ÿ· йÇä,Ís:Þ-× bÓ9¢ÝK}nÇ ö‡ÚÉÈ 4Nì …æç8xÄ{g¦õù~u줠”ƒ¸GA'?À?ĄГÒf¥½‚ƒ}äR¿x3…Nj‚‚x–¥-ˆ à³9ÍSÀW›ø3  Å½ ×R¤Ú}¯êè0ÇbŒƒ ºìíf¼î6“U·aêÞ oõÉî¾;ÝüKèë€lܰò_±S åG0Ê´1¼˜0„!UHû\¾µIVëC÷»ßÝ…Ö0ÎŽ½nþ–ùx9]V9v¥$V®ÛKîu[ô§\_W|à¹~BàÑïÁ!…=ßÞጰÙÎÑ¢Óö…ZdO>»xÂó¯FÐrýÿ)å’¦’T4uÕB¿EV2¨y¤«à)?znWBæÄ?‡&&ΰ€ïcÊt¦®w/YKh‹ µÉ”NwÜ1•Ò¥'ø2¸‡@ùPØvüšð,i&JË×ã^S'æz×Òßâuž…x˜õàq±:ÞéPúÐ,%+UãÔ£~B9G+€5Mk‚·#ŽSÎjËËK:R C°0f>TmÛñù+éeœžk>f]Ñ ¶æ]‚-ƒšµcêP±É2du9Ó&ïLtšiå0= ©X¼«€ø=hŠ0L¶ýµu$·þô©!é…jôšô;-")ŸÃ"Œß  ”Q“þAê»–êÜOñS{·D–GjN@p¥‹å¸ÀO‡izûŠ n˜»ŽSÕÄt/xA9ôÉÛ2D µîõdvª0ÅA†…:+`»bÖÅýŠ6÷Ð,ÏâK „qø‹ ‚¶ ¢$Jc8ô p!KSZ2Ÿ€: Û.õ£® qòüš@ØÅ 9b¼T%ï+ Ã*šÞÛkC[Ä8Óð KQûðÜûc]BëÇzxzøÿA¡7k@°¾ƒ>®Âx§XL²B”ß^RJWÛOÏ&´O¡qàâ€ÚpDC uy©Sï\uéw¸óðCÙ:õ ãW@MÀó4E^b ¥ÇtÔäNƒ¥éüû{A!;Ãø% ¸ó*le¯t«Svë.èá™üŒ!@UÓµ*%y‘(Oh¡ƒ„âÜ–}«ê2p¨R&›—W]Õkß&¡=(ruÖ!NP€Ï®y°ÍBD~8öëp_—ñIÍw(£š¥|ûCØðD#LÄÙNá¡Ng ˜Þ­z¬÷Ê"bÝþ N~H\€é²¨+òç”yôX]ÂEÚÁÏZxr­ Bð}Þ)éŠKdоÜr—K:RÊM‘rï¯ùYMyã°§ëå“|wá ÑýóYA-—GÿVÝð[å­Ò¦ åÿr›Z³¢,dnCl Úñ~4àý¼iOþ¢h4íJíL½^9ïÞ@—>°ìiîéìý{¼ ¥BÂ鑳šç⪼쭈53¨Bím\ô± ÜÉw§)êý$sÎ1eëi(Ûù¸¦(¤áSϨݬzð„ž]šêÀd2"÷B鎆MÏXþIŸÆÑ5ßktÔ¹¯ºy‹AµŒNYyN‡¾cvÁjçø`‡ÚKÛyÏ0‘Ká6°sbH…w;ö¹»ÓABÆüèE, •¬xØ[‚>8j}`¸T“øbÌ’¯çK<Lùñü —æÀä}bÿy_V÷? =¯NLÐxè#Ül>´Æÿqò{¨…Œ2`5Ðì¸n6§îþ%e€ŽÐ0Ï|´fHaŽUÆ»ÐhލsCþcÊ9b] 3Ýø@è6ïjLp‰Bb•P<éÛÃò§X,ÄNÏ4Q=¸ö;òôÈ÷'ÿ °-”‡÷Xúx¦1Ä7-äÆj¯$òЖó4âXЇz*”€L¸õÌ3.I6§Â¡§Š¾QòcuR%B¹ä»Óà´ÍhÿðÜvx´°SI&ÔŽwq  ïâJ kø3qà©I2˜™§Î}:ð þ¾këïOÁ‡æ¿ÁÛYj::¹êž4ãÇüo:y(Ÿi‚C ·8AÿÛ³tîyÆÔ2ÒÝp:[` PêDµï-vâUîèùí{w‘˜$°ÊaÈX=C}NÇ<«Þò§}ö³çÝ|´òšÆ„-‚÷ Ù§ßÖA0ájà<›0޾GÆÓEÁ‰Zq’ÖP6”TâÁ®güaÅñ|¼FrØdϽ4™[ÇH  M:È#úÔ¡7¿õ v´ãϘžáŸ«):ïÀ€>'øâøÈÈʘ>üv~¾Î{'„ pŠx´ÏŽ:"ß#Ô6+­·uËô@}0ÔâãÁµª²u¥Q}ŽTÂ!ÕôÕÐ)84Ú>Oˆñx„]©WY³áÖkš´À×2pMÉÂnë¨Â™]Êù{Œdb‘MÛŠì7Ûß=R£§åôZ:ÄžåÁ“giò]™®ÂKçxÖÿ)‹ÛŽ÷s  ïçM{Ò8ðrÀŽJ3:B;-ÀAHd©××_†jò_³ìFÑÓ[‡³h¾çŒ•ÞñL¼ì¯/²3õTaâŒùÿ«îâžq|Mÿ;ÌñR§Š­7Ýç_|*èÓmv«@„Ò}Ò“fW©—pãàH½>©wšþ'€¬èŠ #ò:¸4,tÐèæ|:wèÄx¿ZïA‹r»åµð䋪ã€æ~ÍÑl6ÄØzÖ+@;ùÎÙMO¬ü&SÆÞÉ/ãÿŒ÷ïv¬tG?uÞf™\tsñ‡Œ[¨ëÔ8*fi(ähüÁSÇþµjhapŒ<[óΉñýýV‹C6 pí>™ya»°+à˜ºà¶%àŠ©¾òè°iÝ éÆ©jS¬ZoðÞ€—ðÄ“¶ÄÀÉ{ÖY!ÿ€˜ü=׺wÜ] ü±“ÝpX›?v¤]ªÊÕ¾$5hþ #â· :)¬å¦?‰˜væaåÃ<ðm+¿q#úÚ'"êª4†Üåй²šôûgæÓ~/©oÏ<"iÊôô|SØ'/µËGø¿¨&hZÎA¯¦×¶€^žÜŽýnº—_þ.4?€ü»/~Iø€†éO©+±mÑ(õ Ø¢eÆó[máÀÍbéÀ ªÔ1u§ùýó/¾ UStŠØnB¶_|õÛÐÈ1ÁÔ|ùcö‡:×ÚnÑ#ÔŽ”$—&mhõø¤ÛÙBË:a¾;Taà ÍG¨2„à:ÉÍUðœFHë \uG¨²ÃAîÕ+TE aéßKÿNÜPpÔ¡o¿Â<¾íçv•Þ Æ‚çÓ;ʤE]÷ö«—–Àf:¦¨í‘3>Šäϰ3àt°òÏ<‹ïT5ÁÚ1m…¯˜ÈØÖìŒxÿòe¨BÚ.íI~ u Çu7ŧ ŽqNÿÛ‘ëø3K0Úµì¹@vÁÏŒgÊåŒe“]ÊØúŽ9Ù÷¾c{㎵")ð~w½,Tö%–é¸yÆ*ƒÉG_¾bæÌL f˧á8keéÔövZ¢ƒ(~C|Í“º' ¥„NÚ&H 49ŸÏê…ÄÑ¡4æÒ6ÌõüëYɹ&¹ÈW¤ñ(˜§_†‡YZ'?$Gd ¶¼Z¬|¦ÅEKLfÆÀÿ1¾#ÖÐÐ'áÛíøšð5†´ÛÆ?ÒgÙ!:F 8”Ƹêt\Z?Ðqmðøèn^~ªVê¸ðä’•á jbŽY«©»i„ÎNzC§êx9ý2ÂCQ ðbå8LÌY臎ÓEpv#À©6ø¼$?©=ðp9?s5?ÍÒ2lœ¢„N—à‰=¶@?.zÀWØ™Zb˜‡~íxî½Ú›¿`ê¯ÛÞjzÏÞc¯aަ”srº¦§~TPP:2f/ÈèŸT/iùü·äÅ£a‡Åd·go¨@¤µƒ‡Rš¢€ÁŠqí™4­œfrO”[ó¢-ü(hùÊWC C&®ÁàÊ|šÿf£€üic×0˜¨:ß‘u¡ÖZ6óT¡§ VÐÙá&eÀA;ÐEç$’¼v8@Ï9Òq¿*o*B+WYØžXê÷D ŒÌ!OÔþŸZ N‘Öf/Ä­j q›¡,$fRëš„Ó2Ýä΋…/0ù-TP"½yî7mPA?‚…¢m“#`(8[†”ðÇÔͨ_ã@¾ÆvÛ8ðïâ€=N ’4cü˜Ë]š×±þÌé­7Û‡hüj..ê’¹üÑRŸ3ÿ=ñøpôÔw`‡@œÕ ,ø  ÉÚÎÓj¾Î&°{48fÿ“ÖÇÂYDF¡ãþ.T:ã¡ï®vjMYÝNÀ³s0éhít³5­Uä>+¼¶RÇûá.Ð<ç Íì1¥[L q¼ü³“ç7|zoÞòÅ:FçÖ2@YÕæµŒ¸ãØg}I”8¾ h›"BÇ„²ÇH@PàžzÖÐIQB(–u—Ê^˜­88J™Ýà gÞ“ºFú—R¤ä¥ Gúž4„EN@GŸ‰#fÍÐjÆŒ"ÈŠäa–¦]Û!_¢®ÎÜæéó°ÿ§@âu_&¬'’é9‡g^§‘}ïé9Üêa=ê°>Ãud9=úòæ:þ$lxöH¹/ÚÇõåõá}0¬Jòþ$iûLú®¼Lçéñµ"?}äuý_ó{ªóëÏÛýÛhÀÛühw:èt„¡C\¢Tªc’ZþíÍËPÇøü[¼ú¥åø‡Ã¹ÛœêÐ%ò«ÍÔ2¯˜;àß²åéOq³qœ8Z#à!<¸€Î‚)€YHÀÈpVîË;z× Àº½c©Z¦¨ÅÁxúæ^¡ƒqs4Ë©»öQ‡9Ò€¦cquªC½³ o·moÞ8S… sÏócÔ]:_QÒ‘\¸¦xšªJÃïîpZSMRÓÿ^¬æ Sß kÇy‚3cçR†œ¯@@²,ô𒸘þ÷#¼úà^I¾«… ¯/¾ùy­Ù\Ê?Ê(ÜseY)¿dωš¸&14{êj{¢ÙoVH[+¼§3)_©×ú‹".Õ\ñM’ôà$qa+üËg“0Æz(­è4jÉk¨ jñVŽ}¦C{WÊob´«·9Ѐ·ùÑîþM°£©ÃÎQw%9µhõØ¿À—îŸ|`:߯ó‹P_¾c;^©âMpÎ4¾¥ N7§SÜ “²Ô±çœù^þæe¨óÅÅU÷ã?‡^f[Ý»å}ôñ¸^ð:`D9Vø HÝ0åå«u÷ò_ý*Bˆ‹×lœª.èE÷ŸºgŒ½Ï(ƒÚÿG½X¸Ìw̳¯9õ¡š:7O#jMܺ֔«µú<Ó'€[Ázb‹à7÷æáÏ!ÝNÝÃm  =àO.¨CÌßžÓÛ »_½` b¸V<¾-ƒÃ û»P°À>‘_iª=›  qšÝ>Ö”ñzæKÚkñC.ìmØ~]ÄÚqdxD'I¤Ÿ¤!P#" ðM‰F¸˜Í+'¬ ŠùG, y`%zQ˜¨£§ ¹´p¤Õ!{=ÉõÓ—o.Üc9µà„WÜgÇA´XuäçAÀk“À %L~óé…ØÃo“#]_És¯û¸R'O ÷ ~N h™ña\ê”k²/a²Ïk ‘çUIò±Tíxšð>δðÆ Ò‰ÑIŠ13g¬ž1aÇ÷qJr[ÞûûÛîð•fõ>÷ÁÕã öË3Ö~Ÿ_âxæb>ô[šÓš˜ÆÑ„ €;À©N3¬¦8„Í™;¾Pž?»†â7@'iöÄRAÜ9á[V\½¾eèMnHÏîw1±gÝäB îfÃ<  :ƒ öVz*KçjϬðJDذǎ€:(¤.vÌZ¼j]8‘™Óägç@”²â9/͘¾kê£ZŸµD°àíÄÄøæŠ{ 0–å¬æÏ†<¡Ô›î ‚0’ÒþÔd/\ðòЗ…Ë”[¿;ËãX3 43>x+ TYx7Ú¿‚‰eCh Œ'ÀZ9¡‚Ò” bÁãùÅ¢»@`Spxd˜Ë#³‚;á‹m]§‚‰Ó>uP”Zf,Ü›Óáy™Âs4L§?ÞèÌGÁÂÓ#<ÍÛuOSg¬¶—Yj·}Øf!á)§ pXÔáÈc~(ŒãôS-%úPø,a$’÷ãTø›0ëS)jÙ°¾ƒ…ÃR"ãäqjÃK•®iÖu Ôèp  À’Ð8ðí8PZ hg郟’ÄÑ øu°Û2Ö¯ùß…}6xÞsý]Œ'þÐŒåÒaïÕ¸0uÛ¹éìç´2µT-RóI'N\ÍôNùSÈÔ?´¹©^ëx²köìf\Û+:oêÐB:{;UÊlGLg® ¥wV»‹™›kAx>QÛ¶3FYdæ„I<8éR;|¤QÕ&Þ XéŠéí*®{²z> N ”)'`H ¾5μ&€ÆÉÝÉmiñiÈ ÓƒÇæ;UW-Éãu­ ;üY†hódnšQ(2óW¾q@ñ§h‘ç–Ïl¤%˜ÕØÿÐþƬ·i‘jÒ ¯LÇ ùÁ?ë§“'í5Ác]+ˆìž²å[‡–œ6”}&6&4Ipõ†7Ö#•ô9V‘ N€Ü0Jü}ÚÕ Ã½íç·ÖŸJLµKäÏ牒ôó Ë~š5yEÓçý‚!®ÍÓŸIž¤"9Òâ™2ïv´ ˆ/òä¿NޤAÃŒ‡8ãýÆ#àñ-9¤2Q FÈuELO‡6àö¾ØB9ЀGV´‹Æ?ä@:ò>Ø×)|éx =úoo¾ü¿ÿûϪÙ]þ›×Úhéé\N“Vƒ³ó¦Wܺú›'¥k<üæTÀgÜ~³í¾øýW¡.óìúy÷÷ÿ¿†Î1ÏXê÷Ù³‡ #ö¦_o§ŒëÓ1F»\t—Ïž¥S´<£ÉÇÝßþ—×ÝÅ‹/ºÓïï^u«ÿqÏ<ö5à¿íV³‡îÕ/¿Èšó—×WÝ'Ÿ|Üýügÿ9TAü0±K¶Xc~ÿ‚…‹¤YÛ ÅŸ†£–ŠJ€.4PÉ€.£êØ™Ÿ.ø/žaÁ(f<u/.1‡Ó±×!›[†KX;AXQ Ø]=„NKŸ³ñóÙÎ:FxP(˜0w~$2ÑﻒྼYQá…ñø8ÙÅ%€W¼'ÍÐBÛN›ÎœP¨ãÌpK®i{ÚjËzüRMÓ6Èj|É¡‰˜Ô”OýdõãADçÄ6î„ë (¤½ðá¸xñiwÐ^äˆÌ€peLêdO˜ð10‰tLÙ&œÓ”Q¸¥¬®4A4×ì‚,L@¾±¨9œ68ÍCè̱DÀg˧%´=0EóÈæD%ÐuÀäI tDÝõ°= N<ßçš,FV-Þpm ,ƒl<P‡k’å}NhxôTâÛV©‚ü.Œ`8'í m¼ä[º`m±Xd(Lÿ ‡Ô"k"@XöΟ&¼“--°qà Ìx8à–e`Ñä·hõ½ø1ñ¯qòÓéOšµûô×÷ºÓÑzÀ×äNof×hg–¾êÂ>.ôóšÍ^6šû7xüõåM¨¦b  ­ü²Æù'8-z €Z4óÉHÇM—ÓUä&³«8ôX\ë°Z8¿¸3ÆlA;, 38+€¼ææ’Ï%ûÓ?¿|ŽÃš»»%xÒ=jðb³èV7£Í¡…UùŽ Àˆ©zòGK€‹æ {që)ÕŒD¨±µÏË…åqNüRX­2­q8<ïØüÈY”oŠ·ü  “ž&gÌçŒñOÕOÁ5è@^„+Hk¬œñu4C*6póŽ%“Ü,Ó îA$·¿IX@IDATñÍÐmp`øÆÿ¢¹"”­pÄÔ'Ã:¨m*¬H=I—AÖ`nÅVhHõLÝÎh«n£<ò}@~:ÓŠC»ýS_€F›}j 1§[º¶þ$ß a”àá>çþ©†€{;⾩•³ …&vÄ¡ÈVkʼnÑ:”ÀŽ[0ÔÓ]~¹F~꘵éxÜ= }&pˆa¿bv€Yªd˳¢vú¼]{“{§ÅYë@*X«½á·4¿N“"÷‚š[ r…çÄç:x&ƒ­ ÷&q? rÆËrȰڪÆá`7/ŠÀ3ꌳ¥%w³&¤3f`¹Q°|¢!¥>ñÎχÀšžå!­:½æ$ÜóÍaá†ò–/ÇÓkÂrKT哾r©'4×}DâYOáÛÓ?"Pˆ§·<ÏhîIW±f(`Eñí:È&ùI ´Ê?RÄ3-·+ÈùþiO©üŠƒdþå(9¼Ø¿ÓÈ[hÀ[ìh7o8q}å‘–ù¯ý‡×1;uOÿ×7_†Ö¤+vîc;Ò˜ùHb €¦c[5P;/=å³BížžsG¿t~=u Sãc‚_b†IÿÅGaêdºæT§ž9¼ÀüDM¹̉3bU¿ù#5š´&ÓË«+:Lǰ×ìø uäœ/g 7h²WØAÛ_,»—_}Åò´hæ—,M»Ää*XY&â¸DîŒis3"(© œ×éÑÝqÐò šSTc](Í­LÜ3–¹©ÍÍ…pæ,}+Uð:²ÕíåþšåRvX\¤j–û•èpÇ;hý” @ )ª ƒáA°‡ &Ž¿ŸÝPÊ,è¯^fXG>:;*Ⱥ&ÂŒøZIÔtÎçg)dìħʀô K‰«û™¾ÂÁRa‹kç«kòß³#TiŒuféîÐLçc¶ó/AI0ÒBe#'ò…Žis­ "'üLÎò¡Fe5ËU»QÙ±¥X»Ô!æzQ8*y ¶gÛB{ ltCÀ•gµ¼4÷†y&}ã{íi3å·?ØYÃ2Þ ¯¨Byíçu’è“ñ$i•ÉÓ‚B S¥> )ÑÃp8µMø>¦ð°`¡ø®è›õ4ˆÓŽ÷s  ïçM{òä@ÌáÔ[@p\õèÔ§FþÀ˜ü¿†Fã_1æÿû_aò@iÄŽóõ “u¯ñ;mnƒ+4ã/3–ÚêØçR»Îóß1ÕíîaÇÚü·ÝÝ-[Öxš´Õ°:ã]^u?úÑgÝýïÿµû?ÿ;Æ7—ÝýíºûŸÿü[ÊÈ‚>¬ðÀÿë¯ïB %àúÙOV¡qŽâûÕóO»çŸ|JúÛîÅ'‘÷«îöõ§XpP\_~ÎÞÐ)€WŸÕ]#|ö#Æ©¯ñ7øä²ûoÿÛßvϰ"8^?aÿ‡KÜ åÌè|x;t©`¢“ÜhÖ fÙ£;½q~OT'­9sÞŸ_ÿ‡PA_°½^âtE¯ãÅø,X$ð‡¸{ýºûŸ¿ú¿ ð›¶I$ö À” .žðZ ¦$=/÷‰ØÚ¦)yÆtÊëkÆŽ¡®Ð·@XûÑG/2¾lô=ÖÖM Ï‚áÎ턱ô°Ä 1x¡ÐA'ÚÛé@'‚`µ»EÜ!]ÌÿlÕ|†j•0Ú3ư)JÊ…1¤;­˜=B£Xœ&ëûnŽ#©¾æëžÉ_!FË©Ã.:wŽ9á5%) œÅCÈH —ò:ÅïÌR±~øÍúaHA órj &:ISŒœ{d¥EÓçTðS¼ %‚ÿ׎üÈÿ9H¬*ŸoüeŠmÆm¬64žTÚ5 ´„Ͱd]ÀÇË댜—´ÃWS}(ˆc~íx7šðn¾´Ð:ÒAÑé”.6£I³¹œoüZ>Wà¿yõÅ£p £}@£”ªq«ˆmÐ¥š¼5‡ÏíÑÎ Ùª…9Àí{ö§€ú sú-~ ³PÏ’9ãÏž—ÀÅ~ΚõA ósfÁZ§DV¼ÅQͱ֋‹ÚÐÇP=ú0íž½¸ =«™²Uîõót®Z3è (ó }¸» ‚¯ØìÆn{»aSš `³û À˜5=ð„ŽyŽ@mÔ;½M1±Û¡ûŽÈá&Ú)7Åw!€›ßÄ@пa®S ¯«ù_â·p˜.yÎôɀͨ[Ýa-ahıúýæ.ÔP¢Ñ°ÕœÍƒ²eMž["çùK`3L±jHºpEàš2âœ8WÃÄAY.ñK Viþ½Àöq_†3߆iêâŒB[ðzB9â;!åIÿáIA S,mG´WÍòжž@ǜփ!3!°‡Ä »B†fÚ¾l|d‚»ßQ@›wÄÕj ‚¬wJ’g8mVÚ;±|É“°Ç“{ØYgÒ1%uü¢dÛû½¯«ŒaE¤òÇ!‘J^!/qµ HnÜLÛ´ ¼ö=ò0j>¦}¢ýÇ€öæß,Ǿ™6à›yÔbüUsàIcçBšNUÆñþÌÙGu~ÿÍxÃ8¿›ö8¯_Sÿ†ñrWÙ;Ð) ÄY>€}'!ÉkO72då5,vac:;wÓ‹6£w•Ýšñ5ûÚ‘3O3sL›¼£¼¦ý¨ˆ$(ìdƒ Æ®õò÷úÀ{>È[Ðù0«µq3Í3;UN dyHO3ª§±ÃÍJhrZ2V+,[œºÅÕ˜iŽX®Ð_Ùup‹³ß/ÿšfêÝk‹¢Ê¥úþÅ]mLïíLãƒÊË’òP$w%¤,¡%á9/?ž>tXOòVÓMüb¡—u˜®à,õæZ·Â.pm ‘)€<›Áo—æcX0ìbÝ—ÑÊ1ç3à}@`§Uîé@ý' ¾`—Vûï2ûÀöÒÞí€;üF°PP D-¶gÐx©àI…ä{ Žjè#ø&О^G»ç[­ïVõ›Êç#˜PTzÈAÿ<ò3~ðŽU(! “–ãþ}sðÐk~B¿n˜§ ê‘h\ÓÞÖÑp M¦MãX\OÃ-ßðœÛ§²@¥9ÄÍ£U žjõ¡‡©ñ§ !ô ¨TM±ïâ@ÞÅ•öဠh¥·ªkMû†éä·ìo]6êT¾cþww7¡4M»Á(°Ð}Ùéää ”§3X}A;™_8&ÏØ¯4cº æ•Ѭí¨Ü¾WÀ(Ó9º>ü&ÎcóKvÔYÏüî™ 7aeÁ;¦òÝßsïT>§â$HÚçŽ]ý€üæŒ3«uÇSÎØµ â‰í~,Ö×­lhÓ®á eº#m :o÷ë_þ6;N™¦v`¥¾‡9Ó]±w]ØhÃò¸Z4 ˆ}ºü²^ÙŃ6ÎßÓeôÖwÎþž8;@D8` yØ~ê¢J»Ó æÞuwq½E˃gð}ôLD¨n^óô‚:J£!’Ëú&;Â,ŽPiй~yMž¾«)^àçðÙg˜“áµ++^0üñüųPWà;.õ `ûbø|€ºf÷óÐ Ðþ MÀ1E"Y;-θâ•pïRLJ šÂ 5ÉëÃa}aŸ¨~…!g$PÏœø¸¡[ßfA$Ó…_Yßk¾Y2«³ÐîSqÑ5WÄᯔ;ÊA¡ôHሇWMRO…ÿ{¨“y˜ÿSXPF{|Ž&ŸoÞ’:ѰNÁbåäé5ᆕõJ÷åË£¼YWþ¾õˆ—H:ò•ãÿ‚ÿ”Y)®£àØ`ò÷?LÌbK}Yޤخžr  O¹Ñ®PP³Ò“?à€—Zýë—Ìë‡î\ù_ýê„ ”îž÷Õ«—¡™×O‡»PÕþíÐù‘æc¨=U)®Hðâúºûø§?À®Ó9¹–üxÉvµÐ5c½nº3_b^g>¾` èòãÏ—¾ê./.xïªûâKÊ؉޼ºë~ñË_„îoŸÎIÿ'ÿ)4žõ˜E³ç€‰€..0oÿ‹ÏCõجïpò{zp˜øŠšgyç—¿üWr¢³u8âjÑýó¯~êÞ³ËIwõ3Æ`¡:­¹Î½{d½{•/O˜»Ç> ÙžpêÓ²Aw\ÓBho€¢Ã½85J#·Ù½ýòóÐ#À·ß­ºËŸ|ÞÍ>& gÁðËç=æm€ÑlìJ".‡BF¨àÏÖÉŸ¿d˜e##p-§Ý'?zºXàÀ¢Gÿß~:GóŸ1ôpµü,t„Ö>Âtßq¬„ò¹ðìXç)ŸÐ›k¤‹/iéàÞ Þm˜Æ xgX ÊaÍqÚæ™i ´¥Óú:¸€'3,²¸€H1.q|`ÌÀ M¡ópwËP@ ©úX¸Išqt u†O.;5"”½‡æ@ ¨)‘ø&ÀÁÕ]¥±(D Hj:ª÷)5iA§HÛ­|Çþt°±*-éT­›o_¡Eä©÷æy`©‡3&Œ/51ÞÐêú{CúðݬŒH‚ÿAõúÅÇŒýÄùœá­Oîz†ÕFÇR†Züÿè¤þõJ¤ý>å@žr£]ÿ€8`—L'm¿4~ÃYÓáî4ñ£qÞß3žžµû_ÓÉë Àæ=8J5­«½¹#\«èôâH¦æm'h?öxÒMz ÀòÊ)|šÞwtö:³Õ:ŽÓ—‰XìTh@ƒ¿¸¼Ä‘OÁ`F¹£pŸî‰àŽò Íޱ.,q„r¥? ”ô,uOÊjgïRÄ;6¸ðw[Àð\îDúó™qk„ÃîîXäšEWîÉÿ¼E gœUŸ„ç‹î“éÇ¡S<ñµ \¯Ðr©(Žv ‹ÎÈ -À;ù(t¹iŽàçY Øhƒõ–Í”œ‹OðPë&KVJ\@R–ŒÇú)õ†úNª¹'_„!µR„ŸPÝ՚͆ð!pë`!g Ð^_#Ø ´,«þbÑ}úÙÔ]ŸSá³Ð‘S.ñ ˜Æ£ ø(8ïfÜa)q-ÖDØ z¤{ø§e÷ ÚVPÒ'p˜,a‹¸´¡íž)m”Ñ’g¿ýl'­_G?Ñ•6Eðˆ€¶ËGÁ0PhP4 ïÑ:k®©{ÄU£7½ÄÞ‘Ú\>ãÒ³,”Ë{Âóž4(Ëÿ©”«<—W~¯¾²‡—zo’¶°Mx˜ãñ‚;óQXóM’õôÿô¿ýafN…Žù¿—é€ðx°Ô›I¢ý|MøCÚí_7ìl=Ôx6ÍßRO5ü,ì#H¢Ùg̪ټö©±öŒ·ó~ ªé›Ò5¥Ãq¥7Ú^Jki<´¡ 1íêé ´T·Öÿ¦ho~H6š±Ã œe^†™bFç¼bS µÏ=¾Ëþ:lçHôLíxµNPV}èëÓ Çÿá -ßÁkXÛÀ¾¶¯M:x—,v†ƒ‡¦úÕ=š? 3Ý35Žqjë§%E‡DA!Ý; XŽ(_=M¢&" zô’‘—.âÝø,ãÞYœšÀG¨ŸS– 6í)Ãb¡ Œ‰¾ZŠ–Úg“ÅÈü@c¸àbAº½ê€¦ÿ „7§÷u*¤]7€òX/ šõ ¨˜fú ë¸k"WÔ‹©}ð¿ÖU = ¥~¸.¾’íïTLÓve¾h´ÐL_ÙÑŽö“_¶w$¢í\«@³¿ü*(ß@ P‘˜ü#_™¹Á9‰ÉÞëJÓ ˜äC@Ø`I+jh¼ýón•yb! TZ=­–KSè'TÅýH5"((Oèì*õPh¾UÛT¹HDêÑG«›wüÊ[ÿe?$Í~µ~…„:ßñZ zÂ&ÑC é:ÕËC`˜0Öît¤T”Ò«ÿÌ»öjÑLbúUG œÐÒ9¦°§@«3™@kOk¯“‡ýªú«—¯-g,X%4ÛñÁåy÷™µ°f®¹u¤ÃeZ—4 mña¸ý’°€[‹u{pÕBLñŽ5«e’FM`(ƒc­™µZ­U˦ek°¼š3µí sú+Àò‚™mmËÑN\c #?èÚ£õIÓyó¯­_‹ÀÖAs¨À–%zåa X€ä7…NÍ6/®5«˜àH";ý—¢bÍÒtŒ°¶Ákx® «·¸&ñ½@Œ\¸…§+"N0·ï #çÉ™á,48¬²Dð‚¢ð´˜-p23ÐÌÕ'ÌԘц'À|F;:rÊr»Öa†S¡C9K¶oÎRÀæÁ30– „dâóGÝã\ ðGH¥l5öOa{ €C%uÚμ£%:ñ 0 U§A`=奠ÜÙÔÐt¤k«„6Àh¦%5ÜK£CŸ÷ü£Q ¬SAÔk_‹Ï€¿Õg‚4¶N5=âÀš\KÐô¿˜+ÄÖµŸL„/“î­E ÃMX£¨2ïŸ!- Ú%¨ñb¾»áíF¿Î&|#íþ¯‡ôRåMOÇH‡(>ܾ àcîÿíoÿ_4}ÇqGóÿòóß… øÆ¿a@j:ôÓeUý£cÄ&€H(ÐÅÕu÷Ó¿ûy¨ÏÎ÷ù tx :¢É8,½Ø–Îúþî5Óî²æü=SøÃu×têòŠí{í•ÇŒ[»\í/~ñËP;à8’™F&°2nËć;‡EAÖ]¿ú½6.ŽXî °ê÷ Ö¿ã Aä3ußzh´Ox6ÔgxË›› §ºC¥Ëºòýÿæy÷Ùß¼È6Æ*ÂÌðãÇê mòõÏ0‚Bü³ÌjÁ,çM Ø±×üý´K +dz¶øuuøéÏŸ3×0ÅÈ2Я®’€@àÛÌ"9ä7Ál9~zÄô|{‹€1űªÃ¤C"{Ê€f6rá¥Kwr v#¥Ð€4ÀéA"(½¾þ„ê"`öŸ\á3pþ¤›áÓáÌ1Û>_­¾d•>FÝ5ÿéÏ~’©—š®L¦LǔҜQpzIÝ5ù#Ìñ·EXÛ3T£ù_áõ€5J'@…XçÐY¾9>jÖ ëÎ) Ða‰Þ‚ePÖ&Tʸà^ h+4ÆJsqÂ,:Yap~ŸàÈ>æuØÌ¡ Tk'H½×2u8²¨‘|å…5i}ñšo’ýôQÑ ³b-©o8ÛáŠa©ER¸ÄÑ2Eä>þPqœ ¤IÇÑ%N²—8jz2¥tŠàšN7ô%ÿÚñ~4àý¼iO¾ç OKÏ%˜E;BÃÙôj÷:T­Ððïo_¡IãˆG˜Sún^ªcŸÿjÍ:ÿÐhüjþhqô|Õ¹ÐÉh~ŒiŸñû)ãôË+ŠÕúŒÑtÝÍØÝÏ…€ì@k¼tcŒŽ !@3~Lùjáö®Õó.r„íö%¶£3¿}©°B<ñؽ.> µgv˜Í;Ö·w?ú5Ö‹{4~©Ï‘g+,RÊÙýþ!Ôò¤Z˜Ó¥ö›òOç4à0å5ts®cà!xråŽKÀ™Ž >³•q(±bþuô (2=KM¹>¥y‡ªo×€ç}•m‚ÓÜr‰°^“®K_ \=xÀ\Æ–,D„U=B‰ ±ƒX)³æÂ„yüsèDcg‹‚—ë¨ù;+À‘•â À¹RÅ…ç âÜ®p¡‚‰k°,A¨ëÌÇ8ìÍŸÓÔ| +J7Ã@¹ÄÉž;E-ÓÑàç`x†hÍ´üxF]ñ·XÃTä…`ä¬Àe›âéYžþe%QÍVƒ¯¡ÚÀuʧBÁ Œñ{ˆ`°.Œ–SyåaÛ’J®M/è.õ3¸×ø‡k?OY4 ¿™Ò ¿Ï´¥C ®|¨UD Éà_±ÈÕ.üÝT}J{ê )U`ä%‚žÙ{?±=i{©Üu¸ÁÿÙÌÉ”û±³}N‡Þ‹’"äŸyµãÝhÀ»ùÒBÿ8@d*¨ Žjõ:úéH'à;¾FÃÞpæ¦> nÙëTÀšS¨Á‹ìA¦c±sá̘#@C¢uxm'$:ÙY¡©9¿>õÈO:K;[¡Å2¥s'Ž>ž:t9>^ÐŽ•{ÚÉ{Ú¡ÒÁ[f—ëà§xÁOæôÆlÎc¯s1åÓ—«-:Þ¿C«uxáÈXºÚ¿Tð×?@MSZú !xÆO-¯- +Bõ/†x«—1mêíg<½ êèøoœî¬}9¸™ €µm¬¦Z+×â`¥oê ‰¶O?µÎ.8ä³±ÂAuB‚•z•Ý)~n$xLàWÚŒá§Ù &‡YÜóîÍÔ©Œntä’·¶üŽçR5æ a“ŽÕø²$Z= ?BÓw†Äv8»ò {æš¾åRà‰…r‘†×†¤–a%ðFjΑ ¶·‹¥2ÜóépZÏžIfC>6‰Eôõܤê»ÉVÅ€¯‡BòQ6+2kx’áÛØl£J¤¤žöa„ž‹˾’w 4aÌþ ~jüñÉ&ÌáŸgS,_âu ¥ÌëC2Z$ ûªäÖòÄ¿’çI)·¼ËwEG±.­ߊMøVlj‘¾?°÷à çØtæÜtð»g¿T“ÿ+ú­îY:K€Þðjl{€(ÅèÕÙ¦N?¾držýã8$óÆO€ÁA`£:Ò#—“Tzætbnó;èé wÌsß2ì°e>þ³·– û÷L¥êi„‘ʪ– À<û¦ƒ 3úu^ÂZ F;×ÃŸŽžúo´^0£áàê„h'LË"luáÕOVIû>“<*ŸŸŸT9cÒ¹ÑÎÕŽ0GÐÀ‡ž+Ö`‚Œri{©Ýº|RŠÎ?ìÁ¡&$8¹¼®žèj²G†fòœaãÌFYU¸¼¨§"¼©+8¨Mò>‚›¼RŸÍ%¤¸@µ!›ö ÕZªí+ ¹÷‚Ã.× ~0%‹p÷6p•CJÅ{NIÓ"Ì,„:‡üJV‡K| lÒô6® A|DMÂ]RÙÕ‹Ëš¶uªÜaΧ©RGtåÐH>.ù+B Ô»lb"Î…ðŠÊŒP‹çXƒ]úxèƒ1Ó‚S)‡A\ÆØo(üç½Z¤É¼H–¤Çhãù^d‡KÛo"ïQ’1¨N‹7\ÓfòV‘Ô̧LzäF­î UX1²w˜"Ï-‘S!l22 ÷m˜1Œ4ìߢÇö1=Yci®óãÞ ^kDrQ!/²¸–<‰ˆõ©òå¶ïå@ÞËšöàûÇA§z,5~Áõå—¬mÉŸyý¿ýõ/j^?À¹&üóßÿ:´€Ä¼4>NÓþ”5ð3fm‡©Ç1k»KkaæÙ³”îDó#vh‘ìG¿v7eì~zÆ>ú”ó'8DZPþ/>2PðRP¹¸)Àr»áû[ š5àqø»ÿ á ªpcÿýì^^ËOœü.ÎÝ'ÿaèdÈOذèòÇ~§Ø9VÍðkŒXHÉ:¸¶€óìÕÕúøp…˜Â–Àèþoø<Ö”Åñé5õû/±1ì0š»g'Ï(‹ßŽ›òAÌ=>RµnjC!¥À)Ϻ»íç¡ 46`ˆ¤B>šÀ÷Ók$ìºKHØ”=˜‚¹@8°(1üTd‘Ç´'S/'Ú§C ó\é¢/^áÖaŒ »-¹wÄ‘!÷[˜±sö]àzO寀¢ôèÔkƒP{X+ ¿q„âÆC¶¥VëëÍ«ÌkU}içšçoãçÞ*ˆpÍw@1º{(¤Zz6s_Þð9Óq~;ÖúÍèPzu‰ðDææ;C0zŽ€Tég³Õ"£´9ˆÿCù>S\ÊéÿxŇ»äÿÖ‚õ#Îü/ØÜŠñÿ1IÅo³GJMÂíx/šð^Ö´ßOÐÓØÛähž;´_7ñ‰¹Ÿ…oî_¿B¸©?à/iÓìÄ=AíËÉ pðí±ìXœö¥¶¡pàb1:AË´ ðO°°¨tîé¾èà-™öÀ8þ£@‹DÒja‚¯­–!*Y´(:[„µ´*:Q,ªLcWããdé;®é‰Ÿ-‰™Ñàø¿þé¼I“TÓ´–‡ZE5À¬,[d€UÛò D0É:Ña§·3,¬:_.ÏñKÐ$® 3›C/úРv—˜¡uhtðý°â9 ¡ÀäN{Sf¨1#K1þφ@¬ô‹a9ˆ Wj^¤ E¢"m¬Ö,Ÿ²†¾[“w8b¨„eµMlMþZhœ vªWúšqéhÓhÇ1[‡ æ€Ð‚Yÿȼ³€ÀÇ€‚“úZd¤#‡NðèŸ!™Ÿù;œ£Å"N”¾¯UjÓ¥ŽvòqÏ{á+åŸÒ~sü~wúsxc/lÎhÎ#–_>àßápÄò üÖÇ­š‡µ´Œ¬£SþÔ°LLÍH}3Da»r"+öõ±­ V+/Oï9j¼¿¶ ).²uB`ÆÉR­¡4{þO9íÏoՔݱÑé›sÈ6rì¾P€-ÀáL0´k¥ïÇXv B9y×ïÄÿŠ|NiC?ÒG @>T&7slÇ7q  ßÄ¡öüç@uRS{“jvvÜÛ!€,åëø>@«§¿ZxÆüõ@]ÑôŸ©ttÆ™âGGh_h'Ÿ±{«^ë#_¯adE7=иwªœ+ùé‘­–¥6³Çº§gÜk’çþ„Š$¦#,ÀrXÆšh‡S6Ù%¨u©“ŽÛºùg˜¼õµÌvÔúŒ™pBcµ£ýó©¡Eë:Z@GY“ŠBåRý= Á \a—,ƒ­~Gø\6ÿâ-ÉÄ©|(@AæSu%Zž÷ígf~;¾É ¨©€$ÐÁµP˜9ÂÍNć@ÀÙ %(Té‡Ú‘Rjæ½GÝå2ØWßnÏô—IP}…†äï}ªõºÒRåÞw8ê;€‡"%²×:ú©àçäÚ:ù𧱂•ޤf§…Ç!€xý{­@à0@nÓEtÂÊA­+ϤÅÿ<$õÕÚv}¡adý“ƒ×‰Ù~¾-šðm9Õâ}€ Ã±ç¡;àÑ{ïœãüWLÃr Y©€xý3åΩuzÝoƒ_#8÷<µövLðüÐaÑÝüjµúh²UÓ˜d©_5\âààR³é(ýü7h@¾*phÖ¿}jç/Nïèì¤Gò¿}uÛmXÕ/ÓôBÔÈfvþéÛˆdšö¾Õ»&]µt;¼ Öœt3†N<Ë|ÒD~ðPíØ®M4p—Ž˜®S„àÈo]æÞ…‹zBGL^ñê&ŽÑÂãIëcç«C,¯àšÿóÛ™ ÀJ>¡:¬ÐüÖ7¡Z.¶n¾ZÒh7´aÇ„•±4®\áåÉÒÂŽùÏ0™ÇžAkÚ/þ‘æxOa‚ð iX@úÑ‚€§€Ãi¡E)ãáüÇ”Í<åå: ¨aŸ.Ào¿ËBû— 2@|¸cJ7Êo½ÆÔEÁêÄÂØE†Œˆ~â{ØöG —ý³yÒqÓ ~ Œ$z q©ã÷{¾½ñ‰™#RDƒ ³vXG&|ËY£AšBÂÀ¿¬ÜK9ÊÑ쮂2„ŸŒU@'r§-ýV{€÷;².VÐúy‡røÉåªü8ÜÕawi„ž+ óD(gsLú.ž”¼‰wÉ &gûÌø¹ð¡ ÊÎ ‡¹z’wÖÜa ×Èð{S¨•zè@ªÁÿ?:„:+DÙÁâg}¶ã[q  ߊM-Ò‡ÈhÙÎiW æt騛W¿ðï˜cÿ/ÿÏÿ*ÈjêÿÝo?Íô;4ä[6»qi_ûÈSüf§e¨c­n-{Åj3‹«rôa/°ÐÔÞÓñðV:øÁ©ï@Ô´ï?®e¿úê«PË—Þ¶ŸsïÒ¶kvÚûý¯~ªv?GyÆ”ºL£“ŒöGÙ\¨¼¹ò äퟛÃ85,cötƒ@Žp’N[áU;Ú¤í§`€ìS-¯~:X;[:R /ìHµ#ª·fnÒ© 2&+ýò÷/»ÿãÿ?Y‡ý—,¥»`úã¢ûÙßÿ(Ts¯ë l¶7¡@ó/þ0fOÞKÆû?ûÉÇÝ5tÁBBϞϺ¿ûW¬éÎæEšÛ£;Іsõ¡óûЀ‚‚8$!‚rºŽ¾õP‹f? *XÈó ¡bÄÎÆ)ö ?¸–þú† ‰–9V‡ÍÍ–†Wß:Äó߃ª²†Ûô¤O ã˜¶Ö Îu\h´g+eèyyŸ±÷‡è½<ƒó3gz(Ù˜ŸmÈ´Gø,V§WÓ‡PÝ'8^ì^…ºí¯í|Æ‚%õÛ×ZÁ¡Nû³l~‹¸FmD)ñQr ð“_:4`g{jŠaIõ™ lL¹øŒCÅ`²`§h„âã]bj&ðïSNEQ9$P«ÝK»NZ1m…3¿‘ù/ ¨-¦cæÂahË« Z‡‚ƒ_0kjðÞCMîØ¸ÄitÁÿW­GZ¡Úñí9ЀoÏ«óƒâ½’aiCšÚÑæõ¨gÌ_À_±qÊ-cþw,°³eÂwöºg'=i4RT¥5»fWûyÕ'M•ªvxz^kêÏ‚?ÿؽá{ÀŽéÄ3Žqjú×’poúôÊšøÖ¯ïß *ø$P`:m´9¼ô¤ #€§Ó‰ „Q»u-ý˜û¯Ì릧µ{K'' qòvÁƒ  ? v«ªxö¸éfymè#š‡þôB€ÔØ.”3¶ŽÉU  ®0Eªf¸]ïXhèŽ}kÆrkEÀ‹KíbJØínyÍ×ú–7_²—ÔñÜã³Ë¬½¯G½sÀhuWìÎ÷ì9–ú®Ov:&9S$MçP4ä²òN¹“W0F·<5i-þ)ðPXêÂ;ò‚ßXàÁ0,G, µªÁºG7Ò> ú"œ|£Œ‘… áZ¹êvXLy½ïÐ{67b ×ÔÍÿ825s“˜É2 4> úà8êµ0ÑO¬Ø8Ñã¼§IùÒæ½UöN)JªÊ=ý̪Ö~ÜÜKnÉÊ…VÉ{ !cês¢é—u¦1œÜGà^j>ˤ%5 yâ6Êù¹ÉrÍR³PP#AD`âÞåõšÀÞÿG0Òç%˜&|#OËã1|FÞ`u†ÈËðáYÅl¿ß†Mø6\jq> TO`G¥f<,‘*ÕàÒ½…ÆüÞ'Àzº2Û ÔUù6‚3@Ÿ“N!ÂñG;µh¹fÌšñ{ÍÝ@ ¦n´o:Ð̧¦Ï²ƒ×+ÕÜ›k¨ézmGmgè¶Sþè c–%Ü9Àa§›—tŒeËI¿W6Wñâ¶œ_o‰ôà ïüi2õ¯—ž¼axváÉóÉÓ\>fÀÅÈ“8ƒ?¯S&뉥ÃÕú#SÔœj¨¹»L·‡ˆJOÉûœé]ÄG/pO€B³.z4RÒs.~™û‡÷ÚBƒ8G’2lÌÔË0U:áïÔsÍÈæ¡µÀwl#Á™”© ”ó¬ÏŒ¡kS¦±ÍÿIždµÌ(däi þ0“¶ùÛÞžòKáBçÅÓÿÇÞ{hK’险ŕU]­Ðr–Ë={øþﱇg9$†ƒ™ÝhQêÊÔÉïû-<ï­V¨nÔÄ £*®Ex¸4÷43777'QÀP ‡,ŸŒ™ºkÌÉ(¢nŒiûœ;¸ Ëò¶Y)†gašÉ'5¶UÔå&¿uTa-žùæm|ÿXTÆv÷­šêïîQZ¥þ‹L Å«cAÜ*l¹Æ_€‚w~+Æ÷{‹gr/¡B–ßàû  ,¹“¡H%L(@FÐHù&èn㯷ÆÀQxkT#þå1à T "DÙÍÔꎽüBgÿúµáq¬Zö#Ü\sÜíË×åmmiw: ¢_î]ó†€@ib %‚âô!Ä7¯P«ºÍO?c,½Ëѳsfw( ùÉø¥GnU šìCgn£ë(´Þ÷v÷'lTû÷×ãÞÝ«—0Âi—; >ÌK¬uûF›¥€Njd"¹­_GI‰ïUl…:åÅL äO×&wFÔ¢¶Œ\6ÎQ ¦5~ˆj÷l˜—y冀g6cK÷”ûô¼Ïìöž (ÁÌÖ[mÂ51³yÃ[.Á‰ÏÎp‹Úÿ„mžÈ7™¹¬â.vePÆvÇ6GÝâ2F #­+Ä6è¡zäD5ÁuÈ)¸¬^ qóR3tuñ,§s Ž#ê©"q·bÔ¸Ö{Ø£…p½¿ÆàjGœ,Xi³žFO\Ë7)ãá€Nò *­ã@ÃLw h¸iÔòjÇmp'‡ûöµ£`TFØ)­kYØÎʰ`{­ò¬áüi‚ž¿ñŸ÷Dâ»ñR%`;A £jx"”òî°E^ 4ÛVßÖ<ë!vX1gàÖ¯Ý.)y‰[G¤ÑÊÑU‚+¿î+©òTõ¯ïƧËRŸ<Çþ6n¼J>’ ,©J3Ññz[ €·ÅÔ1Þ_i˜¤Îr„1òƒùö¯¿ Ó›+Týÿø›ÿ˜%€ÛEï³Ï¿`ÛŸ¾ð™­B]îÙ·,”e_1Î{„1¬S…‹Ïýë·y,Ø8ïý<¦>Dý?{†ë]Š…Yk¨_€ÚÓ]3¼ËžçîLsŽ[Ø?º tfîÔY¨à«/Ý£DýéZ2Ūqð{+Sa5Ì;ít&#Q—"fÐ/-‚£0t‰;ä0ÿ;ÒÉs<ÊÀ*ˆ80´ÇB€ðªEnøOüj?4B^ëì2þ>Ãô=‰ãtß›ôþþÿÙ‡q—ùì˜:Sp[²Üòõç£@;çPœ>~èö5½®v,°6¯ŠÇñ¿›Þë@Õÿx˜G5nwØ_éÔå%t¥Mpk ñâÍPaŽÀ­ •zïÑS»¤2g½xî4Ü{ ƒß¡þ_j £›Î8ê)QȘýê}8Æ—€Ð™©»¨à36Är€ðõJQ©1‰«¢›pÂg´ ,9-¯ÙýX[Õ:픀¶gËôx0f¹è1¹`¥ ë¯X¸À£º!åÛóyG´‘!ƒPîhgèow¡Ä†¤ºä¡~d£¡6’É柣‹yn.»‘J0øº~ïr™ pØt«ciÑlƒyEº5‘à\~ïÎö-CAD›aB€üÄòHîüÔ&Ôok‚¯‰)Ë^þ6ÚÍyÕí7#Çëû1p¾7Ç/ÿ‡a@¶-s=¹Tþzó»Ê:ºô}ýêUïùó¯õëÅõËW:#q³ÖÂØvA­tÝ»÷à—0”"±}™¿Æç΀¥–ÛP0Õ›#¼n0ŠMQyC™MO!Hñ¯^„F¢6D8Ðeí àò}ŒÜÎ8ý "©ÁÞæ–³ä ŽòÕ°mÆf÷1LÉe¨8a0wgaTÁÙç?~œ¡p/¹DÕ™—ŒÞ2C%ýâYáE¹ ¨ÿ%ºUãû ¡¤ÂÃ%7Có´¯X¿<%è 5É;Gà9aíÿ”£yÏ/qîòFH8;;%Ô»+by gM{yÇ7˜àã¿3„¡ø±Xgú{¹ ßGpó9.hg «#N„:—I5Í’g#ÕÈ<´Ù¶7U‡aAñdºo¥ ?Ã,ͺiV^#ku¯½*híR¢ªûî%A}ì¸ õ<¼ðjÿì7ð¶ES¥qž»Gdœ²öb $R ƒgûŒÒÙrz‡Ê'½y´!wº`…oRòlÿR‡ºÍ ®Ô•?D 6TÅS³)¨Æø¨<]cà_㢕áÙxÕMài°FoWOÚQÕÎà²Uù5vB†u©/ùœDŽ ë P(ˆÓqþÆJpw$>¤{#}—Í|?ŽÀ÷ãæøåÿ ÔO: ¦ª?̵öôÃHo]çÇß}Öÿ1ðs{ßÊ=øL/¤ïÙËÃq昳Ãer.ŸgœÐþ2̦^ÎNd¸`ÊËqª|Ó¬Œ"×]úf¬Ä Á“êŒ&œ ’¥×½ÉÔ2ôl©c¶µÆÈOˆ$ƒÕ¹Æ…”Ë·*“¼kÂZ„¬$är¯FÄ;z˜žñùO]¤~t™¡¯úøï!R+ ÁÇ®Y¼K”sƒ“ Œ^Õýd.dŒ@5Âk¨eÖ ‰ç={Áe° j̬m£Õý¡—A÷÷ƒzÚoÆÌÕH`§àÔtßÍ€‹SÃ@(»©šµ«€{r}$O=Ü2ÊŒPÔÁ|mõ÷åpŽ5ætÆÜGðR{1B«>h‘-£0gÒ¶Ãz’²RB¢Èü÷¨*~þ"Àf uñb¥Ï³; RѬA“ §ý2¸briÛ£ü­†e¶Ëº˜‡õuFØe+’k[ñc_úÍþ‰ÚáÊ8é¡/¦í:?ãUT.sàÊwê]äpY·„wqeÅ„ÜMxøjvÕ>ÿvE¿+¥)ÚÍãñzk €·FÕ1âÿ~ 0c’*ñãv†¬%ÿµ¾ü™Ý·m~_¿x‘m~ zõsî¦ÿÜ®jUÇž¢ŽžhØ%}pK›\ ¨«P]÷ž\œæ¸Ëȵ~ „É÷ÂE¹ †É©˜ÕgæNùU_é,Ë™5T*õ’‚Š.zQ]«Òeæ¢Û†_\ˆ™03K#“/wÍÈ)[JhuÈÕ0¾Ì€hŸíAÄàn_+î7_;úúè£yWšc˜æƒÀë2FMÔl_°N T¶Gg=zý›c¹ï­ÐÃí\H¸%Ø/,áÇYP<ùÁ\Ü`p+×8TïËÇeü÷Ù¹‚P¥q¡B„ÌQEK ŠvS¹Üi‹u´Ïl KÁ‹-QØ(­€ü”îŒz98im²¡D•O©FwûæcQÃF”;R;@Í- :@Úg±¨i„fc›·¸î Ó²< ¢ 1l³2æ•@¿©a¨†'úa̪ƤÀ£éÈ<ùœøaô„‰Zn£;dŠ–‘ 8Î`2©3$¬låɺEµÃ¬s“†oäR˜µ}æ¿ ‡ªUÎ5ÞýV‘&ôº×<4@"˜(QqìƒÄí$_âͧeîx=ܤoÂqeu(­Š8þýA €DÏñã_2ýM·Ïß™¿küÿã7ÿ¨Êß÷ßþÓ?º¯ß+}³sÖpaNí=;;GÝ«ŠYÕý¬wòôý@°–þô½@×ôá/øbgf*]‚P«IxñP£½¼ãX(ïpínp+¼A­½úP†qÝSŸôó©ÇÁ~Ø›°>®Ÿ|×›%x9“:5†aæ´:Ê—v¯]î¦ BHmÕ$„üñ£BÖ>Ýç.±”,º¶]äÑJóߨÂF¾tDµÍ´LõpÉ}“ŠW.–‚k>a²~H¤agì2‚ùÏPù?ûù¤÷Á'Ø(œ@˜O¾î-aðjÆÝ5sðêœz„!ràŽ…îá2kpõ ÇMl,úøøn®šF¸Ñ=áüúùÉtÔ¢Øg(i¨c*Xxˆžmv/9ëëaàMU;þùÝ9^]·͢X†7 î_÷ðîW/qåÛh†-Ɖ»KÏ; l‹Œ¾ŠÒ${”q܃kz‚<Á™j{ ”Ù»ŒÓçP£˜ü1^6÷ø¸Ã¨‘4¶gŒ‘¤PÙÒ[@4"ÁÏ@…¾ô‰íÔ¨vÁ-šzŽ` âžù•6.2–×Å:èhA=ˆ‰PZé#Ñiì‚KñBzm‚F'¾ÿýãŒ_~SÆ_N4äÝdMébû×t›¦ËP)˜¿‡ìêòˆÑþ'LA¹RF•ÝU#‚¶ÙÛWj¶¨S cIÜÒvYÁcà(ü0~Ž_ÿb(É^! YØ»•ïêêUï%Ü83¿fŸi`Â0dUùóó³@×çÇ8§9…Á =/|‚ÑÙŇ? tö?Fðä}¾³n•™C}¡ÇØL'§8rç» XnÐü¨‡6檜Ï-™\—‡¥0§Íßk¸óÁ}†Ñi\ÚÚ.¡L æPÔÊïTФÓ2K/Ÿå½!~¼K¬£€«d¶d\˜]èhRð§EîÞ‰š(¬ë!BK×`ø€åå«}ìRÀQÁ ÜÂ7ãà¢ùYiF3÷±«òÏyvxô‘i¦¾Ìf‘jHlmd‰zÊcÆKi–9äPŸ!„!8ÔL.Gëš“¨É-£„uŒAA¤1ûÖÈŽÕÒhñ .#cïHÑ w­‘‡Y,V0ÿ½®ŠEB›‡êdãDB=ÆÈW¬ÊxE0Ÿ U°°u–éƒgC4 €Sõ=‚ªËJŽk]»¼”6™†Ì(Á;»žhd¾‘ÁÒ¾#˜÷A`ÛHër-›Ûvj{¡ŠIš­ƒÛg/p'OäïåxÛFÊkýÉ  | ö ?Mª‹àÊ¡KG>¹´é4¤Å&¢q©w’äÙ÷¤´ÈÜfCÚŠ©Àå=27-ñ½MWß[]>Gð½8 ß‹šã‡¿ÚLU¨dï,{‹±ÜMÀŠ÷lï»CÝÇ9÷÷¼k¯±^HMo~'ë „Ýä”›#{µÜŸÌuW{è ~ŒúƾݺçÌm*¡Æ Î0;=k/Àú¿ßç3Êã)³2×øqÜ!òhR=ç) =žÙµB”WÃŨ^%Äp“z¯™KQG bww„,¸ÿ !„X;K—‘]ˆcˆ_×YÆyÛ˸2Éä˳I#‡äÁszT ":;53b×ð5vT»1–!3C‰´ýa¥ÈÛó 253 *`B ßfM\9øJ] ¥Q¦’‡*ñêÙªEPCĶ]L…RKû§®j€ñÕšÔGÒQË7žæh6¶ úKáFkù­Îj˜ÂoÑVˆcë{@…/^"ÊúË5-ˆ«Ê«¸2ó ¯ºt¡„Ù^3õ&‘Ì\èÅ£ŒV\$áî0ÈÞ~¿3ÆÌ6ñÉÂI/ñ´+PÀq_»cOtÇŠwš\…Ty&üpÙ¿ÖÛØpš:™Ç7®Ô`KèïÑë!¼vÙ~+¼¾¾¿Ò¶-ƾK €w‰Íc^ÂôaøÅü5ÆZâYãdK]ûÞ¼dgÞ Ìo{kfãìžÁØõ=ÁñT¾ÙSÖô c€Ñ%ø@þÀ-'X§a˜Çô§{¬gFR[`ä4ÇL Û´PË‚’;6˜¾K1Ìású½_*ào§ž™ø27½Þ_OXW¦„óL}ÈáÃàNïÒµsuÇV¨_îÇû|¼¾…£ð-”þ`¨:vvìÚ¹û¥sš³þ+õY ò¿Æµï-~þUÿ{úpäA=ç½!–ùUþ¨ògï¡Æs6#Tø9Â×®Güôå_³Tf¨Ž9º*½Ãç\üÑcœÑwÉ(‹UÉ.¨ê_2ã¡„H)4ì0x®9ocœV~£˜QçvÔSºK nJ¯ÿ! ÖÆoþ‘foºtÖj9[µ²^”Z(4y˜Î﹋؇ÀRg ¿F~LO¤Ì8IÛE`2cù5ó— Ë$1DAe@Ifÿ23‹Œ«œŸ¾ØÈ¨; €‚™+*  õ…ó!gÿBú%¶†¸‚a‹k|ïÆ¬H&cÔXÓC‰êÂ[áùѲ&¬cvâÔ:˜©WåG^Â<‡Û>L¡-Säj?à% #ì’Xç­šº Ër¼È°óO|TîùæYR Œ2xþ–‹Ú¶˜í‹ ëÖw`ìÈEÃ=±¤¾U[ˆ\q5ÜÚc¹Æ©ÐKYF¸úôæ‡Ç‘êË·ÿ’Iìbl›÷¡#¾õòÝ8 ß—cèÿ& „1QV˜?g…ÛÈüQ¯¯X÷×ðOÕú‚÷¥‚6 O ¢õ4LhCRÅ?t¦Ar²œ€á‹` Ã÷ø^g¢{f ûb2ú˜”˜æÒ ù`x„¹ª«ViwȨqy¯YLˆˆ $è‘ÔUG%®ÿË V¨ùqI ,GGè´Î~£M°øÃ•Bx«:Õ ¶‹`Ù†Kèº+f­=óèÌÌø¥öï˜8õèšQÙ´â:(í÷îPÂS«‰ÅÒg¤àV#JaÔÊ& ½LL Šb VD<(d!Zñ1²–jlQô€ÔÔöi é@¸©¬©P1¬1ðzWD«ð®¼·ÛR¿* (4=äìY7ÛHžõF‚FXµÑ*h%¿füEmOeÔ¨ðD¶aê¥0 ì®f gÖ®¬B^0üXw}ßÄUH´ÚânGxyìS8è™yÆÂÏÎþý­ð¼ä^#¨(H­ dêÁ›ÅY¦Úû<´Ñh·õqÁ]$B/ÇKYøóBÅ6a ãÁHÕ¾N°¨º*¯ööUAˆ0®·1íµ‚•âÍÔï!oÞiKÚc›¨p½ »ç.ÿÊíø÷Oaà(ü) ¿ÿ›a@"W^í„̦aøà£:]à·¹w+ŒýXï_nu ‹Jñx4F×™ÿ£¼h˜í0þÛ3Íq]ÒÅí4ò‘)•Ô­‘žÖ$ÞC%*毠à,~Ñåw­ a.®ÃKlºwª€±#Í„¥§.AX,q7®õ{ú]•)£óRX¢p=7³˜äMuH!‹ôšíÉ\ªªºbæ£Ñ|¸˜qd$$É-Ã…/S3}âìšô~ð=uÌsî.ÒuU!ŽÛðpÁŠ€å=†yZß”iæ\ñsO@%,Ó/»¬ýÃëèÖÜ.È\uücß»×TXeE±¤ïðb>{Šž[=‰–¹¦X¶¿íÄ^V]AX­vqÁxæC,„Aµl!”}2w¾ªÆ·þ‡ƒîH0Û¾ÓgûÐgoh +4¦¯:ÈeýíWgà:€² ºGB‡‡Âǯ’n[TÈUP]€?ǘ¿•5ªý[–Œ„2|w¾,Øö?â’t}gø G£¥ó3 …ä3¢ÿ„Ö?íHaUKû26&^±ÆØôÝgÇ” z˜‰ƒ,ÈH@å[! ¨œßüÖ½0£H–Ö.{*ƒëÞQÅìÕT ÿá·7RÓÇíV_Çèñz{ €·ÇÕ1æ;Å@1ý{TçÀZóÝûôÓbÍß½öœì‡ªÿøâ/•?Œ‚=ýð‚Qg½Tc¼áÓ'Îî¡líM!ž|ã–øQûCu¡~Ç’_æ6¡‰„`Ñpæ¿Öõ/îg³¯Ÿz­8]0F}XÙÇl–èÚìFÿÁ{ïzÞfsÞ{öì=):[=’ø¾÷Å¿|h~^‰¿Ð™ÿŠãt]¿ÕÃ`´”¼€KÕˆXµ ]e•.â ì)Ϭ¢k­'øã¯Ú›†zÈm<üƽ߆™OéJÞA%ªcò6—Œ¯š9ùÉû¨³kÔOf½sìægãÞå% "0×d˜ïí<Ïݵsðïñ· <’éXì9{WÏY§~©d¦.¹èø¦Gr<¸ »d~ë»h¯A=¨ìÚ>:ûã.ű“åQ_+ëÁAÄ$OÒР6ö%Ç+ÇÄ“´üá•·,ìè¯ Z¤Û^XžqþO5nélV¸~v)Ä5f…¡B› Ê!¡¸%KðÉ7`H¸Âu3Vð‡Qê¡c_°|Û¦ãÌ´âoùhˆø¡|W² +Ÿyhò…þ.F#ki߃ïtŽ-Ê ‡IâŠú”~ô\38ä|¾GàûqsüòoˆóM ðÌx·úÝ ¸¾¹ŠÚÿ~uÏV?Ž÷E w98 ê}\÷ºõfÔ׸C.a8Tbï{!dS–­ª5{±eRòRÏE¹$E¡Ù ßé`ăd–8ùñP‹×0M&#3Ûð¨ÓÝÎ2^æî–Â)õñÔ7gþ‹k´7 ÒF’iÜ˰Psþ¼ÄWr)CsV‚+¥<ÏB—Ø q»>îÕñ0 ªeË$£Á«0éeâ¼Xm?¯ƒ¼%ÔÛ´‡ ýá2®W2¦Hðç¡=M úܰ ¥+£Tþ¼P¾ªk5Z³[…Ü)dÖ#@2Þ;E·£ ¤Sž-'Ò³©S˜·›y›%}UËt.Î`þ¥°¢â¦LέڶÖ1QqÄ5!tƒ€ ‹o·8n2V˜+õ×ÓÓÿÔÅ'xˆg>é°IOtøã•´„‘.á<ËW #(—¸Ò2¡Ô€p§ÝÃa@ÃÐÂÚjôã¸"¡}M…Ìdü··œ*ðN°£6P†?¦RS—g¸²M•Š }*èÂ˳ œÖ€Ô´c¯kÊ sã±ÃŸaþæì¿ìÝ·>¦É²TʦSÜ®{ ¾S…„ ù¡Í]öÝázü\EV"#˜Î"ZžÓºÄ«@GFÚ’ö”`(]x¤hÉe¾ŽÆãuÄÀ_ÎrU_:û_³¾¯[جûc°Ô¡ ÆtP…Z‹‡èC@5øj²®ú½¸T ÒÛ—ª: ‚øñ~€y.R,Æf¿I.Šù+x#H ÅIp™ÍŒ s&™ƒZø&) &ÕÒM_ìI]D:FYÕ '2qëP©2š‹"™ÔÕz›*ä6ÄÑ´>8#¶>æ‘ZóG+ìÇ×x,Á÷]˜,ÌU4.ó5}å_†u¶“²Ctù"ó¥¢$?óÌMJ—>¢ÂGpð9i«vÖÆF^¬3SíZߎ 8s¢n¿*ìDÀñ;ñ‰§Ýƒå¥$ ¡òâÉ9vò©kÅ7Aa&lƒÄý›—ͨ«1TeN†hId–Õ–i¬ýÏ:»Ž¬æy!LÊLÈ®j¸à5å ½’…>ºÍ¿Æ‰£´4#‡˜ï5+§þfʵA3à“á>7¼ú§õ¿›±œñ{ó­Æ“Ðz’>ƒÂ yÏFQB‚(WÜ×KÅà5UyS¡|5æ®+WÓ?\ß?·Õâ!öCØã¸~÷=wÚH¿«…a¶¯Æe¤¶;;.Zg<Îôøü½8 ß‹šã‡ „™’±Öï2ù[Ôüù­Üó¿ÀÊŸµþ{·ýã–â¤ÊœQšßµÖý¨ÝûÞ qÜf–é#³}¨Üžma™ò<ä(×ßG¨‘]7 @. $ ¨h©³X…L5^3ó—©Åa1CŒC‘`rbÔ(¼déBAe g¶¨ñ¢í3/³—HM™anw³ä§:öôâ4jYq«†@Â.Ü’¾ÛÚ1yôÜzå̉r‹ªŽÄ·l ¹ÌÉYjrj„uµ'Ûå-½—Òúœ«Á‹îßdxMÈ3ŸL’›Lì·à_¿9n–] VÙÙ âR ’E‡›ÉL˜Ñ+ Àíd¦äCõÖžbËqÏ­€0`{`ÔÁ’ >ÿZìãœb–°@9­’–C=ÃHa¬¶»„ ú#á0rÃÌ—dîò¡E«‚Ç/ÄÛšuÝõï-³í[“ÂÂ|æ º=qù˜gàã+r e9Œ­ƒmd}„Y7·–ü@gÿƒŠkUéFÉe†^öŸý­æÉÃ¥\‚`($nèçZß—é÷pùøè&YPUßyK€:q»TU}às…%n—­Œù›Ì±V¦•[2ËrŒ_¹¨¯[jK„©jˆÇ|òs÷\!íï7­|]¥Å€Ùkh‹à_ÐgÃø[c[ª#ü! €ÂÎñÛ;Å€ÌÙ¾PF{³¸îýîëß*Ü-îz\àæwsFª´ÿ„}þ@¨.‚ª>ïò‹‡Áªî< 䯢ëýÄ…ó©œOðô]¤ ”ø¨~]uÛòœY¯PÓß²ë`µc/¿¢ì>D'KÒdf AƒúJ(7賯<@;¸nŠ5^´mªnGìHxöѳÞ%¶æ¡à%6 å=pÃÏ?û*pC=–÷‹,g õ-àíñ¹n™³LóÐÒ[è-1ÃÀ„Ò=…ƒ1 ¼Âº˜Õ‚ÐTDß6‡Aò•ç0ÔÛÂÂÇ!‡yva  Ü™÷†ˆ+—5î)€CŽú“uïõ Ë.#êa 80êg˜s‡††‘¨eÎùÙéb—uï•jl—?X¯_îñ C'ꉓex*B^LNw¿a,¬#PÐ÷ö£š˜ …Ó@êÊÙ;$¶O‹Ã!-ëå–2þ¾‚VKžŒ‰¶ Sòu'Àšþ¼x6 5ÔA`ùбˆ­†ÂÛœå›K·="P"Öd$å8bŠ´K¼ªuYf p–á„`§Ÿþ5ëè «Û5N¢¸¯üMs†Ý9ãK&Îx7SFqõ­y# NiQe«&ÉXó¸ö{¿Sù›H-Àž~©õ„ $BRßàÔådH~üj……p›à€©òD 2e‘oiÒ›gIT¦Í[ê]ƒ Ý]é ä½2KŒ®Ø|%Àqí³ß. ~ÊÚÿ;Ÿùôa쌵ÿ ì.9’ú Ÿ ¤¶;À×cà(ü0~Ž_ß!B´$2PC —~àoðêw…w¿E¶úÝõnax 4*×}­êÝÒQÂgƯñPµ¾œm4˜B%µþ…úA.·ˆLÐYÁ„åTˆ&a±¬a’YH $ ê^ù—“èy{¨ÐA jmhÏPâ&wMŠ¢U™)‘¾iÉÇH*4 !ÏÖ@= R¬Ïç0BóM8Áð3/~…kœÄ8³q´nŽË%³Të* –p†ƒI¬CùDþ¥â¥ÅD¥Õ8,’1I0Så‚ݳmM8YðŸXôˆÏüy Î5¯p¿Ya!À¾7~w4n\6X¢[OØôY‹mVÚaÄohèŸnö¯à°Ä"þȲB“’ªÝdJ¹©%OBnß¹S{ë³·Žü¡2¶ƒo2|Þm“G: m»Ãĵ¾‰iw00n Ma cÆ)ÃÝr·gœØcíNÈÏ1Áè£6Ž‚>¿qn™j¨xîhºÙ¶’·ÆZõ+ŒãÔú!Ãjæá]Æ6Bh¿Éžö,iofí­‚ß×£dþÖ5º6‘UðPÕ«í;ß6F¶8 —âb˜x³mйÕÑL#T†!š¡ÑŽ0.2&‚Lò ÌŸ¨û­‰8ˆ@¢0­Âm…qâ£ðã%?u\Ä5xr]{ÅY"½ü=èà*j~Þ5Ð’§í¡”ÜaèÝ3 Ì\;‰ª]~…Ä«Øé§CÜî[ËH˜ëðv>jj Ìð"Jåÿf ÃLÝ`åT+~ÕÄT-½°=þÆEae7SŒ_æ|‰3oðH§½‘äøòÃ8 ?ŒŸã×? 5K– È ñß/Ùç”áß²pÏv¿æäg ±Õ¨ÂQÞüØSï]FãW+ÐgV¯q_¶ ÐðÒHJ9†K^1Fm Q.ÆS³g³q.³V0Y)ˆ ~_mðêÇ7™¿–Ú!"¾dk˜¾×12cÛâ|È™›€³ù«—¯·åë–I0é¡Ðõ! Ô»ìT+L2U4{ê½eýÔ£ƒÞ©ÔÇ· 0 ê¢Ï€ù:õ’Ç${Û݃¡áƒ40·ÌÒH¼Hw¹}mÏÙB†Š<Û»ߊY¨ºÕÑÏüœíV@·ûœóNý¦¸“u ñ«õaÛ$Ý“6ê…. Œþr¶íšY½ÐeŒû+\<³Ä¢í€vzÝÛº­ ¸g&¾ÃírfØ0fegÏiPy#ŒŽ¶ÃïŠÎÛnp’)¾ S`ËWÇ[Ýñåg?‘¿BHr„© ‚Ûì!ŽŒÕÓ O.ƒjdÈ{vþu;›[=·,]lÒŽâé¿,Á_'U]ÉÏ>Ûâí1®zÁË’´ú…º `^cÔú''Ö»×;·§?,tw‰•v íO;ÕNNçV_ZO…™¬×ƒ #w]AáLÓŒ–<§ò’öó{Ë¡WJ´Á‘õ¨º˜<ÏyíÂD|:AèEþ‚äf©Ê0®ŒI Âdr¨bº?p' ×ãçî=AüÉ€¾¾6°ʱÐ@·¶]qüUˆJvÇ?GàOãèã'b@è ~Ψe°÷«ÛÞg_ý!p©Ñþý?ýE ®}eÚ£“³Rsò,ƒOcÉ#OÎÃÔ}×ÅïhªMó8§qP­K¡HFgÛ#NózY{˜{3Ïß]]±ï¦äa>k¶Þ¼z(Ñß9“¿b}è–0÷@¯^\J0e#3… „t‰ÿ—_}è»§åMÎ1\ŽX;viá|}“C˜oÝ’ÅQºv aÄŒ/&”O¹–uËRà !À™²cÛWªiµ¶‡Ð‡ÓbÒC(·ìÃ/†Ô¨©xñêˆx½$½tƒêg² ‘Eš TKq3úÿù£@ ã µøþw–L&0Î ŒûÅWÅ ~dÚB= ³ ±·^펀žnž/zk ^ìV3·×ìkŽ‘0ŽCõ¾£ßbaïš¾Ug¶ìR‰¢> (œÃ¤72¼4@æÄ˜“IɈœqëÖ7‡«=ØÉØ3#f6© F¹C GÕ¬LfûÞGŸœõ.Ï'Y£¿»Yõ¾ø××½;öé¯I3"ïûW·ôU n‰œ_ÌY“V•ßRf‡O“ ëü×_sh•ç Ðw „¥?þ·Ö@—›8.H‰_ñ}ÊÁV¿üõÓÀ2ôcyÀå(Ûhsû;:3{-ÞÇ[<ÀQ¦–Ûg ®AÕáËü˜òN6´;Â"^J9ÆóafÿÆ'D!IæšMHèwiGNC¬iû¬RM©Öxé“ytô߬#<Øõf ß.Ÿžô.Ÿqd2ëãûá ƒ= Æa®ÿ¯8ŒFû q+ã×x® ®Éê+AhKÖÉ :êo3BÎFÃ@òé3+×áRŸˆªÃe 44µnžxd*gÒ>Ê4ßB†ØÉ‹ùç[ìòRi&ã±\þQÒ‹£æ'ŠeLéÞ|R†éšfƒ`§ˆÂ‰ÄÓÙwêj~<ûOÃQ—L¿A°º/`‰ ±¸å74gí[N<®¨ƒ¡“³Y4B5Ž•E~Œó¦®}Ea õè;·0R„‹9´Cl)"ÙÁàÆa@<}3d‹ ïÔ!ÈLÅ_Bó9„Sv®ÀGï&^‹l4ãtÑS:ªÅ$oß“k—Éw<dZoǦ8qÆ?kXw\RC/ôP6D<^o£ðÖ¨:Fü1€Õš¿kâÝ^ýûsGÝÓ­ýöÐ!2—凘ñC¯µ}H±³4¤Lœgm\ ˆF ˾s+@)¶ÆmTƒ3Ó’Bubà·`J]¬Ï O} NêzøÐÆ¿¾cÆT°Gé 5òsvª& ³L‰1åd©º;—)µ9Ì^†o{˜©†6v„Q&i=ÈI%³æ´×©yñOm6 "D|ÕÃxdŠªÄ—h ”²Ž.’ažÒwíÊV‚I§×Ã6­î{Eη꣗L¨Ã˜ò}ʦÅ͵~/•“ÙÆXÿ[:L¢l›².ž¶Ñ:™ÿìÂø2ñeæz&#ôD²HëNš05®é™=Û>óÐ@5­«?á Ž,? {à…´¼N^æÃ«<ÞÛ:Ǫ=iªR–ký¯ˆU6¦Gp[`H#G[…ÿ³ŒƒÄ5 Ç C4KLh•ÊÎáíƒöªúõæ¨ .|Õä8†¬¥^ù˜ùkó!¾½ëd;ÆÌ:}h½«IivpmûøW>x‰Þ‰´nbÞw…’†$£ìÕ¥sÒAäÙ2&I*¼°^ô™üëJVÌÑÙ·i4àr·fƒÎŽ·ìA \lY—ƒÝÞx´®ja[]ÿ|ª[†ªË{]oÐHË_2c¡ëü§Oʽ¯ÞþÎyžžÎö´š 98lZÇTF²!aþ’aªµÉ¶Ä.?ßG³)¼©B‡ùCÂÃàUWãô‘ú3ÓE•MÔÔZuùŠ#ru¶4Zä—ýߩŸ]vÁ¹Œ°þ az¹ Ïô¿= ’ ‚+ ¢’êò¨|«±úzXSöh»ä¬òò›Lü~Ï’ÂÂÀ ö.ÉÐäÄñx_ãÚ?>ß\£UzÔð a@mN.(hMaú³Î÷ÀáKì.ý]¨a¡Â:ÇÖ¸Aˆàwão,‚‚„v3Ž'oq1t òsI[m·kñ^j*lc ø Vœ.j½ø—ìr·çü¾|©±q“°D¹ ;e$¡VÇz™oÎW°óV@çVíÊÓ£÷ü"YN¢ÓUñO§ºRæêÙyž5lã×1\y?äÙò>ÂïÆ€Ôöx1ðN0 jûü³æ‘ß¿ú]輻?]û~}õY kþ˜÷p|Ö›IäùG•Ï\¯?ÿÌìÙï(Õgy`0?å;:rÞµ¾ß_9•òñ:Cð¸yþ"pšú–õþ?üö78¤ÕþóOw¿p tÜ0~ˆ‰.}Ÿ=ÅpLfÏ>y8æy†à}(ñQÃpÍB—;®o®{ÿøÏÿ¨ û¨g!àÖÕ°Á‰$”úCøúXôëÕ¬óØc'0æÛ)å@åad¤‡ºnï þ@g–·W÷½ßÿæ‹@ŽL6³;‰¨Ïüƒ_ÚÁ’őڕô¶D™x‚sœqÎ`øÿáÿyRŒß™?ö ýJHtÞîl¸æì¡3û>‚˱ì£/2!aH¨£—¶±FZôs„˜æù™¸d©€6=ÿ 'P·,ð,^4X[¾dk$‚Åágsö9ΈÜõõzÔi lEph»e*^>Ë‚À—ßxͶÃDqLð¥sJdS,e¢¢®â_f4Çp€ÆcË™þý'ç½3êìl^»…›×·¶qކdøVÿï{÷¨ø×ô•å.ÙçÿÕï8¨PKÙŽº»o†à³ggà}AJ¹w…OO”i+XÜñ›6ÁQ!³HÚHû 6T0ž¦‰¬K…ñ«|³dÄ»ø ŠN‡pGKa0Ë5ðå¸bU*ô6ÏT›,ê¢Þ–S_U^EƒÁJñžì¨Ñ$Ã1G,3!a»£S@L†|SB9\„òÚ‰ ¤QÅo8Ìaø½§ï}Ò»|ï£Ø\\>CCÅÙ ã´åìË~8^o£ðö¸:Æü“è:aöš¿[âXý߱毠Oÿ…žÿôíÏÏ|ÇÔÒ5{òUˆÛ^˜fûMíïìß0gúÂG€œÂG˜ÛC”$&ŠEþÀ5 kåÍlÿžõùë/¾ÆÐïeœ÷(¼üôó;ê+íè ÝþÆôŽâBð,˜ ™ÃGæx$ô俞?üðý@œ³³S–„c<~‰ÅüçŸaóÀ®¸DQúYœ¦GðÞÌ`dضÁYo¬Òá–;„ói ÂhÛp´£j[µ2ä1žë8æ©™>ñÜ@R–ÄÔ¤¥Š)_Âß.gOFŽÚ¿Óè gÔÚzâ,Ü,Á'€>kàûh5@.BKÑŽ¡K n¥Ö ÷;})£™Á(/ŸNµpÆ-w±x·m ÇvÁóÌ-L"| ÿÀwlUö{üƒŠœ\æás1¼àšj ó,>x–z9ËWS£&.éˆØ,xÚ#à·cv>ÇCï}+-aÎW^KÖõ½v8::½¥n:<iÞàäH¨°°à€¡[΂Úg9 ŠÙ¾¤D@Ò¶bN˜;D6àW»µ D ÉK¸©ÐþP ΄­!}9 Òæ ¢$ͰKE‰BD'^m·»WdþÖEDèÉÝpçCÞêïÞíòÇÁ%(A¯ú:É\ã!“ô ÖÃeŠGÃ-E˜CeÃo-yWž©¤±­¬1É O\fsÉoˆqÌtÆ@Ñœ=Òð>+æßåEÇëOcŠz¼Žx(¢[Ì¿­Ãuñëš¿Vÿ®ûo˜¡AÚB²D½+GêîÌ`¡BÐãö ÊI8ïÀz–ØpKýÜ2ë/õ¨ªdŽæ^ݲõ&¼¸¹é-¯¯8áí:‚ÂÁMÀž4rI sð¨ºÖ«ž³4ï Vü3<ùÍçÜ3N\C˜ãÐgÎqÄjd #fíî3ßlÝš4ijá=ù”Ac¶AÜÊ@Kê “¡JðB!” A6 ®öCsœ+Ýã:¡¤Zà“ìDe?ÊN™P#šäÇ7ßâ:˜Yu¼Ìñî¶µD9sé𥶴®ýk‰ï2€[ü²çß­ˆ2ê™5æë©sjŸ> {è5ùƒaúŽò†pR­Î5tí†P¡   PªoOHTxR} …qnXµ‘™©AðÌ€m¶<Ûd¸ÿ‚3 ‹Aˆa¹>ñ”86xöN¸>çÜDðªâ´Fß©K6c`nb¤È 3ª]@fÓK˜½mµ~nÔßÐv¬f\ærÍ?r‰‘¸y¬×Cu¬clbh“ãä GIŒÏØI‰èíú~|/ÚDá¨öß"´¥)Uå•뮽 ­×Ô­ðZoó·ÚÞÚLžæ[©²7ŽøõoÝÃ7¯–àá‘AG;dìÚÀ $!Djô;bÂà­£/ï…oæš,þ$ŽÀŸDÑ1ÂÛ`ÀºªÊ%Ó7—jÍ_÷ ‹ÑÔ<«Çv2õ€×<%vù±‡@„¥óUFžÄÉœ4a\ª˜a2IÆÖµ{ÙК|y}¨ÿÆÿò\«àÛâîzºñí“ö=›[¦Ê…Qïìéi`¹~õÞÿˆã~O´8&ÀùÅI ïë:Yf–+!‚Yº¥¯Ïú¾'©£)¨¥å–XvG}_„}*3hˆaÚBÒV˜y¬Ò §MÎaŽ þ‹ ßY6ÄqhÙÌR]¯Wa•©Ë!ÆÍF„†æú¶3P.÷â¯Ø'Ôølvê씥Œf‡‚¥N~L¨Ëš¼Â0HKrböUØæOý€Z˜ DÐ]¥Aáèâ)ª}…‚ù‰[ߨû~¦¶H{˜èBö®ÁåƒG-èÅ›†v6+Æižýϸ ®MÅ@jTto©öï>‘¸+f^Iž\ˆ¤&„>4gɦS8éQ_Ç¢e»åo ŽÚÖɨüÑŠØ~}ûßáêWèDÕíö…†…–­Ð“›Ìª Xò@݇¡éÍcƼs …û{ri'}ÁoÄ1cÔpU*G} #BêÊ[–Š„j@cÚBÕlŠ?±ü†òÌ{Æ]ÒóâeÄà6oIdP»òLba{¶âÆ<Iès"dˆ”û½62iX—eWðM~t)KJô³B+õ²Þ#—D€v!bNï9ø¿b¬è b{øúÊ7 Ôt‚0ŒžŒ÷Ö/ÆßGÓHY–7 nBs"ºÀôm/ãKqG¶áÑlÊqP±Ýt° ‡‰þ€OŸÔ ½iBvHŒL&3×x18|WÔ4Bà‰Û¶!Ï:šÖȶQ-´@|¤Áûˆ¿± ¶Bó'Yÿïƒ1ähðiŒpk ¹pY³ãõ¶°×>øñ6 À–ÿ®ù/n{÷kOû»ƒˆ1«„ií˜òî H îIVe®Ú3ÎY4FƒóÓ熀Q«-qÔHÅjsiòCgâ•øpè³ñ ðn^bMÿôé9ÌÆ ã¿@# ŒóêÊü"GÝ P#Ö觨µGt‰¦>Q¶½¡m¤Ók™Î‹0j„ÜK Jäú8’Ðg–ÖúO.›õNZ^‚BŽ3qL˜”idÆ2Yð |„ˆ kª‡ÝO~v‰}‚Bß‹ªÂ0¬3(tYãÇDB‰¬Æf2Pµ¾£ !êI]e2µ>B€‚™éuO«WÀh`ì23ä0´ì2Ò]ÁÌ%ñãaAgÿhæ0q€9ÂÒ)NwÌú]CßÝ0^àlçl}9Ùg…ï€õ „—YPÛĘ2ƒf6Ùc‡ ™Áeµž¿ÝE4þç*H™¼éNWá*ÏàÀeÛ­†Ålõôg{¹¯dƼoiä Æ|…ÿ=Ž}¶ Ì<¨P`F„;µ+ö‡a ™C´BKÆ%V%€#µPŽ ×>aƒ!´䬙هÃR–aŠ<(Ž™jõÉXµ^\¥a’ÙÃn†‰µ|D\ÐkÖÂ\dŸ6u¯A3ÏȳQjD ̃/íæññeÞ¹[Æví£ËÚùÏ+y‚O—ÆtìrÚ˜³@&8þ™` 0F8T¸lÆ£lŽo‰£ð–ˆ:Fû. ðS•ñSÕÈÍõÿ¨ú³îÏÚ¿êy˜mœßÀÁ -‡ÛT¾k‡¦7ÌQÆa8t²£<¾q…øQ„Ùýú•æç= ù„kŸÑ¸Î¿òf?¿6Îö÷NõÑ2(\LÐ"H¢3#…ÉŸãˆåì5ÿéÙ<ŽYNNÙ Ç·‘ëÿ Cd ŽfÔU«8‚ùA£ž0‰¯VÍ 3â%ÍÐÂå!=|¡Ú?ð- †x ÁÛ–‡ËÁ¼eÞ•‹¸|'u«–·|hcðè,2õ:¦,¢`Ùćq€T×ùÇ0`·ê¥ÛHÎ}x7‚ˆh€­ÑÌ„YUÇÊ¡=âš—0sÚkIºQvK£°v>ÐN¦@c<Ïz8,‹^@œÆø¨}€ãa€¿ƒJÄiŒÙJáÙJêryûÏqg]­WêmE}N;ªÎµ#€çz­‡GÓ–îÝç7.³_æÉ•Ï™¿ÝÎôïYPÃ?¶HiÕ¬¯?×üt6>'〆nH™iå–Àò.ó– ¹öéìVåzY[Ý-zן¨?™ÿâ%þ@ß™ÚöN\§ï‘ÌrÁ¡kü'Ìü?þ9Vüjˆ7»´]ö«Ïr¦šÐGˆ.)e!åyœð’þDeƒç›ÉŒíŽ;$Á®£íáYA`3\°íqŒó!…œ¤ûdú&U  ÚœòCUf&e^D?Üy§ŒÇÉ­µ³b‚Ï®Šða]Xq»¢qìüBR«;FÆ.M³\¤ÖƒðS4Kù>É•ñb@_I”ã#õÀø£îúdH%ÿŒèĶò<9ÁvžSIÑk…¹@?í'ÉœgŒݮ.Õ!Ä/`š¿• ùÒOåT¨R5•¿oæï80£%éÂ[6ÆiÏ<%^Òa”Àwû$WƒÝkòLuün`ò3Ôüþãò—-À“ K\hFlM©­íë²9‚£ð#uŒÊ×)—*jýçß-^jíÿêöeª pöËѾ2=‰°ŒrËlpç;ÄÏíãö’ïP‘J c€šXu$ÀR\L‡ˆ¹õ bŒªõæë«@]ÈÞsøÎ׿eÍç=0—5Ì?3~(Ñjúw> ÔŠÿ §:¿ú凮ÿ«*w¶P5­{¿úçT*Êžèíðu(ŸDXR£Ÿ5ƒüQ_ýØ6Tüp›%F_/^ºô&„g»æ§ç½§X.ÇoÇ$#üDhZô®^}þð<¨`Ayƒ1K9á‡ÖCÁ'ãy¶r c-ã—"iWàҊΆBa:CÖðÇâÐ6 ĨOÈ«jìöBgú#˜éÔ%o/¨ã ƒmïù,Ù€g;?™ô~6ÅïAöòÓnÒE²0}2¤ÿ”¼Á·#CmO-‘ˆF9'Ë-– Ç^¯ðm€zÿnIǃ¯Lýä) ¦yrã¡>¦È}2Õømu»ï½øRW0F´|<û¹K ö}E¾#fÈBë+p&]OÁc¯cè„Êoü¾ÃŸÄg`ò®G±ÁM´<4hm‚Ý ‰28}D8«×7„†¡Íó£Æ˜O?d{šF™.pŸ MrlQˆ3z·‡ ]2ÐŽàÅ+ü£1¢M“kÆ•m#‰(«ïl£²Ø_;Nêï"œžz™‡ù*Ø&ovš}÷J@…#“v2ÐÌÎTëHßîf§l:º þ‰{`ê÷l9„™©f½ÖÛWñ”e"pÅ#‰ªŒÁk") ™ËÔ9î˜w™û ÿƒŽ‹d|þãûÿÙøxÂï÷üýz Î¬Ëñúi8 ? oÇT` i\ï{_4whîl½S€2mbÕ ûôÇe`‚á¬ÑJ¨ -\5“KÈ”Çr”½ûÀ Úξ6÷Ìò9mouW*ÿû×W½×ìãjõ/Çìo™ù…MÙ§2{?–ûÌÄ.˜áÿü—NYן°>«·;¡w‹ñ×zIJP¶aû–”/s&Snj®ÚI… U¥´-í-ÙV¸Ð› Zg7.jÈ]NüPBã³v»€jFØÁ(u¶3†ÁgVKœ”ƒu±qaepFÝÄ<ÊØYbè§u¡Jµ2 ™Ì/žá€á×V™o-¿íS+Ú+´9´†Y·õ²$°÷6TÙIQ-˜QµGgFÒ_sI¿¥NIÕ |bXß%G —0¥Ñ$Ëh"Xÿã@ñkCDù†óV÷1€9n˜‰1´­20åÑÒrðÎw™ Ð4©워?aÎc.ãxɇlBöÈè3 j §….;‘ˆ]Ó;¡ÊµédÁ8bgBÓŒ­¢ºøÕsàI‰ ÞâøcB5KƉy;óWŒ*‹úÆÊÛAi/Ù€'ëi¯¤©Ô/°Ô9 ô¥.žV_a—M>Ö3åš!¹)¯¥–J˃þ!0ã’¿Õ–D¤µŒCf¦÷Ä1’> }Ëß¼¼’¦ƒ.˜ïˆq ©™žÿ0øó ûÿ'Xÿ™ý»,{™ŒË–ƒ¹¯ƒ£ðc°õ7Wbã¯VfÄì˜uuÝü.Qõ{/0°ÓÕï½î~·¬½ó»Œ“?~~ÕY½ÿÉXëVŒÌÖ˜ªs ^ögK½fRªr÷íoXÛßÜbÏì:n~µ  ö…p¨Ž% °ÛôNYß?=ÇyÀòžÞ6Ç]¯6«ZþS?k#Õ•:›õ.²UñBFC MTøð¯8qû£^ݺj!Ó6cëæôËãL…:ò¤? õ5¿•°ÅIsŠÊ‹‰,CÆf^ZÏ‹wðÔ@ÌìýftÓ•Z¾Ò„êw®>ã &µÿLïú»NlLëÙõÕÝ~3­õ]¤5©&sõ@³5†Õ’퓱0V€Ú<¨æw_|ì)ŒCXŽy†QºÜ qbÝXkÐV—¬‹ÕvÜiHèz»í¶i¿yuÕ©B-X<¬HE塮؛ðè§\Jo¹€Á%5Úì^•Ìù1¾ 禣Ž2i¨¨ÌH£LµIÞZûç&LgIÖHoŽ}Þ@{»ÏG NÁRê쩉^^4B †bÔɧ=´´ËüÒÈúÞ½T½“CýIœÇïÝs’úÜ:hü–&切ªR—²-Ý›¡5Lãeœo]ßH, á¿}.¶Ô äj¬ü'aül«uÝߥ°óÿ®º}«ÌcÀ÷aà(|fŽá߀Ì̳Ûó_²·þ^õÌøÝïÿúöUï W©×zÃ#žL¿ „Pï%讥scÇôøôwf³A•í ©fü²e@wT£›mPMg?ЭCî9 ~®®’º©–Ís 3oOZ{ÿãgÓ³3–Fìuß3ÓÄyþÜ™‘âZWô!>ξؤÝê4r4%(xûÏ:J¼n“ Á,vlû»»e'þß=†v sY±¿[(·ã¸d†¡1B€K(åÝß_ŠW•¾P†—uù àüeB÷l#Œ ‡8í (ÙÇìEƒ‡î†‚‡˜g]×~ zŒŽB sËŒ¦ãŒ{ï^t¡…>¢¯é'Ó²½Ñ[ÂY1(Û쌔¼Ä—Z 1d2G™ˆý¯¦BÁÏ6e/¿áÖS‰‡ÊkÍ/ƒ?Áãìõ?ËiõZyöÐåŒV÷¶ítzŠSƒ`ñŠ&2qrõÉÇ“yñ™8Y]új¤vûH}.$!ÏjÖªç[fì ž—Üîˆá‚˜;DœªËf§Ø› þŸz¢ Œ ŒMÈŽúZÐŽ6ÆäÈèF´‚Ž]ãQ5-¹>‚+ºÈêÖðþà5±ù–öØ/ãv}ãk©Æ³D6¾Â†F ÄMµJ° ½ÕD¤;‰o™îÂIZÓsSôá²ØäÁ‡¤„~¸ùP“† Î[Œ…\Ä1oUú#~#Ù6ªµ?Œÿ”%´3n—Òæó3ðªF |38ª}¦<^?Gà§bîo$ÌÞ˱{ù ì€Îü_½|Ñûoÿðªýo¸÷å§î]V =€ñ–:B%Ú1óJûªÞç÷’íÅvºMU qÝéö56@)‹Äc SºÎ:þ/~õIöókÔ§šÿƒŸºÊ}ö§ïÃpnÓ ~p^p Q^C=ï²Ï f#É‚ °Y†É¦Óˆžô|ÑBÂS¡þÐ}r26g|öiïÅ—×hD¨³ë“c Êô'O.1:d èŒnɶÅËKœíW1â?áëÏ? ô€×so0tTM¬¦dÝÃë—x1¦_ìï¡Â2=Ömñ °ÃáNUºõ …& (7¥ ý¹UH¡\îÈèPâ°æÀ‚ka¯5 yÊ~‡CMðû2)Y‚yIzÝ+o¤O`ÄeìÒLf~wÚ'D ‚‘ƒ»;™h¾13&“©3=˜¤ ôüé¸÷ó_sÁ%qPýßݬ{ŸýîU ÌÏXóå`"a¶@2›>¿ðð"™mz„5ä´ÐêGð3­æ¤¾©;ßÂÖG†võ—™*lR6ÔõŽó „qí |ÎY  /BæÇ%+l:ËŸžà7âcl€ % <+„9]ùŠoÓd_<ê×g÷Óõ¼—̓ÂÜÇ+G¨³Ï©˜­ ¸v;åƒI!èª0~K~ó'eÌ&Gð˜á±|3ŽhP‹ DäÔÉî©"öŽ3Û^å¹<ç2^Û·ozϪȰ\~“ž~È*X„—§Öh5ÖTÂ,†jPh¸Âœ•P¨He^j|—¡»îzáYB…ñß“÷>îýâïþ¯ÀÙÉË)—ólÑÍö¿b]%T^Ç¿?…ÅŸî˜âo0կݱ¾2ý+ë¼dïýêù;Tÿ¯¯ðýto$zÐuçÌ@™µòÞGš××½04È×ëîp‡p–ÏïŽp4œãD˜´2 Ôûgøì×+Øœm|?ÿNB€ 9M'2ñ¯Ïì˵ýûñ"Pã(¾tÖ£ášäj2V­- “¨ŽHşЮ¢WÝ3ß`81Úƒ n öñE€Qâ¡E‡ECœÜ¸./1ƒÌbæˆs†½€i,o/{ Èšå“L2w ´LABrª½Ý·¿¸A»  *HÃ0<ªUm  —<œew— (êŽ ›?ÑÀÌ$Øp ÊÙ©€ˆ[…¼?ÒX§šñó™go5†ç¶æô ÝNd"ÉvGÒ&Û†E¼:Ý‘¸P"™èé9c„£¬F¤Œ³—±n'΂ƒuÔŒ©§ž õÕïØmäs“ëxQ-9É ã2Ø+°Õ»ƒÑ†ÀÌÑ4¦¯Àå³F’Kœ:¹S"yP¨Nœ&Ýš¿g'L`þb$Ót¥BùÇ|’†‚Ó¿à|ît¾$óCÑsä0¡+b?u±O(×¾I}–6ÙÅfíb ªÆðŒ“G;ßÝÃbü$ €Ÿ„¶¿Dùñò+.È,¦ãÚþÚ}þY÷Wà”?,õ™M.QQëÞ4ŒO§?a€ü¸C(PÏ eL§azL;a€êŠUµjà'ŒÑŒo/•²@$`åUéå^w‚vá„ýûªö§øã?q9àLˆ‘{ýúÌ,–ã^"£UU˜?¤*ÛÉQ€un„°â¬UÈ[T¦|ÉŒ)Xh$°`fPr(®¦–W3²7. ÁÝ@ý¼jr… òÖÀOuwTÞW}óOÜànÛ°~× qÍ-E•.æ8\…%òËAÚ)Èx©§ñŒY³VBÂ4l$¨dà¼X(νáå"Ìçh]¨¢Õ ÂÀ»>r­µK×Òw©¿9ñ;H,ZÊ_©¾Ï0òŸ•KE3«­utÛ³gfAï Ÿª¯eÄë%9˜„îÈŽ€pDâÕPª2,Çì½R(}ÙÞ óÙªe`¶_¡+PË"]ŽPå_‚¸•![û—¾ÒÕ¯ãÍmŠáK6ÙòŒƒ ™»Ã!|ð2Ò+øX6—Ã`ƒw©@á)ÇH»üe\#PžÜ¸„²§Å)JfkÎMKÙ˜Îp|nÌ<ñýÞµß÷ŒãuqŸ+ð” J’1ã²åe4…ñ’o 0°»ß¾ªÇ©Œ]ã>gøq£íú?†M„aþ6öP±oçv ùq8 ?_S±u*²Æª^u³÷ævÃA:Â{Öÿ¯Ørw{ÇV@ÖeïØ"uόݓÏ\'Õ^@Ç2îߎç8¨Jx̬AÜž&ôGíD|±í&ä°DöˆcÁ/”8he}y~¨ßœ™ÿéœ Œñ3±>§×í9U­µûÝ÷®áCõÝÛ¼e–¾Ý£`/‚l³¿*| æM›õZ©¤T‹4yä94‡ Q9ú¡ãƒßõY¿¼Ç#Å@„ð‚"¾7Û]´cêÁrÁfÏɈÌ\ý·¦.½ÑU0þ¨Û˜ÂN8-¯¥óf3³ë#ÜÈôd@nÏs¢pë;î®^«Ô˜8[^ ÑbÐö2¶+(UW8°¥îE·îªþWœl§°¢*×e†$ tÉ\2!ƒIÙ‡ö'X[ í2op"S óàSö†‹‰¡:;¿›,5AÐ*“] ö;7É¢Îgâ— —8ʉ„÷» ów™#ËfK[Ì{£“ ÞAg*’] 5@Õ‹/]ÿUŸ¥NÖÙdä+TØ1V·jÀ·Ýš>]¤_KˆÑ¥™Y…Æ Ï%²3¡Ï½÷èTÈS\“¦=“1ÚÂ8êÆ@’Bôû.¬VcÏ =%êå1r£ø1' —¨#3úQWݧ¯v%—aéˆîÙØ¢4M„1Œjâhq  ÎcËæƒñ]VQHÉK—çTáÆæÒN þâV8/~hWbåÅ,Ú]²}ÐþfÎø™í»ïަlÊVÀ1Z³qlg¦à ¼'—äpüógbà(ü™ü÷–¼í7wWq{{wÓûý§¿ ¼ÇùëW×½O¿x¸`‹žaÏ¿Àý/P·À’ˆˆ‰ÓÙH !Z¹à ±ªþ“Lú…®™Ÿ_ž÷~öÿ:Ðþ Bð!Ž{„Ùf…C˜ ¶ñéMÎ5WUÏCÜÆn‡ì«‡pé¤G¿öÂ"Ç0G¬ ›gBëçѶ)s¢Î7 0zÊhâ …*‡Xñ%‚®psS"}õÇW½/¿üŒûUˆá)g \þœõL»™ž¬z#êv³ú—Þîö4ÌL Äî à|ŸBØñì?ËLYübåš¾jy¶‹ÁŒ^Š“%™š’«¯z¿ùÿþ;‚í…yke~ýÁÍHÎMÐ<}ñJÈsÈ ÊiŸšË¯_±ï_¦'‡¹Ÿ¿7î£Ú°þïZ6nâ[@!@4dÝZÈà馜Ÿõì?ƒ5âšü)LD6ˆ±,“¨ì e02?êA»ÈÖ0–tžá¶‰egùvq|õ9[ꘫv·Žw/9¿hÏ1º›³^¼ÇqÓ‡Fú5œÐŸì((æEɺ„‘*£ÏÖBËrHæ€%m`‚2è5êýÅk³*)Ø~ù–´€27 ³|ð© ä!¶%³÷X†8׎A- 8ã…¼DcA¿zXUúƱDM¥oùvòhÊN¿ßxìÐŽ}–7è/ú7d…€&´ ÁÖŸ,´§úGÆXmÍK…9X»WDZm,ަþî¸Íô¨£€>Xñù&´ºþ¢ží»ÙmWˆvÏ´Á1¦€™„à¶ÆB²*­iS)béðÇå–¿Söúøñ¯ùM{Äö9ðãúe ÎÔ~Õö¿ª_²9þù³0pþ,ôýûMì\‚»a?ÿš}þ+¶Ûií}wÝ»fæ/“¿â´½ÛÛÒ8+½wÆÄŒ~—Dϩ˾›ÊÈôC0°^/‚A þŽB²—ií±8¡ozŠŠÿ†p™Yþ kûïýìŒJP}:?…˜ãÖ™ü`Íî™9ËΜ bŒ¾S½À´O¹•­•à1›ø +‚]¤.UµºÍ@J‚íÌ;Ft0§Ѓ¾×Z0€ D^ÆÍ 8Д JÌòD- XºKžàÂu´ Lßæ]#^Û‡ 3ÚÉ,U; )M«ú5>b©í6}³ÑgPhy4n‹0xõ›Åî&,Ÿ`”Í3õtæOþYdŠ n»¯iàÓ ¨cB2Úf"ÃåzÐÃ)¬Ã´ùfˆÿæ2³†/L1xËñÁ®©“…®î±P¯ }†»@ÝYi Þ¶µihxM?¶o2#¥;:6ßâuŠ(¯öF48U“’¾—j´în £?‡ E@Ú¨É!U,á Åß²´aÓQS÷nÏvX~Gÿä¡&­´ÖœS]%É €œ–$h7€,BF( ²áØó;_ó¿û\ëä)8·Ñ\i«0odMŸˆwïàƒzÄ dÔ׿·Äw‹ ¶ùÇã7žx§_õià.Ó¥Õ0æãË’.õö·—åY°õÕo‡¾þgüæçgü®¹SÖý§ø™ý;aˆÀÐZSùÿþt €ŸŽ»—)‹<øcWM Õâ ÿ+4Þk·¡AˆœÁ±Æ—?ŒaDcÔ×Ù¯â@ÜP+(„EyÍ+‚(%š^eÈÅ_H•?to·Mç¬ñ³¶?ãžzãYm¢{UÖ]ãôf aæç–<ØMG¤Šh…ðJÂ`ü”œ°mJ³L ñBIMé«ïü$¤fþÏm]+zi.ˆ™„CÌ5ÈsXÈç-íÝ3y®ª_ëåz (âÔó ÞRFt2Êî–ÙVqAÛ‚§ ZØéóü\‹Úà9n'c]]Á1Yá˺%Lµµö.TÛ%é|§‚ªý7Ìv…ªŽÑÀ¢™p~#Ǭ¼t\Þ> ½¦®u·u=\àÉwéúá’é&Ôê`źDõX#Î à4j3o×õõ  a [þ²íμhK¼¡ …"—-ô-`=J;ÜKºÕÐ+mÎl´h">0N[ÿÆÅ4y*Øà"ëþnõsý¿[~Iž0)sŽ+ŒVˆüHaDÀLKÐuÌ1>ì a †ú†iùæTmîj¼”kãT?z7ÐðÃõÍ|y·/í½ÔˆŽ¡ôï!y8f¼»üóÓiß ŒA/H°SÆ]j§ôã=ÑÚ_£?$|ÿÑð¯!îÝÁ£ðîpùWŸ“D+3 *ü5Ó«ÛÅ5Ûžðì‡áß-{ý×nk‚ÒêÆWèù³§½ñÉiˆæÒsÍQÕ K3‹@ê!Å€õ 8‹PºÖê)DRìAùä)œ ò?ãt¾“îžaìç‰}]IlUע›…ÈòF¹›_ÝÎÜÚ¿ÌP¬‰U±¼@ŸŠéú®w<™Lû&cÈ÷|¢í„HØ×p ;TñîM¿f¾Ä–É2utÝZf–í_0#'åCÊ(ÂHÙ!€A›SÒ”`89q‡C9vxŠ\YÏ[¼Î5>';„…(«¯aœL8ö %†Åñ)PM®ý{fên§e2}Õ¬ÎÂUqËx‹èR—b%|X>AÞáºB®´—‡„)˜Õ·DµßITËBtÕ#É赬ßٛτ:ÌhsÒOuuòçÙ1¤M€Œºòw?½ãpwñ{@5ÍŽáÑG &úv«A¡z»Ìp‡&Gè^ÿ{=:*pÛ¶½K aZô)¬°b›Š»˜4cºoô+¿ã07ù€¢ÖG©u7@Æ6YW¿Ó›µågǺÅmÑÎŒGæa4ǧ°þøÐ]•雸çS\‘(È÷>ë[È+B}·\¯”óVX•ï7ŸâfšgóÕ¶W4F¤Ð cl2Æ\òÓ-73}¶þÍæÌüõú‡ ÀÏqüÓ˜¿¸NŽdv¼Þ ŽÀ;Aã_o&œº ‚0ëÇ÷ kýÿuﳯÿ;€×ñ;¿„x¾ÚÞ÷–¨^÷¨*GìÍýûŸý ‚‹î‚«ÚôžmjB ”tX£"¡„Àk(Åçrö¬ÿþkØ<Âíé/±3q°òäÃg½Ÿÿ§_ºÕÊ5Ø!~î·@OóÜö ÷Áˆ`ÑÕApæO9RüTªŽ†Tñœ| K—(ñ¯¶™‰¶ÖL!n|—ûUFsÁßÿð¼wÅÞpm®®”h‹õŠ£iŽÀÅ1L|d-›5zÖxUÔ5/Ù†°P¥¨-° kÓdž!ç!ÒÏÞ¿`©`‚ æah.±3¸{ Î Ž Á=u Ì›é=$B‰ég ÒÖ›û@…!טï4(ªò?E߯Æåô’uwMðÍ”S­ºX-DºóÙ§^#ÇßÞ2´¢ñ lù‡ÿ™*òò $]ÇŒó‰F ±kYC!å 6s·àÝ`o!®Wå0Òòþû„ÈœtˆzÞãv@gåöמ¤ÐKF¼ÅèQ˜gñäx*4¹tõõsöùu㬀ôŠ}ùB9éŒ<FžEàòΘÛå'HîlÛ$OSÌRùî\^ÊüEGíj±2ö±ã°`p,X€ÞÖ¹”ѱ¼“MïŒò…Ès…¤y'{òÚЗMÐ%—Ãeþæ10"ÿňŒY‚‚Lõýçg#×¥ã¡\$ð¨;|µŸ•÷JÈ6/·ñ¹Œ@ߛݸõLZó]Ó>aì°0==ÿ€e?´äÙû?ë}üÉߺíO@¡ã¾Tÿd’ЦFÇ?ïGà ñßCþÌ%Fú¤W…½e»Ÿjÿ;œÓ¸î¯ Àª›ù#³´>·Ý¢vþôI~Àzïs¶ãá)ñ¦F~ΖÆp%¡ ƒÿøâ‘àQTlßüëçgkxïÙ]°}5 @9NÏÏ`FÞXc&áØbÄ&ŒºQº(sÏ”NòTÚ…"U¼Ó} iòžWƒriXå?dT2îv©ö( H4¹¤=®X;cRPh¹ÅQÏÍM †13ø®Þ ËÍ-E˜ €*ì AÆaeøñ][»š‘IDUý+Àh¸µ€Ö*~Üw/4ËéØ ¡ª~ƒåYêGÙ6q¬'Û†ézx•ƒ‡è#ê)#‘™ ‡¨T\>PS¡w: ¤Î䤺¥ÓŠX ¼ý™ËÄÝUãÇ6Ù­Õ6ßmn ÄŒâeTx“]*nñßlyw[¤[9-o½ÖÇ›vÊÐe¸¬“ƒº€xG‰ÁUõ÷° ÏHYÄw)Ávʬ#°.é3ÖÚeQ…µF—0þì”ÚŸ¹yÕiŒëŒmÇ·eY'në&·”9Ê›`wwè±JIëøKý  €¾›§eY¶‘eÔ9 EGôZúÏt L.íXVÕ‡ ¾q}3ü0û· ¥ ÿy·Ý àÏCoWH‹])«¾M°Ú¦§Ú¹fß!!ßlcgÿfü9õ/OþÃðÏ%Ǿj²ãõÎ1pÞ9Jÿº2l?öo™Y‡6¹Ýó0 6`ͳö¿’öæÈN£Pp-šµWÞ€M÷Â"È0, ú ”8«:CZ-pÌv•ù ì˜ao‡xOƒ 32á5̰H¯U:qœõKh²?:OX5©UjFå:èw‰¯DG L[ÍÀ«ûÔ¾ ŸP,“±¾zÑ+¢UåJVe¢-éË?N‘XC×ï÷šiÚ å³¾Í ªˆl•ßU§£¬T" Ô²ÅU¥úÂT†rœ‹Ìð<Œ=Â7ù)4¢Èú7âkáˆÎÁÚ^=s>j 2LŸÍÖ©å5摼ªy7+ó óÍ‹‘x Mù5¤&ú_¸Ùhs'ŒÝ¶ønW9N„ä”,³}Ô¯) P«~M3…;ʪpûß@¼RˆÌE" ¨Y›é7 6ß}õ–¡ùðÏ]ýÓ|ÊEªVq4…«°Ÿx6™}øIš, v áÕ5eÒK}?¸+`ÃqÂÎØ2WŸÍUºÍa”ô: ÜhÈKƯ«_ ÿÔh ¹ð<ìR t¹¬|ÖŒwF}H•x¶ý  îBPø¢%Ðõri‘Èßô|¹©È®¶Ùð4ÍJøœ¸„^Fõ_¢×w‡µ Te(JÙò]èwÇm J& š4Ó>ôOŠH ¸ŒbzÏFËEÄ—§z€ß’¼ûÃg£r#[æÑü>4äÌ8éÊhÊ®GpJr”îv¾ÙíÞùSî'h³ðùœÎ<øÇ­½%”FîP[Ò¯w‰£ð.±ùW•—Œ U'Ì^fàÌÿ~uÛûâ%Çë—„ßbü÷rÅV?üãÂ¥ÆÙsÝ*ÁïX7¾b€ÛÖ²Òem•žËë)ÑÜjZްà;Læ`P@—úwxòÛ\÷&w}(žßØ£¿¾î½¾{jÒ?ë÷®WøÊÁ:'óÎü·l: „Ì¥|÷KD¡Š {´Âµd†ª ™ªåâOÊF‰¶0ïäïŽ|âËèÖàE& ¼ƒèû¾Â@ìë/nzŸÿþe LAŸô§O&½'¨.Ýö7;wï2uFˆÁûOÿÖíyaªA Þÿ`®0«Õ/–/Á”ðS CSQHXî_3ëÇ`ÁáK[–Mö䯗A!}ø‰G§:ƒB¡ŸÆ¸TJBÕ&ì·.¹\½\ôþñ¿~ÙÛ a߸£öc<,A”V5´Úâz˘EŸ°.ñäSþ†™û¾%ÓJìàŸ`9D]»äRyØ~pˆvIŸùÛ)Ë#Ôí£/p¥ŒFJõ<8¿åà©ÛôL´&žÃ$P!çQQÓËùXláßq’¤0»`ü¦WpÝ<ÕDp3™¯F‘ªÅ7®Ë[d©%BÞ†m˜£µ‡W{7úXЂ]¾_K¥ö§@ãÖÂHμš¿~ÄEÚ Tþi¸±Ž¡ßÅÃÜ<‹çQ,¾Í"·ì¶.™?ÃŽËzWXúÉGâ*ô,Á·0éIª¶Ãiñåûs§Âo|PèL^uþüôÈNfûOßû ÷ëÿô_ž}ðI ‚4eb£¨ÿ¾c €wŒÐ¿®ì @óÏ?̸ï7w½[ î0[ò}ó}É¿3;òEÿ3° kò;~ùžçÙóCö± Û²qYó÷¯l÷BÉ‘ýðÌêv8àW€Ùvˆ½þé±;@† %26¿ýIµÌÌŠ“ÙiQÆàp¨0y©õâ_ q`Fuú›¡5‹”ZûYƒðR¦‚JcJòfÍô%3~Ý»îïí2×-†œU ‘˜öÎX¥  ;嘈’5‚’f‡¨JÜë–è»eP@8@(8BT¿K(|£zÿ“Yå$@ž5zü_ìi—dÉQ¦#cËȽ²ª7@= $à 0Ìÿÿó™Ãœ™a@¨Õµdå{Îó¼æÕêFÀt«ªZá™7ì^_ÍÍï537ߤ£iT6ŽÙçôB3ª ëª_ÚvŒ£lËÊ‚Yü*@2Ú†Z¸ ÝÞ³t•Dè÷Bé©‹´¶Çîm÷G½Wœ4úâö“"ÌBLìeÛËOùïŠ'Zþ’S‡sKzKs Tm3quE€¨¦'ϳkìH–펊Zl«kÿƒ›þd% ñP”¦ZOP‚ù¸Ò%ä#ièƒyI¯ó$´8ö.N5·€Àþ¾ñ~í„¿4ó2ãdÐî¥Güæaãé4í™ÇD‹Å?ÃÓF7q½º$ˆ³Hµ•É–8t–n 3–q+;ŸâR wINXP =òZ-Çw§[ N~vùS€ß‡3ÿ§SgýŸsD÷5:½@iÅÀa?¸Pó¿íÏÉ1σû~)pP¾_z~4¹ùqf&¸cÙŽó{Ñ{^ t,ùs ŒÑ)w¾îð¾vǶ#Ôµý¡ý{^¹K‡Ò«E Ƚ¸Ž÷õóË•g2eg–“’Á{óp\[–‘Éi镈¸© ‡,sËÄ¿> ¸ÁÊeº)`è½ A˜(ùɘeÆÂ( -¬µR¢ÂÀ3Œv…E A¹V6“¸ñ[g„³'=ÂÆuV˜‘îØ— j 9!áU¬ä‚öv¡ ) ÂM6„éô¶‹MË ë’QfÏ•Î~ dB¡“Ä,Mv™tˆuÆùî­Ÿ¹äË=*âØvc· Fà¥=È^\ÓN)²Ê-a\¨‰S-±28¸ Ÿœ¤ÖEQ0<ñÊ/í:tOJ+^qÝCâÝ2mgÛ²ð®L ­»þ‰€&}©“œvw7Ä4&®ï¤ó8´>Yl¶T††NÞThÛS÷} mShS8 Mr%1×rMÏ¿™Ò΄%eCö‹Þ-¢‘¹Ê² _]í5OX2lñ nÍØÃ@5q{º ™ ãwçÄëûrâ”zŠ:™æÚ»ïE5jU;¼Sø~ ¾ ¬†îè—%Ìð×Ü?séJª×”ù.ûëÇýVV=w2><|O8(ß!?–ldxºŒùÛã_p-ßñÿ;îëT? ¥‡ËdÀÄ–!Ê 4%+0„( ó²•ÂD¹•ẠŸÐtx!+å`ºZ`ÛåOQcO›ž± ¸]˦—«àw‡(<­o+LfÛ"×=¡RÂR<¼'BßÉg›#÷ …©Th½½ôÊÎìQÛy÷N¹ÃÏÞR6;2®Â‚dß+>–Ð9ñ/ËÈ(Ãù’dŒTšp#”lûnÿ1÷â¦óô®ƒW¡‘B5JøqeÌ—23 ÄšaiFBÒ{I{T6† ’Ž,2i‘|ÄCz‰—íWÙž0\‡i¨ŸŒR£äP–’Æ%‰^¦å1Ò6J qPJzJŸöÜnÊïÀ2€g…§09òÿ—Àå†BŸTº\¢h&½Ù&(U(5R8Þî|W..ž y{çîUaã¡Ë $W`,éñÛ^¾w^5ˈÈ*C3¶êá*GBi¯Âà1ñSX”@, Ëò/ÊÉûœò(Ó¶åŸ×¼*gÅÈ#ï›÷i×½0ƒ¢°>ùíè—øúƒh¿ç1y›“ûΨO®¿ãåcVi ªn²õ½­îDWÐî÷‹Ø¿7XÚ[åòçwˆõ‰Ö'ôú/.ï÷d?züWÏ^`îçˆ_zþžôç®Q¾Y 8¸„à!뇙©‚Öx„ R7ùù§¯ØÛ“?§Øýêæ«Á=Ð=û·šä1»n'œÎ¢0s€ñlØð9š8fîE/‹õï+ ;ÛûÉÊ †šÆév®™ñïB@œ8 èWlL³fŽÁ’CuÄ,.4ÿ@ÌóHˆô^Qt„Q:ðs?…X±FñÁ\vîå>B™¹æåÛß0† TxõÕÝà–½ãïoØ–—(SèãÆ5'¬ûŸ2ví½è*2uó±iÎ&Ã\ÉWkI8nÇ ü­P”¨¸áDºÍo]¶æÁ@œÓðõ ãÓ÷ЃyÐ>'áoi/¦,Àf®f—!#2Rnª3flûˆÝï2Ð P("ú˜S€i›uðÖ×1ïcæ,ˆnðŽB"þÁ)SGA i†zy„ÇTݘªB¾&{& ‚bºA­<ŒŸ"táß{䙸‡ LÙ1g…‹³Ï½º¹Ù|;GÔdܯЈ°]Ù)ðÐ¨Š•6=‚JF” ¸n‰\ ÁV7y®pcÂ+Ä#÷ø„æ°[ÚD*ûÜ.éνqŠþ–ýt© ¸BÀù ¢¤ò!Ó·ÍM®ž«LÓ ²Í¯Ýy³Dñq§ˆ³~{õ/€¿õRÀ+"÷&J wc¦Ð2>¨æÇ!—LTÄC9fó:l`¾¾;ÆN{ÏzଗÊkHzîQ„Xp¼ÏÉ~Ò‰¸•VÿýÔ§½o|F”å{P´p"l&.¦G uÀ·ÝVez]­G«c¯k`óß…YœUèŽpqÒuس)ßò7LóÙAïC“òëé{¹=ÃÄoéÍÓg]‡MWèÑwþ«—,íhìÎŒ}Ö¿kþgl~’þ˜€ÉßS=ÈÞ¿Øû~Üïà÷Gë÷Z’LPáéx¿ËÒ„œîwsûfð†Ë!gÛ;æí¤¿ìÙÇ|D@¨Åó…†cf´ãÿa¢öÂùh#x¦†Ÿ ýŽ3#¸A·%*ašˆå¨vbüu•þ ñbÒ—ß1î§‹û&sâfŸœ–úÙ›$QÖn~DÅLÝ$hÙË8À¹ k–WzœîŠ|íÁòŠP?–5^€1R]ës°7…7ææƒH˜)·BJò¿h]õ¼wߢÅï8³Û9#$ÃÊÂ9§A֖ξC¶—ôºªC ‰MnÒt(y!mïžñuV@ö :Ü¡é_á¯5ÀìÌqëiÄõy<§­¹¢dõxWÖ™¸4¥É!ÛÒ¥îÆÏæJà+G§‡´éõ&ÿÐ'°òK´.Í}U£Dg{—KˆïrQvíûÀ3¥PWêòzÄMzp¹Z'ï…qyàÎ:ƃ_µ¥TžafûŸs¬oŸôwÁ©žçY÷ïéžµë_V\¨µž`2<üüÀ8(?0?”ì.Îìuû›Ÿ0޹x|ýæëÁÿü?ÿ¸dðqÈæÃëËÀL›0v‡t¼ØÉ#ÆŽ=ŒÇñÎàPÎ8ï‚VÉ(wÁäør ~,ñG °• dq0s?‡M¿dîJh9q"Ø0&¿bŽ€¦Q‡.²#AºE2[˜2ñ„)néŒìÚïœ<¸ÄL/Ü)öœ•;!%«+L’°np ó „öþŒß¼f¯x6þñØÝöãŸ@‹SNèS!šÍ Òņ È;¾­Ù>Ë Á1¥tÈ¡ ¾Û_181éQÜœ¹îhÒ©ãzy7º{Í0 û×/ÙÂö~îAAuž¼4›°V~ÂñÂ^ 1©âÔK¡m¤Ì>õ Hf·»—ÃÅåôše(c³akæWw(ˆsÝá?œq«s tòIcJmòÊ*æwdw7ƒ­!uŽkdu¦|‘Ú0.›Þ°æ2 ?V< o¥µ¶0)ù@®,ùÒ*C¶}– f,¼–ù9F¯e'+<ª…Uz³¤ïúSOš«wØ£ŽOŸ)ˆ£‚`:Ê·~Ðüä åKÚ³äÐØ¦¤Õ̺¼}Å{pC¤¡³Ëø6Ã@­ ´ï‚•­:Yÿöê rŠBbSõ«%ÑÊ`pÑÃwÆ?}tÐËw×½…\Ò€©"|_­ ðV™Ý)è<»RD£žY¨dº :wJ0›ÖÜáöòÏ-ibAŠ•1–˜*–¬ãWØÿäOxrvÎzÿÏú³_º€fÿSüÇÌW9lõ[$þ}ÿòÚÜü` K&ø-ØàgNïÿáþnpsƒà†qlÖäç ˜ „4Œ®ñ8ºJÙ¶Ž–^?ŒôÈ ¦aO1›¦($Ã`(0ns•y&h¸Œ‡øÂ¾0.ñš?0Œü©{É}T\ÊàÜŸà©’Ú2D£À\¸&Àezm¬¿zÖ †_6A±GNš\=/ó  añ€sBH£i9ûÆ£D¸™Ì΀6Tæth$a †Òʤ÷gyAPþžÜ[ùZ(ЋòªÃy‰›UÚÕÉK½aÜß^º€µ‰#íåêQÄè…z —a Y!ª´ Y%ò¥O3·›æxêÝíÛÚ‰Q`L^™1Ÿ¥pBü#ס›—R:¸‚Àrº“æqøé½5”Råk?iOÖƒê¹å|ÀGJ>ö¸û€ñR€V°hJ^Fç (ügX²<’I„ZF@-'öîÇS”' ÎW`LºŒeóì)‰æ£ràŸþkV¸† €uqÓ  5´Žp2‘NA§ÃŠ›FÐßFI8€û¼zí¹û+$ODÉg$„:q*?³ô]vBänRd£…IvYTÂü&~Ì"÷øöÖL„ž¨C#yo$ tq&j]Á$ØK]\ .®ž!è fÌŸ™ÿN ”¿d è[1Âûà~P €”¼ï?s…¾N!š}þé1z¤o.z×ÎX;?j¸i‚D‘ÉÙ•Qð—©?>»Jù½+|ìA"ìùÈïòl8¬¶´»ŠµÈ9¼À­'ì‰v¬‡p"{ëÙßÓ³Ï<•¿y’v¤Éßp'?W8Î¬ÅÆM•²ºÂ‹ÅÀFƒÎ˜¯»+ʪi°”S–Ô N™¬å{`NôdA9ö¿æd<¶Þ ³‡ç»‘f7m’'0.~Üõ"mœ~éj’>‘ýñ^Ï'Ÿ<úã?WXïÉGk„'õ ‰ï®~slÜÂ:¾—0Û0Y®3– sÙã÷ïëWñ²¡g6¸'Bæ±P‡»ÃìMB!ÊC2 ˸‡oðƒ–*KFSApB ;2Š„ÂzB¸ÕK ‰'Ý«Ž@ƒ¸‚°ulõLx{îtÉl]™ÐÏäûN+™ÎW8ŠQ¤Šá·éPG ÷¾"¸JñË÷[~‰˜ì{¡¾A¨½œpvþ “þqöqÿKý\îçV¿§lìÿÙÞ7–Ee¾¥°ƒ×ïƒà÷Aå÷P†ŒÙÞýíýk…kí3f_ÿ7ë_î7·ƒ9ŠÀýðí`;CŸ#<Cæ9Aƒg,{Èø¿Gò:Þ¦Á›"Óì§±ùÝ» ÏÄÀàb~Æò½ œYÂ3éàv®ß2Àï˜5ÒSº[ŽÛ˦7ŒðËf3&Öøköð”? ~xõ†J¹Y…"Ûà$võ†T4Šts»0÷ ~ÆÍK(îõ¨Ùœð02Y_˜Y 2£fõ>GÀ<À(y9Û{~Ëxï[–N²ß¹ ÄSöÝ:Î|,Ý@FÀåƒrj·4ÇXC%YA…qœ3 NÐIo?Êô~ؼFÀLrûv>xý›—ƒ7¯QäÜÏ5ílvÏöµÌ¢†.S÷OgLž#)eíÎò{]·Ð{³}ž±wö¸z~ & +`þ¿Ù ^¿žµ^6=mHwó!{ëp€udý´†}¢¢8y?T ©DÚÁY ¶‡Îr#àRaßÞ ÉAX‹R‘¹~B{ßH"—´_*$š8¾a„Ð}–LÀ»y­2½¡ç,Ø”g×~òÇŒE_¹/{4ð]½pz6Qþt˜ör˜‰ù&(‘™˜)¾Jv V‚ Ãçë‘ã‡ä½BñxýŠ!@‡%ó fnL¸##}1ñ%PYé£í_°ê{DñÌ¿¯4ÆáýD?|ÈÃèÝ ú’Vè¥ð_ÒÞ}²ŸJÀÒɪ@ËWɳÞâCýý¦ÔItD‹¥Çü½×I¢Ã_%R<Òš0Ñ÷aîé}ç,çûÉOÿ2ÐÙþ.÷û‹¿þûÀc·øÅpqù<Ð}þu*®÷þ(Àkzp?N È¢.õcòŸî,7ôü·ìòÇ¡;l)Ã…Qðv €½?˜|¾<Ý+ ’/žï4LŒç²ø,ØsFƒ Ù#×?§éÁJ ¶0Ø "ßß¶ÈËÔNïš?ͽ,kV,¸ÑM2•Ó™y.òæ&ŠhdzìN@P‡kʸ¾\+~qO¼È×´NZ “ £6y‘…=pKõþJEè6†á U8™øgYä#Á¶Ì§?2Ã70K+ê™^´!”é–Âv{°¦¾3Iެ€[cXaXÍ™ i½è‘¢qÑNP”ö±]7àÀƒæ| åÕÕ”", «ôæ)}Ê,wmî¸^ÚŽ”•rYÍ¡'eow ]EÀw”‹±²ØÖÔ#ÂĪÙ.ºA³?Æ‹|ö]*ºbû„Þ=r„/’OÁëC ¥ œ°iÑÒU„§lÃV€¦úÖS&3Úë÷°&ç]¢f¼,ñ´Ä¼Üûï3¡y‘ÀPèûOÜ•ÎÈpusÕŠ‡4UAR¿TQ6‰4Ø$n[E£OˆŸÙ ¥c{ö>H™Ö[!W`<@ÃfmázQÝ8ý¼Ï0Ïͯ+jæ–Åë½'xôì:¬¿å—)»G Í|_0磎×w?ÿ‹«k&Ož.±Øû÷r'ý3ö˜ô÷-Ô}/^à½ý‡/ÔoTaçF:hðd»ô°0Ù@{$=cÈÄ„!4^ؘVrjÃè÷-Ô±6à!®ÅK[Ë–:n‚Ÿ$xõòˆãð…K7·H¶ŒÇ=¹NÓ¿ãß™„IÊüA˜L@Ôäï%¡ìÊQÝÞËB©|™F Ž*lžÙ`ûÎ 7½8iyXñ©‰ß %Áü2t®GL¬n*±-SFø]N|t= Éã„\¥|•–ƒvœó@oßû(_Ü+ü3!“ö°·kZò–À*ðž”ÕŠz!´µfÙ“·óiMÓÑIB=ÄKØ]¼ñ ½Ihžæ:LÌ'¯Š¢‹Y|ŽRÝÔÇzuûˆLŠ!OÍú¾ºî—¸ú5ÿ¶ÑÙ÷¶~‡àÑülŠÖœië.^i"ÂöóÚ¿7Ïou&Ök•JÛ;E°ÛËÏò>&üeÌ?ûý{¸O?ÞwJ¹Ö.5L6‡Ÿ÷Kƒð~éÿ½—¾›ô‡àÈ~þÌú`ÙŸKéæXVø;f)?—)ÄbKÀ"Åû7*4Ü+~ï²½än ŠÜ§/i2"©˜aÂF…{¹³œ¹”™]îXi#eæaî0xð\³Þ}Ëx÷†q^ÇÊPÉ;L,TîY…S!î}la,‹ßο…¯4]àw(ö:™¾Éžn7C«Ã„ ‡xz}Ý<î½È8;Üââĥ㧇™&ÌX¶áaÝ@Ë2ÿJ‚À0ŽÃ!9¼E.“7UPì jÀ‘*i8{üN–tbZp § žÞ§L½6f‡`ÄÚ¶“9ïCåÏQ‡Ô…í± ¬¡±¨Ú»u‚¨$_3²pÄNzkNn´®Y÷ˆmc$í:AŒâ,[×@+úP@ÓÀÒ<Ôߥ}Ò\%KÁÿÀÙ]ˆé †Ã1ötmËÆ ¡f%íÙÛ«u TœÜw„¥$+WìúFééÈ€W— ¤U•NÞYycmM´Ý}4ŸOQ\ë¿Jù8Óٜ͑,ˆ»Ñ°WœŸÒΙÆçæç}ÊÚEØí|vèödæá½Ð2èåÙ$¶“Ï^eÜñ¸\¦iΚ&/úۻWÁ¬c¿ :¡ïòê‘ów¼ÿGü ÝìÇÿ–û˜0ÄtRGûú܇Bƒð¡´Ä÷€‡vÃn~BÇÿæ·ƒ¯Þüjp;¿©½ö1ù¿iþç8sÞ®ð(WÓiÂv¯—L“õäSI÷Oi㘀ZBãÅÝÛŸ<Qp:/ÂÃýÑÞ+\Ë0­‰Û} ƒg8âQ9BÄ(ØÖ±»ºå,Ò-ažw¯nÈ{ “q̹Lär3¢0øVj!d¾ü£8Ä;øõîP¦\9µÌÒÞãÊ^v¸gá¨0qüÝLɲ?Íý“Ûþª”¸PeÁ “»ë™õ™@)Ç5_WfÍ“KHÿ™˜[‘Uˆ)têÞÄÙÃVŒÿbp‹ÀÅ´aèVÍ·,ßdA3æ„Äã Ë©h¿&’£G+?LØ5)1 *–ï/Âïqô¬ „Àç=ÀÂTp-aÞÌÓ ýWŒc³RtðÕ?/³¾É5_Þ³W>жpá3 ¡æö-ïȸZG¤N†%ºDÂ/Sˆ³î.?Ú úå¾À§÷ï|‡lí«`%Þ‚9ª”&ýññ‚ãÝlË;g<^‹€s²@§†kf @*áûžó ‹]s76ÚÉTèHšWíÓàkuD;œº‡irFx8SmZÁ¬–¥˜(l=5;ß‚Ÿ ÑòZ5˜RüïªKA¢ÆYºŽjW8Ш†'­›X£„<燂@ƒÂˆË÷sâFF**f¨ŸÓCZæ¦wh)ù˜Æ|¬O2Уå L[bö˜ŸABö»È:ÿ«ÁOÿü¯ôæsÁÿç¿ü»@×ù»ÔÏyYò‡é¡çÁMò>ü¼ €÷ßß2…fýÑTæZàä¶³†ñ­ŽñÇ ì\ø' @CAîâÇß/¿ÓôþÉÙî ×žË#\-cÀp•|àD‘Ù˜Ôž”qÒ³–»P ³ørŸèƒÂ}Œ›¼¸/ €¸£,0æ»aÌ{û€`ƒÙÁÐéI$ßÎDä^qÄ’ ^>sOq 7B‚)¯YD|FŒŸú£Jª¬IïN,„¼u_§ÙßéT:cÛ¡Dx,FL%ãQ÷AÀÌEÄL¥Cj¥?Ѩp€&.פM—Ê!›$SÙò²èý"…¼j*¢T)?s% ¿“ä&n›(uø%Rm*¤03Ñ’¶wMý‚yÕ³­†4¿=’—ò=)†q Øm(/²¤¿ d¹£÷8ß‹Ý0tPÑZ¢hÅô¯2€õaŽB tF»Š‚aQšHoy ·+ .Z\Êg¹¾‹†?YŒo€•ÓI€’9màC)†”ÄŸj„4*(M¤·ºò£BMÖ“ IÝò19ôÄ}H õyß}o‚éõ“ãZ”ÎhÞ÷go÷î²ïzÔý(d_ù´ˆÁ‡‹´]œ¯Íº|%ZœžT)þÓíœ÷F†ž(,ó«Øëw¢ßåuÆú5ù_pÅf?BÃûþÿBÛC×a?ïà½7Á÷…_*ÌJÓy„ZÌÄšk™è…ùxcO[fçÇ(ãóãVèñ…ç÷W.—Ë{ür®~í¡KOa“üVO³ ­–q¥ ˜ Ö_RÉü½—ÁæžgpË$@˜¼³ì3 ßÚÝüLK7&U`ui ˜»˜¹›ŸÏb•ý빕ž0½zÊÐ8‘fbÿȎd”ò,ÓYÕý²÷”º˜Ñ wîBp+‚Þ.q ßÂÙD…¯à:­¤×Óe²&àiKÍü1¿;âŠÙß,zq&}Tè„)Hš:$#íW›à<Ò{vè@á*ÚAíÛK§#Œs®€Ï={Öü»œÎãŒ}£òŽUòÀ×Íd™ç ñUlÜ™Ð½í¼¿1æ凰¼·=[%´ÖRã’<­ dû¡w+ˆ¸å(ȸêÖ=4¼So¼CÃü3zs±éç{€²çõ« ²*€%hMbµ ߊ‡›g¡FhÒRÅ$ŽD­3íÄíPôf÷À}Ë(xr¿Í¿n=YÏ"øóÐßA¹‚J“4uheÈj“ãö2ùŸ°Käìô2›üdÌŸ¥~3zþSöüwŸûû;©4+.:b"qp  ÀÓÿˆøag¯Æû7Ž3{~ÁÀrÅÌúqì8ü–Rf³§¯ÈåŸ&|ŸüÃXp¬ÜË@jü·C¡ÅÁŒï ua¥6¥O‰T{¡,SBhP0ªn?ìÁC»+‚Ÿüéu*XÜeíþ Ãj™¸ 16!à$¬é=ÅîÕ!e‹HÕÅjsÏop’f <ÅÁùÈ•:'‚‚ƒË³AÓsm=[cý <£4zº´¬Ì.¡Îl3>­G81VÀxàe…<ÐÈ\ ©Þÿ*7ãëðU¸4ãä3Ú“@é=jÃQ+@êG+fž€47M.—ûÎþNYásØ)Ïž·Œ<&cptï{•È["‹ÛIèîŽÛF™¯a4F( C@‹¤ÔË<—nj$¼YjÉI‹BŸæ°í#€º¤Ÿ1ÔßEÇ£G ,ŒõÍt¶"yKBigzçÄ‚Dñ¨¡gJ8ž)GRí­OòðÙ0!’z»ò[qÀ‹·\<ñÑ¡ßGqR2^7«[]•&•›ÁK…07‚æȳñõ~›ëþö¸& 8éBòvï³eRöû݃q oüªmo{ï …ù1Âýòò“@'„؃#@IDATü9ËÿÙ5³ü3ö9=»ä}a¶;ܧæ tlÉüà>8 €®Iþc…Y‘ÄþæË‡ÁË×ÿ’±…þíâvðõË t¢×˜ÁÝã)crl¦ÈgdeÊ/Y—Ï8=Õ±*!—]ºøèëLJÆO8æø7쑵ä1=Ë."0·9™Øqô³/Ö ó$ï˜úa.S”ï5ýºŸþíÝÝ`Åû÷wC̵¸GyárÛ#Ƙ]bç:ûçŸ_Nxžª\²YhEaãØ¯LÖòáhZDŠùQ¦ü„av‰e—Ìþ^Ù“ ]4â QÌGX2/ÁewŽý»5l6þ¡ ÇŸw†¹e'Wx+Û\#X-@?CÒåK |¡9 †ÐPµL¡ \ ‡Ñk/¨Wô”Okw^‚†bɇ{0k4‰@&•¥ /6fH^"¢õå<(Gj"ϲ-0': € Ã3÷¶gžF&Rÿ»· %Í÷˜¸J8¡ffáåe)h w–F{Ïâ)äÁðòô—uûm¿¼x¾ßÆ“Ælßh–©(ónˆâ;z;% ò3!ñS)[`á)¥Ë9“ÁåÉ%ÐÿqLû?ÿÅߺ»Ÿ“ü~úó¿©É~~Íþgìÿ/ÌŠ2V HUØá÷£ÀAøÀä?‹Žo·,ü ÷m€ŠŸu„ ó9Û¹´žŒÂ‡”ƒpØ" #/ïeôÝ`Ìxª Æ…Áp­>C}P 2ŸÐgŠ•§ñ—HªX¡ÝàD°ÚÖ rmu޽•c=ràŒ›žÖútÅ$,ÞA`<ÚëbC— ½Tñ±7ÞO0Œb"‚IOLˆS‚Zzaú¿ ¡n(¨È-u!ÔWL¬Tø;F- ²S¢2£tTÒäõ£¸.ëÊÎÓîz\å/ÅÁëYæ›ndÃs¤ "¾¸ÖoÁÊ_…JëenÕ¼¼·7Ÿºpß Í#n¶GáH¾ã‘®seO­©Oõä©éœÜç¶¹ ^‡…T2\‚çn|ââ°˜Ûû…¦;Pn”B\©Rø”ÀãfÏEyÁÜ¿¢Ç¿„¶æëåº~¡ù;1qËX Â[¥ovæ^þöH}›~²°a6šßCm½qÒ1½¿‹\Ä ä}u©É¨ÒÜð‹ çÝ+á/Ô*!¼HBýÌCç¯ÅI%EŸ˜ü±Œ¥‰Öiæñl{õa¡úF«,ÍV´þMgðwE±ŒXK xѼ"÷ìEÝ×K|âGü«e¨_YKøžT:y?´Œ™A9™`î?9gÌŸ^ÿóYæç®W×/Úîeòw½?Ú·*ò]ØVèá÷ýRà ¼_ú¥çS&™”ŠÞ3Â?fî³ìK®£#*¬K%@!^½]ÿ«HF4_âÀ!б$‡Ä 7$Ø\è=¡˜¤ž~ö2E y{Þ‰´ D˜æl‚,é¢×„ ÕLkÏ.‡„¨IÀ„"ÌõHsv™˜ûÉÉd^Z¢P r(‹u‘ûá,w M„Áï€e€ÜçÇ +W͸Á¹zÈš£=ù­ ó M(£÷jõûN—J÷Т%áaÁUV#Lž óÿ·¡eÖeI†¦N~2ðXæäÕ[Gèi8íãŸAÒ\Áf#gƒyr™ÔrìÁ;ήp—éÙKø*>JMGtÞ*ÒØ{wgHÛ¸¬ÞˆG9qÐi}¨M•´b(<ë ^íý1½k÷ÅA+Ëeï¥dÆ¥EÀ7À3|Û|E0XU=–âÕšÕŒÚB¹Þ‹¯ o¯>‰ñ n¡XØ6ÞG¡ª¼|×CÔhQ()âÈ«ê´󳦯ÓYÕ¼ë–G€ïi¦¯´pãô¸Þ¿ãžHVÞß|îy|Ãßr¼  ñz\ tòÚ¹ßJ)÷õWÛûŸ±§¿ãý'ìäç?në›õþLüsý¿qF˜ýµz¨5Ýe¸ù°)pP>ìöù7±“Y*8…nö³B2Îéý?<¼-%€ÉÙ#Þm}áfïjúÚ[ƒ ÈܶYÚÆ~ó²GÞ{Àn “KŽ%ƒà{ŽùÿÂÕgÙÐü¤öÀvüî§0J|o˜*½h+¦ÕöÈÅ’£mYç?×ä°vkÝ«g'ôèÚ«™h@|µ¨,éj!x¤çø–2Ý–5;ñ!–ôX5Ó‹·x<’>PJÊ›pIžJCzÉÆ§~®yÏPÂÎãwÝynáJžScâÙ;ÎüÛ®Ž†òg RÀ`A–ë´ë)(½‡F¤!bÝé%¾ =ˆ—ÕÁÞµLüU¤Tkˆ³Ñ¤m˜¹xÊ­Ÿ=xËég¥VlŠŠ×tžg{Å8Ï7ØzD.4µÌûS·Vq¤· =åEéó¤Bv„”s ]ç<2ç¤&’‘-ÑjÂÑ©·-XE ŒâBÁSÆø#dI;EèŸ_*„T°[±ÿ “û‹]i—HF9ý¤Iˆ!í¹T,¢”Øö\Þ ÅÛƒ{2Ë¿H“:eIàeµˆE€gé7Tapëp(Gs À`4§MÄAgùÔÓi(¦òÛAWÈ hQ¹-çóžß~x•’Ñ£ïÇåUIý;½M›9$Ö§²¤Ÿáå|S¹ïïˆIçôüþ'§§Œï?œ#ô]æW{û?£MjÙŸÛýºïÿ‘C…•†wði¥À‡Kƒðá¶ÍïÀLÆÄ6¨kVó+Lóx5øÍËÿ5xýö×±(5ÇLÜ9?æÌS·ë2Aç‘1Ó•ë¾÷Lâbùùí=,m=8Þ²Äns?†IØËšÐ#ÎÒ%˜‹ìÂÝ…2޶µ »˜’cÆKî…„’€®!ËÖMA×kDZ¸ExÏ9ÏþÕ«Wƒ9ýÖ,÷ò €Ï¾|>¸þì<øÅ„ ž]¶ܼzÙ i‡|ôkMø)?.Ç;cˆ ËòÄ¿æë˜éy>Rœ¡Ã$©ßØ1\93œÑ¡ŒcÆB{»wËÁ«—7.=óàŸë+v5Fá`¼UÚ;YÍ9 ®ôHC•J©âŠE5¥Jù‘†û#h˜X„ €„vòh‡kØ×_ÆêYô¶Ã„qÙéŒ6qš˜nö”£œ7 zÞ‡•®Ð¶G[E ­£0¤- gº¢Á‹,ÜÒ/1¬3s8°°”Ð Êþb¨b0¿_EØ ¥u_8?‚¶Ôy(mÕé¯0vÿüe®÷¤F„NÙ¨PÔ”~uí>]àŸ~ÁÌsö~P01±|pþ¬ uZcc¸›9`v ]PðlOš+=~VÁ‚7¸ªß¢  Îd[c©‘rð‘ã {¥ú†÷0“Ó–(ÖÓ@ÉÍuÄœ µaóW>sˆ„ ÒÎü‹¶Yp)`¡Åb!žZ x›beŠgþ9:A5×e²°ßs› ”†ã¼·m„¾b*Mèdyï —&Ò±,/ |ꃂ$L¸é}çý pú;ÜB6i#{üçg®óWéš ®™à÷‹¿úÛ@{üçÏöó¿ tœß™þNüÖ˜¿ùø>ÜÇBƒð±´Ô·àãšp8w¶ûE xXÜÅàPÀ0æ;:€#6{u†yy¦»WÖ`»Ó›'Î1pÂorµ2®Â\àxùž##J€Eã/K‘/:ùИî*hïÏ k¦ —’K††€àY§ù?;Ò»^°·ýK„åôlÊEä!WâZ›Ð™øÃ»ÇÁk&{­îp*æ¥B”)Ž6ØœªØ…ÙóvO™&´Ãç¨Ð ,Ó[Är0P°ž¤w{Ô6 8Ëv–û …ø8çÀ:Åì«‚a›Àcå¨O_® ¹{ÇÅ¿ýõ<æYz(I¸âZ¼Š4–"s¥8.îaÞ9@EëŒÿà)”™Ûó—.ê§£J 4íRÂ?Áù1›8â*'Ü%R'=¬Ÿ‡è@Aò”FlÄ„‚ÁŸBß ˆ‹Ú.8NÚåá™"„@Úa)•-³µ÷]cüà =rñO¨PdzBž1~¾æþzúg—“@7±99+(ŽCÚÖ ‹À6éß±ØÖ¼ø¦`ÔcƒÒ %#N²«ÑÞ €—÷I+ޤŸ ôL{éç£ïœõæ! ô‰¼‡¾Qb%ɳ8˜-Ñø¼øI x/‚Ê«û74 ñÆÈø—PR'S屢b ½ÅÇty/€IN^ãöåÙúù'¶6É^1æ:žï,Ï®?å»<Ï¿ó«gÀ+êíê3xÌa¢Ÿôû8ŸêÁ}Œð›ÍÇ‹ÐÌZn®ì §B€ÿ.å®lù@ùX]|ç%Þ5úHC/þ²Å*&Ù5¦o]z˜w=%‚CN!W*ލ` _$/az%áHijۥTè'bYö…Y2ÁnÉ0€“ìäcJl25/{Nô°<À™æk·Â(ÊH %H¢'5+|aÀlXc” {¿ׄô3¡‹£oݘ(½T6>Ôœ­Ps‰šûhþi_®o=á®ýJýEœ‹bpõ›Ûw~ôïa߼Шcè³ŸÊЃ¦ Î ,Ä+øz¤§ Ž*DÖY‰£U ’'¹±ªEÛx«´* N@)Þ"ìh ›ÆÉyEkð ­Q¸Rž—\¡a¾7Á¹ÚÀžp&ûýÓźDæéÎ}9µÐ ˆSV¨ŒÛ*ƒÌ¾W@èšZ}FÅÎ*Šw.ü­O."E¾ó:‡nøûJÒ¼åL—÷‡Gâšçî}Æ?ï—~ ¨$‘ä=2^ÒG!îpH.ï¹t†u<’¹´×õü ç^Z%^…>ýêi\as=®IÃO6ì›.qšç·Sv}K*¤qÝ·¿ÆýO™lɘ?¦ÿV€s\æ7AøgÌâç»ÙaðÍÒÏ: À‡ÞBß…Ÿ Fïÿk®Çû.…tY–[ŒÑ™…M0yª­Ó}Ò£’«¬u+\·Zu›ÞæÙ»WlLÏwÄú¥ ½€áˆ-=aÀ2ÚŒ%{ú\K–¢õ"’+œ5ÌA·}ÄQŠœ Æ¿Á☱uzجVÀN뀳ªGö82–X¹éÊeÜCL×÷LFâøb7 rceS.OÓLྀ\2}{ØêªŽçbãΖ®»!Ó™F&F¼G¡ŠÄ‚¸ž¨…#NNïm+@ÞLõó#Mt$m®„Tòí^rs+"Ô‰[Ýä·~Z˜Á\é}Rˆ=s•sÛ°¸ œzÕ"±È€§qS¶L:H“›„À¿&-échÕçÂscM ™Jõ5©?öx§¼Ê8¾)9;Jò1žï–$Ò}+Ð_)²iVÃ­Ë ‹ÐÉ~3ÿÉ5[+³Ìó„8le;`ç§øîn‘öfOê€0¡ímÁ©/¸‰:ŸÃKx[ ÊÉyZzŒ‡ŸSLœ“’¶÷ýw¿t*Ó¿%uWm`dɨäÏqÁìHŠ)S{ùZTH”ð©+·y æOùéWþ‰Ú*ÖÂýŽRŽ5Æ¥n¾ß©!¶q] &¾1£ÔèA˜JH DAò½ò±-ÅZæ£fÿý®ØÛ_èºþkzþ—ÏÌöw€«ìù9œè{U´ ƒûH)pP>º†+†¤ø]³½ïýü7ÐÛìðæáåàÕf>xI¿Ði}cºŠKöî³–×]¼dGìÕ/ÓX³iË ¦ô[zßoïƒo·¯ßÆ<>ffÓéùÙàóŸt Ð!~Óg0=2\ [L˜ ã2:ÅÙ*½d%Þ0×õœ`6TQ¼% èÿöùÿú7_Ê­g˜—OÃl\z„P@0»ö?c§d¸Y¾ø/®Qw³‡.Öƒ»—ì•t¹V„;æ45ÅkþÌ,~{œNæ—Û…÷¶;ŒÛ^gIqtU œ0"(²LŽ|4û+@†NpƒÛGe N–½…ë’F% Ü<¹[B=׿ø÷Ì}’H±ïVüö¨ñN8&npÏq¼@dJzÈ'Ì[£H¹6ɲ9i¡ræ.‰E"’‹¢‘(n™k@Ýó…4KçÖЈÀ:ÁíRh¢i™£9˜1ÂqnWcŒ˜7²b-½æý%x¼¹Ñªí‰ë«°hPY1&ícøBgõ;¡ï³/6ÌËp?7zö ³Ê'ç<ŠãC?{Œâ +ö1HóðIn°-¹Q¿µ}@Û¶qÇ#ºçý+(žXµéÙ( TYHsa5š…Ê¢ËQ£4Æ/žTýytˆ%•îÁ@6˜u“ÑæŠy0'(DS™˜C•7©éx?èrÙI–4±Á‹|”ûÝ¡WØLq©ˆ«¼èT\&(cQy¶NüÛZ•¿ÑO¾Ü†R¾ÓV–"Èáò{ýWLøûË¿ú»@×ù{ŒïÏþüokƒŸ)Êw™ÿŸÆü-ñà>V €µåòÓF XrÊŸ×Â{þ.²‚ÃØ3Ô0ªµ;™ ~À÷jou óðL€%‚3ë°¢2¥%ë²…c¹ÙÒ~þ “ó`¹GôÌ`ìf„§·KoÇ=Ž˜XvÄÞò%ž`vN’7™=!Æi…ʽG—{ÁŒ±2ÌQ–ZtÑà Ù_Åd„‚áx¯“¶fçÎê·×C:Ìö'”ïäGÍòÎÒGT/Éω„KðJG ¡`R¨ÅœK]Ã.äŠ8…öô°LñEÀ 4v2Ž›} ¡‹µwÇP >ù1C˜2™àµ‹†·qÅxÍkÿ>^»Ød îfËÊŒ·¢«¹ÜµûÙÁ¢ÆÒyæ¯Ìÿ lcë´è,—¡þ ï–¶>§6‰VióK}¬c²ÃC @iµ¸Ã@‡‰"Ý9‹’æ~Ç¿1*ªðfÐRüˆ9b#“g“Áéï(B_óÿÉ•fh¬4 Ã5œ>˜’—2bêë{² ‰çûª@¼Ò³·6F¦ž ÿ{šEãÚIyâ]+¸Á)0­_C?ó8 êWbùh$þ­/ò-Xwï}WÜøGD=aÍ{ï'z)+érßòh÷•7–Û]„½)p1Ê›ÄÄe%‘UõtÖ£†4ž2h¯w¶n¸[ˆacø‚'ýÍfgƒgÏ®×Ï?ɘ¿ý\\>ß­óWa¨±ÅFér>ü~¤8(]õ(³Ïò?¤j ¸”®„†sãívç» —E` £>åD:¡æðå{~˜^…¦w”_ç°8ªPƪAÓÿ–åb}›ßptJý)X8™Z¬¼È³ù=9ß /égpc Ý!`ÕÖFîuò_“ ‚´7¦¡Îǹ@µ´œ²Õó'Ç(ÏÙÕï‚ã{íõgÌeà0æ/¼î |Dm›1JlšÕ󟳦úõàë7ÿ4¸¹ûбFžaˆr˜éð¦Á¬NåB%€±U¯Ü K“1 €¶PzÚcÌ­òW_bÇý¡Ì„¼·ƒ¯ÿáŸ]¨àÿ§ÿñ¿Q,à‚2„ëùçLÚS›œ Î~BÏ è$® s.ØÄG˜^7Âa›u1Þ%{þÏ}7zÂß’cŠ]þ'”¹ùç’ÆËIÉŒ|LÈÄ퓚4r»–A¦Ž4Vb šžã«‘)»–=Ň2Fi@YË~פŒ½[ÇØ1[¿½Y2 ’uÿ™SPÃ[ê©%"¥BÞÂÍ\´9ìÆï¡eñr¼0_ %UõdMÝœç³ñ´Hì§KùHp¶zŽÝkºŸ@£K¶ÂuûcÇÿïùzï¦(H5éRñ€;BΡ“šÀ©eŽ¥À$o=,Ÿ= ™Sž´•^ä‹à0o7üqŸ0p»Ïá=„AG×Ì›W¬æ}H ÊæåpðG?›.>anJä1s>®?ŸºçDʵ ÌPm 0HñëÈÑÍø½˜˜î_‘ i#ÓÞßIoÞèá93, k–ºšAÁŠw ‘*[ë«öÔŠuîÈî^¿V¼~*dNž`zÂÆHwóÔ‰æ)ïP—òZ¹ú9 wÏ7Ö«d8ú]ác~s¼ÀÙt*y"ØývÓ`2‰wƒÎ™9S™ò%@É–B´ƒ˜úO_¤ƒ0™ÌØÐ‡1þ¿`/ÿüsÎqx6øù/óÚów`×ÿ¿{œ/H܆à£iJ¹ˆÂÊIJe6ßYo9ăa€ ˆ2¦'‚ oàrŽ—;µ”aÕÞþ@&ŒâôŠI‚œj⎀Ä¿ç”/Nˆa¿}=I'>°Ö[ªàß 3N{LÎÃx5½#”Ž˜]uÄ4k™¹‚/›ãÐý”gi^'Ã(k†U"ü‘\2±XˆRë–I ß¶žX%ª›gýeð#–Òí"nÀŽÿ:ñÑÕ2@ê1ÏB¶“åŽÇL Išnà"´÷ïðÒ*8¸<2d³¸*24Hº.œ‚8ñÒ+£øŽ£:qz9=b`(êí2Ê|C{¦ç€, @ѳã™j‘—3ü¥™–!‡kf¬à8½âݱçÏs‡.C“äk¬C¾*©Kaòô›2y4ÿ6»÷¼ úQW/ó+e+4SÇØ,Q. Kžc †6ægÖB÷yë~†îù1o¿:ÚÅŒ›ý¨·0¡ÛÊ÷ÃvÈdCÒd¯³À¿[kŒ¯—ñ}¯ªiú/aÞ'ûÄAáD v£*Ëp˜oŒ²¦.Dá 9¦á>eƒ0…û€««OsŽà¿d€Ðýœè—þ$êÁý()pP>¢f• —ðwÓ¨ëþYGï–º^N×Ú0Z&áŽtòIÇ×·±øˬÝ8‡"ÌÁ?Í®éa7»ÌÑ+Û¶}œ¡8©ÌJÁ²bSÇê·r* F à-(l²£Ð^³qŽX3£œçÑ“Øä@šÝeFXþkvÜs]¿RTBSÌÃÒŠ9&þÎ9À#qú³â}Îth¡Ðd"÷©W¿Ä“!jÒ÷‘,³5*e¾.=S`Éïúe²w¯¢[Ç´/L<~dîßå(æçsù•0y'ÐM~ ëD-òjJ–Ö™N B" ”´²~**"ã‹‚¼ç†îÊínêoç/Ù3CzÛ©=0í¢¢TtBÜíÉ5ÊŸ8ëRTµÍ£´Ø;wé —÷¾&5^Efow÷ÞèÁ?ÙöËçR,)&Å¥‚iÛ¼KõH|.ÿ GÕ‰´Ò€<"½Ä·•!ìWðпù¥,èVTåÁCòÒŸßÏàÓâïßëe¾»+i¡‰é’6IÙ‹Äg÷ì}„?0ß) Õ=L›r¸qÉ^áà‹cý'XïN˜ýïxÿ[o3æ~‘%~®ùß_çO.•oyøýRà |$*PðºÃ_zþ˜ü—îý︽3à¹ØùŸùv.,™«`[/X WGrl1e#‰cÒV&Ëx6Ä‘Aȵ†G-,³SÆúéé?{û–žù¨ À]²‹JÄ3êóüÝKÊgKa­ K”6¬€š#Ýë| ÿ¶ôü—l¯»ä¸_õÙb»v¼ZDÄ,ŒPe?ͰQ:*˜@òáÊæ2FŽS%e˜®¹lìÒ©N¿3ëø‰¦ÀJ7’¼ˆ5Ê4 ç˜cÙíozÌÒ3⨠dG;3 þ‚ÚA1^Mü 4BhhŒŽ^pèÞ‰ðîáÙ÷fàþÉY¤›ë @ñv•D¶·•Ö”**Ö5“©wLÔ½ÌOf”GÉ‘gËŽ>ÐÂz/?Š&t×Ì_«(œÐcÌ +Ž0ŽtSÖ심Íà±»žöQ¢,8“å“BheS…Ì÷ˆ«”KÒšŸy @jqðÚ±JÊs¹!‘¦¼e|p«4¶tÑ:âE\öpL¸ ¢¸@r |)Q×gÍG"aã†HRïSžõ³¢ 3Á;·yn¯Vîn»èÜX5=ÌRrCù¾‰ I¢„:Â|bÉî:à¤áí«ôæƒóýÖYï~oÞæŠ/«õÊ’?÷ó¿þŒ!—3Ú}þ¯>áº\0Ûß9*N ¬Mïup?f €¥uþfûß²Ö¹ºË¤¿×o¿¼B@¿~{"€%á{ÃÇmÆÆÜ½¤Ç½‘£ÈpáÕc,üBÌ3b-V ã‹éà'Ì ÔÜïîæíàüÅ$p‰"ᶯÿú«¯Ûö¯”ÁßKÎ_Úósÿí·.#œ²qÏ3˜‹ÐÞ×à çü߯ɵúpgÇÖG [‚lr³Å¬Ï࣠r,X SÈ9AXÏÞ;„P ]¹ ²#3•uÙ3V€¥‡œ¤“ËZëKúì•èÒµ#„ÙóaR#ãÄîh1ÖÒò5»«@Yr”K° pçÐmûsŒ²ï—×éí­Â°3îdn“BRG‹PAâ¿ÄC(,æ°¶1¡_0æëÞî°<©‡K£˜°doIæÊ4Ÿƒ.ÝæŽ“hGCjÊZ2 âj‰ÒÝ;_CRAÚ:÷@h›œŒŸ~Æ81P 挵Íþ@éN´ÁØ ŸB÷8cŽÆ9Kþ€ÎMpFº+A]%â;G<浆¶mSèBy22Üw"áà¤EÌ{—û¹4tÊRG±¬£§ Þß‘† l©¨Fª%¸IKw½–„ZQúû‘÷¢øNÅSÓÛ35Í™”¡†ÍùÞ6k‚>ÒÌÖ ž$%Ûå¢è‚Þ”ˆ‚1*ÀÝSà’£ŽµŽˆ›©óþ_m‚/J…eª\±q_`ê"ÊP$åùØg'ŸÓVÎË™ .ö¿øë¿ t’ßûøù§¿ t²Ÿ3ý=à§fü÷Juتx?* €¤9e€Ý`Ïßíspú‚Ž)}“ƒçf#O´Û H¶Ìžß°‰J™ë©¨ "R§˜†§xm˜Lßf†`A¸œž³(þn€ã¤·¯™ôÇf" –ÿÝñ¶ŒþLè¹oèÁ»)ÊýÂÜý`—˜Sv\Ÿ²e/7svCq"”Ìa²ºg®%k¦}a~:ë3­œRN&éO…W$ºñŸêÙß}á++vB™È+ªŒU ÷vIš=XO S˜QGWóì¸mö@Øu)ººéŽè…I#0ºé¸tìLô¼ùg^Ýõ´ñ’ëë”ÆݤW·Æ‹lÏk¯^9šN,zeb¥ø7³B/¦CɮҔzPT0´Ï1ä£_ °º ”ç 94`ç;èç†>éÍcî™Ü’žL³*„²GÜÛ¦¶s–¢8”ÕÂVPV¹ikï•çÀ]ï“À¼´ˆ´þ gé#îS(Ð¥‹Ç!ðú'’V"ß ÃÝŸ`Ì•²©w!©CÖ|(ÔŸVÎÓ3•¼š…r$‡N!ì½PGq8¿ÛòG'ò¹ìÒТÁÁU&Üêú˜ “¶‰Ö9­a ݼL}ˆÇœ-ÆwÁúZf/WÒä=šž¢0Ï“ÿììY,×/ÜíïŒÿþ®Ý Ð1ÿl¦fxp8(|3‡‹„c¨¬¾K—ÿqy¿†óoF,qÉà^°9OއµO¦ªW8¾“rp£­yàç†2r‘Úæ3Ê–¬ô4í©,9í,³’驄ႚff{$–hgCÏyÍ^¬6DŒ˜3À¶Âä/ó]²ÔÐ9ÎTßÀéíù8Ë\œeâd#ëL5=TóÆ¥ŒÎœŸ|r×z:Ÿ“Wƒ=¼2áÉ̼äu¹öÆ©›u”6öö$I¹Ê­3`ñÒ'8õ(ûÐ@œègïþ‰´÷#=Ë ¹R¡¢ohѼ ò9³ÞmO.HŽ _cûs¿OÏW Iõ$iwÿˆg›:ñ³ñ ;ò]&x˜Œñ5ç{Tð1«N¸Œ¨"™¡è€L³Ye…awýe‡Ëò½R a.ßé`ñQxúžp›6À/Jþ;åò†ýUIÞd™úšo«×£ï<÷¾ûA0-þM_"¢q ä×2÷¿yü‰Øûw,{ïJ™)»¾B›Ç‰¾­¬ùöãíîI ws+—ûyPÏñá?=¯1ÿëû=ÚÁïV¿^NòsŸé¬])߬ÙáùÇJƒðA·¬ÂU¤ÙÁJOÿ}óïçìúǺÿ'Ѱò)tZÙ£[h½ì2YPó§|'ÂL¡F 3÷eˆk÷gÓÓð’®ÆÃ[¿Ê P ”£R0Ä”LÇ>fÛ³ 'ÑMè1Ãð±:À;e_³YngOÒ•7ìOÀnnNH»¿}`+Þû@•™1Ý´)Ãn­Û]g”šG­ƒ‚'uIýâË“BÑ?M¶-NØ`ô B;'«Ü ¥‡ë¯xüP]h NNVÑ‹R¢iZ³ t2¾=ß\>aá½âJ”†Ý‡R’pÚ!8Ãè é8W‚ýÊ–ù‹m~­ˆÏ>­Åf(…%Ñ;6_{Œ¦ÈvÈûãË@‡_ýóÃàþa™2çà‘JR_•ª\àá»ávÐCµ&q()Î=ÿ$Ùòú ÅÄh=ã<³¯6¬=þ—ïºBÓ-¦'ÎM`‰ª†u…½ïy†rÌå×e†Ž"¨s*@ùb€ÆGŠÔí/Û#» ÓŸHžD¸üú¡Ú–:Ñ\Ó@ Ýàë6E_Ëã½"‡B,O“¿Û×J2ITÄ“tàûÊaT¶>e§gä}!½ù¹Ù×#=þ#4ññì|ðìùÏ–±Ç– }~úËÿxÌÄgùñÅ—#¾7…¿þ½÷_¥~ÿ(pP>äÖ–ÂÜ\ ç˜ùŠîÏœÉx÷ ,×cãìª#"³+Ê™ì2 n;ùÄ„µÓ»)f(”1Êg\JHlÊ!Œ,X Ç @Lè&¹ÑŽ n8„“ÛKï’¤sÆËKøÃ¸–Û;ö pM=™;ÁëžÍuV Àøç ÜaÊĆ'œÉëuüø?`vV#® S·cÒõH¯“ÀH¤¦Žldþe›*Å>¥ôäê4?{¢´RX¸Äбj{½¶vÃTœš@M~©{ù¥ ¥ùÎ¥0ž€q©w-ŽÙqo‡­¡øÕø&3j‡!÷À–…ãéÞvú8žþ-iøÐÉ@*ê\'s"að§íðÛÐéu“‹ãáî ”IF|¡míPˆC@Žó«xѳœŒùŸÉW<Üvó–‚rlç D³:¶_#º¸û~Bvª- §ÔNC‘Î3¯¼Sï™õ%ØJ[÷X€:j•̨YÊìÇŽÒ[7ÙsE+U.ñ÷Ýzô !ó‘Î’²¼Õé×_–ölž©Á*!ä!”fÖC%6 ÏEê“ìý° iÞi<¤ñ”ˉ d—]¥OÁ·ámy÷ù1n®ÐU%€Íþ˜é& ÿ“+”´svZ|>xþâ3÷ù$‚Þ^ÿ9 ·0g`IÚ /¿@8(lcÃŒÂJp-¿ËæÀ…Yô+¤U&¤ññ˨dö¤íÉA鿏U¬÷Ê2{ÕZÒ»2ŽŒ“çbÀ„ÃlFê(0³‘Û³sà(¶R£ dŠfˆ³GéÄh ôHé‘5æ«Å!|‰òíáÝz¯°Ì®P8Ï È&Ìpc‰gÅö¾,øéeˆÁ{NÿŽë϶øÐÀòÍ·ÌÊä/CF Ž@Žg÷W‚Gi…3ù…´äQY둬v¸™³^»«ãZ…GüÉÔ”êc»DUá-½ ã>=ÒïO•–w‡¸hjr½C^zÔ]+ø{öDI·x6…’Š“$ݵ/›öd÷>žñsï~ÃT¼Ô3"PÅ|«÷í{aÆO—ïV¿vÍJò¯¿í!ìt÷F+ê;«‹ˆÐg£Åþñ”6ßa–›²;WÉví—wŲÄï;ÜêßM\­Eþ½ŒwÙ¶Œ|ÿû‰ƒdoóÈ7,ç÷j E½wmM& qgì;ÏYüÎôw‰ß±cü(36ú©-}O³ñþd¶?V@‡âò¾Ôíá÷àms?ö2ý/`®Ìög“Ûýz=Ðû_²Ð¾Â –™yPÎÉ9G¬m&¤EA Ç Çµbôt9’foO T „- ð"¸Œ¼÷Êÿgn?ÂÛW7â¢l¡ÜΞšk­…y)4¿nìÝcròŠLÜå}÷¬xàä?M rÓãc&€Ç÷bÁŽòÀãŽyË cŽ5sœüRnÈ­w²±}Ÿºß‹Oœ§øæAýÍgçÝÓÑìgrykBv¯}Ɇy±zPˆ$ ¯„FQXˆ[„L,À‹4ZV<¦5^)Ø„-\Ü[>ñâ>aÂ8òJ]…xxEØ»9ÑÎ{ƒ=ËŒÏ+a½°4QÖíb˜zâKPg¾ó6²Ï<õôh’“!Oø—/Æ9®—g÷„àpÉÓ@ÒP9®ÓûÒ£‰¹V˜¬½Ü-Ðb,#JijjÕ‹—NÒJ3c%LËqH:óŽ¡°hmê šCfTd¢Œ˜ ”xo K$ƒ¡F#‰ Öa»o÷£o¹–¤eÐ}Ig[ºuOûè—rñÏ÷À‹QøQw*ï{ã•û¼ûe L €ÄÙˆÊ"H¤J(&ùN¡S\2#‡Ì|ÏF|û''µm¯[ûž1Ëÿúùç ~·ø=ÅàDÀ “ý&( üæup @ƒð½õéûñkòŸ3îÿkÆïXç?|}ûfðëÛߺáÊ~Ȥ·þõš"¸ž±«—>JÂíà†™÷KÆì£D°dðåkæ¸ |f¨Uažãð¼aœ?Œèèˆ%{L ªhØ,9,(vX7ŒnÈâê˜BÅ#p¸|~BúòÓ*€Èàwà† Ç§ìUtòãÂês6Z1¯pØ^+ÕT!Ì^·'LÃH‘ÚB"…¹“u9âÊ*µtíQé^1ñ/ë†P§l­ÓVîWʉûÅO¦ÛÁ믱’0P9£ÞâÄÇ ЃÊþpv³ŠPºùgá\uîB‚a¾”Qæ’BÉè–kÜ”/Bâo»-í.^4î·ßd„22+-´®8–n­b"CMìÙÊ™9BóSàD€³Úþå'ί޾cüŸ|ÎfN@{õ*sÏóR§5DÅ€´Bëg™7÷æ6¾|½b`9¸½EaeØg2£<&Z®ÃÖmÎÿðŽ¥xŒÅ[o`ÉÐúrëüa· m™—¡šPa·¬.eÀìÈ—¶zä4:1ÃO¼ûÜû!ŒÅÊäx ™S°ùNßGVºäE#íesäÂ/æy Ïâè{К …úÁ!j/ãDÙ!vîIç 饿¥´&H8l“ô¤uî…Ë8…:•$ç'½Uàø.Žâ(ÙL89½|þ“_ ð1ùs”ïÅÕóÁ/ù÷îô7ãºþô“–Œ&( »ÞJ9üü!Sà |°­³‹Àzÿõ=Çýù¯%¡“È$X[f/ÃaìYϰ8 ÊåWS˜ÝæŽI\ìϯà”bnÝ(c…£eóxŽÂVÀÞ2ãõÍ à_s:_Wܸgòè,~ÙøÀÈ3© ¡o®?ƒá][îAç_qº ÜÒ[Ì®\¥š"4Ã#¶2Üî,ÉëɽûúHÜbÆåUýÿÄiyZn¹R,\W¯>![`c²ð)Æ­@².Î׊ð÷‘ÈC”Œ¿’A€Æ¤™qC» &>û(öü»ŸÏÝ/·õPíHja­y#0mžj„m$xq¿B  $ c‡[H^‘›”«a¶®{¯ y€(cµ´“ }ø>Æe€ÝUÜÞ™ P%H`™ée›—xðlyâã Ý!A<×\Ó °Rx¥·÷®ðôSÑÓR!½uõ ¬€»4­÷Íú‘WÊl0y&ÃŒ[øÄb„WŸ `sPí´É;MÓp²Ü}'ýáwo ³œý«¡VñˆÁ/$q¿O¹-¿ÞDiYS¯üù,ROÎ÷-g+ðM{ï6½S–©3ÞÏ8öò?½Ìf>§@—û9³ÚNóË®~( »ïä)ûÃ݇!€íè=Ò\8~ÿr‹ß\‘:šyéϳ¯©ýˆ  »ùΆqwX+Óà¦u!À¼€¯z"!´ÁgIìæÖ…±\U¤Ë„]è…YEJÉäyB` e_®7WIQ⨘†Ñý„¹3¡xþûÉ–‰K˜Øs~E¦nÑHƒÅÃ’”Ô™aŒט}ŽV2ã0RngèzêWœšbɤ&¢á§3ÌœëVŸV(ç1ÏÞqÕòGy¡ ‡SŽ„Zš-,Ì?£¦\pŽÊÐðÝ›,îÍS2t!`’,wLXÑXe€lÒÃv‹[Óð,i#ðîí5ùCÓmqùÜsÛ·ÇEáïJÑ¡– 瘤ÂT]¸Ü ©h€R Kzè.¯³LqSÈ$@ƒV—¼;àh= MÁÏ> ZŽ(r0¡'3ßSßM1EgŸ} mí„OWÉL¸ðŠsJÑãTlËE×úS†´.|ȃX*© i¼÷l† #%úrHQùç(hªŒ:” D¡ö|´(I+„ÿñl6xñéç üSÆú¿üòŽñŸ?|ù³ÿ8¡Ç?Á\sqqè8¿fÿÚè§U(¥~x¢ÀAx¢Åû¿“ÉÈà0%€íÝqáç• ^df±„ãÁøàH®Ý†¹¦~ÅN*Zd Û­çÂ`e²a´@lÃe 0¤OÍ臕ÁEsÚZzU°dÒ›p;9¬Ïâèr_¸Ó#å¹TM–j\7Z1,=÷ŠGØ é1jÐÔ_ÂÜ)_³õ]ŃZTd°Nº{tcw96úy«€2ãtö¼÷1(Öƒ· “LûáFL`ƒ†ùŒÓÌmþQðWç˜"¶0c™7?dâ$ ø·ö9¹d¤Ê±Òæ—pã”p ú,9›ƒ¢Ü‘éì9— Ƚ=êż Þ5æ †qj­¹Â¨¾PÚ¹¬ï+ÌÄ»˜ñr9ÁtŒ™ÿôÜ1þi =þé “™å/TˆÙ~›GkYDQ°f«h5Ñô'¦Îöð—\nÎó[p¨ñzÒ[gó‹Àæä’CN¯¬×©Êð”É" Ï–K>2|eŸ¹œ zê•ù×V$2V(oµžW¨ {cD)Iû´6¢hß+ß],dWû$èAyÐYG†¶¼ŠŽïLÎfà½uîˆùئsí^ È÷,!p–3¶òÄÕ‰Ÿy9|¦’;fìå €3ú5ë_Ðÿ~ñð:~§(/>ùœö|F\{üNfb°UË´ý§€ÃÏß ÀAøAÞç#l2Å  >m`±pÂdô`f°&Õ]wd<"eSÁq1¸Žý'칇€©ˆ)®ÊÝëøóLæQìÝQpW¼ÿ7]qï…±'‰ Þ®ŠK”˜Úóxñ&™¶ F§™Ÿ‹Øaš}3tWµìL× SæG”žM¸%‘„Ý}×þ ¬:±ß´Š5^‘¯„W– „”*Q€(-šÓ‰_®á"^þÓZå è•qüœ²¨Pó‹ˆÍ†ð…ÁaÊø®¶|ÍÓCŽ»uÌÜêW„¹ÓÄÅ |Ünùä²fò;ËŒà¢8¯B;¹Kùìd+Œ¤•ʆP|2¬à»”gÛÍu÷ 눻ø!üÊqLåĘý·ÕÖv‰2ÞâÆc5¸S\œoXüi êØ"he¨DâÚebià+jÝ“!™0ÏÂw 1œ‡ºEÚ§ãâ»´/,ÍG…³;³2oécŽÎZ·Xˆ®òà¹Â ´öø£ÌøˆŸe&1@ed‚Ù@:13™ÔÖ¼šóö—×®ëwcMþ×lëû"pÊn~ZÒóoJÃ~]Èþàø8(¿“D¿Ÿ°øD™Ðý+L£ ¸#êƒ;ÆÀpÿÈA@0ä{–â­ ²édÂÆ:\{CkÖäß1‰nË8­säÌÃû›@-¤›°„0kúaFÛºfia”wŒÓ„ºEÀÄ”*#S»±éëðŒ2âò¾8nî’çAA–/CÌÒ?ƒÊ$e‚s×uÑã“ý+´Ÿp¤yŸÉRŒ ~òÓ‹ÁÖýÙ©×üa=øÍ¿¼ TÁÙ°eð×ÿ÷-é4‰:&ê^ôbôYá|Ì|‡®PFMÂgQªâ]°&§iá&?{ïüÉœõ»'ißIQšÎ`ðSæ¬Áù…K¡â8û–‰˜ÂÌ …˜âd wowÔ: ‚RA¡ÂScÌõìšýéºû‰š&ûéþ3öÙè‰ôw¬¹{÷’‰x¶) t8›i zýç×ÓÁ?er°æ°.ý¹½~…”¶cfH„¾Z€½oçcƒ~ ·wêœÕ1!ØD0.ïó’Ó)i7Çýo^“› \“šQ ™“)½TL•ŠÕ¢÷zõóÝ‘@&‹É‚ááî’ ã‚[…ùŒâû Œx9¼%¦zñË:|6œâ=˳m„´­÷Ó ¡±Ð:þÂá É+³³\€‚ú”‰’Ò™ÿö\ÐQ P¸ó‰U2è(ÊYOçZ8ï@¯R;;f7?fø_]ý1íÃ;Ž€¿d#ŸŸÿå Œ%àäbðÅýKÿ.Òã·×¯P½1”–~{w À¿àßG§ßK,Å6fsíöþUØ”6• Ál/1fq{ôÄ­¬\Š´2D-ôìÙ =†4Tø;TÐ,2èâ±XâobG?¯„ÜRŒ Üq0Š´ë–F” ÓÂÒóW°€·N“õ'ôϵ šü‹ù#°L°0jÀÞÑk˜"²‚4\Ã9ŠŽìX¦»e‡ÃÅÜ(Láõ˜Þ9›°Péó̼ƒ k’)Ðû\™}ÖS™Æ7 £¤·˜*—“¿Z”NÕaã,|$žÒjm›p­"š=|&ÌxôÚ…i+ê·LßœˆÃ_Ìøy²NöÍš´ŸÌèÍ#ÕÄ;»ðá÷(AÍ€2ÛWp9Ÿṵ́œ^1A,=,)ÇX ˜Ó`v%û¸—.ÔFzÛŽi=°,úkÒ¶¡ÄQéñÕñœ‡åœU*qÍ\È1õ'M”!pK5ÈJ½Ò8)ÕªáÒdxÔð ìÚÌX¼[¦Ú6GÜôé0øÛžø™u,½ žGÐ ŒŒ‹w“6ÊgÒòÇß=6tâî•!!ê¢2à˜?:Y qTÜÑý-ÄOË™_H®óÓÉÁ?@i¢ë7ÐòHÞé±4ÙÈ ó~&ùÑÛ¿zæ^þŸf(@+ÀÅå'±8¹Oa?â9}©pÿ €ÿ Õ~°40òF¬‡‰Øù)~é(z1©0*ù› ¿˜÷G¤ ‚—=g{ enjuS¢ FögÚšMMfáøxȬH#ÓŠ —í±IÃ!gò®+l”#üÌ` ©À3YG)€rײ”Is«@Œá¢¦…'V(ÎÌV؇y’>»ØE jp. ­ ²B=7(Q‚@ › diÒ *J~ÜÏ“@ia!¨‘‰ÚÂíýßC:þÖÛ:µ‹e¿òÑ o…¥#*,ÄSù1y„ áQàŒGÆ–“v%ùÿcïM¸$9Ž;Ϭ̬ʺ»Ñx5”Ä7;³zÚ9Þ~ÿ¯²ïí®4+€ šÝuåUûûýÍ=2ªÐ €@7EŠáÕ‘æ§¹»E´™¹ùe5¡»Cbi쟴`.ØÝÓ»DâóXv=$^•¥õjú÷À%­>úûãADýÝ;•f´[/$L«Fâl£~¿)„b*¿kRÊûÉĸ£ÒÀÂD-8õ®*kðZ##›C–˜þê'tŒ.&lQè¸HD^¡)C\ÞSK«B•Ü}WqäéÞž&L}BÒ›Þ4ùd‰ïÍË7 ‚q¸¦ÊªþöÙ‰ªœ}Ã×›”o…°°„>ß(ïUÿ1ÂÛÕýÂ\ßË ~ç—(Ìí£è?=Õü¯B U“?;SÞžiåÁKC&7QàGR`R~$á>T1DRP s?=œhí^ÑîaÂ0Yã2"áÿ¼ŒOÖ5@æ ÞÛßjÏ:iro†tY¤FùÌùsÓ_8žxä¶r­z ÷99¦bº • '•d~œ-wš3ÿ–ƒc„鈧\Dr¥b²œÃÆ= Ðv´ž~˜Æ4¸­§ÎíYõ¿euw5b2Fé ó×Ûªä¨$,=YÓN˜FÑç¶ýg]#'}%Rf %(ôWX…HáWŠ…¥i~šÁ3Ò§¸ÛÓ•£µØÜcwï¼´H“q’—2Ê„º!µù! Û謨··ø:4Gx“v 㪜pwÂùÅ*P+Ðñ±Ö(P]ï°wÑŸJ~¿硽ßÁÇ>DI³Ï´—Va4I«  éŽâ¥IúKÿ³(‘¾ð}Ø-âTð à5»˜áqë–&º•w•þ·NÙÚh9Ÿ[è¾¢‘ÒÞD€L‡´òªwÓ‰E;ý†ÈœòEñ%¦»CNrù~ù–òòÍ>ƒB’¨‹ÿ,“‡†Õ= ~ãeQAåsKØo^K[ÚJ™¼G˶JûŠ~ß‘4Qð¯NÙ£ô}ºuïêºÎò_"ÔöŸ|úË@-—¤]°àï”E€* > ~¨@-“›(ðÓ)0)?†?ƒ|Íù`¡¿pÇ? qîÝÿ| CýÛºÞÂ\ïaÌ7šYÍ 3 £”a9gˤ£Â‡àܼ…9¸XÆäÀ‚ x„J2-Gàœ»0P r°a; ðÜÀò@L¨BY`æµÝ^$ËA8Ïç[P¬yÿ &jWå+ 5ÓsÐæü ó³^7›El4õÍd÷€P*Pì ;ýÃÎ…a¼Ÿ}þùÉlû’9wÚ¦Pùú÷ž+ßæeéïYSÜ÷Nüâ¥ûŸé/ᘾU`°2a¥íú¯8µµòÔ? B¤'Aï_¯£K`«”)q»àMDK¥u¨ˆlYäè½ ¦»ìâî5ôõýX?޾…Êé„,`4Œ©žN»_˜4„a 'À¹àïš ^„®Ï6/,\;•@[¼ýQ+ƒmô¬„ æûO/Y²Nâ”E‘6*(=Á³ô…¼Jç¥4¨P'/‹ù¢€P‹’B^(‘¤åŽwëûV1º{ûÈûØ®)wwÃw½2ÍC›Ó=Ô%=¨nK»iJiä›QFS–¥/Í/ RVd tTÿðÛ<8úHâæ÷èãŽ^åEÒÙ³à$=Ê®yÉäãÈŸwèôË…g&}§>Ç®yñ]R‰_ŽÿT{ÄçG+MÈÃkš­ü6ñ8õàèýâú“@/ç9ÃÜÿ‹/þ1ÐE}gìóÿå¯~˜“þˆ{…Bë{QþñÛGÿÕÑéw¢À§À¤üxÚ}€’²b$*òYÏßÀTœß]3<¹ÇGÜ–ÿ¬`0q( Ùâg˜Ç­s2(5„=£í|#SO†;à©säU°±œ§ G„Ù’¯Z…<.˜ÊhÀ3ý5IgÛ¬ÆÈ,£ÈøÈ¿TAvŒÀð7¢&B2[ÚàÄÖíÑÅ ¾ŒÁã´SF¯šõµÈH½^d?Ð[PX„gyÒr'=Õ}úΧ¦ßôCX8­Yz‘Ùö*-Aº,×VÀøðÂÀc!gt™ÈKÐ:;\ ß›ÂßGePSB"ý¨›6f ‰€6Ç.btÑ iÛìJ}á‚©‘•'¿½ähW÷v;ò³w/¤oˆcŠþbEG…®+ý—ÞÚ׬!6Ûv©Ú9ÆÙÞÌ ›ðP°,ô}ùltÈ?ߟÔæÿ]§ÿÉ·C›ø—¶U=üJSâbHÚ@ÊÔ|¡'혼—¼‹`©ŸŒøGaÓœïZס-u! 0Ùè£íÏiŠfõ”@ÛË+¨ÅŠøñæ½ð.ŽY«âw#.¦êIÅå7R—zü[\ÝFš?ïkÅ<næc4¯àœ¾ûø]äw~q €°çÑ0>ËþR~rŠ“ð¡(ù#ñ„QV6¥¹ÓÁÓ©õà—a9·ìŠýŒJF¤¼¦Œ 3\UÎ*"oÖ8Š’¡Q8J+ô•à—Qé,!£”IiŽÐ"Må ’ßô.\È™?ò1EèÃR}âoiàRî'PgŸgñ%"‘¶Ã(èL HÝö-‰É’ëȲ«FÖú¾%ÿè—sÏ&+€³@Ë/šÛNcð m«ýÑë8²M+Umœ÷¶IQBwÂ@Éç>wógþžLš#ŒUrDËjÜP7íȽ ¶Çaâ´…ÐQ¾þ#õLeÎܽ;œ·gÔè1¾+ý1çÆÏwáÁ7‘<ÕƒÐ)Í·;$Åz þV‡ï +3¶;+üË|;JÁ&dóíä2I< ì(”µ Ì@âUr•³V,'ü£3ý{ë*.l^AêéId…¤õI´b¾‹´±Q%û Æã{ÜН?"âµT9 B^%À‘{)Äñ=îŠc¾qò¦ þè„íéÞXÍ „‹õæÙêÇú FýuNÿY„ú)õ¨œq†ÿ € ïw±ŸSnñsmÀœFä›JeÓÏDGIøp´ü£1³€qÂ==úÜÁHï`Â÷<úå©ÎS6ÖÊ n[Íæ‰„ ·“ÓäéaØÌA+ÿ5Ñ/´ ¬Èö(ðË©`L ·fEÈÊJQ0T ¼S}'gpfžÒQ$©eÌŠ7j¯Q?Ñs-ĆÙY‚<9°›°Ûº4?PÚ8sÒxãGº8ÚWiQ8YŸ…¸Œ¬4G±I”Uà[ÞcgeïáÚnQÔKEžOö:ß'œ &uƒÀg4«À—LQÈly¥­óçNô…|æsDïb=rD"Éì­°5…z™ôKÀœÌ_S}øY©Ï*}î‰C¡½dË¡°&HØÖç¢?JdÑÝç"¸øÎóÖXCvôß ~EZ}T|§BÛvÙnÒ ¨µ TKÂWÿùkÍCú¾ DÂÖ=¾-q Œ¢ iÎwå=”¥¼h}/Vè{ u¥5ÿò£_GæßB-2ßuOïÑQpÅh´/¿ŽÊMI)×ðã·Z_g>)úa¾|?Bè“£|m' zô­@ý¾ÊX´H³ŒŠ²°ySmÃ?IimÍŸ8Ùëzr¢0ç=òäÊÞëϽÔÇ‘ÿõ'? 4|z†µ‡¹GÿníóÒŸIðCëÉ}4 L ÀG#í÷#†gdO¹ìÛ…c7Ë/ß°·¦zÿFý|‡+7ƒ±Ÿ]3Wx.³åNæÓ¾dÁJ€Lîˆüw˜æœ ™÷ˆ‰ÚÕšã€÷^°Ãýì÷µ#¬[Ás ØÀ…5¯ß³ ë {Ëïï•ÎA3ŸìJrÏ߇­)†ÎòǬ˜; Ó„‹ å‰ •9 ˆÐ¿YËÙÙ cô`5rª”xn=ÿÂP¨ ·`¢\`ø)ëÄ®Ðu=Á꘩ ÓŽÈïn™Óê\xŠé[¨BàsÂÊù˜àm NBá"“ð;eb}ð@×Z”Ù¿â´À˜–þPÈ)³‚öü Ú(p©Kó»‡î#ÐiÇB¨Öt„b²`ß·P… l¶~ÔÇš–¤ZÌ¥LH—zev¢Lã‚ï ‚äsò¥õf[}Œ2C¤BòWûx'Wƒ=qNA!§m¿ßE€Y4Yò.A‚ 2%åòû@JòçFI+ðPïyùûöìg³ ÎéÿOÿÀÙýÀ2ù_Íþæ‹ÀôÏýü_Sà»à¯ þ|c“àÜG¢À¤|$Â~Zù‡L»C­šú]õ ÇÖÀÚ·¬À[ ®äˆ‰“|G,ú[‡)’NÞ˜ph [Gƒ0ë˜È%ªÀ¼œ>¨L A#ƒs™ÇËξ^öã s÷S+„\]x„Àýì°5 BÐ(¿ÈQ»äˆy`rB¹:ý9B È #Lª£™â.£n* CµŸél¥çð(JFFÛ4çæ†òÅ´O‡m«£rËÛ¯:Œ¨_K[¸Ucêù­+'ê4 NiI?bh?í³bè`ùŒè¡óÚêU¦¼BW…@è(>“~~SJ‰g:i 9…6PÔŽ¯…šünùÃpr¾´Ìmè÷÷(iø´Fúd§/ß)Q©ø¸6Ã) ÆEè›nç€éƒÝá}·`ÚÑ–·Ó€ÍfèJ€Š—ÄÓ䟑?ôŠU„ïö‘oÅo"«ÞAãT‘õ±óðÓ¹±—6úg¾:ö×ÏǰN¢4˜pbò.Å¢¸ÃàVr[GªõÛÒ¢E %Ð2~ƒ¼2³§+ú½øý°®„E~Âd2_¦¤Zxѧ°x Eœ¸ƒ·UrXV³d[ö¸Èï ÀÕ‹W±(ø_hºÓCºeÛ§¦›æ& @§Ä?&àcPõâ̈ŠÑ›WèºøÏ«}×›ö ¼7\Ì’9gÄBL×0TÍör É0½.PF²0<™[¼š8ç[ÜÏÈb„¦‹EþÜùYñ<"Ì6O3íót»Lž §°é’¢#*Ž[H)œQ™Œå#[â‡Ñ*Iò•@qDI]Ö'Óçßð±áÂÕƒ%äÁ'ö/‹ïàâ@°n´†(O©Ú] žˆ¸ -ŒÔ>iN=UÆ~ÊR#ÿþ¤96)BLbñôFX3u18c„€’â¨w"à<ÂÌÅ› ßBYÅ@¨%@)¤ô!XÎÆáZ¸55ô² Û5+ù}ú±ÉéÏ“ò)E42þ©øNÜÇ/ìß„ŸIòåí’ž¼§â–,¾:_—$3yœj1Ò `Z¦m £¤ªºÀe{xB>⫾ØC3W8]Ô‚!A²˜­=ñ˜¹¹!¾…S–BÂŽ§çª é$?2·^C{í¿Ö¨2pTöá×úÆÎïÐO;ªˆ| FKŒ§ô9¯Ïœ¾sü+¬žàç<¿P €{ýÝ X£ÿbÅÓ"¿1u'ÿǦÀ¤|l ?ÃßO“Qîøwë[Vû³íAyÃÑ·÷woتdÏ“ädhÎìë æZ¸Œ ž[LW& £7~Ç*îZ•礼ü%º¼0;óÃÑË ×— “Ž…LÎãG(²qsw‡P@A;îØòwŒX¸ à∓OØj˜éMÿ[ÛI@eJ…‰ÒT;¯~»$[™š‘Ò†ŠÀÛ„ U¥@˃ûëͯ5# ¿‚Ë'„ ,DWaׄ üÑÞ0À'ì#©þ"ÄÙDA-!̬¶XÄÔ$Òô˜dù#T¨»×þô¦^÷Ü3l\ºx¾Ðú#àñçT@ÂÆÙ½ƒP¤û¯ÁÑ»´'Lk,-KÒGeM¡/Ì­…¤¡¯F)P1°¨¥ÖRÿx*æu›ªé û~ÊoEäM€ GP´²XDÔŽÈ…Íݱ™àÓ@³åÿDT×äVÏŠIßoƒBÝßPå3U!äNªÄäÿ Ð:ÒF¿¥j²1àÁäÏ·ÀËe*sÎ_.ì®àÿìç_ÆäÅœ?—ù¸§_Á-ýÛìí˜àD?&àOEiêÝÁ°¯"ðngÿöúÿ ¼‡“¾Fðÿ¯{¸–ëbŽÜ3ÉtËÝ>d>Ÿ4™ÌÿÈ»s™gw"ÓoÀ_sô+Ê\œ=ÌNý–2Dæ"Ð`^2µe2ŒîÅ6KLÌ.ÄÒä¼ÝÜ;¾¹%¿ÂKó(÷Ó_m]{Íõå]àNÉlÿÌ:…âvtèe5 ø0v¤ßëav&ª)Yá2SÔ ±CckU९tõ^†Ð—°Â›%$EÂз+žÿÇš•‡Ûj³By¹Íœo!X)¿ >¶?û.,g<íIïI§9*Âä Ð/ë"Z‘¼KJˆÏ>+ …¢P™ó.¡ý“Ž®…É•»àrAköõ« Y&Hø®ðÛ óg[Ÿÿ¯ÄM®]4¬œ÷e¡-dò‡³+Îð£ô±øBSþßþÝT¸_`êÿõo™óÖA>œïÏå>.øsw€ =µ«AâÜD?&àOGë0©°¸iÝćàžE]÷oYñ¿. Àí[æxy“çèf¸â C…óÀ¦4¡Ã—Â2ev>p0ç¬sý/Š‚sþ{Y¡¼Â?¥`ÊUº:.Ã5Þ]¦rñƒ,¸"ò àžx Ú´º:Úé‰3Gþ™+U˜ƒHŒr`¹jáÇO%#ñ÷d%^˜V'ß<–i‡)$,EÂòàq¤é¡Aë¬aq#îðGh@¬0uçÆéK, rÍòDD€ïIoG0ýOÓP4Ûg?‹ûVW.î"Ž|Ù¦Ç*þ( ¶©{|Õ>!¾´·Æ›igZÈEFçÕ͓튘Kî°²¸òÞún±Ü`¸¹qþßÅu*bˆgÕÔ“mÄ­pô&¼´¨5+4oyÓVßK{*ln3šO¸EÉŠ‰ß0x=H(­õ»hÓé€à…ÆùÒü@óâ+Ú㣧|¿F Í‹”åBªî—–,hhj1³öâdλ´ŸUMÝ< ü¿âù*'î܇Yb€ZÄ÷ €ÿGHW.»@=ª©ž4ñ™gî< ÚbÉ?Žê½æô¾kû9åªÞKÿg?û›@÷ò»¥ïââ“ÀÃ逓𗔓û÷¡À¤ü 鮨U@*ü÷X´l8ÅoÝž ÂÔð¨À‘2 CŠ ·¦Å².y̵VåT»-âº-óY@:«qĤR³€šhQɨƒn¶Ç…†ðkˆ ÏV©#S·-MöÖ ž§†é’.^×” #ôÁ»L¸ÔÂÐÌögDj•Ô¼'ì)£€mù¸}‘qoÁ!”F1µâÆ/sw˜ç.ýw ×Q…²ßó÷ø~oÙóp—Xí:šTi°\Mk¤~kCÒhx*7ïÆÞ˜ÚПô擺ƶîûÓÿpë‚;¾ Fù[ÖhE í‚¡~TJ )ÿøn;|ò[Õ%dÕy·Æ‘Azf??Ðvö‘¾PŬÌù-yÌ_½,ì…tôK´ýªo£òºØ´ÊÏwá l´Kɱ¿²Ô»{?eÆ?6¥=¢òQxg™…Ç8ŸžÕîÛ ÛÚ!Q ÷¼K,…%å8‡4qÍ–µ+ýGg܆ç6¯ˆ°Ä¤¯ÀÖ*àÈþ䊃V€Î#_>¹TðSV@“?GÁ ÍŸƒzØ'VB_<Ð]uĉí£Cû›‚C#¤Ó~’Ê׺-,_q ØŽ~ÚpzdUþœi€›?<äªäFÿµóAÚÒVè¡!!ʇ´U8;D…FZø³Hò’1Ää—j"Ä­.ï‡÷ÁVPq¶/Ö”TŸ*>ë0HïJ5óî£Rߌø»q{zTÚQ½yU–k鎸u†õ‹S˜|Æ“rfÂõr=®¬e$P­yµ"àÑŸÝ/Ä«ÌÎ.4`!Ñ4Õx¾sÞ}ÏïBÁ,<¥Çšì9ŠWèáùìg ý³Ìõ#ü匕ÀS…œ¢îÉMøs À¤|ô· k‘¹Ô*ÿ·w¯ñ?dÔÿ‡Û?̾zÍœ.Ð5·Ìÿº¸+{—aI €ûÜu«ðì={_?\š™oVôdÈ0(Š3§ÌÂA¶‡yý/¬{ö;&™5ª'ùDÁÌ(N7?7BާP>AØ-9¬Æª½Ým‰Ðoäsýúáž4ê†Ñ˘˜ƒ¦6w@¯¢(hÒiÖ(ä7BÅýâ ëÚÒ–aäñ»~ô¬åé¡Ö’pLòK€U[מ—mÖª:-‘:ä¯äµ±{zÍÑ«À˜ú+>0súŒäOÝǯI_ Aå•O›‡µ\âS‰ðúÕ(„ù—~D`Òw…©‚¹„ª‚…3ò³U¾‘%ë,„¡ýÕätÁšÓ÷oQ¦» oÇ"D #óû›Íìwÿú&0GúòÎc­ AQ PÖ·Ôħ/´.ßH`:ƒ€–¾ݺ BCÞ•V†2é“FúÖ£órDÇ{òu)ç¢K÷Õ±Ò,üfƒ­'tKê}“¨N“oWºÑtü”§]&—s÷Mó¡*VWöphO¼Ît»18ßíQ€ëL÷¶I¡?âPÑÝç? ~ ¯1·uZÜVZ{Àc^ ò *áÄž×ÿÊ9| ÿüü%ûøÿK 'ù9úÿÕ¯]ÀB@Fü¹à‡)¡&‘z¦FW•ÓïDW L ÀŸˆüòÍénõÛD(%àžÑÿýš}Ý(šåÂÚÊìÊÆ”öಎækDÎ ó„a!³£ðqDž‡úYÉ_gÿƒƒ6l`©ÂÌ‹Ã(‘ÐGÌß‹GÆ”Q³°8zYh¼v‡ †°ž>§?[Êh[FMâ$Nµ#m5샄Z\AbQ¡ €Gß!´„†*®&š_ ék0Ð>¸xµäqÁ–SÌ Œ!½Q$E£à@•€eŽ×-ÿÉy;{_Ï™ §(ý´>Gþ«KòC…åy¤5Ò!´²yÔ4üÑŽLû‡DÉ»³}.JS ›Nã¶ŸYÔ,ó:Ê `q0]òð–ò@­:þsÏ¢?w‰ˆ?÷É·ýãY3€ö““û a0[he¡ŽÔãÝð2„:“r°0 uÞGa©öÛ¾½g,˜n+M Ò~Þ=ŽÒËÕ·Ðr÷¨'Á–1À²-Ëžp£7¹ºÀï5ä[jHzÜgõÏwbZ΄P!h†ñÒ-öç}å[Lï$Lµ‡J¬7Ó>4H:{7ƒw/œjÒgá^nëã@ŸWŸý"#~WùŸ]Ï^z’Ÿç;h%È9ihuhõä›(ðïEIø“Q¾¸fæÔᨂ2* F3ïÜùï ™áºp^‡'l¹SæaÓçú‡|ä¯xó]ÕEà* |ŒÒzö˜ŒsX]XX‹Î æ(Æä|¶ÙèŽ[œiž¹až–ȨOü<´žºdó¸”CÐó'{6ÍG;†ܲ†;Ä[. S EWÁt =½{%!HŒ–ïÏÝ;â׌ïÜ}{2âŸ-|׫BИ~ʻڿPEZÂÎöà|itÑ\åÅÅzÙö† Qðkˆ`˜v±Ä#Pë+vÛ¦0Â0 0i*h…Ž|â[{ÒŽöã{É=G¸C»ªŒY2•#}ÚÇ`þ>eÑ_h¦l‚̲äouÖžˆÔmÁåè8óúF'¥m=†…‹‘úl7õy¬±Ð8ŸŒÞ€UBªæT–+$çw*/dµŒÓö-ÄQº£ÿ,䣎,Ü3ìž}Gõ*]Ä;Ÿ¯UV³±#>÷ý›~Ú²%ëB"m-I ºÚ®ÄG¸ó¸€ïî &üXrJX3…£BO'ÝG_ôlåÛQ²ö_Á«Ð×LhjwþÙ5ªMœÁŒIšö‘Ùúêo*íô^„5Ûmœ LÞ´&Ò£:…˜7làJÝASÊ`;ù ¯`}òÑ€ÅwPGïgû¡+ÄÎO‡©úù­[–›¤\Wœ7Ý8•­¸Zœ~\Hþá4¿ŸB û“ÁÞU=ö<(ù´Í ›Ö‘Ò¡õ*ôWDõ{Çø1ã{ Ï‹—Œð½¼ÁUÍë«É_ÁïÁ>s…|L"LC[ãSáô3QàÏ‹“ðQßB!â&‰oçHžûÔU.ŸrVø/Nÿ>gñ?`ZÿæÍíìÍæ_fÀ5 ww³›Û¯a]Œ¶`\g "}¶÷žÃþ‡À½[Â<‡ƒˆ‹p±ÜŒEzµp²¹­æ~ ,Ò‘·Vy¦O£O…)ÿüÑ ¡`wm—GÊ®0ÙïYhf2Øs2¡0^··áyä ³l*cãƒ.¶ÓÕH&Ë2uÍúBpèyÖTý²îŒTh~§:¼Ÿ@¨ðu½Ä Î%o± ì¨G@ùï kVŸ¬f§Ôðô9}©É|àÐ*pÌ”@¬H¥%…Î]© ´V­"Ç·²ŽPt‘¦Ðiš˜åYáN…¾óüþKÎç÷€Úãsó¦Lúe=é¿„®oAºêǧ©YèTƒ£ëK„óÏ*Î8¡ÞÍú8Š¡Ê¡G×” ´Gzý»š(!‰‚” ƒàä]€.ÐpjŒ€ÆgŽéü|'†#°¥SKSá8¦]Bïl‡…Bè¡2ቖQp*‡Ÿ\%RÄR¾—†.uæÛjiâj!y­7OÿÀZ|>>±†ÄU?a ©ðõ T=Üâû3¯³{×4ð‹ßsÿ_\¹5rÔá7qŠ‚(ôòž3¶ò}þ«ß:Çqɾþ¿ÿçÀ¬@àúÙ¯9+¢Îï÷8ßFÿ¡V6orþÜ(0)õÀu­äò>„c#/ä ç,;G¤ÏŽ"›½{Ì¿ÆÜˆ‰€Yìl®ÊrdÎ@{öEG˜ÀÍöX¶Zx\ŸÅ‚V†k…Ë1&..îjyêÓ·m8'åu­3vl¹jÅ-DÒüŠ}ŠvþAA)“K6q»z(n´kdú)7¤Ïáê)‚pqD¸µŽŒ¤¡ÐÆ‹{‰ÀéuxjÚ '³3↫ϱ¢¹0’*ri‹å@—µúeÎê×Ò@<#÷ì{£bFûØ#òÔA@ÖÃÚ‘ Iêäwé { Ä…œ5’§wíeeǪy÷Ê»¸qú»×;æêy/*$Ĺo? -ÏŸV¡Î6C@…±‚‡ëâCh’µ+ ›¦x-Z]l~9¨z)tpkÖd¹¸þ9è»È*x„Ÿ0¯Ì8” § GØÆ RmS É¢<êµ”9'AÔ<öbÂ"ŒÐ‡,è ~t­‡à­T"ËY®€ïÙùÊE_颢0ŒÃ-Ÿ õýÖtâÞó“ïÍ+'Nȃ"]4Ò²e_MÔpBŸý,µŽœàÉ©ŽñUVùcâçÖ¾Õ)ûú¯?Åðó@Gü*ç¬üÖ¾âÑÐ1¹‰¾˜€ønÂÛ`SOÿŒKF­ÉðˆƒDÜ“¿\rÊ Dá•Q–ÌLî† •9,‚š‚§ƒÙ2}  ÜQúÀ)Zû®å‚2C[¤¢œÌ¹»eŒ…A y’™U÷rÑ$Ã8KCŒM“›צ¢¬?üÐ,öG @¸¯ñ%h“Çò5wJÅ4€7‡± m§Œ9[ø”€ÆÇQm,Ôk¬'f'ñ¥X¶žT ²A¨_ÝÅ9¼«T2⻈ˆ!ºì u ïúgÎß=ùXjþ¾ü™÷G ˆ>ï¤U4THÝþ–¦¶Ñö*`UN"øQZNP`|¤¿Ó!2/¡kgŽxm·èÉ”ï&/Kü:GÿÄÇßêjáÔŸt}•?–Òjü¤}äI\p¥IDÌgCô½Ð?Íi8[ö'ÀúÒLÊ ÆÛ¡Éc¿á8w䶤 µ‚ý³ìE:ìÙ¥•V–c´¡Ö—˜ÐUüÙʇ¹_ÿŠ}ýgL×­˜÷?áÀöÉ|?)OÌ*ÿŽx‚þB(0)ñE)LrX Ííl[†hM¹0IJ2¨#@öY ŸaâIGI¥4à Ý÷À¯÷L `—dÖ–[áÖœ'ô¼~•§¢4ˆŸ?XØ?uÉ•?B¼×'üÒ›f0_!P³#Àr<šl;bØ²ŠšS ž5`X¡aß„ +=À!Õ"ÓO›sËžúH#èHZFèȘxtDÝXsßÖÝòƒ' (Þ=sìÞóÛ£@@,¡Ê‘ÊΚ4ÛŸ&ƒc«ÀzSž9vÖ[¸ R3²—ñÜ¿½ ̈Ÿ=ü®º E@^O¼ÇʲÂ>Úu‘n-žQ ´Ý*8+w,= È¯¯4UÛ Fý|8¢Õ¢à(Ö‹$õfÝðK6#F.$oáŒpùŸu-NåIä¶Ç¼Ç¼?aÚ‡5&­ƒ€~¶¸¨^u]4 øî%²¹tõ{€‰|ò#ÆÁá æ¥?ßBU—lýÛ6@5ßr´t§¿2åWú«0m=àétÅÜ>4÷c·ë]´m{ xG÷/^ý¢Fù®òçœÿSçÿû6?oý›ÜD¿T L ÀG{s0A„þzw‡pgÿ[ï²Ö¹ Ó†í™s~œ¯rhÏnÆêaF2§v{&´w¤+tqºèïæá5ž½øàÚ²ßÿöËßÊ Ýÿ}¾d¨PqûàAâe4‘ 0ô\L#ç„"Ÿ~@†(š$“”cÂËçÙò‡ß°iIÄ‹_44)¬Z\•"ð€"ôv¹¹gíûg?Žn­X¡Z£\LÚ”éB6ȬËìüEC…LnIô4EŸ=‚Qëˆî–ão©_¿—iª¯J’“®S(+ ´aº¥›ÌͶæþƒÐªH9ê¬Q¿G £€!|³mÚܳ5Ï9øš¶ Ôç Üyeûü‚õÂ($Ð5[ ›RŸæ®ó!Ã…(*3îrÿ[¦Tœÿß Ìüá V?Ú$}Ü·:áÇÊñó›·@Â-‹Iq„:U.äò%ç…V–Äʼn>Š” WÂü: ÑRhÍ4¥×«¿5êYd¯bê…›xQh‚¬?ìHé«ßñ¡ A‘Ë‹]±†ÆÖªx]œ-f/?½zåò*×õþüWÿ%P!†ðÅoþ90#~þož±àØ?ÿw}Ü0þCÞéç/“ð‘^ZøÜJÁïÉÂnp*KÊh…æ#Lµ,JM BÓGa«ä–˱°ÍEgkB*;PÖ·÷l%CP×#öó-#¥Iø>H;dy ÑÔîˆJ¿éüë¼´¨@|±ÒàœŽ¶’·$¯§vœzÄ— ʉXë@æ:ñ_µI?I ÷Š¥$l<öâñ›?·çÛKÃÚù£е[R¡JUÔWø#ŸZ?ˆŽ©>—),TX¥è%6¢òXZ÷½çxZúi}*ÂRømÑ]Òºkbª Hÿô‡Ió@ð;¼BÆÚ@›r°m£‘‚sÆIƒýV:·!:ÍvDòXîâTÅÀ–ó-±ÖÀ)¡ŸÃ#‰åÒ Ï ì³åõ iNäœô)Õ°Q˜LÑ›Ì\ÿ u¨š°H¬§§ÅºZt=íˆü%¿Ö¢X;äíÎZ ¶ÚñzL”NÉ'Vý#]–“R®jî!ˈýо*]¹²ÖæBÚÐÔ!§¬)9;õFü—³ëŸ1âÿ´LþÌý¿xõˬP)÷_Íþ9Ê·õB%`rþR)0)íÍ)(a  ~žefõ£‚Ÿ†Ó q‰æGÁ‡ _8Çèa>rBnD,áb#¡èŠt™u±n1ØbA%;h¶s åßÍ%š¡ ‚iINaÑa:â]7Vbm0¼*öol¶5­¼âêø-÷ÜѯdèW¸)„€9&™²¹·ú(xƒJÈãbȬa`¾<8 ÝžUë9øˆô¬=@@ö5 þGæõŸ(XlºPVÖ[ 5KPiíÂ!O;j;a2õ±°äœæ~^m zÃ<*^æ›kµÀ¯\ÍCÃí“o—‡üý]*zä_B é,)M³œí²Ï°ëlj'Ö„’\øZ8õW˜²V©·•G-¯E„n* Ð2Žøžµ"ªŽJ+¿Y{žŽ;¥Š^îÇÂŽ{(/Þ†[º8ò÷ØjMþÇ(kîÙ?öd¿SŸ 2ýaê?aÑßéÐ4/òq¡Ÿ—ÿLB îäù §À¤|àˆq6eØ[V€­1Õ¯Ù›¦°†Y–éIjqxïºÇpK±¸ iç;ÚiÒÞSHËC0€W(ºœ‹}ÕŒN¤k$üKâ­Üú-c3ÛZ ;?h[¼Ò8Ék±´긔œ\5¥¡€¿ý#Ú+”#Ð)Wý”0ÕGOù‹ÂAÞ=r惻T Hg ÐöØç~T°4p-€&ÿ\à㻑.Ò_?ERþ@~g|{¤D”©CƒÓ*Ðqï#0Ô«ûÕò*Ü-Ýä¢LRÛŠ´¦ƒç¯äìOó£ªÕ,Íøãê©U"Jb5’Þ ’Zx]è·Ê¶J·þq•/#þ Fü—@¯ïuäþâó@úy£Ÿ'ù¹­Oá¯E.¯Üª&7Qà?&à¾DØ5&eŽîUÐ"8î0ÕÿŽsþ…[…?C½õâ”…rÌëÃúT6ÌóS*û§¹êev„É÷ :?e¾‘µ¯~þi„å£ën¾™}õ³—¸y`¿ùÍ›ÙÑú¨0ܲ¥‰ #Î¥ÒƹA츿]¨“GYf+ ÌQùà®ÊZóÌ"LJ˜5BÈmtóŒúH'sô`FýÓ ²1ôÆíbBñ9uÁ± ²Âsî—ïQ´ó%ë#„æçqT+Œp‘‘÷ºñ;êß´Ë…2*'|ŠÔÆ:KÛD ;ÀØ·Ê|z„ðjòˆÜÜŠ–ÊŠ|ðÅÚRÑЕD1˜]¡b-„(»<ZA÷˜-†Â*C’2 °Y«€ŽbzvS ÖzÅY¦T<öwÓO´†·(X¤ èlú‡?NÞœïOSA qÁQÐ`úD\‡ÆéÒvóÆïWrˆ,Ê¥P"ý®Z s¼E€ö-8¼wÃýS9´ø©Â‘šyÏ­àjµÓ&:¾óc’¿³c®Ãª+ü_\³¢¸b‘ß „ÿ¯ÿ·ÿ3ðŒÿûüͯÿ)0&Fýnÿsô_/TœùBÓµég¢À_:&à¾A“"Õq¾JÀ£ÿ{¯ø…ëjŽÝ!Pœ«WøË3òï%<åodpÑG UÜ“}óÍ5¼hS‚« 3ÛrcžŒ×æ®ÏÈTæ³Ì‚9$ò02RR4#)êE17f±S›OaÎŒ¤)¦ŒÕTm»ÅGÐBgê2½&õbr¯;)ƒ×ìâQ@:"Öœ.Ô™æÁAÂ8ådd B-#æ¿#ü› Cß¡M€V(Â/…ÉGßÖŒ’ícʃ#–`òQ¦/j´RÛ4w ~ÚE•$°¥kÂO:?Æ»kA(Í5ýgÄ$;Α§>*ôà¥EÕFA{\yè?"Ý‚‰"0yøñÆÅV€éEfààvºàöì„mE ÉÖòzOWª\¥µ&fŠ aLr±B_ÙÛ»J€ŸýJ´/§'¿Zk«90~~š>6”ã“&.límµL,H “­È„–Aµ@yi§Jœó?Gøcö?Í"?,ןaøæþ+Öp²Ÿ`Îò÷Û×äß?СU“g¢À L À|2¨ˆ„½ þœûwôíѾQÜ2©

lë[qy#ý“&Viºî¦ú‰gÜâØÆ)ÛD¿ L ÀzQŠ9W£¯9(ÆUÿ[oøsôËÑïˆ"š‘1õzF€[…[†~Þ ø iØ÷—+T,àYs™æËe'wp(‡Ìˆ)ÅŽsžÉL4M­IºÅ" ¨¡,ƒTÄD «`S"ñŒú SâG$G;ï¬P¶}4zÁ娘°B„¦2ë#S™¬©‹|ⲑ8©à¹þ…a›âƒPI_À‡ß #þZ؆%ï‘&úT–êJ¸š×ºiŸ»2ˆÆ¿‹’¤¢%á\ȼ½Ö^À“>£Æ.ÔÍÚ•,Û«·¸ Û¯rN»’jC*cª³ šü4+MèÐ@Úv 'ƒk.*cÅEÓ+B“ãïq#À¨TÔÁPÙ¡Hà“³ýT{1Vô>×óvh¾±ÿPîݱ~›]±j4$c§má×ßÞe‹òëü~tyNáø]ð,ù6N0Éä çüøWŒøÏÏëF¿ëëŸ±ÆæUFü+æüUXçÊj”ÓÏDÿИ€ôzeF¸ûëû7³¯ûe4ÿ–ÕzÿÆ<½PF½<Ùr.=&}.bböÀ¡>¯oŸü[•ôùêõ—2¿³ŒH^ÌÎ=iÌ‹{¸‘Œ;ȵ ,1aƼ˶¤ÇÅM >òìµtn‹gÅ!2šÍíëW±G‚gd|Oó[DA·ôð¨L• &†¿v]P²Éd½P+x²ˆÖSŽ„fÛ#h™óÏÁ@$) ØøE{ÏJ@Ч~= i…Oã:tú!Gákt‡Iד4Øögj€9ñš"¨6¬ÙÖWmAx`ý¸{ Ø„˜ÜâÒÿ s΂ªHs×@t`{s±0—ôŒØ‰² ®yêÌïN…PüRO”&ëk.‹îð—,3§¥ZXB©0TT:”|v¨GãM¨å±ïãÄZ¨Xq¶Ë‡½}æËz‡xü9´½ò¨ Kù  6 š” ­ý-ïô¶÷oì  gJE… gžz× æE±-â¤ïˆÒ•,4*´¶²§'eöÏt Âÿå NîÃr¦Ùß-~ÿðÛÿxvzÅ™þŸÌ~õŸ<ÛÿÚQÛü2çïíP6frþƒS`R>à v¾}ƒà“Y\ýÿÀÈÿŽ“rîåÃOŽ9ë‘®Úé@IDAT‘³a1áÞ $lÞðã «–lŒ8¶ `˜5¦…— ÕNÊ圽i϶::^Ó ±}JÁTï6ÿ„)C–X„àð\÷Ü64¬%Çãÿ³ÁÅxÙ7¯ÒC…Á–E‚j6ÊA•×0Ô p„£÷°¬Nh6­$] xLñ\¯ÆDüÞ!Ч\l˜ã’©N¹Ô• «·3Î"¤S ôùvó꜃×õp‹n‘Ôš¤7É”Û[fG='ˆß²ƒ1Àqô) bMFÉ ]„+ÑÂrHš…uô·F%ÜÓ Óô÷Ç´ž¯C㞺qî´—’B>Ó63ª\ JJE´«à¸Ã”÷ÛÈ÷û;aú섳1V˜ý»àÅ‹Ÿsþ—ì“9ÿ6×_×ø¶´ú&0Qà?*&à½YYžŒÙ5ý¤:O«sÊÝG6•9^íçHGz[€ Ö‚í·m~Nðh pqš+ûNØó8©ðÌ dlK:bè4Ç”€ˆR-?鄨¶ÅÆd¼L•GÁk#yª­DÑ0Ûfš®F|xZ8)Å:~*OÌæ0\©µ'u&\oPº0±5ŨÊgF"eø 0aw=ï‘E ÑÌkªLþ¬Q9*Üñ…g:YÂÁ§ÒƳëÅ—&áVY`ðX‡_¡Úý(ò-=ÕŒÊt“}/£bÒñXä[n\Ö¶YH[|Ê·BAEÚPļ‰e°/-ƒh|UÓE~Ì_´#räÌû.×P¥ü8]|ïrvp½Îž÷]õ¦ý­Dü­É8ݸŽC¨åJkP,MÇüñv¾SæýWX̼®×£|O9Óÿ €£}Ïñw¾šóïžà_&àC¾m˜£V÷×köv_wI+gÕirz×·©¾`ô÷6p‹¥`ýÀñ¾^Œ_Á¾]¢³àè_qaI}+ð]|æs¤2àð֑’GGQ€S*t¼ N+mFö”˰Âd ´a¦;w/oÙˆ%]A‹T©£ÅfOõ%Ph¢#\›ê¨ÚѺsØ: ˈš8™µN…E:'bƒÉÇè>d´nëii¶ßþIK–)T<ªµ¶Ü¾òé¤cÒçˆU†ž˜Î[ŽÛåÀ… ç´âjúB¿Ej‘^,VAÕìÂä Dp ¯®Çë1Êi˜–”ôÂorK¡”x}IÀB$’–÷94ºÇµ,‚1þ±¿²c¡qÊØß’ÍÜq?K®²ßŠ´DÜ8EGc"”çµðÿ¢GÇ´Éû¥Dh<*ëw¡_¾!Wù¯í —Üÿ§ù»àïŠþ5âÿ„|®¸Äb0ÍùKËÉýuR`R~ò{?Ü‡Û ù6p&/úÙ{(|˜!o_ãƒé1yü°¾}ýå¿zåïŽùêÛ¬G‹´óìú›³¯P Ö¬ðØýŒ“b³Eiö¸b~úFÇ‚@×ÈD‘¾›- •Â>מ ô\sàhW™vÂu²\¹‰i⓹&r‹—€ÇÖj í¤L‰hÂΘÄA¬PÎQ¶—Ž´jîÜúš´Ì±#´l†7Öµæ¤.Àsí‚íU®¹@ž¾!ðŽê] vìA8 Úáv®Gȹ·c„½A1ó#øMç BÞþÚj²¥oÀà’m~©›¢s»½çmGzŽd’|AA;C0‹ƒ?× ý‚Z0Ê‚¾íjJ â£xõ}ûDÙf]‡¢’*ñCËÇ:ZÿHlÅÒ„ú±.eÊëoòѶž?qÑðY}çã Î ®ãëPDöµ7˜‚¾› ˆÈkŒ° kSu¡]yëdÑDURšƒ`‹a]¾ ÙVv½R}}~ƒ¹=ènMýží“?ÿ7.¯_Í~óÿ3Ð}þ——ŸÎ~Íœ¿°í«ÑÿЧָ Lø+ À¤|З쨎ðrt““ö²J \mïÉ€^&ܹFàþ–9òz©¼l9à]8W™`z`ƒ`Îé9Üy‰ŽpsÜ#ÜÏi‚º>˜×Èêe9gÉÅaÄò´ìO§Máû2ï Ë.0Îÿ §}aì7a¿2xzn~ÌþdsäïyXQÃòµ~<ž°è.BNMÌõk (¡ÀÈTó½£qžì³Ç¬ï­{¬-€ùeôÖ©0äû9úñq› ?)h[TªQéfmû2B§(ÖÉq…=w–M”R\j¤yŒI,áMÑõ¯YM‹€'GÂcH°Êëiζ¾ë±©¶ÖS µ ˜Iüžk$ì ÅÔ“"øÄeÑa þš"€Bé®xÌ›§å!”hõ&LùjypRÂõÃÛhë­äÈÖƒøð·´~ÄOúÚ˵>¦NãÀ¾ÿ€:Ô»|ºëEzTÚ)¾–!y{b/$´ƒ#×ó¥ß"ÏãL{OcS¶N{IŽÐ§Î@”Y÷øgáf.ÍþÞâçŠÿGû:ÇŸ9ùq¤?Ìù·yk›öù?¥ùúë¢À¤ü¤÷-wêOÄ Rª rGÂÌës[ÜÃÃ=¦L…>€ £}  ûö,øÃ°ÏðåÁȱ¹œ°áÑ„®¸{\8-pÏ<=G˜ö09üíQ °]çØßGÉ Ç=O`ƒpÔ”a,X<_@lÞâÕ: É[tDÛG]aæJh™:üÓoy¤˛8Ãt! eÐå+€ÁÝŸH9¹é јÙWœèl—»ò6¾hs¹ø=4È<±¤®´3gd¸k°akÂÝÆóÏ>KÛGX:¹­/£LÓ“Šl/NÔ9K¨k‰¯ETÖ–^q‡@Ј# …_Òö=¾%'¥âzÊöþ‘jš£ßq9_u[ê9~Ózº4´raü¦õDü¡Q‡iBSmÈ”|ä}n!2û¡GÏýùŠ“£ÿ”í©B±Äà}ú=¤â4Z+Žç÷ë¬_aïI‹ŽökÔÏœ?Gf{Ìoæüñ»Õï xÊ‚?÷ü_^qÒ+ý3ç" ¹?ÓÁ:ýLøë¦À¤ü¤÷ïˆR‰™ƒ$l„þŽÞ·¿¿¹½þ__Î^ß¼åÌwFò¬úßÜF`Á¸N¹ÿ}ΈÅ#tî0ù¿æn¦r¤îîvv;û×ÙšuK¸Þ W—®ÙÿŒ¢±½É¾xÎ žm0ůïŽXcÀy—ë4’΃„2÷HÕ{Ú«t%ìüòšEzÂ8¤IØmÂø dCh‚Гƒ(«±ÁítœpÀz‡–N¼ü˜¹oÚÕ•_zh8µ%!{»„Tõ¦.ð®×%|R= ÀR“}¦lÎù'³a+vDÞk£ªKˆŸXè£0B¿'ï fv:é”IŸc6S¶¨µüÙþ‡Ò¤ªWHS3uÚºt(õµêmÕšØÞj^Ò²÷l¥ø4ä‰ì €UˆOá¼ ùÞý¥¸ôgmCÑed¡ ½m˜šì>’±SLûm#^·Q «‹zZB+Äj•øz—*Tí1A¥I×sÕ¢ÊöŽ_éý·>— 9ÕÅɽûZêZ–Ó3¶÷©3ógÁ©}Wä#tµÿ—ùüýþŸŽø/¸Î÷‹_ÿï}Ÿ¿«ÿ§9ÿ¼’ég¢€wÏMî§Q@–¥HðQ¸Â¼¨ ^·ñ­ï9ÝïîÁ`w„ŽPÊW— gÎP\àçèöÑsèµ™+DÅgÇEB\ο`B}·%/+×K²u €;È«t )#ÚŒòpØ”ðJApƒ¿šI5´œøâòB\¸5Lš6F@5®.ï7kˆÇÏîÅŒ²»€o+ž:| ‡aÀIl?”ÓÙÌî"Ô¤'.øiÀžƒ2õa ñ¢"a9ÒÒª [(R>gï—X2݃e„6/u´ !³áJD½å®`$É‚•¥<è-B¼¤þ“g#Lü¶c@Vt¤pÚf:ž ˆ{„YyGÑë“W Ô•B¤`Š®û½ÚžDj¼üHæÖä0(D‰î Ä¥T<ƒÒKW}Ð×–|êK]ø:LÅ­½¶1×÷Òiä}”ŸnXðžN8buŠðg쉷ù]^sÙÏ糫—œípε¾uòß‹}û1Ÿùi”ŸÀDþMDø)è̯qÌ ’åõ0Œ!h‰÷ËudnÇL^z¶ÿ1#|G—;ûp™Ì<{‡G, šÆ0/¯öj[Y½S q “N™ GUÐFöšä:ƒj^‰…°æðôêËp·{a¦ÞÖGò¤W(aÖ¢!Ž™‰&Q<äþ~æ¥p«¡EšßÚÝ“&Q QÚT™+Þ¶ÁŸI++R4ë1¹Ë“?Îxè‚®µÃüC{Z=•‹â …MI¦7œICIþgÅRܸ&n(zñÄzS;|Wyó?ÇÓýi½-=^Ø ¶G—þ”÷ɯJžNzXN7†–ëÏ“úz¦*òGÿŽÛœÂ_Kpª#Ó´/F`Nä};-ýþ˜ÜߌðÏõ½Îó³ÏÿÌóý3çïEZžðç4A±:ÿŸLn¢ÀD¢À¤üè/!cYd‰sìÌÛzÀÇm| û׎Îgg [<Ñ®6²ËÑqp7oò»¼ºÌ]óØÕWÜm»]2…à°på k„šAg»c¦—@óm°.ô…„Z²ˆPNÞ¹+-±5ïcyfË–¹Q~•†r@ §|C¢Pñæ=ÊGp'ž;F›ÐGÍi‡[”<%ª@‘ eý¾Þ޶·»¡âžWÐ3õø„µÐTB¢ýéѽràP,&ÂDxœ¯óþ üwœ¸Ø/é0„ü%fÿûxÈÏ5£ÿsŽõ=ã¸lž7í_ôŸ~' ¼‹“ð.ª|G\«’CQÙSü8áæâ½Κ‘=3Ý,à;ç.òÏ®W³ór"y¼‘ìŒùz¡«ö½uìÔ-I@§½þæõìî«[nÄ[°5ðž-ƒ·³ßýU õy±Éãg›s Ò»á·7ÔÜ1ݰ}X³Í޵Çù)x1ï<¬)¡Ó9»ý‹“…ãw¦îôÀ#¸[ÞZØø6Ly¿vûacÐÀ%VŒ¦4œp|Ó$€#þ0r9p¨,¨,)­sŽF ·†V¸÷'è(l䩳WUѱTTÏ×  7'¶öCÓrµEáǹÐ¥ÓD¨Pýqqâö‘w V’ÄŠ« fÂÙðîðºÍ2e[œ×׎mÐ ±ÝÓãGù©>¸’Ô«i0i$«'Æ‘É| üäoaÓ´6Rg^Ô©¬h±2¿ùr¸0. ÄZ¤Ç’ôÎs½ã!q˜­1Š¢¾óîéŸø=¶oÒ=þ«ï$Š€ ý¸ûâEà Ûü®Xð÷›ü®ö?g›ß¯~ýOu‡f«dôÿ¼…½Ö Nøë¥À¤ü„w/ëŒãcÊ Kƒf>Âå‘=‡!4ö 5õ_\a²zŒ¯gùŸž_:W¿eñ €×À •áZî9'à1 Ærvÿ¾©§÷÷­ºe0æýb¨­¾Fðȸaº]•$h%* 9(ûT8ÔÙì¥4(›,ßeTd‡‹Üº4aî&&¼±´:5º*' oøÞ!`[Œk†<åÆS&ë:L »³}Ýåü×X(`ˆ´M±b´ Æy° ò&HÄ«ÂÑñ[·i½ ¾ÿàryT»i"¨<”ÃosÒ/³âzóÌú.×ëªxžqÈP¥ÇÉâ6Üë°'upOò7V™*š_-WÝ®C鉚’÷?.ÈR=í€ò†Ïú<ÞY%Æ:¼“aÉ»Êu¾Ä»VeÙC|Ž™÷ï€ëÌù³ÂÿŒ9/ööÕþs ½“'N‰å˜€ýÈÅTú_W*^ž#Ë%†™îÑ_r6¹Â_Ó¿,P2R*éôgMó–;¦6Ž\@×Ï pÅ·#ztâ©P‡‹ý¹#4åÝ '÷6çþw\çÞá°ÕÆUm¶áä ñjDá /ýÔZø-ãVÈu¡k½â¬ä( ©Új|Z@Â]øF Q0Ó ™d¶'nh•àº2R!~{Y+Òïš–7•C»HHÓqéSÇ•ˆDWãß÷´lîçe{ºmèõ÷¸1ìi¶v YzzDÏ×ÂãìúûcrOëТú;4Ï)‚dH~â©Ë<«º•(0d<­Ü¸ÿÏXW_ì§Áϱ¾9ç…y⛬ú_¸ßŸ+|á;ïˆÙßÿCK¶ú倪œæüŸ¼–)0Qà &à 9~H ¸–£?™Ñà y8½Ïãi=ªÖ?…ÍÑ #}ÖZZêˆ=üs÷!³˜ï(÷Ž{„ž¯À9}·:d1Ó꜅0CO <Ùm×'Œî D9íOI3uП8 (ŒÍó¨uh†-çÔÜ3ùÁ9ðc< ®hóÞd¦´¨\]í YA.^• aJWÞÂc±ÔìˆMïBY†nÑ3ãrÌ/þ§E ãt{MOZŒ´ÁbÒB<å"U_ÏÐ+'=e´¬aõšŽ!#r#,K¤E]W¥£…ÓÓÍÆÃzÌC}Dtú“£œyGnNGZñÌ6¸QžAaiq£¤`î dš¶‹qžô©ÕW~¿‚röü)ßdÑÛ^s $½Šæ7å»"H ÚZõw4µ­ïPèiëÒåC"…†éc Ç"„W:»Äc¥ýœ†ñd¿3öù/±¢-PžøW/jO¿ÿêŧñŸcEëÊÀ¼`‡Z'ßD‰ï¡À¤¼‡0ï‹vºN¶î¹ñ\å˳EXsuÏì¹NóŸmYý´…«-/Þî‡-/—ŒL8¤dŒ€ÀßÏ/I²¿àìÅg3[ž^³uðföæüëÙï_ÿfj9§::Öι|zçn—‹Gb²5 …Á9O­® Ð »ójëCFY]¡Î©„c®÷*åþ¬nZGõ;7 ™™:ƒUGPêÄt¯×öV ‰~SÝeÀ5wÖ§Ðw~úõyj…)<¡Š©&Ðï4¥ÂM´u§÷,¡m±;Ö@dê¢5A‰oSâÈt”}óC ÊNz‘<úw¤Êôœ•˺ÊgûZ¥ êh¾€ÐfQåmRÙzâzEFJG¥.0Ù¤•ñJËò>à”IÃc0Þ–§Ô iÍÓëëž8§p†&™„-k•õ]õéfq€®@½jÊ*/“ V…\täÌõ½//ù¹ÿÁ{&Ž]$ûò%“?w^œs Ïûjþ÷€ŸÚçÿ*Ó~÷ÆOsþEþéw¢À÷Q`R¾BOÒ;+ª ÀÐ<×.—E€Šg¿céšû†2z) ãÔ4 ÇF`äO¸$eælW:9¹˜íΈƎ¾ÞÜc€ùÝSÜ]ÁIs 0'å!ÂôaÌ2b-ʇºÄFá΄0dðDûr¸ 5:W³·œƒ S@ï¶Ñ#‰&SïebúWXÉÙ 7t¢´]¦)$&Λù†|zHs^Þ*ì6½ x¢hS+I¼Â“âe±èùˆK›ÌŒåG¾ƒƒ–v’Ú†èѸ)¸zšsÏG\/ÐéaØÇæõ´Á3D ‰‰!/Æ¢*0{ÐE£ë+%`ß"ü+Õ_Ÿqó$s5Cô>ºøùéaãš.¡w¨³°!]åû±\ù…ÁÁ÷?DIé$þ€€$3òBk•³þAù©ùþü.íƒÊGþñß¡€²óà„Ë}.Îõ¿tÔÿyý9 h=ìçüâšï¸í¯`ÜÛ5¹‰ÞIIx'Y¾+²8š¬QA_ŽËK à—ºþžF¾Æ…ʃ>a¯òC}¢%öHó½S\d¿8aÿ2Ö=™7’PiÜ%"^MøáÏ0OÍÅ*;FÁ"@Ñ>\ù^˺eµ©Ì qc?8zãH‰°ö8«þ®â•pì'ØýÌCD²n‰Æ’Dênyš,J(Í2OK;xFq½\ÏÓ`¯³—-ú?Ëd°gìICê‡íyR6 EÏüÝPTý{0gÇ#´ÚàšØ\GoÜó¦õë«©FšÓÆð[ 0^“öÄ–<É&åÚ¿DdJÂv™›w<Äo×›V!Ò@ö+Nhûšë8I3Ùæ ßçzÓß›þ,aœ?æw¡¦u"”é LÚ ëÑiè(ý‡x{™{Ýzì­™½OëøêË!)Ä9¤‹# ß1Ec€ã”à’øÈÖ£™Ü½ÂJÿãçøcõ:aþuÆ9ÿŒöOO_ÉvÀKÊʲT»Zƒhm“›(0Qà¡À¤|µ4±êdrÎü?ì×í1±ówÏÆó.ãã,î®Gx¬oÖìá'sð[õÍë×âp‹ÞÑÃ5a.=(LÔ:ŽÀQâPÁ¹ÙP#ûÿ•JGXv,|ýõ7àg^ïâ©›SÌ©@‰ —´Hè"@×(Ì–L1pÁÛì|û£º·@S~·ëøÓɤ7Ù&x`¯ó6¤“Ý*JkϾ>,D.ÜæhaPìX–³²¹ÔÚ­ÝwA–,ü¨‚~Ûì%IÂ<ƃ4 GPÒ²ÞÎjbò‘ wËGȃCÁâö1!Á8­!ƒÇx—ŸåœUoqiþVWN»A^L1»·"4oTü‘xDµxÈÙ½•/Ä*oPðÓPyè»94¡[:J>i”Öv„³Ås„#»à,Öœë+t½™Ml©¼¿æK®á%T™$‡Ky~Ò¦ö>ƒÚö Ä÷Cª‚ …À}þú}'|*˜òÙç÷<çÃÝ#ô7L{1òŸ!ð/öO³Kø9cß%k^}ö_µ x«ß E`šó/’O¿~*&à  LÐQõÓ¿4:p|bØ8_"À¥>[ÎóWh,YÝ|²D˜#=á {9ccÒÞ°Aˆ ÝŸ®y<—ñÈx©yÏÜÿæõ«‚Þ;ædtàfë3¿Païp[ëB?ù4AÅYÎ æ'÷PNŽ¢eû%ŽÜy_"RF^#îJ5S¿¸E aÙ&¥¬Hô%À…$ùЬ@¼i§Û+Æ”uJ¢ B`aK–ë#x³è·=‰kጢÁ)>]‡æÓßq˜öÄB àM¦™®€ïåNyÞãzÓ‡ä^¸EŒÓM2ü4Kb+7ÞzW6l¡îY{x”íy{¹†'4Uk”ì~žò÷÷С´<øS§kQ¢µ¼Šb ßiÌýp kÀæÁUŽÕ,ù{Ãß§þ±ðouúEbÅ·¦âÜ4Š?¨§S¦‰ÞAIxQÞ¥àTˆÇ°Î0h€0;­è‰šCjÜ“åÄ7ðQaî(žÇÅašt·'ŒÊU+øÂüñ¿uÔ̺]äÝšß;Ã+fì–§°UšÈHá¿wû¡ ì=tø€ôZ”&GVÈ) 1ÖŸƒê7¹Ú¦¯;ëï¾RL5oRlÕµŠzù´n‚ãú#|EÒ\‚( Û×GàÆOV½¢Æá‰lï$¯¯Ç÷üÀqÛô›¥?£lïõŽé—¶ð“êZÏåg%¶JFXÍ>”keþ!ñYQð½ÞgeŸ[¥‡Òcå)±Ïhfy]ÇáO Ã|#=ÌœÀÁ?w/?©À¿^ã{Ìêþ¥ûü™ïwÄïÙþÙîçœH©jú™(0QàGR`R¾‡p ~Ðõšyv§œxP @*¸”oïÜ>Û÷æG0±p?o¤ì–¥~kD/’gË„êzAYÌÔо˜8…´W/ÏÃߌ[pJàâÔc³¢ÿ…ÂQîp›ŸêYo)…™sìÑ1ç üÛ{Z‰vK¦k”…6bÞzLë‘hô,åû(œ!ú˜Á†á†´ÓŽUjùF9m>óºÉC¿œÛ=R _U…¸ªÏ²þI߆M ’’Ìòç{19?T×Q ¸zy»7vc ,Ó…Íö ØîF¥žüÐÞ‰¬`e}®Àý9òWøG ŽÉM˜(ða(0)ßAGÙ}L°@ú}ঘoî¾™Ýno™÷g‘ úa¾eO¿óß[8ÛêèS„œB˜Õû?Ìöo7Û¾e! Wømgw‹; RFI¥òàBGfffïóÕËÏ=á옭PWŸý2£"çVß~óvöðš+†—Àû¦ÞξùÝ[à-¦õm,«UÁZÈ!E·Ôáfûp]˜(x—ÌÇ¿˜sÈënFj¹H"~$„V…Z ß.F,ô/œ¿I\ÓÉp|j]ŠuÅ@á $¤pvb„4Iæ,Âú±Ž íA¨œTs”ëCPËÓ€¼£ª2 h»í|"•ZÑ€Bßbè[ð‰¬¢²-ïX/h™ „6Cö!é Zc[êV¹ž¡ÃÝ í Àôö(0ÍÒ…õ<»6zø:‰2xãã'創‹þ‡o]­÷J»bgF/¥;­[¶-eüÉ\RBÉV \Õaù¹õ y4÷¯Ž=k‚(ÐFùc«ßÎ>qÚå’ó->ýÛßÎ.s…ïÕìÅËŸÍ~õ›$ˆBÎÕòÕ»q{ævÖß3¿îܺ‡ô(V1wr2ŸêÀÓ›³u..Ñ<¿Y3 ÀŽ€ÝÛØ½Å­°pÄœAÂüÄ9Q¦V§.ˆâ@NEË9ý(šªõŸ¬°pd*צ0Ú?až¸9a¤/ƒ…±Òš0ÍHj„¼£üAj÷yÔ2ó½‹Äµ5:zJ=ƒALhãÁŽØ¥E ••O„Ö‡ƒƒA]øÅ뮆*.¢Uxâúúc “´ÇÈ‘Uç]cQ$¡‰-¿S æo®×ÕÂÑ#F͵­bª6÷ |^_aᨦ¢[[ŽJ6n|¨‘A%ñ~,3êãà5« T«ÃøæÅ×]Ô¿Ð?BâäçG˜‡—ä{K<¿Y×b¨"(Ý< ô`*ÆóÔ÷»dOÿÿG<éïlvÁm~Wׯf×WŒúY pqÁ~.¾räß•àêèÐÃÖî L˜(ð!(0)ßAEÍâŽócúg¾û¼}¸ŸýááÉõ<ÌÇë|€2®ë08¦ ÎÏ_bž¿ç<ÿ×ês;»»{3{ø—;”Šxœ/«Ïàžƒ¾ddzq1{õ)Ÿs ë8‹~tŸ _N˜#xõ©×¢²]ðþdv{Á¾ý7/g·°î–C Ú=¼ ŒäVRpRªCEF¬ >æìaC\»¹¢]+…LÞ2Ú5N-H#™9N ˆ®X2y¯ÂÓXu3Y›§J ¾*gªùQjx¼N§"¡€ŽBa[Áí ‰ÂV¥Å¾ãµT÷[Þô(ÞáÌ/þª­•¥LÇ‘t=]óuÏ`ù!wU0ÒJqö§#hõ™3dŠÇŸr¢•Ö#ô‡² ‡3*z;} $l¡' …'JŒñ¸^g‡)àËl 4›o¹e7ϦZZ╞ҿp8 fzûðFÙ­")ßZ%EeÍõ'¶I…x¹ôûþÕ씹ÿ3¦µ^½úåì7ÿøßU ´\_}ØÍþ*“›(0QàãP`R¾‡®{žJ@·lšQ˜®ÌW:˰ê³\bÂÄô¿g_%À«K½OS½×)‚#õÅ¢p„½Úƒ€Ž™—?Æ$ºBà{ ÊŠÅ‹cò¹E *•‰v vüŒõùǰ^Ͷ6á³á¶À½RÒvuÆ TôÊ»ÙPÌœ>E–?±£'¯lÞ5gü~\‹@pÁàùkê… ÌäŽÿÉO—2-Y$kwaXA6Å3â{“ì†ë+ú4ý|=0®ê8®ç‚{ÎŒ  ›¿AM´Mƒ#¢h4Ä|Ë3®Jº)°C?rzº¢ÛCs×B/9*`>ÛÒóÛ€º› g™§òêí×oƒ[.Ñ÷pª²óá*^µ«çè¾ WþRqÒ&~Šž‡ïâ‘—Ñ-D–ªÛƒ¬ª¾ÍV£ ¬ºÝ¢©ÿìüsþW<ŸÌ®9ëÿ+€k[ýw Àa±_okÕ1ýN˜(ðá(0)ï¡¥¬ìÉ_˜!óÿØÚ׌´7„3êg~†€ žÜ¨Ð‚K;ﵦǧ+p¹€ø„\¦P[rŠ‚~ɉhÎó{æ 9§’Šin cMЫƒQ"0³»ÕoŽ4;¦ìÆ[UX½½Gr:¦m¿@ãQ®cW}2&ܹ8s89QÀ O®¡È8ˆQTFCô("›>BMs-Ûá{éˆÇ% Ág]F>wL½ošUÿ¸Èú8VŽžWeÉR½ Ãø÷Ûy[·ÀÙëwžCk|ÃUCÇì?´7ªÄÈœ¿xƒ»Ô;ëÈ#½ÞUQ;TG_Qlùv—(·.ì;á2çý/³Ò¿æü;f¥¿Âß³Y¿2ÂÑÑNp¢ÀDOIøš* vì·g~`~Ãþÿ÷Õ—³¯Þþž8FâÚszáJ}o);fL ,têr¼™ÿ|5;eغßqæù“ý+¬ë[¦Øþçœý}]øƒ8†±>ÎÞÜ|={¼)vëòmâD¹Õo"tn~¿ÞÌ.ÎÞÌÎPr—­5;³ÆÀé€5 Ã7œ°ª¨l`ð¥ˆP%À UŸf‰ZØ£"_Mî®eU Ä;1å#áºI¿ xµš …ü—gŽDU iæ4¥œÂ€eTÔâ¬37Î<Š4‡˜Õ-.qˆ%ÆdÜH?¨z¥iG—üUÖ¼Fk©hÉ4­;fwd-kDšÞ˧YO4‡Ô”²9Ýõ”ßék$S"ºüÚIq¢vÝ«:â~–qŸO/,MÀƒÃ¼ZŒªLÑÑ]+µðÏx¿—J·>)ïîWa¸4Vün÷[`™r®ÿdåTÕ9óÿ¿˜ýÝßý×Ù«Ï‘m*Ÿ¼üE”ÿÿdk”€cÇ<Á‰>&à=D•-úçêÿa€§²ðŽËxÖ˜þšûatK8§B³' #Íf;:uI ˜Œc®~¿¿bï>Ûøþ[- oØÎÇB)-*›5ç ª„‘Rî˜õÍ~.>⎌p#í´"l¨8lå´4#l™ò–ôåP=«ï6DÚ'77-‚ƒ­Ö!37@‹ÊuXQIiQåw K¡Jޝ—ðÞ-å½3G"Ÿü »z¬²¡#4n4EP‚Ç>·<ä˹6=?ÍŠð«æM×-,¢kIø¿¢îèÍ>.Ÿx~zºiÖ7Îc™±«1úwå¨ÜN=-нŽ¡ÞE…ï¥§Š«§éWèSš§€ÿô-ްŸŒñÕÿmtyÇQà2²W1^ €k÷ûsÖ¿+ÿONΘ «•ÿ":|Ö0¹‰>&&à{©ÛY`1Æ, ŒR€äa˜íõ¿®¢g(¶c¤¿U»m€±6S `q8:c›žóÿ.tu4Âví¼&¶MGž!àU ¬Gûô‘CyíÔ¦ PB„Y,–cô¢$yä!›× ëÏbÒdå%ȉ“ÁSªp‚,ÜÞ`Ob~Ƽý…èPß8jìÿÿÙ{Ï&I’$=3’géêî¡»‹9àNðÿ>CN Xœ` vHÏtw‘¤™÷<¯šzxDeU5›&µn™îjDM¸‡ªšq‘æaý]´iºyº”ß‘ õÛÝ%ôVcfq߇ö·«É„ÝÕihB”— cÛ]½9®h¾ºýøÆ¯Ôq'R ÉÔ¯³Äé9ø:ˆ’Û¶üêŽW…*±*Žñ ¹ŽxßONkkë9[[ÿ÷ÒìÓ¾ðW[þ–E;ݺ–øQz`QÞ×Í2ËæÈrZÍ~ÀÄ éhÅѺ'ûÉ0ŒóqŽý½CàÂiðÎþÏÈÒ|î Ðï*qÍ®†å<·žî@¥B¢˜è‹%SB~|XˆŒÑ Ž0ûG?p´î´ø®ÄwßS£„I[_ŠdÎß>ÿÜ¢ ú‰è¢]Ș«uZTnÛì¨Rr0;<¢w@eQm^öòIKôQú¨âWÿÄ«’3¢ÊÔV¡7 àíò¦©’Éé³ æžâfá}ïÈZ¸Ü§ºï#&\ïÈèµüþ’Ù‰œçŸûE*~:oÖÆ¤¶m¾ƒÝFƾ ‡§=k`ôKНrúî„߆}æ¼ÿùÙÙêésWû×¶¿gŸ|йŸÿ˜p ßèí~Ò_ÜÒKü¸=°(ïèoY§Œì3¿ç›1¤9>cDüæ)‡ý¸àÎ=Ó~î7[úÉß³pïås× xz_1÷cªhP—pj 8ab` õÝ!B_Åáóý׫¯þúÈÙþ,:D%€sœp C3r>Tô<è©; ¤Ie}˜0àcö¢Ý³¨ð-_¹ÎÞ4[Ä4ÓniŒõfžm\2õ飿n0èÒ€bŰ?L“TðUZôÁKsÔoòëõER…‡ºƒ' ¿e¯òÅBà•¾Â3œÛövù'‡×©’QU¢­‡T¶N!7²¥ŒmrÊL„ ‚×YòüKO+¤9½ÓUd›ÃE0_§~̉3ÑþßBgHޤuFo™s—ÇÓ‘ UÎ1ç@F­Ûš/Ìeq÷LÝiP`Å C¥‹æóW1´:èÃlaEØ«ᇠΙòž0ïÿâÅ‹Õÿõ_þ+ð×|äç“Õ‹Ï·ú»¿ÿ5ý{n†gþ «Ñ)t¹-=°ôÀÔ‹ð¾Ž–Ë NˆÿPÁª€‘°Æ}¿ÆwÕTĹÿww˜4=ÿ_ Ü2sù@x„î¤I›q DWñK~0èzwX6¬p…þýÃU Æ^{Ò…VËÑÖ™S @m®*G̹ž5õʘM:D¨æJ[‘ØJ­æé&Iæ®§ãH¨þ“6ÖðGAq„0æ"k‹{ì&¢ñ-rô+áY÷!ð­Õ. D%‹LÜ, à8A25õNŠÄ¶Qí-8K3Âì•:p˳¹vŠq F-Fk*¶ãgJÛ¿y]øâ· ¤Öf°×ë{@*æ•¥]I"â52'/j©Úþ]ͼ_¾c\žj©ò©éÿ”-ç(OŸÂ®>Å ð‚Sÿ„ZžgÛ_ÞÙlûkjV{‰\z`é¿Q, À:¶Ù©<Ú³ùÝÖä¡=!KðÂìä—ÅÃ5±ºa c¯i„/ €#$O |€á=8¬CÒ8ïYùA!Ôè+Ðüò_]µ1S™Î"@UH „¬)øÐU}”á±¾.üÛ/7·nâŽvRòNX”¹k<ÓcÎEyI¡œ!°ƒ« 1ƒÎQvg…̼E~¡_â#Nà9st;ý<†íŽÛA&r†”yxîŸòÀc›[>ÆoM¨ëb¾¥ë,¶GWïSù½ÏŠØFÎâ RòYÇÆêçc—3E^úóŽè5Ünî︴z¹¸YÖ&>ß±@AöL §<ÝÒÏüžeÏ?&üǬò÷[d•Üû •µx—XzàoÛ‹ðžþ•¹é„27…ÿ“§«ëVÞg±žó§ŒÜK¬ÂÛ8Z—‘ü­‡ôÇÌåk~oÚ9(£hGì ññÍð¨˜c±"@äÓUäÒë;× &Íh<Ûöµ.j±7àݳàXÁp ²Ð‘ÞÍ '¢”2P­q^êBþH £›éë÷‚n°w0IÜ’R8Lu˜®qô+…BǼ‰3QìrN§LBާˆéäôÕ0¿ åêj!cùM½îAó˜Ê«ß:v„éÛ¢SÎ^pÇ 0µ±‘€ÙQÑaèeÊa„[¶5$y§}Qf¬KçÇßq]Å©®!‘Æ×oë¦4zrHóêsT­MyÒ©!1å…θM´f¤G\ÞcüBÛTÖ¥ ;Õãt‘Ÿ±v¡ë1‹þNø®öâɬø÷¸ßC$*À©ô¼°Qþ–XzàGëExgW+–`PüËD5³Ÿ?9_ýÝú‡Õ'w¿ZÝdKàÃê/_x8Â7£þÛÕúæ5&üZø'{;Fè 5‹ž±"úÉ æ<9ݸCÖ~Ψ¡}Ç÷^~ýÕê«?} 5Gú>°¥ðöò2Ÿü-…Ë‚sîÖ î}‹t¸c€BPÅ3õ¯9œ¨ÏÖ_#®¡µVqˆ$Àz„:¤ülCD 4(a ²øfB‘™«ÎÙq0ê~/2UeãO”Â*<ŸðÇsçÎ…v–m‚)œXh ËT]é³õÇü {$&ë„Xñ®aìt|]’ÞDÏ…µÂ}.ñÒJ{XèE‡ˆÄ h1%éC^åsošÁ!—0.Z=E€?üµíri¡@A™?4ŒË·ôX/žEÕµ*é3šÎQ%ÂZ]Öœ¾$ª=NQŽxÖO˜öáÑä¯Òã´Ø)°zâ±¾œöÇB¿Ï~û«ßýÃYý¨"à1Àç|Ķ¿:ñ/¥x[ÜÒKü=°(ïétN fÍ'O.à²RÛñÕfõæ6Ï6À5 JÀ£ÿZIí¹ÿfÄ ÄzÀøž¼ÅŒ-¹FàŒÅP®@0Þrh£ÿ|/Iÿà‚=¶ blpÇa1|%‡Ò"|—wæ!1ÇÔ#B´,­­€î4ƒSàø=9ÏH‹ÌpÑʆ¾éÂãܵ–aÑcDNê)ÛÈøML^êÍíôB Ãm X½0J«²²q"¹ëfó»Æìè’1±Éá· ‰Ÿ®ëtãæN|ÃÒÀÅožá·<âê–?çT§Ù!#Œ3¿—¨µH˜hnêƒ ÏüQtˆl ÀŠ@¾f鱿Îù?ãW|Ã…šþëùKqqK,=ðSöÀ¢¼³÷Kxewm±ä çc¸"2•yNžU!çG'`„…Ðf¥¾ ø\@¥€ÊB*$Ç=ÒÑ€ü";ÛúZ8BI» ’@IDATO–˜†¡)]Yk_UØ,yÃí7HyºÌÞèuLö°Xüš§%A`ºŽ@F~úIûKõfx3oeµÒÖÝë­ÄOÚh懊{«J’ÿ!\W­ëØát:t9ßáï[¶tšVû;üV‚…M‰U²ýj\Gç9WRîo½SwnÓ3›ûÅB²}§[—%œû›˜Š 'úÕ4@)ÇÇL Œ+GýúN§QkK,=ðSõÀ¢¼£çå• ÿõ=ûò0í3~g}>#[LÚøk…¾ß“ù4sÙ¿w{ Ÿ•ûà•ðgÄ ÏsýKöVwWç|‘ŽUþ˜L‹!cS¦0•†{ŽVB¸Ÿ'sÈA'¬ˆÂÈã:eh(·\” Ëþù9¾&: Zaáˆ;£TðF(³°Ð‚/òðO‘I4¼²!©3¸]O^îˆè)b¨\È߆Z¼´¡DE‘,Å„èáG"NUÄ\VH:Û+áĕՠs?¹ŽlhÂÜ?!O§5$:#èÞ,)±¶µ»Ëˆì’zqã1Öj”þ˜žuß¶OÄÐç&ŠþùEО”koÃÉD@ruY¦ˆâåÖ#ýN›hw~ êä¶ýhý·ÅêõšÜ¯‡ùâ7‘´ž²¦åœ­}^ú£% >me‹;;Šür_z`韨`¯ãsq ù;¾puýzuµaž¿[$îÝÉ-«ìYhÁÊÀÎ@ pdwûfuùç/V7—o¯á,Îã¬{¡sÁ·Œ†î^bõÃ' †‹èp®¸á#CG|Føì‚UÒZX#p{÷ õÑ>8k­ @ùÕi€|<.|úܯn8((öw938T$T¨l8¤¨Jú0†n0+æIƒ¤*Üö• KƸžÈ¢3„TA‰x(ÔáÍ`‚¤I^"¿Û'|=Ë^¤Z«,!Ú^¡ /ßå ’æŒô`té{)Û¯0ÏâõŸx~‡é„(-vÆpZ†¶n|rˆbŠ}U°Â ÷¤=pgÝÆÕTçõ7Í5"ÆMˆf‰ÃŸêŒÌ‚nŸéÖÉ”RfÌpHR‚Õ÷ƒ„-I¬tNø²å§ìùöéç«§ìûÿü³ß¯ž?ûŒïU¼˜öûg 5ñ.=°ôÀOÕ‹ðŽž/ÊŠ~àšæ¨xp#ý„D™?­Žà]È—ùVÀ=_ë“‘>œ ïøˆsò ÌõFXÞ³”?¿Á‚ @”?jþÏ—ÔXQ­8t‘! ¥^n'ÌÈ©®dïKë„‹âÇwÄ^·âô×· Ha¡b!l!‘%öIÄO á*[ë‡B‚xnX)"¯ K„8¥~g#˜©’i\Vu*Œ<~`ÈÀ§.“W²èJª5!lã§(3$Óó~ϾÕ|— YÚÖäcò6œÎ¨\û‹·Ø{T³ê þ*Ü·±EHeíÔ N}›×a4dÞ_ór,Â÷ÒG5ønY»ÎßuÊ3œ!l±gVÿŸ»ý¯-ì ð³×Zæ}5#³x—Xzà'èExg§+$1ÃM== ñžùuGöH6GÍšùK P‚r%lšŠ‚‚̈\x€)ÜíywLðý`GÊšˆïOQüeå¿YH€Ä#¬±äÉË‹¤õì€\9·ÂTê‚ņR¤—ÍS?*`ÃtEÁõI¾J é , W¬¼î†q¦Yˆù/Å¡qFôÈ”q«ì?ÈÝzºKÏ&ø`yµa×½³w|‡?-¿óÄox×ù»ž£[·™aÀùˆ¿éî¡<œÚ¡gvµ÷ÑL?@äTî(v"Iƒ}7Ypœ>ñ‹à?DYuá©ï õ¿MK§ÏÒKüÀ=°({ŠˆKŒPáïÇyî0»ß1ÂwÝ gó £ø™]‚˜ä•Ƶ°Ìú09$¬V•ƒ¬?¸[]_B×Q¿Lá|t [j–¿EY¸»»ÆlïšÊvÔï¨>z©t4‡œ¸Lò#ižÑ·|VòO³OŸ(žQàœµmƒ|ô‡{”„ji.o´K; <ã×aâFYT)#|é›Ù-+e¥ÎÀ·U8ÌO=¨£0NÄ &ÚF²ž”ßõ1>íø?‚ —kØñs¸—ÖAaûçèßÖÿ>¥ÙÂvñOm'¶ý ²tû.‚81QðrRã iß;Úꌎw„ˆ…f[… rßfi–å¡V~ú3Öê€9þFý§|ú7—ÇýwäÙ*àöûÓä¸ôÀÒ?], À¬ï# Xü¹ØÏùöW¬xyóru›i€ûÕKŽæeÓ9£yö ú€ã{pͶ>ÍõÇy””‡KÖø Ä>ÛóVWo *0½çt(N¡|rá SvO·SYTGØzy±‡çÄÁðµFhy¨ýô( ¬!P´;wî9íÏΑ¹w ´;–7_Rç[ÚçgÝÓ%G˜"@(f0þ¹8R`¤Ò)Úú{õÙÿ¦HB©RñôK‡ÃoF÷¡ܺmHeæÞôªòÜê8Ql¶™1xX‘mDŒ!$^‘3w±lcæøbºd`7GU¿sX^§Ï}ÝŠm\åÈsÆ›þîUw¢%vZ ¡©×ñcšúCœþ×ødtêÇÙv—šlÍî$˜6½?LœHã5‘zöuñÝ´Òés̪ÇÍÄA?Ï?ýíê³_ýk8ú÷ÅçÌý»ïÿýà”¹Ð Pø~&øîl©ât„» "P•zÐÎTB&ì›I×^HèZÀ5Wðx5š3!ºŽßWæFa¨€ÆYëafÐõS8x³Â ëýwó4}1çþGr<‚ùá¨.jNSƒÅûœÏ½+™²÷+Ða¡ýÔCÖ|Üil×¹qRÀÉ–TqqõÚVÄî’Å&”@%ÀoR`8ç“¿äå×þüÐOiÐõûS–ûÒKü”=°(ïéýŒHòh’_sù½»l l= ‘ô˜M¹)LÝó|pãu?jÄ##4€®aîøeĤª8`ÞwØUŒßó\uïæ,˜«Â1J@‚wó€™%BÙ!”‘0X"dÔ}åAJÑ#H#ÑK$u),EM™%+‚p¸›=x¦%lÿ _´ïêšLC‹éê5ÍNëð[ÐL]¿]oPgIs´·È|(bNgŽ»WüN]æxòw;÷ËÉk`b#|ˆÐ÷MïóÞ0úÏ‚U¡ @Îà Nûs=@™ý¿o¡Kþ¥–ø[ôÀ¢Ì{&ê˜JÁ¯ðÍÂ<Íü~¥ön™ï¿Æ Ôt.ó½&nÍôGœâwñüS„v) ',ø»%ß1ð>ûí<è5…¸÷%BLdëaˆ12Ç4¯Õ#q­ ó&þkî=`j!£lðØp@]„*x…D‡(Íg†ñT+g¸=¸8üF‰buÃÇ\"e“ƒr3¢ù¡›Dh©p³ýúQ¹J!I27§0Ýš¹ ¾ÂíôÎ#Œƒ`há*WgØK7I…¥ÑãwDØåEò¥ßMêuF¾æ÷N츩°mµÅ$TÂ.¾sÌà,3±•¯sZ‡„y?f¹ßò‚œÎDÈ)–‰²ïÐ~¦ ·ºÉÇ)NãÅZeœ–NÆ<âƒ?™ççË~ø„sü¾Åi:=ms¿ %¼ôÀÒ?u, Àì h•ÿå;õ°ê5ÂöòêfõæõÍêŠ~®¹þô׿ŠéÉfÏŸ? ‚¢p¹¾¾Z]|ñ‡À ‹8Oàþê=7€-ƒ¯¿ü"Ð5N+¬_£(äµ`Ï?DY8Ô®½™7G g=ÂÅ…Ä…ŽkšA³!âhþ‡[èÝqâÅ14²`Ñv“žÑ57¡aÝE“pVt I1íÀ)`°4 c¤mÐb1ˆ)DÌ%ܺäAüJß•:qkŒÌ3žUQË›=íà¯üp·Ó ˜•¥j;õë²Mשﴛë>‰ƒ€4r‹‡.°¢¡ü©7}mb»(PS S:S‡) õ®ºÏ*d¶YyæËg©G&O”KuwÀ½ ý—úJ3—ÓJxþncUà_|ê gÿ?ÿüW«¿âúü×ùäïkü>@ÁòA,né¥~V=°(óÇTÜÄ·td¾æàœ,ö»]¯n®¹.=aÎßöYmÎXÔÇV>ç×ýÌéÅóÏVg|ðÄåzG(WŒèÖÜ£Ü Ok]€ó£/_"¨4ûS¶Vç±XOÿ!åg2@¡ sV ¢”€%Kà …AȬñÂØöaºZz=¡¹98áåˆrÐ$ï-#¾Œ0Jüá Ãt.äd¤pÙNá”W墳ktß÷ažÃÆ©8C(í¦?ÏfôHëQ¿Á({xó Uo|MÞ$ý3”FÝÂýÄÎ<0æÉúU0æ}ê“{¿3WQiZÛ˜Nyœ‚xõŒ*½¬Zäá=ÒÕkAmæuž8&O(¾WŽþ½Ú€pÄuÌåI€±Ý¨Â¸¸¥–øyöÀ¢ì=—(0\ÿTÜ‚çB¿5—«ýoo¹_;êVj²'Óþü |õ†çÂ'WFoêøSÏGFË‚@´†ƒ˜õ9xçM½ÕûY_y}+ ‘«±Át·GÔBÛ†N×Â7¨ð^M¾nõÓ9zÌEÞ.# ãÖL¾¡¹•ÛÀ{?¥“<÷‹ÝByÊù‚HSê®02z†4o3üyú–Êw÷½¼iVg^|‹·)® L߬.Ý̲ÌšÝ  :*”ߊøfå½kžÏoj’~"þýÍŠc”wœ`Ó æÚ—/Þÿiÿ^‚w–¸$,=°ôÀOÔ‹°×ñ-#ü°~å¯wÜÞòé_¦®8²7ò—Û-Ÿñí“Ôoù|ï-ýÜb€®ñ{B ¶w.O¼gK#@†Ñ÷îX3WŠBÀNƒ ¶båÿ-ÌÕÃz¤ŸÑÿÊy#ŒS LØùôºÒ Ò£ |—'øu–Ni8½kÐrVÁ<üÇ­G¿—Îþ˜»Ì6(R>iŽx!ÔÏÿ¸Í$¦Ä ˜+޳¥l”ªÐâÒ­¡`„eãsÈùû£öÁIAÛÛ ½Ð׈VM‰.Ä­·“3yÇÍã™ârB¯¶nGÜÖ…ÇöMH;ú#5(š¹·†g "¶9§}‰¯èÝöŠ0uWF×ÅßÙºÐGèëÕì¯gÈ‚ÿ”ùßßSNùó2mÚq°­Õâ[z`éŸi, ÀìÁ(È2âGèj†w¤ÿæÕåêÕׯWo®Þ¬^¿¾Zýõ_*vÏŸ`úd{“ðäìvu΂»³ÏþÈ–Á7Œ‚PîønÀí׌î9â—…z‡ýÓs?‡Ê'€9+`4{xñÉjÍÖXn8BøîëKÌö}r "S”&'—3kî^ãÖÀ¤ÙâÝâ§ó¾Öz€ö¨aÃ*9mpäQvRÌVn›Ñ2f®õ] E} ¨h¸2˜xêSß›×:"ŽÂŽÿ sžiø hJNd¢V'3Á&«üuâ9Ç?Çï] I·¹”9²§u’ˆUzãK·¯ ps fÇ5òˆlßujüÐÇö5ÚV‹èЦwÛ¦LO ·œñ@eÊ‘ÏzÅ0)Œ ÄÄ_Ÿ~f"}ÆsWS2c½¦zJ‹°3F’4Í©¡#öµúþx9Ú¿xêêþZüwÆ–¿çŸ<ç{|ö—5Ož>EÁŪÅC±Õþ¹®Åkê5¸Å-=°ôÀÏ¢`ï1ÈP½¾ž“¿€;ÖÜa¸Æp V :â¼ÑsÌyýXîõ±ØNÀ=ÿ T«þ=œgódô¤sß4SçLÜžl2ú`AŸ rëžB!ûú‘Ð9ip0ú]†/Óöoë¨v\8 S4”Ò0}æuJÀ¥)°’ Mð yŠ¡=ú‡Sºž¤Œa3q tèå­°5.mDL5¢çâ¡ú`[Q1ÔÀà4=Ét¹#n'8ªe7ÄÍ ¨‰øJ'ï§ïƶ÷¤3Y÷<ûÊ¥×%v­–ø]=[^þ¾C)•'“QSCF€çQì<£‘d‰ÝÏ-Œçm¸Äï#µkãžòWæü±ð÷õ„“¥\ýï—*ÏO¦²¢à z Xz`éŸw, À{ŸÏ˜3£æ­€jDžùu˜°Œ3²P<„þ='ÿ`Ç÷˜`ÊV˜ˆ0÷°p½2Ÿ “­QëP&ò©`òcÀJ@V½øÃÛž–»áñJBÓþñÀåÉ·a £Ò–2ƒŽ4+_î“0qQ_Ñ 1n”;P¶ ñUëæõVâˆú -àV-©Œû~Ãó¸¹ÂðhQ]5çþG‘ßÙe6‰IˆvÄÈ:·H$ª3Žô <£{Ó…DÔS];Ï£ŸôÆIß«MÇ<££R™.FïQPǼÿñ8þ×€ôkÑJU ë»í±ò–¸¥–øÑ{`Qö»|0¾–22ébjÍkAûs¹ØÉƒOœõS¨Çšýø·µ« ÐÜ~ÇQÂB‡eù­ "ˆ7XÊJàÒy÷ã3…p¡ Õ±&`B½cI?óøÊmGvõ"!œÊ9‡o'7 (LÔ5e» ›I¬v6jD'2}넳;Kî;°ÓG¾¹#xn]? ¹sDÜn7eÄn“‰#íkL£ $À$¸ƒ½ß%54C4°ŽèjØåTrô‹øœòêÉè|d³VyÚÔT@mÑwiÉÍ ËŸ QÞq]-æÕOÛMëôy&â’ÄÍ‹«àw›h„¾–)­WœuáWý…˜û±d»Õ8þbòw ËÙ=ïz¾Ûy–`m…‹[z`韺`ï 8éy™Ç ÷,–ULVf+óÂ8æˆ ÿù‹Õ“ÏVÇndƒýå뿬®.1Û³ZnÃÈÿúÍË@çrÍ}Bö¢%ã\ô€¶L¯~ýÖ<œ l²àð/ìà!”v" Üz41 ù¢HÉExB,•Ì>•%–(jØej Яӂ¥"ùˆºÊ¯Ã"á×Ùê¸yXÿ°,túè2èºk tt*#L2[¦øÖÏï#½8Z@„U`áN•¥qôUŒ&—úiSüð@5Õ¶›û§vw~êášTndè)ìm¾¹|¤ç\ InûÀþhò]aú‹„9ôÉæÛƒtwxgʼ}žFyªóDߪõ5¼Ö[ãR ÍG‚–(]žÅÉ!ŸôEÈkòGÙ=eËÓçÏk à|uqê¼?[ÿ¸ŽXÜzÇY—(½~HËi´§¼ßÇgm­ò%KÞÓe¡`ºx¹-=ð“÷À¢ÌAsFáðËLe¸¹‚KB”Ì €+ ‘ÜÇ0ËûÖl0ùcx`ÑŸ£ûÛ+˜!Бœ²²ç|%ï|ö)£}¡ŽAÖê诧1 €é>»ÎŽøœµÎŸ ²n*2UÕ ¡¡T:-‚zGr€Õ–@æ¡õ*Åi!Úþ"6åí¾…XÜ7w+¤0Ë‹@ Ž^í•þ]tVþª¿(­¬è×5¹À Þ–7õEãL¯î0ZìYŽ S£àyêTµáIûEì„AÈ`¢Æ3I˜[N„L‚´«ÿ„MÂþɉ›WLÒ£k§´ו7c*Ù{+8¾“GcjJ @Ö®L­¼§XÜòª@á¯ÒœE´(¾*¿¡‹ZšÓ_‹[z`éŸW, ÀÞópôÖ2´œsÎèÇmO9íÏÃN;ßyzvÆ©B9Âýê¤>ÎþßpÒŸ‚³.3ÿ4‡?ø`,Löž!]„~¿ìGQa¼ÖÁÑpF”G\þw™~·Á]ÙרDÏÒDÝwQZ¢<" >ÄÇ“¢M'¤¸M‚Ï?P‡ý:í„çukÿÂ÷ ì“ü`U¡á~ñƒàÔþYxÕ‡jò@y+ùoAú]ܾw*¢}¹#€ß„¿àŸùUkˆæ`'P{>¿•Þš@éìâoÞˆ¥€¥–ø¦=°(³žRèê„-üÏÙâtΗ͹¯ñ|ö«»ÕùSVöÃðž~òtõŒOž 1`þ<ÂDÿgÌò°AMÝÄîšç¯¡&\¥¡UG¼Çz䟌„eºdQ5Ç?$‚yªV뉃0dh((ð a.òg‡ 11(R0W™µ„t¾á-ØopB6@pg`×…ZP‰J6´4ù:(l´vD©‰_”Q_¼iaç-ÛâOÜÞØb†«Ñq?U#m‹™F›ŒÚñ'b{ *¸)g îdŒqæºvf ™¦5à¼;ÓOÃÊ£ã4’”³-ºþø#± !µ1ªÑg˜‰"-ÆŽBX` Ó–Í<ãK®] ~Ã5ã}QŽYà‘Ø¹P ²øwª˪ð®Öšå»k8UžÕqñ.=°ôÀOÓ‹°ßïòo™(ÌîôâlõÙ¯?_­.W׌ä9põÙ?þç@ÓÏžœ¯~ýw¿tÄsùò‹ÕÕ›çèà׫û¶ ÞppЗ¯9,ˆƒƒ° ȼœ Â_!±Úœ”9»àêGtÍ€»dùõ9UW`³ðˆ…lÔr C|—Ç;Dµ 4‡UI°9=úR©¸¿Ñ,Kd„Ëm!ÎuC7§²Q0A™yV‚?ŠmgºQ†g5Bà”t¨àØÆø KšÖÒ/Ü –¾„%ŹdÑ­04Ç®³$ë/l—êw8¾J»™WÖôV‚ae¤6§¸ÍªÏï5ÌF 8èJÚoÓ_xF$Îx•Ådâéi£|né«F°:ÆÏª£¿“ÍÓÅëßwâåñ¾–(aÓÕÒ%M-_9ôçë–{û5ócñ:y2¦¼ØÈq¿ç¬ðØ_Öø@ß±;Ö©Ü&ß;büXÖ§ ¼j €%VÙ£: Xz`é¹`¯Ãe…þe4Òôì &wÿ„èœÂ\™ ]t€SÏ>û4P“ÿzÍ.Ó‚ ßs(ÐߨÀ ï9¯ÿaVí—û`ÙŽø@õU³ÐéZê’2Êb?¡æd…ôʳü]ð7ö¼9Z’Y’3fÜØ]5³+ø±ùz…¢ Ü‚£r:bWÁ€šRo1ׯo´"`gMÁ†ëžÅ.™¨.GÇ–74]U¿e®|îw&€2@X(ip¹ß ©i…þX»ÍO;›ÛÎt¯žš0.™Ä}KÈ”f_¢Ç1sîX˜GÅb1¥[â6UßnÌ<µý»ô&RÃSæéYì¼@ ~;ûN÷X6Þ|4_•ë”Ae[}*½YLêKlý)kmú·ßqv¬_2’ÐuMœa’<êWX—ÓL†ëý-“ý|„Ï–@•a•âI1Ö?â|çU&zÔÍÅ€^М,[³ ¿Õß; XK,=ð·ìEØëÝC¥ Vˆ¹ß‘?GžbætûÞƒOž< ”Ë)l¯9ïÿmàõõ"u*>s§̃æK¿~Þ—ƒQ6þõÝu …8  à¯€Œ§ÐnÞ8çZu¸ã@¡7/=‚¸, Î{ÈÐÃP;B\é²PR¤]æ‘mc!òá!p X´LdΛ4xv\CÚ3˜²g¡^’ÌÂ"EŽ›zD_ÁH:>ñû2óð ²ï$ÓÊÐv“dÔ%Õ‡ Ã82Ò(O"©ð§n6wãCˆ‰z;«„f±˜-’Wý;/0Es+ îö뙥sVö`œJLõêñ†¬á0ƒt¹lÒ:¢š¦x®°Ïu‚Œ¨G«Ý‹*MON ˜„,éšé%(n zÛÌ[KD¦½˜Ç‹bpÌ׳ó' ~§ÃNÏžšvêôØùÓ@îÈ” Ày~…kîypni«£¸»î­ˆÝäPõÅPaF ˜»®ÜWô»”©jI7Ö˜ÑÇøšZãu_Ý[÷GGLˆDàOûFœ`êñyØ–ØÏ¬ý]·TEmªôhOÊ-@ Ÿ‘¼°ÒXã¢ðæ!ÖjGÿŽî æÄ¿á¯ø™5 VR$Ò…’LŶ€ûñ™Ëª?}Ž6Åw¸ôÀÒ?Z, À{»ÚÑÑ!‰‡_†•QÐÓÎò± †æNxü©<6¦j^Gd­D˜–ü2r%g˜dAG¶žp‡µàÞa+RÔuƒ~Í/§Ç¦`¶ÈC‰IÏ|å­;V‚¸¯ éÜâ'C„Œ‘;§låáNÕw#¥¡›åk”ù6a\¡7ËdÃ7‡sÿÛT¿QL×­¡õ°ú©Ð2F{‚ã­/ÓqÁvu9¿½3a …ð#þ9oã·¼y™3úñr›?·w"*ŽwqRÊŸw“¸é=Ïè}Lð°]ÿ’¯ÿ]뢂 ‚*ô`×ÂÔ·ê{Ù>›ò¶eVóºÒ ¿M£Ü¥–ø[ôÀ¢Ìz–FÈøÁÍF»#Ä‚T¼á‹}9íŒ|Žøo8§Wè?ëëköÕ{²ßCLçÇ0Ö¬šæ(Õœ„æJèÊÐê•¿‚2ogU*†”rÞÍç}…%øµ:˜«¸>5CN˜j¤º²a0Ø€eÍ%FÍÿW£U$lóäR‰DrBW¼mDÉHÃF+X¦ä©ÂH1¸#ƒÀúŒà(‡P,G϶††”_ÂvÛºuÌ.´~Sµ ·PGÛ²OXQ¨âíÛèצ1/[”Žoô&šaŽ4èMø{žöW}®³äÙÇSŸ\o³LD ò@bh§‹ô„iºáló³BCÈhßtGïeözØfýããZèê€þ#¾{qè4A¿šîç±p3í•í‚î P9ðâÏÞí¶ ¾ãå¬ÇÜd1¢°ôÀÒ?J, À^7+ôåÙÂc˜"ã6þi’çÓ¿puõõê¶F¸ÅìÿòõËÀ‡û;>éË6À»K˜þü>¬žóýô3Vþç >|}yÉ7×@|ÃÝ=ß?{ë­x7îˆà ŒÖïù(PŸóoÅîw†üÏ!\¬³ù"@„†Il4Ã{†#X¶UD-îÔšLÌDkHøÃÆ”¼ÙøÏUY?ówä–V!ÕtBê$2­­Sg¶„ÎÙ›Q?•¯ýšs]É*DЬÆœ¾Ð)¹~þâÓ@-§Ìñ?yζW`Ö° öâÙ Ö”pŒrðäâ9i®cAPI€Ž]®õI Úó0|ï£p˜f=€íŒ_ÜÒKü8=°(³~# US&,% l:ð l¾ð‡MÞë–…7t¡Œíhu³z¢@ _k €SÑä¿a4#Níý.䃺 ›†!zëˆ+m” \Ák¤B.ÿM*oy"€L¯`ìV5måpñ8E(lZ(N,ÎÑ'ÜÙ´GÐ2æn43Q&Y‚þç¦@¨€%8â«[’gá9½Yô䜃ä6Ÿô·•Þ—7»Õ%Ô+so³Ïjj‘$ì<Ÿ¢D黥TÂh5IÝ&a¦}DYxe&g5œbJ… øÎ"ÈsŸOL#\XÄÑsÿšñ­gÞuqy¿ %Á_ €ý#Ðc`dÏè_+@úñÇÀÈ_+@Ö` `ä¯àß·¤4*Ó_Öb(¨V}qK,=ðã÷À¢¼³ÏŒþ1@áÊHQŽÌ¶¿$¶ûÜ3ï¿Æ pÇg}YæÓŒàY*X£¸¶ÓùŽrr5ã”ÃøÂÉ* X#êªhÄñð[´Hø {ÛÆ¢„¾›â–º‹%f;S’*zGÎᣑs„áo¼4’¸îh±ô÷e8n·9;¶Q¾lá¹)!ê7¯"ƒæ®j¥YÁÐÈß±Ýþ·ÚýèU}Z˜C€Ê;u5_Õ_ûô ‰ ospŒÁ^ø( øý÷V¿ÉìŸiã5õƒ£•!qâÏfÄïÈ^Åò¢dtùÀïÐÎ%ËÒKümz`QÞѯ2*…„&ÒbjÌßGø#øú.þËÊ„ÿ:NûcW?6Ä? SkŽÞÄäéJhÏp<=F]Q 8=õ‘zH„pZHèqûÔä a+¡LR`ÎPvXlðIœŠ? à~0 ˜”QFšˆ®‚Š ¡®‹ž?¯Jpf¥%¼¯áŒ¢*Íû^†½àNö©¾ÛÜßÊ'më>/cîoe«à@öQ[~_Û‚ç½Q馥®à§û;ñšÃ»LqJÑÔ:a­­ J?pMûÙ9t„Ÿ)Fî ר¾-â(Ôc àý«¹þÓ@qLótË(ŒâOéû±+¡qnó;ãf Àã 3UÅA<ýÀüf´"XÖ!dŠ2ð …ƒ†X‡©m‹gé¥~ìX€½—êœû•©]0úy8á9®g ßúêzus}Éz€»ÕÍíÍêêõW÷ü#>¼^ÿ%ð ŸFIàûèQ".YMÇõÔ?Wû>œp®€fQ¥ñÎ Èø¹Ü^˜?`ͧ©ÿ°R¸é¡Äå­S|#§Y; —”ˆ”®¹‰ÙY4z%ø2n ùEÒ5°]§Ò¡ßõ/œ²4ž —õ¶ÛÑWbê:æþÎó>XÏWá—*gŠ¥‹ëz u⤭Á²Òý*)S4àvx_¤õs“^òÏòJK·Qá¯rQëð'Ožd*ëHý˜JM#|úé…ÂÖ8”®#t`™øk €ßv;ú?æÓÕ™ÞÂ3?‹ø„ hù={ƾ‹ýˆSð?ýÄ5eò?EàúÙ¯XPácàóçŸCsÌùc ¸xò,²ûú3Ò'ß)ë>ùìó@×|œ¿0[ñŸ_ð­wð[ÑÔ/ý­Éß2«nÕ%ôoHn‰R1ùeºúíz˜ }ýNý}ùƒð ÛV <¯L{öéêß¿[ÜÒ?V, À{zZQèµ×Äoy¼ÔåýpϱL+Àš¼ ï80Hè€5_ôËZ$¯Âׄ„îˆ|# % Œ#ß""LEÔ£ñGäÎ7Ö‰ëI{²™/k ªÙJxeÆ1Yoùq5̼íL›¥R•*}})žõm|â3êíô$uâè÷¸-þ{¦$±¿]Ž)ëðl)¤›‰íþAåmîöËš5µÐš¡Âõ­I uB}š_ ù1š'-a¾Æ$TˆûþŸ”@u”¯Ðž,îVáá›O§Jð=Î?`FìÐrUÿP¼æòãjÖW8çc@Âl÷c±ŸÊ¢?h$i)ƒú” ÿ¡ÐÔ»ÊïÛî¹tÄ/ä±rÓÐVB(ûNó1`°ýrÏYÐVHX7·ü›½Tù#ëExÇõçêoÖÑ”Œ7Â_Fjœi#_ûƒO\1…£¶Sžõ1¨Uƒ˜@äHî=f‘è.µ¡ô›ØnæooCP¢|ÌQÕb:Rž[`»„x tDã6y|§5gæÕ`g1yî7ü}ôæ4ÛßpªN{:alÿèLîç–G’ØoÛ#¿S9ÓÊ⢰(™Ñ?¾…þ‘ÄðPýOï#?£ùIÈ—À7=ù‡RP‡ý @€_{öKÈ~æùÇ6>F÷*ñgµ¿óþ¥¨ÏÚÑ %¯þ’"Éžþ¢ÍÂÉÍüzµØÏ¢ðÏB3ï”ÿ½{£œ°üSñû úƒE ¸'¢Ö-*WÑjaMÍi¨ûæ…^žä—9|Oò3âˆ_XJ@è#`òŽÏhžôŒú]Ÿ‚Ð>úî:?>«ùûX ˜¯?ψ(ú3æü{ à„ѽS Â(àkþïuñ·ùßúFñ°=ㅳΣ?© „9‚þòòe Swk¾ÿqsý2°§âÀšÞœ¬:8'\ÏÃþ?ãsÊÂôÝ,ÜÏ<»&è·Å-=ðcôÀ¢¼«—ù 0ÚòÜsç1ègú£)4 exȆ{¾užm0ƒøÉÙœ)µ˜ïÀÉùçØŽ3ß7 ÅoÜs^ÀÃØ ¦€7®=Sö8'î¿~'ñ„=tܰ2$‰zÈ÷äkAä!Íîˆ<ÈG¨«O+\q¢XþJ>PTȹs¸eàM©)¨C»ÐbLîââ·Í3´6‡Õmnhôwݬg-pkÝ–Y¥ÚÛÐBßãl?N4ËÊMbªÜbÔ#0з;>hu_'ž°ƒ@*:øŽYc’}ŸbÂG8´ Pç}šõÎ>þ!h¸™ÓŸÂ(k…Kèh¾—žaßÝóìÓ¯2Ä}á>ÿ!àüÏžo×(쟿ø,Bßé×ùų™ÉŸ5.2„öÔ&„¿m›ÜÜ?Eþr<½ WáÿæÍ׫û?ÿ#p½öÌ«Õõ›?ªø.ó©p¡ïŽëM.¯ùµÂ_¬ž>ûM ŠÙÅÅÓÕoûŸí[ûøéS¿ÅPJà/§—–šþR{`QÞóäøÙ†¹q¸Ž£ª­€†žhýX€.àƒýEAÐJpO>Gt 8Do½&^CjFÞœð/Þ’ˆ¸æÊ@Òµ˜ä­Š,|‚™›0Š5 nf²î ÀT³GÜFNÕ¸›˜3׸µž£·ÀêÜÑö_úfŠ€¨þ}š]Ö#кOõ7=oA`F³«!,ÿx&ÛCÞþÚÒŸyg”fÞ¡!^WVÀ»ÅuįÒWÐÇ^ &÷V´uÊoþX›˜àQXòE>Ó¸x÷jÁï®kU0Ýgß¾&|õaâwÕ¿ÐsüvÕ½&ÀsL—†ë¬ë ÆoÃò©K»iôß¿`8ý«¬YØûúõ—«W¯þÊ:ÿ¡\¾ùCà‹m솳XDxxîø’çëË‚.¢¼Hœð„ÃŤ÷âůÓ÷Ç(î:˱¯·ôÀÑ‹ðŽ^VøçF'³k†wì™QÛúpÍlŸæ~„*¿ö\Š0^9Ó„a*p»—k…M/±Rb8 B]Á­Rq+_&¯ìÁè†V»ýÂw¹© ¼wNã]x l]ÓmX±³„FúÐÁ”ñÞ”ÅÇQå¿ãâºâÞ#K÷ï:;]' €O%1ÐÑxÈS‡pÊõyФäÌm wù ¢"W–+E1¦`Þ—¼c@³Â½Gý¼Ž`ˆ‚ 0¦Àz×T ?‹Uf €< jé Ë\_B]3³#Î,öc”ï^ã2¿a_Sõ‰_â¥Á4” ë«ÆYp¯3F ‰ …¾u×bwËÿdî¿áKžþ¾î7Wünïx7¼œËãw ô}Qð7­qÏÙA–ÿæ¥1¯N‹ýz}ýš¾Õ’rJ9'Q°bMÏÜ~¯>N¶Å,÷¥¾{, Àûú¾&3ÕßcNuÎôœOžÞ¹ÕÉ‘àfu 3Þ8Êó‚Ÿ=À(û‡kÖ¼²ÉÂRÌ1¿Fl\+ >Ó\œ, Tn¨(/„J ]J…“GNQ%}üÃäÜ”8ò%«~˜vÓšâ ;w×X//ñ;<ƒ[²"–7óù#U¥ºÊ!7ªÛ9òùá© béºücš¤•=£ˆ™§æm똑}€)gÂÍ\«9<»”_ <½|ïODU@WŠ`Áct™*‘è!Ö9’±òònd´î;BŒ‚;&t õÈ6?„q¶ùE8âw} xFñ¼ƒNAUœ&†aâÝr_~›üò®Ú*dÌëªþÐP`¤zîÙþcÑÂßo¨H£ü•u@AT×(›ú~ŒÂÃG¾TÂww׫—/í_3ZçØï«Wø_’vÅó»¡_7« ÖHø›òñ~ÌŸ„xîxuüß’Ê‹¡ÒÆfbvaMx¸EøoV_þõM¸B2b×gYôŒ=uÐP•égÄNºö䬶ÑEÀ—E|æU ÐŒïš`þÒ5ç¯Å@:çÌ+ #ðU^uŸ?ÐzÿÉóOFºÎòç[Ó"?p.Øç¿kòï9ÿÑFêõ18o ÿ««7ww7˜ú¿XýÓ?ý·ÀÍšã½Uøþ@ 9î˜xñÙ‹@ûß!?¿Ú@ÏßØð»½¾öƒ`Äòâß²^è«WĪÀº!â^¾ÇðÃ"ãdð뇩NéJ“cpaâsN Ö¶Qœ Iá¶F90ŸNÙy$]`)(&¤~B Œ ÆÇ;$R‚Ã/zK· [1H óZ™&·Í2s&§ÏŒ#`x’§ø»ä@oMz$˜WyÒÕWzÅ™6hJ×+nòt\ÖA W‰«¢¬íòìè0òÑáI7n²*RØV õÊüC=MA/Ô•™Þç †´U ÐøYDǨ.Ò}ùø£˜ñ.)Ì‘ AÃ5ÂR´¨” …º0#xGüîÛV'ýe•¿aò:êÌI=â¯sꬕ§ø5ço¬sêVMü¨î­87¯p}ýfõÕWÈåoGµúô­,4Ó–}¨à‚•ýö‹Vƒ‹zUT°ýó,…k”‹C{yÍlJg…ÜpJè_¿ò£b®8Y=yò)þ“Õ-ßqä¯BrsóÛ(ý;îâ–ø¡z`QÞÛ“ÍúŽÀ`€ŽŽNA=`ºžŒ ó@Fþw †.s]ÀƒÖæïÉï¶ÀÍ1BÛéBè=¬yX ` ä#FüJ˜ý³ ˆ|žDèïÞ3°•zkepmAú5_P‚î¸Jè–Lh;8)21ûx{ho;ÃÛ)³—N“'§·uDa÷ yJÖü©°ó)<WØAý¦tû Sø•'‚‹,VqšÛË \ŸD+q?<ÚSÀë8 Â8Ȭj°ñ=™°j”Ÿà)”[8[•€°*ueÎ> €õP¹¬5v€£~…¹°”èE@׈¿…|Ê@ ń L¸N9´BP~-¥h$/w¼X¶W, ¶‘«úmt×GÒjÌþNk‘ßAÇǾ\äW ýøš'q›Í Öžìƒgò,òfð÷}É;Ã{Ä;p´.Q[h¡Øçý—öT¸ ¶¹–¾·Üt˜Öý„÷ïj„~;ú6‡'x^¯^¿úsà-Gxß\IŸ¬åóÉnžë ùê%Éãµ{Ì÷š/ƒú¬üuf H¿#ã }%|FX\T´Öœrz¼^Ý®¡yÃA~GYÏq¯âa_ßðÌïV_¿ü‚×y/|vò¡ÏÜgæ§™çJÀÜÿ‹DKþæ=°(èb†Î¯Ûwž?ÃL‡ÉO¡s€¯^ýC¾.ÜŸnT`W7,úxœ@IDAT*ÄmœÝò)a`Ö}í袔áÉI‡e"ŒJD€É„î˜GŒu`0˜;楥܎ìÁd/LD„9†D@³BNÔ; þbd…1X¾¢RÞW¸üuŸÑ3B"3GÕ’udIÔäÐæÖ°²´€ØVÝ„AÓzª0t}»N/9ƒ²Z/̨É]0qÆ`=Ò“‰›‚%.°*D_'q„T@Tˆ#“4¤ÛYÔ…¤›K@3»P|…|FìÉ‹@¼ŸÞ¶àѼ2÷áËàŽ v邸æG\¾4TΟ廿ÿÝïÒŸ*ó·L5üæë×kðÖL ¼ºü÷ÕÕëÍê’/O™~øßœ8WèÂR”~e@°+Ü#PÃÁýÃ÷Œü•ëŽ>Qf§ÂvÂðd?²&%¤Ì|°)¢§ÁÝhñü ¹š9sÇÿ€…!wá R…¦Ñƒ.~˯¸FŸ Ó¬jò^v˜$‹Á´*Ó$æóOAÛgéã7o„!ýn¡¦{”­Ðp(© вíCL žG, a0Ňދü„)œh•›t…tø‡ÀO!­·Ì¼O ç„K!¨ƒ|†€‡¶+ô½G!`”èÇeH ãÏsP•”-@i*àÛ ¢¢òqÂ*¡Â‘¨F©HžÊkkÓ´!ý“¶}<7?þ.¯oÞpX«û¯˜o‰Bÿç@ææè›C¨qò!}ã Ÿç^¡ýÃ/þâJ©¨Þ™½¿D<øBêxÞZT.°ØøúT[躃+¯^×® ²ghu‰‚!<::Gy»æúeòA2µÍ†ƒ…žb}ðÙÖ8ÜÅ-=ðÍ{`Q¾a_Éï›i?ŒƒdþšUeÒ2{F ® x`ë˜[Å?r/P˜©b„ÕÃ2[`„=¾ãCG%bv~ÌCx¨$  Q ÀQÊ3 ³$â0¿+ø=Z˜x×(ë]o`›Ä‡PQ6¯a]jf•p¤Ú0 —JTžB‰°×},F@SëƒÙÛMiDH9y& Åe¥mcæ.¢#ˆôß*V[ /‹òmNâ‹i#ÝÒNçëë›õC\~Ò¥C&üÂ(BÐéY"óý}ëåYs¹ ÏH‹LY!e[ÂXB_¯@k—ù#|KÀ»Þ#ÂY|N›í…*¡'þð+Ä{…¿øæÍü¾Ú–Uá6ñ0¦~išß9ìÚYQ*í€~»z?:ôˆe…«Ez î;GýLÜpeÎÿÖ/û±Hïþ†ïZúëÈm‘ô•σgßÊZ^‚þMù;è߀sRs×Á¼˜ªßÕlÙÿÃóñÝq*¿<““êEW Oõ7Kk¶ßÜ\SÏ&¨÷Ëõ >ãv™z÷cznݶþð=°(߸Oë,ÓÔ¹¸Ïõšlïa&Å VW˜WïïÙìÇ\å?&T #þ{˜~AÖÖì»Æ‡ ÞÀdœ.ذ@f¥—ÑL&ÿ," ¥ ÒeüS:?ü …H%afÅ<ªÎ2†¡LÀVÊElMÞœ¬$Yâj‘ÛH&>‚+éàÙ.ÊG! ºMB%Ez°+ÚK€.L ÐìtÃÌm…OH™6U©h˜¡óLŒnШÏù9Ûz4LØ)ŸÂzt\BÌ)‰å¢(Ÿï EoAÈ‘^EHÃÊ‚“>&yaåGˆFA(Ÿæv¡eÄl/añ§lûç;¤i7ï’qÔ¥Ž¢FA ¿ÓQ.Üö]ôó¿%È,õ?a xϨ~[²>©Qcå1ê‡p²)£ó7á(ûÍ›:»ßsü¯._1âÿK V¼ûVúóø˜óçÍÈ–^z•¼Ii³ƒÒGõû1ÞmÂÒoïÍqDö â´ ŠEÜœç:=kŽb~úœ©EÏ`úß×Õ5VB Åºhð‹Å=ŒÛL%2=Á¶MÛk‘3ž·JJ;é/néwõÀ¢¼«g‰÷Ç®Ð?f%ÿ ŸPUÈö鯲°Çùÿ+Nõºã*C•ÁhbTÐô€BÞ£Z£ ¼7,:<`Q!°âØtŒBÐn`Ã÷ZÀk¸“8⇙ïÜa§Ë,«?Àô‚ ª©„¢4ÚèÂð,Ñg6?L‹ú Ë!Ä‚ÝaM æ¦N:½Ô-o„”ùaBÅ75Á½„!CrÒÌ^®iw¸aÑpÄ_qZTP üe3²ŠJR *¦hFÄUÂÞ&V(ùôƒ´,£PòUÄ-n„“”èþqìð0‚°ÊYxë5OíohÑï%Œ¦S—”¡ð–A+\ÁOœ£ì­I^zÍ ¡œ,i?äˆåy‹gþÄÙÖxl‡ô|¾¶Ô0åE1~òžD«THƒþ¿Š2ïÁU.}·Î3‚«:ÛwY,­EÁ_”§€ß9~a)Z´8ÍP¦f× ( ¢—C~€©+ñI¦RÞG;ÓÆèæïE³¿ÂÿåË¿ T1ý_¿Z½yè¶»£Õž×sÖQ8ïoŸØ+»+¤SñI¬[÷Ižêo¡°¼ûÞT¿?.o“ïM4Zž%4²ÈsF„*—l|}ùšg‚ÒˆÝgÍ‚‡ 0ÀïøÍ›7¡¦ÅÀg\ƒò§ å¶ôÀ{z`QÞÓ9o'ågK´¯ÌvŒùÖ:s¾ŽòÃ'Ðô2¡G~àæ‚7çÀ±ò£GƒßÀ\lv ùŸƒø“AŒPpp#ál1c=€°Ò•ÏâŠÃŒ!uÐ̸£(Ñ 6„µ€»0, ÚZ1R1ÆyOÚh% ˜Õ¸+êÊ¢­š3¹YtW~Sh_îøh äbv¡BÕ2‡?dªTº´òoïâçÊÿ   ôYÁã@ÁP8šÏòð3 LÍæ¾ò£>ä& mo\UÂr¤¥ C–•8…°Ô^©ö9o;£@ß÷Ã:F°_kª|•r”q­O¶ÚfÃQ¢Ò.€¦W DáSGóüIàV¶÷0õ³Æ¶eôŸíùèœB_ë”æ¾ÌÉ|¹gñßÝr¦?—ó‰µÍ¿ƒœÝÁo®§`²Ä… y»kÝÍô !-/¤7¢G¨~ ¨ÅãúÎS&TÏ"wn/ÿ ân"r±°¬ä‹àí­S.>I›œPák៖ÛÒß àtÒc(þ8e¦ ý{ÎW :wçÌ‘†L×n4óMìïY°ç8#Б¾‚ž½ýÃ=rnŸÂ´ôâ B"áqyDj<îôP‡á 3RŽë@€ªq¤Œ5Ðó*rKl•·!qh³ã qˆÒA† 0œ 0Ll˜Ì g F%´ÿÄ8¤O‚™°Þö˜®Û†Mr€Õyõd %€{Äß׃tÄ+Á§À®Ñ´tÔ-°Ctà¾EƒÓù».´Ç¼^Òœ”‹á÷H׎“‘g`ÚkoP¾kT‡À®;}‚ ö™Vý§lÖd„?p²…O\òkýÈ6C™ýþnñóy»¸6’œ—­^ô©oüî¸íë¹]“¾EòhWï$(CùPq¿¾rÚ5€Ôù5£û¯¾~x{ûÀyì ¸<:ÂgÖ€Cn ¶}^*9º ¨¨ôõ ·ôÀc=°(õÊ{â åXÀ…°òô‡¯<åxó>‡Á¼\]±Ë-‚192§/THל}A˜*·lí&ñ潜€ •!ø£®½¥"D"`ùaóWôfç0áz‚ú"œ*JÆm`‰{…µJF+NˆinÖiÍ\i1m\Ò,^<ËWŒrà3á5Âu¬gX¡Õ£Ó0?âü®iͤvxUèäF•kݺülS ËTŠ\9Æzˈ¸-c›¡9,©¸ø>ßàKQíª°)l5à¼Ã…ªhFð_B˜9ýYùÖ'ù­í÷ Ÿoûas†ÐšGe¦ª:~-ê²NG8% >4êà ñ¥ç”€‹Ë" ÐW)-áO[ˆwQäöö™ôû\múXîþž4óÿéOÿ’}þÎùkîÿò/ÿøÀ6¿sŽñýûßÿ*P³»Šé±SfõQ[ô¬çQè‰óqIF줙^‡ôà7ýãÙÿé kŸç¶4Óó…AéÓZ„–)½X$€Õ^"êgû>rçïA œ€ËË—Œú/ùÐÏKÂ/Q ^ñ´8”‹¯ô=}rÆJz>˜DŸù^ݱhV˜wÞ—>]UïÛôTdMz_wÚ׎¿ß »_5^S~ÔyêëBÅëë+®k·œ pµúòK¬/=P\ùÊs k†u.×p’ÎÑ8ù¯®òS‚;‹ös¬!-°Ó•^#øT ï“uO]Tv¨¯ù {•‚£°§ýQ LÛ–YñÖµÚ7*ÿÑ‚,v¥uZÁ´¼iê×  ß~;'.t®#içý/ßhV¿"î ¿G]úõ¾šó÷9øNçc<À|g£¯ýènÝÜÿHRð ;˜¼/Sé B¾Ã ýË+¿Eà"?ý׫/¿¾ TxýÚ¾òZå,K^0~Q©“Ïy[³Å·ôÀ·íEø¶=6ס:BTp=À”•_ÏŸ;§ø,?jiúcWP¯aPØ0)çþM+atL•^J‚Œ¡žE?ôŠdÊr¤¾æÓ¢±Ë¼Fœ0•ÑÚm$¶8êù×—xÏZ†¦Ïû6† U傺J>”¢Âì´bȣ§XöPV¨,ÍŠë$¦ˆ ¦þÄI²FºXH¶uëJ¨&màN£cK ®1Ìþ€‚Äé   ¸HŒù£žý5>ë‘üÙ–Ì©FĨù‚H~°m§£ñÀ¢™ƒ|¤Nœ£ù|ØE%CáM‡ä$@…†•'Îm¥Âж>½†À2Ì£Åa–^sü[!1)8³:ïG|5…¿yó5msü¯ù”ï¿þë¼çk~çðóÛ_=~B?Ö»x†à¼q»­ï¸¯W^pß—¼ª>ö™Û 쥿±ïËÕ{PÏ®ãòÒ¨m~׫þ×cŠâMæüß\Þ­þÏ¿¿^ ïØöç¿¿~ÉÙ·î*Òzv¶:~ŽÍ{P|`vH˜uÏg*iñ,=ðÁX€vÑûŠ‘Á,C?Á CV«fîPÐ;ÉÝ_ €éì|ýÆž‘9L(sòGµÈ¯kñÀ6@]˜ÜêpÝød0Oæû'l#Ä®hÇÜ®p!N¿q £80ón6T 3¡ºÇÙEls„ž–Ó>Š­ÀL!¡=Š !Ã2¹‰Ìþe¡‘É?„crH ‰Å$‚ôfšÖÑs„qÒQ‹Nõiz#ΓÿL«`aW»*VZ~p`D4#rFØü¥ iÇ̾eòÖU'eq|‚;•Oÿ˜jù _#võ¨OØ£üZÃ`=Hçýq Cšäw×I)%XZÀ7¾Ï#ø]è˜÷ãw¼¿*Ä(.¦»aÝcs/ßhø+︧u>Áð)óþì÷"g×`ð!Žw*ïøè®ß…oØy¾ võx%®g¹OÂß—Êý›ËKN#|“¿‚ÿ˯.£¸Ào5ïöÖ/ªµóîðlüsšú·ôÀwíEø®=÷V¾Á´aæ%eHÎמDÈ£ó“ÃE<1¿çûûãõTAÏõVè÷™ÿ ~DïK.a_>d’_¿ôa5Ø^´Wq2 Zᄱ‰ç? 0þL¶L…E)”I}ù6H£ †ëT\Šfù¥]Ì­õQYc O˜ËíÒô:ê²Ý\þSÂ0è)•c@â”{*‘·Òæ?ÊJŠ— õOEB@ššÓ…ù'ý] Jáp§>©ˆY¬ë˜?/Ú àa‚— u§ÿGz¸øV% ðL -ÚËsj/•=TŠ‚Z1Þ•š»·ìbòÁ'Ïë ógÝ2E }é™/•Z°Ï ÿq:ß]ÂßEtÎó×Uçû»Úßõþöü=9Åã: «ü®Æo-D~ˆ[=„¢„? Å kyN© ïPTn°ï_3¿Ÿ9çý¯Yp»áÐ…¿S¾ï<Ï|àÂçZ™¾ú=høC4a¡ñ§àzÖŃKù÷ÇŠìÂ"ÀRc\M8²ÖlWÓ2-]›ü+\ëœdãö‡±‡v1xÛ£„bpð ‹…f`iˆ#Ë™+d„¥»fÄšúâO9Œ”º<áÆ)Óü Öh(|ŽhÂIè ›x‹ !•"’¦9i¥6yüË.€¤V¥2;ꦅA|")?W¨ƒFÊ´ÄQ€r«üC@V†,Jb@Î{ÕG OÐXt¸‡À%®öñ|« òp–W+ð3¿õSÁŸr`ÜbÖúP«ö+\ @M„–ôb¨üŠAØé>ÏîÿX¬ ù&7÷O‘‡G᯹_Ø+þß¼þAú†‘³'ý}…î€?V9>½ód|Ê7¯ß肼JýúþŽpfÛ¸šD·Ö|Þ9O<ÏEŸÎß‹Äú÷]sþõ¹ï[¦_½z³zùê†Õþ¬þ¿ñË„L¹Ýb!dÁ_­ äÙ2€ðyÇZ/q IžRÐCÈTfjaècJA*²Ü–xG, À;:æ›FˈË9Úäó«lt¿®Léää.¬@&¡Ï/û†õ~*X¦àâ£;ÎûîEw2á ›y8G/©ð¶,Ë4®™K…Q(¢”bF”,•Ïû$$FþLü]–4`댳 µU±”Š”—õ eÖPˈ´ëÕ¬ÏﺔM_ÁÊÂ$í6…ç¡#d{©"ô "Æò§ð¬Øìþ.<ò;"'oÂÉÚ¾¢<ˆ†’ ì&ìªCîb­yÁBèƒv*åÑÞäJ™Äª ˜Ãÿ´¡ÚW8µÊ<Ñ#Í)º¸2ì#E ßwHŠ!)TaÖ5íR0.Ê´’ßJךŠò}ÜwßÅšó÷ã>µÚßûüÿë¿å?æüO8XëÓONV¿ùì7±<)4=/¿¬:cþœe¹eTª7v¶F6˜o]ÔãÍ3q `9²Ä gÖ<Ölhâù¥Eâf}èڟחWÌùÿ1ð†E~oÞ¬WÿüÏG ô~æ÷úšuþÀíŸq¦HYŠØ2ÊŸ}öyà)þyöì‡]Laãæ A¿3UÙå¾ôÀÛ=°(o÷É÷ˆ)ÞÂSB.Ü‘!D€¹»Ð/艣 —´À?>†mÜÞDDØ"ÌI%o tùŒÂBTA(mä|:@¦'s*QíK&²”¹X¢¤`ªLùÐ'uMr)~ý.ÙÇ赪CVÙ'‚0ÌTáWBžHëfûF}Í‘¨©ö°E‡oºàŒü¦‹¨›UÀ¬»(Ž–¾Õ‡1Ђ°µ’PÞLÀSÏ Žu„~ç­9öª› A]uHšuKu¬Ÿ?1Ãæç#úÄI_úV^|š/Úã_i©pGýAȉˆíæþŽû(!O•ßR WËß0âÍÊù/V¯^þwöŽëœ®>{ÎÇ}¢nós:Hès°ÇÒkõ‚Œ"`¸nÁ(‹T÷/0G8Öãò%É÷Á¿zçx³Tô¹üÝÜbòýú5û0çíljî±Ü²<ø¿¦}¯Tk”oÝ{䯠÷R¡éÑ¿é‹`<Æ|ãX€oÜUF,ÞÛÌŸ°¬€¦ŒªYŽ#<¥ƒqðúœ€cö–0Ï ~rR~x²êRJ€ÊáÁ¸T4¶ L¼§ÌÅ¢$å*p¶á Ï&ðÆÙe,ÖÜ©x%Ô ÎóµÚYLM!ÐàÈ¡eœB.iÕ™$ú›æ_š_b˜ØS–M2©š&l7ÏëÜ €}b„°­Ö'8–å4N h ¶üüøLW`oýÍo¼ù åßtò'PøÛƒ[ïGÕI à§Bfé†zPª~†ÅùìJ‰v ‡áÜb=ÃÒôøký P]AÉsŒ€ÏñCý6~Nô1¾ñ>ù³úÞÇÓú}‹ö¢[7­y7ŒüÝ©£ðwkŸ'}^_iò÷rÛ¢ë HQ¾O¾ú=ª×ß‚ß6µ¿¡x¾K‹[zà›öÀ¢|ÓžúÆx³ Â)ÛÞ±âÁI#×Ô^e¿@æüfQ#~Fû¤*Ä ;«G5B|ºWUÂMR'–ÅQЦW†þïž8•ú›,òó7ì6>öõ¿ôÓÃÔ‘ ¯ßÜð%B!xlñ»¾VIÐ:h^iqÒ##{w¢ø^XwMüÕ†šp éñL3ÜÓçX:Ú°}G­ÿâ–x¼àñ~ùޱ G€å²zûàÉ$ÐÌ.ê)AÍè&uÂé_½@sþ£¡ .Ûô\‰yEšL¢F–°Ï®"Êè5Ù²±fgÆ8ZݦHeâf¤âgR3P/u¸gu×J“ˬKåS¯)7JÍ—ŠÿYA5¼âiˆKœbnJ0Ã:ЙêÔ@ó‘Ól0ÍyëØNŸÕÛÆ€ß+ºªÔ¢NÕ¡Ê3²h×@„ƈÛ5É—2 d©Œþ­:I§„A3í±†¶ÁüöǶ=48e‹ñvº4êªt0ª ~ô0ÓQ´²ý]®¾ü+sê|âwí—ý6¯WÏž¬VOüD7‚ÙOuòüE ÏÍß•–‚L›ùûâ/êhuúnZ„ÊKãtšûõ»ÌL_E‰«÷„'ÁèÜ)0FþлåèﯾæØa`Ìýo.WÿëŸÿÏ‚DGüDø—/üÖßëEÀ†ùL}×NVOŸ~2þIýçŸ×œ¿J€‚¿Ã*®øÇüÇ@Ó½ž>}ØïEÃþÅXøz`Q¾S·½/Ó–›ÔžÇŽÖœÿ½'ÿaf„ψAy•/êÁŒ<²WÒ+ÿ_GžÄ§H#-ä·e8ߨNškÎ ¶Û¦aá|âIkàœ½¬ ìï:»¤¦2@}à\Âβ­‰8„QP¯e%*~nœƒ0OJéaöQ—Æ9”€Tø¯9v½æáÞW\¦V„ Ùžrî„.1P¬Sh¦¾жLu*côϳÚþä·S¦‘D·¸ÆÕUµjÿÈô­¿žÓüyI®[Tþ£Þ}7] zÃèÚUÿëõ5}ËÂ??.ÅÙ êáž²¨ÙÜÃ’|.n©óx`•ÒV`óítâ¶ÿ}pNõà»srâïÿy®¹S&q*êÙÚçz÷*ø¿üêkFý¯‰§®7GÌùŸ:ϯs p½?>çšçW¸kÎwDß#|ÃÆzµÀ8ßSGÿ^»ïXŠYnK<Ú‹ðh·üp‘Åijp¼à‚ó«ùO¦â¨Å¿˜e(*Y°‹‡9 ”ŒáSͬ€!Ç-|ż!ßÅŒ@•g Ì "¥,ÀÀ‚¡A7òKDFe]ø‹EF* a@jÖeITE|x›öˆž€*)òÓ"GÉÝÒ¤†å»¾%`ðŸ?GÔ†«£R+0jY]3!´'$ Žà†£˜xSØÝ£€ô>ü”Èó L&,>× ¥¡è鑞õ1‰j…À2ÉÓù ÆîÛþ‘¼€©| ]\ç:^¨å×29}Ò÷Úo¹SàðÀËQº]©À2üööÊÛÑ/p?»Yïû|Æóƒ ³°åG‰÷{ÌçS‡[ÿÍø˜Ïõõ ÊIÍ÷ߺ¿Ÿc}ýªß:‡w-ÿÒÔäïzà ûÑ;ê÷2¬ÐW)h ãÅ7Ÿ×"ü§×cñ|ƒX€oÐIߥø†L¾)lçŒKð:Þ–ùh!'•=½ )ßûŒ\ÄS棯ö½àÀpΞ¿ÉͼÅhLéø¶•#öÿgïͶ+9ŽtÍHäÄA›¥SuÕWýþ/ѽz­^«/NWÒD‘"™Æý}¿¹Å€I*)‘™))ˆm>š››™›A`ŠÐBݨëœ`(ìòݰµ*ŠÉHÅQÏ*5âÎG¨¤ƒˆ„„ùõó<ÿRáüU€4ÜjHžGºß—FÊMXá䦇*“‚¡Ò« 2®[ÒGXÃ\ç#~w=¤$Æ3ܸFéÑÀ’]•Ëp*½7ýlüyxñ\évø)jyüËÿV¿O¥jQRés$ÍìÙbÉ:€Û­|8gKÅ€ÑòÖ)xWñÒäï ƒfA®_kÄ#-’VQ_Ë*rÞm!T탺¬ð‡ {'Š–+NtJï ųü_ÖYþžDxt¬€™ÿÜ/ƒ’ó•´¤°öì lw”É]BBº^Ø#|MúŽô[è?bWƒ÷*=òo ê¸¢­úÃÏ ü>(?€œ¿ÿUiöN>ýIÿÜð‹ˆ%™ØúæO3ÉóT×µ Éàr½0«@…qÁÖÊ/¯M¥¦|­›ˆ[5ô} $¤ÏýPÐì«|VV³ñòÞcyê½Ñ­ó”Œá;Éd ;žýâÜyPÏäfõ|G¦`÷⯠S©Lñr£°•¹û0/·•–B?·ùñç;M,ãqгòànzI:eϸ‹ïÕû)Ѻyíï<îkü‹z†¢×LQ]ßl3ï^Ûê¾üòmu/¡ÓK„ëk¾ ôÞ}üt¿>ÄÜýÊÝþþ£@-5Z“üB PªØ ý-æåK emßþg¬'xöü[¾Ø·Œéÿˆ-}ÿý;¶!Ëä³xñJ`7 J-îsß~-òSpïíñ)b —‚ÿ“O>™…ÿoûÛÌë+ô}ÿÑG:ÚW p€°éD%àƒû€7ÅÀàM1õ7†ëŽYÑKëŸVªgÄï¦ ³˜[I²!N‚sÜ”2Õy‡'NF¨(‰Ž°‹ßåYů7ýÌàèŽË'‰õþ×SA*Ø~ȵN¿Þv9ˆ<âÏYu˜‚Þ]9)ñ†1'êŸêÏDnüú0a;ïòç7qGn0Nñß0ö¤WñŸ¦|Â?ËÆfï3]3úV¥oñ¦Àñº‹Ÿõ¾ TŒu¥ ×}£]ÍëGž¬wäi{UÜ-YwÜD²{.r4 ƒYºAqØÛ}€+€­"IÛ’¢EýÁb—¯GÖýȼ€ërøŽÇÙårqzvÊHŸ=þ§Xøšß!ù_\¸Åo}±\ú10? ®õO!_Gü.úS¨+À[x@!ßV¶´É_ÅÀûîþ |Pþ¬ý]qV¡„g”ëçŠ@ÊèàK0 a ƒã«ð¾ŸÆyÎzßáW€Ê·ý_?%0¯N’›Üç§„ùŒ¬²ùLù— VÀw|C(°+äøíòw ñvʲl¯ý8L±Ó##°Îpþ)?ÌÁÄ0FqSx zGr¦p‹ÇH)áj @ˆ? ±z_#Ã4ÎHƒNwnÞl亲î©÷,}?¸åµÆüÿ_ÖÓ .—LÄãê¬ý5vpn/Ü®«iŸMx¥Ô\)ƒŽ¡_ÓÑ䯡à?Ãôïÿ³%!º`ïö÷;-à"Bû‹4RW>ýœ¼jοMû­ôs ü†* ¾3œ÷5mí†wX£M×JáªöÅgVÏ?ï]Ð~Þ\~¾Ô?(?n¿“rõUĉü §,´#ωx}u-#e9X éO‡)M㤓]#=ƒ¬¹Ài8Ó‘@;=ó½;Çlþº#Ý}î²¶oNìàý÷ßñë:ʼ®í7Á”—§YýRöyý朠s¨ .da®Pà7ÓkÛ‡É#æß.Oá M¯¹ÿÜ{‚na XçÔwbrç-ÎÖgÄÏâ@äuúÁûð—ì¿ßâ+˜Û[~<ˆ½÷C npL4Ÿ `D ]8 ­mm-Ÿ/e]\xÊ—ü^½Âpꪎú=ñ+„*!Ì÷³¿ÿšé=û·S jžZvvv#Àµ+Ð{~_¡®°üøñ4Úï£~çsýsáÿ¯nî——\ç[Ý'Uκ¥h¤ŸÁuN&-o­ó%VLtÎ~†ìò$?(?9J(AΜXUk¾+²*=W^—V3½×½ÓoN¢2½»áW€Ž?+Ob¯FðÕ—ˆ?’¨ò•% cÏ¡Á̽sìû»%šÇðþþÛŽ}?ÜwŸïçw¿¼¯‹Qõ_å¡ÒpÇ}çñ¾Ç½ç;‘?<¼- ¨œÕåÊw/çÕ=ð‡}ô˜üoo.ÀW‹“åQ «[]òõ7‡*¾›¬ïxðó;Ðgv .ïtÏ¿_ºÜwŽ(cw¥ÿ9EVüó?ßûÅ//±28qx¸ô[ Zåo"ð·{´ï>þüeöWà÷¾~»‚þ³Ï>›¶úùþ—¿üe‚6ùnnòÿWU"üißÓÓ㴯Ϲ @áëÜŠfVo_²Þ‡ßq;O®jKNáìî> lÁ?o›U.ïïÝà-·MJe«0‘K¨H Þô¾˜\Ýõo…í§ï»$ýc€Jënü.Û*ŸûïWoÞ»ÆÏ]ü¿%þPŠ¿¶óݶV¹^[ÓÀ¨‰^G{J ;ÌåšÅŒß¹ü4ðÂ{ˆ¼Çà>~¦€®PØ*ì…Ò÷KN,à†ø\2çXS X<ØG¥¾vülñ±§•ð. €óü¦©€Wè µxï¿Ðçù{ëc’Á¿¼sA²JÞJY g~‡’¯ö%ò '}_x_äÝêgБé8ݺ °i¦­ö±ÿH<æƒ@Óý}.Ô1%qWût$âû Mr,ò«šøï“àÊ„o˜¹Å qîfW]‰:.Ô!ÞŸ'¬w ðÚŸ¿÷ýk}o<ï¶ÅºÐ»Eýþï¾~ëO=©Œ¥Ÿ9}Õýwëø¦ÅlZlú1ž£ëŽ_óãM_ú¾kf×ÂÕ¹qGdµ—^¨€wŠ‹C€î·ÎÅS^OÝk3±¸Ó*à¢?Ãúå¿­=P«€aO7/ÛtIëéKLýB¿ÞwvæAD®à.?á›éº¶HÔÖ>¿º*cÍã+Ø[ð¾€^Ø ‚J€qú^ï¾Sˆõs·ÍGÓ•Ìüý›Ðs¡{‰à¿ä³ÏÂ>¬©×@Mù Úm¶­uý<³wÖ‹{ü PS)ÇkøÂííÏ×ùêcv‘¨VŸî¥Þµúv;ŽÌ¦°ýü¶áà¯`ü>3½Ï€‹@Š<*¬¡Ï 5ÔÚ'œgý`ü¦2îUõÆ©kõyÞЪ£šQF£¬–”°—€%æ":Wû­"B‰-ß›óèp*#Á{ Cûþ3Áj‹ªQðë(°‘O;Ô—Fcl…ïÅ•¸,æk*o»+lÚI{·Í\4(³¬¯ÌeÔ“wš¡Ïò~UÇUÙ+U]ó<=Q¸×]'=ÕI–Ž~WôäÉz…ßßex/ ü ?+ÆÚy¯Gx*0uÎË;zµXn3Vïý¾†£Å αÖ”€•¯þx­2€à??w!Ê’âòœ@+›lÛ5oÖCÏð_Ô|?kj'‚8+%„Éîí{nóãK„QNêd?çü-¯Â]èœ?ûÎK… Ê_‹ýºÞÖñ}w-ˆ«œÅÓä}ºêvÒp½Õ¥À6=—0/Z¯ƒœêÞH ÿó@ý®˜s99åH`úüÌêÇèÐ/îŠW‘{yvq€Æ.7ô£ï,8 Xh›l¢Ü]\†GÐæY0¾Q àÎ΃¡”ç·`š‡˜† Þ»lß Àhî׺˜kQDç7¾…íúÞ°Þ_BŒ†så©`Ïë| Ú}ú%„¼ÉT„Ç$"vè¿vÒ_…Õ§Ìžd'Aɤ768HdoŸ )ü÷÷Ÿª™Î…Hs.£y—Øuû©à]iw®[ÌÆEa2˜:+¡pÎÁ1£=ÂÄ8('2ô­-Ï•/†®Ÿ£ÌÆ—°p¿j£Ÿª¦#íyv}Ñ`ÑÞÅEчuðÝé‰çà×|÷‡àò9\¡ï)¨T˜rI£ÞHH.ÀS_„ÖV}¾:óס§'¡'W¯;wýðáÇMO»»en/|ý¼ø°Ì{§‚òéÓ§ž½ï¾yûßÉÉ Œ™Ñ!÷¾ Tè×»Ãñ¬BàÊýSðWJ÷¹´oËà+¯u¾*ÈN}ÜÕÿÕ×å žì·HèÐFíë/K„G[¾:’X“ÿîâÓO¨`y?ÿüó@-^Ož< ”®ª¿–¼‡?Òf»×ñËÛÛâ‡â4øCIküUÿ+~(½^Â/OŽ_Ú6×´ßñÉË@ùn ÿƒ@ã:sÎi‹BIZ+ÏÕ[.:r2Ë5K¿°Å¸Æ½á»o¿æZqSÚšúTHüÙ¡Åt“Ð)·ßæ 6ÛN…oŸsþG – ùñ£G+~, «ü½K%àƒ`Ëÿ€kb5HxlÈ!”¢½›l$ š=Â~£ü ØŠÃ5̺Ž£v AÀvü%#Œƒ"2žCxü4G†‚’¯Z§•%¸MV,{(ŠP‚ÛÞöT15PGuÆv¿ôj„çsùw<þ“¹n¿j;™7J\l„e1}qá¼°°p*neÀâšî Søüù5•9B§GøÒIÍ}ž³¢ý(_%àœi_}(ýÉÜêÜëÄ=„ª0.tËа õMh¦„;÷[»0TƳ@éIA¹³³Ÿ°ej¯‘u åJôçýí¼„2N©õñÞ¶q-T±U èKëÀ&æü ŒPz2ß’OóÞ°`Ï8Á7 5~ VßìZi(W}FÅ[WåRaô”>û`¯ò¯Ñ¾Â]f¿²ìDð;ç߇ùXfßÏ•ò·EkU§¿ïW|‡àR¢ªû•À×Ú"Þ…õΩGï*S*hì¨XêÉ7žJó‹_QZ< ”×Ê7/i¯âŸäÈÎ‹Ë ù}°¥ Ú>^ëcÀÃ-!´èáÔÙ²©CžŒãçÀ\™žï9F: @Yå\À}s»K·j'5ކV¤ÊÝáñˆ6BœkhÂiŸâÇn uŠ*iv_ÌÓÛÿù—Wlœ•“h}ªÆ‘)ø^¨ŸÄá¨>D’€„ õ4±CàaÐ8íJ$ja4XÒ¹fu2•Ño`(Ð1ÏæÅhF.$ÅK½²îdàs da¾o¥@„×|­Š„FкD(˜¶ [ÆN Í@ &«Ê/ÊÂêù‡ï4—Š¿*a…íîä“Îwí'ž¼Ÿ‡7\»×…÷Ý<|§5¼{›Gp‰E¥1&CÝ«½ª-«-V£Ž~îÄSõ/ýä*¦ÂŸ¼ÓsV_þÙï{Ex¡ôZ†Þå¡Ò¸ƒ¥›kéYzWÐüïå4—iÊ? æÞÁygC»ø^|¦ ôQÚÈiYaó¤¶à‘~°âÒíÊt7\£Nk”ÃÌBòyµ4CÞ*’âK—©&N¨äSÕëë[©³Y»^AóƒoºV<óÀÏÛn÷i@¢S@‡YÒŒm7HöÝ9U¡#Há € †ˆ!Ê+®{…MS>;; ô=Í ûPöžÆæOZ ó%ÿ)•qD"I¦rä@nõS> uE  'G¬Žîì4‡ä}Ñ9ÿézBɼ“Œ³évÍIe´Sß™¶±wD5u|?AVgW Ôœª…²¤ eŒ–Qf†·oRvFžâ·úéð Úò·G§;)IÆ®Åg1#;ä¸íYíXm+Ó°½‹yèG|Ú¨Ú¦ž=z¹ž-#¹-MÀ~£]†­×Z™eeÖšqÅQã©”ÅU­Šú¬ð/š¨ãEÞ3Fÿ„¦£ôäúJO*•77'ÖÁQÒõÛÜ€·0Òµ[¾†§²‚Ði&ÈöfÂU®h—÷>òÃìÆ(Gá‘ÉZm@Ë‘Çy”-_]&°_×+À•ëeÒâeoïA`ãD¡Ü¸1ËŸÊ™¦tjú:ïŵ#jý4÷+üuB¡xígÃè„ú÷;aÓ“8îûÐKÞþ ލv኎¼µÅqÃ;*"^7þ›Åƒ½‚®#ØâÛ›´Ïºø• Á§‚×BE/)Ú;ý±¾W±ˆX_iRž pû5xÅ78Ry¾RXG‰6xäyÕ?ééo~Τçk„ý5Ÿt¾…ެuYCØîÀÂ\Qôì±Ì{¤ÇˆÛ´)φß*‰Â!Ï«Ð` 2 gþBÏÀüC3Òih“Tt÷i³ÖÕ;™sè h²×Ü:(ô—ü2å ¿æ¹,Iwž£\ÒÖç¬ÈWTáÁN'ºUukËS*kA¨üV×íßå‹ç[øù—SzŽX‚»@X};>ǬŠIJ(ãL‡Ða^á—ÇŠ dvGHƒÀéW0& „æÈ`o¯ÌÌ2XOµÛác }º] 2j¸½)¦V„*1I~Ð> ;""2Â.ÀŸÎÎÀËÛ›ãÅÙéóäb$Üù%fZÃÃÎ5Kín=tt»³ópñô“ß:?%1:9W$È×9™¤ÂÿÛo~‡’‘ƒ1"á ½$ê L_B]p&8?? ¾ä‘*9ë JæÊÎy¯O¡"¶áæ8cÁ{y©Ö¤ðTÈu¿ÄB’©8ûãíÍ`Ñ»=[åXXÿÐå€_ß ãðV©¯'÷ã}êL;§_¤<òçZ3eùÖàß›(yB /X(š…‡à‹˜)OAÞ]\ò9èß-…V>ìôàU ýža^ÝGäµ.b}›J@sŠTè_é¼C¸vh÷ ×a>×"+;¼&ÖóÅ©‹ªböWÓDHàßšˆF/$5˜¦ W´Ð¡%*æƒnnvðb´ãCDrpç‚à¥ðÌhkLzÿp–Ê iNÄ.Áq©çt2:œŸ&-ó™S jã·œO^PÕ:#Ù½LRŽlQX§ž'U‰Ré*eª{e¥@ؾÚGk Èô3ʰ<àlwàÛŠ+ö£oÉ)é» Ïö½fQê U®ÐÜë~(=…mm?$:#àööþ×`¿¼ç||ÍÍ7n’áOü“ú €I+€dž-°UtB…¼æÿ† 7/Óçþ³~«6.zs$_/-o¾/h—Õܯ`{»¬»Ü?xp ¦lö¶pDr€'Ó3§œK.ZJÁßé´,?)E©úG³æ¤¦¥Àæý³%‹ôœº„ÎoÀã’þ*¤“CvX=ni­\òGêyŽ%Ô¹ã$»J€òDHöaW¯…§L‹`ͬÉ^׈9XWÅkgÐ1a'z—à‡‚<…è À}ýɽ¼’þÊŸ=F:ÞÞÑÚ§õÔ>GçCNFN×¶TâÍF|ICÒ_"OÀÇñ©Ê’SeX¢®]P;W¤É¶˜æÛnÿzÀFh"•PsÉœ£WãWËo-V×£I*&¯šsJ#C B)ff*¹i9üǼ[µðŽß­s=˜„„?T¤•"9"Фm| .QèB]1va=›L¦ÆóZFb$M»˜)¬ÓÙnbbÄÓNÈ¥ÂbÞÆwA¢&H…°f\GñktšÂS A™¢ÌH¨kè½e*W B¼9"ZÐu3¦ìv:ÄP§™ú œ ïºá×Q˜dBLÇ9C¡áשïuçA]3òÈœbYe¬§#ت¯å#oÑ0ÚK\³Ñ‹² ¯vî8q„0vî1fLP'ŸZfŠÍÂ1;ú9Átœ25KC2îZ„¦Ö/Sï€ë@A1¼5ðíeu&h/SVX@… uî+â(Þ*f\àÕŒ]öƲBŸ w¶Ë`<ÀÐvVçÓ>ž” Ú÷¶ ÅŸ}/ #}N½Ç£ï’\’´ŸBŸåæ­¯}hEútÏ÷ÞxÒZ$äÙÒ+q?ñÍcs(câçœö¹¸PááîœðvÆWݾýæ>ï*ÓÙs¶ÓʤÝÛ½Ëhïôô÷ -ÇG(”@iÀÑÃ6k+j!ŽaôÛ—æ…w,ÊZ¤š_-Æ©~øé#Öx´­uCØìb"@àN'l,jZ=€'#V'®ÉW¯ÔqP&ü˜Þ6 Ïfl•(£ªK]€'¡ùž1²ùöÙ·˜õÑ&ËÓ‡(­ë7ê÷˜Û|¸øÿ¸ TÀiêt޾§O’å÷þ(ÄÙæ¸ü–¼Z P¹Q‹mR‘ Öƒí¨óÉ{¿f{-YœþUä4CÛ]àXSÎÿ_\|ML¶ª$ºfG%‡?Dà ŠÀ*!ý€m‘ k¿&¨Ò¼ÏÖ¯Ì÷Cÿ®OY^~x /XræÀW_^º÷´ÅB7`±ð0m;ßx‘©uû©œø¹`„ZtÇúΔøâÏÿ3PÞ©µêôø/¨·Ìo°Æ„ýì@¢gì¹f(‚BÓk.Š¥„Ô ù…JÐåŸ_¶‚O>ÑÌ*¿æ‡Òêë(„Eå¡pÒúJ¡À4ìðɰòtŠ%oÞ[´‘˜>E¥œ{n‹_…òšÏí–²úŒÇ4bÞfá‡ö˜Ì€,#žÞ‹ ø¾áÏ_}ÉYG ÀçéÍâO_¼Åª¹³s¶øÅ/üØÓ<£¶«s ¶ma¾ Mûm¸b Ysü¹¤Q^Òá¿T˧ݲjZ(S½e¡×­@Ùs¡Ði“Äô7ZF¢¡Ùð+j@­ED×0ükÌeÎͤµÚ©™ZĉŽ÷î{Î6ÞÉx#ÃUyF‡¡À™?oâ!VÈt€tv5Sv 0¥;Rr‘œ½Ð.²ñ ŽG‡ÿÃr³æðë0oq#‘v½ª´ÖÑ”S)„…‰:µ°Ø¬)†ÔŒB¶MªhñW¸ÊoÒ²®®UZLÖí…À˜WY㉈_ƒYFH)¨ı Üð´—0~›>›Ž”Œæ…æáÑç=¡ljà åIšˆ3ò¢S;ªsä©à”3߯Q<Äáɉ«”U¦œk^ƒžNQò,CY›þÅÓ0 …]æÆûS³šœ±†I¨RpëÂ&T åQ(]£`dŽÔ²aRßyà©p2™%É Sgj "u‰dR¨¤ Ž¥¥€VG"üçêçQ÷<úCºý^ÌÅzÓ/Q„ÖÉv£îš<йÒZ¬%ƒwá$~ü\\¾" …®B›E„Ub©iè¯1¸ '* \X[#к:­ÖôÃS•*7ÓOòD1S‘²Ð*È4mT.ÁÕŠž­Y–{¶=mœT_E "qàÆ·µæ¹€M‹™'Â9O-|´ÇÇa€Rû9†óòaPPŸ¾f‘é:4$Ã߬‘ÿîÁb—Ñ¢–6ÝÛ›.%M«ì¨ i®>:|ÎBUJbÉbAóé) ÐQþóá»,ölŒ˜Ú­7ʹ\)_Û–VâÞ/"ÚnÂ6pnßU²2žŠÏ\°}šßJ¶ShA䘨ė†ÕcðOéÖG^æÕxß¾ *Ÿ¾ÖU"ãUå[&ýRT®ÙÝaz±–É8ì#!0-‡ð‡SpxÄbl>}‚®z|äG£LR+ÓþNAÖº‚¹Àþ-ï±®oÓý(+„•@æ&„›B~Õ9L|Ù'í°TÛxò@_ŸÒU\Dd¤¡%| ZbÓå6wõ³¦Y+¯B^$ôÖôH&Š…DŒWÒÑdä•HMÀ•Ö›üšŽ®áADa¬BñÚôbn@Àv¶M—&»*«#rpAyâçŒè×7vÓñ5GéˆÖNPfî"Ô*„æ}çÄo¸¬¥ €`'„­‘ÿ«¤oeÂ)1!HsUzÒäizN¥”Äå—Ńá2k¿ÄèÚÓIIˆ*¥ŒÂvöѹëEŽïl“„Ú‘ýÇ$iǦ-U‚¢à€»Ì»^Sî5 _Kæ5B/MêØóõ5gO] }mó4='……¼Äí”é¢*8–î<â˺X®¡P¤àZ¨—ëŽƳxk…±B¬~gAVžÜÍq%m?XÑ®âª]ßI[”Mw4B4k¨ÖŒósÎJgÍÄÙ™‡¥TÛ(hT&ÛÙ?¾Ï)4´ÜÙ‡kw´…¥ ÑÂE½­¯Ê%ðû]¾Œíå¼ü&Ó•+ÐË‚¦ù^Ü«¤¥Žã=&ÛÒ„Ò‰ À®æ~¡xòÙѱ£Âš¤}ù«9a­‹`†ÔŠÂž—<¯3`~±Ì&JýÔÂÀôTú;}•wq[P<×@I?Gÿá“Z³\³®Bž¡Ï¦ é´/p&ZùñÒÕ½¸´ ú“´"ú.–p%¬°Ä¼o'þlÂ{ÍØ¯¿× pïæûÒJßœå›h’eM;x<<^\Ò÷á .–G\BÛg̃-Ïýä4§Lbýõ8ék‚+¬Ò€ W)^ÕÖQŽÿÔm~¯úßy\õÄï¼úGð°dš ê´Üw†6/AŸž¸íJ“Þ9‹WN 65xz°ó[4V ºÁœ¦ ©JˆÂNê˱B ^éÈýŠrT`  ʕՈ"F[Céñ(ةΒo¯ïƒfÛIZMú*3“SžŒ@Ô˜5 ˜°¨ë&#ÇVý}WB+àñc â9«|Ùnm¹8rŸOm«ê9Jç„£Ô„y®ÀþâŠmNš 3b`›ûÒÝÇ‹ÜÂfÊHVA1ø<ݽŠF™D¥ø JÅol¡œÀnެl¤œÁÑA A|~¸Œƽh¨Ñ1Á añ,ì”J‚Hhú±É’?£.Çm"ܘ ¼ˆðD\[;«|)[ŽaéNÉØ\^°iï !``Gþâ-·n "ùäÇP–>³JåÈR!eY o¥  dyå¬[þ‹I‘Æœ> –d+í¼“Hcä1wÖÏ+Ô5Œ¿°\!«•¥ü¢¬{Ôï–óî/arZENìg0:G~ççŽv=ºÕ©O¼È©w¶›L_:R˜+ÕŸA ÌÕ’&Ò³³ƒ!çò77=ãB Œ:ÙýWOwîô¯½›ÊO´$¨ô+Ä6ÀË6eÚ߯) ËaûnfúE‹efJ„ºP‹€´évZ…™Á‚Ò3¾k%Ü=¡' -®•ž¬G„}À¶ /ómPõkØåÿ±P<êL§Ö@É !oúéé’5@-wó,°¶lzü±–%ècýƒi¾¹ÍqÐ~r¹iÅÖbf¡é¹À%áŸø×¹âb¥¤‰7)Kú–Öïö ^)` ‚«©'žõ+¯ð¸‰~hîû}W:ÕÏGô”·ï¿Éd–ZÊè³e ôž~.O—²¬—#~-…ÌãA¯nõU9= >X ¬õPU»>ü6Ïïwìþ¡€êd®:µ#q.:{V¿øâÿ ¬…}ž*õ-ïÝ»‹¶÷}€kósm´*]tÛ‰#æjeH}¢ZÒU¦—s§ïp•jÐ&ÐpFâ¤; ¢7”iü(æ¯ 6g)l8úD\ûÀ?â’¾?!¾Ê­Ãs³öÎî2…¯ Icº>}üq†}âî‚9ÜLÔB"-™|óü¿5S=Ø{ ƒ8 ôœÞ¯*Œ€óéÓ‡©sä*'^~»øâO_5Ó2WÎù¯?åøS +`e–{»ňÂú*«ë«2WP %uHŠŸ:fº±SiÓÉ Iˆó+™h3OÞ„AuxáxW‘eÂâ‹4ˆ/î÷÷TjÜ®—@l¼"Jæ±XcK£4³Ž@YÜ̹ O#¥-wSl<ú8ÂÂrùçùUF³†žu Í0eC`ÄC…SV©§þ”+&Rž…ÖÒx½J;q}¦¾ú«V³œõ1Æ.ŠTjßhë7) Å”´r›E1“ç6ôôéÇ#@!Ü\ôä>ño²&@…òâü1åv!óþIýèÑc겨b¤"î¾g¡} êW£"¿gptøjñ‡ßÿW¦í\`»|ú”År@q¤SHÅ5‚)}†Çä_ÁúµÞÖ|›@¿-¦[î}žr˜,-@[Ú~¥$ÊCªÛ¯ËÅœ=îíXâa‘Å…Ð’þä˜Ñ _<ç:<¼Z<{)4ëØuðøé9h‰Ë>)ÄEó„†S?â¦øcíJ‘n<¯ãë¯ëÜù££££¯µ°8Ï¿Á¢ÎV gv ÅfgëhÝz)¦QÜÒ9‹Ï0 EáQáŸ`ËP<{ç3•Ž÷P"BÏt6Ûp“çÐ;ATf¯˜–i³¿õ&IÂ4ä')ž2à§É®‚˜±IøÄÓ±Ó3¯ÂnYo4ÿåVÚ¯žWéIræ_ ;\.þò­Ût™^†‡úièÿþÝËÀ|‚kßÅ¥§’^ý–Fí8©*‰2xÇîZw ÿRÔ¸–0 µ+W—¼uËÙóÀð ¬l°ÐÍâ4Q³4#ÄmZ6Hí©·ah c_šÊ÷JïI#•µP ñ¼& IN"›œÄ(s/Ó±¼Ÿ(²#M1æ7¦Ti–o7â¬< Ðiº…e[Э«#˜‡ÌU3T×4©uÎÁ''Z<>Õ5Žè]§Yߌ XÜÛ/“r9ÏÞ±âUß^?=©ùTñ$?܆K¯N°UpßÕµ‹kÌä'ðà0BGUPÍ|²¨liTÍK| CBý˜–!‡iøŽ wMâ&””k[áIöDØéËàè\Ä s6 Û&)·‡¸Ôô&\—EBX„Ÿ-›]Lá&­2'ÌùæÍè- óýaâ"ùk%«’eºÒ.ÿ©Ÿuó2=B>óX ˜g|‹ˆó” ÒŠ¶·Ÿ_Éy–Þ­sá¤Ñ1¨yÅ$ŒuÜc÷†þtÁV¶ù3gÏÙšFuÇÇYDZ}^¦é¼/ÑãæLÐ{/ñ£©Ôé§#FUæ£éeè 0c’X‚×aE©äøµ?àº" bXÚX+þ¶ã6ŠIæ©s„žÊ uZ«Ü«•e…Ö¢…XvD¨÷„˼:uÀ*Ì¥)ØKKˆ|ÊÌQvÙ‘PæàU½}Óxè{áßæ —Í]î ÉKþè¢è£Ã/ã[(éXdeÚs*ã_3T‰ (…ôDÛÙ~ eà ÀøK™µ~på`œ‰Îr3õµ­AÔ¡müíëiJ+Ø´V&¦kfü&ÜØXí,ÏÜug~F× P7ý ”œÇsRâ¾SšU`ßÓOc°± ¹«ã˜uAKøèáÑÅâH JŸmmÌÊßL>XÄÈO誣Õtç²Ôh5CÀœã碻ATÎÂÄ¢hêƒè¸©UýÎN*þ`o˜s&"aØúƒ@¸K§ŸÒ×¾Ÿ»Éƒ1¡M" !ñ¾£gIÏSù›ý;íN¬ë’¼øÑœ“+”¹‰°ÉhêußräØ[kŸ³ $X?¦âYÖ.Pbzà|f¦¹0ÔNïü¼é)=Ns×Ìßi…¿e8ÝPŸL•a”¹5(§£“-,( lŸ²Îˆÿ~K]ËIÆ”ìt•"±sSO†¬Ä®YOÆS‘‰ë#•d¡³E½œ…ÿ0G§4Ï+ð‹y5ÏÖTRÑUˆ' ªs+¡b9ŠÛ­èG²I½I$L2PZñoåZ8¤ŽÅ]F]W¤:?¿_¥òýw©‚«§º³,Þ‘jþURPv¨#²#ŠOAû&AèK.,½¹UwÛô M© *èøÒЪn*92X.i`6WкˆïüzC)É(2i –Vô²ªw×!E($[©¡ê£GÑB¯Vº9úZmÏ¡p{­;-¢ˆÑWÖ wçÇË‘ﶉ‚ÀƒJAæ²kqQ-œá*ìˆü“ñY®”Mûâ®v:ÔÜ~¹ï"?pÖ>~y¤Ö¶(³tš(´Ð`ÌôÃòº~Hdèhw諭ֈK€úæ)(ô‡Ö—ý*#~ þº‘ZÝëWÞ­ÎäåÍ<ô*h"WÐÜvíß°c߇ý~Ê{ܤܼ4=㨰Y¿apƒSð÷åÊH9ä|?q¨K ä‘u5Nù¾£›8 €D¨SËV£]ž¾ŒÒ¤uƱ½Žèž!`Hm±Îˆ×N,sÝbRÝíÐŽ%‹ Ô`ËÑ´„kâ1§¹0õvú• •g~”õ>$.=}Ñ‘Û^ªÔ UüíHÆ1€Eë&¤b'ë?’)°*oÊ1ï Þ_0*,•ë/#œ1e»ÔY&¾Ëžç˜ÀÝ  wQÔõµ«Ü]zňe ë€ë(<¶Ì¶2n‰Ù‘h16ÒãèÎZ“±@fï;z˜ë v¶9›m‹Wä“ý÷*æï™ –ͺY^Ëð)¿UçÜÆ'áê1¿ÖªÃœÅá&ZˆÏë¤JÙó—ò—ñ«QLJû0ï!¤èøûû{lƒzè^ïmÞçä=—8Ì9ÿŒøÄ‰Ô4Û²VQ£Ï: ÇàâbSeJœR iÖ`VáQ…Æ—ÿÐ&yšBáøÙö¯„:€%ª—åu÷×wæ8Âß}9{2ÌeYyLÙ1c?`„.8êeÓcú#ò?ég‹ÀõcñC$½¹¥ÒúÊ(íÛm)|KÔ5ôzMÊ\ØW…ð*b›‹l5Ìé9õ¦–A\(©hq8U¯ðŽO<å5åäâ§²ªâ™•Ë7YH×Z楸L£àˆƒ@DVära N˜– ¼ÖÛú7¤›~þ±BBáŸÕûÀ²BÔ´h·Bðˤ——ÝKŸö¼}OÅÜE«ÝbѯtãÈ߯‹º]9$zÛ2fóÐ8ˆp§†©Ðì'&ø„13å8NÏÛÞÙþñA€2ÔùIé8 Æì»áì¾õ yÚè< ÎD,1ŒðÄsÔkø¤…w4ÜñÚXŽ‚Û4`j†ÂJ‚‰ÿrdž~–BT~¡äΰ”ÀYsy;òÓë®ù€pލ4A.`jF±ÚîAæce0XFUµß\,ž0`óðGﯾJÈ;úÇ¿‡Qܶ$A»gYh‡ðØÜµµ'à€v`/õ)g¼xõ% ǃr8óúÁÞâ·ŸF€²ã“§å¸M±iLVŽB§®£¾¼/Tô{B z0DöÛ°ÃÏ4ŠZŠ@n ¥ëêÃ<>%ÐQŸ ËuÛ_üÇ¿ÿ†½»¥ ·Ï~ñë9;¶Q‚a£ xá–Êᤠˆ/´áK™çUŽ%^Éhw÷˜’1ŒBÏ0_âL6#aiÄ‹zY5GXÉÒ@Ò#.1øQ ñ©ŸeºíRÒ Ä3ôMô}3;†iëѹq-¤ÓGÃØtùb"‚ýóßüÚa”ÏÈýäôrñÇ/_Ò™+¥­Y4êy®)ñØii§?à“„Æ[óI_ìq=B åæZ_¾ø !–ÄcKëþÇo?ÜÂC«‚k3bA!”õ²}gغS?kfÿí*Û/µ60k^¥à…Óf«¦„å½éWƒ~êªê£µ´Ñ Êï¹' fdh›+ì'~ Æ-ž¥L mû­TAþú¯|Ñ=ýÏŸó9hÖãLçž¼üoükMN,{lÙ:üÑÚñäc×ó°Vƒ†—R¢€&;û"<>p™óTšu‰†“ ýÒ#Ê*öñG÷}½ii0—qÝE“4ð*%õB!Âô¬„ë_ CòÄ7 8å^Í„ßÔž¼ò¾ã2ÝöKR¾ˆ£ÿ 'N“ U®ÜÒúç/¿ / ø¤1:€¡Í-‰8#P“|+ê§› àÝ”Ùë¢M~Sº³¼Â¤À‹¸©µ.„Ñzð麒Õcƒ3â$Wb×®{±+žó‹jÒ¦ÛZ Ö,i9Pæ`Z9*t5ôÖ&Ã! ¤Íš:Îèútº¶x”› Þwa¿޿ûÔñîúú$>­›ô㢰šÂÑoÇŽÌåªm&* ßîÑÚ±r¢wBq^Ô[ën„%Оtr¾¸ ƒWú §ÊpSiV ¶H%[¿RMœ-¯ÆÏįçž?á½%°Äþzž»&d• fõÓÎÙ6åœÔÃQýL!„2 -År„bØ}¶a)ùÖ­iÃ5)( ŽH¹6»;^ã\,ôD <+ßài`1åÊã÷üÌÛ$÷i¼òõwµm´(ßm9}7ƒ`…× -•Š\Ü‹)ëØ—B`~µû©ÞRè«&*|Vóü½Ÿß­¼®pQ¯ë. ¬µxU…’‹€3ÿR( £“‰¦ä™Ò_]æ^-íÝp«7©7ÏÈNÂudE„ƒ/ÛßAˆ÷*ð¡.‹“ñ¯õ¦ÇŸk.øÓ¥irÇé'ÞÖëzs'PþëpJbžžUwÛ²ÃÌ\¿âî÷úŸ³Õï ‹Ñûý1d¤­Z.åΩÛVËNYwÚÚãÀ©”‚òo@ø¶Ý{¯¨!ê„Îù¿T8åôe ²]¸"1;Ïâ‡öVdhÕ˜H3o’foë»&CÙ$U£ (¥l`R -;žiú“¡LZú@ôn‘Iæ) ”gdU„ëò2¯4¹w ˆ3\û8B4ää¬.åɯïê)/æ÷z«@Œ×.^ŠE„ ÃØ(‹¦YóØdäã÷¶9‰ÏSÅ¿lÝ­CËeYô»¸ðøÒúŽÌHf"qû58¿„¸Î>êþŸò)çc«Pœ³`FFþ”¯Ç‰¥-F šÛ¶øän›Ý,“&í”ÍÊØn"k´_ª1ª3Ýßa§†bnuŸ$IýŽËh—PÀZî‡mB.Ä´GúY¹…T%—Ùz9jˆQ†ðÈô< uæt•Ææ&ÐQ ŠP…5LhÇó—L¨ël4^Õbug´P¦ý-®ã5´Ä!¯ÉƒTïÝ[6,•Ö çç­ß–óË1mCó<[v>MÕ–Ô‘¡Ö%ÏÀoÚ‘ *üÊÙߊ.4í_£T^ršÚ…ð!ß%'0xj«N 9×øx(Ïq’DŠÁÏÀÒLyGò:¿‰Òæf÷T2ÕÏOݧmFÓIRÂâÊg¿;àUYC©cY ßwÙ—V¸˜#·ÐGFü ~€âõ”38Ü%Œà¿Y‚ ¬¡¬½°`±¦Ÿµ…EßrR0RK}LË:êç”áÊUû©Ü=œ5q€]ÞŒøÉó,Óî¤A€RÆÃc¬@×ÔˆçÎ…¦&ïÖ)Œú×I…ÓVQi+–qœâ%±ØXãœòySgE=b6É“A0ÔÿŒ'FÉäSÑÐê1;¤œÚÊQ¿gZ5]÷#ÿ3O¦/ä@y¢tÝ—<Ñ-¯n¡j9õÞéôRp—þMóçuïµ €ÑÌ/t䌹ÿw¿û¿5Mßbžº¹zAÿvTá)^l[A€Õ(D®ZDë47™õ§ý&A/QiØÏðâÌÉù…<ϰçûô/¾æ×5 àü¿k‚SRp4'¡×6ÁÊqw÷WÜ<¦ë+{_|é&hBy¢(°ïX¨0Ø7¿úô³0s 뺙b×«ï³ «ý©ÓhéN¥°ñH àÔg¯áBý ´KÈ '„Î㇞æ'®*º«œ/r®¡Èìü‡¼ É­+üÂDh/Rñì…Â. 5Öå´]éèÀÅl¶¯u¹ÐÂL›Jªã²È2Uñ+´$ã±íëÞ§ âÁ{Ëá")«mx]¾º%õì3¿q PødåÊE¸÷q«oÙϨ+ÓûkÝd˜*|Ög‚¹«|³­ÏO;¤à£>B¡\† J7> Óæ”Z†ªR˜õ+ŒôÏ–Q"­3#°l.øºñ„>Žá¥/mÿrl@`©šm1|Z1ëoF}¨„\Wpƒ²ˆ:Ç—h(yѽ|'îH€úõ!k1ÀƒÆ -zø‹am”X—"Üœ#ö|„Gö§ ¶sxÂ…ÈøåT˜T¤^°&Â…^‡ãûßÿëÿ t=Ô>Çöë'@Ï_"h´®u äVó5¸Ÿe»¢Pü+Ô®¤E³$ºusß~êHݬuvAø' „6}Ü^-^¼|޵N°HeíþK [ŒK oú”Îc®ýÖ€Ðã¯wŒ¿ú”o‘åM*àNÁ k‘"JM¾µ‘–NŸ¹và’ºXø#ùÚhP2š¤ßd]ô _W‘Tx»ÞæÌ5¯žz´ïË—§‹?°¦Eè·Bü¸Óɩ럴˜Zf¥2ç/´_KÇŸZ~ Þöýío¨Ÿmÿ«_ý*Ð8¶wú7ø{[î½VDB£#ÕÚêwÄש¾éž9Ã!,îÃvµ®.DJDzóǤeÃCüT›ç &q;£¡X´h÷iŽþù½Q\Xh¶\î#oÁ¦îoÏ^.9 ÍÑ!Üóå@H$—E1¾P¦¿Ã(ùrŸQr¸J›¾gÔi†3gY$’Z0Çõè/åMÁR·y÷jÐuOt ï©‹L[¡»åš à&炃üúÜ«ÿ×< KË%\×>ä'*2.øª¯›!Àè4â_bÖ ´¾ÎÇn`N\¡-Ÿ-/ã¼õ,¦t%-mŨí:&JËbWRË/†ežwÜ(¿5¬ªr7U×öž‡îºìßö•*¼ÔÁ O i˜¢N«Ò6ÂÄ…v¦k¸(vy(étŽŒ2áÍ€&J{KI2˦(£åÎy/8Ã4 ÷"V[Œ«®£ÈŽ[36E3¼åêm™B;¾·tÔ'~‰€WÕθoìŒ:¢L‚=ÉñÓÉY]*f ™Ÿ}„6tþ7ÌP«eqÅ·&`ñ%Ó—)jp”§“¶¥¡ôYž£T¦¡uÍ!~²väÒ³#äÜ0á#>>$3Þå³Z®ìw],ËLòŠ›Ú48"ýà+ Ô¨¡ …_Ët×ÎA¢é7B%3­Ë ¨­«—´b™Ò‡é'ÂÔqôŸÂЇi}“üËå1 –9ö÷«¸&Ê“8×Køí²ØÖÁ‘ÅÎŽ¤.²t&oÖ;iÏ)=PÞ«Ü)ŠÓU­ˆ 7…. :–@ h;Rç3x¢–ÛsLçGŒþŸ?èt ÅÇ n e ~OÎz ˜‹n¢@j©Ì´$ w{ëdzT ‰Ã Ë*Ê3yú¹ð|Uêï¿£~žÂ+ ä;*K6•õ÷?.>•§Ÿr†…+þOXè뉎™óGøû©_i&í&];ç/TзÀѾJ€ Ÿ~m 0Œí¯“&Þ¦{›eäY&.ÇŒºÂµæ¶ éô5G%¥Pá\—Z¨ïW ÅÆN›ÿ Csçü•„âÈGS–sB‰÷. ñcK¾Ž¦P4Œ„/´3{ÊÕ'ßm¡q»ÅNá{Î\’ìÆUÔ9N–³ó…ÕùkŽnΚ)X¬{E›sºÿÁ0A?3¤T‡Y@‡ xç]µ¬@²£ºÿµ¦=äÌçE“w·W–µö­¶..tõQt9zÐ$ÈT)Ó¡[oq^À%í}²L%G UÜjÃ.²òQ×Ï?T_Ãø¾ÃÎãy¯“f&Ç}+"æš¼ðK¼ …jiOz+èƒ÷q¶2ïåÄË+=ȰÖX€_ðt>æÅ{¥ÿ­kFŒÇ&A|aâó"Bꨔ1ò­—?ü› #‰yÈöŸûÍïï¼çÁZÐA˜)Æ~êþùŒÅìÓ¥„Žj Àeê¤@káo¦3Œu쮂Ñ-¨V¾hàYì¦çˆ³"Z1ÔQÒ; \(kôÍëÕ÷ý®áúv Ë:îç0EÄß,s¦á-__-І*¥‰†FøÆŠ’|±ÖBùÍ“š÷_ H+üé±ô(øŽô–«ø¡ë(ÊAwj(È4«|Òb•Õrê×ùKoé J^ÔÃ÷BÏD‰`¹ì(BŽœií9eÑÜ)‚Tºƒž1#4×,w°öÂüî†ëˆ–ÄA$céµlÅ/)táBFx½Ê¥ '¿^Rë” ä5Õ’Ö¿ =ª½”– /œë§ì¹¸÷ÄTur0£B+ß«ö+%n>ç/ôj@… ÍýÞ·¢g»¯èt*Ú[¹yï€&p…ÿ%&§V!ø%ô%ûü]”¶3Q_rÿoFCÈG9hé>º7Z´1Cf“^¼Ëk ÅGˆ0‹~$n]€\áþ‚rîùÐÉ‹µo!ò¨ÍK¶ÍÕ9ОŠ&AjTЛ†£^ãÉU ²8NÂè „½=߯Fû»µU¨;"â¦ÊLñ,uùo£½Ü¨GU/bØy;…®ç­˜3 …®ÇöÅFV{»œŸÀ:WõŸQ! þ\^nÓ±ýØ‹§ Ö: Ü{ \¢VËÕ]¢Ù;Ms~^Ï.F².·Ë[ðjçÝ‚A¸›ƒQ# âgœÝzS?C çí6ÕÇŒF›y;êvüÞA‰4Þ’ž©Všû˜¸õKÞy9Rª6 :E)¸´=¤­(GµYnÇ–³m¥m‹)/u›Ç;2“¶2…¬ífd›¡i9Úp>tt!ÓcŒ óÑD.?:ó¬|+Žå^UK¼n ÁÚ¬úJ¢ã1 À{u·É›ÜO†?¤&¤)íÓRÐÌ6Êã.Ÿ¤Ì}a‰€R‘Ô©@*°í;*–+ ë!yÉØµ²í2ÅWJgͳÞ2Ï­‚y>´X-9’u×øº…5†ýÐŽ£Õ pRæ-ªWê7yöMCÞÏ H4tn›.5`½®¾šÇ5üt¦“6Б+þOO_aRE?T8.KŸœ¤–ô=F–ІM‘i,*^´¶ê?e°ŒÒ:?:N:*õ1÷ðÙ>§ÂpòžKâ[ø:b¶­lKÇ}ñ’o9Ý~|zªðw:Dïù–«`Ò§3ùN%ÅQµ¸}õ %‚©ž-,½»;.Hfë, ÛTaû £g-DÈòRF!ÿq±îún¸;mç½õÞSC3À÷‰g­SZ˜ŽŽ]õ϶¿c?-î[økêwÔ_ÓÒi›ûîŽøå=Ïß÷>7]¿+Á?Ð{,úñÝC‰G'û}ê/¿üŸøK¤>6³~{Ä<¿»l5©3'ÄÇj„€£µ7Gýq´­"Ã6N›§±ë•¿ú…ÑÒþ’€t²‘UœE†É¨<áœs;_|ó-ß?g”/ã> ¿øêy`ö-#Ä^¾BœerÖα SXlmx²žéÊÐ9{þá«@áðŒó?BczhÊþƒ}öÍ(¡XÞìéÙyƒFY qvžòL¥ÿT´Þ&M„µ vJEí¼„ÔÓ'°¦~Íõ7Lqœ°×]6€f?ñË—Ÿ€çt™§ƒèóßCƒdäBqç1°–S˜Oº²¿ø«¿¼$ãsþÚâÉ‹Ùúxˆ¦ì™ï;‹Ož°gœ3¬3™Mêk­Ò¦©5*ž°|¹"dîŠ6‚Kâw00“1lÍ÷ç¡"uÒ#‰Ê—ümC•¢=ýÊ 5á—d°tV}i|‹tf:2›ŽÊÍ©b0ȶýÿùE 'à™‰áel{LÇüò´е ;0¿_~úq`Ykœ7­5&â=x‚Ý™¢³*~ÉìN•æܯ¹ ¼ý(̽Áq’ØäÅ}'ʬ‚W3»Àþøø1Œz8çÃ(Ów§‹‹3óÐ,½†P¨ï¡W¦n{où¥£'OžÐ?ØVÈ$º t íì³[³²ؗ~H•ʯ¿}™0~ºv/øùtRFUn/’C"š?Égª yª–ÎëŸþ$OI )Ä»úÕËQèäTÄlÜq‰¥ly£³pá•|§o~cà•>»äÓO0¯UÄU¶·<š›<ø³É]°'´üå?¿XŽŽù<ºPËí‹—G‹ÿõû¯]¬èYÇGðw¦%àëÒçƒý'*~>ùä“i”/½~þùç¡[ß¹¾ã׿þu`Oý¨¼K%ིtçÊ\x¦v{Äâ?€u°p#É0_kÙAø·`¼+?]™-<5´Í]wÕჼ_¢¯ON¢Q¢â+aÈ€N  ă Ôp…øå¥âAV¦­Ò^‰JÔ,R)?zœžÉøœ`¤´«9I-ef9Wsš¦az+Ú é*¼"À('Aæ'WñîÜ6Ïêºê 4}™FFp(OÛ”#å¦CÙ©oo™~¡]Üï_Ïà› ÔQ.¡«áv[Ú lË&r‚QïÑßP#;•!ä) n›Cœ\ĤÊc:2 ¯¶Ðà9nÅ«~Ö•w"Bg…¼êŒ6ƒÆvtdu9 R8vDIÜgÄ,ôÏrÁ-­›Ùä9÷£huÑÆ…a´Z?M¸e–%1âÐ?qQÞE©ðO¯‚‰ŽtÚ ððR°5® !^e²Ò”õñ½ EUÒj kBK¥žsÈ’&ç-§×è«¡Š3­#áäjê2xot]5a7Z`æ¹W…æ„Êyö}ð.îÇ•€ã4£‚U;) ,§œ„zròœú²ÂÕ{»¿`ÑßjN™(ẖË+MÛ@Ë•¢Çzd,´´Ã»”ŸCè;­úöžJE°Å¡Ó,–IÅJ>åÖcæùOPêœÚ<=½fe´Ì*0 $øD´ÐÜk$±$RˆiÖÀ#S<(tgX=¸LäI¤ž !¬“¼õ:_%à‹a!«)gꃕ5 ©Ë†­z2꨿®û¿¼MºtÊâ üzòäÁ!ëLP®8ßÂûÄ: Z(}*Ä[V{Þ¿-ò@ý…úyÅ*›/¦ïàç½R¬ÔeÎg*Ñl5ÿ{nµóçj‚Åt!F†Ä£™K¦cCÏ:¬íÜ×á—tª÷J,¤4˜’®©2ç>3Ç/Ãv®ÿœcb=1¯Íš 7 J²,ÍÛH“‡ØÊZAFzë04™¢{¦M¯.£ÂË\½N@“¯„mWy½óM_¯ q?&üa¸êvì8{ ¸p ·®°rµõ‘ióöô?½í qÛ¡Ôrí¿Î÷÷× ñgä@qêï)[æíÖ¯9!”mÛ#)}÷ç~½:\û÷ó”€\L Z/¯vzÖƒËâxÝwwüï½·ôÎs¶¹T«Štd}\Îwž`j¨´Sà WeèrVÆÒI×9¼ ï^¾è°ÖRE/ßjç Ý=ýNÁd|î]ßSW™Í¡[¶÷”´†aap¨¯?* À”W/• 2…5f!òÖùÄæ¦øp Ñ5bÐ=ýÁÒ™¿2}‹…¢*¶øHÕ& XŠÚc‚:@jh¾¥_R/ñºFŸƒÆjYMAh]PøK§^ ÿžh(ÿ󒎽l›Vª ïî÷=Rd YOž*BàÇÔu{íÅðÚÂ<^çI+œèø4¡«¦mÈl|hÇÉU§é€6~‡è{aèAGc$a¯ñ{ªBÎF'ÌÕ'>]¼¶d(ÓDˆf-š] \SŒèûKZ–âÞà<át±èÏ{…¾Å»¸°KAobŠ?tÒ 'ó˾j·ŽÁô }1:©·da9oº®ã6a¼4‡÷µAG9Ä¢ydO¾ïÀ…‹ô< yè _¾¥ `^ŒÓÅ\«Ö,3·ýR>¸´@'áËÐÕ‚uµ&@…éa:ƒk ]ˆÓõu”>ðë|ß9L|‹_ü^;ÍL©,d*štæÕ+©ò<ް³@ÒH hc<¤¥íÀöâ&ø­(þªÀÅ%~HÏi™DW*™¾q*Ôôk¹UfŽ¥g„•8r^ñÅË“@×B[n‘¿f~ôFS<©¬EÀÁ¸`<Ž<–˜ÏÍâÂ…H¤¡ê&èE»¬ÙÞäK{œí\#d™gYPª€]×É"%íÂêMøº*Ú¬uÛñ‰8ê;i™®¸Ú€þ7¤èÞKåÑôƒð Õ‘ú}€Væô#³”þõÓŒª“VÀþŽÈH[‡m§©vMº¤¿J»"¥–5®TG¶©c‚…™ M:ÜÇ„ñ~T—»ïº;ïR+£ع\ú-g1…ðÇ8…ŽiotÄrò žÄ4 sþ˳—ÌÉk“ð.¼Qá”~b¹§þb¹ÌY>ËÜÒ>Ü"λÒÁ !}'¾ k¡«Œ ] wxì®§1ŸP®#>y|‚éßA‘[å‹Á}pìÔ•ß ©rÚ®>Ï…¡Å+g›ÑŽÖ¨5)Ÿá…ïˆQ…¿g›B«3³Ð?ˆ]­@¦ÍÔÓcd†B—¾)ÿÙÙ¬oO„¾¨Çü´-E®Ï:åk~ZysÒçü«Lzre)­òvù˜W)¦-äÍ£GüÂñK¯ò<éWËàÜRц]ë· ß ÓËáá3ˆÇEu.pyŽ€ý–ççõ%Ÿ=æ|£>‹@@bu\Â!7.d3hro¢ Äž mÒÁÓ†QÀX$™««WÿøåW1ù;B;æ3·øÃa`Fü˜µNÙz ÖÈó%­MÎÈÏa=ËÜ‘S.ûÍ“DS@¿¢::«³\8ÓÚ°Ð}®¶­ÌݵºZ Ó8‹Ðª`0þ_|ýͳ@Í|?9Ï9 k˜5ñÁÈ›—À8RÒÍTE×òV}3H53bÉâÌpÆàÀ²%”?Äw.1øáÙä4¯ Ûyì¯.<Ñzõ©“èœÓ#„éÂH!¬:c«Ö×ÏþÌ(EÎ|ãñõâ_p¸°O¸{ùÒQ¬S(¤G}Ý"'”á9úùæ™ ’—Lï |Õ±¸®q:àú_úY[™ ëH¬“´]–ç€SúÔKyßÕÓ’.v%û¥Ï†œl¨ñ øQ—°à'ˆSQt]Ëc¨ÔÍ Lo¹@ŒëôWªóú§L§‰/Ÿ¥•HiEçó/~ñ êZÖ‚ùš…¡Ç ›Æñgq`!¼å«ƒÏØ/ÜŸ~|¹ø ô· óE ¤^öwûŽíîEÃPüQ@2°{©rfB·Áݨ2á‚ãY`ÚE¥X%:;^8/âŠJëRé3 ÝüFŸ¹kÿ´8Ñ$]£óðÆßýîÿ t7”ÑýW¬ƒr«-øBÙÒÚâ” ƒ¢2ÏÛžæ©Ó¢bͪÿ}[–¼ÌƒÉùB…ÂÚQ51åÁk:ùÁÁÁÑâ?ÿûZ±–g׋o¿õëxU×Lõ];ßožmÍy0øaMï¸-®¦[ý¯Êì:°>µÛ;Á¤·=–0¶N7L™Y`Q6ñÚâ3¥ÊZ™O?aD”¸&ä³_ÿ*°x|•/'(ÔÒÞYÓõâÕa”šÖ<½|Á^ÿžB ÿ½œ© "P£ý>·B¯°ÿ·û·ÀV~ó›ßD0?†¹Âcߥ{¯ÖÅ=¥ ÐØù¼/Ä.ù)ð=åkÛQ/#Ë"8;ÕÔ1‹Ø§_ÚÔH†Ç•óÁåéo:7 =ÍÛÎ÷AŸx8 XsZµoµFþ |2l/½?šÓ»™±²ç˜+BÂBðfŒ¢]àhé¡éçu/øÀ„óqÙRG\»TJžNʃÎr窿ž ¬ÕS)MúãÚ»!ñe#ÓÒÊR2¸§~±d4gtVtg„å×-ìP'ØÄÀ·Œ[‚7¥-Òlgqåe§sÝC}±Œ…bhôÎÁÁ¯3ªueü§¿­¡ùkDñ¦<ÅÄRyÛ¦Râ³ó¹+(ÃÖTÌ3ÿ¾)VXáóLYóÇCæ@U°¢d…xêç:@IDAT.ÊKý’„?Ž0K„xžƒI+TM|€@C¸ØÏQÒñ©‚ËUÅ7¬={u± é) dž±NSÁ‡ŽLʹvÅ•àBÏk0ïSÎ*Wàu½JÀ£ÔƳiêG@ §_UzJ³òÍ˺­`õ>•ãV¨KdîËËz·+aˈE`“Uþ±âÀ©°ÚI£ Ù](÷Ýë¤q*Ý8j²5ý¬,.n+ Àÿ²°ÁÖw›Ö’-ég^ÝFU_‚Ëè5µ4JÜeoh5½Õ¡îßõ{Ó£-Äý9cUñ°PëYà»É¼îI4+ü­CÍûC;œ„zxøuø¢»+ö÷Üe!ï±éŸö øEØž¹Y–Q@«’Ñ'•ò^ºVqèQpî ÉMÄôŒBK»sXØ+&,Gü‡GNcZîä@ÚÒrøïôkçËK*øÛ4n¹¼|'´,òwS O^mj»b1fˆ.´LN ¸D¨°·+¿:t7“ýïüü#c-¨5 ¯c‘¥5i’…Ë|»äðÀ}ÿNñªè8TAÇePØköZþ†ò:éS¥¦Gÿ^-ô­_x4%~Ü{£ˆŒZäâ@ €güÃìè@2t²ý '¡KØ~mˆ!˜º÷Ó´;’¸÷Va›\¼â6ÛbxÖôæüVhÁt5Ñž3«ù~­¹Y§TD– j5d9%p‰ã®†[(—ÀWE‘Àìè>’B[7YÇ%}‘3œª…R–-ó©06‹^ø±ß©žI½Öý5Ó5½î(Ô)g»£œ¸  +PËìZŒªÊ˜v"¼Á{ßyï%£ï÷+,îÊT¨0•±kMÑ|èåôK­ýpÜÏÉÄü¦`ÁSÊ9«ÌìÖΜo¤~ë6ïdVu¤J}M¿d!×S¯•žBß…FÊm mh½m/ë  “Žúr ¤ Ë«èIáh:Ò’tUô$ó(%ºô c†ìži†ž‹Ÿ¹K,W‰Žo,$F^Ù§7v­#XÓ7qACp'ÍÐrjoÁ-±éÓÊTÀò‰¿û—yˆ{édÎ<íK^âUaRÓIGSm­Á)úÿ,®Y)Ú”*©ÚwÂɬB÷ë{ÿy4·MK¶µôÐ-Õá¬ß¼Žíÿ×`ᣦӪüNk¨$•uÔïrx¸ÖúÛ„ÑŠ•%P¡MYê?ËUtò¼¢gïCJ¾h7»Õ«h»`, Q¡sþçcýŠÂß©§BÝ*ì>~騶ÛÌ Š~¶Ý\Ph6ì¶š¯Páo_°½KQt€¡…È‚jÕ‚w¦Šô!ºAv¡×.¡¥ìŒóú •Í&hy´ýÈuʶÅà¢Öãôœ¿u1?值ټJ‘‘û²-üïCù\Ój‡Ÿ?Š{o\B÷Ó•ggœeÍÀå¥ßžG:¢Aâmw \áX]`zã †H Ž&pâ†èõ–HË<* 9—{†B(A3šZbö_²RýŒ¹éó¥ÌV¢pÕ±ñeNjƒÅ°Õ ýšÐF—@Ô…³Wß[ß„BµO͆gì ZßÍM™¼_õrÛ#ò=Ρã1Böt¬:n”2®Î4ëGAIóëí» ¾Â˜,G€D0·ºÂ4ŒÇ%SÍQÈ0˧”ÑàÑ®.æq«ŸÖiËbÇ]g;E¶Ã•P”©‰#æÈ1ñ¯ÓQ´·08×Zxz ½|‹i]vh0]u¯èµÝü^¿4lAøVê+·©J›qFE3ò^gB~’Œ¸™.ýW4øly'=ŸäËl0ÖJøýðÃ#w@KL›ðiqè\f)Ã3éCSuÑ“øk™úRÙk¿¢h¥é1}fnüS·8y^ù&_|uEöƒ½+¾µÀ6)F^Õè© ÷³ÒÆkø›¤é΃yßøàEÊ)tÀ(ýL²z,Z”‰“ó¸Ôc2—ëõõ~J:ÉUº·²è˜N)”öïí7Ò”Ó±RÓõuw  èóv›š;K®¯yG¶9‚Xدõ@ oWÙ‘‚í¯G‡õ¾V»(€ Ü}'´ïiKÛW~á}£Ê?ìäÐþÙ1}Ãé2Žû=wº>Èè6#RøÎÖ3×:„$}ËhC†Ó1]¦e`8êž1ꓚ:$… ëúÎ:UÝy¦NÝc’ªhzTø)æ~çÉ/±¸(ü_”7* =¤éÙѰPþ¨Ð”? }n^Q´^ÛZ^a[«Øî¥T—bçÔªýLº7›œ $¹8û™èЦ…õÅ‹ø Ê#Óbk¬ò"TqðˆsOù“»mÕ:Ù^M£æ¥ÂiºoZŸžówäß#þV¬—e‰ÍN¬Š÷Îß¹`g×Ù8ççÇ‹gßþ‘9¥ohÔ3LÎ7Ìqq>ô>óˆôÁ̱*t Š6ë)ÐÖ›`a*Þbÿ2ÑÄüíØy´SÔŸ­êè¿R‘yzˆsˆÏ¿ T»=8<[ü‰³ë…­º [ó¢YÂÞyG“Viƒ}ôqZ¡'<}út"p‰¡‰ßzKÔÇ,¢iâ¶£¦Ã‹çù–ç|ê˜3´QT©sR|kÀ}únÜBùxä9h´ÖÇѸk¬K1QQ¡ªT.Ÿrã5¹tøàd„Ihcˆ§êÐZ[à#à‹‹ÌÜóß‹SVÞ8b÷ ÓzùÒ3®Ò)ìÜÎá í {;‹ÐËïkõÕWµÀé³Òk…‚hù󸿄4áíïiNã\êªb¨9òÖióª¥LX—_~<ÐÈ‚‰·?]{PzðìúmÎ8(®:»™tr…+â›fÚ¬Ò2L|d¼³c{e«Ôh Íó_|ýÇ0MÛåèøjñû?°P Hõƒ·å²,”Á9èF(­(Üz_±ø3GbÁZ0ë0鯅Rg(Šúó×Äãh\†}ôä1— ’\4çjùïº)T·±¢V¨ÝìÞ:ÛîÙvÊ{ª9h¤¢xkFûA`)nZ'2a?,µ¹ÍT—Z Dol¹X´êcvÃ9ô‰ /ño’É*ÄÏ«W¯¢$BGÛ0tÏžW˜`6GYzö‚Cr®N‹2µ½Ç>ù_¥¿˜‡}#­èÜ}Ú“2 hyâ9‡Ö?'o Ðid/ðáAÅ‹Íd¿¸öl¦°´ÒÔ§²gMÚwªßª<ºçÿdñ ôsÂÇ}\uqqHùÎcòG5A»ïÝsPT2–(ä¶‘N¥À/XÆ:@¶i¿”c•gtISd7 å³®-HNÕø!Ÿÿúõb-ÝçÿMåšÉk7Ïím óÐ2åzüø£;üðãWüÑö³=…¶¯í/ŠÛøàà °…¾ë@ú^‹ˆÏBý¬·x Ryè³ç'šø·6—ð›?…—:ê‚òG°@Íï„ÁÞ_x¶DMñ–5Nú³o:çÏçÀ?ýYfùšûü…ýüÙgŸå¹év^·Âèûõû΀F‡ à‡LÎc8 A‰3·õD¦èÁhj–·@»­ŒÞ¿»Ý ²-JÉòÖöHpúþ·÷l4.0ñHØO=34«EXØÃzÆ•U×~deK¢ZúÌs5Ã=öආx_Ãm¦ÞÌLA)± ½ŠvbaÍù¹`Îyòb(j¦vpçÅk« å@HÎ ƒ•"ñ©Ô]žÆÃÊ'úÇQh8àÀ—º“.¸W0¯TÊ#Æø$Ol¤ÿQNOt´¢™­˜ŒÖÎÐÂrÙY­£~‡‡05p`xq°É*ݵñ"GºŽîÜ9á*~œÇ ©¸)Ttt æ•-?«*Æ¥2Ë·¦Eù\¬Vë¨SWÔŽ×^–½.™ygÅÍkœáœs<…‰ÁÀSt®ÿà+GÖ9Èäjt(”#-<”yhð²œs']+ã¡Jµ/YÚa‡ ­Xç,LÝbd“i´X ‰³¾¸µº9Ô«ŸE®Ï3$û*WâùJQÚKQ+ ÕòÑâ×åè½ð'œ;q¦k<÷}<ùÍPÅ“ôâ³4RÌßé&­…¬;p} ýôŒáé&‚Ê3<,I¦ø¸ƒªëW0œ·¡½ä.ÅgÊG~£–Tåã–ðŠÊøók=õëøÞ)DV߬Þòð½Î<`ggìY–p"“Q.ÂËÇ®ÏñrWP¦2é/PÝ oû 5¦í`ö±šv±Ž–RGÉs;jÀ},ˆx¦Ž† } âGä=‡Gœvz“?ë0§çð#ù™ÑØäFÔˆ_¥ÓöñR°Ë}Ö¿ÏÅO?¤}mWïç#öз%ìË2`-ä7¶¿þ½VÆ{Þ@öª³‹«ÏQÄ…°›~-D¥°ƒþzŠÀC¥*ŽñªÍÌ×ru=,»ýReTÀ{a[ägƱ>Â÷Õ½càîˆÆì-óþ®4ú¥ ·A9ò¯UôX¨4DIëüì6ê«¡Q# 2 )øgG6ÿÌm1ª•P¦} ŒË„dF%5uõVͶ6´„­ð—ú¹ ^‚h¡(Ô)%Ô†úËÌ–ñæVs&a1¯§„T½Î¢FPʈ”\úªz™jרûï:;óÜuè†ówuï›q‰3ÿî(e,SœBLSœ·/™ˆa»s›žÈzê'g]ï7ùºWYdøŽ °0¹çÙ5в÷kaÊåúMÃí(ÅíXoSg\á¯|õ›âÎîškøu’ԟƺåE¨‘ G®úEEiè á_kH¤#ç)ë2–xh³©4#-‰#ï…Ғ̦i¦™· Ïr7®2kÔ|tÏ€||ö1(œÂWõSë”yþÓõ™ûy?ц™Ç¾«»q‹VŒüF °÷Œ44 x™È,QûƒWÓÐ<ͦ%qá{aõ9 ¶9PÛ´º­\à™ *ÌWìš(}7ÏÎÃúéz¯¾¨GÀ¸¯ßâô‹ëJLõŠ~aßH»E™¦xž÷‰Ná.,ÞX‡ÒpÚžS“XÅä9œ¤ö É¬au7•à¾Û ‹HU)ï†ï*êë}Ú¨2k?Í”óê5çï`+8òÚ7O^WVÑ¢éRhm«œú÷}Ó·í«¿P|‰#ù§í<§‹¾÷½÷æ%¬A”ýÂU«cž¡Â ]‘¦|\ª–lÛ%u±H/NØ7I zYÅë±¥¤_šO÷MËi}|¶ü}¯¿åõÒY—÷Ù½C F‚Žbl¼,ücoë§ý9ŒISPZìj„Öx#µ·åÔ3ÈvDÒ ÿøÚS“@ Ÿ3¯…6èèÿèÄï0bã£ÎoeÞ?!¸*[&Sæ|5>‰  ¡ÍA>˼J¬÷Bë½ÐKMÖN&¹O^3æ6G»*T2ZB³¾ÊB/ë`¹éƒx':K§F|”[ãê}*?àF&âëÒ0aº=„b֣ŢëQŒ»„M NZhþŸG2óÆCO8ªÝbka4zÞÃÇÓVšôÝâÄÜGôÞb°£®öfœ~™&Š.< ·+Ž…Ã׉¡L2î}©—Ô’ât'~"â‚ø<ðνÈ*p2çú95³¢sþ®!ÑTê¨T`ìR Z5b²Ý¥aãF|4ý˜yÓŽ}Æ0î §.(Õ1CŒ5 çR8âU)ÑZ#Žª~= ?j^õÇ'ï‚ ¸lÿ~öÑúùr?^¦Ý½û(îiwQ=GEÅ.³/Túi_ëãÕ‚¿aÓ’õ6o¡~ÖÙúÛÿ [ÛÇØ¿ÇVȤ㠕>’sÎ<µ¤m¬*¬Ž¢ÒOQñªÐɺ¤Ê…0€ƒêRÛò!§qÐW†/Ä“làdÀRº/44šù[~cºýM“¶k¡\ü—ï °o/ Ðÿ4i+ܪm­AVè㫌‰á|zâ—©=¼â¼_Õ½¬}*(Uqæ*{Š"‹Ùß…ÐŽøaU”KZ–O”žKP06ý6=;â—ž}ö}¯˜¶¯´/ö¡†âDé{a?7ßðÙðÆÖ³–q(D²#Sj ‹ •$ì§¶ê'J¬O ~_A ¾Ð UÌ-·eÎïõóR h:~ïÁ;S•¸åïåËo &>è¡/—Ï îˆƒýâhë;Ìú9Öíhõ0³#Ì0-×h9g—7Ú‘†ÏÝhÔ¡LØ1!ì L´BÍê/˜_ÿã¿ÉY\=êÙϯ^y¹#msZO>” ltϾ6ÿò—¿œ\â÷YxŸÀ-‘Œ«Ì—®÷c§ +ÔßsÒ]X·½õE1`žýeŽÖ<ÍÞÖÇn=Oè$1‚î-£åÔ™zGØÍW¼[Ƈ9…Ù`9Gq¼«Å…†¨K¦ã|¹gŽkJuKŽóܧ§æë÷ê0—î ÖÏŽ(´#Û©Ä…P?q¦Ò£Ð³¾v*÷vïï? MÜÜ‘þ+„*iC©œB@8F"œvg2´¤­p³Ðäa>e¡¼GA¶_uТ ëGTêB\QF\yoÒ0½{.y!‚/?VäÙèÎ{[•Ùç/=·3ÿß8[ƒi:g[šiÖ@«e>ÒÿÔZZÊÛ®w Ð)‰Š+åq¡?´W¡}«ÚÒ…oe>VhX?/qåhUKšk:üÂßéÉ×lMû ~ôæª?zŠða-ƒýÝ2¹ÇÝåÚ쯲$—„§<ö룧ñm`ŠO¤ÍX‰GGpáêËÃÿŸ½7k³#7Ò4OìA檔R­©êRõÿÿ-s;5OwK¥Ñ’Ê…d0ö}Þ÷3˜»ÇaI2L²šˆÀ18‹Á`0VgY”ÿÁü͹ûƒ?Ëc~Ù“ &ıÓW&~ù¥ßn¨‘Ê™õ#´œB×Ì…ò·~ž£_vœÕñZ¶R„”…-Cä‰âõêà•3½‡J·²Ä=!B㾜žM9:äÛ@e¾mè9—ýD†Hèà PÑÎÿë¯Ý³Pò]¼ÝÓ$´Uf|Z†n³Ö¥åøÌܲÞ;¶2£š¥ëíh¸(~ÓÚu›Ì0ésê» -k´ më ×ò8‘{Aø8S™sáœQ˜Âf@fr¤ÏÇjèlÇ € ÀåSòìNw7¨ á‡1ÚV¾P­j@·™PfÊÂfŠäb$ã™–Pæöñ5Ùä}viìn@ôºÜMÖÆ/øÊŠY%ØÞÌËK™Q¸¦Ò¹>î²ö~¦Ä@O!•v Û=R(xÚúÚifPðÊÊN3^•€Â2*è,s7˜ö·ÑºÑ¦flŒ,Åøå0‡°H)Ï;úï?r(>èò›'éÊzYê kþ<¥<Ö%NÝù©$"ÙN­@“ð ˜ó&žâmYÜC *ey½<*ßg é˜S$GGlTÊE?¾wÔ©/Ù3KáÑÂEÚÈWòƒ°é¦¿yJ+ý¹¨‰:<‡W¡mÁŒ¢a¿tË>úè†> Ÿ5a›UŽQÒ*Ù‡Qni2Ñ¡h×t ‘¥¡ÄÖt¸zÊsSü]Âé°²bA9¬¯Ä–G+_,móR’'¯¬Bi!½¤ƒíKþsÀörAf×ús×ÿ¹>×à%íдųÑnØÈ‡o(NAðË_TÈÐ(ÓÉ]¾y½Ð‹—8U(¢Tà–JáyfXqﺵLâ'¼Ë6—l¾äóç~ìç† ¸ÛÛÕ™† ÝE®Â%½Ðå…í"k[*66¦»Î9W‘í˜ú§¿©ðiTµó_ WF´Ò— ²dýÛ.™£~—¿½þK¦õýŸ¿TûÂ×l|³s¥CG§Q¯ìüåX[k[ÑÅLÅ­Çéy¢Çð—Ö/58õí×”õ+¾Ú<ô»{î.´Ì-¼|MSéå¨vM«, )P¾ñN…Ôš^•{B煼ƛ0Fj==jþE»î™Z‘•Äéh*ŒwMyø«­!‹«ö $‡ÀtÚÔ… $ò^FQˆào ¦±-ï’—JÁ, yª…‹á¤[w’¾WèÁÍtìÀ†7=­‘s÷±:ùaýTJ†*ÁÝRõS—»á4PÚ¿ÓèçŽßþý<óƒ!¡´Ji¬!¬K;¨êôuÛ,OÛ9r¥Þp6ÿÈ3Æ7®í­Ú¦_£„‡Ø¯‚ëí–µB:€G[“(ì*åoÏn]¾¾ÇÝ|e¼a‘f©ërÝZ§–ÉAQfTK*Þ‚š»þÙ$šS&á!ò¡Qd“ˆ[ÑFúVGZ *à <–e™±5L‡V{ö8tî—`–Ⴝ.aÕ¦FeP+/½é¯dbórË¿%l~nž·þ´]~±¨r”Š..Û0¿^;wùE¨Ÿïm;Bý¥±ÏBŸõ÷ÔW–ÃP–i…äk¸jOæ icŒcš*4ëZ&Ÿ 'îmÍCû±˜_MÁÔÀ<úwzê´ Ç7®YÏT©„° ׸lÀK¶,&--"ÏÄ.º[3ùg·žŽÔH’¿nF–gLÕnjî€fqë2Ú- “õ ™³×h«³·Ò‹1êÙˆ  !\ÎȬ¾¼a3I8ÉH†U#6}µXýÔ˜5WW0¸Ì¨¤ßG¸¢ñg(mºü’ɬ è {ò6>NqxõCÈâé_ŒáFØ Ö›×þµüÒ²6 ¤¡ Ö]ÇÃl¼Òßióyσ’- Úv°-qkÆÈ0à-ê8ÃÀä)—ï1]Æ.©)«5ºÉ6|á)ñQÀXgÏõóuH7ýyu´ÂÒÝýÙψb›#”Ž,úبåma"ÿXßò”¼ ÿø,”ÄY¡žP~“ŽçìÆöZÓ»æ4€ ¢K2¡G–U¢‚)P±Ã\@‹:•ƒ8ä1xÐp*(Òa:^'f´Á1B4+•+¯RvDš·P§î½qæBAl½+Ø¥¥|±T šG /Ñ¢6°Ò¥­q¤¥ô¢Å|­Wœ ° ·l¦µÝØ^´V»ú½Å*[~ż_ §2S¼.aQfæBñÎÀôsߘ‰¯¸Z—ZqÎI'xKYT£S?uÚÌ ªøƒÿ¶m×ü8˜S'/lº [tónÃ’–n¬A<ê{öÉ£€ø±c>Rå@_ñëLVåSkäÎdÉÏòž´ož^ò³þòµÐòvùåÝ–‰Á Ò#­4Ƹòˆ¼a–Ïgm¿3yÈ%€†­$¸Ìdšúk-‡°è”¬¦üÖËã³eÐêîrŠGóàœÂÇáúÕ+ðââxõÓObÆ5.ÏýsÎ÷ 6‡íñ:®M˜ÊQ“»7‘ "2nŒÌ«<ô­Æ¸l’?áHãT€Û Dçœ4øá§'0x}Ðâé3¿É¾Å´íc˜ÂNÙÆÉ·µŽ,¬p×»âÎÞõÜBZ†÷î{a3…LÙL,†2r™ni›©dfÖ#rv‹Üÿlõô‡'ÐÍ]ÁŒ,³Ç5Ô±ŽE¹œ±°¤iÛ–xt”!žéÿëe¡1†xzEhF }Äa´"q/MMqR®Q–å»W¹ÍC©ðÈ 6B…¡eµ×¹îM¦¸¿†7ìì¨öäØ!k’*BnÎɇ‘œ®K‰­á*\4é®Üõ âbm˜íññ*#ž¾6Ð8~!uÂ+øŸBÈ?v¬ù«”ֵĮõzA“‰üï?˜¯D²Ð}ÂM‡7LË»OÀчç¢UXvùÄ5¡|¢`ù÷ÿ÷@Ÿ¥CŸ“n(/‰<âz¨4º”vxøøÝjÿP|¯W_~QÊk€Á^…`‚¢’<^ü(}(”ÄÐzºŒ±4þêWO:3à }|I÷2^ÎÙ}¥qn僾Wìão ÛõÍq”ª]î°Œ hËm-[ê&)ßýñ½4T²ÝØ^Œïž ãígoÊÑÑoy'vâð9³ft²àÐe»&9JŸ8‹~òö5³mB‹L–̰Øù‰Ë(qO‘øˆUAô½p“ {$…z—6{F<»Ïú¿K]Ö÷W_}•:VYsÄÿäÉ? ½º|Î'„gLJ;\‚¥øè'ÝÁÍìÉXhE"ü þágðZ¨¢/1K™T48>éE!W('ðÔwß?ãºjîçÈž(¿¶çÆcfò󸻆?ï’Ÿ­ëP¹øÇ?þ1°ùÙ5sß5žòsð=ŒehÓaúY^0ma•©fŒtë§ qO–P+/ýô“ß“ñ¢±Ú?`Þ¶ÛqTÚ;½ÎGØügä'ñ×ý‡?üa’÷â¢üŠkә·îþՙё“7ÿ9pƒ°ÁÝÍnô²1Ôå<9Øâóp14\ŸF¨{f+aÉDs(¤*\»\ÐyžðÍiwý»S;_öc¾—ý bVÛ|cZP t7CÈL o²n¡L"ìN¿áŒÇìO™·aµúɰšÏ?·ƒdmÁ³¹á¯n8³ÄÐOÆgÀ)­MlI‚¦ 7’Ø&»àëaúf ÐxÒÐø ãÎ;ß x[cù¥¥éÚ€¤¡ÖÆ«À¾ºªÏu÷zcÊ› £é”‡ü$ÑRv˜ »ˆ¤áù©uib × ™x(Ó‰ñ.ºÓHÝÈâÛB©6k9z`ùÈ¥#É)‚戯‰9 àni¯j½ºöë‡*²Îôzâ,0[X6ÿØ¡ÉCòšV#l#Z˜Ð°òÌ7îxkäËùE€sÉUõà`9-h9DwàðÖ=BµÏ€M:ôrú[õR5àsxD˜‡ñc¾2-qA~Å·¹d&H9ãS»»­ûÎÂÔ q»ü>[nв õW!hº9‚͆ËÌ8 `£±óªåÛ>üßtޤcZmmVÝ´JU2V›AÀác›¬·BÌBsOÛWóPã+¨ˆyÕ·3~éO çþ÷lÀ Õy/sîl’'y}*„ejŽN8ê@H0ÒEÃÓöœa¨BÂ@åóINCyß„ƒ’:mR_ó³ã.Y(ïÚŽ…ÊÃæiåà:?¦ùY|¥Å«ŒõÛF÷2|×QCyÇ0B­ùØ.¥³³Æ'éÓÜç÷®¸Æ¥ñÒ+©õzYI¹Ñp™îuôïŽÙÓ,ÍPGœyÃϼ̿‚Èܺh´j?i뤛Î<+ì½êÊ7G½É3rU~1î—ÛlÀQ‹ÎúµÙ‘Û™5V8ÆÌÌh<…¼£_…ž¶möF š «&au_>–DÓpÕ«¤æU¿ÔF娾¯ŠúÒwÖoÛnDÝ œRÔÖf„ƒøŒ0.¡\ôHÛlR×E“Yh†ˆR‹)¡=Snk¼+ºÅoD™¢Jw••Xø×«wUÚòU?NGÔnâ‘G„~OUך§åÔ*`´ «ŽÝ‰ ;\ ¾†ÒM¡ä{¡ž0ŸAåšS”œåLÞÃÏLþQ `<å¬Âzž5R s×N ôH¬ºðçLÓCþ‘ Ûíô´3E…ÍÀ§ùf™CÕÖÜVÌ{"_˜`æç¯ãù½¡ø·5ˆ'¢Üí¦¿Û[—PtQì¬;ޏ7ÞE£é)h݃Zr×ßKÝS`ºzúζʯìbSemòu“²38.Ç^œ«3^ßÕ|ܼÜ0¼ Z?Úä¬Þì§ë»cµ¼l^1؇ïl[¾ÓOØÏ*KÿŽß銟i^h¹tw{lþòi¿my:¿_ ¾WÀÎ_MLè—þœÊöö2æic%b>©‹f™#hÌ_«¯f£!RIáuYXç¶ÓÞá%J¥ŸëÂÂLïÁ jh嘖}.É•òQÓc~VTëËëh=r)@aí.…¯‚Ø8"㵘îg8 C(¿Ô¢…YwŒm¯M3¡Ð†ç§RÏ9w}íQE¿#жŽÀD9ª%cÅ®,üŪÅhxÆ–Ï~¼.ß~Ïð%À Kû’`oå-®6`›wx³`ßìV¹Ò¨)ž3n€ÜÊ.r0%¼þ¡ÑðZ‚®‹ÐäÓ~Fg•€ããgQ¶6½n°$ÇŽKÑÉ ²RSä*ìÌ·Qx—k"àSúxXÚmc…¶7T6{»¤kÿ'Ü¡#ÑÌÈ×^¦ÔëþNýßÇÏ*=òov=Íå-ŒÞå¯i/‚î¤mÚn+Žú}–'ä•ðÆ=ˆ„>cÖB·ñmŸÂ.OÃ{¢^ïMét³VêÙ7¹°)mìÂr…‡[¿·7´ÑapÙÖ}Ò3îjŽÔ‚Û£ÃwKÁ±Ï¦D™~—Q´Öé~øp^EêÆ$;s•5rZ»G°<ѽ vÜÜoà­ZÅdÕXK¼Š Â0eVb–†ÌYJCíðÒ<"Ü·ÀO\A¥AÁøÉþÎ|¤³ÆÎ¿\y|ËŸNÁ´Êíïìû–ÉÞ­°£¯¶÷@t”Ó±ÒÚ⥈@;—¸!¡8µ5ùÒ yá@¹;kž|¥ VÆÍ€¦•>"žz['>(¬Ý$¥Òèæ(­n;;5;Ѳ]…‘Ó²)@î³¾Ó*T^W°H³ÙnÅ Ò«¨‘²S&Ÿt§º±òŒ°B.¸5¾œA=,~Çë)Í~Uéñ‡°Ü, ä fÜ«ÿm iI7iÝÂßgýSÀ¹¬úvù§ü‚o=ezŸ@¶Ó€]¿OÃ'ô¬—#¢àŽé;Æü2m5|¤|¨ã¤Îª¸„‘N™h)—£¢*A’ô¬¬Fº‚Q¾9‡òšr6-# µ”ùu`áêð²›Zµ.–‚S¼l`é*6/7l?ùÚ_軦Õ>¬YæcÞ¿Pz‹—al¿MÉç8óÓéXñu7oõû¼üˆÞ›f‡¹Ï9úwvvs0 x’µÍš}ÝJbËØjg2Üæ «2/Ýx-qwc7ÑÓLª¥ŒÑ >#Žký~½ïs–&v8jã À ž™€,plë ×YÕ~½˜ç™©hâoÒ`ýüéÅÅÌQ›u,ÓÖ†Çýh‡ÇšDÀÇ´2Ë"6Á¥Ç`›Þg dq–BŠN™âԈ؎e›O¨ÞÜ8mî44ñ!HÜsÖÍÌ¡£¹V¦Äsd§·Äô“ Á“¸cIÍ0ZßÇê6LÛ¹x¾¹±ÜÚn´Î•°©ý×Qz [{Ufýnp_´Œ&­{׺4èZèòëS@-”ÆHº+MÞŽuW;ws뻣ÏN™ ð wHxbA¾ÿŽÂîðþ×:’襦a´-°’ýÏüX¯ŽfbNk^b¯QB].‰õRl¥¥…/!HÍÍ)â jêþÉ)¶4Á…!äx6’ü+ÄHq—¤$™¸…o9%áng°j´5óP%<×yó@¥öæ¿ÆïŽèúº: Ø–{î ¦Oº‹Î(p>¥Hü¤}"0ªèÝùn†É1Èjø)iZþ$Ó¤!îé“›öXU±uð39Î@fö>rÍ=3I®ÿ“¨²‰'/‚‰—?VK‰’ÔBù׫9ÓŽäÌÂô(<]Ȳ(Ëmž÷׺ÜVtcb̽%cÔß¼Ú#|Gýò³ÏZë í/­Óù·s•¼¨¸Ý‰ëWüYå×}Ÿ™eQ)‘–I¿ÿJæÁ€YÓªO[>ýéïœûÿ1ëå|¬“AùøKË)oÎÇÊ Ö¤¶‚Ã&šÑ…;ŒOèâVŠ~‘Oãe:z;ÄÌ{ù=†J÷÷ù¿~Ë:þgLQ*ÜX"F !…Ç>Çk£Œxp­äîOa™È©ÞîNùdo˜ŠF´µåö¥UšÆ&—‘)2•ÏÚŠCš*å,ñ ù7¾Îq¥É‘} öbX…»_ƒ3}ieØ\— L¬“Ç#DÁÁh‘Îæn6"$,c6Þ.Ö$²LŒKˆÊž ÊfÚWŒv¯¹jõÚ»í# ’Ä”ÆHê­@è )ã±°³Õc6Þ\pÏý5×Úno³‘‡:†âšz’^X…f¸ÁqHO}|kãu׳뢀”« šºI÷B ºŽ×Š\vmro÷4páÏ“ƒKÖMݼ¥éúf-9í¬Pt¾…£Sý®ñ õsªÔ5Ea ¡ôþ9£Ðrýòˆo'Øù{¶÷ÞŸ±~{Á7\C¾a/eÞÞ†¦ðLÓxú¥¨Ä¯ü²ñKšùš 04ƒ¾Îrż±ñóAúVH Âð\b…'¥™#ÊÌ–°`Són83uÝÊ‘õÞeom®¯cŒ'íTªŠüŒö´õ{^\›x«¬ð/tnÐp»XêOñg ³æïŒ 4\VI)JRƒ?ÊÌÛısv³£2†æ˜¦gZÃv§"¾ÊÆ£C¯ö–޹;>BÞ®1ÛHiXûwÊ™½!”É €*Pî‰ÊŒ"9j\ŽÐˆ_ðDið“éfhž&-ÔÃçÄÄs‹‡ ÚÓ8{ ª›YøþdõÃf{´Õå87ÑÕÌ•´õÜ+®ò­÷ åg—³Üã"l~^Öix?ÒX™ÒF·xuŸ¤ÿË:ß5/.á¯Yqz׿Á€FXB;µu~î Às„›–¼¹Œiõ-„¦£&™\CÈbÔ‰{›…}öM¸âpœÓk$î©CMX<:NœÄ7<-ÓŽýÑ#oYWAâ¿Õ0 ¹æ·•‹c*t<›œÅYÞ2²¿b/ƒÇcÌ×v'¿!ûƒƒgö3BŠ“hЇLè ÖÔʘFݲUÏA;SøëEd¯8Ösû›0VáŽPQ@i¦ÑB—?žyµø©°í1¢öã„k’¸GÀ ÷2é)Ò[8ldZ¤¼’Î: Ö‘4"r‹oCtc¼? iiyЦì oüôÉæ7‰k 1ˆ8H( G¡ ¶‰pÉ…®µ£¦kí€ýÐNÏT´:Î(lvpŽŒ„ O…¥¶©îT–ûuLµ'—9:]Ëžà•çÇÙÅíÞ? Utdô -ýðË3™w&ðW d3M©7¸+d 5C<^Já‚ÞøËóÖ‘imÐa™WïaYŸ^u¤¬Fç¯[öd}ÏùJs¡²FÚKWmí°6îbŽÖ·eðë׃é§Íý òfeè=K#wù§wi—a—îª?fpXõÃ:ŒÁ©»Ò¨UØeeƒ2ÑË®¼AP½íqd—äzB Ä%ÿê}~矮cËð yGS¦Üò¼Ì ÀÉ©{œ±qVMû»Ò™ˆVÖš§››§õ—î]KzÏX¼?×2ÿ⃪«×Å`ß8ëϯ›Î‡î½)@æóâ”+ ;l¸¥s¬ÙÁì6RX†”Aó'ÓßmsyÛ?ËêÔmãÓ$Ú"ÞÂYhÑv2jŸ €"ï«ï\h4É€°xÙ}7Õó|K«µf„Iƪ#…ŠØÌ1 ^Ýh+4¿kòÿ–‘KóB°1"Ëòˆž/G2xŒ$;á†fÕïF2oLÚ”ýO<9£%Chbk¿Iú÷„µ0/;,m¦°õÃêŽTŽd)è'Û&94ü̇)LUœž1y½pû¼ô«Š®täGδÄB ú8@ªBEa䢰Z…a ÄŽ­ È{Ú;Ðxm º=u›’'%¸dÓZ\™e3D87ù$h\÷ÿÌ¥ºûþeñú\¹íÄ0™•‚^1“WÓ^ºNlƒ0¼åW87¤ßº½›ûËŸL#ü3è_ûyhe#ÍTícœ‘Àñjʤià;ÝÂ̱öã H‡¤Rd2ŸE ´sÛ p›Ix‰·B~’'•§1ƒ(^¾¼â.®¢2™< ?ÀA§ŸüµŽ®ÜËÂÚ¿ßq6¨Ú·udý”R+ÏÊÓòs»…ÖaCë!8O~ñúdf <¨`Cl[£µÌZ;õZÐ-Gáa*…»Ú®ç§²NQÂÌÆUTMlÜ n/oÃu‹Ì.æŽk‰Ÿæ-y¶!áS‰Ûž²±bª¼ò¢ɸ„Mà䆻!Q“Ø s0ºÂ6£ùÑP“‚ M2˜‡HL^ÉÃþ;yÕ«»¦|ÀÆo Ld<”øñ§|¸ëOüð¶ì4ì<¨F s"â51ñ¹0Š+Báh¹%•5\Û9•·u5=¿â“{Ó™ºŽ2à³…Ãß`˜©|\6êЀòY_MhJÀ¥aîëD¿¢AE£œmxåÛÐ(-½8*·ÿù¡–B.Y3¾7w¶«Ànû!g´ÆÍ‘vö=:ZŽ–ô×¾­ Û”Çÿœþ÷ö8—LhBg)T{'ä ` «”]¸-\;>µˆ”Êݲùr›(a\IØ0¥tÔ¬–yú¹h×”½KÞe — nE¯îHìLÙÖ§—/©»K†½¹ð&´g)–©¿¹ÛúPÀh| šGœ;>ß?[]ÁY’Ù< yxMGIŽ:\§ÅC|‡‚fù«¡Ä\§†KኞY¬À‰1XaÄ¥^íLã–º~ä§Qý>:礟Ÿ±në€ûVÀøùgÜÎ^ïGwmÔsнFê™i¿Ñ—‘8Zz[%@…ì’½ÏøŽÆáá3Ü(—Ï¡ëð[œÕFÑuƒ«{l¬¿”+¯…-þ•Q˜šß(£œÓKH–;J—<êð#-&+xÙ¶œ¡Ùæþ†Ìš¡à{“ݳç‡Üp˜ceÏŸ£°œQGì•€SIÊ«cëØ˜Ð½Þ¯•.*Lv2=;°Èö^§8HSùHåH^ ¨8ú f4ÃXzÛ‹ÿ T‘Nh?B­<è_Œd[3¦a{ „÷¤±X —QætÁ‡d•ǧ?r‹¤yAûSøî’÷ ›¢Ì…ÂÚß «ªÑÏ„Ä׌tšmËÜŠË©Iþ¶mÂ+î\’å²±+ŽÖú±Ÿç‡Ç«C>]}Ķ„sŽþÉ»ì1Úæ3Ä~¿ÂÍ~}lÕNßúòna+oÖ›u`ŸÌ‡OU,¾¶­Ó]5åå5À*5Êó¢”(„½´ÃÆÐ³“¾™IF—ÉûÙŽ^w3¼Í/tëâ6¥üm8vVÕ""ÖY÷ÁiHy6#¿lþ¡•Oÿœ Ž ¨piŠ_:$üm°“™Ýºl°í#–¹›»Ãæ…:„ú%Ð|L@(ð„3K1S00F™üË‘2M~¼]ðæíÖF{ô/Ôš/c§D~‘Ca¯ñýæò†û-ÕÖ´v•1´¶‚b¥BrI« §Ä[”[¿…QÎè[–DJˆªËê$±\å%,nÄÒúQ™ùÜÿ˜µXì”V(vG¦À\ÎØ9uÇ6ñó¯ŸwÂëcÀ«c/I®èp%Ÿ°tòöJ;ñê:Å\&*¢dºÜMŸ¡Aª‹df)4™~hHZä˜ü]ª’®ÒÉKejS™›ïÛ–Ê›Sɵ?¢;‘†Ö¿4’>¯K£;Cj”âµÕ;–‡f™pÃcÉ3‚EŸŠ©ÛÊØùk„õWo; 5ÿ6^"døkêMžÝ‚^\ä´Åå^®û{ÉÕNŽ$WÞIÏrøga4âh{úL éNŸ1QüÊ™_KäŸy[ðÌh±÷ £xÛ“c ƒ ªPµíºÊÏò·¼í³uÕÿ„ã"ïOή¼Xd;wíB£ ¦¯‡„õ¾BvïÒPÅDzsr`b'ø4éÓz\=ú¦¬z§G…Ìóâ½é>Œ—åî­—n§”Gs N£©;&éôÃ=Ðð³Yºgߥk ‚WåÊm˜F­½LB·0&‘ùI€üd*Yñ#Ž—ÌøMy­‹‘ÅÉÄ-{w, —ôÑý¦fâ•‘þ@nN&ÈñØp*ø­”Û²kߨtº _–íGÆñø]Žñzüçm:ô#x#³qAd™˜nŒ¸‰cf8_ ˆB ÈŠ—=åã)(¯±¶î\‚sÆÁzhe¬ù¶ëKÿå»×ÊøS †ª´°êÎB^†Ÿ`ƨ<¨aºö¯ÆÝZ·Wê4SGXÈ¥¥ð‚N'óÓÑ_ÓÁ©4¤Ñ(€ºT-Ê dF‡îs ‡‚õ~¤7 ò-é$mæ£[6’¶1º‡óeàŽ€'z0è&r%?Eošé7™-ƒëî<:Uü(#µØAÛŽÔi%È‚nõ<òlz88 hçŸÏ³IÈKBÜ(ÔIŒ,`‰ºT ㉔ò]S,ž¯øépÂrgW»£, *_åË®gc=Ã%'^;“Þ[,G´À´ãwdä(Iès Ë ¯@æ…WÖ…[X›ÿ¼PËõožäÓÀ|YÏuã-¦ÓΕÙà4M¢†å;û÷³°Š^Q,z¿‹¿å¼pÂ,ðÔßûìØêtB­ûŸ…^Ž2KY¬“Žìg¨Úf'Ü’~Ò}Ññf.iW¶ðNú&AÊŠLûº ”9&\³h@IDAT“¢h6°…¡ÔÓÓÒ=y¾ÂÑõ Õ‚S”¶|‚œ— ÜafÔ‰(—xÜ›l£ÒÐhV£ŒÛWÖSŠA'…–å½ÚÛ¬kÿ·ìþ¯8ÎÐÖ,Ì:O7?¯+ﺾî-ç'ÏwFU–XÊt*ôöùìåc4L4ÍÏÕ»žÇW ªnnpœ îóÏ©±K6õ…iMŒ†‰Îè£Ó×9· ,¯íEFH…jj“xªhä¥ àðÔ_ ÀDÈs$èaüú~ à(Ç•d’fäÕéûlP…¦§Û#€âÁ»E~‰ï:%‘FÔö tÚI@~ÏÜÁ§X%/Ê›£k<ª½ç{ßÀÂô‹^)Êèćwö8L ÁÚÄ&!ænÏéôO¸ôæøØ+CýrÙ¢üàPÅsí»2#½$Þi7$8Súdh‡\Ĩw©o,fZáÆ‹òæ·Sb?™‘KY®“>yö :\†Þ(Á™K?åç¡çsÑ®g»æït©{z)@Á©‘ï_ÏXÜ?pæ§bkóßÑß!xö·Õ³§ÿ =]°~¼³úÃï~hRÌ-´ûèÄ’ViÍwvÕ¥]øNTó%&Äž ¤ŠâžwüÀPîõžYL~òÓ³Õ?>eÙ£“\[¼ú%Å«TQ†Òîç)~ÛI+F ;é·…]Z¡¬áá5kîn†6¡y«,Y/ÙÀ_hÃÏÔ^IÃ=Dmââ½Ð°¶CË^ FÁif¾”Ÿ ÓK—´SFµÛßÿrõùcvÙ3HÊz?=xö©˜4üçÒ[ JðШœšœ$"ŽÄ¹|ª£îùÍ8„ðsâGÇ^ý{š=‡G*µÊa¯Sv ɪ}ÉOñ¯{´òqCÝ*¶]Ëì>¹?l <¸p·1”;srw—½â³Dh1sÚÇàà;›ædl?~3:]B:UaèlãÒ5Z„É9Ê ¯á÷²J*^ûðV(ð¿ < ÍŠÔ wk°ûð4¬¸/Ó\¸uªÌ^½š?g¢kz"lž„#Òr€b×!2€„vDÌKµÝI‡gÉ&ÄNLh›7„Q1XÈè¿f|?2N¨_ãÇü‡v÷³øLÔz ä:¬ë¿ ™B>ry'7·ñ¥4w´GÂ/¹VžÓ¥ Äå €³=ð6[ª˜;ÿº…Ðõ<à™ÿ››ÇYØGp{ñÕë'®[é›ÈÔ”q‹º$—ïôÓ—¯â ¿tæsm”Khò#¯±é×c‰Zé›:©ŒØ]*©MyÉ«ó3Ë‘~ÃJù]ýÚ)ƒ?UtqqÐPòÁ¦MÂÌ’p™á1’FÜ̳eÁcy?DËËŸûÓwˆá¾ ³söˆ%#g‹øž>‘ 1(¬.<¿`’¾Aò…·å-+÷¦zÃMÌBAÃí¦åÏÿ»{ðv>Ú×üܰyÙç(MC¡½#ï^Dá“ÏF÷ªÈðL´ò pÝè?ø—ħb}ßl¤CªˆÝ»I$?ÂvwñžÝl×Êva^ñ{ã}óã Çäª<™›bÐ}†‚¡„¾AâWʦeb>Îx5îy=ÞwôÊ­Ë>Ç1¬ñ–qõÓ´ÿ”«…Ó¾Ä$¯)ðèÌ¥.‘7ÊK2v&näÒê®ú1¶/ÉèóžŠ<ðZntk6Fú!.á=/KqÔ_wÿÊ‘õêš~­ëÛÁ·PT@.…dñÈËrë\ï‡*`×}ÿ ›·ü8’HÛÎW\ÄÚ}Âî<Ê//ò³þ<¿)×úû óá?t&}ø¬Ö‘éT\óÏ&ɺb6+&±T”Ü<ë@%ÿVŒ,ƒî_B«õrô³(,mç1AQ¶ã¼ 6}:Í;a›XËÛ/;–Jv½€4ÐZÈTe\™ {'úxsx!œéaõŸÞ‘¤GýÓža!aˆcÃb‹§g¾~?ö“ùø(ð€ @1l:ŸÑ 9žÍ÷µ7]éGëeãË-¶õÛÀæP¢›‚~ÝÚù{Wwº©ÁoÈžG7ߦ CýËÅqÏÕ"SëͦÀÆÆ¶™O†šs™¹òŒ÷ ª¹>â;âSxÙjIÌT³ä`Ô‘G á3i÷iÓ>Ìä|1JN˜Ð0èèígy®‡ˆŒ $njUŠR6#`Ð1¼Sõ:~¡7^üÜHÐñ^ äÑ‘‘ÖQe[;ÿeg×B{ðƒ:›L¡{¨# [‰Á£ëàeXq9aTÁFªÆ…¡¯#[=bÝùï§ms€‘’3LÕaÕú¾Ç¥µmÙJ@óÞËPz™¿Ê‡˜:>>`D}Êì_lã8­ëÆ»¬ûkv¹1‘-ø”φ͋ÔfW1ŠÝP°“?uÑ•©”YÎ(ŧ_ŒËÎ'|ÍŽµ!Gþgg|%ë×䮜V¦Éך)J­¨¬Ó§;ÿV‚;ŠFómžG½W†ò€a:íB¿FgnMã%L8h’Z“´‰ŸÔÑ™`ùuˆ9+³¬ì‰$¼Ï©Š|çøwò›½ãW—PUjµÊŠæç‚ÎbÍ3Y®û¯×WÓn-éO LÃ`œ5½Že´Â4åÿ6›•n¹ÒR7¬Ç'CùpN®¤´£ªNÅŽ*SŠ]¡ ÑÀ hµ+8Ûãaø$oÎ*wËi8*`n¤kcs”f˜n‹‘[Œ^8Ĺã˜_– 0òO¹|ÆDSw$CZâmš®¹wÚÆÉ ßˆkœžR/7¿D3MM’À-Ä7VúÄmZx¹ä¡6Žq—u-ƒ”¿—õDËÉŒsÔú$G¢â˜=º}â²Í…>Û¡»öW£zò½kèú¹4qÉ¥?ßÿè÷ä½KþbõôéÙêéó[öð=yØxggõÅçÞÕï±±=ö*ÌôòŒ¹´r=Y«ÕJÂÛÐk ¨r¯C‹`±üʧwÌyÌœeûJYg‚”, 'vÒE¯’uÒ™œ†ù)r‚„„mtš§_•]ó÷³â6äí ‰Iøí\Z¶LgvÐMÕwÌâÑW>Æ ½p휽§'Þ€r‹²æ7,<>JJÙ·"O÷Ç~äíå= ˵ÿ™~wrÿôðSàÁ€©ÜNÙc½oÐ9ù=û ¾ÐfçÂn5`Z§±ë‚C£À¨NS•üBcuøÉƒ ^çgctÂSžÃA´l¢6çÛ ýÓ#ißÖ8Ììƒ|²:—Í#^Ù„Óam•š„©SfS‡jñ¡3jOº®œòC†8gTôt®TŒ–ï«wºü„‰’-ðã¹’;¸ºäeäa¹iäŽ<‚óȃEšAk…ÞW|8¦„¶'jzÀŠËʱ´.=0w¨a¸.¢âÎŒÅ÷Ú ù.¦ˆœDt&-(¬´òªß3fNNNsñÏ —Ë\ðѨË|&Ù™ù£øD^‘g¤KÓ¨;|ßµ9? ¯Í«h$_‡xÉqQàÆ`©@I?é:`Ѻi^PþZÚNFXþâP¶åH‡i²7ÔÚ¿“ø$ÎË–_æ¯{YׯM=³t‹z}ÒºgLËz1dµiëFÛ ì§ió_Ç<¨P ©%Ηb—U“°.Œ+ǾÂV¬`¸ZÎæÑFÕÞf<’~Ú6-Ü#ˆ6¯UH ?t’‘d'ÒS¢…ßè` CøÎK˜ÆkCFªhÔ}Rn©Q‚ÕÍ”Ÿa¦, 3¢ ®¬á ÍŸ¤³ö,tT§À½<÷rßáIÙ¼ªWhls,Se¯k:Š(* ½åL ú#;**¹<Ë F·ƒsîá8u蔡B²f –‚Kw î¥2ÐÂi òö ‹²ž‚þ‹w çzÈ<]êU‡m¨ï T‘Ÿ§k¯ºKç& ¨!tÀ;<0—Ûçîè»s“&ËŽíMè!¯W»¡žÇ¦:ûÅrmìŽê)È{vÜ3ã¡?ÏöQ“Bm…^8'ïWù-i#}T²ŠàÅÅù.‚7Fº‰ìÜévGz @eÉ%Ï•ûQ;;˜y]yVÄ]Ú4lÚšçCš¹43™–ô€Õï˜~×0Ê‘ÃJ{íЋîÄõÁúÒ¶éοaû¿ .¢¦&ߨôóËa…Tl,íŒßÌ×Í¿ÍÓ­øü&üür\>½ùµ(ðà €çK½eÊ/•éöS¤ögéÍp‡ùF+Óí”d+ @ÒN±ØUÑÓÝ'0­4èÓèHVµl$É þ•¶x˜nò姦ÓMÝ´18+>a|ÆNqÄO¯MŽ2}.V0ñxcváçyÒuš¶ßŽdù›×ï…v*–C«Ð½]2ÂÊ·‚Ÿ~µ`þeª4IDwrÖôíW!3‚õÈ‘„FH_ßúµÁ$ŸŸ@¶í0œUßáqçU¿7þä¶ ¹u/¿ev.Ž-;Ïͧ\û«Ré¾ß3åý[òȺ{I«VÌöÝ жSíSô´£…^÷24>¡ï(ÞÀÄCp‰¥§üq¥½·2c,>S8âÖê®0†ÃŒlÝú¹'O[ƒy·Éw?ƃ¾æÝo§¨í*Ö_éã_“¤p5^)®Ö£ÿ®'O³,ïµˆÜ Oæã¤Àƒ)2å5þ߸ö¬«k–g|àŠ+Ÿ*‡i]ÁœWL¥ÒíÐh`CF[NI åɉqÓÃB`¸×©h¹6ã^“+tñt/ÃÜàV\è5ýàųçY³D ŸD°‹o˜™¸3S‹Dš]儆€OúèLƒƒ?4œÆÛ4;ÿ¼i:×NŸ×¼·Ãöí0”¯ŒÍÒ¡¦ Š<¢szÝrTÇNø†VnC ¤£òh"¡?þÇÍ¿²ºI¦mî¹ÿò ¦aýä±åÈ’ëÉÀŠ€`"¬Ã]ïÏŸ³®ûŒûËOœÑážp®*ýê+×s#ösÞÝ3ï®ö¹w…‡SºìUÆŸû­¼3-ÓS3D„bÍäÈÞð3È’´zKÇ¥Ÿ#ú2Ö;)#…[¨:ÛqtrNg塚sÎóŠûÛ· Ç&maÝŸ5í=Êßwÿ÷¶Pôu© Pi𺚊°ÿßÿþg:Õ#€ÖjX=ÿÏÕÅé |ÅÒwìýaõØsØö ÐEî»qÁ=ÎI—e^–ž½ÆðL3AqO„Ç+䣂Â5ÄB¯üýñÉsö(üè‰ËË-ÚÚg„‡Ç²¶Ìú>ßvðÞ;×–µKZµõvüRè¿ê×NviÓ\l;”©Ü´ïjBxB«*씤Ja›j“Ê­a ï·:ä ´';uxt;²Â¶Ú™l…ÙF!÷X´û7ÑãïNQ8h1ù%^c`RºG’ V¸ËMõàÄž-F¨¼H9;} |_¾¸Õ‡~ú ë¨Ýý- ëÈúºƒo2þôó±PàÁYÓΨ¯u„ kvØ=2V£FðUv›ËmüçÑ©ûr^*§ñÒ |ÍUÿú·™ÜŽ’‹T¥œ²N™›ÊZÏž1º«Ýlì6ÔõFßIÙÂÒøLÓš~âð¬oÍ÷iŒ–q„A§? Q×b2Rÿ|©9íÎf/ ŠD€¾<‡ ݹ{rZ»x»˜Á±Ð«bŒât±vw™ÖÇϾÓMG|Ä&›¢È0BÛüŒrÁ2œ —Ð[ÿ {nزQØý/G -Ä&vxÝñQÒ"±×6VXn9 ŸÊebåS\¡ï oî¨íÝh©šJÚ„:©8ÝyÝï£mÏ8ú—žÕ¶>»¼÷AËÞöu;3—gùŸð±–££çä¼:?eàÒ€#êH%Ù lvÔ›šåÊ)⦈)œ‰¥8/þPî}Yþe(ýÛê¿ Gš¶Õ\EÌ%DNýŸÓ¶Ž™8>räJ"aèmjÝßôÔz&ïƒM+a²|#~I”Wüt–…2øL I;RYHš ׂ)œËt¦`j:´q~[6ÈïmmHABOÛ¡E5â<›¤ã+³ï É­ëÚº~D d6uN1¦¤’¤xëÓi›à(Ÿv»-… n³ÔÝ÷Yè¶Ž¦²%­O?N€Ó ŠêØÇè¹ù3Ô Çâ*6Ô«_‡ÑG£)7£ÞÄ?§CG·EØàB'ê9度Թ ¨¸ÑÍë]í`çŽæŠ_"äÃt¸™å-¸Ñx˜ÃšŒF°®¤ùgÏA…GJN B’ò§RÈx8ç]â)à„iÕÌ€† ÀÏu„Ç8÷˜Ê*(:òqÆ¡G@~ÂÖ¯y3Z­AÒ™l]â³!$×û ŸŸ»n¹,„³ X îv¿I‡wæoì%Í-¸ríÿȚ3d¢~qi¦¼Ti Ï]ã¶~aç¢)Ë/-0[hvù—òå‚2X ù ×üu¸ºòH]Íž ¯™ rí;Á‰«KÖ‡ÀA¾ßtGqò3§Ý>¯ _ ‡—|NÚÙƒ’{ êãHç´§Ü‘ceÐOZI}p«µi5+DÒg©45½^Ç· g¹–V -íô0—–¦éÒ~7‰âé@¥/ä‡Xßu¤óÌˉ7¤ÓZ˜9Vñ£¯Í³ÍRÞL¸/8Ú×LéZ)šTN—n*ÅÀwÆi·Åµý&¼+ÅO¿!N˜ˆÑÌ5ON´EÈ’áÊV{Ó\ð‚Á¦w>iüµSÂ"ùj”\ÉÐ}¦Ó7„¶âV,„'”Ú¹r—æz¹ëò×Þgϱ—¦t9®Œà%²ñGÔ‘qyú;ÐO¿7|ÕøÍ/š?ñRR~&ÚÔà:ÒH¨^¦C1B|×òN'Ë(/m•GSçÛú]sÝʯ*v6#—{AÍ"xCœ´4ÈÓ̵ž­ õQB ÞKgƒ$” éTáèwm †¥PxÞ´léû)ÂÛMõh<^êJ…U¼G²»54WQ³ÆígwÝ„wÅ.|Sr™ÁýÝá7´3ë“°GIÒÁ0/ L•9ÏÎR7SéçÇŽ¬ù?%o?ŸíLÐK 'Üþ>½]í1î ŒõPÜ?\eRðá¶ê|.Íz˜Å»-™@ÀOü3΃<äe?Ǭ÷{/K$Ç\%ë‰ëkyÔr¹?†r `,õL‘°×“{™D¿¦Ó…‡sRîì’)(Síù¨ºI,´=¬p˜¢zWR¿Mª‚¡6Šñ…}Doɹ÷ƒ—Ù—“6XÙu– M_œ‚¯=ü©ÿ¸KŽå…/ƒcý³L°ý^×—ÁWDýôê# À+tZ¶žp²Ì5² ®óMçiq4ƒŒpTšѨ;†eá’=N3ñ`:4FÓËõÀÐ?àT xð.Òö.|ß9š»ApYÀôW|ãú‚ŽßéÉSÖÎŽnWÿ'ë¼|ÿÚ)]MÖÐS;iÇܦ®ÔÍ„ååo÷% Å£œ¾åýZB#`ûŠw™öრsËõœe Xó4¶5“ ý:nѨ£›¶óªDq8ß’¯°o•_á]ˆÌþÒÆ{ÉwÝø¶ÅGg¼ ;=ørÝ»…½Â_ÁþVFôÚŠ•õG”A…óxÀ»útwðÊoÊ2…‘Œ­‡%d´"ÔÂHl±ì%×¶Ožbë\ûK Ø ŽýY¿“îÞ‡ZÃ~”»þ{T:x÷¿P:¨$Ï&(v’^çë¨ßÎß=2ÿüþÏŽø/.VÏŸý)š£ãß\ý·o¿þ&#ï´Øa@€QF’Ïô³àý¢ O/¥Ï9µê°}O:–qkQw¶½Ì‚ïKÎ÷Ÿ¬þò·à¡C”ÃKÚß’?¤íQâsGÂþ>KJ@/H’žõoºH«ßýîwY[–FZiù‹øeQ¶rJÙg¿ïɨòÚnj†«ø#ñô“On"»ŠÆ¶u÷Ët›Ony2>ãÏ3YíZÓöâ3«Gw=Ã<ûÇ*ʱ®ÊuHe¾ÀéÝýãýþã!iõ1å€úŒì%›£vNhІ£Ldª<@Z‰m(o¼u›î >Á_Ý›< "ÍaÓÑm@Ø«áæ9‚="ªGq0ªaŽäô9n•ˆbxi$KªÉ%qªH†±³ ¸Jƒ¶g_Q š´F”$¦;‰V2w~óndî‹Êb ¿öh‰ ¢*³þ~xO ð ¾Ý «L¦‚а›R´S1ÕûB§ÂV˜D‹%Þ:£PæÅtžw·á»®‹hÃ]B«qS@(À{Ä7Ѥúîx6®ò°úêVXZîú`îÐv†ÎhHÁH*Uõ7ŒÊWï^ÐI»\ähÔJp&d„cmr´ÌKe¨ép¿°,¼TL×e)ó9>:`VêÅÀã~l e@舅±¿ÿ[6ÒíÑY8ëƒrË~:b†±7jh<ê•gý4íß°Ãö{‚8Ð ‘É^ šªh¹'â„ɲÁÀý(—çlR½r–Ée 6ˆ­MùwGߣÿ†úK»â­Aô~(Oñé“ej~‰ôá]ÈÁϛ̀UxýÛCh2å.wCýÓVŒMÓ.â·Ù†°%ëî¦irm¬¦à+Oëö·Zñ ö‰"_ËûS¶ƒ74«ÐºÑ´_»ãùé磤Àƒ)ÅŒÐd8‘OÃ+Li€=eü4˜ÙC ,c ¶íHÄñ^ÐêwÜ œ5û)‰áLÆ lyÉäËvbƒ{©éW ¸t¯=ö«†÷×k2â!]Ÿšê…b!R½sM5´±m¼Ê¤3ì|´=ë‘“<—a–iw‡¯Ò¡u÷²ï• Zœñï¯Æ«ðù%Ä!ÁŠfŽø}[!ò»à­<ƒs½-Lëú޲ÒA_9d„›2SÝ¥}—µGIÝé÷³ô™iè4¿ VuþŽú]^:åqA§ïš¿óþ7õcä¿™ã˜*·Ùì·íÑKòv6Ãuøà<—×_eÖßwyËŸ_Vd¬v Õ©8[àf^iâWÿÜùÎíç̨iíüÅ)ÇHQNB'ŦÅR9l:-¡ïgZ½ªïîåo4|“Ô%“&ÀŸA·‚Ô}è×)7L”ŸýIh~daݶKÅQ·SÈž¤‘’aîÈNßë+M ˜¦ÑžËú}2¯Egïf³NÄnûƒIpé–]î>Ïi½׃)¯ƒ~ÚKw@É%¡iØD5E„`Öâå‹4À…oü–?¾³1"7±BÄyüƳñ ¬ÓZótµ Í ZvˆË4ÚÝy ›Q˜ŸÅ·GMí×8'ÐÚO—£aMA»R% :¥¥{=I¿ÃÕ©B¯Öí -ƒ7¬8^â¶Ä{ •wöØ#"À3ÐnVÌå4°MñÓÝrz` Oh„á»ñÒîΩT;× :¶ Ž´ /YBªÑ¶e+`ý€áöˆÖô‹¶âÆ4?Gb…5íÁhÿÏì/@8;=rÆŸ“·ÐÒi–\ù«`ír•nèš9 ±N 4'Í¢½,ƒÔK5îÙøÞ­PCź©P¨—ÖkºÝ÷êÌ’›e=5#´óþü„3ÿŒüO¼'‚M¢¬ÿû™oU÷I¨ììÎ7É9Ú—. ›Fò°|ý>ywi-v›”™—KÝ¡gl(FbÆõ¸ªäæÓºe,Ol ›yé¡mcig*oòœUÖÕÖ/ý²|:©¨×—íµ¢¤v˜eôö[¾' m$ížtLkØeØOîWSÀ6l»-%@Ê[Ÿ®%W-ÈÿÅÓaüåe ¿òZÚI¸ÿ÷o\(²It÷g@-r.a-y‡Æ¯À°Q\ÁìuÜÏÐvÙ@DJ:žL{á§ v‰Wã‚Úš±ýi’÷¼í•Ç¥.÷7¸»}Ø g§ÓwXƒü<ÐÊëN1´’ùUeª™F·ç¨—~ý.‚im—¡ahͨÖo;ý¬û 5.øWZBÖ5·é€n‚Ûg*úË/o€Wõ+p¹†~Þ!¾ ÷‘Ú æ¨·ó×71C¾’gÕaN P›nÒƒUÒøT­ßìJgD*$Ãø)Í‹+*tmñ·à)Gñ„èÆx›i~Òõø÷£?;¸Xýô”‹m˜â>?ç¢ïÿWI¤#Ûu¿¾n=ô_ýu::;5ëCz:ÍÆ™ù~øKà•Ë í{ò”sý@¿ìg©6W^¬ãR4þâ ùñ VxÚín>¢Aa…Ýš‚LžòTiã“@¸6Ë 3ý¦&C4qõH¡ÐFwÍ ”‹ó£@/BzÎTÿÿû§ïϼCþôzõÝwlºvîfÔ«+ꜥ¡(FÐçÑ£Úa§ïúÿo~ó›@÷Fx·¼~Ò®iÕüÛøþR(5Úö4|]`eGo½ÏÂYÛd™1Ì&ä¡ÜbXô“w˜Øˆ1My+´r ߸ÔÙ¶W3ãöýîm.ÒÚÜD™Ë{•íRþ\"‘/”=eåGò6+¬U¦r{íGzäI—£x>g¦ø»Ð¬}"S™ö2ÂðÅXñ±ÁdÓ)J²Ç[½ÙÒ>¯˜ÙÑ:ÁeöŸÌÏSÀú°ó?8x¬Ø9õ£Œs“ðó@ùa‹½/{{_ÎK¦ŸFX²\%øMeâÏc÷ú!\x)*r$¶F1sZÍh`ʼn͎^'Ô àçŠFg'orš†õt÷·FùVŒÂµ¬£V?~áÈU!¤`rcÛ‡¦ØAie–î¬9)<…ý¾ÝwK^OÝÉ µvüÆFáç­ýÞX¾/(Åý–G€ ÑyÀ;œ ~è<¤ÝlS]Iãÿ€RpE°‰eÈþ%¨4ó…P ´½øéÆ#¼#ôÙôøËf7…%é\pô±Fÿ4x6Pº\´œgz+ÔÚ¨µÝ™‰£¸åB!FùÞèç4ÿùù!ä»À[:†mhúx=Àú¾Š£~ä\(mÓáŒ:åÙXPMJRÎõG_…ãµÚ€ J(°¦ß»Õ!4`™åäaw ÎÏQŠŽQbœÍ`é1›j§Ó!v~•VÒ#­%=¤I¯ù7”~m›‡gäß½kÞ:¥’Ù²•TÚ—h&¿Ëû–ßÑ¿Ö=Uúö €Êš£xùÛ¼›LÖ3ã¹Ûá´‰š ‰2¥(Þ“YqAݩʗ" wG·’¿íÞ´©´}iÔO/îP@zU›®£º*v·ÌÚÝÞ2ƒ”Ü$¬"œe0­ZKú¤gåµ;ð€†ûdÞŽÖƒÓý {ߎmù†Ù2Ž™QîÛ)@‰èeȆ—«eà´´ŽJŽ*‹?ªfÞ7ÿ @èQ?6ÿªU'µF H(›HÿÎpé·é`’ÂØ˜®ñûéÖ-¿½í]÷jëÕ¹Ùù9­½»û(¡qTš®˜¤Ÿ÷ÿÓ²¡¸9*l?­îûŒ¸÷t¼¼£}Ë,ôYÛÊ@•Óµ -}dgM1ªYììH;§®«^®¯¼ þ˜0Ž€Y¿fÄ'nºíÌKÜ„¯gªþRÃàîSFP¸Ì³FF%$ÓoðãŒn.Å!°~*|yGŒ`®P&ýœ¥°s®Ù ãV'VûôOÉÈÇ<ĸ mŽböÚÓݸn’sšÿø˜£p,H7?{-ôHáÿééQ®¡ëíÍ_óc”¼©P@ù"=¦à…E':ù]>¦nTMHXe J¾Óư4øçTHÞ׋ 5‹Dä§÷@„z‰¿#}Çã¼Ùï鳓À3€ç‡Þôç1Z*æ7<–*Tªm[{|æW¨"ílZô{VD¿öׯÛU!ðž-v1BA³¿ÓÃËøEæ ²AËâDÉç´¼rEÅÐ`ƒ2ȰmHl¦|yï1Z¦Ý™l7#h†‹øNé+‚¬+§åsÚ„´lV]W—¸ÖW9«¾lƒµer) xZÞ-¯Ú‹¡f”X| ÌŸ°l‚}úy%;½úš%±1ÈqéîèèÚÂ1õTK£{;çÐÞAm( ´ 亿²Ïé~iïì`ÍZֳж ¼|Ÿmâáùqi×H‹>Es(.”6 9?L̨üÎt‰rPv&Íðú€apÜ6Äf~ÃØ¸j£˜ï¶øøÍg4L¦j·9ÓME>Ú;A03f]ÕétÏ%?~ü9[K²ƒµS]¯”_KhG–n®©GªA]éÙjŠP6²ÁSñV–˜¼¢p÷%T¶Ø·°t–u+iÕ¦60M£µóº¹Ù§!{fÝ3þ6dâ!Á¯Ñÿðߘ&·«L" ¾ÌF!éuËå @• ãþök¿#ÀÅ>éAäUQê‹’ˆQ,;[‰ÿ–kÒ£“’î™–*䛑„ RÝ^XjƒÊÎPOsK³M/6o†Gü’Ÿçüÿ×þ=0»ý¹uòûQ 悦O~×tâü©àÙf¾üòë@ëÛÙ©o¾ù&к÷Ü¿õ/l…`9ƒ5 ñN”\Z»ëê²í¶­sHœú¯l›”Uò§/1xH#;h¡fÙê'墉²Ë•8¾â¹·sAmÝÖ¾ŽÕí^fT6iC›|'Á¶vÎR ¸ºq-ˆ3-NHº„€4,e % pÙ§¾’#hùþ,'ù¨æQÙay„ò{JÜ÷äç¬åyùN©Sø?Ö?úúŠÓÓÃÕ?þñç@GöÏiëÿ3P®’§÷õo­£óóÛÕO¬S+ÊäÅÞ·.3{Æ¿þë¿Úñ+Ã탄-çšú¯¼Q ìTª¡Å†ÄãK˜·¹š§òPÐ~å¥p,)T“—¸Û|ñîš– Í© 53„æxç €BÉ»X¡nìvGÕ¿á"ë÷ê…¬›¨„­ØAùnÄWkg/lÀpK Ëå”õå´Y=Ö¾€h±Ò段LÒãB¥ÖΈÍ07\f³Á¤ÁÖ–;Û¯¢ Xm=ÕÕ3¯G¬®Mp5›ÎÎ y¶c´kSqT\F|©a+ÆU´1# ‰–®r$+Ð?% «Äæ-@ü“eÂÈ/6Ö¶6lâðN…ÈãÐwb<*w´zöô¯¾Õ>ò[è×ûv¹ÄgMp(¦ay®ùÖBuøæ mñjÌÃòŽÖ¼ƒœÆ,J¤S¼©—L#ûž²˜wÊÏÛ´ÈºÚ ©ÛñŸe—?_õ;qà!ÇwÀË ׇœòi!Ýj†§”<ÛŽ<Ù#};ݶ£†ºµ¦¡ýUŒùšµu­[:¨wÜ ã;žÕ|A¸"¯#w‰–Mòš¼a½åK¡Ü†È¸«ŒqIÌ:uFŒ˜KÐT(¶ Ëë+ë*ËM†õ¿ÿÌ` Iú5k*Tœß£_ÂL¬·¼£_0¬x„5¾üKLckëÏœ>™u Xn˜T 8:B&¢ì_\ ;pýnò¡«ËÏü2çchÎ,ËçÏuã&|±m{g`û‚öÁæsêåœïÒØVt·]Ïû!Ÿß»0±ô(ðT8y4Ìz—‰õ‹mŸ" ÇÒáîhPu$X>YÃEêù•;µÞ\.Dës*ÔF¹46^º»!5\†}_îÎ[¡ÙBV(~*º_¦AÚùNhÇ [4¼š®~jºBÓ¿åˆäÖ]K%åç´&4c&E²^1?§£Ë”¥õé:ÓÚ®eÏ4T.zZ«ý]Ñ*ÕÍÙL2<‚ ýh=âé<‡¸îÇâ­ùéŽ+i˜öè$}Y³Q%¼«Œkh  o+ÄÓiCG–D®YßÏ:¿S„þ¹ƒß?¯ ctt@Ò53`ìK!Pá%;R/•öðZ´›(·æªŸÀu >¶Ñ?ï†ÇüŒ²b±Á4å5³Ö¯ŠÞ)÷bËNù»Özê´§ÊŒ €} ›mÁ2È Õ‘ô’HCëZÛ}?7ìtø5¹/1XºÅkýyÂuuš!¤^V],Ïò¢VÑiÔïk­_šKφÔÓT·¦T³¢½ÑO<ŠgŠw$[)òQai,aa’¼c’>áAáí¥õMÞ’æ}u£ß}þw2ùˆZ¾Zo7îäšk>É}‘:Ç÷9øV‡Ÿ¶Ýðè_Ú,ûxh¯·‘¡›‰ë±ßöÎØfÜsÆ"Ûj‹½QÖ½m£e±|0×ÿû#à{S,º¬™ÍQLqǨ(~< ¯<ÜË›æâ$ÂO%Vqp7S'œHê Aìr‚ÐF§•ñ£‡‘ ¦€u§`çWaWˆ‚J¡%ÔØij~­FÐ jþ⤂"/­¸ ×ñ3^‡1¼åóÙÙ—dDÏ£ûéÙ˜Z÷õ5J¸e‹·gÒ7<ÎÄ‘¿=ÓG >ÙV¬eû%8?PDX– êSóâpÆq ¸5]»yñÒ…MÑ:åÑ ÎÖšÏãôºS!Þø‘—á …_ò¡ì1@ûÇb ñ‹Ç`'Ú0/m£½ëëÀÐŽ»¬Ó×(¼ø—ÕoÊä‘R§xOÉÛ‘53KI›NUžtÄ¿uµúŒ»û¯vä­ZãßgÄæÿVîQØÉ:~n©'R¶r­óÈߘð´ÇÄT8x­Pb+¬Á­sž|‰©Ž¢|çÆÆÓS•Ýî_¸àXâQà9ÇþޏåÏë¢/.6áZ u¬òçz¿]MOû×è+¼(?9Ê·®u;Í)”OuëßV¾?(#Û,Ýïj¢ÂHÉÔ‡ïp„¦TÕÓ¶ˆ_ﬥÈg0Ò_%ú2uF§å¾†&ò¶Æ¥IŽáy\ÀÇ=찜ⲛŸ·þU¢OøØÌ_Çt£¬{¦66΀Öm Ž”½Úȳ–Wï‘Ö¯Lêe ÚKFEjQv¼2Ÿ×72´–*V?˜’&°4tÏÓ£ì^±ÊËÞÖÖ÷ïÛÙ8¥)Œpzö6 ™—NjE… ±hl|\çœZnÜqT«†¦àrš]·«×h>Á%Ó(LÓ9J ð‘ÖÒBSÀ5Bù1eutÇ5´ÇO˜²ú>ðŠzºE¸¹yBšéäöèü¿ùú h ôyvp¸úÏ¿ýx~aGä´´½ñ>÷¢›ß~—Áí̳7J?qÕ¯ñ_CU,‡—5Kùx›tÈü¦sÞÝeOÇc—jTJfjžHC&´d7aM&ìÃO \hGˆ1³C_|Î}t|–K¡x}í&ÇsòóÈèÙêñ>Gù€'H2¢wñEgwosõÛ/¾„o¾ ã7fUW*-îKñ¬wÂÉŸëu»C1’Âä‡_;aøÅÖ7óe†P6'4’‚òÛi•·(dhž §¿üãŸlì³Þñs®ÿûÃÀKÞûÝŒƒgªKF;&•a˪Â鉙mø§6¡Ê‡vü¿ÿýï§i~÷§üÛ¿ý[–l?¾w€Ð¶d½7´”ïÃH‰¥UÓ†yj{¢?äæ#yõKÃË[ÊÏÓ§†>W\Üä’.¨|?}î»Ì” …Ò¦ççÈU¸L‹×«ýÇÄ#Ë«Œ]VB‰÷ò$§öÍ“JjÂÏÄjô–›û䆾*‡S Åu„§ÒXj ¼àg\yt厩¿{:êDmF¹™µ,BÎ&8tz³÷WuþX”‡ud÷€5ÿÿ =p5·£Nñü%ÐÛ9¡ÜÿËï¿T6]!çù°Ì1Z³ ôÓƒóÕ_þò$P`ýgß~kŸòöQd¡{°”…-m3Òøå2ñÝ’úှ XGý7™gA^t.™-N†8GÛ¨FMØ4ŽtrVhYe~úâÞU³fW3êÚºk‡§BØí&lXb*Â÷UAbø*³ŽÇúó«âÊèvœBÛ%‚þ–¿œؼÎgº€”WF}Dçïæ>㜰FìºØÙ…ÓÆvŽtg'#½:aàt²ßÎB&7žtm!ö*üº,¬ÉSQ¼"¨èÈÊê|KÁ”]dê•ö òªŸa„D(.*‘‡ôžgöéÈí¬e«^"q6d7K$gô¹½4~Qh‹¿¶Ùø˜‹pJI³Ó†é(–ÙCd¸Î Ís(ª@1⥫Ê6á*"" µk¼BËÂ[ø©´©Ñz•ϼŒfšæe'uĦ¿ƒCÖø3åµúé‰ûxÝo)C§ù°½ž¡tYZëÔ¶ Õ­²Ü3ívÔßmF>èð©GRí:«ÂtoÛÈÁú‰š´>£òI™Í™åNƒQ5§ä}Û€Š˜3ÌÐEˆdoPºT.Bß(H¼£.%“¢[N^Vd·¡ä“ d BÕ¿9å 0¼.SJ{tºy€= •—!:TÅÅã¿´ Ùø©`åT]Í}xø„6âe?uM÷óºnïêXíБÃûŸ=æƒWîŒÍϹãÃ{3˜PÙSÉ>>Réséu“¶Å`Ó¯ÓÑž”ÊD­mK¾è:}_Ä~`@²-B¶s¼/“Ú”…2rŒî„ w^ÿ ´øÕ_³ÎŸ~Í?Áý)U¾ðâÑuGnˆ^žì˜ÚVK£i aE½ïQ Ù¾3£*S€Ó[2^A;|-Ó[ÀLu+€ø‹ÊȺƒY&­+†/W.? ãH´:yÙÊçÙšïœ÷@áAñS0—ǽÍɨøµú_{|‘m €í®WÔä]/áÙeW·üz›Fìò‡Bz\L[†%b® ? #È#(JAqÔ¨á¬G¼ê@xñ#lÛ8tè4ˆéáEGÒÀ[˜fÀGÓ&Úä£:òS ÷¦?Ïö»ÖŸóý¬õ»Ùïœiiñ”U´â›ö«ÂÅ4§½mÀ£~vè­ Ûék»£o¨Ÿa:^¥%†žYÇjn-…«<Ñõ°6ô·.‡êuQÌéµTK“*–Ô‡ÖÔ" ~‹ŒråÆ2½áNÞ ÿv6þ‹$úUø;KWÖ¥<ìRK}•¿1•…syºý¶Ÿõ¨{â¯)åÇ!þ¡¿»ûîwFÔÿõµ¢²ÊÆœàAÐüc½Ýöžf™ÌYŸ\•BíÉ™úŽHÉFoQUV*'[6lš¾oÊ=°`qŽ`–¨ùÐ'0º(¡¤Ézk¦Èä0\m˜)¶]g¬fò†i‰T©¥M&¼-t´R§p³î c§žéüo^>°GÑ£Ó¶C H¢ÕùÛqõhÕéëÖÐÔÌ»¢Öq{ß÷6ùÉl®]5ÓéV»Êø§§O…œP[—?BcÈõ Ú™±DÂÅÍcvøÇ§\‘Ë´ñé©G^ªcË÷m{Iœ®Î@€R¬¸µß2*5ñ©ßì!šq"¬V¹fÞ¨ë†å –XÂp]Ï™Ž:Çí,‰ €£a×¹Õö¾ –—"Dvüð¦¼'.Ńy(„ÌþåÕ0*nKYfÉg–÷N¡iVæÓ#~%¾(*eƒa4¥ä_KbÎÂ]RÌÜœ°î|¦?Ž£yŸÿgû½Ò·h¡²«ò£€«ý%vævú*ÂÝÛÁ;úw ³×ü}×J@+ ¶¡e™F14‹"•Iû½˜e¿ih}Aݪ7ƒ[WŽZFmž¼LÝFþqF«›0kk6ú%¼a¶fGoèh<–ì&eV–©ce(aÔÈ;ÐðñÌoÞ×Ïò¹p F^õÒ¨è—ÜóË:lFcºß=+µZ^·=;n[ʼ²Pkö`h‘ùG唿Êw¡¿Ë¿ÏŸÿx…<ô¦N—5·¶TŠèhÛ[÷ÑT„7WûžÞ‘C¬ e+Ë?'ÈD÷Μd­ëû¤eZE¯êñC"Òƒ)6™dƒ9¦ jc9ðÂèbkuÊE"2¥G¡•0]M±Ò%ǯv™¦ÌßD«5­zJ;´ò7?N®ÄàVÞÒÉ+°MÍ0nÀîpÍ9÷×ïïß®öÐÔܳ½m…y¯³<À“é§p低­rð1é¦f{xèè!ü™ÎúûßÿŸ@/¦QûßZ0âeÃDÚeÿË/¾ „Çé ÎØ$öc \ž<=ãûõç@(ñ÷Øãn×h5:È 2Ŷ֜Ǯáù&•9¥iC–³@ÖFJ?B”ÿx¹èÈËàbf¼m+Ðg7øüËþ;´êcø¦·R—v¹ï¾6 CÁšL¿ø¿:Ó‘M”‰ AàD©Ìõ“fv( rÁÿÂÅa½ÄŸ-zïX®ûF!06RÛ(' êšò§“?cŠ’åSÕÓÓÕß¾{ºúáG/ûqi†ešËÏE¤”•¿Rìü¿ýöÛŒòíÐ}î{Zð\s+¾÷¡u¥µ-½ „ oüÓ”u+¶4îÇ~=ÒõQZ÷k½‹‡FŸ­MÞÁŒ~£’¢\##n°Ù›CÊcé´…‰<àÁiû÷€\3‚¼¼<Â*ØwálËÖWÖ4VUDæ®Qy'žé4EVÞH§¨æ‰wø'¯Ä¡<¹ú­‰=Ž¦ÙžWì…ÚÞ~N=9Mí¾ÝŒ‚OO½¨ªZe¢u¯´.µÖëû«SPys‡>Äk<õ·]:::üiõ§?ÿßÊC/Šûü±yÝ0mÛc£ëæïk@Tü|ƒBä^œÃ£ãÕßþþãêÉÁí늴ù2À{mΤ>aÙüg÷‘záG"#à†oP´wôÁ€b¹H+É«Vé:ˆWÄÊ©º’‡´ÃÞ¸¯„°nó~’5öh{ÖîlÍ‘À¹9«ûÞ«Un‹õ.#¼K…ZæV3jƒ÷Íèg¥­3•1?“N S[g0¬Às4Þ2 ð#uÁyThòåg6ì¢ í<Üöv=×Êš%Â眞þ!à´ññ Çĸ€¥,ÒS@¸3zZ½ïÀTÌUšú´ú¬×®êE>ò†Ü7¸¤üÖ OŠ”ÖˆÓÍT² оO9Qðhß²·Ò'¯Y8¹Ž_ ªP¨“ Æ!nü†WÄFžÑ'Wg˜T|æKœ,Q•+¿Ò Ö§dz×#>* ¼<ý©ðÒyƒ§8\ÎW¬oj/z'§Ôç±{8†0²=fį*mûh[Âν#üVììíàU\ïw wûë×3QÖH±¡ÅyxÓt áFví÷bîý¦¡µ&¯I»2¼Ñcª¯A3ÃùŠ7©ëÑáÇm|ý‡”æÑïˆôïn¾ƒik¹¥Ñú$ñüYÏòøL8u‚ ;5Ÿ kPýò˜Ÿ*ŸZm"6Y"Uü]‡ea-öŒaÏŒ:êkJ;|\?ÒY%À£ÊΆy‡ÇÁ³ï#½Õ ’ŸÁëQ¤U¦±ÝË%`îI’ŽnTOŸÑ3¬ù«œÑñ_^zò)!KéðaÐê€*`3Jµ²T« ”6X:²§ZPgÌ’wñ„ziÁçðøOÆ&:%F¥™â¥§p´be„k×9žèfEc3½šn5ŠÐ”ɇæ˜ñ³qʘ ÕrËö]ô¬m1¼aËÿÒJeÌ)Çm袲TJ’÷ ˆøsêßóâõIXuÙëÅ*xv ù¶]ÿ )µªö溟˜á5nê44Z§YnßXÖzáU«ÎRÕ#¾ðˆå¡BIG¾©t”µã­ê$IAÿ ýZ¿×Àº—¶ý„ex›þhÌO÷È jÐo+¨u4,õ4û¶”JEGýµÎ_°6üõ¨O¨Лþììu õ×vXã›çÇh¤ä æú¡\ÑïΛò¿ãõʇ¦‹;$”§6™Y¨ÎønäNý~œî†õiN}v·¿ubç–åÖ¥Uàa db˜ìØjÊ¿§þ•‡m­×I(9Xƒ8e¹³ Ìj:ãâÅ>~£Ã{;ܨòÃ0ˆ–Ïñ]锾ÂA޳Ô5##g@ ȉ"A½]Bg.8àé³K¾“ÇkgHlk¶;Ý£ý}mâ½))<p D«qw~Œ\:”£&Nüi¹h#B­„Ùm9ØŸxé´aô7$¨ ÀžGÉø|mM[×éúšÃϘËK/j(%@¦oMXFjÆÿ°›;‹ÃqÁOܽ®×ñÜÔrÄÕ¾BùùÎû#n?\±æˆLÏÑ5¡çé7ý=ÿ­eÇÖE1ŒOÜ8æ2…ïSV`) ÝaØüREÀ*ljåîY7ªm±ì–Ûp§L>Í2úf£_Þå·GOøûl‡Zo‹ç|ê+üœ½k®‹%cx™VÀîzá”îNÐôUPdz¯ª=T^!DÅÌoR1MÄ1Z„®¼#œÕ¨•—´möt˜ÿ5ëüû{Lq~¶¿:妲3¦;YKg`=ªºþÿ˜5ÏÞøgß¶;|GûÝñ÷ì€3ÝùŸh1¿@IDATXíƒ"®›­ƒ£‹ó§,w®ØÕïÍ|\»œk¾9áÂ2vͤI+ÛFH—ÑÜ—‚’ïÙÿKfÎèü=¥õx¥3„%çM°-•“ºV[7õ÷g(îÙfŠ.˜LåTãñqÎ@`™"¡…jÕ¸lrm‰Y*-϶4 ¯j”>ˆdÃÑ >Àr¼œ]&ÑJ‡l¥~ý•ŸÓ¥ÂÜýÌÕ·Ož<®Î·ø”#wxûéVG3+²—ºlVÞ‡bJ«õËTjéNAq7ýÖÈÿhuðô/(6G ÌT?¸ ³osV½Ö¸JÕÆ!+Ìé®VïùwÚï9g\¿ÿá)kþ¬qÑù³=‚´Ýù* l$îŸ/~Yß&ýšn¯C3qHqX¢…/rŽ9Z4 <3ýF¥Ú©•R†¿³Md<àm¾d‰ :BMÊ›4ˆŸ);ƒñ· ®;s•^Ò'ÚdÄrizãUû™ÉLfèÂSþ4ÌHàX£}ãYmè4ÌY³Ðξ„[)ž6:gs‹Êmpä~‹¯ÿ7Òã çGlô¼=Xý?žp×Á<¯¢»ÍÆÎý@ëÓ3ÿ_~ñ»@ï.·ƒÿÝïꜿ¼ÿÿøÇiÊßv‰Ûü›Ö¹e|—¦ñheÈ:”Ä@j;ÆG›ƒ'c°0@S»ø±+\š^R™ù2Ad™#je‚¬3‹žãGÌGªøŸŠÃÎçÙÇá²Û £ÎîÖ8AÁÞe½ø³Ç7(`WÜ @þƒ±ÌsÉowMñÙåfHÜ>WÛã%£_òïs”:_:£ç_å ÍÎË£Á,qùÍ9߀ØÝó«v7ùvˆå»ºò›Î, –d?¨Ÿ*³E®uýõ¯ÿ™^òð˜éþ¿"ÛX¬gÙƒêZ}õÅÆê›¯¾ÆMíàñØ«{­G;jÚšKbJGëоà9˨ì­:ãÍŸž­žrŒöÉ–Ô¸EÂæÃs~|Žeå¡mFk[òùמ){P@N˜ž\†¥b}ÒyæÄ·]ÊÐ]iŠ1b ì Pæ.ó܈ù¯Ý:ÂË qzàÁg§g[w”Ù:7¶yücžXj¼2€x6|Y6ïÏ¿‹ Ò,s:µu|üŒÑ:Y°æbS3\>±qžç«o0¨RJzGR5½I“ô¼Ú²Ò«‘ÿIÖþU0T\¡¤bJø)ôÛ¶¶+œyá5©2êÕ¤“¼u« ŸЙAn'¹G–BþjŠŸ(“å>57• [ÛE+m"¼W¯ ‘‘ÒxË3édú£s˜ß˜ž™äM¿&…å}~¦ÄGøŽÔq×JÛ62ǰ¾|2¡ˆ£û` ­Æ Sº¶'4·Ùñ­’MÍQïlpz¼Ë¨“i{NqdÊ’Í_B{,?ºÓywÇ‹T!´¼é¯¦ú`vøÝéÛ1(؄݆¦¨ÚO²!dTHÎözeI­Õ4¬§z–QU:µ¸}ä²Thl¢”mùu¸T¬§4T¸½€ËÙGªât út“l»'ÜÍ¿2šPõ]^Ø•mÑV3èâÅ#Þý]/¬ êà‡a:üšë½=r¤ì@ÀinO ´9Q>òðˆ€ï(ß/¡¬èì¿úŒWÙéG^yµºƒ–âçT+-§èŽ, íÏG]N°ã¯£´Ìâ8fñ20/ÐjyhÛh»ý·œ|ßd|o @ ™¹ºÜÎhõ/­©šË]R„‘ïz¥"ôïwÍøaòµ°ý.òÒ8ägLŰSÚ9‰Žlð™.[ÿ¬o» †ŽôÿgïN˜ìHŽ;ÁP¨Â ôÁnR¢dœµÝýþßfW¶c«Ñˆ‘ì gÝöÿsO/«4n\”mTåóÌÈ8<Ü=<<Î4ì5=B?–¯2aܧs<šÁ·¼–>ºÒwªèÃÏ×Eæ¼j/k¶ù‰s£¾–^ÊÀÊEI#2…Ðø3ÀkT!‚2LyêÓ:(LÃÞW¯ï!¯ø5\7 Iþ­\)Ð0ä6üsσÆv•¸<®Àu™WoâÞ¤T2¹I?Y¥¬\¥çg,ßü¬ÂŽ×Jw®µÿõûJ:žç}s»ÓàWx,/Ý“ƒRðË}á§ÂˈYÌ€”Øâ“Ü»Û ÏÇ~êT¸,è”r/êÔêûž#· =üÔƒ™^ŒçO¥ÈlÀu¶ !Gm({ÀK CבƒIø¯ü'þÀ Ư¼ýà:Ôýò2Ûº“Wá‹}âꚎOŸ$xqÿÚM²×Cÿkc„HE´l¦žè ÞíèCù3B.2¼­áÔÐ5|}‡è¯Óÿ>tàÔ® éT}¨†:óýô!]xn¾?Ó ýŽù¤¹³¡Ã"ßÅ›jðQq¡äê–n´&Êè‰kÎB¡’]Ó>¨êÚÎýÔ%p+›vÔP )(Á*"„¾’Å:ÂŽ QLˆV Nâd÷Õ…Ëñ÷&›ßö‚Œòs?J¯îë9ù•¥M,䟽œ9’ÑHÀ^,ZóB{9¬áfαwæ–ëø$Û^²ê=–A•ÅŠQ'81”m˜Åm‡Ü4þY0”^>X tøZÑHàON2ßex+|úwiès–&øö3Ι"§¢[ÑÊÂeÕ¶d_§%Èü¿c.ísíƒB™gö÷•ÜüáסùC×4o'ìpâ·º£Ùùtï×Ó¬y¼Þ­“BÏŠXN:å±<¢qŒ%C \äe ²æQ RÐ{/¿jl=×ë‚^—›´Ì´oùÝH¹´ Mñié˜6¹ŒŽ©ºtƒoi$Ýœ¥Q0´²ÃÍqâÚ2khÖ½†2H7)›û1¢Á’‰áßG ä3„€Ì ^Äɱùá{;ÇGÙZ•a.ï ÔËË4¼!¸ÞI"Õ04"„ˆ†àkíBŒ¹êŠ+‹JÊ}-pÁ³ •_éø/¿˜æ‹ûe†6÷v¾ýæw ’!"È?=Í÷O;§ÙbqÇe>ü4ÛB왾}û^> ì{æ_•ÐOƒæsÁc½]Eìý?v£ _ÏÞ6>Ðpÿqöx÷—ÿ·àe.B½ÃtÀÇ^h÷(øëìWÃúÆú€N)‚Ð)«9.Ü-Oû„Ÿg{Ë‹¯vž?ó! Œ0OÜ[Â,›á`ßÑÆ>qP>#ø ÁQ£8*ÓÕO±-|ÑÞRŽuå½!zÖ•wx©² ÏնϾýëßâ{.ü šÂ%®DcJµoUpûæÓSˆ z·—að½û)3%±¸6*JÉž)HN¥ºeI¬¡P!q¹©<ÖúSXilÑ…m¥Pq*ÂD¬øÓP7Þßt\qæ“[¡©”c®üÝÉ·‰ÿðÏÿ”aÞžâ±°ÓÐQÀV£¿ÌP]ؽõ8q¿IN™7^œíj.òrÅøžŸ’ ׯ1òr­ý‘ÿÂÍ S’«¾B_tØÒŸÞ°*ÜÜ¿4ò¤sŽÒ:€½T<þ±Ð¶ŒÖ¤Q6gdh¿Ï…W?5þÏ_8£ã éÂ7õLÏ»ç§kAî‚ߦ\뛤[èJ¿ü•×]ù&ÁîÖ€‹ÏÎ^#àЫ»;ÿôÿX:Î)v/^œïüëÿÌ>y2p¾—éÄ|,ê§ï¢k2}=®#äœz|ê´Flêöµq¯‘¯ö ¦"‚÷-“ZÔ—ÿôäe޶Îç¸éC,½:û± >ìïÇ_?Ž^üªôáÐය8t¬4Äß(R'ÑYèêøì¿|ÿlçésßÏÈ+/s8Ú¡Q´¬ˆLܸy/SfSÏ»ô#zÑh ~ñÅÑmèø&ø!høÁ ÈŽ€X™ošQ #(N ¢_ÓßÁbI¦!iꇽüMáYekG¼¹†ùuSBÏW<&N5Aòžüï˜ÿN%eõFè÷ê|wJM¸”a£ËK_¤1 },¨² Tzyþ®ÿx ³Ó«\†ûä÷üÙ_ ÍØ0ß¼Ÿž7e³›ùÆ»1dª².ø¥ ÷¡Èõ¢²4æýÒ-díŸgš-\èGhoæ'§‰IW#?íX¸cízgh×¹üÜïÐìûŠ»<5Éa;ÿ\Z›$&©¥ÀI÷JôÅH3NÁ ãåb\÷2œ¢æt¶u\^ÁÆÃxjñ¨ä×Nc]–s 5Þd{ä»H’Ÿ‚KœÕ½[ôª€ê\k\­âèí8Ç\.éþ^Ÿ]®1²Ì<æa7ùZMou LÓgÉíï iŠ. æŒcrÔ²Ï5kÔ@‚ãJŸÌCêÀDDgñ†ò(b¡]= ¡mb5ò–ÆæftžoK¼JïÑ›C™Ô/CÊôd›‘ŒŒŽ§å’ו§òOÞ«÷cä¥cm«ñ÷(au9wÊËI3DÎd8·M8ºðììnp;Š<¾Ýy˜©Qõúc;Åê:ªž2¬òχx¢uŠŽó‹§.h”ùf>Ö´·—“NñeçæŒˆ>Ny2@/Uº…IÒÑ&†É>™÷¶§×‚ã<1Žr”öAÎÑè#£QjV»ƒd`öÑt$]H/Ò•ž½«ºú‘éøA €P¡‹¸.• zùž&Pgzϼë4Bó~Â0¸Måì,å/ÅLH»ïí]åGaÏ*.r|¯Êza:À¹Õ±~k C„ψJÉzðù-«ÿGqõ"¸-š£;zõº^ಿ5нžÌ¥ki·XÑë¹ÿv‚M¨]üæBŸ·¡QWî.w5:Y¤ƒ[:/8c°kqÍ…yú0 Q*§µèÉ0xët=2Þ¼ižÖŸÞB#P½Ã .ss£)Ñø¬ ~ÅϤ{=‰ñŸæ¿»žU„»Vªç‘<ìïÅÈB0[é!´ÞÛ Ï‹× N#eJÄ"5_Îôäüò ¬¤=³$öW`ɾ®_>ƒw½ƒFn$É®©ó?R_•ÉtÅÞþyF0Œb*¨á~†€Sòìˆrf~w ðYŸú¹ÎûýÝ£Më˜Óƒöñ>Ô 2MQóü¦A³ðÙgt#Æ™Íöõ·> ¾p®³üömÀÔlËmÖÈç1Àxì¦`³Úÿt¹Ò[è$’ôºƒ4ºozùÓAâŽÓ>~ŠºòA €)ØC¦¢¸ß„ ‰ 5ݼ+³‘^änk*EÅAÇ¸Ðæ¦î7yÆÍ‹š«¯e¬üÖZ`ÃÀp0þëÙ‚1Pì‹>%y–EnöE÷¢¹Ãj (7§çùžóÅ…m0çõ©à6ng roÐz‡›¶øE དྷ¿‡¹4¾Y…Ÿá8ŸÅ,GÇ?¬¹¯W‡ÙË›{×¾þªÞ×#O-®…-ÁDëÙ/;ݶ ,”-ª¥"ÝVÙ”a®£ô2ÏåÃ1>ë[ýyX†]7òÊ=Ö,Ë–U» áG«·sª^[õm€å‹„YǰeT&amÖÂz®Ü–µÞ9H/ÀrÊ^ÀRlÛçâ]"Ö|”ͳç);’!ÃŒrœ¥á«R§,wöl]F5mgõ̵2LþÇ% ÃåñØ] F^F`#/¯2e{;á½»·" »›u̷鉓:Êý,õ}§VÕ›ÁûiØ”kx>z¿Î]mðéIzáÅ‹'GWþX yyqÙ ér΋bÙ²ËTGÉì4ü…[ÂØ÷h+~èU#ist ,ü;Îtˆ-´FŸE/Z»1åWðÖG³n¿ž9ôšz2q~Þ=ö3¦@ îÞ0úþ~†—öekË1½ÖWÙ3ùôû0¤?¯ØŸN½bQBjNþ«bµÀç¡•+›²Î+Ï~ÞK…ÆLæhY‘ƒëúf…iå÷ÏÿøíÎ7_? ~çQü—;ßýùãgavöH<ßùÓŸoí<}ö°Êòàá£ýÌádi™Ã±5ê—*=Êš€•ÒŽ€Êzòä? ö{|Ú¾U‰•Z´½ü–F1$ûò‘c* vÓêöíôÀ#ˆEÇ¢Köí×°âi(|o{©-Q<ùðO|.öy q=žó­shŒ£/bAXÌy/CÈë9®/¿üòÊ×Ç7ûÄÑe~r3¤œ²0-ÃxÇÙÊhdãV>Êqûžµo]@ô±ØÈ~®]HR®|Kù©ÝfUËSËDÒJ¤‹:‡ù¨Çÿ×ÿÈÔàûZÛþ>ƒ2¦ô{$Òš$½ïv µK.r_pyuMžŠYƒ2~¸ßü4ÏõÚ]Ò‘iÅ‹½\u*Të¡âyúƒ¡\=þUÙœ9¹Wuô$ ïË—­ogdo‡ÎEÏEB^E¾Öz¡¶ðZþ%IKy£Z ”/3¢£<:QžÉl-Š<¿cŠv7߸™·ã‡áï|û?ÆèÃÛÛ9BúËÚúâÅ—)ƒC¢Z÷ Äë5ï ·_øS£qéíÿýŸ¢ôô³Å9‹úþôŸÿR> {#oY—¨_råhs£ù…ß¹ð¬ºÎˆœvçTP‘BŸ‚]Sjyƒ(ÖÏä !ÓaÖD=ͧ´gßÿq¾¤é<”Wá2«K{éà­:àÒ6Xõøñãzž´´‘âp³~ÈïƒçŠÐ+‚ß¼a€À[F *Cªz>›Šh- Ñ®êÖ<€<Oi—0rÕ‹ S¯TˆEÁU€ c§ŸµV¼Ž¿´X²÷I(JÏ èÝ]‡æR7?LÓ ©Ü½67Ê"FÂÏÉ÷JÞåûö?Ÿgݦ‡Ÿ!6‡ù¸zÿËÌñÿ)ÆÈË”ÁyÜ£ˆb5¬ûzáwcœVC»øÍ0þYÒÿÊ%J'ýÿ:ß>tCÛþN|ÏqrÓ5i ‹hbÞ3€(³QhÇ Ax½•KÞmrÎ0^.ÃîA¾E¾îòß?¹añ(è¶rAÁ8…r«øó JÓ“)gÏËr´§E€'YÚ#?£E8Y/FeÉ¡yª}ö)§¶ßþbçãrüúy‰Ð…Ø"±Ü•|çä MYoч"W™@·[t_½¼mÉ\q[¹ä7wãÅH…‘#†—Qõ!Ò™|y´Ô”ØIøýu®\³|/°۷…œ—ô;—þKÜ\H^q…b~ú6)qj}Ï»‹µ 0q½È½à›kIz3 î*>¾Rü]7 Ô±Þj® ¾"Ç€<ÍØ2c×Û}º‹á²¤3yåU’ÿšßëû`æq££"—†Ïo¤—Œ%îí±%¿ñso ’Ãðµó"_¸ñåO •}õO§J†ëz^ˆÿíx÷ÿQéÓ ÷äP²Ÿþ#é§äyš:é`7†xhjº9Û»•gêªNœn…v ÝvxŽÛÖ„â»%ôf ížÌÀqÖlgÿÿœõ/}|íuݸŽ}òkcaÝAL>ü¨€áÃûzW_=B™ÀלW’⟫sa¦²½™8KÈM€‘ÿ+‚³˜›‹U×ÛsDqzWðª?+%+=TÒ³4jJà2f›kr¬îññ~ž ¾Š¢o­Ê±.¥}xL1ú^š·†ß Ö6ØÌgÙÏß{X;og÷ûtgÌq¡…臞ur_¨†¼•:( öúTv²Œ›a5¦õÌ¢è^ŒÝ¿>Û:¸Vƒ# eWªöžç'Ôs­…‹—2} WøÂ!Ëe*Ûe†ô4´…{¥•DÀ¿‘Ö”uàõà×ã7ž’Λ¬ÃéýâïÍì`‰qf^<ÊùfÎŒ°ø§ØÀ*Š Ÿ0h#ãžGnJ©$ã &ÒŽ”ÀSû”÷ÏþL¸MyÏúZbWš^-¼¬ð<ÝL"ÂÖ 7í]Ê+ˆùÍe5NY“uáDÏ—Ö¨ ƒGâ¦Êl k5rz)±k)C¶îRf2ñ_É­I¹¾WFÏŠM>\Íïmé§N4}¼WŸèŽÐ3£qj$ê<‹k¤+5üÒì^ÞM]¾¹¤,OnàŠ½Wüë¡^æ/9é¤GrùÔõmë:ò‡§¾O`´¢žÓè:?ÿäø°âitõÎu¤L—âµ8kž+ëÚM9Æî§ Ðè7d€0>zÑs-|ÎýyŽmwP‘‘o”’KEëÆš2kŸäKj”AN©GÿõS~ƒ¯«ÜÜO=ªõ:h©ïuJjÖkØ14㤋‡Ú¸¾”}.8L£?~b}J÷Á €má"2ðî1²sEqdFîCÞXg±¢¶ÃDý$js€0ŽH¼Å»fn&X¢l„*ÊW*‘Œ…±ÞWÛ¯-×îUêÙGDRÙòŽðgŽëáýœ‚&æU˜jµ»‘£Â…~pðç4 /ÃX«ß3G|f: ÃðŒ\½GÞ=D¸µÔÛÏHH°d5S–'Ù²Öb›T®ã£ÌiZÅj?ÿ,P¼•!-•YnQ-\ü-ä¤\CÎhT÷í—Ûvâ¡§ÿ„ê"ûc_UÏ#~ŒŽã_ü³ ‰YžJ¤ÓûŸdÙÎå^•¶ô·Éÿ5¸Ñóì­PFŠàÙe¡òB¾J·¼d¡L> -ÒŠç4¾ýn+ý³è¹àÛ[Rõ¸ôÞm[uô±1Ú¾ÊVv_äXä:5/'ëé ݹsÔ•> b¬Ç…Sh€ñ——Ÿ¢I=ðXžû6¿›,>h8~^Gù([h¶íéG†—ôj½ÙÏûžÈ –b÷ âg¬Â%7Ò5/á’ò”úOÙ3ã‘ûe`öèF<"/ç9@(µ8ÆÐÍÌÉêeº$+«)ß~“‘Jø±Z¬¯+ù"%7°Ÿan®Ai-^¯GÞË×À®E©SŠ]¸$ÃÆ©Y´ÉÞ3žs6Ç­{ÁÉŸù÷œE¢ê‡þtÐý»‰ž—Üȼø?X€ƒLr¿–>ÑSà^-d…Ç{éçWAêvv>ñ»å|”t€îßïu8Œ“ý=gF<ݹ™/ßYr=øä§;éÝ/HvîÝ{rõÖ@å¤@nôÁÀªó‘~³Ëé0Ó® K‡èÙ³ÿ,h Àö>:úU¶³ÒdoßËP;Èéi¨¥¾!E®"Yå¾Ü§œM½¥žx^tPbäohÚÄ¿>†–N‘ï Xü´¢›cì›Þ ÊÊ ¦ûȺòšp?Ï£Õƒ¡Å‚ÒGÍÀd½þ;·ïïœf~)Õ!Ê4{ïÒkÊ á²zýðè0ÌKóŸa=Yí暑—P¶EØ,C­µ2iµÁ]ØVJ1CÖºÔ=Eí–dêbÁÎ4Ô¿ÂÑéxö{gÁÓ~zzNIëƒväE†À$Í€èÑîοýë¿UåTY(qïþ·••ÜËü¶!ŒPfxj*a7ø>Nát-B~TGS‚æ™X¯û9ÔàéU~ý…Eg½ ‘€j¬[PQCJSÆTþ:)§Ü¥úQy÷b©¶"ˆà'ÏÓåà ó½/_<Ûùáǧù^¼³ÿõzõNF Ub_‚ësÌù™ãrƵù­Ù÷ÿ®s\]ÁbɇIV÷’…çæ{ú2{wc)Þ¿¿·óõNŠá3FH†)ëäÂ4b#eÐtQ럊Y]ä’·Eï´E þ6<ŒQº£n7[…nf?/…|ž³žú@R+°ÝÝ“¿|w˜ð¾¤æÓÉ{;ß|“3­¦÷!ßÿîë‚ö“k"JŠQaU”ݸ–o|èÒR†ÎXÃé!ÉV˜î$d« ŽÄM¾Pæ3Î#ß}ÞÆ„2'QeRü¤Ù^p“Îý;ò&u(é?Èú‹û)Sm M8ŒâÿÏ?ÿ”a`ëVvc¬>LŽ1”µU¢üÿû?T#@éQ€sÎ:8Šoàºh¿æíæjÆ*{_ÒհЗʸ”³…ÁËÅ \ZÔ£(ˆ4/y&½~×þÑry ¢¿nß½¹s7´¹‘ï1ÔW÷b H?ôFm-îué݇öü&ïÒè¦w}+/L„žY lùaæŸ~™råµâÏÈŒòq¢FÜÝVžúÅR€àÐõ%ø(s. -í,}óÕ—¿ ÍÔýly˼÷íýœ¨“fÞó'ÿ²ó$u% ¾wwþò—-hþûÞÝ;¿ýÝÿVÿ'Ýòßü/V`ò ߪÁ¯3z§ÁË—Owþçÿï ñ?MÃkÚ)Ææé“‚ akm¾|à8óÇÝà'‡÷³Í9ì+ùîÒ¿ËÄA¢’é í™É³úSí £9ÏÅ#é„\Ú³´WOŸ¥S–. ¢ŸÙŒb€ÕsŠ :©ð÷P,àEùÁE£ïtª^Õo8-§xñ¿ êQ©ô³4¬v+ÆíT²ý:¹Jã—PÁTÞRn©˜£ôî.kÞ|E ¨–kšª òJ¢ $S*xʺŒ8ÁÈÊòm²U®qëûñ{œ²•Aɨ\®m¾¸°æDÓN¤ÑË"6 ¯:ÐæQ7SÃt²F¯mÝ`·ö[D!æí6üî&Í *N×óÜåŸî¶Àî2òO)ÛYÑsìÑó䌈W1Å=îs #…•U¬¡é@i[ðØÐk>6”‘¿‚ée×}Âkü­’þ­lIv­ú£mnù‹ñÄ€ÊUëŸÒË_ÝoÕ+åR !Ыò„+TW³Ô4®;" ¬}ê‘`kƒ,ÖylFØõýwŽÜ«ûsÉåS:’öÁœJ0б`‰&†…"¶ eˆ•ua8Îг³÷kX<–“S÷˜)U¡Âp¾¸eÑ.N˜a*~׈A*¦ñÇ@[ÜÒ—ÕѱàTØâë¡rBžX‘¤V´¦$rZz‚»a¾^ß…F2aÊÎÇ®ú²Wï5µx§?4S"⑌£ˆ’cò'dYYžcÖ‹'\„:•貆X¡›Êf‡X=… ¡‰eVýAMJÊZ—ŸJº@Ñ âC¢@¯=SDu»ôÎ)JA5`~sþ¼±è/2Ç{©R§7¼[Ûf2/\fk-èk‹—?º¾‹›ÞÿÀ _È’9èè¯ërWÌ7æ±Ðãﯼ\ÁVbÕXWÞÉ'´º™¼È<zGÅ…žÒü¨²EƒŒ6`øÛ§O²e)#\޾m£¶Ï9ï"%HxÛ»zd@zñKÜn°’iÄ9 åÙš•ÚáU¼üT¼ Q0?MK /rHǸVxdßÐx¡à]ÖnÀ"czþ•'A‰¬ªÃ¦¤[ëxvlA¥B­“IœÐà û²}NZðôÔ±·w"Syš&’ÎÈÉè X½«SÇk‘VêæÌkL\ íË’Ý䡽«Öc V(¹•@¥lÊÇñgô.ïù–—wåšî 5åG¯„N`“é‡Ã…5)§TÝÕ=T8sh‹.†É“i=Lþ!}NçËgËc@dT±á$U8±¬Ê-å»x­ÁRŽ)O½*|:´”·a~Þi¢iª<‘ãLú4®Ýå¨Ûð”\ÞÈ´à«èrD7ú®Ê«¬ H‡> äƒkY°|£ŽOLï. ãØ=Þéù¾|VÐÿY¶_›^óid½{r’µJÿîfTÉ9'%Kä<éÔwK’]á¤LUÐ%(Uü.xË ÿrå}@hê¾u½)Fèú+—5¦G]êuB'/õ$z)ïD\ïýÏVÀÑ—Sv°ëä‚O!õq>Š0•Ìx¶ºÔ¼ÿí;¿‰Ò´O75Œøñ§ç™÷ ÓÓ{xpÿAæ}3çæb>)»•Ƽæµ14éÖIy ÅLËA6¾s-œSŸœÎTyÎmü®P­`sŸtN3G$ÝfòíÌ9}»„'(yÿu”¢Æ3‚£pç$ß5°_–Äìfߺµzì„'¿9kŸBÃóomõ½l¡J /T„Ç¿ tßåÒPÀ¯óÏo*Q:èIP Ô SÐi”:Å’j lI/HD )‹J½*„Ь2ÑAG¡“}ÿ/_Öêö'O2Ä÷"s\™÷vøOÏëZàãËæ¥y-<5´÷º9.•s½1}ýoñnáY+ñ¦©-‰FaU>›j¤yù¢iUX°K/åéñQ~UTùë9wôC×(8äÈmÝk€çb,Âìù^»C¬nï=L²z4Ò‘îã‚î/óIG‘êí<{ž½Âù–ÅoøndïÛßfÝD Eƒw3tùÛo¾(ˆN·’þÃì¥[&ÃÏÈ`å£,¹7G_ÆQѪ{# \u´omH¾Ë-Åzœ;à ݤ—Ë´XñSVöö. 9ñ‹'êÍëåR÷Ü'tŒàýðâŸÿ»Äï:i*Ïéi¦²„;Ëš‰?þñ/y¯þúúãL¼,h‘ Æÿ·¿ýmÁ1JÖ÷.Á[ý•ܘ¦3=a•øaäøð k~ÝNclg~x÷AMϽÀx㋽_´ÏŸ…iœGÎÈ(yR í.RŒ»i ŒÊÜÊŽzèÖnŽÑMXúUÎ٨Ѷ4êvq¶SZ_ÃhÉùSþÞ ì5R¦ä¾Îšœ‹ôª”·,²‹~Ôè ½…`•‚Ÿâ =ƒj‰ÃÚÑ[+äv^ö;ë=xï£+푟o¿ùºh =âÃúŽ}K¦büýÛÎùQõà Ÿb@§Ðмi,5ÌA:¸§þ¡I¦@Rú÷î­“;u¶IöÔ§Møêë»[§Æ0Èz‰jØaEæbDÔÑ(pŽÇœ«’×ݘg%kTq!€u †þ>ÌR'ª3—AZÖòmÔA>þòðdç§l vÖÁAëü P:‚L÷¹'­éÅßüæ7ýh?pä~ù”î£SÀV¤ë9b+‚SA²¨­†Q²ßÞ*x– £FYÎ¥œLRJqa^¥¹ö_2)%ÎŽ€b.ÉUO+ÝÍEAR’zm3+¯-XĽG¢(#E$’5ÓË"¤ûõÙ`U„¡‘JzLZi?Rá¬^¯¦¿qˆrUŽ RW*DÒ.)­Ð£ËÔ »S~»ª Uî<×C+†ýqzî*?yK»‘(åE8>ì¯[YÝ[s\¦6Rþ4„³¶17–n5^áÕ<Ï»òÊü-~”¯ÊZE+¾×2ÚRâùSš¨à7§¼Ða)¾/Dys”$`_òtQ8L¶›Y$µœšò¶~rð¥ÌOj:G9²¸5ÆØ©S“Cžž«Ü·°4½¨(–³ ‘~ñˆ<)CF€’¿Rn¹/zTC!‡`”4å³YÔ¹&£¥Ä½Ï…æ†Ü¥ÕÅG¥.6…Z2:s@Õ¤!nŠ×é%Ïr”º®§<â%¥šëÌKx~`N7¤€—Ó"4þ¦²‚gìàÜ˨wèk’8Ô)#)·Ís·‚Öhá1e¨ÌÍïFá]~Å•¥} ·ïj(SÌäS#KâUZ?Ê *l9T©Ës?m–p¾x^† ÞÊ ?r]¤'¾xß¡k.øvùÓ{ Õ¥.¿QDÇín×H™w>ÎÒítjdy™õQ¾ä`³†Ñ“¬Ë…òÉÕÍ_'‰ð›AºF>ÁŠŽCsy¢—êky-oîÝð}"b~Übjg–¨¿ ÖÈÿ¹ñ,²}i}Q(I¿kÁ^ ‡gY” ʲßG–3P=þÎÓ)¼«Þ*¤Ì`ݧ]Ê[½ˆœj ¾:\ü»<|òL¶#‡^:â5YĪ“=Ó^à¾úw6Š«l#aã_#…ÊþÍEºtŽf'€wꨋû¥²^‘ßÃÏ5®ã§° Ž p³ïÕ8¤­öM‡ÜÎ r ¦UÅ*t±+ÌÁ¾ Ñ~ÉdØââæ k“Z €Ø„ª®Ä-…A*J'ñÆX¨Çü”.”ÜâQŒNOôŠG˜aQ瑜ÔÅʯò_¿näSéçÆ½pVº'p«·ò¤+*ï܃*Ó™<7‚n¸„h"¸]¼¼å¯ªÉ«¯ (P¨üѺ¶ºÄˆ±Û¡~U`1[pGÀ×pËO´ ö×®D~+§®¯…ЉŒýšVO™Ååêw ?ÅôâZó ¬+?ëhM§…^ L…D’¥y.¾h\5b†:¥As¢§÷Êã*KšÂ}²¢šrë8>J•÷5ò°$œˆWQ&­P!\«ÔÑE ‘å<“Ç+Náøóvåùz{'ÅM^9²½U%~$»fÀœ«…nŒá[‘F²yYå•V(PŠøÙr¨PzæFr¤-Þì·°nP7ÑqÜú~ü~Nƒ:°Ê ˵–K錼\OsʸŤC¼É_Á犧ºlÓÍô| ë7Èœ¶pâ+?ÿm#AÒt…~Œp[bÓFvü¼QÎ[„'ÕS¼Æw‹õøTúPsS? Õ%’77Aš>ËSÉE™@-<í2L–1}5Æ…NÞ+s¦‡”]Æ1y«\ Wçëgg^9¤jÊ1#GÕflÚ4° ÜÔÉœg!ž¬¥\ÙLaâY(+ùÊ?dÌT+\ê1ñü‘Sø@¢ßu2Ë}À„×>0*z„Ñɸ €–ßá]á½2<|¿«\ËéC¸nh(XE„ÀÊ`[Cì¡/ ‡öÓ™zÝ'Ù†w”Å {ú9Ï$"ßʪJ5®-^ìÃP½°Üvo¾…¢*}ÞñÁp¬ÞÜ_gĄͫ CZµ0H ?"sEV~Œ\- ɧ/¾¬è÷’šø†À£ý-k *õÝ÷ÿW ÑßRxTk$@‹]d~ù¿ý·ÿ³ c“î W£C*áŸùÑ ú\÷Q׉qŽ,έ§V牤AΘ2e¿Ð1½jaÜûUvn`û¶_ý&¼—Â^‰Ð>¡mÊz”܆ûûæ{íS´9ÂûÕOµp®'ÁõeΓçRþ&VŸèI2ýüùþÎ?~9tÀXôc®ÿñïß',ªÌš’Ç”Ž}‡BƒãÜð.íUAåÀã®ï…}ṉ̃¿U'–ò”Úë×UNò¥¼è‘ Ñwêa×—òeç­_"t':úvÂtüÑ^l.8»åíÜŒ¿ÆöðЊÿ6èê»wÒI ,Ý]²½Ôqy$b°éº,yú"úMe°ÝUù+ï”­ò_f€rpI"´M:Sèø§e˜(Õ¹;ÊšžÓ¤ë$Ð/jQ¯óÿ]óêš;è´ÆÅ¹(ÝZëCk£èÞlèÝh|ÒßnLéšbE€n(³J´¬] Êú“޾x–9çÓÓ„MÃxœ‡.ÜÊW©.WÇëÖ°Z*0Á)ÆRªÕðG 0*@†Ëß_5*pá'ØÚm˜3q ! t76•xå+Ÿ¼«DT&yµÐ×}åZ2µÉ¿æø;ûàœ˜Ë}—A%)‰Œ"‰ºM"cÑ6²ßàÜ¥š§Â²Œ„ÆjKâJ0žÛà¡SWÐâÅšãJãGàÏsðäXà78–->hʊЃ.þ3 › =Wy¾ËmÓSB}!W霅 Õà‡^-SÔRNeMœêu Âóx-Þ¹[ÜŠ(ÕûP=ƒ$$MùÓ†«‹ø‘‹,+'£G¹9½XòF=•²W=¼ÌìÒ4ñÓó5¥…ææ{ä૬–öM‡“Ì¡ñ8'dfýnÖ(€ò%Sɺ3 XÕàç†ÈµáÏ•«¢/Ïu¯@œ8î ¶—´_Ï¢!¯x¸¯L=¯â¸¯W7IKCkT$Ë'Ùh ×IŠÏ°cÆÀË—Œ lÌ–¯ýý/ÒÈŸ††÷ª¬F..,„3´ª¼Ã‡dø3nÂiX×W#Ùe-ã%ˆÏ_¡4Ár•…B.Ïõ"?›‹ÿ0y^½—CѶ£^lì~äË€é¶ô*NÝÒxà;cÆ‚[#ÊÄ |ñÒ6¹ƒÈL‘<ë.NjQé&çÜ´~‰ìÀ( ´‘oÓ¨;G°µë¨Ví{H¼.nÂyŽ“¦ûI»î¥ãe9÷Їòn›”ª/©'%ga“–GhYc’éú*l¦Énê”但ßÙÖ\©ot·¿EeUŠân\PAÇžÂbèæÍ Ÿ…õ‘/®¢UO€òx&ýZ¹«R%‚úlÖµùÔ#ÎzqÑ-äÔº¨í^?8×4ü þ®iQˆ|âŸ-·>" ?г‰!Tð,_¿²Mʪa¢åû¦Oõò¼›û -Ö°ðÕh•2t_Ï‹Ñ})R±2 ìá&lýyG0ÖWIÂD+©ÉÏ@7u¿•³fp"¢(eùwt¿“Ð’ÉéTrU‚~3å ¨5°5ò&¦ò÷+en«8^%ìK"KØUÞ|–¼Ä—µŠhŹUâéa:!ËÊÕ¥bµáÕ ß4ô§ÑWþ÷%ä…q~’d“\hRuh‘¯þ¼O hÇ Î t¯4ëg~k·Dí$’±ÎcLI Ä­Ë6­Ê=妼Ç´2X®½<É…W‘ÙÐÛ¼®{H[·Í9@ÇwÈCÊÔéË£µn¤†÷³Í:=í!Rx9N¥wB…襖^ç™ÉW¹¶2N—²Ìc‡Y?ÅçÊc¨ª°Où Ðé‹_²[!Z_©O¥·è"x…C7xu=\%¦ý‹9HIDATä;ÉГeÁü tS÷2Rފ߼߲v£¶EJÚm¼†ö•‡ú]9*è[(©QÿúôÕ6j»S4²Ù#ÓÛÇË1è×çæ>š€@9NãoXËüˆw¬~C=÷ï}!ÉyãN… ñÿøŸ?„9™¦äŒüT‚Gù«­NöKßË"ˆƒ„+€XÿÅϪwîQ!~ò`ARx%þ„ÅUB·°%zA&Hçg#X5¼’l¹ò I‹§´•±óHšI·æŽ:JáäÛÕHÇOEpÊ(C B™&øÂàßV'˜ì*?ÈÛ ¡ÑñhìHÛ²¢«<É+-ü‹£¥p}ßúǧæ¸ì]ÏümŒÙú§ˆÌqQ0†û {ƒæûÍÏÃÀ…Ï•_£õË~¡Ä÷ïDf2”ì`ÃäècXÍÜŸf(®NFK. ¼û9º¬üÑK!Š^ ½ÀqCÛDˆÑkDú“œÑp'g…ásðI¦¦ž>‰R¨}Ûè{?GÝ>Îõe•¯§±ŸûŸ~úiQm<{öhÆçž…g½hÐ6¯ÿc Üìg'ß¹ó2g«¿ Œ¡åP¨lúö«/ ’ÿ;1>öÃÍ«˜ÑžUäІ¼µÁÒ¼ôÂwÀkt#+Ó¸%d“(tB C² I]Ú¯¼b°D9ZUµ@œ\βf‡±vLJ´2Â× LC«ðñy¾óЋ³âô^ö?‹¬9ÏÝš’‡;ÿøÿGÁ>J6çp|é[mpá1 *«!òƒìûwñÙÙaê΋ù€M¶]®u¬-ƒ²ôD(¦G!ê®*UŽ!3ÔP†«J{Ê¿ ±½ó®›Öñ‹þHb‘Æ,^&_èȪ6,ØBeEº8úQÝš2ýæ7ß„ÿ9b½k}ÃÎŽO’÷4Ý¿ÿGŽ^Î ¥Ëyô(jŠùÚ¿Ž·Î¦¯uGɿкFý ›«& à"óüî:åoyR»ª]æõòP$S> ÕCKR‰Û<'ÿ2Ú•ß‚g `gÛ?ë'¬›R÷ë¤É´ BÇJºÒ€¢§b_A8“±© ª7¿›£·N…é¸8S[(1]g+€ŒÇ|ÿðçï úêçOOŽw2Bw¼|Lç`ßš‡L_‘IûûéÂYE7â%½I/2Þ‹nÜèWß}4¦„zˆàYå%ð”&æé!õ«–òÊ. >½ƒÖ ãó=ê[»é!d8l?gNßÉÁ;öfãZóUÒ呯ÝÈj 'Mý¯¼+Bp¨ùwpI#Áãê§ò(}¼ÉmœòÍ%>CDÅž´’l)dyrà”¥¾¤ä³Þ'Ly'¾¢qÞ••\² €Z…;ï_žÒ©ðI¡z…W*D…ƒ»eo~šRƇ¹ôÕ½Ãê¦q!¸.<[_ë€QÆ•ù{øQn »†àóPÆNˆ€GN¬{•Ö±–³€3›QŠ·ëzÓ´Þ'=i6aû^Ìöëz6èðR©è\Ôc~ _÷6ò;ÝUtìÖ·#BSЈ€wctך€jèU@b4’ÿŒ$äà‘Ý|3CÖªïû÷sØÒý̱§W«A»4¬žP”xCnjÛÕB •ý"Ïä‚'¸¸’‰"РŒ–²> hQGÜäÚP“aT—ûJ² ]2hÚ²}''’qØ9ñà~zé9ÎÍvÇ£Ðå ßÂðm°4£¦¬;ѸSg(<~ìà-+â }ÎMþU£„2OîèØ“âa)ú”ÅBË®¿°ñ'Eõ³ï HÔ#7Y ä7ïÜ¿ÆVþ-[I -s¥ܧNìM³m¯‘¼Xiê2½¾$ zʯœz‘õé>UÙBá2Îò•:tÁ[#WŒLDT·£Vt×jVДMï{ʨ¨Aµx[÷y!ÚVƒ6Þó[©$Â’Z¥™vÚK²U_KNÔ²ž«:5rˆC08,ì¸ÆP–|MïÆ­¼ë=¯6¸8 Ñzn©?Ïa©6Ðn¯S }ÚëR|æ›áßÓ£ô8ý€h~á•k­ݯGtàó×r»Å÷SÜ}T@‡àg£…ÓÛT™c„È9ù.Û-8ÊÆ|×þq+þËX†w³@ò$ „«,ÌED°»VI‡¡U’¹âHÍHÑF²ª:T°RlXËhËÒ‚À•ôÖsoýªà“¦2Œ‡,7Ù.žÛÜÅ]? ð7žË^‚è(;zj´›(ùÞrþÏ-»§ØãŸ—ȲÔÉx*ÇbÁ߮ë• ®¿ÎÎAWc<÷Ý#Cƒ…ë[åTæ…ß—¡ÅÍTTÇ™r‚¦Íœ˜uS’•MŸ«iN/Ä©}æ^Ï|ö6Au”øZ[¥TéÈ«ÃÜ(ãÀ{¼Y`?ëݘîZœ%¢5ÚÁ9}Ѫ|y3üŒFõ¹= UéÄ€8§hRF¥ÔVióÓb½”©RtßÉÆw¹)ŸÔÊ*£àd/ºwS&)›Ï_r(ñ:‰¦qåÙ· ¶•?¡¥ì;u¤†¥SÞ:\ËΆ¤íÏ·ÀèùÐÈjk£¾ŽÙxô?½XùÇèô?¬Ð;¸Ç@êÓ$CÙÐ/ãÜlïy+š ß.—%Ou³üT9Â)ë&|nª’¡·zŽuH’š¦ígxÏUÑ–Ÿ)#Û{²c$ÎÔ ýXåô!šRjÎÙ·ÓÂôQôfÒ@“ó{YSýihžˆ¶Ðjü‹“køRršøð!ñ$cŒ¾Dã¹ÑÏç÷“C0½'ÊÒ3ëÎðr÷’R¹Ó¶ŸdX°¢w#=†ð7VôHŽeMå~uØÊµm»(å™Pa6¹Àˆ’0¬=ѧX#@%È _p‰K˜Ö•Fð«.áÇÉ7*Ÿå'Ù–€ ¢jm4é2Xø ÌEWrfÍÏIO"ÒÚrñ ˜M¥âßÖ3+´˜ª‰ N[ú1±2 »òô4|éî"sÏ}úaz–F\¯þŸù­éù œ®÷%èS.Ãx.¼”× ½åÉ_JåF„»'UÖxp¸•°ðÀšó̱[íŒ^‰R~à¸á¥ô*UÃâîÚêg6óцk}äF¸<äŸ6äŸÞA)<yÉ4hTË(Áôü…£Èg@ºx6ÃPÈ0.!‹"‹.IÎ0é¢OnªãÓG±@{Ѥ)m»8Kyï‡&³@.iáw…ÞhÕ‹ÓS3ŠbíAÞÝÚÍ÷RP§Ñøޏ —¢ÖâËÀŸ2çrôOG*ÖZ)kt‰ã‘û¢çBÂ’¨êaÁ0ÒC} }‚y s‘ ÙñŽì´liè³jPniš.õ>âúìî<|œçü}Û¦ïf+©:Ê«ëP„Jý€nþ’Œ_Å)·¾—®õJàò2E܈üz¯ýò±rMš8ýÖoä/I¾ISÃO¦ç …%tº4ò¢õVêYâÀ×hÚÌFMå¤à`c˜ßÐD>\á‘6> #ìD´¼ïþ凟 ž§ç÷ýwÿ#ðnʰŸ)õ4çªqô-PÃo[áññ“\ÙkŸo‹Ü¼ícK‘Ñ@Æ:ÜŠQ‡S*Çô–[< y¯]Ê+Å/×d˜Û‚D§=òä3ò´—õFs?º[xžf?EbЙòñ©é|n7uqzýâ‹/*mòñüùó¬qx™:÷¼dÄŽ‰̨]TR¸Øù—ÿþ}Òe²þéø¢ £§}8çëÇ_$ŸèQÛ6ƒ@p b)4=SóóÃ{˜l*P¡U¼«»¡Ë¼¡Ê«Õ[Ɉ†ü2‹#|G'ë»'·ïf½Q`‹NÈf' Ù7ºë̉£‚`öFže?þž&?u±ò­Ï혌ø‹G Nƒ²”6ì¿x$pn…é•ûŸ?<ÉÔèq¦äìT‹V uœ‡r¿ŒRõØÜ?~Ñ‹dRg–?c½¹Ñ7õðü|Tà:4„ž?#„“Û ‘#û"´?8ê÷€£ð/¢è.„ÀL X(rŽ ™'U©õˆ ö|*2Ø9cýFñŒŒUï küÄb.PÂÁ'MB¿ÉCUí2:¬#`$ºR-o_ÌÖëÙ„ŽwíQ B\V|âV˜„¯žQj¡?•‘ò¨J¹äå¹S—{œšär¨IOƒ¨Q†<ƒ}h[*U¡“§¿)´8ÕYqé…èíi‘ÖáÓX·ã‡®÷-Ü!Gõö-ê«ù6´È…EÛÐ0Ò³Ñ ßv(«^yÃoÃÎÑRh°xîPÛ¯t—+$”ÞíœRù*FÛ«ô.²b]ÏäU G¦×–F‡ò>IÃ¥1TéчQ„6äyäÚ=€10/šY8w~ž5¾7 7Ë8ŒV 2£” Þƒ¼½õ_<öÉXsÅç,Êg?yOÏŸìԢƔ®ä3ò[°Å&¥îz† åyêûñ[^Ô!B‹wñ;éM %YI,§!A`nƒŒx¦t„¹w·Ãš‚:L~–ƒÀÈðN õË̹ú 5*Ö©÷Qà˵a§alk$Mm8U‡!Ó‡ §,ªWPé·F Þž ÿ¼ãòxÅ-máÆ¯ìOK±¶ÆOAo`ÀÖˆGø*ž=ízÿFÄÓ;'ùBXõlõnÇX,9Âd É“÷FîÜÙNyúŽJQ<Xù‚Þᑵ:H9Ôéd¿±¾ºÌZ“ÈÇÝÈÞ™MeÈ€,á;yõsQeá`p n+ŽÆ) è)CÕœEfŠÍ‹^™8—cQ5›«÷>=xI )‚ÖîìLj7-DO g(¾öˆ›OÅ×ÞüŒY'ô•Q[8DÆk u›BÔh©wÐÙE:“¾´”°ëIaRt&ßèm»Ÿó*^¦þ½È€:hšoèùÏ…/£Éáúšwêõ´grúœÜG7Ö…GhÄáTÄÓ¸zŽÀ;Ã)†k' »9ÑbR˜íŒ¼dU:D˜@ìfU,Ѽ™¯ñ9ÐF/Ñv+z¥Ž~ $¼òyáKð îpãÂúð48¥¬CûÁ}Ê¢üäc}‘™Ñ :Ÿ÷z'ÑIÞˆ ñWÇÑÓœõQFú ùï¶|d´!Y$ýž¶"ëmø¯ÈÐÈ¢D½«Ä {e‚,åOžk:T™…E—\pêò¯pø ÂWJ >}#0“gy!ï讌ú‚ð¨5)ÏæcCI‡üoG’HÊU86RYà ¸ÐËŒ…츉±”Ô—’D7·œò{RÿR·’—ƒ»Ð1¢Ý‚$ž>í _æÂ¯©Ûs¿¡egðÙý~2a\F@Œ`à40œÞ”ŠÁ*´:Ýç2ÛÙ –mu|⟛»ŽÐ?}–£@óùÌÚ&•³ÕoÜÈöµ™¨ˆ–‹Äpp ïkÁ[`3.~ê!%$p.É]”(¡¢>J¸‹4³µHUÆR/•…å½êú}‰]è¯m5møÁ§ó^bmðnü¯è`”wŒ+41Ü鉪"”çÁ±ÏZú¸È"è–,:„7ê®Í“µâq??8|¼Z¦÷óÔxÆ@±u)ëæ*½™ýóh¢RŸå0‡áÄ ½Ÿe‡<œfˆÜ𻈉< ¿£kð½Ê‘½3J©¦SÒ»D#=m_a;´:¸‡E,´‚ìFe«ä§ôÒ$×Üð}FБ3"Œ†mŒïôloå„Ì““þt(àUz 6G[ô—TÃ?EËŽƒ$çkl÷nç¸ùT©¦ž˜ð ƒNøZdEÉü0®ÿ+˜rè¬19lã=S!?ütÐS"QÀgià jÌlׄ‹‘O†»qiڇܑM;7ÒIˆáaš¤ÏYhþB+ÙlDýÆÁgç Ovþ+T~ä±Re]‚6;|ñ¾hžæ,°Î’ÏÔQ˜^´q"!g>d¨#éj”éŽ1:¯©kä‡|Э»î‘'òGÿet=òy¯>9î(õhÕÐ/´I#¼Ÿ¬ííd+[äÃtYäî8‡/ÒwY„ .º×-´X|mºÐ§f‘JÂX½õ1Htvè›ÍVf´D´ü“ õàN>\u†Ñ97½QG`'­³M©óe(¦îêö”BcRGKvA¶øYyŸ†_Á€Ð²gþíZOò¥ÃAsœ)Ñ“'Z&ÉèD[©á÷¦KÝkôã¤þ9ÂOf A3@XµÞ8C¤Ö¨ á=Ž2fy:'~=ÉA) Fšûúîû Á­|;ໂVöºåªÈÉ>•* K dýÝ2¼Ø [„ñ†=¹!ÓŒ Žö‚sÌͳ(ØÖ­»ØJ7BŸºÃ dò‘ç× ôÝ»zƒÉ¯pà—÷!nø~⽪‘<—p¾*]w£”‚«ihÐ*œ0¶€Ÿíüù/Ï"èzZ©LY€uƒ¡¶K¥Ì†ïÝ»#¬ç² Wk°fŽ‹òÁ³© ƒãû€]ón~¶=!äÓ³lCÐÂw./CÿÀ*T¶ôs¯qn‹ýðÈiÔÀB6¤å@´¶Å®¦ Brq;ç€ô‡aÀ£ƒþ(’S×ÌÁ;©­BÁ¼Ï|d#2ª1Z÷HåÑ Õ¡ÞB8¼Ñ‡LSè ™×~÷ÝwÝÆ¨÷¡=Øéûù³Ü3ò”ù|çO¶/Ü(£÷$ÏÏ5–Yÿ‘õ$¿û]¾ÝHá›sÆË^ qL‰ìC%+—J²{tõP4!G¦D)õ `"•BÞÌñª ÅY0 PO³¦Ô(Áxö¼!Z‰zšoQ€edèš²¾ ôÁ°ãìþùê«|M°Œòî$ôˆ€Å}Öƒ¼Ê<¬áÙžN̲ˆ»÷²k(óïLvýQz  #¹Gˆ“r×üÔ'½=Ä)W„-J*.1ÏŽ7ÞœcÅËcþ^>a Ö™YTö*sÚ·öut"9î7`笾±—2WC?Æ#yéF>çDW’ë,<=È|(½¶Î̧ÈSo­…™ü÷ÿȪéLŸ–uë0õ÷IŒ\S tßͯ¾°–ÂBJ×ÞΣÔoÐ(R$#åþ¢òæf+7á¯zèü…®—Œ’èîC²K?2èÒ¨fÈx憖äåºÃÓT®Qú5²®ÊûÒIÖÝ€äßb—oøWé•nHº#¤•Kç„¿pký¸ð˜n,×|ŒÄ×èšz¡S‚[êÏèD¡„/oºèE×Ôý%“Ï(Ù's„8c(DâyF`ÊOXÏ^Pa2øƧç”}òà4Vön†þ%k·!P#Ã-‹ìÜwc Þâ™ç4½QˆQ þô¼U‚(•^²T‚Ò”4ŸÕÃä4ü5÷¹òò­wð;<ôµE#*.\gáIÏýòo‹?Ö–íôL„w}‡ßÕ0d@C«á¼<9*X½~óžù0J¾Ь_ÈU_ ðä0=pÑ Íˆ K>4üwï´Ñ¥Ñ/ùHO DbrvšF§t”ÁIŒ=- ]ˆ›45áoðœkMtãhh„nœ²xǘ¢ôg.›2W(tôüo+y‹{aÙ>ÎÇJ4 ’ÞnÛœµùV| Þ»oïÂK gÒÉ…rÞˆ¡P°$4ɬX™bEž” Æí6¢¸ñè—Ê?zõø:r仄²äÒW_fß?ˆ¯''¯v~ü¡¡Fù¬øežM)äç»éÑ&/å™5::Ò òG þŠŸA—îP,áÔK@”ðÙ\V9ÃÏó´(5lŸÐâUCrI%=Ó-‘r_Ù/ÍX"T?!¿Ya˜ífÚÅHà)#6 3Õèe¤2þtùµòœa·•§‘õνF}FHɆ²ÓÈ2bfo~¤K{¸ûðèp#:FF³ºƒÄ ˆÐçà²xþ`¢¥·{3#¨z½]æ–¨u¡ÛÏ«âz†w'1J•—1õ,óè`x1¢Ÿ· îL¼†y,¯{¡©rرÙI™§'Ù%È@ä1*èÞe¤’l]^\à Ûw“½›–“ŽDtÏò±,Pdzvoè „öoºFG‚ÿÿÀ–ôo¼Å(Å7 Ò3"ö¢ø8oÐ×Ó0K#椺>˜EÀêŒä5‹—´š¨/–ééDXY€›˜Œ´Å@ »’fæÅj€0$mG•‚y›‹ká¨'•̬š[Š'¯ÃôXÁ2‚ÂE„äM£¯í]Ê¡âöP¥ü4BÊDà”W^0ظʷ…´<¼n”åƒF“_§#FôJb+àð;>6ÚÅk~+ʪç—õVûj# hNƒ¿†*ÁšÉå½:åÖøÂí¬Þôc¬ô9ïáåEñꅷˆ$뀛†¢IYxW[œa=pxbÝ„{N9SfI+÷Ã20Bg2„¼ËxN^*zDA¥ÓD˃²ó[Ó "¢ˆ|м`è¨Q…#¨LFzH\äªËäŒ×”xî’¯º7:Q– !ú”»øFJnå ¨f$šhÀ…2ª£TFlp;º§QŒ ŽÎØËÑ™q‰Žì€Ö…è74â+§£Ä•9cæ$ uˆÈ²‘œã”Ä;!»iªSTDLš˜¶¤°å Æ¿êwFSÁ¦—…¯:Þ‡ §UIÀAœ  Ž# ã*Nr¹z— ë04d»NÂÂQ½£äêãë®á×ð¬dqIñsŸtà:A QÇÍœ†R’ÞÙj¸§N» 3l¤°YöQ“¹bd¯gÄ Ãá-äa<é{0Bé˃t>a¿••dc…›¶¡ÔJX‚±½’zê~„9FX~zˆÙ¥!]z‡ÔZM_uf1@"°c€8ûœ¢3:‘"U%WüµÐ°t×n+ ‹ïêuÉ}UŽ~Wé,éNŸÂÍhbèguãiDÅ\$Ÿž?…3׌ ļxŸ¯çRÑ} õ<_ƫᄭ/»g¡A¡ô0g]<”‹C7÷ÇÇ 7y¡—J¯áÓ[ê]"¡{Šb®tÑiá«9ÆHR ´Ž² È"+ U¹Ñ»”Ê‚³|×ÊÇó›ÞHm¹NÏvΕRGgC¾ÂhðÂ[hÚ&ç ¤W‰_”®Æ*F¾"‡yÿ"' [¡Q`è!ès3°înÍ“¯da¸E‡.ä¬g^š¿åU+¡óº•¯\ë‘~ÍÏ2ÎSG2êdD¦ø8`)|(^'^Îu°Æ"IŠAØÐLÒF)Üü*÷«?P9OÝ;ËT–z—Õ!™Â9HŒô°#'¿g/Э[Ù¤½ª¼á‹¡h0QËiÐ7.´¹º(Ð+á +÷:tˆz}7Ç8ƒÒ·@óùó6|d£ÁƧÊN–Kž›ürCNFVÔ7¡g÷dÍG6¦‘È’Ñçø„°­käÃî‘DM<ú*eMÞ‡‡èÏÀdÀ)»*œ4©D0L ʤìòz”y‹ÿôa“—òšë?Ì(O×™ðOòiÈZlœü1ÿ §ì²ãøªg½åO]£+•Y}¡ç7nêa=ÔÏ’ÀâÑ¡ú¡Ñ—N?7- ý%ô¤:áCçüÉ{êêè>uÒ½6 O@¾Ì%^}Îî³1F¨ il ÝS‚ÜÜ₞ »¹Mbdõc÷82güÔT¡Ð³ç m ]³e7= Ž÷•ÕÚ%~ýÞq›ÜRÅ[^‚Qß™.V†ñ.-- ò¯ ÖðÿêÙ›-~Wã/±¼æ>èròi¿Åc…¡.%™F¤`­&vî8ˆö³¯$䆫gŸ« @áàÇûr¼rua‘ÛƒÌqúÆû^ø~°óŸÿñC £^{J ç‹VCÑeAse¯/KNñC“u>kúÑzŒSÈŠ¿þ~:cíòš#UCWå ì´Þü+ú¡©òÂK™Ðtéí¯§Ô瀭m‚w¸WÂwÝ+¨Wi-Êó ÁšVVyîßzQг¶ÍZM·„YĵD·Æ.2ª+rÞÞ­SfÔ=Ùöë^{…ˆÜâ[¿ã ê·<¥ßtoú´ñi8ZÕʾåcäd`b&o8£Ç·2Z’gßýé¾(zyžEq=JB62bã„?Ä^Ù” b›Ÿ[j iuŠŽ§ð¸ ¬x„jhaU9˜·%{wîX¯´MsÉŸƒƒz¦ù:ç<Ìü>=è]¯ °F긦fJÉ:ú´ÀLå[ `õÐ3:ù"£qÜînz0åZOit•‹ƒåšÿUª¼ì×Í·õ<šÒ+x«¼b3x*•*2\©$ ÿ¿v—½#¬ßȼt}³>Ö×1+¿„¸’V#·IøÊ»Jióêµ7;^öŽk èÆÑ_}õUÕYúqÖG/Îçn|6ê »ŸJÀÂÕØPxˆ9ï4<\<ïYº¶™ôÙêzB,Ro;WHa Éƒ`Ê‹#^ý¥>aZÖ |…Y ªÛR\^”PÆâc8û©è9úòîÝ£¢¡Fßh¦UøÖˆ¯“ä»ömt¥%]ç]”Ñ·pzÖ5RoºÇo=Bc¸—­ìÑN:·¹DµŠ°ø] qM‡épˆ'í‘Ïïßy3uuô!H'œûÑ‹Ó>ÁùsvŸ•€Pk‚!¢k”$ˆÐ„Y8Á¾iÜ‹u(TGgª4*a™°¥­óÜÂÖŠ‹öEkaY*FËcû'v…&®Œzì«>™!£QhW¶Sè|'µñ»úüñž4hçÚ6þC÷fpî½v®‹+Úklõ¶{.Ó¼¡DWó-j,à5W¸áúÃwdJ]DÿuœwBËÀV6º·™(Kœ¤ `Ý(ýÚòÃyíйåÆ.–îiÀgÊ¡ð^<þž9 ŸÿÑ‘Sñ”=U;#xÎsRYÀfºDùñ½éаïã ¯±ûë{´á@|ˆ]VÐs]ªÓr'ø Î}ó–ìµ¢TNNùÐB½v?—÷®yZIÏ=c¶®Lí8KÁpÿqæùA«ÏcCd3Â¥çÕáÅ-7›çñÿ°± ý<7kÕ­UäjÐò¶<Éuâï)ÿÀUŒÍí:Oô!#sôy=ss®DËšZD«t féQÓ—½x8Ók9ªƒ³*v~Ö oü^‹`[](åÒÃË:ÜÇ©ŸÈÂö×¥xÅoè2åšôæ¤Kù)û„½’À/|˜´ä;õqà´GëgáÄ™ëfûÑ¢}vÀºäˆ¸Vˆþ±x×s^AÀùQv J!< ®Gê¶üø×»‚éyeÕç,*ä¿+¹Ât”¿ªÖôrÍð^5߆G ܼû\ÝÐŽpÕ €„z¬ZÏsá‡k”ð‡.Û4¶*V/¾ÑÓaäá“ʾð§i€§é¿–Ÿë<€{§ÑüqßeË98Ïœ4ÈI×in`o«ãâýð>k#\hM†•œ)Çh>3”eŒ€eŠ=èˆÖ–Ñ*mÿTmõœfsór%Zu#¯Íñvž ¦=ÛuX‰×e…ëZi®ùå^ùAeu®eqâVO2|©ÚŒ†¸r|ðÎ ’ÓòÂ+Óu´L4ƒ@»~ÒVnvïwA÷JeCË<˜˜çz[í²ÏZ›–ë6lJׄ`ß„ú‘ u”º™2B#r@6\kùáO~èG—©|Ôˆ@Þò/÷¶@‡Žhm­Æ¼ºsÖ<Ç;¸»¸ýçàÄ8åÇoäaÒÙ”c<~!”.Ü óƒhl¨ß® >ÐpYãð.åû…¨ýªhŸ­€pˆ©Òc"E`Eˆ)8sÿäGþøc¾/Ø Ðrg´0•j„$üíoÞ9«†Sa¦Bèo¿wª´¹Ý(4´ß rÍIÕVš¶rá:8 ŽÏÉuÃÐny„€™³ÚAþŒ/å!üëJ÷>˳呆ƒ¢Ð#¦4쿾~öP¥ýÕ”6úZ¸´Ü@exWú¯å]È3'FF”³šÀN[ãÜ=ö¡ÁÿŰœo‡î‚Jgº‘Ge¶Mp-ÛxCÆG±ã/ ¿/ì4L0’[æ[”5†‹+ül<æÅɽa‘ÿzŒ×òXjýÞÏ‹Jr`èWüZÉ›²“©µõŒ•Õ·@28÷F=¬]Ù½•E”Ùåp+ÓF»Ùøj÷7i“².Ãß—Yý¾“i’ÃWxùôëÝ|/¾‡‘»¡n™ë„‘«6p–"ý<¨Â&ÈB? ¢8KÜ®ÿ-Ÿ«ö{øžŸ‹ÃŽŽLyVVýÔIsÐ#ôÚŒþ£ÉÛô£x½´†âA¾¶vžrZtŸÛ·pFÆ) ƒyÊw<ù €oã„[_ê ôÀIM&Œ4‡Žo“þë n |¤’K ÿïÿû‚c\×÷¯Kósòûl D¢»ÇHL&У1‚…‹ø£)¿±pùIA˜ožUŽ¿t…=WØX±à„¿¢í*fÿˆ?Ü]ð#$ gN¸5¬‡Oø³)WpœR²œKåëc”c;@i} ,Ó³[F^|ío¼}½œ2¼-ý‡kyhùéáõíû ?‡_ ¥;νrÈÛE.ù­åß!YÂPúêe?õŸµ F¿ËÖ=¾)^1·´7×[«Ae WyÅÛ¾©»úõ¼I÷Z¸©/æš_k…Î_YNƒ?²¸®W’—æ û‰!p3ý|?`çFF‹òñ½ü˜û ÃXìºØ=ðîT ºC§yþ›ðZ[víq]™ð’<ƒs ¯n"\»§8êç„E+ºŠÜºÐ‡Á(ð¼Öä Kœ^|k×@ËÅÀkÙÿÍÇâEp„“û5‡§wîåùšépÂKG{0éI‹l€Þï¾&¹·ö’Þ:}´”7ýzöÖõ÷à>kׄÄü!°{Â9`˜N¡ˆCI + GÖà{vMÃï˜Qá]†¯ÖqßÄTy‰‚ƒë(4ï××›ÒùØþC ùÂoè Ž5‹~.4V®éÖ4’×T*øÀAÉf"páŸx ºÄyú €x.ï†-Güçònzòq }Öeø5´š2IC¾œ|&}eÅ£ÁU™•wÊŠ_ƒ7J^wd^zâ~ 7eCÃ×ñkü†ŸÊ­¬ÓøƒÞIgëÈ@Š5 W÷ —ƒq#O¾1zˆ'Mé€òãNšC÷y~_pòWù_‡üðïjù®æîÝà O¼Tžñ÷Œ¾àÐ“èž Ðwâžåç¹x5ç·{’ÏÐvîG§xü\×9M¸)<5Àà\Êë~Âþü×y»—.ú‚Ê%/|›¼'ßÉûzüÏñù³7†hˆ:ŒŸJ‰øÂÅKá¹F¨……7ñÖP<Ïe„ôìòþm…ˆPË7E1•`ðÿœdhÎð!†³ÊåZ+Þ©¸Ã—÷ ¥-ÿq*›üñ€?œ wóžâÍ”A|ï@—ðæìÞ–þk~»¿.ðY€Ù“>ˆFp…08 éûà÷¤³¦$O~h¤ìàL€h3#bpwͦ²<¼=O£º¦ž#ü©|¦¬h;üUæ)7ø6N:ðšôÐFzà\ê€ûqÂrSžñW8y*|Aü‘ŸûÉÿ]ÓýÔáÿn „BxDfŽâUI]„Úá7hŠœ8kà§2€â3|sœŠ¿ÿs̺®„Ã:èYÂ^ÿsiÌwƒ×ÐÚã(¢zÂ>áÞnÒ“'eöhÆïþáv?~\<Áç€×Óà# ”Æ,Šò,Ìàî~â€d@šä„Ehˆy9\ÉÛHäQ~àä3øüR:Igœ´\ppÉGáë‚'|À‘}kbÔï§ŒÒýpM{ù+—²à5èYÙ5Œ ‹¿}ð gi ^Xï\ø¥ñSÿÈïZ(¿ðäYc»Vàc, MOqÞ§›táÁÁ1ùÏÿüÏ›…füàNøë8(ÿ8÷®á¯2“ÿAúmžÕ#Û§> 3²2ò>i¿+|‡nCïµA>ú~Âü¹<…¿@é+ûðoÒZü\Zoûnòçžl þÒYóãmÓý”áþ® DŸ ƒhÃôa2Á$Àš@ŒòóNØü)Kpî½_+|aßÅMÅE4 ` ¾àà0ð]òøaá¸V@×qÿ8 …Ê„òS¹(0þh9Š :{Ç]‡â‹Ã`=Oúà\Wžäf Fòp]ž„|ñ~ˆVd …4iƒïÃÁy­`Üóƒ“k¯{å&ËpRn ò~Nnø5ÛÔ´õγòŒÑÃoí”-†ÏG|´™r Ãkù–¾Kƒ N¸ÉãCÓ‹ÌÈ›Ñ2><®—sðy„³tÆŽ|éäT.}\èNyNšï '¾|á3#Ê6eá>a¾.¯y'¼4ÈÃÐ „?8üSö÷天“6H†æù}åó1ÓÙJËÇÌõWäµ&¶ûˆ‚IëJ¿èu|þžAáÅ#PrgþmОxÒ¢°ä4@ü¿IkðžçÏÂ\SÁø½+=Þ¥<“68y¡Ýð‰ÿXøCç‰#÷s ­Ñh>eš´×¸áƒr‚Ê,ÏëŠRøÉWÒžKœÉgpX§ÿ¾î×å…Ãðfä½&¸ÂSaøMØ÷…ÓûHGYÖõeÊï\èëB롃rã7|PNïÄWÞ '–<ò§þKkè4pòyŸpÒ–7\§|ðq /ß6Ï¡‹ðÊ8tœ|F>Æêú ™8##â¬éð¶8¬ÃM¾ÒQ¶1’§|Ê<å|]¼µŸûuzâ)Ï”îžÁ¡ƒ²¼/'͹&ÍÉgžÿÞàßð&cG\†ßZp¼a‰‹U<ðzxqþ–›8 |ãºÇÂ.ƒ«ô&ÎßJûc¿‡ã(Æ5Îü?–à ‚£ Þ†?âpð¤pÐäÏoà”cÂãÃ(‹µÂÏ”CVø„gü†gz”ðR¦)Ôã# ÷ÖYÀžƒ/úº”çú½°®áÃ@añCYÝ»ŒÀñ{€FÓãÚ­ ÈhZMúò]oÏÊ­œ¿Æ­ãOù¡‘ôÑ›¡;2O–GV~M¾wÊ'OùËoÊ^7äý6Nzkù˜ôÇ_#ƒÃÛ¤ûsa¤ý_ÍýÝk¦(•}Îõ&ÆbŽðÍðò¤ñ¦x¯ó>á3ÃàIhÿ^\眧óü¾!šqàÐ ÐÔõ›ßüfsÿº¼?P|ôÇÒ|]\é¯óòL&ïuœIŸ›ô×ù­Ã~¨{8 ½ä1 Çà«,¦(¦LÂx÷9º¡çš_ãr 2ÎóºüÑÿ·¿ýífH[ÃfÍÀ4pëðÒ@»1ÄõL€“ÇÛ6Hë´ßö/ä34ëä¯_ê¤.ãäãt) ¿µ¬ˆÇÿ}8¸¸ðwîÁ5­ß&Ÿ5>×ã¯Ó}›´~IyüWr[éø/PªˆuQÖ³öݽŠ@¡ÿšJ¿ÎOåÅôºüþü~úµå“7~ MÁ¹Þ&mñ)˜w)Ãä%}r0=Ê×å'ݹæý»ä5q~ \+$÷‘qð'¿Fž'­Ñî:¿ÖåƒÃõç5^âN/Z™Üp3‚³+ ÿÿµw·;ªÂP†ùåýß–÷büküŠ'Ëdåì4´–’¯ÉpèîîS´[Ïœà>Õ¿æ[[÷¯‡Ø~©ý_ýºZ*¾Ç¡xÚׇú–“sH—ÊÁq4>ÿø¹˜ŸŸ+Ù¦íÓã’XGŸA?Ïçó»Ël´p}…À@ö%ÀÿØ×|2@²(²˜8 @} Pìk>  €YYLœ„ €À¾(ö5ŸŒ@,> þN;õºµIEND®B`‚eric-6.0.8/eric/pixmaps/eric_2.icns0000644000175000017500000122561112310131042016142 0ustar piotrpiotricns+‰TOC hics#Hics8is32 s8mkICN#icl8il323l8mkit32LÐt8mk@ic08:ic09pWics#Høüüüøð?À?€?€h?ü?ü?üøøüüüøð?À?€?€h?ü?ü?üøics8þý¬¬ýþü{PWXƒ¬ú¬‚R|ƒ­¬PP‚||¦‰­þ{{‚‚‚§­­ü|‚‚¦­­­þ{¬­­­­þý{­­­­­þ‚­­­­þþþþà¬ýü‚ü‚‚ü‚¬‚‚ýW‚‚W‚‚‚WýàþW‚¬]Wü‚W‚‚þþàþþàþþis32 •£”|††mdu˜•ˆlN„|u,W’t_PZƒ …‰’ZddLPTÿ‚ Š}wfaVLDMKƒzfVOHBDOmƒ¿z?€@DX…k62DAM‡ lSVG«„ÿ‚ »¹§¾²¬–ˆ§—' ¿µ™Œµ¤ž¬°kNU ¥«œzª¯Ž© ª’K‚ ]sMF1eSCkN•£¤——Іho›Å°’X1„¤—6wÊ‘T>Kƒ²½ÀyˆƒYDAƒ ´¹ ynh[<8<ƒ±ˆb`XJ99mƒÿ°K><23H…̘?*,/4†²_3130?‡ gLB;¦}ÿ‚ ³²¡µ¬¦‘‚ ’' ¸­’‡¬˜¤¨gGU ¤–t£¨‰¡›¢<‚ WkBF1eNA@CERgŽ §‘\47==A>>EAMs ‘„Y7/056:A?@S zpD;005:BA:Cb €X7339AH‹™°Ñ¾‘KSœÎ½}aYNHHPŠÿ}¸Ïº™]ƒ®‚”^]LBCB*Š§Ú·ÞÄ”¬rgTVV98::Š¡´î¦‚xwpmXWgjL-6:9‹¶¸ˆvheiKhb‚476@E‹й™pgdZae€<>,8?KŒÑ•f^`@chU?6+3=NãʇDFIOD<7005B]Ž áÍŒB5854/-23;b ο€E1,*++21-? ­ YD4+*,01(/V ®sB5/0,//')8n Š\5-/.2535:C‘ ª‚eRDKLPNPU€x‹Žÿª¿™ƒšÄ£.޲Á¡UÇšb¬‘nFf·²³i‡U¸º¡ÄˆÈ±­»Ácœ¶f ¸š»œ,‡ªÐ{Y¿¬)¼ÄK…Ù{oËmÀ<-ˆ±É ¤Ÿ~ Á—½ÊK…¾‹ÈX€ÿ‡±Æ?&h0Áª·Éj˜ÁÈk3¢T‡†Í¸¿Ê}&ǘ̶—žÖz²½±Àˆd€{{0ZwSiŠcW…OD€wmAãÑ1HN:b’ fŠƒ™’wO1=# BfІ€¯µ‹NV! ŽEbXsChSBcmC _€}$V>8NP! ‹3‹¾¯{.#=DG>-! Šÿc„ ‰…b1060;& *ÿ‰u©˜“hFW923&  Šk~£oB;4()  ‹zyI>:'#  ‹¹zD0$' %   Œ·d$  ÿŒ¶§[ Ž ¯\  ª‹@   …b " Ž7 > i/  ‘ wYC.!!&)/8€5RŽÿªÿqfƒXiŽf{]y[1?gS>X'pop4ˆtzi„TV†sp|8_w=^wc}f‡dŒK2r}„,S”LDŠ?€["ˆq‰ilhO‚c{ˆ,R€Tˆ4‹r†! :‚nyˆ@^‚Xˆ@`.‡QŠxz„N …ecŠxX`‘Lv}p}e ˆ;RNM-K0AY<.W0&SLE%ãl8mk)1;1fé› 2PTŠíôû—¹ïåâÿøg¥ëFÕðÿÿVQÿÊ~öåVõÿŸ¡ÿ£pÿ ççKap›ÿìííÐ%ãå&¯ÿƒ;ÿËÿ‡¥ÿy/C¯:àçÌÿÆ>ÿØÿwwXtÿÓÛÉ(ñìéÿáEMÿÂóäÇý=•Êľ^·˜1 Î°rÍŠiÉdzˆ  it32LÐÿÿÿÿÿÿÿÿË¿ÿÿ¿ïÿÿ翼Ʋ£¤¤Ÿ‰‡†Œ¨¿åÿ¿¶¯’‹„xrogbco€€|}|~“¬ÿßÿ­|…zic_[X_hZPOPQRVi{Œ‡…œ—ƒ~†…›Ù%ÿ¯‹omkXVUWWV`jbSOWYVV_it|’Œ©™•}widwÿÓ)ÿwˆmbhjgsnn|…›®ÂÊÆ¢—š‘‡}„Љˆ‡¥™Œˆ€ptqSTžÏ.ÿ“anhbq— ¨¢¼ÊÛâãäâÛÕɧÅËØÕ»¤†tn|†yƒ…„|fYZFiÿË1¿¤ssoƒš¬ž§®±²Ç¾ÞÜÎÉÆ¾µ¨¬±¢°£³Ÿ|ngxxt~‰‘Œq\[IYÿÉ3ÿªvr~œÌ¾—‡vtŒ£®™¿À½©šŠ‰¡¯’…‚kS¹ svx€‹ˆpmw‹”~iZNV¬Ç5ÿ¬}k…qddn[>TLQ\l‚›†…“•£†ss‡©£uZik_½šz{€€ˆxik{ŠŽˆ€q`UNÆ6¸Špq–y?¡b 6x^VS[n{m|™‰‡nfz‡‡^M]x±¦~~zŒ{mevŠƒxsj`\LxÄ8ÿyook@!ƒ˜”2 uÀ—ngdtœsvœ¡›˜sa]gTR‚“¹©ˆ„~{Šuqnooqkefb]UŽÂ:›~phaq]<¶^@j~&Œ¨ykoŒ¥§WG^XO_‡·’}w‰¤Â§’€{xrsusefe]^_U^ÿÁ;ª‚wkejip[gEsU7#4dnoqˆmt¤­ªr˜ÐØéφl‹£¾Ÿ„y€uqnpqmmR@W[[XgÿÀ;‘}nfei¡{†S?>:  J—|€‡^hª¹¿ÕŒtœ—§Éš’Çű¡Šqfnfpqgl\*>PNt¿=þ~sew|}zZn%38 < ”~Vˆ³ª©¶ÅƒJ…€ˆŽˆŽª£“†dPYkjeM'*DS;8>q¾çvS83UxnV@<-.€, QnVqÀ°­µ¿Êš6wz‰f^Yu„wlbN[cYHFQ^acOOU‰½?ÿ‡]DAZtYBFNœ—*&  *›ª•¡¢¸À·À¨)\opwŠbSXl~yXDF7;KNOTWTOWY¼@ësPa‡œ­¾¾žwK‰,, R˜™—rƒ™¸¼±°¢5Acjl|fG\q€€hB>??9KPPQQPPXU»AÄylv„™›ž— ¹gIO'(! ’ž€Wsˆ£­©¤¥a/ejswqGSphCZ`p85`cq{ŒŸq!Niuolqt_8YodV1&=JFHNPBU`dISRX[kÿÿ±E­G+(&&9}¸ËÆ·®´½ÄÂTf¥«šƒL*Rd_/L^hxƒ‡–J'Xluxz_,:i_[X[F14=>?W\XSDNXTOvƒÿ¯EŸ‘€Š™¬·Ôi¦ ¤£¤ ž¡©ZT„‹‘œŽ6fqP0kouqstvv~\-MXD*.:YROPRTUUQRIQUVNMWRG_¶Fª}{ƒ‹‘š¦ÇY‹‘‘’‘ŽŒ4i…†‰ˆ—t8jyw)rspoploru{I,,*;Z: JLNRLNPRQUFNVONRQCRÿ¶ExRu†š§®ÇxX‚|†ˆ†‡„…s9q||›YCmp~6RqlmnknrulR"Qcl_.EPNKHNTSI>UOLQOHOÚ¶ov‰™¤±»ÍxLrv€ƒ‚zzZS€r,ttˆ?Pokrd0[_ilorndH(Usplm%7EDGCHKE5HSKLMDN…¶Eÿpq}ˆ›§·¸Èy3fv}€€vt}Ifolosvu1Rfeeu?"KbiniZ<.;\sojiB );@@DCDDDCDQFJ@Dg¶·Dâx—¯Y€’ˆ…ŽŒŠYyX47EPZe?Rmihgjsv37[]_^fb6-=1'O|Œ@^`ZSR<&3@CJBKHKI@_Ú¸C¬s}\>r‹‚~ydN~‹†jYJPYO=8dg[tppkl; ,9>?AHK<7UXDU\Jfÿ¹BÔu€tYgnttykCSgtsrqxur7BR]bkpsuq^:940X¬WWjga]\D %58AJD2=UNGPOJº@¯}l–¡fead^dw?:fs{|yupzZ;U]emqlbS@%Fx•‘8GVWRPND!7AC41HSNCKNP»@ÿ²‚]†—se^WZfjr|>:l||ulwvDBY_]S?/1c…zs}%>FEDHCA17D>+A?ÿ§‡q_lt„oRe{€†zrrx[5L[^^TI;36DTcgŽVQZ`\ZVA&168;?CE:%8U_]LPQXª¾=Ã’qudXqŽƒDNl…‹€vmjlQ),32/3Baqnge\.KRQTOG(%-/27@GE3KYOS_PVkÿ¾<ÿƒeitqK\imcDBVgl^PKA6)8KV`eaXRMB6 DIG@,$#,6@GKEJR=G\ZqÐÀ;É»™\lfRJMTTXGKJKJ=BHKFIN?UebuÿÁ9ÀÉ£QQ;FHALTSRLDIPWVYF2DMW]O5&+5Ha}c@8>BDFFBD@Iyy†Â+§­½—…o:L:7K]g_@::AQWS?7 CHHFG@Kc~ÝÂ9mœ£mzKLD4CGcj[M?ALKGHFB@>?<:9;>AEDBABCHNOHAOcÌÃ8³‘sRfˆV=MP;;9C[QF?:IX`fhaVD>989:9:97877<>C?@BCDGGF?DR_~ÆÄÑ™dl`Qxj9;?74:FMVS?9>@GKIE?=@€789<:=C?;?AA>EAA?@C>EabqëÄ"ÐÒ©”´‘CR_>0/70.7?A?II9878:9>HMECCDA€CDBDIJDCGAABEAF]boþÅ6Åɯ­·«`KMM:8=A8549?MYQKIB<@>>??=>>;>=@CIJFEFGE@@C?FiyxÔÆ'¼®ˆ— {Ynn@/4:;9739>DEABACIDACB?=:75:@@CB =<=<9Di…вÆ5°°¨rqwsNBTC+'-2;A4-+1214@HFIJIDBA<=@?;BBDAAEEA?<@VblǨ ®‚ZVc™~458:1*3:>@>83313799::€=?@A?;?EDDEEGE??BNUXŽÈ3Ÿ“§°t`•ŽfGG?3*+*+/.3=A8872345:;9<=:9=@BDDCFE@79?JVwÈ4ÿŽi†¤¥pjkprI10/,+*-.5;=?><7;97:;9;8:>@?A>DAC>937EOq¿É2ªƒyŠ•˜eFBNqT401383+**-.1355768<:348:@AA@AA<4456AP_¦É2¶³°{n†¬B89CB:8647C1'&)*,/32//482-6=?AEE@B:679=BMQmÊ2®™¥qYewkSB@@D>.0-+44.-/0334420269@ABBHIDA<7;=??>JTŠÊ2£„ŠuYRMMG>@bU931672-,*'-01566899=ACEDDA=:<@<<=BA[ÿÊŒfS—ˆ}LCH??NH941221213/035€: >@?@BCFDBB=8€7;7BJiË2J>vwtznP;532:610/03206<:;98989>?2/00/+)/:<8988;<98=;8988@L\n‚Ê3—Ÿ´—ZHI\S>99;<21<5210;E?8989=>?AACC?@:8@<::9;>=K^o‚”ɤ“’}yK97951.0634=>7229B?==;>@@€BAACA>;:45;?@=CMZlˆ—È4»ŠwbxU>8200123535:8514;>?:;=CFDEEBA@:65128;B@CHNWeŒÉ ~\IC=:70.0€+#,024536::;;<=@AA?<;<975:;89=<:;?BCBBCDKORN*ͧ‡o`VI>751031/.-/3:<9;<=B€IJLLNSURSRRQOQUY€Z[UUÓ±—†ylffcZWUSKFCEHLTXWUUVZ[] ZYUV^ba_[YfÔ'¿¤“†zvwpijjf_XRUX^dfefdbaefeggfa__a_c_\Ö­§–‚‚|{}yulfeejpr€trhjmmnoki€fU[fKoCÂ"·¤™‘އƒ‡‰…}pklouyyzpptmmuhcb_U3‘i Á¡j-Áÿ¶¢”–……‹Œ†omm_qkrxusq?•6y±€ÑÉšgÀÿ¬ Az¼ÖÑÏÎÓàœò qÄ×ÒÓÒÖ×›<ð ${¸ÙÏÒÕØÏ‡ò .‘ÖÚÕÍÙ½aó"U•¸Í­IÈ_­s£‹“…N‹Ufƒfe|{wd† (F)Š EzMt—‘‹•šœœ„b­(z‰ ¸«­ÅÊÊì‚L­¢¤©œvˆ”±kEn‚¥·ÃÃÁ¶ŠJ‡!U‚5„Djž£¨ÂÌÎÎÏÏÌÛÔª.«+d•·ÇÓÒÒÌÔÓÒÏÕϧQ¥“¹Á¼ÂÈÎÔÖÝq/ަ´·¿ÙØÒÒըצ@€ °ÌÆÅµŸ¢·Ì¥‚,u™·ÉÈÈÚÖÐÑÓÒÐÆÒÐg ª:u¤ËØÖÒÑÔÐÎÒÏÌÎÐÚ¡0uÀØ×ØÖÐÑÕ ¦ËÍÆÎÛÔÍÐÒÒÏÐÓ iÄÙÔÕØÛÖЊ a—¾ÎÊÃËÚÙÔ€ÒÐÎÐÄn ª;l¤×ÓÓ×ØÈ “¯ÈÒÕÏÍÒÙ‚ X¾ØÔÏÎÑÐÎÍÆÊÊÚÇÍ×Ò×ÓÏÎÔÆM\È×ÑÒÑÐÎ~€c©ÖÏÄÊÎÄ‹mœÈÝÚÑÐÑoª/K¢×ÔÏÑÙ¶` *gÅÖÎÐÑ×¼?^ÇÒÎÏÍÈÈÉÏÓЗ<\ªÖÔÔÑÏÑ×r€„×ÑÑÐÑÏz]«ÓÈÉÏÙ¡F G»ØÚ’«}ÉÖÏÐØÀF€mÔÔÌÏÐØm€ Ž×ÐÏÆÎÒÏÍÍ{1­ÙÔÑÎÎÛ‹€ ;º×ÒÑÍÉjD™Î̀ѧ2‚/‚¥4«U±ÚÐÑÖÑi‚%´×ÌÏÐÜv _ÐÑÊÆÒÏËÏ€xØÑÎÏÎÙ©€ÛÒËÇÊ]yÅÉÑÐиA… «ˆÏÓÏÕÚ¦€ /3›ÔÓÓÕÚy ;¹ÕÉÊÎÌÖ¥‚}ÕÒÏÏÒÖ¤m×ÎÆÉÍ\)¥ÕÉÐÌÓyµ<¢ÚÑÐÓÕ¢Yr𬩫­£¸ÈÓÕÔØy$©ÑÇÎÕÖÕ]‚ šÖÒÊÍÐÖ„jÔÌÎÔÏZ\¾ÌÌרÃ7¶P°ÕÓÑÎÍËÎÏÐÙÚÚÜÚÒÅËÏÐÐl3¬ÖÍÒÐ×·&‚J¯ÓÎÌÒÓÓ^‚sÍÉÓÓÍYƒÓÎÑÒØ– ¶fÂÑÎÍÌÑÕÓÑÒÖÕÒÔÖ×ÑÔÑÎÆN7­ØÏÒÐÛŠ‚zÑÒÏÏÓÚ·,‚pÌÑÒÓÌXœÙÏÒÑ×j·‰ËÎÀÍÔÐÊÊÈËÏÍÌËÆ´§§¸Ê¹07®ÙÓÒÔÒX‚ [¯ÕÎÌÍÒÚy‚mÑÕÑÐÇ]ªÙÓÓÔÓV·‰ÍÌÆÈÖ¿YCDFDBBA8.F@:°ÚÏÌÒ½1 [¤ÖÎÌÍÐÛ¯.ƒoÑÎËÌËe ´ÙÐÌÎÑX·‰ÖÑÍÈ×Å7‹"/€:®ÑÂÆÔ¢O­ØÕÏÎÒÙ¨>ƒrÑÌËÏ×vµÓÃÄÍÎU‹`§k¦‡ÓÍÏÊÓÎ`‰ b¡X€:¨ÒÑÓØœ9„¥ÉÐÒÌÊÍË“+…rÒÐÎÈÛ„ ¥ÑÏÔÔÑYŠQ¡¬+¦nÉÐÍÊÍÌ…‡JˆÃ«!€D²ÞÓÐÑÂ¥½ÒÕÑÊÍÆÏÐm†rÓÓÑËЀ™ßÔÑÎ×}‡r©×u¦C¿×ÏÑÒÒ§+…*o›ÌÕ\R¸ÙÓÐÐ×ÚØÖÔÐÐÒÍÌÕ|†rÒÒÐÍÐ|ØÔÑÎØ¯*†Q‡ºàÃ2§ 5®ÕÎÒÐÍËu ƒ]…·Öݰ#f¾ÖÓÑÑÀÇÙÖÐÍÒÑÍÉÙÓœB…wÔÒÐÑÔ†GÅØÒÏÑ×wƒ4u¡ÎÖÚ § }ÑÒÒÔÆÊÁ„Z::?p–®ÉÙÒØwpÅÕÐÏÖ“HŒÃÕÓÒÔËÃÏÔÛ­\„‚ÕÓÐÓÖŽœÚÏÐÎ×Âu5€-_ÁÛ×ÑÉM©<³ÛÓÎÂÐÑÍÁ¢®³½ÑØÑÌÕÀ4‚sÒÔÎÎÚ™ DÊÚÒÂÏÏÉÔÓ¼{, ’ØÒÑÒÕ¥VÆÒÑÒÒÔϬƒ‰Ž¹ØÎÒÌϪ©\ÊÙÂËÙÓÆÊËÓÛÓÐÏÊÆ×š‚|ÍÌÊÍÕœW°ÎÈØÕÇÆÄÎÑŽ>€(ŸÚÒÐÐÕ´% mËÕÌÎÍÑØÜÓÉÉÛØËÆÆÏ}ªf´ÊÜÖÒÓÔ×ÏËÊÌÌÈÐÔa‚’ÉÎØØÜ½0*xÅÜÒÑÑÔÍÍвyYº×ÖÖÓÖÄ:oÄÙÖ€Ó ÙÔÇÖÛÖÖÕÙÇE¬@г¸ÃÊÅ®§®¸»º´¼ª.ƒš¼º´¯»¶<‚O£ÇÎÏÌÌÅù}€ÊÍÈÈÇÊÎW€I–ÁÌÊÈ·Ÿ¡¥ˆnjedT® $:=8" ƒ39(,„9FßÁ;ªwkhk|‚¯‹!hqRˆgD+L—¬°°Ã˜›Èµ°{¨êïöÓ“ˆ ªºšrnjn`VMHG2$5:;çŽhH.9o£¢ƒ[Q$35  aˆo‹åÝêøöò²K°ËÑ˲~”•˜’„i>,?<5/;LPHOD@D½?âwQ>EiƒcUcsÓÄ7!+ 4ÀÞɺÑ×îøðçÂ9»À¼µss€‰€e4'4%);CILJHDJJu¼@×pVx¬Ìéïà¼g¶;4& eËÜÖ¦¿ÜõôðÞÁIj©¸²¬zWl|€rO(,661BGHIIFFMJx»Aœry§ÇÔêæíÞÖå€ch0&3' žÆä¼Œ·ÕòøðÛÎ}L¤¦¡XYgX64BRNQJ%gµÐåë}‚´›‚„;FFUK•‚˜©±×™G °·¸·²§¬‹:7#!Mwtld[WJELHFR:?MF@?fÿ³D·•ª´ÃÒÖ¦V>m°Úçàä×§ŽŸ‡y[‰ Zj¦ªµÍÑB_𥥦¥¢›‰N!PbCBZXUOORGAECM9FKF<7ÿÿ²DÂy€Šš¬’`UŒÉðøðóô󤄿¨tkD\”PMˆ¢µ¼ÃË‹.m”˜š—†`7d†m<+>IDGIC3>BG4BGEAQÿÿ±E½™L/-/2G–Ýôø÷ùøóíâi‹àìÓ¹l=fqqBu–Ÿ²º¸¸¾_8sŒ”‹€_-FЉ|rkG,,6767;>@;19dƒÿ¯E¯¯­ÈßïôúœíóõéãÞÛÖÑol°¸ÉÏѳH~ˆeC“œ¥ ¡Ÿš”—k7^cN59%N|rb^ULFC?C65;=::B;1J¶Fª’¢Áàèîõú’ˆæêè×ËÃÁ½­Cƒ«¶½¹µ‹OŒœ—7“šš˜Œ‰†‡Q426PxN,bbXVHA=;;@26;57=<.:ÿ¶E‘q©Ðîööúù‹ÛÙÛʺ´±­G‰¡£¢ ©d^—˜ BdˆŒ’‡…ƒƒuY)dƒ”€;SSLC98:93,>63894:¶¶Eš° ¶Úõûøöù”y½Ä÷­© ˜l`…ŒŒˆDh”“x9ft‚‚ƒ}oP-jŽ’Ž,=E?=321-#6@646/:m¶E̋éÄÝöøøîô“Qš¨§£¢œ–—Vr‚„‚€€7`zƒŒI$TmtytdD6D%{‘†„€G )8954..(9C9892?™·D–™Ï§Èçóñöëâ‘/HrŠ‘ššU}}~}z{‚6Omw{wq''M^aO4Dvƒ$qŠvnfV14551/1?7;23P‘·D≳Í~ÃéèåíäÇs”k=;La{„N^zwzvtv„=>dhoksk4)<2-]’¨›']zj^UN3$.768088<;4N¶¸C¹›ÈàŠZÐÜÙÅ–m¤¬ zcPA42amrvtswT8\dhkf`Q* /„«®°¡+0Y]UOF@+#232::8AA2W¹¸C몯ËÇÜ›KT”öez‰†‡•R.\hnqrwv~o5LX^`\J25m²¨¦Ÿ“6AGC?;:;<1%<;9HN6Qÿ¹Bº¡“»ÁȰqMSd5q…‰‰Œ{6\jmot|xtvA;MXQ>9mr€¥™“ˆ€D.8988;;+&?C6EI8Wÿ¹BÔ™¼É¶±¬¢¢œ”uC&lƒ‘‘ŽŽ•ŠEP`girvvngW7877e¢Èh!|”†ynfF #116<3#,?:5AA;3;=D»@ÿÞ¿ªÔÓ§”އˆŽŽ—™HE~“‘”Œ‚‚wC?T\\SA17)†¯º¬¢¡/T[RLK@9(*4/+>=02AB_þ¼?Þ⥜Ũƒ„†™¢“S=hyzzvoiU,4<6:Ng‚`›¨ª•‚*FIF?9881+!0?@4FIGYÿ¼>ªßÔÛ§ ™‘x‹šš¢—ƒx}^8M]__TH:5?Tp—°j)xŠ‘„wmT.9<85665*'>HG9<=F›¾=ÛÆÃÇ—†—›ž`iƒ—–…wmigM%+137ATy—˜Ÿ˜¤9+ozvqaS1*//-.25.!7C=AH6?]ÿ¾<ÿ§”¯º¦mqjwvZZhi_TNF9/7Qv‹˜ž˜‹ygK)Y^ZO8,#+255+1>0;LDL¢À;ßßʘ«•l`hlfgPRRV\RNWT!82AY{åÃ8ÜËÜ¿™­Ìƒ\^M9?BPfT?;@N\bfh`THG?<::454..-,-.1.-01257715CRwÆÄ7ñɘ¨œ‰³˜VK>78ANRRI:=FD7€577714€32/..,-,))/00124557801QhkÔÆ5ððØ×ÜèÁ˜¨–U@;;9:>9211..+**.))-./2321.0,,Dd|ÌÆ5×ìë«©»¶·ˆq€`<588;>/)(,-+-8><=96211./20)-/1127850-0BM[Ç4ÑÞî«€~’ܾZVQNB5:<;<<60/*+-//0--../120-/334468731-9JWŽÈ3ÇÖêæ ˆÀÖÎ`\VE52-+..09:/.+')*)++*,-++.35743771++)3NÉ3º¥ÊîéË¥£¡–…VHB<2.)**17742/,//+,,*+)+-.2636340*%&/:e¿ÉߺÕÙÔ•skj~^I@;8:3)'(+)€'),--.,'')*./4433-&€%*:N›É2¶ìõ¸¥ºâ°k^USMHB<88E3('(%""$%&(*,&"(,..2644,'&'*.1>bÊÄÔê¨|‡ ™ƒqib\J42-,56/-/*(%%')€*-€214565/(*))+).@ƒÊÀ¸µÁª†{rmbUXw^B=:?<3))($€'*-.+**-0233121,+-(''+1RÔÊ1«wÅà̱jRPDEUMCCBA:2-+/++,.10/-,-.0255340*'%$&"+Bf˧oa©³ª¥ŒdJB=:?=886330*0421/,,€.023553.**(&%)##6LdwÊ ´˜°È‹‚}›‚NGHJC601.-,+-/1.,+*+,*+/€2-,'$''%(&&,8IbwʳÑõÔxaaueJGLJA3-3,+/5982+**),€-/0/,,)&)%%&'),+7Ia|”É4¯¾Í²’]IFE?=<<93-22-05531.-,-./2122120-*% !'-0,3@A<Ð+ž}l]RH@80+*,++-/01122164499;;<;:9=?CEDEDF??Ѷ›Šyh\VOLE?:7766513€79:<>@BBEECCADIJOKMQM8Ó(®™‡{ldd`WPNKB=989ƒoÇÃÁÅÎt®Ç¸ºÃÅR‹`§k¦ËÃÅÀÉÅ]‰ aW€: ÇÆÉΗ9‚ŸÀÆÉÃÁÃÂŽ+…oÊÇÆ¾Ñ ŸÆÅÊÊÆVŠUž§+¦iÁÆÄÁÇJ„¼¥!€D¬ÕËÇǺŸ·ÉËÇÁļįj†oËËÈÁÆ{”ÖËÈÅÍz‡r£Îr¦C¸ÎÆÈÉÇ¡+…*o—ÄÌ[V±ÐËÇÅÍÐÎÌÊÇÇÉÃÂÌz†oÊÊÇÄÇ|yÐËÈÅΨ*†K…´Õ»1§ 5¨ÍÅÉÇÃÄs ƒ]ƒ°ÍÓ¨"i¹ÌËÉȹÀÏÎÇÅÉÈÄÀÏË™D…sËÉÈÉË‚F½ÎÉÇÈÎsƒ4ržÈÍÏŒ § {ÉÉÊ˾ÀºZ::?p’ªÁÏÈÏtmÀËÇÆÌGˆ½ÍÊÊ̹ÆËÓ¨Zƒ}ÌÉÇÊÍ‹˜ÑÆÆÄͼr8€-a‹¹ÒÏÇÀK©<®ÒËÆ¹ÇÇŧ¬·ÈÏÇÃ̹6‚qÊÌÆÅД BŒÄÒË¹ÆÆÀËɵy/ ŽÏÉÈÊÍ¡V¾É€ÈÊÇ¨Š…ŠµÎÄÉÃÆ¤©[ÃйÂÑʽÀÀÉÐÉÆÆÁ¼Î–‚yÃÂÁÄË—VªÄÁÑ;¼¹ÄÈ‹>€(›ÒÉÆÈÌ®" jÃËÃÄÃÇÏÓÊÀÀÓÑÁ¼»Äzªe¯ÀÓÎÉÊËÍÅÁ¿ÂÁ½ÅË`‚¿ÃÎÎÒµ0,*u¿ÔÊÉÈÊÃÂÅ«wY´ÏÍÌÊξ9l½ÐÌÉÉÊÐ˽ÍÔÍÌÍÑ¿D¬@…¬²»ÁÀ©¡¨²µ´­µ¥.ƒ–´³­¨µ°;‚ M¿ÆÇÄý»²z~ÄÄÀ¿ÀÂÇU€I’¹ÃÁÀ°˜™¡…kgcbR® "5:5" ƒ36',„9JOMK>3S_?5567D!‚ ,676"ÿÿÿÿÿÿÿÿÿÿÿÿƒÿÿÿÿÿÿÿÿËÿâÿÿïÿÿД—¥Œ{€ƒwPIKU‡¿ÿåÿ£žs]fYSKIKEBCFG?2'(4;RfâßÿŽclaPKLGE@8/,07864/0NG&#2@cÿØ%ÿ_nURTOKLPRS^j`LGLNKB90.),3Ixl^B-"AÿÓ)ÌDqPFLPRbbgŠ” ´ÇÏʷý«˜hI0# &JWUG3 `Ï.ÿlR`Y_n|‘š¥£ÂÕíõõôïäÛÍ©À½ÆÊ¯‚F;;.)!  .ÿË1ÿ‹XZ]z™¢ºÂÍÎÈÅ×Ííóýùðâн¼ÁqBMOjoR3".!  ¿É3ÿ†ihyœØÑ­«¥˜ˆ“£žÙêäDZœ˜¨©ƒH ajL:!"#  sÇ5ÿ’[Jtss}vRqhcZQP_\x¦³œruƒ™ˆY+zwZ>$#%# UÅ1ÿ›bNS{k@·wB‰iUD=BKIcŒ~fptlqmnY72@z‚_B'.&€ FÄ3ÿeMJW_>’ŸÆËQwº™mZSdŠbZrrx‚mT<7E6+Ue†zYA&%5" €[Â:ÿnPCDJib:¿|}µ«3}ŽeZg‘¬£E$-(%.M{aIJZr„„^J2 #,  ¿Á;XKEGXb“z]mc»›\. -W_dksF*,(,C|ž½©fT~‰t@,"!  ÿÀYe6ÐrO8&)T‹•|TD" HP5J|O&,EDLJ@7=Hb[=% b½@âb>4@fcT`f¯š$   SPI\X4-*3@I;QLCL:;=3*"  Sÿ»AÄU<]’»ÝãÚ¾X‘„( 7B5ILD19@@CI-NVPR9!*00&  SÿºBœVTy˜­ÍÓÏÀÆÙtIM% ULGUCD:=OHIU;#NTTOC!$.&   Vÿ¹=Ðc^„ ±ÆÛáÇ£¥ÓŸBW?  PHM[4@DI[NLXTCQUOJ)"*&  € a¹C²iwªÅÕåîÚ°™…vJT~]:  9*4HD=AO[LFKZ0"LNK8)>71    Ú€ÿ´DÚ[ož¯ÇæòïÆ€QCQzzKpaMB( AM#$A!-=MOE@AKK*@,#I=.#     $ÿ€ÿ´Ckd„ ³ÖíÞ”="Zš¯ÅÌe^rPGU$.*.5!,/BTA3D?>??@J> $5*     3ÿ³&Žft—±Æ¤V;a—­§Ÿ«±Žt`^QH)<7=0902@C? $-    ªÿ²?›XX`m‚yZU†±½®™Ž’¡zqЇLF)1A=F!@=;)1@;&2=>?A<*0@5)   €  #ÿÿ±E’}F.)(+?ˆ½Á®–ŠŒŠ††+:=@535H'.87;?+7(    ªÿÿ° §jª™–dŠÐðž‹€4z[anik‚%&4=B;63269 .5/#(,     $ƒÿ¯E{y—´ÎÛçŽv¿µª–ˆ|rif31W[^Zkn"KP-8BA93/.1:- 1%  ¶Fªfu”¢¥³ÊÛ{c§ š‰}ug[R:TXTLgR9PR71762,+/3:  ÿ¶EZB€¥¨¤±ÄÒr_’‹‹rmbVC?QOGAi<.D_- &030+,.0+ $#!'   m¶7mddˆ§­¥¬ºÆpLuutnfbZR3*BHF>6H!4=EH&../.*" 1/€  0¶8ÌV~nˆœ­­²«·o.Z_]ZXRRT&7?AA81)*=7$4 &+-( #+€ f·Da_«s}“§°³ i'=HIEGNA"89:7/)$$=3 % !" #    H·DÆDy¼Vu’œ¢£“‚KbA &0< %202-&$+.) %0  $#*     m¸CcO¡¶a8uyr{c6XWJ2#,-)'$"$)! 2&(     "s¸C×Sm Œs23Ggw@>I?85<8<$')'$!#!"  )2%%    !̹Bucpip„’n6"-B8B@;:67>4"*)&## ' &-%"   -ÿ¹Bª[“¨kUsqR(*27B/ €  0HÊ—±à¯D#!!  €   /OjÉž£·W"   ‚ /Lg?Ȫ‘ŒdJ- €ƒ€  '?`LɇX'"  „  € ÌŒp[2!  €€€  #ΧuU<. € #$Ð gN?3' €    !!#Ñ qWH?3--,&  #&'()+&Òÿ†gVMC?D@8,"!€""')&&%(-102'3Õ&ŸweZRQUNFD?90'!"$)/,)+'&(,+-13001/351*.×#š|nc_`aYWZRKA5117>833*6‘% Â"™‚silmifijbWH>=?FFJLFJ=37<::98:*3‘'UtY.Áÿ‘jsmah\fkcOHH?8CLLPO:.8??—.i‰Š‰T)Àÿ¬ 9t‹‰ˆ†‹“Uò/|€ŠSò 2o‘ˆ‰Œ„Jò JŠ‘†t)ô %UmƒdÉ_‘1^E?D3 ‹ ƒ193ˆ Š /*?>KPUWU7#®3Y}_fz‚‚y`9„llt]'/6MUh5€ 4.Yjw{yiFˆ&5 …8\^_t‚‚††‡†ˆ\ «+†<‰Šˆ…‰L9Ž‹ˆ‡f †z“Œ‹Š‹……‡i9oŒ|6xŠŠ‹„Ž“ŽŽˆ‡y­Hkjs€ygeglnmio_ƒCqmlioiƒ!]…„ƒ‚~zp?3{„‚ƒ‚)Utƒƒ€k^b[E==/& ¯  ƒ  „!""!€( ƒ ÿÿÿÿÿÿÿÿÿÿÿÿ„t8mk@  6U|”¯ÁÉ×ãëóóøÿÿÿôܰ‚> )R’®¼Ùêúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéž6(X{šÁÚòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁ/-i˜ºßöþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹%Bcš¼Ôùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿô^V’Åìûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü— $ƒËóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿË(€ÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ'SÀþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ$S²êÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅ.‘çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ‘ \Õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ[1ŸíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïFLÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿé- vàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿã4 †õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿá4 „öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿå7 ŠûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ, ƒõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿº ˆöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“xöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïTaïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌ=ÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŽ.Áÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×2/¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôn²ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿº™üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙHzøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêW3Üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú‡µÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóŒ„üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîIæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâo ¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëkMçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéo ·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜ[?éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿C žþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ®&Jòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒP'Úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð¨6‰þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖe+Üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý±9—ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿã~9ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌNšÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø›&Cåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ƒ¦ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýŠ ,àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ‘`úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïu ¦ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó~1ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðy l÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø… ©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿž8ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾"€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß@³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú~³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµ²ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó[#ÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ#5áÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤Cîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû÷‚CíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüîÚ„Aéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ß¹1@êÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþüùëͤ€P -Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþúôïåв‡`I ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýõíâÚȬˆ]:( ŽÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþýúîÙÎǸžxK'böþýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿþüùðåׯ¸§ŽjA Æùõ÷ùûþÿÿÿÿÿÿÿþþÿÿÿÿþþþÿÿþþûøöù÷øôìàÔ˾®—vW3dãçäçñ÷úþÿÿþþþüûþÿýüüüúûüúõîèççßÝÑÈÁ±¢–}dE$ ŸÔÌÑÝäìòõòóõõóóõöóðííìêåâÝÓÎÊÉÀ¶«¥–†teO5! L­«¬¸ÈÊÎÑÓÔ×ÛÚÚÙØÖÑÍÍÌÍ·¸´©£¡ž’‡ydXI8'`€…’Ÿ¢¥©¥¡¤¨ª©¡¢¥¢ŸŸ˜›“‹…†€vlicXP<0$ LZguyv{ztvsuxqqsqmig`YZVVVJ@95-#%Y5 -7ADADFDCCCFEB@AAA<6022.*# aÐûäžI ˆ÷ÿÿÿÿì›.±þÿÿÿÿÿÿïƒ%—ÿÿÿÿÿÿÿøÜš3tôÿÿÿÿÿÿôд„*,×ÿÿÿÿÿþéɬx= ,¢àöüÿûßÁžp+NITZT1 5XYZGe•¹ÌÙÒµ’V !Hl“›››››}N0Y¥êÞâôúüúá®]lctbGPl§Õ£<5NnÔêûûüòÍxÜÿÿÿÿÿí½†? '[zv@&ÕÿÿÿÿÿøØ²Ž§ÇÆÄÓúÿÿÿÿÿì†iôÿÿÿÿÿÿä¯nËÿÿÿÿÿÿñ¬J³ÿÿÿÿÿØcþÿÿÿÿþÕ™L Vøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë†Oñÿÿÿÿÿü͆3Kñÿÿÿÿÿÿæ—8¦ÿÿÿÿÿÖn±ÿÿÿÿÿö¾maûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ…Iñÿÿÿÿÿó¶`  ÿÿÿÿÿÿýÔ†$¥ÿÿÿÿÿÕxÑÿÿÿÿÿæ¥L‚þÿÿÿÿÿÿÿÿÿÿÿÿÿýùùùüÿüËwJñÿÿÿÿÿâ>oòÿÿÿÿÿÿï¹m¥ÿÿÿÿÿÕxÒÿÿÿÿÿ݈,ŸÿÿÿÿÿýäÜÝÝÝÝÝÝ×ËÊÊÒÝÙ³[ JñÿÿÿÿþÏ‚!Nßÿÿÿÿÿÿý×I¥ÿÿÿÿÿÕxÒÿÿÿÿÿÛrŸÿÿÿÿÿþÊ›š››››››‹{y„–›¥V Jñÿÿÿÿ÷º_0ëÿÿÿÿÿÿûß·w¥ÿÿÿÿÿà}ÓÿÿÿÿÿÛqC ÿÿÿÿÿÿÑh8666667-"B›è¡=Jñÿÿÿÿ÷·šÞÿÿÿÿÿÿÿöÕºB¥ÿÿÿÿÿë‘ÔÿÿÿÿÿÛpKÁè€)ÿÿÿÿÿÿéz–ùüÁa JñÿÿÿÿþñóÿÿÿÿÿÿÿÿïˬƒC ¥ÿÿÿÿÿîœÖÿÿÿÿÿê|xåÿíªByýÿÿÿÿÿú¥, RÅÿÿå«W Jñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ·t/¥ÿÿÿÿÿï˜Æÿÿÿÿÿû§3, ýÿÿÕ—:_óÿÿÿÿÿÿÜb 4¡óÿÿüΈ/Kñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿî•)¥ÿÿÿÿÿð£þÿÿÿÿÿÜfoÓÿÿÿô½oA×ÿÿÿÿÿÿþÎs0F’áÿÿÿÿì¶cmûÿÿÿÿøäõÿÿÿÿÿÿÿÿÿÿõ®6 ¤ÿÿÿÿÿðŒwñÿÿÿÿÿýÏhkÉûÿÿÿÿá£O'¤üÿÿÿÿÿÿÿûãÔÕñÿÿÿÿÿþÔ—>‹ÿÿÿÿÿôµ¶ÝõÿÿÿÿÿÿÿÿÿÿÉ\Àÿÿÿÿÿ÷”TÃÿÿÿÿÿÿÿõÃÌýÿÿÿÿÿúÊ~' fÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö½q‹ÿÿÿÿÿö¡m“ºãüÿÿÿÿÿÿÿÿÿç‡$3áÿÿÿÿÿýªLèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿî±[ 5‹Ûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿå¥O‹ÿÿÿÿÿý±D‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½w°d÷uçwnßι_ŽÞäÁ$FÅ(rµŠTXU’·je»lo­í²´¶Ë$˵UÖzõä’Í•,»Dk¥%JKŠIPE 20Àä™7órì×9wßn¾÷Z‹² $gˆîÁÃ{¯_÷ ¿þô=ßsŽÙð1\á W`¸Ã®Àp†+0\á W`¸Ã®Àp†+0\á W`¸Ã®Àp†+0\á W`¸Ã®Àp†+0\á W`¸Ã®Àp†+0\á W`¸Ã®Àp†+0\á W`¸Ã®Àp†+0\á W`¸Ãøþ¯À`0pôõý?óíqÆáÂÜŸÓð*_[7J˜GzÁøfƒ7óâÀ›ùÓ¿îýÛÿÛ÷í@ýnGï»páB¨R©¸ñj50˜‡¢Ñt<ØËT÷ ±ö áš¹=×Í´³ÁÌÎÉûß•ÿNÇùa}îÛò‡õ>‡÷õC±ç£5çã³Á£Ÿ²ÀÏýœãé¶Êå‹£»•òˆÛkKõH£Ñï•ó«1ëÜ@/’uAÐsA‡¯@(®w “k×W…„9m £§m zÞÁZ67ž™8²wôè;/¾gý[çù¡XÂo»‰¡ø¶þzk­Ž q{=‚·×å¯öVZ!ìŸúÔ§ ÅÀÎ…Ï}5`÷ÞÞÚ:¬Ñ(LíÔKÙf¯;Þîôf//^˜òz½Ùv·s¼Óí=¯ëú±¹v·'3îõ±àxç´~G Í±h4ŽßîY«Ý±J½m• ‚u%#Fð}ÁŒDxmÀÚ­6Š¥v°ðïî[4@øÁþñúNϺýª¥"®%A+s¼j±gÑDØÑ„%ãŽuxŸŒz/¬cà pÊv»oÍ:@¹•i÷¶››óËËëó3³‡R•òáÏpë·Òçóz®e輞U¾æµ€TÃOûèÇü}óÁ>˜«—vmímX]]ž\ß^X,â¯OÕ;½\µÓKuû–À’Çðn|§|`®Lµ\ôý-ˆàŸÃ -šŒY8ŒUF,výø¼R.ZµZá5,xì[œ× x_ ¥ààÊKP»6ïõ,öÔð<ß{‡9¥@^¶Q*žD,—‰Úæ ÏÖ¯÷m4yÐN¾Ç\ËÚÚÖ–õz]‹¥ ‚M«5ËVª­^)X»X°z©f­†×»Áj2&72ùÉñéc_üçÿÃÿµûÚbÝ߆ à¶ø˜~ðùüóŸ‰WóÕK«×GwÖ–ÇwövX(0ï†"`YŠŸ“†ëeî`á#626Îk&Ì `µ°eãcHa'–v‚'2Á—þ)j÷¼.ïmZ³‹Ð#l=~ï‚Þã@X­\µõõ‹E¶-é”,f´–…ËŽ¦mì¡Ã€Ø¾\s°Æ}kÔÍê‚uª`|£U'cPµv³i^ ‹ÞìY"·ãdz$­RlØæf OHsøHFˆpBJJ)ÅA‡à ì‹-Ô7°@kµHz€—K¹ØÉlæK®_»2ýùÏÿöÕ~ÐÚ·ú*€[ýú^ïÂ…]åéô+×_Mý¿ñO'CÉÌ©À`pºÑnÍô¼þT¤¾S«e“‰ôXzr®ïfÆmòhɉQwb|,Ée,3š±B—K“LÇêÖ*Їã–ÁU¯ÛÎÎ.B¶¹™–ˆ`¡-Œ`­ï†¬‡€v$ýöñü¾ ìu8\›¿7‰ëë¤Þš(×âx%\ï¥Õ›æÖð¦·Ó(—¨…Aó%„u/nqB‰V?fÍŽ!ÈmbñÂ_´ZmÇò…¼å‹x2¯oXÐõ,Mh‘Šà­$¢–EqíûV,4ðÀ â`@”0¯K°@ Š !Ú®Ý&#ÐìZˆð ‚§‚§¢4$ "wâØ(7§ÞhdÖ×—æßÒgYû [Ú *€ €ÝŠo—пðÂg#çνšøÍßü©X,¼Ði¶O×jÕ…r¹°ÐØÙMeÒ©\.6¿pÔ …£„ÞgtbÜ&gf](6Ö?’Á"Š4£œ;LY¯m…F Vl îîÂÈiàºGˆõ‰ßÈymÅÐv o-Rm„ÜXR¹Õyx 4Ïÿ½…‹ÝÀ †GÛm cÛ’é˜yI„„>3ŸµòÅ ¶qóeë7“6>Fèú¸í¤[Äô±2q+–ú¶½Ó$¥×m t±ÔQ>F¨">ÃõÅìàEµTE9IAµÌù‡{p¡ò&\Ê0×ɗ׃+€G@Üh¹<-Æ_üž:B#\Ñ—ñzÝÙÝÍâ‰VsçR¤*,º¥ BCp+JðwyM~à±Ç }ùŸ›­îî­—*wn®Ý¸§T­sƒ¡éT&˜=˜Ž&sÁÌX.0wäˆsèðIÐ÷¨mWö°ˆ-bñ´9ðeËÄÂ;øÓ­üð !v$ømt~‘Æì`p΢¸ú»›x|ŸLOA½!o*ߎ`©q£Ûì22ýÄõ¼yèvêXmÜòß­û„ Ã#ŒPVMbµê6`ˆÿtØ’XÞî•E[¾Ø°ë±Ìxe\ýݽŽ=yÈî¼û0@Þn¾g¥]¼ˆF“¢0„î¼g}bzNn^3lBM`±¹žzeFŠø,ánãò·Hâê‡ð ¸&]:Âb¸üǵ–IÜ“D ÞxQ(Gãà3xãífw¡Z+M.œ-^*€ïr3ßöúWƒä¼ðÂ'‚_ýê_ÌÖš{o»|ñò{ÖW׎÷Z½™T23>‰¤Óéð™»ï¶3§ïsrË7Èâ!Û,íÂå V¨W,žIY0€G.¾Œ°×Q¢ÄÄQÑB€åâP'£ïÍ$ã¤ëȉ—»Vênã.'m{0ƒ€&­ƒ%uPæ6~Ð{ˆ7í^•çù™^ø¾îÊAä·Ö9͹Ç2PüÌ­5«@®Õ¶-²³a¡$ jGpëžm<”ŒÙ÷¦ìà郶Sw­QØ3'Ш_$v€µ÷dÍ#‰Â<!t%X¯ÀÛ-{V#ô¸+Þ€°³æ¸ø}€=$;Ì= ät=)4<BQŽ€ ðÁtL”ƒ‡rj<'Ù æw ÛÓÁ'[bÝÒ¡pK<÷Å]½z5òÌ×.ͬl_=}ùò“/íTÞç¹áÃn(Ÿ™=\8t 8-îoбÙ3V· +“ÏÞ Û¸vÝ^xþ)[Þ¼ic§ç,Ê`…ÙÌÄÀŽCŒ»væPÐô¨4A,*,;¤ e‘¶|mɖתVi,91k+ü‹†¦¡ûd, Ø—´s¼¼UëV¬o[t]ñ~·†G€å qž¯ÊqîÉXÈ’°ý6w­³³Œ`孜ߴÖÖ†E="¸è‰U¾ubq”Òué‘ qO ÿùîyÎE¡ í¸îÁ6œuÀp¸nz„p]¬’WF>»Öï ‡ »<çvö…>"‹N(CÁÁ߀Âô¡<ÄWVÀUFfrޝm4 *:^¶YiLÖr£Cà¯Øðoø ¬¯¯Ç×—®.<ýÔŸÝ»¸xáÞÍí;۽ΩDnbrþØq6^ÂJ;u{þéÉWÃÇ‚>÷ôK] ‹Œ߃ä_¾ð¼]¹ü’MßqØG÷¯¿rÙb)¡^> †*Yƒ´ký ÛÜÅ܆{xlr`¯}4B(„ 9𭕪¹¤ÔF£S¤ã¶¬X,“%?€}× W­5(ÙnsÏJµ ê€c"4N!„ í;ÍqÉçXe}¬Xmââ·8ç¯qjNŸÀM“~ÃÂÚhðëÛ颬BQ AŠ&À%ð*„ Š =PXf´è¹È^Ë/òA¸9Ö OÙ i>)$@~VF¢ƒ‚!8ÐÜøq|Wõ‡Rá|ÇÏÙXqOqZ¡Ý†ÐnõÛ¶ö†îoô‡À½¢ßãã àûúcŸyìO÷žÝ½­÷«¥·k•ƒíN;;{h.~ßÛôQñ'¿ö²{î"Hy ²Ín3îsþ<–¸k­^×=n;Ël›šœ²t$nÝBÍGß]wÐ/cù ´€v…G ¾ª¦Ôq=Õr1~n“’óàßGAУ(Ž6”Ý2¬¹>$ ,ºræ‚uÛXq ùp·{Ö&­çI’°¬9Ý’õªÄå„(@ÚöÊ5RkqØyQÂr÷œS˜»Cºq~–{º¹MîbH„c–$½ç`šuRwޝ/•(eçjQ:¤6n¬½þ†õïCàõô ú¨ÀÈ÷òO€£* =”AEÁÈ8 P¡‚¼9<'Ñq¼ tG2áj¹Å[¹ÕCp«BÿŸëûÂùãßýØÜæÞæ™íÝÝ÷VµGÚýÞ<,<÷è™vøè‚oÝž}ò{â _‡è2boyøm65s‹šO°´Q°?û“OÚÒÕ lü¹ôÜñ¶% é<8gÀ8°îoÒv¸ÿ]tÈI1VÖ•‹\@#H¾ž; ½ö 6¹8¬ØùwÐx¯ŒòØósú—ócyÉ”ùqþ¾ªö"¡H‚àJ«µ±êéø¨_øÓÀÕïañƒ€‹AkNe?{1;~rÁ®oâ]Ê!G¹x)&ñÐ(¾¤\tÄ“Û@°ñ~Q”x/òKqÿ;xH=8Êxøs­Xy½ß»T¶”Ù@Ø%ÿ ]¤ÄÐax|I Hñ% iɳLÅ[ü1T·øôÄà‰ }õjöú¹ 3_üÒõZýžR±|¶ÖîÜŒÆ&ÆGr ¹øñéiÛÂåÿê¾hÏ<õ2uï£ö“?ùSvú̽¶WêÙ=÷>`‡ŽZ¾Þ±½Bݾø™?¡ v•0a×®&?2gï{Ç#vþòóÖ$7ßÂÛÄh‘GWö}€ÕSN¿ŽÅí"0urï.9èVk¶r~ÉNß³Ù‰(„ÒzX{rÖ®KlúÄv€?ß$Ö†‹[€W(>'XÉ—ò6iXq/‚‚×4º€vƒ±? o¶±‘q;x䘹O]çyÜ'‚@ó>” ÒŠPzø  ù r÷{¸ý²ôÿÐ’{] ŒšXxÀ¾Ò^€4{}}õཤoË·ôE졼dõ…“ÈðT€$ÃÝÉ3py|§>xb ¦T)èÙ[û1T·èçÃæs{ì·Ã+¿÷ÕƒPRÊïøÚ9ÚìzÁèx,—$³#–Ì’'‡¿þÌ_|Ý.»JýzÑwmìC´ûx«=õÍ—ìÒ•m,i pí¨äÐxð§ìæÍ {ñ™Ç(ŸÝ³›ç¯ÙsŸùkû‰·¼ÏFï&ˆàÉûo ¶µ¾J+Ž"q4.3e´2¥²RvÈb*i3³³–9š°•M»rñš•7 vÿC'm|2e}À¶F3ê»Î]X€$ßü÷LæBÐn£~& Ó Âšnq¯DšoÝ:qÿ(Õ}1‡GáÈz»„H–@8;jñÜ4uûi^ÖJX¡Y·’Â:«(ëE@y‹Üw lˆ¦ÜEð» \{Ê…åð"Ȫ\ÜÈH}Ë#ôÂÔX„£p4T F7ò?„^_ßò+dÒJ/¢Ân'•Œ72=b†[ü1T·à$áÿâ?•«lWo¯,þX¡˜ÿ@­Ó<Ü„Rý %5Ï6òÚöžm½²hyÈékt«Ñ-—òããc§ZŒ›Pt!hØ_ýYëÿõË“gGN·…“÷Â[·¥ëÏ! ]{éÙí¿ÿ»ößÿ·¿a¡É–-uV,SèZj4g¸ïMrö•RÁ!‹Hº0;:nÇà=p„šú¸­Ì¬PS° /œ³¥gmáè$Ê! ¾°©‘8 _·SÁåC œ¶±[o³ˆë ÿkm†¬ð·ÕØáýTæM„lo§÷ž”ü\!’J[ –$“AQN*cÙT‚ü¾h¾èÂ]?u×¼$˜ÀšãHb ahýG"µ„ Â,0ß;Š‚ø?€ »(…”,r.5Ai xdÕ£„'ê.DÕ#×/ ü€ï¯} Hìèx0‘ùv$Ø™Élœxð˜g¿ó…[p‡ýÇK*€ÿ¸?ðŸ$ø¿ýÛÿUø“ð?Ÿ,n­½cgwíÁz½þ@ß Ì;‘p„¼Ø°ÕXÁœ‹¦²v 9kºb›[lâi踣㣔ԎۡCíÚä’}îó×1l oÆx~ w5h?úþ‡l~Þµ?ý£²­Ü¸rݰÏÿùcÇäý'ÿÅOYnʳb¨@€èÈד›§Ÿà²SÓ6=uˆc¦ìÚÕ25ÔÜÇfìáG~œâŸIð‡/Ù_òsïi8O©ö®€bÆòk€Ž=ÑX*qÒæç&íø±C6GqÏòõmûæÓ¯Xy½­8eGg(¡ˆ 'ÒáœG¦-— |—¬ÃÜÂAË&’–_ßµÂÞLAêÿqуx/„¿‡ »àahs‘B@ 0A ÀÁÝwP"5É  ô~nÌA!?òx=B¾« ‘< ÔÈ~zP÷"œÁÁ°ˆ¢È§R‘K©¹‘GAÝ⡸E> ÁG?øê§ÿŸ™h;øðòÚ«ï/W+okö»³Ñô‚ÐZ°j‡%!ê`Íf¶·±Ãƒ°U?ý»qý¦ïÒ6`ÁÏLXˆ4ßg>÷€ßŸÁ‰oÚ¡£Ø©;ßm3só¶¶vÑž}æ6vÙÆæFm–¢ÜøGý [ß½iS§Ç­y‡v™–Ì‘:¤[Nˆ<½øþ=û­½U,ïš/@£dÆÆH8M3¼—,6¶csãMËbéû”ÌV JC"ø¢#`u¬ëÌŒÝ{ÏŒÝqöˆÍζÉÜ,iÄ »óhØ>aW¯Ý´Ò\~<‚‘ÙQ;tp AÚÎbÃÎ]X´âfÅÎ>p—ÍNQáW^ƒ¦K*²V² €dWˆFÕ|aÚô(ê³v=Øè¨Êøð(—Øžî?¿ÊˆËa ˜ § wà‘ºƒ Å&•^¯ ŸrKD$Äý°ñZ …5È©dìÊÑÌ Aþ%¯øø-²Ã¾óe Àw^—ïë³>ú¨ûûëÏ/¿ð¥Ÿ­ÔJ¨5›':ƒ~Ρ[ÅX™­&ÐN9IêÙ½@Ä'ægɵlks˪• JMŽEŠ8?ôÐ#Ö¨Öíß}òÿÆÍ¯Ú|àíä™%žoØÒòU¾/b1—i¤±BÊn™° ‹›KZ"™:ï{âñç,y.aÓ'§íÐÝs”÷&°ü\´Ï’P´Üš­?»6‰‹ŸØæÆu»þÒE2»vÇC!;zbĦ)ó‘µ à¢à!(Ë-ÈGE›_±÷¿ë¨Mš§0Á1ûV%˜%sñÀÙ‡íÄÂvýÊ5ð‹kvyéš½|þ{ŽØ<ý®/®Ø™»O"[ e»iý¼:T`òððád1Í(Nx}šƒ¸4QEb[î¿@?^3@9„äÂó%lC÷HÑ$¯R´ã¾mNÊɲYê$< I‹cX,G!ýÐ oe’™•åsíê[~êûº¾«“ Àwµlơηo|ö…©‹Ï}öÔn¾ðòüžçn;N´‡ ÷qEå¡B“±…:÷ÜŸ¨Â[[ÛV…G€uEø »;¤±hf‰»=:5b—¯]±ë——åÎÛÑSgi ‘³Õ+¶xeŶ·Ö(„Ñ×6í­6ü˜\H»±UþÚC´š´Õj‡lîȨ?;‹Û®´ ¦Ý¢×4jTÁ!43óÓtÚR¨sî[´ê^ÑNÞ‘±Ñ zìá?„¦ ä@Ô‰@Ô CNÞìÛÍ bijlü«çKVíˆ8¥u׎%ú›6–à¸ãcv(|Ìé¨]ùü’m/mÛÈ“d3î&”‰ÛÒÔUóÀ/^»a¥ÍE‰â<–Ì 5õ¢ß…óЩ‰ŒTþ.E¤F Ô ç+«ÑGñàä(v½ƒ£€¶•à'RûiËUºþÜÜiÛ6?¨ì³±toÞMFµ!¢àÐÖîFµñÉÙò‡ï¸ƒ3Þú¡ø}FOþ“éçþ?ºF߃ÕJᑾãìö¡“:̳€U¢~T!bJšf²Õˆâ „m‚šÿLnÔÖ¯®Ú«__D‘tìćíô½iˆGr¥@á Ж‹<’Ð!¡’¹8$Rƒ»0/mU-GÞ¬Kœ>  oØà ´6,K‡Þ±ð¬MÄ,2µìdÖî:{ØîÛBŸBô@AìVò¶#Ñ'.ù!eeÂ÷Ôà´jÔ \òûɸîÍÃ¥ÇS V§)„"P[p‘‹Äúk’ëWjO-ÄÓÙ„må»vÎA+yBÊE¢ 9,?‡:ˆ€dh+B3ªÁP"ñPÄ›;ѵñq>™[ÿ1T?€Ïè÷~ï£#ßxþ©‡ëµÒO7j•)<9<@Ð[Ä•ÀQnZk‚”âùž›ž±ù“gl›øvyu¢ VhËŒ»ym‘tx*Jî?J,ïÙÞV+ݰtnÌöv·¬°P—¥f ¿ˆË_EPp{><`bZ,Á„Î@u„Té=Í  6QCQô®oùÕØƒ1b¶¸Ñ´W¯×íÆ‹¬O/)CT à ˆmîÁõá÷LÐã@0ê¥ÂÑbvrb×y„£ßú¡ø>~Fâïÿé'ÿ—‘ÒúÚ»KÕÊOC¦y‡ëDÆ<@«¢,“„x|„¦I„'FÑ ÖŠn0=n¬Îµg_ì[³3€_ 0áÎ}í›öÌW¾ëÚ²Q,Œ8½ l“Õ-C¦inË‘3oãW!þÙN°™Eé+«Ð§ÒPìKøhòŸoÀà­®¥,Ü:I,?C3=qõÞã…µ€½øì9<‹ë6 ˜÷¶GÄ,ÁMbë=bý=z0hƒrY‡Î@= nÚôßïu©$0`  ý¬.–môĨ“=« ”âØâåwÍf%´bóšE{dG;€‰‹(±-ÞS$ç#ª>7Ÿ—"M@ öëªùá:¨;ˆ@"ÛPá¼}R„ѱŒE4¥Ñ†¬´ƒ2’‹‹"°”Q$äB̫ϵ÷èQPä½=Â%¯J:”ó%8¾ƒ'ê.Ê¢ˆÕ§”ß( º~ ÁQTïÏ=EÔÁ‡@ઘ‚Bð”ß/´x~€ÿ˜`]ã;T² Ä÷t «a¨Œí)uÈÛŒÆÀZ¢¼ï©¡‰­Ë…´½ú×Mûð‡où0`¨¾Ç à/ÿò²—V–Þ¼yõ#íNãíÛ;{c7—wB›»eúÇáLH©£Loê¦cW‰«_~ꢹç.;xç`}(b©÷ª…Õ»>ò vpažüuË®>ÿœ½øµ'-¿±•b³¡ƒ`]H0~Ë-”B…‚ËõWÊK¸"VK,ؼ*uÕëÄrÓuéÅX£x(³Åq)yßi{ßO܇CÒ¦¢¯ŒEvlùÆ ,@<œ8-ºÛêìÃ/ùÕE˜kQß} }°¡5NP@÷pDzÀë/€°o-,28ˆ€ö\°-(·šX=DН‹kŸˆ¦-‚–i9ÞʘP¶eË Z£X „g~jܨ –çøMú8xQbô%ðfpnDGÀûé[ë-¶_“s  ’E‰Æø®Ï¤†Rð4`„ψ9EÒŸ>PØâR4 ôAÑ•IAv› æ—,öoá×Ö*€ï¡xâ‰?Ïæo\yïÖúò¯\_ÙzÛÍÕ­ìÖNÙ)«ä•M“žœ$ÝÅרzY, K'œm[^Y²«O_²­Å¼e@»C¸¢gcc¾õÝw’CŸÂÅe‡Óhãâ‹/úÈu%Ñ&nÑÿNÝp´ÕÓNz™p‹€aÃTAØx+‚ßá§¶€!K>úï·‹S Ç‰³svÿ{¡ý.¬Bã­£HP(f¢õ£!:18£¾Áq"cÀ|r¹‰ñ£èp“àL:‡kð&p,ãç Ùˆ:X@ÍFª#6`Ì@ÁkUôÃPß½Ç9Rx?.DPÆÝi§iHˆa €ï¤õj¤AóqÏ 8ü>`‰Ö¬tÀ(6â~v=ª(,Ñ|ktV5_TfÔ_e]#x6!®M¸‚Çßщ¾à ÙWh¥YƒR*bø‰ïö«u¹”¤ÖÌO12ưãu£­B‘wß¡ø}N¿?øôÿþàÕK—~i}c÷[»å4­*ìUl9?12jɱqËÎÌ»Ÿ¥§Ý¨˜ÛÎú¶-^¥ÿÝÊšmnoÛ ¡ÑP#D8yï âÞ©¼%D´Z†^0\C¥° #„Ü2¤¥pG„ÉB†´±ƒÄô¸ÛÂä“rŸ˜#¡×CÄÂb„LE/üÃ?ÖŽ£'u}tè©.Ñ]F^"á% ¡¦ ®£_¥É&žuü‘DŽÖáúâÜ.ÂamâlÄРᣧÃq‚S“­åB.!÷ÐÆˆRN"ÍØc‡®“.!Xs`8,lŸ™,H*K¶ƒ& jÔ© X|ªà Ñ3 €ºÄë!¬{ŽV`ÛÜ[¯¢ i‡ÉÁ¼ŠkA ðx˜Yè35­(ޝ¯Z–$ßR.zøkÄÏ 'Èx‚¥B ìÿOQ£ÆY_©Ó>TíSp¥ÉnÇP|>§—^z)û¿=ú;_¼tî—Ö6w®µúéä¡ ;qäˆ8~ÔÒ´°Š–‹Ã×O`ýC ¤T¹>ú¾‰Ã‡la—BŸ­mè¹Ë¶¶ºh[»«„´Þb.]Ÿ^3êQߦŠN5õú×Eh[ÄÁ cFƬ±†{Ûjº º…»*@ŠBVËŸÃ÷7¯°AÂEV G¨ —ÎÅll6黽u\xê}„)Jj2žÊYrÌN¾hIRd.¤˜½ËµE÷P}:þà9ãpc8QeêáÍÅdÇPRKFЀ@¤d ˆµÃêDŒ=€<$‘"äG˜éå?·èzÈÖ¯å!Ñ «‹î¡&€Ø^@À§óâªÓ¯®¤ßûOì½µ]¸(ˆ>÷¨0g /„ŸÕ¿/H6 Nx _ˆA¥„-þ¥½V ¡E7€ÿ£`¿¥0ýnÁüEáKêgVö_ äÊðƒ´Y·ÉƒË>ÞÈX{æñÑÏýOß·²¶ø«¥Vý±TbnþÜ™“pÚgií5Hu>ÛL1f&EóEÀâ4ÎèÇG(§=>?n§ï»ÓÖ–í+}–ö]/ÛÆâ›;4…À¢î5¬E8!ê*ò…ÀQ£_¯’I =×d¤ÒJq¿ —Fs)#Ð…M­b¶…x>ŒëëøU0Šâ]„ãà©IÀ¿4VR¡—b‹+—ß'×ÂZSÕ7ÐÓ¸­0n~?PãØäæñóá „ä;s? 0ƒð¡§¦¸õóGr¤4÷zÜG×FæÐÛÐÎ#càÒϵ"°Gê?&ËÏ}Vi6JS>n½Žä¾òõñ€ZÄöE,þÖž•^Ä ¼ Š"Â1(©<ÍÆ'"– ’ç¡Ü êï¾²”«¯*?I½Rµ÷˜¨ßBp7?î?ÇñG¦ \äjøÕj*¼MCð~P~¹Ç¾ñ•»¾zåWh¼ùàøÑùHtnÂâ“cĸ)«Ç«­v*‘ñ‡_vpk üêb bx\ÉJe—B–&©ª˜sO¯5=à6k_zÖÝ9&Þ¸×^yñªßGã³Ë°Üò :Ð}I‘‘LåÎÁÆÅUŒÂ"–VœØ}£ŒÒ`Ë–%”{¬í+},ƒÕ7k#Sxx.|Œ:¯ Z áßX­C0‚Ä3¦})·HºËW˜½ÆÝøÉ;é(vý \x”–Â;væ€]½Ø²k¯îÒ„¾¸ìŠâ{4 eD °ˆAàjËUåºÂ0ôfæðŠŠ–‚µ‡³àR$Ñ#mX'+Ò&S°³[#t"sý— ð ™âu”½Põa@ëQ¢|!NR«‹D˜€¢¯_I”P@k¤N@¾`eDšò‰Sxê@YK¿í7 %ôBä¹äºê¦âS¢XÞ¡x>&>{çË?š¾qùå½píÜÏÔÝ{³“‘Ä`Ý$9}šv¨Ï]ÁP÷‡Ä·CÏzµ°Š°5<Ó˜f[Pd¡Œ5ñEm³i–ÑŸ˜òKfÏÞÖ®¼ü’½üä³víå«J9ù±ºªóXpt\¬¹è®µ*4X\ÛñøÈ’ë[-Üoªðä¾"¸ür_e¯PJ˜Õ×áa͵¹3 æ˜:èCAa5DS‘„ ƒ¯Y Yq+d…M… öäÃÂðœÇbg“{DôðüSƒªK ©ÎôeÐGr&æ'ljn×ÏïZi«b|“T#cÆÀ ´)ƒ¸4.ï êÚH¶ORÐs#‡ƒ¶z=oËE›'}^à€Ê7þͲ­oSÁˆŽŽÅQP1Â+Â0õ#Pµák„ÀìïcxÿükÐ7‘bJÖ%(!×ÃA+ÈËPÜß“‡¤5déäh<¹zÁ€‰ЉH¬85–Åg¸=Cð|Nÿá‘\_ºùî‹WÅ‹¸ï››ÊŽ,ÌQÈ’†ÉÊÄ[úñ  irâÌ£‹ÅR„Å€Näõ]¬m¶\*l‘žÚ¤ªç< Z:ÒX.ÐG<ØÀ¡ãGley‘ªÀ5ÿ<«^+Ö(ÆÙðãsåýÙÕrœIõ|Q¿ßÇõ•^K›a£ú’€P‹J¬ÔŸ˜p]åºqå-hè'M-p¿;("Š( ]éøËsÂ8FÀ®^êXz‚*Â41?H«@& `FŒ/÷œ@ÙÃ:«·žß5—ãjÌŽMÌQI˜ƒñ‡ÇR\¯BPÊ‘“Ü„Ãï äÅnµé‚Åë+./Jbw»âs JLâà¾pJ ø\~®gO @Q=ÿ”e¡ÆCñ’·Çâ·HK2 Vа}V"bÊ­UÞ+„_€ ÏÐAOb_øÙ8¼OòÏ„½&K¿M¹ë£ÇÞZÕ³„XûD¿Ü¢¡ø~0?þxæÒÚ¥w[|á#ÒogÌu6’H9ýD’NÖþ( ,4|ÂÃUN`E©ŠSI¯„F豄±H·œ|>‡™{ n3 z¯N³]ÌÒöú:±o™:úY;}ÿ–I‘çÞ¦£Î.1: ^¢CJ[忪Qf‡Ÿ•ˆÆr>iíG¹üÈ=ײ^1Áè|l@¬@y)uú›7–í0¤–8è¤x^p#LÔµ¢5˜Ã'©ô2Hçà³é¸ÇîxÞQðŒ0yôÈ¿ã‚#XаîxüTüœ°WŸ^±üòž‚ëG[‰Öà1(¬1ÂGžÊCüƒ ²L·¢Ôä¸@2#ƒâ¸XR†© ʹüÀrû±æîÕ´Cý:â&¨qìOþAÑÄá´y²¤>®¢ãr8EWøÞ’¯L~y5ò¡| Ç&àˉäxÕ>ÆÓcQ¾ÃCM_ôô­¢† à;|H¯÷©—^z"ûµŸzßùÍ«¿æfã÷¥g&3!ÚScr|«b8Æ€ê¹BMñÓNašm†C¸Ç ×møuè¸ÕQXâœÓ¢;ÊÆêÓ¿±[¶ókÛÖ¬Vlåê5»qùõ욤ÈRlvå¾C¸¯GÇqÅyÏ…®í-ç6)66;¾í ‘æÖ×j§j_¢ Ÿ»¾UÃB«‰­p€Ã'¦HUŽÂG(’÷.Ùüñ2 Þ‹@‚Kô4•geݶw,C ¯ƒwÈAkHÿ¤ä~4ЇÕV¿}Î H†à"0žˆ5œÇá÷xmŠLñ;Çls‰Ž>œoýʦd@‰B Kße\÷€ëвËëK{Uú¡×™¦À¼>4æ§8›ª42L©¼8LÁUJ…F¥~N¥—HvbýUBÝAAˆüäçô¹w¡÷]y®Q¨¾„_z§RÂbÁ°üzpM)„ýŸµœ¾4ûïs±hxmrf.oÿìõî üë† à»ü 67_NüÉŸüáÃkåÄGFÞš›O$hÑ%÷85æØ(pòÅbãç>n¾¦Ï*öoã‡j¸E´‘¦F‡™&”è±¥‹+Vƒß_ÛÞµ½þZôÆ×Ì<óªÙ}aÚr ¢LÊí qG80_â¤çæ£3Ü -—öH*ð#v`ì’Kïw±ÈȾ¬ þ¯+D)AeпkÖ~õ_¼ ׸fç^~ÕVòZsL(7OæÂcð'K»¼’µü(z–ž€ª[O)#æGb95÷tŽ.È~‹ƒ¡@`û.»"†G³”9OÙ¹§–mõò¶M$è%H=±Öƒ{‹1€»^Y«Øå«›¶±U²‰î~Ë!;qоÔç©¥0Àž‹¿#<5Æ3ÔÉ'±&t¾¥¢ÅÁÊèV¥tÖ%Ï/”X||¹¿iÕÔHíâwšz®1o“ÆžP]ûXø B“ɤíè‘tÝ™@¡Äèæ³d7–oBG¥å6ñ½CzK@¢ºÜÊ¢eæP6ýƒôØ›²Í›;¶µšÇefã )—;Žô+f{#ÌÊì ¨,ç‘Sö“¿ü…HÚˆžKéovDl½9qõ©Vì’˜aZïûì¨ý÷pózÑJŒë7àÍSäׯM—bcD Ê¥Å5º(‹"))~Ö¬> ßtp¿EÚ‰‘a8rrÌÊ[5[ºœ'+°Ž¯PGšÏÇ8*”@_)ÙÍK{¶AƒÐaÀéÓ“4:aü æ6¸‰ªóÚ,¢‚"ÕÿãY‰×¢ðG#Ê[™]šœÔñáÕë@Ý|• Px$…°oý÷­¹?FŒõÐèp­«¤ŸhÌWD8Q~8àëý /A,Ê¡xïo1wð#4Aø–Šø.6×÷ù-Cð÷\p ÿc_ýÃ{‹íŸs“Á÷äf&F<ºÓvÕo‡×#n@¿õØØ.é¹6½ädÇ$xrý¸·k›×¯Úõ—_°•‹AÔ7à¬kOÇ&§ÇìÌ©c6E ‰© ;ÉÏ“ôí ° /^½b úü©…vº’³éé).Òh´ÖgW6;´ì Èœ½òìu»øÂ Rû®¬?ž[÷Ë–õÕCàÜÌ‘´½çÃGlâ€cçÏŸ‡i†…œ˜O Òà)´ësº+å»?òЫ•ê¶»Q…® 7‰4&mÃ~h곚۷Æ(Ƀ€< Œ¡u„TøƒæíFí®»§¬SnÙæ2t_Þ»@¢!ë+%»ñÊ.ŒHúþsÝ“£›™Î©.ŠÆ(U+ÐÂ\Ƽ$)F¤ðó}åg=FÒ(H¼eFš—],‚t¢‚!]:IË`«D˜Ûæ{Œ¬A¤JjP¸†pa'âMè5P0¹Þ%…ª‡Ç`Â@øR0[ù£cN÷ã·ø§»×c¨ö×áuÿÿ+/û,ÂÞj!¬ÒÜÂ!;tç1;AŸ»»ï:IÝyKhlà!„!ŽyìÌ1;xõ²­<þ5ÛÂÂÏŸ:ÈpÌ,]o €X9:÷6¡¼ºlÞcÇø½okË›Ýws°†š/˜q|в‹ˆ‚¦mêP âOÄ^}…ê?Úz©Ì6J¨!‚P–Ì]nñ4Ø)7„À­Ø[š @Þ.œ[³Å—ó›˜hC®4cŸPEãÀ5RLªO~3ÆÞw¥wËû9'€õR·ž„ ¯@‡P ’§oá MH‡¢œv¶éñGU_‚øø²Æu¬ù HÆŒ MÔÁÂËõp@µûÒ8seA4ã/ʹã(ÇB¬œ~ w½M(¢H%*ô“/‡‹s8—.5¤×#ìUÂ'©ºâÚ$òÞ¤ÄÔO@eÊ Á-r÷"±èµ;²'vNUC·Ñc¨þÖ“OþîÄW_¹øîz¯ö¾D&>Aø+² Î F•ºÂJÒ›¾Ï-E!}ÉÕf#–6·mõÕóvã¹gmù•—ù}ƒRW³#¸ë3³ö–GÞiw½ï­þh­>¸@›Ž8Ì“*{ a”/@©‰™I:ùŽSìBY/Uyã´íÊQGЪ™ÔÃмˆ :EÚzÏ2¥g|zÄ-Ì2i·€PÁº9Lþ}õ9²ÓÅWWñ,jÈ’>QzñI`ÄËJI&°Š±tÄOÓ-ïVí#¹ï~`’÷mÙó5”DÌ&ì%‰÷ èͯ<{AÒCÓs1œò¸ùŸw„H?#L-êïÕ¼cr{Çq{Û}gìàÔ˜%fHæØPÝ-øü´³B2bú¨vµ-ß‹V¡Æ?¡èîßbë¶zæžµ=›?=‰&g€¿–.8ï€]PÝ1x|”÷'K6ž!ιCÔÐÝ:ÞCÄ2Ëbù_yÚŒe¸#bxš‘(kˆËí¥žH÷•TùZœD.-ëdâ´OÛµ‹y[»F¼ Þ•_@H›à$í k¬>ûT_È•ð‹*•vTWbƒªÆ~z š~á‚ïêk.ž³³gï°;ï.µúFiî§Õ#@JEŠB}Q§ÓO^ÉfŸ~ø‘æÿÕ\âÀûåÁIü‡¾sôüc¨þŽÏàùÏ|4^.¬ßSþS.Þx :“K¥‰ï‹4§ L 2eW®d„8Ü+CS¥ïþæÅUÛ¸BíÎ)¢=tïývö¾³6yQÑ´@IDATxÔf&ž±†K›/#o?hš›d&lÀh˜²Uv^« >hÖ5›®Ì¦¿r‰vß4 ¹ç­Ùgî²S.¾ôMÆq=m›ç7y-ç‡ èDÈáW¨„»¼K,?šEPÏŽ•TJ_ýAžç€µW\ó®®64"pNŽ%W>‚ëW‹ì`Ú~Úˆa¹Ã(5"Uk­…“);qÇ„]xq‡k+rîŒCâQHR=Žhâ?û€HøxJA†_o˜mÀ …K;0«Ìœ#xâìú!¤ ðÑÿ@5÷â*ÌŸ Ä o­7)Ž¢¶" VØÅÅW}ÿ%¦¶å¢÷¹_u=âl¿•Hî t Þ¥úP Õ!ø¯á»B?ïÏõ¡C| °Ç“*¯Ö‘ôœÒ\B~f*ýõTÚyé}ù7 ûåßâßùñšðïŸä;¿äòìPüÿ,û£þV j׃¥bñçÿòKßüÀå+Ëc㥮“¢Ò¬ª>~Ä£®h³´´R¯úU6ñÞÊ)½=Rc=››²·½÷;FÏ£'Ú±~×mZ'Dë/—©7¡„4¾€ž±6J;ár²ÉT—/@Yé¨Õ:_ñ[c ËtÞÅ…Û½Ÿ¦òo@N¿@Ø{»”ÀªèÎÒéÅ"qù4m®SÄäãïí  0„P]ùÞ‚‚\ApéŲ ÀèqUÉ*ó-!×À)7H©1ùxqùEÐ[ß(Á·³ß.¾Cƒu<Ú”:$Å;€Ô=IèEIv±°è5¿ˆGOw•¢Ãú×±þ;ô=\‡Ï/îþÌ‘2À)š ¦sÖ–rï‘„GE$CG3¶–êþä¡~Ï…}êÚ›€ÑVå¡âv¬¹B‡”’/Ürå¹åþ•h³Æ¨>½ˆaB1õ>Q¤E'VÁ#_õ ¨db¢óB.7òÄ[ΞÙăZø»zÍ-¥† àoùÈž~úóé½úÖýk{ż¹¾÷îë×w§w6›N¹¸†EÝA(ÕÎK=â’ðÔW¿RÐŽ‘¾;õö»í®{î¹?BÃ$”TÚHKXQÛ¢‹-M6=*@CßH²•“pJºÔ•Çaó hBºzþ‚ílmØ$}"¸ÚåÖ«“ ‹AškÅÝ]¿d•íÀfüCšTîùíµùhOßßÿžwÚo=ë[ü0½<Û4ɬ1(C¶Ó¥Ò¯h²•éxƒë/W[{³Ïîë+7…ð79îP,BÈèÏ®.mÙ…W.Ñ®›'Gi¦’Ýß", 57¢”»FFŒ¶Yk¦Øä9ð…ƒæàZåÓ_±k/-Ûµý“YR\Tø™[¥þ&˜ÇâŽLÅíè½LæoJÝ©® ¡)Œ«M@Œ@¥Ãƒ>@œ”w‘$ضG1RŽ0èÀá½ 3´(SSÒì@ºÇ<=†œ!\|QPä·áõïQû_Û«Û&—~Í ŸMÚÔB–Huõ5V ¨ S ŸÊubä!”üÅBæ`tŸ¥Lþr‘U¥¢¯ ‰Çƒg€1÷=ßæ¢ü žOLCHÀm4ׯËú·å%pYŒcó',×DWæ½Ê¨µ¹"GšÏ¡Ÿ¡Ó”èwøâäÌì7O s_õÿÖk^ äK ùð¡ðmŸÁ`ð|èKÏ\9¹•ßúGKÛëï¯w¢Nœ<˜;zt vHß ˜ ±+:u‘¾†°úùäžüŽÝýöûížy«˜à/ ðð Ô¡’\´>uŸËFS»Xsr3û¹#öÂÇ^óI2â^5›,áÎ_xyÑ®ã^§D“¥>@Nƒžôê“ÛF jðóC?Æ`eº¸ÌGæOØ[¼Ç^üú ~§à=®·Å80Ab=*èºx ”—Š„Ÿ ïÀHÌŠäà]Ž®ì·Ûâ:U(#ŸN]œ®O,E_kñT½J'axCò,ŽAZ#}W§ÅWfœqø÷\x¢H â¢{ ¥Oìß$ý·³Sµ• F€ï¨¥7–›Þ€YhÎ𢍷(EÝÝC)¶y}€õ°§ëªþ'põ³´KK  ²(œZ ¾Š¥!&ŸÖ•cª=¹Rx>óÅEûnƒ 1÷'뎦ˆpLuÖZ žSÝ€*"•PÜ€ã÷âmcý½ÁìHâÙçî_ùgÿò{¿öou¬×ÿ@ p†[ã1Tßö9|îËçæ+nᑽzå!RNsS‡ÆŽÎ$Á¼;y„}ŸO\‰ìuè­ã;$`»rå’ýùçþn=î()²šºä²q´‘vü 1)î´ºûÜs¹¢l¿L–Ý%>ys«¼w@i7‚Tv‰*àNÞ—õ»ÖT á•`PëJ£ùÖ‘Z·ºÉ Í a‡ nB¸þc“Ô&Ôað©s®?݆Î:Iþ®n; šd¸¸ÈQ†SÓŽ@ ¤„8âÀ 0èÚt.þ)•¨‡»®¢Mr¼99·…SÌ&|yÛïD§°K)®Ÿj#Åç !”êbTerQsæ Ôç_÷MC=DÓˆàÓ[ÏWꬊB¿ ·(ϸKªìCûÑAXÄÖ¡V‡$…ð£Ö³¦Ú~–Ë˱x9Õˆ Ó‚Ê#À)k®Ã‡‰ïƒ:?ë‚ÓÏz!ü<'‚–J¥åõ¨zR¬@.3^sqaw™`­î5tÈuFˆ;e¥´‰¤‹ñ&7V4U¡n>e•ç•ÓFèï¯jôì\l'Ö¯a77mÏCÄãg¦Ø€XWÇ&¥ˆU„(Æ Ê-džjäuŠÔÞ+¿º|A,˜¥m*¿±Ì¿¢.¤„5øô_Q†K#Ñwlþ c¾…~;( ûe…ÐISñú‹ã¢°¦]IŽÿ7„÷«Ž?‹Ûé3Lñ©S¾ M—VçaÖÇ¥@ª‡@Ã@7)A8*’Õ¨WÕ-h`iR˜ xûˆLNyÞŸ A±¹Ï!-¨žäÞwÃY#pÎçù{“4"‹Åï„)¼F^.Ť1õîÝ…’å o‹¨$¡æ~ä HѪ•˜Ê²IX`ý¡ƒè`ª_@[¢äÀLÛýD,øõCÇ¿XM½rãã…wÞÞ¡xíóûÌg>_,.ýL£Ûù't²=`:f†*¸^‚<¹ªî?å`)é@Éf.à–ª/ =°IwUêù„1Kð!ö¸ý”}“œa„Š@Ç¿ZUa±÷‹aÀø›O^acÏø¯ƒ_ІÖ†½øô Ÿ®+×’8¾RÍg ¼R7\ eŸ]ËQüŸ>$—eÈ=¦üTh,ª&¡ ”>î mwnŠc3¸ËôÃ[[n‚/\ó›{dHõiÚm[ÖVWèó'Ó‰,p"„Mßçð³$bù)V¢Þâšú˜YM7:uÇ4ƒà Ì…ÞÓ#à„cÕPZç j NÑÀtŒþ‡­:-Ë*EèÊ-¿Sp„ô¥ßÀ”»/%3PÊÐ×J&+ï@M<ä6 ã¼€kqH¡ú/ã³UÕŸ|>6k ïyŸ¬>þ‰H¶åIp?c »çN}¥¡ ®DÅðW3Ÿþ‘ûÕWþñ/}œ3Ýþ¡à3üÄóŸåoæ?Ð ´ºÓuO·zŒ†`ƒdRô£Çõ]x¹¼ ÷dˆØa Ë%V–¥ÔF@ÚaûÁ£Í5m¼cí"]rJ”vŠ+⻄" ý¹q7ù]$ÆÊßÓÐsÀkågxŽ!sþ°Ëåk%tå­ãÒ]€‡äÁÅ‹W÷!ñª¬“ÂèpnÕÛhÜŽ¥!1v«P¤Ÿ`bð1¢ÞQGa,+Í4²3óðüQ(‘F©KW^fðh4؃ˆzôòWÌ+é’ í ?£Ø}ßò“&Ät"›~E¢Rlj²ÑDÎRT=6b×®Ø%WCè!z– úh,—² ¦ë*Þ#ÝW+(üÁ‹bŽ_‰¼îá±.=°ßDû `œSJO—ÖA Ȫ+L—"‚//AàŸ¬;ì«1y1R´²ôzRŸ—z$*®Ñ÷=0)2¹þJ3*Ì@?ñ:þÎé+õ^.ÁSÓã£ÿþo¿ï©ÿ'+Ú/}\»íozð裺͕íÃϾúÂôâѻ㓙p:Cë>JzáÓ;P[…ÇdB†.¸ |Õ3#Káo8XÕvŠ­ûtËm2 «¡]å$!ߨ}rýe¢”cBX}s…°+Å¥¶Yz¯Šz\~¯aŽöÈš]q sFF*Òe‰:òøÊÆÕù òx-âˆåæúȇGBiÞ›§cPžtñ,÷ˆ¡¼ŒÔ5í» ÷¬P763 }wÚŠÔÍ`Ö¹«×¥ÕMLúT7î÷0|Mp°Þ~y äj£ñü:IЏò˜×ëqºôLN$luµëOèQi°ƒP4H×â˜e¦ÈH!‰Æs\™Œ9ª ÛmËCðÑPNåû50ˆ"å#0’üOî¼$œï|‰%-Ëý­kQ+¯ÞŠ< ³êùµÜ-01ùˆŽ|oõÇã!ן÷qýê¸ï=ÈÛ!´iÚ@¯NMd>ÿ;N>÷Ëí»÷ûªDï¼ÝozpÁ>åz7co¹xåÊ;Òóóã‡'ç±,°³ù{~8 eÀ1ä÷ÙÉ8µXqXò~5)Aêe7ˆ3”’Ö[¯mìnH›cõ±¤Žb½'#„XÊ$=ó–KŒÌÞ­GÀ声T¡û0tARfu¼Š rîódž³›—wìðÉŒ=}®Kì@ ¹úù˽m—Ëó1 ˆp¡ëøG<ÇuKàК-P§8G7š¶ã’ÚlŽÔ$¢4V}l2i³‡SA°iÜ$%'*oŽþÌB’ƧE¼F‡o†ld’ëögðp¾ýpcŒ#'¹õ­:«ˆ2å5è~BöõYø×Ãu©¶_Y)jÅ÷êƒkBÈ9†~÷»%ù¿Ëõç8|Æà!Ê:®Œ$Ÿ8p`ì©;y$ï¼ëãñ‡çñ¦V}ô£áxoó®Xþ‰ñôñH* §’4´€ðâûƒ¸…ÄÅa¥è?GæšÜ¸Z^b‘°¾$Éî샞÷ˆ÷c Í>œ&‚! Í—¸ö>*…°°IƒQ¼"¤Aã^#+«ø; ÇÖÈ*(Ū)fS«YçÅÐV:‚ÜC t>l6àg@€ü¾ƒâ)íQ ËÍ’"»PÓK)Ž0þ²¬¸2 ãé1Æ{Ú• ( øü3³qbeØ ¤ö<ÒwܨŸÿ—ÅÕu ¿9Hh¹„I IJÁ—´‚°×Wƒ&]'eW$Ô(ìÉMOij·ÙCYËL‚I@8¢n"Ä´«x–¾ÉL삉ɴÄÉÖ¶éä«>|Xb_¸UÄòµB¬ÛGbåúKQÉÝWº5ç+Ö #Àʪ5àuŒb@AóZÖ‘Õæ³ÒgÄ ý»Û¿ ßQãݶ>ÛÌŽÄŸšÌ<¾p0¹ø®wýpÄýºão=Þ´ €ÆáϾøžÊ· ?4þƒäW𤡰jœëஆ ¤*¿®.2~Á‚æ`ñ~EøÙÅíß1à±’²PmæÝUK”݆ñ ؽ£PÁÃùl:× e—û/0-è¿O#¨•šê2\£K,[¯‚ö@÷šL‚ñvv§ÊyUœòÚvõÃÜý0€SPŸHYï:݆vF†fƨu¶SRTœ§M¬.à±æä鳟´Ów¡yÈE*ú*tb臀7Þ’õE:¸/~ÿ{Ì¡,¬ßkØo#ÎõKœø[ï¥ Ÿ¿ G¡`cVà.…=4à˜;gÌ8–Ÿ^:Þ€#¢çîñd(†’‡ oej: s‘Ä%¦á­HÅ¡€—ÄòI¸÷;õȽ—âÙ·ö¼„ŠSså?/Œ¦Išp¯,–ß¾ðÇP2,Êä®BñR)•×¼…0üÈûèñÛ¬fS‘ÇÍdÿrú`èÙ_ûø 4ûá{¼iÀ_>õ©‰šUÜI>4=??U¯mÊÔá+wd™Ù|î¹v,z EÆ'Â ÔæKT&QN6Û4©h0<“mæoê8\ °P®^M¦H*ø£ZûœŽ/ ¯Eõ^€Ýào{Äå ÒdãcLù¡ ŽÂåú%âº$=$x~“1„G¡ì~¼„†mç—è…Ge!¨´©ã/òQÓß_8dr’¦WªÔ+ÌÒ_o–¯_·+çáá{4ÅK »B͹¨ „îëÚiI€9•oi=BUïi|w >ÿÞÖË/¯§­´Ö6J/¾$CDâ0¸8ªH ¢Xz宣LÕ§Ï¡~`v.d×ñXŠ”Hð…s©àJ$ŽWYmÞ#ê®®¬>:aÿz$Ь“ºûÜc$›ÿ7uôÉR¡£ðG”• PêU ©€åß§aó8ƒý7s©èçî<}ä3‰Ùgþùo~€á‡óñ¦TO=õ[±?úòSg™À{ž¢SF4.ÕI×Á‚K1PÂ!í×f\™6,¨•\kÄ+H¿kÓƒ¬óÛn-€ß;ž¤*¹ÊVWÀIÕ#X²&B­´²6¬_±§wþæEpÅÊë°ù$×Y:ÕJXy5?Õ¥²ºJU ôØMŬK´¥Å|N/\p°e%‘lj”î"µôº5}ñ31¹òîÁÞ éÉ{òù^‚k÷¾uÄþê³ëvùF‹ÁÛÒò„C¥»jI&ä\?‹€#@MóEn‘…¨"ü²¦©QF& ¸«ÏWzܨ}£*¨±a¬§(çÁfòùH´ß¨:t–td†a#R"-}-²Q<0yX OÐ'Üõþz´ã)_9Iò´¿.²ìme ¸ÖŒ2d4öKÖ^5ý"B¡³|@PŒGqZÐ;”;rª£¹Äçï¿ëè§Þù‹¿påñwþw]ûÞøCúxÓ)âíÀþ»ÿé,„ŽŸ¯{ýS㩃‘2h{‹…|¢®2@ ™Ö,9¹=6?N*±þk9w×ï+@ºfêy×#îU±ëԋߥg½ÚX)`ÏûVF)&Y@íW Q‡Íß“K?ý#³r£ æå‘B#H"iPrYHi ßõçõ²€Ò•cËúó¥c õÄoaZ…)ô±â]Òeò}ÊÈÿõóä/ΙfüÁi˜¡ÿߨt„j>ˆA „ ø<†A«Í{zªíGëDPjˆ-&¥¥NÅwíJE¦áúë:Ç'ƒvüTÊÊ”îÐÒ \¢ïÇUR~¤,Á ¼6Š‚ZWÕ5öP„AÖa‚”çî *kJ_먢¾Rû €Ûå=$ø¼Ðy|±”þqTú«V]@Qqù¥Üü‘`(ÃØAÅ£Û Jð9†<'–Oº¡‘I¯LÇ?p`þ³ï<ûž+ï|ç¯×t~]¯ú¡}¼éÀ‹/~e~=¿üÎV»xÏÌá;F'³'rþU¬l>ÌI ¯$LS¡@§²Û|gw#„ìbMå²Eòq±†azá«8½W-S£»BìÀ`ØÄ›@)š„æ‰ìX¬ô °òg1¬YôRºÃߤÍ8¶Ózè‘cÉ«ß^¨Æul!=Ž©àFToïdÃckDú­#ò×°øcf ó±œ?S¡ÝyúÔXÄ׿¾qûÇjD¬sÖ à´ÈQ ’sG{2€8Ìx7°p yü®‡ðÔk¦cH…x1¦›¯/û׿Ù%$oGøñ‘P:üïŒÙ7Ä·B]oŠ.@]*YVüuœzi&­MOe¾vòÈø¯œ9süËÅ»Þþ‰O~ºóÉO2‘wÀòŽ"/¾øÔÒç¿ô³ïj··ÏÍ.*-L/’M6NáŒÍäêµkÉÒ½óÙ ‚ŽýôäØtÆíôa3Çn¶˜â(ħXñ¿M¼bê0Ö—¿ñJø“¿÷£ïç™&ÏýÛ—’7_¢*€Þº’$×'ÊÉ$a²“3¶ã†Ù’"Á2yÆOz îß@w¿öÖ:„z}J êìèØ6²T¹$9 ‡å½<ý§©\UPå!%b¤Ó*IôºœZß!yI»ºé´®Aª‡ýñ¢ ¢ö9ÒǨ°sñ•„"ëQ ’‘1'&iEX´ºòAD5 y˜ž;5WHNß1†7Á~…ÈQãâÆ) ˆßí ¬rîoÏ%žÄJôĽƒ˜Ç/C››»"!K‡±CÔj)Bˆ`ÄGJAZÕùAòý|8^~Ü#‹}r â7 6,Ã…µjŒôž‘dÚ¨/Ô •af—²áÏZªüÚá O}è¯}äÒ½÷þ³yç,ï(pyå™û·{›÷Õ³¹‰É©£IÙÜ“ÒÉk/_LV·—“ ßu.9=;K CcyJ©Ï‹ n‰)È¢ñ:4ïè‘q–#¢oýÊfríí+¤êΑ\ÅjO¼ývÎOÓÒëJäÜ+V_¾Ly°e¸©íªñí«2Èèóóñ]Äÿµ+Ûa}Ÿ˜ ¬ÜSW›iÃÁªaÿ•`Àg Òó°^8jpC¶¨7 ¿, £±ýtR‚Cž€DÎccÎGfX« I"š›ã îÁk;m2ïMõ{Òd‹Ô hp½Mâcm°x‚>÷LR·o†‘Ÿ¾áÌZâ{úîѳó¨9røö.aÀØ9Ìa@ ÏéSؾnÉp‡¢*˜©g->[ŠWê¥Û!'‚ÿC—Ú}2+i»’¯lœ_zà-Éa§°Ý{U†ô‚è4}[oBÕX‚­ÀÙÖ=4_~ãøÑ©ß¤ê¿9ýà…wø½mçÛAìÍ<ñ£yëÚ¿þáÕNë±Öø©C¹£f‡ sÉ&1¦¹ñ”8ûµä•¯¾D§›m¸2e±ätÁB‘ØñÎð:úêâ,‰?5 ‡Ãf%üöoüþ7IzYIÎ\8„JMzköUÓYlcÉ1€´tl"™F ¯ÂK¸¢ÄpŸH¹Àª¯7@.|}­—¬\ƒ`›ì ¡¿äþ[Š«‹ˆlt…:ŒŠÑ …àù‡­Iøá9ÙJ7àŸ¦ˆÎ$ m#¢»½‚´¡AŒÂE!¹Û“ð!n „qyn}—ÚèöF#Và V)Ú%6a“Úüêä æ]Y&§¬&w¿g>9q~&)#ô‘ŒúÿHI Ö¾‘Åuئ•ø•×p Ú«Î^€uì(Gî?J‚Õ@•Al¡¹&• zÔ˜8\žz†2Ò™Fô ¨¢h?0ØÚ‹oýì2’Ô "¢}®@˜¶;o·úÅ™Ê7ï¹ãÈçï:Ïïz䯾ö±ýô;ŠóÇ âÏ;‚\¸ðí\ejñ‰·n|ã/ïówegÏ—s‹Ô±ÃÈ·ÙÛJf%'OJX³ß|îÍäâ·.íÈVƒK刈£ìâ?eÀz;ÅסqgÑ8/à˜W¾ú¾î,eyè.–õu:èd›,… œ˜HS"Ì®¶cpÿ"\k€çyƒ¼øuš`Èì§)ÎQ¡¤•œÒZøýO™¯ízEÿp ~^ÊÊ»5´H¸XåÛH)Zî-xQEqî#«ÓÌ3Òï?Ç™Ûo„!´ôôàôÚÕ©kèË»5ýúdïÍe’{>PFR𦡒Y‹69mÁ͇z ¨ºï(óÙA•&ýdù25PòøòÌ»Ü^hEù<@lïcLí†k[ÈyõªzEyx,= ðW¹9¹‰ŽJ<£}FFJSˆ5$r‘ØmFÄÂTðA¥0JqМ+~íÞ»Nüü{ß÷¿öcïo½vç? Éyg.·=û…Åë[/~âÚÆöw÷3“ãã‡Î&yüí[›ôâëR¯µKͼ1zÎãA+’¶Ae›Ká|0ã’ÃxÖnl'¹bJ~;a¾ùÖõ•7.'—^¹˜?{ˆÈ5üÞÚç\­}õ6‘ÖéiW£†Ö¾1:òLþ™¹J2¿P&üv29}f>"WVH9æ!ŸÀýW´ØœÜï#çà—Y3.Ï5Ðæ±ìòzÖéb,Ã9« ¥ø·7¼êV0Òүج¾¯3#@à»å¢ê÷ •ÀÔˆß_&”¸ihǧjÂÑ;*É}€ùÃUF¥h'ÄK=Þ¡H½&cÙ] edíÚ0¹v‰¢žª ‚Xû‡ šû¤X¯›3€÷åXR#o¤Žw+ñ–!Ü "|´Gšh4å6Y@º2ÄÙF¯ßÌ¡פ ðØ’-Ö)]¶ÝÖšÃíj¹üµûï9ñ|è‡?þ?øcÿëåLæ´òÅ;v¹ím/½ôRȯG×7ß|W«“­æÇæÐ·g’`hî’jËÃR™›HÖ Ø™¡ß÷ýè_Jî¹÷\òÔ¯?•üþ—ŸK¾ñ¯^H^zæåd‰¢™áïJ¦¨{g€"å0øäêk—xñÙcä3ªO‘=Œs°OÌua|BRH¹þù>jE…à1 ·ÆxêÔB29_I.¾EëkÄvú0ôÁÍ´´$¤`‘¸UôõÅ úÁC©ÜH×ÌJÓDÔU†É8ºÈªK\wÌ΋·p$]ˆ¬k†âÒé†ZƒõPÓ‡ñ²m¼©×a¢U&°F7`Ô¦Þø{I­F9…:–)3Ù[‡C Gú½–>…A mö¾p‰¡Ç+x?K­Ä˜Eüp:0¬J©…Ëd…*Â5Æ›#oàÈ"GØ#6Ii¶&A€DØèç»N“ÛxöÅÝÞÊFwíС‰g|ןyäÑ}ú{?úßl Œ&³gþ¹í%€ü»Æv[W~àå+Ën5ç¦7w²™­mtø6­·)Ë–õyðòúÃ×!øÍçiHqú<½#cˆ¬DòQècãÊNòæï¯$×h…•ƒ+.Ѐc™vÖ_ù7/„Ø;k¼¾åé # ¹>³E€W…@”ëM‰eR.œHY~Z\Ÿ‡üMJj«£NÁÑ*Ô¹÷ùTd6'ÁPc( 0A´v=r»¢¯/³yìE×Ò'êÀY ÙÑÿ]Ûa:ùþ|+ù:§ e³O_Àì·5l—.sWP´âßsÿTòî÷Žà™×_&M+ú™ûÆ’…SÊÄòÿ -Ùb;ï}îŸ%º‡€ÿþ÷?ô‹îýîßûè_ÿþ£KyÝ®äá¶–^¾VzãwŸºÿÅ·^{ -ž?|äá쥷®&o|ëyºä´ ´ä"íwHO½ 8ºTòY½F{ît—Þõ3Éñs°äO%;7z·‘\yc-ù—×’gÊ/£'SÒEô(õöZxr°®<"¾€7ÄTb`\Á©;L@÷,ÞÁz›Q˜ç/W߯íW%q†,¹UÔ…®°Ñ…vº‰fÐ’°–#UTÐã„tÃCñÒY'¥ ïÁ-vÉb•¨º@«@vÔ‘A{Gƒ<–rÞ4 ÅçßÁç>KÞ™3\÷¥äÝ.ÁéÇ’gŸ»H¨/Õ{ bjP‚»b‡]æ®®D"yÐãS Rüƒ˜BL]Btð•eDt|ñm²ó¬[höŽVûðdB(9"8|1_©çSb ?_¿þæA;3k÷Ÿ^ªÐ4•8â3–!Z b$.ŠVü]XàúÄ^“«ì%_½ûÎÓ_|ä½ïû­Gºÿµwý¥ÿ¶yÀùÿ€œÝÖàéÏþÂØVwç½o¬ .»çxuâä©ä.¾CÇÊÉnçz²Eöî2,*S¤ó©À!1f¥=tñáZ„¶æ(FIrêÜ\ršfko¥ývré⥨©øë½T<­×ìK§>§‹ Ð[T›‘pfÌ™÷oþ¯J®?¶ï²½ØâR>¹z®ŒÍ¡Kf¢±ï‘#¸ôa›¤cb›k¨DXš[)C«8˜‡‰I£Œ?Ö Ké&©õwíFƒÀš…ÎĽ/¼FîM^&îT1bÞûžéäÁGæ“ÃH>öÜ›.¯*Å?Ì Ø¤AeÒ«A xP‰J«RþÐâL²DÑCN^#Ðç·¿ô-Bg›É™üR4óT<×m×Ó ågCÄX9¶+rO»°5ò-ßmy=G>=ËW©‡Ov]ÑF —TÈØ‘rÌÃJ2b¾ÀRŒÁ8œ×B5}Œhæïk ÛEWîÃ%SKpž(¿WÞØHn¬ H>EeÁcY®;õï¸@g^ʃÏΙ»a»t4fW¯Õ¹>Z–aO¨Zq—kk MèJ,Ù•zmT çhhqÌÛA'b(Íôm-®W‚(=è”A£bÐ.^£L¨OH6eˆ¤ —£ÍPG]|ÕãMè±ü·Ät¢£¡Ð(D!­aQb¹ƒ„QokÕJéßÞ}çÙÿûƒ|ü·§â‡èÜó°f̃åÜÛ–skA:MÄyú¡ tʽ%dÚ‚&C¦eÒ4Z~ŒI1O@þ&ÍéÇ}êåD1S®Eû‡J(½·M¸÷6ῆ Oa¤œ®ÏùxJ•[H;Gz7™N—ºþ„—–1üb((=d¨DÐ “…»§t¿-Z±ð gaO9¬™lvìÉão+¢Ó›Ú›B4ê¬ÏÒàèÙ‰ä=8Aý‹ÉÛ¯mÀáúÉqÊ^Í@1|°y¾ãA rQÝ…‚^ä`NvÚmx\ÇÐÁ;€MÕBkØõ£­D„ÜWtौ$‰2« ê„Í0ˆ&£ÙÎ.ÊqºòVhf*¡8}~29ÿÐb²t¶€Ë“^„üö †"2.Äþ˜\A‹8 a³ 258*®+tqÁÙu·È/Ñ4·Ê&9‹h½ „ÉðbèaÛ\¹x—î½€I¤¤HmæŠ÷Çm$‹µM¤¾6hjv¥š£ääÿ­ ÑÑ€êþÚ3{‘R·ñz.[øí¥ãg¾ø½þk_ûЇÿ>þýÏݼÛqUþwà¶$¥üÖÙ\õԇǧ–¦&דê4[+ˆýö™›@¤¥Äö6`¥ý<ñëyJg×èû¦ÑèãÃiQÌ!\£šà±ÅÕ— I@Š×mRk;4íœÇp6GÈK7ùÊ—/%W.n2†U„sá|98©F¯Ž¦lä"Á)‚\AŽÛå¥Þº-Do ‹Lã.\"%¶…ÿ~‡paÅÛ…-Ú€¯ цΪÿ›ÖZ'ì×äœ:Àìá~S¨ž¡­ö,ÅMV®×’¬ü%Ô“£¦“Cw!¡¼Ä?l’¥—C—IÊQåðÚ%R”J܃>y#œFÅ ;ÊWÆÞÈÌ?* cK¢^HôvX¶K¦±¯KðeϽ>lœÉ%Ö³¨'†­—‡ªô{"³j¢ÿ8 JÇöœ‚<ªFÊÍ·¢¯*Œ‰>&dALΜ$‰*íw0ö­¥™ÒÞõà=¿ø±ÿ§ß|Ï{ÞSËdþþøÿ€ÿ£«oCfÆNüã#ƒ|ûþõÆÔ«/¾š¹våRR™î#þ£à¼5By‡t¦)ðyŠª5zžrÔM8š‘w€‘§<ãgÖqÀ€oûn kÚ¾Êì8 svxÀWol‘"ÜJÞõÐ!ÜO¥äË_z‹6ÙÛdѵ“³wÎ`|#©· 15ÐE›R«w@©ÀbMã2Ò AW%¨¥˜¼Ixð6s=²DU],à wÝ…Xl°Ó@ñ§ˆ¾>½hRÑ4@­&ïzø,üô|þ÷!<b(ÈI“úCGzP(ãŽtþ˜fÛ‚Ãj¼ó¡°pèIv·‚8˜ lqÔ×­¹gNë“oF!ZYÇR]ÜÈ ª+&$©óK4í³'árÕ€5ˆ›/!rü%R€Xy‹ØYŒL\Æ a« }ÍÏä“ù9h%ÜXiÕ7ké GŽzêþúÂùwÿä‹ï}Ï{H:pôƒåÿï¸íÀÏ}éÉ;‡™‡?Ü«TŽ]]]ÍlP£oH•Þ<~éáb$ú¥‘ç>)A²„ëövZèߢ‰£!†+š]Vª áæÄ ÃÑÛtÜ!,Ðø «k×v0æˆ6Öò+MlÕRòï:DY¯|òâ‹É+ϯÒšTÙ#T *`¤BÔÖ(,J! ,&@{Xïw0üõçu *…ÌRG Çù×!&×IZÃH©à–Ázc 2É$¢¼Uv'¨¨k\ÁTy6Y˜[$1éX²úÔë$õ“qDêã÷ÎùK”ßn-#:Áu`1ßbNœ·…ÊÐÇs‘'&BCå.Dbí*ªŽ÷°¸gz8¬œäwU AOæ)ñÑàÅÜFU„5utÝ{\#«#èI¿ÿ„ϲeêôSpóE2 ËÜÛ„Qcß$ª‚òÍ*nÂT*:3´ws»Ûxë­Æ«™|î¹÷½ç½OÝ}ÇÉgN¼ëÌõÇÂS,ÿ‘wà¶#ù#•û½þ‡w7Û3MÒ[ïzß4½(%›o¿ž4Ö7ánÔ×'X§_§Tº…¢Eš`L‘§¯å¹Orz¡Œ¼X ËõH1Ø%CÀâ1^gn±–m,þˆ±¢Pü â¯Ã•K¤±ÞwÿÅ<ËÉK/­&W¯Ô(îÙ£ÌcZæ"#MQﶦÜU¤h1$Ëyi§h£Wf _ÖÐ×77YL¦Qf!,U¬ù­b Ü X²Ñ›o3yáëo²Ãqû3œßV]ã­>é“öZûçÑ5ŽM&Ó¤ª®…§ïy–D|TÓ¸3Û‹³»Ž>‹¾Œ(ëÃ\¤‚m–BuC¶õàìêàŠµ-À5 ¦àÜ4þõsSÉ+/oQߎ®<mQNM¡%dÁ¤o\ýØö(Yð-þi·Ý6œVáùôSxNR £Jøk5À<ûœ1|Ï¡\Ûk Â•—àó§5×·_¸š¼þâÊHJ˜':‘tØ’E›.—ºÒäæ©ìšóeŽrx?Œèë"Ùè¥hP ÅR_ª:E2x”ì@$_7µWó£c=DzQ´7BQ‚ÃÀ"!`ȵáð4l&³ØgñëSyx¬ªK‘XL²Ý˜i˶?ÛÙÂñSš®š24¼’Íonáȯ<7õÜòZ=qü}4Að Ë÷ÜV 45|03ì¾wg·PÞÅ€V ºO«±–”m· Ȭ¹ß€ãgè#oÄ©.¤“qñ““ ·(EÈ‹áÎRÚ¸gw`K¹í²ÍO×j¯ámˆ~:Ę-áö¯ÏðЂ‹¨˜£$0‹;ð޳Óɵ«DáÑìâi±• Ô Áa †­Ü¢X¯¸l†_‰xóf‘$æˆ ˜Zd~¨Yl ]æ ÝrÈŇ%k%7Ég ãœÇm¢ëXñ+€Mca“Ò`¼]ˆË­~Úë çÍ`ÓÐ’E7¨Â+‡7:ЀÓzKp`-ù¶Ê’½[yÈ œ!>¾À–(ÊÝY…ZÁ;× @¢„¤T`¿ÎÞYÏ瓌Šêû=ýúûψÿ ®¸w»H(øõU)ÚÕñÜ7fæfsqié™üµ~ŽÛÿãO?úÇ}æŽûCwà¶ ~e…rUbýa%µíî?9ïtråíÕdˆkmr1C}>2ñ~–J9,Ý=tÞq\}“D6¨ì[§¨göà˜ëIæ§»É4T#k´ ây–:Ã{‡H83ŽÕåí`;€;Â<É„ÃF[cWH‡ëân\YA¼Fâ(!•رVÝ_ëÔáGJ)X»k}•JAVžB¯Ÿ£C±åµÁâ9:1 ³]—î¸ÈœãÝ @{êvËá&|aërrå- òWkºXØ[ĉ{ m:Ÿ#âbo÷Ê$$3ô§?‹td晈]èq>·MŽl.@ïÃR(Eºqúøä³§OO=yß#?õ?þ¯g2'8ê`ù“º·ø'_üÇÅÞïå¯ÔºÝ]^Lîvv¹{6ìîíuüõóÉÂÒ¡äÆËoaÕ®ó€v"”56)½¶zm›}:É$¶€2y+ë5bç×Âh§…½AK¸ôM5ËFÖaµ×hHÁôgÜyÆžxÕ zäÈ·p•a$.àŽÙÞr€÷7r…ò8”§m:| OàþÊ͘0*€iBQ°Ö°¶×¨‘§>­Îm¬| ‹µÓÞˆL†Ð^@fõ_[ƒ÷H^½¾œ\|i™c'ˆ,ò"¢E‹»Ä*{Náôºê†¬W@ª#nËõ£0ï»tôiÐß$,ýDút 6Ÿ‡iL4NÀFš‚>cÊ/ï˜ "zÏÀ®2ò””ƹ®Š×Л¬u¤“:G[ÀἪEJ›õ´6;ž¿vîðüo?pÿ#_xìÑüÊì÷þäNò7ÿŸ?©çþ`œ›w`ß»û–fšw=·úú£„°žËg¦KÕq,Þ<ÔvÚˆ¿›$úF¥^‹7²ï®®Ö“UžÎ,¢{üÑéyríipçtî!ÅB°¨.Y~ëdʵŠêÍ$å€û1@̳NÚ+¢+ïuD`âÏuyè§íAú€ÕJ=9À ûEo§PaÈÓˆóãÌ¥€A¯@µ 1>#çчµì£Êlˆ Df ¹X|C +RkM7âoÈ5˜ŒÓÆÆÐµYMA7®7“mÊuk¬(X0€˜†.ÄK´F}=Ke9¾ÃZ°‘r—x~Ûm‡Q¯`ÃNó¤Wæ7DN„ö­ÿ¨CVêµÞ@‰ûa¹.¥~QE=A)À}-èiÓB£ N ˜áñS”IÃ.Ëdi†™Ù¹Ò³'ÎþÆý}ð·Îýÿý³™{±N,w`߀©;ÛåRyð£>òèýin¢X#Ì÷Ûo’·¿ü" 6Öì6¡¾-ÒvATűߕzq—†Ÿ”Žê¼5à]üêBé4dYU§BÁ‰pwì9Œ‚³h¨³ÒŒCW|·æŽqîö¾0…·D‡à1»›GJ®ýòV18êþ+!þ–qïÁÍH·Ü<:ï¨ q ~))1H‚¢-@6šb{0D×Z}-€*Л¸Ç4ÎG`3Q |¶É%°G¿f\ÛPMŒeÀšl¼qm<ª›È£’=ÇHBœäâZ:ÛÂ!º#müщ ÆuÈuUÑu´_H mÈ¢ÿˆ>…´¡FaÊqTôá~¤=UwîS¸ŽªaÌA”ùB䟤NâøîEZ¡…­T*ÏÜu×ùÏ–Æú¿õå_¨,ó ”ƒåOëìkÀs—yvº5™rV+GJ'r×wÐcß\M꛻ʞpWÊcÃwVÖ“.=ûºÑRؘ’+ÀrD¸™–Û&–]]ì#¡Ó> ãdNVÑÁpy÷Œ…[—ivÙè ›ƒXn*°óµí˰¾"2ï.*ÀŽš<6Ê”óGÀQpRÀ”aNE¸m‘#vìa’pèQ¾] ‡^»´¬Ý¨cŸ fŸ9I"ó±_µ@Žë\ë¯/g»@ × ;®Sù¨…÷ÃVç6 Ñ61àš£êb½ £ä·‰G&嘿ÕwFDÆLl„öÅ~ ó’ðÞ Ôù°%8ž•ˆ”ÚŽ‘è©rXÙ¸¡j÷/ FLÍ·'€Ûœ6:ýf7ͽ9»¸ðÔùw=öKÃf÷ÿÕO= é:Xþ´ïÀ¾&_ûê§gIGý­´xŽ88p5W®¡»6’«kèá<´éþþµäÆ«—iˆA@õ÷KH¦è¶HÛëÀ­Ú˜š ݵÔuʪ1¯ÿ[ËxƒY…¾&úpbw,’¤b]ÿVužø¤D¬þ8ï¶î½Àd˜€Àm5”À›mK•'BÆdaÁ>„pÀËÝ#Þí¦ÓíÒ`dš‚«ôÜ[ë„k00á(’ÃSAz©ÒtÓöáó6=|t<9‰Ï¿À¯]í%¯¿Þ$©.ŽAÒlCõu œª»W™»Ùwœu€Ïc;D;BŸ I¶ÏÍÚü˜\\C4Õ䓯C p¹3¥"‚‹$QŠ‘íÙN Z@ Y|DUZ¡÷ÔaË•á1i¤ëãcs¿³xäô¯V—ŽÈrHÁ¢ V)Ãö­n#|õëú›RmÇD"í bîÕ»`§ÞA@IDATKæp\‘ºCT_Ú#žÝÎÁ€¤Û¡‹ºsª»IÄÞ ºîXÙ׈½iÜfãGõ0GHÑÒØˆ×$ÃàÂÔϱæíp¾"F9ÊÞSyB(o`Å5º¸.C/练œ:Ât?òô¹áÆcƒ*zˆnvl‰|‡<‰x>{lHÞVùr{.ï¹´-¨FIðŒå—@VÂmHop#¹€·ý­é…Ó¿txþä³ýC?»ýøãAnØx°üYÜ}K~á…>³ÕË~.S8391U1ϿɃÛ¶“ñʼnäï§ÿrÒÚXÄëøÄs œé£e7 –}=x@æ‘…3óÀ"²Ò3$)áCï¶H!¦ÀXvvˆ‡ÛRÔ¸*ÚûÃãwóVšå¶!¶±îÔXm&)®Ä),úcXý«¢o »5úïq®2l0ú.Aß.@QÈÈ©#ž9O`§ †„ÇÜyU€á±Eê8¦íàô(.!²Ë­£Ú~>@ácÎHà'¶ñÎᜓÑx±ëMÎ>:N;I™õ\Zõ¨ã èã3ïÜ•ø½õæzÕ'¨!v­ÊPü= ih&å7'¦ÿÊÙûÞ÷«}ä¿üæáÃPbõŸÅhþìîÀ¾$—/_®|có·Þ¿ÑÙùO³¹ù…l¿,mzõ­n^K6vÖ(}µ@bÌÉäØÙ\uËIs{‹æ• ¸ŽxÞ'⯅[,‡¸[F¨`2¸§ R#¿höOz‹8Üæ,Šrhô¡Ö*oƒÊÒ«Öp0'‡@ðr˜ÌñÐgбp†ãïP£ÃWÒÆ8f½€>ºy¦@á b”耽¬Ý@µ±­¶c$úx¤Û Z8µIa„0ØÜC‰Á8-ØÓcà¹5 ÂÓ™0F7íê¬31„ƒ¢½ Kˆ=|WånÍq‰…"€ïVä_xØß}âpþØT„i mqûMä™D}JÓâÕÊ̹'Üû]Ÿ¹÷}ÿðÛ‡#®,.w`_€/¿þåÅ­îúûëÙîsã剿ëA²ìt6“åõ‹T·]å!ã-NbežMæ"õ%Æž}ÄtBMåF}'ö-â·ÒhAhN:èÑÛ€ÔTØ y #ªßЃ=£ €éè<À*øâh®»Å+gg8!À±DW·žÝì¼cÃJ ‹°àˆ¶«Î"â#%hHD‚\àZ #Eâw ç„Fñ¨´ß%HAi…]s‚xIÀK.Ÿã:MÃ5H¤ n#•4nùîS h"˜†ûÞÊ÷›Û”TTy$"£ü~ÎÃdFÆC€nVîã×;ð«ÕBZ™˜½^ž8öËïÏÇþ¯“w|ß«÷Þ{þ?äß<é¾$/^uqKïÉOMON€Ê>ºpƒÎ=+;W“Ý«DÌ5¨ùW#ÖŸ\zHC±: à'ð Ǭ›nbš6R”ÙiPOÞŽ45jå5ík®>2 T Í4Ö9{ßð­M j”ÉÒšnäï@ Ô(’ $¬E*‰è³|õ8 6|v €M8À{ØŒ÷o øwŒëÅnPÆÓ g•ƒ›'\TÇå ÖÔ&AAÄ( ¸k w7ê3d\cìÃÇøz“h¸¯Öxaí<5 ê®SÊÙÖ° q¨DVu׿¸¡( zîA¨9¼[71vñ4ÞÎg¼€å¸•Hìõ7EY³qT)=™ÌØÆÔì¿ùè~ìÓßó='^Îdî ¹Êy,>w€ÿòþZÞzë©ò/_|ýžf¦ÿ`~|j\öÓ¤ÆÿÖî5"ú.ÿ¾.¹N ßqs±zœâ—SD·Y\ƒÁ>ÄmõëqºÛ4±lo“£K­@¬}5_|ÙTrš¬µC–ÄVË3 ˆ{Ø i ΓO„ó,ž‚ÈÖÿ>Û‰|ƒp Ö:ºZ{”¯Š \€`—µAýfX1´7Á;,Zâ9àÃÍ娲åaˆë )0A0 ¸²p$úkÀ‹ ÅÌ?zîñ.ç¶w`øí•Üào}7NßÄ>Ä¡ ÁÑC„àÚ88ô~ÎoaÒf] q]¦„áMÖ@4‘r*ÆöC0 Ù~e|bcñÈ©ß}ÿcOüüÒRå¥LæñðsŸþ¼—}Gv¦wŸ;wæ¾ÕFvªI¦ ÚorãÊåä꥗É}ßÀ}g=?¢ý ›I#G/'?‹Þì¡…dåí"ÜžP`€kKì"n»18gVÞ£ó,=y 'øá± òZf]‰ •,îª]Ü‚2Ê ¬í²ë:¦Óí×…XÀÈâ¶<ÆIVÆ•ã*žK¢0&@œŽÁ¹ ÆÿMà÷áðHæ€Q´rbÅz Ã7>ßz) {^v‘û‚`‰ƒçP<—Ãß<ð»§_!¼ªC‡ €ã­±ïyµ= È„TáEŒŽ E€Ó2_ˆg‰ž…0uˆ%*Ä*¤&¢„`¬ÿÜ4±è!­î U,¿qâôÉß<ÿàÇ~)—;ÿ{ï}ü@ç÷±–}G°Ë™)Îo×¥ëׯ¦{-ÙÚZ Úôø­¾Û$’h¸F…/›cÌD¤Ýv&&èØlD«¬€PWïâÜÇ*tΙ’I—Ã~ …^÷_ª?¤„Añ* £,²ýí?7€üãWWéßmôû—¹Ã¶ÜÒàG @B>Ü7¸.ÄCwa HÌHë¬rÓ¶â=ö0^;@ÉÃ#Ð%\JèÞÚ Û˜ž›#9ãpœâ½r‚ãKtïE:/ë ±Yˆö"`8|÷R›D#Ƈ0–&¨pì^7‰“‹?¦]O#îORͧ ¡ì·rJ¹üüá÷|áÝ~ô7¾ç‡þþóœûü{ø·¦°ï@!76 “:Úk6K»7nPìã²Ozr쮓ÉüÑ¥dme-Ù]ÙIÚÛ›Iñ³]¢ ‰,ØéìÜY~dú/¯á//ðtññ,[êKúÊÃ}ÇÏò`kA7hÇ´YÝj$v*òZ¸ÃØ€,ÛuÝiø q=î.`„EÁ8®=¯®ïŽ1ó |ãTé‘#žŸtŸç–´8A1E"1¥ö–¸¯¾/ÒTQgÐ ¶´ Æq-ã²*@^¤‚Úò›‚ª€DÈñ=¿Äi¹Ç¾|Öº/ÈÇcƒ°ðÇmª;#­ækK.”°Cèˆxuéø©_¿çÂ{õÄ?{ñá‡GÙ {îé?˜PÄ~ì‹ÛðÖÿÌÄÖ™A!{&íç \ãøÍ+T˜"óvéD›öq¥fiÎq6Y°ø×±ýà>#ãtWV¸NýÜE)Aîßø@ÄAŠ l¿ÅÉ=&$ö„±àp÷IDø.RÝÏæ½)…†?›¼cì°ª„–þ!1Þ2ù¤ ç% `"í’#ñê ³øÙ{þÁÏŸ?ÿã‚ÿÀàÇ=ÝË˾ O>ù™ìÜ£ƒ{ºÙáÙÆ°]ÞÄ ƒÈ?+xäÈ}/Rp£HÎ~=?;9—L¿+™e¿õ$+å^œ(Øü“LÁ•73ô€€€Î³®¯ ”BéUD™ën+.­äúÖñÒEî=y:"ûݱ*¸ªzz ZUAØ‹Öý!ˆQ›—¡@>×e¦aP=œ¢eÁ¹…n£–ÿlŒ"Çe‘̯F<¿K<±j€v )@ ë‹¢¥ èaLsô‡Ï-ðóœ Û<—c"Íã¾¼Ilx—fšž½üŸ¢à óÔ "øŒ§ÉIÊ«MΧ4L\ê¤ùÏßqïG~åãÿÈkA>ÜÄ}°ì à}”ûçr¥ã4†,Öˆëo¯¯É÷GVþìÁ8HØ(xáê™ \kTÆY¹‘4¸™'A¨˜’—mR”>µò­l± ûÎÕ†#/|ÚâF¹@ÎkDžµ²¼¬ `Ù/›üâ[qðŠÏJ ¸»àÒª¯8­h.£v?]‚eˆ‹ŸÝNCl'„€/¢R®<:Îí·<ÁÁYëØM±^Ó|ú×Wa,Î+’|0’ÇÈVÀþrý"8ôÖ"ä¯=Ÿ XѾLJ×Ä®ËB©†öÚ¤cŒ‰­vš®ÞÈ\ÉU«¿qêÎ~íž{j¯ùx'÷Dz/@ùL¹Ô/¶# / ±ôõçÛëÛ¤Ù6u㧪pʳZÛ%>u FuŸ =ÚV²~c3inm °AïôÜI`R„³fê- !¨«0€ JôçûìçYtüåÈ>,p@^€|:”S–]Vi‚Yì ŸÑ"èƒg3)oºÉÈ4ø7­ïì ¸ý'ƘæáâÐX‹ÅÏ®Ü@8t})†Ç¶<¢#bäaÜd»µöÔí=Ê¡‚`pŒãQ`_çûH8Ü?ª ÎÛ²åa€d„Äk0´×þ± ¤$”¶¸•NfylañKwœºð¹v6ùæÃêÀÚϽÜ/Ëž'Ÿyñ3xÈ2ß·ÓìÞ—‡Íä2pÚ‰¤µFtÞf.ß6ßWœ±±õö훘;’?yŽ} ÉæåmÜ‚kÉ u÷ÊîP Út¼à[ËâÈ¢>vkÀ¨Y‡è. QÝÇ0_@R… HÔé­ /?²ïnbQÀ9A¤ !F …EÂ`\7‚2èÇ9[¤€ú8çWðXh’Np{>KÂÇ;t.8tæ©'ÁÏÎI &À QÒ"¯ºc8(;ݤ!q­R†ðH°Òtä8‡»9+n†¯5 Rô–°[0F…ÌDZ!Føò¦*K&ך_ZxþäÙ;ùÈé{~ïG~ägÂŒÉË>¹{žLõ§ ;ùG›ábé«ãdø%•t•øÿ-âç‰á7ÂŽÀ.²¹xó9|ŒŽ8wc˜LVßÚN.­|+ÙìÐ ˆøtØ=¥Áˆ„Pä‹´ÿÂ×¥-UBˆKî®»NQØ–^¢Ów‘5Íõ! m¥Ì¾Ä¿#/Șræ!^‰‚ TtWb0ÊP;bk¾£<žU£oŽ5¤î¡]Ácý„‹ƒ(±Ÿ„ÆX}]{a|¸yl ìñ¼tù9’TåVå<ŸÖýx×(éU`Hp^>+¨Ry|ýÔ¦žâ°5>9óìäâÑ'ïºÿþ¯>ñÄ?:(×=úwí«¿{ž´JW²ÝîøýÃaa©ß‡Æ“ùÙÙää)ªÙRócý-Ä}jßuvàØDûQþû̧’CGç‘»ÊÏ%§î8Ô–¯'µµk¨ÙÄåÃvKy<Ú°m°ªæöQú¨ºËB€;+W ×Ç:þµªêóZáµä[6[㟞³€opn¶3dàZ°ó#G×P\˜cäèz ”¢`û…s((xBVÇy#”—ï|Ïä6ñÉñ¡Š°Ÿƒb ü̾ž°‡WÏëp0çùdòGi'\| *q3EØä§/=#eD —éâJ¡éÛÓ _<~÷_øŸø¡Ÿ&Íò?ø»¯î€|bÏ.<ˆ¹·V7Þ¿Ù«ÿÍa©47@üÏçg¨1?K³Ž™É­Qðrsu# oÖþ¿óÞ»’ãgŽE^þ9ŸÅù!Ê&EôÏ!æë»®R$OÀ Å;5œÙ(ÃÜ­Ýáj¸Šù„öÙ®Kß·@Uäï±!ÀÆðG<У.mÙkCýÑw/êHg<Ö Ú[„=â³Òƒè¸?¿ñ'81ë}í·¶ñ=Dþ[ª߃ @5Bra?-A!5¢*À›ñ™¥Â:¼×ë}À% QÑ"õñMàK‰iq<{mniásÇNÞõ˽÷çßüÔQnòÁ²/ïÀž–ž½þl©×ê=±Ó؋콱I¸d›F÷´ßý]§0Ömà ¤’o¶“>6GÓ̉ds“‚ rr¸|Y8“6’%ŠPf[cÉæõ1£>ôbTõ99†#Ê-D|Ðj„_€¯ÜÛX!Ü”‘û¯qJÑ ¡f¸®û*q |[w öQÄž‚±nbP}\‘[•Ã_·9ßca¿÷•>äҎƹuÞÑÜ\¯Ø‡OñeD˜blþŒôUíÈ(€^ `D¤àþŽí¡\hŠf¯ ´Äd«ùöâ¡É¯ž¾óÔ¯ÿ•}ü•Ó§B|ãÿ³Oÿìi°ÚXÍ×{ÛgWV®WÛäíS/¥O^Žæ›ý5ø&{É‘ G’‰Ãªš[‘껼vÞ|[öÐW)Ä“)}\}9¤€Ùiêþc£Þ^î';ôDâ`C8¿F¯8D„¶‘KÜØYG!êß[ ØêÓºÆ\” X€S"ˆØÐ 1êÃRPÌ„žÅšýç±·Ž iÁóòYQÍï#ãáÌ$_üÆâ,F¶ö±!:\£Ûõ!¨Xï~‘ñÈÀQàGý7ð’¸hòˆ±Ÿ“kȤRQ:V-ß8zøÂÓ³“§^:}ú z/wl_/{šè£(+ÍN+»EµÛV­hpùMÀ± 4ñ¤4—úéôâ$‘}”оº“¬/¯Àiw¨³Ç“T{ƒãS€“´ÞÒíŽÒk¾šÒ4”’Û"}ÐMéÕÐ%¼E€€  ˆÓ^¿¾±ïn— )‰@ˆöì3¤Ò¦Ù…¡°»uÀe@’€ U€õrn6…Xδƒûˆçc@‰Db þ/qˆÂ΄$ñѯ|ÖÈçù];x¼»øçßÙD,ÂÒÏþ‚[JBžðdŒŠx@oÎmR¬’@pVÿq¼&P‚8fS ªn,ÎÏ~ifìôSgÎüu:þK;XöóØÓ Ÿ­g*3¥òÑSG³É*üº[×ò_Ù.:½ XöíbC¹]lÑõ]EzÂÓ:†=>Cò±¸H‰ªCÓQ´L9î•|C&àêÔ"'D`99@2²Îß>‘~=TEeX(„A ÜvÄÎZûnD@øÊn,›÷àîˆXÇqap‹³1†»ñr±ÚŽîGîøªŽ5þ¾³Óè˜(Úõ÷K¨ÔK¸eoUƒsÇX^ô0†àBº>± Èõ% JHRD×ñÝü†qòœ8³ß˜ªþÎgïüì}'§Þ|ôñÇñ`Ùïw`O€ÊD ;\±vÏì]ƒÙ¥^nåî;oF2¬ñâ!. é±—L“‹~$Éž  -À¶ÖÖiŠ®?h „ª@x¯E;–‘ºD¯” »+bü«Ò "Ѓû[ÅW&.ÍÀõxöG`9EÀmÆ A:H=cb•ãeµà™¯rq{è¹%¬ùîÅ—ùݓݕ ¤%q¬;²âðH0øì>VîjÄäz xìË1ºðtCº¿Óádd„Ù XG¤sÈá™—Q~ºJýî’ï#»nNE}. [f{P¥ª¥ÕÃGO<•;üGägÈ[‚×óº?Âß[zŒåFó˜[V~m#âðÙÅ9Hl ñ@ÍAˆ†žŽíµòÕ,ÈLe¬²2³pôµÍÍÁ&ÄçÖTå`Ùçw`Ï€ía=ßH[³õn}²ÐØÍviÔg;¯·bžßU)£ÛØîÃýiiˆnúký¾K*«~kÝQاuû€:â1­³Æ†Ô¤Õ5û××›Ø °Ð( ‚Þ°ˆÃ-MÅ•ëhC]a@ `ðâdCr øËKcîF¡!ðŽ@h©ì–%>¿¯üˆðJ!¼" 9Ÿ vñeÖsþÀ²0¶ÅXìè»Ò@, s‹HŒ´xr}cù•2”$ëGiÎçóüì§!TâÁWí.;aèO«—Ïœ:ÿÊßú{ÿ¤ûÉOþÓÑÆƒ¿·Åس`5¥Ÿuo8KÉí±ÝõF¶O¹ëöWé¥wìX² °j;«TøÝHZ;Í$Om}!Ÿê´†×wmÙÝA©u-=éÖÛÊP#I Šp07_N¦Ðý7óÛ Ô(ëØñ`屪HácKXÿåìQná·ü .¥„ð 0 CzC ¹#€J&…ýÏŬ öØÐÑÛBM࣋ÆDÙ¸ úXg˜íE¹„ï6óM’aø,³wÅèóh’Q¬„¤G¶ç¶ðgá>Ana³ €Û±®üSÚ™ž¹xǹ¿xý€û{_o¯eÏ€L·]ìôKTÑ)5vpîv(¾YL–NHŸº¬k&Ë—_MrëoRKo:~DÿÕêˆôXýQz³´ì©îЯiÒÙ#-8ñHÓD}œ¤ ”B–:ôæ(ókK.5~½ ÖS¬p¦»d× @û¤¨aähe´Œ¸¬ßBøÎ& "%†å .­õæ8#Ä(/[qIÀe,A# A4X˜ww6(¸¸kìï~†›ÿáÊèãùn1/Á°fm·æ¡`û8¯.¢~`y¦º:>7~ipχjްÜ^w`Ï€f-ͶÒÖDm£Q¢}W¶±ÝJæÐëž¶ü÷é$3‹Qpf:9ÜÄý×_&Ä÷µdùKÉúårÿëÊ” Ô:CýCâR’~RX¸VòfÃ`‘Bžôëëaˆ e‹´¨ÀR,¶åµ_, îwcÕ`í*âêɲgÕ4ìëg~9t$Ö ~¢ŒÑíGêã<¯Àqž+ ÍÕˆ$n‚Ûc\œ’.½[D cŒŒ…\ ûè÷WŠp›ýú¾3.ßC5(±§‚þ„­€mÒb~ùr~P/fªãÛÕreíñÓ§\q÷o¯?{–¬¶wQäÛÕÝÍZawƒ @­%ÿðÆV2½s+>ºmó:ÕzÚøó)šNrtïé¬7’Ë;Qdi>ûXæ€=H«æ·g“mª)6–@öp“ÙãOôéŠëŧUÏ1ºp~’ àÀÍMúÐJŠñ£rÞµ’ÎHŠÛlq'ˆÆM±XÇ…w€o/APnì7ÇœÚ \öÆ }ê 1qŒ.†Lç¦dáwU/%æ­ÔôÚ&n´¸ÿˆBEL‚6å%⣆…B®W©»*”‹…z&kuéÑq7G9xÛçw`Ï€öö6î·Ö·ûµnÚªw29töõÕͤøö+I­UOvw¶¢–~‹þªÿä@ÀÔÔXÒ¦Zpk—@ \€!>ç%‚(¹ªqïMl‰ã—K  Ðáyg×Xw‹3F¯=€4æM€ @í:÷¦ëRbQ²N$d³GîC÷¹%çß<Æã¨ï2pßµx*Ï%ŸpŒc‚÷°[´¹.¿Qr7p¸xÚ€0ož{T1hDäÂû åüÔ\èå‹™V¹œo¡þ´Óþ°Õj5Ëçï<6öÕ¯Ö;Ï>ûl åpËþ¿{–ŒOŒ§­nþ`°KÞ¡XMf-Q}v<ŒõÚ*o%MÛ@¼Ïö(ð‰x?7_¢/ÝádåÊZréaÄïÁøæ#”—Ç×^A]À£0ŒR\ø@´g› _Î\…=¸4èËâIÐÝ'àÄ"8+œÓ¢ãQ\h¤çƒ´ºoQŽù¡óÝ1}ЛŒ8lÑT°ólyŒEðK âÇ™gdî…±aDB¿WXáÄ*0£Ú"aòª-JZ”n,籠‘¿ž‡K­V³ýb)ÛÁðÙ*ær»…4¿›¶ûC²'—Î.žXZxwýú³Ïb9Xn›;°g ÀÂÄBºÙ­ Æg¦‡ÍÚ0]<|rô(€ö ʲ€—8Œ\güo®èã¸T>#£ÿ(Fp‚»ªoGU¿°hø ŽïWö‹µñ™ï<8þh?së“ ŸÛyX¾°g;+F?1\ Ý{î§kÏmÎÏyHX<( ‚ÎY* q‹q8àë90nJB¥£ƒjÁ)vŒ°ƒ¢\4‡ýìnZH79¦M0Ñ\{Ø;ÚÉU(üA>vŒÆßƒeßß=K¼³•R5½ûÂùä®óc™ÙCG“#§Žc¥ßH®^$&`ƒ`2,\‘’Õ‡2Ÿ )¼Ù¤ PŽ&!]r} Ù!Œ·âqÂàö98yÄ„brhƒN@rtíQ H¨ðÛ)ÆýIàˆcAt+X‡¦8‘;àÇ‘@„äÀw9.›¥#‚ß8ÞSÜ"×AC^gƒŸÙÁ7>Œ¶ùXƒÐxo+!ˆj>°s éBÊÈ7íŽÍ¡7çàYÇ@, j˜âjL1‡ ueº4]¡yâ°†[r¢@ðs’ï÷Ú‹¹jeúþøÇ?õä“ܵƒåv¸{š³…̱“Çs ÇÎ'¥ñéèÓ·‘¯HT ½¼)ìÙà‡Ã÷ùB€O …\•ʽ¥dg£“ì¬ó„ST®:4å—‚¬O ‹”èõ€É©ƒ‹+ðÙÜ]gáDrÒà€V”æÎ‘"‹Ô‘IÆð«cfI[!»Êý…¢(Õú0k Â7I‚¶]nsNÁ¹A«à02Ùat~̃È~í¦*ߪâcÅa«÷XX$¢Gl ñ™¤LÌãQÙ ÚL¦‡Ó-d°ªÓ—Ü"ç É|ê$7õ½áøÄÌôÂÑñ%¤€”«¼)ê0ÎÁ²ïÀž%ƒa!ÅÕÖk‘º6@··hg—Ô8¾HÀà(Õ®k/ÃKî»7¬:I›V`ÆòËD*êZÚKUAE_ +0 ·`6WÀŲ^U¾c=ˆ‚Šúä ÜrÞ1Ы/ÌÔ•j‘Ì:ÃF\ßóŽ8»À/¾ ç@ Ô_/§wÑõ(¤Ün |W§÷ü#aᦻ"å~ŠúÚ.Ü®P"~A`¢’~~ ”HܘÈŒaëÁ"tÿñÒí@Ú ÙøÄ'n}êS¶ÿoû}Ù³ ZÈÒ©{°º¹ÓlÔ7¶çÙFf«AÛïúi2ɉ£ IJbÐúÚ(®ßÖ^rÂjl9Šx€»Ïô]cúŒ²>n;pg0c ™¸¹KX°=¹£ÓØ'ç”—ûQ]ßU\D”RûH "2}ƒ{Ža‘©Ç"’(1£ø.<æ6"Gœ“í¦)K#\Båà’‡ýÜßCjü.¡³f6haÄô«ŠUaâL#åð!R—:LQ_[² F„7d:Ùl¶‰€Ëâ.åÒëýav‡Ü§nʶ‰íì`ÐØö·2>yvêèîc=›>ýtÐÀÑÄ,þì·;°g ÀÌøL{³¶óæ Óßn6ëÇû°£í5}®$“¨¨“¤Ocè£@‡XýõûŒÉ¯[å7âv¹<Þ«}…‘€NA+âù,@3tÏ7iDœ0”˜Ä±¬²Ep N«ÝÍù†#.X±§fœ°î@9Žñ$À-@,gçÄâ#‚ùóщ8·¬$ƹyº ê‹£‚Û£†F½)‘;ïhê)øÙSŽgæ(a èû”÷&«B_œhL#à/äÚ•B¾^(fÑ©r»™\nù`b¶Nôã&´u»WM[d°Õf.TìƒüÝ¿[éüÈ<© t°ìÓ;àcº'—¿ý7þv¾;¨/l×·ïç)=¾½¾ž__]FØH*Ô¨æ©öCxo£Fð.Ôøç1ç™V7ãùGt„z \äòYª ` dù­ pêåéÖíøpŠ¢€ÝÙœâî6§·AðÞÊà“¨8¥‚X&ÆÙ,2„€ñG¶­~fžn já GŠia-í ·æÍsÆw?Ëù™Ïͬæù9”½içI—^R{íLÐAݱMA‡ˆÈv!_h Åz&Ÿ«!^ìÐ,u›Ä©•l>¿I.ÄÓX˳.ŸæêHíAš§9Óݨv­:|àƒ>ýôÓNë`Ù‡w`ÏJüà[?ÿùŸÿmt®µvvj¸ó z#ÛlP‚¢Ÿý"5)õ%[ÍSÉÂþôäáÙ‘k»J<­ÿò9º  /ï6Ñ ¶,¨@jx ØG;‚„£âÇÜá箑]Bi¾]æ£Ïô!(¤Bæ´à»Ž¶„Y$‚ºf'òlv§˜ÏmrAkLjf(k?6 Ý^£R¨7ÛlUlÐÎuúX»7n¼8øÔ§>í –}zö,@,üôg~zKÀn·µÛ›žŸ†Ž“÷5Y¾¶šlgHüAooÒ Ìj?˜ÄK Û30’Ôn‰íCC~A§@W°ÞјcÄ®Y#šFA22ô‘[@*É‚èõ,#îì°>ÿ‚|PuviˆkU9bÿ8–7Áˉƒ0¸Ÿ#Þ€}•\Üß FÚtÕEX1ûØöÛAo½¿À ˆF©#µ6Pˆgæ²û[Hu&Kïb¬üˆþÜ}…Zœa…PK)d;›/Àís[ÙÜ`™£i¼VX!˜bï`#Sè7®\+4ÏMtÚÏ//VWW3üà‡ŸúÔ“q×½ŒƒeÞ=K¼Çy]Ï6[µív‚Tà‰j%­¡ëoSÔ%6cež(ûXFÁ7>“ˆüêÞ±mšêM=Ùõ‚Kìªß‹,¥ü½_2ùt%ûGggûúÆb €ªƒF½0º±^b –HŒŠ+Gë=ÎÏ8*?kBrÀÏ€˜Kðœ­-ÀsÈá•Rnõ Cç |p{y˜…5̉dpúL³hBúvfº É•ÑCaÊuû!Ù®v‡Øˆ­\¾p}˜foPôtÏËf2È7[ýÝV륭֓ß6™B øí˜0bÿhâ÷õØÓàüùãƒÆ·¶/g–W¶·–Wæ' ¹ÅñÆÆ&ÒZ‹¢ ÔÀ†ËÛÇšt] {ˆærÇðƒÃãF1@¥@ø«\²P`;Çôñ¨· T‹8¬Fn$#à{ˆò1ÛF:ÀêÀ±4B>xýÊçÞœ™¾~musål£Õ- ©áU"BpXNº…F¦ÛõE‹M|øCcû‘™ÍÇæøÎ ÀØu7Ú]ûW[¡@u€Õ…"FÑ>Ò{åMĪŸ÷f•’¼ Uðò梸ÁÏnàåùý­Ö+vØw“‹K]$ÚBª¸+çÁÉ$ “ƒC‚R° xÅbÁ*#øX yc-Cp<”5E—à\xg¢8?C êPÀóÊu ìøy‚{û3ùë·!ëÅ|aCæ:þÁL£³éoÖW×Ú_xæÀÍÇë¶^ö4ÐðsŸû¹gæ}³×i\ØØ^+7šµ$¥>W çt)SÌ´‘d9§È®²;Yàä²áž§ÞG GôDôU§ "É€%³ë8†‡ß®+xYcŒÒo1ž@®-wvå´…öP÷À訌‚¢âƒÀãGèE\`*ŒÁJNEØ0N þÐÞ³Rõàî5äãPéãX…e‚¾(XÚEdïÉá9A_k?r–~9w¦…ªÓE‚¡>rÒ$­Kf3WÈmsuf¹I®Ãj©›n"NìdõÍ6_r w §:Xn÷;°§ €7ÿc´¯^}ù÷;¥ì{*Õ©F®WÚê×Ó6µ²pó\–Ö ù4K@X_Ÿün®—éf;~Ö(:Q=Ä; ŸÊ¿‚gØÈhçy{W9wàö&*•B%`ˆ×Ò“ø.ñЀˆN:9êEA?î"!qaz9J=ûé%¾ÉhHé|ç—`$ð eÈlüõéXO¼O—….ø °‡=š`‡lÇGõ@z×Ázààƒcá:Ðõ¥ŒI;[6ŠZœl‡(Œ}é¶ú>RR cжÞ+'Z{—Þ^Û¾t)DþðÇðöÿ³ç ÀÃ?ÜûÜç~î©r¹|ÌϦDgïÆn1m´[i§ÝƒËâ¥Æ¿—ëu³Þøì—< E³$ôÈ]àÒxÃB8¹êõÀNlW7W{@ôÎC>ø‚4X;ŸE¿ " ðáåòb’h”Í#M“¨±‹Çàîã7NÔ€cA3à嫌ÝV[ŒùE¬Áp‡¢A€Hèaü’ šJŽ åB¦eaäÐëÑõ©`ô€bÝ'kÿ Ÿ•XPȈ¿x9v'-dv)`J¥Lƒ·ð,gý°•«sÒkkëõññ­à?¨úsûcþß¹Â=OœíÇ>úŸ×ŸüìÏ>OW€áds8¼ÊñRDº+È$LbšÑ²9¬\E°)ÃFÙ/;¹ABäÒÜ07Ì òÔŠÐ`ëß :xÖ”ÈPLˆ€Q_8±É§T–ÌÀñ=,ðŠäÔ„%C˜…˜ç&~QöŽ&¢œòDì0ÌõÑÇ1C§V oiNjÅO.ˆÁ.&; ²û9Û`‚m P>#†‡œ€¯Á™št(nó­Í|µ„´9ó6ûÔGêŒQg5vÞN;½èÑîòN»væÌVçÉ'ñÁòN»û‚€©´ôùÂócÅÒ—’AyfØoß³Kyíf0ÜBR‚Ë¿’Ì»P,ÁÕ±iûHg‡Å‚.?ØGv†Í÷±¸ag•ñ»=TÇPê÷pþ= n Ô2`ãpÂáGB¸â¿¸FôFd‡n°‚Ãu(2¨®tÊ„ñÁÙ3d^ñCê ÛÃBÑaî:£šXÿ2E *0ÀÂ9 €Q:""¦m¥¨’ÙKF0¶wÈÞË’%5ìÁG(¯¥ S£þšXF(é•ÔQLv‰Ž þñ°‰U Ùî j›Áî³ÏÞhSäƒI,ïÄ;°?ÿ™'žøÉõ_ÿ•Ÿý&X»c8hÍbÛ*Ó ¨S¢q"s=œö=)",õÄa‡(Ãf½Áí|² }úƒ|4û úG êµðA7ühïPB‚ˇDÄ5ιB @<“'ÌHîŽ"„¦®à@þ –?ù·8EçH9¹„†Hœ Ù®ú¤—ƒrºA6—ÇG/ÁwÌ‘+ÊÍ‘€¤>dZŸfMWjCÀ Òáù»èþ ,ú-Š#]HçïB õM›(-Œ“õ~)Ý-Æ×ì¶›t8êÔÒvý+O¯èG=ÿ;ù7¯yßç;9·xê€ÏÒÆi$æ%ÚzÃEh멦ç;æ´åh ާ«~‰Ú|å´˜âö‚_G–_i˜ïA0úÃA Yk-ê%änP q@Bè£"ÄÝAߖ¤2¾ú<{î\Ã&ÚFØ­[À1„ƒõ”*G¬7Ù˜"AÀ©‘êÈSOG`Òíõ»œ™nÍ9%XG=„Pšƒc èï¨ ‰.…9Z„ÈAgrFìrØI!›o°_ƒ ´ñë¡PµPFü©ô2ƒÞzm·;žYè<{ãÙÞA5ßï<óþÐØw€Ö¸ñõ±vj£óÂNšë·z;³¬+ÉíÝx¹ÝîUPªùŒ‰X!ôoìþ…´”¯ä{ýú¼VÁÈ#Æ÷±%‹êMi<…ÄÚ·3íNDˆàïã_$ž¥ GÜt $â° ê²·Ð8ÍBØ ˆÔiƒ”\L”]Øs®‡ïð†;ŸcJô.¨P€x¶ŒŸ]B»ˆ&Ýõzz¼†i?Äh¡ù±ÛéQÍ¡0_âHúé¡Ç”[Ãn³PT·ÛÃþdkйÜëo®^îþâ—U7öª®ŸýÄ'’ÜÖV’Y]M¨+óÜ«sýC°¹}>î; àÖ­æ™ÏMlmmœi4–gÉïvÛ9€˜ß®´{ýÊ ‹<©L3lrzQwÐW‘/§¾MP›ÔÀ<a;Á ÏífúÝn¦ÝëæÒV ¢¯ÏÊ ‹#ÆwÞ{¾XÀÝWØÓÙÖCBÐç¨ `ÀއPæNýA§Ù#68 Ó”pó!`Dö.³ó¨@–FeTèIŠÔ$îQ“[›%´¡ËY Š gZƒrZîµëí^s 1¥^ì¦ÝA±XK;‡ãƒ#7’Þ§ž}vÏêú=–L—Ëcßqvñ»žÊWW6_½øjïå_l¿Åÿx‡—‰LËŸòØwÀ­ûñþ÷´ñÌ3¿x9›]huÙ‰­~¡”ÏãO %âkJÝá4áªïÛ75è\+¸“5Cë`ëêeáÀøö0âÁ‹ËôæËP禗ÇR§®¯qR¼ð. ´Q%P¯»¬ý¤Ýîd›M«c›à‡GÍÏ ÐŽtã°r¢ ùžGA¹Øö5ÚBE¿W¢j v¸xBLΠÍ8£8'ïKÛUä†pÊcSèu{Ýbµ¾_¶Ûx+«%„Ú$×vÒÚN.­žjôK/Î^O{’<ùGƒˆ>Í{r¹ïD2süÞéßï©ï>qâÈcgOÜqìè‘ÃD0g“Mz>^½q£ûö•«Ë¯¾yåÛ¯¼òös;›ýo¬m¾¹¶–\ç‚4`‚?áÿì¾&Þ‹Ï|æ3¹…d¡²™ûzµÓ©#Ê·Éèäûu$cÜyùXó1¡cNäû)f¾XG”<–:Jic˜'«†´ZË{`dß<»‘:nÆÚT!RáÍ}®#¯‚)°Ì1™ê8ax#ûU7“„µ†'¹”ˆêÑd³Ü6´8ªïàÏ+ÒzR,U9réî°Ö;UÊwëÍÙÌÖn#»Š¡ÿÝ•VÿÆ =ÌY^}U ?Ÿý¾—Aîüþèòýß®”­¾±4?µø]‡Nþ×<ð®»—U§&¦• äPñƒöpd´©ó¸¼¶Öþæ /m^»±òú[Wþí¥·w¾B«Ç!7ÛÛž%rôÚ÷ú÷}O¼ÁO=õTþÊ•¯—Êå ÍÖëÄÀÔjÉ ÚL%SI}wsx½E×$ß\Êåj¦Ýn¦ô ¥º0VÁd6/–“•d‰}êõjº»»•öûµòòòDºT«}ç~½ÐjeNߥz6¿5ŽD‘$ ä׿*ÙY¿ &†Í±çèfÊåb€·ºsm°ûý¶J¥t¥r-˜­_]]°°fˆüz;-}<ŸÌ?tøÐćÎ\úÀÉãw~×]g. ¥aΤ×NàM¢^cžÿÁIT™äÆêäÒÕ·û/^Z¾øÖg¾õ­/~ã…ÚsÜ›e^ÚnËûõgý¿ÿÎýg}â?éó}âŸ(>|øæõX¶ê|räÈ‘ô'ò'µ‚,wà½O*‡†Sÿ_{ïÕ$Iv¥‰y-3DFꬬ,]Õh‰zg€™ž†X`îîpIÊ7 Ãßk´~´ ý VW8 À¬Š Ë€G¾cñEJ礛wooü?ÿï­Ÿýâ¹ðÂòrù‘V„ëqúxa€ŸíëßýÝß ²²á @IDATý³@ù'ü~åŠ$OJ¾×.׿[œ›û“ËgÏûã±((ÎXßÀ±o }¬ÅBü÷ALIJ ˜xÔît$MUáèè€Äho6‡Qtg™s­268§€ÁWJ0 à+Aaüò× “+ Ÿv;Ý}áüùï^8sÎí÷x¥euöXÐ ’2Æ\Q?¿Ã7vxQuÒFrgøÑ§·Û¿þ`¥µö°Hs‹™8 êqú: 0f_Çe<§Sr!&Ñw¢Ñ‰7Ξ^r‡ü~ºWãx80æC8û§#¯ÄÎÞp@ ì4Þ_½7¸}wµ~óÖnéþ½r¡˜g€tAüø§¯ cðuAr\Ž€ÀÛoKŠÃáùÎÂÜô/?3 ±»’• l83À½A°ô ãÔ}îÃ#€k•ØcÑî´¤k‡ÿó«Å7Sûíz­6¨ÃdÀ8…ä"0v«“€2cpFᤠ¯¿.9‚¾ÀŸOÍÄÿ‡Ëç.]ž›šG€Ä.ƒô§š¯û ¿C  Áš?*¼EØòÅCéÞÊÃÞ¯Þ½Uzï£íÔÁ^ÑŒHøUä òhîO;õ†qúŠ3€¯Àñë `v:#óÑHäß\9þõ奋6ÑÙ8¿ržŽQ‚b;8²'1àMÅn‘jõš´™XÜ}ð þñÇÉÒ­Û™\67¨øIøidœT$–ÿhýgæ2 L…ãôU!0f_‚ã÷G°Â'ÐlJ®-+¹¾]µ3T«pöá¡­ Ç6„‡3£5°_™–æûë½_p­výÆÃÌúz¯T­2ª‘p&ñï"'‘÷®÷ð9Þ' |ilMý: 8.ƒà¶ìp©R¤ì¹\Zîvqî(v_@ÅÇ& ®ñÈå?‹Å"Œ}•jVºûànë—ïÞ¨|øÉnns£“­Õ‡\Þ£ä§Ã=ÿv騱ŽÌi™Ã8}MT¾&@Ž‹Ë¥$ƒgïëV‹áe¿_žœžvúΟùçfâÖpØkð{U£Ë5ÙTEÊ—ŠÒÕW;ïüúnæÆl.›ï7°ôO⦺OÉ?Ê«¸~ˆL7Îß‹ÚOÔ%]G¾Â‹ß’^äKÔ †)ÃGýoV[u`üÛÿûÿì¼ÿþuÃ7¾!½^ÝÒL]SÂx~ö3ázJ|QO ¶Ù~§‚6$Ã$:BÝZüÁ%#úÕÞ|.·}™>’œA&ÍÌÃÆç·X XTn¯lóúÌ–ÉI»}Â?©¹½6C¾Xìߺ³S¹{»ÍåúeÌ÷iØ+"³YÌTùÈÔèõ÷;!~lK6ÃßÈ—pãŸÿye,îýd7†=Ü\‘„¦ÕFÅNQò\1ÕAÂ6ÌA­‡çöò­zY“šÿîûRë?ÿg¿/Cú{M, Àð7#Μù_—+`L§oKÿðï™.^ôÆ.-Ÿÿ¬CEÞýèÝ«ù|VvºÕ U1ÑéáÃZ·‹M<µjqo¯þ¹ppÐÉ/4ú¢“X¾Î4ë¯JЦI¶XÌ&OUc±Ýêúi½òñÇYïó„ñ'?ñ8‚A£Ö(ö U9§©Úݰ°dF…w^³P©­loVSÙl÷0•}¤wåóö‘0£·ÞYä82·DxaðcÅÏBÒl6£¬©VÙª™Œ8Öû0:F¡ÐR #ƒhkE>#áSåO"Sø:¶s¯pà'&ì×°¬­Ý4nnØ"«y  ’gIµÈö¹9뢪/ä‡uÓ à°X±\ Ç$H‹âX¦d1:àðëË•D5­­gò¢R=<<(ÝyÿýûÀiLùD3ò´?ìô7’ñ¿K¨áímëÔù õÿ04X-óàÂW-ŸÙË¿_®û"QWèÜ™©z¯)&£¢`ë¿jìð•Zý¦T*îµ’‘L2ÝO$“ù[ó“ý‡†žqëÝë5J'2®O•dü^\ríy$›Ý+»½î¡Ã Y|ŠÁ;òGϹü–@«PJ›Í‰åÚ&êˆ`ÏT‰©Æâ¥3‹ ‘™¼Rȵ+nŸ9Åv›'&a÷Ýn{ƒ¶¡Ñʵ÷ö÷¼Îlf{·xÓçn\ÝÙï¬W*b.ND&»xVâ.=nÛås$Ü äì~d/Úlk6¦¼Ôpâ¾ ™Ìn +Rßã4t¦¦Ô~4d­­Ý«ìnwÖAõ´ôU2@»,Ût£Ñ±ÛäÒkv%ð/‚¾P£ÛìýG8bx¢v-`U,»ÙÔÓšq~’4<¨NI0cˆèΈ ¥{-â»C“TW_o,ôʥΕl®ÐÏ77ï>|çîÝö{årŸÓ–$ò‰¶YüA2€ï_²MO‡Îªvõ"äyìËæy‡-tjÐμ")-—ÇÑ–‹ñþ`n¦6Dð _Àn±Û¬vÙŒHŒç q¤@7 z}Rd¢.ΜMμz°{˜ÚÞÎ\æjïdkR¢“*ë#IõüïÿéÇØ)ü×åRv¯TɧΟýÖ™r9‹pÂéݰ³{÷ƒ­9³Ñá³Èý¡Ýa6+²i⛚+ì°…ýVÕ¦Z­«ªhŸ'@x1×'×ï¤Ê•2VÑH@väuyê«MÁì i·ÍyêªÛáP±]¹eömâ“óoMON‡ÍK6KZìš ]Ã)cBü“ ¹Ϩ‰qi*\Ÿ˜›Ê¶×7ç66“WlŽìû++÷0¢Ž çYÚ%a°‡LUžÌÀLmÀlCòáÓi¶Hªßor|o4jsÍ͆í3Ó^“"׳Jÿ¡º“ÆÆß–`<4úÑ(øÜR”*½Ç옵ØçÜ^gÐî‘'=ÎÀ’¦ú<Á@(æu»çUE•ççJ~oD±©F‹MÓÍͪô ‡CÍŠ£Ré¨ÄZÅp*:,á+—0yv›"BÁ¦Q šmŠÁ™ˆJ IY]ËãÌÅ4™ ìdŠÛÈÔ¤Ndúƒb?øË™2/„ÞWþè›NWpI³x4 žÛfsºM&{ }Ùä†ç™#lvÁñ bs<ð{nRKTX´Ö7©@›RÀç¶x<.Ÿ×ñŇó;3ª–\\]=¼ºÞiü¢PsU:ªtí.ß•V³ø=›µ±‹øýv-îõËýn»¦áü¬ãüôÔ[-ÙèpšµPA\oÄ.sXÙ!›œV(„í±àÔS»Í…=òƒbµyZíÁ)Òûa³ëâEefiÉç•ï¬]u˜}«×i×–­˜"ŒöZÕªúB¡¨æ¾l–ö¯ QÌx&°Î â'££3ŽÉd“ìšG‚rd"b†ƒA·ûA¨Û߲ݽÝDøuÁDÿŽcòϾ7-1£Å]ÑŠàhÕB_Η»ÖÃ½Ž¥XìZàÍíõ”SÒP³95‹1¶xž ¿Ïçr‚ÉiK_NìÞ Ö[ƒCDQa$ MdÒµ+Ò3Ó•+aÛd¨:åôØ®L„¼o¾K¡‰°×®¹Íá±*š…!šèPl³9À5-nËñEœu¨(=pVÄ‚5²Rbh„Ç"U ‹à„]­Tá߯‰‘’Ùb–2ù´tou×°²VpµZƒ^aHüdˆc üÎÒO~‚ð¿ÏéøDàÕ`ÐófÀ|5䟊»HQ;gy`éIŽÀ=ÄäâôPk¶šT…¡G !¨|aD$ò‹Ø’×’È ¦°ÙÅg2ÜÕj»æòZëcà 箇}I¹¶˜ú¿ƒèÔä¹sv+"ÉŽVµ, UÍ:PÌîEv" âCH1œäÁ9&Ãw€ƒ<ˆ.²`F d2¥.ÈÆ`qjÒôÒ’Õ|éBôâ¹³a5òEdÙ³ZMƒ>¡iV£Q2CZaºê´Û ¦ZчÖÛ¸! Gé›ð¹4‡ &'GÈ4) ªG+ž©Ôªbqo˜Ú7Èívÿ!@A’‹IêÊŠúÖÂüô_íÄ%EÅPŒè‹+,I“Q?\–V±e+UÚ±nÛ3œf>šÍd¶*vÕ f›&*‡Ãb©3Ø>l9@‹3(žª3§:ROeÔöºuirjvx>šyÓíò¾ô‡æ¡Þ»ü~?˜(â €HIäf[jºd¬˜×+büÉIHuâ"ñà7Ôð…ZÀ‘'“Ø® Ø"­ÀÅ:3ÈHï}üqçÿû/7‹÷”¸çICQˆ÷tò÷.¼ðÀO*YÝn¨xšÿ¿E¢oOÆb³‘‰¸Õ®Wñˆêað9hKŽ19?HL¸¥R&‚˜@5\¯ÆÏâ9|ˆgÅ \ã„. q!e)š6hªËQkvOç˵|×ú™ *·ÿñÿÓ?NLHÍW_ú÷²Ñ]éÊ›ÛÔÖ¦ä´)˜œC±-b C~³%F© ê'B²}Lh*NÀùP7}³<3«Fþ©‰ g\Ó“1ÕëöIVûæà8%Yl¡ExsA€ªjA„pÊC42Üã|ŸÒžËñ£¿ÂE ‡·û8]¬‹õ8«l—¦Oi¹|é|.œn—:ûû}ÎÉÙGªøý|^ò¬>h]ð8, ËáTaóÒá‹@(Ð¥PÖ@ò{¨2[ATh/^n·õz¦Y¤R©:ÌÛÃ"´´CÅ#LlèÓ’é›ß”œ.×ä7Ü“–ïħBߊG¢§ÃÁ¨Ó­ùÑE0ü:êé´kú^T¬Xe0ÌAØV0÷x&ø°È„3cè„0á ½l"@â+4(¼T­—¤ëwnößÿðAáÞÝÒa¡0¤ñ1ŸøÄyÊ ›Hü>_à²×ùŸgg¼8{n*šEt/›„cÃ0pˆí‡Áƒ*ð_ßxB"`(*z©ÉfŒ<Ñôh¸xš/2˜*þ"@0Y¨ÊDÞ’sƒ‹,§SùU{©Té`ípÎÚ­!âW±Xs6ÚE/~wÙ`1²È&ÉÄJ‰¶±°‘ κ„§>¾Šˆ”œ‚€ˆ ÝAÂgh}õÊËŽ3 §d‡êÑÃH owÛRëR8x@ÂümR%«UýÒ]oÉb(ݤúÈÍ7Ô:˜ hˆÏãÑe!ôhO›SAä{¶äríè•ÒŸ}ìÄÁj«ºˆ`Êq›Uöø½A£Uq <ìøÃQ*ɈÅpù÷`x3ê€0AüŒ´LM‡ýEðÆ*ÜÿÛ{Íë7S‡X ä§#?©J?¦Bcžo]^–—âoOÅBÿãéS§~pîôÅééÈ‚U•€E[j ”ÇqÕQoñÍ’Ûã@vJ242=ÁQ8‚<‹@ïúh2™.š'à†GÄ8áøÄyˆS KÅrEúðÓ½ŸÿâFáæt*_VP,—,i¥ý‚ê?ý„Ƅϗ^X@$PUçÙ`0ô?YºôWË ½n§„Éù\—c…†jÁå0‚ŽÀÐ)áõ¹/YŸ'ix"—…„èT@fÀ7ð‡ep1˜ŸâGÜäoú }k+Ö¶ v‡¬T+­X¬”‹¥Þhçš©^ú²Ù†¥X*Ùpx™æöÈFŸ«bð†£­AH`Álh„*?vËéÆ&ÖÉ+NUÐrDÈq&üqc(Mmâ0 ZL%ÐV·Û&<í¸ÛŽu©ðšs~ö‰ ¡ÐÁøè¢KÆwt÷õËQýDö!ì6l[Éåòæt¶Òl4† 3ûÁö'2½S€Ÿþtʪiõ—Nß??sú/fâ‹.‹b²CÝç!½„7 ä®#@Ïy¶V[Hd)u¸3L&ú‡Ù*Ö !5ínÃä¤[ ùÂF „f„•œÀ Uá¿!a¡úcþ,V€Äaêd4D(MEN™^¾\ îï—ÏæörÙôƒNIP*—‡Û·oU¥zí^«\É„=Ü7?»,ËÎÕõ]r\jÂéÉHÈ”D $’ŒÞ0)ÉfEÄá6汜*€1˜@hy‚Ña]]H13 ˆ=H>l°¶A ˜ë°¦€~`šmšÂ! õ–õ2Á™ÅwÔ'¶ë¢~Ö®Àb>Žš£±ˆËjÝÇ̾ÄÓQdÚ¨>õ6“ÃÎ`÷!b&ÃwÁX>uÚ@BB(c´SŸ^‘!P»b¢öDÆ#˜ê×™•v jVâþC2šGÒÿ¿yÛë¨)Æozœ®{ùòÙ?yéÂe§Ûá4tfÇ;#'ÎiÆ™P¿Ó 6'ªàpµ”ÜÛ>X]ï^»õ zpP®ÉòÐ8;rœ^œÓæ¦gͰHšÅ†Ã™,º¦‚±ZÚʯ4–BƒæÐ”î¬Þî~ðÉ܃•Âa>?¨ã¶•Òž«[Èw‘ɵ×'.½  Z­MOÇãÿõÒÂò÷g¦=š ËæÐרšƒ§KYJ?JÉt.-Ý_н{wµ¶ú S:8ìÔaØ5UžŽÙÑI¯ˇö¹éy%žæ GbãiB”ÿ Ž96‰T'23ˆkj*®œ^š˜ÝÚ.îå³µ=Hƒ;h˲‚pVýõõºT¯îõdËÇ8®ÈäY˜> !Ld"saÙºtµ_ô„ˆGÆ»@A4ºl(„Ò‰ÈmÅ|–dʽöFôÏaSEï®Ü\¿y¿Q,ÕÛñI¿rúTÜ6Ÿ2b…@´›e "$sa Ô)@›”Ô$^³{Ll›Ó)K098Â9¶·×ö¢oŒÌCÇá½"Oes]mc3ç¸sÅá÷ûÔ‰@ˆ IÌΑ(1¦(µŠò9Ïf•Hd´¼%ñ$®3 x2ÕéÏ/NtåòÅ·.=Ãi•Ôl4ÁCj~¨€Ó»]šxº8„­Z?”6Ö×Û·noVoÝ:¨$%hjý•Á••šíþýŒcfzC›Ÿ ©S“a[,1„üA£bÍÉl?ät²LGGJì<ìþò××ò·îd‹Å5"J~NYHüIä‡È$~ÂçD§n ð¯þ• Nhߟ›ŽýøÂò…)Ÿ0ЂËy5‰žYà°˜×$~fé‰Ý-éý®µ>üøAáêÕƒôý•Âáa»žÍw«Ùl³~ªÕ6ÅZ._€½¿§` Kb>!U8§$‘`ÉNHYnjáwb'ÕlÎÓí6 G‰UåýT¾spP)CPsH¤à|Ù Ü6Tk}«†l•ÍNÌE­.—óTªé4œI€Ç‚žˆaÜãJÀË‘P?„>$=¾À#FÈ:ý¬tge¥ýËw¯ÕßùÕúᵩLb;×ÈdÓÝj-‹“‡T%ð£9z»I˜´‡<šýö!~ƽ-l—U‘%¹i¸»²×ÚÙ©ï¢/ô  Äã\—†Aœ©È£xÚbËåóiÄûG_Xß!•Ù%1ÝÁçh|h „±†ü@håJe¸²–h®®eÙ™ê? ˆ•¾|æµ4¥©C½#$> Ýbá8“@dÀŒðtØ-R~ôÉõÖ»ïßÉݾ“Í bZ&ÆesŠQD»a€º«Õ®ûð°lßX/k.WÊyïÁ¾syiÛsá|\;5·dON+õ v/®5ßÿh=·³Ý.bHÉÏ1N!s¼ï#/ñ£'’¥+ËÖ¨×ë|#:1ye2<«â¨? «NÄ/"±0ôcž¹T.I·î®v?üp#w÷n5 c9% (L FD A‹Hí‚×›ãÞýBŪ® =^m:è÷)v¨Ö\kRÕ„ø«äDdþÈÜ“Þ #žwiš€‘Üò˜)8༶[Wgu=¯.-ìºÏœž·»Ü!Ébgj1Ê£VÑ…!‹=²aÙÈ ë Žà@ú.ÔRˆÄ½LaoxãöÆÏß¹Ÿ½v5›Ýkè\;/ ˆߊ“…êi½çók“>¯M£Ý&¢ }ú!ll(Ÿ öRôˆIŬ@‹ÊÐÆÂÉ5%ØûEÐÐlO±ØKll¦¦Ém»Ïã…`µ™ãƒ¶ˆ>Ò K¦GxÒgÁLÃ]µSªTª4·àÉQâ[¦vÛöh8úýùÙ¥ÓAÜҬᄜ…ö€âP4™¦6+SHCòßhðáýÂÊj!‡Í>ÔX˜GD˱§ƒ¯sß‚mtÀ]yàÊå ÚÆFÑ·¾±¼r±è»r¹¢Ô›ÕÁ§7ÖK++Ù\½> Œ‰C4ú%בIüÄ¥&½0Àò²d™;«]˜Žßœ‰Ç‚œÿ5` ç2’@"0–,®çSò·;MX–ïö®^Û¨ì$›Tù8hD<‘–ƒG5“H!ÜUñé‡ÿ{u}£,¯­ï8¯œË„b‘Yœ(¦K,ª¬8öõåpM±#ìXï¶8 ž;`ǃȹŸJMC­ Ú¬ð[8Z¯fÁ´   Qß Z·I€ˆ¨p¥€žlVMºuï^óg¿x¾úi)í‚HfF§æÁþ’¾ ÅÒ ·›lò¹N$6¥l´Ž6ö B_´_,…‰%B¶ Áâe,•C—=àUÜ©ƒŽÚˆþ±d¨TaXÏC(3ŽtºHlî,å/x¢áL'X½à”†uPEGÐ1@¸œÂ`ŠÕ§ƒñ Ë!aÑx&÷ÒKÊ¥Ss±Wçgâ^»ªIå º[ µ">¥h':A¸0eò™ÁÕ+wïÓ˜öHÙF‚:<2ÒqLȸ>È1ó s•ƒŒ€ŸJe­Tjþµ™b pÆ’0&>1³Ýå •^ 0%)sSŽËS“±W°;.hÄXõzæGà¦ÄKL@$ Tt3%?¼yk¥õÁûéÜv²]„±H@â ¶I(#®ÍA%QKè5ê’©PêzÓ¹Ú:•`³Ž˜kâè@A:Ó!ñëHÒDÌÕà;o2G^sº±Âß`ˆšÊåJ…rå0 ©ó@Bzêkõ”öì×êÉä¸ÌEË?Q•š ^¸’6“Éþ»ï­Tn^¯äásÀ~P­eŸÈh(•È$L¶eôŒƒx §x,:‰š™å‘y …žº9þ3‘ÀË£?‚¹R«Â4’£¶@&ÁPŠ’p)¹Y×.V=b»ûŽt®…ÞmB@º!SêsÕƒ+œ^0‘¦hÁ³CÑ‚§‚Ç#ÙOÍßXÀ’IØ2‰} àTÀú`Œbähõ‚ö†F³ ¦x»}óÖ~!›…ª 9‰y™F:Â…ãÌ2QƒaÏÙ⧃aä2A°àód|ްf™Ä¡ûÈd„Á —^0k’œûå` ²èÆžÖ6Δ#ÁáÈoj߸"†C•ä? UärµÖ[ßÜ+'“íÔ9Jƒµƒ}á)L+zÓÓSV)¹-IÓ¸‹£qýÞ=iž|Ù4¸)ƒz¹~n’¬ÃS  ¯¾H@‘”4ä‘4žø‘ñ0º;©ta7“?ŒO†mÂõÞr–2ÉXD]œ@bBS†@‹LöSÛÒµ·×®ïäË%PƒÄG$'ñלzt0c°:ÝÊ%Q$ê@ûi\$o¡áŒÀäŠÏ"—1= <ù5®„ å!ü p8²þ2Ê<žHL”Üiö~.7H†§!¡Ýfˆ2iüã†}£aÕæF=.ß Öé‘l¡¢(RmvA½<áý3ØVBŠbƒÏ}C”9“h³Ð8UÁXñsÏäRÝ›·“ù‡iLùÈô9Þ$êL¸¦!í=žFí'¼F‚’} ™ÄOÜÁ(ˆÄq$“bY„;í /d:ñ €Û;ÿéH8x%è™`SÔ¨“as ÈŒq$ ûPÂd$Èj¥=Ìf}3ÐûMšÍXF@Š\Ðoʾ|Q…ÏüÍF[9oR žæãZØ @ss’43#ëõ–×d´Îi÷ ì¤ -ç\[6‰-œð“ÈÍ:9—§sÎH+àOOHD°R½.¥òùv.›/ÔüÁ‘ao$•Q”@l±†QËwÀ=ú÷7¥ýdûÖÝüîn¯ˆê‰Ð”^$øÈ”þD|ŠI ¬Ï'íMÌ]‹Âèü¼Å6‹I`HºÃõ1²b£ ¦ æèµF¯ŸÜm`U¡SÝêÝ%<ö‡…Ñl³3¨v Êè54úO`:Ø)Ø d±à\€ÉäFÌçxIÁ d xå×&‚ÁY‡æ24ºç#@Ab,À-C¨[¸Æf~†®<Üh­¯çKˆ=0"dè625/~>‰øqûQbߨJy24š#§ åG‰L —Ï 4xôË tqâ@¢ 9^_r9<“VÅ ”ÜÄÉ$¨NÇ!A (À¼ ¹j2Ÿ9õDc>ƒªX}v§ˆd¾âòÈ5ŸGéál:«Ð¦­V?t]HAP0‰‹cŒKœ Ü1AòÙàê«ÐØÖ妬 ©2‹õx—qèY%ÿpÍ[lòy6>òê 7ø Ï€¢ð.ße™#:+®˜hÚÆµí\!=\Y=¨¯­cëLWH§ÑŠ@™ÄOä},E£fGÀ§M¹Ýª¢`îÍÆ³íT­¹Å•L†ê8@^#àKµŸ†Èn×0LvûÚIU—Â'>›x¯ƒÒ‹ÓG)º&Jx±Z§/„!ûÃ-Ï\Q´Ù]M9*Ð80šÑðä™ÉØŒGµÀá§­eÑÿA"8QK¡ €Ó#¢ìà úa´é–K M8Pr.ÔI´Oj7n.ñ9NkHü$rìx" Èd8ž/l:é À2X—ýe§Ã¤µ¸‡9$G?iJ—¼TUõDo@ 0Âëòÿä·4˜¬f“%\R•ÆDX6°÷(h€GH %ðI”Bd"¢ <Œ-íRT5ùk!­eÛII<¬ØÍy­Žº@bÌs xŽa“ÎoIuèÏ9ìØ«ÂÒÞ§p§×¡dÑûÁý3Dt¶ƒê7Õf¶ËLÌ-•9n%Ó-x³1GˆNßB>.ù7Ãf1)³Ng0®*>¹1-öL H±+‘•¡zÚ!DqŸ¼€Þo=©\Î Ë…JÌŠ”/Ç“:Úƒ ¤/£ÉXÕg ‚Œ|x74,k’ÏÒ–BÞ ÇÉÄl²[?¢ º.xp[„;¶îŒ£3 îÐ+ S°k´êÒîþAg}#UEìÂ…L‘° 6D¸pêõ¤öâö3 }¤I=óÁñÇ“ÎL•¶"Z¸4¿d "l ;R™‰dT_…(¢)˜†b„ØŒ±ï`å€Ò›Rj=‚Ø"Œ)„ydBôñq! u$…qŒ‹¸q…F¬Ñ3¤–kS¡occ:<ýà6Î õ3VÀ¥ªª+TƒE›H È$D™ËÕ ³ƒÍSs;©Vb§PƒOmTq9WM ï"“@?—âqI M8.Äq`Ÿ"«FZýY>B߀ 1uA%lû‰Š:ÉŽxpG±š&vöÛ‡éJÎ7$†Q½ü$#8ž(® Cg0ÄÔŒ`óG]Ô:¸“®Ëµ;$w²\ÚDX!@@'¾¹9ûÂT̰Ù0ìàâÌ@üHxqì9n>¼K÷_“T,–¤ÍíýÎÎÛ(´¶mdÔ#Œ^H#Úý;M'@™¬v›ÅW[±nųãˆ'$f:ÅÐ, eø•ê XwÆz[´Øƒ´HÌós|2౜xGÆAdb¢†€b°DJ'ñ"ãÀTAlÆwa€ÂK,×Äå9,K€$X&Ûb¹tEi¦Gú!rÀ‡åºƒíÁfb ‘¬àÌD£±‡ÞuT!)*Hø a Ÿ¹ß^P…¡ «u© Ç“i–˰%`Ó Ë§tâ*„Ïk²Æã.;¬êˆ1iƒ«¬û6Ê»»˜›ëgÙi|">‘ ‰F¤&–ñQ8¿±-B}N.$NU0Ï-µ‰d¥–/tIø£98%1§$ÇÒ\L™òí¶°xéüòœb„ C_¦$(ÐW¼!´%P¤è$5º(ææÅ(mïmIWoÝk®odkp†d=#mƒõ?{ Œ d_P§‚£?¬GW8tû 7Qóa}º±mÂ‰Í ZÁ5Ø\\•ÇÀ­døŠO +<âWÁÉœ¸*Âö>ö¸?N€ÀIfL­- ‹‡K t “ØM D(ªö\š3ƒp®Èå%ª›…R­ý_~y;½·Ó­‘XñØ#4à34¯¥ Œ'É{݃aË Íf'×ô¹¼/TVñþ/G’]î¬b2ïâ”k1A­·ÓØs€GHò¼&á°äÏ%¶‹Ä ¬ø¤4Ó “q©¡Ö€>Q3èKÅRšN* ,ñ#‚$²?fsxûmI ä%ñù«‹çO½unùœÛaóa‰²¥7DTª÷™ÙoA˜ (3˜¡¢X1§.H÷<ì®®” úÑ]Ô0X™Žì!ûŒÆ‚Œ¦ÔÁº-x-ˆ•š{ &Ä <&\L¨É¡AXˆ”l°Î:‰6€4>6Úa'"áNs&<Ä6Q Lž9EÁïôé$318=èÈ”âŒ~3DpIÝk h©È¥3±„„‚ÌÝk By{?uX«¬­µ©!tlÿbà TÒƒˆDb~,aÛ¨!WèX€k*~€ÌuðJGJ}~R2 ´Çç‰O$\Ó¡év J8½ß2úÕ{©½ÆaºÎ}þ,Ÿ™Zƈáˆb¾ó})Ž—çâK?\>5ýÖÙå… ×=«¿n8%áÑïžTÏkÎûÉHˆ `GcÝ~ê@úôÚÍö{Þ-®­Vòè+ë`]d\rä”ã‰6Ü”ô9;—ìØ7T"¸NÔ\º#ãdÈ5 ¦ ¦SÂQ$Ú!FÿÈœèG@c+™¤X¾£gxquåô€÷øÜ±ôØ—c÷Ç—Ç pâÛ*v¨APÉ£ ‰R…j#½Ê†×$ Ïqü¹$g·MAŸÅ¸fn |8_ý²È@æAÉGb;®ò•‰¬Î£L½‚u˜b1“‰©.‹Y±®¬T;ù|‡J"–õ(!” ˜N°í”n kÕh´CcßHü4Rr©ŽL®^ï wvËmlpiRñAAlûgøîw•§W>Lüi<¾4™;;…ӟéI9,ŸR¼â?Üì°Ÿ¸æL€ƺc3“»[Ã÷>¼ÕyÿÃõÜýûo˜í—À#Øÿ‘ô'ñ?‡ôG¹(R_VÕ]~…ÊŽÂH¨b¬H¼è#‰F?Åá´8à¾w}6 Rµè{«Ù{ø§,„™š/V„ºóž08âo~ÙÑÆ«_&ýèG–…o¼¶°4?­Ê­Vs÷oÿ6¹ýÑGW¤k!û—)ÿwùÎÉgGòʱ0\Q:rÝ—LaH{›ã)²P©JzÜNKd‡¬Õj½'6Œ˜Ñã‹&ß?Žô,‡¾á>d¸ôÝ9þúës‹‘ ;+Ô[[÷×ðv©ÑcóQb=âÚ”nØñÇŽ0¬7ü{UedšÉ(©áßeAü¹x$ØåËÒB8lLLL¾òù^‹L„ÎGÃ×QD¹f™°£ÄGÂj–6AH`¢ $J5ýáÖæà£×Êï¿¿U][¯æ ùAõqMµŸN5$~~&¿Ìð„Pé\~Y·è(™¶NŒXÞµ)*˜¶ÇWo›I.ªXõ³·Z}™¢lÆhF$|ÆäA!|(õÉ»xê[³“KÑDr¿±²RïäJ]2û$2qc~b—"o¾h2Àéñ#:8Ô§ˆH\€¥Á „âÈ…d|ã<“è@©F)ŠÕ&LRÐgS½~9˜Í÷]Ä÷™S¥¦¤qÙ}&7<É­ÖϦ÷däÆDê/Í(ˆ_ú÷’ùb_ó6{濈„Â?=·¼ta6>ëúâ8 ¢#Ý_}ؾ~3Y„ÿµ ÿžH0;¡ÀÃQ0/²±Ô…D"¢ëîrøJÉ —hÏ´!à1ZèžÌD6Aï@2 ®Étœí¬=Z`"c ‘Ï‹-½0” «?¾ 7]¼‹CCùBÞ‹ƒˆ†mæTiy™š ¥?¿n%÷ž‘(øÀ¨Ñ6Ѿ#0P»A#Ð%‰ à°?øO ¯'À¤U”+{Ãn/†@v”¡Rï9™£þ, ™|Ùçòbá êö®ú%?~Žâ.WRcŒË/ž“br2¤”ËåïÆ¦¢ÿáò…3¯,/ÍÉv%РqÕ¤­ÄNóÁJ¦€HO„!U~ѵ/^Ûï÷ÍŠryÐ/äÚTÐ ÷¨Fr ìÁ¼GdãøT±ãeqn"°1Ÿ›¿w¿±Ú¤ÑNFþ²Áøÿc x®ß?çö¸ß:ŽüÙÜÌ©33“§TîÒƒ – N¯®%k œ/p¤Fs.H©ùDF`… Á€Ì@h= )%IÄk:îÚ@—yÎM‚tt$Q …™ÏñÔÛànú´HwÕŸ{d,Ã;mÔ°Ú`…#ƒÏ“.,_¶"†ŸÇfÛÉÁw*»ÅŠ9D¦ÊŸD&CøR0ÃL‰ G$ˆO Ç z~‡A«fhB{ÁHÐ~.×?ØÝ+VægZn¯Kƒfƒ!2 $‚÷Ùo¢§;‡]Zœ¨K‹Áðþî~¤Xn£(;2%ñ¨v\~ádôz½/yö?=³<õs3K¦—pÆ(„ 4Ã’*9ig7Ó)ä›$|2ÚI8úRpÃ{¿·t’ñ¹ áÞD»nØ °bE N€H¤Ð5Lˆi@(N 4ÍaXZZÐî®îLîí7'2™áH"p˜Ÿ;1"ñ•óç{-Ó?_œŽ¿13=µ0™ à\{„ìW°âîì 76 u /}˜¹zÀLUšÈÀŠÄe@„ÚFaÎý9ï×]’…ï2úAùHBщRÛiðâ³´Ú w^<@½áYˆUð/ ƒï&d04–³8q‘„ƒkÙl•p¦ mpÇbþ¹>Zím%Jû;ûý]œßIéOâÿ‚’o =¢8Ô+Åî£bÖÍk>µÚ?8ŽŠ0€âøþ°·³ÛLíìëõF}èu{ÑR›àûì%5 ˜Àõz“f•bѸåü™Eÿêj1ŽõŸu0j~df”Ê`ëçI¦7¯Ø‚ΉáÓÓ^œIpö…Ù¹(ÎvTL°E‰à0`Zl;6JõnæêµzŸõŒü%FcOæbÓIfZœà2Èâpͽtæpg¿»°ÓËB %`Wx˜&“.1Ê@n.á™v§æ—Ì—.nOä2Íåz¥|Xo k6¹ós1€oc†áû‘eÞæ¶] ú|oÏFbßšŸ]ŒLÃf ¢ò’ʈ@_¬ÓWà7¿ßÚÝ©Ö1÷'"¸DBâÔã1DÀéÕU3 ¨ h)©)®tµYtý!ƒÃæ‚FQJgqLx@òºƒÂ‚Ϙz4†êDÎØºjLÉHo:ðÔ±åRº )ŒºhMç3d"*â ./.Ë~ïDÐåp*×ï<Z®§;Éd‹ö92-öá O›àSé}(±uÆÌ¾Ž˜ñ’Ò‹ ›Ì «°ê£6 g6ßA<ÇT6›ÍÌ„ƒ!•á0¢bÁ€!‚¹ˆ÷‡’×ë‘._ÐV×7æŠÅÖ^j¿ŸÆ#{(o¤…‰ÂŸõç'?‘L©”2Èæ§#¯ûüþ7qÈÉB42ïqašÁiY ‚ž¦grÚ¤ÿƒµdãáö#ÖÄf)Ž=§ÛÈ£•§gUùOúÛIfë\q«ûû¥íݽF(syAìÀ#).L S0¢ŽËœ{¼NÕógífû¬jÝ®%w l©×.çD”˜Ï.ëÂðƒ`²ËÅI»K~àÛN»ç>oxi*w‡ü!à° Öë&ÚÁWáx>€8¬d²š5K†#@ Dup„»¢žK¶#è¨G¶ qÚ{ Ï•õØ|:àƒ¢oø¤$|ï“ë}ÅdïÌÏLɓјÀa– |"â!@ÜÑ“P¨ÅGÒ’Å:ôšdâ^±ÂN Lõz¸ˆäWd·M3_6nãä圡µœÕjÿ™À§1¢à'ü±©Øÿ ‡NFìÿ‘ZÁоr@ÆŠ'«ÇØ+¨ÍƒùTw÷Jû‰ƒúìôŒêМ°ïŒÞ×+$l¸ŒÉ2é)È¥ÀX$"¿öÊéX«Õºtïn±v˜é±;“ŒŒZØS½2qô˜ ­,Ül:Î,.ú¾5;{ufj‘‚ð«0(Š&àLëÚ5·Ýè¯>Ü­¤3MÆ! úϱæÔõ‘ñœèt’€æÒƒýÝ^ÁгÓ9H):ŒÀz¬„Cä&P $é$±|<Ô,á Ó·¿iŒú|Î77¶¶ØI©TwRùòF­!åWmÚ4+‹D$›Û퉇B¾%ŸÇsÑát~#è ö¹ÃN·Ë•]… Í$ˆ ÄcýDØ.¢Á‰¦½±™E0â>€O$  ÆñYÄ3x5coO!Ȩ•Kw‚;àψ@h`ÐÚLtÛCDêd¢Ñ\YÙÈÅ¢IåÌé¸ãì™yëLÑ‹®n›Ñ#Ñ2ñ“}fÿ„ÓÅ6²pVT:<ìï<ÜLÏ.¼8Ɉ“Á¸hÈäž* %úÃíÇVÅa¸xî‚I Æ_âáV"íšUö†Ó.*ØF8ÞdÆ<ëÇy\†W^r¸¼îÝ Ø¸µûƒƒüÇ¥Rïj³ÙßTœÕ¬qFe9`UíÒœq(ÿ³À„í­™øô©¹ÉSnxS.Àˆ‘ˆéLÅiÂÁ¿¨pg¦,ƒC•‹ƒõÕBëà É o2IªÿÌ´uW'4t@Éɳ‰duse=935u„‚!8ÌÉb‡ „sÎû Pº´ÛUì××¥uÄT©Ö€.Niq&¬žY¨élÚsp˜] Œ«‚@_$4cÆ›Óév/è^r˜JèN%ð0Äï]ÔÁ1¡¿Q'‰‡Rgs+×p¿‚cgÅyq##Ðh]0¼x¯ì<ØGDf)Æ#•äf1qãÖÝÙɨ{êôÂYÄÿ$O¡Á¿¢Ý‚¡ _‚qÒ&Þ„ Œ/‹tviÉpj~λ½¿ë‚Æ\¡PüÓb±“jõÊ)«eX–ÞˆE6ÎÚíž©¥S1çü\\¡Þ¬·qrUø(¨ \=¶•”„µÚ7RÙt/¹“)ת‘ÆG@Ø¥˜nPÑw?¥%ëfœC F0lÑÁTá•'TiÀ z±ärܨ—Ýî»~“q3ôà~í—Õêà*”…]´áI^Sß°Ê¡9MpYdÎa“LðÚ4*ôh§+ _07›äqFÍ.»§6¬€ˆå·÷úk7ofbÏšW6º=ÓSÓx å€ÈGP²o.¼ÀñÒ—T±h„:ÿ˃§LóÓ³¯»Ñl-Vª{àèͦÙä‡g£¾«(¡eàš)ì(ÄØ/è=YÇt‰{OØV‰Ó,8ÐeIÚ;Èöw‚Š&§F”ø£q§6À¦œøtÒHà¦yÆýû­ûªš´áŒºóØåæò¸£”68uK"צ#Å6Š=G0î‘Ðy(E XË€!¤)1< N„·æ \ryª˜œ“+‹<1 ïpÇ1MS!Bð¸«<ÔÀ},We³Ý$'çd$~"ÃSçVeá…NÜ‚´Ð}n‹zMb’‹jA <1[—<ÐR ñ¢\22©à(®ÒînÓ—Ï#Rx±Ù>ÌT|/]J9®œ¿(Ã! ÌOB¢$Üß±—„ ƒŒŒÈNBåôR•õQ;ЬªáâòiÅa·N#‹f³&C{û•ÈáaëWù¼ð`ŸkF¬FØmX—“eÄ Ak¹ŸFY¶Àç=ƒØìÇÕ0Rô×€= Ú`ÌÅúÁЉ‡íÈ)tߺ}çãk¢FóüË`ŸŽÍ€1"Œú måéÆC§=dÎT hßàxöÀø°xgQ 2Ô<§vÊ fnmµz†:¢=‰Õ ŒqíÄ à5<¾s·)‚/ À:ˆ_œ.q*/úëëÛÕB¾QãàENõFãÿÔqÇ3'*½ €zw ˆÀÃ/÷nß®zmÖu·ÕªÎ¾té%p¿ Jn¨óXÖ²¢ûßBjÙà¹DÁ<£E'ÂP%æþr³ªo&Á€s³‘ÐðÉQgR2¾ÃyôÈІý8`< )™Üéì$óõvã± $~2Naž˜ÜÚ×ôê«%\amv=¼_ ƒÑ£õ ½$^Õ`˜ŒY-~¿lÖ`º1R3ih  iùJeè]Y­”Ò™ÖÄîn1r*øÏž>¥†üA£×゚oò!³P¿)%yR–4àücÒô%BJB2'jtžÏÈŠÙ:ð^°¾âÛÜÊÄ6×kïg¤(‘®ÃDúÁì¬dŽÅäh4ªº°¢ KLõÑzN D3¹ÀQ¢ú®ß†Kb«€ éºM &Q±_[kkU§Ù¼)«Vë FµMÂbËSš`èÂJ”Eò§-€«A= %Y-Hù!ˆ˜Óvgïâa‹mÏŠ#ÙñC"„ac£ú÷ÈÀ8å£Ý§‡Èc‡‰ôŽJ­f†‚ߨ|8æl3‘ç…Hò‹Pšþ±MT2—Š­~£S†_Lçÿ˜ Ç|8ö#€ ‚‹ur]úP"PªóHižGÇ]d"ü5‰ ƒvÆþ‡À¥ðБ$~~ˆXˆS/†å”j‡ýO®]¯}øI*ƒ` 9àñÞ¤z¾L}Pßø–ûô©…é—ý8?—†KVètk‚1Q* Ë8^†ÄdžêYoWëSåt¦¾©ÎºX5jITÇ›¸_¯TúL¦ÞIgŠDö»@Í 9Œæ?` ß:ûJ)&˜!!5$ ƒ°áÔ~™0¤µ›S º ßgŒÂ<ôϸ<&G¥Qnçó8«L¯¿ç÷«Þ…Ï÷^yéì«Ñ‰¨vÁä¨eðŸ®uöQo¾øº³¿ÕÝÙ®¦›­Aâže$W",8ŸÐ㯹ѬYk_v»“0cpEªGc…"A´Ôâôû¬‡ÌLD²0ŒÈM„“ƒ6b¹Ü°‹X¬hðeÑËç!Ø`Í´i*¼&1î`ŒVìÝPÁ´«µŠôɵ{Í?ÙNg³í,ÚG¸¼‰êÃc¡J 8…ÄÏ"ã%â;š=„m‘p&Á“ð©ùÖÏÔúðû‰KÇ‘èÄ5î "ÞȈ ¤Ì6:h¬®¶ êÄ=… sNƒM5È>· ÈI¹ œÆøÄ`÷» ~"ËÚë¯ãšøÊ[¿5¡n IJ\J_¶‹Ó~þ65Ðð‹_d2j¹ëàHP,ÞVkØÃMh¨Ù Hˆ˜F› ‡#aª D…Õÿ±gPß(±ñ$"&?‰œdA´3\,ök¥R-¸™ÜãIª8uËhsð T:‘Îh BêÓ'¡‰ÃN[mú€³t"¨ÒÇbÊpg]Ìì+?Y€!µÝèÿò÷rŸ¼—Å9=Zò ^)U@Tý£#ÉGOâa&2Æ„ç´0†¾y°»‹€`PÄÏz¹$,j9¼ÇkÚ<ÊXª&6»…äVÑ}çvÙiS÷­ zhê84 @ãÓF :í­ænåƒ6úÁ÷ÿÁçožÅöž„ý/~óÀç®Xa<š~ñó·2þÏ•òO|ãEc×ðdD>"‰Î¤ôàÓŽO39x¹:4UjÚ ¨2ñs 4ÑH—\›ƒ¦O~ñ§/”ˆ,dDZÿYæç 7'x¹AZ÷ó ;"6÷ó0±?$^"©H¼‰o(—ÑCWÃwJ[þ®¿¡?öÙ¿üIõ”Ú@™p¢¿:Øú¹Š¡OXi¨”òôtÔ®Ìø û62:²½Ô~˜E›ö2ÝNáâ,S8a6™BbeÐá)0AçtÞƒ"@í¸FY.Ÿõ‘O8 _þFXÏ#V<°Äß;/hx L€Ãr,é%q¬ jK£²=$úÀ¾°ÜÏpü1qÍ÷1†¾{ød›Fì—/Fz!Kä ÚµÌ e7>©aHð*ƒ÷È1\3aGÈûU97ßç<•mb¹Ï“ضI­’š‰å° ¶ë82±í$~ö… €ˆG$~ QáÁ‰ì|v„Ôq\“YùQ–Ÿ„Ïgá‚ÛÏLD|–Ëv’ I dÖ£2ž >IDüÎçY'ï=1¡ ÒÑ5ûÅw ƒc¿ ØV¬Ÿu“è¢È„‹ïzðɱÆ?ŸHÔ|oÔž'=ÅþP ð¹g%¾ËòÈh·‘Ù¦.½¨ €€&’PÚ±ˆ$$ò¨O”l.äòÓ¤˜ÄôUÛBéDd8N¸O+“ÈE†AÍ„ÈH†ÅD¤bŸFÒ›÷yL͇ÌþŒúÇþ’ðžJXøm„¤$&"6‰‡ïM"/ _¿P"âæ#Bâ55 Þgÿ O•móèYÜz®Äö®!,w”XËgßÙ¯CdŽ;Ç™0zÚXã'‘Xî¨í„ÏgÛ϶rŒžôûñçù;ÛÂ~þ¶g¿wb®Gˆwbô%Â~08ø#‰ÆOÙŽü¤~òÞh°ŸWjã•'&>ËzÞrX7%9‰ëxb”žDT>DzÙ7öƒïð3 šÏ?/ò>d&^dxÿ<.¸ý\‰BÊúÙ÷‘²ÓÈdÖÁÄþPª²ÍÏ›Ø'2Õg"á@Ø0;‘ÉP["a™ÌOJüýxžôÌñ{Ï ûãkð9‘ Œ“úÉÁ!î“~ÿ]ß#A~v žÖ¦ÏöåiÏ=O›ŸTïó¼wü ógûCB$óe=LœÚPR>/ƒä;,‡„ø¼öYø°Œ§¥§µýiÏï!0†À„ÀgÛ|}üøcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!0†ÀcŒ!ðÇÿÜj… 'bIEND®B`‚ic09pW‰PNG  IHDRôxÔú$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½YŒ%Ùyçwb½ûÍ›[eeUWõÂÞÈ5I£™±fì¦!`0†Ç€m° Þ§ØOö‹=Q„_ü"Á–^¤—hH@ ›‚ ÛlIÖBIMQRw³ÙKõV•U¹ß¼{¬×¿ÿ™-R äQW“Í&OdGEܸçœøâvüÿßzœó‹—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—€—ÀÃJ xØüõ^^^^Öëõw¼Çƒ Xt£ñ=œ$~œëÇê%à%à%à%à%à%ðáHà;˜ã‡Ó¤oÅKÀKÀKÀK@ø«ÚùG-oø¨ŸÀVÿžü`=?//" |Ÿ Àw¾Ï¿üåæóînðâ``ûÃá‘Y}“ä0¸ÿì;Îϲ­õÍ›{ë7ÞxÝݾ½¿~åW}þóŸ¯~ˆ‡¿•¿"ø¯|ö½¼¼¼B èØ~·æÑÎëïvüo:vÙ þbøÇišqüJp~Þ–ý~xíZäy+Úì­ÚqœFEQmT•‹.NÒVTïDY‡UPaèêuTWÇêÑhuqÑ.®__Ò÷ñßÔ¿ÿîã-ÿßåÇûöüè½¼¼¾¿ø à…^øŽ˜¬Áàµà΃àe†ã‰ØwÀçç¾ívqÏEÃ]Í–Y¸ì„iž_„Ñ* ¢(’´ ‹¤¶Ûý¸Ýn÷Öë2^­æ»eYÇùò´S×U\YÔ!ÜÃÕe˜®Žªvœ.â8^ŸŸ½ù{¿uOÝíüØjoo¸~ýuçö÷·ÖŸûœƒ¬<ǘ>W{·Â·=Ù®'³æ‡ë%à%ðƒ-o#z¿þÕwìÕ1iûïkü/¾ø"˜{ï‘: ã–k9×J]>½Hs7MÖëz=?¯Kçr7ÎÏ[®XEI‘¸² ƒØ%P¸!Z|½–IwU…iX»0Š#bèî’:.†yµJÏŽnlù¤]UyDÂÀ:ˆªuDtÝ.Öë°ªª «k:««qUgaƒ~²^ÇÕÆö ƒ«vvn\ ›ÅjåÆŸýì<þÁ~"~t¼ ௓Œ?î%à%à%ðÁ$púÒ说z{ÈA¤&eîÿvÍù÷ÿKqÔ<êʺSöR§sU—GÝ¢ªÖ.Ê—u]Xêë LªÐa‰ò”›t±áÖµ«‹u¾ Ö4·Öa•â ,õºNËl¹Y”yz~qÿ©²(’Ùê<-«<\ãXC%¢ºöŠÀuU¸ âP%Ikź ]¸¨‹ún¯3ú¿ÇuEîn­çÃa-Ë„'&éß?W?ÔßÈýˆ½¼¼>b Ðï¼øb?Œ¦Á2/£0ZÓSLíyP΋´H²d±ÈÂr¾–Yf묆Q°ÊV벘½o£Nûæc>‡Þ»-%¡+‹¬Wy•|=]®Àí2¬ëyw]Ö ìÜŽ ÁÈï»5–† Èe}àX)¸"˜ªØå°,‹t|v÷fY•ɪœ¤"-ÒAÁ: Ó’vê¢Z©â(Σ0É!ËVš>ÀTPôÚ›G4]´Û›÷ã(YæÙò“£{ïÊÈÐßÝnZ‡eýþvõÓ?ý\VUýúÚ5—Áåñ£òÝ xð]„ây x x üÛHàµ×þp¸^¬?»2™—³uQFç§­¢ÈÂù|¶™ååFYe­<›ÐÈ“E‘„Wµë¥=½êc#>¯«Á:\‡­x˜øËT×à³gËU»¬pÐUR®'Ç‚þ©êu ?°vPÅÐG£¿jW[Œ Ø‚r”·2.¯ƒ$®\Œ¿`Í%´½¦mW”xX\î_‡4`JHæpˆB›ý¨JÃÞ¹„8¹•à~”ÄY·=<ã4{ìѧÞIÓNvóöÃíý%>øíß~åØg|ûSùÁØ÷àã9øQx x |´^Z¿”¿}NO§ájº20=?¾-æ÷7¹Õê(X­$DÕiZñîìº'n>6|ô‘GŸÁòž.ëùFˆ ?Œ[UU„Ù*ÛÌ‹|£vŸW=À<]åÙ ($  ¨[ô÷¬Ê»@8|€GAUWIpC¢Å*o³ÅŸ ¥‡zq˹øÛ9Ô à\ \Ç"~}¹€kÆÔZ×2𹊘Žbù â­ÝšÔüýFò2'ê€sÖ4W«§ ru¼¤Ž·°„u÷&4PDQr”$éQÆyÚê/ç7oÞz›Œƒl´½{¿3l/ër~÷äàOçóºøGÿègó¢Ø[ÿ«õµâ‹_üâûöÑÿèö®§ë///i ¼öÚWZËåµ§ WŽ.¦÷³ÅÅFgñr¹ì­óÃ÷ûuÇùjñÈz]QïR×»)à¹>*‹%fõ }ºlèUÝH ÐCáNcS¥§«¾ù:Ĭž„Ø×Ñêëy–£r#~¡5½,Á[ÌQ뜸ÆJy \“jA<àAÀ{Ôt`‹@{ýEëõ"—Ä¡kcèOaMèò±Â/bâý—+ÇX!=íÕë ÀÜ,ˆ?p´â îŒ~±hƒu}Ø. KY„Ç91,£ šc¹(Û½þie§Õ^%q\v“ÖëÃîàN§5<»}ûgÞì÷¯HX¼ùôÓÿ[¿|”ðA€¥ô}ß^^ºJS[ûrðå/¿©àÍp¸œM‚ƒú¸1“?8t‡ôœ-GÁî®s_ý㯵Ÿ¸ñ“Öh¶˜mÌWóͺ,âb± ÍGåºê æûÕºêK{§—„ä¹`€ ‹2CÙ®©ànï-Åç5ê3Ǫªt´^ÖDêÌKÈ«p—èÄú—¥n¬a ¿®»²êskº;‚N¦ÖF[×WmcÝG«ÇÀ(EBµø,@ô vløÃÐôéC„5$Âñ±+]m ámà +L À™Àg ¡ m¹°‚ ȶP•õª¤G….fA›è.м½ˆ‚,^,&§™‡'ã7{¿ð ÿ ¸uëŸT»»Ï×Ï?ÿ¼¢¯nR úåû ý”üâ%à%à%ðC!/|á áç>÷OFÜÌÖdrÞ98¼w£®³Öƒ³£Ûy:[L¶Ê²Jób‚Ÿ­Z”   gûãzt @îyIpQvëª+äÄ—/º€ºè&(ÈRžb€8„Ä ê“•4H]T|¾"§Nvs€º,(·ÃNVà ÇN$…ÄàøXÞ¼IKCá:`P×À°¶ËÐÏ1ÓÈ¡µ•L øk_ý\h®ƒN—Áþ)I„ívŽ–5 js~LÐÁ†m±°¦9²_ 7Ò’®)°&T.áÚ¸•3•l!©Æ"K€ŽT³j?/Cø:Š“RA…DDbêq´íº½Š×É8©‡¯‡ëd¼Yéùöö#?ûï’Yà¦ßúVþ†гýþ-úûÅKÀKÀKà‡B?ÿó?ï^~ùR¶WÕCû5ÌÕ]ÐøI0µ zí®mL×âÁ;ñ´ˆ­²…Y~ö^Q•}D­•gOJ<Èfð¾&/_ªºRîY9X£“çZ€¦šTl>ú±,í€$[TáBTCv¬% Ôt„…Mr@à¾@ºðíºÑÒQ‰é‘εr Ù‚í1„˯´5›Z?`øóíßÜnE @är4ÿ£Z­¯Èâùœ°Ê=@ @œÿò¡®¹Yâ–¬0(’Ôz¯~åÐ>Y…‘ÆŒ,ˆb„(„±õêS[@÷~-kTeÀ ˜Ë*À?$ÎYx¼šƒ+`9$Ü$ª^à‰Fœ—hÖ¬yå–‹ øs:—˜Ó¼™Ó ’ÑÏ[Ö~|ÀÇ–Î5‚dÚc üçb4píË• „} ìÓè° ´:  J¼~RÜ5Á}é„K#$Ô¤4þR€ÈõÛ=ƉE n»$là¸p‡Þue™»´UbA¨]w£rý„kB§+×ã êAÖˆ€K„ûZ»«†¹¢Š€y_ì5Fñ$ÆCâ!‚n™[%§„3ðXÜã™ÆI÷n·¿y‡û=¾¹wí÷c×^œ×ówþå¿üeùQüò=–€·|ì›÷ðx8 |êS.ó­V+”eÚ/³Å¸º˜d¶~‚††é溨:ä»_˜»ÓÙE-Q÷Õ”¶§À©(ÏÉqm |ÃN> ‰ÓZCû6s~ íÜ"ÝøBÑmB|=C^iàœ-ôeAq÷Õ ‡_ ꀥ ^òõg€xž×nº`ƒ’êM`Í6&hO}€ÒM³jš“N  £µ¯̃D¨=#¢²he¬]Ígn6 øpEi "êÊÚ×Yº–¡UkLú'’ÁXHG‹\Èãc̸(hÜÜmÈõ§½Àõh[Ã+ÔŽšÂ]/ÒS!I­²v˜ýŸ>°¸Ø9µ¹ gÆ1dPg®UÎÊ=‚êÕª$°Lãéh:o0ø`w´w·‚‹ÍÍÞ=ðÀ¤ø½ýÇ€ï­|}ë^^ßEòÕÿóþ|E­à•W^îln¦Ák¯¦ËåEtzúv|zzh1I™üê¿þô‘Gn?Òjµe–³fDÅÇËUŸê8-ªÑl(ØÀÝFíâ·oÕøîѸ»øªûÀ4ùø§QïÑÑ èjÌÝk(íÛægÜø*`_Iò…8ö xÙ7À K9Ei{déjÕ%Ú>=).£O¨GmÚP'œ'R‘Pê7%2¿ÇªòI(‹fÞ4*ÂÐØì¾ÙÐøŠˆCa£J„¢¼ü^àÏu ŒLöÈÜ…‘b8?%c¢àÀ¤U¸˜1Çiã’ ‘ÓU& ‹`°ÔœW¶­2ÏŒf MHCÌ8-ßËñÀ¾È„È  *ªB¡«sV¶XE¨e@:cÎ3¢!$jR–+ ñøÁÛ·â4é×o¥[¿ô?}nv°<šñ‹¿-ä—ï‘<ø Ö7ë%à%ð×KàùçŸO‹to6;o%Aû±ñiÑÊóù5¥Î‘gO^:XGE­t3[Î’·ßy£Ct{‚“þzŠgeÝEÉŒrLöÀ•ð×)~{¶ŽÈtªå±p®ÔlóòU‡Ù½Q›9v‰»: øjôV¶2ØŽà†®Õë e“DG´š4J1kâjCéx¼ùô³}å.föåìC JÂíîÞÒ2ùãK§YÓ¼Û-³ @hÌ=°œç¤Ö³Åg®hüÀ†È¯mŒ6.?¡k1ä³ìÊçWðž€_wÄÃ5Ðà×*(`Î캨?oÜs—Rm0íÆ¸"W¢áwÎí¹sxYÐÖq'dO¸^ñ”‹«Žk¯oàX»ñ½{û/`‹Nuú‘ëöu_d„säÀýeÈ/ÆnK¡XL]µš1…Aæ–Ó¹däÙšÚD®Cžc—9 ÷˜Áè,›.1|„§×yê(¬‡çÕµW¸™ V¿|$à À÷H°¾Y/U ÈgϽ“~w?øñá08>; Ž&oFÇgئgátYÅ_{á×ÛûO4 |ýw¾²Ëtr;ãÉQçôìþF¾`ºñáh¹Zu³ÙÞl¹¸ È¥€è&ynDÕ7è<-êz³=†hƒ? Ä`%°&L ky,©òñ9'(QøxiÀX±÷YƒÛ<RZ4[¶@?Nñ}£ÉK›åƒç˜öõÓç5çr ê˜ ]Åuø< D¬O±>Ž ð!)À­0]‘Wº Ú­bb4{õK­} ’€<öSŽ)x.[¢cçî ÖSÚ^„^ü¦v“ÓsÛ¶ešg<–"a (/X™ ÁßX0Ù“v¨˜&åáÎ%Òé_fy€ Ò”é‚aç,Ùr Hˆ~¸LrY·\ʼB$í‘É?¤9‚ë¦àòóýÀHVZá8® b, X)2òΑIá&“‰ÝSX_½öÚu±ÑpË$‚(AÎNr·X–¤æë‹)V‚¼*§储‹Y&¿E€âùO}æ'~ï¹gŸ9æNÞ]mÞ¹÷ùÏYa~ù%à-¢0}S^?ðßã·%øÙŸýÙðàà ØBÃ?›L‚ÙÁA´åÁ·¾ùÒp°µ1œe«îôb¹S ‹øˆÀ¹.j܈³DQÂÖmPû%;w@®Ü·@BÏÉ!G˜*H t®0ÛGÍFµ–‰[ùí¨ª ˜^c‚³firâ¹LÀo@.àÇÆ `¥¦ÁhºÔÁ5£Ž=[™÷éZä@>Ài¤ & σÒÖò~Û@It©=̱ìñŒ'–€¿˜Ô{´ÆLÔ›"õò)%ù°P@3)m‰p4ä#Õåhµ˜þ p—f®;‹©Î'ž###Ò¨Õ ÊÄ Ö¾”.l¬~]£ƒð©†]½¿•‹)ð„D²Aü±¼'T®2 ûÜ)hõK?s 9Óù8”†ï°‚Ø,9¹\Æ@È\#&¢ñ›‚ÇÔbÌz°reÄ<ž•=6DäÄ5B"î1/G *,(£¼XÎ)ÖPµ£ñ»[ûòÁzŽÞbÂÿðšó-y x ü0Kà«_ýjßÍçýÉâ¬?žÞ¿¹šÏº÷î¾{#˳6þÝÇÐŒ{ÌÉÞ-]µERÝJÐã;À8Ji8˜7d!ç%¯~­";òhI x};ƒÞºÝï¬1!ã+\` ËUª€` üÞÀV`–Ç_žÐ•Èué ¬ Äî`‹ùì¥áâ¯1 n½| @‹ô†ÃA³ÝÜ ®0)š¿‰ÌÅ7x Òºµ£¶…—«|e~þÅ|éîQU°‚§¬“›|Ǹ}™ÿg‹3·\Ž­íÑ6Ú5ýù€\¹ÉŹŸŸ©)Æ/Ü^»Å íZ]㈧n€|욤'B“nµg\¯*|Ö² L¹ò‚¶¦€,…z┪<øû‹ E6¾Ø‹èV LòLJÈÞ®›´À]ƵÅ}·Ò¶ëw6!,¡Q=`¡ÔÅœ€¿µ5ž²œ1K㓆ƨ|¨˜€,_Úøó,g ’«¤1[q=±²ÑÅÚ¡ödE®Vz¶XSp/,foÞ3¡òêÑÿ\ðmŠë 3¹ ýâ´8iå1 œ¶;Òþ3Î\° àSÌ`iÔ*š“Bb·a–— ¸è;ÛÉ¿n€oA{ @@&qüñ¦í+ žïdšßܰ-·µ³íÚhê DBéo l ¢ fGkg$x¬YV¦ó5“N7›¡é«¢Þð6ã£ÀŽS‘‡ñ‘g¯>·F»¦µ—åÍv…ÖœxDís¥@ZàZ·ä6@Û.N,æ³§×(¡:_GR 5 ²Ê°økU,@Üâ[*ˆ­™©mIPwÂ1¾®HÇ+¸ùUŒØP¨÷\'í¸n§ h3ï)~V²¸Â´_ÌÔ™µ+2RÖf(ùN–]6u-2 *Çó¢q¹H x¸Gì4,Ä$ rEéƒñ@Tl`ôÂ×F³ ;œå^–­¢n^ê(í³|± $õá-ž|x²ô-y |,%€VS…-$h¯3ŸÏ{“ÉQk:½¿“çËøäÁƒŽý|zÜ)³"úõó¯û˜¸»@ù#ýãÕºìM§Ó›h€­ùru£Êž¢Â„ADª[8“u–¢Ts@wѾå_—v.ê¢ákiu‰´‡´Ù iàë«)Ó¢UãÞlÉWz[+ìþm7Ds¥ð€ øCÿgþ|F‘è3ç똶ŒAÍ6DÄ‘ÿßH[K Jý#&“4WiºEÝDè D…œ¨HwALÝÔ pý4£]ó^ЇtîpÅÒ!éEäQ]AqÛu£-7"‚ž)ú\‹sŠ'‚Tn6?4Ѧ!Ì@‡Tócü$ÑÈ ´ƒ6TDê“b(°UŒ€HR6—VÎv¡‰}|\ë >gh@ÝT¥&“^»k“y¯V¥[ÎçîàÞ MœÂýçòÉ µ¹ž¶¯‚-x‘{°ör¹T í¥>nT Ùð(¸1!+}—‹@:ö²X†Ç?pŽ®ÃÀl¢c"ùI72ß[,2ð?¾ñààí½l5Y'/i ç—Cž|Rômx |L%¸/¼ðB<qü.7ˆ‘Ûn·×Ë‹òÀœ²`üã=n¾éªX¶VUI›h ßÂ<ßÍ–ùQüñ2+™ö–²0ÒfYð ªeªµõ޹=Nc¦»M кm™Ê4ƒ¢» ž§\ÛhóÒÒåOmn›y\¡íK€æßIºngx ´ÿ¾´z! e@@¾`›JÊgÓb¤@àΟ4W·àO[ÓÆ…NB1VZ»ØÁåX¥aë:™ÂÍÏîÚM Ê# )ÂÀlÑážÕK so-, òõ{#·½CŽ=–‚®YÍ+îxÜÁº0,§Ìê 4sƆ¯}X3wd!æ;(çë:¹G2³`ºÇ² Â;żp9vvE:b ‰ØßëX”ÿÆF—4@ê@ h8çšû¤êQµP…‹t‘"öÛmÈ Ccè&‹H::ÿ ‚uHZ¼‰…cRY44óåKÛ§I¹ ò ùJ´v5„„=‘ = ÙñðødZåy¶;_¬I«·7Ͷø%-fçz¢~ù$ðþ3ûÚóÍx x üI@Úýk¯½t»]ŠílFÇÇo·NNî£^¯ÂÓÓ:úïþ‡ÿ&Zg“~…²Þn:I{›­A•/Ÿ¢^º(êÁ{äÚÇC¢ô5è,, º*· ~µFëƒaï§:¯oÐBÆþ“ü°ß7ͺÝå29»õÚ?†×ï*Ó“¾ÒÎX C€l“ÚÐpÄõ½ž®g ›ÑàR 4hlÅ2±S¶…‰½Ó0 E™Z™ýe~ÇÛÀY`‰Á ÂqC.©Ú:~õ¯Ð¨A$2Ã&}–išž”&'ŸwIp[36ÁL [6;_,_>õ±Zh¬üéæª ^Åp4bU¬tïÅh6!•Ø•@.-@#-Cœðñ'¨Ïú,ºJîêziùUVÐ9k+„Y"D\rJñªžfú}Yå=®t5^eÊ߃€¤°±—À®¤Ý¿úê«íííx29}m²?»Hö½þµÅ"ìÉÉ0¨³ö<[]£F~ïbzÑå}=ÀWÞÅ·}S蜤ʾ#h«Ž 3¤ë(¬Š0H[q¸·ñ»‡£áüÝÆ¦‚éR7Øè»î¿2`³µ¹eš§lÁÒ¬³•Ò¿–ñÝp„AZ'ÿáá}€ˆHrö¥ÑvðIïííðwÓ.¦k@œt¦PD>}=…öÙÊž Fc¶U€c{ mÞÿGX¯cºV@¤+•Ã.¿üñ…iþœ`KVœ‚¸ÄÅ|â¦îœÔ½W_z…XN™ºŽüý¦]« –Lô‚r•VlB›Êz¥~aMVS@æüU9Ÿþ+ƒ‚æÜ„”?´ù@Sí)^+@±be;;Ÿb²Ÿ`xŽ«àŒÀ;Ìõ“Šhý¢Z0z\|†Ü‚Dt·bZmú£òàþ6Ž<£ÕRyý[\äkµP³×b ˆ%'rg(À1²å³ÛÂô¯îB/hí:ñ…hü™Üº¬ º6ÆMÐæ<ý~ù)ãJAПÅxpÿ"8jMó ËRиÜÄÿ3F‚ç«ÎÙéƒÍ*\ì?þxÿæÍ%?í/̓ÀêY<Ìâ ÀÃHÏ_ë%ð Þ†Ñ /¼¼ýöÛñ œÅïå÷Ã÷Þ;ˆ~îç~.º}Mó¿v“hп†q5¿¸IšÖ^Vem€ŽïP££h-ó /ºhàí$N·Ð¦ƒ´Ë<;(jªJ'í°$wMkÚný­JyBŠÜ†™û‡[C—þ¨èº6Åo£ ”~Bš% ’»Î|±ä¾|†v±ßéwè“ó´|á¶ J´ZT #¥NçjÒšˆH7ìh”zmD¦zJ‹Ü |¨gOßFô¥±Á£À¦Yì“NCNä?—I]1Wþø M[à/ÿ½_ઢ6uÍâ[€zVõÏËù9È»UD>¾¬¸U5 oDÔ]Õö/•)@š]„A¥¢ÌnÁ~ŠŠ¦W­iãh怌lÅdDã„•°®€œ•™ ¹žÑ¢²Q0:wØÿÉ´ž`u°l¶1ÏAûZM>ˆÂ‚q/¨®ä!ǽ¾¶E¸0ð¨•Ð%Ü ¤‹«þêËâ$N]Ã*1Ü/‘YDŸ€Ê94×4çX÷ºF‹d£óµkÿ²O#f`€Àr_!V”lÎ2Ž»}L(¿øâ9whŽjÅ/Pž|@Áù˼>j PqOªoôgöûƒ4wöö­ùj¹ŽƒNT××ÑYúß:ºÉK¾µ,kõôîu¶Úiªœ4âèPßQ£ûCTV”}Ùîî…˜Üɘ# àÚ.iéŠ $@©ºÕÖ»òÚû;#LÞ˜òmjYÀEUæx»«"TÐ ø ¨]™…×òÕwäˆÜ0TN»Ëy Šü'Jm²´6étí³:(Óš4€"ë¼@ئ›ì*4FyäBE@Î>ôg &ò«ýæ¨ôQΣ/¥åÉ$mZ?>ý&—]÷[¢m+µŽÔJæJ“vm¬Üs؃À0‹p§Ê\w³M­û̾ÆHû ×þóÑv×mlqO\&RÁnrr9vÆ+Ä'€ †ÂI¬#ÆszŠyŸô8eˆ¨pPUÍkÆ“@``FTHƒe6è-b*Þ@¦ù¶Àù0;’R5ì<¦ê%“"t³‹Z½\ÈÙd†!T[.¶&#Æ)[ˆý"€¾~=W}Á8møÜ”eip¡ƽR EHšjVN–yߦBf_ßËj Å~3<y$â÷±J˜¶k÷èx|{±dB§Ùl§¾/Ì{3=¥føå!$à ÀCÏ_ê%ðý’€Ìùô|ùË_ÎÏÏÃÕjEÔþ˭Ѩ•¼üò|+I‚^]Ïö˜*÷‘ÅbÑãE{ ÷o›ënnâ)®àí¸Œ†ä¿÷ã !]ß‚ñ‚„H}´k° UZRãH‰“©øÚþ æÝ‹™Ô`Të.æz¢ôÎéšâ8mùÛy¹Ks—©jpòIó–G;(Û¿Ñ‚…˰ò嘮U®6Aû4s>ÇÁ.NÇl­³°`p·st÷¦E«9HQšyþÀ¹jVÝXWücÁqQ—u†×5JLÕÒ /}ç´JS.€  ”‚ àLq n&ÔiChˆo¨B@y|Á½¨‡ö/Àíõ†Dâ“Å EÙ¥‚ó´ï]ò !OIKwÀÄA"EÊϧ" Sô’gDÄÒîŒØà& ï^Z,æAdBš>sˆ´°@›qbÞÑc0_¿4q/R¥Àµ¡­tx> ø¥ís¿ïËk"Eù›`ö¤O]¥ÿš“9Aì6#; Ýë`gÇ Ï—¦¾Ó¢ß‰]Û|lÚÔyj_°DbFÜeÄ ›ºKœÂ(‹óaXݲ˜-ºSØŒ_Zž<´}^ß[ ü^ìL§®{ãÆ( ÊÍÕ4H¾ùêññIÑ_¼²OÒô}~‡D»=Þó*—»ÅË3Á̾Ë;7iÒ>°šô†½V§‹nÝí£ík€ˆ3cLÝ€˜RéZ=ŒXäËÖD3+ù2üà”‡±Ô1Ýy˜è%Îg‹Ž7‡0/rå ¤îD©ð2C·ðÝË‚ÐêɼHÉÌɽÂw¬"2=Ìÿu—±˜ ÑŽ4{™ÉE * l(Çø€Æ(¢À {(2Ök­Šv€·Òùš6ðã~KóóËíÀõ¬~ùãuÂÐd’ŽÈ_G Žjµ¸ ªxG{%&þ>‘õkŠÙ¤˜ìÃQ€e펪wqªÂCµ@‘[—_Å`'Z¿MœÃõýŒXˆ˜Iur$N`Ø‹]›{»€ K‘ÆMA$ÑIØ*R5`&Ü'«HŠþLÔÒß)ü#ÿ:Qþ"TZydÕ÷¸«K¨vc )å«’½Ï‘‘þæRà^í =3~H:Aýsµ¾°ÈL®~t®‚E$þWYD8“òj’ç¬X.›m>4]˜U iºÄâBÈɤÌÿÀ,[uÒ:ÏËj«ÌŠŒG]WÂ{ˆ­âCÏ_ê%ð}’@ ðÇý¹wâ~8q—äßóbüñ*ˇ“ÙécD„3K^0âMLd>5òº]™îÃÁp£Ï[4lõ7ôFC7ö\cÓÝxüI×%oóºÉjî.–3›í‰y'˜å›H}Í#³ìí3c…p¸ådf`™c&XâO0`—­› .PD†@„€íZdTJZ‡@ÀV²,B]UõVKH W™Nþ«),º@P@Åe´ÖeÑÔó Æ)¢0À¡µ&=›+ Ê•ÇÏw™Rê{Að\…/(„—೿4!W-퟈xš±h*-‘û_`ê7¸jðÏ­[•۸ѣ éZd‹‰;¿{j>ûñ þ|òêþŽjˆ0nŽMA°É¤$p²Oe¤"ÐrÛ;öŒ• U± ßLua…ï_w–0}¯Rå¤ñk²†Ô®á´íóYµûþÄ#”7 à…ȨônµQ,²#xçà Öˆ\7 ´Hƒ1©"ÁXm‘µ‚6DHGD¬ ô‘%DÖ@_;¡ Ÿ™€ŒÂ`WÑ¥ ø SúR;Zõ8¢Y«ñE³`\âûzˆåb‡x‡ êÖ¢„a‰9úå¡%à…øÐ"ô x |¸Æÿú믧Lªž¾Óÿµßø_º“åj¯Î‹yžu³ñŒüû²=]f0ß}¯Vܾd™ãŒíl«æN°½µ'W¿‹;Lì‚FŸÞfrÍI/ÇëÙtl/á &ª/§€@) C«^¶ š./l>Oÿ9àAj–ùÇ•vV ,yã=°s,ULvg­æ¦txá›_0PŒ@ÌÚÆ|ž0Í-I†À¾ÆÜÍ*ÝZ„»aihÌã"Ò $Êlà™X1çò•m5Zöå…9)yi÷YA¹ÝKPÊξ&íz ମ 8WÀ/7ˆmiK€×˜äåÏgµ{‡°,.\H‰_GŠI‘æ>РiVån(GeD¶)–P]°]-Ö®ÇTºšj¸C „ŽÍ7» ùýºG¥ ‚˜&G›·@D í>ÔŒTaÑÈèÂlæ<"€Ó+ƒ%‹¨eIRŽ€A® @_¨«`J5©FLúÈ] Ý­/Ú³?ú¤;K—ÙÙìÈüÂF±"Ú*Ê_;ú÷ªE ]Ÿõ¯lÖ4ç3L@óùŠÔð³ã{FÀ ¹¦Å8Úu‘µóÙ„ÉR5å—‡”€')@¹—À‡-×_ÿÍt>ídÙdPU«ÏP:gzrúôñéѧ—«,99<¹ĽÎà:ÅvâÞpo€UHq—h¸±ážzöiÓîŸ{æ3o»œ—º ò°ºXM¬än ÀQÙ×_þ wz†¹z>… ¨¾<ùûäÝ[>‡B6¡‚ó €l@*j\ªVe®ÖËZ[›ä@ŽáFKdŸï(ó–¡µbW:Qnc€‡[§€)dcýÀ-˜P& 2_¤àÔQò—ªuX/„:¥ÈãQéÛˆt5E¨«8€ŽLx@¥° ¾‚v1ØØò]® :@—Ø1ùÁóµü™Ÿ^H[ã——o<|ˆÃJ×Sši{ƒê„ÂEM‚Ã}ž¥¿°`¼ w@IšÞbzŒdé6Ïæh¿P€_ø‚|| (ðôËÌwÚžN؈ ØøëBÆvoï»þ°ënB Ó¬÷£ûÍß¼Ÿœäñ7¾ñzè&¯ßÙ*ßË‹ro¹Zìr6èbÒèzŠØk·;Ô×M£NgHd:Uô0õ“¾$)©s˜î[íLjB5ÉZc¯Pi§V˜f±Ä½rç“sw>>ss"ÎWDÄW€rŠéY~f™ëÈÔË_19æ`ó£BÒnKÀ0MR÷A™^òÒ7ñ›ÎÂÍ)q¾V¾Sà Uëœ+M‚£®¨~‡?Þh Uº9‡€UãæFh‘Ö¿>ʢРi¹Rå'ǷͶ¬ñÅ󇣢!ë[ü)¨»€fê“yÝìÍÝ’üOþU]³6ýÈ- °¶¼üVÚe¿"*¿”ïŸÂ@EïCÔiÓÒlµ*ï=1È®ØÈ5è§à8ÓÜéO3ª:"µ˜wÂJI\W‚ÚüãYq¾~!´%+Œ$,{Š¥×ö’–&ÅO­Ò1‹Žë¹[Úӥ෻¬W– ™éµh¼^].w‹±ÉG÷¡öþr+q«=]©ãÖåû7­N8¤vô¥5ÜœÇmÙÇ«16ªËv¾m‡S¯B$†£²¬Ó,¯R~ÿÍ ¯ÎðÛ$O>ØüE^ŽdîñÅ6™ /íÄË»[ÅÞñÙÁî{ï¾ñéù*Û>8›ÿ$%^w™a®’'ÇŒwÁhï±°E*ÞSŸx&j·È·oãß' L³·Q4Åõ0ï·Ÿ/S÷Ö‘€»bÞ8&¡…¦“ ʾÎÜ|5uNîñyì^þÆ×ÝÅøÜ om» ´Ð˜œ» °Ñ+¹DCÖŸò×ÀÒ¢óA#ÐD$‘Ïé% (ÐI‰*OÐÞ½•â{–‚‰UÛÐÀˆ@Bêx ~áÞy—·Kêšñ®ÆË(Q>í¥¬ 9åç[•6½®õ†¨h½ÍVš?öAP‡æN;úN $“°Æg¾sÈÕàz}¯Üöœñ明‰ò`4Ë`D8yÉ9 Ý1ÑŽ¶˜©krçd¨2½š!ÏÕ–âðõKË/dÉ€È- p*)¯+ tš?ŽÓ¦V=ÿ©g¶\»k;"ßdÄuºÖV1þ³¶ÙjZ ¥/[·ktL×\¬­}¾:$9ÓŽV;Wÿ°Ï‡÷- öEÓ¾Z²>µ%g‹D ß%ó DÔJˆàJ~ù$à À‡ Dß„—À¿­^ûÊWZëýÑδZ¶Þ»ûL:,º¯½úâ'ÉùÞ89;ÛŸMf×(3$çþ&pßm^´ºÝdc{'غ¶gÅbÎŽæ€Ní^ú“oØv‰¯ÙüÌDÎC\k¹ÑÖ6ÚºêéS—ki‹b5‘&ËQ@ Ô”VußøúïRzwŽ/ @‚Ðv¶¶Ü=æ&çc÷Ú×_¶×ûð&íàˆ]+eŽ¿’7FE.˜àÃæ¥ð«?oöš\xÁ‰#Ê|­2²-ÔAÅÈ'­Zô¢ÊùoQA0e"+“ùÉ”F-b* ö¹ÍäWc©¿~~Bp¢RÚШkŒv¹¢  w¨¼'ÂqQϰ\0‡=ç«Ü0T ­TÖwÆk;@%»p)VnæJu掤£‹ºdð©j® M¦gXJw†Ö/R4¡nAŽ? ”ã…(±¿œ“9QÚ›@k k’ï\ð(@Å}¦hÕÒÊ{THìÁ¬fTû›(ÅR4˹^wĽ!b6:mI½‚ôEB² hK„„û0÷Œ±Úæé9YÞ½ÿ è¡ö$s½êyrCè!Z¦Š#”†¡¹ã‘ŒŒ˜°“ðü¨-Fƒ€óüE„ØŠHÌ•e¡ã¢r-—œAñÍ>çÙ|/qKþÖÇÕ7Ðlu˜EÍhUöDóÖy%¾§)¬8ÉV®kEçûåƒKÀ€.;¥—ÀßZ'£Q¸§í`µ wÌ]G«Ðôà²E„ùÞb9ß%zº[Ááü±€²OñÑph=gîùé©|Ïü¹¥ÍÇΑ‡®’´ªÃ®™ôT£^Õö’sÓ¤×F ´Z¿ØwÝמܻÏùK7ºqÍêñ·ˆ#èSž7›,Üòœ 9Tåij¨ý¼§Í0Ë1ÀÈ4oÞ¿˜úõÒ—…A/êšÙ`¤ xe&Ö˸â|è¦líÊ/­`<ÕzW<`Ëuœ/ðWÚšòôPéŠX§@>ýføÉ‰Òog€}&üáÈ0Ég½IšØF@†žnøÂ¨íY |\$ \É—Èe:9ûµ,"ô]LX¡á+ö¡°•±pà X[.iŸ-³%jœ °Kç4»Wó³s/¶* ëÚ˜ÛÆ‘¾\qØL¨ZPÉ^¥IjËÔ )Ækvu5$ÀG›×˜›[ _®:F›lÔî•_€eõCßÙ`®ÎAFú¯¹¨y^jZ¤N݈gЪ­Šì7ë 2`(Ž6ÇEü4D-‚fõaÖõe½†¨kÔƒ}©¾cÑ7ZÔ¯Å÷l+Ÿ›T>H C”2¯­†ÜF´¥‡¤I‰D‚4?·Mÿ,Œ]¿«ˆ¦-Wl†ƒv/ ×9ºG…“Ò í6Ÿ%T =Ë೸Ú+ô×ð‰á"_~G²ðˆIbËpôu³Ø¹6LþaŒt$·÷ £(®æBhe‹¥iÌ/-OZ„¾/ï.^ØÁ{ðñÑ|žvgíMôóëe‘_?Ÿœü}4Ô³‹³¿G:]7+kE÷ãÐ×Û. Ú”ÚÝÛß G›#÷ì§ž†lºo~óM÷ö›wÝÁ½C÷ç_ÿ £t}ªÈuÑØoÞzœb:;¤ô¡™²ª”m¶<çœ 6‘õ˜mî¾Eà5ˆ8'ͯDƒZ^L¬¦¿ ƒ /ÖðöM,0¬îÆ¿¬·³^ô-•aÊÈ-ÐD½ÛwÊKÓK¹ Œ"ê!ler— \à/“ê˜Oý¸ê} :"B‡Š± ÐrU $N$Ã倩+Àª<¥ö^þ`NìÄÓùšø¬éF<,šáO€# µ ‚hÛXJXK@²5U‰?ãEzØ ´z¡,2·o w ’ˆ!+ͼ·Zé€G¦±sŽÈ„`¿‘·!ÄÉØ7™0©‡æ|ÞTâÓØTˆÇIû2á‹hò#$M_¡úcp$ÁôÈZ÷Æ5È«UP¨¾„ÙúNAv">zŽJ Ô †±&'Ò5–ÇÏýCÆ„ª£HD 4sî[¥ŠÍRC£ü*m5 _À¯®éK·eV:à[!ŽË­£¡€õüèËþ2 °Äo}Y:ñÛW>Ò…-"/’+.`3L´Ê,K™ÉP5 ¯N»<Ûo>ˆ<ø Ró×x ü `’Þ•GßøÕÿ9žWåFPÍ:ãÙd?ËÊGæËéÞ|6„Èò…X†¼ûZ÷¡'G‘ Á´{]×ÇL¯Zü]€b|>!'|åÞ{çž{ûÎ{îô`gxål?öøãnˆuàúÞ ³Pžw)šžEŠÏ½Êíœ4©~“‹LíD®ƒ4WpôšÖ Z¹ñsÈ@¹Ü2 @J`áÖÖ& ‚)h´[½öµä* (àZ^åü‚¨-¼ŽèV¼À¥´Ë|­} 0G¨fË9ÀÁ~†ù¿ '=£òA^n‰ec1]a© 7Ÿh|UË[2‹nð'âÁ=ª åž+ðÎz–é‚U acfh²^ؾ¾¬§`F¡ŠVY*ÔªiÑ¥mu„våo×d<’¬´„ìU?R‚Ê®ÂB 0@6&ya’, ¶[£ñ˯6uï1Zø€*2Zí±!CϱUw!²Õp¾àKùßu"ÿÚÊFgXÒŽÕ¹€ÒÐøòVÛ§_…Ædóè˜ö¯ddìAƒRŸlõÐ[§Úp‹’ƒi¬³Æ¦ÌÚB{ŠÐOÃÖËïmŸ6•2ª}=gõ{i0¹<ך¹üç²KõG7´Ç0[O…ˆÎB£÷ËÃJÀ€‡• ¿ÞKà¯H`ccÕ®–Ñm’ÆúËG¼[§ÇÇ·Æ“éeQæ«âï¸EöY:ääGÙ}ýÉÛî‘GoRŽ@±!þýÜýÑþ™;xïнþÚÛîå—Þàu*­œ5ùýçÿÅ Pïôúß8!Àl“>;ÌI¸½-p¡1ü@IDATÐ8zB€ ¬S¦¡{å%².N™læŒ.àŽ–¯·íá[o3ÏüÚi×ÅŤÀµÝ§>õI4ÓÂ=8xíÔ¶7?À]QoP•Ï]Vµƒ œfx¡“ ¯7ºbÔ®4ñ±É€QÛ¶2«Kk.ðWTw˜œ Pç)™ ª¦Ç¹2­oloºO<»KÐbB “å¼K—Ô/PßêSyö1¥o…å¤&"# ÷ø»fšÎ¸N€ZbIP&B$ P¤½@:lsŒ~„§†:Ü6'µ{ï(&€v'GrþɦXs¿À;±Mð]¤çÀ˜,ÈŽmQPªó»âäjÐs½~sßmÏqç`B\&DÂ,ν“ßnʹ(D­”K—m“ÒÑÙ²³èÓày~W3/ÊrÆÒÊõȤá+kB± &„$íÜâhÞ@ŸqÊm!m_Cć îöx6ÒØ¹mÓ·EÄ'DÄd]ôs¹µ-£óêf¾Š»Ðq§­YbØ×VçØrµÃ1-fÁa«_§~AET«0¨&ÜÓ9™0cÊ‹[úå!%à ÀC Ð_î%ð¥/}!í÷·‚Ùo%ó"‰|óåaÝr×ò²fóñ ‚–·³²¼‰ô:¯qjò}^d13ê‘ÖœcʈHí“ÆVT³‘ïhæ»{‡îääÌ‘!@MùSôî¹­í·½½…ï~ƒüyf#MS¿¶[”•¥îü¼r½¹ë.Ô Õs[;\³s ]Ï.ôêæk^Ôl2¢æ£)•ëÆS7?Ã-€™ýÚh à/8<Ä·N@RK @*@NÁ€š–ÖÊá""Ú p à¬q(ð¹’‹‚W·4^èìè[ùÇem€´.$ƸķߦÌîŠxb8•‘N©>=DNbÓ¶ã/Mͺ-ÀYèþ”ß/8RÆAÅ`­Ì] Ê[ºíhö9¾ÀÜÜ " Ì@gUÿÔVÑaNþpᘠ5sž iôM°œä©>-;, ë~.Éž/rU FGÏRCo6F=ófuaÈÆjÈR¡tµr…ík˽5€FéPsº9®]צ0Ö¸DÚ8nnéÓì›ìÙИõÜtÿúÜX.Û£1É]óò2Ìû²m4íÉ÷/W‚ã$wµÚg]Ïg}k„:¥k³½ú׎sºÏFÀœÁ†g e +ˆÚåÕÖ„ÿçJÀ€(8™—€$°^!üÃ>ܹAwÒ½x,ŸßšMNGã÷Žo•eÕ_åå-ðS0ª“xKÀß&üÁÁîuÕé04©zLß÷ÿôM€ŽÖ.ÜÁ»n6Õ´°¹Mœsóæ-÷Ÿþ'ÿ>{x¦ö“£÷;¿ó wr6uÏ<ûœûôÔ×í¡åÝ2€ãm §î'ÿæ}úgÜ×~ç+îüU¬ LäC0ŸRÔÊ‹¹»½AêߊBAO?ùŒûÿÅËË—¶ùEFÚ! %ŒÉx{«Þžâ .8WõæËc´lM6ƒÎÇ{Yuþá öÞ–/\š÷òBærüĘúý»¢×L ´»uÍÌØ›²P /Æ3wxçÐ8Á²Ñq?³©!X±Í 6±À FÜÁŠØ€¦úÚ>2Q¹a}è&˜ÛÌJê pV ² 6ºÞ@\@Fý4’ß]¶øñÙ…;§ï‚PÿÙé :í´ l3jþ+Ë@ösMÌ£6,©ë )ü"(Û‹¯_²2²Áx¸bM]—¢ù¶®»—­þ»§¨ íýiŒNØåj]‡ç½Æ] /U”V/åÎÔ%ãmüûJ¹’¶mÁ|,ö´£ÀCev0Ó3!@ü)^hæw=w‘¶¦5~|§YüB¬Ý7° x®ŠÐùâ5cÚæÖ08ð[ @Ï•ÿÌ{ - #MÚqY$";¨Ás¥´{‹h1Ò!Íß¾æ{–áBÜEé£*#MÚæš¹,Šv¯]¬59…_Zž<´}?jà…g¯­^øùèq’<õØÑ/«ùjùx±,žÄ_<ÊóÕMŠøt³¼¾AÓ.àÑ £¤/slD°šêíw'™·UØF/ÅùbꜹSRøÞ|õmLÍ Óú˜ ÊSmz¥>ùäS€¼4| Sôƒ£C÷àðÜQ3Àݼ–b»Ï³€`DξŠîlmßp­î±Jà†«‰b—YYSÛòžwİ÷ú;n#íã³Ý`Eà5.WÓÝ‚7u§Í póæÐ¹.ÁzÄ%„€i>µUPÑ®T™aÆ•`(}Xà‡i€›ˆz«ƒ`åeN¦X‘0\µt㊠P.»M 1È™ÕoFU?¹#æ#‘´•ê%(ó…Ò -EQ$!7µÅÿlaiÐý׌@ a1a’ê-ø)U YUÈÉ~ Šø· ?9-4nªóýq ¨‘'rU¾¿pT‹Úoâ.?³¹ä!Íþ5’€\e)X£¾[³z€¹‚üŒÐ¦¡¯d€¬u’tkû«7úÖ"ËÆ–›¬8 ­Ø8ì;Ug«méÆöÅ$'µyµ28ö›^®6v‘ÎÑÅ—‹ÎPH¿'­x“p*ijÃï8ëêl¿ýÛJÀ€¿­Äüù?ÒP€ßïýÞïug³ƒäîjw#¯¿ôµŸæuº³\ÌC;¼…é¼ðo’©„úQ^”#´Ÿ¿©5Ò õ"}ç½ûöÎˈ̖{$ð„çhþ“ ‚øÐSåîwSRõ:eÏíîÎÛC›¾÷”4>¹Šûl2£”ðö;÷î¶;Ä- ¬MÃK<Ä5 •*im¸½›Ïàwàï/ 5Y…9Ü9ý¿CLÀÿùÿ¦Û áÑOܲòE RÂÛ!=nB¥½醊ºWŸ1sH£FOdES$U%Ï‚í8$¨)B°Æ¤Ðë´;nïºY5öö(?ŒLTdFZêºfò"j‹SÄø|i‘ñÃÑAt-ÆÅü`%U‘hô¥í³O#€¤rõÁ!“ CÕ°S“kU¥œjb Ìü‹9}*!¾A­ÅÅBs s- F†¡ŠïNÍÐÆŒßíR’MY¤©€œMrR¹>7°¼iÊ$N¦…k"¥€ôEæo¢´oíf\Só,ºÀñ-È& *pňCDÈZ‡aÀhÁÒŒkÔp­LÁ¨Ê‡B¢d.dU†€R)Vfͱ[µBPÈÚV¨| Þ°bÆ&8.æÀ÷"BÚâ)id¥_ÐWÇõŸäš1@¶f‘à˜ž…ˆ—b*´è˜s è:ÚÓùê—GÑŒG£Wûl¹[ë[%*hQ&HÓ?¨0X!²éŒãN§w±*™OÙ/-OZ„¾% ôû}&á©úÅÌõ˜‘äi‚Òöf“óç‹2ߟ¯×Vy¶ÃK u.m­™´µ…ðu²˜.äpR9~î÷0ï“@Áo€Â@¿À”/\az¡nn p¶Fn{gÓݸyÝ®­˜PAoEÀUo° àõÐü×î7ßåNë·Lk™>õé„zÚÙp7û4ÙCª¾ ˆåÅ`Þ§Xôþ_ÿ_w7öo¸/þôÿèv¨UêÞÆô?wGÔÛ?˱2Ž UíòLURs€²L žîA¦c£íí—ZÆ®Û0óÝSÞo¸O>ñ¬U-¼F@£¬Š9ȨMµqDìÃ;¯:™? Tq7q{×Gnÿ&¹ôÌ¢·³C$ñ[ÛÒª##J2w/å–àÁ¥ÌõÕ–Ìòü•¸3”9S}óþjž|85ë„°Tàf+€µFžõœ•/Nò1$$vO<½c>¾—œ–fÄN¨0]yP_6ÙÏXÏÈ4}ͤHîÿ­ÁsMyæk,9LéÄœ <3€Bù"Ü.-€Þê`M‘§`ö=üv4£ƒD@V@Ó[†çªÍÙïGÖ iú›âœËûcÜzÎxuUü›ûÒG³ €éºUKéãTM#,B ò£ûæ7kà:TÊaúÖb¼BÍËÚpu>ßÙ×â _°M÷’µ~3Ö4CdÒÃøK,.«$ gývr: Î(QÅÍûåa%à ÀÃJÐ_ÿ#!¯þʯ´Ýȵ¾Ù;zçôf™­“éùí,Ïöð‡oUu‰:`²žHéÄžߨh 35U/EU’“6¬7—̰m S…9´E ¾Ì ü‹M^à 7¦€4 ™zåVtQýf¤¨Ì¦iƯºJßjžûpÍS¼Fã¤!½P¥)8M&çMÒûƒ”\ôÂ\'¾ E°Ú°LÛô+ –©þüäœÊ+‰ûÖkßt§öobÚï*Ñ0p½[>z‚ÏÜ45ùWVÀmTuúf¶È‡ÛNm¬d<àŠÀ½€ï{©Ò¿X&‘Ò­Uç'ÉÀmm^G`±ïOÌ“ÂÈ0$&ZŸC"*Î zŒÜä—Š\$¸à\¹"ØQ½C)Æƒäº ƒ àþæT;TUE¹W>óÐ B")´hvÐôs€úœÙå–˜SZX-|è¯É¯Wzýò,xžVÑs˜“‘.C\T]$ S&~UsTlFL`cHÛ"]À?e+ÄTÐßwŽW’íPc™PÒ›Ìò*Ä£H}jíÐ3h¬:&kC7"·V­>˪”q–À=(¥O l‚`£­´r‘.#¦ék_«‰í}Œ¾ÒÜ5C¢"βþÔ·R/åfЯÁ¾ùÓ0íøe{"š:K}j,ú|µX;Í—vȬ úLy jJL Úœ‘;³ ;Qbb»ºÎo?¸<øà²óWþI`Ò›îœu{69¾~rúÎßɳlëüüä¹’¾¨vû¼ yÓSÀ¶«œ0ŒÉR»Ùª ¯ ¸àe¸P 'æ¾ÀøÚþ-^€ew©ˆP\†)pÅM±ñáÊO áØÜaþ¦`f|™Ÿ~äÙçîw÷EÜïÚt´-ÂÐç:ÊSÀÆ !“QCÿÇ~â1÷‰§v( ô€A°ÝÁ=÷ÊŸÝ-ΘӞ¿„ÒÊ+øÆý¹¬ió†Þ&ï¿úÿ‘{â©[nƒÛ‘¿ž óÐf‰!ˆÒ‰vŠæjÚ*ñ䤸™Ö‰yÑŒwÞÀ û[Ä1\¸ÃC8 N¸×þ pÎîÚß}šX€‰{tÿ),#§îw¿úÛîÁÝ{îþ¦-f6CÅtam[ÄHã !;4ü‚ln¢$Bø-!®ª„se5èàbÙÜ ß–{dwD]…¾»q}×=úÈu2 wrÿ‚ŒŒ…ûíþ”ç·rãƒsG.šÛ»F@"ˆa'rûOlâjY»7/¸o¨j1ðÌwz»n«½ñiA*:‚¶ënn£í§¸qv±dÜD¶j1Z,1ÇGü˜°i>†¤@8DÚh'„ÙÉ#€p_¬µ4z~'ú.€¨&‚Ê +<%ˆç-˜ÂÓX„—X.ÑßæPâ™÷Í Ó¦îEà«Ä #µšZ°*ÈO¥žu™~3ÏÁw…Ês\&|û³£mCPÇ_᳞‡¹z4–†«p¬y.͹ê“gǪ¿8 OyNo¶Úé[ÃáÆ Y0ãÖ‚Ò~yh xðÐ"ô üJ xíµ¯¤''ß _üÝ;›D¶'o¿ñͧH{|±˜_›/VOTe±Q®Ã*ˆ† Žp’ª¹Í[ Œ_£±)PMZ1ïV´]ÙÈ× à -rÂoòbUÑÛ¼ôñs£˜ÉL¦6û‚5Ó:(§´Þ gš´RþêùÜ}ëð®;%=ðìôÈÑKñ6n@Ycg Âu´U•˜ÅÄOÝÿ‹‹ H¹÷Ó)chc…ègÀÔ·h¿6¼‘¥•甩¸w÷>V‚™ûæ+¯uù¼…Öœâ (îÞì 3C+_ ]â–Vǘ›?4BÆ- …Žšã€•j¸/”Àë›ÙƒyÓ2@SŠË…¢×õW2‰q¾>c%81^D§ï™ü“·ÒøðXá"EÉ«!‘ ‹ä-¹€\Í:R*r!tûȈñô˜üh°Ñv½^0ßBo»ëû[XGú¸< Z[–LÀ“àZ™÷–îö£ÇFVò÷ólSdʬH1䎱Á¸úšk‡g ˜ ˆSýÊ M| ‰È([|”ž»žR Ãþ-Ü9d4(°Q• ñMÂ8·/`Ǫ1`ôhî5ßÕX*¹6°4Ÿ9{S¢×4|ýîŒ:KË–%F[ÉÁZˆ.¢Â9*ý,¢ÖDüsŠD©ïôŸNcÕ–á4[iúœb ÷ ý¸$z +S¸^)†öu–úÕs¨Û3²Ï¶k¿MÄ…àD¬ #ó´ð 3žÙ "0K×Á²UÇÙE[ôÃ/+OV‚þú: èNî[ÅøV»ßÿ‡TžÛ¡Ì1eîÓEo.‹üªµ0ó'LLŠ‚áu|Ç”®hküؼ1õ®³™Ó@QùÒÔìâ¹g]°øôgþ./þÈý¿_ýü±;:>ÆDÌÌñzùjÒ’–˜ž`&úÞ-üÏÓùdlÓ÷þo¿öo¨pâÞ¸s€É݈Hÿ­ë¤Ë]sO~òîÚíceàåz篻ӳ#f°»‹Yí‘â=è.•é4€ªë%WǬ*´£Uq þ¯B bjšr÷>ëm‚ÿ@pJKÏf . ŠO{È,}Š:Ðð(s|"s8$ bZÞ%íiêßóñ‰I‰æ+ìjó}M]$œ.Ã¥°ìf¤¾wòº›]Lݺ{Ïõ¯ÍÝ©w-üþªÙ?„(Td<̨vXb^òs _$m !€±Ue¦QÐ9|â™m÷èÔQغ}´ýiz’[;ESÇzÒK° PñðöÞ\.Ýpû1+÷ö[÷ ks*²¤XQhInYöŸ…t16ÉT¥w'÷I#¨äüu?tàM|ù _HÜË/§o-6¶ÖEÞË–³›ø´÷&»QÖÅu‚½¼“Ðú¥ñvzÑ^R]¤ãHy2W¨^fC{áTý™‚ƒVžš9ߊÁ$9Ompr#O½Î¾mÕ®Ú˜Ëã“Çd LÝÝ»ï¹3fõSŽv AP€ÝÓr¯¿ÝhöDþ7Ú7Uæ†ËðõgÁºÆªt6LÖ€šÍðG‹jô[ýx6oüizé2Ñ Ó{?W]€µvs¾SˆCÚøx Ñí¼Ài+|´ŠˆŽ-^@)äA` `²»Ö<5Ò¢yŘTio6½ÀZp,\JÌ‚êý÷zhïú¤!Ĥ\©JÖ#lñ¥ó•‰S@¸â蘫áYôºŠ¾Ýæ¨M Eß F”]ÞÄ "àïà›Ç<¯i‚U˜G¾|™îcrí·6w±vÊ“œœþw{ÁýƤWfv,= ÜT½þœúÒúl¨­ÀTÏQà<…<˜µr×í+ï¿ñï+µ° Qü¦µCX A²È߯ÀÎ&CB>ýËsiCÏÑç\úç~åþhËúRÂÖ4 …­6Š-à îEÇéƒË8`ãm¶ìÛç¿Ü^6̉ÍoºùÕŠ0àv€D¨ýTÑqY/êæ†æÿý¿ÀoÁÆacâ{mm,:—‹X¬´±î‹&øJþŒTÊe+ŒViæIÐ+?=ò•_Vž<¬ýõ?4øò/ü÷íY·¢^ÿl#{íÎ?°¶f‹éO o­Šj«¨Š ^ËTîÁ±`É”¬­jßë%Æ+T¯Rް‡IYÚ½ÒÒxñ2ãóÉo¸”zÿ*ûÆkoNµ»Ï´¼ç§cÓtUî¶Œ«¼IyB3¸§Ÿ~Ö=ÿÿ}÷î{ܯÿÆÿãÎþ7^}É^šO}æg¨xË=òØsîñ'?ƒÕ t÷ïÎÌÔ~øà¡ îÿåb ¨µNz\¾8´HëÃ-P¢¥µÈ¯a@¥¤ʤ¬y´Ü¿ËÄ;Œ¹}ˆ» ÙuÜõ'÷\{€›AQühÀ×ëv#Bµ¥`–²¦ö¨"²¢%+˜nï4f¬ëš*5 Ð½;wÝá» š£àq×îæSÄPhk‡èÿkDÍ#ÑM5iˆn, l€Þ€M&užM)8›`M@üGçöùæ£dUôR÷ܳ;îSÏÞDƒ&¢WÈšŠË9þw@«Å[Qq ý–-™Ù‰×ØºÅøˆ‡ÜØj÷àþ}Š0ãJ™¹wï¸%v^ù“·ˆ \1j±ÎÙß»åvqÁ¤hüŸøäYîî·Þ1òvýÆžÅP¨QYãBQ¶k ÷n• YhÒ!âQt¿ª#ŠLð0ÑÞù•i5”æ^a]æÓÇ¢" W‚)è–Ê•$ W( ‡œ ÔåN0Ðç|3ËÓ¶ú‘U@ñÕë—«FQÏ^¿ñ2h´M¤—g ç§ŠŠŠq™Ì¸oÚžÈjÁo—àGű {…Ž~´üB‘?,[v?Œ•5ƒ¥xAM¦ƒújcEÑí1I̪.Èà8öz¨œyüàè`ö øÓ寽àêŸþyý4ýòðà!„ç/ýxK@Uüt¿üËÿ{ôÒK»áë«qXE;Ežm¡1?ÍK|›I_-ëjÄ~‹—[[÷¾ÆÏKPi}¼¬ôn´}½Á"€M³ôÉ,Î+; à $«“†§¡u‹6‰O rNúÝr¹0-]¾ZiÊz½Ë2 ¶Z¤öúÛ`âŸ8:vwß}Âp†?l~þ>ný}·{ý:ë¾M ôÎ[Ǧ½ŸÜÜ©æG`YEpÞœÀ:íç+¶‡fžÅ²Áà©cÇÍU§€AÑðšzV~ui®K4rL¸É ÿ7÷–bÁPpb§O€!hµe,­ÈG’TNi°êG‘c®I(6ÔF#OÜÙÍ™±N&wzxR a†É>p£¶ÛÞk¹]Àø:}ƒpC´tÂ\²¨BêÊêüÓ¶ÅO1ÁO+÷ÆSîaߟ€J²†ÔP¹dÅdÌUP°“•D€ZQÂXcJb *AÜÚ-ž'ýµ;2þH.Ҿɀ<3a“‹!Òµ@Ë'«Ðoo»kŒWñýþ&yþ¹»Ÿ¼×Lz„–¯ÉšäYcñPí•iYS@%â ò¨‘™\K!«'´¥e‹$¨-LñzÁÃ(Ͷo¿LFÜ,úåÙ= 5϶ѳ9Êç«óìl£“µð[зWÖ*è›}6¦ÁÃÔofŸ%dz)ã纂ÒÍ $¸£àL£&äê‘5£ý¿¡[ÒïŠÿøÿ²B³fUã\þ—…+jUÌÉšX.ÏÏ‹Ï~ö‹˜ÿEgüò°ðàa%è¯ÿXJ@àÿâ‹ÿlpzzÚŠªÅæÍ­ãí|º½3ûÖñÚHêõ3¼›¼S7ÂvÖO¼Wó"4 4+^|¼†®ü®!)]ÊwŒFîɧŸˆwJE¹Z´êúÏñG …gð…Ë÷©i55¯¦¼]ÍÑÈWʧ—É-ð‘?}€Ö+€}÷Þ»î+¿õf¼ïÞ{ëŽùŸeiHÑ`Ü Õ“£Km³9î¹SðGm.gø™!Ë“Ð2XÄ—±OŠ5/ß”5 ®¿ÞÊz½ê­{fQ<—¬)ét]Àss·‹V¾íú£.V}Î9V7‚ð,‹`9½«3”Ú@fR\SLë×ö¯Ž”<™Å™xèícƹpg‡sdÆ9Œ½=2"wãÖ€>â6O¤2 iÚ-š£PMsÈÒ¢èþj|EÄZj'dLǦá2É [r÷αxͱBD¸ äîÐJ‰µ‡X¤k¬¢F@âi<1—À0`:`ecD¤0BäÊ~é d®îEn»¤\ð¤íÒ×euH ìÚ½Þ@ËüñÇ,ß¿GµC¥†¼%EˆvoìáÈ(út÷š6Ó3* G‡Fž|ÇùÒø¥­«´¹1äû‡‰jB¥ ¿~…¬s=#iôÄ#ˆø%× ”­© ÁhVDmC==^‘d&“½‘à<ÑO-2éÓ¬-ÒðõŒåj’_dH?1`?žP–™XŒÃ±…ŽØ×82H’¦Hæ)CB<ãjQ=Q@ßü/$’ÂoN ñß§À8`Ï>eA?—¸ŠÛâÕ·noa¤øÝq3HÿçƒJÀ€*9ÝÇZ/¾xƒ×Ñr# U=Î[æi´¶mÌÿWKŸ<ûOsƒ-f‰£ä>`‡潄#Ó>Ÿ¥Éh«ªsòevUOªÛh÷†ûÔ§ JÝëo½ãÎÎѸ "ý©²§¹ì—h‚-´£ ÌèÊ1/1Ïgfxeæ19ÿ±!>ê…gî¼û¦{‹Uuêï¼þ€YC ð]c^6p¼GþþŸÓ/aRÒdI˜Œÿ?öÞäÙ¶ë¾ïÛ§ïÏíïk€÷ð Z Êj(«8pÉN\ö(ÖÀUe ?ƒÔ(“TªR1“T%U©„Î q•YžA–#;‘(1"h^ÿnßœ¾Ïçó[ç€'4.H¦xö{çì}v³öZ¿½ïïûëz€k¯sèRÎ?SÜô7Çô,Mqð_ÆåÇ}Z6V ÙužöåÑÐ5·®7³;¯í#Ôb2!µû¾€P¨ÙZGM¼Bš€)ŽÒ(rÂùmõA³ ¸ »ÿ£÷ vfÿ0Š!aüåNT8lT²[/ìÉPÎn¿Ð„dL0! qŠà2¢"a 4J€þ*ñ<ƒÐðç3‡@}ò•UOŸ~Fÿ“s…™G­‹p@‰$ÈYMËURð¢Â `/ðoåöÙÇ,Œ¬Ë¤S6Hgl¶6³ÂA†û—Î_$&!GŠf‰çnÝÄuóbÄfT |fû›mfÄÚCÄ]ë.¦ìîÝûaù@¢ŒgߪQ~˜`̰Fö|ÆHDÒ6ÍÒByHP%45AÏÚüTÈP¦þ$æÆ”ƒÇ±„`À5oÍü+üôy„å$„5y®Z Ü–.¥wÜ}jïVb,òŽølõÕSOáˆÒÍýÁ,{xj(ÔPf œ‚@ÏN»Ì1€[¨UG€Î›M5ÖZÉué™@Ÿžƒ oSP­ÇòÓz{s¸¹½9¾ví7¯¢—¬—ÏHµð ¸¾üÿ_øÖ·¾Uj6;ßÿþam:|øÜl2Þ>;>|~Ðï¼@%:*û–6a–5øžÜ?¬£š`­ïž¸+Úê©Y,#¬2ãg‚ž:³óá_Àÿ©*攺µ IߣÅMÐ`õݳƒË œºôµGå3[¢mñâ¨Èlǘàõ‰ ”rGÝU ËXH¦K-þ|‘45¦©`ÆÖ_<ä­þ6ÆÇOÊ"àÌ©ý1–øpŸpeM¼4ù„÷·ö€ç¹íý>å·:‡CƒC»,õÝOá"šàó˜#¨  2sAâi çNiL2{,¥ ®Aÿ7Ö³*Š ZGà©'±µCÉ` µ:ˆ)C@ÏI„ôÉ J-Ú&á)$ôÉ­zì½V9Í.%°W³åzûìs¤_vÑvæŒ-}8è>@ÔÖL½ÄPõ™ÑT¿\^áƒ*€øüÏûUjXsfµlï£Ð”dEØ—)¥{{¼¡Hy„’®ƒk¤#î_ÛB›ÇÀޝZÐíØÓ.,‚*+¬ôy"8óI}cl¼?üçÃ>ègfQ-ÛØg6‰ÏÏçâ£3¯9ÔØïýí'ž5>v›K€èÏÚO‘勵}»ø{|¸[´þpi€¾×øê$—÷‡d†Ìx,% ©]Oæ:h%!}®ügÿ¸'±6‹b¹6/V›ì]/WIµp•Ô\·õ+O­âñæt^ø»óÑ`ïðþ‡_ û7æçÇÓñ+h¿y¢í…3"Ü'À ƒVßkAÆFou¾" k'xɳΑG¯Ytï&ixû×Ñì·Â`AµÿJÚ1kß1MÍšI¤g 5ÏßXËhÿ0BÊ ¡-a„¦]+ÈU‰S®¿ÿš¢&Ü9@RɮݦN?Ef>ùø#LÂa1 ò\µBG‡Ilþ‹ó€Ï1@šÎ,Øqܧ€F+§ºµš¾ù&î ïC逴Dø¯³Ï"”Àÿ;ÐË—E8üH@øXÐÞl®?·‚R©B$bv˜Æxw?Jð>¾û”8„^ö½ó´bê `ŽW°yæÎ~öÂ+ÛDûç³í=nGÅÁÁ –“œU}2ÿu6ǧÌtÁZ,´_n¡`æ> š#d¡Í[€©Çó´^A°ì¨b˜™ŽñM°(@¡lQ8ùFúÉsÎFÔ" aÎÄf‘zäõÏPS{Ðw ºî^ÛΦÛìÍ¿ûå‰[Y¥±O[dKànévNÃ’ðÂö5jHW²3Ü/¹ÞY¶ÕÞË^Ùû‚Ð0»ÿÉ'AÄ=ΧÜqv©ÅÑœw©W p†åbHESöM&ø]ÆÃD÷9åñÊvf‡ fÖ •>K#´q~¨#gÄO€7˜L¹dÚ¥qØçj,D!ÌRÈu¬2\‘}Héy‡ ÆÃAöðˆ 87Ü?Ô]¨ÞGÛZ~R?”ït%ô}ü%Ϋ"ØÔùxM£†‚þŒusH{üÏQ®Î7¶·§;[7¦;¯1±æz¹2 ¬€+#庡_e |ãÿ´¼··W>ëžµa.[úMÇ‹Ü,¿‹oa7lf…ÉŸàUlÃkDdLžÌâ ø WÎp%>lããwÊYK»*H»+‘OžGû ÕS-ß-à°š Ïßt>?%˜ôÏsœf&P‚8úàMÝ‹LÑB.jò?Ó ‡¹VMNtrŽm@@ ’ádÖ„ðñ÷Û¦>e5‘ÌQy­Zq AðéÄO3‚ñºöD‡| i2Ý£™Ñ·à PÏá_gréäTÀ}ÑÂG-ÈéÇ:í 0ö‰n ƒÂ"ªYŒz—Ýð‡k’ŒÎ70°A–A P®üWðqNÏÉ[W“.xóU´›–ú)hÙ×å—Ž1 y?õ á+ÚàœŠÔìÁ¤ÏÍÕü‘+â™súv!QК÷¶Õ S(’G0d—~©ñÛæy<ú¼¼hµ «Z²q#ž…iˆÖ°à5$BȱŽÂbzŸ<‘ôþ+™~­âç3‚T¼o´Åàœ™1ϽŒºŸ‰?w–G1gEŒ±ûHx6œÂõì×ã>Ÿ)_ öŸùÏs¤¯ñÈã¸ÛìœÂ™ö „øJt¤I´}cF™)‹ÌH!‹m9ú"$©ó¤rÖþNÏ*Iô‹Îùi‰Q(ðŸn"—˜o€&q`xã/tA‰yn¹©º½åÍÖËQ`-\!×ÍüjS`·ýÂ+Ù`ñÅÃËãÛ§ÇGu‡ »/ s¶s *¿çë9kõŸœËàaJ h(T†Ó·ËÜ>€2€ø ôr¸9€;°ëLÔc~}ÿ¹¬výfý}÷£dí½'ǬÇÙîÍg²W¿ú•˜aïõ×^ÊúÝ^ö¿þ÷ÿ#>ûSŠÄÜË:Dô×Ñô7®dF›eMÿ0_¢ž™˜Ž5Eq{Yd0ï½ûv 蔨P6Š‹cS*ö]>€É*x ñÁØÇcíÏc¨Ð×`¸Tµ 3¿9MqŒü­W¯ïÚr¸š“‡—a˜Íæ77³Òoe»u´Þ<Çè[yò0²]Þ!ŽTÀ4f}è]ú^Èîß{}ø—w³‹“ËìÝ¿ú€}s&¢¼1æ«¿A#b šÛ3ª%j¥°FÁý"\®wØb!)¢ú¸4¤£Ý§{Õé¼Ó$ão_4yÄhì&IBMœ-‘YýŽ(rD:^µÕC³îd×ëÙí›oBc&0q ù,Ñ®DüDŒÎ¡ ÁŒSÞîw9Âζ“"`Â-ÀÌ1`_üB‹e‚'Uæ(¸žåÉÅc%ˆÁÀtÏ&ç R,ÃÚuf¤¶@ÿ)±lŠX,-Ãìn¬…Bš–—! lÖÁ¼¿ÈÎ)‚tÉü¤ 3…Mâ%Áx%ÇXIF€½‹¯³/Ow•˜NØI<ã( kªÿTsçd¼4œËØ ¦à{˜üGŒãßþì&I:Aû§P m†‚ׇL¬ü“µÉ²P»¿N•Âૃ3’M“u<ßÔL] =\yr/}×ëXr\º¸èÏâÖÍÍN³Y׿ûî{ïþ }kÿòýî?å ]/WEµpU”\·ó+E§íµCï¼óÏ Û§ÜdØ£nLq›Ò§Û˜Ä·à¦›˜vh¸5™— À&S4Ò^¦i=û<ë(Õk83ê™~rv² 3…µ[@."¡ñiwyg‹3šÛvêÔ™¯’æ¢VÞ!CàòŒr·øÁým? Š ß¿÷VSCK”- ØÁ¹å籆JÜ@˜×Ѽ T ?LV“¿•×ô .2}¿4± ~9>Çœ¾âË}aàçÜAèLd¨™8†¹¡ þ|tT´{ ÁìË 0X1¼† hq¯7¡>}ïŒ*zTÇ›P[ß”ÁFc3´ÿÖÕøºJ}ˆÐ•ܺÂzÀ.òŒS½Q €½‰ˆl궪ËqCº–„÷û¡ßhßž'Z«5&€š ¤FëÂÛKAHró{A ›$š£™óK€Uêh žàQ´rœ9Áœ\ñÜËçõòÄ|ðaOa¥ñöœPËZ9Ï H&ÀgU¬ãyûl‚Ìv€1Ѝ¾‹Sƶ"ëŠá·à©©=u”>='à²Ër¼Šã4¡µ…ŸñÈé27£Wjðaˆ?J]öy_Æ¡š:‚ BÒ€ Êö|i)mÌXñv•YûxvÈ¡ì«þU…ÕHÈ(ø§Õ&âO¼7ÛÞÞáIß=Ûµ Ìü½q÷ÅôÁ{ïÿËÿæ_3ãò7Wôœõò)°>#×—ÿêQà­·Þ*ÞØÚº5žö*?Úÿâ`§Ñž\ü|ù/Ã`vÛ­ÆKpž*©T5ͦ2ç¡QÖ°3Áß °­=´z|üím&s1½OÍ Ó>L 3è5 YÑÌ<HÈ]?>ïg}òؾOí|*ç=~PÌÉ_'eŽ<þýÿüßýó¬Ët´ßû³¿Ž´7Xð „ñYç]³.e†a¤NTSÓ¹¦é1>ý ZÞùÕü`–Ò`ü eú]ªÓø…dPz¦ÆÊ9×®=CŒ@%ê Œp9X“8ê"$$€ó)ÊÄí†× I[ ó?" Œ¬'ÝN°âOïeoý«?'7'û" W©´#¡syB`ßšê ;%îÁ؆³'X2H;9>ÏŽž‡;äÚ3û~=ûý¯¿Aty•²¼‚æåÑA6¤^Ás;ðIǰ.ht& ÊÄ’™A_9xyÐ8µp;¯WD!nlh)’nX¡¼ò¶Uñò<%õÏ”ÃÞåˆZ(>³ÝÅê‚¶m,Æp6ÈŠh¥%ìÝ Oà—Ø˜-º %çøaŠGâÿ¸÷ðç_ÃàAKÓÙÝq`·-+Ä€’føCè®ißRÁšüdzn¶à‰J€J‚-BáBÛ)›èF:¹‡K‡qsà{R@˃ð‚n•væ”AV0ÿü!%²7å\šŸˆîó†s ½W¾a#îõôû À Åž»X{ßíSæÞQ°ÍQᨓþè3hÐÆuã;®@e%îa_¶7qã ,Ïyöù¦µ)¯,Ðwx‡Â4¥ ]áÃßÛºf؃·-W§sd4~÷ïÿ³úÿôÖ7 nx|)×ËP`-\×MüjQ`oï(?›lÖ§£~Åï&ZÏ|õY"ΟAKß*–«0›’ùÕ“E$>ÜOÍkÁ_„Œ­àY—_8È8;MR#ðOÑàýÖ7Ñ>L“5̺{fÀ°tÉý§U$õü(ÔïüIÖ…ÉŸœDz—ÑâE,ž'øÎ1Ë‚ v+"˜{íÇ™ú¼O,Á1E'µx™¨æX™*ÁwX ‡‘Ê\kÝ;­ÚÅNá:ÿìb{ƨ5æÐ’1k9.4>fgÆ{úø0¶ž{划§Ú›©p0|€iÔ§öÁ%ÀÁyÔ?¸ÿÁƒìâ¬Ce¿BP—Â>¤ø=T)ì³EyJEgDø }Ï4B³" mSêÒ™ü ì#&/úýâ·‚G2ÂPŽÑ¸Ì!W£.¢Â™µoĤ0ã‹ì’Js€‘C˼£€ k+È-œŠ01,‚þTIúàÙg‡¤ÝáGHfÅ9ÎÀÆdzUøP õk>Nè¡WrâZ4˜O¡ÇÀÂAï2ûøí·³'Zvqü¥[k8¢Ï˜ºÍBp®KàŽ)Aìd7mêøo0YÎÞõÍì7®ÇŒ|•b‡c}44rü £ÓΉ’Ï‘@%¾Œ@À©q.³r¬Cƒ¥¿Ž¡ 0 >)FBí[@Éc®/!Ñ™úW.ôø@ÇŽ[f„pRÂM1ÀŠ#}þ€Õ¸ Nƒõ@QÁH³¹ ,Ý ”÷U@À= FÅZeB¤.… £ó üvú^Ý=„²>X¨œÊò€¿ýçS&!@VB›v–>ÝbãˆßKòPbì99Oôÿ,2¼Œ1âs¾÷ä‚° ž!D{Z2¨XÅ>…)~2ž´6Å[%ß¾÷ç¹kòŠ¢€O\@…¢O Uf½VhëQ!Ó¡(]¸ïÏœZÄ5ÀóÀ¡›ÇkìÓ”{)6I×ÞÚŽr›È~aøÙÖÌÒ\Ë¥õ·F»À4ØíÇß›>yÒ¾ùæ›^º^®€kà ˆ¸nâWƒ›Ùyu0®Üä7:gGo o0gúë0¥MØ×6ºÒæ€ên‡ln@É*}VX‹Èv9­ªÍv 0ôYE­ú6fh4¯&%é@‹4Œ _(At}L™£øÑºêØ\£^Ï®Óòª“ Ðz/™…ïø,ûäíΘëô@(kçó)àË5JZs¼Z¨Ó©™.ß9y ̽‹ÖÜeÚÝà˜Ú¸Z_ÒÖ8ÀaŽ¿Ù¢Bt@•³²T+ë\s~Ò&#]Ë6ø­Flp  àyðX›àã½jXAІ÷úçüHË»ÿ>m¿ûÞ/…{ rÉñ¡®Ú2¿¦ÙÌ‹g ýüÌx“úÿ¯~q‡ãhæ¥7'x®Æø‰™X`_P¥ð7Å´ à—ð *äåˆyä‹ ZBEDÓ#¤)¡s?j¡H+€eœJ…>ÚŸðÍSO†lÚ­f„D_KÓ*ô3fþf†L-„ Ðç0÷ôø]D»-yû|&˜è#ó  ç‘˜=£ÿµ1ÁOeùz дj˜ëéïÄô7ΩòÌ3‹ Pß @OTþs Ê…Öh§H3€)RØHï©/AŽ ý‹>(ÐfY "Eô¶RÎ ˆVk•|£¼YïŸNo¾Y½Œ“Ö_WBµp%d\7òK¤@î_ü‹oÕjÓjíÁã{ƒÑàÅÉd°6}›|ôU÷¶a¼ÍáhZg…áh’;=§ì.Z¿s´»­Æ·€ iâ•sæH†Ž€<¢ÿ+¸&ø\€}‘\ö"õàõ…;P`ŒXüã Š‚(|Œ*e;7oÏÞ‡Ÿ`9ƒÇ&Tü³J_¯{¦è«^¼ÁD-Ñjà–Õüþ îÚ¨q#Û¸ÝSud“ïAþc—ÉËìý-øx/Ï÷¼t’g,·ã\†®æÏ5qB·£è@fyÑã´£ëâÙçv0¯/±ôáç0íæt_ÀÐòñv—ç¿q] ‰ËÃ*ˆ@…ØI@ _3hk9\ç" cp¼ŒOÄ3°Ô–Ý ÀIŽz¶ 1yèä€B #E\Uî5Dkø&XZ†°á™) ´2ûÇqIèijmV®@óD³Ð!.ygÎÀþPÑ£ÿág\%„ƒçúÔ9ÐÀ+!‘yÔ¶Z`Pó¹@JAŒ'C'ÁNp×Za ð.€ ­o>‡` {"faù/P‡àÃZ€FfºI9ßuÏ‘Êñ†H>¦ò­Rú4Ï{š‹×FÌ}Ž˜‰ÏG¿~Ü :ÍØöþ«þüÒmÑØŒç‰—ÆÈØmË8ßœªø¦µ‰çHŸ°( ñÍG¸a¦\‹j…†Þá x=.[]ÖÀqÝÄ/o½õÂà,»1.Œ_ètNŸ==xða¾T ™¼hT™6·ÚŽŠ‡G¹ê‘1Ù÷0Ë 5}Ë Ò¶l`P//Á’áJYöÉ{BSnïPáo«™mîïe/üæYͪ[L» ˜5 Î×D«ïWáÀ8‚î¾òÿ!níls{#ÛÙÛ$½ S÷ñüÄì¯þõŸáïfOî>À¤®v3§%ýÓúy£¶Ú¯Šùâá}Ñ_|²2ÍOý÷ää‡5€k]dÄZ\ 4“Í*Ä4²þPx yâ|/s¸h{ 5Ê NxèZ¸1˜-ìc¢5è5õ×[5ÆÔÎþÓ?þ‡ÌÒ×fZ]ýìX=fÌ@p›×kÐÿýðÞ >~n&v´6¬–(ø¤CAdð"BÍœ…ˆºG(X`êÎQt'Y^—„˜an¹ÿŠXŒÈóÇôM´,!ü”´`Y©“’¦Ð°ƒÀáV Žùæ=&øYª ²câê¤õ?—øë ˆŽÆm<[É¡¦ë32j¿€ÛÆm³1X6ÚLøƒäð V ú2ô=#D‹À9÷æ­ë-â$0qóxV¬"Øí"lÒž°€®nf!ýù<:ª †d ‚>*”¨«aîÇà;-±Å€|–¼~YéêL÷A;W e›•¯l۵†e…} e\這c!0ð±~Fð—P,ðñ)ûV Ú¦3½5Ê 0ÇГ4#KîgԽ݈ÏÒì½)ÙK¾j¥à'Ãg ¾ÄøBhÀR@}Z‚Nh¦ÖPÁ¡HDÿœ8³<<æ=€½ðŸ)P…eÐV{ zsŽ‚…é˜a12(À{Ó†sS<õícQâk`wRžHýÓ,ŠÜpŒ“hÓ’:,¬©ÑÅ6|nö,iðüàD©ˆåà Ö ûî¹þ²-ŽðóC(e%eD0:Ïá' sç +kBh§Ô忟\´$ø÷¢ð°²¸/Àœý¶Ç_Nl0RÚNÀï^{ïy«ÅGâ-¹u,Ë}æ$Úœ#LÏæÅùEöncmXî Ökà ˆ¸nâOóüïŽ_ºûƒÃ“¯RËÿ÷/{ÝÍ'¯ }•î?>¬ƹó‹AÎ<ì1Z¨Z‹¥Eë›Ì?¹Þºý–§­Õ›ÔŸ'Œ}Í€Š C—©0CuøOÏNI¯"¥í|œ}ðï¤ë[íHÑ«R·^æ/òØ'“+qm“)|ï¼°‘ݸµ‡&¬ipƒµk¤žãWÇ>bjÝð‘Êå€pÆ!¡•.ûSÐçÐþ’Sãä«ÂÄ:Ö$p:Û1± ´àêS±7mä(à†zê@IDATˆ  Y´ç€Ðk™:4ZÀøõkÇmÔîX¤_€1]4`s§™½ñÛ·˜†˜òÃ{ Èg.ºæV×3`,,ؼ-Hs:>É:hÜE…&‹‘R9ƒÞs´èsâ f”ᙸˆ"?„ª û ºÐÛRŽtHFþü€, ¦aN ôK“Úxh÷azFP˜A¿`«y»€ Æô>ë1(øE4Óiz†¤ Ð_$Á@?)Èâ6cl ‚U™y¶cžs‰geÂ5;Þžƒ€µüÅ‹²SAèÛ$Ñ6˸ò¸“@ýôØ#G,€ >Ê“¸™¬À{;Gx‚|UÜVà&qF|AÓ™âEcPX‘iˆ@z̹!.Ì– ¨â¬  ý¢o=й¶"«°8ŸCøàêBKtg.Ô{†¯¤À ÐÉeÕªRƒ$ñ]Ñ*äþUj)r6´XžÌsþ½©çhùPc)d`Þà|9ä:š,7è¶yµœ«Ú“­|öš9ëåª(°®Š’ëv~aÀì_<:zPê Š{óÉø™þ°÷\ÐýB0ª÷z£Müò'š1B_/󲄯QýÖЯØç$:[»{ø÷ë€þSønžÝ`ê´zÁ²ZkDj&æ'[´gD®ÿö4&7º@Ô˜¼ÆBA𠲦}£Mí{q«Mt<ùЂÂb¶O-ý™ãyà0Z™¦Q>é†ÿ€ðÌLÖašÓQNsÿ9«€¬ ›€SÒâúÓvÙæzo…W— –L°ìK7ëô±ƒÓ#ª;¤¶aØ N "“Ç_¢ºáE€*TéÃÜÞŸCï“Ùè @/¦ïN« Œa¡&Çž ¼ ý@¼ˆ}˜½&ã˜P‡ 1™ á¿´'+Z6cV°M©£›eE'+þ9MA@÷ iÛ¢ÓÚFpœî ÚM] X@)ó×Ç|Jä\¡NíÕó¢ô³Û|$ j/¿ô}—¡‡i¡yúg™câ<ÏUsS AZ–T•9?e8.NcÑ• `F Trï¢eÁ÷ÁÄx¬Îåb¦3Z׿Ä5ÎZ‘Jì&Ÿ¾†1YnoŠ0‚…}áãõ5dèeÿy_Ùo徊϶À;i„? ìºôµÓ¾vÊElÙý8Þ~óßÓ|×Üéã:N癳'zûy6þ^¶ÂN¢Ð?ø,yªEÞ×t.Žãü(?ŽÒÑÀúëJ(°®„ŒëF~Qü§×oVógõ}ðW_ÆÏúüùÅåËTÝÛeâžÒÉY'§†[£Þ~ pæöVø\6·Ì>'ô©0eo‘u“"?kó£É3Ý(>Ør¶Ët­°Á˜,Åy×Û­mòŇÙõëÏRÄæ$"þ/ðÛk¶î¡ïlN"3¥¦ÿ\í ­•3ü¯–·EËІ“.þ`&qá|ùªµx­ñ<V2cq€9+t¦Îżï3¢è¹(|ºS´Gåž‚šûmG¦¬ Ðlsg‹aYñÜÄpeº²\Á&+—õ¶åÄ+°U0ˆvãLÚ’y‹œ¯ÀBO©qw¢¶ÑðñùkJQDg‚cZž)rÎhW"-RÔ¨Ö¨ àT¼îŸyÿssøù‡úþ¡p `éóÇòðä§„\Š 8-úʵõ'MÑä?ÛñÄ‚VæÈ‡öI?:Ä9Ìu#᥽B—eŠ=®ïÜÔ»î>|¤z!€{[Ú)ž}.þµXHMëì¹4¤ù °µ4nšç±’̱ ”ˆë4A(¥¬=X Ôv縴v[µT³Û kÓs‡fZ3òº<¼!ýÌ1nz÷ÕM^…>>eséÇ\;B«w-Ýi.ÞEçf\õ^ƒÔ`s‹>©‚Ò‘ƒºõÅ_nç”–ÀsOqYþL?ø^íwÇj{ùZ¥ûp3_ïí qoÖ¶ã×f¢D»J,^mI·I|àOšüKJleü¥Æ9믫¡ÀZ¸:®[ù…Qàïìàöt2Þ<==ú½^·ÿÒÁñåþÑñåžf]|þ0Ôbvýæ5¸’}ዯp††¿µE}ùMÒî¨éÏÌtNàSÁPÄ|[F ¨6ÚÔȧf=µÿñè’ÈÂÔo=Û ??%Ÿ´Á.Ö€§'´à÷ïÞ%½î";|úpÄ^3ÚÙè÷*YCKž’¯5\d§çÙÙÑIÊi6+¤Å Ö\7èn ð$œ…iº Hi½`J”0ÇʼÇÜ£O˜Œ[‰²Áaº¥3ÅaЂ@.‰¥ÊPW€ïžÄÆøã 1¿m8±í™úä ú¥`XaÚ·ÀKñí^oɤF³'¤¥95.Ùh¡EÀ†y^L®ÔêŒàux€Qè{Î%é/;…¦yC<]Bó¯š7nÙd4~hhUÀ2‘ûò1ÇÝ@¶pQ\ à `¦ÄÍ¢Á¹‘•š_?$úž\6ŽS²˜Ó*UÄ3&´çôÓ`½îÏBßô+€(‚£d|ÐqŠ…)œmnÏ8±g@˜deª9EÏ ð °Öÿ¢IêÞ!ÅžŽ/ÃR»±ÁõøÁ¹ž;óþñ̬A×lßEŽXiý°0&ž0ò{ JaܨĜÁxN ÆCeX9ÌÁØ…ð­}NÞEK€41Åþ×°Ì @`HÓ œŽ/?}ÂJBŸ–·Š×…ÃÿŸš¶9Æ¢#}¡ìßW€î2]*ö-, 1¬t—•€â/€«çEê WçÌs¼^®”kàJɹnìó¢À·¿ýreúÊÖã>mv¼0î·ÎºýíáxØ-fåœæ}˜ûæv ÀÈoP† B”z©‰ã½Åtªh^ –ý K–ƒ¹çq8ssÚk¾í2-«ZV n,Ã"ÿF C«+RÇ\Ê(1“¤ìoDÌ@‰iLG÷uðe÷‡]²Qýj›cªÍEu9€\v®y7¸<¬-´r™/LXÆ\“s\' j€}ÐÃР‹ñ†½K€žëd¯J Z!ŒHW£“yÚ€E{³õ·íO·ˆ=«/°àÉðƒó[íÞë•‚~Ü'50SßÒ¯U¢ësªæ\£Ubºè[·Q?žýÒMóGh;Å2¸Cæ‹)˜9 Æœthøº?¦ ‡´tL äÌh/hçEÛ4’Ç/#÷‹vnÇ,†ÐWp“ô>“ŠB…}·/´?B.Vf¶½ƒ'Fv‰f.Ÿ®ÝçXYû±ã¯÷e_I€ýZQJ­è¨U!Ìñ°ÞË¢N4 £W Ž’½+Bµþ =k݈fœx÷8 ¨œÓ÷ñ!´ÿ(톂!nFÇBà—<´Ã5ÍDÆ癢õh>—ï•Ï‹×û~qØ—톃_>;Öºeb/mx$~ÅùéÔØëözÜsVçÅÁO¿$La‘gÊ-_i%Ãõr¥í­—5~å)P™>»•« ¿>êw~ôþ;4œ ·__Ük á·³[_z)Lý×oÝ3‰H{-F 1§Ðüs gï6¶± 0zÍ s€ýØ‚90Ý2G³]߀?[+io%T§ê3›Ð/M_3½µï±Hd¿ÿ£ìÞݨ/pN­üÇÙùI9{îµ›”ME+'] Ó8œuÔ€‰«² щ@Kpkærj¤[»µlûZ‹J‚Ä _‡t3΢ŠR˜îaÄEìíl¬’sòóÓE`H1°cµEÀÊ㣥›!&¢¸†ö›[µlÿ™lû&‚BÀ€é\jЇ¶µÂm`-ÀÅ׿È!| @à_…™õ†Ìð7¦ržºÝEŸ €Ü¯\xiÛxþt0 S9¸è}9®ÖkA'˜ŒúªÃ5ÂÀôƒÛAB¢ŸÎhÉ×­ §ömp\ —Å)ÎFw~f3Û=ÖJ“Ëv^ m° ÔR ª06Öü!>Pácµä†*4WXð l.03fl…¥âàèÁg9 ^¤T6ÕÏDŽФûA늖ÞKS÷LÌq%` ˜}¦•z¯²†Ü¬‹ec@›'GCæžè³MÛÄÄ3¦­"LaUü¡›Ç¬FèK €æ«²@+¸­‡@_´h[Ú‚Õ–)RªŽ4`#0by™é_ ×µœjÀì­^ÃÂì‚Áðf³š. ý”ûÂÀ ?+Ö¡åÖ#*Ïiº6RÜE‹À ænÚ›>hµy—à{re7–‹}?0©Ëäa°ôÊÀA¯ˆS97™ò¡dæõÒÔ"lœtü'›]ÞOæ,›e|Iûgìî‹ëãPÂÅ}©_ÎgPk2VÜ H2w09nHKЬñ À6²[pQãV+‡î€¨ÿ¼ÔáÓóø“+-Ÿ ØýÒ9iô«gÉ…KzÚ`§ce,¶Ì¹v.º"m`€Ï¾¨i=ω {H€AÞtqôËëVã3b<;v?Ò8Ý4,:Ëëm@AÄtI-"¾G)>ˆwGï™,´Á»&u„NÏŒžr_,=×¾%\ZR|Ãr,žtõɰÄ+ÖžáSXÛÃi¡'ç×Ë+?=–ZNM9tþ¯še+µºj‡#6‰ 昘1}wz—-®WŸkà³ÓpÝÂçDï~ë[¥ãR÷õ—Ο<½ýƒ~ï?ˆ[…JñV­^.ݹµW̸å6©høóà @4¿L¯· ïZó9¦QU¸j½ý0 à¦z¨r•ød=‰©•¨Áú «.æÌßþ4À{†¦Ñ×€«µvIw÷ªÔw9•4¬£§ Å,€=j÷÷ô *ÜmmoR4gsó0;~ð3~/;|@,kÜæ´Gq@Ó˜3µn+µyK#; Yú¥°€Ub§h) D°ž2œµ&_ûdÜ€®´D %¾ÓW€¼@ „v (P‰8 ”ªmiîQÈÆµÂ”×ݸµ½þÆsÙÖ~AËì½á¦,ªc5¼jÃçÙ6˜o§·xÌÙÉ8;;$(Ž~õ1}«Ñä°Á‹ 7@ Úª~ÚÀü±Ú€Qà¹ÿTÉ¡†….‚?¡äÂÝO]·q>É9}¨KœloÝÙ#…qú13´çá…s6È3V ¶/º‘ð)–HÌq=#ÆŽ´ñPb `iã½O_ÍÇ6Sàã”ë…lK‰uœwÂøŠ:³L–¢œÏ€Ç(#LÌ¥'< h\óÙЇ9®b³•Ìbèä<Öœ N4‚#ëJb z¸ÖâOZ‚uÙ˜ÂyÉu ]C®ó9nnT£žqhER°¸$Âgí¸R@"ïtAÁñóáÅ¢@çï˜PÍ"™\VñZ5ÜeÍ K${Vd¯°Ó¬Ï—×éG{ž”>¤öø\ææ£Î丢רɵýýôBsÊzùìX Ÿ†ë> ¼Å”¾ï>øny·Ûhµ îPQl m¦Aâ{¥@B™äòDWW›€Q K¡¹¥ÉP±`¯ôJ¿$üB SYª>¾õÖЩfÍ|`V"D|’2&sSs³ä®4åjŽW£òXä5øÍw×amfA‰Èë ¸¾N«Û¿ìSK¿‘ýc‚ËCj éoÕ?™ÞêÞ?™z#°û¡éëW,Aˆ È8õ(ÌQŒ…Ýðc{²[ÿõ3Ë%îö<6†ÍõÁˆ—L7±ì F:'Ç^NŠ\wb-jнb´ -–ûD‹ü^’oÙ&ÇX,“k|œ¹çSÁ@ SãQDÿ5íƒ? „ ]LˆCËÚdĆƖzåJ+¥”>ÆópÜve¹Y~Ò@í.æqžñ¦)Z(´ÈjúpÅHH :ЮæþÏ×±Ùœ+÷…†÷‹=Œ•‹ùí;çG-Üšùîï÷R;¾ö5é·´O_â9xÂ?S-E¼s|RLgÒ1+”¯î7Lê=ñ~°Fkš†Õ{æ^æZךRxÎõ^Ã)1~阞Eìˆv!üí ž¼úľôå»"­õ½›'¥ß«ÓÜ›¹ÚãÚóÒÂåüÀBšH<,µÉ‚é¸ÖËR@V¸^Öø•¢Àw¾ó_Uúçï¿L¡”kÿÇ;ÿî«çg'_›äæÛÃbá:…\Šõý­‚u÷Kû[Y¾Î$5LsËÄäp54€VÎâ,ÁtV¡ëóÇZ`ôÁ*5œcíy™/l“jM\ƒ6%°²Œæ TC·Výœ· ~ÛÉâÜ«©ÏͽIŠ¡š÷þ3»Y½ú™õìñ½É8ËÞýß߉öš”¾mo·ÑèЀ/;0öYL«¶®ÀP¢ Ú±í‹Ö“?ÅQÔûÔ­“f'ã.1ŒZj‹Ò»²É"èg>YèˆxD¦Î>2¨~ ¸Ô µZÈ •‡{FaeܱƒÕ,ü €Ä“ø8ñεzví9.æƒПÂÑlŽÚP²@ƒÓÄ_ðžQÔ¥Š¦]Å"’Ë·øÚ@kÚ_•(ùr«´Kë÷/h_/`í(Õoj¤ñ¤c Зé#îœÏ°T C@³Ì,Áj&Í_‹ÈaþL)þ#RêkW„ؼ¾µÝŸd›Fvšìøi'hídK7ún•¡à ›7‹!,+IY hÖÜ/¨8.%®TŽØÙßÈöÐøÏŽºÙù_‚¿~œ?¹Œl“‚kƒ Téma Ÿ«f'Å¢cf*œ¢©Ÿ³¾ ÎCпèBîQÑuA߬%Ñ@Órc ]öI ä}±Ó»¬ÌH…ŒÂÕ1FƒÅV¸”b¼”ó[XItø®­&6rüZêK J)èÈûÁ{ëuÒÆ V´ê{­–ûµÊH‡$XÅV¼sqûã‰Ì{*%ãl~+³ûGßz§R*ŸV+õþF{g¶·÷üœŒÜõr…X WHÌuSWCé8ù^¶ËÝ!ØïÚe÷â&¹9o:¥Y¬¼XþyüîFó3w(ð^ú烉SIŒß4/¸,ç10ËTl%1ï¼’yÅaØ# Të€ZÜ”Â=²§™Z¶Ì’}–vuÒœU2~à0î]%K 0ÛÌ.76£AŸi€]¢ñ÷²K ]œ]J¦¦±X¼Ç¥Bžœ~ø&aAENkúÅMÓuæ›3†eáô_›(ÃÏ8*¸³-˜'<ºs€<×É_ù8ó`‘۱ϱ…æ*ˆqŽ÷“ ³%àh}Ю­Ð`úŸ)nUfð+š.‡#èA.Ó|ë‡m/a…(Àõ˜Ö¶ ÁscíF€¦mž€@fk°*ÀË–Á}ñœt÷* (¥pŽ.wp6mC7;k'ùh!àržû½1{ŒëðÐ}âžÀ+š(ó®x}•w§‚ÀIvt¹l7ÃTopžýÖ|÷ ï‘©`;\o—ânüÝxñ,â¡3þK‡$åÄS…Û'bš0D“_0þ²ãJrhôOÌvCW’Y ÎVyIÀçfy'ýéÉq<k8³Ï<æoða γÒÓþÆëN/±™ñ¬87½b ü9.xKJÇaµJd·|¤—aÁŠƒ4ä»Àé1>šNdö·ývñ~®¸¿ÀíȰ}þùmÏlÃÅã±Ø@|Ò±O²0Æ„÷}L¨e¯Óþõ÷ÕQ`-\-×-}F 0«_}ÑÚºy|ðxëñ_ÿw‡ƒQþã—Ëíú| »ÿîf> ø\ÇÏÐO™¥o¡¯–íS˜j0ÕL¯F#[ËSzÖô²Bf˜b Šœ Äw>oÌÁDŸG u8bd¦cªŸ¡úë¹@'G32ËurWMº¹f¸*€K`Þ¤æÿufÔ$«@†lQ"Ë Û­ÂV›¾ÁÄe‰ð¿á%Ó {þ9CœB…ŒÞþGŽèÌT±æ86êœ~œ$Æ/S•¹†FœŸûµ`Ú³ÆsYo2Ér¢¼ØE¾»Ôþw[É/æk¦I|e®æ˜~ë 5Pµ@yòk†‘¬¸h[sè[D¬HgQ]9¬&Ãnê‹h¤>"à1^ŒÍŒ eŒ7öÏþ†%Àþ‰^ŒÑTC-si­¿ÃOjBL®‹gJŸCŽa\(þô'©Š´ëÄ4‚¯A€_µQÄ"S¦ï¾;\K@æù1¹ßöîFÖ¦‚£ÂšÁyp °b,\äSZ ›æéK· 'ë€+žÓR^Œók h:¦0+ßLÚà›ó†Ÿº`i¨Ï¼¦öxçFüiîW“ץР†„Ú»ñej1®âeLíŒû‹nÑ&cµÓXE켤+ñŒm{:bÍùZ—xD‹¼í|Üçâõ+-_ ’þ{Îfí;Çk-%{X,<Âá;ÛÒÅÞÇkülÃOœäãã—G¿ÒÅîs¯Kü=ðÚM¼#Dý‹jµ|J&ÈÅhrÚeN­Á믿©0°º ®Zý‡S`-ü‡Ón}åUS Õ¬S¶õ%‚ŸnœŸþî`Ð{À¾ýR½v£ŒŸ뙽ð³Wv¶`n…Œùæ¨^@ÀˆCûS)«%›ÅºL}W…ƒ2.€‚Üë„MsÂÝBĤ7;ûžfP祷¶>Z¼õØ©c3®) Ì`Ð 5Ý \/p«*Xmp³¿]»y=€æñ#ŠÑ–傸)ô;7œ;€ëüoå¸ÃÉA6 5Nf­à~ƒÖytê³_¦*# 1À•úmË€–Ì9ø"}ׂQo¶2ßàÐKÌ9ù¼¬+V$`ÞÎö'Óöº¨] ´Ã€ËZ0ãК-;ݦ½Y¹‡yZ&Ž •û¬ZÇ€hA€pÆqíäT¤-¾ãL}ã–S„fÜŽã´$šp¸³-­ñŸ¬ ÚlìWro„ðÇxø–ùèâ”B“ÕC˜PŸ#<èÍj ;eÌÝ€&ÏÝ©Š/1ÕsqÖ@X« ð0™T¸B‚ö˜äí—…u¬y ;ÄŒöpæyZÌÝ£‰ãð7Rª’•fý3‚: ê³Î€ïPÌì×#Òo iñ¸|ÎlôÈ 1ןÁr?/„¯aÊÃ@›ú¨Pšª'ÒÆCó­t\ Q³AwñÈuÓH+td˜ãâCaY½xɰjàvÁ}¢ßEAÀwÌZ<¾jIhä·ãäB(Ö'ÏXé‚`¡Ka58¯óIúIIG–Cw/½fäÓyŸG6¤bãY­Q;ÍåfÿòÏþ‡Îýgÿ9*ÚÑÆÏ·¸s½üÜX ?7ÉÖ\5¾ýo¿]k3EÎ{ßÛï_\<3toL•M"ÊeÍýLý 'Z&¯,`-0¤Â1>ý‚3ÐÀ¡úüå‚L#“-ò»€ À ªy>B~bC[°ŒÌà«ðñz=Æ_;¥.€zšüS1–àtaòÕ¯Ï=LòÜÏ2¼`0ÆQéÄ<Öæ¯qÐj3ðî•óöd\av–Á;Ù‹×Tª“­ÉÌ­0JùHÁ]Éò‚&&îfbâE@#Ö‹tž|1ñsØKã‹ëm$ã.Ûì.Â4ì³=û&+ö¬ÕíÕM[´Ö¿™äŽqX-?i§q ô6àIº7ô‰©ob(˜«I7ϺÈb¡å *ö,õÎûzÿåóàÉcÍ(hˆYKgçÁí^úíÇb8^ÃvàN4Ì=!—;Æš¢÷Kx™eDÇ—R§všc5t#ÿÕÐwž.Õz ¨†àÁM¶Ò`"XÐR ß~XXGÂ)Ô$¡€þ`öW«7kcb0$ç*tXç_Ë‚Ï*füc–š®Sù¾Ðûè½cg87,ÜÂíp¸†xÙk¯KÏOºð¡¯¡íÓvJ+uŸCHÇBÀ¡)ߡ軦’TjÍ»¤v ¥‚ïòO-ü¤¹dùðÜÕAöG+±c¹×vÝéO??yNœì°sSlÀx†EfyáªÑõú*(°®‚Šë6>òÝü³ýBÿùa¿çOÞþ0—ýöõÖ«¥ÒæµúóÎÖ¹Ô˜ìcæ¼ &tªÚ± Cißrµ„!XÅ\Ç8ùÍ&){jꜟÀZíU ILÐ ÏHœ·¼;êÂCÒÖNÃ0ë›ÒH„VFˆp¢sýKU4ÀŸšœbÅkÁˆ?S/.Î)y; hn'Û½¶Ý~ùNöâë/‘n5Î.ÎOh{’ÇZ]£å B²ÊäªæE4UI˜­ ¼3:«˜Ó^<5 ÐhŒ°ý( EœØÅ%šñ"­ –†F€Rü–f ±5åÍHuÌßÞ+Ü0ë.VçéÓÃìîÇcŠ"Qï~ƒ˜üØ éiÓ€¿w‘†‡¥£@ñš%–Ëз ÿ.¡±[ ·wÚ KÙpвã7 Ð î1%pbazY«m. ·sæh°3­ Ü1€_ç>‚”YS¬]|¦FÃ3~<õ³Œî€úH¥|¾B¹hh~ÿýSRÉÖÀß>Dßܬ1áS“÷Í]?»·àyù®”))¬F]¡Ÿ¥¥»fŽàq²yÏtDAçÀíd®ÄåüqŸHþ.Ÿ—XMp!Eÿ9ÑçÖ A»Ž Ë«Äóå(÷j0[dx …–‚¨UûúÌ\ØÅêÒÀPÁMä\Àw€¿côŸ1 Ž–nÄ3“®íéÒ1Ý϶ç›zÛ+_}Ž÷ÍEÛw)Òb韖'ë(˜tJ¸ïˆ0ÿ8Ÿ]Þ×÷Ha„?'®Mï$¯HsÜ3Ïù.Ëæbƒfé•Ù—¥n¹Ô8Ǫ7úÊ+/“8ñ/³·ø¹Ækó±¬-+J¤µïèzYSà—B·ß¦ÈÏQ/ÿÞññŒd·Ûïîд÷læ(òƒß¿àä=98RTrbv6Öpv´ÚÚ¦àà¶,°Š5#JŒIí“pV5vãØ .¢Q7¸ Nÿ¹)ú´­¥æv†/ޤëÀÜl™bDŽ5÷t'ùYpMï’RÀçæèÄä?1?ŒW3½àVÌç¶)SW½4ý]Äk Ù2ÑáÆ¸/²–|Z¾'WLfÅö²÷ÑW3ž¤•Ù»%Ï‹.Ïw;v/Ñ'Û³h n-XˆüqÇ3L›Ó -Àõ1Ýã ŽZùº!|6˹ Ÿ_~¤|¢ÂôDÇ€µ³ï9ͯ‘æ“ׯÇ1¸íÍÕÅ#ywýDH×>kóßó]{œÍXb§B 'q®nÇeÿ½›€¤ ÈÂ@UòõÇ)’b:à—ÕK- x. x¶Íãg¼Þ3µ%½V2š oÛ­R€c0Ö!ê60^ûí32€´¢÷!Lú4l¥ôBƈö+d$Ôx'¦´E¢e ¨úG?Dºÿò>>-G5·OCÍij´Ÿ¾G¡ñû|9Ä®´¬Ö>sw~z .s«‹È릗¬.c3öýäÚ£ñlܹÞ<ãÈž­9Z´]l &NÛÆ+<óEŸ.°Mý…¤ªÙóÏïf/¿´Ïoæ­ØÄzÅûxqe„w,?Zµ ~kPT†šwmŠ”×Ç*¥%cx’ ÷(€D„‹4 8¶£É_¡G«’Køq̬{DdKêê–q ÁÌ?"ºD^ÓXBØa¿Â³î]‘>ÊQ/ñãã‰g£°Íc)„Pâ=xvéuŒÇ•ZL·‰ÞðÀlº\ÊS#:ÉßΓÖþÆCÞ£ËÆÍç–W®®Z¯¯‚kà*¨¸nã碀àßl6‹½ÞÂçs›óùl›¿î]˜ù& ]ÇdOj<  ˆÈŒ¢hŠŒ—Üx5ýÐøù-#W£×§¯o_Àm™êkaŸ¨çGõ-¸+™U€) F%£ÔgïüðìkqŽÚþòŠ<É7ÿBóe,QTG­›öôàã@HPk@:]_ÇÌ>¨sû0F€l ÝÎT+ˆt J{{ÚŽà9úà{èbŒgcE@ã6ž€X+ÆÜ áZIÝ 5\uLÿe¾Š©_KEÑ$w„Úx.~›maŸx¦ÎYä³ ü4=S`÷ïÃ@BÏÁCE¥mø®K,>AK·Y\­ÞŸØñ3_q–_~h"zcsË]îˆs~â:ω½>7Æ‹ä>ß¤ÔÆß¾Êã?½¬ÚEXß3¡Rå¨Qn •š’Özù(°>¢®›ü¦À·(ﻹ9¹szúQëíýoÿ-ôö¢Õ~}c£u§GlîìŠLÙ[®)æ Ï3žmòÏ™˜G¿l~^ƒ±]ÂwŒ@PÂÿ_¬ EÉü`DNIë’C0…̸h™“0`1„ެ?bþz#ý'ø~± / ÍqŒïÜõÇ'wìGg—áߟŽ(ÅŠ¦f` Uþ怺*O€_€–L/3!C3½Ï@ÂA§ƒbSwr!­ 9L¼‰MÑæ4âÎ0«Ï™0ÆèòÕ}üƨ¡Ýö);è ³Á…µn5ƒÍh[—‚,Ö >] ýã )C#uü‰ 2a¡ÉÁ¹×ZÑ–ÿRÎ ÐûXeÐ2¹“°ÆiÌ ‚‘Vr;¯F˽5óßyy7ëî7É €l–‚õ&hø';'‘rwí:ïž‚›ñ>[Þ^>º;'Ýš\ Ò‡£Oβn—ÂGg½ìüË@]ãÚM,(/¼v=ÛÚid;;ÍlkIƒû¤s*,ˆ§àT_ì÷Ý4eÒgžç5Õ²¹ƒ[ m¼I–õ±¬ôÙ?2êß=cše•É« ï™FÝZlc¡ÝeÚTõ‡àÎM‚VIˆ“fglÒÍ tKxŽ]cM¶Nʆ CqØ}‡41×¾ .!hÓ^úÁõ´§Ìä:zÃ=BÐÃ$Ǿi£V=¢à×Y9W}²Ñ~öq±Øê´öÞ”2ëåŠ)°®˜ ëæþýøÚ×¶r÷ïO›ð†6fú›ÃQÿ¹R«¹è5°ùªü%s½[ â‚I Í €†ðË9‚Éà îÓÔÌÚ)è`MsÕ XD ô«È=À·øL >c˜§Â€&t¹—þÿšÛ Ü=:ˆ© xt `£ñ£Évú%~bJú𯷠¸3/œIKäÁÕHmËB3Q·»k€ó´Ë}Õîôi;$;¸d’+šb¨Ÿ¼LÚ×”¾ŒÑ¢å˜žñ œnlA Ò6‚-ãQƒ„¡F{ì¥w|¯.޾ÅWB‡U{®Å¼÷gæÃöV#{þe*2ᢸZt©šwª™Ù>§n}yLJeµ¸æ~Ç?a&½ÙX#ÝÛ6õûééÞžM…€r¦« ÐÙÚóUžêizr¼W‡ {ƒX"eÿ Œ];«g˜´tŽGû4H €öÊz÷y¬ùº‰uÃ}uh]ÃÔoºÞ¨‡æ^ƺÃ3Î ¨laq‹õ2Á³ ²_aÖK¢[œ»`6Ã]Þ'½ ÚH2–xÆáxý²ßŽËkW4d‹ýîðýô¢tN\âþØ-Ävú®‡¼žNÓ÷:-ñÛïtmüfwìRˆþr-3 }ÿXŸåbqPoï#Õ§_ÿú×|± ¬—+¡ÀZ¸2®ù£€å}Ëå»ï¾û¨ùƒw¾÷µEn¶U®^-7š7 ­ÍÂÆf._Æçɯö¹ýÁJ8ý÷ø–EKË=JÄŒðÇb ¦/‡PCq1X0ýV;‚±&MoÔïâ›EC;xL_Mªƒßþ@¢Nÿéq€ûàô(Ìú£süýjùÆ ýÙL€,ïóÆõ˜êw“‰ˆÊô­J¡BÓþ†´}ttBÀÖ ;<>ˆÀBM¼¦šŽh½œµˆ?X¡ÄrµòÕ%ÜÀÎÒóÞ³;Ù”ö§!Ê|ˆ/÷[nHŒÍÆüšÁ‡†ìÀc‡ÌUáÀµš2$ÇÕ2—«=˨m°UÎöonfï¿H•Ñb2â³Ç™äÈ9 F}€Ëþ±^¨…v™g’¢¸µ¤2î`LÁË#·7pt7G |÷{O³ÿsôˆëIô$Ññ³Î‘•b¶C޾…„ìVDóÓÑ9e}•t6¤1x€1á<\*¨¾yÆ"x Ü a €°>wÅÇK«f1Ñ;h=jV$4æëÏ´ÉV(dObíAP˜x‚ïÞzþUüñ¸%|ÜOÙZ7(Ó‹ËÇéž?Æ÷ÏúÑc c!qÚ^ßWkܼ±A:h•i›L9\³÷ÙsDL¡YˈÏ;c%~W‰ îÜ0Rø0@UPÀ¦û‚_ž÷©ÊÀZ>æX=|?µ`̈T@Lýä|¶}Ÿ" •{ÍìZB}6¸/mºx}|³ÛÞ‹-;éaâHÈÒ—c!dùúƒ`‰@è2ÄRdÍ…(:Åx}^y%+ÆàsâTú=À Ï©®yÐMc×`Þ€_Ð/[ô òJ]¤«>7é,™¨9Gšy®÷‘f¶£Ðê©ÖªÐ5 ÍÔËx¥Œ?°mh×°íÃòùûÛï´^þöf\ê}¸1ßüW˜- úâáòa±R=¢@ÕÅÖí×”ýšü“òÇó?ù“?±±õr…X WHÌuS›ßùÎw*íö¸üôüáöÅeç¹ÞÅÙn¾^ºÉ_ÿv©V©SϼC{Ž™ú`ÆšýáZ(Œe2~U 4mÀnÃ|Mÿ› ¤lÃK‚Á«ʤҒXŽÌ0j½£O@ªa¯“>|³dýɽz˜ö;''0Q¬ÔëçUY5®&û”>ÜÙÜÈ6[­jµ:ZÀ-€ìúµ½þ*à¯@F~Ùß'rœHsîe%@AéUºÎd†›ŒÉ~›!`-ýÑ´ÏZ€¦óKÜDÐ R›.‰3ö…ëŒc”uÑ 0[ˆ ^ëå´+gt7i±ä¼¦0 x2tÝžoåø’}¦Ämíײ;¯ne{×ëäßSì:œ_^ÖNA ýÔôðó1‡Ÿ6Ú©×hL5û£>~èAƒ[»€ÞV :¢mÊïî1¡P—:÷ç‡ÄP\]òïµ(Œ{Œ‘Js©–@tMì šÌ.Œø}žÆPåú<]Ô @c[P‹áyŒþ±íVÌ0ȆÎÍî„PË$Á¿€;À:Û;з‹Bʘˆ~ëŒÐèëÖ0-õ·¨pz‚PF¼@—íHùi[ü7Ô’ÐVRŒ©š96€Gˆã³&ÁÔê“<'ã8ìåÄX>)Þ>ÒyÏ ³¼ ë8b4 \Ç—@¿@ذ‰¡ç86žEÄÕK$,+.$ÊÚ KÇÎkAKþñÓ-v+Ø|º"­Ãšà±8‹ã¼ á®àD{²ǽÈsÝH÷`Óý~baÿ§[i#¥f& u”/å.ȼ¸`Ö¤q»Ýž=zôèÓ«——®WWDµpE„\7ó·)Ìÿé_üË­Å¢zíâ¼wëá£÷ÿ£Ùbº]ߨ}ÆX¯ïnV*¤Èðíe`j7樱ÃÉB+F;‹À?Ô‰9€#øç)ï«P0hG0ÿœœÈhmì–c˜,a2Ì é}s€ýìñ£ìòéS½Ž²ûテö";¼wà: ÿ Lˆä­I¦MUb´ÜRö…×^"¾•½òÒ‹Ùówn“nHh_¦¾½‰Éo2!3—Áùè3ܳ9AتggXDýx'zúè0Û¾±“Ý|õvú5ð³k¤îõ.Ñ\— ?ð†6Z@Œ¡ E­‘ÏÚXvn4²/~å…ð/Ÿœe€Ï€Ô5MÛÎ`‡E%@Ò‚CÁ5—Ü6E±£•Ѿ Z~å`¡QT#D¸xõË»ÙþÅŠº»ŸüàgŸèÂ"ƒ§ 4<hd†€5é¢ßÞ2;ƒ¬ÂHÐÞ|L:ܘ´F„Š&Å‚;îíPئ:În=Wξôænvð¨—=|ÿ,2>&{‚ÒÅ;ûôxŠÅƒx-:ÞRMuŽ "h/ þ¬k­Ù.â\ìw‡mwÆ>7¸@´Ÿ 7Skå•QÈ´  Uø6ÿ<¾ùÂFŠA ²¿!ÕÎø…ûŸ`Áú„ĬSS ú13 0ˆ ӧ̯¯¢ø'=´*X;A‚ÁœšÆXSF¸szp}‚1ÃfЕ¡m,º…°hPÙSA"Æ1¶‚VžÛ EalD܆ŸBÆ+‚¹Ö þÂ@\n´£ÀiSJ% dé¥çâ߯‡ÒB;t¡Ï§[«´µ7v{§Oº/¿ü²Q ëås¢j½¬)ðùPà›úÍüWÆ/b(ÎvÆ“þîh2¼OØ(Ö‹ ÌÛÕ<Ó®šÏ/£ˆ¨y˜]å\ôc‘¶53®,\8ÀX8Iž%¤ïr(ìt¢9Ö€Ÿ’^Õ9>ÉÎð7‘[ãf–>Ú">sÀeÁÇi`k? ºµ·ú>Ú}  ß½¶›íìmô°I˜ŸÌ4&ftËø†#úþi¹ ÁA Ú@ 6 —ïŒÿ^PR¸iaÇ].@§"7]w¬ŒC &WÓ-RäÔÁuM·%8®¥b%ˆêtü®R2Y«‡ ?`…6Fý×Z Ö‹êxÜdŒ ]KÁ€”7Ï/UaâNüb¹ßp5 ýë‡Ö î˜Õ4#5‘ó]J€ƒ×Ó2ÄG€â^¹}ãE¡£tÁ¤ÍhkL«»‹`Dmƒ¢9îŒkØøèG‡šÄDþ;`æó÷ùÚRI‡|;W ðð©»wyüÁùžç¯u_\»ÜϾ¸F‚ÓuGÁ²JƒV«Ú|…1˜H`ÕļtAË× 1X &`úwŸÙ6ïc‹bQ¶%àò[A4ŠùðÌrÆ‘ð¬ÕòM?µ€“t±ÃýÙŠîïáÂåÑåÕ_„]ÕÊ‘ ¶òtVw6fÎb#¡€FÂÔO?ætÈ>*<øÎÐE,~p¾û½>×ËíÈ ð>>e¨—îÈqûá×á6 °=¶£¯¶ùSËrDzí4ßs&“Î凼£}‚úõr“©«^üT#ëWDµpE„\7óC?ý¤øñîspŸ?èõ»7GãñoVÕ­í²Úµào1ô ¼ ü­cš.TPa` «ò²2HØ?ŒÔŒ™ U5ù\¦@@ ÿ|˜}I'ï9ü8|úø.ésçhûw³cÌñ —øû5÷Ïq 8sZí¬DN¶þü×~ãKl#{ùw~0¬33\;|¸5ú+ˆzO³d\c|ñ‹(e‹ð`}]¡FM |WÀööÛÇâÀœó€ÝßïÁÝüÀ™Ù}> ê40 hÉú3Åa†*o0m³ ¦€¥ZþÁ蘈ü¬ŽÛÁ@±‘åó)¾iK滳Ï$D7v.Ê Sf8üäôS¯Àfx+ß9g:Œ­X8Ê>~÷ b º€þ½B;}zp @>¼ÙV´SÍ^¶¬ÕA³{Sy€Â Ϫ‘Ü.Ý'Ë¡#Ö€Zö{p;ûpï4ûËóAcÄ,|Ý,F¼ÁG½¬ƒ½½ŸË6Iw=Õ„E1AÑö´˜Ì­3@ŸÂ#¯ýY.¾-ÂSZs¾€é¾Ð@Ù ¹P‚YabÛ´?­PÔŸÄbA(Fóìmžn–‡ªñ>yÔ AJÿ˜ß>Ÿ@i¶M¥>zg ,-³äg€©ÿè„Xj 4œ(b^ìì'7£±ýÈTéìºk”Bƒ;8×”Í1÷žy/ΕUŸuÅz†Ìð%šqtô^t5úVäY„E€~JKŸñŠF!„§]|ûçhì·çùÌiÈ z?ß÷ݵmiIKb÷ô<þ†ãnÚ‹.10ÂàŸë5ëõ‡XPjûQugû${DÀÉzù\)°>WòþÚ6ž£Ìoéoþæ£ÚƒË» =X2=ÞbU.WªXy ¶‚MÀÛ¢N»©x‘NkXšÀ/S †Á1¸ÍjŸûe$á# †„›Dä4¦ü)àØ=>&’»—>z@Ùivüà]ð§‹à«hbF¦ëϯ£±ïlofÏ>{=kn¶²—^}1òÚ­t§Æ<ÓOQÛÁ‘)Œ¨¾Ã[è‡ë[S?M”"2X¦,®6€ŸÕýs3‡Ÿ7lÕjþjõ&~ÉiÒvüŒu6‘£  ŒKféyØ¡53¿¼ùá¸ôýÆ4±öqÃüròÕòjÜ0ý1m F;äôŒfí{…¦\ sn¯[È}B)\f„uâü —&j­‚‘–i­ËÃ`¹¼ÖÖ‚‘9öòw‘ÌÆ”ªBUËЇനIÏýCŸ>I¯]€ý½~ó!ñN¹KœÁ™ 2£V€qXOêä»3ÝCøë=î?#²2Ж>IkûE‘ßn‹Øè…ýLŒžº’ºÑd¬ã¸»Ùi½ÁK!Éèý6}Ü>µ„ôÈÄàEŸ–¯‹gÈ9Ò× l€÷šwÒG øËmÚú¾B?´ï\¡µ‘ZdŒƒpÌö9Ú积†´‰%~§÷"Îq'çG9h6“ Ìo¶ð>V&ŒË½¯mc}°¥]úcížäñ¸?ëXhÒ{àÏŸ=œ~/ó# <ûéâÆñ•š‹ýñ !ìnÃIÅÜ„‰K,/¯mµ:ðÛ_ížgç³ì¿þWéšõ÷çBµð¹õ׻ѷÞúo+O/Ï^«ïÕ®gÝâ—½ó—à íR³Aª|1O‘oþ{P-rCóQg2²;G•03 ¨°M5ç0«â?µÂÓJLÌ‚¦‰] ›ê£áÀÚܽ͞‡µŸ=yÿ}4õ~v‚Ÿ_A q†wÐÒÊòVÝg1ë·˜úµM ßF»ÁìpÍì@v‹‚@IDAT΋·bv>‚×±F¢jä0qʇ_F],ªñ ŠšxHêAUÉÖ2µ!«…ÀiˆÍÑõ×ñßpŒÉö¤Ô=úðA˜ðK[ŒÂŠph‡UT· sÔk*žZ/€Šu:yKÚqGÎ/SRvˆ Ý43Æ0ÐdbžŠ‘ù5¬Å™“¬µ«ö¥Ç† ­jmRKS>øÒñM›s_d­5c<úù»—ƒì€6yv‰öbê]+1ù_Ÿ^EÆÅzwK™ŽX¾·He?3EÆXE¼¹ÈÈ÷æF5b"Ú¤÷…À3–eLü5ÍütÔ©}û´?àýÕe£`YÅ‚#@εp8އ`EgÕ¬C0 g¡™/SPílˆ0±æ&ËÅ1—à}cvAÖʈCUùÃ8ǾƒÚkl[ºJ€O׉ªÑ²ía}¥m…0¦‚eQ!T÷®’0̱yÏ™oÛå×ê“nÅœ¢õ؉9õ#fór~H Où+:¼˜^ö?8º?zç¶ ­—Ï‘kàs$î¯qÓ8¢s_&Åê¸Ä½ÑðKeììí¢õåç€Ü§N¤uˆV7âCm"Ú Æƒá\§ß00**fYUí«Ð†®&ùÁ!>þÃÃìý?ÿóì»ÿîÛhÂpQ¼&Òù`†Á‰ÒßßÚÎ6ZÍìÍ7^Í®a6ß!ÏþBåwki!¯,#Ì)×ë §Ø84!  Ü Òä pä`h!²À¶,—kÖ´Ùvv±Ô6›ÌæÖÏÞˆ+`œ}òî%&õ|öüoÞŽ A2"FæaBrüÇ0Ý9ÑŒHLôŸ?Û֤?ˆúªÌaíØª·x4ϺætÀµ ˆÊÑÃ,K¯Šµ‘f2m-Ö˜on ±"Xh.6nÀt¶'¡+šïî6  ¸·ÌÛ GÓß|n> ÿk=±ŸÓËég"~4ˆ–ÌÓ5ηlƒE—X5œnÛã˜g7ï4"¸ñí¿²øÎW$‚mí  ïѾqŒÅ~ÌD'‡Íƒ‹·ó~+”pᘸ.îû[Ðûñ0YÔŠÙæÄˆ#Yž§Y^°´À¦ž8w“ÔÅjeBC úO°\XÒØF8‡ŽÙ¿E¡$­#Û~Æ{Á~kÕšò±vÿ«(3Ýã½áEÜ!ã¢ÂœZw ÆT˜ñÎØj üIÐ`°mSò‡0DØLƒdå0'‚¹ç0r]BœÊZ.‡±0“ïéqyQlÆ0Ø“ˆ•úíÎðû³;Úó’¸XA?é>þMAÆ£àÃÿxV*ô6èJú+2z¾ "dôUÍ_+ԢߛÏÊÓÙ š/?Â:uttï“îýInèzù¼)°>o ÿµÿÝï~«„ë}ãèâ|§PïF£]€³…‰œDå @¤(K iu ¿¾Üf¢ =qx™€§ý•K ²+c9ˆ´?Ì©’â/Lƒ‰t‰ð?d ÝÓ¬wv­jä5² "`¼¦¦~~_'˜¯ŸÿÚ­}LÒ›ÙfzëBBÀt½@ÈPð©ùèàƒ¥/ü44S×y„ÁÉà´Øð·ãLûš½;¤ñmÌÃþõk\7Àïn™×îå ã#îÈëÐÈ)°S!`N† 5à ©ÖäÎj¡%ÿ»”±oš‹ýé‚[úÌÕü5“ÇâŠc L?wú;Єåy($¸ÏIœ²èˆ‘¤Í ˜ˆÑÜØëYÔ4wb»²= ?׾å5l[Ü&¢ßA‘ÝkDÜso£ê£¼1`8RÖuÎG¤³ÐÂü,±m‡{Z?!=IçÈÙ`µÜ ¬Zm/¥û増qëÔØÖ¯nLƒÕŠÍ«ø „k ˜ó.8¯! œ„Èéz'ÁYËNZª‚´q7@‘†µr…àË - ÌmàÈþ è"Òþ-Ð1Õb¬'Ј œÚJc·“¾kÉ¿åiq'ûÏÿXl§"hûLÜ\=Ûã'íxXÖsÒ>…l¿ö´ŠîÙWúáÏãbiâÚvléÓ nÇžeû__4žŸ¹þCÜX—ç…zéáó²sBJÃzù…P`-üBÈüëq“N§¹ÑÞšüÖ¢3¸yÿáã¯õÿÂp2Ý£Z_Óœqv³èY.K›kã€Ð¢œ W³AM Vws± >ïJYÍŠèwÖ2âîÓSæFÙÃï@tÿ9~þG̶öÁÌ àÊHÃ4 ºì]ßX«Ù^|.»sÇb4ÍìÙg¶  «f7oïÇ:X»øu HëPÕÒÔÀ`˜Çó0hÙ®D,nÃÚà¢ô–U²XšXÆÖeŽ€Ôpv·î`ˆüßúÍìÍßÿí¬C0àÖÞGìûñïðJ0SÜÐÙ稚W7 À³ÿæ5PÏ JÌ4g6ÁëÇd ÜÓÜs5˜1tS°\µL:ì‚n‰M£Ïúõ²:&íÍm*¢û3ÈKŸhï>æ÷½|vû hü€Ú@¶…1å}²*Ã6ÀgÄ3Xì“´Ð"P+œä¤?bd&¶Á‰ÏXáËFxV”ßùúììx”}÷ÏždÇåAvô$Õ5xR¥@éf­­Jvý9â(˜(€‰•qËÄ+“þ nž€g'øÙTæA Š~Ǩx¸Žý ß.²ÄWl› §õ&”çX"ÆhìC"û=E+÷„Z¿ôÕÜm0ãæn#Šú4ɸþìFª%Þ7ߣû½8&òá/cY9GÈ£èdÖ%µÐX kü÷H!,á“j“Fé³â©ElãÙA?bwЦ«‰î(ìS%}WÂ=Æ6iݽ××GÃyiü Ò@ À‚ã\oö[a,-KQ€û¹8)“C²}K7+(ICOW€(Ѹï‡%‡ÜƒuÄ,ϳïqåM Xäõš¡b)ü°\*}tãú‹ï´ww.k•÷iá -|¶…¿ øé²Ú¶‹ëeIµ°~>3¾ñoïÜÉŠ½ùY£<­mÂ,6ÿ{ok[vÞ÷íÓ7÷Üþµõ^u,R,K–`ŠídàL2· °<“€ @I ÈÈ$IƒxNÖ HÙFB‰¦"‰"%ö¬îõïö÷ôM~¿ÿ:çUQql5,²ªx÷{ûîníÕ|kŸ¯ÿ¾5ØûüÂ[JJÚôÚFkÚ*ó+ q¿y%‘Ý )$-nå1HwB6GõmòÃ÷æ„Ô Ià34”§>ãýÅl]‘Ħ¿!{‡‡ûÑ.Þüû¨–IÇŠ½¿½¿Ë‚75¤é%„o#ÑLé‡Ë­Bh\dl'8ÒÏ•½eJ"M µÒmy˜ô]¬èX”ÂÇ0(.4ÆÖ?sŠ„]á°ƒ_>"ÃíDt6>ç£P‹"ý. 2+lªRú lpêÓü¡fB=cÉE°RP7„å*eÅyY–w-†àQc°—‚Ú>ÚG §Ú‚ÐXÖxv¥_{ñ_Bí’çàS}jôÏd8ªàŒ6$U¥]á¥ÆBïw™¦ æž)º·U" ,£3Þxˆ¯!ªåU‚¬ Ò*25T,ÚŒ#”ŸG¶¶é"­êÝGëkx£À€Ë< P"ñ›ÉPõ´Q2J Ò4ËßiŽ1o… ¯lCÛÖISÐä"(ÚÝVëÝAs8Ç:è9~[©Âòž›S“ʼ°RûºþýßLÏØÒææ„‡:ÍZÆ©ÚnV¡Vþñ@­Î¦›½œù×;l¼PYéº.Û/;õ|Ÿg’6eß-êƒMMžÊ¯‘Û«Ž :Ã7è¼×êŽöÛÛ“ï߬k·ØÕö~BàŠx?¡û3R÷ç?×»U_´ž[¦/ÕúÓÿt:?»õï½ý©“ó‹Ã×n5n}ünê¢-±Â¬ÑÁ½R:Ä^ñ F%™L"Ñèààw9|B–8¤ó7žâ„Åjtß~3žîOȉ4¥¼Ò£¾í]öüˆ¹_½öÙ×"ùï`kuíú]Âù¶ íZ¡ÎŸÖpìÃßà핉h ¤²R«^øÍ-‘‘Àfr¬+B(Eé¶£ZÖìÖT.G—µ„D„5H÷o 8zzнÿ) O½úÄÏ!þMšÕ uP}öÓ·‘ÀfÕó7îÀ(\’ÿª“£§Õë<½"H̪ £`žf…³GÇHæÓjx†s$°kbKnom‡)­)ýq:³ÏJˆzpÛQoÏX;a§úî·í&Ò7ñøg½Ÿ»®š|ûMÚ2O–™5, 9 ƒ$p]ü yl´hGìbÌ<ƒiAÐeÎqPäŸßÕÄØ‚xˆF0žþ3û:K)SörU=YâÏq® 墳†=Úàî YíÝ$Ã"š:‚yƒÛ:°u ú€t ¡¡/ÎL( c–Ѝ´pËq¤K!†–ó¹kH ép57ÆŸÔ¾fó+;᤬hÈß1éŠývX ÉpÊç^ºŽã~Ìj6 ¬ÌÇÚ ”Q;cÙÂQqŽéæÆ+{qpìðhÄ"Jç¬xzââP$Õ9Òɵ‚!,Ú¬SÌ5󆨶u†Bí`Hè'ʪ°U:^:§jÕ˜lꢎrwÔ`ÉpIÀ[>cóu=ý¤Ö+€Ø QTó2‘ÖC×S E¼öëÆ2f'x‰ÿ!ö­Ï#n2yÑt~2bÙ¹ïæ!§ðø=./‰ò¸Üî¶¿wëÆþWxüÎ?üý7^¼:yýõßÓ ã¯½1vßí½GÏ׽ɳ«?@àŠ¸ú þÚX­~£þå/c%?^öçõÅŽä»ãÉé¶CÞø.{ËP·"¢Zå\Ä ‰doe%U–€­5A†˜¢nT*A‚áÍ üSbŧ¨PGOO7BÍï»+œìjHÄM¢Xi¢Ò¯\˜g0°âÚölû‡0Hú[ÄÝ»Ìí›þ ü ¢ž¢>Ÿ@¨Ô0`é‚ÉEµ ír 6,yûÅ&JÿàŠ—ˆx©'R¯Oa ŒáŸaŠ˜ páû)T}\bÙ!X„í-Aìf4m° ËttYôÆgQgÒÜÒÞbãx'ÆF0¥Î0 ãìTIK U{,ï‹”eWì;í3âž@Ë}F©g7;(?eh–÷h$ XU~@ày×>¥6éž]L]E±@þ§¬öze—Ç‘Íú×÷âìJ¾z˜< GŸer]ú·ƒ$Ýn³ò!Œ”‹ìçÞ€€ªp¬Öc[¶ „›ÐPo–®åXz[îmnSp](5”¦ƪ4ÌîØ51iû—Ðæ7Aýç@æ\º¢í¿c.w¤sR˜"y£(‡ðÒ¿,W¼Öˆ4ã»Á»Ì÷fl4”èÒʹ¾R¿%œŒz“00T¥ï¥ïj9w$ÐÚܲ*9¿Ù,ÊPm†î«“;Ö”áãE>Ÿw·Ôáw%8ýgÓÀ>/øîz÷¾õQ>¯Ø ›uqú¬/¹YàЄïör«ßÁnW»x<~köúëÿFÄÓÔÕñ/+à/§«R_øÂ¿ó;'·‘õîöûË_€œ|æÍ7îÝùÊ¿ýæ/]\îß´•œçËH'/U×H¯ªU§„‚‰4”þÅ2MÔò œó”fµu‹œÆç¤"ÁÌüù$Q‘ N±+÷±µ.÷©_ø‹´ìãNþú›‡Ò^uçù›ÔAî~¥¨ñŠLH¬ãú¶g¤k¨Ú¤Ž4чLç¨Óß IS'#jŒZV²å?ñ™±Ýz<Ûñ8l… _I­jø V…;=Âãûí‡Õ½·~ˆ„wrE’FBOUŸ| "†ä»…ä¡\g_u«Ï6?Êû¹êÉý‰d¸¤žG÷·YuFÜù©TÂi¨ž‹’¤GÏ{%p}º2?¬O ó_Òä‚àçczEwëK4œ8=éeÚj€1÷£K´Jó=æ„üŒxèCŒQËë¸M§ o|”TÚKD¤ Ô¥téT¶ÌG qb¬/ÓÑbAÀÙi]ÉXÉ–Pî[oG‚éÕ[Œ‡0ÀÓ0Wo|ïéuŸÆÇáé½Ë„Ëf¶$jÁUû\1ÐŒvM>·L›cÍ5U½ÓD¶˜C6ýåX×´áÜ1CWßf7çÀz¬‡h.‰Ò0ÂÃ'—©—€¹kTû·DuÈXj»`^ø^F†ŠRáxÁw•rNJçÀ“}#u?Ï oÜfÑ¥-œY3ŸÞãûc~õ ¤ VR,áuè_'pwÅ?‰4³™g¨d¦ù_4¼Xö¾ïÐýfŒ³±V„é¦Ì›c÷œÿŠï2>sÊšeÑ/ÙïÅ]íƒéŒe /‹Œ&?òX^æuÎ Ý”÷Ô¤àÑ…‡ìÈrmoñ{ñ7B;ËÉ =Áj5¦ßßaòàüÿ\{þküª.û;ßùqGè&XèTFì—{µ­!pÅ\} -\¿þÚÅìVUêfo±:Ùó8?Ýzòäôðìì²{I²ò%„ü‚…T´]ëüä=q€øGâáo³ÃWs §4jbÌ"Ãó'§Þ=:cA–° È$mƽÞþ5Ž5lúûHú׫[·¯Ww^¸…TæB3{!\]¤J‰ÕÂE€DZ  í.`æÍb '4O{HYIÈ‚ŸxÏ{ÅÙ@‚üÏ&1—”Þ!*¥*õ£©@š×ÉÏ €PSÞƒÈß`<9C£MÖBrH\·º}ºæ‰íj‹Øì ocäk¬ǘcÂl´A$Kú#Mô£f%ÀÅ:tØnzê‡ Ø%{Å3û½‚y0嫈ØÄ5"åÍêyJ»QƒS±[[†¢'êŒbAœÎ¾Á¨©Ü6¸§:Þ©L8Ëm^àe%Gû#áã>1TÇ%N‡fp¼v‡¹‚QÙ'‘‘ ÞÔ7ç[ãèh«ß5ªºM´d´'!¤ø³¾yž¹²,çV†å"[Ï$ô¿xý75jidØ]ÈÝ%}s›˜}}\ÀIÿÍ#êÅÕpñ´¾²ŠÄý6Ê÷M‘âu4ålj± 3“È2Éd ;™/Ûu›úÝrÓÐsÕbNÃÐpOGHHä)MKvms °’°ó/Ì‚Xv³¯ßñ;·×¾ï{L}ˆ¹Ä!SÉ Æì«)Éwì7¿†Â:½·™ã|Tè?™ŠÒ XTmP+–¯ª×θKþÇÚñÍ;/5WÝÉ?þooõúë4zµýÄ pÅüÄ@ýÑhè·õ{é²w—ÐÝÝËñÅ+ ÉOMÇ£×P{ìÞ“ËÝËá¢9ß‹-Ârúð¯êüæAþöASV–óZñHÔPǬŽÔ®tJ¢ž;ÍR©I‰K±.ê¼öo vØ6É{öpX쎈~8$qêo‚€eX.Wü ¿‚-¢ÆD|ÿ€)€uèßÂÏ€œm’úd‘ž`V¨lº-ÖQškÔ`F?„רsCþNˆ@bN˜œ+ù¢ŠßG“pìwijwö¨ ˜H †ªÉÈD0wJÑj=”2ëÔ)¡ÄÀ‡kÒ#7—†_rsĹ o¼çî#º:¹Ó^_»ƒ©†Hˆ“Sö#©å€ƒé¹@³"±vIÞvtÔ±­3DfQ&‰v“tÈ ¶4ÂlÚù <6QwÛ÷,+ìôÓ‰9Ò¾&34Nhóä”þXÒWÕ?SFhûšQh¨¶ùfYÏ`Š3ߊ„FêFulÿôa ò]sí‚ß ObN .™ïkbêõ™c˜>kÔ`þ4q°ÒÊ}êó§”–ònѲ¬ù½éGN¹sª?„ðÒœEp+uÄB‰¼K& §:&"¯Á<ÇþŸêxF•úÉl¶ÍÜ’h:s>:~‡š•ð·Àv2¨Žq~ýS"ýÄR?˜ÍÛgC2$Ñw+ÛTúã9vôr(WÛ@àŠøp\]ü‡ pûTèpù|s¾º4ÿI–4ýôñÙå'†Ãñ G§ã¶ÍƤM>%ø‰øü ÄÇÿE”0 -¶úQî+9FÔH‘‘Ÿ›åxwYŒg›Ô|/~üÂ×Õ§Éׯ}ÿúó×ðW©â̴ž?œálÇ{5$îØ‡‘öM0´ÄÉ/Ä5íÉ!$qú%j¥œËOb± CL,+"Vè1AŽu³ö]tq»À7áÑ;÷«ÇŸÂÀœ‹ÃI+Œ9âFÂÆx[˜#èÛDêÃÉ9Ä,Úƒ¨HlÛ¬K€t÷në7@ØØEâ`" ¢ƒêˆ„G³)9ó1‹¼ùõ·P¿²Òá2é /ñ)èB¼‰4@7Þîa@a›¸9Ì­ôÆŒÀ‰}ŽH<œ_DÝ­”­t×%£àõ—ð•`bAE­9‰Óc× Œ±Æ-0ÄA"«ìÏü1žuÔøÚ—k„V4…cU Ö6­d´Â¾C|¬/†ä†ÐÇÛ|×›˜P:Õý·p,„?ÅÿCMÅ¥ €ÃnQ‹Ëh,“‘V€½$Q¡<Ž›tF"‚4ç¦`Þô@Ÿçä[ y2ìo…ó£&•!ÎyCœ'&ÕãÇ|£ö›9W ¾µcF^–±ªjæjÀIÔ”Fšf ÊÚWŽN7Ç¢™á‚pâïà ›tÊz]WAb>ÃÜÒ„9™yQã›ÔÕcÓÏâ¯éGB»ä“•ФQ~6´ÇýÍfû¥6Ã;Î ]Ñ‘6„/°Á\µ€„Ÿ¯ÏVØ©ýò·ÛÖáÜx^×|Ņߌë=Ø—ò4jãìN0û{º’_P®×7å³äMxŸOèÞ£n·ÿ练­ïƒ Þúµÿþ·a}ªê¿zÝ¿óñ2‚w7ñÉšúÿÈýwKüìž]1?»sÿWù—¾ô%˜ö{Û§ÓãÓáè.akÏ]Mnƒ wÁJ„ë÷û7oÕ:¤Ñ.K¤âgR‰”HH¿pQˆ|HB„(6óשŠ[dÖ9mî;»ûÄY?Gžû=bÂï@ð‰¿ÆæßA|j‘ÏP¾«ž˜Ÿß}®„u­éÁÆ™«˜0ˆ;¹eD\!ÑÙ‚3D~vÈÿöÒcù§éBD§6ú(Ù7U®eǨú}|vzñ8ÅÃ[¿ÚF-¯vbíD—Ժʪ"£šQÐ ׉±×Vk¶? —ÿ*¤CUðÔÄ-$jÕüjvöºÕK/Þ­N¶NaŒ,2tCUÆyˆ<ƒXwHÅKþ¥ªÂB7ÑzØþ B¬d;ƒ0ŒÐ,¸Ðí™`¨Ï‚?{‡}¼ùù‡`¹ >evD¤Âò"ÜèAç9ãË=‰çlΩï7;×eßã•KrÔɺØkôè3önÒïà( :~l fñ Tf‘–“3‚y F«±›”§=ëö¤Ç5ˆ—7VŠò!†Üã¥òÀ‡Í1 þçhd.±ý‰Ð ÒDê÷»•Ñ4\ÑÕeŒè̘D×–%’~öË÷ÂÑqd KrÛ>k*0ÔÒjò­Ã€Éˆ5¹'# æGßßa”w8f@¹é-vG¯¦//ù•Fšçw„¯bÊê[à¹|¯ßžkøKp^gž¸°JûhG¥~¿ÿ0ÂÜçÊæÛV¨Ô-£B;|EÊùü ÃûÄ·yÜÙÚ>Á<ÆÀOÔû¹ÙåhÞÏF>Œu_1ÆYûiôyïd05^›7Ú7ÎGþ>RÛK÷]ܹÿòÅk‡×;»ûûíkÝ}¤Ð—Bõà{8Å]V—¬ÄwŽjÜL~-T×bü QVŠA˜üɈ`tœ€'HÄÒ¦ü«ë3Õç>ÿ‹H`ÛÕ‹Ÿû8Ò~ áZ Ñ:vuÝËôä'³žRý²©­d ò؀пñÌ©™žÕÄ*’3 p R—ŒÔ40sŒ–’I× á¤£'TŽöe4i>zx”ØüïïíêÛßyÛ6 b·ѸA’˜ç^>$Uo‡²Å/bJJã`<ë5áCæIƒüÁ ¦Šm!m’AT½¬r(£aŒåXLçÿðTÇN«?ùWZ=º÷˜eŽŸ‘è€ó&Z<éqÆW/¡n¡}€0ÚA jeÉ8ñþ8ç£íýVuýΠzᓇh0=œöÆtaV°+)3ÐP[‚Ü–”ˆ–´ŒÒV!Læ°]HPÊ8Þr]à.d‰ôºòàx³š!r:4în·«—_<¨²®Á£·ˆŽ 'À%á‰Ó±R>êòŒp»p gæˆÏJÛ8¤:õ¤Aë¦_Kò÷ç3sý%Þ<†°ÂPèW cêñ KCÃDÝ#Ñ~ CˆÿZUþ‡{8ìAøo```Á˜ÂÑŘâÌêw$µËŒ–£>.2†† ái"I,úœ$¬S˜ f¹ÚÂüåzÛDHd/w`ÐL\¢™Ñ5 DOæ™Ì„ÊÛóŸÎ¤¦.c¦=6™†tIø³Kì;|S2m†0f1 Ç'èO1å€af”r•ü/è#Ý%™Uª¦½Ò¶ôá«úŠøðÍÙO´Ç_þòÏï4·;ãêþÝÉêìçÏ'—·ß¼÷ð“£ñäöªÖïmßÜm\{þVuûîó 0RÕ.·@¸õêÖÇ_ ÒÕ–?Gâ5ãÝ ð”ÜÎA* q~’¢Œ.ؼ&q•»‡¢Š=¯¾ù­?C V}ÔÜ ÀzåOðT“¨éÑï–\â7—ˆ3LQ:A]¥Ìúg/ZÓîÜ÷×üQ€trMo¸ç'²„O„HÕ–ÛY'jvO¹·I´òøáyõôñ9¡{çHæØ³Q§ß~yåy{ØŒ•ì5‡¸€}Ť,½Éüfˆ>Ãpí Î&:B”ñ]ÐÝ}Š$;a_YÛ÷nüoî@¬ÆHþ'h –QS›âWK½¦ ’™…õl¡YMK â7Aho¿¸]m`RA’žáü†dŒµ"«äÓ…)£§*bH´ð˜ÀBI·©³ÀZÀˆk%j]<ŠÝ>` ±¦ÞÎÚ½3/r)l,w<Æœ#ÁÝ»IΆU¯ºõü6&•Iuôd”=¥æa–Ef”ú~@ô%ÂÑšð¡ÈHÁjkõ:ʼšmO¢®9*8°4ÅïˆãøÑÄ0„q“))I¤ãŠTkþ 'øb ‚ÙòóÊø¨{†"„šc¤tîÉD;#c9™§Ù¨ƒxî™s¿]çÝ~j~Å[øôa¯þ42jC ÃSÊתáœhªXƒ•iæÀxã.I=k-ZF•M¨ap>$ðt%í;ÿ ûþn.µ?ϽEqà l8‚Òg B"æ Ê)?0‘TÏX«cj~@Ï÷ö®ïþÉö w¿QŸ=üúß:¿wï¶y¿7?ßD;ï÷8~ìõ_1?v~´*¼¬fÝúp´G¨Óát¾¸=_,n!1í±Ú½Z³3èպع{¬šVÂÞГ¢¨Q€ˆÖˆÓзmVÚ!ÌXO,Ë)ˆU9jÝ-0Ëpx‘4½Ç'Ç՛ߩ&F y$æ/×Ì(Ý™…ƒ¹‹…DQ…Ù˜8[¤(Á /¥Òn¥\UX&þTÓ;ò_Õ·ý þ }/¼–¼ù²u*ýŸ“ïÝØñ á=Þé'Ög8Î-gDƒÒ¥ýDÑ,Ç~k^‹ƒ”¢Mv˜A@“Þ7yp•LµSãOÑé3vÕû¦ÊÅÉ”´¬ A71 Pwý×@Lô-Ò³ã¢>‰u´Q†b#õ›ß^5µ‰‹Ô"„:P&„Ÿù ±¡õµ,TÜl'G:.1NB%Ï×wóL {C°1yjzç=o‰š„³£öM‹mïjÁ ÅŒÑ÷=Çd=:Ö`:Lœ£¯Á5©§ ñ@½ô-p ¬æ†1¿0Þ7eIeVGŒùÙ¿é³Z§ˆ?üw‹8Êô9Fa(`ßÊsŠ¢e°­Œç%Z‚û¥HÊÔ##wõZ±P1› ÆÀAÍL>kÆä¸düÓd¼Å·EL ùßO-e8RTÅA˜1N P&ެÜ/z ÆÃ¹»Ÿ©ÌY˜hÊ9GþKE©‡º¸Œ&£Ñ¹öÜrôŸ[¦šÓð^ŸàÊó3²·µûèÎíÃ'µîÙð×ý·×†…¼ö¾ýaLBåjûw@àŠøwåêÖ»8¹üá-òÈ£«›½4ªM_ôzÝí9iûºÛƒúÖÞ.›$8xÝÇMdá"6‘ %* +~ýJ+áDfÉé Âé`§îƒ”°;8ö5.qN#Eî’íù9Nu—$‚®™¾WùRÄ#ÂðWR¬»“¿qˆG0÷ņªÍ£‹…Ȋă! žñQŽ]ú[T¾\ƒ`m£„xiYò„cÅ…Mû£‘8Œ 覎½8#Ò Q¸¯íøÚÍíhŒ@˜LðT€¸™ÈÇÌqJëj’­ ³ˆNt€DŽ`ä/û!ïHØ øÚ^ÇD: '—ÕÑ'äH@¹‚³¡dB$Ýq³Þfñ½¢ó#L*À`Œ æ‚Èêñ¾ˆT}qIˆ¤`r|À!&$a;ÐÃA,¯ ;Ú˜™µ5­á/ùž¤ ›~34©Âz+ψqÇñÔÞÙHŒÉPÈ ö˨ mùð1KÜÄöÞï·ð#)¹$”`ÕtÈШå@+Á·áæÂEK;¨ z­X«Ž×ÙQ8\²Ž‚*þ1Ž~S™´0µ‡ó† ¦mîÌ0Ëߔ膡k/HGt ¡oqxôsbx!tÞó3~‰xòšå½.J$`I9¿cñ ¨™)-¯V#LÀ†Ö£¦Ã÷©Db-“ô.ÑNñò=ó 8úJ=vƒwü~Bø­&ß÷ú›¶1ûÀ}7§Ñ!âRC[Àù­­Ëø;ŽíûKö¯ð 1¯3»h|Ÿ{ø-¼ZÀd¾³Õm}ÕÿwkËÉ=²w’ôz­ÆKËW~Z—]mWøÿ…Àx>ºÃ/ûG«éÇFÍùçfËÅv£×&J»Öß'¿þõýöKbÛ!—`‰1)ÙõuãÐÝ$5©¶ KÖ1w­€¡€-¼¿·0˜0¥³Åêq„Ç]¢ 8A°svF;„¸§ÒYŠdò㞈Ng*PWþ‰ŽD`"!ÕµPxÞ B²¦¤È\ulè¬ìs˜Ü”:,¿@…oøŸm¹n ´Õþ‚ŒÃêä˜\úOUÆ]ìò7ŸÛC­ÎÃ4d¬½DÆEpôaÀµ!jÛ:ö]+7ç»m)]•#m‚dÊ|>ŒjøGýÅF³3Ì#g¬ž÷Õ8ÑÛØÌ,xt}@®„]ˆC¿º¶{7ük è{P#MÐ5“©ú~tÿ²zûd¹cÜ‚IXH¤f¨Á]ã¾VÇÎÀ÷p´€”Si¬`¹»À8dt>c°¾é|„"yà-໥¸ðõµx¼ÛŒÀ¨ A~îîNu±3­½Múg$v}tP4$ok2„Fˆ”Ì1„‡g Å`ÆÆe=Ãj>.yWÁ)̃æý4dœCø2†Jˆæš0¬Ì©QªîeꌓW»37"ÃõàÎ$¨ö?C[W¶ë¸r.‰ÝPÚwè5ÁÎáéÚ¤æáLµíJ¬íˆSf‘èí°·yæ½h0¼ŽÖo¹õ.ã3uØ·0rÂÁçüáv²×Õt°\Mð…yëàp뛽ný§ÓÑ›ÿóÿòUcu¯¶®€À$|кàê~/OþjÙ½ËÙèï"j|äÆbÁª1P°þjYmck«šk7ô+‚xKü7¯‘o¿.•{&ÆBøA¢ÇSR~ƒ$ôÄa˜ù£¡€u† ¨Ñ|ˆ:vˆCÄ¿%"‰~6|t ¢£=°‘È” Ô,@]"!oСnËbh¥ª÷0zúÇ±Ž²ÚÞu ‰‰ô|_i×ã’°4[QZqêtg]K0f[Àý‡÷."ù?xçˆØ%í¡y-¤ðNµU‰Ë'1DÄ~—ziöÔ•Ð-ëé–íeÕ>ËH™è« ©Ý0NÞ„HfÀ›^^²\­ –ÐËà€¸BU.X8øüQcõxç3à† Ñû…ecñ*9í¬LG v³Þa tׂ_ )Α"Ê€X’pìç5u©+ªHÙ ÔzO‚–5âÅdKmüü°Í¢>&Ln4!•.û ÑsFhÄBp òsâD<ÄähÈ$2Îôñ2·m™ q“OŒ*•˜®±”ñØj‚þDÒ– â²g^l¶ŠóÅŠ¼K³$¢ÑCê B]VœTO!üÈÍôø{ºR)¾8ÔíîáA\ýGƹ̃\Š"‡’ •KÅ$‘*DL›êÁJã¬\–¨ºe@À¹EHžY÷¦Ô9½aÆ@¢_Bà­GǂǢ³hŒ…mƒ„>&Z±6‚„ÎT´JúiŒ¹^íŽß<Täë¸ÌmÂ¥öUÊE¡0KÒÀ5rò²<ÛxÇÍÎäeß/§uaè)Ëú:¥~JÒ¾.ô: xÕ¤L™‡ýÔ©‘õâ«h7:|sN‡ökHÓwÈ“¿`^–0IÄ’7‰‘^þ°‰| äÙ—iùMC‰¡›ÌeoÇhƒ&9'd~š y«³:¡å¦h~èœ4LŸ;ôßÈ€xù;6Gõ F‰ÝïŠ]À Ìbù¬˜×xö¯´ï¯Ãä>ëîX²¼Ã3áäç¸Myæóü¼ “oúÎ}*V¬ë½!¯æ\h:fûµÏ‰i[ÍL–<æ(!Ï\ÐN6ê+æ^óUvzWþrp˜î:*òî’h "Q·[ßÁ‰ñÞîÞî·>öÚ/ÿàÆí;ç“æÍ«öÝT{õç§+à§?˜|á ÿ¨qÙÿ¯OÇíóúÑ]Ôw/€(Á!}¤õŽÚK‘HSÕ=Èx…gó •6¶ÒÄ`† Ê衟¤ñù0[+æÏW4“ļC冶¢Ò§ßö#ó@Ç7Ì’cÛÀ/çrcÒq,ŽÑïËòâÌñ3Þ<“!àzSÖ{>rT^ç™7¼.ÊÁ>yÇ2Vž ŽT˜úù³içY9;N˧^ßc³œ?ë˜zƒçôyí_i‘¼ã»2zãpø¯Vµû¸ºœ7Í7{ö;n÷ñË¿s¾wçÚø_ü‹×löjû€@àŠø€LÄ¡ª×z«éßÃiöð´6ûe–ø½;Ÿ7¯‹<@)ÛòÛF ]µPs7ÈYo¸›«Ç‰uU]óÂys`ú+(Uª‚1£ªÓû ´ ᨸF[¤Æ|îYüÔ¨|o²•!ó¥_$ˆ¨pêä?e±fs*ñƒ) µŸ‚‰Äd¯ÅLš¼§g’¶ð fôˆD¶~G˨I…x‡=ëY3Ñ0ÕësÄ&,çú˜•êî½y†Mš>’”æàzÕ§µ^ë¨écwF= | SSòBœ¢ûŒ¥H‚釔þ¨pC¢Ö@L˪~2,5$sW¿Ór±V§OI5¬–¢érÈS˜’ä@´ZHøúUÌæäWa.’m޳'ÇFT,«ç þ»2¤Rîáo1Ķ}y‘”CqwY™QGÁsüÔ†ÔÑÒØªQªä­o eŠÃZ[ ‘»G –¹Ã¤ÆLDMª"3è©6ÿl ÕÉwUA!¿ê6ÙÎ…ë&ÐîîN»ÚA£²„12mïØ>¸O¶Iæá˜¾¡`F=M%~{+’a*Iò'™!þuIìÂIrð·ñ+1‚b›ôËj¶ÑèÀª½ð”ÕY)ñì)s‚£àùS|Xãb›~¸2¤}WCå÷ç¸Â|2O,K9;g\ø½Iü ” :ÞðSÄ”Ãw”Ï^æ˜{|X×BÎÇ‚Ü-uç'fÕÌMØÌzOÞ÷8æ¾0§Ç›öÖmÛ¾¿3á‡yG?ŽBü×Gî·Süß¼G}SûÆ1¦*άG^‡¿åÅxŽ^©:ßéwþ¯N«öôæÍÃý±O<¯×ì|ïÁgû“O,_ý×דÎËWÛOW ÀO} ~úÔ¾öµßj~ãͧ³óãk8À]Ïç„þ-0CvÐéã]Ÿ•?~öè«!Š60z°„„ÿ™¤Ò9ê¤Jç\¤Á;¾.³`U¼–Í{Ù-å[>OÉ<ñë_Mü)…NKŽ-kœ½}“`«ö ᦜeƒ #¢ˆ½ÇsM>Št¾nŠgÜâqéCTö–—0òNBº(© â¤Çº’³öóÄsS}!B$þ& ^dw¼ÀÌ«ƒY0}¹]»ÕÓï´º%œ‰±ÇñÂT¶Q'ê†>íäK˜>×rJÞª~ëØÁ‹€Ê‘„+°·‘¶9ƒhÆQ.Ùþ ùºðPD8#ÌHÚæp|%iN:Àî™+á­ðÇÝû€Ç·Ü*E…»;eä­|/ïrôSñ2s±&˜ž‡€QG¾‹<§Hààx¸Ïød]Xç@™¤¦ ¨±ßúv àä»<Ó‹ßeR$Ä-ÓîÂĶñq €ù Íî Œ-Ž–i»2Ñ(I8d‡¯síôÉüÍ]¥Ï6ý6ÜÒy¶Þ_å±÷,ò.1Ô¼½Ù­ƒm­lÉg#ßÀ‚fWßã•ì©ÃûœxîîW´;c/õçÁ¦ÊäÚcç°.çlúŽÏeÂÒöúwê¹U¸…™ód]ÖÏÉŸ»þ…†ûw›Ç„q>ÞÚÞ:~éSŸ<·fã_ýÕßæCúm»µ}€ pÅ|€&ã§Õ•/~ñíö÷·ÏŽ|ë­¯¿†‡óõåÖà!k×Y¨¦ÕÝ"~©kÙ»j_­ö“Ö:k&÷“+݃<;šè$ÈBÛ¯Ž~Ú] U''æfMr‘‹¼„÷U]ϵcK% ÑX7LDµ6Õ±";åeMzCCiW ØLDöñ`·:ˆZÌu³[¢³–êsD(C``1¯­]½,G5 :°•”€fÕ)ÄÒd4£KÂû°Á+1µ‘¼õÄß?ÀVMúÞÏ-²!"Q·8C|lEOû XaÀ¾@M­´±êLiÿQ? Ÿ«6X\§µDb_íTg£ÓêÞ¡u ›"cŒšVv®»8ÏÑsäú@Ôy«GªDz3îý’ô²5"3^øøË¨ÓÏ«ï~óû¬.HØåÓqõøí³Ò7*èÓ|ê*‚Œß<ýŒC8hmúç¦×¹m:&w‰±ŒSÔÜL/enbð¯…3Møžãu«é'ÁÀ„¯)_âk–=¦à¥Ú‹Ñ§¤pÓÛŽðµ0…ï)«÷p‰ã¨öt)u1·ð]™, Ì.k èð78(ß¡ðR%³Ö%ã ckõ1·0–]$Z̷в´ªÇïŒ4(cÒoðŸ€éÓÔRÌ-ÔÏ·â·+_äxœB‰yé¯7¸ï3‡·aèœ[Çê=`áÐ|:þVFù}Xsyæ;2ßî-ÆÖ¢Œßíå»Ëöâ}Ïoˆï‡ZåÏÝɾI¬Ý<Ú®¼pÚ£zs @úKA“vü³.Ÿ玿êàç°˜L2Ú“A«ñ§0ºOž{þÆ×vvŸ’ÍñþÇæ­³ïo_Øêzt©åêÏW Àd"~šÝ8kÏ›“³‹½Éìrÿøôô:ZÞkFs q«Ûêã+ VTzoÄöø¤®RL©Ý™½¤ÍpËÇ ‰HÅüäU}ê„ænY žˆ©àÉ!…ù›;"Bp‰û»R1øˆ E ¥ª×0ÔôÞÕ3^º/Q‰ôo=Þà胄„q ÁóI $:уZŽj¼Nm¼›.Ùõ¦¼•¼(æ4øÐ¥jõVW¬d¨c˜jä¶¶u˜ =ÎZfà™Šv¹M£švÃi=°Ðù*^òÚòO =룗`:ÁùÑxð‹3ÖX`¹ä¨è…9p•Ð)%×B¸ŸI‹x˶me)•fŒÊ) ŒÔcï`y’·+Ò®ÚŒ 2šå­GÈ&/MÇP ÀÍ;NŽ›¯Fú.qÞ¹åœÂþüw¨Ù(›Íóz¾¹Žï·—0/…PBÔ€o³ÍòÉh$x}Ç%s£ùÀÌx·Y›øeè@ÙE¢Ï‚GøȈš; ‰$¯@C³ T²î5°ìà°M¤‹Ò~˜ÚŸ“àIëÐæIf¶Áò͆o†hòŽ2û^¶r)øÊ&,dØ2ôu±oæÑæPÞv‰)þ?…¸¿3Aî×eSÑNÑŽ¢¸çj†ÂxS úN> Ž%íæ{\·ï¸ÊT +·¥{T™­<çžcâe˜<›SõÙïÖîÃ<Þ¿~óá+{ùxМé'”ì§ôîêï_W À_bÁòoÝû‹µ_>ž\{ôøè0Åþ‰÷[`ÒX¤ÙÆ“œœþùþuþŠpD(nª¶ƒ/@ ªåA ŸB|¤±õŸD\o'É@aÄ ¼,Š|-ÃâÈA.!|0mç"h½¸ƒ5:‚lËNHà]’VdªbRó Á“H&Õ.ϵÍ£%GÊ$0 ²o–÷,I_(³X;òÙ~1ib˜?.!P­®ƒ™«îéM®¤¯dªDfo„‹DPûº„Ì~šèÆ8tûHÓÑP® “c‘Ž9:Ƭ„Iµ¬«@Ô|vÌrÀ0?~<”èI¸%r+˜×rNdJ¤+4 mNŸ]¤iÁ ƒ7n_#´®[ýL ¥ñ˜Tß9Kþk:È;¦7û“>Uµ ÀñFéþÎnÿÛLÉQ«»zÔèοþ–\èÕö†À𞜟Tׯ“ãþ|ZÿäéÙù£““W¨vÚ×Ǿ†Q°Hïª&öâºÉa+Øùý?#±oC-LO»Ä]üav?ÿÚ8Uµ ûU&nŸ—yìÛR,³˜ÔËúðU¿L˜‚C)ã³Ûà`ÔÞÚ/7˜U›xKDLݪ¶‡xý»âŸª|™’€„ñ›¾¶%Q‚…ÆiLí0eP¬UF`¢=^´ê}ʧî8šHïú3ˆ«i Œ¾Ò¶œ@‹û}¥YeÈáÅEÑÈXI0]N¶“âÊlæW P€÷trCº¥o ž§:˜sˆfc»º}ç&qÿ,´„3 „ï‚…Œî¿¹D3ЭnÞXAþEsA7"a oeÇmØM*±>uX©]º <#Çëw~Ì—aœ”FSdʦ •y®ÆÄÅŒš^bï¸|Wm€¡{2Aj¢:oÃ1Ms|x£05&š¨áÑ:é¹4±ãžÑæîò’ÈÚñ…¦ÚŽÒ…,e(èvúýx¤ô×ûQl¨p¹åçðmÀÂʽ çu=Öás™¥~¥t»b>ƒ)õ»º#Ÿc,\–M**ásä-Mxà³Ò¢Ç²eÊŸõ|”öäñ,ï÷i'eH< oûMû§¬µ÷&‰ªÞyáå;ßÜé¶OžÜ{çá?ùÍßwýé«í+à>Aïc÷j¿ñ…ÿr«=Ÿl‘Ëþ×7ëƒúµíýC†ëí^—DÿÚM±ùCØ"õ‹ØÅûÁ#e€õLH’Aïù\Œ%…s×9 ì§ËÿX‘%- våB½.‚EO¹TðCcUµ^× Uè 1Úá})S¤)BŒ 8uR?}•øËl°–H=)iËhÉ¡­‘£ §”.í¦"ŒŠULQKüäp»ŠÙ¶wê üT”÷å ‘ðÄÀ*%ö£NÛ<:YBa%4/ƒSµTÛ€{Îz<àÍbg|·Ö×Áˈh3Nòž¼Ÿ¥3Â+M¯aWSŸMb M®uŸE„(>b ÚnBbu‡y¡ ˆ‹Ñu†!.ÕlPö]=ü¶^¾ä,û€¾ú ¤˜Å­Àrnëãº$7ì+°à~bÓ¡ ™„…Þ(½è•ÆG䨼¹–ô[u¦$x³ÈË & 0ô Ÿö7ÐÄ¥=®ý £QѦÏ82dú ØF_Ò4B®Îgû|–!þÖâpâ?ÂÑëð/T÷™w¯×÷lÕg\–ïËkoxÜìyXæÍ¶¿Ïy=ýò¶ ¤Zo)³./ŒüÏ4åô Æ1™#Ÿv:Í'ü¾Ÿ6kõ³ù­®U^m\1‚Iz?ºøk¿õkÍÞ´öòrÕùL³¿x‰”2ÿ )~/|úå]K³µ}€„Ô©Ú,ÃÛdùY©‹HFì C‘öUª”2âB¸b¿JBŠsÁQ€:8ž‰›„²YÔ•¾)‰\ÔÑ“ËŽŠ¶xRìYínHÚÛyüïgF€ÕðDTâr%âyÊ!M¯H/ý ²,¢Cû8ê­t ö.Gsú‹ÅhåG®eBìyÀè2ÖÕ¢¡zm†¾Óø£!YèXæD8ì’‡_53HÆ@•?íˆ}!:*ª °-ÛÜl¶® Á{:I WÓËÚxN‹ÜÇü±h… /Ϊq¯W]Wî±~=%*:õÈ•/¡ë"¹ªØj ‘Øôîð›*t,™GÂ꫽ êïEuû…`É’mO«‡oáÕÅÊ|/Oéqñ-pKžŽ+æ«åa:˜5 dæ#Œ…»4ÄÅ›²9&ªŠÆ‚.:Ì0å4EœZß1 ¢ÄÔHŠ!¹´ïOÐ\Hìô»p©ã!ŒÊ½·`05p Fúbƒ[Ïw«»/êkzä,éë€éÀŒ:Ô9?šžèçÚKhSï(½ü®I‡z½yµ #Á¶,gw)‹s'Úd[5.‚Z-Àr“Ê™÷¤Ë=~:è…ò >Út…EǼc¨.×N½ÚÇíïÊM-×ÑRAÔí®¾ yŸïMr•©ñ=Žð}ð“ƒ'Ì‹Uf0’¿¿Oá½fì—ó ïOBæÄºw®SÌ ï¥œØþºìæ—©am¢Õtã|ç°÷Í_¸öM2ƒ¾=~ó_mŸþ³ßË:®þ|°!pÅ|°ççýè]í _øÖýÉQ÷Éh¸ÃÊr×VÝÕ>i:{8îu/;ø¢¬±4=(¤¾F•@¼Œsß{zé]ﻥ¸eE1`g÷%A;ûM9®½÷îuª qÕºÚ‹ôÉ-Ò¨Ò/å}!*ÑÒ^°·T‹èD¾Ó1(¯©/•£R›÷RGZæ^­#æõFíÍ=Ù’¨"EkFm1fˆâß#± š*" —Ö—òƒízî£9zzí›×gxm™Êפ7³fÄNÃõd2âÀF›ò™Ù+•Uåh$R¶Uº3©j,"Y¯¯M¬$1À0b5ÇK|o.—un£‘pŽÕ¬DŠ•:1Ô”çv±0k´ëX×ó‘6yä0û×oÃ9^×å•}ÂcÛÞ¹ÈçÀ]©ß>eGú× ðDC ¼ÙÔB鯅üłŅ3¤m”ï–v×0Ë‹öAJèØ„L@´EtÞºæ‰^¡×¼£ Þo*~~ ¶«ß†ýg§L’ðæd½ûJ†éÑý³9÷z½­A±¹Ì;þSv=FæuþøL¼áo½OÒO?Eûäæ}ûàæ!×7U®‹å‰å¢]àèsŸÙ¯õ’[3`zXOÚµúQ·Ù<âwpö­½jöÅ/^àó¡Ù®€ÍTýx:ú›ÿò7Û“öÁ+Í‹G7Gçð÷ÎÇOþá~ûpû•½zÁrïOêJXG¨V]ÅμüÝÑE|Ú„´ÕŒš;Ä ã©cOK@"èà¥(!aŸåNS)–]¤_C+ æ5O»Ô× wb#ððǾ¸q¶Óœ ñ˜ã™>1) ˜n†Ý[¬6"®ˆªCH–ÞmÔ]úŒ¨ƒÏfˆ±q¦Ó;ŠÂ:6Àbb0 Ážb6ú/r÷žÉx”–GÄÚ‡è¯ {<ág,üà {#âð¥+[„üݺ¹—@·B‰–AÇ2=÷Ýd^Ü6P‚¬sE¸B(ñ‡à¢ QV+¤S3úŸCYè«ÿMHO«|›èLgiÕHNƒX¾Ä{ÌJŠKTïõ•Ž}õH«¶8Ž  3`…:œwÌ›pzz)±]ýüß}‘þ>_ýþ—¿Q½ýÇQ­ÿùŸW=l篾J0DP{%ðzÍB‡#be ¹&‡ðwlÉ} Å`ìÑüp‚ËœuhWBìã ¤bÆë¸â2ªù¥e}/$ô—ø[Hì/ÎQõs_ Ô´¼ªýÏ0˜~V†Ç´Æƒ=×3hVûϱZ™!×gÍ4^ËøØHl.¾a?ó¢R½¥P½åªx®N·¨.ÐÊœþ7‡0ô­Mzàß‹ø°ö“±¨$ÁÿÁ¼ Çå¹I‰-50úP&A }ï.Ð 4ªë·'Õçÿþauz<­þüë§æÊ*SÐFªT‚ïoãs|˜Þ <ÀËe]‘/̈ã^Ù138«é(C¦GÎðr^ŠFÛºá}P›1!wC-¹>!Ͳ Àˆ´¼j äO%ȉ´à#žÁ à‘9Ò~¶d‰Ö$á”ÿ9Þ3œÂ@£5ú.¡½§7¯mÿæÂ“›w>öõ[Ï?2ùå}Ën^mB\1ÂIû›ty1>k,êíC¸nõ›ÝýΠ×'/|­.–A¸bŸËð²”'ÒÔEÝÚˆ.òh(Õ’, jãøl“èŠnEn>+ÉŸêx¥k±ÌB°šDB57 ›îò† 6Èufãäçı/P¿êyÛ®ÈU)Í*ÅRÔ >‹W^ æóQ Ø“rk”‚´®ßþ¨þݘd¸UúH™SŽNÆ?ÓåN!"—øíªÖ’§/é}ˆš“HÛ-§}á¯{°~$Ÿst_Ã'/rY`1 <ÿã@ `™ noÂ/“Š9Q‚¶šôU·-ÎÍcÀ¿ªû„iR R ¹.™.©‹×˜Þÿ×nvBTÃúêâtλõj Нš½Cœ%uKlC˜¿¥)‹MºÛ²”ϱåœc†Æ1a—̇„ß1Ø_™­„uòí)±k ÐÄQbþ ,Ùe®²ÞÁš¹XÁ€14ÆÅw!{6¯Úð5½ÐG U¥ö7mzd&«”–ûÜɦóa˜·txñ&9íCØu®ljë÷]^0¡Ž‘Që²:?@çÙÏÍÏ/á’ÚËß͘…—ÀñsŽÏúaýëûå­òÌv…Ÿ}v¯6Ì 7˜¼+á§:Z±}I倢º¼ï{-};è¤LGËÊeZ)`*`487d–ômÈ}žåüø¢CÜa_ªkÄËÏ1­ v³vvS3ÇŽÏåˆeìì“çz»ÙVü:$f4Q4vŸ~R¨Œ¥ ¨„òÁìÑŸ¹0§ý¹6wŽYÞfà’e~GØùe’ö™g]ï‘áÙAµOZ_—3>9iḸDcAº^ÆÅ’ÕëO¡Ì-*Ñ WšV3óI3©³6 >öuÀH§@&PxÛõ&¹d¸5[5´ 0¢Â-f!¾7¢SCtuõÈw¶fdÞ»eÊ4$þÎ,è³ÉwdÎ6G.­/¥Ê‰Á ÀJ¸8ø6‹ÂdFòðs'ÂfÔLc‚wÍ1Ò¾©Ïf4ì;ŸÎƒÃB›¾˜$(ƒ„ËËåIJYÛŒ2c´“à+›™&7†¢¤R&ÝñïY›yœ•Àž9fÐBkÀñÇF37îlã{Ózt©Ó¦hŒó€ÃÚmê/l°@¥y!L²§ŸœK•Ü”T­*½´çôœ²‘BAÀ.mX\PM•KzQŽ¯à„΄HÛ.“&“àRî3ۄ凅Ðá5BÛÙæçÚç…éͱï¶cŠôL;ÛíË‘S6».lü.b2 éø[¬¯Œˆ„Ûåw½?Ê`•(%z¿…ž&(&wkI&`{Çe{UK¢uL¼ß—D¯„ Òï )ûã žÒ ®Ù=û7ß`%°«íC+àC?…ÿþ¼óÎèz­=¿M•WÞ¾ÿÝOBn {7Ú½ÁîÁî­úÁöË„˜T&ÇÕ âŠqϳæ¹ò»Îw¤2R}¢öÇéâWcU>¥–y¤0‰Ôˆ`*¬´iÑ-Ãûü²ö’PDç7¨——YéiR6RW [wá$®&G3Þ]]âðvYÍHêcâøÎ^Ì7oí’²5<^Z=˜™€6DÁ-*}[ÖYƒÐé§H]ÂdG´[Ÿ>Se <µ:1U”²Tî„d@GÇgÕcÃÀ$<†Óíìu‘š»!<2 22ŽÇQŠÝ2D‰`¹,é‡Ô€^则•û”1PŠêL]ù_®MÔ“•ÿ´C[·Íë/Ñž’ GiÓ]Æ„ÖYhȉâÞg@$ö„ÁA 6Ùôì£1þ¶¦ «¹j8ÃTfâ3Ÿ;Ìõý·$,pˆ¦Wiq‰`>Æ_€8{¿„â; Æhå9v"ƒ]3pdö7°§ÓJØÎ…ÿŽÿ1N•ÚÓGC4À°‰“Ÿ~¦äÝ»F*i4>;».èS'¥o§ºq‹ÔÔOië‡oL߀D lM!ñcáCŒô6c$¼%߬ü‰¦)5& ôâü…yÀ¯‚ãŠò¹¨Ê Þ™ñ{|4»[ÕŒLØ÷H ¬†„„ŒÑT@¬à|¾Õl€Çáû9÷ΓÛú€lÍÕçÃsŠ(ly7'>’Yð$&™,.7„ÜNÙG5-IpÄ7¬¦Ê2ªùe~.I¤úÃtKü{Ì—• oj9œ Ü+¸ò^mFíSøêËíAë›[½úÃíÁÖ·>öâÝ?…™<9¿ñõƒÆîì÷¿ûúìŸþÓjõË¿’—xïjû0CàŠø0ÏÞ_¢ïÃùEl{m¾_›/g»¨£·{­f§×í6z>R\¿ãNï2&~iâù/FŠT!f’pJ@A3ÁV¢³Bô#mQ&Ä“eDR }§XQóƒb$ÏúË™L/êeª×ªºwʪ)Iý &Ò Q“ kC\'¬= –»<ñ 5ùÚk†ãÍY¬(¢Óö-R•Æò7ýcÆ™BKW!ž²g°” òOéÎØx]Ä1MðLŸáügø_!¶ù²‹±G^ðÈýÀ¿œÏ=ÍVÊù·ÁxyÂ;}2RyW±ÌwÄöláS/}W2ŽZ›z…O˜Ε:[ad¼°&É e€±¶cŸ8‰¢Åì³spTKPômðöVŸu˜§)DO3ŒŸ‚qùƃéi!ý%\r±à˜ í»ƒQ“đˠ2—”/a~Ø÷…'ýwÑ‚”¡—èu  þïû6Ò÷„W† gîˆY‰fΡÀuγ„6ܹ[ÆÆA¶([˜/ÊÖÜá$ß„§¥š<³Ç ‹àÿ¨ç­YÕØï´Éá™ß çÎÍf£†ZO6ç›"ùNßóŒ.—mÝÕg]ö®ÏØS„糊>4š˜òx=öc¿9 òGÃò­1" Ëg:nö€‚¡ÍÚ9i¥Ïpú|Ôm7àíÿhïp÷ oŸßþÚ¿ýÊ3áUõúëþ½Ú> ¸b> ³øïÓÓo½ŒÝ÷Ì&'/#c}Q~gg0èï^«ö¶«Aç š6 rHL €ý½]ÉE¤ïöN3˜fW'ܬNnui†f±Æ22(ÄÙ{Á—ÜÓf æ™gÎA‹¨Q¹BÉ›òV¬¹Ð{ ´@J5$lt1®ÝÌjwçØÞÛÕÍÛû]ˆMÂÐ\œ“ô„°£§Ô]¯ÎX§ƒ/Â`‹T¸ 6ˤÃìô× ¨$86]0³„ÅÒö>ùbÍœH‚="5Ë4Ò2V˜57™›¼Ôa¼ŠB‚sÒSÓ:*`Íøv ƒlò#xÂoDGDÛÂÈèyß‚1!S2sA‹þt¨Óèa`í‹Uùä̃wdˆükþ°©a*3¢T_>ßÀ1Ï©Cç¿»Œò*~cÉÕÀÑü~ZúèÈLeeDæCé’Bfpó€ßØ R5&ÔãííæöÚG×÷w¾r¸·s¯Ýl<œTõwX qñO¾È€¯¶®€Ü”–}á _ÏTÇÃC¢ŸÕÝùjzx€À„í¿S)ýwÛ½,ë:óJ’îj”A••d!Ù ~ûì‘¶”¸$s`+es¹¼tÑŠÈ &ŠÏE‚ä8Ê$ˆxµ;[wɱIÛSL§§gY®V"ÒÛêÑOÚƒðIy6¨éD6Æf´J›Æ¯Oq›Ž´Ï2äi?DI‰Çˆ-R'‘ŽN†öB‚"’6Á ÈZm@è1ýs‹4JýÃóÞé¬Gp9‰¼E&·4.Fñn¤[ ]ƈ䛈‚5¨,çË•Mb$ÃPŽ‘Êóœkk(ÅŸ­&¡}Î ¹û™,kÀMG¸¤X`\Ú)Œ‰37ÀvUkC­têŒú™[/‰ššáâ|ù®Í»I<®õa€VxÜ“ Ÿ6Õ¨ QBvµ<‰–Éz̬ÇÂ0aÒ®õÙ<ýsøjwTÕÈä7d7ÄÏ•õlÍìuj6z0˜:Ùí춪]<ý]ÔG{¿Ñ1øIêj½Þ›YÖW-sIc¨cGÍNZkG3€mø=Ñý2h?Yà¢ß€”2OU‹óLê.T$®Ö“¥š£yöW0G #´I9ÍÖáOÁ1?«Ï¸gM2›þÈØß¶ /Xf³i÷íŸûñ5à!`LEahW¿£2ÊRÿFíoûn2všî6íy;ýqŒüù|Œªð|H•§ƒ^íínýáõýÁ[/ݽû`9™ýÿÃ²«?I\1Ái¡Ôþøÿ÷C¼•;o~íñÍádx8›wÛF£Eæ~¿í|‹',˜‚ÛùwªÓ'çH2ÕÉå“Hê×ÛûY¼§‰ú;AÕ$éŒvïC$â4v®“•¨ ì"‚5–Z¶A?A å©ÓÝÍ×@UÕD§BÊ-ÉEï±Á\°OHWûàͤ^½ FÛ‚¸vý ºyóÒç)tiwZ½õ½±ÅÏIʲÀ9šDØ t¾Í°U+]œâαѪÿ:^¼Ùq,¸®#Áâ‚€C<äLØÒ3ž¸âžñRª ÿ¸úŸH‰7~HÛ†ÊÌľ½AâÂØ±KFí¸y’ÿÂÎUêå†Çr.Œ‚Ö…'·â4§NÆ•ª ûa_%R°`hWô˜csQc!ìã¸i¶ŸÈ‘ÖH[Ry( *‡ˆX¯­Iø›1}ÓË?™)¶µ!îת;w·«ƒQ‡$H8S6ó3@yWåKF< ”i™ÛøˆIØ´í«-AA•ÜÇ0ÂLè\íßÀç¸Þ¸MĪÿ}ýXØGæÍT»ÂݺBÈ05˜qÏóD 8oãp ÂŒ]Û¼pôf`*³ä?BµOÅ_ã‘ò å9·Âq®ÖÂ:ˆOàsO ýÁé2‘b²m"À‚y‚¢Â—>Ú¸íûÜM-SQÙ{·lëG|“åÓœßX2 Ú<Å6¥e„[9Úº —"ƒPºJ»0ÑÊÀ›èÉ´õ‡i£¬G˜—±?ÏN§v+Ϥý·º½Î7;½æãÙ²þ°±Õ:žµêWKú®çè£z¸b>‚3ûÅ/~±~ç¥Æ ÐàÎåùùí§§n’3¿×ïÖ»ý À€} kÖJç_lfG¨º/.Ϫß ‚àhÕRÝ 6j!™5DꨗÅj<ˆ‰hnT0Ø.Èì–C> d zÿ‰|Eä`^M€Ðªá\è/aÞþÞ=LCÂÑvªí½­êã¯Ý­þößùtu~vQ}ÿÛ»ã!!ZHHæï=Bú‡°àÅñ‚ ÿ¦Z…>&!E _bØãÃ;DƯ:¶ÀeƒºEãë²þƒÃXß‘‰ )¢8ó¤%áÙ0÷ȼ‘5ìKäÁ4^fÌ2ausÔÑ+¤ãÑô¹æjkª;w¾(+ ¶CæAõs“Æ–Ù,miS*°T°ªãmTîjIZ0÷puw)a³õ]\À€AàÍÓ1‰T/s2 Î§«Î ,Î`Ì$þÚÿeœíøJò×oj٨l!°ÄüûLK>5…°ËaJücJ¢o:DŠYŠqQ:»L€&Šç;u¬ÃL•uÞYe"X @}r t6¿c65e?+ÂLÆ÷5À4UGï>ÆÑn p9œ£ÕØ0˜#˜Ê.΂¶i~fý4øDrÓ0EûY6J­ûèuhµGÆ&í–& á(,¬'~'Ô)skò¦%¦™”¢‰*µú½û-«ÍÓt¤³âoDFÁo†ò+4c~³­ÆÛךÞé7~xçÆámîï¿xðàýãß‘ø¯~õ¿s$WÛGb€«í#ë׿Q{z¹½Çr²‡³æbgÑde˜F½9kõk&Þ̬â39°ÜIums Rm`ï­³ôìÃðÂtôð„=©ö–[ÕïÎÕ4É9r¦”pÙŠ“÷ƒ Tí#г‰¸r\c»" òd¤téiÌrJõ+œí./.ܼa´§v ï¹^'“QEba³zîÅ]–§u¹WÒ_v `Ø÷ Ñ Fu+R¥¿à»%ëc¹R®AšJÍtÌE‡êôC©+稕—"MÆ(³²Qž²Ç9’ˆZ„kžÍ#ªWƒ¼y$Á ’/#Îß<” (ª¦ ‡RODÌ÷”- ‚DY¼”¦¿ž9^?ÄŠ]y]ª&Ñ«»šäžetÆŒ?B ÊÞ·]ë(Ì…Ý•JÆ·$"›Æ ¥ ÁL1ß´]êœ¸Ú ºÍ êŒ »Ü’!ä¢y!(ýÔÐvê˜dg„‹Ò¾„g¬uN“X»PDj;›yÞÞƒ e®Û‰ü@;£š=I§‡GjSÕnw5  'è( Ñ^Æš5ºÃy­5î>Þ£õ«ígW ÀGp–øÃ6Ûý×@Á/ÏÛóÚÕa­Ý믶ŸG‡¹[öÑým! b“WÇ­qÕ¿{PͪêÉW±{_TOž€yFÏ«ïüàÏ›ÕáÍ^uÐØª^þäk »Eõà BÔèËÑã‹êɃs˜)ëÙŸ‡è§³3¢±íT[³‹÷ˆtJD µsÛÐCî/v”g¹³Æ19}@‚$Ìý~hOzˆNúPÄߊ ô(¡iKÂÓd.h&ì âø%|=ìã¥#’FLP„!:áÍaj\•®EøžÏ¨]oÚƒÀpC➠ǧۮæ§Í{Œ;}BöfÕC˜1š‘£S4Ì뛾p8æœÅ)uHVW˜.jómVìÛ=Äqs»]½øÉÝäQ¸ýüÇF¾¾f¾ZKu4¥/5|Iì¡f ûºà››"¢å(ó`\¿SUâ(m ¾µjx„;û}ç“•ñœN{#Çô©4cŽй`þtµã¶,Œ%º2zLeœúd,õ{¨yÃdH|ç]Lc7¯‘½Fƒå£Ù8×7E&Bbëg‡)@þÏ߆°sN³ê%0*ß¾SD[´G³ar¤^cÑá»·.=sãHðô“v`;2g~b¶kAÛhgÇ.㫺ߌŠþ6”üýlð˜>wØÿÁî y´³·ûµç_¸ó‡ýíGOpvö•ɯü_YVÿ ]my\1¥)‡ýà‡_ê|õþ—ûÃ'ßÛBÒàFÞ…@7jÍv}Õì×–Í>6oÔ‚ˆFÄŒ!âÒ ;râÖÁ®¿½D@,‡êJ CBîŒÃ×}«?Aã0ƒ"ÅÄHB‘|Är"$ÔÃx’Ъ$öˆ0 ¤{qèœt¬ŠqY:WÄÙ(ñö„#ò/DZ$ Ñ“\š„Ç6fSÐ „¬ƒ]_‰G©q‰áÞü“¼Å‘êµÙ›±næâ8´¹ÒñO¤o_ÙE¸Ùx_‰Väê­Ü…ŒY4Ç>OQíêÙ”ôõdRÌCa­÷Lô#È9øH™Ûî(‰ª&¶-åâØ¸9³Œ¬€O<*IJ4ÊØ%i •Y&*e+Ì@9H”„#ב¬†žÿM£G˜“ç¡¥¿jˆJY‰V$uø@—îÉ`Lÿ6á|˜RÚ˜RSµ+‰?cŠ´NÿÒ§u¿ü.œÕòîžKø•tíóš>ú>L€&½þµë'Q“caÓè"xŠC¦÷„C¦tØÍ¢2uù„×Ï,éMAN`hK{½–1ëôÜw¬Ænçè9'>w÷Ü-+ÝìÞäÝlÚìܰl¹dÌ\8³¹û¬SB† ° úᘭN'‰¶šÓBã% À¤Ój±ÔÓ6 û öwÏ1 Žúot¿ò:Äÿjû™Àðšj‰ÿédôK/ >¾ûGoý럟ÌÏ_¨··ïvv®í®zxZ]{µ6ïmW[ƒjŠcß“9ÒúÉET²Ï}þØÖÑqmxrVý«/ünõ û›¿÷­êÛÿ÷÷ÚªöUlê;8„=DܯêHWµÔõØž•Ff¬Â6ZCŒãˆTˆúa>í°c·×“»kuº‚$Ìkɯթî?ù~õö·ßB‚¼$üp‰ û¶ah:VÉG=ûtY=½_à ù“蘺¶GHX¯ñç^$oô™m÷Û=0#¼÷]>Xét‚ÔªûÙ‰ hpFÓ€gÒΞ»¨:hô>Y%%ó’›·A¼D7t¡` ˆÊè“íÆX¬]ZŒ_7Bä+²Î{ e%k‰f*õ[ó|MŒ¼tÛàqû‚—}ßf˦c[˜(¢4øÅ^»‰WozÖJ¡VÚ¦µ,35öˆy `ç6fY_[(Þÿòkè$x.!YÀä0œä¢W Íò»h=¼™PMN›HàöOG?Í+@­¼‘Uu€Fûæg±-_b ×Î/ì\4ÉŽ7ØÛôåú+xô_¯W7_ìWw>ÖÇŸ¤SíîíADéKìü˜£`ôTU×ôJ…)UÍî"FÂ/f#˜üF ž›»»Ýj¼‹¤ŒG }rQ$õ œNÍ ‘\0›®eÁ[tÇ{ÅÿÀ…‘”øÕOxî_ø5ÞÈÉp!:DzPe¸ç›˜×¦ ¤‡À[ûÌóÓŬ&ÓÄNÔÁÏ‚´XÀr.å¼nTɨÙDiãn^³Y6¡šÌƒ+óyßE³dPøidú¸r¥žÿ¶iTÀ>™?ƒa|i„ŸÂÙe˜1¹€)©‡Ï_ßýR¯Ó:yñ•W¾ôüóÏ?€{yóáèáý‹ÇÙë¯QÇ‘«ígW ÀGh²Ÿ>=¯×{Óåb²ºÞZ,g}lÉíîã+ø×Û]?êx¨”.z.Æ¢_TøP[³ß ¶!^fa#D$­ƒÙxƒPÁsÔêzP÷ÈȲsq jNUé\²‰H‹úÖÐe ¾9XV É ¢`²m!„¼r3Ž~šÕö0'€Èb“ᵘªOÅO5BioB»Jû mÑ´Ëi®“ì„ÜüKôÃsÚZ¸ÊÄ9GÐf–gÅKk~6Ä_ì®·¿ÄA W†ÜÁglK©%ÿ=*iªVÍfAîo¨u¤?ûÍmq¹$^þ+›íü‡·g¥9ñÜfÜÝT)'±²[!]ëçÅ€²6¾Þ6’îÊ9ð>eEžº>€›„){®øC™Í×x‘è!¬í¤^ò½îë>ŠÅþîsûL$Ag€ô¯é?k-„(Úëƒqt÷Žó!%äj*$˜qˆ“àiVà:kø½ûàÑ0uFÈ@,ô3Ë8¨XmPúÏУa°Ãk¸xêîµ É5u¥‡–÷¹­ä¿/Q/Õ„h¢ o•«eÇðÿeïM~eË®;½݉þ޸ݻ¯ÍŽÉd&“N6"EWQV‘ÑVK(”iÀ°òÄ<µ†'rþ5ð  ðPâ<° Ë0T*ŠT±Ä^L%³Ï—™¯»ý¾÷÷­ñØX.‹b’Ù0Î{çÄ9»ßç®ßêöÚ4/˜@û¯éLë'´ <7‡år;¾<ÇÇ„?™fõ܇Î_<¦¦•1ðãÖ¾ñ®rϲ·- cÞä޼gõFål§µrxó‰SBhõjüE|å+´zá­hsüºŒÀ†øÍôÙü/ë¬èýÂx:¼Ö›Ô>ÙN®,Џ(•›àw•À*Rblžý$C™Ÿ.SªºypãÔ­ÃÝlk¯“ýÎ?þr6<ëg?ü7™ýè{/aóf/}ûEÔ¸•ìö˯CÈ«Yû°™u®·²½{ÙÎ!„¬ô¯/@’Š%Bªà©T(k/…È`OÆÇ,c# ÏÝãììÎy€ù•›ÛQ¶ªÛ¡^æ{¥²:dŽ1vç1;Õ zCžIEM1„’Bóƒ8êd&Xwv[A€{Cí§ÔkT?Ë"A ôø:BS(Ú·ßa×?¤É»´G‰¸Œ§—’½jlì(ýÅêÎa{ަ%Ú¹jJîP Ð[b-1 á¤9ÃC)ÏÃvš&¥#!ÿut“ºûj² 5k^ÏòkWÜ g†¿þHÛE+VzU’–1oRh ¯k íšm¸¯æD@˜b©"•…ŠxÝ>V¯ñàÉâm¿,R sÇÆŒ˜Árúh\߇“G³a`¼,[ÍÐÖ>[ o°÷çÙ.ÛOéKÒÂ\£HçAËžÂ00Ï =kæ¡í̵`¯cŸþwú˜N?™ÃëPÅŒ0bpUç ™¿; N1OÔûJü¤S;Cû¦úH0— J|B/N:Ç(!²ãÁ£5Z(ÖY4mÄ3È©­Ž í¯ÝíP‡[W[®ï‚×yÒ;SC)û²Móˆ¾È<×kŒmÜg—K™oß1·`zd6©‚í»£É#æ‘ìéïˆ;0S[|”ú]Ôaž“3´C¼\šÏ'Ë9jÿûׯný)«HÎ>úäSÿGk{û¢]i½ øw²/mÀŸýõ<¤/›ã>Ю·¾õ?—Ï'Gµérpm±˜^g]øî|^ÞZ²d‰žFÓÎ:AÝ=Ô€¤‘à1„ »äow§ÃšÿbvíñëÙâpš=¸s?»sûN,¿¸>j4ƒc;ÇÛh¶Ù#[°KÐ*BäA¥*ÁÒÑNÂà !Sk®¤$qÔ{Á»3cüñäw)XÎ2¼* +=vx‰²’%AL!°¬|®„ˈ†¶Ã€9|%ë‹u펡èt„SÊòÖuÒo1ÍV9>©©šÀ4ÇÙ›¹s³Gp"?n‡cïR2ç¦#—”3©¯á»A›b…íV;“3§:-¶·ôö7¸S’þƒûŒ¶Óê¶%Á ¬þ£¿ÁÜéë@S’d¿n# úV¨Ã¾ÄªˆXúMZ} W,ð{vÀ禵{b4·¢ÏüéÚIâ ‹1Sí ÷{ŸñŠ¥ƒë<ÊŒñâ!Ss#Câ?^AžQ'ãé2Øè ÷cx­›òY=ʧ¢,ßjŒ³¡VcH›¿(Å4zOíLz'yø;cuoh¬[¿´zK4þ$bs–ûÏö›¯6ëÕÓ›yæöGž|¦;ªŸ}éKÏk0Ú¿Æ#(ɯñ|º~çÎÿZ'BÚ£ÅèÊó—o°½ï! ‰ù5~ ¸¾Íæ:[Ø÷ÛÀØN àãÞæHÒ9‰Z0ì‰ÝA›eû*yñˆú3ÏdòŸ^do¿ö 9$<î1Îv]Ø8»<é"½_b:¸O¼Ô¼û:–²ëOìR_"]ÁÚ€#×PWúk:B|ï½yåøgÊòÃj E¬³®ãq/¤„Ù ¡Dœ¼!šA-!€Í$Þó˜K¥Õûí‚*rù–6ÊåZ×ZêŽù£Ñ¶ÛéŠq0 Ÿ`ø˜ÿ¥vûª}6Q’¤MïáÜ&ç·C`>?Œ‹Seù^¯_§õœYa„ ¶-6ȲÌéïFÃ8óX&¼ë(CŽ€û*òo)¼÷Ç)íî­´&–SSƒÁ_év S“¥¡m3L² ØÃ{Fs£™zö›~4y€ƒ÷@­ÇÝ£ñœe—K¤ÿuŽKyåÎN»ö&wÍïÕêKVÕÏæU_öksüšÀ†ø¼ýûåf¥ºütuØ¿÷Èd>ÝŸ/Õ¥ @µ…íu;ËÛlkk›Èm8ºAðº§ÂÞχÀv­ÍH°ì5÷.»vó‘l‹€A»vöÉçžÎŽˆÑÿo|7;bÉÞ @—ÝñNï"…㌖Ãqýëå¼öà7>ýŸþëÖîÕñï¥ÓBá¿¡Å›c3¼Ï›AøàÀY~¿D4½Öd6hvǬ¸F0š°dnŠô›Aˆç¨ågÅAV<ÇCBµ@ý” OkÕõ½Hµá =¢ñ¹ž¹ Ñ Õ=~÷p uë<»ùÄ!½” Yr×;gm¿Jê%uÙ>šuïe ]̳Vc’m5A Ä*ì¯Ø‘%æC¢úuÏlñkpµ± ’ƒžbšåBðB"£]’Ù¤Þ†RZoLŸjH.¿eDTKPgCþª.M9Í#|“0þóðqs›mP­ìi´5¥T’)­K í[ª—›<ˆvñ,¼´×Ï©ÍúÖ­3ƒ¿üí9>|y×6'F =# wmãêQÕòMmé>ØB$G+1ß ‘‹SQîê}çŽ@ÙÌïxÐíÌŽC0,Ñ û‘Èq³OJðJ¶}VJhçà3"¡4«V¤ ˜»SüL“ãs|fÔ?W$¤¾¨žWEí§ËE£ZÀŒFZ¡ ðrÍÄziGV‡#)ø©1ŠA1 ípƒqàYØ¿oÇß¼$÷д½Üp§BÇ9ü%ì~˜6¸ ­YޏðàÏ}×~üÌ´‘8æ;]G^Êul=LíåJfcLgÆŒ¥A’ÔÈ”9V†ÞBò—ÑRÛbî1ï¡Ì„í ^Õ2lÀú QÆ<‡@IDATÁùsžÔò¨…æK"-òÇœ xGǵZþ6æ„Svó{«XÊï• ¥³R£Ïî½~?{çå;Ùñƒóì”n{ïÅË ío}û °Â’µVvx};œñžûÌcH0S@âuç…·³Ûo܇Aa9Ô}x¸ùŽgmúÒT f¬00Ö´0„f 4‘†v†€„SbhAzÒß ¥FiwBRŽª—ý¬ÚI˜Y*Á¾¨ec¾ÃüÌÝ ÒΜ#‘ÅzuÔ ®ˆ p –™ ë¶ kYèüH½"z‡Ôq¦‰´‰¶Ún>žý~ØG µ2µÙßÚ¦‹Hí@L‡J+µ3_?¨̨ä{hPÑ[v*àET% ás•@X©àÆÌaô»!s™€2Õ¯/‡}4¦ýå9~œïÜq©$å£&1piòl¡íùèÓ[ƒáàj'°üõ7Y »äÉ%jxk·–µwݾU=Ôf¡TŽÏ ~ÐÎ.« l†/Ý_à§ã¦€º Ç:z'Ÿ*Ô‘Å& Ì[£¥´¿Œz 1!8SåN5v2”qsõŠc\Æ Þ¾BNùÃÏ‚$%ò9gÁsQžÿœ{ýlµ³hŸanDY8ñùÔç c©mîS÷çR%þæ/o¡-«Ã4]ݯf7v¥4¿„©vŒï³ágcgU™`53=–¨Ê¸ûAÿ–ÃÕþŽÔ2;b9ëÝûãÅñ1:¿ù²ßÁ[zåäé§oýÉ#\y³ÖÜzå©§~çÅz¥=ýÚÿë.à¿üì—máæØŒ@ ð~¾ºüj©õr«Ü?ùz­8šÖGã1›£‚ðÐ~”¯`ë´ ¡ËF@Ù‚ÍXŠÝK¨k¨+į/A¤T‡è#èj8ž¶ÑD¹Èõ„es~¶˜ê•Û„¬Åü޻šQ˜²”`’¨kWRŒå}Pÿ|ªÐ‹“>ÒŒ:Jc¬Üa¦¡ˆ±BÆD©UðŸ#Ì9…ðI„ãzElcºV"b8Bù\/õ•¨ÓN‰rt†S¬F _QΊô™Ï£¸’ò¤ñÚ]Õ"Ôt´.¿Ñ- ,QB5« „mI¹W…ů…ùõ!À5í4 KÈw\G»¸½nî:µå¥2×wøí¼ ¥³†ÍÜ{rhÌ‘êw# pÑo² è1‡¦çw€™EDÑÜ{xm©M¦TòTÒWª” \H­áŒFÞˆ|H#Ó¼‰èì‡`>Ú÷—2KŒ§eÄ&6ä‰y‰zm‡í²}Ñ­Õ×êÄ3èé'Ç!ÚNÏ¡º_]ë7@ÒÐP™I0ÉšÌæ÷™õ8¯2j,—˜öuÏ~<Ìà‰s”»:› L<<³ÆurEÚÕ$ý¯4¤µ^ÛË«ü°¿Á0Ð%þª¢\›=ÊY¥{86>X}|Õelÿà§$ƒïÆ”= ÔXñáÕ]Œón¥\9&bã €“Nó¤’·{»>‰F 8þ+Ùâùç)wslFà'F`ÃüÄ`|Ð.¯»sF]õ2ìû/< ÝÙ©6®wòb¥¾»óÚ¿Nöæk/fÇ·_ÍFGY÷ÅW "Y¶õx'ˉ¿^A‚¬vêA`Ã~ ¥í³ç»ØSúP2müÝbð!HˈðÀ O ¢ß zÛ“ŸØËžýÜNò @ à¦<#x ƒî¼ùÒivy:$¤î ûÑwN!båìÿ ­„Bõâ´›±”°DÙÀÑ7,ýƒÉpã¡Øý­„~ª<]Và N&„®Pêó™N}‰Róƒ~è €ˆìf:W%ÚQbMºÄÛXn.T¡ÎªÏX2¶ƒƒÀæÞn]‹Œ• Y*™#W¡Äö¾ @Kð£ŠÜøøFÅÓ6k;ê¶9D}~F:ºœmåÌ->‚ …qfõ[´Û9ðBçï$Ѳ:A͈`¬oŸúƶyІÁ¬UwYþ6c'¾f F‹6.h{”¤—<À©ÏGHÞÙá]t´Y†ìøxζ¿î,¨Y!1}¶å•Ѹu3mÔ³sµ”mï—²½ƒföñç)º”}ûß-íR_„‹s:æºÈzEAwŠ–!6ÍAKA,¥7cHØ]ý)˜–K0Ô ÐÓ†jh”äe\5b%yÖŽ†™ #« Øbó!Ç«Ê^$mýìÌ×xÀoª«¸D’¬úÀ`36!²ìˆ3aÙ~8dØœç¸Ì;sO( †Â©Åý Í i _ìûØc™«ÏÝøH•¿m²$œð²«Œ#ËñФñtnΙ¬ÃdŸÕ0ú¯˜^ŸˆÏ@y¿’¿a‡Ÿ,õðwvïþd~çî|ÁòÂ× ôF{«qç3Ÿúw¾±³·{œ×ö^¸vë©Óqý¿ð…8ˆ¦o¾6#ð׌¯Ôæø Ž ú*D,kbÃnN¦bè•ØV­Š&¿F̳ˆ÷_aýIÀES--Å_¨Î5@ˆ #†}C§Ï‚8Bí¦¨Z„ñ5<°›ÿà¬a ‘fj]¥À&Î^;·–rÄzW0êCÅ fÝé±±ŒÄ—UÛ 9vQÀ)Ó$úÜWbLõRÈŠ{àáôø€ÜöÜ`œÈ º«Ü\+ÁúñYËX}`,ZkßcÉÞ*­aˆ]Ö¥tÒ8cãx€íA„ÉB‰þ  °ìxÆõ*jãx. x½:¬ÓÏúH“Úè=Ÿ¹~Ñ.^?÷ÐΖÙ7ÇP^…{þö¡š—Õ+Ïb MÃsó`„ÂI’~ÆrÀ‡u¦2ì‡ïEh ì¨#»ª3ÎÖÅݨ×3G{™€tmð¨t¤Œ¾16Ï_q‡¯0qSŸ„4þ\ó;ø> ¸%Õøj+LQüH˜´&´s]•g>1Ž\Ê(Ƈ²’?Ž„K”zFŠ…>š«3b!_½rp|ë±GNþÙ½úÄßw7¿)s˜ÎͱŸ ð³#òúý×¾všðÉ{—Ç·Þ<)<^®äÍGoVªµþªõ­ìfù#ÙþuÂãNúÀ9ÁS›íu*ØëKØvKìpq 1BbcM¿ÁWò¬ÃP*jf ¤)E˜‡"f”ŽÙ)!}…ßÊñ°ŸfÖñÄ`³™íöË«ÙÁÁÍÈÛ}0f™àÉÿ€w°ýÃÅÙH„Ðp4Àƒ ú6…uC¶"V€R5R ·ˆ`.€& ¤áycmöÑÁTH?ÃÀ¹ÔÆÏ?½©µ‹ ès WJ7 Ò´ô¶‹¦„]\÷ݽ´÷ûÉ}ÌH•nû«­}A,Ö*'e@¬Ëín[™¢\jÈÕ¹¤²‚öyž» !üDIÚ‘Ö¤‘„–C¡ñ-ZÙŸú ¸tRFI;±êu=áeØ“ˆûÚiÔ8» ð&Ë=s‘Vl±éŽu»j@íÂØ1WâgNÝÇÞsOú -\íG‹8×n¡‘¹ûسâ3°ê~ש—pB+ÒýΖ}´+lá½ñÆŸ önÇš6cîþ·ÊÚÿÆ6Ë:9;vhŽaÞ DiÙeˆóœrjšo×¹f|œ7ÆiÎØvÓÊ(‰’:ržã STÀð_æ}Í‹#´3¾K´Â†P–×V ·\-âËå¤AçšJÿJ8*Ê&éÛŠ í߯œƒ&c!€Ox'gôCÏþ'¼GÔáµGSf€"mõ~Ô ´X±á;2B»¥‰LÍù´‘)<0—Ô'èëc¡’Är ä\[îÙý£Ù|8ZNóré­Çn4_ßélÿÅ£7ÿ^£Y{°[mþ¨=«®á}ðìoü©c8mŽÍüõ#°aþúqù@Üe»ÞÒñFÀíÑ´Ðb}x½@ÌÕb°¾õjVd Xƒe|õÄtZGn bݳÄnT<™ >&*›ñú•Í+úØ{©ŽtâÞÖ‚"-à2%Ï@D¹Kìÿ1%gíÅu›IT›åZVÇk˽㇚ öÂ["¬©!b(¤ «1¯×Öçf8¡.†è‡7<%ÊRKÍá)i-…ôž“Ý~U¿M¯?ê³vê’»®:¼ÛÉ—–ú¥gUú¢äê²/AÛ¶™NÆ‚ââwÒD€• [ |v\ M…›y’¶%Õo;ããh3Ï£Ïü^ç+ž9F ´ía‹wˆø6>S ã£YÃ%wJÁŽÚJoù$Šò€~ÈÜL)dB?º Šªò¾«(È>×\®Ç¹³ŸgM€«·Ø‘-T×2Q2 €RóŒø5b ûOòc¾:š91B™Ï>Ø/×ÿÇ­'Í[ÎÁÜw-Tàþæã*ÇÙ>›&B$r-ãç•%Ì@Af•¹’©ˆy°Ï¤vxããßMÏ,.ß>ηçpº$±ùíSÇüÊô¹œÔñd–0&œýd(x=âPÒw5+%ܧ` ä>Ä^¶„9 ¿~'¾k!ê£.çÍ÷NðWs`KHƒ®~ýÁrÑÙ.öY øàêµÎßü»Ÿû`÷ðäÎdpòå¯<×§Çóé´ùÞŒÀ¿e6 À¿epÞ–Ë?(¾ðÂo߸üݯ>w1:ýô¼PÙivöÛ¥¼†_ÿ=¼¼õø¨ë®Z³A@÷ ÜÓù0žâ©ô7ÃöÈn#Ð ’TJñj‚”(è(h¥¯ 1¨±lIã;ô-aÛ"8 ÚÈ|§G—”…ÚI¸r§„~e§Á{Ôž®AàÙ“Oì#UO³?ÿúËÙуK€ 0ÂëÜÝÙ·Õ;»Äñ‰o¿ À|Ó¦26àDã%ÜÍDø½‰N ¦MP^tH{€$à§V#À[t ÷Àpà1Äëß»­-$}¤¶¼Ø­+–'*¹˜Z²DÀ©Žgñ!ís-¼ ƒëΓ‚ÈE=ªôÓZqJT$ö¶AâÎÇ9@(àäžÍÓ„¯€Àï^–,X¯ Š€qk ‘_;Ä6¿×$(Ì4»s¿LÃñ >¶1>©Z¦v ®nøc‘WÙê êì\æ@sN9»õøVH¢ ÃÓDC—nj¹Á&ÍËÀÑ7æJð»8ðI«%‚¡¬:eT‚õñ(Âx ²Ä¸Û{!PÇ&<ôK§Cß‹9KVzŸ~‘{ö71œÛЄ¸ãŒ@AçžûêÊ¥Q"C-SÂ=ËwÜ쯼ÇzÎdjÉmp:HBY€8ÌÏÔÄxœá#á”ŽÑ (ñËj^SñÓ‚ùuîÛF;¤!8ßàä§œ1`ï¢×ñ÷ÚÃvhp®e@=¢ß”«Ä߃iÆT°$–€AþÆõzé "Ažlo5~xxõÚw¶;¯Ìõw¦Åa:_p”6ÇfþÆ#°aþÆCõ~IøÅ"Äûf¡PÚC]û±qÿâãËR»^o^k¡¸„@5j uœ¤ªmÔˆ vÌÃÁ­€OçµìhrŸõÉCœ¿ <¨$—ª™!XJPR0IÞç-c–Ë̽Œe\J™2˜#~ˆ`ˆaúèp5\&ì.(QÖ.]F î =îˆHfàÊÕí±&úT5/ÿèÚ€Åè<ˆãá…Ëè«ø-¸$m-Ek"ijL#ÉɨÖû¶Ybª•‡š é©L€G~ž $î¢&‘  à± åG°¹Z‚‚ZD$¬‘f«S‹rÜAÐ`Fsú:×Ì@á!ñ“V@ñP£¢#ÝÏ*~yqE¢`¼³F¨ ø¦ ü¬ Z§áy,‘ã3DE¯pøÅ¥Ì @£"€o£ui0×§gÃì+.¦kŸ¨†¦Õ,`éöQ)»Œª¿Úàò¿]––mUîêÍZvãq˜5Ô܇WÛÒÌ~ŒÕnŸ¢kúaʬ–(¤®‹e×¶ÐNÕä9*ì;Ó9‡®è€e4€9¯E€¥@Y,3¡Œ“;ù©±q)£ms÷>ß§˜CÛÍG&TàäRkÓo­i}ZæØ÷ÀÃáeJxí³)-Ÿ­>^ûºÄý”#ƈäI³uTš7¹›ÀÞå]¥.‘tçC™—õéÕßR{ÂßQÓ>0Ij 4ì#L¿kýý» æ˜<2Bްï'ûmÿ¸®êÀuq1XLy/ûÞh½²·[»½·wõ»¿ÿþ‹oò7r\}ãå³×F/-6ú0h›ãç ðs ×{Ÿø‡?<*žŽ&û€ìõR­v@”?âç5+ûæ·à.xâËlÉV¿lm;×k¨Ò¿W ©¯ñ/Wˆà‡½”\¤‡ )¹JNAHÁmŠ™`@¿A%.AXà”4I%Ê­0 H¿üPñ#«’®ªf‰™Þó#– °–*mB ÞÞ¯gûƒ@†%3¤#½ñvA†=IõpÄ[¢-½×|¢Ý”×¶´†aõ<ç~Òð\ª !W]ùéE\oѾ0wp­æ5À•6L ðÊñ™&‡è;eIäcyW4ÑÔüC¢${[ºð!§hs´!ÝŠt¿¸0©‰ø/£b»ç‡jî9ào]Z`!ç àI“aö˜?UÊÌ= ¼ËYÕ@ÈY×”»iR8Aò—îø¸Î߹ȱåwب§Pï߬gmœúÚHÿU¶avµÅ]’䶃§NL>T^Æ_$¶æáŒ¸·™Q‡š‘RØ1dÜÕ4P¿¡„eäd$£@Etò”xïÖÞ÷a®qlygì=‡Úƒ{v–ÿkS€c陈ÄäQï‹}´hçMõ9] p'@ÇÈbxΟAÌS˜™Ì³ìEb#JfBp6‘gÌj_ž°õsÏÚFûÓίɣÊûŒÍªnËœ;‡ö‡?$¾)׿C«°!Î «ü9>·¯j7¢EKÂe- ˜ªa£šs>¯Õ꯶ZÛíVýΣôW‹áþ¿ÿßÍ>»¶#إͱ¿ál€¿á@½_’½pùV©4ÉžFšüX}wïÉݽæ~ÎŽ”t î$p=³ AP¶Z[0-C°!â ô¸5Öâ·ñ ˜«Ê7ÌÄ´¤ø•,,úXb\¬Gu6Nd,ˆWê&ÎÃÀñ­ÄÒ*%ÁDÌ gAéš^?jCªé"ýbYŸ²ôó²AØaˆàcÏíg;6³}ÿ~vùâ1A€ÆÙÛ¯Üð±7߉ýké\õ}Κ( t&F0IÿÖŸÊ9+I)ÅyA kÈq´KirMvˆ3mpü§"V ¨s·.ŠP°ƒ*_÷l€€MÖ?ÀˉŽeÚËuHtG¾\yæŽva‡¦ÌÀµº~¸Šr¢ •­‹öªpð(CPбPiŸ¾ÓdviaÌýŸ¢úמUò·hÚDÑíUò‚~-¤ý­ÝJöÈÓØ÷éßÎ.~¨« øyEü4+²OÑðØžš uÐ54@èghjµv•ºˆ‰„oè_UµOëÌ–0Cš‹]ç DVàÇzCŸ$á»vin`lñˆ\ï3£f«d^üîå´¿NL ”W1ýŽm0moX`‡7§k¦-‚`ú>ÁØWï;/ÚÞýX—í ïWÀ ½wXc>ßyÇÛÃ]½gûùŽw®F¤+‹àJ«9¥=¶0“ÑFòúw,·’— åzá4¯×ïß¼þØ7ëÍöƒ+ûþÈ£7ïVZÍó×îmŸ}ñ‹_俺Téæ{3?ǬÿŽ,›¤ïåÔòËÂpVgguÜõK¥:y2Å©i±  PÓù’¸úË¢AƒŠ.pÈÓ¾¬ú\Õi€P‚rãU{KŠì‡ò,Gé.6qQÚ‚0ÆS!*Y©A>â0¿ÃÛš¼²vqƒ×¸›èCH®Q‡!ÀC,‰åd„-¥*˜ |¬wDhÞp¸Ò¹­Š‡»5Pží±6 <$3þ ®> HM÷"¥ùìWôÍÜé0i꣉ãW”¨G´áÎY§3–¿ÿÂŒú¤÷Á4–¡à^r`£}€‰G|sß{¿S5«úÒXFC£~Æ,@ŽY¡|ÁÇ÷dÂLàjeAŸí‘‘À8óõXƒ®G¿šœ±S:uS¥%ý­½j¶½ÇR>ýܯîf4ô3"iCü 0³-2$€ 'ˆÇ1L>vYŸŸØg@ ŽñHm ›þCi{KË6Çfþö#°aþöc÷žäv½0ë_”ÜÂoû0è"ùuÏ¡0P°}BÇzk‚„…„¦Ô;á ù1$wÍùJP3—¿$3v)œìH— qJHÜÄÿaÙϱÙ_¢@v  p_zA5³àŸ>W;pl 5s©ž„Z©Xo~à)뱺i”Fw u¤E‚Rvq:Èî¼yNZEÂÓÐìàÔ¶Ð G45¢+°ÊJÆ2–/Á5T®½\“à`Vhg8¾¤Ò}AÛc-‘°r+• òl„.ÝrܘHæÄ]ð&hDƆwí²þ¾•hkäË´=¤~€K_Š`„¨'–bBó‡žþûoNLQJœ^A"δÍ6«5 •óÀýãÁ?} æ,§D•~ÌòKÓo'€¾Ëž •Z×ò»Ãuûªòo>ÎFP¨¨÷X0Ê‘¬³W‹ð¼nÑ»}HÛ°çk“VZ5Vƒ&$A¨ˆ À£ óF_ôûƒÃƒ–4ª‹SœN¡nÎm&¦mëx0 ´K&IÕºûQ8¶2 & Jö,œY-œD¤åÇÚ©3Mý¥|ëÑ‘Â8QåÊ·Öåï¸f‡ š uœ|G \å9igR5–i;ŒÅ¯É€Çñ»Ë²H·…v<ûh<š0Ršö·Ð­LSvÕò&ö‹4e q~Ç+M3Fø}NæÖf3dÁàäú`ò—²öð¿ Å‚(Œ=Þƒ þߣµgíÎÎK»W®¿VÊëGy¾xa1eÏ.[1ÍŽ&ögGNÇæØŒÀ/4à¾_mæÿí¥ÿ©:[œÖFµ2¤ù›¿ýJ»³}z9šÜþÊÃ%~ÿœ6Çf~ñØ0¿øþJJüÏOZŸ*”Z»­ÃÆ>xSo—‡åYŽ–í½k—GAÐ&“n®œ‹áÃØiô7·-à0ìv±ï÷X¢7Κˆ¡÷‚À!Ë&ˆ• ‚¬4àÃ%PIjý7ž„OЇd¿viWÚY`ÛUÆ—XPw0Ü:HG~Ⱥ$æ@Hb8"–Ñ´;Vy‹ BØŒ»l(CÌ€.;»Ó쬌œvÕÙ{àZÕ-‹ù "jR0˜¡6÷(S¾Ê:Óv,a7¡_4QкL $–YZ›4(»'±T»­°Ù]Ò(HTàd¶ÛDU¤À>Nv¡öøTIçì•°Tú!bcæêʃ ²ŠèßÚ¬=´¹{¸T.´)HŽ‚eWkËQ–)g2ã0Ý­´û^“Ú¾{lí¼¤ ‘R'D×ño]!($ ËV0,ÜðIxiƒ·ÿú€ÔŽYš_îÓ¡Hç»t˜EŸM±õ«7¼QärSŸQ†„M¤ôp™¤kó}aÔx¸ùšnPeFЗkæÄAçâ °”¯¤ŽxMœ ÀSç-ÞI¯À>Lfó}„9ò‘‰¬É2œœ[á-9dw@Öy î#n§÷L!õSŒ¦³>þj´†8üxG&v›yåÜiÑwó3vúBø’¸²ï†¾ÓÐäXcKyÁ$6Æ‘¶™noSŒ=vøÛclçG'zdCV|Ÿº.ó¼õ-íý•RóíÙ||—÷|³Ä/FxóõnÀ†x·Gô—T^ï²VC²ùâÍ•¼óØa©š7ZÕ~e^ëg‹Z7k²£Ý Õòxt ÙÃΟ< PÄJÕm`]Ò·Gô?"–Ù(h æÚ %TE \qäŒæV`½—ë2A°"­ô>Al¥ä‚zˆO<‡Šéc 5æ®§(Ëòâ™ ˜ãÂ$ðB Oò+»ílïV;»do‚9ˆwz<È~ð!Ki+Àâzvx¨yÀ^€Yj·†À[Uã‘æÃ*KÚ\çﲫŽá\¶Ò–ÌT[+éC˜ÑIÓ†€2aÙ› ¤££åç¤ÙErÎIxÁ2;–¶c&(HS¥|ÇF³B,•¤-ˆb“Kç<Ç ¥xÏÜUp”¢•̧—¹àcp-€Ws‚múløî@¸‹4¯3Ù}LDvŠçŽCÏþÎ "ùáœÖ¹ÑÄ ³Å1F"¹öV^È# f‹¼¶+40 ¶Íx ÑZÚ"À#¬&¿@{pɪ Ìî¸ç’CY)ÇÑø y1˜):«/yå‚»D­ÇqöËL­š:¼ﬥ‘–“û0­M÷^r6´NÙL戴ú}jŽ'$°,lj«êpi"Š3*¤Ÿ`n`(eºŽOxט ¦4>M"°“¡mVM˜_SÌ„¹ršÓËQ8™!Ëshý¸\Ð¥|öÖšY¥ILæo›¥´0/0KûÌ^~k¢äqóVû_·Z•ãÇ?öù¯}ù÷ÿ«¼Ë=bù÷¨—mŽÍ¼û#°aÞý1ý¥”8ÍçÅ|9Ý*”òmTãµE±RöF¥îEût7÷Øg!Ö0 ŽàöòPK+±@´ê’AAO J¢ÑÝòØæ‘ëTÓ/)Gâ¶0Ĭ.Õ\Ñϸ¹ãsƒÓHŸ¸H9#-ŵõC0•Ô—¤ Z/eµ~(äÅÞñÜbí“n†Ç¹ëî%´×n´"ŠKÛ Ó;Æþ~r2@²øðsˆØ÷'*#íÙ¬h!å®i¼>Aô©6–Œ JgÔ)¡^IÒ% 96a^øñcK‰:,Ûbt¨ä­g¼žïzÞ—@0Ùÿøòl^΂£õ8z†[½êl!l„$n›´ß'U:óè(yÆ.|Î…PU7ˆOpíÖ>eZïqILŒd=e¤KÇHðwÇFÛaËÂnN[í·í0m0;œ£ìh#m¸Äâþ«OFúæS¼ôl¯!–LØån:Ì3Ïì P™Á(5B` © ý,POiHAR4¶ÓˆØ¶&¸äìm.¡ð¯PÌ`÷Œ ´hU¤ª³û,û󘞳‹Å%öÕjöìsW‚Xß¼ÕÊNü½p”ýà»÷’Gì!p/Ô§yj'B¬îG ŠDK%Ô´¹FûpBƒxÊ­plH{½@eø[Ï$´Õ¶…IÀ¶!¹Krq˜³}öJ ˆû¨ùwÚD΃ùÐï¢;#ðŽjò õî4ÛÞvGÁRDÓÓœ ”)£”ÔìHÊHšô;bð#A«™ %¿¶ê" ¡ê¼êYðh±d²‚±»0¿sváÛÊ>÷wŸFM=Éþ—ñgÙ)Ž“2®Ã7R#v¡¬sPÏ®?º•V0Ç:_ªep‹ç5p©¾®ÌFMm‚Sª$nx]Õ×l0ÅÑ(¤w•d d+ÊÑñïìŒþ³ÜÐ÷+|HHä˜;÷UÞ½<ÀQÑ_N±Ìíl£°x“(”Ÿ°7\p¹š+XFÄù‰FÞhM(ÍoAÙH{ÞÓyÐ$a*¡:g*ço ²Åoï¥OŽš@åGNçν#ÎÙAѺZ˜GÌÝ›]!*¢÷ôC‘"þ>e,²Ã}+Ò¹i’Ì—>VÑù³ŠzZ«H€ªûÛÌI sÄ6R¿LǽƒÙƒãùt0\¾ƒÒî6›Ž>û…§þ¼Õ¨_½ñ…uøègzûXíüÙg'©^R¯žÍ±w}6 À»>¤ïn_ýêWK—×óÆdq¿]/Íë‹B©Ž W‚&&×´&¦!.,ò`µ§†M•4sâ²ca}Vï¡VÄ|†à•éðc=Nƒñ¼HÚd®—.c{`@ÚòüØ÷À”á{Ä(;»žcžb®¨ðtåÀzÌ|îÜ;'~È㯗–à«£¦å§ŽUûSzžû;òÆ4§ëõ=3ÚæŸ¨Ç¤›®×wâvÜõý³mŽ¿¡{ÇŒ[Äåç½pHsÊäØGí=qýÌ÷ƒüÎm¼×dÑ’c¿ª.…ýŃàòÀsé=ødº´„—YjÁSÀ6ÏÙ6ù¸Tηêµãf£~ùÈSOžyæ ã'žxBÉÿg;±îÌæ¼wm6 À»6”¿œ‚f·ªÈ¹Å/FO”¯í?9ß½s:¬ ‘#¤°sbþOõΟ°U/ˆnœ|Õ”K<Õ ûŸXn4«`k‡xU ).Ë‘˜Ê¤2ñÝ‹HüîÎ;9CÚò>¨{è¦\ȃÈ%Ç:H˜`€áºÚpYjÖËò]¤Eýû¾.«QIRc„PÔPµâô§ÃaŸpª†fA ÓÛh…h Øü_ÁAQ{} àkÃ<ûÌvöÄ#uÔÿ£ì/þâA€çíW/iNçC6¬!Ü0fƒ½]6;âÞæ@3.žeÕÅš'%t_»¾DÝ/Á’fh‰ú%öqAÃP¶¡-à¦@o:Ý)ïíR <9ÅY©þˆÆ¦)»”ÑöP†MÐ&ÞþÔ’¤±íjÚ{ –ì!)w¿†êÞ0ÊÚúKLV‹ó2ÀßhfíöVÖØªeíëv:a?yæìô £Þ¢i®Ö³›OoGpŸ)È­‚avíYS C€fH@â@Fì ¤[&~A3<ß§D´ß3ÂDÓÞÝþ<Ò÷ˆù°‹¤¶ÿ“{ƒ¬‹ LJô1VL8>+¯zë!9§Ü0%¶àœ§ÃÃx’FF5àΤ|T¹ãÆ;é=fèá9æL†€²ÿüóönslFà—>à—>Ä¿Xlôƒ'Þb¸[(Vk8ÜU¦‹Aq‚D©µ“!L*«·$¦tU¿.Kó#ÑTú’B&M€RÞO| 9J^½|RBîüRhˆgz.) ¶ÔÊGižgY—ÍIÐÓ‡vÐð¢i^®%üü·-ññ‡–“K€UB3½[Ï Öš)J£*×:}:8ûH ªªç o°>ªîõGÐ!ÌrTù{VÂŽC¤X¸KÔß`w¶%ÆÅV{14h’Ÿ!³e)-Ú!$;ÓÉØTBž˜ d¼ÈkÁއG,£`Ëš1†t ÔüÁŒ¸¶œþUa&‚à\EãáÌ5àÊ… êÿ*K ëx¥±ßS˜Pbí¾@¦´n™Œƒ±tzŒP¾Q·õ2wÑ׸ðÿí›_<-‚ åù±oá|ùVýàÚ+7ˆRcà@ÍæÂmƒÿ|×H—¾¬ŸçüHC̸ò‹LA†t¦þtûøM5éµ0)Ÿ`¸Œ÷ÆßTò°O–ÅõÆ•™ã"ÒØÍZ‚¾^þ2ëC¦AçÁøâ2 ¼Izw©˜[Ì;}cî™áhÜš±³$øµ”&LFBŽL6~ù[þ œ${0—•bé$¯–ŽZ­Öñ'?ùÌ ÜÅåíÓY7ÅñÿþºY›óf~%#°a~%Ãü·¯dÞÉvA«/#5îu¯#3Õº'•>ÒûÖ¯}I®›µ!È£¬wÿDyºÁjæHŒè \:.µ›‡Á"ñls¶®(hVÙ\^ßmÐJJç,Ô¼@æÄ`JÕšeiÛMK«jØÃk9›åàÉ¿ÐË’7)®jüÙ˜:¹5Ç‹~†ôÄZ,‚~ºÜbˆjÏš[@!'ñ9;Ì Ä:ÁåÔƒwtöïýöÍp<{ù¥ã°iŸá;àG¸»ÑÉ4ìì6ÁÖC›ÂÂa ´·EÜuóBOHö6Ìg\sÞsBùLfJ®¯üübL9hLï±S[HøJš~÷œ¥xž‹€²¾U‚ñ8ÓÆ&qþ-$/ƒ¡ŽB\saƒüÍHUhXÑî4²«×vcó¤¯ÿñ_b{ïg—n¤„ѾÞ4È¡iwóKÿ— jÿ¼šˆÆ6KiÇ Ø=X€á”Ò=ÚLÞè’¿jÕûïøpkŒv)øæÍq! í*d½ ´Oheúø1˜Nà—ñ°_úÈñâr`¡›(9–ŽO0®d æ’4™{M¬ žïÈc¾J8WƈĽh÷=¦:­˜?r{GÆŒ[–Çá+9 oªêÏ»©?j‚TÑo±R¢©DÉ]_¦iŸw“¶oØÕõ/à(¸T{ø Œè“{,8ç¼âÁÌÔ˜gý|wÝ7aŒæäö £y„ ž/ß!~Ã=˜‡W;ß«Ö+g[ík?ìlžtÚµÓlV?ª•&óÍ&>1Ô›¯÷`6 À{0è?O•Ю*@v *·‹£U2ZÑ1iÊNõv“p® ¢°±oq #ЇP’¨ Ìk5D©q„ò•r…CXP{„0ÒA¼T×+ÁÏq [:™tšÓÞ)!–z—Â*©rUçê¨ÇyxÎK¹‘²£.«ƒêšo•;ݧ|/\›Oø©&8›ÖÒ?téÓ†”›ú™ÄúþÕ˜©añ¡± ŒŒè2Mûn¦¨K†ÑžÄ=+Š úb‡€j¤~Ûƒ`>|n{!ÒÌhl½J»3´pØþ±×Srz€E ¦÷:‘IX @¬~xƒûăªÝ¨%ì¾y•­fó&2)k˜qâ“fËT¸¢¸[»BøC¼“@Jd(¼4_bìo7”QE¾€Ø4(L€©êl—û™–\o¡Á ©k ÅuÙ–€»‹TÛFU>$„p·ëf<¬ÿgMþÆèähêW··•¨"Ö €öß¼Fœ}.á0¸>§}ªµ­"£Ä¡W¼À¯êX'>ÍáµoÕ]s” ™Œ­=Apw‹^W%TPëû[` ?€|6`F݃°Ãt‰&¢iâC£’9ƒrlÏ[€M˜ˆÂýevç‹ì’yŸªÉ  9uÕðþ¯°V=‚ËX.c§ fÌÆ_ªÐÒ„Ê’‡?×€|¼3܃݈o í¾ÇÔòîÃ\R®¦'ævÈÒÇ¡{ˆj9\µP¡¯ÖárKÇ™ªÅQʵ:ɯ€øï |3¤#žË!r„"À1ⰽΛ¯ekYJGbœ+-U`ÆÀÇ;„>¶¨»²‹1 ¿ ,ªþsÍ8<ó]·\Z˜]ðn™O3‰ó_A;æºÿ}äg0#4Ë[÷ƒ ²Ã—<›Qþ}Y"úÕ~P.·^$ÜïQ%¯üU±\î²Ræ¨Y( wÒ˜UË7§Í¼#°aÞ‹Qÿÿ©³õ¿#§ì/n@Š>_ž—)•®t »õóþ¸0E½¯X1q³‚ÞJ¥ê|âÄå¯ ¹SÐÌ‚¦Ç=D\Õ÷pe³š”éÞ{J€ˆak‹Õúc²6ÒÈ7ÂÎå„ñ Ð.22±µ«}@š­BÍ玃B/åŒö¼ÀC$Å^V ÈQ ÖRp(.nd!kOî± ÙZH»á<…UÒôÈH‰ õiáKÔÿJsg§ãìrm“F"U­6ÝÐjÐío!†0"AðszËظД0–šdzHùþ´¶[©O•ybBê$›uv¡ðjóݹRe ^ ÒS©Q6`X´=Ƕ¹æ§~™%Ë‘†fZ”Æø¥+Ò§£€ÙÃHŒU€:;2ÖésÝPÄä¸÷v7벤3ü¨_¯ÿ*WÑìÙ¥×Lm4Erű)©øð¾.£ø'{'À9i¾´êèb;M{ÀB!SƒUEþUyÞñ±ôAŸŠ"¾¦$ÒïíÀjꢰ/¦š¯:!‘“ö‚™%í¼Ævè]†hþŽóHþ†Î´çî½ÁßËïœÓº¨U—Œÿ¸Ý*¿‚²çb{§óígžûô÷«Õ­“w.^xãíî÷&óWþþó/Ð5٘ͱ÷v6 À{;þmíõgê…éÅIjt­° ò¯`_,O†ÄÐ[ Ñ¡æÍYŸÏjdÀŠ5ýJ[þƒ¤Naß½Æm 0ò$Rü"QH¤Pª"öÊô$¬´2‘ìï(5»ÌkÁš:b“Ž#ˆ.ÎwkCJF¼r×>õ~tÐ+E[¸&i¢,Ëó? ‘‘Ô=»GAÔ£z™º¸IRÚPY+}æ£øÐ (iêc`5âä%$òFϸ#,-h/ÂöM]%bøÌ¶Ø¦dv€ñÀ¾­ä.¨inPC¡³a”Ã=Û µñ`¦€p ´ë«Þwù-lû-mîÜSú7½*yY»¼8å( (~•Ê0Mb} hæ~˜NVuÊ.„ž;ô­Íi^›¼ŒÒœ-‹™°¶•{@ÙU܈OZ¹!޲`%*Çø˜1 JIáß(Sí÷gŒ§ã>÷aŒF\H¯¤gioTýp¾wÛóIáâ‘Óûü§ìu¥š<¢ é*¾ã+ÚdS³Ù†0=EþX%·}\ª“ÃFïÜÉ éï{`$¿{~+ÉG=ñoÏxŒšÁrÔhç·|}‚©¢ çMí‚\F« à¡ÙÆ×õc´>oÃ$ôëê+õ¼|¾Ýi¼uõðàAsk·ûé×ôO™Îìù /’oŽÍ¼÷#°aÞû9øµ`rñV "r©yv¸èí\œ?hCxÊýî)fÜYÖ:À†Üng“vÂ亵o Õò’åti1(ËØä±’» Aô#ˆ£éxšH§n–¶d‡»%ÄOªÎ_8¥pŠÄZ r†ÆÀÀ/‹)žù¨J,K+Bé ³!Û— BS*ª”GØàÙè&Á½Í•Ðô#PWý 4Âpžƒ ž„C&M•6ÈkNàÕš³û¼K¨KìY/aÞÙ®±/;Rw«Axú8jݾÍ^Ùý{„=¦ R…Iklzc Ph”Üh—íãO¤Qó!£€ÇvŒ™‡Ööüpæð Åëº{Ãk×àGì1öQ$Œ@H¯¦­YaW† ÚÔBëBƒ´Q[ÿ˜‹)šû«9Ä5(²)æ•0èÐæÓcÿÔÐÆ[Ï5Ø}6 :?éÃ|Ðn–­E?hþ9&´Ôãøš3$j[©ÙÆÖü±b€t°s®\±+h‡c7F3⎈vÌÃgO ¢ ä|d:"Ž‚ w‚á ÆPvEÆE6ˆï³ÌsÌt|“áuû†$¦Ÿ)Ò"š-îÔGmÐ~gJúïÙ¦¨L;b,‡ìü§ÂÂ9à?峜–4†n¹U²ï6Çá>Ò¾2é÷„±ÁëòèÕÊ}V\\{¤óÇzý´Ñ~üû­Î#gä9:\6OênÍ¿ôOþ%à¿96#ðþ ð>š«ð'?ügÍy¥¿=\,· ‰íñtØö/Š`zaõ(]'G·"nöKD2ƒÕ¨fv}z©Òen3ü´ù+©nVè)`®w¾ak¡múìÅs%°Ä_T)®Â|1Œm¸t";!ߌo\úæšèñrÈ‚ÀQHVªÀ•WkPRAZ‡U/uõ 8Ä„€Ëâ+Õ…¸Ê¨¡0‹õ…dìóøp_Ð£Ü 8”>G5ä<üç 7>r}¾ PÒ‰Ž¦hî˜Ña¯­@| Ç0Ë^<Ô)L\!è?<ãE,™¦Ò~U»6î*bqfË]™œ-buÂSâ>õ®Á$V_PgHÿÖKÑÖ-¶†fÃ9  wŒ œàKóèÕÔõû0Qý>à^`£$¾0Wh2&hø-è†7¿u0¶ÑWûÃïø¶ÞÕ\8?IËÓtÞl×|Ò\q0òef<¼Ž‚=GãIë`ð;¢RZ´7¾Lã¨ÜzÒû!Óuª0 ý&Ž9–Ñtì=BÀÜ)ñ§˜&·>ÚÏGÆK3ÁÄqã÷ª«¼[ÔEsýÄ”ò[Á|sÆU'@˜¦Y¹Pœü½f½rÄrÕó+Æ;­ÆÙõ~ôï]dõ¬÷ùÏÿgì½ê@jÖæ{3ï›Ø0Ȳ?ú“ÖlT‹5ÞN>˶¹WκYý¥×_ Yè £6g‚ô\žf£ÓS–,@f‹Ëô®^»@ýʽӬ{Úc9jP "ƒ @J‡®åVkP(Ë8˜±yvù3„uIÔ@1¢Õ¬”°q"Í" JöìôA¨FÝüGpl¶<·¨Â \ƒJž2sÀ*ç,ÃáÍ"+a/Ö!Pß„¾¬啘ð¬V<ƒÒº¸LÄ ›<ù,- ` ŠÓ@Ì¡ Å6—Àç1¦5²nËÛ'ð›¯\ž‘œôI£÷˜@HìšÐL„­—`“œh„v ê|¬Ù8‰Åµ`†èc J¤à}cíWø'8øDÌѼôW—‹Á@Yg¨Pgýômi@íg´OûÌq±qƒòsޏtHÆ`ÁœÁzdý"ÚŸ¼Óßà~vz¿‡/öÿµ³$å,Ï mc,ªÌf„zÀZûá0 $øi˜‡›Ç?9u¸SšŸ2G¶161¢l\Kâˆx ~ÿœ 8¬D12¶Õ]' ">ÌÖBÔ”‘aÌc¬y¸d9(ãÉ91ö ^q >÷°½‚;Cëñ• Ôã}¥w‹æ%µhoñà†Y±Í2F¾Xú¾˜Gm¾«)/Cl›º I¹µr“—v™ô@IDATÙwDFÁ±r3!Ã÷¢¨áï­Å^œòþÒE4$ó*çívþÎn«q—P¾wn=ù‘¯•òÊy¹ÒûS¶sê;yo÷ÆÞôwꛈ~ñæxߎÀ†xÿLMaZîV£åMìOŽ&£+½ñ¸ÞíÍóóc¨-Ô¯Ånx…Ð CÙÃôþŸ³£Ÿ’R½`Ë$mk3'íJà²=Uʦ/ÁOÿ‚µä®ÝŸ2–Ž}˜9?ÇgÎoº¿’{•WoUÛÚó}(sd_ÃÉ’Ê\R¶}ÁLp%ÍL†Œd½³Qvy2$ò›>éŸ@šH`¹VdyœTWË0ÍLÆKm‰›bÞlŸcÎãEˆºìÊ#iÒØÊD…T½:øÇ1h¿‹NV€˜cÔ¢{“˜Ûâûe9…FˆI€m(CÃÉÖx—‘ΙçæñeØŸ`œîk–²N9Á(‡6­pß›d¤¿\ÅÜ1÷þ¹hŠJ5ñîÐwmüNËTÕ/ØÇ¼›ÞwD&1ZÈxæÒ}²ˆŒHì)^íjéôZ§zgk«uû¹g?õ#öl¸ìNî½ó¥ÿòa5_ ÿœÏæØŒÀû{6 Àû`~Œ÷ŸïÿÕ;¾wÿì¥ç 5Ÿb½ñ5ˆÎþt<=ë $dHôCÐ!±¬±ÛNSªŒmº$h‘ŽŽ(*¢y±’Ág|˜Â@¡ÏHlè#Úâµ;Ô+¥kаms9ÓY’9^™‰d®­ð¯HxO}H§]>†Ã¹ :·œ w,Wm1È“irÆÕ16 Ÿi4¥ͤ7Ÿ[@{X–þÇÛóµaÈœ{ÝLžåÛþï¨å¨%R…ï»a¢2W›øÎ*ù;„úm¢èIï!¼s³z+;¢1ãÝvëÅzž_n·:ß¹z呪Õö þ0¯–ð¾ü“7“ýÝ›øÀŒ€cs¼Ç#ppp€gÚñq!ï÷û;8Îí³Îz›U~U=ºÅ¦T©^úÀ(ÉIÑ8 ·ÒǪ¼!n:¥ ÞS6¥Ñ^«‡´à¢ªÖ\á­ÄYt‰ÔSé§„¼¶…ã õè¡­ýZÂèò´Uhà ;Ö‰†S ÊûôXf´µ(c<i4©JÊ„S¨q8ÒvÁ\âLÔ}€´TÎeUQíg¨7ÌÃõdü:`ɬ4È€ÔÚ6“ÜVy(ûž6çPôš*ÕýŒ‹xÂÞñ×Sßê~õ¨f­d”aöìCž(ߺ©Æ1µ]iwÚaÞ¸gßx¦Do n¨¯SÞÔLË# cgÒX- é‰ Ç˜ƒ'ú=d ¤Ÿ ŒŸà/8G»œêÄBê¶Q—!œ¹Ñ/X;LŽyb>Vg깸g€cÚ^X“Oj“ZÄ´¤9<-#˜k¡º5Ð:(޾ác5ƒU0f‚4¯„SzÏ‚3Û¤cž žÎܧr‘Á²(„cõª“ѼܰŒx—÷ø„?ÊcNaæ<¢»¤u,#ü,ÚÆ8†Œ—uÛxÁxßePbªI!g6ø¬!s;èlWïom×N:»ûo<ý¹¿ÿÊîÎã—ÿâÿ~åäùMüþïÍ×k6 Àû`¾J7ŽvãÑ¿ûÔSÝÌ÷š7YòמΊÕ9vð ¡`/Æ´©„!œC¤ñÂfS¥ß9Ëð´w*.—ÐAšêa>nZRC*,¸Ñά ñˆ´Ì´s3T(¡šÀƒ0¥Aõ†¨j]V8ˆw¡+ç,7ìb9 ÏܤgŽŠt6•Á Åè¼õ4ßÊíYG³ÙŠ!@p¥~ž¡Bއ+ÂÍb¼ÌÅ„4{%1Ë(¬’@™…Õ ‚würiE'ß:Uù jEŒrvé/!†ú~‹ÝôØS@ WÚ_Gê+€~æF):f Be鮊ÔAâV`¸ö°~oŠ·ŒLŠc´̵E;~¶É ¶ÇN¡Õ £€kš\bì`z<˸U±å„>ÝYôð3À pHØÝµ‰Àú]{|ÚMþõe&(L äôv– + ÀK¾5Êxè“ Ð»„Ò Jñn¨e¢™Aó.×ß8zÐ50«²Ñx`¬‰ñdìiQÒá;!À:¦S3£YIÀ̓¹Rs$à Ä|›Îzü6}\ó% ¯Ž5S PG²œÎ{È}‘AgLwªTŸ¨­à‘QcÌÈ@“â°.%þ6›82c»…(faÁJF]Õ²tL»[íoò¾uÑ}†ë¨\XÞ©'…R{ øÿ¸q©èÍ÷f>#°aÞÓ4šö:”߬7Ê·®å·®Í—ÅV±Dü°J@,f÷.ª¨.ÇÙ›¯_H¨–Ð ü£J_‘Ì5ùJ×c· ¥>(Ý¿ÔV§:` "È5é$òK*¶†\J=DôV‹nyJšÕœû´Aúë<ç&*g)ïˆåSÄVÀS!•×yÏS L êZ”$,DAëÕ†/àÅR;ÒjCw»]¥´ ŠiÔbx„”È35DSãפø«ÛÌd†ÜumŽ$¹<'“Œ(>–®ú±Ûç0e´õ]@BÉSÉiÑtá@‚˜O#>“@$à'B_²:‚ß„A˜â±D}¿T‚¦?¡íଆ¶gûaš9«^wúÒZ{¤}Ã<{B MÓnbd´ôopN„@Í21‚ñSÑ”x'˜ónÚEƒmSŸ9R"g«‡4önÁ>SG— êĨVƒGÑIÇ8Ì$ܨñŽhw)£Á—L6F»äê ÍB‚òZÊ–0 UCÆr,Ò/ZÌx¦Ujg¼/“±z €©âŸÃëÀÇËg“bäã§sKÐÊèc̃/]¼–|ñÐ J29¾B¹>!¦ÓßBæCÀ€Q¼Ríº×ÉafãO²\ôÙm‹vØ{ëñ.nÜzôÛ­ööé¨tñµáßzðÓ·æï|ë?äMûŽMO ójslFà4à}0Yõ|–ã¤u+îa‹•ôËBµ\‘Š%ì¨ïsUì³Ø„B­“À/Èë4êRD>í®õãPg72šŸ6ÙDÀWosu©ªž\Ê]2î>'zètg]®Ñlô˜ŽõÖT«Ó ´:6­IɃè{Ob*H»!OÐs²R¢m£Ä¸'Øz‘ؤ˜.«óVÀé•b.™øR¾žê¥ˆŽgÅ TjxãÀµé3™! ‹lä Õ=}dbƒ÷”ð}ã¥ò6E ”úôHŒåÒk 6ÎÿêŸ ¦}iÔ¸Žƒ±¡BC‡DL8âÀ­„»Œ‘y”Ú]s®toú´Åq_†`†0ä ?ú¶wÀ=Ôû€¯Ñîü7ÇaoéòOÇ6ñeÛ<ö]`ðÄWâűM2rÖ)¯"ð-`ŒŒ9yOb¼’] ž—OÒ9—îA`™n‹ ù}&óàÜdJóƒå¸…°uÊ„rt´ô}pÜ<¼6Ÿ¥; ž#³§¸NSc>Œ¢8ëèj|/Öéd:|ÃV…>,Ð×È×Þ¿Ç=LÞä øc˜~r˜>µ"jèb¼‡,ñ“¯!‹/J¥ïÖY­Ü|ߊó¼Ùx³Ù¬_“±ûßÿ¡h{<ŸN›ïÍ|@G`ü&®Ù\¢gö$Hôh=?ØEÐ(‰^lgù`œÝéá1ŽÃ×£ÑbŒó„­‚ÚZ)8À´{ç—¡ŽŸ_ö9£R&zœ;Ø)–»¿¼Æ`Ç"2¢>Ž{Jk%Mïëç~cá«ÊV*”°ð!ÙJ¼«¨l¦þS´‚gJê&*ÛDÂh ¤ÚÛµÝÈ• T¤øìJ›öpÙF-/8Qc6qhíüçzkA1¨=ßú¬#ˆ½ŠyÚ±…â{Ï_à 7LGš7d`$ô´`ª ñWtÓ|°|%BÇh¢< çmã ÒØÛ2€+ €q ¥³-6†ô25ë#€àwÛàÞ1žúxé Htn¬~´ £. ã&€%Ó“€—3EN÷¡?ƒUðÜ6Û·V³ŠÊš9VíŽFÀ/.Ò¼¸š@pŸNÙ0ž±ä ©Üs–&ú,‚-qÆ C' ;æzæÓ[ÎŒeHÀŒQ߇ÂÍr¦#ŸÏóè]šGÙ¬Ô@«u0fqŽ÷…Wj5œ–+èSbX¬K @ £7£~Ázõˤ=ˆ2¨"ÊËá˜é~Ûùòœ§<ÒS¡}FŽßj£|u–íirLIm»\V(Ðjâvƒ)KGÏÔ‡å²?š`xÇyµúVk»ñF^­ßùÈÇ?ÿæµÖÅb|ùýóãþ¨×úcÂmŽÍ|8F€?ïÍñ^À׿þOë­Wk“åp’I*Õ Eö½Ã­Xdý6 ÿ]_î6ŽJ“SvoC=ø³@º]B|½ž‡úX&AÀG"U\ûÙ‹ˆA,ƒtCðQMŽ~” ñ\CšAƒtÚ `„XKœ(³„v®I€"´w›QÕ¹š%DÕæ‰à Q™„Ò8ñezËá†ÚÀHé¾ìžÔ¡×½ è¦<2k&@À/*ªYjh3üMJ˜RvþƒIqxr‡CÛ%(¬%|•,S2¾MI}d žÀûô9N^záÀ{Ø8:ãÁ@pÚ™¯1ø”‡]öið ,ð»–~ÌZÿp$¿*rû­äíu )VPµíiKÆ ÊfG‚õf‹ªÁM îMàüYViÄ\qßòm_ õ›Ú­¥L}A¼–© ûñ>){måžÖóá:xÁÑßµ`½JÈ=494~ýϼkF&J"©uØ%˶\zãåóxQÒE|Û&ËHŸÕõz-‹[~~úb•Ž“ÓSB"ãWØ6³ûq fü½PþZ“î§±ç}ˆuþ¼7Dñ³ •dp (¡–ÅKò³rù~%ÏßÊóÚ½ÃÇŸº»³s¥×í^t¿ò?<¿ñòw 6LJf6 À{8•…íƒç†ƒå§gÅúSã|¹!º^š7J…Jâ_ ›÷þ1Rö˜¥w—ÇìÀÖÍJxƒ»“Ëü€íd—M$}ƒÄûÿƒÛ‚(" ‚ö’Ç™: XÎüŸ!õ¨4F9Œý]ÉÈåj¸áq&¢(L>$ΰeb mÿ€1AÃ<à†=ÒHée(~•²r©?R|ï‚ôg׉«Oe· ø¨&®èvo2vaó܃1p¹š1ñËHžÚm5Gˆ n6£š™Ü´Ê\´M®´Ï;êÄ$ŸÑ‡´£Ÿ`Gf?”ï'¨¿ZÃ%—ý€€2!Û‹š9âLÿ+nF½K´* mHŠŒ…þ~ÿrˆô>C"7>œ zØàW}ï.y¶5¡í C‚tͲ¯™bÆ^‰”qàw³ÇJ Áw—]Ñî¹ #~Öo8P¾y;‚wYÚÉŒ ʃԫtlÝùðš~»ùGÕÐ|ìáêeóŒƳ"Ãɵ©ØÄyá²DÐ Þ˜5þÉ|xDÛXØC‡IÚíYÕ™òF‰´Gö‚;¼ßN{ø¸Ø>ßmâ(˜Ö(*÷ á «í»®©„(€¸,áìwyõðð›y½õN©˜¿\jn½P-•õñðZ7Ÿýîü¼^›c3ªØ0ïátbK߇~ æÑù’˜es•롆Ú}DZΡ¤¢ÒÞ».höå *~¥ýa—0½0ƒ®!€‰u+À·TäÅñ3ˆáÀ6úKëƒ E X%¦b]žÅÁÉò•Î r‰„e ¥Õ¡z%‡”¥Ã[H_Ps}Ô,hW—kϵp%Yh0 i;µá»DOp œA˜ ü"Añ˜À”ØmPÈzôøæ?_”m%Ù¨2%ª6A$1™ez$|²4nÁÙs.Ìõ\éìæJ ôF}"ñ1Ý‹þSÔþ2ì Çú`\˜3™Ë ž‡Æ$íÍarâ4x®RX­IEë¶ØÂØ]qÍvþ:>Ww+œ}h'…vñø1i~¦|\9‚É µ·Ž†|âàä4ppó¼>°Áضô±ÓÎe úþÓ äð¬còÇŠ…(š†ûrpø\p¥œã]]U/Ãᥠ€‡Pío߱ع6´Ãyâ òN´—KçŹõìtxöògÙ™ô±LçŽ3/VÔ(—CY:ýÉÔaºšŒ§NŒ©ž~£Å²tŽéd»½ûÚáÕ[¯çíΫ¿õý/ ‡Ãù'>ñ ],7Çf>”#ÀŸÄæx¯F ·œï@û[k7Jyƒvƒ€½0% Ù @ 86·ˆç‹ öàÖu4}‚åœñ ¾wà‰r0ˆ”}Ì•ØË€‚¶}É ögµzŠ'@°ä·’±¶]ÑéRׇª³•ÔëŒNÀ ù‡Ò†9öá°KkG•8[¦@„Ê›âd(¢ 7’¡ÏŒ|iÅòD›ü ÄBóáRyÚ¶[Æ€’£ú$)håÒ ÕÞ¬¶[‚ï?ö!P“Ÿmµ$ì¤zæ+ég¨šÅ9Á\bëy†/€ V¥Û »PWðp¤`™‚5“@.‰4‡r# ÞRlˆ´À› RH€ýR}6̆€ v\Úlm´yhËg;Û;!6>[%ÓUØ$æ Hõ¿>dñ’Ã|(½Û™«ú¤ÉAé1J…1˜£QQÔìù޳LU030UÁ0N29Þ ¯~Î룎S™»úÙf£ íR„>x:Û¢¿‚µ¹î~GèYÆ®ÄÿÐÙö Þ=´ ª¿Ï±¥¨…°ë27á ¹2/ø;¢Þ5-—>ÐÁÜ|C"ù9¼"w´®;f^Ó­¸«¸'È3=ÁøØ>u·Öy¼ÙœS äá{Á}špÓËkн˜GÖO˜@âÌudàÇêð¹Çš‘ˆ2üMýO,“O¬Rà"ê§µ «p¦rZI ã[NG&I¦§Ùbnx—LÁŠJ²Êi9¯½Qkn¿ù¹ÏýÞÿµ{õ±—‹Ñ~÷wÿÛS’püQ:m¾7#ð! ð+žÜ?øƒ?(>ùv¯—Ë:+ÆØÁ¯Â6¾øjAÚÔƒÆm_@ù´kOž)!}g n®þ"V,îAè'!åÖ` †]â\°Që²§ø H½Ý–¶‚2Aµ»¶nHvb*$ÐH¯Jô¡É…JiB ¥Òæ ÏˆXAü}î‡|’Ú Â2 4Uµõé3­ÿNÀ(±JÇ)òxŽC‚îG ŒJ,Ï/%G%6Ag‰:*¡ª–“Ê‚t\±÷ '"XÌ0…Ì ‹ ð+%[½¼-³JÛ‚ «LEì —`r0ô'Texã%ù­Š}n`#ëEÅï!Ó`]ÉÎ-ÀñŒrpÈlŸÌŒã›"!Õ…NÉS5¿kÞÕt#úhÞè(éõ©0߀úÔÖ(±Úv×äìWÌ“ÆØP‡¾j`"· ä!‡jgÎṠ±|ìÜyxæ7ERåøL¤æ·÷£jïÅÇ/žÅw°qÛ;æóýðcÁÍ”"•a6ŸÛ/Õéá9Šÿ‰û‘èg¿¢Ì”×&šy]ÞÃ븟ZfôFÑë¸vNÔ&U|¸ÖÀŸUÅKö˜•ÊùJ­ùF%o½ÅHŸð^´FÛ+}ÇÏ6hó{3ÎØ0¿ây}ìŸ<–WO†¿¥zb8.|jVʱü¢ø5 ÷ÏF>hqÚ#`6˜Øà†¥eýS0c‘í\;þáÅüQƒõïãcœÐN²‹£» Á¶iÌ,\¢>oí`C&þ=ûÉý'x«+Å꙾pP%ü (þ!sí9¢Ù±™Œ 'ÈHTIЪâXˆD Ì åì'¸‹ËQøÀÅ$³ õ OÎJ¡Ñ”¾H´U¿KØ €°;ʹ9ÍÏv w®ö¼5‰¬ãìGbé»þ”3Âö®Þ”øôE˜F.«â5¯F¢¾r¬£÷ºK RÇ>¨ÆÆGä÷0fjyµ%±™bN®Q²“ÂV¦Ã¶¨ˆ³ã@וî5“ÔÑ6XNø[¦ióË8²aSGã øê9ŠvX½8ó'ƒÀ ˆ«Þ¶¼8T»0˜$Ë"eئìÞˆ÷"šk™7U<Že{¬x ¤}ú&ãÁ¿¤P‰YŒ´³hۺϜïjLÌ#S ë•3±ô-œyôx¨ ±5«æ{ßË`ªV×Áxx²=÷Ðqß#úGVIç°D>Úe| Ç~)ÆÇñƒ+ ©¿¢1 Fl‡­šõGpC+žÎ'¥æ‹³bí´¾sãO?ö™ßþf³¶sTÞ.½6ÍÆ_úž_VjÃæ{3ö2õaïäû¡´Â7¾ñõZÿÁËÓòt Zµƒz¿ ;b“Iy$Òá­Þ=XË]î°oS@©@xZˆêKh.›Ûä,„iÕë„ò­‚˜•öÿöÞ­×¶äºï[÷ÛÞgŸûé{“Ý)Y’ –mú’Ø2R‰C>Å~ ‡–@ȣůáO`ÐOF;ö‹,ä"Ë íÈ%Û"›T“j6û\÷}¯{~¿ÍZ{f›f³›TšµÏœU³jÔ¨š5שÿ¨QU£béŽpåÑÝÛòHÄÁ ¸j[Õ¾ÝyíaHà-¾¸“ÅzæÝwTX¾ 'bZ°Ž°óý;0jØ7¨åÈQÞ!“ÔK¼2^ÍáL[ØÛ§>º‘eQ¨£vw1¨/¬xWÀÁyøø6¼ïG½‚* bÈÖ…‰ VÄ£e³Ø2u³~¥MlO1Ð9ü:aœü ½~¶@§àRêPŠ£ˆ™×Nñð…¿me‚ñÖ#[5 h¸FPÍDm ¯¼8„jüf…Wœ™qYÜ)š¸ŒÎ}ÎÚøRžH¥1컥œ&ŸYªó÷èR_ Σô’g/¯|JdÍÝÐCk¾]™mr]²$\Ú¸‰­¿ ¯ZnÉa¦Rx¾ï&o›Ãçd$ƒßI+„^jclO¤ÒÛG±=:îö§{Ã鳃é '¯¼öêÙjðtñó?ÿ+þoh]Û¬Z ~LŸû7~ãË“îíù_.ïÜ~úôþÂb½xc|8{a0¹u{Ñõ ÷ 2³·tWüYŸw.槬ú>é|ûí¯,ŽnÝFíŽQ&GƒYgvpÔ9šÝ@Ý?ì¼üÆlK;î<|ç£ØK¶ºÜî“‹ÞÙ-}ްTGÇf€Ch— œ«>gèXÝ7¹=Ž/ȉQ/ <$u¦0ONI´ÃÏü:À)‹ÒŽ™ÀæM§\Œ³0BìÜãO†eæÛå‹.–ü} Yx—µüÙ‘KN #k:n–íÈN _h^W0lµ™WF :`ªã«çƒäV8¸¢>úžœ—wa$ÝEØq1`*eCGY â‚zQÁ+Ô”úÆ–¹|ß)•¹q ¶ƒ€£c FÔóV¤nKáG¸ Z òd"Ì=Îú™ ÔJ¢éÎ2ˆyV;Šƒ’`|#ôdûóó5Í:BdSûNLmãt†#95é \¾FiO}¾)iåj¾饛ï)2…¥™uM¹ .–žÆ¶âDTÒ’‘gÊ)|©tágœ´;úÄ\ß"¨Ñ¼Éß07¿Eéç}“®†I¤IЇȟ’—B„óýˆ`±';ý˜ êO»½Ññáѧ¯¾ù'žt×ë³·Žç_ü”9[×¶ÀËh€Ógÿß~ï+ƒÉxø Pyÿ¼;¿ ”Ý÷ÇG‡“nw4îlÙ’æŠÿSN³q•ùéåqçøô ‡¹œaüå êLlßÖãΘ…j9Í©zÚ+ä܈õ0- ‘š ŒõxÊé‚×ic¨ÈsæCVÌ÷XC€!ö±‹"ª˜‰êœ²°¬t¤N$XjéÆ]dv†Ð‘¸¦'wo¼ù,Ç32÷Ž‘ý:*öP6,ÀÅQqºrziæééé=cµôøŽäü¢æö“d]óm*p8b¥ÙngþÛŒÎLjPSL"ºÞö…åœ1/¯:]3È‚_FÐ8úÍIж»|4}»ª½ëÖÔ#*t)PQ…0óYf8¨QÐY*a»–õ ¦Wi x  :¿—9ž®œEí7ÙÔº&P—újë«+¿Ú‘ßDþ(_j¬‹NMNu¶S>bŠ¥­x¯T|›Íoë·J­Éæ»hë@í•Û* ðûmÑ X›Þ|ðíápüôÕ~úÎnÜyxëö­Õ­Þ¹swþ¹_ð0ŸÖµ-ðÇ·ZàÇôí¯ÆW]¬ùaó{0å8œÑjØœÞp›IKºJFÓK&Á—›9[•°o¿ÂÐ —ώΗ¬üŒ õ.hsO³ýa0Îå"<× ¬Ƀl=ºAkïìV3;Þ­z^zVAÝÕó&ÔãöÙ –¦ à(ûƒ{µ³¶#/§È^vÔ ³*Rø< nn+T]4Tð¢ÓöŠU7bíO ™]ø'ƒüÁ$‹æŒQË PVË!•8!¹#~E z¶Ü͘˜áëÄ+§ 6“"L¸p°Á¾ø KÔÄú}ÚÚ:¹ÎPõ}¡„Õ˜ðeù 唚Á“ºìÉç»zeN>u.q‰$‡Â‰Æ‘tQ®’ž5|âCÅM¿<"âJ Œ+|¤ ÏòÈWË huõ.Ÿ²£‚å(›è§]Œ+ÄM"jaÒ4±å 4„ÉM>™e™å%*ë÷§Ï>õæŸùæË/ÿÌÃñøâÑÏÿüNve´¶þ·@+üˆ?>rïŸÿö?ŸþÛoÿÛ[ÇÝùgéP_šNGw@°i<²Ÿ…öØð_»}í_‹§Yôwqú¬sqÂÊþ‹K@Ê)J ßùóÅ{°ŒÂ†ôzl!Ì ùÆsV¢cPP:ÁMÐpÓ+Ú9 ú9 žó36œ¨×¤é¸íʳw½t·§éÒßs‹*–<òs½Á ¾yk˜N9£o%x8 wôVÀˆ‘úoÌ—‘¤ü¤P€1Qµ»|{w”¨¡ ÁUu:~G|¯àw®uDø°½2õërŽgißÞøÔÇt ê!ìX åO\ì»ïŸòÖìŽp¢S/Î ‚ Z 4’#øÔ™°~LêçÁ:f(G¾;iÑ€è§+gêË6ò‚9 ¦náÕ´ áL/Ä'9EZÊ”VþÍU8ìîÖEg[V§‘GMçuaœõ„Uù^ ÏÔ‡ÄäiÊ.f0oI¬ ï›ûÍ70_öïKêÔ•ä\»@çKèQFÞMŠ´5£~’R4´j)¼øÉô™ýÊï ‡=Q#þ«Áhv9|çþƒ×ÿÏáxúˆ]·o!\6'ù¥¨öÖ¶Àëh€ñçÿÊW¾Ò__¬g“ñÑÑéöä :¾—‡‡·ºýÁtÀÉ+ÎÑ ¸«­+ý9Pæê3¯¨ð1-{·r¬¯óúEÐÇJ(µæ÷͆é:ÎÁ€³†ó²€á¬gµ;¿bô?P ãtÄ$¤ Ø9)ÕѪ»ï2jrAŸá¾s{ê(Ùe qË>:#lrV§Á› ¯4„sû–ÖõX„‡@‘3æÛZ5ÖÅlʳÏb‚‚8…Å•5eQõE2¯[G÷!£ÂFñ‹&Àµ+Ê“¹ i4HŠêÙw§-úŽ")ßú¥lÊò̃>Jã: 4YÄè òû¾ºLÀ[M†sõìI°­|-鸙î»e­Eò7 @ø¢1€¾¤vMˆ©-@NYüN:ËMYiû†—$P}_9Îä†$6x¬*ý2Ï–sí ±‚Eûä»Ô+e¨‰!^¡(yŸË/§±«=tå;©IʉßKʃBx¿®Ö)ïI-øyä|vš)ï˜v(ÄÑ Ñsyp‘£~­-úÝÕÁÇÝ"_Ýz6¾ósö¿øÍÙìΓaoýÍ¿ü—¯.ºÝvÎ?ÞÞÚ ZàGü3x§óÎðÖ½þíû—7oŸŸôèó¦Û1ÆÐc$ôWª¨Ù›Ï1¿k–jŸ3ɼÿ ‚ÀùÆ^˜Œ@­U¦õ؈Æ´Gõ:í³ê@O8ž °mpA/éˆÓ‘/ ³.ý£½)Ã9t¶„]·çÄ;ïÖ¶,ækÚ%€ÃmÒ´ ° vä1Ö¤…‹ðù5%ï(:‚g‡"#kEŠï-\šð6š…m³p(œ· †™*àY¬(ba_™—Gm»€2¡¼Ã"ŸÕøl½l‹h-ˆ €ÁÝa«jÁqÞZ3Êú ,¥.xõ»VÀü‚²Îi™¤ù`ü-PàÒY ßÂzŠfèÌŸ$>q4MÑPkh|/yZg*›|)ƒ ßQ碻ç\o|K/ÛEìÊ®ù‹›~mÇ´ƒÅSt-«ÐËÇ7ºæ÷\wÐìkF™ø d)¹x׿ţ 0éºÝ”ŠôÍ;+ è uY©l™%šŸ¿ÿ =]ö‘‚G£ñ;ÓéÑ·ÆãÙÛ³ñÑ;·^8~çß_t»ÿ£RbëÚh[ iVøÿ^~©3[ûŸ½·¼ýÂüðÇþvÏæ á†Ãÿ>jsÏsöèBÀyç»ï|“óäOs FiìWZºCŸ½b:`KÎù³¿}Ìçvç;#¾â!Ûž£;·²êäñw³%­‘mËÛÇ€Òeá_ôÌ)~ ýïD®ò_r¹Mt%žÑÃD á_PP;àœ®7f¡!2ëú§júj¸–£Wg.>äfŒÊ‚h'2!¨˜ÚA`)Á:Ãt*ÍB# ¥óô<{‰&suïÔ§¨Çêà=šôuÌNF°VL#?®/žzÓéY<ï¼eU¥D-@—˜g´‰‘Q  Â@\¦>Dñže¤K°¸4rj•µ‘,ú‚™eÖâß}ü¾£ÂE’ñc¦·O#mw1ÕrÓ²iZù¥° a¡!=.@܌ȉPm ³–Å€ES˜Q®ñ÷fóø¾òTSÞµ–mãÛÈr7lL%P|î%†:7mrâ3C!VËß­%Q~;NYE!.ma¸ü®G7\ï0É´ÏÁ”ºòçš­æ³_næh¡®Ü9xëèèàáÍÛ¯ü›ÏüÉ_ü—´ùS~›¿}óætù§ÿô/ûi[×¶@Û{-Ð {ñ£2òô››ƒMÿ&óôC:Yp›a;£ûñ=Š|Á2ù«Ó³‹KNšãDž,˜KÈÍ^°[¡Ú€Ö+: p`.<”•õ÷ÿ³«`À²h·Ú:²2°v €rûöšÄi°G˜'–^¼Ðdì­Eã8|’|RÀ0`yË"¬6A¼ ÐJÖäñDCÕ³:­:úÃ0aÞÃynóXûæŸì@R%_Hé\‘nž%jû€»íbÆ\ÒnÅ‚`aÜ´]iÁ§ ¬‹p#J™;šòÚL4MyNšü¨‡,oŠRca›eó¦•ã_q¤²<çcJ L~ƒy'‚ßãä­3u©×.Ï®ŒRùW^N×Ôp-®0+wë¯{Îßã'/ŠŒ‹ß„…wÛÓ|áŸ<ÜLø>Îì•O}ÿ”M‚š ÁÝŸD Fá úÒÛö~ŸêR.é®óðÌ*4(pf{£F‘Yfƒ5‹þù`<~8>8x÷ððè7ßü³ˆ`xöÿãùÅ_ù+¿ÐŽük£¶~Û{-Ð {ñ£¢þžÑ™†Mÿ÷§Ýîkg§=Nëœ_œph Àpzú”øŒ\‡û™LQécÆTMÀÓ‡ÏÒi^<~ èìì×r˜<ëß‘&fسgÎ{;ÌÔÀt‚ Àº€ ‹=&xÍa2Q«`¨ÍA:Út²v¸,ŸS!‚\Îó3¦ú® Ð7CÔÑ"€™u³é´=OPí:`çM’#{3F傃«€I tâ–íLF’) ˆ‡K:ö€Ž*xò”龃l5¤ŒÇà*Ôѹ;"œNp.?ÝœÑ¡Žš¤>†|Ÿk¢Ô:”$…5‚¼³-ÒiÝOöX±”g]LóX`ÝšMúÖ#B‡ò¥ÒðñjMÖ™$,“/¾q¸’´©à]©€`Y/ãªÅAÛ´ð+yÖúþ¶¥nß—Ö/aåW&bÌÃyý–¶‰míûû^#¾¹¾à¬ÓK=ñ=ç@—:àG³NMDñKy–\^Œgðtú+¹]ã ±¿/A>`ÐÏí>àÀ#ÕÿYŠ`ÉšÞœó(žÎf¿Ã¼ÿã—_ù¹ßzý•7ÿp<:x‹Ã¾6™ Ö_h÷ùÓ¸­k[àƒ[ >¸]>¶X¶Æ±*np‹zo¢ø1‚¬9Ì}Éq¯—Ì÷Ÿž~™DÅ•¡±¬ÃO:­ª‰yÝ5Ä©„||?Ë?½S&û^¾cÖ( XÞßw¤é4ÅH‹-¶(_»l¿¦͈=…þ¥Á´ Xp­DóúÔ €öohàxµhÜÆ¶’À©³îRÙ¦¾‚‰I¥%·ŒèI1ÝårHÝ|&¯­¦Ÿ Nó”ú•{©4)º=g6¯]Cø`\©ÁbË¡´m95Z¦ZFý¾°'\N|w«ð[YßaÍoƒ‘ÝÓÉtòµÞpôí[7_üg7޲_ä­þfû¤×[¶àŸÖjom |ÿh€ïß>?tªà¿XÜÜÀ¦ ËðîÐóÞfx:Þ®×öúçXø›ŸŸâŸ0Š¥£›Í¢¶¿ÿ^çðÖ£ø–ÍÆgãgï¼ý.€&`Á©€¬ÎZÏÑ`È5D(²èŽZ:’¶‹ žP7›¡= c½<½ ‘®–|W,&tté?WÇ»¸Ð³çí¯ÓùÃÁ…}ºÝö³ ƒ7#1ÂR  S$[°ÊvøTÚ0MáÈ^놞þgÝÜQ`ò­„ µT5êÒu½‚ ­Z©HÖ(dxžÚÔ[?0SNÑl°É!/¬k°ÞSƸòdLó'ïRµÔ+D¤Yh„*Ò|Ÿ¨˜©³€ÂMÐ,ÝdØ+ÕlpДO¢…±©„Z“൤#¯žÎoa= h(|û|†]ºóàÖ'΂e烼ê%³ÆA¡áM|ÕD€F?E×ÙË”¡~ʇ ÔKQ@'‰þóOÞKJ£&' Sá~Žà)—Ë2üVEÞ,‚‹Ç+ÛÞS ;±ØÏƒ1fÅæƒZ+?-[KQ q¨ßpðìÖ 7¾:›}ýÏý¹ÿæÿ~ó§>÷ä΃ï¾ñÆ/´ûüó1Ú[Ûÿùh€ÿ|}hŠ¿ÿ÷ÿ~¯÷Fq;·æ‹Å½ÁdpˆvÉo³›É3ʇí Ýã0pvxľIç6½ ²C`4@õɱ¾ÓY@NäP•¿bnXí,˜Óï»"Ÿ.Zëéháí©v:bK¼ˆH7èxìJ¿¡´#Üíœíñ7ª4Ì !aùJW„€²Ѱ`J|ø&¿5q’A¦êŒsK^@²¬š;ÜZhÆZæ’÷ /cÉnq¦NyH8¶òmáŠÊžå±€$ñòH™ø•oÉ"¡‚D#ÜðbÆ»*YŠ€õö}]s€¦´ä“ànæ\g”O>›O?e’ß4ùê×Ñq¡kâŒçª.˜/± ©#1¼äa\'˜ú64†Ã×:𯾿ç2œº×x|#©byëM¸´¸‰V'ži©\y6Õx]Ò¨—¾¿©Ð7õ°=¤õ^¿•Â¥Žùü9þt 'jØQk¼@ÛôŒã›ß gß&ïrÞÓÓ9óóó‡{­Qò·÷¶ÚøO·@+ü§Ûæ‡NùÙÏÿì`ÑY~}ƒþí Ðç€ÅLØ¢ÙvnüìêïÜ»ùÞÑ}¶6M:wリ…}“Ã[â˜ùUFèôâô½xÿS§o/¿ÖY_\uN×§h 04aßÿ”ó ²ºê¯ô°îØ0­cƒY HäâÂ]t½ è*þKG‚Š9ã>ý1Ån[9MàE×ÊR‚8GÃÙ¡@ëB+æì³cx_CCFhô†sX)Óùþêo—ÏîÂÌq»Ðk‚u?UòWìŒÈ´ §©cë`Ù‘”N¸àE& (R\º `–)Ÿ8A‰4×Nl;2¬!Á'BÄ™ã§tßM³Iñ¹eä*³ Œ©@Ñgé-@×HÙ9`Hw4²æ.Ë7u’7Ï»º>@FØohVš&´æ ·úZmü\=oZ½Œ4l~ßÁv±>ºhS¸UƒQæÚ²G1"Œü ‘¯B—–«¯Ì¨+\®C¡oÚÁ|Ò–õüým7ò7Gú£~üùM¼äWsª­Bí¿Ý.Xßò‡ÓßMfð—>÷ßýã;w_{ò;__¿ûOþÉo-¿ô¥/Á°um ´-ðƒ¶@í/~Pú–îhŸùYÕùFwLGzƒÎãq\§æT¦˜ƒõ2àŸÑýUçpÂ!=€ö„9ÿÀïÁ=½œÛKAçÓh8I<¨úíé)7"1ñª×³Ož}uKPKõ·dî_¿®`$¸©‚×øMz]‰Dz/ÓðZùE.éYYo'* Ð镃8Ä ©ñ‚Pr™7 úBÎxóªAà)Àd5e°UÐAW.SžZèÁD;@5ÎQ­Î|:«#ÃT« çõ­K^³)$D䃦y•ÉÏæ°²CC\†Joa "Öß8®ç\´Ä—¤¦‚UÚ&Ÿ ðÔ¼„¢I«ï³O» ?WPó`¾š·†a˜÷©ïÒøß“½É—l¾'é<¸¬O¾"K†½qÕúúÚºBÑð(Q!jÈ›˜¦ ½ë`Ê­åY¦‚€Ï¹jN~D]A|ÙïŽ1ôód<œ<ݸy>»ûÚÕßý¯çùð˼MëÚh[àô@+|˜ÖúiO¾ÅÀ~:ºÏx÷g»ƒáƒFÿçÁÍA¯•õÝ#lÿ3z?@˜1jÃ"àðwHìZýÍ!€ÞÎý€žðÕÛ¯wÎÏ:_?<ÄŽþªóäÑ»ŒŒX@Èjÿ¡Æ„è9/=¶NàC"p´¹ºü-¬ 0ѧLÑ›:§ŸÌˆOÀu.¾ÌÏ;`µ#`G¬"Áq‰Ñž§ºã`~^ÜS€cê–:fdO¹ªsí´ëb@WpËÏ~µgŽP`œÛž²8ÅÍ‘÷hÀé†îá}µh§<¸%Ícìt°ÊÎùï;ßϨXl@%àj¤³$”MqÅ'\TÍòê)›r,SßwŠ3‚Äåú>^ºL‰äË`q æxßZ·’=ÓPî„…½,”Õ0-µ+  ŸIr¤ 5q‘‚J}cyÐÈ&»Â¤Î©—â“dùÄGXÂo’2ÊwAdvÛSMKÞEz/þÐ`ã|;[P?Ò,I4Þwù9áoHW´C%\îtÍBÔØŸP¯s±ªåºí¯þþ,\SÏ£h.l`Zw»½Xúÿ?âïS‚ù†ƒƒÂÓþ2}0eòéˆ]ó,¨tˆžž2êJý£Ä M–7hã[ˆYî-„|‚¸ÄŒAÖŸ43å­KqQ]›º¸Ê? S¥ R¢7žáž÷ö‡q˜HjI·¥8îÐ%,=W²=…;\“½ÐÛvħ¤Ñ–É}ik“Ɍŕ-‹¼ÓûâweÕx«"? "Îèú!á–¤Æ/ÜËÝï ‹_ëKœÑI"O­—¾—¯!ÀgèÒ¤Ìü M3.® 옚oJšï:5\ë†I/D¾cÚÏwå’ÎËòd" 4ú{S p ·FëÂaÒÝ3ìf¿×뎾3=¸ñÞ«Ÿú¹Gƒîðô?|sÑ‚¿­Ôº¶~Èh€²á>(›[ÿ~㫯޼=»}pïêE–¦¿²êuo^t6‡ìëîŸõìZÛvNXÀ‡‚ž£~ép O—èü#†wé^ÕÀY#!ônÑ!:/}泋³c,é]tÎO§Yíïü?ÄÌÓ/$zL;åBެ4´ZN/¼q@å^{þ2r BÙ;—AÔR³ÃÔeDF;hÎTψÌuq›Ãl;tG¤Z$Tíï.„‚ ”OÆ\¾eg¿¾||Nê“·`$möX¦‹ìü•zóZ‚ƒ£É(7B[€'™¡w”`±è‚3;5½ZãÒŽ¦ƒ:þµà§ÓŠbŒ°õ)®¤eõ™ðÈå;²B¼+£Ð”º›5kƬþá{kœ4òSV)Zhl/Ó¢â7´5¯~ò_÷ÆïÒÈãî <Ê/¾‰ÚóðÅ’Vt?þ>(ƒðûDÈ£ ªÂÖõ0  Wæf ñ™¿ ¡‚F2ós øõ«K–#à[Ö}0Õ£d¢óGÇððÚ¹s–€£/ÍKT¶† äçŨ–M/(0k‘$êwìþ«îÎYDÐ ZÖ /#IË5œ„ÀVéðˈZx YGÁÎõ`bKO«‚æ5Ýg¥ŒîÙRKºeú²ñ=ÙwX¹Õç ¬–ž—lÒÐÕˆ¬‘€t—PÒ*™lø:q5N +akîø¸ÔG"ÙÔv©Tɼ£¾ÖOû×>É~XËÈ€õÙ/sW„ꜤwzA¿:Gþ»gxp(߆x"ÓÅÕf6—±=œ04rUŸòK–¼¯ù-eš Ú]Zm´8…€‘¿-¬e‡‚‹#¥ {,Åe#ÿmôímwôîÝ—^ûÖOýô_ÿöb»zïsŸûÛí>ÿ¦­[¯mÒ­ðQZïýy?ýÍÁ²{÷zÈ—°Ur%üLe÷ƽ #úÀãÇø2ú¼dÎøñŸÇè1îÁ¼¯‹ÿP÷è. FÿNGjïŠV`tóÅÎf|£sxïÕNwÌÖ@ãéH¡1i-€³¯ßŽvHçì¨mãù€áÕG Ÿ`@ˆŽXëž5 Û!ë]öü\ŽU(€8]m´½ºõÈúD¶Š“xÜŠè³£ió•iŽº6 ’h ïS^k)p8òjßß² û^ÅL¬Ï¾–0ƒO¾RÛý;u‚ž ¶š 3¤×:S'cÏU˜Ò%;a·PZo£g92‘]"Â–äø¶t\IÊûîžeæ I +Ô2 šµ¼ Õõ—Ö1,]Š n|››6“®©RÃÇ&¿¿­:M9F;:kêÑp»®"´áQÕØÖÈwáÛLÓÄå#P[ðƃZK^'¬pšˆÉwâíôa¦°á¤ëMuAùƒpÊoò[,€õ8ß{·ùu#Ì7±d¹ØnÏ·ƒ‡Ä~kzpïßt‡³÷&ÓÙþæóå™E¶®m¶>z ´ÀGoÃk³ƒÞ˽þæÓ«îö#íý÷„åsÃÙvžtÏY­ÏØ©ÖØV oWݜɇ€ª¢rgÁ Êö¾l§§¸Ø÷¿ýGé^uŽÎžtú‡·é`Ñ'°@žŒ—tît¨öÒô¼C6F ¾óÓK,^A3è<}tšEu+¦ ´"¨ê6ÛöâS!{êÀw„ÁÐz¦ó¶ç×b§î³½ Ð%¢tðP'ø L»#s‰1Â,AÓrq)Ê|µ +Ð_~Lê&-[&G¨ ³<=1PWÁYùH>Ž(Õ2X‘­Kõe$2AnݬsA*¨È@C¬ÆEë@ròXV±ŠcžR–Â:$%w“fñŠ3‰˜½+©d1bç*ëU}I-K~Н’Oi+½ãnã“f<áÚÒUð·T#O¸Ž.üÈk½l>¼„õë»)˜­›u$þüYBÌ!5ÄÏtƒ<øžÙZ(/$ ë§f˹~´û ´S€ÿ>«d4öóúƒ"l”øFÇW÷Nç›ßëFoýägÿò¿|ñõ?÷¨·zúí¿ñ7þ—sªÐº¶Úø˜Z >¦†”ÍeÞ.‡,Üï¡öŸ2Œev¿Ûg^ ês––¯ƒoVêo8糋F€Ž~ÃAÏÅ}]v°`³A;à(gWC±“ŸR˜ËT¹Ö€¼G k ¨Ëî]s¤+ü£ÒÏP½Ìµ*\¬0,p2Eaž©5ò³§Îâ²OvóP`9e‹ÎÅÍt/Ò“'t–_hëœs^I:œíR/È‹3zÈG,Ìkú | ­ÒUü,oHZãÌžùpêXݤ¼i>è$\e³êv4å‘{!ò^…“|¿Á>/Z†–ÈZ®ô;Gb8æ¶WžÏï+Ü÷¯—Ii£kòRƒ’šoC½4å§`§Ÿé™xù²”§@ãZƒ!S<î‰y0•¿®«¿qó[ÒÄ%[þûúÃÑ»ƒÁä½nw|Ú\Œz¾h]Ûm |¬-Ð cs¯†ëáæ5Ðî3ýÞðEFÏSFƒKLÿ®ëËgOã÷Ø–'ì`¸³`ª”ðI-9Õõ‚tŒ^òauÔäðF:ÕN÷Ù\EÀ²B«‹ãÎù³ãt¤™;eÝðî žm€+M#lh,_cÄ ï U`ÿü ¸Ô¸óäÌ´º?Áî;i;m;÷€jzqÃ;¼LØgO \²Ønº:uáð²Ø hÒÔðÚ€>ÂMÊxq‚²ÏYè‡/ÏzàOæàDpÖGÃE‚!^—&-àªP&äÚHùiÚ×2X:ÁÂF"*Oò.I“Ÿl ¾e,] þCnfœ‚€AéEÇxy¸æaµRâ#^Ad]Cf~/3ÒñÏÂÇŒ‰¦zVж.à.Eòss„äæÝÚÔ΂ÍV²^6¸‰€“Ä Q^º&)ŒaËQ˜©ñ!jnNÍèÊÚ„KÆì2/T>'¿!ßÇü2á2‡ëLù±é?&pÓ¾7±Œ¡Ý‡a¶ƒv;ï2£Ï¢Qš~ûu¾ÿñìèè7^yý§þjÿïܹóÖ×þÆyûªÛý’¯Ðº¶Úø[ >ÆÆ¼ì^v'ÝшUËcú?”›ts,¹Ï\º"óîì_¦£t0èŸÉõ¥e&Öíß\Q¯½~F¢L(0fÂ_?ÀŠ-€žìWô´8#/·ÿÙéjmoÀðu‰–a#èîÒE%ŽN–zd·A/#/Ê”5ek¼'@býp`E¦@Aþ ŽðšN=¤)×P€‡›9®ç®yŸ° ž4Ññ"™Ô¡œ "Ã!º&TÍ$Òù °Ló¯KÅóÑ<%Sñ£AÙ¯ +Eîè]ë PžVÄôZÁÛ¼5þsÏ$ù ;-áJJÒºTÅ”&°«»Ï\ÉïM^^פ„vÙÞÝš¼ûÏæÓÕüù F4å–1¢¸D×L52¾ßØ„z•o\HIK´¿•âô#‡Ðv~cGüõ7m™i 2-VÝ»dV›Aÿ½À³nwxÜOO†GwÏ¿ñÇëü›m½¶>æh€±A·GÝþb¹½ Š¿L'vÍLG‚£àîÒ£{Ï/™Xt.=€v¤®Y]ïL8ÐýŒÃÓÛ9fÞ-ÀùÅ îr˜SÌ©^]ÇÒßrɢ‡a-çêäðê2çÊŠjF[CÖ€Hl¦â v`Š€uàwÊv+L AXu®Pæ.çcß`X]7t¾œ\@L'N}–šžYå„ ßÁ=ü!´DàaDa'k  I;¸5Ï?òéûŽbÆxÄhÕ0Ee´ˆ÷NÚ¸ <ñ‹¦¢ÔÑ÷QëCDø‹ï!ð¥\Qš¼b¼eú:^Þ6eÿ9̈R¿øæm*PýxKfëPÞÁoe§oæâIktjyt'¹æ¯ü”‚HIEý=t¾ã@ƒ=äsÛdò˃ËÇÄxk®hçIôSYoËJu(õ Í¨†mdš‰Ò•¶ÂçÛÉ»º2Ï`ID=s¢J=ž§`þR~{„=[JmÌl¶á7éwá7Î{_ñnÇÌè£YX®Gݯ#œ½ü©7~ý΃ÞÁ>Æ¿^œ~uüèhþË_ú?ªN¦V¡õÛh[àcjVøêþÓßÿ§£ÍéÅd3^PéMÙ6/;J²Wå²3åZ³R_ÐÞ"hä†nU<½¤KïiZ´$1â/{¸Që«¶5‡  ½Ehö×w~È+XPØVÀ‘?ˆM€„\頡շî>µk€ Ÿxù¥£,4 ­¾à`¶$š$F‡¬WÂÞ (–1aëdƒ ã<|ª5ཛྷÏŠv‰~Œµ.òiè-3·]½Œi,¯>–vß™GWýòdD©«M( ó^ÍsC˜2÷˜ªö¦£¦ËªI·}å›öÄ.¯Ÿ*5>^u¡ã¡òI=ž»¢ÜÈ%_)<ü ’±¶ÕIe‘8ï‡ïfKz¹[eC¾[„Ghô3ýïy*ü©#̆”î%[ZÏ{£Ù³ñÁ§(³ÎׇO¯¾ð¿þ£F #CëÚh[àcoVøšð¿×Ÿ¯>ÇVÿ—/·Wo2¾3O¦Cæó×ô|Nü[»àlÔY0ô9Èâ½ù‚Ð,†bAÔšmÛ¹ûún¾HF«öŒ\Ú9c¤N,f tnßz™÷´s<{Ú9?eÀiçÙ;§Œ¶á{ò4íÑ- øÀŸ5U¶ ó«Ð\]0wÏ|<õ¥,Ò£o9Z8Öóè¡U—ít6>¶‚Iv SÏѨƀ\x¨ÙŒ`¥¥sgÙA,º9w¼QÀ†]’×Õüòô-Ëy⌘y_…¼vÈ#ªà¤Õe"¾¤Kʵí 3Ê$'qÜpòU`dëhX“¸ºä‡NÚ:×/:Yÿ:ê–ÎR-:ÂYhȳE¤JMYÖËX«.OŸýæ¤B|6Sò"Äy¬–ü¤³†‚¥4™š0Lœmžv—^B.ÔçɳÿÒÆŒu¢êÒ¬ ß8 ny™rK8Ú3ÚC¤!_§ö„†©,ßWÂj§ò=飅òro¿ŠŽZž5)аÎɕߤ»ê°5쟾þÚë¿5O÷§“_ßtûoÆëó/~ñ+þè[×¶@Û?Âh€¡qçóùdÜí½Äiw/3¿ýû½"»óÜSoçŽ!:é5'ܬPh®æØFGÕ®=>G÷¢ÞÊývÖ¬ÐXÑY.Ñ\²/ª „'ÿ¡²½7Á,ðÎürÙ™O¾+Òí€]àDÂÂí~®)@j­®P÷3õàâ<1f+j(”ú+]}*Ÿö$Á‚ç’— àþ+\@MºdÈô y6-`e’¯«‡{„ÖƒˆÒN%l!‚Ÿ´¹ðt;5²)Ë2Šâá&z—I6ª²³ O>„u.±°ù ÐÑ\xî^Ø{¤lÛL€#¾¹lÝuy×…§|Ì‹”2,«Ä—v©Sñ¡•ßÝë9×°Í»n®Jf}ª3HòÎ…–§htðkÞ/å>µÙšç&ÉM$F Ùyq–'IÔ2@DÙŒUòðÓ+M©åWËÑV¢ø%°'s›<ðªyIÄ=Ÿ×˜¼º}'\êx-·ðä¦_ëá¡<ºV”«ÅhjG÷e„Ÿ¨Ð×ò2 ¢e\¯P•[Lü6IIÏÍö‡¸ÉÏWÅ÷,¡ÒF¦ÙT×S]cÙø~_µâ¼':º®@íG MA†^ØÇXl‡Û%£g“·~“ÕO:ƒÉ¿ê §O.YÁÆí­m¶~,-Ð C3/®S:´×W›Í§–ËÍ}ݳ»kŒàÝ,„Âj*ûéð6þ›úï¢]zWhPÍ£Ÿ-jiFéK¶ø±}oµ¾Øåg±^oxÐéÏ7:S¶Þ¹{¿3=¸ ß1‹ª&Œ2GÃ[عèŸu¶ï¼ˆcH0§#`\ň ¡&€Î›}×NÀw±ìÓ·Ž<Ž0è(WM€» –êÆµ‚WÀF,€6ü{G´½ìbG\ˆqÉÃ-+¿Å™82ㆢ®Á ÕA%¼˜âTmeFù†’[ÉR½Ä îû.ÀI—¦e„ìp¬³”^½[aŸõŒ„^H.ù‰Lrñ«­;©ª«€k÷]ׯi’x¥˜}bãˆ4¾²Q;¡K=¿Áݘb®À_ó]7N²í ±YÃø UØ&›ªûÒÊ©GS½\MÖû/D¿Øâì,±P¦xŒVØ“¥À?@ØóŠEGâÌœ! }ɉ‹þ¨ÿøèþ ¿ÓŒMo<øíOÿäŸ9O°ò÷S»öÖ¶@Û?úh€¡o-ïÞ¦Ã<_Ý»cyVÃdûtâXûhoܸÍÈhÚ™‘†šžÁ¾@/x®Ï4ðƒ•@ ûl0ë[W’Éwtë•ÿ¬sˆà‰€]FëkvM[ʈ¡« :7Žf¬ ÇÚ çé:ÝÐÝΣ¢› €CÀÝùè-söª¿û XTí¯¦À‘OĦS÷ÏÞ¼ôÿŽùÁ ªôâ$Œ‚¥$ÎàЄ&šç2­P. …(£EŸÅ…ð(´|'?Yz)”Ä5¤;F5*tD;np«Œ<‰“JºïPÂUâø`…iòPÒœ€–FgÝ>ȯå—ÔòúåmÈã{“àÈd—ØÊà*_ËÌëqKÓÕ窴 AŸj¸2¨õÊ:ò¦¥•;:zíòŸý³¯ZËÖµ-жÀ©ZàchèEg3£wû ºÁOmÖýÑ–…z›õC9÷a”>¹ÁH½ÛyõuŽóuàÕYçäÙãÎã÷¾Ý¹zÂâ@ÔíçäAÀÖ>{4ìg³£Îg~ú'~ñÄvêÙê´s~~NGÏ"Âi·sp4ê¼ò©;—§çóÇØ™³Ýðâø» 4ÒÃè>³‹õ˜Š #߬y"zšÑÌF(é.è±é†·HéüN2gN¿pk ØéÛÉGØÒŽtñãïÝù_ÊSh I僮@±ªíòäôAÒ(ÃÑcÊ€¡<]Œ—Ñ;y³È ßÑ$L’.ð”²Ã8ôríbƒ>¾…44ÒIï­à˜4ð·Œ*9”ld)FI‘|u$†É™j47c›Ì¤)dø”r(/ažuø-7í¢œf—w>£éÔµ‰Ü ûé$´>”Ù”Ê ‡F˜¨ï# ®¶½ïŸlÄ%_R¹5¼l{ù –îÕm÷Š©—3A©7Czw†xªŸÂÇm“õöºEÑ™ž¹[?‰Ó6œC~†ïMoÌ~o2š|ãŸüÿ×íÃ×Nûýùñ_ü‹Ÿ_þ¥¿ô…ò µN­ß¶@Û?Òh€Ð¼¿ök¿6¸õé[‡_=ûÚÑ|µ`#¿«ýJï,<:Š×l2úŽ'tº4‡€Ù²sv:C0àè3¦\Ä§Æ +ñé<ØþŸNg쟞¡îgäÏ¢>;l ¦…^;?è(Ò•üì±Ø+N Dp`_Ag}Éqj Ú-–þ´Ð—ïëÜ{d³÷ÏMh® …aß'UòvÓ$©ôÏ´A“‹¡ |ùB( ¦I"L”Lü39à­Aµ€¦©m0C ©ú÷ùýî¢Kð‚¦ñÐ2”påeÝLÛwTÌ~ú…+óÊSg3Öø—"L¬é‰7ÏþÕ<Èç{\%”á†_¡û  {ö“÷Ã’X§æŠð%߸& ·‹3¡<ÔhßK ˆÀ_ùP¿ŸvŽÝ‹“ÑhôÝþpüèp|óøå—_;ÿîwÇû)"YŠiom ´-ðciVøÍ<<>89;ûÅÙvò³'«‹ƒtè,Ìëªó Vò«@Ÿ¯½Ñ¹õ‹¬}ÂÙxЉàÇù®úsÔùl dáƒ;/Ýcä?ÉÜô~öøI:ú«5› è]îôâpŸñX§ã}åÕ;Ì©Ï:à5¿ÀìÏëž‚ŒšáVÔOá„ý×Y0˜“Û´1Àè}+Ȳ¨«—‰~ë_®Àµé%¾¦ÕÜ»2’µr”»®y®|ñÓnyæF¥K;úí,e(ÔJÒ’ªp¶£!ÀÎVÈò;ZGýgü®ÍÇï|ö3òøÈgùï^~ö³_â×Ùº¶Úø£hVø­~Ò»÷Vë×.ç§/œ?ëg½–NºŒôÅcÜ„¹Ï £Ù9à H³Å/5º¤g¬9œçv÷Ngt²ÙÀT€‡Ö¸3ov8a¡ÞšQï²sù˜õ ÙfÓÕü _e©ÖGáÏ|ÀB#?ŒÆ]M¯:3Öп_Ò)Ïéb3ºwÁ!}ôjÍPÅZN%ü¦$ ŠpA·­žœÒ²Ë6"_Ó¿—:4íVGŸ¦ëìð–¢ÑmDóšÄòAˆ—R:Ö E!ÁÑ¿ï%‹Ìý˪a,A)1)A¢újd ]à*BŠ<ŒO±%o¢“'e¹"¾Ôܲ‹#.9vqD„WIkŠ]h›²v"`Y#óí'ì…+ûê'©!Ž·Ÿ¢J— ¦5éÆW¢ÒÔ¬µémã ÈÏ.ïÃo@^®õˆBX!Í:W>ôÃ'7òêCã:â[Â?6#HÀÕj0ê]L§·¾}ãæôãñäíþfõ]RÿíçÿQåDÆÖµ-жÀ»Zà#´øbq6eüé‹ÅÙ‹ÇÏž—ô˜½KU  TùÌÇL;ëÑŠùù ê}ÆàÄ«u„.°Üc¡ßѽÎ*ûÃ{¨ëz›9}¨ûê]”‡€ýñ“‡tÌhD7:Xfù7ÀIýÝQ°žsà@ÞǪ`ñÑ![ $ôÜ=Ò—¤_]\ølÇíà]'g£:VenOÙMÇ,8p Y’Ð¥*¸ÖAÍ %.¨!Èˈè$áï¦À"HTàÏâ?¤#ãådý ‹/>5²Agcý k†«©¯E%cÉÏ[§NÅ|qI3]Ú ² p§^µºQ¸½¤òˆ’–;|äåû¤Ì&©€ëuɼGy‡†kxWvÕßãü\Ðü» ¸u¶ƒiªÜãs3Åò¦|¨´ 6ºÔÓ ‚_À^Ò ü.Vü}˜åýß*o|SfaZÊUðM±Ê¥µ|¾%ÛvÐG /ïÞ}ù­W>ýú¿gjæ­¿õ·þÁw’¿½µ-жÀi ´ÀGhþuwµ!lˉ&ìݵzl¿ÃÄ)!`ÏÈßÎtÅ(ë€!¾‹Ùº¡ctÊ>{ÁÇ‘íp2ê¨BX_1:'Ýí‹«+¶ ²K³Á±€yºt°jT‡Ã<3ö{í¾ú~ü.Kõ5¼ã1¬H9-pÍá+êt€@@ŸÞ_Èü´=;NCg?žÊ[@®]dI!ÚÊ”è ØšbÙxiIšK5¶*÷â Ðgžø¢-(­L¡°æMTWyÕ4]ÚÄ€tDE1\ŸMÃIú*ß:L;K:ÎÛl÷sgÀS,ù9R?aKß³‡£ ¸¸xúþı£½$–YÓ#è1ó‹@ûï>Û®ìœï¢}±Èð€9…îM,¯œ2}À)„N \POÖW[ ÍïUœü ²“obxÅèa‡T$…¾#Hœ\2 v«JRƒSEƒðc¥OòG¢áµJuÂëýòKïöÁäáY€Ú¯w¶ š\H2ê¯#ô:Jféy´¤mƒÄÔ?Ü­Žy)<åCš5 øuñ`( =´²«S5Ò¼º¤é\ZÌ«q Ô– Ê–˜]”õ0Ÿêú&-C^)';8ûbáM›ë[·æ[¥ q*( SoA§l?.|ÜR–ù5$M¦2ð‘vyÚ‹²Æ,ò³M'h,.S4<ÕÒµ.ÃÑàôîÍ›ÿn<}{6¸õ›wîüÙßg)ìq§óáÒº¶Úø£nVø_@°§eÁ|¿;`és_‹~—éšõa`½fó³+å+-ëÙ#«Î×EÙ”¨‹‹í´íŒÕxi¿Ÿ®˜©sA˜g¦"ØYtµ o;p€®§ñØË›#X‡é¸y7öìq¥“÷‰™‰8qãš®Ä=‡>eDÍÜL¶ Vá]n•ËóY›§ZºŽ@ ëï9ˆj5tÍ¿”’öj˜I“ mhø9fæÆWãõe×ø‰ç¹&KgWâ›D½”U(¾çÞ%Ïûi÷Óž+¬aø~úç˜K³+¸|ÏÜ}‰]<Á&¯Æû»ª…C MÖ‡àG¨å¹>4åç77»íÐç!Ó7Æ©Ï i+ÜsŽº~:š ŸLFÓó›7_CJ=ßí o]Ûm ü‘µ@+|„¦`¡—Uø³ƒþlòÂk/ô®°£úU÷Wô‚€üùÙ1#¨IçüdÌv?€˜Ñœû_³˜ÏtDvò3ŠýGl—r$¿¸òÀ ‚ÂýS`ýÕ9ÁAÍù;ç¹+l‡¾túò Ê÷ñQøðÍ+è*”ØxIɳDqR’×2lŽ”Õ$QE]öšÇ?yûà#ªÞ“û‹ÎÕ%Gø^l:gŒ–å¹ OÀ¿dQ_aÛpö¹Ï>}:FFÑC¶ì ;·t6ëÎd„õ¿ñ”¹û“ÎåÙi^œœÐy3­°Ñ\0 ÷Œž½•®»ïÉzôÞß=ë#Dœ²¸ð €£÷%Ç÷˜ã†ìHP¸`Ñ"‚ƒóöU *hñÓáã Ì,ææ™¼Ú8 Ù9ì¿@Ì•‘#å«B¢Pø™³P1B¼)'ÀàÐ5n>ˆrÁæì`Œ¹‚¤RD)Wí†NQÃzTšÔ5ÏÖ‹d%üÈ`ääÆ¿†¾p5wÔÃÕy~«þ ”%Y¯9>ÿ¨¾ï^òy·lÛ$ïS+i|C’:ÖS^]Zós… ùSK6SÍ:”v&²r»ÖÖÈþY1ëäâSUM׺ֵN?Unu`„Fø˜ç×Õ ¥µn^ ¦›ÔPÍi‹qªIã?“ƒéÞáÁWÆãÑ×7ÝáX¬zÏ^aéªum ´-ð‰jVøŸ£?e³<‹õ9Ø„½~C0–‰O¬ò Øú×ÉÖÌÕg…{NÕ£Cf‘ßšž>âˆß#U 18ã˱´pj0Ÿì` .Ïš:æ i)`r6ù“µ¼²ÏÂÔQZiª³|]ÑHÔ¸Ô÷RV© ›&šÆ…GÃg?ÎÒ °¶™‡SQù˯–GOYÚC&ð“¥E¿õµŸ´4;6›—¯Z„:W_Z¡áZ™7„¡ -|pY鯴Ò8ËóS몟ÔäQx(ߺh¤Tùó[5éßGÃe\óè1Ó$_vÁ\>žÎf¯–ÓÉýÏžýO¿øwW_üâ?(¶÷¶ÚøD´@+|„ÏpqqÙS24f$¯]þ)¦{Ý·e?ÿrÉ4BÀâ“ùäEöቜôí€2ÒƒÆúØ Ø2Úï°F`Ê9n£êv8B¸{žØùçL'…`‡ÃáçH›©€Ýκœ}ƒïA:é蔩„‘9Çí:—íèÚQð<–ÔAU°+Â|…œØtðnD—ŸpàRï5¼µp˜© x¹‹A€˜¶0_E(:0Øw}´l#P^q¢sCWc 7ÙXë4޳fWHxê³4Qã[.ÿÊÕ( ¤q­F“_¢&*ðËò>4[~}øù,(ê*¨(A|ýÔ ?qšÜâŠ/M}4Ú&chüƾK©‡Lò±ô¡‘ U~Ö‹Š% Múd".Z |«>ò§áRŸ”}ªh°È¯Pch²PT^奸ý&q3tßå|©«Á°ÿÖxzøÖ`<}§s8šO§O´õOîÖµ-жÀ'©Zà#|‹Î1gÛ6½ílcÇèŠxì›g{œ†õ®®´Ð·î\`Ëö€Å%CQµªéÝø»üDc¨Kgë¡>ã1f|»3@T„YbTù`B55 Š­G CÑQ ,Ésþ€€À1Y¨—ÝAÁIì¯ê^kÃN†´D3ÆVæðÍ 8XÆŠy‚ŒêhÔ( È2¡ T›-sÎðBaQ"ˆK‚ÃbL—*““¢ ×7©ì¡·`Ò\Ä¢Ö×°  '‚ø¨tMz]o’šx…¡äM]!„±Ø•zð¾âjL-àû>6i ¬…¼¸Y½‚Æ[G©Œ,~Ú—Ç”‡o¬$‚¥ß«Ðq]N0†âÆ¡ÂI„W¬ŒÎeÜ0W%Yø7¾Õð9Ÿ·!Uг|xšæÏ"¾´ÐþþFŒì³fCÕ?Ì7,t}å0ϰü÷öôîý·gGw}ëñÕ/ü—ø¡·®m¶>i-Ð þ‹t¿üÿ|y2;œM.×çf<•åê˜1é0,Æm­;¿¨—Œˆ5L/M¯jçë*ò{¨7KÔû+¬ô1Œ_p,p—c„çØý_oÉ”BŸž¶ï:1«øéí·Ì½ºÍPõ¬'ûetžó‚—«ðéìÅs;mGäøQaX‚ g» p¥³·Wç߯yÁM¤ ºÁ‡¨Ü w¢¯P.iÊ\¿B‚Y,(N@ lêÁ/ÌýáFö4þMîFâ5O2–ä ÎÉû‘@ hƒŸå½-kßA×ðÚ%í?®Ïø©ÇŽðù€åëRüŸïf\‡A@’xÓ×Í蟨Ro̳ïÌS\ „7yO3âŒKöÞ«f“£á$q“n÷ÙlgÝûòIŸr „OMÇOZón\öü)øXÄòµ ÐóäÏkÃáT—ŒþÏ8búl¸ôî^Üÿk/l:_²"­k[ mOZ ´À‡ü"_Þ~¹÷ÒWoßgnþõåqÿÓOO»#º¿Þä0×e"Ôãw·[N÷[žvæ—gSLùjägCؾr¢Õ?yÂ6‚ 9°çêµ:&n·«g€}€Å„L\±ppèFk4 ä~ÿ³ó1+ü™R@8XaÔGUüª±Ø±UÙ Ê®/pŸç\iQ„6ß{wE ó9jà A¯;¸Ñù32ô"ùÀW€i@ã‡n0ýÊÈ’rüZŠÑZsÁed)o/ËÚ…aÀÂPkð/Ó!½U”DG×å],·Æðš M~_'UçøÏºú…—©ò)ÏU÷*®¤Õ'ß­.Œ—jDóc©;ЄFQ0|¼5tz>Öt¤i¹ uSvˆyɺfý‚hŒëR`b"ØM;E#DrÑÚ„,7›£ÿu¬„M<‘.$õ¼"Àǯ6¿•®ò­´02ÍEÃüÀ˜æYóf.k0ž=›ŽõGÇh°Þ›Þ9:ûÿ‚Õ°­k[ mOd ´À‡ü,÷ÿÅýîêhÎÌúæ?Ó {íVƒ%føÝ†GOœQ0µ¶>s9ú÷°å5ÞSÊ5´+†ê}v ,çtåÌé_y`ëâj‰€M^BÀ.v@¹î\ë°H€0Ó}¦ 4$ô Öhãé“…<nw­ÏÛª[-uz\áZIíèÝaPQh£ç/ý¸iÑHC§œo–\€é£Í@ *¬¡S¥lqN‘”üM™ä±zü+Ž@J\ªhÑäÍkèËÇ øÄSPápÍ«yÞy{å(Ó4,vɲþ ·o/oú©‡á†Ÿïï«ë›/4øv|˜žh}.GüU( %¯m&ú ƒ&k%‹Ÿä†ÆVÏ_¥¯eɪf®~¥1-œ®i|N²Ÿ@d¾`ãšìʉ’l{ýÁÅ`89 ÆW.—«Û‹7V¿ú«_Ø~éK5Gë·-жÀ'©ZàC~7þc÷Q÷&õ:./Nî¯OGëÍtxpÈâý1L7»í3O|‰Ðß0"ß`m ø/Ÿ°Ê£É` XzràÆ‚ú ©†”!Ö’‰æEVü³ÍŠÑ—óè]LkHhDî–wú+æj—ÃðêŠ%ØtÔŒÇHnËšÐ|Åúƒ¬èÍ<«a:ñ<6éË{Þ¬X9ò§7wz¡†Öp Øã3òújäø¯®X«@FÜèoA ÅGê>ë8"FÀHÓµ2/eÚÄxê/!®‚“ÁDÒ¸ñÏz:'^AO^5Ÿéä,—‚J’ WC5ÛŽ¤IO¼‘\çüUëûÞ&¥YšæÊмU8@kqÊ=ºì°“e“¿Är—¢ÔÉ’†ªÀc\± ±ûm c¥ h $L^| ?£˜TGùJRyµÔ:h5d}³¸´f$³8SêǶR…0í^ñëÙèæ7_zðê×™’úÃÃïœ|þóŸ_Àw/7 Z×¶@ÛŸ˜h€ù)Þzëvwòæœ5]Nÿ[Ùã>lËGà‰|@Ǩ§éEÓ¹ÚãªÃæÚrÒ]u:eætƨüG¬¦GU.„» nŨ~Éåb¿š;cGÜö¦²ò|Šj¸yˆG/bì¨%$ ¸:'o<LäG E4 YþR&s!q–_nªKl¢Õ"˜ÍŠÖoç$±2©PMP‡\ò–ÚH}Í«>Uê]uLøaÜŽÑ÷fÎ72ºVç{Iþ“Iõûú¾~OÝŽÍ÷)³P6Í_öó¾/¼GRø[—Ÿûú“—’k±µnõ9< É5»Zçê˶ᙂ×üþnª‹Àc‚sLüò1„u5ÍÎYPº˜|õmLìS×\­ß¶@ÛŸ”h€û%~†ùévȨoøÏX?Ïçã‹Ós4 ²3g†*ÿ°Gõï6¾ƒÃ!#q ;Bs *}Ôú Õû ²£0¾ø8ÏêZÍËcNdÔî.„š âE-MãèâßÎf|PAS¶= Q«B=t; uÊ¡‘EägzQ”w(ÔfU$á^G¼ÁŒR‡ð´|Bœ` 蛈xI-P„ò_D•¬E5¾âV㪄R˜„K…,×èRNCn}¼ÜÎ(Ðû~Ž¢ÕBÈBWr•ðþÝ¢Jqf,Ô•·[÷j8<`Rù¥ý›‡]\eÜ´k΋Èw"_òòŽ®DÄÅN?¾ëRŒqï~„Ó&Œü¶Þå 'Òy¨‚¡SIj(¢- lÛÙ4ÙÒIì=¬§7OYüwÂÊØoÞ¹÷âï³¥ôÉáO6ðÙ·®m¶>¡-Ð òÃ|çíït_º{«Çh| 0µ;ì­¶}Ö¢€zY¿Vwšá°óóÀ’{ûíLS½5h¨A  àÚÎW•Œ1Át¶Á=h·ô¾ÎÛÛ}ƒÑa‰Ø«M©r{o[ mOV ´À‡üGÓ£î|¾™Ñ‡ÞÛ¬ú7WKfå1ãwÁhZ`ÎÈ_C9¨ò†TÉ˯d¡Þtz¥À²sòì!s¬Lœ_w¶—'t¤®=GsÀß@À®‹ëœ=F2F‹æÛûAQâøgy9„Ç\é€üZ"$¥tÒôÚ]òõÙ£ïnÃ-=††}Öô4GŒ¦`€àÁ–5+ZÈ¡FÀ~ŽÂÝï-0ˆ4­[Þ<X—ÞÞÄŒœ}ƒâ4Aœ‹<¾Ÿ®šômð'üÔZ@™? QRÓ bÄg¦¤€S)‚û5-dqwíÊ«ìˆãJ,ÿZaË(ž/C~Ò¯¤Ñ¦©&õ1{ÅõÔµ4ËuÕˆ ßøMÁM£­H™ sÃMKHÃÛ÷“Ä5u)ùHÝÞ2ïd•´Ò§e¡)¿«|Îò-!PÓ”:K,o\]× à`ZáÁŸƒt¬xôW³ãïÇã§lU=înžõ–ƒÅ¯þêßcñß—¤l]Ûm |B[ >ä‡yòðI÷Á½;T©·éLo`í¯·.6€ßnçòä<€¬EÀÙá„Q÷´stïE:q€{†úŸm|«ÑÛœpÞYõv0LŒ¡  nY4¸ZžÍ:X×éÕ±ƒp.ž³'2u´@Hµ='üe;`#(-8+ìvÜŽ7@æˆÀ)ƒ]¦)²p;̉„Ý;¹(#†|𭯈³d§‚Ú ÷â[VA9^ÃF°~"J—÷sdèv¼Lc(„ ¬V]ë.#¼“g-b¨3Á:ªMØâL¦LÉën‚’Ÿ;l-³:ɲ­?šp«m[™°+`é- ‘WOC,O%W-a—͈z¥Pž›D¹Ö·ð°©@yÜ»WòÚ½†aþ¬NÀÛ”°:©*¾ŸÅ²ôª­„ç â ¯†Ÿ|¸Â?o.¬äUùÙnM‚$þ]fª†A³ÕÛQo=>˜<O'§7'Ç7_ø‰³ËË‹ÿ’Ëœ­k[ mOh ´À‡ü0¯½ÊÀýl퉰C ÷ ·Ë[¤»« té §ŒäAnäݲǿ‹yßÉlF9ì,¹VŒÏ96¸7=Ã:c?àßYœá/° ªŸ•ûlÜb @ð^{Î*ݰ¦}E˜žC`¼‚•¶i»Ìõ«7ïj¦Nô䘂¬®—(Ï,ëcz‚ÍŠð'èV 5>”é €YPØ-t¼”ƒ`wÞuž dÂIPÒ,6ÓJ ˜ 2:„l„“$5:ì®û‹!ýàl¾˜O.Ï®ú«óË.kûº—Xò ÓsNYЇMôÎÑÍ›lá›v†w_ÏŠþîÁmL£˜?æz ýû ¾ì<ý.Úó“ÎÙ =æô?Fû—œ¨žv%ÿ  Õënÿê"0D—«Ú€Þ›U ¼#o{rêâ:ƒ%*þ£¶ L¶R¼¹–k&‡[uµß0„î2œvD§á™¤!h ŠéåœR¬ª tê¬Ð’8(3I>f€(€%_‡êüst'HÊ£ò$2)ܪ’¯Õ2Þ‹ü¦üe¨sׯÉvM›ðÁ ¡DOçT‰Å5 Æš¤_Z°\IéÒ€ø¸Ê¯<ñLD©/1 ÒVå‰;&Š»Î+{FúÍ,ƒ`.ÊpÆÈ°m£ËT@"$-‘•cóÈ·0#´dÊw ñùºysú.Ö“ŸVâl3ß“_[¤Àî°·a*hë5œ8x†ût»šŸüæo~íìWõUëÚh[àÞµ/û„Wó“U=:Ó.Ûôúìè±o¾»\¬ºîY0b_ ŠŸs¹÷^«},LšSÕ]v¿öüs,ïx:FC0éLg¹fÓÎt:Í™,®bŽQ·@ÏåB¿óý`UëÍD°çörÞŸ)„Xƒ -ùM8˜eÈï%»²ê_&-ø Oï/@(!]zvoÒq•¼%Ov Xé ›žøƒ$ IFãüòØL.`#1]ÁÃnŸ½$EïèÉ'/Óv—Ï***ý>oó~ÀEÔsñd‰Û§5Âg~hà 6Ï;B‰Ÿsi½ëºA_ê™m( + È´¹ê{?ÇjïÁööòë(P}ðå·-t×ô{L’[Ðö;6ß2‘Ô•6fÄÏD[[ýã¯Ø÷WXŒ\­ú›5óþíö¿ç›µ}j[àÛ­àC~š“g'ÝÍÔãø:³óË‹éùéå•zƒþÐÂo­_~Í y C·½qçüô)Ûð.˜`Å?=ìòô; —t¨s¾Úú_w&€½§öoßé,±ù?v”϶¿ËÓóÎé퀾dê@·í±u”ÉèÙNÝŽZK€GÌüÒËEêÆ ¤ªú Ö²cã.nO¤£‡§ î–®¢j.[ Íê¨R0€EA·„dƒÆHLeu ŒOHC¯0d’­içäAü-Ó©)•Œ†_@O¥S¸r Ú yñÜ œÑ^È»V+oºK+|®Ó³)‚G߯wIýÞ%§ÅQ~Ã/g"${óR$˜æ@ܼ‰m?ö¶±büK[óœvñÖ„eP@òb¨ð•fÙhBŸwµ>=ÚFgœÌ³u(ëeâ¨ÓF¾eãJö]!µí¤H=©Sê ¹ÊÓùÙ¦­-sÅC:~’¬Båý‡L©ºiºJ[žvw£ëž<Û,Ñé7éx)ŽÅ…kGÿÿºÇ¼?SEë¾áûÐí—‡Öµ-жÀ'½Zà‡øBóÕœ~v»á žÍåÅ%&þ7ýåËõV¶–s¨ÿ—N\Î;'ÇÇŒZû¬ø·“ÝvNŸ=FP˜£æf^Ÿ¡¥ÆZÖìÏwœ¾eøÜC@IDATõä@ùq^ß<Œ°:G‡c¦˜»¿|í¡Ý@{ÝËÒé;bäŸb@âéÝõÅ1Hpf·BÞ¶ï9^ ’ô«‹lÀƒÜ‚E¤í,6$ЄNh˜ì¶ÓU^ú"MœR^?ÊÃô”mr“lå6 ,[&ùTíK‘~´Ò§l®ó§Šò« 7)ÓlТð“Õ5ºÖŒ‰½Ž¦1R£›°CÞJ½K+Ù®e L³9iÑt#pç øZÇ|FíB¦F6ñ¼Lɲw'¨PỤÌC¸'r/ÎrýW¦Ux¡îpaªåê)„ø½ùo#¬ Uó§­W*’ØÕºdýGX tº VÃ^®Y€º\÷ºh6Æ¿ò+súÍo¾·zë­åêððpûë¿þë»Ï]ëÒúm ´-ðÉhVøßáðòp»è/Ðú²ä‰ÉþóÓ«%«é¶CU¨¬HðG¸8¿ê<{ò$óÒsÎØ0Gzr’Sü4¢ã\·¦yçô# <;çûÝf7:‡GSæë=ä-ñWìX;ÒÆÙßÇ¡ëvc€ÏµÇµ#¯`§@1Gˆä%"c³_X©Òpƒ\`&¿\†K¡VÁg€‹ËQ§‚MÊ’WË bg„(g¾P”(Aka˜wˆƒ^Òea"„k+àsîä÷ýšðû¿Xµ#±áO-ó'¹QæSGu{óŒ·ç¤ºvÒ§ ækþ…Ï®Bå©07ƒy¼Qíäožm·}'ØÛ.Ôô•ñb±¢@N~)×F4¹iù*Èéä±[OÈs-Sß"¥̇j^ˆÌáPÆ7ªÁßï Ív8àçÄ¡£Fûþ1ƒ… »óѰ¿ì2ï”qÅu±À¦âh¯Ç^Àív|ðæ›‡—ï½÷ûÛ.y“Öµ-жÀ'µZà‡ø2£‘¦y¹3²SüVZ⣻C=ËcòÍnÜèŒgc:bAºÕœŽÞÖíîÓ·{4ž§%¯Ê{L ïöò3иYâ &‚ÇsŽ…‰¢ÂO¨ÐʵÀTa†ƒÒ&–eÛè;jÅÄb“ÑZT`² eÁÄîÐ>OÄ•èd(Oß{'ï~µË{\Çí§¥Ü”A›‘°ŸÆÄ]§<ò©Öž`ML>ÛºäÞ±)¾!õ½K6ŸjöÒ×ìšlUòø¼£m;Y¡T§¤û½åKœm_…ƒð#ŸÍ¬pêbJ¾'‹úlÔýÙèÚeIwéE¬BÁ ¡´Ï²Øá¤Û›ÞZÏNƒõk¯]­nß6¥RXëÚh[à×­ða?ÉK/w—géÑ.<|TëÛ«‹„;7îÜîLXÑ÷Õ—;¯~æu:S€¸Å(‹ã}/ÚØÀ ûûEeGµž¼vî¾Qš5ŽôÚÙg]À«}¯üôݤO2­ð5„ƒÓcÖœ®:çÿ?{osIvÝwÆ{ñ†oÈ/3+3k&‹¢EÉ,A6,µå -yc 7h€r/zm.{ÙKŠ‹^5zÑKÒhÞª–nÈlÀT«Ûð¶É,·éUdY9}ã›bêßï܈/¿¢X²ŠUd&ɸù½w8÷Ɖ—ñ?çÜsϽpbä+–páK=…0ƒ·¹€e PîBkÄV‘À—·xhµ\ëÀh2ðOÀ è OÃ@_1>¼æcÁQ«ƒ5kÓ@CdØ)Í,¤AÿÈ.æ„óa‚ ÔK,ƒ©Æ&B3Æ$m>j¼4‚„G5eé˜â¦.åsze8Æäõ‡R Ìñ:@Á-=]¥šŽ3}™¦>DÌìè*” ´Råø¶üé9 ˆÚ$ä*‡K»Pù­–ú`qW|™í¹”¨Ïª|^–¾†™£/Ê®.‰àŸê¼ôg„Ò[ýoáR¾%€Øœ§m4ý r8öŸXªçÐe}hþ h1åƒÄ¦-oqŽá=Ï[Ø—¹Z{Ž`àÇ%…¡{¢i¤‘áE%©,ò­Å‰¨ù8½pC¾‚R"×_ô:”Zg¨×—%*\þsàï½Ä­räÄ?¯ù˜< ŸÇ'QÔ—\©`C®oµ’¬§W³#ã|ùäþKiu¯Ò þÀ»à³ÿbWÛÚg  É¸}?È\©,Ÿâ®tsu@ÖçÓ¬y™>Ô¹Ã89F™íøÄ3 OA+yDàg&YŸ³Û„¸ŠpÀ‰¶sŽª ‹€Î}XÒÎpðœ×,Ȧ[$ 3‹Æ4r`äÀSÊQø!ÌþÞ>o»£ëÕîæ ·ºíºêö÷+ÖEÏ&Ͼürvxý({^ Àç^Æqï8{ëíÿQ÷Ý;ÁGK‹ñy¿ª%Fßļbµ ¸±oæ§¾ü×Dß䇲*,]vt¸ Bªå¹ìŽC˜ò¥Úkî˜sè"‚j¡€ã…:¢n#t ”pºÃ§@0عÇ{ÐqLŽ®ã4Ь:¢ùQùoÅjéK “^F&Í9Ê,//çåûÊŽ…¿ÐV‰OÉp´/Û:Mâ-IÁqÚ”³8Æx‚0ùQÃcŸÌ¿šìˆä»ŽãcK™}ýTÂGˆ84# ÆÍ^ðVÙºÔs ™Éx = ?”‰0þÅx A?Ž¥ñIŽ^`æœÏ„¥5$ v®°#…G”0I÷÷‘èÛ¯8iò>MôÔã"úÕêò8“3ªF}ÑÌñYçq½D-5Ói3J¬Ã_€ó@°¯€8Ð3/.+yÏit \…€ÇÀ]Bù>ŸYoÔ‘/> S+Š€º¡/p—|Owcë›Y5nPØö42lOT?dC/íÕ=­4 éÑÎÐúyDx¹´~¦;V¬¬yl+ºÜl‚‰‹“‹|Jˆ©j7«..¸Á#v¼yƒ…,ÿÃoüëÿùï¾úÒW¿ŠÝ£ï7:¿FŒxÒ€â ø2Ö¸Þ±†ïðpÉê§k“£/±f‘MY·^k†Žã3-JÌ«~Ø›~̘  šÜY ÔñÒÆ ¿ÃQÐ7øÄ‚!à>)°*”€: rFÙ‹`C„ñÝn 囯¯U_é ¥Ó³&!*,zskÏÙU9Z×Oúz|m(K@”´ù¤x*$Ö¦X®FÝèCàŽföHzÚöYÑnÀÔH¹4 +ŸÍ8J'd" þý°‡ñý Ô¥áx³éãÁ¶‘ÒIªòø;ª¦ËË6`óãvC{ë¿(û0ÉènȺ$ò8#I§ÿ8î _´ÚÜbÊ{Vм]®i5Ï#9¶tßSm–õã±pbK§€‚.̓fTLm=5Iz )Ïã:]¸:0†Á8?(×fèýÏ?XË)ùáÆj€Zç@ê*²1³Ô°VQNgÓýÌnΦ‹‡“ßþ Ä¿ÚßpŒbü90ràIs`~ˆ'€FÍ+0æK™Çe7"/¼øøR6…& †FÜ¿muö3F¾ûÔxûØ3ÉJ!Þ›ªoê–L@Þ]úâýK}â‘&ÙŽ@@‚ïŽX•„£€¡vé”o\ækÖ%‚žêU?qý¿%–À³d™ö4¢í1NAÙÙ_-„–Í-¹v|‹„‰˜DA?õ›@R–2œHÞ²§¨{y=˜÷;‰šÈ´Žm¼/ª¹‰! ¼÷Tßò# 4xŽqœ:PËÒ·©Ìl7ÕñòO'Æó7ÃÇ S>‰ÈË\jâÇ«°Ÿ²ÜÏãdâ/²æÖ”¨æÁ4hÿÎgþ’Ížñ :PÁi^ΖGÓrÖ]Ô, Ø,²W_ý¿º×ΘFŒxJ80 ?Ôƒà ÊÐdZ>k˜Ú ܃ó”¸Û¿ðw>äû¢G ¯p…€ {Lù8Ú©ÓÒ-|õÐ6àk\Áàä!çÐ0Ê ëÿ“É7ªÑ¯e?üù˾‚®tbDŽÙ¹»o€F8å!8!·ðÖ'ЋêovÛD·˜ˆ“`°@ȉºtÌÈÉ-¶ˆK5cÄ ±•¾­àïbÇ5€”¶`C‰fïÁ¡-¡:ŽÉª~¬ ©8j@1ÑŒvIù—}˜ÏÇ|i„pc —„‹‡ñx~™+I‰<ç£'Z>Î…¶7GÜÓIêÃó^VÐûóY)¬Ùç@7ÆEÝp ‰•˜j)AiÍÿì·Cfú($yOCÕ¸Ž&©ÿAÀ2‹î"Ó¼áÚaòxõ½èœÃb &êð•nŸ&´õ4ú€¹0@S?Z¾ÀÏQs¿?ÞINlƒðW”\p»üÈ ”±(÷¯ñàÛåA>¿¶W7ßúVü$|rÑg jü90rà‰r`~ö³Á /¿É®#j`ÞÖeÕV¬íç…˜¼¬yÓÖ˜õ™Ekgs lõjwK›y¶&ÌzoK´xÀ^tHËÓ1, €s(i\ùç <@?lã\CS'AódŠxósìHÐ{œ|÷BZ8ME Ž‚¶mo™@5|lF¾ÂHš“Öt˜X—:JϪ&Ï?”¢@‚üÑî²ÂÐàC•?|1вYªž¾c|A0„Ökå+}¤:)︧¸AνÏïOÖ7ÁA¾Ó…ÕBЈ|]_"ÿ­aÝKþõ4åS:M oE½íc<½‘|íà#?‡à ¤ãÒL§r¤žÆÑwl9§—«*úëaÌ=NŒ1H«J¶öâHaü’úŸ 7켿€¯æ¿ã)ûÀ•TñP8HG¬\Šäñ#go)èîøð‹Æ8äOÆtuÜØN6“¼<ÉšòÚëoå_‚>6€Çññhdz‘#žFàc2ý|sÞ=w°Øð=®êz¾>>¯&MYlκªÜMÖl \¡Òmšm¶©×,ùbnÿbÍ«±Ên?s-kY°9CȲóó–e‚DõCµ× º#R„P F¯Æ¯F¾\&™f4âMÞì@_„¹Â0«P ƒŸè‘´BßôBÞÈ‘x³còMy½T ˆOýH3ûxû÷–ðî§Ì×5 X´Þ`=mJ s>lõÓT£oÁËú¢WÚÇ*•Xi ¦ÿ~‘×÷‚ U†6‰ã‚´ÁÚ0§ÛGšš–7/¢_t–1å"ûð(ý«i'yn±ü¡D]Û™Ú´u<£Ó3Ü#ߎɂNÏû‹¾?–ÅE.2aŒA.nŸróL`|Ð)ŠÄ»°„'ËUÅMŠsôϵ<’•ãö/ž1•@bÙ @F·Ñ0Žæiï‘-¥KL Bû¦†4RvCŽŸœ=*ÅÝoRó»[A“ÑÌW4ãWA W¢6ÓLS¨cÌ+@wÙš „ 3Øš]]mªn:ËæÕô€1O~å—7ç¹ëíÿhÝ|õñþiL#FÝAªæMôëa%h§¼T@™uú|åçûzSX†(ôRöùI%Q_—ÝYJ*~Hø‘¦êȘ(žÚ7ò e7’9‹âÞ¡0e³æûuôÃì?¼0|hêWóg- ³T(úþB+¦²ÜöŠ55Ñ-Ù ÉöwÌÔüØ»ói]O_¿sjßÑ?Ç19ð90 “ùû÷öÛìZv‚—Ô÷˜Èǯ[ÕMSnw;‚¦ áܧ°ZggÄ dãž|{†&Vg×Ù' @+:Ø_0«3 V‚µ†SÎym þ'l3 Ø&@Ÿ€ ÿ@“%¯}„‚ô6Mq(íñ­‘rhÅ?¤k«Sª‘ú¦Ö@j`¨µ6äC’ŽÀ4R÷\ÐTÖ‰‚ÚF‹Ô¿ýJÂþ¢H¤Ùd›”RFŸÍXút~4%:´ŽKÆBÞ`@ˆ©ZŒýjý eÆ@|8š‘þ‚¦ÙƒFîM] Iq¿$Ówüâ¢^9T¶Ÿ+)ÆÜ7H#Nð/ùæ4BXK|Ô @_dÌóÿè‚óaYeXVx`i*‚‚Ô@²Z-bÖï$¬¿æ|‚Sñâ¡O§¹OØzAœ!¿«èŸ€ÏF?Ó|—çù–gßàÇ¿4''4`*`zæ´¾§xœ#$lÈ;¥Q5ÙUüÀ‹‰x]bÎrç v Æ0¯º=÷âGr°¸yíºÿö¯7Õ¿øjö 7ºø¿¦ì˽^þ0¼ÓÈ‘?&ŒÀÇdô£Ÿû¹îÖÉwÝþ U(.Øt覼Mõî¯Ø®·Üwk6KCÀ€?k2xpð*XçïQ³|¯jâ ŸW¢‚À¾àwΦ×%9*f"•0£Ê¨¹>‚Àa®Îˆ‚½€"Ý8ôG1ÀkÁ?.@„ËÔÓ‚n8ñ Õl#€9°4_àIX@HVJdSí3U”Gpð¾ø8*iG[ï'þìÈ[†<Ú'Îw©)õE0²‚5ž¤™ð¡äePàD–Çýyç~¥|‹ÕD.xEÜ'uŒ‡àÑ®ѵ÷‘BJ’4I#n“ð×ðz¨;TJU?ôu¤KývT·;åVƒD#|.”Ú¾¿*ÊÔä*:¸$ȲW?aÔq8´ÇDå @Èã™Êïr m$Qž)èp=ÙñCÛ"@n3vüV·Sì_ݦæñåá;aÅ?…†© @Ü5ÿ ³<£ü5ĸ —ÿÒ~Ó² ³M±í.Ši·#þߪ¨¦Ýà[4¾°°].Ø0`³šo /ïÓM™Í1¬nŸ6ºê&oÿÁ®½yóÐ{ä˜Fü˜90 “á÷0aήÏ6Äè;Æê”·ú% s(~ôIç5ï¦}Oy Ÿ€ú®ÅÓŸyþu±eÞ™ùþ-qVq½6²_¿ñb˜Œ×ï{ÝWüŠá©¦õ<@Ã÷·I`ð4EÀH `FâàYÊçHýc󆶿q=L tÃ3ŽtL3Ï:²GÇÅípî•Ô=šd@Êrì(ú§t¸¯¨Jï&ê1¨¡Îã¡9Ô¡¿~é—Koh7ÜØå}FgéërL}^êÛÆ|keø‰ T4÷x \{”ÆÐ×%=NÂ…”sôéêÑ|3¯æ¥ZöfG;º÷™2´4ÏÏ\½EÎëÇÈ4a°!O€® B ˆ§‡ÙI¢æ§z<…ÌýFˆüÃ̯™ªÒÌ©›oøY"t;¬AÔA ü±l¦¥¿}L\Ž€öŠ-k[÷gmY7Ø ðáuÙf³­Jü&UM@«fÚ®Û_ú¥ÏõÜv\c90ràÇÍQø˜ÿ­ßú-ü²º÷¿ño|°:=Fï™ÞÃ%z¶nNÏQÖÀævŸ @y‡GTM°Ÿ ð_íN °;]qtÙS®¼×k"bU3ÄùŠ—;úoÑÐ¥}?òÖöú»-°Já8&GAã†[8Íýä†!æM-Íp؃RX< !}l‘9£ô@‰è×ÁÄ€¸æÔl› ´tR3/òý²!…iÉaÈA S©g˜9ûÓÞï1Èrm¹vT"›×¬2Œ>†B[„ÀÐÎ#}…僶uL*÷¦ío¸¶Ì"ûõ~MNŽ÷ÕÓ¸ÈW&‹$A’Q”më—|ó9‡)ŽñìúGdÝpœìÛi1 Á{ì ï6‰ -1–˯“èd[ûåWÑ šûëðAO~4w<ðaotR¶‚¬6çî©›3Ï‘a¢üóÈòœà>Z `?Ú:€S> ™Ÿ¶gÈš¸™N/(3®ï1c¨ëa¸pš¯ñ}™ºÎOè¾Înt›‚Yÿýöb»œçÍÅl·aÑàö´¹ÙΚ¶²ÅÂE3÷ÝË¢~ûíÓæÆe÷õ/ÿs}Æ4r`äÀâÀ(üŒ÷¥I³öý?þS*3«íÈá‹I¿›ñv­0ÿo6¼Uñj¯¶DJeÅÔªÞ„àæ?¾®7XjBúÖX çÄEAÆòôÊOŒsèDVÀÑ%p=®+šØ^$âÈ[?‚Ê¢§,fŠÓ‰ÄLV£ï æ:#‡@ŽvmèÑ2ê…RÌ6X¦å@»L=‘«Yý£­ùWˆ>cQPLzC™`y™úSÇéjæã‰óT+Ñê]ÒµLšrÊ œ‡ô| mÒ9®´×ßÔgÅÉ@72)ðùZ»îDíÇ lm¿jú¦K:ý%fx凇¾âŠš7Ú¹#æ£wTòcS ®=R}êú ëè“ç*ùäwôÇr•ɪlûËr?Ìü–gE»ÂŸ£ÊÛ)ûúu»iÞž·“ò[TÕ™V‚º\a-˜M"mgë÷ÿr÷^™WG71ínÔ¬~í7rz1»F(Œ/~ñƒöÕWït_ÿú7½Å19ð„80 Ÿ„ñL¥ÏK÷ò.lÖköȳ·²b1gU”ñýñ8¯²“S¼¡X °mQ¢ÐÅ€x³×,ù3¦¿ÑЇclÎy=‡ àøú‰ñK 17w Cˆ"éÒl5O‹bûŽ-mÁâ«A»';RX8Ž""aŸ‡¾³U© Ç¤pT´èÚÃPÔ¾qŒ$zVÖŠAH¢ò @”V¤È¹k¨åeƒæ<˜Õm?¤dkHý™7´ ò‰dЋúß'ôCˆ"QÓ]&áxøà~ÂÆN­°‘)O¼Ô’IÇÛ1ÉÏË1I“+&<ï?Þ±K<½®úh?ÑÌ¡ÝKS J4· †Eo˜q4õSäÏBÏ| :è騷†Ý ‚ ËöˆSIÆ­1h0š¸+¤ ¯pà#ÀºyÏd²¡nÍUý™ìX“².óg¿ Á}ŠSž †ú>4 dñ©`×l§gE9¹`áKS\œWóvÚìn_¬Ù"øììîæO™ÙÊϲú×~/V°ÿwú¡ôý×*/FŒøñq`>¯ç‹9îWÌ…u€Ä;ãÍËU<Й¯do€*¢ïùçM‹¦`Žêh·ö”ì,|«ûÊ "ÞŸÃ;Ó²}O}ÓÇÇë¡ç¦|ãÜ"ëõÀsY•®œƒ–m¬—Žžšâ8 ÿ@3À¾®/<Ú…Õ:¦ <àUú¯Œõ?ÔÏ•J—c¼’wYùjÞÇ8·¿??1šá^òŸ(jÇј/ÿ|F™R]ŸKªk}*óxqˆ ÔV ýìسš­€ÛzÍtÌ®n0üçüÖÙÍ¡dƒiÃt°ÓöNWìÚ½¢=aF ¹EY¸ùjú•ÆƯ‘#žNŒÀ'x.‹|¶eKàw²ív¶»Ø¬º ¶ÑÇËÙ’P(Í®[pìêy¶¸Ä;jÊœÿq˜Ú]"-@„ÙŸWr8ÚPMœ×» a¾™&œéíoêÂj ÖnÞïTöÜ£uãÏ—@ÀÓ fÛAv°jÄðd¨/íAg=8íÍIGa0æçÉ ™¦§`c¤ªÃë…ŒXasé§a{éRK®¥ =Ǥâ1<.Û¥1°‰Mjß«ÜÔŒºÑ/%§1÷ÖîÛ˜ÀGÆÄ1Øk¾óÚ” ŸôŒßç?ªERKºýõe}®/}3z:á}C7ž>Ö#htÍ­Gß\cª1OŒE¾nŸdhòWÓ7ö~[´ìC™é´‹0½p¯B& c÷hw©BãçL³„wˆ yú°Îßxÿ˜ó‹œ€>âXaAˆ­}‰l™…5a3ïÚ»´eÛªéÃ]W³¢=cÖ žݪ۲ÄeY47×'Uq˜7ÿì?<Üe-+d5®Ä-õ,#F<Å€OðpŠò Æú SéEË,óè,{ZóÆÆìŽ5€¥‚JÎVº%!ì¬É†;̇æï›<^™¾£9ô ΛÞþÚMu23…@`=A?€?ª¥2ó9s? B€¸¦[€: Ÿ -y>RÌØ^¨Ñ>ò¼‚š¸=áš‚ôÏsi8ÞÇ4­ãµÕC@HÍÌŽty)í>Ï>MCÙ@/å~øû²îPyhøè1èH¶‰1q5´O%f¤3û°Äp=<‡OªvÙ^:ñéó‡1?æÏpx>ŽC†2æË6>³‡1r^óЂ Þ‚óô1çIŸyèCÙÈ ùUèEÀMðçGG]ò+li…%€s~1˜ú)t a‡•Š ¦òéš)'b÷£Ù³ÆšÆý_1´k&ó‹¦hÑì[V¾ÌõyÙ®§çU‡–ÿÆébw½.Û7ÞxÈdXŒ™Ã˜FŒøIáÀ(|‚'u4+kÝœçëÕñ|>»`Ôbw±=Øm·F^Ã…œ·3€ûQéÃ_`_«*“£, Ä–Ú`­5œº†[´0^û¢ïwŽá”'º›å—osµ}“»µsˆ6 “P@[²D•Øï…ÓX ðø]«7e³+­aA°^ÿþШh"0úKR*xtãP£MªÛ7McñÒÞñý 4äGèxš€²G>3ÂÌî "9ÖþlÈ¢ìÊi_+ÕQ2ñ>‡<š.-([¥‚þ;ÆÁ—<Âw"ä,ß›ˆIÊaÄ‘LòÊdØ*î¦Ì<‡Œ>2%/kÅ ÈJò Ø‹î½äe¯Ú¾5Õü9Rˆ7? í9q¥¹'dL‚Jþ¸XŸö.Ûã@¹KMœ `ŠÀº˜÷Ée“ítBä>ü4ÖŒÓåçX²ÈÏÖ,S]AG@Öýók* çchß]Q^¸„ï¢h·Û÷ëF­öúnýÖ馸ÓÈ‘?Q€Oð¸Ê›GÕ2_>8]]Ü$¾ÿù¶Ú-OV§¸ê,È„_c]YQÎ}gËÅ!óþNÅžf¼»›-ñÓxzÞûÀ-Öù÷`ŽrÖ1,·zÂæÞRL„õÀº¾é{ ×\[ ‹È~øÃ].™T.T>ñ( 8ª ˜îX7g”‰gJÖL‡8œ³9)ê'!ÎûìD:UIß»K=ê Õ’(’PóJ#Ú€Štz!%ÆÙ©2×fuqN-ÐÐŒË{¤} rª~ùÝßlL=P×ÝnC q´N\’Ô Ü ·aÑ…_qBþ˜ZÙ‹µù"ŸGy)ð“XÏßS xkApæ›â´çPû‰ah­€ÛA´¹ElN´vË^AžP¼9bäÁ¡kqMuZg~zT'J¢ã$'>õÔ¹ÿ]A\ª.‹3æü· çAõŒ‰‡]ƒ€¡™žmVÓ9û^.OÎÏÏgÕryTýþëoË÷|c90rà'”£ð ܲ^V¼¨ò¢~8+Êsã d´¯Pµ ÃÈâcÅæ@é €å ^2y‹Í–f¢>9ä5èh%ñZ pé‘"á9¾Ñ©#$æŠVb—­¥¨:ø¡d³þ5Ýc\RB ¤y`ß}%; a €hœù•ÒU䣟¾E”ÙlègÈp(Ñç 0XÉLr ú#+§Œa¬d_&˜Í2‰Xú¶¾¤å'ýìzÊ Ê¶’‚‡þè¹ÉƽP‚G*ªA×âx¢‰œÓчt’êJ)î5ñUÒ 3e3¢¨ÅûÁ©ù['iþZ4ãk߉=aÂ÷<È×øAðð“'?DY‚çu_nûdAЦdÈÉ(ÓÜœ‡c¼Qú$xÑþ/6 ÿÜaY¤B€ÄA–V»œ -§U^ŸNêjÎÒ¾ë˼ٻÃö~Ù,Ý…ÓÈ‘?Ñðõ5¦ž“¯}íkEy#ûÅ]ÛüÃínó™{¼ýWV›õ­ ±PVÛU.ðïv+ÝýQ½±¸Šîþán7… VO”†…Þj»@ £Æ®€·kÞßêp|”¦±`ŒG7<=  eEc„Á” ,C£”ÄÌÑq§,W“’ e ˜àï´ƒíüg »ÒE€Xà•å|†2H9 s-Ž.,îó°KÇBªDe‡×CžK¬KK„A¼¯¨G/–€Ê.YÉfJáaý„¥ýè{Ù…Þ¸+Ò³à½t$ÇþfÍ’´y,ÑK—nßH G¿(·Qœ}vŸ×SsäB¿ÅܾULiø´Æ¯€§Ç䟤ÒôÈ@jPsWvÑŒÚ=£áGü}ê¬ âÜ?Ú=ÛïZ^3—DcŒL‰žÚ<‚àŽèé¦ï/mòˆ±4høÒ—ùˆKÍ4@—mq4d]êt7oŠcvøÛ23ÄjÖ®²²¥8{xº[æõÃÓj½žçí¿ý·iÓ1öñkäÀÈŸ|Ä{ê'ÿ6žØt_þò— ãƒ9µX“œøéì‹îvªD[+y©£í·N‹.·ÃýŸ½z¿/|1‚)]Œ·¨…´åœ™]®ã:¨m>þPŸ€GÑhø=.ƒ®VúT ŒÞ„¶€7Kú¶à£c ÿ°8zþ}ÀÜ·€:ŽÈ3T zÑ«è+õÁE  ?zÞ_‡pÀyÜË•cØ@úz}Uõi¨ç¥çqdðQ&ñCžôóãcäkàv´´õŸÿˆ‡§Îæôôœ‚¹ØÓn„ü(£œgè\{ˆWÜ£¹Lfpöîü>zvÐãÚA›çÒ<¢óA„ÏT€PûÌçq‡þ>Æá×¹O£4ÈÇ>ÛZPm_ç¿Ðð] ývŒŸ|<7K£Ä—@‚e}xú#rV~˜* ­Ÿ-©êÕµrWìÌâú¬>:*µBÈÉ19ðSÄq àSx˜·f×ÏØýW“îQ5Ë_&0ú¼.æËj6Ý«ªmvBÜs¤ek|¸]æ;[D"Ü*aÔg¼YÝ!нuœ (PÀ)ÌåÝ­ãØþ^… Aû5SÀ œ•%Ò+YÙ"ĸtM‹f´>hŠœ-fš¾Mâ’ðƒÚФÁÍ@Rñ¦0SåtL™A<Ù @«ðƒDÒu´"7š3Óìþc²©Æþ€#WPXG“´Màl$ï߉nSɾ˟áŽÁ¹t/æ[Ú7ëïÁkI2°ƒ€¿\B<çV àÀüG jÔí«àÌ kÕ KßK±fq‡´xªÎ‰ã¹9aò'­¿À@u;è¥mà4sh³ ”`mžÚ8‚". .Ñ#tDªÏSƒ_ 4¦´ñ8ÃÃH1ïST–DÛGÀ@«¯‘,ÑúÑàÛÉáK@!}óYGˆêIƒªÛW7`«ÙÖ7ßâ rJ ‹j>Û?ǘB<‹ín=YíªmY½÷íÎ÷ʬý×oC3FâhÆ4r`äÀOFàSxšËåß¾êœíQÏX«¾æ­Ïþè9vgm‰ƒŽ'šîÛ¸jks„˜pêwµžj#Y`¯x³×ÀAPÌóÚ›Aoñ‰½`öKƒ·r-Þ‚×&ÍSë›É<5ý1Ž}Y¬`1‡Ô®¯Ò×t‡üT?ª‹£ôÕ×õ…Çú[¿õU¡ÜûGÿè+¬žšßgÚÿ6±Snu]…F%öàE…i¹Üú„TQùÇ °YP4ÁÊ}Ïg¹]Î8S(HØ\g9y•: !­–½¦ß~a1 =ƒ¬ m²Ìé/Žž›h)˜¦s5O¯­kâÀxS%.£.4S­¨_62ëÄyqzrž¤}×}»¡ÔÞ«¡i@ô@ß>â3P‰^R&m´•¥ž¸÷×ÏËÃiCVþò2*÷š¾sòæ'þ35¢Ä?›`Š–‚¿·áS’ûuÔÍÀé)H qôn×î#WçîéƒQö(÷‰²V§ŒôàÜ},ñ§êA€ CcÏ1e Ãïbursžb‡Ýaã¸`4Ôð{Â…<‡‡?M[ÄÌí!}™ò©«r†àRÖ'E½;?g­ÊdQ³se}€Ñ _c90rà§—£ð)>ÛÉí½jqÖ½WwÍ’S™b‰—1<îöy ‡ Ÿîº¼TQ%XkÅ 1@&\`„2ÿ’ ˜Ñ^@ ŸÐ4ê4à L„ž^Ný‚D¬ñ­-J9qÕÏX3¯¥Ây(ˆÑ>`Ïû µõã¤ÂÌØ)à ô¥7KA”Zˆ­zPŽFp¢¦òõûºÄ5 ☕‚¬0ysIþf;§üƒ. ýi©^o P¡§_Z1È æ¹ L2ßäÌ}PˆJf9‡îð\é’¹¨c=Ÿ fødoOí`Àdþ|ŠÜá´ÆÀî%389ÎuXb Zí±D½æŽ×½ŽxÐÔåÀ[ò¾)sþœ‘íæÇ‹@މžú0Š ž³1û‰?¸•ŠŠÞ®Cc[_6î Š î'˜ù‘ \ã¯AÅT´+Ê¡š¬ìÖ<Å¡€7ù–PU9)ùbƒ%ª™ÍÎÖ‹æÎ»ídí;Y÷úëv1¦‘#~š90 ŸâÓ½3½Þ4“»ì \´ÍųM==Åv<çÝ>×B\”ì͚ϰì3±P¨Š'(èV†ÕšÚ ÌýšÿA)¢Ù`ï/‘rq°—Î÷b_Ÿ²@6Æô,)1PC0•ýXn'øƒ»!ü<ºüÚÊÔÆåÌ„m¤|á!eHBhœÆ‰Õ¹TyæÔ®ûgJ,Üȹ”†Wf™Ô‰‡N¬l˾¬¿ræŠÀêôQ ¿l­ïD:2þ¸æˆn®v ¨*$p/x5*c`}<)í¨ë}…¸£rŸèK/×+ßP nð€šr:H§{IŽzÜ‘õðºOI‰ÁÑFÈÓÔuМF„>bK(0´|ã\>cBóîÃf QëQXÈYOÊÁ)óûðdK1–§|…' v¥Éù¢™Õ“m>m«Ý¶Þ®¶Ýæxº¨–š½²ùçÿ÷]œ|Æ4r`äÀÏFàS|ÜE±iÊòè!‘€ ³^¼Ÿçùû¨“àûÐ0/~æ…§`¨Á{]øâ…."iðç© ¾Å@±œ^мė° ¸¥:*ð´À,`ý‚YGÈû?©²ôG°8ºšø Œðe¡ªt8­Œ¨GAD1K´ãœ¡JY“Ùœ[– 6N£R@¤\Ål·cŸ¼©”o‘ øˆ¤žs„%èûLÑ D`²Pß×ýøìÇ@ÎÑq¤lêÓ<Ú]öc–(¬P™SsÀÑet¨¹Ó:šq¯ÉÓ>Ñ•¾s*ÐÔ Vó€¸Ö§SB1·„ ¡kûl 9|jŒÕ ;¿ÎéaO±èØ^:ô M¦Ž¨aô?âpÊrÓÛ1¯oÜ(€žh0ÒD‚ wÂÜ¿‹#r6ñéjblé;òê¬d?ÇÑl‰Ú’9ÿf‡óH9©Ž§®I™×‡·šê¹ë‹öŸÿÑݸù`îø5r`äÀÏ .ß“?3wü£½ÑÉïþîÿ>ÛÞ}¸$€ú_ãµý7·ÕúÎêâôo£ÖÏÖ»“R fi qƒZ4x¦*ô~òx9ã¸F[¯a˜¨À©p†à´ªwX8¯~/tñCózŽ; €Â–ÍZE Eу0Ø„ƒ!o¦ª°m30!:!xAžJ_3!ˆŒH]Ú®B§æ€Ò  Q G¨Î8˜d‚ü1Æq¨))[—q`2È> ¶N&O…]â “jtH@©7rcí„Dt„·®ñî¡“KÈbëØ9`.·&ÐG G#ùS*+ÈX9¹È —á1wמ¾~¾ÁÛ#É•hûYçà°H°=„^b`°‚—¢¢‚“9LÊ0ÆŽ‡Ì#€zÌíS¬wcÄKšíÁ)0/]ºÇAŸ€ä%Á“*Êüœ:°…)£D#\`[¨Z\÷Ï—ñ&¢G} øÓ F¬ùµÄŸ^1ˆjþæ¦m¹®.ÎÐüoíU¯ýë·Ç%~>Ð1øåÀhøt|÷›¿ù?mçw¾ÒÍÛƒ3pãQÓ4s^þ[5(ŸE¼Ì a‚çq+8ÆâõY€AeÖûûDKÎ^Ó^—òñfª¢ÈkV*Š˜>ÊsK„ ô6ï­Ø—¢Év˜Šð=YNëâhW«ù{/ý'x4~9ð³ÅQø<ïÛ·³öädÿ ÷[ ¦ûëö⽦­÷x·ßBÌ×»9ÑÏt2k­ÝÈÉZݺÉsÎ|`] €±ƒ{Þ` dAP^Û4Õ"0e¥@ãtª÷käÄBÿáPR—b*ñQMFGzYIC”ºè?gyI„ Tè¥%V›‹9‹5ì8ŽQÌÓãæ)¼ ÓÛ, 'Ê5ý;V÷ó¿GqÚt*(šÐÎMóö‰µ0RD¾©Cç=Ês-ÓWî˜ 7Ô¥]3¬€&j7‚‡ )Ž íž^#jcŸãâ=ëÃ$‹è' ]ZB@ƒ_t­ysHVÜS›| (çš~é“#Z9rÊ=¹'…=#‰ }Â{ò™TêÉŽ|.ì³Yô‹ýÇûÁ_§í˜n6ËÀv®)Úà²UH(fݦ–,lšE1ß´ë½ölïÞªÀ׿ÂÉŸUð½ÚþŸß|O?ù“xä iäÀÈŸ9ŒÀà‘ß»÷j÷Ì3,öïºcbûïÍÊùiÝà¨?+1ɳ¬ó0Ný¹aïx“O™ÇÁ0±Ä5ÿ*ÿìÑÒÕ¥ÕœEžÀE14væðÙrí¿·0,¦™ßgê@Ç@~,üÀ;D'@<—F"²µ¯¦Â÷ndS/ºŽÍ2ËvˆŸ.šãÍv;Ÿíúîv7Çwt÷΃êáQ†p—1¥çὌiäÀÈŸ]¤7êÏîýÿÈïüŸþÓÿíE^Ò¿®w×NÎÞû%uyv±.p$ÀÐhh Æœ)«YÚW±ó{ÕÔ¼ÉuìØœu7=t ÜO±&Ìp?ö׳ØvË!TÉšÉ^àƒå^:Ч€óÚXŽÛ:¨›x†£!¸&Ò™\àKd@·ßU@IDAT. P¤pQ7Õ´&žà¥)A™€ä4y D$ŸÉt)90§`é' ӨκHpNϸHö²²bÌØ#h$-b!–ØQh,|+¯4€`QŽsºEp ˜Îu\6Ó(½5…i¤©ßëè †ªnö &\»Î³Hñ€ BÀ€¬xˆ²K.RŽUÂc²¡Ð'ÿ|ŽÐ¦j}F$?d?Ê*žÁ{è®Êý½I°i±íc”©ºM³]ÏBÛêyËVð?8`€c90r`äÀ÷q`¾!ŸöåþþmÖa—ß«ë‹ýÙìþ>»-çóö:3´óšé[b£þ ÙP&/_N±ðfÎä36j;PU½ÕüÚ”j§ÆÂu´ÁÄß.Ä%Á@à #°š|]`qpz½ÖKÐ{Æ.ޱ|p‹•@¸ŸÐõ1ÿnë{S1.¬  PKœYŠ‹?è[2îgº³zžšå—@ŠŽ*\“”N”†bDŽ ¤ž–1΀m#ð'¹0Ô)‚€Ç[^¡AñA¡ZÂ4¦ÇÃ쯥òÀr›-Z±òÐ4y~ù¤ó¡½">DÜŒ'† 43 Âê # TCsäisƒ - ñ :ª È¢$âÀŸ!äkúº€®Ó;>;H{?óéŽ'ÇÚülÅÃlf˜íÕþa ì&LšU¯e/bùoPöëš þÓ«®Åt[MçÝúþºbÛÉvu«Äü¿ApØÕçÙñîúͲýý×Þ^ËÇ190rà£80 Å™O)½.Ú½½na ¸X¡Å·ëu¶Ã@œ4˜í·ÇP|c²Z˜ Õ½$ÁC3€¸ Æ™H8ø ‡Î KR…ÂJ !O Ä<³†ŸJv]œÑÎðRwë!“â‡pF—qmXˆ5^oà4&zÚSj/b¿-íðãZ©© T6¡±SÖE£ Ü–lÒò½!óÕþ•6ðr—N/x¯ç¶„c¨£%Ã+ëÄWe E”x¤ H2BVÆØ ÎC¾}G´eÛ9\û§yÉKÉ;F¦alX@“ðo'Ä̧Hêç‡ÏBˆJnHfæ=åjÇ"38<"ó1&¤¦ÄzƒßnåbÍÞdÎØ{ægp­XÊ—U”4"g³^\3ØÔˆE",1ÐgzµÊÛOÝá¢>ÝL»[Ê×fL eÍõ]Û>÷\,ñëon<Œ90ràs`~0_>µÜóoÞ8ÿßxåËr¶ úËùûå´!v{µÄh\vlˆ'@¶!˜«o{õ6/gDz/ Gæõuþ#7v ʦ8±cî=¯ñl«1 kóE *t3 æ¤ÉU„@¯gÙ76)Q#¹åÔÄß6›õNw>ˆ‚™E6ðŠŸþh >¨¤ÀÁ‹pB@×Í Å‰Î=chre#ÁX à‰Î À?=óžÊs<@C,Ø@:Ò‹˜È5ÃUÌH‰»µ(°B_!ÏrC*zH£ã#Øwäs ·² vtîÖáYÈ: ú`Ê…Q¦{ø€_åŒÃ‰÷·;é1éÎSŸEéüÓ#½µ%ᛸîàŒ¢7- XK¸ŸÔx’Õ6­,À‡ Ñc_,ûÔÝkŠ­>»ÃÉ…E®BXi›²bø%žž¸h4ÓYmŒÇ‚ÍzŠý²©ü½vYÕn—wkÖ v· û{A~Ù]ÔÞÊ»ïTo×ý\¿ÃÓÈ‘#þ\ð²Óƒÿøeqûöá_c*wïÞûÇ/¹<D,ñíg_Övzq_ñd°㼇"‹M<_·re»pÖ!^l@°ZBïµ³= r¢‚ªª:p¾ ¾Ê*µ@G(é? ö ÔHÚ²O;ÝHƒ…ô阨«ðAgžuTÄ1>éÙªýÑ+_héØ  X‹ƒ¤0]$wv|⬆«œ2-uµÇæÏ¸èÄÕ £¢9Pø»ú@ù€Dc…„µ`ÊÍ$‹"EŸŠ5¥3çly·Õ•FDRö`ºA¯z­ jñÑšˆŒ4ä5Ä¢pÈ`†‰Ç(€gÄ jÑ?’Æbê+†¹¡ú×ûß!ûÜ”©J}Ü‚ǧˆGŘ©V[n>tÖÛhæÇ'‘© =ý[Ÿ¾óBí5œúÀþö‰`ÆVû< –oÒrÛ­gq~»òOºÝnÞn϶gö9<|£~íµPÏ•ñ0r`äÀÈæÀhøhÞ|ª%ûû¯Vûû|§&\ËáAÛìªÝaÓl÷™Q_â§–€¼›Mv»Úe‚ˆê5ϧ›nVõà›T› J-±ß92@gÀç·‹5M?+«š•¢ÛȬ7†c¾“Öª€ÙY@¤ ÈXÙè·4VÍ ä|jÏjÑ+«·L“#¸aÁ¹W?„4d~›!ÚFa%<ýZÂÞ*­p_Š.,YäL! BÀ”¸!ïÂÁ÷õ³ÀO¶&Ch±d(º±Õ.íiUeQÛA97XžÒHê(WQêA&0t.Ic€ÍPÌ•§ÂN‡&3ê‚çÄæç£¡"§,æl»+cVšà^höØœÕ ‹+Èâ×ÈXFºOg°†BÅ3ò(xºŸï/K™¼GP©+ª%j>›·Ç³ã¶ØÖ‘ðþ˜ù·Ý¼i–È»]Wß}PßÙ/Úö¯îV,ýë¾Vœ°‚0–190rà/ÆQø‹ñé×úÒ—¾Ô~ã¯o·ñ_š‹YYæk¹Â.ÎŽ>öt°ÅÐõbŠija—ùˆ¨@€ö¨V®¦*ø 5NÀ;ÙÚN C³h D«„wZ¬q}ÃFí ÜT¹ é” ƒ.Ñv¤Ã¢…èÍ …PΙÑë¹.öÆ®Ñ^!kWûoÊ<ß Ò2ú‚öo´`ÌÂ_¤þ9ñòC8‰r:µ–;¤‡ÛTO€ )§èéà* ø) £ˆ–.ì‚•18Á_¢SŽDÞc X4¸1Œv2' É`½.Œ À5m˜ŠgÉž|¨Qù»ù c sÛzVMJ´~¸¬dƒdcxGvyè4êPßå““)j}Ûm›‚5U‰óã åãf1gKGüê‹ólvP·çL Ü`ßfY´çDý= ÆÓi³dŸàeÝ 3²co˜èR¹nL#FŒøX€Å®¾² ò»¿û»(oµÅâæ)\[”T´ÃnË$0¸<8b† 4è`ˆ'y9ÏæÎÏ&¥!€AJÐ6ŒÎ®íÓAp HÚ¿#±Ä~Â>AÄœbÌŽâ7‰‚µòH†žEE¯˜^ˆíˆ¹DÀIAÜé]ú…±QK݇îiØ· !¨¶®Îîrtú±¶l@šaè ȸµ‡/€ Íò‚Ù ÇåtUÀo©(*(¿hv§©ÖV"RN’‘†cCWJ²JžsÇÈz±öžiÄ@~[ᓧăJngÞÞöPuZ$¦èƒq&Ò®ÀóNˆQs÷H6½‡~QãÄÁd sþÓÌuî_Ó ¿‡¶AšC­Çø¼‚ÝŒ9|2ù4íñ(?»<¼ø/²sætx<ˆZ² +v& åšíçÑiw÷æ{6E·Ý;ÇÑoÒž¬³î…êY1ìè»pbL‡_úR¶<>vIíü9,Q·®];¸öÒK/úS»ÿütµÝlÎ/ê“»ïlaÙþáî@_A˓䷜ŸÇ1ø‰æÀ(üßoþæon¿ò•¯LÿæßüEâ,Z|üêõº#LŠó|ÇÊôVüˈþÊ4(Š“x+€U†ÁEMÆ®­pະ†éCÏ àØ–Æk ¥Dã}¥Þ*rƒdN`{»9êªàŒ³¡\¹5&*üê ó:¯;LÒD«Ó…€©oLŠ#…j.43L à‘h‹š€E ÁfõeWógHh׉’ÃØðd`æ!À1`ÓÇY†G9 nrkq¨çZÏU‚±dªæÛ² så8ð!@À.ÆÂ”Æd^aQ 9å!3OêÈ Ž¿Ýƒ¾¶ÃOB ‰Þ(°¿Kä,¥ è1?oU5wªÉ"„½ïƒWð„ù¶¬qàTž@:*²õ„+Î ÊãöÀm‰œÁ2Oº-Øx§®7ÝÞ´dJ„éÂB–ˆ{í’å˜ç¸hàÎ8{¾jÎΘ®ÙTݬDØÕ후*Ëý®ØœÈÞ™µÇÇ]wöÁ ¬ÿ÷™çŸu_ÿæëi #F:~} LV« 9.à W|†çø XÞžgþçWø”“bòÿÓNÕÞ¦ü»”ŸÍç»v»%<)Y—ŸÑíXuäÀÓÉQø1?—ßþíßîþà^ÛîW°˜,—7 6C‡ìÊY1=ÅI€°¾¦óÜú`ÀWS2˜È¡¡òbBK[3‘ (GÏÇ&Ïâtá+4e}oª¢Ç4z(‰ DLåÓ²D[c‰7?)¡¸¨)Ã4Vr”x¦«s\ØÞ˜Ó™à6ܽÑ?ÝcF£º8Ký‘Y4¡£Ñ¶ŒSƒSìt\2á@ ¤æ8-H,|ë/‰O`VL¢Ó£B P2¿Pï?Ôc<"5÷°ñƒFøÔ°%€G¬LÀŽ×f»0Ù‡&,ïÆ=ÕõÄc;F UônXTà ùÀ9d’£âƒkPó ¾„©[m ¹?̵8#9LrÐ!Ÿç;Vj°u°s 9kú&ݱjÖa¬×L7à_YK¦Q¶ÝÞ9#Ø“‘1¾x>w &[i€Ûw·sä¿¢›Íö™YH¿·w£ÙÃ]ôîÝewxxÚݸ1}ø<'ëoeûü0˽£[Ÿ;˜t‡(þyžÏ~þÚáÞí[·Ž°LŠÃƒ£|µÞœŸŸW{‹‹ýÍ®9ãÿ)Nº“̓ïñcØžžfONÂàÏ+~«WŽg\cÝ‘Oœ£ðc~ÂæïüÎï<´Ûk×Ê£år‚3à¼,ËvÚbš$\aäŸF̦Ë}bÆàÚ¶ÞìŠ=¶c­  9åïÌ4Ø5AÓD‹D'âªñ}Ÿ@y@r(µì*71(®.db[0T³÷€ŽÎ?³Å|t˜ ´UŠ» ¥—í t Ì'+ô~Tñ*é´L`k@ÄPhÀÞ ­°øs4‚ àËx¸ÐüÍù"/0¡k¶`yÚ ÀA$ÚcРϼChÐ[å„Åt38¤§‹$ HЕj[6Ýùƒñ"T%ͪl;Y‚äU¶Ô;ób Vе^8*¸°Â$6p»P-º‚Û¡”©ǘíæqy[âí :€XÎ˽IµÙ!ˆhû€|[í1É‚”i$¨l;_ ‹òb»‡+&w¦ÝþAÝl6ݺäIð|Œåøþçíœë·/RDÃÛgÚ·ɳs¦D®qWÒ?ù'„h0šœ¯°äãœú€‹gŸÍf×®ý¥Ùlr¸WÎþ{äÀϼpçö+Ï\¿þÒõG‹Ïî•ָɃ{'_XŸ¯›<ؼsðþæb³=ã·úímÕœ7YõïvÛî cÜà¿ všììáÃ윣’Út)ŒW\iäÀOFà <&íö_ü‹×0±¯êƒ|‘m°,³?³Ä¬ïBíd/7^JÖ*—n'˜‰ÁSV˜ã\†rÍÂ4u Q=z U—·›pÖ­¥ îŽFäaxŸ3½ è¡7 À¡ñ"f0M *cLðvl1/HB“Þˆ;Ìb7zF€¥_‘B¯8jÕØ€Y†Š‹!{Ø]¿0ŸÒ蜚à)ÂŽÖÍL¹VyM ¼™µ Àno…nudö6VÓ è)€gE˜IÀ~¡•ßɶ L^ÛöVÉÊ0"ÌóxWrtâVžáá¦ÎÎ~h”ˆò9#ÇÕK’F›8ë4PäéÃõY¯×NVJdãÞ"Ÿ³1.&í._2¯Ÿ|B/0WÒNÏ ù Oò4Ë~Žð›m÷šs!¨Ën:Ö,Û_&°¿¶;éžëÏïZ0¦O…¿ò+Y5åÆþþlqýúþ³e99âø BøÍƒýƒÃý=þ–ƒUBðd¹À ‡iIïðð G*ïNŽÖ7¶LÑݾÕÜÙnÛå£ÉêÖtºÃ*࢖l2›eÛ»wãy*¸ S3þ¿Óȧžñ’~êGùS:À¯}íkå󯋽MqœóÚQ7_Þ›±ïÛtµÚ ŒLoÏ6á[¶BÏe€÷W…³½ÆcCÒðÖáƒN‹1~ÚmJÙÅ"6€-ý &Ì€Ú BÛÝ8p.q–‚¹Ð’°I8IÎå„®µGèšÑQ´ =€Ê ÜAŸv±¿·8¾U ƒoBWÐÓy„º¬ý{Æ ¤-r9 ˆ¼Â9VxyâZ÷ç˜2ÀJ”~|S:ÜÊA šCn—ÉŠü‘ÓñNœ0¯ÛÖŒˆ¼œç¥f9[qL"LÙk—qaþÀ’HÓnq^Eÿ§³Ååÿ ,ðøò_Žé¤ÞÌȳ9¨/æE·¿ý 꼿›µì¼×Ý æót¯Ëe Þz‹Æ¤*é Þr™ø%æëÏ+û3•ÇŒÈ Kùßù;³W÷ÿ`9¿ñ‹¯¾ò×—‹ùÁg_~ñå=þ«Ý¾ù\qãú-üPÓ¶>,XüúðÖ ÖÂf»î6›M{÷Þûõz³mÞ|ëÝ.VÛÝ~ã»o>ztzÁ$ÒŸð»cÙ½×__ÿÑn¿¶úõ°jxÖœŽiäÀÓÉÑðŸË7Úâ½÷šû§»Éóõ:ËÃ&ÝÃwê|“úÙWNb|á€Íä`!Ê1A°s“aÜíà?ëà3öŒÍ¶›6Û;š4¼ŒP«‰ÔOWówîdÛn‰Ý@‡Ë[§-À×Z´ÍŸ¸ÿ ÉàJ½£©3†é³Ömë% ÙYÛ0[³Ë-£Ö4ö}Vª#MLþŒÆyz]2·Ýó5 Ô3÷ÎÚ<ÐØ~x;`Þg8HB@=S b»v ‡‰&¯Wl›v «fMvA‚å,±ª­Óîàœ@ú,· ‚Îõ®«ç> óf>Ù"5i;™ÕL/,ÁÃm¢XêTˆ@ËÐÒ9W›\ãk;o^Ú›·¯ŸbÂçÉܘìeëm=a^¾}ô¨ì^xa´zûLׯ§ãáaÖ¥/x›rÆïBÐýõ_ÏJÂmÏ®__àÝò,*þͽÅìÀÞr¹Üÿç‹Å2[ιùÙãÈÊPŠ1 ñÓf«.~\(’°=wÙîï/®S·Þ_ÎVl´ŒÐ²bcµá7̳½rãlË*æ”+ýÍŸÁ­Ž$G|r<ONk¤ðCp@3úk¯½6],s4ÞoÍ6ùz=CÛï¦[‚î¬VgeEžë ˜³ìþý³´²étÎ;§d9Ý ÓἩ0“‡!žZ—#ñ"ÌØ ´f2üw39ÇiÙ¦.puÇ,Mݺ_’wXtNhâ‹Èœõ®Ãk¯ô4Wýxªó,€lÇZô£è;ÒWïɯaDíÁ/ÀWY¬»‡Œk³ÙM÷AÔùÉrâщýv¦zÔÓBKÒ  †¼â'ÁÄ­þÿ«ùN1X¿$ì½GK'',eè–˜ßq§£¯ú¼{øÖý8>ج»’µô›ò¢«Ù7µJß{¬W˜•7»ûõÆ9{4,Û^HfÜGÖÑÇÙ– Ò÷¾7ënß~½½s'ë¾øÅx±g¯¿ÒHFô½p¨6SþþóÊ>\s¼úØô‹£ç_¾3íÖËê¥Y™½r¸wë•k×îüƒ½åþþ¯þò_¹è# da±R›?>¥O ¹ÿuìJK€Á”à•N8镹ãÿÍ·ßxc{zvÖ<:>9ászq¾>þΟ¾÷ú?ã‡Õÿ‹€~~÷þîÛdL…o€ÿýÝj0aLOF À~hK»_ûµ_ó%Á ¢jÚGxÄÕ,Í[vÝÞÞ|r|\±Z-[#ðžš8`ŠëÚ¶a6ZùMwÀ$ù ¿÷º0¯¤ýým§g¹@y}0}5Fï‚àul*¸o»“]Ùí3Ÿn³³¤¬kÞg<¬ky5$Ó„üY7Ÿ?À<ʦí ÐtàPM7Ëîô”(hþÏR{ðb+\²¿³n¦ŽÿçñÚÜo&Ëkˆ)hÐËõ!± UdeY@þM9bÌ`*·?æöÝìÞ¸']^ºqdÒК'¸ÄzpvšwϬš ›ÎßK¦øyy;Á£.c’}ož´t‰­Ëî~Ù±‹š\÷õ¯ÿ™%vчý’ÆxâÃS÷}~žMvÛ›?âÏq³Òg±è¼|°·xaoo1¿qíf¹à?¡]ö™±rÚŽ_ Z?^}&$êøð:ÇÉõ`±‚@QæìÒÐdÇ'f‹».µõr»[ß@.¸^³Úì”%­ï`XbÀ{rÚáü3?LÓÓÉQx žËW¿úÕî_þËÙܹófâ“ìF5í_0÷¿BûÏ'Ï>»Ü^\¬'õl5½~}Þ}ðA×-—›.C(XnæÝdz,¿Ý´jÌ ñÒ-%Ðfé\¶ÛÍy#γ{+UžYöò^ÕÝDí¾ªæhâ öŒ?íÁ-©å×4jºåÀH§§µ[,ÞÌnÞ<£olëÙìáóèw»= :´ós5}'KuÌ›óË[1s»žœ>»T×-¯Ì9÷æ«óüp;9@@8(»sîÕ¶çƒàÊðvý”ëìÐ?äÞß¼Î~Ȭj@àx¸\vùÙØeN0ÉïÝø°§ýeÞ}ã/f‡‡w O|½1ýÄpàoØçvvô3^×—ËùßX”û/<ÿìÑKÏÞ:øÌÞâàú­gœXiJkÀírR•}çÖøï€àµÉ.Êx釈@Ý5Ë<ÃE=ü7¯?“±„ÏAñâs·³Õz}í¹gŸù9„‰‹7¿óþý‹õîôÛãÓû'ëûsµ~ü ã¨Ìé̾GÎÆ4rà r`ž ó¯tÝýÝ¿ûw}1L°LÞ}ûHoÆ7žÆ‘œÓw~ŸHfñɲWêßþêWC+~Œž©îøû½À~oÜïõïÚáúÓ=~¢1^ʧEç ÉñôÓâÀ3«£E¾7ù Î|Ïã*ú_ãLò—ö÷nÞ~æÎ­ýýƒüÅç^œKÁ}˜ñæÈ£"…€Á à[âTÀnË8.¦þ×®ãs“g7o\Ë«f“¯V³Ãkó}…õv³ºwz¾>™ÍÎß§yâèÿeíh Züÿ:þ¦`˜ž<FàÉ?ƒ«#À‘ì…îÝwßíg#_‰²7ß¼Zåñù«¯¾ª«üOòËä'yìÄxöcçKüÊç¿ppÄÔ³Ó&ÿüb>{þÚõ£—óÅí×nÜ8ºµ˜Ïl=Md+œH™›ǵ/О™·ÿñ ìåmV$ã?˜¯ Ÿn-,Wî’í½ñEaQ- ƒ({Då{ù†P‘]vHUçþýÁ!{W$§Æ4rà©àÀ(<áñ ¾üå/«%ŒiäÀÈ?‡/¿|x-Ûÿq/>7›Ïþ›ùbyçç^~ùó7ŽŽ®=ÿì³ùg^|1ü°ò0”KM^©¹ÿ§6Œtg«¨ßæ§Ë° 8!¦¡E@k« ‰}€z?ÏŽwнȋiy ÇÂ#ÃsÔVë÷ýª%Ày5ƒ¹

ôö{s68œMfÏ/gå ËÅþ³¬í»yxp¸GÄ¿’ð>ÙŒ´]Ò‚µÚ÷{C™Nþ‹ÄÁóaÖŸ@T!Dn_e¨H¸ NÝaÊoü@yVÜàH¨3í¶[­ù¬j¦ˆFQ·‚¿¿“w~¼ÖÓ0yr2¦‘OFàix ãFŒø‹p€e¤{·XÇòì"?øüÑÞþwóÆõç^yå•ÏàÉúÙ_žî„sßf—,ïD•ìׄï_¥0 ù?Àß.S¾‡¡Fhô$OH„ÙŽ#ûkp첓³û8®²ÛÿÇßÞžŸ¯ë?ü£ï5;c7½ k„ –Œ 眎iäÀ“çÀ(<ùg0Ž`äÀÈÿ2&ÌûH²ÙFï-ûùù¼üüÞbyãy‡‡‡Å ôöˆ•±eyßVoYàVm=Y¸ü‰õÇÑ‚(ì{¥NÔóÀ9E©1öêù1f€Ù,I52fv¾:ϱMã¶o½ýnðWï½wÁòئc ­ïU55~›]ýp9¦‘OFàéxã(FŒøh ³û÷³åµ›“YwÿËŬüìsÏÝüoîßzæ™éþ¹€€>U³ €ßM„ÁŒ£&{Aß‘ÏA`èÐ7_ð‚¨ã—{n%€0‘8ܽ÷;<žs¼_Ý{ð¨zðð¼¾w÷üâbU×ÇÇ ‹f¤z úžiäÀSÉQx*Ë8¨‘#®p@tž¿{ìTñöSúÕYYÜyî¹ÛÏܺùLùÂç¦3ÖÊ®7«î#ü†—?`ÎSAFðNIR¤pä\«@àµY©ìñ÷c €Á‚tï¿{ïÝîÁÃ{Ù÷Þ¾·{÷Ýûë“ãÍî{ß]nw]ýð~µ&&•sv6šüåó˜žjŒÀSýxÆÁ9 éÿ1}‰t}ëέÃç‹üö­g0ø^›àð†}Ÿ¿æzé\§³ö“†KÓõP+ñx° fÿT)mDØ_bpìÎÐúOÛ÷Wë«õÙy»[¯Ù~£B> Ö”üèå?î$u5~x*80 OÅc1r`äÀGp`òÒKGû{{“¿]Ìæ¿ðùϾø«hýëæ›Ó¿ü…ŸŸ±eoÀm ³aÞùúô'­^+€aû~?¬X¨™?ý¬©g#2ÛŸöp,ùº©W½Éþø?þÙéÙy÷ý«o¾÷þýíûïUÇw߯N ˆR›gǺßå~Æ×ü'ÖŽßO)Fà)}0ã°Fü¬sÀ%wîÜØŸÏÛÅladŸgôse~år¾4ô`Ò=øåÙ%¬«{‹ÍJáøgéG§ð ®Í ܰKàz}‘­6›ìôô¬>=»hÏÏ·ÕÙEU­7MÅ®Áì.ÝÙ¥ŸÁ`,!êŸÖˆ#§c9ðtp`žŽç0ŽbäÀÈÇpþœ2ç/¡”ÿ½YqðÒ+/½ü÷_þÌKŸ9üÜg?G4ޜоlI Z7¬ÇWýNŠxoÞ?yZÐø+`=LûqL ÏÀQ¹d‰ßàè'ú_lN²ó‹c6þ9ëþã·ÿ¤:;ß4ÿîß¼q|z¶­þäOÏœÕ[–ÿ³ùu»Z¾û_ ðî¨pQ‡ýqn ó¬7¦‘OFà©x ã FŒ¸Âá{:ŸÏæÖ»‰–ö?»¾œÏÝ6{¹ØëÁ|ruv?ÃÜ~œ&¨åÉ0j…lª¤ïpþ› õãG€#K»‹ÍEv¾¾hŸ¶çgëöÑéÅîâl[oCópƒFïqÐö >  ùßs? –›oÝ4PNÆ4ràIs`žôû90r`à@`óÑQvˆæ¸(î¼òâ¿rxmùÒ/þÂ/ܾyãhïððÖôðÚ3±Ô¯Ú¢PcªŸ¹‡ä†?‘t5ú@wû_gjÌùÖš,ÐW¨ñOc…€ëûÝö·B¥ÿÞ;o²ÉÖq÷ÞÝ÷¶ß{ç{›³Óªzýõ‡§˜ûë7ß\Y­ºr¤œçW£gOÍÐøywþó¨@!à]>ð±ŽeƒÀé˜FôOÖÀÇ ¯uÔA0¥äÇ2VógNe<¸ß¼õî»ÕéI»{ûÝÕŠ ‚õñI³Qžèyð\÷#À üšùy¯Õþ=:=`-ƒˆÂé˜F½sþõÐR p0HœŽiäÀÓÁQx:žÃ8Š‘#s gy]ùÞ{Ç€ææáÁA™·ÙÙÃÃEöì[{Ïݹ³`òò /åóÙ2+rWhÖg{^Zè Ø²bñ²œäüµP “Ûn‡pŠÉÿ­æÑñYûŸ¿ó½Í»ïW|°ºxç Y{rÚm £L!è«Á«å î‚ÿ°Ãß ¼GžÂ1ŸÁ"  øûÓȧŠ£ðT=Žq0#Fô˜`§=9Ù^—Ý~óóýÓª¨vE·Ýtùþþ>(^d‹ÅrÊv¼…ñf³Ö€a@?X­Kè_"„qý.\Þ·>éŽON›wß¹·yx|ÞÜ»w±~øp·;?«7¬LþTì5÷«á{ÐÍó8|´ü ÖÓ* Ààg˜0¦§“£ðt>—qT#~–9 h¶÷e«Ó‹êÝé¤Z¿õv}ȲÿÍááñáѵrsp8/>ûÙïr¾?ûìËwØ x1½sûÎtoo/ã4ÛÛ›bXd{Ëgˆï“g‹ÎgçYEР·Þ~‡M|¾Ûܽw¼ý÷ø½‡Ç'ÛÝÛïlVçç5ëûÛj½îÔàý8‡ïqÐêó¾Ú¿ÁÿOø(¼ÃGз¾Ö‚üa˜ž^ŒÀÓûlÆ‘øÙæVüÝ:ÀtWïê ÊýªiÚ¼ÞíÊÍfWÎæ“b³©Û墜íí-òédðï&{“ɶÎ'³b9i«Vÿ"k÷X-7Ïp00¤ïñ£Óæþƒ“úÞý³êþËÍñqµü·›MW± p˜óÈÕèuú<ªÝ›7̳¾u´ü4™ü'_úb¦£Eö-¿>"½úêGü€ìo]!d³ˬûú7ƒwWkÿ4ñðê}=5ç£ðÔ<Šq #FüFù=6ÒïééÿÏÞ›ôÊ’d‰yóxãŽïÞ7äË̪¬¬±U-5«"ÔA¨A$¡V‚À´ê•ZÜiÇî´àŠ?@¸!$ÀBƒ¬êêªÊÊÌ—/óÍwŒyŽp}Ÿyø}¯ª²†Ì|ÙÍb_»×ÃÝÍÍÍ3;çØ±cÇ’Éx¼ÅW›âÙy¯Q¯Ê>î·J¥¸P­=Ì•Êqn§“+îìÄì\-ì´Ž*x Êuv&Ñe°™cÖÿñ'gÓGŸœÎ/¯³ÌúÓéÅ@âw4!™{8ª¿àPåïr>ÏÞûÌ¥~jœxÁ!Ó÷ùv£þï/ªäöÙå0g5ØzT ¤ÛPF¹b(•šéÅoø**Þ~;½Àt#Ys<]äÁéL£ÉWWJˆÏWï}õ&¼F ܯ™¿GY9Šþõ¿þÇLŒFñü\ £üb¯•ü?þ¬ÞkDÉÁAXUE¹n÷^HO²_ FQ«U„è}u»QòOþI „¦Ë¤÷ÿìâ+Høµxy¥ü¯$ÿÒ.ŽœèL§Qîïý½·sƒÁò—Ÿoùx{¾÷ ÷­V”üèGi=þ›sM€ÿ: qÖfü¦ŒÕ¹#sÎÄ'ñp8ßT*‹²#úB!‰ãsýÅ(¿³S¬ìîÅ–Æ{u—Á¹q-*Ĺä⪟°sOòèqoþäÙp:¬g˜°…o}fª{OvdKúéËø³y~Uÿ ÂeaþëÄŸû\á—ÛBž¶’ÿ´¶òÆõøø¸ZøàƒQýéÇWû…’hnžo9ÇËsÅq%ôk™ º‘Ò.IðÜEU/ØÀi…À5Û¬’Âô¿]˜-f¹ÍI-ϱX ’““hý§m +â×Ó»›ß/„_[W_(×›—ÿSÆ@îý£¨Üj½]š\ :íæí§¹MqS[ó«óeüwß}çÙãe­¹ÓÔ ›½zºˆJY¢´¹è#Ý.ìÏÎ>Ôy>eÔ=œ¥D“ðFç½^n9™LQ¥Fë‹‹hþâEIùFÖy¥ð~ZÈýÙŸE% f³åçó(wxEYÀplóOÿéõh0‹¶ìYù³¸×qÎ}ÿûQ¥×K6áX÷¢jÒØ9¤úŠãÁdÃ8½ëêÎÊ[ÝÙÆÉë¬Û;Áÿý‹ɬ^-¹Õ×¾6Y„‘®¯fLÙw¿¬z ®jg­ßõZ,ÃudîýrµJÊhVøý‰ê§˜X‡›y\ÜÎêçÓ7€vÃÀK 'É žs~>Y\^.õç¿dÔoþ~Óo›¿ßñ{™z?sîãhßgÚ( (4(”ü>„Ü?ü‡QÕ6+°¶•y¾Ú©$ÕÖfS®^;…$e„qe>nµr·âxsçÞ½R®XlÅ› ë'Ö]¸B¾ùzn³®%ùâ;áRÉ5!¤:«†|ðšÜžùMúp´ŸpÈŸs,(Û êÔ{ °åø2Ê’å™ ² ÕÂ2\ÙŠÃFãýhþ˽þFF­@ º”;¥Ìc €üÊx’7ËeZ9g49pl÷úÁÆ€ô"A.#·­:šÏã2 ¿å¼}.LÞg0sùŸ|`eEò·n¥m…6|²Ž×·ñ‰Ð-¬‹÷ie=(‚«2kÿ¤ý1òã´R+?AÈWµK+böOÈR? zZP`ú…×iKÔš—Q ×P:¯bº ÓÀ'è'«MXÎæÖN­F,¥ú_ê“óÞåÕt6‹OžÌq‰š[î– ƒ(ɯ~øÑàZ;¯Ä÷U"œû7uÎÿý躀þ]EEOuxæW€ÅF £³Yn1ªÔj»ûÕr¹ööýF§V/•@êjº˜¯†ÃõÕ~ðä½óóÙøáÃ%ËØs‘©H¼,¯Äëó†ü÷¾• XýÊÁA³ó_~÷ï–ÊÅÝÙx3öWSô´õ¸¼y#Žãr§³{˜/pQ¨C¤Ý9-nÝ>Ï$ÎðýÕfƺ7¬î–«q¯7x4Ÿ/Ÿõ¯‹õâüjü!;áæ“ä¬ßŸ]°AÞ”:ÌFç2C³ú¢9£G2s™=ãÔHÝr—CÆï=çE¯L(¼ä?æ%¿q†a-ç9çvÁ© “Ê<¤ÝàthÍyU®ú\Ï[âˆi„Ñj‘LŸ=ž¼à•Iÿjóc¤Ëi™PdF£A³ÔéDåjU¡´¼ÃÈÀa÷÷wŠòwþ«wXñÍ•uzùág¾ùøÑ“ÁjµLöºe–MÂ~©’Û-*zµ»3_R*–œâB±¸>.•6wž¯XŠ9H½ç6ͪ”ÀÑ?8»JY4³pïv̆à—4ì— ½ S)¥:GƒF¦\*Ò£d6§Áή–èpæãQr¾bñåŰ·A:C‹óôÇóŰ÷á‡ãÿÝ¿ë?Ô_†š™&æ‚O(€)¤¥äâ&|6 Üh>¾þ“LÍ|}±V+ï@¨™ÝÜ^­âK ÿWºÅ×_Œ”N7AB_Äùâ'qa>ºDo|~1ÆrºX:Ú4v`"ñþn÷»Åb©ÐnÞʗ㪒{Á" Ÿb¤ƒ#„Lª×µêxz‘Lg%γÙ|‘œOfùÙr?e0X- Ÿ0úúÒ1eöPØiiI<3!ÀNüE™Y|±ð‡ ZÊí¨Š—Y/UŠ ãwJùR¡²L •B9_Mf˜Q±^Ì•¿RÈWvr…ê=Ôí5ÖžÏa.ŒhæOb Ó¹„¡7Ik;Û…U7fAüeO©2ÇD®×î&óîh<‹zÕqi2^_®˜g: mA¨3ËdŠü¬i„r}Žß7Ø2Aѹxñ—1_éLw-ÐT‹4Uï=¤qô~9ÃìajNÛÐ{hà0–¨Ó‰a0Ådo¿Þ¨×K›ÃƒbóÎRgÔ_ .ŸÌ'ÔÑàñãE›÷ÍOÆ# ¿+ Ù½q¯=|¸£ÿÍe©tvšµú>^‹Ô0ƒnÄ–M3YÅí\T¿‡PXÎ#V«¸HªÖß(i ZÁo¹¼u+9¤ï®vwvÑgU˜6ŠË8U,ãi)®”ëÆÿhó+°xDvÞo ]£<ú‹¾ãð+ 0:@»1a˜c1Ò-˜}F%„÷Á’oþ‚ø%ÚŒÊÇ(J&*µ M³u¢6‚êl3˜Ô¡wsênÙÁ& M¿t&A Œ„K…ëö‘á?k7<º ¿ n€ßKói‚áóM:|-É•¿‹B­‹Ê¯çb˜Ϩñ]:R¹];¼oôR²¾h¯Ãe‘Ïœ««W’¨Ý¨£ºkÀØOŽÜ =Y“l-c‰£f[¿êtSz»½QU±‚½ÝÑ¡›Î:­F€)û·惓•\nbïçvÖØôÇÏw‘î×gƒwŸŸ^ }œÏ.^¼8eš`ØjLöìȸY{˜L×C„~ç™O9$ð|;²Äõ:0{ ãÿæIËH@Cm¸þøè3òy3·NÞ lA…Åõ{ÙÅ&ÿɺòq<‡,­É‡YL €åbT‚]rO¼‡z¿Xm´aüÅfå YˆQ”À4Öäüãl £Î¨V:Œ¡ª¹V£Y‡aÇ|ôp=|´\Ì.Y«ÝŒ–­Å**5J&ª¯½,ö÷:š;]&nh¤ip²F½1žçꌬQÉÝǹ„w`UÐ_50œË…j}·Ùˆ«ÍÛ'ß„h×nÝm·š­\¹ToT¹G8ÊQoVŽå È€ç¤ãP©Ô#í‡ԫDܧù\'zPÙøîá¦=Vôæ ßa§¼äƒ?Úc ýúôôâkÏë/·£ù‹ùjùƒry}9-ÿ#£2™¿óä2Èk!‡ëÏÊ|l–ÁüþÔx(ÈÜd2gŸ*•¨PɈ5Âp-ä‡+Æ¿XØ)¡ºi·•&; ÕëÅÊþQ‰ËJñÖÁíF ɵÆ$P½±Üô.&—ßvYEÑ/” ÔáZ!$S=»À Àc›ýÒBïïG•Nµ{·\ˆZ¹üú[ø8Ø«•rõ\Rh•Š…b9nתUºðî]¦íjš¨Ú+¹ZµÖlÔXÒCý¶Ì–$I1_\܇™G»;Ç6V¶ÓN˜¡=€¡´­°ƒ¢  _èŒÙjH Ûê­+­˜ëÞ¦6ÀwÂ/ò™Æ±Àfû"ò[M«-ƒ@W‹¨ÿC;D‹E†¹h§ÕÀºs™»ººê.fq3Ÿ¬Žs@9ê¡©¾tÎä‘4ÃÏô/Ò îoÂoÁÀð[ô7õøÿã(¾¼ ›¢0¢;®ÀÔª¥Rí•\ƒiç»Àµç*åZ¡˜Ô*ÕÜ #½R­Z?”M•‚‘T‘ŽêJFÏܞß|µˆ!On³Šé|1Äóébj%r}:1L>%ÊîiUšç2=ìrÛà\Ùò†’Ço;|½i0ÍEú¦Òj.6óbË€1êÖUuggv»P\¶6¹Í¬ìËE~6¼ÐÒ7ð@3¸Î:uøJžmáRPZN'Éf½¬Uã“b\m—K ªÏ¥e[£ÖUxId8.àßítêg«U 9§v ¬AÇ)Ç(BYK$-ó @¾Xi4vxеb‚”Õ·Pà £7<à•«y`ÉKðq˜¿õèý&ŸJzk*è¶T|[©27Ë1$øÎÍæn!ÆQ»ÙÖ¡Nâ$Ït6aÔoÅ!ü/®×—4+Eè¼’Œ„øÕ:L+ÂL?%Zî_ý«o×h¹j•Ym í_äŽÜùù"³ž<Ûò–^¼˜Y·_¸¸X°|mc€ELrlðCEÃ#d%EÐY®ó¹ÉÈ‘ëj¾¾£˜P®¤U/¾yrôã|®ŒZ}Å/¹ÁìÄH¦¾%”*9‚h`š —[o*ô‚ €… ƒ.8Ž›º¼Dt,аc*[b?°¹…èQCf€©FõÃøsûné¸Y/$_y«úw ìØh¶˜Ò@7PY—rlz«„e0ZcûÛ£B>ưšÙ†\)·Äð_ßä•ÜDF»½SU½_oÔÐNyXæaÚF6T”œ+`PxCå‡ų õiS;<uËê«$Ê„2Ãé4÷ko¿ƒhµ‰NN;çWu%z@IDAT§õ^¯×.7~÷zã«ÑhZe5ÀÉ‹sî Ž’]&§”иü…ûgÿ,Šÿù?ï"–þh±(ÕÈI+Î sQ2ÜšØÙ+3X-ç¾ózže|yÒæ˜N*°¤k–¨´\lâËþ¬‹±Z}>O‹ü=\ Õ«2ðŠðf>Èt¨oêµÎì]`¡Ác¥Ø¡îó¹Ñìñ¦?mfóMþ¬¿(úóÚt‘ܵŽ:=ËxD™‚«÷iãàâ éqþîÝ“Ì.XÒ˜|e³Ì½Yj”ö»»íwËåR{¯»sÝ~£ÝjÅÝäBæíÈâj©„e_û7øa¾<aÞ@\¢ñÚ¬ÿÕr‘ ùrgÀ·~£öÌsÿl6¶Û¼{+еÂ9܇çô º‡9ðZèO¬(âŽ{¸ÌÓ¿Šd,³§ž¢5Ï‹Ex8@ÚÕn¥ísÍ Ü<úñO˜Œ°ü÷ÿá½åÙù`ññÃq<,š¬àXñLõŸ iCõ[7á3càFøÌ(ûR_`®×e8qµ“.Ze¬p£CT¿ßDšo¡Ûû«Šòr¯\¦»3½W«´Ãͳ_š|¿RÅÚ›óf!£N`æZz¯DŸŽ UíÃT ¶ñàެnå} —ö.»szN‰‚„À‡‰„^žâ$eŠét#‹E”Ã=;ý\!¥0cáõh8ŒÄSjå’Ê!ì\µ áÜn!`v^ y¯µeðìÒ>Ãjźe ™c'ñ¦ÀJ’Š>â1h[¢Î%MÅ朇¼’o4ãM§Ãòü³·èk£Vk•ÊwОT n ²rµ2̼Zdþ¶\dZ¡ƒF­‚õ[ š|Öƒ(Q“³Ón«¶…8«ç.þ~¬ó0M#¬ÎÇrF` ßõÇø·u‡™gNÖq‚pnÄG­Œ£X²,# ºì0¿{^;DDÒ@ëBk -4,1:Rs„lPø´û·ÿ6*üÉŸ”iÖë»Åb®™Ï£'˜Œƒgr +”*B\z™à„ç$¤ž6qãl²?™¬š“IþÖlV`Y«*“FI­F“5ê¨Zr."a [‰Z§\)£<ÂâÑ4LL¡ÚÌbueÉMf«x”¢ Úþe°[2_zDÁÛÙü':á&a‡3(½§ ‚{ú$Œ4<ºîY&1mŸ‡ÈW»ß+×2Kº¼TFþLçg:a¥RZç oÊ¥áx½_oöq¹ÿÖhº\V«³Éd¬¦ÈÊü%¶2’ñÃg§/ÚµÊ?ŸNµ>z^Ã'\ù`ïjÓn­6ÍF3×iws”/OŠL/YŒ1‡Éª~—Ê•°ûƒÏKèÅ›D)8ünñ‘–Ñ‘ _%¡$àÌ’bI‚mÒÀXU#©ä‘±XÔ¬1¸*ÄÍVÜZoŠEw†¾¼{§S¼{w·Ô¨•ó'Ç;¨¦®îÁT™Âm!»ac€î_-Œ*ŒHÝÄfLÓ Â–è BU¹¾Ú2A·¾(äž­@'Î-ò¶m„F"üDlƒeVŽ ¶Èç 3†ë_óæÃ LÅÄâ®UcÄ&*ÞÁb±Y­•ïݼÝë͆Ø.Œúý„å¨IÒëÁ>Óº3ïÍ6 ûí·£âÏ~µkµ¤ûío5þ€Õ rßêÔ‹þ‡X—€c¤¥€ÒgPæA&6VÛ«AíßÌç÷§uËár¦‘œÐù‡ÅL WXßL9àd%;2{8U ó;8 Z–Ñt–Œ§‹Í`¼ˆúƒUi0DLÞh‹>™}6|û‹þÀüKóùî^§²*~3º_†£ï}ƒi©N£Ö|«T)ß­–+ÍN£³§r¿ZÃVFÔŧ+Ô¹>ä—ŠÎTâÍžÂË÷ŒRÍSAÓ£½mX«!Œ8mÛéÙjJ›D¨ªPÄÀ¬­=KOà LŸÇFÑEBÛ 4Å8’¯r —þ¤·iå‡lÓ<êУ1òg©âùi4“ž¢¯_Ä{33hsÃyÝü¼ ܯ_(ˆ€]¢\¯Ã!£ä¿„7|•%yoתå¯ÓáËG‡ÇûÌ×å÷ßÀ ËüãKú”„ßÎú¿ÆéÅhÀgOLŸÓ¹íÕ< ñ&fä'10Ü |7ð;5á9I‚ôγÀ3!d—^¦¿&òkœÔ.³%ŽPjµßÑÁaÙå>¨ÿ1^Šæ‹õüì¬Xf&÷9 Mµ¦þߎãéŸÿoÿ×âÿÙÞ^qç«_+ÿ/•Jyÿ¨ÛÛtwÖÉÛ-p³Ë—5;(×ý¬gÃ@ÜšŒîÐòn  )˜¨õàO[9)^Bù±h5NXGÔ´@·ÉĪ…T¨‘ -–Ñbà0Îa Wj5sXgÇõƒƒz·Ù¨ænï6oïuêeÝ9>fu1j5ZàƒµÑaÙUæEñÜk˜‘vN̂Ɔé€;Õ©LXsÍ\áPÛ£¯\–R…<„;Œ´€ImB—2vŸlÑñP‡[–fÛ% 8GðsV¬ô/Îc]Ç®2X¯»Ífµupðøk¬<`'½h8›-YŽæàœP€SœR¸À骾syY8 㿳^• ÑÞa¥´SÎózXª\Aë¬ÁŒŸs–¥Ê$5þUJjŸ"â¸Äî@K‹@Vä/<àå£bñ¼YÅ2ƒ;òX̦0OÖ˜çÉx²ZÆ‹äj¸*±ö\´¸œPzùZi&+ Ðø­ô:Á\^þ¿Î’6V=Ìh¯Óít:;Lõç÷;øåB«F+ %¦-;jÞl(Ÿ}Þz_`yê9ÔmÀm AMQ¥¢­Ë¶¿““‚¢ø°žÍC ÓUÓw¹ m‡h™|ŠF°i{¡=Ræ4¤Q5>c6äR„÷ÒfÈ(?ЪŽ4ˆã| »„" F$Ÿ<ý(ºê6?ýÙãñUo¶üø£y0ØèPlN^~0ý¨Ùބׂ×Ú˜_ D‹2q¾ÿ xú­[ÍúxܼKçÜ«ÕZ÷Ý·šÝn§ÝÁd§Zĺk :> Gf”gÙÇìai§»F0{ä/úÎu÷I{¨#§l¾Î¤¨ø¾4{ÝÛW^5zÛ‡C’ë,á[¿zà†±IŒ¥» L°£Ûé Êݽz˲q³¹ÆØjµžÍ6,S S j‚0€à°K#|ˆ—¯ú£!ù5š­^ùâêŒån%T½Ý`ßÔÚP!NUœ¡Hâ/@.›#dx¢á¹q„€cÎ'ü ·I_–7CŠÓâD‚«Àĸ-k«ØÁ@ýð »é ìïíÆöNT)Kˆ5ÈbtÏ‹)ƒCoÎ5~m!â©êÛ9|¹Nf©XXÍáÚiãßÂ.órÄ'޳2¯YeøCɶO|´=ŒÎÞÛb%ܧïûŒ+˜{PÍ{¨”µÖNr»]lªùËË+–'FkŒöÚ0ëÏQ¿ŒÓ:´±*„@QóÐüÒÕÕ²xu5a¾å|0­™ŸÆøN§óšb€sUǾ±ÐëPìi}ÀÒ4AÆ £b¾žå!žLŠ~)0;íWÒY&3OKÎྦx`0ð§ΘÏìó¨ú™çïV:yµXlv‹ùÆ»´•f«]º‹-Bópw¿]®”ª­& ôËÍ«õ eÚ´{¾lÿ5Šz—[ï´ŸL…Úq(@À£ö-L1U$Ãuš0E¥ÎÚ ¥3.„áìµ_Hƒ…]ÉÛ0ÿ´ßë÷Hçu0ðó5¿«ÐŠÀ´dd›OæÐƒYÄ~ÌÉÙyÙïOVã ÎÅ™ÃC(É„ÆLƒdáÓÊJÏŸÂMÜgÀÀðõº“~ï{;u4“­Õª~Û¯ÿ‘Ÿ'LJ'T­ÕöwoÅGû'Lÿ#½ëÇ”«ª ’:£g;¼’x¬yˆ"]#tj»ˆÁ— ž=±r‘uR“ØÂCd>0g»ÖÝ·Ï³Ž Éà)Áñí4@ý`øÎ66Ë4K’> w&³/ë.Wò£ñ™qwOîåNŽVÌ·çÙhdÞ8;v..–,À/ÏÏqI3Úœ‘LÆ/ãÀ³æ|9þñøÓ$çÉæ½»ÍVyúNïù~ôä°ÝìäÞ¾÷-Œ¢\«œâS1^…©¯2„€,¯¶Ä$fà³.2”-c¨)bÓ¢Ê*LçèEh²wÔº¨MØäÖùbi•Ç CáÞmVAå£o½ûÂ~w/×b±uçê‚°Ä-(fꦅƒõŸ£Þ€°‚#™<þYÑ2mÁ*„Ô@S¢ŽÑ& ¤„Æ\©Ê7Y<°TNø¬;1çÃï­S…ãlWÛÇ¡}„¨ô™ï¥¯¥¯e$4Ýûh1æñ·ßÝœ GlÑ7úÉ8õY‘œž†•qJc´éxÊ¡6€ ÂE€ötzQ§ÔWµJ±Ð`yãn·Y:>º›?<8v¥ßÙ2º/–1c= D _`æžIi½/mϲ >• öyOKõq«·Ûv`û—Ô—,ó‘Å *uÒ“²©-P&Èpù¹‚n£ël°UÁyÏ=ÌÞª–Ê÷X«÷}ç÷ß|ëîa§·î°,¡ŽÉ ëyè ¶Åù|êƒÓP_©êœ­LÙdí_8õu]ÂàQ£V4`ÄYíˆNÁ3Ú„#wë‘"Ù$dÐ<3ÏÐh¬÷4™§±¶n\A`» ð~úØJùÉtâ’|& S#D‹ì¨'Œ´_Bsׯ»°|iÓs6>ðì:݈èQÀµDgKhk°ÛÐ¥BT¯Vó®Ñ,±ÆYÆmnéê ÏÜy <{¯³ï:äv è{Žä2mÀ«0œn#RC-oÄ}¼òb†k~Â(ЛëzMqéeø8#9‡Ëpgœ±–•í¡Nh³y¢IµÌüjß+Veä±êß̨?å$â r" #Þákøõ(“ád²@\uÚÓ·S¥µ|,mã¾à¡ ¦õjHk#…)†Ó´/Ë–>»ÆÓ¶HÙÛ¢ÀgÖååDÀXáŽÈâ©ÂB(p˜.r0a¿ÈdÄë„"‚ èe0ÿtú0½NcÃoú: ¶[øB>4ñí âÑx²éõ†É`0]‹%{ˆ±-se,®øÇJñÙ‘á>;_47á3bàFøŒ{ÉÙˆ£JÛ/l¦ùï±’éOªÕÎý»w¿òwÕFóäø>®\0ˆ¶+Óqì¤ZÆÚ‰s6Ï®œ!À! žâœ¦ALèïj L«ªY Üô.wóŒå6‡ý&í[2dVÕ>†³0òãÉvî[;÷ŒÂ©æ¶S_ßC΃€çÀ px$á £Â]ú¦ÖÇÀœy:—}ûäV©Õ‰‹Ï/ çÃo^œzb%ë®ÙiH¹?•þÕ˜å†ÁÎòçïÍñ‹wq¾˜ðର×mWz—Ë}l)òï~í ÖÄ«no1rf½3š`ÈFÂJ2Iq‘²Uþ½ ̲ràR‡”¤Õ6 `ÖR‰ó4y8‡åy,]ʼ\¯FÕâÎîÁðrl‘¼ÇH¬Â÷!xi9’smiQ/0:™;«Ô€WRï3 ýX?Xw>Û¬R¼ú+Î…‘}héÈXcϼ3~)–¯ÂQBym3A 2ɶȪ’-ÒrqI¶Ä˜Ö„i[ÊòLÛŽí§.PûwŽ#Œ:óOž}r«Reéj‹ÀÁ4ÇÆ{g——¤Û\Û(¸ºÃcêöXO&“áX-ÑŠ×?©³JâàßèïÜ¿ÞÞÛéæßºÿ.*pæ¾Õ°Pæ°ªAà N–1Ìù§£^ëTÜ„æg®Ó ʓ֣ñ¦£9Äç6ÇûZšy?$ìˆSçÙj…WZG Â¬Ã%¶Hµ>Ë>Âå¯ýõSVüô—º,VøXuðÖááîÝ{wÞb¹gùÞÉÉ !ø˜ž8H6Ú Û0a$h†dØØyX8÷up4ÜsSj›,»m£ÕdÊÑ?Z…È>°€Ùö‡¸k¤\ãQÚfÒÕ? í«Õñ   éjƒÌÙve»1Oƒm& iQà [ˆÑôycSQÉTià – ÜÁÕ©Ú8.5m+Ñûþ$yqvš¼÷áÓñü!²ßzþèÑø‚®± ]j+hC"Ž=»¼TÜk¤6ÀiAëDÂççcðü&| n€OAÊ—ewɱzÇmKÑÊåÚ#ïcÖÛ­–* œ¸°¬½–óØñ¨@I’oò:Íc†áÎ42†­:ÁÛðq9HÒœ|’]¯^‚eRÛQÛÔq3f}v©:«•˲Ñ`Bï´zòèm©CÆ + Õ¾ÏÆãÕ¬ÜGZˆË¹þp %Çá¢B‡Ü¡ [ä¼y^‡ ZÏÙqýðúóHSõ)ù¦ÚÅ‚ÔÀÊÑW­æ=• órôžàgØadÀoÂåWS-·¬òçG¼J\%èΛŠKÒ…¯sYl!±Y„ÀE(´à)Àm£³“ÉL›%²Ú/%ºÎ+¼dÙLý2Qö®™„æÀ 2XiÃ@|&YÍÀRü%ñH-NXÖJ&jq¤7 Y2Õ3£®Kƒñ|ÆÒõ9Ó «Ñh˜` šàƒ>‡k…íÔòñêœôô¶ÐÞøè˘ì3ׯd%2]ÚF‰áƲ†G™qM8<Øjݶ?;evxŸJ#\|JÈ}Ÿª=¥ì0¶FTÜ´ËùÒ>¹Žê wé÷xÄ X¦Á§«dØÙ|¾Ò“‡IË•þ kÖfBÛà¹m%çÉ–ÅwxwM~ô¦?&SlL0Ó~¡ó¿"?j \…â[âį؂EŠ8‘:‡S ‘ÂÀí§†_|LZó°3ú.¹Ž§ÓD‹ëšyÿ%·l!ž07õ+dyd—×)ñÊÐò©ÜDþ6 Ü¿ C¯é9žýòÃáW»lOÊÞí‹¿G¶GwnÝù^»Ýùƒâ'o0]Çz^:¢R?=—Ž–2c;{纱]Ub˜= O üÙá\ïk§›/‡ÌëO Óèêü é{] &xæE†gyÙ†T]YP);R.D»xðܬîkê|⨀Q ½ZÃ~aa¯ ÀÔT5ªž–°„ùõ@4¡‰ôùÔˆÒ1M¡µãû>‘eX㹕{Xµ·‚¯r–‚¿ó1–á=vÖ+ÜßDg5ŒÄ°Âf’;•ö•ü-±ØXŸO³·û"û \³ùƒ9ÓÅɬ×BµZXÿÁª‰óœ½³£5˱f5”‡ `m©V6¯.æý»¶ØâYðű$0c5׆”D®×– n…oï5{ëhݯ‘ŸŸñ]©wÌh/,MÃ×Ó!læt½ú LËP• âÂŽ|SPBg?6<þ(¬Õñ~9,ksäˆÀ>¦m‡!H|9bßKG¿i±D°Ÿ·iSãäSD¾GȘŽ9„U$|³X§í°1Ðááq?ô1ͬY*]á”G†¹ê˜’ãC!ÀŒÉ¥ÃM.H—|8}Æ\ýx¹y´|vzÝ>>gõ^¹Ùi·ó{‡Ô_9HnoÙ­ËüÒ{¾D&äð`=¶§ yñ>”t[\ïC1U‹0:ŒôÑ_ÐÔ¸—-Í7"Òvç¨ÓѨgÛ£Ì蕹ۆï¿Å¨¿¼³3OnÓþ;Ôþ·¾rÿÞ÷š­Öѽ;'•7߸‹“¢û4àéˆwÔ a½À7ÕH¤¶Á”kÜà“0€Ñ‘¿+[p@4"V1î§h+`ƒœÔg̪œ^œ%½~¥u£õ{ïˆÂhµ9?Mð™À‚X|f‘n¿Sév%¦¬ Gû‡ød¨äºínÐZI‹´dµh˜é÷´g‘vQ øPCÈ´]yc›±TˆÐW½LçSæüŸG=¶õûËŸ¾7úäÑÙâñ“aÿñãå]c£À âÙͼÖ¤ýܳZã?æ÷9Ä¿mÉwnÂçÀÀð9öy^aoøÜoLQΫôaBîªÍÜ·Àø1úiT‰ËH%òÂÛÕèdi{IÌì€)S’ô¹W† µó«JÏÏ7‰ h 'WŒfÉéÙ(™LXYãò!úœ>êu6¹Çß}­ÞÂ&Šs¹ Û‡ñ‡üS2šŽtå!äϨV¦ Uº0ªþ“iej?@HA¨ë¬‚žÁb¡øt‹Êl>â²­Zu™o7[¬ãÞlj•¸Á;F%Z‘»[â+ÓðmIMFÙí43ÀÁ ÝrS.÷GÕj¡|x˜T¦³J<™’éœáe‘Îðö§Q Ñ|}¹×¿RÌŠÑôJÖój­+b½ó—ŽÚ)_B¦’L< ¾I*ˆ¶‹Ò!°ˆªw <¹@Ì}î_ø’8†hìÀc¯:«8Õ(–Ð*4Œó §%Hr …ñj›oŽ4k~_ 澦ñ‰·¾nȲÙ^³ñ!eqU;"Uk íÚ-Ôr•OÎá‘ir²:Ìr ²Ù÷zë àµwÆø^ÎYS Çøq`«>„úæ DÊ2í'[Àl§¡¯ðÜQjH#|„PÌ-Ì^§cÜmq¸ßŠÙ¼CbÛ¥såÁŸ„Ðï”1e#ÐŒaõ)a¼Âñu¾Ž¤»K-½E­ÜBËwŒÚ¿ËÐÜN{—"ÈèS)C>¡/Q®ìœÎÓ‡Ò…X®ð¾íƒ>Qã¡h´1Ñ(p<›DW—,­D?z†ºX?}ÚcÇͦXJêt>*Lç-V¨´sj´­&V¬N;…éCÛ'™PÜsoÿA$‹. 8…WX­ˆÑt±x'¹¼¬.¯ú‹~>ƒÊ?ôÅ€_û{fxéÙÃ)…€LøÊ˜¿¼ Ÿ7Àç@Úçx¥€³ ýÛlò¶óöý“ïbàwïèàø¨Ýé«\¹BDí3é¨ÒnmÈÚµÎëôœÎµÑ!R¡“8Ú9C4 FWÌå­¢³‹çk–È­‡ÃÑúñ'§‹ñtɆ.Sæ]7h9U5®TÀð+cæZ ùÓÓj£„”½n/Sηš"ó„,Gªá¾«aâ–0¤š\G&gÕŠÿ¯@Œ…8, 2%p„bœŒ’àèÒkvõ¤J(Øà`w‡etùøä¸µ»ÂH¢P˜Œž>^œ‘s{G“ÝCQ‚_ðL-¸fÏŒ7UÔ‰•Ÿÿ|ÂÜæ²¼¿û°¸¿w^¾wwY<9r8TòGŒU“³ø „ößd.0ZNÛ³5 °.Ÿ™`dñ¥}–]¼<(ˆòP##³vŸ «ö$ÅB‰ ÇüŒ'M ÿ¸wøâü,yöüY4-6ggWl9Œ'Œ 1òÊí4KØ1‡œ®4p4ž#Ÿ•£Û-+T÷]ÂÚQ(BEVR‰>¯ñ·±]YHAZÿ…Ócûš¶ 2ì8¾ÌW¡ÖÝ-tñƒ°b³Æ5&ÃTPPÈèŽÝ A¤àÿa:ÙÔúƒuñòjÚzòôYÃNF¨.“WÎÐoB:O® gÑ®Ãö:€—]“À?%¿ô¼ÝúõŸÂX®mòÊÚEZÛ×ùÿî–/·,Uîâ³ù‡í·ŽN¾Ê\ûîWÞz£ÊÎM.ýX ’Îï/±åð›j‰,PÚ.íJ¶ËP¡=¤}IS €sêÖÅŠÊZ#ÍV<è±­ñzÍþ SÚÚ&Ÿw‹o8êh<=}±)·Z³âÅéB äÂáái¡{éV£Vl·ñœLŸa/$µ²šEZÃ4°¢™OVžpRm‘ëûPIË¢^6UD痗럣‰8¿è/?yÜë?{>ŸõKàq7¢Ð¯ªíÛflöom\Q’¹™–ñ›Î º®:®oÂgÄ@Ö?ãk7É?$“0¯9íµ¯AQ»Ýo±¡Ï½½Ý£ÂÞ.ûwh¼2´-KRÂóëZv Þt: A c¼ìˆßÕ÷ªßGt8gôèÉ“õ£§O½ËÑòá‡g£1Ël^œáyŠûupÞeç0f¡Vwžâ’ W©{·ÎK•j1|´S;ØkçÛ­\úâP• ß•u¥p@º$0GN|<³küX0¹ $,!²„)à"M«kb—nI‘v:;0ýBqw·¾3™TJÃᲇ\[Œ@/ÝÅÎÿ ‡¹ìpøÈ#‡uÁòAGž< cR«~\½¸*oX\ëÜ&ó­\±¤{]-½¡<ˆØÛ"4àÕ{¯ÓàUV¼r}íÓL sÄ(1T˜p°o¼{%XNGg2tçYÁk(«œÈF› ¸r4ͦ4!½uª³—‹Ë‹äý$ÃádùÞÏŸN âI³Üçß¼+¿Ó©ÇG»ùJ5A˜d;X6áwá0sX]¨##9Y)·rYI}òD^—ýú"}æûf¡A" Ì3<´I­F¡Þj°'eè\ßí‰jÜL`¡Sé1Uïšk`~l:ØIª°,×Ê“ÍÓg/góiáäøV¾Œ«{*›Tß$ ¸Û¡G¸KŸsÆ=d€1{š•5*»±¬!?þó^È$Ëô³-#ž©s¬eÌ7Êož¼Ý$Ü»s§àrPë\¯©Q(û7¿M…¿¥N¨¸F›£m5xð£]Ø•ì'2c…!Áä1³jëh2¿¤ß’?y¸À‡þòÉãÞìÁ‡—hÇ6«gÏg#›†:ÕÙæÎ•çÃYµ:-ÕYuøìðªQeýÆÑ~+n4ÊñÁA»rtÔvƒ©Üáøï¬RÄVáÄR6n€s“1€¬1Êþ¥aŽú…1&bÁpu±þðÁÃÉ‹ÓÁâ“GýÆ»36=R¾õEz¦ú—Ñ+x¯   à½×>óð½›ð0p#|äý.¯þÙŸ±ÿF77åâsÓ'täƒ:¶În<Îò©t®ž,1K‰Ø/¬ì)öŽ«ŒRÓ×BD¢ãïÆÁ¹Î³çpùñQãåâÅó#ãÉâübÆÈ½Ä»Ö‚Nèxø ã%,¬Ý4d‰ Vb³a¶¦Y2”c31 æŠ}ܬõó«Æõ+1c7¿s©8Ò•®„á!'ÊÀƒXIÄ|ä4´a{J‰71*5°LŠùÇ%SõR³Ý\7k–DçZ€@¼äj¾n»õ¬%°Á/„IJç·ÒƈóµM)+„®¸ÓîG‘ì¹[šx”P¥e0¥0›%!ÜpÓAÍž½“iK¯Gû\gÂeN½×©¦…†9ZçoÓû=¸Ê²¶îUéÆuNàd†ªG)ãÅzîtk{ŸeFý е§¿ô×»)0ê›ÀÈ §ƒN9f 匠éS Îc‰¯ÿ1ÇpÔOžŸž¯Ü²ùÑ£Þìì|´8}1ž^^ͧl¢ÃR‹``VÏð) go0¤e­1Ë5Ù*8.2 8ZhÃLI–cÚÓ¯‚l/ò“1›‘£ºÊmÖ%\µ¶ƒ7ËTHÕèU!Äöf~ÂUª]'LCô£«‹ar~9]àåo>`‰ƒkû(I==¼Îl+dø¶Û‡×jŠÜœ-ÃMø‚¸¾ Ûë;wÍÚºøÝJ¥¸‡c¿?dο{t°ÓD ±d9lʳ5üq¤lHd‡‚uhíÛg.‚—NI ÜèD5f!Fg'­÷>|7¦ãä‡?ü`â<ÛÙÙdx~1‡«Å³gó1~³ÂÁ}FÈW•:êCü1¬ìd¨ûfZ&åïÜîuKÍ[GÝÊzU(bPWØé4¢:KF¦ ¨S—Ä%ç²Ãˆ_¸„R¦ÃWa ?~.”ÇQ–åÒ*Ø1[°ž¯4(Sœ?¾uȆ3¹ü°Ïž'ígw µËËņLÄ‘¿Äâ9Ç3Ž3´ð9—]%L ”<˜à‹?×,ÅÏóÁêÑá^¡Vk0WMR…adN3Sã{ÿÊ4SaL1î™9Û@¯aümIÈ·ÌÕS‚Í(¿¬ú“¼`è!O3å>¼ÏPÌkþÃÙÑÓôCY#÷±]o¦Ñtù{Iòó÷™ÿ8ï¯|t>ÿéOOÙúvþ჉›î ¸©QÈçþÁ%ò$î#oU*·O*5<ß}ç;m§¾Å4Gn3þd:–SGø´Œ…`uØdÅ„P]þlo„YƒCqÂLòðpûKZËØ¬3ÕM=Ö«Ï qùY©Pb‡£Ü†¿b>"B Ä[â®&Çús*Gm€tȺ3Ãæí“0U›Ì—“«¾Óµvwݞ̦uÊœ?Ü;TŠ¢Ýš#­3à fªJk‘:Ú –)¤” ¯Sa -s:˜qa~”ØŸ^ò.?CÝq«}wŽ÷ªr°Ûü/ö:í{obéSgýê&Çib™O£Â‚¤e(ãÀǾ“2TÊÁµñ¦ÑM‡ªjÞmW{ªmé N£ÇÖÂüôã¿âJwùàÃNÌ­oð°» #~p°EVj[¼¶Ÿ³ 3ɳz0#”Ì{½ Þþ¢ðÈàmžUó+°p"Œürö™÷úÌtÛÆÉÕMøB¸¾ú~ãËRW†.Åj®“?À‡û^==pzÓbh Ç¢G1¡%ó“1 :Ä6¢»}è)?G͈™W ;çX¶OÙPãòª·BÏ[ÍÁââr°d3Å`°\°Ôj!AتÛ$f«Ú-|Ë8¬ŸµÜ1ÀÝ!ÎýÁP7…jyšëõ‡+Õz¨ð`¤ 0%PTxø^Â(¤}˜aH.¶?áI(ÜËX™šêrVDæÙæ¶P©Ë•Z¡ú` ‘rG°Ì LxU;"¨IÐŒ“±(#•U\ ñ@õ™ËõÓÙ%Ä‘9NÖvϰRs.™Ñ±L0Ch¸Èn^Á3 Áº¥ááÞbñú ë¢-sÉFhžÓºãÿE´œ+Ôcª Ïð'>Ý”†½u7¨s7/Îz«ÓÓÁòü|0ïõgó :Є,R‚ÎV0y6I,®ò<Øm­æØ›¢Ãý‚Þ:‡Ñ©ð]ëʶâW~·Êk}Ù7Ã?Æ‹cÂ=Ec@p¥—À¸ˆhÊœÏ|¦æxØ\lcbQ"ïµçeÃqCTžMÖÕÁh9ŠãE<M– ñ|»F` 8̾½-‘x —[xL­€¢K ù~>ðð .R¬Ø”´‹Y!Ûâs½L+Íô¿=äpöSé÷Ñ’×*ì’Ô«µ=vïkÕèÌÒå‘XçS`„ýTK³·Íx„]ŠxÑöâ(‡Ì^S‹¡•à"F‰=Üè"ì¯õ/Ùž™~?§Ï¯õ³ã,ƒ}ÜŠÊFÎ2Q¯e¤â<(Âè+E¦•¶uÅbL†ç·À6¸°˜’*Ó„OŸ—± bûªÖU‰}ç ‘Ð̰)Ò¿m,´3„ª•Þ ¡K£Ñdƒ`²êõ&ЦÚ9f™7 )ÂSÆ®ª?;l^Û§=„Õ{Ó[–›ðš0p#¼&DþR6öUUU6½»µ_®ÿQ£Vß½}òÎ]¬¤±ªÙ)%h³íÔö†W×­ZZ¸Ñá"tûÐì锡·¦N;衺‡ÅX Ëþèɳ‡ëá`¼þÁ~†[mæ‰ß»ôúìµ;Ù,õËøk ̸ì`;•qaï Â-qÖú¾ˆ¤>Y,½É¤ßHòï'Ýn½Â`ëèh·xtp+wûÖm¹K˜ë ”ÄQÿ–KÃ0Ë&± LPøÉt[°ôš[Ën`j´ÞÅ ;ÄÅg§ƒöí“jÂÈ·ðäѼø¢äPS¦ïˆAâàü efË¢0æ³EìŽtbVm6/˜öÀj6k¾qg¯»hÇ{»Ç…°\Ñ­{”‚Q/¤õ ó\~-‡#uŽ`…Orhvð·®Ã•0Ú'5¬?ŒâœÞ ‰¼H5ïj«åqÎ[6/.Ö­v»‡£©ŸÚ­:s¹MV5rwn32¯ap©ÖBÆhyÓ2s‚wÚD,rx¼=‡:òÁõEÚHL¤#!ã‚4,kcWÄ܈ŽÑ2jgSE´2¼1Ï2?&r^×8§x°HÛ¢Š’Á`õ8—›ž<9Û],gÅN«S¾srˆd¡§;…P¾o.)Så:ÜÁ¿udp¶†ÿ`8ëy…±„I9³¢AÙlþ-§Étq¹LN'£é¿t‰¾±Äõo øø§ß4ÿ`g'îü·0Æ7ïÝ»wë.[?boÖ„4 âtsG[R2ªá¦W|†’u§mÆÞG6§nlsö mHÊú•@ËvqyžG?ù釋ŸðÑüür4ûèAÿj4^bY¿™0ºç2{û¸}Ûþa9T¥[`ÏÆ‹!¿hýÈlÔj¼[œO“"ü›)‚$î÷’fa³×;i#ôàÁ¸Q«ÅÅ;'êÉI»Òj´ oß¿CÕèäø9%Ž=»Â©Ï zððñð/ÿêáèìl:;}1"°â1Q­/íñ›Ùµ£|ã>Ùžs¶Ÿg9¬º›ð1`§» _pöc‡ªãÚ´]D;KÇí¶êlÇ.ðŽ<1‰§5óÏÚµL'tGÎ^fÍݘ‰ 瑽w”`”ˈ..ûËaòøÉåŒyÓå‹Sìn‰NÍÜü.ð ²±ÃÛù³%óÌT‚Æù)‰p:4… <@]¦3[×ê›^¼’ççµ|‘ý×Ù¿N˜˜îw…?sƒ^ñh “ëP.HŒÑYðÚ¥±é•…vþP¯oºÏE+‚ª¾‚…{Ìê¤~Ù¢2‡DM•²Ä,ƒSâl$&â>Œf É\f——ãN>?‡VóÃÑ€]á QwGÁDýV¼…H@Áp-ÀI³jR˜QÒ8¯Oèg]ÕmýðUÃÒ>¾JŒì;Ý–ò¢y…%€<'u`¶¶Æ÷l?{•h,õñ'gË‹ËÑ⣇W“Ós§i4žrªTȱüÖ™3 õ$âIKïÂr9KZ­‹ùd:[Ÿ_\Ô—«EþøàeÌI#ŒÐB“°t/ƒwáàGž â5J¡ÌFÑézó´]¦y(þx”àdLçhûÊE2”¬>¬Ž•îaÛ´ÆiÓa¹Ú¬Ww«Ü†ÂWþ¢“Ñ$žbÜÃKxx´,ÖIÚèÌNÀ}ði8¨Û¥u)ƒõw4[·ž¯çó øÖN†Táá¯Ï“'~˜OŽh {ZwPÇÜa9Â[?c£±Y9’ß~o¡ Aµâ¥Á¶5;0òá p €0Úy¢çÃñt’P·Ø¶\¬ž¿¸X^^ÍýÞb:™aß3 óý¶û»ý³€qâØ{û‰ç¬.ü Ö—uRÿáðZÍ ‚@~¾˜­¨Þüj¹`äŸ+.üR ™"˜ÄÝýrƒý¦7pÃQÒC:=¿.ž¿èO¯°GÐi«•°ÏzHƒ;˜qJâÒ!—ÚIŠŒÇ¨,ÌÍ–áû“‹óuŒj´¯öI·½WšNG,DåËáÇ媞 ÃÔ¬0–Ñî+㔕öºG[`‚ÄMCFòf5C-ªÂ¬8ø0ìÏ/5wÀhb°BНd£E‰F6ÂyƵ Ç2yvn|$ýþps5­ò—½É:_(%Ç·ÜDžI™· {œô†S ›•b¹\íŒÿH㌅9x˜£~BR ¶¯HðÃ9h¸äašµÉ#Ó‹7¯'Ósü¢Ïp’òdùüÙ‹Å ¦o> ¯úõþ§Ma¡€åñÈ¿ÄÜzôÞ¬1ä ÖöXz®ª,÷bUD®üøé“âh\ïß;D÷”/¸?Z (¨†ôį¸N™¿e1…³Ú™PG<ðÛŽ !>dés¤´J’ëìÄÑÃ1ö±Âñ]TDxÑoϯ 6ŸfÄÞ¶8Ý1Ì¢»àhÐ_\ºÆÀ5í§çg5·UÆæÀ¦"²~ ®ûÕÏP¤4¤ òŒ?XaçN£ùNègxuZ±ãv—H]‰sÔA¾àñ«Ùn3 'K^ëõªíããò;0þÃn÷wÔµf£¾ÃTS ¾©“'`ô[,…Å”ŽvÃí'dº…1kWAðÃhŒ@fŸf–ô¢¥˜G?~²úÙÏ?f9ÝÅøü|>é 34í(ëó·?Èø³~ᵂ°mÅ6cÛñ^ üöwÓ)Ø—ä Æ)l§{Þ4Åý9 ½þf­Ÿ8fGV3^41&\”°I~4šb«Yˆ>üø1DîMýÕlÂÔ•E"/¿%Ó÷[ #Ö½sýœÑ'áËÚ7—7áucàFxÝ%¿ýý(_ÇÅ/üëëõFé­îNç>ú²*ÆY•à^wµÎàÇüèdÔ¤6éãT%Má’§%±*ЫÙeôâìyt~q•<|ðt1Ζg§‹)³Á4 c©”‘u4;[Öéí`v´_&Óe_¢]GƒPÕ_|ýAÒ:¹}ÑfŸúÂÁþ^n<”êÕvÄšA ¶–ͪU·Ä+ÐÝÀ\õÜf¿—Q¦ä6cB™ùa$®ÊS•hA iŒ"묖â®+â5†ï˜:¨ú…U•¿å“xd£ïeü9‰—i–ƒQr9[­+;ÝE|~9Xñ ìËÖhUUÿËŒ·8Þ‚`Ü2f¨õ¥`£?ö0g ãWó¡3$ëK5m0²ãƒEV“¦ÏÞ åæõ˜®ÕwùgÂ÷œiœ»¢}´xï½O&§¨Jú³QƒîŹ\ðoY,W&XVïÏ·qB‡8»ÔkXcM`šóêûÐè´*•oón¹ÝdVs —p9­áT@ eÊôSn”Æð€ t)Bl«éH™h¢œ*qg7ƒ2XàoqWÅ ò^CÌ\ÓU{eàrÅØ¯ ¾i°-—åÓh0ÐCxÛ\œOΙzÉ]\Už>ÛÛÙÙ‹îÜFŒïú³¾¬kq‹æy€?:< å -*lšÖÉ ŸÉ ðæ¸bV ó‰`¤–1,žj hÍòh˜Šß*ä*·v»La5Y:1[Vå,çýð½j a90¸§KvÁkX@&aI*gq¶Tú°Œ¦E“ƒÚOzƒËä§G Œ'5ø³­ˆG™§£}™«8uºÌgö}Û‘m'ëë¢Í¾â;2{i€Â³A¯eÔh—Òû³3\ˆÒφãÉêÙ ´ƒµQ ch~â£gÏ4ÿÈ=Ç~çCÉãG£Éåë I \l ¾ožÖµtIXŸrSÖ®…[üß„/ 7ÀëElîÞ½¨Ì–µµÝ·Êm\¤ï5åv7›ªÆ¹•J|8K}2Ê—‚¡zÖRBÌ<…(š£ÔôQ؈ƒ9ÌÉt´éõ/7}Lü1ÖÇ:€%vùl+Ï+v0;[Æè½÷Ú³ÂÑV¦´#ú š‡Ò §œ…Ķ‚d6­X¿»D±ˆGÃq­X¨Á°å(¤ð‡2ø‚„Ë®ÃÕ§ýð4M–žý¢Á8³âähŸ â$|Þû8;¸ HÜ –Ó qî|Êfì2>C5üsF—KÚ²ØÖ0Êø¶zBB&ÖW ÐF‘6- pmºôc7¾ëox%}-¼§·€%û kÐÖcéEŸe\—½éëm£.”)+°jZ¦¬þ¼–pz¶>}îaÄRppõ>†XoXn5+±B-Âf¾À²®Ä0Nì1@ =ûr(Çö™‘Á²žs¨ÓçsŽ,¤­Ø_=TÒPˆ°‹ Í ¬/VJ+4_óÈêÏäf—ò2A&`Û4Ý”oâK?Q†ê ·,+[W+Sdç%¨Lq™~™Ôï@b®B$2„9ƒ=ëwœÓrðM†-ÌVkZÚJP×osÉðkr_Lõá,§Ôm·‹Ýf³Ñf‡¿&ÓV1»z há&›ú ýÕR‚¦É¶àÚ—e»Mò¥•Â"¶Kµkì|¹î÷&Ép0[‡kÚñ[ÀDmŸf7¯¶q˜¶¬Íh8kÛ±ß/Žý²×ÖG&x6;oÙ·-'œ½Öw?}(ɳÅ5>;Ö æp&6a(]]ÎÃdÿdŒ9*m™´öEaò[nýŽÏŒó¹ß Í‘óMø1p#¼^ä:h5`w¿ün«Qúã[·:;ï|õÍr©X¡K™¯§Õ3RT½ºÝöû&Ð Sõ,¼æP%+K‰Aê0h±Ð;V,ÿy¸üáO~Èœÿlöÿòì\ëÚS¦~ù†@Jüv¦ Nåls4`'ˌ攴½¶#šNBÐæ8"ð|ÌqÀ¡À€Zy=}út¸3/æG»g›ƒ..D¢r¡Îº`_Îæ9YëD&¥˜š¥]š4Û#Ï|Ã@é,+?2F®¹Ñ¸˜zÌ|l‹reDʶë‘0.C9dŒóPˆÙåØ`ûVÁNýIôôéÓóõrº¼ê÷b3¬g.­Jph•fµ<§sõpa p˜Ð'Öœ°‚åöBÇ-<ßv ºo£Qx°lj ‚ñšûÈø‡§Nã$?üñ{£g/^ààgÐûàçƒv «íŽhÖ‹„Û:³\ñöÚgÙhNA@æé”Hb[íõר¬kŸ|4Ùiµ6õË‹E·Q]”wp©„Ÿ‡À'WÁIp :(#Ï-+ÖlÄZP=n-j€f¸\MbŒôŠÃ@9YiQÜÝi'Ãu²Û­´1ªÇzÁ|þZÌ©±mIôe2~&#ö¶Wƒª`Û›ÓQNŒ/.V5F¹ãÏ.kÚâ„ÝY-0ˆsæƒý p»l]#» È™ë–Ñ«¹1¤£l…pÒr(\²ù… £ û'hºâž ú¼_-¨¤áÞ-v¸Ú†Û·«¸ÑÏ—5ÿ‡oÜ9ú*ËKw÷÷«»;ûLëà™j2'O%r§¶h/ŒþÝ™Ñ[`Q5³̸w£jmèh¥R—š.™÷'|üxþèñ³ÅƒW½Ÿ½7º`ªo„}Û>/Îl+¶ ¯íï¶ÛÐcŸ=á0}&ø[±YŸ²ýœýF¤H v8ŒSàÙ8ÏÖM #ã+Sj—Ѻøìù"<+üèÂ|ò¡­pAñ@?HaÊ4WÜÛn…O8=¬wa3>­0.n—‡+ò&¼& 0÷Ÿ+6°ƒi–•:{ÀãO«X-±K]±P 3°‰ß ?¡ïb È¢Uü°$“ë) â\Î6ÃÑl=±âv¾ÖÚ_m¢4ÎÎ#ƒhÙéíT1;–÷‰‚qÞKØLëWŒ“P „!K#áVňeð†U‡ë9ƇJÁF´”’ÀR‰¹@ÎøñL°¢'&üñ,0~ÎfîG|å—ƒ„Ü?J89L–¾úi¯™Yfå7å³ 3rþ #&–H±>‰a°³¥mPá3Ç>AJBF}ÌÀ CyÁ¡`– )ÛgYÓ,³Vý¦ÍFÔ^;úKËã#@3ÑM+^ìÓ~}Nq ú{¦zdòDÁØþp¢~2áÒhCxž^ò›Âë٠ΔR¾Kã³§Yýh¥¯8‹™…¼íår@Û–0zöÈPÍåõç-›åÍGXŽ; \/Y~FÓc¹$-p8D)¶r„£ÿôÿººÂ=qa"?Ïòå2”(ߪS@IDATãùzƒðe0fmÛg7ᯠ7ÀëA´ÿÙQýä¤ù5TŸoîïëðpç­NkÇh{ØÄĺóÐciÙ× 2LÉ«sÐvøÀXÌ-KÀu` þéš•>ëŸýìñèÑã«éÙ>~ÆÁèÓþjû6ÛŠøu”-ܞű}ÿ#ÛŠ×V˜Ç/ß1Ø <ÔÔxØ<[gûÛógQg½zø\8L# '£!âÊ#ß0?å°{~Äá»âø×ÁÆ£›ðº1Q¹×ï߯ü`PXY•ÂÒ¿V\.ÔpªÇhŽ«¾c4¤$X‚꽃–ß9HØ &óÙ‚Ýü¦Ž-Øä‡…K³dÍJÀ@¿ÈK^•u8¯íô‘µãÙ ílÆ›öÕà;†g;³i³÷dÀ³õ ƒ#æ™ÎH­ Ko`” ƒgô'q wƽ ™cÚ4ýËg/¯Ä „4æ÷òÉïxe¹ü¼ð<³,R'$Éï}xb]`–Ì0Š$|ŒT|Vê'­6ƒ2Q˜¥ˆ®?ÏEÀ}ˆà²ûP¿zýÂ+ŸO“¾Ì‡T¤·Â’ÁcxÃN‹xô.6ñüØ(•+=–‘‘¨g>˜f¢ptÝÆxY€Â”‹_Ε^d.Cïá–(Ál%aoÍxºXaw‡‘=0í^ÂbÈŽPïÜ{~µßÚn²6µý"1¿ÌËðKêÎwü†mÎ|lƒ¦³^= ~Ã8¿›Õ·Ø6_Wa3/Ó{˜Þg¦ùu°ñè&¼n ܯ£6öêf“ëtšíoâ÷ëXüß?<_=yÚ<}²êÉOÈZÉÞŽéˆßΕͱyv$ tý„ÃΦ¤oÚ¬£sù+!{–|ê!¬ÍЦf·ÂÈ£@€%Ty®ƒ(€È Ü\…£þPf_Î>g™-ûµóJëKR4çٽħ|xOmÓÿ „¿9"{KB%‘±õù|S»º\<*ÅÓÙùåÙ­¸´Œ¡á%\Ë”œ÷–l‰ÿ@„)l& ÆY>Ÿ¶e³†$òéh2ãµð–EÏÅàÏÕnI\ ›4=|ôëýG›ýÏ-½ÉòéÓÑèŠÑ?¿ ÙI`=¬3á¶þ¬/GwÖ­õüÃ:v•W.5.XÐ3èlUÅwª5ô0èÌjB½­Š¥–Èå|Â*Cz©ÉPc ‰'‘õâ_Xñ`½†'>€€EäÅNkô¯†É°?гe颗É5’:R´~[°í šmÕѶkÇÅKÌÖÏKqÒ&»ÀÝ«”Öy2WÒÃKa ÿ¶E§ËÈŠ³š ˘Úa  ¢—Óú„ø˜oEu a>¶!Ia±Yâøî»ñíf³x„¿åwöÿn{·ˆ Øù°ËFÙ«%Qè¾ ùÚÂ!lÁ1”™oûŒn£yŒA-Ž¥”ÚÖ¸}œ0½\¿ÿÁãá‹ÓÞüáG£KæÚñh•.ùäuñãa›ÑîÇó3û«"¯e®Ân¡<~[ÈÒøžtÂàûV¼å—ÞY šjœ¾Ý%@[柒Ü@VCOLI¨±¶ý¬Ïü*P¡G’‡Ì†¥5Œ¦¸¹]áé/5â ;ÕÎ%s°ó¾*eKìÄvRŸý¶Î–ó0oÃ*mr>}“„Ž9ýã`$†[Ú@ôx† 6 %ÊÀß%*ïïF¥~—›²¿Î|UŸÎ&‹É¬ˆkíý{©öv´nu„ÑeøPJÃBºP®´PÌ †Ëe(»òÈB?N¨'¸S£Ò.®†‹««1.šYà•ÎûgõfýXOÖ¥õæ!á”øÄÙrŸÆÁÏgõ:ä³y´ðsf,p¢Æ æÔkNàK2WZ>™¡qá*/ìˆ ïúÌJl~Û›0µSUµíF7rmöIò4 /½I¥ßùÍÁlmwâÁwgd;ÕãõÿÏÞ›=Yvœ‰}wßoÕ­µ74 €Ä ‡C…4¶¥±=–#äpÈŽð#õ¬'=*ôèв13’È¡@h —êÚï¾ú÷ûòdU5غÉ™©¬:÷œ“'×/3¿-3¿œÎÊôürK½ìv ˜ ¢ÍÊùÿ<ç…hÑ' g{¨ŠgÑF«‚([$ú¯íšK—+é»GU¤²óèGµ:¾zYCûØÊÞÁ¼7æ~›U™<:k¿ˆ¤ìÑoÌ—T Q4DqÓ3ƒå>zOÈDQå¾ÿõÙÅxqz6a«ï’]›<†-Oî+¹ŸxÏý$3,7˜ÁÛ8ûRîOæ¥ó=CGÀ«YøÛGm+Ë”Ãðx匛ËkX/ëbÚ9oÝï · À÷iÌ€¶6›÷îÝk?ØÝ¼×m·ïõ:ý­Nk>BÚ@U©sNòë\ O†Ì*.K.P™Šƒp" W(/±£y†•’éŠ}òi !áÌ@­3èî ioÆA:—¤ÃQŸµ!»/Y«¿úgVÝoµ°æµìÝ¡(íæ:ªÄÐ]Ã¥7$£ô -;yÌj}:Zu¹wNO§q°_ÛÆÊiµŽÕ·lF©F'C ÂuŠX­R˜¿å.¡Mîu8¢øˆZD˜.¥£wtVLJL݇e¹Õùl²nžŸ¯–­Ö²4=qnž€ª”tô´xfu¼¢RÔHU¯Õ*¡±ž¾·xΚ炙r€øŸqNû‹ÙÙéh‰µÆ!eÐfCF‚–Qä-âΚ—g<+Õ«P¢3Œ—uúj‡²®"XuJÛo¶û•u¿Ïú–nUkÔ É7h¦å,40¡©±ÐÔ1ÏGGƒ‘Hê‰Aà•ø³1‘sÜÂÊw‡5æe$X ¶|y6[Ÿ-&ç—œè3ZNX¯Wt°HåMr»‘jiH۴„é.yŒUü8¦(ƒùÇ?¢]RÓÄÜ™¥³éÑÐÝ-£MWìÐ#^49?ÑößP:·ý©úßÛ®Þk´ªŸ´:Øóßì¶{5w¸ÕÒÕýN+ÝïVàêâA"o¿)ŠMŸ‘³¶MÒJ•GûŸ?[?}q´xñb4Añ‡EHÔ€‰±% ö/ûˆÒ´ÏÎû+UÛ‡ì[¶Ø÷å2#`>ö3«eYdÌK?±‡þ_u¶§ñ o¿Îe×ïû,#Éݺ7À-ð&Pú–0ýR¯µê–Þk5jïou;{ýî}Îot[Û¡æ»Ä\f¨ù¢‹¶$Åëñ!òIÝdʇG`%ñrBÃÐ&ˆºþáûïÌ_#¹ ÀM³«¾g[ýÊD2ã|Ž!߯{{•ËÇÛý~½Òo/ö89´¿–þÙçÒʾúX±K~ŽMâÕY@¾X$ÊÓnUK½¶†KVõ~_ɧ‚ÓêN«]eÑ3K°B-,³$¼’ºÙ Š"6ës½Ê>*(ÞÎÕ6ëx±î)O %ŒK©(ÅIßê7žŒ€os4YŸ&«ÖèC;­åšóÒ) éSž jÀ;Tá¶K‘mð! §¼õ–à‡„¯E7Rð$f'5hŠžpäÏ> ¶r]¬¿àpö“Ó±§3^rh‹gºˆ-gfdDàÞEæªJ Áçp<þŽó›—YŸnoWʃ~mÕ¦Ý82"˜:ÕäyÁ O ˜—XNÐj犛aè º¼-Uâæwë-l gð>f…È1§Ñ½<™OOÏ\ظž²ˆ/u°HåŒ#QÑ ¦ÙJ¤…‰^•N ˆØNkî¶jl‚Ú‘p±h‘»›ì†ÚÑþ˜¢\}¶ç'êC¾Æ¹5LßešëO9 ïþÞî.ªÿvUës€áɘ±P&XØX¹z® ôx¸K"Æe·ßDieJø¦‰`ûÕd2Z?ñ”c OO¿ØôG_•X 5P™€Ü_TË˨^÷.ìì[ß§³éÌW—Ë¡&@?{Ê71Æ·öeËç³×­û@à–øî@¯^¶W­A£¾S­nv*õ:낚ì[Oç~‹JôLx34·™ˆ8âÅ ñ=al‹´2}ò5¹À†•È0‘Êi\ÛÛÒÝ;åörYé!Áqd^uB_ôõ vÆçý.åhTf‡‡ÍÁÁA÷.‡ëUzÍU{9ßtO.ʬëÝr•-KZÙÓ…XÇ= à\¨8&­ïtHÙ«¬ G¶©²i›Uâm,qH¯ÜÄÜ›u äIÅuqb:eNALõ¿‘Eàý¦ç?¹D€c=˜>}»úž­S0ÿ‡¼*‹žIšÒÚ&‘¿e(®"‹ôÔø› (ñ¢¼Šb[~3ÉN"mOæÁ! ±íosq9ÈËÂňrF‰ŠEÖ>{Ï’¾Œ‹Ï"K‘çÍ,x}­ÃO‰£èkL'×{±@ SrÎu‡z™([gÑs»©íVHÏàªrx\ù¥Ç¨›A… Á ÁªLÂŒ.Ú**G#"+‚¿­3ºu^ö9Ú­×’,ÉåºÇ˜ISfÙF4ÜB.›eM嵟ò‘w‰m®ƒá#^7WUj&г£n ¶ß±ø¯ƒ«w[mfý1}ØÂ§L~ÖŠD Yä‘ï Ãß¡–rIðw´Áô’©´d$˜ÚLÇîdU«7Ú=ŒþaÈ}äfÑß0;‚‡ÐYäLÀí«‚Ì+UއÎòäð–ÏçßGoáöñ&n€›ÐxûgÅ»^u^>ìT~Úè”ßï¶¶ýî.Çf(m1T3" çn9Ç^ÁœWþêçÈ1žM§ÄH‚Öª!F¿÷Þ' ”7}¼l±š|€™œu«ÞxßäÝ2ç¿r|WµÌѽåumÒ­FeÝÀø û“ÀÑÕú‡•Æ>rF»Vß*7Û¤MLvöå¼¢œDëºô«ñÇëzµd¿tôÊUG¿ìQ¦J„Q>ä-T åJ3™<5|h/I¢8£Ý”uVó Ž)µ¢qPlõ½9nŠò6¿"HR e l'ðØ¨°ˆ¼’_2ÞN÷:{„‹rX/k¯Å¹:v܃€*éãk»ŠÄó¹à¡H#A‹8<45úB:§£é†ÓÛ6_|q:ÿÏ{¹MsÏjwš\ä©´&2WÒWm«ôSšÓßï"Øou˜¢®ïî–÷Ë{ئû°×möúö`ÀVG>¹|)!æ™Ñ*Y_úRh¬,·õ6 í®¬*<üXøU‹y"| ´ª´•\™‚øŸ¼\–8¢FKý0]±ò=’|ƒ3ÏñFdݨÖÖ£r­.9œv½Ì©š¼°ÑÎæ•ë”ïxýŽÄ~ªHkÕË—¬m™4k•Ù ñ­8k+–1׎mGÍ÷3ãzÍ87ÛPkŠ– ’‰:ò(C͉òûÅ~?þW¥Âÿ¦#ÿr+Çôlu*ÛÛ»lþï7¡ýJ÷,@˰&O(ÙMGˆù£pïÝi ?9n£:ÃÚÿÕ¢HãOÎ^Bø'¥ÏŸ~1ùåo>½˜Ž†ãåéß~ ´¯¤m¿ž_piLGï2f<þ^U»u pË|‡Æb —Á=uô‹E¹J™Iõ¸€}×,‰Rå€<œmç=‹/Å-ñ”Ϥ bð "’?šÿ¬1‰;jE±5*[^pÎCJ@ÓôC¡²á=TNd3߆EmšÃCõ‰ï¦{ªãî_ôKŒïQ”ÈÚr,Ê(¡€ôzO„”u4_ ¨C!Ì#݈Ïp!ÉE÷òSäŸßåÇøJü_½,JªDÎ:ùÊOd÷Tþð¿‘³u6LÔŸ”PJ+P‘†m¹¤A4æ2ÃÚˆœY”+)N*pSò÷9KÿJtJ|‰Rðð&®Ù„׫mXž¹î4ëMVyh’Ïþ!’8YÖÎ+ÇÝz‡‹{t­h‚W]jIÃ;!"áÒ^=æjþÁþ0:õðð Ä»yYß½ç‹Çou¶›þ‰K· Ýë*˜ŠL>q±‚eOíôú®“I‘_J_ÒF‹VÂÂ7еz +}˜k³ÿ @o>Ç+Å‹{ÀÔïÙÑñ³OÓXTDh¦xEÁÚÌï|3›j·C6Z‚W†¥ý"÷Õýö™¬¸Q)|oÝ-¾· À׿[¼cÄsGcQ-m_Œ7ý{بnZ˜ÿÛBJØÓg/4ÜÆB 7B’|yR”à&M dÌØId0GªŒ±n„@ Eœg‰ë<ÙF”¦¹Ò²Š~®$îø†Ê]•s¢™ g·ÒÞ&ÄS-Ò‰ü ì»ØHùzO¡ŒÌeÉëöSèÉé ñtˆ‘Å‚”Ç´õ»%Êt=¬Egüì  -‡‹åzR𭦨ê“çÁ®9Pž•€@ž9þ[Ü#w@‰e¼ò Ü=Çb-²šdQ©]8¡±@ŠÈgQÉ7Ê~“9ðÙrÊlYÉ À‰GÛΧZ¨„iO $§ãÍÑÑåüWŸçã““ù%fÝ=WA NÄí¿·ùåUÿjDì"õ7u¡zçNwko·ùÓAÿðýî`ž¶Ýg&*8÷€NhÙ”„Ch݉E;ׂ.ûˆŸZ#îy£Õô W¼È%_…Ù£—'+XÚ|þôlòäùøòìl†…ƒhm[\éU†s×ÖQ)V©Õú]%Íó»Pñ+ÉÝÞêÂSÇghðÇ-~N{PD @DºÁðd¿ËmåðŠv ¾‚65PÀäÕ¢®úèQç}ÿÙ~p§ÿàჽÁÎö›`ÍÞ± ̬ Õ%~bR¿Nº´k!åÑð‹8|¶=Ä'ç'›³óSŽþ½œsìîNXZÕûöá(ì„eÖ_ûø;Á’x·î!n€ïÐèçŒù^:‰¤†"ÇL+†ë½Ö±H!KÀ +ð Á952dEH†SE¨ê^rDÿL°¯‹j$ãÞÆŠÄ ¤eZ$­do:æ’r"½BºÎÈO)$!>Ã$¼‘ßÓK¢(… ÄvÆp¦ëO¾Kœ3ÒS`è@NÿÆ Ž~ÁED?‰0yÑ;Â⃈,ÑgÑ3‹¼T¥`À¼Š8ÿí"ÒXKünrÑ‘x"zQ]¿úQâN¬¨arö †~ã)ü­oÑV‘(ßíQ°.dœrŠ«ÿ‡˜ýkº9í‹©gÄî]$ž·vIüõ‹rr%®wN›Õvi¶;¤îr:ŸLVQ‘èWÖ$ªŒwb~ø,%ó,ÿó…7Ñ4Ü®]ö$ ‹Û¬ù‰u8šl8jyé°SÈ},`ND‰“T8×ÓúÉÉ~7¢eê:îE7ã…zX—\‰\‚6—ÝxùÙø)™×TÖ€‰og¡cÝ5Ìþ° ]ûV1´Rz¹Ïe0‹pöÿ,( 3ÿÒ[n¶"ý£-ž°Áð5ÅZuGû‚ðÊ’ÿ;ó6Œbçöç· Àwè}Fp v:µRo«^î÷k±Z „óØ“äáTv KD½.æÙ)‚ÄõHþ}Φ¨u»]Rb¨ˆ) mb;yÎAôg˜,|þn-¥Pü lnñkíí›2¤á¢%œæ˜!µ²øïì|uüòx=fÅfzWjœëéÝÐæ¢+r»º'ß·øM ðk‘ºÄÛ²y¥ãÆ>g)c7³Mš2j"c«³>7’2¹ë’úüªcùL¥ äºÕ*€ö Ìá?äME_I=ƾ“#¦| Þðº(~¾*å¡2bLa EÏÏ/.—“éðr‰2€90¬z#k…d²&%¯¹Éd™ú­»…À·Bà–øV}}Žÿ ­W*Í6›ëZ pkH% î@ˆ ÷«U¿Ž|þƒ`‚}$ ®@Ö]íæµÀ_{ž«$|㯱¼sÅ¿?¾ó$“î>ó”‚„_ ¯ü˜òõ·?áÿ”·>žú7’ÒÓጠç™Õ¦Ê¸T,¾áç];…ðYÊóµÌƒ¸Ø!€¥Cw  X-Ù I^)áw±ùºJ-UU‡W¾_}÷‹jޏ'X¤ D–µé¥Ùd¾czp<æü†ÑjN=$øùʈÜwxfÞ™7ööJ,G¯ jÍõ½f³~À©TÝ­~¯UÃ([SÙB¯ &Ñ^“\bKóûWAë»ÏõÏ0ÊàNGpÎÝíãédsy9]^\L—c ÿzâ"|ÖúƒPYÏ×1)“Èémà¡»^ôžè3IcFŸöÁ X~ûfÔ!ߩѫ¹Û„jBV0±å5Å‘O’i†bÁ~jç¬õ ~ˆ‚Ëo"Š™Í~züŽ»F,|â%uD1¦qxñ_IÏïgÓ–åPš ",R6ª´:•ù:õ¼Ý+ö:ÏES"ÿÑÁ¸"Û:»½#F¾ÚDp1–©•YÄhÚb®(’êö ¥pñðj6(ØT›ê“é«y›åÑцã_ƒ˜ü ˆNé,_Þ….jyíõŒÃÉ»°ˆÇ€HŸ‘ñÑLÍñÉxùôÙÅâÙ³ñäùóÅÞJs.âRšSâWÚ÷Ù» ‘Xʼ©«þøÇ¥-ÒÜjö+?j5+ÿ¼¿Ûºûñ·Øþ×hµÚ¬To ¥Oc*Šš5£ÜgÛ…KÕá‘v’9ã»jm‰“¦-R m}¦bÙ ¿(]²÷ðËg§ãÏ¿8Ÿ=11ã¡ùߟÒP»a3ñ²Ž>¿³S‰Ä†ŠØn*óÈæM¦9$Ñhà€½L@ô­+¾Ñ¬¨M0T4*í;fX§A‚AmIKFUåJ„Wïîû¯³É—þocG21ƒBR~BQ ãƒ{ä\Ñg–&!ÙB y»µôü|±yùb†&…”ižÌþ5Dyñ¤‹½„«Ì•cãÖÝBà­ pMwÞ*Úm`!€Å5,­T9 Ú)@ë\ú ÖëézÇÀú‡¦¸PH–0ŽºH"¥“<®¿å ‘ƒÁÜÇŸb&„äßlü#Bh#@ŠÞCB"Q1F‘[ø¥|RžaxÈïÆÍá̈‚¥2JÌU[’N–œøu¤ž±¦ÿ8 i"C*Ò¡8¦Fù)þ!9ƒ=Ý9Á!ö•± `½hš\Ø"¢ÅþAÒ õ£J[å)7¯]Ô' €ŸòGj"pr½ ó½nêmWÍ-8‰š#•7¿ùü‹ÙééåòÉç£áÓ§óX¯A2™Xåº*¹ZÇ,¹úýÝÚ¯ yöË8U¯Yg,±ó-’»_dJ4mí2a5¬.¿GÕ#•xŽI|ú¤g&¨¹2#›)95_[œ¬¸µU+¡iIŒ€Z¾"íœG0ºDIÞ9ãTè¯öSÖò_Ü)T˜¾Öœ0_„}Ä+/ôÙ>’ý ónp$â­ûÇ [àÝÚßQÌ]ãœÊ Q«lUËõ6*Q,%[z"šW.1§([¬ à{’œÃ+˜‹è"#¾>"­âΜx80MüyÄ ééu¦.4‡Æƒà†‘¿HDÂaEòíÀ›†Òwú–2wûšE€Ò­ ’¹ÖÞ6ª]§æ'ëÍtÆ67,ö¥€2'E¹#Ãþë¬DÇ$1Su§N@°u0®eu—€yHˆÜþÇYò« Ç䱘l­”bä5ááyYY/ŸßÞ¥¢½&ž,| 2á0pT«øê».µáeÜP3sÆ – '؇¯†£áÒs\åû¬ Á½²'…É‹Eæù¹›ó(hŒÒ¬:ÿ÷[­êÇØüw0¸³Õß*uº=æþ95'lñ”ÍA斓ߨšµÓÙι¯úUßÒcòò9#BDEÐpLçÓÒéÉåêåñÅj8¤Æ“t¾ÁzÞ¬«Dßúz™§·uÁ”¥Hö]™÷ý»æ=£þF‡± QË]”?Þ‹Wý¬{\&Çp½ŠDÚ¹~ÓþªCÓWj2u—¾À1™]Šë;—@ÿ—Ú#} æEOᢰ_ 3ûE¾ ;߳߻õ}¸u·¸eÞ­¸§ªy9Yvvºë. øÐµb^¿Òqa>HWD„¤ÌÒzóÊAM¥‹5kÖ¼ÃwÃZ¢®êªe°†ˆC´Ì$!žÏÓ¡8/NŸ£UV:@v#ºáƒp‹ÝEŠ"3ç8ý'msðßÒþ{4îF nH…”QÄ¥vÁˆÄˆ«þÖ$âëZ®õú’‹Õ]Ë9 ¼V«Éx³^,W“™‡¾XgÊËeáÊÔ/Š`V"TòC} Q*—H§@¬³ã‘…„ð€ì'PÎvK=óÙêÓß¼œ=}q>{ñb<ìï¾ÿÞ!¬^Â? [ð|Û§ôuK/Ö@˜ Ï,ý«Eñ9Ãó: ýõÓñË“‹éólœ]I<™°ˆü¼T+çuo…·Ú‘ÌœØB7''P¯š˜Äk´‘?аXñHKãñº4®ÖG/gó§ÏÇÓó‹Õš“ ¡ÈÜ+þ|WZ¾YŒT„×üb’Pn~Cõ°¿Ýød{»õñÝíæ‡Ü#w@5èDT1\NÔ¶uú†§²óÕþ¡siŠ„Q˜h•N—‰›mjR¦‡‰ƒÒb<-=yúYéåñ)SG“³óñâŒYÚJbe=UYç˺f©ÕïÖóM™‚~ÅEÌÔbQ=+Ç•¶ÑÑÇi$ªîŠðòÝ`iMƒcÐ>.ìœ~ƒ1FïBÔ4 ‰|JÇ_Ç Œk\†>yûóWä—sÊÛ²\1!ö=3¾r) Ãp¦WÀ™ òÖD˜åE€NyÙ÷…ë­»…À;Cà–xgЕÊsïz’ $ƲD œwÇsx0 U{Ç«RHÀÁ/FÅ9  ú>l'¢—\«¯$šty3Ïæ#ÎW9?EÍ:Gï@:n¼éBV¾áQú*ͳ]ó ¦?5 –%j |Cfá [”5¾¤5hÖÓÉb æLû%ךmàÿ›ÒFÊ}ÅIhç‘jÄ2„F}S=9]M `•ùb¶¬b¹¥ÆEµºˆº´P±²‚lu|<›^`e2 »Ç"A/!ä%ÉDä‰&q®±t9ÅxH^á]´Oâ犿ŸaÑ';`Ì+`å£S+ »Ó¾jFô‹è¹Üùž‚Ìòµîç?/U?ý´T᤿F¯×ޙͪ}ÖŸ<Øê5ïíïïv¶ûýõÈÞc{u´·ô„'•VÂÓï_u¹J‰Ñ%Œô]˜VçÖ5«;²ðS..ÆKl6-æ“2g¡²nö‚Lð­›Ï+¸¬­ùÚºæ Üu=,²àM„?1Ñ||‰Õ]׸xÂ;û©Ñð  zŒMú¬}y~ôò|ñ«_ŽÏÎÏ–s‰«Û³D,^ï ópÏ.c*¿Ýt…¿qÑåp7ÂEo¯Œ¼ÔœBìÅ«\(ûU*ßoÞ}Îî&"õù‹ÏCï›Ê¥‘ a[LýSäà÷@oàt6Y…|“pÜ”,³4g÷æwI•`§2nýòŠÚ(AòD>WP(ø™Ëõ×N-KÔ¢¡FFÓϳÒÅèùæ|tº™MfœVÇÌ âH3!ôîâ?5ªtÕd†Ä~Ç•'“R“Ó';lé;Øl5Ôoÿo[ýþîO?ùɃíín·½‹1¼bãŠr˜¼„ˆróO¡¢ð2›ISA÷ nï¢>Jÿyñ§*.]Åpv¦' !¿=)={þbý_~ùÙäøøb~òl~1®±qu³r”R=çÀ»g×çÅŽî;;ë¦ Ÿ%·ò­NC!à§ñ@}‡q8¶ £>i Xà‡ádàä–æö1˜äü¾~’ò_-¦'{¶X ¶ŠT⺠až¼¤E•>%ÐëÉòx‡IŠ0Â>¦jÂ×¼ðÓ ¾…31/‘¹ò²÷êwën!ðθeÞt)¢»†ó@u¸re@WPÆøð4,c5Æ3Hƒ{H¾»Î'0Tãá•B_ ÿK —g„/—Ì1ËGÄá8⌯JÞæøVN•økœå±†:UÛ8·åÉX`R*ø7 #ËwÕYÒ`<ÈTaý(}¤š¬w(ÊA}‚ɧóÙË8_}¾™Jå{ø½Y\ ¢5ŒêbÎ'r‰f‹ãÇFµÅøOÓ-ó5k7X›õ¸‰¼}¶ü¹^¹.‘vþAòo|þy©Z¯³ª¯¼Øn6·÷µöv§6`±¶~:Ýv³]ka‰Ê3(,îU¹HD>’ÿ¸rš_w— Y õTö9ï‰Yà(k—Ò>c¶ü ‡—\ÃÕx8[GóÇÖ/P&¹ì>·O®gÖld-@&\_W„·òOcÈ'MUÔWŸë/×Ï©†| ©öz†¶µ eèïivMÜëÜÍ„ó÷ÈW¦‘… æ±(ƒ}çºìKQ¢DÆ×‹{j,nÝ-~XÜ2ß¾WØ ÌQ‡×Ç›-&gÙ Ûyààw¾1¤Q<8Å-Fžìç"ùâhüìÅÉìé³áÙó#Nÿ›_IùÖÃípj1”Œ½Û•~‡ø½î/wYñ÷Q£ÖùdggÿþÃ{üíV«õç?ù Ùf¯¿Ëgþ)³s"O9PP‰å?${ Emyc?EÆ‚]í…sà®Gi²?RÂÈ¡7´UéW¿þmi8•~ñËOç¿þõogGÇ£Ù/ÿîô”}ÿóG³1 ;×£>ö5Yú÷„Cß=ÝP?Ûí;;Šš4g!=“ÐsÝŠWÔÅŸpil%i:jhŠÈ~ŽK1&ݶˮIâ—‘ð7ÕNkÓÄžAV„i”€H¼ô[~lHþhQ`Ða–íGÀ›ryW»b{h¬È] N Z, ‚Ù2šT6-ÛÊz¤ó1®²¾}¸…À÷[àû)E•¾TO&'Æ1ùžÔŽÁHø‘ª²È–Bçp†Äá™ ú]$“ÀX~’`ˆ+$‚gDæ^y.;Uô[JC ûÕÁZ|å¥xÅ÷5´ÈéÙÐtâ&[Ínæ“ÀfŒ·v‡=äx—(™?™· œ~HXØDVŠ ) È=…ðJÿšt³V£0díEŒÌ´dþÑw¿Eêy®ÿ§?-U_.Jíæ²¼]®µv›ÍÆ~»Q?ì4[­fk§ÝjkåbÕ†áD=_N  ¢“Š“ ÷èÜ|ÍÏÞã²kI!JÙOS¿ÎûOØòqy9Äâßhuv~¹ºädÃñ˜©vkÂÇ*ôZë”/¥~ŸóÝïWõäù»9ÆN€=RÉ5IIæ²M››¸øX|å–âûÀ' o½^T(`—šKíW÷ôœ}Â;5œóaz‰½1ÍĤûUJE¼œ\„‹ø±¯É,¤îpòÁC™¾_¿¼,•ÿÃø—壣Yùàà©P)ýò—û«ûoÿcÆsá‡w¾ÿ#ÍWÅ[à;À6S1“ÈD:°¿”ÙÁ|£ŸfA?kE±Ó7P !ÅH¤Ìñ%FÎÙ‚çKe¹|o¯Ñ©—šÕßnç£ájˆÀwŽä¥4é`øC ˆŒì•ʽ|—!ƒ½ÎI7½”ü–9¥&˜ìÏk8÷¸‡Ù€û÷›½{÷Ûìèîìt[àç‹ßþvòדÉròÙgçíóó@«y…´0Ȉ¢Hêwoµ…`YF”€œ…³„^Œ[.•Þ¦ˆìþ€*í¢Ôæ•ZÚvq[#šˆF |â@AøÎêÿËóä‹Íé ¦Áä) cùœï÷r5·p“Hnþê¯:³YkçáÃê.kþôN£¾»}g矶›;‡û{ƒ½½½V³ÛÜݾ‡²‰“'«²ãà)ÖI–YxÈüЕT’?‰F—âîÖ>וDéfª_ü¦Á©ªP3żvÌùS–ú•–ðóä³ß²ódRúþãßÍÝëÿù“‹‹/¾8ÇòïržLÇáFÂß:(éûlŸôrþ_Éߺê/£øu}ƒOoéèAa›_­uö)«\¢’ZŸÌ‚˜zOM)Œœ¢q—ƲòÓÚÅù¥¹›h=êM¶UnÍXjÛì–[˜öZLÇ¥&`¢QÙi·x›¶;-”ü}OÑqéŸ$ÕÕØ2h[ˆ„·í–û—Rþ[ ö3&Œ íAûo ¿×ÁÿÍ¿éïVÍ~x¯Ùþ»¿[?Ÿlø¦öÃ4Œïýf|^¿Å¹¡—¦bAЖ„Ë~^k·Lâ1ÔÒŠaþ•;¤"º È]kІ5˜>`¾|Žz®‹<ãSªkdÉOfœ²ÅÈ & ]¿ÞšïoʵÇìô<ÀììŸ6êÃf«ÉJÿ~—[ig{[bG•‰iÞ.„»Ée˜Þ+. £p+p `Wo·¤ú„‰:Ez4«ö|ÏÎ_bÌh²y~ôruttÁ¹ ³ùË—‹)kPþ’kçR}¼çúx·/xÏÚ!ël¿ˆºrÿNÎrG•Š{¼S92*uîž×p3CýTVÄxŒàAÛÑEõš¶*°È<]­¶ñ ›ÝÎ"d°baJÔ”ñWâWSóÿ†ói†VÁ HÄ¢¹Å01'²ö´1`n\þýcsëu³Á wÐ~ôé×?LÖlÎ᜵A£juvŒªô7sücÕ÷Zß[à;‚ÓU½^%”€_1˜M>#œªâŠcû%CKo׿Y’pgA£ÞEÚÜ”·¶öë‹ecÓlŽ8àÅ©Vvß-‚ Ñ*m½Žðî‡r¡;¯%Ùob¨| ÓÝâŽn#Þ¹•Êf©qç 1`:»5دõ»ýúÖ>zðàñÃ;ï+z-ç‹É|±:ûÅ}xr2>UB<¡$-# ÑÉ‘o„EX-Trcû¢¦Œg3¬B}ì¢=0£KRJlÉ@S¬ yG;r§ËоÌ‹–d$¢h+‚V¥Žm“$¥à)ÉÄ4ûOÚü¨Íéò•Z‰úÁÎàýf³ÿ ÓnîînmáïïííÞi·H;Ý‹þ ̉ 5ÒÁL>òãˆÚ i2p2-ýôr|z:]žr¨áh9¡ßyÒŸ°—° saï¿u•)µMì“Yúw”|oÎZ’rEEƒ¡Õ%¦ªÞÃQQ?‡ñ+Âk÷"$o50g\c½ƒ0qœ9•Ò¬o!½÷õ TÁ´7¶ªK¥6cz ÓS,aøÊ~#<«æ©to‘£¨†H­‘ý'Jb‰u"ÞcZÉ ß0ýÕÒm–ìE <âŠk&¥ˆÿäæ4×bÑ”ËËöªR> ËÝëowï~ðþÁ¿j·;Gïýéƒ:\ØÓ£'§ÇÇ—óOµZü—¿Y,ž¿\¢ö-™J‘©xÇ>gÔå‘Þn¿· À·‚èëа¯""{`\ü¢ö괯 ‰CHŒ |U°Žÿø:$¯€øèÒqäQ¤jo7º˜j7[•FýÂ=P”`#Qñz•ÑÞu‚¿Ÿ§ÌHì|~]9Dƒ »¸`û^VÄóX* Õ.F‚šN¹Ö?¨÷ÚÝÖÞGÞÿàáûα›hdÇý‡v"x/ówp~]¾™Pb»É”÷÷K[ÛÛÕîýƒîö{zï±Åm{çÎÖÝv·½sçp¯¿·³SGX;©Î—Ó:G˜#wÁ ù™¦DŸ™ý«zß(Þ_ã‚1£}ªc@&¶ 3âÖ|¡L›ÐLDĪ ^ß‹l¾R[==h4adz•æ`Pî Î`*fhÚ»»ÍR§S)}ôáî‡Êpœtó!ß;ƒíÁ½n§¿Ç¶¾ÖÖÖv›~•fC‚„Õ$ˆÙc%˜;`Ù(G” €ØO"}Gçé™êG^+Z2ÆW’äeÊ“þèžYÀÐ,ãl]ÆšfY«—‚×~!ƒ¡¥ËÈŠg#ÄÔQƒá·ÚflÞ¸(ƒÂOO{‘ Ø#æÌRÙ.v òŒû—ÿ²TëõJ0îín£Qûyþ;Ívó ƒt¸Çß¿ÓǼ5ú³JKðŒG³úÙÙxs~>îq¦Å.xP\gÇw¸~È>W@?CŸ[÷ƸeÞT¯ ÈœÞ+ˆÿ|y‰ äªhá¹÷|Yå7„œ±¼J»ßâ=$†·ÈÂícŽt¯dd†íH¨§QwCüéáåÛÒæhª’S/wz•n·_c<¬·JË~$˜…Üð.ïÊáé‡w"øŒäåy}ž¹š†ü\úËÿ¥÷³N§ñ`g‹-oÛÛÿ'[Ûv=z¸½µ5hìÔïìßÃðÌóÍúÛ¿eú¨ŒDú>‘‡ aû¯„FéRÆÃw/ƒé# ªMP/W ”B"°ÏR}²x:%¡ÊÖÅ^:çÛuJùº+Þ Œô‚*’}s°UªÿKˆíÏØõx‡é’Ýn4ß¿{ÿÞáÇ»;ÛÕŸýäOXáT-MÆó²Ì¨cþ7Ÿ}±ùâËËÁx<ý€>˜…§˜ê—ý,–‡[÷æYÞºw„@àZã³Pu±Z` ÅiQ,ª¿®+¦ñŸºl~¾‘¯^á òÔ Áá¡9Ra`­ÔYÔ =…°ÚDS«d"7ì%V÷’øyý.¹$'6?Ýkj—>¿BGf¡òOþÉ6ûØ7•ÝN‰ç ×iô{½€A¿7èö{ÛÕF½ÄKÕ7H`ÍåYé-`c~Yr¦ÿºÀ»TêË.áÀµIâb…jq‘o”œÕäÒ|‰D´IÁ'*ÆOÜ}·­Šœ®›óø•Y·UÝÛë°c¿ºétšÕííN­Í¾ú»wv´Ñèuûû XìPa[ZL‚ 0ÇN5‡Eˆ>A•Ç·âfk9¼SŒÐY†¸øâôă§T@¥Q{‡ªî˜ž ŒkN›Åz?Ç_®ONÏ6ÇǧËgJþ—ÓåÉéx†¤ëé~K·1’’¼Yz÷’àçK"¯ŸˆÙçüþûë‡ÖO³xN¯Qj NXñÙD:Vîí鉂IMé8¦¼"ŠíÂÖNàÌ0w÷p„U À˜p†„&/óµ}ÂqOì€o‰°,¶o$N:2uœ8Èbßúm3áè ª‘BÄ›÷Höõçç /•Jÿ¢Ô¸h*¥¹ã{‡-­÷zÝνN«}§×ïíÁé÷÷ØPéDåÎCÓš•.ë£Éz<[XN¸Š+ùŒ÷„Ç­{GÜ2ï8£i§{øg—£ÉÅhx6áúnoÕ¨rÒ‡ðhHÄ-B 5²‘è®"ƒ@Ž~ß•øE~Ë ÑÐã•èD(`„Y—öwYߩ޽ÓL¦Zh™=ÿòËyFPy`x—Fˆ„EÜ¿/GÁßÈ•ÿÝ¿+5ÏÎJõÕªþglMÛ†êÿêÀÿ~g{ÿàñ?ÚëtºÍ{wïUXüV:¿8+ýê7¿*}ùôhý«_=ŸžŸO=€¨6­ë¨£Eï„\xÕe®¾ƒ”Õh±èÊ5ÇÐeÑf‚Φ°J¶QjIèBòÄKyHCH݈G•o…œß)ÿä“k“Ù¤úÉÇã:õ9ž·´Õcq{ö·zûŽîmšn6¯£æÏë T 9WŸuV}Ç,Š+CÙp2 ÏÎg(­ NöµIAÁô„…]U0&ê-³3KG§_ßËõÿ÷7ÿuüåÓãÅóçãá“'ÃK ଎Ž9ì™ä€±ÌšýHéK‚o¿RâòÒÏû“âþî2yîŸ'rÿÁÜA 2nΩǼº9ÚPºpP¤bŠ.[ÞŽ1æ‘4ú7Ïnþf¡mô1+£¶`ˆ®‰MÌðö1Í€A¥l»¤¼½›lüÄÀô µyÓ«(GI£@TÂmŒÍzµ|x°Õ.mö›g«þ‡[,ºdæ²B[èòxÏL‰~)qŸþx\¹ôóR†©¶Xl}/óhk«~o0hÿ¬iÙûðýÒëmíìšûwÐtUK³‘;gfŒ÷O×—Ãõ¯}¼øígCN]T0@Ù¼ö5i–u¿ußn€ïDÖC­Ç‹ú˜Ãq'ì•^q´m d1¶H;敚lçºÎ…Gň ß@-2 ¢üËóž?rw~Ö­v ^*#E6:íê Abï`Ú–^>ç©ðþÇâ*ñ¥êÉI© xZvý=ª¿ßlµuÛ­÷{Ý.köZÝn¯Šô6ÚONÙSZ:9»DBrøÌlÍáC傸g$P|ÓJ2?ÏÔ ÀñŠx”Øm/Á7ž”ð¢•$°WÈ\/¥½âOIÑ–Œ6“J$y»A¨4Ë‹e»<ëw›ƒ õT{>3>ÍR»µK>Hz"þ‹¦]±AÂ`›Ûz…$^åZ#¼S'‰°QDã%~|à¢fñ§•J§›bž™ÇªÌSAòI¾Sm“ªŸ`y¢-¹S<À9X)/r °:Ìõõ8Ü©Ýi`ì©Ü„ˆ6àÙò¸¶Ïûl™¼rò<þQ¹òò‚Sרªê—ï×*õ[Öý­~çÃn·3 vüÝ­AiÀX· p¿S*{Œ6êübÈ5YžŸ³õÃ_€]s7ëÚäªÊÿ sË|‡6{q‚ì°¿ØÞën¿x9Ÿ,–óö£÷ª0òÕÊŠì|^ é ô×b¨VTëóâ¾cût"‰P -¯Q1X.C×-D§Öíµ×ÍÖºM4WźV`ÀM†`«¸‹˜“ÌÀÃÚýë]jnßm.§«­åºý¡úÞùñãÑé´wïì Û{,}«í î`÷SÊHd¬¯|ùìùü?ÿâW‹GÃño;<—sT°ŠjïL`\¹Íi„¬´“zˆ;öý{/r†½_m¶Œm}“Þëë=¸gÚ£gLÛ°¶±ß¹„`Í*ÛÉ;´BN â5é„31©, «EÍÕý1íèi±^ ’W‡kº61š$BºV%ˆ}Gm€.¦2L›ï˜´Ò?i 4ôãQŽX÷[ž_Œ˜û_Ï üJùÖл%”  ï—\vç^3Áw†ýì×\†÷›a ñô½;iŠI‰±Öë—õûmͶœÖyÝL–¤^qi!‚AàS´'m0hpwkÀìB¥4Ø>köúÌ›¯K£òË’“W¶Ç.ÏšMfÄ„ý“k|òI©9«¶þËö~òèÑ?ÛßÝûé`Ðë>~|«ÝnÕz­=”RÃZ׊>;FÃ2\þù‹ÑñÉåòÉ“ñÙ—O—cLŸ— é;ù?&àü1•å–ø­º¾q:®Béler=XÌ2 •& d w´ª‰û§ãs ÃÈ9ÂÃ8蟤BÊ„¤¡FA;â€Z­sŸû„lC/‘‚È×g±$©üñ8P( K­ÏüôÇ¢Naû˜9Á³aµï}æÀQ‡S­ÅjФš˜ =gÆ–á¦gÙ¹H¨Ùw&2žÇP.¶hJ8_™àKíô»PÔŸ«¸eHçW%B·nÚúeÄ|Û5ˆOÄ‘±KEÏZ2nNÇ )ò=i"ŠoFóÑô¼š 5M^ª¤­Ž}&²"Œ[“‹*ÂØ¯BòÂ`Z¬•§<*ýÞœD¶Þ%úö«<ïï{Ö¨ê—y÷»WÎÇ߃³Ýn^‘eQ×ÙËpˈ¥™àg(}à‹{ÜÒ—â4Ò#Õ*+N|\B°`fm”®qS֯ĺéÏ9yBEvü¤&õ))Ö½°Õ—{½Zo2ÁP_ÔáMß^îvÁd<;Öm§H–û‹+³H·ÊQ_w)جš|Ìàþ°Ûë6v÷vЀ±­¹Ò!0‹It<Ät'wRqÔô‚ ƒ«Ãß¾—ûd1þXªù÷¿v [÷Ž€àƒxÁ€ @ÖlÚ é?ÈÉ>ùc\ºçšƒñ/†©t;æ’ý&òvÜÃ@A@ Ÿ%i2©yV Ö‚ûƒnk½Ú­‡ëÝj÷aDNž=[~Î8Rà%¢¸É¼-â‡s•ÿï÷ºãñ¼q>-ïl–›ýn·;8ØÞúYµÚØf>ügõZ½ÿ£Ç?Þîu{,dE#¯Viã£iÛóóÓÍÅð|óüÅÉâÉ—§ã³³Åt2Ù¸ M@©S©'ß3áy+âƒÕ7ãiš•F ¸Ël¥Hêà ›-!ùôè–G‰nú–0°_%êb©¬žO˜P${uÐ-£‹È&˜>³ŽÆ÷2θüÅBÅ"’#1|çŸJ»!ñ¦á§•BÝ‚uëÚ:$.I&‘J‡ƒ‡è–·Ë?þø‚MÝê³g—‹zã‰k3=9Y]’&›O6Jþ"a¥{aîá>®¼–ð«Èí¼~?NŽ ¶w¼ðÈ38Ñ“¡JáD‚: ã€3¯úitË@ÁXÁnqÓÑ´›ñÅú¤¹8?›½Ò;å{näqQ¥„,­åIñ®ûGtl¨Ì:íáÖl¦]ü;`‚ÁÏÌNFÜ?ÔÏîn·C'üÓͪŠ‹ò_rÂáöƒ¿`¼ï>¸w§qïða5Ö¡ âÚ V``ヨ5­? éôⲄùŸ%ûÿ±rsŸ‚/÷1û™}Ðë–ßÕÝ2ïA;¥öAWŒ>¬ˆhT4úptm–’¶QÛÛýËÀ1o䌾J¥ñÝ0^×N%¹)—P¥Á5Àô†XÍ«³ nÍr¡ ümð¼›™*#‰è‡våŸü¤TÿË¿ÜêÕµ6‹õ>ª×›{»ÝîûõVã£N ó¶{ƒ»[Ûlaÿ†¥÷œjÇöZCõÇHÑ¢«œ87íÙóãÙj8‚ø7s‚ÈØX‰þMI@f@ä ß72n”p*%/´™Ü)ÌÈ«OD×ïúgš шFTãã'œßDêaiÏd|/¨tÄ·ŠxGRFH‰â—SHqüd .ÇÉ¡ì3¯¸"ÓËqâ{¤!qáM‘øªðÖIbç–³FioÚ¶ö¬É&‹ûôSžŒÎHÿ“ãÓñDÇÃp¦aì%¼3¶M^É–÷?Œ@H7J^EÝógï2ÑVÜ}ε&Õ^0è7Ò¡I70F3 ·Oóáh¶ÞžÎ ÿôßÈÚ–$›™¿€ŽßÒc„Ÿ·+Žo±Ø×m…Ø’` ‹b«»;ƒÚ|Qit{'½Ù|5‡(¶ãÇ·Ójbdìq^¿çšvò`Ͳ׫V}öÝí¶;?b7ÏÖþþزÜÝß=èiï‚ů­#Â%Lõ¨#Úa¸¸®//G+´ÿËñÄíÕ›Lì3³ÿÕ»ßsÿK ý½ÔþN&· À»µe!ý¼1a}×”ùWLƒ°6:µbþZBͪ¯äY’^O7ÍÆ@2B¶çÊü¢†ß÷WQ¶Œœbë¨æîáýÊŠ¹2s÷àΓý!çv:£}ö ·8NóÑD Jgâ%%µ¾¸XNç‹ýÌ1¯öÉ-§ŽwŸõwÌ;-%,¬û­{Ü2o4Ç®HoŘ]1pçÌ»²mɹèÌd!6Ís†¶ •Ô0؉Ûûˆà;xġϟ.ýÆãUX³ôÀozŽß‚8±m„Ñ,ATÙ.×n–7‹¦e;•Êz=m´\fð¬"t€ü NÓžf£v¹UÛé5öz½ƒF¥ñ Q-ßÅâÝVúßïö¶vûý-ŒûtÊØ¶Çð]ÄêB¿rlû ¸TÍ\¸6™ÎÖ£ñl=/Wó9³LJ;©ˆèØKLâ%ÁÏwým›"5ž^ãH-þ¦,‘vß¾M`„oŒ”Ó!l”•ò'DžZÒ6¶¡ó€«ðe0ß„×ÏJ:nû ­Àk2 /~‚ ©[¨L.,‚¹™×U¯‰ŒSÞ~—’äoÆKoÅß"HüéZÆ&3´µ˜Ug³JYÛìîö{Óé¼Ìô­ét±Wm`ª~Žmi$!S°+–ò÷ãl.×ÝÀ»DÝ¢~V‹+nÅó+¥Ñ/4 †KE M¯¼« R6“v  T€,î~ãÈÓ«étÉö´ù’ñΰ_@ãRHÓ²¯s)O¾†[fÜòÚÜZY;ƒ-èÒV¿W¾¸aB·ük] F2ˆVŽq' €ã\°Øï¿>ó×èÍýB»Ç‘ÊDžµ‡õ»Ìåw8:á!ãèÑö–}¶÷[ìUf]O‡>…1#û¡a®D0ù ¾ 6©ÝdºXhšÎU`ÍÏduy9Ya€j‰P4`órÜgG|æ•ÇýëM€[÷í°ãܺ·‡€rF/³ølx19:99}Âq*Ë/Ÿ÷PÉ×1c_Ùîï—Õê-À¢àØ HD—ôŠ´óï²mG­R‡=&™‡ñèµX„$ âÁÁH»^úàáis4¾¬ž ™+~Ì*ùËÅl|4•¬ùÚ5Y“ärÀx÷ú¾\åÞ½Ã=ì6»›,߃èßÛîöÿ;þÎû÷ï<êw{½ÝÁac÷NÍú¦El Ñ…ÅIK¤R³ ¨è“´ç—Hþ'Ó'_¼œ¿xyÉ)4ËÁŒ”%ï¾»@M)@ÉTÉÀú}+B¨tQ²öØ‘iåV»V “«Ê5ĬÊÖá²t.5ÖGé_„\º²ÑÒ;V!``f¥ÑhXzòÅ«V:ÄŒ1†Jv8`æ€è¨Ý‘Äý¦vÁ¸Æö7mYs!*"%)h …Y}Ƶ&FvÙwûPZŸ`‰q†-]wÀ k‘ŽÝδWL½Xµj¡¬­Êþî]Ö_\¶õÖ!g,º[ûÏGã)Z®j‹5Ç_qðo`ú”À¾äÛ¤ôÃ;%mlQ·Ù:¬}6W5ÖWøy¥¥bÙŠ‚B³ÛºD€Ò=Á†TžÜ3@á¼ Òåby޳¢¾‹/ÏÎËÕñKŒUa5ñ¸ÏÊör§½EX°€Z… Ç)–%H­lë_êšb[&JD™ý[\“öûúç=¦ªÊ?ùäàp¯ÑA€~\.»tާ§k¥c¥b5Y;ö½·Ã¿ø¥ÖÞÞá=àêôzóŸRžÞý÷ºÿuÿ{ùßÇnÇCLù5¿ÿhÀ´vJöØ¡ä4§EiΜ~;™Kâa/ì÷ñ«³aéùѳկ~óÅèül:GË2׬?ÙØ·dêÕpØÇëOo<[wƒ[÷ޏeÞ pA¦‰ÊPõ$ÙÕäâbr‰=ù.‡Ö¬0äòh³!? è@ìl7Z÷Zíö'Húý­þÎö`{»1ìrÊß Ã3`Oë±£ÁPH €°àÛl>eëßÛôã%ÒÀœAX 䢊+ Kû2"¯7F~Øè÷¸Ü#ßýá]Ê™ÅÈÏÜmÁ$4^ûæ'‹lLŠî¡âŸ³~aT::yC#«oú3¦9¶Êåzh>dÔ GQÖ‚è¤tBú'A§Eü–]lTìÕ+K³×Ÿ¯`Rf”Ç’EéŒ(OÔ3ùY¯˜ö Œêp™wbطةQ¹w÷²5 _<í°ÌÛíáÃv»ÖeúbD1pC[Ù"ÚoÄ|ø»¸*3ßÐý ΪðA)ˆŠu‰?s¸ŽOÖZ—ŸãŸhÇŒ:ÆM†;ô 5|ú~³{ÐTÖsIêéååj ¥jÙ«fÚm€ÐØad@n¸üYé_xÄ­xN Aê*ñl ÌH—F[ÝÊÞN·½ÆÌc»6è +˜~\Ÿ ‡¥åé2´\÷c¹(q¤œ³ãõ\°<íÂBoâÞ­T–h{FóÇ0’[à¸?k·ê{,X<àà*Nòë—v±[ á¯PJ0G²O #y¡ × á&ÁÔm&3N·¼(]ކkÔÿsÖ¹Õ—ÁÖæqï=kýë^·€wjÚW#Ý2¯ÂãÞX5½œ°:xÒ^w/.GôÒÜ`þÊMÕe€s¯"\ ‰x”VD YdÔT £¿¢±ä)Åü±ˆ1Nõ³ËËYãèåéºÛWvhïA©EOLð%Û\"Òý#~£<~smˆ%p{pœþIkÚ:v#УšÍ^åáÇÍþÖVy2^¶kÍ“SV¶&ëùjÍñÄëê…À˧4r"ŒïÚþÊϾÓeúdžû,F<Ä0×N¯×úZÇîÃû÷ÂÊýÎýû‡Û&;ûÐ÷s~7cžz²8Âí•òë‚ÛÊRAë?Y³É«¾~¿_®Ÿ=[¿<>]\œ.c·}1~Ç|Öøœ™ïo2Þ vë¾ · À7AçÛ¿JáŒt¶­,ÎjõyûìübŽŠl½Õß…ø§>š$Lx2ˆŒÀofã§H”#AA¸÷G­í`škœÁÓeŽ­uÿAùrë²µÞLüæÍGÐþ§Ïf³j}þr>-cC5Üj-ñw`9 ¼t¢#³ûZ§Í~¤€Îj<Ý®mu? Ô;ëyåŸÕêÕ{õ:ö½{í¶·öغ¼ÝÃOyoçNYK~l,EV–]ûÞIºÒT*Ù™«Oa])q΂úm^¾|¹~ñòdutt1fàèr¸Ì €À±Iü³ä¯Z0Oøý[Ýö` ®@Ñ\TÕ©Õ7 Œ)9]¹(cjQ10꼇¡6JçxÅÉr¾óAú A\çóÚæóÏÙË|z†ˆø|±ºÐ~ï½2€ªüøñGU¦JK@JGýÒ1Ì#-†4½ÌÚg`ŽÈË>d~–Á¼ã&¥Â©ÆÈeðÝS(MË-Ù¢á"¶T¯‚°™VÎÁx •b'€ôV˜¹µ-î’Ʋ\o®»J¸óùù#`·`ádg:^Œ›ËgK(kà›ÍÒÚÛÅÔl/]´rzü~~µ~ãXMNlÔ bŒ+I• Ù|ü‰‡t÷±Y‚ïWB"8ª“ þ¤)àx àG૔탣áÐjëÓãYûéó£ÍVRúðñ’V‡DR,—ÅK÷(Tn»€$l£ªŠÓOü{ȃÇLÚ¾^åÃGšœØXŸÎÎïõËÁ_L0Ç,Ô¬T.ÇË '‘Â×–.a—eˆMÝvðþ6®üèQ©w³ ÎpxÏ'ð$ÎlË!ýOLw´9¹ò^»Ó®=|ð¨Þïõ9š¼}ØŠZ§®lz["­ï1{ÈýU¤ž'\ OÖ_<{²z~4ž¿D±‚ Q‘$òÂÚ±ž™€¬ ðÛÛÖ(·î«¸e¾ ‘wxgЭ§Óòl:ÙL”SÔðÓédÚDÍâbÇ…†V«È€îÒ¤c>Žâ“C$ÈA5­ƒ*$´$ÊCP^ˆdüÖK,À oWîß;@:›Ušœµ=OšãÊ"eŽ2]žt¦ w‚$yAyíötÙí––àûM­Öe@mm-9“{Sív÷VwÚõúÖVw‹?•­F³þ¢ÃѶP}îév¶«h!@Êí €V'Ê-âc§ùóßlhA@¾(%6¬ ‡X…iÚÕdºD 'ÑeiÀ»D^l™Dþö&ÄFt^l°³VYw[§\i±¡MUX¢l3þ¬ºÛø5…¨g1¯h¾hGê‚*½ÖQþTWSV‰-æ8ÃÙ¦Ù;‡\í¶_®ÛÍ&‡±G ¬Íá(•8“@õ)ļf6H·É™pê#)÷Â;nÉ'BæN$fåʪרa}wn:E£V„O‹ÍR?²!Œ ÆOÌ'[•6Ü=º+½a.ûËU{“ÉØ—w&“Eíôt¾GºÛGœ’%P ø»ÅÆó]œš„ÙÆÌ®¨r~M RTÕ›Wn®WâßRŽ´_¬'ˆ2§ŒßWØÃ¨#©ÖS˜žá~›í€3§z³ycáÊAj,ãæpQhôX@ò¤e›XfóÓ ˜ëR´IQ¦(³íH|Ÿ9”+43ûdPmnÖ£þdÒÚg!â·Ê2®‘ÆÏg,>½dÍ3fÑØH_â𬠠&/ÑÔù|åPó×Ù7TooJÍõis—£Ž9‹³ñ^£^ÝiU6ëíGà’Á`«Ýi¶šÍÁÎN…„š}Æä A%§*Í&1>©/Ólh¾YOû—ÂÁl¶ÜpüÔš#¾1r´Ñ¥&2¡Ïãüæ=ãWêqU¡Û‡·‚À-ðVàzm`ö®–$üÇ—£ ªº—È­£f»ÑìXÀìpüëÝ@¶Îo;bžÑîË@ÐyËH”ÃÐÁ’Æé \Œ`³ Ëxž-` $ý|,©c6­F¿ü£Çûœ®·¨ïío?d«ÐæË§OFcí»OÆœ ‡¹âéiãùìì_æ„ÍÕo6õò½)¢ºæ`¼ `Q6Õõºõ>…èÖ6õOÚuÌxv[ý;‡»»L;4÷÷V·Ñeo·½Í!”™mä|÷ôKð!|QV kªeT5~DVÚÅpNÄ/V,ZŒJg_®~ý俾|v>{òÅùøùó¥HLÂrs¡“’¦R¿’ ÿü¦„ðmÁ‰wöP/•FóÁ¦V}PoˆÖv[h4'Ñ)PoqÔ1 §ÉR‘ØÍLòšŒÐXI~™‹…Pk¤'V}öù“‹£ã£éø7¿žqìï)'žVj{wÕï¶Õ?ýñû;N«ò£Çï7zL³Þ¿{·txpmš¤zX#ˆ9Ä„üu¡ZåŽEèxÏ„ÃòDÿ‚ØOY0*ÓýŠB{¬ŸHW‚¦À+ÜœeM¢.ÅÇßKPrF@´‹»Í°Ì)”}Í´þæ³£í'÷Ž>|y|v¶©Ìgç×OŸ.1°>§¨ŸÙöp« ‹eDÞß›kRn”ô· ¤eÍ›C=¬Šûüué—§ ¸%b•>AbJÁµpˆØÚà¤H&ˆ„±S/ì°aÜFóÛï.Y€÷ìò’žÝáæ¿ýæ‹£­ÎÏÎϘæªö;ý005gJ…FKcP˜o¹Èén´3Pzr2fÜÍÏ2© 3(S§³ËƒA…Ó²zŒïÒO÷î<{||rüããã—çÃÑä´R™ü7v'œœŸ–þ_fŸÓo°Ø¸tÑœm Ð ²öÇR c[­Jcw5®Ü_÷jÉôÊš½‚Ÿƒ»û, Ýc_(*þ‡kLmÂ€Ü f5ïv±.±˜ÔÄŠHg]P~µNø¹&õ]™)û¬x•ÿ³ÒÑóÑú—¿8_œžÌ˜ò[p5J¥MŒyËi™ÿ.þóòÝ1/°oݺï[à»ÐeGÅVµ™;ƒfìa…WDP*RI ¾D…»ñ˜½nÞEæW*\Ç­’‚Ì ¤h ¿„ÈxSraþ‘¹¸X,ÎYóœ*–„Ò3óÝhLHŸó½v{ÑhwkõZît¥ûàg¬¢^1¿Ç€sp†Ê»Â¿[®¬˜Ôïí7ÛM¶ñ5{œUßçp{¦ùaÅcù}™M¨Ëj*¨—ebk5Ž'“´®+ŠEÝS™õxì¦Bàh¥‰G+.°xÛ€Bp%v–ôM5?çy@©€íðmÎ\Ù(i%ÑÕ3Y‹zµìé|Jk©Œ×IDyµÂqóÉ+`o„(…ˆ*†ÆÇ6J‡ ȱK K§LÏ2s³Y•—õæE¥¹dmÆÙùÃ.ëêÙÅe$YÅð Ò±µØ™Ð ©Íɵækš)Ã\¤"Û«›Ä?Iú€„ŠÆö2‰ !âÄCŠ4¬ a‹ •¡lúÇÑ´Åw?érÿÂt³;']|J9{0óÆ`»Ý÷dœÃÃöžVµñxv:]!¬rlëÅE0håg“³¾‹³:ðE(«j•F™»ÓíAHˆWá,³°ÐE[ _øô¾áŒ›_Óƒ˜®(c8À‰áë•Cp7Wt[Wª³ xÁØâš¬ëlñaM ÙR¸€åW2÷5üÓÍ5&ò–­r56H>Š‚§õ‰vÌËœ`GC¦ºÃ¢¶V—‹)ÛçKVä®Îwf»ŒJ£¶9`|"ºûCzàÿßÞ™=Y–÷ùî[íKoÃ))Ë–Ãްÿÿ'?ØrÈ"%ŠËÌp¶êêÚoÝ}ó÷%.ªkšÝÕ[ÕŒ%ݨsî98@â 3±%*µéöö¸ÙíV盛É#~‡‡ŸrÄîÝcò3f°‰ÇËYó1–"w·Ú»] úl³Â€tb:a¿?[ퟅ &J±Y‰,‘Q’lÈK…Í5Šaý;ês|€R`›×¸Çœi¤‰[}Q´¤ž*\nãùj[·.éåïÚæ ZÜ]à.tÞü.33µT5SÝCÖµo¾|Ãáj‹Í«V·¾ýøÑ“*sƒ-‡xÝæ–{sö’iÏ©CH<Æ…r†¡`‰AÄŽÛ#ÜÙÛH4ï}‘Z«mÏÎu¥gÄédÈÊ£_ý¢§¶=Ÿ71O€E½Áá×ßÿ)Ìjéh;’hUg­+z™ú• %Wþ4Ù¦NÁr~ýõ˜úm×ÚMöÎ!,9/šºÌU3Ä<€)MÌÀkÊÆ%“F = ´—0.W _]M9’ö¼òÕW‹þí`ðüx8>?˜Z1Sö(íMÚó²àÕí^}ç5%ÎÍ΀ÞbQëÖ `6YÒÞ~ZÝê¶›¬ÚVD5Õ•ÃS–,`=;=‚Ñ£êã1Œf¬tÀùׯ‡Å“þ1BOôæ>†•cø}š'f¸Ýïaà¡ZàÄÖÞì)´(MÖÑÚ1ZLð:ÛóSf´á袘d/¯A×یˋ Èh³¢ßÝFì—æœƒ˜Û‡aÊHƒkɹtFÀ­4A!ï «z¡ïìÉä€qƒ’bï˜ó˜3613`Ï#”>ã+Æ·ïýPq]'ÎÝÝŽ^¤Ö]üGеz{V¯s9kÑ›Œ<*ÑáÍÈ­Ÿþð§JAúG§ºãÔšpq“L ©PiÏk«HµÙ²ÓYÎ8÷3úuNJEÔëýƒkäòªº]xKA„ÜÐuBrÚQ–EªiÔBê]ЧB’¦Z¤iÅP¶‹ý¢ ï7~®î—÷¢ %èn‚xÉ·3Ž.Hù²bÑzÍ)D¾Öùä™Yˆ<¿&å(ß[ÏT$ÂAŽŒ s+í™þ|o>˜QZjhBÏ¿‰Ä׫:Ë>|𓃧¶IH>4î 7þ$ºÅÝŸæE‚Ã%Üã¿c|Žï=.º‰àµ¶ÌMN$YÕ67°†ÞÉv}·ÿ¶[k ¸ðŸ Ç•0Á°`çªE˜e£Šö‹¯v«ö¤ÙZvZñvÜÞ×ÜìmÖ±á]ƒ83§b€À&íÞÆ‰·‘FCådKo&›¼¤ºµV¯Ì0ÿ=æØ'sx"§}¢ˆÌ—h'XQ‹¶-zÛ¹^…1÷þ½æç†)î( ÀÇh…tŽJշψíädüýpX]llõ¦³þ#TðÖá£f¯»YýìÙ¯X<ãÙ´Æ6.k°aØ[ >M‹cœûÓt&«í+[Û`âö˜eâ1ƦB€ÇÈ6BžUÑDfïp2fP"¢Lߪ8Øc­1jº»ý¸ë¢ù°Æ˜*‡vð.†<ùÆy¯Oí™;„þÇáhð™¥ù^žFëwéçËeHÀˆÃ¾¿=Q#• ÄGÌOp±øþøÛÅñéÙt0dgðdÅfà*¶öÔúó\`¾:è`"‘›wqè1•V·Io%íüƒD¡”WHìL½sî2 I™²yU©òŠfÊXî&ÍSí¥‰«Ëùj2.s^ÜSô¬+Û¤[§w¶Ç=CçcŒ9TZ'/Nz¿ß¾ênm5ÿù_¿gøµÝø¿|´±¿»Ù`IýgÏ~Ž0j0ËFˆõÐäz T1ÏÀVÊY¼ãüê‡åʾþ(œ”/•:vÑÑ#u¦eÄöÑÈ/C!ð]kÒãùu´A¦ïzë×’^^iÌòÅÊßüüïY}>kn÷>}Ât×âððÝ‹«‹Éó£‹ÃÍí“__õçÏ¿øÃø·,H»„¼/É«åh¹Ù«ÓIÔÛœª^´vPi5j{Ÿ`¤ès¶ ww6?©³ã¤Š,‰2JÊ/¡u*1QDÐìM”W§¤r¢±èÑŽòàp†m¶7j[[Ï*››Íæ.[5êÈÑz}¯\È/7ñ~@L®ýYž~ýõì·ì”ÙúÍÿ}~°±ÙÙØÛøóã‡×ìUX4G”(ÍšÀOþÇ•¿D?¢9'"ý-ÕzßKð:Üú[ã3ë¯v&°äèÁN;ÍêFw‹µ;Kvý ö)³Bõp†M&#±ªyÌ¡Ï3v¯P)VõÆ£Fs‹'saXë¯3ĦÃý­*{üI½?¡NHw-6¤k½°mƒ»|J^>Uc¶Qç ”Ö™Z‡üFE-FÍPFÙ‚SŒ {þ+GÏÏ+'¬þþbyí ”Dk{Öçy~GWåËkòÜ¿wàã@´"ªØu.½å6Â>üɰ{¾à¯Võòê yè.l…±ÃÂÅàP¶êÔh266Á€ÙÂ`^~#Ó·Ê€/‡ÒiÿÄ# v£r5=QÐ0Sô—`ULy#0ÏY©ùá9Kcì]'’‚‚@F&Ï!ñøV 1v zK¥™÷Nô鸗ÿÖOâ¡÷‰ à `$+éÊ6 ›82¿yƒÖ' –#æP±³ºŒäÒJ`q l¹fæpûú2I£zçš ­âžÐýZ—cL"®ä@`9¦÷Í‘€‹ƒåÞŸ!x˜¤øÍµuDº³²¨Pk°âYeÀ«íõ~@š¬¶úÃS7`i±ÐrÙaãF½×Û\=yìH’½zAq¤+‡d¹~²Ÿ†üs©+Б•˜()âpØÜ°Æâ{+ÓZlK?ÍqúŒp2yëfåÇ®8’·Â 0Æ[í/:˜n®ìnOœ“Åeûúš$Ù$.‡nu‰ Ñ»º”MP­Õì¹.;È*†±Ú›ìà`ä™Ã¤00ûò!.ÿ˜Or°N'ݧgé‘ÿ¥Kí3,é蹘³ŠXdÌÜå–~¢Ð·¬´¡[2ÍÁ:ŽÕ•Ã÷§gŒùMóËÁªÁö¸­Í]°LøWÙâgKˆêrCWŠDaôX.¾ó‡Þú¶v”VüÌÓ*¦ìþ˜¤À»Óů[ÜD¨#€™|š«¸Ï†v'£$rœFµºmmh5·±‡É0ŸU]°1ÂÄŽÛûûÃÒ¢õ#ôI M;V› Ú #ýVšTŸdP‹OS”¼ &Åüe,\ÜÊâ‰%x±Ã•@c|B”ÙÛî­/N³fÿ>u‡ÏŠ{ExBw¿—¹[Iíá]RuÙ/]¹¤"7ÎNæGôš°Ôu½õÅ—ß´XPÓ|¼÷ <“…^mæÍ˜ ³×†m™ž¿=fÍ«UÛÀíñë™ázâMN}Óm°6˜‡b6æ:¡JÃ/ÆáPduŒ àc÷‚m<MŸ²,™4` MÚñ¬“ˆ†M`¿q„#œÂ"‰sBò> EnãKsoúæ Â(]Çl2òQZµ»"`lýÁpq~>œ\^ŒÆƒþ|Ââ$L+­rOÑÞ¢‚3÷ü-Þâ.þïåèM†Á駃=fæÁµ-+¤âeZ˜½×…P;ˆuÀa¼üFRÅ>¤ŒÑ÷ª#&(–ìdl2°ÌØ|ã}®ýÕ;ïØ+ZŒG½ÞœYœÓåñ‹açêjÙºêÙrÙ«~þóÏìªUv¡Û ÷ïã2 »¤4³)1*a£¼’â!ŽgŽØÃ3/–›e2Œâ7£³”§ˆ¤:£R ’9cªkT¬[œËXråW¿ü¼96¶zÛ™Kn±ûd£{Vgçýþl‡õ''”í÷''•¯‰Î¼[ÆF.ƒ¿ËUÁLꬥavz™º"WêQ oóe]ÿ¤˜™Y£äÿù鵺ž‹'·ñÛ‹xéÖ‹ð¡b+&&ëtŽÌRçÉ4Œcù©ÈH»õÑzé³CÚRíüb|</FøÓW[Ç'Ǭ“›µ¨Q(q=Ìúî  5)'§TÄ;ù\×êëÊf9Y.A" ǽeÈ3w§X|i!p*/Û6w¼N£?,«‰"·5›5•ûmæòYØË£}j&ÕaÖ¤ÏÀº$x€Š‚»Ú*$.uaº—pá¤%bô`è(‘ñÈ¢ÞÑ^ÆÃ´f‰êüÆÊè§â*Í®?¹¾²‹iÀÜÿé代Óéé9¦ÿ&7sÿևܶmß¹íûÜ:"Ö&[Ü=!P€ÒÊhŔɪL8³šžœžVÚ(¹{ŸÔíínv~ý7Ï7–Ë-öÌoÑ«×r ”F"] 8\6c.Üm3 Qw¸zÛù>¼áxœ·-‹ßÑöaÁÄhe1º€PŸÒ# ]ÚÁhRx[ä*âKb\fä7Ž:(—Ýi`« J½LƒŒÑ—*2~Oô>yf#7©ì< ÙùãPKd^:†oí§8WêúöQÏ//GÓ«ËÉ´µ˜ ¯c+¸Ê ²" ¾yh03 áxo·ž‰@ˆ1Í‚±uøX,˜—Œ|­\ç@ÌUGñ¡—ÿäÕ?ñ?¥i…Å}G˜£ /Èh„R Á_i•y5Oé Á¸W 4úÀr#g,[–š´ZUÞ™Õ··—WÃîåÕye‡Új«×íUv·öc]ˆÉ[Ü/tXœNS.ë|ä2RÉD8¯”PäŸò´ÇH%Sù³ê’‰«#W¹Ì)4žqnC].<× •4[Ÿ´˜÷öÆ'v7ºWý«a«Ó®¢s\eùA†}ŸI3nÙg4}vÛ‘(ÍÕ|ÞÖ„b§Ãü}þüd|~†¥r Ho»¶Ý{/¾¹íçönR)jnŠûxŠðñƒÑŠ+3·²Ži[X ×bØ¢ùâxr=Ôp3Á€ ›è´-d'ÉÌ îíHêíq)”]ùíÜšÈ06pÛd,Œß|+#©¤t'‘nî˧çŒ?kâDʱ?A˜+JIDATC¹gJß…<s&SY5!lýÜÄ‚IEâG@8tpU1ˆ9>™€2¯ú Æ´ÎÛúq¼6ýH›_œ1a7ë….šD$C Ÿ™!»^F„ëƒçp}oçtŠ+ôµ$wÃD¥A'CÔî‚…IÙÉ$¯™¯Ïñ!9¸Ú+'y²”iiOÕkø:6S-gn–5Øv®S~TdÌögñ¹Bż›7F|¶šbç«û8g(ƒKLÐ6w·Ÿ7 ØèícHHKÆè‘|h$Xl#oPìQ?^BtF³Þ˜Q¼yĘC©Ée“H’ѧ:ãÐoä™4Ì·Š_ŒTÏ´ÁÔ88﨣]õLJÕV£ÝôgÔy”€ËO™C!žÏêõ!í£:<þznìS¸¼el¾U„̆._+N£sê|wc›iîNg[õN;̓(Œ²ó«g|ÉU…-ì˜á~%lþΫ¯¯ëò5 Ä+ £¬,¯È˺i}tG@ÀŽþq†Åäj6­UÏÎúµ§g,Ï©Ö÷÷q:žÇü:Ýæ:Ú;¾Jz5K½éPâ‰Lg¾nÈ ââiŲ¢Ç¶Í\޾¶ÕÜ|DùòÛÞ<©PvÖ^®ÃÏyi»_?%WöêA /„*&á¼òI†‹oâžØ¬ûhξt^¥X't*‰Ö‹ŠÎ„ƒÀÆ“1Û}' LIs|*­"QîU,åŸÖƒÜî}æos·¦‚»âî¢Ü ŒÁ¼òÂ&{u:·6‹Îóçô¥gýo¶¶ÇØóO]vÕµ«ÚÛ»šƒÊFÍF`ï3<ÂHfÞf¥¶·¢áDÃ¥ê§^¹ÁSÃ’¹ûM´ F÷tHþ2ºf÷¥ÜƘ¶‚Žî¢í:†÷Ã`Ì¢2`×Oz˜¨¡üUB¯DíÞ {“®r5VV@Ç”…=MÃú.VùB¿‹Çd"ðO> 1=Ÿ†‰0§EåììlqyuY9úžáÀo/Æ'§cØÇé%F€½{Œ. s{P~/Ãxo·É@îÆ½V ½x¢œ½Hó5ŸO"Ÿ]ªTÂROŒ¾MDggv"O\Í·Ïʼn‹£' ÌÞFÃt08\ï.ÝóóG¹®št| -ƒûÚœù²žìãíajíÖî´…¸„-êÏ[ò:ÇÇó­?þ±¿»»{Þ>>>›m°3óä¬Ï1-½:æY[››Uçäwö]ˆ ûèÆãáZ°¥qKÿIÏhóR¯ú70oŠû(ŠðQðÝ|l%– XQ5Záo™:†g*ÓÓ uuþñ/1½Që6ê¿]ìíµ7>ûôóÞ“ÇO»v¯º½±ƒU:-ùÑG%ï±UMS}ºlvÓžš(jqMÃÿkaooôFÃöm¨Ñbi¦2B¼áu ù2æYX*dÈ.Ç­ÁGŸgÉ”_b|ç÷yûž*‰ÿd©×kü‰MÈÃLÇígrÎ §GÜIü T­øñN+ý£ÙñùsÚÙøèx:Ä´ê€Å^yÞOáèhŠ=Ÿ‰¯BR†ðÁ®³ÑÀš j×&CåÌÑ6Y,§Ñœ¥ "¡WìíõjGÀuiŠº|JÉÇø°¸ò­åâ‰ùnµ69¾õik¹è°2þywgëÊž}‡m¨=É-¼ùùoq›“ïvðn3SpÒÖgÛxÎt¨\Sl£‹‹e Êú€Y³ýå„áðæ7??îíìv›?{¶×þì³ÃçBTþãÖ¦x¨OÎÏS“™[ý¤SæOÝ¡¼‚1[ppËÓü{熽ýq —›(ù4¬ *6]"ߎaÁ­/vàRÝ‹Ñ#dúÓƒ'•ÅÞ3LJ»³ùdëôìjÿùÉÅ/˜ö9Þßÿíòúzruù?/Y<ë¾$Ë[od*¤ÒÞØìnþŒÑ©Ÿooì>Ùû´Ã¹Ì];’åBÚq%h†Ü¨›¶>N;WÌ?â·ÏÒ}Ê/÷äWçE8TXþ›­úg?ßÙÜÚnÖÿåwýÍj}ºb¶ÊÑ=ƒ£^eßr´\-»#=Ï 0øöÛa•ų“ÓéFÿjúdg»Ûzñ÷G½ƒƒíæ“ÃGµŸ={©lاÍK“´Z\tkŽr}‹ÄH)‘Maq£b扒î>°=&g,š.aT¾« é[vs̉;Z¨Yq¯Nuɰ8=ë{‡s½­Ê¢"b¢V.›ád¬S UñŠŽ,o±d¢ë˜‚ ‚$ŸOœN9øç»ç³ç/ÎgGGƒëãã)ƒCQî¹ÌmçzÛ~¾z_Fá!\QîU…¾­DÆ.ãvJ@ï:ª><’E/ã z3ع?=è_Þ›=wµ1¸YmsÒ Ûš˜¿MÛòB¸"€dÑö¢AG3'Jœ+5{o¢‡˜Àúqj§¼XÃ5Ú£ ’ ¶m¿alßóFïd@7Î8ðÖ«}z;áó—g2 Di„u„A¥ƒ* /ʨxç3Þ;Ís¶þ ç}–ýslît8^"ÖX†ör/pî(ô³àWXêowCå;ݨð€u ]*Äк3ÆÈòât‰ 0&ÁœàÍx ñÏïÒç²GFïq‚ÛFgQc1žCˆh¶9ë‡õEÆ—FófR0)Ãy‹–è8ïA3ýK*ÏSÏ}Œï`à¡6­î\5µÚ¬Öé.[ì,áØØQÔ%ñ—J£¹ùÇOËŒFìdóÆ‘N8…‡Î:¡£ø’ãjpë‹X&eñ(¸T0x§bZyÄ֜—¤7Z N©©ÕÛ]ÅkØ›yÆ~ ¬×¬‰@ª…G10BÛ‘D°^F»ÓÕM&Ï8îºÓéu·˜zfɶî8§Bм‘œ„kœÎ2 gìáD#gêå3Qt'V9½±Û çŽåkì11@HËPºôÞ£ŠªôÍNkp_¹ìϯX'ÑÂÐÍ‚£§Q$Ú‹Ýý:ë;†XÕdÇþ.UŒºˆM©YÉV±-eòå Û ƒ˜[o£îFSX¢Òå\—ÑšÏú`å5+s¾Ž²"³Ö÷…Ð,‰«qÅ•´×C’JØ&Z£À&µpQ3_1Ða²‰Ë ¢[10ä¼ëÅùÅp~=˜±`¾ .[ÿ³¿ÝûKŸûLŒs¶¸-î¾( Àý iå´’ZY¿²âf&±Á}›vÐa•÷¹Ã„ß~7Ù9¿¨£ážÎ×Ëù[r‡ ÔéÖv7ÐÄUÛªv:t‰9"‘¸ªÞf)o°…EƒáD˜–ón<öO4P¿‚4­0-àá‰ízÃÿ`…0Hçû4뙘~ÄFñq¡|âôM0cà›”ôÙ£#ƒ †KÀè%¯§Nršf9ÛíÎÏgÓ“ãÉôòb6X‹œ¶e¯Ö¯W‰S{2§9ø ‡éF%콦5î&[€ÝÜUÐf“Uÿ2ÅPjÌ+ 7çïö­dª¢Šâ J<.¦êp:b·=WH2ÒË?d_ä-dŽ˜ÛŸù1oFiÞ ¯*¾·g™™ ñØñmÒ{¢7ºj×jc0œ·—ó‹)Cë‹ýÝ1Ê$&œ»ê£ý§JOì=¸žÄ¼ T"˜“K0F‰’z®[âkŽ :uTƒp±:ÜR$LzFÅ6Nê4¥L‘^(P„q +ÞÛem#BÌ Ð{§ÿZkl`)™ýßµ}²¤ôo{ñó­cNÃCwÚuF’PØûÏ©xŽn8„®M†fhL+O™E‚)?Ë%Ãï(O"CÞ&ZÍV4$âùc~,k•&ç¶;˜Øì2õ2 ™¯ÈäÄ&bÙXŽÒéHŽõSEÎòÉkTµ™SŸ›TX–»ÌǕ夎ìënlž.ÏNGÝëÁªMYig¿úøð)I22µ±•2mš*D’v’•@Ú¯»Y^Ò­P¶Ë¤,Pž<ÌÙI# ôÈáB>Ó0í-?Ì.§yÄ÷š«n‘ÖÐ}¸zyÆF4Í1#GÏP¹c{¬iß´ˆÅd]K„ÿlqN<$ͦ¡÷'3AÒ±:=»žõÍñøìl8a-uuÉZaâ›^mßzñWÛƒÏŶ¸@ s‚ˆú¯.J+if2t•½Ì@ÞeW€Œ£óûßO䙽ó‹£ùáþùòà Ý¾îïmnoõËϧµ­ª#è¬ðJ£€ÎsÚÂäÙšñÒºÎSË´ìsÉéFá¸Ï­Oþ0ö'Ê>Ö 2â´Ç÷Äc-æneYè…é×µ’á4A8zÑ¢ùñ’)ÌØWZ¿uÓôC8J‹?M‚ ó1'ÆŒF‹Õé‹‹ÿÆ0÷þs.«efù*3±Ê|&Æì4q̉|x$2;,<‘P‹5ÊÄ,LTT`‰æ¿œÿÆÝº ÌÅNì†!ž:‚έžöRC5x³îÞ¬Òo=ðê3ù“Ù™WŸ) £Îpt™`VŒ|ïˆ@ãòÒ(–­Ó3¬‘­'ƒé·ß,ö·ZÓÙDÓ°õÿòwóf¯×­>{ö”‘‡xœD_†„ L ÎZc݈²ç>åÃë þ’GÂðÒj†Ù[BB¬B5¾5´†“­7I0œM¤aŽšÊÁ±•E‹©ÆIjõ-¦Ö­|¦²cù«øØnrY³žŽí½§)¶QŽ;õVA©ðì°PG²¦¬-úPVI/õr¹º^SR\é[K¬ÿãOPœÈöI”¹=r‡å»í mðIm>í#‹ëÑ‚ÖÀv-:‡«}ç†eë»Íͳ2(»ÕõɉUzžä¹µÕÀNÀåÆùÅYug{«þŸþvÞDù×PÚN kyÖÇ”?¬"*Û¾t'ÀÑINè§2K ½m;ý“‹Fhï óÓ¦bdf4Jå@=¡ìXÛÀô¢Ç;sÆS »àlãásvåLì¥sÖ1ÓýÕêê’ýLaá(êÆ<Ž!‡j­Ý†°ýÏÚÝéüE”µ´%HCµ$œE\]]ö§³ýãÕØSÛ¼åmÝÎ^³ÂïÕßÖûâ¢Ü?°¶K½LÌ ,Æ25½ C~8´õ`ø®O/ŽŽË¬óâtRŽ9—»}Á¸EÆQŸb\Ä&”Ùð%QÚ°àEñˆ^«ËèaÒªÁ8 ›†m€0ƒh…$Ĥ û݉wÄô¢š=ü8z뉩È쉈/`êŠÈ€Ñ“[+Æ.r,?2Íg2Ýt|-?ȤÎ-iÎ3šé¼=ЕéôH–W²p=”¬,å« !ßçkîF¼úgŽò1Ó#bžòŠsœÙ®…¹S$bòÔ­RµúÔÑ ¯Ø»‘‚•ç.äùðÐm€ë©IÁ¿fÊŽk´‡Â¯úãzpmÏ)Š…²P@dÿ&ò•VæS eŽ^ýÐù\Píê• YX" îQ ³»¤;o±à´9.kßï°½Ã鵆G·šœ6Øì¦¢$6é¾Qv¢ÈR¹ù<ÊŒT½å$¤ ÌI¤››®†Ä'd–úCÏ—zÆŽ?ð˜LªXÍ[V®G«þõ9½Á«éÑñ¸ÂB9ðŠ6b~RKÜÇoŒ Ön`êž*Ë(AC?•4˜[c'‹®1#QZŒÃÖI`Z'p€+tD©ØÒñ7nHb] qáûéÌó28‰j¼Uªb}N³Z¹ë€µoaµQZ-KéË4[v¶w¯–‹ÏUj,+×Ô-vBV×ì,à¬ùêÅ‹am:©Ö¿Û9Cáh3k†>ºãŒ`À“ɦ›6Eá ÑA¯õ0ʃ£ðÖíÌÖÈËPôÇÓ+N œbgcµó¥Æ~úƒ$Àóg[WÝØbl9éç˜ùOP0kx5dši±ÀÅ a©FíL}‚ô‰%ýŒ­}îèñx_Båå“YC#íd}Å!ióþõ|Œ1(•} -×wïõÖqŸå{n‹{HŠpÿèZ‰õÎ ªÅÚ““Ø3tØþ®ëüù«ÙÕ·ßÌ^°W|ã_~7åФFóóÕ.k"êŸ>Ûó”íú/>ßdGg³±¹±Ë4`ZïÀŠ‰È‡ú”Àä(~Û¾lŸ à&Yh¹º<§?ãÙ œµ´'nZVk])VêÛ‹ˆ-°ÄG„Núnñ\z”ó˜‘ /Ï.¯æœ!@™ºÐÕL¬÷ÿÚ©”ÀôTù/¦á¸úMüD `ý í ‹î~¤9ñÊúnÛVÉõj]×ûΫ8Eq„@QX¢•ÃXeVfÛ¢ß mwTYK«Ü¯˜žÅˆ:›u1"Ò@g_ÒÇG†+Xà4ÌÓ±Šž‰C°öNYÁzs^ë6±" nVV¨Ó¦d&"›@ µûÑüì|8ŽfË‹sNgn/3oM£ÙJBl>W(( µ$—ц‹-Èévý×TÌ¢YKÌwý‚ljQƒZOЋ Á1™b´tº\:×8e¹uÙ³ée¤zqÓççâùÑŽ…GeÔEmÒm Ç­æœÎÍŒyÞ ƒÛXK_p–3‹%&£9ò~µê]1M¡¸#@`í1‹ÍxÂ`:Š–iùM9uا‡…!Fdt™sÞú;çnwâ|s”€ ~ø1¿†•IZÖ!‰.3Gë“ø¨ XŸ´çSG8VÙï=bÄz~ÕŸ´ {y~5‚‘Cüª»Â ìÊárfq¹ç3y w›:‚çÅhëY¨uêqå‚#懡¹‚!0`ؘ½ÞLKŒÀàâb1…ù³Ý“3‘ÑØ;›@x©2ÕÛ)'Zný5n¡²…ìꪞ O£ö¨|p±ƒ {SƒöMZVĘTWF´œià— ’^úKàP G›‰µÔ}Éꌴ1«þ±í;œ0°Å̺HG¬Æ>Üúc)½í[Þj9YFY‘Sª:@™¡ôVgä§:¡×NÛƒj§Ý\îìòzÖ`žc™,tÁc#–öC¿Û/A¬†@U ˆî¶ ê9#œ¥¹<»‚ípÎá„Ø&`ìoÊÀµ½tÊÈB’ ¶Šªø«ÄŸ €¦¹­ûÆØ]:r4#”a3â–S°W…¼ dçK}~æÕp\ÄÈ oHß³D°$D/fùþöï—EE€â¢< ®Æš+µ\/“¶MØ›“182 Ö»cÏM]FÑäºEãâà“}‚37uË›Â)d¼ÇHü¬ºµUc^”®\4;{$ÓÙè¢ÅòÓÅk,¸aß8}±üæh¼í ·¾„ˆá§‚M§ðvgv²{%|b‰àd}ͯ°ã#kŸ^†=^{ù0çS?Ãûî^ÂÿùÍéðøøúȽËjý{uŸz==t.lð¯–ÌL8d½¼¼\Œäyk¦–((Y»`‚k%ÍGŒÔ`§ž‘[Fg8Ö· Ã[½8a×ó˜óا1ß™?}׫uÈ‘$½8X‡ Þ;šôéú·Û}îâÂMêSûü \Y4/.æ{ÐÙüâËÉûè[ε6+ð[T .gǨX2úÌ( JŒŠM®lD¤ã€Á:”8«±p84¬rÄ”Cïí-*dÄM5 …VEŠž_Ø2@Ö8<ªh#¾`åy¥½Löèëáòþ×ɸݩ »­ó~»ùÛþd¶˜Ÿ\NÆÌ"ÍÙE:b†Ëzå¤îyS¿Æ˜%û5)(FUè@ ÂzÅÎâ ïÀƒ¶³øÓŸ®†œÓ Âþ—Á4R ¶aÝ×xy«íÛºk[Wy³Œ,K,"®¶Y#°Í–ÁöÅùd—dÐÅÆŒÕTj‡­ÍV‹q39ÚG+^ÒJáMˆ«¸¦ó VZÙóXò%uΫ;k¢< ˜ÛÞíbö™>ìsVu£ú»+89ŸÝé^ûö©K’@"‰ù xØÎýíi™âä3•¨œ6·Å=ExTSœ¹þË02•AøÜŠ/öVr½½7¯ôrâ„8¾ ‰CØhàI*Ç–ÁêùL7¡Fˆ±9ß'öf_C—øBô]äÅÞâ씓``ŒÔIC¦/‚¿ü“?|ùäG¸3ÑW}— ˜ÇÈçÇÒ2¢×xÞæx¤êjÈä(Ã±ÕŽÒ s½œÎ0‰õSKèm£Dw$û/¶x.ñ H^5ÑÁÍP(]qÌ‘Üõ*'Å—Wë‘xäú¤bàoë‰õÊ…àÖ1fàcjÅáà6Búf,ëXÕœWï “Ðoa‹Ê­o.Óg'CQÝ ŸªN¼£ê™É£$1® „UøSϸ®0ñÌ  O…=ßü &éÄûLïýk¢ḑS¦ÌÙñPgï#2‹“Ë–ä³ã3F¼x¦)æè]ÐñjR¯Z¯ä ÅáË=,T«Ý9à¶\•f§Ìˆÿ4®c÷½Þö.¶iËÈV™ËJÅÍönù´Á%3ʈ04kŠ Ñ˜²)Àå¤ë6]h¢ƒ6iŠ2Ê)¹È‘÷ZêsÇsX®!¤¶Ó-ü|Nz¯ºÜ&}žëá«aþâ·uãU÷Ê#ã²]ëÅêö}ÆîÝ ‹ûp¬dÅ=,™X±ó¡ ÀÞÚc<[ bT@­WFîÜaîé9Z S÷÷£·ãÒ¤êìjѼÄ2a­žc‰Ð†¼Ý|XðfoÔ@ë7jÙ6:Ûå;7lÂ>”³§$MúÜkr$@oÏ@eà^ó›’Ù&ÅèJõ†+3¶—’—å%6!Hß%q„œVû˜½YqÞÂòà÷Ês¢ãû.qÜFZ¤Íë^¡’w ¸6Àºb]²NY_ÄÌö-ž qŸ¼²Lq©Új¬,£÷¨‰[ò‡Ü;òª{“%OQ{D+¶¦ñ;‡w¾&ßk¡‰j8Zç¤?×½Œ±=@éõù_¸ï¾s…ÆÕWà:m¬j}ˆõüøF4Û0~º!ø­YË™õå/bz݃uFx `¹Ú«¶ÂH§J?_Ž·oü£à×=Ç[íù[—-£gxGlç¹ü¼ZVÛàTçäG¶vÆtŽß¥v½^Ò«Æ'5A皬<˜Ç‹uNL3Æ^ ø®Î°~o^,—¬ÀÜ"€§ærÜÒ$>ò>Gÿõ3ë¬ïî#-¢)îMàMÈÜïs+²^'›µÂÛ¸lÜ–÷6 Ay•ç†+£÷~Í’ˆÈ8Öý0¿#†ñéMß¿ÁIGnÔ™¿!èöX!kõÒ¦½Ìç>ˆ"NÒŠayÓoiÈN,MÛt}ž·ov0\• !å Å,ã¶\ÄÚxõâò·Òd\Ö#ãµÎøLábz^MÓzå;Ÿ5TLÖ¿ù6V`ç÷<ÿP’ˆñÝœô‰§tçrõ™¸êÅØç–¿aô7D P\§ßMTÚ.Ì›tx·ùØ“2Æ¥ózó]÷·yÎÊÂÕþ¥×t¥Áú­—æ|•véuØò°}XG­ãÒªRå@ƒ~Ž$4¬ï¼O®' ½³ 3컸W1Ïê®24Œyôª³ìÅÜ:åÎÛ Èedž­3* †ó·ei^õïã¤K¼ÅÈëíúqÍ géÊqØ.s™½Ë÷Éþø½qéo·yG‚¤×t?6 ¢(îmüX àmtüµ¼ÏŒÀÆdƒ–)Êìlä6¯2™ž‚# nàbx™' ™,h‚Qþ ÔëØèLÆæU&ccó÷Oí¤Å¡R¯Ò&ó”Ý·3¿–…iX^eÊ·xβòÞ²’ž»“墵ÜâÍÊ€½7…“>ÇqW<»Óù­^št^s}²Y¤Y:̧4™¶¿ÅÖ:#Më^%wë¤Õ|g¥Áz(ݾó¹å|„·¬æCºÅÔu†aD†Ì‹ù5Nóç7Æa9z5·pÆ›•Ó}[:†ÑK¯´Y¼·|œ¶ñYV²²èUåÀ¼.+ܾ·ËÂ[L¬ÇÒ"æbù>ÎïåS~o¹¼ï÷|òZg<Æ'mbqŠ÷ÙÛp%Hq÷@QîÅ÷#Wp”LL'c±ÁÊ”}&³Ö¿êd|2 …á#Ãí[igf,#Î=ùOíd2¯2Jóv_ÌÆ¸2#6Ï:Šå«mÁçb¥pñ^¬²ÀâöµNfmÙXnÒm¼2rËÌ8ÄØ´Óøü­¿ÏÅýˆ¼Êô~Ĥÿª“²QêlX™»µK&à¡Ì´e¯:Ãç^¿=ýûºÌTe »Éþh€Ò S8ÝSPØŸiXïí]É ½¾É™¶ad¤bõ6ægÙY6–Ÿ÷¯°Æñ^Æ.öÒô.ƒ`ot™¡·Þü·õigýûWi³Né­G?¶“N¦el¾½÷™å-öü-ßùL—…˜xÞ0Ò®7–‘aô–‘áŒÃò¾ogZÒëõküwxÓ‘.Ÿéßä|—i4Œ=j§<,‹ïñæÅºèõ)^eÒú“óÊí;±Ì˜Ëgr}y×sYIÿ‡(w¥cÜzÝûÒ•¾*?¢|0t÷ö¡ŒÁŠoãò^æ•™…Ï^ç2ó³üdâL3kßÞ›îOídT2ó-Mâp_θôÆ+ÓÃ,€¸}­3¼a¥)cuM–…ñær{]ÙÈ@³zˆ<}¤/ÍÆoZÒc>t ëtþØNìÌ¿XJŸ4Ic¦õÕr7¼ï¬æCŸËÛÈC.¿µ<­Ç†Ëùåö^].3ÓÈõõ}Èôßû[š³²hÉB6+<ú(g:b“ëi¿³ ¤ÑïsY½Ï÷w…Íe~W˜òîø)˜Àeåß|´¹,2#0CùÙ«™³‡é;¯úq2žÛŒÒ†øS;iºÍ ‚lî]åë]éÈð2V2ÁLßë¾É½kË0—Ñ«áÄ93xñ¿+¾W¿}Ÿß¹îd!â²Üó¿]ÇÞ'Î k^FG¯ºŒÁ«uÐ<¨¬èáÁpdÅõºœG¿÷Û< ðã‡tY‘Éi¿oZ™v¿Ëå‘HóhžïË)ðÅÚ«Ød¼¹}'gøüÍû*ï”@ ôÓ pŸ•ì§ÉÁ¿ŸTs{• ¾)‡2¿ù˜™{1¦ñ1ñøý¿g>ê™gæû&ú-qVpéßæ ›ËæuaM?Ç“Ëüuá>öYŽ;×'Ó4miËyÿØ4>äûŒ£ôYw9Ãdú­«–•BRÿª3oör §°{¨¢g>2mëGïuÉåãG9ó 3oÃ&¾ãÓÊJWVhßñÓìß3?%#ø÷ŒëCç-—› 1ßHš2œÌt>äû«ßdÌÞ?™çmWž÷¶]Xãʘ{ÿc¹,4sÞ¬t_MçCò/ÍŽ¨dáÿºŽ‹ñf%Gš1æöAÜC¶óyŸå$6¹®=4.v‰ôa¸ÏJö0–X ‚ÀËaryÖ›ø–Âí¶°+¸ w ð¦†tÇ'åUA  PøÑ¸Í«nßß&$÷róõö»r_( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@A  P( ‚@Aà¯ÿ2<Oa¶çIEND®B`‚eric-6.0.8/eric/pixmaps/aboutEric_2.png0000644000175000017500000007735512342634026017015 0ustar piotrpiotr‰PNG  IHDR…áæ¿vpsRGB®Îé pHYs.#.#x¥?v~’IDATìÁ ¦eaèûÿó¼Û·÷×{ϾÌ0첪 `DQQÊ=š5zS&fQ¯INɉF³hÔÄ“ÍDQq‹Š@d`€fŸéžîžÞ¿ý{÷g¹žªÔ­[§JâIpIÒ¿«V­ZµjÕªU«V­ZµjÕªU«V­ZµjÕªU«V­ZµjÕªU«V­ZµjÕªU«V­ZµjÕªU«V­ZµjÕªU«V­ZµjÕªU«V­ZµjÕ¿‹`ÕOÖZH)1Æ ¥ä'„°ü VýÔYk¥ÖÇqBþ7éÊRö;®qB.{ë–—)´ôåxoÏ9×ÜÏ3L°ê§Âš¼<{ìwaq¶2wú¸×ì4ÝNkEï¾ä²JW—­ý^cT¦…º…²€XoeùÄž•ÎäëéL˜b\ð*½juøÑ‘Ñ-Oô»½¯ õî /WX ù7¬ú±³ÖŽ=üäëO±O±Àÿ!ÁªgÜ£ö>çá÷_uz~fG7iyÆÈz'[ŒQ¥tIiU&‘•j‚Eˆ(ÊD?ΉRC±T²Æáx.Ž+€ !uÍà`*ë)È!È JRoãURD i,jÂȵ^à™=¤ó w Mœõµ—¿ú?+„ˆù Vý³Ö:÷ÜõÅà;ßù¦—˜Ü¿ü¢+ž7}zjãÌÊÂö$‹ÏŠâxO”$E£¯2×iœÀÃñ\´†RÕRÐ,-¶i5ú”ëE‚b éH„tQyFPäqúˆO©¤ñÝž.³fp˜¢[âÉýG8ë‚AÖLt’”NG&š^¤È— ñ\N™…;öüõŽmÛÞÿ²7üiÊ@°êGbm>øÕO¸~σ÷n™Ø°a2ö’¥å¥ ©QcQí§z$6®k´‘ü€ô=¼b€ã; Žt)ÕJ àø. ó‹,7(341ˆp¿@sqW „îR¬h A #5”¤[lQ¯IéÑ82ÊæÁkpò­Ì/ÏQ³,wO°Ø˜ÃµË¸y›ùÓ1ýŽ^ªßôñòÓ¢~I…`Õ5søá_ý§Ï=ûøäñçK?˜ÈÉ×âŠÍ©5…4×Áº-è‡1íN(Š~•’3H±X¤P (”+Tª%GÙ±{µÊ..Ò‡•Nƒƒ'–ê{˜[8ÄÆ­8vô²^“n§ ªCm …•m|šò`„ c<ËÜLNÒ xÎe¢úUŽ<9‡ÊYÖÄÚ„0ê÷3Èa°ì³¼˜±¸ÑjæK7¼ð²üÊûoÿ„"çiþ‹³ÖŠ»¿÷u÷K_ý’sá…—VµQWÌN¹túÔÉ-®_Ë•º°Õí–¬°¬Ý°†ÚèÃCày¥åÖoÞ‚0>;'öPª8Žp,ÿ‹±šNÒG“›„\kò~ÌÜÒ 7m§…ÔðëeÊ¢€29Çgõ²Ü8F¿ÿQºHk¾O{ºÏúu£lß¾…å9ɱÃ+ŒŽú‹`Ò¤"UŠ1Š…ùŒVËâ ‡¢ë39™0P.ß}ÓïüÊkϽö·æy.ÿEYÕÿâ£ï_÷ÿ¼û;üRõžïï¾û¾½;\¯4²fÃhÛk‡Äæí[ŸcbÃ(õr™Æâ cõq”£™™™åÌgQ”%>= Ú*ÈsŒ0h•’å)½n‹$í32RçøÜûnÿ—ífý¶*}«Œª¬èZ­˜¥™Ýþ4³s§˜_ž%¥G5€u¶­Æ„–¹ÓKTF3œJD’ä”´Ë` @YÚ툲€¼(‰úŠXC¥,huÂ}=¶˜çi¸üb­u¦'?çS÷W¿åͯxžô‹[½ÀÛ000T~Ösž+ÏÝõ,Nw Uò’+f±ëЬ×0R G„Q›$n£LDÜë ]hçfm™—Xzø¦< %‡“31[·ïdý¦µ¬ÌjNNÎá•rjµ*Ú7Tq©D>y7ÂV#œr—(–Ø®‹k è$dqJÕF¤‡†¶0Žkq˜-óóÍ‹­}âûBœmø!\þkû»ëüì¿ýöþ‡¹`dplÓº­çÚK.¿D^{õË™ [Äžá+·~‰ÓÍ%F6Là‹,†.ƒ5—@„TËàp‰‰ñaºaŸ™pšµv3Ö/AP³Bd–éå ¢¬Ek®A¸Ô¥¨ ŒÕªlÚ:Áô‰'9½4I:ÿÕ4bæÑ”¥Å”©Ù„›þîyœqÞ6ö¯§Ð©àÊKœ’¤ê:ô› §ÂéÙˆPK„ç!RKÞ×(‘3èINœ*<5 !šV_¡µC±(«½¸Áwo¹Ù ?„ËbÖÚò7¾úÉ]ÇNzé'ÿç^o«£ÛÖﺀ-ëΠ±¬ÅÜr…üúƒDŘø6÷Ý}'ϾñE,®#Ï2Ê¥"¾‘§!õ Æ))\Ðá‡æ(ŒmäPü8ÂßD-/2nZ,ô2ך&qRlåZ™!=ÊÆ‘ùÔI:ÇŸ ×™aþäÅ(e\–ÉKOKªãkhÈÍa‹Ó.`{ …\Rp:Î襖næb‚"y;ljr*ÚRH Ê*0 ÇÓ8TŒ@a){ =X޵èGÙxÇ‚§áòŸÔîØúáßë»fç®_l5×\vÅeþç\ÂoúKn[ú&ÛÏxÍFƒ…¥N3;yˆç¾þ†‹Oœ 2R ÎŽ’‹ŒœJ™ûÄm—j9 nDlØÍͲ²0…73=xš4è+èw%"1¨ Çõ–ѽ&TD…1î[F¤CÓ¡gœZ•ñ Ufûœ·e;#õAòJ—$îc<‰r$i/@ ÀQDqi†Q9Fr£È•Âä–$·XJKŒÒXŽßt:=÷ñ' ž†Ë2å•Û¿ò/ý»¿ýÓŸoÇɵ^¹ìýÂÛß„ô ¼û7qzz™ÛîÜKœV¸èܵ^èpåyç‚Ôüîý¼øµÏ']Z&Lz¤ª†Ñ1yÒi§xÊC(Ëá°Íüd •楯)Ç“yzQdˆÄ¥L°µûÈ’‡®ÄôWbZK1*éQ)U¦ïÙºm-­Åœ°oPHœX“…– äa¤™¢^)¢2pÀSš$LIz%ORð™ôcH•@)HbCn-°GX£õb¹ž†Ãßúò_•^zí¥?Û×oþСGÞ(ËåóF7ntÖoßÁ—¿ø=þô÷ÿš^§ÍÍŸû2GçË_ù^uý*#Û8°ÿ.zÍ™Ç;o|ck†(m$j)|§H¹4@Òô›†ZeœË/¿˜#ç‘ïÜÏ¥—®c¬îà&ßÔÊlÞ²‘²ƒÌ"\ÓãÁÛ ±°ˆëiq ÛË0iŒï¦$ºG Fê£t:)q'Fä9^š#㜴“Ñ\Îè…†\ âLÄ ŒÀq$6Ç•”kCm=ãÌ[¿~û~ÃáðŸÀ×nþà³÷?ôÝ÷NMýõ®ŠwQ*—Œ°Ð yêà,ûîßë{œwÞ™¼ò of|d-_øò^îºë^|ð)^pýuHúÌLOñø£û¨unüùë(lja+œ ¥ÕjTjœûìç±{ÛŒÍÖ-°t¢Ãç?ñ-Ž<0M8Õ¤wj™É‡Ÿbþ±'™zø §÷ŸÀiæ\qî94Ž·É;çnÀ÷,ÝÜaçæ³Ø¸e'YdÙ±k„•¥9Âp™@çÄy¿‹$å`L<ÍÑq‚ 3ÜLQ²@ aŒrÖ#J$i"p‘dÚb€(1(mûë7nü‡÷üÎo<ô{ø”å‡pùÌZ;ð—üÎwÞsÏÞwDVËÀuº¹%îÇ$YÌÞñK4WŽ;Ek¹ÁàøÝ4ç¦÷½›ÙÓ /yÍoqÎùÏâá¿Ì†íg0´ [wùã?úžx€³Yé4˜Ø2ŠW(TN/NròÄ F*gìÀ>Dub™‘‰€™= ëÚÃy—¬á~ñÙìÚ}ë«[¸îʸý»{9yx’¡‘:—¼|S÷õ¸ý{ûxÅ _ÈH¥Ï¡£s˜•ÓÄaN¸²B‘ÛÍÊÐìwQýßäŒ%ëÒ²XàJŸNh©K Ë4Ò6Ý8B8P.;ø® VviltàJWZž†à? ƒuïºã³[Û§§ÿd¹½r]‚=2#pëU*ÃÃã²ë‚‹yøžý|íÓ_AçŠ~ôC|æ3·rÿÞ½üÁ_ßαƒ]žzbÍ¥cÌœ¼õ¨9´Mº˜ ç­åE¿tN ÜšDå•ä ³e“Ç·þᛨx…7üßë9c­K­!H2ãñ±弋wðâ—_É‘II­¸Žu#»òÖòÄãrË7¿Î7öÞÎëßôf N‰@ ÎÞÔd~z†fç$ó‹!i’âêú=úÚAÖÉÃÕ°qNÁÒØâ:Jy(íñÔdD»¯9o[J)¥ÑOÐÆ0<äÑŽØûê×_ÿÚW¾ý3Ë< —ÿ`¾÷í›·ÜzËGÞÐh.½>ÉÍ}ë "(‚çrõË^A/LøâÍ_àŒ /!»¤aÛ7ò—ûW<´w?{.~6_ÿü§Xœk²pz’°{•wïHWR¨8ìºlœó¯eæôÍVá–Y»i#õênþãÏ2:^çe¿¸‹á‘”Siœb‹wœÁ`ªÔàž#]ÒSDnL¡p¯ù(ëJ;Ù~ö¥lšßÎK*M^ôÒŸÃñ}ÒNÈÔ7³ÜžGd=)a;¢»˜àv3†×•XYlãkCÑZ°’8´ôËÀ€Ïðø_»kžs!hF1ãÃ’uc>•’K'²(Q4×½ò†·†§ãòÈ—>ûçgÝúåÏýaàz/ cá6TNed``JÆ7oF¬ážï|•‹_p ãC<|÷}lØ4L­$Xœž£P 8uä YGÓXZ&‹CÈ#Ï!‰²LR®–ÃÝáÜ ¯@·îa×¶€u£yâ±#|ñO>Ϲ­åÊë׃s”S³“êNÁ¥VªÑ+tcS'ºœó"IRÖÈj‡Ükq²¿ÄBû)/e×Î <±p”¹ée†'FØsîc[“ûWؽe”SÇZ4ð8xrÇËè Í€ç`•@(‹’¡Ñ"Ë]ÅWo›a~9¡èÁk‹Ô]–»1§c†jQd¸à‚µ'K#—4¬µâ,?„ËyÚp¿õµ[®ôÁïüÊ@­ve³Òl‡Œï^φ3w J5z™ jîøÆÜó;yׇ~›÷½ñ×iÎ.°vCŒfí¦1–N71ZÑ\š%î÷‘ŽÇŽígrìøã,Yšá¸‚r­ÊSäÖ›ïáÜgoçÑïÝÍßì½…÷>ÉkÞqo{ÇÕœ˜¾—nÚ¥¾Ö‚°”Ë5ÂXPÑ6oÚÀc?ÄôT 3ÑÅ5)åªÅ¶ng‰Šà»§‰Š´z‹½Ëýˆ4¢”gœžÇU’‚ïRö}Ÿˆ©®q¨”pÈ•%ц0K8µ”0X‡+žµ†n'¥êH*.ke‘¥•k`6‹(•ª~.?ãšQ·øÕÏþÅoœ:qèF²íðÑÌÍ7PÂ’›dÇLƒ ^p ™(ÓM¬[c :Êçÿôï©VÊd>Ýf“j`9u|“)OÐîÌá…åøáÒa Öâ0¥6\¥¹tŠ/~ì{hn%aø˦Wíâu¯ÙÁÜ©{‰£)Jƒ]p»<‹Ÿp³65gŠñáéýc FË£´¼4d@DˆÌvcl33·Œí¸Øb‚Ìbê6§­ ^&iŸŽ „KÉÏ©¹ cM¤-I‹}…-J&Ö)xø~FÝËñS^@?à *Ç®’OàmkmA‘ð4\~†Yk‹_ù›ÿñ‡÷í{è­ûö)œ]¦T`Ýö¬Ý¼™Z…'Š›?ð7¬?ãL†×®!Îú¼ù¦·rÆÙ›8~ÿ>>üë$ 3Ú]‹ô”V!(”‹DýˆB¡Dž§h«1<)(V=Â^¡‘¿ñá˨Žå¸C–ù™åiC_H¦V&ñ‹m4TÍŽpˆMÕ”‡<Ön!N$“Ç–)Ÿ9ŒqHDjH€5å:BÎOÇíô(ÐëôtÈ3Ÿ ߥێ© ÅT?A hÆ‚^_ÓïåTÊ.åŠGPóÐâ0'‹,ž¹´Ø$CãZ\ßbÄi_†…ËϨîòA÷cúµwßþí»ß>»ÐλøÞð®«)Ž­g`Ó&ÖmØÂ°•,ÎÎñÄG¸÷žïóäR]S¦Pî³ïžÛyF¡Z¤·ÑëdÔG ¬HJÅ D',Ú€Á€µ¸T–³yÛå5=N.fÍÀű"ƒOž!—+¬ÓÔ†‹TÜž"v]Çajº#k Kæ§Ûl‹4ÍFÂèŽQLê`rƒè[†Æ+|ÿ®ÇØqÖf¹[w‰»i= ½„²Ç<ÔÓXßb=I¥Z §2:ÚR­øW¢3ï Œµ ±¶Hk°F ¥Eº†$5Xi,?—ŸA6‰jùó÷ýѽ?ôgë°óÒ_~ã[·’ÈîÐÒÚ Ou§ tÌÐð ãlãMϹ€ÖâùÀïqäá£lÞ¾–ù3ä‘Fâ‡1›vl0ufO¶H¢ ?(Æ) BP©UnNšd %ç^±‰V[PÁ8."_O’Ï1ßY¤8Tb¥Ÿ"KŠáZTV“ PÚÁwÎ8w”‡îYFÇ?ó± ƒÈ)I#Íȶ’o+ÚͲïàI½^Fw Jûœœ yòP›BÍah(Àzq¢Ø¾­Âr#¡gŒ}Š%0Æ`¬%M ®ã`­ÅXƒçKÀ‚´8Ž(‚…ËÏkmé÷Þýú?˜ê.üÒÆKϦº{+¦6ÈlÔ§>Vg Rbeyžb¥DR†£+§­œÌŽ14^gÏÙ{øæßÞÊŽs¶1sda‚b£SÇW¨ÖŠlØZÁ*˜ŸMžÂuAÁCH…ã9d ׸ðÊ-t²Yüê ~Ž= ³'c‚A›yZÊÏ‘N4êáà*0Âå¹/:Ÿ‡¾{'½…>å¡òFJ­@/AÁB§Ã5/>›;¿ö»¶Žá;’þRÊìT›ƒ'¸ž`xý ¥j@à *e¥S p ‚ååˆv7fhÐG0¹EJAà;ÄQŽëXiÉs JEP¹ÒÂsË!ù2Ù>üáÿøå›–âÖ[w^y!£gm‡J §:@el ¥ê Bº  S­ ²·XhÎ3½pŠÙÙ)œªàÊk¯Æ•.­Å·ofdb„,Ï)VJá°¼Ð'SÇ7Œ®‘ ;Têá(‚"diN*ÆÆêTj‚¹™ÍyÅ쉔ö² »œÑZê’+‰ Š8¥"¡.™Â/’;.ÆuéôsF×0´ÆçÉ»&¨"CMÖˆÊxF@n©Öp¤Ë©ã-öïŸãá‡fxêHƒ(3lØ2Fm|w¨†(*c%b¥ÐVQ­9X aœãºß¾C–Z”²Ha±Æ`ŒEk³<4T?(„ОëXž†ËÏ*ÿŸ{ÿoOV¢·¯9ë’BîV¨ ¬c :‚Œ *®EK8ÍhÌ78½p77Ô*e|Ç¡·Ô`ÿ¾[7Î+ßöj&O§<4MîjN>q ‘ ¬qXYŒ©Ö<<Çâù•CØÏAÒD#¤$ŠSöÝ÷Ãë*¨Tâ'5ª~••+ ®bbg‘,ÑDy€gt$Ь­pE% Ž›sÙµ;ùúß?BkrŽ¡z‘[¼$#ïæ¸ YFc.¢x¬Ý1JàIvì);–ãS+ŒÈ¬Æ ý$'Ž3tžaÆu õºCØWè\ ¥ƒ# Î ®#Ö‚×%l¶nÃÆY~.?¬µî¼ÿ­ï™/;¿½e×¹RXrm‚À¢PC5´µ(·L.-Ý¥ÑkØ€ly…cpß‘StWtVVÀ•~ê¶ îˆËæË6@%çðÞ£èLãºQÏÅ•.ÆX¤´$q_õ5o{ϵ¬ÙRâÎï|—ÁÑ2ãëëHQãÔ‰)N[`tc‘ú‹$&MPÍ2ÂÓ`Ž+PÂÒYé!2«ç^º†Çïªñà??ÅË_u!çÑ[iRu‹4O÷¹kÿI ŽËõ¯¸€ñÍÌÌ®`¥Ae)¶ÄìÔ˺u’,Gk… „Ae×øŽ Ï •’ƒÊ-Zƒç1ß—he¬–'_rÃðοã_ãòSf­u÷¦7¾Ó-GïݺëJ©ü ~¡BPÀºŠõõ¤Zã::·,ÏNòðÞÛ8¹ïaŽÂD1Ãå*=çb.{åõàSÿð)Z½Ccƒ+1=Åæ‹6²{ëî¿ýqNŸ\Àæe)VBj„¼ò­—rñóGÙwÿlÜQ¥Ýìsâ©ÞÊ"¿øŽç¯ô8q` Õ¬S”ÄsgPöC/'îk²\ƒÐ©ʼäUgóù?Ƚ·äòçn¡R xôîcì¿ç4±Q¼æµQ*ñäì%$á“Ç8°÷+œxä žp¸ñÕ¯áù/½†Ñ5:~‡ûÂc8Õ˜!Q-ä8ÖAjMÁú<ñø÷}ç^ÞðË¿ÆoýM¾÷­Ïq×­_%Íbòb‘•©y„ ŠãôÚ!+ ‚:y4A±\böbÍš2ŽW&V}JÏи ÌæHTÀÔ‰vm—\õ¢3ùî­G) ¹lØS¡èy :>¹Ú#A(ˆsM¾ÑZ 9x`M›†¸ê%ÒI":Y›fœÕ&¿{†#ûLL)8$¡/ ž/‘րРͦ¢0$ñ…D rÖ@)”°HÂH3\ñ÷m[_ºÂZ+ hþ…ËOØ#kÃôÜÔû>óñ¯ßøÔ£‹¢Õþ>a¿‡1†âè Fi§çÙ´u /û…WpÍuÏax¼^Ìéä md |K˜(Œ±´F¨Ë}{¿Me@qjþNªCÃ<ëúMlÜóbž|äÍNû$í›$óYFæS)ý•Œ—Õ Ö‚)¥xŠt°ºJ‚_pxòÈ7¼ùL&/rôáe*ewM@XÎq…¡ª%6tñ”CÔŒi/ö8xh™v–³û¼ zA“fØBë” °˜^Ì%Ï-sôÅòbDØ’Ô«’š2–Di B€r™¡r£ˆs©9݈QÚ’Ä ÏX*’<·tC{²>Tùø{?òHƒBaÀ4ÿBðôäû6î_øÖí»oáúj°¾øØƒ‡˜=v×ú¶×9ë ‚AA½êâ&ÓøÆea¾ÃÃûç81rÉó7pæåãth‚NЭæcðë…†¹Éœ••kÁuÀq&µLø>õAIP†^š¡Œ Íaßà:’ZYà:×3ôz†‚ïÿÙ-·Ýý;¢ø¬ˆ§a­­!úü —ŸSGO”ŸèÝñÆ»ï}ôå›÷\ì9÷ žûòXª…"*‰q\>}Ëg(­FTºª¾Æu}2 ‹±¥,ažàŠœW‚ÌžÏÝw>I–æ¬ß4Àüä Ô<2¥é6#ªå"ýö4g_þ*v]´¹ã'H2ÃÒÂiâ´ÉÊRÊe/ÜDØ )È2Ã5\²4%Ö9ŽÔ8Â⸒¸Ÿ%}Öm«³û‚1NŸlÓ^êQ€L·Cºí³“=Wb¤tŠ.Rfd]…4–¸“Aª(•âVŽÍ5/Ù8á²q4`±‘Å /Äï[–^_£Ô\æ2+â_!„èóÿãòrÇSŸ¹¡ãeïÙ±=(næd2Å@}Œzií¹8²À ¬Òî5X˜ir¦{!)Ʀx&Ť)Ä)ŽÖ(mÈ3ƒrbò4ÃMs:3Ëzr޳.؈µíVŸŠW¦P” Ç䌖k¬´OòÔƒ‡¸ìù¹ðY—Ò˜ï2°v…¿ùÐCd©&‘äÈ-h‘£5y¦‘ü@jè6b®}éN>ÿ×07Ù¤PªÑîç KKmš$±aó®A&‡ÌͶÚ$±Ö¢2…g@kKÖË‘Ú`2C«cq•ŠŽ XsÁ±j2¥©D ‹çJz о \€,S Ýž]Õß²qw‘³¯§XõXœ I{š¤¡ú )Lªq”%î*’PãXƒÉ &Ó¤INçHmXb­p<‹'%yIl¤Às,Y®É3ËbC%cCïû¯þÎçù7’ü˜ÍÎ^÷µ;þé—O­t7šB [ĨŒû8"ÁAÙ€4øÂ’›eRbÙ¡Ñ]$Lû„iBœ&ÄaF¿‘Ðo¦ÄMEØJ [ ­å>3“MJ¥€rÁƒÜRð|²~FÖNHšªSÎGxxïÊU¨Œ&„f‘È®0;qñó.ey:béT‡¤ÝD&]ò0A'“j²P¡c‹Î,:2˜ÄPðz>®TìØ>Hk1çàã ,Ì·]_áŒg ²nW™êÚœs.¡×Rœ:Ô%i§è(G¤‘Z¤²ˆtjP‰Á*ƒ/,®µT •ú¡!ÀZC–’ÔâJ‰ï ´¶(mèGZ þþƒô¾OŸõì7‡üI~Ìþæ¶?¼ñð‰S/…"ƒÖ øž nN¥è2X-àᚘ4K)VâN<êÓ[nv:è4& ²8Fe)yª0±%éiº”n+dp¨HÁÈ3讄ôûtC¢¥ˆ¼—R/웢xT«Íàh‘n»Íyí¡XõÙÿýiôàãü;I~LnøÕkKªèüæø™;'aDm¬‚²]²¼…ƒ@*IET)"1q_Eh|ºËMzS °Ò"9µ„]hB³‰ív*Eg1½^‡°•à{¦Ž,áX‡áá’~F+tª±©ÆÆ)szù aR«V‰æ«Ð¯ÑšÑHÑbvöQÆ76ÙuN»oo2{B¡:y'ƒÐàã sAÞרTÓïD,Ì·9~¬ÅÌLŸÊ€G¡à× ² ¾–ÈÔ¢Ú)i·ÍŽmEŒ2,Ï¥d}ˆú•1‚4Ç4ƒ$·(‹m 6¯spBÒ‹ ž+(•â\³ÒÖy½â}ºö=ÿýO>Ì3ÀåÇäòÝ[> ç´§3a2KPupEyØC#Iµ$pJdB‘ª E†JSˆ-'÷Ÿdxm•‰u5|¥5žM¤¹²TJeÖ¬à¾;zlÚ2ˆÒ9±Xc‹Aš ”ièDy®V· Å*ØÌB9CË¡GOpѳ'øû‡k "e|¼‚-k‚RÉ'Ž¢8ee9äôlBsÞEe¼`ˆ™©E²\Ìèwª_À÷4VC§3Pqô Ĩo¡¾#ÑF£r¨z,X%Ž@º‚JÑ¡^÷É”¡Ù3¸¾CnÁä ¤ˆÎ9sàæë^ðÜ¿ä_9úÆ÷ž ?ß¾ë¯o¼ÿÑ[ßqÙ¯+'}‡T…8[ø5‡Üzä™@ MF¨b:ý&ªqjršNqò±Iz ŠVSES’–¤ß'Jcܲ$Õ9å `òð “Gæ8ë¬qTžƒAë«2¬N‘YŠt nÙrð±Žt¨×+²Ê‚³„Împ¨•9y´CÒOðp„Äæ–,Éi5SNžh1w:díú_9ÈgWÈuý÷7©¯±Œl28VA(IZy”w5Eéôæ’bI`E)\V)ð]2c•ªGª,KME±äãHhusŒ1ÍÝÛ>òÒ—]ýg×½åK“<ƒ\žaÖÚÚo½ÿª× íX³“'öý3“Ç'¹ø¬=øuc"Â(@¨½8¢VÉ0:!JÚ¨V‰£Žñû{'>øßüì½ì=úƒµ#£†Æ]JãE‚´€Sô s‡Ç8F­æ£TF¦4BH¬”k@å`2<6~bɧÕì£TH¿'‘ÂŃï{䱡›fì¹p#c%î»ã0³§BÂŽbbm™Å嘅¥dz\ö¼1ÎØ]%¨ eK¹ïã.I¦èužÒ8‘À¦Ç`ÃrÒgçÖ!––J,5#J5· Ö‚,HTfðï8ô;šRÑÅqºaFµâS,XXîáùtÎÜ^ùø•×\öÑþâVx†9<Ã.¹ªýÂÇæN¾Yl¾¦ânÚFè$Üvó—iL­pÞYç“,Ji±Î Q4$4¦˜´Äãw|KL0dØsÑ/ºa'ck „Ý„……ÍF—å¹åɶ›1w¤ÃÒl—­ÛÆ(=2¥Q:©6ÃØk5Ò)0¾ÃÂ\Ÿ^7¥6àQ*‚ Ç‘Š’ç`2…+¡½ÜÅŠuƒ%ší„ù唩éŒùfÂøN‡«^µ‰ 4¶’ Aû^ÅC)… hkq¥Å÷$BX¬ÒŽf¸ZàÔd—,ÔžCÑs‰Â) Ž0ÊÒïç>ÒF¸P¬D±á²—VÝXDÅT¦pŒÅdŠpÅàË€c"–æûTª‚B Q1Ä]ƒÉ:Y¤(mÂ2Xõ©W}fs:]ËÆ‰€ªK'ÌðCižwéGNÄ,®¤­K/ÙýÛ¿òž||Ë9/oòcäð zÁ«Ïzïc“jÏÌl&â¬Eì7Ñy‚Ðýå&×\!;Ρ5¿À¡NpÏgŽ`Z=Îߺ[>~;ÖUŒNÔ0:Ç(1šBÁc`¤ˆã;h­IŒ¢ŸdëŽî'9ãëŠ,AÉÇó%ÖZ\,+)øƒÉE¡ñq¤d~.f|´L»R©ú(­H3ƒè03±~kÀ ?¿“î[ÆàráÏÕp|Š]Ld!7d:8¹Gk)bv*"ðÁ“«,®H :ƒƒ p%çg–“Ó)ݾåÒ³‡Ø°¾ÀÁã=¤kIsÍy{J>žØÓ‹Ù‘·½åºw½ûƒwzpbwÊ™Ã3äÛ÷}ñºï¼ûíÛ.~å`³ÕçÄq× |ß!oƒîf|ôaJ…œ ¯æìóÖ12¢ª2" j´f\¹<ãÞû†\{ã<ßø-Çyí?=F9Xæwÿý£ôæGn-(:Šæ’zœhljévMšÕŽÎ<:%×Îü@“ÁZ§ŒB¯«tbÀ“0™—V½NäöIY8·2B#tûpâXÁ™ —¯Ê~ø‡¾ó_|çþå-oqþþ¸ûþ·ýñüo“ù›¿¬{èYÜüÜëøŠW\Ù«PïTtd‘zX±¸”¸xþ+§ÏQm7ìÛ;àU/}!ÿèÏâîO=Jc™[n?‚{ÆÍ( 1ÀhëDo¾¤ªÚ6S§Ä¾ý]._Ø!Õ™2*jN/FBv bXj‘6Ü ­ÒÔÂÚZ͉ûY¹:bu½áÒ•Š3çvX>Ôçÿé5|Õ7¡» XW¸ã¯¶øô빩Ïò‘€™¡¹`¸ZÑNÚIC3NŒ72¡íráü„ÔK ŠŠ¡j(†à,t#“ \ºœ˜NCûJŽê3™µl +úpœ¢€GδÌÏ-¾ëÇÿ‡úÑ×~×/š¿G¿/øÊ¥ï䨮8½ÕÑiºÂžý°w׌­Í‡‘IBg6/nRÌe¶·Ö)fÆhuߌ^7ðê.PÕèc\µ$3ú}á¦]‡ðá½ô5?õÏßô{ú©_zÿ_ 7Ÿœ^_ìþŠŸ¾¸š–Î]9Moa“={k\ [_¡+‘µ ;@1šº¥×m)»FÑÉ$Z&í”­Ͼv7ް̇Þÿ³Qü`MšD(‚ÐT-ÓaW™´ÐÀ|¿ä¡‡¶ÙÞjXœd2£iÅ…ËcN™p~eƸ“._÷º—rieƒÕË3^ñºk9|Ënr¿fRO=˜M+Ö×*R-D_à¾ÆÖúŒÃ×õ‰(ÒÞf¨«3i–i«ŒgÃÚ„âÌuƒ²ÃB§ËåÕ–ók®¿¦Ëþ]Ðë!fV6j&ÓÌÂBàØ‘N»=kw½û_þ_ýÈþøïÝÅ? ÈH;ßôÝ—™ßÿ©ûÞÇlõž6ά3Œ~Îll ± =ê™3·û0=«é0dÏR¢,œõ5gs½âÒÆŒÅAïûž[yÛÛà—G|ùËö3?èqi{JˆÂâB—¹2Ín'fÓ p˳wqêÔ6÷œÜÄE˜VÑ8pbŽã7îcqqŽÃ»¯åßð\þŸÿ0GžµÀü¡W®n°¯+ˆÀÆ¥ŠÉªA*)‰¬\Ýb{}LYDJu¦Û-^(1’k„¶q¡ßbtš R2†UÅ=—GÌõàækKfMMw>0?'<|:±ÐW^tû2³Y⣟ÚúøK¾üÅ¿ù‚Ýôï_÷ÝoŸòLøüù½ؽ2è¯<|y­³ëÚ.=ðVC'vaãmzW¡¿Ðcœº<ôH`ÏþCDíqxÿUêñbQt³id2.(GN3KÄ9¸‘÷¿ÿQΟqÝõ»X^î‚Ò¶‰œ3©5!'cm}ÊhÜÐfBYÚßaÿá9?kq¾¤vÇSä…7ÝÎü_ÅŸüö½¼äë±tDØs¸qJ®êí–”vifLF‰¿yÿ˜~¯Ï-4Nܨœ(B§€¤Ö *­aæâjæØþ’ãKbiÚ[2œV\X©1‡cKNž«›á$üŸ?ýã¯ýõ¯ã|œ§ˆÈ SÎ~e}zcgÈ6ÃÓ'é6ctZ0¼8CÊš^ÎìßÛáÐîE>ðþ“”>OŒ‘ƒ¥0 2í¤¦™ôhêD3Ë´ÒððÚ”ç={/½9õÈë—'ô{dz0ž¶LëŒèö"{ÎqôÄûŽÏà`Ò&fe@:‘Ê¡ì”ô—"÷Üq…€‚&bÙº:$Ä–è‚&…Q¤ÝraíÒˆ¦rö,´Õ”RíÔˆÁW0¡MŽ+t‹‚BÛã†Ô8/¹­Ç¾e˜Õ&Î#§ìY*8¼¿äôÙ†•+öÈ­·ýµ_ûÿð6‘— y ‰|ž>zî÷¿êþ«'_zLJïäÄËö³±ržc×\˹ÙV7ÏrýõÎáAG¦L³óœ»yðáûi,S×Â5áèA%^mLkÆkC’DºeA3ò0pve‡ÑFb{C9{~FÙr.0¿§ÇÂ>‹‡Þ|`qO—=‡çèõJ6¦™œjD”ñöŒræLÇ-RGÞsÿÝl¯OÀ¡Ýi]L<Ôg:4ÆãL§,oõÔ¨§™Õ“9“gÚ 6ŒªM0è Ksn!ŒfÜ2Úi9°/²g_àüjìNöíÔubs%óòëöø+¿þ~âùßù5yYæ)Fø<¸»þØ¿~ýX¹<ýÖ4w ‡¾lžŽ˜gõÁÓœ»÷Ó´£« ê1áȉ}hžQÝpîì©ÙAsCŒå]r Y ’ÐÌ”ébŒ¬¬Ö´æ8¶ÀÂÅ °ïúº{²+„Biê„%CU˜î$ÚÆñ,äFmLISeóÑ–3÷¯Káy¯<@§Ì™NnÂx§æê¥šjšH5L·„¢€œ2ÝRtan.°ÐS …œ (E¨'ÆÜœRv“d¬ï´”¥p``¡ë^MòêG÷þÞOüÆ£ÿ‹H§(áóp×ù_{å$}wè]»ô§wžåÔ™±{@»Êìâ&ëg.ã³1µLص»C3kh'‰2(»—z<úÀƒ¹@j2&-Éœn?°“"õÔæçèõº´ò79Cg9tó2Ë×-ÐY,èÏuXÈ}úýªNÎt<ãü©56®ŒØÙ®HQa6I¤˜Î1ÚÙÆÅXZ0¿(Œv&ÌÏbu•èv•n7²0WRÆÀhT1µ J¥ÓÁˆ"x6¢ er2’;„L?t™M„ѸaïØ¿4&fMïënzö¿úÉ·~ì<ÅE>Gç7ÿSqasí»­wxiÐ9ÆÆ•»xô®“ ^vŒáÊVî¹Àbѧ9š³^5 zŠkš‘qemL7G:Þ¥i²Ü¥¿(p¸?'¥©R #ív¦5gÐôæ"A’`S§T'Œ*f³Š++œ?³ÍÙ“cÚ:Îân˜Ÿ‹Üpû"Ï~î^NèóÉ»àû6Ù\bY8|Øé–-ƒžbæzд f-XdÐs:‚McäEP@°,ÔæÄ² Õ5!Ï»¾ÃpœroÏ¿uü–çÿÜøÿä[…§:ásô¾ß¾Xö—ÖtñEE­>û(wüC\~ôNÎÝ}{–hF»rÓ‰£»„v½Âvͤ`Ü ãÊHK‘ÎRÄ;Î\¿ ß)sý.“†3÷oráÑ!Ë {H¡Ìíš#U-2®™Mjªªa6©ê³ï@—Á ¢±°)ºÕ C¢7äÆO3½¨ìl'¬urc¤Ö©&€;îNv!™ƒÐ´Ž D…2ÀQ„lNjœ-+•`™j–8²W9¶§Ÿ¸õÿëÿÇ?úiù"!||äýß~èßoå#·‡•u:s‡ö^G¯»Å»~é'™n\dynR͵ôήyX qÖ²w!ROœ“%Pw#:ÂRlè—JPÁjg:JL† E ™NŒµõŠ^·’ÎèÏt:ÊÜ\d~>Ðí*9gr›hêLNÆt–( ÅêDjAEð0AP¬r<;1©uŠ 8N­¢ 8$s‚EbPpÌ…Y-Z®½¦ (b}èÐKßô“?û¾_ã‹Hàs°ÿÅK¯=µ³þ½ËÇoÔýгWäÁûî¢ì`na7ÓáE.Ÿ9EP€9õÖˆé• ÚÂlØRÏ2Ö•µ uÊtzÎx»%M2±7Œ·jfÛ “­šRà–ë¸æ@sa±МèDçÀñE–÷ôéw < õ̙٦#¨&ÐÖBn”v*x«´•“RÏ 5’cÙq²Ý˜gLŒ ê–! …RJ£ u“™5‰…¹ÌÞÝ…]ËõmÏ{íOüèÿôÎ_‘Ì™Èç`5´ß5¿çúÝ3*¶6.pîÌÝ4ÕÃáv/•,í9L›"£IMoŽ3`•«W*Š® §n[ÊŽqë³çÈžiî­©'™Ò…Jœ^¯`a>27Ì„D&Õ {ŽD,;UeLÇÎÖN"S3› Õ,aÉI­#EPr2rchB¬uª”!C6à T„( "ˆB B“Œ¶u‚ ‚à.¨B§b!¨:.Ž‹S7™¦Í´É™Ÿ‡ýûAÊ~~î ^óK¯ý†ýEiù"y’¿ç–ûvßxfõ*W¯œáÁ{?Êd<¡­á•³¬™Ý2X\b<\ÃBKܲÐ-™v2ZdŠ~dn)±±]¡â\¤Ëdh¤*pi*d³Vñʨ2ié”0´kM6À˜©±}µFƒ'ˆ ¢¡m@ 0dzкӶFÀ)ƒ A1qpGEpÀLШT­C$ªBˆ€#@kFª&eºaZgRÎQ¸þxIòÌpê^óê—ÿò¾ÿß¾UD2_¤"OR·;m±Ù¹pï§yôäÝöõ<çÖçòá÷þÛõ,õv`Ž;ÄÝYÁ´f6J4³¸ÒT ¬ÄB˜f! &Ó†ØËd3¶ÆHÄšD•…jlh„^O™Ša–1wr6Rk¤ä,-F‚ãQƈ)CP¢ nN,œNáAÉÙ¨Ç TU!Š’RÆMèu#É ±Œ(¸;99!8Ýž"8àìÙ9z¨w*éž~É _ñcoøþ?|¯ˆd¾ˆEž„»Î¿§7O^s»ç»ÜôÚWpìÄí¤®rêÎÓ6Îo²sîÍN¤º°0 ç„J&–Êî.l¯’…4R†žéõ R¨‰]˜Û%Ìdžþng+@Ý ´-4 x+tc$EjÐ&uFÜ1Ü 7Žˆ Îgˆ9*BÊNJ=NŒƒÌ ›“r"(ô:³Q”J+B›" Q…Ô:u•) ¥ßSv-@ÞØø–7ÿðÿÉ{EÄxˆ< Ã:½Âzùš³ÅHÖ¤bi´D¯3 Ê€]7?Ÿç|õ73Þ¹Œ¦1¡Jè¬á¡O<@n+B4êqÅ «ìÞW25‡¦vŒ†nW(KA’³6º@Ñ)Dè‰cg”A3¢B]f Âc\p3Âg$s'ª€‚¨P˜ã€ª€Â¬u\ÀE@…(BƒÐº’à© ±Á²1›:6Í ãÄ2\w“Òvý².½èM?ö¦þŽˆ42 *z{ý]°³Q1ž´t ˆâPR0·Ð§i*f³†íqfÖ8K  ’yœæ†s¥× ¨@cNT¡è¢`î¤ " …(9îPE Xë´Ùèw• ‚ H,;m†¢€NG)EH Ìœ6׸ *Ðé:K Ž ”“›Ò,ŽÿÖ _ü]oï‰džf"‹?yàzu<<²{þ(arˆ­“§±=5ÓÁÓiͬ‰¼ä«¿…åÅëøÃó;œZ½ÌâTÃ-Ú¶ÃÜBA5›aMCÑQT  àdsÊ`IYIæÌÆ-& æŽ Ä ¸C[³ÖÉfÄ à Ü30ŠBxœ%(¤ä$ ì¡²9”"HATpW'"FÑÉh Ô,- ÝEçRevàð±?{ý÷¼ñgŸÿâÿnÌÓPàoñµßÿ¿6ÓâÐ|ï:Žî}k+—9êQ.¾@=M¼êë^ÍîcG™_ÜM;n¸òèi‚nw‘ÁÂ9eêI‹gÇ]3êª%g#D'›QDÊB *¸AjÏPUFUmv!%¨*§IŽˆŸ!`"B‚;Ì*#µŽ¡( JQ*spETÑ ¸ Um¤dˆ$¼¥¾ÒídÆæô÷îú–ïxó¼ò?ô(OSÏâS}ú5Ͻ1— ºÌÂü>;Âê¥Ó¨¯þÚW1ØÕçêê*’f”ÒÐÓ†zk‹ÅAIë%Õ¤¥­ž3–2bÎxTÑ4™ºI4uf:ËTµT™Dý€dA€N©A0‡œÁ A Q>ÃÜAD„¶qšÖA„" 10Qp3AUAQ%gHÉi£Í†bHvªÖ° K»W¾òkþñûíÿõÏœ§±Ègq¥>ÿœ‡¾·+Ŏݸ ŽnÐ_J¼ò;^ÅÎúy®^8Ç}û89§FWìß“èÕÊÙ®2nŒ¦É€SöœdàÉ)BÄÍ¢¸ êÐ N7Ó´NÛ8±PŠ(¸dGp, 1(.FJàæˆ´ÙÁ¡ˆP7†ˆTø 3 @ŒBÕ8ªB'Úd¨±¦u¦©3î`š$”Áéu„n¿ðãGŸõßðÏ~ì/¾÷õÀÓYä³èí ½Þ®y¹|j¢s†ÞžvFz]êÎ=ºÊpk â„TM©6w8º{ç<ë Ûç6¹:ÓÔ-b &Xvpga±`:IXk¨(Z(Ù„i‰¨ƒ˜‘³ƒ‹Aq\ÄABW!¸ˆð8E(£à.dD0A0‡”2ÃQƒ»ƒ’‘Z§ßQî…&ÃòòàŽ—¿äå¿å%‰§¹Èg¡s2úª¯~•<> k«3v¶®’SEÚÙÍá=×sÝÍû³‹l¬m‘ë)ƒ®sáôi­¥[tXZÈQÒÌí)BÉmÍüœ2gfÓ–ÿ‡@“‰<;1;ªBˆAÀ¡MN“D „ ’3©œœœ S(AÀÄi³pB! JJŽ"(J]e²ÁtšQ…¨Bn`~N)\Ø%º Ê ^þâ_}Í·ýÒƒ<(ŸÅ• …µ5GD¼ââ§Ï2<¹J½¾Ê\×8~Í—ö ¾H¶FÛ®^…Sç§œ¹2f:L”Ò¡»D ŒG Mݲ¸+°g¤Ó3ÐŒDCÄq²ANFJFjœ”6;);Ùœºqšuë´ÉQʨt èB*‚¥"!(îP·Nj2Ý*N·pæ»B~i,.Döî›ûó×}Ï[ßÇ3Dä Üuï_/ܵúÑ›}nÓCQ0Ú¼Äö™STe‚q»«“Œ' ƒEaïñŒ‡êñŒr¹Æf#ÆkC°L3™QM uˆ©MLS‹»Ñé nAŒ¨dBI@2ÈŽeçq"ƒ`ÙlÌœ²æúJ ŠeGE0u(:Š"dD ⸠Mcx'(¨8Q„¡i399ýPUÂuOܵ¼tÓÏ‘'°Ñ®ÇI5ÝoëZ7Sz]è† ÓíU¶®ŽX½° ´tí”$‹ÔM&éŒlSŽÜÞc7ÂÉOnPÏQme˜ýn$µ€+)R BÀŒܖœB P¡PAq’9î *QIŽä I@ÅAbà1‚dAh[£m¨B• NÓ.F]*0è³ÆéÍõòñkŸ÷^¸‹gŠÈØ™LûÕDo<°ÍÖêin{á³9zÓσ÷|œõów1Ù9Çxu‹.czu‰¢èÕ))O ÒÒDŠ^‡R»ìÙçÌZGQèI™¶N°Scn`æN›0ÏŽE€"‚ˆó8ÏP à`’ Ä  à"ˆ*É3À¡• Ì¡S ê€;)9;ˆQW˜”ÑY~hï‘ã'y‰<õÑ0n­í,\8·¥£mnzÎM¼ù(sÓs—©Öâž}‚Ów>D/F4;V·ä6![—¦EK]'š Y-”ªNxrh3Ö&NY€%G¢ÒQ¥ 8Qb„ NÎ šó8ˆAÈ"†ªÊà`Ž9¥ .´­‘[§N ÆgXr‚:„º7|®§íÒr?---¬Þýñwoó y›W¹rqÍVÏ­ûd2“Ó'Ï2L¿Ï••K, bbïÞe†{çml‘<ãE&%!ƂյšnHhr2r†l MJx›uBTD„²PÊ(äìDÁÉÙ±Ö1w"ˆ⨂!€¸#"8NP@ w§MƬ7ˆ *‚c˜ƒ8„½R˜Ìü1x·§m·Çssý‘¥¼SôN,¿õç:W~øÇþ:ó yáÜÚ•¼±1äºÛnæàuǹ|é0Ûak£áÊö ‘WíÜõ×sï'/áÙiÁšD!1ƒg§× d v¢S¦iŒ”œ<3æç~7`9fŽâø,¿öæ[¥·`<ô‰?g²y• ÍŒRJFÃD§Œì^ìS7†#”(rËx»f\µäÆQê©c­1sÇÌIîh€²Tvu…(BÛdÚäˆ;AÀÜ@P'·Ž›EÁ…Ç9áq‚µMÀ…ÔB6§®ND !›“²Ì*§ß/£æY+u§§CK¶CX¯§;ÇËή]Àež"O@*‘Å¥]ñ9¯x™PôØÚ:Kh ¶/lÊ ÏRI³«çkRŠ`l53Ìtê ˆJ;iÙ»Üe6N´*˜€¨â%H\œ>Ž$1h$sç("„(¸ Á#sÁ38P'£©¢ê6“²³Ø/Pki“Ñš#â¨â ˆâ‹sjªâM’YÐ0q—t¬6SÝøòò[Ïž|÷Úñ¿)ñ4ysnseãêÚæÊ•ã›“™l/põiVOsñœ[†—+Æ ™ÔFê‰P× Ã db€HÀ²‘§ÂxX3ß/h$Ó$ÈæXw@ÁÌ(àŽ9Ñ)Th³£€æNÓ8ª`Á3gVE Âü¢¢*”ɨ§Î‰•iãîE)A’ YcȳÊë‹a,Ëäq˜5²­d3¥¦¸ãcŸ\þí·ßÚw¼þ×§±È8¸x`|fý܃ÃÍl¬mpõêinXj8pp‰Õ•«Lw*¦Sg²3ų5¢! @j rÈ– f¨ !*–ªÎ„(ˆ;žwA Ä!™Ó6< ur'„R@UP\œlTˆA1‡œŒÇµÙ¨§Ždƒ¦1ÜPˆ«HÖ(M§ëìÞÖ­7e§3îõÊâ¶„x)VÜåbJ¶ž›ÔLÆÃ¥¢(§N½orôú¯1ž¦"OàE·½t|Çýý7›gÏýÆÖæîõµKôv®âõ”^w@îze&§–jV‘ÚLSըʢ@)wAÌÈnN#NHÂã:¥Ò:´Éi’¨B`ÙÉÙÁ… à8‚B2ÇE(T0`45<ƒpsppËÍÉ"B,‚•…V¢R#Ҹǩ(UYƶۉ[ +Ë«±ç’ÉÙd~)ÕÕ¨šN·SS%Õ2èßàé,ò¤ÿ×oû…átój{Ëm7°~é!øä9ÔÕ$‘kÈ)ó¸ JöŒ:„l´MES;*n˜9ˆN©É€ºJ ˆ â¸ " *8.˜ Y2XrðW%çLJŠ ¨(m2<;)»[vºeðØ75 uY׆@“ÊPÌŠÆ knçBÃYNáz±iò´®ëÍõ³\ñ ù,nºþ–S|ð½[>µÿþ}6¹4ðéÎVhS¦Í-m“ bZ'Õ`’)£àÑhjœ¢в@$£Z#µNÎŽ‚£Ò´†9”QQs'ˆ" ˆ î ÅfU‹»SŠu›0ƒ"ˆw£¸ŠšjÈ´!úÌÑ© CU3AÇÝN÷й¬ªÆ ¢ú0&«E§ØXÞÝ™þ쿽Óy‰|¯|ù×|ú³|êÓ÷Þ8ª‡y¾¿Ë{!0žmÉlÚ bRí´®)bÌ3¨Ñë:‘Mr “ÌÜ Ä D7°UA” x6TÊBA3ÚÖÉ´Y£ *¢ *x7UËÙ ÇÊ"¶*:“ •«ÎTu’³M©&!Ä«ªaC +e·sNE.Šúån?¬ý»wÞ›yŠ|"Òþùÿè«õGÿñöά·’g†ºtâ@&™+›0ëÏ´ªµÔ».mm-H¨µÉ0c‚€‰â‘DŠTÀ ¬Æb@Dœlx † "(êuM18¦!Ç"$-qÕl^Y–ÒÌs(¤.¢ÖAuRFº*ƒ:Dß1c¤.Ç®"ºê.‘ÙXZì¯ÿê;>a7¬×ÿl0«ž­ÍyZtŠÜ×A:ÚS‰!çlf¹o–­ß)[K„ uSUœÛPW³Ð6 9%TB­A1-ËBBÐ 7mÛºŒ!l¹Sš[¯Ü©CЦ@RР É !VC•³ål®–½qghf*Ʊ(†‚OEt£Lb,¦f>+‹0{ëo|pÆ—üŸƒ;ïúÓ¥³§îxåÎdgÿx<)µýé´oëx¦ MÎ)ÔmÕ%<¥ÔjnuÏ–ÚÄd2¹m$„0²¸wT£”E$©ý11`¨f˹ÕÊÝêÜ´9›‰†0'¸hPÑV‚ÎTãÌ¡™¥”£9uN–C CAg¢2 *)ÄT´î÷ÊÙ[ÞúÇ™/ùÿ%|Ž>~ÇŸ\yå¾C£Ñ¸7šŽ»MUÏ7­u„ØAB›S+mÛ9¥P”ÝYÀ­©f1U³©ÖU¥³Ù¸ÓÔµƒÕE 5†XB$’ŠÖ‚aN¢Vf9·MãuU—æÖª#¢Šˆ˜åXµ˜™Yp <™Q‰Òµ¸[vÏŠXQÆög~å½5¾õ[=|p×37˜»áÒÊÕÿèïÜòE@ø<|ô#ï:¼¹yqa{¸Y6MÕ«ë6¶wP›#9'͹QquÕ I)·Ò4µ¶õˆÉx*©­Å,‹Š¶A5« EQj ê@ˆA“¨$°ÆÌR]×Ò6UpsswTµVfN*ÊÎÄTÔ ÉîfmJ9w:¥Og•ÏÏõü'~îÝ™ÿòä{¾÷ÀW?û–›¿ïúknýÚ×(þæÎOÎNžzø¯î{ðìvÒ»>øÁ­žÂ„ÏÕ•OÆGNÞ·°¹µÑ™Í¦eÛÖ>™ÖÑMRJ&îÙ›&EpW‹¡pq·”jÜRÞÙÙqKMvËžR"¨A4Eðb A“YV,DµºªÛÔ69§ì"°0?˜ G3ïw fµån¯ƒ¢Þï—¾½3“Ÿüù?0þž}Çwv—®=²üºnxé›o½ñ¶CÝrÇ 25÷=x²º÷Áû>vÏý§ïû7ëìY¦< Ÿ§;ïxW±±¹¦ãɈ²P^û?Ró öú7ì>¾¼ëØ›_üÂç|óÍ×ß¶ÐÎ2Ù '“Ýéu;ôº}êv‡ºóþäÃoúÝß¹ô§ÀyÀy ‰|ž^ð’Òò%Ÿñ/ÿåþk¢ùé>ï…ß~ûÍ·JÛ6]§ÔHN8ªŠY¢ÛíSµ”>0|>0ÆÀO!‘/ùBI§»û{_ôœ—|Ûso»U&Ó `¸ƒ¸N@¯×çÒ•3|è#5z÷¼çò=÷LŽ{x Š|ÉäèàŸÿÜ/ûî/»íÖ0žNÉ9‚CÀ€ B§ìòð£'ùý÷|hýßsÿÙõµ4 pž‚"_òyûŸßò¬—^wô¹oyÉ—½ú@UU˜î06 æûÄ !ð¡;>’þÓû>võ/?²²²¾–ÆÀð°ÎSPàK>o×\SÞ°¼¼ë¥B½»?7û½¸S¢ÛéÒ¦-ÞûþTo{Ç.üå‡VÏÇVç;»‹<žäóv÷Ý£éG?vª¸óÓ\_[)Æ“‘ÆØÊÂÂ.ÝÞÙæïy߯ÛëcgzprÕœ8Ü|øppžb„ÿ²„Çü³×SÌ͸fÏÞ7GT°œí§Þ²r0þnÿ/ço'ßÿÏ÷.·­,9†"Ê`w~é7Öço·øfàe½‡ûý¢ÝõÝù¯?Ôošlñ—g·®®¦0î¶øÜ ¯Ãk÷ì)dqÉÏÆû¾¼[tÊîœ2ß+QuêfÊhxþìÊÕÙ£fëïX¿Ê“$üù¾ï'Üy'òO^ó·çA~Ÿ÷aßßÏó|¿ßß¹¿½o\»À.@¤xX2)Z¶+ë´,[LuYN2Ö¤©ìÌô¤Ó&ÓÖi“Iâ´Æ;v-+¶*ë6u/ðÄ}íìb{_¿ó{=ϧ€ÈÒI€²'ο×k`Gì³{ö´Q¯Ôn¬ôÞÞÕô+Úï)dÚ=­ µàÔòz-Zyáâù‰çòJ¿ôÏ~oâ?M=øfxùO„åºÄKRHRØ¿£mÄfÛ3ÝÝig{©ç}{‡ÚÆ&/_øÿÏñ?¹p^óÞ÷âÕ°{÷`K¾`yïèÞ;ƒ€ýß±SIÄZlÙÕ‰Ù¹¹g¯\]xê?ÿÙâÓ€ã­uÍÀ0 ´ÀTO_Ù»§íÊ™Óë'W’#ÀÀrï}ï¶Ûðjµ-;)ç¼üÖ­m÷ mÙ´Ó×ÅrA±¥$žK³}_@¡ÑZ¡µB¡èèjcay:½¶²¼²:sâñ'OþwßüæÂ rCŸý,fpÓàHk±ûCï:¸eO6—¹»µØßÕÚé×…$,æÚÚŠä29Â(BEš‚1#›Â(ÞÛ^ºðÈÔ•ÉËŸùTøG.­ÿGŽÔx•úácŸwçÎ\ü#¥–.ýð±þ×ùäï;[hïîÌß·w‹ý¥B mm-]]í}œ:ñ½—ffŽŸ+YýÕµ×ZÛÚ7uu™ÁRvà~?S(iì¦î®ÁC»vÜVò=2bSDÀ$Ý4¿´ôî3ÏÆó^üÃ?ý“ùÿ,ÂkDñN>¡E¤úÿaé¥ï¿|ucÃΚèÍìc:7oñ÷Œnؽsô¶ž>{ß³Ÿú7pyðË[øùÉîØ¶ù==½¹‡ú{‡GZK÷´äÛ‚FÑÙUìØ2¸Mg4’$Æ:A‰ àpN¨U#l’0Ð=ì oÙÕ÷Ä3ß=1~8BÞ†ÇßÀ¿ûý;”jùÄ@÷îGúFºZ·ã MRRëm…J¥N’¤8çP ’Ä(‚ŒÇðæýÅm›víëh=õ/“ô¹ûÏŸ¯ýOLnüü+ŸßµçÀ¿ßÔû Z]­ÖZ[ÛÝyßÂ8â×>þQ0F”MãüÚš¹£XÜäµ–<• Ú Ù …©kÇWXí~xã'<ôÙ»ûîÛ½søÃ…`óÇG‡·ôtw *'P­4㘶R­¡Z«“$­A)…ÖšD(Á9K­’ÍüàéÈÿâðú…ó·óÀq äm~Fÿößm{Wwûî;²íÎOlßß“ñŠÚJJš¦ÄQ‚ "£k'ø¾AP8q Ap©ÅxC[·ûJÅ[fæ¦ÌÕ«ñ0?9½¨•Äw´wtmjÍ÷ùB)°‰B\Šˆ#Šc¢8Æ9 8nXX;WÚ<¸ããxßÞÁRKGÆ¥&hÔc -YJ-Yâ$¥Fˆ8´1 ãi\ªHÅ’X‹ôu䜳;WfÃùùdXýÊWÐÝ}ùöunÿôèÐý{ò™™ wg1³i´Û4ÔÛµ)ÛÑÖø:8ç¨×&§¦Ü×=-å²-§UÞàSŸnÙ~çÁýÿl÷Ž;þÅ¡ýw?¸©g[ÑYOÕj!«+kx¾¦££DKKž8N‰‡g ¢Àh \*ˆ…ïûdƒ Ï{Q¾øçOμðÂÂL£€1à,ó6 ?ƒõ¯·ÜÛ^Úû{#Ãêíڬð§/0Xç0žGøD6Fé”ï”òIm‚ñ ž6`qXçPâØ¼¥'cmmóøäÂÌÆF:»´dÃñËË}•¥­--äF¶oÒIâPZ µëR´Òˆ€M½]Ýú¶]û<ßd(—«`À9K¾%GoO;Fl JR ä2 @"VPAàÓÑÞš¿|9{áÂú”«@åòäj­/ìkïÔƒý}ZlLêb”8g-"ç6Æ/ÏÚÇ~xv: å0¬òšO¶ç×ßó®ûþ׃ûüÚÞÑÛ‹"†j¥J”$ds>¾ç³ys?ëåUÎ]7ªkÒÚÚ¢[ŠE|Ïà{ijç@+MkK /?&öå'g^<²<†’cÀ80ļ Ã;ôþ_£ÛKÅ]¿¿køŽ;Û{HÓk-Z)´2øžÃòâÑçÒo}ûkßxôÅå³/6ÖÊ‹ÆxÎkoíU¥Rç6I¹Áh…(E.S¤PÌ´,.]ñΞ-O+õš+]¾¼š..Íäúú‚–¡mÛ½ÔY’$ÅZ­1Z£•ÆÚ±>Q#&Š"2ù€|.‹­­Ì-^ã™Eëë+ÒÝU2ù\ IJƒs‡³ 8Œ1  µÔÁü•â™ós³õº›æëuiŸØèÍÑðŽíƒÅö¶6¬X’Ä¢kÖ:D "piòjúÌáKSq,?Nu®û䧺éÐûþͽ‡8ØRèP•r•rµ†1¥R|.Gd«ùÑ áÿâ±¥/þù3S‡Ÿ;¹¶°pÍ4º¥%çµ–òx:ƒs‚³Ž\6ÃøÔyùÓ?l橧禢Hàp8\„·axþ÷ÿƒLÔøÝ½»}b°w‹Ž“k"(°Ñ˜åñ'ž®üÉ—žž~êÉÅ©sÊ+§N-¯{yze~iÊ–Z‚ÒÎ#j£\Ã!xFãƒÃ‘Ä–Þ®U­/•Ξ¿:[.»  œ$¤W¯†i½±Ú=<ÔÑÚÙÖ«¢$Bi…A#b‰Â˜F-ÂY‡ŸÑd²Ùl€§ ÙLŽ+×.¹ÿü—O¬üáž|öų+kë×(dý–Í[TÇ‚1nD„l°V]õ^82¶¸±a/WRš’Y]+çÚÛ3[÷íÝé'q âPJ‚ÖàiÍÅËÉsÏ]cN'äÃîÞüà{öüóCï½ñTy­‚ÖÍd³¥¶׿ù«ÇžÚøƒ?zfòùç—fWWmcq1Y9svaåØËcå³/5––®Jó²½½*—-Fe¾ñèÓ«ùÕ “aH œN'€Ó@ÂMÞ»íøÐm;îùç»Fn/†qD’$ˆFk‚ ƒ“„ïýà‡ë¿ÿ¿06v)ZMR‰€9`* eíêt=l„KÁèhwiSß&…8¢("à?år§ÏMÔ¯N7.GêKËJ[»¾cÿž‚8®Sh-Da‚M,…bŽ|!ƒï{DaJdó=qÄþñ—þΣ“Ók«®¶¾fWÎ_^_^[¶ [ú7)‡C)‡µ‚Ök-Zk|? IÄ=ýìË+KKÉ0 \¤Zµu?nß5:ÐÛÙÞ¥¬µh " ÁF1ÖÅœ>ÿ£µÃÏÎÍ8ÇYàÜ?ü‡™¡¡¡ÿ펽?Qð»”ÒŽ|. [È¢€$*Õ2_{ô‡_ùêÑ+W.'k@ ˜NZËL¥âÜäDµvü•kµó—.ÖÂhÝïîl N9þñ_YXH+À9àp8 DÜ[ôÉO äöìÜþȾ={;ã$ÆÙ¥4ÆSÆ'<æéð«ßxy~~.©+ÀE` ¸ ´Å1G­Ì?ûÂ>424Ò‘ZA¬u(¥PZpÖÑÙ6 /ÓlÎÇ¥jņgÎO\ZYèêêìSQbSÔ|. ›õˆãgQŠB¾À‰3Gí—¾üÃé'~¸xÕ9àp¶Ñýü ׿o¿íôûvï¾­ÓYÁ9Á:‡V ç7$iBW»o6äûÏ«•$Àk)ž=³ôÔ…K¶oß¶£è<±B"1Î .… —¡\NêiJÊk´ñîÙ²ëã›zwªÕÕ5Z;ò8+¤IŠu ´ã;ý°üµ¯›šžN×€Eà0Ì9`è«Õ¤ïØÑrßÔ•Gž{n¬e½Úññp ˜N'€S@Ì-ò¸EÛwø÷÷nyïç©Ö*(¥ð}ƒÒ c c—Ϲ¯|ý¹ÙãÇkóÀp.S@ؾ¾n«/Ÿœ¹í¿yxãîÖÖ<àc­Å J)âP†"Ð h Æ­¥tårù¥+W§îìë̆N°V@„L`¨7Ä9œ… “cjö*ßxôÅ…'~¸xÕ9bà4p’FCÖ—Wâý.UÎ9DDÀ(2AJ!WÌ©ööB^ë%ß9º% .U*É+/M^{øçk£ Cœ$4ê1¢A9PÊG)×­={ ùÛv<²ÿ޶jµ†6 —:¢0EdøÑÉWÜ·}e~z:YÀIà$p ðÐ ôË‹Éå'çFn \Ƴ@Ì;àq ~çw¶e;K[s {{W†ˆ€@œà”âÂøÕÚËÇW0œß´)súÀÁB("¥înam-{é¥z›Öv­V«x†\.@)@)”Òˆsˆ€Q¢Ã븰´T?<}má£ï:è¶yF”m .ŒÐž"— ²šg=²þÔSWæœ#N'€À8 Z“´vd—­³Üàyç,bA (Q¤©¥\)ËêJ%tŽn ×-llÈ™……øl¹‘À7ʉ`¥Ë NøQܰ,¼³poGëö2,–×ÈøpbÉúYœÔyéèÉ…³gë À2p8 œ®ñªX–ËÀe`XÚ€¸\¼C·ÀâÑöÖÞ» ù66*eP€8Äiœsàâ(õî¿¿¯§¯¯¥><”ën½W)>¾¾RºÝ¨{9»P- Àp 8 X^³u«íèìÛj­&‰#¼¬Áó<Ä ¹\ŽÙk3®^‹P„¿®‘ñ½²µ–z-$ŽJ¥©Œ(’ØðcÆxº·¯og{[7Õj™l.ƒñ<âÔb­ˆãÌÙ™ÆÜ|\&KÀp›[Öø[àq ²¹¶M]훣c¾¯ #K%(¥ð”O!—A‰Ržg”Öc .14\ˆµ)7cP€~àRÄqJš¦cÀ3¬­ÎJ¥Z³¼‰‘QÖ2ù¾O$X›bŒ!SßóI’“ç.•—Ó 0œÆËëÔÐÖ oÝÖé$ ç‘(‹g< c NRÎ^˜ØXXHÖ€E`ƒ¿.Ê弪s—j‚¬(+ˆVˆR8^uð`i×–®Û|_¡F E’¦ãQ78{q|½R±`¸Lò_˜æ ôû™BÑSˆÐhDT«"‚ï2¹€ŒçxÚÓXq(%ˆs€ày …œQxž‡ïg(äóä²9 …<—ÁZPÊçÚb¹~y²VæMô÷cÅ) ‡pƒBÏxdrY¦çæìÉS3ë"Ô€y`Xá >ñHñ‘£ïßÜ7ˆ1 µÆ9ZãÄáyšL&ËÉ3gÜKG/o8GDÀ ¼ÓÎE G&Ïø8 Z+”‚4IѼJ{Jwunöëã)D6šÀ÷Y]­¦çÏ/mˆ°ÌÓ@Êa7ñ¿üÎh·Jý}h‡Vš$I‰cGoO Q Pˆm RˆRg ‚/ðPÎaŒ‡R çÀJ™8ŠÝârƒ4‰±bÉøY::|](t‘Ï)Ê•¥F‘1oB…Ö‚Q |´Ö qŒOÄ3W` ˜–yƒÏý½}ÛF·ÿ#C{¶V!qœ‚6µˆR­Cjc^9}®rþüÆ"°,ŽŸdAÈç’(A‰Ã‰ÂF–Ô ™Œæ†¾Þ€L ´8‡o<”R‡Ò´¦R(—S ,óÀ*žQÜ ”FkÖÎoo7rï½ÅÝ>¸ûÝ¥®7 ŒìÞ¾u‡^ߨ…!hˆâÁ¥ŽB>ÃzeãÏžÿôËO^9õru9JH€I` ˜ê¼ A@ ZkpÏ3„aB‡t´·SÈ JãOMDmåZD.§im-Éù(çÀ3†\6‡QŠ¿ Ÿüd÷}û÷ïüÜþ]‡þÞÅ k+ŸÿÇÏLÓÀe æmxÜ„¤ž 66œDƒ °€u­! #ªÕŒ¯Ø1Rèzáˆn"w˜àÖ8^óÈ#Ì÷ômþÔ¡}÷ýƒûîy ÿ‰gŸû«ÇÆø+ Âu"ÐÚ‘¥¥Ãaˆ“”$uˆ”²´µgõ¯ÿÚîM½ÝmÛ†vºKA&K%4êuÒ4Bá')zL©˜¡X(peöùíÃKO¾<y2\b` 8œ&y‚Bƒˆ~ iTcÊå*.õA蘙 [•Òtw•¨… ’ÄbE¬ hkÍšÍÛò¥é™†vÅÏàóŸ'¨‡ƒ¿xûîÝÿ÷ßóÀæþ^þãS/UŽ_ûEàeàó6xϵù÷è÷_Z¹:Ó¼A’@±(……8áë, h-vñÑ_þxK-Zû¤6"Kb­ Æ3d=ƒV?còKëóéáç.¬_ž”  œÆ€1à$Ðà­× ?æœÃhƒñ4IœàœE6 jmã*ÊÅ6àç°Öb¦·³Wíß7Ôqìèj& ¥X„[ô¡÷ækuÿwï=ô®tß]û{ÛJ}?óBôïJêuÙœçxÜ‚å…$Â)ß'Œc‚ÀC{Î9”R„qÌöáÁÂÁ;»îúþc O å&~ï }•lá7vŽ~lsÿè{¶nÝ¥”Sœó©Jß7¾uléÌéê+q,§€“À ámˆ"‚‡Ãá£Ê€g4^ÆC¡YZJç®L/ÍÝ{7C8ÐZaŒF)Å ÊîºcGééÃg9Ýx ¸¤Üœúä§:Ž ýöèÖ‘_¿ëÀ=¹$µ8b^>>–ÎΆu`hp ýÌì×Ýe å&r¾Á(¥XЀRŠ\6‹Cã ߇JÅÕ/LLM–+sÛ‚ M‰K±Ö¡4¤ÎáÒ„CûïÞ÷ð¥ýSS'wTÊö0Å[S¿õ[]#Ý=ÝìÙý«##{övw R+Wðý€©™+òÄ3××Ó `X"nÂãæ“õΜ_ëëîò”A…ÒÏhÒTˆ¢ˆ8ÊòÀ=; ê¿}áØ 6Ü—¾ûÝõ ¼Á?ý§ƒý~ w·ú>ÞݽíC[·öõvmÖa£µ1…b W®Œ§/¼ty±Ñp«À$0”yÍêåJŸlIµ§ +ƒbr|FþðKß^»ÿž;ƒûîÞ_ܺy¤ÁâiÖ ­5N Šb’ÔR-7PFã‡~î=~©%óÑþ¾£Ï>?ñ§/¿þð6ZKŒ6£HSpJ£d}C&£)—½p~íôé3Óïy×ÝÝ^£ž`­C)…S@K±È{ß}Ç–$Ž~ëégÇü4‰ÿßóç)ó~ós{ ¹ŽïÙ½óƒ;¶îØ7´u‡çDˆuœ8´†ã¯œk\[_¡,@ÌMxÜ‚#GªWwí:wáÀÞý ô Rë8'£©×jX爓ˆbv€‡ßÓ=¼w÷èïLÏN}øÎ;fŸkiÉ_ËfuÅ.ÓÑÞ~çÖ=½]-¹^F ª•2Jk´§‰mƒÃGN­MŒ7Ö5`˜„×\«Å[×9 µF{ë,6µh­ñ2¥¶N¹t)š9}êpüìóg:ï¿W÷ÏÝs¨¸kt'QF17¸ÔR¯Gd2aœ`ŒB|!NBì½Ë´;ìëyeK±å¥öã?ª}¥VcŽ·+Ø6‡ÅZÁF+´Ñ8qxž¡­CS,joi .]Z?rô•¿rû¾áFç{võÈ™³göoØÔˆ# SjÕΞ …,q˜P)Ç ôäG†÷Ü63»¼'—óÉç3€Â÷”‚ I‘¤!ˆ¥VOÈç²™€ks3¼rrz=Šh“ÀPç ´ÎeJÅMJ+.u8§ð<@Ïä3¾\Ž....åÏž[Û|ìØx÷Ãíë¼ç®;Š›¶’& «k«(£éênÅYGµZ§¼^Cë m­ÝêCïhGwWÇÿÜÓùâ¡§/þ‹åådÞàôvæ²]wµ Ê hÀ9ÐÒT€”öÖ®lOoKÇåË+¬¯ËØ“OŸ{~ttëà/¼û¡œï"ÍuJamJ’8ÚJêý¿´­ýž»ö½qyáþËWç*¨ÕùlÐÛ“Ï´m½óŽ]*ë¨T«¬®–Éd²YF-¤­TbfaÚ8=·a-ëÀ0”¹†[c¯]‹üÔ- t÷{[¶yi å27tt”P€ÒŠ8N©UkÔª!JP¾ç)cŒò=£ªÕçRD,8ÁZG£–Íùdsy^8þRøÍož¹Z­ºIàð °Ê¼ûÞ–íC[G~£/ÕZ —:”V€FœP©Vä©çO,.ÌGOµš[Ÿ˜¨ÖO¹’–ËË:—“lWG¯®UcZÛ ø‡Rh4ÂFL§Ø$Á÷òìÛ½'×Ñìjm‹oGÕÜìLr°¼f`€öƒûüöÐÖá.çRÄZJ+<Ï xòé+SÓå3À¹ååT×ÕáRÉëÙ¶][g £ëq‚gS/«û7åF‡v´nØ>ØÕ>ØVÌ·¨|1G’$ „$q41q˜"VÈçr<ôåúw¾{îjÊ$ð2p¹·¦ L?þøÚPwÈ#nÏ®‡²ibèì(¡”&ŠbRkÉf<²9ƒÂó5µjL¥RÅ÷=â8Å9®sˆ(D£5ZyTªkœ;=Y^^NëÀ<0Ìó‡ x¾a}¥B¶à“Ëù8}ç_üùì¿Ù½»eï@ë€s)Ö:У@¡IR‹³߃®.Uzß9ÆŸnå›È“9Ïø;zàxqcÓ”4u$©Ek…ˆC‡!.uT*u*ÕîÞ´hçpVÑV*¢Ú Æ(|?`cc•ߨV]Xæ2·ÈãÖ0 Œ=þØÚ÷¢ðú}/nÛ³k{Ëöï2a=A+KÆóðƒR”#I™œ&“Í… ÅbŽ ðÐZ#ÕjH.Íd¹rm:9vbz1M¥ ,s@ÌOØÖ_¢££@æhm͢Ѥ֡µFkEKv3ÝÃyc®úiŠž®›Ã‘£GË‹ccÏì¼ï¾³›>òÁÁ{îØïç³y¬µ €Ô9œƒÖÖq˜pÃî£ØûÖþnóÑٙƉÇWçóùí[ó"?£1\'¥ ¾sh­è,vªÛ÷´~ÿ±ÙÖzÝ€±8v݇/þ`uíéâò̦{´y`›ò ˆhlšŠTâ,õ0%ŒÝÝ”Zk«óve%‘0NÑZˆÒ R»ˆ§ 3WËé‰W®.§)ëÀ°8n‘Ç­[ÎÞ3Ϭsòäsw8xfÛí»Ïµär=½žßÕÞÒ’Ïv£•G-Zuç/^+//Ç.Èx´µäó8A¸Î ±sÆ`”fnq=œlT%`XäM,•iœ½T ÆWªÕÅÅ$ÙXO( mí½½mÅjmÕÝ@pX¦5`umÍ-÷»‹;Ç'¾Y}ïÏŸîºãÀmíý=Ý*“ó4µh@D¨‡Ž8Ž™™Ž&&×j'&–^Ý,Wî:ØxÁ2³sËqy#%J-J)ŒA+Ek{žLF¥Ù¬)Ôë®8 \²–üÉÕtvæð={o;Û{çÁím{në+¶å{qN£¦­13{µzåJ%®U,™|†0Zciaµ<»Õ¢º`#u \ŠQÎ:7}-ª‹À°È; xg°8ìF”¢Kk<ÏC÷weshÅ "ÂÕ¹°&ŽÓ𛲖x8 <¤ü„ÁAú[‹¥ÿ¾\‰ni%´iгŒáÇZÛ¼¬VŠååäðgÀS€ãU`6£ž§nëîÚZ[ ¹Œ‡há¤VQ)ÇD‘ГtcÝE"°|øöç~càa§ý/¼|zµce=IÒÔ¡x•”§Éf äâXí ð—À_)°¸Ø¡»¾öN?§”Fki år†¡³¼¤€ðæ"àðpH¹EïŒã¼ª\aØZ:­E]™ 3@' x•–k-·"æË@Ê›˜%™¥< ,°DÖòc«+)×u1?-.³Àv`#Memn.Ú<7G? y{5`Xª\÷Ÿ¾|í px7Â[Kx] œ*À’+Q–ùù¤èä§­ ^'À2°Ì›KkÀ4òxülÆkÀà  Ð ´ó:V€% åÖ„À*oM€kÀã¼jXB@m@+¯jðÓ¨§€5` Ø´ss°¬‹@ƒWm¯K@…·&À¯³À°Ìý@/Pâ§•E Áë° ¬òæ,°Ê;¤ø›Q¼Î%ÞÜ: Ü:á­i ¿® X^ÕÂë¨ðö< Ä­‹¯  À2òÖ°ÎOS€´ðÖª@ÂOþ)šþ6(^'455555555555555555555555555555555555555555555555555555555555555555555555555555555555555ýWàÿ@£7>M2lÐIEND®B`‚eric-6.0.8/eric/pixmaps/eric_1.ico0000644000175000017500000027054212307344046016001 0ustar piotrpiotr…áLq(…ÂÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþþþþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþþþþþþþûûûííííííííííííííííííýýýþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýííííííííííííûûûþþþþþþñññññññññòòòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûíííííííííííííííííííííííííííííííííóóóþþþþþþÿÿÿìììÑÑÑÐÐÐÑÑÑåååíííííííííííííííííííííïïïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþúúúíííííííííííííííííííííùùùþþþþþþþþþþþþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõõ×××ÃÃÃÁÁÁººº¥¥¥”””””””””•••¨¨¨½½½ÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÉÉÉóóóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìì쬬¬••••••¤¤¤¹¹¹ÁÁÁÀÀÀ°°°¡¡¡¡¡¡ÅÅÅýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýàààÃÃÃ¥¥¥”””””””””””””””””””””””””””›››±±±ÂÂÂØØØþþþÝÝÝŽŽŽrrr‡‡‡”””””””””””””””””””””•••¹¹¹÷÷÷ÿÿÿÿÿÿÿÿÿïïïÒÒÒ¹¹¹¢¢¢”””””””””””””””¢¢¢¸¸¸ÁÁÁÁÁÁÁÁÁÃÃÃ×××ééééééééééééééééééìììþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÛÛ¶¶¶™™™wwwdddccc\\\IIIHHHHHHKKK```ccccccccccccccccccccccccccccccjjjšššáááÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëëë’’’OOOIII\\\ccccccccccccQQQeee¼¼¼ýýýÿÿÿÿÿÿÿÿÿþþþòòòÏÏϤ¤¤€€€cccJJJHHHHHHHHHHHHHHHHHHHHHHHHSSScccxxx³³³õõõÝÝÝ~~~AAAGGGHHHHHHHHHHHHHHHHHHHHHZZZªªª÷÷÷ÿÿÿüüüÜÜܶ¶¶rrr[[[HHHHHHHHHHHHHHHZZZcccccccccdddxxxŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒªªªãããÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÛÛÛ«««|||VVVBCC>AA>CC:IN;KN;KN:JM>AA>??>??>AA>AA>AA>AA>AA>AA>AA>AA>AAGGG‚‚‚ÀÀÀûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæéé~‹@MO=BB>AA>??>AA>AA:EE;GG___¼¼¼ýýýÿÿÿÿÿÿøøø×××±±±•••oooEHG:HH?????SSS§§§õõõ¹ÌÏY„Š:TU:KJ9HG9HH9HG9HI:KJRTUUUªªª÷÷÷ûûûÏÏÏ¡¡¡}}}TVV=AB8GG9HH9II9JI9FF>CC>??>??>??>@@???DDDEEEEEEEEEEEEEEEEEELLL„„„ÅÅÅûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÚÚÚªªª{{{GPP6]\Ky|N€„O“•R¤e¥¬j¦®Y ¤J„GpsKwyP†ˆUUŽUŽTŒRŠŠUWŽ’K}~sw>AAwww¾¾¾ùùùÿÿÿÿÿÿÿÿÿÿÿÿÄßÞw¶»€·Ã…ÂËŠËÔ‰ÊÒŒËÖŽÌ×€ÊÒ:kk…††ÑÑѱ±±ŽŽŽnnnMRR1SSJ‚…j­²œÝä‘ÑÙŠÈЇÆÏˆÇЈÈÑŠÊÔ‰Éӻł¾ÉÉÔo®·^š›~¢¡èèèþþþÿÿÿ¿××l³·ÏØ‹ÊÓŠÉÒŠÊÒŒÊÓ‰ÆÎŒÊÓ…ÆÎ6eezzzÕÕÕ¿¿¿€ƒƒ:^]_œ Öá‘ÎÙ‹ÊÓ‡ÆÐ…ẪÂʈÈщÇÐÏØËÖƒ¾É{²¼ÉÑ”ÓÜÏ׎ÌÕÍØ’ÏÙ“ÒÜ™×á‡ÈÒ=hg@CC|||ÅÅÅýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòòò®®®Pwv\¨ª“ÔÝÍÖ»Ä|¶¿ÐØÑÙÏ׃¿È}¸Â¹Ä~·Ã„ÀËŠÈÒÍØ…Â̈ÆÐ‡ÇшÇÒ…ÄÎ~µÁˆÆÐ–ÓÝT•˜8GG___ŸŸŸáááÿÿÿÿÿÿÿÿÿÿÿÿÁÖ×t°·ÊӾƽȄÁʇÄÍŠÇÒt²º;VU………ŽŽŽqqqQQQ6FF=kma£¨ËÕ·ÁŠÇÏÒÙÑÙ‰ÈÑ~·Á}¸Â|¶À}·ÃŠÆÑ™×ãc«¯c“”¦¶¶ùùùÿÿÿÿÿÿÿÿÿåëëp¦©”ÑÚÍÖˆÇÒ‡ÆÏ‰ÆÑ‰ÈÐŽÍÕ…ÂÉB^_’’’ÚÚÚš››AedY˜œ”ÐÛ‹ÊÓ„ÁÊ…ÂË…Ã͆Ã̇ÆÏ‹ÌÕÌÖ—×á—ÖáÏØŒÅÎ…½Æ’ÔÚÑÙÏ׃¿È}·À~¸Ã}¶ÂÈÔS‹9DDeee­­­ïïïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÞÞ|‘‘V–›•ÕÞÏ׎Î׊ÆÐz±»‡ÇÎÒÙŠÊÓ¼ÆÉÒ’ÓÝ~·ÀƒÀÉŠËÓ‹ËÓŒÏÙ“ÏÙŒËÔ‹ËÔ‡ÇÑ‚¼ÆˆÆÐ‘ÏÚu·À6ZZEEE‚‚‚ÀÀÀùùùÿÿÿÿÿÿÿÿÿÂÓÓ}¸½”ÓÝ‹ÉÒ†ÅΆÂˇÈÑÏÙv´»9MO[[[QQQ7FF5\]OŽx¼Â—Öß’ÑÛ€¼Ã}¸¿ŽÑÙŒÎׂÂË~¸Ã‰ËÓ„ÁˈÃÌ„ÎÖ_ž¢l‘ÛÝÝþþþÿÿÿÿÿÿÿÿÿÿÿÿíòòm¥§ŽÏÙŽÎ׉ÈщÆÏ‹ÊÓˆÆÎÊÒq¹¾?]\¡¡¡ÍÍÍd{{W–˜“ÐÙ‹ÉÒ‰ÈшÇÒ‰ÈÒ‡ÈщÆÏ‹ÊÒ˜Øà€ÃËsµ»e ¢g«¬j¦©e¡§ÓÚ˜ØâŒÌÕ~ºÃ„ÁʈÉÒ~ºÃŒÈÓo²¸4OOOOOÑÑÑþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÐÐT……y»Á”ÑÛŠÉÑ‹ÊÒÍÕ‚½Æzµ¾„ÁÊŒÇчÇÐn´ºg§«‚°±œÄÅ¡ÊË›ÄÄz¶·sµ»|ÆË“ÏÙŠÈчÆÑ‰ÈÒ‹ËÔÐ×Bxz@@>@@>@@>@@>@@>@@>@@>@@>@@>@@@@@CCCCCCCCCCCCACC>@@>@@???___ªªªõõõÿÿÿÿÿÿÿÿÿøúúwœ •Ò݉ÇѽǺĀ»ÅŠÇÒ|ÅÍ8eeKLL’’’ÚÚÚÿÿÿþþþÍÞÝ‚°²i²¶–Õß‹ÊÓ‰ÇЄÂË„Ä΄ÁÌÌÔ˜Úák­±8ce;CCVVV˜˜˜ÕÕÕþþþÿÿÿÿÿÿÿÿÿÿÿÿ¯®¿Ç‡ÅЂ¿È€¾È…Á̈Å΋ÊÓE‡‡ppp¬ÈÈ~ÀÈÌ׃ÂʼÆ}¸ÂƒÁÊÏÚn¬³;MMŒŒŒâââÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáêëbž¦ŠÆÏƒ½Èƒ¿É|¸ÁƒÂÊŒËÖÈÒXš cd}}}ÜÜÜÿÿÿÿÿÿþþþÎÑÑb‰ŠËÓ‚½È¼ÆºÆŒÎØ‹ÌÖŒÌÖ‘ÐÛr·¾5[Z@@@ggg¡¡¡ÑÑÑüüüÿÿÿÿÿÿæêêi£¦ÌÖ‹ÌÕ‰ÈÑ‚ÀÉ„ÁˇÆÏ…ÄÍŒÊÔs®²:NNfffÄÄÄþþþÿÿÿÿÿÿïïïu”•…ÆÍÍÖ…ÂÌ…ÁË‹ÌÕ‹ÊÓ‰ÉÒAuvpppËÍÍ|£¥¿È†Â̺ņÄÏŽÎÚ‹ËÖ•Óßd©­5LMCCCyyy´´´åååÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîîîÞÞÞÞÞÞÞÞÞãããýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøúú{³µˆÌÕÊÔˆÆÏ‰ÆÏŒÌÔŒÌÔ“ÏÙU”–:EEKKK{{{¶¶¶ãååìñðìððìòòèîî¾ÄÄZy³¼†ÂÍŒËÖŠÉÒ‹ÌÓÍÕŽÎØ‚¿È>bc}}}ÜÜÜÿÿÿÿÿÿôôô¯µµY””ÏÚ‡ÇÒ…ÂÎ}¸ÂŠÊÔƒ¿Ë„ÃÍŠÈÓÐÙH‚…6EEDDDqqq¡¡¡ÑÑÑõõõöööÅÆÆi’’ÊÓ‰ÈÑŠËÔ…Å·ÅΉÈщÈÒ‹ÉÒt½Ä4]`sssÄÄÄþþþÿÿÿþþþÍÍÍh‰Š‰ÇÏÌÕ†ÃÍ}¸Â„Ã͆ÁÌŒËÔCwwpppÁÁÁ¸ÎÍh§«’ÐۻńÀ̈ÇѿɌÈÓƒÈÑ=su>@@TTT………µµµåååÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõõÜÜܶ¶¶€€€„„„ªªªãããÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»ÙÙq¼À•Ò܈ÇЉÈÑŒÌÔÎÕ’ÑÛk³¹4]\@@@WWW²²²ÚÚÚùùùñññÎÎΞžžMqrƒ¾ÇÍÖŠÈчÅΊËÓ‹ÌÔÐÙ‚ÀÉ?b`€€€ÜÜÜÿÿÿþþþÌÌÌx‡‡]¡¥’ÐÚ†ÄÎ…ÁË}·Á‡ÇÒ†ÄÍ„ÂÌ„¿Ê‹ÆÏt´º:ii>@@DDDqqq˜˜˜¼¼¼ÁÁÁ–——SxzÌÖ‰ÈшÇÐ…Ä͇ÈωÈÒˆÉÒŽÍÖÍÔ8hkˆ‰‰ÔÔÔþþþÿÿÿççç¡§§G~ŠÎÕÌÖ‡ÄÏ€ºÅ€¼Ä€ºÅŠÆÎCvxaaaªªªìî»€ÉІÀ˽LjÈÒ„ÀˆÃÍÉÒY›Ÿ0NN@@@VVV†††µµµäääþþþùùùëëëÔÔÔ»»»™™™}}}WWWBBBMMM„„„¼¼¼öööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöùù‚¾À‹Í×ÍÕ‰ÈщÇÏŠËÒÎØ”ÔÞU˜š1SS@@@SSSzzzŸŸŸ¼¼¼¬¬¬’’’bkkGƒ†’Õß‹ÈÑ…ÁʆÄ̇Å͇ÇÎ’ÐÚ„ÁÉJii•••ÞÞÞøøøÚÚÚ¥§§Nqpw»ÁÎÖ‡ÆÏ‡ÅÎ~¸Á„ÁË‹ÍׇÇцÄÏ‚ÀÉ‘ÏÙ_¥ª4^]=??CCC]]]ˆˆˆ†††Z``F{ÐØ‹ÊÓ‰ÈцÅ͇ÆÏƒÂË…ÄÍÍÖyÁË8`céééÿÿÿùùùÁÁÁsR“—•ÔÜÌÖŒÉÕ†ÅÎ…ÃÌ‚¼Ç‡ÅÍF|~NNN¡¡¡õõõ¾ÕÕf¡§‘Ì×€ºÅŠÌÔ‰ÉÒˆÇшÅÎ…ÄÍG‚„2GG@@@VVV„„„©©©ÅÅż¼¼¤¤¤ŒŒŒttt\\\:HH?ab;WW>??\\\˜˜˜ËËËùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ÔÓj©¯•ÒÛËÓ‡ÆÎ‡ÆÎ‰ÈÑÎ׌ÍÖI‹Ž8GG@@@EEE\\\mmmcccJMM3\]m´º–ÔߌËÕ…ÂˈÇψÇωÈΔÓÜj°µYvuµµµóóóÅÅÅžžžmttG|}ŽÎ׉ÈщÇψÉÑ‚ÀɻƇÅÏŠÊÔŠÊԿʆÅÎ“ÐØ\Ÿ¢5dc:CC@@@JJJAGG3XYd§¯“ÑÜŒÍÕŠÍÖˆÇЉÈÑ…Ä͈ÇДÑÛv±¹H__›››êêêúúúÍÍÍš››Ejirµº’ÐØ‰ÈщÉÓ‰ÆÐ†ÆÏ‚ÀÉ€¿ÈCƒ…JMM¡¡¡õõõó÷÷…±±k¶¼‰Á͆ÄΈÆÒŒÌÕˆÇÒ‡ÂÌ€ÀÈExy2HG@@@KKKeee†††€€€\\\KKK:BB4VUI„‡z¼Ã[šŸ4LLAAAkkk›››ËËËøøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøûû¾¾r¹½”ÑÛ‹ËÓ‰ÈЇÆÎ‰ÈÑ’ÎÚwÆËL/SR=CD@@@?@@9CC1^]X•ššØâˆÄ͆Ä̈ÇЋÊÔ‰ÊÑŒÉÒ”ÔÞR”—‚ŽŽÒÒÒÄÄÄ•••cdd6``h¯µ‘ÎØ…ÆÍ‡ÇΉÇІÇÏ‚ÀÉ}·Â¹Å‚ÁˆÄΊÊÓËÖ‘Ì×mµº@op2CC3JI=std£«–ÓÝ‹ÊÕŠÊÓŒÌÕ‰ÈчÆÏ‡ÆÏˆÇДÑÝXœŸXhh±±±ôôôÖÖÖVgfNƒ‡”ÔÛ‹ÊÒ‡ÆÐ‰ÇчÆÐ‡ÇÑŠÈÓŠÃÎP‡ˆEMM¡¡¡õõõÿÿÿäëëy¶¶€ÂɈÄÍ~·Ã½É„Ã͈ÇÑ–Öß|¹ÁF}4JJ>@@@@@IIIAFF6HH9_^F‚†j®³ŽÓÚ–ÔÝ…ÊÒF|~;BBAAAkkk›››ËËËøøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáððxµµ|½Ä’Ï׋ËÓ‡ÆÎŠÊÔÎØ’ÐÚÎÕT›Ÿ8nr5]_prW–š{¿ÆÖß”ÒÜËÔˆÅÎÎØj±·5_a??O[[x‘’ž£¥ÔÔÔüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûüü÷úúÕââÓââËÜÛŸÈÇŽÆÇn³¶|³ºyÀÅsµ½~ºÃ€ºÄ¼Æ‚¾Èƒ¾É“ÒÛw¿Åq¬°z±´Þææ÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþþþþùûûßêêßííÞíìßííàííýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþþþþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþìóóÞéèÝéèÝéèÞééêòòþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿééé———\\\AHH;FF4XWBpqAlm6EE@@@KKKttt¢¢¢ÇÇÇîîîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþýýýßééßëëÆáà¿À›¿ÁœÅÅŸÉËŸÊÌŸÈÉ ÇÈ­ÐÑÛèèêññÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿééé‰\e>\h@_k?^lGftNm{QrPq~Qq~Mo|Nq~Su‚\{ˆkˆ”aŒgƒr˜v™~—Ÿ€˜ ˜Ÿ€—ž‹Ÿ¦’¤«—¨®¥´¹µÁƺÆÊÁÌÐÌÔ×ÕÜßãçéêíïôõöüýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýþÄÖ׆®­¥£wœšmŽf††\}}TtuGfiNjlGcd@\a<[^3X_,RX)OT&LR%JQ)KR'IQ&GR"EO%ER&HW+M].Qa.Sb/Td.Td-Tc1WgD=E8@5=8?OAP?O=ODUCTDUBS!IZ+Rb8[l8\l9^jAdo@amDdnPmwSoy^w‚e}‡az„l…Žx˜„™¡“¦­™ª±©·½¸ÄÈÊÓÖÖÜÞæêëúûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ÈÆw›—j“’[…ƒQxwFml49/5 +1 (1 +4 /8 +1 ,017 27 28 18 2< 3> 3@ 5E 6G8H7F9I;K 7H8K;MARDW%K\%NZ(N[$JU*LX4U`/P]9WdCamKhsMiu[wi‚qˆ’rˆ’…™¡—©®¦´¹ºÅÉØÞàåéêöøøýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåèèy–•b„‚Emj>ji9cb-XW%PPDE;< 69 16 +1 (. ,4 *4%1%/ )/ )0). .3,2/64=5?3= -</?0@/>1A2C2D2C 4F 5E7J7I 1> 1> 2? 1@ 3C 1A5E4C4E=N$EW-N]7WcCalLgrTmw_wuŠ“ˆ™¡¡¯¶¾ÈÌÖÜßêîïüýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðòñƒ“„{–xm‘o6`N#QBK<E7>2:2833/ ,+ -- 13 -. &( &( +- 12 23 55 5804+0(1(2(3,='7&5*;,=,;->.? /? 2B 1A 3C 2B *9)8 -= -?(9&7 )< +> .B2F:L"ES-MYD;D;A993 3/32 0/ )) *+ )+ ')()()-/,/,2/4/7.7+4*9+<+;*:+;-<-<,<-=1A2A.? -?/A ,> (9 ); -@ ); &:#5 3 '< -A 0@7F*IX;Xd@]i@\hLhsZt}n„Œž¥©·½ÈÑÔàåçéíïøùúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÏÙÒ—¬Š~•k^€THq=ƒp,_P$PD!LAH>?6:2 4-6/;4;68655 36 /3+2.60909 3; 26.1*,*7,;/>/?,<+:,=-</?2D5E3C4B6G6E/=,</>-=,=)9&7$4"1!2&72C:I AP-N]4Vb.=/=2A/@,:,:-=0@1C3E5G6F4C6F9J8H4E4E1A*:*9*:'7 42%7 +>7GCSFT$FS4R_Kit\w‚}’››¯·¹ÈÏÏÚÞØâåèîð÷ùúþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ø÷§Á¤ÁØ£¸Í‘›¾r©‰7q^TBQ?H9VHQDC9<2<0?0B4A;:9 23,1-7 7D 1>-8-512 42 624B7G3A-:.<0A-<->-?,=*;,=/>0?.=+9+8.=/?4F6H2D,=):&= 3 4':,? 2E6F=M;J-KYDdp]y†‚œ§¢·¿ºËÐÏÜßóö÷ýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôöóªË¤Ùòµâ÷µÂæ¤Yˆd+^F#dIaHnT%|c]LN@J=H9L9K7 A9 =9 86),0A/@ .C .C .B3G0F0E ,? %9 *> %6"2 ,A*C&>%9&:(:(:+<2D 5G:J,O]Mop›ª²¬ÁÆÔàâýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿô÷ô¾˜’¨z½Ñš»ß£Ta<{V9|X0vX6…gA¡…+{fRDL=L<SBTDQIA= 41.. /0 /0*.)+')&%)'/-2:3>0;,6+7,:+8)7*9,<+;):*> ,? -A 2E 2F 2F 2G 0D ,> += ):"3%:'=(=(;&8%6(:#3,> 4HDU?evd„‘ž§®ÃÇíòóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòöò~ž{=P/f|R˜Â‰c§pUžkO”hA„aE’oN°’'u_ C2 @1 :, 4*5* 93 <7 95 73 1/97 54 88 :9 6600*,!).6 6@ 3>0;.:.:,:,:-<0>.>+>-?.A 2F 2E 2F 7I 3G -> 0A /B*:(;*=(<%8(:*=)<+?"4,?CY/ZlRy†m™É×Ùøûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïóïs”rLcBCX7xŸpŒÁƒq§kv²yr¶‡V™s(eORBPAL@C9G=<3?;C=>6;29/9. 5, 0+ 0,/203.4/5 5; 4:172;2</9-8,8,7-:/=.@0B0B3E2C3D3D4E9H6D.<+8)7+;,;(8%6$7&8,A#6"6 3II]6gpn•šìññüýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòõò…¬†d‚YToL˜Å’àõ«·×‹ Ù”xÅŒC„^P<TEQGGBB=C>QJVQE?B9C5F5?-A2<2 7013.3*1.204+/+/-3,3.62:3=0:/:/<-@-@,>/B-?0B3E2B 7H 5E 2A 7F6C1>,9(6&7&7"5$8(>"7%< 7LMQe“øúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõøõ˜Â›ƒ®}q—kžÌ—ÃØ–ªmZŒY;~Q*kE)kM/dO1dQ'NDK@L? j[(skLFJAE8A3E3J<F=?8 13)-'-)-(*#%$()-&,&-)2-7.8.8,7+<+<):*<,=/A1C 2D 4E 3C 1A 0A1</<.:.= -? ,?*>%9&<'=*B/D3:Gtyó÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùûú¤Ò®“ؘœÒ‘†±yL‚a5uW(oP+\-‚Z5‚U;tF?rB7d9*f<_9 |T!|fJ@ 4- 62 .- ++ 11 // 33//*+*,--*,&*'/)4)6)8'4(3+3.4/5+6,7*6.;2A2A3C3E 3E 3G 3G 4H 5C 4B /=(6 ): -? .B(<)>'<(>-E+F?QÙãåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûüüµÜ¿§ìª½ñ¬†©pWYS…a\šsh³‡b¨{YšiN…SCvG:j@3jF&aDL8F8=42,1.22 --)'43 <: 64 21 .-//22.3*3'3$1$2&4)4*2)/(.)4*6-91?4C1A2C0A/C 5H 5J 5G 7C 4A 4B -;'6(8(;*=*?.C*=&:1O6L’±¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏð׸õµËò®¡»}{ i|¦sŽ»ˆ¸ë¶¦Þ¨X‹^6e>+]6#W7J4O?KAH:K=E;>8=941 54LJ FC.-'&)'''()%)!*!,".$2%3%0&.(/*1)4,8'3 *!.'5-=.@/A.@0C 6I 7C 3> 6C 3A*7(7&7);(9)</C0E1O>TP‹üýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ÷ã¿ú·²Ó‘©¼|›Ð…“Ì‚¥ÏºãªŽÀˆD{O'f<_9gD`J)mc)cbWDJ7A3?4<6A=<:;; //%&%& %&&&)*&)#-%/&2)6(6(4)3+3,4/;0>,:$/ ,#/(6)9+;->-A2B 6B3> 3@ 4B /> -;#1%3'7$4'6,@+E0E>M¾ÕÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙðß~³sxZ£®p±á“¦Ý“®æ¡–Ò“`—eC†V8ŠV.‚R pJ.‚gG¥•"^ZI4@+>,<.3+ 1+:8 /. *, +/-1,0 11 25 05 /7-8*5)5)5,91=2;.7,8,:0>/>-;+:*8*8+=0C/B/?5?7A3? 4@ 7E 2? /='4&3)7%3 /'==V:PGu…çñóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛéÝr¢k§kÄÍŠÈê¡Äõ«´ë¨–ךwº„TŸhS«oQ®tI¢qE˜x4}jSJM7G1D1A16-2, +* )) *, *- (,.3 8; 8< 7= 8A 7B 5A2A.:-80<1;-7+8-:-<)6(6,;)7*8+;,=.>/?4?7C2=4? 7F 3A 4C;J 1@*:)8&3%6(</E;P…ª°þÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñóñ¡Ë–³Ù’Ûç¡õôºÚå¯shS|WŠÂ”–؟̌Ֆ†µW„a2]F3eQ8\C0P;$D28+2)2-(%)()),.)*+, 04 =B AG 3=-60:.9)3&0(2*3*4*9,:,;+:+:,</>+;)8+9.>1A4A3A8E7D 3B 5D 6D8F 6D 3A +9)5-<)?)>1H!ciÐåäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶Ù²¬Þ˜Þñ±ä踈™sPrO7fC@sLŽÌ”¹ï¥½æž{”a4P00X:(W?2U?3ZD F42'4,7086 67 68 =? 9: <>26 4827,2'.(1&/'1*3.9-8(4(5*9-=-=.=.=0?3B2A,:*9/<2B5E9H7F4D3C 4E 7F :H 8F 0=.;2?+@4N?WDM?|yîóòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØéØ©æ¢Êò°›¶…_Y^“hYžmR”cVŽZ«Õ’žÀ~FZ/1S/1c> T6D0D3;+ 5)<4=6=;DF=@<@ 9< 78+/-/,1+0,2/65=9C4?2<5@4@1B0A.?-=.>1A1@1@4B6E2A.;,>3E1B0@4F4E 4D 6E 8G 9G 7D 5B5A 1C)<=PM\IOd“ñøùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºóÀ³ñ®Á‚e¥jl´wwĆu¿€€Æ{±kY†J?j8J†SB‰Z1{WI5 6'1$6+ 6/ 5056DG15 (,#(+/,1,1,2+0+26> @H AK?H>L?M:N9L6H3E3C2C,;,:.<0>3?.=%8-B.E/C3D0B.=3B 9H :G 6C 4A.< ,:-;0@>TPi K`¥©ùûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊóÔ®ö¶Õ‡‘Ñ„¥Ù°Õ‘»Ü–ËꟖ½uhŽRj¡cn¯w]s5fN8+<0B5A7A: A< 667; *./0 68:< <@ >D ?D:?8>7=5<7??IAN,:-:+6(4-70?(?(?*@-A.B1D2B3B2A0;0;1<,< .;-9(6,DEhYƒjƒ¤ÈÎÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæøìµúƮ뤢غãŸÛê¨æë¬Ú墥ih—]\“_X‹bR‚d(M< E6I;E8MCGC :99< 26 27 == CCJF DL KT IR EN FN GO AK4=6?8C0<.:.;.<-<-;+9,<,<*8)6+:-:+;)C)B.G1I.D/C0B2B3F6E2@5C1? 5>8A1>'<,GCioŒ$„’¸ÒÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøýûÆöÝÄæÌª×±²ðÂÐðÀ×ë¾§¼‘/^;)a=)`B-R<,UAM9J6K8Q?KA 11.2)2(02955=9NETaO^@M:F :F 5A /; .: 2?5B6C8E (B(B,E/I3M5K3I0E1E6K3H9J:@7>;C =G8C0<5B HWYkfv­ÆÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýýÏõåÂ⹯…—ÉšÇë¹Éóµw–e;g=HPX‘gUŒg$R9?-8, 2+C;4/ -) 0.66=@PT=?33243423349:5756=>CC OO QP EH CGAG>F>H9E4@4B6F3D4E2D.A.@2B7J7L8M/B,@ 3H 3E 7A 8C 7C 8C :G :G0>?M JZ O`]lÅ×Ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìþ÷Ë㺇¢sX|P|©p™Ê‰Y€J]…Pyªpy®{Qˆ`K1M8@;75652/;6@:GARO HFQW JS8A 97 =:@< ?< C>LG MG KEJCG@B<>8JDKG>;:98:46594;3;5?3>1;6B9G6D0=.;0?2A3E0B); 3I 1E 1? 3@ 2? .<1? 7E7F.;><E>J?ZK ]Q ^S[aLVDR:7C<KDSLXQXQ^XbZ \X YRWRKD;4>68295 :6 76 66 4727 2917,2,5/;0;.9-9.=.=.> 4F+<.@ 0D3D 3D 3E 2B 2C.=5E.;+7/< O`N\!^g®ÏÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ®Ê§ŸÇ†Åäš°ä’€¶hn›S§¹oÅØ‡±z'Z8)fF)hO"YTHH32;7@: ;3B9mdla ?= 469> :6C?PM[YffgidinrkpchW^ IMQJPHG@C>>:<;?@;= 5: 8<;? 6=29/9-6+5,7-;.>0@3D0B+=-@ 0A /@ 1B 4G 9K ;M M9I4C0>LCNIPK FA @: JC :1:0C8C> A< B? >> GIgmktR^KWAL 3>4<QJZQVOOILGKHIGEDAAAA >> ;> ;A 5< 7=09.:/;-<.?.?4H0E0C 2C1B2B/@0B6F ;L =N ?P =M4D/==LM[!gp¶ÌÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ¬Ø»¿Ú¨ïö¿Û襯Ç}ÒÜ—Áä ?uM#bC4nV%E9 Q1\;iLlZc^qsflBBC?K8P8W8[HaRcU\SOI@>@@BC79 #$+---/) ;3B:NF[Sc[`X[UTO PLGB LHEF@BAD;C9C 9D 1B.A 1E,A /F/E1>2>4B3B1>2A6F 9J :J 8I 8J 7H 4?9A Wb`k®ÂÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùüú°á¿åðÀìò¹ÉÒ’ˆœcTyJJ+J2(XG+KA+i?e<iFzcf^X\MVHJ@>P:`Ag@ qL%xV&xY.‚e(tZI9&?/N:S;)dG$\CPDE;=3 2* 4+NCfY qdug"ƒu%‹zncmggd ]X aa QSLQFNAJ6B5B4A3>1:4>/80:2>6D6D6F4C.?1C 6E FZaªÅÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÃèÙÏåÀôõÍ¢¢lNf8m¡fA‡W$Y=.^L3_Q&jB mEuP`LWNONGKUUJH]ImNxS)‚Y+~X'vR(oS,sU)cJ 1!\=-tJ1~N6„V@†l@ˆs8j%eRD4 ) 5+UF-„s7œ•ic=9)'&%2189AD>BGNBH@F >F 9A3;4>3@4D 8I :M 3H1? ;C K7I8VF%_O'YJ 'P4+sG0‚N7ŽXA‹fH•pG—rFšu=Žk(jMR:B,<(0! %  %# ## (' (( 00<>@D37 *- 08 7? 7@ 8D5C 7G :M6J5F8F ;P 0G$:8OLfPh4gy¶ËÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–º¤V~[€ŠW»qs¨c€À^—h.jI]DVOTP)vl6€n0yaYBS> P@SFVYWaP^ MK><:< 16 ',+01)I7 T<.xR,Z-•`/šc+“])[*‘]&ƒS%}N&zM'tJa=W94'  O<UCUAZHXGJ; /%% (,4 5B 7G3D4F5L*E6Q >W :L,82>IVQdWk|¦·þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè÷ïœÑ§€ŒV—Çxy­e’Ë‹P{U2rK1–o,–“,Œ‹5‰2saL8J2oQˆo¡Œ„Œzˆ e|folqbkSbJW7A  1#I1d9qB…Q+ e1©n.Ÿe.›b0™c,‰W4]/„S3}T@v\ K6]B#w[mQaIgPUDK=A6   !% %*%- ) *(54E9M5M)G/1ENa7E1<9CKYDZ*HPxœÚçïþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎæØãÔŽ·ÅlšÄlq¶tO„YR”bDšc#‹x6±™FÜ Q3GrTXvXH’*•†š–ˆ‹}$…y wslimjde)vwLN(* 46=@>A;@ 14 ** -, 64KE#mb0x5˜x1“m5™f<¢g<¡_B¡eoͪ,  Y;!yOxN|Q{UwWjXYNYM =/ $!4*50 3165 26 19 0; 2? 7G5L )<- 8M KcDZEX;MKa Ja*?*Pc›´¼ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúûúÈÞ¤²Å{ÀæŒ}¼qJŽW[°qK¤o&Žx/œ‚7˜v:sNTŠb]ŒfG£*—zš~ ¡ƒ$—z)‹o(~u$uo(ys7ŒIE)'MJ!`]#c`^[[XVTVVRS>> 21 /, 4-K=fT2Žo8›s7šl;–kk½ /dN !W;"sK,Ž_"’_‹\{UwXnSeOXD  392:9D;H3B+; '7$ 2G,>=S Pg.@7Kg^x8Yf­¿ÆøûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëùóÇ￞¿„g‘K^³btÚ‰^½…:·Š<¥{>‚\U‹_L‰[=ƒT+Œ^(’f*™n/“j.Žd3’hF¡:ƒw$B9-ug5s6…v:Ž}:’1†s)xg)xj%rs*uy#di &) (,LRVXRRA> 0,)$0)5.Ep9/(mN=›p1¨s(­v*º€©u–f“h9Ÿ|2(?.M<QBQC JC DABB>A;@7@5? /;5F9N !0 0B7K DZBX-=(99J ObN]h†Žæíîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþ¾êÒ…¿Šu”Pz¹h„׉‚ê«G¿€7’]\šhd”cH…W9ŒZ#†W*‰c2“l>ŽoA”tS²7n\!TF5{h@zEšƒ@–}?–~8w3‹s0‰o/ˆp+‚{/„@@9:MO VZ&ae$cgbebcWX GF98 (% *.v]4¢|6À-µ„"¬| ®Ÿs:­ˆ"N> 0![B_F\GQD MD RL KJ ?B=D 3; 0; /; 8E :H'@X 9P?V 7L/@-<7F OaI{ˆÓàäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑåà~ʘ¥_‚¶hâ—”ö·KÄzL¬kh¤kZ„W[£m8ˆX)’c-‰d-€a@ƒlU¥B†o $YI8zf@‰t@vC–~A—}>—|<–|6Žt2‹p-„k9šbZ 1-#`\ VU%]^$]`%ei#no qrorcd[^XYJJ1-  >.%n3»’*»)½‘#£~>»–.jU  0 fHoPuYlY`S XN PMKLFM"& !( .82=5B @O%4  .A?X =S ?S”w:t4‹p<™:—~=›„+kX + WE$_N*iX(hW(l^&qc%xl"{r|rwrmsen$v ,17;CHPRRP :9 MF+‹‚:Å­H¸¡ #„]›m-™q)Œj$†izbtb qd]U  -. 24 49 3;8B=H >L9J1A+&6D]BZ 5H5E?LYj?MIbmÛçëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢ÓÇYŽl_ƒ[¯on¶\v»d‹ÇyŠÀ‰¦ì¹m´‰+VA $7gRw´ #3-:(C€aA„d>ƒe:ƒf;‰n<“w:w8z5w3ŠwG©”B60%$^O'cT,m[+r_'p\$p`$uh$|q!zrrlyz$~[_,/RUEHYZYXTR_\ .-  D>1•‰ )# i!¥t/žr-—q(˜so„k*‹wI?!42 88 3<7C6D6D _s BU+IWÅÚàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓëêI£r°…Åè–€²\ŽËr–ÚŒ­ä²]|c +0cAA>@:@F-©s:µ‚/¬x#¨s³~£x4¤„&  =4LC XMUMNHGFBF=G=K 8H+</@;L,:,::M

K#+30;7C8H3C >S :O/C @U4D GZ 8I 3@q›¨òùúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿp£›C‘€ÐèÓ‡™OuR{̈‰åŽŒíŽéƒ¥å„¬ä„¦ð’™é׆‹Â˜3Q=†»ŸV„n*# -+ B?$YQ-p[5…b;ŽeGrG8NB3{o0wi2xj4zi2yg-ug'sj#sr$xv2~ ,& % $^S1cZ5d\l[#ra!i\l]=„v0i`#&#&37MO88" '#gZ&‘$Ÿˆ#ª/Žt  B* Y {^mac` ZZRSJMQ[  $#/3.29B3A7E:M+;4E @Q5C ;JES0;>H„¨±ñ÷øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØæäB„sªÏ®ŸÀ›p¡sw¿|ƒÕƒ–ï¨óªí‘¶ô›®ö¦¡ì ‘ßœ™Ó©Xc'"$E3:o\E…xK‘ƒCŠy@ŒqHvD•kT}?h@49s7{o8|n9}k7|i4{j.zm'uq(~w$Šx"71/bWApf@nc}evasa%|k&QJ !!BBVU [Z!_]SO 72'! H?|j!š…)}i  H2Žf‰kwijc i_]Ubb/5./37166@6E0?3G0C+> O/= L‡§´ëôöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¼³p©‚ʘWŠZ…ÆŽÔƒ¤í‘°ù›«ô·ú«³ø·¦ë°¦ë¶®è¿Tm\1I}SW˜kWœtVœzS™zSœPœ}L˜sK”nV—ze²•!PB.h]?‚s=}m?l?‚m=‚n6€s/|r-‚y#€q!H@0m^BzgAta‡g${c$wb,€o !GA^X%ib&jb,tl$kcbYME1*2*_S"fX  R<—r‡k${g!€m }e m]d^  ()23D…w>zlD‚mD†oC‡q<…s3€r2ƒy/Š€  I?2}gB‚iB|b%‹g,}bG¨‹E:$#FA"g[(qc.zl0~p0}q.{q)wi!nc[Q 81*# 0) WB •r+“w2Žv$‰m ‡f„lXO439;=B:@8C4E->.C.E&;&88NCVBT3E8M >T1F -?_~âìïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÚÏ}Æ›b›ov£j Î„°ßŒ­ù›§û¢ ù¤¯÷´»ø¼¿ó½ÆôÔOnUNxNyÁus¼nyËzuÆt¿‚mµƒe«c©b¨XžyM‘vD‡qH;5rdD†tH‹rGrFŽr?Žt7Šs7†vYŸ›+&<1%–q4ŽiE™s6Še]™~YŠt kai](v_.€h0…l-~j/‚o1‡v,~m+}o&ti]UG@! I<+ˆp3Œp0‘p%k—j&’s5*  0*@9 EECF&6@U=T6O2J 7P9P5K4IMm{àêïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúüüzŒj•k‡®uªÔŠ¥ìŒ§ò–¤ï—²íŸÈû¬Ñö¬×óÞTmX[€U¡èŽ•Ü™ç…—ç‹ÚŒ€ÌŒw¿‹s¹‹l·Š^¹†T¯†X¸•&XG3'@wP¢Z³ŠU±‚P²…I´†J¨…}²¢J‡s*@hW¨€Xf 7Œq$‚j,“w4“k5”l4—p.k+Šj,‰m,…o/„r4‡w2}s3zqUO '#  $I9nQ~[(˜p$cL C4XC\K UPPNVVDK=L=N9P=W9RCZ=S+=6K=W7Q2J 7P=T€7xm1*>4!I@=5 -$:*U@-~c) !$lShKfN \OWM ZTIJDOER=QX 4‘h>•iE¢rB¨w:žp7 s2¢t/Ÿt/™t/™v2’v;˜D™ƒ4+:0eR0fX1bXLB4*+"@6 >.'yZ!xSrRfR ^O ^QWSOWFOBS BS BU DU GU6G2M9U:R >W >T6GT;R?S©½ÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýËæÙSƒh‡¬„ÅÛ°ÕØ¶ÔظÝàÅÔØÁØÛÕ|„xŸ‚Çé°Æì±¿ö±µúµ§÷´˜ó±‹ò¯îªyé£|ê§~î¶uãµîË>}h0!_²ˆd¹‰iljfˉ\ʆeÕ“eŇºÿÔ:Y@5&*A6/( ( %ZD1a<’_JªrBªv;£p6¦s3¨v2©y4­‚/¡y4™xD«L<*!#[J&rX5~h5xh*h_XQ75 %ZH2k"T}VhM aMkW ZQ UY[`UcRc ?L6B =G.> 4S @] >W>T Ma5G5F :RL)QH$E7+<¢l2‘W8›_?£p>©t=°|7±|4³5µƒ4¯‚@´Ž8ˆr>/0qZ1‚a5q3‡u4xs8vy)]a+- !QA8‹i&‹ZˆZwWlSjTjZii^_ =E)1(0+4/7(5 .M ?] JdCWAS SAWF[9Nv” ýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöùùÁÔÏJZU":C9-7.+5,@ ?H ;S5J5I>R9NIb =T-? 7K>P J] EX*Uk¸ÇÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöøùÀÛØ4SJv©d’hjœi‚·k¾x‹©u^gR44/754‚‚ÅÎÆÓôÛÄú̥ﭜð°’ïÂ÷ÉöÌ–óΤòζ™0>(Üì¾éôƪ†@]G7W@@`;'@'+IX>yT@}[B„b\¯†4 2!ND‡p8a2z`,oW1(53IJPQ AD BCHH GJ HS;H.= @WA_BaPo0C @S ES FN DTEbRxŒïôöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöúù“¶±`st¨ƒvª~޾l–Än°Õ€Î䔬µ|^^C++'* gpe²¬ÊðçµãÝ¢âÙ漙æÄžçÌ¦åÆ­Õ¹kbÉè´ucHkC^—g[™ig›lb¢r,2vQ4‰a2f*‰bD¹‹)[=1‡a7”i;©l7¯r.ªs-¹‚7˘HØ©WÒ® L89Žk7›p:£w?ž|>Ÿu>Ÿm>¢m@rCœ}@4tr*^_ !C97sf6rh8zj .&-#SBP?VHQI JDLO MR MSPY­~?®{?¯v?¬t@¥vC¢~H G˜’#VU2/ CL;9>9(cQ(sSY>aEZHXJQSQ\T]MR =CNY GV CV CW[t8I 8GN]MXGW BX4G_ýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÝÛd“ƒx´—–·ƒ¥Áƒ±ÇƒÍÜ‹àééí’ðì–äâ–¡ pCC2?K7‹¢ƒÃÞÄÇåÐÕñÞÖöØ}—u)<"м€j¬hOšUDŽPN‡c‡Åž*$#! /%.$UϤxX ‚^+’i1±…<¾’S¹–\åÂP½ !nN6¯€E®}G¼…@»‚?¼‚?¼€@¸z@³v@©zA¤~V¼£8€v %#HCG@  (.=ss9zg.{T(vOqJhN[I\]Yf FN @@LOQX GR GU EUZo;J2?HWNZ FV BU EX(XiÙäèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ÆÅ]†”¸Œ ¾ˆ¬ÆŽÄÓ˜Ð×—ðð©íí¢ðð¢ïñŸÏÕˆ‡“TS]2*6!,.7+ds`ž¯™ž¯š>P:fˆ_w«qbŸ`P’TPŽVS{`$4'      >lYbÁ¡5ˆk#€^nNaEM8V¶—(VB/9´~;ņFdžUØ’J̇EÑŽBÅ‚?ºzC¶zH´S¼‘F›0' MEAŠH–‡'XW %=qsL€8c9‰g(uSiR jXaZIJ @BKJVUJO GM GQ IT N\?K @MFTES HWCU GYHZ·¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³ÃÂhk·…”¶†¬Ä‘¾Ï˜Ôà âç¡áæžïö¢ðøÛ苾Ñx¦År’¬lo‚XP[C=G5)3&+7&u•pu o`Ž_T†V2Y6    M}kWž„[@!pQ1Œh?j5jK )];FÆ‚>Ë€IáXæ”Yå”Læ—FÓ‹B¿€G¹SÀŽW½‘F3?0J”€O˜‡CŠ{LŽˆ8fl45&'B}xQ=r;ƒq4}m$bVB:@:[UUTQPPR NS HO KSBL DON[JWAL FTET KZ GWLx†ùüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿ¾ÌÀh“k€­}Œ±§Ë»Ø—ÃÙ–ÊÚ”äò¦éô£ãëœÑÞ’ŸÆkÁo¤À}±Ã”ÉÞ²ƒ”xHZDžÀ˜zžw\z[7M6   % (" ,$ '    4*:šuFµˆI³„UÃŽkª| ?&2}KDºrDÒDó“[ò˜[ê•Kâ•GÒOÒ“RÃ`Íš>…b $BˆgO˜yN“zUžˆL~DtIŠƒ #**%OS'TZ/`g.cbC>*^S(]M'dV]\TSOPMO NS KQ?F JTLVO[DO EQGV GV JX#VbÙåçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ®»½Nonu¥†‹¼ˆ—Ç€©Ö´Ü„Èé’ÙòŸÜï¥ä÷ªºé†¤Ìz™´u®ÀŽÜô¿ºÊª1?.AT>OhP:I;$& .$4,+% & # &  '=4mÔ«A£vGº„Dˈ^¤o4b:;”ZD¸pGÚ…=øTõŸ[ö¢Oô¦Oç£OÑ›T—eÉž>)I-\©xN”hO—n[¦ƒQž}EpO›ƒ=2995B4B "/ &"LQ'VR+^R&]V"eh`cW[QUKP;A CIOWLTNXIT BM HU JV HTP\½ÏÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ¯¶Bf`g‘s‰»€šÉ~›Æx·ÜˆÕðžÉÝ”ÓéËòž½Þ’¸Ì“ÎܪÛç¼xƒk-=*PkO/D2&1'$ %3)2*.)   " 'lÆŸPÀKÓ–Kî¤]¹:wHIªkB¼u>Ó†4îšKøªSø¬Fî¥Kä¨KÍYΦV¯‰%@ˆYOšdQŸfXªtPŸtP xF•pAŠs;/']X/gt1ivIZ &0 +4?DLNRUYaHMRX =C ;BLTKS FNHQPZ FQ GS LW JV DQ–¯¶ÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿ©¸¼åž]ÝžC™dT°v=Â6Ö2ì¥Bú¸Hõ·Eô°Eä¬HѨUÏ®%fL)L fKš]X²kS¬kR®rO¤wU§ˆ?0%^M(dX-on8‚.q)nL]#1)9;K@J8AJT 7? 7=IRJRHPGN GOJS HR DO JTO[FQ{˜Ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ¸ÄÉ7HP"+0Ta`–£—²¹ ÑدòõÊôôÝÚØÆ³«™wn^@A2KZ? Ôœ„¹…~´†&<+ !4-   "     ,I=NÖ§&¿‡8â AÞ7žlk¿3ÁŠ0â£6÷½;ûÉ7îº;ò¯>ã²DÔ°R̲7%H-M©iE WZÅlP¹jN·oQ°~A„tE80p]+q[/k0…r+„}#v…iX‚:!9 .88D'0&.@JFP@IIRHPNV IO HQ EP DOO[DQƒœ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ÆÐSkv&3; %#BE>beXnsgCD:(,PS:imM]gD¬É”Ëö»•½—/#/*'     &[½œVÓ©Uå­JÈ”HªˆçºGÌš7Õ -ä¯(ó½+ûÀ3õ¸6à´PòÐRʯ$(fFP³rQ¿pMÀpD¹qB¼}R–5mbHƒb;tRC†Y0‚g3“{&$ƒ‚mtRo(O)G 7J+=1)= 4HBOCLHNIQLV IXIWGQBMKYGWƒš£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÃÐÖr›K`m0:E!+"'."I`GŒ¦y—§sšeŽ’`GI2LS;4A2($ =:"        %  "1)=hY5t]9xa9{c†æÆhà¼HÖª-ç¯õ°ú¸)÷Á5îÅKñÔ>«• ,=‹gR»|NÈ}FÍ€;Æ„5Ç“>·”5kal£kW†N[‘M=št2”v “†}j woQ_4c)K@\ =` :c 4[(D 1CDNSWYaN] GcQfJT>JEUBVŒ ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÝãå}•ŸZv‚Ocp@SY\}o¥Œ¯©€¡t€Ža2<#­Å“)5%!6-/F=9PA' ?33 )(Œ~°Ø­r£|/=O> FC5oWH]=1<"!    7oKvÛœ^ÀQ¯m\³nzÇ„“Ô”9hC<XUÔ£Nó¿0ê´ï·6óÆWú×.‚l2‡c_ЙVÔ_å—k蜑ò·ÉýÛ…·šO‘{ÁñÓÇ÷Ö¼èÏa°¯?”˜)Ž™"~ƒfpOb Af\y]eZkYtQtEk =^Lm']0  2 5M ?Y =WTq€úýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþêîªDfsDejInjJldW|hjtnr¤¿›r‚g % ¥²§XVKϯ–Á…q‹XFfB4+ !(# 6"aka§ncµrd°n_¨jr¾}wÝž,~TuP4߬8ùÓ:æá<æâAäÜxp@® þëÝÄœæÒÆúíàÿÿ¯ÐÒa…{C/|¤Š†§’‡£™uÂÆX¤­6•›+~‚$v{sgds&tuip[lRk Ps GlJpFlCh"= -9]Ci 7V 5SGfLoñöøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·ÆËXw‚EhkGnlFi^DeUD_M«È©£´—,2$M^SØÔÁMGAE( ¿ló°š yf”ƒq3-$!(#AYQR†`?wLT˜dZ£ih¯ru³ws§pz³„‰Ù«D‘rWCo`LO =< @; 1+"h[]ǯñذþô´ëèrª¡Q‚Z–†ƒÚ«v ‹Sl`›´³ÙÜg³³CŸš>”*zx%zv€ry(tphlfrdxXr Qs HmBh 7Y@e#Ho8\ 3W 6X Ac nc¬ž9og3obJšŽ?Št8zUaŠ|‰¬§oŽÍÈËÀ^·œW©™?Žƒ-„€Š€!€x6ˆ‚,zrsjpds _z Qs@d AgEl ?` 8[ ˜Y=¢hC°zG¯dÕ¢Mšo|Í•ŽÐЏ|…ÇjØ‹qß„qÔtsÊhqÂixÉs}Ά…җ•z±†OsM5lNj\Xq"Mk"?an¾¬žûÜp̉b¥„L|0{ —†z%‡†-šŒ$‹u"†kxfqon{hˆ dˆ_†Z~Z} UwJiD] E^ 9LZu‚úûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéîï¶ÅÅ`~{\wf{ˆu¢£–ŸŽƒ»¨›È±ž¿º”z‚]6D#§^u£RoMx§Xn«^c®hZµxV¿ˆ]Ê•qç°W­xuÀªêšÉð›Òó©ÁöÀ—éšyØ€rÛxrÎw}΂’Ëšªß¼˜Í¸d©Gšw#x^ngZ~?h "JzÚÄŽõÍ_¼uX™xHŒy.|}”…‹ƒ‚(™Š#ˆn(k#fuqr}ji’ g’hb…X{NkF^ F[ 4Fgƒûüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþòõõ¦µ°_sm_pmyƒ¯½µÿÿüîôßìùÖ˜¬„‚šiš·}£À€™µi“µm—Ã~ŒÄ…‹Ë‘•Ö¢¨í¼®â¶·ŒÙóÃãñÂëøÂçý¾Òû²¿ö¥®ð››ÖŠÀ•½ˆ¢Ëžºí½‘ÍŸp·„Cž}‚ŠXm AW%7a÷„óà`©‡PˆvEŠz,ux"”†z) —Ž|‰m!ˆn vutv…y– q– cŠ b‚ ZoNdAS =O 7K}˜¥üýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõøù¸ÃÆ‘n€~_uqrƒz©º¦ÝãÕÊÔº×ÜÃÛæ¾Øë¡ÌâšÉÞ›¿×˜¶Í—¯Ã•ºÌ¤ÖæÄ¹Â©ñôáêëÙíïÐûÿ¾÷þ¼óþ¼éù¹Ùð®É禿墰ؙ°Ü›½ðª»è¨p½š"‰—'•*—!z{Gža½¹^—Dvn?€s*†oŒlŒy%‚‹(ž(ªŒxƒn ‡u…yˆ‰|‰y–j“ a} Xa N^M^@R9L©»ÆþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿèììÌÓÔ¨³²‰—”dwr`pizŠt„u†•t§¹”½Ñ«ÒîÃÝùÓÉâÀàòÖÝõÒÁصìýÝöÿæüÿçÿÿáÿüÝûûÚõúÚóûØì÷ÕàñÏÏèÂÃáºÓõΰΪf‡ty­­†ÐɃÏÅäÖŸáΖн‰³¤k§–GzxaxZg†2«£?«¢,u&‰v$•‚€#ˆŠ…z h `q Wa KWLZ=N9TcÕáæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýùúúö÷÷Ûàß­¹ºƒ”•}‹‹WihCUQBVP[sjjˆx|™‹ž‹‹¨’š·»×¹ÁÕºííàôùêúüíùÿîùÿîöþìçöÝäùÝÜ÷ØÙôÓÐèμҴàñÒÕçÃÕîÑàþ×èÿâãý޵຋԰fÁ›9µ"®…•t wd’€@¶¤Bœ.tj4‰4’ˆ)‹†~~z€x~ _f NUOZSc 2BPl{óøúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùúûÎÕÙ’ ¦‡–šq‡‡\xuUsiMj^j‹ya€mVq]cwftzp}ƒy„˜‰š¥•«º¦ÐäËßðÙãðÝãößÐç˺ġæÔ¨½¼ŽÚÞ¬§¸‡•«…œsv˜se§U©€7¯†-À‘$µ#ºœ‚%ŽzXǶe»²K‹GЇ5„-ƒ€yumlhls}\hDQ!CP®ÅÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿïòôÐØÚ¾Ḛ̈°{’’i…`~xPl`QhUNdRNdRSjTZsY]y\^z\b|_lŠi€¡{„§~mŽfZ{QQxMb_^“`f™hR‚VS„ZE[Bd5”l,žs,›u2!¦ƒ#´“(¶š=‡€ §¢›ªˆ†‘‡œ¡dŽŒJ{u5zy%u}Zd+Ye¨ºÁüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûüüõ÷÷ñôóÜäåÂÏΠ´­šY{nKn_EhYDhTBeO?_LDfOHkRHhOGuYD„g4mQ(Z@1jK;sR=vTAxU;sQ<{X/rS5†c2m%”s0‘xC¢‘M¦š&tn7¦™>¾²7¶£3§”0Ÿ‰,•|*€w%fn7kt¥¾ÄûüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïôóÃÒÍŸµ®­¢‡¤˜kŒ|_„sV{iHq]?n]7{i7zg1p],gQ*`G4jP5hN9mQ:qT4qT5sU2ƒd%”uA”‚S–ŠSŠ-‰€ ¬•³–œƒ’x š~5˜‚²ºÊÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñöôäìêÇÕÖ¾ÎЧ¼Á–²µ|ž¡p™›]Šˆ\‡UƒyQ‚sCsc»(Žm ž1%¾×>ÿÄñ>cQîrŽ_®&ón>™kM7â#““ÕÒøPÙÓ®ÌÆjä¤ôiàܦLŽó¬2KŠa #¶P,Mê\Eˆ %%ʰyµ{ ‰Ùæ.çøeêÌr|êè¢;9:7y0?`ޱJ$Jlà™f“@Š @EŸ¥‰2Ãun°Ê<§Y£ "&È1&@±D„¨&G‰)t w5Ç/GÂ{¼}pÎ}vôáø€kq\.pž)KLL‹ŠmÚ€¡b—’ l1d›Kf–«Œ)qä#”€,‚AgÍ´%'¢â®æøÅ‹˜â`ãÄáæÇÇ÷…ÇÒËò"AΘs” ˆqäd@ ¤d•ˆ˜ †”Àˆ>[ÂBÌ.K â ‡”5 /ã©ÓÂáx‰M2,ŠcÈ*J)J† ô0ô)Yã®çxw„|àðÒß蟎'n•)¦è±ËyŽgآǥb@IE ±<ÅŽ1†/bb žcH…Á«x*,BINx “±D› 1ž:¶"gÄ]Ïñn–ìý'æÿãa–\°=à[ôèñ·HùG¬‘P!BŽ"$L¨ó[ÔɹŒ²NŠAÈIè±É61h°AŠ£† ŒñXrRb”]”!Á—als îzŽwcÉ>´Üû쨗6‹,Ò°É®³F`„Pá鲃% "”Š3X6i2dG G…²C ¬3ML`DÊ ¦ð$”(&Ä@„'A€€àQ,Š, Üõ?/Ã"÷Ÿêü~¾\;J‹Ãá ÷ñÏyš69˜)r** "Åc8ƈ OŸ0!cOA—YÖ˜fTd8tñl³EŸ&M&$””¤@…Ãâ±1Ëû€ãç#,ÚŽÏý§ãÓ9jTXÀQ²Aà'ø×Ì"Äx¶I‰è³Ç0¢F- g)êÄŠÁ“²Ì9I…C°Ìó4%ëDÌ‘p ÈIqJ„€jÏjM,†»žáç3g>p|îÇILŠ#%ÅQ2"#aÀ„“|ŒLS0¤Ï˜˜eL…p‡AØf (9ž!®JIŸË,"ì)É)I0,EPbiEã¹ë9~³ÜpþoÍ∩a°Tì²Æ*W€G©± Ü`L…9Â3\ưÃ.Ç’ xÆ@—Ó¼H&9—¹Ä9–S±Ã(Š¢XQîj†·C8Ô8õ¡álZ“Œ””%&Jr JÖÉHðL0ݧ l1Ë.kT”(žŠ@À0ijáir„ +”€'¨ÃÅR¡XïÏÙS‹®NΓ<Ãû†ã혱§ï3@djŠa¥d—‚ŠŠ‚ (±l2gH@ À )êÌp%„ ŠgÈ«dÜCJ ¤IÌ:¢aDN „áûÀRÜ#ç‡|SƼo8~¶”æþæäxº‚a ”¤$ Ø”€à©TìpˆE€Š‚ 2F”(pšoS0 Š>×1XšäTbæ¸Ì!Eñt‰™–ÊŸ‹:X[ ä.Û¼8~¶…æ‰ÏŽ>’æcˆñ‚§ bƒqJÅžëÔi£ ž‚c@y.˜'ÆQ²ÎuNs<%c`D `q,`ñÔˆ™ T$áCÙ™ÃÑ /ò¹ÂûŠãg©qàŸˆØg±¤@¤(Ö¸‡5¾Mij4Șð2*æ¦(ù!*/ñ>ãøYÚÇ*æj°Ã ¤,âÈ™0bÈ ŸÄqƒ¸ 8Ú9 rAQ„œ”ŠœEéÓ%°Ê*æ9Å4J F`‡Ç#ôÈãˆG@1X&á‘øø’k1äû|U.ò«%"” ù…°‚òVRî}¬ý%{Ì)‡ò]Ö¨˜ð2³NÂ4‡Y$¢ä5*E¨±%A1(ž193|”žK(OII…'%!%§"ÆàɈ‘ðHzÏ17Í„ïñ¯ä¿Z-î5÷»ïð²ŸN‘0¦à]sütS­ùOUS™cƒ r„ÃÿËî¥Ë ™3R™bB@,PQ£Ã.) Vd%}J‰FdÀ£X,}ræÈS§¦^?Ô<|Ìtó¾&«üjÍrvþðçø¤«Ë ùQö'KÏÖ¸À&Ê»âøij,ÏÇǃÊÓô€!5>Ë ^à+ÄôY  !Á¨ðìÒb•€A‡#zl3¢NÉfy„1Ï1¤¤¤ÄQgD KÁ.ÐÃPPÃj¢ÏÌ–&;|—¯Ê ~µNröDíKòÑæLnT£Ó Ÿè¿´ó§ùWÁIÅ»àøi¦ÚËÿþøHzá291Sg‹PPG<ˆÀ9Ö“àP ̰Îʡà FxJ, C*`äd4)ÙÅBÏ<ºÐ9,)k|‹?—m~µ–¹ç3µ/5O˜VaØÓ ­ö}þ­6›\×âù¹9ÞšcáTõÙDí.H˜ðx<Û¤c— $4H€@EÀS§Ç€O„`ðŒ3b—1 œa†ˆ«@Ÿ’À¥"  ¤ŒáhQ1&Ñ,<œ=œÎc¸È×øžŒøÕjqìÓõ¿Ù\–ÄöXµI×·jÙ=l0`…wÁñÖzÙ¡O–Kµ5<;”äXJ<S±ÉYÏs„E< xÊ»àx+†#KíÏ[²C‡m¥Ãbɰ Ùä4)è3({†Ú\§@˜àh1Ͻ|ƒˆ.c <# [”4)Ù(P1bŒÐ&¦¤ C3,¸3‹Í%ÉØå þœó¢üªé=üõÖ}YRr‹“,íicÊÎPðßç†xÞÇ[™±‡w´)œ!MÆ8* fÌufˆ¹Ìˆi,Ϙ”ˆ6M¦ˆhàYå %Šœ e$€0 ©hÐCPr‚ÖôÁöÂáhå2ßà;2à½À'›/ÏÏÐQck¦ëêS2MŸ§ø./ˈwÅñæbŽžl~²ªl‚ã:Ó$L³Á#¦Hð”„>1¹Äe,B‰Óeކ G \c„ Èñl‚Šbr @X*Ê~h¡}XjŒy–?çG’ó³ ¯Q~~Â+”7*ÿêÙïù¢ž'e\uœ¶CÜ!á"Oó—%ç­`hp'eB‰rÇ››MO||2ÈviÒ ba!a‹-  ÀS2Á³MEFÆ<=290â:/%BAÁ%ÛÀ.‚Ãâ0<ž»$Ô4 ©?lçÄpƒoó—r·& £A“kØ£~‡U6ð¼9ƒQG©Ø&ð ¡Aƒ.]+Üä ÖXeÈT›dY‘öq~ÂØv¸Â:} ñ¼‘A€:-flƒÈõ¦STØ£ìäãu…Ëä¼J„ÀëÅ|ðÁå?’4Z¡ \a@ Á`©Ø"¢ ”˜W(9D›¡bƒ-rÆô T@%†KI Â"  8*&ÔÉüœy ×;jÚ¼À×ù¾¼•=¦mתfíN/ž1GâØžüxôüh²Âe®G<=ÇLÔ$m7gÌÊùͧÙ!Á2…¥kM·{Ñ‚;à¬Táêîó£ëÛ¼Ä%ÞŒb­ÚnÁ&¯'Ô˜fζ-Z›jÏDÇ¢Eõ‹5‡°G쎶?ø;+¤ìˆçÇ›™©þÝòD¶Ã“L³ÍG CÉ%"¦NŠ!Gˆ¹BBŒÅ˜0d• Re‰‚3B‰‰0Ä Á€€bQ˜3Dg–²ƒ³Åãü—Dysޱ87³dŽ™ãq£˜¶½4­jbŸåÉý7zßÈ)q½³ÍC;×^hزYpÍœéÚïä_x¹N¬­ƒõlr*<Ò˜j>ƒØ¢½wü¿u« «ìi±„AQµ¸Õ´¾~¤y:™zòï¯3Ŷx^1Íq3Ûi‰ÎD£F1禣:qH­-Øg0I}~Æ3Ï&<·8~RÊò²ûÆ8N“óm&(ŽCPb e‹- ˜ãÔ±”]*:´¨¨ð”(ŠAƒR"*2átᘛCy™¯óo¥Ï[9Ê=‹SŸ”Gãƒiݧê¢(˜1n Ìõîmfåkß«³œ|:éÍÕ«FèÆ±‹B¦Y°!TÏ–ÍCÇNÝ_?÷|/­Åµª¦ñ {sÑ¡Çw»_cÄM÷휊 Ô†4?hÅ­j6›*îirŽÂ6PçKG{Ÿ‡ãƒICãEQ0¹áNVÅdÉ´oa†aÙçøIÖÒüBêY¡É n±KŒ1%‚ G¥ fœ>c„&-,‚°KA Çæ¸ûi˜]ÖiÒ¡ÁZ(†Dx2fÙ`ŒRZÔ‰Q¦È¡L¨P„ Að(€ X ž€! D ž%¢NH—>É×d•·¶Ä½Õ¿\¿ÇdXcÓºOÔO&å$‘ ^¸%Ö£GÿÞö—oP°úÖž¹jî©N‰ñÂ>cgOÏ&¢¦«bœ*>¨A½°Ïº£‡×®Oç²CþøùûÖ§¼°Ïª( ”ìYâþ´;~(íVqVm\s­*Œ]Ÿ2QE½X’dÚ·¦¥Ë ~Ä%Jö9Þ(¶³†ãñEF (éÑã c„” 1B@‹„ ŠÆL°ž1€ Êž ‹á6% ƒRJIB‹8»»þWëΟ´ê…[›p‹U—Ô¥[˜ÍÝíínÕ±ê…W¹†t˜h"«¬üÑà?qS´Î ¯pD PãăÍ/×ÏIVÀj”NùVÍõdT¿Ø ãªÏ(.Áº®oµ¥Ëó¶DÙçx£éÚÜ£¡/[œ¢ÉóÔ©Sg *,ŠÁPà€ÅEÈr”( X,E0@…`P@K Fƒzø`}aYº xœ¯È6?ÍÉÞÂïDgMæÙ#i<§µy™a€Zzëù¥Ý²:lÕ 7Y:Kp‰1»L3Õ?záþ)z¼Õ(íùNÇu¹ž×KÛ§ý,w¶?Ì5¬&’Sý×7þÞµäU/ì‘ÈÇËép¶·ð¸³¦^U$Φ|gÊ,âÙdâL“†›#™L;ÛRi±Æã<Á¦(¯r¼žaæ¤<E²L‡M~È‹4˜ Ä8 }r CCOIŽ`08Ê x<ŠÁ"(Á°'"P¢4¨…ÔŽIƒ-¾Ã7dƒŸ¦Åß2nd7YuiWk]©ñ2?äú¬/Úÿç¹3ÓÔØg{ÖŸ·cÉÑÿ"üãµî¯cÕ&=ßëš” Ù]xñÛƒÎGmË û©‘R±güµg.ß·@Ì-"ŽD(€frà?Š>Þ¨—ÜŽªÓ5³ôyŠ§Ø¡Í´ÄY/seL#JéóßgS”;8^/Næ Ýh‚0¡ÅYÖ‰h²Æ‹¡Åbˆ 5ðL9^£{‹àQ % ÃóÕ=™£Òd›?ã›Òç§;²ØøxÖ- {Ä4Ç-+Cžá+Òç¶ô?“ÒŸ®³ÏÓ–%»@yƒ¯¿èåUVkÓ­™vyš'åEÒ?tÿ«¶„W©„4¤¦ÀJþ? ÿ¯­úûDuÈy î>Ñè–†=bj´2Óa‹ò=nP“ÑfŠãÑCÉ%žfC<¯ãx½^6ýa}<9uzôiRÇóc ÅQ0¦Bp 1ŠÇ#(ð@ÀP` €€àÚÔý©lö´Øå;|Súüt søÓÑñÈUÜ"j/Ú«ò4BDa f/ÖÚ)¯©³Gÿ‹Éçw]—×Hê:b[ìò4ß㮸X;#NÙ'bƒpÛèòâe=‰a¢^²ÊBràSnQ {¬ÆI×G)žæ»\“ ë„]6Ùæ* k¼,oàx½¥Cѽ>˜k4ȸB å)fDLˆKƘÁ ""<Š`P ‚<‚ KñsnvIìò|]úü,Ó³ÙÇêmo¸-T/Ÿ?·› ­²‘u§öT‘8áŠ#æ¶Ñz´Áp›U5}šPp™Ç¹$ tŠÙÜò*«‹±DÜBv©vØd[D)z÷¥nf·ˆÉB*®ð+Rq‹(•î2ä*‚â¥à'8îÔâÀçò¹¬A+”Ìp‚Enp„˜Œ>`Q”PRJA‰ (Š0Å"(`0@À#bÐCæþ…¨Å„Çùšìð³uOÚÖyö®¸ÿ2çÛÃ8©¦e&5€óµæœ1WIJ‚ç¶PÕ7’%‰•}‘«•¢lð W¥bÏâ¡d*6žW‰u2B¹E£~¬Â¾àu„ØÆ}fZ {¬—£lò W$ç¢TT¼%ÇÒ…Ú§EMÌYrrŽNr‰¡ÄPQâKÀ’`É @aO@E1ö ž Á£tÂýSi‡À‹ükÙám°r&nãÙgiÎÜ'§lÀEV]ÁMFÁöY•Œ$¦åu¹åUbW®ñ²ŒÙÓbéAÛÁð 1i•Y:ì"¼ U’ÕNÚ4°Ï™l$JŸ‹ yGw’¹P¦ç1tx-V¸NDÅרF±K ðX €!Ø£Á (AJ!"ö¥ížx®ó5¹ÊÛ!$©:å‘Fš^#7nRÕ€F>‰p~‚UeÞV®±ÍËÉÅúÇêõÀ>«.i–Qƒ’ÏO°$è¼.fQà1‘ÆìŠòŽ8îd­!}‹e‡]@™§Î€Eˆ0äTJ< (‚bìA¥$GGIJYšÀÃK¼=1µNÙg±ÖÅÆö‰qš`bE+?ö‘SoP1Áó&œ¦¥\”‚=£ÃŸwÇbW²OLFÍa°FÅ›PÁ@6^ nó9^#´" ±½ÄKl³A‰ç<ˆñ(K›m* P Áã,O„CØcP„@I@,CÎ4#KÎs|_”·iFæQö‰éMZ±iÊ+ÄXã -‰/&q%׹Ο$ÆF#ž—5Àr‚cºßl·+ëb’´S%u<l‰çM¨h FDPö…JwÉÙÂó9^#YkN&±Î˜13L(ðL¨˜0XjÄÀ x{,  )–=ƒ €R¡XÀ TXšÒv²EÎ_ʘ·OFÙ'¸AZ'Bñ¼Æc†R0fdäìð‚lðf$ºÎËKæ9š,ý†ûÝl §ÜdULšv¥Þ#å—ó&4QÙÀ¨áu4PPøi",çUŽ×ˆÆ³24z\å2«D2MÌEJ< † O…!Pa0({A‚ @„ Å!xŠàÜÇä\â ?7ïû›½—™B Ü)g‡†² Xf ¿áTÅóÊ­¯O K0 ÷4?'kÏU©ç&«6ª»)“Ι×yËRñ&¼˜0‰[^¡ª0`DÁO3ÅÉ ý§_Ô¢Ü⸃“)®ayŒ#¬³ÉE† ¤RöJ!`,%‚â1E±(`P<ƒ' 5YŒd›ŠÅóö©-±ì 2ÌvŸjgÌëyɹ-å¾z÷óÙç¿2¦¡7Äó:•^>8—ÊŽœNÖ×™Va¸ML³êeÙMÖxŠg𦬊ÅQ%cë1ܦåd²R›0åÍ ¹ÿLôùìg~oŠˆëÜ⸃ÁsUVÉqôØdEPú ñ(àPJÀ (Eö`0@‰'{,âë2'±Ñu¶¸Ê;¡«ýñ.)¯*jOnñæ„yN´/ûüø÷²É o hç¿;2˜í6³nhxW±Ï¨»:5JçyšçÙå-™X£‡JñnñìußÛåÍ9î5‡®}©óÈÆý³Ì°Ê*ûw%ŒÃ!;äå ^£,B `P,JE…'ÁP^ % T ÂMZ§g{±7›¬;Ë;QÊxh¼Á³O›;K )QÞ¨ÅsøTû‹î¯Å'Ç“(;üC­óX»2Wî䥎ŸL¿)åg5Ž©·ó æÙ§ÙÊ‘s›TÞH˜áT²ðÅä·çʃQ6ƒ²F`Ÿã!´ø 9Â6p@ŠGŘ †@ÅK†ÁS‚EE€ %àƒ  ‰ÍLÍH(ëiLƘwBW*ÏkÄF‡Øxr@å51Kœ˜Ÿÿhø\vÖÍK³!1ìJˆZ‚r“U«±õÂëÅò·øß7ɹÎo$¼Ž(­jóFy!QnIæ¿8ûÏvÙåõš,›¥ã­ßqŸnΕ­¬aIJÃ6ûwP-|›Š Gð*‚ ‹Å X `  E©*68±DÒ²Í(Å•!ªzv ñ¶Uý—7ÌŽ}†æüï-=7—\cˆ ¦8Ú˜{È}>º7›*ë´‚‹ ¬±ÉbÏ«´žÄéx”£¢^¸ƒ1Nþán÷â?ŽXçÊŒáJ(qãñ÷w)qÜbˆg>wøŸ­0Ån«q’ÓϘßÈND­2q­27ØÏ>Çk4ŒÇƒ­l%,rž]‚Ê‹G0xÁŽ‚ €BÀP„Š "j&#M×umWÓT­Ó–oÙ±Rñvm=Ñ×›‡¼°/vžþoWÿïüÅáOŽcfº{\>ãṅ¤ˆHl½4}®2fO;ª×Ô)·˜(óUevüNYŠ/¼*æPëˇæVþzžrœWM…×_Öˆsã®4{á–ÈœYþk\=»Ä«¦Yè-~Æ}"YŽ»U\YlŒeÌuƼÊñm]ªí4‹h(u"2 ¤"``OÀ`€€ €EÙìñ …ŒšiØšLÛ¶¢†Í4ÂF&¦Á&ïÄèúÖùhjÞÆ^¸ÅPË>yô¾ñÓ£¦wéâÞôP4’ÒÆ¦gu©¸å¨Lg¦àE‚ŒâÖLÔ(wò¾Ö/¼Ê0ÝþÛÏÿŸ¼Øâ»ÜÖ”vQnñâ´X•ÍgÏ´cÛ^¸ÉPO?yüTÿ[;_m¯žíë\ûLø¨ý`½ëãÒbK„UÖ(y•ã5ÊîlUó¬³F x”Š€bÙ£0ƒ°Gñ€¢({< ÁS3m×r±sZ“ºmD™‰Ôæ&— ‹áí lÿÝÑW]xÐ/Üb©…4™I±…8Jƒ+ {¬Z[+l ç nÓXãÀ>õyÆFÔ³N5Æa,ЍöYZ|ìØÁÍ?ºú•㬰‚¢¥h©î<¯0eæOþWáÛÏñAk¼p“¡¦Gó­ß¬Ö‹QÕ®umÛ§¥á6±YåÊ*Q^å¸Óäz(úýVf¼æ¦’€Ráˆ)‹A€Š€¢ A £‚âÄà$•š©»šË¬ó‰6\ÍÖLdl6¸Â vàyÛTdr¹8ôüJ-?ƒ ^¸ÅP µÀ¼€˜˜ Ö(¸MÀò ¥2~Í )5šÙds´+¹³‚za_*ËÓÿeü‰Ëÿp㙘 J¯F#eŸ"Ž¥f2<ôÂFwrTcQ/Üd¨‡Ì,¤€¼"Äŵ±Äì²FÁw*®®ssEš…(ä2ÖܨX<{D"À# 1HPC,Œ¨4‘š©ÙÔÅâ°eê¶fRã šk¼ÌUv$çÒCrhe#/”SêCPEöƒA^LÔ¬b¥bƒ]Qn IѪê)"Üd"-®àç¹Â9;?3Ó¬åcõ‰á&å&‘ˆZïK½/ì]ˆ.ËÊsvVb+ìk¦‹íftV¶¾ãûKy× ·ˆ1"ÄDÁ:+$Þ¦Q’vésñÜÁñ*ñ¬ÿËæÿ¼µ³41ãjb™„‚R*àŠ"VVAÅgU NŒI%u‘M%ÂàBL%6ÆÍ×9ÏuðމjAFl[³®²e¤ÆÇ¥z‡$>28AUnë2)¸Ä Ƽbòà ˇӺu‚zÐZ”qž5†¼ÀÇ9—tlMÂØ„º ·‰`L*n&ê \aôؕó®¦F¸IDœ³W¸ŽElÒ‹›e>,kUƒ8MÔ8µ˜ã¨Dâp ÛÜ`Èë8^%ªVÿÔüƒóaÎFU'1•¨©Ä4UB‚±êŒœˆ‰$–Ä#jÄ'©5Ö©S‡ ÎDÆ©ËíØlsK¬HÎÏETsÆìÒs7ᨈqXR,%·ö b•©xEÿi‘ÑÂRRB›.Ž •®°Ã&÷Ét沄áG†¥¢¥"+ÿùY2R„Û '—㉨EIÔ&#A€˜”@Ä@AN¥`ÄË\¤àuw (ã§^>ý×M$¡4>BÄxS©^ƒx¨°8‰„[¬$Ɖ$˜€qbÕ”±:ã‚ñ6Ø` 34[\ã*;Rñs¯JÆì2CJBƒ ÁPÒ'' Ü0úœ§Ï>™¢Á:JFTôQÏPŸcyX¤A¸ÍW¹DW{tS Üf€’UFtØâ9¦h`C`DgÈC”@Áˆ’œ±(¯#B`ŸŠpÖýÕÇÇŠPxib,Æ[AÁ{ãEQ,`ŒEÔ« *"ÎXP ¬ýÿÛƒ·(¢(Š¢síSUˆÁÿàÿÊKľª½—M‰`ÃK?ÔHÕLŽDÄ<ÌÑ5Ç6nøÀ'neÞ̉@4&)Ì΋‘ ` Zx`121Ñx"À$™… Fž0­NܘivÜrÃWíXýÕÀsò†/›ºê­äÆ QVØÆ”†0•2µ0“"h°A³ŽÜµ={¾qÇV «xF‹Íw>Œ´‹Õ„`i–ä"vQ’L²@X'uWKìØrdÏ^Õ+ ¼ t糈÷ºÔÑMKœÍ(€)I'i𤳧3Óét’Yfõ*Bˆâ¼ãЉ` S@LR,&éÌ$‰I%«ÿ$„(^°iÜ+̽Lñ(?™{%³z3¬ÎF°:+Áꬫ³¬ÎJ°:+?ØzÒl~emJIEND®B`‚eric-6.0.8/eric/pixmaps/ericWeb48.ico0000644000175000017500000002267612310120025016355 0ustar piotrpiotr00 ¨%(0` gw"ƒ, : K% °iB ¥U& £O# —D" Š5 ‚+t$!w ‚*3…0~9ÙšK)ÿ¨_8ÿ¸xQÿ¯e5ÿ¬_1ÿ¡T/ÿ–G(ø>&¶‹=(UŒ9'u10L ‚4)C@,¥šJ*û¬a/ÿÂ…Gÿݶ‚þîׯþïØ±ÿèËšÿâÁÿຆþÙ®|ÿÄŒ[ÿ§^3ÿ˜L/ÜA/vv$ÿÿÿv'&‹>5†¡YAí¶wQÿÉ“[ÿÒ ^ýݲtþëРþøèËþúíÕÿ÷æÆÿñØ®ÿéÍœþäÄ•þÜ´ý¼x-þ³m1ÿ¡T+ÿ‘@)Å}#K-ËÜæ%¶±¾\•K@£ªeIÿ³l6ÿ¸p)þ¾z)ÿÂ)þÌ.þâ¼tÿùíÔÿüòÛÿûìÎÿøæÄÿïÖ©ÿã‘ÿÛ·‡þĉFÿ¶n'þ³j+ÿ£T'ÿŽ: ã{!V¡£° –hiïžQ5ÿ¦V!ÿ¯e&þ·s0ÿ¼x*ÿņ-ÿצTÿìЙÿùèÅÿûìÏÿûíÑÿùêÌÿøæÆÿìÏ£ÿݵ~ÿ½~8ÿ°h%ÿ­c(þ©]&þœN$ÿŠ4ây R0DOh^h€dRVê“@(ÿžO$ÿ¦Z&ÿ¬a%ÿ¶q,ÿ¿}+ÿЛJÿà¸pÿóݯÿ÷ä½ÿøã»ÿ÷à³ÿöà¶ÿôݲÿðÕ©ÿéÅ‘ÿÁ.ÿ²j$ÿª`&ÿ¤U"þ P#ý–B ÿ„*Úu<;]4`CPІ7(ÿ–AÿŸQ'ÿ¤V!ÿ®e%ÿ¹v+ÿÆŠ<ÿØ©aÿíÑžÿöâ¼ÿöß´ÿöÝ­ÿôÙ¥ÿñÔœÿîÏ–ÿëË”ÿìË›ÿß¶€ÿ¹s&ÿ­e&ÿ¥W"ÿK þ–Bÿ“B)ÿƒ(¯l /BTAF`sv64ñŽ7ÿ•AÿŸO#ÿ¨[$ÿ²j(ÿ¿€:ÿÑ¡^ÿÚ­iÿ÷åÉÿôݵÿóÚ­ÿóاÿñÔÿðÓšÿêÇ…ÿçĉÿܯlÿܵÿ‰Hÿ¯f!ÿª]$ÿŸO!ÿ–Bþ<ÿA2û~'UNªªl’’D`ƒƒW_~€[Yx{[SrxY>ckZ4ZfW8^jVfsM7`nE3^mA5]k9,UiWP=HÆ1&û4ÿšJ&ÿ£U&ÿ¯h2ÿ»{>ÿË–ZÿÆŠ9ÿÏšIÿîÕ¬ÿóܵÿñרÿðÔ¢ÿòÕ¤ÿïИÿß°_ÿΔ7ÿlj.ÿÂ/ÿÇQÿ¹}Cÿ¦Xÿ T$ÿ˜Fÿ‘8þ“D3ÿ„/%¨w±ÕÕn¦¦uOxxšGil®Geh¶2Y^·&NWºAK¼ÿ›I ÿ¤V%ÿ¦VÿÌžrÿ·o#ÿÃ…;ÿÏŸ[ÿÍ—IÿݲoÿÖ¥VÿЖ:ÿÏ”4ÿÍ‘2ÿËŽ3ÿć1ÿ¿+ÿ¿{+ÿ¸r(ÿ³l*ÿ´q:ÿªa3ÿšHÿ“=ÿ>&ÿ:,ÿ{$T‚ ¹Â® x‚lÂ*WL÷@7ù /.ü'*þ%*þ&)þ,-ý,0þ)5þ%6ý);ý->ý/@û.;ø89?üx.%ÿŠ.ÿ’;ÿšI ÿ¡Rÿ¿‡_ÿ®d!ÿ·x7ÿÐ¥sÿÌ—Uÿ€(ÿÄ„(ÿȉ-ÿÊŒ1ÿÈ‹.ÿlj-ÿƆ-ÿÃ.ÿ¾}+ÿµt)ÿ²m(ÿ¬f&ÿ¯f.ÿ«d6ÿ¡S(ÿ˜E!ÿšM4þ˜N>ÿ€)Ÿ~³Ê¯F}œqë-eRþ>4þ5/þ0,ÿ .,ÿ )-ÿ.4ÿ-4ÿ+2ÿ*9þ*;ÿ+;þ0Aþ1AþG=Aÿ~-!ÿ‹0ÿ’<ÿœI ÿ¨`3ÿµtEÿº{Eÿ༘ÿìÕºÿÔ©yÿË—UÿÈ>ÿƈ4ÿÅ…-ÿă,ÿă,ÿÂ,ÿ¿~.ÿ¼x*ÿ¸r)ÿ³l(ÿ®d%ÿ¦[$ÿ¯l>ÿÆ‹`ÿ½zQÿ R5ÿ¦fSÿ„+!Í…ÛÿÆhÃÝ ùE‚dÿTAÿQCÿB2ÿD8ÿ05ÿ.;ÿ-2ÿ54ÿ4Aÿ,:ÿ)8ÿ,=ÿ.?ÿOÿ¹u*ÿ¸t.ÿ´m(ÿ±h&ÿ­d'ÿ©\#ÿ¦X%ÿµo@ÿÆ‹`ÿ¿‚^ÿ·tPÿ±kPÿ'ê} Ì—lˆ«xú„°wÿCŠaÿ"V?ÿO?ÿ[Pÿ@7ÿ<0ÿ 84ÿ+-ÿ*+ÿ'.ÿ*4ÿ-6ÿ+9ÿB-3ÿŠ@6ÿ‘=)ÿ8ÿ–Aÿ³tTÿÚ¶žÿóãÓÿÆ”iÿÛ¸˜ÿáÁ ÿÞ¼˜ÿΟqÿΞnÿѤuÿÏ¢sÿÁ†Iÿµm'ÿ³k'ÿ°h'ÿ­d&ÿ©_%ÿ¥X"ÿ£T%ÿ²k=ÿÈiÿÏ¡ˆÿ¹xWÿ®hMÿƒ(Ú„ ÒÿÜU£ÒònŸmÿp±ÿ8n@ÿ#X:ÿTEÿ5/ÿ 32ÿ54ÿ('ÿ&(ÿ"-ÿ"1ÿ'.ÿ*2ÿ<4:ÿ}3+ÿ–D4ÿ•D+ÿœM.ÿ¿‹rÿèÑ¿ÿîÚÈÿíÖÁÿî×ÀÿòÝÆÿìÓ·ÿׯˆÿÊšmÿÉ—gÿÁ‡Rÿ¶r4ÿ±h&ÿ®f%ÿ¬b$ÿ©^$ÿ¦Y#ÿ¢T"ÿžO"ÿ¬c9ÿ»{RÿÊ—{ÿ¹vWÿ§`Hÿƒ* ·~¸ì·HªÄ€ñÂä›ÿŠÇŽÿA‘]ÿ-fÿ YMÿ;*ÿ 1,ÿ +-ÿ '+ÿ 36ÿ-8ÿ*7ÿ+4ÿ-9ÿ4LVÿv5/ÿ•B3ÿ³xiÿ²u_ÿ»ƒlÿíÚÌÿíØÆÿëÔ½ÿëÑ·ÿḛ̀ÿìÓ·ÿçʬÿÌœrÿ¸w>ÿ®e'ÿ­b$ÿ¬d'ÿ«`&ÿ¨\#ÿ¦X#ÿ£T"ÿŸO ÿ›I ÿ©]5ÿµqJÿµrQÿµoPþŸTAÿƒ.%uxÙüÍ*ÉÞžÕ™®€ÿV‘fÿ•È…ÿT}Tÿ%M7ÿ:*ÿ 2-ÿ 47ÿ/2ÿ24ÿ)1ÿ+5ÿ-7ÿ,:ÿO`ÿlDCÿ¤^Sÿ³xkÿÈž‘ÿ½ŠvÿòâÖÿíÙÈÿëÔ¿ÿéÏ·ÿåÅ©ÿã¤ÿæÆ¨ÿܳÿ¾€Nÿ¬c*ÿ¬c+ÿª`*ÿ§Z$ÿ£U"ÿ¢T$ÿŸN ÿ›JÿœJ#ÿª^9ÿ´oJÿ±jHÿ¯iJÿ•E6ÿ‚0'7p™ÿÿ¸ÿ¸‘ˆÇƒý¦×’ÿŠ´mÿKQÿ"S=ÿ :.ÿ :8ÿ 15ÿ23ÿ7>ÿ5<ÿ9Cÿ:Hÿ4Fÿ ;Nÿ9>Gÿœjfÿ®qeÿÅ—ŒÿÁ€ÿòåÛÿíÙËÿëÓÀÿëÔÀÿéεÿᾟÿÛ³‘ÿܳÿÍ›qÿ‡Yÿ§Z%ÿ¦Y'ÿ©`3ÿ¢S$ÿKÿ›I ÿ˜Eÿ Q,ÿ©_<ÿŸO0ÿ¡R7þ£X?ÿ‘A4ω3-ÞÿúS¯×­ñ»Ù¦ÿa‡Yÿ7mMÿ9/ÿ92ÿ01ÿ 6;ÿEIÿCJÿ7<ÿ27ÿ49ÿ>Bÿ8Aÿ 4AÿnUVÿ±zqÿÄ™ÿ°tcÿÖ³¥ÿõéÞÿíÚÌÿæËµÿåǯÿãÁ¦ÿÊ–rÿÈ’lÿæÄ¢ÿ´qFÿ³rKÿ¨]2ÿ¢R'ÿ°qPÿ›H ÿ•Cÿ“>ÿžP.ÿ R4ÿŠ1þ‚"þŸVFÿŽ=3zw íÿâ!’¯w͆·kÿŒ«dÿO†ZÿD=ÿ8:ÿ F>ÿ WSÿ <ÿUSÿcaÿQPÿJCÿ>7ÿ7:ÿ>9<ÿ©yÿÄš‘ÿº„wÿ³vfÿàöÿîÚÌÿíÛÍÿè͹ÿÃŽoÿ›J!ÿ¾„`ÿ¸xTÿ©c=ÿ¸~aÿ§b>ÿšG ÿ¬fGÿO.ÿšI'ÿžN-ÿªaAÿ®hJÿ–D.ÿŸVHÿŠ9/Üv)âÿä¿á«Ûîªü§»tÿ0dFÿP:ÿ\GÿTUÿICÿO6ÿbLÿ_Vÿ>Bÿ>=ÿ@<ÿD>ÿLJÿ(X^ÿ~TSÿ–ÿØÿ¶‚tÿÃ’„ÿðàÓÿçξÿëÖÆÿÛº¨ÿ°oRÿ®jHÿ¹|[ÿ¦_=ÿ½‚_ÿ¤X2ÿ•?ÿšH(ÿ“?!ÿ•?"ÿžQ7ÿ±lPþ¾†nýµybÿ”B2ÿzffÎÿí+ÀΥѡcÿ1mKÿYCÿnVÿPIÿ HCÿ]HÿcFÿO=ÿ+ÿ-pCÿ@•gÿ1~[ÿO5ÿC,ÿ;Vhÿ–VSÿЮ©ÿ¼ƒÿ¹…yÿÖµ¨ÿìÙÊÿäÈ·ÿÙ¶¡ÿɘÿÅvÿ¶z^ÿ¡W;ÿΟƒÿÈ—|ÿ¶€kÿ·{fÿ§bMÿ¤]Dÿ¥]Gÿº€lþ¼„nþšM=ÿ‚(‘]U׿¢¸„|¢ÀoûXšaÿ#…tÿ/~mÿ6nTÿ†{ÿy}ÿ]gÿ ‰ÿ"YIÿ VDÿ'p]ÿ"{nÿ€€ÿT^ÿ6=ÿ ;Aÿ`\ÿ7F?ÿiQDÿ ƒuÿ¿ž”ÿÁ‘Šÿº„}ÿ·yÿ´|tÿ¬j_ÿ¦`Tÿ¥dWÿ–]Qþ†NFèy5.“Y!ˆÉÔd´Š†¢Ï„ûršhÿ\‹]ÿvÏwÿl³pÿF…cÿC’wÿ%d\ÿ\Uÿ1.ÿ%]Sÿ's`ÿ"teÿ$rÿ@7ÿ YTÿjdÿ__ÿ#+ÿ,ÿ.†^ÿK}\ÿiNAÿ|e\ÿ€umÿqkÿ|`]ÿlFBÿK/2ÿ()5ÿ;PüEV¯ev5Uª 3“Á¡Ðn¥qþ¤õ’ÿµÿŸÿ¬ô°ÿEcQÿ/YFÿ2g\ÿ>‰kÿ?€bÿ+e\ÿ9}nÿ0ykÿ!vpÿ4,ÿ5scÿ"‚kÿB<ÿ47ÿFIÿFAÿo_ÿG7ÿ|_ÿzlÿ MLÿÿ/1ÿ3@ÿ.Bÿ5Gÿ4Aý?Q±Rr7Ø¡hi¢hð«éÿ¯ÿ®ÿÇÿÐÿ^fÿm¸jÿqÁ…ÿcª‚ÿWž|ÿ)YNÿG‡qÿAŒsÿ9†{ÿC9ÿ=™qÿ8v]ÿKBÿ)zeÿ1ˆtÿ(xlÿOJÿÿ%~aÿ&¦ÿG7ÿ$ ÿBGÿ1Cÿ+Eÿ.Dÿ7Jÿ1Hþ ;R¼ Ed?„Ǹj–n–—Íü¸þœÿæÿÊÿ~™yÿ¦ì‡ÿ–è’ÿwÅŽÿdÆ“ÿ.p]ÿ<‚fÿR½†ÿbÇžÿ.bNÿK zÿ8dPÿ,‡iÿ8žsÿ-“nÿ/xÿ4~sÿ1,ÿ?3ÿdGÿ?-ÿ_IÿTPÿANÿ=Vÿ9Lÿ5Nÿ6Rÿ8LþUAÿÿ "ÿ ÿÿÿPÉ–ÿOÒŽÿC _ÿ>÷¡ÿMú¯ÿRÏ¥ÿ.]>ÿV§gÿY°‚ÿ(_OÿMVÿDXÿ:CÿPTÿCHÿ BIÿKSÿ EPÿFQò-k{O’Š2J\]9JOÕef]þ|nÿyw[ÿs‹_ÿJiNÿ ÿ  ÿ ÿÿÿ4~dÿ?¿ŽÿT¿•ÿ(ò·ÿ,ÿÇÿ>´žÿ)]:ÿJÈoÿ=ªzÿ9hJÿ2ˆiÿ ƒ‚ÿ 4Tÿ#;ÿ(?ÿAIÿPXÿMYÿ ESõ1hyZÿÿÿ]~•I=Tf¸Db[ú„Ÿuÿ˜¨zÿUgNÿ#ÿÿ(ÿÿÿiˆjÿo¦zÿq§‚ÿ>à©ÿ(ÿËÿD¾œÿ?£bÿQý‘ÿYË™ÿ‹ºŒÿb¾ ÿ!–’ÿ Eeÿ ?\ÿ @kÿ6Lÿ !,ÿ (<ÿ ,=ö!HZ^q”¨%Iju‡BeeäfŠsþq†hÿ5=0ÿ†xkÿœdQÿ9) ÿÿYlÿc¶oÿ}°xÿAžzÿ£”ÿ ~ÿ\·¤ÿ£íÚÿ€®¢ÿ‹ª”ÿ‚ÁÄÿ0ÿarÿkrÿXsÿ Jsÿ(Fÿ %Eÿ7XùNlu›ÍËU|‹NOsv§YsjñDRMþ’ÿ¼‹ƒÿB4/ÿwŒxÿw¹ƒÿJ`ÿo¢ÿn~ÿVž}ÿ[¤jÿT¨oÿP–xÿ'fEÿ=aeÿŒÆÀÿi¸–ÿ'‰|ÿ*Š~ÿwoÿWqÿJtÿCkÿ?`þC[5a™”¼ÕX€ap‘‡¸nrjòª “ýgrOþ{¢\ÿb¦QÿM³tÿ`Ãÿ Ø—ÿ«îœÿ‚ãzÿ{Êvÿ‰Ç˜ÿ0~^ÿ0SÿV¥›ÿb¬‚ÿ!ƒuÿ"‡ÿ ‰jÿpuÿ j”ÿ[ÿD\þ@O©"re ›Ãµtˆ†V©¹³§´¡¾­¼šáµÅŽô¹Ó£ýÊâ¿þîôÖþÿÿêÿÿÿÛÿå÷ÆÿàþËÿˬÿT¡«ÿŠÖÌÿl¤’ÿƒmÿ‡ÿ)—ƒÿ†yÿ{ÿ\rÿ=MüBUˆaQ·-}iw|{–—0_zv\[vwŒ_€w¶e…tÔ~‰~뎗Œú¦³¡ý½Ðµþ¹Äžþ°¾ŽþªÃþo¦{ÿ*¦yÿ¥ƒÿA¦•ÿ_™–ÿA…„þhjþ=LÒ$DSB³ª¬i‘•d•Ž#b…wALrcq8cN˜<`M³7hTË"`KÝ'_Eå/dEï-pQõ7Œsø0‘…ü/ž’ö+ ‰ß5›Ž­BqOÿÿµ©±Ë|‘¼§€¯¶q®µ)q®§8¸«Kz§¢Ym£¡mP•’{D•“^U¦¢2„çÏÁÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿ€ÿÿÿþÿÿü?ÿÿðÿÿðÿÿàÿÿàÿÿÀðàÀÀÀÀÀÀÀÀÀààððøø?øÿüÿüÿþÿÿÿ?ÿ€ÿÀÿàÿðÿøÿüÿþÿÿÿÿÀÿÿðÿÿüÿÿÿÀÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿeric-6.0.8/eric/pixmaps/eric.png0000644000175000017500000040166312342634027015573 0ustar piotrpiotr‰PNG  IHDRÂáÔ5">sRGB®Îé pHYs.#.#x¥?vXIDATxÚŒ½k¸­WQ&ZoÕø¾9×Ú;;@¶n^€GT0ÀI r‚\ —VÅ4`s9¶"ˆ¨€€€€x°in^h/}úð*rGT8È%( IØdg¯5ç7ªêü¨ãûæÚÁ§·>age®ysŒUo½ï[øìGÿðÔ¿ZÝȰKY.DäVËxö@ìdà¹k){›ƒ«u:½=ýÕÃë¾²=ýÕk¯þÔíïõëÌ °Ä3¸›»Ì@<íääf:m«š33À€¸ÀD°“Ç_v'"'""wS°ÛT'S­UE ""€»9&€äæä "0ÀDˆç!09y<óÎ'wS3%2æ‘¿ÛàæVk­jB)p{ñoQ¼ ¹Ç/T#"0 …†à¦mŰÁ­º«;MÓ¶ª £f ;Q¾+ä{1˜ÁÃ+ù²›ÓþYLJaËxlÜ;gOq¬°°Ä{c0ì¦èt?Æós²Â2ºkü.1ƒÄÄ̲’²fXV,¹—ul!"`et7w³zhºÝ\ –ÃS_rSN×é:Óíµÿöîzâ¼ vW‘• û\Vm=ãÇ:“[uˆÙu"€Üéÿoשÿ®Ù»4·´UjÛËm2«äæîîjºm_¹»Ûöð€§ƒ¯™MV7ñÌRÖ± NÎ2ÆÓN‡_SÝèt@D–/mZããEÁân›Mu's'"aLÕˆH-_SjNDª.7ÃÍÕÈÜóžŒg0sf˜yžª‰@Õ݉™˜Á@ü†¶“Q<ƒ0õh5ò4ÙÞºôç$¢ªNDëQÌ};ÙþZÌèç|“ {eu±¬âôɰ×ÏÀ̤ÄʰŒÌ,c€ {D(ãñø Óá×ܵ/IY›MDT·§ˆÈµº«[-«`AœP‚»õ½!²Ž,ýüF`1Ý’Ûò% Cºø'—5Åv­BD_ÿ"mNÿ›”=°ÝždÜ»annÂâ³qâ5L§Ú„¥½†¬d:m:±ŒRÖãþ†ë¾€¨¯ˆn±5áyØÍÔ¬º€Õȱ?Ü­EÉ€Ý@_<2> ›MuÚn·UÈ voGºÇ9Ï(€ò\_'ˆdl_”ò¿fdw'7€™c›!ž*Bç2ì"{Ó=‚pD7´˜ '‹533AΰK Xy G["À…@î¦:Á‰V£hœn'òJŠÛ˜·;s³µƒíïù¸*RöDVeuVÝ\ëVÝ”yp.€D Xéne<zy©˜nYÆP ’_ \È=o:¹[„ )kr—²GnqóEÔÈ L’LÆX4–‘Ü´nÜÕÝŽŸó­DÎ<˜UÓ x 7°¸i„N–âî "7”•Nî†"ñƹ2HÿŠ)W†À…ÈpW×ÉüÐÝëtå}Ó-¯–öu›U€‡ÕÙ¯önä®fSlK@ÜÕMëö”ÕC³¿%²"3"bÀEdOU§ëÈ]ë¡ÖÃ2»öÔ5©#w®ym'"%rssRs‘øÄ‘a/îõØ©æÎ "ŠŠ€.ù0iß*žŸáæ¥@D´^Éz%Ã0æÒ-ŽIŽÅ—È2‚xÜ»¡é¤ÓA|;q?€ 2PRd®æZ!ÅtŠD!"Q„ˆºùºYe#û1\Ö”“}:ˆ[“e$b´OÔîQõ¼ì#\0óà®^Õê†"MœƒÆ÷e: … Ddõet›Ài[ÒØöJ2ì2¬Ï&° û‘Ü'·ºq×2ì‘“—¹GTu7wG»ëXÆÈF#fÓâĬFž’ÙPBwÄÆ€»‘Mœ#ÂF\ž¹|y€#j¢§}MÚ®Ó´™ªa(ÄÌÌ)ËwD‚·GêDDÄää^ÛÓ2À„È‚dæëêDfJ‚C"Vy¿ïÀ‹Dô8<‘Bî†!@ãnd*Å”Øè=ãnWˆIüݽ’“jU½BTrwòx¡¸9úïºÅ©v7r*ãÀãÙ±Î) #"ë\¾Õùïhº}ûšé[¬‚œ»ÜœŽùeŽ×uWWuS€©6ð2Æ -/§‘ ºÍ”3~…h ±{Ü a$nsqwp‰« `çY/rO+“y ¶I"޹鶝 D5cVÍ&o¹L„ ÓêÞb®»Ù”ßx¦Í?t723ÝšV"Ó:¹ÕÍÖJÙ))¤N,ljæ"QT4cNˆ€{f5•9&çm—Ï9ïHsméüü„ ™—"óî%,ªww0‹¬ã ˜¶×Â<¸)x™Æx+.=n ó 6ErçZçâÌRÖQCôMÀ‰çúÁúçT"9òy£$sQÝF=A`änœ–›"€”qt7W㨞Ý#”»MD¤ÅÅ.àÝFAÖ>luò"²¶qÈF/0Dïî,ËGˆ£¬+k°;Ë(eU§Ó\Ö/0×Ý‘ë¹õ<ËÝÕªV«UÍ f2·¨>zD^,©dæW`8œ'SݪeàRò{57(;)säN‹"2Mf€È=Ê|"qžM.Žó@ñÏx/¦>'1LÄ`{ù‰\‰˜yhg5>÷À„œß¶šÅý1¿M·ˆƒÈ33Uµ©ª΀i_1Ì+æùiÞKñÖÜâüLÕX&ÓIëáöôW!¹* nFdž+X­‚‹ {,£«µàN@FÏ^òÄ>@n®q‘CAdV™,Z™K83Ð!²]W‹T$€8<4SV|nZÀ,ƒéN$5QÅu«‘óæ!ƒÄ3œpöT·¹jÜ”Q'yfÖ›¶IcÝ”ÜЫ Ó¹L‰¥Ì ˜"O'"ŽJßh”QR[Âs™»qYE:a"jRÓjº9<Ül'k¥ ÇU7'7½Q¯—ó;±ƒAêË+oYãGîÙŸ¡§œýIÖ# FCasÏ€ÕÒ—Øîʲá"P›nÁeYùBÓ 81KAVŠÒ×2˜)Y•²—@ÔUñ¢¦˜n=·1{K`~$²†G-ÒÌøB­Z\“ñœí¿E‘Þ¾™jVEVq=»‹eÔé\˜…Á¤FB^+qõ«y¨YȽdlˆ<ňy æ<~ÈÊKdE½vƒ€Å]ƒSfÚ=…l‡r2«3efæÁLÍ´ªiõ}Ja†093˜UriÄ¥£W-h¹D†(¶c£©šSüŸºyFFñ–AÄF‚±§(ÅÝ\·Dî‘ ÌûÞˆ(îRÏÐÖö‘É[ÎK ˆÚØEE"Ÿu_œ«E}r2wÉÓ«‡¦ÌàâæfUÕªz­nîE¸³Pa,VL‰ÌLÝMÕˆHD$˶LÕv•–¸EÎeºÉ\Ãjà˜}²,hå•»eÔÉ;ݶ"±yÈ]3º‚³ *j5*#öb±Ý"Ë‹°g÷pf:9ªÕC){RötºŽd <‘e•Y¤u\‘?j  nDLDZݽ´^úiCræc·û€ž zÖòyöƒº„ÞñÝé6øE¦’h£+ ¦›@?¢ÅMé(¥s½­‚8;Šó[ wÒzà:EÑܨBnsŸÈ‰Áœ½è¾ý{'†ÞÀ )«^õ`ã¦ÃjÊ%âÂeU¦Í×u:-²î85d b.ÀŒFQÆ\ÀC ¤Ñ@P!)ëÊË–ífëN,LDª&âEØ ãXÖëlš«™¹MÑósŠÄ“ÈEÐ NóÂ- Ä0â‡ÆW¢Óf³U•Â{ëôÄn¤á8Ø.Z Ðn?¹»:skáhÝ6¢¹:óVíy¡Ö‰ÈDJË×8o׏ТÌXœØBÄ=‹Î¯Yô‡„AäÛÍ¡9D‚ª}(lFRd]¤ Ù©´Zd""¦"Z{ªq$â0 ½Ó¦æ…,Þ^´XÆÈ‰úã7^fÍ}:™kfg‘¢¬ðüêª=èè5õ<‚Lî:jÝHY¸ “ê¤u“F$DŠš¿^§«nOÁ\Ȳ r"×m|(·:¬ÎnL w÷HHM‰À²JÙ€8“ ûfS@¨-aŒÈà:A†t¸ íŠÒe²“mìH¯âm·ŒÕlŠç%þgoÿxtZjm(¹ÎÐh@=ãÀædjÄ$Œ­zito•ë³eSËK•%7| IË*¾GÕøÅÕªtЏÔíA¾è ®Å®Ž ̃/à¦ZO»Y”q¢0Ä¥hVyØ[ÜÐŽrp@ß^ždwu­ÎBäus20øGv³Î¬@å춨ÛÐ|Æñ{ ’ÜÜÈÙ‚ÓKê¦EÞ¬êº5›òüZm×a>rÚœYC2ÄE·änÕ•KÏê˜ñ¥ ±åX>cÞÑþçÂe•áFfê‰ÖCÓíz=,r4 F‘ˆªÖZ3Ò«Z´˜b€€~I·¦|§þèN˨Ud¦ÕÌ£œ.E%s¢(«‰Ýk¼óDÁD–©¤)ÀÁÔa§š_Cà¡`ÌÐõN7?«N°0;±;™+‘‚¤ÁsH Ç3ÆînªÕÌTÝŒ¼aXCÖëqwÅ@3«µN- [´˜2×b©Ü="_®˜«yeÇv":Øè8°éäÅ"¢EÛÝÉ@»6Î?g>ˆ @ÍU-„àNg@HÐÚÙÖ;ÙÔf ¥Ì´ž(…À`©Óé¾J¦ÛˆžxÄÙÅŠô‡¤™OÑ sWZ`aÚšEî>¬ÏŽí¡ÓA,=‘Å]ÂRˆ e]§Ó-Ô Äɬ’Ã\áqŸˆxØ p-Þg–¨^{λ ‰öª ;H <>ÈY-Åž"ú™Kò˜L&w+C02XdÜ›­Æ×môq(Á…ˆÂLDÇŽŸ]¨ñ/o¿ÈcLmYÅ #¨”5³”º½ÎmbÞén5ªâiiOJ:Î+ØÏå€qÿFnÓtx2‘Ùéc­2jÉKT勦9—•™×¦`Ùœ1$#š÷›Œ²®×ƒÌ´buË*îNrça/“\W@âžÈΰÃ]}šw-ÿT?€n¤¬pW÷ 0m˰:+0‚Ü1@¬l#´¬ ƒÈ˜U^Ö5…Ëj„J4eÓzȲ2›(ËØݧIÁp#óï8FÂâ•ÂíêöH{-Ú¹wCïÿÜëP$¹DZ7λ€G-Ìed‰{ÂÝäZ™ºWõüORÖÞB…»‚ØIÜœÈ4ÉÄf‰xJÁ¢À@ª¦ê¥ð0H)Žv [ÓF<®µyň¬fªž¥˜1 À,‘å݃¹’g6Ë Å\6=} Q9›2jäähD`qÕF”+;0¢7«ÛÓw€¤uCDÌšnšÓYÕ(“Åh""˜k„z;˪D»’A–ö­PÆãăÈè`»+[V‘,‡fɰg:õ¶;µïdè04ËYI”ÞÑäéÈ/ Ô²_tº+—àÖ¸MYö+|:$f9šÎnà"\¬n¢â ÖcI$±”}"RÝdØÕmì+b&3³É½¸Ûj Ñj5¡ŒÇ‚Pʦ_l¦[7Sóí”Ý `/MÕ:k*LA;%¢"‰g$Ä”µÖ$”HÊ>KÏKâ8~ŭʰçn ˜Bà¼`‰ï\2mw-Àu: ²Øc¥ìGBåh¤¥6m—„ƒØu…ö³ruÕݶüfÙÇ‹k,nM×ÉãVë=¥9ËFÔïj“k%æíá˜ÙmÒ,FÑ@X®:Å zN§Ý­¸VÓ:S©¥4PÏ"îJY'=Ln,#x° Ÿ—‹éT·§¦Ã“:®ÛS‘Çó, .æ²à½'¸Nî¤Z;‰ZU™#c2H¿ ­­D²b‹›Õù7ü¡¥NR$™VkW‚Do×l«jœSIØiA0Èþ¨{­['7%'2u57w£DGD( ž{§ù݈à gF)¥dfôà$ÿ:‘%ºÐVÌlró Q1XøÌ‹’ªfáæ}Å:ɹÅ‚àÞLvú°N•÷Ör|¿˜n­æŽ6«›æá€ÖC€-ÏùLÎw3ÇóG>U°ewE„ Å„©u  3b^"S€˜wÏpÆÔÓ)Ø V#ËÏ[ÎM-ÊÆvyG?xÔ–u¢1 Á¬2«YK2»UP ­Z€ùÒwomÕ£ì!Hr¸¸˜M ´‰úíÎe%!âh͆($¥E[n€d’©n‚…¹ÞvúZTБ»;ëÄn¯Oã¨ös׈¨º=@U.ýÐù`(‰@ëõ^ Jòñ]GMSÊþ2ª¶BÃê„›FW=¶NÎ<J˜—ä™å:Xvù KT-ºÞýu‚iå†PIYõ"Æ«¡å1$¥ƒ¶ÁÕr‡´õô¶ß2?µèv öFÅŒ¦hìO2s²sˆ£…)DnºaY%õ5Ø#4/ÄæLBz‘äùl§6¦4Ð{ «Õú=pÕ©ÕºaP¢ 4÷"e°ÝNÎ&eHŒÑˆKYEŠ-ºÛѺ‘@»šJ'àh1EWY7›­h½.²¸nêhOh¼t7õä_¯ê¦®¶I;ÅR˜a yBÚ!.7Ì<òhŽ>xç vU¸V7F ö%'`à~ï¹Öº =R¼U/E†ÂS­µN¥ ›™»:¡”sa1jlÜv®¤C·‘á9¸l¶vúPOãƒC­Ç|EDÌ 9˜MYÆ;¼=Þ¢•Ipòqïœ.pšºM–u'T7¨Ë\ÍýPÊ:áu°ÖÓ=ÓÌì†Bºã3ysèü-&஡ ‹¨&šQ7ƒh6¹NI þ‹YÆíˆFo­ÙeQI" @¦œEKÓŒ¸a™[i°d<Ú ýöíPcëà/šf“9JÙêJÙÝYuˆN§ÁË,ŒÈ ã’‹šiÜ»aÝž6ÝH˰Ô* Ìš="Fp•T]ÛOÔ¼V‹˜n{z(eí¬‰ãâé4¦Ôt@’ Ûx¡)™rY·d ZÉ\m²ÌŸdæð°3—Ø!)u,r†ä=PÔÀŽ—e=B XuÃÙßGr±]°ÅzAÀˆpqRRí=À¼IÐâ&r7ŸâŒô§²ˆæ;¢›l?×)vÿÜk”®èµuùT4dãagˆ[&×É´F!S†uSjºI{gÃ0ÐÌÈKqeA7ìîé42sjM€j^Ýlš&0Æa4Þl4‡‡43˜ê"Ë«UµV¯Õ¢/9 < TÕÝ£¯êÑ"*´¢8J’M67 =ë|.MÝS~'RÆqÄj'‘Œž vyí¤t’;saNä¨H!r"WÜ™%•¸‹ÆN‹£¹b +3<à¨õV#Û+Ìwƒê†¹$²V;»~è’38Ë‘½åVžiašäó”ý•5¹»V.«®åÍgËw¢æ‡½­MD¾Q·š¥3¹%I£Õ€Ae!Ó lr¢’… "«Î uCnË$ÚÝ`ÚÕœ–;|yU¾Ÿ.®Óêd!èj„- ÑÑ’þ Ó­×ÉÝCâ0¢¶ èÐhå®dÖ¨ˆ¾hS°Q—¼ŠEXû‘Îs|ÞL·Û¥ jvô¬£È(ã¾Û*Xýe<ÎÓhº5d)‹^ët]ÕŒž¥ðPB!‚Þt>λÈ^R"ˆê!sîR Ôå6ñ‹ÒàE@XŠÖÖCN_‡ÙTÆã Èx̵êtºÃ5`ÑzÐYý9#kéróFÀ¬TN¹@¿Ñ§åžØ}Cõ4óÐà ‘­X:Œ® 0m{ػʳNÔ"º­95k£adÃë°È°UË*‚µÞË"S“Öà³DúMëöTòàZ·ÔÌs+kíô«5õ?,Ë5Êøã<[ô÷ׄ±ʺÏpZ@Öæ^«¯×½¾‹‡¶¯%8 ÔZ·›)\„‡2;]oŒ_ tŸñÚN ‚Hq×Z'3*q‹„4\âÎxak’ƒÊ®Z°`/®GoZ#wÒ  ¶d±b UK †E˜À-õóhþγ.j¥CP€ÈD°9˜‰f4i){îF¶(¥Ä‹æ.!„O–uãEf"PŽ%ý' ¹¬²Ùºä0oÞ7Y-™ƒ üë–¹DÒâ:,º€ ƒ•6]I RÊȲRM¥öf«äÄfæZ'"GÖtƒÈ0xÿ°Ìµ‰ñM­áùä‘Cz6ÄG³qX7AwéœÞÎ!m”Æ Tβ‘ÿ­K±p‹;VÝk£ƒ¤ŽÖ[ÚNîà2ªúfk§TÃÀû™åm³–,ÈêÓu)lѰ:+š¡!ÑétϬ»ˆ3tÍD)ŸÄ\T•˪S;[.¾”nžž[ùÞÌAÂÿbŒãêd etµ ²öµí ñ—q}ÃÀ‹Ü&ÓI†=¢=÷“é)#ŵªº·6•£÷\ |êFÖ²Tx}‚Ñ[ó®4ð"0 "0«Ñâ÷¼†üWX’Át²íaPâ .ËÕ–—IÞ—ÑhY«fÕ (n 1Ê*˜¯“QkÄB›M-cé¡|)5t3ö¸‡ô%éÌ%ªºÔ•ù°´àÐéÀ­&1vÖãy~ãVÃ7R,­ÛSfS‘I3)ëh͇Ô2"¬Œû­_(G×`H§$n4ò@4<´ŠÍI¶@,Hd'´ÉÄå2÷¹ïžlåû6Êù8%Z×Ñ‘o|&ß©¯›þ §(*ÄfSF½PßÇÇ`æðÑ»ÖIä‹ðYdNæpÜ8àצUˆRÕZg vÄM`ÌCô‰\à(““ªnÝ]$0GcHþöÖÖÕâfSv‹ˆÌâœÃhb.Óºaæ9}FªL=HË, ݘægô´¦²ž¼´Ljnbî¬í¬Xb©¡‚5#RÊ„Ý{^“ÔE·àæÅNÈñý2^|âX9q¬HY‡O€÷ùår‰&8“›T›(v{úªv$È@®U­±ÍòT3KYà:‘”ŒL' õé>ºi´h[ÚåËë9Šz­§;5mO± ²¨µA0Ù&o·‚˰:+Õ¥V•³Ã Ã^1˜‹‹Úá‘ ”‡AIÖÂqæ"Dý´ã>Ã’!µ]­4~œ])ÀuRÝ€Ž., K Á¸Ym¦*5]©§éQŒbS?Éñø‚˜å–~XßÀ=X´F'n•¨8[tüXÆÃS_"b×D4¬KN®›SMYmd‹ï;n)pð{jwN\ƒWЭ³š”ÞÌ”\Í•y`³#G ¢ï¿ý97>ÿæÃêìqÿÜÕÞ9Ãú†Ãú;ª…&¯À–g¡wQw”9Gš0iÅBËJ∜aѺլ{ˆÄõo¿NNœ¡sìv qò>k.‹³3–ñ˜¯o`6­öo”gÞ*íý-GÔ£^Óe=¸s4:µv± Xª{RkÀ…7âJtH­]r°A2© %ô.+cÑ-˜_b¡1Û½{–Jë}-qÃYÁÙXËUÝnQÿ¯Ë§=ãkB‡¤Î¾ÉíᄎôNf\ÂôÈ[ÊJ‰ÎÔ¥Yb~}’\:sý“6·ˆtرSùŸb×úrùMaî•™QwFQ^‚S½p¯9Ó/åhC)À¦fcã!ÃzGtßZ`²Ö&ÛÆöÝluixGD¥È0¬B^²H™)!Ôàºç Y% ~R4s×q Š»¶œÑ¾î^#¿ÜßY2㎫’!ÖeèÔq5¤¬ƒi¦é'âU«MS îúМ=ãýpzn&PK '!7fw·Õ*Mç2ƒNÓ ·Ðî e ‰7l®˜›šmU'"š&SsF“D8‰`W"ë…èáUÃX'»+]2L“M‡'›w™çzödª^‹ùh0[ö%Ó¢ô|-z"]~3ò–¸Ÿéð»sð£¾^:]zÈZᲚܽw£:IJmØ}Bu:M³ó¯ÏŸÎlÜ´*éV͸$Ÿy'·Úq‘+`ç†s_HFe·QÚ½G©éµ–æ#½¤X^š®iÁWq6º¾?G“]’uð¸§!½ÕjäÐv¦’ÒÉ;AIäTÓm€_qíG.Z¤¸8ZK®áw>KCihøŒ Ç NNdf“Ù¶ùé–PÂ@àHóVtcD$B<æ-0®¥HI†xwÍ85z8Lᄤ`ËS$ÐàvjËa,·i¸Ì–…Cs7ð NŽp2Ø35Ýj=Ì«²•í"‹ƒ‚&åªru³È›\ÈIöd^ÝsÌwŽ973uÆ™á2 ý‡Ä´ÛÀD8ëÇõh¨êöºÑƒÓ7ò¿ æypq0`GðuSš-º=X÷‹lkÖ#xS ‚fU"§EH3¿XX¦§õTjѽّÌßmã¥Ã™¨;î”J¦®D]Öûs5 ¡÷ÏѲ4«N9âŸX!q³ '@‚.Úm²'n8æŒz÷@yk7FÄiéÔ’!ß»5ÍóhUR;‚µ=¿×f¥¶£:[JŒ¼³Ä¤×Ê!ÕßÝASl³# ¡4øòzîû#»1í—‚–ïì†Ázæ3”3¿ª3÷},Oר-TÅŽú¿õŒÕó»Ùé ¦ÝƒBb$®! ؘyXêÍ¿•ØŸílHŸ˜ ór"˜mÍk6Ô€PÝ™n‰ C #·(B;òì7HȱöR—BBDjªuÃŒ¨Ü·®û#̃IFDóvj×s‰»š¼=xaê“e5™ªMÕ ©’§ó z1¼IÛÁàPÚØËÆ æ!}URט¾MÑ,ËÓÕbDŒ!¿Âe'¡ÇÍ]‡’Ù‹à(¤8ÿÊ2ÙtwKS3‡7gkùFÁ”–èUó9Ÿ{£pìØÈqrŒÕ Ë@Ù}öåiôtñ0÷eÂÐozÓ© ‚­}ÀD<|Q~5ø¯/ 1äö™df̹[zª•[²ô> JÃ.Úˆ,ê˜#KM¾„’~}Ë^Ç^Að…“1úø‰% tËæ¡?ÞÀ»”Hç d ’FéW©×Mú9ç b3£æ³{&…þHÍ Õ"ï`îè_·5—KÓm3`w­Ôˆˆ}l*Xë~kÿîÅ;( ™.Ë‘ÿOé÷Ñ<´g.íîTÄæÓ‚#’Yj+ýÒ§RÊ*6J³ðælæDìK–Á]L'æàÐ -ì&’…|±¹§0£Ì¯ pSæÑ½² á­W11°!°‚|c&K}ï$³Ùk–&ÄÎj“ª‹Ä7×:täÛÌXwjä`odÀí»'¬ºÐ‡€<" ´ÎËc›IŠ5{Ž£¹EîL(f[渊†E£?xî.A¤«ªAyšó;iÏ«¬ÒŽQÉ—ÌóaqçÛ"¼òŽ*÷xAnj¾/f¼yË/ßK*‰“6ثǛÝ~NN(ØpYù,_¨g÷ó#aìév¬Ô=<×+$J[?oІÈ9h>š»M¢uÒÉO ‹»)A· JH4¼hi*Œ®]|îλžÄq<ÝB+É„¤`/J¢¢Ý¼Œ )¼5ÛÁ4²ló ú,  Ôsòö¿y>ÒÔÔ‡ >Œ“=lD¦iµH+Õ¡¦ ªÛmL7 pPÆ aÞl’Ð,J(æÜ•"ez–Ò .v·á7·AfföFÉ[͵9[u·1bBœ7ãAÊÚû7‹ Ç„ËÚÚËì®êv¹‘hYºø×ƒU\Û"WN/´RÒR<ݹÅej®LÏè´ìÐIÊjÙh&6XÜý5,¦fç‘4ê.˜Û ýð8íGŠ[wc[ê;;Ê#ŸÏAêœ}|xM³D²6I¥4[6v³ö÷ªíNHHJo#“. 7)UÞí†ù!’SÌÖSš÷bks€¤”Â94×a™¯9(þi`8‡ÍÍN =V©A÷°–³[ҷɉœY¢8§4„‚h$Æ Y8^F®‰Í~:ž¶Ñ5?—Á9`YOæžÃvG–tÒ–8ƒ–~’4™ ÑNjæÿF!¿$8—EZ´·–=¸Þvì=»6%É;¥fV—{ôvÒ},>XdಊÍÝ’K ÀTJ¶»c†÷’Ï!ßcü »{lÍODÓÀÙmšQ“æ>¼Á¦°ðJÅÔŽ:¨MCÊNÜh ¼Y€‰˜f³€AK ©‘çdb÷Žj¥ ²¥«ÕH£Ôܶ“1QjüÁç ‘AdÕLªÌÝÂ3Ñ¬Ž’×u?Éh1ÀEFæÂ ,fÀtO¦¬¶ˆ(h@õ°Ýç…ˆB pôUû škÙC”ªgj“},’$Ëí²g¥{ǘû0¥áƒ²È:ÕI–7zPk—Z½E!ld”¹Þ™ XB%³Õ)VÍÔˆB¨ŠÞ~¬Ûèx£s÷ïb1Á¢Ö?”yTHFfà’†ÞÈÉqÍfš½a¹Ó¢lnûëiÓÅ‘$Çb2`'ŠE Ñ©ÊDð„h<7 K&‚1¬–˜Ò.@qXþ[#avÝC;CÁ“@‚ÁÉÁa‘†ð÷ óSƒ¹³“3Ü=ð›˜Ä–Ä}Á,Î6.*2.‡»CŒ(Áø̶hSº9¨aÒÞ¼mU“ìg“-NµhàêáuDg©3 Bs[8Åc¥«,Îh“v·¶ˆi;Ém´¸ûzoµƒm È´ng]`«ÍÔlË>Ú»Vš{ÿw©§à™O~w¡Ÿ8~GJi_XÌ™n`¼8O_Xt“xž ½P:õœqþOØ™Gí¦jÊ\‚ºˆ ºôÊ<’ŠMâVßþ½Í~¸œ}â¬oýÖ[ýÐ=/¹üò‡íí­{°KÄÄêÓÑ’Oä³4µ…A-ñJ'^ÎpÍ•OWñÿÛGx‘P\ #‘²v™¡³¦Þmjj4ß-¥»†˜L»aŠ5{M4WI#×Ûßÿþýo z#†!G‹Éo÷ý¾Þ;écïýCoþ¨-ššÏ®­@"7GX¤;\ôc~ÏkCô?,23Ïð¸0âh,FòM$`™ØÍûOãù`ï¦3³¥›ù †n€ ÉðÅ®v‡‹óÁw¾:ù-ˆðÌDFæ½R?be;!š!h¹%&ÙµÝyF£)›<ÔE Íè7˜ÏfÔ‹éçmN»lÛ¤¨j…\'µ¨8„YÊ9Ë܉™ÆRÔö4¹WPº ÍQ€(!¬¤$3鬹¤E1Z{nÄUgÁbÐ[d UÚ$ÂViK RJ‘b@„ç¨ô,£ºÊ ‚uTÖ<léÜli†‚©­˜´ë®Õꪊ 2H³`$n }´ÞXŸÐ4š¹.ëg0«Ûk¯è™1¸^¾íÒúiD"rŒlGØ&1pY†Š]ä´ëRBz&cd®f°;&w6´Å¤rÌCL‰>ó©›Ùf³ùÊ—¯úà‡?úoüï¿÷º?ø½×üÎ-oq»!èÀžó«ûikU-"{bfäDlj“D<KŽNèã[fÎ â¿¶¾]TÎѶqwâÈ0zéÊ)ì "¯‰0›QºÃâsNês$FµázMvI³´OÕürÆSéaùcûfpØØ6þ.°Ü òÙúqr"Éùä9ø§åáð.P&wbsç•\G0SG ÌèjDì\§¾­úˆŸçÏò®C‹NñòºP aN@ NÈÚ ]Lsˆ¬È‚ŦìÜ0ƒ¦'óæë˜¤x;¤`a.©ëäÛnº÷hVI÷%¨NgŠ®b²îjL+Œ·Ã;îŸÚ|JïúF¶àn 9imbPëƒîœšÚJ ï%ˆÒ˜ÃTU“[h/~ܳéÄÉyê®zX€Šf¾5[sNŠÆÚ ‘ÙÔAØ~Óè&2¸°š;‘3!FÒ‹ˆ´ÞNUÝÔVÌsçDÉÙ’¥å_î6YóPßï|Vóæ `ê(ñ¸ß±¶KSÛ5rßµäèB‘Y[‚r¦bxW†Ÿþ ùOð,ê¤ÈY:-Ä|½,ýåYj©ÐBƒØ2Ð¥†u¦=šX¯×ÜüfÜüf|àý_ñÊß{ôOüôŸ¿ã-«ÕÐ jÛ, ï$Zy0ÞÏ¥99‹Ï±,w3õ¡³ ¤â–W©e3jÞ„ ²;I}þL·Ÿ!'ñ¹æ¢( ™(.ÑPŒ¬Ÿ¼uÐQ¦p o)ˆyNâs7ÇRŒ² À>•Ö„ÿÆ92}Æ,#(sÄQ•ô¯ß‹@NN9Ü9Ø^žƒq ÓA³&ntnxÊkˆº s.^t)Nò¤dÍÍ|²¼o¸Qm=Ÿ& ÌA(hb"2u8yFަ&á›…˜“”beĈ°¤F•n¢ÜÀŽLª¥1‰Ÿ"–Rc͘š´)öÃáfÃÙ/r°‡ ž˜h;¹;•Òfcá^N Ç6$=8¬uÑnÕóˆjûSæ)3á¾+8iav× ‡¨ 3š“:¨”KuâX&ŒL,dÕëaÊr¸‹hCF|9”³ÍUF£hª›ºŠÄ-¢µjVqàÞn³$¢ÂDµº™È,d0ÝzNi•–,xòöSOÝܱlš éZµˆî…÷‰ͬl¦¾/X ‹TkG%’ÎF3HÇÝœ´Ï7Îîî"ëˆïÖdãî6K»Ü3oe¸«ðz1V×+Y0xæ´±¬Ñ{ôûß÷7þ·7?ê‘#ÓÏ~îÊß|ñËÿþãŸ<ûĉG<üÁ¸ÿ½>û¹/\þÈǽû\„ãh­w¹û¿ñ÷_yó þÃç?ÿÅß|ñ+?ö‰¸Á‰³qùƒð€{eþñÜáNŸüä?ýÚo¼üƒú¨»ßá»o÷³Oºâ6·¹5ÀßváEoÓï¾üU¯ÿ›¿ýàÁÁæ;¾ý–O~âOÞùNß%Þ·]x×?xí‹éy/þÿþùsßu»Û¼àWžñ/ÿòå_~þK?õéþ®ÛçóÿËÏßôüG ô¹/üëK_þºO|òS'NœuùÃîwÿûÞÃÝn{‡ú‹?~Í«ïMÿï»Þ{Í5_¿éù7zÔÃ/{øCïK„ ¿ïät»;>0sÏ÷½…a„Á¡¿ê ýV G ½Ýôgo}ù}ýÛÞùî÷]s͵çŸî#ö×?ä‡>÷…/=ú§ŸóôŠ"A¢ðZqéeW¼æϹÙ7Ÿÿ]w¾ü£ówù?îòðwþWüîëþèÏÿòo®ºúäûßõZ'üã§?û’W¼é#÷Oî~ûÛÞú‰?õ€o¿õ·8üŽ_ñö7<÷uoü‹wýõǾvòÔMλáÃ~äî¹ì¢xGwú¡'½ü…ÑËÞú¹/|å¶ßq³_ü¹‡é+×¼èåoûÌg¿támnþܧ?êü›œô _üÊ+_ûŽO~ê 'Žï?ä²»ÞûÒ;ºû/yÂÛþàÿzÝÿòÝýw×|íÔù79çò]üÐ\äDßwñã‰è{/¾"¶ÇÞùJï{»±¢z†”J‘$ijWQÒ¸¬Ø†%/ÄcÎHBëÌ$!°÷ysm;`àždѰâÃU"bK¯×Îá­ÂJròää“;Òî5q¢™–ìÝ$°0‘œ¾RÊH6¤oJÞ%—€ØƒÔAëDC=ªXÆ µkÕt‚%~†)–£Mäâ˜&H$Ä€šjÐÓº‰Z¼h¸ÌAà2¬ßn·ÒhÆAoÎ2Yr†¸1˜µ¥/Lô1ÚmiãöîŸ{%ºgkcøZjõÜ»[Ýn{êD9´…GÓ´öôÌppÍ]#ËÙW¢ö¡gBˆù =ûRúADL2ô­¸ˆ¶3i4a»ðåjæ1F«M?Š‹<ô!—ýßo|ó£þ+¯üâ?æñÏzæSŸÿ¼gþsW>åçž=Œã}ï}[ÝòïzÏß^òÞ-´w¾ëÝßvë[Þâæ\yå•?þØŸyÖ3žò‚_}öç?ÿÅ'?íÙ«õê>÷¾dvêSŸù‰Ç=åéO{âoýú/ðÿ¼óÝ?õø§½æ•/úÖ[ß‚Ïù//ú±G>ø¹ÏzòÞþþû>ð‘g>ûù¿ùÂçÞá»/$b=ë¹/ü¥gÿìí.¼Íkßð¦Ç=þ™föœg=éöÞæuoxóó~íå/ùç’ù•_ü—Ÿzü3Ÿþ´+ž÷KOû•_zÚ3Ÿ·Z÷ºç]‰ð¤§ýʃ~ä‡~òѽÉy7úêUW¿à7^MŽGüè}?öþ·_ø½—ýýûßù¨8Z§u4 U$•Hýä§ÿÚƒ.»Ç£q¿óÎ;窫O¾è%¯w¢‡?ä>·¸à?üÕß|ôî}O´bþê½ï¿Õ-¿å‚o¾i+ˆòÛÿÅ_yÕƒ/»øŠŸxàþÞÁ?ý™+ŸøÔ=ù ?ú‚ç>žÜÞùWzÒ3~û·_øŸoyó›‚èçñÕ—ÝçNzØ¥7>÷¬«®úú‹_õvrÈewkêWóM?ÿ3úÎoÿ–7½ý=Où…W›ùÏ=ñA·ýŽ þðmïyÑËÞòüç<„/~ùßžøô—=åŠ>ûiøâ¿^õ Ï{í0È%w¿ƒ“ÿüs^yÙ}îüc?zŸ{ë®>ù[¿óVÓúÐ\ô¾¿üÍ;ÞóIïÿË瑘êÙ‹ƒÙZå*†UvÔsΦ»N‡¥ÉW郖^„ãR0êìt&7á"yCþ¼··"£È™^ñ`" #wïÆ5YV ‰†…QJòs¤xÓ]P \[äËÚgîfZC”†ôP¶¨À’Qì ê¾¢ÛF\†ij#E}^y7kƒhXFjÝÆa²M5¬L5pø~“‰ ]îÀDˆq$‰95X6¼·$ ѯÙTqÓœ“‡Ñsňà¹bÔ\/sp3–ÕB™ÒþPI4³;ª‡[JHuJ™)ciÞG±MI’EŠžþ/ˆ8 3 °‚ùzÌJ:…`×5œg.$–m.Z& ®NôO–qÑ j,Ü”¶àÖ·ºà W^é®/~é«®xÜ£/¹ø®ät«[ßâYÏxê ~ý%÷»ï½.¿üÁo~ËŸ\zKˆ@¤ÿý-|ùÃø‹ûÕÿéq¾äâ»t«[ßòYÏ|ê ^ø’ûÞûž]p㎗¼ìÕ?󄟼ÿýîlÆûß÷ž×ºî·_ñÚßzás‰èÿíj±‹î|ÇŸ}òã^ñª×¿êå¿+öúÿúâón|®»?ôÁ÷ÿßzÕ»þç›o|ãs졺ß+÷ ¦—½ê ?õØG\r÷»8Ñ-ou‹güÜúõßxÕ½.½ý·7¼´OG¾éMÏê~ì|ÌÏ>âòFà˜Ä`_’q£/á–¨6¯pÑÇÞÿVþðõ/JHšü¦çßøIOøþég=òa÷}È/}ÛŸþ¯»_ô½qa½õÿ׃pÚ-8¿þËOɱíNô;¯yÛO?æGî}Ï;‡ôöÞ÷¸Óu§^ýº?ý•_x¬½öe?‡VƒŸ“>þ±?|ÅS^òË~0vãKõ§otî "¿ÿ½~àå¯ùô†_¸Ñ9gƒè÷þ×¾ñFäzõëÿüÑ—ßó¢;Ý–ˆ.¸ÙyO¾âG^úª?ºänßMD¯ýí§¦÷éyç{Âcî󸧾ôÁ—Ý)j}sC·Åà Òä 5¯‰XÍ–²9“8æyHÜùÊŸ˜åÌ©fô–ΡóÉa@¢¸f¸¬!¥×ta\bZkÝhݘVO¸Z0öÃ^ÏÕt3sL7–“HZ™»—ÙÌ ÅÅ.ˆy„é=1«³†ñ,){,+–‘˪ ûeÜ—²—£LydEÖ9j¥ G[±ŒYæ‡t•Ò=/íyF–„:m«N‚´>‰9£5å…"ã¸ÇqµZ ÃXÊà­V§Z§i;m¦i3M[Õm †Š_—ˆtÛLµnT715ȬFm:Ù<¦eަÓ[í8O¨´AGº³ÉcëöZ×)ÿÆU§YÁ%F<¦µxì°nRg–ƒµËZ†ý2/ãqöeØY‰¬˜3ùMIa!¥CãÄÜgtïÄФ©Éõ1š: šv|g bÏÆŽàñBòkäóh'{×{Þ{é=ïÖ`¾ýíoûÿôi@î}é=>ò‘}õ«×ÑUW]ów÷ñKïy±;¿û=ï½ôÒ‹vb·¿Ýwþã?}šˆ=i“ Ð{ß÷¡{\|:%|ÉÅýíû?ø)牨–îrç;~ðÃKñÑyçÝ8–àgŸ0·óλQüëÙgŸ¸öÚSQx½ç¯?péÅ…N‰ ·ûÎoÿÇO}~qghø›nz“/}ùß@eɆ”°ŽJ˜ƒèï?ð¶ðíÿà}üòñ¾ãúÓO|èàDÒ&yƒˆoz“s¿ô嫜蒻ÿÀß}ìSWí$ˆ®¾æäßâÓ—ÜýN1ø·#hD(Þ¹Däôâî?x‡Öî@w¿Ëwà#ÿØ%ÍÓì&7ºÁ—ÿík‘?÷œ³bžu|mæçžs"xgß;uÝAD‡÷~à“w»Ë…QæºÛwÜú›?ýÏÿÒš¥æ:Å95·ŸsüË_¹ÆÕfàØ›Ú51‹fG ”Ý«{ ÂSwuR·Ú~±–˜PŸJ—ÎÝõ à”$7#™¥}dJ N'¤…¤u˜†´J!„.h_$ƒrs¦0…ëC#Ôãy)øi. {ž“¦:Ê&q=Ñb*ÄX5A}s²!#³Þ)Pvfq¯h†üqƒ¦uHÌ ¶)J•RV”z|9sÔÚuš*@C)ÌcØ*·ñÔÙ4Kcù0½p]±ÄÙf@=çÅŸÖù´äg4âK„ĘbØçš0¤Ü>üÍì#1bה̂™Wm¨êŽ]ºçÜ{óæX•5PUPÅÜ‚‚4‚2=ZqÀÖnÑVTÚ§>‡µEm”QQ[ĹU[d¡qŠ*¨9+3oÞé {¯ñþˆˆµ×9÷Vi¿ÏçÕ!ÍÊ{óÜ}ö‰+â÷ûþþúé_ùø&ÃsÛ[oó „ì‹\ØÙÙ?~tÙg"›G×vv¦¾U ¥©ˆtæ l-›s |)gç’[…¶÷¾âk~ô€I!ÿ‹¸,-ºÂíÂÀʃב(²ÆŽè1OT}bò/$C;€Ý„ÒUmŽƒ£W "Qc£CW®"…Öv`©¯„„ËÛM³aXû&˜‰ˆÀ"lô^ä5\?óv…ج;E„›ä.×pH‘¼¦‡8VÜ_!Ǽ®Â¢é™¦H¯ýÅ|ǻޫ¼DÕ$¿ãÝï}ô¿yá0/&RýÉ[ßþä'=Ð?ƒhËŒ1XWPPùˆë>ð¡T²$uù–®L\8L¨‘š&¦”ÌïˆP‚$U-k³5“ú+64-G˜XYdÓ3Üûª{mYÿƒÿùŽãÇ7¯¼ìbÁì Å ªÏnAàG>ìï~ßǰüH"ï»þãxÈý\ ë]g`«˜¹ÌôdÉ`i+X«ÓœAòCtïôŸmÆ ñ±-8š.Áõ÷hšØu½üÊNû- À¢J^'é‰{Íÿ]P#ƒAÞëi™Ôk¨R¸(¥ Š&46j,1sÜKjU>RÔ¡jIlÖœ5,Mb–”ŠTÒ8\>ɪc?f²Õ~h…sî8-tn¨H¿F<éT1§9ç.çyê÷´‰VJiîgzð·Q©ˆ·U¾›\ÞÈè‘ŀœ)͵؇”¢&3ûƒÑg1Â’Õ–:²YÞêdЉ7dõB] š%©W 뇟íá0L¤e£»’3±b(«§¢j²še(ˆ[Ý šñ[§ò05!´D1ÆIˆ#­†ZCÔiucßg b¡/‚ÉAÜ:â²a×ù2z†XÌg·ÞzÛÛþ×ÛÿýüÎßø¿óú×½b4#žðù?õ3/}×{Þß'è:þë÷è›þãwF­tÏýú¯}ñOýü7>÷9ˆ:C¤ÿò=ÿùÅ?õ’w¾û½‹E7_,Þû¾>÷›ÿ“Jß´ê†ïù®oå«õOÞò»ûÓý½Å[þìí¯|Í_ðŸ¿Uç úgy癳™åì¹óoxão¿íÏßù]/ø¶2s@ ‹÷.„ªbÖÒÿ»Ÿÿ¼Ÿù¹W½ë¯®ŸÏ»ùlñÞë?üþÓ÷aB"Ò«°ï_ôÀû¾õÏßsr>™”§Rý<:8¼¥FÁ›ß\¤*cüœg?ùç^þÆç<ûÉJÁê¬M‰t‡,j+Âïø–g½þ×ÿømù½½Ùt:ýów|èW~óϾõ›¾ÊSjñ+ßßšD/²~â·æTÏËbgvÎÌéyßðÄWüò[Þ÷ÁœÏ³ÙôƒûÏßýC¿2¼ðl ;#rí5—ýÅ»?–R*"©þO'µE_̹çÔ3'æ§…bÏ„YD¢¯tRQãüä‹T›ú3Ǥ“\e&}¿ßwYs–AD£Ä‚U%Ýw{—¢Y»m™Æ*7S$‹ô>Ð-'\U¹wŒ:–EI’³­ìêWE8Å&»‰ÙÏ”@ ã!STk T^p^ N3·èmE# ;AÀ@˜™3s !Ù(?˜ËV)4Ï·§…=$9e¦¾[¤¨iG„Q›ÐÊ&V…T— $–¯‹t,YÑ¢ŽZ«Xnm¡fPÆ:ÁbPŒ@l(Ò\Wöæâ¨¦œ+|&©“‡«¸›JBOþLŒµIÔC/šÚëi°e£Çr™Æ• mˆÔB8²±qõÕW=í+ŸòÏ}ÎÚÚ†¶l{èÃ^ûê_|Ù+^õ}?ð£óÙì~×Þ÷YÏøª’ó´¯zÊk^÷«OùŠ'§ ñ!×=øµ¯~ùË^ñêïûþÿ:›Í®½ö¾ÏzæÓ–A“Ðîíõ•?ÿÒW½è'þ»ˆ<âáùµ×ÿÒx­¾¶ýÍGþ%¯:wþü‰“ÇŸòä'¾ù·~ùØÑ£h6žf@M¬ âóI)p¼îA|å+^ü‹¯zÃþן™Íæ÷»ï}žþUOrá'º¯J<ìKïCþ±zþüøË^ôâ_Ü<²~ý;ßdÀ¿h.)]:üÓßþiÑ´û²ÒÍ„JÚxòó«¿þ?Ÿøeòñ{㘡h®JWwÍÕWüÒÏÿ«^ÿ{?óÒß‘ëtÍ+þûwßïêK+'1øü°’NIA?«ö—ˆÒú1ã (÷¿ï¥?õÃßð†7½óÅ/ýýù¢¿úª‹Ÿüo²ô@)3ƒj û/xÖO½ì~î—þðÈÆäí¿ÿ“‚L„,źå£;æ¡ÍP·€ˆ ¸Ã³ŸR¿(V¢D—\"Xò#Kä@7;ßMÏ.¦çºéÙÅôìÞùÏÞÿË~¨ïçMÓš]…Šœ¬BU°N])lXŒ¡IÅÒ¶Xµcš0©u£šš[cNó(©Éù"ÉI®%n* ßyJF£SÕÄ"©Û…2Þ2ð„<­„Èò/ÉB¨8YÉ3c’&¡tøÙ€0vÝ4ÆÆ 1…_1ª«JöóÔ zF3ù­…<ÛÑŒBûǯûú+.Ýl'ÇÛɉvr¢­ZÊÀYݜĺTi„úÊYL%”bI5…Y÷"<5¯ÆâÅq)g®§ÐSÅ ¯î@‡LÓ¥˜Y–áŸ>£3 ¢T3JJÇðê˼@êl~`2^,´‹Š´‡rõµüÜg>fUðˆ´á þdsH'K•& Jæ¶8OixˆˆáÊÁQʉ'ÁÐf–(”´ê£†p°Ã€ArË‹-¹Pfþ!õK§Ú‰¨*ƒê®v:"ÒUŒÈ X²þt¢;ÿ+Ý`=ÙJÎl!¿Xßèñ6­S꣰rò O Wšw¿IÇ"#žÆÆv:0ߢ†# 'ÕÒ#…JþRõ+Mß è€í1Ä1…!AkWŒíÊqµ˜ÕìžöЖ,e‚«ÞÁB“*QéÞÎ'„`³yaæžB ÊpZ:¥"Q j¤LpÌòKö¯x¥Ö=TRyœøKuY;.÷@D¤1}¥sLäÏ3Å1²"œíÓ¢8¿ˆ€£1­\1ÕÀR½POt,¬ÿ8'¯›8€ 8/çïê3ÒŸ+i±ÂšbjÅÿ8ðiɒǹ¤¤|ëWð"Þí¨"— n©#”K A]1‹õ ~1P%ñ–oe!.N]¨¶Òú‰#Gá•UUa«9|õŒCëç»,!Î\qFÔïFªµâ+@@‚•Ó,nF5÷¾jòÝšAHpˆ8sþ¼µØ9ö…ŒUÒêƒ|X-™"À,U†JÇù\´‚ *ˆZ? ʰn­A „®¯6è—÷À#Bö=ÌãözTØâr ÿÕ}c ÛYšóØ“¾Bý•bhü@[ÈG]Ïë«øÎq¨ï¨j÷•`ÔÍûÑXÅÌ–“Q#¸GC.æ†Tf©¦Bï„ûaá|¢VR’%ƒæàïæ Dj@ÖP#NâÁŸžTå3nñ ! †¨‘205à¢:=ª¨rгé"AùÛšŸÅ%’ÍáÚ=eöb-Åðkäòìu ¥0%(‹û¨õ0%¥'µm»¤`ð­ûk–QÛêH3:K?(ö­›€RA ÂÛºïî…Sîg˱:øˆ 3ÅÉê¾gˆúÊhf\ÿH*$ðg¨9˜×îCË94ࡤà.…§ ÑÕôÊ"ý«ºuX~º{¶G%» gøŽ2HÏñšŸžJªŸ)pX`€g„ C_š— þ?þóŸ4 ¡Ž€µO­~…)¨Ðüé¶§¶Œ«@ ¥ÜØ'2ƒu£C$½wëýТYoÎêBF0ŠÃ󇻢„<ªJZ¥x"ì² *ƒ)®´“âû&•å˜&¬Ô ê>”s€WÏA¥¥WžíwJ1ñ®ÿà+²BW,N|¬Ðè8!S[ÚXÉU¥í­sÈJØ(‹‡ˆÀò²ÈÈû~/ڼú"Y›qPñÂJK³CŠÞY”e•¬•šs—ó‘BiF¦ºN5/ž1ìntJID$jEzËq6½bVP­¯zq5‰$—|ÄR4ÌÎ?Q¬;_ŸÙ‹o_HÔÚÏ—{‘”sWç—é;Fí¤øñ "ƒèéU €(D½_­…ÔS„ëmí´.¬WL;hƒHqîsš `ˆcTk™ÆopRC¨Ù*(Z]¦Ã —‡ýÚ䨚¬kbC(aÅZw{›¬èçaÔb™h°‡«t%wkÓã7OÙ«ZaUÍf€Â‡í‡Ã ˆ f.¨ôO­ÑX˜4•†´’ðwF5bÓke9 ª*ˆ}ïÏ}úce`†ö„°KvóùVdfĪ9o¶ø3y¦»g†*oW/Š©Ób1õ*kÓ¸Õ@`ã#t†I… öŸÇeÑ~‡¢†¹'šÈR Ý?éD<³Y—‡‰å±h³½Zûp¸nRÞ¨2CQÄMå_.-HµRÞÆÚ˜ìEÚ8ª¥òb±’©3ÑÇ& U®¨ìJ†jDXü£qñP…*Wiˆ‚Ë(ò·F…ÆH‚HDpÏ ˆÄÜû&*Ü·À†ïFaDÁGcÇõDÓCÙPâÃGôÛZ5ð,­÷¥¢ãÛ*¨D²’u<öWÈb¢ú8ƒÄ1—ÚR5èmÙà¹2u*Ü?oµ,ºG¢Çè»b€ê:gî• hrïûÚh‡âêŠQ¡Õál(‡°¨ÑÜ$“jU3P}¢˜î–‘KÃL“~Ö‡gǰ[¶¢n=2$Ö”&›´»§e)‡C†žaWîçe¶Ô÷ªÍ¦‡t†Âj×­…%\ _¼v°ŽüEÎíÁ!ÆÇ2—óÒp¶â¶œHû¬f)¼`é15• AH„`J^Êl‚© @eì fe;¶$Yt)ã\cEÀq‹`Mìh«ø&­„Ái“R®jÕÎëGˆ)åó-wSŽ*h…²©Äáúì«ZM} è…¹>̳qí°A€ƒh9`¸¡GR%¥X»½$ðPÅ«³«&¡Ÿ"î&¢ "çŽÓœâÈwuÉXbôêrÃò' ”¡ñ\vâÂIr2š%®õƒdÞÞÊÜY¡ alÐcÕ;Á‰-ü:ê0C)ë®- µÆ"Å‘¬Ѹj"O@+)žè&tß“ uFÌ=ç…Në4äm)T±!@N\¤Ýv†²Ý¤|ØUz–Æ.h`Ö¤‚gñ¸s0¿ÿ …öá&ã¶X.tÙ ªS‹³uµœ{T}åàW±;LržC½O·@(ÛùÂÄZå%ªá00h1Èãàh¡'Zä‹nëéç,]‹~<ÝqÀ£àa`½B )Ï!³Œ¥äSÙÐÄ,¥ð¡åÊ%5=Oá™USïø—”ƒ>Ùç²j­ABv1]6‰ÕÉ*nøêóÃ}Màw%ÉÛz–È8ÊVw|µ TOÃußž ó ¨ûXðTdmÙX&‹}¢³û ND`i¯Z£¹ü¼†ôtºÓ]Ç^–6\üZE"5÷Q/³ù`ÒD :r4ZÜã£ïíÝþáá¯A¨ü=PŒTê’'˜s= ÔaB°¥ê!"I©2Zu=š­4éqRrÉg.3&;€[/\D¾ÐGQšÁÑv T¶öHÆz* zH#«VWÌÔÁ¼ò‡ëÌ–‚–÷E¥Z¨¬f(SÛ{(£ƒÈü ¼†p7#‚HRú½††—¡ƒp*NÏã¤j܆‚‚í¸7Œ,º/„‘ë+ÙîNU;i×F””\ûR¨Ìì°^P(\¹Û8÷Ì¡æ¨ÒxH„‚{#z4<"i*œs^„0’¼0M’Ø| 9ÊW¼Ðøh@6‘@ÓØ ShBƒe1aá-)Œ–¥×t@I÷ÕYëˆý(ŒKM”2jð$ 8ä̰¨¥s+¢µg$ç$*&–  à^É‹])ÄCÚ’áJ›e™ZxÕuGîŽÙ¬oÙ2CzåeèêÀ„e ‚ëñNJ«õb˜²ÉÒê }ËCÕI¼Z³{Ÿ‚¶Z°·¯¬¨qÉâ9gYy.•EûnšV'E£âóú%éãbé ªâuú—Q½RQ -…Ö4ûFy ¯aY¿Kaûiƾ.­[ê]êy†½v*— ¶v²OKŸ5­ö”2ÙbQ Ia·{ÞçrZ•TÙ+ƒsåàæàÅKkº0Ì•܆ÿrJhä´Èi^Å=/E†ÚT¸¤vQcðZÅbÉŽš`Uh{²éMÑ‹ …Ìœúéuǽ•`Îue´T’Ôµìó 9T:pt ›aÈœ;&eî™{¬~PÛS™ç-—ûšB£ Ý ²dC£c1ÂÀ¸5ªÊuVf ß?¤n«>͵CèSÏ,M ""!6ÂÙ䫯¤)ÒQéË’„Ì…%.A,§Å’Äg_ÈI„ƒ)qx‹ŒG·í:$É}8­@‘m¡ âürú®Æ Ë$üåKÈÕ£zIî5š — kmóÄCWü+¯¤¦™ ±ÍIéyH­‡ÒkJÕBãó››ÅÒ‰‡]”ýÈ\}^‚ºYlaä‹áã X!*¥¬üb(·ÕÄP«ÙÉwPs`IBËPyäòQT·0U'Ø"Ù.B_ «‹ÉÃ|þÂöÿØ+>ò±Š1~ø=oÞ‚eßzÙÙ×"¨ºu²œ¥å%‘Žõ¼žêʨ¼a!¢Ç>ãÇßÿÖŸî:YõéU”÷˜, %ÈÆ2T4‘ËQÛܺr*æX-çmYÖë,CAGú¤]jWQÙqx 7q»dæÞˆ&è/M…ÎFpçäf*”ýäëTýêV*žÑjq„f…,¥ÜYás…+¼†Ö0”ý8Qˆ Ây¡>ËbJ3ù½"H€É„ò M´fD%t¨•PhNR·§ù©ï•˜­Y#J™‘&¢gNóé×ÖFz(«®˜[¼¸·¸s >DÄ Ñ·F‰yH‘0ˆ <ôX K¾U×l"ª¢¾¸PT4 ÌԎˤò`8ÇRß§¢¥;!àáǪ,уíƒëñHò!…a¹€¥‰óÁÀ›J1+~n¬ZÃáMúS;[ˆh¹¡¡°™tÉj(–X¦1(1ä™Ýþ±ïÁ—:_k,}Y°ŒT+gÏõdfõHÑTs ¯ƒÌ,É•$ÆçÞ;kEeåÒ!•ó[?èV:æôòWþæƒxÍ«^úÃMSð¥õ”Cµù9Õ¼ÅUðožð¶1 tìèÆCtõ·|ãW\{Íe€$\5€˜+=î/zß[~/‹ˆÃÒ„‰°rÎ^Iê$$ëÐ+ãœíWª'år»ìQBBÀ¸J'³bˆ sA –ÏYRR†RæLwbEgHUÌ̈¨É]Ê=KŽ¡¡0"Š€pŠºÀ­ô’¶cñ½!–(4]gôDQô±`éçÁãaKqg¤ÚL-Ü:êµnx$Â:ÊÑŽ{H @2™”ÒIìUIÖ .e‹ˆDÂÛ#h‰C¤‡)æ”sb‘bˆ id4…Æz .וëÙòBÐ+ÖgÎ9÷!„ÇH‘°ñ—îõÊÃܯ˜‹Ü‡>Ñ!ÇôTUG 3ôqù'дPé}H+º•^F.å `aUq—9QhVG¦¶y‚Xªë! ÿ2øsÁƒ§{æô¥”4d¢,)f¼M5%§& áP¿Êeóáf5$µ¶dË <¤¡ÊÔãÛʉT3± áÉGÄCJ0VÊGTƒ•W÷×À0ž ƒžÔ<¸å„kADÕÞ©)W5>©\ÿ¡ÿÁo½´m›Ò©!"K‘ 2¾ä­~["|äÝ¿ ˆ]×ßqç¹÷^ÿñïù¡×üÂOþ§‡~ѽťPÆ/÷ŸÑ¤²ê‚ò~f¡…¥Ÿ®üañ±Gi-¥R Ë FVÚO‚ e…›WœÚ>Ê€¤A†%Œ³ºc³Åÿ£ÑP¸Š!a¢‘{Š’‚éBl"FÑÌ%ë,(hZQš %¤&§YÎÙÓa4Ü- R¶A$úzÒðˆšA¯ƒ@BB} ÷>ò¾d·]ß0lÕºƒî7U´¢õ5dî~ÔÍú4Ëæ *€.CÏB5Ôªš“âS#RâH`¤®¢&çN×…‹~–Ú&6#‘œS› @R>M'"!ÄØXËi2ü–·*«ƒ?X2•Us6W­ÌÝ–¿@*ÊÒç…_þò[TÍñ¼Ö>[8ªƒÕº ÅdÉG¬Ü\Ëè«~ÈCë)ž6R$jÔ_t¤9w""9§™ö8œ•,IB•­ôÒH¤ï¶õžqdÇ.DÄŒ=\ž…å§@¼œ2´MÔA„=® [–N)Õmjú p”æ9»F/4í: Jîc@¢180„œç¶ŽåœR¨cA(b/¢H!lë+†ÔFÃÐM}_>ôðôˆš› ƒ U4÷E%žÕ\&ß•F Š®dɉX^|uÞQ©–‡5 Sc¨®žß—ô ´aÈIÆUP^Í@©6Z¹”Î"5³Ùë•‘|Õ‡Õ°Ë6Pú’ 'x‰mº<2®RËØÐÚS +–ªÃt8è®hð ê½kËb—ï³iN G2ùZ¦´¨â-k[}XYñDä CÐ&ï€øÇ|<ôK¾þþC¿‡ˆÿüééµoþØß}RDþû¿ðùßðÀû߀ú¥Ï}î×~ë­ñŽž;¿ýÑ÷ý†=°2¹ðæ‡~é7þÝÞ¬¯ó³ŸûÂó¿÷¿ÿÀ ¿ù~ú¿Â{þúo¿ç^òº_ü‘kîs/ø‰Ÿ}ÃsžýåÏÿ¶¯^›Œl|lO…¢–e{‰$À2ŸwãQsÅe§®¾ê’ë?ôÉ'<öÁzý?ø‘OÝ窋¯¸üÔõoûÙÇ>ýG®ÛO«$÷qOÑ‹~ö÷žù”G~ó×>þäñõs[{¯ýõ¿dç<ãÑŸûÂßÿßÞôÝßöÔÿÐ×!ÊõþÔ¾øw^ñâÿpõUÀþìï=ã+ñï¿æ±§N9¿µûš_§|í³S3—E¦rÏÚ)+£’ûœ;R­¢Ð>ö š§R¼.´z¿JQ‰V¿ËeÅgî7fï2_C3Åø'Ü%Ïäª;°Ü)õÕÄ€óÜVRÔ¢®õE/༒A$,Ì}J)eiÄf¤Ù^ÂÝ@qöžÔ¡Ð¶k—T¦Ršœ{}f„8R[QãkPHä7½þ>™s̲[ôÜ€ Û7V¹1K€Yõa¢W,”¶H 2$‘Ø% ÎJÄXÙ¶WfðTu‹¼ê¬/Z›½Î aluýR= ¥pØç‡üˆKªÕÕ³íЊ®¸|VÌ w£ºž¾UáÎÃÒÆ»ÁýÜíë¯ÄúËGBPæ)ð@c±°[\6sÉš.Õˆ>*j¬AY¯¹Q…— ¦ìù¯24×Us4øeËép[½¬xÀ¸zI"ˆÈ_~þàۿò¥úžþÔ/ÛߟþʯÿñK~ê…øòŸý>"%UéÌÚò߇Gšà‚3 ¼å/>ðoû`yöÓó–¿øÐ¾ôAú÷¾õ/?òì§=––æö~õåßAdX—Ó}Áóžò]?üƯ}Æ£ãwßóm߸ħ<á!ª9}òã¯ÛŸÎãwßó“?øøÕ—};Y„œ¾èèw}ëS_ðC¿öµÏzÌ=ʫފ™ a`tè2zÊ<œÑn6­z–´»ªÆÏi¾·7Í÷9-ÌãÄ=s 1RÓ4±iôGòƒ?3»pÁ>±›—tGTƒÅS_ô‘J`!cbqÔ4#m{ËÈÓñjщpÏižÓ\õ˜ˆ$Üw‹Ýùlw>ßåÜ£â¦Ìedê΋ÔOÍÀªs0°qˆkFFþ¢€þtBÏ%ÉœçûûûÓé~îçZy3÷Ì ‡@MÓ4MKjý¥à£w¶%Ø !3K¾ç'»TF‡8ŽÍ:…Qˆ[[…6Ä1[>Ú)ž"/ÁܱV!ŸóÊžWê²"²9 é€å¦²Ö0 ¸<{ÆÖ¡Íþ¾RÁ—ØüÇEf¸Ô~Š°Ç™{hÎ ýçÎ˸ӛւÏ#ƒ &–dt˜y‡î†5¡H.ih¥Ä›£ì0!W) œÓÂU™âúpX½'ShÔXQV–bm~“¥†txã˜J»”hyÈ®©Âh™ >ò±|—=½]'>þßüíÇ>¡×!‘î€D…RkÛ*½³î¦Ïßù+¿ù¶¿x×G_ð¼§ È—}é}æs·Ýq×–€œ;¿óén{Üc0ôôÃ3 ˆ¨r$Âŧ6ÏœÝáýýûâûû¢^àq~Àÿþ‡›|’»´½èä‘3g·¥,<è=îáŸRcÁß ç2+“¥5(…“*7Þ²×lõâ:Á&F‰ÑŽŸÂ¬<%¡šWÖÓñ´j€†¨‘Ùñ–¥€îMß M.ŒÞÇDÝiú¼•ʘoÍ`$„`"߬¦]‘BÏø¦§ódiA &“žÈ¶ÒœÅ Åœ‰Ì8€*NdCkÍÀÓk¡Øô”£èw¦ÐèÆ¬„´”‚_7ÐÙq ÆSTt§’}k‚‚\BSj2½*Ñ+h¹ÙKùÓë)ýžZ•­ÿêݦó{ÿëJD+c„ƒª¦ý5¹Õäžîõʨ6Xí‘ãl²mef3Ùk"¹,Ëe` âe¬QdâK« –Ú¾Cúè"Ù1Žz}¥Ø©Ea ˆBβÏÊ=ÉÆ•Îc$ |UNýqöOÖàP𙦅 âöÎÞ‰ãÇêÎñcÇwv÷+’w(ÀªÀÔ ¾øIß%ãQsåå=ù Ã/}ïh4²ìiO~ä[ßþ‘oý÷Oú_ïþß_ùåoôQè8tåRù–J¹³7;º¹V_°ÍñÎÞìÐ~“<<êžE¦+à›•Bt‘< dPX‰p\†¤•yŠHú¯ôØ»ôüÎ= 3²"ÚñˆÂàʱs·52à>µñ$teœ+ÌíØKâÛ$aI•Ζ‘[Œ@H8¬Á×ÄŽJÂ2„BìP’Á@‡¦Ô•øt†• „E˜³t]ÏÒÒ(e¦¤Hž›" ö,9éÆf€Ê¸F 4ÀLa45PÚ1ÑáoMqžU±¸ŽŒÚƒzÅ¢@ÐØ ­žH †HÔˆѪËó|JÊR¸[.É=”Ôá|šk’žá$$Û×r> & x7cÓ{p=--…+½ªÖÊb!/CÎ囼WQt‘ýKN‚ye>ëpÒƒîÕ/c°Õ/ëìWlõuï¼´œHCk2Œ`aÈû9àè•T¾$©NÑ2fãÜ—C‰MD$÷ŸSÞÙüï~◑ÿê}yÔÿ¨z¸*Í€ÝÜæN&’"“²Í­aƒõóA—]zâÊ{]ôÆ7¿û’‹_zÑ1GJCÎ)Z9EùSÙ.åÃ|Õ{?øÉ÷´G•ÇðûÿæS{ð½ë¯ZÚhB—r‡-ßV*iŒízubÂLJÞô"°…¼6¼R|àðU¥=ôDLqz¦£? ›@‘HÅ™'¢á£ ˆºtܧɜA„ˆ–ÖÕ1Ð3žwèd6г€ÁëÊ•2_ÓR~oõñϯbÎ!Pˆ-snš Ç¶Xº8‹sgÜA3ï‹}¢i¶!”¾eH]—ÞÅ fö·­—ê•[dóbà 6„$’1´>5f‘œÓ"ô³Z«;E™½™"õ©Cb„#̈}¡Ô\á ïà¹ÞgÊ8ü©üÙòvÆŠ$߭zÄKplH]](ÿ3€¡©$MŠþ©|ZXÔ‡6^ÚY Èáïòì¬q¹n!¨k0+ ,ÔŽeVŠlU+É›PçÿV„ïòª|ê…">»psNs³ rfIžé²”S‡hYJƒ5G|ÇóþÝw|ÏÏL&Í—?þ1€ðž÷}äuoøƒ×¿òE+–!¢€zCªÅ2Z³.Èê¶ð; žýô/ù‘ÿæÏý·ÿª|àkï{éÛßóO}ÂC‚R/¤ùßòõÿÞ{ÓúZû¸G?@Þÿ7Ÿzãï¼÷å?ùMu"µï M_TîƒöÕlÔP@HTÛT£s­œ -¬Ä\õÿ`°å‰1`)€R™‹¾R‡>µfXbrN Œ–ð‹¢U´g" 5D©ÐƒÛçk9Èuàѵ¬±T©°  Gd7PôÌ ,Š?›<°ÆÀ§œ“õ_ʹ±TΙL'“1ÄQÑBÙ÷ 24JeoJ)ظ 3„PºÌ„ų¸|Å8gõ9]4º!!…”2¥èÅ,º<ŸïBO9# 3ëµûüÍŸÞÞ¿“¯¥>Y?zâøÅÇ6OnnkPˆ(6ñp®ÒÝoáàQ½,гø˜4—y^]¸w@(^÷€¸<Ä?à5(%yy¢Êh[Ó a%ìñÐÙÊ1ˆ%õñ¼ú5bÈ´”ßgÏË•6§ÊÆ0ëoË®ß>õxTõnâ^—vçqÛ  Щn¾ª*ï/»Œ†² Ñý®¹òÕ/ûÁ_zÝïþôK~Mvݵ¯yùßïšËu-ÁÖò£1ôDe‹©rU±[Ȥ¦5#@¾ß}.¹èäæcuï2…¾ïùÏüé—ÿÑϽòOŽlŒë«MHÌœÙh1W_uñK~üù¼ó^ûg"òàÜë~ü¹×Üûb8…›˜C ‡úDÿÅÒ¹ô›wÝô¾ÔíÛ¬•šýJq1é¸Ú£†+"ÅÅþ]–j7;×ÍÎïÿìCžòóE¬eÔïƒ|ð éo[ãImED„³ +dŸS/ AµŽêò$%›ä¢ H«‰‰H]eâv­ÚŒLZš\§Þ•Põeå¼Ð!š(9û:P¢c1üpÔÆD[ÝAì)ô={ž%"Åbë@“ì‹o0€†Œ)ì1pîD‰ú¾ ‘Ðwóétog{k6Ûûì'ÿªi'Hqy|t£ïÒÖÞt:›†öç}!Nµ©šQ;wÝþ|ò¨G77ÖNœ:yɱͧ/¾lcc3€a¡)¹4x©:¡Ò´Y:Œ»Ñ¾š suÆ<`!]j9ñ Å3ÃuP“ª&Ž—dÿ•èµÎȣ嬽åA0&×*-—’#ÊȈW”¡Ž»]=6ô'ÿ˜ ¤Ê0t¥vÛ ŒsYÜUc®¾5|GÏËè\™ï–£@5Á$£æ@µ|:°)ÖÅ‹¶”ÞäöUÂà®ÈY³ʢ̣ámƒ§¿zõþl‹†lW &ÛáË©¦¶ÔbDhl-K×qF…@1sNú®u]ˆ‹EÞ›íÝqî̹­³ón:í¦‹EÞÙß[ô³ÌЧnÑwœÒúd<¡„2?ßO¹O}—p²6‘@HF# ҈ĴÀÅ6œíöá’qs´…µóç·6ÂÚñÝf2kÖâ“ çòlqîÜv¡k÷oºñÎ[î·±yù}îóˆ&å¦iš&¾£W Aî)Ž+pL%²¿­¿™…ÆáÁ\akbe‘w£ŽvjýÝoZ×µh-#=Ó”œ(YmN‡bЇÚ(«ÆpP¶œƒ]4>PF[{:Ϭ°b«Nß×ñÙYy™3ÂÆÍÑÔEÅ[IE4 '+Èr²¦ÊNq°W9PÅkš—ZëæpÈ•SEŸmæÙ‡Å à[Ëmf©¥€oûË¿}ȃî}Ñ©cæÏ‘K¥ÿ‹–l’  ”x‰£ð¯Â’*Úô¿ ½‡;§®–Qr¯7·Ù—F–~–÷w޹'½3j˜Š¶Šb2ĉéB¼jsJ}Ê, í(ÆHf)ÂHMœsï9³âØHÔÈ`^vš½dÉY¹èžKÉÀž÷M¡<‚$©MU½E¬¡LÌ™9 眓ª‚‚Ðà.µ#‚¤ÌÀÌ„c`Cv6‹Å”[Œ ñÓ}"Zý±iBjÙ‘~6Dx±˜÷]êz^,fÓÙî]¶ÎíœÛÛÛ½õÌ)çÅbÁ ]Î)sN…ØBJ‚„'ŽHÛçwÏݹ#‘Ž;²¶ÞÑd}cwg†õ³L$GŽ5£–#ÏçÛëttctó­ýöVüôÅ'7±'Üõãºæ3ÙÚžßqþï9â¦ÏÝðˆG>ñä©KDúvDjµO{¥,V JIQ^ªYXˆ %þÄ‚YCÕmq5*ÕSV8üÕÊž€° ­2דLù„¤>­L V‰“X¯¤|äš±¶TCa)Nb¹%·3¸UNs¯¹â#>ÄwdÿO€^š£S‡†•PuPÙÉKÅÓɾâOȆfžŽiü#¦Äå諵cU‰TØNâŸ9¥v2 ðÀšÂ ¯,UP¼]jRêÊsžõ¸ç<ë±%ÏÂ¥åètÍòm Òä –>T€ˆXj¡2IÑGírGøÍ0te–)´¬ï[Ùu®rÏÐP¡+ËV -V„žÇ9ÍuÿÜû~¡¦‰ÌCÎ1ƒ0 $Dî5ã)õìKÚQÃ’™©A,æwR!¤ @˜;ßZèW"焃Hfá:Q‡Óœ¹Cl(´’™¹ND-…€hÌ'3ç,9 ‹ÄhyDÙÐ÷]×3óhÔŒGãœû®›÷IF£Ö£8¯yø ½JZ ¢¥œ…ì? !†Ð0KŸºù|1MÏm¿õ–›wöwd:›Ûíõ¹ëºE׳dÀ€a!€ Ãdsm<Öר¡­óçîºëL·X»äA÷aH››ë³½Åtoš°Á4MjÆ2K3‚µõ‚8â“öÇ'n¸09~û‘[aëöÍþ“ ×Ü|ãM)wÇO7ëáÂ…Ù¹Ùö»[·îœ½u>Ë{ÛÛi>äcžzñé˰OMá€eû`•)%¬Ðl‡c{©¼¥Å°¢Œ5 _$yXìOG ûeèæ¸hP‚¦º?ÌQ´Š–h(C¬§+EsÙé9 \ÜS'SïëýÀëz’A+šÔ¦UÎõçR)ѹ7=/'ä°TjµrY.¯+w‰€’ªTRÏäB"Hú‘âÞ!oUpÈ\©U[¨ùŸbE¬É"ÀJˆŠ"Гdç€~„ªÅ5¢ê½[ÜtÃ1lÞ÷þW$žNÖÖvvÏÆ¶½ô^ëwÝyçÆ(îíí5aw<ñ¤oGÐs—Ö›Bl÷wÒ|oz¯Ë¯ºæÒKæ»Û{ÛŸOæ£QÜúüÍ7œß:ߎòå—ŽzÿûÞ|ÓÎM7ŸûÈG?¸·ßÅSŸ}ìÄ)nšÑ’¬xUꬡÜE3„ƒœ^<¦Q$«›aØt«o½šm–®žý‡iæaËúU$‡JÊônQÕö¿ ¸w¾-®Dª^®ç¤«©º>² ä¢[ôì2ƒ׳NÝj§~ø]=cÔÜ£ÛõØ®IâÜKN2vÌsãQœŒ-ˆ‰9Ù¢9´ª½Ï,EK~|S' 3΋»î¼ãæ›n¸áÆRæE$ÜìÏGŽ9}ù¥Û;{óÝÙÚæ‰µpd-F͸m›¦Çã¶ŒN_rÑ¥W\:nÆbNÙÙÛ¾hít8ö µÛÎ|ú^WÞ«ë¶þùÿÐBšœ¾¼_Üut-Ù<ŸdOxk<áv=u{‹1\ ßtÃ4Êñ‡=øÁÇž¾áŸÏŸÝþ;îÒ¹´=^džÛ4Ÿö7mÁ™Ñd¶Ÿ!g‚þ£}ß©cG¿ä ÏÔSŒQI`~l?@3ºx3R(íË ŒÎ&KÅdµºo•Úe ÝhÝVŸPIßí\vÐÁ24§Hþ_ Çp°’ŠòÒògYRŠÈËòïì{ùå ’ÈÒùݳè<‚fPû«PއŸQ·jnÀ:w*¿ÅŠôgƒ Ïÿ“Z ;xAMh¹*ÜÀ'1m†ø7E¡ %³@¦$‹@ƒZV¯’%QúD(ª‘F%IiÞÐS_W²=`x©@E« u°VÞý.Ç÷K‘¢¤QX•OƒâÙÝÙõœ%K ˜\ëÖC %E!bÎý‘5õƒçÜMgÝÎîbÔÒÚdÔ´“£1 gÀ &qq1Dîg:õ ¡ adiyÎ9§œ!%Ñh ]Ç9‹ÒNì~è}Ï™¥i0†Ð4ãUÄyÁÌú'Û&ŠHßçÌ} ŒMÔ0n ‹±FÀ¹S&À¢ÏÌÒD‰‘@iœ˜³Þê!NfeSå4Ï9SííÏo¿ý¶­ógo¿ãÖ>áöÎîwž¹°»“r:vâØ‰‹ŽOެ^ß` íúx4šœ¼ø²K.¿Wf˜„#WœºÏxÆ1(#¨OóYžÏÒ Ïú9ôȹGÊmì4M·Þ®éÜÆé#—ŸzÄ‘8€[Ï~fo«ïnÚÙ¿s6缿s~÷ÜþîçR®¾÷}/¾èôÖùý]ÿ¡ÔËñãq4ÂqC C7“'ØŸÝYܶ5E “8:vt¼³½ý‘_íƒuêôåšÄKD²róÜÜfÜ:­6üu¥¥ÆÌgœ†Xf¤í‰áàí®›eaå’0Hê¡©ûÿ´ZÈ(”y1p^<‰¨þïºvÎtȾo苈U¡æ×Þ‡fá’îî)@ÐçÚ‚y ‡jÈvå|©ò€+ƒ U$=›z)ÏÛNw›\„%Ä¥øZ ”žk ¨ÑËùÇš ƒÊÊ@ÄF$&ˆŽ;DŒ¦ÍR¼†fŽyVrîPG6倥Ši†ï:ÀJi“aÅiö¤ ½‡…ä°bÒ‰§qjMèÁntYK<À,(à§)ŽˆÉŽ*cÎÀœ?rdss3¢bè‘2è¢ÆA>N(D$ã8Âùt–ÓT¥8G‰qš±¾È±Ÿ%5v)ç.eá,HÐ6®“E€Øóå¥ï9KÊÒ4Ä쑽ìâË®¼ä’Ó—@îÏݺäÔe“£ë7Üð™EŸ®¹úÚÑz„1D­s€Äœ30àt¶?ë§D0j÷|þÃïÿÀ£®½òÒS›{’'pìäúúÞnÓõ=]è`ïÂ|oçìgn?sËîþö<ß9&<ÙòÚÆ±k¯¼|ûÝ|ÓÙØÌÆÇ8´yÞ-F]a\‡¼+»;`±¿ÞŽˆãlÖOç9B`6½ãÖÏ9vQ± Ú–p§¥L¶£@ɪ´[f7§ÚÝ¥S¦4¯yzêz*-QÈá E u¿¤Î !ÁŠw˜à´´{ ënÜØžmDàí¶¤ºúè¾.ú¥·àœaèC\á’ T.‡áåQ¨¥Qyø¡,GZ„9×ã‹ìLn‚*»Z8ãÆ¡BA­¢"Ë0ü\Û@Ù¸7½&KÁðsùa²µç8>bÊ…`AÀ€ígÑñ€Ë¿*=õÝlÎæ9ÿ'ÿT¾&YÙ,­ü~\•‹r¶weR]í„»¯ÜïÓ´mS2ÙõKˆ²ËDC‰DV·Ò“;Â@8Û²°xÔS—R" ˜BÛ´kÇZ¥Š0çNïÌ]žwº±Í(„‘(Nb³Ñ‚p^ìììN§óшƣÈÌHã(ĉHÎ1†ql¾àà\¾¤?PÓhž°t}—ÒyâÄ¥§&SN‹íúY×ͧ{»ë›ãS'ÖOŸØ¼äÈŸ|OwÉøþ¾¼ïûÛnÈ_èsÞßïn¹e¾»w¡Ïû)ï§kãñæ‘cGbs’ÚÙßuû9ˆ#»)/r1@A$Í¥_¬¯a”v§ëºœr‚HˆÖ'ÍÖÖì 7~úªû^×¶ ˈ…1wè±ì*Í{ÃZJè^µkNõžs¶xQ“”“@F!v¸øj’nmÇ\­˜•¢]m™Øú‰Ê1‡ŸTGom˜Sm¨¯M@4œß‡'Š¥FÊ€Y*ô0ø³ó#×Eß%SI8ór^˜ÜûED›uá©«+i‰ÿ„aàõ ݱá Ð”9èúËê÷A¢:E¸Ž65KÉŪÚp5"¢;ý@@‡BS ‘sÒ½‚°=n14ûòÍqù0-^X„RƒÂj²°è”íÙƒ‘­ôœ»U¦×ò}ûùVN ݳ†Ã ’&RÖ@@HƒÙmUîÈœ-®Y߯ùu÷Ô_¿­mk”ôvDæ#YÔ°êÁpM¡i(† FcÎå4G§ºàßøx±™Ph=©&q^QÓ¥=½ÉŽY×hŸæ!DIýÌ¢Ñ?ä–ÔÔ/fóEî{Ç#jÛ Rà¶Aæ”RN™‰ ííï}ê“ÿðOŸüäÙ­ ãµÍÑÚøô½¯½ä^—ÜïºG\yúÞ·nŸ=ak}|”Z¹…g·Üzûbº×†€9ÉbÒË,mL&_4¹öÌçg¦—l^ÖwyÑϰÓÄ$¸ïg³ùÎ|šy Ó| -È8ììÜW<ìâIsû]ŸùÌ;?“7ŽŒ¶÷Ãm·o?úq¿úšËâå§>ñO»Û¦£uYo0„,Ó<_[ì­5M?iÓïÓh 2u}„Ô@æ¶IúÜísæf.ÇdÔG™6)Ž@ún‘3 È™Ûoìf;‹È1dà6„ê7X *À±<Ê)÷³C¬JC4é r`/ÍÎÇiŠ%Dá„€ˆD*‡2qT††Ù'’ú\׬”œæÆñ+âìÜQh­ÚÑuùìå<—¥O’ U”$[ÛR+(— ©Ã.ûR›Ô…µÔ ÆV>D:>L|WÑM@óiJÜ@bD¤¾ õõÃÄÖ»Aj-j$þÝýùz×"Ü{jok{×ÕÄMBȼäCS#Vî³þ J×Èݧ%/Up M;‡ÿÿÿ‰;w}"õSÕ"…Ðn(Ï•âˆÂXq¸LPG Š#ÎHŽíÆbÿ.Î]7ÛêçúÙV7ÛéûEŒ¶ÒÑ…n«¿T pÐ(ØÝ¦YTB’²ä…aN‘ˆ,úqÚ5‘Æã‰Ç["™¿ÍiÖw{"c›õGúƒˆ0…1"r^,{)1‚.÷mRî{‰1„ЈŢàxDëkåÙÀ©W:Ql îÚÚþë½ësŸ»1†Ñ±]qï+ñÅ|øu_2øü¹/ŒýýwÿÉMwÞrñéK`C3:¿X¤n¾6¦õ µ0'莭&ÇG'noßM7íßçÂh<Ç0s#Û Ø›v:˜Ï»Ýýó{Óí<•5oNF—]vš`þ…ÏöÂþÙÝí[OÝ[pܺ-ß¼½õ…3=~íwÜïªûÞ놟ËÇÆ 1ÌóÊd-¬Âbg7 MyrÛ™n§kbPè9ͤÛëš–×!@î÷ç ×(;ó~>'æ07ç¶ÎÜyË?®y2ÆQ £v¬{d , ÍD÷Ë*œÐ÷:ÄQU.Q—‡…ñQ>¤ÖÃØnX‚X³®ChÄÛ K‹¢(ÂÍèh9*1'Ns@Êý¾~a7=—úýÐLP寥!è‚n½Õµ©äÜ陃Ù2½­d礄FÛópF¤¾Û+a°Þû8X8ånÏŽçyaOÄÜOõÁ“Ó¢ÔDË'÷>¦Þ¨P3Éý8-˜S7Ûîg³Ùl‘Kß ‰´±y 1„fR6ûèŸqK„vM»9}IZ ízîöD·¾9Íô!c»¡k±—±4èd@(q*u{D‘âX{”~±}èÊTbâ8-vq¶{;Ý~fšYRZ–UyJ!æÌ +ÉšMä`æœÍʦâÂú_Ñá“ú¥áå=„Ûóʦ~´~:ôûîG?袃Ï(ÍóÑåih"ä.Äqˆ“ЬÅfÔ¶kz+µ¤PìÞ’[‰˜s—úyŸ8\,˜YÖ&‘sæ×Sý,ç^DB!6¦ÖÔÜ]æ.õ="pî)6kfì㤇œûœ{­Ù)3!‚¨m )bå ¡¤hØÕÖ©°æÂ'Dê÷}FÚÝßýÄ'?ú®|<¬o?uåî{äÆäÒ3wžm>à¿0;çÎÜqæS7¾óÝoÛŸú¨žÏ-:î·æãöðT(wÝþF\Œc×5h’Ãñ¿ûÌöíwÍ6/½â¦þsãõËy|â$ìoÀÞ…ùÍwnaŸ·;èxÎhmmã8Œ/=:9Þ¥oü§þÜ-9ŸÝ¾å [goß9NÇ¢Œö¹ï˜7/½l'wNæ{ǰ훜º¦‡&И@³LÝÚ‘£ç§y/50Ù˜MSž§8Ïcµ í^fè9/bÌIº¸ I˜SÂî^¾°»»èy›sÄCˆ1©~«:rŠ_PÃ…O~òãÿûÝÞ¾úþ×]{ÝÃ?ý‰[Þñ–?¿ýöÝý½éææ‰fmýÔ§Ž]|êÍ¿ýškø€ëðEÿëwþø²^%æã3@ laúÐdh±šïÌÇM<ûùs‹œ¸f­ß?¿uËYˆ›ûãÙúhïï^ØÞ›CN„”h­Èz˜í6ñÂÖwÍç[ópó­<ŸnŒe,‹9æpnÁ—^v¯›î¸sëÌþ•§6ÖÖóZ‡“>ïwš€mìfÀÜŽR˜™‹9@n›©[Ì9÷©è…IÁ`sDMCyo1›îŽ‚Dˆm#mãè@—V…âH {i±[„ŸÚâùf9G»ß£+FUl„sæLÁµ÷ š2+ãNM3GÅ’pš+‡!4ëZ+ßÁ•C¢ßáP4U ƒA 4&wWÿ™/y@’œr^¸ey°«5=Å9!r±–«J$Í·µXsîËz­|[eÍâ‘ÊâHÏà¥òæ¾ó²µ›ÒÔPm %Û#Ä5ˆÍÄ>#ÍD8wó­ÏÉzð¯üBB«¥06k€”ú}(IŽÕÒEþqqµ¨–â‘ržë@œ¼žÓ\8å<a\FÚ9Í8ws¾c>Û€³[‹ÿ—·÷ ¶,»ÎÃÖZ{ïsnz¹_ç0 1ƒ@Ð ")€IQ0-û‡].«T¤]–«lÉ*«¤*ɦdI.IVQÁ”l1HŠ@ ˆ!"Mf¦'÷LçÜýò½÷¤½×Zþ±÷9ï¾îpH©Ü55õ^÷½/Ü»Ï:k­/9K±fÅÿÇ s¬¡·”ÎÛ[Å(µŽ•t¶ Ý}@+Äš­ž]Ý­¶3Å4ÌÙ¯i ZE²&F°µŽqÃØñõ¢aûÌê[ã%$›Íq¨C3Ž'cz-ªžìAÓ¶†£SMòîÆÑ¨Šrƒ{La%‘ÆûP7 Šþ—®]fEõªKØb OÙÎ%““õû9¦Làˆ\‰p“Lb0©?cfg¯ï°s:_æ¸; Ý6‡(žN¬ÊêùgŸ|öä3›;̳|èýÿôgíW¿øñŸ9täÇÿôO'f<¾zþÂö×~ûß/¬®Ü¸xæcêÇ-ë\)!A×5Tu5{ÎUú™ ¼iê¡€7šb{{rs ½ñ$¿êæÖí`F–k*&ªU=Áf.·ÞRUoV›å¾åÛcXßÚ”zL€3“ßýØ#§¿¼Yš™þ°7(ó 2àŠ€Hˆš •‡ÜúÃAS7YæØshšzRah}#€OjïCð¢Á0™3¾i&;ã¹~ƌܜ»¸šŒSöl¤u¡­*ÜYG©¨‚MjÎdΦ³¦ñ¤ÊÔù7·f:qäŒrd2H}bˆ(‘Œ¤kƒ¦cƒm²Èc›xöb¦1Ö€e7t}jüE¢{CâÀ§jS´’ö):–ÍŽöQ¤|çìÕ&H²†²ÝWjªƒÏdËðo¡$U§ÊïúÁ¨Ðµ>°'w'¡Ve.ëV¸LÝt¸ûbv®ZdPR!Ü´)ž ì»Jj²¡ª€Hä-¤ÍFŒ(ç&ö•­=q˜eø&w»VòÃP“q ÍT•ë:°¨!´†¬%iµ¼±ŽBWCùNDÏ®»œ]šä»ÜF1ºÃ³f¼qö‘]¯ Öº!ÎøÓ¤Èõã'nLb7:cI‹G’aÛ3®olÏf#_ï(Èx21D€`Mk§†Dѳm$CðˆÁEº°³N%$Õ.gÀ’i„½ˆˆª÷9̆%Eß@k3$K¸{†¢"Jid †${hC¤†'ãPa´%ˆL¦•˜©¨¢*³¨°–U¹víÒ ÏŸ|íÌiµ´¸zð£ŸþØÜÒÒ/þíôÿü‹Ï=r÷?ú'ÿ×Ö&½ëm÷í]/ás?ù3Ï=ý­áÊÒS_yâC¿ûÿØë§^0&ì¨ÅWê˲hL“eÚo ¦žnÞ¨n\ÞÊç>𱎜Y_Ûëûõ6fd@l]ÕxšåV°£Æ›7s€W/`Ø™›s†jm1é÷G=úöâ ßijidâ±i˜=€¸Ü¢ã<÷lÄ4•+¢¾Ñª µg‹Æ‘d!ï© $uM³R)v„aØwD*Ü„ºöÆùR;#.%c9c(ɸ˜ö: [“«r´W *hQ©¨ÓWá¸XDréFÞŠ)¢®œ} *ñ¬ x2ÀíIàÆ®RWË,ìMnè$ìªmËÖÔY#¶Ú&`&Ÿa× cï7ž»í(p¨âª,â…iŒ™“ \'aKÛìqÉSñÍx÷/#_L‹×§ð2™£D“P_¨tÈR–¶»pqTc¬rhq?âP¥82$"3{ãñåVëCÈÑì5ͪ\¥Ôç #›/Dü™¹Ra™U‚€†f7ª ê,å†ÈäÇ&ò±ô±ÞIñ7ÎêÍ åÿsKûùVÙjêmî’RZHÅ£±”¸ÈÓA˜ªÌ¾–P…f¾ Í44U/·ÑR=q§¹‰·½¢bfÈf™Ë²,"’„ ,ãIÙëYg3UáЀ¤ŒÈõ;*\sD5ˆx‘Ä7 “!Bd"ìÒ˜S6\ÜÄ™¼µ4EUU²H ¾"²q"A EÒ°*ˆjU1"XƒH|8úõ7ÞxéÚ›…ç¹ý«w¿í^0ù—¾øo?ñôÙ3§V÷-þâßý»;ïÿø7ÿõó—ªúQ“Ã/üÕÿó¯ü¾S\9÷Ò©_ù;ÿôËÿáw~;ûõí–â•Ë—×&—œå~Pýú•¢š†j®¹÷Þûì/ž}úäÎÕŸúÌÝ×ßšðÖ3ë²Å••ýûzÅx£.§†Ç™©N~÷ÅíëÛ¼ÇWõú`d‚¯rtýBÝþ}K+‡ßn´´¸:À9)*ôJ"`ÜT^EM¿?ª½-w$Ô8öêº×½¢$>¯‚¨'R²Æ‚X—™<ë}©ÎªPbV"’É(^áì ¤6b€;â·S JN¸é£Ì­äѨÉïÈbŽ'3Aöd”SEKH­ _ã'k ¶¤BÄ»öÁulª®XtËÓ”1À¡Þ‡Õ5V)ÜÅu¡OˆO­Y(Eb_«×ŒÃ{4æØ±ÆÝTC9(î¡f 7*A9ÜÎÐLuK¶OÀT¿„2²ÚJJÉî25Œ]H"w*ÕÝÕvJÒVb_’͹)T9øiDÉÅ,¯¸¡æÀ{dc”CÐ)ˆ®…›ÈŠW¥r¼Y¶KEß4 °$‘Ò-ËÍԓʶ¢·C@w,©·L÷ÿ±H}LÖÝ¥DìÚ‘ìµÕh ŸÒyb=i .×}µÝ”u±æËͪØáÆK«bòšŒ ß,ѬÝXBM™ÔY¢äº„๮Œôó~/ø ñ œ Xkš*LÆÂ^¬µƒ2™vólK”¨!cm_A³î÷ÚÌšZ¸îºÑ®®[ã.n¹“»2¤LAb_vÎd@$¡FƒÂ 5Ù SÞÕ}Æñ¼åT¥µ²±¹²‚ú¤:¯€*¡n¸jÊ~NçˆdÍfKƒŸÎd™D¦‹„ÀMâQ4“îb"5zÅ2¶—n]Ú¦ŠEncµ½+ùGT >x/9j¼°è[” ÿÚ•Kjmüº&2–à?^Óz‡2Šd)ñ'R©ß{xXQ—j–P%£L®ã±ðÕ‡Ò×ÛÜL|½3-Ùe#2¡õfÏ,¢ÐÔ ‘Zk£ã8‘%"i|ÅAãKc-ôú£X(¹.‚¨‡Ð¨ŠÄ9ÐYD´­Ï±sl)vûv=䀢×rS7Å9GD1õÝtÖ˜(÷ɬ®}1™œ>õÂ+¯<;O ŸgóÍqQzàÁGç—·/_ßêÍÕhìÁóÁÒOæñ_ùµ¯Ž· ›/-¯5vð?ýµÿÊ™ëÿáó¿¶°¼ð+¿ôk½€ãÿ…c};ž›®ßØ ÚTUäößu×уœ;S^:sua~ù“ÿ¹{<ü¯é_ü«oq>7C¶g„* ¶gæ—çN;úð#÷}à±w^=¿þïóëçOžyôí¾ëЋk¥jþÀêÃýl”Í-ßó¶û¥â3WÏÕãMc¬ƒ¡n*ïr?×Ï 6W¯ÙK€¬X{½Ï YqÔˆfÏje£¤à|hÄZ÷µì;°Là–¥a;·¶öÞ‰àÙ36›çDñ]žMû!Ò8D#è…ò´'3ˆu a[+“¯£íá,¥¤›è!F©E–xR$#2 ìUün+,¡ž)÷𠍙XI#A=uO×JE nK%T»ùzmÈ®iWk¨òH¤ÊÀ‰oTEƒp4¶3þ r3à&%'KHtׄäˆäâ‚"öuÃï…B<ÏU‡2ÒÑÛ`íVrÖ:lAÄom6Jt«™F5Þ$f“rÚðJCäB3QZ‰8pÄf™ëº!JV±€F&–¢ —nŠ„ï¡{ µ‚$çvÆ¿ã–Óš[yM¢pKu~+méíþ-£½5&×Yô-éšef/®-…E|h¦‰HÏ>2¸™4åFh¦Mµåëí² ÂÑB)ª•"àU×TUcÉY›&/Ek1ÊFƒ¯DQ¤aVï¹—Ûøƒ"FØ #sʈàm"Æ]UûMÃnjÎ8­’qyÏ9UB ÌÁW¢ÖD…R’|‰Â¥ çž}ú[—¯_gM¿W°–EãÁ7^ÿ±{ÿ‡?òù_ùBÿé^]ׯ\¾ûáÏ]¼~íüïáÅWn<öÞà£?{×Ý'¾óÍ/þ³_zvayåÄ='Fùá'¿ýÔ¿ü—¿zyíüw¾rýêêÑå¥ý nØË²þ¤Ú|åõ§C#}”#ùr½]½tñ»‹ÇÏÝûžáJ–ß<}ss§T‚FasÝ?~×§ÿôc÷>ôÐÊâ±y»rß‘9râÁ“/¼|ùÜåú†Ç^Ø¿|ö™Í§¾÷Ôù•söç>ãàµõf2å•‹kXnnAUŽŒÜÜQ7USWEMÀ—¢ B>8»9‘A>Zœ[2ÓPV×ÇÕD@òåh3EÕ ‡£à kÄ «¯2YôÐB²Y¾Ãnf®í§¢N¥ëògr¨$*y\;Û’°7ÖÄ©0²·Q‰lÊD¨Šá´+èXV»®¸yœ®bG¸KަWùx?`O‰I¾Ï» H¬~nЏÁPuÒ—.5¯³ï#²Ì¡½Ê:ÜiO·1½ƒqO¯šZÄbÄ‹ÒtÜÆö‘ËZcù®ÙÍ%T"j öé÷Œ5X\>ßn<[û`J¤´ˆìíâo¡VÔÐLâÊ¡jEÚÊðÓ~÷Ÿ€ã@[jm\{ï;CBº/Æ 7L´‡–4[õbm7¢À¢ÜšåÇÒw{L8ûm‰!©ìÊúÖYnÓ-{Oiw²4 t˜Ù)ØH¾eÄu‚_ØiÛÝJAØé@´bÌ•„:î…CãEÅÅ YÛCBeñ"ŒÐ>TÔ9ë\f  !ŠŽÜDHFcTÄ-‘MwrDUñ>:;tq€* 3§HB2¨” /€ªFÉ’ª‚È bÈ #³ QãRog{ëäSß}ýÔK[ÓsK™ ‚xåÈ~5Yæ½áèÛßúî¥ ·'…|äȱÏýôÏýÅŸÿk_ÿò~þ¯ÿýÇÿä_øƒ'žûÊ+ߟl_¾zåÜÍkÏVEAû³‡÷·¶¾ú…ï,¿²üÉŸþØ¡ã‡Ô°›3Xת¸~ö¶‡W‹µ/üÆ×|uãñŸ>þÐ#ýUÈò­£Åõ²Ë×Ê/|éû<ø©<¼]çk×wª<[š[¾çÈ;ï9òž—N>ÿì‹/þÖ¿ûÆÚúæŸú±ŸüПøð7þÃïLê*÷;Z×\Nlðã¢1ÊŒ^¡ð 44/=gÊ š²ñ¾†¦,kuÎùÚqKsƒ‹×§'_y}iiù+ˆns:™”•gXXÈp47Ta4 ×^Øå€ÆY"ש›‰¬ “ÍM6¸S"ˆÄ­_„7Í[ëkjí)[´&TÆõ“@miCÍ@reäT@ÄÒ–|WUe A&Ü íŠgnäpdþI:á¾cþ%ýqû°g÷©ýlŸÒ6‰»þ#êÈR˜IdÚ½™ëÈHw nÝÑFKyaþÇD¶ø*Ù|.j½„›Xg5„Æs¬)dTm6²ˆù`E“Oyü¥šôc G¼>Vj@Œ­Rd¹ªªp5ó3çݨ±×3Á@hÊÀRT ƒžIèÐÞÆ†}ÛxUkÐ6^¢­Ph·¢¢Q“šS›Iz§[+àñŸØ{ÎbSwl÷ý_|îϘ‡\»q¹ÜY[Z^ºûcé/ÿüoñwÜw_/ïÿÊ¿økÅÆúµ›g×nÞ¨ËkYn{YŸ,‘ƒÞ¼¹çm>ö“VÕtR–U¨†ss›^kóÎÇÞwæäÉï}íPóÉÿ‘Ç~d¹,¯]k¶a8u°°4¿8°`4yízøÊ‹—k`ɰ}?¿OŽìï=ôŽ»‹%øæ ßxè¾cŸüøãƒåÅNÝò“—¿õYl‡vvv¤ærk:VÔÞ]Û8c ¤ÞMËа™TrpÿQ—åßzæÂ3ÏÝ,jžË'W×̃nÿÊp07•i …Gër ªÔe•‘s¹Í@," ù%#Ò1]@´Qáˆî¡qê4ØZcw©Q Ì @„\_X¢¤-v=i¿ß"Vcò.¾I•cQNÝ+7©ªÂÞØñ]±‡%ʰ&º¨ª°´Êw‰¿—±’w?ë±?ëØßØ8·›1¯­ùNwM“§}ˆJÚ°!&˜&,ÈtÈp4'å"—C¥ÊÂB†l–uóœ#²‘Öí›ÉÞdfN£½Ip–„šC'÷Š.PH&®AUBÕøhÕâ$§ e͆0Ïêºéºl ¬±H±¤kW"©60û ‘Ä3ã6Þ6±GIÇ꯻|£;¢êíJ4õ³·ÐŽÛ¿Îl§y; µ+¯"ú&¶Íq½Òý-¾¬¡™t¤â(‰M›æd»ëg=b+Ú95¤Õç »«Æ K¬“É(Dc-F¶¤½Râ6sh+ÀèÑ­Ñ•DÛ}+ÆåÉ.Wô4%ƒP”)JÜv%À¢\‹xêB¥0FˆŽvˆk7o<ûô·^{õd>Ðqåóá ?ØáÐô{÷¿ãÝn0:wþ•K×|ôцýõK7Œ5 £ÑÂòü×¾ð;æ¡Çûê—¾°¼rdãææÅK—D¦*Íp4šNÆ[ÛþÈ‘ÃÛÛ`˜\3?r6§Rš¦œÖÍ`¸üÀ{yíäOüÛߟŸÏüg?zà ¿zå¦ËXÏúUăk¼Ù*ÊIÐÁþÁØïÀ€$Ôaê&¥Œ{Ù˜Ã=÷ùħßW›æêÅÓï¾ïþ³k>ûÙÇß8õ²ŒëóWvŽ]¼|q½ØÚ,Ö7§'Þ6(ÆãºjFÖ ˆ‚XSL}xyinaqøg®}û7Ux”S?7“‚Ã5¿SÖû–ó…a>-jtÃ~¿ÊI𚦳˜ΡD ELKÉÙ*H¶G¶×rDÈvÃû®±ÅîÚÚP—>¡ìHˆdÇ6VAµåÔD Ýö[sœ–¶¬  t äÝzs‡ÎÇP¸Ù}„:Z· ²igvž ¼¼“ý]K ŠK³X……k“Èä¡ÚAcc %²DÍž5H}&»e2Ùì(ÃèãrŸH‰™¬s ˆÅ7uE¡º%O¸UT7eGѪán:Žo ‘-‹)‹Šh,‹¢»Ã¯!…0 ¬2+·€{W°˜œ%°`'E Ûö˜·|°GúæÕó–¯p ·ôŽÔú·Ho²f÷¨ìêãý°s‹ðÕ6¨?mý:öC"E‡z¬-1-¡™?åP†f\5Üx©k¶ Åê1œÉpð!Ô€dL øTнc SUT‘6€;rTâ±&2Í “Sºtvâ1°£yj!ÙÑÏDÚ929"‰4íwé\gøü¹ ßùæãÍmGKWnn5.¬îsÑéÄöæWWGGøí?xêÊOýÌŸ}ï»ßþÿÆß¾yãü÷îgÙÕ³gYêþÀüÁ—¿xøÐ+£á¥SÏ;g··¯-/ïO·€Ëb º²ù⹫kçócýO‡ù‰+_{ø¹³îà‘/}é·¿ý;ß{÷»ïþÀÇî[8PÔõ…iu¹„­Þ(÷:èõç*žŸ„a᳋ç7ΞÞ~ôîÑx§™Ê.„I¹^Vg¶6OZéò°qmkRž¿xþÆµÉ ïùí ×çïZØ9ù‚]=8/¤«£¥óþÒ¥óãµ+Ó© ÖËóªöÚˆuy–÷F«s›“âÿú³®ÖÞËÀÁÑ£ù'–½åµí×ËqQÌÍÕ;þýz`kír–[cÐ*±ª°aTd °v ám¿ Éš‘ÈjR¯[D"›w[4͉¦í¢š˜@Pw ðÖïÆ!¹XzRhX”NI9'i $žlofSɳ¡Ø.ÄO}µ«R¤p¨báøcp(»U¦37Ðbñ{ñJ‰ß éBIm¯G²±M&×GÌ5)KH¿ *C;þs7Ë·íœ_’ÐLè@ì=ÑD"-7ŠŠâC3‰[DT¥Î‡T¸ Í$ÖÍ7Oóª(8‹"M݈1UYq·g´6½Þ댘=µ-,®:D˜>eQDT/·”×[DJ·,þH¸úìƒo•{ÞZpÿpˆ)ºsï ¢ÚN¬„JÄ# ûR¸ ¾ˆ~±‰?_âµ\^[ W²lUæPI¨ƒŸ6åÆÖNU”<-C¼Df—­¹l$²¨´©ŠÉ…7Ƥ$)'wæÍ’4&20l:I{ýe#ÕF[¶Lñ1ÿ9ÂS)؃'ƒÆäÖf¾®Ã+/Ÿ|ýÕ“¡©ÍÆÆ–88râȾÇLoà1«ëFžýþ³/=ùÔÅÓg>õÙOÿâ_ÿ;_ûÕ/<¾êª á¾GNlln½úÂÙÁÜ\YL®_½è}¡šøÃ½tñ›§ €Ön¬e³´º¼~sò¯~é×?þÙ®î;þúËÏŸ~õôsO¾pþ̹O}æOþ¹ÿì“Ε®=Ó@5·äÄ¡Ûë|C¾‘~6äðáS¯_¾|~íød߯úæth@·½¡‰]rË"üä·O®<Šeμqa´8|þÜ ŠÛy?þ…‹VM¯ÉGýž¥ìÜ¥q¾jç.PphJíÙ‹¬5ÛWÖÆ£Qóþ÷ î?ql{kß¿Ñc³²¸º²S7DërËF¼!2–T”ÌL)Q 0í¸MÔÚ^¸l4c7N„f·qS芀h%Dr)ˆ 2"² µ³0R*4ŒMµÑd5NHZ¯9PÅ4¶uÙãÂA•;§¢´—Üí@“Ô§\Üu¼§£ ­ÚÎì!šƒh+´® öÒä”bTT9$ªHp:{ l…[±jÇ &îM¥ŽËº;´Ã‘>±Û,#Šp¡’he’9BL}¥¹-?¥åÕ ! ApoOK¤$W,˜ý×0³gDƒé‘·©‘÷4³³+ÎX¼n‡ËgÍJÞLÚ”jâ[, w,©Ý3¢Z¬J`_¶ØQ"š°/Uû"Î_Ì5¢ñõNB-[|\%{ˆU¡¨˜’º#ò¥ºä)@C؆/îÆÅtžiI1›lhE!ò@¥õ%"JÑ{Ê’›wkë­ïüˆ¦ ßF’¨Q ­5ªXÕ "£Á7Å+Ï?}ãÚåb»>waíâå›Ü5_½-Ë~ï½\Áµ7®Œ'Ó}‡OdÙè¹'¾ó—¾ÿ|(Æó+ƒÜñdçæÑCû¯œ>ÿêso8tG7¯\œ¬Ý°àÊɯɧ6릙ô'“i]ëÎöL騉#›;;¿üÿ_ÿåüȉ|4¢Õ«RŒ?ò£wÿìO?L|öúׇͫsuÛÆm;Q×ä9 j„‡½ÕÚÍ­sýQùÈ XqV +”+¾¯UÎëUÉ[[Þy¿6×RóÖÚCs\ÅP‚€½º] MŸ×‚­a±7ûÐ1›Æ‰Ý)ý椎{‡îYŽzÖù€ý¸&»n{ÃIÅ,Ìçzy–YÊúKÚÜ`Ö~nú=“Ü £F¥õé°ÙH•³½¡ @qïÖ}!P*"dQc¦7u–*Ç`¢˜¶­’LTÙfs-Õ”½Ëç÷Ö‘ ˜\ìZ{*ê4kw%5Mß<ã÷,‰25ãÚË¡ö¡“驲u– w³6A…#o)eBò$e_v5ŽÈª”"!. ¢Ç¾ÒÞ†J5n.vMÓi7ç9žmáf6_ƒm¬ÙuTDï=³6¾1{™!CdráJƒG³u@„~ÏÄÒS7¡•Ø6ƒ+>ö­â¥—›™6UÒ[à: TRã[—À"Øm? wÒŽ4¬ ¬{”ï·˜†¼Ù\Çó?]4ÍYÿ§XCUÁ*¤£ÐÂDÝEêL£ó¦°h¼E#’UáÎc&®«}3aiã\£9UÊÅŒ¿vÜhK#Ì1›ÞŠÄw‹÷v‰±K‘ó( ¶†  Â^$ã’7ÊlhA¤Ò³OùäQß‚†ŒI4ƒ6>DqD´Ãçrg§xíäwÇ›7_yõÒ^xmcs‡”e½ãðõ/}ëÞG¿ñøÏüÔþ÷ì37ãªþ_ùŸßÿà][_ÿò¯þÚɧ¾ ¡É\æ³>l¯o×U•¹ Šj27Z¨ªmcÜÎd =çd´¹µ¹~cûžÿƒúWVäëåE—¹WNžã:ñÆÆf]WlY+Ÿ9ŸõM‚L¶ëº¥ÅìèÁ¥ºqÎl\:{EûŽkúÚ ‡à ^àÐÁƒÏ^ØÜغôÆåÕûr%›[“~Ï¢…íquðÐ’ñxáÂF³1± ÏÜhHލÜñÛ•¯)‚ ±s£ô‹¢)?È ê:C­›º ÔõûÕeÖåsn”ÊXjSa²¤Ado&ŸC ,_ˆê81YÔ&AgýÕ¶P|gP €Vc0o [mm•‘¸ VKŠLëq¸£­ýz1´‘¾¹:íIÍ!öShsI PÚ¸' 2™ˆ7»[U%$cv½LŒÎN4LUfI)öÅŒtêbÈ2W»2*MÅñ¹Iðn\òÊ pÓ:*é¬ùdëŒÆZÀ!A`a,u]s®™Õ ÎJÕpg\äÃl¸4¤üZJu“TfB‘‹ÕÙPµÏÒ;xÎ~«dü²¢é "#­¿Å-%ODßLÿþ–H ,¾½5{›;zV|Ñl±})4;H6m»“§\“DÌ»’µè8ׯu±/U9ª?ÙO'EØû¨@è÷{(ì1m:EY|$“ÆJÊíÚ€YX¢‚2Æ”imQKD1‰Ð!´,A„IÓ}WC[ÎS É$ŒI’­+ÐeVD-ˆ5‚ãqõÆÉ§žþþ‹Ïž|ýúÚdÙ{8|âîCw8tøðÀÚW_>õä“O~í_ÿÖâÒÒüê2õ`qeîý9P¯Ìí,ô,¢kÂüÜò‚êUB$û÷ï¿zùº`˜÷'ÓÂõóºnŠI½ï@nrÙÞ.—çþÜùaÜ÷½gÎ^™Û?Èpxyzq®(ô×6®—åÅ¥ev«=^©Ô6Á… ®ï5_è£q;“ÉÆæ$s«\+æyésðMŰ2ôû=_põÌÛØ“ 0 Ь·TîCÏ›ëÛÇû°3 W·wt`67]žì4åTçÜâ⨗;ÓsuÃYÏ ×ì2Ôo5JèU|í¹—;°X×\3“És¢Ì@Ôhì‰KB² â›q’EFþS4Ùlyï©’5 L§.ü'9yCôàÈvÃkÑ qè,™LÑ@kóزÁnv€"¨7HNߨí©2ª°²²·°7vЮPÃ-~%Ê•ª9E6­kgü.Æ f©?‰DÊ™3Šóx$c*áZBª¡»Løb$"k¡™ì::‹p(BàÙîL5Äé»ÛH2kœ»­Ak)6V±â°hS†˜;Ùx AX`GÙ3\ß^»¿LÃûLô[ÂÛúÛ}p˳ººÙQAYß´äýpë[ o;zë" ÔAö±†v¯e? Í$î˜ 1ÞC#˜Ø àÑb–Û+$~ÍkÏ—ø_U%h,µ £Ý@žà½÷ž ÕÑÀÞZVc”ˆˆ,†¤3 *  @”‘±dŒŠ@„€wEu6¢ÀDF“.”’SIòîV&Ê¢*_Ø«Òx\}õK_xâOmmOŽÝs×gþüçöŸ8a† ƒÕ}s+‡ö/Îç ¿ïG6ÿø¹té¥çŸ?{ö5oªû::ž^»øú¹……~6ÌòA¿Ü¬6Öv—œ{msÒfyÏí[]¹|隀6>`]× ÚåYîª0öß¿ôàÛ÷¯_,Âf.~ee0\6[×wΜ¹`Û«lØ ³Aæ¤â¦Qבּ¦œÈåK;{‹+æÆVqåÜöÑ••õ듹CK£Ñ\¹1&Æ-/«ý^xî¥{8ÑlTƒafè+™TlÀAåûhö éú¥zs[rìlÞw+«ƒ5[L|" z9ˆrK# AƒT"!#HÊÂHÂ,5Kæ°nØtJN…^Ï´W€€°F«´²#’²²'›KþªvÀvZuæg:@) Rˆ0/¬,‘S™Tó3b' 5’…ÓC¶QÉä*>Öbâzבa¦” !œI˜Pa¹-YO“]»<åP·›_QØ“HÑ.R Ù¼‹!éxû)rƒˆDiªÄímæKš¬»Ú;»¬l“ÉÁ"F±P\}FŸ~g’.ô ‹îºÒů¿Çpøv â¶ìr÷¥R:ôî·â½j"¸MtË„~ÇÊx otÖô?ÕŸÛ¿ï-_߆fÂMwXª’ &aá†ý4ZÎÄ÷¸GGŠFhÙΡ¨ÂÎÄO‹PÖÜxñ!®´ó¾N1”¥$5Ö 5C@19’ªÖêƒQ\ÇwN5t7$ ! ¦È‡¤¬oÓ@„ïUãÒ¶(‰‹ChLÚ”âæVùùÏÿ›o¿ðâðØòŸø êè½÷ÙÁ`ìpqŸÛwx,º¶v®odß¾Õ‘9øÀ±¥·à±íÍO|õ·žúÙw~øA <…’µõTW~gçÊ#ï9VÕÕ•Ë›“­ÓƒÑ`aaq:-(†Š-¬,Q¯OÆMSÒï<Ž}³v“z£%!Xä½¼qsrÓ q€s[•‚ɬh32¤l – KGN¬œ:½vþ•Íãï&[;*°4Æ‘Ÿzè÷ßè[ßýÁÎÎt™éZ±°4\ZìSãI¹4ZØÚ„ßzîµ­íÚìwÃ¥>öòeæØ±…­É¤®{ìF™ëQkhâQg\Dþ\µ  ˆb–9iT/™#u¶]’'DŒí‰„Î#8¡™DƒŒÖ¿ƒÉ¸ÐLÚTèÁn…ƒuý˜!¯H@ Š1® Á¨% *Ñp¾ã'®(†(vŠ‹!ãú*ÈF*tËóo#M«1o¦­]wlô’Q¨Œ…>2XŒ°/¢>ØW±øE™‡:¶Ø³±}jšIìÊwsk@ã.5ÁñƲ/)„zoIb¥cx'ä¿¥õƒ¡„ªªeÍ‘s¶J¾ÝŽÝVWLC‹Î~—®åŒÖú™#Vd-µ“ïX÷]Ù¥öèäÞcÞ®/²†ä¶èùØœý±»Ñ?†ÐÞ†zÜÔÛÆæÂÅ—-µÂ‡f‚Æ‘qÉaQ%Ä3ÑZ%BQ…¢âiÊZÊŠËŠëFâMU…€Z-H™Œ»£ñ*BÔwÆ+Ñô{6r˜fäÆ\–^¡užDEPÀäl,©RÔŠ„Éz@„Ö"j=ˆ€€jTÅYŒÖAã­éçÿíÿ½ÃüÞÇß?wô..n„©”°´ÿ ò+k×pØ· Àé«g›‰?¸ïp>È÷,./_ýúå7^8õÐÛ8ÿêë—N_É]?[n®­¯ml]¹H‡Ž.7u¹½Á£»~u@–™Þp4·0ÄÌôswåúµ^>ú‘-GçÆH¦kmÈ“}-’ÓN'žÈ$¥^òsB@£$ÑàBÙwayÑ÷s6±.Bçšö¹ÉíX»ÐºhºL–}oÖ qf¢l§ñ‘Tß93u­¨!ô­5ŸéøF {!½¥ AM‹é’!a™-giåG»Ÿ­Ó:b×?vhÆ #žœ1Õ7!®ßÑ}ùŽUì––óvòæìÃþÓNôhÁµÕôz]¬Ùl ²¢09iNŒ®C3Žu­*w˜µjb1Ò„ … !( ø !UNö%ŠH„–œÔ%5 Z‚‚D7-kÐZkl A´ Ïªr¿Ÿì¶€$úŠ0KðB4ÐCcP9š-+ †ÄZMž¾eJ‘µ:Þ)þýoþÚ ®—NËÀ}+ìú,€S¯g²ÜVÁAŽ}ÃN-âëêü3+óËû——~ôc~áûOþ«¿÷ËGï:VNv,¸Å…•õ›ë½~O°8ñÆÜ`püîåp¨±Î­mÖ™cK07—£!֨ɷ›ºØæGÞµzâÁÅÍéºêP‚3¦)ÇÃ+gÇ;E1\Úì;€Á°?ÊaXL¡OvØ få:×5²£»ºûà¡‹Ï<ýòæ•íáü‚‡Þœs¡dg²J‹ô~û¿û¿zæ• Ç2¡×/ß|íÌù›Ó‡W¶y¦yÆÀv«Wi\† °ÿÐèæÍ­rii9kŒD£ãÌ8$8‘–ÀÀL±Ã°íõ“ç™ÎJ$©£ÚMômÕìËHG²dœuCæZ%çì‹÷K¨Œ´DU0$b˜Bq¥˜2 u7Ò#MÓdDB£iH,ŽÖ ‚‰öì E²¨ÜÉã>ŠC¥@HÐYG‡PC2läø_\SĈ§¿¨ÝuU–P¥®¢ õЉâ "…€@šŠrš}½“Ì–À¤uªpݤV£ñÒÁ%óŒŒ2öÖñÓ8øÇ!êÓÓR’EHî\è(ïi–®ßm3g «B3!H±>&rèLæÇ-ôø[ fh…žwÔeÞóy3eѵ!½#Mê‡ÃVÝ_ÚPC3Þ½‹ú2N[ÂA¸ªë&Ú®toCkV˜ÞU,Ñ]^$ñ<9Th¡HÆ‚€j`– b>DTcуhAEÕÇþ\%êLÎ"ˆú²ÇS"¢ª˜ç¶×‹ |Ø{Ϫ` 8ˆ¨-¼ß镉Ìv¾üÅÏoùâžw=Ôß¿º D&§¼Ÿ™,ÏçœÉp0åfÐØf}k§ZÛ†nvŠìþƒK|×{»tñìþƒï%¥s/Ÿ­ƒï‡b«ÀÅÍ›d$¿ûÞ¾gO€“IM £Q¯˜Êt»L ó ƒ¾¹º>ÝO– ?®jSCy5öã­2ŸË™Œ%ç‚8—“Í|LH¹­ ?¿DGï›{òéòõg/}ôÇŽ· ?®•pinÀ¾¡†A—WV®½v9£ìÒÖBà­­r~ixøÈálqXÕM6B¨ÀøáBÏPøÚ‡Pæç²É¤,ËÚ°ŽˆÀc¦º¬#u$¨¨1½Üúz§7´& ‰Š:¾Y†šÆËê>¹¾]Ïel¯©¶âÛÍ1I‚pÕ‡d¨ Yo±Å1B[=»1NÓâùñuÌ!i1Àq–³©mÓšì‹n­¡Jí ´­’Úq?÷:îE;D+‰A "™)Öñ®zvìË;V«®í*Z§þ¼½˜¾•ùGîÿH[Ñîç´ì ïð¾éú±ÈÁ 7¾OAvïBÝË!ªÎRÝH`U¢,ݽU¢>y:´±‹mg§:BVõCw»î¸ª8æb–‘¥”i H14.¹¢.™¬×&?ǵ@z‹É Òx2ý7¿û…rˆ‡Žžhjîå ½ÁBÕPîæ,ä¥TÖ œë0¿³¾uccûê°7Úwษ|qeý^:ùï{õ•Ó¯¾1¿2wåÊUê¯Í‘ù Ôœ~éx%C¾ÍM??ï f<ñÆÚ^/ßÞÞ™Nx{ÃùÄ{ï{øÀž>uäî}÷?rˆûý¹P„Ó¯½úÚ+g–÷³Çö9j€'Â,ÖpZM8cdÇ ,î›ìƒ÷|õ7¿ûÒÓ¯ø#oŽzÌd}›–{ƒµk/½qú•ËÇŽÏ?þ‰9théÚõ í ó~Ñ7ÅkW¼çþ|y©ï}S”ÓÌ™À2‹M]C†ˆYL`cI|ÄdH•!™"ŒƒÌ¢xTÀÚ `Ô§5YšŠ*¾‘¸Rï,sŒAk(Ëì.«<¹ÄBôÙKá"âg ÝÕ©¢‰KÒ$oçÐz¹“AUPa¬gºÔ›èà™4 ‰Ï1âA‘‚ŸFyÚTj<ÀÑ$a»ÌXÄ'5=¤¬e6^)> †Ä©p*Ü­qI¤ÄX7pqSÜYÌÅÇÄšIߺKµ(Ãì´³AÝÓNÞR@no;?yhCÇ2KÝcn!ÃÏÖÜ®-åV°¤ ·ï=géM?ÜhyV´¾g¬¦=Eó‡™Þ ÎþŸp7Úž¸.+n|Õx‰e±ɦ7ÜÁ°{{êî€ñˆ¬ÔY7­Y¿/ÐÖ£;6—ž%Þ£T›F1ËÈi٦ȩƒÆ1¶‹lœ¢:p¤ïEdb Œ%ÌgÄ@u2|åë¿IÃÞ‰ãw[Óï[ìöÏGƒù¬·,äò°1¥@ÍÕN9KÓTÖÏœzæÆ©3Åúf±5•Q¿OHuUolmôLß.fu(Äø>~*¿ñâébêó¼šÞÎfÞh-Âäú“©/‹ð±O¿ïoýãϽöêëO<ñÆsßyù쫯--¨¦=4à¡‘ÉßGè÷|³jpÚ€Æ pð\6žk!´XV“÷|ðîK§®^xõì=‡–ï¹ïW ÒXrÍõæÔ3çN¾òú±ý Ÿø³?zàðʦÅ€øÚöZ|äÞ…kç¯Þ¸¾ 6¸äœñGdB1¾ö JýŒ|Ðà%wàÇÔkMy®Nņ†³Á<‡:J AHX[#p’vèñ\5SBˆ·çè $¢è,´ñ²”ÓŒ,ìÅ4€UWg•=G\Û¸~Lü‚6/ÉAëf/ܨ/£a»ÍF‰­áua Ù©w7H‘F*Ü ŠqCRöÕ¶°³ÌuJ^’˜Dä£6)ÖÁØœÆR˜¢ÈÑ’É¢ÛHÜÄ:Ýþ­’ë×ÓëÚ²¾Œ2'ÇŸµÄÑ}™ÛtÌ;²2g+äl8ÛŠîY¶KÎLŽq”iî’™Ú )¶‚úÄÌ,«Ù¿%ÏÏ&¼VÓ[lßzeüÿk² Z7ïiE}Û&xö^Äoö[‹¶ýstúJ·bU m²3s]‹8‹Æ µ¤ª"˜çh(qƒ1.Žùh\4&#íà­ßEYqì<)F»Ä†4ŽEH¶öá«¿÷ÅÆL½¿`²ƒ>’ƒÞ°f,®`oÀÞ“s¡idçÒùWŸ{úü˯Ü<{öêÕ À‘ù•ÕÕ•O~âc=ôàÊÊÊSO?õÕ¯mRÃÃsÖ¸¦Ší“{ß'Þý¡?öÝß{þå—O9Éd¼‡ZØ“xüO?úWþÖO=õÔ·ÏŸ»±r`4\0ÓÉv9l¯¿ã®¿üs?ú¿üþìÙ‹×ßXxàýsìÅosNP—Sï«ÜIclD¤ª­x®7øÑÇúÊí§¾õ¢†pâÄJ¿ŸyõêÉo¼vùâ¦3øÀ;[¹xym¦½ÛØÞ MÀrj÷­ôGýåÉÚööú†ÍÜh”YKÍ´n‚·D懽±/J¼ôò~æ¬1„@Âj0蜓P)%‹˜®ëѤ˜&C@@C°!Ë’*<¦Æ ×ÂM1F#V d@Y…k—ÏGË÷(ÿñÉ)*º…¡‰™Iþ;{hvÇO¤˜ìÔmfÛ‰Û´0½íl¥f=“¢$rTV.ÒòRC²_JÕB;Ëób )iïUm\ÚÆ¶õ7þ¥ˆ‰úØþe†d‰\Sm¶Ñ¡Íá[6Ä=[Üg-âg?íèŸÑdzÅîU÷º²›Äš3$ÐVjÖŽùˆ™£è‰w ÿÍ¡wšcXüi¸þáKÏÛÕ¢o½{ý#èëÛuªn·óë-¢…ÙW¤” Áüœ(Ðqˆ°ÅRɪøÎÕ‘Á{ŽÁ®í&E‰(Ë£TfuÖÉ‚!ÍM)¥+úìEãQ‘†C¡ Ööãä%a2­‰4Ï¡E¤Æ‡?xêw·tóà]Ç·Lo8õlûvŽF£mGÐT\ÎPmlyæ©g¿þ»§žv{}maeñÄázüC?ñéO‚òêò 7`YþÈkÎ|ÿ~ð™ÿÌ¡£—_½ V8T…/î=zä¿ý«Ÿû{óŸ_yãÆá»Vv¶Ç‚Úë úý¬¬ÆUYýüßüðw¿÷»ç/žË{yÞì_]û‰Ñ\î«Ét{<7âGn0ï2:~ωçžyöôs§ßÿé÷î?rp²µ6új:ýÎ7ŸûägV.¬,Ͻ÷Cïºzæ²çpäøÒÜÒp2¾ú¥ßøÖ Ï¿~æÌUEÝ¿:Ÿ {uÙlìx ÅÁ•eŠçÏœþ3þѯéÌ©—N­ì=òž{šàCØTÎÄBÈ %‚ 2Ý(YzÇ;î~öÙSÏ;ôÆpàäB$„Ø®8¡«¼m`¬îÎjñ\ 9“Ê®QPDÊMíÖ)×7¯>óʨ­Û,ªq/ì”[ƒÅñA¦ã%ã–†s믜úƒ/~ñ¥§ž,67?òØ£?ñ©>püðèÈR=_ïì\ uÑïåÎi­Þ{Ý)ÂÊþƒŸþÙϾþêëOüÆ×ýèƒÇ»z.àݱÁÍ›7×®<ðè1ί{#Ë×­Ù¸çÞAõo§Ï}ÿÔÑ»…0°®Àô—\í§úcôÿñö¦A–d×yØ9çÞ›Ë{¯¶®ê}îÙ1 À` ARI\4I“´MR¤õÃáp8²8ì_ ;ì…WFHr0,ÑÚLË”LÒ ƒË`0kO÷ôLï[uumoͼyï=Ç?nfVVU÷Ì´wìüo¼{á•ñ#¦Á‚¨TØ2‚'ðÌH) N§¥”|öô¡õÉ·_¾ J?õì©“++q…ý¥K—¯Ü¿õÌsgífå'…IÄÎ)‚èi<±^}`Î }]•8&"@p&T ‘ú¹I59!@@“ÒmoÙ3§zÀV%‘„»¤ÓÞ3"Š­1ÞüEéç·4E‰QMxu?"l«`Ü Qq:H¡ˆÛUK j탘­N-îT *QI4Ö«µÅ¥Q‹­©;ÎïÐÝ}›DW[Û³¶-ˆjýx}Fi_´C !”ulF÷‰(Óê–.‘eH{³äH%qˤd_Š„è*W¢‘6ÉCûEèñI´¦Ê±øà»…‚#Ih÷÷À’J¸žÚ™ëQ"d‰ŠÛ˜] ÔXÄï¯ïßxÂC²•ö“ö?Xº¦ïDý+jbÝ=¯º’†Ú¨é{rC !(Uß Ü‚÷°˜Íƒ WUYU,iB]œ¼°³Ö’ZñIb*Ì^j5E”ˆÚÓÎø!£Éöko~Û)’Älg M’'žHA8°´<— ¶¯ßúÎWçüŸÿùtk+KõÓÏ?û#?ô¹';þÈÇ!÷ÖoÛbÓô}Þ猸d6FóÛ¯¿õê[—õ?úÛ¯žzãϾü¥ó_}ëè‰ù4×ó‹ Kål}s4F£É´ßcERZïƒ_>¼”æúòùõG;WYžÍ4&¨RØhò¿mTϘô½+wþúÏ=ñ¯\}ëͯ~ãöSÏÕ=È„ À£T •h<‡Õh} Ê¢ZX4=óĹ'Ž¢Àþ@ªV7×.¾s^»~øxŠÂÀ)ììÌHfLp•OØ $lg¶—¦I¼½‚g™ÒÄ0€sÁ³×©6s}ÊÓ~ži¯óT'µÆö–ÆR¶¾ñ4Å[½½ð|àDª4ï¥Êôj;»vÒ'Èqu Mêä8D€Æ-?Ƹí‘û"i±¼ÖQò*‰4RŒfp±¨q¨LlQã$ $£¥"qð‘4Â-% ÉÐ…¸—ØA½š…©NÑD”J€è«)’%*âÖwDšqjnS‰„Q“øÖRâK×Ò­.…БÕÙõÔ8‡ìF¨pW³‡zd<ó?dÚ-Ò­ïûkèÃrèö‚x‰;Àýÿµ>uQdiOQþÀªú>5pGÅ$"!ˆGiW*qý×1Ñâ]ÍÚK¶Î¸oת™  ÍŒk£‰jzGOÆ–øR«SvéXT™‚x_Åéžx2žlkðå?ýø}ßh{<0=†P$ô]½så׿råõ‹Û«ý<ÿâþø‹/½8¬wðÔÒ¶ ß(®9e³A9 «’@Ä ¢S0vZ½ýöÛï¿ÉÖ¼ø‰Ï?rìôŸ~é_¿÷ú ®2Ó;ë×îØ’zs‡i:) ÑÜ\ZU¥ø•AoéÚ{[w‘°Ÿr/3?óƒ^?ËËÊ­—SÊ·îo- ’ïÿ‘'ïÝ*ßøÎÍl^9;gäJO™@ÐL ï‡e1­n_½¿që©'ûÄ‹ÏTF~Rgýø¹$UÎßÝß8rh>]RI/ETU%s^iBìªT%!ðpÄé¼6Ú(!DT‚γ00CY:õL™‚¹•#ÁϲDiIBÚP-Œ]€Ö*®¹{™êKD¥S·UQ¤wÖ”H"¬H+™d3c¢ÏwcW¬£F³ b LÚeÝ×F ã;ªÝæÅõˆì×$¦Û•56ûíÀ—xöѹÎA²¡š*ƒÑ,•Tà"ÂH-Ó¾½þI'1ƒ‘"%€Ùy?kL›¼4«-­$®D»›Gi2Üwº~Ü©­„]¿%ˆ¤ÝˆìGåR·÷DÜwç6c(!hMa÷®³nÉÛÉvx,ÐU1|ïà{—ÌÔÒWÛ‰¾{ÙDí<<$×óatÑý”þ¿<ç)¢@;ÓAû*Ûþÿkˆ=/±±¸ï\À3HkQSß!5@T[š²&¦F®÷P²ãÇŒ( m H“š,1Í.x[¹*xñµ&¥l’äãét{ºù_ý7¿ywuÍÌ]žÍf…+UïÈro0xãÆ½ë—®ƒõÇÿÙçg?ö‰§8Ø[H·¦÷îL®•É4(ˉ‰/ª*è)Å윺yåÎ¥ o$ùÜ­»¯-.:xzðC?ýÒ¹'.¼qþÖêdbݵ+×Ë¡]˜øÊÚ‘VIêÇ.O²Ñ:O†¶· ÒA ! €J’TœëyG%•àÅKw>ýýÏn¯«þO¾tåü­¹ùGx˜”%IQ˜¤BœØaaÇvmmxåæ|¾wòɣܫÆãÑÌÏ\–bQ–§Ïæýþ¡w^¹¹zw«›¬¯Ì¥yb*¤àY€SDã_1x@fÜ,°"šŸlÏʲ H` ‹šó~Âè)­<š¾ÖDˆYBi¢h÷¼Xw ‡T\ð9Ï>HLìÉB„,Ÿ_.¢¡mb]9jG`“) MM)Á¡Ò)³ ×@ì*—j5jRIsÕÔúÔ6H®æC£† DZTÑ´c)Ý•âÿÖd~e„C­YñÕš‹T Žó‹Šx$âàH³#჊£7I%€ÑÁ8X[…ÀÒ€v]”¸üm0¢ý;K÷g:âÃÞQFÉï|j-Í!zî¶eÚ-‡Øò±?÷Y²ÞÙêî°¦ö!KËýÊ¥÷A=°ñ|ØFB#êT¼A`_ ÝcEUJ ñ kúÐvƒ‰µ Mê8¼ZB-à$ÓîPò>&ßÅ9Lb+ýë;ÁŠ;pi4L ¾t¾òŽkóT…J©ÑltåîÝ×Þº¸q?Œ¶Ô7÷»JëÉpÃ$ Œa„ñdôijO¿ô“Ÿÿä‹/{äÊÝýâ”ò"Ð  @°@ñÑ®ªÂÔ’Ôì•osõîµúé4½{Õí»8XJÏ|fñèsŸnç¹9ü•ÇŽýæßýG¯üÑ˧]9±p¦—ôî£òêÚêp£xégžš;†Û~êuÕc­A«ÊËD¥a‰½”Þ‘eÜÝ{ñ çß<~á­›7ßY?uæXžP.O9¡)3 gåжgwîÞÿî›7DÁŸ=AÔ:¯Îô+‹!TÞÙrª9×_H–oÝØ®ÁÖzYËù…,^ö¥bDN•¢åS×-@P E€”>(…̱å¬a DÈ Õú·rLŠ´J"lHu&(GO[Î!Ò4­¥°‡ˆÉÔˆSM}ÛiEo:A­Da҅£~)&nFê~«ÁôÌÈÙ„Ö·”ŒHhʃÌB ÌÍæIHĵ k¥Òz&eÒü›Ø8G…2b÷;º¬º•ƨÊ)&Uå B‡Å¹ŸÚJ9ƒìšÐcEÇ{yØÔX—?C±b²ìú7y7ìܪ÷”ãÜ—Âôþà{·E‹/›$ˆv3â»!òÝ_ùÊ¥þnêß÷º‘' %íé[Ì+¾giö)Hø/ C[EXÄ‹pMd@`ާQK×WmG@ Ò¡ 4I'¡²•Aj3ZœUöÂê[øÇo<þÄG~æ—åó—n¾÷n®_ ·˜ƒsÕd6áÇéoÿÚc/>­Œž†‘¯f8EÁ 3° !yñ!5ÀEYBpôÎ…kßúÆËóýüéçÏ„0™%Ø0© UÒ[ÌóÅÊí_û•_>ÿÕ ¯û›ÃíûëK65¹¨QY–£YyüÄÒG?}úÎmì)ÔdMÀU"™€E‰Q‚WÞ[;uäà§>uæ½ wo^ß<²rp¶]˜Llu]^w×ë\ëíý§\k§¶ìNHÞùº&Q½'©]6FSþüeœñþ¢¬ýßÑíòh¿½G¸Ê»iOM@H}HÆïúÐ&/Åˬ ì#-¾ö¼ñžãø·ˆ¹.Ô™ý™‘ sæo%òPK´ÀiZat:`ëüñ­¯}û;K§Nœ{þ) O¾ð{·¸´äÆ^6é¥Ë—þåïý™º €0¤Ñˆø2˜rÏ\Ð:hE€*`ߺùÞ¥ÛŸûkŸH5l¬®q®@p¾„ÒZ“’ÝÞ˜bæ,‰ÁÊU;oCPÄ(…eáÁÓê½Ññ³sÏE=¾íÆÌ©û6(¦ FÄ:Ð&®Ÿ°NË‘à}!JNY@+LÙÂQZo3æÈ† Ì샣ˆve õˆdj¾ !8Þ»åѵtyéð¹S÷ìPÕËçó¹,éÒP/í-›ÅþÆkׯ>²vó0€f gPZŽXˆ«X$€¯&,~<Év£ÉÍY6xî…3Û[ÃYUeÔ#¥ÃJ¡"6 æû[“Ûo|û­'|ä¹ÓGW¿{ã>öîLF³ÿåús(FöàÁ[8Ê•RàDÀ ¨:)]˜] ¢ˉ˜Þg_:»ugõÖõ»iO’¤7u+[[Ãõû«ÃíIááÌãnÝ.†“ÑÚÚ((`Á J¥#[¶Õö$oXQš'˜LØàÄy_:‚xd­(x¶–‰@ÌõŒWÎâhÆŠôÑÃG€+¥I+J éxv9†‘¥ÆA™"ÕYÛ]¶,«vîëåµd^™Ñè¤?bWl£ÒQÙ˜(  tÍe÷§ ½˜E$Öµ¶\*•4ÁÅ\{;ERÑ:$ íþ&6Âö[ÅÈmBRÑ»š£I+“‡j†È"Ld”ÉcÚnóë6:í6õBµøL»6õ¡ÖÅ¿uôìÝf°ÛKîró”hµ÷ìòDZõCw”ñW"?4tTßá-µÍS,7";KƒnƒÙ­G´*ÿ@t2Ž"B t[¦÷·¦oû Ãàßs Ý#Çj…a‰!-ì 6©èw·ÿeÅÛ•J›ôò@9Ai°ŬNPÄJQUymtšjšŽÂ"À;×ÍtHHD$ZÕèç*c-5‘\Œ§‘Ëw¯]Ü.0?rîñ*W C€±žOôâbZ oÙog̰„‚”™p™xPP‰­ t¼â Bp^¼…l¥ë/õ¿ñ'ο~áì£OŸ=ôî{ë˜`𠌞0+ KKƒ¥ñÆúÆÚ݃GŽV†à|ð• €¸5ݼ:¼¹U…aðGIçÈXUæIÖS¤€ {v£ÙpXŽ€ÁBå”x(+(-Ø}D*Ï%’ë;WÈÅ7îmlŒŸyþôÝ뛊0ÏR$cHØVÖ:WT4VùüÒ0ÜRÚe½"íÏfvÍ9ºrÃ~âÅgŽ?øî;÷öÀ ë÷¶5X“$•UÁÒ"Ä‹w5«eHW–×ïmŸ{dyóÙs.\º}m£×ƒàÇ£Éj@; _XÖ.,ʽӿqùþêÉâÒ\QÌœ Ž­'‘$Sa4 Âb4¸’5"ðÑñD|àÀLŒš”ç ¨¼÷l´V𕆢pD`+Øžø³§ŽÍ/,:;Õ3ѤÅêÐÂA3øD("¬S²Y¢×bb(K(Muî¥÷#»àfH&Ú}Eit䌄¶fÉJ§ ëµ{`Wét®6²SI¤²Sƒ>Å`w$¥tJ%Í.²U± .3xË¡ ¾é"‰â´¦sÚ1 Æd\öekã[]f-ß[a¼ógeHLÙ¢-,BÑQÚ¥5ª—¡²—q¹?:x ³Ûåí YGî`;Fho‡Øxðµ´}þ¸ˆ‹t÷˜uªÇÃíø3m‰óøþ*Ù­­;ä§Ýµ²ûš¦¿¨Äó¯°»qîJ¿ö?BÍkvžÑVZ¢t·ùTˆ/½ÿ–z¾U’¦ÐfÓ+$aƨ> q#QôÒâû‰iç!Z:·,B޹¡PSðZé}!&©)«êëßýú•éðЉǒ¹ Ò¾šcU?7¾r:8ÓO ‚0•+ƒ8 fcg…uä€RÅ ÁQØ(*ÁJ¬5÷Ë­áp4èõŽ_ÙXÝ^>¾¢HS øÊ*åÁåÌW^{íÕÌøÞbP½I¶P§n¦‡#ûùþáÿíïÿÓk×ú*‹5£–<¤"ŒHâ-ǘ‰‚€–4!_TëÅæòJÿäñ×/ß½yíŽJÔâsüìáå”8ë›tÞ>ùüÑ‹o¯]yw}q1Kz¥Vˆ)00C…X1H`Ï ¥ 01ë„z·'nZ„,“@å|ðdEŠPï‘ÀûPy<~xyåà²÷e¬¡ZQ½Ú¦öƃècŒÝ ³ã™¢yf¾ÓÅÄ*Vsì:NãÆ °®#FüL8&n2“k§if§ ¶¤„$ˆ ™dÀì£x”Ù'ù|[X‘LÝÏ6ëNáP»)×2PßXÛÔdGæ_[ì€HTÖ‡¦ŒÖ?Fº *çàAIy–h«ÜªÝ}„€pǦ~ÿôÚjPïüÀt—˜'hæ]-gÛ™vÅòwy¿ÅV”¨uÝåW¯ºee×ò¡- {üîBx@ª!F7÷.@¿çgö?þ½õ§íƹÅôv9cuUAÑNÀÄN÷0¼$ñ”vgÑö¡ïóI#FGHiØÔÛO¥aïØœ®Ü ïu¾nmå;)ä×â ™¥ÍÏ©ñ…·®^ø½?þÃS}>ŸŸWËs@dIRA1Èz}ì[¨ 0°sJO]Âý¹Ü•ÖÙ²â \•+R‚«‚uàráÀÀÕÔgƒdcmhg³A/ËÓÌTÄ•3kCÎU© P—Õâ¼¹|ñŽ&m özz:’ù¥Ì—xçÆÚ‹/}ò·ëõ›^úÂG4(ï‚°€ª]0â+z¸*2N&Ó*Ër[êápvê‘ùG=~ú‰ƒ˜”Z“€@qòÑC‡ŽÌ_y{õîÍí£§çU@"ñ¡˜8ò>pà”{®\Hf¶§®´¼0 cpj„˜”ïÙ6†ª ’4;zìh]C5MIBF“RˆûlÕ›‹J!^Rí%XVG!˜ŽYGÞ…ä™j#Eµ¢87tK-ì•ï5¡íòVO¨fvJ§ÂŒ¤8¸Pç>ö³qrW¦ß¤+¶Ü£ÊÛ¡GÙ%4©œ17úœ »‚Ù3»h1åí+;DTÑ ŠècÎRtÂ÷e¼If¥õ§½7s¸¥ÊGâg»Žìކ ·èô›ÝúØ-F{~µýnË´ÙÓl¶i‹y/¡‘5² °DZ¬ž!£D„£¾s ˜%àƒããw­VÓéÖã¸ûKqÀW wÞȦg[‹÷¯\Hoÿp]êƒ[Clt%±úå™­UüÃé®Ìc??§Îk­Uv{lº[ðUŒG®¹ ŠHkC£iHS Q)€!¬(q•wHÑÙ>:î@›"q7Ê >øëk×/L.<ùÂÇôü²^Ì\ÈsÌReŒ6àYfh^e*vPPÂ"2of[•(·‡¤)AÅÃ|k!'šg(‰¹smK+ Wtÿwº±u3šXDëZi#oëäaÌÕ6šªó"v½ù°Ûó‰D˜(¦, ’!ï#¡£í(%Öñ¸´ªMÌj2“jr¾ÂÎ×µº.:EKak<ùꥯ<ñ‰LÊ›·×§e1é-/&™! Œ jC$âÀ[%hH“&œnŽìh~<ç‹ÙÒÂ@ÊÒ9ï ³ Þ•^) •›N ±eJ¸¶ºÕŸëŸ;w €Ø´P€Àñ œ^»ua2:Ôר+Ƥ!¯¦2m÷çÒµµË?ÿ+?ðo|ëÛ_¿üÙOަV;Ë•$‰ñâ™zyB60B(g~:™ ·†ë³ÍÍɽ5G¤Žž\8rvàl¡Yã•>¹éöÖ¹ss¯/¥ë÷F[‡ÕƒšˆC$øà@'õ=XXÈlM½!Mk#·µÅ K´r@ÉÔ230VàE s`(+Y˜ï?rútE–ªØ„f©J4&†h·¦s7ýSºm{LÛ¼çÀuea„Pê.ÜE ª¼ˆïë šØŒ6œšÁ<^91°¾IjB"•ÄJ:È]VSUlˆ·£šæÑ$…Dm_ÄB|ùðQÐY‡…´—% Å„çz,uEtž„ŽéQ¤‚vËeh”EmHÏ~VüÃzÒýõ´-=mõiËeÛf6I¬;ÝOwƒ«3„ÀJ‘÷u¨Z”xÆæ4ÖJEÈ YX)”†·¥º{X©Õ fµnêTæ,¾¶_ÜX‘½Ä&†š>KP×Å*v¦{ò–[RêžbM߇ Ú5º¨¿Ž®ÕÝB·‘´ŽABø@ñ4^Î{È]T.Þ«Ï%ª؈DŸŒcøYm\ÖaMC£S’Vé‰õfµ æq^$„œsßxû[ƒ‡`~îîæÖ£ÇzKf2Û`UÍÁ<(Ö™JSPΕ₦Ô¥FÑxsk²še©Òãb¼=é)4\ùeQU.ˆ“ù¹ù­õÍ{7×W–“$)gNQœABÏ …òñõ;å¬è÷B5˜ÜÓËGÛ’.Lm1.gÓ…áæÏÿâGþáÿü]ãÍâÁþá“Ú0„Yš(2 öCÞ•Å´ØÚÞ½µµ¹m,¥<º|õ=/è‚ÞLô¼A%U"IUU9á°qìÈ‘Ã+½;[«·ü\tB¨8Ñ lYS—|똈<Ãx伇ã'ôÒ¼!CB\ÎüÔJ?¡,3eé†3 L+K ÇŽ%¥8¦†C©!­k·îœä­+{ü:€ž%ÚÅŽ¦ÍøÍR€-™éf¡Ýœê¸Š•Þ¤óˆÊd ©©¡„Hª±dò@Cû­zUÅŒåh*‹(u/Qö:î¸Ùxv,$H“W»óÂqaÃb+rln¬^ûúk/=óã÷¯o±ÓK”f•@¾€RÎC*@PlC€‚ÑâÖúÖ­‹7Vúú@ßï€c1  0—Î`ð4ȳc'–o¾wMÕp<"¡Š›)ìwŒJ‘ê H=\01¤уVÔnù˜Es|5u4š*f¢º˜61;Ä€=K‰¶§n÷ªû›Çnê’¢æ´òþMè~¿®H©µ¥w„0-|ç‚"âv×}š=u·µî—t«;âÓ­Z²Ùj<›'ÖÅÛf¢ŽlW¢Ø¥GÏ´Z·m%EA‘¹rë»7Vßzúù[ê ÇÅìd¬ç3`[”xV>¨ -+qeåm±dáâÅ‹>úÈÉC'ß»réÛòÖ틎í=¼pøÐbš«­éD ö˜¢¥uxëõ+ëwï8uÔ{ï]åY´AáàH`¯Àéà$_:ØÜŽ·§“áâÒÜt6&·eMª§#I´±ÁæÔÏý»ŸùÖ7Îo¬ßÓj P(IÌØUÎûûë“Û«k¤øäéù§Ÿ=|øÔˆ—ö´JUéÃdjS€„”T:ØBÕ¦[@Èiòøãƒûë³[wm>§²,©‚çÀ©!¥°ªÄ3ôrU¸0+‚187—úÓÂz†^?Ë23ž“Â/Í%G/ôò¥àfyJ‰¦$¡…¹Ì(i=/¢v¥—«X7c›Y“š£ŠWicLJJ·¤wi¬žÚô‰4?î6­3&,QL‹!•΢Ýrd˜Æž4îÐI¥¨¢·ŽFÒ¨ŒÑ¶iPQ˜I«^lÐVÀUžÞŽ¢ý]h0÷V,óÄZÎS|”áàÄÙ!F“‘è Ú2+£ÚYt\İ»zJ'a·]/¶Ä[Úm[׺‹ò÷à$ߘæuëT ‹@üìÚMhlÚ&4îIãæ”HXP X¤Èhä¦ëŒÃK$u5M˜g¥}c­ÅÞ« ® >@ƒßÒ¡¶èÜ3ï﯒m}Jä}8¤1P`]´‹Ý·Ž®EÞs`л”,{ºî.¾´ïydf}€ S=õaÓl ÷®ÑUÇT/&$ÜaGc¼Ô:ôÔqcJËRA@Ô6ðëþäÀË  ùâõwßûä>;<Ëú©—ÊÚHA¥fUð¹W„…+ØÍú!ù³/}ãø©ƒ¿ðÿäù×ÞúÊÿõò•K.mܹ}©×ë÷–VÒù¥,[îÍœ• çòþötëÆ»·Œ¡C‡ç³žÊÊÖòÕ$T!HY¤é`¦j<š•³1HÊj¥ÄW!OæËY僛$å©s+ó‹O¿ò5·~oóöÍ­~vøðñ´\½?ÏìÜœ~ö“‡{òð`A®|½éë$K|˜Ú<[¬K_±w¡4›Z†ÍsgŽl¯‡7/Þ_»²žï§À$E IB™I¬g¬¼ÖÚ˜tVØÀ0?ÈóÞÂh6áðr~úØÊ _â࣌B"L ¥uø hM,ÐË5dYKU妨 Š•NéœÈ 2Ò&°C놤k> €JúMŽk_ú:CcÀAÍÙ¨Ml…tZó;Ûžšò©È"{«tw©ÑOس¯£>êÌD$fÙ£m*gV$°·ñerR£WÙ!x®@ªãLb/Q RD*M4¨:ë[ÂdÂ,qÚ¿uÝí`91†vì 8ÚSIˆ>u·Ì»œ–Õ¥SÑT¿D}ïÅvŽ] §;´$£‰Iˆ˜½‡hKªÖ¤!¢Z§„µ+Rfwè¥Ýò»3ë÷ëëC÷/1öƒKñ]?Øÿ>4²èkû²©ëóL$ ¢ÄO3Ôë­AïïÛÒ¾ç¸ØoUK»xÿ:¼1 EЇ¤‘ÚŠãLßx†‚RdLF*ERPÓšY@@ˆT¤µJã‘#ÌôíÕ—ïóH-?·Ñ[|ÛÝ_zìøínÿÛÿÖßüâJ:¿±5ÒƒJ%II× ÐŸÛÞ¹¡&0¯¿õÊx²vò©Ç_û;ÇÏ.þ­ÿìo^:óÎ[·ß{ëîêÝ{·o­­mèäzO%8·”ºÒÏrç¼÷ ♌ö ÑÍ7°Â TQ9z~É”ÞZ;›L²^ƪ—¦£át©'N*$ÐÞ]½ôî\/ýØS'ßMðîÚðÖÝñõ;~6øè Ÿ<»”÷Ñó•#¥æ4ƒÄàè>l]É–ôl˜1¸àËb:UÒD%ªiI³µ³gR„Þí;3»åú!SDI‹1è¼X†Å…’0- ÖÄ ®ŸçÁ͆[“ù^rîÔéÅ……ª“ÆÔPšÐ g²„òÞœ&§T=RDc·èË?ó$«OÄhö‹i›%C&­\»£DRÁ³¯f’At!‰ègí<²ûßéÚG6JsÛÔXé,ºÐGÍ%6† ‘̛ͽ©0’Fö,!ý®š¢°Õ,† ©Ú7TÑ‚ÄÙÄê±– µ"•Vvæ¬/¬íâ×ݪá;´›É±KG‹©¥Ë3íúÝá÷õ´+sbØ¥°l‡tê)>®Aã,—×Î1K]^gEØ_Õ!΢òQ"XÏŽÉCh‹i€ˆDÅï‚g­ ‚€…Øš%îù³´¥ð{³¶ûð~{ª¸Ti5KÝ=iL Ñð q¨ Oí"6„½ï¤ÝSì¡âï,Cºùh<Û‡h´#LRýt;VD ên‚ƒw68Š´JD¦¶ Ò•7Ö¿*s+áÈ'7{ƒÛûÂ󿼈¿ñŸÿwÿà¿ø_à‹_üØs7G}>§Ç²ÀŽ·ç‡›#Ø:tpåøŸ¿úv%››WÛ›÷×ïÞXXHYxáûÏ|ôcK›'G[Ó­ÕéÝ[íõÍ»†7ÞÏfUo`úIo¸UPlrQ Ž{ie¯Ÿ<³´5yvEQ.ôõt24:é鼚Nû3©fež„ÍûÛ=œ²ríÛ`”¥T}ªšVy–°÷EåÙËh8F­ÕæöÆÚú¤pœ (Íä©fÏÿ•Å¥sbÁ1bˆSž?…ÍqÕÏqn!+-ß_ßš›wýœ”˜Â{vŒì Càà‚%t§çΦUZã¤÷WýÒ2=¹X”UU…¬g¶G–-<óè²1ðÎå!°<÷‘§ççœdY/Ñ”&”¥:KU–&J ‚ARIÕ»Çw´ïDe"‰Z„&‰«. D†›ÔX¦N¬QmÇY‡Ç4«Òfõ{Rˆ‰óÁ]í‚5…®v&m¸PÐz‰ s¨B¨ê*ÙxR»Ð%5?µ¤q…Úf#c³ªÞƒ˾tøv–54Âô±€F};ÈWŽKË›`ËùßþF÷<ûŸøü/ýÐKÅïÿñ¿¸pa‡tùOˆÂ ‰AHˆQ4Pm¢Ð(¼C,Òb|`™‹´Öï- î{SÓ·‹ÑPóƒvIÚµu\¹ î‡1\ vxÚ¿}ŸC û2xD„PF`IÈÔŽdµ9“°pHÊC@Òe$"BD­Î¯ÙP$ EhËjzíö ,:xbùÈñ;¯^ž«üðÒ­û·>þÜÿí?ø¯ÿàwþèŸÿãöÊ7_]ùí?{ò³‡ì—>³¼´¼vkýÐÉcü»_LƇ¯TEÉÄ9¯4‰‡íÍÙd8›-äYªÅ³2ø_8sö±•[·×¼° >€6Êp%Žkbi„$•Fÿ¿ Rð00ÉÊ|ãþ çiÒKÓéÔÏÚ°wH zÙlb76†·®o;'O=wR§ÅÆúðÈñƒ½9]< ³"^BvVeó.Ï€ËYUpDÁ2{@!­@B`ÏQá+œ œmô Ÿ^½½}ç¶?q"?s"W ïoÍV¤ÎÛÀî ß÷¤·îwÿŸ+ƒ¾~á“Ïçy?¸Qš˜<ï§ e fY’&Jk¥µfÉÊäØ(Çu2Ã6ÚrÖ†F“¤,‘‰Yžë`¬Â109ækFˆÈ "©´5!€"5¦ŸÔ.Ck)éè€INm}DÄN x;Ú€ú2FÔu6Šˆ›5Þ m‹à˜³Ã¬04éLR—cëÝ4Z@ùše)!H4j™ëEýUkÀ{V{ÎKôè® QaÍ— šÀ¥ý#k3Xßkñ–ÚGÔßã'ÒšÝyÏ.Èþ,ãó:Ïw«RüÉ=þ̹ŸðÞW N’ü§þÚ¯þÄfÿçü“wß@ó¥)¦,܆ÇDò“ÖŠö×Éî×qýÿö_ä¡Ãµj{Êól¨Iø… ­Ï!èý•qO°ÒþÚú!N¬%Ï*EÒµIBí3†éM"1bA£(WïÂÐD~(‚ &ñ†ˆ"ÂÃÙ­‹wÂÖìØíó·V쟪ž ™z ß}åõ“KG~ü_:õôàå?üÎù7/¼ü¥×Îõú§?õÄ_ýÑç•Ýüî—_Q)׆ !Í8€0(ÈúÙÜRÌ ÀIľ o]^MÓ¼¿0·=ç#àCU™Ô¤ U¡BÐ ¼B2¤4`ñàÁWI€詳G¾uÿºÈt²µ9î ’~ž¦CXœOîÜÚ¼ti«¬ÜÊAõùÏ=}ìôÑÿñï}SuøØ¢ÒÖ[àÅz €Á¶ Ktä—–9Ëi2t³I´âDM„Á‡ 8€h@£(Ï5Ì {íšÝÚö'Ž^xö”èòõó7s´5²i Ï~dñÎêæëoo,/ÏúSŸDŸæ}c(Ͳ<Õ½5ñ’›x‡=4ʈDx6ªcƒ«¡—Æ‚r<|8Ë’ý Q–ZâYoB½tkh\ Ä5hb+^uűcù¯ÿò¯sP¥-AD)"¤ØïXk³,ýÅŸþµÊÍþñoÿ£7f ð ¤`„ŠÑ>"øÔŠ…B`ErÙú’ÂÙEþå›Ó‡UçØ{vë^<ÆZˆI2î[jKí­ßÇeo¿àìÃüd³%Œ>7Ed?)D [¦j”›_Ûè6çsö6`ÍèwÖ‡W¯¼œ N{ôs_ýò¿|û_ýÞÑOY|v\§ÙÌ]ŸÞ¹ðæ•cG~ê×>ù‘óK³5ùöŸ\ýú—¾ùõß{£ŸêÑpúÜ=5ŽzƒLc’Í'¾’àµÑ\NJ0?È“E5Üœ<’=½´ñÆýI9ÌõˆAš•wÕü E$¥€ ˆ+âÝdè‚÷'Í_šËÖÖ'‹s“à|°8ž”if†Ãé×þôîpÛž=·ôÑçN}¦ÿÙïüKÿ÷æå«Å`Ð+l9ÜšåiƒxàY¼¯Š¡JÆv²²’..šû÷ìhCÒƒh' Šô gÄ– ôzxË޻㴢>}xeqñþF9œ¬k¥&¡³gÒiY¼üòú£çŽ=ÿ±O1 e’ &Hêçy–R–&F©º€’ÎÚd0é|wl¯F%µ‰*ªæ„n~&ÎàP©võÙÎïuhûö\í š’ÒˆIÕhã}Ñ$ƒ»Û¸Jª!x Á"\³DÙGYOmqyNqq_/ëÝ.ûÆ\9ÚåÅçöñÙE‚°FR1BJ$X;­i1ûÄ)ÄÀ²s¶}«EÄ3{c’#@— õþt-å¾kDßZÄZ9ÞÓ‡ºÎ€?™ù ±/¾¸üùÏþ{³™/‹©sžÓ,ÑŠœ•uˆˆ™øàE’_úÙ_·vô[ÿÇoݹS$HËÆO‘±(Œã|—¹ßÊóuæßhOºkªÆ]öNûåL;î¹ÁаÖëí&<½ÿkna¨Vñ0ˆÉV¡a<Ô$ ¥ÑeiBJ5ìA@@E¤CpιVîŠJÕ‡5 ŒV¤tõÞ¥—¯m<öÉÓ••/üä¸Ùí«öêÆÆõ‰]î«CHf2.Uâ¯ßº|ëÖh6=zîçÿæÇ¿ï…'ß~óλ/&S_Î ,)W”i’¦¹¤+ë‹¢ .q9ÓaYZ×/g'N§Wßõ£Í¹^bKÖÍÏ ô ¥5† 1V^À%!QýbZ”6¤ :rxm£¼µºqä芤´5ß¾¼qÍ­Âþ«O|úûN.ÌçÁðÚ¨zëÍ!{X:J +('.UÁϬŸdë Çη›(—Íçù}o½eÌÖY®§É(²…Ëslåàp«<~ÛV|èpzìàâ\?ÛšmN&•äù¹|~ Æ9aò©?vöÜ3ål+K{&OµÂ4¡4QynR£Ò4Õ&V¨$®#›8:!A+(Šåµ®’¤YíŒÌ5ÿI«^lú]ÕÀQW¿ÑAdºR%$m’A»Ï‚d”É#”YP-  ¦ˆú’CÃâ]5öÑM™ƒ¬¦¸s54Wöíö íõ¡Þ8yÔ½m«Eb_[â×ÔÜÎÑVÁÄ|°k -§iÈ"u:©Åˆ×&Sñ+ͤã÷€ŠÓíѺF$]…Rôö‰lÐnêsƒ,Ýó%hø…Ÿ9}úÐÇ3ï|MN$âÀŽ%ñµQ,RÍl`é÷Ò<ŸûÕ_øµíâ»ÿì_|ûîz±( QÍ"$±î×Y°ñOÑ*ƒÞ/Üiz¶Ÿìùà æŽEÖ‡Ö=E¹voA`¶2v¹hm%ED£kI)B½;F¬vxÚCý06£ïWæãÒ]!uì£"v¯TÖÑ&Õw’IRNMš˜4ÐÇŽ  øÝ«_îT¤ ( Y¢™«²‚ƒ }öôÚ›÷‡áÀ’9~Ü,Î¥Yf†ãÉæx–Õ﫲ïü»W‹ÑˆþʧŸ;~ô_y>ȲT+0û½4It–åFSšG¥f …ØQïÆÊ…­]];{›¦ÙŽêumúºqŸ¡h„¬’^=¦ 3»šÒ„´Ã ª#é•®Q#¤º5nâæ[ߦȷ Á {_ƒ›Eë娇Bœë]Áq©,BÕ€]!ªB1Âñ;Æ­V¯fMƒp\bú›d'ODS£K‘%ÞݲÕ@yÍH’¸?UåKÄ{+Ç•‹nèµÃÞŽ®¦I[zؽ¹gÚ*廳<3DfhìC+ÇkÁÀø·þFbJÁü\æ=›Dk­„ÅùkQ)!5²oaá…üùÿàßáÎÖïþëß¼Q9V¤‹÷ŒZãžØzêÐþ¢cú‡ìO÷ÿØNVîRˆ±ìUlªÝûè8:„PŸ…1™1K³$‰¶Ö;Ïúÿ®»_—׺©ïõòx¶Þ·ˆÿ/koþ%Yvœ‡EÄ]Þ{™Y™U]ÕÕËtOÏ`öìpA"‚ H˜´˦e‰Ò‘múGÿ²-Y-š"-R‚E“)Q>¦¹ˆ2)‚€I„°‚³ôÌôôR{Væ[î½áîËWÙ5ƒe»Îœ>5UÝ•Y/óÅøâ[9©vÆZ5/k˜}7 þˆ¤ "1;ne5 ¨Þ<|vöèã/<°8`¼}ý굨qsÒ]tÆÂüøÞ¡³Ó“eÝF®*#cznïùI[]+·?öŸ}çOÿƒó…÷Gïxïã¾ðÕ¤@eXV@\‰A æÔÔ¢]Ayýòø…¯†0ï®<8[žvÎQvb°@Hê¼ePh>9Ʋ(êŽ[Úxåæ_ûôŸ>ÿB(O¾½zü;ó;;»£$õ½î(q<Ḡ;M3>™s·à½½ãK'ž¬ãEŒvN 0Åötɱ…)ˆ‘ÔÆ¸5M³ …:Æ–J묊VÆGf~Ò}õOº¶“·¾yzå´ ¨Ö휷¶d¹ŒwÓ¤r)W/î|÷ßoP”›²°Öf’•Î;ã½ñÎ HÎÏ5teždVHÙ0¶_‹¯Š©QI+—™LÓlÑkÝ8ÇpbNÄ\1êW+‘ëå¡}Û—òæÝØ ÉZWåê ¬ì{ßaæRXdk;5s› h–*åšuñYÐ#Ê"1¯¡86™rh\¹™ýîTYAR»èËbjG42tá©ñ>@ÍPöT2â3?&Ä3S¾-`¿Ö?×QŠ‚³hˆê&½FEóM:¸a¨’)˜3Á¾§ˆfåR®¡‰õwÆàÿØ_'ô"†È{·ªÝÙÚôH‰*CÌœ‹ˆµÆy‡HŸùÌÝ“EœŽ]ok)Ë@­9[E¯›x½öÉŸ/pC²Æë¦’¼¾óu­ Öí Ï™ã _LI‡g’O;$R^¼ÃÞiÑ^í9’ÓŸ³}c×bÑäKEaŒ±ˆD%Ià Ñ"‚®\ÊqEpQaDBã•C´w°ßÜK£ #r|º<Ü™ÒPhºzÿ`c²±±5«Ó½[ûÆAÓiâªrìL²bô`~òØ›/ÿ'Þû+?ÿ™È_yç·<)ÊÓYåªÂ:dê’ÔM d° \öô¸¾öÀÖc^~éù;Fy2T;Û(8…()&é8µË¦›/ì{ËgŸ=ìs/†ù\Ÿ~÷ôïyüê£ö›—eqÚµmkœ1#HˆZŸ.–y‘X»:&ÂV:iX£€FoXbà˜ˆ„¦“êòn#ϦhŠI·7 gàÙg篼šžxdüÄÙé¢kC*¼/—Š‘…÷ï¤mzÛSÛ¡ç.]¿ñæ”"@ðÞ´¥••¯ cå>Ôú‰JžTdNRŽßÈ%µ¥!' +×®³(CIm6É‚÷a›Ô/7É!ÙkDÔœ“h|>Ys«›mFs °‚ÉÛd\Þ˯ð*1ÔûÖ™Â"‹âóTž™ö),³ÃÓ ÞWeŽœ5 yïêýþD—Ä©EÄL&iÛ.Ã!ÊÎ…‘(ÚÇÞ˜yÕ×$ÖS>/[¼Þ¡ÙÐëì0ø*',‰Å;•´¨#³Þ°ü ¶LgÄ{СÍ54«3—~¨¡ù‹ù Ø“Î{úñ¿ñ·ˆl­1}.@H)/5‹¡¬'NY¡¤ªÖ"lšBœjø»ÿè'»+“ªð”•o9Áö6ÌxàêÂ×RŽDïKÜìík_¯4ýùC:ò,kµRô Fï{èû}ó ƒeÑ[W¹b*²"Úu‹”sõô\_<Ä‚~Óñ¸,!V.æCc’Ă֠µ.Sµ‡=©`wö’É(ê­åÁèÆû¯V{/µ_8>|yº[£½úòËËîèÖ›ŽŠÐžÞ¶å–3®K.v‚bÔÓ4` EkN?úýŽMø×¿úYî¾ðþ¾M ©Õå²ÐjâfU±¬›ÅAC†Œ·§Gµ%ó胗‹ãÃ#«2º`Û¦«Û9 ( ’.êúààdï œž€óþÚ#×/^Úúê­/¢‹O¼÷ƃoÝ^Móæ{ ã@NÚ® ýÈÒþ­x|·±H[DŒs&‚†Ô&JØ ŠJ—êEgà´,ü•]"(&n£²lëú _¹Ç"ï{×xsÃÔá`4±Ævó¹vIîíwÆÀ¾}»éº?þâñÝØmÖ'¯Vã™3jP $gBUN,IaÁÄ1f(†ŒS ¡íIçnãÁ¼£Ça$„ñ“,FêýdÉåŠ6t‘C$Ã]ïO¬bÊåRUrêgÎPÊÿ6û³²(7‰ÂºúÉplòV=Å¥J䨿­—R¬† ˜ÕJÙÞ‰¹C ² )ÙB8 RŠ U¶@Þ‘w„䬕ª\M‚„™TŸ/„!ô… ±—«ßwOê}9—¹òÞ¬cMË)Ŭ»}Ý€åuÛÐsórVЬ08ö¹¶&–ÜXåÿÝ“Žÿ›¿ù7‰§ˆ}¿ jú:k2S*?ñœw "ªà W–ÅaýG?ñ?üž1xµ¨¼£lÍ•íKú¨.„s|õ×®z䌥VL×ù°Üy.©ô\nè}p*êp´ô£ó ‘E\!Ô Iש£™4jqèš• Ñ*µTP‰0vóÁ¦.ûž'9½ÖtúµŒ¨oö‘TViK=üj3O‰Èˆï}iû¶Q "Ås /•H§þÞÑ|ö…?úÂK/=¿sÕ•#Û6]Ø;5)lmV¡ñûwæäÝŒ™q<®ŒI¥¾pÂ6´)$>Ü?ýÊúÃ}êúCÓŸýéßþå_øƒ÷¼ï¡k×w¼3ãiá *ËEºH!$^vc,Œ¹réÂóÏŸÞ|þÞÓO‡íMWú.4wïî,5O6ðÒ•êé7?T–[ùoýÿÝ?k÷ø¡·Oyê²ÌOZBmbQš6² Ø"Ä w^=Y.[àx\¦½ ˆR޲h"$ÕéÔq®M£ÂŨP•£^¼÷õç=P¼åéͦ]Í›7]ß8:YþÙ t°µ]¼÷vwG_ùÓ;‡Çæo» í|2‘.-yg¨,|YGÑûÂ9—eãÆUªÚ›t¬"ÚÉ q°àªpXféOf}ž™!X'ûVNÒ™ü €²Âͽ3‡uð5qȱò«Õ–pj ‚Ë??…EoP/D˜LÆß €"]¶3~” p!?€ð²çc‡@¹…·±AU95œÚ”xÿ¨+ 3l2S›¥*œ.ÓkïaCÀu“^ëç4(ë³P}<…Èί[Æio Çr¶'Îvs™†ùÚ-ÊÃi%‰éLÓ¹r_>›å›–èûãË»QŒ-"‘µ&×è$«#ÁP.Éyi–±Â“±ÖZóûô¿þúoÜÝônê\ŸÐE½aÈé¨ìƒÏ÷°ðRäèþ•µ¬™ÜÇC‚ûbÖ21Μ‡’•øŒÃOˆÀ ™AÁ ëúÌ›ºþdt¥[•µ÷ål¦Ä„²*îÁ¾–oÿÿýcYGg1}ˆÉ¬¶±Öb¢ÞåWË’p` hÈ ^ =*ª*·æÇzùÝ/Þ>Ü_´>MÒÝtRIe¡¥ãe³jE –MKšp²uµJ/Iê*;ŸVÉ{»X¦ù±]Ö ’ýãÏ~i÷âì¯ÿè·ýʯ|þ?ýüé“GO=ù Ôát¾LÂUULÆEi 9Û=:lºv%ŒÊâ]ï¹öÒKw_º{xëè¸ RwNw/•O¼íúöÕͲ*7ËKW/?0¹6ýú×;ËÛ¿ãñFBw|z¡€¢4ÝRæû‹î0„h ¨Ìárqûæ]I0š9,"jAˆ‘#¥@¨`À€U@Cu•éàôäùçïˆÊÛß\mÏÜýƒÉ¯_.Xº½£8Û€'Þ|ñÚµ‹‡‡Ë›¯ŽëEýÔOíݽµ³é7f…wê­xeaªª*‹¢(+kúJÆ.GùÏ\U‡Xã¾—M¹à g2U–Ï#¢uc‘¸jÅúñú4-ˆŒ=ð½‚S‘†x;ÖTY9gͧ°@@4T!öwI¯5’”O‘È„»ì`/W Lñ8¡ªÂ±Î‚ö_d|ìæ Û$ÓµËÜõtADÁYâ•ü<'dÀ*a­Ô½_ØÎ’³Î,ïZâPêĉe\Ù¡ª†˜óæü@mÕ074›g"%¢³ù!«cðmBB΢)^·‘$eÖ=î~äG®;[©$B’>¢g €±=*"Hèœéº$ýyiuÿøS?ñÒKõ®-FÞfC¼\C%D Ä!2öÜ–%ÚÞQJržó”t0½ÖZô¾øhÑ×6v|¿nnH‡žt8f†Ô“û\¢¥ÇgóêEJS~¸ìVfWÖZ³îðø:&}çtŸ÷uà«_ïuëoYºœjë5kQdÅb±ÆåÙ¿VÙ´Ì&Ÿ&§0eSŸ—1-÷OîÝ{ïG¾ëÞ+[/}é '{sÍ-NšÅÁñL–“É•æÖí‹r¶5%¤ÍíIlIEšE¼WVã­Áea_xáÞ…­O~ò[ÿàžûÒ—^l—í‡.FŨ(ôd¾Œ1‰ 28Ch 4ñöî‹]J4¸íiµ{yçÒÍË¡îAíƒ]þ¥ŸýíƒÃ£Ÿœì\™Þ=ܹ:k›E×AlÝiÀHX/£D%\ÜyuÏZ;Ûœ0GHjP¢‰ƒvŠŒÎ€÷d€P¡i‚"€söÞa÷ÂÍtm·xôMïÈòÈ+Šá•»‡{Ñ:xâ¡ÉÉióùßüÚî•§¾ó»>òÛ¿ùk˓ۓ‘ñŽœÃÂÓ¨*«ªp–Fã©3@¨¹Z© Çf)­ˆ¢Dfe;²¶ïWê«òjÈQïòi‘ g2¢jl†“Y³zFU†¿¾4ÎãöÐó"`¬ö>wˆ&'¬ÓéÉøØa¦÷ç¿™7BÜj´f%Ȫ¡ŽÝÑu¹¶†ÐÂʰ} ¬Ì5sG"Ð2¯Á#f±ÄltVCåuI<¹¹ƒ®ã VÍ¥5“¬û3!fßÏ8ƒÍ™/I~Úr¶hê;Ó 2äÿvh>ð‹Ï¼éGX’%‚l%š˜AUŠÂ"³ ^–¢À" P–¥bú;ÿðï-ñZUe×Qg‰ŠÂä>ÔÌVʽÝœÖAg5ëÒÏÞ¹y­t±u>l~nëäùoº3´^Ê©±{S¾ìh¼[Û®íót–ŒCcm¶é±¯[C7éüËœ#¬›B½®sª³^UsC€9D ɪr~Žª"Ì€ˆØ+üT9¬)2ÑÞ>Þçñ›¿þÜ 'ܤ—_‡¹™Íp¬‹z1nºškoy ‘ÿâoú’wÆ—NOuãÂÔ”%„çSê 5It&|±¬ÛÛwæ[[ÓùÑÑ|ïøéÇ/§¶ûÊ—o}íôæ;Óé8tÑL'ãEHÇÇ‹“eÛ4]SG@)Fv¶=y÷¯“²ÚÕMl€ÕZ;.}YlËlûbù;¿õ'q.W˜Y'VåôøÈú€ –Áƒ÷0ŠMJÇ Žºƒ»wæÎMfÓÇ{,Šá6²%`B…ì´=ñ%1«wæ'Géo©®]1†ÚéÕ[{G]„ÝíêÚ¥^\þþÿ½xÓ~ËûÞýÖoùa´Õbþ©«ÛeAÖ’s4*mU‚³bh¤Ï²D2’zR‘Šñ“<\g™9B®¤+Á;š3Rý@o2öŒLŠFû ^+ÂY¹”ë/§–ÈeQᘩïiEÌÌ(yŒ£þ3E©9ȤNËÕÓ l[“!$Ãb%äWIHÌ[#DZY41§F…{ݧªJdI9S>ß«eYÇe“ò8œW·ÃÝ;4w¹IÌѶyNìïÖ\J bM½*œA{™ú1ÊY›³*µ¹†æïw>Q–ÍèŸ:¬+rk<˜€ä*ß÷Ú³š­ç«]sãÆøCßö£¢<¸þ" d ¨z‘¾1$C"’“1ÖËðòßù»?ˆW‹*§ÃBk©p”½GséÌ(§3} ]¯øYA›Š¨¯kô7\ê!ª¿8÷Gxò7X•¯£¨q´ÉOu=ï3¯Årþà@Xhù½‘AÞ¢°ÃI/ÜÙAD|ÎZ”Yùõb"^»©GBÉ¡ƒ„Ö¬¼¾A•#"²¤¬°Î•ÞÑ9Ûô’í-ñ†·> å{UE€ÎœÞ¾{ëdïö•w>°¸ýœ)\èbsong´qvvÇñÕ} 2ºPj’ƒ{‡˜þ¬,fÏ}}¯ô¸µ™&•‰!¶ul‹—VMU˜¶i9Ahåð`ñø#×/LgŸÿÂ׿øï_- šmU¢éø8¦$ÖCQÙYuýêl:›ì^ݼxeÃvÞD%p•CKåtÜFŸÖ'{§Öã /ÜéZ€ºw^Ú›\$fáTÔ*€ÀrÎmµsde¾ŸNîå[Kc§`!j수@K⨄PZ4äAdïh‘R|ËÓ“Ë»cceQ×ϽT³Ê¸¢Ý ®°æËÏ/OåýßúÄãïþøhëq"ç‹Ò9Z6©p¾ôT¦ªŠÑhl-„Ü€rHÆ”Ì]Æ9ÖDŽ%£0@÷‹,.ðð^SIf²VÒ¸¼F–ˆ°R¦ DP…¤"q åg„4Kã{’üJŒ”E’rêµÙ; É*Ç\{ sÛ»D«"YM­hè¸RËa‘ÍÆ)´Çy™ÆÜ©H½\vQ29/¦&Fébo·®­ ÙÖkœÙ‘å"KC²NNÓÉÖœçjîðÓb”•òy+£…{¶|¯ %É*õ׺¯¶4j ”ltÏ ½§j$ûжï„öMoÿè_ú/™³Óc¯%B”­ø9IiuwKNJ¬†ð³Ÿÿ¹_ÿ»ÓÊn’·+;ÚŒŠA:\¯¡Ùc%û¹Óºž¹².u½Ïåoeß7ÔÐÕ[`-pøûë&ÍçP©OQÊp¯õÄ•óaDD í-©2 !+8•EO!Wa5”ÎBD¾}l?7¿v¢'êY0ÙU$7½UÚ<¤«JN'rÙE4g.!ÑŠ*AU_™¿üåýç?û{ŸÞ¼<¡ùöòöÍ+ßxâñ§ÿí¿ú?.$ÙôÉ%»e§{_™GnßúàÎÁ‚¿ò'ŸW‚æA3Û*ËÀÅÈ›ãÖ7ÝF¨OŽºS,ü¨ BGºt{wÂÉü`ÿèôå›pç|!no9¾à·/mïìlT»ÆnG_R9òÕæ„§å>qб! ZÕpÔ8[4Ë(šö—?ý‡G÷æÀm;úÊñ•«[æxï4‘óÎ-ÚvZ5ßz–âF㺛 ÔFˆÁŸ‚¦ÔEqžÆMÇ®ô$Ì»v‘¤…‡ÉÄÊËwëE›JïÊ1lÌ@_|ñx†î{>ü±+oÿXG¥u¶,¼sά ãU¥© c)¡, M²-Y]ù€'Wm G2…p'ÜåúJÍéˆ,f}=P؉œ¤n•n¹N wÆp0—]çW̓ö9ÛÂÂ-æ*Qó&#§³‘*gI{æK©$4I a1ű2lT•S=dyÆnž£=3¿•S+ˆà»(Ò³,5!Ä$mרCVRÆÎ†T>YÙâ‘@í‚T!¡É p/ÓYÇørBgþ]a+5<Äjý¢C,ÒÐ= þÇUiÑ;J« ¥<2ŸÍõ,ë « &}æ™ÙüñQ¦>­zc DPàÄ!&csÆ…È„HÆJˆÿü—úæÍå®-FÆæAÞZrýØŽ†p¨¡¹ÍEjåã‰kÇIï¨?¬Î†èÌ¡åwGÔuÛª×]Ê]í,À×u’D¨ˆ‘ÕfgcpQ'ï¨@Å*¼É4aM2 %´šœ%gɪ²ˆ¾1ot~S’©ô'gê•­\í{fÌ™HI’ô$me΢ºѳê¯æ×ÿô¥;J‘)º:ÀéâÈ”|éê…úôÎórgØœž‚_ºvU}µsqüø3ß½}G/í΋Žf*£ÊÀRYàDºù+u껆ꥀX †‹.=0¾ôÀ?-Çéå­­«'Á9´ÞªHsUÔ8’ ËºSÆ<ªÕíb9_p¤ƒ“î…g_îÑ”4@±Ù»3/=  ²ŸœÜ­çó&Emk9ÞOEE³ Ó´ñ¤ÞѸ„ñFS7®la‘@™¥n“3–”àÊåb4‡ ² >âÁlO¥(/ìÌöò;>GØ¥‡ØØ¿Õtuf²¬»£káôD|A ù6Pk™Ì¶ 0ãñl±h_<ýz5¦ñ•ÑøÆlvujKã&Æù¢äYÞ (8M)-çËnÙ¥eXœ¶¡M)hj°^.OæõâÕÑÞ­–p…»ûup]4‡‡ãTeÁç'Ë®H0®ŠË—6ªkÅr¹X.Û¶ —¶‹Ùf ¨w†@¨OU5ªÄà‰™éÑIÝvݤ¢r,whJæó°*‘W"Ÿê©·¼o›¹eëeôë~ˆ|]»åsž­(¹ñW"‚¹CW=Ë5Ó.Hî¬35*&2Ôƒ§ÎRQøA„™ÍÆÈøû’Aß \žëCÏE+Ÿk¤…Sb!³ò?Ï̾Uc’ÅKf=ì›Èç͆‚d¶Œ¯ì\ܧpxx{/ž¤–½»‰U7ö•_ÎOÛ¶Vî0ÈÄNÛÓvZ¸¼}zÚ¨­§j'^¸¸q\û ´¬ ªr `vv/<ÿì~Ç2žºÉfi¼aa›½=8¢2´'íͯîݺy÷ÞþIÛ†¢€`yHvëbõÈ×¾j_|ùëÇGóÛ·ïïml@Œ±.a:uâ-]¾6 $rÖât2IRÅ®³ªÌL–XRRP©¬)K¯œN›Br’µÇËæðdéP.oû+—]âîàØ>üä‡~æã€ÎYS”…·Î¶(ËÒ»jTJ[DH’:×OßgL‰±iÊž-O´ª’+6…ŠpHY¸Ê$¾oÄÊOÌŽJ¢+âT®kYÞ.©ãÔfenT´çÌ÷1œ13ÞóÏ5+·Cr/"± d’5¶Ì=rÍÐ.pLƒí|Ƈy²oqÞ,äèëìn'C]LYz»å|ïYƒY*úúa’ñ¾õÁöœã²1Øv¼þ-k@‰ ±ZƒyÀ_ù{’Éys+¹z 2«uÅ`“T…±7Ô6ûüK¿ôrQüý'žØøø‡?éÜXDD Xcœ3!0üÞ~îw~go‡ŠQÙòÃošç"t³ˆk}¢Ïmòúþ}€D×¾áªÖ€öèÇPvR’³Rs«ü×õ ¹quóûÉ#ÑæŸþâOݼ¹¼ìªìΖËtÎÐ΃|^s… Q2àp¹|íÅT«K—öAæ?€¼¯¯çÉ‘¥ °ºnçð®g>™œ%çsXxïŠbTUEaœµEáœ5v…d9w6yXWåü"@$We±CŸFG6Tö$ã\5˜(gbïªÚÒjOù¼ìy´+V|n9,²QH.¦Â)/å0ô˜D„¥‹½·[i‡ð~öß™—G¾iË”^¬ Ö1¶P-ˆWDÔì}dh3%öíí`ù>TðõqPÑ “ã€xÞ·î \Ñ’( |ïŒWž­§îKÅÈ?3/µ†ïÂÚ.ë¼Ðsõ­|ó…ÉM X  I²ùüJ, Œ›Ïž¬aÍ´§®c³’cÂKR ©ÌáÙÏž~îs‡Îý£‹‹Ç›|ùËóƒƒnCîä²I…'QQkHHµCqy_Ç43¥!c×üÎ9Ÿ6¬çªÍzŠÔб®×èõ~Nä<9hE3]¬i9÷‚¢Ýuœa™lBNˆ‘Õôi ¢Xƒv%çC2®¯¡½#=Ûô÷:Ú¿6ãôŒ©@]1¸öªâjlŽ …ÞšÏ0ÓÕçÏ?w¯u›m8JéüÃ×gæä°‹cäH©[wÎ-ÁÉd«º°=« —!<"¨OReN‰³Â¯í’!ð¡#Ià:霋“‘DWÌTÙ˜RW &‘Ec•­ ›W;ÕͰDí-@R›Mà™[å¨ÊÌ!³”†šÂ’cb­Û6„˜;"ªMËë#[û4Ê®ã[±QÆc[tÆ7L*AÛVàZQMF– O,à‰$)(C€˜š²%!¤6pÛqv)€6ÈPì]JýûýÁpëtëÈCe\ÙÂçÛ²†=ÿ«¡:¬‡yœEó)ÒåeˆúæYØÆbx fuÎX€$}=µ u{–;Ÿ hoða!Ä~¥&¢†À±@å¨ Ì¤,šm*UacâVMØô0zgcæ|r!$Y=1`Qd陳¢ÃiEº:+ ¹ýL÷÷§¯ë䔯aÆdjŸM p{Û_ºPl]ð—/—»߉`ªÊ“qª½í˜° ¢ó6±´]ܹ¸á¬ ±ùã¯þÒWÿdþò+Í~Ý!âE.8oAX *ÈzcV›±LiŠI !§³œŽ ?úêB6½µþ&týhH¦ÙÈk ß¯d^:ì"­já> ²§ß÷T§ŒeërU¯Ýzîù»ÍOŒulïÅ[¯œ¼x²¸mG®,6Ç2š=`ýxÿx:žÍvKw\Ý[„.Ü[v–Ø8¦P›¦…Í튌îÝYÔ½¤Â5Ð0GC` •DÅÔ]ÙžíîÌ@a>6¡ÍžÎëzíÆxri[@Rà)ffT±ÖH"á[/„†Ôq'0ˆp’8„ŽRå­HRk@T$D ê:ae²†¡q`-g·$Öº ]RkdgÆ“¢^êîßöèc_¸¢°Eá|áFeQEQ8ï¬s}œ®$ƒD8»ñÈÎ&θ*gɉÄb| @Èà ˆÆV`ËËwãFÂqÅUɲ˜_¯žœ¤ÙÇ3dR¤¸äXçmRìN…Û¦ 1ɲI!JŒ’ Yúb¢ìA—’U•ÙØryæòSÿEP¢¡³&«€9·¿ùxïÅ—–m+7ªQ.d1‘¨à¦Ek(Äåd».µAÚŽC”ºåÜ–o׺Më¨å0ÝzÍa}œÅ6¹ˆtAN(Ádâ®?6ºö@ùë¿q÷ªT‰•HâÎ4°gÔ@}íR’ÝÝòúÕÉhdÞõΧ§Å[T$„Ô´AX¬5]Uá¸ûÝOzÿÕW›|ççê&ª)¡w䔄r­$÷6….áȸ’º7+`úpUˆI²Ñr.|ƒ@b]Ô)O£²¿Ácê ^ëÄÕ”4¥ûx¯ƒG_Ž~BÄ¡ýqããÂÙM9q©®a¥fÙ‚ªµFœåÄØÄĘb4„†ü;žøäÛÓ¶ëDÚûÙñì³§Ý1oL9j'î ¡k¬^"BPEcWýD’Ô‚*¹Ê~Ó>tÝ”ý»ƒ3JÓq–@ :2³ShPÔ>™.ïx¡7ãê~óâžY^ìNÆ»W¤&¾tp÷¥›êåbo2Þ7'›ÓÓý}oƒwºµQÎ`ëtÑ.òÆt\·]âW®Žn\Ÿ-ê6.Ú““è%Ú„­‚óU5rãÊ•¥©JôŽöOO¸ûÉ”BÇ&‰“?•:µËæ@•BSdà$Êb5ˆœ˜#ƒ‚qHH(SPU`ÉŒXÈ„–­5$…*drd„*µdD•ÌYˆ1¥ÄQÄYšÍ`:wãÆûŸ|úcÌ\V•w®,‹²,'“ ï¬ó¾,+k}¶1P$ €“‘½0óÓ‰WÖ•›¾Úråf†Ì‹ÑvOŸù6©uãÌôÌÌvÄœ-Ì«Déwô½%¨Ä¾ åNR—›PŽMìNRXv]·¬Sž©ë–ÛŽ_<­ƒ "llØéÔílù­-éÒħo /^Üʶ HÚˆ*’”A€‹ªµöÂø{?úAc üéË¿ôû¿¿ó Þ±~³ò£ÊˆhYï¨ ”{±ºál&ß´Ütú]ÿé[ßú/ÿÅO½²žd%ŠÙ½ß­ûs—YgS/¡9vyÑX?~#k’s¬¦! uøúº!ÂýF¥Ù‹ ³$ôLšãé{2©ôªQB›ËnKí•ëÏÜ].íȾ|óϾþìçëEÃI›òÄËÞ‰ïvfÛ¸zxûÏš®cŒÝI½ƒÖŽ'a©AÅ» S,¬Ž6:SÁ½ƒc"¸¾;ÚY:Uw§±B†Õ´‰ ‚,Ú4:-uÐŨŤ‚ Rq},‹½…1ÄITÈfÆ@à¹-•”Dò97Ù‰ t\x"4]””Ä;gÈ"¹Œ/eû‰’ºØž¢¤Ð1Cb†k—Š‹;ÕÑ|¾lý3oÿðƒ<¥à‹²(ÊÂÛñh4žL¼sÞkQ¥efP‰YBFdË”ÞlLJë7¬Ÿ8?µ~r–5¿’CœSD$gÝ83~sߺò´—òÚÛÅK?ÈHh N ‡:†y×.— ×Mê‚|îö!xO»»åûÞ~áñëõ®4Ɖ"ˆ !s 1¥Ó:†.:Tá$1#¢14{Lˆ9A°7.ýà‚yûï~õ_õOOoÄqU–Þ˜Á³’¥ Ü´<_¦ãÓî²ÄŠHĸ¾Þ]¸³{x2qÓ‹vwVîîú·!â•Êï|÷o~ôã*þ`ù¾Ö®h"³!tïÍ’V2¤!³d@Erƒ“œ¦Ø¢]¼R¼ó±Ío{ç'¬±1ñrÙzW4 âÆFÀmˆÌR¨5Ù3EÄyKØ{!€õÖB@cÖ<ý ÇÔ0‹ˆ @ )¿¯¬1‘ÛO}ꥱ±y{F&SëÑt×ý ²í¡(/±ôAº(…#ƒý¦¼úõµWfó®VYyК•co¾™Ò„ ÜU€fïéõ o¶ €”–Ⱦ³êOnߺõ¹çŽïÎv¦¯îÞ|þæÁK·hWGn{!~ksc:Ý:=:—lYnÏO”\”"/–@MXU×qR"Ÿ kŒM×rB#ä:†Ð²!°Š™u¹lUpÒRx † ¤”R^ÔQæÙü©P¦<« ¨·` 8`†˜´ C^„c„ÂùÒ™$T{-Pâ Æ0»$‘e:±»ÛÅdâ|A~ãÂC~è¡G¾ŠbTFޤ(LY¹¢ðeYZctźí=çW^ËY×[C€õ6Ì«$Ì@O:´¶Œ:ón•“HT‰<쑆›),꺙/ãé"þûý“ÉÄ~Ë·\x×3ŸP1Yèh-d?‘ÞúS3<ˆØ48oEÄer;õ67¹¿“d™rÕÙoûä'¾ãk/üÒoýÖÝ-v©˜/c•LLd å0ךqe?ñÉg |{+_8]œ«,ÞÓåͨ"¨ú¢B°9f.13'–ò°i­ÉžrDP–&‹ bvi;ÉÙ9ÚÚõ_¿ã›W·¾Ð….ÅBL…wƘ¦^XCÎyÈ@jbðÎQJÌ,„èÍó­É¤MÞM>ùƒÿÅg¾ðÏçwö¤†Q•i…½¢4qoz’•”Ë&5÷óOßà£q)ß·£‘ÝÜt×wGï|çæÅÉGŒ)A•P—m·¬ÛuæÁÓþ¬_ÁÙŽoy¥YÈ%¾ëø£÷ôàã~ä‰ ÷­U5J‰§”„™ì²îbHÞ[BrÎøÂþù¯•(kö“;÷¾²®<\~ögÿég`cl3÷ÃY´+öºöµð(Â>¦‰`¸¤‰ÅZc¿Q+šwŽëʪ7~D¥$MYT¬«mÒJßµŸÛ;¦³(#™B…¡ ÝéþÞ|ïö…éìégÞ:šNŽ÷æ¯îÝ ã;õ¼IÇPy³{ùÒÑí{‹vQ*µ‹šœõQ8.Ù†’Â9RÏ ´ RÝ5‹&úr,Ê¡€*‚Rx‰$„ÕæH$Ë™½3›3KˆË¥„V@XA5Cù¹oc‹ žÄ8 ˆÄ „¨ê)À„˜T€œ3¤,á”i}áRb@m˜‹Š­-Ÿ’,—úèS}葉sTÖ§“IUx_xkEÓ*ÖM‡¬Já¨ÐU¥WÉRé·yò«cr¨9ã*°~¢ÂÔ¯•24åÛë5ATbŠMÎØPIœš\Cc7ÝÉböÂçïÍfîc»ryóœu,‘9‚‚±`•…û….fGËl”B2† oAûs!ÒìË™“{Sk ³°ˆ1øîgþÊS¾ò?õ‹5¦«±bÖ.Pá©*Mݰ5dHöñÓŸyþ/¼ÿÛ'æÛ'›BdDäô´©FÅÎÎtqZg3܆Ø:kY„ú,OUa!BcÈZõJyë°ÍÕávhœ£GߺñÔS_ùˆAoŒÏŽ¥!vͲiÚÀ,£Q1ž¸²°,â½cæ¦ Ø·uÔçЉ D"a¾ÿZµø¶Ç>±³ó¿ÿÂ/¼|5U„(¤]¶à,†(, ¢1IÓñGþÒåéÔÅ(ß”Ë8™íé{-n•ÎZamCaÕbÔ¶ ]'îë™ÖD™ôš“!|tÏæ’ÚÙ—n²a?ö]W¾ô=›³+°¤År!¬Î™”¤mÃp­&“²*ýÿÛkõ:ï+çK–ögþÉg¸ÓKE™kè`׿²è­F³gJjXÌêwOˆík hî+×RÞ †Rßóä²+g"…¤ÂÐë>e5*Â@uÂ>I\O¹EëÑïlM|èí×®¼©˜îL_{ôæ—žÝ{å =lM&ãQeÔeÙÎO—#ˆ5¦œ°ŒuÝÆÓÎYã=Ž7JÆ„&&M~LÛÌrÑw1AîëšE¼³Â ©(¨ðä ±H䑌Í:2U„Â’$Ь8³y2' $*€JÞxKÔçôIñŽˆT´Ë B†8qÛu£‘™m8²°XxðÑ>ôÈ¡(láµTfTo©ð†°Õ@é/lÖª«¬t“€k\úÕ ”·®6×P"׿L4çô/YÔî±7‘”•ï*)Å%‡§.×ÐÓEøüþq]§|äòÕ 'C(Ò…È1iå‰)}, fI²ªµV5eº ‹ƒµDÙµ †ˆóÞÈÒpQͧQâX¹þ«¿ñcÿãOþämß<€£<­+ë]ïÝ9û/}é¤(>õ÷ü@I‹EÓ¶áê•YÛ4„#'%çLˆiØ—fHØ̲œœ„GY©£úäSÓ[_i÷¹‹¬ïyÏöûßõ eD4™t]ºdiÛcÄ­­ÉhTxo­³bÛ†¶‹@9(0±|ÓkªDüÀÖ÷½ï}¿øû¿¿G½<‘…œ5„ 47CÎàïþîÞßþÏÿë|Þ¨ª³Ö:Ê".kIUCHÖš¦í2Å83ï%¥€= °nÚ81+ñ‚;Çz\qDà\€³ ñy©ÝØp?ò=×½úÂÐ4M½¬EÁ–YB—RúÿùZ{_ÙƒågæŸ|&F¹ZVy~Ï6©gÚ¼/Sdú¶¶.ÕüUµß(ûóÏÓ®G—äǦ>~+Š‚VOЈ͡çù&Gò9T2ትåŽ#¸¶³±Η‘M)îM—ùÒtãå›_‹Im ·6ÖXÚM¦*ÑŽœ3`K7-ÉZ^ìwVH“YÎ9P>⊠pQ=žÀát!1" CbŠ ¡±…Ï&5 ŒPªC^ ©ŠQƒ€ÙkKA£&bƒjÅ ›ùž ‰Õ·)BQHP 牉X”­!K]ˆ1&cLQXchT:kd²ý¶'ßö […³T”EU&Þ™²°„ÊÜÙ>ÓQ³0ÙÌ>§0ëaëAn‹‚h²2‘ˆŒYA¥ùUÍ™E™Ø¤Â9¾˜S-±áÔ…ö(…Åé"üÁê2?ô}Ÿ6D’AB‰ŠˆÖš²ˆƒ·öF‹rÞˆ‹´]c²Z{BaîCïrDEÌ2íÀ ‚ýÛíGÿûŸøÇ)NF6§~ñJ÷Yô¨|îsGŸúзÿUæ”"B$´Ö°ˆŠ:k²Wqæc®í^teýIªÚ†n4²Ç.o–ÿÉ||\\iÛÈc @hmVǧ.Ä”x²QM7*cŒ/œˆtm`–’ˆd»5FTÿ¼×Ê™ÒûßõÃÏ?ÿ¿ÜÞo®b…HŒØ´©(26HQecâ^Ù¯íÿú™¿ðU$©jÞ¢0³ˆCÞYæÄTDÅäÌÊšCšýF5E&CmËo°›ZE¥Bf¶ Áy"p'6Îч¿ûÒ;ŸùþÞÞôÙ²ìª\ÃÞûœ{ï{ùr®ª¬A¥’ÐT²#aaa30ÁÐ’@¦™1¸‘;ìhG÷‡þ:¢£;ìvƒ Hb²-JŒ02ÂFH¨,!µ&IU%Õœóî½çì½×ZýaísÞË”„GtGTddå«zyß¾÷¬½ÖúMl*"•s®@-üxVÓçªT‡ƒŸ}çuD—Ò"b‚®ãÙè/LÖ¨Elh&&GÝMNT'÷p›³?Gê&AûbtÖ‘&S}­ªyj@Õ˜ÝRE©ÅL˜#‡yè2_¡õ ÈÛMH£ã³^ñõo,é0¥Žȧ}—ìês"eHiGeØ®7«ŽOŸÛÀe(¤„¬ÅSÇ1GP…à ô»E‡ ¦H¹€)H…õ&W-DJcQP4ÄÚÀô†()€TõL&äò;„@h®*`bÊD  CL¹TU#cÕÊA€¡(c±QRÔÝÞN/àÒ}qufo°‡_øâï6…”0†.ÂjÕw1.W+&‡×]$&dž­Äè )Èmž fBœ˜;·Gj†ó ê §Gƒh1_žzÈGÕ:LDúAÊFÊv®¡yþúÞ^üöoüQ3hÞ£`ˆÝx’ÈÌüémr˰·1 +‹Šn·#³Ï1|™B ÌÇ)5Q"B´ã¸‘’Òò{¾çÒoýÖ3À2Er%~ŠÔ%‚ zwì?ò‘7o¾ó»¿õGC­äŠˆµHLD´ëûq,hàc¡/¬*ˆg7‘ŠŠ¨®Vüàƒ«|ËO aÉEJ13],ú’k­âG‹EwîünŒáèhËBPŠ ‡Æuýo9«"¦ðƒoúþöó¿âä$%CC P €Pôž´øà¯îú×_÷šÉ'¼0À jg/ú4æJŒ¿Tï͈‰s­°èÒÁA!<.7ÍØ˜ñ+…ŠÚzS÷¹¼êU§¿ù oíûNÕD2#j•ÿÿΊößþ‹¿Ôu|V32Aäú¯¡³ÉÜh»@ƒš´öóvæÒ­Cý šnÒš»î¹çÉeÆÉ´ŠŒ@ÜGÉD„¹ÿ®Ô±àx6[Ó'øZ‰tŠÎÒ¦ëSLq Ï<øÚ{‡­Ê°Z”’r>zþÆÁÕõÕË›8Ä@Ðçí`±Ä”­ô½–­+IÅ ¬( ¸áàòäZ+„@Ȭ`¨X”‹*ƒ#U¤&1Ru®«ˆKƪh` $àÄ$RÅÕExªÄŒÈF€Hbp8ªx|{Ô=†ÂtPG+YlÐòé^:«½¢Ó¾\±>ô·€A꺾ïº.®–‹¾ïR€•PkÙÖZ`bÆ#"#’i™I -äËåÀÌÇ…Î× D(ôÍ2†â1¡J%„ÄदJD²ÔAêVòºæ£2HÙå|ñê]wõßö·~Ô̼rÎcŒcl&fþ„ßꀾ%$L]‘q( šsE$@àÍ÷ïþ¨ˆø\Ù”(@L¯|ñ÷?öÊ_øô§÷_€+M“ VÍœ«7ôŸûÜÑ/^}ç›þî÷.O 1 CögÏà’«ó¾g›b/8p­âÕ'Äpnõ?þý @%b'i´±,ךbèúTk)Är®‹Eç–ôjJŠ`Ά¿ÂY€! ¦DUmçå/Ûýó¿8¼m]Øøäþ|$¸Ï–¿û¾çþå׾╠ÛYV]-»ÙƱô}óN‘Kq„ÚòXÌ,&þâ7!ÐÉ9W'iìñð~¢†>µÝtKþá·¾à¡{ÞRª0©U"üªgµ\-‚ª8àdÄfªÿ gÕõˆ¾ý]¿#ÕDLHL>È»³×ÜúžÔ%Ô_6æä¶aýËçÔŸ´;¼“Ѿ‰”¦¾WÊÆZÀƒÔš™ ÌDe0Ä)t#`c+¬íBxx¸¾|…!ŽRT¯ŽGOQêvN5¼¡0^yúéÃ¥ÝsÏéZqQÎÝ»¼q½®÷;QŠÀ–ÇR‚!3lÇ>Fæ¸=Üæ¬)!1Cd6th­¦¢fnÒ¨!@×ѲhP‚¨Œ •½ßQUTkÞ¦`jãXæXG'‡ªè c`¦ZkŒñ{¾í'>÷¹¾ÞÖeU\GHˆL¾Ñ£K¸¸ºù=üäO|ÍY|sˆRrué ›˜;8Š 8 ½jëUB`Uõ ˆVmñ¢H$"C®±O.ì™Ú0–ãÜõÉÔüIU°* €¥Šoîð¬TTÕbd@`Bc L±£ïü–¿÷©O¿ÓâÄðPªë”PЈ°Kt?.çwž áW_ýÒJng%˜±Ã1—\j`îR”ªˆXEÈs jfªUbä+WÆ ©sÖã1?‡Ð1¥™Ø4×ÐÓ§Óÿø÷ÿc§ªŒ S8Ê_~V8Öºy使|ó¦Ç Áï8õúW¿5ð¢ë¸J½ó³ Uñ—~í_ä¬wÇžb .Q`JÑËè±Ú8r³š'˜Ý';ÐcÕ©B~y“ÿwž}øë&z¾6 ùØR001ÇÕÌCäP½3RÍĽ4–¼­b¦í ¢£~3@ÌÙôp}óæÍƒˆ{g÷±Úz½³ÉRóáXŽ.îêppcgQIÇx*ïœ µ”õvÍØ1Ä¥zþtèv— iÌ4ÛÍ(¥Ô±ÀÙ3Ç èˆs5"X.¸ïB˜ôÅ @B§È`¦r¸=i&ˆÌF@H0f!€™‘Ä•®ò`ÖÀ”"'Š" ªf ´5Ï÷%Hövö¤†ðäMHçzÍK(uçº.¥”úÄ)X-yXÐX*2¢ˆ}Ünmöbê¦  ·Øpyº†Û†ÎÌ3l~1͆9Z•i‹jóZÀ°·x`ù7ßðÊS;½VجÆ\vwýN¢Eê4£j8«TÍÀl"i½éM—yäÉ®ºÜYE¡‹³4Eà‚t‡¥þÜÏÿÅÛÞö›÷}“°R#77 ÿuºìq>ÆšÛz›LŠf¶ÝŒªcX.»~‘˜è`½-¥v)ö}TÕ±H‡a=<Ípš¹!*|Õ³Bo½­õ7^>DUDÑlµÚÛÛ‹ÃZNÅè @! ?¿s4[4º+ö¿ýÛÏ>üâuà%˜;y3"‚º¥€A!"‚ˆ kõM*z6½…qTXÌ3èqAqn“×Ð*­†îîÆü“o#N5gs<䫞U—VË•Hýß}çÇ>vÃU°Þb¿ÿ™çÿ?üÌ,ßú¦ïN|7s$¼ƒ³bŠ1üê{þÙg‡{ûv‘<¾Ô[Q_Pø•c$³ã­Åm)„'ýeæ N&ˆœ—TMÁ¾R+:×Mw6½½ÈÊ`êIŸ¦R&5"äÐs\õμ°ËÃÑõ2’î$>;\O7žöN…›ÃµØƒT¸|å ;{ç_ô¢×&ÞýÈç?øÄ•gîºgA0”õÁ0ânJœGTCJªSàÀag'ö]•rå®H-|¢ ¦„Æ)±Rl[ªˆ&tQY•¦NcVBH Í€üÚÑ\•˜"RÇ+ ‰"ºÛژ݇¦r”>¢T]îÒ™3¨Iž9ª§Nßÿª×¿e±¸Ð¥RXôi¹\­vwÝ"¥ÈÁíаñä[6Ä€ñFÚM1]{®Jrˆ¯…OÅñ± )½í“Õ#=dtPê R¼ ÍÃãáã×nƒüè[ ˆ@„ˆ<LUgš€:49Â!¢á{ßÿ ŸûÜхؽ`é«^¨UK¶Ï~âèŸø£½½G¿áοìÁï;:ÚŽ¹Žë1Ž)ªÚ˜ –\™)¥è•‡m¨Z ­Þõæ½½±­¬Á¥~•Zl@#–ì®máç~î/þá?|ïÝ{oAUU}]àÍgiSm•¢Óñ¢©mƱVµÕª?{f§Tñ…Ëf–«>Å`Èõ]ïþéÇ_«ÚéÓé[¾åâk_þH¡ŽÛ¿ä¬D<"|§á¶Ly,DÄ‘ª¨T}ÙËv?õáý¾p—HÔÂr§f (…‹ž»Jÿ×Ͼóý'ÿ!ÌgÖ~>5Cç8 ÄÀ9W& Ç\ÌŒå’oI…À^:¤9ª4L鲌]ÇÿÓOý@·Ãž‡°ÚY~öé÷¼ç=O–¢wÇÅÜ*ªÙBØ žyrû¿ÿÓG.^ì^ÿú³¯{å[SXšGº}…³Š!}â³|úÓû—º…Ãñ!M¸ülº8»M»Ùʼ¶œÕFóÍû3’Ä?ñ½/Þ?Üž`ÒΙ_~œŸ¯ ž\Ǭ¥Zó_‡Q¾õ»~Äu©ùðhP­ÌDÜmÊ"ožxªå±õ•çì(Ñ…%_nا/›#-Û—Ÿ¿üôeS~ø5¯záK_×÷;Wž=|þ‰'Ç£mËúæ~ÝBןÙ9µK¡“RA1r !0‘Š–<€ißSêx±€Ý½hjä™…l!´…¢C%k©’‹‚)Es¬z‹¬s”Ì€±IlK-¹¨˜Å€16y‚º?'¡Lns‡ª(â+$©0ªT,ƒí®$-q£euþÒ‹^þ–Ýå‹E×/ú>ÅÅ¢[ô±‹S @µ˜ÖÉë¼5Œ­]2Ñ)¡Ú´¨d3ùÓüƹÓ]L;zŽKnÏÌh0%ÁQ"ˆÈ¡7h’fÕ ZGÓêhR-ÉGeÜÏÃív¼~Ÿ¸¶þ‰üIæ4gDL“¯âi±Ù$†ˆ@ÌLq“ŸyÇ/ÿÊ•+ùÁåjÕ¹½êä: ÐÞ¡ kûÄg÷Ÿ|ö“/ºÿe§Nê;ιä±l‡,U™˜µ !•©qô¤93@zዯþÑŸ\Ù¡àƒ'"Æ.²óGBaF®ð\ù›_÷j¢(*n³dˆèÊ–[ô^fŒ(MŒXÆ!{Qˆ1ìžZ.Î¥¦\jÎuwwÑõ‰)–ºý?æg®^/u‹½a ÿó|ôÃç.~áìÞùÓɳ¢y®l]bkŽpêA&òÀ¹»žûÀ£WÎt±ÁÅS¤å¬‘ñ2·¾9æ/<ý©W?üz_+·T¾fpçY>gOÇDLªÔª1áþø£gú„زCÜ@ϱø1«×ÐÍ %èÿò~Šq&wxV¥Ú©ÝÕoüî;ï÷ž»ú½=d”¦¿ÈõEK;ê¡}òs7ÿËýóÇþäÂ=_Ü[½"Ä΃POž è;~ñ÷ï ½»:…€1P“*…­Šè¿o-'k(4èÿØÃߦµ'":ü¾¬îóÎINÇÿ;¢ã¡)’™ 1Ä´ÚÛKNä&Ž*Ù)çN95´@érÞ÷¹ÄÓ{g^ùª¯·ë?ýô‡/?ö|ÎÝuîë¿á —ºÿòÍ'«ôÊW½(ß|êÆ³OõöNŸ•’(ô ã°­¦1‹‚!DT]¨¥*X PƒHˆªHkÍ-°ùÖ0 BŒ¤`¥((Ð@À ͪÐÍÝ'ãE3(µÖjÀ™Œ(І¢Í“У‰'bŸH.ÀR„RtI²Ó‡rp¤Ö‡»î}Ý—^Õu}ߥÅbµZ­˴躮sÛ™h*M¦éåI‹™ÇÉÑ X­Z³GD•œbá‰cê[†{ aÇL‰;âਸ਼ð瘤™ª–†,å£2äáæÑz³X}úú7~ãÄ^jiZl3CR[øð4q" s é³O=òîwñü©îîe?§œ;]fn[v›-ž~zûÞ÷?òÃoùûËå©mËv“cäåªË¹ŠˆªÎ©v¦ê°“Ó:ïÚû®½½Ç‡›J„DF¢¢ˆÒÂuIM*ªû¹þ»á§~äYc9™™6ê¨Aã?™ˆEƱøú.­vz& ‘`½ŽÖÛÅ"b)Bˆ]ŸÂcÏ=ò®w=¹}§Û²õBè¿ökOž?ÿö·ýØÛ˜{‘áø¬ˆˆÐÌB ZµI‹‘ˆ†ÀsCijüwEþt̺èYÝ@ÍúÈN2I‘D„/†þóŸ?*uBçÒa'–™Y«>ÀÆVJMÑýâj <`Œ·óíCâÙ—Óá¸1ëUßö£Zå¼-wvV¢Hˆ?ý®Ÿ¾zu¼o± 'còpvÌCQBdÆ%,kµÍÓòŽw<¾·÷Ï¿ã;î~ø¡ï]óØÎªjŒñ]ÿúí̸è8N.‹s­ôY~æÒû]~[ cm}®y Ã÷·t£4aí“-Îû—P¥a´<ä’Åñ?³ÊëͺäZKÎ¥H­cÖq¨µ"õ).©ëÕQWìRm_†*ÞÈ¡q€ˆ@MÜlÓ³ÔzØZ4çK216Š!ŠgJ$d‘f{S²ˆVBAQØäR«u«øàË^óÊW¼5rêb\ô]ßwË>¤)5½YÛ]:°î 9½É¦ñÜ/bt'fÄÏ~ìßžÚ]„n7¤vc·gÜ–°[] aÒŠ8'“²EbÓê¿zú±–­”#)›ZÖy{=76ëÃõF>üôµK—oxõ«UUƒH€CÞêÎÓ²Íwø!ÄÏ<þ«ïyÏ“÷/–gú4‡£µpó)SÈÿ\Ôˆp…áòÑðäsŸùÚWýªŠËe·Xt*êËÁæ¥{ÌÑ™™À@!~îÏ?Ü Mðç/$bOÄœª|§üìþöþ‡ž9³óðLµn¢ßÁ¦"*UÍ,0u]Z.»Uß9·q¬µÖa,"º··ƒ\ª¨-—«}ì—~íמ< Ý™.y‡?œÞ­(\>ÿðC~ãßøëD5ˆÇ£¡ƒZ3¦¡(îHC$¢¢ø±O~4 µxNnÔý6¯^A6V6Ÿ}é‹__Jng5Ñš@ÈfD5µ1×<Ö”â“Wß÷©OíŸí;ŸµÝßµ§u2¸ªã›ß|ß‹ï}K.ùÏŠ(l‡£Ÿ~×;ŽŽJs8˜Râ.QäÅ„î©yü3"ÆH»!à~òúG?ñ‘³w}ñì©Wú…‡È=ûúе{ÒÂßýå" `ŠÇ+Q" „8CLôeÆùyÏé…q^•25gÕpöt‡=éè Çz)³)$ÀZDIK¼Àæ@êÂ0S4õÎ詃gŸüâcayÏ™³«x1¸ÖïéKÞð’s/ìY·¥l>õg3«qE¡lÇe_î½Ç.×zxõ`[q+¦9HH d5e`51 D(…DB }C³ AŒ!E7Ö«Êä³6v©9×øç]UK0ˆT¡>$˜PQ™ ‘ÜÂ=b bj )F&Ül%Y| SÈ[E­)Þ;}÷K_ò¦È«.9ý^û)…”bA­úÌÄÇíæ-bèò0CC›Övæ‘î€ýSáþ[Äï˜ÝÕкZx="™™J•²®e-’k>*ÃÍ2”á`³­ëR«}÷·ü¸LÒx—穘j+ŸnÒÓî}0$^Oýú¯?õ’Ó»>¸´êIC3(ʤAQļܸ÷ÏCÝê±gÖðá_øæ7üƒŠãä¾l`F+Óž‰1;Hb`jòª—}ÓïýÞ¯ÖjLÆnêh6A $j¬(Š1Ðé1½ï}ÏýÃkÿ™ íEËûÐZÄaëE—‚¨•RK™ˆÇ\ýf­ÕÓJ1þöïÿü?xÕ;,Oøi£(TÐDt/-ž¯ÃÛáçþç·ý±:Íím`¯UmíC`¿Ð‘QDK©Ê ‘Ã,/ÿÙ0stæGÕ;}3#.jÿñßü®oÛ¤”Ðã×ÁNȦcsñÍf3¨Øù3§>ÿLÝ©¡Š¦©Ü˜A©¦S€óå:ÜwßòU_óßç2Ö\ïä¬D¡–áŸýì;j5oÕýíRówYÖjDrisN³Ù' L÷VÊkýWÿê ÷Ý÷3?öý¿K}©òÈ#Ož§Ž}¿Á4c9Þu6\žÛ'”諚“md³èÿ RÏ0o<½e½è±¢~¹ô“9)wövB n!|­åCQ²Ë7oÀeÉ›SÝN´~»=Ì} w¿àâÓ?öÄãO­×Ï…¤¸Þ‚ÔºÙò¨—övÏ¿dï37÷·‡UUj!óÈ6!5]®ªU³y²–03¬] ¦À*"ª4¥9Ä@IT‹¹YR "¦j>;*˜AÚ,@þØ©kȘPÁŒ€™€ó¨šs1ƒ±d†ªªE iµâU'!rÝ zãrqO`K)ö]·ÚY¦.ÆRJíÄ&eDg N‚Z•©2…,U1Óà= KOõt’©‡å9-ÖTÀù’U'ÛKÙJm¶#ëm²þÉs7¾é›.‡˜œóh³‰‰S‘xò ·Vˆ€ßõ+¿qéübØó|– ž³Ã6CöÊä½f}j!9p)-þèƒ×¾þ5›c`@Ä1—RDDb ÄÔäÓêP‰ 4 „Žqr}5—KÎûn}3E[öüÌÕm®G)¹U` Ÿ÷­*Z«”Rwww».¨šŠë0@ÍÆ±B L1òf;æ~æWÿø¯Ý¿\¦ØRÞÜ-¿u72;%ëꞺ¾ýôã¼ò¡¨’§(i@DU¥É@–·CÄÐ2§…Ã]wõO~r³è'ì×|÷s¼Ùwèј>ðè{þö~¼”ÑÏŠ©qrkQõ §Zˆ\€šRG=Y¦ª“‹h.Šˆ?ñ?¥¦ZåNÎ*ÆRü¿ßñÓpo¿ð”æ0EòSj‘|Sì‡{rˬͶŠzÙí„._ÿ·úöoÿö»|.chsº°=·Ž¼†ÎáQ~Èó¿ž4N<¹Àt1ÑIŸ¦0G’ô"¼sèÔܶZìû4çl8ýÛ .³ñ1© ÅLq¾èÁ+_Ø\?Ø_p¯’·#Äå*Ô¤àæ ª Åöëóá~2Ü é¾sgv–«p¸AQÍ¢* $YA•€úžK±nÇ"10 hFcpNº6J½ÛB›ePI+‚¡76À¨„ .•­`L$&ÖÅ&øUƵ1¢Up]³™îŽ%WF)@Q-b8ÂéEZ¬Æ£îyð•¼øëc)õ]ê‹åb¹³è»išŠLÅPÍFuuWPDR·M­Nÿt'7"Ði áy™f:·®ªUÊ)0'äèaà2|"ÐDxlàT¶R·¥äaÔëûùÔ©øÚ—ý°hÍyšè k•Ƥ <3NÚžâ»óíà—BôgÉ)â'uu-ܵbVñ0w,[}ôS¼ñµ?F ãX|ÎM)@ÉÕ…Ç®§fj†»]ŠU¨ïY·FxL¥V3dFoE½¿0£èÑÿç7ÿöëHÍŒÀÉäâæ‡Pª„À‹eç†Á®¤ L.WGÄÕª‡ ˆ‹~ùÁýÊüÁ•{ûã`wç øÖOÄúkµõ¶úß~žºG½þʇ`â9 3•R}èsU7¶ < %çÚ5@‰J»ûî~õ4¤Ûz_’ˆšÿÔCÿÑÞxãë ñtV]ÇâíN­ÂÌ*¶ÝæÔ…¾‹n-pxXéÖÍK³WçòðßyŠ”;<+{ä½?{íÚxßb¸¥rö‰çÌQŸOÔ25“F®LT¥ÑòJÕDt‰õC¿s î9µð?ðq å¶Q!5àãÙúË4‘sôáI¹üm±žÎ5oEgW§y™ú—+—˜@íöD¦f[í«×¦šoI“.•œ„öÎs4Xíô¯ûÚ×>s÷ö¹g·¨y}t(¥Œ²Xðùûîy1(Þ¼þì³W‹h—J¡Çþüéƒ#PÜÛ=%Ûu4®ÙHÁP¹‹)°”MJ9n6ºÝ”±Žè ­R™D4Š!#Ï.¦– @ÿo™ÜÔ`³•!;sb¤Ð G *XU @Ä,¢ÈÔœ6GÅ')&R©*ÖuØ/)®óZêb§{èáo Ý©”º¾ï«årgÕ¥Î.k*a/¥sⱜH¯Br¢(˜jE$¤Ô6¤ÆŒ!,Û,Ä ‘9.ü×¹E$ÀU+ªÔ&šÐZó¦lo”q?oomêf¨Ÿ¾~ðC?ð×j­¥UD'î!ºD3µË¹"1qè>þgÿòɧ¶/ÙÛíR æõe¿¨¹í˜g9ÉÑ}Ác  EÚ²ÙÖ3–}ôú_ Ãs®)ÀÖ$:aÅGy"ç]7W=ØÙ eíéx·0WR$Ø@B€S5þ×ÿzãë_[Ì407©˜/÷s)Šû¹r¬‘7pžrÓG>ý‹ÿþß?w©_8±ÆùÞs(ñÜ[5ÅÊôz®]ËH”ÖÆLÇ:óõÊK÷™Ä2Y¨èÝøâ—Nr²Ã#â鯄GGõhü£ÓË¿¶³2%DS+ER2"û;Bη DØâ~N›AΟï^õ5ß[¥˜¿)_í¬ˆÂf{óOþäÆýË¥%~ÍWº™á?QZ3h¦ Fªh ÍêŸ&9<"…ç+Ä+²Ãý4)î½'óºo3N=Y(çºÙÚÿ/©¶‘çï2Oûw¦\òØ5œy£ÞP˜ÊèÉhª…‰[gê3‰V,Å šÀšoââÜ…‹ç¶Ãõ+O=ypõZ$èãV—Ë w_b¾ôÅÏŸyö‰gTV¥„u)²Í76Ûƒ$ ljŠ‹´£2fC6›dØÛëW;‹tj›í¶š)™zL9xú/)˜‚©¨kU%@fÕ ҪèØ tM Å„HäÒz¤B• €ÎÁÉ¥–b`­r[{ëv b€¨5&âÅݾjïÌ ˜,¦]CèºDHâQU@D˜@´u!ÄÉýº­¨ÕZ·jnCúä7j .=& z/¦` ¦MƒOs w S)RÖ’×eÜ—²®u#u³æ¢GõÂùt~÷›UŠ7MS¨¯¡{Fx-H1Tñ ¹ú¾÷=÷‚åj*kµlzRAWk“æ¢PnI*WƒEÇOl¯ß¼BZtݘyBNf†‰("Šˆ;Ü2c¶[] uÊqóÅ*Y—èúf4¢é̾h\w€.m_ò¼•¢µJ©!pˆÉlûþ÷?wêûÄ!`d N»¢'šÜ¦p)EU<ÁDtr,)Ç3Ž1DïMc`¦œkkúaΪÀÛ›<Œ!B2ü£}þMßñwªŸ•©AËÔ³ýýu×ÅZDES !°JG½e­§­L›ÁuË?ùæ2±iÕ;9+$ýÅw¿{Ùó\æ¦|@œÜê`Þ]¶e5/zw†5Wyõ%L¹§sßDEg‰²ÿ:Õè[G³!ýÃEªvœSçtrimΦ''ÿ=QjMRÃ=Ô@¤–*""1°™"1!oJ9Ú…å’¹+ãÍ+Ï|¡®vwúpfqt/W÷׋¾¿ôÀ×nÜ6ë¼Þr— `”ƒk7ó C­[‘:ŒˆC)c•-± Ú/™XUH›s1Tµª¨jâ8a³L&wtPÓfªŠËUX­À7JDDN ÁÓk€ˆŠ` TÄ RADÑ 5C5Eƒ>BLPªä¬©‡>…lýÙ‹/íúÝ®K)öËU».Æ@d"c­UDÉ!f0¢dV‘œa(ˆ&ª•89D@©¾>ù½€Ès(HˆK·&±cµ¨ÿCfjXU²I0ÉëZ·RÇ:jkY—ªÃ(zóà-o¹WU‘‰àDdó2Õ†#û$0ò³¿z›ËïÕS%<â‚ =•Þ¿ÏIù㎠ Û!&ìRHÄc)DT?;BèUÒ%FêhrŠäVók˜’*àVb|ìé÷Їþ^ÉÊDÁb.µ!®O®Æ)¹šƒmL‹E2Àa[þŸþë{&BtÜÙkÄÌß>“wÛÖ:¸‰¦Rpw>Ghkò’**ªÄÈÊæ$Rt›y›ÃhNHò¿t‡âóÏä±H¢Ž¡É´Ä(EÜSU¤•ÁRÊmÈ¥hU³1ë… Ý ÎoÕBïä¬vV;Ÿzì‘££rßbéõnž»½†ºý’{÷9+®ŠQhÁX«±5wýx"jÇ¢$êIÔÇÄ)jɶ^I'Gðãžtæù¥:KäOòðÛPïa~I =9ΟœåO2¢Tm~5S–¤R­£göÔ*NrÖ‹¯¾F)×nìî-BªdÒ- —‡í°¯Ãáª_ñv”mEZX/0,SÄ‚²ÙîßàSùô)ÈG›ÍÁXª @4-`R‹lóbd€Ž0!EJ4 %5m’Ù6ƒy”)O±×D¦@ÌAªª*QS H3Y˜ €TÚÆ€8€©‚Anb"ÃVŠ(ˆÂѶªñÅ»^Cè»År¹ìûÄhDšóP«˜G¶``ffÄ€Œ@@VË -ñÉb‹*ôáŸÉÙ GS´g[›"ÇæèAÍŸØefdDb­y­ZµŽu¸)2JÝŽc]oë0*3¾à®·æ1W5„™/Þ<åšé¸²ˆžzjs‘:wwÉF3 ñ„‰j‚6ç¦}¥|]ÿx§.æ±^¿~xöìnóûiŒk4Có¥ª/æÁfe3~)üêÖŽÍ…Ò¯pª†'ŸÜ¼ü…H„*JH“騃XÀLµˆ¯! 2…ÀÄHD!°)}æÙ_¿y3_ê^ì¸)žaB0ð¶€õy¥Pª®Î‘&@vœó®ªŠˆÆLÄ(rˆ\‹xb‡wßO=ó\„(²õžçS_ÏÈ„‡‡U¤4Íœž©¾hŽ‘Cd Ñ®‹‹E ·²F8Õ®êøýß|ÿ±­öW=+æù}ï{îî¸pþY&ÄÜûй†Î:5²ÉIGôLS?ýròß×IþäV#„~æs$~©­ž©Oº‹|YSf:!„u‹üË™OPwÒ?æTO/"0©O.UFö6OÄbütRìµV³"B`e8Ún`ÿp×PõÔ^¿ ðYìêbIH¹G<Úô€´=Ê„#ؾÙöâ wî?»sõóÏ}ñ‰±–(Z)¹PÝY- ŒLI•J$ŒÆZ«0ÕäW\  P™˜âHHÄ@Ì5ƒ%˜M7 ù£9‰@¨&DµdAƒÀ%æq,RÍP¬Ö*ÐGˆ‘ªh©öÀ}/ÞÝ»ˆ(­Kµ–êƒdH‘ Ed;T3 ÌÎ""æhP½c©h*b>Î3#¢5œ¹½]m¡ä$üƈtè¿¥ ²¡™V0;vrªƒjMŠ”m.ZÅ>qõæk_s:rmtô§¬$S5AòÌ2SÕŠtùò¸èâcUÈEܼÎÛµ ?›þúÔ?'kžìI!†Î´æ\ö÷×/žö3“ˆšZÓwaó íûÔîV‘@E&Öšh´èsŸ;úöo$Q•*J6eLze˜áÀLÄLìÒ233ÇbŠÿù?_9 Ý\:ƒ•BŽá÷5v¢ÁY.¹”âÆþ‡Æ\¼PÎah!°»¾›Y)5•ƒ=ÿüŒ¾´ÒÍ=!е,5¢ €²¿†EŸÌ æZªœ;·"ç±æ\} (2cè‹l3oáE÷¼i,¹ær'gHŸ}ê=›M=ÝÅÉ7„ÐZцÂÑüÊýKU”=¨õ¤Úkµ V6€j8»ˆzùÂI&7¿'w£³{ÓÉê ü-M½L!¦`¡E†¢C_Ý oäý]otQµÔqŠT*‰BšìvÄTÜËÀ›Vf$âRµ”’³@ßGéh¬Û­_<ºqåæ…‹§_öš¿qíÁ×?ùÄŸ•gþLóµëëeÌË8¢ðΠDÄC×Ä£AI‹úu§ %žƒj´Y/€q#`É¥ÔºD Ù¦P\ïnµ‚!¹‹‘J›Ëº  BÇé €0Óôî"Rƒ–«P (**¨AŒDˆ8†‡P Ëð• aÍaµ»¸ç…/K±!„@DÆŒÌa²ÏaÜ5ç¢ ]¸KÌ fª5Sµš° Ìœ8¹hxLŠ˜•Ù°‘` õô•(qš—híõ"Šd•*uÐ:HÙ˜J-ë\Z¾¦*üõ—¿5—<Ë‚‰P ½3m>Î^01$dÆýýry½­UZ|¹ó®\2ƒ-ÔõË&{»´ÌäϬ±ë3 ¥TwímCZçÒøÿ6ošnIsÀÆ7š£ê'¶»9Ër=6ûQ«("&HѹGĘ8ÌAQ•ª¢šbÿùËÿææÍ|OZ¸‹%OKƒFöFìå¢Î²œdš ZÈE_x÷Šˆj-ÞG33"”\}¾v¼»ë¢ˆŠ8ü-D/W«§žÚv‘N0œnCH¨ë+Žiõj‚@SÖZ£¾OfP²¨5åxõ šÙ–È¥ô¥ê~x‘´Ö;<+üÿñòiKó­6{{+=sü‡H‘=«º ¶ö‰<£[Õ‚S˜¶)»¢g”65‡Þ×Ï2ÿ¦uëS ½ š?'"ûÅŒ³®)LK·Oô·ÕP:Î4b2³Àh¾¿`ŒªX` ܼEЩ7Úrlb×E"A„qÔõf8¸±9¸zx´°·“.ÜuwïKâ¹K÷¿ü!ªÏ>óù?ýç_8xæ¹a I²àшe4ʪãèZ=¼ym³Pàj€=sèr)ƒ Ñ"‚V8(–*Õ,pˆDDÚX=fĆ‘€÷Д€X] É“c›Þ2Y%¤j€LÔUƒZUÄ èJ`0ÖZ‹Å¨IJ¡€RXììì;·sêœkQˆC!Æ@Äó‰"§Ä„Jd9+1D6D6ÍŒ§d@d†ÐVœíi è?‘é±)1˜rÚqÞî aŸ˜‰ÖTUF•,2JÙº™S+UÇQ/År.1p6bò܆V‡¦©…È0œ?—Œ¬ bßñ…À )Rˆ#­VaµâUúÚew¾ù®1›A \‰Ð5¯µj%®¹¨ZŠáð`³{j™RȹV•)OTŒ™˜±V=Zsp"¸—!rÀ>ÑvTÜpYp˜ €TõÔEtöOÌ´Xuþ“ªå*¦æò|"ÐÿôŸ.ïÖÈ œÂÆiÖú€?Kæý ²êüÜîSyðÁ˜¿xz(¥ö}BÄa7¶9&N)%oÊõ‰'ÖwÅþ6¸ùKÿÕt~Ì­ùBí¬Ž†œ«Š^¼ët­¢¦LCTõE¶~yþ¸Ø·ÿíï+µ‚éœ6µ§žÚ\êˆàø[c#1ù8ß*¤H„0ßyfPÚ²ëxÆG„fªàø’xSr"0j†ªüÏ¿^ä%rnB½ùûГˆè¬ ŽäÎ=íÉzJ:¹ %˜® bê{ò"Oú*oI”<¤4x<¯Jí»Þ)¥¦2f…ëƒëWo]Ó×nì]=xãùJ‡Û_ìbÝÛYv÷¿ÀöËþž;ª—´ ¹dR&îö×å¤"ê°-H¤u,þã•q4Ð@žz¬ŠD¢æ*`ÊDD€ª³èÏõÀ¿DhdJ@¤h€¨ŒDLÁ(%B„1Kਪ&LD¥€¨¡ˆ‡Ì¹/¬(ŒTaµŒ;ËeöÂj÷t¤H(†€è 7 ¦HŠ©ï‚›E”*5"``"^.{Ó ÈnÇ0ÉØ—xàŠƒ90rèy6§~ÞB¹w¼ž#h1•Z·*cÞ^w‹ûZ7*ãv1ë§o¼ñçs.)árÙÉVU%‹bŠìDιV)Yº>ª8u |ßwýÌ€˜ŽŽ6ªjдŒì®ˆ°ŒUÍj©Ì4Žâ·W).R 7pC"U³ÍvÜÙíUµ”BHÈþ(3û‚¯ä*¢¥hŸØ=zg|ÖæO.ÔÚçO‘û’0“Sœwæ+Q#¦qÌnlfHÈjŸyf{Ïòx+ꈰwŽ9Ž$™mœææî¡{þ;aDŸŠC õz€qÈy±hñ ËUÇL5‹š‰hˆq³=òŠã¡l4n$qr;ÿÔÌTK€’kÎOŸYi[xƒ{ìVáÀˆhÓ‚U¦ÿˆB\™¾“³bŠøØ/϶ù8aôˆmôö7ÚÕº.úòoëÊzœÜ¶ˆ€`RgR+pÚ¤hlþ¡òZ|rÊ„·µ™'M–zš«¤Ï1þÍço"bí•ÌH½Û…¹¾É{§.fÂ] DL!®B=ˆ‘b%fò.Ïûh± Ö `0Uñ/†Å‚ÉD®ݸ¼Ýãááøäº¾qýzè° Q‡®‹—î»°ãÆúÆs€$jˆfz´?Þ—=(2€B©"¢B‹ªÔF$@óÆŒ42‚(#(¹¥N–Ê Okþ“UW;ß!B®NRÓ\êz ¦€`! Ò ²Q].™€Ž6ÎaäÝn¹³{æÌ…´Ø-5#ZdŽ)L€@âÕ=°».õ}ËT­hlj‚mcÛ¬6ÎOž)ÀˆÇÉ ì¹Xì{Räfã$E=#$¯Qëè¶xãX=Z§V»ÿüßÍ9o·¶\v]¶[ÅIþX«ã\²Û¡©IõhI3$Œû>”bªÆ¤„hîa‚X6¢jLäYÖ<11Ølæ€Y©A>ÃVŽŽ¶)†¸ë‚¨–\  …JTS;8¨÷¤¾! ,¢3{f¶Ú™¨&®d¥XDBŠà~n!P)o·Ù‘DÀþÇÞ=í”qÜŠâ-ôšù Ô =³ž:Ei‡“gµ\v¥ˆªqð7´`Ê|VÂû?üob<î~žA­r¢‡:-9WÄ`ªþf-1Æ0[ ˜™Ìt%ïdÂñÊÒw2÷Ý·Œ!Q¨wxVˆøéÏœ…ŽNÐ%ýâÁ[øIt[VÇÔG·LÃù«ª–˜ÝÐí¢Õƒ*\€ë»øclmR—¢¯Y½JÖ¶¡kËÓ¹PÞF=9Ú·¬ÃÛøö'¾¹hžd98qÄûP_ÒµõíÌ Œ1M-Ò¼•›öu`ZÁt¹ZÂþÍûî¿÷k^ójƒÃÍþSQÙÈåç7–‡Õ2¼úõ÷í_Ûùè‡n^~ö˜ªÐ8 d€ e@ S@C+‚ ]G‚@C·T‡¹T¤T•Mí–!‡•Dmâ6ù›Ià“ªê„¸€Çˆ c@F­6ŽÕ ˜cGR- ŠÚÖr¤J˜©d`²ª ñÔn·ÚÙ[íœ[õ§wvÏ.ç²éº³}×õ}GÓö„ÚÛ @?)¼­S3A›_»™‰aãÄL>Ej%÷½çŽ8'Ój>Xv>qrû€ö—ó5Õ|xtt´DÔ¶£2ãj¹Ša¬U†!/ˆÎ=B×EDsÉ£{ž 2{6h[S0Sóñ‰ý³ÐÍ óÉ”þاü6–œê?Q®êHZ×E_ÂΉ~S#æ²c»Í¾ý:äo}ÙEW ÜÉY…ÈUò3ÏlïI‹“6tmÓB-)Þ ¶>È«3˜‘¦Jªíê3à€)–Æ“ó}£×zW= Âj®ïgWÊù&5­õ¸VÎ÷œch·oOö¤µÚÜä¶ÝèŒÔŸåýB35Ç23:1øaÎ:*þ­çDfÔHÆE¢A‡õf3ELÖ^«”1«‘©B•êƒ:¤B5(Å=Õ“‘}ééF¡à‘ˆ›ÚÊÛò€€& Ö˜¡ÉÆÑP•˜¸ÖPU i p´Uè:è;6Œb!ÆeŠË~±J±“2ZêzÉLÁdÑN'Ö|ñØb3S$RP@g²ºã½Ö#2JŒè| H‘¸#îØŒÛ˜?™ÞËf#u[ËzîLM…&€XÍ.\è}—"®7cÎÕ×~]ŠˆàpG©²Ýfè)VƒÝ#µ!>“íñDׂ)ΑˆbDÓ©^̎¶ií»bJÁùöu‚‡Ç±,—ÝD¢k›?páÙ<Š6Âc=îu\¼r¾;–c!TQé:šÝÔ‡!Çqs !ÅPĆüôáaÙíÂì?4_‚‡ž;°æ…i¶òñVÔá7¼æ‡9þ•Î ÖÓeo[O‡MSàmÍÉÆí6Š·w—è×!#y8JEW7[3©†ˆµªW™)‚É^ûð›Õ×ï_õ¬úÔü/þU  !$ò)¡²™5<—°FlS›ëMDߎ£Âlp3ãïs×¼¥ußEÈ8ˆ˜šèq‹:#oˆÜÔí_ÊÀUµùròEªÇ"Ý.ôÔ[3EOÆW!¢(ÔI'`–·£ä¢G›zpT×u̪*Œèk8廬3‰æƒññ9Xük¯~Í7}Ûôì êÎÎé¾ôë7 Œe<Û”½Õ©å¹ía}ö‰á´”œÓ’Ó‚k9PdR-eÜÖÐu1o·ÉLKV1„.¥Ðu|&©æ,C®nã˜@'ú¸Õ¹‘[62‚™‡¼ûþTÀ cˆLN7UML¬€¬Û†(‹ÖÚ>ù ësW1b܉]ßuqÑ-úÅbÙ‡Z²ãID¡e}b‹<„Iê¢ÉµOÕŽ' B%"0°fê‹G¿9ÇÇeˆ+ }ˆ‹´8»=/Þ‡€J–²)ù° û*Yµ¨Œn”7kµ ÷v~IÇÈRu 1æ }ŸJ©ãX ÆÐ÷1vxì8¦Ñ ÞjÖ÷±Á`ÞMy>¦PLLTçµ—Mêéy…í,U—ð'Ï×õû_DDZˆÆR}D]~ê§JôZªÚ¶ÉùûÄLŠLV¦¡ožÚQ. ±ˆ"rcͯÞo¨@lð_þø÷pVIù?'4ýÍòÆyÖkùöíù:|Ý×õeË_õ¬è×ë·c‹Ej¤Ë¹|7ª¢—Ι¦:ƒÔR«ªu)†ÈÎê0ôå£ Õ¬zú|céü¿”½û³mÙUß7^s®µöÞçœ{o?Õ­'êF X€ƒP( âiƒz L c’øñƒ«’Ê_à_œrå  ”È…í$!Û¢ŒeAÈ<ŒD?¤~÷½÷œ½×ZsŽ1òØk}o·ä+•ªëöí¾§÷™gï¹Æãûý|i€ÖêI6€žßÙYÉþá3M/n–WeÑ:4ˆ>ý22~Å/V)_¨ÊÌÔB«`K©Ó’øR¡ 9^U…ªÍ^×[Û×7l¶(‚ËëñM¤—CEoÙëcF—‰€BFDÅ:M¯Ï¤9µ1Á’GÏ 7ñC 8PÙ¦ê U©½þüžódu"š/nú§þ´˜ñaœTÁ5–ÃaÜŠãD3ø¨ÂÜõŽ–2ÝsõôüÆ~,¹c&òDTÀÌ­ÌÎnDÔg²n¼ëK@óXâ38C7”GÞ/ ÀT´K"Ž6N g§ÁR¦©(Œ³1 ƒ(ânÃ]'îÔånØl¶9oRÞ¤¼éºmßoÀâH€RëÜcœ¸\ÜÕ¬hJuaœg‹v™ˆÑÌ…E„‰Qɲt,}xê‘I8 Mö´îèM#n^ëa -nÕ#WÕAÍçb/»ÖÇÆ\„ ©”ZŠŸ›MEÄ®Oa>e!U+U»œb)í#ˆ@A•'Z5¡¡Ž$&5]ÉÑEº›U_àFL‘±ÂL„)Ç‚ÐrÎép˜ÍŒˆº.}æ3‡ˆš/ùwÖwÌ„}GIè0)@SÞþA€†V ¿- Ä]Nj–0lK1+çO~òæUÌÇ~ó¶!Œ6pQÅxÓ‘YTÕ«º»ç7ÿ€Æ çÎÏ ˆTç?ýÓóºa؆<6$“|$½þ^î;`¿Ÿ³Ùu)ç(<(ÎëçÝÁK©µ/³ï úTõ”ˆÂMçwtVµ–'Ÿ‡^¢…§#ÀçÏs?~Ý2Õ5_/Ws˜Vá“»·M½ú*C^Õ«Fb¡^ ÂV}>S@+±¸a‹­}©š1’–$¤Î·Y;š[y¹IcÒt|·bŒëçÒ^I^ˆÜbÈï>/07p-KœºJÀF{áÃÓ7ož<{}?¾pxŽÎ/¾øÕÈáÙÇ¿PÇyc¶“Ý QKå J2` "æ”ê\Ê\EÈ«½ðüõM×!Vuƒ â!šSÜ••À­ªUz¤`Т7œ«"’*Íb, µF„(6!R3ëz›g;”)[Cqp“ ÌL‚)³:}HÕ9çÝÕ«w ›+œ¶¹Ût]—%Çó¶”Y$5œ † ´’ƒÅ`„(|ܘ“$Aä” íÇøvÀ½CŒû(@½¤-qféYºØ·‡bû…jÙ›Õ:ÝÐrp-œ}§¹Wµ òžœH)ÅÜ„ĹT­U/.¦«W·¹K¥TS×¹`Ÿ ‡&¿Mó¼ABª™"}1*aó£ÅÖ7LJ+uÏ8ð#쀦ªæI˜ë’pWK•$}ŸêÅE=Ëi]æDÛžE¨ïš¤éa£ÎÒãõ‹kÄ©º$©ÕJÑ.'@@káª]§ë×Ë}Ò¯4¼µ¯?†N„X5houAX>UÇoû¶—唪ξü§ïð¬˜Ò¯ÿæÏ„¥•zì¸âíS‰—Á\Çj¨¥v]ê:a!DŒàèÀ6›YÈW`.Õs¦Ë1 º™_»–£ø»Ã³*u~öÙùe¹W˜¤­Î—mé%hq•|_G·,l ÛR¡–zvu¾Eàózòºä`i˜PÕ­iZ6ƒcKaAÇã9CüDnáVµP´ä@Gûµ„>ùÓ¤×f=æ) „¹£EFŒ:¸{„^@&tœA‘φž.ûixþɧñð̃Cõ®+O?ýÔùùùþbšG=\SbØ $¤ÄÌê¥Lª>)€Öö|Rƒ9,@Œ^cˆFÈMjsq3„,Žf>;ÄŒ1Bk‘ƒoL@팀’ÃI!?€jõ0.IÆÈP&³ƉRÆÄ’7©ï:DCîÒæÚ•{6›mλ~{µß^IÝ.u½¤N$×xpû 8¸Öºu¡Ö ‘ãe¸)˜—`Ø r+Ó\jÕê5Ö2‚”̬¸«ÖQËÈiü]ä5…OÔMµ^¢;YŸØ{ÕݶwvðÈŒŒ÷é8ͪ›ˆ·Œahx½§¹@ó7g!Áaœ#hˆaÙïªj}‘Ö-Äüöä&$bw"t³RêÞÝ»ŽÏoŽÓŒÈ""ä`ó\¹ëÒfÓ?öì?‰ÏdÄF ßbì+ÕæbñhÙœ‹Ú?Èg”¤ÖÜ¿p 1Sp7ú!OS™çÊLŒùßú—Ý–]ëz/Ľ…§-5ó5¶è³e|àáëþÒìÇ,ç;«¡4Ç€ƒ=éæÕ4\÷ZÎ?ö±gïOCŒ×R4öKñ„¶[9ÄH·DEÍ>ôIUUµV mLã—ħU`×Ѳ‘ŽÔ&8=w"ò;:+a¯Í˜ê3g¹…mÔJøé´6Wåæz±®iÈÆŽVâí‚kpÒeªÚ]q‡®«¢Ç2*.S¦¦|°ê±ô¶ýúÅWls›‡Æ.ÿø‘µðí='2»t_­ •PeÇ#ý|_§Ùö’K‚Ì)ÊWaqoŠ÷ªfÚ =÷ÄŸýìSÏž?í.¬»¹ìd{Z®4Ìn:×½Á0!zÈWšYìÌÚMkÙ‹‹C×I¼U$Iu?ÍSÑœ,¢'DZFA™„jÎéüüâÚ]§µÌû‹Ú÷bã8 }‡Ähîûý4 ©Víß_=ì‰'öŸúÔþúõĶVcfÁíV^÷º“‡zp—¾*%I©3óÏ|æ|W$fgÍÓña² Þϵ:Š E0à¢qÉ)MÓÌL¬ZX|´p|½H UcÖ~ôÙ+žW”ïêÉq‡)¨þ¥3JõÚ:J«Šàßß:ßïÇÃ4 9öZÓT¢×•Ä"ÜuéæÍÃéÙ¶§Ò÷Ù̦¹î6»üêO¯Ó؆"¾•f„„^ýÅéë­š3£†4MÍÜ€y‰FÄý~B€~“S"óK,€ªž¦œdšËœ•YË;žŠ.HQ䣄ŽwÝk½^MQÛ™®eLÓä7VH[Š6-}$÷DˆÀú<‹¦> àÑ@ÌÅZ ˜zDWµX€áÖ@ã´ÄmÝ)Þ^ö«z—?uýcñ¶x)ÖÀfÓ™5#;¨ÎP;ŒªêI°ër’ÞÁwÄÛÔæù’x~v|ò™'íÙë®EÕ„Óf˾éÁëxHeÞ×RÊ4™×$ ¡#¹‹Öª^\«%7H4£†wÇ{nµcb„RÝ Ì‚Jcó¢• E§±‚ƒ$"5[Œ±c%H2SÊÝfèR?qΩï7,i—7Hyw²;=»k³===½²ÙnONÏúÍ–9÷›~·=ADcb"RãA7ÍVŠ C×%‘>„b1n»y>ö=§$.0S–Œ€Ä€#p NáSB¤¨IÀ´¬w¨Õ±ÍF[½@-{××ñm¼i* %Þåó\Ý=%é‡|8Lñ ék™k©J„YÒ?ûŸyì±}k0•b/ÞÛ­ï7{Q‡Ù¨såʈaµ_…%ß*\¼üÛÇžýð‡Ÿø½aàøÿsÏÍ»NŽ™«½º‰Õc\³¶6ŠSdÒ­а·šGSBl-¶@ ^x¡ìr›Ž^Ú‡¢Ú]InU/ûʹØ3eþÑÿêuªŽà e4¹L0 %Vµœ% Ô!›1µív÷ÌÿÑ]¿Wúˆ`‚”VC ¹•Ü?—ç{žkÎ lˆÌ¼˜…‹L«•R@’˜Y4õkX©9ˆ !gU—«Ï(%RõÄÍâ]¦ZmU ½U —Ú¡µ¾n]65¾bë«ÅeÕä<Ë_j.¶Z ¹•æb9‘PóD£mŽÅOm[ÝtT0ßÖÅ3@ĬX³•'Ó\³ãMTˆªê4ëò¯E±D¾ÛíÀë\æýaVCj+†õâæ«¿è•óôÜú¹}yݧ±h+-ñc¡;ÕR¦iž›/¸„Æb+dÀnÕ‰€€„A À4f €¡ª åµè%äXÍ›)!tÅØLµZ"ƒØ³Vu-†D}'"bT(qJÃvw2lv±á€~ئÔõ›ÝvsrvõžÓ³«W¯Ýszvíôì ¢u¹Ë]ç^§Éc4àˆÖ÷Ãvƒ¥LÓTÏ/fDL‚}/Dùìt·j)EÍâç’Ü­ºWÄU¯åP§,ƒ¥QË…¥ÁêÖO­Skêµ”ù<¢Ù›¬¸¬}&ªEç©0S„YH˜ç©Ncé‡ÌLÕ4š»°K½jØô·Ëq¸t×Åvn%MÔjѦّép¼¯ì6±|™»BmƒD8ÜÔÃsz–ÒvË]Ç9QT¡=:•ê²~‰‚0†@·]»Ø‡ ÑLMÝ Ñ4Ø+–RÒº¿¸¨§YZUÈ-W..͸@Õ :ʨ†öc}Ʀw¾ó/»ò×ÇyL‰ƒð¶¢âk_dšJÎÊ·”ØÌØíð¿ÿäïžB •å ^Ywôíc«vkVð²"¶FZ·Çª-µ1¾ßX„®1w©±âÖý*ÚläÎÏŠ·ÞQØÆ¸ÀÔ@–Ñæ :¶*,êÑK‡ûš› íNl8›bëZÔ#]1®¯ÐHTµRLmá9!B1‘Øã%¬Õs:¢).*޵‹¿Mg*¬[·þ/ž‡›ÕÖ ´ÉK„Ú4×Võ?@ןänÝ ªi©UÍýâüœS’ÝV0ð—÷^»ûâÿè©Çž8=9½ví®ç®LûRÔÕk©Z ˜"ÏE«Vu0CÅ£•jÕЄ)å„dˆJˆŒ¬æV«V‹ÏdÈ®DDKÕ)¥0ˆš›14e­Ê¼œØǹ¨VBJ™@K-¦^!%Ì̉1Qaæ®O]Ÿd6Û®Ûˆ³°`ÊÃnszzõÍv{×Ý×NNv]OB•ErÇDÈršr½ B·RkUƒÃá€9Éf“ NÌÝæé0ÏÛù.Óf³kzÒÑÙaE×RͬjµNTµ8mbËhõÝŠÕÑtC},90ÞI»“®“Ó¨¯BÉ‚ÍücnËz@^mÑaž‹©µÈ‡õní2­w¥;@ºå¢„åAÞ$„|‹Æ¹,òO&;&˜u™Ô€"Ð Ç.±ÄØ(Ç‚Åσpáè‚@Ì‹HÀ…)' s'·ÂÛ›kj`×;:+wŸ´-f/ó¢Aù‹•¤/žçÞÖM_šŽîb @㽿@øVËÒݯ Æ–ÅàÒ®ÔH4‹iç‹°ÍÔd Ë¢ŒPLK¤¯›b§¹F.]‰#bÌõr÷‡f+ y3AµÌCjA‘~—ÜTg÷`èչ̦>dyø•¯yî…§Ÿzþéq¼Ñ1v›!;wÖñ{S%Ÿ‘ „+®Vf`#BÈìU½– ´$Õ)¥žBviÕJ5FJ)\1ÅÂ#è`FÄfæ`\µªgɹs7á™ ¡Njß5h—7C×§Ô K'½ô݆%™§Ôõý°=†ÝnwrõÚµ«wÝ; ÛÍvÓu¹ëz‡ŠöÙ¬NóŒ"H„ÄÝf;€»ÙŽ[3«õPª§D]×:¥¼É€ÇÞ( [5«@L$S èìVU'¶j:™'î›?H'«c,ô­NÑC˜Ns±¢^«‡ìQ«07ÇWCæ ª‘»ë\¢ ÛX”3ggòÔãS({ã¦çãPɘUE)ºþm\‚ÇQ91û_?3¡œvü‹ xû€eˆÏI©6Ív¾¯°d­js"<šy‰`JTÕy¹[MÉ´ÎS=æ fÄpl·=!ŽSQUfyâ‰C×µ°&˜‹M“Ú‚IÏj­þ,L]Ïý›øÒW}ï8M¦°ž•¯Ò}¦uß h(‰£Ÿ‘§®ô}?ýoÖ;Œ#¶¹Ø8Û§÷×®e3ß_¯I’šgŒ†ÂhˆØVÛj-@¸V›¦2—RæZKáͶ=`æRê4–Rj×-ºiF$,Ë-ѬJîµú“udÆ/ÿò³oÿ†÷ˆäižÌ€Ï –°6XÒß<âʈjQ —?úó_ú…_ø‹Œø²<¬aÄ”ñrGOmZJëÂãH4ê— kÂÈ ¥Ä$íå:ßs—¼ú5ÿ‡O}òîe‡ýps>æ®öû¾ÌSJ=ñEûy>Ô¹TRÄ®j«Ü1³WLIØ [ƒäŽÀ)!#{d1P؃™&pâÌñÄœ9±b –+R’Ä]7Ô¾€Yî6)I—‡ÔuV­ßlR8§äàÃf»Ùnûa“R—ò°=¹ÖýÐ÷›Ý&Iê2›Îæ¶Ñ]tllËLà%æÝyùI!“iloÀ#ôP`l.^j‚» k€“ª/Yö5¼ó‹7;ž‚§ÈltÓ>Å„a•Ž3‚Ïs%˜ƒ¤jÓŒK§­–½UÜ}šk?Ðkün€k¶ñEóïˡ貭‹£ÛÁ›)^«˜xð qÐ DÚ'í0YÛV³•jûC}t:¼þõ§oyó{~âý?±‘K«I|¢bèJ $”j p8Lç7÷HÈL»~Ó÷)%‰•‡"‰OóÆÍe{måh­´õ:ü’/9ýÎo~צߚû›W×ñFîØ;[Òò%ƒ¦L7ãÆ\ Ô5.ñ˜í´òþŽ•¤Í‡~¤ÆÝÖžæl˜Aw@N„\ÊXë AgŽ/ë—Ý{ßsÏ>zýæÔo:$Îiž§I8ãê´;ÇÃá0ÕRK)ZJ)»™`jŽ]–„L„ŒänˆàjfuÉûŽÄ˜¸³¦DE›]»M%%¹8?”Rï»÷J×I™å–Ÿáå 8+4ÞídÉd¸D­+&~©zð¸»_ð.¶Ž¢ê< ­ÞÙà9­*£Ï–~àݯúÒW½k*s­ú™ÏŒ÷o{:1_f™Ü ÇZç /žÞÊ‹§»!­G„œ8 9«g. %ÌÈQ“†ûÃìr7ô²lâÛ¹˜Øìà©ësXBÃ$NÞ8;Ù¾úUÿñŸü’V@ˆ…˜k·íº-80u9«™Õ¹ÔZÍü º§CŒY‘­9ÝUk)`.LI2³' †¸™[Éý¡fæiê&î7§ªJ,žû¡Ì‰;Úu¹s`¦ÝÐk,ßSÊHxzrÆ’EºÜu"üðî_=ñôF… Õ@üö|PøhÜV¯ÿµ ]¡ë&<$ejP–ú´ªïúTßð†+oy󻈺ç_¸>Íu»~û·Ÿ»†y Ñ;²ð®OÜ[ ¢ŸKð ˆ´úQkµ! =i0-1ûŽ*-‹{^|`}ßÀÛÓ:A› S×eDt+ˆh±üöâVÜÔÔ %J,ænªŽÈDnuèåî«÷«NˆÒ%Ûm¼¦rØï÷û)åM—:D§q<RNÓþbž†µTӺߟ/é®jfLB«OÄ)G`‹H­eAÎ)‰0s×›”òxØ3'‘œûÞRJˆÜ¬sÌœsçîÄÜå~{rš$±ˆˆ°äœ;éû$a¢œ³ÄwCôZç2Ž@èÌ$) é\«ö}B$·½ƒ¹›•Áݽ¨ SÎìŽjÕ˜ÄMÝkÓK/óx$L’n©¿9dÕ—·$î¿@4ÈÄ<ÔrÀ¶’ ˃# À5Î4é.¥'Ÿ_}Ä:%Ž˜ $œ/JQTÆH”“`F&6Ý×¼þí¿ñ?V/‰;‹ÕŪ(@:¢ä¤îÆÒ!2I¯õw}Pûbëåf-3Ê<ʸLcV0»8è§÷¯{ÝÉwË#jªµ$Nþ­Ÿ1h|/¡$íåD+éjåÞ S8ÇÝ\r`É/ºÝ`Úš 1‚_Ý|õ›ÞøU) ¸Û<ïÝÛ'å ;«¡úLBeª€øûöÞ8öoí tT{FZѺs[µ q™y›¯ñÔ«üþ¶**36†'áR51™B¸¢¦qŽÛVÕ•Z~¢ª›U" néç?+"r°¿òoýÿâ'××°‚8Ì]œcï‰ìGJ{ó¸Ù²œÔ[›÷•ç´jžâ×s±gm;ýÛîÿÚ7~Ÿªk-ÓTäÿá—§ÉîîyÍ£¤Ë±êvIFh7û*xz‘h,Ÿl7Ï­o£ÜmÜ*’pKX‹‘°w rß·ve`©;C|Žh´æ]õ¾£”:€†%bFw$7Cp«µÖÃXˆPæYÕ"€ÛÝéÙ|(WU3›çaD§”{pD>Œ{I)lOæùÐ%Äyoªæ~¤îÔ‰ *`"w ª»j=¸ÖxÍàY&mŸV5pS5Î󝹨£ó~šìmo{ð•÷|wÕ˜3ÿøÇ_x iYú·¤3&aœÖðÞ¥¯¯j"Xª Ã(n™0B)Ú&ìLDXŠ"‚YA¯G qüâÎÏêp˜`»ë«š«ŸœÈºiГ£È6-ÀõV£‘´kÎШ=’_ÔÔƒz\LAåã+Zqu# âœ9¸‹05Ú"á©ÿïýW¿óÎϪËÛ³³¤/Õ¢Œ‹8€ ÎÅ0 v÷cªHžˆPj35ø‘Uiíë?3ñøûß—ùA³9L·ÛÝ€€¿ñsO]Ãsä6$Y´·-šô(ùX4z{íŒ (/.òœB¿K1&céãƒtÔÒåßRûãHÌ„k˜Ÿ,ÎØ@á¹W$A¤c‘ ³V-àŠè"ÀŽOàíöš—2—:ƒc:‘Ò7°¹ª#QÎiè{@`·SaFD­µj­eV-Z+8 SN›Aˆ€[Ú"#¡–'ÖovAxr/à÷”º”óeޱ¤$’D$ò_´jî:D6Ó”º®rîEZ®'‹dNÂ$’Â_Ua ûœÐIsŠ7sœODÑ­u«ˆŒDHÛÔT+ku«ˆÎ a˜çRkdþp'r‡f.^ÂÃ’ç¦ÕêäRÁÍêd2ƒ"‚®­½jm9 Ñû3÷Æ3k‰Ò&~¾Ï>3¢WÓHÄ)¶ÄÄ#ƺ)$alÉ]:ì§Ãa~è¡Ý³M[“˜ Mźl5!µé:’`“ h¼O\k­{oI¥EÍÇI«zkç'-ês±Zýæ¾>6í¯]ËÿÍÿM¢t±ß " ¥ßùÄÏ©z×G‚m‰,[Í2EiöDs3ØnYLMÉ"ï~Í׌ƒå¦°¶°–¤¢æÌ±ìjêŽa½ó³Úï'b*U‰éµ¼óî»ÿ§Ïk==ݬ@åuréþ¿gï*ÜéY §¿úŸ\ûõ=ù1âÔ›mnWõ$¤Eƒ)cMt©¥_wñMáTÃ1ÐÈùñy²Œ¯|åæßùH—úÃa*.@èºüÔ ÿòùçç—›Á¸XÐ5Ev¯û#:zŒÝ2MyGóûbîZGD"Îa]þQ·JD1Z0’‘R>‰©ÖY®»Íá…›óaT’ÎÝУsÓ €ŒJ$d-)#¦áx²ºCîÈSNx÷ªµïæi*Ä…J‡øbÕ¢áðAJ"Ó4j­aópÓ¹ÌZ«ˆäÔ@­s4㈠’Œ…IB;*’BY9M³: ]'Ò²C„ ‹t$‚€ÌTµ"RJ=8¤œ$%Idz Bµ'K€bõ%à ÑÝÓ¦=¢—BôÎm,Œb+hVÀJläÝ!L–ñŽD’Àúf´P˺: ó¿š*0·`A"kâAÎfu²Tb™ oŽ£¢uôeŠº~à¼i ‡ž?ýÌž‚‰êó)ñˆN“"ºÃÍ£@‹¯3•ò–7¿ýÇþ÷Ý?˜ÎÅ£š ºéˆžˆÜÀ©MYjÔï¦%,î:ϵ.7f Ž*¶n“¦ÉÞò–û¾â¡w“jnßšƒ}ìcÏÝ/}ô¼±}ý¦Ä`l‡ÂïÒW: ÂLîXKE¦È• âd»>„C± ÷5:Ñ£ÿ öP„¾ ³ªÕjÕ”$ ›Û#ïù‘ú¡÷ÿÁ\¿»v›ƒØ¨¶ºceM¦@µ‚D×_ëåRû¨R„cù="Æjà) }f¡Ð?Ij{ÕËr,ÞWƒðŸÿù¾™kïð¬Ìê_yÃ;ýCÿsUOÒÜý¨6—0€ú-q/ªkÊ®m?©µöŒ}ý1þî3ó¾õ[ïÓW¿ÇÝÇq$¢$Ò¸Cæ¿òÁOôÄëHd•74º ÓeЏòO?á^T§¥ZL®±ögéÍŠ»kK#äIRÞ¥uÒ::T¿L‹Et@¢ä(ˬ <"àfêaªp$6fbN‰!;uý¶ÌS­eL‡¾–Z5†2D›‡ÚBü(ç®ï‹jM’ªSsp-³¹21µY1¶Ç·F&å!R‹%9"Î¥ÔZE—"!Nyè… £êŽp÷”ClBÄD7x³ë¥KóE³Ń¥¨7cþ¾ÌŽÚšty܉7w¼5~]ôçnÞ¸ HdÌÈœ$eD ïftPîæ0Epmë`.–ë‰M§‡µh§¢¹Õ=qGÒ›ND©iøE’èDélf ñI%sU#¢ª–Ó%ÁÁcÝâj¬ÖMíôT-û‡ònšTé }öœM‘´ÂMNh,6C;3PˆµÒaÒ§ÊøÜyyè¡Ý[¿õ¿p#µ èî´sÇ'nÞ¬÷öa1ŠüáVe0Ís­Õ«z$„¯oò®£ªµª: `«û†Ôào¸_#ÆœÄ̘™™Ô¼”¾ò͆-:Ó;?+3a†\«–Rº.½ý;yè¡|ðƒÓ^–64Ã2€²DÎb3Ç ‘t*—ÊÊÛ YvôûLlDrBb& œ‹ªš·Pk3ËyÈ™æb̘…Â7ñè£û¹ŒÀv§g•»íßxõ÷~ïùx@¤ZÛÕ±ºÈha³ƒú×:t}à­CÒÕk;{F§ûîëÿëG~Dd[뤵FŠA­Š„"RÊøè£ûûsËÆÓd¬(EW ÙqËçŠOÓr+S2jÔÁÝ‘8»©¤í²yhëÔuÁŠHnZ¦ë¦Vª³ÍÅ´\¬¥+`¨u}êÆˆ$¾"Gd„˜x¤E°pO[á\k!Õj1 q\‡R-YPH‘S…¹”—÷¥sww"‰|½¸Ë˜±M»×=`dp’Ä„„”k-Ìì¦"‚„k#"l>S¤‹"²¤Uý¸êmݵjEt$)u^Ò›i©õ<–ì²kª¤¥l·ZÕÁÀZÍ«:a”3«ê…JÇ +ÂÊwTµR­L7â½MÒ#rêNàpþ$‘çhAÂÅDÜ9³"²1-9••ÿÆŒ¿û‡¿øU¯7 ªGø¹û\´AéM½)ó˜éæ=1å^~äÿæ?ü_~\Wƒi6÷Z+ƒQXéˆ2Û¹è\‰§ª…¡n](“ýÙùy×Ñ#ï~ÏÕ«÷Ôic“SJ ›|×u¿ø«ÿ¬K4ô!%ŒýÒ¦—y®‡©V×êf1k±;4Á?Âê$·%‰(%Þï'ÌLBLfŽ’" 0‡™Kb(E#ù :«~Èñoš9¡ã_ÿý_öÐÍôã?ñ™ýáþ4„ð‹ s¢qV&LND.@^ÔLU/IÆD8—v y øÔCyÀj–’0S­êèµjJœZ¤šÙvÛÝ<÷ûéž{6»Àu82Ôüñ_|ðõ¯y§yý|gÅ(Ìj¡9¬ßóí|üãÿ0üK†HU =&ñ =ò_ï”VøËÊm*ÕžÖ©ëè?ÿîW¾þ‹Þ¡îµŒ!€ µ¹ 0’üÊÿý^Ì ôö-D„/¥øÇ”ÛêÐàó!¡,m;HqÆl´Ñ׉»eT®…¤m K×oîUx>¿°?4f{d„ÄP9õG~÷ M`[F(&‚Gi LµªZk­µÆìI„ÝRêÀKëšKÕNKLˆÀC8)kåe¦ˆän"»EPs€¢Xæ~ ÷CiÎ}ß]ANZFDvD÷‚‘sŽˆ’À‘ˆ#/>J(°5Ë28ê^ܼ‰U]ÁÑÁ/eÏ—OÛvr«ŸAcÑʤ@#È •½±|¶Ñ‘ÜLUU] ÆÙ¦Ùvo<1"ÍãóëO¶aÚ fNCnªNfEut+³‹øšÍöãá+¾Øæ¹Ö¢Öîqz ¤l+Ê©eó֪Ĕ×¹$Ù~ã7Þû‘<ýåwÅ~–÷£FW%BÊÇ=£šGÛÁdªMÒôã¾Vÿú¯¿û+~{× ø<Ï5¶Ôª°Î®ïê\?ûÙñÝp¬}޵IüF)Æ·TDj|ȼ";§Þ"’ B_Á±Ë¢fˆðÔŇÞûÞ?yÓ›îú¦¯ûf®K³¹®¥.w럕V‹ÍL×%­fÕÔI6ÿoÿ{ïÿúØg÷÷ç>'r'kz€[| ¨œ<°Qˆ˜æRÍÛ,2Š»a`bÉdZ)™V¦HyH‰¢ u&º¸£îv²AKÚ{¥ÿ×ÿú™/û"4ý|g `ê^«ºÑÛßþò|àÑpˆ¼xµK¥Ô— R­öÓcG\,lŸ± ¾õ[îû«oü~B4P ;©:R £ÖªŸøÄõ{¥£…9ÛTŒÑ²4šâ(øÜ¤ÖËÌ!’¶yç†bkZ™¶œJ°Øä0ј8¯Âi×b¹úlÄÉ}RânÉXsH£‚B_Ô²^¶ô!÷ê"W@'r5rg&ËÑZ 3Ä.™MKU'´x­ Ñ6_NëDÜ`g"¸?B N]´ý¦aÆô”)w9DÖoŠ$t53õyž‘£w‡%°Z´Zd“ÅŠ™š)!²¥ä6SÜηŸ˜!‘¯I‰ ËÚ¨XÀ” R ô²®ê¹5„§9ì=J22wuº±®qHz0sJ«Óê <«Ó¢Ü$nc¶gŸ‡›HCC`D{¢Cð†¶ YŸ»×Z[¶—/}Í;æùý賟íT9¢““Æš—n.Ê–óQ//Ðy¶7}Ý]oøâ· q¿7¯jq2¥DׯQp}äw~ºŽ×ÈVª6xÝ\ì0Ö²|, ÑT«ZJTªb„Ô—Úv”¸‰SG“Äe_Íñjÿ ˆò[¿õìG>ò?~ñûïùŽïÏÒ;€Zõ¶€¶/ô¬`šf‡ s‡:§œþÎüÝþ??ù±=wŸõ95“ªÕ%l. :A5$ îZ“¯Û"027ƒÍ†Ð2ˆ¯¾û%_º E(g©¥œœ¤ëµD.gÓ‡exôѽcE$Õú¹ÎJÕ˜©ª»™Ò—¼ê]ßôMïÿЇž¼¯ö]¦xÙñß­à¸x#q¡`㲎/P3øª¯ºú×þ³Dઅb M¸Ø¬#Ö‚\õçOþr3㪴¿lÛc²|\r¦—B߇?€w’¶€H”¢^#N_Žd¤d:»;Á")mçwcxеhWóÙ"ÇSoÕVüœ‚n®nMꈀµ*¸£°#º5…€›VÈ)#ÑV„($Ò*¸%î"nR”ãÇ 2Í_€Sì¦JÈ,Ćm <¢ôv[+hÉ=gw­eT‘“YÐ&H„8‹ªÇËMMuVuwff‘¶é\¬²ËöŒã×"ÆÐýÛåKžX UŽ\=  x|þP«š+Š8âB°¨ÅÌL„Y$Åðv±?‚›ê6©€ ‚»iA$³²”¥µLPCd¢Šm6 ]¢ÝNþé‡>ð]ßòCÂá©§V¼,»³(ͼºOÓŒˆ¥Ôóóƒªå.}í_z÷ë~ìý?ÿkõ‡NvAôˆÍOˆ«Ã /0f j~ã¢|z¿Ï™¾áîùÊ×½kžj©Å¼ uãÈD"]…÷‘¿â楪6T„K­‘¤S«ææz ¢““¡VZÙõk_/‚¿úk?ý]oyÄL?ÏY•ªKè)"‚A}ó×¼ûÁ?ø¾÷}*9Þ]º`V…’è28þxÅ´êí?[ÆÃA_÷º“÷|ïuÝvœö„†îH Ü퉂Â]Õ˜ùÃ~êf"ˆÚ³òbŠhJÄÏ'l¸­»'„¦Xj™ºVsw®¦8ñ%,¼m†ŽSy VŒqB$aJÜd’pGdo§6ª«jnž°ÏÚ–3±Y¡R! X×§0Ì x4ëá2¡14Ó¸ú£¸›ƒ³jíåHBÆn!½ Qz¬W[ì3¶È#h?­ îD<À\º[­R¤ŽÅ]UÁÜju­î®Dà@HnHL”½Á“ˆXµº7¸·Ë5íníÄâÇ´D²¸WKV×s÷y6D¤ÜN,ZqRˆ‘¢è­Kw¬¶'û+ólÁÜùèÓ0Ûm¤ëXºªmŽ[Ô‰MxçA$BDFS«jàÍ’TUss,¥DyÒwtOéJ—ž~zúÿè'ï¿¿ÿwþ@×m¼ hð =+"ú¬ªÀo-U¿ôÕïøïÿÞùOýìûîp¯tKër™î£Rr$‘ÛaEKp ÌÅ®ôI×ýwˆžΞZì:X¬g£f¹z5—ÀQÙÝ+ýïüÎsßùÍcp„_ò¬XØÍR .Tµp-¿âî·þwïð³¿ôþÇ?l˜ÏJ¦Ph.‹?F:™ÁE©Ï•ùÁ‡wüµw!&wr›ûœŽÏ*.+‹_äôZ)±\¢[£ãC`<œÿþo-–Ý\¦‹§ËxÓL6Cþf˜[VébËħ«ÝG1@b–¸ú™(9 …lQQ8¸ÎµÎ³-¬¸ ‘E€–TXDjqꮈÆ‹µf‚VcE Æ›Rfwcjëïõ Nœk6®¢Šxo"a‚èñ½6ÖI؃P˜Ýmž ²Æ¢L#t6X¼½Æ ´'.`ð'aıÄÄÍLÑȹ€”É[œœ‡ø3âé#‘Å „‘e‘2ßvb ‘‰ãy@ÍÊåÚ¼¼ÄœE'Á2„ûr6¡|"J« …XRwpSÕK¥vÿê¯ýü{Þö£j¥®H²#‰wU›æ2Žóùùáìls÷ݧ0ϵV}á…s3?9ݼúþ·ý·tÓ´ÿ·¿ÿßýÝç÷{ÁÛRwÎÎÒ×ýÝ_ñð;rî¦y<¦•öèñ0§$‘œbùÿ[{×`˶«ö…{‡ùÞ÷è­ŠoÖü¸¤ê<—ãqÙï‡'?ç1ï g6³{÷.ù>Ž“ (1½á›¿ÿußTT Öe·ˆ‘%¥€Š@©Ëáp¿q÷¼Ñvh/òÓݱ̀6 ¹ÖåÙgç?4íhcwV«Ý½¨‡Y]4yq¨05ŸÓ>à#î–¥Vu¶ø=Ù†QDBF,U8qJûœÃQ0'òÛOÍ^Ž»Bú©O]þçï~Ë·Üú¾ïùáÄIMÁSÇ¿ú³"§vƒ—ž²T×­gù»ÿƒ|õ«úïüÔ ¼Ìv)­\¨¾V*¦Îy HTú´ ÷S}úéónó„J+J¬YD1sþ'F‚ýž_Àå¼Ùqì&¶˜Á“:}êS—ûÔO|ýSNµ<ଘ<%E(žƒ~‘Z)Eæ¼ÿóæ¿üþÿX>ú;?ù¾÷}埸°á\ó]*f3¾îu·ÿØk¿ûæÙÙOܦ˽Ãï{V6M#æaüÀžóW÷%0sÃÜèÁÕÌ3‰º6_b¹„Í¡-¹`É̴Έäq'ØópWí—5cö* 7|ÏõhR«¦IÊUjô™= TÒs<„k©Á2Q‘J”ÀÌ{OtvºVu{z߀Çk +¢Á©§Í=`¿‰³Ë qþ.Ð^[7Ú|LDªcÒDÉ¡ mß!l’‘B©‰Àmsz GS\»1t>LY}fqbDÖûSÏj‹‘ZŠXÛV'~®'&jê^^·ˆUÑ¥ÀHÕ ©ó¼û4†°Ý”ÒH&Udv[qŸk‰)±N›Ú]zç¿úçù/þ×ÎX^æêñ„h€¢êŽ¿OeXö¼uP0ªÎô±2Ñåa‡4 Ó0м(!ge&`ˆ˜¬;e¬`ýèÝÿá£ÿÓŸü“w¾ëÍÿùáx4•?ØY¹!©Ÿ•óóŸ~å÷ý÷³þ/ÿèG>÷âᎌC&3` Å}8F9YUíÊʾîeÑDu7~³gæ*2ŽYD/.<󙜘q~sy,¯xüOüãî_§ nN ï¤éïøä÷ß³Y½~VÌ$6¥H …ꮄ‹Ò·~Ó_ø¶§//îþúoþŒ(ßú¶Ö|ÿÞáÞýËÝ~¤L‡{‡¯ò¬†!™Ôå _8¾l˜6j%ì‚Z·&ip'nÍí¯+—kµÙþþÓ* qæ¼ã4æéœ(çé6"µfˆLì z‡ ÁíÚœÔ`aQfry9ÿ‘o}KÀ,Hq“›wyì&’þ–z¼¨jˆgˆax%˜°2Ú~;±ÝÇa_ÔqÊ)ï¼Ót ¡ÙX‘¥Ju#Ql"™Zf©Eµ¨i`¬„ž‰äú"¿i}ËÒ3'oýˆRøz„îÝB¹y1©ˆ P•6Ä›MøöªÀZI½%ð›Õ{p§Ð‡ ($ZOLÕÉ L°¸Ì­»‹vM3âûÞý“7ÏÒ8Ð8òÍ}švçÃî‘<Þä¼ã¼Gb0å´ã´ [¸!ä¨ÅffJP7*jDx;Ÿ|îòXŸùú?üïÔZ[ÀÅű)‹â“O=r¸˜1‘!êÛ`¸¸œ‡œJ•e.——³T=S»u¾Ó 4r-r8,ØÛM̓*9yô&͇2ën `3 ‘šþ«Ÿ}Ï8îwœS”Ñ!Ó4ònâûôò'oßH7vœ]%jµ‡3îìéWÛ8òñ°ä!™j)2—i7ÌÇÅ?b'TÆNYñCù7åž„cHÎäöfÔ2Ð÷È;àü΋üðûßô†og‰Ñ̾¦³2»u¾«µ"â¿ÿï¾ùùû¿ù[Ÿº7w ßCž¸é¡Í΄ïöò—PÿÄ“OQ‘6¬¢¾Ô0ƒ!'§{Ó4 õ…ßó+¸5d¦ÖÐqpí™ñžÔ~ìß¾ñ;þØ29=«ª}¾Ì¥³v»!ü‹1èãPkM<¾üÎk_õòoê‰o=\–e^æyA´?ÀY=òÈ­÷}øÿøýÛÃàbYoHSB&bÆ!s·ÑBÄë­¨]õfÝXüB"†Ý#±&n+)œ½ÞQT–æ›´§äõ´·Q¥8 Œ(ÍÙˆ|ƒÜÓÓbÞD"ÊH¢*ó¢ˆ0HZBÆh-T,òf×MQûÄ䈘¼ ¸†‘‰úž¾‘^‘1°Û¿ûNPTKñv‡4 a£O9%Ó³ÜqÝ:ˆÈ€jâµÕ‹™ (‘¬¶˜ÝãÆË††QKDlRÕ¬Và‰€ƒŠ-/À @É­w€‡Ä z˜5³q`Äâ”) ^F»ÝUa.9d:ÛqžÎóxËhÝ.9#%N“Ô£?Í„xðÁ°g€ÝH ÀrcŸî_V3ø£·Ï?øÁçïÜyÇÓ¯ü>aÂRDDŽÇâÅn·‘(É,KhPÐsÓrâ‹ËùxX˜ÉÍR¦ËËùþýcNŒ÷îüÎôy\Êì"p퀛ãX ÔŒU¨š˜‰h†®+U3dB£ðdzYž>ÿÜáGßù¿ÿ…?óŸíÏ&©u{V0`r6£”ˆ†d‰YÕ–¹@Î µ(’â<Ï"r8Ì_ËY]\\¼ûÝϺ‰·™Ž‡ºd¾‘°SîOÑäm:… ÅÖÅÎμ¡4ÄCçÏÇm‰H8§);ʧÑ5û´ºêû—´b"Ñœ°(î{æCÛM š ¸}}8:7|À!ÎhµÐL)Ü|}]Je2Á“}ZÏ(í=Ñ0Ži\õÞÆäV¦ÕqL Ly4‘bVÛ³™póéÖ¬©‰ÔÅOšeò¿¢º¤ÝÖ™@ &…„è(Dœ˜j;±ïÄ)P¦íâ¶™ºd*@ñ v˜ËÛsüøXûâsÏ-_wó,M-~‡zŸèyCu¢9êC¸ø$rô.ŒóŽx$9ï[½k©gR)™™Ê"u®Ë}Sïò(œœ¼Øz÷zG!Þd!±™‰,îT8Üúg3-¦ÂIcÂm¹[þÊÑ`RS©Çã|<ê¼h©VkERÞqš˜Gæ(!P{3èïVu ÀdQÒ*¨4Nmó²r‚¦·¯œˆ¸•rg9óT­fÕT Œú>ÍLˆbrü(L`¦5ˆh ÷ûH¦ëo²= 1bÚyŠ{Ü!ø‰¢kÕ}ð¼Îb´ññÆý#Ú™i9.ó‹Ëñ…åø¼ÊR— ÕºÂ2Rzܲ‘ÅüH8dÊ™Î&~Íí›ï~÷³üè;Æq8÷—œçòÄ[”ÓåålMµí‹5Æ’»ÄØûvè0"ÜMC­òüó¥HJ\J=æ_¼xá…û/¾xq÷îÅ‹/\Ü»w8KYê²ÔýnÆÌÌ>dægž¹÷x=h‹©±}´ç¼SY¤Ö0»\Cßóºu+ïögœèþ½c-òØcç7oîZ\.›ÚÝv1>h{å+÷Cõô\mýzîx‚«Q]}x¶K¯Øí_|±üÈÛô—~åÇ祾ì©ÇiÈ_ëY1Ë ñÏþ'o}ë+žƒå³ÇÃEÜ* ó,]¯ew¹¼îu·s‹±òö\Hè:=Ÿm,”†è”{ê©é¸ˆF`pÐ:˜032ãé©a÷ÉO^üýò÷†ÌÃ0R›“uDLÎ~U§(ÄÚ£‰Vþ¿ZJ|y˜¿Æë*qþøgašVÒáµÒ”± ¿.¢ï™Ç#?ñßø«ßã&ÄRFJHäþxäáþ³{ÐêÞ‚îL &DJÌcNCw9;E  !' P #䦦ïè„g´ÕmZO Ì¥ú=/D¤Öê+&r .–YÛz1„Š}¨wbâ»áÇnìsΘ3¹Qh›G2Æ“£áë>G´Ãš F3!4ïŽÝuŒÏ9ÿ›gžxæ‘óo…»÷Žcæ;/{d9.®Û ÷nQ@LÌ‘9¸ RŒìnÕe©ççûœÓá0{Tï2@—9SJ< Ã~?îv#39"vçÎ-w†0Néó/üÌoüÆ‹OìÆqà!SJ¡£÷]SJDœµÎÝ3¿{¹ååű¾üvO=öÍÌtÿ⨢OܹmjÇãÒËIJì4Òy©¾ê=ßÿ‘÷üʯÝàœ¥D»É¹+0fŽÐ¤ÖÚPCÜnP•ûs÷žùí¼ê>wk÷æä™ï_ÓY1ã·¿åMoøöb¿û±Oßã‚Ã@Ñè1V1Pµ{µ~ïwÿ§ªà”&¢ÈLÎã&DbR1‰Pù JH©ÚÇ>ò;wo¦€GÁÌ'åØ "ÂÓïßÿÁ_ûÃßðÙÛû×ÌEL•™Yc¢'fJÌÃrNã8À²TöÑ,¤ã±ÌÇ¥V¹wo‡ôU\WÛ5p§ày^Þñ/ÞýŽÓÀ)abL‰†¼f8°¹ŽB{DâvÕ`ÎCD¼ß‰µO|{% DäÈät"¶AŠì3ÎûZ.OúÛn×A¾ÛE%ì»<˜ˆ‚|Û6maÇ-`Ô3` RçyQUs~Ù^eé­¡V K%dßÛ¨Óâ³¼+G]lŽm©ÊâÁpfêrB„ÄÙ;]ØŠÝgQm%ÌH9`Ê F1§ûû'A,ˆ‹w”›§±t‘Üë$HÇUªhl[K•¾í SjÚì+'3¦s\jÕ*šILUôÐÁk÷±* ³ÈÌiR)i83m(6qz0"¥DÀ)áá(C¦×â­_ÿÐ ùì;¿óÎGßòè£ç¥!á²”y.!ô"1Ue¦”“§¢{’rråÌ­[û‹ûG3ÛíÇ›7w•ÒÉXJÀZu‡ãaöpHùã¿÷Ž©‰üÜ¿§·¢/ja]êf»ðDˆççÙT]Tž¤Š¨ Cök×ÔDÕ4Gi‘Ó>çnéoKQwÚ \vœ&Ö"ÖÓW¤ýý‹úö·ÿÞ«^õ#?ôUk:ÌGùÚÏŠøì{ßòC¯}íOþÄ?ú´»yv©hµG8Çã¼zsøð.*"LäÔ(ÄÕ‡CÜlßñÚ·þüÿõ#½Sc@3HÝJ®*$€§`wyYßþöß{ãÿÙŸú÷~ 3«â úy”L¬<ÂHa)V ©Š|ùËw™IE¹½ä±óR$¥ÌÌË\æ"¦4 ™(«U5$‘òÂá}Ði_Qÿò¯þ®s³šÿiç_y¨jhÛ°gLý¾ƒü•2:îH‰ˆ]ÌmÝ'v¢#G@äL$Ï¡À7õ߸WÁqH.~ó+\T«G'¸Eº,6£šè'ÿÜ}.ÖU{¶3" Xcãät¤|à+þðß{ã}ó¾w÷9)“¨ [D‹² ãÀD—Ë2KÎv8,)%D8¿uãñÇÏÁlž/>ýÜ¿~ñÅÃsÏ-_þòü•¯,‡ƒ,‹Òsä—E$–ÛDH†/ßï¼åìÓíHu9²/ûüÞ7H'žÍ[|ÿ}"(hIël¦mfÇ­ y¬e8# ¥ÉLÚãIÁÖÜqN“Êœ½hÆÂ·…P–Z¤¹r¦qàÄñ£Â&"¦V÷+²RmsÊ­²ÃFwä2úX1•RKYÔ¥ß9§aäfî¹!NvÅŽVCA$‹uS’z4«ŽÌÅ@éJŸhºY^Qóµ£5{!Dý­w g Ýrt«G©R£î^91Dd0¨RÄ9Ä %ΉÛ̾êEUZ MΜóNzˆ¸y¿ãiäœbe—Ò>7Mk¬ iðO? 7œ8íJVDFÊÃôˆ”ƒ9fÊ0†â9%óÜÇ?~Y´ ½ïÜ™îÜw;~€;E\¸7Ÿÿ+ÄË¢ãŽÔ3à ‡L)¡G!¥‰Ó8ÊÒã|—¢^b¼YKL¥ØÅÅ‹E^0š¿|ÿ½¿óÙÏ>;ö³÷RA„Û·‡;wÆiâ”ðöíüòGß² :?QNƒë\IÉTaQsRŠ!’¨ÑËh:åñ‹ýè?ø®ïzò~ÝŸWÅRf3#L˜Ã¹Š™Ô8‚3ÝKJRðââÅO=û®_þå/ùËËÅE±ÇiÜßà(YÄîÒòú×ßZJGÎC.ËœÃx8Õ0%vßb‡¯òA&6&¬Ÿúé›/ünÙjL½£œ(#óÑöl—†JË¢ï}ï³ï}ï?¼sgúŽïxä_ýì^O4ˆøRšRö'?ˆÎ_ºûswï–ßú­{Ï?¿¼ðBééðª6Ϫjgšr»]Lq"$ @€ñô#èc;S¤Òö]¤/„ˆ0 ¬jgûôs?û9•f IÕÎ$ÕÆóœ‹~æS—Ÿ¶ËØÕ¤‚ø‰p7±Œ9ŦŠŸcßKQ÷„2Uq(Ú ‰ "€î&~eÞ_~¾¾ãŸÜíþçÇ^ö²éÉ'§Ül1{.“/ú–EË¢_ynùÒ—æÃAî߯‡ƒÀ¹äq ›y‚ ŽýybÊ5I8Þ›ßó‰/|ùóŸ?|â——âm݃W(ŒD¸ßó0ÐãwîŒ9a©ê>Oýü›/§{B)êÍ"åDC%¸ü|ý×?÷ùŸÇÏ3¿wè„â.bÞWÞ¨ÉÁÊ »…)$&¯HZ¯*\ÑûG¦Óг5ÐN^Iû€ßwJ›à»Æ¿ï·ÿ+µ}öÝQÛó$ ´©8QG˜³Ëœ¢ØðXé^Ê»vL÷,_UA"dv]¼q£ú˜D Üu¨y>¹ŽÈ Ó:8ol}U«£<0 Ì¡ôoì($ÒåÍgÈwëäjâJý¦=t'©&Õ ›Ó‰ְ繫“=)ÌO™[â1ô¤Ç™Ô*¢¦mej¼¥ibGŠZûOˆ˜’:€È͵Jü@nD¿zî±Óüsä;6ïÑ®b¨b—‡: ƒiÅ4!'o;fÝyÁHÉa\¤Äà 0õà9⬊à ,%F–zô?2iN´›¸Öèmö ñ0ñ&íÊ-M˜qó?D¬VM‰]ŸùĽáýX›Føš*Ѽ^ߤôÈ8„ ¨¨=ÙQ Y”YqÌô3ÿÇgU?C„lžm‰ÑYJ&¾âU¬Pª.÷tVyá÷ÊoÃ}7ˆTçfŸ2R©êÝb2¨UÃŒÉ Îöio© k¹R¸Ó#ãi•<)[½JšÅ¿ñWëv´:ù®—‡×Ð Þs8ÛSófî¢,ÁëÐëÓZªþ¡nrpµ’Æ6&˜4œRŠaðÁÐhöAgCæI;ýcîŒöA¼…vežï¿rNí'ñÏ+˜*`Ô˜d£UŸås¢œ²—Z"qäÁœå#‹oØUk\ùÂlص?º%þÐföªZÀDÁ@@`žšµ˜j<`ÀÉ¢>è:ä„ IÔïEAýÞË™’ñ I˜\$–ýã¯ÅeüfkŽ…ûv§)õµž“"ú‰ ¢_F˜ú¥&j*Å}H€À<Å j¨©‡Uæ¦ãê—##“S¸Üþ*úiTa€ã8TD°Ü×n)*BÝ[·§A¸ ^šTa;—Qólv›QoèD¨ß'"zÍǼR«/и]W¡,íZ÷ë¡ãà½CQïJ¦ ©ç×›ÁnŒ¤ŠŽ$pøo––¾‹Àíˆ2ã8ònäžš-¶(2˜†&ù»/7ÊžHdBÆŒÓÈ'ÏŒ—ŠJ9#žTüaŸ˜ÜGµVe›7rŸ”™×ÀKÿ’ñAÓljÔ¨Ž« Ù«ä¶òö ^Esò“_“©äKQêWã6®ê„èîŸÑCUí¸ä5f.azr­øvsÛ€A7Oî¯ÆÒéaë&"L”&*'Þ—[#Q·Œ ·'dN“nswÓ$õ(å Z8Mœw±-iµã}Ž,rbÏ9Ø8TE^·ˆøÁ™Y¡¦ztêeèš`õk‚ÔøF"ÚÌ’ShC‘9!5ñuM€ZTНb,ܪÖ-0˜UwZ-‹m¢ š©˜ Ù{DéXË*V|%” ÷²«HµQ¬6!h^NÑò“6#Ô Á7a=1‚«'¦VYðÝqa áT+7öÉY“ÌSn„~køH$ÏX&J*%¢íÍRc‹£@Í ‰“ÊB¼˜éЂÏï×´w”½÷<1œ'Œøuo£|såã¼—È~¹õ"ŒãÄD*íNº=†¾[‰š“ØÌLd6׳À~â*æŠû¥à<‹eòwçúôÞÑ ®í°Ó˜×î°7¡Û¤x4c ÁXÔ†LµFYbRõM…lüÛB{S¦zjÑt½Œn»0¯žÐâ£!#%͉Pt‹äãÕ†îÁs}Ã-̼0å6;ùÁ{mÿF¢6DI]1~É 8­t£Õ®Ç-5¨ÿ~½À¸§1®½ª;Šzêôµ’5ÑDŸÜ¿ÊG—û¿$N£çÝB ÖO¢ÍzHžÕü'"%¶UC"˜GñÄPÂZÞÌz\‡*¤Ä9çR*±¦`ψª§‘Œ"n{¬…ºqFÓÙºb0)ó²x‡2L4t;QSñH=ltzo‰Û¦ ɰV©"æ”§ ¤„99ËωD+"²ÿÄÒzpGP§•ÑÕ×G""ÕŒP7ci@·amžLjF"uñÍR;1cæœr­R­&NNEpX4ñ€”ˆj{ò!®'f`Æ~btŸ³]òS?üa÷˜CNÒðT»õlU|ÝB,Sc1ÿ°2Qî wJ`¦\]›;dí¡nÌî¿ñ†¥ƒMÞ§¡k4pÅe½oU[‹WO4óa_Ô.¼"Å»‰§§‘†L>ÈenN¼©R\Ù2‘˜E(ñaÖfH±î.ü=fÙVj€J„7öi‹-¸Û¡À^éÔQ™ØºPÅRB5tÿö”P€±ŠË£±óXû¡õWëUòz‘ ‡`O…ÛÖt?·œ ŠöíÉõ.ì¤ùëýš©ÄœÖç«y¾ïî·ÄÎÅ ¶ñG6Os¨‘BÚë£q[H‡N]Nx}ÙØå› ìÜŽöŽk¯¨(£š ‰:ôñU6¤'µÞ?ÖÆºoGµ]jµú´»G¹‚0°ÑL”8Mµk„È<š©«Ý‰‘5»á›¹s¨G\: ‘)嫈B+DÝÔÎBM nþTK1³Ö¥s?¤†Í_ BWêFεÖ*V«z-“¯q“oo¾J–‹°%óbÚ(–òiØ=^—»Áвf¶Ÿ–(ƒãéfª9wæœsƒ¸±è9¨ê+ €¼ñdçêw’î–áÎçD­)â $ÞƒŒyâé7¬¢ç7rbÌ)HÐ݉:ZˆL+ñ u6­#›J]ŠZÂÁˆÐˆ¢ûsäñ0‹W ]ŒÔš rÓ‰Ñ&Í`^‘=š8…z‚ŒÍ?>È”-~œ² 6;ÙLloÓ^e¼Œ®Å…D·ý½êš‡blî[÷Ÿ‘0]ÍDâ@™6/ë\" ¤T¥ŒUÔaæRµ#Wº=Â-záyñk‡øðXãM1]Ñ€"ÈÛNÓAÒþÃÒÆª™Éú«,£½¤‹µ™8­üPJ jàäüN¿¯}GOÔ–ø”}åk%à¤UC•1ÎQ½‘Z7ë³ó¾Gj*„ÕAcêŒív<ÁJÑqd"6æÁñ€`ø†k-e™:@)efÈY¼h2@˜Ë¡”¨Ü À¸%œ2€xH3åÐD"æU΄ªþ‘8ñÓÄ C¾¦Çµßß<"}[åè­C– ”T•Å"Óœ= %ºõ8±rrb~C4r‚£·.U’¹èá(7ö-Þ ‘Òþ âã| 0Ì#´ecä-ZZ6„-°ð=Ï_ñOÜTT‚Ñ­öüïÙ! 1Dú¼Ä±+/ÜWU¥ ‘ùÄ|*U5“‰ã9dÝM´xOÁ)!e°•à5”(‹Ìþ2Í8; Ó¹$·k¦t ¬uŸ´k)ÖYÐÛ×µwõRøP9t äË‹®–2Q"TîbÓªf*3À¾Á¾ &cpŠå¼ˆ/ýODzµZ¥L^‰JÕ^7§ÌþûNÒt¡WŸþúHÛgfÑ"fEÄá*:µõKÜ·ýN|0WQn«Þ3;MÀÑ–¢ÿdQ\ëÅzUÚø[7ùyïò¶i[¯‘H<œÔ¥ÍQ¥wú'0ÅIïù -ÓCGø¾_z˜Ÿ·½¼ƒ6!œ§D¾öÈ•ÜAj¯¤Öòfúoe5xëçì"¬À”xðzÔ4”m¥ˆ<,á3r¥— §Ow‡ü(Ç]4 MYïV1žÆÞÚO/²Ü¬M¸9.{H‘E¬SرÜûk±6„˜\÷ý”ε,j–-"QCäœy3žº½ '|85Šˆ¬–¥ .»ÿiÔÖÐé÷´Ng5DAÇî÷i¦€H@h¾A@Úb©˜<¢ۉ]1uCR mþ*è §n× „ü$¨d«BÁl):Ê"õÈyg–}>ÑGȶ‚d”¦€bH›Ã{[ý1Ùl¥€gC&6©F„§`lÖ _£ÓGÍ]µÛ{["'í¶E_ ´z†¬À‚¦Æ 0ÃMÄ@#A³ÊfÉ—¥l `Æ<e3å4ù‘'<ªÔ¤èRÎZmÌqÂã!qþùfQusmÍ£ïµ|ä_Š.EUÔ'zïδ*”ªªÝzø9QJÙÉgWOÌ2¤©¶ÍÜK¶™´AÎoÏ?•Ü™?0ì$¤kRgDDœ Æ~Î@¡Êò' ˆœLªOñf¢²t±µ²ðº®ß½9ö¹%ð„&c3 !€7›f"GŒÅhòÆ•ëSGD6-ˆìg¨LS@ ĽȚVïÖU Bò·Íi™™ÎLkÊg΋òÊè®`>HÊÁuDÈÃy˜ÎloD)—¦RÅTm?qï+kÛøsÂØ™*X[Ê;fšìÊýì\¼zKo ^W–3|eÛ³!PÛ ‘Ú´:[eä6n„b$„¯üýv»•m¿ãjgå{ÑÞÜQr•]Ï5êϘ-å £–ÝtËgZíE:¼E~8–½Wž7¸í:¯SÇðüð,†DWt¢Wó»|íëÆ‚²mˆÉÛ–­§+ë‘8&w$rÂSš8eý„‘š¦Œ ˜2·Ð¤õWÛTmþW©UͽÑÕ‚xoÞÅD‚¦ßFµÛqšÓr<t†œG×)yé70¢¦ >Ò¢+ÍÔ¤´ZéËä6öÔ>Nláwˆh«É“Ãf¦)‚ERmö<‡•þŵeð`Z}õƒèñ³ì¼rÀ¢ûu!`”!kT$1­"U˜Qɾbr³;5«Uû½‡”R>Ëã­íÇÈ~åu³Ñhl›o7R2ÄlRÌT—KJQÊ‘ÒÌ"K=šVSÁàdTCY¹¦†J+Þ:ªëaÎZç¾F³¾¤ŽA¼W Ñ´š­1 @<ÔrXÚ³aIà G B™¦‰e¹˜È÷ÖfC>ë¹®f U Šˆ ’¥™æñÜLópCdîfØ.«U¥¨‘Î}ó|Ù’,EÕ ٷ›ÒH¡½¾l ªãÈ=Ù (¢‡×—××;¯*ê„î^²;u×'ÀÓðáŒôŽo<ìûnÔПÞÊ9Ï h­e' "çuñ–fÿ@Htýòà’£ªuˆÀkßKa¯P¬®ŠèzÅô¶´k@½|Ÿjê‘3 ÷c¥¸Î$€3[oƒ¾”@JW¸ú”2QòQJ£…QfrŒ|±;&w<Âÿ›VÕ j‡®<âXÀ’_×u‹¦¹ Ó)¢¡PJÉ+¢™È­½×àÔu´ ªžÒ<Ÿüca Ïfo(Ù´´{;€cõ}'¾6—Ý–?ÀDoR­Q]%bÀZb¯ß™êúQß}7_jCB2­Î•37*m[1©ÒNÌ:µËLAãlãßx÷Á¡Ÿa)D¦4"qn¨¤$å¢×и"`Ç¢‘WU@ó[ß¡[¿$¤ÎͽPË]]3š†þ¿D澦P`$nn NW ÜÖëñ Ž>7Áqæ}Z6yÚÕ¹õ«&álz·†¨ÂvƒÅw#y:Yý÷pþ—¯nð·ä°“ú_3¸"Æ—¶ö~³¯Qú¯‰ð6KCo¯›Ý½ÔÛßçI³Oˆ}xw0Á}°Q^Œ*ÞSøFÂõÉñA¨¶t!ãÊÃ猜(MDÙ∠†œâöˆhNiöò * €sÒJþÇ€ÛZv¦™  Æ(Zô«|šF >¹€Sš¢»ñ¦‘ÈÕx ±ó‚ú§5Èð.«Hl;µ4ƒÚž}Ô˶3…ðUës…º…¨" 1yÚ*"•fÎäÇ¢¿yò’Éb&€žÌì–ä¹{?¯QÕ^ñÛäÛCØýóÒ:¢ÊÒ븯ƒ 4qnN.þûŠiäØt¡!VPèh£ÊÒ&_q? DRYú.:;¸#HôS¶{vÕJäQÄÐŒ÷­¯¾¹r*ˆÝR!…”RÞADg uÃÓª2SšLÄŸß`FœÁÙ ./B ‹™‚YÉã-­³_Dãj_˜wH9Œýyu¾Çi‡#…/,R>+ó=Ä™“™é8°ˆ^ªS>™¯òímuE·ä§S¶ÓõšršÓuœfAêÜ®§a¸N\‰*äHŸ—ÕéÛÑÅ3Û·LÛE–÷Œ=({ˆ™¶%Ø ™¿çÓ@¤«õô¤’ö¹{5]¿oÿeŸ~'êØ~àþ–üÿú[º^ÁSŒç-ɧ5¸¡šIÇUë¼>ãÌC0“ ý~‹ýFZYM}@33>gï.Ó3L”= Ì,LžÀ­‚˜&³¦î¤"Rfž²ŽhÌ\«OT'êÒJ?5o{{žŒ$ª†Ø½è±YFQÛ!yŠ'ö¼_—‡ @ï|ûP?˜ŠÄ‰û‚iKчu,pÊtFã çš§>pg˜5„KµÅß•ç>²—ÁTÀÔÁ>N;•ÙT Mµ-è W"vBM‘M@¯>qµé@Ü<[·Ïãë¿ß¸É¬»µMñ µcm]IfšÆ›[9™‰µæ78½IIÃöMÉ-¬L+rB@Î{+—WÄyœ ÉÌ8ï¡Øº† 4qÞun¼” çcY=´¨¨Ö‰§®”!«¨»Í»KºÉ7Q3¯òàp<¡%TÕ•RJW2{uÛVÛŽ<°6õJWjß7†¾«—§áê8|ÒäžÌìÁj³ÓÒ¶Z(¡½„Èö!‘ uZ.}“¾kÖkn Ý&íDë_{òÞ¶'öÀ7–\‰t…¾u{ÒÓix4-Ö!öøåf’ßJ€ŽBR÷ùô1³i~Ûê‰u¸ÇXAb%Dk¬Ì0gU!“H‹2uþ“Çϵ-¿/Ù!BõU¸‹ò­Ñû¹cêx¨S¾ƒ’rŒŸÎ:ŠÍ9oö£†ëþ”º( þWD!mD-r5àTŸí‰™µGÞû‰™º]»Ù°¹±jßŇ–!NÚ£Ô€‚SÐNl½Û²Ç$ û<Üàá¬YÊÖÍã J'ÕK=˜,Ö"‰L‰!fj“„Ó Ù¤:C~ks〠òälÐ-W´=öäúÀszÑËÒhë2Jµx°åÀºØcë7R.Á”‡ÞÉâÊQ¾&n°ýó9TH„¦´4¾š0˜·u¹‡€i8ëý2T¹@ns-¡g9ÞER*(PLÍ¡)T1uÞ6d†ké¾_å[²N·½žöºÖ_øÄxmñÌúüaÃþÉ7º^¶úž‹Aþß´/=¹_i0íÁ”x1üÕz }˜ïr¯¶'ϧí›ÔkîbÛ?&⬳s•½ ÛÌ8íWÄH4BD®œ‰rƒö8—ª>ªƒøÊìÙäf®-ÜÃ]æÜmTÅ[7÷:@/>kkq˜O¤PʦƒcÕÂì6à @P9†Ã4R¸ä­—ek'ÍofäD¦bÝZÓ ø’GA”fÌAê\ Ê©iÓPPŒä„@ßè·¨íyÐ5vè½^8!ʼn³koÛ¦®‘êUZ»G”0¾ÂY-Ä£ÇΤDf&õ¨RN%U®§¢„œ²Ö£oíM‰ ÄA…u·ãϦ§!#)"©Î¦m)DLœÝ“pû,ª¿è¦†b{êlõ½2º ~Ân§ ²8.ø€ÁØRįzCH³ …÷•ƒi‰o‘'ÐççI0N #JRÕt‰‡e0ÿØÑO•ð…q*ˆ¡8wÁãê‰)«Vâì)Z 4—àÅü`n¹`’/,A¯2îwg/ú=¬–õ.l[ûNªÆï[%»öºÀlWõõìꆇ©‡ý,½â÷†ñ¯X½©6¹í=fp·ý<@-Ö¾ÅuYJù¬®,¥¸?;ÛÉýFCCÆÐŒÌO-›%#%Šp4€R4äV੪޾iâ!¼-L=yÉQ•**‹Ô:•½kÜLÕ°‡&u§°­é6;R6HÐÂE€hhm©µe¬¿ñÃ,–1S³E|Õâ518ñ¹ÞNóYü9Aæ&L&âÝƪ;<"€„¥TlBsÚ ™9 ‘Í Û¦›(©ŠHõÒÙ’ˆüÄ‚–‹¤¥ÝÄžBCœ8Mîó⢣-ÚˆŽo"ƒ©JQ­Äád"Ø)Mþü€P©¶PhJÎ@Q™‰"ÌДÄá°wÕ?L—KZc¾l›ªÝæœì :çÉ7'søÈ‡z“º®àt¦=®%›ÜäÐH–ûþ%¦µ”K31©â*¬E<¾…ò®»¶qöjÛÜѹs ñàñ'|†zl~ƒí}ºÙré^…n`¿›’™ÎK@ËL“ËL±T²“ü ßÐÆ¾´y ôè³ùõ^6RQ7Õð ïN/}N‰XYßòêOpÞ“Òv"ê äI­<¡ëoGû‡yëõ9¡ÓŸœáõÒÜ›eÝD«vg¢*êé•C0ÞÁ¤ûßvâêñ–>:me‹}"ó„;¿’('î¡Á›MvÓ}:ÌÀ€dCžâ­æuÞ²™„ñ1!q²Èà3¬Z|©Wô”x5Ϥâf ÈhªM Õ±Nè üˆ›‰VdÐ<:Œ6Ôq $×8œÓäëñØÚkñP½”!‰[Ê»Â`)‚¨CŽÀDÆ•aF€äN0ˆF°º1ë0œ…–¿›’º\ÕÔº³*ÖÈ"9"#D˜»~¹$8Ÿ©Ì!v@ÖzDNVŠH–1MD)$¹˜¨ õ[OvŸ£µ[MTØŽ5nu¨}—»Žcý ¹‘µˆ@hà{7îóä(3 ¥|ÇÙÐâ£q£?â„HU5FïX²ÉlR| ¶,j”vf@È&Å·¦bD&•Ò$*þ-ˆG¿‰‡˜)ê›Ë­,—¡…Ý |ˆAŽØâÅî23#¹±18³› 9ûð„UK¸ìÆêfÝf^—Q^7´>Yšo;»“rÐ;Ó-²¹­_]þèÛö—žâ¶C'~@·ÛGé-Ù[æ ]ÅO×윦ÚܾòõUÒÃ|ÿüõxný[?¬¹fÆZדLm/¬…4ÜìƒÕ*¯>ô »„9¯C ŽÓØâØ<X‰Èýß,UòÌ'¸ØBÌ*‘‘ëS¼Êâ¨G„¼÷ÒÐ’?вû·ÇÔFw/‚Ö%’?Ì,”È€(åÂ×#ª‹™ºQE´œ~ÁZ‹lB»2„"l¶ †”ÍÄd‘x´PKÜk±Ì¶u‘©°xV39RID9!¡KlÁ7ìÖÆ7Ïúb.Üüb ÙüÔz ZÚ‰±7ÈnçÌì\q1E€ZíòXSÂiRh…Þ;PÎ;ßt›VäVøÌ yÐzTR‡`ˆ¬1ºì IÕâVªÎuKù¬]B«¼½ËŸÂÖáÚñÜLµÎ±|§u´w «`޶4@ÀNž #@î|#ï^€)qKcµØ›™Tèà2ˆ%-—ˆ„”ASÅLŠ˜Tk­Gä¤R“KH‡ÞC¨,µy¸8ƒ³Ç±.÷Í ±ˆ‰‡-TU–Ãó˜&N""@î:¶ Ò àpy¯–£ªC6HKÑÄ*ú½ý€ì€UFÉxâ'¦SjÝ(¯dllU@çä^VÛJ}åK,þñö/·> $uC“¾š¿òå°[ƒ“À½ÿ 1KÔºn*¬v Agæ{*O˜ 4—kyPÅï‘$ŒüÀrœzšþn+aaj®çIEND®B`‚eric-6.0.8/eric/pixmaps/eric6.ico0000644000175000017500000001627612371441521015646 0ustar piotrpiotr00¨(0`ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïõõ×ááÈÔÔÅÐÑÃÎÏÂÍϺÇʹÆÊ»È̾ËÐÄÐÔÈÓ×ËÕÙÑÚÝÝäæäéëïðñõ÷÷ýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ûû¼ÖÖ”­­˜š{‘“k‡‹`}„VrzWr{_y†e€Žf„n‹–|• ˆ§•©®Ÿ¯µ·ÂÇÑÙÝåëë÷øúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÌÕÔm””Mst1WZ%DI7@6=7;7?;I@OBRIX-Rc8^iAcnPivf~ˆ‚—  °µÉÒ×ïñòþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö÷ô˜Ÿ0\QD; 10'*%*&)-.,0)5&7*<.? 2B3@2?2C=N4UcPluvŠ“®ºÀäéêûûüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêð釣|-eR>45/0, ., )-.4-4+2*9*;+;0A1A-=);$7 '87E0S_Rnx“§«ÒÛßôøøþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþðÿçÄÝ¢E‚dTAQCB2D805.;-2544A,:)8,=.?/B /A*:#7"8.?8GAan”¬¶æîíþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÃÓ¾}–fm§oIœueU ;/@9 50 4. /-,,/9.9+8,:,?0D 3E 0A):&8%7%8>Pzš£ïôõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÏéÒŠ¬z„°wCŠa"V?O?[P@7<0 84+-*+'.*4-6+9,>2B 4E 3A.:&9$9')7%8&=(QfØæèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêùê®Ç†Â䛊ǎA‘]-f YM;* 1, +- '+ 36-8*7+4-9(4'5)92?7A0> +8"1(@ ªúýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøþöÑã­™®€V‘f•È…T}T%M7:* 2- 47/224)1+5-7,:+<.=-<.>4D 5E 9H 1>(<Ra±ÌÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÖÿֈǃ¦×’Š´mKQ"S= :. :8 15237>5<9C:H4F/A+;+8':*A.B2B3@,71G>~–Åãèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿý³Ù±»Ù¦a‡Y7mM9/9201 6;EICJ7<2749>B8A3?0?.A.E1G2F3E 6?0: WS <UScaQPJC>7 7805-6*5)7,>,A 1A 0A0?9HJ€‰ÌáäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþßðÕÛî«§»t0dFP:\GTUICO6bL_V>B>=@<D>LJUQ\ZFI9D3F1D2A3B8G2E6AL}†ÅÝäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÿûËÖµ¡c1mKYCnVPI HC]HcFO=+-pC@•g1~[O5C,M@!" 1-4303).+13@5G2E3I;n„¡ÀÉøüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÑÜãÀqXša#…t/~m6nT†{y}]g‹\#nHnOE8 *0.?,D+=>OQdv”£Ýçéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿù¼Ó˜_£Z;²†?†bG‰]$¤}3£"c\"_X'ng'qmah*5 24N=9‚c#?2'€Q(µyšp<- -# C=7=5A / (<8M=SNyˆ°ÆËûüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþýÅäÈ“ËdωZ–^8Œ]4’q5gV(WGC‘w@œ8™{&wiEC%`dafRX.67*!Œg-Èš)u^ ='rW XO =@# .7*: ,>8JL\†¥¬îñôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåóx¶bŠÄ~Cy_/iU.A<1hNA’q9’w> ‰"YI VD'p]"{n€€T^6= ;Aa]XPU90±~•tKC7:9C/? 3H 8K BPn—£Ýåèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþ­×Á£Ï…ršh\‹]vÏwl³pF…cC’w%d\\U1.%]S's`"te$r@7 YTjd__#+,&šl'È”S@ ?2UOIL+8)67J5H ?TY‹ÏÞâÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝîì¦Ì²n¥q¤õ’µÿŸ¬ô°EcQ/YF2g\>‰k?€b+e\9}n0yk!vp4,5sc"‚kB<47FIFAo_G7|_zl ML/13@.B5G5BRy†ËÙàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËïØq§p«é¯ÿ®ÇÿÐ^fm¸jqÁ…cª‚Wž|)YNG‡qAŒs9†{C9=™q8v]KB)ze1ˆt(xlOJ%~a&¦G7$ BG1C+E.D7J1HInÂÑØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ûú§Á©˜Í‚¸þœæÿÊ~™y¦ì‡–è’wÅŽdÆ“.p]<‚fR½†bÇž.bNK z8dP,‡i8žs-“n/x4~s1,?3dG?-_ITPAN=V9L5N6R8LMs„ÕÞäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïùõ¶Ö¸“˜y™“‡oqlÇÿĈü°|ø³Y¸›5sTx圄ó­CaJ1MB9*<šeA­s1¯{:²Š#VG"_L.od463%%a pW WW =K4@3M?X;L;Nkžó÷øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæñï~‰GmJWr@„k‚—Œ¡äÀ¥ÿÓ ÿÞ¬Ž™¼Œ]c)G+F‹j(^E,sH;±n4Г1pI59•pB v<…t"JJ2w\#fPA7 76 @EUA " PÉ–OÒŽC _>÷¡Mú¯RÏ¥.]>V§gY°‚(_OMVDX:CPTCH BIKS EPOY½ÑÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ´¼ÃYgkef]|nyw[s‹_JiN    4~d?¿ŽT¿•(ò·,ÿÇ>´ž)]:JÈo=ªz9hJ2ˆi ƒ‚ 4T#;(?AIPXMYLY¶ÉÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÚàsƒGe^„Ÿu˜¨zUgN#(iˆjo¦zq§‚>à©(ÿËD¾œ?£bQý‘YË™‹ºŒb¾ !–’ Ee ?\ @k6L !, (<3C­»Âÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêïòž°µVuufŠsq†h5=0†xkœdQ9) Ylc¶o}°xAžz£” ~\·¤£íÚ€®¢‹ª”‚ÁÄ0arkrXs Js(F %E ;[“­»þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýýËÖÛ‹£¥bzrDRM’¼‹ƒB4/wŒxw¹ƒJ`o¢n~Vž}[¤jT¨oP–x'fE=aeŒÆÀi¸–'‰|*Š~woWqJtCk?`k‹šùúüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷úü¿ÎÏ—¯¨uyqª “grO{¢\b¦QM³t`àؗ«îœ‚ãz{Êv‰Ç˜0~^0SV¥›b¬‚!ƒu"‡ ‰jpu j”[D\`€Š÷úùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþôø÷ÐÖÖÎ×ԽǸ¶Ã¥¸Ç’¹Ó£Êâ¿îôÖÿÿêÿÿÛå÷ÆàþËˬT¡«ŠÖÌl¤’ƒm‡)—ƒ†y{\r?O‚š¤üüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúüüóôõæëëÅÏͤ³´Œ¤~™‹ˆ’ˆ™Ž¦³¡½Ðµ¹Äž°¾ŽªÃo¦{*¦y¥ƒA¦•_™–A…„hj?_kÆÎÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýõ÷÷éðïÖßܯÀ¹ˆ¢•v‚_†v?uc=oW~Ø$Y˜¦Qs}‘Y¯½§fs…ñ¸ÕkRç¢`Zt{a‘@@#T ŒŠ‡]ƒ›˜åE¨¥T+T*#ƒÛ¶ï¼xjË FF.Þôø¡'ݳ³ÇÏ/ž‹ó^šeKkKY§Y§!ÈÌr¥!MYœñ´PŽë*…ˆA E aT®Èj5 `ÌÆ5`g+ƒ]Ã/…[ë2I©i[UÕÑÈÍ;.zÅä¶Ë6=þ¿H)8gBаÛXo¬Ì-Ï.®ÌÍž?Û‹BÆÍ¥’LË •Ü@—Êrc½ÛiÅ^űŒ0œY6âYTé3]Wš42¤7\­;Ô=~äÌE—V‡‡¬^^ôz"Ée” ÞPÙ 7Úm¯~ÿ•/z!ôfD½••óaÔ^Zž[X˜mEí¢ÈÖÚÝD )$`Ó0‹˜"˜º%·6ØGLº¶ºÞhµ„ÌjCUD„mÚíõ&ÅÉÐñ¥mE–›a .6©Ó©”°…Ö™þÉê „o[m¬Tt#œYo­PÝ ¼»ºœ!]~ÓÛÿ½ô5€Èÿ\‚³Ù釟|(N“Vo£ÝkļH²|tëxœdÝ^â˜KªŽãØ®e{¾¸ÕþêŽ w”ü2ŠMhöZ'g6¬Êž•µS[¶OŸ=Ì¢vØë‚è•Ê»¦¹àUS‘deC¯,ò¼g]{Õgޝ.kk'i/‹p¨zfc­¯1­Ë¿÷ûÝõíÿ‘=”RR )åÚúòô™£ÓÓ'ÓŒÍÌž]o65Ò#ãÃ¥þr½Zð\×+—Ç&·"eîÚãú!&"”–½¼Dr•s)yœ­l4·LLõÒ¤dYñ¶=ˆµ¬¦AS–;lc1 ã…¥•ó«¥¢À‚Ѳ½}¸®½²¼á÷3â§yÎ]I«¡»ÝÔCÀœÆ"“à{hmm½¹¾0¼åÂÿ8¬H?yèÉöº(é9¥úž+®xÉM¯Yîµ;à.]4d‘Å]![ë-.©´XÚèMŽŒÅ93¢,Î(iWJ !yš¤Ý<ë •fQSèr¦F¼—»O}amÞ°]2»˜m›Ú961Ò\’³s+†ËK¥@š*ê§&S¤Ä Ó ëRÉYVZõaC!ÕEÊ"´¦Ö—çæÏÞ²ýûöÐZgYüݾqÿÁ{@B­>rÅ _òòëo[L:™¡¾òõ\noôÇYOR ¬Z¢J|KWëîÐ`=LâÅdaDOjÓËÕLU#â­”u:+­d#t¤=P &¶ -Ì_Þ˜+VEºøt±±^Ì/åwþÝ‹wíß~¤yÎîù'8ÃÄÅ%q;÷‰¿¼”&#Ã@…汈W @γBJXHI´ŠçfŽ_qý«1&ÿŽ=º“§ëž/6 QîŸØ:º«Õ+ ÿÓw?ž:Ùã}÷‘ï»æ7®7§9cžë˜4åER±2â ª­¸Ú÷Ø“+öÀ–SٳȜ(qgPuÖ¢“+…œ:¯äÕdÿ–>›ÏÏö΋z‹«³óNZ b+I ·°Û®kÒµu”ÛÛÉŒa¢B‡Œ*Ëá]NRîKmçJhJC¾B´g€4 ‘ÉÆü Ëö¿–§‡¾÷µCÜ;=îòk.»öâ+>|ç_}gã›S»^ÐnµÖ6"beKs§^øÆÛëÄ]?6ã÷Ù;ËãÀÁÕ˜›Y—ž•µÒñI+]Yj®Íe¾P].,+‡åJXœ E*©=pò‰*jJõ"EH)Ö–âý[§ú*Uî‡y+ ‚ ¾aadXD¤ƒ‚)Á•T\ .„â:çZ+!µ‚À4PFJküïÎCku~æøw¿ýåÇ?Œmû—ïx36ì¾÷Îå…Æwî;˜þeûFN¯õ®Û¿°<ù½G_õ†—$ QR2ãEÒë†0Ч“îê\G°Ó7¿ñæsùj”¶±ÅPN=°“^švcì2°2q3ëld"|ÏR‹‰³mûHg'±€I&¹iË5à‚‰ŠïT!CÈ<)òˆ¹¶ Ä4Š3(òLq ‘Æ`”ªÿÒ¦ÖóÔC ¾0wêÐÁ:qú™BÃðÔöÊÀàßüÕÝÞó~×ç¾úÌágxh¦ù†;¨ßò¿|ä3ó¿­Ï/=þ‰ïüúþ•™îü|Ÿ=y\žAyÚN‹$óÆk¯ºéÀÁo=øÉ?øøëÞù\µÃPeÒ@AyÛ¾Évc­»±ŽE÷¡o?c`Z­×úúPØcÊ”¶ËãÛs ŒØÜÆiN•HS‹$L)M,'hvÃ"ⸯ¤"êÉ(S#ŒQ!±(4ÑÈ X`l•+%ôïh·ÕXzôûw?ñè½Ý"Ö¦«©=·Òl_~êÑ#¦ïì½ð‘í[Æ?ó…Çþø>l:µ7¿ç/_yÍÁ{¾úÅ/|alxä¿üÁ;ŽÁ3n°¾œ/žëZµÒ¾]?쬵_|íå÷å«~ßWúÝÉQß)½"¦Ó, ³±á¾›\ñø¡“,î]rÑàŠ'ÎwñÔþÝÕ‰©,^)öü‰3%UH[l´’"M¨)-D{—L#¦d.(SÁè^aƒÒŒi^(—‚JÈriùîî=þÙÅüùèñÔ£ßùö×>µÞk!‡Šdq–³ìMï}O»™Ÿ›>ßi´ªƒµ°àwþΗ–ó›^ÿ¿_|É žzüËãS»jGt…þÉG>zræ±òÞj³×ÚÚox–í[Ëës³33}¾µkg™ÖOC¾!kq&jõ˜&¨ÛSû¯~ó[¯Ù}á¥cÁÖW^wû=ß;8{z®ÖW¹â¶ÝóD÷<ðÄ«_ñŠ>?>uvE5—³„'ͦ\‡ ÕŽCg¦â¶Ò,VE,C›½DûŽ[v¼VÑ ³ðPß:a|ëSßYóMïÛ5BK-Œ3eüùŸŸÝùŽWÝvÝ™9\rFGû.¬#Çž}ú ß¼ûïyãÛßa×hïD{ua±Ý›]]Oм ’CÅ’àJ•'¹Sq[©"Ó”! !si7–û·—|·hŹTª^3F/xÑoÿÑ]–SzþŽ,‹Ÿ~âàǾ±´¼+Œm Yôú[_%ù—îúâ®WdIX$Ñ–©-õ‰¿~òà‘=—_s÷ç?¹¾Ò^[žKÂeÁCi¦ØöÉî«/yQÿâòZ»ÓEÔ™ØR †ïú“ÏöVn}ëîz_q¾·@œN™V­Qá¶ ‹£ó)Íl{Öh?=êîœÚ{åÄêÔM~ûÆ›˜fÑK滫Ñ]E,BP$Ý4\ÏiÈê£ns½kJåh g‰Žr].›õÁÚ×¾¿:³’`€vš Öñè€é»´—êl›–óü= »­üì_Îy¶“ä-Áý¾ªU®ëNNÊòð¡û¿zùËn¨÷מzð‘ñ‰zÉEë +¶c?s’õdk£Á²xj$Ïrư¸I’Êvß¾ñWËΡÝÛ­Ñþ-Çž9ó¥~~ße#×Ý2äìù¥9»ÂˆMKn)Ìü03ÎÏ„߈sOâ ÇÎl¼±Ö=‘ÅîãÇÖή,4êC}{öնй#Í ·öŸŸî´À89»N "Y6ˆ ®õ;P|õ;‹«Ü1`׈S©ÒF˜\Èj%’¦êe¯ß°ñ|ôÐZ¯.ÏÝ{÷'—ÏÏĉhw“Á ÇÆ/ØÜRÄP˜È{¿qï¡oÜ÷?þÏ¿ó¶_o/­ŒW@É‘‰å¶’¢½±”Å1&ÆŽ© ¦Ï=‹@³‚мRpâÉÙ¯ßuhß5SO?ðàßüÂч¿þ½·¿û½×Ï,<aeDÒžWJ2äK{rbü™gŸ\˜ï¨¡ªÂ ´î"ÚÛðQù±çûR§±õ¨Óˆ¢"u9;¹°J¶Mê™æé™,&¾‹,D¸Ð¹T ËÏoäÕ ¼èÃa¯öËt;ÍT+Xb©Vêùx~®µ>}ôá‡ïÿ§£ÇΜ>»¼²ÚHó鹋­K_vC^Xäš–ÊAÿçÿ¯¿|•ͰÝ,}þÜšb‚¨Û[!ˆ ÐçN·0¤•V(KŠR=hoœÿÒŸÿåô“£ÔÏÇéÄkwÿÒëw¬œ8KçÝj4´ m2›²n‰ÌÖ£ÞB/žnõ{ýts£HÊ(EL'a¦Ólq¥¡{T;9fYEó®PÃÝåÌBÔ5y‰‚Ìd*uÎ`=ÚÁC£ŽS6L“U n +.Pä[Æn×,•ªÏG£ÝûÙ»>þðcÇf—n©<:µcdr²\ò={â®ýíØ® ê#Ëßqç»öNœ{ô‰?ýõ' ë†DH²='SÛv9/¤– ‘IÕúJ¿ñ§WœÖôêbÒXP1ÂóÍ9Óé–%ªLÉ”-BäÕŒ‘‰¾,ÇsÓ ï‚º¢r ª Ö°WAx1›?G{‘vÔ‹úª„3sȤa7« 1çA;CQ,ãˆûõ|Ã*RC–p–jƒÇZçL*D¨¦¦V –=¿<´ÖO>rïýáïÍ/6ö_~é›>p½30Vž˜ßZ×x}i娱3zèø±ÇƒaÏöâ'݃8³'j¦QUúì&Ë5ËͲ\– (КZ@ Æ'·÷yÃÑìúéárÍpZ'Ó§9nÈRÝñi©‰ŒRBÈüBLp©\Ç« Ýí©l·òþýª Š+ëÚ ÿÐ÷ŸÙqÑjti…f¡ÄÚ°£Ü@Lôd$µ©µýÀŽëIø&¢X2išHi eRc­´BkLU^¨½åþì5Þû¥ú¿ëñÒÍï¾epÛ¶Û´6\”ª'ÂKfµzuðÒío¿öÒÎúÊŸ}连yêìäÔÈêÌ"O%š%ÙÄnk\U–f;yÊLË.²!„üR€(/rï{ÑD§‹¼rŸ"ñ±œ¯¬öÖšÛŒ ìŠzÉ×V€´d„$&!»öõ?y¨!3m2S·b„`\¤²o{_þ]Ñm'žIˆÂ•Š'C%¤9»˜?ÕµK¤V³´A²\Lm÷­<ÊX¿c:.(¥”ÖE¡(!Zk¥•ab X ‘?<¾ýµOñÛŸ»â¢àÂmªT]JãÊ@¥ì»Íƪ㻹g›çQ‡3=P¬ìٻ盟øúŽ‹·/ž™CšXŽ­¤˜?× JÎø6_ X]ʱ!(E–m ,ˆAXÕzéÀu[{lÉ ª¦ÓÇai6³ª¦f†%Q‚SC9˜ØE0 ÑÞxɓ߻/Z‹½Z™·Š’gA”#„Öz½^µ÷¾¯=³{Û€Ip¼Q,ÍwOδ¨êcU7°,ù–nv²JÕ¢6j4Òn˜Õª&B ¸ÆY&ÉRN‰&Xs.AÁàà(ü vð³ìÕZ¼ïŸ¾óÀWv^w ÿ¢)ðK$(ûÃnPE˜Vkõ T]Ë:kíÕ…µóKKó$@×½üzŠig½·ej²o¨qîø.B¤±3¡ˆ©ú‡qmø„ˆ°`Ï10PñKhe±×^K3E·Âël„\`m9Äué¤ÊF¦Ã U”öbÞ?R® ›Ç¿?×Wp"Y++[ž¡p]©–¦çÏuŽYyêÉÅgZ)Sã[JƒUZ+!϶|c`ÈÍ„Z%¢A%§T›&²L -„ÆHk¥”Òž_ŸÜ?ïýD­<òÀWNß[{Ñ¥œú¥òh9èÓÈVʪ9#YÁZ«­åµeÊUÉ÷LB¢Ö‘'|Í»_77{Ϋ-p*gM#Ž´"Íõ,(ц‰‡$æ€P‘K„qšOê‹›y)0ƒæL³:ZÚé°\¦Ü2´%s€\°® ÈHʯzùλÿþpgn¥V ×FÎxÈiOc­•Ô³Œ‘ý–wì±9Ñçæ›ý5›iI-ç<˘äL+I‰ªTH ÉÆ„ ȸ¢!­A%`š´o`ìç?_zø›_zê›#ìBÚðJC­Ùö²JRkA=ŽQG†­¨ei‹5šÓ'>ræ|ØlõšM øô‰SÚÚG'¯ŸŸ>xV2I)I#J1UJc¬à,–i,ßý[/ÞêÞwÿ÷ªýÞàX£Òù™ùåéµþ-NåF¬Š\´=dHЈP$î5#Ä -Ѿ+‡Ÿý~éñoŸ¸íµ,Èší€:íåøûGfmBoyõ¥ƒ“åÅ¥¦ÆJ°bH»Kók ô訟3.¥ÀR‚IJIgÊw‰àZJ0 PJ›&–BOmÛ=08ùsöxäÑ{zê‹[w_!Lß´}+ÒÔw*c…””Éuciߙ}⩵3§TšÕ½à²k/¿ê5· €O~ꓨW¨"U$&/Ûrá¶­Þóìòìšæ²’‚!,F¯¹ãÊË_ÚÿģǶìºíxæD5×ßúÞk³f4stC´+vg+’Te'–Á³X2.A"ˆ“ŠíÝôÚ½Ÿÿ‹Ç¾çäÕ/ÜêûÖÓN9´œ)ñú7\f×ÜãK«ÔFÍfGÇ™i£É »»–´–»¶G=°X*©( ¤ âžCn™†E1ÁZq¤"ȽêºÛ11žçf<ü};F›182¤ãР². ª-ã³ïð3Ÿž}æidz·ìÝqÓëozɵWú-ù%f éµ¹/ßõo¹ó튮Yœ¾ûÛöÎÿrÇÃŒ‚©„_ªhÍÂ^üªw~ã ß5]âÕ¼]—”‚À£|ð¢=¦ùž ~ç]KÏÜ»péKF¥Ö: ¥.8Ò RB*[ÝbÇÖþ[oÛý廎*ΤÖg޶-ku0¬6Z=”ò„q‘RͲõ!4VÁkR„ 3u,ÄRL@€zÕl·D˜É¡“˜Dä4Ò *õúî½×þëåúéz¤Yç+÷Ò®ya¡Flc[+¤eQ§ÈQúÄCýgzÐ`ì×]uÕµ.ÓË„J¢öyÉ(+Ô·îÚ>>5ùôýÏN]3î“•éÙ¹ëý£³å~kÏe[ ɆƂ ªÿò÷¼ï[Gáá rÍv’‡I81âžœY»áú}zò»K㓃VÀŠ\K@%Bi%ADn.…cCåK/~ì±å0á“•ñjÐÊóGžœÚQÁè¬ô,TÁ±‚´t¹dÐBõºÌ­šB€ D´Û$¦‰¹Ö! ¨Ó—]}ÅÀÈÔÏ̓ñì¾îÚH:•R— ª4Gy­R«yöêcO>ú…»Ï>Œ´¸é•7¼üú˯yÑÞ4j¬ä³Í‚ ØÈ`Ju6ò§=ùÁßùOŸûÇg¾ýÌÔžŠU©_9Æ€·[]#ía›ªfØéß6¢°œ9NíÊ “”¨i"Á³f±:Psœ™}ÿïxç+Wl¸ÞR ,IG éi a/ï­Æ®ma‚.Ü?´wÿÖz‹ïûƉ'Ò‰.’’H@\³‚¥H#!-‚¨ÖiÈ]ƒ`@ €çH J!`L©=JjµÒ5׿!üóñ`E6·øÄß|âSW¼îúåõ6rMÄ.àäøôу_™9|Ò@ä¯{ýKo¾¡g©göI¦IÕtØœh‚¥´µyìÙùGîøM¿òkï¼ã7øÖç¾ÿõ¯,ãŽÓœ_EÚ²œÁ¨›X[V…§CŽç.ÃÃ1¼LÄ®eÖQÂVraÍÏ4wOá—ÜxÁ÷¾~Ö­Ññ=¾cUbr’‚€d\òfÚÙHN]›˜¨½ä¦½<í±Xì’—L<ûàâ™'ZCCŽ×G, ó b¤ c­I¤¡Ýv ›c„A $©Hc@X“®¾øÀ ÿͺýT<ËNž{òCúȉ§×;݇’8RJ9ýU%äúÂêĶ­·¾ùÕ7¼òÚú F¶œŸL¡‹­™:É…RÚ–‰‚€~äàwý²8¿z_P«¿à–‰-{^uüð©vÏ~t­•w ç·}ìaÞkÍq“í¸ªb€r ƒí -ƒ4Ó&ÇÏlÜþŽ æÎ­Ÿ}ªá{”[‰Ç)RÄ:¡† i;ë®G'O5ºŒ_¸(²Úí¤#eaYZEÙ/ôÎõ4éàJ€Ë%S( i#‚`¦| q%2}g¹• ©óLJ—}̹v*ã×ßúnÇ«ü›¥{îÏ+;óõ¯~ýA› >󸩥鳔/²œi‘Þú¶_zÙÛo«ô•8írh$G4ÌE£œ€FÒ1Wݴ϶gN¯þ×ßúâ/¼éÚË_~I+IŒ|Û§³áºìó‹îÀ(ݱm²ä•„îtb¾ºÒ¼å·÷4:©íšUÛ¢¦¶- ˆ,)Fšißð—ŽçŸüØ3ãS•‹ YUT (Í•ê!SѵÕÞSGVf’+^:~ÁÕƒ=hƒÌe' GJ™eMÓD­Ìñf³Ð(B‘*ôiVªØò *˜P¨à(‰%¸ä!J5T©_|㯿õ}ÿ¬Ç‡Rj¾uìs_ûüØîìÙ÷¢Þv;؎ȳ>B?ó…pGë( ¡ˆÁ””šLæ2×J#!tÂsŠx™bÀ æƒ÷g›(¯Î-BÉ`B†í4𜸻°÷ê×î¾ljåÜLÎÔÆÚrV´›ÅU¯˜HÚ‰½z¹D!gE‘IN°$Hг˜§y<º½rá¥˳ÝîFTBÄe`8ë&a··4­73Œ‰åPŒ V:ë1(„ë’¬Ã5—–‰· Ñ-ýÖz«H3aX(ëIÓÔ€tK ¨T¦+kÌ0m!ËÄ\¨$Ö£“ßüÚÿôÃ`<÷3ËÇ¿}⛕m“Îd}6Ÿ/W*nŸ4(Ávݨµ¶Ø¾€(€)]ªPEYA¤Rq¦ÉxÁhÁ{‹SÇW.ºt‹Ö¬Û‰}ó}äÚˆ(ÞÝÙŸºê¥[¼àÊÖjXiþí?É i!‚†œ#€kHa­¤äLb(TØÊ^~óÎÏüðÊ\ÛvKݘƒ@ݵµvž©ÉÝÕ¹sÉÊR·6µÖ‚ C”šEK¥˜êô4€89% DC!™¸Àiƒâ¨'c"ÏÆ„’@Œþ7¿ë·k[È>—«ÍùûŸýÖjTôíØÉŠ±È¼žRÈU% ;¡I ÏlmN…* ˜ŽRHÌ (¸P…B ¤Y`üúéÙÓk·¾eKs×"TKK.xŠ’vV‹yÅ3dÆQ¶Bkb÷ØàèôÜ©öo˜j¬vI! µ’@1…$a@Xên7­–Èõ/Ýyÿ=§Ît}'1ït»f ·lu¶ï\[_\_LvDå\0¢J…âÒ ( …ÁA 8 \i@à8ƒÎ¤ô +Ì90¡,‚ ¢—œA˜ÒßúÝ;¯¸îö¾†Ï™‡”ü³w|.ïºÃãÚ­Ò:wMŒdNQjy>pejÍU.•Îp¯ƦG9(Tä0åÀ„VBàÒœæbq®íº–gÀµí›yÌâ:FžÛ÷ÔÁÃ^~ž¨u­Ý¥%rù‹¯üôG¿²q¾W¤íÙl„"šçBs ´Ð ‘mQ+¦혪?ÚXˆÖ,íð‡v`·‚ƒ~ñÕ}¿¼pþTXîW6F¡רÄAJ`,Џֶƒ‹Bʼn*y µb ŽLSCK©4è4G¯{ã/»õ͘?|Ÿ³ý݇Ž}óËßù'd;ÕñaÀ4(Pî;´ØUIIÁ Ç·²^ÄÓ8j´Š^OKr–e‚¼*Óy$ÃVv’jͱM‹3›I´‡ëIº‘ò¨¨Øèèó¶eÑ «ýNØíî¿l˜GZ0.b®R©¹®±@ˆ#`@ÒR).„à®*MÒrjweßåcÕrÍ–*Þ¹¿b˜dq:ÉC‘ÇBk@ ’žÔJ3‚ƒÖ „Bå™jtDÁµëb  þß§"!4+t‘ëË_øò7¼ý˜Ú?RŸ›ññÌô#ÓÙ‘Ë_v7‰"`»¦cK +¤r*!¤¥F@-Üm6»kËg~Ùä±P…Fi¡Ò”­ó”ËHDi†‘Þ½w$éIeä€5 ­ ‘ëtúüÙ ¯j:¶•çˆe" {kËgÞùk7â£_Ú6j ¥p€×DV…2(± œekgEs=nld3g“n[¸®²ïš P†Íµ”(1u8:áÌ;+ª\ÑØ@HiQh›‚(´Æ€˜TމV2Íõð V4 BiŒÖ€%¹~ÑKoy÷ûï¬ôOü¨•|<²"{àôw†/j=1=¶Å:d\(c}8€eÖsÀ‘–²l³ÑXæ×L å]D1€Öš À…Hó‚…²äØÓgÎMêõr3d¦€‘ÖJj.ÑË“I’ oLWl”:mi”;KKOï¾ht÷Å•ïioÙæleœuL“ÄRɲ¼ÝJæg¢0~ÙŒCd–Cæ–äºÈŠBvwlw¦Ÿ +¡fj(‹‚R¨È5!P Æ€Ö»š¥¶‡•VaªlƒX& #^dä–ÛßøŽ÷ÿA¥>þcó9ð¸ÿ¡ÏFYä,ÔÓV@ˆ%¼º![ÄeH‚ `¢( Ó³Gfë#ÁÐhɤ @ )  d*Úw½áÑò#÷F[«BrD´–\hPX1°ê¥)çi”u•€f<†”>õôÌe× ýýSg¸”€ŠÁA_{r]3Ëò4+šdy)$÷_æVmq~q˜Å¡±mRKèu³²OëU3Iò4Öà‚I°TRp ´@˜ L‘ïJÅdBµ#EMÂ5(.,×}ë/¿ý–_þM¿2òãó'õX^=óÀcŸ½æUÿ©ÕK†‡eR¤4Fà 4Çœ!.¢nÛVêTºëÑñí}»/ð<ßL‹<ÇÒ¨Ú¹ÄtŽ>v“Kö ‰"G)…¤THK­å…ÂÈò‘eá^'-’’M4VZ¥Lq  ®}ñÖÇ\œ?!®ë}žažð0f‹KÝN7ß²Õ½èµÑ-ÖÒ¢%¤LSg©1(í¡!y`°ñaûèɼÛÖ¦‰ÒLi®„&µMAH„¶ÚKU»'üÀÄ []ÖW«¾ç½¿qýÍïr¼¾»ž?©Ç·ïÿë @;†w{âÛsçæ.¿hY1•J“ÔBÂŽ²´ä3%ó4{öèôïÿù¯>ýø3ßüìÃÏ>S-¹}ý~mºƒŽUØÄ1NžylºT2…`LH„°ÆXi‚ƒbÍe–×ì´c!’8ÂQ­”irïé¥óIÒC#Þz#[Ûȉ¡¯zñÀ® «¤lO{±I-š3õ„!$I‘.€g rÕÈãÛjîF;uK”z 5` ¦L ™„Ä=é:”P&,ðMDZ×Q¥Vºã}xé­ï³ìÒORÏŸÈc½yìLçŒ^{1û¢ácŸ?Ñë5_û¾7D™²ê…°›IYVÐYL¨ò:x°4ˆgÖNxéÈ _vÛáC§Ž{ª¹¸šÍ,ðBóɽƵ¯˜Ø2(”JšB¨«M÷– ^pLÌLÄòŒK.¹LÒÞžæés Xà)e˜smZF_ÙŒNA#-+¾Ñéå¡o{óÛn¼ýý†ü„ÿorçwþ¸[#â‘£{¶ÓÂ;_¹*ת“¥«®Ú÷ýO|èëOVHÙ¯6Â,_*ZI´”VÉàÁ/Þ=µg˜zaz¡Ûíõ Ø;w_Ú¿cG­êX襙ìÜ©–ç™õºÇ¤àR`4p%(‰`Œ4BÁuñÒ\è»F­lYfQ Rš°Tj)ã^& -”Þh²NW츚¾ì݃}cƒ1Ïža“Gá[•%­ÕÔ1m?8Ö¼PY¤%QH ª—‚CQÙ'Q¤ ¦Êž€0 „Aj¹uÔÌRgô×>xç­¿ô;ÔtòÅøÇ­öé3ö÷ï®NÔyâˆJJ#eûCŸû?¿ö×_ýÜß|Úÿ|°õÊ›ß °kY™L?~$í•z¹ÈrÜm¥ÍåO‹r`Ökî–©ê{ú*•ò‡ÿð‰u.5lÉ%0øÁÇ>,Ô@J …™œpŽú$lf]Ç\#ê0×ÃBHŒ’:ËÄÌÙ®_6ÇÜ\仦I²X® P²¤¥LŸ¹fçefŽe¨K† -m`THAè3-Ï,eQ ;'­’O6:…çày.ÂT\îßãž>—Swëû›Ïî}Á+&ÏÕkõéÑì¬~ñЧFöߨîÄ3G§cÈ4 ï‚ ÙɧŸrm~àúúÞý£õjpä¾Ù¯|ú¡ÖZwÛ¾AË%Ži–j–ã˜JIj`©T!¸ØÄ$œK.ÕÂl£T71Æ”`Á•ˆ°  HV”LxÜÃþÙé(Ï¥e„Wjm5;v¼·ugpÛk'o~Ë„éÕ¿ðÉ' c†…±4‹XðX¤ÝB$(47“ÊBF AqmR䨨¢D ”$jy]8Ý¿£,$:¿a ¶ Û&Œ¹E6¶íú?þاF&ö=·²?æ|u÷¡­A…X¥«oºþ•öλ|#ï“úaÄjUsvþ¬>ݶ•;¶%ø•_}•âÿþ“¯5–z{Œ+%òX{%K%9“N`ÅYJ§¦vû3§ì¸Ñ*bJ{މ™"(Ž8I‘ÆŠŸ¯ºbË‘ã«çWÒ‚«4Ï·ï.¿õS»÷ÖÒ„'J=öøªè·8ÓQ‡»”÷6r,…Ì…Ê9‹9UžmVPJK­()ÁqŒ0Òkë0ëNœ²^̃˜‚ÑácÅí¿øæ_ýÍ?uƒþçü(ïÇñ8¿r”›qŒVŸªÖGR6Rb½”CÚk®†¦‰’‚{žbY¾ÖÍ#¢¶nëÿÅ÷½à}xáäùñ­}Žmƒà¾E5¶A+¡’§|xÀß1é{º»}´\¤ÐD#L€JucÉrƒKÜ‹ùâôÚìl¦µšÚïÝtûØÔž’‚¬ ÝV 9£ÍõTruóîµ(Ì2•ÇÏ ƒæ˜sU+ÁÚšb©tbhmxxq‰_{¶;ƒU‹+ž¹e9²Ñ•%ÚFõ>ôû׿òÿúg¬~vZCh´ÂÄêuºNŸ&«±­L.•®gWüŠ»±°D,ÇÌ'ȫۄ«ÕNsrOí¶7îÿΗŸ•\nÛÕWëó Š™PÁ„–R+ePÜ^ wl«­ÌƳgšý}žày¦R*¹ž$y»+Â-.å®gž›NÇwy×Ý´ubÙ·‡I–g9Á*: ÅúR¬„B,QªP™d2Q ”mhÅUK¬ ¿JY.ëe´¶ML°zúxæØä†ËJy!¨‚©8çB)×E»¶Ù»ö\÷¦;>2:±ç§×ò#{$¼Ù2Ã\.0–8{lÃeÑ–ºq~f8ƒ”Ò"£®cSb3ç ¦ãùðÀúhÿ¥ŸýÔ‘¨]| ß÷mB‘åP›â˜«<,aÂ$z÷TíWÂŽØ9(Lˆf'kwX^pâ†á½öW|ïÞg§ûo­ï(gf¼ÒŠÝ±èmXè¥ Ê& ¨F ¡ÐŠÉ4‘Z(-A A1í§žaØÔXXKÛÝbjÂq,‰)³±Znä‚CµJ†,®Í½W¼îmïùÝjmø§Ú!õ#{,¦Éy<}ül¶¾l ”ZsÍ€(WÊV«§2ä™ök£Ž*,èõU„ièfC·›ùr++{Î{î¸èïþîäý«ÑÕ× ž³ÜM Eå’í›D*ÕëŠ,Í1 ÷VÏë=ÛÖ¥¹ª†¶ù“;Êe´¶õº[÷ýåŸ|ì‚R0b­m´l„´–ód]0M +n36 jbv¹60% ¤â9 \ QªYB¨^ž]|vo53VØ |tfV”\|ùþz–‰6Ÿz×»?xÙµ¯¢Ôúi·þhý \ð/.9µºQÝZZ>yÿÊÑÃ#Ûª*î:Ónɉ…}zšô ŽPìŒnñ"%‘a‘,¥Il˜‘f™ ”–ï¹gfa>Ú>U­×B0çBJ)¸Â€¤PfÅŒK@® Zƒ£þè}40 ­µ —íÚÿ•Ï=ôÍ»Ž]yËDe õº@SY°¢Ë‰À<‘©$ß»Ž;´#–Z1È5EÈ2€®@*ŒH§'—ÖåÄ 99lRSô›½4_\)”†‰asvY½ðeoùÀo~°Ú¿ãgÓèü£ÙÆñt´ÞìY›Å85zK2 GÊÁ~k¤V¾ÿž³¦(¥Ã&ò XDò¤`‰á2`…`™äˆi¤—îíw=7Ýi®&®CÒZ¢8åi!1Û¡}Ãþø¶ÒÀdž‘p‘™Y4×`Z¦[¡G[#€ jÒÎFPN5ÂCDyGk@åˆåº¯nð<5á©¢D#A!.´Æ`†H7f‚é+÷8uÈŠ\!=½”öUŒÑAsvž±õ?ÿá¯Ýðª·ý,oÉü¿ÔÍןnyì»KÛ®l­,LlÙz>›[oÏOMéQÏ §ÓTê‹·ÕN9Á”, ´eƇ1Ýà^ZÄž@Ô6 – Ù#ó+aÔÝž_ÈL LŸ}NiÈ-*' å>»oÔw³•J) „pÜÍÌL§1G½ûijÝfxÈ£%1<â¦=ÇÒ2͸­ŠT©\?‹@J™%\ Œ€Ê¹@ž*>± B±˜G! }dae ,j¤(D{E¾ù–Û^ý¿~¤<8õÏ~5ìy1_ÝõÝ¿úöCÿ‘K‚°µ26¬Ÿš=ìmxC mÀnìü|K°KfU'`#$ hIÔë)ˆe8MRº²^p¥‡&J¥!ÇðÈÀTÉîW¦ˆY!”P£4œi-‘d(j¥"Åí>w¢AMt鋇,S*–Z¡8,6–‹<¢€´«(A†RHÛDž ¾OJ60H¡0¡"Q¾M›$B5Cnšhh”lm™}7ÝúöWüÒïÿŒ%~4(_>Ö9öø½OÍŸ›û^­_Ï–Ú͹UÅJª5‹eŒ'Â$¸VqfN¶<Ÿ&âBiÛ%¡ EªB¥Àw›3üø¡9Ë£#»ëõí%«l¸¾U’®ëZkBtg ç­µ(ìæ‚©"†,¢Hý(ìj¤*e/(£(LŸPŠ\Ø6¶mZòM“’(ÊÓŒ{&¶,@ (BZ*Š‘IJh DºÄÎŬ¿ûSQ¼ä ïúý‹_p#üœòCÍWZ«ÕÞ׃5ÑZ;%ƒ@*Õ&Ö$ʳ,_[i-ÌuçÏÆ¼º\ƒÀ§;ö—÷îëß6ä9 '·ÛÍž’htTÛ&÷¬$ø0Δ⠨çh‹ÁŠ1E !ŒRJSÓÈDEA¨ºtÊ SuõM¿}ý­¿R©ÀÏ/?”‡Pb¥h¡ò¶¦Ìwîß•±«—N?uþÙi „[¢I$•k°¼@BŒ¸¼™+$˜ÂqÄÒ\ “Z4Ó~‘¹–aaä×­$d•vÉÇÕ’!CÖ˺~ÕOò¨¯fI‘ç,K „ѾýÞÀíy”PU*QÃ&ë‹ëG×Rjb’^0e†]¡¸–L ®óâLj­¥FBIJã# LB4`B¦LS‚Mƒ(„•’ÔÖcýDÁ›~ãcû¯~-ü¼óCÌWî;û宎í_ ›§çŽôowìΗÿìwÓÖRݯ.žêå>w=]  DÍx‰ 9y.–ˆ6ƒ€…*”¹&&©B§‘Hz&˜¦‰j4sÇ6#3×7, û> bÛXJ)¹`…”B¥™0 ¬ !8`„4PV¹ÖRS‚×At%  ¡4AÈ ˆ ´ 4Ê$`ƒoÝb8Žû¦wü?W¾ðvxäß³«Óž;½uÿ ´ºÐ9sîÜa„*ãcõñ öûþ’$"裼†«©[&–­OS^(í¸$ì0 ÄvŒX¬$A …òºoWÉ¢dc5+\wí0ä ¡ÒxÍrˆŠ2+µ)°I‰D¬ œ)„‘(R€BJ¤™ÔޤP À@†Ö(©)BÔ@¦0Œ‘T:ËdÁU¹å )UßrÇ_\ràFx~äßöxbù8­fwZ‹ççžeyØë­Õ*f¥o” %…S†IðbŠ7ÖrÃFÄÐ禥.ÚëK-Ù±¢H¤©QŽ´ã¥€ú <$@Š‚õQ%už«4ÖPH(²å™PB ®‘ƒ`)”d DR\çB‚©”V€¢0B%ˆ Ź&!@Z#ŒÁ25ÆZ#­‘.˜d\r¡ƒ[þ/½í#û/}ºwÿíð|ʿᡓEºxì™™³ÏNîºø¢}ßÿÖÝâdÅ ¡ ã#ÏZQ¸È"Á² 4f9³$¦J%¢ž‘¤Œ:R*Õ‰s@T1‘K”Ç Spœ"¥”TZK©WBèJ™„âH*H)! À °h¥©¡-CK© ¦•‚|6’",„Ô 96 ˜’ƒÖZ Mˆ¶Œ@è¾*1@ë`ð‚wýê_íÜy5<ÏBÿÕŽÙεÎj½ëæë&¶í6>÷ÔìégÖ¬U,ú?Ø{×Ë®ëLl­µ÷>{î³nUݪê®gWõƒý$)R¢Ä‘-ÓÆÙ1l8™ $“É ’üËßü ‚`c3Á 2@âAf<žqd;–(‰âC|“M6Ùï®î®GW×û}Ÿçœ½÷Zùq[Š"›”-{HeÖ¯BáÜ{ÏÙßÙëñ­ÇÖQ¶wÛ’y±\­™üжš™QäâÒ;©µÖ“‘ñ:mïæí£ vö±ß•ÍE* 01 1D1ý=â­X+$¢02z'Þ0"€ÇF‘õKt€š@z]7PS¥„ÒŒ‹åáÿæïþãÙÏŸ†¸{uMgN©F ±IÃ3Ç/\ãÙÝ{{Íå弩#A9ñÞzÐ@kŒ]‹ÅÇãT¦#(Ö°¤ó€ì+Èr k!ÏA,FZ+E˜YèdE˜Q|.ˆH€,„è¼8Z4€h Z‰F`Ïâ¼SqÞ³ È"ZÏF£&tV²Ô† 1Õ*&)Uÿ£ÿâïÏžü<‚ñ)xÚ½M½¿`²mL«­j&“Ú©ÇÏ}ëwÚÍurm•:êå7ß¾îmª4gí4‰h`8è¶r%gÂG¢“í.F¡21 @Œ]ÎÍ–òH˜¥Ì Œ ( Ì °ý‹hB @BÃ"D=+‚ ˆ@¨s@+¢Š‹@çì¹×îúÄðLŽ `hø¿õÏœý|^åaxlØû*[ÙZôNªf³kÂ$.W‹#C››ëµzyð¨v{û÷Kw/ïÍ&vÛ*BÞ±ÆP«e3ÏQHº9Aš XËÂ"¬"2Fƒw"9*B@ðXÀ±8¤€r/Š(2èRvˆˆH‚HV$ÏœXVØ[.œÕcƒÒ³É¯ýúÿ|ús Ƨ౩5v§½qÿ~©VªInY¤۶izxí͵#G“P¥ñ+Ô ¹›¶;64 Q S,ò<íõòƒ¶ïåR-¡è‡cLÅ„âXB΢ MˆHÀ"Î" ‚AòžE PDP![±ž )DF@ìÅz0ÂDç€Y¬Ï„‘ÂHªeÁ„î6ƒßøööñßC€/$·¶nÝóûåâ´êŒíÏ/ð`ÖMv»Ý¬—ë¯|ë÷ê•còOþåÍõJÒÃ}kÃbÙ¤½ç¹ ‰ (Ÿ)I´óäXzmË$À"„ Š€Í¸gÅ3k… @D„X”cH‘"pN@¢ Ð3°@€ˆº_0ˆýõˆ€È&ôäT–BµŠQEÖ2ùõoýíßþÝÿQë¾ xÌ,tª$ƒ?ö{+»wn½Ñn¯Ç¥øoþ'¿U+k}õ‰KÏ}ßu\¬¢¸V0vv[½Ã4e­ÐfÂP80Â!¡°Øœq’õ˜HA ÑYqV@h… Î *…ÂÒIY”A 2{BD$$d†,ó̬µ— ÉöäÌWžúÏÿ«ÿ5Ëð¹—Ç£ÙnÞon»òÀA×–jOûw:½íýõ7¾ù夭߽QˆKSÓ |éØê­ÛI”4{¦×N™µŸgȲßM‚˜îƒeŒ*&Úhè6}†^+–ܲw’± !h€¾Êê“j„(YÊž E($މ°ÿaçÄ{qV3Š(öŸ{˜~lòïþ·¿_*Öà‹ ÇNwëÚ÷Á™<^ƒñÝBÕýêúæÎ½­•嫯¿Å(öí´1è⌖®oµsÎs A,ŽAœ¥…Y! # „J…‘Ï­Ø\´!£Q˜Á ‚°F­HaAD°^@ÀhÈrFDE@؉hi.Dje¢6ØÍ|žy`¹Ã@IbT0ßúÖßùìÇc~Nñ £Zqýζ ãÁr³Õ)ÇQfaùîæáþ>èŽK»é^s| |îäèÁòÞV·gˆ‘½€H¹bºÇ– ‰ yÆnæ502{/ Z!¢" ƈÀ3?˜kG€Fô €È€„ý 8ç[¹ˆh…α³RitrO|õWžùÖ‰€_<>žo¿Ÿ.^UËó·ZÛ›½x°é]ZRG‡î^}ý‡ßÝÝ^ñY7‰$Èp´T”.Ükw[­ÌõÈûзŠ´Û¶×í?B_GyÑ}«€ €ƒ B¨@!8´Ou@hH!"Rh49/HHβgèv=hBï™ A0.*Óÿö¿ü‘oÀG>~´³C6ÙøäèÎÆõûï- †lñh}jbäzup«™³n¤¾•wö»ä8ó¨Pkð™E„v+Sh‡a”ÈÖF–e‚Ô7 ÒñY€<# d´BkÅ:шÆÐ@Ÿ[" 4å ±‡Ì 0 µ1F€¥€bJúËÏüÆìɯÃJ>ïÝÆÎZ§Ú$cZ{«‹wÒÀA;~?owò¤‚CS#íÃNÖîõŒ{­öö!°Ï;½´Ã$ œu]gE8Œ0ŒŒÖàz¥€cðýñ €Z!#xÏ °?j‹ÒŠØ !2 ˜Ð ’BÆëÝîA{uç`osáÌgÇOüO7.¿µsïNs¹½¹A;΢­®ó]…6L´‰Ã€¢ÁaéYÁD@cl:o3ÍŒ…XÄza&/`˜~@  °:p Z"9f‹X @Äyö^5‰týøO Žý2àá½ßÞÚ½s}¹µ{pâ܉ÑSãiŸ8_Own^~áí…‹7c­É gÖ[‡ûëyר,s¹H†Ò̉°ž­S v‚šB"«@4!(P„ZƒBñ^@€h`­Ð3 2z@ °°€ ­eo%s€ ÀN )Ìr†j), WÆŽL¨_PÙ¿k<Øïlìm.ot:½…ù¥C÷¯7ÖVˉ)k74T?*µv÷x1Þ9ÔÚlng‘r¤Ñ;ö<æÎ‰õBH¨4!b`(Ðè½hñ^Øö©EPˆH(D@JŠ ¢€( 븗0hB`@¥!°Ó,•ÃÚ@­>v$ â^¯­”þb™ÁC)’ÝÝÃcgN›Z_}zÍýÝ|ã Y.ëgþÖñw^½uåÝUñbsä<$Ь=ˆd€\âHy)$ðÎç9;'¾Ç¥’"ÅÞsßÃB$DR,ìQ„ •!vÒm³R °xOâ¼hŠPDX’‚ªVK•ÚàðÀQÉecíîÌìù/<„4>5ù·þöïM:—ùæÛÏuö6=佃֡ =P)d9 `B0Þ¶²vj}.„˜u…-÷D˜Å‰‚  Z„ÑæÞ:A…ÀÂ@@â­£Æ>{ò ÷lÁ3‚ ³àY²LBð€mDÏâ¼h½T’Å‘q’j’ ”+{;«cGf‹¥ð‹‡K¥¯}éi0ñþþ’²æ`e_©øŽKµëÅ›÷2ç4°òœõ gÉ©+àÀh²;Tzmg ‰$T((dpÈ`8 0ˆJ£*Ñ €„( sœgb fÖ;/•‚!¶Ö±eÁŸ(7RX+h¥ˆL!JJq¡\HŠI±&Ìû{ëI±ŠH_`<4)èú½µ½Nïàpenz4ß\¸¿rè½=\OÛeï¬Î:˜eŽAy­@ƒbÏ>£°}˜• &GŸ;ð,ì@€€™a£ÅZ/ô "y.DÀŠYz)€Q@ K"ÂÀq–KæòÔÍA‚ŒÆ 0¨UžƒJµ^j„…j±4P*  eïl–vèðEäcð0Ú Åwövw·w·¶æªùÈhusm«ÛL»]é4»âQ“&¥Àå xöŠ™•&ö’f^iDñ"‚È€ŽÅæ¡ñ˜¹ñ ) ðA™ˆ xE¨±€w ÖsÖ@Ïç,": ­u”„Åb‚J ˜b±:Ôh”˵¡Ñ©j}´Zk”+CAgiG)­MøIG<|îí9©ÑÊðûWÞØÝ\ßÙ^›[’uã(ñÞ;›öRg}žfD*0† ÈD™½€°ä(Ê!„Yë$w¬4¡RÀ¾ïà¢BéW®8A4„ Ðê²x Ò§Ö؃gñ ˆh],‚( ð”L’ŠêõúÀàh}°12:>دÖG I©”•6_l}±Žò½½GNNï¬Þ¼þî2‰K;ÎgàEäÅ“€òló4Ï„A˜Y@Bp¬HP ‘PÀ;èŸ C„‚Ìè Á;1Bä½wެcñâ¼°—8Ô&&Q„…Áb¥fŒ¤X,ËÕêàÈØÄÈèxcl²>8EqR¬˜à‹dÌ?‘O…ŒWnÝi4zkKíÃ]ë¼õÖæ#ƒ³â2`ôFÑœg Æ  ¢' ÀYvV¼@@­)·Ì&B`…„Ô?ü D@^jEÄ"€Ì:f0 cCZ)­ƒ ŠÂ$ ¢¤X¬$ÅrFÆIR=R®7ŽŸ©Të¥r5ã/„‚úLx”K•'Î?ñgÏÿqǶÊÅz¬T«·×íX@N›–œV Ø‹â8 aîÀ;DE€Z¡&væ g À 03Z+ Ø„ýò[P„¤QkÅ‚Çq‚8âB\(Al‚¨PHêÃåJ}hxtxt¼>8R,W¾p4â§çÏÏ?{çêK»{n£¹#¡I` ÃA†i‡;½^êm®#±9Ø Ñ+bk÷Ó@@CÂ^)43HŽŠQXPB?¡¤P‘V†£Â(ô®?I8ÌS H…0,Äq¡T+U e‚P™ .£¸X© VkCµúp}°Q,UKåÁVÖÿñú›ßÿÊ 6m6Û­n§Óévºv«×í¤išv3›;gÙ9ï•­)s,¡Ñ€‚À ¬ )BDBT$DèShH)h£B†¬AåÎ) ¢¸à­ ÃB\(aDHÅr¹˜”M`¥V/U’¤R­ 6F' I©\©~¡Á€‡×_>õ¥íÍÛ›;‹¤T¢0Ñt"Ť”öÒ^7Ísksë ¤ÖæÞs#iƒ€"ÌÞZÑJC!*%,À„ˆG$f Ã0Š …¸Lh‚ˆ½ Òq\$Rq”˜ ôÞ’¤P(Æ…b±TÑ:(–ªI©R® Dq1)–«µA­ |ñåax”еãs:ßêö² Hê†a¡T®¦½´ÝlÕÂ4Ë|–yqè{Yž9ïÙ{aAÔÂŒ,žeÆh­€úæD+¥c´µ®˜”•¬·QRbçIk­ © â âB’Ë}Fq'A‹•¾GEñ/ð©ýjöþµk?ÚÞÛAç\«ÕiîtºÝ ˆéðð€”êµlÞÕ ³,³¹Í²D¼gTJŠDQ†¡6JDÙ¡Ö&âb©’öºZQ!A¥ƒ0zà‹DQbL¨´IŠåR©ª ‚0Œ’(Š I9Â0*„QôŵÞ?7Ì~cc~}}ÁZ×K{ÝN'íeÖZv» "J)ñ6‚´Ûu.ϲžwÎ{QßÙ ÂHØgi·T®9k=;c¥ƒ ˆ4ÒJAaHì™”Ž EöÅ…BR ÃÈaÆAš ¾háÅ_pÎnnÞmµöó<Ïó´Óéä¹õÖ)m¼w¹Í)Mä½óÎ!³OÓ”½ã"y› R*…DÊ9k‚PkÌ„±0³°R&à ˆ•ÖÆ„Î;­DŠ Å ƒ0R¤Hi­ ‚_¦mñsàiÚé´÷²,Íò,K»¹µì=)ÍÌÎæÞû0Œ ÁÚ<0¡sÖ9›¥=fÖZ÷ƒ=¥"i­úŠ^)m‚‘D$Ï3¥ôû<ˆÂ( ‚™µ I‘ÖRZkƒˆD„HJim~‘Öbggõòû϶š›ÃSç/8<8¶»¿óÜ˯¿ñæa¯W1A033sâĉ .œ?¾V«ý5«¬_ }§Ù{»¿¿¦`µ:þKH|à…?d9D¤ÓÙët›ÒWâ¸X,>|£¨¬Õԥ˫WX¸96RvNnÞêX›$IrêÔ©sçÎÍÍÍ8q¢V«}Æ[‘{DÐé®/-Ü@`` "xŒãRcä\WÊå¡_Xüñž‘Y÷—¬·Q¤v¶¯¯Þ_Óº¹»»é"8¤Åê‘(œš¿008ý‘g臇ý`Û{׿‹íÍ»–}žïmmܨV5Kåøñoc>Xâþ•YÖ¾qãù<Ýj.t;-”B~o\,$åÉѱó§N~íc߃½½½K—.­¬¬,...,,ìïïgYæœá£Gk_~òT}àøùGŸln¥éæöúϾÛÙbßšä áWÏ=þ»I’„áÇ0ÇyžÎÏ¿yåMvY¯³Y‹½,+aâÈThçÄÚÜ³àƒ¨™™¥ÓÎêõrÄQ¼üÆk]{njêÜW¾ò•O‚äçÃãà`y~þûÛó¥„êå£J yëœçæa+tÌŒÖ2¡V&`ɮ߸¹¹ÿÍßø{ÓÓ³DtóÚŸ¬¯??64vØLK‰2F%ZZë­ó œ’ï¿ôÊ¥+ùÙ3£ã£šÀUJ¥8 {]"5þ¤©Ÿã<–õõKï_úŸnNtâÅ9çòÌzñ ¢‰÷ÂbŒ@a畦Ƨ¶v®\»†ƒ###[í·Þø1)_І …Ä[v"œåy–çÌ€`eëq½§ŸHjŤì,ôºyRŠÊ¥(·®›f"LJ  ÒÄxë½ U—–n,ÞÛ®VÇêõ:3¿öÆö6nžÞ‰òŠ$hTˉƀ™»]»tïÞ÷Ÿ¿¥uñܹsŽÉ7·ÞxíÿZ¼ýüØ`0Ra¯;tow_(—J…wkk»$b¦¦¦ŠÅâ_Ö¿:<¼÷þ{ÿºéê°u)³gò*2¡eûúÛ¯\¹rwßW*áÄxinf|òÈñr)J{©OsPŽ9ÑåÓ''Þ¸øú•+3'Ož:ÖåŒmæ”ÐŽ” z™¡r¹\­Vû~ùòæ¯={þ‘£ÍÁA³“¦F™Z­ÁagïG?~îõ·—ï¯y£yf*9y|ôÌ©ÙÑÆPã4ËØÛ( n-^{ñ•››[ €~ä‘G.\¸pìØ±BáiãO×WÎeo¾ùö ç6õ¾ßЄ {«/¾üÖ_X¼·RØ?7·ðîbgeýžVùñc³‡ÍƒhEZ)¶¹o ­mÜÞØ’ññc•JQïìòüÝ›ÃCª^md6CB$â³4ïu2ölB £ ŠM* ãåõÛßùîÅ_Z»zsscëžF71>aó\@”R}Ç·ï€FA°Ûܾyë`ddj||¼ÙlözùÒ½ÍVsí‘S³6w ŒˆBš´Ý^^ZYÉOŸ>áÂcÌÎÎêÍ›8>RÑÍýDqEA¹Z^ÛØúá‹oýðùµÈæ!bus‹oÎoݸ³¼±q´o4êq”¤Yó/\ºr‚>.\8{ö¬ùä|Ú§ï›·^<ܾ}æÔé4K­u ˆ‚ t’¿üêåï?·Ÿe5cÌÑÑF­Vëv»[[ë/¿~{jrhnêT·×íö²¾Ã èY`âèÈ‹¯ÝXYyüë_ÿ:"Æq|ýzáwæg&kÒ,€$YÏyëKå‚1 º ˜$~ëÒ›/½zkiÑx_F(\¹Ú[]½¤5œ}ä|æ2"rÎ)¥`lh¢×»¼µµÕívggg{½³÷Ò-./L™Ê˜ Á{bñi–аw-€ð')Ñök¯ýŸ‰ij™@ð•JAÚ[—[ÙÜÚzö…7ß}o7KËI’ŒMOOçy~çÎÝýçVö/]}ë±s‹OåÑ; Ëï¾·'Rú0Ÿd9>yÞÛÝzëäìtnsö‘”Æ@™ ÐϽòê«oldY¥^¯Ÿ8qbnnn||üàà`mmíÖ­÷.^šŸ›žs^DÀ{î·ô³çÁÚX»µ´´´têÔ©Ç|hh(ŽÃ7ßZÞÚݪdiꤩ+ÄAé~úôÞÞ~e À^œuž‰Ÿ{ñõw/ífYyxx¸<=z´×ëÍÎÎnüD^zeáöÝW;]×jÆÇœ={öÂ… çÎ ‚à/Ÿ/-½ ¼oL½Ýi!¢1 •R·oüøÕÅÝÝJ£ÑxòÉ'çææNž<999™¦éÝ»w‹ÅâÕ+ÿÏÆæa¥R0Þ{(D`îeíímfÃpvv¶Ùl.-=rmutèHÊýV ÕíYafA/¯®¼ðÊí•{c‚³gÏž8qbvvÖS«UW–Ä™ûç†A(£(çìöööÐÐPÇ_[;wóÆÕ,ï ¨ÜÚ^7d@TyîëõzÇYÖ[[}õÔɱv»C Ùq–:Rd‚ðËï¿uq3˪ÃÃÃ}NåüùócccÖÚf³¹¹¹¹¾¾¾°°pÿþôüüüööv¹œœ88èÿ\£Ñ8~üÌʽé<“À‹xöI S`H*•J£ÑX\ºx°»:5üÈVs?4JX|d"–îõ›÷›Íòàà`‰ .Œ@ƒƒƒƒƒƒÓÓÓÓÓÓóóóõzýàà@k}üøñ'NÄqü—寶w0~Øjö¡ f¶YšONÂÉ“C'O˜£G×ïßeq“0… …§êb)î¦Y­‰Dú£yà#ôR¡P8ztòÚÕ8sÒíZÑDZSRŠÐh³²¾|íÖ®µÉ‰Çú`œ>}ºÏgÌÎN/ÝE@DαµžP™Ã Ü;”½Ã ˆ[ÿ6úEœ™™y#)±8D-"qEqÀ Ì^˜ X,ܼöÃcG‡Í6+mâ00ZÅQüîõ›7o¥J•çææ> ÆGçØ±c'OžìÿÇó³—ýEð¸ïí80½nª _À ù‰G}òQˆÂбõ­RA?zfI‰÷Îd¹ÝëvZB1îû<¦ÛI³ì§Dƒ‚" ÃÀà½õEúú{»[ªÑhÌÍÍõƒ©È¥íí»¤Ä{²yÆÀ  #¥µ/q¯¯¯f™/—Ëfã8.•*ž}·“æ¹-—Ç¢mÎýš#fv¾U«ÎµÛÍ(•Ö¹óÞK |ûöv/ fffŽ?>77÷U®ÕjŸ‘Žü9ðèõšõê‘4K•Bc(ͼÍ,"j4I¢ ÖŠ<*¥Ä©^žzï@)ÕoÑ`h@Ìs×÷y@«ýýµ^–ÿìÝ ¡1ÆÖ{§”r¹c`£µé{›ÖÇÇŽ{ä‘Gæææ>CDîÞ}éèÈ ‹‚@k‹^+€J)·°¼%R®T*üV†¥RQxßY "#(àEûÃ`ww!RMcT¿;­sJénz¸¼ºCT˜˜˜8~üøÌÌÌ_ßþ°ø¼XôÅ’‘^/k·31F…qjhMš¼0⃹"Z#‚0‚ ÖÚ˜0)â(N’B CïÑlïgÍÃzßJ)€üæ´ÒaÝÛØ\¾×I’âÈÈÈììì‡iŒ[·^ÏÓûã#G”"bf ba­) £Ë×®ÍÏé0 ‡††~Š„GÈz>ŒƒBhØC¿¶ËY÷“µZuÌz¥QHQ`Ìþ^w}ÃU*Õ‘‘‘‰‰ ­ÿzÏçì´÷š»+ñPƒ¬uyÎá²ô›hH©Q¼8öAè@#³R™ÁK3ÏìönÏYëÙ‡AX«é$,ÄØéµ˜ÕÏzD@$ "ê[¬……åNÛ=:422òáìéý•ï¾óÇSGÛ½4ψxçQ(çóëóˇÍx|¼144ôQî]€ Í, ³ Ï¼ó”;ˆcBa6J£pÜ?©¢ÕËÒŽkŒŒŒüÕ% õ'+«öÆÚA­<’¥™1ÆsÖI³b;ï^~ûË÷‰"Cä…IiöÜoHfÏ ª™öhgœõ@„Cƒ.IjµÂí»{åòÈÐÐÐGÞ/¥• ƒ€çYyE ˇÌÉÈÈÈÈÈÈ4F§³ÿþ{X‰Ú•ÒQ›åÞ{MH„¤•1*ƒ7ß~íòûˆƒF£Ñhü¬*G ï8·93 ¢µ¬ŒŠbÕî‚ 8”þÄLžE¼Ó¤Ä;£u£ÑýŒÎÒ/fVHÅ$ñ Àžmî!P¹S7o‰µ˜üg>ЇS:Í{Ÿ¤"fjª40004ôÓ™2ÏÈàt»i?~, îÆÞþAÕûx ¢ˆ,.]ºvùÏ5m:u¾ÝéôG#öÝ7ÅRòÞ•+Ï¿t{ï°X¯×gffFFF>²?æYž[a­Lc”Ò„ØŸ‹–f™ËÙ9ÅAÇ}2&ŽãŸN«ü5ækE„´AH%ˆL–ÙþŠÔka’H©4ù\l†ÃÃÃp™Y–mmmµÛm¤ÎÙG¢RI>’€C›»f³ÍN´QQ(´³ÕÛÚ‚z}°¯¬––Þ¿}ûù¼·TŠ‚±Æ©,ÏD„´&¥´‰t«WÞ|éG/ÜY^¢‰‰‰‰‰‰©©©,j¥”¢0TÞ?ÈD±1ŠÓ´m­UNºÝ´ÓJ¢À(M”¦yš÷G|Àg ë>"YÖ]Xx±1¤jõ§“¿ ¬0gÖF@ÁܦƒᡵÇÿÚÌÌÌC é¿J…BÁZ»½½}pp°³õndV»ÙVËÒÒÒØØØiç|/·q‘éÏCF$Rä9KŠÊº…wßýg‡{ Å8<9}âà°•¥)d¹vœƒÖÁ{¯_ÿÑËw÷¶Š‚zvvfnnnbbâãÉT"&­UšZ—§µZ:g7Ö÷ÊaÅJ% cƒÌ •Š£ø/VG|ûö[ ϰ·0ï†Ç‚rylzzú“@}DÌ’ ðÌD¦Y»ƒµ´Ù<˜šš:vìØÃ¼·Ÿ 566rñÓÚ[¼pæôëïdßûþËGîþæoþæx$%SJb•[g ¢¯Tƒ¯=U<ÒHµábýh}.Ël¯Ûu.Cйu½n^.†Å$YZö…+·ïd½^%‚ÉÉÉ .œ9s擼RD¥4€ˆ˜€zí¼Ùl³ ööv×7ö*S44Xî¤=k½g/^0€j%(–sy0¯ë3‰sù•«/ݾùÝ‘z2>:þÇß{í•7þüìÙÇÆÆÆ~n<Š¥!0 k%ŽŒ³e­µRªXŒB]ªÕööÖvww§§§?ÕóÛÛ[¹rù;û;7.œ>·¶±úÆÅÅkW]±8öÓeˆ,(,ð f*ÅÁo?óí ˆŒó™Ë­€·^ˆ”Ò*ÒŠP™P½s¸uíÆŽwcÅbñƒÒ©óçϲᕢ?EJi²¹eqY–Zk÷ö=è7PxÏ4<И¯Z›íîî6O5!YÖýþ÷ÿéáîÕ §'«å‘K×ßzåõ›·fgOýEãÁc`LšçA IkfFÄ4Ï'ŽÖïoÜY__ϲì!xt;{ï_þóÖÁµÓó§Ï!ãµÛwoÜh–J#årùÃ!z“Í­c H ˆÑz¯HYç* ä’ @Þy¥±ÕLã°pæäãßúõüÆ|69ñØéÓgÏŸ??55õIi!æþ¼kDT éPP©ÔØ=¸í,*õ j•:u²qñÝËkk_>qâÄCžZD.]¿þ]Û^üÚ—³Î3ä—ß_lµÔØèÀÃ}³OT‰ˆÄÕͽû€ÊzÏ”hägN™™6÷î]YZZú$.rqéâ‹/þ£Õ¥W§FFŽŒÎØ,Û=ܹqý¾p811qäÈ‘CÒ/·`á݈Hª›ílím“Ø:k½cïY|?/Ö@1©üÎð̯~m¬\Ú:yrvzzú!9C¤P÷G•öçuÄQÄ@Æ Ö uÔìªÃæºÒº¯o‘À1³³_:{nx¨»|ïîêêê'!±±qçùçÿÑ«0<=úènWD–ï/½m_Qqff¦Ñh<$ò0k|dìÑÛ‹žE£B…¨”6‰²,Ë3ûø¹cItûý˲²2ÿá6›› ‹¯þø…ßï­VM:=çœO{©ÖÁòòÂÂR/Iª333“““àÑ:Üê¶·H#0xçÙ €(À…;÷ÿÿ£þGÿïâ½E$ ¢@¡6JÚ{oo7{i¯—çð«_ûÚÔQûÒ‹ÿàÙgÿ¥µö“}¿~ƒ@ŸèT„e *¥3qíú}£wâ= ƒÏ]/Í¢ ~üÜØÞö^yåÏÚíæG¾vmíÖ÷¾û^yùB¶pêØì@¹‘÷º,L—¯,4ƒB!i4ÇŽ{ˆ‡öÐþóÒØÎ®ÛÙß>ÒM»Ì¢u;Ϝ۬=q~hkwýÍWÿþ¥øÈààX˜,Ï[ÍE-Yµ?’f½v«‰D¤)÷½w./5›ñäd­ÑhÌÌÌ| ‚7·W¬""Mž½wžˆt¨+µ¡vgð¥Ww¯ß|ùäÉë_~ôÌÉã'²,K³Øùn7 CæV)#¹MÏŸ~¬œ,ÜYþÁwþäðo<ý;##£Z5¼÷ŠTŸeQ•Ã09yîúÕqö̾¢XD´Rèeé±É³ÅâÚü‹ÿünž¿ð­É©3µ¡­­{7®=¿·ón±Ÿ=6Ç"ÞYϾ›æâE°3¿°é]0===22òpžñax”Ëåbñäüíùñ±£A€p–ºN;­—’$ÊSÛjæ#C“Ç&ÍÊýíÖ£0ŒB­Ë¬KA|§k … ƒµõûK÷ÚZWfffFGG?ì†:犅QÂþäfF­D´2…0(–gºÝî+¯®Ý¾ýòãÝ}ìÜ©ñ±IgíÞþ*ª°çv»Û<è‚´k«•¡¯?U»øÞÛÿêo~û7ÿ‡ééc¶½­ÖÞÞîêTcš€ˆÀ9påbY馦æÞ}w赋W¾ñÕ§ ³÷zñÞYËÕrý×uj{{ã`ÿ¥ÍÿY!!o[û¥ÇÎD&iµÛ{{Í0 ¢H÷:iµ\^ÝZ¹·’–ËG&'';öa-ýóá1888>þØo^­\yýñ3_Î2hw:ÚP!Ž@@EŠöš¤P<†Z­Tk‡(è=ÛÌA!PÚÜ\XÜÝ¥±±±ñññ8àZIžöº½¬Ýé’iåœÊÄ sÓ#<ÇñÊÊÊÒÒÒwŸ]½{wïk_Ù<{ò[¬VK€DŠ‚ ìvÜþn›û§ÕªÒ7žúêÅ«o}ï»ÿË̱gžyæw?ø¹,K R .CéEշۘă Õááa©TššzòÍ·þ…¦×~å+_Kó^¯—!"aß-ãN»•Ä¥áÁÆñièeÝnWÒ44½,%…Ƙn7Ëz¹° à[÷;3==<>>þ©Ýoú¡ünqbbâöí§^|ù»ìäøôygU} ŒHY–;ï£PG±Q€ÚP§·Zmctž?˜ô#‚"¢ˆu«½¿¸°•çÁÈÈÈäääÈÈOu¯†±Ò:ØmE‰‰cÃ""Œ‡‡žy晥¥¥»wï.--Ý¿¿øGßyïîùͳ§§Ž¬Óîôz™0WªDPD"ÒlvÒ4›x$R÷îßö_þáÍo}ó¿ëó;;óå’cvÞ3)²Î³g£!ÛÖÚÙÙ¹_yéµh|ã«ä.÷Î9ÇÖy"aJSvÜju[ít¨1@B–™=VËE¬*¥Ð˜àðpïæÝ-‘°ÑhŒŒŒ<|s| ˆ811177×l>ýÃ~|í`vzäØì—Ó®%ô¡Ö&PˆÈÖrS…Yj‹Å84‰@»ÆQ…Ñòúêòjž$ƒ}>î#-u­šäݰR‰Èy&"",EãÅÂs¹÷þé§Ÿ_YY¹}ûöõë×_yýö¥7wöZO\8Sˆ Þûþ€EÇÌ •J9O-œ:qüÂùèÍK/¿ûî&'/œ:uêà`«VQ&$ÂHÊ0a½X?65¼µÛêt:sssÛÛÛÛÛ;ú½7÷.œ=9>6¥ˆw°°ï¦.Íxhh \Áý½ÍÝ=›åŽH2×tn[+Z[ë®®¦¥Ò‘ÑÑÑF£ñ©ÕþŸÊ ž9sÆ9¯¼vñ½+W.¾»…ªVÇJAEQÐtóý¥åÃý}„ºR1Qlú»Yræ@)BÚÙoïïë±±¡ÑÑÑááá:ÇnßYi6wí ¿¿'ÍC—$ª\5ÕJÐK›Ýtgoo¯ß111Q«ÕnÝšŸ¿õÇzcþöÊñÙ£#Ãa¤EÀyO"Òíqnó͵µt¿•UÊï}ýëå©©©Á:ìl¯oì6›.sˆb¥Zˆ"ç½ÍÍͳgÏ?~¼Ûíégøö›o¿8;30s¬T)4˜‰õ²ýí½ÕÕ¬Ûqafùa·íZ]“gÂ^œ°W¨°Ý+œ81Üh4~öÁn<±_9Зùùù×ßÚavDh³ït·{šùAã“$’éééÑÑџݳa8±¶9úãßnu¼öm,híˆpd¤ýÁÍÔëõ'Ÿ|rhh¨^¯OLLÌÏÏ_º|ý½Ë Iq)2Jú¡ €÷ÐéØÜ {Ès€ƒƒ =ö´›•žßxû½åNú³€PaBBez½œ>}ZD±T*ݺuãÕ×7ßzçqµß/ïxoœ{ø"‘àíษáÄÄÄgdé?=ÉÕ‡’$_XXØÝÝ‘,Ëú@¡ †††Ò3Ñg|GFF>–_!2&ª„a^¯×?.ííí}D¹…axâĉ#GŽÜ½{·R©Ôjµ•••õõõNÿøD¥`p0©V«CCC}²¹\›mçs;»A<¼@<ôzI­õÙ³gK¥Rþ{÷îmnnîîîŠH?Æ¿·±_bòÑ%Özllì3¦?kÒqvvvllìÞ½{<ò3gY¶½½½¿¿ÿá7÷g³L?Ó›}lf ÇÆÆ¾ùÍo@¥RŠ¢HDûÁéG®/•JçΫÕj“““÷îÝûàN>‰ù¯ÕjÃÃÃýï©V«>úèÐÐÐÇý#âùv¥Ô±cÇêõúÑ£G×××777›ÍæGB‚¾¶ÏŸþì3*¥>cJñçëÿøàâÿ¯};Fa( ]²zÿÛ9:¹ªt¤˜„–vhJߟCÐ<‚‰­µedcžOWÙè½Ï_¤Æ$Ç­VJy8YC­û‘ì•·mÛÆyrÎ)¥ñ Š1î‹ !Ìo‘sâµÖ9žå-tY›ùäkÕ›ûÕ~ºW6'~«ô¸rÁ%à!<ă‡xðâ!<ă‡xðâ!<ă‡xðâÁC<ă‡xðâÁC<ÄãrÝêqÙ•7µ_`IEND®B`‚eric-6.0.8/eric/pixmaps/eric_2.ico0000644000175000017500000063154212307344202015775 0ustar piotrpiotráá L3(á   :::"%%%4OOOOOOO.%%%%%%%%%%%%%%%*OOOOB%%%%=OOO  EOOOOOOOOOOOOOO6%Twyv`OOOOOOOOOOL )LOOOOOOOO;%%%%%%;Xeeen‚ŽŽŽŽŽkeeeeeeeeeeeeeee>\…ŽŽ‰ueeeer†Ž‚VC_v‹ŽŽŽŽŽŽŽŽŽŽŽŽƒoe^(!aš´ ŽŽŽŽŽŽŽŽŽŽ{H @^h|ŽŽŽŽŽŽŽ…qeeeeeeP@@@@@@@@@$-\q†š¥¥¥®½½½½½«¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥‘^^½½µ¥¥¥¥¥¥²½—X+]u‹Ÿµ½½½½½½½½½½½½¯¥†[! g ¦À¾½½½½½½½½½½º‰I (XsЍ»½½½½½½±¥¥¥¥¥¥”‚€€€€€€€€y^% 4d…±¾¿¿ Ä ")Ð "'Ð $)Ð "'Ð #&п¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿p:##r &&·!#ÐÊ¿¿¿¿¿¿ÈÐ Ä—X(Oh€µÌ!!Ð 21Ð>>ÐBAÐAAÐ??Ð??Ð>=Ð 79Ð)(Ð""ÐÐ Å¿¿¿›[!W_£!]iîFLà%%Ð ÐÐÐÐÐÐ Ð%%Ð 10Ð88ϼ‰I ?f}š³ÀÏÐÐ! Ð Ð! ÐÐ Ç¿¿¿¿¿¿¿¹·········¢xD 5i‡¤Æ@?Ù&bbå(onå-€å2’“îAœ¤ýX¡§ý`¤¬ýa¤ªýL£¦ü+}}ë"]\å!Z[å#bbå*vvå0‰‰å2å2ŠŠå2ŠŠå/Š‹å0‹‹å0Љå/…ˆå2‹‹å1Œå2‚ƒå --ѯ…X*‚©Vš¡üJ’˜ý5‘ô.‚…å*qrå$ddå&hhå*yyå.ƒ…å8”“ñEý33×—X;d|“¨ÊCBÞ7‚„õa¤©ýj¯´ýn¹ÁýnºÂýnºÂým·¾ým¸¼ýn¹½ýk´¹ýg¨­ýg¤¨ýP›ý(wwî"QQåBAÝÆš[!7¡¢²wÕÙÿsÃÇýg«±ýi¨­ýcŸ¥ýd ¦ýg¤©ýg¤§ýe£§ýf¤©ýh©­ýp¸¼ýLŸú ''ʼnI =m¦Æ<;Ý"\^ç4‹úW¡¥ýg¥ªýd¢§ýf£©ýh¦«ýV£ý1‹Šñ&mmå VVåPQå"UVåOQåFHå /2ÔÇÇÇÇÇ ÇÇ ÇÇÀµŒ_.eˆ±AAÜ-x{ð^¨­ýÎØÿÍ×ÿ‰ÇÒÿ‰ÊÒÿŽÏ×ÿ“ÑÚÿ”ÓÝÿ•ÕÝÿ•ÖÜÿŠÌÓÿŠÅÎÿ‡ÄÍÿ‹ÈÑÿˆÅÎÿ‰ÆÏÿÐØÿ“ÒÚÿ‘ÐÚÿÎØÿÍ×ÿˆÂÍÿ…ÀÊÿ’ÐÜÿÊÔÿ€ÁÉÿKJݼ™i)6¢¡«ŽÑÚÿˆ¾Èÿ…ÅÎÿ•ÖßÿÌÕÿËÔÿÊÕÿÏØÿÐÙÿ”×áÿ¿Çÿ 32ÑŒX"Wqˆ¤¼ 22Ý5vyôi¬³ÿŒÏØÿ—ÒÜÿ‘Í×ÿ“ÎØÿ’ÍÖÿ’ÎØÿÉÒÿËÓÿÈÒÿÍØÿŽÍÖÿÌÕÿ™Øâÿ’×âÿ•ÔßÿkºÀÿ acÆ„Z!)su²ËÒÿ•ÐÚÿÌÖÿ–Öàÿ”ÓÝÿ‘ÐÚÿ–ÔÞÿ”ÓÜÿ”ÒÛÿ”ÓÜÿ”ÓÜÿ¤áëÿ^—›û¶wF 9j‹¯ .-Ù1suóbª¯ÿŒËÔÿ’Øàÿ›Úæÿ™Øäÿ–Õàÿ–Õßÿ•ÔÞÿ˜ÓÞÿ‡ÉÓÿ…ÁËÿ|²»ÿ|µ¾ÿ‹ÉÒÿŒÒÚÿfÃÇÿU®¯ùN‘•÷G…‰÷H€„÷G}€÷Ay|÷#st÷$su÷%sv÷'qrö;;âÁŸj+.g„°^]äUŸ¡þxºÂÿ‹¿Êÿ–ÖÞÿ‘ÑÚÿŽÍÕÿ‰ÇÏÿˆÄÍÿŠÉÒÿŠÈÒÿŠÊÓÿ‹ÊÓÿŒÌÕÿˆÇÐÿˆÈÐÿ†ÄÎÿ}·Âÿ}·Áÿ|¶ÀÿºÅÿ‚ÀÊÿƒÀÊÿ…ÃÍÿƒ½Çÿ€¸ÄÿÏÙÿÈÓÿ‡ÓÛÿ(}|ïÈ©xI,«ŠÉÑÿ·Âÿ¸Âÿ’ÔÝÿ‹ÉÔÿŠÈÓÿ‹ËÔÿŽÎØÿŠÈÑÿ—ÑÝÿd°´ÿ --ÌwD'Hbyš³"!ÓNNèF•—ý×Ýÿš×áÿËÔÿ‡ÄÍÿŠÉÐÿŠÊÒÿŠÈÑÿ‰ÊÓÿ‰ÊÓÿˆÈÐÿ…ÂÍÿ„ÄÎÿ|¹Ãÿ{´¾ÿ¹ÃÿŒÆÒÿ…ÉÓÿ^ž¢ÿ\\ªZ"ZY©wÀÇÿÌÖÿ…ÃÊÿŠÊÑÿŒËÕÿˆÉÒÿŒÍÖÿŠÈÑÿ‰ÆÎÿ‰ÆÎÿËÓÿÔÜÿ1}~÷´d%"a‹»BCåCŽû„Ï×ÿ–ÒÜÿÎØÿ‹ÉÒÿŠÈÒÿˆÈÓÿ†ÅÍÿÍÖÿ‡ÈÑÿˆÆÏÿÌÖÿÏØÿ‡ÄÍÿ}µÀÿz¯ºÿŒÇÐÿÚäÿ›ÕÞÿšÔÝÿ”ÒÛÿ—ÔßÿšÙãÿšÚãÿ‡ÙÞÿŠÛáÿ‰ÙàÿˆÕÝÿ=z|õÌ©|H N~³ gfèd·»ÿ’Ì×ÿ„½Æÿy±ºÿˆÆÐÿÑ×ÿŠÊÒÿŠÊÒÿ‡ÆÐÿ‡ÄÎÿ†ÆÍÿ‰ÉÑÿ‡ÇÑÿÎØÿ‹ËÕÿ¿Êÿy³½ÿƒÁËÿ‡ÇÑÿ€»Åÿ€»Åÿ¾Èÿz³½ÿ{·Âÿ~»Åÿv¯ºÿ½ÇÿˆÄÎÿ—ÑÛÿTšü67Ù¸ŽX&{|«ƒÀÉÿ€»Åÿ{²½ÿ‰ÉÓÿ‰ÈÓÿ‰ÈÒÿŠÉÓÿ‹ÌÕÿ‹ËÔÿŽÐÚÿ:‘’õ¼n/IeyŽ¢Â@?ä>}~újª±ÿ‹ÊÓÿ˜Øàÿ‹ËÓÿ‹ËÓÿ‰ÇÏÿ‡ÆÍÿ†ÄÍÿ‰ÈÑÿ‡ÅÏÿŒÌÖÿŒÌÖÿ„ÂÌÿzµ¿ÿ½ÇÿÎÙÿ‰ËÕÿ_Ÿ¥ÿ%llÞ ;<¤OFFuN£¥ô™ÖÞÿ‰ÈÏÿŒÍÔÿˆÇÒÿˆÈÒÿŒÊÓÿŠÈÑÿ‰ÇÎÿ‰ÈÐÿËÒÿ‡ÇÎÿKLä¢b"Tw³VXíhª¯ÿ•×âÿ“ÒÛÿŠÈÑÿ‰ÈÑÿ‡ÆÏÿ‡ÆÑÿ†ÃÌÿ€¿ÈÿˆÇÐÿ‡ÆÏÿ‰ÇÐÿÏØÿŒÊÓÿŠÊÓÿƒ¿Èÿ|´¾ÿ}¶ÁÿÏØÿŒÌÒÿŠÊÓÿŠÈÐÿ‡ÅÎÿ…ÃÌÿŠÈÑÿ‰ÇÐÿŽÌÕÿÍØÿ–ÒÜÿc©®ÿ::ß»Š\(g›baâh¸¾ÿØâÿÍÖÿ†ÂÌÿ{´½ÿ|²»ÿÒÚÿŽÏÖÿÑÙÿŽÎÖÿˆÇÏÿ}ºÃÿ{¶Àÿy´¾ÿy³½ÿ}¸Âÿ¾Èÿ‡ÆÐÿŠÊÔÿ†ÅÏÿ¿Éÿ…ÅÏÿ‰ÉÓÿ…ÅÏÿ‰ÊÕÿ‡ÇÑÿ{³¿ÿ‚¼ÇÿˆÆÐÿÌÖÿ}ÃÉÿ"]_è¿—j1 fg«»Åÿ‹ÊÓÿ€½Çÿ~¹Äÿ€¾Æÿ¿Èÿ†ÄÍÿ‡ÆÎÿ…ÂÍÿ‹ÄÏÿ+ggì­nbzŽ¥·.-Ú$ddñ]¥©ÿ–ÓÞÿˆ¿Éÿy®·ÿ‹ËÑÿÒØÿÓÙÿÏ×ÿ‰ÉÑÿ½Æÿ{µ¾ÿ{¶Àÿy²¼ÿ}¶Âÿ~»ÅÿˆÇÑÿ•Óàÿ„ÍÕÿA†ˆúIIÊ ))€(K?|~è™ÕÞÿ‰ÇÏÿŽÎÕÿŠÉÒÿ‡ÅÏÿ‰ÇÏÿ‹ÈÑÿ‰ÇÐÿ‰ÈÒÿŽÍÖÿ‡ÅËÿBCà•b0l«HHç]¢§ÿ–ÒÝÿŠÇÒÿ†ÄÍÿ€¾Æÿ„ÀÊÿ…ÃÍÿ„ÁÊÿ†ÆÎÿˆÅÐÿŠËÔÿ‰ÈÑÿ‡ÅÏÿÐÚÿÏØÿ”ÑÛÿ–ÑÛÿˆÂÌÿ{±ºÿ‡ÂÌÿ‘ÓÙÿŽÑÙÿÒØÿŒÌÔÿ„ÂÊÿ|µÀÿ{¶Àÿ{²¾ÿ{´Àÿ»Æÿ‚ÀÉÿXYé¾r4 HƒMOÞW§©þœØáÿŽÍ×ÿÌÕÿÏÖÿ„ÂÉÿw®·ÿ‰ÉÐÿÑÙÿÎØÿÏÖÿ…ÃÌÿ{´¾ÿ…ÂÍÿÌÕÿ…¿Èÿ…½ÉÿÏØÿ–Öáÿ•Ößÿ”ÔßÿŒÉÔÿ‰ÇÒÿ‡ÈÒÿ‡ÇÐÿ‰ËÔÿˆÉÒÿ»Æÿ‚¿Éÿ‰ÇÐÿŒÊÕÿ’ÔÝÿ8€‚÷ΩR a_«‹ÉÑÿÐÛÿ‰ÉÒÿˆÇÐÿ…ÃÌÿƒÁÊÿ†ÃÌÿ‡ÈÐÿ‰ÆÐÿ‘ÍØÿ)[[ì­y¢¹ÎCBâ8ƒù‚ÄËÿ™Øáÿ“ÓÝÿ‡ÆÐÿy²ºÿ¼ÄÿÑÙÿÎ×ÿŒÏ×ÿˆÉÑÿ|·Àÿ€ºÅÿŠÌÕÿ»Æÿ{´¿ÿ†ÃÌÿ—Ùãÿ|¹Áÿ;ñ ;:¬W!!<6noå•ÔÞÿŒÊÒÿŽÐÙÿˆÇÒÿ‡ÅÏÿ‰ÈÑÿ‰ÊÑÿ‰ÊÒÿ†ÅÍÿÎÕÿx¾ÃÿBD݃TU‚CDØ]™Ÿÿ”ÏØÿ‰ÇÎÿ‡ÆÏÿ‡ÆÏÿ…ÄÏÿ‡ÆÑÿ‡ÈÑÿ‡ÆÑÿ†ÅÎÿ‚¿Êÿ‹ÊÓÿ’ÒÚÿ™ÕÞÿÕÝÿÌÔÿi¸½ÿX¸»ñw¾Åÿ€¼Åÿ‰¿Èÿ”ÕÞÿÑÙÿÏØÿ‹ËÕÿ~ºÃÿ{¶ÀÿˆÊÓÿ„ÂËÿz´¾ÿ€¼ÅÿšÜåÿHŒû˱|J[ 65­E‰‹øžÝåÿÏ×ÿˆÈÐÿŠÊÒÿÌÔÿ‰ÉÑÿz´¾ÿ{´¾ÿŒÏØÿ‹ËÖÿ†ÅÎÿ¼Åÿ‰ÃÌÿ›Øâÿ‹ÒÛÿb§¬û_¢úb¤©ùb¥ªùc¥­ùh°µùƒËÒÿ—ÓÛÿËÔÿŒÉÒÿ‰ÉÒÿˆÉÑÿƒ¿Éÿ„ÄÍÿˆÈÐÿˆÇÑÿ—ÔÞÿ`¢§ÿ'&×»”j-TU«ŠËÓÿÐÚÿ‹ÉÒÿ‹ÌÓÿ‡ÆÏÿ†ÄÍÿˆÇÏÿŠËÔÿŽÎ×ÿÒÛÿ&WWì·¥ºÎ<<å8wz÷n±¶ÿŽÕÝÿ“ÒÚÿŒÊÒÿŒÌÔÿŒÌÓÿ»Âÿw¯¹ÿ‰ËÔÿŽÐØÿ‡ÆÏÿ€»Åÿ~ºÃÿ‰ÊÓÿŒÐØÿ†ÄÌÿ‡ÂÌÿŽËÕÿS§ªý'jiÚ 76š/## ed·pÂÇþËÕÿŒÌÕÿ‡ÆÏÿ‰ÇÐÿ‹ÊÑÿ‹ËÔÿˆÈÑÿ†ÅÍÿ”Î×ÿS¬°ü 00Ï}=c 11¿9‰Šö×ÞÿŠÇÑÿ‡ÅÎÿ‰ÉÒÿŠËÓÿŒÌÕÿˆÈÓÿ†ÇÑÿˆÇÒÿ‰ÇÐÿ‹ÈÒÿ“ÓÛÿ†ÉÑÿT™›û-~~ß#]^»WV›]\~%aa¤)mpÕI„ˆûqÇÊÿ˜ÛäÿŽÌ×ÿ„ÁËÿ|¸Áÿ†ÅÐÿŽÐÙÿˆÇÐÿ¿Èÿ¿Èÿ’ÐÚÿc¬°ü 32ݹf(5q ^_Úm±·ÿ•ÔÝÿ‹ËÓÿˆÇÐÿŠÈÐÿ‹ÌÔÿÌÖÿ‡ÃÌÿz²»ÿ{¶¿ÿ~¹ÃÿˆÂËÿ–ÕÞÿl½ÂÿB—šî/wxßTRžA@iPOWZZLYXL`_{,yyÍIœ êm¼ÂÿÒÛÿÌÖÿˆÆÐÿˆÅÐÿˆÇÒÿˆÇÐÿ‡ÆÏÿ’ÑÛÿvÉÐÿbaé Ū}I QR¤d¿Áÿ’ÑÚÿŠÊÒÿ‹ÉÓÿŠÉÒÿ…ÄÌÿ…ÄÍÿˆÆÐÿ‹ÉÔÿ‹ÍÖÿ!POìÀÍ 64á3lm÷^Ÿ¤ÿ“ÓÛÿ—×ÞÿŽÎÖÿŠÉÑÿˆÈÐÿ‹ÌÔÿŒÍÕÿŠÉÒÿ}·Àÿy³¾ÿ}ºÃÿ½ÆÿˆÉÒÿŠËÓÿ‹ÍÖÿÐØÿ”ÓÜÿƒÏ×ÿV”ÿIHÀb.ML†j­³ý‘ÌÖÿŒËÔÿ‰ÈÑÿ‰ÈÑÿ‰ÈÑÿ‹ËÔÿ‰ËÓÿˆÉÒÿ•Î×ÿI™›õ¼}= |&``〿Æÿ”ÑÚÿ‡ÄÎÿ…ÃÌÿ‡ÆÏÿˆÇÒÿ‡ÆÐÿˆÇÑÿŠÊÔÿŠÊÕÿ’ÍÕÿ‚ÍÔÿR“ÿ(fiá97§SRH)JGŒiaÙT“–ÿz¼Äÿ—ÕÞÿŽÎØÿÎØÿŒÎ×ÿ‹ËÒÿ‡ÆÏÿƒ¿Èÿ†ÃÌÿ‚ÅÍÿ$UWñ¦yI7 --‘BŒùÊÒÿˆÅÍÿˆÇÑÿ‹ËÓÿŒÌÔÿŒÌÔÿŒÌÓÿ‰ÊÑÿ€¼Åÿy³¼ÿÍ×ÿ…ÊÒÿS £ù&_`Ñ 86‚ ! 8]\kpL"qqœ?’”ãe¬²þˆÆÎÿ”ÓÝÿŒÌÖÿˆÇÐÿ†ÅÎÿÊÔÿ›×àÿN‘•ú ++Ô»Š]IRwF²´õ”Î×ÿ‹ÉÒÿ‡ÆÏÿ‰ÈÑÿˆÇÐÿ…ÄÍÿ‰ÈÒÿ‰ÅÐÿƒÆÎÿMLö<=ä5uv÷c¥«ÿŒÍÕÿÏØÿ‡ÅÍÿ„ÁËÿ‡ÆÎÿŠÊÔÿ‹ËÓÿŒÌÔÿŒËÒÿŒÊÓÿ…ÀÊÿx°¹ÿ†ÃÌÿ‡ÈÑÿ‰ÈÑÿ‡ÇÏÿŠÊÔÿšÙâÿt¾Ãÿ+||è<<±_ FE†l¬²ý“ÑÛÿŒËÔÿ‰ÆÑÿˆÅÎÿˆÆÏÿ‰ÉÒÿ‹ËÔÿˆÆÏÿ’ËÖÿDˆŠõ¼}O **¬KŽ‘þ”ÔÛÿ‹ÊÓÿ‰ÈÑÿ‡ÅÎÿ‡ÈÐÿ‡ÄÏÿ‚¿Èÿ…ÄÎÿ‰ÈÑÿ•ÑÜÿr½Ãÿ(yzé87¯ _xKM(PN‚&hhØ[ ¤ùˆÈÐÿ”ÒÛÿ‘ÎØÿŽÎÖÿŒÍÕÿˆÉÑÿ‰ÆÑÿÎØÿ:‹‹øϸb"8KK³b­°ü“ÎÖÿ„ÀÉÿƒÁÈÿ‡ÅÎÿˆÉÑÿˆÉÓÿ‡ÅÎÿ‰ÇÐÿ†ÂÌÿ¸Áÿ àéÿRšœýECÅ s4YX<fd:€€æi²·ÿ›ØâÿËÖÿ‰ÉÒÿ‰ÉÒÿ’ÏÙÿx½ÅÿUWê¿s;88HH­­æ”Ï×ÿ‹ÉÓÿ‰ÉÐÿ‹ËÔÿ‰ÉÒÿˆÈÑÿ‰ÉÒÿˆÆÏÿpÃÈÿ3ŠŠÿg²·ÿŽÐØÿ”ÐÜÿŽÎÖÿŠËÓÿˆÇÏÿƒÁÉÿƒÁÉÿ†ÅÍÿ‰ÇÑÿŠËÒÿ‡ÆÐÿˆÈÏÿ‰ÇÐÿ{µ¾ÿÎÖÿŽÏÙÿ‹ÉÒÿ‘Ï×ÿœÚãÿj«°ÿ)jiç ))œH 76†j©®ý”ÓÝÿŒËÖÿ‰ÈÑÿˆÇÎÿ‰ÈÐÿ‰ÊÓÿŠËÔÿ…ÃÌÿ’ËÕÿD…õ¼}eGEÏu¼Ãÿ‘ÐÙÿ‹ËÔÿ‹ËÔÿˆÈÑÿˆÉÒÿ‡ÆÏÿ‡ÅÏÿˆÉÓÿÑÚÿŠÕÝÿ+uvî##«[RQ0RQ0ÑT ¤þŠÔÜÿ—ÖÝÿŽÏÕÿˆÇÎÿ‡ÆÏÿ‘ÐÚÿn¹¿ÿ?>åÀ¢j-T,ooâ‹ÔÜÿÏØÿŠÉÒÿˆÈÏÿ‰ÈÒÿ‹ÊÓÿ‹ÈÑÿˆÆÎÿ‡ÅÍÿ†ÃÎÿ†¾Çÿy½ÃÿZXæŠWNN]`R"glËVš¡ú€ÄÍÿ—ÔàÿÐÙÿŒÊÕÿ’ÒÚÿ>ƒ…û̲‡^ 43DBž æ”ÌÖÿ‰ÇÐÿŠÊÓÿŽÍÖÿŠÊÓÿ‰ÈÑÿˆÇÐÿ‰ÆÏÿŽÌÕÿ’ÏÛÿ—ÕáÿÑÚÿŠÊÓÿ‡ÇÐÿŒÌÕÿ‹ÍÖÿŠÈÒÿˆÇÏÿˆÇÐÿ‹ÊÓÿ‹ÉÑÿ‡ÇÐÿ‡ÄÌÿ‡ÆÏÿ|´¿ÿ‰ÇÐÿÒÛÿ“ÐÚÿ…ÌÔÿWž¢üSUÜ 10‡8/.†d¢©ý’ÐÚÿ‰ÈÑÿ‰ÊÑÿ‰ÇÎÿ‰ÈÒÿˆÉÒÿˆÇÐÿ¿Èÿ™ÖàÿAx|õ ¼}s3qsñ“ØßÿËÔÿŒÌÕÿŒÌÕÿ‰ÈÒÿˆÇÐÿ‡ÆÎÿ†ÅÐÿ‰ËÓÿ˜×âÿ_¢§ÿ65Èr=HH$RQ‹4„…âw´ºÿ”×ßÿŽÊÔÿ…ÄÍÿËÖÿ™Øâÿ:vx÷ϪWd.knè›Ùâÿ‹ÊÕÿ‰ÈÓÿˆÇÐÿˆÇÐÿ‹ÊÓÿ‹ÊÕÿ‹ÉÓÿ‡ÅÎÿ…ÂÌÿˆÃÍÿE“ý 67Æk.$ts"dcp0‚ƒÌ[©®þ™×âÿÌÕÿ–ÐÚÿaª°ý 98ÝÀr=  ..DA”–æ–ÏÚÿŒÊÓÿ‰ÉÓÿŠËÓÿ‹ËÔÿˆÇÏÿ‡ÆÐÿ‡ÇÒÿˆÉÓÿ†ÆÐÿ†ÆÎÿ‡ÅÐÿ‹ËÕÿŠÊÕÿŒÎÖÿŠÊÕÿ‰ÉÓÿˆÇÐÿˆÇÐÿŠÉÓÿ‹ÊÕÿ‹ÊÓÿ‡ÄÍÿ‡ÄÍÿ~·Âÿ…ÃÌÿ‘ÎØÿÍØÿ>ƒû >=Ηv_" 0/†b¢§ý’ÒÛÿ‰ÆÏÿ‹ÊÓÿˆÅÎÿ†ÆÐÿ‹ÊÓÿ„ÀÉÿ}¸ÁÿšÛåÿ;oqõ ¼}6<“J‘”öœØâÿŠÊÓÿŠÊÓÿŠËÔÿˆÈÑÿ‡ÆÏÿ‰ÈÒÿˆÉÓÿŒÌÕÿ…ÌÖÿ'klñŸ]UTa+uw³Jù‘Î×ÿŽÌ×ÿŠÉÔÿ—Öáÿ\ª®ÿ;=â¾—m4d5†…ë˜ÓÞÿ‰ÊÓÿ‡ÇÐÿ‡ÆÏÿ„ÂËÿ…ÄÌÿ‰ÈÓÿ‹ÌÕÿ‰ÉÒÿ†ÂÍÿ‰ÄÏÿ$``è“b"^^(ZX¬F—™ñtÄÊÿšÕÞÿÏØÿ-opñƲ‚C  )(D;ŠŠæ—ÑÛÿÐÙÿŒÌÔÿŠÊÑÿ‰ÉÒÿ†ÅÎÿ„ÁÌÿ„ÃÍÿÌ×ÿŽËÕÿ’ÍØÿÌ×ÿŒËÔÿ‹ÉÔÿ‰ÉÓÿ‰ÊÒÿˆÉÒÿ‰ÈÑÿ…ÃÌÿ†ÂÊÿ‡ÇÏÿ‹ÌÕÿŠÊÓÿ†ÃÍÿƒÀÊÿŽÏÙÿÍ×ÿL¦©ÿ0/㿵 }X: 0/†b ¥ý“ÓÜÿ‰ÈÑÿ‹ËÔÿ‰ÈÏÿ†ÄÍÿˆÇÐÿƒÁÊÿ|¶Àÿ–ÔÞÿ:koõ ¼}RUºa¸¼ÿšØâÿŽÎ×ÿŠÉÑÿ‰ÉÒÿˆÇÐÿ…ÃÌÿ„ÁËÿ‰ÉÔÿ”ÓÜÿe§®ý43Ò}O OM™M“ÿ~ÎÓÿ•ÒÞÿ‘ÎÙÿÇÏÿ'bcêÁ¬|< 0/†c ¥ý“ÔÜÿ‡ÆÐÿ…ÄÍÿ‡ÆÏÿˆÈÑÿ€½Èÿ€»ÅÿŽÌ×ÿáêÿ:oqõ ©s,~~º‚½Æÿ»ÆÿƒÀÈÿˆÆÐÿÎØÿŒÍ×ÿŒÍ×ÿŠÉÔÿŒÌÖÿ‰ÆÑÿLPæ¦g'XW2RQ•HšœïÍÕÿKŒŽåpW"U`¤o½Åÿ’ÐÚÿ‡ÅÐÿ†ÄÎÿˆÆÐÿ‡ÆÐÿ€»Åÿ‡ÇÐÿÍÖÿŒÊÓÿËÓÿhiê¦}}}}}}}}}}}}}wdUUUXk|}}‡QP³$kjª?>2D7uuæ™Óßÿ¾Èÿy³½ÿ{¶Àÿ¾Éÿ„ÀÊÿˆÆÒÿ…ÁÍÿˆÀÌÿ'^`ì¿—X88NM:]^‘4|}æb­³ü‰ÆÐÿŠÅÏÿŽÏÚÿ‰ÈÒÿŠÉÒÿ‹ÊÓÿˆÆÎÿˆÊÒÿˆÉÒÿ‰ÇÐÿ’ÐÙÿ†ÎÖÿKŸ¡üOPïﱉa#0/†c¢§ý’ÓÝÿ†ÄÎÿ‡ÈÐÿ…ÄÍÿ„ÁÊÿƒÁÊÿ‰ÉÑÿÍ×ÿ€ÓÙÿiióŸ`1Žº‹ÉÔÿ‡ÁÍÿ{´Àÿ{³½ÿ‚½Çÿ‚¿Éÿ‡ÅÐÿ†ÄÎÿƒ¾Éÿ~¼ÅÿKJæ¦g'bagA¡£ž9¸¸‡HH.U_¤n½Äÿ“ÑÛÿ‰ÇÓÿ†ÄÎÿ‡ÃÍÿ…ÂÊÿºÃÿ‡ÆÐÿŒÍØÿÍÖÿÀÆÿFEÚ¸µµµµµµµµµµµµµµ¤•••••˜«µµµs? D6quæ›×âÿˆÈÒÿƒÀÊÿ|µÁÿz´¾ÿy³½ÿ‚½Çÿ‹ÉÕÿÐÚÿ/{|í ×j1SR=b`•Q’ÿÇÏÿ›Öàÿ‹ËÔÿ‰ÈÑÿŠÉÒÿ…ÃÌÿ„ÂËÿ„ÃÎÿ„ÃÌÿˆÆÑÿ‘ÑÛÿ˜Ýåÿc¥©ÿWYï Ѿ¡v@ 0/†bŸ¦ý‘ÐÚÿ‚½Èÿ‚ÀÊÿƒÀËÿ‚ÀËÿ‰ÇÑÿ‰ÉÓÿÊÔÿvÆËÿYZà•U3ºËÖÿŒËÕÿ„ÃÍÿ}·Âÿ|´Àÿy±»ÿºÃÿˆÆÑÿŽÏÙÿ…ÇÐÿLMæ¦g'Ub¤kºÀÿŠÄÏÿ„ÀÊÿ‡ÄÎÿˆÅÏÿ~ºÄÿ|¶Àÿ‰ÇÐÿÍÖÿŒÌÔÿ|½ÃÿEDÞ ÅÅ Å Å Å Å Å Å Å Å Å Å Å ÅÁ¿¿¿¿¿¿ Å Å ÅÅò†I D6rvæš×ãÿŠÉÓÿ‡ÇÏÿ…ÅÍÿ†ÄÍÿ„ÁÊÿƒÁÊÿ†ÅÎÿÎØÿP£¥þ ))ש}A [[RUr+‚‚ÌoÂÈÿ–ÒÜÿˆÆÏÿ‰ÈÑÿ†ÅÎÿ…ÂËÿ†ÆÏÿ…ÄÎÿ‚¿ÈÿŠÌÓÿŽÍÖÿ›Øàÿn¯´ÿ[^ñÊ´‰^00†_™Ÿý‘ÑÚÿƒÃÍÿ‚ÀÈÿ¾Çÿ‚¾Éÿ„ÀÊÿ¾ÈÿÆÑÿu¾ÃÿPPÕ•U3ŽŽºŒËÕÿŒÊÕÿ‰ÈÒÿ†ÄÍÿ†ÄÎÿ„ÃËÿ„ÀÉÿ†ÄÍÿ‹ÈÑÿ†ÈÑÿNPæ¦g'Td¢jµ¼ÿŠÄÍÿƒ¿Éÿ€»Åÿƒ¿Éÿ|¶Àÿ¾ÉÿŠÊÒÿ‹ËÔÿ‡ÆÏÿuµ»ÿ7~~ø6ruõ8vwõ8wxõ9twõ7twõÕ--Õ ))Õ *)Õ --Õ 32Ø\^ê/ssõ?wzõG…‡õPOÜ»‰WD6vvæœ×áÿ‹ÊÓÿ‹ËÓÿ‹ËÕÿŠÊÔÿˆÇÏÿˆÇÏÿŠÉÑÿ‘ÌÔÿuµ»ÿ //×¶‰\77_(x}ï…ÑØÿˆÄÍÿˆÅÏÿ‡ÅÎÿƒÀÉÿ…ÄÍÿ‡ÆÏÿƒÂËÿ‹ËÓÿ‰ÉÏÿŽÌÔÿ‘×ÞÿJ•˜þ 31áÀžuB 00†]™ ý“ÒÝÿ‰ÊÔÿˆÅÏÿ†ÄÎÿ†ÆÎÿ‡ÅÏÿ‚½ÇÿˆÀÉÿp·¾ÿJIÕ•U.†…ºËÔÿŒÊÔÿ‰ÉÒÿ‹ËÔÿ‹ÊÓÿˆÇÐÿ‡ÆÏÿŠÉÑÿŒÉÑÿ‡ÉÑÿPOæ¦j-Xf†S³·þÌÕÿ‡ÇÑÿƒÁÊÿ|·Áÿx±¹ÿ‰ÊÒÿŠËÕÿ‹ÌÖÿ‰ÉÓÿËÓÿ‘ÐÙÿ“ÒÛÿ”ÓÜÿ“ÔÝÿÏØÿŽÍÖÿ–×àÿ˜Øàÿ›Þåÿ–ÕÞÿ˜Øáÿ™Ùãÿ–ÖÞÿ˜Øáÿ…ÕÝÿ{ÑÕÿw½Äÿn®³ÿh«°ÿe§®ÿg¦­ÿm®µÿuÅËÿŒÔÜÿ“Î×ÿ–ßèÿ;”•òÆ™o3D4qsæš×âÿ‹ËÓÿˆÉÐÿŒÌÔÿŠÊÒÿ‰ÉÒÿ‹ËÔÿŠËÓÿÊÓÿ|ÌÑÿ]^é Åœg'88 LP¢V’•þŒÍÔÿŒÉÑÿ‡ÄÎÿ†ÃÌÿ†ÄÎÿƒÁÉÿ¿Èÿ†ÄÎÿ‰ÇÐÿŽÎÔÿÍÖÿÎÖÿ/moôɵ‡N10†^™žý“ÔÝÿŒÎØÿˆÈÒÿˆÇÑÿˆÉÒÿ‰ÈÑÿ‡ÅÎÿˆÁÊÿm°·ÿEDÕ•U)wxºŒËÔÿŽÎÕÿ‰ÉÒÿŠÌÔÿŒÌÔÿ‰ÉÒÿ‹ËÔÿ‹ËÔÿŒËÓÿ‰ÊÒÿNNæªP32H>§¦ã“ÌÖÿˆÆÒÿ†ÃÍÿ}¸Âÿ~¹Âÿ‰ÉÑÿ‰ÈÑÿŠÉÒÿˆÈÒÿ‹ËÓÿ‹ÌÕÿŠÉÒÿ‰ÈÒÿ†ÅÐÿ‡ÆÐÿ†ÃÍÿ‡ÅÏÿ‹ÊÐÿÐÙÿÍÕÿ‰ÈÏÿˆÇÐÿŠÇÐÿŠÈÑÿŽÊÓÿ‘ÎØÿ“ÑÛÿ’ÐÚÿÎØÿ‹ÈÒÿÎ×ÿÏÚÿ‹ÈÑÿ†ÂÍÿºÃÿ‘ËÕÿY™û̯u5D3opæ›×àÿ‰ÊÓÿ‡ÈÐÿ‹ÉÓÿŠËÒÿŠÊÒÿŠÊÒÿŠÌÔÿÍÖÿ ÝæÿC~‚öɦzJ00QO£c­²ü˜×àÿŠÈÒÿ‰ÈÒÿˆÅÏÿ†ÇÐÿ†ÅÎÿ…ÄÍÿ‰ÉÏÿÎÕÿÏÙÿ—ÔÝÿ`¥ªÿ87Þ»‘f(00†^˜ýŠÈÒÿ‰ÊÒÿÍØÿ‰ÊÒÿˆÈÑÿŠÈÑÿ‡ÆÑÿ‹ÅÐÿj«²ÿ@@Õ•U#`aº‹ÈÐÿŽÍÖÿ‡ÈÏÿ‰ÉÑÿ‹ËÔÿŠÊÒÿŠÊÒÿŠËÔÿÏØÿÏ×ÿ!SRæ½a##"@8Œã—ÐÞÿ…ÂÍÿ…ÀËÿ†ÄÏÿ‹ÉÔÿ„ÀËÿ½Æÿ„ÂËÿ‰ÈÑÿ‰ÈÒÿ‹ÌÕÿŠÉÒÿ‡ÆÑÿ†ÄÍÿˆÇÏÿ…ÄÍÿŠÉÒÿŠÊÒÿÎÕÿÍÕÿ‰ÈÑÿˆÅÏÿ‰ÆÏÿŒËÔÿ‹ÊÓÿŠÉÑÿŠÉÔÿˆÆÏÿ‚¾Çÿ½Çÿ‰ÊÔÿ‡ÇÐÿ‚ÁÌÿ¿Èÿ…ÃËÿ‹ÄÏÿa¨­û 76زu5D3opæ›Öáÿ‰ÉÒÿ†ÅÌÿ†ÅÌÿ‹ÉÓÿŠÉÓÿ‡ÆÍÿ‰ÈÑÿˆÇÐÿ›ÙãÿZ¥¨ÿ 87ܺŒW >=L2vwéŒÒÙÿŽÌ×ÿ‰ÈÑÿ…ÄÍÿˆÇÑÿ†ÄÍÿ‰ÇÐÿ‹ËÓÿÌÓÿÏ×ÿÍ×ÿ†ÇÑÿ&fgôʦp10/†c¡¦ýÉÕÿ€¾Æÿ‰ÊÔÿ‰ÊÔÿ‡ÈÏÿ‹ÌÓÿŠÉÔÿÍ×ÿm®´ÿ<<Õ•UVW¸‹ÈÐÿÏÙÿ‡ÇÐÿ†ÃËÿ‰ÈÑÿ‹ÉÒÿ‡ÆÏÿ‰ÈÏÿ‰ÉÒÿ’ÓÚÿ*qrêÀ¡v:?1orâ’ÊÖÿƒ½Çÿ‹ÉÓÿ‰ÈÓÿŒÌÕÿ‰ÈÒÿ†ÄÍÿ½Æÿ„ÀÉÿ‡ÅÌÿ‡ÇÎÿ…ÄÍÿ†ÄÍÿˆÇÑÿˆÉÒÿ„ÁÊÿˆÉÑÿŒÌÔÿ‹ËÓÿŠÈÐÿ‰ÈÑÿ‰ÈÓÿŠÉÒÿÌÕÿ‹ÌÕÿŠÉÒÿ‹ÊÓÿ‰ÉÒÿƒÀÉÿ~½ÅÿƒÂÌÿƒÂÌÿ‚ÀÉÿ‚ÁÉÿ‡ÉÓÿ‡ÃÍÿw½Äÿ[Zîµu5D5ruæ™ÕÞÿŒÊÓÿˆÈÑÿ‡ÆÏÿŠÉÒÿ‹ÊÓÿ‡ÆÏÿ‰ÇÐÿ‡ÆÏÿ’ÐÙÿƒÆÎÿST潘n5 US¢f¯´ÿÍ×ÿ†ÄÍÿˆÇÐÿŠÊÓÿ„ÃÌÿ‡ÆÏÿ‹ËÕÿ‹ËÒÿŠÊÒÿŠÈÒÿ˜ØâÿP’”úÑ®q30/†d¡¨ýÏØÿ|·ÁÿƒÁËÿŽÍ×ÿ‰ÇÐÿ‰ÈÑÿˆÇÐÿËÔÿm¯¶ÿ=<Õ•UYY e²·ÿ–ÑÛÿŠÈÒÿ‡ÅÍÿŠÈÒÿ‹ÈÓÿ‡ÆÑÿ‰ÆÏÿˆÇÐÿ–ÕÞÿK•—ýÑ´M'')*opÜx»Äÿ‰ÅÎÿÒÚÿ‡ÇÐÿˆÆÑÿˆÇÑÿŠÉÒÿŠÊÔÿ‡ÆÎÿˆÅÍÿ‰ÄÌÿŽÅÏÿ‘ËÕÿ•Í×ÿ“ÌÖÿÅÐÿ“ËÕÿ–Ð×ÿ•ÑÚÿ‘ÐØÿŽËÔÿÌÖÿŒÍ×ÿÏØÿŽËÖÿŽÍÖÿŠÉÒÿˆÆÏÿ~¹Âÿ{¶¾ÿ‡ÆÏÿ‡ÉÒÿ‰ËÔÿ…ÅÐÿˆÆÑÿ‡ÅÏÿŒÄÍÿ)]`ñµu5 M5qqæ–ÓÜÿˆÄÏÿˆÆÏÿ†ÃÍÿ†ÄÌÿŠÉÓÿ‹ÉÔÿ‡ÄÎÿ‰ÆÐÿŒËÔÿÓÝÿ;ƒ‡ùή…`  ..]D‚…é•ÌÕÿ‚¿Èÿ„ÁÊÿ„ÅÎÿ¿Èÿ…ÂËÿˆÉÑÿ‹ËÓÿ‹ËÓÿˆÆÑÿ“ÏÙÿr»ÀÿBCå±U0/†c¢§ý‘ÑÛÿºÅÿºÄÿ‹ÌÕÿ‹ÌÓÿ‰ÈÑÿŠÉÒÿÉÔÿo±¸ÿ<<Õ•U22cH‰‹ì—ÒÜÿˆÆÑÿ†ÃÍÿ†ÂÍÿˆÆÐÿŒËÕÿˆÆÐÿ‡ÆÏÿ“ÑÚÿm´»þ <:ẑg'_]œa©¯ù–ÑÜÿËÔÿ‰ÈÒÿ‰ÈÑÿˆÇÑÿ‰ÈÑÿŒËÕÿ‰ÈÑÿ‹ÉÒÿ‡ÇÍÿFüAˆŠñHŽ’êI˜™äIžŸàN©ªàT¹¼ábº¿ÿ‚ÇÍÿ…ÄÌÿ†ÆÎÿ‰ÇÎÿŠÇÏÿ‡ÅÎÿ„ÂËÿƒÂÊÿŠÆÏÿ{µ¿ÿ‚¿ÈÿÐÙÿŠÊÓÿŠÌÓÿŠÌÓÿ‹ËÒÿ‰ÉÒÿ’ÊÖÿ-kkñµu5g3noé–ÏÙÿ‚¿Èÿ¼Äÿƒ¾Èÿ‚½Çÿ‰ÈÒÿŽÐÚÿŠÊÔÿŠÉÓÿ‹ÉÔÿ–ÓÞÿe§¯ý--Ø¿ yK/.2%pqÒ~ÍÔÿËÔÿŠËÔÿ‡ÈÑÿ½ÆÿƒÁÊÿ‚ÀÉÿ‡ÅÍÿˆÈÐÿ‡ÇÏÿ‰ÉÓÿ•ÔÛÿ(VUîÀ•Y)+*“e¤ªý•ÖÞÿ„ÃËÿ€¹Åÿ„ÁËÿŒËÖÿŠÈÑÿŠËÕÿÌ×ÿn²¹ÿ<<Õ•U! B +~@x~óˆÂËÿƒÀÉÿÍÖÿŠÉÒÿˆÉÐÿ‹ÉÓÿŒÌÔÿÎÖÿ‹ÉÓÿ•ÐÚÿ-jkñµu5 F ##“:ð•ÓÝÿˆÇÑÿŠÉÒÿ‡ÆÏÿ{´Àÿ‡ÆÐÿ‰ÉÒÿ€¼Æÿ‚¾Èÿ…ÅÍÿ‹ÉÒÿ—ÕßÿP™žÿ 88à¿©ˆj=  ;@?žq®µÿÍ×ÿ‡ÆÏÿ‹ÌÕÿˆÇÐÿ…ÅÎÿ‡ÆÏÿ…ÄÌÿŠËÕÿ‰ÇÒÿˆÇÐÿÍÖÿ:—šþ #(Õ™YV .-©k«°þ•Õßÿ‡ÆÏÿ†ÃÍÿ}·Ãÿ€»Äÿ…ÂÌÿ€»ÅÿÎÙÿs¹¿ÿ<;Õ•U?>gCŠŽø’Õßÿ‹ÈÔÿ~ºÃÿ‚½ÈÿÍØÿ‚½Çÿ¼Æÿ†ÃÍÿ‘Í×ÿuÁÇÿUU濲Šk@ Cfmmmd1a`mQ¦ªð›ÖàÿŒÊÓÿ‰ÆÏÿ‰ÆÎÿŒËÔÿÍÖÿŒÍÖÿÌÕÿ•ÓÜÿOšžý **Ø¿²‡\4*cBz€õÌÖÿŒÌ×ÿ‹ËÓÿˆÅÐÿˆÇÐÿŠËÓÿÍÕÿÍÕÿŒÍÕÿ–ÐÛÿ-kkñµu5[>=¿a²¶ÿ’ÐØÿ‡ÄÏÿ†ÄÎÿ…ÃÎÿ}·ÁÿƒÀÊÿŠÊÔÿ„ÀÊÿ…ÁËÿ…ÁËÿ¼ÆÿˆÅÏÿ‰ÈÑÿ<~øÏ¿©Œl@#9l 0/´r®¶ÿ‘ÐÚÿ†ÅÌÿˆÈÐÿ‡ÆÏÿ‡ÄÍÿ‰ÈÑÿ‰ÉÒÿŠËÓÿˆÇÑÿ‰ÉÔÿ”ÒÛÿL®¯ÿ ,/шY4 t FGÓpº¾þ”ÓÛÿ‰ÈÑÿˆÄÎÿ‚¾Êÿ}·Áÿ»Åÿ}¶Àÿ‹ÆÑÿr¶»ÿ ;;Õ•e)!lj´tÀÇÿÊÖÿ€¼Æÿ»ÄÿŒÊÖÿ†ÃÍÿƒÁËÿ…ÃÍÿ„¿ÈÿŒËÖÿD“ü .-ÝÀ«m= :Zo¦¬¦„X 77&)€¿€ÎÖÿ“ÏÙÿ‰ÇÏÿ‰ÈÏÿ‰ÉÑÿŠÉÐÿ‹ÌÓÿ‹ÊÕÿ“ÐÚÿ€ÌÒÿ#qpï$#н„mJ *a„ -,ÃQ˜Ÿù™Õàÿ‡ÅÐÿ†ÄÍÿ…ÃÌÿ‡ÄÎÿˆÇÏÿ‰ÇÎÿŠÉÑÿŽÍÖÿ›×áÿ+deñ±u5V„XX܃ÃÉÿÍÕÿ‡ÆÏÿ‚ÀÉÿ„ÃËÿºÃÿ|¹ÁÿŒÍ×ÿ‡ÆÐÿ‡ÅÏÿˆÈÒÿ„ÀÊÿƒÂËÿŽÉÓÿs½ÄÿaaéÈ¿¬Šv_Og‰/.Êq°·ÿ’ÐÚÿ‰ÇÑÿ‰ÊÑÿ‡ÄÍÿ…ÃÌÿ‡ÆÏÿ‡ÆÑÿ…ÃÍÿ‡ÆÎÿŠÉÓÿ•ÑÜÿE¤¦ÿ +/Ît<V Œ#ilñ†ÓÛÿ‘ÏØÿŽÌ×ÿŠÈÑÿ†ÃÎÿ„ÁËÿ‚¿Èÿ»ÅÿŠÅÐÿuºÁÿA@Õ¥y=>=cAŽ‘ð’ÐÚÿ…ÀÊÿ{´¼ÿ‰ÊÓÿ‰ÉÔÿ…ÄÎÿŠÈÓÿ…ÃÎÿ‰ÅÐÿ‚¿Çÿ(ggòÊ¿­‹j@ )LZp†š°ÀÀ»™}QUTmN—šú”×àÿÍÕÿ‹ÉÓÿ‰ÈÒÿ‡ÅÌÿŠÊÑÿÌÖÿÍÖÿ™Õßÿi¬²ÿ(efñɾ¬‘t^F`i~£!ZYézÄËÿ˜ÖáÿŠÈÓÿƒ¿Èÿ„ÂÉÿ‡ÆÎÿˆÅÍÿ‡ÇÍÿˆÇÐÿËÔÿ™Øáÿ(]\ð›m1:l¨>‚ƒù—ÕÞÿŠÊÒÿŠÉÒÿ‰ÈÑÿˆÈÑÿ‚¾Éÿ{´¾ÿ‰ËÔÿŒÏÙÿˆÇÑÿ‰ÆÒÿ…ÃÍÿ½Æÿƒ¾Çÿ™ÕßÿZ®±ÿ[\éÌ¿´ }|’·][èyÉÑÿÎ×ÿŠÊÓÿ‹ËÔÿˆÈÑÿ‡ÆÏÿ‰ÈÑÿ„ÁÊÿ„ÀÉÿ‡ÆÏÿŒËÔÿ”ÐÛÿ2‡‡ñ¸p1Kx /.¾O–˜ý™ÔÛÿ‹ÉÓÿŠËÕÿ‹ÊÔÿˆÆÒÿˆÈÐÿ„ÁËÿ€¾ÈÿƒºÅÿuÀÆÿIHÕµ}= ]^ºp¯´ÿ“ÎØÿ{³¾ÿ„ÄÍÿÏÙÿŠÇÓÿˆÆÑÿ†ÄÎÿ‚ÀÉÿ‹ÅÏÿX¤§ÿJJëÍ¿©‹qY;B^h|›°Ï@Bæ4lmëNMæǼ“f3(qs¹r·½ÿ•ÐÙÿŒÊÑÿ‰ÈÑÿ‡ÇÏÿ‡ÅÍÿ‡ÅÎÿˆÈÑÿÌÕÿ™×àÿU¤§ü =;Ü Ä¿´ŠŒ  ¯ :9áL”—ý–×áÿŽÌ×ÿŒÌ×ÿˆÆÏÿ…ÃÌÿŠÉÑÿ‰ÈÑÿ‡ÇÏÿ‹ÊÑÿ“ÐÚÿ{ÈÎÿUVé ‡UTiŒ 76Ð\§®ü”ÑÚÿ‡ÆÍÿˆÇÏÿˆÇÑÿ‡ÈÐÿ…ÄÍÿ~»Ãÿ¾Èÿ‡ÇÑÿŠÈÓÿ‹ÍÖÿŠÈÓÿ‚¾Èÿ~¼ÄÿÏÙÿ’ÉÓÿf«²ÿ!bbìÊÁ¼¨¨ÆGFë`¢ÿ˜ÔÞÿŒËÔÿ‹ËÔÿŒÍÖÿ‰ÉÐÿˆÇÐÿˆÈÑÿ‡ÅÎÿ‡ÇÐÿˆÉÒÿÍÖÿ•ÐÛÿ+`cî©p1+g™WVë|ÁÈÿ‘Ï×ÿŒÍÕÿ‰ÆÐÿ‰ÈÑÿˆÇÓÿ‡ÆÐÿ†ÄÎÿ…ÃÌÿ€¸ÂÿoÀÆÿZYå¸}=SRV4€ä{ÉÏÿŠÃÍÿ»Åÿ†ÄÎÿŠÈÒÿ‹ËÖÿ‰ËÔÿ…ÃÍÿ‚»ÆÿšÛåÿc¡¨ÿJLíË¿±š†qt‹¨» Ä 11Ù&mnïk­´ÿœÞæÿXŸ¤û /.ÙÀ¦ˆg.ed].‰ˆØ…ÑÚÿÏ×ÿ‰ÈÒÿ‹ÊÒÿ‰ÈÐÿˆÅÏÿ‰ÇÐÿ‰ÇÐÿÌÕÿ‹ÕÜÿO˜šþQRì )(Ñ¿¿···À 87áL‰ÿ—Öáÿ‘ÏØÿ‚¼Åÿ†ÄÏÿŒÉÒÿ‰ÈÒÿ‹ËÓÿ‹ÉÑÿ‰ÇÎÿŠÈÐÿ™ÕßÿRŸ£û ..¾p8[” ')É@y{ý„ÊÒÿ‹ËÔÿ…ÄÌÿ‡ÆÎÿˆÉÏÿˆÇÏÿ‡ÇÐÿ…ÃÊÿºÅÿ{´¾ÿ|·Áÿ„ÃÎÿ‰ÈÓÿ‰ÉÓÿ„ÄÌÿ‹ÌÕÿ‡ÂÍÿ˜ÓÛÿhÄÉÿ8‚ó 33àÀÀÒWWçX—›ÿ™ØâÿŒËÔÿˆÇÒÿ‹ËÔÿŒÍÖÿŠÊÔÿˆÈÑÿ†ÆÏÿ‡ÄÍÿˆÇÐÿ‰ÇÐÿŽÌ×ÿ‰Ð×ÿ#MNí•g*$^‚''ÉG‰‹û›ØàÿŠÇÏÿ‰ÈÑÿ‰ÇÑÿŠÉÓÿˆÆÑÿ‡ÆÐÿ‡ÇÑÿŒÌ×ÿ„ÀÉÿ‹ÈÑÿ7nqõ ¼}=GFu9’êˆÒÙÿ†ÂÍÿ{¶¾ÿz´¾ÿƒÀËÿ‡ÈÑÿ‹ËÖÿ…ÄÌÿŒÍØÿ—ÕáÿY–™ÿKLéË¿¾± ´ÀÏ32Û'pqð]¦«ÿ‰ÓÛÿ˜ÓÝÿ‘ÎØÿ€ÈÎÿ?y{ü Ò¿§ƒb1ml†]¥ªÿ“ÑÙÿÍÖÿ‹ËÔÿ‰ÊÒÿˆÇÎÿ‡ÆÏÿŠÊÓÿŒÊÕÿÎØÿ–×àÿi®´ÿ,pqó :<ÝÊÇÌ=@ß$^^èG‘•ü„½Æÿ’ÐÛÿÐÙÿ‰ÆÏÿ…ÃÍÿ…ÃÌÿŠÇÐÿ‹ÌÓÿŠÉÑÿŠÌÓÿ’Ï×ÿÈÐÿ(qsëUYy›ÈjjëwÄÊÿ’ÑÛÿ‰ÉÒÿ†ÅÍÿ‡ÆÎÿˆÇÐÿˆÇÏÿˆÇÏÿ‰ÈÑÿ‡ÅÏÿƒÂÌÿ€»Çÿ}¸Áÿy´¾ÿ€»Åÿ‹ËÕÿÍ×ÿˆÆÏÿ„¿Æÿ”ÐÜÿ•ÕÜÿ>‚„üJJèWWèF“ûsÅÊÿ”ÐÙÿ‹ÊÔÿŠÉÒÿ‹ÊÕÿ‰ÊÓÿŠÊÓÿ‰ÉÒÿˆÇÐÿ‡ÆÏÿˆÈÑÿˆÇÒÿˆÇÒÿÍÖÿ`¶»ÿCFãŠO%a~ $#·-km÷{¾Ãÿ“ÓÚÿŠËÓÿˆÆÐÿ†ÅÎÿˆÇÐÿ†ÄÎÿ‡ÄÎÿ‡ÄÎÿˆÈÒÿ½ÆÿŠÄÎÿ;nqõ ¼}= VWœ`£ÿ™Øâÿ‰ÈÓÿ€½Çÿ~ºÅÿ{´Àÿ|·ÁÿˆÈÒÿ‹ËÕÿÏÚÿÈÒÿ`®³ÿ,srð 00ÙÇ¿¿Ê87Ý!\]çB‘úi¯´ýˆÑÛÿ—ÔÞÿÍ×ÿ‰ÇÐÿˆÇÐÿ’ÐÚÿo¼ÁÿUTæǾ¢…h3~~kjšPœŸû‘ÎÖÿËÒÿ‹ÊÒÿ‡ÇÎÿ‡ÆÏÿÍØÿŽÐÙÿ‹ËÔÿËÕÿ—ÓÜÿtÅÉÿNœ¡ÿ;y|ö0vwöF„‡öX«®ÿ|ÀÈÿ‰ÅÍÿ…ÀÊÿŒÍÖÿ“ÓÞÿŒËÔÿˆÈÑÿ…ÅÌÿ‡ÄÎÿ†ÅÍÿˆÇÑÿŽÎÖÿžÛäÿV£ü;:¸m5U~œ )(Ðhgèkº¿ÿ—ÓÜÿ‹ÊÓÿŒÌÕÿ‰ÉÓÿˆÇÎÿ…ÅÌÿ‡ÇÎÿˆÇÑÿŠÉÔÿ‡ÆÏÿ‡ÆÏÿ‰ÇÑÿˆÄÐÿƒÀÌÿ}·Âÿ~·Âÿ¼Æÿ‹ÌÕÿ‚¼Çÿ¼Åÿ—×áÿŽÏØÿ‚ÆÌÿ†ÄÌÿÑØÿ•ÒÛÿŒÈÒÿ‡ÄÎÿ‹ÌÕÿŽÐÙÿ‹ËÔÿŠÊÒÿ‰ÈÑÿ‡ÄÍÿ…ÃÌÿ‡ÆÏÿˆÉÒÿˆÇÒÿ—ÓÝÿW‘•ú#$¼vC :w¦FDæe¦«ÿ•ÓÜÿŽÎÖÿŒÌÖÿ‰ÈÑÿ†ÅÎÿ‰ÈÓÿ‰ÈÓÿˆÇÏÿ‡ÆÐÿ‡ÆÏÿ¼Æÿ‹ÃÎÿ@suõ ¼}=[Z1QR´Q‘”þ•ÔÝÿÌ×ÿˆÆÐÿ…ÂÌÿ¹Äÿ}¸Áÿ~¶Áÿ‹ËÓÿ‰ÄÍÿ‹ÃËÿˆÌÓÿ[ž£þ!_`ð>=Ý DCà-tsô\¢¦ÿƒÆÎÿ‘ÔÝÿšÙäÿ‘ÑÚÿ‹ÊÓÿ‰ÉÑÿˆÅÏÿ…ÃÌÿ‰ÆÏÿ–Õßÿ`¦©ÿFEç Ä¿¨‡d+!!qp¤_¨¬ÿ—ÒÚÿÌÕÿˆÆÍÿŠÇÑÿÏÖÿÐÙÿ‹ËÔÿŠËÒÿ‹ÉÑÿËÓÿ”ÏØÿ‘ÔÛÿˆÔÛÿ‘ÌØÿ‹ÄÏÿ†ÁÌÿ‡ÅÏÿˆÆÎÿ…ÃÍÿ‰ÇÏÿ‰ÇÐÿˆÆÏÿ‡ÅÎÿ‡ÅÌÿˆÇÏÿŒËÓÿ–ÓÜÿk¾Áÿ]]â‚F"^— 32Ú?z|ýlµ»ÿ™ÔàÿŠÈÑÿ‰ÉÓÿŒÌÖÿ‹ÌÔÿ‹ËÔÿ†ÅÎÿ…ÆÍÿ‡ÅÍÿˆÉÒÿ‡ÆÎÿ‰ÄÍÿ†ÌÕÿ{ºÂÿ“ÏÙÿ…ÁÎÿ}¶Ãÿz³Áÿƒ¿Éÿ¼Æÿ¹ÂÿÒÜÿ’ÒÛÿ“ÓÝÿ‹ÉÓÿ‡ÆÎÿŠÉÑÿˆÇÎÿ‰ÈÐÿÎÕÿÐÙÿŒÍÖÿŠÊÒÿ‰ÊÒÿˆÆÍÿ‡ÆÎÿ‡ÆÎÿˆÇÐÿŠÈÑÿÂÍÿ,lnñŸ` :{FGØQ™þ—ÔÝÿŽÍÕÿŠÉÓÿŠÊÑÿ‡ÆÑÿÌÖÿ‹ÊÓÿ‰ÉÒÿ‹ËÔÿŠÊÓÿˆÈÒÿ‚¾Èÿˆ¾ÊÿA~€õ¼ƒTRQNMªI˜šîtÆÌÿ•ÑÜÿŒÉÔÿ†ÂÏÿ¸Äÿy±¾ÿ¾Èÿƒ¾Èÿ~¶Áÿ‘ÑÚÿ¡âìÿ†ÌÒÿ{ºÁÿw¶½ÿÑÙÿ–ÔÜÿËÓÿŽÍÕÿÐÙÿŽÎ×ÿŠÊÓÿ‹ÉÓÿˆÇÏÿˆÆÎÿ‡ÄÎÿÊÓÿ—ÒÞÿL‹þ 32â Å¿¤‚e+tt "vx©Rž ý‹ÉÑÿ“ÏÖÿŽÌÔÿ‰ÇÏÿ‹ÊÓÿ‹ÊÒÿŠÇÑÿ‡ÆÎÿˆÇÏÿ‰ÈÎÿ‰ÄÎÿ…ÁËÿ€»Åÿ¾Èÿ…ÃÍÿ‰ÉÕÿ‰ÇÑÿ…ÃÎÿ†ÂÌÿ‡ÃÌÿ‡ÅÎÿˆÇÐÿˆÄÍÿŠÇÑÿÌÖÿ‡ÆÎÿ4€ï &&Ÿ\"c>>Ç@ù¿Çÿ¹ÃÿŒÍ×ÿ‰ÊÒÿ‰ÉÒÿŠÊÕÿÍÖÿŒÌÖÿ‡ÆÑÿ†ÅÎÿˆÅÐÿˆÉÒÿˆÊÓÿ‘ÌÕÿ\¼Àÿ"omúq²¹ÿ‹Ê×ÿ†½Ëÿ¸Ãÿ¼Åÿz³½ÿx°ºÿ…ÂÌÿŒÌÖÿÐÙÿÎÕÿ‡ÆÏÿ†ÄËÿˆÇÏÿ‰ÊÒÿˆÈÏÿŒÉÒÿ‹ÌÔÿŠÉÑÿ‰ÆÎÿˆÇÏÿˆÈÐÿ‡ÅÍÿ‰ÆÏÿŽÆÒÿY•œÿABÄg6 AEDÀRšŸû‘Í×ÿ“ÌÕÿŽÈÒÿŒÅÎÿÉÒÿŒÆÐÿŒÆÑÿŠÇÐÿŠÇÑÿ‰ËÔÿ†ÇÏÿ†ÅÐÿ…ÄÍÿ‡¹ÅÿEŽ’õÔ`" LL]\^1twß\¥§û‡ÈÐÿŽÉ×ÿ‚¼Éÿ|µÀÿ€»Åÿ}µÀÿw¯¹ÿ€»ÅÿÌÕÿ’ÒÛÿ“ÔÜÿÍÕÿ‰ÆÎÿ‰ÆÎÿ‰ÉÐÿ‰ÈÑÿˆÇÎÿ‹ÌÓÿŠÉÒÿ‰ÈÐÿˆÇÏÿŠÉÐÿ‰ÇÍÿ‡ÅÎÿ†ÂÎÿ‹ÅÐÿMŠÿACçǾ¥y<~nmŽ@–˜âe¸»ÿ‘ÓÚÿ“Í×ÿŒÊÓÿŠËÔÿŒÌÓÿ‡ÅÎÿˆÅÏÿ‡ÆÎÿ…ÄÍÿ~¹Äÿ€»Åÿ‰ÇÑÿ‡ÅÏÿˆÈÒÿˆÆÐÿ‡ÅÐÿ†ÃËÿ†ÃËÿ‡ÅÎÿ‰ÇÐÿ‰ÄÎÿ”ÑÙÿ–ÛãÿMŽ’þ ?>·e+"??›MŒüÌÔÿ˜ÍØÿ…¶Áÿ”Í×ÿ”ÎÙÿŽÊÕÿŒÌÖÿÌÖÿÏØÿŒÊÔÿˆÇÐÿˆÉÒÿˆÇÐÿ‡ÈÑÿ—Óßÿb³ºú87á ZZÝN’–üt·Àÿ†ÇÒÿ•ÍÙÿŽÅÐÿ‡½Èÿ{²¼ÿ}·Àÿ‹ÉÒÿ‘ÓÜÿŒÍÖÿ‡ÅÎÿ†ÄËÿˆÆÏÿ†ÅÎÿˆÅÎÿ‰ÈÑÿ‹ËÓÿ‡ÆÐÿˆÅÍÿ‡ÆÏÿ‰ÆÐÿ’ÇÓÿV¨­ÿSSÓ‚4  99)GŽ‘à‰ÐØÿ‚ÆÍÿ€ÅÌÿÈÏÿÈÎÿÊÐÿ€ÉÏÿ|ÉÏÿŠÔÛÿ™Ößÿ›×áÿ“Í×ÿ‹ÆÐÿ‰ÇÐÿˆ»ÅÿEš›õà`"PP5ZZ‡6‡ˆÚ\«°ÿ„ÅÑÿŽÅÒÿ‹ÅÐÿƒ¿Éÿ~·Ãÿy°ºÿy²»ÿ…ÂÍÿÒÛÿŽÐÙÿ‰ÆÏÿ†ÂËÿ†ÆÏÿˆÆÏÿˆÅÎÿ‰ÈÑÿ‹ËÓÿ‰ÈÑÿˆÅÌÿˆÇÏÿ‡ÅÍÿ‚ÀÊÿ{¶ÀÿŒÊÔÿŠÔÞÿJ—šÿ 77äõ|<iilk<{zCœžãk·¼ÿŒÇÑÿ‰ËÔÿ—×áÿ“ÒÜÿ’ÎØÿÌÕÿŠÆÏÿ|µÁÿƒ¿Éÿ‰ÉÓÿˆÆÐÿˆÆÐÿˆÈÒÿ‡ÅÎÿ†ÁËÿ†ÁËÿˆÅÎÿÊÔÿÎÕÿp»ÀÿAŽðNRÅU*‘¸·ÿ4Š‹oÆÌÿgÀÆÿ\¼½ëS¯²ë\¼½ç`º¿ü„ÆÎÿˆÈÑÿÍÖÿ‘ÒÚÿ‘×âÿ•ÒÚÿ‘Î×ÿÌÕÿŒÊÕÿ•ÓÝÿYšœù¼ŽEE‰rs–4‚ÞIˆŠæT ¤çlºÁÿ‡ÀÊÿ~µ¾ÿ{´¿ÿ‘ÌØÿ”ÓÜÿŽÏØÿˆÉÐÿ…ÃÍÿ‡ÈÑÿ‰ÈÑÿ‡ÄÏÿŠÉÒÿŠËÔÿŠËÔÿ‘ÎÙÿ™Õßÿf¬±ÿ mkÔ|: <··3µµf=ÃÃt9À¾t8¿¾t8¿½t8¾½t8¿½t9¼¿t(šš—0„„ÞE„†æN‘—æV®²ñx¿Æÿ‰ÌÕÿžÑÝÿO®±ú7=µ‡`"88TS0Z[”2}ÜRŸ¤ÿyÆÍÿÌÕÿ™Öáÿ’ÏÙÿ„½Åÿ€¸ÀÿˆÂËÿÍ×ÿŒÍÖÿ‰ÊÒÿ‡ÄÍÿ‡ÆÏÿ‰ÊÓÿ‡ÄÏÿˆÇÒÿŠËÕÿŠÉÒÿ‰ÊÓÿ‰ÇÑÿ‚½Çÿ|¶¿ÿ‰ÇÑÿË×ÿ‘ÑÚÿ>‡ˆþ;9å°|<pp=$|{1€¦5’ÓVŸ¥ùiª°ùn´»ùoÂÊú€ÉÒÿ‹ÂÌÿš×áÿ–ÔßÿŽËÖÿŠÈÓÿŽÌÖÿ‹ÉÒÿŽÉÒÿ’ÎÙÿ—ÑÜÿqÁÆþH”•û'ouÜ 21}Fs¢¤ÿs¢¤ÿ0st¦‘¸·ÿs¢¤ÿs¢¤ÿs¢¤ÿihx(jl¦%lm¦,{~¦,„†Æ?“•å_ž¥ùh©®ùn»ÁûŽÍÕô¡Ýéÿ[“˜ôm= QP%RR%fdAjk”.xx¦2‡ˆ¦)„…ÃK”–ú€ÃÊÿšÖßÿ–ÒÜÿ‘ÍÙÿÉÒÿŠÉÒÿŽÍÖÿÌÕÿ“ÐÛÿ”ÏÚÿÁÊÿMŽ’û]]Ï ""x2 *ORwˆŠ>=§"XZÉ1€ã]¡¦úNµ¸ùR^«O0 OU5X\ˆ'll¦,~}ÊN•™ùb ¥ùy²»ÿy²»ÿt»ÁÿšÕàÿ”ÐÛÿ”ÐÚÿŒÉÕÿ‰ÆÐÿ‡ÄÏÿˆÇÐÿ‡ÇÐÿ‡ÇÑÿ‡ÅÏÿ„ÂÌÿ…ÄÎÿ~¸Âÿ‚¿ÉÿÏÙÿŒÊÔÿ•ÐÚÿ™ÙäÿM—›ï—k3hg'_^O‘¸·ÿ‘¸·ÿU”•ÿ*yzË2npÄC“•Û_²µÿ‡ÅÍÿ„ÁÉÿˆÄÎÿ„ÁËÿ‚ÁÉÿZ­²ÿ?ˆŠâki¹ >=pEPK =M /2$ GF=YWOSQo0bd­E’”Û2}~Ë ..[4 NNKJtCœžÿ>~ƒÛA˜šòg¸½ÿÁÉÿw·¾ÿx¶¾ÿv²»ÿ]®²ÿ=æ#bcØ?>•""I0Oh}‘£´´²« ,,žnm‚ ,6S NMKJOIHOc¢§ÿA†‰ÿ gfÄ>‚ÛJ£¥ðtÁÆÿ‡ÆÎÿ‰ÉÒÿÇÎÿŒÇÑÿŠÅÐÿ‡ÂÍÿŠÅÐÿ‰ÂÏÿŒÅÑÿ‡ÀÌÿ”ÑÛÿ£äîÿŠÖÝÿ…ÂÌÿe«±ÿ+Œ‹Ìl= VV‚¾Ç„½Ç«SRI#hjm&{yŒ)}|Œ&xyŒ&tsŒkjx >>5((&SSQPxx[[feZ]YddŒ!cdŒ dbŒacŒ_aŒ\^‹JIN)). Ij~”¨¼Á ÃÄ Ä¿»—‚l:FFfe^]V#_aŒ$opŒ2žžÿ,„ƒÙI†ðN‰ŽðP‹’ðV“˜ðW•›ðY—žðV•™ð[™ðZ—›ð-ƒ…Ûce¤VUœJJN 1p”©¹!!Ñ''ÒRQã3koôB‡ˆô-mmñ //Ü¿»¬ŠjMMW1LK3 KJ3 PO3`_3^]3^]3_]3VV3 PO3WV1 1q µ&&ÓRRèC†‰ük«°þpÃÇþ’ÏÚÿœÛåÿ…ÆÎÿ9„ú 22ׯ¿ª‘y_(3 55Ÿ!ihÝMšœøxÃÊÿ‘ÑÚÿ•ÒÜÿÎØÿ‡ÂÍÿ„ÂËÿ’ÏÙÿÎÕÿL™úFGëÉ¿¹Ÿƒb+&?x|Ô€ÌÒÿ¨ßèÿ•ÒÜÿËÔÿ‰ÈÒÿŠÊÓÿ‚¿Èÿ€¼Åÿ‹ËÓÿÏ×ÿšÖßÿV™ÿXWêÑ¿¿¢jMWVWW„D‹òŒÌÕÿ“ÐÙÿŒÉÒÿ‰ÆÏÿˆÆÏÿ…ÃÌÿŠÉÐÿŒÌÖÿŒÌÔÿŽÎ×ÿ–ÓÜÿp»Àÿ7{|ù 23ßý©•sI[Y„L•™û‘×Þÿ’ÏÚÿ‰ÆÏÿˆÅÎÿ‰ÈÑÿŠËÔÿÎ×ÿ‹ÌÕÿŠÉÒÿËÕÿ“ÏÙÿŠÌÔÿP“ÿ 54âÀ¿³‘a" ML§[ £ý›ØâÿŠÊÓÿ‰ÉÒÿÍÖÿ‰ÉÒÿŠÉÒÿŒÌÕÿŠÉÒÿ‰ÉÒÿŠÊÓÿÎ×ÿ—ÕÞÿF‘•ýWYé *,Õ¿¡a"MM>+ilÛm¬±ÿ˜ÔÞÿŠÇÐÿˆÈÑÿ‡ÆÏÿ‰ÇÐÿŠÉÒÿŠÉÒÿ‡ÆÏÿ‰ÊÓÿŒÌÕÿÏÙÿˆÍÖÿd¬±ÿ%^^ó%$Ña"VUW]_Ó`¢ÿ•ÒÜÿŽÎ×ÿ‹ÊÓÿŒÍ×ÿ‹ÍÕÿŒËÔÿ‰ÊÒÿ‰ÉÒÿ‰ÉÒÿ†ÄÍÿ‹ÈÑÿŸÜçÿ~ÁÈÿ.vwÓŠ^¤¾Â˜¶¹Ž­°‡§©‚¤¦VUK#a`ÓV£¨øÉÒÿˆÃÍÿ„ÀÉÿ„ÁËÿ…ÁËÿ¾Æÿ¿Èÿ…ÂËÿ†ÃÌÿ–Õàÿ…Ï×ÿ^¬°ÿ'sr¹a1 °ÅÇš¸º’±³‡¨ª€¡£zŸv•—v“•v‘“t‘p‹n‰‹mˆŠj†ˆlˆ‹q‹pŠŽpŠk‡g„‹`}„ Wv~ Ts| Oox Klv IkuKnyMo{Np|Or}Ru€Tv„Uw„Sw„Sx…Ty†U{‡Qx„MtJq Gm| Fm{ In|DixVV-feFŠŒúŽËÕÿ‹ÅÏÿ½Èÿ…ÂÌÿƒ¿Êÿ‚¾Éÿ”ÒÜÿ—×âÿ`£¨ÿ4wzñFF· ',g" ·ÈÊ ¼¿’±´ ‡¨«"¡£(xœž)t–—/r‘0r‘/t,r‘,n‹Œ0mŠ‹0l‰‹3nˆ‹3o‰Œ4qŠ2pŠ5k‡Ž3f„Š3aˆ3Ww~5Nnw6Mox-Jlv,Ikt+Hjt,Hlx2Jmy/Mo{3Or~/Ru0Swƒ1Tx„/Ty†-Ty‡-Sy†'Qw„%Mt$Hp~!En|Cjy!@hv&EkzElzFkyEjxHlzKnz Jlx Kly KlxJkwKkw$$KK—=…‡âh²·ÿ›×áÿ“ÒÛÿ”ÒÜÿˆÈÑÿe¨®ÿ<}~ë BA¿77s(ÄÎÎ®ÃÆ•³µ+…§©4{Ÿ 8tšœAo“•Dn‘JpŽ‘OrŽ‘FsŽGo‰‹Jmˆ‰Jg†‡Mi†‰Ilˆ‹JmˆŒKl‡ŽGk†Cc€‡L^{‚HSv~IKktJCfoMAeoN@dnPAeoLDgsFFhuDGjvEKnzGNq}FNr€HNqHOt‚EQvƒAPx…=Nv‚7Ks€6Hp}5@hu;Ejw3Fjw3Dhu5Ght-Fiu)Efr'FfrDepDepDeqDerDfqDdp Eeq EfrPPQPt-xyÊ_]œ 98Y" ÄÎÎ ‰¬°D{¢¤^pššci““ef‘‘na‰‰y\‚^~€„]|ˆa‚a[{}‡Uvv‰Vux‡Tuy…Wx~Opv†Jlt‡Imu„IltDgpƒ9]f…1Wa‰3Yd„4Xcx4Ycx2Xd4Yf8\i~:_m~gus:crx;est=gul;esh7aqd3\mg3]le6_n]5]n_7_nb7_nc9`p_:bpX>drQ@esJ?dqHAer?>bnB>`mB>`l9<\h8>_k+@`l%@`lAbmAbnBdpCdoCco CcoµµFt ¡ln››vdy[……‚Yƒ„…X}~‹Vy{‘Yz{™Yxz XwyTsuNmo¤Lmn¢KmpœHioœIjq—Gjq”Aem˜_k?_k?_k @`l«ÂÄ@u¦¦xi˜˜’d’‘‘aŽY„ƒ”QyyžNrt§Nqr¯Rst²Vtv°Tsu¬Lkm´Cce¿Cdf·Bbfµ9\a»9_f´:`f²3Yaº0Xaº+RZ¼&MW¿"JS¿DOÀCN½EQ·ESº!GU¹$IX¸%L\·)P_¶,Td°-Vf±)Td²$O_·&Qbª(Rbª"M^¸$O_±#P`«%P`£(Sc›)Te™(Sd™+Uf˜-Uf—-Vf-UdŒ1Yg†4\jƒ4[h}1Xd}1Wc0Ta2Vcn/S`f/Q^h1R_a3VaS7ZeK7YeD8Zf=8Zf2:\h*<\h!<\h=]i=]i ޱ·mo¡¡©c“°\‹Š¨Xˆ†£T€¨Nwu®Flm¸DghÄDfgËIjlÅLkmÃEegÉ>]_Ñ>^`È3V[Ï,QWÕ(PWÓ(RYÓ&OV×$LTØCKÜAIÚ@IÚdeÎDë=Dë;Cé;Dê;Dê9Eì9Dì8Eê8Gê;Kç>Oæ?Qã>Oá?PßARàARá@Qà?QáBSÚCTÑEVÏGXÊHZÊGXÐ HZÇ#L^Ã#J[¾ IXÁ$MZ·%M[¼'N[¹&LX¶$JW±$IV®%HV¤%GUŸ%GUš'JW’,O\,P\}0S`o/Sah2Wc^2VcZ2UbL1S`F4Vb86Wd+6Xb 7Wb3T` /O\ˆªªpi““Ð[ŠÕR„ÎJzwÐEsqÏ@ihÓ8`aß1YZè1XYç0VXæ-QTî-PSô-OR÷*JOù&FKù#CGõAHô>Fõ8?÷5=ø8?ø;Aö;Aõ9?ô9@ô:Aõ8B÷4>ø3?ù5B÷7Fõ9Hó:Lò:Iï8Ií8Jð8Jò;Lë=Oî;Míû 3Aû 4Eú 5Fú 7Gù 6Gù 5Fù 6Hø :Lö9Jú 8Jú 8Iú8Iù;Mô?Qî?Rç?Ræ@Rà@NàANÞ?LáBOØ?LÚANÒ@MÓ@NÎBQ¾AO¹BQ¾ DQ· ES¸"GU¬$JX 'KZ•&JZ‹&IX‰)LZw)LYi)MY[+LXL+LWB,MZ-.O\/O\ †Ÿ‘p“çhìVƒ‚ëGvséAliê9dcé1[Zí,VUï&PPô IIúDFü>@ý9=ÿ59ÿ/5ÿ -3ÿ +1ÿ (0ÿ&0ÿ +4ÿ .7ÿ +2ÿ ).þ */ý -3ü /4ü /4ý 17þ 18ÿ 3<ÿ 3=ÿ 4?þ 3@þ 2Aý 3Dü 4Dÿ 4Eü 2Bü 4Dü 7Hý 7Hý 6Gÿ 5Gû 4Gû8Jú;Mú:Mö;Mò=Mí>KîIð;HìNËCR¼!GW´!FU¯!DT¦ CQ§"FT—"HS†#GSw%GSl%GUZ*KW<*KV.+KX!,KY.M[«¸·arßi‹ŠõNtsó:ecò7edó4a`ó-XXö%PPö!MMøFGû>?ü:;þ 69ÿ 37ÿ .4ÿ )0ÿ (.ÿ +3ÿ +4ÿ'3ÿ%1ÿ%0ÿ (/ÿ )0ÿ )0þ).þ -2þ,1þ-3ÿ/6ÿ3<ÿ5>ÿ5@ÿ3=ÿ-;þ/?þ0@þ0@þ.=þ0@þ3Cÿ2Cÿ2Dÿ2Cÿ1Dþ 4Fý 4Eý 4Fú 3Fø 4Eø 6Dö:Gñ9Fö=Kø:Hù9Fñ6D÷4Aö3Aô5Cí9Hé:IÝK¨?L–ANƒ!CQs$ER_#CQQ'GU:+KZ(,MZ,LXœ«Ÿ¤mˆwôXwaúHmXø@gZù:e[ú.`Rû#UGýNCþG<þ:3þ60þ33ÿ43ÿ-1ÿ )+ÿ )-ÿ -1ÿ25ÿ 04ÿ+1ÿ )-ÿ ),ÿ +,ÿ ,-ÿ--ÿ--ÿ//ÿ/0ÿ-3ÿ/5ÿ0:ÿ/:ÿ-9ÿ*7ÿ&4ÿ'7ÿ*;ÿ*:þ)8þ(9ÿ .?ÿ 2Cÿ 2Bÿ 2Cÿ 3Dý 2Cþ 1Aþ 0Bý .?þ,;ý/<ù 2?ù 2?û 5Cû 2Aý 3Bû3Dü6Fü5Fú2Bø 0?÷4Dò8Jì8Jã9Kà:JÚLÈÿ .?ÿ 0Aÿ 2Bÿ 2Bÿ 1Aÿ 1Aÿ 2Aÿ 2Aÿ.<þ*7ÿ*7þ+:þ.=þ /?þ+;ÿ+;ÿ-=þ-=ý,>ü /Bû 0Cø1Eò5Fé7Gå9FÛ8FÕ6EÏ8FÂ8Hº7F³:Iª:Jž>NŽ"FUy(IVd)KYJ'JX3)KY"(KX )MZ«¤yi|hèƒÿ‚¤|þMtXþ(WEþ O@ÿJ;ÿG:ÿB6ÿ=3ÿ;3ÿ=4ÿ73ÿ3/ÿ /,ÿ -+ÿ 00ÿ 01ÿ *+ÿ &'ÿ %&ÿ &(ÿ )+ÿ .0ÿ 01ÿ13ÿ 35ÿ 48ÿ25ÿ-3ÿ+0ÿ)1ÿ)1ÿ)3ÿ*4ÿ-=ÿ):ÿ&5ÿ'6ÿ+;ÿ->ÿ,<ÿ,;ÿ->ÿ->ÿ.>ÿ/?ÿ2Bÿ1Aÿ1Aÿ 3Dÿ 2Cÿ +;ÿ )8ÿ *:ÿ ->ÿ -?ÿ )<ÿ'7ÿ$6ÿ (;ÿ )<þ (;ý )>ü +?ú-Aø 1Aó 3Aê2Aâ3BÕ4CË5DÃ5D½6Dº7E³ÿ1Aÿ2Aÿ0@ÿ->ÿ -?ÿ/Aÿ -?ÿ *<ÿ (9ÿ );ÿ -?ÿ ,?ÿ (:ÿ &:ÿ$6ÿ 3þ!4þ &;ý *?ý ,=ü .=ú />ó 0Aã3BÕ4CÐ4CË3BÌ8FÄ;J¿=J±=K¡ CP‹"FSv$JYZ$IV?%IY&'N^"+Vg2^pˆŸ‹ªŠŸ|ï†tÿh‚VÿLwRÿ=€iÿ8|hÿ.eTÿ'VIÿ%QEÿ#PDÿ ODÿF<ÿ@7ÿ;3ÿ 4-ÿ 3+ÿ70ÿ;4ÿ:5ÿ86ÿ75ÿ 33ÿ 13ÿ .1ÿ*/ÿ)1ÿ-5ÿ.6ÿ.8ÿ08ÿ 3;ÿ 37ÿ04ÿ-/ÿ),ÿ)5ÿ+9ÿ.>ÿ/>ÿ-=ÿ,<ÿ*9ÿ,<ÿ->ÿ-<ÿ-<ÿ0@ÿ2Cÿ4Dÿ3Cÿ0@ÿ2@ÿ5Fÿ 6Gÿ1?ÿ*8ÿ)8ÿ-<ÿ->ÿ+;ÿ+<ÿ):ÿ&6ÿ%6ÿ$4ÿ#3ÿ#4ÿ%7þ):û ,?ó /@ì /@è 1Bâ5FÛ5EÔ8GÎ8FÊ5ÿ7.ÿ7/ÿ7/ÿ80ÿ81ÿ93ÿ:3ÿ:4ÿ63ÿ 64ÿ 66ÿ79ÿ 49ÿ 05ÿ.5ÿ/8ÿ 4>ÿ 3=ÿ19ÿ07ÿ04ÿ/3ÿ.1ÿ-1ÿ.:ÿ+;ÿ+9ÿ.>ÿ2Bÿ1Aÿ,;ÿ*9ÿ+:ÿ,;ÿ.>ÿ0Aÿ3Eÿ5Gÿ5Gÿ6Gÿ7Fÿ6Eÿ7Fÿ8Hÿ6Gÿ5Eÿ3Cÿ1Aÿ1Bÿ.?ÿ*;ÿ(7ÿ'8ÿ&7ÿ#3ÿ.ÿ-ÿ0ÿ#3ü%6ù'8ó-<î 1Cæ 7Gã 0>Þ /=Ù9HÌ:H¿=K®@PžDT"K\m'RdR1_q>>jz3Ny†.aŠ’/v˜ "f‘™‹«±­¼­`Šª‚ÞºÒšÿ¯ÄÿªpÿwŸrÿpªÿIˆsÿ$\JÿO>ÿ D4ÿ <-ÿ >0ÿ;.ÿ;1ÿ;3ÿ=4ÿ>4ÿ=0ÿ9,ÿ 8)ÿ 8/ÿ 63ÿ 33ÿ 33ÿ 05ÿ-3ÿ-7ÿ 1>ÿ 3?ÿ 1=ÿ-5ÿ,3ÿ/0ÿ33ÿ 52ÿ 64ÿ3?ÿ1@ÿ/>ÿ0>ÿ1@ÿ0@ÿ.>ÿ-;ÿ,;ÿ-=ÿ.?ÿ0Aÿ0Bÿ1Cÿ2Eÿ4Eÿ4Dÿ3Bÿ3Cÿ6Gÿ8Iÿ8Hÿ5Eÿ4Eÿ5Fÿ3Cÿ-=ÿ+;ÿ,;ÿ,;ÿ+:ÿ%9ÿ 7ÿ 4ÿ#7þ(;ý)>ú0Bö5Hò3Dî3Dë/=å .=Ý7GÎ=MÃ=NµAQœ!L]€'Ugi3`sUDp~GSŒAk’š4i˜b—ˆ©°¤¸¤±ƒëÆÜ¦ÿ¼Ð•ÿ¨Æƒÿ¸…ÿh¡…ÿ9s`ÿVDÿVDÿO>ÿI:ÿVGÿXIÿMAÿC9ÿ=3ÿ;0ÿ=0ÿ@0ÿB3ÿB9ÿ?<ÿ 98ÿ 33ÿ-1ÿ+1ÿ/:ÿ 7Dÿ 3?ÿ.<ÿ-6ÿ-5ÿ12ÿ 33ÿ 52ÿ 63ÿ4@ÿ7Fÿ6Fÿ2@ÿ-:ÿ,:ÿ0?ÿ0Aÿ-<ÿ-=ÿ-?ÿ->ÿ,=ÿ*;ÿ+<ÿ-=ÿ/>ÿ0?ÿ/>ÿ-<ÿ*8ÿ*8ÿ-<ÿ.>ÿ/@ÿ4Fÿ6Hÿ4Fÿ1Cÿ,=ÿ)9ÿ)>ÿ$<ÿ 3ÿ3ÿ$7þ';ý*=ü-@ù+;÷2Dô2Có+;í ,;ã6FÓÿI=ÿG9ÿG6ÿG5ÿ H4ÿ B6ÿ :5ÿ =9ÿ :8ÿ*-ÿ/3ÿAJÿ 3>ÿ -6ÿ -7ÿ /4ÿ 27ÿ 76ÿ 98ÿ 93ÿ 83ÿ7Aÿ6Dÿ7Dÿ5Bÿ0>ÿ+9ÿ)6ÿ(5ÿ)6ÿ'5ÿ(6ÿ)8ÿ->ÿ0Aÿ/Aÿ/Aÿ /Dÿ /Dÿ .Aÿ 0Dÿ2Gÿ 0Eÿ /Dÿ 0Eÿ *<ÿ %8ÿ )=ÿ *<ÿ#3ÿ#3ÿ -Bÿ .Fÿ(Aÿ%<ÿ#7ÿ#7ÿ%9ÿ(:þ);þ)9ý-@ü3Fú1Dù->ð.?å:KÕ@U¾L`§'Vi‘4ds|Dsj]ˆ‘Uv¤;irŸ¸œ«£Ì—ôÖç±ÿÞò³ÿÜø³ÿ˜ÄÿO‚`ÿ6oTÿ.oRÿ"hMÿgMÿ#w\ÿ5š}ÿ0†pÿXJÿPCÿL>ÿF9ÿP?ÿZEÿUAÿQEÿLFÿ <9ÿ20ÿ)*ÿ)-ÿ /5ÿ).ÿ*2ÿ)0ÿ&+ÿ%)ÿ&%ÿ,+ÿ2-ÿ 95ÿ =Fÿ ;Hÿ5Bÿ.:ÿ)4ÿ)4ÿ,9ÿ-<ÿ,:ÿ*9ÿ+:ÿ,<ÿ-?ÿ.?ÿ->ÿ+=ÿ ,?ÿ -@ÿ ,@ÿ .Bÿ 3Fÿ 1Eÿ 0Eÿ 1Eÿ .Cÿ -Bÿ /Bÿ -@ÿ );ÿ#5ÿ!3ÿ$9ÿ%>ÿ(?ÿ+Aÿ-Bÿ+Aÿ);ÿ%7ÿ)=ÿ%5þ&7þ.@ý/Bù->î6Gà@UÇJ^®$Uh™3gtˆDtrS€‰3‹«°šº—©i’`îawOÿ’¦wÿÌç¯ÿ…·€ÿGˆXÿB…XÿFˆ]ÿC†aÿ?‚aÿCŽmÿJ¨‹ÿ<•zÿ%zdÿP@ÿL<ÿL<ÿI:ÿJ<ÿOAÿQGÿIEÿ ?;ÿ 73ÿ 51ÿ 20ÿ 1/ÿ 53ÿ --ÿ +,ÿ--ÿ+,ÿ)(ÿ&&ÿ'&ÿ))ÿ(.ÿ-5ÿ1:ÿ2<ÿ/9ÿ-8ÿ,8ÿ+8ÿ*6ÿ)6ÿ)7ÿ*7ÿ+:ÿ+:ÿ)9ÿ)9ÿ*>ÿ+>ÿ,?ÿ /Cÿ 2Fÿ 2Fÿ 2Eÿ 5Hÿ 4Hÿ 2Eÿ +=ÿ ):ÿ -?ÿ ->ÿ%5ÿ$6ÿ';ÿ';ÿ&9ÿ%7ÿ#5ÿ$6ÿ%6ÿ)<ÿ%6ÿ#4ÿ(:ÿ-Aü1Fô 6KèAVÔI\»"Td¨0co™Q†aDy€‰§«±Ž¯LpFò;L-ÿWkEÿ•·ÿ†º‚ÿ`¦oÿX¡mÿUœlÿJeÿB†cÿF’oÿO¯ÿ?šÿ[Hÿ A1ÿ @1ÿ =/ÿ 6)ÿ 3)ÿ 3(ÿ 4-ÿ :5ÿ <7ÿ :5ÿ 94ÿ 41ÿ 2/ÿ97ÿ 64ÿ 76ÿ::ÿ ;:ÿ 88ÿ 33ÿ/0ÿ*,ÿ!)ÿ)0ÿ3<ÿ 7Aÿ 4>ÿ1;ÿ/;ÿ.:ÿ.:ÿ-:ÿ,:ÿ-:ÿ-<ÿ0>ÿ0@ÿ->ÿ+>ÿ-?ÿ-@ÿ0Cÿ 2Fÿ 2Eÿ 1Eÿ 5Hÿ 7Iÿ 3Gÿ /@ÿ .?ÿ 1Bÿ /Bÿ +<ÿ(9ÿ(<ÿ*=ÿ)=ÿ'9ÿ%9ÿ);ÿ+>ÿ&9ÿ-Bÿ+>ÿ"3ÿ#5ý3Iø :QíAVÞN_Ë!Td¸.amŸ]†‹CF~‚ zœ|¯LpGóH]=ÿAT4ÿa€Wÿ‹ºƒÿ¸zÿk£hÿm¨oÿr¯}ÿi­‚ÿVštÿ3t\ÿ#aLÿOAÿO@ÿNAÿC7ÿD9ÿE;ÿ:1ÿ93ÿA=ÿB;ÿ>6ÿ:3ÿ:1ÿ 7.ÿ9/ÿ 5-ÿ 3+ÿ /,ÿ 0-ÿ/2ÿ02ÿ03ÿ-3ÿ-3ÿ 38ÿ 6=ÿ 4;ÿ28ÿ2:ÿ3=ÿ2;ÿ/9ÿ-8ÿ,8ÿ,7ÿ,7ÿ-:ÿ/=ÿ.>ÿ.@ÿ0Bÿ/Aÿ1Cÿ3Eÿ2Cÿ2Cÿ4Eÿ3Dÿ4Eÿ7Fÿ7Fÿ3Aÿ-;ÿ*7ÿ(6ÿ(7ÿ+;ÿ,<ÿ):ÿ'7ÿ%7ÿ%8ÿ$5ÿ+?ÿ,Aÿ#5ÿ 3þ(=û3Jõ ÿI@ÿQIÿMIÿD=ÿ>6ÿ>3ÿA5ÿA3ÿ:,ÿ<1ÿ:/ÿ 3.ÿ 3-ÿ13ÿ 23ÿ05ÿ.4ÿ05ÿ 49ÿ 39ÿ.3ÿ-3ÿ/6ÿ18ÿ/9ÿ09ÿ0:ÿ1;ÿ/;ÿ-8ÿ-9ÿ/<ÿ/>ÿ.Aÿ/Bÿ-?ÿ/Aÿ2Cÿ0Aÿ1Bÿ3Eÿ6Gÿ5Fÿ ;Lÿ ÿUOÿ#e_ÿPNÿC<ÿG>ÿF8ÿE3ÿI6ÿD/ÿF4ÿG4ÿ@8ÿ;3ÿ24ÿ-0ÿ)2ÿ%.ÿ)-ÿ-/ÿ*-ÿ')ÿ(*ÿ*/ÿ)-ÿ(-ÿ+2ÿ06ÿ3;ÿ4>ÿ3<ÿ0;ÿ/:ÿ-<ÿ+?ÿ+?ÿ*<ÿ+>ÿ-@ÿ+>ÿ-@ÿ0Bÿ/Bÿ/?ÿ 1Aÿ 3Cÿ 1?ÿ 0@ÿ 3Cÿ 7Dÿ6Bÿ1>ÿ.:ÿ,9ÿ+:ÿ*;ÿ);ÿ%8ÿ!4ÿ%9ÿ)?ÿ&=ÿ#8ÿ)Aÿ0Dü ;?ùMOöC|“ŸÀ¤˜v³zðˆµ‚þvoÿˆ·†ÿ¯Øÿ­Æˆÿ€¡hÿTƒRÿA|Pÿ.sJÿ)kEÿ+pOÿ.mOÿ2dNÿ4gPÿ,TEÿ"M?ÿPAÿP@ÿiWÿ.‚tÿe_ÿIBÿI@ÿH<ÿ=2ÿ@3ÿC3ÿH<ÿH<ÿC=ÿ>8ÿ 34ÿ*-ÿ(-ÿ(-ÿ)-ÿ)+ÿ%'ÿ"$ÿ#(ÿ(-ÿ(.ÿ%,ÿ%-ÿ'0ÿ)3ÿ-6ÿ-7ÿ.7ÿ-6ÿ+7ÿ+<ÿ,<ÿ)9ÿ):ÿ*<ÿ,=ÿ.@ÿ2Cÿ1Cÿ 3Eÿ 5Fÿ 4Fÿ 3Cÿ 1Bÿ 0Bÿ0=ÿ1;ÿ/<ÿ.:ÿ-<ÿ .>ÿ -?ÿ -?ÿ-Bÿ(<ÿ%9ÿ&;ÿ'=ÿ(=ÿ,Dÿ/Dÿ.9þ ;Cý2kp¯µÈʣʭqv¾ƒì•ؘþ˜Ðÿ•Àƒÿr¡pÿI€`ÿ9wXÿ*mOÿ(tRÿ*\ÿ+Xÿ3‚Vÿ4zNÿpBÿ8c9ÿ0d;ÿ#c;ÿ_:ÿyPÿ)oÿgZÿ E;ÿ 6.ÿ 83ÿ 31ÿ -,ÿ ,+ÿ 22ÿ 20ÿ 00ÿ 33ÿ00ÿ +,ÿ)*ÿ*,ÿ --ÿ,,ÿ'*ÿ%)ÿ&.ÿ)3ÿ)5ÿ)6ÿ)8ÿ'5ÿ(3ÿ)3ÿ+3ÿ-4ÿ05ÿ.6ÿ+6ÿ,8ÿ+6ÿ*7ÿ.<ÿ1@ÿ2Aÿ1Aÿ3Dÿ3Eÿ 3Eÿ 3Fÿ 3Gÿ 3Gÿ 4Hÿ 5Eÿ 5Bÿ 4Bÿ 0>ÿ)7ÿ(7ÿ *;ÿ -?ÿ 0Eÿ*>ÿ(<ÿ)>ÿ(=ÿ%9ÿ*Aÿ.Fÿ+Fÿ.EþLZâ…¨¯+­Ì·b|Ƌݤë¦þ¸ò«ÿăÿiaÿL}[ÿC|[ÿA‚`ÿL—rÿO¤zÿLœpÿM˜gÿL]ÿL…OÿF|Jÿ@sCÿ;tHÿ0pIÿ!`@ÿV<ÿVCÿI=ÿ ;3ÿ 2+ÿ 2-ÿ31ÿ 11ÿ --ÿ'&ÿ)(ÿ/.ÿ 54ÿ 54ÿ 32ÿ00ÿ --ÿ //ÿ21ÿ03ÿ-2ÿ+3ÿ*5ÿ%3ÿ%2ÿ%4ÿ&4ÿ(4ÿ)4ÿ*2ÿ)0ÿ)-ÿ)0ÿ*5ÿ*5ÿ,7ÿ/<ÿ4Bÿ7Eÿ3Bÿ0@ÿ3Dÿ1Aÿ.Aÿ3Eÿ 6Jÿ 6Jÿ 3Gÿ 6Eÿ 7Bÿ 4Bÿ 3Aÿ .<ÿ)6ÿ'7ÿ*:ÿ(:ÿ(;ÿ+?ÿ+Bÿ-Cÿ)>ÿ&9ÿ&:ÿ-Jÿ3Mÿ 7G÷Mƒb¼ÖÄDŽÖͳò±ÿÆö³ÿ¤Èˆÿs’_ÿc…[ÿl“iÿv¦zÿˆÀÿΜÿƒ¼ÿl£sÿV…[ÿEsGÿ:h?ÿ0\9ÿ*W8ÿ*ZBÿ'[EÿG9ÿ?3ÿ?4ÿ?5ÿ60ÿ1-ÿ31ÿ43ÿ .-ÿ,*ÿ 75ÿ FDÿ FBÿ 96ÿ2/ÿ.-ÿ-+ÿ-,ÿ/.ÿ/1ÿ,1ÿ(0ÿ&1ÿ$0ÿ#0ÿ#1ÿ%3ÿ(3ÿ(3ÿ)2ÿ)0ÿ)/ÿ)0ÿ)4ÿ+7ÿ+8ÿ,8ÿ,9ÿ-<ÿ/>ÿ1@ÿ0Bÿ/Aÿ/Cÿ2Dÿ 3Gÿ 3Hÿ 6Jÿ 7Eÿ 6@ÿ 4@ÿ 6Cÿ 4Cÿ ,:ÿ'5ÿ&6ÿ(;ÿ)<ÿ(;ÿ':ÿ,Aÿ1Fÿ-Aÿ(>ÿ/MÿÿC;ÿA:ÿ>:ÿ73ÿ 43ÿCBÿOMÿ B@ÿ.-ÿ&%ÿ%%ÿ'&ÿ%%ÿ&&ÿ%(ÿ"&ÿ (ÿ!*ÿ -ÿ#/ÿ%3ÿ%3ÿ%2ÿ$/ÿ%-ÿ'.ÿ*1ÿ*3ÿ*5ÿ-9ÿ*7ÿ"-ÿ&ÿ)ÿ"/ÿ(6ÿ,<ÿ-?ÿ/@ÿ->ÿ->ÿ/Bÿ 4Hÿ 8Gÿ 5@ÿ 3>ÿ 5Bÿ 7Eÿ /=ÿ*8ÿ)8ÿ%5ÿ'7ÿ);ÿ(9ÿ'8ÿ)=ÿ1Dÿ2Gÿ/Lÿ6QÿBTÿQ_»z¨­.·ïÀÓÀúµÿµÚ—ÿ«¼}ÿ¦Â€ÿ˜Ò…ÿ’Ì‚ÿœÈ†ÿ³ÜŸÿ¸âªÿŠÿQˆZÿ2h@ÿ"e;ÿ_9ÿgCÿaFÿ`Oÿ*mdÿ*ddÿ#\NÿR<ÿH7ÿB3ÿ@5ÿ=4ÿ=7ÿA=ÿ<:ÿ=;ÿ ::ÿ //ÿ&'ÿ%%ÿ %&ÿ %&ÿ%&ÿ()ÿ(+ÿ%)ÿ#-ÿ%.ÿ%1ÿ&3ÿ)6ÿ(6ÿ'5ÿ)3ÿ)3ÿ+3ÿ+3ÿ-6ÿ/<ÿ0>ÿ/<ÿ(6ÿ#-ÿ ,ÿ!-ÿ%3ÿ)7ÿ)9ÿ*:ÿ,<ÿ-?ÿ-Aÿ1Bÿ 6Dÿ 6Aÿ3>ÿ 3?ÿ 5Cÿ 3Aÿ .=ÿ .<ÿ$2ÿ$2ÿ%4ÿ'7ÿ%5ÿ#3ÿ)9ÿ,Aÿ+Eÿ,Dÿ4Fÿ@Oÿ?‹s¼ÒÖ¯à·êˆ¾zÿ}šcÿŽ˜`ÿ­Äÿ«à’ÿ¡ØŽÿ¦Ø•ÿ«å¡ÿŽÄŠÿešhÿFƒUÿ>€Rÿ.Mÿ)vIÿhCÿgIÿ6‹tÿG¡“ÿ)gdÿN?ÿI1ÿ>+ÿ<+ÿ<.ÿ6,ÿ2+ÿ2-ÿ<:ÿ75ÿ --ÿ)*ÿ ),ÿ ,/ÿ+/ÿ *-ÿ--ÿ/1ÿ03ÿ.3ÿ-5ÿ,5ÿ)4ÿ(3ÿ(3ÿ(4ÿ)5ÿ-9ÿ0;ÿ1:ÿ07ÿ-7ÿ-:ÿ,;ÿ0=ÿ1@ÿ/>ÿ-;ÿ*9ÿ*8ÿ*9ÿ)7ÿ)9ÿ-@ÿ1Dÿ0Cÿ.@ÿ3?ÿ6@ÿ5@ÿ3?ÿ 3@ÿ 5Bÿ 5Cÿ 2?ÿ 0?ÿ'4ÿ".ÿ#1ÿ(6ÿ'6ÿ#1ÿ 0ÿ$9ÿ7QÿB[ÿ:NÿOcÂm¦·=ªÒ±Ûe•XÿtŽXÿ£¨mÿÂÖŽÿ¸ëœÿ±éÿµï¦ÿ±ò­ÿŠÌŽÿcŸkÿJ“_ÿHšcÿ?eÿ;šeÿ1Ž`ÿ/†cÿ=˜€ÿ=•…ÿ \XÿL;ÿJ0ÿD-ÿC/ÿC2ÿ=/ÿ4-ÿ 1+ÿ42ÿ 1/ÿ ,-ÿ -0ÿ-2ÿ-0ÿ-3ÿ16ÿ 69ÿ 79ÿ 49ÿ 39ÿ 3;ÿ 3>ÿ/<ÿ-9ÿ-;ÿ,8ÿ,7ÿ/;ÿ3?ÿ3=ÿ08ÿ,6ÿ)6ÿ+8ÿ-<ÿ.<ÿ+9ÿ*8ÿ-;ÿ,;ÿ(6ÿ+:ÿ->ÿ.@ÿ.@ÿ-@ÿ.@ÿ1<ÿ6@ÿ9Dÿ4?ÿ1=ÿ 9Cÿ 9Gÿ 2?ÿ 1@ÿ 4Cÿ 3Bÿ -;ÿ)9ÿ+9ÿ'4ÿ#1ÿ$6ÿ-Aÿ5Lÿ:Pÿ >Uÿ)hy©³ÆÆ«È«Òw¨oÿ“³tÿ¼È†ÿÖâÿÐí¨ÿÎø±ÿºé¨ÿ—Î’ÿÌ•ÿ‚Æÿc«sÿ_ªrÿa·wÿa¸|ÿZ­wÿU¦|ÿC‹oÿ-kXÿ!VJÿ"Q@ÿ!N5ÿH3ÿE2ÿB2ÿ;.ÿ3,ÿ2,ÿ )(ÿ(&ÿ'(ÿ )*ÿ )+ÿ ')ÿ '*ÿ .2ÿ 6:ÿ 9<ÿ :?ÿ 9@ÿ 9Bÿ 9Cÿ 6Bÿ 8Dÿ 4Cÿ0<ÿ-8ÿ,6ÿ.:ÿ0:ÿ-6ÿ-7ÿ,9ÿ-;ÿ-<ÿ+:ÿ(5ÿ'5ÿ+:ÿ,;ÿ)7ÿ)7ÿ)8ÿ+:ÿ,<ÿ.>ÿ.@ÿ2>ÿ5Aÿ6Bÿ3>ÿ2=ÿ6Cÿ 5Eÿ 4Bÿ 2Aÿ:Iÿÿ.O;ÿ%E3ÿ<-ÿ3)ÿ2)ÿ2-ÿ)%ÿ)'ÿ))ÿ))ÿ-.ÿ+,ÿ)*ÿ,-ÿ/2ÿ 8=ÿ@Fÿ @Fÿ 4=ÿ-6ÿ-6ÿ0;ÿ.9ÿ)3ÿ(2ÿ%/ÿ(2ÿ*3ÿ)2ÿ+5ÿ*9ÿ,:ÿ,;ÿ,;ÿ+:ÿ+:ÿ,;ÿ-=ÿ/>ÿ+;ÿ)8ÿ*9ÿ,:ÿ.>ÿ0@ÿ4Bÿ3Aÿ3Aÿ8Eÿ8Fÿ6Cÿ 3Bÿ 5Dÿ 5Cÿ 7Eÿ8Fÿ 6Dÿ 4Bÿ 0?ÿ)7ÿ)5ÿ.<ÿ*<ÿ)Aÿ)?ÿ.FÿBPÿedÂo³­3¨Ò¡ÿªÜ—ÿÎç£ÿíø¼ÿéë¼ÿ«‚ÿ`zVÿBhEÿ4`?ÿGyRÿŠÈ“ÿ±ò±ÿ±å˜ÿ¸åÿ“±yÿNkDÿ1P3ÿ1[>ÿ,]Eÿ1XBÿ:\Dÿ3ZDÿ#G5ÿ5)ÿ1&ÿ3,ÿ4-ÿ53ÿ 54ÿ 34ÿ 46ÿ ;<ÿ 68ÿ66ÿ8:ÿ25ÿ 48ÿ 6<ÿ38ÿ,2ÿ&-ÿ'/ÿ(2ÿ%/ÿ%/ÿ(1ÿ)3ÿ-8ÿ-8ÿ)3ÿ'3ÿ'4ÿ)8ÿ,;ÿ-=ÿ-<ÿ-<ÿ-<ÿ.=ÿ0@ÿ2Aÿ2Aÿ-<ÿ*8ÿ*9ÿ.<ÿ2Aÿ3Cÿ6Eÿ:Iÿ 9Iÿ7Fÿ3Cÿ3Cÿ 3Cÿ 5Eÿ 8Gÿ :Hÿ:Hÿ 4Bÿ -:ÿ-:ÿ3@ÿ+;ÿ-Eÿ6Qÿ=Wÿ@MÿHLÿh`£«ÆÄ «ÔªÁ¡Þ—ÿÈíªÿØí³ÿªµŠÿk€_ÿZ€\ÿVdÿE…[ÿ>yOÿMƒUÿÊÿÖø¯ÿ¸Ø“ÿl}Jÿ2F%ÿ-M-ÿ,W6ÿL0ÿD.ÿ(I6ÿ&P=ÿF3ÿ7*ÿ6+ÿ<5ÿ?8ÿ=:ÿ>=ÿ<>ÿ;>ÿADÿADÿ ADÿ DEÿ37ÿ13ÿ04ÿ/4ÿ/5ÿ-3ÿ-3ÿ-4ÿ-6ÿ/9ÿ1;ÿ.8ÿ1:ÿ2=ÿ/9ÿ-9ÿ-=ÿ-=ÿ.>ÿ.>ÿ.>ÿ/?ÿ0@ÿ1Aÿ0?ÿ2Aÿ3Bÿ3Bÿ0?ÿ-;ÿ-9ÿ.>ÿ2Cÿ4Fÿ3Dÿ0@ÿ3Bÿ5Fÿ5Eÿ 7Gÿ 7Gÿ 7Eÿ 7Fÿ 7Eÿ 5Cÿ 3@ÿ 2?ÿ3=ÿ0?ÿ +Aÿ-Bÿ=RÿL\ÿJQÿ PPéB|vÄÖÖ ·Ø¸t£ç£ÛÀö¯ÿ¸å¦ÿ€¨tÿ_ˆ[ÿc˜kÿd¦rÿd¯wÿd«tÿX“\ÿm¤iÿ¤Ì†ÿ€¦gÿB\0ÿ4T-ÿ=oEÿ5oGÿ'cBÿN6ÿ?.ÿ;+ÿ 4&ÿ 3(ÿ :-ÿ <5ÿ :3ÿ76ÿEEÿFJÿGÿÿ7Bÿ9Eÿ7Eÿ4Fÿ3Eÿ1Bÿ.>ÿ-=ÿ.>ÿ1Aÿ2Bÿ1?ÿ0>ÿ2@ÿ5Dÿ8Gÿ5Dÿ0>ÿ):ÿ+?ÿ2Eÿ1Cÿ.@ÿ1Cÿ4Fÿ3Eÿ1Aÿ3Bÿ 6Eÿ 9Hÿ ;Hÿ :Hÿ 8Eÿ 6Cÿ5Cÿ 5Eÿ 0Bÿ):ÿ6HÿGZÿM]ÿEPÿP[éQ’˜w«ïµÁ¸ø·ÿ£âŸÿy¼|ÿhªmÿi¯sÿyăÿzƈÿy‚ÿ†Ì…ÿƒÄzÿr£`ÿU‚Gÿ@k8ÿNƒNÿJ[ÿC‹]ÿ6‚\ÿV>ÿ>-ÿ 5&ÿ2$ÿ5*ÿ9.ÿ 5/ÿ 50ÿ 00ÿABÿAEÿ/3ÿ (,ÿ%*ÿ!%ÿ ÿ+/ÿ-2ÿ-2ÿ-2ÿ-3ÿ-2ÿ*0ÿ,3ÿ5=ÿ>Fÿ AJÿ BLÿ@Iÿ>LÿANÿ>Mÿ:Nÿ9Mÿ8Jÿ5Gÿ3Eÿ3Cÿ3Dÿ0@ÿ+9ÿ,:ÿ-;ÿ.=ÿ0<ÿ2>ÿ1?ÿ&8ÿ&:ÿ-Bÿ.Eÿ.Bÿ0Dÿ3Dÿ0Bÿ-<ÿ0?ÿ4Cÿ 8Hÿ :Gÿ 7Dÿ 5Aÿ 4@ÿ /=ÿ*8ÿ -;ÿ-;ÿ.>ÿ4FÿE_ÿQlÿG`ÿ M[ËZ’•^­ë¼±ú¼í¤é¦ÿ…Ìÿ‹Ì‚ÿšÖÿ¡Ô‹ÿ¨Òÿ¯Ø’ÿÄéŸÿ±ÚŽÿ€ªeÿaˆNÿ`“Wÿr¯rÿa¤rÿXšpÿÿ ;Aÿ >Cÿ =Bÿ9>ÿ6<ÿ5;ÿ3:ÿ3:ÿ7>ÿ:CÿCNÿBOÿ>Jÿ>Iÿ7Fÿ3Fÿ5Hÿ7Iÿ5Gÿ3Eÿ2Cÿ1@ÿ.=ÿ+9ÿ-:ÿ,8ÿ)5ÿ)4ÿ-8ÿ1?ÿ+?ÿ&=ÿ)?ÿ*@ÿ,@ÿ-Bÿ/Bÿ1Dÿ1Aÿ3Cÿ3Bÿ2Aÿ1<ÿ0<ÿ0;ÿ1<ÿ-<ÿ *9ÿ/;ÿ,8ÿ(6ÿ)<ÿ6RÿMpÿX€ÿ]yÿ `p½X¨?³åÂe¦öºß³øµÿå‹ÿŸÚ…ÿ¸â•ÿÈà—ÿàç¡ÿëí¨ÿíò¨ÿÊØÿˆªgÿ¦eÿy±pÿv±vÿoª}ÿ]oÿ2VCÿ;.ÿ ?5ÿD9ÿD9ÿE<ÿJAÿFBÿ >:ÿ==ÿ<<ÿ 37ÿ 14ÿ9:ÿ >?ÿBBÿGFÿ ?Dÿ BHÿ FLÿ DIÿ @Eÿ @Fÿ DJÿ FMÿAIÿ8@ÿ3<ÿ;Dÿ:Dÿ3?ÿ3=ÿ-:ÿ,<ÿ-=ÿ->ÿ-=ÿ,;ÿ+:ÿ,;ÿ-;ÿ-<ÿ+9ÿ)5ÿ)4ÿ+7ÿ-8ÿ.;ÿ,Bÿ)Cÿ)@ÿ,Dÿ/Eÿ.Cÿ-Aÿ0Cÿ0Bÿ3Cÿ4Cÿ3Dÿ3@ÿ2=ÿ1<ÿ2?ÿ/@ÿ/>ÿ 8Aÿ4?ÿ-:ÿ&9ÿ'Dÿ2TÿIyÿwŸÿ€ÿ py£¡Ä¾,ÄâЭôÈËÀúÐÿµâ¯ÿ£Ôœÿ¨à¦ÿÀë­ÿÚí³ÿØç¯ÿÖåªÿ’³}ÿDyJÿH€PÿeJÿ=kQÿ%Q=ÿL:ÿ P=ÿM;ÿG7ÿNBÿQHÿ>=ÿ68ÿ4:ÿ.4ÿ .3ÿ39ÿ ;;ÿ ?@ÿGCÿLEÿJRÿ O[ÿ P\ÿ JVÿ HTÿ ITÿ DNÿ BMÿ >Jÿ 4?ÿ1;ÿ 5Aÿ 6Cÿ 1<ÿ /<ÿ0<ÿ2=ÿ1=ÿ0<ÿ0>ÿ/=ÿ-:ÿ-<ÿ->ÿ*;ÿ*9ÿ*9ÿ,<ÿ-?ÿ-=ÿ):ÿ(@ÿ)Cÿ*Cÿ-Hÿ2Mÿ1Lÿ/Gÿ/Dÿ.Aÿ0Dÿ0Bÿ3Gÿ:Mÿ5Gÿ3Eÿ8Hÿ 4?ÿ 2;ÿ6>ÿ;Cÿ 8Cÿ0>ÿ*=ÿ.Bÿ7OÿJ`ÿ h|ÿyˆúls¡ºÀ5±éÎŸÂøÜñÄàÈÿªÔ±ÿªëÀÿÀòÆÿÔïÀÿÖíÀÿ¾Ð¦ÿQsOÿQ1ÿ'_<ÿ*cDÿ-[Aÿ.P<ÿ(R>ÿL8ÿJ7ÿG3ÿJ8ÿR@ÿMBÿ>8ÿ *,ÿ-1ÿ+3ÿ%-ÿ+3ÿ3:ÿ45ÿ55ÿB<ÿNGÿU`ÿRaÿGTÿ;Gÿ7Bÿ8Cÿ5Aÿ1=ÿ-8ÿ -9ÿ 1<ÿ 3?ÿ5Aÿ7Cÿ9Fÿ ;Fÿ ?Fÿ ?Gÿ Aÿ ?Bÿ;=ÿ:=ÿ@BÿRVÿ FJÿ68ÿ23ÿ24ÿ35ÿ24ÿ02ÿ13ÿ79ÿ79ÿ36ÿ46ÿ;=ÿAAÿ EFÿ OPÿ QQÿ HJÿ CGÿ CGÿAGÿ>Fÿ ?Hÿ=Hÿ9Fÿ4Aÿ3@ÿ4Dÿ6Fÿ3Dÿ3Dÿ3Eÿ1Cÿ.Aÿ-@ÿ0Bÿ3Dÿ7Jÿ7Lÿ8Mÿ7Lÿ/Bÿ+?ÿ1Eÿ 3Hÿ 3Eÿ 7Bÿ 8Bÿ 8Cÿ 8Cÿ 9Cÿ 9Fÿ ÿ GBÿ E@ÿ EAÿE?ÿB<ÿ@:ÿ@:ÿ=7ÿB=ÿQMÿ ROÿGDÿ?>ÿ>>ÿ;>ÿ7;ÿ6:ÿ8>ÿ6>ÿ4=ÿ5>ÿ6Bÿ5Aÿ3?ÿ5Bÿ9Gÿ:Hÿ6Eÿ1?ÿ/<ÿ/=ÿ2@ÿ4Eÿ3Cÿ5Hÿ/Bÿ'9ÿ /Cÿ 4Jÿ 1Dÿ 1>ÿ 3?ÿ 3@ÿ 3>ÿ 0=ÿ2?ÿ 4Cÿ ;Iÿ7Eÿ1>ÿ6Dÿ HZÿ Zlÿ VhÿJ[ó#ip—ºÒÒ#ºôÖ—Êà¯ô·‚ÿv—dÿ]…Pÿlœ`ÿ|­mÿ[†LÿZGÿv˜]ÿ‹³vÿ’ˆÿhœlÿ,`@ÿN3ÿW>ÿMBÿ?BÿAAÿ9:ÿ43ÿ=9ÿA;ÿF>ÿJBÿVLÿ RNÿ NHÿUZÿU\ÿFRÿ >Hÿ 76ÿ<8ÿC?ÿE@ÿFAÿHDÿMHÿUOÿWQÿ TNÿ RMÿ TMÿPJÿJDÿD>ÿ>8ÿ@:ÿB=ÿ;7ÿ53ÿ64ÿ65ÿ34ÿ13ÿ37ÿ38ÿ28ÿ3:ÿ3<ÿ09ÿ-4ÿ/:ÿ3>ÿ5Cÿ5Bÿ2?ÿ-:ÿ-;ÿ.=ÿ1@ÿ,<ÿ1Cÿ2Dÿ):ÿ-Aÿ 4Iÿ 1Eÿ 2Aÿ 3Bÿ 3Bÿ 1Aÿ .=ÿ.=ÿ1@ÿ2?ÿ 8Hÿ0>ÿ)5ÿ5CÿHZÿ Ugÿ \mÿMTóilœ³ÒÔ=µéÊZÈà¦ç¼Ô“ÿÂå˜ÿœÊÿeWÿ[LÿZ‹Iÿw¡[ÿ­kÿ­Äÿ³Ö•ÿZŠZÿQ2ÿ$`?ÿ aEÿPGÿQ\ÿ QWÿ;?ÿ:9ÿHEÿE<ÿI>ÿWHÿ`Oÿ aVÿ cXÿ\aÿPUÿERÿDQÿ;9ÿA9ÿHAÿNGÿVOÿ]Vÿ[TÿZTÿ`Zÿg_ÿd_ÿ ]Zÿ \Vÿ [WÿWRÿF@ÿ<4ÿ?7ÿ;4ÿ93ÿ ;7ÿ <7ÿ 97ÿ 87ÿ 77ÿ 57ÿ 37ÿ 27ÿ 39ÿ 27ÿ-3ÿ+3ÿ,5ÿ.9ÿ/9ÿ-8ÿ-8ÿ-9ÿ .<ÿ 0?ÿ*9ÿ/@ÿ 4Fÿ-?ÿ*:ÿ.@ÿ0Cÿ 3Dÿ3Dÿ 3Eÿ 3Eÿ 3Dÿ 3Dÿ 4Eÿ.>ÿ5Eÿ3@ÿ,:ÿ+7ÿ)4ÿ@Pÿ UgÿFTÿFQó%w´¼ÒÔ9ÄÒÆ‹µÔÆ…ÿ¾Ú“ÿÆïŸÿ£Úˆÿµhÿh—Pÿˆ¯dÿµ¾vÿÄØÿĈÿ?lDÿW7ÿ*hHÿ)iNÿ%`TÿRRÿFEÿ43ÿ52ÿC?ÿ >7ÿ ;3ÿ<3ÿ WLÿvmÿk`ÿ ECÿ64ÿ 5:ÿ:>ÿ 96ÿ?;ÿIDÿROÿ[Xÿcaÿikÿegÿdhÿlpÿotÿhmÿchÿ[aÿ MTÿIJÿQIÿPHÿIBÿD>ÿB=ÿ>:ÿ ;9ÿ>=ÿ?@ÿ;=ÿ 6:ÿ 5:ÿ :=ÿ;?ÿ 7>ÿ 3:ÿ19ÿ/9ÿ-6ÿ,5ÿ+5ÿ,8ÿ-;ÿ.=ÿ/?ÿ0Aÿ3Dÿ1Dÿ->ÿ+=ÿ-@ÿ 0Aÿ 0Aÿ /@ÿ 1Bÿ 3Fÿ 8Iÿ :Lÿ ;Mÿ Mÿÿ3AÿBPÿTcÿ U`ÿ/ryÛ¸ÎÐJz£|z¨pìÂÚ˜ÿØôªÿÆòÿ¡Ð}ÿrTÿ“·iÿÎÌ‚ÿÌÜ“ÿ‹¸}ÿ0[8ÿ"cBÿ/oPÿ-cMÿRCÿ<2ÿ5.ÿ?6ÿA:ÿD>ÿ FAÿ GAÿ>8ÿ=6ÿ NFÿ QHÿ 93ÿ3,ÿ71ÿ>8ÿ >;ÿ ;8ÿ =;ÿ @?ÿ BCÿ IJÿ]dÿ s|ÿ r}ÿ`mÿXgÿVdÿO\ÿANÿ6DÿCHÿ[Tÿ[RÿUNÿOIÿIEÿFBÿECÿIGÿEEÿBCÿ>?ÿ=>ÿ>@ÿ=?ÿ9=ÿ 9?ÿ 7?ÿ 3;ÿ 3:ÿ 1:ÿ-7ÿ-9ÿ,8ÿ+9ÿ2Bÿ/@ÿ.?ÿ4Hÿ3Fÿ/Bÿ0Cÿ 2Cÿ 1Cÿ0Aÿ0@ÿ.?ÿ1Bÿ 4Gÿ 9Jÿ =Nÿ =Nÿ =Nÿ >Nÿ;Lÿ3Cÿ.<ÿ2@ÿEUÿQ`ÿ P\ÿ8tyË·ÌÎ=ÀÖÊS}À’×µÔÿÔç«ÿåø·ÿÊâœÿ«dÿ¨ÂyÿÐÖÿÒï¨ÿm¦rÿ&U4ÿ-yWÿ4oWÿ&L>ÿC0ÿG-ÿJ5ÿ cLÿdUÿ\Qÿa_ÿcaÿiiÿ >?ÿ ;6ÿ A<ÿD6ÿH:ÿH3ÿP<ÿQDÿODÿTJÿMEÿ @;ÿ ;8ÿ @@ÿUVÿTVÿBFÿ;@ÿ 15ÿ%)ÿ #'ÿ '+ÿ ++ÿ=5ÿPGÿXPÿVNÿVNÿXPÿUPÿRLÿQLÿMIÿIFÿJHÿ GEÿ @=ÿ B@ÿ DFÿ=@ÿ9>ÿ?Cÿ7@ÿ2:ÿ3>ÿ 7Cÿ0?ÿ+:ÿ*=ÿ.@ÿ0Dÿ2Gÿ/Gÿ/Cÿ3Cÿ0>ÿ4Cÿ6Eÿ4Cÿ/>ÿ.=ÿ2?ÿ6Fÿ ;Lÿ >Qÿ @Qÿ >Mÿ ÿ2=ÿ>Gÿ \gÿhrÿ&gmȪÄÊ:—έ”«Ð£ìØëºÿööÀÿâëªÿÀÔ‹ÿÄÔÿÒÜœÿªÐÿBwNÿG-ÿ*rRÿ2gRÿ(G=ÿ!M3ÿ'd8ÿ!dAÿhHÿr[ÿk\ÿcaÿrvÿ owÿMTÿFDÿEAÿL8ÿR>ÿV6ÿ[9ÿ_HÿeQÿlZÿl[ÿl`ÿeZÿLEÿ 74ÿ 75ÿB@ÿGFÿ54ÿ )'ÿ21ÿ:7ÿ1-ÿ /)ÿ 2*ÿ 6.ÿ =5ÿJBÿVNÿd[ÿh_ÿe\ÿc[ÿ\Uÿ[Uÿ VPÿ PIÿ TMÿ NMÿIIÿFGÿEFÿBGÿ@Hÿ =Fÿ ;Eÿ 9Iÿ0?ÿ 3Fÿ 3Gÿ,@ÿ,Aÿ 0Gÿ0Eÿ0>ÿ0:ÿ3@ÿ3?ÿ3Aÿ3@ÿ2?ÿ4Cÿ6Eÿ7Gÿ7Hÿ6Fÿ5Fÿ5Fÿ 6Iÿ :Iÿ 7Aÿ3<ÿ>Fÿ VcÿWeÿ"]l²­ÆÎ2¡ØºÝÈïÄÿíï¾ÿíòºÿÚâ¡ÿœ¨mÿy“\ÿPvGÿ"Q/ÿ>%ÿT=ÿ)WGÿ+JBÿ+`Bÿ)p=ÿc=ÿhDÿy_ÿtcÿ`\ÿW[ÿLTÿPWÿDCÿ@>ÿN9ÿW@ÿgAÿhAÿoJÿ'}Xÿ#sTÿ(z[ÿ.‚eÿ*y\ÿ%iTÿ>/ÿ%ÿ7(ÿL9ÿO:ÿU<ÿ(dGÿ)dFÿ!XBÿQEÿH=ÿB8ÿ:0ÿ 1)ÿ 2)ÿC8ÿZNÿhZÿ pcÿseÿyiÿ$ˆzÿ%‹zÿsgÿkcÿrlÿgdÿ ]Xÿ caÿ ]]ÿOQÿMQÿGOÿFMÿ?Iÿ7Bÿ6Cÿ6Aÿ3Aÿ3>ÿ0:ÿ4=ÿ4>ÿ/8ÿ0:ÿ1<ÿ3@ÿ6Dÿ6Dÿ6Fÿ5Eÿ3Bÿ.?ÿ0Aÿ 3Eÿ 7Dÿ ;ÿ1.ÿ0/ÿ<;ÿ;<ÿJLÿHMÿDIÿHQÿELÿ=Eÿÿ2?ÿ4Dÿ 7Hÿ 9Jÿ 8Jÿ 3Hÿ1Cÿ3?ÿ ;Bÿ =Gÿ 4Cÿ%7ÿ/Eÿ _…ÿ Z€ÿIgÖM…šhÜåçšëÐàÒöÎÿëøÒÿÌÐ’ÿt‚Qÿmš[ÿy±rÿ]ªmÿG†Zÿ8sUÿ.cLÿ-dRÿ'mQÿ"sPÿ'}]ÿmQÿ\HÿaOÿ[PÿmdÿHDÿMHÿkdÿ]Wÿ]PÿcUÿcPÿzcÿoRÿiMÿ`Gÿ\Fÿ#dOÿ%dOÿ7|eÿ$RAÿÿ %ÿD-ÿ"\<ÿ)oEÿ-|Lÿ3ŠQÿ:‹\ÿC‹kÿG“rÿF’rÿC“rÿB“rÿ6‚cÿ V@ÿ6%ÿ#ÿÿ"ÿÿ ÿ ÿ "ÿ$50ÿ'-.ÿÿ ÿ ÿÿÿÿÿ##ÿ#$ÿ&'ÿ 79ÿADÿCEÿGJÿHLÿCIÿAEÿ:@ÿQÿ ;Pÿ1Cÿ3Aÿ:Fÿ >Nÿ 4Iÿ"4ÿ#9ÿ.ÿ <.ÿ @3ÿJ?ÿJ?ÿ$VJÿI>ÿÿÿ4#ÿ V9ÿ,rHÿ.zLÿ2ˆQÿ9Ž\ÿ>‹dÿD“lÿD˜oÿC˜pÿB˜pÿ>“lÿ3…`ÿ+yVÿ$mMÿ_AÿW;ÿP7ÿG3ÿ<)ÿ-ÿÿ ÿÿÿÿ"1-ÿ40ÿ# ÿ,)ÿ41ÿ1.ÿ $"ÿÿÿ &%ÿ12ÿ7;ÿ ,/ÿ"%ÿÿ#)ÿ 18ÿ 19ÿ2<ÿ 7Bÿ 7Dÿ 8Fÿ 8Hÿ 6Iÿ5Hÿ4Gÿ9Jÿ5Fÿ 7Lÿ?Zÿ /Fÿ)>ÿ2Fÿ9NÿMeÿXpÿBXø I]ÀNˆœZÆÔÌVkÔPzWÿs}Oÿˆ¡cÿŽÆwÿs¨cÿ‚À}ÿ}¼€ÿDwRÿ+iHÿ`Dÿ`QÿRTÿXTÿ)vmÿ2|lÿ=†rÿ*pWÿV?ÿXAÿ N8ÿVHÿXJÿWZÿ `eÿUdÿRaÿ PQÿDCÿ=?ÿ ;?ÿ 28ÿ '-ÿ %-ÿ '-ÿÿ ÿ ÿ6-ÿD4ÿJ7ÿ)cEÿ.€Wÿ)Xÿ*“]ÿ-šaÿ,˜`ÿ)’[ÿ(Zÿ*•]ÿ)Ž[ÿ%ƒQÿ&€Pÿ&}Oÿ)}Oÿ'tJÿe?ÿ_<ÿ'O;ÿ(ÿÿ ÿ9)ÿ&cLÿUBÿZDÿ`Lÿ[HÿZHÿO?ÿ8,ÿ * ÿ%ÿÿ ÿ ÿÿÿÿÿÿ (ÿ)1ÿ1=ÿ 6Dÿ6Fÿ3Dÿ3Eÿ6Jÿ3Lÿ)Eÿ1Lÿ Tÿ ;Mÿ-:ÿ*4ÿ9EÿIVÿRdÿI\ûC]Õ k‹Š¨ÆÖ!œÒ³…Âãs‚Pÿ€aÿ•Òÿs¨cÿ•΋ÿ€³€ÿ1[;ÿ/sMÿ,Žhÿ/—ˆÿ&‹•ÿ+‚‚ÿ1|ÿ5}pÿ2o\ÿC/ÿE.ÿeGÿwWÿ‹vÿˆÿƒ‹ÿ yƒÿ s‹ÿ `zÿ alÿlrÿckÿ\hÿP`ÿGVÿ9Fÿ(2ÿ ÿ ÿ ÿÿÿ2#ÿF1ÿ];ÿr?ÿzEÿ…Mÿ&—Zÿ-¨eÿ/ªiÿ-¤dÿ+š]ÿ-š_ÿ/˜`ÿ)†Tÿ,†Uÿ3‹Zÿ-Pÿ-wNÿ@z\ÿ-TAÿ ÿÿ -ÿ"dLÿX@ÿ#tZÿ tXÿ]Gÿ_IÿdOÿUDÿM<ÿE8ÿ;1ÿÿÿ ÿ ÿ #ÿ%ÿ$,ÿ#,ÿ(ÿ)ÿ"-ÿ*9ÿ5Gÿ;Oÿ8Mÿ3Nÿ'Fÿ3ÿ!5ÿ ?TÿM_ÿ6Cÿ-7ÿ4?ÿ>GÿMZÿNaÿ1Jÿ-OûVбz¦ÎH«ÜÂÁÒÎÿ­¨gÿÀâ}ÿ—Äoÿ€Æ}ÿRˆVÿDwRÿFˆWÿFœdÿ7¤‚ÿ†}ÿ:³šÿJÈ£ÿ"\@ÿ$Q4ÿ;dHÿJlPÿ5yeÿ6€mÿ’€ÿœÿ•ˆÿŠ}ÿ}tÿwoÿvtÿlkÿmkÿihÿ`aÿ#klÿ+twÿ ]aÿ +-ÿÿ "ÿ ./ÿ --ÿ ÿÿ! ÿ)%ÿ 82ÿJBÿZPÿ&vhÿ3’ÿ7šƒÿ2tÿ3—sÿ3•mÿ5šiÿ@ªrÿ?¤iÿ6—Zÿ3ŽTÿH•oÿe¸šÿÿÿ6 ÿ_AÿvMÿvNÿvNÿtMÿsQÿpQÿaOÿXGÿPFÿTHÿ @3ÿ ÿ ÿ%#ÿ.'ÿ 2+ÿ10ÿ //ÿ22ÿ14ÿ 07ÿ /8ÿ-8ÿ.:ÿ 3Bÿ 5Hÿ 3Jÿ#5ÿ-ÿ 3HÿIaÿMeÿCXÿ3Dÿ2Aÿ;LÿMcÿ Rlÿ.Bÿ#7ÿ Ig×-˜dªÌԵκ{ôé¦ñÊÀwÿ¡¼aÿšÄmÿz¾yÿX\ÿX•hÿ[£mÿF˜`ÿ,‹lÿ†}ÿ<ºœÿB¼—ÿ$`Aÿ5iGÿ`‹kÿ_|]ÿV£‹ÿO¡ŽÿšŽÿ˜Šÿ˜Šÿ•…ÿ$‚ÿ*Ž‚ÿ#|vÿeaÿ#wtÿmkÿ ikÿ-€€ÿNNÿ#$ÿ')ÿFHÿUWÿMPÿOTÿ\cÿTWÿDFÿ97ÿ /-ÿ&%ÿ'%ÿ0+ÿB;ÿ"saÿ)€iÿ3•sÿ-‹hÿ.‹_ÿ4—aÿ8š`ÿ@¦dÿG¯kÿW­…ÿÞÀÿ#ÿÿ@(ÿ/€Zÿ yNÿ |QÿƒVÿƒWÿ€[ÿ}[ÿ"waÿo\ÿ\Rÿ\OÿTAÿÿ ÿ%!ÿ 6+ÿ 6/ÿ53ÿ74ÿ 96ÿ 36ÿ 16ÿ 3;ÿ 5@ÿ 6Dÿ 7Eÿ 8Jÿ5Lÿ6Lÿ 1ÿÿ(:ÿ AWÿCZÿ QiÿVlÿ@Tÿ;MÿNeÿ Wpÿ6Mÿ.ÿ*;ÛBT›s¦µ.ºÚ¡ÕÈà¡ÿ«ÀrÿÀçŽÿŠÆvÿV’VÿG•]ÿ\µtÿR«sÿ3•sÿ"“ƒÿ1˜|ÿ5“rÿ8wTÿHVÿVdÿ\ŽgÿG¡|ÿ=˜wÿ •vÿœ}ÿ"£‚ÿ!Ÿÿ(’rÿ(ˆkÿ)tÿ+‚|ÿ"mgÿ-€zÿ9’ÿWRÿ)%ÿ 41ÿTQÿ _\ÿ$eaÿ#eaÿ a]ÿ\Xÿ[VÿXWÿ[\ÿZ[ÿMNÿ<;ÿ 54ÿ .,ÿ# ÿ 4-ÿB6ÿ[Lÿ*}dÿ7—vÿ5•oÿ4•kÿ5“iÿDpÿvƪÿ0hPÿ ÿ %ÿ2zVÿ!rJÿ.Ž_ÿ$“`ÿ$•aÿ‹\ÿ}UÿwVÿyWÿmRÿhPÿiRÿ -"ÿÿÿ ;.ÿ 7.ÿ81ÿ?7ÿ =6ÿ65ÿ 36ÿ 6;ÿ9?ÿ9Bÿ8Cÿ2>ÿ1?ÿ2@ÿ0@ÿ*ÿ ÿ%ÿ 3Iÿ8Oÿ ?UÿVrÿWpÿ?Rÿ,=ÿ0Aÿ Rkÿ E[ÿ&6ü!/³,m‚_ÐâçµÊ¦jÜú¸ãÄÚ†ÿw“RÿNyAÿ[˜[ÿW­mÿ_¸vÿ_¼€ÿCµÿ,«•ÿ*Šoÿ)z\ÿ@ƒ_ÿJVÿGzUÿZaÿ;‹kÿ4‹iÿ!—wÿ%ª†ÿ)±ÿ%¤€ÿ)’pÿ%ƒdÿ)sÿ(zsÿ7’‹ÿ2ˆƒÿ 2-ÿÿ?:ÿ%idÿ)liÿ ][ÿ[Wÿ#d`ÿ)pmÿ+trÿ,ytÿ'olÿ _aÿWZÿTUÿ]_ÿQQÿ 33ÿ#!ÿ($ÿ#ÿÿ!ÿ 7'ÿW>ÿ"sQÿ)}Zÿ@…kÿ\¡ˆÿvÔ­ÿÿ ÿ$_Aÿ/‹]ÿ)ƒVÿ)iÿ+¦pÿ&¦sÿ!œkÿˆcÿ‚]ÿ‚dÿ!‚gÿ)†iÿH9ÿÿ ÿ>2ÿ=1ÿ<3ÿB<ÿ D>ÿ A?ÿ >@ÿ 9=ÿ39ÿ2:ÿ3=ÿ;Gÿ:Hÿ6Eÿ,;ÿ):ÿ#3ÿ ÿ ÿ'9ÿ 6Lÿ,>ÿ6Jÿ JaÿMcÿ.?ÿ1BÿQkÿoŠÿ\vÿ,=Ï 8J’ºÆ;Šà­¹Èå«ÿ€¡hÿ[@ÿ`œTÿaÈrÿrÔ†ÿ_¸€ÿD³ƒÿ7¾“ÿ?¡yÿ8|XÿH‚ZÿXˆ[ÿFˆZÿ?ƒUÿ1aÿ-“eÿ)˜mÿ-Ÿtÿ2œrÿ-“kÿ/Žeÿ/Šcÿ3…sÿVºªÿ:Š}ÿ#ÿÿRGÿ,reÿ.wkÿ6†wÿ;Ž}ÿ9Ž}ÿ4ˆvÿ.€oÿ+ziÿ(veÿ%phÿ%stÿ)swÿ+tzÿTZÿ ÿÿ9>ÿMQÿVWÿOOÿ :8ÿ'$ÿÿ*$ÿ ?5ÿRHÿ+[Pÿg³Ÿÿ6+ÿÿ #ÿ6gÿ;•kÿ.Ÿmÿ-¡oÿ(³zÿ+¼‚ÿ!­yÿ˜eÿ“eÿ“iÿ5¡}ÿ+iRÿÿ ÿ=-ÿI8ÿI:ÿOAÿOBÿLDÿ GCÿ B@ÿ==ÿ9=ÿ8=ÿAGÿ;Dÿ3=ÿ 3@ÿ .;ÿ4Fÿ;Oÿ -ÿ ÿ)ÿ@Wÿ 8Mÿ1Cÿ Ogÿ@Uÿ%3ÿ 0ÿ0Bÿ Odÿg}ÿ?Nù)4¸=|ŠbÚååŸÎ­{Ðø¼ê·Üÿ€ª_ÿh£Zÿ]¼iÿyÞÿmÐ’ÿJ¼Šÿ-«€ÿ9—mÿFŽeÿX—iÿ]‹_ÿE†Xÿ>…Vÿ)ƒWÿ&†Zÿ&eÿ'’iÿ,gÿ,‹eÿ3’hÿ=¡wÿWº£ÿ,g]ÿÿ .&ÿ-seÿ4€rÿ>Ž}ÿ=Žÿ5‚sÿ4‚sÿ9}ÿ<•‚ÿ3Švÿ*yiÿ,}kÿ/ƒwÿ%prÿ(svÿ(psÿ=@ÿ 03ÿBGÿTZÿPTÿQRÿRRÿTQÿWRÿLFÿ93ÿ& ÿÿÿ;1ÿ#RGÿ ÿ ÿ `Bÿ;“mÿ7±|ÿ3«wÿ'­wÿ)³zÿ!­zÿŸpÿ˜iÿ’hÿ7¨‚ÿ;…lÿ  ÿ ÿ 1$ÿO<ÿR@ÿVEÿUEÿ LAÿ FAÿ FCÿ JIÿHJÿ?Cÿ39ÿ3<ÿ:Dÿ+6ÿ +8ÿ5Eÿ3Eÿ;Oÿ4Gÿÿÿ3Dÿ @UÿŠtÿE—ÿFƒÿCœ€ÿCœ‚ÿ=—zÿ5‹rÿ3‹rÿ3Žsÿ/ˆkÿ/Štÿ.ˆ€ÿ3…ÿPLÿ --ÿCCÿNOÿ UXÿ#Z]ÿ*hmÿ'hmÿ!eiÿgkÿegÿ`cÿWXÿIIÿ??ÿÿ##ÿ ÿÿ (ÿ%_Mÿ)†iÿ9ª†ÿ7Æ•ÿ/·ˆÿ#­ÿ%³‚ÿ!³…ÿ £wÿ5­ˆÿ@¤ƒÿÿÿ%ÿT<ÿaEÿcHÿaIÿXGÿRFÿ QFÿ TLÿ OLÿFEÿ BEÿ@Gÿ8?ÿÿÿ /9ÿ .9ÿ-7ÿ >Jÿ AOÿ(ÿ ÿ$3ÿB[ÿ 6Mÿ:Qÿ@Xÿ 5Iÿ6Hÿ4Eÿ$0ÿ6Eÿ Xkÿ L_êPcˆ±¼8‹Â­©}Ê•ÿ}£`ÿ†·lÿ€¸iÿŸçÿšøºÿeØŽÿ9±kÿR«lÿh¦lÿU†Wÿc‹\ÿT¦oÿ8ˆXÿ+aÿ)’dÿ/…dÿ-€aÿ=€iÿFŽvÿZ­•ÿ>iÿ ÿ9-ÿ2s`ÿ8zgÿ?ˆsÿ@tÿA’yÿC—ÿA—}ÿ?—}ÿ<—zÿ<•|ÿ6Žtÿ2‹pÿ1Šoÿ,‚lÿ9šŽÿ#ogÿ +'ÿD@ÿ%c`ÿ VUÿ$[\ÿ%_aÿ$]aÿ%eiÿ#kmÿ#rrÿprÿorÿghÿVXÿ]`ÿVVÿLLÿ<8ÿ !ÿ ÿ ÿ/"ÿ]Gÿ*£}ÿ4¼“ÿ*ºŽÿ,¾’ÿ'ºÿ#£}ÿ6³ŽÿL¾šÿ-"ÿ ÿ &ÿX@ÿlLÿoQÿtXÿoZÿgVÿ]Qÿ XNÿ RNÿ LJÿJMÿELÿ ,0ÿ ÿÿ#*ÿ -7ÿ 1<ÿ3>ÿ6Dÿ @Oÿ3Cÿÿÿ -@ÿ@Zÿ :Pÿ >Tÿ ?Rÿ;Mÿ?Oÿ4Dÿ-:ÿ7Fÿ ;Lÿ @QÒOŽrÆÚÜÀØÖSD—wáv¤lÿœÄ‚ÿ¸È}ÿ¸ç£ÿ­úÀÿlÊ|ÿ@«Tÿ]­`ÿw¯hÿlŸeÿi`ÿ_³€ÿ;`ÿ,…`ÿ)ˆdÿ1vaÿ5zgÿ`—ÿh¤ÿo¯­ÿ ÿ ÿ?y_ÿC…iÿ?‚gÿ?…iÿCŽrÿB’vÿ?sÿ>•wÿ:Žsÿ6pÿ=œ|ÿ3pÿ4Žrÿ7•yÿ0Šmÿ:šƒÿVHÿ 4*ÿRFÿXLÿ"\Rÿ%_Wÿ'c]ÿ%d`ÿ%ieÿ$olÿ pkÿpmÿpoÿrrÿhoÿivÿ`kÿJTÿ"\dÿ1v|ÿ ..ÿÿÿÿ( ÿ`Rÿ+£‹ÿ=Æ«ÿ8À¦ÿ-¦Žÿ1³“ÿAȤÿOÿ,ÿÿ.ÿ 1Dÿ ?TÿG]ÿ ;Pÿ->ÿ 3Eÿ @Qÿ8IÿAPÿ0=ÿ )óVe‘¼ØÞ"s¦O…Wë•ÈŠÿÈà•ÿ¤Ì“ÿ…Àÿa¸iÿH¯Uÿ\¨[ÿt«gÿy­sÿw¡oÿW£sÿF—lÿ8—oÿ-‹eÿQ¨ŠÿXµ—ÿN‚yÿ4QLÿ)'ÿ ÿ?/ÿ3lTÿ2ÿ\MÿWJÿ#]Qÿ-k`ÿ-peÿ'haÿ'mgÿ%tmÿ"vpÿvrÿwrÿvtÿszÿgpÿ_hÿ$rzÿQWÿ&*ÿ ,-ÿEFÿQNÿHDÿ0)ÿÿ0(ÿk]ÿ3¯šÿ<À«ÿ:ƨÿIÖ·ÿ-`Oÿ ÿ #ÿ#wXÿ—hÿ’hÿ+•oÿ%ˆhÿ#}cÿzdÿp_ÿk]ÿg]ÿ_Xÿ WUÿ ÿÿÿ /2ÿ 03ÿ 15ÿ.3ÿ3=ÿ9Dÿ5Aÿ ;JÿJ]ÿ 9Mÿ)ÿ#ÿ(8ÿ=RÿH`ÿ>Qÿ 2Eÿ5Fÿ4DÿFUÿ RcÿM]ÿ#.úJ]£‹ºÈ3ÀÔÌ;MŸ‚¼k¤€ÿ±ÀÿVsIÿ4X0ÿT’JÿiÆ[ÿwÀhÿ·iÿy«rÿ€¯|ÿ[œrÿk¸ŽÿmبÿH¦}ÿGrÿ&H9ÿÿ ÿÿ ÿ#G4ÿ4lOÿ—zÿ6Šrÿ3Špÿ<˜€ÿ?Ÿ†ÿ3‹wÿF¦Žÿ%XGÿ )ÿQ@ÿ#_Lÿ'dQÿ-mZÿ(iVÿ#cQÿ)p`ÿ%raÿ%vhÿ%|oÿ"}sÿ }rÿypÿooÿovÿksÿ%|†ÿ 9@ÿ%*ÿDJÿ?EÿJOÿTVÿ]\ÿMLÿ'%ÿÿ :8ÿ lhÿ)ÿOçÐÿ=’ÿ ÿ  ÿaHÿ—gÿ#Ÿpÿ.œrÿ+“lÿ+Žlÿ#Škÿ€dÿ|eÿ veÿ#wiÿ\Qÿÿÿÿ //ÿ 33ÿ7<ÿ 6<ÿ 4<ÿ6?ÿ >Hÿ>Iÿ6Bÿ8Gÿ BTÿ0?ÿ(ÿ,ÿ8NÿHcÿD\ÿ 8Lÿ3Dÿ9Fÿ8EÿZkÿTdÿ+ú2A§k¯GÚçë †ÌÀˆD’sïg‹gÿ`†\ÿƒ¯rÿs±`ÿm¼[ÿz¼hÿ‹Èyÿ‚¼ÿПÿ£ï¼ÿm³ˆÿ7eNÿ6$ÿÿ!ÿ-VCÿa¦Šÿz­Ÿÿ)#ÿ/ ÿB}_ÿ?|]ÿA…eÿ>ƒeÿ;‚eÿ:…iÿ;‹pÿ<’vÿ:vÿ:zÿ7Žzÿ5wÿ1†sÿ>œˆÿG¤ÿ8-ÿ* ÿ$ZLÿ#]Nÿ(eUÿ,lZÿ-saÿ(o[ÿ'p]ÿ$p`ÿ#seÿ%ymÿ#}rÿ!zrÿtmÿomÿ€ƒÿ$}€ÿdhÿ,.ÿ 7:ÿUXÿEHÿQRÿ acÿVTÿTRÿgcÿIHÿ$#ÿÿ2-ÿskÿ4•ˆÿ ÿ  ÿ iQÿ«wÿ#£sÿ/Ÿrÿ,˜pÿ-˜sÿ&˜sÿoÿˆmÿiÿ-ŠwÿG=ÿ ÿ ÿ -)ÿ53ÿ 87ÿ ;=ÿ =Aÿ =Bÿ7>ÿ4<ÿ3=ÿ9EÿNÿ >Pÿ5Gÿ 0ÿ!ÿ ):ÿXsÿ\rÿ/@ÿ;Iÿ1@ÿ9Gÿ ]pÿWmÿ*:ú+<ÉE‚•\ÆÜâµØØUD¯¡êO—yÿ¸ŠÿÊíŸÿƒ³cÿ|³XÿÎwÿ‹Ð€ÿ¸ø¸ÿ­à¸ÿ`ƒgÿ#ÿ  ÿ%ÿ&`7ÿ`ʆÿ}ÖœÿgµƒÿŽÆœÿJoTÿ0ÿQ•oÿIkÿFiÿAˆhÿ=†iÿ:ˆlÿ3hÿ+t`ÿ,weÿ5ˆwÿ9€ÿ7‹ÿ6‚ÿWĺÿI¡—ÿ)$ÿ)"ÿ MCÿ&]Oÿ-kXÿ'dTÿ&kWÿ'mZÿ$p\ÿ#p\ÿ!raÿ#whÿ#zlÿ"ymÿ tkÿtlÿ"ƒ|ÿ'€|ÿ A=ÿ+*ÿ 77ÿPOÿXZÿNOÿXXÿ]\ÿXXÿZZÿ__ÿRTÿBBÿ$&ÿ "ÿNJÿ3-ÿ ÿM:ÿ¦tÿ#«vÿ4¨wÿ/£tÿ,¡sÿ%£vÿ£vÿ“oÿˆhÿ2—}ÿ4+ÿÿÿ:3ÿB<ÿB>ÿ ><ÿ==ÿ@Aÿ=@ÿ9>ÿ9Aÿ=Fÿ:Eÿ5Bÿ ?Pÿ >QÿDZÿ)8ÿ ÿ*:ÿ F[ÿ J_ÿ-=ÿ@Qÿ=Oÿ0AÿpŠÿi…ÿ#3ú*;â0ko¯Êԃʼ±<—zÿ`Ÿrÿ«Ð€ÿ“Äoÿ—Îmÿ“Ò|ÿ«éŸÿ’À•ÿ4"ÿ%ÿ*A-ÿJ|Tÿy¾ƒÿ_¾yÿ]Âyÿh¾}ÿcµvÿr¤vÿt¡yÿ='ÿ=wWÿO—rÿM“oÿH“rÿAŽpÿ8ƒiÿ3gÿ6ˆrÿ>•‚ÿF£’ÿC¡’ÿ=˜Žÿ5ˆ€ÿ5wrÿD?ÿÿ*%ÿ#PHÿ)]Rÿ+hXÿ(gWÿ(m\ÿ'p]ÿ%s_ÿ#p_ÿ!raÿ"seÿ#vhÿ"vlÿ"vmÿ"zoÿ'ˆ|ÿ%zoÿ.)ÿ:7ÿIFÿ"`_ÿZXÿ\[ÿ edÿgdÿdaÿ`_ÿTRÿRRÿVVÿEIÿ 03ÿ +*ÿÿ ÿ 2#ÿ—iÿ(µ€ÿ8­ÿ2ªzÿ-¦wÿ%¨yÿ«}ÿšsÿ˜tÿ7š€ÿ,$ÿÿ ÿ@6ÿIAÿPIÿ LFÿGDÿFEÿBCÿ?Dÿ=Eÿ;Eÿ8Eÿ9Gÿ @Rÿ 9Mÿ6Gÿ ÿ#%ÿÿ ÿÿÿ C0ÿ"|`ÿ1£€ÿ3¯Šÿ(­…ÿ ±†ÿ«…ÿ*˜ÿ,y_ÿ ÿÿUAÿhTÿeTÿeZÿ `WÿUMÿVPÿ[XÿPPÿEJÿHRÿ>Jÿ )ÿÿ"ÿ+3ÿ.8ÿ3?ÿ:Eÿ8Hÿ4Cÿ5IÿDZÿ 7Lÿ-Aÿ BWÿ ;Nÿ3Bÿ FXÿBTÿ,9ÿ2?ö]r«\Ÿ­8¯ÎÊ:4}p×@Ž|ÿ•È­ÿøøçÿi€eÿCdEÿs·}ÿyÖŠÿë“ÿ‹ëŽÿšçƒÿéƒÿ¦âƒÿ¨â‚ÿ£íŽÿ¤ï’ÿ‹àˆÿ€Ô…ÿ’Οÿ/L9ÿElTÿšØ¸ÿi¡†ÿ2L@ÿ& ÿ !ÿ&%ÿ0.ÿE@ÿ!WNÿ*kWÿ0z\ÿ2ƒ[ÿ=iÿA†kÿH9ÿ;0ÿ-m_ÿ3|pÿ0wiÿ0viÿ2yiÿ3zhÿ1ygÿ.vgÿ)shÿ%skÿ#srÿ"vvÿ+€tÿ2zÿ % ÿÿJBÿ)h]ÿ0`Xÿ5c\ÿiZÿl[ÿ&sdÿ!h\ÿeXÿ'wgÿC†zÿ3riÿ24ÿ!ÿ%(ÿ /3ÿGJÿ<=ÿ '%ÿÿ*%ÿ_Rÿ&‹zÿ)œˆÿ$¡ˆÿƒÿ+¾¡ÿ-pXÿ  ÿ,ÿyRÿ wVÿ w\ÿm`ÿd_ÿ`]ÿ WXÿTUÿIJÿ IPÿR\ÿ (ÿ ÿÿ((ÿ.3ÿ,/ÿ6=ÿ:Cÿ3Aÿ7Dÿi_ÿs_ÿzdÿm[ÿ!raÿp_ÿ.…tÿ4`Zÿ&#ÿÿ()ÿBCÿPPÿWWÿWVÿRPÿ>;ÿ&!ÿ)#ÿ D;ÿtgÿ#•€ÿ!—€ÿ/¼¤ÿ*eRÿ  ÿ.ÿƒZÿƒaÿ…hÿvgÿicÿhaÿ a[ÿUOÿURÿW\ÿ18ÿ ÿ ÿ !ÿ01ÿ24ÿ.2ÿ4>ÿ:Cÿ4Bÿ0>ÿ5Hÿ2Dÿ):ÿ-?ÿ =Oÿ ?Pÿ6Eÿ0>ÿ †zÿ:rÿ8zmÿ<€rÿ:}iÿ:kÿ8lÿ3}oÿ/|pÿ)wrÿ(|vÿ)‹|ÿscÿÿ61ÿ1aVÿ3e[ÿIvlÿGpeÿ …kÿz`ÿ }gÿtaÿ"wgÿ,}oÿ ÿ ÿ%%ÿCBÿQOÿ [Zÿ!\Zÿ%ecÿ#d`ÿ_ZÿPJÿ1*ÿ% ÿ6-ÿ\Nÿtcÿ&¤Žÿ TCÿ ÿ 3$ÿgÿiÿŠlÿ}kÿ"phÿmaÿ paÿ g\ÿleÿ \`ÿ ÿÿÿ)*ÿ02ÿ5:ÿ47ÿ1:ÿ7@ÿ8Hÿ3Bÿ,?ÿ7Mÿ4Iÿ)<ÿ/Bÿ BUÿ BTÿ3Bÿ3@ÿ ?Nÿ9Gÿ1?ÿ-;ÿ6HãQk—H¤=}¨Ÿƒ;vWæšÖ¦ÿ†ÄÿVŠZÿyµsÿ•ØÿŽÒ€ÿ¤ëÿ±úÿ­ô˜ÿ«ö£ÿ·ú­ÿµúºÿªï¯ÿ¦éµÿªíºÿ³ïÄÿ“º¡ÿ!ÿ&E,ÿN…XÿZšiÿ[¡rÿVœrÿVœwÿTšwÿTœ|ÿUŸ€ÿR}ÿN˜tÿL˜pÿN“pÿW˜|ÿlºœÿ7r_ÿA6ÿ0k`ÿ?‚sÿ=}mÿ>mÿ@€lÿ@‚mÿ@ƒmÿ;ƒrÿ5€sÿ0}rÿ-vÿ/‹}ÿm`ÿÿ@9ÿ2o_ÿ.k[ÿE}hÿCs`ÿ%Šiÿ €cÿ'ycÿ&ydÿ8œˆÿ ,$ÿ ÿ ($ÿE>ÿ\Uÿ"e]ÿ'mdÿ&lcÿ,tkÿ-wmÿ$kcÿ g]ÿ]TÿG@ÿ0)ÿ,%ÿ@7ÿykÿ NBÿ  ÿ ;+ÿ“oÿ’pÿ†kÿ$}gÿ*lÿ…oÿ }cÿ o\ÿwkÿ==ÿ ÿ ÿ%%ÿ.0ÿ56ÿ=Bÿ;@ÿ3;ÿ4>ÿ8Iÿ4Fÿ-Bÿ1Fÿ1Fÿ*>ÿ+>ÿ=Rÿ J`ÿ G\ÿ:Iÿ5Cÿ9Iÿ9Iÿ=Pÿ4Fÿ2FóLe¥6v’EÄÚâ Tƒg¥o¾†ø˜é¨ÿW\ÿsªmÿ˜ÔŠÿŽÊ|ÿÚ…ÿ­öÿ­øÿ¨ö¨ÿ¯ú±ÿ³ø¾ÿªò¸ÿ­í¼ÿµïÄÿÀúÔÿ’Ÿÿ4!ÿCoHÿ]œeÿ`¤lÿc«rÿ`¨rÿa«}ÿa­‚ÿ]¦€ÿ\¦‚ÿ]¦ƒÿ[¤ÿTwÿQ—pÿPoÿXšÿEƒoÿ<2ÿ"OFÿCƒvÿ>zmÿ?|lÿEƒmÿD…oÿD†pÿ@†sÿ9ƒsÿ3rÿ1€wÿ2Šÿ%|rÿÿ?7ÿ3ydÿ2wcÿE‚iÿDyaÿ'Šhÿ%ˆdÿ-|cÿB¤ˆÿ$p`ÿ ÿ--ÿC>ÿ aVÿ$k_ÿ)seÿ.zmÿ0}pÿ0}rÿ/|pÿ-yoÿ)viÿ"peÿe[ÿRIÿ6/ÿ& ÿ7/ÿ/(ÿ ÿ@1ÿ’mÿ#’rÿ+“wÿ1Žvÿ0†pÿŠkÿ …eÿ‚iÿ#ƒsÿ ÿÿÿ/-ÿ67ÿ9<ÿ=Bÿ;@ÿ6Aÿ8Cÿ4Eÿ.>ÿ-Bÿ/Dÿ-Dÿ&;ÿ#5ÿ/Cÿ>TÿCWÿEVÿ;Mÿ1Bÿ8Mÿ @Vÿ8Mÿ-@ÿ)<ó6M°/pŠBÈÜ⟼«@EgЈئøi¤wÿ]Zÿ’Àÿ¤Öˆÿ±âŽÿ­öšÿ­úœÿ£ú¤ÿ¤ú¨ÿ¯øµÿ±ø·ÿ¼ô¾ÿ¾òÀÿÌúÜÿ¼˜ÿ1 ÿUƒVÿs¸rÿe¨cÿmºmÿzÌ€ÿrÂÿp¼€ÿkµ€ÿi³…ÿcª€ÿ_¤}ÿ`¨€ÿ[¡|ÿQ“pÿI‹oÿRš‚ÿ%ZIÿL?ÿ=}oÿC…tÿBƒpÿGŠrÿF‹rÿF‹pÿA‹sÿ<Šsÿ5†rÿ3…tÿ?†}ÿJ“Žÿ ÿ4,ÿ'€eÿ)•pÿ<‹iÿE“pÿ1ƒ`ÿ9’lÿTŽwÿrµšÿÿ2)ÿ"ldÿ`Vÿ$mZÿ)vaÿ-}hÿ-hÿ+zgÿ,|iÿ2†tÿ1†vÿ+}lÿ)|mÿ%thÿg\ÿTLÿ@9ÿ-'ÿÿ ÿ?3ÿ&pÿ)…kÿ0‹oÿ3•vÿ/’rÿŽiÿ•kÿŽpÿ iWÿÿÿ&"ÿ;3ÿ=;ÿ@Aÿ=@ÿ8=ÿ>Hÿ=Gÿ1Bÿ/@ÿ3Iÿ-Cÿ/Hÿ4Oÿ&9ÿ(ÿ%7ÿ;Oÿ@Pÿ>Pÿ9Nÿ4Hÿ5Lÿ4Jÿ 6Oÿ6Mÿ,?û/C½)g|Tm¦‹^W¦wÞQˆ`ÿi˜dÿŸÊˆÿÈ}ÿ«Ø†ÿ«ô—ÿ¯úÿ£ú£ÿŸø¡ÿ­ö¯ÿ·ú¸ÿÄú¾ÿÂô¼ÿÌúÖÿ‹¸•ÿ/ÿc—aÿ€ÈyÿƒÎzÿƒÔ|ÿwÆtÿyÊÿ}Ì…ÿsºƒÿoµƒÿh­‚ÿi¯…ÿi¯†ÿcª‚ÿ_ªƒÿQ˜zÿ\ªÿ6t`ÿ?4ÿ$WJÿA…tÿEˆsÿL’tÿJ’tÿJ“tÿE“tÿ@’vÿ:vÿ8wÿJŠ€ÿv³³ÿ)#ÿ +#ÿ`ÿ&¤zÿ3‹eÿFŸwÿB•oÿ>‹hÿz¨ÿ.J;ÿÿ'p`ÿvkÿ sdÿ*|cÿ0†iÿ1ˆlÿ3rÿ0†oÿ/…oÿ.‚oÿ0†tÿ-€pÿ-pÿ.‚tÿ+|rÿ"iaÿ]VÿNGÿ # ÿ ÿ #ÿhWÿ2…pÿ7rÿ-ˆiÿ)‹hÿ“kÿ˜kÿ-¡}ÿD3ÿÿ ÿ ;2ÿ D9ÿ FDÿ OPÿLOÿADÿDOÿ>Hÿ1Bÿ7Iÿ4Lÿ9Tÿ3Mÿ8Tÿ9Rÿ%9ÿ/ÿ);ÿ>PÿE\ÿ;Qÿ4Jÿ1Hÿ 5Nÿ 8Pÿ:Qÿ3Hÿ*<ÿ0DÅ*e|o]“|‚I2öTVÿ’¸ƒÿ¡Î†ÿªÔ†ÿ¨ëŽÿ¨ò“ÿŸö•ÿ«ø£ÿ¼ú¯ÿ·ú¨ÿÌú¯ÿÈô¯ÿÖúÜÿ±“ÿ0ÿw¦pÿ˜ÜˆÿŽÔ}ÿˆÒvÿ‹Ø}ÿ܆ÿŠÚŠÿ€ÌŠÿwÀ†ÿp¸†ÿmµˆÿm³†ÿd±…ÿ[±ƒÿP£|ÿW±ŽÿG—|ÿUÿ:Tÿ4Lÿ:Rÿÿ%5ÿ8LÿD\ÿ8Pÿ6Pÿ1Iÿ 8Pÿ 7Pÿ9Pÿ6Lÿ;Qÿ3Hÿ.B»1kƒL¦À·/Et_³Zˆaý‚¨yÿ‹³vÿªÔŠÿ¨ëŽÿ¡ëŠÿªöœÿ¤ï—ÿ¯ëœÿ¾úªÿÎú­ÿÒö¯ÿÞúâÿ—·Ÿÿ2ÿm˜eÿŸåÿ—Ü‚ÿ’Þ|ÿšéˆÿ—ç‹ÿÞ‹ÿ†Òÿ}È‹ÿv¾‹ÿsº‹ÿp·‹ÿh·ˆÿ]¸†ÿT¯…ÿT±‹ÿT±’ÿF7ÿ.#ÿ=Šsÿ@‹rÿUª†ÿZ³ŠÿU­€ÿU·ˆÿM¯ƒÿI³†ÿF«…ÿ]¡‹ÿЏ«ÿ@|hÿ 'ÿhIÿ ’hÿ9Žhÿ@ŽiÿDŠgÿlÆšÿMdQÿ ÿ1}eÿ4Špÿ€hÿ,“wÿ3“lÿ4’kÿ5•mÿ4—pÿ/lÿ,Šiÿ+Škÿ,ˆmÿ,…oÿ-‚oÿ2†vÿ4†wÿ2}sÿ4}tÿ-meÿIDÿ &"ÿÿ ÿ ,#ÿN=ÿlPÿyXÿ…`ÿ)˜pÿ(oUÿ ÿÿL<ÿWBÿZFÿ\Rÿ RNÿPNÿ WVÿLRÿ@Gÿ=Lÿ>Nÿ6Mÿ6ÿ:3ÿ-%ÿ .#ÿ A/ÿ U?ÿoTÿ/ˆiÿ;,ÿ ÿ<,ÿ%mUÿcHÿcJÿ`Rÿ VLÿUNÿ ]VÿORÿBDÿ@MÿDRÿ-ÿ8•pÿ?wÿ=•mÿ?špÿ@¤tÿ;Ÿpÿ8pÿ7¡sÿ3¡sÿ.špÿ-˜rÿ-’pÿ0˜vÿ3•wÿ1Šrÿ4ˆsÿH¡ÿ3pcÿ *#ÿ 5+ÿUGÿ'XNÿ5XPÿ"ODÿ6-ÿ.#ÿ3%ÿH8ÿ'cPÿ$ÿ ÿ[Dÿ%yZÿ sQÿoOÿkUÿ ]Nÿ ZMÿ ZOÿQOÿNNÿLUÿHQÿDVÿäC]w«ÊÔƒ³—w³Šøe—oÿ’ÀŠÿ£Ò•ÿ¯Ô•ÿÀÞ¡ÿÌå«ÿçúÆÿÖë·ÿàôÂÿòúíÿ·Æ·ÿ3?.ÿ—sÿÂéªÿÂëªÿ·ï¡ÿ¸ø¨ÿ±úªÿ¨ö¨ÿ˜í¨ÿé¨ÿŠçªÿ‚ç¦ÿzà¡ÿvÞŸÿsâ£ÿrà¨ÿeУÿiÖ­ÿiÒ±ÿ3iUÿ%ÿL£€ÿ\±…ÿVªzÿ`¼ƒÿcÈŠÿaÎŽÿ]Ò’ÿ_Ö•ÿpÖÿpКÿïÀÿ4#ÿ#I7ÿA}cÿi“ÿRrcÿ8}eÿ-mXÿ ÿ$WAÿ,ƒ[ÿ;—lÿ?’dÿG¦tÿDªzÿ=£rÿ8pÿ6¡sÿ3£tÿ1£tÿ/¡vÿ0wÿ.švÿ3˜zÿ2tÿC£Šÿ?zÿ4+ÿ )!ÿRCÿ"kVÿ.m[ÿ5g\ÿ.g[ÿTIÿ?5ÿ.&ÿ%ÿ1*ÿ ÿ(ÿ&oUÿ)}\ÿ"zTÿwQÿoWÿeOÿ `Pÿ cRÿ \Uÿ XTÿ PXÿIOÿ EUÿ ETÿ GXÿ FXÿ EUÿ GXÿ DPÿ5Eÿ0Lÿ ;Xÿ8Tÿ9Pÿ¤rÿ9¤pÿ6¦sÿ3¨vÿ2¨wÿ2ª|ÿ4­‚ÿ/£zÿ2˜vÿ9}ÿC¦ŠÿN=ÿ "ÿH<ÿ%dOÿ&sXÿ3gÿ7yiÿ2vgÿ)g_ÿ\UÿHEÿ )'ÿÿ ÿ4)ÿ4ˆlÿ0‹gÿ"Tÿ €UÿtVÿcJÿ aMÿlVÿ cWÿ VOÿ VZÿ]`ÿTaÿVdÿPaÿ @Nÿ5Aÿ 9Eÿ ÿ.Jÿ @`ÿ ?[ÿ >WÿRÿ D[ÿ@Uÿ=Tÿ6Lÿ6J½>y6«È¾Lv³˜ÁXs\ûˆŸˆÿœ˜ˆÿrh]ÿJB?ÿVOJÿD@AÿA>?ÿ;9:ÿ..-ÿ14,ÿ¡«’ÿÒí¼ÿÖòÀÿÆï¸ÿºò³ÿ¯ö³ÿªø·ÿ¡ú¼ÿ•ú¸ÿŠö±ÿƒö­ÿø­ÿ€ô¯ÿˆô±ÿ…ò·ÿ|åµÿwÞµÿ‚éÊÿe¼¡ÿC1ÿ:)ÿlÀÿ}ÖŸÿtÌŽÿpÐŽÿpØÿoÜ—ÿyï£ÿë¤ÿ—â¤ÿÂöÎÿ-B.ÿ ÿ,ÿ'=6ÿ/B=ÿ#E<ÿ=4ÿ3&ÿ1#ÿAªtÿ0ˆXÿ4“Xÿ:œaÿ@¤pÿ>¤sÿ=ªtÿ;­zÿ7¯zÿ4¯|ÿ3³ÿ4³‚ÿ4¯ƒÿ1œvÿG¸˜ÿ6€lÿ ÿ 'ÿ'[Lÿ.rZÿ._ÿ5‹mÿ5‹sÿ2}pÿ1soÿ3ssÿ-ehÿEGÿÿ ÿ.&ÿ8Šmÿ5‹gÿ%ˆXÿ ŠXÿ\ÿoRÿgPÿlUÿ gWÿ dWÿikÿklÿT]ÿ ¤oÿ@±zÿ@º‚ÿ6·ÿ5µ€ÿ5¸…ÿ7ºˆÿ3±€ÿHÆœÿQÄŸÿG5ÿ ÿF4ÿ,hRÿ8ƒeÿ8Šhÿ6’rÿ5˜zÿ7‹|ÿ<…|ÿDƒƒÿ?szÿ,aeÿGIÿ ÿ ÿ$`Lÿ:†gÿ-“dÿ"‹Zÿ€[ÿ|\ÿz]ÿiOÿkZÿzkÿ[Xÿ<;ÿ&,ÿ $ÿ$,ÿ 2:ÿ 4=ÿ 4=ÿ5:ÿ 3?ÿ 0Mÿ 4Pÿ :Tÿ B[ÿDXÿ;Mÿ:JÿF[ÿ 6Hÿ,=ÿ 2Dÿ8Mÿ=QÿI`ÿI_ÿ?Tÿ6O½ WpBÿÿÿœ·µJ•¾¾¹7GBÿ!.)ÿPeRÿFZHÿ>T?ÿAV@ÿUoJÿa|TÿI\Aÿ*5#ÿ&-#ÿAE=ÿˆ‹‚ÿ¸Æ¸ÿÐçÖÿØøâÿ¾ëÎÿ±ëÀÿ¤ò·ÿœò¯ÿ˜ú«ÿ“ú³ÿ‹òºÿ‹öÂÿŽúÎÿŽôÌÿòÊÿšòÎÿ…¾¤ÿ)H3ÿ6M4ÿ¤Îÿ¾à¯ÿÌýÆÿ¯çµÿ}³ŽÿNaÿBeDÿ=]8ÿ!ÿ  ÿO…`ÿH\ÿ@oUÿGv]ÿB|cÿEƒgÿ[œzÿ)ÿ $ÿ;Zÿ>‚ZÿE•dÿ<Ÿaÿ:¤dÿD¸wÿ=ȃÿ%ºwÿ,¼‚ÿ9ÂŽÿ6¼ÿ2³Šÿ`Ö±ÿBwaÿ ÿ4#ÿ&oQÿ+|[ÿ6Šiÿ=ŽrÿNÿ IXÿ HVÿ EXÿ =Wó>V¨i—¨ÿÿÿÿÿÿÿÿÿŽ­·A’º¸6WMÿvª‚ÿh˜sÿh˜hÿo£mÿƒºmÿоrÿœÄ‚ÿŽ«wÿkv\ÿAD9ÿ-,)ÿ754ÿwtvÿ·¸µÿÂÖÆÿÖúÞÿÄøÌÿ«ï³ÿ£ò­ÿší·ÿ’ïÄÿŽöÈÿŽöÊÿ“ôÎÿ˜òÎÿ£òÎÿ³åÆÿXtZÿ:D-ÿÜë¾ÿïöÈÿÄØ­ÿl†hÿ}ZÿE‹hÿ=€]ÿ]³Šÿ8#ÿÿ5rRÿ=sUÿFdÿ<£`ÿ:ªcÿ>µpÿ6À|ÿºvÿ*†ÿ<ʘÿ5µŠÿLà¸ÿ?sÿ%ÿ ÿ"`Dÿ-…]ÿ-cÿ6mÿ@“zÿ?•rÿ?—lÿ?šiÿ?œhÿ@˜mÿA˜sÿ?tÿ5voÿ,dcÿBGÿ ()ÿ HFÿLŠ|ÿIˆvÿ=ƒgÿ7€`ÿ3z`ÿ1v\ÿI=ÿ ÿ ÿ41ÿEEÿOPÿPQÿ BDÿ @Aÿ EFÿIIÿ GJÿ GOÿ JWÿ5Aÿ/>ÿ >TÿB]ÿA`ÿBaÿUvÿ 5Jÿ2EÿCUÿFTÿ GPÿ EMÿ DVÿEaÿ A\ì&]vgÿÿÿÿÿÿÿÿÿ£ÆÂXh•×`Žrÿp£‚ÿr¦|ÿw«|ÿ¾oÿÀkÿŸÊvÿµØ†ÿÊà•ÿ±¾ƒÿvvUÿ99)ÿ(( ÿ,.&ÿNUHÿ’¡•ÿ±ÌÂÿÐúéÿÆöéÿ¦ÞÎÿœâÀÿ˜é¾ÿ•éÂÿëÌÿéÌÿ£çÆÿºëÎÿ…£ˆÿ_rRÿÖôÀÿ¡ºˆÿRmHÿHlFÿW‹`ÿZ•hÿ]’dÿo£rÿZ—iÿ(ÿ,hFÿ5|Uÿ3ˆ`ÿ2Šcÿ-Šcÿ*†_ÿH¸‹ÿ-ÿ 8"ÿ4gÿ1€[ÿ9’gÿ:¤hÿ>µsÿ3«oÿ.­tÿ)µ|ÿ3Èÿ:ÎÿFÒ¤ÿ`íÆÿA0ÿ ÿQ<ÿ6ˆgÿ6“kÿ6£tÿ;Ÿwÿ?œ|ÿ>vÿ=oÿ>kÿ>¡lÿ@œpÿAœvÿC˜€ÿ=†}ÿ1pmÿ2kmÿ=<ÿ "ÿ!MBÿ9wgÿ;ylÿ7wiÿ:mÿB7ÿÿ3(ÿN?ÿM>ÿRFÿVJÿPJÿ HCÿ HIÿMQÿ LQÿ LQÿ PXÿ JUÿ8Dÿ >Mÿ EXÿ C[ÿC\ÿB\ÿVsÿ 9Oÿ4FÿEWÿN]ÿIUÿ ENÿ DWÿGaÿ BXÿ 7L³e¡&ÿÿÿÿÿÿƾƒX†pðkœƒÿ}µÿtª}ÿ†³iÿ¸hÿ£Êsÿ£Äpÿ¼ÒzÿÒâÿéï¡ÿ‹ÿkkIÿ13 ÿ"#ÿ#& ÿ>DDÿ€Ž•ÿ±Âÿ±ÐÐÿ¸íÈÿ£Ü¸ÿ—Ô³ÿŸÚ¾ÿ¦àÈÿªÞÆÿ¼åÈÿ¸Ú¸ÿ—±ˆÿz—kÿRkDÿLmDÿw³tÿy€ÿVeÿJ€VÿHwQÿ[šmÿ6 ÿ+eEÿ@Šcÿ9kÿ8’lÿ6šrÿ7vÿAµŠÿ%ÿdDÿ*ˆaÿ(ƒ]ÿ5rÿ8¤oÿ9­vÿ-¨sÿ-¦tÿ9ºŠÿ<Ä—ÿ8ÈœÿaúÎÿ8ˆlÿ ÿ6$ÿ8oÿ=—pÿ<Ÿsÿ8¨vÿ<¨zÿ?¦}ÿ?¨zÿ?ªvÿ>¨rÿ?¨rÿ@¤tÿB¡yÿEŸƒÿE—‹ÿCŽŠÿ9|}ÿFDÿÿÿA8ÿ(VVÿ)WZÿ%UOÿ-)ÿ3(ÿ&eTÿ!gMÿT=ÿ[FÿXBÿRFÿUIÿRTÿQUÿ MWÿR[ÿX_ÿ FOÿ9Bÿ HUÿ GWÿ AUÿ CXÿ CZÿZvÿ @Uÿ3Dÿ ?OÿN_ÿNZÿGRÿ FXÿ CZÿ7Jÿ$6ó)\oeÿÿÿmš‹™Q€rüw±—ÿy¯ÿ‹¯wÿŸÂ€ÿ¨Ä}ÿ¯Ê}ÿÌÞŠÿÚçÿàçŽÿïòœÿéé˜ÿº¸zÿppLÿ-/ÿÿÿ&,*ÿt‚vÿÀܸÿÈëÆÿºâÀÿ¨Ð³ÿ¯ÖÂÿ¾àÎÿÎëÔÿÈíÈÿ}˜sÿ);#ÿ\yPÿ•Ê‹ÿo·mÿZ¤`ÿI—Uÿ>tLÿ/X=ÿr­…ÿ)J3ÿ'D0ÿX‚gÿ<]Lÿ8ZGÿIzcÿTrÿ;dÿ )ÿ7wÿ rRÿsQÿ,—mÿ4¤tÿ-šlÿ-ªzÿ3ªÿOÀšÿGÀ˜ÿCÒ¨ÿoýÖÿ E4ÿ&ÿkLÿ8¤zÿ@ŸtÿAªzÿ9­wÿ<³}ÿ>³€ÿ>³}ÿ?µzÿ@³vÿ?¯vÿ?¨wÿ@¤zÿD¤…ÿM¨—ÿJ¡—ÿ$[Xÿ )&ÿ #!ÿÿÿ-5ÿ.;ÿ')ÿ!HJÿ3s`ÿ-kWÿ,zUÿaAÿhGÿgFÿaLÿ[IÿRQÿRUÿUcÿT\ÿJLÿ BFÿ BFÿR[ÿ JVÿ CTÿ EVÿ EWÿ_vÿ FXÿ2@ÿ6DÿJXÿP]ÿJVÿ FWÿ CWÿ ?Tÿ7IùNcžŽµÀÿÿÿ¼ÎÌ5\†}±Z|ÿzµ˜ÿ“·†ÿ¤À†ÿ¦À‚ÿµÊ†ÿÊÚ‹ÿØâÿéï’ÿéë’ÿïë•ÿòïÿØÖ“ÿššmÿOP:ÿ "ÿÿ"ÿ0;(ÿm€cÿºÒ¸ÿ·Ð¸ÿÈåÐÿÔïÜÿÔòØÿÆåÂÿ[rRÿ-A&ÿ‚¯vÿˆÆƒÿV˜VÿN˜TÿF“QÿE€Uÿaœzÿ‚¼—ÿ2 ÿÿ!ÿÿÿÿ$ÿÿ ÿ]Ôªÿ7˜wÿwVÿ €]ÿ(‹dÿ-sÿ3ºŽÿ=ºÿO¯ŽÿQÄÿhúÞÿ@—zÿ !ÿQ7ÿ-ª|ÿ:³‚ÿE±ÿJ¾ˆÿDÀ…ÿ@¼ƒÿ?¾ƒÿ?¾‚ÿ?º|ÿ@·yÿ@³vÿA«zÿA¦|ÿF¨†ÿW¼¤ÿ9‚vÿ,)ÿ-)ÿ"ZTÿTLÿ &"ÿÿ ÿ)/ÿ:ipÿD‹wÿ4r_ÿ.|Tÿ-|TÿrIÿ sNÿgNÿ]Iÿ\Zÿ`cÿUcÿ DLÿ <=ÿIJÿPTÿPWÿ GPÿ HUÿ GUÿ FVÿ[oÿ GWÿ3Aÿ4AÿFUÿM[ÿLWÿ EVÿ BUÿ EXÿ GZþ ?RÎBwˆ<ÿÿÿ¸ÊÆ8Gpk·\’…ÿ“¸Žÿ—·ƒÿªÆŽÿ¯ÈŽÿÄÔ—ÿÄÐÿçé£ÿòò¨ÿíí¡ÿòò£ÿëëœÿéëœÿÄÊ‚ÿˆ“Wÿ[e7ÿ9B#ÿ)ÿ)ÿ-7*ÿAL?ÿz‹vÿ¨º¤ÿ¾Ðºÿ€“|ÿ7J2ÿa‚Zÿz«sÿl¦hÿ]]ÿP“TÿO“UÿT…_ÿV|dÿ&8*ÿ  ÿÿ ÿ ÿ ÿ ÿÿ ÿ ÿ"D5ÿظÿF¦†ÿ/‚eÿ'…cÿ }[ÿoOÿcGÿM8ÿ4cÿsçÆÿF3ÿ%ÿ/cÿ=ÌŽÿ;ÀƒÿEÄ…ÿUØ“ÿN΋ÿFÈ…ÿDÎÿBƃÿ?¾}ÿ?¸yÿCµzÿG³ÿJ³†ÿU¼•ÿD—}ÿ:0ÿ0*ÿ.k`ÿB‚ÿG•†ÿ-iaÿ'1ÿÿ ÿ4ahÿUŽÿ@oÿ5_ÿ:Šhÿ)yUÿ%pPÿgQÿhUÿg_ÿ\WÿGJÿ ?AÿEEÿQQÿVVÿJOÿ FLÿ GPÿ HRÿ IUÿ Q`ÿ DQÿ;Gÿ ?LÿFTÿERÿHVÿ HWÿCUÿ EWÿ GZþ =Oà'arjÖåé ÿÿÿªºº7LtoÀp˜tÿ•ºŠÿŸ¾Žÿ¡¼ÿ¸Ê˜ÿÀ̘ÿÐÖœÿåé¦ÿëë¤ÿëë¤ÿïò¡ÿïöšÿéò’ÿÔâ‚ÿÄÔtÿ­Âmÿ’«eÿm€OÿIW9ÿ8C.ÿ,3%ÿ*2%ÿ3;0ÿ-7)ÿ2A-ÿlgÿv£oÿg˜cÿ\“\ÿOŠRÿJ…Oÿ$>)ÿ ÿ  ÿÿÿÿÿÿÿÿÿ  ÿÿ)?3ÿ…åÄÿ]·—ÿlOÿG/ÿZ?ÿ mPÿ&aHÿ'_Gÿ#T9ÿ ÿ"F-ÿF·}ÿ;̆ÿ<Æ€ÿHÖ‹ÿTà’ÿZà’ÿTâ•ÿJâ•ÿFÔ‹ÿAÄ€ÿ?¸|ÿE¸ÿM¼ˆÿWÄ“ÿVº’ÿP=ÿ +!ÿ3oaÿJ—†ÿGŽƒÿA‹|ÿFƒÿDt€ÿ=Hÿÿ(-ÿA|tÿTšÿJ˜ÿ=…lÿ9ˆlÿ.w]ÿ+wcÿ*tcÿRJÿ ;4ÿ =<ÿRPÿXVÿJJÿQPÿPRÿ OTÿ HOÿFOÿ JTÿFQÿBLÿ DPÿN\ÿJWÿ @LÿDPÿ FUÿDTÿ L[ÿ JZÿ DVýVh±•¼Äÿÿÿÿÿÿÿÿÿ­¾¼GX}]Øi—hÿЏƒÿ†¯|ÿ—¸…ÿ±Ò˜ÿ³ÊŽÿÌàŸÿÔàœÿÊÖ’ÿåï¤ÿïøªÿòø¨ÿâíšÿÌÖˆÿ­Ätÿ¨Îtÿ¼àŠÿ·Öÿ¡¸‚ÿ‹šwÿ|‹lÿP_Jÿ+6'ÿ9I5ÿ€Ÿzÿƒª}ÿ`…_ÿ_†_ÿTyTÿ&?(ÿ ÿ ÿ ÿ ÿ ÿ!ÿ"ÿ ÿ#ÿ& ÿ ÿ ÿ ÿ ÿ(<3ÿ?hXÿaEÿ-…aÿG·‹ÿIµˆÿWÄ’ÿoȘÿ2T6ÿ ÿ&a:ÿFµsÿ@ÂyÿCÖƒÿGí“ÿTï—ÿ`é“ÿVç“ÿMç˜ÿIÚÿGÌŠÿGÀ…ÿL¼†ÿU¾ŽÿcÎÿ4yZÿ &ÿ"T>ÿM—|ÿQœƒÿTœ†ÿH|ÿJŽÿOކÿ=tpÿ-_[ÿÿ '&ÿ>wvÿO“’ÿ=ywÿEÿ GQÿ MWÿLVÿP[ÿIUÿ ALÿ FRÿHVÿ GVÿ GUÿ IXÿ AOèHz†iÿÿÿÿÿÿÿÿÿ­¾³SGelÍNrlÿt£…ÿ‹¼ÿ¼}ÿÌ‚ÿªÖ‚ÿ±ÚƒÿÀâ‹ÿÎí—ÿÚòŸÿÚï£ÿåò«ÿÞø¤ÿµå‚ÿ¤Îyÿ¡¾yÿ•­sÿµÆ•ÿÚò¼ÿÞïÊÿyˆoÿ$3"ÿCW@ÿOhOÿQgQÿ/;0ÿÿ#ÿ&ÿ $ÿ ÿ+!ÿ2*ÿ3+ÿ*$ÿ ' ÿ '!ÿ ÿ ÿ& ÿÿ ÿ ÿ)@7ÿoЫÿL¯ƒÿ>¡sÿG¼…ÿ@Ȇÿ]ÈŠÿW}Rÿ/a9ÿ:ŽVÿA¯kÿGÂvÿFâŠÿ=øœÿMöŸÿ_ôÿWö¤ÿOô¦ÿPë¤ÿMØœÿQΚÿU—ÿkÖ¨ÿ6wXÿÿ%T5ÿZ¦vÿO•hÿO•lÿP˜pÿ[¦ƒÿT¡€ÿJ˜vÿDŽpÿOšƒÿM>ÿ &&ÿCDÿ3@ÿ4Aÿ/=ÿ$ÿ %+ÿ IOÿ)ZVÿ$RMÿ-aTÿ&]Uÿ"ceÿ!giÿ\`ÿWZÿQUÿPTÿ GMÿ;Aÿ @Fÿ LTÿOWÿLTÿNXÿMXÿ CNÿ CNÿ HUÿ JWÿ HTÿ GTÿ ANé;mzÿÿÿ¯·P>]dÍHm`ÿgsÿ€±zÿ•È€ÿŸÎ}ÿŸÌyÿ¨ÌzÿÆé’ÿØòŸÿÌâ˜ÿÔâÿÖô¡ÿÆô—ÿ¾çÿ±ÎŠÿ±ÆÿÆÖ£ÿÚë¼ÿÂЯÿDP=ÿ ÿ+>*ÿ 1"ÿ$2%ÿ-6-ÿ"ÿÿ ÿ #ÿ+"ÿ<1ÿ4-ÿ92ÿ ÿÿÿ ÿ ÿ ÿÿÿ ÿ1(ÿlÆŸÿX¾ÿJ¼ŠÿOÒ•ÿIé¡ÿiç¡ÿOzOÿ5oAÿC¡cÿB³mÿFÆyÿBÞŠÿ8òšÿHø¤ÿZø¦ÿTö¦ÿIï¤ÿOíªÿLÖŸÿMƘÿZÌ¡ÿiФÿ)P;ÿ ÿAŠ[ÿPšgÿM•aÿW¤rÿX¨wÿQwÿT¡|ÿJœtÿD’mÿN…ÿ:,ÿA>ÿ*]]ÿ.asÿ1etÿ H[ÿ &3ÿ ÿ-5ÿFHÿMLÿ$UNÿ!URÿ!`eÿW]ÿTWÿ\dÿV\ÿOTÿ :?ÿ8>ÿ IOÿNVÿ JRÿ GOÿHRÿP[ÿLVÿ DPÿ GTÿ LWÿ IVÿ HUÿ CQÿ+]k¥ÆØÜÿÿÿÿÿÿ£³ÄeBckãLmiÿaŠpÿ|ªÿ޼€ÿ“ÀÿŸÆ}ÿ¼àÿÐëœÿÊÞ“ÿÌÞ“ÿÐéŸÿÎé¦ÿÀÖœÿºÈ•ÿØà±ÿâë¾ÿàå¾ÿˆlÿ"-ÿr—oÿÊÿtœzÿ/B2ÿ' ÿ#ÿÿ ÿ?3ÿ>3ÿ ÿ ÿÿ ÿ ÿ ÿ ÿÿÿ"ÿ("ÿ ÿÿ[˜}ÿhÊ£ÿ?À‹ÿ@Ö˜ÿ=åÿ]ö«ÿLŸkÿ?XÿT­sÿBºyÿ;Æ€ÿ3Њÿ.åšÿ?ø±ÿJô³ÿIúµÿBí¨ÿBà¦ÿGÚ¨ÿLΤÿXЭÿF¡ÿ7$ÿ2ÿP¨mÿMaÿQ¤cÿTªiÿT«oÿP¨pÿN£rÿLyÿE’tÿ#\IÿF6ÿ.laÿ*g]ÿ-koÿ1ptÿ3tƒÿ)etÿDRÿ .;ÿ(3ÿ 3@ÿ?OÿIVÿU`ÿ>Gÿ 5=ÿV_ÿOXÿ 6>ÿ :@ÿFNÿLUÿLTÿGOÿ EMÿ FNÿMUÿOZÿ FPÿ EOÿ LVÿ LWÿMXÿFQÿ#Ua¾±ÈÎÿÿÿÿÿÿŸ±·bA_c×*D:ÿç³ÿ?دÿHÒ±ÿPÆ­ÿF2ÿ$ÿ-vMÿP¯kÿDŸWÿV¼eÿ[ÊrÿMµhÿN·oÿPµwÿQ¡†ÿ7sgÿF8ÿ0o\ÿ)kVÿ.w`ÿ/‚lÿ0…pÿ,…|ÿ*‚}ÿ!t…ÿi}ÿh“ÿ ?cÿ2ÿ 9ÿ*6ÿ 3=ÿ7Dÿ&/ÿ")ÿ 6@ÿDOÿFPÿ?HÿHQÿIQÿHPÿNVÿ LQÿ FMÿ HRÿ EPÿ BLÿJUÿO\ÿDQÿ!O[Ä­ÄÊ"ÿÿÿÿÿÿ¤³¼Miƒ•ÔF[eÿ",1ÿÿ ÿ382ÿTXLÿvzgÿ“—‚ÿ—œÿmmaÿ44)ÿ-+ ÿ?=-ÿQR<ÿQ[>ÿ_oNÿÆò·ÿÀò·ÿ·éºÿGdLÿ ÿÿ($ÿ+>6ÿÿ ÿ ÿÿÿ ÿÿÿ ÿ  ÿ ÿ ÿÿ ÿ ÿÿM‹sÿRå·ÿ8Â’ÿBÜ¡ÿMç¨ÿ/£pÿI­ÿŠåµÿOКÿ2Æÿ3Ü£ÿ/ç±ÿ/ï¼ÿ-úÆÿ2ø¼ÿ7ôµÿ7â±ÿAàºÿWòÐÿPĨÿ3#ÿ)ÿ=šiÿR³oÿQºlÿTÂmÿM¼mÿG·mÿGºvÿQÈ‹ÿZ«•ÿ(ZOÿ=y`ÿ7rXÿ8\ÿ9\ÿ.€hÿ3Žvÿ.—Šÿ%‚yÿ#}…ÿhsÿ\|ÿJmÿCÿ%Bÿ 1Aÿ/=ÿ#0ÿ(ÿ&5ÿ 5EÿUBÿ ÿ ÿ+)ÿ2-ÿÿ ÿ ÿÿ ÿ  ÿÿ ÿ ÿ ÿ ÿ ÿÿÿÿ ÿ(ÿεÿ—éÎÿwÞ¸ÿ|å¾ÿZ¯ŽÿV¨‹ÿܺÿhÚµÿWÒ«ÿAÖ¨ÿ,àªÿï±ÿý¸ÿ ýÀÿ*øÀÿ/çºÿ<åÆÿXøÜÿG³Ÿÿ/"ÿ5#ÿI­|ÿN¸vÿMÂyÿFÄwÿ>Â}ÿ7¾ÿ3Âÿ8À—ÿP¡ÿ2aTÿ`•`ÿDm@ÿ]—VÿVŽOÿ4Žlÿ8˜vÿ ’ƒÿ ‹|ÿ#‹yÿ$…|ÿR\ÿ@Vÿ *Zÿ .Rÿ C_ÿ Eeÿ7[ÿ.Qÿ)Jÿ%@ÿ(Aÿ ÿ4B?ÿÿB0ÿ.hQÿ‚ÚºÿzïÊÿ_Ú³ÿDÚ«ÿ0é±ÿ!ò¯ÿø±ÿö·ÿ+öÀÿ7öÈÿ@íÈÿQçÌÿ6—€ÿ6(ÿ!X@ÿdÔœÿOºwÿNÊ}ÿM؃ÿA΃ÿ<̈ÿ8Ê’ÿ?Îÿ<…tÿ7k\ÿrªsÿc•]ÿ\“VÿX’Rÿ@¡ÿ6•vÿ ‚ÿ&šÿo_ÿskÿ]hÿTlÿ/cÿ$Eÿ8Qÿ>Zÿ >aÿ Akÿ?kÿ 6Vÿ*Dÿ /@ÿ _ÿ@Vÿ,;ÿ'ÿ )3ÿHZÿ8Jÿ2JÿIiÿJcÿM`ÿÿÿÿ ÿ) ÿN>9ÿ ÿ#ÿ ÿ ÿÿ ÿ  ÿ*#ÿ#ÿ ÿ#)ÿÐçÄÿÂíÀÿ•Ìÿç¯ÿ£ëµÿÂýÒÿo¤zÿ5W<ÿO‹hÿvÔ¦ÿkï¸ÿEç¯ÿ*Ø¡ÿÞ¡ÿ"íªÿ%òªÿ?ýÀÿWúÈÿgâºÿ2rWÿP3ÿLmÿiíŸÿMÜ€ÿMïÿIý’ÿIòŽÿMé’ÿVÞ—ÿ_ÖœÿJ’ÿvÀ«ÿ“Òÿz­|ÿŽÎ—ÿ‹È’ÿiÚÄÿeØÆÿ4³µÿ*˜˜ÿ8³¯ÿ)’“ÿ(|ŽÿRlÿ&Nÿ ?cÿ CVÿ FZÿMlÿFiÿ @hÿElÿFkÿUrÿH_ÿÿ ÿÿÿ*ÿ3Qÿ7Lÿ)8ÿ#ÿ&ÿ$3ÿ%ÿ&IXÍÿÿÿÿÿÿ‹£ªZOp|²CgrþNryÿHhkÿC`]ÿMleÿXwkÿcƒoÿlsÿ£ÂÿØòÐÿvlÿH\@ÿ“­†ÿ«È¡ÿ-8)ÿÿ)5)ÿXmXÿÿ ÿOO=ÿC1&ÿ_E8ÿM/&ÿ0ÿ&ÿ ÿÿ ÿÿ *#ÿ ÿ ÿH-ÿÜ£ÿoÖ—ÿ]€ÿO¯mÿU¯lÿh¼wÿ˜ë£ÿzµzÿ-V5ÿ5eCÿeÆ“ÿ_â­ÿIÞ«ÿ:å±ÿ)é¯ÿô·ÿ1ôÄÿHýÒÿ[çÈÿ+waÿ&rPÿ\Æ’ÿdàÿVÚŽÿ]ë•ÿ]ç“ÿrçœÿˆéªÿ±òÂÿ£Ø±ÿNŠtÿˆÜÀÿ·íÈÿ¨Ü³ÿÔÿíÿ±çÆÿ‚ààÿU³µÿ4¤³ÿ&†ÿ*•ÿowÿXiÿ E[ÿ4XÿZyÿWaÿNZÿRgÿUrÿRvÿNtÿ ?dÿ ;ZÿLmÿ)h‹ÿ1Fÿÿÿÿ ÿ ÿ&ÿ!3ÿ 1Gÿ =Wÿ 6Oÿ8M䊪·=ÿÿÿÿÿÿÄÐÒ(c€ŠtBckÁIhoþIikÿIidÿMkaÿNl]ÿJhVÿg…hÿÊçÊÿ—³ÿaz[ÿ•¯‹ÿ±Ì¨ÿDT@ÿÿ)ÿIZHÿH[Jÿ ÿÿ˜‚oÿw[LÿlF:ÿT3(ÿ3 ÿ ÿ ÿ ÿ ÿÿ ÿ  ÿ"C,ÿyΓÿmÄŠÿcº|ÿ[µtÿiÄ€ÿc¯mÿe¨lÿ£ë¦ÿoµ€ÿ3hDÿ%gDÿCºÿVýÈÿ=ò¾ÿ-ëºÿ$éºÿ1éÀÿHúÔÿVçÌÿ)|hÿ.‚eÿ]ÊŸÿZÊ—ÿ[Ò•ÿeàŸÿlç¡ÿŠô¸ÿªÿÒÿÎÿéÿ¨ÜÀÿ3cOÿ?s`ÿ¾éÐÿÐÿÜÿ­ÔÄÿŸÎµÿ=……ÿ;ƒ…ÿ,Ž—ÿ(†ÿptÿirÿXhÿWlÿ Owÿ[wÿelÿdpÿasÿZsÿQpÿJoÿ FkÿCeÿ @`ÿ Wzÿ%]€ÿ(@ÿÿÿÿ*ÿ )AÿXÿ@[ÿ 2Hä`ŽŸEÿÿÿÿÿÿ‚œ¦3XwŠ­EgwðAakÿEilÿIokÿJmhÿGl]ÿ[‚lÿa…kÿl‹rÿ¡¾œÿ˜¯ÿ`lTÿ!%ÿÿ+2'ÿïýôÿXTHÿ ÿzgÿøÊ¯ÿÀkÿeQÿUEÿ\:,ÿ*#ÿ!ÿ&-(ÿÿ ÿ ÿ ÿItNÿc¡lÿ`¤kÿc³pÿd³pÿc«kÿaªlÿh±rÿâ¡ÿiÒ•ÿ#tMÿkHÿ*¼Žÿ3ï¾ÿ9ïÖÿ:ÜÞÿ8ØÚÿ>âàÿ5ÆÀÿohÿ3œÿzÿôÿ‚öâÿŠÞÊÿ¡çØÿÄöíÿÚÿÿÿÞÿÿÿ¨ÈÌÿv•“ÿ3`Jÿ#L6ÿtœ‚ÿ¯˜ÿBXQÿ­ÐÈÿzÊÐÿd­·ÿA£¨ÿ4‹’ÿ-€ƒÿ'y}ÿ rzÿ!}‹ÿe|ÿesÿ&ttÿ%svÿelÿ[kÿVlÿ Olÿ Rwÿ HmÿMsÿBhÿCiÿCiÿ+Jÿ 1ÿ%CÿDlÿEmÿ :[ÿ1Oÿ 8WÿGgÿ7Rä9p†Tÿÿÿ·ÄÌ p˜}JlyÙAckÿEiiÿHolÿGlaÿDeXÿEdRÿD_Lÿ“±“ÿÚöÒÿ€sÿ*0"ÿ"ÿÿ†œÿÐÊ·ÿGC<ÿ0ÿvNAÿØ’}ÿý¸¡ÿ£r`ÿwcÿ†wgÿ60&ÿ081ÿ ÿ ÿ2G?ÿLyWÿ3`<ÿEQÿU˜cÿZ¤iÿc«oÿl³sÿo­rÿm¦mÿk¨wÿÆ•ÿvУÿ:Žmÿ_Hÿv\ÿ }pÿWZÿ HHÿ JGÿ IAÿ 6/ÿaUÿM·£ÿyçÌÿšúâÿ¯ÿòÿÊÿÿÿ£ÞÖÿtª¡ÿW…‚ÿQzÿsÀœÿ†Ú­ÿtˆÿMhXÿe}zÿ·ØÖÿŠØÜÿlµ¸ÿM­«ÿ9ÿ:Žÿ*zyÿ"ryÿ%‚Šÿo|ÿpyÿ(vrÿ#mmÿekÿdrÿeyÿ[tÿ Trÿ Orÿ Imÿ Chÿ@gÿ6Wÿ=aÿ#Jsÿ ?dÿ7[ÿ 3Wÿ 3Uÿ ;\ÿ Bcÿ =[ÿ3MöVm|¸ÒÚÿÿÿªµGX|Š˜;coÛ?eoûGopÿJrmÿQvlÿOlaÿQhXÿo€pÿ_hVÿ#(ÿ"ÿ*0)ÿ`miÿíåØÿýýýÿaC;ÿW4-ÿi;1ÿˆPDÿÈ}ÿýíÖÿrcWÿÿÿ ÿQ\[ÿÌúíÿ¯ýØÿ†é¨ÿhÀ†ÿaµzÿQ˜cÿW•cÿ¼€ÿ«ØŸÿ«¾•ÿ±¾šÿÆÎ«ÿÔâÄÿœ¯ÿ1@8ÿ!ÿ'(ÿ,3ÿ47ÿ65ÿ61ÿ:2ÿB6ÿTDÿ3teÿX¤“ÿ‹ÞÔÿvº·ÿ/`\ÿ.g`ÿG—’ÿO¦šÿFiÿMŽhÿz¦“ÿˆ­ÿµÒØÿ`ryÿÐÎÿy¼·ÿW­œÿ[±ÿQ¤˜ÿ>ƒÿ-}ÿ)†‚ÿ…ÿ €zÿ/|vÿ+wsÿ(ywÿpsÿipÿdtÿ _sÿ \|ÿ Uyÿ Gmÿ @gÿ BiÿCiÿ>aÿ8Xÿ 7Zÿ ;eÿ :_ÿ =`ÿ Aaÿ8Uÿ7QÿE]¦Š±¾+ÄÐÔ|˜£]OrÃcÿ @cÿ>]ÿ:Uÿ >Wÿ5LÜh’ŸH±ÂÊ8rŽœŽGkv¼CemæLkmÿZwsÿ€¡˜ÿˆ¤—ÿ\maÿ&)%ÿ ÿÿ·±¯ÿ·µµÿQ96ÿȦ¡ÿýÔÊÿýÜÎÿÞ±ÿ)ÿ ÿ ÿ-7-ÿýýøÿ—¼£ÿœ¾œÿ¼Šÿmÿ`…Xÿ]Š]ÿ]“gÿX’hÿM…_ÿCyWÿNˆdÿo¯‹ÿe£‚ÿ5hMÿI†hÿ†àµÿ†ç¼ÿyتÿlÆ—ÿo‹ÿyÈ‹ÿŽÞ•ÿ—å•ÿƒÖŠÿwÌ‚ÿiÈ…ÿcÌÿ6Š\ÿ'pLÿPªzÿ=ƒ\ÿ@yUÿ?tPÿ,sPÿ-vXÿ3ZZÿDmrÿªÒíÿ#3@ÿ‹Ð¾ÿ³ÿëÿpÆ—ÿc±ˆÿZ…ÿN“ÿ<†ÿ5—†ÿ’zÿpÿ5Šÿ9—ÿ(vÿ!zrÿ|rÿtrÿgkÿ [kÿ TlÿOpÿMrÿNsÿMrÿLlÿHhÿCgÿBiÿ Eiÿ Fiÿ Daÿ C_ÿJeÿ/DîPw†p¡µ¼5mŠ—rHep·@[`õFccÿWtpÿœÄ·ÿ¯ØÆÿRd]ÿ ÿ!ÿÌÊÆÿÈ·³ÿôÜÔÿýýýÿýòâÿ<-)ÿ ÿÿ$&ÿºÿ˜µŠÿhŠaÿhaÿ\“ZÿU“XÿLVÿCˆTÿ=†WÿC“cÿL£tÿG—mÿT£yÿGŠdÿ7lMÿ`£wÿŸí·ÿŽÔŸÿ}¼ŠÿoŠÿeÎŽÿlΆÿsЃÿwÎ|ÿlºiÿ`«`ÿe³gÿe·rÿlĆÿlÆŽÿV¤wÿp¸ÿP‹eÿBlJÿGwTÿ%sWÿ p\ÿ)[dÿ,Xiÿ€³Öÿ-@ÿt¾ªÿ¤ýàÿyÒšÿe·†ÿ\ŸƒÿN“}ÿ9Š‚ÿ2ƒÿ—ÿ€sÿ)ƒ€ÿ5—ÿ*Ž€ÿ%ˆyÿ!…rÿwlÿg`ÿ_hÿctÿiŠÿhÿ aˆÿW}ÿRvÿRtÿLoÿEiÿDdÿDcÿ@[ÿ C]ÿD]ÿ)<îBhyvÚÞâ š«µ?\z…¦Bcií>]_ÿDd`ÿsœ•ÿÌïâÿtˆ}ÿÿ''%ÿ}vrÿ€icÿe[VÿT<6ÿ ÿ#ÿ ÿgpNÿŸÂ†ÿRkBÿkVÿdWÿG—Pÿ?•Oÿ;•Tÿ6’Uÿ5š`ÿ;¤mÿA±|ÿD«|ÿ`ÒŸÿO¤wÿO˜oÿƒÖÿ‹Î’ÿ³|ÿ‹¼}ÿoÄ|ÿ[Ô‚ÿkà†ÿoÜ|ÿrÔpÿrÆeÿl¼cÿo¾eÿtÆsÿvÊ‚ÿzÌŽÿp¸…ÿÌœÿw¨|ÿRpIÿGiGÿlUÿh]ÿ!XoÿG`ÿP€¦ÿ2JÿvƱÿ¤ýçÿàœÿk¾…ÿa£…ÿP“|ÿ5‚}ÿ-ˆzÿ˜€ÿ…wÿ"ÿ2Ÿ˜ÿ+—†ÿ%wÿ#ˆmÿ|iÿoaÿklÿlwÿk†ÿh‹ÿ cˆÿ\‚ÿX|ÿVwÿVyÿQtÿJkÿFcÿC\ÿ E_ÿCXÿ'9ÿ?ew“ÎÖÚ%Ÿ³·ka‚…±:]]ß:\Xÿi†|ÿŸº¨ÿ€Š}ÿ[\WÿMB=ÿC61ÿVD@ÿaNEÿwmZÿ…kÿ&ÿCO1ÿ¡Æ‚ÿHa5ÿiŽOÿeŽNÿ_˜RÿXšRÿX¡\ÿR¤cÿOªoÿP±yÿR¼ˆÿUºŠÿkÚ¦ÿU¤yÿTšlÿŠÖ—ÿœà˜ÿšÌŠÿªÐŠÿŸÚ—ÿ’â¤ÿƒàŽÿvÎ|ÿsÎtÿtÐoÿvÌrÿÒ|ÿ…ÔˆÿÔ˜ÿœà«ÿ̨ÿw·ÿd¡}ÿJ‚]ÿ:wUÿo]ÿhcÿWsÿ@]ÿ%Joÿ1MÿwÒ¼ÿšúàÿtÖÿaµÿ\œ€ÿN|ÿ3€}ÿ+…|ÿœ†ÿ‹€ÿzzÿ(“ÿ)•†ÿ!†pÿ#Škÿ!ƒkÿ|kÿywÿr|ÿhƒÿdˆÿ dŠÿ eÿcŠÿ_‚ÿ_‚ÿ Z|ÿPoÿHcÿE\ÿ E\ÿ >Qÿ(9ôNwˆ„ÎØÚœµ·YX€€¨EaUøWp[ÿt€mÿ­³£ÿʾ±ÿµ£—ÿéØÈÿòÚÆÿÜÚ±ÿÀ¾˜ÿ‹˜lÿ;J(ÿr˜Qÿ‚­_ÿ€³Xÿw¦Rÿ…­[ÿz«[ÿw³gÿk³lÿc¸yÿ]¼‚ÿ]Ê“ÿgÔÿyï·ÿiÈÿ_­tÿʃÿ±íÿÐú¦ÿåý¤ÿàýºÿÒýÈÿ¯ô«ÿâÿ}àƒÿvà}ÿtÐzÿvÌ|ÿƒÈˆÿ˜ÈÿªÚºÿµàÎÿ€À¨ÿaª’ÿL¦‚ÿ-†gÿpdÿprÿZ€ÿGrÿ/Tÿ-NÿƒëÐÿúÚÿhÊ‚ÿVªoÿU’vÿIwÿ2|}ÿ)€}ÿ•…ÿ…ÿ|}ÿ"’‹ÿ)œˆÿ#Šoÿ)’mÿ%†hÿ"|dÿtpÿsyÿoŠÿl’ÿl•ÿ i“ÿiÿh‹ÿ`ƒÿXzÿQoÿIcÿE\ÿ EZÿ 9Lÿ,<ô\…˜ÐÜܦ¸³rgwÎG]XáZliür€zü€Š†ÿºÈÀÿýýúÿýýïÿÚçÊÿëøÔÿœ¯ˆÿ}•eÿ—¯|ÿœº}ÿ¤À€ÿœ¸lÿ“±hÿ•ºsÿ—ÄÿŽÄ…ÿˆÄˆÿÒšÿ—ؤÿ¦ëºÿ¼ôÆÿ˜Æœÿ•ºŽÿØòÂÿâôÆÿåí¼ÿíýÄÿçý¾ÿØýµÿÆöªÿ¼ö£ÿ­ïšÿŸÚÿÈ‚ÿ޼ÿ—¾ŠÿŸÈšÿºç¸ÿ±ëºÿˆÄ—ÿr¸…ÿU¦wÿ$ÿz…ÿXmÿ H`ÿ1Aÿ 2BÿgÎÀÿ…øéÿpÀœÿT˜}ÿO†vÿGŠzÿ1‚wÿ'ƒsÿ“zÿ"•†ÿz€ÿƒƒÿ+¨œÿŽ|ÿˆmÿ ‹rÿ!…lÿ €vÿvrÿsÿy‹ÿy—ÿs—ÿ e‹ÿcŠÿ aÿ [pÿRiÿGZÿ?Qÿ =Oÿ 9Mÿ6Iíd¤rØÞÜ'¦·¸Wgƒ•F]_ÇF]]ëXkhïg|wÿ‚ÿš­ÿÔâÈÿúýëÿâëÌÿÎØ·ÿàâÄÿÞéºÿÔçšÿÄÚ‹ÿ·ÎƒÿºÒŠÿµÎ‹ÿ­ÆŠÿ¨Ä‹ÿ£ºŠÿ­Ä˜ÿÚíÈÿ¼Ê«ÿ±¸¡ÿïòÞÿëëØÿååÐÿïôÈÿøÿ¸ÿôÿ·ÿïÿµÿíÿ·ÿâø±ÿÒï¦ÿÆâÿºàšÿ·àšÿ«Ö•ÿ«Ø•ÿ·ë£ÿ³é¡ÿ³å¡ÿ“Øÿ.¦¨ÿ}ÿt€ÿ‚ÿv|ÿ[`ÿ@ÿ[ÆÄÿp·¯ÿL…€ÿBtlÿA€tÿ0ˆsÿ(ˆpÿmÿ Šwÿ(}ˆÿ$‚‹ÿ*ª¨ÿ$¨šÿ’|ÿ†rÿ‚lÿƒsÿ€sÿ……ÿ…ŠÿyŠÿv•ÿm•ÿ c’ÿ azÿ Zeÿ Qaÿ O`ÿ I[ÿ ?Qÿ 0Dÿ5LÐ…«ÀNÞååÈÐÒ%¯±]l‚‚‹MdgµDWUÙWlh÷ewo÷lvÿw…zÿ—¦˜ÿºÊ¸ÿµÆ­ÿÊÜ«ÿâúÀÿçúÊÿâöÆÿÖò¾ÿÒëÀÿÌç¾ÿÌâ¾ÿÐâÂÿÜôÐÿÒçÄÿÐâÂÿëøÞÿíøÞÿïôÞÿöøÚÿÿÿÒÿýúÎÿöøÊÿôøÊÿíöÊÿëöÈÿâöÆÿÖí¾ÿÌç·ÿÂà¯ÿ³Ò¤ÿ¼â±ÿÒúÈÿÂå·ÿz¡}ÿH‚‚ÿP¡ÿmÐÎÿhÊÈÿd¸ÿa¼³ÿzĸÿt¸«ÿk˜‹ÿZŠ|ÿN†wÿCƒsÿ%gÿ €hÿŽlÿ“zÿ•ÿˆ…ÿ-£ÿ5¨ÿ(Šzÿ"ƒrÿ"ˆsÿ$’ÿ"Žÿ!‹Šÿ†Šÿ€ÿ‚—ÿvÿ d€ÿ ]oÿ U]ÿ JWÿ LZÿN]ÿBTÿ *<óCZ¤š¾Ð-Üàà·ÂÂDˆšœ}gyv—Od`¿O`ZÖVe`û_oeõP_TõT`Løm}cÿƒ“yÿœ±’ÿ¸Ô¯ÿÔïÌÿÎëÌÿºÔµÿØëÒÿåýÜÿºÔ³ÿµÎ«ÿâöÔÿïÿâÿøÿçÿúÿçÿÿÿçÿÿýåÿýýåÿýýâÿøýâÿöýàÿöýàÿïöÜÿçöÚÿÚïÐÿÎéÆÿÎëÈÿÒòÐÿ­Êªÿl…mÿ±¨ÿÈÄÿ•ÌÀÿ’ʾÿ¤ëÖÿ±øçÿ·ïØÿ±éÒÿªÔÂÿ˜Æ³ÿv¸¤ÿTœ†ÿ%ƒkÿw]ÿ tUÿ v]ÿ }rÿ†}ÿAÀµÿC­¤ÿ5†}ÿ*‚vÿ(Žzÿ%•ƒÿ Žÿ"ˆ†ÿ%ˆ‹ÿ…Žÿw‹ÿ k}ÿcwÿ `mÿ Xcÿ NZÿ JVÿJZÿ 9Iÿ )9ã5gq¾ÚåÞââ ±¼¸4’“oay|ˆGad¢Tgh¯WiiÞJ\\ù>PMÿ:MIÿJ`Zÿ\wmÿg…vÿt’…ÿw“ƒÿ€ŸŠÿЍ’ÿ“±—ÿ³Ð³ÿ³Î¯ÿÂÒºÿééÜÿíôåÿööçÿöúëÿöýëÿöÿëÿøÿíÿïúçÿåöÜÿåúÞÿâúÞÿØôÔÿÚôÔÿÔëÒÿ·Î±ÿÜíÌÿåòÒÿØçÂÿÖëÌÿåýÚÿÞúÐÿéÿàÿéÿàÿ¾çÀÿªØ³ÿ…Ò­ÿlÄÿAº“ÿ6·ÿ¯…ÿšwÿ iÿyeÿ&Šÿ?µ£ÿI«ÿ3}rÿ1wmÿ6Š€ÿ7’ˆÿ-ˆÿ%†ƒÿ||ÿzÿ|€ÿrwÿ Zaÿ OVÿNWÿR`ÿP`ÿ 1Aÿ3Fãc¦S¸ÄÌ!‹œ¤Z]r|ŠMckÈNdiÎNghâOkhìTrlÿTrgÿMh[ÿ[yiÿv—‚ÿiˆrÿ_ycÿdgÿs‚rÿƒ†}ÿ‹Ž…ÿ’—‹ÿ—’ÿ¡¦˜ÿ¨¯¡ÿ¯º¨ÿÈÖÂÿåøàÿïÿéÿôÿíÿíúéÿëýçÿÚïÖÿºÌ¯ÿíÞ³ÿøàµÿÌÆ˜ÿíé¸ÿØâ±ÿ¤±ƒÿŸ±Šÿ—¨€ÿ€Ÿzÿ}¡}ÿi±‹ÿ\¯†ÿ9­…ÿ7¸Žÿ(Ä•ÿ"·Žÿ·˜ÿ#·šÿŽvÿ(zÿUÀ±ÿmÒÄÿZ£œÿA‹…ÿ?Š…ÿ,…ÿ#zÿ}yÿzvÿsrÿiiÿagÿirÿ]hÿQ]ÿAOÿ 1?÷-_v§£ÄÒ'·ÆÊ1ˆŸ¦Me‚‹jMlp§Pss¾PrpßNmkôOoiïOogòNmcøIh\ÿOgXÿVhXÿVhXÿXk[ÿ\p_ÿcydÿlƒkÿr‹rÿv’tÿ|—yÿ‚ÿˆ¤ƒÿš¸—ÿ¨Ê¡ÿŸÀ˜ÿz˜tÿl†_ÿ|˜kÿr•gÿ}¡pÿg’aÿmœiÿy¨vÿ`_ÿe•lÿXˆ_ÿJ‹eÿJ•mÿ;Ÿvÿ:¨}ÿ,¨|ÿ*¡zÿ0¦†ÿ,ªŠÿ"«Šÿ$¨‹ÿ%ªŽÿD­Ÿÿ]«¨ÿsœ¡ÿ‚“œÿy—ÿ|˜ŸÿmŸÿH}ÿ6liÿ3toÿ4ˆŠÿ5—¡ÿ't€ÿT]ÿ=I÷>NtŸ³DÈÔÖ#¦¼¾OššsUtt’Qrm®WztºUvpÙQmaèQkWïNhT÷LdQÿIcOÿLdOÿNhPÿOkPÿOkPÿOkOÿOiOÿRmPÿ]}[ÿd…cÿo’kÿr—mÿ]ƒ[ÿFlEÿ=e?ÿU…XÿP…Vÿ\•dÿTˆ[ÿJzPÿO€XÿEwOÿA}Xÿ@…]ÿ0ƒ_ÿ0‹dÿ*—oÿ-—rÿ3•yÿ(—wÿ£€ÿ'¸˜ÿ.Ì­ÿ-Ž€ÿ3smÿƒ¤ªÿ««ºÿ†…Žÿ€‚Šÿ…œÿtŸœÿ_ŠÿGvÿ+llÿV]ÿLTÿU`÷%[l±Zˆ•@ºÊÌ6—¯³Sy—•ec†|„Z€tªUzoÁMseöGl]ðEi[ùDiXùChUÿAePÿ>`Mÿ@cNÿEhQÿEiQÿCdMÿAgNÿDƒhÿ@ƒhÿ3oUÿ$WAÿ%[@ÿ1lOÿ7pPÿ9sRÿE\ÿ:oNÿ;sRÿ=zXÿ1pRÿ0sUÿ8ˆeÿ3Žlÿ!’oÿ,—zÿ7ŽyÿHŸÿ\­£ÿ-yrÿ'}vÿ-ªšÿ.¾¯ÿ.Àªÿ)¸¡ÿ&¦ÿ&Ÿ†ÿ&š€ÿ%wÿ*zÿ)ksÿ%`iî0hsµv¡«SÌÚØ/šµ¯a}“–i‹€·W€r³W‚pÉRziÊLs`ãIs_ïIp\ïGoZ÷DmWÿ@iUÿ5s`ÿ7}iÿ6zeÿ0p\ÿ-iQÿ)dLÿ*`Fÿ3kOÿ5iNÿ7kOÿ:oRÿ;sUÿ5rTÿ3rTÿ5vWÿ1ƒcÿ ’oÿ-“yÿF“‚ÿT—‹ÿ_—’ÿ3wÿ+†ÿ£’ÿ­—ÿºÿ³•ÿƒÿ•yÿ˜|ÿš}ÿ1’ÿE‹—ÆW’š‘µÎÒEÌÚÔC£¾³e¯¦xp“Žˆ_…†¸_††ÄZ€ƒÛJz|áBwwá@tsñF€}ô;rkô>vlÿ8l\ö9k\ö3cQö7hUÿ3cOÿ4cPÿ6hTÿ4gRÿ9oXÿ@‚kÿ@’€ÿIŸŽÿPœÿE’†ÿD“‹ÿ1‹ƒÿ+†ÿ%†ÿ ‚ÿ#†}ÿ$€wÿ%|sÿ+vò7€ØCšŽÎa¨¨ºÚÞ@ÎÚà=¸ÎÖR—³¼\‚¡ªp•Ÿ–d‹°d‹»d‹»ZŠ…Éa—‹ÉZ…ÓN‚tàFyléI|oéGwhôGwhöGwhòGwhòCtr÷;wsû2vÿ-†ÿ(€|þ wpý&ttý,stï9stëGz}ÔV…ˆ¢i“•†œ¼¼ZÖçå3ÿÿÿÿÿÿÿÿÿÿÿÿºÔÒIÂÞØI¦ÎÊbœÄ¾T…·±i«³k«³«³„«³«³‚ª­¨R†Š×9zyß4|yÚCƒƒÒE}ÈR†Š¶d•˜‚ª­i±ÎÎ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÂÎÚ ÂÎÚÂÎÚÌÚÜ$¼ØÚ=ÆÈLšÈÆO¤ÄÄG·ÌÎ7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿðüþð?üÿÿÿÿÿÿÿ€ÿÿÿÿÿðÿðøðàÿÿÿÿÿ€ÿÿÿÿÿÀÿðààÀÿÿÿÿÿ€ÿÿÿÿÿ€àÀàÿÿÿÿÿ€ÿÿÿÿÿàà>ÿÿÿÿÿ€ÿÿÿÿþàþà<ÿÿÿÿÿ€ÿÿÿÿþ?àøð<ÿÿÿÿ€ÿÿÿÿü?ààð8ÿÿÿÿ€ÿÿÿÿøà€ð0ÿÿÿÿ€ÿÿÿÿøà?ðp?ÿÿÿÿ€ÿÿÿÿøðàÿðpÀ?ÿÿÿÿ€ÿÿÿÿðüðÿð`?ðÿÿÿÿ€ÿÿÿÿðÿðÿð`þÿÿÿÿ€ÿÿÿÿðÿÀðÿð`ÿÿÿÿÿÿ€ÿÿÿÿð?ÿððÿð@ÿÿÀÿÿÿÿ€ÿÿÿÿð?ÿøðÿð@ÿÿàÿÿÿÿ€ÿÿÿÿà?ÿþðÿð@ÿÿøÿÿÿÿ€ÿÿÿÿàÿÿðÿð@ÿÿüÿÿÿÿ€ÿÿÿÿàÿÿð`ð@ÿÿþÿÿÿÿ€ÿÿÿÿàÿÿðx?ð@ÿÿÿŸÿÿÿÿ€ÿÿÿÿàð~?ð@ÿÿÿÿÿÿÿÿ€ÿÿÿÿàð€ð@ÿÿÿÿÿÿÿÿ€ÿÿÿÿàð?Àð@ÿÿÿÿÿÿÿÿ€ÿÿÿÿàð?Àð@ÿÿÿÿÿÿÿÿ€ÿÿÿÿðð?àð@ÿÿÿÿÿÿÿÿ€ÿÿÿÿðððð@ÿÿÿÿÿÿÿÿ€ÿÿÿÿðððð@ÿÿÿÿÿÿÿÿ€ÿÿÿÿððøð`ÿÿÿÿÿÿÿ€ÿÿÿÿððøð`ÿÿÿÿÿÿÿ€ÿÿÿÿøðøð`?ÿÿÿÿÿÿÿ€ÿÿÿÿøþàøðpÿÿÿÿÿÿÿ€ÿÿÿÿüüàøðpÿƒÿÿÿÿÿ€ÿÿÿÿüøÀðàxþÿÿÿÿÿ€ÿÿÿÿþøÀ`àxøÿÿÿÿÿ€ÿÿÿÿþ@€À|Àÿÿÿÿÿ€ÿÿÿÿÿ€~ÿÿÿÿ€ÿÿÿÿÿ€~?ÿÿÿÿ€ÿÿÿÿÿ€<ÿÿÿÿ€ÿÿÿÿÿÀ8?€ÿÿÿÿ€ÿÿÿÿÿàx>?àÿÿÿÿ€ÿÿÿÿÿðð>?ðÿÿÿÿ€ÿÿÿÿÿüàÿþ?üÿÿÿÿ€ÿÿÿÿÿÿà øÿÿ€ÿÿÿÿÿ€ÿÿÿÿÿÿðÿÿãÿÀÿþÿÿøÿÿÿÿ€ÿÿÿÿÿÿÿ0ÿÿÿÿÿøÿøÿÿÿÀ?ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà?ÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿþ€wÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿ€7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿð?ÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿà?ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿà?ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿà?ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿü?ÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿ€?ÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿàÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿðÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿøÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿøÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿüÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿüÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿþÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿ€ÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÀ?ÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÀÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÀÿÿÿÿÿÿÿ€ÿÿÿÿÿÿàÿÿÿÿÿÿÿ€ÿÿÿÿÿÿàÿÿÿÿÿÿÿ€ÿÿÿÿÿÿðÿÿÿÿÿÿÿ€ÿÿÿÿÿÿðÿÿÿÿÿÿ€ÿÿÿÿÿÿø?ÿÿÿÿÿÿ€ÿÿÿÿÿÿøÿÿÿÿÿÿ€ÿÿÿÿÿÿüÿÿÿÿÿÿ€ÿÿÿÿÿÿüÿÿÿÿÿÿ€ÿÿÿÿÿÿþÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿ€ÿÿÿÿÿÿ€ÿÿÿÿÿÿÿ€ÿÿÿÿÿ€ÿÿÿÿÿÿÿÀ?ÿÿÿÿÿ€ÿÿÿÿÿÿÿà?ÿÿÿÿÿ€ÿÿÿÿÿÿÿàÿÿÿÿÿ€ÿÿÿÿÿÿÿðÿÿÿÿÿ€ÿÿÿÿÿÿÿøÿÿÿÿÿ€ÿÿÿÿÿÿÿüÿÿÿÿÿ€ÿÿÿÿÿÿÿþÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÀÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÀÿÿÿÿÿ€ÿÿÿÿÿÿÿÿàÿÿÿÿ€ÿÿÿÿÿÿÿÿðÿÿÿÿ€ÿÿÿÿÿÿÿÿøÿÿÿÿ€ÿÿÿÿÿÿÿÿü?ÿÿÿÿ€ÿÿÿÿÿÿÿÿþ?ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿ?ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÀÿÿÿÿ€ÿÿÿÿÿÿÿÿÿàÿÿÿÿ€ÿÿÿÿÿÿÿÿÿðÿÿÿÿ€ÿÿÿÿÿÿÿÿÿøÿÿÿÿ€ÿÿÿÿÿÿÿÿÿüÿÿÿÿ€ÿÿÿÿÿÿÿÿÿþÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿàÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿðÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿüÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿþÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø?ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€eric-6.0.8/eric/eric6_diff.pyw0000644000175000017500000000027612451233400015205 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_diff import main main() eric-6.0.8/eric/patch_modpython.py0000644000175000017500000001103312451233370016215 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003-2015 Detlev Offenbach # # This is a script to patch mod_python for eric6. """ Script to patch mod_python for usage with the eric6 IDE. """ from __future__ import unicode_literals import sys import os import shutil import py_compile import distutils.sysconfig # Define the globals. progName = None modDir = None def usage(rcode=2): """ Display a usage message and exit. @param rcode return code passed back to the calling process (integer) """ global progName, modDir print("Usage:") print(" {0} [-h] [-d dir]".format(progName)) print("where:") print(" -h display this help message") print(" -d dir where Mod_python files are installed" " [default {0}]".format(modDir)) print() print("This script patches the file apache.py of the Mod_python" " distribution") print("so that it will work with the eric6 debugger instead of pdb.") print("Please see mod_python.html for more details.") print() sys.exit(rcode) def initGlobals(): """ Module function to set the values of globals that need more than a simple assignment. """ global modDir modDir = os.path.join(distutils.sysconfig.get_python_lib(True), "mod_python") def main(argv): """ The main function of the script. @param argv list of command line arguments (list of strings) """ import getopt # Parse the command line. global progName, modDir progName = os.path.basename(argv[0]) initGlobals() try: optlist, args = getopt.getopt(argv[1:], "hd:") except getopt.GetoptError: usage() for opt, arg in optlist: if opt == "-h": usage(0) elif opt == "-d": global modDir modDir = arg try: filename = os.path.join(modDir, "apache.py") f = open(filename, "r", encoding="utf-8") except EnvironmentError: print("The file {0} does not exist. Aborting.".format(filename)) sys.exit(1) lines = f.readlines() f.close() pdbFound = False ericFound = False sn = "apache.py" s = open(sn, "w", encoding="utf-8") for line in lines: if not pdbFound and line.startswith("import pdb"): s.write("import eric6.DebugClients.Python.eric6dbgstub as pdb\n") pdbFound = True else: s.write(line) if line.startswith("import eric6"): ericFound = True if not ericFound: s.write("\n") s.write('def initDebugger(name):\n') s.write(' """\n') s.write(' Initialize the debugger and set the script name to be' ' reported \n') s.write(' by the debugger. This is a patch for eric6.\n') s.write(' """\n') s.write(' if not pdb.initDebugger("standard"):\n') s.write(' raise ImportError("Could not initialize debugger")\n') s.write(' pdb.setScriptname(name)\n') s.write("\n") s.close() if ericFound: print("Mod_python is already patched for eric6.") os.remove(sn) else: try: py_compile.compile(sn) except py_compile.PyCompileError as e: print("Error compiling {0}. Aborting".format(sn)) print(e) os.remove(sn) sys.exit(1) except SyntaxError as e: print("Error compiling {0}. Aborting".format(sn)) print(e) os.remove(sn) sys.exit(1) shutil.copy(os.path.join(modDir, "apache.py"), os.path.join(modDir, "apache.py.orig")) shutil.copy(sn, modDir) os.remove(sn) if os.path.exists("{0}c".format(sn)): shutil.copy("{0}c".format(sn), modDir) os.remove("{0}c".format(sn)) if os.path.exists("{0}o".format(sn)): shutil.copy("{0}o".format(sn), modDir) os.remove("{0}o".format(sn)) print("Mod_python patched successfully.") print("Unpatched file copied to {0}.".format( os.path.join(modDir, "apache.py.orig"))) if __name__ == "__main__": try: main(sys.argv) except SystemExit: raise except: print("""An internal error occured. Please report all the output of""" """ the program,\nincluding the following traceback, to""" """ eric-bugs@die-offenbachs.de.\n""") raise eric-6.0.8/eric/eric6_pluginrepository.py0000644000175000017500000000336412451233370017553 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Eric6 Plugin Installer. This is the main Python script to install eric6 plugins from outside of the IDE. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from PluginManager.PluginRepositoryDialog import PluginRepositoryWindow return PluginRepositoryWindow(None) def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ] appinfo = AppInfo.makeAppInfo(sys.argv, "Eric6 Plugin Repository", "", "Utility to show the contents of the eric6" " Plugin repository.", options) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/Plugins/0000755000175000017500000000000012557365360014102 5ustar piotrpiotreric-6.0.8/eric/Plugins/PluginCodeStyleChecker.py0000644000175000017500000003564112451233370021010 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the code style checker plug-in. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, pyqtSignal, QCoreApplication from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from Project.ProjectBrowserModel import ProjectBrowserFileItem from Utilities import determinePythonVersion import Preferences # Start-Of-Header name = "Code Style Checker Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "CodeStyleCheckerPlugin" packageName = "__core__" shortDescription = "Show the Python Code Style Checker dialog." longDescription = """This plugin implements the Python Code Style""" \ """ Checker dialog. A PEP-8 checker is used to check Python source""" \ """ files for compliance to the code style conventions given in PEP-8.""" \ """ A PEP-257 checker is used to check Python source files for""" \ """ compliance to docstring conventions given in PEP-257 and an""" \ """ eric6 variant is used to check against eric conventions.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class CodeStyleCheckerPlugin(QObject): """ Class implementing the code style checker plug-in. @signal styleChecked(str, dict, int, list) emited when the style check was done. """ styleChecked = pyqtSignal(str, dict, int, list) def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(CodeStyleCheckerPlugin, self).__init__(ui) self.__ui = ui self.__initialize() self.backgroundService = e5App().getObject("BackgroundService") path = os.path.join( os.path.dirname(__file__), 'CheckerPlugins', 'CodeStyleChecker') self.backgroundService.serviceConnect( 'style', 'Python2', path, 'CodeStyleChecker', self.__translateStyleCheck, onErrorCallback=self.serviceErrorPy2) self.backgroundService.serviceConnect( 'style', 'Python3', path, 'CodeStyleChecker', self.__translateStyleCheck, onErrorCallback=self.serviceErrorPy3) def __serviceError(self, fn, msg): """ Private slot handling service errors. @param fn file name (string) @param msg message text (string) """ self.styleChecked.emit( fn, {}, 0, [[1, 1, '---- ' + msg, False, False, False]]) def serviceErrorPy2(self, fx, lang, fn, msg): """ Public method handling service errors for Python 2. @param fx service name (string) @param lang language (string) @param fn file name (string) @param msg message text (string) """ if fx == 'style' and lang == 'Python2': self.__serviceError(fn, msg) def serviceErrorPy3(self, fx, lang, fn, msg): """ Public method handling service errors for Python 2. @param fx service name (string) @param lang language (string) @param fn file name (string) @param msg message text (string) """ if fx == 'style' and lang == 'Python3': self.__serviceError(fn, msg) def __initialize(self): """ Private slot to (re)initialize the plugin. """ self.__projectAct = None self.__projectCodeStyleCheckerDialog = None self.__projectBrowserAct = None self.__projectBrowserMenu = None self.__projectBrowserCodeStyleCheckerDialog = None self.__editors = [] self.__editorAct = None self.__editorCodeStyleCheckerDialog = None def styleCheck(self, lang, filename, source, args): """ Public method to prepare a style check on one Python source file. @param lang language of the file or None to determine by internal algorithm (str or None) @param filename source filename (string) @param source string containing the code to check (string) @param args arguments used by the codeStyleCheck function (list of excludeMessages (str), includeMessages (str), repeatMessages (bool), fixCodes (str), noFixCodes (str), fixIssues (bool), maxLineLength (int), hangClosing (bool), docType (str), errors (list of str), eol (str), encoding (str)) """ if lang is None: lang = 'Python{0}'.format(determinePythonVersion(filename, source)) if lang not in ['Python2', 'Python3']: return data = [source, args] self.backgroundService.enqueueRequest('style', lang, filename, data) def __translateStyleCheck(self, fn, codeStyleCheckerStats, results): """ Private slot called after perfoming a style check on one file. @param fn filename of the just checked file (str) @param codeStyleCheckerStats stats of style and name check (dict) @param results tuple for each found violation of style (tuple of lineno (int), position (int), text (str), fixed (bool), autofixing (bool), fixedMsg (str)) """ from CheckerPlugins.CodeStyleChecker.translations import \ getTranslatedMessage fixes = 0 for result in results: msg = getTranslatedMessage(result[2]) fixedMsg = result.pop() if fixedMsg: fixes += 1 trFixedMsg = getTranslatedMessage(fixedMsg) msg += "\n" + QCoreApplication.translate( 'CodeStyleCheckerDialog', "Fix: {0}").format(trFixedMsg) result[2] = msg self.styleChecked.emit(fn, codeStyleCheckerStats, fixes, results) def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ menu = e5App().getObject("Project").getMenu("Checks") if menu: self.__projectAct = E5Action( self.tr('Check Code Style'), self.tr('&Code Style...'), 0, 0, self, 'project_check_pep8') self.__projectAct.setStatusTip( self.tr('Check code style.')) self.__projectAct.setWhatsThis(self.tr( """Check Code Style...""" """

This checks Python files for compliance to the""" """ code style conventions given in various PEPs.

""" )) self.__projectAct.triggered.connect( self.__projectCodeStyleCheck) e5App().getObject("Project").addE5Actions([self.__projectAct]) menu.addAction(self.__projectAct) self.__editorAct = E5Action( self.tr('Check Code Style'), self.tr('&Code Style...'), 0, 0, self, "") self.__editorAct.setWhatsThis(self.tr( """Check Code Style...""" """

This checks Python files for compliance to the""" """ code style conventions given in various PEPs.

""" )) self.__editorAct.triggered.connect(self.__editorCodeStyleCheck) e5App().getObject("Project").showMenu.connect(self.__projectShowMenu) e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\ .showMenu.connect(self.__projectBrowserShowMenu) e5App().getObject("ViewManager").editorOpenedEd.connect( self.__editorOpened) e5App().getObject("ViewManager").editorClosedEd.connect( self.__editorClosed) for editor in e5App().getObject("ViewManager").getOpenEditors(): self.__editorOpened(editor) return None, True def deactivate(self): """ Public method to deactivate this plugin. """ e5App().getObject("Project").showMenu.disconnect( self.__projectShowMenu) e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\ .showMenu.disconnect(self.__projectBrowserShowMenu) e5App().getObject("ViewManager").editorOpenedEd.disconnect( self.__editorOpened) e5App().getObject("ViewManager").editorClosedEd.disconnect( self.__editorClosed) menu = e5App().getObject("Project").getMenu("Checks") if menu: menu.removeAction(self.__projectAct) if self.__projectBrowserMenu: if self.__projectBrowserAct: self.__projectBrowserMenu.removeAction( self.__projectBrowserAct) for editor in self.__editors: editor.showMenu.disconnect(self.__editorShowMenu) menu = editor.getMenu("Checks") if menu is not None: menu.removeAction(self.__editorAct) self.__initialize() def __projectShowMenu(self, menuName, menu): """ Private slot called, when the the project menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) """ if menuName == "Checks" and self.__projectAct is not None: self.__projectAct.setEnabled( e5App().getObject("Project").getProjectLanguage() in ["Python3", "Python2", "Python"]) def __projectBrowserShowMenu(self, menuName, menu): """ Private slot called, when the the project browser menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) """ if menuName == "Checks" and \ e5App().getObject("Project").getProjectLanguage() in \ ["Python3", "Python2", "Python"]: self.__projectBrowserMenu = menu if self.__projectBrowserAct is None: self.__projectBrowserAct = E5Action( self.tr('Check Code Style'), self.tr('&Code Style...'), 0, 0, self, "") self.__projectBrowserAct.setWhatsThis(self.tr( """Check Code Style...""" """

This checks Python files for compliance to the""" """ code style conventions given in various PEPs.

""" )) self.__projectBrowserAct.triggered.connect( self.__projectBrowserCodeStyleCheck) if self.__projectBrowserAct not in menu.actions(): menu.addAction(self.__projectBrowserAct) def __projectCodeStyleCheck(self): """ Private slot used to check the project files for code style. """ project = e5App().getObject("Project") project.saveAllScripts() ppath = project.getProjectPath() files = [os.path.join(ppath, file) for file in project.pdata["SOURCES"] if file.endswith( tuple(Preferences.getPython("Python3Extensions")) + tuple(Preferences.getPython("PythonExtensions")))] from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog import \ CodeStyleCheckerDialog self.__projectCodeStyleCheckerDialog = CodeStyleCheckerDialog(self) self.__projectCodeStyleCheckerDialog.show() self.__projectCodeStyleCheckerDialog.prepare(files, project) def __projectBrowserCodeStyleCheck(self): """ Private method to handle the code style check context menu action of the project sources browser. """ browser = e5App().getObject("ProjectBrowser")\ .getProjectBrowser("sources") if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1: fn = [] for itm in browser.getSelectedItems([ProjectBrowserFileItem]): fn.append(itm.fileName()) isDir = False else: itm = browser.model().item(browser.currentIndex()) try: fn = itm.fileName() isDir = False except AttributeError: fn = itm.dirName() isDir = True from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog import \ CodeStyleCheckerDialog self.__projectBrowserCodeStyleCheckerDialog = CodeStyleCheckerDialog( self) self.__projectBrowserCodeStyleCheckerDialog.show() if isDir: self.__projectBrowserCodeStyleCheckerDialog.start( fn, save=True) else: self.__projectBrowserCodeStyleCheckerDialog.start( fn, save=True, repeat=True) def __editorOpened(self, editor): """ Private slot called, when a new editor was opened. @param editor reference to the new editor (QScintilla.Editor) """ menu = editor.getMenu("Checks") if menu is not None: menu.addAction(self.__editorAct) editor.showMenu.connect(self.__editorShowMenu) self.__editors.append(editor) def __editorClosed(self, editor): """ Private slot called, when an editor was closed. @param editor reference to the editor (QScintilla.Editor) """ try: self.__editors.remove(editor) except ValueError: pass def __editorShowMenu(self, menuName, menu, editor): """ Private slot called, when the the editor context menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) @param editor reference to the editor """ if menuName == "Checks": if self.__editorAct not in menu.actions(): menu.addAction(self.__editorAct) self.__editorAct.setEnabled(editor.isPyFile()) def __editorCodeStyleCheck(self): """ Private slot to handle the code style check context menu action of the editors. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is not None: if editor.checkDirty() and editor.getFileName() is not None: from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog \ import CodeStyleCheckerDialog self.__editorCodeStyleCheckerDialog = CodeStyleCheckerDialog( self) self.__editorCodeStyleCheckerDialog.show() self.__editorCodeStyleCheckerDialog.start( editor.getFileName(), save=True, repeat=True) eric-6.0.8/eric/Plugins/PluginWizardQMessageBox.py0000644000175000017500000001007612451233370021162 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the QMessageBox wizard plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "QMessageBox Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "MessageBoxWizard" packageName = "__core__" shortDescription = "Show the QMessageBox wizard." longDescription = """This plugin shows the QMessageBox wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class MessageBoxWizard(QObject): """ Class implementing the QMessageBox wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(MessageBoxWizard, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('QMessageBox Wizard'), self.tr('Q&MessageBox Wizard...'), 0, 0, self, 'wizards_qmessagebox') self.action.setStatusTip(self.tr('QMessageBox Wizard')) self.action.setWhatsThis(self.tr( """QMessageBox Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create a QMessageBox. The generated code is""" """ inserted at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) """ from WizardPlugins.MessageBoxWizard.MessageBoxWizardDialog import \ MessageBoxWizardDialog dlg = MessageBoxWizardDialog(None) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), True) else: return (None, False) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/PluginWizardE5MessageBox.py0000644000175000017500000001015012451233370021224 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the E5MessageBox wizard plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "E5MessageBox Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "E5MessageBoxWizard" packageName = "__core__" shortDescription = "Show the E5MessageBox wizard." longDescription = """This plugin shows the E5MessageBox wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class E5MessageBoxWizard(QObject): """ Class implementing the E5MessageBox wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(E5MessageBoxWizard, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('E5MessageBox Wizard'), self.tr('&E5MessageBox Wizard...'), 0, 0, self, 'wizards_e5messagebox') self.action.setStatusTip(self.tr('E5MessageBox Wizard')) self.action.setWhatsThis(self.tr( """E5MessageBox Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create an E5MessageBox. The generated code is""" """ inserted at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) """ from WizardPlugins.E5MessageBoxWizard.E5MessageBoxWizardDialog import \ E5MessageBoxWizardDialog dlg = E5MessageBoxWizardDialog(None) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), True) else: return (None, False) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/CheckerPlugins/0000755000175000017500000000000012557365360017010 5ustar piotrpiotreric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/0000755000175000017500000000000012557365404021562 5ustar piotrpiotreric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py0000644000175000017500000001100012451233370025656 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # # pylint: disable=C0103 """ Module implementing an interface to add different languages to do a syntax check. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject, pyqtSignal from E5Gui.E5Application import e5App from Utilities import determinePythonVersion class SyntaxCheckService(QObject): """ Implement the syntax check service. Plugins can add other languages to the syntax check by calling addLanguage and support of an extra checker module on the client side which has to connect directly to the background service. @signal syntaxChecked(str, dict) emited when the syntax check was done. """ syntaxChecked = pyqtSignal(str, dict) def __init__(self): """ Constructor """ super(SyntaxCheckService, self).__init__() self.backgroundService = e5App().getObject("BackgroundService") self.__supportedLanguages = {} def __determineLanguage(self, filename, source): """ Private methode to determine the language of the file. @param filename of the sourcefile (str) @param source code of the file (str) @return language of the file or None if not found (str or None) """ pyVer = determinePythonVersion(filename, source) if pyVer: return 'Python{0}'.format(pyVer) for lang, (env, getArgs, getExt) in self.__supportedLanguages.items(): if filename.endswith(tuple(getExt())): return lang return None def addLanguage( self, lang, env, path, module, getArgs, getExt, callback, onError): """ Public method to register a new language to the supported languages. @param lang new language to check syntax (str) @param env the environment in which the checker is implemented (str) @param path full path to the module (str) @param module name to import (str) @param getArgs function to collect the required arguments to call the syntax checker on client side (function) @param getExt function that returns the supported file extensions of the syntax checker (function) @param callback function on service response (function) @param onError callback function if client or service isn't available (function) """ self.__supportedLanguages[lang] = env, getArgs, getExt # Connect to the background service self.backgroundService.serviceConnect( '{0}Syntax'.format(lang), env, path, module, callback, onError) def getLanguages(self): """ Public method to return the supported language names. @return list of languanges supported (list of str) """ return list(self.__supportedLanguages.keys()) def removeLanguage(self, lang): """ Public method to remove the language from syntax check. @param lang language to remove (str) """ self.__supportedLanguages.pop(lang, None) self.backgroundService.serviceDisconnect( '{0}Syntax'.format(lang), lang) def getExtensions(self): """ Public method to return all supported file extensions for the syntax checker dialog. @return set of all supported file extensions (set of str) """ extensions = set() for env, getArgs, getExt in self.__supportedLanguages.values(): for ext in getExt(): extensions.add(ext) return extensions def syntaxCheck(self, lang, filename, source): """ Public method to prepare to compile one Python source file to Python bytecode and to perform a pyflakes check. @param lang language of the file or None to determine by internal algorithm (str or None) @param filename source filename (string) @param source string containing the code to check (string) """ if not lang: lang = self.__determineLanguage(filename, source) if lang not in self.getLanguages(): return data = [source] # Call the getArgs function to get the required arguments env, args, getExt = self.__supportedLanguages[lang] data.extend(args()) self.backgroundService.enqueueRequest( '{0}Syntax'.format(lang), env, filename, data) eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/jsCheckSyntax.py0000644000175000017500000000432512451233370024706 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # # pylint: disable=C0103 """ Module implementing the syntax check for Python 2/3. """ import os import sys def initService(): """ Initialize the service and return the entry point. @return the entry point for the background client (function) """ path = __file__ for i in range(4): path = os.path.dirname(path) sys.path.insert(2, os.path.join(path, "ThirdParty", "Jasy")) return jsCheckSyntax def normalizeCode(codestring): """ Function to normalize the given code. @param codestring code to be normalized (string) @return normalized code (string) """ codestring = codestring.replace("\r\n", "\n").replace("\r", "\n") if codestring and codestring[-1] != '\n': codestring = codestring + '\n' # Check type for py2: if not str it's unicode # if sys.version_info[0] == 2: # try: # codestring = codestring.encode('utf-8') # except UnicodeError: # pass return codestring def jsCheckSyntax(file, codestring): """ Function to check a Javascript source file for syntax errors. @param file source filename (string) @param codestring string containing the code to check (string) @return dictionary with the keys 'error' and 'warnings' which hold a list containing details about the error/ warnings (file name, line number, column, codestring (only at syntax errors), the message, a list with arguments for the message) """ import jasy.js.parse.Parser as jsParser import jasy.js.tokenize.Tokenizer as jsTokenizer codestring = normalizeCode(codestring) try: jsParser.parse(codestring, file) except (jsParser.SyntaxError, jsTokenizer.ParseError) as exc: details = exc.args[0] error, details = details.splitlines() fn, line = details.strip().rsplit(":", 1) error = error.split(":", 1)[1].strip() cline = min(len(codestring.splitlines()), int(line)) - 1 code = codestring.splitlines()[cline] return [{'error': (fn, int(line), 0, code, error)}] return [{}] eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/__init__.py0000644000175000017500000000023212451233370023655 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the Syntax Checker plugin. """ eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py0000644000175000017500000001533312552224202024346 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # # pylint: disable=C0103 """ Module implementing the syntax check for Python 2/3. """ import ast import re import sys import traceback try: from pyflakes.checker import Checker from pyflakes.messages import ImportStarUsed except ImportError: Checker = None VcsConflictMarkerRe = re.compile( r"""^<<<<<<< .*?=======.*?>>>>>>> .*?$""", re.MULTILINE | re.DOTALL) def initService(): """ Initialize the service and return the entry point. @return the entry point for the background client (function) """ return syntaxAndPyflakesCheck def normalizeCode(codestring): """ Function to normalize the given code. @param codestring code to be normalized (string) @return normalized code (string) """ codestring = codestring.replace("\r\n", "\n").replace("\r", "\n") if codestring and codestring[-1] != '\n': codestring = codestring + '\n' # Check type for py2: if not str it's unicode if sys.version_info[0] == 2: try: codestring = codestring.encode('utf-8') except UnicodeError: pass return codestring def extractLineFlags(line, startComment="#", endComment=""): """ Function to extract flags starting and ending with '__' from a line comment. @param line line to extract flags from (string) @keyparam startComment string identifying the start of the comment (string) @keyparam endComment string identifying the end of a comment (string) @return list containing the extracted flags (list of strings) """ flags = [] pos = line.rfind(startComment) if pos >= 0: comment = line[pos + len(startComment):].strip() if endComment: comment = comment.replace("endComment", "") flags = [f.strip() for f in comment.split() if (f.startswith("__") and f.endswith("__"))] return flags def syntaxAndPyflakesCheck(filename, codestring, checkFlakes=True, ignoreStarImportWarnings=False): """ Function to compile one Python source file to Python bytecode and to perform a pyflakes check. @param filename source filename (string) @param codestring string containing the code to compile (string) @keyparam checkFlakes flag indicating to do a pyflakes check (boolean) @keyparam ignoreStarImportWarnings flag indicating to ignore 'star import' warnings (boolean) @return dictionary with the keys 'error' and 'warnings' which hold a list containing details about the error/ warnings (file name, line number, column, codestring (only at syntax errors), the message, a list with arguments for the message) """ try: import builtins except ImportError: import __builtin__ as builtins # __IGNORE_WARNING__ try: if sys.version_info[0] == 2: file_enc = filename.encode(sys.getfilesystemencoding()) else: file_enc = filename # It also encode the code back to avoid 'Encoding declaration in # unicode string' exception on Python2 codestring = normalizeCode(codestring) # Check for VCS conflict markers conflict = VcsConflictMarkerRe.search(codestring) if conflict is not None: start, i = conflict.span() lineindex = 1 + codestring.count("\n", 0, start) return [{'error': (file_enc, lineindex, 0, "", "VCS conflict marker found") }] if filename.endswith('.ptl'): try: import quixote.ptl_compile except ImportError: return [{'error': (filename, 0, 0, '', 'Quixote plugin not found.')}] template = quixote.ptl_compile.Template(codestring, file_enc) template.compile() else: module = builtins.compile( codestring, file_enc, 'exec', ast.PyCF_ONLY_AST) except SyntaxError as detail: index = 0 code = "" error = "" lines = traceback.format_exception_only(SyntaxError, detail) if sys.version_info[0] == 2: lines = [x.decode(sys.getfilesystemencoding()) for x in lines] match = re.match('\s*File "(.+)", line (\d+)', lines[0].replace('', '{0}'.format(filename))) if match is not None: fn, line = match.group(1, 2) if lines[1].startswith('SyntaxError:'): error = re.match('SyntaxError: (.+)', lines[1]).group(1) else: code = re.match('(.+)', lines[1]).group(1) for seLine in lines[2:]: if seLine.startswith('SyntaxError:'): error = re.match('SyntaxError: (.+)', seLine).group(1) elif seLine.rstrip().endswith('^'): index = len(seLine.rstrip()) - 4 else: fn = detail.filename line = detail.lineno or 1 error = detail.msg return [{'error': (fn, int(line), index, code.strip(), error)}] except ValueError as detail: try: fn = detail.filename line = detail.lineno error = detail.msg except AttributeError: fn = filename line = 1 error = str(detail) return [{'error': (fn, line, 0, "", error)}] except Exception as detail: try: fn = detail.filename line = detail.lineno error = detail.msg return [{'error': (fn, line, 0, "", error)}] except: # this catchall is intentional pass # pyflakes if not checkFlakes or Checker is None: return [{}] results = [] lines = codestring.splitlines() try: warnings = Checker(module, filename, withDoctest=True) warnings.messages.sort(key=lambda a: a.lineno) for warning in warnings.messages: if ignoreStarImportWarnings and \ isinstance(warning, ImportStarUsed): continue _fn, lineno, col, message, msg_args = warning.getMessageData() if "__IGNORE_WARNING__" not in extractLineFlags( lines[lineno - 1].strip()): results.append((_fn, lineno, col, "", message, msg_args)) except SyntaxError as err: if err.text.strip(): msg = err.text.strip() else: msg = err.msg results.append((filename, err.lineno, 0, "FLAKES_ERROR", msg, [])) return [{'warnings': results}] eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/0000755000175000017500000000000012557365360023401 5ustar piotrpiotreric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/__init__.py0000644000175000017500000001515112451233370025501 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Package containg pyflakes adapted for Qt. """ """ License Copyright 2005-2011 Divmod, Inc. Copyright 2013-2014 Florent Xicluna Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ """ Changes 0.8.1 (2014-03-30): - Detect the declared encoding in Python 3. - Do not report redefinition of import in a local scope, if the global name is used elsewhere in the module. - Catch undefined variable in loop generator when it is also used as loop variable. - Report undefined name for `(a, b) = (1, 2)` but not for the general unpacking `(a, b) = func()`. - Correctly detect when an imported module is used in default arguments of a method, when the method and the module use the same name. - Distribute a universal wheel file. 0.8.0 (2014-03-22): - Adapt for the AST in Python 3.4. - Fix caret position on SyntaxError. - Fix crash on Python 2.x with some doctest SyntaxError. - Add tox.ini. - The `PYFLAKES_NODOCTEST` environment variable has been replaced with the `PYFLAKES_DOCTEST` environment variable (with the opposite meaning). Doctest checking is now disabled by default; set the environment variable to enable it. - Correctly parse incremental `__all__ += [...]`. - Catch return with arguments inside a generator (Python <= 3.2). - Do not complain about `_` in doctests. - Drop deprecated methods `pushFunctionScope` and `pushClassScope`. 0.7.3 (2013-07-02): - Do not report undefined name for generator expression and dict or set comprehension at class level. - Deprecate `Checker.pushFunctionScope` and `Checker.pushClassScope`: use `Checker.pushScope` instead. - Remove dependency on Unittest2 for the tests. 0.7.2 (2013-04-24): - Fix computation of `DoctestSyntaxError.lineno` and `col`. - Add boolean attribute `Checker.withDoctest` to ignore doctests. - If environment variable `PYFLAKES_NODOCTEST` is set, skip doctests. - Environment variable `PYFLAKES_BUILTINS` accepts a comma-separated list of additional built-in names. 0.7.1 (2013-04-23): - File `bin/pyflakes` was missing in tarball generated with distribute. - Fix reporting errors in non-ASCII filenames (Python 2.x). 0.7.0 (2013-04-17): - Add --version and --help options. - Support `python -m pyflakes` (Python 2.7 and Python 3.x). - Add attribute `Message.col` to report column offset. - Do not report redefinition of variable for a variable used in a list comprehension in a conditional. - Do not report redefinition of variable for generator expressions and set or dict comprehensions. - Do not report undefined name when the code is protected with a `NameError` exception handler. - Do not report redefinition of variable when unassigning a module imported for its side-effect. - Support special locals like `__tracebackhide__` for py.test. - Support checking doctests. - Fix issue with Turkish locale where `'i'.upper() == 'i'` in Python 2. 0.6.1 (2013-01-29): - Fix detection of variables in augmented assignments. 0.6.0 (2013-01-29): - Support Python 3 up to 3.3, based on the pyflakes3k project. - Preserve compatibility with Python 2.5 and all recent versions of Python. - Support custom reporters in addition to the default Reporter. - Allow function redefinition for modern property construction via property.setter/deleter. - Fix spurious redefinition warnings in conditionals. - Do not report undefined name in __all__ if import * is used. - Add WindowsError as a known built-in name on all platforms. - Support specifying additional built-ins in the `Checker` constructor. - Don't issue Unused Variable warning when using locals() in current scope. - Handle problems with the encoding of source files. - Remove dependency on Twisted for the tests. - Support `python setup.py test` and `python setup.py develop`. - Create script using setuptools `entry_points` to support all platforms, including Windows. 0.5.0 (2011-09-02): - Convert pyflakes to use newer _ast infrastructure rather than compiler. - Support for new syntax in 2.7 (including set literals, set comprehensions, and dictionary comprehensions). - Make sure class names don't get bound until after class definition. 0.4.0 (2009-11-25): - Fix reporting for certain SyntaxErrors which lack line number information. - Check for syntax errors more rigorously. - Support checking names used with the class decorator syntax in versions of Python which have it. - Detect local variables which are bound but never used. - Handle permission errors when trying to read source files. - Handle problems with the encoding of source files. - Support importing dotted names so as not to incorrectly report them as redefined unused names. - Support all forms of the with statement. - Consider static `__all__` definitions and avoid reporting unused names if the names are listed there. - Fix incorrect checking of class names with respect to the names of their bases in the class statement. - Support the `__path__` global in `__init__.py`. 0.3.0 (2009-01-30): - Display more informative SyntaxError messages. - Don't hang flymake with unmatched triple quotes (only report a single line of source for a multiline syntax error). - Recognize __builtins__ as a defined name. - Improve pyflakes support for python versions 2.3-2.5 - Support for if-else expressions and with statements. - Warn instead of error on non-existant file paths. - Check for __future__ imports after other statements. - Add reporting for some types of import shadowing. - Improve reporting of unbound locals """ __version__ = '0.8.1' eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py0000644000175000017500000007601612451233370025355 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # # Original (c) 2005-2010 Divmod, Inc. # # This module is based on pyflakes but was modified to work with eric6 """ Main module. Implement the central Checker class. Also, it models the Bindings and Scopes. """ import doctest import os import sys PY2 = sys.version_info < (3, 0) PY32 = sys.version_info < (3, 3) # Python 2.5 to 3.2 PY33 = sys.version_info < (3, 4) # Python 2.5 to 3.3 builtin_vars = dir(__import__('__builtin__' if PY2 else 'builtins')) try: import ast except ImportError: # Python 2.5 import _ast as ast if 'decorator_list' not in ast.ClassDef._fields: # Patch the missing attribute 'decorator_list' ast.ClassDef.decorator_list = () ast.FunctionDef.decorator_list = property(lambda s: s.decorators) from . import messages if PY2: def getNodeType(node_class): # workaround str.upper() which is locale-dependent return str(unicode(node_class.__name__).upper()) # __IGNORE_WARNING__ else: def getNodeType(node_class): return node_class.__name__.upper() # Python >= 3.3 uses ast.Try instead of (ast.TryExcept + ast.TryFinally) if PY32: def getAlternatives(n): if isinstance(n, (ast.If, ast.TryFinally)): return [n.body] if isinstance(n, ast.TryExcept): return [n.body + n.orelse] + [[hdl] for hdl in n.handlers] else: def getAlternatives(n): if isinstance(n, ast.If): return [n.body] if isinstance(n, ast.Try): return [n.body + n.orelse] + [[hdl] for hdl in n.handlers] class _FieldsOrder(dict): """Fix order of AST node fields.""" def _get_fields(self, node_class): # handle iter before target, and generators before element fields = node_class._fields if 'iter' in fields: key_first = 'iter'.find elif 'generators' in fields: key_first = 'generators'.find else: key_first = 'value'.find return tuple(sorted(fields, key=key_first, reverse=True)) def __missing__(self, node_class): self[node_class] = fields = self._get_fields(node_class) return fields def iter_child_nodes(node, omit=None, _fields_order=_FieldsOrder()): """ Yield all direct child nodes of *node*, that is, all fields that are nodes and all items of fields that are lists of nodes. """ for name in _fields_order[node.__class__]: if name == omit: continue field = getattr(node, name, None) if isinstance(field, ast.AST): yield field elif isinstance(field, list): for item in field: yield item class Binding(object): """ Represents the binding of a value to a name. The checker uses this to keep track of which names have been bound and which names have not. See L{Assignment} for a special type of binding that is checked with stricter rules. @ivar used: pair of (L{Scope}, line-number) indicating the scope and line number that this binding was last used """ def __init__(self, name, source): self.name = name self.source = source self.used = False def __str__(self): return self.name def __repr__(self): return '<%s object %r from line %r at 0x%x>' % (self.__class__.__name__, self.name, self.source.lineno, id(self)) def redefines(self, other): return isinstance(other, Definition) and self.name == other.name class Definition(Binding): """ A binding that defines a function or a class. """ class Importation(Definition): """ A binding created by an import statement. @ivar fullName: The complete name given to the import statement, possibly including multiple dotted components. @type fullName: C{str} """ def __init__(self, name, source): self.fullName = name self.redefined = [] name = name.split('.')[0] super(Importation, self).__init__(name, source) def redefines(self, other): if isinstance(other, Importation): return self.fullName == other.fullName return isinstance(other, Definition) and self.name == other.name class Argument(Binding): """ Represents binding a name as an argument. """ class Assignment(Binding): """ Represents binding a name with an explicit assignment. The checker will raise warnings for any Assignment that isn't used. Also, the checker does not consider assignments in tuple/list unpacking to be Assignments, rather it treats them as simple Bindings. """ class FunctionDefinition(Definition): pass class ClassDefinition(Definition): pass class ExportBinding(Binding): """ A binding created by an C{__all__} assignment. If the names in the list can be determined statically, they will be treated as names for export and additional checking applied to them. The only C{__all__} assignment that can be recognized is one which takes the value of a literal list containing literal strings. For example:: __all__ = ["foo", "bar"] Names which are imported and not otherwise used but appear in the value of C{__all__} will not have an unused import warning reported for them. """ def __init__(self, name, source, scope): if '__all__' in scope and isinstance(source, ast.AugAssign): self.names = list(scope['__all__'].names) else: self.names = [] if isinstance(source.value, (ast.List, ast.Tuple)): for node in source.value.elts: if isinstance(node, ast.Str): self.names.append(node.s) super(ExportBinding, self).__init__(name, source) class Scope(dict): importStarred = False # set to True when import * is found def __repr__(self): scope_cls = self.__class__.__name__ return '<%s at 0x%x %s>' % (scope_cls, id(self), dict.__repr__(self)) class ClassScope(Scope): pass class FunctionScope(Scope): """ I represent a name scope for a function. @ivar globals: Names declared 'global' in this function. """ usesLocals = False alwaysUsed = set(['__tracebackhide__', '__traceback_info__', '__traceback_supplement__']) def __init__(self): super(FunctionScope, self).__init__() # Simplify: manage the special locals as globals self.globals = self.alwaysUsed.copy() self.returnValue = None # First non-empty return self.isGenerator = False # Detect a generator def unusedAssignments(self): """ Return a generator for the assignments which have not been used. """ for name, binding in self.items(): if (not binding.used and name not in self.globals and not self.usesLocals and isinstance(binding, Assignment)): yield name, binding class GeneratorScope(Scope): pass class ModuleScope(Scope): pass # Globally defined names which are not attributes of the builtins module, or # are only present on some platforms. _MAGIC_GLOBALS = ['__file__', '__builtins__', 'WindowsError'] def getNodeName(node): # Returns node.id, or node.name, or None if hasattr(node, 'id'): # One of the many nodes with an id return node.id if hasattr(node, 'name'): # a ExceptHandler node return node.name class Checker(object): """ I check the cleanliness and sanity of Python code. @ivar _deferredFunctions: Tracking list used by L{deferFunction}. Elements of the list are two-tuples. The first element is the callable passed to L{deferFunction}. The second element is a copy of the scope stack at the time L{deferFunction} was called. @ivar _deferredAssignments: Similar to C{_deferredFunctions}, but for callables which are deferred assignment checks. """ nodeDepth = 0 offset = None traceTree = False builtIns = set(builtin_vars).union(_MAGIC_GLOBALS) _customBuiltIns = os.environ.get('PYFLAKES_BUILTINS') if _customBuiltIns: builtIns.update(_customBuiltIns.split(',')) del _customBuiltIns def __init__(self, tree, filename='(none)', builtins=None, withDoctest='PYFLAKES_DOCTEST' in os.environ): self._nodeHandlers = {} self._deferredFunctions = [] self._deferredAssignments = [] self.deadScopes = [] self.messages = [] self.filename = filename if builtins: self.builtIns = self.builtIns.union(builtins) self.withDoctest = withDoctest self.scopeStack = [ModuleScope()] self.exceptHandlers = [()] self.futuresAllowed = True self.root = tree self.handleChildren(tree) self.runDeferred(self._deferredFunctions) # Set _deferredFunctions to None so that deferFunction will fail # noisily if called after we've run through the deferred functions. self._deferredFunctions = None self.runDeferred(self._deferredAssignments) # Set _deferredAssignments to None so that deferAssignment will fail # noisily if called after we've run through the deferred assignments. self._deferredAssignments = None del self.scopeStack[1:] self.popScope() self.checkDeadScopes() def deferFunction(self, callable): """ Schedule a function handler to be called just before completion. This is used for handling function bodies, which must be deferred because code later in the file might modify the global scope. When `callable` is called, the scope at the time this is called will be restored, however it will contain any new bindings added to it. """ self._deferredFunctions.append((callable, self.scopeStack[:], self.offset)) def deferAssignment(self, callable): """ Schedule an assignment handler to be called just after deferred function handlers. """ self._deferredAssignments.append((callable, self.scopeStack[:], self.offset)) def runDeferred(self, deferred): """ Run the callables in C{deferred} using their associated scope stack. """ for handler, scope, offset in deferred: self.scopeStack = scope self.offset = offset handler() @property def scope(self): return self.scopeStack[-1] def popScope(self): self.deadScopes.append(self.scopeStack.pop()) def checkDeadScopes(self): """ Look at scopes which have been fully examined and report names in them which were imported but unused. """ for scope in self.deadScopes: if isinstance(scope.get('__all__'), ExportBinding): all_names = set(scope['__all__'].names) if not scope.importStarred and \ os.path.basename(self.filename) != '__init__.py': # Look for possible mistakes in the export list undefined = all_names.difference(scope) for name in undefined: self.report(messages.UndefinedExport, scope['__all__'].source, name) else: all_names = [] # Look for imported names that aren't used. for value in scope.values(): if isinstance(value, Importation): used = value.used or value.name in all_names if not used: messg = messages.UnusedImport self.report(messg, value.source, value.name) for node in value.redefined: if isinstance(self.getParent(node), ast.For): messg = messages.ImportShadowedByLoopVar elif used: continue else: messg = messages.RedefinedWhileUnused self.report(messg, node, value.name, value.source) def pushScope(self, scopeClass=FunctionScope): self.scopeStack.append(scopeClass()) def report(self, messageClass, *args, **kwargs): self.messages.append(messageClass(self.filename, *args, **kwargs)) def getParent(self, node): # Lookup the first parent which is not Tuple, List or Starred while True: node = node.parent if not hasattr(node, 'elts') and not hasattr(node, 'ctx'): return node def getCommonAncestor(self, lnode, rnode, stop): if stop in (lnode, rnode) or not (hasattr(lnode, 'parent') and hasattr(rnode, 'parent')): return None if lnode is rnode: return lnode if (lnode.depth > rnode.depth): return self.getCommonAncestor(lnode.parent, rnode, stop) if (lnode.depth < rnode.depth): return self.getCommonAncestor(lnode, rnode.parent, stop) return self.getCommonAncestor(lnode.parent, rnode.parent, stop) def descendantOf(self, node, ancestors, stop): for a in ancestors: if self.getCommonAncestor(node, a, stop): return True return False def differentForks(self, lnode, rnode): """True, if lnode and rnode are located on different forks of IF/TRY""" ancestor = self.getCommonAncestor(lnode, rnode, self.root) parts = getAlternatives(ancestor) if parts: for items in parts: if self.descendantOf(lnode, items, ancestor) ^ \ self.descendantOf(rnode, items, ancestor): return True return False def addBinding(self, node, value): """ Called when a binding is altered. - `node` is the statement responsible for the change - `value` is the new value, a Binding instance """ # assert value.source in (node, node.parent): for scope in self.scopeStack[::-1]: if value.name in scope: break existing = scope.get(value.name) if existing and not self.differentForks(node, existing.source): parent_stmt = self.getParent(value.source) if isinstance(existing, Importation) and isinstance(parent_stmt, ast.For): self.report(messages.ImportShadowedByLoopVar, node, value.name, existing.source) elif scope is self.scope: if (isinstance(parent_stmt, ast.comprehension) and not isinstance(self.getParent(existing.source), (ast.For, ast.comprehension))): self.report(messages.RedefinedInListComp, node, value.name, existing.source) elif not existing.used and value.redefines(existing): self.report(messages.RedefinedWhileUnused, node, value.name, existing.source) elif isinstance(existing, Importation) and value.redefines(existing): existing.redefined.append(node) self.scope[value.name] = value def getNodeHandler(self, node_class): try: return self._nodeHandlers[node_class] except KeyError: nodeType = getNodeType(node_class) self._nodeHandlers[node_class] = handler = getattr(self, nodeType) return handler def handleNodeLoad(self, node): name = getNodeName(node) if not name: return # try local scope try: self.scope[name].used = (self.scope, node) except KeyError: pass else: return scopes = [scope for scope in self.scopeStack[:-1] if isinstance(scope, (FunctionScope, ModuleScope))] if isinstance(self.scope, GeneratorScope) and scopes[-1] != self.scopeStack[-2]: scopes.append(self.scopeStack[-2]) # try enclosing function scopes and global scope importStarred = self.scope.importStarred for scope in reversed(scopes): importStarred = importStarred or scope.importStarred try: scope[name].used = (self.scope, node) except KeyError: pass else: return # look in the built-ins if importStarred or name in self.builtIns: return if name == '__path__' and os.path.basename(self.filename) == '__init__.py': # the special name __path__ is valid only in packages return # protected with a NameError handler? if 'NameError' not in self.exceptHandlers[-1]: self.report(messages.UndefinedName, node, name) def handleNodeStore(self, node): name = getNodeName(node) if not name: return # if the name hasn't already been defined in the current scope if isinstance(self.scope, FunctionScope) and name not in self.scope: # for each function or module scope above us for scope in self.scopeStack[:-1]: if not isinstance(scope, (FunctionScope, ModuleScope)): continue # if the name was defined in that scope, and the name has # been accessed already in the current scope, and hasn't # been declared global used = name in scope and scope[name].used if used and used[0] is self.scope and name not in self.scope.globals: # then it's probably a mistake self.report(messages.UndefinedLocal, scope[name].used[1], name, scope[name].source) break parent_stmt = self.getParent(node) if isinstance(parent_stmt, (ast.For, ast.comprehension)) or ( parent_stmt != node.parent and not self.isLiteralTupleUnpacking(parent_stmt)): binding = Binding(name, node) elif name == '__all__' and isinstance(self.scope, ModuleScope): binding = ExportBinding(name, node.parent, self.scope) else: binding = Assignment(name, node) if name in self.scope: binding.used = self.scope[name].used self.addBinding(node, binding) def handleNodeDelete(self, node): name = getNodeName(node) if not name: return if isinstance(self.scope, FunctionScope) and name in self.scope.globals: self.scope.globals.remove(name) else: try: del self.scope[name] except KeyError: self.report(messages.UndefinedName, node, name) def handleChildren(self, tree, omit=None): for node in iter_child_nodes(tree, omit=omit): self.handleNode(node, tree) def isLiteralTupleUnpacking(self, node): if isinstance(node, ast.Assign): for child in node.targets + [node.value]: if not hasattr(child, 'elts'): return False return True def isDocstring(self, node): """ Determine if the given node is a docstring, as long as it is at the correct place in the node tree. """ return isinstance(node, ast.Str) or (isinstance(node, ast.Expr) and isinstance(node.value, ast.Str)) def getDocstring(self, node): if isinstance(node, ast.Expr): node = node.value if not isinstance(node, ast.Str): return (None, None) # Computed incorrectly if the docstring has backslash doctest_lineno = node.lineno - node.s.count('\n') - 1 return (node.s, doctest_lineno) def handleNode(self, node, parent): if node is None: return if self.offset and getattr(node, 'lineno', None) is not None: node.lineno += self.offset[0] node.col_offset += self.offset[1] if self.traceTree: print(' ' * self.nodeDepth + node.__class__.__name__) if self.futuresAllowed and not (isinstance(node, ast.ImportFrom) or self.isDocstring(node)): self.futuresAllowed = False self.nodeDepth += 1 node.depth = self.nodeDepth node.parent = parent try: handler = self.getNodeHandler(node.__class__) handler(node) finally: self.nodeDepth -= 1 if self.traceTree: print(' ' * self.nodeDepth + 'end ' + node.__class__.__name__) _getDoctestExamples = doctest.DocTestParser().get_examples def handleDoctests(self, node): try: (docstring, node_lineno) = self.getDocstring(node.body[0]) examples = docstring and self._getDoctestExamples(docstring) except (ValueError, IndexError): # e.g. line 6 of the docstring for has inconsistent # leading whitespace: ... return if not examples: return node_offset = self.offset or (0, 0) self.pushScope() underscore_in_builtins = '_' in self.builtIns if not underscore_in_builtins: self.builtIns.add('_') for example in examples: try: tree = compile(example.source, "", "exec", ast.PyCF_ONLY_AST) except SyntaxError: e = sys.exc_info()[1] position = (node_lineno + example.lineno + e.lineno, example.indent + 4 + (e.offset or 0)) self.report(messages.DoctestSyntaxError, node, position) else: self.offset = (node_offset[0] + node_lineno + example.lineno, node_offset[1] + example.indent + 4) self.handleChildren(tree) self.offset = node_offset if not underscore_in_builtins: self.builtIns.remove('_') self.popScope() def ignore(self, node): pass # "stmt" type nodes DELETE = PRINT = FOR = WHILE = IF = WITH = WITHITEM = RAISE = \ TRYFINALLY = ASSERT = EXEC = EXPR = ASSIGN = handleChildren CONTINUE = BREAK = PASS = ignore # "expr" type nodes BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = \ COMPARE = CALL = REPR = ATTRIBUTE = SUBSCRIPT = LIST = TUPLE = \ STARRED = NAMECONSTANT = handleChildren NUM = STR = BYTES = ELLIPSIS = ignore # "slice" type nodes SLICE = EXTSLICE = INDEX = handleChildren # expression contexts are node instances too, though being constants LOAD = STORE = DEL = AUGLOAD = AUGSTORE = PARAM = ignore # same for operators AND = OR = ADD = SUB = MULT = DIV = MOD = POW = LSHIFT = RSHIFT = \ BITOR = BITXOR = BITAND = FLOORDIV = INVERT = NOT = UADD = USUB = \ EQ = NOTEQ = LT = LTE = GT = GTE = IS = ISNOT = IN = NOTIN = ignore # additional node types LISTCOMP = COMPREHENSION = KEYWORD = handleChildren def GLOBAL(self, node): """ Keep track of globals declarations. """ if isinstance(self.scope, FunctionScope): self.scope.globals.update(node.names) NONLOCAL = GLOBAL def GENERATOREXP(self, node): self.pushScope(GeneratorScope) self.handleChildren(node) self.popScope() DICTCOMP = SETCOMP = GENERATOREXP def NAME(self, node): """ Handle occurrence of Name (which can be a load/store/delete access.) """ # Locate the name in locals / function / globals scopes. if isinstance(node.ctx, (ast.Load, ast.AugLoad)): self.handleNodeLoad(node) if (node.id == 'locals' and isinstance(self.scope, FunctionScope) and isinstance(node.parent, ast.Call)): # we are doing locals() call in current scope self.scope.usesLocals = True elif isinstance(node.ctx, (ast.Store, ast.AugStore)): self.handleNodeStore(node) elif isinstance(node.ctx, ast.Del): self.handleNodeDelete(node) else: # must be a Param context -- this only happens for names in function # arguments, but these aren't dispatched through here raise RuntimeError("Got impossible expression context: %r" % (node.ctx,)) def RETURN(self, node): if ( node.value and hasattr(self.scope, 'returnValue') and not self.scope.returnValue ): self.scope.returnValue = node.value self.handleNode(node.value, node) def YIELD(self, node): self.scope.isGenerator = True self.handleNode(node.value, node) YIELDFROM = YIELD def FUNCTIONDEF(self, node): for deco in node.decorator_list: self.handleNode(deco, node) self.LAMBDA(node) self.addBinding(node, FunctionDefinition(node.name, node)) if self.withDoctest: self.deferFunction(lambda: self.handleDoctests(node)) def LAMBDA(self, node): args = [] annotations = [] if PY2: def addArgs(arglist): for arg in arglist: if isinstance(arg, ast.Tuple): addArgs(arg.elts) else: args.append(arg.id) addArgs(node.args.args) defaults = node.args.defaults else: for arg in node.args.args + node.args.kwonlyargs: args.append(arg.arg) annotations.append(arg.annotation) defaults = node.args.defaults + node.args.kw_defaults # Only for Python3 FunctionDefs is_py3_func = hasattr(node, 'returns') for arg_name in ('vararg', 'kwarg'): wildcard = getattr(node.args, arg_name) if not wildcard: continue args.append(wildcard if PY33 else wildcard.arg) if is_py3_func: if PY33: # Python 2.5 to 3.3 argannotation = arg_name + 'annotation' annotations.append(getattr(node.args, argannotation)) else: # Python >= 3.4 annotations.append(wildcard.annotation) if is_py3_func: annotations.append(node.returns) if len(set(args)) < len(args): for (idx, arg) in enumerate(args): if arg in args[:idx]: self.report(messages.DuplicateArgument, node, arg) for child in annotations + defaults: if child: self.handleNode(child, node) def runFunction(): self.pushScope() for name in args: self.addBinding(node, Argument(name, node)) if isinstance(node.body, list): # case for FunctionDefs for stmt in node.body: self.handleNode(stmt, node) else: # case for Lambdas self.handleNode(node.body, node) def checkUnusedAssignments(): """ Check to see if any assignments have not been used. """ for name, binding in self.scope.unusedAssignments(): self.report(messages.UnusedVariable, binding.source, name) self.deferAssignment(checkUnusedAssignments) if PY32: def checkReturnWithArgumentInsideGenerator(): """ Check to see if there is any return statement with arguments but the function is a generator. """ if self.scope.isGenerator and self.scope.returnValue: self.report(messages.ReturnWithArgsInsideGenerator, self.scope.returnValue) self.deferAssignment(checkReturnWithArgumentInsideGenerator) self.popScope() self.deferFunction(runFunction) def CLASSDEF(self, node): """ Check names used in a class definition, including its decorators, base classes, and the body of its definition. Additionally, add its name to the current scope. """ for deco in node.decorator_list: self.handleNode(deco, node) for baseNode in node.bases: self.handleNode(baseNode, node) if not PY2: for keywordNode in node.keywords: self.handleNode(keywordNode, node) self.pushScope(ClassScope) if self.withDoctest: self.deferFunction(lambda: self.handleDoctests(node)) for stmt in node.body: self.handleNode(stmt, node) self.popScope() self.addBinding(node, ClassDefinition(node.name, node)) def AUGASSIGN(self, node): self.handleNodeLoad(node.target) self.handleNode(node.value, node) self.handleNode(node.target, node) def IMPORT(self, node): for alias in node.names: name = alias.asname or alias.name importation = Importation(name, node) self.addBinding(node, importation) def IMPORTFROM(self, node): if node.module == '__future__': if not self.futuresAllowed: self.report(messages.LateFutureImport, node, [n.name for n in node.names]) else: self.futuresAllowed = False for alias in node.names: if alias.name == '*': self.scope.importStarred = True self.report(messages.ImportStarUsed, node, node.module) continue name = alias.asname or alias.name importation = Importation(name, node) if node.module == '__future__': importation.used = (self.scope, node) self.addBinding(node, importation) def TRY(self, node): handler_names = [] # List the exception handlers for handler in node.handlers: if isinstance(handler.type, ast.Tuple): for exc_type in handler.type.elts: handler_names.append(getNodeName(exc_type)) elif handler.type: handler_names.append(getNodeName(handler.type)) # Memorize the except handlers and process the body self.exceptHandlers.append(handler_names) for child in node.body: self.handleNode(child, node) self.exceptHandlers.pop() # Process the other nodes: "except:", "else:", "finally:" self.handleChildren(node, omit='body') TRYEXCEPT = TRY def EXCEPTHANDLER(self, node): # 3.x: in addition to handling children, we must handle the name of # the exception, which is not a Name node, but a simple string. if isinstance(node.name, str): self.handleNodeStore(node) self.handleChildren(node) eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/messages.py0000644000175000017500000002160412451233370025551 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # # Original (c) 2005 Divmod, Inc. See __init__.py file for details # # This module is based on pyflakes for Python2 and Python3, but was modified to # be integrated into eric6 """ Module providing the class Message and its subclasses. """ class Message(object): """ Class defining the base for all specific message classes. """ message_id = 'F00' message = '' message_args = () def __init__(self, filename, loc): """ Constructor @param filename name of the file (string) @param loc location of the issue """ self.filename = filename self.lineno = loc.lineno self.col = getattr(loc, 'col_offset', 0) def __str__(self): """ Special method return a string representation of the instance object. @return string representation of the object (string) """ return '%s:%s: %s' % ( self.filename, self.lineno, self.message % self.message_args) def getMessageData(self): """ Public method to get the individual message data elements. @return tuple containing file name, line number, column, message ID and message arguments (string, integer, integer, string, list) """ return (self.filename, self.lineno, self.col, self.message_id, self.message_args) class UnusedImport(Message): """ Class defining the "Unused Import" message. """ message_id = 'F01' message = '%r imported but unused' def __init__(self, filename, loc, name): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name name of the unused import (string) """ Message.__init__(self, filename, loc) self.message_args = (name,) class RedefinedWhileUnused(Message): """ Class defining the "Redefined While Unused" message. """ message_id = 'F02' message = 'redefinition of unused %r from line %r' def __init__(self, filename, loc, name, orig_loc): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name name of the redefined object (string) @param orig_loc location of the original definition """ Message.__init__(self, filename, loc) self.message_args = (name, orig_loc.lineno) class RedefinedInListComp(Message): """ Class defining the "Redefined In List Comprehension" message. """ message_id = 'F12' message = 'list comprehension redefines %r from line %r' def __init__(self, filename, loc, name, orig_loc): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name name of the redefined object (string) @param orig_loc location of the original definition """ Message.__init__(self, filename, loc) self.message_args = (name, orig_loc.lineno) class ImportShadowedByLoopVar(Message): """ Class defining the "Import Shadowed By Loop Var" message. """ message_id = 'F03' message = 'import %r from line %r shadowed by loop variable' def __init__(self, filename, loc, name, orig_loc): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name name of the shadowed import (string) @param orig_loc location of the import """ Message.__init__(self, filename, loc) self.message_args = (name, orig_loc.lineno) class ImportStarUsed(Message): """ Class defining the "Import Star Used" message. """ message_id = 'F04' message = "'from %s import *' used; unable to detect undefined names" def __init__(self, filename, loc, modname): """ Constructor @param filename name of the file (string) @param loc location of the issue @param modname name of the module imported using star import (string) """ Message.__init__(self, filename, loc) self.message_args = (modname,) class UndefinedName(Message): """ Class defining the "Undefined Name" message. """ message_id = 'F05' message = 'undefined name %r' def __init__(self, filename, loc, name): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name undefined name (string) """ Message.__init__(self, filename, loc) self.message_args = (name,) class DoctestSyntaxError(Message): """ Class defining the "Doctest syntax Error" message. """ message_id = 'F13' message = 'syntax error in doctest' def __init__(self, filename, loc, position=None): """ Constructor @param filename name of the file (string) @param loc location of the issue @param position position of the syntax error """ Message.__init__(self, filename, loc) if position: (self.lineno, self.col) = position self.message_args = () class UndefinedExport(Message): """ Class defining the "Undefined Export" message. """ message_id = 'F06' message = 'undefined name %r in __all__' def __init__(self, filename, loc, name): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name undefined exported name (string) """ Message.__init__(self, filename, loc) self.message_args = (name,) class UndefinedLocal(Message): """ Class defining the "Undefined Local Variable" message. """ message_id = 'F07' message = ('local variable %r (defined in enclosing scope on line %r) ' 'referenced before assignment') def __init__(self, filename, loc, name, orig_loc): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name name of the prematurely referenced variable (string) @param orig_loc location of the variable definition """ Message.__init__(self, filename, loc) self.message_args = (name, orig_loc.lineno) class DuplicateArgument(Message): """ Class defining the "Duplicate Argument" message. """ message_id = 'F08' message = 'duplicate argument %r in function definition' def __init__(self, filename, loc, name): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name name of the duplicate argument (string) """ Message.__init__(self, filename, loc) self.message_args = (name,) class Redefined(Message): """ Class defining the "Redefined" message. """ message_id = 'F09' message = 'redefinition of %r from line %r' def __init__(self, filename, loc, name, orig_loc): """ Constructor @param filename name of the file (string) @param loc location of the issue @param name name of the redefined function (string) @param orig_loc location of the original definition """ Message.__init__(self, filename, loc) self.message_args = (name, orig_loc.lineno) class LateFutureImport(Message): """ Class defining the "Late Future Import" message. """ message_id = 'F10' message = 'future import(s) %r after other statements' def __init__(self, filename, loc, names): """ Constructor @param filename name of the file (string) @param loc location of the issue @param names names of the imported futures (string) """ Message.__init__(self, filename, loc) self.message_args = (names,) class UnusedVariable(Message): """ Class defining the "Unused Variable" message. Indicates that a variable has been explicitly assigned to but not actually used. """ message_id = 'F11' message = 'local variable %r is assigned to but never used' def __init__(self, filename, loc, names): """ Constructor @param filename name of the file (string) @param loc location of the issue @param names names of unused variable (string) """ Message.__init__(self, filename, loc) self.message_args = (names,) class ReturnWithArgsInsideGenerator(Message): """ Class defining the "Return values in generator" message. Indicates a return statement with arguments inside a generator. """ message_id = 'F14' message = '\'return\' with argument inside generator' eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/translations.py0000644000175000017500000000521512451233370026463 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing message translations for pyflakes warning messages. """ from __future__ import unicode_literals from PyQt5.QtCore import QCoreApplication __all__ = ["getTranslatedFlakesMessage"] _messages = { 'F01': QCoreApplication.translate( 'pyFlakes', '{0!r} imported but unused.'), 'F02': QCoreApplication.translate( 'pyFlakes', 'Redefinition of unused {0!r} from line {1!r}.'), 'F03': QCoreApplication.translate( 'pyFlakes', 'Import {0!r} from line {1!r} shadowed by loop variable.'), 'F04': QCoreApplication.translate( 'pyFlakes', "'from {0} import *' used; unable to detect undefined names."), 'F05': QCoreApplication.translate( 'pyFlakes', 'Undefined name {0!r}.'), 'F06': QCoreApplication.translate( 'pyFlakes', 'Undefined name {0!r} in __all__.'), 'F07': QCoreApplication.translate( 'pyFlakes', "Local variable {0!r} (defined in enclosing scope on line {1!r})" " referenced before assignment."), 'F08': QCoreApplication.translate( 'pyFlakes', 'Duplicate argument {0!r} in function definition.'), 'F09': QCoreApplication.translate( 'pyFlakes', 'Redefinition of {0!r} from line {1!r}.'), 'F10': QCoreApplication.translate( 'pyFlakes', 'Future import(s) {0!r} after other statements.'), 'F11': QCoreApplication.translate( 'pyFlakes', 'Local variable {0!r} is assigned to but never used.'), 'F12': QCoreApplication.translate( 'pyFlakes', 'List comprehension redefines {0!r} from line {1!r}.'), 'F13': QCoreApplication.translate( 'pyFlakes', 'Syntax error detected in doctest.'), 'F14': QCoreApplication.translate( 'pyFlakes', "'return' with argument inside generator"), } def getTranslatedFlakesMessage(message_id, message_args): """ Module function to get a translated and formatted message for a given pyflakes message ID. @param message_id message ID (string) @param message_args arguments for a formatted message (list) @return translated and formatted message (string) """ if message_id in _messages: # Avoid leading "u" at Python2 unicode strings msg = _messages[message_id].replace("{0!r}", "'{0}'") msg = msg.replace("{1!r}", "'{1}'") return msg.format(*message_args) else: return QCoreApplication.translate( "pyFlakes", "no message defined for code '{0}'")\ .format(message_id) eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.ui0000644000175000017500000001125612253117353026010 0ustar piotrpiotr SyntaxCheckerDialog 0 0 650 500 Syntax Check Result <b>Syntax Check Results</b> <p>This dialog shows the results of the syntax check. Double clicking an entry will open an editor window and position the cursor at the respective line.</p> true QFrame::NoFrame QFrame::Raised 0 Exclude Files: Enter filename patterns of files to be excluded separated by a comma 2 Qt::Vertical Press to start the syntax check run Start <b>Result List</b> <p>This list shows the results of the syntax check. Double clicking an entry will open this entry in an editor window and position the cursor at the respective line.</p> true true File/Line Message Source 0 0 Shows the progress of the syntax check action 0 Qt::Horizontal %v/%m Files Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource E5SqueezeLabelPath QLabel
E5Gui/E5SqueezeLabels.h
E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
startButton excludeFilesEdit resultList buttonBox
eric-6.0.8/eric/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py0000644000175000017500000003722712537064320026031 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a simple Python syntax checker. """ from __future__ import unicode_literals import os import fnmatch from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem, \ QApplication, QHeaderView from E5Gui.E5Application import e5App from .Ui_SyntaxCheckerDialog import Ui_SyntaxCheckerDialog import Utilities import UI.PixmapCache class SyntaxCheckerDialog(QDialog, Ui_SyntaxCheckerDialog): """ Class implementing a dialog to display the results of a syntax check run. """ filenameRole = Qt.UserRole + 1 lineRole = Qt.UserRole + 2 indexRole = Qt.UserRole + 3 errorRole = Qt.UserRole + 4 warningRole = Qt.UserRole + 5 def __init__(self, parent=None): """ Constructor @param parent The parent widget. (QWidget) """ super(SyntaxCheckerDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.showButton = self.buttonBox.addButton( self.tr("Show"), QDialogButtonBox.ActionRole) self.showButton.setToolTip( self.tr("Press to show all files containing an issue")) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.resultList.headerItem().setText(self.resultList.columnCount(), "") self.resultList.header().setSortIndicator(0, Qt.AscendingOrder) self.noResults = True self.cancelled = False self.__lastFileItem = None self.__fileList = [] self.__project = None self.filterFrame.setVisible(False) self.checkProgress.setVisible(False) self.checkProgressLabel.setVisible(False) self.checkProgressLabel.setMaximumWidth(600) try: self.syntaxCheckService = e5App().getObject('SyntaxCheckService') self.syntaxCheckService.syntaxChecked.connect(self.__processResult) except KeyError: self.syntaxCheckService = None self.filename = None def __resort(self): """ Private method to resort the tree. """ self.resultList.sortItems(self.resultList.sortColumn(), self.resultList.header().sortIndicatorOrder() ) def __createResultItem(self, file, line, index, error, sourcecode, isWarning=False): """ Private method to create an entry in the result list. @param file file name of file (string) @param line line number of faulty source (integer or string) @param index index number of fault (integer) @param error error text (string) @param sourcecode faulty line of code (string) @param isWarning flag indicating a warning message (boolean) """ if self.__lastFileItem is None: # It's a new file self.__lastFileItem = QTreeWidgetItem(self.resultList, [file]) self.__lastFileItem.setFirstColumnSpanned(True) self.__lastFileItem.setExpanded(True) self.__lastFileItem.setData(0, self.filenameRole, file) itm = QTreeWidgetItem(self.__lastFileItem) if isWarning: itm.setIcon(0, UI.PixmapCache.getIcon("warning.png")) else: itm.setIcon(0, UI.PixmapCache.getIcon("syntaxError.png")) itm.setData(0, Qt.DisplayRole, line) itm.setData(1, Qt.DisplayRole, error) itm.setData(2, Qt.DisplayRole, sourcecode) itm.setData(0, self.filenameRole, file) itm.setData(0, self.lineRole, int(line)) itm.setData(0, self.indexRole, index) itm.setData(0, self.errorRole, error) itm.setData(0, self.warningRole, isWarning) def prepare(self, fileList, project): """ Public method to prepare the dialog with a list of filenames. @param fileList list of filenames (list of strings) @param project reference to the project object (Project) """ self.__fileList = fileList[:] self.__project = project self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.filterFrame.setVisible(True) self.__data = self.__project.getData("CHECKERSPARMS", "SyntaxChecker") if self.__data is None or "ExcludeFiles" not in self.__data: self.__data = {"ExcludeFiles": ""} self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) def start(self, fn, codestring=""): """ Public slot to start the syntax check. @param fn file or list of files or directory to be checked (string or list of strings) @param codestring string containing the code to be checked (string). If this is given, fn must be a single file name. """ if self.syntaxCheckService is not None: if self.__project is None: self.__project = e5App().getObject("Project") self.cancelled = False self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.checkProgress.setVisible(True) QApplication.processEvents() if isinstance(fn, list): self.files = fn elif os.path.isdir(fn): self.files = [] for ext in self.syntaxCheckService.getExtensions(): self.files.extend( Utilities.direntries(fn, True, '*{0}'.format(ext), 0)) else: self.files = [fn] self.__clearErrors(self.files) if codestring or len(self.files) > 0: self.checkProgress.setMaximum(max(1, len(self.files))) self.checkProgress.setVisible(len(self.files) > 1) self.checkProgressLabel.setVisible(len(self.files) > 1) QApplication.processEvents() # now go through all the files self.progress = 0 self.check(codestring) def check(self, codestring=''): """ Public method to start a check for one file. The results are reported to the __processResult slot. @keyparam codestring optional sourcestring (str) """ if self.syntaxCheckService is None or not self.files: self.__finish() return self.filename = self.files.pop(0) self.checkProgress.setValue(self.progress) self.checkProgressLabel.setPath(self.filename) QApplication.processEvents() self.__resort() if self.cancelled: return self.__lastFileItem = None if codestring: self.source = codestring else: try: self.source = Utilities.readEncodedFile(self.filename)[0] self.source = Utilities.normalizeCode(self.source) except (UnicodeError, IOError) as msg: self.noResults = False self.__createResultItem( self.filename, 1, 0, self.tr("Error: {0}").format(str(msg)) .rstrip(), "") self.progress += 1 # Continue with next file self.check() return self.syntaxCheckService.syntaxCheck(None, self.filename, self.source) def __processResult(self, fn, problems): """ Private slot to display the reported messages. @param fn filename of the checked file (str) @param problems dictionary with the keys 'error' and 'warnings' which hold a list containing details about the error/ warnings (file name, line number, column, codestring (only at syntax errors), the message) (dict) """ # Check if it's the requested file, otherwise ignore signal if fn != self.filename: return error = problems.get('error') if error: self.noResults = False _fn, lineno, col, code, msg = error self.__createResultItem(_fn, lineno, col, msg, code, False) warnings = problems.get('warnings', []) if warnings: source = self.source.splitlines() for _fn, lineno, col, code, msg in warnings: self.noResults = False scr_line = source[lineno - 1].strip() self.__createResultItem(_fn, lineno, col, msg, scr_line, True) self.progress += 1 self.checkProgress.setValue(self.progress) QApplication.processEvents() self.__resort() if self.files: self.check() else: self.checkProgressLabel.setPath("") self.checkProgress.setMaximum(1) self.checkProgress.setValue(1) self.__finish() def __finish(self): """ Private slot called when the syntax check finished or the user pressed the button. """ self.cancelled = True self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) if self.noResults: QTreeWidgetItem(self.resultList, [self.tr('No issues found.')]) QApplication.processEvents() self.showButton.setEnabled(False) else: self.showButton.setEnabled(True) self.resultList.header().resizeSections(QHeaderView.ResizeToContents) self.resultList.header().setStretchLastSection(True) self.checkProgress.setVisible(False) self.checkProgressLabel.setVisible(False) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() elif button == self.showButton: self.on_showButton_clicked() @pyqtSlot() def on_startButton_clicked(self): """ Private slot to start a syntax check run. """ fileList = self.__fileList[:] filterString = self.excludeFilesEdit.text() if "ExcludeFiles" not in self.__data or \ filterString != self.__data["ExcludeFiles"]: self.__data["ExcludeFiles"] = filterString self.__project.setData("CHECKERSPARMS", "SyntaxChecker", self.__data) filterList = [f.strip() for f in filterString.split(",") if f.strip()] if filterList: for filter in filterList: fileList = \ [f for f in fileList if not fnmatch.fnmatch(f, filter)] self.resultList.clear() self.noResults = True self.cancelled = False self.start(fileList) def on_resultList_itemActivated(self, itm, col): """ Private slot to handle the activation of an item. @param itm reference to the activated item (QTreeWidgetItem) @param col column the item was activated in (integer) """ if self.noResults: return if itm.parent(): fn = Utilities.normabspath(itm.data(0, self.filenameRole)) lineno = itm.data(0, self.lineRole) index = itm.data(0, self.indexRole) error = itm.data(0, self.errorRole) vm = e5App().getObject("ViewManager") vm.openSourceFile(fn, lineno) editor = vm.getOpenEditor(fn) if itm.data(0, self.warningRole): editor.toggleWarning(lineno, 0, True, error) else: editor.toggleSyntaxError(lineno, index, True, error, show=True) else: fn = Utilities.normabspath(itm.data(0, self.filenameRole)) vm = e5App().getObject("ViewManager") vm.openSourceFile(fn) editor = vm.getOpenEditor(fn) for index in range(itm.childCount()): citm = itm.child(index) lineno = citm.data(0, self.lineRole) index = citm.data(0, self.indexRole) error = citm.data(0, self.errorRole) if citm.data(0, self.warningRole): editor.toggleWarning(lineno, 0, True, error) else: editor.toggleSyntaxError( lineno, index, True, error, show=True) @pyqtSlot() def on_showButton_clicked(self): """ Private slot to handle the "Show" button press. """ vm = e5App().getObject("ViewManager") selectedIndexes = [] for index in range(self.resultList.topLevelItemCount()): if self.resultList.topLevelItem(index).isSelected(): selectedIndexes.append(index) if len(selectedIndexes) == 0: selectedIndexes = list(range(self.resultList.topLevelItemCount())) for index in selectedIndexes: itm = self.resultList.topLevelItem(index) fn = Utilities.normabspath(itm.data(0, self.filenameRole)) vm.openSourceFile(fn, 1) editor = vm.getOpenEditor(fn) editor.clearSyntaxError() editor.clearFlakesWarnings() for cindex in range(itm.childCount()): citm = itm.child(cindex) lineno = citm.data(0, self.lineRole) index = citm.data(0, self.indexRole) error = citm.data(0, self.errorRole) if citm.data(0, self.warningRole): editor.toggleWarning(lineno, 0, True, error) else: editor.toggleSyntaxError( lineno, index, True, error, show=True) # go through the list again to clear syntax error and # flakes warning markers for files, that are ok openFiles = vm.getOpenFilenames() errorFiles = [] for index in range(self.resultList.topLevelItemCount()): itm = self.resultList.topLevelItem(index) errorFiles.append( Utilities.normabspath(itm.data(0, self.filenameRole))) for file in openFiles: if file not in errorFiles: editor = vm.getOpenEditor(file) editor.clearSyntaxError() editor.clearFlakesWarnings() def __clearErrors(self, files): """ Private method to clear all error and warning markers of open editors to be checked. @param files list of files to be checked (list of string) """ vm = e5App().getObject("ViewManager") openFiles = vm.getOpenFilenames() for file in [f for f in openFiles if f in files]: editor = vm.getOpenEditor(file) editor.clearSyntaxError() editor.clearFlakesWarnings() eric-6.0.8/eric/Plugins/CheckerPlugins/Tabnanny/0000755000175000017500000000000012557365404020561 5ustar piotrpiotreric-6.0.8/eric/Plugins/CheckerPlugins/Tabnanny/__init__.py0000644000175000017500000000022412451233370022655 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the Tabnanny plugin. """ eric-6.0.8/eric/Plugins/CheckerPlugins/Tabnanny/TabnannyDialog.py0000644000175000017500000002305412537064320024020 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the tabnanny command process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os import fnmatch from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem, \ QApplication, QHeaderView from E5Gui.E5Application import e5App from .Ui_TabnannyDialog import Ui_TabnannyDialog import Utilities import Preferences class TabnannyDialog(QDialog, Ui_TabnannyDialog): """ Class implementing a dialog to show the results of the tabnanny check run. """ def __init__(self, indentCheckService, parent=None): """ Constructor @param indentCheckService reference to the service (IndentCheckService) @param parent The parent widget (QWidget). """ super(TabnannyDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.resultList.headerItem().setText(self.resultList.columnCount(), "") self.resultList.header().setSortIndicator(0, Qt.AscendingOrder) self.indentCheckService = indentCheckService self.indentCheckService.indentChecked.connect(self.__processResult) self.filename = None self.noResults = True self.cancelled = False self.__fileList = [] self.__project = None self.filterFrame.setVisible(False) self.checkProgress.setVisible(False) self.checkProgressLabel.setVisible(False) self.checkProgressLabel.setMaximumWidth(600) def __resort(self): """ Private method to resort the tree. """ self.resultList.sortItems( self.resultList.sortColumn(), self.resultList.header().sortIndicatorOrder()) def __createResultItem(self, file, line, sourcecode): """ Private method to create an entry in the result list. @param file filename of file (string) @param line linenumber of faulty source (integer or string) @param sourcecode faulty line of code (string) """ itm = QTreeWidgetItem(self.resultList) itm.setData(0, Qt.DisplayRole, file) itm.setData(1, Qt.DisplayRole, line) itm.setData(2, Qt.DisplayRole, sourcecode) itm.setTextAlignment(1, Qt.AlignRight) def prepare(self, fileList, project): """ Public method to prepare the dialog with a list of filenames. @param fileList list of filenames (list of strings) @param project reference to the project object (Project) """ self.__fileList = fileList[:] self.__project = project self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.filterFrame.setVisible(True) self.__data = self.__project.getData("CHECKERSPARMS", "Tabnanny") if self.__data is None or "ExcludeFiles" not in self.__data: self.__data = {"ExcludeFiles": ""} self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) def start(self, fn): """ Public slot to start the tabnanny check. @param fn File or list of files or directory to be checked (string or list of strings) """ if self.__project is None: self.__project = e5App().getObject("Project") self.cancelled = False self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.checkProgress.setVisible(True) QApplication.processEvents() if isinstance(fn, list): self.files = fn elif os.path.isdir(fn): self.files = [] extensions = set(Preferences.getPython("PythonExtensions") + Preferences.getPython("Python3Extensions")) for ext in extensions: self.files.extend( Utilities.direntries(fn, True, '*{0}'.format(ext), 0)) else: self.files = [fn] if len(self.files) > 0: self.checkProgress.setMaximum(len(self.files)) self.checkProgress.setVisible(len(self.files) > 1) self.checkProgressLabel.setVisible(len(self.files) > 1) QApplication.processEvents() # now go through all the files self.progress = 0 self.check() def check(self, codestring=''): """ Public method to start a style check for one file. The results are reported to the __processResult slot. @keyparam codestring optional sourcestring (str) """ if not self.files: self.checkProgressLabel.setPath("") self.checkProgress.setMaximum(1) self.checkProgress.setValue(1) self.__finish() return self.filename = self.files.pop(0) self.checkProgress.setValue(self.progress) self.checkProgressLabel.setPath(self.filename) QApplication.processEvents() self.__resort() if self.cancelled: return try: self.source = Utilities.readEncodedFile(self.filename)[0] self.source = Utilities.normalizeCode(self.source) except (UnicodeError, IOError) as msg: self.noResults = False self.__createResultItem( self.filename, 1, "Error: {0}".format(str(msg)).rstrip()) self.progress += 1 # Continue with next file self.check() return self.indentCheckService.indentCheck( None, self.filename, self.source) def __processResult(self, fn, nok, line, error): """ Private slot called after perfoming a style check on one file. @param fn filename of the just checked file (str) @param nok flag if a problem was found (bool) @param line line number (str) @param error text of the problem (str) """ # Check if it's the requested file, otherwise ignore signal if fn != self.filename: return if nok: self.noResults = False self.__createResultItem(fn, line, error.rstrip()) self.progress += 1 self.checkProgress.setValue(self.progress) self.checkProgressLabel.setPath("") QApplication.processEvents() self.__resort() self.check() def __finish(self): """ Private slot called when the action or the user pressed the button. """ self.cancelled = True self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) if self.noResults: self.__createResultItem( self.tr('No indentation errors found.'), "", "") QApplication.processEvents() self.resultList.header().resizeSections(QHeaderView.ResizeToContents) self.resultList.header().setStretchLastSection(True) self.checkProgress.setVisible(False) self.checkProgressLabel.setVisible(False) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() @pyqtSlot() def on_startButton_clicked(self): """ Private slot to start a code metrics run. """ fileList = self.__fileList[:] filterString = self.excludeFilesEdit.text() if "ExcludeFiles" not in self.__data or \ filterString != self.__data["ExcludeFiles"]: self.__data["ExcludeFiles"] = filterString self.__project.setData("CHECKERSPARMS", "Tabnanny", self.__data) filterList = [f.strip() for f in filterString.split(",") if f.strip()] if filterList: for filter in filterList: fileList = \ [f for f in fileList if not fnmatch.fnmatch(f, filter)] self.resultList.clear() self.noResults = True self.cancelled = False self.start(fileList) def on_resultList_itemActivated(self, itm, col): """ Private slot to handle the activation of an item. @param itm reference to the activated item (QTreeWidgetItem) @param col column the item was activated in (integer) """ if self.noResults: return fn = Utilities.normabspath(itm.text(0)) lineno = int(itm.text(1)) e5App().getObject("ViewManager").openSourceFile(fn, lineno) eric-6.0.8/eric/Plugins/CheckerPlugins/Tabnanny/Tabnanny.py0000644000175000017500000003352112451233370022676 0ustar piotrpiotr# -*- coding: utf-8 -*- """ The Tab Nanny despises ambiguous indentation. She knows no mercy. tabnanny -- Detection of ambiguous indentation For the time being this module is intended to be called as a script. However it is possible to import it into an IDE and use the function check() described below. Warning: The API provided by this module is likely to change in future releases; such changes may not be backward compatible. This is a modified version to make the original tabnanny better suitable for being called from within the eric6 IDE. @exception ValueError The tokenize module is too old. """ from __future__ import unicode_literals # Released to the public domain, by Tim Peters, 15 April 1998. # XXX Note: this is now a standard library module. # XXX The API needs to undergo changes however; the current code is too # XXX script-like. This will be addressed later. # # This is a modified version to make the original tabnanny better suitable # for being called from within the eric6 IDE. The modifications are as # follows: # # - there is no main function anymore # - check function has been modified to only accept a filename and return # a tuple indicating status (1 = an error was found), the filename, the # linenumber and the error message (boolean, string, string, string). The # values are only valid, if the status equals 1. # # Mofifications Copyright (c) 2003-2015 Detlev Offenbach # # __version__ = "6_eric" import tokenize try: import StringIO as io except (ImportError): import io # __IGNORE_WARNING__ if not hasattr(tokenize, 'NL'): raise ValueError("tokenize.NL doesn't exist -- tokenize module too old") __all__ = ["check", "NannyNag", "process_tokens"] def initService(): """ Initialize the service and return the entry point. @return the entry point for the background client (function) """ return check class NannyNag(Exception): """ Class implementing an exception for indentation issues. Raised by tokeneater() if detecting an ambiguous indent. Captured and handled in check(). """ def __init__(self, lineno, msg, line): """ Constructor @param lineno Line number of the ambiguous indent. @param msg Descriptive message assigned to this problem. @param line The offending source line. """ self.lineno, self.msg, self.line = lineno, msg, line def get_lineno(self): """ Public method to retrieve the line number. @return The line number (integer) """ return self.lineno def get_msg(self): """ Public method to retrieve the message. @return The error message (string) """ return self.msg def get_line(self): """ Public method to retrieve the offending line. @return The line of code (string) """ return self.line def check(file, text=""): """ Private function to check one Python source file for whitespace related problems. @param file source filename (string) @param text source text (string) @return A tuple indicating status (True = an error was found), the filename, the linenumber and the error message (boolean, string, string, string). The values are only valid, if the status is True. """ global indents, check_equal indents = [Whitespace("")] check_equal = 0 if not text: return (True, "1", "Error: source code missing.") source = io.StringIO(text) try: process_tokens(tokenize.generate_tokens(source.readline)) except tokenize.TokenError as msg: return (True, "1", "Token Error: {0}".format(str(msg))) except IndentationError as err: return (True, str(err.lineno), "Indentation Error: {0}".format(str(err.msg))) except NannyNag as nag: badline = nag.get_lineno() line = nag.get_line() return (True, str(badline), line) except Exception as err: return (True, "1", "Unspecific Error: {0}".format(str(err))) return (False, None, None) class Whitespace(object): """ Class implementing the whitespace checker. """ # the characters used for space and tab S, T = ' \t' # members: # raw # the original string # n # the number of leading whitespace characters in raw # nt # the number of tabs in raw[:n] # norm # the normal form as a pair (count, trailing), where: # count # a tuple such that raw[:n] contains count[i] # instances of S * i + T # trailing # the number of trailing spaces in raw[:n] # It's A Theorem that m.indent_level(t) == # n.indent_level(t) for all t >= 1 iff m.norm == n.norm. # is_simple # true iff raw[:n] is of the form (T*)(S*) def __init__(self, ws): """ Constructor @param ws The string to be checked. """ self.raw = ws S, T = Whitespace.S, Whitespace.T count = [] b = n = nt = 0 for ch in self.raw: if ch == S: n = n + 1 b = b + 1 elif ch == T: n = n + 1 nt = nt + 1 if b >= len(count): count = count + [0] * (b - len(count) + 1) count[b] = count[b] + 1 b = 0 else: break self.n = n self.nt = nt self.norm = tuple(count), b self.is_simple = len(count) <= 1 # return length of longest contiguous run of spaces (whether or not # preceding a tab) def longest_run_of_spaces(self): """ Public method to calculate the length of longest contiguous run of spaces. @return The length of longest contiguous run of spaces (whether or not preceding a tab) """ count, trailing = self.norm return max(len(count) - 1, trailing) def indent_level(self, tabsize): """ Public method to determine the indentation level. @param tabsize The length of a tab stop. (integer) @return indentation level (integer) """ # count, il = self.norm # for i in range(len(count)): # if count[i]: # il = il + (i/tabsize + 1)*tabsize * count[i] # return il # quicker: # il = trailing + sum (i/ts + 1)*ts*count[i] = # trailing + ts * sum (i/ts + 1)*count[i] = # trailing + ts * sum i/ts*count[i] + count[i] = # trailing + ts * [(sum i/ts*count[i]) + (sum count[i])] = # trailing + ts * [(sum i/ts*count[i]) + num_tabs] # and note that i/ts*count[i] is 0 when i < ts count, trailing = self.norm il = 0 for i in range(tabsize, len(count)): il = il + i / tabsize * count[i] return trailing + tabsize * (il + self.nt) # return true iff self.indent_level(t) == other.indent_level(t) # for all t >= 1 def equal(self, other): """ Public method to compare the indentation levels of two Whitespace objects for equality. @param other Whitespace object to compare against. @return True, if we compare equal against the other Whitespace object. """ return self.norm == other.norm # return a list of tuples (ts, i1, i2) such that # i1 == self.indent_level(ts) != other.indent_level(ts) == i2. # Intended to be used after not self.equal(other) is known, in which # case it will return at least one witnessing tab size. def not_equal_witness(self, other): """ Public method to calculate a tuple of witnessing tab size. Intended to be used after not self.equal(other) is known, in which case it will return at least one witnessing tab size. @param other Whitespace object to calculate against. @return A list of tuples (ts, i1, i2) such that i1 == self.indent_level(ts) != other.indent_level(ts) == i2. """ n = max(self.longest_run_of_spaces(), other.longest_run_of_spaces()) + 1 a = [] for ts in range(1, n + 1): if self.indent_level(ts) != other.indent_level(ts): a.append((ts, self.indent_level(ts), other.indent_level(ts))) return a # Return True iff self.indent_level(t) < other.indent_level(t) # for all t >= 1. # The algorithm is due to Vincent Broman. # Easy to prove it's correct. # XXXpost that. # Trivial to prove n is sharp (consider T vs ST). # Unknown whether there's a faster general way. I suspected so at # first, but no longer. # For the special (but common!) case where M and N are both of the # form (T*)(S*), M.less(N) iff M.len() < N.len() and # M.num_tabs() <= N.num_tabs(). Proof is easy but kinda long-winded. # XXXwrite that up. # Note that M is of the form (T*)(S*) iff len(M.norm[0]) <= 1. def less(self, other): """ Public method to compare the indentation level against another Whitespace objects to be smaller. @param other Whitespace object to compare against. @return True, if we compare less against the other Whitespace object. """ if self.n >= other.n: return False if self.is_simple and other.is_simple: return self.nt <= other.nt n = max(self.longest_run_of_spaces(), other.longest_run_of_spaces()) + 1 # the self.n >= other.n test already did it for ts=1 for ts in range(2, n + 1): if self.indent_level(ts) >= other.indent_level(ts): return False return True # return a list of tuples (ts, i1, i2) such that # i1 == self.indent_level(ts) >= other.indent_level(ts) == i2. # Intended to be used after not self.less(other) is known, in which # case it will return at least one witnessing tab size. def not_less_witness(self, other): """ Public method to calculate a tuple of witnessing tab size. Intended to be used after not self.less(other is known, in which case it will return at least one witnessing tab size. @param other Whitespace object to calculate against. @return A list of tuples (ts, i1, i2) such that i1 == self.indent_level(ts) >= other.indent_level(ts) == i2. """ n = max(self.longest_run_of_spaces(), other.longest_run_of_spaces()) + 1 a = [] for ts in range(1, n + 1): if self.indent_level(ts) >= other.indent_level(ts): a.append((ts, self.indent_level(ts), other.indent_level(ts))) return a def format_witnesses(w): """ Function to format the witnesses as a readable string. @param w A list of witnesses @return A formated string of the witnesses. """ firsts = [str(tup[0]) for tup in w] prefix = "at tab size" if len(w) > 1: prefix = prefix + "s" return prefix + " " + ', '.join(firsts) def process_tokens(tokens): """ Function processing all tokens generated by a tokenizer run. @param tokens list of tokens @exception NannyNag raised to indicate an indentation error """ INDENT = tokenize.INDENT DEDENT = tokenize.DEDENT NEWLINE = tokenize.NEWLINE JUNK = tokenize.COMMENT, tokenize.NL indents = [Whitespace("")] check_equal = 0 for (type, token, start, end, line) in tokens: if type == NEWLINE: # a program statement, or ENDMARKER, will eventually follow, # after some (possibly empty) run of tokens of the form # (NL | COMMENT)* (INDENT | DEDENT+)? # If an INDENT appears, setting check_equal is wrong, and will # be undone when we see the INDENT. check_equal = 1 elif type == INDENT: check_equal = 0 thisguy = Whitespace(token) if not indents[-1].less(thisguy): witness = indents[-1].not_less_witness(thisguy) msg = "indent not greater e.g. " + format_witnesses(witness) raise NannyNag(start[0], msg, line) indents.append(thisguy) elif type == DEDENT: # there's nothing we need to check here! what's important is # that when the run of DEDENTs ends, the indentation of the # program statement (or ENDMARKER) that triggered the run is # equal to what's left at the top of the indents stack # Ouch! This assert triggers if the last line of the source # is indented *and* lacks a newline -- then DEDENTs pop out # of thin air. # assert check_equal # else no earlier NEWLINE, or an # earlier INDENT check_equal = 1 del indents[-1] elif check_equal and type not in JUNK: # this is the first "real token" following a NEWLINE, so it # must be the first token of the next program statement, or an # ENDMARKER; the "line" argument exposes the leading whitespace # for this statement; in the case of ENDMARKER, line is an empty # string, so will properly match the empty string with which the # "indents" stack was seeded check_equal = 0 thisguy = Whitespace(line) if not indents[-1].equal(thisguy): witness = indents[-1].not_equal_witness(thisguy) msg = "indent not equal e.g. " + format_witnesses(witness) raise NannyNag(start[0], msg, line) eric-6.0.8/eric/Plugins/CheckerPlugins/Tabnanny/TabnannyDialog.ui0000644000175000017500000001146712253117350024007 0ustar piotrpiotr TabnannyDialog 0 0 650 400 Tabnanny Result <b>Tabnanny Results</b> <p>This dialog shows the results of the tabnanny command. Double clicking an entry will open an editor window and position the cursor at the respective line.</p> true QFrame::NoFrame QFrame::Raised 0 Exclude Files: Enter filename patterns of files to be excluded separated by a comma 2 Qt::Vertical Press to start the tabnanny run Start <b>Result List</b> <p>This list shows the results of the tabnanny command. Double clicking an entry will open this entry in an editor window and position the cursor at the respective line.</p> true false false true Filename # Source 0 0 Shows the progress of the tabnanny action 0 Qt::Horizontal %v/%m Files Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource E5SqueezeLabelPath QLabel
E5Gui/E5SqueezeLabels.h
E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
startButton excludeFilesEdit resultList buttonBox
eric-6.0.8/eric/Plugins/CheckerPlugins/__init__.py0000644000175000017500000000024112451233370021102 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the various core checker plugins. """ eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/0000755000175000017500000000000012557365404022167 5ustar piotrpiotreric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.ui0000644000175000017500000003751012474634043027030 0ustar piotrpiotr CodeStyleCheckerDialog 0 0 650 700 Code Style Check Result <b>Code Style Check Results</b> <p>This dialog shows the results of the code style check. Double clicking an entry will open an editor window and position the cursor at the respective line and position.</p> true QFrame::NoFrame 0 0 0 0 Exclude Files: Enter filename patterns of files to be excluded separated by a comma 2 Qt::Vertical Press to start the code style check run Start Press to fix the selected issues Fix Selected Qt::Vertical 20 18 Press to load the default values Load Defaults Press to store the current values as defaults Store Defaults Press to reset the default values Reset Defaults Exclude Messages: Enter message codes or categories to be excluded separated by a comma Press to select the message codes from a list Included Messages: Enter message codes or categories to be included separated by a comma Press to select the message codes from a list Fix Issues: Enter message codes of issues to be fixed automatically (leave empty to fix all) Press to select the message codes from a list Don't Fix Issues: Enter message codes of issues not to be fixed automatically Press to select the message codes from a list Max. Line Length: Enter the maximum allowed line length (PEP-8: 79 characters) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 60 119 79 Qt::Horizontal 40 20 Docstring Type: Select the rule set for docstrings Qt::Horizontal 40 20 Select to allow hanging closing brackets Allow hanging closing brackets Qt::Horizontal 40 20 Select to repeat each message type Repeat messages false Select to fix some issues Fix issues automatically false Select to show ignored issues Show ignored Qt::Horizontal 40 20 <b>Result List</b> <p>This list shows the results of the code style check. Double clicking an entry will open this entry in an editor window and position the cursor at the respective line and position.</p> true QAbstractItemView::ExtendedSelection true File/Line Code Message 0 0 Shows the progress of the code style check 0 Qt::Horizontal %v/%m Files Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource E5SqueezeLabelPath QLabel
E5Gui/E5SqueezeLabels.h
E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
startButton loadDefaultButton excludeFilesEdit excludeMessagesEdit excludeMessagesSelectButton includeMessagesEdit includeMessagesSelectButton fixIssuesEdit fixIssuesSelectButton noFixIssuesEdit noFixIssuesSelectButton lineLengthSpinBox docTypeComboBox hangClosingCheckBox repeatCheckBox fixIssuesCheckBox ignoredCheckBox resultList fixButton storeDefaultButton resetDefaultButton buttonBox repeatCheckBox toggled(bool) fixIssuesCheckBox setEnabled(bool) 132 286 343 286 repeatCheckBox toggled(bool) ignoredCheckBox setEnabled(bool) 138 269 380 271
eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.ui0000644000175000017500000000533212320026140027572 0ustar piotrpiotr CodeStyleStatisticsDialog 0 0 531 372 Code Style Checker Statistics true false true Count Code Message Qt::Horizontal QDialogButtonBox::Close statisticsList buttonBox buttonBox accepted() CodeStyleStatisticsDialog accept() 248 254 157 274 buttonBox rejected() CodeStyleStatisticsDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleFixer.py0000644000175000017500000030420212475122730025423 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a class to fix certain code style issues. """ from __future__ import unicode_literals try: # Python 2 from StringIO import StringIO # __IGNORE_EXCEPTION__ except ImportError: # Python 3 from io import StringIO # __IGNORE_WARNING__ import os import re import tokenize # CodeStyleCheckerDialog tries to import FixableCodeStyleIssues what fail under # Python3. So ignore it. try: import pep8 except ImportError: pass FixableCodeStyleIssues = [ "D111", "D112", "D113", "D121", "D131", "D141", "D142", "D143", "D144", "D145", "D221", "D222", "D231", "D242", "D243", "D244", "D245", "D246", "D247", "E101", "E111", "E121", "E122", "E123", "E124", "E125", "E126", "E127", "E128", "E133", "E201", "E202", "E203", "E211", "E221", "E222", "E223", "E224", "E225", "E226", "E227", "E228", "E231", "E241", "E242", "E251", "E261", "E262", "E271", "E272", "E273", "E274", "E301", "E302", "E303", "E304", "E401", "E501", "E502", "E701", "E702", "E703", "E711", "E712", "N804", "N805", "N806", "W191", "W291", "W292", "W293", "W391", "W603", ] class CodeStyleFixer(object): """ Class implementing a fixer for certain code style issues. """ def __init__(self, filename, sourceLines, fixCodes, noFixCodes, maxLineLength, inPlace, eol, backup=False): """ Constructor @param filename name of the file to be fixed (string) @param sourceLines list of source lines including eol marker (list of string) @param fixCodes list of codes to be fixed as a comma separated string (string) @param noFixCodes list of codes not to be fixed as a comma separated string (string) @param maxLineLength maximum allowed line length (integer) @param inPlace flag indicating to modify the file in place (boolean) @param eol end of line character(s) (string) @param backup flag indicating to create a backup before fixing anything (boolean) """ super(CodeStyleFixer, self).__init__() self.__filename = filename self.__origName = "" self.__source = sourceLines[:] # save a copy self.__fixCodes = [c.strip() for c in fixCodes.split(",") if c.strip()] self.__noFixCodes = [ c.strip() for c in noFixCodes.split(",") if c.strip()] self.__maxLineLength = maxLineLength self.fixed = 0 self.__reindenter = None self.__indentWord = self.__getIndentWord() if inPlace: self.__createBackup = backup else: self.__origName = self.__filename self.__filename = os.path.join( os.path.dirname(self.__filename), "fixed_" + os.path.basename(self.__filename)) self.__createBackup = False self.__eol = eol self.__fixes = { "D111": self.__fixD111, "D112": self.__fixD112, "D113": self.__fixD112, "D121": self.__fixD121, "D131": self.__fixD131, "D141": self.__fixD141, "D142": self.__fixD142, "D143": self.__fixD143, "D144": self.__fixD144, "D145": self.__fixD145, "D221": self.__fixD221, "D222": self.__fixD221, "D231": self.__fixD131, "D242": self.__fixD242, "D243": self.__fixD243, "D244": self.__fixD242, "D245": self.__fixD243, "D246": self.__fixD144, "D247": self.__fixD247, "E101": self.__fixE101, "E111": self.__fixE101, "E121": self.__fixE121, "E122": self.__fixE122, "E123": self.__fixE123, "E124": self.__fixE121, "E125": self.__fixE125, "E126": self.__fixE126, "E127": self.__fixE127, "E128": self.__fixE127, "E133": self.__fixE126, "E201": self.__fixE201, "E202": self.__fixE201, "E203": self.__fixE201, "E211": self.__fixE201, "E221": self.__fixE221, "E222": self.__fixE221, "E223": self.__fixE221, "E224": self.__fixE221, "E225": self.__fixE221, "E226": self.__fixE221, "E227": self.__fixE221, "E228": self.__fixE221, "E231": self.__fixE231, "E241": self.__fixE221, "E242": self.__fixE221, "E251": self.__fixE251, "E261": self.__fixE261, "E262": self.__fixE261, "E271": self.__fixE221, "E272": self.__fixE221, "E273": self.__fixE221, "E274": self.__fixE221, "E301": self.__fixE301, "E302": self.__fixE302, "E303": self.__fixE303, "E304": self.__fixE304, "E401": self.__fixE401, "E501": self.__fixE501, "E502": self.__fixE502, "E701": self.__fixE701, "E702": self.__fixE702, "E703": self.__fixE702, "E711": self.__fixE711, "E712": self.__fixE711, "N804": self.__fixN804, "N805": self.__fixN804, "N806": self.__fixN806, "W191": self.__fixE101, "W291": self.__fixW291, "W292": self.__fixW292, "W293": self.__fixW291, "W391": self.__fixW391, "W603": self.__fixW603, } self.__modified = False self.__stackLogical = [] # These need to be fixed before the file is saved but after all # other inline fixes. These work with logical lines. self.__stack = [] # These need to be fixed before the file is saved but after all # inline fixes. self.__multiLineNumbers = None self.__docLineNumbers = None self.__lastID = 0 def saveFile(self, encoding): """ Public method to save the modified file. @param encoding encoding of the source file (string) @return error message on failure (tuple of str) """ import codecs if not self.__modified: # no need to write return if self.__createBackup: # create a backup file before writing any changes if os.path.islink(self.__filename): bfn = '{0}~'.format(os.path.realpath(self.__filename)) else: bfn = '{0}~'.format(self.__filename) try: os.remove(bfn) except EnvironmentError: # if there was an error, ignore it pass try: os.rename(self.__filename, bfn) except EnvironmentError: # if there was an error, ignore it pass txt = "".join(self.__source) try: enc = 'utf-8' if encoding == 'utf-8-bom' else encoding txt = txt.encode(enc) if encoding == 'utf-8-bom': txt = codecs.BOM_UTF8 + txt with open(self.__filename, "wb") as fp: fp.write(txt) except (IOError, UnicodeError) as err: # Could not save the file! Skipping it. Reason: {0} return ("FWRITE_ERROR", (str(err),)) return def __codeMatch(self, code): """ Private method to check, if the code should be fixed. @param code to check (string) @return flag indicating it should be fixed (boolean) """ def mutualStartswith(a, b): """ Local helper method to compare the beginnings of two strings against each other. @return flag indicating that one string starts with the other (boolean) """ return b.startswith(a) or a.startswith(b) if self.__noFixCodes: for noFixCode in [c.strip() for c in self.__noFixCodes]: if mutualStartswith(code.lower(), noFixCode.lower()): return False if self.__fixCodes: for fixCode in [c.strip() for c in self.__fixCodes]: if mutualStartswith(code.lower(), fixCode.lower()): return True return False return True def fixIssue(self, line, pos, message): """ Public method to fix the fixable issues. @param line line number of issue (integer) @param pos character position of issue (integer) @param message message text (string) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if isinstance(message, (tuple, list)): code = message[0].strip() else: code = message.split(None, 1)[0].strip() if line <= len(self.__source) and \ self.__codeMatch(code) and \ code in self.__fixes: res = self.__fixes[code](code, line, pos) if res[0] == 1: self.__modified = True self.fixed += 1 else: res = (0, "", 0) return res def finalize(self): """ Public method to apply all deferred fixes. @return dictionary containing the fix results """ results = {} # step 1: do fixes operating on logical lines first for id_, code, line, pos in self.__stackLogical: res, msg, _ = self.__fixes[code](code, line, pos, apply=True) if res == 1: self.__modified = True self.fixed += 1 results[id_] = (res, msg) # step 2: do fixes that change the number of lines for id_, code, line, pos in reversed(self.__stack): res, msg, _ = self.__fixes[code](code, line, pos, apply=True) if res == 1: self.__modified = True self.fixed += 1 results[id_] = (res, msg) return results def __getID(self): """ Private method to get the ID for a deferred fix. @return ID for a deferred fix (integer) """ self.__lastID += 1 return self.__lastID def __findLogical(self): """ Private method to extract the index of all the starts and ends of lines. @return tuple containing two lists of integer with start and end tuples of lines """ logical_start = [] logical_end = [] last_newline = True sio = StringIO("".join(self.__source)) parens = 0 for t in tokenize.generate_tokens(sio.readline): if t[0] in [tokenize.COMMENT, tokenize.DEDENT, tokenize.INDENT, tokenize.NL, tokenize.ENDMARKER]: continue if not parens and t[0] in [tokenize.NEWLINE, tokenize.SEMI]: last_newline = True logical_end.append((t[3][0] - 1, t[2][1])) continue if last_newline and not parens: logical_start.append((t[2][0] - 1, t[2][1])) last_newline = False if t[0] == tokenize.OP: if t[1] in '([{': parens += 1 elif t[1] in '}])': parens -= 1 return logical_start, logical_end def __getLogical(self, line, pos): """ Private method to get the logical line corresponding to the given position. @param line line number of the issue (integer) @param pos position inside line (integer) @return tuple of a tuple of two integers giving the start of the logical line, another tuple of two integers giving the end of the logical line and a list of strings with the original source lines """ try: (logical_start, logical_end) = self.__findLogical() except (SyntaxError, tokenize.TokenError): return None line = line - 1 ls = None le = None for i in range(0, len(logical_start)): x = logical_end[i] if x[0] > line or (x[0] == line and x[1] > pos): le = x ls = logical_start[i] break if ls is None: return None original = self.__source[ls[0]:le[0] + 1] return ls, le, original def __getIndentWord(self): """ Private method to determine the indentation type. @return string to be used for an indentation (string) """ sio = StringIO("".join(self.__source)) indentWord = " " # default in case of failure try: for token in tokenize.generate_tokens(sio.readline): if token[0] == tokenize.INDENT: indentWord = token[1] break except (SyntaxError, tokenize.TokenError): pass return indentWord def __getIndent(self, line): """ Private method to get the indentation string. @param line line to determine the indentation string from (string) @return indentation string (string) """ return line.replace(line.lstrip(), "") def __multilineStringLines(self): """ Private method to determine the line numbers that are within multi line strings and these which are part of a documentation string. @return tuple of a set of line numbers belonging to a multi line string and a set of line numbers belonging to a multi line documentation string (tuple of two set of integer) """ if self.__multiLineNumbers is None: source = "".join(self.__source) sio = StringIO(source) self.__multiLineNumbers = set() self.__docLineNumbers = set() previousTokenType = '' try: for t in tokenize.generate_tokens(sio.readline): tokenType = t[0] startRow = t[2][0] endRow = t[3][0] if (tokenType == tokenize.STRING and startRow != endRow): if previousTokenType != tokenize.INDENT: self.__multiLineNumbers |= set( range(startRow, 1 + endRow)) else: self.__docLineNumbers |= set( range(startRow, 1 + endRow)) previousTokenType = tokenType except (SyntaxError, tokenize.TokenError): pass return self.__multiLineNumbers, self.__docLineNumbers def __fixReindent(self, line, pos, logical): """ Private method to fix a badly indented line. This is done by adding or removing from its initial indent only. @param line line number of the issue (integer) @param pos position inside line (integer) @param logical logical line structure @return flag indicating a change was done (boolean) """ assert logical ls, _, original = logical rewrapper = IndentationWrapper(original) valid_indents = rewrapper.pep8Expected() if not rewrapper.rel_indent: return False if line > ls[0]: # got a valid continuation line number row = line - ls[0] - 1 # always pick the first option for this valid = valid_indents[row] got = rewrapper.rel_indent[row] else: return False line1 = ls[0] + row # always pick the expected indent, for now. indent_to = valid[0] if got != indent_to: orig_line = self.__source[line1] new_line = ' ' * (indent_to) + orig_line.lstrip() if new_line == orig_line: return False else: self.__source[line1] = new_line return True else: return False def __fixWhitespace(self, line, offset, replacement): """ Private method to correct whitespace at the given offset. @param line line to be corrected (string) @param offset offset within line (integer) @param replacement replacement string (string) @return corrected line """ left = line[:offset].rstrip(" \t") right = line[offset:].lstrip(" \t") if right.startswith("#"): return line else: return left + replacement + right def __fixD111(self, code, line, pos): """ Private method to fix docstring enclosed in wrong quotes. Codes: D111 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 quotes = re.match(r"""\s*[ru]?('''|'|\")""", self.__source[line]).group(1) left, right = self.__source[line].split(quotes, 1) self.__source[line] = left + '"""' + right while line < len(self.__source): if self.__source[line].rstrip().endswith(quotes): left, right = self.__source[line].rsplit(quotes, 1) self.__source[line] = left + '"""' + right break line += 1 # Triple single quotes converted to triple double quotes. return (1, "FD111", 0) def __fixD112(self, code, line, pos): """ Private method to fix docstring 'r' or 'u' in leading quotes. Codes: D112, D113 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 if code == "D112": insertChar = "r" elif code == "D113": insertChar = "u" else: return (0, "", 0) newText = self.__getIndent(self.__source[line]) + \ insertChar + self.__source[line].lstrip() self.__source[line] = newText # Introductory quotes corrected to be {0}""" return (1, ('FD112', (insertChar,)), 0) def __fixD121(self, code, line, pos, apply=False): """ Private method to fix a single line docstring on multiple lines. Codes: D121 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 if not self.__source[line].lstrip().startswith( ('"""', 'r"""', 'u"""')): # only correctly formatted docstrings will be fixed return (0, "", 0) docstring = self.__source[line].rstrip() + \ self.__source[line + 1].strip() if docstring.endswith('"""'): docstring += self.__eol else: docstring += self.__source[line + 2].lstrip() self.__source[line + 2] = "" self.__source[line] = docstring self.__source[line + 1] = "" # Single line docstring put on one line. return (1, "FD121", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD131(self, code, line, pos): """ Private method to fix a docstring summary not ending with a period. Codes: D131 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 newText = "" if self.__source[line].rstrip().endswith(('"""', "'''")) and \ self.__source[line].lstrip().startswith(('"""', 'r"""', 'u"""')): # it is a one-liner newText = self.__source[line].rstrip()[:-3].rstrip() + "." + \ self.__source[line].rstrip()[-3:] + self.__eol else: if line < len(self.__source) - 1 and \ (not self.__source[line + 1].strip() or self.__source[line + 1].lstrip().startswith("@") or (self.__source[line + 1].strip() in ('"""', "'''") and not self.__source[line].lstrip().startswith("@"))): newText = self.__source[line].rstrip() + "." + self.__eol if newText: self.__source[line] = newText # Period added to summary line. return (1, "FD131", 0) else: return (0, "", 0) def __fixD141(self, code, line, pos, apply=False): """ Private method to fix a function/method docstring preceded by a blank line. Codes: D141 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 self.__source[line - 1] = "" # Blank line before function/method docstring removed. return (1, "FD141", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD142(self, code, line, pos, apply=False): """ Private method to fix a class docstring not preceded by a blank line. Codes: D142 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 self.__source[line] = self.__eol + self.__source[line] # Blank line inserted before class docstring. return (1, "FD142", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD143(self, code, line, pos, apply=False): """ Private method to fix a class docstring not followed by a blank line. Codes: D143 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 self.__source[line] += self.__eol # Blank line inserted after class docstring. return (1, "FD143", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD144(self, code, line, pos, apply=False): """ Private method to fix a docstring summary not followed by a blank line. Codes: D144 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 if not self.__source[line].rstrip().endswith("."): # only correct summary lines can be fixed here return (0, "", 0) self.__source[line] += self.__eol # Blank line inserted after docstring summary. return (1, "FD144", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD145(self, code, line, pos, apply=False): """ Private method to fix the last paragraph of a multi-line docstring not followed by a blank line. Codes: D143 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 self.__source[line] = self.__eol + self.__source[line] # Blank line inserted after last paragraph of docstring. return (1, "FD145", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD221(self, code, line, pos, apply=False): """ Private method to fix leading and trailing quotes of docstring not on separate lines. Codes: D221, D222 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 indent = self.__getIndent(self.__source[line]) source = self.__source[line].strip() if code == "D221": # leading if source.startswith(("r", "u")): first, second = source[:4], source[4:].strip() else: first, second = source[:3], source[3:].strip() else: # trailing first, second = source[:-3].strip(), source[-3:] newText = indent + first + self.__eol + \ indent + second + self.__eol self.__source[line] = newText if code == "D221": # Leading quotes put on separate line. msg = "FD221" else: # Trailing quotes put on separate line. msg = "FD222" return (1, msg, 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD242(self, code, line, pos, apply=False): """ Private method to fix a class or function/method docstring preceded by a blank line. Codes: D242, D244 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 self.__source[line - 1] = "" if code == "D242": # Blank line before class docstring removed. msg = "FD242" else: # Blank line before function/method docstring removed. msg = "FD244" return (1, msg, 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD243(self, code, line, pos, apply=False): """ Private method to fix a class or function/method docstring followed by a blank line. Codes: D243, D245 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 self.__source[line + 1] = "" if code == "D243": # Blank line after class docstring removed. msg = "FD243" else: # Blank line after function/method docstring removed. msg = "FD245" return (1, msg, 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixD247(self, code, line, pos, apply=False): """ Private method to fix a last paragraph of a docstring followed by a blank line. Codes: D247 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 self.__source[line - 1] = "" # Blank line after last paragraph removed. return (1, "FD247", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE101(self, code, line, pos): """ Private method to fix obsolete tab usage and indentation errors. Codes: E101, E111, W191 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if self.__reindenter is None: self.__reindenter = Reindenter(self.__source) self.__reindenter.run() fixedLine = self.__reindenter.fixedLine(line - 1) if fixedLine is not None and fixedLine != self.__source[line - 1]: self.__source[line - 1] = fixedLine if code in ["E101", "W191"]: # Tab converted to 4 spaces. msg = "FE101" else: # Indentation adjusted to be a multiple of four. msg = "FE111" return (1, msg, 0) else: return (0, "", 0) def __fixE121(self, code, line, pos, apply=False): """ Private method to fix the indentation of continuation lines and closing brackets. Codes: E121, E124 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: logical = self.__getLogical(line, pos) if logical: # Fix by adjusting initial indent level. changed = self.__fixReindent(line, pos, logical) if changed: if code == "E121": # Indentation of continuation line corrected. msg = "FE121" elif code == "E124": # Indentation of closing bracket corrected. msg = "FE124" return (1, msg, 0) return (0, "", 0) else: id = self.__getID() self.__stackLogical.append((id, code, line, pos)) return (-1, "", id) def __fixE122(self, code, line, pos, apply=False): """ Private method to fix a missing indentation of continuation lines. Codes: E122 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: logical = self.__getLogical(line, pos) if logical: # Fix by adding an initial indent. modified = self.__fixReindent(line, pos, logical) if not modified: # fall back to simple method line = line - 1 text = self.__source[line] indentation = self.__getIndent(text) self.__source[line] = indentation + \ self.__indentWord + text.lstrip() # Missing indentation of continuation line corrected. return (1, "FE122", 0) return (0, "", 0) else: id = self.__getID() self.__stackLogical.append((id, code, line, pos)) return (-1, "", id) def __fixE123(self, code, line, pos, apply=False): """ Private method to fix the indentation of a closing bracket lines. Codes: E123 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: logical = self.__getLogical(line, pos) if logical: # Fix by deleting whitespace to the correct level. logicalLines = logical[2] row = line - 1 text = self.__source[row] newText = self.__getIndent(logicalLines[0]) + text.lstrip() if newText == text: # fall back to slower method changed = self.__fixReindent(line, pos, logical) else: self.__source[row] = newText changed = True if changed: # Closing bracket aligned to opening bracket. return (1, "FE123", 0) return (0, "", 0) else: id = self.__getID() self.__stackLogical.append((id, code, line, pos)) return (-1, "", id) def __fixE125(self, code, line, pos, apply=False): """ Private method to fix the indentation of continuation lines not distinguishable from next logical line. Codes: E125 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: logical = self.__getLogical(line, pos) if logical: # Fix by adjusting initial indent level. modified = self.__fixReindent(line, pos, logical) if not modified: row = line - 1 text = self.__source[row] self.__source[row] = self.__getIndent(text) + \ self.__indentWord + text.lstrip() # Indentation level changed. return (1, "FE125", 0) return (0, "", 0) else: id = self.__getID() self.__stackLogical.append((id, code, line, pos)) return (-1, "", id) def __fixE126(self, code, line, pos, apply=False): """ Private method to fix over-indented/under-indented hanging indentation. Codes: E126, E133 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: logical = self.__getLogical(line, pos) if logical: # Fix by deleting whitespace to the left. logicalLines = logical[2] row = line - 1 text = self.__source[row] newText = self.__getIndent(logicalLines[0]) + \ self.__indentWord + text.lstrip() if newText == text: # fall back to slower method changed = self.__fixReindent(line, pos, logical) else: self.__source[row] = newText changed = True if changed: # Indentation level of hanging indentation changed. return (1, "FE126", 0) return (0, "", 0) else: id = self.__getID() self.__stackLogical.append((id, code, line, pos)) return (-1, "", id) def __fixE127(self, code, line, pos, apply=False): """ Private method to fix over/under indented lines. Codes: E127, E128 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: logical = self.__getLogical(line, pos) if logical: # Fix by inserting/deleting whitespace to the correct level. logicalLines = logical[2] row = line - 1 text = self.__source[row] newText = text if logicalLines[0].rstrip().endswith('\\'): newText = self.__getIndent(logicalLines[0]) + \ self.__indentWord + text.lstrip() else: startIndex = None for symbol in '([{': if symbol in logicalLines[0]: foundIndex = logicalLines[0].find(symbol) + 1 if startIndex is None: startIndex = foundIndex else: startIndex = min(startIndex, foundIndex) if startIndex is not None: newText = startIndex * ' ' + text.lstrip() if newText == text: # fall back to slower method changed = self.__fixReindent(line, pos, logical) else: self.__source[row] = newText changed = True if changed: # Visual indentation corrected. return (1, "FE127", 0) return (0, "", 0) else: id = self.__getID() self.__stackLogical.append((id, code, line, pos)) return (-1, "", id) def __fixE201(self, code, line, pos): """ Private method to fix extraneous whitespace. Codes: E201, E202, E203, E211 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 text = self.__source[line] if '"""' in text or "'''" in text or text.rstrip().endswith('\\'): return (0, "", 0) newText = self.__fixWhitespace(text, pos, '') if newText == text: return (0, "", 0) self.__source[line] = newText # Extraneous whitespace removed. return (1, "FE201", 0) def __fixE221(self, code, line, pos): """ Private method to fix extraneous whitespace around operator or keyword. Codes: E221, E222, E223, E224, E225, E226, E227, E228, E241, E242, E271, E272, E273, E274). @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 text = self.__source[line] if '"""' in text or "'''" in text or text.rstrip().endswith('\\'): return (0, "", 0) newText = self.__fixWhitespace(text, pos, ' ') if newText == text: return (0, "", 0) self.__source[line] = newText if code in ["E225", "E226", "E227", "E228"]: # Missing whitespace added. return (1, "", 0) else: # Extraneous whitespace removed. return (1, "", 0) def __fixE231(self, code, line, pos): """ Private method to fix missing whitespace after ',;:'. Codes: E231 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 pos = pos + 1 self.__source[line] = self.__source[line][:pos] + \ " " + self.__source[line][pos:] # Missing whitespace added. return (1, "FE231", 0) def __fixE251(self, code, line, pos): """ Private method to fix extraneous whitespace around keyword and default parameter equals. Codes: E251 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 text = self.__source[line] # This is necessary since pep8 sometimes reports columns that goes # past the end of the physical line. This happens in cases like, # foo(bar\n=None) col = min(pos, len(text) - 1) if text[col].strip(): newText = text else: newText = text[:col].rstrip() + text[col:].lstrip() # There could be an escaped newline # # def foo(a=\ # 1) if newText.endswith(('=\\\n', '=\\\r\n', '=\\\r')): self.__source[line] = newText.rstrip("\n\r \t\\") self.__source[line + 1] = self.__source[line + 1].lstrip() else: self.__source[line] = newText # Extraneous whitespace removed. return (1, "FE251", 0) def __fixE261(self, code, line, pos): """ Private method to fix whitespace before or after inline comment. Codes: E261, E262 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 text = self.__source[line] left = text[:pos].rstrip(' \t#') right = text[pos:].lstrip(' \t#') newText = left + (" # " + right if right.strip() else right) self.__source[line] = newText # Whitespace around comment sign corrected. return (1, "FE261", 0) def __fixE301(self, code, line, pos, apply=False): """ Private method to fix the need for one blank line. Codes: E301 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: self.__source.insert(line - 1, self.__eol) # One blank line inserted. return (1, "FE301", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE302(self, code, line, pos, apply=False): """ Private method to fix the need for two blank lines. Codes: E302 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: # count blank lines index = line - 1 blanks = 0 while index: if self.__source[index - 1].strip() == "": blanks += 1 index -= 1 else: break delta = blanks - 2 line -= 1 if delta < 0: # insert blank lines (one or two) while delta < 0: self.__source.insert(line, self.__eol) delta += 1 # %n blank line(s) inserted. return (1, ("FE302+", 2 - blanks), 0) elif delta > 0: # delete superfluous blank lines while delta > 0: del self.__source[line - 1] line -= 1 delta -= 1 # %n superfluous line(s) removed. return (1, ("FE302-", blanks - 2), 0) else: return (0, "", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE303(self, code, line, pos, apply=False): """ Private method to fix superfluous blank lines. Codes: E303 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: index = line - 3 while index: if self.__source[index].strip() == "": del self.__source[index] index -= 1 else: break # Superfluous blank lines removed. return (1, "FE303", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE304(self, code, line, pos, apply=False): """ Private method to fix superfluous blank lines after a function decorator. Codes: E304 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: index = line - 2 while index: if self.__source[index].strip() == "": del self.__source[index] index -= 1 else: break # Superfluous blank lines after function decorator removed. return (1, "FE304", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE401(self, code, line, pos, apply=False): """ Private method to fix multiple imports on one line. Codes: E401 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 text = self.__source[line] if not text.lstrip().startswith("import"): return (0, "", 0) # pep8 (1.3.1) reports false positive if there is an import # statement followed by a semicolon and some unrelated # statement with commas in it. if ';' in text: return (0, "", 0) newText = text[:pos].rstrip("\t ,") + self.__eol + \ self.__getIndent(text) + "import " + text[pos:].lstrip("\t ,") self.__source[line] = newText # Imports were put on separate lines. return (1, "FE401", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE501(self, code, line, pos, apply=False): """ Private method to fix the long lines by breaking them. Codes: E501 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: multilineStringLines, docStringLines = \ self.__multilineStringLines() isDocString = line in docStringLines line = line - 1 text = self.__source[line] if line > 0: prevText = self.__source[line - 1] else: prevText = "" if line < len(self.__source) - 1: nextText = self.__source[line + 1] else: nextText = "" shortener = LineShortener( text, prevText, nextText, maxLength=self.__maxLineLength, eol=self.__eol, indentWord=self.__indentWord, isDocString=isDocString) changed, newText, newNextText = shortener.shorten() if changed: if newText != text: self.__source[line] = newText if newNextText and newNextText != nextText: if newNextText == " ": newNextText = "" self.__source[line + 1] = newNextText # Long lines have been shortened. return (1, "FE501", 0) else: return (0, "", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE502(self, code, line, pos): """ Private method to fix redundant backslash within brackets. Codes: E502 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ self.__source[line - 1] = \ self.__source[line - 1].rstrip("\n\r \t\\") + self.__eol # Redundant backslash in brackets removed. return (1, "FE502", 0) def __fixE701(self, code, line, pos, apply=False): """ Private method to fix colon-separated compound statements. Codes: E701 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 text = self.__source[line] pos = pos + 1 newText = text[:pos] + self.__eol + self.__getIndent(text) + \ self.__indentWord + text[pos:].lstrip("\n\r \t\\") + \ self.__eol self.__source[line] = newText # Compound statement corrected. return (1, "FE701", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE702(self, code, line, pos, apply=False): """ Private method to fix semicolon-separated compound statements. Codes: E702, E703 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 text = self.__source[line] if text.rstrip().endswith("\\"): # normalize '1; \\\n2' into '1; 2' self.__source[line] = text.rstrip("\n\r \t\\") self.__source[line + 1] = self.__source[line + 1].lstrip() elif text.rstrip().endswith(";"): self.__source[line] = text.rstrip("\n\r \t;") + self.__eol else: first = text[:pos].rstrip("\n\r \t;") + self.__eol second = text[pos:].lstrip("\n\r \t;") self.__source[line] = first + self.__getIndent(text) + second # Compound statement corrected. return (1, "FE702", 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixE711(self, code, line, pos): """ Private method to fix comparison with None. Codes: E711, E712 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ line = line - 1 text = self.__source[line] rightPos = pos + 2 if rightPos >= len(text): return (0, "", 0) left = text[:pos].rstrip() center = text[pos:rightPos] right = text[rightPos:].lstrip() if not right.startswith(("None", "True", "False")): return (0, "", 0) if center.strip() == "==": center = "is" elif center.strip() == "!=": center = "is not" else: return (0, "", 0) self.__source[line] = " ".join([left, center, right]) # Comparison to None/True/False corrected. return (1, "FE711", 0) def __fixN804(self, code, line, pos, apply=False): """ Private method to fix a wrong first argument of normal and class methods. Codes: N804, N805 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 text = self.__source[line] if code == "N804": arg = "cls" else: arg = "self" if text.rstrip().endswith("("): newText = text + self.__getIndent(text) + \ self.__indentWord + arg + "," + self.__eol else: index = text.find("(") + 1 left = text[:index] right = text[index:] if right.startswith(")"): center = arg else: center = arg + ", " newText = left + center + right self.__source[line] = newText # '{0}' argument added. return (1, ("FN804", (arg,)), 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixN806(self, code, line, pos, apply=False): """ Private method to fix a wrong first argument of static methods. Codes: N806 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @keyparam apply flag indicating, that the fix should be applied (boolean) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ if apply: line = line - 1 text = self.__source[line] index = text.find("(") + 1 left = text[:index] right = text[index:] if right.startswith(("cls", "self")): # cls or self are on the definition line if right.startswith("cls"): right = right[3:] arg = "cls" else: right = right[4:] arg = "self" right = right.lstrip(", ") newText = left + right self.__source[line] = newText else: # they are on the next line line = line + 1 text = self.__source[line] indent = self.__getIndent(text) right = text.lstrip() if right.startswith("cls"): right = right[3:] arg = "cls" else: right = right[4:] arg = "self" right = right.lstrip(", ") if right.startswith("):"): # merge with previous line self.__source[line - 1] = \ self.__source[line - 1].rstrip() + right self.__source[line] = "" else: self.__source[line] = indent + right # '{0}' argument removed. return (1, ("FN806", arg), 0) else: id = self.__getID() self.__stack.append((id, code, line, pos)) return (-1, "", id) def __fixW291(self, code, line, pos): """ Private method to fix trailing whitespace. Codes: W291, W293 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ self.__source[line - 1] = re.sub(r'[\t ]+(\r?)$', r"\1", self.__source[line - 1]) # Whitespace stripped from end of line. return (1, "FW291", 0) def __fixW292(self, code, line, pos): """ Private method to fix a missing newline at the end of file. Codes: W292 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ self.__source[line - 1] += self.__eol # newline added to end of file. return (1, "FW292", 0) def __fixW391(self, code, line, pos): """ Private method to fix trailing blank lines. Codes: W391 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ index = line - 1 while index: if self.__source[index].strip() == "": del self.__source[index] index -= 1 else: break # Superfluous trailing blank lines removed from end of file. return (1, "FW391", 0) def __fixW603(self, code, line, pos): """ Private method to fix the not equal notation. Codes: W603 @param code code of the issue (string) @param line line number of the issue (integer) @param pos position inside line (integer) @return value indicating an applied/deferred fix (-1, 0, 1), a message for the fix (string) and an ID for a deferred fix (integer) """ self.__source[line - 1] = self.__source[line - 1].replace("<>", "!=") # '<>' replaced by '!='. return (1, "FW603", 0) class Reindenter(object): """ Class to reindent badly-indented code to uniformly use four-space indentation. Released to the public domain, by Tim Peters, 03 October 2000. """ def __init__(self, sourceLines): """ Constructor @param sourceLines list of source lines including eol marker (list of string) """ # Raw file lines. self.raw = sourceLines self.after = [] # File lines, rstripped & tab-expanded. Dummy at start is so # that we can use tokenize's 1-based line numbering easily. # Note that a line is all-blank iff it's "\n". self.lines = [line.rstrip().expandtabs() + "\n" for line in self.raw] self.lines.insert(0, None) self.index = 1 # index into self.lines of next line # List of (lineno, indentlevel) pairs, one for each stmt and # comment line. indentlevel is -1 for comment lines, as a # signal that tokenize doesn't know what to do about them; # indeed, they're our headache! self.stats = [] def run(self): """ Public method to run the re-indenter. @return flag indicating that a change was done (boolean) """ try: stats = self.__genStats(tokenize.generate_tokens(self.getline)) except (SyntaxError, tokenize.TokenError): return False # Remove trailing empty lines. lines = self.lines while lines and lines[-1] == "\n": lines.pop() # Sentinel. stats.append((len(lines), 0)) # Map count of leading spaces to # we want. have2want = {} # Program after transformation. after = self.after = [] # Copy over initial empty lines -- there's nothing to do until # we see a line with *something* on it. i = stats[0][0] after.extend(lines[1:i]) for i in range(len(stats) - 1): thisstmt, thislevel = stats[i] nextstmt = stats[i + 1][0] have = self.__getlspace(lines[thisstmt]) want = thislevel * 4 if want < 0: # A comment line. if have: # An indented comment line. If we saw the same # indentation before, reuse what it most recently # mapped to. want = have2want.get(have, -1) if want < 0: # Then it probably belongs to the next real stmt. for j in range(i + 1, len(stats) - 1): jline, jlevel = stats[j] if jlevel >= 0: if have == self.__getlspace(lines[jline]): want = jlevel * 4 break if want < 0: # Maybe it's a hanging comment like this one, # in which case we should shift it like its base # line got shifted. for j in range(i - 1, -1, -1): jline, jlevel = stats[j] if jlevel >= 0: want = \ have + \ self.__getlspace(after[jline - 1]) - \ self.__getlspace(lines[jline]) break if want < 0: # Still no luck -- leave it alone. want = have else: want = 0 assert want >= 0 have2want[have] = want diff = want - have if diff == 0 or have == 0: after.extend(lines[thisstmt:nextstmt]) else: for line in lines[thisstmt:nextstmt]: if diff > 0: if line == "\n": after.append(line) else: after.append(" " * diff + line) else: remove = min(self.__getlspace(line), -diff) after.append(line[remove:]) return self.raw != self.after def fixedLine(self, line): """ Public method to get a fixed line. @param line number of the line to retrieve (integer) @return fixed line (string) """ if line < len(self.after): return self.after[line] def getline(self): """ Public method to get a line of text for tokenize. @return line of text (string) """ if self.index >= len(self.lines): line = "" else: line = self.lines[self.index] self.index += 1 return line def __genStats(self, tokens): """ Private method to generate the re-indent statistics. @param tokens tokens generator (tokenize._tokenize) @return reference to the generated statistics """ find_stmt = True # next token begins a fresh stmt? level = 0 # current indent level stats = [] for t in tokens: token_type = t[0] sline = t[2][0] line = t[4] if token_type == tokenize.NEWLINE: # A program statement, or ENDMARKER, will eventually follow, # after some (possibly empty) run of tokens of the form # (NL | COMMENT)* (INDENT | DEDENT+)? self.find_stmt = True elif token_type == tokenize.INDENT: find_stmt = True level += 1 elif token_type == tokenize.DEDENT: find_stmt = True level -= 1 elif token_type == tokenize.COMMENT: if find_stmt: stats.append((sline, -1)) # but we're still looking for a new stmt, so leave # find_stmt alone elif token_type == tokenize.NL: pass elif find_stmt: # This is the first "real token" following a NEWLINE, so it # must be the first token of the next program statement, or an # ENDMARKER. find_stmt = False if line: # not endmarker stats.append((sline, level)) return stats def __getlspace(self, line): """ Private method to count number of leading blanks. @param line line to check (string) @return number of leading blanks (integer) """ i = 0 n = len(line) while i < n and line[i] == " ": i += 1 return i class IndentationWrapper(object): """ Class used by fixers dealing with indentation. Each instance operates on a single logical line. """ SKIP_TOKENS = frozenset([ tokenize.COMMENT, tokenize.NL, tokenize.INDENT, tokenize.DEDENT, tokenize.NEWLINE, tokenize.ENDMARKER ]) def __init__(self, physical_lines): """ Constructor @param physical_lines list of physical lines to operate on (list of strings) """ self.lines = physical_lines self.tokens = [] self.rel_indent = None sio = StringIO(''.join(physical_lines)) for t in tokenize.generate_tokens(sio.readline): if not len(self.tokens) and t[0] in self.SKIP_TOKENS: continue if t[0] != tokenize.ENDMARKER: self.tokens.append(t) self.logical_line = self.__buildTokensLogical(self.tokens) def __buildTokensLogical(self, tokens): """ Private method to build a logical line from a list of tokens. @param tokens list of tokens as generated by tokenize.generate_tokens @return logical line (string) """ # from pep8.py with minor modifications logical = [] previous = None for t in tokens: token_type, text = t[0:2] if token_type in self.SKIP_TOKENS: continue if previous: end_line, end = previous[3] start_line, start = t[2] if end_line != start_line: # different row prev_text = self.lines[end_line - 1][end - 1] if prev_text == ',' or (prev_text not in '{[(' and text not in '}])'): logical.append(' ') elif end != start: # different column fill = self.lines[end_line - 1][end:start] logical.append(fill) logical.append(text) previous = t logical_line = ''.join(logical) assert logical_line.lstrip() == logical_line assert logical_line.rstrip() == logical_line return logical_line def pep8Expected(self): """ Public method to replicate logic in pep8.py, to know what level to indent things to. @return list of lists, where each list represents valid indent levels for the line in question, relative from the initial indent. However, the first entry is the indent level which was expected. """ # What follows is an adjusted version of # pep8.py:continuation_line_indentation. All of the comments have been # stripped and the 'yield' statements replaced with 'pass'. if not self.tokens: return first_row = self.tokens[0][2][0] nrows = 1 + self.tokens[-1][2][0] - first_row # here are the return values valid_indents = [list()] * nrows indent_level = self.tokens[0][2][1] valid_indents[0].append(indent_level) if nrows == 1: # bug, really. return valid_indents indent_next = self.logical_line.endswith(':') row = depth = 0 parens = [0] * nrows self.rel_indent = rel_indent = [0] * nrows indent = [indent_level] indent_chances = {} last_indent = (0, 0) last_token_multiline = None for token_type, text, start, end, line in self.tokens: newline = row < start[0] - first_row if newline: row = start[0] - first_row newline = (not last_token_multiline and token_type not in (tokenize.NL, tokenize.NEWLINE)) if newline: # This is where the differences start. Instead of looking at # the line and determining whether the observed indent matches # our expectations, we decide which type of indentation is in # use at the given indent level, and return the offset. This # algorithm is susceptible to "carried errors", but should # through repeated runs eventually solve indentation for # multiline expressions. if depth: for open_row in range(row - 1, -1, -1): if parens[open_row]: break else: open_row = 0 # That's all we get to work with. This code attempts to # "reverse" the below logic, and place into the valid indents # list vi = [] add_second_chances = False if token_type == tokenize.OP and text in ']})': # this line starts with a closing bracket, so it needs to # be closed at the same indent as the opening one. if indent[depth]: # hanging indent vi.append(indent[depth]) else: # visual indent vi.append(indent_level + rel_indent[open_row]) elif depth and indent[depth]: # visual indent was previously confirmed. vi.append(indent[depth]) add_second_chances = True elif depth and True in indent_chances.values(): # visual indent happened before, so stick to # visual indent this time. if depth > 1 and indent[depth - 1]: vi.append(indent[depth - 1]) else: # stupid fallback vi.append(indent_level + 4) add_second_chances = True elif not depth: vi.append(indent_level + 4) else: # must be in hanging indent hang = rel_indent[open_row] + 4 vi.append(indent_level + hang) # about the best we can do without look-ahead if (indent_next and vi[0] == indent_level + 4 and nrows == row + 1): vi[0] += 4 if add_second_chances: # visual indenters like to line things up. min_indent = vi[0] for col, what in indent_chances.items(): if col > min_indent and ( what is True or (what == str and token_type == tokenize.STRING) or (what == text and token_type == tokenize.OP) ): vi.append(col) vi = sorted(vi) valid_indents[row] = vi # Returning to original continuation_line_indentation() from # pep8. visual_indent = indent_chances.get(start[1]) last_indent = start rel_indent[row] = pep8.expand_indent(line) - indent_level hang = rel_indent[row] - rel_indent[open_row] if token_type == tokenize.OP and text in ']})': pass elif visual_indent is True: if not indent[depth]: indent[depth] = start[1] # line altered: comments shouldn't define a visual indent if parens[row] and not indent[depth] and token_type not in ( tokenize.NL, tokenize.COMMENT ): indent[depth] = start[1] indent_chances[start[1]] = True elif token_type == tokenize.STRING or text in ( 'u', 'ur', 'b', 'br' ): indent_chances[start[1]] = str if token_type == tokenize.OP: if text in '([{': depth += 1 indent.append(0) parens[row] += 1 elif text in ')]}' and depth > 0: prev_indent = indent.pop() or last_indent[1] for d in range(depth): if indent[d] > prev_indent: indent[d] = 0 for ind in list(indent_chances): if ind >= prev_indent: del indent_chances[ind] depth -= 1 if depth and indent[depth]: # modified indent_chances[indent[depth]] = True for idx in range(row, -1, -1): if parens[idx]: parens[idx] -= 1 break assert len(indent) == depth + 1 if start[1] not in indent_chances: indent_chances[start[1]] = text last_token_multiline = (start[0] != end[0]) return valid_indents class LineShortener(object): """ Class used to shorten lines to a given maximum of characters. """ def __init__(self, curLine, prevLine, nextLine, maxLength=79, eol="\n", indentWord=" ", isDocString=False): """ Constructor @param curLine text to work on (string) @param prevLine line before the text to work on (string) @param nextLine line after the text to work on (string) @keyparam maxLength maximum allowed line length (integer) @keyparam eol eond-of-line marker (string) @keyparam indentWord string used for indentation (string) @keyparam isDocString flag indicating that the line belongs to a documentation string (boolean) """ self.__text = curLine self.__prevText = prevLine self.__nextText = nextLine self.__maxLength = maxLength self.__eol = eol self.__indentWord = indentWord self.__isDocString = isDocString def shorten(self): """ Public method to shorten the line wrapped by the class instance. @return tuple of a flag indicating successful shortening, the shortened line and the changed next line (boolean, string, string) """ # 1. check for comment if self.__text.lstrip().startswith('#'): lastComment = True if self.__nextText.lstrip().startswith('#'): lastComment = False # Wrap commented lines. newText = self.__shortenComment(lastComment) if newText == self.__text: return False, "", "" else: return True, newText, "" elif '#' in self.__text: pos = self.__text.rfind("#") newText = self.__text[:pos].rstrip() + self.__eol + \ self.__getIndent(self.__text) + self.__text[pos:] if newText == self.__text: return False, "", "" else: return True, newText, "" # Do multi line doc strings if self.__isDocString: source = self.__text.rstrip() blank = source.rfind(" ") while blank > self.__maxLength and blank != -1: blank = source.rfind(" ", 0, blank) if blank == -1: # Cannot break return False, "", "" else: first = self.__text[:blank] second = self.__text[blank:].lstrip() if self.__nextText.strip(): if self.__nextText.lstrip().startswith("@"): # eric doc comment # create a new line and indent it newText = first + self.__eol + \ self.__getIndent(first) + self.__indentWord + \ second newNext = "" else: newText = first + self.__eol newNext = self.__getIndent(self.__nextText) + \ second.rstrip() + " " + self.__nextText.lstrip() else: # empty line, add a new line newText = first + self.__eol + self.__getIndent(first) + \ second newNext = "" return True, newText, newNext indent = self.__getIndent(self.__text) source = self.__text[len(indent):] assert source.lstrip() == source sio = StringIO(source) # Check for multi line string. try: tokens = list(tokenize.generate_tokens(sio.readline)) except (SyntaxError, tokenize.TokenError): if source.rstrip().endswith("\\"): # just join the continuation line and let the next run # handle it once it tokenizes ok newText = indent + source.rstrip()[:-1].rstrip() + " " + \ self.__nextText.lstrip() if indent: newNext = indent else: newNext = " " return True, newText, newNext else: multilineCandidate = self.__breakMultiline() if multilineCandidate: return True, multilineCandidate[0], multilineCandidate[1] else: return False, "", "" # Handle statements by putting the right hand side on a line by itself. # This should let the next pass shorten it. if source.startswith('return '): newText = ( indent + 'return (' + self.__eol + indent + self.__indentWord + re.sub('^return ', '', source) + indent + ')' + self.__eol ) return True, newText, "" candidates = self.__shortenLine(tokens, source, indent) if candidates: candidates = list(sorted( set(candidates).union([self.__text]), key=lambda x: self.__lineShorteningRank(x))) if candidates[0] == self.__text: return False, "", "" return True, candidates[0], "" source = self.__text rs = source.rstrip() if rs.endswith(("'", '"')) and " " in source: if rs.endswith(('"""', "'''")): quote = rs[-3:] else: quote = rs[-1] blank = source.rfind(" ") maxLen = self.__maxLength - 2 - len(quote) while blank > maxLen and blank != -1: blank = source.rfind(" ", 0, blank) if blank != -1: if source[blank + 1:].startswith(quote): first = source[:maxLen] second = source[maxLen:] else: first = source[:blank] second = source[blank + 1:] return ( True, first + quote + " \\" + self.__eol + indent + self.__indentWord + quote + second, "") else: # Cannot break return False, "", "" return False, "", "" def __shortenComment(self, isLast): """ Private method to shorten a comment line. @param isLast flag indicating, that the line is the last comment line (boolean) @return shortened comment line (string) """ if len(self.__text) <= self.__maxLength: return self.__text newText = self.__text.rstrip() # PEP 8 recommends 72 characters for comment text. indentation = self.__getIndent(newText) + '# ' maxLength = min(self.__maxLength, len(indentation) + 72) MIN_CHARACTER_REPEAT = 5 if len(newText) - len(newText.rstrip(newText[-1])) >= \ MIN_CHARACTER_REPEAT and \ not newText[-1].isalnum(): # Trim comments that end with things like --------- return newText[:maxLength] + self.__eol elif isLast and re.match(r"\s*#+\s*\w+", newText): import textwrap splitLines = textwrap.wrap(newText.lstrip(" \t#"), initial_indent=indentation, subsequent_indent=indentation, width=maxLength, break_long_words=False, break_on_hyphens=False) return self.__eol.join(splitLines) + self.__eol else: return newText + self.__eol def __breakMultiline(self): """ Private method to break multi line strings. @return tuple of the shortened line and the changed next line (string, string) """ indentation = self.__getIndent(self.__text) # Handle special case. for symbol in '([{': # Only valid if symbol is not on a line by itself. if ( symbol in self.__text and self.__text.strip() != symbol and self.__text.rstrip().endswith((',', '%')) ): index = 1 + self.__text.find(symbol) if index <= len(self.__indentWord) + len(indentation): continue if self.__isProbablyInsideStringOrComment( self.__text, index - 1): continue return (self.__text[:index].rstrip() + self.__eol + indentation + self.__indentWord + self.__text[index:].lstrip(), "") newText = self.__text newNext = self.__nextText blank = newText.rfind(" ") while blank > self.__maxLength and blank != -1: blank = newText.rfind(" ", 0, blank) if blank != -1: first = self.__text[:blank] second = self.__text[blank:].strip() if newNext.strip(): newText = first + self.__eol if second.endswith(")"): # don't merge with next line newText += self.__getIndent(newText) + second + self.__eol newNext = "" else: newNext = self.__getIndent(newNext) + \ second + " " + newNext.lstrip() else: # empty line, add a new line newText = first + self.__eol newNext = self.__getIndent(newNext) + \ second + self.__eol + newNext.lstrip() return newText, newNext else: return None def __isProbablyInsideStringOrComment(self, line, index): """ Private method to check, if the given string might be inside a string or comment. @param line line to check (string) @param index position inside line to check (integer) @return flag indicating the possibility of being inside a string or comment """ # Check against being in a string. for quote in ['"', "'"]: pos = line.find(quote) if pos != -1 and pos <= index: return True # Check against being in a comment. pos = line.find('#') if pos != -1 and pos <= index: return True return False def __shortenLine(self, tokens, source, indent): """ Private method to shorten a line of code at an operator. @param tokens tokens of the line as generated by tokenize (list of token) @param source code string to work at (string) @param indent indentation string of the code line (string) @return list of candidates (list of string) """ candidates = [] for tkn in tokens: tokenType = tkn[0] tokenString = tkn[1] if ( tokenType == tokenize.COMMENT and not self.__prevText.rstrip().endswith('\\') ): # Move inline comments to previous line. offset = tkn[2][1] first = source[:offset] second = source[offset:] candidates.append( indent + second.strip() + self.__eol + indent + first.strip() + self.__eol) elif tokenType == tokenize.OP and tokenString != '=': # Don't break on '=' after keyword as this violates PEP 8. assert tokenType != tokenize.INDENT offset = tkn[2][1] + 1 first = source[:offset] secondIndent = indent if first.rstrip().endswith('('): secondIndent += self.__indentWord elif '(' in first: secondIndent += ' ' * (1 + first.find('(')) else: secondIndent += self.__indentWord second = (secondIndent + source[offset:].lstrip()) if not second.strip(): continue # Do not begin a line with a comma if second.lstrip().startswith(','): continue # Do end a line with a dot if first.rstrip().endswith('.'): continue if tokenString in '+-*/,': newText = first + ' \\' + self.__eol + second else: newText = first + self.__eol + second # Only fix if syntax is okay. if self.__checkSyntax(self.__normalizeMultiline(newText)): candidates.append(indent + newText) return candidates def __normalizeMultiline(self, text): """ Private method to remove multiline-related code that will cause syntax error. @param text code line to work on (string) @return normalized code line (string) """ for quote in '\'"': dictPattern = r"^{q}[^{q}]*{q} *: *".format(q=quote) if re.match(dictPattern, text): if not text.strip().endswith('}'): text += '}' return '{' + text if text.startswith('def ') and text.rstrip().endswith(':'): # Do not allow ':' to be alone. That is invalid. splitText = [item.strip() for item in text.split(self.__eol)] if ':' not in splitText and 'def' not in splitText: return text[len('def'):].strip().rstrip(':') return text def __lineShorteningRank(self, candidate): """ Private method to rank a candidate. @param candidate candidate line to rank (string) @return rank of the candidate (integer) """ rank = 0 if candidate.strip(): if candidate == self.__text: # give the original a disadvantage rank += 50 lines = candidate.split(self.__eol) offset = 0 if lines[0].rstrip()[-1] not in '([{': for symbol in '([{': offset = max(offset, 1 + lines[0].find(symbol)) maxLength = max([offset + len(x.strip()) for x in lines]) rank += maxLength rank += len(lines) badStartingSymbol = { '(': ')', '[': ']', '{': '}'}.get(lines[0][-1], None) if len(lines) > 1: if (badStartingSymbol and lines[1].lstrip().startswith(badStartingSymbol)): rank += 20 if re.match(r".*[+\-\*/] \($", lines[0]): # "1 * (\n" is ugly as hell. rank += 100 for currentLine in lines: for badStart in ['.', '%', '+', '-', '/']: if currentLine.startswith(badStart): rank += 100 for ending in '([{': # Avoid lonely opening. They result in longer lines. if currentLine.endswith(ending) and \ len(currentLine.strip()) <= len(self.__indentWord): rank += 100 if currentLine.endswith('%'): rank -= 20 # Try to break list comprehensions at the "for". if currentLine.lstrip().startswith('for'): rank -= 50 rank += 10 * self.__countUnbalancedBrackets(currentLine) else: rank = 100000 return max(0, rank) def __countUnbalancedBrackets(self, line): """ Private method to determine the number of unmatched open/close brackets. @param line line to work at (string) @return number of unmatched open/close brackets (integer) """ count = 0 for opening, closing in ['()', '[]', '{}']: count += abs(line.count(opening) - line.count(closing)) return count def __getIndent(self, line): """ Private method to get the indentation string. @param line line to determine the indentation string from (string) @return indentation string (string) """ # copied from CodeStyleFixer return line.replace(line.lstrip(), "") def __checkSyntax(self, code): """ Private method to check the syntax of the given code fragment. @param code code fragment to check (string) @return flag indicating syntax is ok (boolean) """ code = code.replace("\r\n", "\n").replace("\r", "\n") try: return compile(code, '', 'exec') except (SyntaxError, TypeError, UnicodeDecodeError): return False eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/pep8.py0000644000175000017500000022613112554665654023431 0ustar piotrpiotr#!/usr/bin/env python # -*- coding: utf-8 -*- # pep8.py - Check Python source code formatting, according to PEP 8 # Copyright (C) 2006-2009 Johann C. Rocholl # Copyright (C) 2009-2014 Florent Xicluna # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation files # (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. r""" Check Python source code formatting, according to PEP 8. For usage and a list of options, try this: $ python pep8.py -h This program and its regression test suite live here: http://github.com/jcrocholl/pep8 Groups of errors and warnings: E errors W warnings 100 indentation 200 whitespace 300 blank lines 400 imports 500 line length 600 deprecation 700 statements 900 syntax error """ from __future__ import with_statement # # This is a modified version to make the original pep8.py better suitable # for being called from within the eric6 IDE. The modifications are as # follows: # # - made messages translatable via Qt # - added code for eric6 integration # # Copyright (c) 2011 - 2015 Detlev Offenbach # __version__ = '1.5.6' import os import sys import re import time import inspect import keyword import tokenize import ast from optparse import OptionParser from fnmatch import fnmatch try: from configparser import RawConfigParser from io import TextIOWrapper except ImportError: from ConfigParser import RawConfigParser # __IGNORE_WARNING__ DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__' DEFAULT_IGNORE = 'E123,E226,E24' if sys.platform == 'win32': DEFAULT_CONFIG = os.path.expanduser(r'~\.pep8') else: DEFAULT_CONFIG = os.path.join(os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'), 'pep8') PROJECT_CONFIG = ('setup.cfg', 'tox.ini', '.pep8') TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite') MAX_LINE_LENGTH = 79 REPORT_FORMAT = { 'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s', 'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s', } SINGLETONS = frozenset(['False', 'None', 'True']) KEYWORDS = frozenset(keyword.kwlist + ['print']) - SINGLETONS UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-']) ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-']) WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%']) WS_NEEDED_OPERATORS = frozenset([ '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<>', '<', '>', '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '=']) WHITESPACE = frozenset(' \t') NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE]) SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT]) # ERRORTOKEN is triggered by backticks in Python 3 SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN]) BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines'] INDENT_REGEX = re.compile(r'([ \t]*)') RAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,') RERAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,.*,\s*\w+\s*$') ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b') DOCSTRING_REGEX = re.compile(r'u?r?["\']') EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[[({] | []}),;:]') WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?: |\t)') COMPARE_SINGLETON_REGEX = re.compile(r'([=!]=)\s*(None|False|True)') COMPARE_NEGATIVE_REGEX = re.compile(r'\b(not)\s+[^[({ ]+\s+(in|is)\s') COMPARE_TYPE_REGEX = re.compile(r'(?:[=!]=|is(?:\s+not)?)\s*type(?:s.\w+Type' r'|\s*\(\s*([^)]*[^ )])\s*\))') KEYWORD_REGEX = re.compile(r'(\s*)\b(?:%s)\b(\s*)' % r'|'.join(KEYWORDS)) OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)') LAMBDA_REGEX = re.compile(r'\blambda\b') HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$') # Work around Python < 2.6 behaviour, which does not generate NL after # a comment which is on a line by itself. COMMENT_WITH_NL = tokenize.generate_tokens(['#\n'].pop).send(None)[1] == '#\n' ############################################################################## # Plugins (check functions) for physical lines ############################################################################## def tabs_or_spaces(physical_line, indent_char): r"""Never mix tabs and spaces. The most popular way of indenting Python is with spaces only. The second-most popular way is with tabs only. Code indented with a mixture of tabs and spaces should be converted to using spaces exclusively. When invoking the Python command line interpreter with the -t option, it issues warnings about code that illegally mixes tabs and spaces. When using -tt these warnings become errors. These options are highly recommended! Okay: if a == 0:\n a = 1\n b = 1 E101: if a == 0:\n a = 1\n\tb = 1 """ indent = INDENT_REGEX.match(physical_line).group(1) for offset, char in enumerate(indent): if char != indent_char: return offset, "E101 indentation contains mixed spaces and tabs" def tabs_obsolete(physical_line): r"""For new projects, spaces-only are strongly recommended over tabs. Okay: if True:\n return W191: if True:\n\treturn """ indent = INDENT_REGEX.match(physical_line).group(1) if '\t' in indent: return indent.index('\t'), "W191 indentation contains tabs" def trailing_whitespace(physical_line): r"""Trailing whitespace is superfluous. The warning returned varies on whether the line itself is blank, for easier filtering for those who want to indent their blank lines. Okay: spam(1)\n# W291: spam(1) \n# W293: class Foo(object):\n \n bang = 12 """ physical_line = physical_line.rstrip('\n') # chr(10), newline physical_line = physical_line.rstrip('\r') # chr(13), carriage return physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L stripped = physical_line.rstrip(' \t\v') if physical_line != stripped: if stripped: return len(stripped), "W291 trailing whitespace" else: return 0, "W293 blank line contains whitespace" def trailing_blank_lines(physical_line, lines, line_number, total_lines): r"""Trailing blank lines are superfluous. Okay: spam(1) W391: spam(1)\n However the last line should end with a new line (warning W292). """ if line_number == total_lines: stripped_last_line = physical_line.rstrip() if not stripped_last_line: return 0, "W391 blank line at end of file" if stripped_last_line == physical_line: return len(physical_line), "W292 no newline at end of file" def maximum_line_length(physical_line, max_line_length, multiline): r"""Limit all lines to a maximum of 79 characters. There are still many devices around that are limited to 80 character lines; plus, limiting windows to 80 characters makes it possible to have several windows side-by-side. The default wrapping on such devices looks ugly. Therefore, please limit all lines to a maximum of 79 characters. For flowing long blocks of text (docstrings or comments), limiting the length to 72 characters is recommended. Reports error E501. """ line = physical_line.rstrip() length = len(line) if length > max_line_length and not noqa(line): # Special case for long URLs in multi-line docstrings or comments, # but still report the error when the 72 first chars are whitespaces. chunks = line.split() if ((len(chunks) == 1 and multiline) or (len(chunks) == 2 and chunks[0] == '#')) and \ len(line) - len(chunks[-1]) < max_line_length - 7: return if hasattr(line, 'decode'): # Python 2 # The line could contain multi-byte characters try: length = len(line.decode('utf-8')) except UnicodeError: pass if length > max_line_length: return (max_line_length, "E501 line too long ", length, max_line_length) ############################################################################## # Plugins (check functions) for logical lines ############################################################################## def blank_lines(logical_line, blank_lines, indent_level, line_number, blank_before, previous_logical, previous_indent_level): r"""Separate top-level function and class definitions with two blank lines. Method definitions inside a class are separated by a single blank line. Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of related one-liners (e.g. a set of dummy implementations). Use blank lines in functions, sparingly, to indicate logical sections. Okay: def a():\n pass\n\n\ndef b():\n pass Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass E301: class Foo:\n b = 0\n def bar():\n pass E302: def a():\n pass\n\ndef b(n):\n pass E303: def a():\n pass\n\n\n\ndef b(n):\n pass E303: def a():\n\n\n\n pass E304: @decorator\n\ndef a():\n pass """ if line_number < 3 and not previous_logical: return # Don't expect blank lines before the first line if previous_logical.startswith('@'): if blank_lines: yield 0, "E304 blank lines found after function decorator" elif blank_lines > 2 or (indent_level and blank_lines == 2): yield 0, "E303 too many blank lines (%d)", blank_lines elif logical_line.startswith(('def ', 'class ', '@')): if indent_level: if not (blank_before or previous_indent_level < indent_level or DOCSTRING_REGEX.match(previous_logical)): yield 0, "E301 expected 1 blank line, found 0" elif blank_before != 2: yield 0, "E302 expected 2 blank lines, found %d", blank_before def extraneous_whitespace(logical_line): r"""Avoid extraneous whitespace. Avoid extraneous whitespace in these situations: - Immediately inside parentheses, brackets or braces. - Immediately before a comma, semicolon, or colon. Okay: spam(ham[1], {eggs: 2}) E201: spam( ham[1], {eggs: 2}) E201: spam(ham[ 1], {eggs: 2}) E201: spam(ham[1], { eggs: 2}) E202: spam(ham[1], {eggs: 2} ) E202: spam(ham[1 ], {eggs: 2}) E202: spam(ham[1], {eggs: 2 }) E203: if x == 4: print x, y; x, y = y , x E203: if x == 4: print x, y ; x, y = y, x E203: if x == 4 : print x, y; x, y = y, x """ line = logical_line for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line): text = match.group() char = text.strip() found = match.start() if text == char + ' ': # assert char in '([{' yield found + 1, "E201 whitespace after '%s'", char elif line[found - 1] != ',': code = ('E202' if char in '}])' else 'E203') # if char in ',;:' yield found, "%s whitespace before '%s'" % (code, char), char def whitespace_around_keywords(logical_line): r"""Avoid extraneous whitespace around keywords. Okay: True and False E271: True and False E272: True and False E273: True and\tFalse E274: True\tand False """ for match in KEYWORD_REGEX.finditer(logical_line): before, after = match.groups() if '\t' in before: yield match.start(1), "E274 tab before keyword" elif len(before) > 1: yield match.start(1), "E272 multiple spaces before keyword" if '\t' in after: yield match.start(2), "E273 tab after keyword" elif len(after) > 1: yield match.start(2), "E271 multiple spaces after keyword" def missing_whitespace(logical_line): r"""Each comma, semicolon or colon should be followed by whitespace. Okay: [a, b] Okay: (3,) Okay: a[1:4] Okay: a[:4] Okay: a[1:] Okay: a[1:4:2] E231: ['a','b'] E231: foo(bar,baz) E231: [{'a':'b'}] """ line = logical_line for index in range(len(line) - 1): char = line[index] if char in ',;:' and line[index + 1] not in WHITESPACE: before = line[:index] if char == ':' and before.count('[') > before.count(']') and \ before.rfind('{') < before.rfind('['): continue # Slice syntax, no space required if char == ',' and line[index + 1] == ')': continue # Allow tuple with only one element: (3,) yield index, "E231 missing whitespace after '%s'", char def indentation(logical_line, previous_logical, indent_char, indent_level, previous_indent_level): r"""Use 4 spaces per indentation level. For really old code that you don't want to mess up, you can continue to use 8-space tabs. Okay: a = 1 Okay: if a == 0:\n a = 1 E111: a = 1 Okay: for item in items:\n pass E112: for item in items:\npass Okay: a = 1\nb = 2 E113: a = 1\n b = 2 """ if indent_char == ' ' and indent_level % 4: yield 0, "E111 indentation is not a multiple of four" indent_expect = previous_logical.endswith(':') if indent_expect and indent_level <= previous_indent_level: yield 0, "E112 expected an indented block" if indent_level > previous_indent_level and not indent_expect: yield 0, "E113 unexpected indentation" def continued_indentation(logical_line, tokens, indent_level, hang_closing, indent_char, noqa, verbose): r"""Continuation lines indentation. Continuation lines should align wrapped elements either vertically using Python's implicit line joining inside parentheses, brackets and braces, or using a hanging indent. When using a hanging indent these considerations should be applied: - there should be no arguments on the first line, and - further indentation should be used to clearly distinguish itself as a continuation line. Okay: a = (\n) E123: a = (\n ) Okay: a = (\n 42) E121: a = (\n 42) E122: a = (\n42) E123: a = (\n 42\n ) E124: a = (24,\n 42\n) E125: if (\n b):\n pass E126: a = (\n 42) E127: a = (24,\n 42) E128: a = (24,\n 42) E129: if (a or\n b):\n pass E131: a = (\n 42\n 24) """ first_row = tokens[0][2][0] nrows = 1 + tokens[-1][2][0] - first_row if noqa or nrows == 1: return # indent_next tells us whether the next block is indented; assuming # that it is indented by 4 spaces, then we should not allow 4-space # indents on the final continuation line; in turn, some other # indents are allowed to have an extra 4 spaces. indent_next = logical_line.endswith(':') row = depth = 0 valid_hangs = (4,) if indent_char != '\t' else (4, 8) # remember how many brackets were opened on each line parens = [0] * nrows # relative indents of physical lines rel_indent = [0] * nrows # for each depth, collect a list of opening rows open_rows = [[0]] # for each depth, memorize the hanging indentation hangs = [None] # visual indents indent_chances = {} last_indent = tokens[0][2] visual_indent = None # for each depth, memorize the visual indent column indent = [last_indent[1]] if verbose >= 3: print(">>> " + tokens[0][4].rstrip()) for token_type, text, start, end, line in tokens: last_token_multiline = (start[0] != end[0]) newline = row < start[0] - first_row if newline: row = start[0] - first_row newline = not last_token_multiline and token_type not in NEWLINE if newline: # this is the beginning of a continuation line. last_indent = start if verbose >= 3: print("... " + line.rstrip()) # record the initial indent. rel_indent[row] = expand_indent(line) - indent_level # identify closing bracket close_bracket = (token_type == tokenize.OP and text in ']})') # is the indent relative to an opening bracket line? for open_row in reversed(open_rows[depth]): hang = rel_indent[row] - rel_indent[open_row] hanging_indent = hang in valid_hangs if hanging_indent: break if hangs[depth]: hanging_indent = (hang == hangs[depth]) # is there any chance of visual indent? visual_indent = (not close_bracket and hang > 0 and indent_chances.get(start[1])) if close_bracket and indent[depth]: # closing bracket for visual indent if start[1] != indent[depth]: yield (start, "E124 closing bracket does not match " "visual indentation") elif close_bracket and not hang: # closing bracket matches indentation of opening bracket's line if hang_closing: yield start, "E133 closing bracket is missing indentation" elif indent[depth] and start[1] < indent[depth]: if visual_indent is not True: # visual indent is broken yield (start, "E128 continuation line " "under-indented for visual indent") elif hanging_indent or (indent_next and rel_indent[row] == 8): # hanging indent is verified if close_bracket and not hang_closing: yield (start, "E123 closing bracket does not match " "indentation of opening bracket's line") hangs[depth] = hang elif visual_indent is True: # visual indent is verified indent[depth] = start[1] elif visual_indent in (text, str): # ignore token lined up with matching one from a previous line pass else: # indent is broken if hang <= 0: error = "E122", "missing indentation or outdented" elif indent[depth]: error = "E127", "over-indented for visual indent" elif not close_bracket and hangs[depth]: error = "E131", "unaligned for hanging indent" else: hangs[depth] = hang if hang > 4: error = "E126", "over-indented for hanging indent" else: error = "E121", "under-indented for hanging indent" yield start, "%s continuation line %s" % error # look for visual indenting if (parens[row] and token_type not in (tokenize.NL, tokenize.COMMENT) and not indent[depth]): indent[depth] = start[1] indent_chances[start[1]] = True if verbose >= 4: print("bracket depth %s indent to %s" % (depth, start[1])) # deal with implicit string concatenation elif (token_type in (tokenize.STRING, tokenize.COMMENT) or text in ('u', 'ur', 'b', 'br')): indent_chances[start[1]] = str # special case for the "if" statement because len("if (") == 4 elif not indent_chances and not row and not depth and text == 'if': indent_chances[end[1] + 1] = True elif text == ':' and line[end[1]:].isspace(): open_rows[depth].append(row) # keep track of bracket depth if token_type == tokenize.OP: if text in '([{': depth += 1 indent.append(0) hangs.append(None) if len(open_rows) == depth: open_rows.append([]) open_rows[depth].append(row) parens[row] += 1 if verbose >= 4: print("bracket depth %s seen, col %s, visual min = %s" % (depth, start[1], indent[depth])) elif text in ')]}' and depth > 0: # parent indents should not be more than this one prev_indent = indent.pop() or last_indent[1] hangs.pop() for d in range(depth): if indent[d] > prev_indent: indent[d] = 0 for ind in list(indent_chances): if ind >= prev_indent: del indent_chances[ind] del open_rows[depth + 1:] depth -= 1 if depth: indent_chances[indent[depth]] = True for idx in range(row, -1, -1): if parens[idx]: parens[idx] -= 1 break assert len(indent) == depth + 1 if start[1] not in indent_chances: # allow to line up tokens indent_chances[start[1]] = text if last_token_multiline: rel_indent[end[0] - first_row] = rel_indent[row] if indent_next and expand_indent(line) == indent_level + 4: pos = (start[0], indent[0] + 4) if visual_indent: code = "E129 visually indented line" else: code = "E125 continuation line" yield pos, "%s with same indent as next logical line" % code def whitespace_before_parameters(logical_line, tokens): r"""Avoid extraneous whitespace. Avoid extraneous whitespace in the following situations: - before the open parenthesis that starts the argument list of a function call. - before the open parenthesis that starts an indexing or slicing. Okay: spam(1) E211: spam (1) Okay: dict['key'] = list[index] E211: dict ['key'] = list[index] E211: dict['key'] = list [index] """ prev_type, prev_text, __, prev_end, __ = tokens[0] for index in range(1, len(tokens)): token_type, text, start, end, __ = tokens[index] if (token_type == tokenize.OP and text in '([' and start != prev_end and (prev_type == tokenize.NAME or prev_text in '}])') and # Syntax "class A (B):" is allowed, but avoid it (index < 2 or tokens[index - 2][1] != 'class') and # Allow "return (a.foo for a in range(5))" not keyword.iskeyword(prev_text)): yield prev_end, "E211 whitespace before '%s'", text prev_type = token_type prev_text = text prev_end = end def whitespace_around_operator(logical_line): r"""Avoid extraneous whitespace around an operator. Okay: a = 12 + 3 E221: a = 4 + 5 E222: a = 4 + 5 E223: a = 4\t+ 5 E224: a = 4 +\t5 """ for match in OPERATOR_REGEX.finditer(logical_line): before, after = match.groups() if '\t' in before: yield match.start(1), "E223 tab before operator" elif len(before) > 1: yield match.start(1), "E221 multiple spaces before operator" if '\t' in after: yield match.start(2), "E224 tab after operator" elif len(after) > 1: yield match.start(2), "E222 multiple spaces after operator" def missing_whitespace_around_operator(logical_line, tokens): r"""Surround operators with a single space on either side. - Always surround these binary operators with a single space on either side: assignment (=), augmented assignment (+=, -= etc.), comparisons (==, <, >, !=, <=, >=, in, not in, is, is not), Booleans (and, or, not). - If operators with different priorities are used, consider adding whitespace around the operators with the lowest priorities. Okay: i = i + 1 Okay: submitted += 1 Okay: x = x * 2 - 1 Okay: hypot2 = x * x + y * y Okay: c = (a + b) * (a - b) Okay: foo(bar, key='word', *args, **kwargs) Okay: alpha[:-i] E225: i=i+1 E225: submitted +=1 E225: x = x /2 - 1 E225: z = x **y E226: c = (a+b) * (a-b) E226: hypot2 = x*x + y*y E227: c = a|b E228: msg = fmt%(errno, errmsg) """ parens = 0 need_space = False prev_type = tokenize.OP prev_text = prev_end = None for token_type, text, start, end, line in tokens: if token_type in SKIP_COMMENTS: continue if text in ('(', 'lambda'): parens += 1 elif text == ')': parens -= 1 if need_space: if start != prev_end: # Found a (probably) needed space if need_space is not True and not need_space[1]: yield (need_space[0], "E225 missing whitespace around operator") need_space = False elif text == '>' and prev_text in ('<', '-'): # Tolerate the "<>" operator, even if running Python 3 # Deal with Python 3's annotated return value "->" pass else: if need_space is True or need_space[1]: # A needed trailing space was not found yield prev_end, "E225 missing whitespace around operator" else: code, optype = 'E226', 'arithmetic' if prev_text == '%': code, optype = 'E228', 'modulo' elif prev_text not in ARITHMETIC_OP: code, optype = 'E227', 'bitwise or shift' yield (need_space[0], "%s missing whitespace " "around %s operator" % (code, optype)) need_space = False elif token_type == tokenize.OP and prev_end is not None: if text == '=' and parens: # Allow keyword args or defaults: foo(bar=None). pass elif text in WS_NEEDED_OPERATORS: need_space = True elif text in UNARY_OPERATORS: # Check if the operator is being used as a binary operator # Allow unary operators: -123, -x, +1. # Allow argument unpacking: foo(*args, **kwargs). if (prev_text in '}])' if prev_type == tokenize.OP else prev_text not in KEYWORDS): need_space = None elif text in WS_OPTIONAL_OPERATORS: need_space = None if need_space is None: # Surrounding space is optional, but ensure that # trailing space matches opening space need_space = (prev_end, start != prev_end) elif need_space and start == prev_end: # A needed opening space was not found yield prev_end, "E225 missing whitespace around operator" need_space = False prev_type = token_type prev_text = text prev_end = end def whitespace_around_comma(logical_line): r"""Avoid extraneous whitespace after a comma or a colon. Note: these checks are disabled by default Okay: a = (1, 2) E241: a = (1, 2) E242: a = (1,\t2) """ line = logical_line for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line): found = m.start() + 1 if '\t' in m.group(): yield found, "E242 tab after '%s'", m.group()[0] else: yield found, "E241 multiple spaces after '%s'", m.group()[0] def whitespace_around_named_parameter_equals(logical_line, tokens): r"""Don't use spaces around the '=' sign in function arguments. Don't use spaces around the '=' sign when used to indicate a keyword argument or a default parameter value. Okay: def complex(real, imag=0.0): Okay: return magic(r=real, i=imag) Okay: boolean(a == b) Okay: boolean(a != b) Okay: boolean(a <= b) Okay: boolean(a >= b) E251: def complex(real, imag = 0.0): E251: return magic(r = real, i = imag) """ parens = 0 no_space = False prev_end = None message = "E251 unexpected spaces around keyword / parameter equals" for token_type, text, start, end, line in tokens: if token_type == tokenize.NL: continue if no_space: no_space = False if start != prev_end: yield (prev_end, message) elif token_type == tokenize.OP: if text == '(': parens += 1 elif text == ')': parens -= 1 elif parens and text == '=': no_space = True if start != prev_end: yield (prev_end, message) prev_end = end def whitespace_before_comment(logical_line, tokens): r"""Separate inline comments by at least two spaces. An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. They should start with a # and a single space. Each line of a block comment starts with a # and a single space (unless it is indented text inside the comment). Okay: x = x + 1 # Increment x Okay: x = x + 1 # Increment x Okay: # Block comment E261: x = x + 1 # Increment x E262: x = x + 1 #Increment x E262: x = x + 1 # Increment x E265: #Block comment """ prev_end = (0, 0) for token_type, text, start, end, line in tokens: if token_type == tokenize.COMMENT: inline_comment = line[:start[1]].strip() if inline_comment: if prev_end[0] == start[0] and start[1] < prev_end[1] + 2: yield (prev_end, "E261 at least two spaces before inline comment") symbol, sp, comment = text.partition(' ') bad_prefix = symbol not in ('#', '#:') if inline_comment: if bad_prefix or comment[:1].isspace(): yield start, "E262 inline comment should start with '# '" elif bad_prefix: if text.rstrip('#') and (start[0] > 1 or symbol[1] != '!'): yield start, "E265 block comment should start with '# '" elif token_type != tokenize.NL: prev_end = end def imports_on_separate_lines(logical_line): r"""Imports should usually be on separate lines. Okay: import os\nimport sys E401: import sys, os Okay: from subprocess import Popen, PIPE Okay: from myclas import MyClass Okay: from foo.bar.yourclass import YourClass Okay: import myclass Okay: import foo.bar.yourclass """ line = logical_line if line.startswith('import '): found = line.find(',') if -1 < found and ';' not in line[:found]: yield found, "E401 multiple imports on one line" def compound_statements(logical_line): r"""Compound statements (on the same line) are generally discouraged. While sometimes it's okay to put an if/for/while with a small body on the same line, never do this for multi-clause statements. Also avoid folding such long lines! Okay: if foo == 'blah':\n do_blah_thing() Okay: do_one() Okay: do_two() Okay: do_three() E701: if foo == 'blah': do_blah_thing() E701: for x in lst: total += x E701: while t < 10: t = delay() E701: if foo == 'blah': do_blah_thing() E701: else: do_non_blah_thing() E701: try: something() E701: finally: cleanup() E701: if foo == 'blah': one(); two(); three() E702: do_one(); do_two(); do_three() E703: do_four(); # useless semicolon """ line = logical_line last_char = len(line) - 1 found = line.find(':') while -1 < found < last_char: before = line[:found] if (before.count('{') <= before.count('}') and # {'a': 1} (dict) before.count('[') <= before.count(']') and # [1:2] (slice) before.count('(') <= before.count(')') and # (Python 3 annotation) not LAMBDA_REGEX.search(before)): # lambda x: x yield found, "E701 multiple statements on one line (colon)" found = line.find(':', found + 1) found = line.find(';') while -1 < found: if found < last_char: yield found, "E702 multiple statements on one line (semicolon)" else: yield found, "E703 statement ends with a semicolon" found = line.find(';', found + 1) def explicit_line_join(logical_line, tokens): r"""Avoid explicit line join between brackets. The preferred way of wrapping long lines is by using Python's implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation. E502: aaa = [123, \\n 123] E502: aaa = ("bbb " \\n "ccc") Okay: aaa = [123,\n 123] Okay: aaa = ("bbb "\n "ccc") Okay: aaa = "bbb " \\n "ccc" """ prev_start = prev_end = parens = 0 backslash = None for token_type, text, start, end, line in tokens: if start[0] != prev_start and parens and backslash: yield backslash, "E502 the backslash is redundant between brackets" if end[0] != prev_end: if line.rstrip('\r\n').endswith('\\'): backslash = (end[0], len(line.splitlines()[-1]) - 1) else: backslash = None prev_start = prev_end = end[0] else: prev_start = start[0] if token_type == tokenize.OP: if text in '([{': parens += 1 elif text in ')]}': parens -= 1 def comparison_to_singleton(logical_line, noqa): r"""Comparison to singletons should use "is" or "is not". Comparisons to singletons like None should always be done with "is" or "is not", never the equality operators. Okay: if arg is not None: E711: if arg != None: E712: if arg == True: Also, beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context! """ match = not noqa and COMPARE_SINGLETON_REGEX.search(logical_line) if match: same = (match.group(1) == '==') singleton = match.group(2) msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton) if singleton in ('None',): code = 'E711' else: code = 'E712' nonzero = ((singleton == 'True' and same) or (singleton == 'False' and not same)) msg += " or 'if %scond:'" % ('' if nonzero else 'not ') yield (match.start(1), "%s comparison to %s should be %s" % (code, singleton, msg), singleton, msg) def comparison_negative(logical_line): r"""Negative comparison should be done using "not in" and "is not". Okay: if x not in y:\n pass Okay: assert (X in Y or X is Z) Okay: if not (X in Y):\n pass Okay: zz = x is not y E713: Z = not X in Y E713: if not X.B in Y:\n pass E714: if not X is Y:\n pass E714: Z = not X.B is Y """ match = COMPARE_NEGATIVE_REGEX.search(logical_line) if match: pos = match.start(1) if match.group(2) == 'in': yield pos, "E713 test for membership should be 'not in'" else: yield pos, "E714 test for object identity should be 'is not'" def comparison_type(logical_line): r"""Object type comparisons should always use isinstance(). Do not compare types directly. Okay: if isinstance(obj, int): E721: if type(obj) is type(1): When checking if an object is a string, keep in mind that it might be a unicode string too! In Python 2.3, str and unicode have a common base class, basestring, so you can do: Okay: if isinstance(obj, basestring): Okay: if type(a1) is type(b1): """ match = COMPARE_TYPE_REGEX.search(logical_line) if match: inst = match.group(1) if inst and isidentifier(inst) and inst not in SINGLETONS: return # Allow comparison for types which are not obvious yield match.start(), "E721 do not compare types, use 'isinstance()'" def python_3000_has_key(logical_line, noqa): r"""The {}.has_key() method is removed in Python 3: use the 'in' operator. Okay: if "alph" in d:\n print d["alph"] W601: assert d.has_key('alph') """ pos = logical_line.find('.has_key(') if pos > -1 and not noqa: yield pos, "W601 .has_key() is deprecated, use 'in'" def python_3000_raise_comma(logical_line): r"""When raising an exception, use "raise ValueError('message')". The older form is removed in Python 3. Okay: raise DummyError("Message") W602: raise DummyError, "Message" """ match = RAISE_COMMA_REGEX.match(logical_line) if match and not RERAISE_COMMA_REGEX.match(logical_line): yield match.end() - 1, "W602 deprecated form of raising exception" def python_3000_not_equal(logical_line): r"""New code should always use != instead of <>. The older syntax is removed in Python 3. Okay: if a != 'no': W603: if a <> 'no': """ pos = logical_line.find('<>') if pos > -1: yield pos, "W603 '<>' is deprecated, use '!='" def python_3000_backticks(logical_line): r"""Backticks are removed in Python 3: use repr() instead. Okay: val = repr(1 + 2) W604: val = `1 + 2` """ pos = logical_line.find('`') if pos > -1: yield pos, "W604 backticks are deprecated, use 'repr()'" ############################################################################## # Helper functions ############################################################################## if '' == ''.encode("utf-8"): # Python 2: implicit encoding. def readlines(filename): """Read the source code.""" with open(filename) as f: return f.readlines() isidentifier = re.compile(r'[a-zA-Z_]\w*').match stdin_get_value = sys.stdin.read else: # Python 3 def readlines(filename): """Read the source code.""" try: with open(filename, 'rb') as f: (coding, lines) = tokenize.detect_encoding(f.readline) f = TextIOWrapper(f, coding, line_buffering=True) return [l.decode(coding) for l in lines] + f.readlines() except (LookupError, SyntaxError, UnicodeError): # Fall back if file encoding is improperly declared with open(filename, encoding='latin-1') as f: return f.readlines() isidentifier = str.isidentifier def stdin_get_value(): return TextIOWrapper(sys.stdin.buffer, errors='ignore').read() noqa = re.compile(r'# no(?:qa|pep8)\b', re.I).search def expand_indent(line): r"""Return the amount of indentation. Tabs are expanded to the next multiple of 8. >>> expand_indent(' ') 4 >>> expand_indent('\t') 8 >>> expand_indent(' \t') 8 >>> expand_indent(' \t') 16 """ if '\t' not in line: return len(line) - len(line.lstrip()) result = 0 for char in line: if char == '\t': result = result // 8 * 8 + 8 elif char == ' ': result += 1 else: break return result def mute_string(text): """Replace contents with 'xxx' to prevent syntax matching. >>> mute_string('"abc"') '"xxx"' >>> mute_string("'''abc'''") "'''xxx'''" >>> mute_string("r'abc'") "r'xxx'" """ # String modifiers (e.g. u or r) start = text.index(text[-1]) + 1 end = len(text) - 1 # Triple quotes if text[-3:] in ('"""', "'''"): start += 2 end -= 2 return text[:start] + 'x' * (end - start) + text[end:] def parse_udiff(diff, patterns=None, parent='.'): """Return a dictionary of matching lines.""" # For each file of the diff, the entry key is the filename, # and the value is a set of row numbers to consider. rv = {} path = nrows = None for line in diff.splitlines(): if nrows: if line[:1] != '-': nrows -= 1 continue if line[:3] == '@@ ': hunk_match = HUNK_REGEX.match(line) (row, nrows) = [int(g or '1') for g in hunk_match.groups()] rv[path].update(range(row, row + nrows)) elif line[:3] == '+++': path = line[4:].split('\t', 1)[0] if path[:2] == 'b/': path = path[2:] rv[path] = set() return dict([(os.path.join(parent, path_), rows) for (path_, rows) in rv.items() if rows and filename_match(path_, patterns)]) def normalize_paths(value, parent=os.curdir): """Parse a comma-separated list of paths. Return a list of absolute paths. """ if not value or isinstance(value, list): return value paths = [] for path in value.split(','): if '/' in path: path = os.path.abspath(os.path.join(parent, path)) paths.append(path.rstrip('/')) return paths def filename_match(filename, patterns, default=True): """Check if patterns contains a pattern that matches filename. If patterns is unspecified, this always returns True. """ if not patterns: return default return any(fnmatch(filename, pattern) for pattern in patterns) if COMMENT_WITH_NL: def _is_eol_token(token): return (token[0] in NEWLINE or (token[0] == tokenize.COMMENT and token[1] == token[4])) else: def _is_eol_token(token): return token[0] in NEWLINE ############################################################################## # Framework to run all checks ############################################################################## _checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}} def register_check(check, codes=None): """Register a new check object.""" def _add_check(check, kind, codes, args): if check in _checks[kind]: _checks[kind][check][0].extend(codes or []) else: _checks[kind][check] = (codes or [''], args) if inspect.isfunction(check): args = inspect.getargspec(check)[0] if args and args[0] in ('physical_line', 'logical_line'): if codes is None: codes = ERRORCODE_REGEX.findall(check.__doc__ or '') _add_check(check, args[0], codes, args) elif inspect.isclass(check): if inspect.getargspec(check.__init__)[0][:2] == ['self', 'tree']: _add_check(check, 'tree', codes, None) def init_checks_registry(): """Register all globally visible functions. The first argument name is either 'physical_line' or 'logical_line'. """ mod = inspect.getmodule(register_check) for (name, function) in inspect.getmembers(mod, inspect.isfunction): register_check(function) init_checks_registry() class Checker(object): """Load a Python source file, tokenize it, check coding style.""" def __init__(self, filename=None, lines=None, options=None, report=None, **kwargs): if options is None: options = StyleGuide(kwargs).options else: assert not kwargs self._io_error = None self._physical_checks = options.physical_checks self._logical_checks = options.logical_checks self._ast_checks = options.ast_checks self.max_line_length = options.max_line_length self.multiline = False # in a multiline string? self.hang_closing = options.hang_closing self.verbose = options.verbose self.filename = filename if filename is None: self.filename = 'stdin' self.lines = lines or [] elif filename == '-': self.filename = 'stdin' self.lines = stdin_get_value().splitlines(True) elif lines is None: try: self.lines = readlines(filename) except IOError: (exc_type, exc) = sys.exc_info()[:2] self._io_error = '%s: %s' % (exc_type.__name__, exc) self.lines = [] else: self.lines = lines if self.lines: ord0 = ord(self.lines[0][0]) if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM if ord0 == 0xfeff: self.lines[0] = self.lines[0][1:] elif self.lines[0][:3] == '\xef\xbb\xbf': self.lines[0] = self.lines[0][3:] self.report = report or options.report self.report_error = self.report.error self.report_error_args = self.report.error_args # added for eric6 integration self.options = options def report_invalid_syntax(self): """Check if the syntax is valid.""" (exc_type, exc) = sys.exc_info()[:2] if len(exc.args) > 1: offset = exc.args[1] if len(offset) > 2: offset = offset[1:3] else: offset = (1, 0) self.report_error_args(offset[0], offset[1] or 0, 'E901', self.report_invalid_syntax, exc_type.__name__, exc.args[0]) def readline(self): """Get the next line from the input buffer.""" if self.line_number >= self.total_lines: return '' line = self.lines[self.line_number] self.line_number += 1 if self.indent_char is None and line[:1] in WHITESPACE: self.indent_char = line[0] return line def run_check(self, check, argument_names): """Run a check plugin.""" arguments = [] for name in argument_names: arguments.append(getattr(self, name)) return check(*arguments) def check_physical(self, line): """Run all physical checks on a raw input line.""" self.physical_line = line for name, check, argument_names in self._physical_checks: result = self.run_check(check, argument_names) if result is not None: (offset, text) = result[:2] args = result[2:] self.report_error_args( self.line_number, offset, text, check, *args) if text[:4] == 'E101': self.indent_char = line[0] def build_tokens_line(self): """Build a logical line from tokens.""" logical = [] comments = [] length = 0 prev_row = prev_col = mapping = None for token_type, text, start, end, line in self.tokens: if token_type in SKIP_TOKENS: continue if not mapping: mapping = [(0, start)] if token_type == tokenize.COMMENT: comments.append(text) continue if token_type == tokenize.STRING: text = mute_string(text) if prev_row: (start_row, start_col) = start if prev_row != start_row: # different row prev_text = self.lines[prev_row - 1][prev_col - 1] if prev_text == ',' or (prev_text not in '{[(' and text not in '}])'): text = ' ' + text elif prev_col != start_col: # different column text = line[prev_col:start_col] + text logical.append(text) length += len(text) mapping.append((length, end)) (prev_row, prev_col) = end self.logical_line = ''.join(logical) self.noqa = comments and noqa(''.join(comments)) return mapping def check_logical(self): """Build a line from tokens and run all logical checks on it.""" self.report.increment_logical_line() mapping = self.build_tokens_line() (start_row, start_col) = mapping[0][1] start_line = self.lines[start_row - 1] self.indent_level = expand_indent(start_line[:start_col]) if self.blank_before < self.blank_lines: self.blank_before = self.blank_lines if self.verbose >= 2: print(self.logical_line[:80].rstrip()) for name, check, argument_names in self._logical_checks: if self.verbose >= 4: print(' ' + name) for result in self.run_check(check, argument_names): offset, text = result[:2] args = result[2:] if not isinstance(offset, tuple): for token_offset, pos in mapping: if offset <= token_offset: break offset = (pos[0], pos[1] + offset - token_offset) self.report_error_args( offset[0], offset[1], text, check, *args) if self.logical_line: self.previous_indent_level = self.indent_level self.previous_logical = self.logical_line self.blank_lines = 0 self.tokens = [] def check_ast(self): """Build the file's AST and run all AST checks.""" try: tree = compile(''.join(self.lines), '', 'exec', ast.PyCF_ONLY_AST) except (SyntaxError, TypeError): return self.report_invalid_syntax() for name, cls, __ in self._ast_checks: # extended API for eric6 integration checker = cls(tree, self.filename, self.options) for args in checker.run(): lineno = args[0] if not self.lines or not noqa(self.lines[lineno - 1]): self.report_error_args(lineno, *args[1:]) def generate_tokens(self): """Tokenize the file, run physical line checks and yield tokens.""" if self._io_error: self.report_error_args(1, 0, 'E902', self._io_error, readlines) tokengen = tokenize.generate_tokens(self.readline) try: for token in tokengen: self.maybe_check_physical(token) yield token except (SyntaxError, tokenize.TokenError): self.report_invalid_syntax() def maybe_check_physical(self, token): """If appropriate (based on token), check current physical line(s).""" # Called after every token, but act only on end of line. if _is_eol_token(token): # Obviously, a newline token ends a single physical line. self.check_physical(token[4]) elif token[0] == tokenize.STRING and '\n' in token[1]: # Less obviously, a string that contains newlines is a # multiline string, either triple-quoted or with internal # newlines backslash-escaped. Check every physical line in the # string *except* for the last one: its newline is outside of # the multiline string, so we consider it a regular physical # line, and will check it like any other physical line. # # Subtleties: # - we don't *completely* ignore the last line; if it contains # the magical "# noqa" comment, we disable all physical # checks for the entire multiline string # - have to wind self.line_number back because initially it # points to the last line of the string, and we want # check_physical() to give accurate feedback if noqa(token[4]): return self.multiline = True self.line_number = token[2][0] for line in token[1].split('\n')[:-1]: self.check_physical(line + '\n') self.line_number += 1 self.multiline = False def check_all(self, expected=None, line_offset=0): """Run all checks on the input file.""" self.report.init_file(self.filename, self.lines, expected, line_offset) self.total_lines = len(self.lines) if self._ast_checks: self.check_ast() self.line_number = 0 self.indent_char = None self.indent_level = self.previous_indent_level = 0 self.previous_logical = '' self.tokens = [] self.blank_lines = self.blank_before = 0 parens = 0 for token in self.generate_tokens(): self.tokens.append(token) token_type, text = token[0:2] if self.verbose >= 3: if token[2][0] == token[3][0]: pos = '[%s:%s]' % (token[2][1] or '', token[3][1]) else: pos = 'l.%s' % token[3][0] print('l.%s\t%s\t%s\t%r' % (token[2][0], pos, tokenize.tok_name[token[0]], text)) if token_type == tokenize.OP: if text in '([{': parens += 1 elif text in '}])': parens -= 1 elif not parens: if token_type in NEWLINE: if token_type == tokenize.NEWLINE: self.check_logical() self.blank_before = 0 elif len(self.tokens) == 1: # The physical line contains only this token. self.blank_lines += 1 del self.tokens[0] else: self.check_logical() elif COMMENT_WITH_NL and token_type == tokenize.COMMENT: if len(self.tokens) == 1: # The comment also ends a physical line token = list(token) token[1] = text.rstrip('\r\n') token[3] = (token[2][0], token[2][1] + len(token[1])) self.tokens = [tuple(token)] self.check_logical() if len(self.tokens) > 1 and (token_type == tokenize.ENDMARKER and self.tokens[-2][0] not in SKIP_TOKENS): self.tokens.pop() self.check_physical(self.tokens[-1][4]) self.check_logical() return self.report.get_file_results() class BaseReport(object): """Collect the results of the checks.""" print_filename = False def __init__(self, options): self._benchmark_keys = options.benchmark_keys self._ignore_code = options.ignore_code # Results self.elapsed = 0 self.total_errors = 0 self.counters = dict.fromkeys(self._benchmark_keys, 0) self.messages = {} def start(self): """Start the timer.""" self._start_time = time.time() def stop(self): """Stop the timer.""" self.elapsed = time.time() - self._start_time def init_file(self, filename, lines, expected, line_offset): """Signal a new file.""" self.filename = filename self.lines = lines self.expected = expected or () self.line_offset = line_offset self.file_errors = 0 self.counters['files'] += 1 self.counters['physical lines'] += len(lines) def increment_logical_line(self): """Signal a new logical line.""" self.counters['logical lines'] += 1 def error(self, line_number, offset, text, check): """Report an error, according to options.""" code = text[:4] if self._ignore_code(code): return if code in self.counters: self.counters[code] += 1 else: self.counters[code] = 1 self.messages[code] = [] # Don't care about expected errors or warnings if code in self.expected: return if self.print_filename and not self.file_errors: print(self.filename) self.file_errors += 1 self.total_errors += 1 return code def error_args(self, line_number, offset, text, check, *args): """Report an error, according to options.""" code = text[:4] if self._ignore_code(code): return if code in self.counters: self.counters[code] += 1 else: self.counters[code] = 1 self.messages[code] = args # Don't care about expected errors or warnings if code in self.expected: return if self.print_filename and not self.file_errors: print(self.filename) self.file_errors += 1 self.total_errors += 1 return code def get_file_results(self): """Return the count of errors and warnings for this file.""" return self.file_errors def get_count(self, prefix=''): """Return the total count of errors and warnings.""" return sum([self.counters[key] for key in self.messages if key.startswith(prefix)]) def get_statistics(self, prefix=''): """Get statistics for message codes that start with the prefix. prefix='' matches all errors and warnings prefix='E' matches all errors prefix='W' matches all warnings prefix='E4' matches all errors that have to do with imports """ return ['%-7s %s %s' % (self.counters[key], key, self.messages[key]) for key in sorted(self.messages) if key.startswith(prefix)] def print_statistics(self, prefix=''): """Print overall statistics (number of errors and warnings).""" for line in self.get_statistics(prefix): print(line) def print_benchmark(self): """Print benchmark numbers.""" print('%-7.2f %s' % (self.elapsed, 'seconds elapsed')) if self.elapsed: for key in self._benchmark_keys: print('%-7d %s per second (%d total)' % (self.counters[key] / self.elapsed, key, self.counters[key])) class FileReport(BaseReport): """Collect the results of the checks and print only the filenames.""" print_filename = True class StandardReport(BaseReport): """Collect and print the results of the checks.""" def __init__(self, options): super(StandardReport, self).__init__(options) self._fmt = REPORT_FORMAT.get(options.format.lower(), options.format) self._repeat = options.repeat self._show_source = options.show_source self._show_pep8 = options.show_pep8 def init_file(self, filename, lines, expected, line_offset): """Signal a new file.""" self._deferred_print = [] return super(StandardReport, self).init_file( filename, lines, expected, line_offset) def error(self, line_number, offset, text, check): """Report an error, according to options.""" code = super(StandardReport, self).error(line_number, offset, text, check) if code and (self.counters[code] == 1 or self._repeat): self._deferred_print.append( (line_number, offset, code, text[5:], check.__doc__)) return code def error_args(self, line_number, offset, code, check, *args): """Report an error, according to options.""" code = super(StandardReport, self).error_args(line_number, offset, code, check, *args) if code and (self.counters[code] == 1 or self._repeat): self._deferred_print.append( (line_number, offset, code, args, check.__doc__)) return code def get_file_results(self): """Print the result and return the overall count for this file.""" self._deferred_print.sort() for line_number, offset, code, text, doc in self._deferred_print: print(self._fmt % { 'path': self.filename, 'row': self.line_offset + line_number, 'col': offset + 1, 'code': code, 'text': text, }) if self._show_source: if line_number > len(self.lines): line = '' else: line = self.lines[line_number - 1] print(line.rstrip()) print(re.sub(r'\S', ' ', line[:offset]) + '^') if self._show_pep8 and doc: print(' ' + doc.strip()) return self.file_errors class DiffReport(StandardReport): """Collect and print the results for the changed lines only.""" def __init__(self, options): super(DiffReport, self).__init__(options) self._selected = options.selected_lines def error(self, line_number, offset, text, check): if line_number not in self._selected[self.filename]: return return super(DiffReport, self).error(line_number, offset, text, check) class StyleGuide(object): """Initialize a PEP-8 instance with few options.""" def __init__(self, *args, **kwargs): # build options from the command line self.checker_class = kwargs.pop('checker_class', Checker) parse_argv = kwargs.pop('parse_argv', False) config_file = kwargs.pop('config_file', None) parser = kwargs.pop('parser', None) # build options from dict options_dict = dict(*args, **kwargs) arglist = None if parse_argv else options_dict.get('paths', None) options, self.paths = process_options( arglist, parse_argv, config_file, parser) if options_dict: options.__dict__.update(options_dict) if 'paths' in options_dict: self.paths = options_dict['paths'] self.runner = self.input_file self.options = options if not options.reporter: options.reporter = BaseReport if options.quiet else StandardReport options.select = tuple(options.select or ()) # if not (options.select or options.ignore or # options.testsuite or options.doctest) and DEFAULT_IGNORE: # # The default choice: ignore controversial checks # options.ignore = tuple(DEFAULT_IGNORE.split(',')) # else: # Ignore all checks which are not explicitly selected or all if no # check is ignored or explicitly selected options.ignore = ('',) if options.select else tuple(options.ignore) options.benchmark_keys = BENCHMARK_KEYS[:] options.ignore_code = self.ignore_code options.physical_checks = self.get_checks('physical_line') options.logical_checks = self.get_checks('logical_line') options.ast_checks = self.get_checks('tree') self.init_report() def init_report(self, reporter=None): """Initialize the report instance.""" self.options.report = (reporter or self.options.reporter)(self.options) return self.options.report def check_files(self, paths=None): """Run all checks on the paths.""" if paths is None: paths = self.paths report = self.options.report runner = self.runner report.start() try: for path in paths: if os.path.isdir(path): self.input_dir(path) elif not self.excluded(path): runner(path) except KeyboardInterrupt: print('... stopped') report.stop() return report def input_file(self, filename, lines=None, expected=None, line_offset=0): """Run all checks on a Python source file.""" if self.options.verbose: print('checking %s' % filename) fchecker = self.checker_class( filename, lines=lines, options=self.options) return fchecker.check_all(expected=expected, line_offset=line_offset) def input_dir(self, dirname): """Check all files in this directory and all subdirectories.""" dirname = dirname.rstrip('/') if self.excluded(dirname): return 0 counters = self.options.report.counters verbose = self.options.verbose filepatterns = self.options.filename runner = self.runner for root, dirs, files in os.walk(dirname): if verbose: print('directory ' + root) counters['directories'] += 1 for subdir in sorted(dirs): if self.excluded(subdir, root): dirs.remove(subdir) for filename in sorted(files): # contain a pattern that matches? if ((filename_match(filename, filepatterns) and not self.excluded(filename, root))): runner(os.path.join(root, filename)) def excluded(self, filename, parent=None): """Check if the file should be excluded. Check if 'options.exclude' contains a pattern that matches filename. """ if not self.options.exclude: return False basename = os.path.basename(filename) if filename_match(basename, self.options.exclude): return True if parent: filename = os.path.join(parent, filename) filename = os.path.abspath(filename) return filename_match(filename, self.options.exclude) def ignore_code(self, code): """Check if the error code should be ignored. If 'options.select' contains a prefix of the error code, return False. Else, if 'options.ignore' contains a prefix of the error code, return True. """ if len(code) < 4 and any(s.startswith(code) for s in self.options.select): return False return (code.startswith(self.options.ignore) and not code.startswith(self.options.select)) def get_checks(self, argument_name): """Get all the checks for this category. Find all globally visible functions where the first argument name starts with argument_name and which contain selected tests. """ checks = [] for check, attrs in _checks[argument_name].items(): (codes, args) = attrs if any(not (code and self.ignore_code(code)) for code in codes): checks.append((check.__name__, check, args)) return sorted(checks) def get_parser(prog='pep8', version=__version__): parser = OptionParser(prog=prog, version=version, usage="%prog [options] input ...") parser.config_options = [ 'exclude', 'filename', 'select', 'ignore', 'max-line-length', 'hang-closing', 'count', 'format', 'quiet', 'show-pep8', 'show-source', 'statistics', 'verbose'] parser.add_option('-v', '--verbose', default=0, action='count', help="print status messages, or debug with -vv") parser.add_option('-q', '--quiet', default=0, action='count', help="report only file names, or nothing with -qq") parser.add_option('-r', '--repeat', default=True, action='store_true', help="(obsolete) show all occurrences of the same error") parser.add_option('--first', action='store_false', dest='repeat', help="show first occurrence of each error") parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE, help="exclude files or directories which match these " "comma separated patterns (default: %default)") parser.add_option('--filename', metavar='patterns', default='*.py', help="when parsing directories, only check filenames " "matching these comma separated patterns " "(default: %default)") parser.add_option('--select', metavar='errors', default='', help="select errors and warnings (e.g. E,W6)") parser.add_option('--ignore', metavar='errors', default='', help="skip errors and warnings (e.g. E4,W)") parser.add_option('--show-source', action='store_true', help="show source code for each error") parser.add_option('--show-pep8', action='store_true', help="show text of PEP 8 for each error " "(implies --first)") parser.add_option('--statistics', action='store_true', help="count errors and warnings") parser.add_option('--count', action='store_true', help="print total number of errors and warnings " "to standard error and set exit code to 1 if " "total is not null") parser.add_option('--max-line-length', type='int', metavar='n', default=MAX_LINE_LENGTH, help="set maximum allowed line length " "(default: %default)") parser.add_option('--hang-closing', action='store_true', help="hang closing bracket instead of matching " "indentation of opening bracket's line") parser.add_option('--format', metavar='format', default='default', help="set the error format [default|pylint|]") parser.add_option('--diff', action='store_true', help="report only lines changed according to the " "unified diff received on STDIN") group = parser.add_option_group("Testing Options") if os.path.exists(TESTSUITE_PATH): group.add_option('--testsuite', metavar='dir', help="run regression tests from dir") group.add_option('--doctest', action='store_true', help="run doctest on myself") group.add_option('--benchmark', action='store_true', help="measure processing speed") return parser def read_config(options, args, arglist, parser): """Read both user configuration and local configuration.""" config = RawConfigParser() user_conf = options.config if user_conf and os.path.isfile(user_conf): if options.verbose: print('user configuration: %s' % user_conf) config.read(user_conf) local_dir = os.curdir parent = tail = args and os.path.abspath(os.path.commonprefix(args)) while tail: if config.read([os.path.join(parent, fn) for fn in PROJECT_CONFIG]): local_dir = parent if options.verbose: print('local configuration: in %s' % parent) break (parent, tail) = os.path.split(parent) pep8_section = parser.prog if config.has_section(pep8_section): option_list = dict([(o.dest, o.type or o.action) for o in parser.option_list]) # First, read the default values (new_options, __) = parser.parse_args([]) # Second, parse the configuration for opt in config.options(pep8_section): if options.verbose > 1: print(" %s = %s" % (opt, config.get(pep8_section, opt))) if opt.replace('_', '-') not in parser.config_options: print("Unknown option: '%s'\n not in [%s]" % (opt, ' '.join(parser.config_options))) sys.exit(1) normalized_opt = opt.replace('-', '_') opt_type = option_list[normalized_opt] if opt_type in ('int', 'count'): value = config.getint(pep8_section, opt) elif opt_type == 'string': value = config.get(pep8_section, opt) if normalized_opt == 'exclude': value = normalize_paths(value, local_dir) else: assert opt_type in ('store_true', 'store_false') value = config.getboolean(pep8_section, opt) setattr(new_options, normalized_opt, value) # Third, overwrite with the command-line options (options, __) = parser.parse_args(arglist, values=new_options) options.doctest = options.testsuite = False return options def process_options(arglist=None, parse_argv=False, config_file=None, parser=None): """Process options passed either via arglist or via command line args.""" if not parser: parser = get_parser() if not parser.has_option('--config'): if config_file is True: config_file = DEFAULT_CONFIG group = parser.add_option_group("Configuration", description=( "The project options are read from the [%s] section of the " "tox.ini file or the setup.cfg file located in any parent folder " "of the path(s) being processed. Allowed options are: %s." % (parser.prog, ', '.join(parser.config_options)))) group.add_option('--config', metavar='path', default=config_file, help="user config file location (default: %default)") # Don't read the command line if the module is used as a library. if not arglist and not parse_argv: arglist = [] # If parse_argv is True and arglist is None, arguments are # parsed from the command line (sys.argv) (options, args) = parser.parse_args(arglist) options.reporter = None if options.ensure_value('testsuite', False): args.append(options.testsuite) elif not options.ensure_value('doctest', False): if parse_argv and not args: if options.diff or any(os.path.exists(name) for name in PROJECT_CONFIG): args = ['.'] else: parser.error('input not specified') options = read_config(options, args, arglist, parser) options.reporter = parse_argv and options.quiet == 1 and FileReport options.filename = options.filename and options.filename.split(',') options.exclude = normalize_paths(options.exclude) options.select = options.select and options.select.split(',') options.ignore = options.ignore and options.ignore.split(',') if options.diff: options.reporter = DiffReport stdin = stdin_get_value() options.selected_lines = parse_udiff(stdin, options.filename, args[0]) args = sorted(options.selected_lines) return options, args def _main(): """Parse options and run checks on Python source.""" pep8style = StyleGuide(parse_argv=True, config_file=True) options = pep8style.options if options.doctest or options.testsuite: from testsuite.support import run_tests report = run_tests(pep8style) else: report = pep8style.check_files() if options.statistics: report.print_statistics() if options.benchmark: report.print_benchmark() if options.testsuite and not options.quiet: report.print_results() if report.total_errors: if options.count: sys.stderr.write(str(report.total_errors) + '\n') sys.exit(1) if __name__ == '__main__': _main() eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/__init__.py0000644000175000017500000000025112451233371024264 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Package containing the code style checker and fixer plug-in. """ eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py0000644000175000017500000001503312451233371025711 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the code style checker. """ import sys import pep8 from NamingStyleChecker import NamingStyleChecker # register the name checker pep8.register_check(NamingStyleChecker, NamingStyleChecker.Codes) from DocStyleChecker import DocStyleChecker def initService(): """ Initialize the service and return the entry point. @return the entry point for the background client (function) """ return codeStyleCheck class CodeStyleCheckerReport(pep8.BaseReport): """ Class implementing a special report to be used with our dialog. """ def __init__(self, options): """ Constructor @param options options for the report (optparse.Values) """ super(CodeStyleCheckerReport, self).__init__(options) self.__repeat = options.repeat self.errors = [] def error_args(self, line_number, offset, code, check, *args): """ Public method to collect the error messages. @param line_number line number of the issue (integer) @param offset position within line of the issue (integer) @param code message code (string) @param check reference to the checker function (function) @param args arguments for the message (list) @return error code (string) """ code = super(CodeStyleCheckerReport, self).error_args( line_number, offset, code, check, *args) if code and (self.counters[code] == 1 or self.__repeat): self.errors.append( (self.filename, line_number, offset, (code, args)) ) return code def extractLineFlags(line, startComment="#", endComment=""): """ Function to extract flags starting and ending with '__' from a line comment. @param line line to extract flags from (string) @keyparam startComment string identifying the start of the comment (string) @keyparam endComment string identifying the end of a comment (string) @return list containing the extracted flags (list of strings) """ flags = [] pos = line.rfind(startComment) if pos >= 0: comment = line[pos + len(startComment):].strip() if endComment: comment = comment.replace("endComment", "") flags = [f.strip() for f in comment.split() if (f.startswith("__") and f.endswith("__"))] return flags def codeStyleCheck(filename, source, args): """ Do the code style check and/ or fix found errors. @param filename source filename (string) @param source string containing the code to check (string) @param args arguments used by the codeStyleCheck function (list of excludeMessages (str), includeMessages (str), repeatMessages (bool), fixCodes (str), noFixCodes (str), fixIssues (bool), maxLineLength (int), hangClosing (bool), docType (str), errors (list of str), eol (str), encoding (str), backup (bool)) @return tuple of stats (dict) and results (tuple for each found violation of style (tuple of lineno (int), position (int), text (str), ignored (bool), fixed (bool), autofixing (bool), fixedMsg (str))) """ excludeMessages, includeMessages, \ repeatMessages, fixCodes, noFixCodes, fixIssues, maxLineLength, \ hangClosing, docType, errors, eol, encoding, backup = args stats = {} if fixIssues: from CodeStyleFixer import CodeStyleFixer fixer = CodeStyleFixer( filename, source, fixCodes, noFixCodes, maxLineLength, True, eol, backup) # always fix in place else: fixer = None if not errors: # avoid 'Encoding declaration in unicode string' exception on Python2 if sys.version_info[0] == 2: if encoding == 'utf-8-bom': enc = 'utf-8' else: enc = encoding source = [line.encode(enc) for line in source] if includeMessages: select = [s.strip() for s in includeMessages.split(',') if s.strip()] else: select = [] if excludeMessages: ignore = [i.strip() for i in excludeMessages.split(',') if i.strip()] else: ignore = [] # check coding style styleGuide = pep8.StyleGuide( reporter=CodeStyleCheckerReport, repeat=repeatMessages, select=select, ignore=ignore, max_line_length=maxLineLength, hang_closing=hangClosing, ) report = styleGuide.check_files([filename]) stats.update(report.counters) # check documentation style docStyleChecker = DocStyleChecker( source, filename, select, ignore, [], repeatMessages, maxLineLength=maxLineLength, docType=docType) docStyleChecker.run() stats.update(docStyleChecker.counters) errors = report.errors + docStyleChecker.errors deferredFixes = {} results = [] for fname, lineno, position, text in errors: if lineno > len(source): lineno = len(source) if source: if "__IGNORE_WARNING__" not in \ extractLineFlags(source[lineno - 1].strip()): if fixer: res, msg, id_ = fixer.fixIssue(lineno, position, text) if res == -1: itm = [lineno, position, text] deferredFixes[id_] = itm else: itm = [lineno, position, text, False, res == 1, True, msg] else: itm = [lineno, position, text, False, False, False, ''] results.append(itm) else: results.append([lineno, position, text, True, False, False, '']) else: results.append([lineno, position, text, False, False, False, '']) if fixer: deferredResults = fixer.finalize() for id_ in deferredResults: fixed, msg = deferredResults[id_] itm = deferredFixes[id_] itm.extend([False, fixed == 1, True, msg]) errMsg = fixer.saveFile(encoding) if errMsg: for result in results: result[-1] = errMsg return stats, results eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.py0000644000175000017500000000653012451233371027621 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog showing statistical data for the last code style checker run. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QDialog, QTreeWidgetItem from .translations import _messages, _messages_sample_args from .Ui_CodeStyleStatisticsDialog import Ui_CodeStyleStatisticsDialog import UI.PixmapCache class CodeStyleStatisticsDialog(QDialog, Ui_CodeStyleStatisticsDialog): """ Class implementing a dialog showing statistical data for the last code style checker run. """ def __init__(self, statistics, parent=None): """ Constructor @param statistics dictionary with the statistical data @param parent reference to the parent widget (QWidget) """ super(CodeStyleStatisticsDialog, self).__init__(parent) self.setupUi(self) stats = statistics.copy() filesCount = stats["_FilesCount"] filesIssues = stats["_FilesIssues"] fixesCount = stats["_IssuesFixed"] ignoresCount = stats["_IgnoredErrors"] del stats["_FilesCount"] del stats["_FilesIssues"] del stats["_IssuesFixed"] del stats["_IgnoredErrors"] totalIssues = 0 for code in sorted(stats.keys()): message = _messages.get(code) if message is None: continue if code in _messages_sample_args: message = message.format(*_messages_sample_args[code]) self.__createItem(stats[code], code, message) totalIssues += stats[code] self.totalIssues.setText( self.tr("%n issue(s) found", "", totalIssues)) self.ignoredIssues.setText( self.tr("%n issue(s) ignored", "", ignoresCount)) self.fixedIssues.setText( self.tr("%n issue(s) fixed", "", fixesCount)) self.filesChecked.setText( self.tr("%n file(s) checked", "", filesCount)) self.filesIssues.setText( self.tr("%n file(s) with issues found", "", filesIssues)) self.statisticsList.resizeColumnToContents(0) self.statisticsList.resizeColumnToContents(1) def __createItem(self, count, code, message): """ Private method to create an entry in the result list. @param count occurrences of the issue (integer) @param code of a code style issue message (string) @param message code style issue message to be shown (string) """ itm = QTreeWidgetItem(self.statisticsList) itm.setData(0, Qt.DisplayRole, count) itm.setData(1, Qt.DisplayRole, code) itm.setData(2, Qt.DisplayRole, message) if code.startswith("W"): itm.setIcon(1, UI.PixmapCache.getIcon("warning.png")) elif code.startswith("E"): itm.setIcon(1, UI.PixmapCache.getIcon("syntaxError.png")) elif code.startswith("N"): itm.setIcon(1, UI.PixmapCache.getIcon("namingError.png")) elif code.startswith("D"): itm.setIcon(1, UI.PixmapCache.getIcon("docstringError.png")) itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(1, Qt.AlignHCenter) eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py0000644000175000017500000010325512537064320027036 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the results of the code style check. """ from __future__ import unicode_literals import os import fnmatch from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QAbstractButton, \ QDialogButtonBox, QApplication, QHeaderView from E5Gui.E5Application import e5App from .Ui_CodeStyleCheckerDialog import Ui_CodeStyleCheckerDialog import UI.PixmapCache import Preferences import Utilities from . import pep8 class CodeStyleCheckerDialog(QDialog, Ui_CodeStyleCheckerDialog): """ Class implementing a dialog to show the results of the code style check. """ filenameRole = Qt.UserRole + 1 lineRole = Qt.UserRole + 2 positionRole = Qt.UserRole + 3 messageRole = Qt.UserRole + 4 fixableRole = Qt.UserRole + 5 codeRole = Qt.UserRole + 6 ignoredRole = Qt.UserRole + 7 def __init__(self, styleCheckService, parent=None): """ Constructor @param styleCheckService reference to the service (CodeStyleCheckService) @param parent reference to the parent widget (QWidget) """ super(CodeStyleCheckerDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.excludeMessagesSelectButton.setIcon( UI.PixmapCache.getIcon("select.png")) self.includeMessagesSelectButton.setIcon( UI.PixmapCache.getIcon("select.png")) self.fixIssuesSelectButton.setIcon( UI.PixmapCache.getIcon("select.png")) self.noFixIssuesSelectButton.setIcon( UI.PixmapCache.getIcon("select.png")) self.docTypeComboBox.addItem(self.tr("PEP-257"), "pep257") self.docTypeComboBox.addItem(self.tr("Eric"), "eric") self.statisticsButton = self.buttonBox.addButton( self.tr("Statistics..."), QDialogButtonBox.ActionRole) self.statisticsButton.setToolTip( self.tr("Press to show some statistics for the last run")) self.statisticsButton.setEnabled(False) self.showButton = self.buttonBox.addButton( self.tr("Show"), QDialogButtonBox.ActionRole) self.showButton.setToolTip( self.tr("Press to show all files containing an issue")) self.showButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.resultList.headerItem().setText(self.resultList.columnCount(), "") self.resultList.header().setSortIndicator(0, Qt.AscendingOrder) self.checkProgress.setVisible(False) self.checkProgressLabel.setVisible(False) self.checkProgressLabel.setMaximumWidth(600) self.styleCheckService = styleCheckService self.styleCheckService.styleChecked.connect(self.__processResult) self.filename = None self.noResults = True self.cancelled = False self.__lastFileItem = None self.__fileOrFileList = "" self.__project = None self.__forProject = False self.__data = {} self.__statistics = {} self.__onlyFixes = {} self.on_loadDefaultButton_clicked() def __resort(self): """ Private method to resort the tree. """ self.resultList.sortItems(self.resultList.sortColumn(), self.resultList.header().sortIndicatorOrder() ) def __createResultItem(self, file, line, pos, message, fixed, autofixing, ignored): """ Private method to create an entry in the result list. @param file file name of the file (string) @param line line number of issue (integer or string) @param pos character position of issue (integer or string) @param message message text (string) @param fixed flag indicating a fixed issue (boolean) @param autofixing flag indicating, that we are fixing issues automatically (boolean) @param ignored flag indicating an ignored issue (boolean) @return reference to the created item (QTreeWidgetItem) """ from .CodeStyleFixer import FixableCodeStyleIssues if self.__lastFileItem is None: # It's a new file self.__lastFileItem = QTreeWidgetItem(self.resultList, [file]) self.__lastFileItem.setFirstColumnSpanned(True) self.__lastFileItem.setExpanded(True) self.__lastFileItem.setData(0, self.filenameRole, file) fixable = False code, message = message.split(None, 1) itm = QTreeWidgetItem( self.__lastFileItem, ["{0:6}".format(line), code, message]) if code.startswith(("W", "-")): itm.setIcon(1, UI.PixmapCache.getIcon("warning.png")) elif code.startswith("N"): itm.setIcon(1, UI.PixmapCache.getIcon("namingError.png")) elif code.startswith("D"): itm.setIcon(1, UI.PixmapCache.getIcon("docstringError.png")) else: itm.setIcon(1, UI.PixmapCache.getIcon("syntaxError.png")) if fixed: itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed.png")) elif code in FixableCodeStyleIssues and not autofixing: itm.setIcon(0, UI.PixmapCache.getIcon("issueFixable.png")) fixable = True itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(1, Qt.AlignHCenter) itm.setTextAlignment(0, Qt.AlignVCenter) itm.setTextAlignment(1, Qt.AlignVCenter) itm.setTextAlignment(2, Qt.AlignVCenter) itm.setData(0, self.filenameRole, file) itm.setData(0, self.lineRole, int(line)) itm.setData(0, self.positionRole, int(pos)) itm.setData(0, self.messageRole, message) itm.setData(0, self.fixableRole, fixable) itm.setData(0, self.codeRole, code) itm.setData(0, self.ignoredRole, ignored) if ignored: font = itm.font(0) font.setItalic(True) for col in range(itm.columnCount()): itm.setFont(col, font) return itm def __modifyFixedResultItem(self, itm, text, fixed): """ Private method to modify a result list entry to show its positive fixed state. @param itm reference to the item to modify (QTreeWidgetItem) @param text text to be appended (string) @param fixed flag indicating a fixed issue (boolean) """ if fixed: code, message = text.split(None, 1) itm.setText(2, message) itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed.png")) itm.setData(0, self.messageRole, message) else: itm.setIcon(0, QIcon()) itm.setData(0, self.fixableRole, False) def __updateStatistics(self, statistics, fixer, ignoredErrors): """ Private method to update the collected statistics. @param statistics dictionary of statistical data with message code as key and message count as value @param fixer reference to the code style fixer (CodeStyleFixer) @param ignoredErrors number of ignored errors (integer) """ self.__statistics["_FilesCount"] += 1 stats = [k for k in statistics.keys() if k[0].isupper()] if stats: self.__statistics["_FilesIssues"] += 1 for key in statistics: if key in self.__statistics: self.__statistics[key] += statistics[key] else: self.__statistics[key] = statistics[key] self.__statistics["_IssuesFixed"] += fixer self.__statistics["_IgnoredErrors"] += ignoredErrors def __updateFixerStatistics(self, fixer): """ Private method to update the collected fixer related statistics. @param fixer reference to the code style fixer (CodeStyleFixer) """ self.__statistics["_IssuesFixed"] += fixer def __resetStatistics(self): """ Private slot to reset the statistics data. """ self.__statistics = {} self.__statistics["_FilesCount"] = 0 self.__statistics["_FilesIssues"] = 0 self.__statistics["_IssuesFixed"] = 0 self.__statistics["_IgnoredErrors"] = 0 def prepare(self, fileList, project): """ Public method to prepare the dialog with a list of filenames. @param fileList list of filenames (list of strings) @param project reference to the project object (Project) """ self.__fileOrFileList = fileList[:] self.__project = project self.__forProject = True self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.__data = self.__project.getData("CHECKERSPARMS", "Pep8Checker") if self.__data is None or \ len(self.__data) < 6: # initialize the data structure self.__data = { "ExcludeFiles": "", "ExcludeMessages": pep8.DEFAULT_IGNORE, "IncludeMessages": "", "RepeatMessages": False, "FixCodes": "", "FixIssues": False, } if "MaxLineLength" not in self.__data: self.__data["MaxLineLength"] = pep8.MAX_LINE_LENGTH if "HangClosing" not in self.__data: self.__data["HangClosing"] = False if "NoFixCodes" not in self.__data: self.__data["NoFixCodes"] = "E501" if "DocstringType" not in self.__data: self.__data["DocstringType"] = "pep257" if "ShowIgnored" not in self.__data: self.__data["ShowIgnored"] = False self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) self.excludeMessagesEdit.setText(self.__data["ExcludeMessages"]) self.includeMessagesEdit.setText(self.__data["IncludeMessages"]) self.repeatCheckBox.setChecked(self.__data["RepeatMessages"]) self.fixIssuesEdit.setText(self.__data["FixCodes"]) self.noFixIssuesEdit.setText(self.__data["NoFixCodes"]) self.fixIssuesCheckBox.setChecked(self.__data["FixIssues"]) self.ignoredCheckBox.setChecked(self.__data["ShowIgnored"]) self.lineLengthSpinBox.setValue(self.__data["MaxLineLength"]) self.hangClosingCheckBox.setChecked(self.__data["HangClosing"]) self.docTypeComboBox.setCurrentIndex( self.docTypeComboBox.findData(self.__data["DocstringType"])) def start(self, fn, save=False, repeat=None): """ Public slot to start the code style check. @param fn file or list of files or directory to be checked (string or list of strings) @keyparam save flag indicating to save the given file/file list/directory (boolean) @keyparam repeat state of the repeat check box if it is not None (None or boolean) """ if self.__project is None: self.__project = e5App().getObject("Project") self.cancelled = False self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.statisticsButton.setEnabled(False) self.showButton.setEnabled(False) self.fixButton.setEnabled(False) self.startButton.setEnabled(False) if repeat is not None: self.repeatCheckBox.setChecked(repeat) self.checkProgress.setVisible(True) QApplication.processEvents() if save: self.__fileOrFileList = fn if isinstance(fn, list): self.files = fn[:] elif os.path.isdir(fn): self.files = [] extensions = set(Preferences.getPython("PythonExtensions") + Preferences.getPython("Python3Extensions")) for ext in extensions: self.files.extend(Utilities.direntries( fn, True, '*{0}'.format(ext), 0)) else: self.files = [fn] # filter the list depending on the filter string if self.files: filterString = self.excludeFilesEdit.text() filterList = [f.strip() for f in filterString.split(",") if f.strip()] for filter in filterList: self.files = \ [f for f in self.files if not fnmatch.fnmatch(f, filter.strip())] self.__resetStatistics() self.__clearErrors(self.files) if len(self.files) > 0: self.checkProgress.setMaximum(len(self.files)) self.checkProgressLabel.setVisible(len(self.files) > 1) self.checkProgress.setVisible(len(self.files) > 1) QApplication.processEvents() # extract the configuration values excludeMessages = self.excludeMessagesEdit.text() includeMessages = self.includeMessagesEdit.text() repeatMessages = self.repeatCheckBox.isChecked() fixCodes = self.fixIssuesEdit.text() noFixCodes = self.noFixIssuesEdit.text() fixIssues = self.fixIssuesCheckBox.isChecked() and repeatMessages self.showIgnored = self.ignoredCheckBox.isChecked() and \ repeatMessages maxLineLength = self.lineLengthSpinBox.value() hangClosing = self.hangClosingCheckBox.isChecked() docType = self.docTypeComboBox.itemData( self.docTypeComboBox.currentIndex()) self.__options = [excludeMessages, includeMessages, repeatMessages, fixCodes, noFixCodes, fixIssues, maxLineLength, hangClosing, docType] # now go through all the files self.progress = 0 self.files.sort() self.check() def check(self, codestring=''): """ Public method to start a style check for one file. The results are reported to the __processResult slot. @keyparam codestring optional sourcestring (str) """ if not self.files: self.checkProgressLabel.setPath("") self.checkProgress.setMaximum(1) self.checkProgress.setValue(1) self.__finish() return self.filename = self.files.pop(0) self.checkProgress.setValue(self.progress) self.checkProgressLabel.setPath(self.filename) QApplication.processEvents() if self.cancelled: self.__resort() return self.__lastFileItem = None if codestring: self.source = codestring else: try: self.source, encoding = Utilities.readEncodedFile( self.filename) if encoding.endswith( ('-selected', '-default', '-guessed', '-ignore')): encoding = encoding.rsplit('-', 1)[0] self.source = self.source.splitlines(True) except (UnicodeError, IOError) as msg: self.noResults = False self.__createResultItem( self.filename, 1, 1, self.tr("Error: {0}").format(str(msg)) .rstrip(), False, False, False) self.progress += 1 # Continue with next file self.check() return errors = [] self.__itms = [] for error, itm in self.__onlyFixes.pop(self.filename, []): errors.append(error) self.__itms.append(itm) eol = self.__getEol(self.filename) args = self.__options + [ errors, eol, encoding, Preferences.getEditor("CreateBackupFile") ] self.styleCheckService.styleCheck( None, self.filename, self.source, args) def __processResult(self, fn, codeStyleCheckerStats, fixes, results): """ Private slot called after perfoming a style check on one file. @param fn filename of the just checked file (str) @param codeStyleCheckerStats stats of style and name check (dict) @param fixes number of applied fixes (int) @param results tuple for each found violation of style (tuple of lineno (int), position (int), text (str), ignored (bool), fixed (bool), autofixing (bool)) """ # Check if it's the requested file, otherwise ignore signal if fn != self.filename: return # disable updates of the list for speed self.resultList.setUpdatesEnabled(False) self.resultList.setSortingEnabled(False) fixed = None ignoredErrors = 0 if self.__itms: for itm, (lineno, position, text, ignored, fixed, autofixing) in \ zip(self.__itms, results): self.__modifyFixedResultItem(itm, text, fixed) self.__updateFixerStatistics(fixes) else: for lineno, position, text, ignored, fixed, autofixing in results: if ignored: ignoredErrors += 1 if self.showIgnored: text = self.tr("{0} (ignored)").format(text) else: continue self.noResults = False self.__createResultItem( fn, lineno, position, text, fixed, autofixing, ignored) self.__updateStatistics( codeStyleCheckerStats, fixes, ignoredErrors) if fixed: vm = e5App().getObject("ViewManager") editor = vm.getOpenEditor(fn) if editor: editor.refresh() self.progress += 1 self.__resort() # reenable updates of the list self.resultList.setSortingEnabled(True) self.resultList.setUpdatesEnabled(True) self.checkProgress.setValue(self.progress) QApplication.processEvents() self.check() def __finish(self): """ Private slot called when the code style check finished or the user pressed the cancel button. """ self.cancelled = True self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.statisticsButton.setEnabled(True) self.showButton.setEnabled(True) self.startButton.setEnabled(True) if self.noResults: QTreeWidgetItem(self.resultList, [self.tr('No issues found.')]) QApplication.processEvents() self.statisticsButton.setEnabled(False) self.showButton.setEnabled(False) else: self.statisticsButton.setEnabled(True) self.showButton.setEnabled(True) self.resultList.header().resizeSections(QHeaderView.ResizeToContents) self.resultList.header().setStretchLastSection(True) self.checkProgress.setVisible(False) self.checkProgressLabel.setVisible(False) def __getEol(self, fn): """ Private method to get the applicable eol string. @param fn filename where to determine the line ending (str) @return eol string (string) """ if self.__project.isOpen() and self.__project.isProjectFile(fn): eol = self.__project.getEolString() else: eol = Utilities.linesep() return eol @pyqtSlot() def on_startButton_clicked(self): """ Private slot to start a code style check run. """ if self.__forProject: data = { "ExcludeFiles": self.excludeFilesEdit.text(), "ExcludeMessages": self.excludeMessagesEdit.text(), "IncludeMessages": self.includeMessagesEdit.text(), "RepeatMessages": self.repeatCheckBox.isChecked(), "FixCodes": self.fixIssuesEdit.text(), "NoFixCodes": self.noFixIssuesEdit.text(), "FixIssues": self.fixIssuesCheckBox.isChecked(), "ShowIgnored": self.ignoredCheckBox.isChecked(), "MaxLineLength": self.lineLengthSpinBox.value(), "HangClosing": self.hangClosingCheckBox.isChecked(), "DocstringType": self.docTypeComboBox.itemData( self.docTypeComboBox.currentIndex()), } if data != self.__data: self.__data = data self.__project.setData("CHECKERSPARMS", "Pep8Checker", self.__data) self.resultList.clear() self.noResults = True self.cancelled = False self.start(self.__fileOrFileList) def __selectCodes(self, edit, showFixCodes): """ Private method to select message codes via a selection dialog. @param edit reference of the line edit to be populated (QLineEdit) @param showFixCodes flag indicating to show a list of fixable issues (boolean) """ from .CodeStyleCodeSelectionDialog import CodeStyleCodeSelectionDialog dlg = CodeStyleCodeSelectionDialog(edit.text(), showFixCodes, self) if dlg.exec_() == QDialog.Accepted: edit.setText(dlg.getSelectedCodes()) @pyqtSlot() def on_excludeMessagesSelectButton_clicked(self): """ Private slot to select the message codes to be excluded via a selection dialog. """ self.__selectCodes(self.excludeMessagesEdit, False) @pyqtSlot() def on_includeMessagesSelectButton_clicked(self): """ Private slot to select the message codes to be included via a selection dialog. """ self.__selectCodes(self.includeMessagesEdit, False) @pyqtSlot() def on_fixIssuesSelectButton_clicked(self): """ Private slot to select the issue codes to be fixed via a selection dialog. """ self.__selectCodes(self.fixIssuesEdit, True) @pyqtSlot() def on_noFixIssuesSelectButton_clicked(self): """ Private slot to select the issue codes not to be fixed via a selection dialog. """ self.__selectCodes(self.noFixIssuesEdit, True) @pyqtSlot(QTreeWidgetItem, int) def on_resultList_itemActivated(self, item, column): """ Private slot to handle the activation of an item. @param item reference to the activated item (QTreeWidgetItem) @param column column the item was activated in (integer) """ if self.noResults: return if item.parent(): fn = Utilities.normabspath(item.data(0, self.filenameRole)) lineno = item.data(0, self.lineRole) position = item.data(0, self.positionRole) message = item.data(0, self.messageRole) code = item.data(0, self.codeRole) vm = e5App().getObject("ViewManager") vm.openSourceFile(fn, lineno=lineno, pos=position + 1) editor = vm.getOpenEditor(fn) if code in ["E901", "E902"]: editor.toggleSyntaxError(lineno, 0, True, message, True) else: editor.toggleWarning( lineno, 0, True, message, warningType=editor.WarningStyle) @pyqtSlot() def on_resultList_itemSelectionChanged(self): """ Private slot to change the dialog state depending on the selection. """ self.fixButton.setEnabled(len(self.__getSelectedFixableItems()) > 0) @pyqtSlot() def on_showButton_clicked(self): """ Private slot to handle the "Show" button press. """ vm = e5App().getObject("ViewManager") selectedIndexes = [] for index in range(self.resultList.topLevelItemCount()): if self.resultList.topLevelItem(index).isSelected(): selectedIndexes.append(index) if len(selectedIndexes) == 0: selectedIndexes = list(range(self.resultList.topLevelItemCount())) for index in selectedIndexes: itm = self.resultList.topLevelItem(index) fn = Utilities.normabspath(itm.data(0, self.filenameRole)) vm.openSourceFile(fn, 1) editor = vm.getOpenEditor(fn) editor.clearStyleWarnings() for cindex in range(itm.childCount()): citm = itm.child(cindex) lineno = citm.data(0, self.lineRole) message = citm.data(0, self.messageRole) editor.toggleWarning( lineno, 0, True, message, warningType=editor.WarningStyle) # go through the list again to clear warning markers for files, # that are ok openFiles = vm.getOpenFilenames() errorFiles = [] for index in range(self.resultList.topLevelItemCount()): itm = self.resultList.topLevelItem(index) errorFiles.append( Utilities.normabspath(itm.data(0, self.filenameRole))) for file in openFiles: if file not in errorFiles: editor = vm.getOpenEditor(file) editor.clearStyleWarnings() @pyqtSlot() def on_statisticsButton_clicked(self): """ Private slot to show the statistics dialog. """ from .CodeStyleStatisticsDialog import CodeStyleStatisticsDialog dlg = CodeStyleStatisticsDialog(self.__statistics, self) dlg.exec_() @pyqtSlot() def on_loadDefaultButton_clicked(self): """ Private slot to load the default configuration values. """ self.excludeFilesEdit.setText(Preferences.Prefs.settings.value( "PEP8/ExcludeFilePatterns")) self.excludeMessagesEdit.setText(Preferences.Prefs.settings.value( "PEP8/ExcludeMessages", pep8.DEFAULT_IGNORE)) self.includeMessagesEdit.setText(Preferences.Prefs.settings.value( "PEP8/IncludeMessages")) self.repeatCheckBox.setChecked(Preferences.toBool( Preferences.Prefs.settings.value("PEP8/RepeatMessages"))) self.fixIssuesEdit.setText(Preferences.Prefs.settings.value( "PEP8/FixCodes")) self.noFixIssuesEdit.setText(Preferences.Prefs.settings.value( "PEP8/NoFixCodes", "E501")) self.fixIssuesCheckBox.setChecked(Preferences.toBool( Preferences.Prefs.settings.value("PEP8/FixIssues"))) self.ignoredCheckBox.setChecked(Preferences.toBool( Preferences.Prefs.settings.value("PEP8/ShowIgnored"))) self.lineLengthSpinBox.setValue(int(Preferences.Prefs.settings.value( "PEP8/MaxLineLength", pep8.MAX_LINE_LENGTH))) self.hangClosingCheckBox.setChecked(Preferences.toBool( Preferences.Prefs.settings.value("PEP8/HangClosing"))) self.docTypeComboBox.setCurrentIndex(self.docTypeComboBox.findData( Preferences.Prefs.settings.value("PEP8/DocstringType", "pep257"))) @pyqtSlot() def on_storeDefaultButton_clicked(self): """ Private slot to store the current configuration values as default values. """ Preferences.Prefs.settings.setValue( "PEP8/ExcludeFilePatterns", self.excludeFilesEdit.text()) Preferences.Prefs.settings.setValue( "PEP8/ExcludeMessages", self.excludeMessagesEdit.text()) Preferences.Prefs.settings.setValue( "PEP8/IncludeMessages", self.includeMessagesEdit.text()) Preferences.Prefs.settings.setValue( "PEP8/RepeatMessages", self.repeatCheckBox.isChecked()) Preferences.Prefs.settings.setValue( "PEP8/FixCodes", self.fixIssuesEdit.text()) Preferences.Prefs.settings.setValue( "PEP8/NoFixCodes", self.noFixIssuesEdit.text()) Preferences.Prefs.settings.setValue( "PEP8/FixIssues", self.fixIssuesCheckBox.isChecked()) Preferences.Prefs.settings.setValue( "PEP8/ShowIgnored", self.ignoredCheckBox.isChecked()) Preferences.Prefs.settings.setValue( "PEP8/MaxLineLength", self.lineLengthSpinBox.value()) Preferences.Prefs.settings.setValue( "PEP8/HangClosing", self.hangClosingCheckBox.isChecked()) Preferences.Prefs.settings.setValue( "PEP8/DocstringType", self.docTypeComboBox.itemData( self.docTypeComboBox.currentIndex())) @pyqtSlot() def on_resetDefaultButton_clicked(self): """ Private slot to reset the configuration values to their default values. """ Preferences.Prefs.settings.setValue("PEP8/ExcludeFilePatterns", "") Preferences.Prefs.settings.setValue( "PEP8/ExcludeMessages", pep8.DEFAULT_IGNORE) Preferences.Prefs.settings.setValue("PEP8/IncludeMessages", "") Preferences.Prefs.settings.setValue("PEP8/RepeatMessages", False) Preferences.Prefs.settings.setValue("PEP8/FixCodes", "") Preferences.Prefs.settings.setValue("PEP8/NoFixCodes", "E501") Preferences.Prefs.settings.setValue("PEP8/FixIssues", False) Preferences.Prefs.settings.setValue("PEP8/ShowIgnored", False) Preferences.Prefs.settings.setValue( "PEP8/MaxLineLength", pep8.MAX_LINE_LENGTH) Preferences.Prefs.settings.setValue("PEP8/HangClosing", False) Preferences.Prefs.settings.setValue("PEP8/DocstringType", "pep257") @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() elif button == self.showButton: self.on_showButton_clicked() elif button == self.statisticsButton: self.on_statisticsButton_clicked() def __clearErrors(self, files): """ Private method to clear all warning markers of open editors to be checked. @param files list of files to be checked (list of string) """ vm = e5App().getObject("ViewManager") openFiles = vm.getOpenFilenames() for file in [f for f in openFiles if f in files]: editor = vm.getOpenEditor(file) editor.clearStyleWarnings() @pyqtSlot() def on_fixButton_clicked(self): """ Private slot to fix selected issues. Build a dictionary of issues to fix. Update the initialized __options. Then call check with the dict as keyparam to fix selected issues. """ fixableItems = self.__getSelectedFixableItems() # dictionary of lists of tuples containing the issue and the item fixesDict = {} for itm in fixableItems: filename = itm.data(0, self.filenameRole) if filename not in fixesDict: fixesDict[filename] = [] fixesDict[filename].append(( (filename, itm.data(0, self.lineRole), itm.data(0, self.positionRole), "{0} {1}".format(itm.data(0, self.codeRole), itm.data(0, self.messageRole))), itm )) # update the configuration values (3: fixCodes, 4: noFixCodes, # 5: fixIssues, 6: maxLineLength) self.__options[3] = self.fixIssuesEdit.text() self.__options[4] = self.noFixIssuesEdit.text() self.__options[5] = True self.__options[6] = self.lineLengthSpinBox.value() self.files = list(fixesDict.keys()) # now go through all the files self.progress = 0 self.files.sort() self.cancelled = False self.__onlyFixes = fixesDict self.check() def __getSelectedFixableItems(self): """ Private method to extract all selected items for fixable issues. @return selected items for fixable issues (list of QTreeWidgetItem) """ fixableItems = [] for itm in self.resultList.selectedItems(): if itm.childCount() > 0: for index in range(itm.childCount()): citm = itm.child(index) if self.__itemFixable(citm) and citm not in fixableItems: fixableItems.append(citm) elif self.__itemFixable(itm) and itm not in fixableItems: fixableItems.append(itm) return fixableItems def __itemFixable(self, itm): """ Private method to check, if an item has a fixable issue. @param itm item to be checked (QTreeWidgetItem) @return flag indicating a fixable issue (boolean) """ return (itm.data(0, self.fixableRole) and not itm.data(0, self.ignoredRole)) eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.py0000644000175000017500000000534712451233371030214 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to select code style message codes. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog, QTreeWidgetItem from .Ui_CodeStyleCodeSelectionDialog import Ui_CodeStyleCodeSelectionDialog import UI.PixmapCache class CodeStyleCodeSelectionDialog(QDialog, Ui_CodeStyleCodeSelectionDialog): """ Class implementing a dialog to select code style message codes. """ def __init__(self, codes, showFixCodes, parent=None): """ Constructor @param codes comma separated list of selected codes (string) @param showFixCodes flag indicating to show a list of fixable issues (boolean) @param parent reference to the parent widget (QWidget) """ super(CodeStyleCodeSelectionDialog, self).__init__(parent) self.setupUi(self) codeList = [code.strip() for code in codes.split(",") if code.strip()] from .translations import _messages, _messages_sample_args if showFixCodes: from .CodeStyleFixer import FixableCodeStyleIssues selectableCodes = FixableCodeStyleIssues else: selectableCodes = [x for x in list(_messages.keys()) if not x.startswith('F')] for code in sorted(selectableCodes): if code in _messages_sample_args: message = _messages[code].format(*_messages_sample_args[code]) elif code in _messages: message = _messages[code] else: continue itm = QTreeWidgetItem(self.codeTable, [code, message]) if code.startswith("W"): itm.setIcon(0, UI.PixmapCache.getIcon("warning.png")) elif code.startswith("E"): itm.setIcon(0, UI.PixmapCache.getIcon("syntaxError.png")) elif code.startswith("N"): itm.setIcon(0, UI.PixmapCache.getIcon("namingError.png")) elif code.startswith("D"): itm.setIcon(0, UI.PixmapCache.getIcon("docstringError.png")) if code in codeList: itm.setSelected(True) codeList.remove(code) self.__extraCodes = codeList[:] def getSelectedCodes(self): """ Public method to get a comma separated list of codes selected. @return comma separated list of selected codes (string) """ selectedCodes = [] for itm in self.codeTable.selectedItems(): selectedCodes.append(itm.text(0)) return ", ".join(self.__extraCodes + selectedCodes) eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/DocStyleChecker.py0000644000175000017500000013704012451233371025547 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a checker for documentation string conventions. """ # # The routines of the checker class are modeled after the ones found in # pep257.py (version 0.2.4). # try: # Python 2 from StringIO import StringIO # __IGNORE_EXCEPTION__ except ImportError: # Python 3 from io import StringIO # __IGNORE_WARNING__ import tokenize import ast import sys class DocStyleContext(object): """ Class implementing the source context. """ def __init__(self, source, startLine, contextType): """ Constructor @param source source code of the context (list of string or string) @param startLine line number the context starts in the source (integer) @param contextType type of the context object (string) """ if isinstance(source, str): self.__source = source.splitlines(True) else: self.__source = source[:] self.__start = startLine self.__indent = "" self.__type = contextType # ensure first line is left justified if self.__source: self.__indent = self.__source[0].replace( self.__source[0].lstrip(), "") self.__source[0] = self.__source[0].lstrip() def source(self): """ Public method to get the source. @return source (list of string) """ return self.__source def ssource(self): """ Public method to get the joined source lines. @return source (string) """ return "".join(self.__source) def start(self): """ Public method to get the start line number. @return start line number (integer) """ return self.__start def end(self): """ Public method to get the end line number. @return end line number (integer) """ return self.__start + len(self.__source) - 1 def indent(self): """ Public method to get the indentation of the first line. @return indentation string (string) """ return self.__indent def contextType(self): """ Public method to get the context type. @return context type (string) """ return self.__type class DocStyleChecker(object): """ Class implementing a checker for documentation string conventions. """ Codes = [ "D101", "D102", "D103", "D104", "D105", "D111", "D112", "D113", "D121", "D122", "D130", "D131", "D132", "D133", "D134", "D141", "D142", "D143", "D144", "D145", "D203", "D205", "D221", "D222", "D231", "D232", "D234", "D235", "D236", "D237", "D238", "D239", "D242", "D243", "D244", "D245", "D246", "D247", "D250", "D251", "D901", ] def __init__(self, source, filename, select, ignore, expected, repeat, maxLineLength=79, docType="pep257"): """ Constructor @param source source code to be checked (list of string) @param filename name of the source file (string) @param select list of selected codes (list of string) @param ignore list of codes to be ignored (list of string) @param expected list of expected codes (list of string) @param repeat flag indicating to report each occurrence of a code (boolean) @keyparam maxLineLength allowed line length (integer) @keyparam docType type of the documentation strings (string, one of 'eric' or 'pep257') """ assert docType in ("eric", "pep257") self.__select = tuple(select) self.__ignore = ('',) if select else tuple(ignore) self.__expected = expected[:] self.__repeat = repeat self.__maxLineLength = maxLineLength self.__docType = docType self.__filename = filename self.__source = source[:] # statistics counters self.counters = {} # collection of detected errors self.errors = [] self.__lineNumber = 0 # caches self.__functionsCache = None self.__classesCache = None self.__methodsCache = None self.__keywords = [ 'moduleDocstring', 'functionDocstring', 'classDocstring', 'methodDocstring', 'defDocstring', 'docstring' ] if self.__docType == "pep257": checkersWithCodes = { "moduleDocstring": [ (self.__checkModulesDocstrings, ("D101",)), ], "functionDocstring": [ ], "classDocstring": [ (self.__checkClassDocstring, ("D104", "D105")), (self.__checkBlankBeforeAndAfterClass, ("D142", "D143")), ], "methodDocstring": [ ], "defDocstring": [ (self.__checkFunctionDocstring, ("D102", "D103")), (self.__checkImperativeMood, ("D132",)), (self.__checkNoSignature, ("D133",)), (self.__checkReturnType, ("D134",)), (self.__checkNoBlankLineBefore, ("D141",)), ], "docstring": [ (self.__checkTripleDoubleQuotes, ("D111",)), (self.__checkBackslashes, ("D112",)), (self.__checkUnicode, ("D113",)), (self.__checkOneLiner, ("D121",)), (self.__checkIndent, ("D122",)), (self.__checkSummary, ("D130")), (self.__checkEndsWithPeriod, ("D131",)), (self.__checkBlankAfterSummary, ("D144",)), (self.__checkBlankAfterLastParagraph, ("D145",)), ], } elif self.__docType == "eric": checkersWithCodes = { "moduleDocstring": [ (self.__checkModulesDocstrings, ("D101",)), ], "functionDocstring": [ ], "classDocstring": [ (self.__checkClassDocstring, ("D104", "D205")), (self.__checkEricNoBlankBeforeAndAfterClassOrFunction, ("D242", "D243")), ], "methodDocstring": [ (self.__checkEricSummary, ("D232")), ], "defDocstring": [ (self.__checkFunctionDocstring, ("D102", "D203")), (self.__checkImperativeMood, ("D132",)), (self.__checkNoSignature, ("D133",)), (self.__checkEricReturn, ("D234", "D235")), (self.__checkEricFunctionArguments, ("D236", "D237", "D238", "D239")), (self.__checkEricNoBlankBeforeAndAfterClassOrFunction, ("D244", "D245")), (self.__checkEricException, ("D250", "D251")), ], "docstring": [ (self.__checkTripleDoubleQuotes, ("D111",)), (self.__checkBackslashes, ("D112",)), (self.__checkUnicode, ("D113",)), (self.__checkIndent, ("D122",)), (self.__checkSummary, ("D130")), (self.__checkEricEndsWithPeriod, ("D231",)), (self.__checkEricBlankAfterSummary, ("D246",)), (self.__checkEricNBlankAfterLastParagraph, ("D247",)), (self.__checkEricQuotesOnSeparateLines, ("D222", "D223")) ], } self.__checkers = {} for key, checkers in checkersWithCodes.items(): for checker, codes in checkers: if any(not (code and self.__ignoreCode(code)) for code in codes): if key not in self.__checkers: self.__checkers[key] = [] self.__checkers[key].append(checker) def __ignoreCode(self, code): """ Private method to check if the error code should be ignored. @param code message code to check for (string) @return flag indicating to ignore the given code (boolean) """ return (code.startswith(self.__ignore) and not code.startswith(self.__select)) def __error(self, lineNumber, offset, code, *args): """ Private method to record an issue. @param lineNumber line number of the issue (integer) @param offset position within line of the issue (integer) @param code message code (string) @param args arguments for the message (list) """ if self.__ignoreCode(code): return if code in self.counters: self.counters[code] += 1 else: self.counters[code] = 1 # Don't care about expected codes if code in self.__expected: return if code and (self.counters[code] == 1 or self.__repeat): # record the issue with one based line number self.errors.append( (self.__filename, lineNumber + 1, offset, (code, args))) def __reportInvalidSyntax(self): """ Private method to report a syntax error. """ exc_type, exc = sys.exc_info()[:2] if len(exc.args) > 1: offset = exc.args[1] if len(offset) > 2: offset = offset[1:3] else: offset = (1, 0) self.__error(offset[0] - 1, offset[1] or 0, 'D901', exc_type.__name__, exc.args[0]) def __resetReadline(self): """ Private method to reset the internal readline function. """ self.__lineNumber = 0 def __readline(self): """ Private method to get the next line from the source. @return next line of source (string) """ self.__lineNumber += 1 if self.__lineNumber > len(self.__source): return '' return self.__source[self.__lineNumber - 1] def run(self): """ Public method to check the given source for violations of doc string conventions. """ if not self.__filename: # don't do anything, if essential data is missing return if not self.__checkers: # don't do anything, if no codes were selected return try: compile(''.join(self.__source), '', 'exec', ast.PyCF_ONLY_AST) except (SyntaxError, TypeError): self.__reportInvalidSyntax() return for keyword in self.__keywords: if keyword in self.__checkers: for check in self.__checkers[keyword]: for context in self.__parseContexts(keyword): docstring = self.__parseDocstring(context, keyword) check(docstring, context) def __getSummaryLine(self, docstringContext): """ Private method to extract the summary line. @param docstringContext docstring context (DocStyleContext) @return summary line (string) and the line it was found on (integer) """ lines = docstringContext.source() line = (lines[0] .replace('r"""', "", 1) .replace('u"""', "", 1) .replace('"""', "") .replace("r'''", "", 1) .replace("u'''", "", 1) .replace("'''", "") .strip()) if len(lines) == 1 or len(line) > 0: return line, 0 return lines[1].strip().replace('"""', "").replace("'''", ""), 1 def __getSummaryLines(self, docstringContext): """ Private method to extract the summary lines. @param docstringContext docstring context (DocStyleContext) @return summary lines (list of string) and the line it was found on (integer) """ summaries = [] lines = docstringContext.source() line0 = (lines[0] .replace('r"""', "", 1) .replace('u"""', "", 1) .replace('"""', "") .replace("r'''", "", 1) .replace("u'''", "", 1) .replace("'''", "") .strip()) if len(lines) > 1: line1 = lines[1].strip().replace('"""', "").replace("'''", "") else: line1 = "" if len(lines) > 2: line2 = lines[2].strip().replace('"""', "").replace("'''", "") else: line2 = "" if line0: lineno = 0 summaries.append(line0) if not line0.endswith(".") and line1: # two line summary summaries.append(line1) elif line1: lineno = 1 summaries.append(line1) if not line1.endswith(".") and line2: # two line summary summaries.append(line2) else: lineno = 2 summaries.append(line2) return summaries, lineno if sys.version_info[0] < 3: def __getArgNames(self, node): """ Private method to get the argument names of a function node. @param node AST node to extract arguments names from @return tuple of two list of argument names, one for arguments and one for keyword arguments (tuple of list of string) """ def unpackArgs(args): """ Local helper function to unpack function argument names. @param args list of AST node arguments @return list of argument names (list of string) """ ret = [] for arg in args: if isinstance(arg, ast.Tuple): ret.extend(unpackArgs(arg.elts)) else: ret.append(arg.id) return ret arguments = unpackArgs(node.args.args) if node.args.vararg is not None: arguments.append(node.args.vararg) kwarguments = [] if node.args.kwarg is not None: kwarguments.append(node.args.kwarg) return arguments, kwarguments else: def __getArgNames(self, node): # __IGNORE_WARNING__ """ Private method to get the argument names of a function node. @param node AST node to extract arguments names from @return tuple of two list of argument names, one for arguments and one for keyword arguments (tuple of list of string) """ arguments = [] arguments.extend([arg.arg for arg in node.args.args]) if node.args.vararg is not None: if sys.version_info[1] < 4: arguments.append(node.args.vararg) else: arguments.append(node.args.vararg.arg) kwarguments = [] kwarguments.extend([arg.arg for arg in node.args.kwonlyargs]) if node.args.kwarg is not None: if sys.version_info[1] < 4: kwarguments.append(node.args.kwarg) else: kwarguments.append(node.args.kwarg.arg) return arguments, kwarguments ################################################################## ## Parsing functionality below ################################################################## def __parseModuleDocstring(self, source): """ Private method to extract a docstring given a module source. @param source source to parse (list of string) @return context of extracted docstring (DocStyleContext) """ for kind, value, (line, char), _, _ in tokenize.generate_tokens( StringIO("".join(source)).readline): if kind in [tokenize.COMMENT, tokenize.NEWLINE, tokenize.NL]: continue elif kind == tokenize.STRING: # first STRING should be docstring return DocStyleContext(value, line - 1, "docstring") else: return None def __parseDocstring(self, context, what=''): """ Private method to extract a docstring given `def` or `class` source. @param context context data to get the docstring from (DocStyleContext) @param what string denoting what is being parsed (string) @return context of extracted docstring (DocStyleContext) """ moduleDocstring = self.__parseModuleDocstring(context.source()) if what.startswith('module') or context.contextType() == "module": return moduleDocstring if moduleDocstring: return moduleDocstring tokenGenerator = tokenize.generate_tokens( StringIO(context.ssource()).readline) try: kind = None while kind != tokenize.INDENT: kind, _, _, _, _ = next(tokenGenerator) kind, value, (line, char), _, _ = next(tokenGenerator) if kind == tokenize.STRING: # STRING after INDENT is a docstring return DocStyleContext( value, context.start() + line - 1, "docstring") except StopIteration: pass return None def __parseTopLevel(self, keyword): """ Private method to extract top-level functions or classes. @param keyword keyword signaling what to extract (string) @return extracted function or class contexts (list of DocStyleContext) """ self.__resetReadline() tokenGenerator = tokenize.generate_tokens(self.__readline) kind, value, char = None, None, None contexts = [] try: while True: start, end = None, None while not (kind == tokenize.NAME and value == keyword and char == 0): kind, value, (line, char), _, _ = next(tokenGenerator) start = line - 1, char while not (kind == tokenize.DEDENT and value == '' and char == 0): kind, value, (line, char), _, _ = next(tokenGenerator) end = line - 1, char contexts.append(DocStyleContext( self.__source[start[0]:end[0]], start[0], keyword)) except StopIteration: return contexts def __parseFunctions(self): """ Private method to extract top-level functions. @return extracted function contexts (list of DocStyleContext) """ if not self.__functionsCache: self.__functionsCache = self.__parseTopLevel('def') return self.__functionsCache def __parseClasses(self): """ Private method to extract top-level classes. @return extracted class contexts (list of DocStyleContext) """ if not self.__classesCache: self.__classesCache = self.__parseTopLevel('class') return self.__classesCache def __skipIndentedBlock(self, tokenGenerator): """ Private method to skip over an indented block of source code. @param tokenGenerator token generator @return last token of the indented block """ kind, value, start, end, raw = next(tokenGenerator) while kind != tokenize.INDENT: kind, value, start, end, raw = next(tokenGenerator) indent = 1 for kind, value, start, end, raw in tokenGenerator: if kind == tokenize.INDENT: indent += 1 elif kind == tokenize.DEDENT: indent -= 1 if indent == 0: return kind, value, start, end, raw def __parseMethods(self): """ Private method to extract methods of all classes. @return extracted method contexts (list of DocStyleContext) """ if not self.__methodsCache: contexts = [] for classContext in self.__parseClasses(): tokenGenerator = tokenize.generate_tokens( StringIO(classContext.ssource()).readline) kind, value, char = None, None, None try: while True: start, end = None, None while not (kind == tokenize.NAME and value == 'def'): kind, value, (line, char), _, _ = \ next(tokenGenerator) start = line - 1, char kind, value, (line, char), _, _ = \ self.__skipIndentedBlock(tokenGenerator) end = line - 1, char startLine = classContext.start() + start[0] endLine = classContext.start() + end[0] contexts.append(DocStyleContext( self.__source[startLine:endLine], startLine, "def")) except StopIteration: pass self.__methodsCache = contexts return self.__methodsCache def __parseContexts(self, kind): """ Private method to extract a context from the source. @param kind kind of context to extract (string) @return requested contexts (list of DocStyleContext) """ if kind == 'moduleDocstring': return [DocStyleContext(self.__source, 0, "module")] if kind == 'functionDocstring': return self.__parseFunctions() if kind == 'classDocstring': return self.__parseClasses() if kind == 'methodDocstring': return self.__parseMethods() if kind == 'defDocstring': return self.__parseFunctions() + self.__parseMethods() if kind == 'docstring': return ([DocStyleContext(self.__source, 0, "module")] + self.__parseFunctions() + self.__parseClasses() + self.__parseMethods()) return [] # fall back ################################################################## ## Checking functionality below (PEP-257) ################################################################## def __checkModulesDocstrings(self, docstringContext, context): """ Private method to check, if the module has a docstring. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: self.__error(context.start(), 0, "D101") return docstring = docstringContext.ssource() if (not docstring or not docstring.strip() or not docstring.strip('\'"')): self.__error(context.start(), 0, "D101") def __checkFunctionDocstring(self, docstringContext, context): """ Private method to check, that all public functions and methods have a docstring. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ functionName = context.source()[0].lstrip().split()[1].split("(")[0] if functionName.startswith('_') and not functionName.endswith('__'): if self.__docType == "eric": code = "D203" else: code = "D103" else: code = "D102" if docstringContext is None: self.__error(context.start(), 0, code) return docstring = docstringContext.ssource() if (not docstring or not docstring.strip() or not docstring.strip('\'"')): self.__error(context.start(), 0, code) def __checkClassDocstring(self, docstringContext, context): """ Private method to check, that all public functions and methods have a docstring. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ className = context.source()[0].lstrip().split()[1].split("(")[0] if className.startswith('_'): if self.__docType == "eric": code = "D205" else: code = "D105" else: code = "D104" if docstringContext is None: self.__error(context.start(), 0, code) return docstring = docstringContext.ssource() if (not docstring or not docstring.strip() or not docstring.strip('\'"')): self.__error(context.start(), 0, code) def __checkTripleDoubleQuotes(self, docstringContext, context): """ Private method to check, that all docstrings are surrounded by triple double quotes. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return docstring = docstringContext.ssource().strip() if not docstring.startswith(('"""', 'r"""', 'u"""')): self.__error(docstringContext.start(), 0, "D111") def __checkBackslashes(self, docstringContext, context): """ Private method to check, that all docstrings containing backslashes are surrounded by raw triple double quotes. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return docstring = docstringContext.ssource().strip() if "\\" in docstring and not docstring.startswith('r"""'): self.__error(docstringContext.start(), 0, "D112") def __checkUnicode(self, docstringContext, context): """ Private method to check, that all docstrings containing unicode characters are surrounded by unicode triple double quotes. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return docstring = docstringContext.ssource().strip() if not docstring.startswith('u"""') and \ any(ord(char) > 127 for char in docstring): self.__error(docstringContext.start(), 0, "D113") def __checkOneLiner(self, docstringContext, context): """ Private method to check, that one-liner docstrings fit on one line with quotes. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return lines = docstringContext.source() if len(lines) > 1: nonEmptyLines = [l for l in lines if l.strip().strip('\'"')] if len(nonEmptyLines) == 1: modLen = len(context.indent() + '"""' + nonEmptyLines[0].strip() + '"""') if context.contextType() != "module": modLen += 4 if not nonEmptyLines[0].strip().endswith("."): # account for a trailing dot modLen += 1 if modLen <= self.__maxLineLength: self.__error(docstringContext.start(), 0, "D121") def __checkIndent(self, docstringContext, context): """ Private method to check, that docstrings are properly indented. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return lines = docstringContext.source() if len(lines) == 1: return nonEmptyLines = [l.rstrip() for l in lines[1:] if l.strip()] if not nonEmptyLines: return indent = min([len(l) - len(l.strip()) for l in nonEmptyLines]) if context.contextType() == "module": expectedIndent = 0 else: expectedIndent = len(context.indent()) + 4 if indent != expectedIndent: self.__error(docstringContext.start(), 0, "D122") def __checkSummary(self, docstringContext, context): """ Private method to check, that docstring summaries contain some text. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return summary, lineNumber = self.__getSummaryLine(docstringContext) if summary == "": self.__error(docstringContext.start() + lineNumber, 0, "D130") def __checkEndsWithPeriod(self, docstringContext, context): """ Private method to check, that docstring summaries end with a period. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return summary, lineNumber = self.__getSummaryLine(docstringContext) if not summary.endswith("."): self.__error(docstringContext.start() + lineNumber, 0, "D131") def __checkImperativeMood(self, docstringContext, context): """ Private method to check, that docstring summaries are in imperative mood. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return summary, lineNumber = self.__getSummaryLine(docstringContext) if summary: firstWord = summary.strip().split()[0] if firstWord.endswith("s") and not firstWord.endswith("ss"): self.__error(docstringContext.start() + lineNumber, 0, "D132") def __checkNoSignature(self, docstringContext, context): """ Private method to check, that docstring summaries don't repeat the function's signature. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return functionName = context.source()[0].lstrip().split()[1].split("(")[0] summary, lineNumber = self.__getSummaryLine(docstringContext) if functionName + "(" in summary.replace(" ", "") and \ not functionName + "()" in summary.replace(" ", ""): # report only, if it is not an abbreviated form (i.e. function() ) self.__error(docstringContext.start() + lineNumber, 0, "D133") def __checkReturnType(self, docstringContext, context): """ Private method to check, that docstrings mention the return value type. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return if "return" not in docstringContext.ssource().lower(): tokens = list( tokenize.generate_tokens(StringIO(context.ssource()).readline)) return_ = [tokens[i + 1][0] for i, token in enumerate(tokens) if token[1] == "return"] if (set(return_) - set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) != set([])): self.__error(docstringContext.end(), 0, "D134") def __checkNoBlankLineBefore(self, docstringContext, context): """ Private method to check, that function/method docstrings are not preceded by a blank line. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return contextLines = context.source() cti = 0 while cti < len(contextLines) and \ not contextLines[cti].strip().startswith( ('"""', 'r"""', 'u"""', "'''", "r'''", "u'''")): cti += 1 if cti == len(contextLines): return if not contextLines[cti - 1].strip(): self.__error(docstringContext.start(), 0, "D141") def __checkBlankBeforeAndAfterClass(self, docstringContext, context): """ Private method to check, that class docstrings have one blank line around them. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return contextLines = context.source() cti = 0 while cti < len(contextLines) and \ not contextLines[cti].strip().startswith( ('"""', 'r"""', 'u"""', "'''", "r'''", "u'''")): cti += 1 if cti == len(contextLines): return start = cti if contextLines[cti].strip() in ( '"""', 'r"""', 'u"""', "'''", "r'''", "u'''"): # it is a multi line docstring cti += 1 while cti < len(contextLines) and \ not contextLines[cti].strip().endswith(('"""', "'''")): cti += 1 end = cti if cti >= len(contextLines) - 1: return if contextLines[start - 1].strip(): self.__error(docstringContext.start(), 0, "D142") if contextLines[end + 1].strip(): self.__error(docstringContext.end(), 0, "D143") def __checkBlankAfterSummary(self, docstringContext, context): """ Private method to check, that docstring summaries are followed by a blank line. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return docstrings = docstringContext.source() if len(docstrings) <= 3: # correct/invalid one-liner return summary, lineNumber = self.__getSummaryLine(docstringContext) if len(docstrings) > 2: if docstrings[lineNumber + 1].strip(): self.__error(docstringContext.start() + lineNumber, 0, "D144") def __checkBlankAfterLastParagraph(self, docstringContext, context): """ Private method to check, that the last paragraph of docstrings is followed by a blank line. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return docstrings = docstringContext.source() if len(docstrings) <= 3: # correct/invalid one-liner return if docstrings[-2].strip(): self.__error(docstringContext.end(), 0, "D145") ################################################################## ## Checking functionality below (eric specific ones) ################################################################## def __checkEricQuotesOnSeparateLines(self, docstringContext, context): """ Private method to check, that leading and trailing quotes are on a line by themselves. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return lines = docstringContext.source() if lines[0].strip().strip('ru"\''): self.__error(docstringContext.start(), 0, "D221") if lines[-1].strip().strip('"\''): self.__error(docstringContext.end(), 0, "D222") def __checkEricEndsWithPeriod(self, docstringContext, context): """ Private method to check, that docstring summaries end with a period. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return summaryLines, lineNumber = self.__getSummaryLines(docstringContext) if summaryLines: if summaryLines[-1].lstrip().startswith("@"): summaryLines.pop(-1) summary = " ".join([s.strip() for s in summaryLines if s]) if summary and not summary.endswith(".") and \ not summary.split(None, 1)[0].lower() == "constructor": self.__error( docstringContext.start() + lineNumber + len(summaryLines) - 1, 0, "D231") def __checkEricReturn(self, docstringContext, context): """ Private method to check, that docstrings contain an @return line if they return anything and don't otherwise. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return tokens = list( tokenize.generate_tokens(StringIO(context.ssource()).readline)) return_ = [tokens[i + 1][0] for i, token in enumerate(tokens) if token[1] in ("return", "yield")] if "@return" not in docstringContext.ssource(): if (set(return_) - set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) != set([])): self.__error(docstringContext.end(), 0, "D234") else: if (set(return_) - set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) == set([])): self.__error(docstringContext.end(), 0, "D235") def __checkEricFunctionArguments(self, docstringContext, context): """ Private method to check, that docstrings contain an @param and/or @keyparam line for each argument. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return try: tree = ast.parse(context.ssource()) except (SyntaxError, TypeError): return if (isinstance(tree, ast.Module) and len(tree.body) == 1 and isinstance(tree.body[0], ast.FunctionDef)): functionDef = tree.body[0] argNames, kwNames = self.__getArgNames(functionDef) if "self" in argNames: argNames.remove("self") if "cls" in argNames: argNames.remove("cls") docstring = docstringContext.ssource() if (docstring.count("@param") + docstring.count("@keyparam") < len(argNames + kwNames)): self.__error(docstringContext.end(), 0, "D236") elif (docstring.count("@param") + docstring.count("@keyparam") > len(argNames + kwNames)): self.__error(docstringContext.end(), 0, "D237") else: # extract @param and @keyparam from docstring args = [] kwargs = [] for line in docstringContext.source(): if line.strip().startswith(("@param", "@keyparam")): at, name = line.strip().split(None, 2)[:2] if at == "@keyparam": kwargs.append(name.lstrip("*")) args.append(name.lstrip("*")) # do the checks for name in kwNames: if name not in kwargs: self.__error(docstringContext.end(), 0, "D238") return if argNames + kwNames != args: self.__error(docstringContext.end(), 0, "D239") def __checkEricException(self, docstringContext, context): """ Private method to check, that docstrings contain an @exception line if they raise an exception and don't otherwise. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return tokens = list( tokenize.generate_tokens(StringIO(context.ssource()).readline)) exception = [tokens[i + 1][0] for i, token in enumerate(tokens) if token[1] == "raise"] if "@exception" not in docstringContext.ssource() and \ "@throws" not in docstringContext.ssource() and \ "@raise" not in docstringContext.ssource(): if (set(exception) - set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) != set([])): self.__error(docstringContext.end(), 0, "D250") else: if (set(exception) - set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) == set([])): self.__error(docstringContext.end(), 0, "D251") def __checkEricBlankAfterSummary(self, docstringContext, context): """ Private method to check, that docstring summaries are followed by a blank line. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return docstrings = docstringContext.source() if len(docstrings) <= 3: # correct/invalid one-liner return summaryLines, lineNumber = self.__getSummaryLines(docstringContext) if len(docstrings) - 2 > lineNumber + len(summaryLines) - 1: if docstrings[lineNumber + len(summaryLines)].strip(): self.__error(docstringContext.start() + lineNumber, 0, "D246") def __checkEricNoBlankBeforeAndAfterClassOrFunction( self, docstringContext, context): """ Private method to check, that class and function/method docstrings have no blank line around them. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return contextLines = context.source() isClassContext = contextLines[0].lstrip().startswith("class ") cti = 0 while cti < len(contextLines) and \ not contextLines[cti].strip().startswith( ('"""', 'r"""', 'u"""', "'''", "r'''", "u'''")): cti += 1 if cti == len(contextLines): return start = cti if contextLines[cti].strip() in ( '"""', 'r"""', 'u"""', "'''", "r'''", "u'''"): # it is a multi line docstring cti += 1 while cti < len(contextLines) and \ not contextLines[cti].strip().endswith(('"""', "'''")): cti += 1 end = cti if cti >= len(contextLines) - 1: return if isClassContext: if not contextLines[start - 1].strip(): self.__error(docstringContext.start(), 0, "D242") if not contextLines[end + 1].strip(): self.__error(docstringContext.end(), 0, "D243") else: if not contextLines[start - 1].strip(): self.__error(docstringContext.start(), 0, "D244") if not contextLines[end + 1].strip(): self.__error(docstringContext.end(), 0, "D245") def __checkEricNBlankAfterLastParagraph(self, docstringContext, context): """ Private method to check, that the last paragraph of docstrings is not followed by a blank line. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return docstrings = docstringContext.source() if len(docstrings) <= 3: # correct/invalid one-liner return if not docstrings[-2].strip(): self.__error(docstringContext.end(), 0, "D247") def __checkEricSummary(self, docstringContext, context): """ Private method to check, that method docstring summaries start with specific words. @param docstringContext docstring context (DocStyleContext) @param context context of the docstring (DocStyleContext) """ if docstringContext is None: return summary, lineNumber = self.__getSummaryLine(docstringContext) if summary: # check, if the first word is 'Constructor', 'Public', # 'Protected' or 'Private' functionName, arguments = context.source()[0].lstrip()\ .split()[1].split("(", 1) firstWord = summary.strip().split(None, 1)[0].lower() if functionName == '__init__': if firstWord != 'constructor': self.__error(docstringContext.start() + lineNumber, 0, "D232", 'constructor') elif functionName.startswith('__') and \ functionName.endswith('__'): if firstWord != 'special': self.__error(docstringContext.start() + lineNumber, 0, "D232", 'special') elif functionName.startswith(('__', 'on_')): if firstWord != 'private': self.__error(docstringContext.start() + lineNumber, 0, "D232", 'private') elif functionName.startswith('_') or \ functionName.endswith('Event'): if firstWord != 'protected': self.__error(docstringContext.start() + lineNumber, 0, "D232", 'protected') elif arguments.startswith(('cls,', 'cls)')): if firstWord != 'class': self.__error(docstringContext.start() + lineNumber, 0, "D232", 'class') else: if firstWord != 'public': self.__error(docstringContext.start() + lineNumber, 0, "D232", 'public') eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.ui0000644000175000017500000000553012224275427030201 0ustar piotrpiotr CodeStyleCodeSelectionDialog 0 0 450 350 Code Style Message Codes true Select the message codes from the list: Select the message codes from this table QAbstractItemView::NoEditTriggers true QAbstractItemView::ExtendedSelection QAbstractItemView::SelectRows false true true Code Message Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok codeTable buttonBox buttonBox accepted() CodeStyleCodeSelectionDialog accept() 227 279 157 274 buttonBox rejected() CodeStyleCodeSelectionDialog reject() 295 285 286 274 eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/NamingStyleChecker.py0000644000175000017500000003775612451233371026270 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a checker for naming conventions. """ import collections import ast import re import os import sys class NamingStyleChecker(object): """ Class implementing a checker for naming conventions. """ LowercaseRegex = re.compile(r"[_a-z][_a-z0-9]*$") UppercaseRegexp = re.compile(r"[_A-Z][_A-Z0-9]*$") CamelcaseRegexp = re.compile(r"_?[A-Z][a-zA-Z0-9]*$") MixedcaseRegexp = re.compile(r"_?[a-z][a-zA-Z0-9]*$") Codes = [ "N801", "N802", "N803", "N804", "N805", "N806", "N807", "N808", "N811", "N812", "N813", "N814", "N821", "N831" ] def __init__(self, tree, filename, options): """ Constructor (according to 'extended' pep8.py API) @param tree AST tree of the source file @param filename name of the source file (string) @param options options as parsed by pep8.StyleGuide """ self.__parents = collections.deque() self.__tree = tree self.__filename = filename self.__checkersWithCodes = { "classdef": [ (self.__checkClassName, ("N801",)), (self.__checkNameToBeAvoided, ("N831",)), ], "functiondef": [ (self.__checkFuntionName, ("N802",)), (self.__checkFunctionArgumentNames, ("N803", "N804", "N805", "N806")), (self.__checkNameToBeAvoided, ("N831",)), ], "assign": [ (self.__checkVariablesInFunction, ("N821",)), (self.__checkNameToBeAvoided, ("N831",)), ], "importfrom": [ (self.__checkImportAs, ("N811", "N812", "N813", "N814")), ], "module": [ (self.__checkModule, ("N807", "N808")), ], } self.__checkers = {} for key, checkers in self.__checkersWithCodes.items(): for checker, codes in checkers: if any(not (code and options.ignore_code(code)) for code in codes): if key not in self.__checkers: self.__checkers[key] = [] self.__checkers[key].append(checker) def run(self): """ Public method run by the pep8.py checker. @return tuple giving line number, offset within line, code and checker function """ if self.__tree and self.__checkers: return self.__visitTree(self.__tree) else: return () def __visitTree(self, node): """ Private method to scan the given AST tree. @param node AST tree node to scan @return tuple giving line number, offset within line, code and checker function """ for error in self.__visitNode(node): yield error self.__parents.append(node) for child in ast.iter_child_nodes(node): for error in self.__visitTree(child): yield error self.__parents.pop() def __visitNode(self, node): """ Private method to inspect the given AST node. @param node AST tree node to inspect @return tuple giving line number, offset within line, code and checker function """ if isinstance(node, ast.ClassDef): self.__tagClassFunctions(node) elif isinstance(node, ast.FunctionDef): self.__findGlobalDefs(node) checkerName = node.__class__.__name__.lower() if checkerName in self.__checkers: for checker in self.__checkers[checkerName]: for error in checker(node, self.__parents): yield error + (self.__checkers[checkerName],) def __tagClassFunctions(self, classNode): """ Private method to tag functions if they are methods, class methods or static methods. @param classNode AST tree node to tag """ # try to find all 'old style decorators' like # m = staticmethod(m) lateDecoration = {} for node in ast.iter_child_nodes(classNode): if not (isinstance(node, ast.Assign) and isinstance(node.value, ast.Call) and isinstance(node.value.func, ast.Name)): continue funcName = node.value.func.id if funcName in ("classmethod", "staticmethod"): meth = (len(node.value.args) == 1 and node.value.args[0]) if isinstance(meth, ast.Name): lateDecoration[meth.id] = funcName # iterate over all functions and tag them for node in ast.iter_child_nodes(classNode): if not isinstance(node, ast.FunctionDef): continue node.function_type = 'method' if node.name == "__new__": node.function_type = "classmethod" if node.name in lateDecoration: node.function_type = lateDecoration[node.name] elif node.decorator_list: names = [d.id for d in node.decorator_list if isinstance(d, ast.Name) and d.id in ("classmethod", "staticmethod")] if names: node.function_type = names[0] def __findGlobalDefs(self, functionNode): """ Private method amend a node with global definitions information. @param functionNode AST tree node to amend """ globalNames = set() nodesToCheck = collections.deque(ast.iter_child_nodes(functionNode)) while nodesToCheck: node = nodesToCheck.pop() if isinstance(node, ast.Global): globalNames.update(node.names) if not isinstance(node, (ast.FunctionDef, ast.ClassDef)): nodesToCheck.extend(ast.iter_child_nodes(node)) functionNode.global_names = globalNames def __getArgNames(self, node): """ Private method to get the argument names of a function node. @param node AST node to extract arguments names from @return list of argument names (list of string) """ if sys.version_info[0] == 3: posArgs = [arg.arg for arg in node.args.args] kwOnly = [arg.arg for arg in node.args.kwonlyargs] return posArgs + kwOnly else: def unpackArgs(args): """ Local helper function to unpack function argument names. @param args list of AST node arguments @return list of argument names (list of string) """ ret = [] for arg in args: if isinstance(arg, ast.Tuple): ret.extend(unpackArgs(arg.elts)) else: ret.append(arg.id) return ret return unpackArgs(node.args.args) def __error(self, node, code): """ Private method to build the error information. @param node AST node to report an error for @param code error code to report (string) @return tuple giving line number, offset within line and error code (integer, integer, string) """ if isinstance(node, ast.Module): lineno = 0 offset = 0 else: lineno = node.lineno offset = node.col_offset if isinstance(node, ast.ClassDef): lineno += len(node.decorator_list) offset += 6 elif isinstance(node, ast.FunctionDef): lineno += len(node.decorator_list) offset += 4 return (lineno, offset, code) def __isNameToBeAvoided(self, name): """ Private method to check, if the given name should be avoided. @param name name to be checked (string) @return flag indicating to avoid it (boolen) """ return name in ("l", "O", "I") def __checkNameToBeAvoided(self, node, parents): """ Private class to check the given node for a name to be avoided (N831). @param node AST note to check @param parents list of parent nodes @return tuple giving line number, offset within line and error code (integer, integer, string) """ if isinstance(node, (ast.ClassDef, ast.FunctionDef)): name = node.name if self.__isNameToBeAvoided(name): yield self.__error(node, "N831") return if isinstance(node, ast.FunctionDef): argNames = self.__getArgNames(node) for arg in argNames: if self.__isNameToBeAvoided(arg): yield self.__error(node, "N831") return if isinstance(node, ast.Assign): for target in node.targets: name = isinstance(target, ast.Name) and target.id if not name: return if self.__isNameToBeAvoided(name): yield self.__error(node, "N831") return def __checkClassName(self, node, parents): """ Private class to check the given node for class name conventions (N801). Almost without exception, class names use the CapWords convention. Classes for internal use have a leading underscore in addition. @param node AST note to check @param parents list of parent nodes @return tuple giving line number, offset within line and error code (integer, integer, string) """ if not self.CamelcaseRegexp.match(node.name): yield self.__error(node, "N801") def __checkFuntionName(self, node, parents): """ Private class to check the given node for function name conventions (N802). Function names should be lowercase, with words separated by underscores as necessary to improve readability. Functions not being methods '__' in front and back are not allowed. Mixed case is allowed only in contexts where that's already the prevailing style (e.g. threading.py), to retain backwards compatibility. @param node AST note to check @param parents list of parent nodes @return tuple giving line number, offset within line and error code (integer, integer, string) """ functionType = getattr(node, "function_type", "function") name = node.name if (functionType == "function" and "__" in (name[:2], name[-2:])) or \ not self.LowercaseRegex.match(name): yield self.__error(node, "N802") def __checkFunctionArgumentNames(self, node, parents): """ Private class to check the argument names of functions (N803, N804, N805, N806). The argument names of a function should be lowercase, with words separated by underscores. A class method should have 'cls' as the first argument. A method should have 'self' as the first argument. @param node AST note to check @param parents list of parent nodes @return tuple giving line number, offset within line and error code (integer, integer, string) """ if node.args.kwarg is not None: if sys.version_info >= (3, 4): kwarg = node.args.kwarg.arg else: kwarg = node.args.kwarg if not self.LowercaseRegex.match(kwarg): yield self.__error(node, "N803") return if node.args.vararg is not None: if sys.version_info >= (3, 4): vararg = node.args.vararg.arg else: vararg = node.args.vararg if not self.LowercaseRegex.match(vararg): yield self.__error(node, "N803") return argNames = self.__getArgNames(node) functionType = getattr(node, "function_type", "function") if not argNames: if functionType == "method": yield self.__error(node, "N805") elif functionType == "classmethod": yield self.__error(node, "N804") return if functionType == "method": if argNames[0] != "self": yield self.__error(node, "N805") elif functionType == "classmethod": if argNames[0] != "cls": yield self.__error(node, "N804") elif functionType == "staticmethod": if argNames[0] in ("cls", "self"): yield self.__error(node, "N806") for arg in argNames: if not self.LowercaseRegex.match(arg): yield self.__error(node, "N803") return def __checkVariablesInFunction(self, node, parents): """ Private method to check local variables in functions (N821). Local variables in functions should be lowercase. @param node AST note to check @param parents list of parent nodes @return tuple giving line number, offset within line and error code (integer, integer, string) """ for parentFunc in reversed(parents): if isinstance(parentFunc, ast.ClassDef): return if isinstance(parentFunc, ast.FunctionDef): break else: return for target in node.targets: name = isinstance(target, ast.Name) and target.id if not name or name in parentFunc.global_names: return if not self.LowercaseRegex.match(name) and name[:1] != '_': yield self.__error(target, "N821") def __checkModule(self, node, parents): """ Private method to check module naming conventions (N807, N808). Module and package names should be lowercase. @param node AST note to check @param parents list of parent nodes @return tuple giving line number, offset within line and error code (integer, integer, string) """ if self.__filename: moduleName = os.path.splitext(os.path.basename(self.__filename))[0] if moduleName.lower() != moduleName: yield self.__error(node, "N807") if moduleName == "__init__": # we got a package packageName = \ os.path.split(os.path.dirname(self.__filename))[1] if packageName.lower() != packageName: yield self.__error(node, "N808") def __checkImportAs(self, node, parents): """ Private method to check that imports don't change the naming convention (N811, N812, N813, N814). @param node AST note to check @param parents list of parent nodes @return tuple giving line number, offset within line and error code (integer, integer, string) """ for name in node.names: if not name.asname: continue if self.UppercaseRegexp.match(name.name): if not self.UppercaseRegexp.match(name.asname): yield self.__error(node, "N811") elif self.LowercaseRegex.match(name.name): if not self.LowercaseRegex.match(name.asname): yield self.__error(node, "N812") elif self.LowercaseRegex.match(name.asname): yield self.__error(node, "N813") elif self.UppercaseRegexp.match(name.asname): yield self.__error(node, "N814") eric-6.0.8/eric/Plugins/CheckerPlugins/CodeStyleChecker/translations.py0000644000175000017500000005154212451233371025257 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing message translations for the code style plugin messages. """ from __future__ import unicode_literals from PyQt5.QtCore import QCoreApplication __all__ = ["getTranslatedMessage"] _messages = { "E101": QCoreApplication.translate( "pep8", "indentation contains mixed spaces and tabs"), "E111": QCoreApplication.translate( "pep8", "indentation is not a multiple of four"), "E112": QCoreApplication.translate( "pep8", "expected an indented block"), "E113": QCoreApplication.translate( "pep8", "unexpected indentation"), "E121": QCoreApplication.translate( "pep8", "continuation line indentation is not a multiple of four"), "E122": QCoreApplication.translate( "pep8", "continuation line missing indentation or outdented"), "E123": QCoreApplication.translate( "pep8", "closing bracket does not match indentation of opening" " bracket's line"), "E124": QCoreApplication.translate( "pep8", "closing bracket does not match visual indentation"), "E125": QCoreApplication.translate( "pep8", "continuation line with same indent as next logical line"), "E126": QCoreApplication.translate( "pep8", "continuation line over-indented for hanging indent"), "E127": QCoreApplication.translate( "pep8", "continuation line over-indented for visual indent"), "E128": QCoreApplication.translate( "pep8", "continuation line under-indented for visual indent"), "E129": QCoreApplication.translate( "pep8", "visually indented line with same indent as next logical line"), "E131": QCoreApplication.translate( "pep8", "continuation line unaligned for hanging indent"), "E133": QCoreApplication.translate( "pep8", "closing bracket is missing indentation"), "W191": QCoreApplication.translate( "pep8", "indentation contains tabs"), "E201": QCoreApplication.translate( "pep8", "whitespace after '{0}'"), "E202": QCoreApplication.translate( "pep8", "whitespace before '{0}'"), "E203": QCoreApplication.translate( "pep8", "whitespace before '{0}'"), "E211": QCoreApplication.translate( "pep8", "whitespace before '{0}'"), "E221": QCoreApplication.translate( "pep8", "multiple spaces before operator"), "E222": QCoreApplication.translate( "pep8", "multiple spaces after operator"), "E223": QCoreApplication.translate( "pep8", "tab before operator"), "E224": QCoreApplication.translate( "pep8", "tab after operator"), "E225": QCoreApplication.translate( "pep8", "missing whitespace around operator"), "E226": QCoreApplication.translate( "pep8", "missing whitespace around arithmetic operator"), "E227": QCoreApplication.translate( "pep8", "missing whitespace around bitwise or shift operator"), "E228": QCoreApplication.translate( "pep8", "missing whitespace around modulo operator"), "E231": QCoreApplication.translate( "pep8", "missing whitespace after '{0}'"), "E241": QCoreApplication.translate( "pep8", "multiple spaces after '{0}'"), "E242": QCoreApplication.translate( "pep8", "tab after '{0}'"), "E251": QCoreApplication.translate( "pep8", "unexpected spaces around keyword / parameter equals"), "E261": QCoreApplication.translate( "pep8", "at least two spaces before inline comment"), "E262": QCoreApplication.translate( "pep8", "inline comment should start with '# '"), "E265": QCoreApplication.translate( "pep8", "block comment should start with '# '"), "E271": QCoreApplication.translate( "pep8", "multiple spaces after keyword"), "E272": QCoreApplication.translate( "pep8", "multiple spaces before keyword"), "E273": QCoreApplication.translate( "pep8", "tab after keyword"), "E274": QCoreApplication.translate( "pep8", "tab before keyword"), "W291": QCoreApplication.translate( "pep8", "trailing whitespace"), "W292": QCoreApplication.translate( "pep8", "no newline at end of file"), "W293": QCoreApplication.translate( "pep8", "blank line contains whitespace"), "E301": QCoreApplication.translate( "pep8", "expected 1 blank line, found 0"), "E302": QCoreApplication.translate( "pep8", "expected 2 blank lines, found {0}"), "E303": QCoreApplication.translate( "pep8", "too many blank lines ({0})"), "E304": QCoreApplication.translate( "pep8", "blank lines found after function decorator"), "W391": QCoreApplication.translate( "pep8", "blank line at end of file"), "E401": QCoreApplication.translate( "pep8", "multiple imports on one line"), "E501": QCoreApplication.translate( "pep8", "line too long ({0} > {1} characters)"), "E502": QCoreApplication.translate( "pep8", "the backslash is redundant between brackets"), "W601": QCoreApplication.translate( "pep8", ".has_key() is deprecated, use 'in'"), "W602": QCoreApplication.translate( "pep8", "deprecated form of raising exception"), "W603": QCoreApplication.translate( "pep8", "'<>' is deprecated, use '!='"), "W604": QCoreApplication.translate( "pep8", "backticks are deprecated, use 'repr()'"), "E701": QCoreApplication.translate( "pep8", "multiple statements on one line (colon)"), "E702": QCoreApplication.translate( "pep8", "multiple statements on one line (semicolon)"), "E703": QCoreApplication.translate( "pep8", "statement ends with a semicolon"), "E711": QCoreApplication.translate( "pep8", "comparison to {0} should be {1}"), "E712": QCoreApplication.translate( "pep8", "comparison to {0} should be {1}"), "E713": QCoreApplication.translate( "pep8", "test for membership should be 'not in'"), "E714": QCoreApplication.translate( "pep8", "test for object identity should be 'is not'"), "E721": QCoreApplication.translate( "pep8", "do not compare types, use 'isinstance()'"), "E901": QCoreApplication.translate( "pep8", "{0}: {1}"), "E902": QCoreApplication.translate( "pep8", "{0}"), # DocStyleChecker messages "D101": QCoreApplication.translate( "DocStyleChecker", "module is missing a docstring"), "D102": QCoreApplication.translate( "DocStyleChecker", "public function/method is missing a docstring"), "D103": QCoreApplication.translate( "DocStyleChecker", "private function/method may be missing a docstring"), "D104": QCoreApplication.translate( "DocStyleChecker", "public class is missing a docstring"), "D105": QCoreApplication.translate( "DocStyleChecker", "private class may be missing a docstring"), "D111": QCoreApplication.translate( "DocStyleChecker", 'docstring not surrounded by """'), "D112": QCoreApplication.translate( "DocStyleChecker", 'docstring containing \\ not surrounded by r"""'), "D113": QCoreApplication.translate( "DocStyleChecker", 'docstring containing unicode character not surrounded by u"""'), "D121": QCoreApplication.translate( "DocStyleChecker", "one-liner docstring on multiple lines"), "D122": QCoreApplication.translate( "DocStyleChecker", "docstring has wrong indentation"), "D130": QCoreApplication.translate( "DocStyleChecker", "docstring does not contain a summary"), "D131": QCoreApplication.translate( "DocStyleChecker", "docstring summary does not end with a period"), "D132": QCoreApplication.translate( "DocStyleChecker", "docstring summary is not in imperative mood" " (Does instead of Do)"), "D133": QCoreApplication.translate( "DocStyleChecker", "docstring summary looks like a function's/method's signature"), "D134": QCoreApplication.translate( "DocStyleChecker", "docstring does not mention the return value type"), "D141": QCoreApplication.translate( "DocStyleChecker", "function/method docstring is separated by a blank line"), "D142": QCoreApplication.translate( "DocStyleChecker", "class docstring is not preceded by a blank line"), "D143": QCoreApplication.translate( "DocStyleChecker", "class docstring is not followed by a blank line"), "D144": QCoreApplication.translate( "DocStyleChecker", "docstring summary is not followed by a blank line"), "D145": QCoreApplication.translate( "DocStyleChecker", "last paragraph of docstring is not followed by a blank line"), "D203": QCoreApplication.translate( "DocStyleChecker", "private function/method is missing a docstring"), "D205": QCoreApplication.translate( "DocStyleChecker", "private class is missing a docstring"), "D221": QCoreApplication.translate( "DocStyleChecker", "leading quotes of docstring not on separate line"), "D222": QCoreApplication.translate( "DocStyleChecker", "trailing quotes of docstring not on separate line"), "D231": QCoreApplication.translate( "DocStyleChecker", "docstring summary does not end with a period"), "D232": QCoreApplication.translate( "DocStyleChecker", "docstring summary does not start with '{0}'"), "D234": QCoreApplication.translate( "DocStyleChecker", "docstring does not contain a @return line but function/method" " returns something"), "D235": QCoreApplication.translate( "DocStyleChecker", "docstring contains a @return line but function/method doesn't" " return anything"), "D236": QCoreApplication.translate( "DocStyleChecker", "docstring does not contain enough @param/@keyparam lines"), "D237": QCoreApplication.translate( "DocStyleChecker", "docstring contains too many @param/@keyparam lines"), "D238": QCoreApplication.translate( "DocStyleChecker", "keyword only arguments must be documented with @keyparam lines"), "D239": QCoreApplication.translate( "DocStyleChecker", "order of @param/@keyparam lines does" " not match the function/method signature"), "D242": QCoreApplication.translate( "DocStyleChecker", "class docstring is preceded by a blank line"), "D243": QCoreApplication.translate( "DocStyleChecker", "class docstring is followed by a blank line"), "D244": QCoreApplication.translate( "DocStyleChecker", "function/method docstring is preceded by a blank line"), "D245": QCoreApplication.translate( "DocStyleChecker", "function/method docstring is followed by a blank line"), "D246": QCoreApplication.translate( "DocStyleChecker", "docstring summary is not followed by a blank line"), "D247": QCoreApplication.translate( "DocStyleChecker", "last paragraph of docstring is followed by a blank line"), "D250": QCoreApplication.translate( "DocStyleChecker", "docstring does not contain a @exception line but function/method" " raises an exception"), "D251": QCoreApplication.translate( "DocStyleChecker", "docstring contains a @exception line but function/method doesn't" " raise an exception"), "D901": QCoreApplication.translate( "DocStyleChecker", "{0}: {1}"), # NamingStyleChecker messages "N801": QCoreApplication.translate( "NamingStyleChecker", "class names should use CapWords convention"), "N802": QCoreApplication.translate( "NamingStyleChecker", "function name should be lowercase"), "N803": QCoreApplication.translate( "NamingStyleChecker", "argument name should be lowercase"), "N804": QCoreApplication.translate( "NamingStyleChecker", "first argument of a class method should be named 'cls'"), "N805": QCoreApplication.translate( "NamingStyleChecker", "first argument of a method should be named 'self'"), "N806": QCoreApplication.translate( "NamingStyleChecker", "first argument of a static method should not be named" " 'self' or 'cls"), "N807": QCoreApplication.translate( "NamingStyleChecker", "module names should be lowercase"), "N808": QCoreApplication.translate( "NamingStyleChecker", "package names should be lowercase"), "N811": QCoreApplication.translate( "NamingStyleChecker", "constant imported as non constant"), "N812": QCoreApplication.translate( "NamingStyleChecker", "lowercase imported as non lowercase"), "N813": QCoreApplication.translate( "NamingStyleChecker", "camelcase imported as lowercase"), "N814": QCoreApplication.translate( "NamingStyleChecker", "camelcase imported as constant"), "N821": QCoreApplication.translate( "NamingStyleChecker", "variable in function should be lowercase"), "N831": QCoreApplication.translate( "NamingStyleChecker", "names 'l', 'O' and 'I' should be avoided"), # CodeStyleFixer messages "FD111": QCoreApplication.translate( 'CodeStyleFixer', "Triple single quotes converted to triple double quotes."), 'FD112': QCoreApplication.translate( 'CodeStyleFixer', 'Introductory quotes corrected to be {0}"""'), "FD121": QCoreApplication.translate( 'CodeStyleFixer', "Single line docstring put on one line."), "FD131": QCoreApplication.translate( 'CodeStyleFixer', "Period added to summary line."), "FD141": QCoreApplication.translate( 'CodeStyleFixer', "Blank line before function/method docstring removed."), "FD142": QCoreApplication.translate( 'CodeStyleFixer', "Blank line inserted before class docstring."), "FD143": QCoreApplication.translate( 'CodeStyleFixer', "Blank line inserted after class docstring."), "FD144": QCoreApplication.translate( 'CodeStyleFixer', "Blank line inserted after docstring summary."), "FD145": QCoreApplication.translate( 'CodeStyleFixer', "Blank line inserted after last paragraph of docstring."), "FD221": QCoreApplication.translate( 'CodeStyleFixer', "Leading quotes put on separate line."), "FD222": QCoreApplication.translate( 'CodeStyleFixer', "Trailing quotes put on separate line."), "FD242": QCoreApplication.translate( 'CodeStyleFixer', "Blank line before class docstring removed."), "FD244": QCoreApplication.translate( 'CodeStyleFixer', "Blank line before function/method docstring removed."), "FD243": QCoreApplication.translate( 'CodeStyleFixer', "Blank line after class docstring removed."), "FD245": QCoreApplication.translate( 'CodeStyleFixer', "Blank line after function/method docstring removed."), "FD247": QCoreApplication.translate( 'CodeStyleFixer', "Blank line after last paragraph removed."), "FE101": QCoreApplication.translate( 'CodeStyleFixer', "Tab converted to 4 spaces."), "FE111": QCoreApplication.translate( 'CodeStyleFixer', "Indentation adjusted to be a multiple of four."), "FE121": QCoreApplication.translate( 'CodeStyleFixer', "Indentation of continuation line corrected."), "FE124": QCoreApplication.translate( 'CodeStyleFixer', "Indentation of closing bracket corrected."), "FE122": QCoreApplication.translate( 'CodeStyleFixer', "Missing indentation of continuation line corrected."), "FE123": QCoreApplication.translate( 'CodeStyleFixer', "Closing bracket aligned to opening bracket."), "FE125": QCoreApplication.translate( 'CodeStyleFixer', "Indentation level changed."), "FE126": QCoreApplication.translate( 'CodeStyleFixer', "Indentation level of hanging indentation changed."), "FE127": QCoreApplication.translate( 'CodeStyleFixer', "Visual indentation corrected."), "FE201": QCoreApplication.translate( 'CodeStyleFixer', "Extraneous whitespace removed."), "FE225": QCoreApplication.translate( 'CodeStyleFixer', "Missing whitespace added."), "FE221": QCoreApplication.translate( 'CodeStyleFixer', "Extraneous whitespace removed."), "FE231": QCoreApplication.translate( 'CodeStyleFixer', "Missing whitespace added."), "FE251": QCoreApplication.translate( 'CodeStyleFixer', "Extraneous whitespace removed."), "FE261": QCoreApplication.translate( 'CodeStyleFixer', "Whitespace around comment sign corrected."), "FE301": QCoreApplication.translate( 'CodeStyleFixer', "One blank line inserted."), "FE302+": lambda n=1: QCoreApplication.translate( 'CodeStyleFixer', "%n blank line(s) inserted.", '', n), "FE302-": lambda n=1: QCoreApplication.translate( 'CodeStyleFixer', "%n superfluous lines removed", '', n), "FE303": QCoreApplication.translate( 'CodeStyleFixer', "Superfluous blank lines removed."), "FE304": QCoreApplication.translate( 'CodeStyleFixer', "Superfluous blank lines after function decorator removed."), "FE401": QCoreApplication.translate( 'CodeStyleFixer', "Imports were put on separate lines."), "FE501": QCoreApplication.translate( 'CodeStyleFixer', "Long lines have been shortened."), "FE502": QCoreApplication.translate( 'CodeStyleFixer', "Redundant backslash in brackets removed."), "FE701": QCoreApplication.translate( 'CodeStyleFixer', "Compound statement corrected."), "FE702": QCoreApplication.translate( 'CodeStyleFixer', "Compound statement corrected."), "FE711": QCoreApplication.translate( 'CodeStyleFixer', "Comparison to None/True/False corrected."), "FN804": QCoreApplication.translate( 'CodeStyleFixer', "'{0}' argument added."), "FN806": QCoreApplication.translate( 'CodeStyleFixer', "'{0}' argument removed."), "FW291": QCoreApplication.translate( 'CodeStyleFixer', "Whitespace stripped from end of line."), "FW292": QCoreApplication.translate( 'CodeStyleFixer', "newline added to end of file."), "FW391": QCoreApplication.translate( 'CodeStyleFixer', "Superfluous trailing blank lines removed from end of file."), "FW603": QCoreApplication.translate( 'CodeStyleFixer', "'<>' replaced by '!='."), "FWRITE_ERROR": QCoreApplication.translate( 'CodeStyleFixer', "Could not save the file! Skipping it. Reason: {0}"), } _messages_sample_args = { "E201": ["([{"], "E202": ["}])"], "E203": [",;:"], "E211": ["(["], "E231": [",;:"], "E241": [",;:"], "E242": [",;:"], "E302": [1], "E303": [3], "E501": [85, 79], "E711": ["None", "'if cond is None:'"], "E712": ["True", "'if cond is True:' or 'if cond:'"], "E901": ["SyntaxError", "Invalid Syntax"], "E902": ["IOError"], "D232": ["public"], "D901": ["SyntaxError", "Invalid Syntax"], "FWRITE_ERROR": ["IOError"], } def getTranslatedMessage(message): """ Module function to get a translated and formatted message for a given pyflakes message ID. @param message the message ID (string) @return translated and formatted message (string) """ if isinstance(message, list): message, args = message else: args = [] if message in _messages: if isinstance(args, int): # Retranslate with correct plural form return _messages[message](args) else: if message.startswith(('FD', 'FE', 'FN', 'FW')): prefix = '' else: prefix = message + ' ' return prefix + _messages[message].format(*args) elif ' ' in message: # already translated return message else: return QCoreApplication.translate( "CodeStyleFixer", " no message defined for code '{0}'")\ .format(message) eric-6.0.8/eric/Plugins/PluginTabnanny.py0000644000175000017500000003056212451233371017400 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Tabnanny plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, pyqtSignal from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from Project.ProjectBrowserModel import ProjectBrowserFileItem from Utilities import determinePythonVersion import Preferences # Start-Of-Header name = "Tabnanny Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "TabnannyPlugin" packageName = "__core__" shortDescription = "Show the Tabnanny dialog." longDescription = """This plugin implements the Tabnanny dialog.""" \ """ Tabnanny is used to check Python source files for correct""" \ """ indentations.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class TabnannyPlugin(QObject): """ Class implementing the Tabnanny plugin. @signal indentChecked(str, bool, str, str) emited when the indent check was done. """ indentChecked = pyqtSignal(str, bool, str, str) def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(TabnannyPlugin, self).__init__(ui) self.__ui = ui self.__initialize() self.backgroundService = e5App().getObject("BackgroundService") path = os.path.join( os.path.dirname(__file__), 'CheckerPlugins', 'Tabnanny') self.backgroundService.serviceConnect( 'indent', 'Python2', path, 'Tabnanny', lambda *args: self.indentChecked.emit(*args), onErrorCallback=self.serviceErrorPy2) self.backgroundService.serviceConnect( 'indent', 'Python3', path, 'Tabnanny', lambda *args: self.indentChecked.emit(*args), onErrorCallback=self.serviceErrorPy3) def __serviceError(self, fn, msg): """ Private slot handling service errors. @param fn file name (string) @param msg message text (string) """ self.indentChecked.emit(fn, True, "1", msg) def serviceErrorPy2(self, fx, lang, fn, msg): """ Public method handling service errors for Python 2. @param fx service name (string) @param lang language (string) @param fn file name (string) @param msg message text (string) """ if fx == 'indent' and lang == 'Python2': self.__serviceError(fn, msg) def serviceErrorPy3(self, fx, lang, fn, msg): """ Public method handling service errors for Python 2. @param fx service name (string) @param lang language (string) @param fn file name (string) @param msg message text (string) """ if fx == 'indent' and lang == 'Python3': self.__serviceError(fn, msg) def __initialize(self): """ Private slot to (re)initialize the plugin. """ self.__projectAct = None self.__projectTabnannyDialog = None self.__projectBrowserAct = None self.__projectBrowserMenu = None self.__projectBrowserTabnannyDialog = None self.__editors = [] self.__editorAct = None self.__editorTabnannyDialog = None def indentCheck(self, lang, filename, source): """ Public method to prepare a style check on one Python source file. @param lang language of the file or None to determine by internal algorithm (str or None) @param filename source filename (string) @param source string containing the code to check (string) """ if lang is None: lang = 'Python{0}'.format(determinePythonVersion(filename, source)) if lang not in ['Python2', 'Python3']: return self.backgroundService.enqueueRequest( 'indent', lang, filename, [source]) def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ menu = e5App().getObject("Project").getMenu("Checks") if menu: self.__projectAct = E5Action( self.tr('Check Indentations'), self.tr('&Indentations...'), 0, 0, self, 'project_check_indentations') self.__projectAct.setStatusTip( self.tr('Check indentations using tabnanny.')) self.__projectAct.setWhatsThis(self.tr( """Check Indentations...""" """

This checks Python files""" """ for bad indentations using tabnanny.

""" )) self.__projectAct.triggered.connect(self.__projectTabnanny) e5App().getObject("Project").addE5Actions([self.__projectAct]) menu.addAction(self.__projectAct) self.__editorAct = E5Action( self.tr('Check Indentations'), self.tr('&Indentations...'), 0, 0, self, "") self.__editorAct.setWhatsThis(self.tr( """Check Indentations...""" """

This checks Python files""" """ for bad indentations using tabnanny.

""" )) self.__editorAct.triggered.connect(self.__editorTabnanny) e5App().getObject("Project").showMenu.connect(self.__projectShowMenu) e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\ .showMenu.connect(self.__projectBrowserShowMenu) e5App().getObject("ViewManager").editorOpenedEd.connect( self.__editorOpened) e5App().getObject("ViewManager").editorClosedEd.connect( self.__editorClosed) for editor in e5App().getObject("ViewManager").getOpenEditors(): self.__editorOpened(editor) return None, True def deactivate(self): """ Public method to deactivate this plugin. """ e5App().getObject("Project").showMenu.disconnect( self.__projectShowMenu) e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\ .showMenu.disconnect(self.__projectBrowserShowMenu) e5App().getObject("ViewManager").editorOpenedEd.disconnect( self.__editorOpened) e5App().getObject("ViewManager").editorClosedEd.disconnect( self.__editorClosed) menu = e5App().getObject("Project").getMenu("Checks") if menu: menu.removeAction(self.__projectAct) if self.__projectBrowserMenu: if self.__projectBrowserAct: self.__projectBrowserMenu.removeAction( self.__projectBrowserAct) for editor in self.__editors: editor.showMenu.disconnect(self.__editorShowMenu) menu = editor.getMenu("Checks") if menu is not None: menu.removeAction(self.__editorAct) self.__initialize() def __projectShowMenu(self, menuName, menu): """ Private slot called, when the the project menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) """ if menuName == "Checks" and self.__projectAct is not None: self.__projectAct.setEnabled( e5App().getObject("Project").getProjectLanguage() in ["Python3", "Python2", "Python"]) def __projectBrowserShowMenu(self, menuName, menu): """ Private slot called, when the the project browser context menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) """ if menuName == "Checks" and \ e5App().getObject("Project").getProjectLanguage() in \ ["Python3", "Python2", "Python"]: self.__projectBrowserMenu = menu if self.__projectBrowserAct is None: self.__projectBrowserAct = E5Action( self.tr('Check Indentations'), self.tr('&Indentations...'), 0, 0, self, "") self.__projectBrowserAct.setWhatsThis(self.tr( """Check Indentations...""" """

This checks Python files""" """ for bad indentations using tabnanny.

""" )) self.__projectBrowserAct.triggered.connect( self.__projectBrowserTabnanny) if self.__projectBrowserAct not in menu.actions(): menu.addAction(self.__projectBrowserAct) def __projectTabnanny(self): """ Private slot used to check the project files for bad indentations. """ project = e5App().getObject("Project") project.saveAllScripts() ppath = project.getProjectPath() files = [os.path.join(ppath, file) for file in project.pdata["SOURCES"] if file.endswith( tuple(Preferences.getPython("Python3Extensions")) + tuple(Preferences.getPython("PythonExtensions")))] from CheckerPlugins.Tabnanny.TabnannyDialog import TabnannyDialog self.__projectTabnannyDialog = TabnannyDialog(self) self.__projectTabnannyDialog.show() self.__projectTabnannyDialog.prepare(files, project) def __projectBrowserTabnanny(self): """ Private method to handle the tabnanny context menu action of the project sources browser. """ browser = e5App().getObject("ProjectBrowser").getProjectBrowser( "sources") if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1: fn = [] for itm in browser.getSelectedItems([ProjectBrowserFileItem]): fn.append(itm.fileName()) else: itm = browser.model().item(browser.currentIndex()) try: fn = itm.fileName() except AttributeError: fn = itm.dirName() from CheckerPlugins.Tabnanny.TabnannyDialog import TabnannyDialog self.__projectBrowserTabnannyDialog = TabnannyDialog(self) self.__projectBrowserTabnannyDialog.show() self.__projectBrowserTabnannyDialog.start(fn) def __editorOpened(self, editor): """ Private slot called, when a new editor was opened. @param editor reference to the new editor (QScintilla.Editor) """ menu = editor.getMenu("Checks") if menu is not None: menu.addAction(self.__editorAct) editor.showMenu.connect(self.__editorShowMenu) self.__editors.append(editor) def __editorClosed(self, editor): """ Private slot called, when an editor was closed. @param editor reference to the editor (QScintilla.Editor) """ try: self.__editors.remove(editor) except ValueError: pass def __editorShowMenu(self, menuName, menu, editor): """ Private slot called, when the the editor context menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) @param editor reference to the editor """ if menuName == "Checks": if self.__editorAct not in menu.actions(): menu.addAction(self.__editorAct) self.__editorAct.setEnabled(editor.isPyFile()) def __editorTabnanny(self): """ Private slot to handle the tabnanny context menu action of the editors. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is not None: if editor.checkDirty() and editor.getFileName() is not None: from CheckerPlugins.Tabnanny.TabnannyDialog import \ TabnannyDialog self.__editorTabnannyDialog = TabnannyDialog(self) self.__editorTabnannyDialog.show() self.__editorTabnannyDialog.start(editor.getFileName()) eric-6.0.8/eric/Plugins/PluginVcsSubversion.py0000644000175000017500000001610012451233371020431 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Subversion version control plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, QCoreApplication from E5Gui.E5Application import e5App import Preferences from Preferences.Shortcuts import readShortcuts from VcsPlugins.vcsSubversion.SvnUtilities import getConfigPath, getServersPath import Utilities # Start-Of-Header name = "Subversion Plugin" author = "Detlev Offenbach " autoactivate = False deactivateable = True version = "6.0.0" pluginType = "version_control" pluginTypename = "Subversion" className = "VcsSubversionPlugin" packageName = "__core__" shortDescription = "Implements the Subversion version control interface." longDescription = \ """This plugin provides the Subversion version control interface.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" def exeDisplayData(): """ Public method to support the display of some executable info. @return dictionary containing the data to query the presence of the executable """ exe = 'svn' if Utilities.isWindowsPlatform(): exe += '.exe' data = { "programEntry": True, "header": QCoreApplication.translate( "VcsSubversionPlugin", "Version Control - Subversion (svn)"), "exe": exe, "versionCommand": '--version', "versionStartsWith": 'svn', "versionPosition": 2, "version": "", "versionCleanup": None, } return data def getVcsSystemIndicator(): """ Public function to get the indicators for this version control system. @return dictionary with indicator as key and a tuple with the vcs name (string) and vcs display string (string) """ global pluginTypename data = {} exe = 'svn' if Utilities.isWindowsPlatform(): exe += '.exe' if Utilities.isinpath(exe): data[".svn"] = (pluginTypename, displayString()) data["_svn"] = (pluginTypename, displayString()) return data def displayString(): """ Public function to get the display string. @return display string (string) """ exe = 'svn' if Utilities.isWindowsPlatform(): exe += '.exe' if Utilities.isinpath(exe): return QCoreApplication.translate( 'VcsSubversionPlugin', 'Subversion (svn)') else: return "" subversionCfgPluginObject = None def createConfigurationPage(configDlg): """ Module function to create the configuration page. @param configDlg reference to the configuration dialog (QDialog) @return reference to the configuration page """ global subversionCfgPluginObject from VcsPlugins.vcsSubversion.ConfigurationPage.SubversionPage import \ SubversionPage if subversionCfgPluginObject is None: subversionCfgPluginObject = VcsSubversionPlugin(None) page = SubversionPage(subversionCfgPluginObject) return page def getConfigData(): """ Module function returning data as required by the configuration dialog. @return dictionary with key "zzz_subversionPage" containing the relevant data """ return { "zzz_subversionPage": [QCoreApplication.translate("VcsSubversionPlugin", "Subversion"), os.path.join("VcsPlugins", "vcsSubversion", "icons", "preferences-subversion.png"), createConfigurationPage, "vcsPage", None], } def prepareUninstall(): """ Module function to prepare for an uninstallation. """ if not e5App().getObject("PluginManager").isPluginLoaded( "PluginVcsSubversion"): Preferences.Prefs.settings.remove("Subversion") class VcsSubversionPlugin(QObject): """ Class implementing the Subversion version control plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(VcsSubversionPlugin, self).__init__(ui) self.__ui = ui self.__subversionDefaults = { "StopLogOnCopy": True, "LogLimit": 20, "CommitMessages": 20, } from VcsPlugins.vcsSubversion.ProjectHelper import SvnProjectHelper self.__projectHelperObject = SvnProjectHelper(None, None) try: e5App().registerPluginObject( pluginTypename, self.__projectHelperObject, pluginType) except KeyError: pass # ignore duplicate registration readShortcuts(pluginName=pluginTypename) def getProjectHelper(self): """ Public method to get a reference to the project helper object. @return reference to the project helper object """ return self.__projectHelperObject def activate(self): """ Public method to activate this plugin. @return tuple of reference to instantiated viewmanager and activation status (boolean) """ from VcsPlugins.vcsSubversion.subversion import Subversion self.__object = Subversion(self, self.__ui) return self.__object, True def deactivate(self): """ Public method to deactivate this plugin. """ self.__object = None def getPreferences(self, key): """ Public method to retrieve the various settings. @param key the key of the value to get @return the requested setting """ if key in ["StopLogOnCopy"]: return Preferences.toBool(Preferences.Prefs.settings.value( "Subversion/" + key, self.__subversionDefaults[key])) elif key in ["LogLimit", "CommitMessages"]: return int(Preferences.Prefs.settings.value( "Subversion/" + key, self.__subversionDefaults[key])) elif key in ["Commits"]: return Preferences.toList(Preferences.Prefs.settings.value( "Subversion/" + key)) else: return Preferences.Prefs.settings.value("Subversion/" + key) def setPreferences(self, key, value): """ Public method to store the various settings. @param key the key of the setting to be set @param value the value to be set """ Preferences.Prefs.settings.setValue("Subversion/" + key, value) def getServersPath(self): """ Public method to get the filename of the servers file. @return filename of the servers file (string) """ return getServersPath() def getConfigPath(self): """ Public method to get the filename of the config file. @return filename of the config file (string) """ return getConfigPath() def prepareUninstall(self): """ Public method to prepare for an uninstallation. """ e5App().unregisterPluginObject(pluginTypename) eric-6.0.8/eric/Plugins/PluginWizardQFileDialog.py0000644000175000017500000001054312451233371021124 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the QFileDialog wizard plugin. """ from __future__ import unicode_literals import re from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "QFileDialog Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "FileDialogWizard" packageName = "__core__" shortDescription = "Show the QFileDialog wizard." longDescription = """This plugin shows the QFileDialog wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class FileDialogWizard(QObject): """ Class implementing the QFileDialog wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(FileDialogWizard, self).__init__(ui) self.__ui = ui self.__pyqtRe = re.compile(r"(?:import|from)\s+PyQt([45])") def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('QFileDialog Wizard'), self.tr('Q&FileDialog Wizard...'), 0, 0, self, 'wizards_qfiledialog') self.action.setStatusTip(self.tr('QFileDialog Wizard')) self.action.setWhatsThis(self.tr( """QFileDialog Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create a QFileDialog. The generated code is""" """ inserted at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) """ match = self.__pyqtRe.search(editor.text()) if match is None: pyqtVariant = 0 # unknown else: pyqtVariant = int(match.group(1)) # 4 or 5 from WizardPlugins.FileDialogWizard.FileDialogWizardDialog import \ FileDialogWizardDialog dlg = FileDialogWizardDialog(pyqtVariant, None) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), 1) else: return (None, 0) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/__init__.py0000644000175000017500000000022112451233371016173 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing all core plugins. """ eric-6.0.8/eric/Plugins/PluginVmTabview.py0000644000175000017500000000364012451233371017527 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Tabview view manager plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QT_TRANSLATE_NOOP, QObject from PyQt5.QtGui import QPixmap # Start-Of-Header name = "Tabview Plugin" author = "Detlev Offenbach " autoactivate = False deactivateable = False version = "6.0.0" pluginType = "viewmanager" pluginTypename = "tabview" displayString = QT_TRANSLATE_NOOP('VmTabviewPlugin', 'Tabbed View') className = "VmTabviewPlugin" packageName = "__core__" shortDescription = "Implements the Tabview view manager." longDescription = """This plugin provides the tabbed view view manager.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" def previewPix(): """ Module function to return a preview pixmap. @return preview pixmap (QPixmap) """ fname = os.path.join(os.path.dirname(__file__), "ViewManagerPlugins", "Tabview", "preview.png") return QPixmap(fname) class VmTabviewPlugin(QObject): """ Class implementing the Tabview view manager plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(VmTabviewPlugin, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of reference to instantiated viewmanager and activation status (boolean) """ from ViewManagerPlugins.Tabview.Tabview import Tabview self.__object = Tabview(self.__ui) return self.__object, True def deactivate(self): """ Public method to deactivate this plugin. """ # do nothing for the moment pass eric-6.0.8/eric/Plugins/PluginWizardQRegExp.py0000644000175000017500000001000012451233371020303 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the QRegExp wizard plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "QRegExp Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "QRegExpWizard" packageName = "__core__" shortDescription = "Show the QRegExp wizard." longDescription = """This plugin shows the QRegExp wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class QRegExpWizard(QObject): """ Class implementing the QRegExp wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(QRegExpWizard, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('QRegExp Wizard'), self.tr('Q&RegExp Wizard...'), 0, 0, self, 'wizards_qregexp') self.action.setStatusTip(self.tr('QRegExp Wizard')) self.action.setWhatsThis(self.tr( """QRegExp Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create a QRegExp. The generated code is inserted""" """ at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) """ from WizardPlugins.QRegExpWizard.QRegExpWizardDialog import \ QRegExpWizardDialog dlg = QRegExpWizardDialog(None, True) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), 1) else: return (None, False) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/DocumentationPlugins/0000755000175000017500000000000012451233404020237 5ustar piotrpiotreric-6.0.8/eric/Plugins/DocumentationPlugins/__init__.py0000644000175000017500000000025412451233371022354 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the various core documentation tool plugins. """ eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericdoc/0000755000175000017500000000000012557365404021624 5ustar piotrpiotreric-6.0.8/eric/Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.ui0000644000175000017500000004565012263302017025774 0ustar piotrpiotr EricdocConfigDialog 0 0 554 550 Ericdoc Configuration true 0 General Output Directory: Enter an output directory Qt::NoFocus Press to open a directory selection dialog Additional source extensions: Enter additional source extensions separated by a comma Select to recurse into subdirectories Recurse into subdirectories Select, if no index files should be generated Don't generate index files Qt::Horizontal QSizePolicy::Expanding 145 20 Select to exclude empty modules Don't include empty modules Qt::Horizontal QSizePolicy::Expanding 40 20 Exclude Files: Enter filename patterns of files to be excluded separated by a comma Exclude Directories Enter a directory basename to be ignored Press to add the entered directory to the list Add Press to delete the selected directory from the list Delete List of directory basenames to be ignored Qt::NoFocus Press to open a directory selection dialog Style Style Sheet Enter the filename of a CSS style sheet. Leave empty to use the colours defined below. Qt::NoFocus Press to open a file selection dialog Colours Press to select the class and function header background colour. Class/Function Header Background Press to select the class and function header foreground colour. Class/Function Header Foreground Press to select the level 2 header background colour. Level 2 Header Background Press to select the level 2 header foreground colour. Level 2 Header Foreground Press to select the level 1 header background colour. Level 1 Header Background Press to select the level 1 header foreground colour. Level 1 Header Foreground Press to select the body background colour. Body Background Press to select the body foreground colour. Body Foreground Press to select the foreground colour of links. Links This shows an example of the selected colours. true QtHelp Generate QtHelp Files true false Output Directory: Enter an output directory Qt::NoFocus Press to open a directory selection dialog Namespace: Enter the namespace Virtual Folder: Enter the name of the virtual folder (must not contain '/') Filter Name: Enter the name of the custom filter Filter Attributes: Enter the filter attributes separated by ':' Title: Enter a short title for the top entry Select to generate the QtHelp collection files Generate QtHelp collection files Qt::Vertical 20 271 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource tabWidget outputDirEdit sourceExtEdit recursionCheckBox noindexCheckBox noemptyCheckBox excludeFilesEdit ignoreDirsList ignoreDirEdit addButton deleteButton cssEdit bodyFgButton bodyBgButton l1FgButton l1BgButton l2FgButton l2BgButton cfFgButton cfBgButton linkFgButton sample qtHelpGroup qtHelpDirEdit qtHelpNamespaceEdit qtHelpFolderEdit qtHelpFilterNameEdit qtHelpFilterAttributesEdit qtHelpTitleEdit qtHelpGenerateCollectionCheckBox buttonBox buttonBox accepted() EricdocConfigDialog accept() 31 480 31 498 buttonBox rejected() EricdocConfigDialog reject() 125 482 125 499 eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericdoc/__init__.py0000644000175000017500000000022312451233371023720 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the Ericdoc plugin. """ eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.py0000644000175000017500000005443212451233371026012 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the parameters for eric6_doc. """ from __future__ import unicode_literals import sys import os import copy from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QColorDialog from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_EricdocConfigDialog import Ui_EricdocConfigDialog from DocumentationTools.Config import eric6docDefaultColors, \ eric6docColorParameterNames import Utilities import UI.PixmapCache from eric6config import getConfig class EricdocConfigDialog(QDialog, Ui_EricdocConfigDialog): """ Class implementing a dialog to enter the parameters for eric6_doc. """ def __init__(self, project, parms=None, parent=None): """ Constructor @param project reference to the project object (Project.Project) @param parms parameters to set in the dialog @param parent parent widget of this dialog """ super(EricdocConfigDialog, self).__init__(parent) self.setupUi(self) self.outputDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.ignoreDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.cssButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.qtHelpDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.__okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.__initializeDefaults() self.sampleText = self.tr( '''''' '''''' '''''' '''''' '''''' '''''' '''

''' '''Level 1 Header

''' '''

''' '''Level 2 Header

''' '''

''' '''Class and Function Header

''' '''Standard body text with ''' '''
some links embedded.''' '''''' ) # get a copy of the defaults to store the user settings self.parameters = copy.deepcopy(self.defaults) self.colors = eric6docDefaultColors.copy() # combine it with the values of parms if parms is not None: for key, value in list(parms.items()): if key.endswith("Color"): self.colors[key] = parms[key] else: self.parameters[key] = parms[key] self.parameters['outputDirectory'] = \ Utilities.toNativeSeparators(self.parameters['outputDirectory']) self.parameters['qtHelpOutputDirectory'] = \ Utilities.toNativeSeparators( self.parameters['qtHelpOutputDirectory']) self.parameters['cssFile'] = \ Utilities.toNativeSeparators(self.parameters['cssFile']) if self.parameters['cssFile'].startswith("%PYTHON%"): self.parameters['cssFile'] = self.parameters['cssFile'].replace( "%PYTHON%", Utilities.getPythonModulesDirectory()) self.ppath = project.getProjectPath() self.project = project self.outputDirCompleter = E5DirCompleter(self.outputDirEdit) self.ignoreDirCompleter = E5DirCompleter(self.ignoreDirEdit) self.qtHelpDirCompleter = E5DirCompleter(self.qtHelpDirEdit) self.recursionCheckBox.setChecked(self.parameters['useRecursion']) self.noindexCheckBox.setChecked(self.parameters['noindex']) self.noemptyCheckBox.setChecked(self.parameters['noempty']) self.outputDirEdit.setText(self.parameters['outputDirectory']) self.ignoreDirsList.clear() for d in self.parameters['ignoreDirectories']: self.ignoreDirsList.addItem(d) self.cssEdit.setText(self.parameters['cssFile']) self.sourceExtEdit.setText( ", ".join(self.parameters['sourceExtensions'])) self.excludeFilesEdit.setText( ", ".join(self.parameters['ignoreFilePatterns'])) self.sample.setHtml(self.sampleText.format(**self.colors)) self.qtHelpGroup.setChecked(self.parameters['qtHelpEnabled']) self.qtHelpDirEdit.setText(self.parameters['qtHelpOutputDirectory']) self.qtHelpNamespaceEdit.setText(self.parameters['qtHelpNamespace']) self.qtHelpFolderEdit.setText(self.parameters['qtHelpVirtualFolder']) self.qtHelpFilterNameEdit.setText(self.parameters['qtHelpFilterName']) self.qtHelpFilterAttributesEdit.setText( self.parameters['qtHelpFilterAttributes']) self.qtHelpTitleEdit.setText(self.parameters['qtHelpTitle']) self.qtHelpGenerateCollectionCheckBox.setChecked( self.parameters['qtHelpCreateCollection']) def __initializeDefaults(self): """ Private method to set the default values. These are needed later on to generate the commandline parameters. """ self.defaults = { 'useRecursion': 0, 'noindex': 0, 'noempty': 0, 'outputDirectory': '', 'ignoreDirectories': [], 'ignoreFilePatterns': [], 'cssFile': '', 'sourceExtensions': [], 'qtHelpEnabled': False, 'qtHelpOutputDirectory': '', 'qtHelpNamespace': '', 'qtHelpVirtualFolder': 'source', 'qtHelpFilterName': 'unknown', 'qtHelpFilterAttributes': '', 'qtHelpTitle': '', 'qtHelpCreateCollection': False, } def generateParameters(self): """ Public method that generates the commandline parameters. It generates a list of strings to be used to set the QProcess arguments for the ericdoc call and a dictionary containing the non default parameters. This dictionary can be passed back upon object generation to overwrite the default settings. @return a tuple of the commandline parameters and non default parameters (list of strings, dictionary) """ parms = {} args = [] # 1. the program name args.append(sys.executable) args.append( Utilities.normabsjoinpath(getConfig('ericDir'), "eric6_doc.py")) # 2. the commandline options # 2a. general commandline options if self.parameters['outputDirectory'] != \ self.defaults['outputDirectory']: parms['outputDirectory'] = Utilities.fromNativeSeparators( self.project.getRelativePath( self.parameters['outputDirectory'])) args.append('-o') if os.path.isabs(self.parameters['outputDirectory']): args.append(self.parameters['outputDirectory']) else: args.append(os.path.join( self.ppath, self.parameters['outputDirectory'])) else: self.parameters['outputDirectory'] = \ self.defaults['outputDirectory'] if self.parameters['ignoreDirectories'] != \ self.defaults['ignoreDirectories']: parms['ignoreDirectories'] = \ self.parameters['ignoreDirectories'][:] for d in self.parameters['ignoreDirectories']: args.append('-x') args.append(d) if self.parameters['ignoreFilePatterns'] != \ self.defaults['ignoreFilePatterns']: parms['ignoreFilePatterns'] = \ self.parameters['ignoreFilePatterns'][:] for pattern in self.parameters['ignoreFilePatterns']: args.append("--exclude-file={0}".format(pattern)) if self.parameters['useRecursion'] != self.defaults['useRecursion']: parms['useRecursion'] = self.parameters['useRecursion'] args.append('-r') if self.parameters['noindex'] != self.defaults['noindex']: parms['noindex'] = self.parameters['noindex'] args.append('-i') if self.parameters['noempty'] != self.defaults['noempty']: parms['noempty'] = self.parameters['noempty'] args.append('-e') if self.parameters['sourceExtensions'] != \ self.defaults['sourceExtensions']: parms['sourceExtensions'] = self.parameters['sourceExtensions'][:] for ext in self.parameters['sourceExtensions']: args.append('-t') args.append(ext) # 2b. style commandline options if self.parameters['cssFile'] != self.defaults['cssFile']: cssFile = self.project.getRelativePath(self.parameters['cssFile']) if cssFile.startswith(Utilities.getPythonModulesDirectory()): cssFile = cssFile.replace( Utilities.getPythonModulesDirectory(), "%PYTHON%") parms['cssFile'] = Utilities.fromNativeSeparators(cssFile) args.append('-c') if os.path.isabs(self.parameters['cssFile']): args.append(self.parameters['cssFile']) else: args.append( os.path.join(self.ppath, self.parameters['cssFile'])) for key, value in list(self.colors.items()): if self.colors[key] != eric6docDefaultColors[key]: parms[key] = self.colors[key] args.append("--{0}={1}".format( eric6docColorParameterNames[key], self.colors[key])) # 2c. QtHelp commandline options parms['qtHelpEnabled'] = self.parameters['qtHelpEnabled'] if self.parameters['qtHelpEnabled']: args.append('--create-qhp') if self.parameters['qtHelpOutputDirectory'] != \ self.defaults['qtHelpOutputDirectory']: parms['qtHelpOutputDirectory'] = Utilities.fromNativeSeparators( self.project.getRelativePath( self.parameters['qtHelpOutputDirectory'])) if os.path.isabs(self.parameters['outputDirectory']): args.append("--qhp-outdir={0}".format( self.parameters['qtHelpOutputDirectory'])) else: args.append("--qhp-outdir={0}".format( os.path.join(self.ppath, self.parameters['qtHelpOutputDirectory']))) if self.parameters['qtHelpNamespace'] != \ self.defaults['qtHelpNamespace']: parms['qtHelpNamespace'] = self.parameters['qtHelpNamespace'] args.append("--qhp-namespace={0}".format( self.parameters['qtHelpNamespace'])) if self.parameters['qtHelpVirtualFolder'] != \ self.defaults['qtHelpVirtualFolder']: parms['qtHelpVirtualFolder'] = \ self.parameters['qtHelpVirtualFolder'] args.append("--qhp-virtualfolder={0}".format( self.parameters['qtHelpVirtualFolder'])) if self.parameters['qtHelpFilterName'] != \ self.defaults['qtHelpFilterName']: parms['qtHelpFilterName'] = self.parameters['qtHelpFilterName'] args.append("--qhp-filtername={0}".format( self.parameters['qtHelpFilterName'])) if self.parameters['qtHelpFilterAttributes'] != \ self.defaults['qtHelpFilterAttributes']: parms['qtHelpFilterAttributes'] = \ self.parameters['qtHelpFilterAttributes'] args.append("--qhp-filterattribs={0}".format( self.parameters['qtHelpFilterAttributes'])) if self.parameters['qtHelpTitle'] != self.defaults['qtHelpTitle']: parms['qtHelpTitle'] = self.parameters['qtHelpTitle'] args.append("--qhp-title={0}".format( self.parameters['qtHelpTitle'])) if self.parameters['qtHelpCreateCollection'] != \ self.defaults['qtHelpCreateCollection']: parms['qtHelpCreateCollection'] = \ self.parameters['qtHelpCreateCollection'] args.append('--create-qhc') return (args, parms) @pyqtSlot() def on_outputDirButton_clicked(self): """ Private slot to select the output directory. It displays a directory selection dialog to select the directory the documentations is written to. """ startDir = Utilities.fromNativeSeparators(self.outputDirEdit.text()) if not startDir: startDir = Utilities.fromNativeSeparators(self.ppath) directory = E5FileDialog.getExistingDirectory( self, self.tr("Select output directory"), startDir, E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: # make it relative, if it is a subdirectory of the project path dn = Utilities.toNativeSeparators(directory) dn = self.project.getRelativePath(dn) while dn.endswith(os.sep): dn = dn[:-1] self.outputDirEdit.setText(dn) @pyqtSlot() def on_ignoreDirButton_clicked(self): """ Private slot to select a directory to be ignored. It displays a directory selection dialog to select a directory to be ignored. """ startDir = Utilities.fromNativeSeparators(self.ignoreDirEdit.text()) if not startDir: startDir = self.ppath directory = E5FileDialog.getExistingDirectory( self, self.tr("Select directory to exclude"), startDir, E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: # make it relative, if it is a subdirectory of the project path dn = Utilities.toNativeSeparators(directory) dn = self.project.getRelativePath(dn) while dn.endswith(os.sep): dn = dn[:-1] self.ignoreDirEdit.setText(dn) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add the directory displayed to the listview. The directory in the ignore directories line edit is moved to the listbox above and the edit is cleared. """ basename = os.path.basename(self.ignoreDirEdit.text()) if basename: self.ignoreDirsList.addItem(basename) self.ignoreDirEdit.clear() @pyqtSlot() def on_deleteButton_clicked(self): """ Private slot to delete the currently selected directory of the listbox. """ itm = self.ignoreDirsList.takeItem(self.ignoreDirsList.currentRow()) del itm @pyqtSlot() def on_cssButton_clicked(self): """ Private slot to select a css style sheet. """ cssFile = E5FileDialog.getOpenFileName( self, self.tr("Select CSS style sheet"), getConfig('ericCSSDir'), self.tr("Style sheet (*.css);;All files (*)")) if cssFile: # make it relative, if it is in a subdirectory of the project path cf = Utilities.toNativeSeparators(cssFile) cf = self.project.getRelativePath(cf) self.cssEdit.setText(cf) def __selectColor(self, colorKey): """ Private method to select a color. @param colorKey key of the color to select (string) """ color = QColorDialog.getColor(QColor(self.colors[colorKey])) if color.isValid(): self.colors[colorKey] = color.name() self.sample.setHtml(self.sampleText.format(self.colors)) @pyqtSlot() def on_bodyFgButton_clicked(self): """ Private slot to select the body foreground color. """ self.__selectColor('BodyColor') @pyqtSlot() def on_bodyBgButton_clicked(self): """ Private slot to select the body background color. """ self.__selectColor('BodyBgColor') @pyqtSlot() def on_l1FgButton_clicked(self): """ Private slot to select the level 1 header foreground color. """ self.__selectColor('Level1HeaderColor') @pyqtSlot() def on_l1BgButton_clicked(self): """ Private slot to select the level 1 header background color. """ self.__selectColor('Level1HeaderBgColor') @pyqtSlot() def on_l2FgButton_clicked(self): """ Private slot to select the level 2 header foreground color. """ self.__selectColor('Level2HeaderColor') @pyqtSlot() def on_l2BgButton_clicked(self): """ Private slot to select the level 2 header background color. """ self.__selectColor('Level2HeaderBgColor') @pyqtSlot() def on_cfFgButton_clicked(self): """ Private slot to select the class/function header foreground color. """ self.__selectColor('CFColor') @pyqtSlot() def on_cfBgButton_clicked(self): """ Private slot to select the class/function header background color. """ self.__selectColor('CFBgColor') @pyqtSlot() def on_linkFgButton_clicked(self): """ Private slot to select the foreground color of links. """ self.__selectColor('LinkColor') def __checkQtHelpOptions(self): """ Private slot to check the QtHelp options and set the ok button accordingly. """ setOn = True if self.qtHelpGroup.isChecked(): if not self.qtHelpNamespaceEdit.text(): setOn = False if not self.qtHelpFolderEdit.text(): setOn = False else: if '/' in self.qtHelpFolderEdit.text(): setOn = False if not self.qtHelpTitleEdit.text(): setOn = False self.__okButton.setEnabled(setOn) @pyqtSlot(bool) def on_qtHelpGroup_toggled(self, enabled): """ Private slot to toggle the generation of QtHelp files. @param enabled flag indicating the state (boolean) """ self.__checkQtHelpOptions() @pyqtSlot(str) def on_qtHelpNamespaceEdit_textChanged(self, txt): """ Private slot to check the namespace. @param txt text of the line edit (string) """ self.__checkQtHelpOptions() @pyqtSlot(str) def on_qtHelpFolderEdit_textChanged(self, txt): """ Private slot to check the virtual folder. @param txt text of the line edit (string) """ self.__checkQtHelpOptions() @pyqtSlot(str) def on_qtHelpTitleEdit_textChanged(self, txt): """ Private slot to check the title. @param txt text of the line edit (string) """ self.__checkQtHelpOptions() @pyqtSlot() def on_qtHelpDirButton_clicked(self): """ Private slot to select the output directory for the QtHelp files. It displays a directory selection dialog to select the directory the QtHelp files are written to. """ directory = E5FileDialog.getExistingDirectory( self, self.tr("Select output directory for QtHelp files"), self.qtHelpDirEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: # make it relative, if it is a subdirectory of the project path dn = Utilities.toNativeSeparators(directory) dn = self.project.getRelativePath(dn) while dn.endswith(os.sep): dn = dn[:-1] self.qtHelpDirEdit.setText(dn) def accept(self): """ Public slot called by the Ok button. It saves the values in the parameters dictionary. """ self.parameters['useRecursion'] = self.recursionCheckBox.isChecked() self.parameters['noindex'] = self.noindexCheckBox.isChecked() self.parameters['noempty'] = self.noemptyCheckBox.isChecked() outdir = self.outputDirEdit.text() if outdir != '': outdir = os.path.normpath(outdir) if outdir.endswith(os.sep): outdir = outdir[:-1] self.parameters['outputDirectory'] = outdir self.parameters['ignoreDirectories'] = [] for row in range(0, self.ignoreDirsList.count()): itm = self.ignoreDirsList.item(row) self.parameters['ignoreDirectories'].append( os.path.normpath(itm.text())) cssFile = self.cssEdit.text() if cssFile != '': cssFile = os.path.normpath(cssFile) self.parameters['cssFile'] = cssFile extensions = self.sourceExtEdit.text().split(',') self.parameters['sourceExtensions'] = \ [ext.strip() for ext in extensions] patterns = self.excludeFilesEdit.text().split(',') self.parameters['ignoreFilePatterns'] = \ [pattern.strip() for pattern in patterns] self.parameters['qtHelpEnabled'] = self.qtHelpGroup.isChecked() self.parameters['qtHelpOutputDirectory'] = self.qtHelpDirEdit.text() self.parameters['qtHelpNamespace'] = self.qtHelpNamespaceEdit.text() self.parameters['qtHelpVirtualFolder'] = self.qtHelpFolderEdit.text() self.parameters['qtHelpFilterName'] = self.qtHelpFilterNameEdit.text() self.parameters['qtHelpFilterAttributes'] = \ self.qtHelpFilterAttributesEdit.text() self.parameters['qtHelpTitle'] = self.qtHelpTitleEdit.text() self.parameters['qtHelpCreateCollection'] = \ self.qtHelpGenerateCollectionCheckBox.isChecked() # call the accept slot of the base class super(EricdocConfigDialog, self).accept() eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericdoc/EricdocExecDialog.ui0000644000175000017500000000553412060166053025453 0ustar piotrpiotr EricdocExecDialog 0 0 753 602 Ericdoc true 0 3 Messages 0 3 <b>Ericdoc Execution</b> <p>This shows the output of the Ericdoc generator command.</p> 0 1 Errors 0 1 <b>Ericdoc Execution</b> <p>This shows the errors of the Ericdoc generator command.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource contents errors buttonBox eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericdoc/EricdocExecDialog.py0000644000175000017500000001274512451233371025472 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the ericdoc process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os.path from PyQt5.QtCore import QProcess, QTimer from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5MessageBox from .Ui_EricdocExecDialog import Ui_EricdocExecDialog import Preferences class EricdocExecDialog(QDialog, Ui_EricdocExecDialog): """ Class implementing a dialog to show the output of the ericdoc process. This class starts a QProcess and displays a dialog that shows the output of the documentation command process. """ def __init__(self, cmdname, parent=None): """ Constructor @param cmdname name of the documentation generator (string) @param parent parent widget of this dialog (QWidget) """ super(EricdocExecDialog, self).__init__(parent) self.setModal(True) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = None self.cmdname = cmdname def start(self, args, fn): """ Public slot to start the ericdoc command. @param args commandline arguments for ericdoc program (list of strings) @param fn filename or dirname to be processed by ericdoc program (string) @return flag indicating the successful start of the process (boolean) """ self.errorGroup.hide() self.filename = fn if os.path.isdir(self.filename): dname = os.path.abspath(self.filename) fname = "." if os.path.exists(os.path.join(dname, "__init__.py")): fname = os.path.basename(dname) dname = os.path.dirname(dname) else: dname = os.path.dirname(self.filename) fname = os.path.basename(self.filename) self.contents.clear() self.errors.clear() program = args[0] del args[0] args.append(fname) self.process = QProcess() self.process.setWorkingDirectory(dname) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.process.finished.connect(self.__finish) self.setWindowTitle( self.tr('{0} - {1}').format(self.cmdname, self.filename)) self.process.start(program, args) procStarted = self.process.waitForStarted(5000) if not procStarted: E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format(program)) return procStarted def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.accept() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __finish(self): """ Private slot called when the process finished. It is called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.process = None self.contents.insertPlainText( self.tr('\n{0} finished.\n').format(self.cmdname)) self.contents.ensureCursorVisible() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.contents.insertPlainText(s) self.contents.ensureCursorVisible() def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ self.process.setReadChannel(QProcess.StandardError) while self.process.canReadLine(): self.errorGroup.show() s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericapi/0000755000175000017500000000000012557365404021630 5ustar piotrpiotreric-6.0.8/eric/Plugins/DocumentationPlugins/Ericapi/EricapiConfigDialog.py0000644000175000017500000002623612515231365026025 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the parameters for eric6_api. """ from __future__ import unicode_literals import sys import os import copy from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter, E5DirCompleter from E5Gui import E5FileDialog from .Ui_EricapiConfigDialog import Ui_EricapiConfigDialog import Utilities import UI.PixmapCache import DocumentationTools from eric6config import getConfig class EricapiConfigDialog(QDialog, Ui_EricapiConfigDialog): """ Class implementing a dialog to enter the parameters for eric6_api. """ def __init__(self, project, parms=None, parent=None): """ Constructor @param project reference to the project object (Project.Project) @param parms parameters to set in the dialog @param parent parent widget of this dialog """ super(EricapiConfigDialog, self).__init__(parent) self.setupUi(self) self.outputFileButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.ignoreDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) for language in sorted( DocumentationTools.supportedExtensionsDictForApis.keys()): self.languagesList.addItem(language) self.ppath = project.getProjectPath() self.project = project self.__initializeDefaults() # get a copy of the defaults to store the user settings self.parameters = copy.deepcopy(self.defaults) # combine it with the values of parms if parms is not None: for key, value in list(parms.items()): self.parameters[key] = parms[key] self.parameters['outputFile'] = \ Utilities.toNativeSeparators(self.parameters['outputFile']) self.outputFileCompleter = E5FileCompleter(self.outputFileEdit) self.ignoreDirCompleter = E5DirCompleter(self.ignoreDirEdit) self.recursionCheckBox.setChecked(self.parameters['useRecursion']) self.includePrivateCheckBox.setChecked( self.parameters['includePrivate']) self.outputFileEdit.setText(self.parameters['outputFile']) self.baseEdit.setText(self.parameters['basePackage']) self.ignoreDirsList.clear() for d in self.parameters['ignoreDirectories']: self.ignoreDirsList.addItem(d) self.sourceExtEdit.setText( ", ".join(self.parameters['sourceExtensions'])) self.excludeFilesEdit.setText( ", ".join(self.parameters['ignoreFilePatterns'])) for language in self.parameters['languages']: if language == "Python": # convert Python to the more specific Python2 language = "Python2" items = self.languagesList.findItems( language, Qt.MatchFlags(Qt.MatchExactly)) items and items[0].setSelected(True) def __initializeDefaults(self): """ Private method to set the default values. These are needed later on to generate the commandline parameters. """ self.defaults = { 'useRecursion': False, 'includePrivate': False, 'outputFile': '', 'basePackage': '', 'ignoreDirectories': [], 'ignoreFilePatterns': [], 'sourceExtensions': [], } lang = self.project.getProjectLanguage() if lang in DocumentationTools.supportedExtensionsDictForApis: self.defaults['languages'] = [lang] else: self.defaults['languages'] = ["Python3"] def generateParameters(self): """ Public method that generates the commandline parameters. It generates a list of strings to be used to set the QProcess arguments for the ericapi call and a dictionary containing the non default parameters. This dictionary can be passed back upon object generation to overwrite the default settings. @return a tuple of the commandline parameters and non default parameters (list of strings, dictionary) """ parms = {} args = [] # 1. the program name args.append(sys.executable) args.append( Utilities.normabsjoinpath(getConfig('ericDir'), "eric6_api.py")) # 2. the commandline options if self.parameters['outputFile'] != self.defaults['outputFile']: parms['outputFile'] = Utilities.fromNativeSeparators( self.project.getRelativePath(self.parameters['outputFile'])) args.append('-o') if os.path.isabs(self.parameters['outputFile']): args.append(self.parameters['outputFile']) else: args.append( os.path.join(self.ppath, self.parameters['outputFile'])) else: self.parameters['outputFile'] = self.defaults['outputFile'] if self.parameters['basePackage'] != self.defaults['basePackage']: parms['basePackage'] = self.parameters['basePackage'] args.append('-b') args.append(self.parameters['basePackage']) if self.parameters['ignoreDirectories'] != \ self.defaults['ignoreDirectories']: parms['ignoreDirectories'] = \ self.parameters['ignoreDirectories'][:] for d in self.parameters['ignoreDirectories']: args.append('-x') args.append(d) if self.parameters['ignoreFilePatterns'] != \ self.defaults['ignoreFilePatterns']: parms['ignoreFilePatterns'] = \ self.parameters['ignoreFilePatterns'][:] for pattern in self.parameters['ignoreFilePatterns']: args.append("--exclude-file={0}".format(pattern)) if self.parameters['useRecursion'] != self.defaults['useRecursion']: parms['useRecursion'] = self.parameters['useRecursion'] args.append('-r') if self.parameters['sourceExtensions'] != \ self.defaults['sourceExtensions']: parms['sourceExtensions'] = self.parameters['sourceExtensions'][:] for ext in self.parameters['sourceExtensions']: args.append('-t') args.append(ext) if self.parameters['includePrivate'] != \ self.defaults['includePrivate']: parms['includePrivate'] = self.parameters['includePrivate'] args.append('-p') parms['languages'] = self.parameters['languages'][:] for lang in self.parameters['languages']: args.append('--language={0}'.format(lang)) return (args, parms) @pyqtSlot() def on_outputFileButton_clicked(self): """ Private slot to select the output file. It displays a file selection dialog to select the file the api is written to. """ startFile = Utilities.fromNativeSeparators(self.outputFileEdit.text()) if not startFile: startPath = Utilities.fromNativeSeparators( self.project.getProjectPath()) startFile = (startPath + "/" + self.project.getProjectName() + ".api") filename = E5FileDialog.getSaveFileName( self, self.tr("Select output file"), startFile, self.tr("API files (*.api);;All files (*)")) if filename: # make it relative, if it is in a subdirectory of the project path fn = Utilities.toNativeSeparators(filename) fn = self.project.getRelativePath(fn) self.outputFileEdit.setText(fn) def on_outputFileEdit_textChanged(self, filename): """ Private slot to enable/disable the "OK" button. @param filename name of the file (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(filename != "") @pyqtSlot() def on_ignoreDirButton_clicked(self): """ Private slot to select a directory to be ignored. It displays a directory selection dialog to select a directory to be ignored. """ startDir = Utilities.fromNativeSeparators(self.ignoreDirEdit.text()) if not startDir: startDir = self.ppath directory = E5FileDialog.getExistingDirectory( self, self.tr("Select directory to exclude"), startDir, E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: # make it relative, if it is a subdirectory of the project path dn = Utilities.toNativeSeparators(directory) dn = self.project.getRelativePath(dn) while dn.endswith(os.sep): dn = dn[:-1] self.ignoreDirEdit.setText(dn) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add the directory displayed to the listview. The directory in the ignore directories line edit is moved to the listbox above and the edit is cleared. """ basename = os.path.basename(self.ignoreDirEdit.text()) if basename: self.ignoreDirsList.addItem(basename) self.ignoreDirEdit.clear() @pyqtSlot() def on_deleteButton_clicked(self): """ Private slot to delete the currently selected directory of the listbox. """ itm = self.ignoreDirsList.takeItem(self.ignoreDirsList.currentRow()) del itm def accept(self): """ Public slot called by the Ok button. It saves the values in the parameters dictionary. """ self.parameters['useRecursion'] = self.recursionCheckBox.isChecked() self.parameters['includePrivate'] = \ self.includePrivateCheckBox.isChecked() outfile = self.outputFileEdit.text() if outfile != '': outfile = os.path.normpath(outfile) self.parameters['outputFile'] = outfile self.parameters['basePackage'] = self.baseEdit.text() self.parameters['ignoreDirectories'] = [] for row in range(0, self.ignoreDirsList.count()): itm = self.ignoreDirsList.item(row) self.parameters['ignoreDirectories'].append( os.path.normpath(itm.text())) extensions = self.sourceExtEdit.text().split(',') self.parameters['sourceExtensions'] = \ [ext.strip() for ext in extensions if len(ext) > 0] patterns = self.excludeFilesEdit.text().split(',') self.parameters['ignoreFilePatterns'] = \ [pattern.strip() for pattern in patterns] self.parameters['languages'] = [] for itm in self.languagesList.selectedItems(): self.parameters['languages'].append(itm.text()) # call the accept slot of the base class super(EricapiConfigDialog, self).accept() eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericapi/EricapiExecDialog.ui0000644000175000017500000000553412060166053025463 0ustar piotrpiotr EricapiExecDialog 0 0 753 602 Ericapi true 0 3 Messages 0 3 <b>Ericapi Execution</b> <p>This shows the output of the Ericapi generator command.</p> 0 1 Errors 0 1 <b>Ericapi Execution</b> <p>This shows the errors of the Ericapi generator command.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource contents errors buttonBox eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericapi/EricapiConfigDialog.ui0000644000175000017500000002042412263301564026002 0ustar piotrpiotr EricapiConfigDialog 0 0 500 600 Ericapi Configuration true Enter an output filename <b>Output Filename</b><p>Enter the filename of the output file. A '%L' placeholder is replaced by the language of the API file.</p> Output File: Qt::NoFocus Press to open a file selection dialog 0 1 Languages Select the languages of the APIs to generate QAbstractItemView::ExtendedSelection Additional source extensions: Enter additional source extensions separated by a comma Qt::Horizontal QSizePolicy::Expanding 31 20 Select to recurse into subdirectories Recurse into subdirectories Select to include private classes, methods and functions in the API file Include private classes, methods and functions Base package name: Enter the name of the base package Exclude Files: Enter filename patterns of files to be excluded separated by a comma 0 2 Exclude Directories Enter a directory basename to be ignored Press to add the entered directory to the list Add Press to delete the selected directory from the list Delete List of directory basenames to be ignored Qt::NoFocus Press to open a directory selection dialog Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource outputFileEdit languagesList sourceExtEdit recursionCheckBox includePrivateCheckBox baseEdit excludeFilesEdit ignoreDirEdit addButton ignoreDirsList deleteButton buttonBox buttonBox accepted() EricapiConfigDialog accept() 41 477 41 497 buttonBox rejected() EricapiConfigDialog reject() 113 480 113 501 eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericapi/__init__.py0000644000175000017500000000022312451233371023724 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the Ericapi plugin. """ eric-6.0.8/eric/Plugins/DocumentationPlugins/Ericapi/EricapiExecDialog.py0000644000175000017500000001274312451233371025500 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the ericapi process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os.path from PyQt5.QtCore import QProcess, QTimer from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5MessageBox from .Ui_EricapiExecDialog import Ui_EricapiExecDialog import Preferences class EricapiExecDialog(QDialog, Ui_EricapiExecDialog): """ Class implementing a dialog to show the output of the ericapi process. This class starts a QProcess and displays a dialog that shows the output of the documentation command process. """ def __init__(self, cmdname, parent=None): """ Constructor @param cmdname name of the ericapi generator (string) @param parent parent widget of this dialog (QWidget) """ super(EricapiExecDialog, self).__init__(parent) self.setModal(True) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = None self.cmdname = cmdname def start(self, args, fn): """ Public slot to start the ericapi command. @param args commandline arguments for ericapi program (list of strings) @param fn filename or dirname to be processed by ericapi program (string) @return flag indicating the successful start of the process (boolean) """ self.errorGroup.hide() self.filename = fn if os.path.isdir(self.filename): dname = os.path.abspath(self.filename) fname = "." if os.path.exists(os.path.join(dname, "__init__.py")): fname = os.path.basename(dname) dname = os.path.dirname(dname) else: dname = os.path.dirname(self.filename) fname = os.path.basename(self.filename) self.contents.clear() self.errors.clear() program = args[0] del args[0] args.append(fname) self.process = QProcess() self.process.setWorkingDirectory(dname) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.process.finished.connect(self.__finish) self.setWindowTitle( self.tr('{0} - {1}').format(self.cmdname, self.filename)) self.process.start(program, args) procStarted = self.process.waitForStarted(5000) if not procStarted: E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format(program)) return procStarted def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.accept() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __finish(self): """ Private slot called when the process finished. It is called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.process = None self.contents.insertPlainText( self.tr('\n{0} finished.\n').format(self.cmdname)) self.contents.ensureCursorVisible() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.contents.insertPlainText(s) self.contents.ensureCursorVisible() def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ self.process.setReadChannel(QProcess.StandardError) while self.process.canReadLine(): self.errorGroup.show() s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() eric-6.0.8/eric/Plugins/PluginWizardQFontDialog.py0000644000175000017500000001007612451233371021154 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the QFontDialog wizard plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "QFontDialog Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "FontDialogWizard" packageName = "__core__" shortDescription = "Show the QFontDialog wizard." longDescription = """This plugin shows the QFontDialog wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class FontDialogWizard(QObject): """ Class implementing the QFontDialog wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(FontDialogWizard, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('QFontDialog Wizard'), self.tr('Q&FontDialog Wizard...'), 0, 0, self, 'wizards_qfontdialog') self.action.setStatusTip(self.tr('QFontDialog Wizard')) self.action.setWhatsThis(self.tr( """QFontDialog Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create a QFontDialog. The generated code is""" """ inserted at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) """ from WizardPlugins.FontDialogWizard.FontDialogWizardDialog import \ FontDialogWizardDialog dlg = FontDialogWizardDialog(None) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), True) else: return (None, False) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/PluginSyntaxChecker.py0000644000175000017500000003454212451233371020403 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Syntax Checker plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject from E5Gui.E5Action import E5Action from E5Gui.E5Application import e5App from eric6config import getConfig from Project.ProjectBrowserModel import ProjectBrowserFileItem import Preferences # Start-Of-Header name = "Syntax Checker Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "SyntaxCheckerPlugin" packageName = "__core__" shortDescription = "Show the Syntax Checker dialog." longDescription = """This plugin implements the Syntax Checker dialog.""" \ """ Syntax Checker is used to check Python source files for correct""" \ """ syntax.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class SyntaxCheckerPlugin(QObject): """ Class implementing the Syntax Checker plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(SyntaxCheckerPlugin, self).__init__(ui) self.__ui = ui self.__initialize() from Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckService import \ SyntaxCheckService self.syntaxCheckService = SyntaxCheckService() e5App().registerObject("SyntaxCheckService", self.syntaxCheckService) ericPath = getConfig('ericDir') path = os.path.join(ericPath, 'Plugins', 'CheckerPlugins', 'SyntaxChecker') self.syntaxCheckService.addLanguage( 'Python2', 'Python2', path, 'SyntaxCheck', self.__getPythonOptions, lambda: Preferences.getPython("PythonExtensions"), self.__translateSyntaxCheck, self.serviceErrorPy2) self.syntaxCheckService.addLanguage( 'Python3', 'Python3', path, 'SyntaxCheck', self.__getPythonOptions, lambda: Preferences.getPython("Python3Extensions"), self.__translateSyntaxCheck, self.serviceErrorPy3) # Jasy isn't yet compatible to Python2 self.syntaxCheckService.addLanguage( 'JavaScript', 'Python3', path, 'jsCheckSyntax', lambda: [], # No options lambda: ['.js'], lambda fn, problems: self.syntaxCheckService.syntaxChecked.emit(fn, problems), # __IGNORE_WARNING__ self.serviceErrorJavaScript) def __serviceError(self, fn, msg): """ Private slot handling service errors. @param fn file name (string) @param msg message text (string) """ self.syntaxCheckService.syntaxChecked.emit( fn, {'warnings': [(fn, 1, 0, '', msg)]}) def serviceErrorPy2(self, fx, lang, fn, msg): """ Public method handling service errors for Python 2. @param fx service name (string) @param lang language (string) @param fn file name (string) @param msg message text (string) """ if fx == 'Python2Syntax': self.__serviceError(fn, msg) def serviceErrorPy3(self, fx, lang, fn, msg): """ Public method handling service errors for Python 2. @param fx service name (string) @param lang language (string) @param fn file name (string) @param msg message text (string) """ if fx == 'Python3Syntax': self.__serviceError(fn, msg) def serviceErrorJavaScript(self, fx, lang, fn, msg): """ Public method handling service errors for JavaScript. @param fx service name (string) @param lang language (string) @param fn file name (string) @param msg message text (string) """ if fx == 'JavaScriptSyntax': self.__serviceError(fn, msg) def __initialize(self): """ Private slot to (re)initialize the plugin. """ self.__projectAct = None self.__projectSyntaxCheckerDialog = None self.__projectBrowserAct = None self.__projectBrowserMenu = None self.__projectBrowserSyntaxCheckerDialog = None self.__editors = [] self.__editorAct = None self.__editorSyntaxCheckerDialog = None def __getPythonOptions(self): """ Private methode to determine the syntax check options. @return state of checkFlakes and ignoreStarImportWarnings (bool, bool) """ checkFlakes = Preferences.getFlakes("IncludeInSyntaxCheck") ignoreStarImportWarnings = Preferences.getFlakes( "IgnoreStarImportWarnings") return checkFlakes, ignoreStarImportWarnings def __translateSyntaxCheck(self, fn, problems): """ Private slot to translate the resulting messages. If checkFlakes is True, warnings contains a list of strings containing the warnings (marker, file name, line number, message) The values are only valid, if nok is False. @param fn filename of the checked file (str) @param problems dictionary with the keys 'error' and 'warnings' which hold a list containing details about the error/ warnings (file name, line number, column, codestring (only at syntax errors), the message, a list with arguments for the message) """ from CheckerPlugins.SyntaxChecker.pyflakes.translations import \ getTranslatedFlakesMessage warnings = problems.get('warnings', []) for warning in warnings: # Translate messages msg_args = warning.pop() warning[4] = getTranslatedFlakesMessage(warning[4], msg_args) problems['warnings'] = warnings self.syntaxCheckService.syntaxChecked.emit(fn, problems) def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ menu = e5App().getObject("Project").getMenu("Checks") if menu: self.__projectAct = E5Action( self.tr('Check Syntax'), self.tr('&Syntax...'), 0, 0, self, 'project_check_syntax') self.__projectAct.setStatusTip( self.tr('Check syntax.')) self.__projectAct.setWhatsThis(self.tr( """Check Syntax...""" """

This checks Python files for syntax errors.

""" )) self.__projectAct.triggered.connect(self.__projectSyntaxCheck) e5App().getObject("Project").addE5Actions([self.__projectAct]) menu.addAction(self.__projectAct) self.__editorAct = E5Action( self.tr('Check Syntax'), self.tr('&Syntax...'), 0, 0, self, "") self.__editorAct.setWhatsThis(self.tr( """Check Syntax...""" """

This checks Python files for syntax errors.

""" )) self.__editorAct.triggered.connect(self.__editorSyntaxCheck) e5App().getObject("Project").showMenu.connect(self.__projectShowMenu) e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\ .showMenu.connect(self.__projectBrowserShowMenu) e5App().getObject("ViewManager").editorOpenedEd.connect( self.__editorOpened) e5App().getObject("ViewManager").editorClosedEd.connect( self.__editorClosed) for editor in e5App().getObject("ViewManager").getOpenEditors(): self.__editorOpened(editor) return None, True def deactivate(self): """ Public method to deactivate this plugin. """ e5App().getObject("Project").showMenu.disconnect( self.__projectShowMenu) e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\ .showMenu.disconnect(self.__projectBrowserShowMenu) e5App().getObject("ViewManager").editorOpenedEd.disconnect( self.__editorOpened) e5App().getObject("ViewManager").editorClosedEd.disconnect( self.__editorClosed) menu = e5App().getObject("Project").getMenu("Checks") if menu: menu.removeAction(self.__projectAct) if self.__projectBrowserMenu: if self.__projectBrowserAct: self.__projectBrowserMenu.removeAction( self.__projectBrowserAct) for editor in self.__editors: editor.showMenu.disconnect(self.__editorShowMenu) menu = editor.getMenu("Checks") if menu is not None: menu.removeAction(self.__editorAct) self.__initialize() def __projectShowMenu(self, menuName, menu): """ Private slot called, when the the project menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) """ if menuName == "Checks" and self.__projectAct is not None: self.__projectAct.setEnabled( e5App().getObject("Project").getProjectLanguage() in self.syntaxCheckService.getLanguages()) def __projectBrowserShowMenu(self, menuName, menu): """ Private slot called, when the the project browser menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) """ if menuName == "Checks" and \ e5App().getObject("Project").getProjectLanguage() in \ self.syntaxCheckService.getLanguages(): self.__projectBrowserMenu = menu if self.__projectBrowserAct is None: self.__projectBrowserAct = E5Action( self.tr('Check Syntax'), self.tr('&Syntax...'), 0, 0, self, "") self.__projectBrowserAct.setWhatsThis(self.tr( """Check Syntax...""" """

This checks Python files for syntax errors.

""" )) self.__projectBrowserAct.triggered.connect( self.__projectBrowserSyntaxCheck) if self.__projectBrowserAct not in menu.actions(): menu.addAction(self.__projectBrowserAct) def __projectSyntaxCheck(self): """ Private slot used to check the project files for syntax errors. """ project = e5App().getObject("Project") project.saveAllScripts() ppath = project.getProjectPath() extensions = tuple(self.syntaxCheckService.getExtensions()) files = [os.path.join(ppath, file) for file in project.pdata["SOURCES"] if file.endswith(extensions)] from CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog import \ SyntaxCheckerDialog self.__projectSyntaxCheckerDialog = SyntaxCheckerDialog() self.__projectSyntaxCheckerDialog.show() self.__projectSyntaxCheckerDialog.prepare(files, project) def __projectBrowserSyntaxCheck(self): """ Private method to handle the syntax check context menu action of the project sources browser. """ browser = e5App().getObject("ProjectBrowser").getProjectBrowser( "sources") if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1: fn = [] for itm in browser.getSelectedItems([ProjectBrowserFileItem]): fn.append(itm.fileName()) else: itm = browser.model().item(browser.currentIndex()) try: fn = itm.fileName() except AttributeError: fn = itm.dirName() from CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog import \ SyntaxCheckerDialog self.__projectBrowserSyntaxCheckerDialog = SyntaxCheckerDialog() self.__projectBrowserSyntaxCheckerDialog.show() self.__projectBrowserSyntaxCheckerDialog.start(fn) def __editorOpened(self, editor): """ Private slot called, when a new editor was opened. @param editor reference to the new editor (QScintilla.Editor) """ menu = editor.getMenu("Checks") if menu is not None: menu.addAction(self.__editorAct) editor.showMenu.connect(self.__editorShowMenu) self.__editors.append(editor) def __editorClosed(self, editor): """ Private slot called, when an editor was closed. @param editor reference to the editor (QScintilla.Editor) """ try: self.__editors.remove(editor) except ValueError: pass def __editorShowMenu(self, menuName, menu, editor): """ Private slot called, when the the editor context menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) @param editor reference to the editor """ if menuName == "Checks": if self.__editorAct not in menu.actions(): menu.addAction(self.__editorAct) self.__editorAct.setEnabled( editor.getLanguage() in self.syntaxCheckService.getLanguages()) def __editorSyntaxCheck(self): """ Private slot to handle the syntax check context menu action of the editors. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is not None: from CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog import \ SyntaxCheckerDialog self.__editorSyntaxCheckerDialog = SyntaxCheckerDialog() self.__editorSyntaxCheckerDialog.show() if editor.isJavascriptFile(): unnamed = "Unnamed.js" else: unnamed = "Unnamed.py" self.__editorSyntaxCheckerDialog.start( editor.getFileName() or unnamed, editor.text()) eric-6.0.8/eric/Plugins/PluginWizardQInputDialog.py0000644000175000017500000001012012451233371021333 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the QInputDialog wizard plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "QInputDialog Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "InputDialogWizard" packageName = "__core__" shortDescription = "Show the QInputDialog wizard." longDescription = """This plugin shows the QInputDialog wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class InputDialogWizard(QObject): """ Class implementing the QInputDialog wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(InputDialogWizard, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('QInputDialog Wizard'), self.tr('Q&InputDialog Wizard...'), 0, 0, self, 'wizards_qinputdialog') self.action.setStatusTip(self.tr('QInputDialog Wizard')) self.action.setWhatsThis(self.tr( """QInputDialog Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create a QInputDialog. The generated code is""" """ inserted at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) """ from WizardPlugins.InputDialogWizard.InputDialogWizardDialog import \ InputDialogWizardDialog dlg = InputDialogWizardDialog(None) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), True) else: return (None, False) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/PluginVmListspace.py0000644000175000017500000000366612451233371020065 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Tabview view manager plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QT_TRANSLATE_NOOP, QObject from PyQt5.QtGui import QPixmap # Start-Of-Header name = "Listspace Plugin" author = "Detlev Offenbach " autoactivate = False deactivateable = False version = "6.0.0" pluginType = "viewmanager" pluginTypename = "listspace" displayString = QT_TRANSLATE_NOOP('VmListspacePlugin', 'Listspace') className = "VmListspacePlugin" packageName = "__core__" shortDescription = "Implements the Listspace view manager." longDescription = """This plugin provides the listspace view manager.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" def previewPix(): """ Module function to return a preview pixmap. @return preview pixmap (QPixmap) """ fname = os.path.join(os.path.dirname(__file__), "ViewManagerPlugins", "Listspace", "preview.png") return QPixmap(fname) class VmListspacePlugin(QObject): """ Class implementing the Listspace view manager plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(VmListspacePlugin, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of reference to instantiated viewmanager and activation status (boolean) """ from ViewManagerPlugins.Listspace.Listspace import Listspace self.__object = Listspace(self.__ui) return self.__object, True def deactivate(self): """ Public method to deactivate this plugin. """ # do nothing for the moment pass eric-6.0.8/eric/Plugins/PluginAbout.py0000644000175000017500000000761412451233371016702 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the About plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QAction import UI.Info import UI.PixmapCache from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "About Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "AboutPlugin" packageName = "__core__" shortDescription = "Show the About dialogs." longDescription = """This plugin shows the About dialogs.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class AboutPlugin(QObject): """ Class implementing the About plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(AboutPlugin, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initActions() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("help") if menu: menu.removeAction(self.aboutAct) menu.removeAction(self.aboutQtAct) acts = [self.aboutAct, self.aboutQtAct] self.__ui.removeE5Actions(acts, 'ui') def __initActions(self): """ Private method to initialize the actions. """ acts = [] self.aboutAct = E5Action( self.tr('About {0}').format(UI.Info.Program), UI.PixmapCache.getIcon("helpAbout.png"), self.tr('&About {0}').format(UI.Info.Program), 0, 0, self, 'about_eric') self.aboutAct.setStatusTip(self.tr( 'Display information about this software')) self.aboutAct.setWhatsThis(self.tr( """About {0}""" """

Display some information about this software.

""" ).format(UI.Info.Program)) self.aboutAct.triggered.connect(self.__about) self.aboutAct.setMenuRole(QAction.AboutRole) acts.append(self.aboutAct) self.aboutQtAct = E5Action( self.tr('About Qt'), UI.PixmapCache.getIcon("helpAboutQt.png"), self.tr('About &Qt'), 0, 0, self, 'about_qt') self.aboutQtAct.setStatusTip( self.tr('Display information about the Qt toolkit')) self.aboutQtAct.setWhatsThis(self.tr( """About Qt""" """

Display some information about the Qt toolkit.

""" )) self.aboutQtAct.triggered.connect(self.__aboutQt) self.aboutQtAct.setMenuRole(QAction.AboutQtRole) acts.append(self.aboutQtAct) self.__ui.addE5Actions(acts, 'ui') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("help") if menu: act = self.__ui.getMenuAction("help", "show_versions") if act: menu.insertAction(act, self.aboutAct) menu.insertAction(act, self.aboutQtAct) else: menu.addAction(self.aboutAct) menu.addAction(self.aboutQtAct) def __about(self): """ Private slot to handle the About dialog. """ from AboutPlugin.AboutDialog import AboutDialog dlg = AboutDialog(self.__ui) dlg.exec_() def __aboutQt(self): """ Private slot to handle the About Qt dialog. """ E5MessageBox.aboutQt(self.__ui, UI.Info.Program) eric-6.0.8/eric/Plugins/PluginWizardQColorDialog.py0000644000175000017500000001015512451233371021322 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the QColorDialog wizard plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "QColorDialog Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "ColorDialogWizard" packageName = "__core__" shortDescription = "Show the QColorDialog wizard." longDescription = """This plugin shows the QColorDialog wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class ColorDialogWizard(QObject): """ Class implementing the QColorDialog wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(ColorDialogWizard, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('QColorDialog Wizard'), self.tr('Q&ColorDialog Wizard...'), 0, 0, self, 'wizards_qcolordialog') self.action.setStatusTip(self.tr('QColorDialog Wizard')) self.action.setWhatsThis(self.tr( """QColorDialog Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create a QColorDialog. The generated code is""" """ inserted at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) and a success flag (boolean) """ from WizardPlugins.ColorDialogWizard.ColorDialogWizardDialog import \ ColorDialogWizardDialog dlg = ColorDialogWizardDialog(None) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), True) else: return (None, False) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/ViewManagerPlugins/0000755000175000017500000000000012557365360017651 5ustar piotrpiotreric-6.0.8/eric/Plugins/ViewManagerPlugins/Tabview/0000755000175000017500000000000012557365360021252 5ustar piotrpiotreric-6.0.8/eric/Plugins/ViewManagerPlugins/Tabview/Tabview.py0000644000175000017500000013453212557123354023230 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a tabbed viewmanager class. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QPoint, QFileInfo, pyqtSignal, QEvent, QByteArray, \ QMimeData, Qt, QSize from PyQt5.QtGui import QColor, QDrag, QPixmap from PyQt5.QtWidgets import QWidget, QHBoxLayout, QSplitter, QTabBar, \ QApplication, QToolButton, QMenu, QLabel from E5Gui.E5Application import e5App from ViewManager.ViewManager import ViewManager import QScintilla.Editor from QScintilla.Editor import Editor import UI.PixmapCache from E5Gui.E5TabWidget import E5TabWidget, E5WheelTabBar from E5Gui.E5Led import E5Led import Preferences from Globals import isMacPlatform from eric6config import getConfig class TabBar(E5WheelTabBar): """ Class implementing a customized tab bar supporting drag & drop. @signal tabMoveRequested(int, int) emitted to signal a tab move request giving the old and new index position @signal tabRelocateRequested(str, int, int) emitted to signal a tab relocation request giving the string encoded id of the old tab widget, the index in the old tab widget and the new index position @signal tabCopyRequested(str, int, int) emitted to signal a clone request giving the string encoded id of the source tab widget, the index in the source tab widget and the new index position @signal tabCopyRequested(int, int) emitted to signal a clone request giving the old and new index position """ tabMoveRequested = pyqtSignal(int, int) tabRelocateRequested = pyqtSignal(str, int, int) tabCopyRequested = pyqtSignal((str, int, int), (int, int)) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(TabBar, self).__init__(parent) self.setAcceptDrops(True) self.__dragStartPos = QPoint() def mousePressEvent(self, event): """ Protected method to handle mouse press events. @param event reference to the mouse press event (QMouseEvent) """ if event.button() == Qt.LeftButton: self.__dragStartPos = QPoint(event.pos()) super(TabBar, self).mousePressEvent(event) def mouseMoveEvent(self, event): """ Protected method to handle mouse move events. @param event reference to the mouse move event (QMouseEvent) """ if event.buttons() == Qt.MouseButtons(Qt.LeftButton) and \ (event.pos() - self.__dragStartPos).manhattanLength() > \ QApplication.startDragDistance(): drag = QDrag(self) mimeData = QMimeData() index = self.tabAt(event.pos()) mimeData.setText(self.tabText(index)) mimeData.setData("action", b"tab-reordering") mimeData.setData("tabbar-id", str(id(self)).encode("utf-8")) mimeData.setData( "source-index", QByteArray.number(self.tabAt(self.__dragStartPos))) mimeData.setData( "tabwidget-id", str(id(self.parentWidget())).encode("utf-8")) drag.setMimeData(mimeData) if event.modifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier): drag.exec_(Qt.DropActions(Qt.CopyAction)) elif event.modifiers() == Qt.KeyboardModifiers(Qt.NoModifier): drag.exec_(Qt.DropActions(Qt.MoveAction)) super(TabBar, self).mouseMoveEvent(event) def dragEnterEvent(self, event): """ Protected method to handle drag enter events. @param event reference to the drag enter event (QDragEnterEvent) """ mimeData = event.mimeData() formats = mimeData.formats() if "action" in formats and \ mimeData.data("action") == b"tab-reordering" and \ "tabbar-id" in formats and \ "source-index" in formats and \ "tabwidget-id" in formats: event.acceptProposedAction() super(TabBar, self).dragEnterEvent(event) def dropEvent(self, event): """ Protected method to handle drop events. @param event reference to the drop event (QDropEvent) """ mimeData = event.mimeData() oldID = int(mimeData.data("tabbar-id")) fromIndex = int(mimeData.data("source-index")) toIndex = self.tabAt(event.pos()) if oldID != id(self): parentID = int(mimeData.data("tabwidget-id")) if event.proposedAction() == Qt.MoveAction: self.tabRelocateRequested.emit( str(parentID), fromIndex, toIndex) event.acceptProposedAction() elif event.proposedAction() == Qt.CopyAction: self.tabCopyRequested[str, int, int].emit( str(parentID), fromIndex, toIndex) event.acceptProposedAction() else: if fromIndex != toIndex: if event.proposedAction() == Qt.MoveAction: self.tabMoveRequested.emit(fromIndex, toIndex) event.acceptProposedAction() elif event.proposedAction() == Qt.CopyAction: self.tabCopyRequested[int, int].emit(fromIndex, toIndex) event.acceptProposedAction() super(TabBar, self).dropEvent(event) class TabWidget(E5TabWidget): """ Class implementing a custimized tab widget. """ def __init__(self, vm): """ Constructor @param vm view manager widget (Tabview) """ super(TabWidget, self).__init__() self.__tabBar = TabBar(self) self.setTabBar(self.__tabBar) iconSize = self.__tabBar.iconSize() self.__tabBar.setIconSize( QSize(2 * iconSize.width(), iconSize.height())) self.setUsesScrollButtons(True) self.setElideMode(Qt.ElideNone) if isMacPlatform(): self.setDocumentMode(True) self.__tabBar.tabMoveRequested.connect(self.moveTab) self.__tabBar.tabRelocateRequested.connect(self.__relocateTab) self.__tabBar.tabCopyRequested[str, int, int].connect( self.__copyTabOther) self.__tabBar.tabCopyRequested[int, int].connect(self.__copyTab) self.vm = vm self.editors = [] self.indicator = E5Led(self) self.setCornerWidget(self.indicator, Qt.TopLeftCorner) self.rightCornerWidget = QWidget(self) self.rightCornerWidgetLayout = QHBoxLayout(self.rightCornerWidget) self.rightCornerWidgetLayout.setContentsMargins(0, 0, 0, 0) self.rightCornerWidgetLayout.setSpacing(0) self.__navigationMenu = QMenu(self) self.__navigationMenu.aboutToShow.connect(self.__showNavigationMenu) self.__navigationMenu.triggered.connect(self.__navigationMenuTriggered) self.navigationButton = QToolButton(self) self.navigationButton.setIcon(UI.PixmapCache.getIcon("1downarrow.png")) self.navigationButton.setToolTip(self.tr("Show a navigation menu")) self.navigationButton.setPopupMode(QToolButton.InstantPopup) self.navigationButton.setMenu(self.__navigationMenu) self.navigationButton.setEnabled(False) self.rightCornerWidgetLayout.addWidget(self.navigationButton) if Preferences.getUI("SingleCloseButton") or \ not hasattr(self, 'setTabsClosable'): self.closeButton = QToolButton(self) self.closeButton.setIcon(UI.PixmapCache.getIcon("close.png")) self.closeButton.setToolTip( self.tr("Close the current editor")) self.closeButton.setEnabled(False) self.closeButton.clicked[bool].connect(self.__closeButtonClicked) self.rightCornerWidgetLayout.addWidget(self.closeButton) else: self.tabCloseRequested.connect(self.__closeRequested) self.closeButton = None self.setCornerWidget(self.rightCornerWidget, Qt.TopRightCorner) self.__initMenu() self.contextMenuEditor = None self.contextMenuIndex = -1 self.setTabContextMenuPolicy(Qt.CustomContextMenu) self.customTabContextMenuRequested.connect(self.__showContextMenu) ericPic = QPixmap( os.path.join(getConfig('ericPixDir'), 'eric_small.png')) self.emptyLabel = QLabel() self.emptyLabel.setPixmap(ericPic) self.emptyLabel.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) super(TabWidget, self).addTab( self.emptyLabel, UI.PixmapCache.getIcon("empty.png"), "") def __initMenu(self): """ Private method to initialize the tab context menu. """ self.__menu = QMenu(self) self.leftMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("1leftarrow.png"), self.tr('Move Left'), self.__contextMenuMoveLeft) self.rightMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("1rightarrow.png"), self.tr('Move Right'), self.__contextMenuMoveRight) self.firstMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("2leftarrow.png"), self.tr('Move First'), self.__contextMenuMoveFirst) self.lastMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("2rightarrow.png"), self.tr('Move Last'), self.__contextMenuMoveLast) self.__menu.addSeparator() self.__menu.addAction( UI.PixmapCache.getIcon("tabClose.png"), self.tr('Close'), self.__contextMenuClose) self.closeOthersMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("tabCloseOther.png"), self.tr("Close Others"), self.__contextMenuCloseOthers) self.__menu.addAction( self.tr('Close All'), self.__contextMenuCloseAll) self.__menu.addSeparator() self.saveMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("fileSave.png"), self.tr('Save'), self.__contextMenuSave) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAs.png"), self.tr('Save As...'), self.__contextMenuSaveAs) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAll.png"), self.tr('Save All'), self.__contextMenuSaveAll) self.__menu.addSeparator() self.openRejectionsMenuAct = self.__menu.addAction( self.tr("Open 'rejection' file"), self.__contextMenuOpenRejections) self.__menu.addSeparator() self.__menu.addAction( UI.PixmapCache.getIcon("print.png"), self.tr('Print'), self.__contextMenuPrintFile) self.__menu.addSeparator() self.copyPathAct = self.__menu.addAction( self.tr("Copy Path to Clipboard"), self.__contextMenuCopyPathToClipboard) def __showContextMenu(self, coord, index): """ Private slot to show the tab context menu. @param coord the position of the mouse pointer (QPoint) @param index index of the tab the menu is requested for (integer) """ if self.editors: self.contextMenuEditor = self.widget(index).getEditor() if self.contextMenuEditor: self.saveMenuAct.setEnabled( self.contextMenuEditor.isModified()) fileName = self.contextMenuEditor.getFileName() self.copyPathAct.setEnabled(bool(fileName)) if fileName: rej = "{0}.rej".format(fileName) self.openRejectionsMenuAct.setEnabled(os.path.exists(rej)) else: self.openRejectionsMenuAct.setEnabled(False) self.contextMenuIndex = index self.leftMenuAct.setEnabled(index > 0) self.rightMenuAct.setEnabled(index < self.count() - 1) self.firstMenuAct.setEnabled(index > 0) self.lastMenuAct.setEnabled(index < self.count() - 1) self.closeOthersMenuAct.setEnabled(self.count() > 1) coord = self.mapToGlobal(coord) self.__menu.popup(coord) def __showNavigationMenu(self): """ Private slot to show the navigation button menu. """ self.__navigationMenu.clear() for index in range(self.count()): act = self.__navigationMenu.addAction(self.tabIcon(index), self.tabText(index)) act.setData(index) def __navigationMenuTriggered(self, act): """ Private slot called to handle the navigation button menu selection. @param act reference to the selected action (QAction) """ index = act.data() if index is not None: self.setCurrentIndex(index) def showIndicator(self, on): """ Public slot to set the indicator on or off. @param on flag indicating the dtate of the indicator (boolean) """ if on: self.indicator.setColor(QColor("green")) else: self.indicator.setColor(QColor("red")) def addTab(self, assembly, title): """ Public method to add a new tab. @param assembly editor assembly object to be added (QScintilla.EditorAssembly.EditorAssembly) @param title title for the new tab (string) """ editor = assembly.getEditor() super(TabWidget, self).addTab( assembly, UI.PixmapCache.getIcon("empty.png"), title) if self.closeButton: self.closeButton.setEnabled(True) else: self.setTabsClosable(True) self.navigationButton.setEnabled(True) if editor not in self.editors: self.editors.append(editor) editor.captionChanged.connect(self.__captionChange) editor.cursorLineChanged.connect(self.__cursorLineChanged) emptyIndex = self.indexOf(self.emptyLabel) if emptyIndex > -1: self.removeTab(emptyIndex) def insertWidget(self, index, assembly, title): """ Public method to insert a new tab. @param index index position for the new tab (integer) @param assembly editor assembly object to be added (QScintilla.EditorAssembly.EditorAssembly) @param title title for the new tab (string) @return index of the inserted tab (integer) """ editor = assembly.getEditor() newIndex = super(TabWidget, self).insertTab( index, assembly, UI.PixmapCache.getIcon("empty.png"), title) if self.closeButton: self.closeButton.setEnabled(True) else: self.setTabsClosable(True) self.navigationButton.setEnabled(True) if editor not in self.editors: self.editors.append(editor) editor.captionChanged.connect(self.__captionChange) editor.cursorLineChanged.connect(self.__cursorLineChanged) emptyIndex = self.indexOf(self.emptyLabel) if emptyIndex > -1: self.removeTab(emptyIndex) return newIndex def __captionChange(self, cap, editor): """ Private slot to handle Caption change signals from the editor. Updates the tab text and tooltip text to reflect the new caption information. @param cap Caption for the editor @param editor Editor to update the caption for """ fn = editor.getFileName() if fn: if Preferences.getUI("TabViewManagerFilenameOnly"): txt = os.path.basename(fn) else: txt = e5App().getObject("Project").getRelativePath(fn) maxFileNameChars = Preferences.getUI( "TabViewManagerFilenameLength") if len(txt) > maxFileNameChars: txt = "...{0}".format(txt[-maxFileNameChars:]) if editor.isReadOnly(): txt = self.tr("{0} (ro)").format(txt) assembly = editor.parent() index = self.indexOf(assembly) if index > -1: self.setTabText(index, txt) self.setTabToolTip(index, fn) def __cursorLineChanged(self, lineno): """ Private slot to handle a change of the current editor's cursor line. @param lineno line number of the current editor's cursor (zero based) """ editor = self.sender() if editor and isinstance(editor, QScintilla.Editor.Editor): fn = editor.getFileName() if fn: self.vm.editorLineChanged.emit(fn, lineno + 1) def removeWidget(self, object): """ Public method to remove a widget. @param object object to be removed (QWidget) """ if isinstance(object, QScintilla.Editor.Editor): object.cursorLineChanged.disconnect(self.__cursorLineChanged) object.captionChanged.disconnect(self.__captionChange) self.editors.remove(object) index = self.indexOf(object.parent()) else: index = self.indexOf(object) if index > -1: self.removeTab(index) if not self.editors: super(TabWidget, self).addTab( self.emptyLabel, UI.PixmapCache.getIcon("empty.png"), "") self.emptyLabel.show() if self.closeButton: self.closeButton.setEnabled(False) else: self.setTabsClosable(False) self.navigationButton.setEnabled(False) def __relocateTab(self, sourceId, sourceIndex, targetIndex): """ Private method to relocate an editor from another TabWidget. @param sourceId id of the TabWidget to get the editor from (string) @param sourceIndex index of the tab in the old tab widget (integer) @param targetIndex index position to place it to (integer) """ tw = self.vm.getTabWidgetById(int(sourceId)) if tw is not None: # step 1: get data of the tab of the source toolTip = tw.tabToolTip(sourceIndex) text = tw.tabText(sourceIndex) icon = tw.tabIcon(sourceIndex) whatsThis = tw.tabWhatsThis(sourceIndex) assembly = tw.widget(sourceIndex) # step 2: relocate the tab tw.removeWidget(assembly.getEditor()) self.insertWidget(targetIndex, assembly, text) # step 3: set the tab data again self.setTabIcon(targetIndex, icon) self.setTabToolTip(targetIndex, toolTip) self.setTabWhatsThis(targetIndex, whatsThis) # step 4: set current widget self.setCurrentIndex(targetIndex) def __copyTabOther(self, sourceId, sourceIndex, targetIndex): """ Private method to copy an editor from another TabWidget. @param sourceId id of the TabWidget to get the editor from (string) @param sourceIndex index of the tab in the old tab widget (integer) @param targetIndex index position to place it to (integer) """ tw = self.vm.getTabWidgetById(int(sourceId)) if tw is not None: editor = tw.widget(sourceIndex).getEditor() newEditor, assembly = self.vm.cloneEditor( editor, editor.getFileType(), editor.getFileName()) self.vm.insertView(assembly, self, targetIndex, editor.getFileName(), editor.getNoName()) def __copyTab(self, sourceIndex, targetIndex): """ Private method to copy an editor. @param sourceIndex index of the tab (integer) @param targetIndex index position to place it to (integer) """ editor = self.widget(sourceIndex).getEditor() newEditor, assembly = self.vm.cloneEditor( editor, editor.getFileType(), editor.getFileName()) self.vm.insertView(assembly, self, targetIndex, editor.getFileName(), editor.getNoName()) def currentWidget(self): """ Public method to return a reference to the current page. @return reference to the current page (Editor) """ if not self.editors: return None else: return super(TabWidget, self).currentWidget() def setCurrentWidget(self, assembly): """ Public method to set the current tab by the given editor assembly. @param assembly editor assembly to determine current tab from (EditorAssembly.EditorAssembly) """ super(TabWidget, self).setCurrentWidget(assembly) def indexOf(self, object): """ Public method to get the tab index of the given editor. @param object object to get the index for (QLabel or Editor) @return tab index of the editor (integer) """ if isinstance(object, QScintilla.Editor.Editor): object = object.parent() return super(TabWidget, self).indexOf(object) def hasEditor(self, editor): """ Public method to check for an editor. @param editor editor object to check for @return flag indicating, whether the editor to be checked belongs to the list of editors managed by this tab widget. """ return editor in self.editors def hasEditors(self): """ Public method to test, if any editor is managed. @return flag indicating editors are managed """ return len(self.editors) > 0 def __contextMenuClose(self): """ Private method to close the selected tab. """ if self.contextMenuEditor: self.vm.closeEditorWindow(self.contextMenuEditor) def __contextMenuCloseOthers(self): """ Private method to close the other tabs. """ index = self.contextMenuIndex for i in list(range(self.count() - 1, index, -1)) + \ list(range(index - 1, -1, -1)): editor = self.widget(i).getEditor() self.vm.closeEditorWindow(editor) def __contextMenuCloseAll(self): """ Private method to close all tabs. """ savedEditors = self.editors[:] for editor in savedEditors: self.vm.closeEditorWindow(editor) def __contextMenuSave(self): """ Private method to save the selected tab. """ if self.contextMenuEditor: self.vm.saveEditorEd(self.contextMenuEditor) def __contextMenuSaveAs(self): """ Private method to save the selected tab to a new file. """ if self.contextMenuEditor: self.vm.saveAsEditorEd(self.contextMenuEditor) def __contextMenuSaveAll(self): """ Private method to save all tabs. """ self.vm.saveEditorsList(self.editors) def __contextMenuOpenRejections(self): """ Private slot to open a rejections file associated with the selected tab. """ if self.contextMenuEditor: fileName = self.contextMenuEditor.getFileName() if fileName: rej = "{0}.rej".format(fileName) if os.path.exists(rej): self.vm.openSourceFile(rej) def __contextMenuPrintFile(self): """ Private method to print the selected tab. """ if self.contextMenuEditor: self.vm.printEditor(self.contextMenuEditor) def __contextMenuCopyPathToClipboard(self): """ Private method to copy the file name of the selected tab to the clipboard. """ if self.contextMenuEditor: fn = self.contextMenuEditor.getFileName() if fn: cb = QApplication.clipboard() cb.setText(fn) def __contextMenuMoveLeft(self): """ Private method to move a tab one position to the left. """ self.moveTab(self.contextMenuIndex, self.contextMenuIndex - 1) def __contextMenuMoveRight(self): """ Private method to move a tab one position to the right. """ self.moveTab(self.contextMenuIndex, self.contextMenuIndex + 1) def __contextMenuMoveFirst(self): """ Private method to move a tab to the first position. """ self.moveTab(self.contextMenuIndex, 0) def __contextMenuMoveLast(self): """ Private method to move a tab to the last position. """ self.moveTab(self.contextMenuIndex, self.count() - 1) def __closeButtonClicked(self): """ Private method to handle the press of the close button. """ self.vm.closeEditorWindow(self.currentWidget().getEditor()) def __closeRequested(self, index): """ Private method to handle the press of the individual tab close button. @param index index of the tab (integer) """ if index >= 0: self.vm.closeEditorWindow(self.widget(index).getEditor()) def mouseDoubleClickEvent(self, event): """ Protected method handling double click events. @param event reference to the event object (QMouseEvent) """ self.vm.newEditor() class Tabview(QSplitter, ViewManager): """ Class implementing a tabbed viewmanager class embedded in a splitter. @signal changeCaption(str) emitted if a change of the caption is necessary @signal editorChanged(str) emitted when the current editor has changed @signal editorChangedEd(Editor) emitted when the current editor has changed @signal lastEditorClosed() emitted after the last editor window was closed @signal editorOpened(str) emitted after an editor window was opened @signal editorOpenedEd(Editor) emitted after an editor window was opened @signal editorClosed(str) emitted just before an editor window gets closed @signal editorClosedEd(Editor) emitted just before an editor window gets closed @signal editorRenamed(str) emitted after an editor was renamed @signal editorRenamedEd(Editor) emitted after an editor was renamed @signal editorSaved(str) emitted after an editor window was saved @signal editorSavedEd(Editor) emitted after an editor window was saved @signal checkActions(Editor) emitted when some actions should be checked for their status @signal cursorChanged(Editor) emitted after the cursor position of the active window has changed @signal breakpointToggled(Editor) emitted when a breakpoint is toggled. @signal bookmarkToggled(Editor) emitted when a bookmark is toggled. @signal syntaxerrorToggled(Editor) emitted when a syntax error is toggled. @signal previewStateChanged(bool) emitted to signal a change in the preview state @signal editorLanguageChanged(Editor) emitted to signal a change of an editors language @signal editorTextChanged(Editor) emitted to signal a change of an editor's text @signal editorLineChanged(str,int) emitted to signal a change of an editor's current line (line is given one based) """ changeCaption = pyqtSignal(str) editorChanged = pyqtSignal(str) editorChangedEd = pyqtSignal(Editor) lastEditorClosed = pyqtSignal() editorOpened = pyqtSignal(str) editorOpenedEd = pyqtSignal(Editor) editorClosed = pyqtSignal(str) editorClosedEd = pyqtSignal(Editor) editorRenamed = pyqtSignal(str) editorRenamedEd = pyqtSignal(Editor) editorSaved = pyqtSignal(str) editorSavedEd = pyqtSignal(Editor) checkActions = pyqtSignal(Editor) cursorChanged = pyqtSignal(Editor) breakpointToggled = pyqtSignal(Editor) bookmarkToggled = pyqtSignal(Editor) syntaxerrorToggled = pyqtSignal(Editor) previewStateChanged = pyqtSignal(bool) editorLanguageChanged = pyqtSignal(Editor) editorTextChanged = pyqtSignal(Editor) editorLineChanged = pyqtSignal(str, int) def __init__(self, parent): """ Constructor @param parent parent widget (QWidget) """ self.tabWidgets = [] QSplitter.__init__(self, parent) ViewManager.__init__(self) tw = TabWidget(self) self.addWidget(tw) self.tabWidgets.append(tw) self.currentTabWidget = tw self.currentTabWidget.showIndicator(True) tw.currentChanged.connect(self.__currentChanged) tw.installEventFilter(self) tw.tabBar().installEventFilter(self) self.setOrientation(Qt.Vertical) self.__inRemoveView = False self.maxFileNameChars = Preferences.getUI( "TabViewManagerFilenameLength") self.filenameOnly = Preferences.getUI("TabViewManagerFilenameOnly") def canCascade(self): """ Public method to signal if cascading of managed windows is available. @return flag indicating cascading of windows is available """ return False def canTile(self): """ Public method to signal if tiling of managed windows is available. @return flag indicating tiling of windows is available """ return False def canSplit(self): """ public method to signal if splitting of the view is available. @return flag indicating splitting of the view is available. """ return True def tile(self): """ Public method to tile the managed windows. """ pass def cascade(self): """ Public method to cascade the managed windows. """ pass def _removeAllViews(self): """ Protected method to remove all views (i.e. windows). """ for win in self.editors: self._removeView(win) def _removeView(self, win): """ Protected method to remove a view (i.e. window). @param win editor window to be removed """ self.__inRemoveView = True for tw in self.tabWidgets: if tw.hasEditor(win): tw.removeWidget(win) break win.closeIt() self.__inRemoveView = False # if this was the last editor in this view, switch to the next, that # still has open editors for i in list(range(self.tabWidgets.index(tw), -1, -1)) + \ list(range(self.tabWidgets.index(tw) + 1, len(self.tabWidgets))): if self.tabWidgets[i].hasEditors(): self.currentTabWidget.showIndicator(False) self.currentTabWidget = self.tabWidgets[i] self.currentTabWidget.showIndicator(True) self.activeWindow().setFocus() break aw = self.activeWindow() fn = aw and aw.getFileName() or None if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) def _addView(self, win, fn=None, noName=""): """ Protected method to add a view (i.e. window). @param win editor assembly to be added @param fn filename of this editor (string) @param noName name to be used for an unnamed editor (string) """ editor = win.getEditor() if fn is None: if not noName: self.untitledCount += 1 noName = self.tr("Untitled {0}").format(self.untitledCount) self.currentTabWidget.addTab(win, noName) editor.setNoName(noName) else: if self.filenameOnly: txt = os.path.basename(fn) else: txt = e5App().getObject("Project").getRelativePath(fn) if len(txt) > self.maxFileNameChars: txt = "...{0}".format(txt[-self.maxFileNameChars:]) if not QFileInfo(fn).isWritable(): txt = self.tr("{0} (ro)").format(txt) self.currentTabWidget.addTab(win, txt) index = self.currentTabWidget.indexOf(win) self.currentTabWidget.setTabToolTip(index, fn) self.currentTabWidget.setCurrentWidget(win) win.show() editor.setFocus() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def insertView(self, win, tabWidget, index, fn=None, noName=""): """ Public method to add a view (i.e. window). @param win editor assembly to be inserted @param tabWidget reference to the tab widget to insert the editor into (TabWidget) @param index index position to insert at (integer) @param fn filename of this editor (string) @param noName name to be used for an unnamed editor (string) """ editor = win.getEditor() if fn is None: if not noName: self.untitledCount += 1 noName = self.tr("Untitled {0}").format(self.untitledCount) tabWidget.insertWidget(index, win, noName) editor.setNoName(noName) else: if self.filenameOnly: txt = os.path.basename(fn) else: txt = e5App().getObject("Project").getRelativePath(fn) if len(txt) > self.maxFileNameChars: txt = "...{0}".format(txt[-self.maxFileNameChars:]) if not QFileInfo(fn).isWritable(): txt = self.tr("{0} (ro)").format(txt) nindex = tabWidget.insertWidget(index, win, txt) tabWidget.setTabToolTip(nindex, fn) tabWidget.setCurrentWidget(win) win.show() editor.setFocus() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) self._modificationStatusChanged(editor.isModified(), editor) self._checkActions(editor) def _showView(self, win, fn=None): """ Protected method to show a view (i.e. window). @param win editor assembly to be shown @param fn filename of this editor (string) """ win.show() editor = win.getEditor() for tw in self.tabWidgets: if tw.hasEditor(editor): tw.setCurrentWidget(win) self.currentTabWidget.showIndicator(False) self.currentTabWidget = tw self.currentTabWidget.showIndicator(True) break editor.setFocus() def activeWindow(self): """ Public method to return the active (i.e. current) window. @return reference to the active editor """ cw = self.currentTabWidget.currentWidget() if cw: return cw.getEditor() else: return None def showWindowMenu(self, windowMenu): """ Public method to set up the viewmanager part of the Window menu. @param windowMenu reference to the window menu """ pass def _initWindowActions(self): """ Protected method to define the user interface actions for window handling. """ pass def setEditorName(self, editor, newName): """ Public method to change the displayed name of the editor. @param editor editor window to be changed @param newName new name to be shown (string) """ if newName: if self.filenameOnly: tabName = os.path.basename(newName) else: tabName = e5App().getObject("Project").getRelativePath(newName) if len(tabName) > self.maxFileNameChars: tabName = "...{0}".format(tabName[-self.maxFileNameChars:]) index = self.currentTabWidget.indexOf(editor) self.currentTabWidget.setTabText(index, tabName) self.currentTabWidget.setTabToolTip(index, newName) self.changeCaption.emit(newName) def _modificationStatusChanged(self, m, editor): """ Protected slot to handle the modificationStatusChanged signal. @param m flag indicating the modification status (boolean) @param editor editor window changed """ for tw in self.tabWidgets: if tw.hasEditor(editor): break index = tw.indexOf(editor) keys = [] if m: keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") tw.setTabIcon(index, UI.PixmapCache.getCombinedIcon(keys)) self._checkActions(editor) def _syntaxErrorToggled(self, editor): """ Protected slot to handle the syntaxerrorToggled signal. @param editor editor that sent the signal """ for tw in self.tabWidgets: if tw.hasEditor(editor): break index = tw.indexOf(editor) keys = [] if editor.isModified(): keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") tw.setTabIcon(index, UI.PixmapCache.getCombinedIcon(keys)) ViewManager._syntaxErrorToggled(self, editor) def addSplit(self): """ Public method used to split the current view. """ tw = TabWidget(self) tw.show() self.addWidget(tw) self.tabWidgets.append(tw) self.currentTabWidget.showIndicator(False) self.currentTabWidget = self.tabWidgets[-1] self.currentTabWidget.showIndicator(True) tw.currentChanged.connect(self.__currentChanged) tw.installEventFilter(self) tw.tabBar().installEventFilter(self) if self.orientation() == Qt.Horizontal: size = self.width() else: size = self.height() self.setSizes( [int(size / len(self.tabWidgets))] * len(self.tabWidgets)) self.splitRemoveAct.setEnabled(True) self.nextSplitAct.setEnabled(True) self.prevSplitAct.setEnabled(True) def removeSplit(self): """ Public method used to remove the current split view. @return flag indicating successfull removal """ if len(self.tabWidgets) > 1: tw = self.currentTabWidget res = True savedEditors = tw.editors[:] for editor in savedEditors: res &= self.closeEditor(editor) if res: try: i = self.tabWidgets.index(tw) except ValueError: return True if i == len(self.tabWidgets) - 1: i -= 1 self.tabWidgets.remove(tw) tw.close() self.currentTabWidget = self.tabWidgets[i] self.currentTabWidget.showIndicator(True) if len(self.tabWidgets) == 1: self.splitRemoveAct.setEnabled(False) self.nextSplitAct.setEnabled(False) self.prevSplitAct.setEnabled(False) return True return False def getSplitOrientation(self): """ Public method to get the orientation of the split view. @return orientation of the split (Qt.Horizontal or Qt.Vertical) """ return self.orientation() def setSplitOrientation(self, orientation): """ Public method used to set the orientation of the split view. @param orientation orientation of the split (Qt.Horizontal or Qt.Vertical) """ self.setOrientation(orientation) def nextSplit(self): """ Public slot used to move to the next split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.tabWidgets.index(self.currentTabWidget) + 1 if ind == len(self.tabWidgets): ind = 0 self.currentTabWidget.showIndicator(False) self.currentTabWidget = self.tabWidgets[ind] self.currentTabWidget.showIndicator(True) if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() def prevSplit(self): """ Public slot used to move to the previous split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.tabWidgets.index(self.currentTabWidget) - 1 if ind == -1: ind = len(self.tabWidgets) - 1 self.currentTabWidget.showIndicator(False) self.currentTabWidget = self.tabWidgets[ind] self.currentTabWidget.showIndicator(True) if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() def __currentChanged(self, index): """ Private slot to handle the currentChanged signal. @param index index of the current tab (integer) """ if index == -1 or not self.editors: return editor = self.activeWindow() if editor is None: return self._checkActions(editor) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) if not self.__inRemoveView: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def eventFilter(self, watched, event): """ Public method called to filter the event queue. @param watched the QObject being watched (QObject) @param event the event that occurred (QEvent) @return always False """ if event.type() == QEvent.MouseButtonPress and \ not event.button() == Qt.RightButton: switched = True self.currentTabWidget.showIndicator(False) if isinstance(watched, E5TabWidget): switched = watched is not self.currentTabWidget self.currentTabWidget = watched elif isinstance(watched, QTabBar): switched = watched.parent() is not self.currentTabWidget self.currentTabWidget = watched.parent() if switched: index = self.currentTabWidget.selectTab(event.pos()) switched = self.currentTabWidget.widget(index) is \ self.activeWindow() elif isinstance(watched, QScintilla.Editor.Editor): for tw in self.tabWidgets: if tw.hasEditor(watched): switched = tw is not self.currentTabWidget self.currentTabWidget = tw break self.currentTabWidget.showIndicator(True) aw = self.activeWindow() if aw is not None: self._checkActions(aw) aw.setFocus() fn = aw.getFileName() if fn: self.changeCaption.emit(fn) if switched: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) return False def preferencesChanged(self): """ Public slot to handle the preferencesChanged signal. """ ViewManager.preferencesChanged(self) self.maxFileNameChars = Preferences.getUI( "TabViewManagerFilenameLength") self.filenameOnly = Preferences.getUI("TabViewManagerFilenameOnly") for tabWidget in self.tabWidgets: for index in range(tabWidget.count()): editor = tabWidget.widget(index) if isinstance(editor, QScintilla.Editor.Editor): fn = editor.getFileName() if fn: if self.filenameOnly: txt = os.path.basename(fn) else: txt = e5App().getObject("Project")\ .getRelativePath(fn) if len(txt) > self.maxFileNameChars: txt = "...{0}".format(txt[-self.maxFileNameChars:]) if not QFileInfo(fn).isWritable(): txt = self.tr("{0} (ro)").format(txt) tabWidget.setTabText(index, txt) def getTabWidgetById(self, id_): """ Public method to get a reference to a tab widget knowing its ID. @param id_ id of the tab widget (long) @return reference to the tab widget (TabWidget) """ for tw in self.tabWidgets: if id(tw) == id_: return tw return None eric-6.0.8/eric/Plugins/ViewManagerPlugins/Tabview/__init__.py0000644000175000017500000000024212451233371023346 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the tabview view manager plugin. """ eric-6.0.8/eric/Plugins/ViewManagerPlugins/Tabview/preview.png0000644000175000017500000007267712060166053023447 0ustar piotrpiotr‰PNG  IHDRúÁnúbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ 1'e3Åp IDATxÚì½y[×u'|ßþ°ï[h½±Ù\šÍ]µR’¥Ø±;Nì¤&cóœÉ(õ%_ÕT%“šÊ?ÉÔü3‰'UvFŠ,Ù²-ɲ$Š’%nâÖ\º›dï Ðè@cßw¼ý}<jõÆ–HÙMëýŠìÞ»¸÷ââžwÎùÝsÏ…–––€ _T 8ŽG£ÑF£qÏ«FÄçóÁ0,²Œ­+•J‚ ÎÎÎ{^u:žšš²Ùl[â{¢(Çq¿™¶4V«•çÖý!<Ï+•JÇïyÕ …B˜B¥o^oýÿäËe¯Äe×â'Þ­,õÉ¢Ëî°ºòðR¤£½mUÍ⊮ˆët¥Ù¤¸N‹Ë[õÏ.îëÛ‰ ˆ<½îø\k‡aÃð­ð=q ýõ„ pq…ìÊø€P(ät:1 “^SÕÝݽ^ažçïhx”J%NW.—´Z€ah–åT* ™HÔë5»Ã¡Tªîò{òÜ{Ç굚F«µÙì€B!o0¥[ Ãð<¯P(6Õ/Èë~òüóÏÔjõ…ü~ÿÉ“'9Ž{óÍ7%wùìÙ³ …ââÅ‹‚ ´µµ½üòËSSSsssÕëuNh4ù|É`0ˆâÝãouwoï½wÕÍèȰ(Š‘pxzfª^«¿ð‘F«½qã: #Ùlv|l”eÙJµ‹Åz:5šŒý—.˜Mæ‘áJ¥r~.811Àq"™Lh4©•|>§7è7îI6›9qâx«Ç{óÆu¥Juü·¨Å0Œ(бX”¦©ñ±1A …\<gðёáÅ…y†e!ªÕª$IŠ¢X(äí6‹ìýo5ŒDGþÇ™ÿñ£ó?Z\Xìóô±Y 0::ªP(DQ´Ûí(Šúýþ'žxbzzº\.SÅ0 AmmmóóóçÎûÞ÷¾÷I Ào\y±XüàÃ_‡Ã¡¥¥ˆÉdEÃð\.›L$êõúü\T(®z}mF“ùêÕ+$I.-E¼^N …âÃ~ ¸r¥?íÛp|âƒû¾ÿÞ»nwkÏŽÍÖ7Ó—«Õf³ Æ…ù¹3§O)•*ŽçNüÀçk3™Í7®êõz(´ˆãøÒRÄëó=óÌWfg^¯÷ÃÞokkßàÔ„¬¶ Fc£_éÿJÝW˜™™yùï^&bSO©ÇEQFÓÓÓÓÞÞ~ôèÑk×®uuuýùŸÿùc=6??ŸÉd …Âã?n4%Á’ üÿ¦§žúR[[›×ëÓëõ*µ‚¡€†ã9EaÁq\«Óù|¾×1 Dᡇáx®¥¥erbÌîp@ät¹l6ûääx¥\¾r¥ÿñcOÌÍͶ¶¶6[ááŽ=áyÅÐÅÅùd2A ŸÏÍÏ}ìñ……yNg³Ûq‚ðx<8Ž?ôð#år9àŸN§S€ÿ©/= ÎjµšÛUɰåðÂÐ õÖ:Ø € ¸¶tmrzQE1‹¹\®ááá;w6 ¥\.75ôµµÚ 9ŽÙ·ïÀgèÌàÀµC‡˜à |Û¶íÍë‹‹ >_Û&¿ÏñŠn⋠ׯØàÏs=;v–× |ªž@`“…÷íÛÏóÜÁC‡—7Ç ¼<á¶¶=|ñÆE€ðÜwt´w|î4¨À <¿%fÏ󿱞È&ÐÄs_znjjêÂèX€Ûà¶ïíûn·ûó•J€P.—¶Â÷§)ê7Ö“Zµ’Ïçeh«áŸþŸòüù|¾Í׿r¹8ŽÃq ¼ YŒåîýs«^¯‹Å/Ú@s‡ AòœÛ²°è|½xðàA0ΦóU›ñS/6¡J„D @%E© Ê— øm‡¹K”òOþEÆììlµV[~¥H·ÚQú– Ä0œÛªÝÝá\óavõêÕƒ’$¹ú.A$IJ:Q!JëÒƒ™A#«tµÃÖgÃn“†Öà[ët½BULÃkñkE ÅT„ê6Á"†³a¯Å»Éo˜«æŒ*c,sü‰ œ] Ctò$ø"ç*=;v7ß&â±ý¢ÜÙà8nfff÷îÝk €4饸I ¢ùè»7Þínéæ®ÝÖ.Šb0 0Z¡*‘ld§{ç|j^Ň·?<ïqõüjðW½ž^Q·µl‹âÁdpŸoÇsUªzÙ‚ “Æ´˜^ìvv³[£k}Þ>Àttz)·ä1{*ÊhxôÁmfÊ™ñÈøö7n´š[“ŤÄ];wÉ3à Fhš.•J0 k4qQq‡…0’$%ŠsMH³‚ é…(ŠñBœåYÙã³ø E²‘Vsk¥Q)ÕKÅZQÅ\5W§ën{á˜ÓÐ*´³§Ü([´–cKõ’ÏâK—ÒsÉ9ŸÕ7¤XªT/y-Þ:]Œs·©Æ\5·«uWº’Ã0Üaïè´wÂì³ú"ÙˆN©‹d#¼À9&M¢(ärÙ?ùö7ÿß~+ŸÏñË¢ÂîÌT8Îõ‚¥Wûy­¦ÖÇv<ÖíìžOÍ–rK‡;—꥛ 7½/˳$FºŒ.F‰ÀvçvÇs­#SÎdÊ·ÉM`Dª¡(ªÄ•½­½8ŠÔ®¡ÅÐÒfkk6=ÛÕº«FÕ|_ª” &ƒ6M£ÐèUú‰ÈD›­ã9ù·—!™*¥bñÿýëÿP*—+@@àF ®Qâkúw0­p\©T.7Òºt ¤VØHëõižd㻀d1iÖ˜ažŒNînݽAÉ]`—ì|ÁÑùšÑdn¾¥óãávx쑇>_®zƒI¼ñü¾#‡h×Û¥Ï~@äjà€Älò„ø¢!NOO6ß"0¬Òù¨ÝÙj4333n·Ûb±¬å[ÀÍGus H¡Z@T£Ð,/YiTV\Y|5oT¥¿wüJ Ç 0‚ÀH®šãÞªµ(– gÂm¶6 Áš%ã Þl¸,_@x}íOoßññLËç~uî&À7á,Ë{ï½·ž¡²â±(&~~õçýþå×Ó‹¯]}­F‚ˆÍUsWf¯P,547Ê„Fã'nžLyÀ¹©só©ù‘ÐÈàÜ  ±|ìãÚ2‹‹™ÅKþKç§ÎW•7®½‘¯æ¥[7nÄò±Åôâò†fb3o¾I³´<dH`Yv³N°B¡( ;wîÜÀR_îd+YA<&OÓR§9Ú¤1é:‚ÂèTtÊcö¨I5`,4v¸ó0Çsu¦>† Ȩ6Út¶É¥I@ƒi“A‚)–Za-¤DQ´ëí&I£ÐtÚ;»[º#¹ £Jä«ùæšC8ÆQÜ¡wh? 9Í»» ðEõƒ×¼~ 0;;ûþûïW*•õ,õ4¨WtØ;ºZº¤f¹ÅТUhwºwÑaëP·emzÛàÜ  P+h•Z^àKõR4båFÙ¨6j–c“Ť Ñ|ôãCp¢˜0iLÓÑi†c¤µ3‡ÞaÕZ1E±¹Öbh±h,z•~—{ŽâÛZ¶á.O…/êüÿî D’$AË}€Œ>³œºKHÄÿ^ßÞ{U!ðƒà <¾hº~³³ëãÍ!™LúÄå‰{À ‚°Â"©š{Õï[¼·ÊŒ•SbCð…@DÊR¸žÈ#+ã¾Æ=¦Aƒ x×dlqØ€­tÞ]]ÏBžþùx®B`ˆÍ¸vJûáá቉‰ööö5õCÓ?– „—NΜ,7Ê6 pqæb4u›ÜK¡0J±Ôí…8‘x†c  Ä­…á–gg³" ” XuÖfPÃõùëN£³Á4`žˆLTAñBü£É jÃXxlbiEЋÓ)–º¼fÖ˜›,› 9úÜä¹|5_gêý3ýµáôøé[[mά1K} ÕFFE “AF(–º0s¡ÓÞI³´DQQ€!¸ÎÔOJ—ÓFµñÄÍ>«ïìÄY®ÀQÀ‹<˳ùZ>” UFš£! ¢ÀðL¶’æ£Fµ±©Hyç¾Ü(ûã~ƒÊ 0!q²P+ Íù¬>Š¥AH1ÔphXE Á®/\'1²Á4HŒ¤X EP@Nà¤A>qã„Yk T¨Š^©—2Ñ,ÀH¿¿ßap°<+ˆAÒ/Õèwœ¼Às‡Â(@bª ‡†­Z+/ð’髆Ô&`Úú³?‹7óF0š1*€Ï빃H&“‰D‚a˜5ﮎåcãKãû|û¤¥zé«û¾êûç’s³çêìU›Þ¦!5(‚"R¦ÊÚŒ†G»Ý'nž¨P•®@ÀitŽGƽ¯Im0S£kñB|<<¾·m/#ÙJÖitZ -.“‹á˜T)EsôddREª rœpk7Œ ,Ï( PbÛþéØô\rNEªfb30…Ç Òß>Ç€fé#]Gçã…¸F¡QªJ£ÒçíìT/ýòÚ/5JUk5©MfÙitæ*9§ÑÍEÅÃ14KÇ ±{ÇO/ýÔ¨6’Yg꽞މÈÄBjyŽçÔ„ºÅØ¢UhÇ#ã…jᮑ‰l%K±#ªr}þº]o§XЏî â…øûÃï·Z$éDøwo¼Ûnk¯Óu†*ãDd"˜ >¶ý±VK+†`ç§Îç«ùG·?š«æ`žMÌ>¹ûÉW.¾Øß¶?” mwnŸŠNåª9­BL{=½0÷zzg¢3CU•6k[Ÿ¯0Ÿ gÃuºþJø Áéy$” =ìx¸Óx¿h€µ¯ßM$ÙlvvvvM¢É5W"¹ÍÒ-†–fT)E³´Ug¥XJ«Ôbæ2ºbù˜šTh;`T•¸²N× ”PâJ†{œ= LáÐ;ÔÄ'V×éºUg]q1SÎ$Š ³ÆLb$‰‘z•‘r£œ)g *ƒT¦F׿’sÒk–g/L_ØîÜ®$”Œ˜Ô&†õ*½ÓèLÓÍ>G²­Bk×Û´p›Ü­†ai›²Ãà8Ðv`»sû@pÀ¢µHŒ,Ö‹9ôŸÕ§W饀?·É½×·—ÄI¯Å+‚UgM—ÓZRËò,/ðNƒ†áÞÖÞ:S—Ú%0‚እzÍÒm¶¶ÞÖÞVs«Ek!˜féJ£ÒaïØÕºËmr/¤HŒd8FE«ÎŠ¡˜N¡«PNàw¶ê¬sɹUã^£ÐèTºVs«Qmt™\.£KCjê~†á®Ké•zFе"4KKûõÚíí0 ÷yûæRs‚(„³á]k1´HÃu¤ëÇs‚ HZî~1ÖŒºƒ äp8víÚµmÛ¶5ó§¯6f…Çå‘Ï«ÖZ¬; ºÑí잉Í<Ðù@¾–w>«OM¨y@4_ÍëÅ»4¨ z•^«Ô"0Bb$‘t)½«uW…ª(pE¡Vp›Ý’ D± ©r]VµÛÙ-‚Ëè‚!XMª¥(!í´/ðŒô8{QØÖ²@‰^o¯ŠPy­^ÉdÒ*µ‚ ìñîQJÅ}_¡VЫôZ…V‰+uJŽâv½ÝapH2¦$”¢(v9ºÔ¤Z§Ô‘iP,Z Š $FºMn«ÎjPAØëÛ Ðiïl··j»Î®Uh-Z‹WLS‡­Ãmr7˜F¯§—ÄH%¡t›Ü¥zIÒ$VA¡rèN£SMªkt푞G>«‚ ‚wµîª4*f­¹ÅÐB`„YcV‘*‹ÖbP¸BúkÖšQp›Üz¥Þ 6¨Iu›­M§ÒµšZ{\=™rÆ 6˜Ô&‡ÞÁ œÇâцcÚ­íÅz±ÓÞé4:!òY}í¶v+a½/L h,®×>ie%è7 'M>ŽçxeÞ(–g!IÓz=U³úõÏÁ0¼fÊÙ ^ŽÁïÇ©‘ …ü3Ÿã–H-ж¶u ®5£Š65‚ÖyýÇoû²û(¸ð3.„år¹÷Þ{¯»»ûðáÛ¡ASÑ©V¢u·e·ï£æOŸÎLO«¬Ö®/™g˜àÉ“î(E"(I¶ìÛWŠFF#[«ñ chk°õú™ÿößzÿìÏ&_ÝÞ×WK¥ôOÇïý¾~æF2š°ÞBØÈEQ„5s1¬a÷‹"A0ŠNýò—½ÿñ?²ÅT*óºÖÖÂâ"@àù;!Š˜Rxÿ}E¹zFQãʱÏ0ù¹9„ ØZMÅñL©t0 _ùÊWäA”q_»kª€;8ÁÙlV­VƒÁF£±ú®|J¤ŒßqÈçóÕjµD"±¦,Ïx÷hš^~Æwkƒ¼6³!¦^¯ãßXó ìÕ4¨<Ö2¶ v+ "bˆˆÂ‚ZIØlÖMiÇ=ºÞÝ,,2¶&ZZZ–›0‚ L$ü›ò6ÆŠ/[D2¶&–gÕæm31ĺ0<<<99IQÔûï¿ýúõõê]aEðƒôädâæM@=—«çr+mªL¦Q(¬¸X ‡žÏÍÎ2•ÊÆ_¦3Õꊋ3ï¼3õÆl½.Éaaa õáS1ù`°ù¶°°Ð\‰ã¦¼´´¢NŽ¦Ë±ØÆur4=óöÛü:‡¬-Gii‰g˜j2Y¹Sw‰㟛mŽó­4Á_ÿZ*ùñÅÛ¨¥ÓÒ¯°úÖÄ ^Ež¿%ë‘T*•EQÄq|nn®»»{µ°úˆ$k{{zjªãé§ÿÏÿakµJ,†)ÕT*tþ¼ÞëEp0æ ¡Õ–£Ñð¥KÍ‹×þ÷ÿFp¼žÍ.ž;ÇÑôâÙ³MëÜnÀÌ[oM¿õ¡Õ†/^¤J¥ÔؘÖéLܼ9ú´Òl&õz@ôêU…É´xîœÒl÷÷Þ}׺cGàĉ¬ßD1øÁ¤Ápý‡?8ÎàóÂýý™©)ÃüÇ+-–É×_¯¥Ó"ÏçææÔvûÀ?ÿs%Ÿ}ÿ}•ͦ¶ÙÙéé‰_üºk×Ôo”ÂaަΜá(ÊÿÎ;Ö]»0…0óöÛÑj"¹t S*'_©VëétüæMSW×Ôo7óÖ[\½>ûÁs'OjìöÙ÷ß×{½Ò¢ÞÍÿûÙzFé·ÞâðåËõLÆÐÞ.M²É_ü‚®V×.Õs¹ÔÄDii‰­×CçÏ£ EàĉF¡™œ,Çã{EQôG2Wõy=ëj»ÝÞ´ò×ÝP¼> jëíe ½×˳¬Â``jµæSGïõ ,«0ér™º}ÑÞ×ײoŒ ®˜?}!¾Õ7Ãp•*92" BjlLçv GW«Ž}ûêÙ¬T¦šJá*Õö¯}äÇ?v:dß³GíphœNL©Ì-{÷–—–¬==µô­“ðÔ6[%ß¼é}äµÝŽ)•ϯ4››ã¯kmy¾‰ˆ<Ÿ$…u £(€ ÷áÃÅP(5>nlow?ði0(L&‘ç©R S*ké´cïÞF>¿Õ4ß Á¼ý°nÊú@E†ÛÛÛgff|>ŸÓé\S³ (ºÜ IRày­Ó) ‚Òb©¦RµdRÓÒÒÈç-Û·£HŽŽÖÒiµÝN æžé"AÅ…ËEêõ¦ÎNºXÔ{oðù&®VZ-S(ÜGŽ ‘žö;VŽFqµS*•‹uûöÔø¸ëÐ!” &“Ún4²Yž¦[zhéÚ5¥É„)•j»==9YŽFµ.×ÜÉ“­=¤4Ù¬TFÑüü¼ÂhDIRi±QDÂÑ×WŠD”f³¤’##õ\®çÿ°–J™»»¥:(B¢óxâ7n´>ø ¡Ñ¨ív‘ãÔ6›Êf«g2ÖžL© $™žœÔ{<˜J¥s»aVÙlRë@1•JïñQTÛí*‹%7;ëèë‹\¾ìØ»—Êç5--Ç¡¡²ZëÙ¬¹»»šJ}>Ç£q8MOLt<ý´ôIãoìê"u:Q+ñ8Œ¢j«µ¸°ÀÑt1Òº\µtÚØÑaîîÎLM‰<_ …”fsnv–4èJEc³¹N ZmÖïÇT*B£ÁÜÕ¥4›qµZ WÙR4(Š¢Ëçv ’EÙÊÝ’‡ã¸R©\ ¡û­ê¾J"Á°d´|ö§ËRù¼êÓW" Ï´€ë¹[«énk€/ ªÕêráþi%•x쑇î–ZnýÖ¿§ÆáX=ûoܸñé& S}&Úš³ 4™¾È³µ $Yïw`(Ššœœäy~bbb½“â7 A+±Xj|ü– Ûhp  ­$I(jæ­·2ÓÓ3ï¼SŽFã7oNœXMòܪ_JáðŠ‹« % ŠT±Ø|766&õMº¸º@cƒƒ…ÅEºR8nS*µ\n–äfñüy™jÜÊXñt^Nƒ®»–L&/_¾ìñx>úè#·Û½f(ÄêhP‰ÆiÙ¿䥗¶ãR±…³g+‰Äî?ýÓáÿ÷Î/™k4Žkê)JT¹lðù"W®Þ{†á–ƒ)Z¤,€Ù IDAT/\8NÛÒ’šœtìÙ“a¾ï~s³³¦îî›/¼pèùçs€ ¥ÉTXXÐû|So¼qðùç³~?~Û-..޼ôÒÁ¿ú«™wÞ1uvj]®b8ÜþÔS˜BQÏfKѨä2ªíöÎ/Á0eçÏž%u:Eµnw%/Ì͹_¿Ž’d>Ôy½Ï<£(‚ã•h ’cc¾Ç_(íd¨¦ÓÉÑÑR$ÂQÔÜÉ“‘þ~Q‹¡].7òySW—ûÈ‘æÌ†T;KW¯ê<ž¥«Wér‚áF.'~rFÆ–ÂF>€Íf˜L&tgØjÔÐÖ–6o߾܌VÙí™éi¶VÓ¹Ýj›­åÀímN‰k4ÊKK™éér4ª÷z ­6HëY@érYa4*Íf…Ñè{ì±ùÓ§qµú–ÿ­RAÄsœ(å¥%¦ZU˜LJ³™Ðj!æY¶“z=ûhA8Šª&“Z—Km·»ÂÕjB­(ÆF>/°¬¡½}éÊiÑJi2é½^­Ëå:tˆ.•º~ÿ÷ŽÓº\ÒÇõ>ßÒÕ«M+ÈÔÕµtíšyÛ¶\ `ß³'=9iÙ±£‰4 çãŸÒ ‘ñ¡AoÍü»b‚ Iry,нeDAh®|æ’/½ôÒ÷¾÷½;‰bñÞ&ñMÙz{åÉ·P*•–p!»Wüd=öØ#Ý•yúyŸ°ÉÙ¿qIdz>ëž§°–gÿ–õÀ²è uçM½^¯V«,Ë.--UסeVŸÃQ”´H E1Õêc{>o<ñÄò M •"ÃÒu[+±‚(Š/^¼páEQétúÍ7ßÜ ÈÌÌŒ¾ò `ìg?K/œ93æŒüÈøíb5 Áô”G¹µ˜o‚xà+W®h4½^ïóùÖ¬w5 êØ³GJ~ð/ÿ‚ ñÀyôel5HEI'( ]Ÿ¥F$üøÇ?æ6·Àg6­ä±–±’$EQ:+›eÙu5À&@NŒ%ã¾p›E]z÷Ýw ÅîÝ»Aøú׿¾¦Á/›@2î h…¯+™@‚ Àkj‚}ôQŽã‡Ùl^OKÈO}÷Ö AoçuF7ö‰„Z­^3-sƒÊ¸O°âñ/Š"ÏÝZC×£85ÍÃ?Œ EQôG$¢Œß ié:ºÞ:‚ °Þ*iP÷°& Ã0ü)¹Ö¬Õ©«UFq[ ëÑ <ϯ½,Šâ©S§~¿¿¿¿“šEÁ‡7îÍà`4•ªÉ¿ŠŒß–€Û4(Š¢èê@9IGôõõ]¿~=ŸÏûý~a=M«iÐññä¹s¡–í?ýÓ¥C‡\Ùl½Ph|å+]çχž~ºã¥—†ÿôOwŸ8رÃòßÿûÚ¦ÿ×ÿú_ßþö·ÇÆÆ”J¥ ÉdòÛßþ¶J>ûQÆ=5VÑ €a^'’^Ú s¹\0\ÓÄ_ÍüttaÔëLK‹FÚvéri¢‡»lOå[ßÚùøã¾Çó5Ýó#GŽƒÁ–––©©©C‡)Šôí\Q2d|Np3@$It½§»R©ìííu¹\ûöí‹Åbk²œ«iÐééìþýN’D¿ó>¥}õÕñÇ]ÇŽµ=»ðì³ÝssyÀïÿþ¶«W#ÍhšÞ»wo(:räEQf³yÍ$\2d|f¬¦A9žÇh4ÐüüüÀTäsJŒ•ÉÔÍfÅf–²Ù¬^¯Gå 2>T*•å, Ç/Ï(ñ‡YWlҷؘµX”›¬Êl6Ë¿“ŒÏÏX“­Õjðzç©©)¿ß_,þóŸ_»vm=Ój *Šà•WF7îÍÂB¡\¦å_EÆo‹jÒ jµÝ@hB¡Z­.•J¶uR®~êOL¤âñÊøxêÅoîÙã(©Tõÿ°çí·g¾ñžW_{øaÏñãþ;¬÷wI5üä'?q»ÝEétº N£‘!ã^ ¸MƒV*•u7Å·¶¶l6Ûw¿ûÝ“'Onl5õ@w·9®årFƒ‹DŠñxÅhT¼òÊ胶ž93Oè׿ÞóÈ#Þ§ŸîhgZ­6j4šÅÅEù§’ñ9™@+®H4¨V«…7pp=O¡P8}úôMoí½~=¦Ñà• ýè£Þœ Ãcò7óÀÜ\þ›ßÜqôh+‚@>èIHå¥h‹žžE­V«üSÉø<°^œN©T‚æææ§—>'hd$¹{· Aä@Q¿Mlý®hÇ;ò›}}vyôeüÖ±šê„!P,áõ´C&“I&“¢(NOOûýþõ@>)^Æ}'Á Ðëõë†BLNNÞ¼y3Ÿ>}º¸,Ýþ ÓJ>([ÆÖÇZ4¨pK¬·Ö××Èår;wî 4MoÞ·!c+ @ZØH ¢Óé:;;£Ñ¨V«]ó€Œ N‰”!cë`õ¦‰-‹ë†Bh4iYê;ßùŽ<‚2îk¬gœët:†?û9yò¦x÷V§G—–ÆÊå2¼æ†Ã04M3 “Éd «¢[_°òùÃðô¦\.çr9IlDQÌçó,Ë6•TeY:õjµZ¯×yžoº,ë姸퓀¡¡ØÆcÁ0|ÓR!—Ë1 “N§s¹Ü e(u‰eÙ·(ŠÚ°b>Ÿ§(*—Ë•Ëe𦠅B­Vã8Ž¢(Š¢†Yó[Ð4-uFj·X,Ò4ÍfÓéôÝl[•Ö¤AaH2s¿þ뿎¦K+ÊEñäÉ“ 6›mrrò׿þõ‘#GV׋a‚ ËI™)~ç;ÇrÎÎær¹Ë ““éj•™˜Hkµ¤R‰~øÃ†Ãá|>o·Ûûûû¯]»–J¥NŸ>a˜J¥úû¿ÿû'žxAžç_|ñʼn‰‰l6ë÷ûa>sæŒÉdªT*ápXʼn‰ µZ=44¤×ëI’ÌÌd¦¦Ò&“òúõ˜ ˆóóùH¤¤Ó‘—/G,ÕåËár™þŸÿó2†ÁííFÀÐÐÐÅ‹³Ùì‰'A bvvV¯× …x<þÓŸþÔl6ôÑGµZÍf³Ý¼yS¥RMOO¿÷Þ{N§svvÖd2]½zµÙº„ÙÙÙsçÎÆ—_~Ùl6Ÿ9s†eÙãÇó<óæÍÉÉÉX,600°÷öjM¼öÚkÕj5‘HÐ4]¯×Oœ81??‡/]º´{÷îåœÈø´h4+"íg£9„)›MFx½ôèG… Èh4"òð›@MWX§#t¶¶êøÃëJ%öƒ üú×Á^¸ùoÿvãܹéS,ËRŲìéÓ§/\¸ðä“Of2³ÙìõzOŸ>m±X¤¤ EQFãõzƒÁà±cÇ|>ß… ÆÇÇûûû•JåÕ«W§¦¦>úè#©f›M5<œˆ¾úêøÏ>þÒK#o½5ó·{vv6÷æ›S?ùɘZ£(ÜÚzk¹zaaáÙgŸÍf³»wï>|øðk¯½våÊ•l6û£ýH£Ñèr¹*•Êc=–Ífóùü /¼J¥Axùå—/\¸ðÞ{ï™L¦SÓf³ÕëõL&ÓÖÖÖÓÓò¬ï‡AÈf³‘HdM¶ «««y"m"‘Ø¿½^?pàÀÞ½{µZ­<‰ï! $Š¢À •Jo¼…¦éh4ÚÖÖ¶É–´ZÂhT(¨Ç£ïî6ëõd,V6›•ɲ·ÔÙlþ‹¿ø‹'Ÿ|òòåËßúÖ·Þ|óM‹Å¢V«'''wïÞ-Š"˲?þñóù|>Ÿ¯Õj‹e||¼»»ûøñãÓÓÓ‚ d2E}>Ÿt~kOOTóÀ@tx8F…(‚zÍdj]]¦‘‘¤Õªêì4vt}>Ãà`T*¿mÛ¶ÿøÇ^¯Wzët:¥ó”G(BdnnN¯×¿ýöÛ€@ `±XB¡P©Tr:ííí.—kpp°\.¿óÎ;‘H¤i:êõúp8<99944„aØøø¸ Z­6™LªT*Q#‘È/ùËB¡ð¯ÿú¯Ë†ajµÚ‡~X©T.^¼(ÏûÏ‘E@½^‡fgg¯ûckÆ5×¹ÖspI’$bù†½^/" CÒ_‰… ý]~œ^<ý½ßû½\.W«ÕÜn·(ŠM^U†yžŸššÚ½{·ôVR8ͤ×ÒÅÛ¯Åfo9Nx饑?ÿó½( ‚ˆ ŸèRóœäh4J„Ùl^®ÊVC³õ¦Ç¿üâÙ³g;Öežç›·Vä h¾E‘¦é7n<üðÃÍV–÷åü²L0Ü%ŠÅâr3UÅWüx-úЃ@ ×&ß-nM‡[ÆVÃêS"O\ µè}}w•}ëР¥AV+{Š2> Šã8ò7ó7k²@'NœˆÅbƒág?û™ßïß½{÷êzQôãܺ’”Jüý¯ìÜi‘¦yQK%šã„R‰Æ0DÚˆùÃþpppP§Ó †………Ÿýìg ÃN‡¢è?üÃ?<ôÐC‚‚ðâ‹/NNNBT(hš~ã7”J¥Z­æ8Žã¸‘‘)„(‚›799‰ã¸Z­ŽÅb&“‰eY–eËå²R©L&“,ËZ,–±±±ýû÷§R)Ç£V«aÎf³4Mët:†aÜn·ì§ÞG&(ŠRÖ6A @ p#_ísW©Tt:Ýüü¼F£±Û×ØÚ²zG˜J¥I¥ª--šH¤ìñè2™z&S3™µ«Õf³N§­Vk<?uêÔw¾óË—/F§ÓY(|>Ÿ´&°´´d·ÛãñøÌÌÌ“O>977×ÖÖ m6ÇqÅbÑ`0$“É®®.…BÁóâðp†!›M]¯³ŽñÆäóÏây±Ñ`µZB£Á ln.¯Rá‡Zì .=zTZö:~üø±cÇûúúÚÛÛs¹†a™L†$I“ÉÇív{(r:Ò ›‚ äóùmÛ¶-,,´¶¶J rf—-‹õv„=pè€ÌÉøBÒ Wýx5úÀ¡w›]\[+ ÔfäþFd\¸pA£ÑtttHá >úèš GƒÊ¸iÐÈèèèH&“±XL¯×OMM­¹bO°<Ð2î ÜŽX÷€ €Z­–Ä@£ÑÐ4½Z†ÖÔ,òXËØúФA×=  P(zzzA( _ÿú××dKå 12îG¨Iƒ2 ³îŽ0‚ ¤ãñžyæyeü®AÁÆdl«Ó£§@ª ÊòðÞ+´6 ò8Ü%ÖHŽ"@Ú(³¦ày¾¿¿EÑ\¾|Ùáp4cî76úË <”"1Ò¦»•P:” y-ÞX>æ4~b!]JkÀÄÒÄÁöƒ+êÉUr&)œ {Ìž»ÿþCsC;Ü;T„Šb©\%W¥«¹JN«ÐjšÙÄl¯§×ªýDZÒfo¥Î¢cÕœImZ³–góÕ¼Mg›‰ÍT»þÓeÅ+Ö‹RƒÀ·¦»ÄH6â5{e¸{¬EƒŠ¥R‰<ÿüó±lyE0AN§shhˆ¦iE§§§{zzV‹ ‚ 8Ž7}‚õÀ«×_ey¶ÃÞè÷÷S¨"ÙÈåÀeA¥’Ñ\TI(#¹ˆ?î7ª™ræJà Ax€ã9IÒÆ#ãK¹%‡Áq-xME¨$g`<2>›Ñ(47nø¬¾áÐp²˜\L/&‹Iš£?ýÀkñ*p QHøã~Š¥>ý°ÕÔ:ôY}4KÏÄf\&×@p@úR€‹3“¥$ŽâËÃFµQÒïÞx7WÍÅ 1ÀBz![ͺn¡D² ©YH/Œ„Fº]xà£ÉÌZóDd‚ @"À ܹÉsuº®Uh‡æ‡, †bpÉ,ÐÝC"3—Oï@$‹²ƒ^·ö0 “$i4-Ëš+ÍŠVdÉUr‚ 4Y CK(òÇüV­u)·äµxízûÅ™‹sɹ["#zÕÊ-ùj¾ÝÞ^gê>«o›cÛ­§;Ïœ>1Ó«ô,ÇNE§|Vßõùë]Ž®©èÔÐüP0´ém;];Ùr–ãoi­b­¸^¨Q5F* ÅPÑ|Ti¢ÝÖnP¤’‰b‚åY“ÆÔaë0ªJB)Q¢bp—„³ùÅ;lÿ~þßiަ‚Mz GqÅ}V_ºœ®Q5š¥›ÿ;×߉d#$FæÓóƒc44Únkÿhò£H6L]&×÷Ž U‘žò¬½‡X#TÀéÑkµÚ‹/¾X­V9ŽS*•ë…K¬>!ÇpŸÕ×|RvØ:”0kÍ3±›ÎÆrl¢˜ð˜=ƒ£ik…2¡ùÔürÃi›cÛ™ñ3fY‰+ýñ[‡ÓxÌžj£ªÀÑ|Ô÷kÚ@<ÐåèzG‹¡Å¬6OF'YŽ%q²Éí( ¥Ae¨3õh>š­d‹µb¶’U“j5¡&0¢T+5̓Ê)gQÈ×òÙJ6UJMG§qO—Ó,ÏJæT’Àˆ 7ìzøC‹t±×Ó‹!X•ª^ \émíå¾LÝZ·él‚(Àœ*¥üq? £‰BÂap ÍYµV®p•a"2£8'p¥zéìÄY‰;–qÏM Àb±ƒÁ¡™è½Ú–Ñgî Ô`,ÏjwHF³ôÀÜ@‡­cÅ2óºt˜(Œ‡Ç?W§yó(T c‘±üoÉbÒ®·Ë,Ð=Áz;Â{ä¡-š]+@qÇbF<²ý‘ÍW Cðïž-ò«Ô†G{]ï®IQ5¬ÍÔ€eã³™@ÒÆn°ñ Ã@„¢(Ã0(Š®¹`=©XÍš:%ðŒˆ¢È †`M’Gz}O„x‚yGt¹Š€ÀÊÃΖç*”:ÖG–g1âÇ]ºU­È ‚€!'p¢(6ý†c`n¶xÇ´‡â„T`y»·ÌKÐaò!œŸ·Nõ];=:Çq—/_>uê”Óé¼víÚž=k<8W§G ñW_ÉUrw³&ÅñÜåÀe¯Å;87ØïïßݺÊ„ÎOŸ¯Q5)‚H§ÔI¬¢WHá4KCΆuJ$~‰b¢\/(±^XÊ-¡š)gòµÔÉ6›ŒN^›½Æ ÜÕàU“Æ$>gÆÏ$ЉH&24?T¨.L_EQŠâî•‹¯( % d1Y¨†‡[Œ-K¹%@¹QN•R$N†3aˆÑ\†áK3—QÀ1|44ê2¹¢¹(Ã3ª’.§ÛUíj –'ò¦,êUéу±”=º&Ç¢èáÇs¹œÅbÙ³gÏðððz,Ð Ÿ¸T/Ñ,ÝŒ„ùl€a¸JU¥ÚoRÊ„ßñøÀÜ ÁͰˆX>6ÎWóz•Þ÷ïnÝÍñœ¿I±Ôxxü`ÇÁ¹®¸±pC0«Îš)gz‡ÓèÌUr’ý]ª—NR‘*B×|T7˜Æµà5F=O¾–—"0a4<*¹‰Bâ‰]O\½ H 5m0]Ku?dÑZæRs¼À ¢ ˆB®œ³j­^‹·ËÑufü Á^«—ÀˆD1qÉI§Ô¡0Êp 'pñBÜ 6„2¡Ñð¨AeÐ(4JëE†c&–&¤/òOZžò¤MϨóV:$O£Ñ¬½%²Ñhüó?ÿ3 Ë‹‹?úÑ Ã&iÐx!ÎpŒMk»+Ö–¥3åL¼WâʦÜjn½0}Á¨2ªIu“áé´wÍÕ™z,ƒ Èmr‡³áR½$™ûKe+Y#%‚RRKIŒÓRn‰fi†còµ¼IcÚåÞÈUsRÍR“*¥ÂÙ°Äâ£Zgê4Kë”:‰Ê”¸³“g[Í­JkEŽçêt]EªúÊSÙ) IDAT¼}ÓÑéÉ¥I­B‹!†`‚(TŽç–rK ©#t*†Ô”ê%À&µi‡s/ðÅzà6ºkTMZÔ3¨ Éb²Ü(Ç ñJ£Rgê¢(*p…–”3§v·£ƒªÕêÚéÑA¨V«¢(*ŠF£ ˆ´Ex¥F$I.g’ÚdBHH‹8ŸÝ·…ÓÀ ‚šîD¼G`Ĥ6ñߌA`8‚ Ó@C0ŽçHœ„$ÝEC1Š¡¤.Aº¼¶¿m?#,Ï*pÇs’e†a–gIŒ”Zl²RIš¥q—­%WD…P:dÑÞŠÓ–´‡¨Gs4ÇsJB)­ïJfÄ:]G`@ŒP,E`ÍÒŒâp6ü¥Þ/!AP¹Q&1EPÉó¡9šÄH–g›žÀvd»ìlke‡öµØÃGÜãÄX÷Š•qGÈNðÝÓ û÷îAï&1–¼)þ·ˆ907æ›oƒÃrÐħ A9 P(ÖeΜ9sõêUNwáÂ…p8ÜÑѱf½+Ò£—ñò©À©J£"ùÁ/ž{±N×[M­’¡2³j­’_(©òt)}n꜒¸eë7‰×®¾Æ‹|$‘æSó&µIây$û„ø…Ô‚Qm\~‘ã9V`YQ’åYB$g”ã9)`N2'–,f5 ÏÁ0Ls´d#I±z‚àNs´ Çoïné¾u (œ8K ‰“"yç¾F×BÙQmDAEAXŽmÖÙü Ã30€OŽÔɧ˜ÄÑ\Ô¬5ß\¸9§XêìÄÙ]s]å*¹³“giŽ–Æ$œ ŸŸ:o7Ø%ŸÄ Ü0€å¹¾§¿"=º)‹q›Õ²vztEŸ|òÉ_ýêW6›Íl6Çb±õ|‹›â—òK#¡‘½¾[G Ö¨Z0´h-ÁDШ6NǦ]F×ñÇEQüÏÇþ3Àª³ú¬>–c#¹Hs'q‹¡Åmrïóí{ûúÛ¡Áлž&ƒ³ç•‹¯|mÿפ¢\5LÝf÷Ë_þƒ }p61ÛïïÿòÞ/¿?ü~—£ëñÞ~?UJ=³ç™Á¹Á{ÇäÒ¤N©Ë”3Ï=³ç™“c'ŸÚõÔHh¤ÅÐrrìä|j¾ÏÛ7ŸšïõôÎ§æ¥ØžB­à1{NŽÜîܾ|Õ¶N×CÙ×êýÉ¥Ÿè•zŸÕ787x¤ëH p]RŒÍÒ…†à©èÔ¡ŽCÒ ô¥™K™JæÎ¢ùèáÎ÷< ŽE`¤JUA¨P†cP­P Á$¶§Ü(+0E xa›îÿoﻃۺÎ|ÏE¹ÀE¯D#‚ì)Qª¶éQ¢d,[‘½Ù8ÞØžlvãìËμ™ìþ‘Y¿ÍN&3›ÉfÖñóSœÙ±-[‘ljz£hÒ"E±‘€è½×[ÞG†i¤eËE²ñ „.Î=÷â;÷|çw¾ï÷)Òxz=U›V"OR<@Q”–WðÇñ¿üå/åååñx\¯×G"‘{¤A!¡^,)†Ÿèä:{ÀžÎ¦Ub“ÁÔH4LÀeqÛ íð€`<¸äYR‰U|6†d®„˜+.ñ1>NàE5h–¼K9–&KdêKêÍ^3üÐê³êäºx*nPr}£Õ^Ý.äéJG1“ò¤<Ónh粸µšZ­L+âˆâ鸘+–ð$áD¸UßZ*/-‰¹âi‰R¤´ø,µÅµÁxFÔÁ–yl^©¼T€ 4bM‹¾ÅtÈr1W¬–¨YLV*›Š$#Ls—aNâ[Ê·äâ52xFÆ“qPN©¼4ŠW£©‰§ã©lÊr0A[E|j”•Á5=쉄'‰&£þ˜?•M••beÿòýH{|“iPÇéÿøÿèðGW¹@P8?NK¥R‹Å²{÷n Ãòº@+“☠Óks¿´\ ¯-®…ÑεšZ¸UT,-&IR“@R’¤H ÅtƒÎÈÑðb®˜Ë⊸"¥H™Î¦™t¦€#Hf’Uª*ƒGü0•MU©ªà1c1YZ™VÆ—)EJ˜¬©¢©¨#4¨ (µùmåŠò¶ò¶h*ª*Ä\1Œ?#HB'Óédºú’úX:&åK‹„EJ‘îèäºD:Q¥ªÒËõþ˜?Á*âˆdƒÎ`1Yr\Ä•ÊKI’䲸<6O%Réd:‹£©B‰\ ‡ý,!¢‘hDŒÙ„!.‹Û\Úˆ´ P+@ÀDSQ9_Ž  È@,Шm„B*“ÊÙjuu*“â²¹ZD[pÖC6›]•?cñ0ñ˜N[r_,ÐZôÁgp_ûðµÁv°½°þ44è,+nÛÖ¶ù¾Šä=ŒÌÏCaý\À­Ÿn–/<þ×ÇZ_Z.‚ ë®®^½záÂÇ­VëðððÆ4èʽӶi¸ú™1眻2qÅõû£þx:¾ê§mÓ™²M­ý®Õg¥( F×@Æ ò$!–ýË0ܦ°X}Ö ŽLÛ§ïñZÒx:—Ep/ˆ§ãþ¨Ÿ|ÀÿTÿB\ÄO½‡;P…ãwM"ÿ>Nß³gÏÉ“'ý~ÿíÛ·étzkk뽜Éê·^™¸RWRw?Šn® *äÙXÒS(µƒ‹ƒJ‘rÆ>cò˜vVï4yLÒ´o®¯RYÙ m€ü©Écb1YF/|oÛ÷ „LÒUŠ”L:3šŒî¬Þ YIf’0-«BYqkþÖþºýw–ïHùÒ&mÓˆyD+Óž<…2P›çx­TÄ¥²© £:;Ì^óœsN/×›<¦mC…¢pcúF8Þ\¶¹g¦ê‚Q€b1Xðép}êúŽªS¶)¸‹J„d|™Õg-W”û¢>)O c4t2Ý¢gñ-?…’“_Ø s^(ŠZW}xx¸ººznn. ÍÏϯ—9¹*#̰ã$®—ëï—·" BS‰T$EJùÒT&5çœÃPÌì5 0A¹¢ÜñQµà^ñe9e+µXM„œ/¯TVæ )@µê[ã©ø„uBÌ»K¹(EÊP]$,bÒîN¡¯f~Õ•ÔE’‘@,KÆJå¥Y"‹x]qB¨`Ò™p_B-V㮫g³E 84Z$(ʱ|Ž4è*ë‡4(FË?$‰ÅÅEE<¸uëV“É”×Ý_[!¦JUõÞwàóï3C'×-º7—mž²MÅR1L'äõEúûL•ª*“ÍãÁ¶Š¶@ƒ&'ìIf“Z©öË\ñ °4 ÷óÂzU"ÛwlcÜÏVâÚàtý³)RÝgnÃ'‚ Øj ^ýdhÁj?_h•«##Òéôºòè7oÞd³Ù555ÅÅÅÛ·o¿Ç“Ùv”‰ÊùòÏý2AGN‚ÁvKyÒ4žžwίJó¥(Êè0êd:“Ç“|Q_“¶I%V¥ñ´Ùkæ á :7•nBnÙF“Q_Ô'⊸,®ÑnlÒ5ÉrÀ‚kÁâ³”HKŠEî°Ûì5sXB£ÕRÚ2b)•—ÆZMm‘ hÎ5Ǥ3Ý‹±&Šyb&ˆ$#\WÆ—E“Q¸E¸àZ`£l1WlõYÛ4mk@_4 z÷éÃfç/’G£Ñ¶nÝj6›m6[6›-++»GÔ´ÿuà¯Ã¦áûén"0yL“Ë“#K#ýóý&éúÔuOØ3n§(jxiøöÂíy×üûwÞƃި—¤È[ó· |9\õ.y—ü1¿;ìž°Nl.ÛŒ8bI¤ç†Ï[Æ ’p…]€X*öî­wq÷E}Ž€cÈ4$áIrÊÌ:™Ž¤ÈYÇì¨yÔ°Ñéô-å[–ýˉf`q VS›Ì$‹Eýóý®«g¦§T^JD½¶>§ *ØyÌö~`ü`Ò:9j¶O›½f›gõY“™ä’g©`_ ƒ±®àÃáËåååå»ví:uêÔ½?¤3xæ>å/16n$#¾¨oÂ:áxëKêåB9ÌGñGýÖ Š¢µ‹îE@*›šZžÊÉûÐÚ·š¿%âŠò&æ«D*{ÐÀ 3râY@²x‹É"HC1:ò±]U ŲDrApŘX:›ƃ æa“5nÇ |¥$¸+DLã³ùád8šŒ.F˜@#ã˾µé[ëüGýÃI ?ÇÏ;§ÑhœNçØØXuuõ=®Ôbu{u{]qÝýtˆ„')“—˜G¤|©˜+æ²¹‰t"Z|–,‘•ò¤ždÂ2aÐ|QŸ'ì©PV¬â ‚$`VW®\ “Îl-k´N–HK|Q_mq-e Pý*KdËŠÊÌ^³„'ßZò.Á)_êùY  ¡aLlÞ5ß m·ŒkeZ­Të »H’ÜѾÃõ Š‚ˆ$#3Ž…P‰,.››Ê¤ ·6cŸ±ùm8‰3hŒ‚u~ùAýîÙšu|æX þ8(¯jÈ'J‰|Ì›Ê$`HœÅg‰&£eEe¹à3€ÙkŽ¥båŠòµ¨XFwæÏ>à7¦‚~¡ˆD"+ \$y¦w†pìÛ³‹qŸºöç$Áçš‹Üó‡ëáë–Ëò,ÊåòuWêrž¼šWý%ü6÷¢ÿUÀ}"_R<µ‘ DQ”Õje2™*•ÊápÐh4•Ju/.(?xôÑ2—+F¤F#dãÙL<Ã-Úhw3Hb @¤ ’ ™& JØ¢»½½½Ö–†äÐ ø|hPýg?ûÙÚ|’$=Ï7¸\î©S§ø|~IIIÞÅõJyt€Ùu––Š^xá ŠÒ7mRÜ“nÓ“¦íc.VÔµt[x ž­ßF¤ùº¡#xŸ=7KfI÷¸›Åg-ßZ-…d J=;»i“ª«Ëd³Eôz1u/^Ä0Ìãñ¤R)Ç300PRRÂ`0H’¼~ýz(J$ƒƒƒ<ïÆ$I†Ãa¸-rçμ£º€¯òÈ£/ûÙˆ¾T— Óé2™L*•êêê™™™ÖÖÖµeÂH’d2™CCC©TŠÏç766êõ¼?þÑ/c••Ò'Ÿ¼[)LݪV·ªîq·¨L”§Iœ .YB–åK6™ ™CASÁfà)\^#_|‘¯æ/ßZ®ù°€@ÀŠÅ2‰DöÒ¥y‚ öï×R©ÔÒÒRccãääd(Òëõ$IÂA©TêìÙ³uuu;wî„âvýýý4-“É<óÌ3±X¬`ßä‘GÿpÿwÝ"y¯¾új,Ójµv»Åb噃›*•ª¸¸X¡PPuë–mnÎ?=í‘J16{µ¯"(0Ø ¶˜I1&›É°YVÔEyhQ]‘%è,ºí¶MV-£JZõ±r¼fshjÊsã†Y¥â+¼\0 [\\,--e±Xjµzaa!‰¼öÚk^¯wvvA‹%“É***ºººpW*•(Š’$¹^Œw_{‹äÝ/ ´VH$}%WØÕÕµiÓ&™L¶òÃl6›óТÑhgggsss^y‹¾ÞØHý>Y Dè±Ç[ûáÊ\>Ÿøðá‚)X h·$Anä­:z½@·BQ·Æ ?4Ýü,Æêìì”Ëå×®];}úô®]»ò>bWɣ筥÷a›d¿íر‰šùòräÂ…¹înó¶mwTÜnw €SJ,[^^¦Óé°5¿ßo³ÙD"Ñââb&“ …B¡Pˆ¢(–H$~þóŸoÛ¶-‡ÃaÇétz,³X,, æA{<§Ó)p÷ûýÑh™J¥ ªÅåË—KJJÂá°ÃáÀ0lvv¶§§‡Ëåf³ÙT*E’$Žã¯½öZccãâùEïŒW^ó± „%”‰ghtZØŽ{ãþ9?ÊCcŽ˜ñ´Q¨Æ=ñt8Ýÿ_ýÚ]Úßý×ïÚÚÚ®_¿ÞÙÙ¹eË–‚i~9H$«±s¶ÀF,ƒÁØ·o_8Öh4ºÿNôôX._^ Óiÿú¯ïÛl‘ù—]wîxrÿ{òäÉææf‡Ã‹Å¹yóæ‹/¾W6›íäÉ“‡>uêÔ³Ï>{õêÕP(ÔØØÈf³¹\nQQ‘T*ýÃþ°cÇŽp8L›Í¾~ýúßÿýßóù|€Õj=uêÔ÷¿ÿýsçÎ:th``ÀçóéõzX°¦¦‚ .\¸€aصk×***œNçÑ£G…Bá¡C‡Þ{ï½çŸ>b¦D ÒD6™e XÉ@“bÆÓF”‹¢|P€#åLŸœny±%l §#éÁWñ$¾ãïØòÓ-4:M¡PÌÍÍÕÕÕÍÏÏìòKÃ*ÿ|¥ç’ßJ¥RøÃŽã³³³uuuë-®×&ů&“–Hd ø|ÖŽ%r9gfÆëñÜÍyߺukwwwkkëùóç7oÞ\WW788899yûöíáááòòòD"QQQ¡ÑhpO§ÓÛ·oï½÷ ù¯_¿~½½½ýÂ… £££CCC¥¥¥©TªªªJ¥Re2™t:½oß¾÷Þ{O¯×?~<Çãñ¹¹9Eu:F ‡Ã‚”••uttƒA‡“N§ác X,+ÏDlФ‚¦ ER<å¡4:-Ï t¤¨®(h fY'yJ^Å –Å-â¤R©¼ K|U4h~ˆ ÇC’¤B¡Èd2'o»kc„Báz ÊíŽq8Lƒ ¥T*¾Û“H06›‚$‰¾¾¾§žzÊív‹ÅbŠ¢H’Ìf³±XL.—Ã’•gÏžõù|/¼ðB H$¯¿þúO}:ÿð‡?„_B¡Ðçó1 6›Í`0(Š …B</NÃfY,t“üñ¼>^6žÐ´T(ųð4ާqƒFgÒá.8¼?ï¾ûî‘#GúûûÓéôÞ½{ ¦ùå _,‘°ïÛ³ëkBƒPÀW@ƒäÑ x] Š¢ˆiPǯ\¹rüøqŸÏ÷öÛoŸ9sæKîñôôºÊSgΜ¹víš}À>w~î£!nMŸüØE’”©Ëßûf}ak¾7_7/][š™™9zôhÞö3±ÌðÑád 9ø¾<¾`C_§EðÊuðº,У>ú׿þ5™L:ÎP(´½zïIñÙlö¿ÿû¿ Œ°øÖ·¾˜››{óÍ7!ÿ“H$6oÞ,•J½^ïÈÈHmmíïÿ{N§P(FFFvíÚõÆo´µµÅãñ––C€I1ÏÏä;“š6 ¥eÙ™“3áåpéÞÒ…Ë ¢RQÄI†’DšˆØ#B­Ðóÿ<ºÝ:y­ Ô Oœ8; =*“ÉžþyFGéš­&—).“YR\..ÐÃÇWÒ ‚0>œhëù6—.]ª©©‰Åb­­­pE¸ö°Oµ–Éd”J%A{öì1™LAtww»\®mÛ¶555éõú¦¦¦÷Þ{¯¹¹Y­Vg2¹\~èС`0ØÜ܇ÛÚÚrC™¯âKÊ%[¤t©¤RµG}FBC´íÚT0%Ö‹ñ$h€Hd–TÔ+bΘþ½´J*Ô …ZáÚÁ™ÓH¥£te³’ÁbYOáy/àa§As†›H§Ó(Š.//ïÝ»7‰ìÚµk¥¸îʆî} Àår«««‹ŠŠ‚ÁàîÝ»ár¹---===(ŠîܹPTTtäÈ.—«T*­V+Ü}Û·oßÀÀÀ¶mÛ<`ddÄd2ÁðìòŽò¥ëKl»õÇ­¡¥Eg` A¼Ó^q™˜ÈEQ8¶…›Ôìv2°»×;;;›‹…‹Å¿üå/×^[ÈŽØ#"}aYÿu[€O¤Aï+åÑ!6 A?/$IQÔ½W®ÿâ)àaÁ4è}±@+MÿK‹ Ê+dô•4RÀŸ?11qçÎx<ÞÛÛ+‰ÆÆÆaNãòòr¿P(ìììDäèÑ£ ™L.--iµÚ“'Oæç竪ªnw¬»ÛRS#õÕ……€Ó½reQ"ÁŽŸDÐÕešžö^½j:uʸgEéËËËG-//¿yóf6› …üã«««¯]»f6›ÇÐÐV«½}ûvMMÍ©S§ZZZFGG'''Qíêêb0¯¼òJqq±ÅbI&“0·Çãuuuy½ÞÒÒÒ‚¥~AÈf³+½ Š¢f,^&Õ—êhëùL†±X¬X,&‘HPÍ[F`- Ù®]Ú’á쬯½]wê”1Ï\¹²89éqæÛt:}tt´­­íÖ­[‘Hdii‰N§Óh4½^¿}ûv Ãà…G!‹C¡Ífëïïw¹\Z­öÒ¥K­­­ããã0)Y*•f2™þþþŽŽŽH$‚ãx___SSÔAñz½>ŸËåúýþ\lŸ\Î “ápª·wyhÈqó¦•ÇC_yå6‡Ã|牡!GGGy[›fûöç®ÀD$R+l6Ûf³á8~ãÆ`0È`0nݺµuëV8ž —ËŒŽŽ>úè£~¿Ÿ ˆÑÑÑÆÆFƒÁPZZ +++»»»‰„Ãá(˜é—‹ “âÃáð|Ëdôõõ‰D"ƒÁ°¶µIñL&êñÄ•NgtçNm 4™‚[·³ÙŒ²2qY™~++Љ‰‰–––h4j0ü~¿ÏçÛ¹sçÀÀ€^¯ûí·‹‹‹åry(R«Õ]]]=öI’V«5‹I¥Ò¹¹¹†††l6‹ã¸Ñh …BÚŸ×ë …"‘( †Ãá‘‘‘ÖÖÖ[·nUUUq¹\K~ÌÌø®^5aAN‹e¬ÖÈÓO×÷ôXöì)åp˜ííZ&“~ùòÂÖ­Å(JO&“ƒannN(NLLhµÚƒ†Ãa£Ñ­Ífkkks:,k||AEa2~(’ËåðFY,–ÙÙYÕÜÜÌd2s]*à‹@2™\•?oÐ3}©îs‹ºÿŒ0¿ß/•JóþW0pknnž™™Ñëõë‰P$ù‚®^5íÜ©…)šŸˆ@ ‹áµÃ.Á× ÜÐBüÅW…p8¼2š“$ɳ½FÖýÇ}¾4èzÖ‹? ʇF–K‡Ï‹Ïfj<ò)žÁ‰dU—6°~Pˆ>zÐhPrC”$I—Ë )Š ƒkY¤ ZÀC„µ¥P?ÅqÜét¾ûî»@àµ×^‹D"÷Hƒîuâ‚wM•ÈOˆEQª’ðx¼¦¦¦ üÚÂNp ôÉÑ ápxbb7F+w_W䟄Báw¿û]øþÀ,ì–Jñ|Ã×+¥Â¡Ó7\|fתp¯ x‘7fçó+µA¿èËX^Žà8Yø9 ¸Ï5X”'8™L^½zõÆæý÷ß«¯¯Ïã?}X$/·öù2/¾x¦±Q‘Lf“Iœ$)¯7‘É^oœÅb0™4ÀñãÇ'''¹\î¿ÿû¿oÙ² ¾ñÆCCCƒÁív£(úæ›oÆãq±X‡aLA&Ctv.”•I\®h<ž!IÊã‰cÓáñÛ«b(IDATˆÑh JI£ÑíÚRMœN§QõÛßþvxxX"‘¤Ói‹åv»étz €I~¿ŸF£9NEÝnw:†'‚ˆÅb—/_^ZZb2™ÉdÃ0§Ó ˆD"ét:‹ÍÎÎ* ‡ÃÁb±ü~*•ZOAµ€¯«v‚)Šš·ùÙèºòè† †ùùy±X¼ÿþ+W®ÜËÌp¹bl6S `ýÃ?\ø§ÚzõêR(”d±óóþ^hyâ †m–••544ä6¿êêê0 »yó¦Ë媨¨ðù|8}út"‘øÑ~Äb±2¢»Û²k—î…ΊDìmÛŠ]®Xq±`nÎ/•b^o¢½]K£!cc®C‡jP”>w¹xñb]]]MMÍ… (ŠBQÔï÷k4¥RY^^~üøq‰D299YSSóÓŸþ4w!\.7‹1>>ž}öÙË—/9räøñãßùÎw0 [^^–Ëå7nÜàp8f³™ÏçÿøÇ?.˜Úƒ‰µ¾:ò! ºn‘¼H$Âáp,ËŸþô§†††¼‡­•G/- 2©”c0Èöï×SE§Ó¸\¦ZÍO$²¹ÆS©T °Ùl‰DââÅ‹Á`ÐétšÍfƒQWWGQTII‰J¥‚ì}2‰g2„Ñè“H0€…ã$†I£!$IÉdœ§žªÙ²E¢ôÜ–«Z­~饗4ÍîÝ»9l*×àÞ½{gffš››#‘ˆX, …étúôéÓ¹{Äãñ †T*}òÉ'E"QSSSqqñþýû¯_¿NQ”ÓéÌd2t:$IF# vö°¸@E}‚.Žã6›Ãá°Ùl§ÓÉf³u:ÝÚvQåp8+÷¸\~ ”Ë9.W\¥âƒ©`0)²“É,‡ŠDl¬¼Íf³‡^¯‡ÃR©Ôápà8®P( Ie³YÊ–H$4 I›Í!¡B§#gΛš”›7«íö¨TŠ¥RxQ07ç×ëE, ¡­Ób±ˆÅâóçÏÇãñ#GŽˆD¢D"a±X$ EQ,+™LNNN>þøã9/Êù|¾âââl6Ëår———¹\.Žã‘HD§ÓÙív¥R s ÊØ,¢ÑèJˆ$ÉÓ7g°¤£ ^À7È£#hÐx<[0‚o2òT‰Ü˜M¥RgΜ±ÛígΜéíí½G4•Âÿã?zl¶È½¹råÊ•+WL&Ó¯ýk¿ß?ìììÌùßÑhôرck¿ØÝÝMQÔŋϟ?ÿiF)¸panãc®\YÌdî:…‘Hä7Þ˜™™ß¾}{mO~¿ÿÍ7ßü Õ¾~÷»ßõöö&‰µÿe·Ûß~ûí\:åÕ«WçææòžÝb±¼óÎ;6›­`ߟv¬¤Aëù6UUUçÎ;pà€T*]^^^Zµ|󦵯Ïú7ÓpèЉï}¯Îáˆ>µš?6æzé¥¶ŽŽrüÍ:::”JeŽZ^^6 ð÷6 t:¢¨¿üå/KKKÛ¶m3™LGŽ9}ú´Ûí…B Édò±Ç{ùå—>ÜÝÝÍb±”J¥ÉdúÛ¿ýÛW_}uÛ¶m‡|ðelÌÅdÒÞ~{¢½];=í¥ÑÍ›Õ##ÎC‡j^yåösÏ5¿þú°ÇÿÁ¡ëFE"Ño~ó‰Dòío{ddÄn·Ÿ8q¢¥¥ebbbûöí&“illlçÎñxœN§ÿéOjii1‚(о¾>˜­¦T*i4šÏç{ñÅW®’Nç7„BaOOÁ`èëëS«Õ©T* 8p “É‚û·+..Þ±cG(š››;}úô¾}û®]»vðàÁééé¾¾¾Ç{Œ ˆt:ýú믷··÷ööòx<‘H4<<¼yóæááaƒÁàõzC¡Ð/~ñ‹oø bUBÌ'ìg2•J%‰@[[[0¼G´¹YÙÞ®+)TUI¿ÿý›-R\,ˆÇ3*ÏçKäuœÆÇÇãñøáÇïܹ‡ÛÛÛa½T‚ Âáp"‘0 ÃçóµµµqäÈ‘±±1³Ù +v577×ÕÕ!²cÇ—˵ÿ~‡³yóæ\rý¦Mªh4N:(N34±»yÓº}{‰Éܾ½äðáÚ¶6Í#èáñ2™ìðáÃ/^‰DeeeÑh” £ÑØÐÐ`±XvïÞm4Ùlö¦M›¤RéOÛØÚªÆÚÚÚùùùžžt©oܸ(++›ššª¬¬„£v~~¾¡¡affò*‹‹‹{öìéììÜ»wïÄÄ„Ñh¬««›žžÖh4PjellÌjµ>þøãÝÝÝl6{ff†Á`ä–ò~¿Ÿ$Ék×®=õÔSCCC°ôXoo¯^¯?yòäÓO?Íf³-‹Z­>qâD}}ýÌÌ ›Í~úé§ËËa£ÑçvÇó››eeb‘ˆ=?xòIéSƽ{K{{­Z­Ðl©ßþ¶Ã@Àï÷óùüááá‘‘¹\žL&%ɱcÇ*++ÏŸ?ïv»›šš¦§§ ”»»téR8îèèèíímhh8wîœR©„¬Ô¬Vkkkëûï¿_YYyùòe:^^^>88XUUõç?ÿù'?ùÉüü¼N§K&“×®]Û¾}ûåË—«ªª,ËóÏ? ÈÐÐü)+++OŸ>ãxEEÅÐÐPmmíéÓ§_zé%­VûͤAië=Ú …@ èîî y=œUIñE56*vïÖiµB yòÉš[·–E"öø¸+ÏÌÍÝ¥ü‹‹‹!÷µ®"‘ÈÿüÏÿ8N‹Å¢Õja¨œ×ëÅq\«ÕVWW÷õõL&sðàÁ÷Þ{O­Vg³Y¿ß___öìÙŽŽŸÏ;ÐÛÛË`0¼^o èëë#Zɾ}ûfgga B¡ IÒh48pÀårá8>99ÙÔÔÔÐÐPYY‡¡HÛÌÌ “ÉÌÝ&•ŠŸÉápÚnºÝñùy¿^/:vl¢¾¾èâÅùH$ýÜsÍ{ö”îÛWšSU©®®.))éííµZ­z½¾¾¾þܹsp=‰D Åèèèþýûív;<¾··—$Éùùy6›ÝÓÓÃf³étºÃáØµk×ÔÔ ãƒê‡cÿþýf³*j555•••étºT*µ¸¸Ç•T*…ÜL胱pŸ¾··Çñp8ÜÔÔ”Édššš¾ÞÖò%Å碃ò³@‰DÕ=öXSSŸÏW«Õy' û†mVTH’I¼®®ˆÉ¤ùýÉöv­LÆ©¬”j4¸µ‰D>,•Ja¼ªª*¡Pèõzy<ÞÜÜœ^¯ïëëS©TSSS!•J¥¥¥¥ÝÝÝ•••'hµZ‰DRZZÚÛÛ‹ HkkëôôtCCC4åóù?þ8‹ÅZXX€ mP¯Š¢¨T*e±X"‘Hee%Œ”†æ.‘H 2—Édjnnß´i“@ H$0izÚ;3ããp˜EEÜêj©Ã£(ê‡?lq)))-H¥ØÈˆ“ËEOŸžÑëÅ.WŒËeþùÏdU•Ôl^¹²øòËûh4D©äÃãFs»Ý@­VÆ®®.EGFF~ðƒ•JuáÂ…²²2Aÿîïþ®`:_86»Ý¶ÂnI”É 6GŸžžFD­Và ۼ¡k™‘ˆ-“q0Œ©Ó‰jkåËéŒÉd‰„Ë:P hvvFÚF‡322b³Ù¦§§c±X<÷x<0ŽW¥Ri4µZ ‹¢ÂF†‡ãã.³9K¯¦R¸×›(/—LNzärne¥´ºZZV&v|èe% ,_·¸¸800Àb±p/))(ŠšL&>ŸíÚµƒ¢ x!‰›rÿôe™ì]¡ü¡0%A:ÓÉò€¼º@AÒé4øJ’AP4¬3p·,Žã¹–W¶O|e0ð=\$ä>Äq<{‡ã$IR°A’¤^}ø…ZX,:Ž“ $?:;$¥( ž.wuA°Ùl" )†ãx2™koo/TõúÚàöÀpeÕGeN½^ϹÞ;åb°nF‚ ¹à¡O› 7™ákÎèøh¹¼ªåœgÿ„f·ò}îÍJŒÁø˜uþô§m.KèùÎYùõ\4,N¹1™L&“¹{÷î‚Ñ|ÍÁ33Ó?ûéOhtú+xmåêŽq/_^ð)Р<,@­V¿ôOÿ‹Á`*•Êh4ò  ™Lvww{<¯¿¼¼üóŸÿüiÐ x@:Þ±£N§qœø„“GW(555ëe ­Æ* €™tÒ¶lýèÏLZ(þh`gíÝØØX]]¢¨@ `2™yökMU*z<hllÈf?Ò‡¥Ñh±I;ˆ®’ÇŸ‚ºŸJÏ£0ð‚F£­gƦ¯€oöØ(Ü‚  €  €¾y`ŠÄ<³/å6nGßà$Ŧ!†H$ZZZ’R*V¸-|SÀ¦!Š"9Y¯øÅ—€P($‰r¯B¡0‰ðx¼D"aX*•b±X™L†ÉdæôÝaÈŒËf³(ŠÂ Õñx*¥ ‚p8¼²Ù•óùüX,Æårá)Òé4l–¦ÌmkÐétØx:f³ÙÉdž‚Ïççm¼Ðÿµ¥Øü q.3þÇ©GIEND®B`‚eric-6.0.8/eric/Plugins/ViewManagerPlugins/__init__.py0000644000175000017500000000024312451233371021746 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the various view manager plugins. """ eric-6.0.8/eric/Plugins/ViewManagerPlugins/Listspace/0000755000175000017500000000000012451302716021565 5ustar piotrpiotreric-6.0.8/eric/Plugins/ViewManagerPlugins/Listspace/__init__.py0000644000175000017500000000024412451233371023676 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the listspace view manager plugin. """ eric-6.0.8/eric/Plugins/ViewManagerPlugins/Listspace/Listspace.py0000644000175000017500000006716612451302716024106 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the listspace viewmanager class. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal, QFileInfo, QEvent, Qt from PyQt5.QtWidgets import QStackedWidget, QSplitter, QListWidget, \ QListWidgetItem, QSizePolicy, QMenu, QApplication from ViewManager.ViewManager import ViewManager import QScintilla.Editor from QScintilla.Editor import Editor import UI.PixmapCache class StackedWidget(QStackedWidget): """ Class implementing a custimized StackedWidget. """ def __init__(self, parent): """ Constructor @param parent parent widget (QWidget) """ super(StackedWidget, self).__init__(parent) self.editors = [] def addWidget(self, assembly): """ Public method to add a new widget. @param assembly editor assembly object to be added (QScintilla.EditorAssembly.EditorAssembly) """ editor = assembly.getEditor() super(StackedWidget, self).addWidget(assembly) if editor not in self.editors: self.editors.append(editor) def removeWidget(self, widget): """ Public method to remove a widget. @param widget widget to be removed (QWidget) """ if isinstance(widget, QScintilla.Editor.Editor): self.editors.remove(widget) widget = widget.parent() super(StackedWidget, self).removeWidget(widget) def currentWidget(self): """ Public method to get a reference to the current editor. @return reference to the current editor (Editor) """ widget = super(StackedWidget, self).currentWidget() if widget is not None: widget = widget.getEditor() return widget def setCurrentWidget(self, widget): """ Public method to set the current widget. @param widget widget to be made current (QWidget) """ if isinstance(widget, QScintilla.Editor.Editor): self.editors.remove(widget) self.editors.insert(0, widget) widget = widget.parent() super(StackedWidget, self).setCurrentWidget(widget) def setCurrentIndex(self, index): """ Public method to set the current widget by its index. @param index index of widget to be made current (integer) """ widget = self.widget(index) if widget is not None: self.setCurrentWidget(widget) def nextTab(self): """ Public slot used to show the next tab. """ ind = self.currentIndex() + 1 if ind == self.count(): ind = 0 self.setCurrentIndex(ind) self.currentWidget().setFocus() def prevTab(self): """ Public slot used to show the previous tab. """ ind = self.currentIndex() - 1 if ind == -1: ind = self.count() - 1 self.setCurrentIndex(ind) self.currentWidget().setFocus() def hasEditor(self, editor): """ Public method to check for an editor. @param editor editor object to check for @return flag indicating, whether the editor to be checked belongs to the list of editors managed by this stacked widget. """ return editor in self.editors def firstEditor(self): """ Public method to retrieve the first editor in the list of managed editors. @return first editor in list (QScintilla.Editor.Editor) """ return len(self.editors) and self.editors[0] or None class Listspace(QSplitter, ViewManager): """ Class implementing the listspace viewmanager class. @signal changeCaption(str) emitted if a change of the caption is necessary @signal editorChanged(str) emitted when the current editor has changed @signal editorChangedEd(Editor) emitted when the current editor has changed @signal lastEditorClosed() emitted after the last editor window was closed @signal editorOpened(str) emitted after an editor window was opened @signal editorOpenedEd(Editor) emitted after an editor window was opened @signal editorClosed(str) emitted just before an editor window gets closed @signal editorClosedEd(Editor) emitted just before an editor window gets closed @signal editorRenamed(str) emitted after an editor was renamed @signal editorRenamedEd(Editor) emitted after an editor was renamed @signal editorSaved(str) emitted after an editor window was saved @signal editorSavedEd(Editor) emitted after an editor window was saved @signal checkActions(Editor) emitted when some actions should be checked for their status @signal cursorChanged(Editor) emitted after the cursor position of the active window has changed @signal breakpointToggled(Editor) emitted when a breakpoint is toggled. @signal bookmarkToggled(Editor) emitted when a bookmark is toggled. @signal syntaxerrorToggled(Editor) emitted when a syntax error is toggled. @signal previewStateChanged(bool) emitted to signal a change in the preview state @signal editorLanguageChanged(Editor) emitted to signal a change of an editors language @signal editorTextChanged(Editor) emitted to signal a change of an editor's text @signal editorLineChanged(str,int) emitted to signal a change of an editor's current line (line is given one based) """ changeCaption = pyqtSignal(str) editorChanged = pyqtSignal(str) editorChangedEd = pyqtSignal(Editor) lastEditorClosed = pyqtSignal() editorOpened = pyqtSignal(str) editorOpenedEd = pyqtSignal(Editor) editorClosed = pyqtSignal(str) editorClosedEd = pyqtSignal(Editor) editorRenamed = pyqtSignal(str) editorRenamedEd = pyqtSignal(Editor) editorSaved = pyqtSignal(str) editorSavedEd = pyqtSignal(Editor) checkActions = pyqtSignal(Editor) cursorChanged = pyqtSignal(Editor) breakpointToggled = pyqtSignal(Editor) bookmarkToggled = pyqtSignal(Editor) syntaxerrorToggled = pyqtSignal(Editor) previewStateChanged = pyqtSignal(bool) editorLanguageChanged = pyqtSignal(Editor) editorTextChanged = pyqtSignal(Editor) editorLineChanged = pyqtSignal(str, int) def __init__(self, parent): """ Constructor @param parent parent widget (QWidget) """ self.stacks = [] QSplitter.__init__(self, parent) ViewManager.__init__(self) self.viewlist = QListWidget(self) policy = self.viewlist.sizePolicy() policy.setHorizontalPolicy(QSizePolicy.Ignored) self.viewlist.setSizePolicy(policy) self.addWidget(self.viewlist) self.viewlist.setContextMenuPolicy(Qt.CustomContextMenu) self.viewlist.currentRowChanged.connect(self.__showSelectedView) self.viewlist.customContextMenuRequested.connect(self.__showMenu) self.stackArea = QSplitter(self) self.addWidget(self.stackArea) self.stackArea.setOrientation(Qt.Vertical) stack = StackedWidget(self.stackArea) self.stackArea.addWidget(stack) self.stacks.append(stack) self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) self.setSizes([int(self.width() * 0.2), int(self.width() * 0.8)]) # 20% for viewlist, 80% for the editors self.__inRemoveView = False self.__initMenu() self.contextMenuEditor = None self.contextMenuIndex = -1 def __initMenu(self): """ Private method to initialize the viewlist context menu. """ self.__menu = QMenu(self) self.__menu.addAction( UI.PixmapCache.getIcon("tabClose.png"), self.tr('Close'), self.__contextMenuClose) self.closeOthersMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("tabCloseOther.png"), self.tr("Close Others"), self.__contextMenuCloseOthers) self.__menu.addAction( self.tr('Close All'), self.__contextMenuCloseAll) self.__menu.addSeparator() self.saveMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("fileSave.png"), self.tr('Save'), self.__contextMenuSave) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAs.png"), self.tr('Save As...'), self.__contextMenuSaveAs) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAll.png"), self.tr('Save All'), self.__contextMenuSaveAll) self.__menu.addSeparator() self.openRejectionsMenuAct = self.__menu.addAction( self.tr("Open 'rejection' file"), self.__contextMenuOpenRejections) self.__menu.addSeparator() self.__menu.addAction( UI.PixmapCache.getIcon("print.png"), self.tr('Print'), self.__contextMenuPrintFile) self.__menu.addSeparator() self.copyPathAct = self.__menu.addAction( self.tr("Copy Path to Clipboard"), self.__contextMenuCopyPathToClipboard) def __showMenu(self, point): """ Private slot to handle the customContextMenuRequested signal of the viewlist. @param point position to open the menu at (QPoint) """ if self.editors: itm = self.viewlist.itemAt(point) if itm is not None: row = self.viewlist.row(itm) self.contextMenuEditor = self.editors[row] self.contextMenuIndex = row if self.contextMenuEditor: self.saveMenuAct.setEnabled( self.contextMenuEditor.isModified()) fileName = self.contextMenuEditor.getFileName() self.copyPathAct.setEnabled(bool(fileName)) if fileName: rej = "{0}.rej".format(fileName) self.openRejectionsMenuAct.setEnabled( os.path.exists(rej)) else: self.openRejectionsMenuAct.setEnabled(False) self.closeOthersMenuAct.setEnabled( self.viewlist.count() > 1) self.__menu.popup(self.viewlist.mapToGlobal(point)) def canCascade(self): """ Public method to signal if cascading of managed windows is available. @return flag indicating cascading of windows is available """ return False def canTile(self): """ Public method to signal if tiling of managed windows is available. @return flag indicating tiling of windows is available """ return False def canSplit(self): """ public method to signal if splitting of the view is available. @return flag indicating splitting of the view is available. """ return True def tile(self): """ Public method to tile the managed windows. """ pass def cascade(self): """ Public method to cascade the managed windows. """ pass def _removeAllViews(self): """ Protected method to remove all views (i.e. windows). """ self.viewlist.clear() for win in self.editors: for stack in self.stacks: if stack.hasEditor(win): stack.removeWidget(win) break win.closeIt() def _removeView(self, win): """ Protected method to remove a view (i.e. window). @param win editor window to be removed """ self.__inRemoveView = True ind = self.editors.index(win) itm = self.viewlist.takeItem(ind) if itm: del itm for stack in self.stacks: if stack.hasEditor(win): stack.removeWidget(win) break win.closeIt() self.__inRemoveView = False if ind > 0: ind -= 1 else: if len(self.editors) > 1: ind = 1 else: return stack.setCurrentWidget(stack.firstEditor()) self._showView(self.editors[ind].parent()) aw = self.activeWindow() fn = aw and aw.getFileName() or None if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) def _addView(self, win, fn=None, noName=""): """ Protected method to add a view (i.e. window). @param win editor assembly to be added @param fn filename of this editor (string) @param noName name to be used for an unnamed editor (string) """ editor = win.getEditor() if fn is None: if not noName: self.untitledCount += 1 noName = self.tr("Untitled {0}").format(self.untitledCount) self.viewlist.addItem(noName) editor.setNoName(noName) else: txt = os.path.basename(fn) if not QFileInfo(fn).isWritable(): txt = self.tr("{0} (ro)").format(txt) itm = QListWidgetItem(txt) itm.setToolTip(fn) self.viewlist.addItem(itm) self.currentStack.addWidget(win) self.currentStack.setCurrentWidget(win) editor.captionChanged.connect(self.__captionChange) editor.cursorLineChanged.connect(self.__cursorLineChanged) index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def __captionChange(self, cap, editor): """ Private method to handle caption change signals from the editor. Updates the listwidget text to reflect the new caption information. @param cap Caption for the editor (string) @param editor Editor to update the caption for """ fn = editor.getFileName() if fn: self.setEditorName(editor, fn) def __cursorLineChanged(self, lineno): """ Private slot to handle a change of the current editor's cursor line. @param lineno line number of the current editor's cursor (zero based) """ editor = self.sender() if editor: fn = editor.getFileName() if fn: self.editorLineChanged.emit(fn, lineno + 1) def _showView(self, win, fn=None): """ Protected method to show a view (i.e. window). @param win editor assembly to be shown @param fn filename of this editor (string) """ editor = win.getEditor() for stack in self.stacks: if stack.hasEditor(editor): stack.setCurrentWidget(win) self.currentStack = stack break index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def __showSelectedView(self, row): """ Private slot called to show a view selected in the list. @param row row number of the item clicked on (integer) """ if row != -1: self._showView(self.editors[row].parent()) self._checkActions(self.editors[row]) def activeWindow(self): """ Public method to return the active (i.e. current) window. @return reference to the active editor """ return self.currentStack.currentWidget() def showWindowMenu(self, windowMenu): """ Public method to set up the viewmanager part of the Window menu. @param windowMenu reference to the window menu """ pass def _initWindowActions(self): """ Protected method to define the user interface actions for window handling. """ pass def setEditorName(self, editor, newName): """ Public method to change the displayed name of the editor. @param editor editor window to be changed @param newName new name to be shown (string) """ if newName: currentRow = self.viewlist.currentRow() index = self.editors.index(editor) txt = os.path.basename(newName) if not QFileInfo(newName).isWritable(): txt = self.tr("{0} (ro)").format(txt) itm = self.viewlist.item(index) itm.setText(txt) itm.setToolTip(newName) self.viewlist.setCurrentRow(currentRow) self.changeCaption.emit(newName) def _modificationStatusChanged(self, m, editor): """ Protected slot to handle the modificationStatusChanged signal. @param m flag indicating the modification status (boolean) @param editor editor window changed """ currentRow = self.viewlist.currentRow() index = self.editors.index(editor) keys = [] if m: keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") self.viewlist.item(index).setIcon( UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) self._checkActions(editor) def _syntaxErrorToggled(self, editor): """ Protected slot to handle the syntaxerrorToggled signal. @param editor editor that sent the signal """ currentRow = self.viewlist.currentRow() index = self.editors.index(editor) keys = [] if editor.isModified(): keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") self.viewlist.item(index).setIcon( UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) ViewManager._syntaxErrorToggled(self, editor) def addSplit(self): """ Public method used to split the current view. """ stack = StackedWidget(self.stackArea) stack.show() self.stackArea.addWidget(stack) self.stacks.append(stack) self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) if self.stackArea.orientation() == Qt.Horizontal: size = self.stackArea.width() else: size = self.stackArea.height() self.stackArea.setSizes( [int(size / len(self.stacks))] * len(self.stacks)) self.splitRemoveAct.setEnabled(True) self.nextSplitAct.setEnabled(True) self.prevSplitAct.setEnabled(True) def removeSplit(self): """ Public method used to remove the current split view. @return flag indicating successfull removal """ if len(self.stacks) > 1: stack = self.currentStack res = True savedEditors = stack.editors[:] for editor in savedEditors: res &= self.closeEditor(editor) if res: try: i = self.stacks.index(stack) except ValueError: return True if i == len(self.stacks) - 1: i -= 1 self.stacks.remove(stack) stack.close() self.currentStack = self.stacks[i] if len(self.stacks) == 1: self.splitRemoveAct.setEnabled(False) self.nextSplitAct.setEnabled(False) self.prevSplitAct.setEnabled(False) return True return False def getSplitOrientation(self): """ Public method to get the orientation of the split view. @return orientation of the split (Qt.Horizontal or Qt.Vertical) """ return self.stackArea.orientation() def setSplitOrientation(self, orientation): """ Public method used to set the orientation of the split view. @param orientation orientation of the split (Qt.Horizontal or Qt.Vertical) """ self.stackArea.setOrientation(orientation) def nextSplit(self): """ Public slot used to move to the next split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.stacks.index(self.currentStack) + 1 if ind == len(self.stacks): ind = 0 self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() index = self.editors.index(self.currentStack.currentWidget()) self.viewlist.setCurrentRow(index) def prevSplit(self): """ Public slot used to move to the previous split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.stacks.index(self.currentStack) - 1 if ind == -1: ind = len(self.stacks) - 1 self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() index = self.editors.index(self.currentStack.currentWidget()) self.viewlist.setCurrentRow(index) def __contextMenuClose(self): """ Private method to close the selected editor. """ if self.contextMenuEditor: self.closeEditorWindow(self.contextMenuEditor) def __contextMenuCloseOthers(self): """ Private method to close the other editors. """ index = self.contextMenuIndex for i in list(range(self.viewlist.count() - 1, index, -1)) + \ list(range(index - 1, -1, -1)): editor = self.editors[i] self.closeEditorWindow(editor) def __contextMenuCloseAll(self): """ Private method to close all editors. """ savedEditors = self.editors[:] for editor in savedEditors: self.closeEditorWindow(editor) def __contextMenuSave(self): """ Private method to save the selected editor. """ if self.contextMenuEditor: self.saveEditorEd(self.contextMenuEditor) def __contextMenuSaveAs(self): """ Private method to save the selected editor to a new file. """ if self.contextMenuEditor: self.saveAsEditorEd(self.contextMenuEditor) def __contextMenuSaveAll(self): """ Private method to save all editors. """ self.saveEditorsList(self.editors) def __contextMenuOpenRejections(self): """ Private slot to open a rejections file associated with the selected editor. """ if self.contextMenuEditor: fileName = self.contextMenuEditor.getFileName() if fileName: rej = "{0}.rej".format(fileName) if os.path.exists(rej): self.openSourceFile(rej) def __contextMenuPrintFile(self): """ Private method to print the selected editor. """ if self.contextMenuEditor: self.printEditor(self.contextMenuEditor) def __contextMenuCopyPathToClipboard(self): """ Private method to copy the file name of the selected editor to the clipboard. """ if self.contextMenuEditor: fn = self.contextMenuEditor.getFileName() if fn: cb = QApplication.clipboard() cb.setText(fn) def __currentChanged(self, index): """ Private slot to handle the currentChanged signal. @param index index of the current editor """ if index == -1 or not self.editors: return editor = self.activeWindow() if editor is None: return self._checkActions(editor) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) if not self.__inRemoveView: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) cindex = self.editors.index(editor) self.viewlist.setCurrentRow(cindex) def eventFilter(self, watched, event): """ Public method called to filter the event queue. @param watched the QObject being watched @param event the event that occurred @return flag indicating, if we handled the event """ if event.type() == QEvent.MouseButtonPress and \ not event.button() == Qt.RightButton: switched = True if isinstance(watched, QStackedWidget): switched = watched is not self.currentStack self.currentStack = watched elif isinstance(watched, QScintilla.Editor.Editor): for stack in self.stacks: if stack.hasEditor(watched): switched = stack is not self.currentStack self.currentStack = stack break currentWidget = self.currentStack.currentWidget() if currentWidget: index = self.editors.index(currentWidget) self.viewlist.setCurrentRow(index) aw = self.activeWindow() if aw is not None: self._checkActions(aw) aw.setFocus() fn = aw.getFileName() if fn: self.changeCaption.emit(fn) if switched: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) return False eric-6.0.8/eric/Plugins/ViewManagerPlugins/Listspace/preview.png0000644000175000017500000005754012060166053023765 0ustar piotrpiotr‰PNG  IHDR1úF_çübKGDÿÿÿ ½§“ pHYs  šœtIMEÖ 2 •¥_e IDATxÚì½wt\×u.~n›z§÷Aï$ØI(š”)QÍ’K¶žœÄV¬<Çq’—·’eÇë%yË/yZ¶“§çúÓz’¢¸I²UH‰]`o €è½ 0ƒÁ`0½Þ¹wnýýq) ÀN ¨û-..Ìígfï»÷>ç;ߺ»»çææP…APœ‹hþ.‚"(€ A€ @0D(`ÀV5ð™A2™L§Ó Je}m%ÇwïÞ­Ñhnä Ã`&þͲìÝóä¾¾>†aPõÌÇv®±W™—{E!Êã(Šã¸èÞ‚Þyçµ\"‘ÅGòCðu‰çùÜsWx§ˆOÅr, ÃâõyžçC°¥Wþø”@¹ l“,õ3š¦Û;:KJʶø|ÞžÙôõmÑçóŒŒ$‰ÁÁÁÎÎÎH$ÒÝÝÉd¾óïd2žç»ººÜnw ‡Ã Ãܳ&e2™û·›ŸŸÏ»‚ ADßXøûÃÎ÷·ïÿÄEèÌ»—ß‹Í-9}&<N… Š˜ N‘49â9?rþâÈEA¢éèTpŠb¨‰ù‰ËЖgNŒ±h:z¬ç˜;äNd¯ž~u>~í OôŸxçò;$M.¾QÿLÿ±žcÏI6úYÇq8®Õhu ÿp–¢¨ëºŸüä'‚ ìÚµ ðd2988øÈ#œ:uÊl6g³Y†/\¸€a˜Édâ8îþèîY“T*ÕŽ;nüx‚D¢ØT|-Îsl’L*d #nDa”¤I–g5 Ì„g6”nhoE´ßÓ_e«¤³ií“í¸ïóôUÛª»¦ºªíÕ&I<Ð5Õ% –«å˜Üap˜5æSËÕ‚Ñ,½Õ™„S(0…N©ã>žŠáE’lõ3žçI’üÿ~ñÓÍ›·îÞóÇr€ëÇÉÊÊʧžzJ¥RÕÕÕ0 s»ÝZ­6•JH$"‚ÝnGAÂiíâ)zB$Ñ*µ×|’g£é¨J¦zlÓcV•¤É4y-³Ç,I%ÓTEÐd&©”)é0˱)2å¹13kÌ2TN…9žcyVLEÌ'æSdJ§ÒEÓQ¦Ð(42TÏÄŽ!iR¯ÒYâšO’‰,›­uÔî^»†àH:²ø:>>É]¹ÒÚÞvåÍ7íõΈétöìÙ†††êÉL&C„F£AQ”a‚R©”Ùl¦( Al6{ôèÑ'Ÿ|òÀO?ý´Åb¹Sõ¤ÕjU*•gº§Œ a¹z2›Í¢(š÷E€a˜J¥ãXà½ûߨ”cò©E‡D`„¤I•\EP„“g™,#‚!0’¦Òç†Ï­u®­°VˆGŠ'¦È”ø‘fi\g™¬“_{Z&K1”N¥[î¦R=ù™I’ýÃ:½aaK<k ^?wU©T¢q‹'…BP*•™LöüóÏCôâ‹/ÞûVÉåò?X¥Lyƒã üšo+1€èH ì?»mõjý—¶)÷DòÚÛM†Ê )þ½ø£„Ï8  ÉdrQ¯OAðò»­©la=î¶"d¯Õz;WXÈWú]_xá `ý#IÕägÌ'‘Éd‹ .PE³™ì²•ÌÆJ[ÿTÀ Qf(&˰€ ‡aÚ»»]Rüõ­3Ÿ?Eѧžz*¯O.Ù"“É€H¦ ¡pº<œÎ¢òŠª…-33îy÷õsW­Z°êÕE7Ô9»Æü[jìEf €™`bm©9MÑ4Ë5ŠXŠâxÞ¨QéÔòÓ]SEqçšA¥Išá¸©Ãòw°Iz½þ‰'žxÿý÷óî…ax!BŠ.*õ H(4à8nI oäL‚`YvIJÔsáÔèLE`¥òÇ ¸ÃJ:0ÀP¸cÔÇó<†ÀÁx:˰EkUò;ëb‰ÜÜÜüøãK?­„Õê“@ˆÅ"ED:‹òüù¤?’ÞZãÈdŠf2lz>6NáJY8‘!)¦Äª»:ê£nÜéŸ ¬-³vÍ™´JÕJ™A£ô0{#w¼=±XŒa˜îîîåƒ%c!yé>$|ºR.Wðf:8]a­Xr¢ØÞÜ z#^‡Þ"( œ ›µæ1ÿ.Ç‹ŒEŸ(>E¦Ôr5 ÃÞ°WâJ™R%Så}È^Oo±±˜á˜h:º®xÝ-?[îÁÕ º¥ ð Cc2ËÐ"+yá…œNç ƒï¬¯¯/++koo?zô¨ÕjM$o¾ùf<ïëë›››s»Ý‡ã•W^™F£3336›í6§ŒµZaØ´?¦DA›ç‡”Éd ÃtttlÞ¼9oœ”Ëå‹£e$^m{Õñn)߸8r±±ºQ)Sž:ÏÄ'ç'G|#4K @˜˜Ÿèœê$²D‚L4I1TÛd[–ɶO¶ÇˆØÐìP”ˆŠ` zµ*­/êñXuÖwO…µBô7\û†í:{ÿLÿ||ÞóS Ue­ò„=ÅÆâÜ "Ùõö–Ñ_Ô‡+ñ`"#bãþñ¹Ø\µ½Z¯ÒzݽU¶ªAï /æs‡ÜD ¦¿ÚV=9?Ye«jŸlŸðOÀ0̸̰Ü¡w.Ž^Da†àæ¾æ:gÝéÁÓ&ÜN…‡f‡LÓÁ΃¼ÀwOwûã~š¥f˜âÊÄ9&ïœêœN×:®½òæbsþá©ÀTûd»^­ïšê‚ èP×!³ÖlÓÚ&“е޷"âx#éÈäüdŸ§ob~ÂòÌ'æcé˜IcòF¼½î^£Æ(0úgú»§»õ*}s_óÚ¢µGºTX*¦ƒÓãþqµ\}jà‚ G.ƈX:›šRÈWƯèTº‹ÃÉÇscscV…QAΜ¿êºªQjzÜ=ŠøFp^#+Ð8ɲl0@€ XàyŠ¢X–õ„n`^ˆB¡(//×jµSSS<ð@:†aØb±ˆÿ·´´<øàƒ4M;Žh4ê÷ûÇÇÇoŠ^s;(--eY6ï.q,dñ¼D&‘¢R¢™ŠoqF)†Â,”%Éä†Ò ¡TèìàY\ŽÃ¼¹|³ÓàÌd3ãþñ­å[CÉUge8¦ÄT²¡dƒ%i*­Ä”S©5;䨆`†»69&I&uJ†`CQ Åò,A)*¥À Œ¢`28è\ðÉNW箺]¼À'3I†e2ÙL–Í*dŠžéž…¦¡Êñ\¯§—¤I‡Á±¾dýÂÕzÜ=Y6«”)[ÇZXG€`V+Ô5öšbcq‰±d}Éúw MY4–@" UjËÌe]S] 2qqôbµ­Úipjš…GŠJ´î!Š¡ì:ûøüø\lN´…LaÕXq^l,uœbœ$’ã9J7:7jÓÛ<O½F¼c§«“b©SI</5•: N’&ŽI‘)»Þ.òìÔrµUg]°ûwJ¦*·–ûãþmÛ‰€˜Èi”šS‰˜¬ŽÍm.ß,Gå*¹ªÜ\>æ³él‚ Ĉ˜AmÀP¬Ö^;>?¾³n§Øv‚"H†¬µ×’ iÓÙ2tFäÐ3Sj.åxN-W3ÏÄÍ3/ðõÅõÓ¡i¦@aT£ÐØt6€•o(ÙΦi–Nd[*¶DÒ‘ kÅP4Kq㸼¾¸>˜ –[ÊUr•SdÙ¬7n(Ù0æÓ«ô 2ÏÄkl5i*]n-/·”+0E–ÉFÒ‘µEk3tƦ³Y¦³ @@ Äip.P‹ (0 ÛÊ6 ÍéÕz@¸WÉUI2Yl,õÚuö¹èÅRK7Š/_µ\ÝTÛT •nœ † p<Ãp6K2 3&®ÏA¿Ð4ív»+**Ξ=ûðÃßþ\çä ¯€Ü9ÍNL!SËï {ÊÌeñL<œ WÛ?Q$2‰þ™þ†Ê†¼tYAdBL,¢cH=+b¥=4;Tc¯QË?Mñ„&ÐT˜ü-’$ûGô‹8è±X´e4xg„d2™ØÑòØcNV¿?@V‡Ik3Û6•­NU·t—ÊV»fùn$ØUöÿŸoÆ kÖ¬aYvjjª¤¤$>ôÐCétúäÉ“eee‹…a˜ÒÒÒŸ›}Çœ ççççççׯ_ßÕÕÃp8N&“_üâÇÇÇY–=räˆJ¥úÓ?ýÓïÿûV«uË–-©T ð¶¶6qbô /¼pkMêé陟Ÿ§(jaZÖbˆÜºÅõ¤Ø/Wk«•¬ABÄI½^¿¸{•çy ^¿?ª¸¸ø7ÞË奥¥CCCƒP[[[\\ŒaŠ¢F£Q­V«T*A ª««s8†ùý~—Ë%Ž=z´ººº¬¬ÌëõF"‘¶¶6•J…aXeeå-7©¼¼|ÇŽjµz¹/Íf!C°"S‘d  Ç-s;AîL¿ë õ^n^‡½^o]]ÝÁƒ¿ò•¯äM\o¿ß5Wû#§Ý¨ðN°S² …ÐÁCÄâA –eß¿0|w¥–óú›Ùl6›Í€{)r@ DdK}”ðôÉ%£"¿]í­ËLÉ­'­ÀêÉ$„,øä*Á`ðå—_niiÉ»7—['é H(4ˆT°%‘sû¤\.·Ûíá°4ýJªDî<ûUï“‚ 466åöJ: Ü€D/…—„ÎU'Y–ýÊW¾²B©)AÂꊜàF¸u ¥R¹nݺ2uI·NBc‰„?Ïó<ÏK$Vqœ¤iúìÙ³:®©©)woîXAÃû÷—<ø`ÒëA¡×'ÜîªÇ$î«„O Ç-æ À"Vo{¦§§{{{çææò&¥y{t”F#‚a2—á8¦TÊõzÉ,$|êäA@@Wu{‚Á I’ « -Þ›[OVìÝ P™¯1õtwSæK‚„ëpîø$ϯæ±ÊÊJAª««sHc! K&4ƒû€[‡¢è¾}ûVh°ô«K(|·¼¯|reHc!V…•.qÑÕÍã …B‡>sæÌ Ÿôz“>_ ¿a MD0(þíko'cKðc)*=?¿dcph(齎L;‹:óq·{¹cÄÛå= 4<œ˜™Y²—&ަoá‹âh:åóÝÙ/?å÷Ï÷õINu›õd^nÝõµ$?܈–¤R©t8ÝÝÝ7nÌûZ¢¹<×Ú:×Ñ@ g'ϲ“ÍÍÁ`jn•Ë©xœ¥(×É“¸ÝŽ©T€¹®.†$Óss®“'Q…Â}þ|ljʼvíl[›Êb;rF±Ã‡^/ϲ3­­º’’¾ßþ–gÙ¾ßüFQ†ƒƒƒ¦ÚÚþ7ß̦R‘‰‰Ù¶6ëºuQñxË~¤+)ñ\¼›œDU*×É“J£Q®Ñ0•Êsñ¢®´Ôuò¤mÆéóç‰`ÐÛÚ4VU<(S«gÛÛý==@<—.) †©³gáÑÑàÀ€±º‚ –¢BÃÃi¿?9;K'“†; (›L²5üþûó== ½~úÌD&›mo </ÊÔj×É“T,u¹"cc0ŠºNžThµràëè [Ö¬ñ\¸`ª­u:EF"d$èïW㇫-ŽK.w#‰+EQKDGf«8NÂ0|åÊ•Ïþó7~Š¡¢Be6‡FF8†q_¸P´c 2>ƒP0ÙÜ,ð|âãèd¨¨ £Ñt ÁpphˆŠÇ1•J ­S§O <¹ÝÄüüÄñã AdÂaA¢““ö͛۷ëJJ²‰€ç¸„Ç“˜™á²Yã ½Þ¶q£yÍÃdÍÈ@bSפ.aÈp‚a*'#CUUéƒ"ry&É&“)ŸÏºnëäI:•êûmÃaª©™8~<éóñ@åòù¾¾ÐȈ¹®.‰¸N‚Ÿž;|xðw’LÌÌ„†‡y–uŸ;Gƒt:ˆP¨û7œ ±éé‰ãÇã˜jk5kö*~FQ‚ØL†N¥¦Ï£ 2c)*Ò!ùÛmöê}tš¦av8Ë%Kæj) †Ê‡Ö••©Ìf*·Ô×{/_–k4Ùd’ç8•Ñ.jlx~ÁþBÃѱ1™ZÛí*£1áõ&ggµÅÅD(d[¿ž£i}y¹¾´·ÛÛ·£ …Â`ЩÌf•ÅâëèˆNN&gg‰PHãtª,T¡ƒÓT¡Œà6›Êd*yðAŽa´%%â.D&#ÃáÄÌLÒëŒ+ôz:ÖÏuvÒé´Êd¢Ói2›¹|Ym³ ƒ$™ÑQi¡. ÷¨ž¼¸uǹÝnE•JåØØØÆs©<¹Q1!;;ç~¸â¯ÿú´R‰>ôPù… žÇ¯¾tÉSV¦'If~>]_oyë­þŸÿüÉŠ =àÊ•+ÃÃÃ=ôPkkë“O>i6›%K’pgÝò>ñɲ²2¯×Ëó<‚ 9êärëôz¹J… »\±õë­ï¾;X^®ïë›ÇqÙ·¿½ç…ÉÉXi©N¼ÈØØXeee<§i:K>)áÎ"—[·ZÇBd2YIIIyyùèèhqqñ |¹Ýq†ázzü{÷V Ä0üÈHè[ßj¸rÅ»n‚€F#GQX£‘ÍÎ&ÊÊô€mÛ¶ ÔÖÖj4µZ-Ù„;[Oæí‰¼oµ?PÅq, Áq|ñíèhØjUcV§žçS©ÔâˆÂóüý¬ýq]¬Y#%¢ 2¡]Í0ÌÌÌ Ïó^¯—^F†XâÖI(üÜõþYÖãñ:t(“Éìß¿?‰H¿®„ÕˆÜ8±Šû]«««M&“R©Ü°aà ɺĭ“Pø%e®O®Öy!¢v«\.G–Ñ2”÷¹Z+që$¸CÞoºu×MÖ¥ÜUB›hnî ÃÐý¬ýQhD´Ï—”lQÂrV AÐê[ëN„?üpzzÚb±477·µµmÞ¼9÷ (ŠŠ+1,Œ…Ð4øÖ·Žò<Ðëóói—MMÅ òz“,Ë㸠põêÕ·ß~{ll¬ººš¢¨ßüæ7W®\Ñét—/_.++»zõjssó¶mÛýýýo½õ– ­­­&“éòåËEEE¡P‚ d2är¹×ëÕétbˆ„R‰ù|)ýþA00 y< • ›žŽQûã_)*Ò˜L*ÀÌÌÌK/½T^^n2™$ó½/’eÙÅ"Ç ¹ƒ«/w… hïÞ½---z½~ïÞ½ÍÍÍ7x"MsÁ¬_oùÁ.56]¾ìu»ãÓÓñh”ܰÁúÒKCе"ÀÑ£G!bYÖápD"‘p8ÇÓéôB000ð />|8‘HÐ4íõz¿ñoÐ4ýÎ;ïà8Ç›ššÎ;çñxžzê©ÆÆFÀÌL"Î .\ð46õöÎëõ — lÚdÿè£Éo»ad$“55ÿù›Ieðg§GÄ*Î]Àk¯½V__Ÿw¯8²˜9`2©**ô£Qù¥/­Á0D´v»G€keç¾ð…_| Õja…BÅÅÅ2™Œçùp8<99™ÉdÞ{ï½’’’S§N9N‡Ã!‚V«íìì$B¼Ñh‹>úhmmíǹ+38„ ¨¤DKÌÇĚ⊛šJÖ¬±,Ôeee?ùÉOêêê$Û½_‘W·nUò]9ŽËd2ù|>¹\^^^ž7wÍ廆B¤Í¦3‹Šey·;n6«H’AQÄfSH’„ H&“ýò—¿|æ™gAèèèØ·oßÜÜœÕjU(±XL«Õ›ÍÖÒÒRUU…ãx6›Õëõ^¯·´´4èt:žçõz=I’>Ÿ¯¤¤D, ÆÆ"4ÍÚl8Ç $Éüò—=ñ b"]T¤Íd“ISñ8U^®—ìõ¾G.ß•ã¸ýG¤õ'%HøÔêI‚ Û¤¸þ$,}5÷Ù,ÇóRY(a©OæåÖ­JŸ<{öìÕ«WƒÁà¡C‡ZZZn°ž„ è7º¯\ñ®påñññW_}õܹsâÇ'N¼ÿþûñx|jj 099¹Ð¥ä÷û_ýõééé¡¡!žç»»»8J¥Ä½óóó±E‹‡Ÿ93S+Ü—¢ØsçÜ '&&Þÿ}RZó3¾æúäªÌåjkk{{{¬Vëäää®]»òt^åè x<‰7ßìû—ùü÷¾wJ¥ÂššJµÛñ¾¾ù†çÿøŸÄãñŠŠŠžž‚ xž÷x†av»=ï.·Û=88Ȳì±cÇ®^½º\b ­ +¡À‘—[WÐqr~~>¯‰’­­­^¯×år-)”o'±” á^"·ß€^ëÃ0£ÑØ7“gÂ!Š¢f³¹±±qûöíW¯^Íûf‘t$¾CæŽO´:Ã0@ o°Ãqü¨Tª–»“"§„BÆêãÖaf³Ùn9´åÖ“’H(4¬2ݺkq2Ÿ+‘$™Éd8Ž›]®oV Y¬¹ ˆFÉ•y§étša˜L& BÜȲ¬ßïçy~±¾s:æ8.NG£Q‘K”«4KD2™\|©Å¯Æóü ¼ÖŽMs+þ¨B6ËænÅb‚ d2‰4[ÈÈË­+\í­Vk0\¾h®ölj'¦¦¦ôzýáÇÍf³Åbɽ‚ Úâ–xœùú×j42šæúûV«úìY7 C>Šb­V5àí·ß±Z­§N2›Í“““ccc½½½‘HäÀ‹E\]ëÝwßu»Ý$Iž9sfpp°¾¾þ;ßùÎc=vþüy†aü~ÿØØ˜R©lnn^»víþýû7mÚäv»GFFP½råŠV«}å•WœNçìììüü¼ÕjmiiÑjµÃÃÃÁ`PìpŽFÉãÇ'Ö¯·ž;çž›KÑ4×Ýí7™Tíí>žÜîD_ßüädôÿý¿ÎmÛœjµ 0999==­×ë¿÷½ï=òÈ#ðz½†õ÷÷ëõú––AôzirfžÅnÉóü;TÐõd0Ì“íÚµK´`§ÓÙÒÒ’Wj —[§Ó)ÊÊt?\ù¿ÿ÷…gžYûæ›}2òïÿÞ…aHuµá¥—öB !ŠF£âE~õ«_á8®V«ŸþùcÇŽÙl¶…ùÓ4MwuuýùŸÿ¹Ïç …BíííõõõcccCCC3334Moܸq~~^&“a&>ÃéÓ§Ÿ{î¹@ 077G„Ýn/--D"}}}ÓÓÓ4M=z” …B!* á¸ÌëMÄãÔ/~Ñ¡×Ë7o¶Ã0tæÌ4 Cé4að“OÖèõ ƒA©Õ^{¥þò—¿ÄqÜçóéõúD" c±X8~àŽ=Š¢¨¨Q"9CÔ“ù¸upAדV«u…¾Òd2)ÂÊÄ·ÅP(P­V®ÕÊu:ÅÖ­ŽÒRÝÕ«sÅÅZNŽ ×.b·ÛGGGR©TQQQMMÍš5kÞxãúúzAÆÇÇ ‚øÅ/~!—ËŸ}öÙ¶¶6ÇCÓôÌÌL}}½Ëår¹\E¥ÓéÞÞ^‹Åâóù¼^ïèèh¿ÈSïîî]š¦i—Ë566ÖÕÕ…¢èÀÀ€V«Õjµ ëÛº\±þþÀ… • S©0ŽƒÕÕ†ÙÙ¤^/×häÛ¶9‹‹µ33‰P(#žRTTT__¿~ýzÇgggµZ-Š¢‘H¤­­Í`0 Iuu¡¹en7dáò] ˲½ž¸Až‡ï*6F$£æµ³¼:0ŒÀ0Äó CŽãa¿q‹]yž_(DÅ[LMM™L&q¢ à H"jhhhãÆbÕúÑG=þøã'NœxôÑG\ÒáÄ0Œ\.oq­„@ŽãÞ/ ÏÌq×ðÞ{C>XZ\¬åy† €[!,|â“#²øÇnnn~ôÑGãñøÄÄÄŽ;$·,œžL&“«3PÐt•JuºË%iHøLùdA÷»F£Ñ[~§KÜ: …UÆ­CQÔ`0äÖ“‚ .j.OOO‹ìŸþþþÊÊʈ#C;vìøÕ¯~åp8‚Ëå~¿ýúõ—/_Þ¶m›ßï×h4ápØçóíÙ³g```×®]}ôQ}}ýÃ?,9Àj‰œ õxYÂ[€Óéÿ8}úôr—;W«¤D»cGñ®]¥™ óßÿûmm³™HPèn™ë“h!?®B¡È[OÂ0¬V«år9Çqr¹úhrÍóèh8%¸\1µZ6=gY>%§§ã>_ê7º7m²+(àµ×^kmmU«Õû÷ï7 étš ˆt:Ý××W\\,RÞÞyçQb¯­­Íl6ÿìg?{ðÁýë_kµZA¦§§F£øîûû¿ÿ{ŽãÇÀÀ@[[ÛÈÈH}}ýþýûiš6™Lããã*•j~~>˜L&É4? `Yvq\ä8nÈ,h·T*•·ßuïÞ½---¢¸«Ïç#âFxH‚z{çŸx¢æ{ß;-—#=V=7—‚a(™Ì"ÃкuÖêjãü|zᦣ(Êqœ×ë …B»wïFQÔï÷qîÜ9“ÉD’¤(¬<77§Õj‹‹‹!Z»v­øf9xðàÞ½{›ššÄ· ‚ 'OžÔëõEQ†ÍÌÌ õõõy½Þ¢¬„û>wÍ›+ôXˆV«]¡´X,ëÖ­+++S«ÕyÅ%õd"‘ ‡3½½ó:\£‘³,ŸJeU*”¦9q\öÔSµuu&†²Yná"~¿ÇñM›6‹ë”$“IQg¹²²‚ “É”J¥R©Ôìì,A<ÏÏÎÎÊåò‰‰‰«W¯VWW§R©C‡‰«-FAâñ8˲©TÊårÇb1†S©Š¢N§óù@î,ŸËÉÂ廚L&Žã:]‘\¾+ÏóE)Š`0¨ÕjE×%@QÇq°ˆï Aòp˜T«e¢›Ÿ<é*-ÕíØQg•J”çFÃÀïOëõ • $“ÉÎÎÎ;w†B!«ÕšN§Åq—t:m³Ù†¿Sš¦QM&“6›-›Íò<¯R©¢Ñ¨\.O&“f³™¢(ÇÅ…L&S4Åq<•J) ÇÅù_¡PÈ`00 #>¶„Ï‚C¦ÓéÙ{1w-hÍe³Ù¬R©Îõº r^Ò\–p_æ®Aäj.4g ‘HÜrçdî>ÒXˆ„B³ðU¦‘A^¯‡ Ø˲gΜI$>úèG}¤Óéž|òɼ –~u …ï–¹>Y¸}<<Ï‹ ›æŠûöíƒ h||¼ªª*NSTže^su$/•PhXBày^ø‚ž«e4sóMA.^¼¸qãF³Ù,:äÝ›©,AÂ]ÍóM{'£ÑhnlËd2‘H¤¿¿ßf³aÖØØ(ròÖ“·NB!'®y¹u­¹¬Õj!wlÉvµZ½0ªþ¹Ï}Núi%Üg(h-ÉH$rË5 !4WKBç®yuë ZKÒl6çæ›Ç;w®¥¥…a˜ööv‚ nüšï½7”JÑ+ͲO|áãàààää¤ÇãùÿøÇ#nìíí}ï½÷ÂáðäääÊ·‹ÅbŒÅ>êÃáp(’,RBÞ8A…'Ãápnlƒaxç·ŠF£¥¥¥+pëÀ¢ñÉXŒíÛWùÿpF©Dwî,imõîÛWyù²·´TG’ìÜ\ªªÊðÖ[ý?ûÙååz@{{»Ñhܽ{7A¥¥¥â•»ºº~øáÇ#RUUÕÒÒ".Ëçõz÷íÛ788X]]ír¹²Ù,AÏ>û,A…’9޳Ùl§NÚ½{·Çã±Ûí»ví’¬ó3‹\nÁ'-Knœ„ hffÆb±X­Öòòòƒ%[ôz€ ˜ññÈÈHxx8TQ¡ÿõ¯{iš»|Ù;>yî¹uÅÅ%%º¼—"I’a–e;::žzê) ÃD ’ÉÉIA2™L?MÓ­­­ñx|ãÆýýý2™,‘Hd2™ÖÖVQ=‚ Ý»wøá‡>Ÿ/JvùO_s#gáÆI–eƒÁ`nœL§ÓÇw:ÙlÖb±(Ь']®hr¹u=Â0Ìüü¼/âÇãñcÇŽE"‘x<þþûïK?­„UZOæM  =NænGDì/±X,:n¹®W‰['¡ð×U¦['ÆÉÜíétúå—_N§Ó£££¯½öZ^t V/ ·Ã0£ÑØ7“\²Çñ—^zIüûG?úÑ ‰Ä­“Pà¹ë*ãÖ‰qRJ7%Üǹëªìw½åЖ«[woêɹ9À²’½I¸Q+ÍõÉÂÕ\–ÉdÉd2Ì*Q°Xs™eÙ“'Ož?Þh4ž;wnddDS]AÆB$“É"’ã„o~óÈÖ­N™ ‰FI¥ ‡3‘$›N3¢\Eï~øý ÓÓÀé¡P*A2 ²Yð†à 0 ’IðÂÑQ`µ‚÷Þá0(/é4xé%°s'ˆÇ†D°,8qD" ¨Hxå•Wªªª~ó›ßøýþ‰‰‰îînFÓÛÛët:ãñ¸øîŒÇãA´··Ûív‘ÓÇó|__ß;ï¼SQQqüøqAX–Å0ÌårŽŽªÕjžç†Éd2@`xxØáp¼úê«Û¶my‹¿ '†Y²vú;T¸>©Õj ƒË]â“0 WTTLMMmÙ²… ˆ`0¸qãÆ¼>)—Ë1 ƒaA‚<žä~t¹²ÒÀ0|M±½Ý÷ÿpF«•ÿà—Ö¬1ÿë¿¶ÆãÔ¶mNÇóçAq1èën7P«Áw¿ o¾ ptwƒ–`µ‚¿ú+ÐÞš›ÁÌ (-?ü!¨©—.]»Àßþ-˜žÁ xï=@Qà_þ´¶‚¹9‚ššPoo^¯w8.—K¯×§ÓiµZ}õêÕººº£Gž:uÊï÷ ‚ V«_ýõâââ×_½££# z½^…BqäÈ‘L&ƒ ˆZ­nmmõx‰¢¨R©„¥Š5AŒŒŒ(•ʧžzjûöícccRÕ$a•Fżܺ‚ÖH¥R-YÃÇñ¯ýë — ÏÕ­“æjI(4äåÖn„AQT­VßòdŽ\É$òjd®OrG’dnpã8®£££¿¿Ÿ$ÉæææÎÎΛ* —CÒçó\¼˜š› Ž^ç:<Ÿœ]²1ærÅ—émZ@6™x˜™¹o†ŠÇÅÿ³©ÔÂÆå®¹°gY÷… ¯—ÊUK„%§ ‚ôzãn·Àó ¯÷Ú^AHx½yF­Փyµ$ —ïŠã¸L&óKø®•JuåÊ•J511±iÓ¦¼„†årùâž¹\¾Bå9ð»ß•?ôB§›>{ÖTS3ÙÜL‹lÚÁA…^?qìn³‰]²á‘‘”ÏǤӮ' ™»z5<:jZ³fæâE}yùØáÃ0†M?˜@är÷ùóÚ¢¢‘> Óé¡÷Þc)J¦Vû::,k׎|ð¤ææfÛÚ †q 3uú4 éJJL&3vè\§‹¹\éùy†¢¼­­0жÿô§¦º:g§\« ¹ÏŸ—k4ÓgÏ:¶l ô÷O67+ ×É“JƒÁ}îÜLKKIS 21s¹ W~üc•ÑH„þöv•ÙYèÜ:qè&¯#Q•ÍfÙlVü#¿ÍÝÔíX–gYç¹lÀ1 /ixH¸oÆœò²p}r¡ \²eÙ¶¶¶_þò—^¯÷•W^¹páÂr­½©zrìСуCÃí/¿ xûíé3g$£‘pW2w|² ¹u‚ ˆ“î—ðxPݱcG(òûý‹evv–¦é›Y9rV?ñưÿí¿ê¿ò•{–FJølbõéÖAÄ0LnpËd2?ýéOe2™Ãá (j¡nÌ[O.Ž–+ßS©0• Á0qð@¦V£Ë¬¢'AÂ-ЖødAÇIqÐIœ”ËåßúÖ·A0 Ï?ÿ<‚ ‹gj/I}Á¢~WÉ$`–9 ×'E©¨\_BdA€ç¦†p$·”Phž—[W¸¹«  …båœs7»{køÄ>æô2 CI=´nÉÂóéÖÁ«Çòlssóï~÷;¯×{àÀ_üâw**þeefÕIDATâí gýö·}‡å'£s<iÝ|2M&}©Tk?ðÛßþvÉÇóÁÚÚÚZ[[o᛹zõ* ¹¹9 I–½ÚÝr‰O‚BÖX(Š>úè£0 Û·ow¹\+dê Ü¥•ÇB¼ð‡ObÃÛ|eÏž²S§¦þâ/òŽŸžšj›ÕÊå?¾råKkÖ ‡BO×Õ ƒ—<žZ£Ñò130;;›J¥²Ùì~ðƒçž{îÈ‘#©Têûßÿ>MÓ4M;vì‹_üâ’‹ÿó?ÿ³Åbq8/¾øâ«¯¾úì³Ïž8qB.—¯[·ÎårÕ×ןRÔwDQtïÞ½ccc<Ï?ýôÓ0 ³,‹¢èš5k¶oßžN§»»»N1›ÍÕÕÕƒƒƒÉd²©©iíÚµZ­ö‘GaxÏž=Z­vãÆÅÅņQÃð–-[$㾟°úâ$I’,ËŽŽŽ=ðÀÊOºÁbס©©I Ç­à–0 }ó›Û"òá‡+4y]ÙnÇe2d¡bdôÅ ¨/hp:í8^¤Õ2‚ k×® ‡Ã;wîø|>¯×»uëVñ”l6«V«Ÿ|òÉP(TVVf2™t:Ýž={²ÙìæÍ›•J%Çq‚ˆg566 mž„G^n]Aë +•Ê3ÝSKtÐo<ÅÅq|R¹%@‡Ïç‰Ç PÙWY‰/CQ …ƒAñH‚ö”•©!H¤Â/†aÄMÄÉdRûñìªë¾›®Û&¡À3¾t:½˜îÂqÜþ‹ÃèýÚà›Õ­›-..λ«±¨¨±¨èFnºÖbYk±ÜÔs.\½A‡,— HXE&š['¬>Ÿä8îÂ… 0 755]¸pA¯×7ÞØÌŒ•CJ XÎ'³Éä\WWé®]щ ‚€ Hy%Ü&V·nùÚÞµk—Èwº|ùòr‰ÁMqëÄD7ÿ¥& žÏ¦R ÿ$“’pGÒ×\Ÿ\}q‚ —Ëe·Ûyž¯«« …BE)r¸©¹Üºëhd%“Ëf‰&ÓºçžïØ!™‘„;`r#çê‹“étúܹsóóóZ­–$I«ÕzGV ¦Qs$H¸7Ñ%/·nõÅIÇÿò/ÿRüûÙgŸ]!Y¿)¼‹XJpWëÉ%c!…έ»ýßÔñ÷xiJ òFNPÈ:+”Å.—kffFü#/—©ß”Î@0\öŽÉ.Sp2™ XæÊÃp #™š„å—[·ú‚ƒÈ¦?wîܦM›¦¦¦âñø×¿þõÛr+\Á×ÖÆPn³ÍuuA©Õq§dçN÷ùóöÍ›{~õ«š'ŸT™L‘ñqçöíd$`I2›JQ±X:\ÿüóþ®.•ÅÂÓtÂë­yòIIñM Ùº_-F£Q¯×;Îþþ~ŸÏGQTîHÆÍêÖ­PO&}¾Ê}ûdjµ¸l“ɘëêÂcc©¹9gCƒeíZÇæÍãÇÛ7mR ®'ŽãfÓ×¾ÖWTR~lzš§éuÿå¿H)a±•.IîVe=™N§þóŸ§Ói Ã4Mmm­zÑTŒ%©ùc…~WÛÆÃï½—œeI’Édz½ Ç™ ‚áØÔŒ¢sÝ݈L¦²X Ž»Ý4A‚àiiQ sË‚ar½^~Ã4 Ÿò“aS¸où®7«¹|éÒ¥Ï}îs’•H¸—‰+A«Isùö|S¹kÞ`+AÂÝîY6W%·îvªgÉ'%²•®VnI’çÏŸŸ}úé§>¬T*ÿäOþ$ïò[7Å­Kä®Ê(AÂ]Æ}­S*•kÖ¬!IrnnnÛ¶mJ¥’$ÉÛ¿ìrkHp—°útë–A$Iâ8®R©\.W*•RäG¾YÝ:“É$Y‰„{œ¸r ú‡M†W_î*“É0 {â‰'ìv»R©T«ÕwdD–† %VŸObVSS#þ]VV¶BbpSõd(Z³fdîeîzŸèÖÝ=W—¾ ÷8wÍ'VŸORÕÜÜ|üøq‚ ~ÿûßÇ?^Ò| ruV®' òßÇ’³³w¶!Á¡¡›:>éóQùÿ{WÔÖy®ÎѾKhC±‹;Æ8©ã=v𤙹m3™4žÎÜ{;sï¯ÎýáÉ´wîíŸô¶I&K›4Žkâ‰Ç®—`Œl³9Ä`l± Ä"2„оžíþøb•‚¤@bR‹œç#Ð9ßùÎá{Ï»~ÏKSË(–\bÆlŽƒgÏNܾmom% b²£œAÐd{û’ÓÝV+Ž¢¡¹9ïÄ%Bk¤µu™g»²X,½^ßÐаk×.t‹ÅI ƒU ›&xë|ð`Þb ÎÎ’8ΕɄ99óKÉ‘#÷?ù¤øÐ!¯Ýq»é,ÖÜà`åë¯K !êþà géõ®ÁÁ‚={ú>ûL÷Ì3îááx0˜ÿÌ3£×®eéõöÛ·+^]VRAPÀé|pâ„8/a0ÐPˆ%¡‘ˆ4?êË/Õ›7ÏšÍ$I²E"’$ /¾Èàp ºp!»ªjêÎ<e £MM±@Àmµ¦§7ìØ1sÿ~vuõð… ¦×^“ @hç9 ƒËu³D¢Ûo¾©0§»»%æ“'ÆÆb~¿×nçæºGF䥥S¹µµ¹;wÚnÞçåQ"´æërÍ™yzÃ0­V+‘HPMC¢³Úž°Ô;¡ÙYˆFcp8,‘H”›;ÝÕEàxÄíV™LYEEQ¯×k·3ŽD4L§kjjÆ››YB¡Çf“èt¶o÷ØlÒ¢"ÇóvíBƒAå¦M²G,‰aªòr¿ÃE£›- •ýä'¾©)IAK(d‹Å‰DZX˜³mã]{däË·ÞÊÛ¹f0¼v»¦¦†-‘!P«çúû³JJø …rÓ& @&I’„étÇI’Ä¢Q4æ«T<¹ÅX"‘877t(°Äb ¨¯ –PÈ–HƒÎá¨***ñ nVIþ‡9R©@­V”•߸Q¸oÂd2xŸïÞ=›Í&‘Hrss Åèè(%?káO®Þ:ŸÏgµZaóxŸO(šL¦@ 0;;K£ÑL&“Ïç³ÙlƒƒƒÑhôáÇ|>¿¿¿ŸÇãI$’ªª*™LÖßßaØ»ï¾»Äøôù|###6›M p¹Ü©©)‹Å‡Ãá°ËåZ2I‹…¢¨^¯oii‘Édb±Ø`0ðx¼žž6› òOúSâ4Íl6#F%‰J¥R©TZ­V«ÕÊd2†…B¡ÅbÁ0Œ €­X.—ÉÌ«w%I2‹!Ãp<g2™I«XW˹ÜÙÙ¹uëÖTnhh(;;›ÍfÃ0Ì`0€ ƒ\.g¡P(\YC‡£Óé¨eéKtIOØLíá‰D®\¹rúôiEûûû—!‘æÙÅãqÀq¼»»ûÖ­[$Iž;wnðÑîD‚ À1@quvv†Ãa‚ Ž?ŽaX[[Žã]]]@ƒãøýû÷!º|ù28˜¸ííí(Š‚ sçÎÍÍÍ}òÉ'gΜžžžNx _|ñ…Ïç»yóæñãÇ“ÿío{æÌ`‚F"‘wÞy‚ Ç­ÛÓÓFÆq¼¡¡áã?öûýñxEÑ3gÎ\¹rÅb±444«Çqp"¸µ%Ϥ»»û׿þõÝ»w!ã8¸ðêëë©^ôß™§'çò_|ár¹ÆÆÆRÙœ«å­s»Ý©¾²Ùlõõõ/½ôR}}½T*=vìØõë׃Á`WWW"CpõêÕ™™ƒÁpñâE“Éd±X‚P(r¹üÎ;W®\ÉÉÉinnr¹üÚµk‡nll¬¨¨p8õõõ2™L(ŽŽŽŽK$’Û·o;ÎcÇŽ™Í溺:>Ÿ¿°°pïÞ=vôèQ`ëšÍæÎÎN“ɤP(ŒF#Ajµ: ]ºt©»»ûÀ <ûÇ?þq~~~ïÞ½mmm"‘èĉB¡P$ †±±±Ï>û¬¸¸˜ÃáìÛ·EѾ¾¾x<þöÛo+•Ê`0˜››‰Dîß¿ÿ /,N‡TWW?xð`Ë–-o¾ùf]]ÝÇsrrG___mm-Ç3›Í555”€¥·]× o \‰DV«uaa¬þï>lš ­B¡(--5›ÍyyyÏ<ó ÑH„ÇãFN’A ÔÖÖVVVF½^‚–N§³¤¤D­V—••¿ôÙgŸ-((P«Õ‘H„N§›L&¿ßïñx)--Õét†=ÿüó ðF§Ó#‘AEEEƒÉd‚d)èʉD€ %N, ûöí)–P(AБ#Gôz½Á``±XZ­öG?úA^¯—ËåÖÔԀЫÛí†a8F£Q¥R‰ãx]]Õj ƒû÷ï×h4]]]Ë;8ÖÖÖÂ0<77777·gÏž’’:Ža%ußh»&»f^ÍŽãýýýz½¾ººº¼¼¼¨¨hy¬Ü‹ÅZ¬-Y,V[= ¦Ú®FvïÞÍ`0èt:ÐEr¹\.—‹D¢H$Âd21 LÐN§S.—çååMOOççç×ÕÕ‰Åb™L†aX~~¾ÝnÏÏÏ‹Å0 ƒÁX,¦×ëçççëêêB¡ÑhÌÉÉñx<•••333:nff¦¸¸˜ÉdÆb±;wÚív¥R‡³²²t:]uuuQQQ]]D"µ~¿óæÍÕÕÕv»=77\±ªªÊívF"¥R)`6™L†•••I$N—““t†a2™ŒF£•——‡B!NWSS355•——wíÚ5“ɔȋ€Î¼‰D$eggûýþçž{Îétj4 ÞYÔfèo’ÉX,¶$(8hŸ_·Üt:Tº¬û£§§ç ,UAQd}!«TÖµÓé,((P*•k7yZÉ‘ CIÝ7†0‚ÁàâGŠãøzæþX­? l¼' ‰$Jú ±N§û°+¯ r…K4)o]æÉd4mmme±X&“éâÅ‹:.iåÕæB’À(¬©íº¼¶†3°¶ŽÉdõööú|>Ç£P(RÝðãŠñP °vb¹D&!(e’$IµZ-‘Hx<Þ±cÇRññlå<ir!(¬Ö Ï@8nmmU((Š^½zµ¢¢âq9ÜÔ¡ð$ ódR 8p|>räH˸Ú: ?4¬“Úºbµ<ijÐ)Pø>ÝËÌÓ“†Y,@››k³Ù‚(LFþ½Ú\Øv¼Øív.—+—Ë>|H£Ñ–ì™ IÒår±Ùlƒ¼…Um>§Óé4-PËtcymˆÄfdŒ‡Ëå655Ùl¶óçÏÏÌÌ<–aû¿–# ž?Þår577›ÍfƒÑÑÑá÷ûÿûß'®>>>~ùòeÇó·¿ý­¡¡¡¥¥eaa¡©©éäÉ“¡P¨¹¹¹¯¯¯»»ûÒ¥Kn·ûÂ… ~¿Ü‹Íf³Z­ -]__Ïápø|þ§Ÿ~J­Úu¯“ÖÖežL2 ‡ƒ ÈììlQQÑÈÈHÒÖ‘«í ›f“”×ëu»Ýccc÷îÝŒ8àøÊÊÊDéÏÙ³g].׉'ªªª †J¥ ‡Ã¹¹¹[·n%IÒív÷ôôé‡ ƒiT(Ø`%•J ™Læääd8æñxݼy“Ãá †p8¼qãÆ«W¯r8œ¡¡!†kkkoÞ¼¹a×Ë%—Ë…B!ŸÏçñxÑhtnnN*•Â0üÓŸþ4'Þ ²œjäþAÒ:žu[ïºZî¶¶¶¤õ@ß3z{{¹\.‚ >Ÿ/)…õd»†B¡Åk2S¹?V~Ùȹ\^^N-ÖŽL&«­Ëð\Hšhêjkë(j6 ÿ”¼D&¡Lìá‰Dß{ゥ©©sçÎýæ7¿Ie©S=|(<áX'µu§´´tllL¡PçQ½Y)¬/džLƒAÇÃápÂáp__ßË/¿œô°ÕÖÖ¥é K®ÃÃÃAB ¾…$étzFö„e³Ùr¹üÈ‘#"‘èàÁƒ©B©«Íï¥éNÂZEQBŠQ¸Ý³™'“t:=''|N“è_mm]"kOÂ÷¦'a‰F£óóób±˜N§Ó Aðç¤×œßzÏŠãµÏ‹Â·A:^yù…ÿü_ƒÐ"#ã®MMM—.] ŸþùåË—Óø“‹këÒËçó?þø~B—ž=;ØÐ`]~ØG==5ŽŒœêíu…ß ôÎÍ.,@Ôj·[ÿqcôB$Òép@ôÕW_MNN.¹‹¿üå/àéS§R5xÄ0¬££Ãn·‡B¡©©©å…ò‡£³³“ZÜ+“¸Ë5÷¯ÿö«ººÝn·ÈdFú“z½¾¡¡!OLL0™ÌÄvÊÅ©×D…Ý7â—¿lšß¸QþÞ{]Û¶å\¼8ôÆUà+óÌÌÿuvî+,¼i³ùb±qÇârÕétÿÞØ¨äñzgfèõÿÛÖvff·N÷?mmåJeE­nwFÓl³½½oßåË—?~úôi¡PÈãñîÞ½»wï^PØÓÓ311±d2õõõN§³¢¢bll AÁÁÁÇ·´´$yäÈ‘>ú(''ÇívK$’^xáÏþóÖ­[OŸ>ýôÓOkµZj¡g0×hr4š¯}1¿Ï›‘2‰¢¨F£‘H$‡£ººÚápD"‘¤Í|`îèèp8½òÊ+i„“ HÅ5ÁÐмXÌV«ùªýû¿ÞvgjŠË`|épäŠÅCóóîp¸D.WòùîpXÌfoU(|Ѩ34*ÃnwµZí …,óóåJeEvv Wñùñxp+ß¾}›Á`lÙ²xÂ$I–””&“i6›F#x•8ŽíÛ·ŽŽîÙ³çÎ;*• ‚ ÂÂB™LF’¤V« <綾^¢Ñh@ÇÆö¡ðä8Sýfú ŽÎÝ‘û'[[[KJJŒFc[[[YYYR…KO=õEÇÓ˜¯0L{ùå.WøÐ¡b:..–eeqŒ¯ó¹µyy WfgOx½*•˜Í¶y½Û´Z5ŸÇñ ¯%ˆ1Ç<žCrù·¶nÓjÿëé§ææÊ•ÊIŸo>.//Ÿžž…BƒÁ`0´µµÆ;wvuu•———”” (zýúõ²²2pÅÿøÇ‹åàÁƒƒazzº¯¯oÛ¶mmmmF,oÚ´ çN§œ‡åC!ƒb<••›ótß%ëtN7u­ÛtAÀM­sù± †ã½33z™Lô[Ub±I’i¶hF—´R^Ñc1ˆ"ÝËLD"‘¡á± ¹yLM^`_·q×Jm A6k4¢eÂb±Ò$˜í·H02%ãi¹}«0?gÇS[ìö ,Cc<±X¬µµU*•–——·¶¶j4š’’’ï>¬ÕjMUÊçúûÕÕÕÞEÁi2 V)“„©¢âwß×éòÅb±{~ÊÄ\ƒÁ0wïÞ@¤½½=i"aµ<YYY)=ØHd~x˜Àñ€Ó˜ž?©õDá»'ˆX,VU½Yš•‹Å0Ë =¹DœáóùR©T£ÑLLLø|¾Dië’³–¤%Ó›¯i¾åÈd›~þs‚6ìØ±øxjIQø. ÓéA¿×ëYX´¨¡P˜2Éåñ–Dù…Bá±cÇ *ü&2!9$I¦a÷€ H¥R-o®Hš¢ººjÉ_\c0õ\(Px¢@É$ ”LR @’I (™¤@·],÷ôô # """ Module implementing the Python re wizard plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "Python re Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "PyRegExpWizard" packageName = "__core__" shortDescription = "Show the Python re wizard." longDescription = """This plugin shows the Python re wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class PyRegExpWizard(QObject): """ Class implementing the Python re wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(PyRegExpWizard, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('Python re Wizard'), self.tr('&Python re Wizard...'), 0, 0, self, 'wizards_python_re') self.action.setStatusTip(self.tr('Python re Wizard')) self.action.setWhatsThis(self.tr( """Python re Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create a Python re string. The generated code is""" """ inserted at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) """ from WizardPlugins.PyRegExpWizard.PyRegExpWizardDialog import \ PyRegExpWizardDialog dlg = PyRegExpWizardDialog(None, True) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), 1) else: return (None, False) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/PluginVcsMercurial.py0000644000175000017500000002005212451233371020216 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the Mercurial version control plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, QCoreApplication from E5Gui.E5Application import e5App import Preferences from Preferences.Shortcuts import readShortcuts from VcsPlugins.vcsMercurial.HgUtilities import getConfigPath import Utilities # Start-Of-Header name = "Mercurial Plugin" author = "Detlev Offenbach " autoactivate = False deactivateable = True version = "6.0.0" pluginType = "version_control" pluginTypename = "Mercurial" className = "VcsMercurialPlugin" packageName = "__core__" shortDescription = "Implements the Mercurial version control interface." longDescription = \ """This plugin provides the Mercurial version control interface.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" def exeDisplayData(): """ Public method to support the display of some executable info. @return dictionary containing the data to query the presence of the executable """ exe = 'hg' if Utilities.isWindowsPlatform(): exe += '.exe' data = { "programEntry": True, "header": QCoreApplication.translate( "VcsMercurialPlugin", "Version Control - Mercurial"), "exe": exe, "versionCommand": 'version', "versionStartsWith": 'Mercurial', "versionPosition": -1, "version": "", "versionCleanup": (0, -1), } return data def getVcsSystemIndicator(): """ Public function to get the indicators for this version control system. @return dictionary with indicator as key and a tuple with the vcs name (string) and vcs display string (string) """ global pluginTypename data = {} exe = 'hg' if Utilities.isWindowsPlatform(): exe += '.exe' if Utilities.isinpath(exe): data[".hg"] = (pluginTypename, displayString()) data["_hg"] = (pluginTypename, displayString()) return data def displayString(): """ Public function to get the display string. @return display string (string) """ exe = 'hg' if Utilities.isWindowsPlatform(): exe += '.exe' if Utilities.isinpath(exe): return QCoreApplication.translate('VcsMercurialPlugin', 'Mercurial') else: return "" mercurialCfgPluginObject = None def createConfigurationPage(configDlg): """ Module function to create the configuration page. @param configDlg reference to the configuration dialog (QDialog) @return reference to the configuration page """ global mercurialCfgPluginObject from VcsPlugins.vcsMercurial.ConfigurationPage.MercurialPage import \ MercurialPage if mercurialCfgPluginObject is None: mercurialCfgPluginObject = VcsMercurialPlugin(None) page = MercurialPage(mercurialCfgPluginObject) return page def getConfigData(): """ Module function returning data as required by the configuration dialog. @return dictionary with key "zzz_mercurialPage" containing the relevant data """ return { "zzz_mercurialPage": [QCoreApplication.translate("VcsMercurialPlugin", "Mercurial"), os.path.join("VcsPlugins", "vcsMercurial", "icons", "preferences-mercurial.png"), createConfigurationPage, "vcsPage", None], } def prepareUninstall(): """ Module function to prepare for an uninstallation. """ if not e5App().getObject("PluginManager").isPluginLoaded( "PluginVcsMercurial"): Preferences.Prefs.settings.remove("Mercurial") class VcsMercurialPlugin(QObject): """ Class implementing the Mercurial version control plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(VcsMercurialPlugin, self).__init__(ui) self.__ui = ui self.__mercurialDefaults = { "StopLogOnCopy": True, # used in log browser "UseLogBrowser": True, "LogLimit": 20, "CommitMessages": 20, "PullUpdate": False, "PreferUnbundle": False, "ServerPort": 8000, "ServerStyle": "", "CleanupPatterns": "*.orig *.rej *~", "CreateBackup": False, "InternalMerge": False, "Encoding": "utf-8", "EncodingMode": "strict", "ConsiderHidden": False, } from VcsPlugins.vcsMercurial.ProjectHelper import HgProjectHelper self.__projectHelperObject = HgProjectHelper(None, None) try: e5App().registerPluginObject( pluginTypename, self.__projectHelperObject, pluginType) except KeyError: pass # ignore duplicate registration readShortcuts(pluginName=pluginTypename) def getProjectHelper(self): """ Public method to get a reference to the project helper object. @return reference to the project helper object """ return self.__projectHelperObject def activate(self): """ Public method to activate this plugin. @return tuple of reference to instantiated viewmanager and activation status (boolean) """ from VcsPlugins.vcsMercurial.hg import Hg self.__object = Hg(self, self.__ui) return self.__object, True def deactivate(self): """ Public method to deactivate this plugin. """ self.__object = None def getPreferences(self, key): """ Public method to retrieve the various settings. @param key the key of the value to get @return the requested setting """ if key in ["StopLogOnCopy", "UseLogBrowser", "PullUpdate", "PreferUnbundle", "CreateBackup", "InternalMerge", "ConsiderHidden"]: return Preferences.toBool(Preferences.Prefs.settings.value( "Mercurial/" + key, self.__mercurialDefaults[key])) elif key in ["LogLimit", "CommitMessages", "ServerPort"]: return int(Preferences.Prefs.settings.value( "Mercurial/" + key, self.__mercurialDefaults[key])) elif key in ["Commits"]: return Preferences.toList(Preferences.Prefs.settings.value( "Mercurial/" + key)) else: return Preferences.Prefs.settings.value( "Mercurial/" + key, self.__mercurialDefaults[key]) def setPreferences(self, key, value): """ Public method to store the various settings. @param key the key of the setting to be set @param value the value to be set """ Preferences.Prefs.settings.setValue("Mercurial/" + key, value) def getGlobalOptions(self): """ Public method to build a list of global options. @return list of global options (list of string) """ args = [] if self.getPreferences("Encoding") != \ self.__mercurialDefaults["Encoding"]: args.append("--encoding") args.append(self.getPreferences("Encoding")) if self.getPreferences("EncodingMode") != \ self.__mercurialDefaults["EncodingMode"]: args.append("--encodingmode") args.append(self.getPreferences("EncodingMode")) if self.getPreferences("ConsiderHidden"): args.append("--hidden") return args def getConfigPath(self): """ Public method to get the filename of the config file. @return filename of the config file (string) """ return getConfigPath() def prepareUninstall(self): """ Public method to prepare for an uninstallation. """ e5App().unregisterPluginObject(pluginTypename) eric-6.0.8/eric/Plugins/PluginEricapi.py0000644000175000017500000001420512451233371017176 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Ericapi plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, QCoreApplication from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action import Utilities from eric6config import getConfig # Start-Of-Header name = "Ericapi Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "EricapiPlugin" packageName = "__core__" shortDescription = "Show the Ericapi dialogs." longDescription = """This plugin implements the Ericapi dialogs.""" \ """ Ericapi is used to generate a QScintilla API file for Python and""" \ """ Ruby projects.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" def exeDisplayData(): """ Public method to support the display of some executable info. @return dictionary containing the data to query the presence of the executable """ exe = 'eric6_api' if Utilities.isWindowsPlatform(): exe = os.path.join(getConfig("bindir"), exe + '.bat') data = { "programEntry": True, "header": QCoreApplication.translate( "EricapiPlugin", "Eric6 API File Generator"), "exe": exe, "versionCommand": '--version', "versionStartsWith": 'eric6_', "versionPosition": -3, "version": "", "versionCleanup": None, } return data class EricapiPlugin(QObject): """ Class implementing the Ericapi plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(EricapiPlugin, self).__init__(ui) self.__ui = ui self.__initialize() def __initialize(self): """ Private slot to (re)initialize the plugin. """ self.__projectAct = None def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ menu = e5App().getObject("Project").getMenu("Apidoc") if menu: self.__projectAct = E5Action( self.tr('Generate API file (eric6_api)'), self.tr('Generate &API file (eric6_api)'), 0, 0, self, 'doc_eric6_api') self.__projectAct.setStatusTip(self.tr( 'Generate an API file using eric6_api')) self.__projectAct.setWhatsThis(self.tr( """Generate API file""" """

Generate an API file using eric6_api.

""" )) self.__projectAct.triggered.connect(self.__doEricapi) e5App().getObject("Project").addE5Actions([self.__projectAct]) menu.addAction(self.__projectAct) e5App().getObject("Project").showMenu.connect(self.__projectShowMenu) return None, True def deactivate(self): """ Public method to deactivate this plugin. """ e5App().getObject("Project").showMenu.disconnect( self.__projectShowMenu) menu = e5App().getObject("Project").getMenu("Apidoc") if menu: menu.removeAction(self.__projectAct) e5App().getObject("Project").removeE5Actions([self.__projectAct]) self.__initialize() def __projectShowMenu(self, menuName, menu): """ Private slot called, when the the project menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) """ if menuName == "Apidoc": if self.__projectAct is not None: self.__projectAct.setEnabled( e5App().getObject("Project").getProjectLanguage() in ["Python", "Python2", "Python3", "Ruby"]) def __doEricapi(self): """ Private slot to perform the eric6_api api generation. """ from DocumentationPlugins.Ericapi.EricapiConfigDialog import \ EricapiConfigDialog eolTranslation = { '\r': 'cr', '\n': 'lf', '\r\n': 'crlf', } project = e5App().getObject("Project") parms = project.getData('DOCUMENTATIONPARMS', "ERIC4API") dlg = EricapiConfigDialog(project, parms) if dlg.exec_() == QDialog.Accepted: args, parms = dlg.generateParameters() project.setData('DOCUMENTATIONPARMS', "ERIC4API", parms) # add parameter for the eol setting if not project.useSystemEol(): args.append( "--eol={0}".format(eolTranslation[project.getEolString()])) # now do the call from DocumentationPlugins.Ericapi.EricapiExecDialog import \ EricapiExecDialog dia = EricapiExecDialog("Ericapi") res = dia.start(args, project.ppath) if res: dia.exec_() outputFileName = Utilities.toNativeSeparators(parms['outputFile']) # add output files to the project data, if they aren't in already for progLanguage in parms['languages']: if "%L" in outputFileName: outfile = outputFileName.replace("%L", progLanguage) else: if len(parms['languages']) == 1: outfile = outputFileName else: root, ext = os.path.splitext(outputFileName) outfile = "{0}-{1}{2}".format( root, progLanguage.lower(), ext) outfile = project.getRelativePath(outfile) if outfile not in project.pdata['OTHERS']: project.pdata['OTHERS'].append(outfile) project.setDirty(True) project.othersAdded(outfile) eric-6.0.8/eric/Plugins/PluginWizardQRegularExpression.py0000644000175000017500000001033312451233371022603 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing the QRegularExpression wizard plugin. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox # Start-Of-Header name = "QRegularExpression Wizard Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "QRegularExpressionWizard" packageName = "__core__" shortDescription = "Show the QRegularExpression wizard." longDescription = """This plugin shows the QRegularExpression wizard.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" class QRegularExpressionWizard(QObject): """ Class implementing the QRegularExpression wizard plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(QRegularExpressionWizard, self).__init__(ui) self.__ui = ui def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ self.__initAction() self.__initMenu() return None, True def deactivate(self): """ Public method to deactivate this plugin. """ menu = self.__ui.getMenu("wizards") if menu: menu.removeAction(self.action) self.__ui.removeE5Actions([self.action], 'wizards') def __initAction(self): """ Private method to initialize the action. """ self.action = E5Action( self.tr('QRegularExpression Wizard'), self.tr('QRegularE&xpression Wizard...'), 0, 0, self, 'wizards_qregularexpression') self.action.setStatusTip(self.tr('QRegularExpression Wizard')) self.action.setWhatsThis(self.tr( """QRegularExpression Wizard""" """

This wizard opens a dialog for entering all the parameters""" """ needed to create a QRegularExpression string. The generated""" """ code is inserted at the current cursor position.

""" )) self.action.triggered.connect(self.__handle) self.__ui.addE5Actions([self.action], 'wizards') def __initMenu(self): """ Private method to add the actions to the right menu. """ menu = self.__ui.getMenu("wizards") if menu: menu.addAction(self.action) def __callForm(self, editor): """ Private method to display a dialog and get the code. @param editor reference to the current editor @return the generated code (string) """ from WizardPlugins.QRegularExpressionWizard\ .QRegularExpressionWizardDialog import \ QRegularExpressionWizardDialog dlg = QRegularExpressionWizardDialog(None, True) if dlg.exec_() == QDialog.Accepted: line, index = editor.getCursorPosition() indLevel = editor.indentation(line) // editor.indentationWidth() if editor.indentationsUseTabs(): indString = '\t' else: indString = editor.indentationWidth() * ' ' return (dlg.getCode(indLevel, indString), 1) else: return (None, False) def __handle(self): """ Private method to handle the wizards action. """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: code, ok = self.__callForm(editor) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction() eric-6.0.8/eric/Plugins/PluginVcsPySvn.py0000644000175000017500000001561112451233371017357 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the PySvn version control plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, QCoreApplication from E5Gui.E5Application import e5App import Preferences from Preferences.Shortcuts import readShortcuts from VcsPlugins.vcsPySvn.SvnUtilities import getConfigPath, getServersPath # Start-Of-Header name = "PySvn Plugin" author = "Detlev Offenbach " autoactivate = False deactivateable = True version = "6.0.0" pluginType = "version_control" pluginTypename = "PySvn" className = "VcsPySvnPlugin" packageName = "__core__" shortDescription = "Implements the PySvn version control interface." longDescription = \ """This plugin provides the PySvn version control interface.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" def exeDisplayData(): """ Public method to support the display of some executable info. @return dictionary containing the data to be shown """ try: import pysvn try: text = os.path.dirname(pysvn.__file__) except AttributeError: text = "PySvn" version = ".".join([str(v) for v in pysvn.version]) except ImportError: text = "PySvn" version = "" data = { "programEntry": False, "header": QCoreApplication.translate( "VcsPySvnPlugin", "Version Control - Subversion (pysvn)"), "text": text, "version": version, } return data def getVcsSystemIndicator(): """ Public function to get the indicators for this version control system. @return dictionary with indicator as key and a tuple with the vcs name (string) and vcs display string (string) """ global pluginTypename data = {} data[".svn"] = (pluginTypename, displayString()) data["_svn"] = (pluginTypename, displayString()) return data def displayString(): """ Public function to get the display string. @return display string (string) """ try: import pysvn # __IGNORE_WARNING__ return QCoreApplication.translate('VcsPySvnPlugin', 'Subversion (pysvn)') except ImportError: return "" subversionCfgPluginObject = None def createConfigurationPage(configDlg): """ Module function to create the configuration page. @param configDlg reference to the configuration dialog (QDialog) @return reference to the configuration page """ global subversionCfgPluginObject from VcsPlugins.vcsPySvn.ConfigurationPage.SubversionPage import \ SubversionPage if subversionCfgPluginObject is None: subversionCfgPluginObject = VcsPySvnPlugin(None) page = SubversionPage(subversionCfgPluginObject) return page def getConfigData(): """ Module function returning data as required by the configuration dialog. @return dictionary with key "zzz_subversionPage" containing the relevant data """ return { "zzz_subversionPage": [QCoreApplication.translate("VcsPySvnPlugin", "Subversion"), os.path.join("VcsPlugins", "vcsPySvn", "icons", "preferences-subversion.png"), createConfigurationPage, "vcsPage", None], } def prepareUninstall(): """ Module function to prepare for an uninstallation. """ if not e5App().getObject("PluginManager").isPluginLoaded( "PluginVcsSubversion"): Preferences.Prefs.settings.remove("Subversion") class VcsPySvnPlugin(QObject): """ Class implementing the PySvn version control plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(VcsPySvnPlugin, self).__init__(ui) self.__ui = ui self.__subversionDefaults = { "StopLogOnCopy": 1, "LogLimit": 20, "CommitMessages": 20, } from VcsPlugins.vcsPySvn.ProjectHelper import SvnProjectHelper self.__projectHelperObject = SvnProjectHelper(None, None) try: e5App().registerPluginObject( pluginTypename, self.__projectHelperObject, pluginType) except KeyError: pass # ignore duplicate registration readShortcuts(pluginName=pluginTypename) def getProjectHelper(self): """ Public method to get a reference to the project helper object. @return reference to the project helper object """ return self.__projectHelperObject def activate(self): """ Public method to activate this plugin. @return tuple of reference to instantiated viewmanager and activation status (boolean) """ from VcsPlugins.vcsPySvn.subversion import Subversion self.__object = Subversion(self, self.__ui) return self.__object, True def deactivate(self): """ Public method to deactivate this plugin. """ self.__object = None def getPreferences(self, key): """ Public method to retrieve the various settings. @param key the key of the value to get @return the requested refactoring setting """ if key in ["StopLogOnCopy"]: return Preferences.toBool(Preferences.Prefs.settings.value( "Subversion/" + key, self.__subversionDefaults[key])) elif key in ["LogLimit", "CommitMessages"]: return int(Preferences.Prefs.settings.value( "Subversion/" + key, self.__subversionDefaults[key])) elif key in ["Commits"]: return Preferences.toList(Preferences.Prefs.settings.value( "Subversion/" + key)) else: return Preferences.Prefs.settings.value("Subversion/" + key) def setPreferences(self, key, value): """ Public method to store the various settings. @param key the key of the setting to be set @param value the value to be set """ Preferences.Prefs.settings.setValue("Subversion/" + key, value) def getServersPath(self): """ Public method to get the filename of the servers file. @return filename of the servers file (string) """ return getServersPath() def getConfigPath(self): """ Public method to get the filename of the config file. @return filename of the config file (string) """ return getConfigPath() def prepareUninstall(self): """ Public method to prepare for an uninstallation. """ e5App().unregisterPluginObject(pluginTypename) eric-6.0.8/eric/Plugins/VcsPlugins/0000755000175000017500000000000012557365360016177 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/0000755000175000017500000000000012557365404021051 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnTagBranchListDialog.py0000644000175000017500000002724412537064321025720 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show a list of tags or branches. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QTimer, QProcess, QRegExp, Qt, pyqtSlot from PyQt5.QtWidgets import QHeaderView, QLineEdit, QDialog, QInputDialog, \ QDialogButtonBox, QTreeWidgetItem from E5Gui import E5MessageBox from .Ui_SvnTagBranchListDialog import Ui_SvnTagBranchListDialog import Preferences class SvnTagBranchListDialog(QDialog, Ui_SvnTagBranchListDialog): """ Class implementing a dialog to show a list of tags or branches. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnTagBranchListDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = QProcess() self.vcs = vcs self.tagsList = None self.allTagsList = None self.tagList.headerItem().setText(self.tagList.columnCount(), "") self.tagList.header().setSortIndicator(3, Qt.AscendingOrder) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.rx_list = QRegExp( r"""\w*\s*(\d+)\s+(\w+)\s+\d*\s*""" r"""((?:\w+\s+\d+|[0-9.]+\s+\w+)\s+[0-9:]+)\s+(.+)/\s*""") def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path, tags, tagsList, allTagsList): """ Public slot to start the svn status command. @param path name of directory to be listed (string) @param tags flag indicating a list of tags is requested (False = branches, True = tags) @param tagsList reference to string list receiving the tags (list of strings) @param allTagsList reference to string list all tags (list of strings) """ self.errorGroup.hide() self.intercept = False if not tags: self.setWindowTitle(self.tr("Subversion Branches List")) self.activateWindow() self.tagsList = tagsList self.allTagsList = allTagsList dname, fname = self.vcs.splitPath(path) self.process.kill() reposURL = self.vcs.svnGetReposName(dname) if reposURL is None: E5MessageBox.critical( self, self.tr("Subversion Error"), self.tr( """The URL of the project repository could not be""" """ retrieved from the working copy. The list operation""" """ will be aborted""")) self.close() return args = [] args.append('list') self.vcs.addArguments(args, self.vcs.options['global']) args.append('--verbose') if self.vcs.otherData["standardLayout"]: # determine the base path of the project in the repository rx_base = QRegExp('(.+)/(trunk|tags|branches).*') if not rx_base.exactMatch(reposURL): E5MessageBox.critical( self, self.tr("Subversion Error"), self.tr( """The URL of the project repository has an""" """ invalid format. The list operation will""" """ be aborted""")) return reposRoot = rx_base.cap(1) if tags: args.append("{0}/tags".format(reposRoot)) else: args.append("{0}/branches".format(reposRoot)) self.path = None else: reposPath, ok = QInputDialog.getText( self, self.tr("Subversion List"), self.tr("Enter the repository URL containing the tags" " or branches"), QLineEdit.Normal, self.vcs.svnNormalizeURL(reposURL)) if not ok: self.close() return if not reposPath: E5MessageBox.critical( self, self.tr("Subversion List"), self.tr("""The repository URL is empty.""" """ Aborting...""")) self.close() return args.append(reposPath) self.path = reposPath self.process.setWorkingDirectory(dname) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.process = None self.__resizeColumns() self.__resort() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __resort(self): """ Private method to resort the tree. """ self.tagList.sortItems( self.tagList.sortColumn(), self.tagList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.tagList.header().resizeSections(QHeaderView.ResizeToContents) self.tagList.header().setStretchLastSection(True) def __generateItem(self, revision, author, date, name): """ Private method to generate a tag item in the taglist. @param revision revision string (string) @param author author of the tag (string) @param date date of the tag (string) @param name name (path) of the tag (string) """ itm = QTreeWidgetItem(self.tagList) itm.setData(0, Qt.DisplayRole, int(revision)) itm.setData(1, Qt.DisplayRole, author) itm.setData(2, Qt.DisplayRole, date) itm.setData(3, Qt.DisplayRole, name) itm.setTextAlignment(0, Qt.AlignRight) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') if self.rx_list.exactMatch(s): rev = "{0:6}".format(self.rx_list.cap(1)) author = self.rx_list.cap(2) date = self.rx_list.cap(3) path = self.rx_list.cap(4) if path == ".": continue self.__generateItem(rev, author, date, path) if not self.vcs.otherData["standardLayout"]: path = self.path + '/' + path if self.tagsList is not None: self.tagsList.append(path) if self.allTagsList is not None: self.allTagsList.append(path) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnTagBranchListDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnBlameDialog.ui0000644000175000017500000001062312060166053024225 0ustar piotrpiotr SvnBlameDialog 0 0 690 750 Subversion Blame true 0 6 true QAbstractItemView::NoSelection false false false Revision Author Line 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close blameList errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnUtilities.py0000644000175000017500000000554412451233371024063 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing some common utility functions for the subversion package. """ from __future__ import unicode_literals import os import Utilities from .Config import DefaultConfig, DefaultIgnores def getServersPath(): """ Module function to get the filename of the servers file. @return filename of the servers file (string) """ if Utilities.isWindowsPlatform(): appdata = os.environ["APPDATA"] return os.path.join(appdata, "Subversion", "servers") else: homedir = Utilities.getHomeDir() return os.path.join(homedir, ".subversion", "servers") def getConfigPath(): """ Module function to get the filename of the config file. @return filename of the config file (string) """ if Utilities.isWindowsPlatform(): appdata = os.environ["APPDATA"] return os.path.join(appdata, "Subversion", "config") else: homedir = Utilities.getHomeDir() return os.path.join(homedir, ".subversion", "config") def createDefaultConfig(): """ Module function to create a default config file suitable for eric. """ config = getConfigPath() try: os.makedirs(os.path.dirname(config)) except OSError: pass try: f = open(config, "w") f.write(DefaultConfig) f.close() except IOError: pass def amendConfig(): """ Module function to amend the config file. """ config = getConfigPath() try: f = open(config, "r") configList = f.read().splitlines() f.close() except IOError: return newConfig = [] ignoresFound = False amendList = [] for line in configList: if line.find("global-ignores") in [0, 2]: ignoresFound = True if line.startswith("# "): line = line[2:] newConfig.append(line) for amend in DefaultIgnores: if amend not in line: amendList.append(amend) elif ignoresFound: if line.startswith("##"): ignoresFound = False if amendList: newConfig.append(" " + " ".join(amendList)) newConfig.append(line) continue elif line.startswith("# "): line = line[2:] newConfig.append(line) oldAmends = amendList[:] amendList = [] for amend in oldAmends: if amend not in line: amendList.append(amend) else: newConfig.append(line) if newConfig != configList: try: f = open(config, "w") f.write("\n".join(newConfig)) f.close() except IOError: pass eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.ui0000644000175000017500000001432412060166053025460 0ustar piotrpiotr SvnRepoBrowserDialog 0 0 650 667 Subversion Repository Browser URL: 0 0 Enter the URL of the repository true QComboBox::InsertAtTop 0 4 true true true 5 File Revision Author Size Date 0 1 Errors <b>Subversion errors</b><p>This shows possible error messages of the svn list and svn info commands.</p> true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok urlCombo repoTree errors input passwordCheckBox sendButton buttonBox buttonBox rejected() SvnRepoBrowserDialog reject() 359 660 286 274 buttonBox accepted() SvnRepoBrowserDialog accept() 146 660 8 472 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnPropSetDialog.py0000644000175000017500000000366512451233371024626 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a new property. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .Ui_SvnPropSetDialog import Ui_SvnPropSetDialog import Utilities import UI.PixmapCache class SvnPropSetDialog(QDialog, Ui_SvnPropSetDialog): """ Class implementing a dialog to enter the data for a new property. """ def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(SvnPropSetDialog, self).__init__(parent) self.setupUi(self) self.fileButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.propFileCompleter = E5FileCompleter(self.propFileEdit) @pyqtSlot() def on_fileButton_clicked(self): """ Private slot called by pressing the file selection button. """ fn = E5FileDialog.getOpenFileName( self, self.tr("Select file for property"), self.propFileEdit.text(), "") if fn: self.propFileEdit.setText(Utilities.toNativeSeparators(fn)) def getData(self): """ Public slot used to retrieve the data entered into the dialog. @return tuple of three values giving the property name, a flag indicating a file was selected and the text of the property or the selected filename. (string, boolean, string) """ if self.fileRadioButton.isChecked(): return (self.propNameEdit.text(), True, self.propFileEdit.text()) else: return (self.propNameEdit.text(), False, self.propTextEdit.toPlainText()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/ProjectBrowserHelper.py0000644000175000017500000011275712451233371025540 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the VCS project browser helper for subversion. """ from __future__ import unicode_literals import os from PyQt5.QtWidgets import QMenu from E5Gui.E5Application import e5App from VCS.ProjectBrowserHelper import VcsProjectBrowserHelper from Project.ProjectBrowserModel import ProjectBrowserFileItem import UI.PixmapCache class SvnProjectBrowserHelper(VcsProjectBrowserHelper): """ Class implementing the VCS project browser helper for subversion. """ def __init__(self, vcsObject, browserObject, projectObject, isTranslationsBrowser, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param browserObject reference to the project browser object @param projectObject reference to the project object @param isTranslationsBrowser flag indicating, the helper is requested for the translations browser (this needs some special treatment) @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectBrowserHelper.__init__(self, vcsObject, browserObject, projectObject, isTranslationsBrowser, parent, name) def showContextMenu(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the file status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ if self.browser.currentItem().data(1) == self.vcs.vcsName(): for act in self.vcsMenuActions: act.setEnabled(True) for act in self.vcsAddMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) if not hasattr(self.browser.currentItem(), 'fileName'): self.blameAct.setEnabled(False) else: for act in self.vcsMenuActions: act.setEnabled(False) for act in self.vcsAddMenuActions: act.setEnabled(True) if 1 in self.browser.specialMenuEntries: try: name = self.browser.currentItem().fileName() except AttributeError: name = self.browser.currentItem().dirName() if not os.path.isdir(name): self.vcsMenuAddTree.setEnabled(False) for act in standardItems: act.setEnabled(True) def showContextMenuMulti(self, menu, standardItems): """ Public slot called before the context menu (multiple selections) is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the files status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ vcsName = self.vcs.vcsName() items = self.browser.getSelectedItems() vcsItems = 0 # determine number of selected items under VCS control for itm in items: if itm.data(1) == vcsName: vcsItems += 1 if vcsItems > 0: if vcsItems != len(items): for act in self.vcsMultiMenuActions: act.setEnabled(False) else: for act in self.vcsMultiMenuActions: act.setEnabled(True) for act in self.vcsAddMultiMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: for act in self.vcsMultiMenuActions: act.setEnabled(False) for act in self.vcsAddMultiMenuActions: act.setEnabled(True) if 1 in self.browser.specialMenuEntries and \ self.__itemsHaveFiles(items): self.vcsMultiMenuAddTree.setEnabled(False) for act in standardItems: act.setEnabled(True) def showContextMenuDir(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the directory status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ if self.browser.currentItem().data(1) == self.vcs.vcsName(): for act in self.vcsDirMenuActions: act.setEnabled(True) for act in self.vcsAddDirMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: for act in self.vcsDirMenuActions: act.setEnabled(False) for act in self.vcsAddDirMenuActions: act.setEnabled(True) for act in standardItems: act.setEnabled(True) def showContextMenuDirMulti(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the directory status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ vcsName = self.vcs.vcsName() items = self.browser.getSelectedItems() vcsItems = 0 # determine number of selected items under VCS control for itm in items: if itm.data(1) == vcsName: vcsItems += 1 if vcsItems > 0: if vcsItems != len(items): for act in self.vcsDirMultiMenuActions: act.setEnabled(False) else: for act in self.vcsDirMultiMenuActions: act.setEnabled(True) for act in self.vcsAddDirMultiMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: for act in self.vcsDirMultiMenuActions: act.setEnabled(False) for act in self.vcsAddDirMultiMenuActions: act.setEnabled(True) for act in standardItems: act.setEnabled(True) ########################################################################### # Protected menu generation methods below ########################################################################### def _addVCSMenu(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ self.vcsMenuActions = [] self.vcsAddMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Update from repository'), self._VCSUpdate) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddMenuActions.append(act) if 1 in self.browser.specialMenuEntries: self.vcsMenuAddTree = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add tree to repository'), self._VCSAddTree) self.vcsAddMenuActions.append(self.vcsMenuAddTree) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Copy'), self.__SVNCopy) self.vcsMenuActions.append(act) act = menu.addAction(self.tr('Move'), self.__SVNMove) self.vcsMenuActions.append(act) if self.vcs.version >= (1, 5, 0): menu.addSeparator() act = menu.addAction( self.tr("Add to Changelist"), self.__SVNAddToChangelist) self.vcsMenuActions.append(act) act = menu.addAction( self.tr("Remove from Changelist"), self.__SVNRemoveFromChangelist) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log'), self._VCSLog) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), self._VCSLogBrowser) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsSbsDiff.png"), self.tr('Show differences side-by-side'), self.__SVNSbsDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__SVNExtendedDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsSbsDiff.png"), self.tr('Show differences side-by-side (extended)'), self.__SVNSbsExtendedDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), self.__SVNUrlDiff) self.vcsMenuActions.append(act) self.blameAct = menu.addAction( self.tr('Show annotated file'), self.__SVNBlame) self.vcsMenuActions.append(self.blameAct) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self._VCSRevert) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Merge changes'), self._VCSMerge) self.vcsMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__SVNResolve) self.vcsMenuActions.append(act) if self.vcs.version >= (1, 2, 0): menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLock.png"), self.tr('Lock'), self.__SVNLock) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Unlock'), self.__SVNUnlock) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Break Lock'), self.__SVNBreakLock) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Steal Lock'), self.__SVNStealLock) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp) self.vcsMenuActions.append(act) act = menu.addAction( self.tr('List Properties'), self.__SVNListProps) self.vcsMenuActions.append(act) act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp) self.vcsMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menu = menu def _addVCSMenuMulti(self, mainMenu): """ Protected method used to add the VCS menu for multi selection to all project browsers. @param mainMenu reference to the menu to be amended """ self.vcsMultiMenuActions = [] self.vcsAddMultiMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Update from repository'), self._VCSUpdate) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddMultiMenuActions.append(act) if 1 in self.browser.specialMenuEntries: self.vcsMultiMenuAddTree = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add tree to repository'), self._VCSAddTree) self.vcsAddMultiMenuActions.append(self.vcsMultiMenuAddTree) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsMultiMenuActions.append(act) if self.vcs.version >= (1, 5, 0): menu.addSeparator() act = menu.addAction( self.tr("Add to Changelist"), self.__SVNAddToChangelist) self.vcsMenuActions.append(act) act = menu.addAction( self.tr("Remove from Changelist"), self.__SVNRemoveFromChangelist) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__SVNExtendedDiff) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), self.__SVNUrlDiff) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self._VCSRevert) self.vcsMultiMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__SVNResolve) self.vcsMultiMenuActions.append(act) if self.vcs.version >= (1, 2, 0): menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLock.png"), self.tr('Lock'), self.__SVNLock) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Unlock'), self.__SVNUnlock) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Break Lock'), self.__SVNBreakLock) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Steal Lock'), self.__SVNStealLock) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp) self.vcsMultiMenuActions.append(act) act = menu.addAction( self.tr('List Properties'), self.__SVNListProps) self.vcsMultiMenuActions.append(act) act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp) self.vcsMultiMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuMulti = menu def _addVCSMenuBack(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuBack = menu def _addVCSMenuDir(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ if mainMenu is None: return self.vcsDirMenuActions = [] self.vcsAddDirMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Update from repository'), self._VCSUpdate) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Copy'), self.__SVNCopy) self.vcsDirMenuActions.append(act) act = menu.addAction(self.tr('Move'), self.__SVNMove) self.vcsDirMenuActions.append(act) if self.vcs.version >= (1, 5, 0): menu.addSeparator() act = menu.addAction( self.tr("Add to Changelist"), self.__SVNAddToChangelist) self.vcsMenuActions.append(act) act = menu.addAction( self.tr("Remove from Changelist"), self.__SVNRemoveFromChangelist) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log'), self._VCSLog) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), self._VCSLogBrowser) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__SVNExtendedDiff) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), self.__SVNUrlDiff) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self._VCSRevert) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Merge changes'), self._VCSMerge) self.vcsDirMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__SVNResolve) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp) self.vcsDirMenuActions.append(act) act = menu.addAction( self.tr('List Properties'), self.__SVNListProps) self.vcsDirMenuActions.append(act) act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp) self.vcsDirMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuDir = menu def _addVCSMenuDirMulti(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ if mainMenu is None: return self.vcsDirMultiMenuActions = [] self.vcsAddDirMultiMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Update from repository'), self._VCSUpdate) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsDirMultiMenuActions.append(act) if self.vcs.version >= (1, 5, 0): menu.addSeparator() act = menu.addAction( self.tr("Add to Changelist"), self.__SVNAddToChangelist) self.vcsMenuActions.append(act) act = menu.addAction( self.tr("Remove from Changelist"), self.__SVNRemoveFromChangelist) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__SVNExtendedDiff) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), self.__SVNUrlDiff) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self._VCSRevert) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Merge changes'), self._VCSMerge) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__SVNResolve) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( self.tr('List Properties'), self.__SVNListProps) self.vcsDirMultiMenuActions.append(act) act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuDirMulti = menu ########################################################################### # Menu handling methods below ########################################################################### def __SVNCopy(self): """ Private slot called by the context menu to copy the selected file. """ itm = self.browser.currentItem() try: fn = itm.fileName() except AttributeError: fn = itm.dirName() self.vcs.svnCopy(fn, self.project) def __SVNMove(self): """ Private slot called by the context menu to move the selected file. """ itm = self.browser.currentItem() try: fn = itm.fileName() except AttributeError: fn = itm.dirName() isFile = os.path.isfile(fn) movefiles = self.browser.project.getFiles(fn) if self.vcs.vcsMove(fn, self.project): if isFile: self.browser.closeSourceWindow.emit(fn) else: for mf in movefiles: self.browser.closeSourceWindow.emit(mf) def __SVNResolve(self): """ Private slot called by the context menu to resolve conflicts of a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnResolve(names) def __SVNListProps(self): """ Private slot called by the context menu to list the subversion properties of a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnListProps(names) def __SVNSetProp(self): """ Private slot called by the context menu to set a subversion property of a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnSetProp(names) def __SVNDelProp(self): """ Private slot called by the context menu to delete a subversion property of a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnDelProp(names) def __SVNExtendedDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository. This gives the chance to enter the revisions to compare. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnExtendedDiff(names) def __SVNUrlDiff(self): """ Private slot called by the context menu to show the difference of a file of two repository URLs. This gives the chance to enter the repository URLs to compare. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnUrlDiff(names) def __SVNSbsDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository side-by-side. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.svnSbsDiff(fn) def __SVNSbsExtendedDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository side-by-side. It allows the selection of revisions to compare. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.svnSbsDiff(fn, extended=True) def __SVNBlame(self): """ Private slot called by the context menu to show the blame of a file. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.svnBlame(fn) def __SVNLock(self): """ Private slot called by the context menu to lock files in the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnLock(names) def __SVNUnlock(self): """ Private slot called by the context menu to unlock files in the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnUnlock(names) def __SVNBreakLock(self): """ Private slot called by the context menu to break lock files in the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnUnlock(names, breakIt=True) def __SVNStealLock(self): """ Private slot called by the context menu to steal lock files in the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnLock(names, stealIt=True) def __SVNConfigure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("zzz_subversionPage") def __SVNAddToChangelist(self): """ Private slot called by the context menu to add files to a changelist. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnAddToChangelist(names) def __SVNRemoveFromChangelist(self): """ Private slot called by the context menu to remove files from their changelist. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnRemoveFromChangelist(names) ########################################################################### # Some private utility methods below ########################################################################### def __itemsHaveFiles(self, items): """ Private method to check, if items contain file type items. @param items items to check (list of QTreeWidgetItems) @return flag indicating items contain file type items (boolean) """ for itm in items: if isinstance(itm, ProjectBrowserFileItem): return True return False eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnLogDialog.ui0000644000175000017500000001160512203730423023724 0ustar piotrpiotr SvnLogDialog 0 0 751 649 Subversion Log 0 3 Log <b>Subversion Log</b><p>This shows the output of the svn log command. By clicking on the links you may show the difference between versions.</p> Select to show differences side-by-side Show differences side-by-side 0 1 Errors <b>Subversion log errors</b><p>This shows possible error messages of the svn log command.</p> true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Close contents sbsCheckBox errors input passwordCheckBox sendButton buttonBox buttonBox rejected() SvnLogDialog close() 262 624 271 647 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnDialog.ui0000644000175000017500000001016012060166053023260 0ustar piotrpiotr SvnDialog 0 0 593 499 Subversion true 0 2 Output true false 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource resultbox errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/icons/0000755000175000017500000000000012060166053022150 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/icons/preferences-subversion.png0000644000175000017500000000130012060166053027346 0ustar piotrpiotr‰PNG  IHDRÄ´l;‡IDAT8Í”ÏKTQÇ?÷½7oÆÞ›¦Ž†â&GÄRPlS‹¢EQ A›v­‚Ú¹uÝ¿ÑFhQA%”š%Š) VþÀudÔ÷ëÞiQèˆ?h"©—s¸÷{?÷p8犛ݽ¾Ò ›:‘_>œïób]¸¾ü¹<™+\?Àõ®àz08ÓŽúGàÀ÷ÿ>8³ºÄ«§÷™ü»`C®ÓÝu›µÙ<Ï9\[¸¾¾žÆÆMMM(¥@?X[PÆÑh”‘i‚P9f¤èPí6xk}ÏÝÜ#p¶²¬./LDXÊ8Œs‰—ŸDÎF†­ìúÁàµEÖ>=Âö¦QRnæ”bàåŠÅ<¦æ±’qBCh‘SÔ—8Ì¿À÷÷ÖÛXú:ƽ®NÊÊÊù0•%‹aHŸ:ë"7®w01µ@""9¥i9ZšQî¯'g‰'k÷‚ÃöqúûI5438)°¬M¦Ž.ï{“NÕ2»ª³²ÚcxXb‘± ì²³û—"Y}ŠçC‹<ì›A…w^5B4´_£çÉ–%lî´'5zž}Ä9Ö@‘•Ø¿ºaRÓr‰ˆ©#„Ø%¨¨J6ÓÌ-;”ÚŠÌòw„GA,YG¸X⸕gñËѪ6@Ëk7!€ÝÐ|óeŽÑáw\9—¦2`Ä,“„m’°CÜêháò™¬,Lídü»67;ƒm[ˆ Kyq194|©ŸÊŠR2©:œ¾7Ä V’;w)©i£îtÏW¸¾Äqf>1:ü–dõ…Â3nn?Omºô¾Ìmï ¡±è'‰§¯"s:®' iMhYQ4}ï5M70ò:êÿùèÿ9ø¸Cû¼N#ãªIEND®B`‚eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/icons/subversion.png0000644000175000017500000000130012060166053025047 0ustar piotrpiotr‰PNG  IHDRÄ´l;‡IDAT8Í”ÏKTQÇ?÷½7oÆÞ›¦Ž†â&GÄRPlS‹¢EQ A›v­‚Ú¹uÝ¿ÑFhQA%”š%Š) VþÀudÔ÷ëÞiQèˆ?h"©—s¸÷{?÷p8犛ݽ¾Ò ›:‘_>œïób]¸¾ü¹<™+\?Àõ®àz08ÓŽúGàÀ÷ÿ>8³ºÄ«§÷™ü»`C®ÓÝu›µÙ<Ï9\[¸¾¾žÆÆMMM(¥@?X[PÆÑh”‘i‚P9f¤èPí6xk}ÏÝÜ#p¶²¬./LDXÊ8Œs‰—ŸDÎF†­ìúÁàµEÖ>=Âö¦QRnæ”bàåŠÅ<¦æ±’qBCh‘SÔ—8Ì¿À÷÷ÖÛXú:ƽ®NÊÊÊù0•%‹aHŸ:ë"7®w01µ@""9¥i9ZšQî¯'g‰'k÷‚ÃöqúûI5438)°¬M¦Ž.ï{“NÕ2»ª³²ÚcxXb‘± ì²³û—"Y}ŠçC‹<ì›A…w^5B4´_£çÉ–%lî´'5zž}Ä9Ö@‘•Ø¿ºaRÓr‰ˆ©#„Ø%¨¨J6ÓÌ-;”ÚŠÌòw„GA,YG¸X⸕gñËѪ6@Ëk7!€ÝÐ|óeŽÑáw\9—¦2`Ä,“„m’°CÜêháò™¬,Lídü»67;ƒm[ˆ Kyq194|©ŸÊŠR2©:œ¾7Ä V’;w)©i£îtÏW¸¾Äqf>1:ü–dõ…Â3nn?Omºô¾Ìmï ¡±è'‰§¯"s:®' iMhYQ4}ï5M70ò:êÿùèÿ9ø¸Cû¼N#ãªIEND®B`‚eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnChangeListsDialog.py0000644000175000017500000002317212537064321025433 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to browse the change lists. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QRegExp, QTimer from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QListWidgetItem, \ QLineEdit from E5Gui import E5MessageBox from .Ui_SvnChangeListsDialog import Ui_SvnChangeListsDialog import Preferences class SvnChangeListsDialog(QDialog, Ui_SvnChangeListsDialog): """ Class implementing a dialog to browse the change lists. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnChangeListsDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = None self.vcs = vcs self.rx_status = QRegExp( '(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*') # flags (8 or 9 anything), revision, changed rev, author, path self.rx_status2 = \ QRegExp('(.{8,9})\\s+(.+)\\s*') # flags (8 or 9 anything), path self.rx_changelist = \ QRegExp('--- \\S+ .([\\w\\s]+).:\\s+') # three dashes, Changelist (translated), quote, # changelist name, quote, : @pyqtSlot(QListWidgetItem, QListWidgetItem) def on_changeLists_currentItemChanged(self, current, previous): """ Private slot to handle the selection of a new item. @param current current item (QListWidgetItem) @param previous previous current item (QListWidgetItem) """ self.filesList.clear() if current is not None: changelist = current.text() if changelist in self.changeListsDict: self.filesList.addItems( sorted(self.changeListsDict[changelist])) def start(self, path): """ Public slot to populate the data. @param path directory name to show change lists for (string) """ self.changeListsDict = {} self.filesLabel.setText( self.tr("Files (relative to {0}):").format(path)) self.errorGroup.hide() self.intercept = False self.path = path self.currentChangelist = "" self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) args = [] args.append('status') self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['status']) if '--verbose' not in self.vcs.options['global'] and \ '--verbose' not in self.vcs.options['status']: args.append('--verbose') if isinstance(path, list): self.dname, fnames = self.vcs.splitPathList(path) self.vcs.addArguments(args, fnames) else: self.dname, fname = self.vcs.splitPath(path) args.append(fname) self.process.setWorkingDirectory(self.dname) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.inputGroup.setEnabled(False) self.inputGroup.hide() if len(self.changeListsDict) == 0: self.changeLists.addItem(self.tr("No changelists found")) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) else: self.changeLists.addItems(sorted(self.changeListsDict.keys())) self.changeLists.setCurrentRow(0) self.changeLists.setFocus(Qt.OtherFocusReason) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.process is not None: self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') if self.currentChangelist != "" and \ self.rx_status.exactMatch(s): file = self.rx_status.cap(5).strip() filename = file.replace(self.path + os.sep, "") if filename not in \ self.changeListsDict[self.currentChangelist]: self.changeListsDict[self.currentChangelist].append( filename) elif self.currentChangelist != "" and \ self.rx_status2.exactMatch(s): file = self.rx_status2.cap(2).strip() filename = file.replace(self.path + os.sep, "") if filename not in \ self.changeListsDict[self.currentChangelist]: self.changeListsDict[self.currentChangelist].append( filename) elif self.rx_changelist.exactMatch(s): self.currentChangelist = self.rx_changelist.cap(1) if self.currentChangelist not in self.changeListsDict: self.changeListsDict[self.currentChangelist] = [] def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnChangeListsDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnOptionsDialog.py0000644000175000017500000001063512451233371024660 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter options used to start a project in the VCS. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QDir, pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_SvnOptionsDialog import Ui_SvnOptionsDialog from .Config import ConfigSvnProtocols import Utilities import UI.PixmapCache class SvnOptionsDialog(QDialog, Ui_SvnOptionsDialog): """ Class implementing a dialog to enter options used to start a project in the repository. """ def __init__(self, vcs, project, parent=None): """ Constructor @param vcs reference to the version control object @param project reference to the project object @param parent parent widget (QWidget) """ super(SvnOptionsDialog, self).__init__(parent) self.setupUi(self) self.vcsUrlButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.vcsDirectoryCompleter = E5DirCompleter(self.vcsUrlEdit) self.project = project self.protocolCombo.addItems(ConfigSvnProtocols) hd = Utilities.toNativeSeparators(QDir.homePath()) hd = os.path.join(hd, 'subversionroot') self.vcsUrlEdit.setText(hd) self.vcs = vcs self.localPath = hd self.networkPath = "localhost/" self.localProtocol = True msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_vcsUrlButton_clicked(self): """ Private slot to display a selection dialog. """ if self.protocolCombo.currentText() == "file://": directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Repository-Directory"), self.vcsUrlEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.vcsUrlEdit.setText( Utilities.toNativeSeparators(directory)) else: from .SvnRepoBrowserDialog import SvnRepoBrowserDialog dlg = SvnRepoBrowserDialog(self.vcs, mode="select", parent=self) dlg.start( self.protocolCombo.currentText() + self.vcsUrlEdit.text()) if dlg.exec_() == QDialog.Accepted: url = dlg.getSelectedUrl() if url: protocol = url.split("://")[0] path = url.split("://")[1] self.protocolCombo.setCurrentIndex( self.protocolCombo.findText(protocol + "://")) self.vcsUrlEdit.setText(path) @pyqtSlot(str) def on_protocolCombo_activated(self, protocol): """ Private slot to switch the status of the directory selection button. @param protocol selected protocol (string) """ if protocol == "file://": self.networkPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.localPath) self.vcsUrlLabel.setText(self.tr("Pat&h:")) self.localProtocol = True else: if self.localProtocol: self.localPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.networkPath) self.vcsUrlLabel.setText(self.tr("&URL:")) self.localProtocol = False @pyqtSlot(str) def on_vcsUrlEdit_textChanged(self, txt): """ Private slot to handle changes of the URL. @param txt current text of the line edit (string) """ enable = "://" not in txt self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) def getData(self): """ Public slot to retrieve the data entered into the dialog. @return a dictionary containing the data entered """ scheme = self.protocolCombo.currentText() url = self.vcsUrlEdit.text() vcsdatadict = { "url": '{0}{1}'.format(scheme, url), "message": self.vcsLogEdit.text(), "standardLayout": self.layoutCheckBox.isChecked(), } return vcsdatadict eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/subversion.py0000644000175000017500000026011112451233371023611 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the version control systems interface to Subversion. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os import re import shutil from PyQt5.QtCore import pyqtSignal, QProcess, QRegExp, QCoreApplication from PyQt5.QtWidgets import QLineEdit, QDialog, QInputDialog, QApplication from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from VCS.VersionControl import VersionControl from .SvnDialog import SvnDialog from .SvnUtilities import getConfigPath, amendConfig, createDefaultConfig import Preferences import Utilities class Subversion(VersionControl): """ Class implementing the version control systems interface to Subversion. @signal committed() emitted after the commit action has completed """ committed = pyqtSignal() def __init__(self, plugin, parent=None, name=None): """ Constructor @param plugin reference to the plugin object @param parent parent widget (QWidget) @param name name of this object (string) """ VersionControl.__init__(self, parent, name) self.defaultOptions = { 'global': [''], 'commit': [''], 'checkout': [''], 'update': [''], 'add': [''], 'remove': [''], 'diff': [''], 'log': [''], 'history': [''], 'status': [''], 'tag': [''], 'export': [''] } self.interestingDataKeys = [ "standardLayout", ] self.__plugin = plugin self.__ui = parent self.options = self.defaultOptions self.otherData["standardLayout"] = True self.tagsList = [] self.branchesList = [] self.allTagsBranchesList = [] self.mergeList = [[], [], []] self.showedTags = False self.showedBranches = False self.tagTypeList = [ 'tags', 'branches', ] self.commandHistory = [] self.wdHistory = [] if "SVN_ASP_DOT_NET_HACK" in os.environ: self.adminDir = '_svn' else: self.adminDir = '.svn' self.log = None self.diff = None self.sbsDiff = None self.status = None self.propList = None self.tagbranchList = None self.blame = None self.repoBrowser = None self.logBrowser = None # regular expression object for evaluation of the status output self.rx_status1 = QRegExp( '(.{8})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)') self.rx_status2 = QRegExp('(.{8})\\s+(.+)\\s*') self.statusCache = {} self.__commitData = {} self.__commitDialog = None self.__wcng = True # assume new generation working copy metadata format def getPlugin(self): """ Public method to get a reference to the plugin object. @return reference to the plugin object (VcsSubversionPlugin) """ return self.__plugin def vcsShutdown(self): """ Public method used to shutdown the Subversion interface. """ if self.log is not None: self.log.close() if self.diff is not None: self.diff.close() if self.sbsDiff is not None: self.sbsDiff.close() if self.status is not None: self.status.close() if self.propList is not None: self.propList.close() if self.tagbranchList is not None: self.tagbranchList.close() if self.blame is not None: self.blame.close() if self.repoBrowser is not None: self.repoBrowser.close() if self.logBrowser is not None: self.logBrowser.close() def vcsExists(self): """ Public method used to test for the presence of the svn executable. @return flag indicating the existance (boolean) and an error message (string) """ self.versionStr = '' errMsg = "" ioEncoding = Preferences.getSystem("IOEncoding") process = QProcess() process.start('svn', ['--version']) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = \ str(process.readAllStandardOutput(), ioEncoding, 'replace') self.versionStr = output.split()[2] v = list(re.match(r'.*?(\d+)\.(\d+)\.?(\d+)?', self.versionStr) .groups()) for i in range(3): try: v[i] = int(v[i]) except TypeError: v[i] = 0 except IndexError: v.append(0) self.version = tuple(v) return True, errMsg else: if finished: errMsg = self.tr( "The svn process finished with the exit code {0}")\ .format(process.exitCode()) else: errMsg = self.tr( "The svn process did not finish within 30s.") else: errMsg = self.tr("Could not start the svn executable.") return False, errMsg def vcsInit(self, vcsDir, noDialog=False): """ Public method used to initialize the subversion repository. The subversion repository has to be initialized from outside eric6 because the respective command always works locally. Therefore we always return TRUE without doing anything. @param vcsDir name of the VCS directory (string) @param noDialog flag indicating quiet operations (boolean) @return always TRUE """ return True def vcsConvertProject(self, vcsDataDict, project): """ Public method to convert an uncontrolled project to a version controlled project. @param vcsDataDict dictionary of data required for the conversion @param project reference to the project object """ success = self.vcsImport(vcsDataDict, project.ppath)[0] if not success: E5MessageBox.critical( self.__ui, self.tr("Create project in repository"), self.tr( """The project could not be created in the repository.""" """ Maybe the given repository doesn't exist or the""" """ repository server is down.""")) else: cwdIsPpath = False if os.getcwd() == project.ppath: os.chdir(os.path.dirname(project.ppath)) cwdIsPpath = True tmpProjectDir = "{0}_tmp".format(project.ppath) shutil.rmtree(tmpProjectDir, True) os.rename(project.ppath, tmpProjectDir) os.makedirs(project.ppath) self.vcsCheckout(vcsDataDict, project.ppath) if cwdIsPpath: os.chdir(project.ppath) self.vcsCommit(project.ppath, vcsDataDict["message"], True) pfn = project.pfile if not os.path.isfile(pfn): pfn += "z" if not os.path.isfile(pfn): E5MessageBox.critical( self.__ui, self.tr("New project"), self.tr( """The project could not be checked out of the""" """ repository.
""" """Restoring the original contents.""")) if os.getcwd() == project.ppath: os.chdir(os.path.dirname(project.ppath)) cwdIsPpath = True else: cwdIsPpath = False shutil.rmtree(project.ppath, True) os.rename(tmpProjectDir, project.ppath) project.pdata["VCS"] = ['None'] project.vcs = None project.setDirty(True) project.saveProject() project.closeProject() return shutil.rmtree(tmpProjectDir, True) project.closeProject(noSave=True) project.openProject(pfn) def vcsImport(self, vcsDataDict, projectDir, noDialog=False): """ Public method used to import the project into the Subversion repository. @param vcsDataDict dictionary of data required for the import @param projectDir project directory (string) @param noDialog flag indicating quiet operations @return flag indicating an execution without errors (boolean) and a flag indicating the version control status (boolean) """ noDialog = False msg = vcsDataDict["message"] if not msg: msg = '***' vcsDir = self.svnNormalizeURL(vcsDataDict["url"]) if vcsDir.startswith('/'): vcsDir = 'file://{0}'.format(vcsDir) elif vcsDir[1] in ['|', ':']: vcsDir = 'file:///{0}'.format(vcsDir) project = vcsDir[vcsDir.rfind('/') + 1:] # create the dir structure to be imported into the repository tmpDir = '{0}_tmp'.format(projectDir) try: os.makedirs(tmpDir) if self.otherData["standardLayout"]: os.mkdir(os.path.join(tmpDir, project)) os.mkdir(os.path.join(tmpDir, project, 'branches')) os.mkdir(os.path.join(tmpDir, project, 'tags')) shutil.copytree( projectDir, os.path.join(tmpDir, project, 'trunk')) else: shutil.copytree(projectDir, os.path.join(tmpDir, project)) except OSError: if os.path.isdir(tmpDir): shutil.rmtree(tmpDir, True) return False, False args = [] args.append('import') self.addArguments(args, self.options['global']) args.append('-m') args.append(msg) args.append(self.__svnURL(vcsDir)) if noDialog: status = self.startSynchronizedProcess( QProcess(), "svn", args, os.path.join(tmpDir, project)) else: dia = SvnDialog( self.tr('Importing project into Subversion repository')) res = dia.startProcess(args, os.path.join(tmpDir, project)) if res: dia.exec_() status = dia.normalExit() shutil.rmtree(tmpDir, True) return status, False def vcsCheckout(self, vcsDataDict, projectDir, noDialog=False): """ Public method used to check the project out of the Subversion repository. @param vcsDataDict dictionary of data required for the checkout @param projectDir project directory to create (string) @param noDialog flag indicating quiet operations @return flag indicating an execution without errors (boolean) """ noDialog = False try: tag = vcsDataDict["tag"] except KeyError: tag = None vcsDir = self.svnNormalizeURL(vcsDataDict["url"]) if vcsDir.startswith('/'): vcsDir = 'file://{0}'.format(vcsDir) elif vcsDir[1] in ['|', ':']: vcsDir = 'file:///{0}'.format(vcsDir) if self.otherData["standardLayout"]: if tag is None or tag == '': svnUrl = '{0}/trunk'.format(vcsDir) else: if not tag.startswith('tags') and \ not tag.startswith('branches'): type, ok = QInputDialog.getItem( None, self.tr("Subversion Checkout"), self.tr( "The tag must be a normal tag (tags) or" " a branch tag (branches)." " Please select from the list."), self.tagTypeList, 0, False) if not ok: return False tag = '{0}/{1}'.format(type, tag) svnUrl = '{0}/{1}'.format(vcsDir, tag) else: svnUrl = vcsDir args = [] args.append('checkout') self.addArguments(args, self.options['global']) self.addArguments(args, self.options['checkout']) args.append(self.__svnURL(svnUrl)) args.append(projectDir) if noDialog: return self.startSynchronizedProcess(QProcess(), 'svn', args) else: dia = SvnDialog( self.tr('Checking project out of Subversion repository')) res = dia.startProcess(args) if res: dia.exec_() return dia.normalExit() def vcsExport(self, vcsDataDict, projectDir): """ Public method used to export a directory from the Subversion repository. @param vcsDataDict dictionary of data required for the checkout @param projectDir project directory to create (string) @return flag indicating an execution without errors (boolean) """ try: tag = vcsDataDict["tag"] except KeyError: tag = None vcsDir = self.svnNormalizeURL(vcsDataDict["url"]) if vcsDir.startswith('/') or vcsDir[1] == '|': vcsDir = 'file://{0}'.format(vcsDir) if self.otherData["standardLayout"]: if tag is None or tag == '': svnUrl = '{0}/trunk'.format(vcsDir) else: if not tag.startswith('tags') and \ not tag.startswith('branches'): type, ok = QInputDialog.getItem( None, self.tr("Subversion Export"), self.tr( "The tag must be a normal tag (tags) or" " a branch tag (branches)." " Please select from the list."), self.tagTypeList, 0, False) if not ok: return False tag = '{0}/{1}'.format(type, tag) svnUrl = '{0}/{1}'.format(vcsDir, tag) else: svnUrl = vcsDir args = [] args.append('export') self.addArguments(args, self.options['global']) args.append("--force") args.append(self.__svnURL(svnUrl)) args.append(projectDir) dia = SvnDialog( self.tr('Exporting project from Subversion repository')) res = dia.startProcess(args) if res: dia.exec_() return dia.normalExit() def vcsCommit(self, name, message, noDialog=False): """ Public method used to make the change of a file/directory permanent in the Subversion repository. @param name file/directory name to be committed (string or list of strings) @param message message for this operation (string) @param noDialog flag indicating quiet operations """ msg = message if not noDialog and not msg: # call CommitDialog and get message from there if self.__commitDialog is None: from .SvnCommitDialog import SvnCommitDialog self.__commitDialog = SvnCommitDialog(self, self.__ui) self.__commitDialog.accepted.connect(self.__vcsCommit_Step2) self.__commitDialog.show() self.__commitDialog.raise_() self.__commitDialog.activateWindow() self.__commitData["name"] = name self.__commitData["msg"] = msg self.__commitData["noDialog"] = noDialog if noDialog: self.__vcsCommit_Step2() def __vcsCommit_Step2(self): """ Private slot performing the second step of the commit action. """ name = self.__commitData["name"] msg = self.__commitData["msg"] noDialog = self.__commitData["noDialog"] if not noDialog: # check, if there are unsaved changes, that should be committed if isinstance(name, list): nameList = name else: nameList = [name] ok = True for nam in nameList: # check for commit of the project if os.path.isdir(nam): project = e5App().getObject("Project") if nam == project.getProjectPath(): ok &= project.checkAllScriptsDirty( reportSyntaxErrors=True) and \ project.checkDirty() continue elif os.path.isfile(nam): editor = e5App().getObject("ViewManager")\ .getOpenEditor(nam) if editor: ok &= editor.checkDirty() if not ok: break if not ok: res = E5MessageBox.yesNo( self.__ui, self.tr("Commit Changes"), self.tr( """The commit affects files, that have unsaved""" """ changes. Shall the commit be continued?"""), icon=E5MessageBox.Warning) if not res: return if self.__commitDialog is not None: msg = self.__commitDialog.logMessage() if self.__commitDialog.hasChangelists(): changelists, keepChangelists = \ self.__commitDialog.changelistsData() else: changelists, keepChangelists = [], False self.__commitDialog.deleteLater() self.__commitDialog = None else: changelists, keepChangelists = [], False if not msg: msg = '***' args = [] args.append('commit') self.addArguments(args, self.options['global']) self.addArguments(args, self.options['commit']) if keepChangelists: args.append("--keep-changelists") for changelist in changelists: args.append("--changelist") args.append(changelist) args.append("-m") args.append(msg) if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, fnames) else: dname, fname = self.splitPath(name) args.append(fname) if self.svnGetReposName(dname).startswith('http') or \ self.svnGetReposName(dname).startswith('svn'): noDialog = False if noDialog: self.startSynchronizedProcess(QProcess(), "svn", args, dname) else: dia = SvnDialog( self.tr('Commiting changes to Subversion repository')) res = dia.startProcess(args, dname) if res: dia.exec_() self.committed.emit() self.checkVCSStatus() def vcsUpdate(self, name, noDialog=False): """ Public method used to update a file/directory with the Subversion repository. @param name file/directory name to be updated (string or list of strings) @param noDialog flag indicating quiet operations (boolean) @return flag indicating, that the update contained an add or delete (boolean) """ args = [] args.append('update') self.addArguments(args, self.options['global']) self.addArguments(args, self.options['update']) if self.version >= (1, 5, 0): args.append('--accept') args.append('postpone') if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, fnames) else: dname, fname = self.splitPath(name) args.append(fname) if noDialog: self.startSynchronizedProcess(QProcess(), "svn", args, dname) res = False else: dia = SvnDialog( self.tr('Synchronizing with the Subversion repository')) res = dia.startProcess(args, dname, True) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() return res def vcsAdd(self, name, isDir=False, noDialog=False): """ Public method used to add a file/directory to the Subversion repository. @param name file/directory name to be added (string) @param isDir flag indicating name is a directory (boolean) @param noDialog flag indicating quiet operations """ args = [] args.append('add') self.addArguments(args, self.options['global']) self.addArguments(args, self.options['add']) args.append('--non-recursive') if noDialog and '--force' not in args: args.append('--force') if isinstance(name, list): if isDir: dname, fname = os.path.split(name[0]) else: dname, fnames = self.splitPathList(name) else: if isDir: dname, fname = os.path.split(name) else: dname, fname = self.splitPath(name) tree = [] wdir = dname if self.__wcng: repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return # oops, project is not version controlled while os.path.normcase(dname) != os.path.normcase(repodir) and \ (os.path.normcase(dname) not in self.statusCache or self.statusCache[os.path.normcase(dname)] == self.canBeAdded): # add directories recursively, if they aren't in the # repository already tree.insert(-1, dname) dname = os.path.dirname(dname) wdir = dname else: while not os.path.exists(os.path.join(dname, self.adminDir)): # add directories recursively, if they aren't in the # repository already tree.insert(-1, dname) dname = os.path.dirname(dname) wdir = dname self.addArguments(args, tree) if isinstance(name, list): tree2 = [] for n in name: d = os.path.dirname(n) if self.__wcng: repodir = d while not os.path.isdir( os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return # oops, project is not version controlled while os.path.normcase(d) != \ os.path.normcase(repodir) and \ (d not in tree2 + tree) and \ (os.path.normcase(d) not in self.statusCache or self.statusCache[os.path.normcase(d)] == self.canBeAdded): tree2.append(d) d = os.path.dirname(d) else: while not os.path.exists(os.path.join(d, self.adminDir)): if d in tree2 + tree: break tree2.append(d) d = os.path.dirname(d) tree2.reverse() self.addArguments(args, tree2) self.addArguments(args, name) else: args.append(name) if noDialog: self.startSynchronizedProcess(QProcess(), "svn", args, wdir) else: dia = SvnDialog( self.tr('Adding files/directories to the Subversion' ' repository')) res = dia.startProcess(args, wdir) if res: dia.exec_() def vcsAddBinary(self, name, isDir=False): """ Public method used to add a file/directory in binary mode to the Subversion repository. @param name file/directory name to be added (string) @param isDir flag indicating name is a directory (boolean) """ self.vcsAdd(name, isDir) def vcsAddTree(self, path): """ Public method to add a directory tree rooted at path to the Subversion repository. @param path root directory of the tree to be added (string or list of strings)) """ args = [] args.append('add') self.addArguments(args, self.options['global']) self.addArguments(args, self.options['add']) tree = [] if isinstance(path, list): dname, fnames = self.splitPathList(path) for n in path: d = os.path.dirname(n) if self.__wcng: repodir = d while not os.path.isdir( os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return # oops, project is not version controlled while os.path.normcase(d) != \ os.path.normcase(repodir) and \ (d not in tree) and \ (os.path.normcase(d) not in self.statusCache or self.statusCache[os.path.normcase(d)] == self.canBeAdded): tree.append(d) d = os.path.dirname(d) else: while not os.path.exists(os.path.join(d, self.adminDir)): # add directories recursively, # if they aren't in the repository already if d in tree: break tree.append(d) d = os.path.dirname(d) tree.reverse() else: dname, fname = os.path.split(path) if self.__wcng: repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return # oops, project is not version controlled while os.path.normcase(dname) != \ os.path.normcase(repodir) and \ (os.path.normcase(dname) not in self.statusCache or self.statusCache[os.path.normcase(dname)] == self.canBeAdded): # add directories recursively, if they aren't in the # repository already tree.insert(-1, dname) dname = os.path.dirname(dname) else: while not os.path.exists(os.path.join(dname, self.adminDir)): # add directories recursively, # if they aren't in the repository already tree.insert(-1, dname) dname = os.path.dirname(dname) if tree: self.vcsAdd(tree, True) if isinstance(path, list): self.addArguments(args, path) else: args.append(path) dia = SvnDialog( self.tr('Adding directory trees to the Subversion repository')) res = dia.startProcess(args, dname) if res: dia.exec_() def vcsRemove(self, name, project=False, noDialog=False): """ Public method used to remove a file/directory from the Subversion repository. The default operation is to remove the local copy as well. @param name file/directory name to be removed (string or list of strings)) @param project flag indicating deletion of a project tree (boolean) (not needed) @param noDialog flag indicating quiet operations @return flag indicating successfull operation (boolean) """ args = [] args.append('delete') self.addArguments(args, self.options['global']) self.addArguments(args, self.options['remove']) if noDialog and '--force' not in args: args.append('--force') if isinstance(name, list): self.addArguments(args, name) else: args.append(name) if noDialog: res = self.startSynchronizedProcess(QProcess(), "svn", args) else: dia = SvnDialog( self.tr('Removing files/directories from the Subversion' ' repository')) res = dia.startProcess(args) if res: dia.exec_() res = dia.normalExit() return res def vcsMove(self, name, project, target=None, noDialog=False): """ Public method used to move a file/directory. @param name file/directory name to be moved (string) @param project reference to the project object @param target new name of the file/directory (string) @param noDialog flag indicating quiet operations @return flag indicating successfull operation (boolean) """ rx_prot = QRegExp('(file:|svn:|svn+ssh:|http:|https:).+') opts = self.options['global'][:] force = '--force' in opts if force: del opts[opts.index('--force')] res = False if noDialog: if target is None: return False force = True accepted = True else: from .SvnCopyDialog import SvnCopyDialog dlg = SvnCopyDialog(name, None, True, force) accepted = (dlg.exec_() == QDialog.Accepted) if accepted: target, force = dlg.getData() if not target: return False if not rx_prot.exactMatch(target): isDir = os.path.isdir(name) else: isDir = False if accepted: args = [] args.append('move') self.addArguments(args, opts) if force: args.append('--force') if rx_prot.exactMatch(target): args.append('--message') args.append('Moving {0} to {1}'.format(name, target)) target = self.__svnURL(target) args.append(name) args.append(target) if noDialog: res = self.startSynchronizedProcess(QProcess(), "svn", args) else: dia = SvnDialog(self.tr('Moving {0}') .format(name)) res = dia.startProcess(args) if res: dia.exec_() res = dia.normalExit() if res and not rx_prot.exactMatch(target): if target.startswith(project.getProjectPath()): if isDir: project.moveDirectory(name, target) else: project.renameFileInPdata(name, target) else: if isDir: project.removeDirectory(name) else: project.removeFile(name) return res def vcsLog(self, name): """ Public method used to view the log of a file/directory from the Subversion repository. @param name file/directory name to show the log of (string) """ isFile = os.path.isfile(name) noEntries, ok = QInputDialog.getInt( None, self.tr("Subversion Log"), self.tr("Select number of entries to show."), self.getPlugin().getPreferences("LogLimit"), 1, 999999, 1) if ok: from .SvnLogDialog import SvnLogDialog self.log = SvnLogDialog(self, isFile=isFile) self.log.show() self.log.start(name, noEntries) def vcsDiff(self, name): """ Public method used to view the difference of a file/directory to the Subversion repository. If name is a directory and is the project directory, all project files are saved first. If name is a file (or list of files), which is/are being edited and has unsaved modification, they can be saved or the operation may be aborted. @param name file/directory name to be diffed (string) """ if isinstance(name, list): names = name[:] else: names = [name] for nam in names: if os.path.isfile(nam): editor = e5App().getObject("ViewManager").getOpenEditor(nam) if editor and not editor.checkDirty(): return else: project = e5App().getObject("Project") if nam == project.ppath and not project.saveAllScripts(): return from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self) self.diff.show() QApplication.processEvents() self.diff.start(name) def vcsStatus(self, name): """ Public method used to view the status of files/directories in the Subversion repository. @param name file/directory name(s) to show the status of (string or list of strings) """ from .SvnStatusDialog import SvnStatusDialog self.status = SvnStatusDialog(self) self.status.show() self.status.start(name) def vcsTag(self, name): """ Public method used to set the tag of a file/directory in the Subversion repository. @param name file/directory name to be tagged (string) """ dname, fname = self.splitPath(name) reposURL = self.svnGetReposName(dname) if reposURL is None: E5MessageBox.critical( self.__ui, self.tr("Subversion Error"), self.tr( """The URL of the project repository could not be""" """ retrieved from the working copy. The tag operation""" """ will be aborted""")) return if self.otherData["standardLayout"]: url = None else: url = self.svnNormalizeURL(reposURL) from .SvnTagDialog import SvnTagDialog dlg = SvnTagDialog(self.allTagsBranchesList, url, self.otherData["standardLayout"]) if dlg.exec_() == QDialog.Accepted: tag, tagOp = dlg.getParameters() if tag in self.allTagsBranchesList: self.allTagsBranchesList.remove(tag) self.allTagsBranchesList.insert(0, tag) else: return if self.otherData["standardLayout"]: rx_base = QRegExp('(.+)/(trunk|tags|branches).*') if not rx_base.exactMatch(reposURL): E5MessageBox.critical( self.__ui, self.tr("Subversion Error"), self.tr( """The URL of the project repository has an""" """ invalid format. The tag operation will""" """ be aborted""")) return reposRoot = rx_base.cap(1) if tagOp in [1, 4]: url = '{0}/tags/{1}'.format(reposRoot, Utilities.quote(tag)) elif tagOp in [2, 8]: url = '{0}/branches/{1}'.format( reposRoot, Utilities.quote(tag)) else: url = self.__svnURL(tag) args = [] if tagOp in [1, 2]: args.append('copy') self.addArguments(args, self.options['global']) self.addArguments(args, self.options['tag']) args.append('--message') args.append('Created tag <{0}>'.format(tag)) args.append(reposURL) args.append(url) else: args.append('delete') self.addArguments(args, self.options['global']) self.addArguments(args, self.options['tag']) args.append('--message') args.append('Deleted tag <{0}>'.format(tag)) args.append(url) dia = SvnDialog(self.tr('Tagging {0} in the Subversion repository') .format(name)) res = dia.startProcess(args) if res: dia.exec_() def vcsRevert(self, name): """ Public method used to revert changes made to a file/directory. @param name file/directory name to be reverted (string) """ args = [] args.append('revert') self.addArguments(args, self.options['global']) if isinstance(name, list): self.addArguments(args, name) names = name[:] else: if os.path.isdir(name): args.append('--recursive') args.append(name) names = [name] project = e5App().getObject("Project") names = [project.getRelativePath(nam) for nam in names] if names[0]: from UI.DeleteFilesConfirmationDialog import \ DeleteFilesConfirmationDialog dlg = DeleteFilesConfirmationDialog( self.parent(), self.tr("Revert changes"), self.tr("Do you really want to revert all changes to" " these files or directories?"), names) yes = dlg.exec_() == QDialog.Accepted else: yes = E5MessageBox.yesNo( None, self.tr("Revert changes"), self.tr("""Do you really want to revert all changes of""" """ the project?""")) if yes: dia = SvnDialog(self.tr('Reverting changes')) res = dia.startProcess(args) if res: dia.exec_() self.checkVCSStatus() def vcsSwitch(self, name): """ Public method used to switch a directory to a different tag/branch. @param name directory name to be switched (string) @return flag indicating added or changed files (boolean) """ dname, fname = self.splitPath(name) reposURL = self.svnGetReposName(dname) if reposURL is None: E5MessageBox.critical( self.__ui, self.tr("Subversion Error"), self.tr( """The URL of the project repository could not be""" """ retrieved from the working copy. The switch""" """ operation will be aborted""")) return False if self.otherData["standardLayout"]: url = None else: url = self.svnNormalizeURL(reposURL) from .SvnSwitchDialog import SvnSwitchDialog dlg = SvnSwitchDialog(self.allTagsBranchesList, url, self.otherData["standardLayout"]) if dlg.exec_() == QDialog.Accepted: tag, tagType = dlg.getParameters() if tag in self.allTagsBranchesList: self.allTagsBranchesList.remove(tag) self.allTagsBranchesList.insert(0, tag) else: return False if self.otherData["standardLayout"]: rx_base = QRegExp('(.+)/(trunk|tags|branches).*') if not rx_base.exactMatch(reposURL): E5MessageBox.critical( self.__ui, self.tr("Subversion Error"), self.tr( """The URL of the project repository has an""" """ invalid format. The switch operation will""" """ be aborted""")) return False reposRoot = rx_base.cap(1) tn = tag if tagType == 1: url = '{0}/tags/{1}'.format(reposRoot, Utilities.quote(tag)) elif tagType == 2: url = '{0}/branches/{1}'.format( reposRoot, Utilities.quote(tag)) elif tagType == 4: url = '{0}/trunk'.format(reposRoot) tn = 'HEAD' else: url = self.__svnURL(tag) tn = url args = [] args.append('switch') if self.version >= (1, 5, 0): args.append('--accept') args.append('postpone') args.append(url) args.append(name) dia = SvnDialog(self.tr('Switching to {0}') .format(tn)) res = dia.startProcess(args, setLanguage=True) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() return res def vcsMerge(self, name): """ Public method used to merge a URL/revision into the local project. @param name file/directory name to be merged (string) """ dname, fname = self.splitPath(name) opts = self.options['global'][:] force = '--force' in opts if force: del opts[opts.index('--force')] from .SvnMergeDialog import SvnMergeDialog dlg = SvnMergeDialog( self.mergeList[0], self.mergeList[1], self.mergeList[2], force) if dlg.exec_() == QDialog.Accepted: urlrev1, urlrev2, target, force = dlg.getParameters() else: return # remember URL or revision if urlrev1 in self.mergeList[0]: self.mergeList[0].remove(urlrev1) self.mergeList[0].insert(0, urlrev1) if urlrev2 in self.mergeList[1]: self.mergeList[1].remove(urlrev2) self.mergeList[1].insert(0, urlrev2) rx_rev = QRegExp('\\d+|HEAD') args = [] args.append('merge') self.addArguments(args, opts) if self.version >= (1, 5, 0): args.append('--accept') args.append('postpone') if force: args.append('--force') if rx_rev.exactMatch(urlrev1): args.append('-r') args.append('{0}:{1}'.format(urlrev1, urlrev2)) if not target: args.append(name) else: args.append(target) # remember target if target in self.mergeList[2]: self.mergeList[2].remove(target) self.mergeList[2].insert(0, target) else: args.append(self.__svnURL(urlrev1)) args.append(self.__svnURL(urlrev2)) args.append(fname) dia = SvnDialog(self.tr('Merging {0}').format(name)) res = dia.startProcess(args, dname) if res: dia.exec_() def vcsRegisteredState(self, name): """ Public method used to get the registered state of a file in the vcs. @param name filename to check (string) @return a combination of canBeCommited and canBeAdded """ if self.__wcng: return self.__vcsRegisteredState_wcng(name) else: return self.__vcsRegisteredState_wc(name) def __vcsRegisteredState_wcng(self, name): """ Private method used to get the registered state of a file in the vcs. This is the variant for subversion installations using the new working copy meta-data format. @param name filename to check (string) @return a combination of canBeCommited and canBeAdded """ if name.endswith(os.sep): name = name[:-1] name = os.path.normcase(name) dname, fname = self.splitPath(name) if fname == '.' and os.path.isdir(os.path.join(dname, self.adminDir)): return self.canBeCommitted if name in self.statusCache: return self.statusCache[name] name = os.path.normcase(name) states = {name: 0} states = self.vcsAllRegisteredStates(states, dname, False) if states[name] == self.canBeCommitted: return self.canBeCommitted else: return self.canBeAdded def __vcsRegisteredState_wc(self, name): """ Private method used to get the registered state of a file in the VCS. This is the variant for subversion installations using the old working copy meta-data format. @param name filename to check (string) @return a combination of canBeCommited and canBeAdded """ dname, fname = self.splitPath(name) if fname == '.': if os.path.isdir(os.path.join(dname, self.adminDir)): return self.canBeCommitted else: return self.canBeAdded name = os.path.normcase(name) states = {name: 0} states = self.vcsAllRegisteredStates(states, dname, False) if states[name] == self.canBeCommitted: return self.canBeCommitted else: return self.canBeAdded def vcsAllRegisteredStates(self, names, dname, shortcut=True): """ Public method used to get the registered states of a number of files in the VCS. Note: If a shortcut is to be taken, the code will only check, if the named directory has been scanned already. If so, it is assumed, that the states for all files have been populated by the previous run. @param names dictionary with all filenames to be checked as keys @param dname directory to check in (string) @param shortcut flag indicating a shortcut should be taken (boolean) @return the received dictionary completed with a combination of canBeCommited and canBeAdded or None in order to signal an error """ if self.__wcng: return self.__vcsAllRegisteredStates_wcng(names, dname, shortcut) else: return self.__vcsAllRegisteredStates_wc(names, dname, shortcut) def __vcsAllRegisteredStates_wcng(self, names, dname, shortcut=True): """ Private method used to get the registered states of a number of files in the VCS. This is the variant for subversion installations using the new working copy meta-data format. Note: If a shortcut is to be taken, the code will only check, if the named directory has been scanned already. If so, it is assumed, that the states for all files has been populated by the previous run. @param names dictionary with all filenames to be checked as keys @param dname directory to check in (string) @param shortcut flag indicating a shortcut should be taken (boolean) @return the received dictionary completed with a combination of canBeCommited and canBeAdded or None in order to signal an error """ if dname.endswith(os.sep): dname = dname[:-1] dname = os.path.normcase(dname) found = False for name in self.statusCache.keys(): if name in names: found = True names[name] = self.statusCache[name] if not found: # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return names ioEncoding = str(Preferences.getSystem("IOEncoding")) process = QProcess() args = [] args.append('status') args.append('--verbose') args.append('--non-interactive') args.append(dname) process.start('svn', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), ioEncoding, 'replace') for line in output.splitlines(): if self.rx_status1.exactMatch(line): flags = str(self.rx_status1.cap(1)) path = self.rx_status1.cap(5).strip() elif self.rx_status2.exactMatch(line): flags = str(self.rx_status2.cap(1)) path = self.rx_status2.cap(2).strip() else: continue name = os.path.normcase(path) if flags[0] not in "?I": if name in names: names[name] = self.canBeCommitted self.statusCache[name] = self.canBeCommitted else: self.statusCache[name] = self.canBeAdded return names def __vcsAllRegisteredStates_wc(self, names, dname, shortcut=True): """ Private method used to get the registered states of a number of files in the VCS. This is the variant for subversion installations using the old working copy meta-data format. Note: If a shortcut is to be taken, the code will only check, if the named directory has been scanned already. If so, it is assumed, that the states for all files has been populated by the previous run. @param names dictionary with all filenames to be checked as keys @param dname directory to check in (string) @param shortcut flag indicating a shortcut should be taken (boolean) @return the received dictionary completed with a combination of canBeCommited and canBeAdded or None in order to signal an error """ if not os.path.isdir(os.path.join(dname, self.adminDir)): # not under version control -> do nothing return names found = False for name in list(self.statusCache.keys()): if os.path.dirname(name) == dname: if shortcut: found = True break if name in names: found = True names[name] = self.statusCache[name] if not found: ioEncoding = Preferences.getSystem("IOEncoding") process = QProcess() args = [] args.append('status') args.append('--verbose') args.append('--non-interactive') args.append(dname) process.start('svn', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), ioEncoding, 'replace') for line in output.splitlines(): if self.rx_status1.exactMatch(line): flags = self.rx_status1.cap(1) path = self.rx_status1.cap(5).strip() elif self.rx_status2.exactMatch(line): flags = self.rx_status2.cap(1) path = self.rx_status2.cap(2).strip() else: continue name = os.path.normcase(path) if flags[0] not in "?I": if name in names: names[name] = self.canBeCommitted self.statusCache[name] = self.canBeCommitted else: self.statusCache[name] = self.canBeAdded return names def clearStatusCache(self): """ Public method to clear the status cache. """ self.statusCache = {} def vcsInitConfig(self, project): """ Public method to initialize the VCS configuration. This method ensures, that an ignore file exists. @param project reference to the project (Project) """ configPath = getConfigPath() if os.path.exists(configPath): amendConfig() else: createDefaultConfig() def vcsName(self): """ Public method returning the name of the vcs. @return always 'Subversion' (string) """ return "Subversion" def vcsCleanup(self, name): """ Public method used to cleanup the working copy. @param name directory name to be cleaned up (string) """ args = [] args.append('cleanup') self.addArguments(args, self.options['global']) args.append(name) dia = SvnDialog(self.tr('Cleaning up {0}') .format(name)) res = dia.startProcess(args) if res: dia.exec_() def vcsCommandLine(self, name): """ Public method used to execute arbitrary subversion commands. @param name directory name of the working directory (string) """ from .SvnCommandDialog import SvnCommandDialog dlg = SvnCommandDialog(self.commandHistory, self.wdHistory, name) if dlg.exec_() == QDialog.Accepted: command, wd = dlg.getData() commandList = Utilities.parseOptionString(command) # This moves any previous occurrence of these arguments to the head # of the list. if command in self.commandHistory: self.commandHistory.remove(command) self.commandHistory.insert(0, command) if wd in self.wdHistory: self.wdHistory.remove(wd) self.wdHistory.insert(0, wd) args = [] self.addArguments(args, commandList) dia = SvnDialog(self.tr('Subversion command')) res = dia.startProcess(args, wd) if res: dia.exec_() def vcsOptionsDialog(self, project, archive, editable=False, parent=None): """ Public method to get a dialog to enter repository info. @param project reference to the project object @param archive name of the project in the repository (string) @param editable flag indicating that the project name is editable (boolean) @param parent parent widget (QWidget) @return reference to the instantiated options dialog (SvnOptionsDialog) """ from .SvnOptionsDialog import SvnOptionsDialog return SvnOptionsDialog(self, project, parent) def vcsNewProjectOptionsDialog(self, parent=None): """ Public method to get a dialog to enter repository info for getting a new project. @param parent parent widget (QWidget) @return reference to the instantiated options dialog (SvnNewProjectOptionsDialog) """ from .SvnNewProjectOptionsDialog import SvnNewProjectOptionsDialog return SvnNewProjectOptionsDialog(self, parent) def vcsRepositoryInfos(self, ppath): """ Public method to retrieve information about the repository. @param ppath local path to get the repository infos (string) @return string with ready formated info for display (string) """ info = { 'committed-rev': '', 'committed-date': '', 'committed-time': '', 'url': '', 'last-author': '', 'revision': '' } ioEncoding = Preferences.getSystem("IOEncoding") process = QProcess() args = [] args.append('info') args.append('--non-interactive') args.append('--xml') args.append(ppath) process.start('svn', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), ioEncoding, 'replace') entryFound = False commitFound = False for line in output.splitlines(): line = line.strip() if line.startswith(''): commitFound = False elif line.startswith("revision="): rev = line[line.find('"') + 1:line.rfind('"')] if entryFound: info['revision'] = rev entryFound = False elif commitFound: info['committed-rev'] = rev elif line.startswith(''): info['url'] = \ line.replace('', '').replace('', '') elif line.startswith(''): info['last-author'] = line.replace('', '')\ .replace('', '') elif line.startswith(''): value = line.replace('', '')\ .replace('', '') date, time = value.split('T') info['committed-date'] = date info['committed-time'] = "{0}{1}".format( time.split('.')[0], time[-1]) return QCoreApplication.translate( 'subversion', """

Repository information

""" """""" """""" """""" """""" """""" """""" """""" """""" """
Subversion V.{0}
URL{1}
Current revision{2}
Committed revision{3}
Committed date{4}
Comitted time{5}
Last author{6}
""" ).format(self.versionStr, info['url'], info['revision'], info['committed-rev'], info['committed-date'], info['committed-time'], info['last-author']) ########################################################################### ## Public Subversion specific methods are below. ########################################################################### def svnGetReposName(self, path): """ Public method used to retrieve the URL of the subversion repository path. @param path local path to get the svn repository path for (string) @return string with the repository path URL """ ioEncoding = Preferences.getSystem("IOEncoding") process = QProcess() args = [] args.append('info') args.append('--xml') args.append('--non-interactive') args.append(path) process.start('svn', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), ioEncoding, 'replace') for line in output.splitlines(): line = line.strip() if line.startswith(''): reposURL = line.replace('', '')\ .replace('', '') return reposURL return "" def svnResolve(self, name): """ Public method used to resolve conflicts of a file/directory. @param name file/directory name to be resolved (string) """ args = [] if self.version >= (1, 5, 0): args.append('resolve') args.append('--accept') args.append('working') else: args.append('resolved') self.addArguments(args, self.options['global']) if isinstance(name, list): self.addArguments(args, name) else: if os.path.isdir(name): args.append('--recursive') args.append(name) dia = SvnDialog(self.tr('Resolving conficts')) res = dia.startProcess(args) if res: dia.exec_() self.checkVCSStatus() def svnCopy(self, name, project): """ Public method used to copy a file/directory. @param name file/directory name to be copied (string) @param project reference to the project object @return flag indicating successfull operation (boolean) """ from .SvnCopyDialog import SvnCopyDialog rx_prot = QRegExp('(file:|svn:|svn+ssh:|http:|https:).+') dlg = SvnCopyDialog(name) res = False if dlg.exec_() == QDialog.Accepted: target, force = dlg.getData() args = [] args.append('copy') self.addArguments(args, self.options['global']) if rx_prot.exactMatch(target): args.append('--message') args.append('Copying {0} to {1}'.format(name, target)) target = self.__svnURL(target) args.append(name) args.append(target) dia = SvnDialog(self.tr('Copying {0}') .format(name)) res = dia.startProcess(args) if res: dia.exec_() res = dia.normalExit() if res and \ not rx_prot.exactMatch(target) and \ target.startswith(project.getProjectPath()): if os.path.isdir(name): project.copyDirectory(name, target) else: project.appendFile(target) return res def svnListProps(self, name, recursive=False): """ Public method used to list the properties of a file/directory. @param name file/directory name (string or list of strings) @param recursive flag indicating a recursive list is requested """ from .SvnPropListDialog import SvnPropListDialog self.propList = SvnPropListDialog(self) self.propList.show() self.propList.start(name, recursive) def svnSetProp(self, name, recursive=False): """ Public method used to add a property to a file/directory. @param name file/directory name (string or list of strings) @param recursive flag indicating a recursive list is requested """ from .SvnPropSetDialog import SvnPropSetDialog dlg = SvnPropSetDialog() if dlg.exec_() == QDialog.Accepted: propName, fileFlag, propValue = dlg.getData() if not propName: E5MessageBox.critical( self.__ui, self.tr("Subversion Set Property"), self.tr("""You have to supply a property name.""" """ Aborting.""")) return args = [] args.append('propset') self.addArguments(args, self.options['global']) if recursive: args.append('--recursive') args.append(propName) if fileFlag: args.append('--file') args.append(propValue) if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, fnames) else: dname, fname = self.splitPath(name) args.append(fname) dia = SvnDialog(self.tr('Subversion Set Property')) res = dia.startProcess(args, dname) if res: dia.exec_() def svnDelProp(self, name, recursive=False): """ Public method used to delete a property of a file/directory. @param name file/directory name (string or list of strings) @param recursive flag indicating a recursive list is requested """ propName, ok = QInputDialog.getText( None, self.tr("Subversion Delete Property"), self.tr("Enter property name"), QLineEdit.Normal) if not ok: return if not propName: E5MessageBox.critical( self.__ui, self.tr("Subversion Delete Property"), self.tr("""You have to supply a property name.""" """ Aborting.""")) return args = [] args.append('propdel') self.addArguments(args, self.options['global']) if recursive: args.append('--recursive') args.append(propName) if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, fnames) else: dname, fname = self.splitPath(name) args.append(fname) dia = SvnDialog(self.tr('Subversion Delete Property')) res = dia.startProcess(args, dname) if res: dia.exec_() def svnListTagBranch(self, path, tags=True): """ Public method used to list the available tags or branches. @param path directory name of the project (string) @param tags flag indicating listing of branches or tags (False = branches, True = tags) """ from .SvnTagBranchListDialog import SvnTagBranchListDialog self.tagbranchList = SvnTagBranchListDialog(self) self.tagbranchList.show() if tags: if not self.showedTags: self.showedTags = True allTagsBranchesList = self.allTagsBranchesList else: self.tagsList = [] allTagsBranchesList = None self.tagbranchList.start(path, tags, self.tagsList, allTagsBranchesList) elif not tags: if not self.showedBranches: self.showedBranches = True allTagsBranchesList = self.allTagsBranchesList else: self.branchesList = [] allTagsBranchesList = None self.tagbranchList.start( path, tags, self.branchesList, self.allTagsBranchesList) def svnBlame(self, name): """ Public method to show the output of the svn blame command. @param name file name to show the blame for (string) """ from .SvnBlameDialog import SvnBlameDialog self.blame = SvnBlameDialog(self) self.blame.show() self.blame.start(name) def svnExtendedDiff(self, name): """ Public method used to view the difference of a file/directory to the Subversion repository. If name is a directory and is the project directory, all project files are saved first. If name is a file (or list of files), which is/are being edited and has unsaved modification, they can be saved or the operation may be aborted. This method gives the chance to enter the revisions to be compared. @param name file/directory name to be diffed (string) """ if isinstance(name, list): names = name[:] else: names = [name] for nam in names: if os.path.isfile(nam): editor = e5App().getObject("ViewManager").getOpenEditor(nam) if editor and not editor.checkDirty(): return else: project = e5App().getObject("Project") if nam == project.ppath and not project.saveAllScripts(): return from .SvnRevisionSelectionDialog import SvnRevisionSelectionDialog dlg = SvnRevisionSelectionDialog() if dlg.exec_() == QDialog.Accepted: revisions = dlg.getRevisions() from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self) self.diff.show() self.diff.start(name, revisions) def svnUrlDiff(self, name): """ Public method used to view the difference of a file/directory of two repository URLs. If name is a directory and is the project directory, all project files are saved first. If name is a file (or list of files), which is/are being edited and has unsaved modification, they can be saved or the operation may be aborted. This method gives the chance to enter the revisions to be compared. @param name file/directory name to be diffed (string) """ if isinstance(name, list): names = name[:] else: names = [name] for nam in names: if os.path.isfile(nam): editor = e5App().getObject("ViewManager").getOpenEditor(nam) if editor and not editor.checkDirty(): return else: project = e5App().getObject("Project") if nam == project.ppath and not project.saveAllScripts(): return dname = self.splitPath(names[0])[0] from .SvnUrlSelectionDialog import SvnUrlSelectionDialog dlg = SvnUrlSelectionDialog(self, self.tagsList, self.branchesList, dname) if dlg.exec_() == QDialog.Accepted: urls, summary = dlg.getURLs() from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self) self.diff.show() QApplication.processEvents() self.diff.start(name, urls=urls, summary=summary) def __svnGetFileForRevision(self, name, rev=""): """ Private method to get a file for a specific revision from the repository. @param name file name to get from the repository (string) @keyparam rev revision to retrieve (integer or string) @return contents of the file (string) and an error message (string) """ args = [] args.append("cat") if rev: args.append("--revision") args.append(str(rev)) args.append(name) output = "" error = "" process = QProcess() process.start('svn', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished: if process.exitCode() == 0: output = str( process.readAllStandardOutput(), Preferences.getSystem("IOEncoding"), 'replace') else: error = str( process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') else: error = self.tr( "The svn process did not finish within 30s.") else: error = self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.').format('svn') return output, error def svnSbsDiff(self, name, extended=False, revisions=None): """ Public method used to view the difference of a file to the Mercurial repository side-by-side. @param name file name to be diffed (string) @keyparam extended flag indicating the extended variant (boolean) @keyparam revisions tuple of two revisions (tuple of strings) @exception ValueError raised to indicate an illegal name parameter type """ if isinstance(name, list): raise ValueError("Wrong parameter type") if extended: from .SvnRevisionSelectionDialog import SvnRevisionSelectionDialog dlg = SvnRevisionSelectionDialog() if dlg.exec_() == QDialog.Accepted: rev1, rev2 = dlg.getRevisions() if rev1 == "WORKING": rev1 = "" if rev2 == "WORKING": rev2 = "" elif revisions: rev1, rev2 = revisions[0], revisions[1] else: rev1, rev2 = "", "" output1, error = self.__svnGetFileForRevision(name, rev=rev1) if error: E5MessageBox.critical( self.__ui, self.tr("Subversion Side-by-Side Difference"), error) return name1 = "{0} (rev. {1})".format(name, rev1 and rev1 or ".") if rev2: output2, error = self.__svnGetFileForRevision(name, rev=rev2) if error: E5MessageBox.critical( self.__ui, self.tr("Subversion Side-by-Side Difference"), error) return name2 = "{0} (rev. {1})".format(name, rev2) else: try: f1 = open(name, "r", encoding="utf-8") output2 = f1.read() f1.close() name2 = name except IOError: E5MessageBox.critical( self.__ui, self.tr("Subversion Side-by-Side Difference"), self.tr( """

The file {0} could not be read.

""") .format(name)) return if self.sbsDiff is None: from UI.CompareDialog import CompareDialog self.sbsDiff = CompareDialog() self.sbsDiff.show() self.sbsDiff.compare(output1, output2, name1, name2) def vcsLogBrowser(self, name, isFile=False): """ Public method used to browse the log of a file/directory from the Subversion repository. @param name file/directory name to show the log of (string) @param isFile flag indicating log for a file is to be shown (boolean) """ if self.logBrowser is None: from .SvnLogBrowserDialog import SvnLogBrowserDialog self.logBrowser = SvnLogBrowserDialog(self) self.logBrowser.show() self.logBrowser.start(name, isFile=isFile) def svnLock(self, name, stealIt=False, parent=None): """ Public method used to lock a file in the Subversion repository. @param name file/directory name to be locked (string or list of strings) @param stealIt flag indicating a forced operation (boolean) @param parent reference to the parent object of the subversion dialog (QWidget) """ args = [] args.append('lock') self.addArguments(args, self.options['global']) if stealIt: args.append('--force') if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, fnames) else: dname, fname = self.splitPath(name) args.append(fname) dia = SvnDialog( self.tr('Locking in the Subversion repository'), parent) res = dia.startProcess(args, dname) if res: dia.exec_() def svnUnlock(self, name, breakIt=False, parent=None): """ Public method used to unlock a file in the Subversion repository. @param name file/directory name to be unlocked (string or list of strings) @param breakIt flag indicating a forced operation (boolean) @param parent reference to the parent object of the subversion dialog (QWidget) """ args = [] args.append('unlock') self.addArguments(args, self.options['global']) if breakIt: args.append('--force') if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, fnames) else: dname, fname = self.splitPath(name) args.append(fname) dia = SvnDialog( self.tr('Unlocking in the Subversion repository'), parent) res = dia.startProcess(args, dname) if res: dia.exec_() def svnRelocate(self, projectPath): """ Public method to relocate the working copy to a new repository URL. @param projectPath path name of the project (string) """ from .SvnRelocateDialog import SvnRelocateDialog currUrl = self.svnGetReposName(projectPath) dlg = SvnRelocateDialog(currUrl) if dlg.exec_() == QDialog.Accepted: newUrl, inside = dlg.getData() args = [] args.append('switch') if not inside: args.append('--relocate') args.append(currUrl) args.append(newUrl) args.append(projectPath) dia = SvnDialog(self.tr('Relocating')) res = dia.startProcess(args) if res: dia.exec_() def svnRepoBrowser(self, projectPath=None): """ Public method to open the repository browser. @param projectPath path name of the project (string) """ if projectPath: url = self.svnGetReposName(projectPath) else: url = None if url is None: url, ok = QInputDialog.getText( None, self.tr("Repository Browser"), self.tr("Enter the repository URL."), QLineEdit.Normal) if not ok or not url: return from .SvnRepoBrowserDialog import SvnRepoBrowserDialog self.repoBrowser = SvnRepoBrowserDialog(self) self.repoBrowser.show() self.repoBrowser.start(url) def svnRemoveFromChangelist(self, names): """ Public method to remove a file or directory from its changelist. Note: Directories will be removed recursively. @param names name or list of names of file or directory to remove (string) """ args = [] args.append('changelist') self.addArguments(args, self.options['global']) args.append('--remove') args.append('--recursive') if isinstance(names, list): dname, fnames = self.splitPathList(names) self.addArguments(args, fnames) else: dname, fname = self.splitPath(names) args.append(fname) dia = SvnDialog(self.tr('Remove from changelist')) res = dia.startProcess(args, dname) if res: dia.exec_() def svnAddToChangelist(self, names): """ Public method to add a file or directory to a changelist. Note: Directories will be added recursively. @param names name or list of names of file or directory to add (string) """ clname, ok = QInputDialog.getItem( None, self.tr("Add to changelist"), self.tr("Enter name of the changelist:"), sorted(self.svnGetChangelists()), 0, True) if not ok or not clname: return args = [] args.append('changelist') self.addArguments(args, self.options['global']) args.append('--recursive') args.append(clname) if isinstance(names, list): dname, fnames = self.splitPathList(names) self.addArguments(args, fnames) else: dname, fname = self.splitPath(names) args.append(fname) dia = SvnDialog(self.tr('Remove from changelist')) res = dia.startProcess(args, dname) if res: dia.exec_() def svnShowChangelists(self, path): """ Public method used to inspect the change lists defined for the project. @param path directory name to show change lists for (string) """ from .SvnChangeListsDialog import SvnChangeListsDialog self.changeLists = SvnChangeListsDialog(self) self.changeLists.show() QApplication.processEvents() self.changeLists.start(path) def svnGetChangelists(self): """ Public method to get a list of all defined change lists. @return list of defined change list names (list of strings) """ changelists = [] rx_changelist = QRegExp('--- \\S+ .([\\w\\s]+).:\\s*') # three dashes, Changelist (translated), quote, # changelist name, quote, : args = [] args.append("status") args.append("--non-interactive") args.append(".") ppath = e5App().getObject("Project").getProjectPath() process = QProcess() process.setWorkingDirectory(ppath) process.start('svn', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = \ str(process.readAllStandardOutput(), Preferences.getSystem("IOEncoding"), 'replace') if output: for line in output.splitlines(): if rx_changelist.exactMatch(line): changelist = rx_changelist.cap(1) if changelist not in changelists: changelists.append(changelist) return changelists def svnUpgrade(self, path): """ Public method to upgrade the working copy format. @param path directory name to show change lists for (string) """ args = [] args.append("upgrade") args.append(".") dia = SvnDialog(self.tr('Upgrade')) res = dia.startProcess(args, path) if res: dia.exec_() ########################################################################### ## Private Subversion specific methods are below. ########################################################################### def __svnURL(self, url): """ Private method to format a url for subversion. @param url unformatted url string (string) @return properly formated url for subversion (string) """ url = self.svnNormalizeURL(url) url = url.split(':', 2) if len(url) == 3: scheme = url[0] host = url[1] port, path = url[2].split("/", 1) return "{0}:{1}:{2}/{3}".format( scheme, host, port, Utilities.quote(path)) else: scheme = url[0] if scheme == "file": return "{0}:{1}".format(scheme, Utilities.quote(url[1])) else: try: host, path = url[1][2:].split("/", 1) except ValueError: host = url[1][2:] path = "" return "{0}://{1}/{2}".format( scheme, host, Utilities.quote(path)) def svnNormalizeURL(self, url): """ Public method to normalize a url for subversion. @param url url string (string) @return properly normalized url for subversion (string) """ protocol, url = url.split("://", 1) if url.startswith("\\\\"): url = url[2:] if protocol == "file": url = os.path.normcase(url) url = url.replace('\\', '/') if url.endswith('/'): url = url[:-1] if not url.startswith("/") and url[1] in [":", "|"]: url = "/{0}".format(url) return "{0}://{1}".format(protocol, url) ########################################################################### ## Methods to get the helper objects are below. ########################################################################### def vcsGetProjectBrowserHelper(self, browser, project, isTranslationsBrowser=False): """ Public method to instanciate a helper object for the different project browsers. @param browser reference to the project browser object @param project reference to the project object @param isTranslationsBrowser flag indicating, the helper is requested for the translations browser (this needs some special treatment) @return the project browser helper object """ from .ProjectBrowserHelper import SvnProjectBrowserHelper return SvnProjectBrowserHelper(self, browser, project, isTranslationsBrowser) def vcsGetProjectHelper(self, project): """ Public method to instanciate a helper object for the project. @param project reference to the project object @return the project helper object """ helper = self.__plugin.getProjectHelper() helper.setObjects(self, project) self.__wcng = \ os.path.exists( os.path.join(project.getProjectPath(), ".svn", "format")) or \ os.path.exists( os.path.join(project.getProjectPath(), "_svn", "format")) or \ os.path.exists( os.path.join(project.getProjectPath(), ".svn", "wc.db")) or \ os.path.exists( os.path.join(project.getProjectPath(), "_svn", "wc.db")) return helper ########################################################################### ## Status Monitor Thread methods ########################################################################### def _createStatusMonitorThread(self, interval, project): """ Protected method to create an instance of the VCS status monitor thread. @param interval check interval for the monitor thread in seconds (integer) @param project reference to the project object @return reference to the monitor thread (QThread) """ from .SvnStatusMonitorThread import SvnStatusMonitorThread return SvnStatusMonitorThread(interval, project, self) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnOptionsDialog.ui0000644000175000017500000001246112263304147024645 0ustar piotrpiotr SvnOptionsDialog 0 0 565 169 Repository Infos <b>Repository Infos Dialog</b> <p>Enter the various infos into the entry fields. These values are used to generate a new project in the repository. If the checkbox is selected, the URL must end in the project name. A directory tree with project/tags, project/branches and project/trunk will be generated in the repository. If the checkbox is not selected, the URL must contain the complete path in the repository.</p> <p>For remote repositories the URL must contain the hostname.</p> true Log &Message: vcsLogEdit Select, if the standard repository layout (projectdir/trunk, projectdir/tags, projectdir/branches) should be generated Create standard repository &layout Alt+L true Select the protocol to access the repository &URL: vcsUrlEdit Enter the log message for the new project. <b>Log Message</b> <p>Enter the log message to be used for the new project.</p> new project started &Protocol: protocolCombo Enter the url path of the module in the repository (without protocol part) <b>URL</b><p>Enter the URL to the module. For a repository with standard layout, this must not contain the trunk, tags or branches part.</p> Select the repository url via a directory selection dialog or the repository browser Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource protocolCombo vcsUrlEdit vcsUrlButton vcsLogEdit layoutCheckBox buttonBox accepted() SvnOptionsDialog accept() 47 142 51 164 buttonBox rejected() SvnOptionsDialog reject() 204 146 205 165 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnCopyDialog.py0000644000175000017500000000670012451233371024135 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a copy operation. """ from __future__ import unicode_literals import os.path from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter, E5DirCompleter from E5Gui import E5FileDialog from .Ui_SvnCopyDialog import Ui_SvnCopyDialog import Utilities import UI.PixmapCache class SvnCopyDialog(QDialog, Ui_SvnCopyDialog): """ Class implementing a dialog to enter the data for a copy or rename operation. """ def __init__(self, source, parent=None, move=False, force=False): """ Constructor @param source name of the source file/directory (string) @param parent parent widget (QWidget) @param move flag indicating a move operation (boolean) @param force flag indicating a forced operation (boolean) """ super(SvnCopyDialog, self).__init__(parent) self.setupUi(self) self.dirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.source = source if os.path.isdir(self.source): self.targetCompleter = E5DirCompleter(self.targetEdit) else: self.targetCompleter = E5FileCompleter(self.targetEdit) if move: self.setWindowTitle(self.tr('Subversion Move')) else: self.forceCheckBox.setEnabled(False) self.forceCheckBox.setChecked(force) self.sourceEdit.setText(source) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public method to retrieve the copy data. @return the target name (string) and a flag indicating the operation should be enforced (boolean) """ target = self.targetEdit.text() if not os.path.isabs(target): sourceDir = os.path.dirname(self.sourceEdit.text()) target = os.path.join(sourceDir, target) return (Utilities.toNativeSeparators(target), self.forceCheckBox.isChecked()) @pyqtSlot() def on_dirButton_clicked(self): """ Private slot to handle the button press for selecting the target via a selection dialog. """ if os.path.isdir(self.source): target = E5FileDialog.getExistingDirectory( None, self.tr("Select target"), self.targetEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) else: target = E5FileDialog.getSaveFileName( None, self.tr("Select target"), self.targetEdit.text(), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if target: self.targetEdit.setText(Utilities.toNativeSeparators(target)) @pyqtSlot(str) def on_targetEdit_textChanged(self, txt): """ Private slot to handle changes of the target. @param txt contents of the target edit (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( os.path.isabs(txt) or os.path.dirname(txt) == "") eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnStatusMonitorThread.py0000644000175000017500000001203312451233371026062 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the VCS status monitor thread class for Subversion. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import QRegExp, QProcess from VCS.StatusMonitorThread import VcsStatusMonitorThread import Preferences class SvnStatusMonitorThread(VcsStatusMonitorThread): """ Class implementing the VCS status monitor thread class for Subversion. """ def __init__(self, interval, project, vcs, parent=None): """ Constructor @param interval new interval in seconds (integer) @param project reference to the project object (Project) @param vcs reference to the version control object @param parent reference to the parent object (QObject) """ VcsStatusMonitorThread.__init__(self, interval, project, vcs, parent) self.__ioEncoding = Preferences.getSystem("IOEncoding") self.rx_status1 = \ QRegExp('(.{8,9})\\s+([0-9-]+)\\s+(.+)\\s*') self.rx_status2 = QRegExp( '(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*') def _performMonitor(self): """ Protected method implementing the monitoring action. This method populates the statusList member variable with a list of strings giving the status in the first column and the path relative to the project directory starting with the third column. The allowed status flags are:
  • "A" path was added but not yet comitted
  • "M" path has local changes
  • "O" path was removed
  • "R" path was deleted and then re-added
  • "U" path needs an update
  • "Z" path contains a conflict
  • " " path is back at normal
@return tuple of flag indicating successful operation (boolean) and a status message in case of non successful operation (string) """ self.shouldUpdate = False process = QProcess() args = [] args.append('status') if not Preferences.getVCS("MonitorLocalStatus"): args.append('--show-updates') args.append('--non-interactive') args.append('.') process.setWorkingDirectory(self.projectDir) process.start('svn', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(300000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.__ioEncoding, 'replace') states = {} for line in output.splitlines(): if self.rx_status1.exactMatch(line): flags = self.rx_status1.cap(1) path = self.rx_status1.cap(3).strip() elif self.rx_status2.exactMatch(line): flags = self.rx_status2.cap(1) path = self.rx_status2.cap(5).strip() else: continue if flags[0] in "ACDMR" or \ (flags[0] == " " and flags[-1] == "*"): if flags[-1] == "*": status = "U" else: status = flags[0] if status == "C": status = "Z" # give it highest priority elif status == "D": status = "O" if status == "U": self.shouldUpdate = True name = path states[name] = status try: if self.reportedStates[name] != status: self.statusList.append( "{0} {1}".format(status, name)) except KeyError: self.statusList.append( "{0} {1}".format(status, name)) for name in list(self.reportedStates.keys()): if name not in states: self.statusList.append(" {0}".format(name)) self.reportedStates = states return True, self.tr( "Subversion status checked successfully (using svn)") else: process.kill() process.waitForFinished() return False, \ str(process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') else: process.kill() process.waitForFinished() return False, self.tr( "Could not start the Subversion process.") eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnLogBrowserDialog.py0000644000175000017500000006022512523374571025322 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog to browse the log history. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QTimer, QDate, QProcess, QRegExp, Qt, pyqtSlot, \ QPoint from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QHeaderView, QLineEdit, QWidget, QApplication, \ QDialogButtonBox, QTreeWidgetItem from E5Gui import E5MessageBox from .Ui_SvnLogBrowserDialog import Ui_SvnLogBrowserDialog import Preferences class SvnLogBrowserDialog(QWidget, Ui_SvnLogBrowserDialog): """ Class implementing a dialog to browse the log history. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnLogBrowserDialog, self).__init__(parent) self.setupUi(self) self.__position = QPoint() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.filesTree.headerItem().setText(self.filesTree.columnCount(), "") self.filesTree.header().setSortIndicator(0, Qt.AscendingOrder) self.vcs = vcs self.__initData() self.fromDate.setDisplayFormat("yyyy-MM-dd") self.toDate.setDisplayFormat("yyyy-MM-dd") self.__resetUI() self.__messageRole = Qt.UserRole self.__changesRole = Qt.UserRole + 1 self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.rx_sep1 = QRegExp('\\-+\\s*') self.rx_sep2 = QRegExp('=+\\s*') self.rx_rev1 = QRegExp( 'rev ([0-9]+): ([^|]*) \| ([^|]*) \| ([0-9]+) .*') # "rev" followed by one or more decimals followed by a colon followed # anything up to " | " (twice) followed by one or more decimals # followed by anything self.rx_rev2 = QRegExp( 'r([0-9]+) \| ([^|]*) \| ([^|]*) \| ([0-9]+) .*') # "r" followed by one or more decimals followed by " | " followed # anything up to " | " (twice) followed by one or more decimals # followed by anything self.rx_flags1 = QRegExp( r""" ([ADM])\s(.*)\s+\(\w+\s+(.*):([0-9]+)\)\s*""") # three blanks followed by A or D or M followed by path followed by # path copied from followed by copied from revision self.rx_flags2 = QRegExp(' ([ADM]) (.*)\\s*') # three blanks followed by A or D or M followed by path self.flags = { 'A': self.tr('Added'), 'D': self.tr('Deleted'), 'M': self.tr('Modified'), 'R': self.tr('Replaced'), } self.intercept = False def __initData(self): """ Private method to (re-)initialize some data. """ self.__maxDate = QDate() self.__minDate = QDate() self.__filterLogsEnabled = True self.buf = [] # buffer for stdout self.diff = None self.__started = False self.__lastRev = 0 def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.__position = self.pos() e.accept() def show(self): """ Public slot to show the dialog. """ if not self.__position.isNull(): self.move(self.__position) self.__resetUI() super(SvnLogBrowserDialog, self).show() def __resetUI(self): """ Private method to reset the user interface. """ self.fromDate.setDate(QDate.currentDate()) self.toDate.setDate(QDate.currentDate()) self.fieldCombo.setCurrentIndex(self.fieldCombo.findText( self.tr("Message"))) self.limitSpinBox.setValue(self.vcs.getPlugin().getPreferences( "LogLimit")) self.stopCheckBox.setChecked(self.vcs.getPlugin().getPreferences( "StopLogOnCopy")) self.logTree.clear() self.nextButton.setEnabled(True) self.limitSpinBox.setEnabled(True) def __resizeColumnsLog(self): """ Private method to resize the log tree columns. """ self.logTree.header().resizeSections(QHeaderView.ResizeToContents) self.logTree.header().setStretchLastSection(True) def __resortLog(self): """ Private method to resort the log tree. """ self.logTree.sortItems( self.logTree.sortColumn(), self.logTree.header().sortIndicatorOrder()) def __resizeColumnsFiles(self): """ Private method to resize the changed files tree columns. """ self.filesTree.header().resizeSections(QHeaderView.ResizeToContents) self.filesTree.header().setStretchLastSection(True) def __resortFiles(self): """ Private method to resort the changed files tree. """ sortColumn = self.filesTree.sortColumn() self.filesTree.sortItems( 1, self.filesTree.header().sortIndicatorOrder()) self.filesTree.sortItems( sortColumn, self.filesTree.header().sortIndicatorOrder()) def __generateLogItem(self, author, date, message, revision, changedPaths): """ Private method to generate a log tree entry. @param author author info (string) @param date date info (string) @param message text of the log message (list of strings) @param revision revision info (string) @param changedPaths list of dictionary objects containing info about the changed files/directories @return reference to the generated item (QTreeWidgetItem) """ msg = [] for line in message: msg.append(line.strip()) itm = QTreeWidgetItem(self.logTree) itm.setData(0, Qt.DisplayRole, int(revision)) itm.setData(1, Qt.DisplayRole, author) itm.setData(2, Qt.DisplayRole, date) itm.setData(3, Qt.DisplayRole, " ".join(msg)) itm.setData(0, self.__messageRole, message) itm.setData(0, self.__changesRole, changedPaths) itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(1, Qt.AlignLeft) itm.setTextAlignment(2, Qt.AlignLeft) itm.setTextAlignment(3, Qt.AlignLeft) itm.setTextAlignment(4, Qt.AlignLeft) try: self.__lastRev = int(revision) except ValueError: self.__lastRev = 0 return itm def __generateFileItem(self, action, path, copyFrom, copyRev): """ Private method to generate a changed files tree entry. @param action indicator for the change action ("A", "D" or "M") @param path path of the file in the repository (string) @param copyFrom path the file was copied from (None, string) @param copyRev revision the file was copied from (None, string) @return reference to the generated item (QTreeWidgetItem) """ itm = QTreeWidgetItem(self.filesTree, [ self.flags[action], path, copyFrom, copyRev, ]) itm.setTextAlignment(3, Qt.AlignRight) return itm def __getLogEntries(self, startRev=None): """ Private method to retrieve log entries from the repository. @param startRev revision number to start from (integer, string) """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.intercept = False self.process.kill() self.buf = [] self.cancelled = False self.errors.clear() args = [] args.append('log') self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['log']) args.append('--verbose') args.append('--limit') args.append('{0:d}'.format(self.limitSpinBox.value())) if startRev is not None: args.append('--revision') args.append('{0}:0'.format(startRev)) if self.stopCheckBox.isChecked(): args.append('--stop-on-copy') args.append(self.fname) self.process.setWorkingDirectory(self.dname) self.inputGroup.setEnabled(True) self.inputGroup.show() self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) def start(self, fn, isFile=False): """ Public slot to start the svn log command. @param fn filename to show the log for (string) @keyparam isFile flag indicating log for a file is to be shown (boolean) """ self.sbsCheckBox.setEnabled(isFile) self.sbsCheckBox.setVisible(isFile) self.errorGroup.hide() QApplication.processEvents() self.__initData() self.filename = fn self.dname, self.fname = self.vcs.splitPath(fn) self.activateWindow() self.raise_() self.logTree.clear() self.__started = True self.__getLogEntries() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__processBuffer() self.__finish() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.inputGroup.setEnabled(False) self.inputGroup.hide() def __processBuffer(self): """ Private method to process the buffered output of the svn log command. """ noEntries = 0 log = {"message": []} changedPaths = [] for s in self.buf: if self.rx_rev1.exactMatch(s): log["revision"] = self.rx_rev.cap(1) log["author"] = self.rx_rev.cap(2) log["date"] = self.rx_rev.cap(3) # number of lines is ignored elif self.rx_rev2.exactMatch(s): log["revision"] = self.rx_rev2.cap(1) log["author"] = self.rx_rev2.cap(2) log["date"] = self.rx_rev2.cap(3) # number of lines is ignored elif self.rx_flags1.exactMatch(s): changedPaths.append({ "action": self.rx_flags1.cap(1).strip(), "path": self.rx_flags1.cap(2).strip(), "copyfrom_path": self.rx_flags1.cap(3).strip(), "copyfrom_revision": self.rx_flags1.cap(4).strip(), }) elif self.rx_flags2.exactMatch(s): changedPaths.append({ "action": self.rx_flags2.cap(1).strip(), "path": self.rx_flags2.cap(2).strip(), "copyfrom_path": "", "copyfrom_revision": "", }) elif self.rx_sep1.exactMatch(s) or self.rx_sep2.exactMatch(s): if len(log) > 1: self.__generateLogItem( log["author"], log["date"], log["message"], log["revision"], changedPaths) dt = QDate.fromString(log["date"], Qt.ISODate) if not self.__maxDate.isValid() and \ not self.__minDate.isValid(): self.__maxDate = dt self.__minDate = dt else: if self.__maxDate < dt: self.__maxDate = dt if self.__minDate > dt: self.__minDate = dt noEntries += 1 log = {"message": []} changedPaths = [] else: if s.strip().endswith(":") or not s.strip(): continue else: log["message"].append(s) self.__resizeColumnsLog() self.__resortLog() if self.__started: self.logTree.setCurrentItem(self.logTree.topLevelItem(0)) self.__started = False if noEntries < self.limitSpinBox.value() and not self.cancelled: self.nextButton.setEnabled(False) self.limitSpinBox.setEnabled(False) self.__filterLogsEnabled = False self.fromDate.setMinimumDate(self.__minDate) self.fromDate.setMaximumDate(self.__maxDate) self.fromDate.setDate(self.__minDate) self.toDate.setMinimumDate(self.__minDate) self.toDate.setMaximumDate(self.__maxDate) self.toDate.setDate(self.__maxDate) self.__filterLogsEnabled = True self.__filterLogs() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process and inserts it into a buffer. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): line = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.buf.append(line) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def __diffRevisions(self, rev1, rev2): """ Private method to do a diff of two revisions. @param rev1 first revision number (integer) @param rev2 second revision number (integer) """ if self.sbsCheckBox.isEnabled() and self.sbsCheckBox.isChecked(): self.vcs.svnSbsDiff(self.filename, revisions=(str(rev1), str(rev2))) else: if self.diff is None: from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self.vcs) self.diff.show() self.diff.raise_() self.diff.start(self.filename, [rev1, rev2]) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.cancelled = True self.__finish() @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_logTree_currentItemChanged(self, current, previous): """ Private slot called, when the current item of the log tree changes. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the old current item (QTreeWidgetItem) """ if current is not None: self.messageEdit.clear() for line in current.data(0, self.__messageRole): self.messageEdit.append(line.strip()) self.filesTree.clear() changes = current.data(0, self.__changesRole) if len(changes) > 0: for change in changes: self.__generateFileItem( change["action"], change["path"], change["copyfrom_path"], change["copyfrom_revision"]) self.__resizeColumnsFiles() self.__resortFiles() self.diffPreviousButton.setEnabled( current != self.logTree.topLevelItem( self.logTree.topLevelItemCount() - 1)) @pyqtSlot() def on_logTree_itemSelectionChanged(self): """ Private slot called, when the selection has changed. """ self.diffRevisionsButton.setEnabled( len(self.logTree.selectedItems()) == 2) @pyqtSlot() def on_nextButton_clicked(self): """ Private slot to handle the Next button. """ if self.__lastRev > 1: self.__getLogEntries(self.__lastRev - 1) @pyqtSlot() def on_diffPreviousButton_clicked(self): """ Private slot to handle the Diff to Previous button. """ itm = self.logTree.currentItem() if itm is None: self.diffPreviousButton.setEnabled(False) return rev2 = int(itm.text(0)) itm = self.logTree.topLevelItem( self.logTree.indexOfTopLevelItem(itm) + 1) if itm is None: self.diffPreviousButton.setEnabled(False) return rev1 = int(itm.text(0)) self.__diffRevisions(rev1, rev2) @pyqtSlot() def on_diffRevisionsButton_clicked(self): """ Private slot to handle the Compare Revisions button. """ items = self.logTree.selectedItems() if len(items) != 2: self.diffRevisionsButton.setEnabled(False) return rev2 = int(items[0].text(0)) rev1 = int(items[1].text(0)) self.__diffRevisions(min(rev1, rev2), max(rev1, rev2)) @pyqtSlot(QDate) def on_fromDate_dateChanged(self, date): """ Private slot called, when the from date changes. @param date new date (QDate) """ self.__filterLogs() @pyqtSlot(QDate) def on_toDate_dateChanged(self, date): """ Private slot called, when the from date changes. @param date new date (QDate) """ self.__filterLogs() @pyqtSlot(str) def on_fieldCombo_activated(self, txt): """ Private slot called, when a new filter field is selected. @param txt text of the selected field (string) """ self.__filterLogs() @pyqtSlot(str) def on_rxEdit_textChanged(self, txt): """ Private slot called, when a filter expression is entered. @param txt filter expression (string) """ self.__filterLogs() def __filterLogs(self): """ Private method to filter the log entries. """ if self.__filterLogsEnabled: from_ = self.fromDate.date().toString("yyyy-MM-dd") to_ = self.toDate.date().addDays(1).toString("yyyy-MM-dd") txt = self.fieldCombo.currentText() if txt == self.tr("Author"): fieldIndex = 1 searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive) elif txt == self.tr("Revision"): fieldIndex = 0 txt = self.rxEdit.text() if txt.startswith("^"): searchRx = QRegExp( "^\s*{0}".format(txt[1:]), Qt.CaseInsensitive) else: searchRx = QRegExp(txt, Qt.CaseInsensitive) else: fieldIndex = 3 searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive) currentItem = self.logTree.currentItem() for topIndex in range(self.logTree.topLevelItemCount()): topItem = self.logTree.topLevelItem(topIndex) if topItem.text(2) <= to_ and topItem.text(2) >= from_ and \ searchRx.indexIn(topItem.text(fieldIndex)) > -1: topItem.setHidden(False) if topItem is currentItem: self.on_logTree_currentItemChanged(topItem, None) else: topItem.setHidden(True) if topItem is currentItem: self.messageEdit.clear() self.filesTree.clear() @pyqtSlot(bool) def on_stopCheckBox_clicked(self, checked): """ Private slot called, when the stop on copy/move checkbox is clicked. @param checked flag indicating the checked state (boolean) """ self.vcs.getPlugin().setPreferences("StopLogOnCopy", self.stopCheckBox.isChecked()) self.nextButton.setEnabled(True) self.limitSpinBox.setEnabled(True) def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.errorGroup.show() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnLogBrowserDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnTagDialog.py0000644000175000017500000000431612451233371023737 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a tagging operation. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_SvnTagDialog import Ui_SvnTagDialog class SvnTagDialog(QDialog, Ui_SvnTagDialog): """ Class implementing a dialog to enter the data for a tagging operation. """ def __init__(self, taglist, reposURL, standardLayout, parent=None): """ Constructor @param taglist list of previously entered tags (list of strings) @param reposURL repository path (string) or None @param standardLayout flag indicating the layout of the repository (boolean) @param parent parent widget (QWidget) """ super(SvnTagDialog, self).__init__(parent) self.setupUi(self) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) self.tagCombo.clear() self.tagCombo.addItems(sorted(taglist)) if reposURL is not None and reposURL != "": self.tagCombo.setEditText(reposURL) if not standardLayout: self.TagActionGroup.setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def on_tagCombo_editTextChanged(self, text): """ Private method used to enable/disable the OK-button. @param text text of the tag combobox (string) """ self.okButton.setDisabled(text == "") def getParameters(self): """ Public method to retrieve the tag data. @return tuple of string and int (tag, tag operation) """ tag = self.tagCombo.currentText() tagOp = 0 if self.createRegularButton.isChecked(): tagOp = 1 elif self.createBranchButton.isChecked(): tagOp = 2 elif self.deleteRegularButton.isChecked(): tagOp = 4 elif self.deleteBranchButton.isChecked(): tagOp = 8 return (tag, tagOp) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/ProjectHelper.py0000644000175000017500000005673412451233371024176 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the VCS project helper for Subversion. """ from __future__ import unicode_literals import os from E5Gui.E5Application import e5App from VCS.ProjectHelper import VcsProjectHelper from E5Gui.E5Action import E5Action import UI.PixmapCache class SvnProjectHelper(VcsProjectHelper): """ Class implementing the VCS project helper for Subversion. """ def __init__(self, vcsObject, projectObject, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param projectObject reference to the project object @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectHelper.__init__(self, vcsObject, projectObject, parent, name) def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ return self.actions[:] def initActions(self): """ Public method to generate the action objects. """ self.vcsNewAct = E5Action( self.tr('New from repository'), UI.PixmapCache.getIcon("vcsCheckout.png"), self.tr('&New from repository...'), 0, 0, self, 'subversion_new') self.vcsNewAct.setStatusTip(self.tr( 'Create a new project from the VCS repository' )) self.vcsNewAct.setWhatsThis(self.tr( """New from repository""" """

This creates a new local project from the VCS""" """ repository.

""" )) self.vcsNewAct.triggered.connect(self._vcsCheckout) self.actions.append(self.vcsNewAct) self.vcsUpdateAct = E5Action( self.tr('Update from repository'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('&Update from repository'), 0, 0, self, 'subversion_update') self.vcsUpdateAct.setStatusTip(self.tr( 'Update the local project from the VCS repository' )) self.vcsUpdateAct.setWhatsThis(self.tr( """Update from repository""" """

This updates the local project from the VCS""" """ repository.

""" )) self.vcsUpdateAct.triggered.connect(self._vcsUpdate) self.actions.append(self.vcsUpdateAct) self.vcsCommitAct = E5Action( self.tr('Commit changes to repository'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('&Commit changes to repository...'), 0, 0, self, 'subversion_commit') self.vcsCommitAct.setStatusTip(self.tr( 'Commit changes to the local project to the VCS repository' )) self.vcsCommitAct.setWhatsThis(self.tr( """Commit changes to repository""" """

This commits changes to the local project to the VCS""" """ repository.

""" )) self.vcsCommitAct.triggered.connect(self._vcsCommit) self.actions.append(self.vcsCommitAct) self.vcsLogAct = E5Action( self.tr('Show log'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show &log'), 0, 0, self, 'subversion_log') self.vcsLogAct.setStatusTip(self.tr( 'Show the log of the local project' )) self.vcsLogAct.setWhatsThis(self.tr( """Show log""" """

This shows the log of the local project.

""" )) self.vcsLogAct.triggered.connect(self._vcsLog) self.actions.append(self.vcsLogAct) self.svnLogBrowserAct = E5Action( self.tr('Show log browser'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), 0, 0, self, 'subversion_log_browser') self.svnLogBrowserAct.setStatusTip(self.tr( 'Show a dialog to browse the log of the local project' )) self.svnLogBrowserAct.setWhatsThis(self.tr( """Show log browser""" """

This shows a dialog to browse the log of the local""" """ project. A limited number of entries is shown first. More""" """ can be retrieved later on.

""" )) self.svnLogBrowserAct.triggered.connect(self._vcsLogBrowser) self.actions.append(self.svnLogBrowserAct) self.vcsDiffAct = E5Action( self.tr('Show differences'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show &difference'), 0, 0, self, 'subversion_diff') self.vcsDiffAct.setStatusTip(self.tr( 'Show the difference of the local project to the repository' )) self.vcsDiffAct.setWhatsThis(self.tr( """Show differences""" """

This shows differences of the local project to the""" """ repository.

""" )) self.vcsDiffAct.triggered.connect(self._vcsDiff) self.actions.append(self.vcsDiffAct) self.svnExtDiffAct = E5Action( self.tr('Show differences (extended)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), 0, 0, self, 'subversion_extendeddiff') self.svnExtDiffAct.setStatusTip(self.tr( 'Show the difference of revisions of the project to the repository' )) self.svnExtDiffAct.setWhatsThis(self.tr( """Show differences (extended)""" """

This shows differences of selectable revisions of""" """ the project.

""" )) self.svnExtDiffAct.triggered.connect(self.__svnExtendedDiff) self.actions.append(self.svnExtDiffAct) self.svnUrlDiffAct = E5Action( self.tr('Show differences (URLs)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), 0, 0, self, 'subversion_urldiff') self.svnUrlDiffAct.setStatusTip(self.tr( 'Show the difference of the project between two repository URLs' )) self.svnUrlDiffAct.setWhatsThis(self.tr( """Show differences (URLs)""" """

This shows differences of the project between""" """ two repository URLs.

""" )) self.svnUrlDiffAct.triggered.connect(self.__svnUrlDiff) self.actions.append(self.svnUrlDiffAct) self.vcsStatusAct = E5Action( self.tr('Show status'), UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show &status'), 0, 0, self, 'subversion_status') self.vcsStatusAct.setStatusTip(self.tr( 'Show the status of the local project' )) self.vcsStatusAct.setWhatsThis(self.tr( """Show status""" """

This shows the status of the local project.

""" )) self.vcsStatusAct.triggered.connect(self._vcsStatus) self.actions.append(self.vcsStatusAct) self.svnChangeListsAct = E5Action( self.tr('Show change lists'), UI.PixmapCache.getIcon("vcsChangeLists.png"), self.tr('Show change lists'), 0, 0, self, 'subversion_changelists') self.svnChangeListsAct.setStatusTip(self.tr( 'Show the change lists and associated files of the local project' )) self.svnChangeListsAct.setWhatsThis(self.tr( """Show change lists""" """

This shows the change lists and associated files of the""" """ local project.

""" )) self.svnChangeListsAct.triggered.connect(self.__svnChangeLists) self.actions.append(self.svnChangeListsAct) self.vcsTagAct = E5Action( self.tr('Tag in repository'), UI.PixmapCache.getIcon("vcsTag.png"), self.tr('&Tag in repository...'), 0, 0, self, 'subversion_tag') self.vcsTagAct.setStatusTip(self.tr( 'Tag the local project in the repository' )) self.vcsTagAct.setWhatsThis(self.tr( """Tag in repository""" """

This tags the local project in the repository.

""" )) self.vcsTagAct.triggered.connect(self._vcsTag) self.actions.append(self.vcsTagAct) self.vcsExportAct = E5Action( self.tr('Export from repository'), UI.PixmapCache.getIcon("vcsExport.png"), self.tr('&Export from repository...'), 0, 0, self, 'subversion_export') self.vcsExportAct.setStatusTip(self.tr( 'Export a project from the repository' )) self.vcsExportAct.setWhatsThis(self.tr( """Export from repository""" """

This exports a project from the repository.

""" )) self.vcsExportAct.triggered.connect(self._vcsExport) self.actions.append(self.vcsExportAct) self.vcsPropsAct = E5Action( self.tr('Command options'), self.tr('Command &options...'), 0, 0, self, 'subversion_options') self.vcsPropsAct.setStatusTip(self.tr( 'Show the VCS command options')) self.vcsPropsAct.setWhatsThis(self.tr( """Command options...""" """

This shows a dialog to edit the VCS command options.

""" )) self.vcsPropsAct.triggered.connect(self._vcsCommandOptions) self.actions.append(self.vcsPropsAct) self.vcsRevertAct = E5Action( self.tr('Revert changes'), UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Re&vert changes'), 0, 0, self, 'subversion_revert') self.vcsRevertAct.setStatusTip(self.tr( 'Revert all changes made to the local project' )) self.vcsRevertAct.setWhatsThis(self.tr( """Revert changes""" """

This reverts all changes made to the local project.

""" )) self.vcsRevertAct.triggered.connect(self._vcsRevert) self.actions.append(self.vcsRevertAct) self.vcsMergeAct = E5Action( self.tr('Merge'), UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Mer&ge changes...'), 0, 0, self, 'subversion_merge') self.vcsMergeAct.setStatusTip(self.tr( 'Merge changes of a tag/revision into the local project' )) self.vcsMergeAct.setWhatsThis(self.tr( """Merge""" """

This merges changes of a tag/revision into the local""" """ project.

""" )) self.vcsMergeAct.triggered.connect(self._vcsMerge) self.actions.append(self.vcsMergeAct) self.vcsSwitchAct = E5Action( self.tr('Switch'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('S&witch...'), 0, 0, self, 'subversion_switch') self.vcsSwitchAct.setStatusTip(self.tr( 'Switch the local copy to another tag/branch' )) self.vcsSwitchAct.setWhatsThis(self.tr( """Switch""" """

This switches the local copy to another tag/branch.

""" )) self.vcsSwitchAct.triggered.connect(self._vcsSwitch) self.actions.append(self.vcsSwitchAct) self.vcsResolveAct = E5Action( self.tr('Conflicts resolved'), self.tr('Con&flicts resolved'), 0, 0, self, 'subversion_resolve') self.vcsResolveAct.setStatusTip(self.tr( 'Mark all conflicts of the local project as resolved' )) self.vcsResolveAct.setWhatsThis(self.tr( """Conflicts resolved""" """

This marks all conflicts of the local project as""" """ resolved.

""" )) self.vcsResolveAct.triggered.connect(self.__svnResolve) self.actions.append(self.vcsResolveAct) self.vcsCleanupAct = E5Action( self.tr('Cleanup'), self.tr('Cleanu&p'), 0, 0, self, 'subversion_cleanup') self.vcsCleanupAct.setStatusTip(self.tr( 'Cleanup the local project' )) self.vcsCleanupAct.setWhatsThis(self.tr( """Cleanup""" """

This performs a cleanup of the local project.

""" )) self.vcsCleanupAct.triggered.connect(self._vcsCleanup) self.actions.append(self.vcsCleanupAct) self.vcsCommandAct = E5Action( self.tr('Execute command'), self.tr('E&xecute command...'), 0, 0, self, 'subversion_command') self.vcsCommandAct.setStatusTip(self.tr( 'Execute an arbitrary VCS command' )) self.vcsCommandAct.setWhatsThis(self.tr( """Execute command""" """

This opens a dialog to enter an arbitrary VCS command.

""" )) self.vcsCommandAct.triggered.connect(self._vcsCommand) self.actions.append(self.vcsCommandAct) self.svnTagListAct = E5Action( self.tr('List tags'), self.tr('List tags...'), 0, 0, self, 'subversion_list_tags') self.svnTagListAct.setStatusTip(self.tr( 'List tags of the project' )) self.svnTagListAct.setWhatsThis(self.tr( """List tags""" """

This lists the tags of the project.

""" )) self.svnTagListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnTagListAct) self.svnBranchListAct = E5Action( self.tr('List branches'), self.tr('List branches...'), 0, 0, self, 'subversion_list_branches') self.svnBranchListAct.setStatusTip(self.tr( 'List branches of the project' )) self.svnBranchListAct.setWhatsThis(self.tr( """List branches""" """

This lists the branches of the project.

""" )) self.svnBranchListAct.triggered.connect(self.__svnBranchList) self.actions.append(self.svnBranchListAct) self.svnListAct = E5Action( self.tr('List repository contents'), self.tr('List repository contents...'), 0, 0, self, 'subversion_contents') self.svnListAct.setStatusTip(self.tr( 'Lists the contents of the repository' )) self.svnListAct.setWhatsThis(self.tr( """List repository contents""" """

This lists the contents of the repository.

""" )) self.svnListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnListAct) self.svnPropSetAct = E5Action( self.tr('Set Property'), self.tr('Set Property...'), 0, 0, self, 'subversion_property_set') self.svnPropSetAct.setStatusTip(self.tr( 'Set a property for the project files' )) self.svnPropSetAct.setWhatsThis(self.tr( """Set Property""" """

This sets a property for the project files.

""" )) self.svnPropSetAct.triggered.connect(self.__svnPropSet) self.actions.append(self.svnPropSetAct) self.svnPropListAct = E5Action( self.tr('List Properties'), self.tr('List Properties...'), 0, 0, self, 'subversion_property_list') self.svnPropListAct.setStatusTip(self.tr( 'List properties of the project files' )) self.svnPropListAct.setWhatsThis(self.tr( """List Properties""" """

This lists the properties of the project files.

""" )) self.svnPropListAct.triggered.connect(self.__svnPropList) self.actions.append(self.svnPropListAct) self.svnPropDelAct = E5Action( self.tr('Delete Property'), self.tr('Delete Property...'), 0, 0, self, 'subversion_property_delete') self.svnPropDelAct.setStatusTip(self.tr( 'Delete a property for the project files' )) self.svnPropDelAct.setWhatsThis(self.tr( """Delete Property""" """

This deletes a property for the project files.

""" )) self.svnPropDelAct.triggered.connect(self.__svnPropDel) self.actions.append(self.svnPropDelAct) self.svnRelocateAct = E5Action( self.tr('Relocate'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('Relocate...'), 0, 0, self, 'subversion_relocate') self.svnRelocateAct.setStatusTip(self.tr( 'Relocate the working copy to a new repository URL' )) self.svnRelocateAct.setWhatsThis(self.tr( """Relocate""" """

This relocates the working copy to a new repository""" """ URL.

""" )) self.svnRelocateAct.triggered.connect(self.__svnRelocate) self.actions.append(self.svnRelocateAct) self.svnRepoBrowserAct = E5Action( self.tr('Repository Browser'), UI.PixmapCache.getIcon("vcsRepoBrowser.png"), self.tr('Repository Browser...'), 0, 0, self, 'subversion_repo_browser') self.svnRepoBrowserAct.setStatusTip(self.tr( 'Show the Repository Browser dialog' )) self.svnRepoBrowserAct.setWhatsThis(self.tr( """Repository Browser""" """

This shows the Repository Browser dialog.

""" )) self.svnRepoBrowserAct.triggered.connect(self.__svnRepoBrowser) self.actions.append(self.svnRepoBrowserAct) self.svnConfigAct = E5Action( self.tr('Configure'), self.tr('Configure...'), 0, 0, self, 'subversion_configure') self.svnConfigAct.setStatusTip(self.tr( 'Show the configuration dialog with the Subversion page selected' )) self.svnConfigAct.setWhatsThis(self.tr( """Configure""" """

Show the configuration dialog with the Subversion page""" """ selected.

""" )) self.svnConfigAct.triggered.connect(self.__svnConfigure) self.actions.append(self.svnConfigAct) self.svnUpgradeAct = E5Action( self.tr('Upgrade'), self.tr('Upgrade...'), 0, 0, self, 'subversion_upgrade') self.svnUpgradeAct.setStatusTip(self.tr( 'Upgrade the working copy to the current format' )) self.svnUpgradeAct.setWhatsThis(self.tr( """Upgrade""" """

Upgrades the working copy to the current format.

""" )) self.svnUpgradeAct.triggered.connect(self.__svnUpgrade) self.actions.append(self.svnUpgradeAct) def initMenu(self, menu): """ Public method to generate the VCS menu. @param menu reference to the menu to be populated (QMenu) """ menu.clear() act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._vcsInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.vcsUpdateAct) menu.addAction(self.vcsCommitAct) menu.addSeparator() menu.addAction(self.vcsNewAct) menu.addAction(self.vcsExportAct) menu.addSeparator() menu.addAction(self.vcsTagAct) if self.vcs.otherData["standardLayout"]: menu.addAction(self.svnTagListAct) menu.addAction(self.svnBranchListAct) else: menu.addAction(self.svnListAct) menu.addSeparator() menu.addAction(self.vcsLogAct) menu.addAction(self.svnLogBrowserAct) menu.addSeparator() menu.addAction(self.vcsStatusAct) menu.addAction(self.svnChangeListsAct) menu.addSeparator() menu.addAction(self.vcsDiffAct) menu.addAction(self.svnExtDiffAct) menu.addAction(self.svnUrlDiffAct) menu.addSeparator() menu.addAction(self.vcsRevertAct) menu.addAction(self.vcsMergeAct) menu.addAction(self.vcsResolveAct) menu.addSeparator() menu.addAction(self.svnRelocateAct) menu.addAction(self.vcsSwitchAct) menu.addSeparator() menu.addAction(self.svnPropSetAct) menu.addAction(self.svnPropListAct) menu.addAction(self.svnPropDelAct) menu.addSeparator() menu.addAction(self.vcsCleanupAct) menu.addSeparator() menu.addAction(self.vcsCommandAct) menu.addAction(self.svnRepoBrowserAct) menu.addAction(self.svnUpgradeAct) menu.addSeparator() menu.addAction(self.vcsPropsAct) menu.addSeparator() menu.addAction(self.svnConfigAct) def __svnResolve(self): """ Private slot used to resolve conflicts of the local project. """ self.vcs.svnResolve(self.project.ppath) def __svnPropList(self): """ Private slot used to list the properties of the project files. """ self.vcs.svnListProps(self.project.ppath, True) def __svnPropSet(self): """ Private slot used to set a property for the project files. """ self.vcs.svnSetProp(self.project.ppath, True) def __svnPropDel(self): """ Private slot used to delete a property for the project files. """ self.vcs.svnDelProp(self.project.ppath, True) def __svnTagList(self): """ Private slot used to list the tags of the project. """ self.vcs.svnListTagBranch(self.project.ppath, True) def __svnBranchList(self): """ Private slot used to list the branches of the project. """ self.vcs.svnListTagBranch(self.project.ppath, False) def __svnExtendedDiff(self): """ Private slot used to perform a svn diff with the selection of revisions. """ self.vcs.svnExtendedDiff(self.project.ppath) def __svnUrlDiff(self): """ Private slot used to perform a svn diff with the selection of repository URLs. """ self.vcs.svnUrlDiff(self.project.ppath) def __svnRelocate(self): """ Private slot used to relocate the working copy to a new repository URL. """ self.vcs.svnRelocate(self.project.ppath) def __svnRepoBrowser(self): """ Private slot to open the repository browser. """ self.vcs.svnRepoBrowser(projectPath=self.project.ppath) def __svnConfigure(self): """ Private slot to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("zzz_subversionPage") def __svnChangeLists(self): """ Private slot used to show a list of change lists. """ self.vcs.svnShowChangelists(self.project.ppath) def __svnUpgrade(self): """ Private slot used to upgrade the working copy format. """ self.vcs.svnUpgrade(self.project.ppath) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnLogDialog.py0000644000175000017500000002742012451233371023746 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn log command process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QTimer, QProcess, QRegExp, QUrl, pyqtSlot, qVersion, \ QByteArray from PyQt5.QtGui import QTextCursor from PyQt5.QtWidgets import QWidget, QLineEdit, QApplication, QDialogButtonBox from E5Gui import E5MessageBox from .Ui_SvnLogDialog import Ui_SvnLogDialog import Utilities import Preferences class SvnLogDialog(QWidget, Ui_SvnLogDialog): """ Class implementing a dialog to show the output of the svn log command process. The dialog is nonmodal. Clicking a link in the upper text pane shows a diff of the versions. """ def __init__(self, vcs, isFile=False, parent=None): """ Constructor @param vcs reference to the vcs object @param isFile flag indicating log for a file is to be shown (boolean) @param parent parent widget (QWidget) """ super(SvnLogDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.process = QProcess() self.vcs = vcs self.contents.setHtml( self.tr('Processing your request, please wait...')) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.contents.anchorClicked.connect(self.__sourceChanged) self.rx_sep = QRegExp('\\-+\\s*') self.rx_sep2 = QRegExp('=+\\s*') self.rx_rev = QRegExp( 'rev ([0-9]+): ([^|]*) \| ([^|]*) \| ([0-9]+) .*') # "rev" followed by one or more decimals followed by a colon followed # anything up to " | " (twice) followed by one or more decimals # followed by anything self.rx_rev2 = QRegExp( 'r([0-9]+) \| ([^|]*) \| ([^|]*) \| ([0-9]+) .*') # "r" followed by one or more decimals followed by " | " followed # anything up to " | " (twice) followed by one or more decimals # followed by anything self.rx_flags = QRegExp(' ([ADM])( .*)\\s*') # three blanks followed by A or D or M self.rx_changed = QRegExp('Changed .*\\s*') self.flags = { 'A': self.tr('Added'), 'D': self.tr('Deleted'), 'M': self.tr('Modified') } self.revisions = [] # stack of remembered revisions self.revString = self.tr('revision') self.buf = [] # buffer for stdout self.diff = None self.sbsCheckBox.setEnabled(isFile) self.sbsCheckBox.setVisible(isFile) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, fn, noEntries=0): """ Public slot to start the cvs log command. @param fn filename to show the log for (string) @param noEntries number of entries to show (integer) """ self.errorGroup.hide() QApplication.processEvents() self.intercept = False self.filename = fn self.dname, self.fname = self.vcs.splitPath(fn) self.process.kill() args = [] args.append('log') self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['log']) if noEntries: args.append('--limit') args.append(str(noEntries)) self.activateWindow() self.raise_() args.append(self.fname) self.process.setWorkingDirectory(self.dname) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.inputGroup.setEnabled(False) self.inputGroup.hide() self.contents.clear() lvers = 1 for s in self.buf: rev_match = False if self.rx_rev.exactMatch(s): ver = self.rx_rev.cap(1) author = self.rx_rev.cap(2) date = self.rx_rev.cap(3) # number of lines is ignored rev_match = True elif self.rx_rev2.exactMatch(s): ver = self.rx_rev2.cap(1) author = self.rx_rev2.cap(2) date = self.rx_rev2.cap(3) # number of lines is ignored rev_match = True if rev_match: dstr = '{0} {1}'.format(self.revString, ver) try: lv = self.revisions[lvers] lvers += 1 url = QUrl() url.setScheme("file") url.setPath(self.filename) if qVersion() >= "5.0.0": query = lv + '_' + ver url.setQuery(query) else: query = QByteArray() query.append(lv).append('_').append(ver) url.setEncodedQuery(query) dstr += ' [{2}]'.format( url.toString(), query, self.tr('diff to {0}').format(lv), ) except IndexError: pass dstr += '
\n' self.contents.insertHtml(dstr) dstr = self.tr('author: {0}
\n').format(author) self.contents.insertHtml(dstr) dstr = self.tr('date: {0}
\n').format(date) self.contents.insertHtml(dstr) elif self.rx_sep.exactMatch(s) or self.rx_sep2.exactMatch(s): self.contents.insertHtml('
\n') elif self.rx_flags.exactMatch(s): dstr = self.flags[self.rx_flags.cap(1)] dstr += self.rx_flags.cap(2) dstr += '
\n' self.contents.insertHtml(dstr) elif self.rx_changed.exactMatch(s): dstr = '
{0}
\n'.format(s) self.contents.insertHtml(dstr) else: if s == "": s = self.contents.insertHtml('
\n') else: self.contents.insertHtml(Utilities.html_encode(s)) self.contents.insertHtml('
\n') tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process and inserts it into a buffer. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): line = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.buf.append(line) if self.rx_rev.exactMatch(line): ver = self.rx_rev.cap(1) # save revision number for later use self.revisions.append(ver) elif self.rx_rev2.exactMatch(line): ver = self.rx_rev2.cap(1) # save revision number for later use self.revisions.append(ver) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def __sourceChanged(self, url): """ Private slot to handle the sourceChanged signal of the contents pane. @param url the url that was clicked (QUrl) """ self.contents.setSource(QUrl('')) filename = url.path() if Utilities.isWindowsPlatform(): if filename.startswith("/"): filename = filename[1:] if qVersion() >= "5.0.0": ver = url.query() else: ver = bytes(url.encodedQuery()).decode() v1 = ver.split('_')[0] v2 = ver.split('_')[1] if v1 == "" or v2 == "": return self.contents.scrollToAnchor(ver) if self.sbsCheckBox.isEnabled() and self.sbsCheckBox.isChecked(): self.vcs.svnSbsDiff(filename, revisions=(v1, v2)) else: if self.diff is None: from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self.vcs) self.diff.show() self.diff.start(filename, [v1, v2]) def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnLogDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/__init__.py0000644000175000017500000000041112451233371023144 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Package implementing the vcs interface to Subversion. It consists of the subversion class, the project helper classes and some Subversion specific dialogs. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnMergeDialog.ui0000644000175000017500000001147212354033767024262 0ustar piotrpiotr SvnMergeDialog 0 0 456 152 Subversion Merge true Select to force the merge operation Enforce merge Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Target: Enter the target <b>Target</b> <p>Enter the target for the merge operation into this field. Leave it empty to get the target URL from the working copy.</p> <p><b>Note:</b> This entry is only needed, if you enter revision numbers above.</p> true QComboBox::InsertAtTop false 1. URL/Revision: 0 0 Enter an URL or a revision number <b>URL/Revision</b> <p>Enter an URL or a revision number to be merged into the working copy.</p> true false 0 0 Enter an URL or a revision number <b>URL/Revision</b> <p>Enter an URL or a revision number to be merged into the working copy.</p> true false 2. URL/Revision: qPixmapFromMimeSource tag1Combo tag2Combo targetCombo forceCheckBox buttonBox buttonBox accepted() SvnMergeDialog accept() 35 101 34 126 buttonBox rejected() SvnMergeDialog reject() 105 107 105 126 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnTagBranchListDialog.ui0000644000175000017500000001155112060166053025673 0ustar piotrpiotr SvnTagBranchListDialog 0 0 634 494 Subversion Tag List <b>Subversion Tag/Branch List</b> <p>This dialog shows a list of the projects tags or branches.</p> true 0 2 <b>Tag/Branches List</b> <p>This shows a list of the projects tags or branches.</p> true false false true Revision Author Date Name 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource tagList errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnDialog.py0000644000175000017500000002137412537064320023307 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog starting a process and showing its output. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QTimer, QProcess, pyqtSlot, Qt, QProcessEnvironment from PyQt5.QtWidgets import QLineEdit, QDialog, QDialogButtonBox from E5Gui import E5MessageBox from .Ui_SvnDialog import Ui_SvnDialog import Preferences class SvnDialog(QDialog, Ui_SvnDialog): """ Class implementing a dialog starting a process and showing its output. It starts a QProcess and displays a dialog that shows the output of the process. The dialog is modal, which causes a synchronized execution of the process. """ def __init__(self, text, parent=None): """ Constructor @param text text to be shown by the label (string) @param parent parent widget (QWidget) """ super(SvnDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.proc = None self.username = '' self.password = '' self.outputGroup.setTitle(text) def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.proc is not None and \ self.proc.state() != QProcess.NotRunning: self.proc.terminate() QTimer.singleShot(2000, self.proc.kill) self.proc.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.proc = None self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) if Preferences.getVCS("AutoClose") and \ self.normal and \ self.errors.toPlainText() == "": self.accept() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.normal = (exitStatus == QProcess.NormalExit) and (exitCode == 0) self.__finish() def startProcess(self, args, workingDir=None, setLanguage=False): """ Public slot used to start the process. @param args list of arguments for the process (list of strings) @param workingDir working directory for the process (string) @param setLanguage flag indicating to set the language to "C" (boolean) @return flag indicating a successful start of the process """ self.errorGroup.hide() self.normal = False self.intercept = False self.__hasAddOrDelete = False self.proc = QProcess() if setLanguage: env = QProcessEnvironment.systemEnvironment() env.insert("LANG", "C") self.proc.setProcessEnvironment(env) nargs = [] lastWasPwd = False for arg in args: if lastWasPwd: lastWasPwd = True continue nargs.append(arg) if arg == '--password': lastWasPwd = True nargs.append('*****') self.resultbox.append(' '.join(nargs)) self.resultbox.append('') self.proc.finished.connect(self.__procFinished) self.proc.readyReadStandardOutput.connect(self.__readStdout) self.proc.readyReadStandardError.connect(self.__readStderr) if workingDir: self.proc.setWorkingDirectory(workingDir) self.proc.start('svn', args) procStarted = self.proc.waitForStarted(5000) if not procStarted: self.buttonBox.setFocus() self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() return procStarted def normalExit(self): """ Public method to check for a normal process termination. @return flag indicating normal process termination (boolean) """ return self.normal def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.proc is not None: s = str(self.proc.readAllStandardOutput(), Preferences.getSystem("IOEncoding"), 'replace') self.resultbox.insertPlainText(s) self.resultbox.ensureCursorVisible() if not self.__hasAddOrDelete and len(s) > 0: # check the output for l in s.split(os.linesep): if '.e4p' in l: self.__hasAddOrDelete = True break if l and l[0:2].strip() in ['A', 'D']: self.__hasAddOrDelete = True break def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.proc is not None: self.errorGroup.show() s = str(self.proc.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.proc.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnDialog, self).keyPressEvent(evt) def hasAddOrDelete(self): """ Public method to check, if the last action contained an add or delete. @return flag indicating the presence of an add or delete (boolean) """ return self.__hasAddOrDelete eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnChangeListsDialog.ui0000644000175000017500000001314312060166053025411 0ustar piotrpiotr SvnChangeListsDialog 0 0 519 494 Subversion Change Lists true Change Lists: 0 1 <b>Change Lists</b> <p>Select a change list here to see the associated files in the list below.</p> true true 0 2 <b>Files</b> <p>This shows a list of files associated with the change list selected above.</p> true 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close changeLists filesList errors input passwordCheckBox sendButton buttonBox buttonBox accepted() SvnChangeListsDialog accept() 248 254 157 274 buttonBox rejected() SvnChangeListsDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnStatusDialog.py0000644000175000017500000011251412451233371024507 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn status command process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QTimer, QProcess, QRegExp, Qt, pyqtSlot from PyQt5.QtWidgets import QWidget, QHeaderView, QLineEdit, QApplication, \ QMenu, QDialogButtonBox, QTreeWidgetItem from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .Ui_SvnStatusDialog import Ui_SvnStatusDialog import Preferences class SvnStatusDialog(QWidget, Ui_SvnStatusDialog): """ Class implementing a dialog to show the output of the svn status command process. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnStatusDialog, self).__init__(parent) self.setupUi(self) self.__toBeCommittedColumn = 0 self.__changelistColumn = 1 self.__statusColumn = 2 self.__propStatusColumn = 3 self.__lockedColumn = 4 self.__historyColumn = 5 self.__switchedColumn = 6 self.__lockinfoColumn = 7 self.__upToDateColumn = 8 self.__pathColumn = 12 self.__lastColumn = self.statusList.columnCount() self.refreshButton = \ self.buttonBox.addButton(self.tr("Refresh"), QDialogButtonBox.ActionRole) self.refreshButton.setToolTip( self.tr("Press to refresh the status display")) self.refreshButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.diff = None self.process = None self.vcs = vcs self.vcs.committed.connect(self.__committed) self.statusList.headerItem().setText(self.__lastColumn, "") self.statusList.header().setSortIndicator(self.__pathColumn, Qt.AscendingOrder) if self.vcs.version < (1, 5, 0): self.statusList.header().hideSection(self.__changelistColumn) self.menuactions = [] self.menu = QMenu() self.menuactions.append(self.menu.addAction( self.tr("Commit changes to repository..."), self.__commit)) self.menuactions.append(self.menu.addAction( self.tr("Select all for commit"), self.__commitSelectAll)) self.menuactions.append(self.menu.addAction( self.tr("Deselect all from commit"), self.__commitDeselectAll)) self.menu.addSeparator() self.menuactions.append(self.menu.addAction( self.tr("Add to repository"), self.__add)) self.menuactions.append(self.menu.addAction( self.tr("Show differences"), self.__diff)) self.menuactions.append(self.menu.addAction( self.tr("Show differences side-by-side"), self.__sbsDiff)) self.menuactions.append(self.menu.addAction( self.tr("Revert changes"), self.__revert)) self.menuactions.append(self.menu.addAction( self.tr("Restore missing"), self.__restoreMissing)) if self.vcs.version >= (1, 5, 0): self.menu.addSeparator() self.menuactions.append(self.menu.addAction( self.tr("Add to Changelist"), self.__addToChangelist)) self.menuactions.append(self.menu.addAction( self.tr("Remove from Changelist"), self.__removeFromChangelist)) if self.vcs.version >= (1, 2, 0): self.menu.addSeparator() self.menuactions.append(self.menu.addAction( self.tr("Lock"), self.__lock)) self.menuactions.append(self.menu.addAction( self.tr("Unlock"), self.__unlock)) self.menuactions.append(self.menu.addAction( self.tr("Break lock"), self.__breakLock)) self.menuactions.append(self.menu.addAction( self.tr("Steal lock"), self.__stealLock)) self.menu.addSeparator() self.menuactions.append(self.menu.addAction( self.tr("Adjust column sizes"), self.__resizeColumns)) for act in self.menuactions: act.setEnabled(False) self.statusList.setContextMenuPolicy(Qt.CustomContextMenu) self.statusList.customContextMenuRequested.connect( self.__showContextMenu) self.modifiedIndicators = [ self.tr('added'), self.tr('deleted'), self.tr('modified'), ] self.missingIndicators = [ self.tr('missing'), ] self.unversionedIndicators = [ self.tr('unversioned'), ] self.lockedIndicators = [ self.tr('locked'), ] self.stealBreakLockIndicators = [ self.tr('other lock'), self.tr('stolen lock'), self.tr('broken lock'), ] self.unlockedIndicators = [ self.tr('not locked'), ] self.status = { ' ': self.tr('normal'), 'A': self.tr('added'), 'D': self.tr('deleted'), 'M': self.tr('modified'), 'R': self.tr('replaced'), 'C': self.tr('conflict'), 'X': self.tr('external'), 'I': self.tr('ignored'), '?': self.tr('unversioned'), '!': self.tr('missing'), '~': self.tr('type error'), } self.propStatus = { ' ': self.tr('normal'), 'M': self.tr('modified'), 'C': self.tr('conflict'), } self.locked = { ' ': self.tr('no'), 'L': self.tr('yes'), } self.history = { ' ': self.tr('no'), '+': self.tr('yes'), } self.switched = { ' ': self.tr('no'), 'S': self.tr('yes'), } self.lockinfo = { ' ': self.tr('not locked'), 'K': self.tr('locked'), 'O': self.tr('other lock'), 'T': self.tr('stolen lock'), 'B': self.tr('broken lock'), } self.uptodate = { ' ': self.tr('yes'), '*': self.tr('no'), } self.rx_status = QRegExp( '(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*') # flags (8 or 9 anything), revision, changed rev, author, path self.rx_status2 = \ QRegExp('(.{8,9})\\s+(.+)\\s*') # flags (8 or 9 anything), path self.rx_changelist = \ QRegExp('--- \\S+ .([\\w\\s]+).:\\s+') # three dashes, Changelist (translated), quote, # changelist name, quote, : self.__nonverbose = True def __resort(self): """ Private method to resort the tree. """ self.statusList.sortItems( self.statusList.sortColumn(), self.statusList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.statusList.header().resizeSections(QHeaderView.ResizeToContents) self.statusList.header().setStretchLastSection(True) def __generateItem(self, status, propStatus, locked, history, switched, lockinfo, uptodate, revision, change, author, path): """ Private method to generate a status item in the status list. @param status status indicator (string) @param propStatus property status indicator (string) @param locked locked indicator (string) @param history history indicator (string) @param switched switched indicator (string) @param lockinfo lock indicator (string) @param uptodate up to date indicator (string) @param revision revision string (string) @param change revision of last change (string) @param author author of the last change (string) @param path path of the file or directory (string) """ if self.__nonverbose and \ status == " " and \ propStatus == " " and \ locked == " " and \ history == " " and \ switched == " " and \ lockinfo == " " and \ uptodate == " " and \ self.currentChangelist == "": return if revision == "": rev = "" else: try: rev = int(revision) except ValueError: rev = revision if change == "": chg = "" else: try: chg = int(change) except ValueError: chg = change statusText = self.status[status] itm = QTreeWidgetItem(self.statusList) itm.setData(0, Qt.DisplayRole, "") itm.setData(1, Qt.DisplayRole, self.currentChangelist) itm.setData(2, Qt.DisplayRole, statusText) itm.setData(3, Qt.DisplayRole, self.propStatus[propStatus]) itm.setData(4, Qt.DisplayRole, self.locked[locked]) itm.setData(5, Qt.DisplayRole, self.history[history]) itm.setData(6, Qt.DisplayRole, self.switched[switched]) itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo]) itm.setData(8, Qt.DisplayRole, self.uptodate[uptodate]) itm.setData(9, Qt.DisplayRole, rev) itm.setData(10, Qt.DisplayRole, chg) itm.setData(11, Qt.DisplayRole, author) itm.setData(12, Qt.DisplayRole, path) itm.setTextAlignment(1, Qt.AlignLeft) itm.setTextAlignment(2, Qt.AlignHCenter) itm.setTextAlignment(3, Qt.AlignHCenter) itm.setTextAlignment(4, Qt.AlignHCenter) itm.setTextAlignment(5, Qt.AlignHCenter) itm.setTextAlignment(6, Qt.AlignHCenter) itm.setTextAlignment(7, Qt.AlignHCenter) itm.setTextAlignment(8, Qt.AlignHCenter) itm.setTextAlignment(9, Qt.AlignRight) itm.setTextAlignment(10, Qt.AlignRight) itm.setTextAlignment(11, Qt.AlignLeft) itm.setTextAlignment(12, Qt.AlignLeft) if status in "ADM" or propStatus in "M": itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable) self.hidePropertyStatusColumn = self.hidePropertyStatusColumn and \ propStatus == " " self.hideLockColumns = self.hideLockColumns and \ locked == " " and lockinfo == " " self.hideUpToDateColumn = self.hideUpToDateColumn and uptodate == " " self.hideHistoryColumn = self.hideHistoryColumn and history == " " self.hideSwitchedColumn = self.hideSwitchedColumn and switched == " " if statusText not in self.__statusFilters: self.__statusFilters.append(statusText) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, fn): """ Public slot to start the svn status command. @param fn filename(s)/directoryname(s) to show the status of (string or list of strings) """ self.errorGroup.hide() self.intercept = False self.args = fn for act in self.menuactions: act.setEnabled(False) self.addButton.setEnabled(False) self.commitButton.setEnabled(False) self.diffButton.setEnabled(False) self.sbsDiffButton.setEnabled(False) self.revertButton.setEnabled(False) self.restoreButton.setEnabled(False) self.statusFilterCombo.clear() self.__statusFilters = [] self.currentChangelist = "" self.changelistFound = False self.hidePropertyStatusColumn = True self.hideLockColumns = True self.hideUpToDateColumn = True self.hideHistoryColumn = True self.hideSwitchedColumn = True if self.process: self.process.kill() else: self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) args = [] args.append('status') self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['status']) if '--verbose' not in self.vcs.options['global'] and \ '--verbose' not in self.vcs.options['status']: args.append('--verbose') self.__nonverbose = True else: self.__nonverbose = False if '--show-updates' in self.vcs.options['status'] or \ '-u' in self.vcs.options['status']: self.activateWindow() self.raise_() if isinstance(fn, list): self.dname, fnames = self.vcs.splitPathList(fn) self.vcs.addArguments(args, fnames) else: self.dname, fname = self.vcs.splitPath(fn) args.append(fname) self.process.setWorkingDirectory(self.dname) self.setWindowTitle(self.tr('Subversion Status')) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.refreshButton.setEnabled(True) self.__statusFilters.sort() self.__statusFilters.insert(0, "<{0}>".format(self.tr("all"))) self.statusFilterCombo.addItems(self.__statusFilters) for act in self.menuactions: act.setEnabled(True) self.process = None self.__resort() self.__resizeColumns() self.statusList.setColumnHidden(self.__changelistColumn, not self.changelistFound) self.statusList.setColumnHidden(self.__propStatusColumn, self.hidePropertyStatusColumn) self.statusList.setColumnHidden(self.__lockedColumn, self.hideLockColumns) self.statusList.setColumnHidden(self.__lockinfoColumn, self.hideLockColumns) self.statusList.setColumnHidden(self.__upToDateColumn, self.hideUpToDateColumn) self.statusList.setColumnHidden(self.__historyColumn, self.hideHistoryColumn) self.statusList.setColumnHidden(self.__switchedColumn, self.hideSwitchedColumn) self.__updateButtons() self.__updateCommitButton() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() elif button == self.refreshButton: self.on_refreshButton_clicked() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.process is not None: self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') if self.rx_status.exactMatch(s): flags = self.rx_status.cap(1) rev = self.rx_status.cap(2) change = self.rx_status.cap(3) author = self.rx_status.cap(4) path = self.rx_status.cap(5).strip() self.__generateItem(flags[0], flags[1], flags[2], flags[3], flags[4], flags[5], flags[-1], rev, change, author, path) elif self.rx_status2.exactMatch(s): flags = self.rx_status2.cap(1) path = self.rx_status2.cap(2).strip() self.__generateItem(flags[0], flags[1], flags[2], flags[3], flags[4], flags[5], flags[-1], "", "", "", path) elif self.rx_changelist.exactMatch(s): self.currentChangelist = self.rx_changelist.cap(1) self.changelistFound = True def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnStatusDialog, self).keyPressEvent(evt) @pyqtSlot() def on_refreshButton_clicked(self): """ Private slot to refresh the status display. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.inputGroup.setEnabled(True) self.inputGroup.show() self.refreshButton.setEnabled(False) self.statusList.clear() self.start(self.args) def __updateButtons(self): """ Private method to update the VCS buttons status. """ modified = len(self.__getModifiedItems()) unversioned = len(self.__getUnversionedItems()) missing = len(self.__getMissingItems()) self.addButton.setEnabled(unversioned) self.diffButton.setEnabled(modified) self.sbsDiffButton.setEnabled(modified == 1) self.revertButton.setEnabled(modified) self.restoreButton.setEnabled(missing) def __updateCommitButton(self): """ Private method to update the Commit button status. """ commitable = len(self.__getCommitableItems()) self.commitButton.setEnabled(commitable) @pyqtSlot(str) def on_statusFilterCombo_activated(self, txt): """ Private slot to react to the selection of a status filter. @param txt selected status filter (string) """ if txt == "<{0}>".format(self.tr("all")): for topIndex in range(self.statusList.topLevelItemCount()): topItem = self.statusList.topLevelItem(topIndex) topItem.setHidden(False) else: for topIndex in range(self.statusList.topLevelItemCount()): topItem = self.statusList.topLevelItem(topIndex) topItem.setHidden(topItem.text(self.__statusColumn) != txt) @pyqtSlot(QTreeWidgetItem, int) def on_statusList_itemChanged(self, item, column): """ Private slot to act upon item changes. @param item reference to the changed item (QTreeWidgetItem) @param column index of column that changed (integer) """ if column == self.__toBeCommittedColumn: self.__updateCommitButton() @pyqtSlot() def on_statusList_itemSelectionChanged(self): """ Private slot to act upon changes of selected items. """ self.__updateButtons() @pyqtSlot() def on_commitButton_clicked(self): """ Private slot to handle the press of the Commit button. """ self.__commit() @pyqtSlot() def on_addButton_clicked(self): """ Private slot to handle the press of the Add button. """ self.__add() @pyqtSlot() def on_diffButton_clicked(self): """ Private slot to handle the press of the Differences button. """ self.__diff() @pyqtSlot() def on_sbsDiffButton_clicked(self): """ Private slot to handle the press of the Side-by-Side Diff button. """ self.__sbsDiff() @pyqtSlot() def on_revertButton_clicked(self): """ Private slot to handle the press of the Revert button. """ self.__revert() @pyqtSlot() def on_restoreButton_clicked(self): """ Private slot to handle the press of the Restore button. """ self.__restoreMissing() ########################################################################### ## Context menu handling methods ########################################################################### def __showContextMenu(self, coord): """ Private slot to show the context menu of the status list. @param coord the position of the mouse pointer (QPoint) """ self.menu.popup(self.statusList.mapToGlobal(coord)) def __commit(self): """ Private slot to handle the Commit context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getCommitableItems()] if not names: E5MessageBox.information( self, self.tr("Commit"), self.tr("""There are no entries selected to be""" """ committed.""")) return if Preferences.getVCS("AutoSaveFiles"): vm = e5App().getObject("ViewManager") for name in names: vm.saveEditor(name) self.vcs.vcsCommit(names, '') def __committed(self): """ Private slot called after the commit has finished. """ if self.isVisible(): self.on_refreshButton_clicked() self.vcs.checkVCSStatus() def __commitSelectAll(self): """ Private slot to select all entries for commit. """ self.__commitSelect(True) def __commitDeselectAll(self): """ Private slot to deselect all entries from commit. """ self.__commitSelect(False) def __add(self): """ Private slot to handle the Add context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getUnversionedItems()] if not names: E5MessageBox.information( self, self.tr("Add"), self.tr("""There are no unversioned entries""" """ available/selected.""")) return self.vcs.vcsAdd(names) self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus() def __revert(self): """ Private slot to handle the Revert context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Revert"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return self.vcs.vcsRevert(names) self.raise_() self.activateWindow() self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus() def __restoreMissing(self): """ Private slot to handle the Restore Missing context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getMissingItems()] if not names: E5MessageBox.information( self, self.tr("Revert"), self.tr("""There are no missing entries""" """ available/selected.""")) return self.vcs.vcsRevert(names) self.on_refreshButton_clicked() self.vcs.checkVCSStatus() def __diff(self): """ Private slot to handle the Diff context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Differences"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return if self.diff is None: from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self.vcs) self.diff.show() QApplication.processEvents() self.diff.start(names) def __sbsDiff(self): """ Private slot to handle the Side-by-Side Diff context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Side-by-Side Diff"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return elif len(names) > 1: E5MessageBox.information( self, self.tr("Side-by-Side Diff"), self.tr("""Only one file with uncommitted changes""" """ must be selected.""")) return self.vcs.svnSbsDiff(names[0]) def __lock(self): """ Private slot to handle the Lock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems(self.unlockedIndicators)] if not names: E5MessageBox.information( self, self.tr("Lock"), self.tr("""There are no unlocked files""" """ available/selected.""")) return self.vcs.svnLock(names, parent=self) self.on_refreshButton_clicked() def __unlock(self): """ Private slot to handle the Unlock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems(self.lockedIndicators)] if not names: E5MessageBox.information( self, self.tr("Unlock"), self.tr("""There are no locked files""" """ available/selected.""")) return self.vcs.svnUnlock(names, parent=self) self.on_refreshButton_clicked() def __breakLock(self): """ Private slot to handle the Break Lock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems( self.stealBreakLockIndicators)] if not names: E5MessageBox.information( self, self.tr("Break Lock"), self.tr("""There are no locked files""" """ available/selected.""")) return self.vcs.svnUnlock(names, parent=self, breakIt=True) self.on_refreshButton_clicked() def __stealLock(self): """ Private slot to handle the Break Lock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems( self.stealBreakLockIndicators)] if not names: E5MessageBox.information( self, self.tr("Steal Lock"), self.tr("""There are no locked files""" """ available/selected.""")) return self.vcs.svnLock(names, parent=self, stealIt=True) self.on_refreshButton_clicked() def __addToChangelist(self): """ Private slot to add entries to a changelist. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getNonChangelistItems()] if not names: E5MessageBox.information( self, self.tr("Remove from Changelist"), self.tr( """There are no files available/selected not """ """belonging to a changelist.""" ) ) return self.vcs.svnAddToChangelist(names) self.on_refreshButton_clicked() def __removeFromChangelist(self): """ Private slot to remove entries from their changelists. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getChangelistItems()] if not names: E5MessageBox.information( self, self.tr("Remove from Changelist"), self.tr( """There are no files available/selected belonging""" """ to a changelist.""" ) ) return self.vcs.svnRemoveFromChangelist(names) self.on_refreshButton_clicked() def __getCommitableItems(self): """ Private method to retrieve all entries the user wants to commit. @return list of all items, the user has checked """ commitableItems = [] for index in range(self.statusList.topLevelItemCount()): itm = self.statusList.topLevelItem(index) if itm.checkState(self.__toBeCommittedColumn) == Qt.Checked: commitableItems.append(itm) return commitableItems def __getModifiedItems(self): """ Private method to retrieve all entries, that have a modified status. @return list of all items with a modified status """ modifiedItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.modifiedIndicators or \ itm.text(self.__propStatusColumn) in self.modifiedIndicators: modifiedItems.append(itm) return modifiedItems def __getUnversionedItems(self): """ Private method to retrieve all entries, that have an unversioned status. @return list of all items with an unversioned status """ unversionedItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.unversionedIndicators: unversionedItems.append(itm) return unversionedItems def __getMissingItems(self): """ Private method to retrieve all entries, that have a missing status. @return list of all items with a missing status """ missingItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.missingIndicators: missingItems.append(itm) return missingItems def __getLockActionItems(self, indicators): """ Private method to retrieve all emtries, that have a locked status. @param indicators list of indicators to check against (list of strings) @return list of all items with a locked status """ lockitems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__lockinfoColumn) in indicators: lockitems.append(itm) return lockitems def __getChangelistItems(self): """ Private method to retrieve all entries, that are members of a changelist. @return list of all items belonging to a changelist """ clitems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__changelistColumn) != "": clitems.append(itm) return clitems def __getNonChangelistItems(self): """ Private method to retrieve all entries, that are not members of a changelist. @return list of all items not belonging to a changelist """ clitems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__changelistColumn) == "": clitems.append(itm) return clitems def __commitSelect(self, selected): """ Private slot to select or deselect all entries. @param selected commit selection state to be set (boolean) """ for index in range(self.statusList.topLevelItemCount()): itm = self.statusList.topLevelItem(index) if itm.flags() & Qt.ItemIsUserCheckable: if selected: itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setCheckState(self.__toBeCommittedColumn, Qt.Unchecked) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnBlameDialog.py0000644000175000017500000002032412537064321024243 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn blame command. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QTimer, QProcess, Qt, pyqtSlot from PyQt5.QtWidgets import QHeaderView, QLineEdit, QDialog, \ QDialogButtonBox, QTreeWidgetItem from E5Gui import E5MessageBox from .Ui_SvnBlameDialog import Ui_SvnBlameDialog import Preferences class SvnBlameDialog(QDialog, Ui_SvnBlameDialog): """ Class implementing a dialog to show the output of the svn blame command. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnBlameDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = QProcess() self.vcs = vcs self.blameList.headerItem().setText(self.blameList.columnCount(), "") font = Preferences.getEditorOtherFonts("MonospacedFont") self.blameList.setFont(font) self.__ioEncoding = Preferences.getSystem("IOEncoding") self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, fn): """ Public slot to start the svn status command. @param fn filename to show the log for (string) """ self.errorGroup.hide() self.intercept = False self.activateWindow() self.lineno = 1 dname, fname = self.vcs.splitPath(fn) self.process.kill() args = [] args.append('blame') self.vcs.addArguments(args, self.vcs.options['global']) args.append(fname) self.process.setWorkingDirectory(dname) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.process = None self.__resizeColumns() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __resizeColumns(self): """ Private method to resize the list columns. """ self.blameList.header().resizeSections(QHeaderView.ResizeToContents) def __generateItem(self, revision, author, text): """ Private method to generate a blame item in the blame list. @param revision revision string (string) @param author author of the change (string) @param text line of text from the annotated file (string) """ itm = QTreeWidgetItem( self.blameList, [revision, author, "{0:d}".format(self.lineno), text]) self.lineno += 1 itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(2, Qt.AlignRight) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.__ioEncoding, 'replace')\ .strip() rev, s = s.split(None, 1) try: author, text = s.split(' ', 1) except ValueError: author = s.strip() text = "" self.__generateItem(rev, author, text) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnBlameDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnUrlSelectionDialog.py0000644000175000017500000001312512451233371025632 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the URLs for the svn diff command. """ from __future__ import unicode_literals from PyQt5.QtCore import QRegExp, pyqtSlot from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .Ui_SvnUrlSelectionDialog import Ui_SvnUrlSelectionDialog import Utilities class SvnUrlSelectionDialog(QDialog, Ui_SvnUrlSelectionDialog): """ Class implementing a dialog to enter the URLs for the svn diff command. """ def __init__(self, vcs, tagsList, branchesList, path, parent=None): """ Constructor @param vcs reference to the vcs object @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param path pathname to determine the repository URL from (string) @param parent parent widget of the dialog (QWidget) """ super(SvnUrlSelectionDialog, self).__init__(parent) self.setupUi(self) if vcs.version < (1, 4, 0): self.summaryCheckBox.setEnabled(False) self.summaryCheckBox.setChecked(False) self.vcs = vcs self.tagsList = tagsList self.branchesList = branchesList self.typeCombo1.addItems(["trunk/", "tags/", "branches/"]) self.typeCombo2.addItems(["trunk/", "tags/", "branches/"]) reposURL = self.vcs.svnGetReposName(path) if reposURL is None: E5MessageBox.critical( self, self.tr("Subversion Error"), self.tr( """The URL of the project repository could not be""" """ retrieved from the working copy. The operation will""" """ be aborted""")) self.reject() return if self.vcs.otherData["standardLayout"]: # determine the base path of the project in the repository rx_base = QRegExp('(.+/)(trunk|tags|branches).*') if not rx_base.exactMatch(reposURL): E5MessageBox.critical( self, self.tr("Subversion Error"), self.tr( """The URL of the project repository has an""" """ invalid format. The list operation will""" """ be aborted""")) self.reject() return reposRoot = rx_base.cap(1) self.repoRootLabel1.setText(reposRoot) self.repoRootLabel2.setText(reposRoot) else: project = e5App().getObject('Project') if Utilities.normcasepath(path) != \ Utilities.normcasepath(project.getProjectPath()): path = project.getRelativePath(path) reposURL = reposURL.replace(path, '') self.repoRootLabel1.hide() self.typeCombo1.hide() self.labelCombo1.addItems([reposURL] + sorted(self.vcs.tagsList)) self.labelCombo1.setEnabled(True) self.repoRootLabel2.hide() self.typeCombo2.hide() self.labelCombo2.addItems([reposURL] + sorted(self.vcs.tagsList)) self.labelCombo2.setEnabled(True) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __changeLabelCombo(self, labelCombo, type_): """ Private method used to change the label combo depending on the selected type. @param labelCombo reference to the labelCombo object (QComboBox) @param type_ type string (string) """ if type_ == "trunk/": labelCombo.clear() labelCombo.setEditText("") labelCombo.setEnabled(False) elif type_ == "tags/": labelCombo.clear() labelCombo.clearEditText() labelCombo.addItems(sorted(self.tagsList)) labelCombo.setEnabled(True) elif type_ == "branches/": labelCombo.clear() labelCombo.clearEditText() labelCombo.addItems(sorted(self.branchesList)) labelCombo.setEnabled(True) @pyqtSlot(str) def on_typeCombo1_currentIndexChanged(self, type_): """ Private slot called when the selected type was changed. @param type_ selected type (string) """ self.__changeLabelCombo(self.labelCombo1, type_) @pyqtSlot(str) def on_typeCombo2_currentIndexChanged(self, type_): """ Private slot called when the selected type was changed. @param type_ selected type (string) """ self.__changeLabelCombo(self.labelCombo2, type_) def getURLs(self): """ Public method to get the entered URLs. @return tuple of list of two URL strings (list of strings) and a flag indicating a diff summary (boolean) """ if self.vcs.otherData["standardLayout"]: url1 = self.repoRootLabel1.text() + \ self.typeCombo1.currentText() + \ self.labelCombo1.currentText() url2 = self.repoRootLabel2.text() + \ self.typeCombo2.currentText() + \ self.labelCombo2.currentText() else: url1 = self.labelCombo1.currentText() url2 = self.labelCombo2.currentText() return [url1, url2], self.summaryCheckBox.isChecked() eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnCommandDialog.ui0000644000175000017500000001334612354033734024575 0ustar piotrpiotr SvnCommandDialog 0 0 628 141 Subversion Command Subversion Command: 0 0 Enter the Subversion command to be executed with all necessary parameters <b>Subversion Command</b> <p>Enter the Subversion command to be executed including all necessary parameters. If a parameter of the commandline includes a space you have to surround this parameter by single or double quotes. Do not include the name of the subversion client executable (i.e. svn).</p> true QComboBox::InsertAtTop false 0 0 Enter the working directory for the Subversion command <b>Working directory</b> <p>Enter the working directory for the Subversion command. This is an optional entry. The button to the right will open a directory selection dialog.</p> true QComboBox::InsertAtTop false Working Directory:<br>(optional) 0 0 Project Directory: 0 0 This shows the root directory of the current project. project directory Select the working directory via a directory selection dialog <b>Working directory</b> <p>Select the working directory for the Subversion command via a directory selection dialog.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource commandCombo workdirCombo dirButton buttonBox buttonBox accepted() SvnCommandDialog accept() 41 103 49 129 buttonBox rejected() SvnCommandDialog reject() 173 109 174 128 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnTagDialog.ui0000644000175000017500000001171112354034031023713 0ustar piotrpiotr SvnTagDialog 0 0 391 216 Subversion Tag true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok 0 0 Enter the name of the tag <b>Tag Name</b> <p>Enter the name of the tag to be created, moved or deleted.</p> true false Name: Tag Action Select to create a regular tag <b>Create Regular Tag</b> <p>Select this entry in order to create a regular tag in the repository.</p> Create Regular Tag true Select to create a branch tag <b>Create Branch Tag</b> <p>Select this entry in order to create a branch in the repository.</p> Create Branch Tag Select to delete a regular tag <b>Delete Regular Tag</b> <p>Select this entry in order to delete the selected regular tag.</p> Delete Regular Tag Select to delete a branch tag <b>Delete Branch Tag</b> <p>Select this entry in order to delete the selected branch tag.</p> Delete Branch Tag qPixmapFromMimeSource tagCombo createRegularButton createBranchButton deleteRegularButton deleteBranchButton buttonBox accepted() SvnTagDialog accept() 85 192 25 214 buttonBox rejected() SvnTagDialog reject() 122 193 128 210 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnLogBrowserDialog.ui0000644000175000017500000002631012300444743025274 0ustar piotrpiotr SvnLogBrowserDialog 0 0 700 800 Subversion Log From: Enter the start date true To: Enter the end date true Select the field to filter on Revision Author Message Enter the regular expression to filter on 0 5 true QAbstractItemView::ExtendedSelection false false true true Revision Author Date Message 0 2 true 0 3 true false false true true Action Path Copy from Copy from Rev Press to get the next bunch of log entries &Next Enter the limit of entries to fetch Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 10000 20 Select to stop listing log messages at a copy or move Stop on Copy/Move Qt::Vertical Press to generate a diff to the previous revision &Diff to Previous Press to compare two revisions &Compare Revisions Qt::Horizontal 39 26 Select to show differences side-by-side Show differences side-by-side 0 1 Errors <b>Subversion log errors</b><p>This shows possible error messages of the svn log command.</p> true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
fromDate toDate fieldCombo rxEdit logTree messageEdit filesTree nextButton limitSpinBox stopCheckBox diffPreviousButton diffRevisionsButton sbsCheckBox errors input passwordCheckBox sendButton buttonBox
eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnSwitchDialog.py0000644000175000017500000000336112451233371024464 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a switch operation. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_SvnSwitchDialog import Ui_SvnSwitchDialog class SvnSwitchDialog(QDialog, Ui_SvnSwitchDialog): """ Class implementing a dialog to enter the data for a switch operation. """ def __init__(self, taglist, reposURL, standardLayout, parent=None): """ Constructor @param taglist list of previously entered tags (list of strings) @param reposURL repository path (string) or None @param standardLayout flag indicating the layout of the repository (boolean) @param parent parent widget (QWidget) """ super(SvnSwitchDialog, self).__init__(parent) self.setupUi(self) self.tagCombo.clear() self.tagCombo.addItems(sorted(taglist)) if reposURL is not None and reposURL != "": self.tagCombo.setEditText(reposURL) if not standardLayout: self.TagTypeGroup.setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getParameters(self): """ Public method to retrieve the tag data. @return tuple of string and int (tag, tag type) """ tag = self.tagCombo.currentText() tagType = 0 if self.regularButton.isChecked(): tagType = 1 elif self.branchButton.isChecked(): tagType = 2 if not tag: tagType = 4 return (tag, tagType) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/Config.py0000644000175000017500000002067712451233371022632 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module defining configuration variables for the subversion package. """ from __future__ import unicode_literals # Available protocols for the repository URL ConfigSvnProtocols = [ 'file://', 'http://', 'https://', 'svn://', 'svn+ssh://', ] DefaultConfig = "\n".join([ "### This file configures various client-side behaviors.", "###", "### The commented-out examples below are intended to demonstrate", "### how to use this file.", "", "### Section for authentication and authorization customizations.", "[auth]", "### Set password stores used by Subversion. They should be", "### delimited by spaces or commas. The order of values determines", "### the order in which password stores are used.", "### Valid password stores:", "### gnome-keyring (Unix-like systems)", "### kwallet (Unix-like systems)", "### keychain (Mac OS X)", "### windows-cryptoapi (Windows)", "# password-stores = keychain", "# password-stores = windows-cryptoapi", "# password-stores = gnome-keyring,kwallet", "### To disable all password stores, use an empty list:", "# password-stores =", "###", "### Set KWallet wallet used by Subversion. If empty or unset,", "### then the default network wallet will be used.", "# kwallet-wallet =", "###", "### Include PID (Process ID) in Subversion application name when", "### using KWallet. It defaults to 'no'.", "# kwallet-svn-application-name-with-pid = yes", "###", "### The rest of the [auth] section in this file has been deprecated.", "### Both 'store-passwords' and 'store-auth-creds' can now be", "### specified in the 'servers' file in your config directory", "### and are documented there. Anything specified in this section ", "### is overridden by settings specified in the 'servers' file.", "# store-passwords = no", "# store-auth-creds = no", "", "### Section for configuring external helper applications.", "[helpers]", "### Set editor-cmd to the command used to invoke your text editor.", "### This will override the environment variables that Subversion", "### examines by default to find this information ($EDITOR, ", "### et al).", "# editor-cmd = editor (vi, emacs, notepad, etc.)", "### Set diff-cmd to the absolute path of your 'diff' program.", "### This will override the compile-time default, which is to use", "### Subversion's internal diff implementation.", "# diff-cmd = diff_program (diff, gdiff, etc.)", "### Diff-extensions are arguments passed to an external diff", "### program or to Subversion's internal diff implementation.", "### Set diff-extensions to override the default arguments ('-u').", "# diff-extensions = -u -p", "### Set diff3-cmd to the absolute path of your 'diff3' program.", "### This will override the compile-time default, which is to use", "### Subversion's internal diff3 implementation.", "# diff3-cmd = diff3_program (diff3, gdiff3, etc.)", "### Set diff3-has-program-arg to 'yes' if your 'diff3' program", "### accepts the '--diff-program' option.", "# diff3-has-program-arg = [yes | no]", "### Set merge-tool-cmd to the command used to invoke your external", "### merging tool of choice. Subversion will pass 5 arguments to", "### the specified command: base theirs mine merged wcfile", "# merge-tool-cmd = merge_command", "", "### Section for configuring tunnel agents.", "[tunnels]", "### Configure svn protocol tunnel schemes here. By default, only", "### the 'ssh' scheme is defined. You can define other schemes to", "### be used with 'svn+scheme://hostname/path' URLs. A scheme", "### definition is simply a command, optionally prefixed by an", "### environment variable name which can override the command if it", "### is defined. The command (or environment variable) may contain", "### arguments, using standard shell quoting for arguments with", "### spaces. The command will be invoked as:", "### svnserve -t", "### (If the URL includes a username, then the hostname will be", "### passed to the tunnel agent as @.) If the", "### built-in ssh scheme were not predefined, it could be defined", "### as:", "# ssh = $SVN_SSH ssh -q", "### If you wanted to define a new 'rsh' scheme, to be used with", "### 'svn+rsh:' URLs, you could do so as follows:", "# rsh = rsh", "### Or, if you wanted to specify a full path and arguments:", "# rsh = /path/to/rsh -l myusername", "### On Windows, if you are specifying a full path to a command,", "### use a forward slash (/) or a paired backslash (\\\\) as the", "### path separator. A single backslash will be treated as an", "### escape for the following character.", "", "### Section for configuring miscelleneous Subversion options.", "[miscellany]", "### Set global-ignores to a set of whitespace-delimited globs", "### which Subversion will ignore in its 'status' output, and", "### while importing or adding files and directories.", "### '*' matches leading dots, e.g. '*.rej' matches '.foo.rej'.", "global-ignores = *.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc", " *.pyo .*.rej *.rej .*~ *~ #*# .#* .*.swp .DS_Store", " *.orig *.bak cur tmp __pycache__ .directory", " .ropeproject .eric4project .eric5project .eric6project", " _ropeproject _eric4project _eric5project _eric5project", "### Set log-encoding to the default encoding for log messages", "# log-encoding = latin1", "### Set use-commit-times to make checkout/update/switch/revert", "### put last-committed timestamps on every file touched.", "# use-commit-times = yes", "### Set no-unlock to prevent 'svn commit' from automatically", "### releasing locks on files.", "# no-unlock = yes", "### Set mime-types-file to a MIME type registry file, used to", "### provide hints to Subversion's MIME type auto-detection", "### algorithm.", "# mime-types-file = /path/to/mime.types", "### Set preserved-conflict-file-exts to a whitespace-delimited", "### list of patterns matching file extensions which should be", "### preserved in generated conflict file names. By default,", "### conflict files use custom extensions.", "# preserved-conflict-file-exts = doc ppt xls od?", "### Set enable-auto-props to 'yes' to enable automatic properties", "### for 'svn add' and 'svn import', it defaults to 'no'.", "### Automatic properties are defined in the section 'auto-props'.", "# enable-auto-props = yes", "### Set interactive-conflicts to 'no' to disable interactive", "### conflict resolution prompting. It defaults to 'yes'.", "# interactive-conflicts = no", "### Set memory-cache-size to define the size of the memory cache", "### used by the client when accessing a FSFS repository via", "### ra_local (the file:// scheme). The value represents the number", "### of MB used by the cache.", "# memory-cache-size = 16", "", "### Section for configuring automatic properties.", "[auto-props]", "### The format of the entries is:", "### file-name-pattern = propname[=value][;propname[=value]...]", "### The file-name-pattern can contain wildcards (such as '*' and", "### '?'). All entries which match (case-insensitively) will be", "### applied to the file. Note that auto-props functionality", "### must be enabled, which is typically done by setting the", "### 'enable-auto-props' option.", "# *.c = svn:eol-style=native", "# *.cpp = svn:eol-style=native", "# *.h = svn:keywords=Author Date Id Rev URL;svn:eol-style=native", "# *.dsp = svn:eol-style=CRLF", "# *.dsw = svn:eol-style=CRLF", "# *.sh = svn:eol-style=native;svn:executable", "# *.txt = svn:eol-style=native;svn:keywords=Author Date Id Rev URL;", "# *.png = svn:mime-type=image/png", "# *.jpg = svn:mime-type=image/jpeg", "# Makefile = svn:eol-style=native", "", ]) DefaultIgnores = [ "*.orig", "*.bak", "cur", "tmp", "__pycache__", ".directory", ".ropeproject", ".eric4project", ".eric5project", ".eric6project", "_ropeproject", "_eric4project", "_eric5project", "_eric6project", ] eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnRevisionSelectionDialog.ui0000644000175000017500000003213312203730423026646 0ustar piotrpiotr SvnRevisionSelectionDialog 0 0 399 519 Subversion Diff true Revision &1 Select revision before last commit PREV Select last committed revision COMMITTED Select base revision BASE Select head revision of repository HEAD true Select working revision WORKING false false 0 0 Enter a revision number Qt::AlignRight 1 999999999 false Enter time of revision false Enter date of revision yyyy-MM-dd true Qt::Horizontal 40 20 Select to specify a revision by number Number Select to specify a revision by date and time Date Revision &2 Select revision before last commit PREV Select last committed revision COMMITTED Select base revision BASE Select head revision of repository HEAD false Select working revision WORKING true false 0 0 Enter a revision number Qt::AlignRight 1 999999999 false Enter time of revision false Enter date of revision yyyy-MM-dd true Qt::Horizontal 40 20 Select to specify a revision by number Number Select to specify a revision by date and time Date Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource number1Button number1SpinBox date1Button date1Edit time1Edit head1Button working1Button base1Button committed1Button prev1Button number2Button number2SpinBox date2Button date2Edit time2Edit head2Button working2Button base2Button committed2Button prev2Button buttonBox buttonBox accepted() SvnRevisionSelectionDialog accept() 27 512 21 143 buttonBox rejected() SvnRevisionSelectionDialog reject() 79 512 73 140 number1Button toggled(bool) number1SpinBox setEnabled(bool) 62 45 148 43 date1Button toggled(bool) date1Edit setEnabled(bool) 70 77 136 74 date1Button toggled(bool) time1Edit setEnabled(bool) 16 74 257 74 number2Button toggled(bool) number2SpinBox setEnabled(bool) 32 281 128 283 date2Button toggled(bool) date2Edit setEnabled(bool) 49 310 134 310 date2Button toggled(bool) time2Edit setEnabled(bool) 55 322 264 320 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnCommitDialog.ui0000644000175000017500000000576212060166053024445 0ustar piotrpiotr SvnCommitDialog 0 0 450 384 Subversion Commit Message Enter the log message. <b>Log Message</b> <p>Enter the log message for the commit action.</p> true false Recent commit messages Select a recent commit message to use Changelists Select the change lists to limit the commit Select to keep the changelists Keep changelists Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok qPixmapFromMimeSource logEdit recentComboBox changeLists keepChangeListsCheckBox buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnRelocateDialog.ui0000644000175000017500000000566612060166053024756 0ustar piotrpiotr SvnRelocateDialog 0 0 531 119 Subversion Relocate true QFrame::StyledPanel New repository URL: Enter the URL of the repository the working space should be relocated to Current repository URL: Select, if the relocate should happen inside the repository Relocate inside repository (used, if the repository layout has changed) Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok newUrlEdit insideCheckBox buttonBox buttonBox accepted() SvnRelocateDialog accept() 31 75 29 92 buttonBox rejected() SvnRelocateDialog reject() 69 74 69 95 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnNewProjectOptionsDialog.ui0000644000175000017500000001461012263304054026641 0ustar piotrpiotr SvnNewProjectOptionsDialog 0 0 562 201 New Project from Repository <b>New Project from Repository Dialog</b> <p>Enter the various repository infos into the entry fields. These values are used, when the new project is retrieved from the repository. If the checkbox is selected, the URL must end in the project name. A repository layout with project/tags, project/branches and project/trunk will be assumed. In this case, you may enter a tag or branch, which must look like tags/tagname or branches/branchname. If the checkbox is not selected, the URL must contain the complete path in the repository.</p> <p>For remote repositories the URL must contain the hostname.</p> true Enter the tag the new project should be generated from <b>Tag in VCS</b> <p>Enter the tag name the new project shall be generated from. Leave empty to retrieve the latest data from the repository.</p> Select the protocol to access the repository &Protocol: protocolCombo Enter the url path of the module in the repository (without protocol part) <b>URL</b><p>Enter the URL to the module. For a repository with standard layout, this must not contain the trunk, tags or branches part.</p> &URL: vcsUrlEdit Enter the directory of the new project. <b>Project Directory</b> <p>Enter the directory of the new project. It will be retrieved from the repository and be placed in this directory.</p> Select to indicate, that the repository has a standard layout (projectdir/trunk, projectdir/tags, projectdir/branches) Repository has standard &layout Alt+L true Project &Directory: vcsProjectDirEdit &Tag: vcsTagEdit Select the repository url via a directory selection dialog or the repository browser Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource protocolCombo vcsUrlEdit vcsUrlButton vcsTagEdit vcsProjectDirEdit projectDirButton layoutCheckBox buttonBox accepted() SvnNewProjectOptionsDialog accept() 37 176 38 198 buttonBox rejected() SvnNewProjectOptionsDialog reject() 147 177 153 197 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnMergeDialog.py0000644000175000017500000000632612451233371024266 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a merge operation. """ from __future__ import unicode_literals from PyQt5.QtCore import QRegExp from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_SvnMergeDialog import Ui_SvnMergeDialog class SvnMergeDialog(QDialog, Ui_SvnMergeDialog): """ Class implementing a dialog to enter the data for a merge operation. """ def __init__(self, mergelist1, mergelist2, targetlist, force=False, parent=None): """ Constructor @param mergelist1 list of previously entered URLs/revisions (list of strings) @param mergelist2 list of previously entered URLs/revisions (list of strings) @param targetlist list of previously entered targets (list of strings) @param force flag indicating a forced merge (boolean) @param parent parent widget (QWidget) """ super(SvnMergeDialog, self).__init__(parent) self.setupUi(self) self.forceCheckBox.setChecked(force) self.rx_url = QRegExp('(?:file:|svn:|svn+ssh:|http:|https:)//.+') self.rx_rev = QRegExp('\\d+') self.tag1Combo.clear() self.tag1Combo.addItems(mergelist1) self.tag2Combo.clear() self.tag2Combo.addItems(mergelist2) self.targetCombo.clear() self.targetCombo.addItems(targetlist) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __enableOkButton(self): """ Private method used to enable/disable the OK-button. """ self.okButton.setDisabled( self.tag1Combo.currentText() != "" or self.tag2Combo.currentText() != "" or not ((self.rx_url.exactMatch(self.tag1Combo.currentText()) and self.rx_url.exactMatch(self.tag2Combo.currentText())) or (self.rx_rev.exactMatch(self.tag1Combo.currentText()) and self.rx_rev.exactMatch(self.tag2Combo.currentText())) ) ) def on_tag1Combo_editTextChanged(self, text): """ Private slot to handle the tag1Combo editTextChanged signal. @param text text of the combo (string) """ self.__enableOkButton() def on_tag2Combo_editTextChanged(self, text): """ Private slot to handle the tag2Combo editTextChanged signal. @param text text of the combo (string) """ self.__enableOkButton() def getParameters(self): """ Public method to retrieve the merge data. @return tuple naming two tag names or two revisions, a target and a flag indicating a forced merge (string, string, string, boolean) """ return (self.tag1Combo.currentText(), self.tag2Combo.currentText(), self.targetCombo.currentText(), self.forceCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnRevisionSelectionDialog.py0000644000175000017500000000571712451233371026676 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the revisions for the svn diff command. """ from __future__ import unicode_literals from PyQt5.QtCore import QDate, QDateTime, Qt from PyQt5.QtWidgets import QDialog from .Ui_SvnRevisionSelectionDialog import Ui_SvnRevisionSelectionDialog class SvnRevisionSelectionDialog(QDialog, Ui_SvnRevisionSelectionDialog): """ Class implementing a dialog to enter the revisions for the svn diff command. """ def __init__(self, parent=None): """ Constructor @param parent parent widget of the dialog (QWidget) """ super(SvnRevisionSelectionDialog, self).__init__(parent) self.setupUi(self) self.date1Edit.setDate(QDate.currentDate()) self.date2Edit.setDate(QDate.currentDate()) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __getRevision(self, no): """ Private method to generate the revision. @param no revision number to generate (1 or 2) @return revision (integer or string) """ if no == 1: numberButton = self.number1Button numberSpinBox = self.number1SpinBox dateButton = self.date1Button dateEdit = self.date1Edit timeEdit = self.time1Edit headButton = self.head1Button workingButton = self.working1Button baseButton = self.base1Button committedButton = self.committed1Button prevButton = self.prev1Button else: numberButton = self.number2Button numberSpinBox = self.number2SpinBox dateButton = self.date2Button dateEdit = self.date2Edit timeEdit = self.time2Edit headButton = self.head2Button workingButton = self.working2Button baseButton = self.base2Button committedButton = self.committed2Button prevButton = self.prev2Button if numberButton.isChecked(): return numberSpinBox.value() elif dateButton.isChecked(): return "{{{0}}}".format( QDateTime(dateEdit.date(), timeEdit.time()) .toString(Qt.ISODate)) elif headButton.isChecked(): return "HEAD" elif workingButton.isChecked(): return "WORKING" elif baseButton.isChecked(): return "BASE" elif committedButton.isChecked(): return "COMMITTED" elif prevButton.isChecked(): return "PREV" def getRevisions(self): """ Public method to get the revisions. @return list two integers or strings """ rev1 = self.__getRevision(1) rev2 = self.__getRevision(2) return [rev1, rev2] eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnStatusDialog.ui0000644000175000017500000002242312203730423024466 0ustar piotrpiotr SvnStatusDialog 0 0 955 646 Subversion Status <b>Subversion Status</b> <p>This dialog shows the status of the selected file or project.</p> Qt::Horizontal 40 20 &Filter on Status: statusFilterCombo Select the status of entries to be shown QComboBox::AdjustToContents 0 3 true QAbstractItemView::ExtendedSelection false true Commit Changelist Status Prop. Status Locked History Switched Lock Info Up to date Revision Last Change Author Path Commit the selected changes &Commit Qt::Vertical Add the selected entries to the repository &Add Show differences of the selected entries to the repository &Differences Show differences of the selected entry to the repository in a side-by-side manner Side-b&y-Side Diff Revert the selected entries to the last revision in the repository Re&vert Restore the selected missing entries from the repository &Restore Qt::Horizontal 40 20 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource statusFilterCombo statusList commitButton addButton diffButton sbsDiffButton revertButton restoreButton errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnCommitDialog.py0000644000175000017500000000771012451233371024455 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the commit message. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot from PyQt5.QtWidgets import QWidget, QDialogButtonBox from .Ui_SvnCommitDialog import Ui_SvnCommitDialog import Preferences class SvnCommitDialog(QWidget, Ui_SvnCommitDialog): """ Class implementing a dialog to enter the commit message. @signal accepted() emitted, if the dialog was accepted @signal rejected() emitted, if the dialog was rejected """ accepted = pyqtSignal() rejected = pyqtSignal() def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnCommitDialog, self).__init__( parent, Qt.WindowFlags(Qt.Window)) self.setupUi(self) if vcs.version < (1, 5, 0): self.changeListsGroup.hide() else: self.changeLists.addItems(sorted(vcs.svnGetChangelists())) def showEvent(self, evt): """ Protected method called when the dialog is about to be shown. @param evt the event (QShowEvent) """ self.recentCommitMessages = Preferences.toList( Preferences.Prefs.settings.value('Subversion/Commits')) self.recentComboBox.clear() self.recentComboBox.addItem("") self.recentComboBox.addItems(self.recentCommitMessages) def logMessage(self): """ Public method to retrieve the log message. @return the log message (string) """ msg = self.logEdit.toPlainText() if msg: if msg in self.recentCommitMessages: self.recentCommitMessages.remove(msg) self.recentCommitMessages.insert(0, msg) no = int(Preferences.Prefs.settings .value('Subversion/CommitMessages', 20)) del self.recentCommitMessages[no:] Preferences.Prefs.settings.setValue( 'Subversion/Commits', self.recentCommitMessages) return msg def hasChangelists(self): """ Public method to check, if the user entered some changelists. @return flag indicating availability of changelists (boolean) """ return len(self.changeLists.selectedItems()) > 0 def changelistsData(self): """ Public method to retrieve the changelists data. @return tuple containing the changelists (list of strings) and a flag indicating to keep changelists (boolean) """ slists = [l.text().strip() for l in self.changeLists.selectedItems() if l.text().strip() != ""] if len(slists) == 0: return [], False return slists, self.keepChangeListsCheckBox.isChecked() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Cancel): self.logEdit.clear() def on_buttonBox_accepted(self): """ Private slot called by the buttonBox accepted signal. """ self.close() self.accepted.emit() def on_buttonBox_rejected(self): """ Private slot called by the buttonBox rejected signal. """ self.close() self.rejected.emit() @pyqtSlot(str) def on_recentComboBox_activated(self, txt): """ Private slot to select a commit message from recent ones. @param txt text of the combo (string) """ if txt: self.logEdit.setPlainText(txt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnUrlSelectionDialog.ui0000644000175000017500000000767212060166053025627 0ustar piotrpiotr SvnUrlSelectionDialog 0 0 542 195 Subversion Diff true Repository URL 1 Select the URL type 0 0 Enter the label name or path true Repository URL 2 Select the URL type 0 0 Enter the label name or path true Select to just show a summary of differences Summary only Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok typeCombo1 labelCombo1 typeCombo2 labelCombo2 summaryCheckBox buttonBox buttonBox accepted() SvnUrlSelectionDialog accept() 230 188 157 178 buttonBox rejected() SvnUrlSelectionDialog reject() 292 166 286 178 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnRelocateDialog.py0000644000175000017500000000240412451233371024756 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c)2015 Detlev Offenbach # """ Module implementing a dialog to enter the data to relocate the workspace. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_SvnRelocateDialog import Ui_SvnRelocateDialog class SvnRelocateDialog(QDialog, Ui_SvnRelocateDialog): """ Class implementing a dialog to enter the data to relocate the workspace. """ def __init__(self, currUrl, parent=None): """ Constructor @param currUrl current repository URL (string) @param parent parent widget (QWidget) """ super(SvnRelocateDialog, self).__init__(parent) self.setupUi(self) self.currUrlLabel.setText(currUrl) self.newUrlEdit.setText(currUrl) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public slot used to retrieve the data entered into the dialog. @return the new repository URL (string) and an indication, if the relocate is inside the repository (boolean) """ return self.newUrlEdit.text(), self.insideCheckBox.isChecked() eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnPropListDialog.py0000644000175000017500000001734012451233371025001 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn proplist command process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import QTimer, QProcess, QProcessEnvironment, QRegExp, Qt from PyQt5.QtWidgets import QWidget, QHeaderView, QDialogButtonBox, \ QTreeWidgetItem from E5Gui import E5MessageBox from .Ui_SvnPropListDialog import Ui_SvnPropListDialog import Preferences class SvnPropListDialog(QWidget, Ui_SvnPropListDialog): """ Class implementing a dialog to show the output of the svn proplist command process. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnPropListDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = QProcess() env = QProcessEnvironment.systemEnvironment() env.insert("LANG", "C") self.process.setProcessEnvironment(env) self.vcs = vcs self.propsList.headerItem().setText(self.propsList.columnCount(), "") self.propsList.header().setSortIndicator(0, Qt.AscendingOrder) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.rx_path = QRegExp(r"Properties on '([^']+)':\s*") self.rx_prop = QRegExp(r" (.*) *: *(.*)[\r\n]") self.lastPath = None self.lastProp = None self.propBuffer = "" def __resort(self): """ Private method to resort the tree. """ self.propsList.sortItems( self.propsList.sortColumn(), self.propsList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.propsList.header().resizeSections(QHeaderView.ResizeToContents) self.propsList.header().setStretchLastSection(True) def __generateItem(self, path, propName, propValue): """ Private method to generate a properties item in the properties list. @param path file/directory name the property applies to (string) @param propName name of the property (string) @param propValue value of the property (string) """ QTreeWidgetItem(self.propsList, [path, propName, propValue.strip()]) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, fn, recursive=False): """ Public slot to start the svn status command. @param fn filename(s) (string or list of string) @param recursive flag indicating a recursive list is requested """ self.errorGroup.hide() self.process.kill() args = [] args.append('proplist') self.vcs.addArguments(args, self.vcs.options['global']) args.append('--verbose') if recursive: args.append('--recursive') if isinstance(fn, list): dname, fnames = self.vcs.splitPathList(fn) self.vcs.addArguments(args, fnames) else: dname, fname = self.vcs.splitPath(fn) args.append(fname) self.process.setWorkingDirectory(dname) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.process = None if self.lastProp: self.__generateItem(self.lastPath, self.lastProp, self.propBuffer) self.__resort() self.__resizeColumns() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ if self.lastPath is None: self.__generateItem('', 'None', '') self.__finish() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') if self.rx_path.exactMatch(s): if self.lastProp: self.__generateItem( self.lastPath, self.lastProp, self.propBuffer) self.lastPath = self.rx_path.cap(1) self.lastProp = None self.propBuffer = "" elif self.rx_prop.exactMatch(s): if self.lastProp: self.__generateItem( self.lastPath, self.lastProp, self.propBuffer) self.lastProp = self.rx_prop.cap(1) self.propBuffer = self.rx_prop.cap(2) else: self.propBuffer += ' ' self.propBuffer += s def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/0000755000175000017500000000000012557365404024455 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.py0000644000175000017500000000365312451233371027760 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Subversion configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from Preferences.ConfigurationPages.ConfigurationPageBase import \ ConfigurationPageBase from .Ui_SubversionPage import Ui_SubversionPage class SubversionPage(ConfigurationPageBase, Ui_SubversionPage): """ Class implementing the Subversion configuration page. """ def __init__(self, plugin): """ Constructor @param plugin reference to the plugin object """ super(SubversionPage, self).__init__() self.setupUi(self) self.setObjectName("SubversionPage") self.__plugin = plugin # set initial values self.logSpinBox.setValue(self.__plugin.getPreferences("LogLimit")) self.commitSpinBox.setValue( self.__plugin.getPreferences("CommitMessages")) def save(self): """ Public slot to save the Subversion configuration. """ self.__plugin.setPreferences("LogLimit", self.logSpinBox.value()) self.__plugin.setPreferences( "CommitMessages", self.commitSpinBox.value()) @pyqtSlot() def on_configButton_clicked(self): """ Private slot to edit the Subversion config file. """ from QScintilla.MiniEditor import MiniEditor cfgFile = self.__plugin.getConfigPath() editor = MiniEditor(cfgFile, "Properties", self) editor.show() @pyqtSlot() def on_serversButton_clicked(self): """ Private slot to edit the Subversion servers file. """ from QScintilla.MiniEditor import MiniEditor serversFile = self.__plugin.getServersPath() editor = MiniEditor(serversFile, "Properties", self) editor.show() eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/__init__.py0000644000175000017500000000025012451233371026551 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package implementing the the subversion configuration page. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.ui0000644000175000017500000001000612060166053027731 0ustar piotrpiotr SubversionPage 0 0 402 384 <b>Configure Subversion Interface</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Log No. of log messages shown: Enter the number of log messages to be shown Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 999999 Qt::Horizontal 41 20 Commit No. of commit messages to remember: Enter the number of commit messages to remember Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 100 Qt::Horizontal 40 20 Edit the subversion config file Edit config file Edit the subversion servers file Edit servers file Qt::Vertical 388 21 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnCopyDialog.ui0000644000175000017500000000733012263303755024127 0ustar piotrpiotr SvnCopyDialog 0 0 409 138 Subversion Copy true Source: Shows the name of the source <b>Source name</b> <p>This field shows the name of the source.</p> true Enter the target name <b>Target name</b> <p>Enter the new name in this field. The target must be the new name or an absolute path.</p> Target: Press to open a selection dialog <b>Target directory</b> <p>Select the target name for the operation via a selection dialog.</p> Select to force the operation Enforce operation Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource targetEdit dirButton forceCheckBox buttonBox sourceEdit buttonBox accepted() SvnCopyDialog accept() 32 79 32 97 buttonBox rejected() SvnCopyDialog reject() 101 80 101 97 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnPropListDialog.ui0000644000175000017500000000567412060166053024773 0ustar piotrpiotr SvnPropListDialog 0 0 826 569 Subversion List Properties <b>Subversion List Prperties</b> <p>This dialog shows the properties of the selected file or project.</p> 0 3 <b>Properties List</b> <p>This shows the properties of the selected file or project.</p> true false false true Path Name Value 0 1 Errors <b>Subversion proplist errors</b> <p>This shows possible error messages of the subversion proplist command.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource propsList errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnDiffDialog.py0000644000175000017500000003744512461215125024103 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn diff command process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QTimer, QFileInfo, QProcess, pyqtSlot, Qt from PyQt5.QtGui import QColor, QBrush, QTextCursor from PyQt5.QtWidgets import QWidget, QLineEdit, QDialogButtonBox from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog from .Ui_SvnDiffDialog import Ui_SvnDiffDialog import Utilities import Preferences class SvnDiffDialog(QWidget, Ui_SvnDiffDialog): """ Class implementing a dialog to show the output of the svn diff command process. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnDiffDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Save).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.process = QProcess() self.vcs = vcs font = Preferences.getEditorOtherFonts("MonospacedFont") self.contents.setFontFamily(font.family()) self.contents.setFontPointSize(font.pointSize()) self.cNormalFormat = self.contents.currentCharFormat() self.cAddedFormat = self.contents.currentCharFormat() self.cAddedFormat.setBackground(QBrush(QColor(190, 237, 190))) self.cRemovedFormat = self.contents.currentCharFormat() self.cRemovedFormat.setBackground(QBrush(QColor(237, 190, 190))) self.cLineNoFormat = self.contents.currentCharFormat() self.cLineNoFormat.setBackground(QBrush(QColor(255, 220, 168))) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def __getVersionArg(self, version): """ Private method to get a svn revision argument for the given revision. @param version revision (integer or string) @return version argument (string) """ if version == "WORKING": return None else: return str(version) def start(self, fn, versions=None, urls=None, summary=False): """ Public slot to start the svn diff command. @param fn filename to be diffed (string) @param versions list of versions to be diffed (list of up to 2 strings or None) @keyparam urls list of repository URLs (list of 2 strings) @keyparam summary flag indicating a summarizing diff (only valid for URL diffs) (boolean) """ self.errorGroup.hide() self.inputGroup.show() self.intercept = False self.filename = fn self.process.kill() self.contents.clear() self.paras = 0 self.filesCombo.clear() self.__oldFile = "" self.__oldFileLine = -1 self.__fileSeparators = [] args = [] args.append('diff') self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['diff']) if '--diff-cmd' in self.vcs.options['diff']: self.buttonBox.button(QDialogButtonBox.Save).hide() if versions is not None: self.raise_() self.activateWindow() rev1 = self.__getVersionArg(versions[0]) rev2 = None if len(versions) == 2: rev2 = self.__getVersionArg(versions[1]) if rev1 is not None or rev2 is not None: args.append('-r') if rev1 is not None and rev2 is not None: args.append('{0}:{1}'.format(rev1, rev2)) elif rev2 is None: args.append(rev1) elif rev1 is None: args.append(rev2) self.summaryPath = None if urls is not None: if summary: args.append("--summarize") self.summaryPath = urls[0] args.append("--old={0}".format(urls[0])) args.append("--new={0}".format(urls[1])) if isinstance(fn, list): dname, fnames = self.vcs.splitPathList(fn) else: dname, fname = self.vcs.splitPath(fn) fnames = [fname] project = e5App().getObject('Project') if dname == project.getProjectPath(): path = "" else: path = project.getRelativePath(dname) if path: path += "/" for fname in fnames: args.append(path + fname) else: if isinstance(fn, list): dname, fnames = self.vcs.splitPathList(fn) self.vcs.addArguments(args, fnames) else: dname, fname = self.vcs.splitPath(fn) args.append(fname) self.process.setWorkingDirectory(dname) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.inputGroup.setEnabled(False) self.inputGroup.hide() if self.paras == 0: self.contents.setCurrentCharFormat(self.cNormalFormat) self.contents.setPlainText( self.tr('There is no difference.')) self.buttonBox.button(QDialogButtonBox.Save).setEnabled(self.paras > 0) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() self.filesCombo.addItem(self.tr(""), 0) self.filesCombo.addItem(self.tr(""), -1) for oldFile, newFile, pos in sorted(self.__fileSeparators): if oldFile != newFile: self.filesCombo.addItem( "{0}\n{1}".format(oldFile, newFile), pos) else: self.filesCombo.addItem(oldFile, pos) def __appendText(self, txt, format): """ Private method to append text to the end of the contents pane. @param txt text to insert (string) @param format text format to be used (QTextCharFormat) """ tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.setCurrentCharFormat(format) self.contents.insertPlainText(txt) def __extractFileName(self, line): """ Private method to extract the file name out of a file separator line. @param line line to be processed (string) @return extracted file name (string) """ f = line.split(None, 1)[1] f = f.rsplit(None, 2)[0] return f def __processFileLine(self, line): """ Private slot to process a line giving the old/new file. @param line line to be processed (string) """ if line.startswith('---'): self.__oldFileLine = self.paras self.__oldFile = self.__extractFileName(line) else: self.__fileSeparators.append( (self.__oldFile, self.__extractFileName(line), self.__oldFileLine)) def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): line = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') if self.summaryPath: line = line.replace(self.summaryPath + '/', '') line = " ".join(line.split()) if line.startswith("--- ") or line.startswith("+++ "): self.__processFileLine(line) if line.startswith('+') or line.startswith('>') or \ line.startswith('A '): format = self.cAddedFormat elif line.startswith('-') or line.startswith('<') or \ line.startswith('D '): format = self.cRemovedFormat elif line.startswith('@@'): format = self.cLineNoFormat else: format = self.cNormalFormat self.__appendText(line, format) self.paras += 1 def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Save): self.on_saveButton_clicked() @pyqtSlot(int) def on_filesCombo_activated(self, index): """ Private slot to handle the selection of a file. @param index activated row (integer) """ para = self.filesCombo.itemData(index) if para == 0: tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() elif para == -1: tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() else: # step 1: move cursor to end tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() # step 2: move cursor to desired line tc = self.contents.textCursor() delta = tc.blockNumber() - para tc.movePosition(QTextCursor.PreviousBlock, QTextCursor.MoveAnchor, delta) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() @pyqtSlot() def on_saveButton_clicked(self): """ Private slot to handle the Save button press. It saves the diff shown in the dialog to a file in the local filesystem. """ if isinstance(self.filename, list): if len(self.filename) > 1: fname = self.vcs.splitPathList(self.filename)[0] else: dname, fname = self.vcs.splitPath(self.filename[0]) if fname != '.': fname = "{0}.diff".format(self.filename[0]) else: fname = dname else: fname = self.vcs.splitPath(self.filename)[0] fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Diff"), fname, self.tr("Patch Files (*.diff)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fname: return # user aborted ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Diff"), self.tr("

The patch file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) eol = e5App().getObject("Project").getEolString() try: f = open(fname, "w", encoding="utf-8", newline="") f.write(eol.join(self.contents.toPlainText().splitlines())) f.close() except IOError as why: E5MessageBox.critical( self, self.tr('Save Diff'), self.tr( '

The patch file {0} could not be saved.' '
Reason: {1}

') .format(fname, str(why))) def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnDiffDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.py0000644000175000017500000003771212537064321025505 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the subversion repository browser dialog. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QHeaderView, QLineEdit, QDialog, QApplication, \ QDialogButtonBox, QTreeWidgetItem from PyQt5.QtCore import QTimer, QProcess, QRegExp, Qt, pyqtSlot from E5Gui import E5MessageBox from .Ui_SvnRepoBrowserDialog import Ui_SvnRepoBrowserDialog import UI.PixmapCache import Preferences class SvnRepoBrowserDialog(QDialog, Ui_SvnRepoBrowserDialog): """ Class implementing the subversion repository browser dialog. """ def __init__(self, vcs, mode="browse", parent=None): """ Constructor @param vcs reference to the vcs object @param mode mode of the dialog (string, "browse" or "select") @param parent parent widget (QWidget) """ super(SvnRepoBrowserDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.repoTree.headerItem().setText(self.repoTree.columnCount(), "") self.repoTree.header().setSortIndicator(0, Qt.AscendingOrder) self.process = None self.vcs = vcs self.mode = mode if self.mode == "select": self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).hide() else: self.buttonBox.button(QDialogButtonBox.Ok).hide() self.buttonBox.button(QDialogButtonBox.Cancel).hide() self.__dirIcon = UI.PixmapCache.getIcon("dirClosed.png") self.__fileIcon = UI.PixmapCache.getIcon("fileMisc.png") self.__urlRole = Qt.UserRole self.__ignoreExpand = False self.intercept = False self.__rx_dir = QRegExp( r"""\s*([0-9]+)\s+(\w+)\s+""" r"""((?:\w+\s+\d+|[0-9.]+\s+\w+)\s+[0-9:]+)\s+(.+)\s*""") self.__rx_file = QRegExp( r"""\s*([0-9]+)\s+(\w+)\s+([0-9]+)\s""" r"""((?:\w+\s+\d+|[0-9.]+\s+\w+)\s+[0-9:]+)\s+(.+)\s*""") def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def __resort(self): """ Private method to resort the tree. """ self.repoTree.sortItems( self.repoTree.sortColumn(), self.repoTree.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the tree columns. """ self.repoTree.header().resizeSections(QHeaderView.ResizeToContents) self.repoTree.header().setStretchLastSection(True) def __generateItem(self, repopath, revision, author, size, date, nodekind, url): """ Private method to generate a tree item in the repository tree. @param repopath path of the item (string) @param revision revision info (string) @param author author info (string) @param size size info (string) @param date date info (string) @param nodekind node kind info (string, "dir" or "file") @param url url of the entry (string) @return reference to the generated item (QTreeWidgetItem) """ path = repopath if revision == "": rev = "" else: rev = int(revision) if size == "": sz = "" else: sz = int(size) itm = QTreeWidgetItem(self.parentItem) itm.setData(0, Qt.DisplayRole, path) itm.setData(1, Qt.DisplayRole, rev) itm.setData(2, Qt.DisplayRole, author) itm.setData(3, Qt.DisplayRole, sz) itm.setData(4, Qt.DisplayRole, date) if nodekind == "dir": itm.setIcon(0, self.__dirIcon) itm.setChildIndicatorPolicy(QTreeWidgetItem.ShowIndicator) elif nodekind == "file": itm.setIcon(0, self.__fileIcon) itm.setData(0, self.__urlRole, url) itm.setTextAlignment(0, Qt.AlignLeft) itm.setTextAlignment(1, Qt.AlignRight) itm.setTextAlignment(2, Qt.AlignLeft) itm.setTextAlignment(3, Qt.AlignRight) itm.setTextAlignment(4, Qt.AlignLeft) return itm def __repoRoot(self, url): """ Private method to get the repository root using the svn info command. @param url the repository URL to browser (string) @return repository root (string) """ ioEncoding = Preferences.getSystem("IOEncoding") repoRoot = None process = QProcess() args = [] args.append('info') self.vcs.addArguments(args, self.vcs.options['global']) args.append('--xml') args.append(url) process.start('svn', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished: if process.exitCode() == 0: output = str(process.readAllStandardOutput(), ioEncoding, 'replace') for line in output.splitlines(): line = line.strip() if line.startswith(''): repoRoot = line.replace('', '')\ .replace('', '') break else: error = str(process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(error) self.errors.ensureCursorVisible() else: QApplication.restoreOverrideCursor() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) return repoRoot def __listRepo(self, url, parent=None): """ Private method to perform the svn list command. @param url the repository URL to browse (string) @param parent reference to the item, the data should be appended to (QTreeWidget or QTreeWidgetItem) """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.repoUrl = url if parent is None: self.parentItem = self.repoTree else: self.parentItem = parent if self.parentItem == self.repoTree: repoRoot = self.__repoRoot(url) if repoRoot is None: self.__finish() return self.__ignoreExpand = True itm = self.__generateItem( repoRoot, "", "", "", "", "dir", repoRoot) itm.setExpanded(True) self.parentItem = itm urlPart = repoRoot for element in url.replace(repoRoot, "").split("/"): if element: urlPart = "{0}/{1}".format(urlPart, element) itm = self.__generateItem( element, "", "", "", "", "dir", urlPart) itm.setExpanded(True) self.parentItem = itm itm.setExpanded(False) self.__ignoreExpand = False self.__finish() return self.intercept = False if self.process: self.process.kill() else: self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) args = [] args.append('list') self.vcs.addArguments(args, self.vcs.options['global']) if '--verbose' not in self.vcs.options['global']: args.append('--verbose') args.append(url) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.__finish() self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __normalizeUrl(self, url): """ Private method to normalite the url. @param url the url to normalize (string) @return normalized URL (string) """ if url.endswith("/"): return url[:-1] return url def start(self, url): """ Public slot to start the svn info command. @param url the repository URL to browser (string) """ self.url = "" self.urlCombo.addItem(self.__normalizeUrl(url)) @pyqtSlot(str) def on_urlCombo_currentIndexChanged(self, text): """ Private slot called, when a new repository URL is entered or selected. @param text the text of the current item (string) """ url = self.__normalizeUrl(text) if url != self.url: self.url = url self.repoTree.clear() self.__listRepo(url) @pyqtSlot(QTreeWidgetItem) def on_repoTree_itemExpanded(self, item): """ Private slot called when an item is expanded. @param item reference to the item to be expanded (QTreeWidgetItem) """ if not self.__ignoreExpand: url = item.data(0, self.__urlRole) self.__listRepo(url, item) @pyqtSlot(QTreeWidgetItem) def on_repoTree_itemCollapsed(self, item): """ Private slot called when an item is collapsed. @param item reference to the item to be collapsed (QTreeWidgetItem) """ for child in item.takeChildren(): del child @pyqtSlot() def on_repoTree_itemSelectionChanged(self): """ Private slot called when the selection changes. """ if self.mode == "select": self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True) def accept(self): """ Public slot called when the dialog is accepted. """ if self.focusWidget() == self.urlCombo: return super(SvnRepoBrowserDialog, self).accept() def getSelectedUrl(self): """ Public method to retrieve the selected repository URL. @return the selected repository URL (string) """ items = self.repoTree.selectedItems() if len(items) == 1: return items[0].data(0, self.__urlRole) else: return "" def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.__resizeColumns() self.__resort() QApplication.restoreOverrideCursor() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.process is not None: self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') if self.__rx_dir.exactMatch(s): revision = self.__rx_dir.cap(1) author = self.__rx_dir.cap(2) date = self.__rx_dir.cap(3) name = self.__rx_dir.cap(4).strip() if name.endswith("/"): name = name[:-1] size = "" nodekind = "dir" elif self.__rx_file.exactMatch(s): revision = self.__rx_file.cap(1) author = self.__rx_file.cap(2) size = self.__rx_file.cap(3) date = self.__rx_file.cap(4) name = self.__rx_file.cap(5).strip() nodekind = "file" else: continue url = "{0}/{1}".format(self.repoUrl, name) self.__generateItem( name, revision, author, size, date, nodekind, url) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(SvnRepoBrowserDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnPropSetDialog.ui0000644000175000017500000001135312263304360024602 0ustar piotrpiotr SvnPropSetDialog 0 0 494 385 Set Subversion Property true Property Name: Enter the name of the property to be set Select property source Qt::NoFocus File Text true Enter text of the property true false false Enter the name of a file for the property false Press to select the file via a file selection dialog Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource propNameEdit textRadioButton propTextEdit propFileEdit fileButton textRadioButton toggled(bool) propTextEdit setEnabled(bool) 49 78 76 140 fileRadioButton toggled(bool) propFileEdit setEnabled(bool) 35 287 49 319 buttonBox accepted() SvnPropSetDialog accept() 67 360 74 380 buttonBox rejected() SvnPropSetDialog reject() 196 367 199 385 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnCommandDialog.py0000644000175000017500000000630312451233371024600 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the Subversion command dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_SvnCommandDialog import Ui_SvnCommandDialog import Utilities import UI.PixmapCache class SvnCommandDialog(QDialog, Ui_SvnCommandDialog): """ Class implementing the Subversion command dialog. It implements a dialog that is used to enter an arbitrary subversion command. It asks the user to enter the commandline parameters and the working directory. """ def __init__(self, argvList, wdList, ppath, parent=None): """ Constructor @param argvList history list of commandline arguments (list of strings) @param wdList history list of working directories (list of strings) @param ppath pathname of the project directory (string) @param parent parent widget of this dialog (QWidget) """ super(SvnCommandDialog, self).__init__(parent) self.setupUi(self) self.dirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.workdirCompleter = E5DirCompleter(self.workdirCombo) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) self.commandCombo.clear() self.commandCombo.addItems(argvList) if len(argvList) > 0: self.commandCombo.setCurrentIndex(0) self.workdirCombo.clear() self.workdirCombo.addItems(wdList) if len(wdList) > 0: self.workdirCombo.setCurrentIndex(0) self.projectDirLabel.setText(ppath) # modify some what's this help texts t = self.commandCombo.whatsThis() if t: t += Utilities.getPercentReplacementHelp() self.commandCombo.setWhatsThis(t) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_dirButton_clicked(self): """ Private method used to open a directory selection dialog. """ cwd = self.workdirCombo.currentText() if not cwd: cwd = self.projectDirLabel.text() d = E5FileDialog.getExistingDirectory( self, self.tr("Working directory"), cwd, E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if d: self.workdirCombo.setEditText(Utilities.toNativeSeparators(d)) def on_commandCombo_editTextChanged(self, text): """ Private method used to enable/disable the OK-button. @param text ignored """ self.okButton.setDisabled(self.commandCombo.currentText() == "") def getData(self): """ Public method to retrieve the data entered into this dialog. @return a tuple of argv, workdir """ return (self.commandCombo.currentText(), self.workdirCombo.currentText()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnSwitchDialog.ui0000644000175000017500000000747612354034011024454 0ustar piotrpiotr SvnSwitchDialog 0 0 391 146 Subversion Switch true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Tag Name: 0 0 Enter the name of the tag <b>Tag Name</b> <p>Enter the name of the tag to be switched to. In order to switch to the trunk version leave it empty.</p> true false Tag Type Select for a regular tag <b>Regular Tag</b> <p>Select this entry for a regular tag.</p> Regular Tag true Select for a branch tag <b>Branch Tag</b> <p>Select this entry for a branch tag.</p> Branch Tag qPixmapFromMimeSource tagCombo regularButton branchButton buttonBox accepted() SvnSwitchDialog accept() 53 113 34 139 buttonBox rejected() SvnSwitchDialog reject() 110 123 110 139 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnDiffDialog.ui0000644000175000017500000001144512060166053024060 0ustar piotrpiotr SvnDiffDialog 0 0 749 646 Subversion Diff 0 3 Difference <b>Subversion Diff</b><p>This shows the output of the svn diff command.</p> QTextEdit::NoWrap true 8 false 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the subversion process &Send Alt+S Enter data to be sent to the subversion process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Close|QDialogButtonBox::Save filesCombo contents errors input passwordCheckBox sendButton buttonBox buttonBox rejected() SvnDiffDialog close() 197 624 201 645 eric-6.0.8/eric/Plugins/VcsPlugins/vcsSubversion/SvnNewProjectOptionsDialog.py0000644000175000017500000001455312451233371026664 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the Subversion Options Dialog for a new project from the repository. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QDir, pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_SvnNewProjectOptionsDialog import Ui_SvnNewProjectOptionsDialog from .Config import ConfigSvnProtocols import Utilities import Preferences import UI.PixmapCache class SvnNewProjectOptionsDialog(QDialog, Ui_SvnNewProjectOptionsDialog): """ Class implementing the Options Dialog for a new project from the repository. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the version control object @param parent parent widget (QWidget) """ super(SvnNewProjectOptionsDialog, self).__init__(parent) self.setupUi(self) self.vcsUrlButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.projectDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.vcsDirectoryCompleter = E5DirCompleter(self.vcsUrlEdit) self.vcsProjectDirCompleter = E5DirCompleter(self.vcsProjectDirEdit) self.protocolCombo.addItems(ConfigSvnProtocols) self.vcs = vcs hd = Utilities.toNativeSeparators(QDir.homePath()) hd = os.path.join(hd, 'subversionroot') self.vcsUrlEdit.setText(hd) self.localPath = hd self.networkPath = "localhost/" self.localProtocol = True ipath = Preferences.getMultiProject("Workspace") or \ Utilities.getHomeDir() self.__initPaths = [ Utilities.fromNativeSeparators(ipath), Utilities.fromNativeSeparators(ipath) + "/", ] self.vcsProjectDirEdit.setText( Utilities.toNativeSeparators(self.__initPaths[0])) self.resize(self.width(), self.minimumSizeHint().height()) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_vcsProjectDirEdit_textChanged(self, txt): """ Private slot to handle a change of the project directory. @param txt name of the project directory (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths) @pyqtSlot() def on_vcsUrlButton_clicked(self): """ Private slot to display a selection dialog. """ if self.protocolCombo.currentText() == "file://": directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Repository-Directory"), self.vcsUrlEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.vcsUrlEdit.setText( Utilities.toNativeSeparators(directory)) else: from .SvnRepoBrowserDialog import SvnRepoBrowserDialog dlg = SvnRepoBrowserDialog(self.vcs, mode="select", parent=self) dlg.start( self.protocolCombo.currentText() + self.vcsUrlEdit.text()) if dlg.exec_() == QDialog.Accepted: url = dlg.getSelectedUrl() if url: protocol = url.split("://")[0] path = url.split("://")[1] self.protocolCombo.setCurrentIndex( self.protocolCombo.findText(protocol + "://")) self.vcsUrlEdit.setText(path) @pyqtSlot() def on_projectDirButton_clicked(self): """ Private slot to display a directory selection dialog. """ directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Project Directory"), self.vcsProjectDirEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.vcsProjectDirEdit.setText( Utilities.toNativeSeparators(directory)) def on_layoutCheckBox_toggled(self, checked): """ Private slot to handle the change of the layout checkbox. @param checked flag indicating the state of the checkbox (boolean) """ self.vcsTagLabel.setEnabled(checked) self.vcsTagEdit.setEnabled(checked) if not checked: self.vcsTagEdit.clear() @pyqtSlot(str) def on_protocolCombo_activated(self, protocol): """ Private slot to switch the status of the directory selection button. @param protocol selected protocol (string) """ if protocol == "file://": self.networkPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.localPath) self.vcsUrlLabel.setText(self.tr("Pat&h:")) self.localProtocol = True else: if self.localProtocol: self.localPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.networkPath) self.vcsUrlLabel.setText(self.tr("&URL:")) self.localProtocol = False @pyqtSlot(str) def on_vcsUrlEdit_textChanged(self, txt): """ Private slot to handle changes of the URL. @param txt current text of the line edit (string) """ enable = "://" not in txt self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) def getData(self): """ Public slot to retrieve the data entered into the dialog. @return a tuple of a string (project directory) and a dictionary containing the data entered. """ scheme = self.protocolCombo.currentText() url = self.vcsUrlEdit.text() vcsdatadict = { "url": '{0}{1}'.format(scheme, url), "tag": self.vcsTagEdit.text(), "standardLayout": self.layoutCheckBox.isChecked(), } return (self.vcsProjectDirEdit.text(), vcsdatadict) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/0000755000175000017500000000000012557365404017771 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnTagBranchListDialog.py0000644000175000017500000002011412537064321024625 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show a list of tags or branches. """ from __future__ import unicode_literals import os import pysvn from PyQt5.QtCore import QMutexLocker, QRegExp, Qt from PyQt5.QtWidgets import QHeaderView, QLineEdit, QDialog, QInputDialog, \ QApplication, QDialogButtonBox, QTreeWidgetItem from E5Gui import E5MessageBox from .SvnUtilities import formatTime from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnTagBranchListDialog import Ui_SvnTagBranchListDialog class SvnTagBranchListDialog(QDialog, SvnDialogMixin, Ui_SvnTagBranchListDialog): """ Class implementing a dialog to show a list of tags or branches. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnTagBranchListDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.vcs = vcs self.tagList.headerItem().setText(self.tagList.columnCount(), "") self.tagList.header().setSortIndicator(3, Qt.AscendingOrder) self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback def start(self, path, tags=True): """ Public slot to start the svn status command. @param path name of directory to be listed (string) @param tags flag indicating a list of tags is requested (False = branches, True = tags) @return flag indicating success (boolean) """ self.errorGroup.hide() if not tags: self.setWindowTitle(self.tr("Subversion Branches List")) self.activateWindow() QApplication.processEvents() dname, fname = self.vcs.splitPath(path) reposURL = self.vcs.svnGetReposName(dname) if reposURL is None: E5MessageBox.critical( self, self.tr("Subversion Error"), self.tr( """The URL of the project repository could not be""" """ retrieved from the working copy. The list operation""" """ will be aborted""")) self.close() return False if self.vcs.otherData["standardLayout"]: # determine the base path of the project in the repository rx_base = QRegExp('(.+)/(trunk|tags|branches).*') if not rx_base.exactMatch(reposURL): E5MessageBox.critical( self, self.tr("Subversion Error"), self.tr( """The URL of the project repository has an""" """ invalid format. The list operation will""" """ be aborted""")) return False reposRoot = rx_base.cap(1) if tags: path = "{0}/tags".format(reposRoot) else: path = "{0}/branches".format(reposRoot) else: reposPath, ok = QInputDialog.getText( self, self.tr("Subversion List"), self.tr("Enter the repository URL containing the" " tags or branches"), QLineEdit.Normal, self.vcs.svnNormalizeURL(reposURL)) if not ok: self.close() return False if not reposPath: E5MessageBox.critical( self, self.tr("Subversion List"), self.tr( """The repository URL is empty. Aborting...""")) self.close() return False path = reposPath locker = QMutexLocker(self.vcs.vcsExecutionMutex) self.tagsList = [] cwd = os.getcwd() os.chdir(dname) try: entries = self.client.list(path, recurse=False) # dirent, lock already unicode in Python 2 for dirent, lock in entries: if dirent["path"] != path: name = dirent["path"].replace(path + '/', "") self.__generateItem(dirent["created_rev"].number, dirent["last_author"], formatTime(dirent["time"]), name) if self.vcs.otherData["standardLayout"]: self.tagsList.append(name) else: self.tagsList.append(path + '/' + name) if self._clientCancelCallback(): break res = True except pysvn.ClientError as e: self.__showError(e.args[0]) res = False except AttributeError: self.__showError( self.tr("The installed version of PySvn should be" " 1.4.0 or better.")) res = False locker.unlock() self.__finish() os.chdir(cwd) return res def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.__resizeColumns() self.__resort() self._cancel() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ self.errorGroup.show() self.errors.insertPlainText(msg) self.errors.ensureCursorVisible() def __resort(self): """ Private method to resort the tree. """ self.tagList.sortItems( self.tagList.sortColumn(), self.tagList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.tagList.header().resizeSections(QHeaderView.ResizeToContents) self.tagList.header().setStretchLastSection(True) def __generateItem(self, revision, author, date, name): """ Private method to generate a tag item in the taglist. @param revision revision number (integer) @param author author of the tag (string) @param date date of the tag (string) @param name name (path) of the tag (string) """ itm = QTreeWidgetItem(self.tagList) itm.setData(0, Qt.DisplayRole, revision) itm.setData(1, Qt.DisplayRole, author) itm.setData(2, Qt.DisplayRole, date) itm.setData(3, Qt.DisplayRole, name) itm.setTextAlignment(0, Qt.AlignRight) def getTagList(self): """ Public method to get the taglist of the last run. @return list of tags (list of strings) """ return self.tagsList eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnBlameDialog.ui0000644000175000017500000000514112060166053023144 0ustar piotrpiotr SvnBlameDialog 0 0 690 750 Subversion Blame true 0 6 true QAbstractItemView::NoSelection false false false Revision Author Line 0 1 Errors true false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close blameList errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnUtilities.py0000644000175000017500000000701512451233371022776 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing some common utility functions for the pysvn package. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QDateTime, Qt import Utilities from .Config import DefaultConfig, DefaultIgnores def formatTime(seconds): """ Module function to return a formatted time string. @param seconds time in seconds since epoch to be formatted (float or long) @return formatted time string (string) """ return QDateTime.fromTime_t(int(seconds))\ .toTimeSpec(Qt.LocalTime)\ .toString("yyyy-MM-dd hh:mm:ss") def dateFromTime_t(seconds): """ Module function to return the date. @param seconds time in seconds since epoch to be formatted (float or long) @return date (QDate) """ return QDateTime.fromTime_t(int(seconds)).toTimeSpec(Qt.LocalTime).date() def getServersPath(): """ Module function to get the filename of the servers file. @return filename of the servers file (string) """ if Utilities.isWindowsPlatform(): appdata = os.environ["APPDATA"] return os.path.join(appdata, "Subversion", "servers") else: homedir = Utilities.getHomeDir() return os.path.join(homedir, ".subversion", "servers") def getConfigPath(): """ Module function to get the filename of the config file. @return filename of the config file (string) """ if Utilities.isWindowsPlatform(): appdata = os.environ["APPDATA"] return os.path.join(appdata, "Subversion", "config") else: homedir = Utilities.getHomeDir() return os.path.join(homedir, ".subversion", "config") def createDefaultConfig(): """ Module function to create a default config file suitable for eric. """ config = getConfigPath() try: os.makedirs(os.path.dirname(config)) except OSError: pass try: f = open(config, "w") f.write(DefaultConfig) f.close() except IOError: pass def amendConfig(): """ Module function to amend the config file. """ config = getConfigPath() try: f = open(config, "r") configList = f.read().splitlines() f.close() except IOError: return newConfig = [] ignoresFound = False amendList = [] for line in configList: if line.find("global-ignores") in [0, 2]: ignoresFound = True if line.startswith("# "): line = line[2:] newConfig.append(line) for amend in DefaultIgnores: if amend not in line: amendList.append(amend) elif ignoresFound: if line.startswith("##"): ignoresFound = False if amendList: newConfig.append(" " + " ".join(amendList)) newConfig.append(line) continue elif line.startswith("# "): line = line[2:] newConfig.append(line) oldAmends = amendList[:] amendList = [] for amend in oldAmends: if amend not in line: amendList.append(amend) else: newConfig.append(line) if newConfig != configList: try: f = open(config, "w") f.write("\n".join(newConfig)) f.close() except IOError: pass eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnRepoBrowserDialog.ui0000644000175000017500000000606012060166053024376 0ustar piotrpiotr SvnRepoBrowserDialog 0 0 650 500 Subversion Repository Browser URL: Enter the URL of the repository true QComboBox::InsertAtTop true true true 5 File Revision Author Size Date Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok urlCombo repoTree buttonBox buttonBox rejected() SvnRepoBrowserDialog reject() 353 493 286 274 buttonBox accepted() SvnRepoBrowserDialog accept() 140 474 8 472 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnPropSetDialog.py0000644000175000017500000000242112451233371023533 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a new property. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_SvnPropSetDialog import Ui_SvnPropSetDialog class SvnPropSetDialog(QDialog, Ui_SvnPropSetDialog): """ Class implementing a dialog to enter the data for a new property. """ def __init__(self, recursive, parent=None): """ Constructor @param recursive flag indicating a recursive set is requested @param parent parent widget (QWidget) """ super(SvnPropSetDialog, self).__init__(parent) self.setupUi(self) self.recurseCheckBox.setChecked(recursive) def getData(self): """ Public slot used to retrieve the data entered into the dialog. @return tuple of three values giving the property name, the text of the property and a flag indicating, that this property should be applied recursively. (string, string, boolean) """ return (self.propNameEdit.text(), self.propTextEdit.toPlainText(), self.recurseCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnDialogMixin.py0000644000175000017500000001350112451233371023224 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog mixin class providing common callback methods for the pysvn client. """ from __future__ import unicode_literals from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QApplication, QDialog, QWidget class SvnDialogMixin(object): """ Class implementing a dialog mixin providing common callback methods for the pysvn client. """ def __init__(self, log=""): """ Constructor @param log optional log message (string) """ self.shouldCancel = False self.logMessage = log def _cancel(self): """ Protected method to request a cancellation of the current action. """ self.shouldCancel = True def _reset(self): """ Protected method to reset the internal state of the dialog. """ self.shouldCancel = False def _clientCancelCallback(self): """ Protected method called by the client to check for cancellation. @return flag indicating a cancellation """ QApplication.processEvents() return self.shouldCancel def _clientLoginCallback(self, realm, username, may_save): """ Protected method called by the client to get login information. @param realm name of the realm of the requested credentials (string) @param username username as supplied by subversion (string) @param may_save flag indicating, that subversion is willing to save the answers returned (boolean) @return tuple of four values (retcode, username, password, save). Retcode should be True, if username and password should be used by subversion, username and password contain the relevant data as strings and save is a flag indicating, that username and password should be saved. """ from .SvnLoginDialog import SvnLoginDialog cursor = QCursor(QApplication.overrideCursor()) if cursor is not None: QApplication.restoreOverrideCursor() parent = isinstance(self, QWidget) and self or None dlg = SvnLoginDialog(realm, username, may_save, parent) res = dlg.exec_() if cursor is not None: QApplication.setOverrideCursor(cursor) if res == QDialog.Accepted: loginData = dlg.getData() return (True, loginData[0], loginData[1], loginData[2]) else: return (False, "", "", False) def _clientSslServerTrustPromptCallback(self, trust_dict): """ Protected method called by the client to request acceptance for a ssl server certificate. @param trust_dict dictionary containing the trust data @return tuple of three values (retcode, acceptedFailures, save). Retcode should be true, if the certificate should be accepted, acceptedFailures should indicate the accepted certificate failures and save should be True, if subversion should save the certificate. """ from E5Gui import E5MessageBox cursor = QCursor(QApplication.overrideCursor()) if cursor is not None: QApplication.restoreOverrideCursor() parent = isinstance(self, QWidget) and self or None msgBox = E5MessageBox.E5MessageBox( E5MessageBox.Question, self.tr("Subversion SSL Server Certificate"), self.tr("""

Accept the following SSL certificate?

""" """""" """""" """""" """""" """""" """""" """""" """
Realm:{0}
Hostname:{1}
Fingerprint:{2}
Valid from:{3}
Valid until:{4}
Issuer name:{5}
""") .format(trust_dict["realm"], trust_dict["hostname"], trust_dict["finger_print"], trust_dict["valid_from"], trust_dict["valid_until"], trust_dict["issuer_dname"]), modal=True, parent=parent) permButton = msgBox.addButton(self.tr("&Permanent accept"), E5MessageBox.AcceptRole) tempButton = msgBox.addButton(self.tr("&Temporary accept"), E5MessageBox.AcceptRole) msgBox.addButton(self.tr("&Reject"), E5MessageBox.RejectRole) msgBox.exec_() if cursor is not None: QApplication.setOverrideCursor(cursor) if msgBox.clickedButton() == permButton: return (True, trust_dict["failures"], True) elif msgBox.clickedButton() == tempButton: return (True, trust_dict["failures"], False) else: return (False, 0, False) def _clientLogCallback(self): """ Protected method called by the client to request a log message. @return a flag indicating success and the log message (string) """ from .SvnCommitDialog import SvnCommitDialog if self.logMessage: return True, self.logMessage else: # call CommitDialog and get message from there dlg = SvnCommitDialog(self) if dlg.exec_() == QDialog.Accepted: msg = dlg.logMessage() if msg: return True, msg else: return True, "***" # always supply a valid log message else: return False, "" eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnLoginDialog.ui0000644000175000017500000000601112060166053023171 0ustar piotrpiotr SvnLoginDialog 0 0 400 145 Subversion Login true Select, if the login data should be saved. Save login data Enter password QLineEdit::Password Password: Username: Enter username Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok usernameEdit passwordEdit saveCheckBox buttonBox accepted() SvnLoginDialog accept() 23 129 23 141 buttonBox rejected() SvnLoginDialog reject() 81 121 81 145 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/ProjectBrowserHelper.py0000644000175000017500000011400512451233371024444 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the VCS project browser helper for subversion. """ from __future__ import unicode_literals import os import pysvn from PyQt5.QtWidgets import QMenu from E5Gui.E5Application import e5App from VCS.ProjectBrowserHelper import VcsProjectBrowserHelper from Project.ProjectBrowserModel import ProjectBrowserFileItem import UI.PixmapCache class SvnProjectBrowserHelper(VcsProjectBrowserHelper): """ Class implementing the VCS project browser helper for subversion. """ def __init__(self, vcsObject, browserObject, projectObject, isTranslationsBrowser, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param browserObject reference to the project browser object @param projectObject reference to the project object @param isTranslationsBrowser flag indicating, the helper is requested for the translations browser (this needs some special treatment) @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectBrowserHelper.__init__(self, vcsObject, browserObject, projectObject, isTranslationsBrowser, parent, name) def showContextMenu(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the file status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ if self.browser.currentItem().data(1) == self.vcs.vcsName(): for act in self.vcsMenuActions: act.setEnabled(True) for act in self.vcsAddMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) if not hasattr(self.browser.currentItem(), 'fileName'): self.blameAct.setEnabled(False) else: for act in self.vcsMenuActions: act.setEnabled(False) for act in self.vcsAddMenuActions: act.setEnabled(True) if 1 in self.browser.specialMenuEntries: try: name = self.browser.currentItem().fileName() except AttributeError: name = self.browser.currentItem().dirName() if not os.path.isdir(name): self.vcsMenuAddTree.setEnabled(False) for act in standardItems: act.setEnabled(True) def showContextMenuMulti(self, menu, standardItems): """ Public slot called before the context menu (multiple selections) is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the files status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ vcsName = self.vcs.vcsName() items = self.browser.getSelectedItems() vcsItems = 0 # determine number of selected items under VCS control for itm in items: if itm.data(1) == vcsName: vcsItems += 1 if vcsItems > 0: if vcsItems != len(items): for act in self.vcsMultiMenuActions: act.setEnabled(False) else: for act in self.vcsMultiMenuActions: act.setEnabled(True) for act in self.vcsAddMultiMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: for act in self.vcsMultiMenuActions: act.setEnabled(False) for act in self.vcsAddMultiMenuActions: act.setEnabled(True) if 1 in self.browser.specialMenuEntries and \ self.__itemsHaveFiles(items): self.vcsMultiMenuAddTree.setEnabled(False) for act in standardItems: act.setEnabled(True) def showContextMenuDir(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the directory status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ if self.browser.currentItem().data(1) == self.vcs.vcsName(): for act in self.vcsDirMenuActions: act.setEnabled(True) for act in self.vcsAddDirMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: for act in self.vcsDirMenuActions: act.setEnabled(False) for act in self.vcsAddDirMenuActions: act.setEnabled(True) for act in standardItems: act.setEnabled(True) def showContextMenuDirMulti(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the directory status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ vcsName = self.vcs.vcsName() items = self.browser.getSelectedItems() vcsItems = 0 # determine number of selected items under VCS control for itm in items: if itm.data(1) == vcsName: vcsItems += 1 if vcsItems > 0: if vcsItems != len(items): for act in self.vcsDirMultiMenuActions: act.setEnabled(False) else: for act in self.vcsDirMultiMenuActions: act.setEnabled(True) for act in self.vcsAddDirMultiMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: for act in self.vcsDirMultiMenuActions: act.setEnabled(False) for act in self.vcsAddDirMultiMenuActions: act.setEnabled(True) for act in standardItems: act.setEnabled(True) ########################################################################### # Protected menu generation methods below ########################################################################### def _addVCSMenu(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ self.vcsMenuActions = [] self.vcsAddMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsPySvn", "icons", "pysvn.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Update from repository'), self._VCSUpdate) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddMenuActions.append(act) if 1 in self.browser.specialMenuEntries: self.vcsMenuAddTree = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add tree to repository'), self._VCSAddTree) self.vcsAddMenuActions.append(self.vcsMenuAddTree) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( self.tr('Copy'), self.__SVNCopy) self.vcsMenuActions.append(act) act = menu.addAction(self.tr('Move'), self.__SVNMove) self.vcsMenuActions.append(act) if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0): menu.addSeparator() act = menu.addAction( self.tr("Add to Changelist"), self.__SVNAddToChangelist) self.vcsMenuActions.append(act) act = menu.addAction( self.tr("Remove from Changelist"), self.__SVNRemoveFromChangelist) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log'), self._VCSLog) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), self._VCSLogBrowser) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRepo.png"), self.tr('Show repository info'), self.__SVNInfo) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsSbsDiff.png"), self.tr('Show differences side-by-side'), self.__SVNSbsDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__SVNExtendedDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsSbsDiff.png"), self.tr('Show differences side-by-side (extended)'), self.__SVNSbsExtendedDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), self.__SVNUrlDiff) self.vcsMenuActions.append(act) self.blameAct = menu.addAction( self.tr('Show annotated file'), self.__SVNBlame) self.vcsMenuActions.append(self.blameAct) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self._VCSRevert) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Merge changes'), self._VCSMerge) self.vcsMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__SVNResolve) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLock.png"), self.tr('Lock'), self.__SVNLock) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Unlock'), self.__SVNUnlock) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Break Lock'), self.__SVNBreakLock) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Steal Lock'), self.__SVNStealLock) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp) self.vcsMenuActions.append(act) act = menu.addAction( self.tr('List Properties'), self.__SVNListProps) self.vcsMenuActions.append(act) act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp) self.vcsMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menu = menu def _addVCSMenuMulti(self, mainMenu): """ Protected method used to add the VCS menu for multi selection to all project browsers. @param mainMenu reference to the menu to be amended """ self.vcsMultiMenuActions = [] self.vcsAddMultiMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsPySvn", "icons", "pysvn.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Update from repository'), self._VCSUpdate) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddMultiMenuActions.append(act) if 1 in self.browser.specialMenuEntries: self.vcsMultiMenuAddTree = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add tree to repository'), self._VCSAddTree) self.vcsAddMultiMenuActions.append(self.vcsMultiMenuAddTree) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsMultiMenuActions.append(act) if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0): menu.addSeparator() act = menu.addAction( self.tr("Add to Changelist"), self.__SVNAddToChangelist) self.vcsMenuActions.append(act) act = menu.addAction( self.tr("Remove from Changelist"), self.__SVNRemoveFromChangelist) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__SVNExtendedDiff) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), self.__SVNUrlDiff) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self._VCSRevert) self.vcsMultiMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__SVNResolve) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLock.png"), self.tr('Lock'), self.__SVNLock) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Unlock'), self.__SVNUnlock) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Break Lock'), self.__SVNBreakLock) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsUnlock.png"), self.tr('Steal Lock'), self.__SVNStealLock) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp) self.vcsMultiMenuActions.append(act) act = menu.addAction( self.tr('List Properties'), self.__SVNListProps) self.vcsMultiMenuActions.append(act) act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp) self.vcsMultiMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuMulti = menu def _addVCSMenuBack(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsPySvn", "icons", "pysvn.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuBack = menu def _addVCSMenuDir(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ if mainMenu is None: return self.vcsDirMenuActions = [] self.vcsAddDirMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsPySvn", "icons", "pysvn.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Update from repository'), self._VCSUpdate) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Copy'), self.__SVNCopy) self.vcsDirMenuActions.append(act) act = menu.addAction(self.tr('Move'), self.__SVNMove) self.vcsDirMenuActions.append(act) if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0): menu.addSeparator() act = menu.addAction( self.tr("Add to Changelist"), self.__SVNAddToChangelist) self.vcsMenuActions.append(act) act = menu.addAction( self.tr("Remove from Changelist"), self.__SVNRemoveFromChangelist) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log'), self._VCSLog) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), self._VCSLogBrowser) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRepo.png"), self.tr('Show repository info'), self.__SVNInfo) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__SVNExtendedDiff) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), self.__SVNUrlDiff) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self._VCSRevert) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Merge changes'), self._VCSMerge) self.vcsDirMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__SVNResolve) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp) self.vcsDirMenuActions.append(act) act = menu.addAction( self.tr('List Properties'), self.__SVNListProps) self.vcsDirMenuActions.append(act) act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp) self.vcsDirMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuDir = menu def _addVCSMenuDirMulti(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ if mainMenu is None: return self.vcsDirMultiMenuActions = [] self.vcsAddDirMultiMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsPySvn", "icons", "pysvn.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Update from repository'), self._VCSUpdate) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsDirMultiMenuActions.append(act) if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0): menu.addSeparator() act = menu.addAction( self.tr("Add to Changelist"), self.__SVNAddToChangelist) self.vcsMenuActions.append(act) act = menu.addAction( self.tr("Remove from Changelist"), self.__SVNRemoveFromChangelist) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__SVNExtendedDiff) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), self.__SVNUrlDiff) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self._VCSRevert) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Merge changes'), self._VCSMerge) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__SVNResolve) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Set Property'), self.__SVNSetProp) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( self.tr('List Properties'), self.__SVNListProps) self.vcsDirMultiMenuActions.append(act) act = menu.addAction(self.tr('Delete Property'), self.__SVNDelProp) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__SVNConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuDirMulti = menu ########################################################################### # Menu handling methods below ########################################################################### def __SVNCopy(self): """ Private slot called by the context menu to copy the selected file. """ itm = self.browser.currentItem() try: fn = itm.fileName() except AttributeError: fn = itm.dirName() self.vcs.svnCopy(fn, self.project) def __SVNMove(self): """ Private slot called by the context menu to move the selected file. """ itm = self.browser.currentItem() try: fn = itm.fileName() except AttributeError: fn = itm.dirName() isFile = os.path.isfile(fn) movefiles = self.browser.project.getFiles(fn) if self.vcs.vcsMove(fn, self.project): if isFile: self.browser.closeSourceWindow.emit(fn) else: for mf in movefiles: self.browser.closeSourceWindow.emit(mf) def __SVNResolve(self): """ Private slot called by the context menu to resolve conflicts of a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnResolve(names) def __SVNListProps(self): """ Private slot called by the context menu to list the subversion properties of a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnListProps(names) def __SVNSetProp(self): """ Private slot called by the context menu to set a subversion property of a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnSetProp(names) def __SVNDelProp(self): """ Private slot called by the context menu to delete a subversion property of a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnDelProp(names) def __SVNExtendedDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository. This gives the chance to enter the revisions to compare. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnExtendedDiff(names) def __SVNUrlDiff(self): """ Private slot called by the context menu to show the difference of a file of two repository URLs. This gives the chance to enter the repository URLs to compare. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnUrlDiff(names) def __SVNSbsDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository side-by-side. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.svnSbsDiff(fn) def __SVNSbsExtendedDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository side-by-side. It allows the selection of revisions to compare. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.svnSbsDiff(fn, extended=True) def __SVNBlame(self): """ Private slot called by the context menu to show the blame of a file. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.svnBlame(fn) def __SVNLock(self): """ Private slot called by the context menu to lock files in the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnLock(names) def __SVNUnlock(self): """ Private slot called by the context menu to unlock files in the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnUnlock(names) def __SVNBreakLock(self): """ Private slot called by the context menu to break lock files in the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnUnlock(names, breakIt=True) def __SVNStealLock(self): """ Private slot called by the context menu to steal lock files in the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnLock(names, stealIt=True) def __SVNInfo(self): """ Private slot called by the context menu to show repository information of a file or directory. """ try: name = self.browser.currentItem().fileName() except AttributeError: name = self.browser.currentItem().dirName() name = self.project.getRelativePath(name) self.vcs.svnInfo(self.project.ppath, name) def __SVNConfigure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("zzz_subversionPage") def __SVNAddToChangelist(self): """ Private slot called by the context menu to add files to a changelist. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnAddToChangelist(names) def __SVNRemoveFromChangelist(self): """ Private slot called by the context menu to remove files from their changelist. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.svnRemoveFromChangelist(names) ########################################################################### # Some private utility methods below ########################################################################### def __itemsHaveFiles(self, items): """ Private method to check, if items contain file type items. @param items items to check (list of QTreeWidgetItems) @return flag indicating items contain file type items (boolean) """ for itm in items: if isinstance(itm, ProjectBrowserFileItem): return True return False eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnLogDialog.ui0000644000175000017500000000542412203730423022646 0ustar piotrpiotr SvnLogDialog 0 0 751 649 Subversion Log 0 4 Log <b>Subversion Log</b><p>This shows the output of the svn log command. By clicking on the links you may show the difference between versions.</p> Select to show differences side-by-side Show differences side-by-side 0 1 Errors <b>Subversion log errors</b><p>This shows possible error messages of the svn log command.</p> true false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close contents sbsCheckBox errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnDialog.ui0000644000175000017500000000447612060166053022215 0ustar piotrpiotr SvnDialog 0 0 593 499 Subversion true 0 3 Output true false 0 1 Errors true false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource resultbox errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/icons/0000755000175000017500000000000012060166053021070 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/icons/pysvn.png0000644000175000017500000000162012060166053022754 0ustar piotrpiotr‰PNG  IHDRÄ´l;WIDAT8µ”Ïk\UÇ?÷ýÌøÞLfòc&’’&N3¡$&ÐP!(ØêBQ ºsU(wÝví¿á¦àJD« hA›Z I«)©¦É41&Nf23™÷Þ}÷>µÉ`Ú@¤=p9Îás‡ï9âý+פc›¸ŽIÇ¿Þm÷m±iB©¾HµÅšPÆ„RF1a¤°‹g`Ƴ€þ/p,åÓ×¶7ùîËYœ¿ùtÁ–ÚáÊå T˳DQpxíQÀÃÃÜ87Á›/=Oe}©½c MÆl¯F؉¦…¼M^}¡ÌÜÆ8Ÿåe|ßCÄ ¹ RiâXÒß×C­8Dpý2À¢Ö›Q £´P±¤Ï«1Qø) •),/ÏÅKÒ}|’¡³DRJEÆ,ßgnæGòg÷;nE’8 éK5ym¬‚kĤlÉ™«ˆ¨JÆ\¦?}†ÁÒ)0;*i›¢Á†ÌÓYz•˜{‡ž”)2佩 ç'~G¨âÄM¹K5ìy(!aòÒ„RAÛ"¦…e¨(Þï8‰LJ]iG dƒ­‡íÝõÀ§.sÜoM‚8 ¨CÍPJ`jzÓ ‘Uº­?èÏ9T‚³Ÿe7NÊÎæL¹HWªN—½FMõr·:vdà#ûv¼}æœIÁIEND®B`‚eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/icons/preferences-subversion.png0000644000175000017500000000130012060166053026266 0ustar piotrpiotr‰PNG  IHDRÄ´l;‡IDAT8Í”ÏKTQÇ?÷½7oÆÞ›¦Ž†â&GÄRPlS‹¢EQ A›v­‚Ú¹uÝ¿ÑFhQA%”š%Š) VþÀudÔ÷ëÞiQèˆ?h"©—s¸÷{?÷p8犛ݽ¾Ò ›:‘_>œïób]¸¾ü¹<™+\?Àõ®àz08ÓŽúGàÀ÷ÿ>8³ºÄ«§÷™ü»`C®ÓÝu›µÙ<Ï9\[¸¾¾žÆÆMMM(¥@?X[PÆÑh”‘i‚P9f¤èPí6xk}ÏÝÜ#p¶²¬./LDXÊ8Œs‰—ŸDÎF†­ìúÁàµEÖ>=Âö¦QRnæ”bàåŠÅ<¦æ±’qBCh‘SÔ—8Ì¿À÷÷ÖÛXú:ƽ®NÊÊÊù0•%‹aHŸ:ë"7®w01µ@""9¥i9ZšQî¯'g‰'k÷‚ÃöqúûI5438)°¬M¦Ž.ï{“NÕ2»ª³²ÚcxXb‘± ì²³û—"Y}ŠçC‹<ì›A…w^5B4´_£çÉ–%lî´'5zž}Ä9Ö@‘•Ø¿ºaRÓr‰ˆ©#„Ø%¨¨J6ÓÌ-;”ÚŠÌòw„GA,YG¸X⸕gñËѪ6@Ëk7!€ÝÐ|óeŽÑáw\9—¦2`Ä,“„m’°CÜêháò™¬,Lídü»67;ƒm[ˆ Kyq194|©ŸÊŠR2©:œ¾7Ä V’;w)©i£îtÏW¸¾Äqf>1:ü–dõ…Â3nn?Omºô¾Ìmï ¡±è'‰§¯"s:®' iMhYQ4}ï5M70ò:êÿùèÿ9ø¸Cû¼N#ãªIEND®B`‚eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnChangeListsDialog.py0000644000175000017500000001114012537064320024342 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to browse the change lists. """ from __future__ import unicode_literals import os import sys import pysvn from PyQt5.QtCore import pyqtSlot, Qt, QMutexLocker from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QListWidgetItem, \ QApplication from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnChangeListsDialog import Ui_SvnChangeListsDialog class SvnChangeListsDialog(QDialog, SvnDialogMixin, Ui_SvnChangeListsDialog): """ Class implementing a dialog to browse the change lists. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnChangeListsDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.vcs = vcs self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback @pyqtSlot(QListWidgetItem, QListWidgetItem) def on_changeLists_currentItemChanged(self, current, previous): """ Private slot to handle the selection of a new item. @param current current item (QListWidgetItem) @param previous previous current item (QListWidgetItem) """ self.filesList.clear() if current is not None: changelist = current.text() if changelist in self.changeListsDict: self.filesList.addItems( sorted(self.changeListsDict[changelist])) def start(self, path): """ Public slot to populate the data. @param path directory name to show change lists for (string) """ self.changeListsDict = {} self.cancelled = False self.filesLabel.setText( self.tr("Files (relative to {0}):").format(path)) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() locker = QMutexLocker(self.vcs.vcsExecutionMutex) try: entries = self.client.get_changelist( path, depth=pysvn.depth.infinity) for entry in entries: file = entry[0] changelist = entry[1] if sys.version_info[0] == 2: file = file.decode('utf-8') changelist = changelist.decode('utf-8') if changelist not in self.changeListsDict: self.changeListsDict[changelist] = [] filename = file.replace(path + os.sep, "") if filename not in self.changeListsDict[changelist]: self.changeListsDict[changelist].append(filename) except pysvn.ClientError as e: locker.unlock() self.__showError(e.args[0]) self.__finish() def __finish(self): """ Private slot called when the user pressed the button. """ self.changeLists.addItems(sorted(self.changeListsDict.keys())) QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) if len(self.changeListsDict) == 0: self.changeLists.addItem(self.tr("No changelists found")) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) else: self.changeLists.setCurrentRow(0) self.changeLists.setFocus(Qt.OtherFocusReason) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.cancelled = True self.__finish() eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnOptionsDialog.py0000644000175000017500000001063512451233371023600 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter options used to start a project in the VCS. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QDir, pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_SvnOptionsDialog import Ui_SvnOptionsDialog from .Config import ConfigSvnProtocols import Utilities import UI.PixmapCache class SvnOptionsDialog(QDialog, Ui_SvnOptionsDialog): """ Class implementing a dialog to enter options used to start a project in the repository. """ def __init__(self, vcs, project, parent=None): """ Constructor @param vcs reference to the version control object @param project reference to the project object @param parent parent widget (QWidget) """ super(SvnOptionsDialog, self).__init__(parent) self.setupUi(self) self.vcsUrlButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.vcsDirectoryCompleter = E5DirCompleter(self.vcsUrlEdit) self.project = project self.protocolCombo.addItems(ConfigSvnProtocols) hd = Utilities.toNativeSeparators(QDir.homePath()) hd = os.path.join(hd, 'subversionroot') self.vcsUrlEdit.setText(hd) self.vcs = vcs self.localPath = hd self.networkPath = "localhost/" self.localProtocol = True msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_vcsUrlButton_clicked(self): """ Private slot to display a selection dialog. """ if self.protocolCombo.currentText() == "file://": directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Repository-Directory"), self.vcsUrlEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.vcsUrlEdit.setText( Utilities.toNativeSeparators(directory)) else: from .SvnRepoBrowserDialog import SvnRepoBrowserDialog dlg = SvnRepoBrowserDialog(self.vcs, mode="select", parent=self) dlg.start( self.protocolCombo.currentText() + self.vcsUrlEdit.text()) if dlg.exec_() == QDialog.Accepted: url = dlg.getSelectedUrl() if url: protocol = url.split("://")[0] path = url.split("://")[1] self.protocolCombo.setCurrentIndex( self.protocolCombo.findText(protocol + "://")) self.vcsUrlEdit.setText(path) @pyqtSlot(str) def on_protocolCombo_activated(self, protocol): """ Private slot to switch the status of the directory selection button. @param protocol selected protocol (string) """ if protocol == "file://": self.networkPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.localPath) self.vcsUrlLabel.setText(self.tr("Pat&h:")) self.localProtocol = True else: if self.localProtocol: self.localPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.networkPath) self.vcsUrlLabel.setText(self.tr("&URL:")) self.localProtocol = False @pyqtSlot(str) def on_vcsUrlEdit_textChanged(self, txt): """ Private slot to handle changes of the URL. @param txt current text of the line edit (string) """ enable = "://" not in txt self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) def getData(self): """ Public slot to retrieve the data entered into the dialog. @return a dictionary containing the data entered """ scheme = self.protocolCombo.currentText() url = self.vcsUrlEdit.text() vcsdatadict = { "url": '{0}{1}'.format(scheme, url), "message": self.vcsLogEdit.text(), "standardLayout": self.layoutCheckBox.isChecked(), } return vcsdatadict eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/subversion.py0000644000175000017500000030312712451233371022536 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the version control systems interface to Subversion. """ from __future__ import unicode_literals import os import sys import shutil import time from PyQt5.QtCore import Qt, QMutexLocker, pyqtSignal, QRegExp, QDateTime, \ QCoreApplication from PyQt5.QtWidgets import QLineEdit, QDialog, QInputDialog, QApplication from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from VCS.VersionControl import VersionControl import pysvn from .SvnDialog import SvnDialog from .SvnUtilities import getConfigPath, amendConfig, createDefaultConfig import Utilities class Subversion(VersionControl): """ Class implementing the version control systems interface to Subversion. @signal committed() emitted after the commit action has completed """ committed = pyqtSignal() def __init__(self, plugin, parent=None, name=None): """ Constructor @param plugin reference to the plugin object @param parent parent widget (QWidget) @param name name of this object (string) """ VersionControl.__init__(self, parent, name) self.defaultOptions = { 'global': [''], 'commit': [''], 'checkout': [''], 'update': [''], 'add': [''], 'remove': [''], 'diff': [''], 'log': [''], 'history': [''], 'status': [''], 'tag': [''], 'export': [''] } self.interestingDataKeys = [ "standardLayout", ] self.__plugin = plugin self.__ui = parent self.options = self.defaultOptions self.otherData["standardLayout"] = True self.tagsList = [] self.branchesList = [] self.allTagsBranchesList = [] self.mergeList = [[], [], []] self.showedTags = False self.showedBranches = False self.tagTypeList = [ 'tags', 'branches' ] self.commandHistory = [] self.wdHistory = [] if pysvn.version >= (1, 4, 3, 0) and \ "SVN_ASP_DOT_NET_HACK" in os.environ: self.adminDir = '_svn' else: self.adminDir = '.svn' self.log = None self.diff = None self.sbsDiff = None self.status = None self.propList = None self.tagbranchList = None self.blame = None self.repoBrowser = None self.logBrowser = None self.statusCache = {} self.__commitData = {} self.__commitDialog = None self.__wcng = True # assume new generation working copy metadata format def getPlugin(self): """ Public method to get a reference to the plugin object. @return reference to the plugin object (VcsPySvnPlugin) """ return self.__plugin def getClient(self): """ Public method to create and initialize the pysvn client object. @return the pysvn client object (pysvn.Client) """ configDir = "" authCache = True for arg in self.options['global']: if arg.startswith("--config-dir"): configDir = arg.split("=", 1)[1] if arg.startswith("--no-auth-cache"): authCache = False client = pysvn.Client(configDir) client.exception_style = 1 client.set_auth_cache(authCache) return client ########################################################################### ## Methods of the VCS interface ########################################################################### def vcsShutdown(self): """ Public method used to shutdown the Subversion interface. """ if self.log is not None: self.log.close() if self.diff is not None: self.diff.close() if self.sbsDiff is not None: self.sbsDiff.close() if self.status is not None: self.status.close() if self.propList is not None: self.propList.close() if self.tagbranchList is not None: self.tagbranchList.close() if self.blame is not None: self.blame.close() if self.repoBrowser is not None: self.repoBrowser.close() if self.logBrowser is not None: self.logBrowser.close() def vcsExists(self): """ Public method used to test for the presence of the svn executable. @return flag indicating the existance (boolean) and an error message (string) """ self.versionStr = ".".join([str(v) for v in pysvn.svn_version[:-1]]) self.version = pysvn.svn_version[:-1] return True, "" def vcsInit(self, vcsDir, noDialog=False): """ Public method used to initialize the subversion repository. The subversion repository has to be initialized from outside eric6 because the respective command always works locally. Therefore we always return TRUE without doing anything. @param vcsDir name of the VCS directory (string) @param noDialog flag indicating quiet operations (boolean) @return always TRUE """ return True def vcsConvertProject(self, vcsDataDict, project): """ Public method to convert an uncontrolled project to a version controlled project. @param vcsDataDict dictionary of data required for the conversion @param project reference to the project object """ success = self.vcsImport(vcsDataDict, project.ppath)[0] if not success: E5MessageBox.critical( self.__ui, self.tr("Create project in repository"), self.tr( """The project could not be created in the repository.""" """ Maybe the given repository doesn't exist or the""" """ repository server is down.""")) else: cwdIsPpath = False if os.getcwd() == project.ppath: os.chdir(os.path.dirname(project.ppath)) cwdIsPpath = True tmpProjectDir = "{0}_tmp".format(project.ppath) shutil.rmtree(tmpProjectDir, True) os.rename(project.ppath, tmpProjectDir) os.makedirs(project.ppath) self.vcsCheckout(vcsDataDict, project.ppath) if cwdIsPpath: os.chdir(project.ppath) self.vcsCommit(project.ppath, vcsDataDict["message"], True) pfn = project.pfile if not os.path.isfile(pfn): pfn += "z" if not os.path.isfile(pfn): E5MessageBox.critical( self.__ui, self.tr("New project"), self.tr( """The project could not be checked out of the""" """ repository.
""" """Restoring the original contents.""")) if os.getcwd() == project.ppath: os.chdir(os.path.dirname(project.ppath)) cwdIsPpath = True else: cwdIsPpath = False shutil.rmtree(project.ppath, True) os.rename(tmpProjectDir, project.ppath) project.pdata["VCS"] = ['None'] project.vcs = None project.setDirty(True) project.saveProject() project.closeProject() return shutil.rmtree(tmpProjectDir, True) project.closeProject(noSave=True) project.openProject(pfn) def vcsImport(self, vcsDataDict, projectDir, noDialog=False): """ Public method used to import the project into the Subversion repository. @param vcsDataDict dictionary of data required for the import @param projectDir project directory (string) @param noDialog flag indicating quiet operations @return flag indicating an execution without errors (boolean) and a flag indicating the version controll status (boolean) """ noDialog = False msg = vcsDataDict["message"] if not msg: msg = '***' vcsDir = self.svnNormalizeURL(vcsDataDict["url"]) if vcsDir.startswith('/'): vcsDir = 'file://{0}'.format(vcsDir) elif vcsDir[1] in ['|', ':']: vcsDir = 'file:///{0}'.format(vcsDir) project = vcsDir[vcsDir.rfind('/') + 1:] # create the dir structure to be imported into the repository tmpDir = '{0}_tmp'.format(projectDir) try: os.makedirs(tmpDir) if self.otherData["standardLayout"]: os.mkdir(os.path.join(tmpDir, project)) os.mkdir(os.path.join(tmpDir, project, 'branches')) os.mkdir(os.path.join(tmpDir, project, 'tags')) shutil.copytree( projectDir, os.path.join(tmpDir, project, 'trunk')) else: shutil.copytree(projectDir, os.path.join(tmpDir, project)) except OSError as e: if os.path.isdir(tmpDir): shutil.rmtree(tmpDir, True) return False, False locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(os.path.join(tmpDir, project)) opts = self.options['global'] recurse = "--non-recursive" not in opts url = self.__svnURL(vcsDir) client = self.getClient() if not noDialog: dlg = SvnDialog( self.tr('Importing project into Subversion repository'), "import{0} --message {1} .".format( (not recurse) and " --non-recursive" or "", msg), client) QApplication.processEvents() try: rev = client.import_(".", url, msg, recurse, ignore=True) status = True except pysvn.ClientError as e: status = False rev = None if not noDialog: dlg.showError(e.args[0]) locker.unlock() if not noDialog: rev and dlg.showMessage(self.tr("Imported revision {0}.\n") .format(rev.number)) dlg.finish() dlg.exec_() os.chdir(cwd) shutil.rmtree(tmpDir, True) return status, False def vcsCheckout(self, vcsDataDict, projectDir, noDialog=False): """ Public method used to check the project out of the Subversion repository. @param vcsDataDict dictionary of data required for the checkout @param projectDir project directory to create (string) @param noDialog flag indicating quiet operations @return flag indicating an execution without errors (boolean) """ noDialog = False try: tag = vcsDataDict["tag"] except KeyError: tag = None vcsDir = self.svnNormalizeURL(vcsDataDict["url"]) if vcsDir.startswith('/'): vcsDir = 'file://{0}'.format(vcsDir) elif vcsDir[1] in ['|', ':']: vcsDir = 'file:///{0}'.format(vcsDir) if self.otherData["standardLayout"]: if tag is None or tag == '': svnUrl = '{0}/trunk'.format(vcsDir) else: if not tag.startswith('tags') and \ not tag.startswith('branches'): type_, ok = QInputDialog.getItem( None, self.tr("Subversion Checkout"), self.tr( "The tag must be a normal tag (tags) or" " a branch tag (branches)." " Please select from the list."), self.tagTypeList, 0, False) if not ok: return False tag = '{0}/{1}'.format(type_, tag) svnUrl = '{0}/{1}'.format(vcsDir, tag) else: svnUrl = vcsDir opts = self.options['global'] + self.options['checkout'] recurse = "--non-recursive" not in opts url = self.__svnURL(svnUrl) client = self.getClient() if not noDialog: dlg = SvnDialog( self.tr('Checking project out of Subversion repository'), "checkout{0} {1} {2}".format( (not recurse) and " --non-recursive" or "", url, projectDir), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: client.checkout(url, projectDir, recurse) status = True except pysvn.ClientError as e: status = False if not noDialog: dlg.showError(e.args[0]) locker.unlock() if not noDialog: dlg.finish() dlg.exec_() return status def vcsExport(self, vcsDataDict, projectDir): """ Public method used to export a directory from the Subversion repository. @param vcsDataDict dictionary of data required for the checkout @param projectDir project directory to create (string) @return flag indicating an execution without errors (boolean) """ try: tag = vcsDataDict["tag"] except KeyError: tag = None vcsDir = self.svnNormalizeURL(vcsDataDict["url"]) if vcsDir.startswith('/') or vcsDir[1] == '|': vcsDir = 'file://{0}'.format(vcsDir) if self.otherData["standardLayout"]: if tag is None or tag == '': svnUrl = '{0}/trunk'.format(vcsDir) else: if not tag.startswith('tags') and \ not tag.startswith('branches'): type_, ok = QInputDialog.getItem( None, self.tr("Subversion Export"), self.tr( "The tag must be a normal tag (tags) or" " a branch tag (branches)." " Please select from the list."), self.tagTypeList, 0, False) if not ok: return False tag = '{0}/{1}'.format(type_, tag) svnUrl = '{0}/{1}'.format(vcsDir, tag) else: svnUrl = vcsDir opts = self.options['global'] recurse = "--non-recursive" not in opts url = self.__svnURL(svnUrl) client = self.getClient() dlg = SvnDialog( self.tr('Exporting project from Subversion repository'), "export --force{0} {1} {2}".format( (not recurse) and " --non-recursive" or "", url, projectDir), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: client.export(url, projectDir, force=True, recurse=recurse) status = True except pysvn.ClientError as e: status = False dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() return status def vcsCommit(self, name, message, noDialog=False): """ Public method used to make the change of a file/directory permanent in the Subversion repository. @param name file/directory name to be committed (string or list of strings) @param message message for this operation (string) @param noDialog flag indicating quiet operations """ if not noDialog and not message: # call CommitDialog and get message from there if self.__commitDialog is None: from .SvnCommitDialog import SvnCommitDialog self.__commitDialog = SvnCommitDialog( self.svnGetChangelists(), self.__ui) self.__commitDialog.accepted.connect(self.__vcsCommit_Step2) self.__commitDialog.show() self.__commitDialog.raise_() self.__commitDialog.activateWindow() self.__commitData["name"] = name self.__commitData["msg"] = message self.__commitData["noDialog"] = noDialog if noDialog: self.__vcsCommit_Step2() def __vcsCommit_Step2(self): """ Private slot performing the second step of the commit action. """ name = self.__commitData["name"] msg = self.__commitData["msg"] noDialog = self.__commitData["noDialog"] if not noDialog: # check, if there are unsaved changes, that should be committed if isinstance(name, list): nameList = name else: nameList = [name] ok = True for nam in nameList: # check for commit of the project if os.path.isdir(nam): project = e5App().getObject("Project") if nam == project.getProjectPath(): ok &= project.checkAllScriptsDirty( reportSyntaxErrors=True) and \ project.checkDirty() continue elif os.path.isfile(nam): editor = e5App().getObject("ViewManager")\ .getOpenEditor(nam) if editor: ok &= editor.checkDirty() if not ok: break if not ok: res = E5MessageBox.yesNo( self.__ui, self.tr("Commit Changes"), self.tr( """The commit affects files, that have unsaved""" """ changes. Shall the commit be continued?"""), icon=E5MessageBox.Warning) if not res: return if self.__commitDialog is not None: msg = self.__commitDialog.logMessage() if self.__commitDialog.hasChangelists(): changelists, keepChangelists = \ self.__commitDialog.changelistsData() else: changelists, keepChangelists = [], False self.__commitDialog.deleteLater() self.__commitDialog = None else: changelists, keepChangelists = [], False if not msg: msg = '***' if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) fnames = [fname] if self.svnGetReposName(dname).startswith('http') or \ self.svnGetReposName(dname).startswith('svn'): noDialog = False locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) opts = self.options['global'] + self.options['commit'] recurse = "--non-recursive" not in opts keeplocks = "--keep-locks" in opts client = self.getClient() if not noDialog: dlg = SvnDialog( self.tr('Commiting changes to Subversion repository'), "commit{0}{1}{2}{3} --message {4} {5}".format( (not recurse) and " --non-recursive" or "", keeplocks and " --keep-locks" or "", keepChangelists and " --keep-changelists" or "", changelists and " --changelist ".join([""] + changelists) or "", msg, " ".join(fnames)), client) QApplication.processEvents() try: if changelists: rev = client.checkin(fnames, msg, recurse=recurse, keep_locks=keeplocks, keep_changelist=keepChangelists, changelists=changelists) else: rev = client.checkin(fnames, msg, recurse=recurse, keep_locks=keeplocks) except pysvn.ClientError as e: rev = None if not noDialog: dlg.showError(e.args[0]) locker.unlock() if not noDialog: rev and dlg.showMessage(self.tr("Committed revision {0}.") .format(rev.number)) dlg.finish() dlg.exec_() os.chdir(cwd) self.committed.emit() self.checkVCSStatus() def vcsUpdate(self, name, noDialog=False): """ Public method used to update a file/directory with the Subversion repository. @param name file/directory name to be updated (string or list of strings) @param noDialog flag indicating quiet operations (boolean) @return flag indicating, that the update contained an add or delete (boolean) """ if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) fnames = [fname] locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) opts = self.options['global'] + self.options['update'] recurse = "--non-recursive" not in opts client = self.getClient() if not noDialog: dlg = SvnDialog( self.tr('Synchronizing with the Subversion repository'), "update{0} {1}".format( (not recurse) and " --non-recursive" or "", " ".join(fnames)), client) QApplication.processEvents() try: client.update(fnames, recurse) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() if not noDialog: dlg.finish() dlg.exec_() res = dlg.hasAddOrDelete() else: res = False os.chdir(cwd) self.checkVCSStatus() return res def vcsAdd(self, name, isDir=False, noDialog=False): """ Public method used to add a file/directory to the Subversion repository. @param name file/directory name to be added (string) @param isDir flag indicating name is a directory (boolean) @param noDialog flag indicating quiet operations (boolean) """ if isinstance(name, list): if isDir: dname, fname = os.path.split(name[0]) else: dname, fnames = self.splitPathList(name) else: if isDir: dname, fname = os.path.split(name) else: dname, fname = self.splitPath(name) names = [] tree = [] wdir = dname if self.__wcng: repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return # oops, project is not version controlled while os.path.normcase(dname) != os.path.normcase(repodir) and \ (os.path.normcase(dname) not in self.statusCache or self.statusCache[os.path.normcase(dname)] == self.canBeAdded): # add directories recursively, if they aren't in the # repository already tree.insert(-1, dname) dname = os.path.dirname(dname) wdir = dname else: while not os.path.exists(os.path.join(dname, self.adminDir)): # add directories recursively, if they aren't in the # repository already tree.insert(-1, dname) dname = os.path.dirname(dname) wdir = dname names.extend(tree) if isinstance(name, list): tree2 = [] for n in name: d = os.path.dirname(n) if self.__wcng: repodir = d while not os.path.isdir( os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return # oops, project is not version controlled while (os.path.normcase(d) != os.path.normcase(repodir)) and \ (d not in tree2 + tree) and \ (os.path.normcase(d) not in self.statusCache or self.statusCache[os.path.normcase(d)] == self.canBeAdded): tree2.append(d) d = os.path.dirname(d) else: while not os.path.exists(os.path.join(d, self.adminDir)): if d in tree2 + tree: break tree2.append(d) d = os.path.dirname(d) tree2.reverse() names.extend(tree2) names.extend(name) else: names.append(name) locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(wdir) opts = self.options['global'] + self.options['add'] recurse = False force = "--force" in opts or noDialog noignore = "--no-ignore" in opts client = self.getClient() if not noDialog: dlg = SvnDialog( self.tr('Adding files/directories to the Subversion' ' repository'), "add --non-recursive{0}{1} {2}".format( force and " --force" or "", noignore and " --no-ignore" or "", " ".join(names)), client) QApplication.processEvents() try: client.add(names, recurse=recurse, force=force, ignore=not noignore) except pysvn.ClientError as e: if not noDialog: dlg.showError(e.args[0]) locker.unlock() if not noDialog: dlg.finish() dlg.exec_() os.chdir(cwd) def vcsAddBinary(self, name, isDir=False): """ Public method used to add a file/directory in binary mode to the Subversion repository. @param name file/directory name to be added (string) @param isDir flag indicating name is a directory (boolean) """ self.vcsAdd(name, isDir) def vcsAddTree(self, path): """ Public method to add a directory tree rooted at path to the Subversion repository. @param path root directory of the tree to be added (string or list of strings)) """ tree = [] if isinstance(path, list): dname, fnames = self.splitPathList(path) for n in path: d = os.path.dirname(n) if self.__wcng: repodir = d while not os.path.isdir( os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return # oops, project is not version controlled while (os.path.normcase(d) != os.path.normcase(repodir)) and \ (d not in tree) and \ (os.path.normcase(d) not in self.statusCache or self.statusCache[os.path.normcase(d)] == self.canBeAdded): tree.append(d) d = os.path.dirname(d) else: while not os.path.exists(os.path.join(d, self.adminDir)): # add directories recursively, # if they aren't in the repository already if d in tree: break tree.append(d) d = os.path.dirname(d) tree.reverse() else: dname, fname = os.path.split(path) if self.__wcng: repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return # oops, project is not version controlled while (os.path.normcase(dname) != os.path.normcase(repodir)) and \ (os.path.normcase(dname) not in self.statusCache or self.statusCache[os.path.normcase(dname)] == self.canBeAdded): # add directories recursively, if they aren't in the # repository already tree.insert(-1, dname) dname = os.path.dirname(dname) else: while not os.path.exists(os.path.join(dname, self.adminDir)): # add directories recursively, # if they aren't in the repository already tree.insert(-1, dname) dname = os.path.dirname(dname) if tree: self.vcsAdd(tree, True) names = [] if isinstance(path, list): names.extend(path) else: names.append(path) locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) opts = self.options['global'] + self.options['add'] recurse = True force = "--force" in opts ignore = "--ignore" in opts client = self.getClient() dlg = SvnDialog( self.tr('Adding directory trees to the Subversion repository'), "add{0}{1} {2}".format( force and " --force" or "", ignore and " --ignore" or "", " ".join(names)), client) QApplication.processEvents() try: client.add(names, recurse=recurse, force=force, ignore=ignore) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() os.chdir(cwd) def vcsRemove(self, name, project=False, noDialog=False): """ Public method used to remove a file/directory from the Subversion repository. The default operation is to remove the local copy as well. @param name file/directory name to be removed (string or list of strings)) @param project flag indicating deletion of a project tree (boolean) (not needed) @param noDialog flag indicating quiet operations @return flag indicating successfull operation (boolean) """ if not isinstance(name, list): name = [name] opts = self.options['global'] + self.options['remove'] force = "--force" in opts or noDialog client = self.getClient() if not noDialog: dlg = SvnDialog( self.tr('Removing files/directories from the Subversion' ' repository'), "remove{0} {1}".format( force and " --force" or "", " ".join(name)), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: client.remove(name, force=force) res = True except pysvn.ClientError as e: res = False if not noDialog: dlg.showError(e.args[0]) locker.unlock() if not noDialog: dlg.finish() dlg.exec_() return res def vcsMove(self, name, project, target=None, noDialog=False): """ Public method used to move a file/directory. @param name file/directory name to be moved (string) @param project reference to the project object @param target new name of the file/directory (string) @param noDialog flag indicating quiet operations @return flag indicating successfull operation (boolean) """ rx_prot = QRegExp('(file:|svn:|svn+ssh:|http:|https:).+') opts = self.options['global'] res = False if noDialog: if target is None: return False force = True accepted = True else: from .SvnCopyDialog import SvnCopyDialog dlg = SvnCopyDialog(name, None, True, "--force" in opts) accepted = (dlg.exec_() == QDialog.Accepted) if accepted: target, force = dlg.getData() if not target: return False if not rx_prot.exactMatch(target): isDir = os.path.isdir(name) else: isDir = False if accepted: client = self.getClient() if rx_prot.exactMatch(target): target = self.__svnURL(target) log = "Moving {0} to {1}".format(name, target) else: log = "" target = target if not noDialog: dlg = \ SvnDialog( self.tr('Moving {0}').format(name), "move{0}{1} {2} {3}".format( force and " --force" or "", log and (" --message {0}".format(log)) or "", name, target), client, log=log) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: client.move(name, target, force=force) res = True except pysvn.ClientError as e: res = False if not noDialog: dlg.showError(e.args[0]) locker.unlock() if not noDialog: dlg.finish() dlg.exec_() if res and not rx_prot.exactMatch(target): if target.startswith(project.getProjectPath()): if isDir: project.moveDirectory(name, target) else: project.renameFileInPdata(name, target) else: if isDir: project.removeDirectory(name) else: project.removeFile(name) return res def vcsLog(self, name): """ Public method used to view the log of a file/directory from the Subversion repository. @param name file/directory name to show the log of (string) """ isFile = os.path.isfile(name) noEntries, ok = QInputDialog.getInt( None, self.tr("Subversion Log"), self.tr("Select number of entries to show."), self.getPlugin().getPreferences("LogLimit"), 1, 999999, 1) if ok: from .SvnLogDialog import SvnLogDialog self.log = SvnLogDialog(self, isFile=isFile) self.log.show() QApplication.processEvents() self.log.start(name, noEntries) def vcsDiff(self, name): """ Public method used to view the difference of a file/directory to the Subversion repository. If name is a directory and is the project directory, all project files are saved first. If name is a file (or list of files), which is/are being edited and has unsaved modification, they can be saved or the operation may be aborted. @param name file/directory name to be diffed (string) """ if isinstance(name, list): names = name[:] else: names = [name] for nam in names: if os.path.isfile(nam): editor = e5App().getObject("ViewManager").getOpenEditor(nam) if editor and not editor.checkDirty(): return else: project = e5App().getObject("Project") if nam == project.ppath and not project.saveAllScripts(): return from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self) self.diff.show() QApplication.processEvents() self.diff.start(name) def vcsStatus(self, name): """ Public method used to view the status of files/directories in the Subversion repository. @param name file/directory name(s) to show the status of (string or list of strings) """ from .SvnStatusDialog import SvnStatusDialog self.status = SvnStatusDialog(self) self.status.show() QApplication.processEvents() self.status.start(name) def vcsTag(self, name): """ Public method used to set the tag of a file/directory in the Subversion repository. @param name file/directory name to be tagged (string) """ dname, fname = self.splitPath(name) reposURL = self.svnGetReposName(dname) if reposURL is None: E5MessageBox.critical( self.__ui, self.tr("Subversion Error"), self.tr( """The URL of the project repository could not be""" """ retrieved from the working copy. The tag operation""" """ will be aborted""")) return if self.otherData["standardLayout"]: url = None else: url = self.svnNormalizeURL(reposURL) from .SvnTagDialog import SvnTagDialog dlg = SvnTagDialog(self.allTagsBranchesList, url, self.otherData["standardLayout"]) if dlg.exec_() == QDialog.Accepted: tag, tagOp = dlg.getParameters() if tag in self.allTagsBranchesList: self.allTagsBranchesList.remove(tag) self.allTagsBranchesList.insert(0, tag) else: return if self.otherData["standardLayout"]: rx_base = QRegExp('(.+)/(trunk|tags|branches).*') if not rx_base.exactMatch(reposURL): E5MessageBox.critical( self.__ui, self.tr("Subversion Error"), self.tr( """The URL of the project repository has an""" """ invalid format. The tag operation will""" """ be aborted""")) return reposRoot = rx_base.cap(1) if tagOp in [1, 4]: url = '{0}/tags/{1}'.format(reposRoot, Utilities.quote(tag)) elif tagOp in [2, 8]: url = '{0}/branches/{1}'.format( reposRoot, Utilities.quote(tag)) else: url = self.__svnURL(tag) self.tagName = tag client = self.getClient() rev = None if tagOp in [1, 2]: log = 'Created tag <{0}>'.format(self.tagName) dlg = SvnDialog( self.tr('Tagging {0} in the Subversion repository') .format(name), "copy --message {0} {1} {2}".format(log, reposURL, url), client, log=log) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: rev = client.copy(reposURL, url) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() else: log = 'Deleted tag <{0}>'.format(self.tagName) dlg = SvnDialog( self.tr('Tagging {0} in the Subversion repository') .format(name), "remove --message {0} {1}".format(log, url), client, log=log) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: rev = client.remove(url) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() rev and dlg.showMessage( self.tr("Revision {0}.\n").format(rev.number)) dlg.finish() dlg.exec_() def vcsRevert(self, name): """ Public method used to revert changes made to a file/directory. @param name file/directory name to be reverted (string) """ recurse = False if not isinstance(name, list): name = [name] if os.path.isdir(name[0]): recurse = True project = e5App().getObject("Project") names = [project.getRelativePath(nam) for nam in name] if names[0]: from UI.DeleteFilesConfirmationDialog import \ DeleteFilesConfirmationDialog dia = DeleteFilesConfirmationDialog( self.parent(), self.tr("Revert changes"), self.tr( "Do you really want to revert all changes to these files" " or directories?"), name) yes = dia.exec_() == QDialog.Accepted else: yes = E5MessageBox.yesNo( None, self.tr("Revert changes"), self.tr("""Do you really want to revert all changes of""" """ the project?""")) if yes: client = self.getClient() dlg = SvnDialog( self.tr('Reverting changes'), "revert {0} {1}".format( (not recurse) and " --non-recursive" or "", " ".join(name)), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: client.revert(name, recurse) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() self.checkVCSStatus() def vcsSwitch(self, name): """ Public method used to switch a directory to a different tag/branch. @param name directory name to be switched (string) @return flag indicating, that the switch contained an add or delete (boolean) """ dname, fname = self.splitPath(name) reposURL = self.svnGetReposName(dname) if reposURL is None: E5MessageBox.critical( self.__ui, self.tr("Subversion Error"), self.tr( """The URL of the project repository could not be""" """ retrieved from the working copy. The switch""" """ operation will be aborted""")) return False if self.otherData["standardLayout"]: url = None else: url = self.svnNormalizeURL(reposURL) from .SvnSwitchDialog import SvnSwitchDialog dlg = SvnSwitchDialog(self.allTagsBranchesList, url, self.otherData["standardLayout"]) if dlg.exec_() == QDialog.Accepted: tag, tagType = dlg.getParameters() if tag in self.allTagsBranchesList: self.allTagsBranchesList.remove(tag) self.allTagsBranchesList.insert(0, tag) else: return False if self.otherData["standardLayout"]: rx_base = QRegExp('(.+)/(trunk|tags|branches).*') if not rx_base.exactMatch(reposURL): E5MessageBox.critical( self.__ui, self.tr("Subversion Error"), self.tr( """The URL of the project repository has an""" """ invalid format. The switch operation will""" """ be aborted""")) return False reposRoot = rx_base.cap(1) tn = tag if tagType == 1: url = '{0}/tags/{1}'.format(reposRoot, Utilities.quote(tag)) elif tagType == 2: url = '{0}/branches/{1}'.format( reposRoot, Utilities.quote(tag)) elif tagType == 4: url = '{0}/trunk'.format(reposRoot) tn = 'HEAD' else: url = self.__svnURL(tag) tn = url client = self.getClient() dlg = SvnDialog(self.tr('Switching to {0}').format(tn), "switch {0} {1}".format(url, name), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: rev = client.switch(name, url) dlg.showMessage(self.tr("Revision {0}.\n").format(rev.number)) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() res = dlg.hasAddOrDelete() self.checkVCSStatus() return res def vcsMerge(self, name): """ Public method used to merge a URL/revision into the local project. @param name file/directory name to be merged (string) """ dname, fname = self.splitPath(name) opts = self.options['global'] from .SvnMergeDialog import SvnMergeDialog dlg = SvnMergeDialog(self.mergeList[0], self.mergeList[1], self.mergeList[2], "--force" in opts) if dlg.exec_() == QDialog.Accepted: urlrev1, urlrev2, target, force = dlg.getParameters() else: return # remember URL or revision if urlrev1 in self.mergeList[0]: self.mergeList[0].remove(urlrev1) self.mergeList[0].insert(0, urlrev1) if urlrev2 in self.mergeList[1]: self.mergeList[1].remove(urlrev2) self.mergeList[1].insert(0, urlrev2) rx_rev = QRegExp('\\d+|HEAD|head') locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) recurse = "--non-recursive" not in opts if rx_rev.exactMatch(urlrev1): if urlrev1 in ["HEAD", "head"]: revision1 = pysvn.Revision(pysvn.opt_revision_kind.head) rev1 = "HEAD" else: revision1 = pysvn.Revision( pysvn.opt_revision_kind.number, int(urlrev1)) rev1 = urlrev1 if urlrev2 in ["HEAD", "head"]: revision2 = pysvn.Revision(pysvn.opt_revision_kind.head) rev2 = "HEAD" else: revision2 = pysvn.Revision( pysvn.opt_revision_kind.number, int(urlrev2)) rev2 = urlrev2 if not target: url1 = name url2 = name else: url1 = target url2 = target # remember target if target in self.mergeList[2]: self.mergeList[2].remove(target) self.mergeList[2].insert(0, target) else: if "@" in urlrev1: url1, rev = urlrev1.split("@") if rev in ["HEAD", "head"]: revision1 = pysvn.Revision(pysvn.opt_revision_kind.head) rev1 = "HEAD" else: revision1 = pysvn.Revision( pysvn.opt_revision_kind.number, int(rev)) rev1 = rev else: url1 = urlrev1 revision1 = pysvn.Revision(pysvn.opt_revision_kind.unspecified) rev1 = "" if "@" in urlrev2: url2, rev = urlrev2.split("@") if rev in ["HEAD", "head"]: revision2 = pysvn.Revision(pysvn.opt_revision_kind.head) rev2 = "HEAD" else: revision2 = pysvn.Revision( pysvn.opt_revision_kind.number, int(rev)) rev2 = rev else: url2 = urlrev2 revision2 = pysvn.Revision(pysvn.opt_revision_kind.unspecified) rev2 = "" client = self.getClient() dlg = \ SvnDialog( self.tr('Merging {0}').format(name), "merge{0}{1} {2} {3} {4}".format( (not recurse) and " --non-recursive" or "", force and " --force" or "", "{0}{1}".format(url1, rev1 and ("@" + rev1) or ""), "{0}{1}".format(url2, rev2 and ("@" + rev2) or ""), fname), client) QApplication.processEvents() try: client.merge(url1, revision1, url2, revision2, fname, recurse=recurse, force=force) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() os.chdir(cwd) def vcsRegisteredState(self, name): """ Public method used to get the registered state of a file in the vcs. @param name filename to check (string) @return a combination of canBeCommited and canBeAdded """ if self.__wcng: return self.__vcsRegisteredState_wcng(name) else: return self.__vcsRegisteredState_wc(name) def __vcsRegisteredState_wcng(self, name): """ Private method used to get the registered state of a file in the vcs. This is the variant for subversion installations using the new working copy meta-data format. @param name filename to check (string) @return a combination of canBeCommited and canBeAdded """ if name.endswith(os.sep): name = name[:-1] name = os.path.normcase(name) dname, fname = self.splitPath(name) if fname == '.' and os.path.isdir(os.path.join(dname, self.adminDir)): return self.canBeCommitted if name in self.statusCache: return self.statusCache[name] name = os.path.normcase(name) states = {name: 0} states = self.vcsAllRegisteredStates(states, dname, False) if states[name] == self.canBeCommitted: return self.canBeCommitted else: return self.canBeAdded def __vcsRegisteredState_wc(self, name): """ Private method used to get the registered state of a file in the vcs. This is the variant for subversion installations using the old working copy meta-data format. @param name filename to check (string) @return a combination of canBeCommited and canBeAdded """ dname, fname = self.splitPath(name) if fname == '.': if os.path.isdir(os.path.join(dname, self.adminDir)): return self.canBeCommitted else: return self.canBeAdded name = os.path.normcase(name) states = {name: 0} states = self.vcsAllRegisteredStates(states, dname, False) if states[name] == self.canBeCommitted: return self.canBeCommitted else: return self.canBeAdded def vcsAllRegisteredStates(self, names, dname, shortcut=True): """ Public method used to get the registered states of a number of files in the vcs. Note: If a shortcut is to be taken, the code will only check, if the named directory has been scanned already. If so, it is assumed, that the states for all files has been populated by the previous run. @param names dictionary with all filenames to be checked as keys @param dname directory to check in (string) @param shortcut flag indicating a shortcut should be taken (boolean) @return the received dictionary completed with a combination of canBeCommited and canBeAdded or None in order to signal an error """ if self.__wcng: return self.__vcsAllRegisteredStates_wcng(names, dname, shortcut) else: return self.__vcsAllRegisteredStates_wc(names, dname, shortcut) def __vcsAllRegisteredStates_wcng(self, names, dname, shortcut=True): """ Private method used to get the registered states of a number of files in the vcs. This is the variant for subversion installations using the new working copy meta-data format. Note: If a shortcut is to be taken, the code will only check, if the named directory has been scanned already. If so, it is assumed, that the states for all files has been populated by the previous run. @param names dictionary with all filenames to be checked as keys @param dname directory to check in (string) @param shortcut flag indicating a shortcut should be taken (boolean) @return the received dictionary completed with a combination of canBeCommited and canBeAdded or None in order to signal an error """ if dname.endswith(os.sep): dname = dname[:-1] dname = os.path.normcase(dname) found = False for name in self.statusCache.keys(): if name in names: found = True names[name] = self.statusCache[name] if not found: # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return names from .SvnDialogMixin import SvnDialogMixin mixin = SvnDialogMixin() client = self.getClient() client.callback_get_login = \ mixin._clientLoginCallback client.callback_ssl_server_trust_prompt = \ mixin._clientSslServerTrustPromptCallback try: locker = QMutexLocker(self.vcsExecutionMutex) allFiles = client.status(dname, recurse=True, get_all=True, ignore=True, update=False) locker.unlock() dirs = [x for x in names.keys() if os.path.isdir(x)] for file in allFiles: # file.path is always unicode in Python 2 name = os.path.normcase(file.path) if self.__isVersioned(file): if name in names: names[name] = self.canBeCommitted dn = name while os.path.splitdrive(dn)[1] != os.sep and \ dn != repodir: dn = os.path.dirname(dn) if dn in self.statusCache and \ self.statusCache[dn] == self.canBeCommitted: break self.statusCache[dn] = self.canBeCommitted self.statusCache[name] = self.canBeCommitted if dirs: for d in dirs: if name.startswith(d): names[d] = self.canBeCommitted self.statusCache[d] = self.canBeCommitted dirs.remove(d) break else: self.statusCache[name] = self.canBeAdded except pysvn.ClientError: locker.unlock() # ignore pysvn errors return names def __vcsAllRegisteredStates_wc(self, names, dname, shortcut=True): """ Private method used to get the registered states of a number of files in the VCS. This is the variant for subversion installations using the old working copy meta-data format. Note: If a shortcut is to be taken, the code will only check, if the named directory has been scanned already. If so, it is assumed, that the states for all files has been populated by the previous run. @param names dictionary with all filenames to be checked as keys @param dname directory to check in (string) @param shortcut flag indicating a shortcut should be taken (boolean) @return the received dictionary completed with a combination of canBeCommited and canBeAdded or None in order to signal an error """ if not os.path.isdir(os.path.join(dname, self.adminDir)): # not under version control -> do nothing return names found = False for name in self.statusCache: if os.path.dirname(name) == dname: if shortcut: found = True break if name in names: found = True names[name] = self.statusCache[name] if not found: from .SvnDialogMixin import SvnDialogMixin mixin = SvnDialogMixin() client = self.getClient() client.callback_get_login = \ mixin._clientLoginCallback client.callback_ssl_server_trust_prompt = \ mixin._clientSslServerTrustPromptCallback try: locker = QMutexLocker(self.vcsExecutionMutex) allFiles = client.status(dname, recurse=True, get_all=True, ignore=True, update=False) locker.unlock() for file in allFiles: # file.path is always unicode in Python 2 name = os.path.normcase(file.path) if self.__isVersioned(file): if name in names: names[name] = self.canBeCommitted self.statusCache[name] = self.canBeCommitted else: self.statusCache[name] = self.canBeAdded except pysvn.ClientError: locker.unlock() # ignore pysvn errors return names def __isVersioned(self, status): """ Private method to check, if the given status indicates a versioned state. @param status status object to check (pysvn.PysvnStatus) @return flag indicating a versioned state (boolean) """ return status["text_status"] in [ pysvn.wc_status_kind.normal, pysvn.wc_status_kind.added, pysvn.wc_status_kind.missing, pysvn.wc_status_kind.deleted, pysvn.wc_status_kind.replaced, pysvn.wc_status_kind.modified, pysvn.wc_status_kind.merged, pysvn.wc_status_kind.conflicted, ] def clearStatusCache(self): """ Public method to clear the status cache. """ self.statusCache = {} def vcsInitConfig(self, project): """ Public method to initialize the VCS configuration. This method ensures, that eric specific files and directories are ignored. @param project reference to the project (Project) """ configPath = getConfigPath() if os.path.exists(configPath): amendConfig() else: createDefaultConfig() def vcsName(self): """ Public method returning the name of the vcs. @return always 'Subversion' (string) """ return "Subversion" def vcsCleanup(self, name): """ Public method used to cleanup the working copy. @param name directory name to be cleaned up (string) """ client = self.getClient() dlg = SvnDialog(self.tr('Cleaning up {0}').format(name), "cleanup {0}".format(name), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: client.cleanup(name) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() def vcsCommandLine(self, name): """ Public method used to execute arbitrary subversion commands. @param name directory name of the working directory (string) """ from .SvnCommandDialog import SvnCommandDialog dlg = SvnCommandDialog(self.commandHistory, self.wdHistory, name) if dlg.exec_() == QDialog.Accepted: command, wd = dlg.getData() commandList = Utilities.parseOptionString(command) # This moves any previous occurrence of these arguments to the head # of the list. if command in self.commandHistory: self.commandHistory.remove(command) self.commandHistory.insert(0, command) if wd in self.wdHistory: self.wdHistory.remove(wd) self.wdHistory.insert(0, wd) args = [] self.addArguments(args, commandList) from Plugins.VcsPlugins.vcsSubversion.SvnDialog import \ SvnDialog as SvnProcessDialog dia = SvnProcessDialog(self.tr('Subversion command')) res = dia.startProcess(args, wd) if res: dia.exec_() def vcsOptionsDialog(self, project, archive, editable=False, parent=None): """ Public method to get a dialog to enter repository info. @param project reference to the project object @param archive name of the project in the repository (string) @param editable flag indicating that the project name is editable (boolean) @param parent parent widget (QWidget) @return reference to the instantiated options dialog (SvnOptionsDialog) """ from .SvnOptionsDialog import SvnOptionsDialog return SvnOptionsDialog(self, project, parent) def vcsNewProjectOptionsDialog(self, parent=None): """ Public method to get a dialog to enter repository info for getting a new project. @param parent parent widget (QWidget) @return reference to the instantiated options dialog (SvnNewProjectOptionsDialog) """ from .SvnNewProjectOptionsDialog import SvnNewProjectOptionsDialog return SvnNewProjectOptionsDialog(self, parent) def vcsRepositoryInfos(self, ppath): """ Public method to retrieve information about the repository. @param ppath local path to get the repository infos (string) @return string with ready formated info for display (string) """ try: entry = self.getClient().info(ppath) except pysvn.ClientError as e: return e.args[0] if hasattr(pysvn, 'svn_api_version'): apiVersion = "{0} {1}".format( ".".join([str(v) for v in pysvn.svn_api_version[:3]]), pysvn.svn_api_version[3]) else: apiVersion = QCoreApplication.translate('subversion', "unknown") hmsz = time.strftime("%H:%M:%S %Z", time.localtime(entry.commit_time)) if sys.version_info[0] == 2: hmsz = hmsz.decode(sys.getfilesystemencoding()) return QCoreApplication.translate( 'subversion', """

Repository information

""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """
PySvn V.{0}
Subversion V.{1}
Subversion API V.{2}
URL{3}
Current revision{4}
Committed revision{5}
Committed date{6}
Comitted time{7}
Last author{8}
""" )\ .format(".".join([str(v) for v in pysvn.version]), ".".join([str(v) for v in pysvn.svn_version[:3]]), apiVersion, entry.url, entry.revision.number, entry.commit_revision.number, time.strftime( "%Y-%m-%d", time.localtime(entry.commit_time)), hmsz, entry.commit_author ) ########################################################################### ## Public Subversion specific methods are below. ########################################################################### def svnGetReposName(self, path): """ Public method used to retrieve the URL of the subversion repository path. @param path local path to get the svn repository path for (string) @return string with the repository path URL """ client = pysvn.Client() locker = QMutexLocker(self.vcsExecutionMutex) try: entry = client.info(path) url = entry.url except pysvn.ClientError: url = "" locker.unlock() return url def svnResolve(self, name): """ Public method used to resolve conflicts of a file/directory. @param name file/directory name to be resolved (string) """ if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) fnames = [fname] locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) opts = self.options['global'] recurse = "--non-recursive" not in opts client = self.getClient() dlg = SvnDialog(self.tr('Resolving conficts'), "resolved{0} {1}".format( (not recurse) and " --non-recursive" or "", " ".join(fnames)), client) QApplication.processEvents() try: for name in fnames: client.resolved(name, recurse=recurse) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() os.chdir(cwd) self.checkVCSStatus() def svnCopy(self, name, project): """ Public method used to copy a file/directory. @param name file/directory name to be copied (string) @param project reference to the project object @return flag indicating successfull operation (boolean) """ from .SvnCopyDialog import SvnCopyDialog rx_prot = QRegExp('(file:|svn:|svn+ssh:|http:|https:).+') dlg = SvnCopyDialog(name) res = False if dlg.exec_() == QDialog.Accepted: target, force = dlg.getData() client = self.getClient() if rx_prot.exactMatch(target): target = self.__svnURL(target) log = "Copying {0} to {1}".format(name, target) else: log = "" target = target dlg = \ SvnDialog( self.tr('Copying {0}').format(name), "copy{0} {1} {2}".format( log and (" --message {0}".format(log)) or "", name, target), client, log=log) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: client.copy(name, target) res = True except pysvn.ClientError as e: res = False dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() if res and \ not rx_prot.exactMatch(target) and \ target.startswith(project.getProjectPath()): if os.path.isdir(name): project.copyDirectory(name, target) else: project.appendFile(target) return res def svnListProps(self, name, recursive=False): """ Public method used to list the properties of a file/directory. @param name file/directory name (string or list of strings) @param recursive flag indicating a recursive list is requested """ from .SvnPropListDialog import SvnPropListDialog self.propList = SvnPropListDialog(self) self.propList.show() QApplication.processEvents() self.propList.start(name, recursive) def svnSetProp(self, name, recursive=False): """ Public method used to add a property to a file/directory. @param name file/directory name (string or list of strings) @param recursive flag indicating a recursive set is requested """ from .SvnPropSetDialog import SvnPropSetDialog dlg = SvnPropSetDialog(recursive) if dlg.exec_() == QDialog.Accepted: propName, propValue, recurse = dlg.getData() if not propName: E5MessageBox.critical( self.__ui, self.tr("Subversion Set Property"), self.tr( """You have to supply a property name. Aborting.""")) return if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) fnames = [fname] locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) opts = self.options['global'] skipchecks = "--skip-checks" in opts client = self.getClient() dlg = \ SvnDialog( self.tr('Subversion Set Property'), "propset{0}{1} {2} {3} {4}".format( recurse and " --recurse" or "", skipchecks and " --skip-checks" or "", propName, propValue, " ".join(fnames)), client) QApplication.processEvents() try: for name in fnames: client.propset(propName, propValue, name, recurse=recurse, skip_checks=skipchecks) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.showMessage(self.tr("Property set.")) dlg.finish() dlg.exec_() os.chdir(cwd) def svnDelProp(self, name, recursive=False): """ Public method used to delete a property of a file/directory. @param name file/directory name (string or list of strings) @param recursive flag indicating a recursive list is requested """ from .SvnPropDelDialog import SvnPropDelDialog dlg = SvnPropDelDialog(recursive) if dlg.exec_() == QDialog.Accepted: propName, recurse = dlg.getData() if not propName: E5MessageBox.critical( self.__ui, self.tr("Subversion Delete Property"), self.tr( """You have to supply a property name. Aborting.""")) return if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) fnames = [fname] locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) opts = self.options['global'] skipchecks = "--skip-checks" in opts client = self.getClient() dlg = \ SvnDialog( self.tr('Subversion Delete Property'), "propdel{0}{1} {2} {3}".format( recurse and " --recurse" or "", skipchecks and " --skip-checks" or "", propName, " ".join(fnames)), client) QApplication.processEvents() try: for name in fnames: client.propdel(propName, name, recurse=recurse, skip_checks=skipchecks) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.showMessage(self.tr("Property deleted.")) dlg.finish() dlg.exec_() os.chdir(cwd) def svnListTagBranch(self, path, tags=True): """ Public method used to list the available tags or branches. @param path directory name of the project (string) @param tags flag indicating listing of branches or tags (False = branches, True = tags) """ from .SvnTagBranchListDialog import SvnTagBranchListDialog self.tagbranchList = SvnTagBranchListDialog(self) self.tagbranchList.show() QApplication.processEvents() res = self.tagbranchList.start(path, tags) if res: if tags: self.tagsList = self.tagbranchList.getTagList() if not self.showedTags: self.allTagsBranchesList = \ self.allTagsBranchesList + self.tagsList self.showedTags = True elif not tags: self.branchesList = self.tagbranchList.getTagList() if not self.showedBranches: self.allTagsBranchesList = \ self.allTagsBranchesList + self.branchesList self.showedBranches = True def svnBlame(self, name): """ Public method to show the output of the svn blame command. @param name file name to show the blame for (string) """ from .SvnBlameDialog import SvnBlameDialog self.blame = SvnBlameDialog(self) self.blame.show() QApplication.processEvents() self.blame.start(name) def svnExtendedDiff(self, name): """ Public method used to view the difference of a file/directory to the Subversion repository. If name is a directory and is the project directory, all project files are saved first. If name is a file (or list of files), which is/are being edited and has unsaved modification, they can be saved or the operation may be aborted. This method gives the chance to enter the revisions to be compared. @param name file/directory name to be diffed (string) """ if isinstance(name, list): names = name[:] else: names = [name] for nam in names: if os.path.isfile(nam): editor = e5App().getObject("ViewManager").getOpenEditor(nam) if editor and not editor.checkDirty(): return else: project = e5App().getObject("Project") if nam == project.ppath and not project.saveAllScripts(): return from .SvnRevisionSelectionDialog import SvnRevisionSelectionDialog dlg = SvnRevisionSelectionDialog() if dlg.exec_() == QDialog.Accepted: revisions = dlg.getRevisions() from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self) self.diff.show() QApplication.processEvents() self.diff.start(name, revisions) def svnUrlDiff(self, name): """ Public method used to view the difference of a file/directory of two repository URLs. If name is a directory and is the project directory, all project files are saved first. If name is a file (or list of files), which is/are being edited and has unsaved modification, they can be saved or the operation may be aborted. This method gives the chance to enter the revisions to be compared. @param name file/directory name to be diffed (string) """ if isinstance(name, list): names = name[:] else: names = [name] for nam in names: if os.path.isfile(nam): editor = e5App().getObject("ViewManager").getOpenEditor(nam) if editor and not editor.checkDirty(): return else: project = e5App().getObject("Project") if nam == project.ppath and not project.saveAllScripts(): return dname = self.splitPath(names[0])[0] from .SvnUrlSelectionDialog import SvnUrlSelectionDialog dlg = SvnUrlSelectionDialog(self, self.tagsList, self.branchesList, dname) if dlg.exec_() == QDialog.Accepted: urls, summary = dlg.getURLs() from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self) self.diff.show() QApplication.processEvents() self.diff.start(name, urls=urls, summary=summary) def __svnGetFileForRevision(self, name, rev=""): """ Private method to get a file for a specific revision from the repository. @param name file name to get from the repository (string) @keyparam rev revision to retrieve (integer or string) @return contents of the file (string) and an error message (string) """ output = "" error = "" client = self.getClient() try: if rev: if isinstance(rev, int) or rev.isdecimal(): rev = pysvn.Revision( pysvn.opt_revision_kind.number, int(rev)) elif rev.startswith("{"): dateStr = rev[1:-1] secs = QDateTime.fromString(dateStr, Qt.ISODate).toTime_t() rev = pysvn.Revision(pysvn.opt_revision_kind.date, secs) elif rev == "HEAD": rev = pysvn.Revision(pysvn.opt_revision_kind.head) elif rev == "COMMITTED": rev = pysvn.Revision(pysvn.opt_revision_kind.committed) elif rev == "BASE": rev = pysvn.Revision(pysvn.opt_revision_kind.base) elif rev == "WORKING": rev = pysvn.Revision(pysvn.opt_revision_kind.working) elif rev == "PREV": rev = pysvn.Revision(pysvn.opt_revision_kind.previous) else: rev = pysvn.Revision(pysvn.opt_revision_kind.unspecified) output = client.cat(name, revision=rev) else: output = client.cat(name) output = output.decode('utf-8') except pysvn.ClientError as e: error = str(e) return output, error def svnSbsDiff(self, name, extended=False, revisions=None): """ Public method used to view the difference of a file to the Mercurial repository side-by-side. @param name file name to be diffed (string) @keyparam extended flag indicating the extended variant (boolean) @keyparam revisions tuple of two revisions (tuple of strings) @exception ValueError raised to indicate an invalid name parameter type """ if isinstance(name, list): raise ValueError("Wrong parameter type") if extended: from .SvnRevisionSelectionDialog import SvnRevisionSelectionDialog dlg = SvnRevisionSelectionDialog() if dlg.exec_() == QDialog.Accepted: rev1, rev2 = dlg.getRevisions() if rev1 == "WORKING": rev1 = "" if rev2 == "WORKING": rev2 = "" elif revisions: rev1, rev2 = revisions[0], revisions[1] else: rev1, rev2 = "", "" output1, error = self.__svnGetFileForRevision(name, rev=rev1) if error: E5MessageBox.critical( self.__ui, self.tr("Subversion Side-by-Side Difference"), error) return name1 = "{0} (rev. {1})".format(name, rev1 and rev1 or ".") if rev2: output2, error = self.__svnGetFileForRevision(name, rev=rev2) if error: E5MessageBox.critical( self.__ui, self.tr("Subversion Side-by-Side Difference"), error) return name2 = "{0} (rev. {1})".format(name, rev2) else: try: f1 = open(name, "r", encoding="utf-8") output2 = f1.read() f1.close() name2 = name except IOError: E5MessageBox.critical( self.__ui, self.tr("Subversion Side-by-Side Difference"), self.tr( """

The file {0} could not be read.

""") .format(name)) return if self.sbsDiff is None: from UI.CompareDialog import CompareDialog self.sbsDiff = CompareDialog() self.sbsDiff.show() self.sbsDiff.compare(output1, output2, name1, name2) def vcsLogBrowser(self, name, isFile=False): """ Public method used to browse the log of a file/directory from the Subversion repository. @param name file/directory name to show the log of (string) @param isFile flag indicating log for a file is to be shown (boolean) """ if self.logBrowser is None: from .SvnLogBrowserDialog import SvnLogBrowserDialog self.logBrowser = SvnLogBrowserDialog(self) self.logBrowser.show() QApplication.processEvents() self.logBrowser.start(name, isFile=isFile) def svnLock(self, name, stealIt=False, parent=None): """ Public method used to lock a file in the Subversion repository. @param name file/directory name to be locked (string or list of strings) @param stealIt flag indicating a forced operation (boolean) @param parent reference to the parent object of the subversion dialog (QWidget) """ comment, ok = QInputDialog.getText( None, self.tr("Subversion Lock"), self.tr("Enter lock comment"), QLineEdit.Normal) if not ok: return if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) fnames = [fname] locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) client = self.getClient() dlg = \ SvnDialog( self.tr('Locking in the Subversion repository'), "lock{0}{1} {2}".format( stealIt and " --force" or "", comment and (" --message {0}".format(comment)) or "", " ".join(fnames)), client, parent=parent) QApplication.processEvents() try: client.lock(fnames, comment, force=stealIt) except pysvn.ClientError as e: dlg.showError(e.args[0]) except AttributeError as e: dlg.showError(str(e)) locker.unlock() dlg.finish() dlg.exec_() os.chdir(cwd) def svnUnlock(self, name, breakIt=False, parent=None): """ Public method used to unlock a file in the Subversion repository. @param name file/directory name to be unlocked (string or list of strings) @param breakIt flag indicating a forced operation (boolean) @param parent reference to the parent object of the subversion dialog (QWidget) """ if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) fnames = [fname] locker = QMutexLocker(self.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) client = self.getClient() dlg = \ SvnDialog( self.tr('Unlocking in the Subversion repository'), "unlock{0} {1}".format( breakIt and " --force" or "", " ".join(fnames)), client, parent=parent) QApplication.processEvents() try: client.unlock(fnames, force=breakIt) except pysvn.ClientError as e: dlg.showError(e.args[0]) except AttributeError as e: dlg.showError(str(e)) locker.unlock() dlg.finish() dlg.exec_() os.chdir(cwd) def svnInfo(self, projectPath, name): """ Public method to show repository information about a file or directory. @param projectPath path name of the project (string) @param name file/directory name relative to the project (string) """ from .SvnInfoDialog import SvnInfoDialog dlg = SvnInfoDialog(self) dlg.start(projectPath, name) dlg.exec_() def svnRelocate(self, projectPath): """ Public method to relocate the working copy to a new repository URL. @param projectPath path name of the project (string) """ from .SvnRelocateDialog import SvnRelocateDialog currUrl = self.svnGetReposName(projectPath) dlg = SvnRelocateDialog(currUrl) if dlg.exec_() == QDialog.Accepted: newUrl, inside = dlg.getData() if inside: msg = "switch {0} {1}".format(newUrl, projectPath) else: msg = "relocate {0} {1} {2}".format(currUrl, newUrl, projectPath) client = self.getClient() dlg = \ SvnDialog(self.tr('Relocating'), msg, client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: if inside: client.switch(projectPath, newUrl) else: client.relocate(currUrl, newUrl, projectPath, recurse=True) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() def svnRepoBrowser(self, projectPath=None): """ Public method to open the repository browser. @param projectPath path name of the project (string) """ if projectPath: url = self.svnGetReposName(projectPath) else: url = None if url is None: url, ok = QInputDialog.getText( None, self.tr("Repository Browser"), self.tr("Enter the repository URL."), QLineEdit.Normal) if not ok or not url: return from .SvnRepoBrowserDialog import SvnRepoBrowserDialog self.repoBrowser = SvnRepoBrowserDialog(self) self.repoBrowser.start(url) def svnRemoveFromChangelist(self, names): """ Public method to remove a file or directory from its changelist. Note: Directories will be removed recursively. @param names name or list of names of file or directory to remove (string) """ if not isinstance(names, list): names = [names] client = self.getClient() dlg = \ SvnDialog(self.tr('Remove from changelist'), "changelist --remove {0}".format(" ".join(names)), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: for name in names: client.remove_from_changelists(name) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() def svnAddToChangelist(self, names): """ Public method to add a file or directory to a changelist. Note: Directories will be added recursively. @param names name or list of names of file or directory to add (string) """ if not isinstance(names, list): names = [names] clname, ok = QInputDialog.getItem( None, self.tr("Add to changelist"), self.tr("Enter name of the changelist:"), sorted(self.svnGetChangelists()), 0, True) if not ok or not clname: return client = self.getClient() dlg = \ SvnDialog(self.tr('Add to changelist'), "changelist {0}".format(" ".join(names)), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: for name in names: client.add_to_changelist(name, clname, depth=pysvn.depth.infinity) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() def svnShowChangelists(self, path): """ Public method used to inspect the change lists defined for the project. @param path directory name to show change lists for (string) """ from .SvnChangeListsDialog import SvnChangeListsDialog self.changeLists = SvnChangeListsDialog(self) self.changeLists.show() QApplication.processEvents() self.changeLists.start(path) def svnGetChangelists(self): """ Public method to get a list of all defined change lists. @return list of defined change list names (list of strings) """ changelists = [] client = self.getClient() if hasattr(client, 'get_changelist'): ppath = e5App().getObject("Project").getProjectPath() locker = QMutexLocker(self.vcsExecutionMutex) try: entries = client.get_changelist(ppath, depth=pysvn.depth.infinity) for entry in entries: changelist = entry[1] if sys.version_info[0] == 2: changelist = changelist.decode('utf-8') if changelist not in changelists: changelists.append(changelist) except pysvn.ClientError: pass locker.unlock() return changelists def svnUpgrade(self, path): """ Public method to upgrade the working copy format. @param path directory name to show change lists for (string) """ client = self.getClient() dlg = \ SvnDialog(self.tr('Upgrade'), "upgrade {0}".format(path), client) QApplication.processEvents() locker = QMutexLocker(self.vcsExecutionMutex) try: client.upgrade(path) except pysvn.ClientError as e: dlg.showError(e.args[0]) locker.unlock() dlg.finish() dlg.exec_() ########################################################################### ## Private Subversion specific methods are below. ########################################################################### def __svnURL(self, url): """ Private method to format a url for subversion. @param url unformatted url string (string) @return properly formated url for subversion (string) """ url = self.svnNormalizeURL(url) url = url.split(':', 2) if len(url) == 3: scheme = url[0] host = url[1] port, path = url[2].split("/", 1) return "{0}:{1}:{2}/{3}".format(scheme, host, port, Utilities.quote(path)) else: scheme = url[0] if scheme == "file": return "{0}:{1}".format(scheme, Utilities.quote(url[1])) else: try: host, path = url[1][2:].split("/", 1) except ValueError: host = url[1][2:] path = "" return "{0}://{1}/{2}".format(scheme, host, Utilities.quote(path)) def svnNormalizeURL(self, url): """ Public method to normalize a url for subversion. @param url url string (string) @return properly normalized url for subversion (string) """ protocol, url = url.split("://", 1) if url.startswith("\\\\"): url = url[2:] if protocol == "file": url = os.path.normcase(url) if url[1] == ":": url = url.replace(":", "|", 1) url = url.replace('\\', '/') if url.endswith('/'): url = url[:-1] if not url.startswith("/") and url[1] in [":", "|"]: url = "/{0}".format(url) return "{0}://{1}".format(protocol, url) ########################################################################### ## Methods to get the helper objects are below. ########################################################################### def vcsGetProjectBrowserHelper(self, browser, project, isTranslationsBrowser=False): """ Public method to instanciate a helper object for the different project browsers. @param browser reference to the project browser object @param project reference to the project object @param isTranslationsBrowser flag indicating, the helper is requested for the translations browser (this needs some special treatment) @return the project browser helper object """ from .ProjectBrowserHelper import SvnProjectBrowserHelper return SvnProjectBrowserHelper(self, browser, project, isTranslationsBrowser) def vcsGetProjectHelper(self, project): """ Public method to instanciate a helper object for the project. @param project reference to the project object @return the project helper object """ helper = self.__plugin.getProjectHelper() helper.setObjects(self, project) self.__wcng = \ os.path.exists( os.path.join(project.getProjectPath(), ".svn", "format")) or \ os.path.exists( os.path.join(project.getProjectPath(), "_svn", "format")) or \ os.path.exists( os.path.join(project.getProjectPath(), ".svn", "wc.db")) or \ os.path.exists( os.path.join(project.getProjectPath(), "_svn", "wc.db")) return helper ########################################################################### ## Status Monitor Thread methods ########################################################################### def _createStatusMonitorThread(self, interval, project): """ Protected method to create an instance of the VCS status monitor thread. @param interval check interval for the monitor thread in seconds (integer) @param project reference to the project object @return reference to the monitor thread (QThread) """ from .SvnStatusMonitorThread import SvnStatusMonitorThread return SvnStatusMonitorThread(interval, project, self) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnInfoDialog.py0000644000175000017500000002012412537064320023033 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show repository related information for a file/directory. """ from __future__ import unicode_literals import os import sys import pysvn from PyQt5.QtCore import Qt, QMutexLocker from PyQt5.QtWidgets import QDialog, QApplication from .SvnUtilities import formatTime from .SvnDialogMixin import SvnDialogMixin from VCS.Ui_RepositoryInfoDialog import Ui_VcsRepositoryInfoDialog class SvnInfoDialog(QDialog, SvnDialogMixin, Ui_VcsRepositoryInfoDialog): """ Class implementing a dialog to show repository related information for a file/directory. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnInfoDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.setWindowFlags(Qt.Window) self.vcs = vcs self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback self.show() QApplication.processEvents() def start(self, projectPath, fn): """ Public slot to start the svn info command. @param projectPath path name of the project (string) @param fn file or directory name relative to the project (string) """ locker = QMutexLocker(self.vcs.vcsExecutionMutex) cwd = os.getcwd() os.chdir(projectPath) try: entries = self.client.info2(fn, recurse=False) infoStr = "" for path, info in entries: if sys.version_info[0] == 2: path = path.decode('utf-8') infoStr += self.tr( "" "").format(path) if info['URL']: infoStr += self.tr( "")\ .format(info['URL']) if info['rev']: infoStr += self.tr( "")\ .format(info['rev'].number) if info['repos_root_URL']: infoStr += self.tr( "" "").format(info['repos_root_URL']) if info['repos_UUID']: infoStr += self.tr( "" "").format(info['repos_UUID']) if info['last_changed_author']: infoStr += self.tr( "" "")\ .format(info['last_changed_author']) if info['last_changed_date']: infoStr += self.tr( "" "")\ .format(formatTime(info['last_changed_date'])) if info['last_changed_rev'] and \ info['last_changed_rev'].kind == \ pysvn.opt_revision_kind.number: infoStr += self.tr( "" "")\ .format(info['last_changed_rev'].number) if info['kind']: if info['kind'] == pysvn.node_kind.file: nodeKind = self.tr("file") elif info['kind'] == pysvn.node_kind.dir: nodeKind = self.tr("directory") elif info['kind'] == pysvn.node_kind.none: nodeKind = self.tr("none") else: nodeKind = self.tr("unknown") infoStr += self.tr( "")\ .format(nodeKind) if info['lock']: lockInfo = info['lock'] infoStr += self.tr( "")\ .format(lockInfo['owner']) infoStr += self.tr( "" "")\ .format(formatTime(lockInfo['creation_date'])) if lockInfo['expiration_date'] is not None: infoStr += self.tr( "" "")\ .format(formatTime(lockInfo['expiration_date'])) infoStr += self.tr( "")\ .format(lockInfo['token']) infoStr += self.tr( "")\ .format(lockInfo['comment']) if info['wc_info']: wcInfo = info['wc_info'] if wcInfo['schedule']: if wcInfo['schedule'] == pysvn.wc_schedule.normal: schedule = self.tr("normal") elif wcInfo['schedule'] == pysvn.wc_schedule.add: schedule = self.tr("add") elif wcInfo['schedule'] == pysvn.wc_schedule.delete: schedule = self.tr("delete") elif wcInfo['schedule'] == pysvn.wc_schedule.replace: schedule = self.tr("replace") infoStr += self.tr( "")\ .format(schedule) if wcInfo['copyfrom_url']: infoStr += self.tr( "" "")\ .format(wcInfo['copyfrom_url']) infoStr += self.tr( "" "")\ .format(wcInfo['copyfrom_rev'].number) if wcInfo['text_time']: infoStr += self.tr( "" "")\ .format(formatTime(wcInfo['text_time'])) if wcInfo['prop_time']: infoStr += self.tr( "" "")\ .format(formatTime(wcInfo['prop_time'])) if wcInfo['checksum']: infoStr += self.tr( "")\ .format(wcInfo['checksum']) infoStr += "
Path (relative to project):{0}
Url:{0}
Revision:{0}
Repository root URL:{0}
Repository UUID:{0}
Last changed author:{0}
Last Changed Date:{0}
Last changed revision:{0}
Node kind:{0}
Lock Owner:{0}
Lock Creation Date:{0}
Lock Expiration Date:{0}
Lock Token:{0}
Lock Comment:{0}
Schedule:{0}
Copied From URL:{0}
Copied From Rev:{0}
Text Last Updated:{0}
Properties Last Updated:{0}
Checksum:{0}
" self.infoBrowser.setHtml(infoStr) except pysvn.ClientError as e: self.__showError(e.args[0]) locker.unlock() os.chdir(cwd) def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ infoStr = "

{0}

".format(msg) self.infoBrowser.setHtml(infoStr) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnOptionsDialog.ui0000644000175000017500000001246112263303613023562 0ustar piotrpiotr SvnOptionsDialog 0 0 565 169 Repository Infos <b>Repository Infos Dialog</b> <p>Enter the various infos into the entry fields. These values are used to generate a new project in the repository. If the checkbox is selected, the URL must end in the project name. A directory tree with project/tags, project/branches and project/trunk will be generated in the repository. If the checkbox is not selected, the URL must contain the complete path in the repository.</p> <p>For remote repositories the URL must contain the hostname.</p> true Log &Message: vcsLogEdit Select, if the standard repository layout (projectdir/trunk, projectdir/tags, projectdir/branches) should be generated Create standard repository &layout Alt+L true Select the protocol to access the repository &URL: vcsUrlEdit Enter the log message for the new project. <b>Log Message</b> <p>Enter the log message to be used for the new project.</p> new project started &Protocol: protocolCombo Enter the url path of the module in the repository (without protocol part) <b>URL</b><p>Enter the URL to the module. For a repository with standard layout, this must not contain the trunk, tags or branches part.</p> Select the repository url via a directory selection dialog or the repository browser Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource protocolCombo vcsUrlEdit vcsUrlButton vcsLogEdit layoutCheckBox buttonBox accepted() SvnOptionsDialog accept() 24 130 24 151 buttonBox rejected() SvnOptionsDialog reject() 104 135 104 148 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnCopyDialog.py0000644000175000017500000000670012451233371023055 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a copy operation. """ from __future__ import unicode_literals import os.path from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter, E5DirCompleter from E5Gui import E5FileDialog from .Ui_SvnCopyDialog import Ui_SvnCopyDialog import Utilities import UI.PixmapCache class SvnCopyDialog(QDialog, Ui_SvnCopyDialog): """ Class implementing a dialog to enter the data for a copy or rename operation. """ def __init__(self, source, parent=None, move=False, force=False): """ Constructor @param source name of the source file/directory (string) @param parent parent widget (QWidget) @param move flag indicating a move operation (boolean) @param force flag indicating a forced operation (boolean) """ super(SvnCopyDialog, self).__init__(parent) self.setupUi(self) self.dirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.source = source if os.path.isdir(self.source): self.targetCompleter = E5DirCompleter(self.targetEdit) else: self.targetCompleter = E5FileCompleter(self.targetEdit) if move: self.setWindowTitle(self.tr('Subversion Move')) else: self.forceCheckBox.setEnabled(False) self.forceCheckBox.setChecked(force) self.sourceEdit.setText(source) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public method to retrieve the copy data. @return the target name (string) and a flag indicating the operation should be enforced (boolean) """ target = self.targetEdit.text() if not os.path.isabs(target): sourceDir = os.path.dirname(self.sourceEdit.text()) target = os.path.join(sourceDir, target) return (Utilities.toNativeSeparators(target), self.forceCheckBox.isChecked()) @pyqtSlot() def on_dirButton_clicked(self): """ Private slot to handle the button press for selecting the target via a selection dialog. """ if os.path.isdir(self.source): target = E5FileDialog.getExistingDirectory( None, self.tr("Select target"), self.targetEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) else: target = E5FileDialog.getSaveFileName( None, self.tr("Select target"), self.targetEdit.text(), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if target: self.targetEdit.setText(Utilities.toNativeSeparators(target)) @pyqtSlot(str) def on_targetEdit_textChanged(self, txt): """ Private slot to handle changes of the target. @param txt contents of the target edit (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( os.path.isabs(txt) or os.path.dirname(txt) == "") eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnStatusMonitorThread.py0000644000175000017500000001433012451233371025004 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the VCS status monitor thread class for Subversion. """ from __future__ import unicode_literals import os import pysvn from VCS.StatusMonitorThread import VcsStatusMonitorThread import Preferences class SvnStatusMonitorThread(VcsStatusMonitorThread): """ Class implementing the VCS status monitor thread class for Subversion. """ def __init__(self, interval, project, vcs, parent=None): """ Constructor @param interval new interval in seconds (integer) @param project reference to the project object (Project) @param vcs reference to the version control object @param parent reference to the parent object (QObject) """ VcsStatusMonitorThread.__init__(self, interval, project, vcs, parent) def _performMonitor(self): """ Protected method implementing the monitoring action. This method populates the statusList member variable with a list of strings giving the status in the first column and the path relative to the project directory starting with the third column. The allowed status flags are:
  • "A" path was added but not yet comitted
  • "M" path has local changes
  • "O" path was removed
  • "R" path was deleted and then re-added
  • "U" path needs an update
  • "Z" path contains a conflict
  • " " path is back at normal
@return tuple of flag indicating successful operation (boolean) and a status message in case of non successful operation (string) """ self.shouldUpdate = False client = pysvn.Client() client.exception_style = 1 client.callback_get_login = \ self.__clientLoginCallback client.callback_ssl_server_trust_prompt = \ self.__clientSslServerTrustPromptCallback cwd = os.getcwd() os.chdir(self.projectDir) try: allFiles = client.status( '.', recurse=True, get_all=True, ignore=True, update=not Preferences.getVCS("MonitorLocalStatus")) states = {} for file in allFiles: uptodate = True if file.repos_text_status != pysvn.wc_status_kind.none: uptodate = uptodate and \ file.repos_text_status != pysvn.wc_status_kind.modified if file.repos_prop_status != pysvn.wc_status_kind.none: uptodate = uptodate and \ file.repos_prop_status != pysvn.wc_status_kind.modified status = "" if not uptodate: status = "U" self.shouldUpdate = True elif file.text_status == pysvn.wc_status_kind.conflicted or \ file.prop_status == pysvn.wc_status_kind.conflicted: status = "Z" elif file.text_status == pysvn.wc_status_kind.deleted or \ file.prop_status == pysvn.wc_status_kind.deleted: status = "O" elif file.text_status == pysvn.wc_status_kind.modified or \ file.prop_status == pysvn.wc_status_kind.modified: status = "M" elif file.text_status == pysvn.wc_status_kind.added or \ file.prop_status == pysvn.wc_status_kind.added: status = "A" elif file.text_status == pysvn.wc_status_kind.replaced or \ file.prop_status == pysvn.wc_status_kind.replaced: status = "R" if status: states[file.path] = status try: if self.reportedStates[file.path] != status: self.statusList.append( "{0} {1}".format(status, file.path)) except KeyError: self.statusList.append( "{0} {1}".format(status, file.path)) for name in list(self.reportedStates.keys()): if name not in states: self.statusList.append(" {0}".format(name)) self.reportedStates = states res = True statusStr = self.tr( "Subversion status checked successfully (using pysvn)") except pysvn.ClientError as e: res = False statusStr = e.args[0] os.chdir(cwd) return res, statusStr def __clientLoginCallback(self, realm, username, may_save): """ Private method called by the client to get login information. @param realm name of the realm of the requested credentials (string) @param username username as supplied by subversion (string) @param may_save flag indicating, that subversion is willing to save the answers returned (boolean) @return tuple of four values (retcode, username, password, save). Retcode should be True, if username and password should be used by subversion, username and password contain the relevant data as strings and save is a flag indicating, that username and password should be saved. Always returns (False, "", "", False). """ return (False, "", "", False) def __clientSslServerTrustPromptCallback(self, trust_dict): """ Private method called by the client to request acceptance for a ssl server certificate. @param trust_dict dictionary containing the trust data @return tuple of three values (retcode, acceptedFailures, save). Retcode should be true, if the certificate should be accepted, acceptedFailures should indicate the accepted certificate failures and save should be True, if subversion should save the certificate. Always returns (False, 0, False). """ return (False, 0, False) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnLogBrowserDialog.py0000644000175000017500000004767012451233371024243 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog to browse the log history. """ from __future__ import unicode_literals import os import sys import pysvn from PyQt5.QtCore import QMutexLocker, QDate, QRegExp, Qt, pyqtSlot, QPoint from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QHeaderView, QWidget, QApplication, \ QDialogButtonBox, QTreeWidgetItem from E5Gui import E5MessageBox from .SvnUtilities import formatTime, dateFromTime_t from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnLogBrowserDialog import Ui_SvnLogBrowserDialog class SvnLogBrowserDialog(QWidget, SvnDialogMixin, Ui_SvnLogBrowserDialog): """ Class implementing a dialog to browse the log history. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnLogBrowserDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.__position = QPoint() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.filesTree.headerItem().setText(self.filesTree.columnCount(), "") self.filesTree.header().setSortIndicator(0, Qt.AscendingOrder) self.vcs = vcs self.__initData() self.fromDate.setDisplayFormat("yyyy-MM-dd") self.toDate.setDisplayFormat("yyyy-MM-dd") self.__resetUI() self.__messageRole = Qt.UserRole self.__changesRole = Qt.UserRole + 1 self.flags = { 'A': self.tr('Added'), 'D': self.tr('Deleted'), 'M': self.tr('Modified'), 'R': self.tr('Replaced'), } self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback def __initData(self): """ Private method to (re-)initialize some data. """ self.__maxDate = QDate() self.__minDate = QDate() self.__filterLogsEnabled = True self.diff = None self.__lastRev = 0 def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ self.__position = self.pos() e.accept() def show(self): """ Public slot to show the dialog. """ if not self.__position.isNull(): self.move(self.__position) self.__resetUI() super(SvnLogBrowserDialog, self).show() def __resetUI(self): """ Private method to reset the user interface. """ self.fromDate.setDate(QDate.currentDate()) self.toDate.setDate(QDate.currentDate()) self.fieldCombo.setCurrentIndex(self.fieldCombo.findText( self.tr("Message"))) self.limitSpinBox.setValue(self.vcs.getPlugin().getPreferences( "LogLimit")) self.stopCheckBox.setChecked(self.vcs.getPlugin().getPreferences( "StopLogOnCopy")) self.logTree.clear() self.nextButton.setEnabled(True) self.limitSpinBox.setEnabled(True) def _reset(self): """ Protected method to reset the internal state of the dialog. """ SvnDialogMixin._reset(self) self.cancelled = False self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() def __resizeColumnsLog(self): """ Private method to resize the log tree columns. """ self.logTree.header().resizeSections(QHeaderView.ResizeToContents) self.logTree.header().setStretchLastSection(True) def __resortLog(self): """ Private method to resort the log tree. """ self.logTree.sortItems( self.logTree.sortColumn(), self.logTree.header().sortIndicatorOrder()) def __resizeColumnsFiles(self): """ Private method to resize the changed files tree columns. """ self.filesTree.header().resizeSections(QHeaderView.ResizeToContents) self.filesTree.header().setStretchLastSection(True) def __resortFiles(self): """ Private method to resort the changed files tree. """ sortColumn = self.filesTree.sortColumn() self.filesTree.sortItems( 1, self.filesTree.header().sortIndicatorOrder()) self.filesTree.sortItems( sortColumn, self.filesTree.header().sortIndicatorOrder()) def __generateLogItem(self, author, date, message, revision, changedPaths): """ Private method to generate a log tree entry. @param author author info (string) @param date date info (integer) @param message text of the log message (string) @param revision revision info (string or pysvn.opt_revision_kind) @param changedPaths list of pysvn dictionary like objects containing info about the changed files/directories @return reference to the generated item (QTreeWidgetItem) """ if revision == "": rev = "" self.__lastRev = 0 else: rev = revision.number self.__lastRev = revision.number if date == "": dt = "" else: dt = formatTime(date) itm = QTreeWidgetItem(self.logTree) itm.setData(0, Qt.DisplayRole, rev) itm.setData(1, Qt.DisplayRole, author) itm.setData(2, Qt.DisplayRole, dt) itm.setData(3, Qt.DisplayRole, " ".join(message.splitlines())) changes = [] for changedPath in changedPaths: if changedPath["copyfrom_path"] is None: copyPath = "" else: copyPath = changedPath["copyfrom_path"] if changedPath["copyfrom_revision"] is None: copyRev = "" else: copyRev = "{0:7d}".format( changedPath["copyfrom_revision"].number) change = { "action": changedPath["action"], "path": changedPath["path"], "copyfrom_path": copyPath, "copyfrom_revision": copyRev, } changes.append(change) itm.setData(0, self.__messageRole, message) itm.setData(0, self.__changesRole, changes) itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(1, Qt.AlignLeft) itm.setTextAlignment(2, Qt.AlignLeft) itm.setTextAlignment(3, Qt.AlignLeft) itm.setTextAlignment(4, Qt.AlignLeft) return itm def __generateFileItem(self, action, path, copyFrom, copyRev): """ Private method to generate a changed files tree entry. @param action indicator for the change action ("A", "D" or "M") @param path path of the file in the repository (string) @param copyFrom path the file was copied from (None, string) @param copyRev revision the file was copied from (None, string) @return reference to the generated item (QTreeWidgetItem) """ itm = QTreeWidgetItem( self.filesTree, [self.flags[action], path, copyFrom, copyRev] ) itm.setTextAlignment(3, Qt.AlignRight) return itm def __getLogEntries(self, startRev=None): """ Private method to retrieve log entries from the repository. @param startRev revision number to start from (integer, string) """ fetchLimit = 10 self._reset() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() limit = self.limitSpinBox.value() if startRev is None: start = pysvn.Revision(pysvn.opt_revision_kind.head) else: try: start = pysvn.Revision(pysvn.opt_revision_kind.number, int(startRev)) except TypeError: start = pysvn.Revision(pysvn.opt_revision_kind.head) locker = QMutexLocker(self.vcs.vcsExecutionMutex) cwd = os.getcwd() os.chdir(self.dname) try: nextRev = 0 fetched = 0 logs = [] while fetched < limit: flimit = min(fetchLimit, limit - fetched) if fetched == 0: revstart = start else: revstart = pysvn.Revision( pysvn.opt_revision_kind.number, nextRev) allLogs = self.client.log( self.fname, revision_start=revstart, discover_changed_paths=True, limit=flimit + 1, strict_node_history=self.stopCheckBox.isChecked()) if len(allLogs) <= flimit or self._clientCancelCallback(): logs.extend(allLogs) break else: logs.extend(allLogs[:-1]) nextRev = allLogs[-1]["revision"].number fetched += fetchLimit locker.unlock() for log in logs: author = log["author"] message = log["message"] if sys.version_info[0] == 2: author = author.decode('utf-8') message = message.decode('utf-8') self.__generateLogItem( author, log["date"], message, log["revision"], log['changed_paths']) dt = dateFromTime_t(log["date"]) if not self.__maxDate.isValid() and \ not self.__minDate.isValid(): self.__maxDate = dt self.__minDate = dt else: if self.__maxDate < dt: self.__maxDate = dt if self.__minDate > dt: self.__minDate = dt if len(logs) < limit and not self.cancelled: self.nextButton.setEnabled(False) self.limitSpinBox.setEnabled(False) self.__filterLogsEnabled = False self.fromDate.setMinimumDate(self.__minDate) self.fromDate.setMaximumDate(self.__maxDate) self.fromDate.setDate(self.__minDate) self.toDate.setMinimumDate(self.__minDate) self.toDate.setMaximumDate(self.__maxDate) self.toDate.setDate(self.__maxDate) self.__filterLogsEnabled = True self.__resizeColumnsLog() self.__resortLog() self.__filterLogs() except pysvn.ClientError as e: locker.unlock() self.__showError(e.args[0]) os.chdir(cwd) self.__finish() def start(self, fn, isFile=False): """ Public slot to start the svn log command. @param fn filename to show the log for (string) @keyparam isFile flag indicating log for a file is to be shown (boolean) """ self.sbsCheckBox.setEnabled(isFile) self.sbsCheckBox.setVisible(isFile) self.__initData() self.filename = fn self.dname, self.fname = self.vcs.splitPath(fn) self.activateWindow() self.raise_() self.logTree.clear() self.__getLogEntries() self.logTree.setCurrentItem(self.logTree.topLevelItem(0)) def __finish(self): """ Private slot called when the user pressed the button. """ QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self._cancel() def __diffRevisions(self, rev1, rev2, peg_rev): """ Private method to do a diff of two revisions. @param rev1 first revision number (integer) @param rev2 second revision number (integer) @param peg_rev revision number to use as a reference (integer) """ if self.sbsCheckBox.isEnabled() and self.sbsCheckBox.isChecked(): self.vcs.svnSbsDiff(self.filename, revisions=(str(rev1), str(rev2))) else: if self.diff is None: from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self.vcs) self.diff.show() self.diff.raise_() QApplication.processEvents() self.diff.start(self.filename, [rev1, rev2], pegRev=peg_rev) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.cancelled = True self.__finish() @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_logTree_currentItemChanged(self, current, previous): """ Private slot called, when the current item of the log tree changes. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the old current item (QTreeWidgetItem) """ if current is not None: self.messageEdit.setPlainText(current.data(0, self.__messageRole)) self.filesTree.clear() changes = current.data(0, self.__changesRole) if len(changes) > 0: for change in changes: self.__generateFileItem( change["action"], change["path"], change["copyfrom_path"], change["copyfrom_revision"]) self.__resizeColumnsFiles() self.__resortFiles() self.diffPreviousButton.setEnabled( current != self.logTree.topLevelItem( self.logTree.topLevelItemCount() - 1)) @pyqtSlot() def on_logTree_itemSelectionChanged(self): """ Private slot called, when the selection has changed. """ self.diffRevisionsButton.setEnabled( len(self.logTree.selectedItems()) == 2) @pyqtSlot() def on_nextButton_clicked(self): """ Private slot to handle the Next button. """ if self.__lastRev > 1: self.__getLogEntries(self.__lastRev - 1) @pyqtSlot() def on_diffPreviousButton_clicked(self): """ Private slot to handle the Diff to Previous button. """ itm = self.logTree.topLevelItem(0) if itm is None: self.diffPreviousButton.setEnabled(False) return peg_rev = int(itm.text(0)) itm = self.logTree.currentItem() if itm is None: self.diffPreviousButton.setEnabled(False) return rev2 = int(itm.text(0)) itm = self.logTree.topLevelItem( self.logTree.indexOfTopLevelItem(itm) + 1) if itm is None: self.diffPreviousButton.setEnabled(False) return rev1 = int(itm.text(0)) self.__diffRevisions(rev1, rev2, peg_rev) @pyqtSlot() def on_diffRevisionsButton_clicked(self): """ Private slot to handle the Compare Revisions button. """ items = self.logTree.selectedItems() if len(items) != 2: self.diffRevisionsButton.setEnabled(False) return rev2 = int(items[0].text(0)) rev1 = int(items[1].text(0)) itm = self.logTree.topLevelItem(0) if itm is None: self.diffPreviousButton.setEnabled(False) return peg_rev = int(itm.text(0)) self.__diffRevisions(min(rev1, rev2), max(rev1, rev2), peg_rev) def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ E5MessageBox.critical( self, self.tr("Subversion Error"), msg) @pyqtSlot(QDate) def on_fromDate_dateChanged(self, date): """ Private slot called, when the from date changes. @param date new date (QDate) """ self.__filterLogs() @pyqtSlot(QDate) def on_toDate_dateChanged(self, date): """ Private slot called, when the from date changes. @param date new date (QDate) """ self.__filterLogs() @pyqtSlot(str) def on_fieldCombo_activated(self, txt): """ Private slot called, when a new filter field is selected. @param txt text of the selected field (string) """ self.__filterLogs() @pyqtSlot(str) def on_rxEdit_textChanged(self, txt): """ Private slot called, when a filter expression is entered. @param txt filter expression (string) """ self.__filterLogs() def __filterLogs(self): """ Private method to filter the log entries. """ if self.__filterLogsEnabled: from_ = self.fromDate.date().toString("yyyy-MM-dd") to_ = self.toDate.date().addDays(1).toString("yyyy-MM-dd") txt = self.fieldCombo.currentText() if txt == self.tr("Author"): fieldIndex = 1 searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive) elif txt == self.tr("Revision"): fieldIndex = 0 txt = self.rxEdit.text() if txt.startswith("^"): searchRx = QRegExp( "^\s*{0}".format(txt[1:]), Qt.CaseInsensitive) else: searchRx = QRegExp(txt, Qt.CaseInsensitive) else: fieldIndex = 3 searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive) currentItem = self.logTree.currentItem() for topIndex in range(self.logTree.topLevelItemCount()): topItem = self.logTree.topLevelItem(topIndex) if topItem.text(2) <= to_ and topItem.text(2) >= from_ and \ searchRx.indexIn(topItem.text(fieldIndex)) > -1: topItem.setHidden(False) if topItem is currentItem: self.on_logTree_currentItemChanged(topItem, None) else: topItem.setHidden(True) if topItem is currentItem: self.messageEdit.clear() self.filesTree.clear() @pyqtSlot(bool) def on_stopCheckBox_clicked(self, checked): """ Private slot called, when the stop on copy/move checkbox is clicked. @param checked flag indicating the check box state (boolean) """ self.vcs.getPlugin().setPreferences("StopLogOnCopy", int(self.stopCheckBox.isChecked())) self.nextButton.setEnabled(True) self.limitSpinBox.setEnabled(True) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnTagDialog.py0000644000175000017500000000441012451233371022652 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a tagging operation. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_SvnTagDialog import Ui_SvnTagDialog class SvnTagDialog(QDialog, Ui_SvnTagDialog): """ Class implementing a dialog to enter the data for a tagging operation. """ def __init__(self, taglist, reposURL, standardLayout, parent=None): """ Constructor @param taglist list of previously entered tags (list of strings) @param reposURL repository path (string) or None @param standardLayout flag indicating the layout of the repository (boolean) @param parent parent widget (QWidget) """ super(SvnTagDialog, self).__init__(parent) self.setupUi(self) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) self.tagCombo.clear() self.tagCombo.addItems(sorted(taglist)) if reposURL is not None and reposURL != "": self.tagCombo.setEditText(reposURL) if not standardLayout: self.TagActionGroup.setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_tagCombo_editTextChanged(self, text): """ Private method used to enable/disable the OK-button. @param text tag name entered in the combo (string) """ self.okButton.setDisabled(text == "") def getParameters(self): """ Public method to retrieve the tag data. @return tuple of string and int (tag, tag operation) """ tag = self.tagCombo.currentText() tagOp = 0 if self.createRegularButton.isChecked(): tagOp = 1 elif self.createBranchButton.isChecked(): tagOp = 2 elif self.deleteRegularButton.isChecked(): tagOp = 4 elif self.deleteBranchButton.isChecked(): tagOp = 8 return (tag, tagOp) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/ProjectHelper.py0000644000175000017500000006053012451233371023103 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the VCS project helper for Subversion. """ from __future__ import unicode_literals import os from E5Gui.E5Application import e5App from VCS.ProjectHelper import VcsProjectHelper from E5Gui.E5Action import E5Action import UI.PixmapCache class SvnProjectHelper(VcsProjectHelper): """ Class implementing the VCS project helper for Subversion. """ def __init__(self, vcsObject, projectObject, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param projectObject reference to the project object @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectHelper.__init__(self, vcsObject, projectObject, parent, name) def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ return self.actions[:] def initActions(self): """ Public method to generate the action objects. """ self.vcsNewAct = E5Action( self.tr('New from repository'), UI.PixmapCache.getIcon("vcsCheckout.png"), self.tr('&New from repository...'), 0, 0, self, 'subversion_new') self.vcsNewAct.setStatusTip(self.tr( 'Create a new project from the VCS repository' )) self.vcsNewAct.setWhatsThis(self.tr( """New from repository""" """

This creates a new local project from the VCS""" """ repository.

""" )) self.vcsNewAct.triggered.connect(self._vcsCheckout) self.actions.append(self.vcsNewAct) self.vcsUpdateAct = E5Action( self.tr('Update from repository'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('&Update from repository'), 0, 0, self, 'subversion_update') self.vcsUpdateAct.setStatusTip(self.tr( 'Update the local project from the VCS repository' )) self.vcsUpdateAct.setWhatsThis(self.tr( """Update from repository""" """

This updates the local project from the VCS""" """ repository.

""" )) self.vcsUpdateAct.triggered.connect(self._vcsUpdate) self.actions.append(self.vcsUpdateAct) self.vcsCommitAct = E5Action( self.tr('Commit changes to repository'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('&Commit changes to repository...'), 0, 0, self, 'subversion_commit') self.vcsCommitAct.setStatusTip(self.tr( 'Commit changes to the local project to the VCS repository' )) self.vcsCommitAct.setWhatsThis(self.tr( """Commit changes to repository""" """

This commits changes to the local project to the VCS""" """ repository.

""" )) self.vcsCommitAct.triggered.connect(self._vcsCommit) self.actions.append(self.vcsCommitAct) self.vcsLogAct = E5Action( self.tr('Show log'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show &log'), 0, 0, self, 'subversion_log') self.vcsLogAct.setStatusTip(self.tr( 'Show the log of the local project' )) self.vcsLogAct.setWhatsThis(self.tr( """Show log""" """

This shows the log of the local project.

""" )) self.vcsLogAct.triggered.connect(self._vcsLog) self.actions.append(self.vcsLogAct) self.svnLogBrowserAct = E5Action( self.tr('Show log browser'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), 0, 0, self, 'subversion_log_browser') self.svnLogBrowserAct.setStatusTip(self.tr( 'Show a dialog to browse the log of the local project' )) self.svnLogBrowserAct.setWhatsThis(self.tr( """Show log browser""" """

This shows a dialog to browse the log of the local""" """ project. A limited number of entries is shown first. More""" """ can be retrieved later on.

""" )) self.svnLogBrowserAct.triggered.connect(self._vcsLogBrowser) self.actions.append(self.svnLogBrowserAct) self.vcsDiffAct = E5Action( self.tr('Show differences'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show &difference'), 0, 0, self, 'subversion_diff') self.vcsDiffAct.setStatusTip(self.tr( 'Show the difference of the local project to the repository' )) self.vcsDiffAct.setWhatsThis(self.tr( """Show differences""" """

This shows differences of the local project to the""" """ repository.

""" )) self.vcsDiffAct.triggered.connect(self._vcsDiff) self.actions.append(self.vcsDiffAct) self.svnExtDiffAct = E5Action( self.tr('Show differences (extended)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), 0, 0, self, 'subversion_extendeddiff') self.svnExtDiffAct.setStatusTip(self.tr( 'Show the difference of revisions of the project to the repository' )) self.svnExtDiffAct.setWhatsThis(self.tr( """Show differences (extended)""" """

This shows differences of selectable revisions of""" """ the project.

""" )) self.svnExtDiffAct.triggered.connect(self.__svnExtendedDiff) self.actions.append(self.svnExtDiffAct) self.svnUrlDiffAct = E5Action( self.tr('Show differences (URLs)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), 0, 0, self, 'subversion_urldiff') self.svnUrlDiffAct.setStatusTip(self.tr( 'Show the difference of the project between two repository URLs' )) self.svnUrlDiffAct.setWhatsThis(self.tr( """Show differences (URLs)""" """

This shows differences of the project between""" """ two repository URLs.

""" )) self.svnUrlDiffAct.triggered.connect(self.__svnUrlDiff) self.actions.append(self.svnUrlDiffAct) self.vcsStatusAct = E5Action( self.tr('Show status'), UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show &status'), 0, 0, self, 'subversion_status') self.vcsStatusAct.setStatusTip(self.tr( 'Show the status of the local project' )) self.vcsStatusAct.setWhatsThis(self.tr( """Show status""" """

This shows the status of the local project.

""" )) self.vcsStatusAct.triggered.connect(self._vcsStatus) self.actions.append(self.vcsStatusAct) self.svnChangeListsAct = E5Action( self.tr('Show change lists'), UI.PixmapCache.getIcon("vcsChangeLists.png"), self.tr('Show change lists'), 0, 0, self, 'subversion_changelists') self.svnChangeListsAct.setStatusTip(self.tr( 'Show the change lists and associated files of the local project' )) self.svnChangeListsAct.setWhatsThis(self.tr( """Show change lists""" """

This shows the change lists and associated files of the""" """ local project.

""" )) self.svnChangeListsAct.triggered.connect(self.__svnChangeLists) self.actions.append(self.svnChangeListsAct) self.svnRepoInfoAct = E5Action( self.tr('Show repository info'), UI.PixmapCache.getIcon("vcsRepo.png"), self.tr('Show repository info'), 0, 0, self, 'subversion_repoinfo') self.svnRepoInfoAct.setStatusTip(self.tr( 'Show some repository related information for the local project' )) self.svnRepoInfoAct.setWhatsThis(self.tr( """Show repository info""" """

This shows some repository related information for""" """ the local project.

""" )) self.svnRepoInfoAct.triggered.connect(self.__svnInfo) self.actions.append(self.svnRepoInfoAct) self.vcsTagAct = E5Action( self.tr('Tag in repository'), UI.PixmapCache.getIcon("vcsTag.png"), self.tr('&Tag in repository...'), 0, 0, self, 'subversion_tag') self.vcsTagAct.setStatusTip(self.tr( 'Tag the local project in the repository' )) self.vcsTagAct.setWhatsThis(self.tr( """Tag in repository""" """

This tags the local project in the repository.

""" )) self.vcsTagAct.triggered.connect(self._vcsTag) self.actions.append(self.vcsTagAct) self.vcsExportAct = E5Action( self.tr('Export from repository'), UI.PixmapCache.getIcon("vcsExport.png"), self.tr('&Export from repository...'), 0, 0, self, 'subversion_export') self.vcsExportAct.setStatusTip(self.tr( 'Export a project from the repository' )) self.vcsExportAct.setWhatsThis(self.tr( """Export from repository""" """

This exports a project from the repository.

""" )) self.vcsExportAct.triggered.connect(self._vcsExport) self.actions.append(self.vcsExportAct) self.vcsPropsAct = E5Action( self.tr('Command options'), self.tr('Command &options...'), 0, 0, self, 'subversion_options') self.vcsPropsAct.setStatusTip(self.tr( 'Show the VCS command options')) self.vcsPropsAct.setWhatsThis(self.tr( """Command options...""" """

This shows a dialog to edit the VCS command options.

""" )) self.vcsPropsAct.triggered.connect(self._vcsCommandOptions) self.actions.append(self.vcsPropsAct) self.vcsRevertAct = E5Action( self.tr('Revert changes'), UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Re&vert changes'), 0, 0, self, 'subversion_revert') self.vcsRevertAct.setStatusTip(self.tr( 'Revert all changes made to the local project' )) self.vcsRevertAct.setWhatsThis(self.tr( """Revert changes""" """

This reverts all changes made to the local project.

""" )) self.vcsRevertAct.triggered.connect(self._vcsRevert) self.actions.append(self.vcsRevertAct) self.vcsMergeAct = E5Action( self.tr('Merge'), UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Mer&ge changes...'), 0, 0, self, 'subversion_merge') self.vcsMergeAct.setStatusTip(self.tr( 'Merge changes of a tag/revision into the local project' )) self.vcsMergeAct.setWhatsThis(self.tr( """Merge""" """

This merges changes of a tag/revision into the local""" """ project.

""" )) self.vcsMergeAct.triggered.connect(self._vcsMerge) self.actions.append(self.vcsMergeAct) self.vcsSwitchAct = E5Action( self.tr('Switch'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('S&witch...'), 0, 0, self, 'subversion_switch') self.vcsSwitchAct.setStatusTip(self.tr( 'Switch the local copy to another tag/branch' )) self.vcsSwitchAct.setWhatsThis(self.tr( """Switch""" """

This switches the local copy to another tag/branch.

""" )) self.vcsSwitchAct.triggered.connect(self._vcsSwitch) self.actions.append(self.vcsSwitchAct) self.vcsResolveAct = E5Action( self.tr('Conflicts resolved'), self.tr('Con&flicts resolved'), 0, 0, self, 'subversion_resolve') self.vcsResolveAct.setStatusTip(self.tr( 'Mark all conflicts of the local project as resolved' )) self.vcsResolveAct.setWhatsThis(self.tr( """Conflicts resolved""" """

This marks all conflicts of the local project as""" """ resolved.

""" )) self.vcsResolveAct.triggered.connect(self.__svnResolve) self.actions.append(self.vcsResolveAct) self.vcsCleanupAct = E5Action( self.tr('Cleanup'), self.tr('Cleanu&p'), 0, 0, self, 'subversion_cleanup') self.vcsCleanupAct.setStatusTip(self.tr( 'Cleanup the local project' )) self.vcsCleanupAct.setWhatsThis(self.tr( """Cleanup""" """

This performs a cleanup of the local project.

""" )) self.vcsCleanupAct.triggered.connect(self._vcsCleanup) self.actions.append(self.vcsCleanupAct) self.vcsCommandAct = E5Action( self.tr('Execute command'), self.tr('E&xecute command...'), 0, 0, self, 'subversion_command') self.vcsCommandAct.setStatusTip(self.tr( 'Execute an arbitrary VCS command' )) self.vcsCommandAct.setWhatsThis(self.tr( """Execute command""" """

This opens a dialog to enter an arbitrary VCS command.

""" )) self.vcsCommandAct.triggered.connect(self._vcsCommand) self.actions.append(self.vcsCommandAct) self.svnTagListAct = E5Action( self.tr('List tags'), self.tr('List tags...'), 0, 0, self, 'subversion_list_tags') self.svnTagListAct.setStatusTip(self.tr( 'List tags of the project' )) self.svnTagListAct.setWhatsThis(self.tr( """List tags""" """

This lists the tags of the project.

""" )) self.svnTagListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnTagListAct) self.svnBranchListAct = E5Action( self.tr('List branches'), self.tr('List branches...'), 0, 0, self, 'subversion_list_branches') self.svnBranchListAct.setStatusTip(self.tr( 'List branches of the project' )) self.svnBranchListAct.setWhatsThis(self.tr( """List branches""" """

This lists the branches of the project.

""" )) self.svnBranchListAct.triggered.connect(self.__svnBranchList) self.actions.append(self.svnBranchListAct) self.svnListAct = E5Action( self.tr('List repository contents'), self.tr('List repository contents...'), 0, 0, self, 'subversion_contents') self.svnListAct.setStatusTip(self.tr( 'Lists the contents of the repository' )) self.svnListAct.setWhatsThis(self.tr( """List repository contents""" """

This lists the contents of the repository.

""" )) self.svnListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnListAct) self.svnPropSetAct = E5Action( self.tr('Set Property'), self.tr('Set Property...'), 0, 0, self, 'subversion_property_set') self.svnPropSetAct.setStatusTip(self.tr( 'Set a property for the project files' )) self.svnPropSetAct.setWhatsThis(self.tr( """Set Property""" """

This sets a property for the project files.

""" )) self.svnPropSetAct.triggered.connect(self.__svnPropSet) self.actions.append(self.svnPropSetAct) self.svnPropListAct = E5Action( self.tr('List Properties'), self.tr('List Properties...'), 0, 0, self, 'subversion_property_list') self.svnPropListAct.setStatusTip(self.tr( 'List properties of the project files' )) self.svnPropListAct.setWhatsThis(self.tr( """List Properties""" """

This lists the properties of the project files.

""" )) self.svnPropListAct.triggered.connect(self.__svnPropList) self.actions.append(self.svnPropListAct) self.svnPropDelAct = E5Action( self.tr('Delete Property'), self.tr('Delete Property...'), 0, 0, self, 'subversion_property_delete') self.svnPropDelAct.setStatusTip(self.tr( 'Delete a property for the project files' )) self.svnPropDelAct.setWhatsThis(self.tr( """Delete Property""" """

This deletes a property for the project files.

""" )) self.svnPropDelAct.triggered.connect(self.__svnPropDel) self.actions.append(self.svnPropDelAct) self.svnRelocateAct = E5Action( self.tr('Relocate'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('Relocate...'), 0, 0, self, 'subversion_relocate') self.svnRelocateAct.setStatusTip(self.tr( 'Relocate the working copy to a new repository URL' )) self.svnRelocateAct.setWhatsThis(self.tr( """Relocate""" """

This relocates the working copy to a new repository""" """ URL.

""" )) self.svnRelocateAct.triggered.connect(self.__svnRelocate) self.actions.append(self.svnRelocateAct) self.svnRepoBrowserAct = E5Action( self.tr('Repository Browser'), UI.PixmapCache.getIcon("vcsRepoBrowser.png"), self.tr('Repository Browser...'), 0, 0, self, 'subversion_repo_browser') self.svnRepoBrowserAct.setStatusTip(self.tr( 'Show the Repository Browser dialog' )) self.svnRepoBrowserAct.setWhatsThis(self.tr( """Repository Browser""" """

This shows the Repository Browser dialog.

""" )) self.svnRepoBrowserAct.triggered.connect(self.__svnRepoBrowser) self.actions.append(self.svnRepoBrowserAct) self.svnConfigAct = E5Action( self.tr('Configure'), self.tr('Configure...'), 0, 0, self, 'subversion_configure') self.svnConfigAct.setStatusTip(self.tr( 'Show the configuration dialog with the Subversion page selected' )) self.svnConfigAct.setWhatsThis(self.tr( """Configure""" """

Show the configuration dialog with the Subversion page""" """ selected.

""" )) self.svnConfigAct.triggered.connect(self.__svnConfigure) self.actions.append(self.svnConfigAct) self.svnUpgradeAct = E5Action( self.tr('Upgrade'), self.tr('Upgrade...'), 0, 0, self, 'subversion_upgrade') self.svnUpgradeAct.setStatusTip(self.tr( 'Upgrade the working copy to the current format' )) self.svnUpgradeAct.setWhatsThis(self.tr( """Upgrade""" """

Upgrades the working copy to the current format.

""" )) self.svnUpgradeAct.triggered.connect(self.__svnUpgrade) self.actions.append(self.svnUpgradeAct) def initMenu(self, menu): """ Public method to generate the VCS menu. @param menu reference to the menu to be populated (QMenu) """ menu.clear() act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsPySvn", "icons", "pysvn.png")), self.vcs.vcsName(), self._vcsInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.vcsUpdateAct) menu.addAction(self.vcsCommitAct) menu.addSeparator() menu.addAction(self.vcsNewAct) menu.addAction(self.vcsExportAct) menu.addSeparator() menu.addAction(self.vcsTagAct) if self.vcs.otherData["standardLayout"]: menu.addAction(self.svnTagListAct) menu.addAction(self.svnBranchListAct) else: menu.addAction(self.svnListAct) menu.addSeparator() menu.addAction(self.vcsLogAct) menu.addAction(self.svnLogBrowserAct) menu.addSeparator() menu.addAction(self.vcsStatusAct) menu.addAction(self.svnChangeListsAct) menu.addAction(self.svnRepoInfoAct) menu.addSeparator() menu.addAction(self.vcsDiffAct) menu.addAction(self.svnExtDiffAct) menu.addAction(self.svnUrlDiffAct) menu.addSeparator() menu.addAction(self.vcsRevertAct) menu.addAction(self.vcsMergeAct) menu.addAction(self.vcsResolveAct) menu.addSeparator() menu.addAction(self.vcsSwitchAct) menu.addAction(self.svnRelocateAct) menu.addSeparator() menu.addAction(self.svnPropSetAct) menu.addAction(self.svnPropListAct) menu.addAction(self.svnPropDelAct) menu.addSeparator() menu.addAction(self.vcsCleanupAct) menu.addSeparator() menu.addAction(self.vcsCommandAct) menu.addAction(self.svnRepoBrowserAct) menu.addAction(self.svnUpgradeAct) menu.addSeparator() menu.addAction(self.vcsPropsAct) menu.addSeparator() menu.addAction(self.svnConfigAct) def __svnResolve(self): """ Private slot used to resolve conflicts of the local project. """ self.vcs.svnResolve(self.project.ppath) def __svnPropList(self): """ Private slot used to list the properties of the project files. """ self.vcs.svnListProps(self.project.ppath, True) def __svnPropSet(self): """ Private slot used to set a property for the project files. """ self.vcs.svnSetProp(self.project.ppath, True) def __svnPropDel(self): """ Private slot used to delete a property for the project files. """ self.vcs.svnDelProp(self.project.ppath, True) def __svnTagList(self): """ Private slot used to list the tags of the project. """ self.vcs.svnListTagBranch(self.project.ppath, True) def __svnBranchList(self): """ Private slot used to list the branches of the project. """ self.vcs.svnListTagBranch(self.project.ppath, False) def __svnExtendedDiff(self): """ Private slot used to perform a svn diff with the selection of revisions. """ self.vcs.svnExtendedDiff(self.project.ppath) def __svnUrlDiff(self): """ Private slot used to perform a svn diff with the selection of repository URLs. """ self.vcs.svnUrlDiff(self.project.ppath) def __svnInfo(self): """ Private slot used to show repository information for the local project. """ self.vcs.svnInfo(self.project.ppath, ".") def __svnRelocate(self): """ Private slot used to relocate the working copy to a new repository URL. """ self.vcs.svnRelocate(self.project.ppath) def __svnRepoBrowser(self): """ Private slot to open the repository browser. """ self.vcs.svnRepoBrowser(projectPath=self.project.ppath) def __svnConfigure(self): """ Private slot to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("zzz_subversionPage") def __svnChangeLists(self): """ Private slot used to show a list of change lists. """ self.vcs.svnShowChangelists(self.project.ppath) def __svnUpgrade(self): """ Private slot used to upgrade the working copy format. """ self.vcs.svnUpgrade(self.project.ppath) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnLogDialog.py0000644000175000017500000002362512451233371022671 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn log command process. """ from __future__ import unicode_literals import os import sys import pysvn from PyQt5.QtCore import QMutexLocker, QUrl, Qt, QByteArray, qVersion from PyQt5.QtGui import QCursor, QTextCursor from PyQt5.QtWidgets import QWidget, QApplication, QDialogButtonBox from .SvnUtilities import formatTime from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnLogDialog import Ui_SvnLogDialog import Utilities class SvnLogDialog(QWidget, SvnDialogMixin, Ui_SvnLogDialog): """ Class implementing a dialog to show the output of the svn log command. The dialog is nonmodal. Clicking a link in the upper text pane shows a diff of the versions. """ def __init__(self, vcs, isFile=False, parent=None): """ Constructor @param vcs reference to the vcs object @param isFile flag indicating log for a file is to be shown (boolean) @param parent parent widget (QWidget) """ super(SvnLogDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.vcs = vcs self.contents.setHtml( self.tr('Processing your request, please wait...')) self.contents.anchorClicked.connect(self.__sourceChanged) self.flags = { 'A': self.tr('Added'), 'D': self.tr('Deleted'), 'M': self.tr('Modified') } self.revString = self.tr('revision') self.diff = None self.sbsCheckBox.setEnabled(isFile) self.sbsCheckBox.setVisible(isFile) self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback def start(self, fn, noEntries=0): """ Public slot to start the svn log command. @param fn filename to show the log for (string) @param noEntries number of entries to show (integer) """ self.errorGroup.hide() fetchLimit = 10 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.filename = fn dname, fname = self.vcs.splitPath(fn) opts = self.vcs.options['global'] + self.vcs.options['log'] verbose = "--verbose" in opts self.activateWindow() self.raise_() locker = QMutexLocker(self.vcs.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) try: nextRev = 0 fetched = 0 logs = [] limit = noEntries or 9999999 while fetched < limit: flimit = min(fetchLimit, limit - fetched) if fetched == 0: revstart = pysvn.Revision(pysvn.opt_revision_kind.head) else: revstart = pysvn.Revision( pysvn.opt_revision_kind.number, nextRev) allLogs = self.client.log(fname, revision_start=revstart, discover_changed_paths=verbose, limit=flimit + 1, strict_node_history=False) if len(allLogs) <= flimit or self._clientCancelCallback(): logs.extend(allLogs) break else: logs.extend(allLogs[:-1]) nextRev = allLogs[-1]["revision"].number fetched += fetchLimit locker.unlock() self.contents.clear() self.__pegRev = None for log in logs: ver = "{0:d}".format(log["revision"].number) dstr = '{0} {1}'.format(self.revString, ver) if self.__pegRev is None: self.__pegRev = int(ver) try: lv = "{0:d}".format( logs[logs.index(log) + 1]["revision"].number) url = QUrl() url.setScheme("file") url.setPath(self.filename) if qVersion() >= "5.0.0": query = lv + '_' + ver url.setQuery(query) else: query = QByteArray() query.append(lv).append('_').append(ver) url.setEncodedQuery(query) dstr += ' [{2}]'.format( url.toString(), query, self.tr('diff to {0}').format(lv) ) except IndexError: pass dstr += '
\n' self.contents.insertHtml(dstr) author = log["author"] message = log["message"] if sys.version_info[0] == 2: author = author.decode('utf-8') message = message.decode('utf-8') dstr = self.tr('author: {0}
\n')\ .format(author) self.contents.insertHtml(dstr) dstr = self.tr('date: {0}
\n')\ .format(formatTime(log["date"])) self.contents.insertHtml(dstr) self.contents.insertHtml('
\n') for line in message.splitlines(): self.contents.insertHtml(Utilities.html_encode(line)) self.contents.insertHtml('
\n') if len(log['changed_paths']) > 0: self.contents.insertHtml('
\n') for changeInfo in log['changed_paths']: action = changeInfo["action"] path = changeInfo["path"] if sys.version_info[0] == 2: action = action.decode('utf-8') path = path.decode('utf-8') dstr = '{0} {1}'.format(self.flags[action], path) if changeInfo["copyfrom_path"] is not None: copyfrom_path = changeInfo["copyfrom_path"] if sys.version_info[0] == 2: copyfrom_path = copyfrom_path.decode('utf-8') dstr += self.tr( " (copied from {0}, revision {1})")\ .format(copyfrom_path, changeInfo["copyfrom_revision"].number) dstr += '
\n' self.contents.insertHtml(dstr) self.contents.insertHtml('

\n') except pysvn.ClientError as e: locker.unlock() self.__showError(e.args[0]) os.chdir(cwd) self.__finish() def __finish(self): """ Private slot called when the user pressed the button. """ QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() self._cancel() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __sourceChanged(self, url): """ Private slot to handle the sourceChanged signal of the contents pane. @param url the url that was clicked (QUrl) """ self.contents.setSource(QUrl('')) filename = url.path() if Utilities.isWindowsPlatform(): if filename.startswith("/"): filename = filename[1:] if qVersion() >= "5.0.0": ver = url.query() else: ver = bytes(url.encodedQuery()).decode() v1 = ver.split('_')[0] v2 = ver.split('_')[1] if not v1 or not v2: return try: v1 = int(v1) v2 = int(v2) except ValueError: return self.contents.scrollToAnchor(ver) if self.sbsCheckBox.isEnabled() and self.sbsCheckBox.isChecked(): self.vcs.svnSbsDiff(filename, revisions=(v1, v2)) else: if self.diff is None: from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self.vcs) self.diff.show() self.diff.start(filename, [v1, v2], pegRev=self.__pegRev) def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ self.errorGroup.show() self.errors.insertPlainText(msg) self.errors.ensureCursorVisible() eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/__init__.py0000644000175000017500000000047112451233371022072 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Package implementing the vcs interface to Subversion. It consists of the subversion class, the project helper classes and some Subversion specific dialogs. This package is based upon the pysvn interface. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnMergeDialog.ui0000644000175000017500000001147112354033627023174 0ustar piotrpiotr SvnMergeDialog 0 0 456 152 Subversion Merge true Select to force the merge operation Enforce merge Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Target: Enter the target <b>Target</b> <p>Enter the target for the merge operation into this field. Leave it empty to get the target URL from the working copy.</p> <p><b>Note:</b> This entry is only needed, if you enter revision numbers above.</p> true QComboBox::InsertAtTop false 0 0 Enter an URL or a revision number <b>URL/Revision</b> <p>Enter an URL or a revision number to be merged into the working copy.</p> true false 0 0 Enter an URL or a revision number <b>URL/Revision</b> <p>Enter an URL or a revision number to be merged into the working copy.</p> true false 2. URL/Revision: 1. URL/Revision: qPixmapFromMimeSource tag1Combo tag2Combo targetCombo forceCheckBox buttonBox buttonBox accepted() SvnMergeDialog accept() 40 96 40 117 buttonBox rejected() SvnMergeDialog reject() 119 102 119 120 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnTagBranchListDialog.ui0000644000175000017500000000606712060166053024621 0ustar piotrpiotr SvnTagBranchListDialog 0 0 634 494 Subversion Tag List <b>Subversion Tag/Branch List</b> <p>This dialog shows a list of the projects tags or branches.</p> true 0 3 <b>Tag/Branches List</b> <p>This shows a list of the projects tags or branches.</p> true false false true Revision Author Date Name 0 1 Errors true false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource tagList errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnPropDelDialog.ui0000644000175000017500000000507412060166053023476 0ustar piotrpiotr SvnPropDelDialog 0 0 494 98 Delete Subversion Property true Enter the name of the property to be deleted Select to apply the property recursively Apply &recursively Property &Name: propNameEdit Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource propNameEdit recurseCheckBox buttonBox accepted() SvnPropDelDialog accept() 37 77 37 95 buttonBox rejected() SvnPropDelDialog reject() 88 75 88 96 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnDialog.py0000644000175000017500000001244212537064320022223 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of a pysvn action. """ from __future__ import unicode_literals import pysvn from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QDialog, QApplication, QDialogButtonBox from .SvnConst import svnNotifyActionMap from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnDialog import Ui_SvnDialog import Preferences class SvnDialog(QDialog, SvnDialogMixin, Ui_SvnDialog): """ Class implementing a dialog to show the output of a pysvn action. """ def __init__(self, text, command, pysvnClient, parent=None, log=""): """ Constructor @param text text to be shown by the label (string) @param command svn command to be executed (display purposes only) (string) @param pysvnClient reference to the pysvn client object (pysvn.Client) @keyparam parent parent widget (QWidget) @keyparam log optional log message (string) """ super(SvnDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self, log) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.outputGroup.setTitle(text) self.errorGroup.hide() pysvnClient.callback_cancel = \ self._clientCancelCallback pysvnClient.callback_notify = \ self._clientNotifyCallback pysvnClient.callback_get_login = \ self._clientLoginCallback pysvnClient.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback pysvnClient.callback_get_log_message = \ self._clientLogCallback self.__hasAddOrDelete = False if command: self.resultbox.append(command) self.resultbox.append('') self.show() QApplication.processEvents() def _clientNotifyCallback(self, eventDict): """ Protected method called by the client to send events. @param eventDict dictionary containing the notification event """ msg = "" if eventDict["action"] == pysvn.wc_notify_action.update_completed: msg = self.tr("Revision {0}.\n").format( eventDict["revision"].number) elif eventDict["path"] != "" and \ eventDict["action"] in svnNotifyActionMap and \ svnNotifyActionMap[eventDict["action"]] is not None: mime = eventDict["mime_type"] == "application/octet-stream" and \ self.tr(" (binary)") or "" msg = self.tr("{0} {1}{2}\n")\ .format(self.tr(svnNotifyActionMap[eventDict["action"]]), eventDict["path"], mime) if '.e4p' in eventDict["path"]: self.__hasAddOrDelete = True if eventDict["action"] in [pysvn.wc_notify_action.add, pysvn.wc_notify_action.commit_added, pysvn.wc_notify_action.commit_deleted, pysvn.wc_notify_action.delete, pysvn.wc_notify_action.update_add, pysvn.wc_notify_action.update_delete]: self.__hasAddOrDelete = True if msg: self.showMessage(msg) def showMessage(self, msg): """ Public slot to show a message. @param msg message to show (string) """ self.resultbox.insertPlainText(msg) self.resultbox.ensureCursorVisible() QApplication.processEvents() def showError(self, msg): """ Public slot to show an error message. @param msg error message to show (string) """ self.errorGroup.show() self.errors.insertPlainText(msg) self.errors.ensureCursorVisible() QApplication.processEvents() def finish(self): """ Public slot called when the process finished or the user pressed the button. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self._cancel() if Preferences.getVCS("AutoClose"): self.accept() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.finish() def hasAddOrDelete(self): """ Public method to check, if the last action contained an add or delete. @return flag indicating the presence of an add or delete (boolean) """ return self.__hasAddOrDelete eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnChangeListsDialog.ui0000644000175000017500000000615112060166053024332 0ustar piotrpiotr SvnChangeListsDialog 0 0 519 494 Subversion Change Lists true Change Lists: 0 1 <b>Change Lists</b> <p>Select a change list here to see the associated files in the list below.</p> true true 0 2 <b>Files</b> <p>This shows a list of files associated with the change list selected above.</p> true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close changeLists filesList buttonBox buttonBox accepted() SvnChangeListsDialog accept() 248 254 157 274 buttonBox rejected() SvnChangeListsDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py0000644000175000017500000010545612451233371023436 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn status command process. """ from __future__ import unicode_literals import os import sys import pysvn from PyQt5.QtCore import QMutexLocker, Qt, pyqtSlot from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QWidget, QHeaderView, QApplication, QMenu, \ QDialogButtonBox, QTreeWidgetItem from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .SvnConst import svnStatusMap from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnStatusDialog import Ui_SvnStatusDialog import Preferences import Utilities class SvnStatusDialog(QWidget, SvnDialogMixin, Ui_SvnStatusDialog): """ Class implementing a dialog to show the output of the svn status command process. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnStatusDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.__toBeCommittedColumn = 0 self.__changelistColumn = 1 self.__statusColumn = 2 self.__propStatusColumn = 3 self.__lockedColumn = 4 self.__historyColumn = 5 self.__switchedColumn = 6 self.__lockinfoColumn = 7 self.__upToDateColumn = 8 self.__pathColumn = 12 self.__lastColumn = self.statusList.columnCount() self.refreshButton = \ self.buttonBox.addButton(self.tr("Refresh"), QDialogButtonBox.ActionRole) self.refreshButton.setToolTip( self.tr("Press to refresh the status display")) self.refreshButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.diff = None self.vcs = vcs self.vcs.committed.connect(self.__committed) self.statusList.headerItem().setText(self.__lastColumn, "") self.statusList.header().setSortIndicator(self.__pathColumn, Qt.AscendingOrder) if pysvn.svn_version < (1, 5, 0) or pysvn.version < (1, 6, 0): self.statusList.header().hideSection(self.__changelistColumn) self.menuactions = [] self.menu = QMenu() self.menuactions.append(self.menu.addAction( self.tr("Commit changes to repository..."), self.__commit)) self.menuactions.append(self.menu.addAction( self.tr("Select all for commit"), self.__commitSelectAll)) self.menuactions.append(self.menu.addAction( self.tr("Deselect all from commit"), self.__commitDeselectAll)) self.menu.addSeparator() self.menuactions.append(self.menu.addAction( self.tr("Add to repository"), self.__add)) self.menuactions.append(self.menu.addAction( self.tr("Show differences"), self.__diff)) self.menuactions.append(self.menu.addAction( self.tr("Show differences side-by-side"), self.__sbsDiff)) self.menuactions.append(self.menu.addAction( self.tr("Revert changes"), self.__revert)) self.menuactions.append(self.menu.addAction( self.tr("Restore missing"), self.__restoreMissing)) if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0): self.menu.addSeparator() self.menuactions.append(self.menu.addAction( self.tr("Add to Changelist"), self.__addToChangelist)) self.menuactions.append(self.menu.addAction( self.tr("Remove from Changelist"), self.__removeFromChangelist)) if self.vcs.version >= (1, 2, 0): self.menu.addSeparator() self.menuactions.append( self.menu.addAction(self.tr("Lock"), self.__lock)) self.menuactions.append( self.menu.addAction(self.tr("Unlock"), self.__unlock)) self.menuactions.append(self.menu.addAction( self.tr("Break lock"), self.__breakLock)) self.menuactions.append(self.menu.addAction( self.tr("Steal lock"), self.__stealLock)) self.menu.addSeparator() self.menuactions.append(self.menu.addAction( self.tr("Adjust column sizes"), self.__resizeColumns)) for act in self.menuactions: act.setEnabled(False) self.statusList.setContextMenuPolicy(Qt.CustomContextMenu) self.statusList.customContextMenuRequested.connect( self.__showContextMenu) self.modifiedIndicators = [ self.tr(svnStatusMap[pysvn.wc_status_kind.added]), self.tr(svnStatusMap[pysvn.wc_status_kind.deleted]), self.tr(svnStatusMap[pysvn.wc_status_kind.modified]) ] self.missingIndicators = [ self.tr(svnStatusMap[pysvn.wc_status_kind.missing]), ] self.unversionedIndicators = [ self.tr(svnStatusMap[pysvn.wc_status_kind.unversioned]), ] self.lockedIndicators = [ self.tr('locked'), ] self.stealBreakLockIndicators = [ self.tr('other lock'), self.tr('stolen lock'), self.tr('broken lock'), ] self.unlockedIndicators = [ self.tr('not locked'), ] self.lockinfo = { ' ': self.tr('not locked'), 'L': self.tr('locked'), 'O': self.tr('other lock'), 'S': self.tr('stolen lock'), 'B': self.tr('broken lock'), } self.yesno = [ self.tr('no'), self.tr('yes'), ] self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback self.show() QApplication.processEvents() def __resort(self): """ Private method to resort the tree. """ self.statusList.sortItems( self.statusList.sortColumn(), self.statusList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.statusList.header().resizeSections(QHeaderView.ResizeToContents) self.statusList.header().setStretchLastSection(True) def __generateItem(self, changelist, status, propStatus, locked, history, switched, lockinfo, uptodate, revision, change, author, path): """ Private method to generate a status item in the status list. @param changelist name of the changelist (string) @param status text status (pysvn.wc_status_kind) @param propStatus property status (pysvn.wc_status_kind) @param locked locked flag (boolean) @param history history flag (boolean) @param switched switched flag (boolean) @param lockinfo lock indicator (string) @param uptodate up to date flag (boolean) @param revision revision (integer) @param change revision of last change (integer) @param author author of the last change (string) @param path path of the file or directory (string) """ statusText = self.tr(svnStatusMap[status]) itm = QTreeWidgetItem(self.statusList) itm.setData(0, Qt.DisplayRole, "") itm.setData(1, Qt.DisplayRole, changelist) itm.setData(2, Qt.DisplayRole, statusText) itm.setData(3, Qt.DisplayRole, self.tr(svnStatusMap[propStatus])) itm.setData(4, Qt.DisplayRole, self.yesno[locked]) itm.setData(5, Qt.DisplayRole, self.yesno[history]) itm.setData(6, Qt.DisplayRole, self.yesno[switched]) itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo]) itm.setData(8, Qt.DisplayRole, self.yesno[uptodate]) itm.setData(9, Qt.DisplayRole, revision) itm.setData(10, Qt.DisplayRole, change) itm.setData(11, Qt.DisplayRole, author) itm.setData(12, Qt.DisplayRole, path) itm.setTextAlignment(1, Qt.AlignLeft) itm.setTextAlignment(2, Qt.AlignHCenter) itm.setTextAlignment(3, Qt.AlignHCenter) itm.setTextAlignment(4, Qt.AlignHCenter) itm.setTextAlignment(5, Qt.AlignHCenter) itm.setTextAlignment(6, Qt.AlignHCenter) itm.setTextAlignment(7, Qt.AlignHCenter) itm.setTextAlignment(8, Qt.AlignHCenter) itm.setTextAlignment(9, Qt.AlignRight) itm.setTextAlignment(10, Qt.AlignRight) itm.setTextAlignment(11, Qt.AlignLeft) itm.setTextAlignment(12, Qt.AlignLeft) if status in [pysvn.wc_status_kind.added, pysvn.wc_status_kind.deleted, pysvn.wc_status_kind.modified] or \ propStatus in [pysvn.wc_status_kind.added, pysvn.wc_status_kind.deleted, pysvn.wc_status_kind.modified]: itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable) if statusText not in self.__statusFilters: self.__statusFilters.append(statusText) def start(self, fn): """ Public slot to start the svn status command. @param fn filename(s)/directoryname(s) to show the status of (string or list of strings) """ self.errorGroup.hide() for act in self.menuactions: act.setEnabled(False) self.addButton.setEnabled(False) self.commitButton.setEnabled(False) self.diffButton.setEnabled(False) self.sbsDiffButton.setEnabled(False) self.revertButton.setEnabled(False) self.restoreButton.setEnabled(False) self.statusFilterCombo.clear() self.__statusFilters = [] QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.args = fn self.setWindowTitle(self.tr('Subversion Status')) self.activateWindow() self.raise_() if isinstance(fn, list): self.dname, fnames = self.vcs.splitPathList(fn) else: self.dname, fname = self.vcs.splitPath(fn) fnames = [fname] opts = self.vcs.options['global'] + self.vcs.options['status'] verbose = "--verbose" in opts recurse = "--non-recursive" not in opts update = "--show-updates" in opts hideChangelistColumn = True hidePropertyStatusColumn = True hideLockColumns = True hideUpToDateColumn = True hideHistoryColumn = True hideSwitchedColumn = True locker = QMutexLocker(self.vcs.vcsExecutionMutex) cwd = os.getcwd() os.chdir(self.dname) try: for name in fnames: # step 1: determine changelists and their files changelistsDict = {} if hasattr(self.client, 'get_changelist'): if recurse: depth = pysvn.depth.infinity else: depth = pysvn.depth.immediate changelists = self.client.get_changelist(name, depth=depth) for fpath, changelist in changelists: if sys.version_info[0] == 2: fpath = fpath.decode('utf-8') changelist = changelist.decode('utf-8') fpath = Utilities.normcasepath(fpath) changelistsDict[fpath] = changelist hideChangelistColumn = hideChangelistColumn and \ len(changelistsDict) == 0 # step 2: determine status of files allFiles = self.client.status(name, recurse=recurse, get_all=verbose, ignore=True, update=update) counter = 0 for file in allFiles: uptodate = True if file.repos_text_status != pysvn.wc_status_kind.none: uptodate = uptodate and \ file.repos_text_status != \ pysvn.wc_status_kind.modified if file.repos_prop_status != pysvn.wc_status_kind.none: uptodate = uptodate and \ file.repos_prop_status != \ pysvn.wc_status_kind.modified lockState = " " if file.entry is not None and \ hasattr(file.entry, 'lock_token') and \ file.entry.lock_token is not None: lockState = "L" if hasattr(file, 'repos_lock') and update: if lockState == "L" and file.repos_lock is None: lockState = "B" elif lockState == " " and file.repos_lock is not None: lockState = "O" elif lockState == "L" and \ file.repos_lock is not None and \ file.entry.lock_token != \ file.repos_lock["token"]: lockState = "S" fpath = Utilities.normcasepath( os.path.join(self.dname, file.path)) if fpath in changelistsDict: changelist = changelistsDict[fpath] else: changelist = "" hidePropertyStatusColumn = hidePropertyStatusColumn and \ file.prop_status in [ pysvn.wc_status_kind.none, pysvn.wc_status_kind.normal ] hideLockColumns = hideLockColumns and \ not file.is_locked and lockState == " " hideUpToDateColumn = hideUpToDateColumn and uptodate hideHistoryColumn = hideHistoryColumn and \ not file.is_copied hideSwitchedColumn = hideSwitchedColumn and \ not file.is_switched self.__generateItem( changelist, file.text_status, file.prop_status, file.is_locked, file.is_copied, file.is_switched, lockState, uptodate, file.entry and file.entry.revision.number or "", file.entry and file.entry.commit_revision.number or "", file.entry and file.entry.commit_author or "", file.path ) counter += 1 if counter == 30: # check for cancel every 30 items counter = 0 if self._clientCancelCallback(): break if self._clientCancelCallback(): break except pysvn.ClientError as e: self.__showError(e.args[0] + '\n') self.statusList.setColumnHidden(self.__propStatusColumn, hidePropertyStatusColumn) self.statusList.setColumnHidden(self.__lockedColumn, hideLockColumns) self.statusList.setColumnHidden(self.__lockinfoColumn, hideLockColumns) self.statusList.setColumnHidden(self.__upToDateColumn, hideUpToDateColumn) self.statusList.setColumnHidden(self.__historyColumn, hideHistoryColumn) self.statusList.setColumnHidden(self.__switchedColumn, hideSwitchedColumn) self.statusList.setColumnHidden(self.__changelistColumn, hideChangelistColumn) locker.unlock() self.__finish() os.chdir(cwd) def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.refreshButton.setEnabled(True) self.__updateButtons() self.__updateCommitButton() self.__statusFilters.sort() self.__statusFilters.insert(0, "<{0}>".format(self.tr("all"))) self.statusFilterCombo.addItems(self.__statusFilters) for act in self.menuactions: act.setEnabled(True) self.__resizeColumns() self.__resort() self._cancel() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() elif button == self.refreshButton: self.on_refreshButton_clicked() @pyqtSlot() def on_refreshButton_clicked(self): """ Private slot to refresh the status display. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.refreshButton.setEnabled(False) self.statusList.clear() self.shouldCancel = False self.start(self.args) def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ self.errorGroup.show() self.errors.insertPlainText(msg) self.errors.ensureCursorVisible() def __updateButtons(self): """ Private method to update the VCS buttons status. """ modified = len(self.__getModifiedItems()) unversioned = len(self.__getUnversionedItems()) missing = len(self.__getMissingItems()) self.addButton.setEnabled(unversioned) self.diffButton.setEnabled(modified) self.sbsDiffButton.setEnabled(modified == 1) self.revertButton.setEnabled(modified) self.restoreButton.setEnabled(missing) def __updateCommitButton(self): """ Private method to update the Commit button status. """ commitable = len(self.__getCommitableItems()) self.commitButton.setEnabled(commitable) @pyqtSlot(str) def on_statusFilterCombo_activated(self, txt): """ Private slot to react to the selection of a status filter. @param txt selected status filter (string) """ if txt == "<{0}>".format(self.tr("all")): for topIndex in range(self.statusList.topLevelItemCount()): topItem = self.statusList.topLevelItem(topIndex) topItem.setHidden(False) else: for topIndex in range(self.statusList.topLevelItemCount()): topItem = self.statusList.topLevelItem(topIndex) topItem.setHidden(topItem.text(self.__statusColumn) != txt) @pyqtSlot(QTreeWidgetItem, int) def on_statusList_itemChanged(self, item, column): """ Private slot to act upon item changes. @param item reference to the changed item (QTreeWidgetItem) @param column index of column that changed (integer) """ if column == self.__toBeCommittedColumn: self.__updateCommitButton() @pyqtSlot() def on_statusList_itemSelectionChanged(self): """ Private slot to act upon changes of selected items. """ self.__updateButtons() @pyqtSlot() def on_commitButton_clicked(self): """ Private slot to handle the press of the Commit button. """ self.__commit() @pyqtSlot() def on_addButton_clicked(self): """ Private slot to handle the press of the Add button. """ self.__add() @pyqtSlot() def on_diffButton_clicked(self): """ Private slot to handle the press of the Differences button. """ self.__diff() @pyqtSlot() def on_sbsDiffButton_clicked(self): """ Private slot to handle the press of the Side-by-Side Diff button. """ self.__sbsDiff() @pyqtSlot() def on_revertButton_clicked(self): """ Private slot to handle the press of the Revert button. """ self.__revert() @pyqtSlot() def on_restoreButton_clicked(self): """ Private slot to handle the press of the Restore button. """ self.__restoreMissing() ########################################################################### ## Context menu handling methods ########################################################################### def __showContextMenu(self, coord): """ Private slot to show the context menu of the status list. @param coord the position of the mouse pointer (QPoint) """ self.menu.popup(self.statusList.mapToGlobal(coord)) def __commit(self): """ Private slot to handle the Commit context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getCommitableItems()] if not names: E5MessageBox.information( self, self.tr("Commit"), self.tr("""There are no entries selected to be""" """ committed.""")) return if Preferences.getVCS("AutoSaveFiles"): vm = e5App().getObject("ViewManager") for name in names: vm.saveEditor(name) self.vcs.vcsCommit(names, '') def __committed(self): """ Private slot called after the commit has finished. """ if self.isVisible(): self.on_refreshButton_clicked() self.vcs.checkVCSStatus() def __commitSelectAll(self): """ Private slot to select all entries for commit. """ self.__commitSelect(True) def __commitDeselectAll(self): """ Private slot to deselect all entries from commit. """ self.__commitSelect(False) def __add(self): """ Private slot to handle the Add context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getUnversionedItems()] if not names: E5MessageBox.information( self, self.tr("Add"), self.tr("""There are no unversioned entries""" """ available/selected.""")) return self.vcs.vcsAdd(names) self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus() def __revert(self): """ Private slot to handle the Revert context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Revert"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return self.vcs.vcsRevert(names) self.raise_() self.activateWindow() self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus() def __restoreMissing(self): """ Private slot to handle the Restore Missing context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getMissingItems()] if not names: E5MessageBox.information( self, self.tr("Revert"), self.tr("""There are no missing entries""" """ available/selected.""")) return self.vcs.vcsRevert(names) self.on_refreshButton_clicked() self.vcs.checkVCSStatus() def __diff(self): """ Private slot to handle the Diff context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Differences"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return if self.diff is None: from .SvnDiffDialog import SvnDiffDialog self.diff = SvnDiffDialog(self.vcs) self.diff.show() QApplication.processEvents() self.diff.start(names) def __sbsDiff(self): """ Private slot to handle the Side-by-Side Diff context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Side-by-Side Diff"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return elif len(names) > 1: E5MessageBox.information( self, self.tr("Side-by-Side Diff"), self.tr("""Only one file with uncommitted changes""" """ must be selected.""")) return self.vcs.svnSbsDiff(names[0]) def __lock(self): """ Private slot to handle the Lock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems(self.unlockedIndicators)] if not names: E5MessageBox.information( self, self.tr("Lock"), self.tr("""There are no unlocked files""" """ available/selected.""")) return self.vcs.svnLock(names, parent=self) self.on_refreshButton_clicked() def __unlock(self): """ Private slot to handle the Unlock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems(self.lockedIndicators)] if not names: E5MessageBox.information( self, self.tr("Unlock"), self.tr("""There are no locked files""" """ available/selected.""")) return self.vcs.svnUnlock(names, parent=self) self.on_refreshButton_clicked() def __breakLock(self): """ Private slot to handle the Break Lock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems( self.stealBreakLockIndicators)] if not names: E5MessageBox.information( self, self.tr("Break Lock"), self.tr("""There are no locked files""" """ available/selected.""")) return self.vcs.svnUnlock(names, parent=self, breakIt=True) self.on_refreshButton_clicked() def __stealLock(self): """ Private slot to handle the Break Lock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems( self.stealBreakLockIndicators)] if not names: E5MessageBox.information( self, self.tr("Steal Lock"), self.tr("""There are no locked files""" """ available/selected.""")) return self.vcs.svnLock(names, parent=self, stealIt=True) self.on_refreshButton_clicked() def __addToChangelist(self): """ Private slot to add entries to a changelist. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getNonChangelistItems()] if not names: E5MessageBox.information( self, self.tr("Remove from Changelist"), self.tr( """There are no files available/selected not """ """belonging to a changelist.""" ) ) return self.vcs.svnAddToChangelist(names) self.on_refreshButton_clicked() def __removeFromChangelist(self): """ Private slot to remove entries from their changelists. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getChangelistItems()] if not names: E5MessageBox.information( self, self.tr("Remove from Changelist"), self.tr( """There are no files available/selected belonging""" """ to a changelist.""" ) ) return self.vcs.svnRemoveFromChangelist(names) self.on_refreshButton_clicked() def __getCommitableItems(self): """ Private method to retrieve all entries the user wants to commit. @return list of all items, the user has checked """ commitableItems = [] for index in range(self.statusList.topLevelItemCount()): itm = self.statusList.topLevelItem(index) if itm.checkState(self.__toBeCommittedColumn) == Qt.Checked: commitableItems.append(itm) return commitableItems def __getModifiedItems(self): """ Private method to retrieve all entries, that have a modified status. @return list of all items with a modified status """ modifiedItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.modifiedIndicators or \ itm.text(self.__propStatusColumn) in self.modifiedIndicators: modifiedItems.append(itm) return modifiedItems def __getUnversionedItems(self): """ Private method to retrieve all entries, that have an unversioned status. @return list of all items with an unversioned status """ unversionedItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.unversionedIndicators: unversionedItems.append(itm) return unversionedItems def __getMissingItems(self): """ Private method to retrieve all entries, that have a missing status. @return list of all items with a missing status """ missingItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.missingIndicators: missingItems.append(itm) return missingItems def __getLockActionItems(self, indicators): """ Private method to retrieve all entries, that have a locked status. @param indicators list of indicators to check against (list of strings) @return list of all items with a locked status """ lockitems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__lockinfoColumn) in indicators: lockitems.append(itm) return lockitems def __getChangelistItems(self): """ Private method to retrieve all entries, that are members of a changelist. @return list of all items belonging to a changelist """ clitems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__changelistColumn): clitems.append(itm) return clitems def __getNonChangelistItems(self): """ Private method to retrieve all entries, that are not members of a changelist. @return list of all items not belonging to a changelist """ clitems = [] for itm in self.statusList.selectedItems(): if not itm.text(self.__changelistColumn): clitems.append(itm) return clitems def __commitSelect(self, selected): """ Private slot to select or deselect all entries. @param selected commit selection state to be set (boolean) """ for index in range(self.statusList.topLevelItemCount()): itm = self.statusList.topLevelItem(index) if itm.flags() & Qt.ItemIsUserCheckable: if selected: itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setCheckState(self.__toBeCommittedColumn, Qt.Unchecked) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnBlameDialog.py0000644000175000017500000001117212537064321023164 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn blame command. """ from __future__ import unicode_literals import os import sys import pysvn from PyQt5.QtCore import QMutexLocker, Qt from PyQt5.QtWidgets import QHeaderView, QDialog, QDialogButtonBox, \ QTreeWidgetItem from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnBlameDialog import Ui_SvnBlameDialog import Preferences class SvnBlameDialog(QDialog, SvnDialogMixin, Ui_SvnBlameDialog): """ Class implementing a dialog to show the output of the svn blame command. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnBlameDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.vcs = vcs self.blameList.headerItem().setText(self.blameList.columnCount(), "") font = Preferences.getEditorOtherFonts("MonospacedFont") self.blameList.setFont(font) self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback def start(self, fn): """ Public slot to start the svn status command. @param fn filename to show the log for (string) """ self.errorGroup.hide() self.activateWindow() dname, fname = self.vcs.splitPath(fn) locker = QMutexLocker(self.vcs.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) try: annotations = self.client.annotate(fname) locker.unlock() for annotation in annotations: author = annotation["author"] line = annotation["line"] if sys.version_info[0] == 2: author = author.decode('utf-8') line = line.decode('utf-8') self.__generateItem( annotation["revision"].number, author, annotation["number"] + 1, line) except pysvn.ClientError as e: locker.unlock() self.__showError(e.args[0] + '\n') self.__finish() os.chdir(cwd) def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.__resizeColumns() self._cancel() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __resizeColumns(self): """ Private method to resize the list columns. """ self.blameList.header().resizeSections(QHeaderView.ResizeToContents) def __generateItem(self, revision, author, lineno, text): """ Private method to generate a blame item in the blame list. @param revision revision string (string) @param author author of the change (string) @param lineno linenumber (string) @param text line of text from the annotated file (string) """ itm = QTreeWidgetItem( self.blameList, ["{0:d}".format(revision), author, "{0:d}".format(lineno), text]) itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(2, Qt.AlignRight) def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ self.errorGroup.show() self.errors.insertPlainText(msg) self.errors.ensureCursorVisible() eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnUrlSelectionDialog.py0000644000175000017500000001316412451233371024555 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the URLs for the svn diff command. """ from __future__ import unicode_literals from PyQt5.QtCore import QRegExp, pyqtSlot from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui import E5MessageBox import pysvn from .Ui_SvnUrlSelectionDialog import Ui_SvnUrlSelectionDialog import Utilities class SvnUrlSelectionDialog(QDialog, Ui_SvnUrlSelectionDialog): """ Class implementing a dialog to enter the URLs for the svn diff command. """ def __init__(self, vcs, tagsList, branchesList, path, parent=None): """ Constructor @param vcs reference to the vcs object @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param path pathname to determine the repository URL from (string) @param parent parent widget of the dialog (QWidget) """ super(SvnUrlSelectionDialog, self).__init__(parent) self.setupUi(self) if not hasattr(pysvn.Client(), 'diff_summarize'): self.summaryCheckBox.setEnabled(False) self.summaryCheckBox.setChecked(False) self.vcs = vcs self.tagsList = tagsList self.branchesList = branchesList self.typeCombo1.addItems(["trunk/", "tags/", "branches/"]) self.typeCombo2.addItems(["trunk/", "tags/", "branches/"]) reposURL = self.vcs.svnGetReposName(path) if reposURL is None: E5MessageBox.critical( self, self.tr("Subversion Error"), self.tr( """The URL of the project repository could not be""" """ retrieved from the working copy. The operation will""" """ be aborted""")) self.reject() return if self.vcs.otherData["standardLayout"]: # determine the base path of the project in the repository rx_base = QRegExp('(.+/)(trunk|tags|branches).*') if not rx_base.exactMatch(reposURL): E5MessageBox.critical( self, self.tr("Subversion Error"), self.tr( """The URL of the project repository has an""" """ invalid format. The operation will""" """ be aborted""")) self.reject() return reposRoot = rx_base.cap(1) self.repoRootLabel1.setText(reposRoot) self.repoRootLabel2.setText(reposRoot) else: project = e5App().getObject('Project') if Utilities.normcasepath(path) != \ Utilities.normcasepath(project.getProjectPath()): path = project.getRelativePath(path) reposURL = reposURL.replace(path, '') self.repoRootLabel1.hide() self.typeCombo1.hide() self.labelCombo1.addItems([reposURL] + sorted(self.vcs.tagsList)) self.labelCombo1.setEnabled(True) self.repoRootLabel2.hide() self.typeCombo2.hide() self.labelCombo2.addItems([reposURL] + sorted(self.vcs.tagsList)) self.labelCombo2.setEnabled(True) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __changeLabelCombo(self, labelCombo, type_): """ Private method used to change the label combo depending on the selected type. @param labelCombo reference to the labelCombo object (QComboBox) @param type_ type string (string) """ if type_ == "trunk/": labelCombo.clear() labelCombo.setEditText("") labelCombo.setEnabled(False) elif type_ == "tags/": labelCombo.clear() labelCombo.clearEditText() labelCombo.addItems(sorted(self.tagsList)) labelCombo.setEnabled(True) elif type_ == "branches/": labelCombo.clear() labelCombo.clearEditText() labelCombo.addItems(sorted(self.branchesList)) labelCombo.setEnabled(True) @pyqtSlot(str) def on_typeCombo1_currentIndexChanged(self, type_): """ Private slot called when the selected type was changed. @param type_ selected type (string) """ self.__changeLabelCombo(self.labelCombo1, type_) @pyqtSlot(str) def on_typeCombo2_currentIndexChanged(self, type_): """ Private slot called when the selected type was changed. @param type_ selected type (string) """ self.__changeLabelCombo(self.labelCombo2, type_) def getURLs(self): """ Public method to get the entered URLs. @return tuple of list of two URL strings (list of strings) and a flag indicating a diff summary (boolean) """ if self.vcs.otherData["standardLayout"]: url1 = self.repoRootLabel1.text() + \ self.typeCombo1.currentText() + \ self.labelCombo1.currentText() url2 = self.repoRootLabel2.text() + \ self.typeCombo2.currentText() + \ self.labelCombo2.currentText() else: url1 = self.labelCombo1.currentText() url2 = self.labelCombo2.currentText() return [url1, url2], self.summaryCheckBox.isChecked() eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnCommandDialog.ui0000644000175000017500000001334612354033554023515 0ustar piotrpiotr SvnCommandDialog 0 0 628 141 Subversion Command Subversion Command: 0 0 Enter the Subversion command to be executed with all necessary parameters <b>Subversion Command</b> <p>Enter the Subversion command to be executed including all necessary parameters. If a parameter of the commandline includes a space you have to surround this parameter by single or double quotes. Do not include the name of the subversion client executable (i.e. svn).</p> true QComboBox::InsertAtTop false 0 0 Enter the working directory for the Subversion command <b>Working directory</b> <p>Enter the working directory for the Subversion command. This is an optional entry. The button to the right will open a directory selection dialog.</p> true QComboBox::InsertAtTop false Working Directory:<br>(optional) 0 0 Project Directory: 0 0 This shows the root directory of the current project. project directory Select the working directory via a directory selection dialog <b>Working directory</b> <p>Select the working directory for the Subversion command via a directory selection dialog.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource commandCombo workdirCombo dirButton buttonBox buttonBox accepted() SvnCommandDialog accept() 27 103 27 119 buttonBox rejected() SvnCommandDialog reject() 137 100 137 123 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnTagDialog.ui0000644000175000017500000001170712354033674022654 0ustar piotrpiotr SvnTagDialog 0 0 391 197 Subversion Tag true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok 0 0 Enter the name of the tag <b>Tag Name</b> <p>Enter the name of the tag to be created, moved or deleted.</p> true false Name: Tag Action Select to create a regular tag <b>Create Regular Tag</b> <p>Select this entry in order to create a regular tag in the repository.</p> Create Regular Tag true Select to create a branch tag <b>Create Branch Tag</b> <p>Select this entry in order to create a branch in the repository.</p> Create Branch Tag Select to delete a regular tag <b>Delete Regular Tag</b> <p>Select this entry in order to delete the selected regular tag.</p> Delete Regular Tag Select to delete a branch tag <b>Delete Branch Tag</b> <p>Select this entry in order to delete the selected branch tag.</p> Delete Branch Tag qPixmapFromMimeSource tagCombo createRegularButton createBranchButton deleteRegularButton deleteBranchButton buttonBox accepted() SvnTagDialog accept() 24 163 24 186 buttonBox rejected() SvnTagDialog reject() 70 168 70 183 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnPropDelDialog.py0000644000175000017500000000322012451233371023502 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a new property. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_SvnPropDelDialog import Ui_SvnPropDelDialog class SvnPropDelDialog(QDialog, Ui_SvnPropDelDialog): """ Class implementing a dialog to enter the data for a new property. """ def __init__(self, recursive, parent=None): """ Constructor @param recursive flag indicating a recursive set is requested @param parent parent widget (QWidget) """ super(SvnPropDelDialog, self).__init__(parent) self.setupUi(self) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) self.recurseCheckBox.setChecked(recursive) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def on_propNameEdit_textChanged(self, text): """ Private method used to enable/disable the OK-button. @param text ignored """ self.okButton.setDisabled(text == "") def getData(self): """ Public slot used to retrieve the data entered into the dialog. @return tuple of two values giving the property name and a flag indicating, that this property should be applied recursively. (string, boolean) """ return (self.propNameEdit.text(), self.recurseCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnLogBrowserDialog.ui0000644000175000017500000002102012300444743024205 0ustar piotrpiotr SvnLogBrowserDialog 0 0 700 600 Subversion Log From: Enter the start date true To: Enter the end date true Select the field to filter on Revision Author Message Enter the regular expression to filter on 0 5 true QAbstractItemView::ExtendedSelection false false true true Revision Author Date Message 0 2 true 0 3 true false false true true Action Path Copy from Copy from Rev Press to get the next bunch of log entries &Next Enter the limit of entries to fetch Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 10000 20 Select to stop listing log messages at a copy or move Stop on Copy/Move Qt::Vertical Press to generate a diff to the previous revision &Diff to Previous Press to compare two revisions &Compare Revisions Qt::Horizontal 38 29 Select to show differences side-by-side Show differences side-by-side Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
fromDate toDate fieldCombo rxEdit logTree messageEdit filesTree nextButton limitSpinBox stopCheckBox diffPreviousButton diffRevisionsButton sbsCheckBox buttonBox
eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnSwitchDialog.py0000644000175000017500000000336112451233371023404 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a switch operation. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_SvnSwitchDialog import Ui_SvnSwitchDialog class SvnSwitchDialog(QDialog, Ui_SvnSwitchDialog): """ Class implementing a dialog to enter the data for a switch operation. """ def __init__(self, taglist, reposURL, standardLayout, parent=None): """ Constructor @param taglist list of previously entered tags (list of strings) @param reposURL repository path (string) or None @param standardLayout flag indicating the layout of the repository (boolean) @param parent parent widget (QWidget) """ super(SvnSwitchDialog, self).__init__(parent) self.setupUi(self) self.tagCombo.clear() self.tagCombo.addItems(sorted(taglist)) if reposURL is not None and reposURL != "": self.tagCombo.setEditText(reposURL) if not standardLayout: self.TagTypeGroup.setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getParameters(self): """ Public method to retrieve the tag data. @return tuple of string and int (tag, tag type) """ tag = self.tagCombo.currentText() tagType = 0 if self.regularButton.isChecked(): tagType = 1 elif self.branchButton.isChecked(): tagType = 2 if not tag: tagType = 4 return (tag, tagType) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/Config.py0000644000175000017500000002067712451233371021552 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module defining configuration variables for the subversion package. """ from __future__ import unicode_literals # Available protocols for the repository URL ConfigSvnProtocols = [ 'file://', 'http://', 'https://', 'svn://', 'svn+ssh://', ] DefaultConfig = "\n".join([ "### This file configures various client-side behaviors.", "###", "### The commented-out examples below are intended to demonstrate", "### how to use this file.", "", "### Section for authentication and authorization customizations.", "[auth]", "### Set password stores used by Subversion. They should be", "### delimited by spaces or commas. The order of values determines", "### the order in which password stores are used.", "### Valid password stores:", "### gnome-keyring (Unix-like systems)", "### kwallet (Unix-like systems)", "### keychain (Mac OS X)", "### windows-cryptoapi (Windows)", "# password-stores = keychain", "# password-stores = windows-cryptoapi", "# password-stores = gnome-keyring,kwallet", "### To disable all password stores, use an empty list:", "# password-stores =", "###", "### Set KWallet wallet used by Subversion. If empty or unset,", "### then the default network wallet will be used.", "# kwallet-wallet =", "###", "### Include PID (Process ID) in Subversion application name when", "### using KWallet. It defaults to 'no'.", "# kwallet-svn-application-name-with-pid = yes", "###", "### The rest of the [auth] section in this file has been deprecated.", "### Both 'store-passwords' and 'store-auth-creds' can now be", "### specified in the 'servers' file in your config directory", "### and are documented there. Anything specified in this section ", "### is overridden by settings specified in the 'servers' file.", "# store-passwords = no", "# store-auth-creds = no", "", "### Section for configuring external helper applications.", "[helpers]", "### Set editor-cmd to the command used to invoke your text editor.", "### This will override the environment variables that Subversion", "### examines by default to find this information ($EDITOR, ", "### et al).", "# editor-cmd = editor (vi, emacs, notepad, etc.)", "### Set diff-cmd to the absolute path of your 'diff' program.", "### This will override the compile-time default, which is to use", "### Subversion's internal diff implementation.", "# diff-cmd = diff_program (diff, gdiff, etc.)", "### Diff-extensions are arguments passed to an external diff", "### program or to Subversion's internal diff implementation.", "### Set diff-extensions to override the default arguments ('-u').", "# diff-extensions = -u -p", "### Set diff3-cmd to the absolute path of your 'diff3' program.", "### This will override the compile-time default, which is to use", "### Subversion's internal diff3 implementation.", "# diff3-cmd = diff3_program (diff3, gdiff3, etc.)", "### Set diff3-has-program-arg to 'yes' if your 'diff3' program", "### accepts the '--diff-program' option.", "# diff3-has-program-arg = [yes | no]", "### Set merge-tool-cmd to the command used to invoke your external", "### merging tool of choice. Subversion will pass 5 arguments to", "### the specified command: base theirs mine merged wcfile", "# merge-tool-cmd = merge_command", "", "### Section for configuring tunnel agents.", "[tunnels]", "### Configure svn protocol tunnel schemes here. By default, only", "### the 'ssh' scheme is defined. You can define other schemes to", "### be used with 'svn+scheme://hostname/path' URLs. A scheme", "### definition is simply a command, optionally prefixed by an", "### environment variable name which can override the command if it", "### is defined. The command (or environment variable) may contain", "### arguments, using standard shell quoting for arguments with", "### spaces. The command will be invoked as:", "### svnserve -t", "### (If the URL includes a username, then the hostname will be", "### passed to the tunnel agent as @.) If the", "### built-in ssh scheme were not predefined, it could be defined", "### as:", "# ssh = $SVN_SSH ssh -q", "### If you wanted to define a new 'rsh' scheme, to be used with", "### 'svn+rsh:' URLs, you could do so as follows:", "# rsh = rsh", "### Or, if you wanted to specify a full path and arguments:", "# rsh = /path/to/rsh -l myusername", "### On Windows, if you are specifying a full path to a command,", "### use a forward slash (/) or a paired backslash (\\\\) as the", "### path separator. A single backslash will be treated as an", "### escape for the following character.", "", "### Section for configuring miscelleneous Subversion options.", "[miscellany]", "### Set global-ignores to a set of whitespace-delimited globs", "### which Subversion will ignore in its 'status' output, and", "### while importing or adding files and directories.", "### '*' matches leading dots, e.g. '*.rej' matches '.foo.rej'.", "global-ignores = *.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc", " *.pyo .*.rej *.rej .*~ *~ #*# .#* .*.swp .DS_Store", " *.orig *.bak cur tmp __pycache__ .directory", " .ropeproject .eric4project .eric5project .eric6project", " _ropeproject _eric4project _eric5project _eric6project", "### Set log-encoding to the default encoding for log messages", "# log-encoding = latin1", "### Set use-commit-times to make checkout/update/switch/revert", "### put last-committed timestamps on every file touched.", "# use-commit-times = yes", "### Set no-unlock to prevent 'svn commit' from automatically", "### releasing locks on files.", "# no-unlock = yes", "### Set mime-types-file to a MIME type registry file, used to", "### provide hints to Subversion's MIME type auto-detection", "### algorithm.", "# mime-types-file = /path/to/mime.types", "### Set preserved-conflict-file-exts to a whitespace-delimited", "### list of patterns matching file extensions which should be", "### preserved in generated conflict file names. By default,", "### conflict files use custom extensions.", "# preserved-conflict-file-exts = doc ppt xls od?", "### Set enable-auto-props to 'yes' to enable automatic properties", "### for 'svn add' and 'svn import', it defaults to 'no'.", "### Automatic properties are defined in the section 'auto-props'.", "# enable-auto-props = yes", "### Set interactive-conflicts to 'no' to disable interactive", "### conflict resolution prompting. It defaults to 'yes'.", "# interactive-conflicts = no", "### Set memory-cache-size to define the size of the memory cache", "### used by the client when accessing a FSFS repository via", "### ra_local (the file:// scheme). The value represents the number", "### of MB used by the cache.", "# memory-cache-size = 16", "", "### Section for configuring automatic properties.", "[auto-props]", "### The format of the entries is:", "### file-name-pattern = propname[=value][;propname[=value]...]", "### The file-name-pattern can contain wildcards (such as '*' and", "### '?'). All entries which match (case-insensitively) will be", "### applied to the file. Note that auto-props functionality", "### must be enabled, which is typically done by setting the", "### 'enable-auto-props' option.", "# *.c = svn:eol-style=native", "# *.cpp = svn:eol-style=native", "# *.h = svn:keywords=Author Date Id Rev URL;svn:eol-style=native", "# *.dsp = svn:eol-style=CRLF", "# *.dsw = svn:eol-style=CRLF", "# *.sh = svn:eol-style=native;svn:executable", "# *.txt = svn:eol-style=native;svn:keywords=Author Date Id Rev URL;", "# *.png = svn:mime-type=image/png", "# *.jpg = svn:mime-type=image/jpeg", "# Makefile = svn:eol-style=native", "", ]) DefaultIgnores = [ "*.orig", "*.bak", "cur", "tmp", "__pycache__", ".directory", ".ropeproject", ".eric4project", ".eric5project", ".eric6project", "_ropeproject", "_eric4project", "_eric5project", "_eric6project", ] eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnRevisionSelectionDialog.ui0000644000175000017500000003213312203730423025566 0ustar piotrpiotr SvnRevisionSelectionDialog 0 0 399 519 Subversion Diff true Revision &1 Select revision before last commit PREV Select last committed revision COMMITTED Select base revision BASE Select head revision of repository HEAD true Select working revision WORKING false false 0 0 Enter a revision number Qt::AlignRight 1 999999999 false Enter time of revision false Enter date of revision yyyy-MM-dd true Qt::Horizontal 40 20 Select to specify a revision by number Number Select to specify a revision by date and time Date Revision &2 Select revision before last commit PREV Select last committed revision COMMITTED Select base revision BASE Select head revision of repository HEAD false Select working revision WORKING true false 0 0 Enter a revision number Qt::AlignRight 1 999999999 false Enter time of revision false Enter date of revision yyyy-MM-dd true Qt::Horizontal 40 20 Select to specify a revision by number Number Select to specify a revision by date and time Date Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource number1Button number1SpinBox date1Button date1Edit time1Edit head1Button working1Button base1Button committed1Button prev1Button number2Button number2SpinBox date2Button date2Edit time2Edit head2Button working2Button base2Button committed2Button prev2Button buttonBox buttonBox accepted() SvnRevisionSelectionDialog accept() 27 512 21 143 buttonBox rejected() SvnRevisionSelectionDialog reject() 79 512 73 140 number1Button toggled(bool) number1SpinBox setEnabled(bool) 62 45 148 43 date1Button toggled(bool) date1Edit setEnabled(bool) 70 77 136 74 date1Button toggled(bool) time1Edit setEnabled(bool) 16 74 257 74 number2Button toggled(bool) number2SpinBox setEnabled(bool) 32 281 128 283 date2Button toggled(bool) date2Edit setEnabled(bool) 49 310 134 310 date2Button toggled(bool) time2Edit setEnabled(bool) 55 322 264 320 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnCommitDialog.ui0000644000175000017500000000576212060166053023365 0ustar piotrpiotr SvnCommitDialog 0 0 450 396 Subversion Commit Message Enter the log message. <b>Log Message</b> <p>Enter the log message for the commit action.</p> true false Recent commit messages Select a recent commit message to use Changelists Select the change lists to limit the commit Select to keep the changelists Keep changelists Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok qPixmapFromMimeSource logEdit recentComboBox changeLists keepChangeListsCheckBox buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnRelocateDialog.ui0000644000175000017500000000566612060166053023676 0ustar piotrpiotr SvnRelocateDialog 0 0 531 119 Subversion Relocate true QFrame::StyledPanel New repository URL: Enter the URL of the repository the working space should be relocated to Current repository URL: Select, if the relocate should happen inside the repository Relocate inside repository (used, if the repository layout has changed) Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok newUrlEdit insideCheckBox buttonBox buttonBox accepted() SvnRelocateDialog accept() 31 75 29 92 buttonBox rejected() SvnRelocateDialog reject() 69 74 69 95 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnNewProjectOptionsDialog.ui0000644000175000017500000001504212263303530025557 0ustar piotrpiotr SvnNewProjectOptionsDialog 0 0 562 200 New Project from Repository <b>New Project from Repository Dialog</b> <p>Enter the various repository infos into the entry fields. These values are used, when the new project is retrieved from the repository. If the checkbox is selected, the URL must end in the project name. A repository layout with project/tags, project/branches and project/trunk will be assumed. In this case, you may enter a tag or branch, which must look like tags/tagname or branches/branchname. If the checkbox is not selected, the URL must contain the complete path in the repository.</p> <p>For remote repositories the URL must contain the hostname.</p> true Enter the tag the new project should be generated from <b>Tag in VCS</b> <p>Enter the tag name the new project shall be generated from. Leave empty to retrieve the latest data from the repository.</p> Select the protocol to access the repository &Protocol: protocolCombo Enter the url path of the module in the repository (without protocol part) <b>URL</b><p>Enter the URL to the module. For a repository with standard layout, this must not contain the trunk, tags or branches part.</p> &URL: vcsUrlEdit Enter the directory of the new project. <b>Project Directory</b> <p>Enter the directory of the new project. It will be retrieved from the repository and be placed in this directory.</p> Select to indicate, that the repository has a standard layout (projectdir/trunk, projectdir/tags, projectdir/branches) Repository has standard &layout Alt+L true Project &Directory: vcsProjectDirEdit &Tag: vcsTagEdit Select the repository url via a directory selection dialog or the repository browser Select the project directory via a directory selection dialog Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource protocolCombo vcsUrlEdit vcsUrlButton vcsTagEdit vcsProjectDirEdit projectDirButton layoutCheckBox buttonBox accepted() SvnNewProjectOptionsDialog accept() 29 157 29 181 buttonBox rejected() SvnNewProjectOptionsDialog reject() 129 163 129 177 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnMergeDialog.py0000644000175000017500000000632612451233371023206 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a merge operation. """ from __future__ import unicode_literals from PyQt5.QtCore import QRegExp from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_SvnMergeDialog import Ui_SvnMergeDialog class SvnMergeDialog(QDialog, Ui_SvnMergeDialog): """ Class implementing a dialog to enter the data for a merge operation. """ def __init__(self, mergelist1, mergelist2, targetlist, force=False, parent=None): """ Constructor @param mergelist1 list of previously entered URLs/revisions (list of strings) @param mergelist2 list of previously entered URLs/revisions (list of strings) @param targetlist list of previously entered targets (list of strings) @param force flag indicating a forced merge (boolean) @param parent parent widget (QWidget) """ super(SvnMergeDialog, self).__init__(parent) self.setupUi(self) self.forceCheckBox.setChecked(force) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) self.rx_url = QRegExp('(?:file:|svn:|svn+ssh:|http:|https:)//.+') self.rx_rev = QRegExp('\\d+') self.tag1Combo.clear() self.tag1Combo.addItems(mergelist1) self.tag2Combo.clear() self.tag2Combo.addItems(mergelist2) self.targetCombo.clear() self.targetCombo.addItems(targetlist) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __enableOkButton(self): """ Private method used to enable/disable the OK-button. """ self.okButton.setDisabled( self.tag1Combo.currentText() == "" or self.tag2Combo.currentText() == "" or not ((self.rx_url.exactMatch(self.tag1Combo.currentText()) and self.rx_url.exactMatch(self.tag2Combo.currentText())) or (self.rx_rev.exactMatch(self.tag1Combo.currentText()) and self.rx_rev.exactMatch(self.tag2Combo.currentText())) ) ) def on_tag1Combo_editTextChanged(self, text): """ Private slot to handle the tag1Combo editTextChanged signal. @param text text of the combo (string) """ self.__enableOkButton() def on_tag2Combo_editTextChanged(self, text): """ Private slot to handle the tag2Combo editTextChanged signal. @param text text of the combo (string) """ self.__enableOkButton() def getParameters(self): """ Public method to retrieve the merge data. @return tuple naming two tag names or two revisions, a target and a flag indicating a forced merge (string, string, string, boolean) """ return (self.tag1Combo.currentText(), self.tag2Combo.currentText(), self.targetCombo.currentText(), self.forceCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnRevisionSelectionDialog.py0000644000175000017500000000571712451233371025616 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the revisions for the svn diff command. """ from __future__ import unicode_literals from PyQt5.QtCore import QDate, QDateTime, Qt from PyQt5.QtWidgets import QDialog from .Ui_SvnRevisionSelectionDialog import Ui_SvnRevisionSelectionDialog class SvnRevisionSelectionDialog(QDialog, Ui_SvnRevisionSelectionDialog): """ Class implementing a dialog to enter the revisions for the svn diff command. """ def __init__(self, parent=None): """ Constructor @param parent parent widget of the dialog (QWidget) """ super(SvnRevisionSelectionDialog, self).__init__(parent) self.setupUi(self) self.date1Edit.setDate(QDate.currentDate()) self.date2Edit.setDate(QDate.currentDate()) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __getRevision(self, no): """ Private method to generate the revision. @param no revision number to generate (1 or 2) @return revision (integer or string) """ if no == 1: numberButton = self.number1Button numberSpinBox = self.number1SpinBox dateButton = self.date1Button dateEdit = self.date1Edit timeEdit = self.time1Edit headButton = self.head1Button workingButton = self.working1Button baseButton = self.base1Button committedButton = self.committed1Button prevButton = self.prev1Button else: numberButton = self.number2Button numberSpinBox = self.number2SpinBox dateButton = self.date2Button dateEdit = self.date2Edit timeEdit = self.time2Edit headButton = self.head2Button workingButton = self.working2Button baseButton = self.base2Button committedButton = self.committed2Button prevButton = self.prev2Button if numberButton.isChecked(): return numberSpinBox.value() elif dateButton.isChecked(): return "{{{0}}}".format( QDateTime(dateEdit.date(), timeEdit.time()) .toString(Qt.ISODate)) elif headButton.isChecked(): return "HEAD" elif workingButton.isChecked(): return "WORKING" elif baseButton.isChecked(): return "BASE" elif committedButton.isChecked(): return "COMMITTED" elif prevButton.isChecked(): return "PREV" def getRevisions(self): """ Public method to get the revisions. @return list two integers or strings """ rev1 = self.__getRevision(1) rev2 = self.__getRevision(2) return [rev1, rev2] eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.ui0000644000175000017500000001706212203730423023411 0ustar piotrpiotr SvnStatusDialog 0 0 955 646 Subversion Status <b>Subversion Status</b> <p>This dialog shows the status of the selected file or project.</p> Qt::Horizontal 40 20 &Filter on Status: statusFilterCombo Select the status of entries to be shown QComboBox::AdjustToContents 0 4 true QAbstractItemView::ExtendedSelection false false true Commit Changelist Status Prop. Status Locked History Switched Lock Info Up to date Revision Last Change Author Path Commit the selected changes &Commit Qt::Vertical Add the selected entries to the repository &Add Show differences of the selected entries to the repository &Differences Show differences of the selected entry to the repository in a side-by-side manner Side-b&y-Side Diff Revert the selected entries to the last revision in the repository Re&vert Restore the selected missing entries from the repository &Restore Qt::Horizontal 40 20 0 1 Errors true false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource statusFilterCombo statusList commitButton addButton diffButton sbsDiffButton revertButton restoreButton errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnCommitDialog.py0000644000175000017500000001021312451233371023365 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the commit message. """ from __future__ import unicode_literals import pysvn from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot from PyQt5.QtWidgets import QWidget, QDialogButtonBox from .Ui_SvnCommitDialog import Ui_SvnCommitDialog import Preferences class SvnCommitDialog(QWidget, Ui_SvnCommitDialog): """ Class implementing a dialog to enter the commit message. @signal accepted() emitted, if the dialog was accepted @signal rejected() emitted, if the dialog was rejected """ accepted = pyqtSignal() rejected = pyqtSignal() def __init__(self, changelists, parent=None): """ Constructor @param changelists list of available change lists (list of strings) @param parent parent widget (QWidget) """ super(SvnCommitDialog, self).__init__( parent, Qt.WindowFlags(Qt.Window)) self.setupUi(self) if pysvn.svn_version < (1, 5, 0) or pysvn.version < (1, 6, 0): self.changeListsGroup.hide() else: self.changeLists.addItems(sorted(changelists)) def showEvent(self, evt): """ Protected method called when the dialog is about to be shown. @param evt the event (QShowEvent) """ self.recentCommitMessages = Preferences.toList( Preferences.Prefs.settings.value('Subversion/Commits')) self.recentComboBox.clear() self.recentComboBox.addItem("") self.recentComboBox.addItems(self.recentCommitMessages) def logMessage(self): """ Public method to retrieve the log message. This method has the side effect of saving the 20 most recent commit messages for reuse. @return the log message (string) """ msg = self.logEdit.toPlainText() if msg: if msg in self.recentCommitMessages: self.recentCommitMessages.remove(msg) self.recentCommitMessages.insert(0, msg) no = int(Preferences.Prefs.settings.value( 'Subversion/CommitMessages', 20)) del self.recentCommitMessages[no:] Preferences.Prefs.settings.setValue( 'Subversion/Commits', self.recentCommitMessages) return msg def hasChangelists(self): """ Public method to check, if the user entered some changelists. @return flag indicating availability of changelists (boolean) """ return len(self.changeLists.selectedItems()) > 0 def changelistsData(self): """ Public method to retrieve the changelists data. @return tuple containing the changelists (list of strings) and a flag indicating to keep changelists (boolean) """ slists = [l.text().strip() for l in self.changeLists.selectedItems() if l.text().strip() != ""] if len(slists) == 0: return [], False return slists, self.keepChangeListsCheckBox.isChecked() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Cancel): self.logEdit.clear() def on_buttonBox_accepted(self): """ Private slot called by the buttonBox accepted signal. """ self.close() self.accepted.emit() def on_buttonBox_rejected(self): """ Private slot called by the buttonBox rejected signal. """ self.close() self.rejected.emit() @pyqtSlot(str) def on_recentComboBox_activated(self, txt): """ Private slot to select a commit message from recent ones. @param txt selected recent commit message (string) """ if txt: self.logEdit.setPlainText(txt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnUrlSelectionDialog.ui0000644000175000017500000000767212060166053024547 0ustar piotrpiotr SvnUrlSelectionDialog 0 0 542 195 Subversion Diff true Repository URL 1 Select the URL type 0 0 Enter the label name or path true Repository URL 2 Select the URL type 0 0 Enter the label name or path true Select to just show a summary of differences Summary only Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok typeCombo1 labelCombo1 typeCombo2 labelCombo2 summaryCheckBox buttonBox buttonBox accepted() SvnUrlSelectionDialog accept() 230 188 157 178 buttonBox rejected() SvnUrlSelectionDialog reject() 292 166 286 178 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnRelocateDialog.py0000644000175000017500000000240412451233371023676 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c)2015 Detlev Offenbach # """ Module implementing a dialog to enter the data to relocate the workspace. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_SvnRelocateDialog import Ui_SvnRelocateDialog class SvnRelocateDialog(QDialog, Ui_SvnRelocateDialog): """ Class implementing a dialog to enter the data to relocate the workspace. """ def __init__(self, currUrl, parent=None): """ Constructor @param currUrl current repository URL (string) @param parent parent widget (QWidget) """ super(SvnRelocateDialog, self).__init__(parent) self.setupUi(self) self.currUrlLabel.setText(currUrl) self.newUrlEdit.setText(currUrl) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public slot used to retrieve the data entered into the dialog. @return the new repository URL (string) and an indication, if the relocate is inside the repository (boolean) """ return self.newUrlEdit.text(), self.insideCheckBox.isChecked() eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnPropListDialog.py0000644000175000017500000001301312451233371023712 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn proplist command process. """ from __future__ import unicode_literals import os import sys import pysvn from PyQt5.QtCore import QMutexLocker, Qt from PyQt5.QtWidgets import QWidget, QHeaderView, QApplication, \ QDialogButtonBox, QTreeWidgetItem from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnPropListDialog import Ui_SvnPropListDialog class SvnPropListDialog(QWidget, SvnDialogMixin, Ui_SvnPropListDialog): """ Class implementing a dialog to show the output of the svn proplist command process. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnPropListDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.vcs = vcs self.propsList.headerItem().setText(self.propsList.columnCount(), "") self.propsList.header().setSortIndicator(0, Qt.AscendingOrder) self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback def __resort(self): """ Private method to resort the tree. """ self.propsList.sortItems( self.propsList.sortColumn(), self.propsList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.propsList.header().resizeSections(QHeaderView.ResizeToContents) self.propsList.header().setStretchLastSection(True) def __generateItem(self, path, propName, propValue): """ Private method to generate a properties item in the properties list. @param path file/directory name the property applies to (string) @param propName name of the property (string) @param propValue value of the property (string) """ QTreeWidgetItem(self.propsList, [path, propName, propValue]) def start(self, fn, recursive=False): """ Public slot to start the svn status command. @param fn filename(s) (string or list of strings) @param recursive flag indicating a recursive list is requested """ self.errorGroup.hide() QApplication.processEvents() self.propsFound = False if isinstance(fn, list): dname, fnames = self.vcs.splitPathList(fn) else: dname, fname = self.vcs.splitPath(fn) fnames = [fname] locker = QMutexLocker(self.vcs.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) try: for name in fnames: proplist = self.client.proplist(name, recurse=recursive) counter = 0 for path, prop in proplist: if sys.version_info[0] == 2: path = path.decode('utf-8') for propName, propVal in list(prop.items()): if sys.version_info[0] == 2: propName = propName.decode('utf-8') propVal = propVal.decode('utf-8') self.__generateItem(path, propName, propVal) self.propsFound = True counter += 1 if counter == 30: # check for cancel every 30 items counter = 0 if self._clientCancelCallback(): break if self._clientCancelCallback(): break except pysvn.ClientError as e: self.__showError(e.args[0]) locker.unlock() self.__finish() os.chdir(cwd) def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if not self.propsFound: self.__generateItem("", self.tr("None"), "") self.__resort() self.__resizeColumns() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self._cancel() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ self.errorGroup.show() self.errors.insertPlainText(msg) self.errors.ensureCursorVisible() eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/0000755000175000017500000000000012557365404023375 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.py0000644000175000017500000000364712451233371026703 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Subversion configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from Preferences.ConfigurationPages.ConfigurationPageBase import \ ConfigurationPageBase from .Ui_SubversionPage import Ui_SubversionPage class SubversionPage(ConfigurationPageBase, Ui_SubversionPage): """ Class implementing the Subversion configuration page. """ def __init__(self, plugin): """ Constructor @param plugin reference to the plugin object """ super(SubversionPage, self).__init__() self.setupUi(self) self.setObjectName("SubversionPage") self.__plugin = plugin # set initial values self.logSpinBox.setValue(self.__plugin.getPreferences("LogLimit")) self.commitSpinBox.setValue( self.__plugin.getPreferences("CommitMessages")) def save(self): """ Public slot to save the Subversion configuration. """ self.__plugin.setPreferences("LogLimit", self.logSpinBox.value()) self.__plugin.setPreferences( "CommitMessages", self.commitSpinBox.value()) @pyqtSlot() def on_configButton_clicked(self): """ Private slot to edit the Subversion config file. """ from QScintilla.MiniEditor import MiniEditor cfgFile = self.__plugin.getConfigPath() editor = MiniEditor(cfgFile, "Properties", self) editor.show() @pyqtSlot() def on_serversButton_clicked(self): """ Private slot to edit the Subversion servers file. """ from QScintilla.MiniEditor import MiniEditor serversFile = self.__plugin.getServersPath() editor = MiniEditor(serversFile, "Properties", self) editor.show() eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/__init__.py0000644000175000017500000000025012451233371025471 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package implementing the the subversion configuration page. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.ui0000644000175000017500000001000612060166053026651 0ustar piotrpiotr SubversionPage 0 0 402 354 <b>Configure Subversion Interface</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Log No. of log messages shown: Enter the number of log messages to be shown Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 999999 Qt::Horizontal 41 20 Commit No. of commit messages to remember: Enter the number of commit messages to remember Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 100 Qt::Horizontal 40 20 Edit the subversion config file Edit config file Edit the subversion servers file Edit servers file Qt::Vertical 388 31 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnCopyDialog.ui0000644000175000017500000000732312263303417023044 0ustar piotrpiotr SvnCopyDialog 0 0 409 138 Subversion Copy true Source: Shows the name of the source <b>Source name</b> <p>This field shows the name of the source.</p> true Enter the target name <b>Target name</b> <p>Enter the new name in this field. The target must be the new name or an absolute path.</p> Target: Press to open a selection dialog <b>Target name</b> <p>Select the target name for the operation via a selection dialog.</p> Select to force the operation Enforce operation Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource targetEdit dirButton forceCheckBox buttonBox sourceEdit buttonBox accepted() SvnCopyDialog accept() 32 79 32 97 buttonBox rejected() SvnCopyDialog reject() 101 80 101 97 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnPropListDialog.ui0000644000175000017500000000563512060166053023710 0ustar piotrpiotr SvnPropListDialog 0 0 826 569 Subversion List Properties <b>Subversion List Prperties</b> <p>This dialog shows the properties of the selected file or project.</p> 0 3 <b>Properties List</b> <p>This shows the properties of the selected file or project.</p> true false false true Path Name Value 0 1 Errors <b>Subversion proplist errors</b> <p>This shows possible error messages of the subversion proplist command.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource propsList errors eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.py0000644000175000017500000004242612461215125023016 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the svn diff command process. """ from __future__ import unicode_literals import os import sys import pysvn from PyQt5.QtCore import QMutexLocker, QFileInfo, QDateTime, Qt, pyqtSlot from PyQt5.QtGui import QColor, QCursor, QBrush, QTextCursor from PyQt5.QtWidgets import QWidget, QApplication, QDialogButtonBox from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnDiffDialog import Ui_SvnDiffDialog import Utilities import Preferences class SvnDiffDialog(QWidget, SvnDialogMixin, Ui_SvnDiffDialog): """ Class implementing a dialog to show the output of the svn diff command. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnDiffDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.buttonBox.button(QDialogButtonBox.Save).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.vcs = vcs font = Preferences.getEditorOtherFonts("MonospacedFont") self.contents.setFontFamily(font.family()) self.contents.setFontPointSize(font.pointSize()) self.cNormalFormat = self.contents.currentCharFormat() self.cAddedFormat = self.contents.currentCharFormat() self.cAddedFormat.setBackground(QBrush(QColor(190, 237, 190))) self.cRemovedFormat = self.contents.currentCharFormat() self.cRemovedFormat.setBackground(QBrush(QColor(237, 190, 190))) self.cLineNoFormat = self.contents.currentCharFormat() self.cLineNoFormat.setBackground(QBrush(QColor(255, 220, 168))) self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback def __getVersionArg(self, version): """ Private method to get a pysvn revision object for the given version number. @param version revision (integer or string) @return revision object (pysvn.Revision) """ if isinstance(version, int): return pysvn.Revision(pysvn.opt_revision_kind.number, version) elif version.startswith("{"): dateStr = version[1:-1] secs = QDateTime.fromString(dateStr, Qt.ISODate).toTime_t() return pysvn.Revision(pysvn.opt_revision_kind.date, secs) elif version == "HEAD": return pysvn.Revision(pysvn.opt_revision_kind.head) elif version == "COMMITTED": return pysvn.Revision(pysvn.opt_revision_kind.committed) elif version == "BASE": return pysvn.Revision(pysvn.opt_revision_kind.base) elif version == "WORKING": return pysvn.Revision(pysvn.opt_revision_kind.working) elif version == "PREV": return pysvn.Revision(pysvn.opt_revision_kind.previous) else: return pysvn.Revision(pysvn.opt_revision_kind.unspecified) def __getDiffSummaryKind(self, summaryKind): """ Private method to get a string descripion of the diff summary. @param summaryKind (pysvn.diff_summarize.summarize_kind) @return one letter string indicating the change type (string) """ if summaryKind == pysvn.diff_summarize_kind.delete: return "D" elif summaryKind == pysvn.diff_summarize_kind.modified: return "M" elif summaryKind == pysvn.diff_summarize_kind.added: return "A" elif summaryKind == pysvn.diff_summarize_kind.normal: return "N" else: return " " def start(self, fn, versions=None, urls=None, summary=False, pegRev=None): """ Public slot to start the svn diff command. @param fn filename to be diffed (string) @param versions list of versions to be diffed (list of up to 2 integer or None) @keyparam urls list of repository URLs (list of 2 strings) @keyparam summary flag indicating a summarizing diff (only valid for URL diffs) (boolean) @keyparam pegRev revision number the filename is valid (integer) """ self.buttonBox.button(QDialogButtonBox.Save).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self._reset() self.errorGroup.hide() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.filename = fn self.contents.clear() self.paras = 0 self.filesCombo.clear() self.__oldFile = "" self.__oldFileLine = -1 self.__fileSeparators = [] if Utilities.hasEnvironmentEntry('TEMP'): tmpdir = Utilities.getEnvironmentEntry('TEMP') elif Utilities.hasEnvironmentEntry('TMPDIR'): tmpdir = Utilities.getEnvironmentEntry('TMPDIR') elif Utilities.hasEnvironmentEntry('TMP'): tmpdir = Utilities.getEnvironmentEntry('TMP') elif os.path.exists('/var/tmp'): tmpdir = '/var/tmp' elif os.path.exists('/usr/tmp'): tmpdir = '/usr/tmp' elif os.path.exists('/tmp'): tmpdir = '/tmp' else: E5MessageBox.critical( self, self.tr("Subversion Diff"), self.tr("""There is no temporary directory available.""")) return tmpdir = os.path.join(tmpdir, 'svn_tmp') if not os.path.exists(tmpdir): os.mkdir(tmpdir) opts = self.vcs.options['global'] + self.vcs.options['diff'] recurse = "--non-recursive" not in opts if versions is not None: self.raise_() self.activateWindow() rev1 = self.__getVersionArg(versions[0]) if len(versions) == 1: rev2 = self.__getVersionArg("WORKING") else: rev2 = self.__getVersionArg(versions[1]) else: rev1 = self.__getVersionArg("BASE") rev2 = self.__getVersionArg("WORKING") if urls is not None: rev1 = self.__getVersionArg("HEAD") rev2 = self.__getVersionArg("HEAD") if isinstance(fn, list): dname, fnames = self.vcs.splitPathList(fn) else: dname, fname = self.vcs.splitPath(fn) fnames = [fname] locker = QMutexLocker(self.vcs.vcsExecutionMutex) cwd = os.getcwd() os.chdir(dname) try: dname = e5App().getObject('Project').getRelativePath(dname) if dname: dname += "/" for name in fnames: self.__showError( self.tr("Processing file '{0}'...\n").format(name)) if urls is not None: url1 = "{0}/{1}{2}".format(urls[0], dname, name) url2 = "{0}/{1}{2}".format(urls[1], dname, name) if summary: diff_summary = self.client.diff_summarize( url1, revision1=rev1, url_or_path2=url2, revision2=rev2, recurse=recurse) diff_list = [] for diff_sum in diff_summary: path = diff_sum['path'] if sys.version_info[0] == 2: path = path.decode('utf-8') diff_list.append("{0} {1}".format( self.__getDiffSummaryKind( diff_sum['summarize_kind']), path)) diffText = os.linesep.join(diff_list) else: diffText = self.client.diff( tmpdir, url1, revision1=rev1, url_or_path2=url2, revision2=rev2, recurse=recurse) if sys.version_info[0] == 2: diffText = diffText.decode('utf-8') else: if pegRev is not None: diffText = self.client.diff_peg( tmpdir, name, peg_revision=self.__getVersionArg(pegRev), revision_start=rev1, revision_end=rev2, recurse=recurse) else: diffText = self.client.diff( tmpdir, name, revision1=rev1, revision2=rev2, recurse=recurse) if sys.version_info[0] == 2: diffText = diffText.decode('utf-8') counter = 0 for line in diffText.splitlines(): if line.startswith("--- ") or \ line.startswith("+++ "): self.__processFileLine(line) self.__appendText("{0}{1}".format(line, os.linesep)) counter += 1 if counter == 30: # check for cancel every 30 lines counter = 0 if self._clientCancelCallback(): break if self._clientCancelCallback(): break except pysvn.ClientError as e: self.__showError(e.args[0]) locker.unlock() os.chdir(cwd) self.__finish() if self.paras == 0: self.contents.setCurrentCharFormat(self.cNormalFormat) self.contents.setPlainText( self.tr('There is no difference.')) self.buttonBox.button(QDialogButtonBox.Save).setEnabled(self.paras > 0) def __appendText(self, line): """ Private method to append text to the end of the contents pane. @param line line of text to insert (string) """ if line.startswith('+') or line.startswith('>') or \ line.startswith('A '): format = self.cAddedFormat elif line.startswith('-') or line.startswith('<') or \ line.startswith('D '): format = self.cRemovedFormat elif line.startswith('@@'): format = self.cLineNoFormat else: format = self.cNormalFormat tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.setCurrentCharFormat(format) self.contents.insertPlainText(line) self.paras += 1 def __extractFileName(self, line): """ Private method to extract the file name out of a file separator line. @param line line to be processed (string) @return extracted file name (string) """ f = line.split(None, 1)[1] f = f.rsplit(None, 2)[0] return f def __processFileLine(self, line): """ Private slot to process a line giving the old/new file. @param line line to be processed (string) """ if line.startswith('---'): self.__oldFileLine = self.paras self.__oldFile = self.__extractFileName(line) else: self.__fileSeparators.append( (self.__oldFile, self.__extractFileName(line), self.__oldFileLine)) def __finish(self): """ Private slot called when the user pressed the button. """ QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() self.filesCombo.addItem(self.tr(""), 0) self.filesCombo.addItem(self.tr(""), -1) for oldFile, newFile, pos in sorted(self.__fileSeparators): if oldFile != newFile: self.filesCombo.addItem( "{0}\n{1}".format(oldFile, newFile), pos) else: self.filesCombo.addItem(oldFile, pos) self._cancel() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() elif button == self.buttonBox.button(QDialogButtonBox.Save): self.on_saveButton_clicked() @pyqtSlot(int) def on_filesCombo_activated(self, index): """ Private slot to handle the selection of a file. @param index activated row (integer) """ para = self.filesCombo.itemData(index) if para == 0: tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() elif para == -1: tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() else: # step 1: move cursor to end tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() # step 2: move cursor to desired line tc = self.contents.textCursor() delta = tc.blockNumber() - para tc.movePosition(QTextCursor.PreviousBlock, QTextCursor.MoveAnchor, delta) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() @pyqtSlot() def on_saveButton_clicked(self): """ Private slot to handle the Save button press. It saves the diff shown in the dialog to a file in the local filesystem. """ if isinstance(self.filename, list): if len(self.filename) > 1: fname = self.vcs.splitPathList(self.filename)[0] else: dname, fname = self.vcs.splitPath(self.filename[0]) if fname != '.': fname = "{0}.diff".format(self.filename[0]) else: fname = dname else: fname = self.vcs.splitPath(self.filename)[0] fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Diff"), fname, self.tr("Patch Files (*.diff)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fname: return # user aborted ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Diff"), self.tr("

The patch file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) eol = e5App().getObject("Project").getEolString() try: f = open(fname, "w", encoding="utf-8", newline="") f.write(eol.join(self.contents.toPlainText().splitlines())) f.close() except IOError as why: E5MessageBox.critical( self, self.tr('Save Diff'), self.tr( '

The patch file {0} could not be saved.' '
Reason: {1}

') .format(fname, str(why))) def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ self.errorGroup.show() self.errors.insertPlainText(msg) self.errors.ensureCursorVisible() eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnRepoBrowserDialog.py0000644000175000017500000002452112537064321024417 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the subversion repository browser dialog. """ from __future__ import unicode_literals import pysvn from PyQt5.QtCore import QMutexLocker, Qt, pyqtSlot from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QHeaderView, QDialog, QApplication, \ QDialogButtonBox, QTreeWidgetItem from E5Gui import E5MessageBox from .SvnUtilities import formatTime from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnRepoBrowserDialog import Ui_SvnRepoBrowserDialog import UI.PixmapCache class SvnRepoBrowserDialog(QDialog, SvnDialogMixin, Ui_SvnRepoBrowserDialog): """ Class implementing the subversion repository browser dialog. """ def __init__(self, vcs, mode="browse", parent=None): """ Constructor @param vcs reference to the vcs object @param mode mode of the dialog (string, "browse" or "select") @param parent parent widget (QWidget) """ super(SvnRepoBrowserDialog, self).__init__(parent) self.setupUi(self) SvnDialogMixin.__init__(self) self.setWindowFlags(Qt.Window) self.repoTree.headerItem().setText(self.repoTree.columnCount(), "") self.repoTree.header().setSortIndicator(0, Qt.AscendingOrder) self.vcs = vcs self.mode = mode if self.mode == "select": self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).hide() else: self.buttonBox.button(QDialogButtonBox.Ok).hide() self.buttonBox.button(QDialogButtonBox.Cancel).hide() self.__dirIcon = UI.PixmapCache.getIcon("dirClosed.png") self.__fileIcon = UI.PixmapCache.getIcon("fileMisc.png") self.__urlRole = Qt.UserRole self.__ignoreExpand = False self.client = self.vcs.getClient() self.client.callback_cancel = \ self._clientCancelCallback self.client.callback_get_login = \ self._clientLoginCallback self.client.callback_ssl_server_trust_prompt = \ self._clientSslServerTrustPromptCallback self.show() QApplication.processEvents() def __resort(self): """ Private method to resort the tree. """ self.repoTree.sortItems( self.repoTree.sortColumn(), self.repoTree.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the tree columns. """ self.repoTree.header().resizeSections(QHeaderView.ResizeToContents) self.repoTree.header().setStretchLastSection(True) def __generateItem(self, parent, repopath, revision, author, size, date, nodekind, url): """ Private method to generate a tree item in the repository tree. @param parent parent of the item to be created (QTreeWidget or QTreeWidgetItem) @param repopath path of the item (string) @param revision revision info (string or pysvn.opt_revision_kind) @param author author info (string) @param size size info (integer) @param date date info (integer) @param nodekind node kind info (pysvn.node_kind) @param url url of the entry (string) @return reference to the generated item (QTreeWidgetItem) """ if repopath == "/": path = url else: path = url.split("/")[-1] if revision == "": rev = "" else: rev = revision.number if date == "": dt = "" else: dt = formatTime(date) if author is None: author = "" itm = QTreeWidgetItem(parent) itm.setData(0, Qt.DisplayRole, path) itm.setData(1, Qt.DisplayRole, rev) itm.setData(2, Qt.DisplayRole, author) itm.setData(3, Qt.DisplayRole, size) itm.setData(4, Qt.DisplayRole, dt) if nodekind == pysvn.node_kind.dir: itm.setIcon(0, self.__dirIcon) itm.setChildIndicatorPolicy(QTreeWidgetItem.ShowIndicator) elif nodekind == pysvn.node_kind.file: itm.setIcon(0, self.__fileIcon) itm.setData(0, self.__urlRole, url) itm.setTextAlignment(0, Qt.AlignLeft) itm.setTextAlignment(1, Qt.AlignRight) itm.setTextAlignment(2, Qt.AlignLeft) itm.setTextAlignment(3, Qt.AlignRight) itm.setTextAlignment(4, Qt.AlignLeft) return itm def __listRepo(self, url, parent=None): """ Private method to perform the svn list command. @param url the repository URL to browser (string) @param parent reference to the item, the data should be appended to (QTreeWidget or QTreeWidgetItem) """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() if parent is None: parent = self.repoTree locker = QMutexLocker(self.vcs.vcsExecutionMutex) try: try: entries = self.client.list(url, recurse=False) firstTime = parent == self.repoTree # dirent elements are all unicode in Python 2 for dirent, lock in entries: if (firstTime and dirent["path"] != url) or \ (parent != self.repoTree and dirent["path"] == url): continue if firstTime: if dirent["repos_path"] != "/": repoUrl = dirent["path"].replace( dirent["repos_path"], "") else: repoUrl = dirent["path"] if repoUrl != url: self.__ignoreExpand = True itm = self.__generateItem( parent, "/", "", "", 0, "", pysvn.node_kind.dir, repoUrl) itm.setExpanded(True) parent = itm urlPart = repoUrl for element in \ dirent["repos_path"].split("/")[:-1]: if element: urlPart = "{0}/{1}".format(urlPart, element) itm = self.__generateItem( parent, element, "", "", 0, "", pysvn.node_kind.dir, urlPart) itm.setExpanded(True) parent = itm self.__ignoreExpand = False itm = self.__generateItem( parent, dirent["repos_path"], dirent["created_rev"], dirent["last_author"], dirent["size"], dirent["time"], dirent["kind"], dirent["path"]) self.__resort() self.__resizeColumns() except pysvn.ClientError as e: self.__showError(e.args[0]) except AttributeError: self.__showError( self.tr("The installed version of PySvn should be " "1.4.0 or better.")) finally: locker.unlock() QApplication.restoreOverrideCursor() def __normalizeUrl(self, url): """ Private method to normalite the url. @param url the url to normalize (string) @return normalized URL (string) """ if url.endswith("/"): return url[:-1] return url def start(self, url): """ Public slot to start the svn info command. @param url the repository URL to browser (string) """ self.url = "" self.urlCombo.addItem(self.__normalizeUrl(url)) @pyqtSlot(str) def on_urlCombo_currentIndexChanged(self, text): """ Private slot called, when a new repository URL is entered or selected. @param text the text of the current item (string) """ url = self.__normalizeUrl(text) if url != self.url: self.url = url self.repoTree.clear() self.__listRepo(url) @pyqtSlot(QTreeWidgetItem) def on_repoTree_itemExpanded(self, item): """ Private slot called when an item is expanded. @param item reference to the item to be expanded (QTreeWidgetItem) """ if not self.__ignoreExpand: url = item.data(0, self.__urlRole) self.__listRepo(url, item) @pyqtSlot(QTreeWidgetItem) def on_repoTree_itemCollapsed(self, item): """ Private slot called when an item is collapsed. @param item reference to the item to be collapsed (QTreeWidgetItem) """ for child in item.takeChildren(): del child @pyqtSlot() def on_repoTree_itemSelectionChanged(self): """ Private slot called when the selection changes. """ if self.mode == "select": self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True) def __showError(self, msg): """ Private slot to show an error message. @param msg error message to show (string) """ E5MessageBox.critical( self, self.tr("Subversion Error"), msg) def accept(self): """ Public slot called when the dialog is accepted. """ if self.focusWidget() == self.urlCombo: return super(SvnRepoBrowserDialog, self).accept() def getSelectedUrl(self): """ Public method to retrieve the selected repository URL. @return the selected repository URL (string) """ items = self.repoTree.selectedItems() if len(items) == 1: return items[0].data(0, self.__urlRole) else: return "" eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnPropSetDialog.ui0000644000175000017500000000660012060166053023521 0ustar piotrpiotr SvnPropSetDialog 0 0 494 385 Set Subversion Property true Enter text of the property true false Property &Name: propNameEdit Enter the name of the property to be set Select to apply the property recursively Apply &recursively Property &Value: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop propTextEdit Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource propNameEdit propTextEdit recurseCheckBox buttonBox accepted() SvnPropSetDialog accept() 28 362 28 386 buttonBox rejected() SvnPropSetDialog reject() 94 366 94 383 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnCommandDialog.py0000644000175000017500000000630312451233371023520 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the Subversion command dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_SvnCommandDialog import Ui_SvnCommandDialog import Utilities import UI.PixmapCache class SvnCommandDialog(QDialog, Ui_SvnCommandDialog): """ Class implementing the Subversion command dialog. It implements a dialog that is used to enter an arbitrary subversion command. It asks the user to enter the commandline parameters and the working directory. """ def __init__(self, argvList, wdList, ppath, parent=None): """ Constructor @param argvList history list of commandline arguments (list of strings) @param wdList history list of working directories (list of strings) @param ppath pathname of the project directory (string) @param parent parent widget of this dialog (QWidget) """ super(SvnCommandDialog, self).__init__(parent) self.setupUi(self) self.dirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.workdirCompleter = E5DirCompleter(self.workdirCombo) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) self.commandCombo.clear() self.commandCombo.addItems(argvList) if len(argvList) > 0: self.commandCombo.setCurrentIndex(0) self.workdirCombo.clear() self.workdirCombo.addItems(wdList) if len(wdList) > 0: self.workdirCombo.setCurrentIndex(0) self.projectDirLabel.setText(ppath) # modify some what's this help texts t = self.commandCombo.whatsThis() if t: t += Utilities.getPercentReplacementHelp() self.commandCombo.setWhatsThis(t) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_dirButton_clicked(self): """ Private method used to open a directory selection dialog. """ cwd = self.workdirCombo.currentText() if not cwd: cwd = self.projectDirLabel.text() d = E5FileDialog.getExistingDirectory( self, self.tr("Working directory"), cwd, E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if d: self.workdirCombo.setEditText(Utilities.toNativeSeparators(d)) def on_commandCombo_editTextChanged(self, text): """ Private method used to enable/disable the OK-button. @param text ignored """ self.okButton.setDisabled(self.commandCombo.currentText() == "") def getData(self): """ Public method to retrieve the data entered into this dialog. @return a tuple of argv, workdir """ return (self.commandCombo.currentText(), self.workdirCombo.currentText()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnSwitchDialog.ui0000644000175000017500000000747412354033654023406 0ustar piotrpiotr SvnSwitchDialog 0 0 391 146 Subversion Switch true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Tag Name: 0 0 Enter the name of the tag <b>Tag Name</b> <p>Enter the name of the tag to be switched to. In order to switch to the trunk version leave it empty.</p> true false Tag Type Select for a regular tag <b>Regular Tag</b> <p>Select this entry for a regular tag.</p> Regular Tag true Select for a branch tag <b>Branch Tag</b> <p>Select this entry for a branch tag.</p> Branch Tag qPixmapFromMimeSource tagCombo regularButton branchButton buttonBox accepted() SvnSwitchDialog accept() 21 122 21 136 buttonBox rejected() SvnSwitchDialog reject() 67 122 67 134 eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnLoginDialog.py0000644000175000017500000000315612451233371023215 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the login dialog for pysvn. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_SvnLoginDialog import Ui_SvnLoginDialog class SvnLoginDialog(QDialog, Ui_SvnLoginDialog): """ Class implementing the login dialog for pysvn. """ def __init__(self, realm, username, may_save, parent=None): """ Constructor @param realm name of the realm of the requested credentials (string) @param username username as supplied by subversion (string) @param may_save flag indicating, that subversion is willing to save the answers returned (boolean) @param parent reference to the parent widget (QWidget) """ super(SvnLoginDialog, self).__init__(parent) self.setupUi(self) self.realmLabel.setText( self.tr("Enter login data for realm {0}.") .format(realm)) self.usernameEdit.setText(username) self.saveCheckBox.setEnabled(may_save) if not may_save: self.saveCheckBox.setChecked(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public method to retrieve the login data. @return tuple of three values (username, password, save) """ return (self.usernameEdit.text(), self.passwordEdit.text(), self.saveCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.ui0000644000175000017500000000526312060166053023001 0ustar piotrpiotr SvnDiffDialog 0 0 749 646 Subversion Diff 0 4 Difference <b>Subversion Diff</b><p>This shows the output of the svn diff command.</p> QTextEdit::NoWrap true 8 false 0 1 Errors true false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Save filesCombo contents errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnNewProjectOptionsDialog.py0000644000175000017500000001456712451233371025611 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the Subversion Options Dialog for a new project from the repository. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QDir, pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_SvnNewProjectOptionsDialog import Ui_SvnNewProjectOptionsDialog from .Config import ConfigSvnProtocols import Utilities import Preferences import UI.PixmapCache class SvnNewProjectOptionsDialog(QDialog, Ui_SvnNewProjectOptionsDialog): """ Class implementing the Options Dialog for a new project from the repository. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the version control object @param parent parent widget (QWidget) """ super(SvnNewProjectOptionsDialog, self).__init__(parent) self.setupUi(self) self.vcsUrlButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.projectDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.vcsDirectoryCompleter = E5DirCompleter(self.vcsUrlEdit) self.vcsProjectDirCompleter = E5DirCompleter(self.vcsProjectDirEdit) self.protocolCombo.addItems(ConfigSvnProtocols) hd = Utilities.toNativeSeparators(QDir.homePath()) hd = os.path.join(hd, 'subversionroot') self.vcsUrlEdit.setText(hd) self.vcs = vcs self.localPath = hd self.networkPath = "localhost/" self.localProtocol = True ipath = Preferences.getMultiProject("Workspace") or \ Utilities.getHomeDir() self.__initPaths = [ Utilities.fromNativeSeparators(ipath), Utilities.fromNativeSeparators(ipath) + "/", ] self.vcsProjectDirEdit.setText( Utilities.toNativeSeparators(self.__initPaths[0])) self.resize(self.width(), self.minimumSizeHint().height()) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_vcsProjectDirEdit_textChanged(self, txt): """ Private slot to handle a change of the project directory. @param txt name of the project directory (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths) @pyqtSlot() def on_vcsUrlButton_clicked(self): """ Private slot to display a selection dialog. """ if self.protocolCombo.currentText() == "file://": directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Repository-Directory"), self.vcsUrlEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.vcsUrlEdit.setText( Utilities.toNativeSeparators(directory)) else: from .SvnRepoBrowserDialog import SvnRepoBrowserDialog dlg = SvnRepoBrowserDialog(self.vcs, mode="select", parent=self) dlg.start( self.protocolCombo.currentText() + self.vcsUrlEdit.text()) if dlg.exec_() == QDialog.Accepted: url = dlg.getSelectedUrl() if url: protocol = url.split("://")[0] path = url.split("://")[1] self.protocolCombo.setCurrentIndex( self.protocolCombo.findText(protocol + "://")) self.vcsUrlEdit.setText(path) @pyqtSlot() def on_projectDirButton_clicked(self): """ Private slot to display a directory selection dialog. """ directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Project Directory"), self.vcsProjectDirEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.vcsProjectDirEdit.setText( Utilities.toNativeSeparators(directory)) def on_layoutCheckBox_toggled(self, checked): """ Private slot to handle the change of the layout checkbox. @param checked flag indicating the state of the checkbox (boolean) """ self.vcsTagLabel.setEnabled(checked) self.vcsTagEdit.setEnabled(checked) if not checked: self.vcsTagEdit.clear() @pyqtSlot(str) def on_protocolCombo_activated(self, protocol): """ Private slot to switch the status of the directory selection button. @param protocol name of the selected protocol (string) """ if protocol == "file://": self.networkPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.localPath) self.vcsUrlLabel.setText(self.tr("Pat&h:")) self.localProtocol = True else: if self.localProtocol: self.localPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.networkPath) self.vcsUrlLabel.setText(self.tr("&URL:")) self.localProtocol = False @pyqtSlot(str) def on_vcsUrlEdit_textChanged(self, txt): """ Private slot to handle changes of the URL. @param txt current text of the line edit (string) """ enable = "://" not in txt self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) def getData(self): """ Public slot to retrieve the data entered into the dialog. @return a tuple of a string (project directory) and a dictionary containing the data entered. """ scheme = self.protocolCombo.currentText() url = self.vcsUrlEdit.text() vcsdatadict = { "url": '{0}{1}'.format(scheme, url), "tag": self.vcsTagEdit.text(), "standardLayout": self.layoutCheckBox.isChecked(), } return (self.vcsProjectDirEdit.text(), vcsdatadict) eric-6.0.8/eric/Plugins/VcsPlugins/vcsPySvn/SvnConst.py0000644000175000017500000001005512451233371022107 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing some constants for the pysvn package. """ from __future__ import unicode_literals from PyQt5.QtCore import QT_TRANSLATE_NOOP import pysvn svnNotifyActionMap = { pysvn.wc_notify_action.add: QT_TRANSLATE_NOOP('Subversion', 'Add'), pysvn.wc_notify_action.commit_added: QT_TRANSLATE_NOOP('Subversion', 'Add'), pysvn.wc_notify_action.commit_deleted: QT_TRANSLATE_NOOP('Subversion', 'Delete'), pysvn.wc_notify_action.commit_modified: QT_TRANSLATE_NOOP('Subversion', 'Modify'), pysvn.wc_notify_action.commit_postfix_txdelta: None, pysvn.wc_notify_action.commit_replaced: QT_TRANSLATE_NOOP('Subversion', 'Replace'), pysvn.wc_notify_action.copy: QT_TRANSLATE_NOOP('Subversion', 'Copy'), pysvn.wc_notify_action.delete: QT_TRANSLATE_NOOP('Subversion', 'Delete'), pysvn.wc_notify_action.failed_revert: QT_TRANSLATE_NOOP('Subversion', 'Failed revert'), pysvn.wc_notify_action.resolved: QT_TRANSLATE_NOOP('Subversion', 'Resolve'), pysvn.wc_notify_action.restore: QT_TRANSLATE_NOOP('Subversion', 'Restore'), pysvn.wc_notify_action.revert: QT_TRANSLATE_NOOP('Subversion', 'Revert'), pysvn.wc_notify_action.skip: QT_TRANSLATE_NOOP('Subversion', 'Skip'), pysvn.wc_notify_action.status_completed: None, pysvn.wc_notify_action.status_external: QT_TRANSLATE_NOOP('Subversion', 'External'), pysvn.wc_notify_action.update_add: QT_TRANSLATE_NOOP('Subversion', 'Add'), pysvn.wc_notify_action.update_completed: None, pysvn.wc_notify_action.update_delete: QT_TRANSLATE_NOOP('Subversion', 'Delete'), pysvn.wc_notify_action.update_external: QT_TRANSLATE_NOOP('Subversion', 'External'), pysvn.wc_notify_action.update_update: QT_TRANSLATE_NOOP('Subversion', 'Update'), pysvn.wc_notify_action.annotate_revision: QT_TRANSLATE_NOOP('Subversion', 'Annotate'), } if hasattr(pysvn.wc_notify_action, 'locked'): svnNotifyActionMap[pysvn.wc_notify_action.locked] = \ QT_TRANSLATE_NOOP('Subversion', 'Locking') svnNotifyActionMap[pysvn.wc_notify_action.unlocked] = \ QT_TRANSLATE_NOOP('Subversion', 'Unlocking') svnNotifyActionMap[pysvn.wc_notify_action.failed_lock] = \ QT_TRANSLATE_NOOP('Subversion', 'Failed lock') svnNotifyActionMap[pysvn.wc_notify_action.failed_unlock] = \ QT_TRANSLATE_NOOP('Subversion', 'Failed unlock') if hasattr(pysvn.wc_notify_action, 'changelist_clear'): svnNotifyActionMap[pysvn.wc_notify_action.changelist_clear] = \ QT_TRANSLATE_NOOP('Subversion', 'Changelist clear') svnNotifyActionMap[pysvn.wc_notify_action.changelist_set] = \ QT_TRANSLATE_NOOP('Subversion', 'Changelist set') svnNotifyActionMap[pysvn.wc_notify_action.changelist_moved] = \ QT_TRANSLATE_NOOP('Subversion', 'Changelist moved') svnStatusMap = { pysvn.wc_status_kind.added: QT_TRANSLATE_NOOP('Subversion', 'added'), pysvn.wc_status_kind.conflicted: QT_TRANSLATE_NOOP('Subversion', 'conflict'), pysvn.wc_status_kind.deleted: QT_TRANSLATE_NOOP('Subversion', 'deleted'), pysvn.wc_status_kind.external: QT_TRANSLATE_NOOP('Subversion', 'external'), pysvn.wc_status_kind.ignored: QT_TRANSLATE_NOOP('Subversion', 'ignored'), pysvn.wc_status_kind.incomplete: QT_TRANSLATE_NOOP('Subversion', 'incomplete'), pysvn.wc_status_kind.missing: QT_TRANSLATE_NOOP('Subversion', 'missing'), pysvn.wc_status_kind.merged: QT_TRANSLATE_NOOP('Subversion', 'merged'), pysvn.wc_status_kind.modified: QT_TRANSLATE_NOOP('Subversion', 'modified'), pysvn.wc_status_kind.none: QT_TRANSLATE_NOOP('Subversion', 'normal'), pysvn.wc_status_kind.normal: QT_TRANSLATE_NOOP('Subversion', 'normal'), pysvn.wc_status_kind.obstructed: QT_TRANSLATE_NOOP('Subversion', 'type error'), pysvn.wc_status_kind.replaced: QT_TRANSLATE_NOOP('Subversion', 'replaced'), pysvn.wc_status_kind.unversioned: QT_TRANSLATE_NOOP('Subversion', 'unversioned'), } eric-6.0.8/eric/Plugins/VcsPlugins/__init__.py0000644000175000017500000000025512451233371020277 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the various version control system plugins. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/0000755000175000017500000000000012557365404020635 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/PurgeExtension/0000755000175000017500000000000012557365404023614 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/PurgeExtension/HgPurgeListDialog.ui0000644000175000017500000000400312060166053027451 0ustar piotrpiotr HgPurgeListDialog 0 0 500 400 Purge List true QAbstractItemView::NoEditTriggers true QAbstractItemView::NoSelection Qt::ElideLeft Qt::Horizontal QDialogButtonBox::Close purgeList buttonBox buttonBox accepted() HgPurgeListDialog accept() 248 254 157 274 buttonBox rejected() HgPurgeListDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/PurgeExtension/ProjectHelper.py0000644000175000017500000001335612451233371026732 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the purge extension project helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui.E5Action import E5Action from ..HgExtensionProjectHelper import HgExtensionProjectHelper import UI.PixmapCache class PurgeProjectHelper(HgExtensionProjectHelper): """ Class implementing the purge extension project helper. """ def __init__(self): """ Constructor """ super(PurgeProjectHelper, self).__init__() def initActions(self): """ Public method to generate the action objects. """ self.hgPurgeAct = E5Action( self.tr('Purge Files'), UI.PixmapCache.getIcon("fileDelete.png"), self.tr('Purge Files'), 0, 0, self, 'mercurial_purge') self.hgPurgeAct.setStatusTip(self.tr( 'Delete files and directories not known to Mercurial' )) self.hgPurgeAct.setWhatsThis(self.tr( """Purge Files""" """

This deletes files and directories not known to Mercurial.""" """ That means that purge will delete:

    """ """
  • unknown files (marked with "not tracked" in the status""" """ dialog)
  • """ """
  • empty directories
  • """ """
Note that ignored files will be left untouched.

""" )) self.hgPurgeAct.triggered.connect(self.__hgPurge) self.actions.append(self.hgPurgeAct) self.hgPurgeAllAct = E5Action( self.tr('Purge All Files'), self.tr('Purge All Files'), 0, 0, self, 'mercurial_purge_all') self.hgPurgeAllAct.setStatusTip(self.tr( 'Delete files and directories not known to Mercurial including' ' ignored ones' )) self.hgPurgeAllAct.setWhatsThis(self.tr( """Purge All Files""" """

This deletes files and directories not known to Mercurial.""" """ That means that purge will delete:

    """ """
  • unknown files (marked with "not tracked" in the status""" """ dialog)
  • """ """
  • empty directories
  • """ """
  • ignored files and directories
  • """ """

""" )) self.hgPurgeAllAct.triggered.connect(self.__hgPurgeAll) self.actions.append(self.hgPurgeAllAct) self.hgPurgeListAct = E5Action( self.tr('List Files to be Purged'), UI.PixmapCache.getIcon("fileDeleteList.png"), self.tr('List Files to be Purged...'), 0, 0, self, 'mercurial_purge_list') self.hgPurgeListAct.setStatusTip(self.tr( 'List files and directories not known to Mercurial' )) self.hgPurgeListAct.setWhatsThis(self.tr( """List Files to be Purged""" """

This lists files and directories not known to Mercurial.""" """ These would be deleted by the "Purge Files" menu entry.

""" )) self.hgPurgeListAct.triggered.connect(self.__hgPurgeList) self.actions.append(self.hgPurgeListAct) self.hgPurgeAllListAct = E5Action( self.tr('List All Files to be Purged'), self.tr('List All Files to be Purged...'), 0, 0, self, 'mercurial_purge_all_list') self.hgPurgeAllListAct.setStatusTip(self.tr( 'List files and directories not known to Mercurial including' ' ignored ones' )) self.hgPurgeAllListAct.setWhatsThis(self.tr( """List All Files to be Purged""" """

This lists files and directories not known to Mercurial""" """ including ignored ones. These would be deleted by the""" """ "Purge All Files" menu entry.

""" )) self.hgPurgeAllListAct.triggered.connect(self.__hgPurgeAllList) self.actions.append(self.hgPurgeAllListAct) def initMenu(self, mainMenu): """ Public method to generate the extension menu. @param mainMenu reference to the main menu (QMenu) @return populated menu (QMenu) """ menu = QMenu(self.menuTitle(), mainMenu) menu.setIcon(UI.PixmapCache.getIcon("fileDelete.png")) menu.setTearOffEnabled(True) menu.addAction(self.hgPurgeAct) menu.addAction(self.hgPurgeAllAct) menu.addSeparator() menu.addAction(self.hgPurgeListAct) menu.addAction(self.hgPurgeAllListAct) return menu def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("Purge") def __hgPurge(self): """ Private slot used to remove files not tracked by Mercurial. """ self.vcs.getExtensionObject("purge")\ .hgPurge(self.project.getProjectPath(), all=False) def __hgPurgeAll(self): """ Private slot used to remove all files not tracked by Mercurial. """ self.vcs.getExtensionObject("purge")\ .hgPurge(self.project.getProjectPath(), all=True) def __hgPurgeList(self): """ Private slot used to list files not tracked by Mercurial. """ self.vcs.getExtensionObject("purge")\ .hgPurgeList(self.project.getProjectPath(), all=False) def __hgPurgeAllList(self): """ Private slot used to list all files not tracked by Mercurial. """ self.vcs.getExtensionObject("purge")\ .hgPurgeList(self.project.getProjectPath(), all=True) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/PurgeExtension/HgPurgeListDialog.py0000644000175000017500000000161012537064320027470 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to list all files not tracked by Mercurial. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QDialog from .Ui_HgPurgeListDialog import Ui_HgPurgeListDialog class HgPurgeListDialog(QDialog, Ui_HgPurgeListDialog): """ Class implementing a dialog to list all files not tracked by Mercurial. """ def __init__(self, entries, parent=None): """ Constructor @param entries list of entries to be shown (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgPurgeListDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.purgeList.addItems(sorted(entries)) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/PurgeExtension/__init__.py0000644000175000017500000000025012451233371025710 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Package implementing the purge extension support interface. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/PurgeExtension/purge.py0000644000175000017500000001066112451233371025302 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the purge extension interface. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QProcess from PyQt5.QtWidgets import QDialog from ..HgExtension import HgExtension from ..HgDialog import HgDialog class Purge(HgExtension): """ Class implementing the purge extension interface. """ def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(Purge, self).__init__(vcs) self.purgeListDialog = None def shutdown(self): """ Public method used to shutdown the purge interface. """ if self.purgeListDialog is not None: self.purgeListDialog.close() def __getEntries(self, repodir, all): """ Private method to get a list of files/directories being purged. @param repodir directory name of the repository (string) @param all flag indicating to delete all files including ignored ones (boolean) @return name of the current patch (string) """ purgeEntries = [] args = self.vcs.initCommand("purge") args.append("--print") if all: args.append("--all") client = self.vcs.getClient() if client: out, err = client.runcommand(args) if out: purgeEntries = out.strip().split() else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: purgeEntries = str( process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace').strip().split() return purgeEntries def hgPurge(self, name, all=False): """ Public method to purge files and directories not tracked by Mercurial. @param name file/directory name (string) @param all flag indicating to delete all files including ignored ones (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if all: title = self.tr("Purge All Files") message = self.tr( """Do really want to delete all files not tracked by""" """ Mercurial (including ignored ones)?""") else: title = self.tr("Purge Files") message = self.tr( """Do really want to delete files not tracked by Mercurial?""") entries = self.__getEntries(repodir, all) from UI.DeleteFilesConfirmationDialog import \ DeleteFilesConfirmationDialog dlg = DeleteFilesConfirmationDialog(None, title, message, entries) if dlg.exec_() == QDialog.Accepted: args = self.vcs.initCommand("purge") if all: args.append("--all") args.append("-v") dia = HgDialog(title, self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgPurgeList(self, name, all=False): """ Public method to list files and directories not tracked by Mercurial. @param name file/directory name (string) @param all flag indicating to list all files including ignored ones (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return entries = self.__getEntries(repodir, all) from .HgPurgeListDialog import HgPurgeListDialog self.purgeListDialog = HgPurgeListDialog(entries) self.purgeListDialog.show() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.py0000644000175000017500000001156212451233371026245 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to select a revision. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgRevisionSelectionDialog import Ui_HgRevisionSelectionDialog class HgRevisionSelectionDialog(QDialog, Ui_HgRevisionSelectionDialog): """ Class implementing a dialog to select a revision. """ def __init__(self, tagsList, branchesList, bookmarksList=None, noneLabel="", parent=None): """ Constructor @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param noneLabel labeltext for "no revision selected" (string) @param parent parent widget (QWidget) """ super(HgRevisionSelectionDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.tagCombo.addItems(sorted(tagsList)) self.branchCombo.addItems(["default"] + sorted(branchesList)) if bookmarksList is not None: self.bookmarkCombo.addItems(sorted(bookmarksList)) else: self.bookmarkButton.setHidden(True) self.bookmarkCombo.setHidden(True) if noneLabel: self.noneButton.setText(noneLabel) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.idButton.isChecked(): enabled = self.idEdit.text() != "" elif self.tagButton.isChecked(): enabled = self.tagCombo.currentText() != "" elif self.branchButton.isChecked(): enabled = self.branchCombo.currentText() != "" elif self.bookmarkButton.isChecked(): enabled = self.bookmarkCombo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(bool) def on_idButton_toggled(self, checked): """ Private slot to handle changes of the ID select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tagButton_toggled(self, checked): """ Private slot to handle changes of the Tag select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branchButton_toggled(self, checked): """ Private slot to handle changes of the Branch select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmarkButton_toggled(self, checked): """ Private slot to handle changes of the Bookmark select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(str) def on_idEdit_textChanged(self, txt): """ Private slot to handle changes of the ID edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_tagCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branchCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmarkCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark combo. @param txt text of the combo (string) """ self.__updateOK() def getRevision(self): """ Public method to retrieve the selected revision. @return selected revision (string) """ if self.numberButton.isChecked(): rev = "rev({0})".format(self.numberSpinBox.value()) elif self.idButton.isChecked(): rev = "id({0})".format(self.idEdit.text()) elif self.tagButton.isChecked(): rev = self.tagCombo.currentText() elif self.branchButton.isChecked(): rev = self.branchCombo.currentText() elif self.bookmarkButton.isChecked(): rev = self.bookmarkCombo.currentText() elif self.tipButton.isChecked(): rev = "tip" else: rev = "" return rev eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgTagDialog.py0000644000175000017500000000657512451233371023324 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a tagging operation. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgTagDialog import Ui_HgTagDialog import UI.PixmapCache class HgTagDialog(QDialog, Ui_HgTagDialog): """ Class implementing a dialog to enter the data for a tagging operation. """ CreateGlobalTag = 1 CreateLocalTag = 2 DeleteGlobalTag = 3 DeleteLocalTag = 4 def __init__(self, taglist, revision=None, tagName=None, parent=None): """ Constructor @param taglist list of previously entered tags (list of strings) @param revision revision to set tag for (string) @param tagName name of the tag (string) @param parent parent widget (QWidget) """ super(HgTagDialog, self).__init__(parent) self.setupUi(self) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) self.tagCombo.clear() self.tagCombo.addItem("", False) for tag, isLocal in sorted(taglist): if isLocal: icon = UI.PixmapCache.getIcon("vcsTagLocal.png") else: icon = UI.PixmapCache.getIcon("vcsTagGlobal.png") self.tagCombo.addItem(icon, tag, isLocal) if revision: self.revisionEdit.setText(revision) if tagName: index = self.tagCombo.findText(tagName) if index > -1: self.tagCombo.setCurrentIndex(index) # suggest the most relevant tag action self.deleteTagButton.setChecked(True) else: self.tagCombo.setEditText(tagName) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_tagCombo_editTextChanged(self, text): """ Private method used to enable/disable the OK-button. @param text tag name entered in the combo (string) """ self.okButton.setDisabled(text == "") @pyqtSlot(int) def on_tagCombo_currentIndexChanged(self, index): """ Private slot setting the local status of the selected entry. @param index index of the selected entrie (integer) """ isLocal = self.tagCombo.itemData(index) if isLocal: self.localTagButton.setChecked(True) else: self.globalTagButton.setChecked(True) def getParameters(self): """ Public method to retrieve the tag data. @return tuple of two strings and int (tag, revision, tag operation) """ tag = self.tagCombo.currentText().replace(" ", "_") tagOp = 0 if self.createTagButton.isChecked(): if self.globalTagButton.isChecked(): tagOp = HgTagDialog.CreateGlobalTag else: tagOp = HgTagDialog.CreateLocalTag else: if self.globalTagButton.isChecked(): tagOp = HgTagDialog.DeleteGlobalTag else: tagOp = HgTagDialog.DeleteLocalTag return (tag, self.revisionEdit.text(), tagOp) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgCopyDialog.ui0000644000175000017500000000732312263302730023475 0ustar piotrpiotr HgCopyDialog 0 0 409 138 Mercurial Copy true Source: Shows the name of the source <b>Source name</b> <p>This field shows the name of the source.</p> true Enter the target name <b>Target name</b> <p>Enter the new name in this field. The target must be the new name or an absolute path.</p> Target: Press to open a selection dialog <b>Target directory</b> <p>Select the target name for the operation via a selection dialog.</p> Select to force the operation Enforce operation Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource targetEdit dirButton forceCheckBox buttonBox sourceEdit buttonBox accepted() HgCopyDialog accept() 32 79 32 97 buttonBox rejected() HgCopyDialog reject() 101 80 101 97 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgClientPromptDialog.ui0000644000175000017500000000512212060166053025177 0ustar piotrpiotr HgClientPromptDialog 0 0 400 400 Mercurial Client Input true Message: Shows the message sent by the Mercurial server true true Input: Enter the response to be sent to the Mercurial server Qt::Horizontal QDialogButtonBox::Ok inputEdit buttonBox messageEdit buttonBox accepted() HgClientPromptDialog accept() 248 254 157 274 buttonBox rejected() HgClientPromptDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/FetchExtension/0000755000175000017500000000000012557365404023563 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/FetchExtension/HgFetchDialog.py0000644000175000017500000000407612451233371026562 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter data to be used for a fetch operation. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from .Ui_HgFetchDialog import Ui_HgFetchDialog import Preferences class HgFetchDialog(QDialog, Ui_HgFetchDialog): """ Class implementing a dialog to enter data to be used for a fetch operation. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(HgFetchDialog, self).__init__(parent) self.setupUi(self) self.recentCommitMessages = Preferences.toList( Preferences.Prefs.settings.value('Mercurial/Commits')) self.recentComboBox.clear() self.recentComboBox.addItem("") self.recentComboBox.addItems(self.recentCommitMessages) @pyqtSlot(str) def on_recentComboBox_activated(self, txt): """ Private slot to select a commit message from recent ones. @param txt text of the selected entry (string) """ if txt: self.messageEdit.setPlainText(txt) def getData(self): """ Public method to get the data for the fetch operation. @return tuple with the commit message and a flag indicating to switch the merge order (string, boolean) """ msg = self.messageEdit.toPlainText() if msg: if msg in self.recentCommitMessages: self.recentCommitMessages.remove(msg) self.recentCommitMessages.insert(0, msg) no = int(Preferences.Prefs.settings.value( 'Mercurial/CommitMessages', 20)) del self.recentCommitMessages[no:] Preferences.Prefs.settings.setValue( 'Mercurial/Commits', self.recentCommitMessages) return msg, self.switchCheckBox.isChecked() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/FetchExtension/HgFetchDialog.ui0000644000175000017500000000557212060166053026547 0ustar piotrpiotr HgFetchDialog 0 0 400 300 Fetch Changes true Commit Message Enter commit message or leave empty to use the default message true Recent commit messages Select a recent commit message to use Select to switch the merge order Switch Parents when Merging Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok messageEdit recentComboBox switchCheckBox buttonBox buttonBox accepted() HgFetchDialog accept() 248 254 157 274 buttonBox rejected() HgFetchDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/FetchExtension/ProjectHelper.py0000644000175000017500000000576212451233371026703 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the fetch extension project helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox from ..HgExtensionProjectHelper import HgExtensionProjectHelper import UI.PixmapCache class FetchProjectHelper(HgExtensionProjectHelper): """ Class implementing the fetch extension project helper. """ def __init__(self): """ Constructor """ super(FetchProjectHelper, self).__init__() def initActions(self): """ Public method to generate the action objects. """ self.hgFetchAct = E5Action( self.tr('Fetch changes'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Fetch changes'), 0, 0, self, 'mercurial_fetch') self.hgFetchAct.setStatusTip(self.tr( 'Fetch changes from a remote repository' )) self.hgFetchAct.setWhatsThis(self.tr( """Fetch changes""" """

This pulls changes from a remote repository into the """ """local repository. If the pulled changes add a new branch""" """ head, the head is automatically merged, and the result of""" """ the merge is committed. Otherwise, the working directory""" """ is updated to include the new changes.

""" )) self.hgFetchAct.triggered.connect(self.__hgFetch) self.actions.append(self.hgFetchAct) def initMenu(self, mainMenu): """ Public method to generate the extension menu. @param mainMenu reference to the main menu (QMenu) @return populated menu (QMenu) """ menu = QMenu(self.menuTitle(), mainMenu) menu.setIcon(UI.PixmapCache.getIcon("vcsUpdate.png")) menu.setTearOffEnabled(True) menu.addAction(self.hgFetchAct) menu.aboutToShow.connect(self.__aboutToShowMenu) return menu def __aboutToShowMenu(self): """ Private slot to handle the aboutToShow signal of the background menu. """ self.hgFetchAct.setEnabled(self.vcs.canPull()) def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("Fetch") def __hgFetch(self): """ Private slot used to fetch changes from a remote repository. """ shouldReopen = self.vcs.getExtensionObject("fetch")\ .hgFetch(self.project.getProjectPath()) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Fetch"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/FetchExtension/__init__.py0000644000175000017500000000025012451233371025657 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Package implementing the fetch extension support interface. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/FetchExtension/fetch.py0000644000175000017500000000365312451233371025223 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the fetch extension interface. """ from __future__ import unicode_literals import os from PyQt5.QtWidgets import QDialog from ..HgExtension import HgExtension from ..HgDialog import HgDialog class Fetch(HgExtension): """ Class implementing the fetch extension interface. """ def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(Fetch, self).__init__(vcs) def hgFetch(self, name): """ Public method to fetch changes from a remote repository. @param name file/directory name (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False from .HgFetchDialog import HgFetchDialog res = False dlg = HgFetchDialog() if dlg.exec_() == QDialog.Accepted: message, switchParent = dlg.getData() args = self.vcs.initCommand("fetch") if message != "": args.append("--message") args.append(message) if switchParent: args.append("--switch-parent") args.append("-v") dia = HgDialog( self.tr('Fetching from a remote Mercurial repository'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.ui0000644000175000017500000001141712060166053023433 0ustar piotrpiotr HgDiffDialog 0 0 749 646 Mercurial Diff 0 3 Difference <b>Mercurial Diff</b><p>This shows the output of the hg diff command.</p> QTextEdit::NoWrap true 8 false 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Close|QDialogButtonBox::Save filesCombo contents errors input passwordCheckBox sendButton buttonBox buttonBox rejected() HgDiffDialog close() 197 624 201 645 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBookmarkDialog.ui0000644000175000017500000002300012334163407024323 0ustar piotrpiotr HgBookmarkDialog 0 0 400 255 true Name: Enter the bookmark name 0 0 Select a bookmark Revision Select to specify a revision by number Number false Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 158 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false 0 0 Enter a tag name true Select to specify a revision by a branch Branch: false 0 0 Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select tip revision of repository Parent true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok nameEdit nameCombo numberButton numberSpinBox idButton idEdit tagButton tagCombo branchButton branchCombo bookmarkButton bookmarkCombo tipButton buttonBox buttonBox accepted() HgBookmarkDialog accept() 248 274 157 274 buttonBox rejected() HgBookmarkDialog reject() 316 260 286 274 numberButton toggled(bool) numberSpinBox setEnabled(bool) 48 89 118 87 idButton toggled(bool) idEdit setEnabled(bool) 36 109 105 116 tagButton toggled(bool) tagCombo setEnabled(bool) 43 142 102 141 branchButton toggled(bool) branchCombo setEnabled(bool) 42 170 115 171 bookmarkButton toggled(bool) bookmarkCombo setEnabled(bool) 51 196 108 201 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ProjectBrowserHelper.py0000644000175000017500000010155512451233371025316 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the VCS project browser helper for Mercurial. """ from __future__ import unicode_literals import os from PyQt5.QtWidgets import QMenu, QDialog from E5Gui.E5Application import e5App from Project.ProjectBrowserModel import ProjectBrowserFileItem from VCS.ProjectBrowserHelper import VcsProjectBrowserHelper import UI.PixmapCache class HgProjectBrowserHelper(VcsProjectBrowserHelper): """ Class implementing the VCS project browser helper for Mercurial. """ def __init__(self, vcsObject, browserObject, projectObject, isTranslationsBrowser, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param browserObject reference to the project browser object @param projectObject reference to the project object @param isTranslationsBrowser flag indicating, the helper is requested for the translations browser (this needs some special treatment) @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectBrowserHelper.__init__(self, vcsObject, browserObject, projectObject, isTranslationsBrowser, parent, name) # instantiate the extensions from .ShelveExtension.ProjectBrowserHelper import \ ShelveProjectBrowserHelper from .LargefilesExtension.ProjectBrowserHelper import \ LargefilesProjectBrowserHelper self.__extensions = { "shelve": ShelveProjectBrowserHelper( vcsObject, browserObject, projectObject), "largefiles": LargefilesProjectBrowserHelper( vcsObject, browserObject, projectObject), } self.__extensionMenuTitles = {} for extension in self.__extensions: self.__extensionMenuTitles[ self.__extensions[extension].menuTitle()] = extension self.__extensionMenus = {} for extension in self.__extensions: self.__extensionMenus[extension] = \ self.__extensions[extension].initMenus() def __showExtensionMenu(self, key, controlled): """ Private slot showing the extensions menu. @param key menu key (string, one of 'mainMenu', 'multiMenu', 'backMenu', 'dirMenu' or 'dirMultiMenu') @param controlled flag indicating to show the menu for a version controlled entry or a non-version controlled entry (boolean) """ for extensionName in self.__extensionMenus: if key in self.__extensionMenus[extensionName]: self.__extensionMenus[extensionName][key].setEnabled( self.vcs.isExtensionActive(extensionName)) if self.__extensionMenus[extensionName][key].isEnabled(): # adjust individual extension menu entries self.__extensions[extensionName].showExtensionMenu( key, controlled) if (not self.__extensionMenus[extensionName][key].isEnabled() and self.__extensionMenus[extensionName][key] .isTearOffMenuVisible()): self.__extensionMenus[extensionName][key].hideTearOffMenu() def showContextMenu(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the file status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ if self.browser.currentItem().data(1) == self.vcs.vcsName(): controlled = True for act in self.vcsMenuActions: act.setEnabled(True) for act in self.vcsAddMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) if not hasattr(self.browser.currentItem(), 'fileName'): self.annotateAct.setEnabled(False) else: controlled = False for act in self.vcsMenuActions: act.setEnabled(False) for act in self.vcsAddMenuActions: act.setEnabled(True) for act in standardItems: act.setEnabled(True) self.__showExtensionMenu("mainMenu", controlled) def showContextMenuMulti(self, menu, standardItems): """ Public slot called before the context menu (multiple selections) is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the files status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ vcsName = self.vcs.vcsName() items = self.browser.getSelectedItems() vcsItems = 0 # determine number of selected items under VCS control for itm in items: if itm.data(1) == vcsName: vcsItems += 1 if vcsItems > 0: controlled = True if vcsItems != len(items): for act in self.vcsMultiMenuActions: act.setEnabled(False) else: for act in self.vcsMultiMenuActions: act.setEnabled(True) for act in self.vcsAddMultiMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: controlled = False for act in self.vcsMultiMenuActions: act.setEnabled(False) for act in self.vcsAddMultiMenuActions: act.setEnabled(True) for act in standardItems: act.setEnabled(True) self.__showExtensionMenu("multiMenu", controlled) def showContextMenuDir(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the directory status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ if self.browser.currentItem().data(1) == self.vcs.vcsName(): controlled = True for act in self.vcsDirMenuActions: act.setEnabled(True) for act in self.vcsAddDirMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: controlled = False for act in self.vcsDirMenuActions: act.setEnabled(False) for act in self.vcsAddDirMenuActions: act.setEnabled(True) for act in standardItems: act.setEnabled(True) self.__showExtensionMenu("dirMenu", controlled) def showContextMenuDirMulti(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the directory status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status """ vcsName = self.vcs.vcsName() items = self.browser.getSelectedItems() vcsItems = 0 # determine number of selected items under VCS control for itm in items: if itm.data(1) == vcsName: vcsItems += 1 if vcsItems > 0: controlled = True if vcsItems != len(items): for act in self.vcsDirMultiMenuActions: act.setEnabled(False) else: for act in self.vcsDirMultiMenuActions: act.setEnabled(True) for act in self.vcsAddDirMultiMenuActions: act.setEnabled(False) for act in standardItems: act.setEnabled(False) else: controlled = False for act in self.vcsDirMultiMenuActions: act.setEnabled(False) for act in self.vcsAddDirMultiMenuActions: act.setEnabled(True) for act in standardItems: act.setEnabled(True) self.__showExtensionMenu("dirMultiMenu", controlled) ########################################################################### ## Private menu generation methods below ########################################################################### def __addExtensionsMenu(self, menu, key): """ Private method to add an extension menu entry. @param menu menu to add it to (QMenu) @param key menu key (string, one of 'mainMenu', 'multiMenu', 'backMenu', 'dirMenu' or 'dirMultiMenu') @return reference to the menu action (QAction) """ act = None if key in ['mainMenu', 'multiMenu', 'backMenu', 'dirMenu', 'dirMultiMenu']: extensionsMenu = QMenu(self.tr("Extensions"), menu) extensionsMenu.setTearOffEnabled(True) for extensionMenuTitle in sorted(self.__extensionMenuTitles): extensionName = self.__extensionMenuTitles[extensionMenuTitle] if key in self.__extensionMenus[extensionName]: extensionsMenu.addMenu( self.__extensionMenus[extensionName][key]) if not extensionsMenu.isEmpty(): if not menu.isEmpty(): menu.addSeparator() act = menu.addMenu(extensionsMenu) return act ########################################################################### ## Protected menu generation methods below ########################################################################### def _addVCSMenu(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ self.vcsMenuActions = [] self.vcsAddMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsMercurial", "icons", "mercurial.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsMenuActions.append(act) self.__addExtensionsMenu(menu, 'mainMenu') menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository only'), self.__HgForget) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Copy'), self.__HgCopy) self.vcsMenuActions.append(act) act = menu.addAction(self.tr('Move'), self.__HgMove) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log'), self._VCSLog) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), self._VCSLogBrowser) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsSbsDiff.png"), self.tr('Show differences side-by-side'), self.__HgSbsDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__HgExtendedDiff) self.vcsMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsSbsDiff.png"), self.tr('Show differences side-by-side (extended)'), self.__HgSbsExtendedDiff) self.vcsMenuActions.append(act) self.annotateAct = menu.addAction( self.tr('Show annotated file'), self.__HgAnnotate) self.vcsMenuActions.append(self.annotateAct) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self.__HgRevert) self.vcsMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__HgResolved) self.vcsMenuActions.append(act) act = menu.addAction( self.tr('Conflicts unresolved'), self.__HgUnresolved) self.vcsMenuActions.append(act) act = menu.addAction( self.tr('Re-Merge'), self.__HgReMerge) self.vcsMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__HgConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menu = menu def _addVCSMenuMulti(self, mainMenu): """ Protected method used to add the VCS menu for multi selection to all project browsers. @param mainMenu reference to the menu to be amended """ self.vcsMultiMenuActions = [] self.vcsAddMultiMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsMercurial", "icons", "mercurial.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsMultiMenuActions.append(act) self.__addExtensionsMenu(menu, 'multiMenu') menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository only'), self.__HgForget) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__HgExtendedDiff) self.vcsMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self.__HgRevert) self.vcsMultiMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__HgResolved) self.vcsMultiMenuActions.append(act) act = menu.addAction( self.tr('Conflicts unresolved'), self.__HgUnresolved) self.vcsMultiMenuActions.append(act) act = menu.addAction( self.tr('Re-Merge'), self.__HgReMerge) self.vcsMultiMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__HgConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuMulti = menu def _addVCSMenuBack(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsMercurial", "icons", "mercurial.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__HgConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuBack = menu def _addVCSMenuDir(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ if mainMenu is None: return self.vcsDirMenuActions = [] self.vcsAddDirMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsMercurial", "icons", "mercurial.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsDirMenuActions.append(act) self.__addExtensionsMenu(menu, 'dirMenu') menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction(self.tr('Copy'), self.__HgCopy) self.vcsDirMenuActions.append(act) act = menu.addAction(self.tr('Move'), self.__HgMove) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log'), self._VCSLog) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), self._VCSLogBrowser) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsDirMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__HgExtendedDiff) self.vcsDirMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self.__HgRevert) self.vcsDirMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__HgResolved) self.vcsDirMenuActions.append(act) act = menu.addAction( self.tr('Conflicts unresolved'), self.__HgUnresolved) self.vcsDirMenuActions.append(act) act = menu.addAction( self.tr('Re-Merge'), self.__HgReMerge) self.vcsDirMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__HgConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuDir = menu def _addVCSMenuDirMulti(self, mainMenu): """ Protected method used to add the VCS menu to all project browsers. @param mainMenu reference to the menu to be amended """ if mainMenu is None: return self.vcsDirMultiMenuActions = [] self.vcsAddDirMultiMenuActions = [] menu = QMenu(self.tr("Version Control")) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsMercurial", "icons", "mercurial.png")), self.vcs.vcsName(), self._VCSInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Commit changes to repository...'), self._VCSCommit) self.vcsDirMultiMenuActions.append(act) self.__addExtensionsMenu(menu, 'dirMultiMenu') menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add to repository'), self._VCSAdd) self.vcsAddDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove from repository (and disk)'), self._VCSRemove) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show status'), self._VCSStatus) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences'), self._VCSDiff) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), self.__HgExtendedDiff) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() act = menu.addAction( UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Revert changes'), self.__HgRevert) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( self.tr('Conflicts resolved'), self.__HgResolved) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( self.tr('Conflicts unresolved'), self.__HgUnresolved) self.vcsDirMultiMenuActions.append(act) act = menu.addAction( self.tr('Re-Merge'), self.__HgReMerge) self.vcsDirMultiMenuActions.append(act) menu.addSeparator() menu.addAction(self.tr('Select all local file entries'), self.browser.selectLocalEntries) menu.addAction(self.tr('Select all versioned file entries'), self.browser.selectVCSEntries) menu.addAction(self.tr('Select all local directory entries'), self.browser.selectLocalDirEntries) menu.addAction(self.tr('Select all versioned directory entries'), self.browser.selectVCSDirEntries) menu.addSeparator() menu.addAction(self.tr("Configure..."), self.__HgConfigure) mainMenu.addSeparator() mainMenu.addMenu(menu) self.menuDirMulti = menu ########################################################################### ## Menu handling methods below ########################################################################### def __HgRevert(self): """ Private slot called by the context menu to revert changes made. """ names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) self.vcs.hgRevert(names) def __HgCopy(self): """ Private slot called by the context menu to copy the selected file. """ itm = self.browser.currentItem() try: fn = itm.fileName() except AttributeError: fn = itm.dirName() self.vcs.hgCopy(fn, self.project) def __HgMove(self): """ Private slot called by the context menu to move the selected file. """ itm = self.browser.currentItem() try: fn = itm.fileName() except AttributeError: fn = itm.dirName() isFile = os.path.isfile(fn) movefiles = self.browser.project.getFiles(fn) if self.vcs.vcsMove(fn, self.project): if isFile: self.browser.closeSourceWindow.emit(fn) else: for mf in movefiles: self.browser.closeSourceWindow.emit(mf) def __HgExtendedDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository. This gives the chance to enter the revisions to compare. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.hgExtendedDiff(names) def __HgSbsDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository side-by-side. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.hgSbsDiff(fn) def __HgSbsExtendedDiff(self): """ Private slot called by the context menu to show the difference of a file to the repository side-by-side. It allows the selection of revisions to compare. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.hgSbsDiff(fn, extended=True) def __HgAnnotate(self): """ Private slot called by the context menu to show the annotations of a file. """ itm = self.browser.currentItem() fn = itm.fileName() self.vcs.hgAnnotate(fn) def __HgResolved(self): """ Private slot called by the context menu to mark conflicts of a file as being resolved. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.hgResolved(names) def __HgUnresolved(self): """ Private slot called by the context menu to mark conflicts of a file as being unresolved. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.hgResolved(names, unresolve=True) def __HgReMerge(self): """ Private slot called by the context menu to re-merge a file. """ names = [] for itm in self.browser.getSelectedItems(): try: names.append(itm.fileName()) except AttributeError: names.append(itm.dirName()) self.vcs.hgReMerge(names) def __HgForget(self): """ Private slot called by the context menu to remove the selected file from the Mercurial repository leaving a copy in the project directory. """ from UI.DeleteFilesConfirmationDialog import \ DeleteFilesConfirmationDialog if self.isTranslationsBrowser: items = self.browser.getSelectedItems([ProjectBrowserFileItem]) names = [itm.fileName() for itm in items] dlg = DeleteFilesConfirmationDialog( self.parent(), self.tr("Remove from repository only"), self.tr( "Do you really want to remove these files" " from the repository?"), names) else: items = self.browser.getSelectedItems() names = [itm.fileName() for itm in items] files = [self.browser.project.getRelativePath(name) for name in names] dlg = DeleteFilesConfirmationDialog( self.parent(), self.tr("Remove from repository only"), self.tr( "Do you really want to remove these files" " from the repository?"), files) if dlg.exec_() == QDialog.Accepted: self.vcs.hgForget(names) for fn in names: self._updateVCSStatus(fn) def __HgConfigure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("zzz_mercurialPage") eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/icons/0000755000175000017500000000000012060166053021734 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/icons/stopServer.png0000644000175000017500000000134012060166053024614 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<_IDATÁ1h\eàïïÝ]®wœw¦Ák‡TÉT$!898¸DAM×Á­ƒT‡‚ƒSÀ΢¡¦Ì*â"tJÕ¢P4CŃäz^.ïÞûý¾p«U.[ ‹°÷ì&÷oœ"€›+nOº¹‰ 2™Š¬çÚÍ€ÁGr³\¢eÚeÑߎ¢!ÙJ®Ò‡q£ŒgO½àÕe(œ9õ½C-µ£0«O“ÍóÙ±×\ÕV‘ ‚R¡eÕCß)g«›6ч+Å·}¯[ÒR•É$ ;3ô³{:Ò7>Û ´â£§Ý+ÞÕQ•K‘ ˆH¸ã7Í^˜ËòåI—WµÕä¶ ŒL”Rk)½éSgÝl9›,ÍxNE¦414pâ?9R‰Šš†K³”•‹çfŒ‰±‘§N 傪(¨¨ºâPe1)r—Õ=öĉ<Ñ7%R©—äÊ…¬T"ˆþtìØ±=kZ"‚ (•’r?øK‘H¤*ê¦ÕU¤ˆå~Rî%zÆ jêšÚ.jkª J…¡D¹—•»‰ž¶ …Ä”BjJCåFþ(wÃ;­øhÔ½ê}m $¢‚à…¡/ü¨Þ séÃñ7ÉÚ‘Kf¤š.hjh¨›21ò‹/Õ…÷îü"V¿š¬§6Ìk¨©HA!7ö«Ï˶¶7kø`2;ò²5MU© *ŒÜõƒºì(ÌÝ'D°Ú‰›åúXÝó^4'øÝCC5ÉV¸¾Ý‡¼µâvÑ- ¤R©´çÚ½€ðv+.[²hûöì†ûwOøRBôÝô3pIEND®B`‚eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/icons/startServer.png0000644000175000017500000000134012060166053024764 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<_IDATÁ¿k\uðÏ÷½w9+gÎ6mš!ÕŠ8 $ ¤‚Ô! KT4Ä? Cq°S)Eq˜ÁQCD0ƒƒ¥tÌbH,:™"êi-g~™¼¼{ßçç*ÜjÅ ãaÌ(6ªukÉêü>¡psÊbo°ÐÓC&S“u\»¹*ðq;.ÄÙ#´œ5¤ò§§öÑ”,%×?éB¨0ß®6óá}—½æœ† ¥ûØÑRß #·ºdÐ[8ÎMzE¿šLD¥–i܇ûÌ*M•ßu½e\KŸ=$ T8qä'ËÚÒ·?_I÷Zñ‡Ã3—Mê÷Œº‡»¤.dR‰¶¿tÔ^¿ÿURLœ ò†~u}RlùÌ&©š†¦wp2XL$½ñÜs.¨É¤¹øÂ‚¤jêš.ÊõÆ“8vj@®”ÈÚÓõÀ‡~DPÓç’Sq,‰£…!uO<ñ¯§þ±ëS‹Ž¤R/)ÄÑ,Šà7[þvâ¼óúDQ”Å0ô»JHeê™sæ]AOe[7’¸žèÈ•J5Mmg½ëŽ+ˆJ¥‰¸žÅµDÇ~… ÏpÃU@¥pì±D\KâªÎ¾w,W(5½é¶«€R!·ìN\Måßn'3».H¼`RDQáØÏ¾Ö>¸½*LÓ›MÍÑTW“‚R!÷‹/Ê–îÎ*Ì´«ÍÞð±WÍ8£O*¨”ŽÝóPC¶Fît ˜nW q6×ð¼½,øÕ¶Gê’¥pýnBà½)‹å`©T"•J¥×–WB€÷[Õ„qcF±aÝZX½·Àÿhó³ÍØLHIEND®B`‚eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/icons/mercurial.png0000644000175000017500000000231212060166053024423 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ •>Ö•tEXtCommentCreated with GIMPW%IDAT8Ë•ALYÇo˜i­@ĈºY°XSÂ&M„DŒÆhÂÆ"œ8 ‰gô¤ðÂÆÈ.\ !n"¢`[Ýn<èɈTB RBÚqvJ§o›"ˆû%“—™÷¾ÿû}ß{ß7BJ)ù%“I677ÙÚÚÂ4M4M£  €£G’››KVBaû¨ êºÎ»wïXXX ‘Hð5ƒ‚¼¼Mmm-‡FJi‹‹ïÇãqB¡Ÿ?&''ÇvøšNJI:¦´´¯×Kyy¹-¾GXJ‰@0=3Íììì®ð¾g™L)%>Ÿêêj”o !ý"‘HØ™M(ƒƒƒÄãq¤”{…b±–eÙYv^QZZZxüø1Bˆý…__ár¹°,‹ÿqiì|G£QVVVX\\Dd2)„ ™Lât:Ñ4§OŸYŒp¶æ,º®ï:íåÚív“H$þ»n“““,,, ( ×®]£µµ•+W®àùɃªª˜¦INNÎ…EÁívóòåK”·o߇q8444pïÞ=Ž?ÎÝ»w¹Ý{›h4Jaa!Š¢Ø!gŸýˆ5M#£ÎÍÍ¡i.\àäÉ“,//ÐÕÕ…;ßÍÐÐ@Ã0ðz½477³¶¶†¢ì=§Ó‰ËåbuuÅãñø3ÀÀïtvvrçΜN'RJ®ß¸Î³?žqùòeŽ£¦¦†`0HII étڦΎUUU„ÃáÊ‹F£LOOS__Oee徇µ½½Íüü<÷ïß§­­ ˲H¥Rö¼aܺu‹öövTUÝ¿¤-ËâË—/¸\.TUÝUƱXŒ™™¶¶¶lj!%%%x<Î;ÇÇwšPvA8æÍ›7$“ITU¥®®ŽÚÚZ{Óââb4‡F:¶7K¥R\ºt‰GQYYICCÃN!X__·i¤”¤R)^¿~ÍÄÄÄ®hÌLR©‡¢°°ÎÎNB¡< ©©‰êêêb˲¤Ói;¿–eáóùèíí¥­­ €¥¥%ÖÖÖðûýTUUaY±XŒááa:::¸xñ"yyy;ÄÛÛÛèºnÓ†Acc#‡ƒ ›xvv–óçÏsêÔ) ÃÀ4M&&&¥¨¨¿ß”r‡XÓ4>}úĉ'0M“žž Ã`pp«W¯°ººÊúú:^¯—L&C$! ÒÓÓÃøø¸Ýð÷4ú¥¥%úúú(**¢¬¬ŒX,†®ë  ª*ÏŸ?'??Ÿ©©)"‘/^¼ÀçóÑÚÚÊ™ŸÏÐøKãÞFŸý°²²Â“'Oø8÷¿ßÏÍßnr¤àóó󌌌066F?ñxœ>ÐÝÝMEEÅÁ¿¦o‹#ûžß¿Oè¯I=IÍÙšmÞ×ï_´«œÖ´â5IEND®B`‚eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/icons/preferences-mercurial.png0000644000175000017500000000231212060166053026722 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ •>Ö•tEXtCommentCreated with GIMPW%IDAT8Ë•ALYÇo˜i­@ĈºY°XSÂ&M„DŒÆhÂÆ"œ8 ‰gô¤ðÂÆÈ.\ !n"¢`[Ýn<èɈTB RBÚqvJ§o›"ˆû%“—™÷¾ÿû}ß{ß7BJ)ù%“I677ÙÚÚÂ4M4M£  €£G’››KVBaû¨ êºÎ»wïXXX ‘Hð5ƒ‚¼¼Mmm-‡FJi‹‹ïÇãqB¡Ÿ?&''ÇvøšNJI:¦´´¯×Kyy¹-¾GXJ‰@0=3Íììì®ð¾g™L)%>Ÿêêj”o !ý"‘HØ™M(ƒƒƒÄãq¤”{…b±–eÙYv^QZZZxüø1Bˆý…__ár¹°,‹ÿqiì|G£QVVVX\\Dd2)„ ™Lât:Ñ4§OŸYŒp¶æ,º®ï:íåÚív“H$þ»n“““,,, ( ×®]£µµ•+W®àùɃªª˜¦INNÎ…EÁívóòåK”·o߇q8444pïÞ=Ž?ÎÝ»w¹Ý{›h4Jaa!Š¢Ø!gŸýˆ5M#£ÎÍÍ¡i.\àäÉ“,//ÐÕÕ…;ßÍÐÐ@Ã0ðz½477³¶¶†¢ì=§Ó‰ËåbuuÅãñø3ÀÀïtvvrçΜN'RJ®ß¸Î³?žqùòeŽ£¦¦†`0HII étڦΎUUU„ÃáÊ‹F£LOOS__Oee徇µ½½Íüü<÷ïß§­­ ˲H¥Rö¼aܺu‹öövTUÝ¿¤-ËâË—/¸\.TUÝUƱXŒ™™¶¶¶lj!%%%x<Î;ÇÇwšPvA8æÍ›7$“ITU¥®®ŽÚÚZ{Óââb4‡F:¶7K¥R\ºt‰GQYYICCÃN!X__·i¤”¤R)^¿~ÍÄÄÄ®hÌLR©‡¢°°ÎÎNB¡< ©©‰êêêb˲¤Ói;¿–eáóùèíí¥­­ €¥¥%ÖÖÖðûýTUUaY±XŒááa:::¸xñ"yyy;ÄÛÛÛèºnÓ†Acc#‡ƒ ›xvv–óçÏsêÔ) ÃÀ4M&&&¥¨¨¿ß”r‡XÓ4>}úĉ'0M“žž Ã`pp«W¯°ººÊúú:^¯—L&C$! ÒÓÓÃøø¸Ýð÷4ú¥¥%úúú(**¢¬¬ŒX,†®ë  ª*ÏŸ?'??Ÿ©©)"‘/^¼ÀçóÑÚÚÊ™ŸÏÐøKãÞFŸý°²²Â“'Oø8÷¿ßÏÍßnr¤àóó󌌌066F?ñxœ>ÐÝÝMEEÅÁ¿¦o‹#ûžß¿Oè¯I=IÍÙšmÞ×ï_´«œÖ´â5IEND®B`‚eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBranchInputDialog.py0000644000175000017500000000340712451233371025015 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a branch operation. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgBranchInputDialog import Ui_HgBranchInputDialog class HgBranchInputDialog(QDialog, Ui_HgBranchInputDialog): """ Class implementing a dialog to enter the data for a branch operation. """ def __init__(self, branches, parent=None): """ Constructor @param branches branch names to populate the branch list with (list of string) @param parent reference to the parent widget (QWidget) """ super(HgBranchInputDialog, self).__init__(parent) self.setupUi(self) self.branchComboBox.addItems(sorted(branches)) self.branchComboBox.setEditText("") self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_branchComboBox_editTextChanged(self, txt): """ Private slot handling a change of the branch name. @param txt contents of the branch combo box (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(txt)) def getData(self): """ Public method to get the data. @return tuple of branch name (string) and a flag indicating to commit the branch (boolean) """ return (self.branchComboBox.currentText().replace(" ", "_"), self.commitCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgCommandDialog.py0000644000175000017500000000417112451233371024155 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the Mercurial command dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgCommandDialog import Ui_HgCommandDialog import Utilities class HgCommandDialog(QDialog, Ui_HgCommandDialog): """ Class implementing the Mercurial command dialog. It implements a dialog that is used to enter an arbitrary Mercurial command. It asks the user to enter the commandline parameters. """ def __init__(self, argvList, ppath, parent=None): """ Constructor @param argvList history list of commandline arguments (list of strings) @param ppath pathname of the project directory (string) @param parent parent widget of this dialog (QWidget) """ super(HgCommandDialog, self).__init__(parent) self.setupUi(self) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.okButton.setEnabled(False) self.commandCombo.clear() self.commandCombo.addItems(argvList) if len(argvList) > 0: self.commandCombo.setCurrentIndex(0) self.projectDirLabel.setText(ppath) # modify some what's this help texts t = self.commandCombo.whatsThis() if t: t += Utilities.getPercentReplacementHelp() self.commandCombo.setWhatsThis(t) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_commandCombo_editTextChanged(self, text): """ Private method used to enable/disable the OK-button. @param text ignored """ self.okButton.setDisabled(self.commandCombo.currentText() == "") def getData(self): """ Public method to retrieve the data entered into this dialog. @return commandline parameters (string) """ return self.commandCombo.currentText() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBookmarkRenameDialog.py0000644000175000017500000000423012451233372025471 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to get the data to rename a bookmark. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgBookmarkRenameDialog import Ui_HgBookmarkRenameDialog class HgBookmarkRenameDialog(QDialog, Ui_HgBookmarkRenameDialog): """ Class implementing a dialog to get the data to rename a bookmark. """ def __init__(self, bookmarksList, parent=None): """ Constructor @param bookmarksList list of bookmarks (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgBookmarkRenameDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.bookmarkCombo.addItems(sorted(bookmarksList)) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __updateUI(self): """ Private slot to update the UI. """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( self.nameEdit.text() != "" and self.bookmarkCombo.currentText() != "" ) @pyqtSlot(str) def on_nameEdit_textChanged(self, txt): """ Private slot to handle changes of the bookmark name. @param txt text of the edit (string) """ self.__updateUI() @pyqtSlot(str) def on_bookmarkCombo_editTextChanged(self, txt): """ Private slot to handle changes of the selected bookmark. @param txt name of the selected bookmark (string) """ self.__updateUI() def getData(self): """ Public method to retrieve the entered data. @return tuple naming the new and old bookmark names (string, string) """ return ( self.nameEdit.text().replace(" ", "_"), self.bookmarkCombo.currentText().replace(" ", "_") ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgTagBranchListDialog.py0000644000175000017500000002651012537064320025266 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to show a list of tags or branches. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, QProcess, Qt, QTimer, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, \ QTreeWidgetItem, QLineEdit from E5Gui import E5MessageBox from .Ui_HgTagBranchListDialog import Ui_HgTagBranchListDialog class HgTagBranchListDialog(QDialog, Ui_HgTagBranchListDialog): """ Class implementing a dialog to show a list of tags or branches. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(HgTagBranchListDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = QProcess() self.vcs = vcs self.tagsList = None self.allTagsList = None self.__hgClient = vcs.getClient() self.tagList.headerItem().setText(self.tagList.columnCount(), "") self.tagList.header().setSortIndicator(3, Qt.AscendingOrder) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path, tags, tagsList, allTagsList): """ Public slot to start the tags command. @param path name of directory to be listed (string) @param tags flag indicating a list of tags is requested (False = branches, True = tags) @param tagsList reference to string list receiving the tags (list of strings) @param allTagsList reference to string list all tags (list of strings) """ self.errorGroup.hide() self.intercept = False self.tagsMode = tags if not tags: self.setWindowTitle(self.tr("Mercurial Branches List")) self.tagList.headerItem().setText(2, self.tr("Status")) self.activateWindow() self.tagsList = tagsList self.allTagsList = allTagsList dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if self.tagsMode: args = self.vcs.initCommand("tags") args.append('--verbose') else: args = self.vcs.initCommand("branches") args.append('--closed') if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.process = None self.__resizeColumns() self.__resort() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __resort(self): """ Private method to resort the tree. """ self.tagList.sortItems( self.tagList.sortColumn(), self.tagList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.tagList.header().resizeSections(QHeaderView.ResizeToContents) self.tagList.header().setStretchLastSection(True) def __generateItem(self, revision, changeset, status, name): """ Private method to generate a tag item in the tag list. @param revision revision of the tag/branch (string) @param changeset changeset of the tag/branch (string) @param status of the tag/branch (string) @param name name of the tag/branch (string) """ itm = QTreeWidgetItem(self.tagList) itm.setData(0, Qt.DisplayRole, int(revision)) itm.setData(1, Qt.DisplayRole, changeset) itm.setData(2, Qt.DisplayRole, status) itm.setData(3, Qt.DisplayRole, name) itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(1, Qt.AlignRight) itm.setTextAlignment(2, Qt.AlignHCenter) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.vcs.getEncoding(), 'replace').strip() self.__processOutputLine(s) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ li = line.split() if li[-1][0] in "1234567890": # last element is a rev:changeset if self.tagsMode: status = "" else: status = self.tr("active") rev, changeset = li[-1].split(":", 1) del li[-1] else: if self.tagsMode: status = self.tr("yes") else: status = li[-1][1:-1] rev, changeset = li[-2].split(":", 1) del li[-2:] name = " ".join(li) self.__generateItem(rev, changeset, status, name) if name not in ["tip", "default"]: if self.tagsList is not None: self.tagsList.append(name) if self.allTagsList is not None: self.allTagsList.append(name) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgTagBranchListDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgUserConfigDataDialog.py0000644000175000017500000000532012451233372025433 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter some user data. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_HgUserConfigDataDialog import Ui_HgUserConfigDataDialog class HgUserConfigDataDialog(QDialog, Ui_HgUserConfigDataDialog): """ Class implementing a dialog to enter some user data. """ def __init__(self, version=(0, 0), parent=None): """ Constructor @param version Mercurial version info (tuple of two integers) @param parent reference to the parent widget (QWidget) """ super(HgUserConfigDataDialog, self).__init__(parent) self.setupUi(self) if version >= (2, 3): self.transplantCheckBox.setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public method to retrieve the entered data. @return tuple with user's first name, last name, email address, list of activated extensions and dictionary with extension data (tuple of three strings, a list of strings and a dictionary with extension name as key) """ extensions = [] extensionsData = {} if self.fetchCheckBox.isChecked(): extensions.append("fetch") if self.gpgCheckBox.isChecked(): extensions.append("gpg") if self.purgeCheckBox.isChecked(): extensions.append("purge") if self.queuesCheckBox.isChecked(): extensions.append("mq") if self.rebaseCheckBox.isChecked(): extensions.append("rebase") if self.shelveCheckBox.isChecked(): extensions.append("shelve") if self.transplantCheckBox.isChecked(): extensions.append("transplant") if self.largefilesCheckBox.isChecked(): extensions.append("largefiles") largefilesDataDict = {} lfFileSize = self.lfFileSizeSpinBox.value() if lfFileSize != 10: # default value is 10 MB largefilesDataDict["minsize"] = lfFileSize lfFilePatterns = self.lfFilePatternsEdit.text() if lfFilePatterns: largefilesDataDict["patterns"] = lfFilePatterns.split() if largefilesDataDict: extensionsData["largefiles"] = largefilesDataDict return ( self.firstNameEdit.text(), self.lastNameEdit.text(), self.emailEdit.text(), extensions, extensionsData, ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBookmarksInOutDialog.py0000644000175000017500000002525712537064320025517 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to show a list of incoming or outgoing bookmarks. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, QProcess, Qt, QTimer, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, \ QTreeWidgetItem, QLineEdit from E5Gui import E5MessageBox from .Ui_HgBookmarksInOutDialog import Ui_HgBookmarksInOutDialog class HgBookmarksInOutDialog(QDialog, Ui_HgBookmarksInOutDialog): """ Class implementing a dialog to show a list of incoming or outgoing bookmarks. """ INCOMING = 0 OUTGOING = 1 def __init__(self, vcs, mode, parent=None): """ Constructor @param vcs reference to the vcs object @param mode mode of the dialog (HgBookmarksInOutDialog.INCOMING, HgBookmarksInOutDialog.OUTGOING) @param parent reference to the parent widget (QWidget) @exception ValueError raised to indicate an invalid dialog mode """ super(HgBookmarksInOutDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) if mode not in [self.INCOMING, self.OUTGOING]: raise ValueError("Bad value for mode") if mode == self.INCOMING: self.setWindowTitle(self.tr("Mercurial Incoming Bookmarks")) elif mode == self.OUTGOING: self.setWindowTitle(self.tr("Mercurial Outgoing Bookmarks")) self.process = QProcess() self.vcs = vcs self.mode = mode self.__hgClient = vcs.getClient() self.bookmarksList.headerItem().setText( self.bookmarksList.columnCount(), "") self.bookmarksList.header().setSortIndicator(3, Qt.AscendingOrder) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path): """ Public slot to start the bookmarks command. @param path name of directory to be listed (string) @exception ValueError raised to indicate an invalid dialog mode """ self.errorGroup.hide() self.intercept = False self.activateWindow() dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if self.mode == self.INCOMING: args = self.vcs.initCommand("incoming") elif self.mode == self.OUTGOING: args = self.vcs.initCommand("outgoing") else: raise ValueError("Bad value for mode") args.append('--bookmarks') if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.process = None if self.bookmarksList.topLevelItemCount() == 0: # no bookmarks defined self.__generateItem(self.tr("no bookmarks found"), "") self.__resizeColumns() self.__resort() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __resort(self): """ Private method to resort the tree. """ self.bookmarksList.sortItems( self.bookmarksList.sortColumn(), self.bookmarksList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.bookmarksList.header().resizeSections( QHeaderView.ResizeToContents) self.bookmarksList.header().setStretchLastSection(True) def __generateItem(self, changeset, name): """ Private method to generate a bookmark item in the bookmarks list. @param changeset changeset of the bookmark (string) @param name name of the bookmark (string) """ QTreeWidgetItem(self.bookmarksList, [ name, changeset]) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.vcs.getEncoding(), 'replace') self.__processOutputLine(s) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ if line.startswith(" "): li = line.strip().split() changeset = li[-1] del li[-1] name = " ".join(li) self.__generateItem(changeset, name) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgBookmarksInOutDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.ui0000644000175000017500000000670312263302645024152 0ustar piotrpiotr HgArchiveDialog 0 0 400 167 Mercurial Archive true Archive: Enter the file name of the archive Type: Select the archive type Prefix: Enter the directory prefix for the files in the archive Select to recurse into subrepositories Include Subrepositories Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Press to select the archive file name via a file selection dialog archiveEdit archiveButton typeComboBox prefixEdit subReposCheckBox buttonBox buttonBox accepted() HgArchiveDialog accept() 248 254 157 274 buttonBox rejected() HgArchiveDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgConflictsListDialog.py0000644000175000017500000003461012451233372025361 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a dialog to show a list of files which had or still have conflicts. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot, Qt, QPoint, QProcess, QTimer from PyQt5.QtGui import QWidget from PyQt5.QtWidgets import QAbstractButton, QDialogButtonBox, QHeaderView, \ QTreeWidgetItem, QLineEdit, QApplication from E5Gui import E5MessageBox from E5Gui.E5Application import e5App from .Ui_HgConflictsListDialog import Ui_HgConflictsListDialog import Utilities.MimeTypes class HgConflictsListDialog(QWidget, Ui_HgConflictsListDialog): """ Class implementing a dialog to show a list of files which had or still have conflicts. """ StatusRole = Qt.UserRole + 1 FilenameRole = Qt.UserRole + 2 def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(HgConflictsListDialog, self).__init__(parent) self.setupUi(self) self.__position = QPoint() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.conflictsList.headerItem().setText( self.conflictsList.columnCount(), "") self.conflictsList.header().setSortIndicator(0, Qt.AscendingOrder) self.refreshButton = self.buttonBox.addButton( self.tr("&Refresh"), QDialogButtonBox.ActionRole) self.refreshButton.setToolTip( self.tr("Press to refresh the list of conflicts")) self.refreshButton.setEnabled(False) self.vcs = vcs self.project = e5App().getObject("Project") self.__hgClient = vcs.getClient() if self.__hgClient: self.process = None else: self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.__position = self.pos() e.accept() def show(self): """ Public slot to show the dialog. """ if not self.__position.isNull(): self.move(self.__position) super(HgConflictsListDialog, self).show() def start(self, path): """ Public slot to start the tags command. @param path name of directory to list conflicts for (string) """ self.errorGroup.hide() QApplication.processEvents() self.intercept = False dname, fname = self.vcs.splitPath(path) # find the root of the repo self.__repodir = dname while not os.path.isdir( os.path.join(self.__repodir, self.vcs.adminDir)): self.__repodir = os.path.dirname(self.__repodir) if os.path.splitdrive(self.__repodir)[1] == os.sep: return self.activateWindow() self.raise_() self.conflictsList.clear() self.__started = True self.__getEntries() def __getEntries(self): """ Private method to get the conflict entries. """ args = self.vcs.initCommand("resolve") args.append('--list') if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(self.__repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.refreshButton.setEnabled(True) self.__resizeColumns() self.__resort() self.on_conflictsList_itemSelectionChanged() @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() elif button == self.refreshButton: self.on_refreshButton_clicked() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __resort(self): """ Private method to resort the tree. """ self.conflictsList.sortItems( self.conflictsList.sortColumn(), self.conflictsList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.conflictsList.header().resizeSections( QHeaderView.ResizeToContents) self.conflictsList.header().setStretchLastSection(True) def __generateItem(self, status, name): """ Private method to generate a tag item in the tag list. @param status status of the file (string) @param name name of the file (string) """ itm = QTreeWidgetItem(self.conflictsList) if status == "U": itm.setText(0, self.tr("Unresolved")) elif status == "R": itm.setText(0, self.tr("Resolved")) else: itm.setText(0, self.tr("Unknown Status")) itm.setText(1, name) itm.setData(0, self.StatusRole, status) itm.setData(0, self.FilenameRole, self.project.getAbsolutePath(name)) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.vcs.getEncoding(), 'replace').strip() self.__processOutputLine(s) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ status, filename = line.strip().split(None, 1) self.__generateItem(status, filename) @pyqtSlot() def on_refreshButton_clicked(self): """ Private slot to refresh the log. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.inputGroup.setEnabled(True) self.inputGroup.show() self.refreshButton.setEnabled(False) self.start(self.__repodir) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgConflictsListDialog, self).keyPressEvent(evt) @pyqtSlot(QTreeWidgetItem, int) def on_conflictsList_itemDoubleClicked(self, item, column): """ Private slot to open the double clicked entry. @param item reference to the double clicked item (QTreeWidgetItem) @param column column that was double clicked (integer) """ self.on_editButton_clicked() @pyqtSlot() def on_conflictsList_itemSelectionChanged(self): """ Private slot to handle a change of selected conflict entries. """ selectedCount = len(self.conflictsList.selectedItems()) unresolved = resolved = 0 for itm in self.conflictsList.selectedItems(): status = itm.data(0, self.StatusRole) if status == "U": unresolved += 1 elif status == "R": resolved += 1 self.resolvedButton.setEnabled(unresolved > 0) self.unresolvedButton.setEnabled(resolved > 0) self.reMergeButton.setEnabled(unresolved > 0) self.editButton.setEnabled( selectedCount == 1 and Utilities.MimeTypes.isTextFile( self.conflictsList.selectedItems()[0].data( 0, self.FilenameRole))) @pyqtSlot() def on_resolvedButton_clicked(self): """ Private slot to mark the selected entries as resolved. """ names = [ itm.data(0, self.FilenameRole) for itm in self.conflictsList.selectedItems() if itm.data(0, self.StatusRole) == "U" ] if names: self.vcs.hgResolved(names) self.on_refreshButton_clicked() @pyqtSlot() def on_unresolvedButton_clicked(self): """ Private slot to mark the selected entries as unresolved. """ names = [ itm.data(0, self.FilenameRole) for itm in self.conflictsList.selectedItems() if itm.data(0, self.StatusRole) == "R" ] if names: self.vcs.hgResolved(names, unresolve=True) self.on_refreshButton_clicked() @pyqtSlot() def on_reMergeButton_clicked(self): """ Private slot to re-merge the selected entries. """ names = [ itm.data(0, self.FilenameRole) for itm in self.conflictsList.selectedItems() if itm.data(0, self.StatusRole) == "U" ] if names: self.vcs.hgReMerge(names) @pyqtSlot() def on_editButton_clicked(self): """ Private slot to open the selected file in an editor. """ itm = self.conflictsList.selectedItems()[0] filename = itm.data(0, self.FilenameRole) if Utilities.MimeTypes.isTextFile(filename): e5App().getObject("ViewManager").getEditor(filename) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.ui0000644000175000017500000004071712312353424026417 0ustar piotrpiotr HgRevisionsSelectionDialog 0 0 371 505 Mercurial Diff true Revision &1 Select to specify a revision by number Number false false Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 40 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false Enter a tag name true Select to specify a revision by a branch Branch: false Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select tip revision of repository TIP false Select revision before last commit PREV true No revision selected Revision &2 Select to specify a revision by number Number false Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 40 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false Enter a tag name true Select to specify a revision by a branch Branch: false Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select tip revision of repository TIP true Select revision before last commit PREV No revision selected Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource number1Button number1SpinBox id1Button id1Edit tag1Button tag1Combo branch1Button branch1Combo bookmark1Button bookmark1Combo tip1Button prev1Button none1Button number2Button number2SpinBox id2Button id2Edit tag2Button tag2Combo branch2Button branch2Combo bookmark2Button bookmark2Combo tip2Button prev2Button none2Button buttonBox buttonBox accepted() HgRevisionsSelectionDialog accept() 54 440 21 143 buttonBox rejected() HgRevisionsSelectionDialog reject() 106 440 73 140 number1Button toggled(bool) number1SpinBox setEnabled(bool) 62 45 148 43 number2Button toggled(bool) number2SpinBox setEnabled(bool) 72 258 183 258 id1Button toggled(bool) id1Edit setEnabled(bool) 32 71 147 72 id2Button toggled(bool) id2Edit setEnabled(bool) 68 286 230 286 tag1Button toggled(bool) tag1Combo setEnabled(bool) 59 105 129 101 branch1Button toggled(bool) branch1Combo setEnabled(bool) 50 124 117 128 tag2Button toggled(bool) tag2Combo setEnabled(bool) 36 306 149 306 branch2Button toggled(bool) branch2Combo setEnabled(bool) 73 331 140 331 bookmark1Button toggled(bool) bookmark1Combo setEnabled(bool) 24 152 135 148 bookmark2Button toggled(bool) bookmark2Combo setEnabled(bool) 21 363 145 361 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgCopyDialog.py0000644000175000017500000000647312451233372023521 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a copy or rename operation. """ from __future__ import unicode_literals import os.path from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter, E5DirCompleter from E5Gui import E5FileDialog from .Ui_HgCopyDialog import Ui_HgCopyDialog import Utilities import UI.PixmapCache class HgCopyDialog(QDialog, Ui_HgCopyDialog): """ Class implementing a dialog to enter the data for a copy or rename operation. """ def __init__(self, source, parent=None, move=False): """ Constructor @param source name of the source file/directory (string) @param parent parent widget (QWidget) @param move flag indicating a move operation (boolean) """ super(HgCopyDialog, self).__init__(parent) self.setupUi(self) self.dirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.source = source if os.path.isdir(self.source): self.targetCompleter = E5DirCompleter(self.targetEdit) else: self.targetCompleter = E5FileCompleter(self.targetEdit) if move: self.setWindowTitle(self.tr('Mercurial Move')) else: self.forceCheckBox.setEnabled(False) self.sourceEdit.setText(source) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public method to retrieve the copy data. @return the target name (string) and a flag indicating the operation should be enforced (boolean) """ target = self.targetEdit.text() if not os.path.isabs(target): sourceDir = os.path.dirname(self.sourceEdit.text()) target = os.path.join(sourceDir, target) return Utilities.toNativeSeparators(target), \ self.forceCheckBox.isChecked() @pyqtSlot() def on_dirButton_clicked(self): """ Private slot to handle the button press for selecting the target via a selection dialog. """ if os.path.isdir(self.source): target = E5FileDialog.getExistingDirectory( self, self.tr("Select target"), self.targetEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) else: target = E5FileDialog.getSaveFileName( self, self.tr("Select target"), self.targetEdit.text(), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if target: self.targetEdit.setText(Utilities.toNativeSeparators(target)) @pyqtSlot(str) def on_targetEdit_textChanged(self, txt): """ Private slot to handle changes of the target. @param txt contents of the target edit (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( os.path.isabs(txt) or os.path.dirname(txt) == "") eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgClient.py0000644000175000017500000003277512451233372022711 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing an interface to the Mercurial command server. """ try: str = unicode except NameError: pass import struct import io from PyQt5.QtCore import QProcess, QObject, QByteArray, QCoreApplication, \ QThread from PyQt5.QtWidgets import QDialog from .HgUtilities import prepareProcess class HgClient(QObject): """ Class implementing the Mercurial command server interface. """ InputFormat = ">I" OutputFormat = ">cI" OutputFormatSize = struct.calcsize(OutputFormat) ReturnFormat = ">i" Channels = (b"I", b"L", b"o", b"e", b"r", b"d") def __init__(self, repoPath, encoding, vcs, parent=None): """ Constructor @param repoPath root directory of the repository (string) @param encoding encoding to be used by the command server (string) @param vcs reference to the VCS object (Hg) @param parent reference to the parent object (QObject) """ super(HgClient, self).__init__(parent) self.__server = None self.__started = False self.__version = None self.__encoding = vcs.getEncoding() self.__cancel = False self.__commandRunning = False self.__repoPath = repoPath # generate command line and environment self.__serverArgs = vcs.initCommand("serve") self.__serverArgs.append("--cmdserver") self.__serverArgs.append("pipe") self.__serverArgs.append("--config") self.__serverArgs.append("ui.interactive=True") if repoPath: self.__serverArgs.append("--repository") self.__serverArgs.append(repoPath) if encoding: self.__encoding = encoding if "--encoding" in self.__serverArgs: # use the defined encoding via the environment index = self.__serverArgs.index("--encoding") del self.__serverArgs[index:index + 2] def startServer(self): """ Public method to start the command server. @return tuple of flag indicating a successful start (boolean) and an error message (string) in case of failure """ self.__server = QProcess() self.__server.setWorkingDirectory(self.__repoPath) # connect signals self.__server.finished.connect(self.__serverFinished) prepareProcess(self.__server, self.__encoding) self.__server.start('hg', self.__serverArgs) serverStarted = self.__server.waitForStarted(5000) if not serverStarted: return False, self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg') self.__server.setReadChannel(QProcess.StandardOutput) ok, error = self.__readHello() self.__started = ok return ok, error def stopServer(self): """ Public method to stop the command server. """ if self.__server is not None: self.__server.closeWriteChannel() res = self.__server.waitForFinished(5000) if not res: self.__server.terminate() res = self.__server.waitForFinished(3000) if not res: self.__server.kill() self.__server.waitForFinished(3000) self.__started = False self.__server.deleteLater() self.__server = None def restartServer(self): """ Public method to restart the command server. @return tuple of flag indicating a successful start (boolean) and an error message (string) in case of failure """ self.stopServer() return self.startServer() def __readHello(self): """ Private method to read the hello message sent by the command server. @return tuple of flag indicating success (boolean) and an error message in case of failure (string) """ ch, msg = self.__readChannel() if not ch: return False, self.tr("Did not receive the 'hello' message.") elif ch != "o": return False, self.tr("Received data on unexpected channel.") msg = msg.split("\n") if not msg[0].startswith("capabilities: "): return False, self.tr( "Bad 'hello' message, expected 'capabilities: '" " but got '{0}'.").format(msg[0]) self.__capabilities = msg[0][len('capabilities: '):] if not self.__capabilities: return False, self.tr("'capabilities' message did not contain" " any capability.") self.__capabilities = set(self.__capabilities.split()) if "runcommand" not in self.__capabilities: return False, "'capabilities' did not contain 'runcommand'." if not msg[1].startswith("encoding: "): return False, self.tr( "Bad 'hello' message, expected 'encoding: '" " but got '{0}'.").format(msg[1]) encoding = msg[1][len('encoding: '):] if not encoding: return False, self.tr("'encoding' message did not contain" " any encoding.") self.__encoding = encoding return True, "" def __serverFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__started = False def __readChannel(self): """ Private method to read data from the command server. @return tuple of channel designator and channel data (string, integer or string or bytes) """ if self.__server.bytesAvailable() > 0 or \ self.__server.waitForReadyRead(10000): data = bytes(self.__server.peek(HgClient.OutputFormatSize)) if not data or len(data) < HgClient.OutputFormatSize: return "", "" channel, length = struct.unpack(HgClient.OutputFormat, data) channel = channel.decode(self.__encoding) if channel in "IL": self.__server.read(HgClient.OutputFormatSize) return channel, length else: if self.__server.bytesAvailable() < \ HgClient.OutputFormatSize + length: return "", "" self.__server.read(HgClient.OutputFormatSize) data = self.__server.read(length) if channel == "r": return (channel, data) else: return (channel, str(data, self.__encoding, "replace")) else: return "", "" def __writeDataBlock(self, data): """ Private slot to write some data to the command server. @param data data to be sent (string) """ if not isinstance(data, bytes): data = data.encode(self.__encoding) self.__server.write( QByteArray(struct.pack(HgClient.InputFormat, len(data)))) self.__server.write(QByteArray(data)) self.__server.waitForBytesWritten() def __runcommand(self, args, inputChannels, outputChannels): """ Private method to run a command in the server (low level). @param args list of arguments for the command (list of string) @param inputChannels dictionary of input channels. The dictionary must have the keys 'I' and 'L' and each entry must be a function receiving the number of bytes to write. @param outputChannels dictionary of output channels. The dictionary must have the keys 'o' and 'e' and each entry must be a function receiving the data. @return result code of the command, -1 if the command server wasn't started or -10, if the command was canceled (integer) @exception RuntimeError raised to indicate an unexpected command channel """ if not self.__started: return -1 self.__server.write(QByteArray(b'runcommand\n')) self.__writeDataBlock('\0'.join(args)) while True: QCoreApplication.processEvents() if self.__cancel: return -10 if self.__server is None: return -1 if self.__server is None or self.__server.bytesAvailable() == 0: QThread.msleep(50) continue channel, data = self.__readChannel() # input channels if channel in inputChannels: input = inputChannels[channel](data) if channel == "L": # echo the input to the output if it was a prompt outputChannels["o"](input) self.__writeDataBlock(input) # output channels elif channel in outputChannels: outputChannels[channel](data) # result channel, command is finished elif channel == "r": return struct.unpack(HgClient.ReturnFormat, data)[0] # unexpected but required channel elif channel.isupper(): raise RuntimeError( "Unexpected but required channel '{0}'.".format(channel)) # optional channels or no channel at all else: pass def __prompt(self, size, message): """ Private method to prompt the user for some input. @param size maximum length of the requested input (integer) @param message message sent by the server (string) @return data entered by the user (string) """ from .HgClientPromptDialog import HgClientPromptDialog input = "" dlg = HgClientPromptDialog(size, message) if dlg.exec_() == QDialog.Accepted: input = dlg.getInput() + '\n' return input def runcommand(self, args, prompt=None, input=None, output=None, error=None): """ Public method to execute a command via the command server. @param args list of arguments for the command (list of string) @keyparam prompt function to reply to prompts by the server. It receives the max number of bytes to return and the contents of the output channel received so far. @keyparam input function to reply to bulk data requests by the server. It receives the max number of bytes to return. @keyparam output function receiving the data from the server (string). If a prompt function is given, this parameter will be ignored. @keyparam error function receiving error messages from the server (string) @return output and errors of the command server (string). In case output and/or error functions were given, the respective return value will be an empty string. """ self.__commandRunning = True outputChannels = {} outputBuffer = None errorBuffer = None if prompt is not None or output is None: outputBuffer = io.StringIO() outputChannels["o"] = outputBuffer.write else: outputChannels["o"] = output if error: outputChannels["e"] = error else: errorBuffer = io.StringIO() outputChannels["e"] = errorBuffer.write inputChannels = {} if prompt is not None: def func(size): reply = prompt(size, outputBuffer.getvalue()) return reply inputChannels["L"] = func else: def myprompt(size): if outputBuffer is None: msg = self.tr("For message see output dialog.") else: msg = outputBuffer.getvalue() reply = self.__prompt(size, msg) return reply inputChannels["L"] = myprompt if input is not None: inputChannels["I"] = input self.__cancel = False self.__runcommand(args, inputChannels, outputChannels) if outputBuffer: out = outputBuffer.getvalue() else: out = "" if errorBuffer: err = errorBuffer.getvalue() else: err = "" self.__commandRunning = False return out, err def cancel(self): """ Public method to cancel the running command. """ self.__cancel = True self.restartServer() def wasCanceled(self): """ Public method to check, if the last command was canceled. @return flag indicating the cancel state (boolean) """ return self.__cancel def isExecuting(self): """ Public method to check, if the server is executing a command. @return flag indicating the execution of a command (boolean) """ return self.__commandRunning eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgExtension.py0000644000175000017500000000141712451233372023434 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the base class for Mercurial extension interfaces. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject class HgExtension(QObject): """ Class implementing the base class for Mercurial extension interfaces. """ def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(HgExtension, self).__init__(vcs) self.vcs = vcs def shutdown(self): """ Public method used to shutdown the extension interface. The method of this base class does nothing. """ pass eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py0000644000175000017500000016516112523374571024703 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to browse the log history. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os import re from PyQt5.QtCore import pyqtSlot, Qt, QDate, QProcess, QTimer, QRegExp, \ QSize, QPoint from PyQt5.QtGui import QCursor, QColor, QPixmap, QPainter, QPen, QBrush, QIcon from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QHeaderView, \ QTreeWidgetItem, QApplication, QLineEdit, QMenu from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .Ui_HgLogBrowserDialog import Ui_HgLogBrowserDialog import UI.PixmapCache COLORNAMES = ["blue", "darkgreen", "red", "green", "darkblue", "purple", "cyan", "olive", "magenta", "darkred", "darkmagenta", "darkcyan", "gray", "yellow"] COLORS = [str(QColor(x).name()) for x in COLORNAMES] class HgLogBrowserDialog(QWidget, Ui_HgLogBrowserDialog): """ Class implementing a dialog to browse the log history. """ IconColumn = 0 BranchColumn = 1 RevisionColumn = 2 PhaseColumn = 3 AuthorColumn = 4 DateColumn = 5 MessageColumn = 6 TagsColumn = 7 LargefilesCacheL = ".hglf/" LargefilesCacheW = ".hglf\\" PathSeparatorRe = re.compile(r"/|\\") ClosedIndicator = " \u2612" def __init__(self, vcs, mode="log", parent=None): """ Constructor @param vcs reference to the vcs object @param mode mode of the dialog (string; one of log, incoming, outgoing) @param parent parent widget (QWidget) """ super(HgLogBrowserDialog, self).__init__(parent) self.setupUi(self) self.__position = QPoint() if mode == "log": self.setWindowTitle(self.tr("Mercurial Log")) elif mode == "incoming": self.setWindowTitle(self.tr("Mercurial Log (Incoming)")) elif mode == "outgoing": self.setWindowTitle(self.tr("Mercurial Log (Outgoing)")) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.filesTree.headerItem().setText(self.filesTree.columnCount(), "") self.filesTree.header().setSortIndicator(0, Qt.AscendingOrder) self.refreshButton = self.buttonBox.addButton( self.tr("&Refresh"), QDialogButtonBox.ActionRole) self.refreshButton.setToolTip( self.tr("Press to refresh the list of changesets")) self.refreshButton.setEnabled(False) self.vcs = vcs if mode in ("log", "incoming", "outgoing"): self.commandMode = mode self.initialCommandMode = mode else: self.commandMode = "log" self.initialCommandMode = "log" self.__hgClient = vcs.getClient() self.__detailsTemplate = self.tr( "" "" "" "" "" "" "" "" "
Revision{0}
Date{1}
Author{2}
Branch{3}
Tags{4}
Bookmarks{5}
Parents{6}
" ) self.__bundle = "" self.__filename = "" self.__isFile = False self.__currentRevision = "" self.intercept = False self.__initData() self.__allBranchesFilter = self.tr("All") self.fromDate.setDisplayFormat("yyyy-MM-dd") self.toDate.setDisplayFormat("yyyy-MM-dd") self.__resetUI() self.__messageRole = Qt.UserRole self.__changesRole = Qt.UserRole + 1 self.__edgesRole = Qt.UserRole + 2 self.__parentsRole = Qt.UserRole + 3 if self.__hgClient: self.process = None else: self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.flags = { 'A': self.tr('Added'), 'D': self.tr('Deleted'), 'M': self.tr('Modified'), } self.__dotRadius = 8 self.__rowHeight = 20 self.logTree.setIconSize( QSize(100 * self.__rowHeight, self.__rowHeight)) self.BookmarksColumn = self.logTree.columnCount() self.logTree.headerItem().setText( self.BookmarksColumn, self.tr("Bookmarks")) if self.vcs.version < (2, 1): self.logTree.setColumnHidden(self.PhaseColumn, True) self.__actionsMenu = QMenu() if self.vcs.version >= (2, 0): self.__graftAct = self.__actionsMenu.addAction( self.tr("Copy Changesets"), self.__graftActTriggered) self.__graftAct.setToolTip(self.tr( "Copy the selected changesets to the current branch")) else: self.__graftAct = None if self.vcs.version >= (2, 1): self.__phaseAct = self.__actionsMenu.addAction( self.tr("Change Phase"), self.__phaseActTriggered) self.__phaseAct.setToolTip(self.tr( "Change the phase of the selected revisions")) self.__phaseAct.setWhatsThis(self.tr( """Change Phase\n

This changes the phase of the""" """ selected revisions. The selected revisions have to have""" """ the same current phase.

""")) else: self.__phaseAct = None self.__tagAct = self.__actionsMenu.addAction( self.tr("Tag"), self.__tagActTriggered) self.__tagAct.setToolTip(self.tr("Tag the selected revision")) self.__switchAct = self.__actionsMenu.addAction( self.tr("Switch"), self.__switchActTriggered) self.__switchAct.setToolTip(self.tr( "Switch the working directory to the selected revision")) if self.vcs.version >= (2, 0): self.__lfPullAct = self.__actionsMenu.addAction( self.tr("Pull Large Files"), self.__lfPullActTriggered) self.__lfPullAct.setToolTip(self.tr( "Pull large files for selected revisions")) else: self.__lfPullAct = None self.actionsButton.setIcon( UI.PixmapCache.getIcon("actionsToolButton.png")) self.actionsButton.setMenu(self.__actionsMenu) def __initData(self): """ Private method to (re-)initialize some data. """ self.__maxDate = QDate() self.__minDate = QDate() self.__filterLogsEnabled = True self.buf = [] # buffer for stdout self.diff = None self.__started = False self.__lastRev = 0 self.projectMode = False # attributes to store log graph data self.__revs = [] self.__revColors = {} self.__revColor = 0 self.__branchColors = {} self.__projectRevision = -1 self.__projectBranch = "" def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.__position = self.pos() e.accept() def show(self): """ Public slot to show the dialog. """ if not self.__position.isNull(): self.move(self.__position) self.__resetUI() super(HgLogBrowserDialog, self).show() def __resetUI(self): """ Private method to reset the user interface. """ self.branchCombo.clear() self.fromDate.setDate(QDate.currentDate()) self.toDate.setDate(QDate.currentDate()) self.fieldCombo.setCurrentIndex(self.fieldCombo.findText( self.tr("Message"))) self.limitSpinBox.setValue(self.vcs.getPlugin().getPreferences( "LogLimit")) self.stopCheckBox.setChecked(self.vcs.getPlugin().getPreferences( "StopLogOnCopy")) if self.initialCommandMode in ("incoming", "outgoing"): self.nextButton.setEnabled(False) self.limitSpinBox.setEnabled(False) else: self.nextButton.setEnabled(True) self.limitSpinBox.setEnabled(True) self.logTree.clear() self.commandMode = self.initialCommandMode def __resizeColumnsLog(self): """ Private method to resize the log tree columns. """ self.logTree.header().resizeSections(QHeaderView.ResizeToContents) self.logTree.header().setStretchLastSection(True) def __resizeColumnsFiles(self): """ Private method to resize the changed files tree columns. """ self.filesTree.header().resizeSections(QHeaderView.ResizeToContents) self.filesTree.header().setStretchLastSection(True) def __resortFiles(self): """ Private method to resort the changed files tree. """ sortColumn = self.filesTree.sortColumn() self.filesTree.sortItems( 1, self.filesTree.header().sortIndicatorOrder()) self.filesTree.sortItems( sortColumn, self.filesTree.header().sortIndicatorOrder()) def __getColor(self, n): """ Private method to get the (rotating) name of the color given an index. @param n color index (integer) @return color name (string) """ return COLORS[n % len(COLORS)] def __branchColor(self, branchName): """ Private method to calculate a color for a given branch name. @param branchName name of the branch (string) @return name of the color to use (string) """ if branchName not in self.__branchColors: self.__branchColors[branchName] = self.__getColor( len(self.__branchColors)) return self.__branchColors[branchName] def __generateEdges(self, rev, parents): """ Private method to generate edge info for the give data. @param rev revision to calculate edge info for (integer) @param parents list of parent revisions (list of integers) @return tuple containing the column and color index for the given node and a list of tuples indicating the edges between the given node and its parents (integer, integer, [(integer, integer, integer), ...]) """ if rev not in self.__revs: # new head self.__revs.append(rev) self.__revColors[rev] = self.__revColor self.__revColor += 1 col = self.__revs.index(rev) color = self.__revColors.pop(rev) next = self.__revs[:] # add parents to next addparents = [p for p in parents if p not in next] next[col:col + 1] = addparents # set colors for the parents for i, p in enumerate(addparents): if not i: self.__revColors[p] = color else: self.__revColors[p] = self.__revColor self.__revColor += 1 # add edges to the graph edges = [] if parents[0] != -1: for ecol, erev in enumerate(self.__revs): if erev in next: edges.append( (ecol, next.index(erev), self.__revColors[erev])) elif erev == rev: for p in parents: edges.append( (ecol, next.index(p), self.__revColors[p])) self.__revs = next return col, color, edges def __generateIcon(self, column, color, bottomedges, topedges, dotColor, currentRev, closed): """ Private method to generate an icon containing the revision tree for the given data. @param column column index of the revision (integer) @param color color of the node (integer) @param bottomedges list of edges for the bottom of the node (list of tuples of three integers) @param topedges list of edges for the top of the node (list of tuples of three integers) @param dotColor color to be used for the dot (QColor) @param currentRev flag indicating to draw the icon for the current revision (boolean) @param closed flag indicating to draw an icon for a closed branch (boolean) @return icon for the node (QIcon) """ def col2x(col, radius): """ Local function to calculate a x-position for a column. @param col column number (integer) @param radius radius of the indicator circle (integer) """ return int(1.2 * radius) * col + radius // 2 + 3 radius = self.__dotRadius w = len(bottomedges) * radius + 20 h = self.__rowHeight dot_x = col2x(column, radius) - radius // 2 dot_y = h // 2 pix = QPixmap(w, h) pix.fill(QColor(0, 0, 0, 0)) painter = QPainter(pix) painter.setRenderHint(QPainter.Antialiasing) pen = QPen(Qt.blue) pen.setWidth(2) painter.setPen(pen) lpen = QPen(pen) lpen.setColor(Qt.black) painter.setPen(lpen) # draw the revision history lines for y1, y2, lines in ((0, h, bottomedges), (-h, 0, topedges)): if lines: for start, end, ecolor in lines: lpen = QPen(pen) lpen.setColor(QColor(self.__getColor(ecolor))) lpen.setWidth(2) painter.setPen(lpen) x1 = col2x(start, radius) x2 = col2x(end, radius) painter.drawLine(x1, dot_y + y1, x2, dot_y + y2) penradius = 1 pencolor = Qt.black dot_y = (h // 2) - radius // 2 # draw a dot for the revision if currentRev: # enlarge dot for the current revision delta = 1 radius += 2 * delta dot_y -= delta dot_x -= delta penradius = 3 painter.setBrush(dotColor) pen = QPen(pencolor) pen.setWidth(penradius) painter.setPen(pen) if closed: painter.drawRect(dot_x - 2, dot_y + 1, radius + 4, radius - 2) elif self.commandMode in ("incoming", "outgoing"): offset = radius // 2 painter.drawConvexPolygon( QPoint(dot_x + offset, dot_y), QPoint(dot_x, dot_y + offset), QPoint(dot_x + offset, dot_y + 2 * offset), QPoint(dot_x + 2 * offset, dot_y + offset) ) else: painter.drawEllipse(dot_x, dot_y, radius, radius) painter.end() return QIcon(pix) def __getParents(self, rev): """ Private method to get the parents of the currently viewed file/directory. @param rev revision number to get parents for (string) @return list of parent revisions (list of integers) """ errMsg = "" parents = [-1] if int(rev) > 0: args = self.vcs.initCommand("parents") if self.commandMode == "incoming": if self.__bundle: args.append("--repository") args.append(self.__bundle) elif self.vcs.bundleFile and \ os.path.exists(self.vcs.bundleFile): args.append("--repository") args.append(self.vcs.bundleFile) args.append("--template") args.append("{rev}\n") args.append("-r") args.append(rev) if not self.projectMode: args.append(self.__filename) output = "" if self.__hgClient: output, errMsg = self.__hgClient.runcommand(args) else: process = QProcess() process.setWorkingDirectory(self.repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') else: if not finished: errMsg = self.tr( "The hg process did not finish within 30s.") else: errMsg = self.tr("Could not start the hg executable.") if errMsg: E5MessageBox.critical( self, self.tr("Mercurial Error"), errMsg) if output: parents = [int(p) for p in output.strip().splitlines()] return parents def __identifyProject(self): """ Private method to determine the revision of the project directory. """ errMsg = "" args = self.vcs.initCommand("identify") args.append("-nb") output = "" if self.__hgClient: output, errMsg = self.__hgClient.runcommand(args) else: process = QProcess() process.setWorkingDirectory(self.repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') else: if not finished: errMsg = self.tr( "The hg process did not finish within 30s.") else: errMsg = self.tr("Could not start the hg executable.") if errMsg: E5MessageBox.critical( self, self.tr("Mercurial Error"), errMsg) if output: outputList = output.strip().split(None, 1) if len(outputList) == 2: self.__projectRevision = outputList[0].strip() if self.__projectRevision.endswith("+"): self.__projectRevision = self.__projectRevision[:-1] self.__projectBranch = outputList[1].strip() def __getClosedBranches(self): """ Private method to get the list of closed branches. """ self.__closedBranchesRevs = [] errMsg = "" args = self.vcs.initCommand("branches") args.append("--closed") output = "" if self.__hgClient: output, errMsg = self.__hgClient.runcommand(args) else: process = QProcess() process.setWorkingDirectory(self.repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') else: if not finished: errMsg = self.tr( "The hg process did not finish within 30s.") else: errMsg = self.tr("Could not start the hg executable.") if errMsg: E5MessageBox.critical( self, self.tr("Mercurial Error"), errMsg) if output: for line in output.splitlines(): if line.strip().endswith("(closed)"): parts = line.split() self.__closedBranchesRevs.append( parts[-2].split(":", 1)[0]) def __generateLogItem(self, author, date, message, revision, changedPaths, parents, branches, tags, phase, bookmarks=None): """ Private method to generate a log tree entry. @param author author info (string) @param date date info (string) @param message text of the log message (list of strings) @param revision revision info (string) @param changedPaths list of dictionary objects containing info about the changed files/directories @param parents list of parent revisions (list of integers) @param branches list of branches (list of strings) @param tags list of tags (string) @param phase phase of the entry (string) @param bookmarks list of bookmarks (string) @return reference to the generated item (QTreeWidgetItem) """ msg = [] for line in message: msg.append(line.strip()) rev, node = revision.split(":") if rev in self.__closedBranchesRevs: closedStr = self.ClosedIndicator else: closedStr = "" msgtxt = msg[0] if len(msgtxt) > 30: msgtxt = "{0}...".format(msgtxt[:30]) columnLabels = [ "", branches[0] + closedStr, "{0:>7}:{1}".format(rev, node), phase, author, date, msgtxt, ", ".join(tags), ] if bookmarks is not None: columnLabels.append(", ".join(bookmarks)) itm = QTreeWidgetItem(self.logTree, columnLabels) itm.setForeground(self.BranchColumn, QBrush(QColor(self.__branchColor(branches[0])))) if not self.projectMode: parents = self.__getParents(rev) if not parents: parents = [int(rev) - 1] column, color, edges = self.__generateEdges(int(rev), parents) itm.setData(0, self.__messageRole, message) itm.setData(0, self.__changesRole, changedPaths) itm.setData(0, self.__edgesRole, edges) if parents == [-1]: itm.setData(0, self.__parentsRole, []) else: itm.setData(0, self.__parentsRole, parents) if self.logTree.topLevelItemCount() > 1: topedges = \ self.logTree.topLevelItem( self.logTree.indexOfTopLevelItem(itm) - 1)\ .data(0, self.__edgesRole) else: topedges = None icon = self.__generateIcon(column, color, edges, topedges, QColor(self.__branchColor(branches[0])), rev == self.__projectRevision, rev in self.__closedBranchesRevs) itm.setIcon(0, icon) try: self.__lastRev = int(revision.split(":")[0]) except ValueError: self.__lastRev = 0 return itm def __generateFileItem(self, action, path, copyfrom): """ Private method to generate a changed files tree entry. @param action indicator for the change action ("A", "D" or "M") @param path path of the file in the repository (string) @param copyfrom path the file was copied from (string) @return reference to the generated item (QTreeWidgetItem) """ itm = QTreeWidgetItem(self.filesTree, [ self.flags[action], path, copyfrom, ]) return itm def __getLogEntries(self, startRev=None): """ Private method to retrieve log entries from the repository. @param startRev revision number to start from (integer, string) """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.buf = [] self.cancelled = False self.errors.clear() self.intercept = False preargs = [] args = self.vcs.initCommand(self.commandMode) args.append('--verbose') if self.commandMode not in ("incoming", "outgoing"): args.append('--limit') args.append(str(self.limitSpinBox.value())) if self.commandMode in ("incoming", "outgoing"): args.append("--newest-first") if self.vcs.hasSubrepositories(): args.append("--subrepos") if startRev is not None: args.append('--rev') args.append('{0}:0'.format(startRev)) if not self.projectMode and \ not self.fname == "." and \ not self.stopCheckBox.isChecked(): args.append('--follow') if self.commandMode == "log": args.append('--copies') if self.vcs.version >= (3, 0): args.append('--template') args.append(os.path.join(os.path.dirname(__file__), "templates", "logBrowserBookmarkPhase.tmpl")) else: args.append('--style') if self.vcs.version >= (2, 1): args.append(os.path.join(os.path.dirname(__file__), "styles", "logBrowserBookmarkPhase.style")) else: args.append(os.path.join(os.path.dirname(__file__), "styles", "logBrowserBookmark.style")) if self.commandMode == "incoming": if self.__bundle: args.append(self.__bundle) elif not self.vcs.hasSubrepositories(): project = e5App().getObject("Project") self.vcs.bundleFile = os.path.join( project.getProjectManagementDir(), "hg-bundle.hg") if os.path.exists(self.vcs.bundleFile): os.remove(self.vcs.bundleFile) preargs = args[:] preargs.append("--quiet") preargs.append('--bundle') preargs.append(self.vcs.bundleFile) args.append(self.vcs.bundleFile) if not self.projectMode: args.append(self.__filename) if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() if preargs: out, err = self.__hgClient.runcommand(preargs) else: err = "" if err: self.__showError(err) elif self.commandMode != "incoming" or \ (self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile)) or \ self.__bundle: out, err = self.__hgClient.runcommand(args) self.buf = out.splitlines(True) if err: self.__showError(err) self.__processBuffer() self.__finish() else: self.process.kill() self.process.setWorkingDirectory(self.repodir) self.inputGroup.setEnabled(True) self.inputGroup.show() if preargs: process = QProcess() process.setWorkingDirectory(self.repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: process.waitForFinished(30000) if self.commandMode != "incoming" or \ (self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile)) or \ self.__bundle: self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.__finish() def start(self, fn, bundle=None, isFile=False): """ Public slot to start the hg log command. @param fn filename to show the log for (string) @keyparam bundle name of a bundle file (string) @keyparam isFile flag indicating log for a file is to be shown (boolean) """ self.__bundle = bundle self.__isFile = isFile self.sbsCheckBox.setEnabled(isFile) self.sbsCheckBox.setVisible(isFile) self.errorGroup.hide() QApplication.processEvents() self.__initData() self.__filename = fn self.dname, self.fname = self.vcs.splitPath(fn) # find the root of the repo self.repodir = self.dname while not os.path.isdir(os.path.join(self.repodir, self.vcs.adminDir)): self.repodir = os.path.dirname(self.repodir) if os.path.splitdrive(self.repodir)[1] == os.sep: return self.projectMode = (self.fname == "." and self.dname == self.repodir) self.stopCheckBox.setDisabled(self.projectMode or self.fname == ".") self.activateWindow() self.raise_() self.logTree.clear() self.__started = True self.__identifyProject() self.__getClosedBranches() self.__getLogEntries() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__processBuffer() self.__finish() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.refreshButton.setEnabled(True) def __modifyForLargeFiles(self, filename): """ Private method to convert the displayed file name for a large file. @param filename file name to be processed (string) @return processed file name (string) """ if filename.startswith((self.LargefilesCacheL, self.LargefilesCacheW)): return self.tr("{0} (large file)").format( self.PathSeparatorRe.split(filename, 1)[1]) else: return filename def __processBuffer(self): """ Private method to process the buffered output of the hg log command. """ noEntries = 0 log = {"message": [], "bookmarks": None, "phase": ""} changedPaths = [] initialText = True fileCopies = {} for s in self.buf: if s != "@@@\n": try: key, value = s.split("|", 1) except ValueError: key = "" value = s if key == "change": initialText = False log["revision"] = value.strip() elif key == "user": log["author"] = value.strip() elif key == "parents": log["parents"] = \ [int(x.split(":", 1)[0]) for x in value.strip().split()] elif key == "date": log["date"] = " ".join(value.strip().split()[:2]) elif key == "description": log["message"].append(value.strip()) elif key == "file_adds": if value.strip(): for f in value.strip().split(", "): if f in fileCopies: changedPaths.append({ "action": "A", "path": self.__modifyForLargeFiles(f), "copyfrom": self.__modifyForLargeFiles( fileCopies[f]), }) else: changedPaths.append({ "action": "A", "path": self.__modifyForLargeFiles(f), "copyfrom": "", }) elif key == "files_mods": if value.strip(): for f in value.strip().split(", "): changedPaths.append({ "action": "M", "path": self.__modifyForLargeFiles(f), "copyfrom": "", }) elif key == "file_dels": if value.strip(): for f in value.strip().split(", "): changedPaths.append({ "action": "D", "path": self.__modifyForLargeFiles(f), "copyfrom": "", }) elif key == "file_copies": if value.strip(): for entry in value.strip().split(", "): newName, oldName = entry[:-1].split(" (") fileCopies[newName] = oldName elif key == "branches": if value.strip(): log["branches"] = value.strip().split(", ") else: log["branches"] = ["default"] elif key == "tags": log["tags"] = value.strip().split(", ") elif key == "bookmarks": log["bookmarks"] = value.strip().split(", ") elif key == "phase": log["phase"] = value.strip() else: if initialText: continue if value.strip(): log["message"].append(value.strip()) else: if len(log) > 1: self.__generateLogItem( log["author"], log["date"], log["message"], log["revision"], changedPaths, log["parents"], log["branches"], log["tags"], log["phase"], log["bookmarks"]) dt = QDate.fromString(log["date"], Qt.ISODate) if not self.__maxDate.isValid() and \ not self.__minDate.isValid(): self.__maxDate = dt self.__minDate = dt else: if self.__maxDate < dt: self.__maxDate = dt if self.__minDate > dt: self.__minDate = dt noEntries += 1 log = {"message": [], "bookmarks": None, "phase": ""} changedPaths = [] fileCopies = {} self.__resizeColumnsLog() if self.__started: self.logTree.setCurrentItem(self.logTree.topLevelItem(0)) self.__started = False if self.commandMode in ("incoming", "outgoing"): self.commandMode = "log" # switch to log mode if self.__lastRev > 0: self.nextButton.setEnabled(True) self.limitSpinBox.setEnabled(True) else: if noEntries < self.limitSpinBox.value() and not self.cancelled: self.nextButton.setEnabled(False) self.limitSpinBox.setEnabled(False) # update the log filters self.__filterLogsEnabled = False self.fromDate.setMinimumDate(self.__minDate) self.fromDate.setMaximumDate(self.__maxDate) self.fromDate.setDate(self.__minDate) self.toDate.setMinimumDate(self.__minDate) self.toDate.setMaximumDate(self.__maxDate) self.toDate.setDate(self.__maxDate) branchFilter = self.branchCombo.currentText() if not branchFilter: branchFilter = self.__allBranchesFilter self.branchCombo.clear() self.branchCombo.addItems( [self.__allBranchesFilter] + sorted(self.__branchColors.keys())) self.branchCombo.setCurrentIndex( self.branchCombo.findText(branchFilter)) self.__filterLogsEnabled = True self.__filterLogs() self.__updateDiffButtons() self.__updateToolMenuActions() # restore current item if self.__currentRevision: items = self.logTree.findItems( self.__currentRevision, Qt.MatchExactly, self.RevisionColumn) if items: self.logTree.setCurrentItem(items[0]) self.__currentRevision = "" def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process and inserts it into a buffer. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): line = str(self.process.readLine(), self.vcs.getEncoding(), 'replace') self.buf.append(line) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def __diffRevisions(self, rev1, rev2): """ Private method to do a diff of two revisions. @param rev1 first revision number (integer) @param rev2 second revision number (integer) """ if self.sbsCheckBox.isEnabled() and self.sbsCheckBox.isChecked(): self.vcs.hgSbsDiff(self.__filename, revisions=(str(rev1), str(rev2))) else: if self.diff is None: from .HgDiffDialog import HgDiffDialog self.diff = HgDiffDialog(self.vcs) self.diff.show() self.diff.raise_() self.diff.start(self.__filename, [rev1, rev2], self.__bundle) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.cancelled = True if self.__hgClient: self.__hgClient.cancel() else: self.__finish() elif button == self.refreshButton: self.on_refreshButton_clicked() def __updateDiffButtons(self): """ Private slot to update the enabled status of the diff buttons. """ selectionLength = len(self.logTree.selectedItems()) if selectionLength <= 1: current = self.logTree.currentItem() if current is None: self.diffP1Button.setEnabled(False) self.diffP2Button.setEnabled(False) else: parents = current.data(0, self.__parentsRole) self.diffP1Button.setEnabled(len(parents) > 0) self.diffP2Button.setEnabled(len(parents) > 1) self.diffRevisionsButton.setEnabled(False) elif selectionLength == 2: self.diffP1Button.setEnabled(False) self.diffP2Button.setEnabled(False) self.diffRevisionsButton.setEnabled(True) else: self.diffP1Button.setEnabled(False) self.diffP2Button.setEnabled(False) self.diffRevisionsButton.setEnabled(False) def __updateToolMenuActions(self): """ Private slot to update the status of the tool menu actions and the tool menu button. """ if self.initialCommandMode == "log" and self.projectMode: if self.__phaseAct is not None: # step 1: count entries with changeable phases secret = 0 draft = 0 public = 0 for itm in self.logTree.selectedItems(): phase = itm.text(self.PhaseColumn) if phase == "draft": draft += 1 elif phase == "secret": secret += 1 else: public += 1 # step 2: set the status of the phase button if public == 0 and \ ((secret > 0 and draft == 0) or (secret == 0 and draft > 0)): self.__phaseAct.setEnabled(True) else: self.__phaseAct.setEnabled(False) if self.__graftAct is not None: # step 1: count selected entries not belonging to the # current branch otherBranches = 0 for itm in self.logTree.selectedItems(): branch = itm.text(self.BranchColumn) if branch != self.__projectBranch: otherBranches += 1 # step 2: set the status of the graft action self.__graftAct.setEnabled(otherBranches > 0) self.__tagAct.setEnabled(len(self.logTree.selectedItems()) == 1) self.__switchAct.setEnabled(len(self.logTree.selectedItems()) == 1) if self.__lfPullAct is not None: if self.vcs.isExtensionActive("largefiles"): self.__lfPullAct.setEnabled(bool( self.logTree.selectedItems())) else: self.__lfPullAct.setEnabled(False) self.actionsButton.setEnabled(True) else: self.actionsButton.setEnabled(False) def __updateGui(self, itm): """ Private slot to update GUI elements except tool menu actions. @param itm reference to the item the update should be based on (QTreeWidgetItem) """ self.detailsEdit.clear() self.messageEdit.clear() self.filesTree.clear() if itm is not None: self.detailsEdit.setHtml(self.__detailsTemplate.format( itm.text(self.RevisionColumn), itm.text(self.DateColumn), itm.text(self.AuthorColumn), itm.text(self.BranchColumn).replace( self.ClosedIndicator, ""), itm.text(self.TagsColumn), itm.text(self.BookmarksColumn), ", ".join( [str(x) for x in itm.data(0, self.__parentsRole)] ), )) for line in itm.data(0, self.__messageRole): self.messageEdit.append(line.strip()) changes = itm.data(0, self.__changesRole) if len(changes) > 0: for change in changes: self.__generateFileItem( change["action"], change["path"], change["copyfrom"]) self.__resizeColumnsFiles() self.__resortFiles() @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_logTree_currentItemChanged(self, current, previous): """ Private slot called, when the current item of the log tree changes. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the old current item (QTreeWidgetItem) """ self.__updateGui(current) self.__updateDiffButtons() self.__updateToolMenuActions() @pyqtSlot() def on_logTree_itemSelectionChanged(self): """ Private slot called, when the selection has changed. """ if len(self.logTree.selectedItems()) == 1: self.__updateGui(self.logTree.selectedItems()[0]) self.__updateDiffButtons() self.__updateToolMenuActions() @pyqtSlot() def on_nextButton_clicked(self): """ Private slot to handle the Next button. """ if self.__lastRev > 0: self.__getLogEntries(self.__lastRev - 1) @pyqtSlot() def on_diffP1Button_clicked(self): """ Private slot to handle the Diff to Parent 1 button. """ if len(self.logTree.selectedItems()): itm = self.logTree.selectedItems()[0] else: itm = self.logTree.currentItem() if itm is None: self.diffP1Button.setEnabled(False) return rev2 = int(itm.text(self.RevisionColumn).split(":")[0]) rev1 = itm.data(0, self.__parentsRole)[0] if rev1 < 0: self.diffP1Button.setEnabled(False) return self.__diffRevisions(rev1, rev2) @pyqtSlot() def on_diffP2Button_clicked(self): """ Private slot to handle the Diff to Parent 2 button. """ if len(self.logTree.selectedItems()): itm = self.logTree.selectedItems()[0] else: itm = self.logTree.currentItem() if itm is None: self.diffP2Button.setEnabled(False) return rev2 = int(itm.text(self.RevisionColumn).split(":")[0]) rev1 = itm.data(0, self.__parentsRole)[1] if rev1 < 0: self.diffP2Button.setEnabled(False) return self.__diffRevisions(rev1, rev2) @pyqtSlot() def on_diffRevisionsButton_clicked(self): """ Private slot to handle the Compare Revisions button. """ items = self.logTree.selectedItems() rev2 = int(items[0].text(self.RevisionColumn).split(":")[0]) rev1 = int(items[1].text(self.RevisionColumn).split(":")[0]) self.__diffRevisions(min(rev1, rev2), max(rev1, rev2)) @pyqtSlot(QDate) def on_fromDate_dateChanged(self, date): """ Private slot called, when the from date changes. @param date new date (QDate) """ self.__filterLogs() @pyqtSlot(QDate) def on_toDate_dateChanged(self, date): """ Private slot called, when the from date changes. @param date new date (QDate) """ self.__filterLogs() @pyqtSlot(str) def on_branchCombo_activated(self, txt): """ Private slot called, when a new branch is selected. @param txt text of the selected branch (string) """ self.__filterLogs() @pyqtSlot(str) def on_fieldCombo_activated(self, txt): """ Private slot called, when a new filter field is selected. @param txt text of the selected field (string) """ self.__filterLogs() @pyqtSlot(str) def on_rxEdit_textChanged(self, txt): """ Private slot called, when a filter expression is entered. @param txt filter expression (string) """ self.__filterLogs() def __filterLogs(self): """ Private method to filter the log entries. """ if self.__filterLogsEnabled: from_ = self.fromDate.date().toString("yyyy-MM-dd") to_ = self.toDate.date().addDays(1).toString("yyyy-MM-dd") branch = self.branchCombo.currentText() closedBranch = branch + '--' txt = self.fieldCombo.currentText() if txt == self.tr("Author"): fieldIndex = self.AuthorColumn searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive) elif txt == self.tr("Revision"): fieldIndex = self.RevisionColumn txt = self.rxEdit.text() if txt.startswith("^"): searchRx = QRegExp("^\s*{0}".format(txt[1:]), Qt.CaseInsensitive) else: searchRx = QRegExp(txt, Qt.CaseInsensitive) else: fieldIndex = self.MessageColumn searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive) currentItem = self.logTree.currentItem() for topIndex in range(self.logTree.topLevelItemCount()): topItem = self.logTree.topLevelItem(topIndex) if topItem.text(self.DateColumn) <= to_ and \ topItem.text(self.DateColumn) >= from_ and \ (branch == self.__allBranchesFilter or topItem.text(self.BranchColumn) in [branch, closedBranch]) and \ searchRx.indexIn(topItem.text(fieldIndex)) > -1: topItem.setHidden(False) if topItem is currentItem: self.on_logTree_currentItemChanged(topItem, None) else: topItem.setHidden(True) if topItem is currentItem: self.messageEdit.clear() self.filesTree.clear() @pyqtSlot(bool) def on_stopCheckBox_clicked(self, checked): """ Private slot called, when the stop on copy/move checkbox is clicked. @param checked flag indicating the state of the check box (boolean) """ self.vcs.getPlugin().setPreferences("StopLogOnCopy", self.stopCheckBox.isChecked()) self.nextButton.setEnabled(True) self.limitSpinBox.setEnabled(True) @pyqtSlot() def on_refreshButton_clicked(self): """ Private slot to refresh the log. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.inputGroup.setEnabled(True) self.inputGroup.show() self.refreshButton.setEnabled(False) # save the current items commit ID itm = self.logTree.currentItem() if itm is not None: self.__currentRevision = itm.text(self.RevisionColumn) else: self.__currentRevision = "" if self.initialCommandMode in ("incoming", "outgoing"): self.nextButton.setEnabled(False) self.limitSpinBox.setEnabled(False) else: self.nextButton.setEnabled(True) self.limitSpinBox.setEnabled(True) self.commandMode = self.initialCommandMode self.start(self.__filename, isFile=self.__isFile) def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the mercurial process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.errorGroup.show() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgLogBrowserDialog, self).keyPressEvent(evt) @pyqtSlot() def __phaseActTriggered(self): """ Private slot to handle the Change Phase action. """ currentPhase = self.logTree.selectedItems()[0].text(self.PhaseColumn) revs = [] for itm in self.logTree.selectedItems(): if itm.text(self.PhaseColumn) == currentPhase: revs.append( itm.text(self.RevisionColumn).split(":")[0].strip()) if not revs: self.__phaseAct.setEnabled(False) return if currentPhase == "draft": newPhase = "secret" data = (revs, "s", True) else: newPhase = "draft" data = (revs, "d", False) res = self.vcs.hgPhase(self.repodir, data) if res: for itm in self.logTree.selectedItems(): itm.setText(self.PhaseColumn, newPhase) @pyqtSlot() def __graftActTriggered(self): """ Private slot to handle the Copy Changesets action. """ revs = [] for itm in self.logTree.selectedItems(): branch = itm.text(self.BranchColumn) if branch != self.__projectBranch: revs.append( itm.text(self.RevisionColumn).strip().split(":", 1)[0]) if revs: shouldReopen = self.vcs.hgGraft(self.repodir, revs) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Copy Changesets"), self.tr( """The project should be reread. Do this now?"""), yesDefault=True) if res: e5App().getObject("Project").reopenProject() return self.on_refreshButton_clicked() @pyqtSlot() def __tagActTriggered(self): """ Private slot to tag the selected revision. """ if len(self.logTree.selectedItems()) == 1: itm = self.logTree.selectedItems()[0] rev = itm.text(self.RevisionColumn).strip().split(":", 1)[0] tag = itm.text(self.TagsColumn).strip().split(", ", 1)[0] res = self.vcs.vcsTag(self.repodir, revision=rev, tagName=tag) if res: self.on_refreshButton_clicked() @pyqtSlot() def __switchActTriggered(self): """ Private slot to switch the working directory to the selected revision. """ if len(self.logTree.selectedItems()) == 1: itm = self.logTree.selectedItems()[0] rev = itm.text(self.RevisionColumn).strip().split(":", 1)[0] if rev: shouldReopen = self.vcs.vcsUpdate(self.repodir, revision=rev) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Switch"), self.tr( """The project should be reread. Do this now?"""), yesDefault=True) if res: e5App().getObject("Project").reopenProject() return self.on_refreshButton_clicked() def __lfPullActTriggered(self): """ Private slot to pull large files of selected revisions. """ revs = [] for itm in self.logTree.selectedItems(): rev = itm.text(self.RevisionColumn).strip().split(":", 1)[0] if rev: revs.append(rev) if revs: self.vcs.getExtensionObject("largefiles").hgLfPull( self.repodir, revisions=revs) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.py0000644000175000017500000001146112451233372024011 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a bundle operation. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgBundleDialog import Ui_HgBundleDialog class HgBundleDialog(QDialog, Ui_HgBundleDialog): """ Class implementing a dialog to enter the data for a bundle operation. """ def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None): """ Constructor @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param parent parent widget (QWidget) """ super(HgBundleDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.compressionCombo.addItems(["", "bzip2", "gzip", "none"]) self.tagCombo.addItems(sorted(tagsList)) self.branchCombo.addItems(["default"] + sorted(branchesList)) if bookmarksList is not None: self.bookmarkCombo.addItems(sorted(bookmarksList)) else: self.bookmarkButton.setHidden(True) self.bookmarkCombo.setHidden(True) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.multipleButton.isChecked(): enabled = self.multipleEdit.toPlainText() != "" elif self.tagButton.isChecked(): enabled = self.tagCombo.currentText() != "" elif self.branchButton.isChecked(): enabled = self.branchCombo.currentText() != "" elif self.bookmarkButton.isChecked(): enabled = self.bookmarkCombo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(bool) def on_multipleButton_toggled(self, checked): """ Private slot to handle changes of the Multiple select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tagButton_toggled(self, checked): """ Private slot to handle changes of the Tag select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branchButton_toggled(self, checked): """ Private slot to handle changes of the Branch select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmarkButton_toggled(self, checked): """ Private slot to handle changes of the Bookmark select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot() def on_multipleEdit_textChanged(self): """ Private slot to handle changes of the Multiple edit. """ self.__updateOK() @pyqtSlot(str) def on_tagCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branchCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmarkCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark combo. @param txt text of the combo (string) """ self.__updateOK() def getParameters(self): """ Public method to retrieve the bundle data. @return tuple naming the revisions, base revisions, the compression type and a flag indicating to bundle all changesets (string, string, boolean) """ if self.multipleButton.isChecked(): revs = self.multipleEdit.toPlainText().strip().splitlines() elif self.tagButton.isChecked(): revs = [self.tagCombo.currentText()] elif self.branchButton.isChecked(): revs = [self.branchCombo.currentText()] elif self.bookmarkButton.isChecked(): revs = [self.bookmarkCombo.currentText()] else: revs = [] baseRevs = self.baseRevisionsEdit.toPlainText().strip().splitlines() return (revs, baseRevs, self.compressionCombo.currentText(), self.allCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgExtensionProjectHelper.py0000644000175000017500000000477112451233372026131 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the project helper base for Mercurial extension interfaces. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject class HgExtensionProjectHelper(QObject): """ Class implementing the project helper base for Mercurial extension interfaces. Note: The methods initActions(), initMenu(mainMenu) and menuTitle() have to be reimplemented by derived classes. """ def __init__(self): """ Constructor """ super(HgExtensionProjectHelper, self).__init__() self.actions = [] self.initActions() def setObjects(self, vcsObject, projectObject): """ Public method to set references to the vcs and project objects. @param vcsObject reference to the vcs object @param projectObject reference to the project object """ self.vcs = vcsObject self.project = projectObject def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ return self.actions[:] def initActions(self): """ Public method to generate the action objects. Note: Derived class must implement this method. @exception NotImplementedError raised if the class has not been reimplemented """ raise NotImplementedError def initMenu(self, mainMenu): """ Public method to generate the extension menu. Note: Derived class must implement this method. @param mainMenu reference to the main menu (QMenu) @ireturn populated menu (QMenu) @exception NotImplementedError raised if the class has not been reimplemented """ raise NotImplementedError def menuTitle(self): """ Public method to get the menu title. Note: Derived class must implement this method. @ireturn title of the menu (string) @exception NotImplementedError raised if the class has not been reimplemented """ raise NotImplementedError def shutdown(self): """ Public method to perform shutdown actions. Note: Derived class may implement this method if needed. """ pass eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgRepoConfigDataDialog.ui0000644000175000017500000002011512304143035025377 0ustar piotrpiotr HgRepoConfigDataDialog 0 0 500 352 Mercurial Repository Configuration true Default Upstream URL: Enter the URL of the upstream repository Username: Enter user name to acces the upstream repository Password: Enter the password to acces the upstream repository QLineEdit::Password Press to show the password true Default Push Upstream URL: Enter the URL of the upstream (push) repository Username: Enter user name to acces the upstream (push) repository Password: Enter the password to acces the upstream (push) repository QLineEdit::Password Press to show the password true Large Files Minimum file size: Enter the minimum file size in MB for files to be treated as Large Files Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter MB 1 10 Qt::Horizontal 215 20 Patterns: Enter file patterns (space separated) for files to be treated as Large Files Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
defaultUrlEdit defaultUserEdit defaultPasswordEdit defaultShowPasswordButton defaultPushUrlEdit defaultPushUserEdit defaultPushPasswordEdit defaultPushShowPasswordButton lfFileSizeSpinBox lfFilePatternsEdit buttonBox buttonBox accepted() HgRepoConfigDataDialog accept() 248 254 157 274 buttonBox rejected() HgRepoConfigDataDialog reject() 316 260 286 274
eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/GpgExtension/0000755000175000017500000000000012557365404023247 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignaturesDialog.py0000644000175000017500000003163712537064320030003 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog showing signed changesets. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, QProcess, QTimer, Qt, QRegExp, \ QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, \ QTreeWidgetItem, QLineEdit from E5Gui import E5MessageBox from .Ui_HgGpgSignaturesDialog import Ui_HgGpgSignaturesDialog class HgGpgSignaturesDialog(QDialog, Ui_HgGpgSignaturesDialog): """ Class implementing a dialog showing signed changesets. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent reference to the parent widget (QWidget) """ super(HgGpgSignaturesDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = QProcess() self.vcs = vcs self.__hgClient = vcs.getClient() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path): """ Public slot to start the list command. @param path name of directory (string) """ self.errorGroup.hide() self.intercept = False self.activateWindow() self.__path = path dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("sigs") if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.process = None if self.signaturesList.topLevelItemCount() == 0: # no patches present self.__generateItem("", "", self.tr("no signatures found")) self.__resizeColumns() self.__resort() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __resort(self): """ Private method to resort the tree. """ self.signaturesList.sortItems( self.signaturesList.sortColumn(), self.signaturesList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.signaturesList.header().resizeSections( QHeaderView.ResizeToContents) self.signaturesList.header().setStretchLastSection(True) def __generateItem(self, revision, changeset, signature): """ Private method to generate a patch item in the list of patches. @param revision revision number (string) @param changeset changeset of the bookmark (string) @param signature signature of the changeset (string) """ if revision == "" and changeset == "": QTreeWidgetItem(self.signaturesList, [signature]) else: revString = "{0:>7}:{1}".format(revision, changeset) topItems = self.signaturesList.findItems( revString, Qt.MatchExactly) if len(topItems) == 0: # first signature for this changeset topItm = QTreeWidgetItem(self.signaturesList, [ "{0:>7}:{1}".format(revision, changeset)]) topItm.setExpanded(True) font = topItm.font(0) font.setBold(True) topItm.setFont(0, font) else: topItm = topItems[0] QTreeWidgetItem(topItm, [signature]) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.vcs.getEncoding(), 'replace').strip() self.__processOutputLine(s) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ li = line.split() if li[-1][0] in "1234567890": # last element is a rev:changeset rev, changeset = li[-1].split(":", 1) del li[-1] signature = " ".join(li) self.__generateItem(rev, changeset, signature) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() @pyqtSlot() def on_signaturesList_itemSelectionChanged(self): """ Private slot handling changes of the selection. """ selectedItems = self.signaturesList.selectedItems() if len(selectedItems) == 1 and \ self.signaturesList.indexOfTopLevelItem(selectedItems[0]) != -1: self.verifyButton.setEnabled(True) else: self.verifyButton.setEnabled(False) @pyqtSlot() def on_verifyButton_clicked(self): """ Private slot to verify the signatures of the selected revision. """ rev = self.signaturesList.selectedItems()[0].text(0)\ .split(":")[0].strip() self.vcs.getExtensionObject("gpg")\ .hgGpgVerifySignatures(self.__path, rev) @pyqtSlot(str) def on_categoryCombo_activated(self, txt): """ Private slot called, when a new filter category is selected. @param txt text of the selected category (string) """ self.__filterSignatures() @pyqtSlot(str) def on_rxEdit_textChanged(self, txt): """ Private slot called, when a filter expression is entered. @param txt filter expression (string) """ self.__filterSignatures() def __filterSignatures(self): """ Private method to filter the log entries. """ searchRxText = self.rxEdit.text() filterTop = self.categoryCombo.currentText() == self.tr("Revision") if filterTop and searchRxText.startswith("^"): searchRx = QRegExp( "^\s*{0}".format(searchRxText[1:]), Qt.CaseInsensitive) else: searchRx = QRegExp(searchRxText, Qt.CaseInsensitive) for topIndex in range(self.signaturesList.topLevelItemCount()): topLevelItem = self.signaturesList.topLevelItem(topIndex) if filterTop: topLevelItem.setHidden( searchRx.indexIn(topLevelItem.text(0)) == -1) else: visibleChildren = topLevelItem.childCount() for childIndex in range(topLevelItem.childCount()): childItem = topLevelItem.child(childIndex) if searchRx.indexIn(childItem.text(0)) == -1: childItem.setHidden(True) visibleChildren -= 1 else: childItem.setHidden(False) topLevelItem.setHidden(visibleChildren == 0) def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgGpgSignaturesDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignaturesDialog.ui0000644000175000017500000001520612060166053027757 0ustar piotrpiotr HgGpgSignaturesDialog 0 0 700 600 Signed Changesets true Qt::Horizontal 40 20 Qt::Horizontal 40 20 Select the category to filter on Revision Signature Enter the regular expression to filter on 0 3 true false true 1 false Press to verify the signatures of the selected revision &Verify... Qt::Horizontal 40 20 0 1 Errors <b>Mercurial errors</b><p>This shows possible error messages.</p> true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
categoryCombo rxEdit signaturesList verifyButton errors input passwordCheckBox sendButton buttonBox
eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/GpgExtension/ProjectHelper.py0000644000175000017500000000776112451233372026371 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the gpg extension project helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui.E5Action import E5Action from ..HgExtensionProjectHelper import HgExtensionProjectHelper import UI.PixmapCache class GpgProjectHelper(HgExtensionProjectHelper): """ Class implementing the gpg extension project helper. """ def __init__(self): """ Constructor """ super(GpgProjectHelper, self).__init__() def initActions(self): """ Public method to generate the action objects. """ self.hgGpgListAct = E5Action( self.tr('List Signed Changesets'), UI.PixmapCache.getIcon("changesetSignList.png"), self.tr('List Signed Changesets...'), 0, 0, self, 'mercurial_gpg_list') self.hgGpgListAct.setStatusTip(self.tr( 'List signed changesets' )) self.hgGpgListAct.setWhatsThis(self.tr( """List Signed Changesets""" """

This opens a dialog listing all signed changesets.

""" )) self.hgGpgListAct.triggered.connect(self.__hgGpgSignatures) self.actions.append(self.hgGpgListAct) self.hgGpgVerifyAct = E5Action( self.tr('Verify Signatures'), UI.PixmapCache.getIcon("changesetSignVerify.png"), self.tr('Verify Signatures'), 0, 0, self, 'mercurial_gpg_verify') self.hgGpgVerifyAct.setStatusTip(self.tr( 'Verify all signatures there may be for a particular revision' )) self.hgGpgVerifyAct.setWhatsThis(self.tr( """Verify Signatures""" """

This verifies all signatures there may be for a particular""" """ revision.

""" )) self.hgGpgVerifyAct.triggered.connect(self.__hgGpgVerifySignatures) self.actions.append(self.hgGpgVerifyAct) self.hgGpgSignAct = E5Action( self.tr('Sign Revision'), UI.PixmapCache.getIcon("changesetSign.png"), self.tr('Sign Revision'), 0, 0, self, 'mercurial_gpg_sign') self.hgGpgSignAct.setStatusTip(self.tr( 'Add a signature for a selected revision' )) self.hgGpgSignAct.setWhatsThis(self.tr( """Sign Revision""" """

This adds a signature for a selected revision.

""" )) self.hgGpgSignAct.triggered.connect(self.__hgGpgSign) self.actions.append(self.hgGpgSignAct) def initMenu(self, mainMenu): """ Public method to generate the extension menu. @param mainMenu reference to the main menu (QMenu) @return populated menu (QMenu) """ menu = QMenu(self.menuTitle(), mainMenu) menu.setIcon(UI.PixmapCache.getIcon("changesetSign.png")) menu.setTearOffEnabled(True) menu.addAction(self.hgGpgListAct) menu.addAction(self.hgGpgVerifyAct) menu.addAction(self.hgGpgSignAct) return menu def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("GPG") def __hgGpgSignatures(self): """ Private slot used to list all signed changesets. """ self.vcs.getExtensionObject("gpg")\ .hgGpgSignatures(self.project.getProjectPath()) def __hgGpgVerifySignatures(self): """ Private slot used to verify the signatures of a revision. """ self.vcs.getExtensionObject("gpg")\ .hgGpgVerifySignatures(self.project.getProjectPath()) def __hgGpgSign(self): """ Private slot used to sign a revision. """ self.vcs.getExtensionObject("gpg")\ .hgGpgSign(self.project.getProjectPath()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/GpgExtension/__init__.py0000644000175000017500000000024612451233372025351 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Package implementing the gpg extension support interface. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignDialog.py0000644000175000017500000001206412451233372026550 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter data for signing a revision. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgGpgSignDialog import Ui_HgGpgSignDialog class HgGpgSignDialog(QDialog, Ui_HgGpgSignDialog): """ Class implementing a dialog to enter data for signing a revision. """ def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None): """ Constructor @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgGpgSignDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.tagCombo.addItems(sorted(tagsList)) self.branchCombo.addItems(["default"] + sorted(branchesList)) if bookmarksList is not None: self.bookmarkCombo.addItems(sorted(bookmarksList)) else: self.bookmarkButton.setHidden(True) self.bookmarkCombo.setHidden(True) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.idButton.isChecked(): enabled = enabled and self.idEdit.text() != "" elif self.tagButton.isChecked(): enabled = enabled and self.tagCombo.currentText() != "" elif self.branchButton.isChecked(): enabled = enabled and self.branchCombo.currentText() != "" elif self.bookmarkButton.isChecked(): enabled = enabled and self.bookmarkCombo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(bool) def on_idButton_toggled(self, checked): """ Private slot to handle changes of the ID select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tagButton_toggled(self, checked): """ Private slot to handle changes of the Tag select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branchButton_toggled(self, checked): """ Private slot to handle changes of the Branch select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmarkButton_toggled(self, checked): """ Private slot to handle changes of the Bookmark select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(str) def on_idEdit_textChanged(self, txt): """ Private slot to handle changes of the ID edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_tagCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branchCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmarkCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark combo. @param txt text of the combo (string) """ self.__updateOK() def getData(self): """ Public method to retrieve the entered data. @return tuple giving the revision, a flag indicating not to commit the signature, a commit message, an ID of the key to be used, a flag indicating a local signature and a flag indicating a forced signature (string, boolean, string, string, boolean, boolean) """ if self.numberButton.isChecked(): rev = "rev({0})".format(self.numberSpinBox.value()) elif self.idButton.isChecked(): rev = "id({0})".format(self.idEdit.text()) elif self.tagButton.isChecked(): rev = self.tagCombo.currentText() elif self.branchButton.isChecked(): rev = self.branchCombo.currentText() elif self.bookmarkButton.isChecked(): rev = self.bookmarkCombo.currentText() else: rev = "" return ( rev, self.nocommitCheckBox.isChecked(), self.messageEdit.toPlainText(), self.keyEdit.text(), self.localCheckBox.isChecked(), self.forceCheckBox.isChecked() ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/GpgExtension/gpg.py0000644000175000017500000000775612537064320024404 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the gpg extension interface. """ from __future__ import unicode_literals import os from PyQt5.QtWidgets import QDialog from ..HgExtension import HgExtension from ..HgDialog import HgDialog from ..HgRevisionSelectionDialog import HgRevisionSelectionDialog class Gpg(HgExtension): """ Class implementing the fetch extension interface. """ def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(Gpg, self).__init__(vcs) self.gpgSignaturesDialog = None def shutdown(self): """ Public method used to shutdown the fetch interface. """ if self.gpgSignaturesDialog is not None: self.gpgSignaturesDialog.close() def hgGpgSignatures(self, path): """ Public method used to list all signed changesets. @param path directory name of the project (string) """ from .HgGpgSignaturesDialog import HgGpgSignaturesDialog self.gpgSignaturesDialog = HgGpgSignaturesDialog(self.vcs) self.gpgSignaturesDialog.show() self.gpgSignaturesDialog.start(path) def hgGpgVerifySignatures(self, path, rev=None): """ Public method used to verify the signatures of a revision. @param path directory name of the project (string) @param rev revision to check (string) """ # find the root of the repo repodir = self.vcs.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if rev is None: dlg = HgRevisionSelectionDialog( self.vcs.hgGetTagsList(repodir), self.vcs.hgGetBranchesList(repodir), self.vcs.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: rev = dlg.getRevision() if rev is not None: if rev == "": rev = "tip" args = self.vcs.initCommand("sigcheck") args.append(rev) dia = HgDialog(self.tr('Verify Signatures'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgGpgSign(self, path): """ Public method used to list the available bookmarks. @param path directory name of the project (string) """ # find the root of the repo repodir = self.vcs.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgGpgSignDialog import HgGpgSignDialog dlg = HgGpgSignDialog(self.vcs.hgGetTagsList(repodir), self.vcs.hgGetBranchesList(repodir), self.vcs.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: revision, noCommit, message, keyId, local, force = dlg.getData() args = self.vcs.initCommand("sign") if noCommit: args.append("--no-commit") if message: args.append("--message") args.append(message) if keyId: args.append("--key") args.append(keyId) if local: args.append("--local") if force: args.append("--force") if revision: args.append(revision) dia = HgDialog(self.tr('Sign Revision'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignDialog.ui0000644000175000017500000002542612312353424026540 0ustar piotrpiotr HgGpgSignDialog 0 0 400 518 true Revision Select to specify a revision by number Number false Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 158 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false 0 0 Enter a tag name true Select to specify a revision by a branch Branch: false 0 0 Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select tip revision of repository Parent true Commit Message Select to not commit the signature Do Not Commit Enter a commit message (leave empty to use default) true Key-ID: Enter the ID of the key to be used Select to make the signature local Local Signature Select to sign even if the signature file is modified Force Signature Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok numberButton numberSpinBox idButton idEdit tagButton tagCombo branchButton branchCombo bookmarkButton bookmarkCombo tipButton nocommitCheckBox messageEdit keyEdit localCheckBox forceCheckBox buttonBox buttonBox accepted() HgGpgSignDialog accept() 252 271 157 274 buttonBox rejected() HgGpgSignDialog reject() 316 260 286 274 numberButton toggled(bool) numberSpinBox setEnabled(bool) 48 89 118 87 idButton toggled(bool) idEdit setEnabled(bool) 47 131 105 116 tagButton toggled(bool) tagCombo setEnabled(bool) 43 142 102 141 branchButton toggled(bool) branchCombo setEnabled(bool) 42 170 115 171 bookmarkButton toggled(bool) bookmarkCombo setEnabled(bool) 51 196 108 201 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgMultiRevisionSelectionDialog.ui0000644000175000017500000002063112313335210027232 0ustar piotrpiotr HgMultiRevisionSelectionDialog 0 0 450 338 Mercurial Revisions true Revision Select to specify a list of changesets Revisions: true Enter revisions by number, id, range or revset expression one per line true QPlainTextEdit::NoWrap Select to specify a revision by a tag Tag: false 0 0 Enter a tag name true Select to specify a revision by a branch Branch: false 0 0 Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Limit Results true false Enter number of entries to show: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 9999 Qt::Horizontal 164 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok changesetsButton changesetsEdit tagButton tagCombo branchButton branchCombo bookmarkButton bookmarkCombo limitGroup limitSpinBox buttonBox buttonBox accepted() HgMultiRevisionSelectionDialog accept() 266 319 157 223 buttonBox rejected() HgMultiRevisionSelectionDialog reject() 334 319 286 223 tagButton toggled(bool) tagCombo setEnabled(bool) 89 149 253 149 branchButton toggled(bool) branchCombo setEnabled(bool) 80 175 238 175 bookmarkButton toggled(bool) bookmarkCombo setEnabled(bool) 45 201 251 201 changesetsButton toggled(bool) changesetsEdit setEnabled(bool) 59 81 157 80 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.py0000644000175000017500000004122412461215125023445 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the hg diff command process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, QProcess, QTimer, QFileInfo, Qt from PyQt5.QtGui import QBrush, QColor, QTextCursor, QCursor from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QLineEdit, QApplication from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5Application import e5App from .Ui_HgDiffDialog import Ui_HgDiffDialog import Utilities import Preferences class HgDiffDialog(QWidget, Ui_HgDiffDialog): """ Class implementing a dialog to show the output of the hg diff command process. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(HgDiffDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Save).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.process = QProcess() self.vcs = vcs self.__hgClient = self.vcs.getClient() font = Preferences.getEditorOtherFonts("MonospacedFont") self.contents.setFontFamily(font.family()) self.contents.setFontPointSize(font.pointSize()) self.cNormalFormat = self.contents.currentCharFormat() self.cAddedFormat = self.contents.currentCharFormat() self.cAddedFormat.setBackground(QBrush(QColor(190, 237, 190))) self.cRemovedFormat = self.contents.currentCharFormat() self.cRemovedFormat.setBackground(QBrush(QColor(237, 190, 190))) self.cLineNoFormat = self.contents.currentCharFormat() self.cLineNoFormat.setBackground(QBrush(QColor(255, 220, 168))) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def __getVersionArg(self, version): """ Private method to get a hg revision argument for the given revision. @param version revision (integer or string) @return version argument (string) """ if version == "WORKING": return None else: return str(version) def start(self, fn, versions=None, bundle=None, qdiff=False): """ Public slot to start the hg diff command. @param fn filename to be diffed (string) @param versions list of versions to be diffed (list of up to 2 strings or None) @param bundle name of a bundle file (string) @param qdiff flag indicating qdiff command shall be used (boolean) """ self.errorGroup.hide() self.inputGroup.show() self.intercept = False self.filename = fn self.contents.clear() self.paras = 0 self.filesCombo.clear() if qdiff: args = self.vcs.initCommand("qdiff") self.setWindowTitle(self.tr("Patch Contents")) else: args = self.vcs.initCommand("diff") if self.vcs.hasSubrepositories(): args.append("--subrepos") if bundle: args.append('--repository') args.append(bundle) elif self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile): args.append('--repository') args.append(self.vcs.bundleFile) if versions is not None: self.raise_() self.activateWindow() rev1 = self.__getVersionArg(versions[0]) rev2 = None if len(versions) == 2: rev2 = self.__getVersionArg(versions[1]) if rev1 is not None or rev2 is not None: args.append('-r') if rev1 is not None and rev2 is not None: args.append('{0}:{1}'.format(rev1, rev2)) elif rev2 is None: args.append(rev1) elif rev1 is None: args.append(':{0}'.format(rev2)) if isinstance(fn, list): dname, fnames = self.vcs.splitPathList(fn) self.vcs.addArguments(args, fn) else: dname, fname = self.vcs.splitPath(fn) args.append(fn) self.__oldFile = "" self.__oldFileLine = -1 self.__fileSeparators = [] QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(True): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return self.process.kill() self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: QApplication.restoreOverrideCursor() self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ QApplication.restoreOverrideCursor() self.inputGroup.setEnabled(False) self.inputGroup.hide() if self.paras == 0: self.contents.setCurrentCharFormat(self.cNormalFormat) self.contents.setPlainText( self.tr('There is no difference.')) self.buttonBox.button(QDialogButtonBox.Save).setEnabled(self.paras > 0) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() self.filesCombo.addItem(self.tr(""), 0) self.filesCombo.addItem(self.tr(""), -1) for oldFile, newFile, pos in sorted(self.__fileSeparators): if oldFile != newFile: self.filesCombo.addItem( "{0}\n{1}".format(oldFile, newFile), pos) else: self.filesCombo.addItem(oldFile, pos) def __appendText(self, txt, format): """ Private method to append text to the end of the contents pane. @param txt text to insert (string) @param format text format to be used (QTextCharFormat) """ tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.setCurrentCharFormat(format) self.contents.insertPlainText(txt) def __extractFileName(self, line): """ Private method to extract the file name out of a file separator line. @param line line to be processed (string) @return extracted file name (string) """ f = line.split(None, 1)[1] f = f.rsplit(None, 6)[0] f = f.split("/", 1)[1] return f def __processFileLine(self, line): """ Private slot to process a line giving the old/new file. @param line line to be processed (string) """ if line.startswith('---'): self.__oldFileLine = self.paras self.__oldFile = self.__extractFileName(line) else: self.__fileSeparators.append( (self.__oldFile, self.__extractFileName(line), self.__oldFileLine)) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ if line.startswith("--- ") or \ line.startswith("+++ "): self.__processFileLine(line) if line.startswith('+'): format = self.cAddedFormat elif line.startswith('-'): format = self.cRemovedFormat elif line.startswith('@@'): format = self.cLineNoFormat else: format = self.cNormalFormat self.__appendText(line, format) self.paras += 1 def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): line = str(self.process.readLine(), self.vcs.getEncoding(), 'replace') self.__processOutputLine(line) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Save): self.on_saveButton_clicked() @pyqtSlot(int) def on_filesCombo_activated(self, index): """ Private slot to handle the selection of a file. @param index activated row (integer) """ para = self.filesCombo.itemData(index) if para == 0: tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() elif para == -1: tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() else: # step 1: move cursor to end tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() # step 2: move cursor to desired line tc = self.contents.textCursor() delta = tc.blockNumber() - para tc.movePosition(QTextCursor.PreviousBlock, QTextCursor.MoveAnchor, delta) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() @pyqtSlot() def on_saveButton_clicked(self): """ Private slot to handle the Save button press. It saves the diff shown in the dialog to a file in the local filesystem. """ if isinstance(self.filename, list): if len(self.filename) > 1: fname = self.vcs.splitPathList(self.filename)[0] else: dname, fname = self.vcs.splitPath(self.filename[0]) if fname != '.': fname = "{0}.diff".format(self.filename[0]) else: fname = dname else: fname = self.vcs.splitPath(self.filename)[0] fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Diff"), fname, self.tr("Patch Files (*.diff)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fname: return # user aborted ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Diff"), self.tr("

The patch file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) eol = e5App().getObject("Project").getEolString() try: f = open(fname, "w", encoding="utf-8", newline="") f.write(eol.join(self.contents.toPlainText().splitlines())) f.close() except IOError as why: E5MessageBox.critical( self, self.tr('Save Diff'), self.tr( '

The patch file {0} could not be saved.' '
Reason: {1}

') .format(fname, str(why))) def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgDiffDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py0000644000175000017500000000675412451233372026113 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to add a sub-repository. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5FileDialog, E5MessageBox import Utilities import UI.PixmapCache from .Ui_HgAddSubrepositoryDialog import Ui_HgAddSubrepositoryDialog class HgAddSubrepositoryDialog(QDialog, Ui_HgAddSubrepositoryDialog): """ Class implementing a dialog to add a sub-repository. """ def __init__(self, projectPath, parent=None): """ Constructor @param projectPath project directory name (string) @param parent reference to the parent widget (QWidget) """ super(HgAddSubrepositoryDialog, self).__init__(parent) self.setupUi(self) self.pathButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.__ok = self.buttonBox.button(QDialogButtonBox.Ok) self.__ok.setEnabled(False) self.__projectPath = projectPath self.typeCombo.addItem("Mercurial", "hg") self.typeCombo.addItem("GIT", "git") self.typeCombo.addItem("Subversion", "svn") msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __updateOk(self): """ Private slot to update the state of the OK button. """ path = self.pathEdit.text() url = self.urlEdit.text() self.__ok.setEnabled( path != "" and not os.path.isabs(path) and url != "" ) @pyqtSlot(str) def on_pathEdit_textChanged(self, p0): """ Private slot to handle the update of the path. @param p0 text of the path edit (string) """ self.__updateOk() @pyqtSlot(str) def on_urlEdit_textChanged(self, p0): """ Private slot to handle the update of the URL. @param p0 text of the URL edit (string) """ self.__updateOk() @pyqtSlot() def on_pathButton_clicked(self): """ Private slot to handle the path selection via a directory selection dialog. """ path = E5FileDialog.getExistingDirectory( self, self.tr("Add Sub-repository"), os.path.join(self.__projectPath, self.pathEdit.text()), E5FileDialog.Options(E5FileDialog.Option(0))) if path: path = Utilities.toNativeSeparators(path) if path.startswith(self.__projectPath): path = path.replace(self.__projectPath, "")[1:] self.pathEdit.setText(path) else: E5MessageBox.critical( self, self.tr("Add Sub-repository"), self.tr("""The sub-repository path must be inside""" """ the project.""")) return def getData(self): """ Public method to get the data. @return tuple containing the relative path within the project, the sub-repository type and the sub-repository URL (string, string, string) """ return ( self.pathEdit.text(), self.typeCombo.itemData(self.typeCombo.currentIndex()), self.urlEdit.text() ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/RebaseExtension/0000755000175000017500000000000012557365404023733 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/RebaseExtension/HgRebaseDialog.py0000644000175000017500000002263412451233372027103 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a rebase session. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgRebaseDialog import Ui_HgRebaseDialog class HgRebaseDialog(QDialog, Ui_HgRebaseDialog): """ Class implementing a dialog to enter the data for a rebase session. """ def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None): """ Constructor @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgRebaseDialog, self).__init__(parent) self.setupUi(self) self.tag1Combo.addItems(sorted(tagsList)) self.tag2Combo.addItems(sorted(tagsList)) self.branch1Combo.addItems(["default"] + sorted(branchesList)) self.branch2Combo.addItems(["default"] + sorted(branchesList)) if bookmarksList is not None: self.bookmark1Combo.addItems(sorted(bookmarksList)) self.bookmark2Combo.addItems(sorted(bookmarksList)) else: self.bookmark1Button.setHidden(True) self.bookmark1Combo.setHidden(True) self.bookmark2Button.setHidden(True) self.bookmark2Combo.setHidden(True) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if not self.parentButton.isChecked(): if self.id1Button.isChecked(): enabled = enabled and self.id1Edit.text() != "" elif self.tag1Button.isChecked(): enabled = enabled and self.tag1Combo.currentText() != "" elif self.branch1Button.isChecked(): enabled = enabled and self.branch1Combo.currentText() != "" elif self.bookmark1Button.isChecked(): enabled = enabled and self.bookmark1Combo.currentText() != "" if self.id2Button.isChecked(): enabled = enabled and self.id2Edit.text() != "" elif self.tag2Button.isChecked(): enabled = enabled and self.tag2Combo.currentText() != "" elif self.branch2Button.isChecked(): enabled = enabled and self.branch2Combo.currentText() != "" elif self.bookmark2Button.isChecked(): enabled = enabled and self.bookmark2Combo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(bool) def on_id1Button_toggled(self, checked): """ Private slot to handle changes of the ID1 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_id2Button_toggled(self, checked): """ Private slot to handle changes of the ID2 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tag1Button_toggled(self, checked): """ Private slot to handle changes of the Tag1 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tag2Button_toggled(self, checked): """ Private slot to handle changes of the Tag2 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branch1Button_toggled(self, checked): """ Private slot to handle changes of the Branch1 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branch2Button_toggled(self, checked): """ Private slot to handle changes of the Branch2 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmark1Button_toggled(self, checked): """ Private slot to handle changes of the Bookmark1 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmark2Button_toggled(self, checked): """ Private slot to handle changes of the Bookmark2 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(str) def on_id1Edit_textChanged(self, txt): """ Private slot to handle changes of the ID1 edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_id2Edit_textChanged(self, txt): """ Private slot to handle changes of the ID2 edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_tag1Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag1 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_tag2Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag2 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branch1Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch1 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branch2Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch2 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmark1Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark1 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmark2Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark2 combo. @param txt text of the combo (string) """ self.__updateOK() def __getRevision(self, no): """ Private method to generate the revision. @param no revision number to generate (1 or 2) @return revision (string) """ if no == 1: numberButton = self.number1Button numberSpinBox = self.number1SpinBox idButton = self.id1Button idEdit = self.id1Edit tagButton = self.tag1Button tagCombo = self.tag1Combo branchButton = self.branch1Button branchCombo = self.branch1Combo bookmarkButton = self.bookmark1Button bookmarkCombo = self.bookmark1Combo tipButton = None else: numberButton = self.number2Button numberSpinBox = self.number2SpinBox idButton = self.id2Button idEdit = self.id2Edit tagButton = self.tag2Button tagCombo = self.tag2Combo branchButton = self.branch2Button branchCombo = self.branch2Combo bookmarkButton = self.bookmark2Button bookmarkCombo = self.bookmark2Combo tipButton = self.tip2Button if numberButton.isChecked(): return "rev({0})".format(numberSpinBox.value()) elif idButton.isChecked(): return "id({0})".format(idEdit.text()) elif tagButton.isChecked(): return tagCombo.currentText() elif branchButton.isChecked(): return branchCombo.currentText() elif bookmarkButton.isChecked(): return bookmarkCombo.currentText() elif tipButton and tipButton.isChecked(): return "" def getData(self): """ Public method to retrieve the data for the rebase session. @return tuple with a source indicator of "S" or "B", the source revision, the destination revision, a flag indicating to collapse, a flag indicating to keep the original changesets, a flag indicating to keep the original branch name and a flag indicating to detach the source (string, string, string, boolean, boolean, boolean, boolean) """ if self.sourceButton.isChecked(): indicator = "S" elif self.baseButton.isChecked(): indicator = "B" else: indicator = "" if indicator: rev1 = self.__getRevision(1) else: rev1 = "" return ( indicator, rev1, self.__getRevision(2), self.collapseCheckBox.isChecked(), self.keepChangesetsCheckBox.isChecked(), self.keepBranchCheckBox.isChecked(), self.detachCheckBox.isChecked() ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/RebaseExtension/HgRebaseDialog.ui0000644000175000017500000004671312312353424027071 0ustar piotrpiotr HgRebaseDialog 0 0 650 394 Rebase Changesets true Source / Base Revision Select to use the parent of the working directory as the base Use &Parent as Base true Select to use a revision as the source &Source Revision Select to use a revision as the base &Base Revision false &Revision Select to specify a revision by number Number true Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 40 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false Enter a tag name true Select to specify a revision by a branch Branch: false Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Qt::Vertical 20 18 &Destination Revision Select to specify a revision by number Number false Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 40 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false Enter a tag name true Select to specify a revision by a branch Branch: false Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select tip revision of repository Current branch tip true Select to collapse the rebased changesets Collapse Changesets Select to keep the original changesets Keep Original Changesets Select to keep the original branch names Keep Original Branch Name Select to detach the source from its original branch Detach Source Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource parentButton sourceButton baseButton number1Button number1SpinBox id1Button id1Edit tag1Button tag1Combo branch1Button branch1Combo bookmark1Button bookmark1Combo number2Button number2SpinBox id2Button id2Edit tag2Button tag2Combo branch2Button branch2Combo bookmark2Button bookmark2Combo tip2Button collapseCheckBox keepChangesetsCheckBox keepBranchCheckBox detachCheckBox buttonBox buttonBox accepted() HgRebaseDialog accept() 124 864 21 143 buttonBox rejected() HgRebaseDialog reject() 176 864 73 140 number1Button toggled(bool) number1SpinBox setEnabled(bool) 86 163 201 164 number2Button toggled(bool) number2SpinBox setEnabled(bool) 99 699 204 700 id1Button toggled(bool) id1Edit setEnabled(bool) 56 189 245 190 id2Button toggled(bool) id2Edit setEnabled(bool) 95 725 248 726 tag1Button toggled(bool) tag1Combo setEnabled(bool) 83 215 241 216 branch1Button toggled(bool) branch1Combo setEnabled(bool) 74 241 229 242 tag2Button toggled(bool) tag2Combo setEnabled(bool) 63 751 248 752 branch2Button toggled(bool) branch2Combo setEnabled(bool) 100 777 248 778 bookmark1Button toggled(bool) bookmark1Combo setEnabled(bool) 48 267 245 268 bookmark2Button toggled(bool) bookmark2Combo setEnabled(bool) 48 803 248 804 parentButton toggled(bool) rev1GroupBox setDisabled(bool) 139 49 226 126 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/RebaseExtension/ProjectHelper.py0000644000175000017500000001161012451233372027041 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the rebase extension project helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox from ..HgExtensionProjectHelper import HgExtensionProjectHelper import UI.PixmapCache class RebaseProjectHelper(HgExtensionProjectHelper): """ Class implementing the rebase extension project helper. """ def __init__(self): """ Constructor """ super(RebaseProjectHelper, self).__init__() def initActions(self): """ Public method to generate the action objects. """ self.hgRebaseAct = E5Action( self.tr('Rebase Changesets'), UI.PixmapCache.getIcon("vcsRebase.png"), self.tr('Rebase Changesets'), 0, 0, self, 'mercurial_rebase') self.hgRebaseAct.setStatusTip(self.tr( 'Rebase changesets to another branch' )) self.hgRebaseAct.setWhatsThis(self.tr( """Rebase Changesets""" """

This rebases changesets to another branch.

""" )) self.hgRebaseAct.triggered.connect(self.__hgRebase) self.actions.append(self.hgRebaseAct) self.hgRebaseContinueAct = E5Action( self.tr('Continue Rebase Session'), self.tr('Continue Rebase Session'), 0, 0, self, 'mercurial_rebase_continue') self.hgRebaseContinueAct.setStatusTip(self.tr( 'Continue the last rebase session after repair' )) self.hgRebaseContinueAct.setWhatsThis(self.tr( """Continue Rebase Session""" """

This continues the last rebase session after repair.

""" )) self.hgRebaseContinueAct.triggered.connect(self.__hgRebaseContinue) self.actions.append(self.hgRebaseContinueAct) self.hgRebaseAbortAct = E5Action( self.tr('Abort Rebase Session'), self.tr('Abort Rebase Session'), 0, 0, self, 'mercurial_rebase_abort') self.hgRebaseAbortAct.setStatusTip(self.tr( 'Abort the last rebase session' )) self.hgRebaseAbortAct.setWhatsThis(self.tr( """Abort Rebase Session""" """

This aborts the last rebase session.

""" )) self.hgRebaseAbortAct.triggered.connect(self.__hgRebaseAbort) self.actions.append(self.hgRebaseAbortAct) def initMenu(self, mainMenu): """ Public method to generate the extension menu. @param mainMenu reference to the main menu (QMenu) @return populated menu (QMenu) """ menu = QMenu(self.menuTitle(), mainMenu) menu.setIcon(UI.PixmapCache.getIcon("vcsRebase.png")) menu.setTearOffEnabled(True) menu.addAction(self.hgRebaseAct) menu.addAction(self.hgRebaseContinueAct) menu.addAction(self.hgRebaseAbortAct) return menu def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("Rebase") def __hgRebase(self): """ Private slot used to rebase changesets to another branch. """ shouldReopen = self.vcs.getExtensionObject("rebase")\ .hgRebase(self.project.getProjectPath()) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Rebase Changesets"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgRebaseContinue(self): """ Private slot used to continue the last rebase session after repair. """ shouldReopen = self.vcs.getExtensionObject("rebase")\ .hgRebaseContinue(self.project.getProjectPath()) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Rebase Changesets (Continue)"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgRebaseAbort(self): """ Private slot used to abort the last rebase session. """ shouldReopen = self.vcs.getExtensionObject("rebase")\ .hgRebaseAbort(self.project.getProjectPath()) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Rebase Changesets (Abort)"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/RebaseExtension/__init__.py0000644000175000017500000000025112451233372026031 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Package implementing the rebase extension support interface. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/RebaseExtension/rebase.py0000644000175000017500000001057112451233372025541 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the rebase extension interface. """ from __future__ import unicode_literals import os from PyQt5.QtWidgets import QDialog from ..HgExtension import HgExtension from ..HgDialog import HgDialog class Rebase(HgExtension): """ Class implementing the rebase extension interface. """ def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(Rebase, self).__init__(vcs) def hgRebase(self, path): """ Public method to rebase changesets to a different branch. @param path directory name of the project (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False res = False from .HgRebaseDialog import HgRebaseDialog dlg = HgRebaseDialog(self.vcs.hgGetTagsList(repodir), self.vcs.hgGetBranchesList(repodir), self.vcs.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: (indicator, sourceRev, destRev, collapse, keep, keepBranches, detach) = dlg.getData() args = self.vcs.initCommand("rebase") if indicator == "S": args.append("--source") args.append(sourceRev) elif indicator == "B": args.append("--base") args.append(sourceRev) if destRev: args.append("--dest") args.append(destRev) if collapse: args.append("--collapse") if keep: args.append("--keep") if keepBranches: args.append("--keepbranches") if detach: args.append("--detach") args.append("--verbose") dia = HgDialog(self.tr('Rebase Changesets'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res def hgRebaseContinue(self, path): """ Public method to continue rebasing changesets from another branch. @param path directory name of the project (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False args = self.vcs.initCommand("rebase") args.append("--continue") args.append("--verbose") dia = HgDialog(self.tr('Rebase Changesets (Continue)'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res def hgRebaseAbort(self, path): """ Public method to abort rebasing changesets from another branch. @param path directory name of the project (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False args = self.vcs.initCommand("rebase") args.append("--abort") args.append("--verbose") dia = HgDialog(self.tr('Rebase Changesets (Abort)'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgClientPromptDialog.py0000644000175000017500000000334512451233372025222 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a prompt dialog for the Mercurial command server. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QTextCursor from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgClientPromptDialog import Ui_HgClientPromptDialog class HgClientPromptDialog(QDialog, Ui_HgClientPromptDialog): """ Class implementing a prompt dialog for the Mercurial command server. """ def __init__(self, size, message, parent=None): """ Constructor @param size maximum length of the requested input (integer) @param message message sent by the server (string) @param parent reference to the parent widget (QWidget) """ super(HgClientPromptDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.inputEdit.setMaxLength(size) self.messageEdit.setPlainText(message) tc = self.messageEdit.textCursor() tc.movePosition(QTextCursor.End) self.messageEdit.setTextCursor(tc) self.messageEdit.ensureCursorVisible() @pyqtSlot(str) def on_inputEdit_textChanged(self, txt): """ Private slot to handle changes of the user input. @param txt text entered by the user (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(txt)) def getInput(self): """ Public method to get the user input. @return user input (string) """ return self.inputEdit.text() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgExtensionProjectBrowserHelper.py0000644000175000017500000000540712451233372027472 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing the project browser helper base for Mercurial extension interfaces. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject class HgExtensionProjectBrowserHelper(QObject): """ Class implementing the project browser helper base for Mercurial extension interfaces. Note: The methods initMenus() and menuTitle() have to be reimplemented by derived classes. """ def __init__(self, vcsObject, browserObject, projectObject): """ Constructor @param vcsObject reference to the vcs object @param browserObject reference to the project browser object @param projectObject reference to the project object """ super(HgExtensionProjectBrowserHelper, self).__init__() self.vcs = vcsObject self.browser = browserObject self.project = projectObject def initMenus(self): """ Public method to generate the extension menus. Note: Derived class must implement this method. @ireturn dictionary of populated menu (dict of QMenu). The dict must have the keys 'mainMenu', 'multiMenu', 'backMenu', 'dirMenu' and 'dirMultiMenu'. @exception NotImplementedError raised if the class has not been reimplemented """ raise NotImplementedError def menuTitle(self): """ Public method to get the menu title. Note: Derived class must implement this method. @ireturn title of the menu (string) @exception NotImplementedError raised if the class has not been reimplemented """ raise NotImplementedError def showExtensionMenu(self, key, controlled): """ Public method to prepare the extension menu for display. Note: Derived class must implement this method to adjust the enabled states of its menus. @param key menu key (string, one of 'mainMenu', 'multiMenu', 'backMenu', 'dirMenu' or 'dirMultiMenu') @param controlled flag indicating to prepare the menu for a version controlled entry or a non-version controlled entry (boolean) @exception NotImplementedError raised if the class has not been reimplemented """ raise NotImplementedError def _updateVCSStatus(self, name): """ Protected method to update the VCS status of an item. @param name filename or directoryname of the item to be updated (string) """ self.project.getModel().updateVCSStatus(name) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBookmarksListDialog.py0000644000175000017500000002560712537064320025373 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to show a list of bookmarks. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, QProcess, Qt, QTimer, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, \ QTreeWidgetItem, QLineEdit from E5Gui import E5MessageBox from .Ui_HgBookmarksListDialog import Ui_HgBookmarksListDialog class HgBookmarksListDialog(QDialog, Ui_HgBookmarksListDialog): """ Class implementing a dialog to show a list of bookmarks. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(HgBookmarksListDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = QProcess() self.vcs = vcs self.__bookmarksList = None self.__hgClient = vcs.getClient() self.bookmarksList.headerItem().setText( self.bookmarksList.columnCount(), "") self.bookmarksList.header().setSortIndicator(3, Qt.AscendingOrder) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path, bookmarksList): """ Public slot to start the bookmarks command. @param path name of directory to be listed (string) @param bookmarksList reference to string list receiving the bookmarks (list of strings) """ self.errorGroup.hide() self.intercept = False self.activateWindow() self.__bookmarksList = bookmarksList dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("bookmarks") if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.process = None if self.bookmarksList.topLevelItemCount() == 0: # no bookmarks defined self.__generateItem( self.tr("no bookmarks defined"), "", "", "") self.__resizeColumns() self.__resort() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __resort(self): """ Private method to resort the tree. """ self.bookmarksList.sortItems( self.bookmarksList.sortColumn(), self.bookmarksList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.bookmarksList.header().resizeSections( QHeaderView.ResizeToContents) self.bookmarksList.header().setStretchLastSection(True) def __generateItem(self, revision, changeset, status, name): """ Private method to generate a bookmark item in the bookmarks list. @param revision revision of the bookmark (string) @param changeset changeset of the bookmark (string) @param status of the bookmark (string) @param name name of the bookmark (string) """ itm = QTreeWidgetItem(self.bookmarksList) if revision[0].isdecimal(): # valid bookmark entry itm.setData(0, Qt.DisplayRole, int(revision)) itm.setData(1, Qt.DisplayRole, changeset) itm.setData(2, Qt.DisplayRole, status) itm.setData(3, Qt.DisplayRole, name) itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(1, Qt.AlignRight) itm.setTextAlignment(2, Qt.AlignHCenter) else: # error message itm.setData(0, Qt.DisplayRole, revision) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.vcs.getEncoding(), 'replace').strip() self.__processOutputLine(s) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ li = line.split() if li[-1][0] in "1234567890": # last element is a rev:changeset rev, changeset = li[-1].split(":", 1) del li[-1] if li[0] == "*": status = "current" del li[0] else: status = "" name = " ".join(li) self.__generateItem(rev, changeset, status, name) if self.__bookmarksList is not None: self.__bookmarksList.append(name) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgBookmarksListDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py0000644000175000017500000021365012451233372023753 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the VCS project helper for Mercurial. """ from __future__ import unicode_literals import os from PyQt5.QtWidgets import QMenu from E5Gui import E5MessageBox from E5Gui.E5Application import e5App from VCS.ProjectHelper import VcsProjectHelper from E5Gui.E5Action import E5Action import UI.PixmapCache import Preferences class HgProjectHelper(VcsProjectHelper): """ Class implementing the VCS project helper for Mercurial. """ def __init__(self, vcsObject, projectObject, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param projectObject reference to the project object @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectHelper.__init__(self, vcsObject, projectObject, parent, name) # instantiate the extensions from .QueuesExtension.ProjectHelper import QueuesProjectHelper from .FetchExtension.ProjectHelper import FetchProjectHelper from .PurgeExtension.ProjectHelper import PurgeProjectHelper from .GpgExtension.ProjectHelper import GpgProjectHelper from .TransplantExtension.ProjectHelper import TransplantProjectHelper from .RebaseExtension.ProjectHelper import RebaseProjectHelper from .ShelveExtension.ProjectHelper import ShelveProjectHelper from .LargefilesExtension.ProjectHelper import LargefilesProjectHelper self.__extensions = { "mq": QueuesProjectHelper(), "fetch": FetchProjectHelper(), "purge": PurgeProjectHelper(), "gpg": GpgProjectHelper(), "transplant": TransplantProjectHelper(), "rebase": RebaseProjectHelper(), "shelve": ShelveProjectHelper(), "largefiles": LargefilesProjectHelper(), } self.__extensionMenuTitles = {} for extension in self.__extensions: self.__extensionMenuTitles[ self.__extensions[extension].menuTitle()] = extension def setObjects(self, vcsObject, projectObject): """ Public method to set references to the vcs and project objects. @param vcsObject reference to the vcs object @param projectObject reference to the project object """ self.vcs = vcsObject self.project = projectObject for extension in self.__extensions.values(): extension.setObjects(vcsObject, projectObject) self.vcs.iniFileChanged.connect(self.__checkActions) def getProject(self): """ Public method to get a reference to the project object. @return reference to the project object (Project) """ return self.project def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ actions = self.actions[:] for extension in self.__extensions.values(): actions.extend(extension.getActions()) return actions def initActions(self): """ Public method to generate the action objects. """ self.vcsNewAct = E5Action( self.tr('New from repository'), UI.PixmapCache.getIcon("vcsCheckout.png"), self.tr('&New from repository...'), 0, 0, self, 'mercurial_new') self.vcsNewAct.setStatusTip(self.tr( 'Create (clone) a new project from a Mercurial repository' )) self.vcsNewAct.setWhatsThis(self.tr( """New from repository""" """

This creates (clones) a new local project from """ """a Mercurial repository.

""" )) self.vcsNewAct.triggered.connect(self._vcsCheckout) self.actions.append(self.vcsNewAct) self.hgIncomingAct = E5Action( self.tr('Show incoming log'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Show incoming log'), 0, 0, self, 'mercurial_incoming') self.hgIncomingAct.setStatusTip(self.tr( 'Show the log of incoming changes' )) self.hgIncomingAct.setWhatsThis(self.tr( """Show incoming log""" """

This shows the log of changes coming into the""" """ repository.

""" )) self.hgIncomingAct.triggered.connect(self.__hgIncoming) self.actions.append(self.hgIncomingAct) self.hgPullAct = E5Action( self.tr('Pull changes'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Pull changes'), 0, 0, self, 'mercurial_pull') self.hgPullAct.setStatusTip(self.tr( 'Pull changes from a remote repository' )) self.hgPullAct.setWhatsThis(self.tr( """Pull changes""" """

This pulls changes from a remote repository into the """ """local repository.

""" )) self.hgPullAct.triggered.connect(self.__hgPull) self.actions.append(self.hgPullAct) self.vcsUpdateAct = E5Action( self.tr('Update from repository'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('&Update from repository'), 0, 0, self, 'mercurial_update') self.vcsUpdateAct.setStatusTip(self.tr( 'Update the local project from the Mercurial repository' )) self.vcsUpdateAct.setWhatsThis(self.tr( """Update from repository""" """

This updates the local project from the Mercurial""" """ repository.

""" )) self.vcsUpdateAct.triggered.connect(self._vcsUpdate) self.actions.append(self.vcsUpdateAct) self.vcsCommitAct = E5Action( self.tr('Commit changes to repository'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('&Commit changes to repository...'), 0, 0, self, 'mercurial_commit') self.vcsCommitAct.setStatusTip(self.tr( 'Commit changes to the local project to the Mercurial repository' )) self.vcsCommitAct.setWhatsThis(self.tr( """Commit changes to repository""" """

This commits changes to the local project to the """ """Mercurial repository.

""" )) self.vcsCommitAct.triggered.connect(self._vcsCommit) self.actions.append(self.vcsCommitAct) self.hgOutgoingAct = E5Action( self.tr('Show outgoing log'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Show outgoing log'), 0, 0, self, 'mercurial_outgoing') self.hgOutgoingAct.setStatusTip(self.tr( 'Show the log of outgoing changes' )) self.hgOutgoingAct.setWhatsThis(self.tr( """Show outgoing log""" """

This shows the log of changes outgoing out of the""" """ repository.

""" )) self.hgOutgoingAct.triggered.connect(self.__hgOutgoing) self.actions.append(self.hgOutgoingAct) self.hgPushAct = E5Action( self.tr('Push changes'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Push changes'), 0, 0, self, 'mercurial_push') self.hgPushAct.setStatusTip(self.tr( 'Push changes to a remote repository' )) self.hgPushAct.setWhatsThis(self.tr( """Push changes""" """

This pushes changes from the local repository to a """ """remote repository.

""" )) self.hgPushAct.triggered.connect(self.__hgPush) self.actions.append(self.hgPushAct) self.hgPushForcedAct = E5Action( self.tr('Push changes (force)'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('Push changes (force)'), 0, 0, self, 'mercurial_push_forced') self.hgPushForcedAct.setStatusTip(self.tr( 'Push changes to a remote repository with force option' )) self.hgPushForcedAct.setWhatsThis(self.tr( """Push changes (force)""" """

This pushes changes from the local repository to a """ """remote repository using the 'force' option.

""" )) self.hgPushForcedAct.triggered.connect(self.__hgPushForced) self.actions.append(self.hgPushForcedAct) self.vcsExportAct = E5Action( self.tr('Export from repository'), UI.PixmapCache.getIcon("vcsExport.png"), self.tr('&Export from repository...'), 0, 0, self, 'mercurial_export_repo') self.vcsExportAct.setStatusTip(self.tr( 'Export a project from the repository' )) self.vcsExportAct.setWhatsThis(self.tr( """Export from repository""" """

This exports a project from the repository.

""" )) self.vcsExportAct.triggered.connect(self._vcsExport) self.actions.append(self.vcsExportAct) self.vcsLogAct = E5Action( self.tr('Show log'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show &log'), 0, 0, self, 'mercurial_log') self.vcsLogAct.setStatusTip(self.tr( 'Show the log of the local project' )) self.vcsLogAct.setWhatsThis(self.tr( """Show log""" """

This shows the log of the local project.

""" )) self.vcsLogAct.triggered.connect(self._vcsLog) self.actions.append(self.vcsLogAct) self.hgLogBrowserAct = E5Action( self.tr('Show log browser'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), 0, 0, self, 'mercurial_log_browser') self.hgLogBrowserAct.setStatusTip(self.tr( 'Show a dialog to browse the log of the local project' )) self.hgLogBrowserAct.setWhatsThis(self.tr( """Show log browser""" """

This shows a dialog to browse the log of the local""" """ project. A limited number of entries is shown first.""" """ More can be retrieved later on.

""" )) self.hgLogBrowserAct.triggered.connect(self._vcsLogBrowser) self.actions.append(self.hgLogBrowserAct) self.vcsDiffAct = E5Action( self.tr('Show differences'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show &difference'), 0, 0, self, 'mercurial_diff') self.vcsDiffAct.setStatusTip(self.tr( 'Show the difference of the local project to the repository' )) self.vcsDiffAct.setWhatsThis(self.tr( """Show differences""" """

This shows differences of the local project to the""" """ repository.

""" )) self.vcsDiffAct.triggered.connect(self._vcsDiff) self.actions.append(self.vcsDiffAct) self.hgExtDiffAct = E5Action( self.tr('Show differences (extended)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), 0, 0, self, 'mercurial_extendeddiff') self.hgExtDiffAct.setStatusTip(self.tr( 'Show the difference of revisions of the project to the repository' )) self.hgExtDiffAct.setWhatsThis(self.tr( """Show differences (extended)""" """

This shows differences of selectable revisions of the""" """ project.

""" )) self.hgExtDiffAct.triggered.connect(self.__hgExtendedDiff) self.actions.append(self.hgExtDiffAct) self.vcsStatusAct = E5Action( self.tr('Show status'), UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show &status...'), 0, 0, self, 'mercurial_status') self.vcsStatusAct.setStatusTip(self.tr( 'Show the status of the local project' )) self.vcsStatusAct.setWhatsThis(self.tr( """Show status""" """

This shows the status of the local project.

""" )) self.vcsStatusAct.triggered.connect(self._vcsStatus) self.actions.append(self.vcsStatusAct) self.hgSummaryAct = E5Action( self.tr('Show Summary'), UI.PixmapCache.getIcon("vcsSummary.png"), self.tr('Show summary...'), 0, 0, self, 'mercurial_summary') self.hgSummaryAct.setStatusTip(self.tr( 'Show summary information of the working directory status' )) self.hgSummaryAct.setWhatsThis(self.tr( """Show summary""" """

This shows some summary information of the working""" """ directory status.

""" )) self.hgSummaryAct.triggered.connect(self.__hgSummary) self.actions.append(self.hgSummaryAct) self.hgHeadsAct = E5Action( self.tr('Show heads'), self.tr('Show heads'), 0, 0, self, 'mercurial_heads') self.hgHeadsAct.setStatusTip(self.tr( 'Show the heads of the repository' )) self.hgHeadsAct.setWhatsThis(self.tr( """Show heads""" """

This shows the heads of the repository.

""" )) self.hgHeadsAct.triggered.connect(self.__hgHeads) self.actions.append(self.hgHeadsAct) self.hgParentsAct = E5Action( self.tr('Show parents'), self.tr('Show parents'), 0, 0, self, 'mercurial_parents') self.hgParentsAct.setStatusTip(self.tr( 'Show the parents of the repository' )) self.hgParentsAct.setWhatsThis(self.tr( """Show parents""" """

This shows the parents of the repository.

""" )) self.hgParentsAct.triggered.connect(self.__hgParents) self.actions.append(self.hgParentsAct) self.hgTipAct = E5Action( self.tr('Show tip'), self.tr('Show tip'), 0, 0, self, 'mercurial_tip') self.hgTipAct.setStatusTip(self.tr( 'Show the tip of the repository' )) self.hgTipAct.setWhatsThis(self.tr( """Show tip""" """

This shows the tip of the repository.

""" )) self.hgTipAct.triggered.connect(self.__hgTip) self.actions.append(self.hgTipAct) self.vcsRevertAct = E5Action( self.tr('Revert changes'), UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Re&vert changes'), 0, 0, self, 'mercurial_revert') self.vcsRevertAct.setStatusTip(self.tr( 'Revert all changes made to the local project' )) self.vcsRevertAct.setWhatsThis(self.tr( """Revert changes""" """

This reverts all changes made to the local project.

""" )) self.vcsRevertAct.triggered.connect(self.__hgRevert) self.actions.append(self.vcsRevertAct) self.vcsMergeAct = E5Action( self.tr('Merge'), UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Mer&ge changes...'), 0, 0, self, 'mercurial_merge') self.vcsMergeAct.setStatusTip(self.tr( 'Merge changes of a revision into the local project' )) self.vcsMergeAct.setWhatsThis(self.tr( """Merge""" """

This merges changes of a revision into the local""" """ project.

""" )) self.vcsMergeAct.triggered.connect(self._vcsMerge) self.actions.append(self.vcsMergeAct) self.hgCancelMergeAct = E5Action( self.tr('Cancel uncommitted merge'), self.tr('Cancel uncommitted merge'), 0, 0, self, 'mercurial_cancel_merge') self.hgCancelMergeAct.setStatusTip(self.tr( 'Cancel an uncommitted merge and lose all changes' )) self.hgCancelMergeAct.setWhatsThis(self.tr( """Cancel uncommitted merge""" """

This cancels an uncommitted merge causing all changes""" """ to be lost.

""" )) self.hgCancelMergeAct.triggered.connect(self.__hgCancelMerge) self.actions.append(self.hgCancelMergeAct) self.hgReMergeAct = E5Action( self.tr('Re-Merge'), UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Re-Merge'), 0, 0, self, 'mercurial_remerge') self.hgReMergeAct.setStatusTip(self.tr( 'Re-Merge all conflicting, unresolved files of the project' )) self.hgReMergeAct.setWhatsThis(self.tr( """Re-Merge""" """

This re-merges all conflicting, unresolved files of the""" """ project discarding any previous merge attempt.

""" )) self.hgReMergeAct.triggered.connect(self.__hgReMerge) self.actions.append(self.hgReMergeAct) self.hgShowConflictsAct = E5Action( self.tr('Show conflicts'), self.tr('Show conflicts...'), 0, 0, self, 'mercurial_show_conflicts') self.hgShowConflictsAct.setStatusTip(self.tr( 'Show a dialog listing all files with conflicts' )) self.hgShowConflictsAct.setWhatsThis(self.tr( """Show conflicts""" """

This shows a dialog listing all files which had or still""" """ have conflicts.

""" )) self.hgShowConflictsAct.triggered.connect(self.__hgShowConflicts) self.actions.append(self.hgShowConflictsAct) self.vcsResolveAct = E5Action( self.tr('Conflicts resolved'), self.tr('Con&flicts resolved'), 0, 0, self, 'mercurial_resolve') self.vcsResolveAct.setStatusTip(self.tr( 'Mark all conflicts of the local project as resolved' )) self.vcsResolveAct.setWhatsThis(self.tr( """Conflicts resolved""" """

This marks all conflicts of the local project as""" """ resolved.

""" )) self.vcsResolveAct.triggered.connect(self.__hgResolved) self.actions.append(self.vcsResolveAct) self.hgUnresolveAct = E5Action( self.tr('Conflicts unresolved'), self.tr('Conflicts unresolved'), 0, 0, self, 'mercurial_unresolve') self.hgUnresolveAct.setStatusTip(self.tr( 'Mark all conflicts of the local project as unresolved' )) self.hgUnresolveAct.setWhatsThis(self.tr( """Conflicts unresolved""" """

This marks all conflicts of the local project as""" """ unresolved.

""" )) self.hgUnresolveAct.triggered.connect(self.__hgUnresolved) self.actions.append(self.hgUnresolveAct) self.vcsTagAct = E5Action( self.tr('Tag in repository'), UI.PixmapCache.getIcon("vcsTag.png"), self.tr('&Tag in repository...'), 0, 0, self, 'mercurial_tag') self.vcsTagAct.setStatusTip(self.tr( 'Tag the local project in the repository' )) self.vcsTagAct.setWhatsThis(self.tr( """Tag in repository""" """

This tags the local project in the repository.

""" )) self.vcsTagAct.triggered.connect(self._vcsTag) self.actions.append(self.vcsTagAct) self.hgTagListAct = E5Action( self.tr('List tags'), self.tr('List tags...'), 0, 0, self, 'mercurial_list_tags') self.hgTagListAct.setStatusTip(self.tr( 'List tags of the project' )) self.hgTagListAct.setWhatsThis(self.tr( """List tags""" """

This lists the tags of the project.

""" )) self.hgTagListAct.triggered.connect(self.__hgTagList) self.actions.append(self.hgTagListAct) self.hgBranchListAct = E5Action( self.tr('List branches'), self.tr('List branches...'), 0, 0, self, 'mercurial_list_branches') self.hgBranchListAct.setStatusTip(self.tr( 'List branches of the project' )) self.hgBranchListAct.setWhatsThis(self.tr( """List branches""" """

This lists the branches of the project.

""" )) self.hgBranchListAct.triggered.connect(self.__hgBranchList) self.actions.append(self.hgBranchListAct) self.hgBranchAct = E5Action( self.tr('Create branch'), UI.PixmapCache.getIcon("vcsBranch.png"), self.tr('Create &branch...'), 0, 0, self, 'mercurial_branch') self.hgBranchAct.setStatusTip(self.tr( 'Create a new branch for the local project in the repository' )) self.hgBranchAct.setWhatsThis(self.tr( """Create branch""" """

This creates a new branch for the local project """ """in the repository.

""" )) self.hgBranchAct.triggered.connect(self.__hgBranch) self.actions.append(self.hgBranchAct) self.hgPushBranchAct = E5Action( self.tr('Push new branch'), self.tr('Push new branch'), 0, 0, self, 'mercurial_push_branch') self.hgPushBranchAct.setStatusTip(self.tr( 'Push the current branch of the local project as a new named' ' branch' )) self.hgPushBranchAct.setWhatsThis(self.tr( """Push new branch""" """

This pushes the current branch of the local project""" """ as a new named branch.

""" )) self.hgPushBranchAct.triggered.connect(self.__hgPushNewBranch) self.actions.append(self.hgPushBranchAct) self.hgCloseBranchAct = E5Action( self.tr('Close branch'), self.tr('Close branch'), 0, 0, self, 'mercurial_close_branch') self.hgCloseBranchAct.setStatusTip(self.tr( 'Close the current branch of the local project' )) self.hgCloseBranchAct.setWhatsThis(self.tr( """Close branch""" """

This closes the current branch of the local project.

""" )) self.hgCloseBranchAct.triggered.connect(self.__hgCloseBranch) self.actions.append(self.hgCloseBranchAct) self.hgShowBranchAct = E5Action( self.tr('Show current branch'), self.tr('Show current branch'), 0, 0, self, 'mercurial_show_branch') self.hgShowBranchAct.setStatusTip(self.tr( 'Show the current branch of the project' )) self.hgShowBranchAct.setWhatsThis(self.tr( """Show current branch""" """

This shows the current branch of the project.

""" )) self.hgShowBranchAct.triggered.connect(self.__hgShowBranch) self.actions.append(self.hgShowBranchAct) self.vcsSwitchAct = E5Action( self.tr('Switch'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('S&witch...'), 0, 0, self, 'mercurial_switch') self.vcsSwitchAct.setStatusTip(self.tr( 'Switch the working directory to another revision' )) self.vcsSwitchAct.setWhatsThis(self.tr( """Switch""" """

This switches the working directory to another""" """ revision.

""" )) self.vcsSwitchAct.triggered.connect(self._vcsSwitch) self.actions.append(self.vcsSwitchAct) self.vcsCleanupAct = E5Action( self.tr('Cleanup'), self.tr('Cleanu&p'), 0, 0, self, 'mercurial_cleanup') self.vcsCleanupAct.setStatusTip(self.tr( 'Cleanup the local project' )) self.vcsCleanupAct.setWhatsThis(self.tr( """Cleanup""" """

This performs a cleanup of the local project.

""" )) self.vcsCleanupAct.triggered.connect(self._vcsCleanup) self.actions.append(self.vcsCleanupAct) self.vcsCommandAct = E5Action( self.tr('Execute command'), self.tr('E&xecute command...'), 0, 0, self, 'mercurial_command') self.vcsCommandAct.setStatusTip(self.tr( 'Execute an arbitrary Mercurial command' )) self.vcsCommandAct.setWhatsThis(self.tr( """Execute command""" """

This opens a dialog to enter an arbitrary Mercurial""" """ command.

""" )) self.vcsCommandAct.triggered.connect(self._vcsCommand) self.actions.append(self.vcsCommandAct) self.hgConfigAct = E5Action( self.tr('Configure'), self.tr('Configure...'), 0, 0, self, 'mercurial_configure') self.hgConfigAct.setStatusTip(self.tr( 'Show the configuration dialog with the Mercurial page selected' )) self.hgConfigAct.setWhatsThis(self.tr( """Configure""" """

Show the configuration dialog with the Mercurial page""" """ selected.

""" )) self.hgConfigAct.triggered.connect(self.__hgConfigure) self.actions.append(self.hgConfigAct) self.hgEditUserConfigAct = E5Action( self.tr('Edit user configuration'), self.tr('Edit user configuration...'), 0, 0, self, 'mercurial_user_configure') self.hgEditUserConfigAct.setStatusTip(self.tr( 'Show an editor to edit the user configuration file' )) self.hgEditUserConfigAct.setWhatsThis(self.tr( """Edit user configuration""" """

Show an editor to edit the user configuration file.

""" )) self.hgEditUserConfigAct.triggered.connect(self.__hgEditUserConfig) self.actions.append(self.hgEditUserConfigAct) self.hgRepoConfigAct = E5Action( self.tr('Edit repository configuration'), self.tr('Edit repository configuration...'), 0, 0, self, 'mercurial_repo_configure') self.hgRepoConfigAct.setStatusTip(self.tr( 'Show an editor to edit the repository configuration file' )) self.hgRepoConfigAct.setWhatsThis(self.tr( """Edit repository configuration""" """

Show an editor to edit the repository configuration""" """ file.

""" )) self.hgRepoConfigAct.triggered.connect(self.__hgEditRepoConfig) self.actions.append(self.hgRepoConfigAct) self.hgShowConfigAct = E5Action( self.tr('Show combined configuration settings'), self.tr('Show combined configuration settings...'), 0, 0, self, 'mercurial_show_config') self.hgShowConfigAct.setStatusTip(self.tr( 'Show the combined configuration settings from all configuration' ' files' )) self.hgShowConfigAct.setWhatsThis(self.tr( """Show combined configuration settings""" """

This shows the combined configuration settings""" """ from all configuration files.

""" )) self.hgShowConfigAct.triggered.connect(self.__hgShowConfig) self.actions.append(self.hgShowConfigAct) self.hgShowPathsAct = E5Action( self.tr('Show paths'), self.tr('Show paths...'), 0, 0, self, 'mercurial_show_paths') self.hgShowPathsAct.setStatusTip(self.tr( 'Show the aliases for remote repositories' )) self.hgShowPathsAct.setWhatsThis(self.tr( """Show paths""" """

This shows the aliases for remote repositories.

""" )) self.hgShowPathsAct.triggered.connect(self.__hgShowPaths) self.actions.append(self.hgShowPathsAct) self.hgVerifyAct = E5Action( self.tr('Verify repository'), self.tr('Verify repository...'), 0, 0, self, 'mercurial_verify') self.hgVerifyAct.setStatusTip(self.tr( 'Verify the integrity of the repository' )) self.hgVerifyAct.setWhatsThis(self.tr( """Verify repository""" """

This verifies the integrity of the repository.

""" )) self.hgVerifyAct.triggered.connect(self.__hgVerify) self.actions.append(self.hgVerifyAct) self.hgRecoverAct = E5Action( self.tr('Recover'), self.tr('Recover...'), 0, 0, self, 'mercurial_recover') self.hgRecoverAct.setStatusTip(self.tr( 'Recover from an interrupted transaction' )) self.hgRecoverAct.setWhatsThis(self.tr( """Recover""" """

This recovers from an interrupted transaction.

""" )) self.hgRecoverAct.triggered.connect(self.__hgRecover) self.actions.append(self.hgRecoverAct) self.hgIdentifyAct = E5Action( self.tr('Identify'), self.tr('Identify...'), 0, 0, self, 'mercurial_identify') self.hgIdentifyAct.setStatusTip(self.tr( 'Identify the project directory' )) self.hgIdentifyAct.setWhatsThis(self.tr( """Identify""" """

This identifies the project directory.

""" )) self.hgIdentifyAct.triggered.connect(self.__hgIdentify) self.actions.append(self.hgIdentifyAct) self.hgCreateIgnoreAct = E5Action( self.tr('Create .hgignore'), self.tr('Create .hgignore'), 0, 0, self, 'mercurial_create ignore') self.hgCreateIgnoreAct.setStatusTip(self.tr( 'Create a .hgignore file with default values' )) self.hgCreateIgnoreAct.setWhatsThis(self.tr( """Create .hgignore""" """

This creates a .hgignore file with default values.

""" )) self.hgCreateIgnoreAct.triggered.connect(self.__hgCreateIgnore) self.actions.append(self.hgCreateIgnoreAct) self.hgBundleAct = E5Action( self.tr('Create changegroup'), self.tr('Create changegroup...'), 0, 0, self, 'mercurial_bundle') self.hgBundleAct.setStatusTip(self.tr( 'Create changegroup file collecting changesets' )) self.hgBundleAct.setWhatsThis(self.tr( """Create changegroup""" """

This creates a changegroup file collecting selected""" """ changesets (hg bundle).

""" )) self.hgBundleAct.triggered.connect(self.__hgBundle) self.actions.append(self.hgBundleAct) self.hgPreviewBundleAct = E5Action( self.tr('Preview changegroup'), self.tr('Preview changegroup...'), 0, 0, self, 'mercurial_preview_bundle') self.hgPreviewBundleAct.setStatusTip(self.tr( 'Preview a changegroup file containing a collection of changesets' )) self.hgPreviewBundleAct.setWhatsThis(self.tr( """Preview changegroup""" """

This previews a changegroup file containing a collection""" """ of changesets.

""" )) self.hgPreviewBundleAct.triggered.connect(self.__hgPreviewBundle) self.actions.append(self.hgPreviewBundleAct) self.hgUnbundleAct = E5Action( self.tr('Apply changegroups'), self.tr('Apply changegroups...'), 0, 0, self, 'mercurial_unbundle') self.hgUnbundleAct.setStatusTip(self.tr( 'Apply one or several changegroup files' )) self.hgUnbundleAct.setWhatsThis(self.tr( """Apply changegroups""" """

This applies one or several changegroup files generated by""" """ the 'Create changegroup' action (hg unbundle).

""" )) self.hgUnbundleAct.triggered.connect(self.__hgUnbundle) self.actions.append(self.hgUnbundleAct) self.hgBisectGoodAct = E5Action( self.tr('Mark as "good"'), self.tr('Mark as "good"...'), 0, 0, self, 'mercurial_bisect_good') self.hgBisectGoodAct.setStatusTip(self.tr( 'Mark a selectable changeset as good' )) self.hgBisectGoodAct.setWhatsThis(self.tr( """Mark as good""" """

This marks a selectable changeset as good.

""" )) self.hgBisectGoodAct.triggered.connect(self.__hgBisectGood) self.actions.append(self.hgBisectGoodAct) self.hgBisectBadAct = E5Action( self.tr('Mark as "bad"'), self.tr('Mark as "bad"...'), 0, 0, self, 'mercurial_bisect_bad') self.hgBisectBadAct.setStatusTip(self.tr( 'Mark a selectable changeset as bad' )) self.hgBisectBadAct.setWhatsThis(self.tr( """Mark as bad""" """

This marks a selectable changeset as bad.

""" )) self.hgBisectBadAct.triggered.connect(self.__hgBisectBad) self.actions.append(self.hgBisectBadAct) self.hgBisectSkipAct = E5Action( self.tr('Skip'), self.tr('Skip...'), 0, 0, self, 'mercurial_bisect_skip') self.hgBisectSkipAct.setStatusTip(self.tr( 'Skip a selectable changeset' )) self.hgBisectSkipAct.setWhatsThis(self.tr( """Skip""" """

This skips a selectable changeset.

""" )) self.hgBisectSkipAct.triggered.connect(self.__hgBisectSkip) self.actions.append(self.hgBisectSkipAct) self.hgBisectResetAct = E5Action( self.tr('Reset'), self.tr('Reset'), 0, 0, self, 'mercurial_bisect_reset') self.hgBisectResetAct.setStatusTip(self.tr( 'Reset the bisect search data' )) self.hgBisectResetAct.setWhatsThis(self.tr( """Reset""" """

This resets the bisect search data.

""" )) self.hgBisectResetAct.triggered.connect(self.__hgBisectReset) self.actions.append(self.hgBisectResetAct) self.hgBackoutAct = E5Action( self.tr('Back out changeset'), self.tr('Back out changeset'), 0, 0, self, 'mercurial_backout') self.hgBackoutAct.setStatusTip(self.tr( 'Back out changes of an earlier changeset' )) self.hgBackoutAct.setWhatsThis(self.tr( """Back out changeset""" """

This backs out changes of an earlier changeset.

""" )) self.hgBackoutAct.triggered.connect(self.__hgBackout) self.actions.append(self.hgBackoutAct) self.hgRollbackAct = E5Action( self.tr('Rollback last transaction'), self.tr('Rollback last transaction'), 0, 0, self, 'mercurial_rollback') self.hgRollbackAct.setStatusTip(self.tr( 'Rollback the last transaction' )) self.hgRollbackAct.setWhatsThis(self.tr( """Rollback last transaction""" """

This performs a rollback of the last transaction.""" """ Transactions are used to encapsulate the effects of all""" """ commands that create new changesets or propagate existing""" """ changesets into a repository. For example, the following""" """ commands are transactional, and their effects can be""" """ rolled back:

    """ """
  • commit
  • """ """
  • import
  • """ """
  • pull
  • """ """
  • push (with this repository as the destination)
  • """ """
  • unbundle
  • """ """
""" """

This command is dangerous. Please use with""" """ care.

""" )) self.hgRollbackAct.triggered.connect(self.__hgRollback) self.actions.append(self.hgRollbackAct) self.hgServeAct = E5Action( self.tr('Serve project repository'), self.tr('Serve project repository...'), 0, 0, self, 'mercurial_serve') self.hgServeAct.setStatusTip(self.tr( 'Serve the project repository' )) self.hgServeAct.setWhatsThis(self.tr( """Serve project repository""" """

This serves the project repository.

""" )) self.hgServeAct.triggered.connect(self.__hgServe) self.actions.append(self.hgServeAct) self.hgImportAct = E5Action( self.tr('Import Patch'), self.tr('Import Patch...'), 0, 0, self, 'mercurial_import') self.hgImportAct.setStatusTip(self.tr( 'Import a patch from a patch file' )) self.hgImportAct.setWhatsThis(self.tr( """Import Patch""" """

This imports a patch from a patch file into the""" """ project.

""" )) self.hgImportAct.triggered.connect(self.__hgImport) self.actions.append(self.hgImportAct) self.hgExportAct = E5Action( self.tr('Export Patches'), self.tr('Export Patches...'), 0, 0, self, 'mercurial_export') self.hgExportAct.setStatusTip(self.tr( 'Export revisions to patch files' )) self.hgExportAct.setWhatsThis(self.tr( """Export Patches""" """

This exports revisions of the project to patch files.

""" )) self.hgExportAct.triggered.connect(self.__hgExport) self.actions.append(self.hgExportAct) self.hgPhaseAct = E5Action( self.tr('Change Phase'), self.tr('Change Phase...'), 0, 0, self, 'mercurial_change_phase') self.hgPhaseAct.setStatusTip(self.tr( 'Change the phase of revisions' )) self.hgPhaseAct.setWhatsThis(self.tr( """Change Phase""" """

This changes the phase of revisions.

""" )) self.hgPhaseAct.triggered.connect(self.__hgPhase) self.actions.append(self.hgPhaseAct) self.hgGraftAct = E5Action( self.tr('Copy Changesets'), UI.PixmapCache.getIcon("vcsGraft.png"), self.tr('Copy Changesets'), 0, 0, self, 'mercurial_graft') self.hgGraftAct.setStatusTip(self.tr( 'Copies changesets from another branch' )) self.hgGraftAct.setWhatsThis(self.tr( """Copy Changesets""" """

This copies changesets from another branch on top of the""" """ current working directory with the user, date and""" """ description of the original changeset.

""" )) self.hgGraftAct.triggered.connect(self.__hgGraft) self.actions.append(self.hgGraftAct) self.hgGraftContinueAct = E5Action( self.tr('Continue Copying Session'), self.tr('Continue Copying Session'), 0, 0, self, 'mercurial_graft_continue') self.hgGraftContinueAct.setStatusTip(self.tr( 'Continue the last copying session after conflicts were resolved' )) self.hgGraftContinueAct.setWhatsThis(self.tr( """Continue Copying Session""" """

This continues the last copying session after conflicts""" """ were resolved.

""" )) self.hgGraftContinueAct.triggered.connect(self.__hgGraftContinue) self.actions.append(self.hgGraftContinueAct) self.hgAddSubrepoAct = E5Action( self.tr('Add'), UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add...'), 0, 0, self, 'mercurial_add_subrepo') self.hgAddSubrepoAct.setStatusTip(self.tr( 'Add a sub-repository' )) self.hgAddSubrepoAct.setWhatsThis(self.tr( """Add...""" """

Add a sub-repository to the project.

""" )) self.hgAddSubrepoAct.triggered.connect(self.__hgAddSubrepository) self.actions.append(self.hgAddSubrepoAct) self.hgRemoveSubreposAct = E5Action( self.tr('Remove'), UI.PixmapCache.getIcon("vcsRemove.png"), self.tr('Remove...'), 0, 0, self, 'mercurial_remove_subrepos') self.hgRemoveSubreposAct.setStatusTip(self.tr( 'Remove sub-repositories' )) self.hgRemoveSubreposAct.setWhatsThis(self.tr( """Remove...""" """

Remove sub-repositories from the project.

""" )) self.hgRemoveSubreposAct.triggered.connect( self.__hgRemoveSubrepositories) self.actions.append(self.hgRemoveSubreposAct) self.hgArchiveAct = E5Action( self.tr('Create unversioned archive'), UI.PixmapCache.getIcon("vcsExport.png"), self.tr('Create unversioned archive...'), 0, 0, self, 'mercurial_archive') self.hgArchiveAct.setStatusTip(self.tr( 'Create an unversioned archive from the repository' )) self.hgArchiveAct.setWhatsThis(self.tr( """Create unversioned archive...""" """

This creates an unversioned archive from the""" """ repository.

""" )) self.hgArchiveAct.triggered.connect(self.__hgArchive) self.actions.append(self.hgArchiveAct) self.hgBookmarksListAct = E5Action( self.tr('List bookmarks'), UI.PixmapCache.getIcon("listBookmarks.png"), self.tr('List bookmarks...'), 0, 0, self, 'mercurial_list_bookmarks') self.hgBookmarksListAct.setStatusTip(self.tr( 'List bookmarks of the project' )) self.hgBookmarksListAct.setWhatsThis(self.tr( """List bookmarks""" """

This lists the bookmarks of the project.

""" )) self.hgBookmarksListAct.triggered.connect(self.__hgBookmarksList) self.actions.append(self.hgBookmarksListAct) self.hgBookmarkDefineAct = E5Action( self.tr('Define bookmark'), UI.PixmapCache.getIcon("addBookmark.png"), self.tr('Define bookmark...'), 0, 0, self, 'mercurial_define_bookmark') self.hgBookmarkDefineAct.setStatusTip(self.tr( 'Define a bookmark for the project' )) self.hgBookmarkDefineAct.setWhatsThis(self.tr( """Define bookmark""" """

This defines a bookmark for the project.

""" )) self.hgBookmarkDefineAct.triggered.connect(self.__hgBookmarkDefine) self.actions.append(self.hgBookmarkDefineAct) self.hgBookmarkDeleteAct = E5Action( self.tr('Delete bookmark'), UI.PixmapCache.getIcon("deleteBookmark.png"), self.tr('Delete bookmark...'), 0, 0, self, 'mercurial_delete_bookmark') self.hgBookmarkDeleteAct.setStatusTip(self.tr( 'Delete a bookmark of the project' )) self.hgBookmarkDeleteAct.setWhatsThis(self.tr( """Delete bookmark""" """

This deletes a bookmark of the project.

""" )) self.hgBookmarkDeleteAct.triggered.connect(self.__hgBookmarkDelete) self.actions.append(self.hgBookmarkDeleteAct) self.hgBookmarkRenameAct = E5Action( self.tr('Rename bookmark'), UI.PixmapCache.getIcon("renameBookmark.png"), self.tr('Rename bookmark...'), 0, 0, self, 'mercurial_rename_bookmark') self.hgBookmarkRenameAct.setStatusTip(self.tr( 'Rename a bookmark of the project' )) self.hgBookmarkRenameAct.setWhatsThis(self.tr( """Rename bookmark""" """

This renames a bookmark of the project.

""" )) self.hgBookmarkRenameAct.triggered.connect(self.__hgBookmarkRename) self.actions.append(self.hgBookmarkRenameAct) self.hgBookmarkMoveAct = E5Action( self.tr('Move bookmark'), UI.PixmapCache.getIcon("moveBookmark.png"), self.tr('Move bookmark...'), 0, 0, self, 'mercurial_move_bookmark') self.hgBookmarkMoveAct.setStatusTip(self.tr( 'Move a bookmark of the project' )) self.hgBookmarkMoveAct.setWhatsThis(self.tr( """Move bookmark""" """

This moves a bookmark of the project to another""" """ changeset.

""" )) self.hgBookmarkMoveAct.triggered.connect(self.__hgBookmarkMove) self.actions.append(self.hgBookmarkMoveAct) self.hgBookmarkIncomingAct = E5Action( self.tr('Show incoming bookmarks'), UI.PixmapCache.getIcon("incomingBookmark.png"), self.tr('Show incoming bookmarks'), 0, 0, self, 'mercurial_incoming_bookmarks') self.hgBookmarkIncomingAct.setStatusTip(self.tr( 'Show a list of incoming bookmarks' )) self.hgBookmarkIncomingAct.setWhatsThis(self.tr( """Show incoming bookmarks""" """

This shows a list of new bookmarks available at the remote""" """ repository.

""" )) self.hgBookmarkIncomingAct.triggered.connect( self.__hgBookmarkIncoming) self.actions.append(self.hgBookmarkIncomingAct) self.hgBookmarkPullAct = E5Action( self.tr('Pull bookmark'), UI.PixmapCache.getIcon("pullBookmark.png"), self.tr('Pull bookmark'), 0, 0, self, 'mercurial_pull_bookmark') self.hgBookmarkPullAct.setStatusTip(self.tr( 'Pull a bookmark from a remote repository' )) self.hgBookmarkPullAct.setWhatsThis(self.tr( """Pull bookmark""" """

This pulls a bookmark from a remote repository into the """ """local repository.

""" )) self.hgBookmarkPullAct.triggered.connect(self.__hgBookmarkPull) self.actions.append(self.hgBookmarkPullAct) self.hgBookmarkOutgoingAct = E5Action( self.tr('Show outgoing bookmarks'), UI.PixmapCache.getIcon("outgoingBookmark.png"), self.tr('Show outgoing bookmarks'), 0, 0, self, 'mercurial_outgoing_bookmarks') self.hgBookmarkOutgoingAct.setStatusTip(self.tr( 'Show a list of outgoing bookmarks' )) self.hgBookmarkOutgoingAct.setWhatsThis(self.tr( """Show outgoing bookmarks""" """

This shows a list of new bookmarks available at the local""" """ repository.

""" )) self.hgBookmarkOutgoingAct.triggered.connect( self.__hgBookmarkOutgoing) self.actions.append(self.hgBookmarkOutgoingAct) self.hgBookmarkPushAct = E5Action( self.tr('Push bookmark'), UI.PixmapCache.getIcon("pushBookmark.png"), self.tr('Push bookmark'), 0, 0, self, 'mercurial_push_bookmark') self.hgBookmarkPushAct.setStatusTip(self.tr( 'Push a bookmark to a remote repository' )) self.hgBookmarkPushAct.setWhatsThis(self.tr( """Push bookmark""" """

This pushes a bookmark from the local repository to a """ """remote repository.

""" )) self.hgBookmarkPushAct.triggered.connect(self.__hgBookmarkPush) self.actions.append(self.hgBookmarkPushAct) def __checkActions(self): """ Private slot to set the enabled status of actions. """ self.hgPullAct.setEnabled(self.vcs.canPull()) self.hgIncomingAct.setEnabled(self.vcs.canPull()) self.hgBookmarkPullAct.setEnabled(self.vcs.canPull()) self.hgBookmarkIncomingAct.setEnabled(self.vcs.canPull()) self.hgPushAct.setEnabled(self.vcs.canPush()) self.hgPushBranchAct.setEnabled(self.vcs.canPush()) self.hgPushForcedAct.setEnabled(self.vcs.canPush()) self.hgOutgoingAct.setEnabled(self.vcs.canPush()) self.hgBookmarkPushAct.setEnabled(self.vcs.canPush()) self.hgBookmarkOutgoingAct.setEnabled(self.vcs.canPush()) def initMenu(self, menu): """ Public method to generate the VCS menu. @param menu reference to the menu to be populated (QMenu) """ menu.clear() self.subMenus = [] adminMenu = QMenu(self.tr("Administration"), menu) adminMenu.setTearOffEnabled(True) adminMenu.addAction(self.hgHeadsAct) adminMenu.addAction(self.hgParentsAct) adminMenu.addAction(self.hgTipAct) adminMenu.addAction(self.hgShowBranchAct) adminMenu.addAction(self.hgIdentifyAct) adminMenu.addSeparator() adminMenu.addAction(self.hgShowPathsAct) adminMenu.addSeparator() adminMenu.addAction(self.hgShowConfigAct) adminMenu.addAction(self.hgRepoConfigAct) adminMenu.addSeparator() adminMenu.addAction(self.hgCreateIgnoreAct) adminMenu.addSeparator() adminMenu.addAction(self.hgRecoverAct) adminMenu.addSeparator() adminMenu.addAction(self.hgBackoutAct) adminMenu.addAction(self.hgRollbackAct) adminMenu.addSeparator() adminMenu.addAction(self.hgVerifyAct) self.subMenus.append(adminMenu) specialsMenu = QMenu(self.tr("Specials"), menu) specialsMenu.setTearOffEnabled(True) specialsMenu.addAction(self.hgArchiveAct) specialsMenu.addSeparator() specialsMenu.addAction(self.hgPushForcedAct) specialsMenu.addSeparator() specialsMenu.addAction(self.hgServeAct) self.subMenus.append(specialsMenu) bundleMenu = QMenu(self.tr("Changegroup Management"), menu) bundleMenu.setTearOffEnabled(True) bundleMenu.addAction(self.hgBundleAct) bundleMenu.addAction(self.hgPreviewBundleAct) bundleMenu.addAction(self.hgUnbundleAct) self.subMenus.append(bundleMenu) patchMenu = QMenu(self.tr("Patch Management"), menu) patchMenu.setTearOffEnabled(True) patchMenu.addAction(self.hgImportAct) patchMenu.addAction(self.hgExportAct) self.subMenus.append(patchMenu) bisectMenu = QMenu(self.tr("Bisect"), menu) bisectMenu.setTearOffEnabled(True) bisectMenu.addAction(self.hgBisectGoodAct) bisectMenu.addAction(self.hgBisectBadAct) bisectMenu.addAction(self.hgBisectSkipAct) bisectMenu.addAction(self.hgBisectResetAct) self.subMenus.append(bisectMenu) tagsMenu = QMenu(self.tr("Tags"), menu) tagsMenu.setIcon(UI.PixmapCache.getIcon("vcsTag.png")) tagsMenu.setTearOffEnabled(True) tagsMenu.addAction(self.vcsTagAct) tagsMenu.addAction(self.hgTagListAct) self.subMenus.append(tagsMenu) branchesMenu = QMenu(self.tr("Branches"), menu) branchesMenu.setIcon(UI.PixmapCache.getIcon("vcsBranch.png")) branchesMenu.setTearOffEnabled(True) branchesMenu.addAction(self.hgBranchAct) branchesMenu.addAction(self.hgPushBranchAct) branchesMenu.addAction(self.hgCloseBranchAct) branchesMenu.addAction(self.hgBranchListAct) self.subMenus.append(branchesMenu) bookmarksMenu = QMenu(self.tr("Bookmarks"), menu) bookmarksMenu.setIcon(UI.PixmapCache.getIcon("bookmark22.png")) bookmarksMenu.setTearOffEnabled(True) bookmarksMenu.addAction(self.hgBookmarkDefineAct) bookmarksMenu.addAction(self.hgBookmarkDeleteAct) bookmarksMenu.addAction(self.hgBookmarkRenameAct) bookmarksMenu.addAction(self.hgBookmarkMoveAct) bookmarksMenu.addSeparator() bookmarksMenu.addAction(self.hgBookmarksListAct) bookmarksMenu.addSeparator() bookmarksMenu.addAction(self.hgBookmarkIncomingAct) bookmarksMenu.addAction(self.hgBookmarkPullAct) bookmarksMenu.addSeparator() bookmarksMenu.addAction(self.hgBookmarkOutgoingAct) bookmarksMenu.addAction(self.hgBookmarkPushAct) self.subMenus.append(bookmarksMenu) self.__extensionsMenu = QMenu(self.tr("Extensions"), menu) self.__extensionsMenu.setTearOffEnabled(True) self.__extensionsMenu.aboutToShow.connect(self.__showExtensionMenu) self.extensionMenus = {} for extensionMenuTitle in sorted(self.__extensionMenuTitles): extensionName = self.__extensionMenuTitles[extensionMenuTitle] self.extensionMenus[extensionName] = self.__extensionsMenu.addMenu( self.__extensions[extensionName].initMenu( self.__extensionsMenu)) self.vcs.activeExtensionsChanged.connect(self.__showExtensionMenu) if self.vcs.version >= (2, 0): graftMenu = QMenu(self.tr("Graft"), menu) graftMenu.setIcon(UI.PixmapCache.getIcon("vcsGraft.png")) graftMenu.setTearOffEnabled(True) graftMenu.addAction(self.hgGraftAct) graftMenu.addAction(self.hgGraftContinueAct) else: graftMenu = None subrepoMenu = QMenu(self.tr("Sub-Repository"), menu) subrepoMenu.setTearOffEnabled(True) subrepoMenu.addAction(self.hgAddSubrepoAct) subrepoMenu.addAction(self.hgRemoveSubreposAct) changesMenu = QMenu(self.tr("Manage Changes"), menu) changesMenu.setTearOffEnabled(True) changesMenu.addAction(self.vcsRevertAct) changesMenu.addAction(self.vcsMergeAct) changesMenu.addAction(self.hgShowConflictsAct) changesMenu.addAction(self.vcsResolveAct) changesMenu.addAction(self.hgUnresolveAct) changesMenu.addAction(self.hgReMergeAct) changesMenu.addAction(self.hgCancelMergeAct) act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsMercurial", "icons", "mercurial.png")), self.vcs.vcsName(), self._vcsInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.hgIncomingAct) menu.addAction(self.hgPullAct) menu.addAction(self.vcsUpdateAct) menu.addSeparator() menu.addAction(self.vcsCommitAct) menu.addAction(self.hgOutgoingAct) menu.addAction(self.hgPushAct) menu.addSeparator() if graftMenu is not None: menu.addMenu(graftMenu) menu.addSeparator() menu.addMenu(bundleMenu) menu.addMenu(patchMenu) menu.addSeparator() menu.addMenu(self.__extensionsMenu) menu.addSeparator() menu.addAction(self.vcsNewAct) menu.addAction(self.vcsExportAct) menu.addSeparator() menu.addMenu(tagsMenu) menu.addMenu(branchesMenu) menu.addMenu(bookmarksMenu) menu.addSeparator() menu.addAction(self.vcsLogAct) menu.addAction(self.hgLogBrowserAct) menu.addSeparator() menu.addAction(self.vcsStatusAct) menu.addAction(self.hgSummaryAct) menu.addSeparator() menu.addAction(self.vcsDiffAct) menu.addAction(self.hgExtDiffAct) menu.addSeparator() if self.vcs.version >= (2, 1): menu.addAction(self.hgPhaseAct) menu.addSeparator() menu.addMenu(changesMenu) menu.addSeparator() menu.addAction(self.vcsSwitchAct) menu.addSeparator() menu.addMenu(subrepoMenu) menu.addSeparator() menu.addMenu(bisectMenu) menu.addSeparator() menu.addAction(self.vcsCleanupAct) menu.addSeparator() menu.addAction(self.vcsCommandAct) menu.addSeparator() menu.addMenu(adminMenu) menu.addMenu(specialsMenu) menu.addSeparator() menu.addAction(self.hgEditUserConfigAct) menu.addAction(self.hgConfigAct) def showMenu(self): """ Public slot called before the vcs menu is shown. """ super(HgProjectHelper, self).showMenu() self.__checkActions() def shutdown(self): """ Public method to perform shutdown actions. """ self.vcs.activeExtensionsChanged.disconnect(self.__showExtensionMenu) self.vcs.iniFileChanged.disconnect(self.__checkActions) # close torn off sub menus for menu in self.subMenus: if menu.isTearOffMenuVisible(): menu.hideTearOffMenu() # close torn off extension menus for extensionName in self.extensionMenus: self.__extensions[extensionName].shutdown() menu = self.extensionMenus[extensionName].menu() if menu.isTearOffMenuVisible(): menu.hideTearOffMenu() if self.__extensionsMenu.isTearOffMenuVisible(): self.__extensionsMenu.hideTearOffMenu() def __showExtensionMenu(self): """ Private slot showing the extensions menu. """ for extensionName in self.extensionMenus: self.extensionMenus[extensionName].setEnabled( self.vcs.isExtensionActive(extensionName)) if not self.extensionMenus[extensionName].isEnabled() and \ self.extensionMenus[extensionName].menu()\ .isTearOffMenuVisible(): self.extensionMenus[extensionName].menu().hideTearOffMenu() def __hgExtendedDiff(self): """ Private slot used to perform a hg diff with the selection of revisions. """ self.vcs.hgExtendedDiff(self.project.ppath) def __hgIncoming(self): """ Private slot used to show the log of changes coming into the repository. """ self.vcs.hgIncoming(self.project.ppath) def __hgOutgoing(self): """ Private slot used to show the log of changes going out of the repository. """ self.vcs.hgOutgoing(self.project.ppath) def __hgPull(self): """ Private slot used to pull changes from a remote repository. """ shouldReopen = self.vcs.hgPull(self.project.ppath) if shouldReopen: res = E5MessageBox.yesNo( self.parent(), self.tr("Pull"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgPush(self): """ Private slot used to push changes to a remote repository. """ self.vcs.hgPush(self.project.ppath) def __hgPushForced(self): """ Private slot used to push changes to a remote repository using the force option. """ self.vcs.hgPush(self.project.ppath, force=True) def __hgHeads(self): """ Private slot used to show the heads of the repository. """ self.vcs.hgInfo(self.project.ppath, mode="heads") def __hgParents(self): """ Private slot used to show the parents of the repository. """ self.vcs.hgInfo(self.project.ppath, mode="parents") def __hgTip(self): """ Private slot used to show the tip of the repository. """ self.vcs.hgInfo(self.project.ppath, mode="tip") def __hgResolved(self): """ Private slot used to mark conflicts of the local project as being resolved. """ self.vcs.hgResolved(self.project.ppath) def __hgUnresolved(self): """ Private slot used to mark conflicts of the local project as being unresolved. """ self.vcs.hgResolved(self.project.ppath, unresolve=True) def __hgCancelMerge(self): """ Private slot used to cancel an uncommitted merge. """ self.vcs.hgCancelMerge(self.project.ppath) def __hgShowConflicts(self): """ Private slot used to list all files with conflicts. """ self.vcs.hgConflicts(self.project.ppath) def __hgReMerge(self): """ Private slot used to list all files with conflicts. """ self.vcs.hgReMerge(self.project.ppath) def __hgTagList(self): """ Private slot used to list the tags of the project. """ self.vcs.hgListTagBranch(self.project.ppath, True) def __hgBranchList(self): """ Private slot used to list the branches of the project. """ self.vcs.hgListTagBranch(self.project.ppath, False) def __hgBranch(self): """ Private slot used to create a new branch for the project. """ self.vcs.hgBranch(self.project.ppath) def __hgShowBranch(self): """ Private slot used to show the current branch for the project. """ self.vcs.hgShowBranch(self.project.ppath) def __hgConfigure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences("zzz_mercurialPage") def __hgCloseBranch(self): """ Private slot used to close the current branch of the local project. """ if Preferences.getVCS("AutoSaveProject"): self.project.saveProject() if Preferences.getVCS("AutoSaveFiles"): self.project.saveAllScripts() self.vcs.vcsCommit(self.project.ppath, '', closeBranch=True) def __hgPushNewBranch(self): """ Private slot to push a new named branch. """ self.vcs.hgPush(self.project.ppath, newBranch=True) def __hgEditUserConfig(self): """ Private slot used to edit the user configuration file. """ self.vcs.hgEditUserConfig() def __hgEditRepoConfig(self): """ Private slot used to edit the repository configuration file. """ self.vcs.hgEditConfig(self.project.ppath) def __hgShowConfig(self): """ Private slot used to show the combined configuration. """ self.vcs.hgShowConfig(self.project.ppath) def __hgVerify(self): """ Private slot used to verify the integrity of the repository. """ self.vcs.hgVerify(self.project.ppath) def __hgShowPaths(self): """ Private slot used to show the aliases for remote repositories. """ self.vcs.hgShowPaths(self.project.ppath) def __hgRecover(self): """ Private slot used to recover from an interrupted transaction. """ self.vcs.hgRecover(self.project.ppath) def __hgIdentify(self): """ Private slot used to identify the project directory. """ self.vcs.hgIdentify(self.project.ppath) def __hgCreateIgnore(self): """ Private slot used to create a .hgignore file for the project. """ self.vcs.hgCreateIgnoreFile(self.project.ppath, autoAdd=True) def __hgBundle(self): """ Private slot used to create a changegroup file. """ self.vcs.hgBundle(self.project.ppath) def __hgPreviewBundle(self): """ Private slot used to preview a changegroup file. """ self.vcs.hgPreviewBundle(self.project.ppath) def __hgUnbundle(self): """ Private slot used to apply changegroup files. """ shouldReopen = self.vcs.hgUnbundle(self.project.ppath) if shouldReopen: res = E5MessageBox.yesNo( self.parent(), self.tr("Apply changegroups"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgBisectGood(self): """ Private slot used to execute the bisect --good command. """ self.vcs.hgBisect(self.project.ppath, "good") def __hgBisectBad(self): """ Private slot used to execute the bisect --bad command. """ self.vcs.hgBisect(self.project.ppath, "bad") def __hgBisectSkip(self): """ Private slot used to execute the bisect --skip command. """ self.vcs.hgBisect(self.project.ppath, "skip") def __hgBisectReset(self): """ Private slot used to execute the bisect --reset command. """ self.vcs.hgBisect(self.project.ppath, "reset") def __hgBackout(self): """ Private slot used to back out changes of a changeset. """ self.vcs.hgBackout(self.project.ppath) def __hgRollback(self): """ Private slot used to rollback the last transaction. """ self.vcs.hgRollback(self.project.ppath) def __hgServe(self): """ Private slot used to serve the project. """ self.vcs.hgServe(self.project.ppath) def __hgImport(self): """ Private slot used to import a patch file. """ shouldReopen = self.vcs.hgImport(self.project.ppath) if shouldReopen: res = E5MessageBox.yesNo( self.parent(), self.tr("Import Patch"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgExport(self): """ Private slot used to export revisions to patch files. """ self.vcs.hgExport(self.project.ppath) def __hgRevert(self): """ Private slot used to revert changes made to the local project. """ shouldReopen = self.vcs.hgRevert(self.project.ppath) if shouldReopen: res = E5MessageBox.yesNo( self.parent(), self.tr("Revert Changes"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgPhase(self): """ Private slot used to change the phase of revisions. """ self.vcs.hgPhase(self.project.ppath) def __hgGraft(self): """ Private slot used to copy changesets from another branch. """ shouldReopen = self.vcs.hgGraft(self.project.getProjectPath()) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Copy Changesets"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgGraftContinue(self): """ Private slot used to continue the last copying session after conflicts were resolved. """ shouldReopen = self.vcs.hgGraftContinue(self.project.getProjectPath()) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Copy Changesets (Continue)"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgAddSubrepository(self): """ Private slot used to add a sub-repository. """ self.vcs.hgAddSubrepository() def __hgRemoveSubrepositories(self): """ Private slot used to remove sub-repositories. """ self.vcs.hgRemoveSubrepositories() def __hgSummary(self): """ Private slot to show a working directory summary. """ self.vcs.hgSummary() def __hgArchive(self): """ Private slot to create an unversioned archive from the repository. """ self.vcs.hgArchive() def __hgBookmarksList(self): """ Private slot used to list the bookmarks. """ self.vcs.hgListBookmarks(self.project.getProjectPath()) def __hgBookmarkDefine(self): """ Private slot used to define a bookmark. """ self.vcs.hgBookmarkDefine(self.project.getProjectPath()) def __hgBookmarkDelete(self): """ Private slot used to delete a bookmark. """ self.vcs.hgBookmarkDelete(self.project.getProjectPath()) def __hgBookmarkRename(self): """ Private slot used to rename a bookmark. """ self.vcs.hgBookmarkRename(self.project.getProjectPath()) def __hgBookmarkMove(self): """ Private slot used to move a bookmark. """ self.vcs.hgBookmarkMove(self.project.getProjectPath()) def __hgBookmarkIncoming(self): """ Private slot used to show a list of incoming bookmarks. """ self.vcs.hgBookmarkIncoming(self.project.getProjectPath()) def __hgBookmarkOutgoing(self): """ Private slot used to show a list of outgoing bookmarks. """ self.vcs.hgBookmarkOutgoing(self.project.getProjectPath()) def __hgBookmarkPull(self): """ Private slot used to pull a bookmark from a remote repository. """ self.vcs.hgBookmarkPull(self.project.getProjectPath()) def __hgBookmarkPush(self): """ Private slot used to push a bookmark to a remote repository. """ self.vcs.hgBookmarkPush(self.project.getProjectPath()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgAnnotateDialog.ui0000644000175000017500000001114612060166053024333 0ustar piotrpiotr HgAnnotateDialog 0 0 690 750 Mercurial Annotate true 0 6 true QAbstractItemView::NoSelection false false false Revision Changeset Author Date Line 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close annotateList errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgLogDialog.py0000644000175000017500000004765412451233372023336 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the hg log command process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, QProcess, QTimer, QUrl, QByteArray, \ qVersion from PyQt5.QtGui import QTextCursor from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QApplication, QLineEdit from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .Ui_HgLogDialog import Ui_HgLogDialog import Utilities class HgLogDialog(QWidget, Ui_HgLogDialog): """ Class implementing a dialog to show the output of the hg log command process. The dialog is nonmodal. Clicking a link in the upper text pane shows a diff of the revisions. """ def __init__(self, vcs, mode="log", bundle=None, isFile=False, parent=None): """ Constructor @param vcs reference to the vcs object @param mode mode of the dialog (string; one of log, incoming, outgoing) @param bundle name of a bundle file (string) @param isFile flag indicating log for a file is to be shown (boolean) @param parent parent widget (QWidget) """ super(HgLogDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.process = QProcess() self.vcs = vcs if mode in ("log", "incoming", "outgoing"): self.mode = mode else: self.mode = "log" self.bundle = bundle self.__hgClient = self.vcs.getClient() self.contents.setHtml( self.tr('Processing your request, please wait...')) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.contents.anchorClicked.connect(self.__sourceChanged) self.revisions = [] # stack of remembered revisions self.revString = self.tr('Revision') self.projectMode = False self.logEntries = [] # list of log entries self.lastLogEntry = {} self.fileCopies = {} self.endInitialText = False self.initialText = [] self.diff = None self.sbsCheckBox.setEnabled(isFile) self.sbsCheckBox.setVisible(isFile) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, fn, noEntries=0, revisions=None): """ Public slot to start the hg log command. @param fn filename to show the log for (string) @param noEntries number of entries to show (integer) @param revisions revisions to show log for (list of strings) """ self.errorGroup.hide() QApplication.processEvents() self.intercept = False self.filename = fn self.dname, self.fname = self.vcs.splitPath(fn) # find the root of the repo self.repodir = self.dname while not os.path.isdir(os.path.join(self.repodir, self.vcs.adminDir)): self.repodir = os.path.dirname(self.repodir) if os.path.splitdrive(self.repodir)[1] == os.sep: return self.projectMode = (self.fname == "." and self.dname == self.repodir) self.activateWindow() self.raise_() preargs = [] args = self.vcs.initCommand(self.mode) if noEntries and self.mode == "log": args.append('--limit') args.append(str(noEntries)) if self.mode in ("incoming", "outgoing"): args.append("--newest-first") if self.vcs.hasSubrepositories(): args.append("--subrepos") if self.mode == "log": args.append('--copies') if self.vcs.version >= (3, 0): args.append('--template') args.append(os.path.join(os.path.dirname(__file__), "templates", "logDialogBookmarkPhase.tmpl")) else: args.append('--style') if self.vcs.version >= (2, 1): args.append(os.path.join(os.path.dirname(__file__), "styles", "logDialogBookmarkPhase.style")) else: args.append(os.path.join(os.path.dirname(__file__), "styles", "logDialogBookmark.style")) if self.mode == "incoming": if self.bundle: args.append(self.bundle) elif not self.vcs.hasSubrepositories(): project = e5App().getObject("Project") self.vcs.bundleFile = os.path.join( project.getProjectManagementDir(), "hg-bundle.hg") if os.path.exists(self.vcs.bundleFile): os.remove(self.vcs.bundleFile) preargs = args[:] preargs.append("--quiet") preargs.append('--bundle') preargs.append(self.vcs.bundleFile) args.append(self.vcs.bundleFile) if revisions: for rev in revisions: args.append("--rev") args.append(rev) if not self.projectMode: args.append(self.filename) if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() if preargs: out, err = self.__hgClient.runcommand(preargs) else: err = "" if err: self.__showError(err) elif self.mode != "incoming" or \ (self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile)) or \ self.bundle: out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out and self.isVisible(): for line in out.splitlines(True): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(self.repodir) if preargs: process = QProcess() process.setWorkingDirectory(self.repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: process.waitForFinished(30000) if self.mode != "incoming" or \ (self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile)) or \ self.bundle: self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.__finish() def __getParents(self, rev): """ Private method to get the parents of the currently viewed file/directory. @param rev revision number to get parents for (string) @return list of parent revisions (list of strings) """ errMsg = "" parents = [] if int(rev) > 0: args = self.vcs.initCommand("parents") if self.mode == "incoming": if self.bundle: args.append("--repository") args.append(self.bundle) elif self.vcs.bundleFile and \ os.path.exists(self.vcs.bundleFile): args.append("--repository") args.append(self.vcs.bundleFile) args.append("--template") args.append("{rev}:{node|short}\n") args.append("-r") args.append(rev) if not self.projectMode: args.append(self.filename) output = "" if self.__hgClient: output, errMsg = self.__hgClient.runcommand(args) else: process = QProcess() process.setWorkingDirectory(self.repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') else: if not finished: errMsg = self.tr( "The hg process did not finish within 30s.") else: errMsg = self.tr("Could not start the hg executable.") if errMsg: E5MessageBox.critical( self, self.tr("Mercurial Error"), errMsg) if output: parents = [p for p in output.strip().splitlines()] return parents def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ self.inputGroup.setEnabled(False) self.inputGroup.hide() self.contents.clear() if not self.logEntries: self.errors.append(self.tr("No log available for '{0}'") .format(self.filename)) self.errorGroup.show() return html = "" if self.initialText: for line in self.initialText: html += Utilities.html_encode(line.strip()) html += '
\n' html += '{0}
\n'.format(80 * "=") for entry in self.logEntries: fileCopies = {} if entry["file_copies"]: for fentry in entry["file_copies"].split(", "): newName, oldName = fentry[:-1].split(" (") fileCopies[newName] = oldName rev, hexRev = entry["change"].split(":") dstr = '

{0} {1}'.format(self.revString, entry["change"]) if entry["parents"]: parents = entry["parents"].split() else: parents = self.__getParents(rev) for parent in parents: url = QUrl() url.setScheme("file") url.setPath(self.filename) if qVersion() >= "5.0.0": query = parent.split(":")[0] + '_' + rev url.setQuery(query) else: query = QByteArray() query.append(parent.split(":")[0]).append('_').append(rev) url.setEncodedQuery(query) dstr += ' [{2}]'.format( url.toString(), query, self.tr('diff to {0}').format(parent), ) dstr += '
\n' html += dstr if "phase" in entry: html += self.tr("Phase: {0}
\n")\ .format(entry["phase"]) html += self.tr("Branch: {0}
\n")\ .format(entry["branches"]) html += self.tr("Tags: {0}
\n").format(entry["tags"]) if "bookmarks" in entry: html += self.tr("Bookmarks: {0}
\n")\ .format(entry["bookmarks"]) html += self.tr("Parents: {0}
\n")\ .format(entry["parents"]) html += self.tr('Author: {0}
\n')\ .format(Utilities.html_encode(entry["user"])) date, time = entry["date"].split()[:2] html += self.tr('Date: {0}, {1}
\n')\ .format(date, time) for line in entry["description"]: html += Utilities.html_encode(line.strip()) html += '
\n' if entry["file_adds"]: html += '
\n' for f in entry["file_adds"].strip().split(", "): if f in fileCopies: html += self.tr( 'Added {0} (copied from {1})
\n')\ .format(Utilities.html_encode(f), Utilities.html_encode(fileCopies[f])) else: html += self.tr('Added {0}
\n')\ .format(Utilities.html_encode(f)) if entry["files_mods"]: html += '
\n' for f in entry["files_mods"].strip().split(", "): html += self.tr('Modified {0}
\n')\ .format(Utilities.html_encode(f)) if entry["file_dels"]: html += '
\n' for f in entry["file_dels"].strip().split(", "): html += self.tr('Deleted {0}
\n')\ .format(Utilities.html_encode(f)) html += '

{0}
\n'.format(60 * "=") self.contents.setHtml(html) tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process and inserts it into a buffer. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.vcs.getEncoding(), 'replace') self.__processOutputLine(s) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ if line == "@@@\n": self.logEntries.append(self.lastLogEntry) self.lastLogEntry = {} self.fileCopies = {} else: try: key, value = line.split("|", 1) except ValueError: key = "" value = line if key == "change": self.endInitialText = True if key in ("change", "tags", "parents", "user", "date", "file_copies", "file_adds", "files_mods", "file_dels", "bookmarks", "phase"): self.lastLogEntry[key] = value.strip() elif key == "branches": if value.strip(): self.lastLogEntry[key] = value.strip() else: self.lastLogEntry[key] = "default" elif key == "description": self.lastLogEntry[key] = [value.strip()] else: if self.endInitialText: self.lastLogEntry["description"].append(value.strip()) else: self.initialText.append(value) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def __sourceChanged(self, url): """ Private slot to handle the sourceChanged signal of the contents pane. @param url the url that was clicked (QUrl) """ filename = url.path() if Utilities.isWindowsPlatform(): if filename.startswith("/"): filename = filename[1:] if qVersion() >= "5.0.0": ver = url.query() else: ver = bytes(url.encodedQuery()).decode() v1, v2 = ver.split('_') if v1 == "" or v2 == "": return self.contents.scrollToAnchor(ver) if self.sbsCheckBox.isEnabled() and self.sbsCheckBox.isChecked(): self.vcs.hgSbsDiff(filename, revisions=(v1, v2)) else: if self.diff is None: from .HgDiffDialog import HgDiffDialog self.diff = HgDiffDialog(self.vcs) self.diff.show() self.diff.start(filename, [v1, v2], self.bundle) def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the hg process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgLogDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/__init__.py0000644000175000017500000000037712451233372022744 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Package implementing the vcs interface to Mercurial. It consists of the hg class, the project helper classes and some Mercurial specific dialogs. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBranchInputDialog.ui0000644000175000017500000000451612307125304025000 0ustar piotrpiotr HgBranchInputDialog 0 0 400 128 Create Branch true Enter branch name: Enter the new branch name (spaces will be converted to _) true Select to commit the branch Commit Branch Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok branchComboBox commitCheckBox buttonBox buttonBox accepted() HgBranchInputDialog accept() 248 254 157 274 buttonBox rejected() HgBranchInputDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgRemoveSubrepositoriesDialog.ui0000644000175000017500000000517712060166053027150 0ustar piotrpiotr HgRemoveSubrepositoriesDialog 0 0 500 300 Remove Sub-repositories true true QAbstractItemView::ExtendedSelection false Press to remove the selected entries &Remove Select to delete the removed entries from disc Delete removed entries from disc Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok subrepositories removeButton deleteCheckBox buttonBox buttonBox accepted() HgRemoveSubrepositoriesDialog accept() 248 254 157 274 buttonBox rejected() HgRemoveSubrepositoriesDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgTagBranchListDialog.ui0000644000175000017500000001153112060166053025245 0ustar piotrpiotr HgTagBranchListDialog 0 0 634 494 Mercurial Tag List <b>Mercurial Tag/Branch List</b> <p>This dialog shows a list of the projects tags or branches.</p> true 0 2 <b>Tag/Branches List</b> <p>This shows a list of the projects tags or branches.</p> true false false true Revision Changeset Local Name 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource tagList errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.ui0000644000175000017500000000760512263302470026071 0ustar piotrpiotr HgAddSubrepositoryDialog 0 0 550 142 Add Sub-repository true &Path within Project: pathEdit Enter the path of the sub-repository relative to the project Select the path of the sub-repository with a directory selection dialog &Type: typeCombo Select the type of the sub-repository Qt::Horizontal 40 20 &URL: urlEdit Enter the URL of the sub-repository Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok pathEdit pathButton typeCombo urlEdit buttonBox buttonBox accepted() HgAddSubrepositoryDialog accept() 248 254 157 274 buttonBox rejected() HgAddSubrepositoryDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgOptionsDialog.py0000644000175000017500000000232312451233372024230 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter options used to start a project in the VCS. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_HgOptionsDialog import Ui_HgOptionsDialog class HgOptionsDialog(QDialog, Ui_HgOptionsDialog): """ Class implementing a dialog to enter options used to start a project in the repository. """ def __init__(self, vcs, project, parent=None): """ Constructor @param vcs reference to the version control object @param project reference to the project object @param parent parent widget (QWidget) """ super(HgOptionsDialog, self).__init__(parent) self.setupUi(self) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public slot to retrieve the data entered into the dialog. @return a dictionary containing the data entered """ vcsdatadict = { "message": self.vcsLogEdit.text(), } return vcsdatadict eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgStatusMonitorThread.py0000644000175000017500000001341612451233372025445 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the VCS status monitor thread class for Mercurial. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import QProcess from VCS.StatusMonitorThread import VcsStatusMonitorThread class HgStatusMonitorThread(VcsStatusMonitorThread): """ Class implementing the VCS status monitor thread class for Mercurial. """ def __init__(self, interval, project, vcs, parent=None): """ Constructor @param interval new interval in seconds (integer) @param project reference to the project object (Project) @param vcs reference to the version control object @param parent reference to the parent object (QObject) """ VcsStatusMonitorThread.__init__(self, interval, project, vcs, parent) self.__client = None self.__useCommandLine = False def _performMonitor(self): """ Protected method implementing the monitoring action. This method populates the statusList member variable with a list of strings giving the status in the first column and the path relative to the project directory starting with the third column. The allowed status flags are:
  • "A" path was added but not yet comitted
  • "M" path has local changes
  • "O" path was removed
  • "R" path was deleted and then re-added
  • "U" path needs an update
  • "Z" path contains a conflict
  • " " path is back at normal
@return tuple of flag indicating successful operation (boolean) and a status message in case of non successful operation (string) """ self.shouldUpdate = False if self.__client is None and not self.__useCommandLine: if self.vcs.version >= (2, 9, 9): # versions below that have a bug causing a second # instance to not recognize changes to the status from .HgClient import HgClient client = HgClient(self.projectDir, "utf-8", self.vcs) ok, err = client.startServer() if ok: self.__client = client else: self.__useCommandLine = True else: self.__useCommandLine = True # step 1: get overall status args = self.vcs.initCommand("status") args.append('--noninteractive') args.append('--all') output = "" error = "" if self.__client: output, error = self.__client.runcommand(args) else: process = QProcess() process.setWorkingDirectory(self.projectDir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(300000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') else: process.kill() process.waitForFinished() error = str(process.readAllStandardError(), self.vcs.getEncoding(), 'replace') else: process.kill() process.waitForFinished() error = self.tr("Could not start the Mercurial process.") if error: return False, error states = {} for line in output.splitlines(): if not line.startswith(" "): flag, name = line.split(" ", 1) if flag in "AMR": if flag == "R": status = "O" else: status = flag states[name] = status # step 2: get conflicting changes args = self.vcs.initCommand("resolve") args.append('--list') output = "" error = "" if self.__client: output, error = self.__client.runcommand(args) else: process.setWorkingDirectory(self.projectDir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(300000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') for line in output.splitlines(): flag, name = line.split(" ", 1) if flag == "U": states[name] = "Z" # conflict # step 3: collect the status to be reported back for name in states: try: if self.reportedStates[name] != states[name]: self.statusList.append( "{0} {1}".format(states[name], name)) except KeyError: self.statusList.append("{0} {1}".format(states[name], name)) for name in self.reportedStates.keys(): if name not in states: self.statusList.append(" {0}".format(name)) self.reportedStates = states return True, \ self.tr("Mercurial status checked successfully") def _shutdown(self): """ Protected method performing shutdown actions. """ if self.__client: self.__client.stopServer() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.ui0000644000175000017500000003475212331456763024672 0ustar piotrpiotr HgLogBrowserDialog 0 0 1000 800 Mercurial Log 0 1 Errors <b>Mercurial log errors</b><p>This shows possible error messages of the hg log command.</p> true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P From: Enter the start date true To: Enter the end date true QFrame::Raised 2 Qt::Vertical Branch: Select the branch to filter on QComboBox::AdjustToContents QFrame::Raised 2 Qt::Vertical Select the field to filter on Revision Author Message Enter the regular expression to filter on 0 7 true QAbstractItemView::ExtendedSelection false false true Graph Branch Revision Phase Author Date Message Tags 2 3 true 0 4 true false false true true Action Path Copy from Press to get the next bunch of log entries &Next Enter the limit of entries to fetch Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 10000 20 QFrame::Raised 2 Qt::Vertical Select to stop listing log messages at a copy or move Stop on Copy/Move Press to generate a diff to the first parent revision Diff to Parent &1 Press to generate a diff to the second parent revision Diff to Parent &2 Press to compare two revisions &Compare Revisions QFrame::Raised 2 Qt::Vertical Qt::Horizontal 38 29 Select to show differences side-by-side Show differences side-by-side Select action from menu QToolButton::InstantPopup Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close 1 3 true E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
fromDate toDate branchCombo fieldCombo rxEdit logTree detailsEdit messageEdit filesTree nextButton limitSpinBox stopCheckBox diffP1Button diffP2Button diffRevisionsButton sbsCheckBox actionsButton errors input passwordCheckBox sendButton buttonBox
eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.py0000644000175000017500000002164412451233372026433 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the revisions for the hg diff command. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgRevisionsSelectionDialog import Ui_HgRevisionsSelectionDialog class HgRevisionsSelectionDialog(QDialog, Ui_HgRevisionsSelectionDialog): """ Class implementing a dialog to enter the revisions for the hg diff command. """ def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None): """ Constructor @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param parent parent widget of the dialog (QWidget) """ super(HgRevisionsSelectionDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.tag1Combo.addItems(sorted(tagsList)) self.tag2Combo.addItems(sorted(tagsList)) self.branch1Combo.addItems(["default"] + sorted(branchesList)) self.branch2Combo.addItems(["default"] + sorted(branchesList)) if bookmarksList is not None: self.bookmark1Combo.addItems(sorted(bookmarksList)) self.bookmark2Combo.addItems(sorted(bookmarksList)) else: self.bookmark1Button.setHidden(True) self.bookmark1Combo.setHidden(True) self.bookmark2Button.setHidden(True) self.bookmark2Combo.setHidden(True) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.id1Button.isChecked(): enabled = enabled and self.id1Edit.text() != "" elif self.tag1Button.isChecked(): enabled = enabled and self.tag1Combo.currentText() != "" elif self.branch1Button.isChecked(): enabled = enabled and self.branch1Combo.currentText() != "" elif self.bookmark1Button.isChecked(): enabled = enabled and self.bookmark1Combo.currentText() != "" if self.id2Button.isChecked(): enabled = enabled and self.id2Edit.text() != "" elif self.tag2Button.isChecked(): enabled = enabled and self.tag2Combo.currentText() != "" elif self.branch2Button.isChecked(): enabled = enabled and self.branch2Combo.currentText() != "" elif self.bookmark2Button.isChecked(): enabled = enabled and self.bookmark2Combo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(bool) def on_id1Button_toggled(self, checked): """ Private slot to handle changes of the ID1 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_id2Button_toggled(self, checked): """ Private slot to handle changes of the ID2 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tag1Button_toggled(self, checked): """ Private slot to handle changes of the Tag1 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tag2Button_toggled(self, checked): """ Private slot to handle changes of the Tag2 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branch1Button_toggled(self, checked): """ Private slot to handle changes of the Branch1 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branch2Button_toggled(self, checked): """ Private slot to handle changes of the Branch2 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmark1Button_toggled(self, checked): """ Private slot to handle changes of the Bookmark1 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmark2Button_toggled(self, checked): """ Private slot to handle changes of the Bookmark2 select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(str) def on_id1Edit_textChanged(self, txt): """ Private slot to handle changes of the ID1 edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_id2Edit_textChanged(self, txt): """ Private slot to handle changes of the ID2 edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_tag1Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag1 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_tag2Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag2 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branch1Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch1 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branch2Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch2 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmark1Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark1 combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmark2Combo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark2 combo. @param txt text of the combo (string) """ self.__updateOK() def __getRevision(self, no): """ Private method to generate the revision. @param no revision number to generate (1 or 2) @return revision (string) """ if no == 1: numberButton = self.number1Button numberSpinBox = self.number1SpinBox idButton = self.id1Button idEdit = self.id1Edit tagButton = self.tag1Button tagCombo = self.tag1Combo branchButton = self.branch1Button branchCombo = self.branch1Combo bookmarkButton = self.bookmark1Button bookmarkCombo = self.bookmark1Combo tipButton = self.tip1Button prevButton = self.prev1Button noneButton = self.none1Button else: numberButton = self.number2Button numberSpinBox = self.number2SpinBox idButton = self.id2Button idEdit = self.id2Edit tagButton = self.tag2Button tagCombo = self.tag2Combo branchButton = self.branch2Button branchCombo = self.branch2Combo bookmarkButton = self.bookmark2Button bookmarkCombo = self.bookmark2Combo tipButton = self.tip2Button prevButton = self.prev2Button noneButton = self.none2Button if numberButton.isChecked(): return "rev({0})".format(numberSpinBox.value()) elif idButton.isChecked(): return "id({0})".format(idEdit.text()) elif tagButton.isChecked(): return tagCombo.currentText() elif branchButton.isChecked(): return branchCombo.currentText() elif bookmarkButton.isChecked(): return bookmarkCombo.currentText() elif tipButton.isChecked(): return "tip" elif prevButton.isChecked(): return "." elif noneButton.isChecked(): return "" def getRevisions(self): """ Public method to get the revisions. @return list two strings """ rev1 = self.__getRevision(1) rev2 = self.__getRevision(2) return [rev1, rev2] eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgPhaseDialog.py0000644000175000017500000000422712451233372023642 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter data for the Mercurial Phase operation. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgPhaseDialog import Ui_HgPhaseDialog class HgPhaseDialog(QDialog, Ui_HgPhaseDialog): """ Class dimplementing a dialog to enter data for the Mercurial Phase operation. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(HgPhaseDialog, self).__init__(parent) self.setupUi(self) self.phaseCombo.addItem("", "") self.phaseCombo.addItem(self.tr("Public"), "p") self.phaseCombo.addItem(self.tr("Draft"), "d") self.phaseCombo.addItem(self.tr("Secret"), "s") self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) def __updateOk(self): """ Private slot to update the state of the OK button. """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( self.revisionsEdit.toPlainText().strip() != "" and self.phaseCombo.currentText().strip() != "") @pyqtSlot() def on_revisionsEdit_textChanged(self): """ Private slot to react upon changes of revisions. """ self.__updateOk() @pyqtSlot(str) def on_phaseCombo_activated(self, txt): """ Private slot to react upon changes of the phase. @param txt activated entry (string) """ self.__updateOk() def getData(self): """ Public method to retrieve the entered data. @return tuple with list of revisions, phase and a flag indicating a forced operation (list of strings, string, boolean) """ return ( self.revisionsEdit.toPlainText().strip().splitlines(), self.phaseCombo.itemData(self.phaseCombo.currentIndex()), self.forceCheckBox.isChecked() ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgUserConfigDataDialog.ui0000644000175000017500000002135312334167221025423 0ustar piotrpiotr HgUserConfigDataDialog 0 0 400 455 Mercurial User Data true User Data First Name: Enter the first name Last Name: Enter the last name Email: Enter the email address Extensions Select to activate the fetch extension Fetch Select to activate the GPG extension GPG Select to activate the largefiles extension Large Files Select to activate the Purge extension Purge Select to activate the queues extension Queues Select to activate the rebase extension Rebase Select to activate the shelve extension Shelve Select to activate the transplant extension Transplant false Large Files Minimum file size: Enter the minimum file size in MB for files to be treated as Large Files Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter MB 1 10 Qt::Horizontal 215 20 Patterns: Enter file patterns (space separated) for files to be treated as Large Files Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
firstNameEdit lastNameEdit emailEdit fetchCheckBox gpgCheckBox largefilesCheckBox purgeCheckBox queuesCheckBox rebaseCheckBox shelveCheckBox transplantCheckBox lfFileSizeSpinBox lfFilePatternsEdit buttonBox buttonBox accepted() HgUserConfigDataDialog accept() 257 378 157 274 buttonBox rejected() HgUserConfigDataDialog reject() 325 378 286 274 largefilesCheckBox toggled(bool) largefilesGroup setEnabled(bool) 225 173 55 276
eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgImportDialog.ui0000644000175000017500000001765712263303074024052 0ustar piotrpiotr HgImportDialog 0 0 500 380 Import Patch true Commit data Select to not commit the imported patch Do not commit true Commit message: false Enter the commit message or leave empty to use the default one true Commit Date: false Enter optional date for the commit yyyy-MM-dd HH:mm false Qt::Horizontal 40 20 Commit User: false Enter optional user for the commit Strip Count: Enter number of leading directories to strip off (default 1) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 9 1 Qt::Horizontal 118 20 Patch File: Enter the name of the patch file Press to select the patch file via a file selection dialog Select to enforce the import Enforce Import Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok noCommitCheckBox messageEdit dateEdit userEdit stripSpinBox patchFileEdit patchFileButton forceCheckBox buttonBox buttonBox accepted() HgImportDialog accept() 257 364 157 274 buttonBox rejected() HgImportDialog reject() 325 364 286 274 noCommitCheckBox toggled(bool) messageEdit setDisabled(bool) 70 44 95 113 noCommitCheckBox toggled(bool) dateEdit setDisabled(bool) 121 41 134 202 noCommitCheckBox toggled(bool) userEdit setDisabled(bool) 228 48 230 229 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/styles/0000755000175000017500000000000012334163310022141 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/styles/logDialogBookmark.style0000644000175000017500000000121112060166053026610 0ustar piotrpiotrchangeset = 'change|{rev}:{node|short}\nbranches|{branches}\ntags|{tags}\nparents|{parents}\nuser|{author}\ndate|{date|isodate}\ndescription|{desc}\nfile_copies|{file_copies}\nfile_adds|{file_adds}\nfiles_mods|{file_mods}\nfile_dels|{file_dels}\nbookmarks|{bookmarks}\n@@@\n' file_mod = '{file_mod}, ' last_file_mod = '{file_mod}' file_add = '{file_add}, ' last_file_add = '{file_add}' file_del = '{file_del}, ' last_file_del = '{file_del}' file_copy = '{name} ({source}), ' last_file_copy = '{name} ({source})' tag = '{tag}, ' last_tag = '{tag}' branch = '{branch}, ' last_branch = '{branch}' bookmark = '{bookmark}, ' last_bookmark = '{bookmark}' eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/styles/logBrowserBookmark.style0000644000175000017500000000121712060166053027042 0ustar piotrpiotrchangeset = 'change|{rev}:{node|short}\nuser|{author|email}\nparents|{parents}\ndate|{date|isodate}\ndescription|{desc}\nfile_copies|{file_copies}\nfile_adds|{file_adds}\nfiles_mods|{file_mods}\nfile_dels|{file_dels}\nbranches|{branches}\ntags|{tags}\nbookmarks|{bookmarks}\n@@@\n' file_mod = '{file_mod}, ' last_file_mod = '{file_mod}' file_add = '{file_add}, ' last_file_add = '{file_add}' file_del = '{file_del}, ' last_file_del = '{file_del}' file_copy = '{name} ({source}), ' last_file_copy = '{name} ({source})' tag = '{tag}, ' last_tag = '{tag}' branch = '{branch}, ' last_branch = '{branch}' bookmark = '{bookmark}, ' last_bookmark = '{bookmark}' eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/styles/logBrowserBookmarkPhase.style0000644000175000017500000000123612060166053030024 0ustar piotrpiotrchangeset = 'change|{rev}:{node|short}\nuser|{author|email}\nparents|{parents}\ndate|{date|isodate}\ndescription|{desc}\nfile_copies|{file_copies}\nfile_adds|{file_adds}\nfiles_mods|{file_mods}\nfile_dels|{file_dels}\nbranches|{branches}\ntags|{tags}\nbookmarks|{bookmarks}\nphase|{phase}\n@@@\n' file_mod = '{file_mod}, ' last_file_mod = '{file_mod}' file_add = '{file_add}, ' last_file_add = '{file_add}' file_del = '{file_del}, ' last_file_del = '{file_del}' file_copy = '{name} ({source}), ' last_file_copy = '{name} ({source})' tag = '{tag}, ' last_tag = '{tag}' branch = '{branch}, ' last_branch = '{branch}' bookmark = '{bookmark}, ' last_bookmark = '{bookmark}' eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/styles/logDialogBookmarkPhase.style0000644000175000017500000000123012060166053027572 0ustar piotrpiotrchangeset = 'change|{rev}:{node|short}\nbranches|{branches}\ntags|{tags}\nparents|{parents}\nuser|{author}\ndate|{date|isodate}\ndescription|{desc}\nfile_copies|{file_copies}\nfile_adds|{file_adds}\nfiles_mods|{file_mods}\nfile_dels|{file_dels}\nbookmarks|{bookmarks}\nphase|{phase}\n@@@\n' file_mod = '{file_mod}, ' last_file_mod = '{file_mod}' file_add = '{file_add}, ' last_file_add = '{file_add}' file_del = '{file_del}, ' last_file_del = '{file_del}' file_copy = '{name} ({source}), ' last_file_copy = '{name} ({source})' tag = '{tag}, ' last_tag = '{tag}' branch = '{branch}, ' last_branch = '{branch}' bookmark = '{bookmark}, ' last_bookmark = '{bookmark}' eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.py0000644000175000017500000001441412451233372024162 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the archive data. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QFileInfo from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter, E5DirCompleter from E5Gui import E5FileDialog from .Ui_HgArchiveDialog import Ui_HgArchiveDialog import Utilities import UI.PixmapCache class HgArchiveDialog(QDialog, Ui_HgArchiveDialog): """ Class implementing a dialog to enter the archive data. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the Mercurial object (Hg) @param parent reference to the parent widget (QWidget) """ super(HgArchiveDialog, self).__init__(parent) self.setupUi(self) self.archiveButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.__archiveFileCompleter = E5FileCompleter() self.__archiveDirCompleter = E5DirCompleter() self.__activeCompleter = self.__archiveFileCompleter self.archiveEdit.setCompleter(self.__activeCompleter) self.__activeCompleter.model().setNameFilters([]) self.typeComboBox.addItem( self.tr("Detect Automatically"), "") self.typeComboBox.addItem( self.tr("Directory of Files"), "files") self.typeComboBox.addItem( self.tr("Uncompressed TAR-Archive"), "tar") self.typeComboBox.addItem( self.tr("Bzip2 compressed TAR-Archive"), "tbz2") self.typeComboBox.addItem( self.tr("Gzip compressed TAR-Archive"), "tgz") self.typeComboBox.addItem( self.tr("Uncompressed ZIP-Archive"), "uzip") self.typeComboBox.addItem( self.tr("Compressed ZIP-Archive"), "zip") self.__unixFileFilters = [ self.tr("Bzip2 compressed TAR-Archive (*.tar.bz2)"), self.tr("Gzip compressed TAR-Archive (*.tar.gz)"), self.tr("Uncompressed TAR-Archive (*.tar)"), ] self.__windowsFileFilters = [ self.tr("Compressed ZIP-Archive (*.zip)"), self.tr("Uncompressed ZIP-Archive (*.uzip)") ] if Utilities.isWindowsPlatform(): self.__fileFilters = ";;".join( self.__windowsFileFilters + self.__unixFileFilters) else: self.__fileFilters = ";;".join( self.__unixFileFilters + self.__windowsFileFilters) self.__fileFilters += ";;" + self.tr("All Files (*)") self.__typeFilters = { "tar": ["*.tar"], "tbz2": ["*.tar.bz2", "*.tbz2"], "tgz": ["*.tar.gz", "*.tgz"], "uzip": ["*.uzip", "*.zip"], "zip": ["*.zip"], } self.subReposCheckBox.setEnabled(vcs.hasSubrepositories()) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.__projectPath = \ vcs.getPlugin().getProjectHelper().getProject().getProjectPath() msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_archiveEdit_textChanged(self, archive): """ Private slot to handle changes of the archive name. @param archive name of the archive (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(archive != "") @pyqtSlot() def on_archiveButton_clicked(self): """ Private slot to select the archive name via a file selection dialog. """ type_ = self.typeComboBox.itemData(self.typeComboBox.currentIndex()) archive = Utilities.fromNativeSeparators(self.archiveEdit.text()) if not archive: archive = self.__projectPath if type_ == "files": archive = E5FileDialog.getExistingDirectory( self, self.tr("Select Archive Directory"), archive, E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) else: archive, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Select Archive File"), archive, self.__fileFilters, None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if archive: ext = QFileInfo(archive).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: archive += ex if archive: self.archiveEdit.setText(Utilities.toNativeSeparators(archive)) @pyqtSlot(int) def on_typeComboBox_activated(self, index): """ Private slot to react on changes of the selected archive type. @param index index of the selected type (integer) """ type_ = self.typeComboBox.itemData(index) if type_ == "files": if self.__activeCompleter != self.__archiveDirCompleter: self.__activeCompleter = self.__archiveDirCompleter self.archiveEdit.setCompleter(self.__activeCompleter) else: if self.__activeCompleter != self.__archiveFileCompleter: self.__activeCompleter = self.__archiveFileCompleter self.archiveEdit.setCompleter(self.__activeCompleter) if type_ in self.__typeFilters: self.__activeCompleter.model().setNameFilters( self.__typeFilters[type_]) else: self.__activeCompleter.model().setNameFilters([]) def getData(self): """ Public method to retrieve the data. @return tuple giving the archive name (string), the archive type (string), the directory prefix 8string) and a flag indicating to recurse into subrepositories (boolean) """ return ( self.archiveEdit.text(), self.typeComboBox.itemData(self.typeComboBox.currentIndex()), self.prefixEdit.text(), self.subReposCheckBox.isChecked(), ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgTagDialog.ui0000644000175000017500000001324312354033515023277 0ustar piotrpiotr HgTagDialog 0 0 391 255 Mercurial Tag true Name: 0 0 Enter the name of the tag <b>Tag Name</b> <p>Enter the name of the tag to be created, moved or deleted.</p> true false Revision: Enter a revision to set a tag for Tag Action Select to create a tag <b>Create Tag</b> <p>Select this entry in order to create a tag.</p> Create Tag true Select to delete a tag <b>Delete Tag</b> <p>Select this entry in order to delete the selected tag.</p> Delete Tag Tag Type Select to create/delete a global tag Global Tag true Select to create/delete a local tag Local Tag Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource tagCombo revisionEdit createTagButton deleteTagButton globalTagButton localTagButton buttonBox buttonBox accepted() HgTagDialog accept() 94 226 25 214 buttonBox rejected() HgTagDialog reject() 131 226 128 210 deleteTagButton toggled(bool) revisionEdit setDisabled(bool) 145 164 137 49 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgUtilities.py0000644000175000017500000000245612451233372023437 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing some common utility functions for the Mercurial package. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QProcessEnvironment import Utilities def getConfigPath(): """ Public function to get the filename of the config file. @return filename of the config file (string) """ if Utilities.isWindowsPlatform(): userprofile = os.environ["USERPROFILE"] return os.path.join(userprofile, "Mercurial.ini") else: homedir = Utilities.getHomeDir() return os.path.join(homedir, ".hgrc") def prepareProcess(proc, encoding="", language=""): """ Public function to prepare the given process. @param proc reference to the proces to be prepared (QProcess) @param encoding encoding to be used by the process (string) @param language language to be set (string) """ env = QProcessEnvironment.systemEnvironment() env.insert("HGPLAIN", '1') # set the encoding for the process if encoding: env.insert("HGENCODING", encoding) # set the language for the process if language: env.insert("LANGUAGE", language) proc.setProcessEnvironment(env) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBookmarkRenameDialog.ui0000644000175000017500000000524412334163447025471 0ustar piotrpiotr HgBookmarkRenameDialog 0 0 400 102 Rename Bookmark true New Name: Enter the bookmark name Bookmark: 0 0 Enter the bookmark name to be renamed true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok nameEdit bookmarkCombo buttonBox buttonBox accepted() HgBookmarkRenameDialog accept() 248 254 157 274 buttonBox rejected() HgBookmarkRenameDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgRepoConfigDataDialog.py0000644000175000017500000001115712451233372025427 0ustar piotrpiotr# -*- coding: utf-8 -*- """ Module implementing a dialog to enter data needed for the initial creation of a repository configuration file (hgrc). """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QUrl from PyQt5.QtWidgets import QDialog, QLineEdit from .Ui_HgRepoConfigDataDialog import Ui_HgRepoConfigDataDialog import UI.PixmapCache from .LargefilesExtension import getDefaults as getLargefilesDefaults class HgRepoConfigDataDialog(QDialog, Ui_HgRepoConfigDataDialog): """ Class implementing a dialog to enter data needed for the initial creation of a repository configuration file (hgrc). """ def __init__(self, withLargefiles=False, largefilesData=None, parent=None): """ Constructor @param withLargefiles flag indicating to configure the largefiles section (boolean) @param largefilesData dictionary with data for the largefiles section (dict) @param parent reference to the parent widget (QWidget) """ super(HgRepoConfigDataDialog, self).__init__(parent) self.setupUi(self) self.defaultShowPasswordButton.setIcon( UI.PixmapCache.getIcon("showPassword.png")) self.defaultPushShowPasswordButton.setIcon( UI.PixmapCache.getIcon("showPassword.png")) self.__withLargefiles = withLargefiles if withLargefiles: if largefilesData is None: largefilesData = getLargefilesDefaults() self.lfFileSizeSpinBox.setValue(largefilesData["minsize"]) self.lfFilePatternsEdit.setText( " ".join(largefilesData["pattern"])) else: self.largefilesGroup.setVisible(False) self.resize(self.width(), self.minimumSizeHint().height()) @pyqtSlot(bool) def on_defaultShowPasswordButton_clicked(self, checked): """ Private slot to switch the default password visibility of the default password. @param checked state of the push button (boolean) """ if checked: self.defaultPasswordEdit.setEchoMode(QLineEdit.Normal) else: self.defaultPasswordEdit.setEchoMode(QLineEdit.Password) @pyqtSlot(bool) def on_defaultPushShowPasswordButton_clicked(self, checked): """ Private slot to switch the default password visibility of the default push password. @param checked state of the push button (boolean) """ if checked: self.defaultPushPasswordEdit.setEchoMode(QLineEdit.Normal) else: self.defaultPushPasswordEdit.setEchoMode(QLineEdit.Password) def getData(self): """ Public method to get the data entered into the dialog. @return tuple giving the default and default push URLs (tuple of two strings) """ defaultUrl = QUrl.fromUserInput(self.defaultUrlEdit.text()) username = self.defaultUserEdit.text() password = self.defaultPasswordEdit.text() if username: defaultUrl.setUserName(username) if password: defaultUrl.setPassword(password) if not defaultUrl.isValid(): defaultUrl = "" else: defaultUrl = defaultUrl.toString() defaultPushUrl = QUrl.fromUserInput(self.defaultPushUrlEdit.text()) username = self.defaultPushUserEdit.text() password = self.defaultPushPasswordEdit.text() if username: defaultPushUrl.setUserName(username) if password: defaultPushUrl.setPassword(password) if not defaultPushUrl.isValid(): defaultPushUrl = "" else: defaultPushUrl = defaultPushUrl.toString() return defaultUrl, defaultPushUrl def getLargefilesData(self): """ Public method to get the data for the largefiles extension. @return tuple with the minimum file size (integer) and file patterns (list of string). None as value denote to use the default value. """ if self.__withLargefiles: lfDefaults = getLargefilesDefaults() if self.lfFileSizeSpinBox.value() == lfDefaults["minsize"]: minsize = None else: minsize = self.lfFileSizeSpinBox.value() patterns = self.lfFilePatternsEdit.text().split() if set(patterns) == set(lfDefaults["pattern"]): patterns = None return minsize, patterns else: return None, None eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgDialog.py0000644000175000017500000002412012537064320022653 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog starting a process and showing its output. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QProcess, QTimer, pyqtSlot, Qt, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QLineEdit from E5Gui import E5MessageBox from .Ui_HgDialog import Ui_HgDialog import Preferences class HgDialog(QDialog, Ui_HgDialog): """ Class implementing a dialog starting a process and showing its output. It starts a QProcess and displays a dialog that shows the output of the process. The dialog is modal, which causes a synchronized execution of the process. """ def __init__(self, text, hg=None, useClient=True, parent=None): """ Constructor @param text text to be shown by the label (string) @param hg reference to the Mercurial interface object (Hg) @param useClient flag indicating to use the command server client if possible (boolean) @param parent parent widget (QWidget) """ super(HgDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.proc = None self.username = '' self.password = '' if useClient: self.__hgClient = hg.getClient() else: self.__hgClient = None self.vcs = hg self.outputGroup.setTitle(text) self.show() QCoreApplication.processEvents() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.proc is not None and \ self.proc.state() != QProcess.NotRunning: self.proc.terminate() QTimer.singleShot(2000, self.proc.kill) self.proc.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.proc = None self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) if Preferences.getVCS("AutoClose") and \ self.normal and \ self.errors.toPlainText() == "": self.accept() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.normal = (exitStatus == QProcess.NormalExit) and (exitCode == 0) self.__finish() def startProcess(self, args, workingDir=None, showArgs=True): """ Public slot used to start the process. @param args list of arguments for the process (list of strings) @keyparam workingDir working directory for the process (string) @keyparam showArgs flag indicating to show the arguments (boolean) @return flag indicating a successful start of the process """ self.errorGroup.hide() self.normal = False self.intercept = False self.__hasAddOrDelete = False if args[0] in ["fetch", "qpush", "qpop", "qgoto", "rebase", "transplant", "update", "import", "revert", "graft", "shelve", "unshelve"] or \ (args[0] in ["pull", "unbundle"] and ("--update" in args[1:] or "--rebase" in args[1:])): self.__updateCommand = True else: self.__updateCommand = False if showArgs: self.resultbox.append(' '.join(args)) self.resultbox.append('') if self.__hgClient is None: self.proc = QProcess() self.proc.finished.connect(self.__procFinished) self.proc.readyReadStandardOutput.connect(self.__readStdout) self.proc.readyReadStandardError.connect(self.__readStderr) if workingDir: self.proc.setWorkingDirectory(workingDir) self.proc.start('hg', args) procStarted = self.proc.waitForStarted(5000) if not procStarted: self.buttonBox.setFocus() self.inputGroup.setEnabled(False) E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() return procStarted else: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand( args, output=self.__showOutput, error=self.__showError) if err: self.__showError(err) if out: self.__showOutput(out) self.normal = True self.__finish() return True def normalExit(self): """ Public method to check for a normal process termination. @return flag indicating normal process termination (boolean) """ return self.normal def normalExitWithoutErrors(self): """ Public method to check for a normal process termination without error messages. @return flag indicating normal process termination (boolean) """ return self.normal and self.errors.toPlainText() == "" def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.proc is not None: s = str(self.proc.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') self.__showOutput(s) def __showOutput(self, out): """ Private slot to show some output. @param out output to be shown (string) """ self.resultbox.insertPlainText(out) self.resultbox.ensureCursorVisible() # check for a changed project file if self.__updateCommand: for line in out.splitlines(): if '.e4p' in line: self.__hasAddOrDelete = True break QCoreApplication.processEvents() def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.proc is not None: s = str(self.proc.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() QCoreApplication.processEvents() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.proc.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgDialog, self).keyPressEvent(evt) def hasAddOrDelete(self): """ Public method to check, if the last action contained an add or delete. @return flag indicating the presence of an add or delete (boolean) """ return self.__hasAddOrDelete eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgGraftDialog.py0000644000175000017500000000735312451233372023650 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a graft session. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QDateTime from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgGraftDialog import Ui_HgGraftDialog class HgGraftDialog(QDialog, Ui_HgGraftDialog): """ Class implementing a dialog to enter the data for a graft session. """ def __init__(self, vcs, revs=None, parent=None): """ Constructor @param vcs reference to the VCS object (Hg) @param revs list of revisions to show in the revisions pane (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgGraftDialog, self).__init__(parent) self.setupUi(self) self.dateTimeEdit.setDateTime(QDateTime.currentDateTime()) if vcs.version < (2, 3): self.logCheckBox.setEnabled(False) self.logCheckBox.setChecked(False) self.logCheckBox.setVisible(False) if revs: self.revisionsEdit.setPlainText("\n".join(sorted(revs))) self.__updateOk() def __updateOk(self): """ Private slot to update the state of the OK button. """ enable = self.revisionsEdit.toPlainText() != "" if self.userGroup.isChecked(): enable = enable and \ (self.currentUserCheckBox.isChecked() or self.userEdit.text() != "") self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) @pyqtSlot() def on_revisionsEdit_textChanged(self): """ Private slot to react upon changes of revisions. """ self.__updateOk() @pyqtSlot(bool) def on_userGroup_toggled(self, checked): """ Private slot to handle changes of the user group state. @param checked flag giving the checked state (boolean) """ self.__updateOk() @pyqtSlot(bool) def on_currentUserCheckBox_toggled(self, checked): """ Private slot to handle changes of the currentuser state. @param checked flag giving the checked state (boolean) """ self.__updateOk() @pyqtSlot(str) def on_userEdit_textChanged(self, txt): """ Private slot to handle changes of the user name. @param txt text of the edit (string) """ self.__updateOk() def getData(self): """ Public method to retrieve the entered data. @return tuple with list of revisions, a tuple giving a flag indicating to set the user, a flag indicating to use the current user and the user name, another tuple giving a flag indicating to set the date, a flag indicating to use the current date and the date, a flag indicating to append graft info to the log message and a flag indicating a dry-run (list of strings, (boolean, boolean, string), (boolean, boolean, string), boolean, boolean) """ userData = (self.userGroup.isChecked(), self.currentUserCheckBox.isChecked(), self.userEdit.text()) dateData = (self.dateGroup.isChecked(), self.currentDateCheckBox.isChecked(), self.dateTimeEdit.dateTime().toString("yyyy-MM-dd hh:mm")) return (self.revisionsEdit.toPlainText().strip().splitlines(), userData, dateData, self.logCheckBox.isChecked(), self.dryRunCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgConflictsListDialog.ui0000644000175000017500000001527712335671447025370 0ustar piotrpiotr HgConflictsListDialog 0 0 650 450 Mercurial Conflicts true <b>Conflicts List</b>\n<p>This shows a list of files which had or still have conflicts.</p> true QAbstractItemView::ExtendedSelection false false true Status Name Qt::Horizontal 40 20 Press to mark the selected entries as 'resolved' Resolved Press to mark the selected entries as 'unresolved' Unresolved QFrame::Raised 2 Qt::Vertical Press to re-merge the selected entries Re-Merge Press to edit the selected entry Edit Qt::Horizontal 40 20 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close conflictsList resolvedButton unresolvedButton reMergeButton editButton errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBookmarksInOutDialog.ui0000644000175000017500000001065012334163471025475 0ustar piotrpiotr HgBookmarksInOutDialog 0 0 520 494 true 0 2 <b>Bookmarks List</b> <p>This shows a list of the bookmarks.</p> true false false true Name Changeset 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource input passwordCheckBox sendButton bookmarksList errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgMultiRevisionSelectionDialog.py0000644000175000017500000001300312451233372027251 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to select revisions. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgMultiRevisionSelectionDialog import \ Ui_HgMultiRevisionSelectionDialog class HgMultiRevisionSelectionDialog( QDialog, Ui_HgMultiRevisionSelectionDialog): """ Class implementing a dialog to select revisions. """ def __init__(self, tagsList, branchesList, bookmarksList=None, emptyRevsOk=False, showLimit=False, limitDefault=100, parent=None): """ Constructor @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param emptyRevsOk flag indicating that it is ok to not enter revisions (boolean) @param showLimit flag indicating to show the limit entry (boolean) @param limitDefault default value for the limit (integer) @param parent parent widget (QWidget) """ super(HgMultiRevisionSelectionDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.__emptyRevsOk = emptyRevsOk self.tagCombo.addItems(sorted(tagsList)) self.branchCombo.addItems(["default"] + sorted(branchesList)) if bookmarksList is not None: self.bookmarkCombo.addItems(sorted(bookmarksList)) else: self.bookmarkButton.setHidden(True) self.bookmarkCombo.setHidden(True) self.limitSpinBox.setValue(limitDefault) self.limitGroup.setVisible(showLimit) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.changesetsButton.isChecked(): enabled = self.changesetsEdit.toPlainText() != "" elif self.tagButton.isChecked(): enabled = self.tagCombo.currentText() != "" elif self.branchButton.isChecked(): enabled = self.branchCombo.currentText() != "" elif self.bookmarkButton.isChecked(): enabled = self.bookmarkCombo.currentText() != "" if not enabled and self.__emptyRevsOk: enabled = self.limitGroup.isChecked() self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(bool) def on_changesetsButton_toggled(self, checked): """ Private slot to handle changes of the Changesets select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tagButton_toggled(self, checked): """ Private slot to handle changes of the Tag select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branchButton_toggled(self, checked): """ Private slot to handle changes of the Branch select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmarkButton_toggled(self, checked): """ Private slot to handle changes of the Bookmark select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot() def on_changesetsEdit_textChanged(self): """ Private slot to handle changes of the Changesets edit. """ self.__updateOK() @pyqtSlot(str) def on_tagCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branchCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmarkCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(bool) def on_limitGroup_toggled(self, checked): """ Private slot to handle changes of the Limit Results group status. @param checked state of the group (boolean) """ self.__updateOK() def getRevisions(self): """ Public method to retrieve the selected revisions. @return tuple of selected revisions (list of strings) and number of entries to be shown (integer) """ if self.changesetsButton.isChecked(): revs = self.changesetsEdit.toPlainText().strip().splitlines() elif self.tagButton.isChecked(): revs = [self.tagCombo.currentText()] elif self.branchButton.isChecked(): revs = [self.branchCombo.currentText()] elif self.bookmarkButton.isChecked(): revs = [self.bookmarkCombo.currentText()] else: revs = [] if self.limitGroup.isChecked(): limit = self.limitSpinBox.value() else: limit = 0 return revs, limit eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/0000755000175000017500000000000012557365404024607 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectBrowserHelper.py0000644000175000017500000001016012451233372031260 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing the largefiles extension project browser helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from ..HgExtensionProjectBrowserHelper import HgExtensionProjectBrowserHelper import UI.PixmapCache class LargefilesProjectBrowserHelper(HgExtensionProjectBrowserHelper): """ Class implementing the largefiles extension project browser helper. """ def __init__(self, vcsObject, browserObject, projectObject): """ Constructor @param vcsObject reference to the vcs object @param browserObject reference to the project browser object @param projectObject reference to the project object """ super(LargefilesProjectBrowserHelper, self).__init__( vcsObject, browserObject, projectObject) def initMenus(self): """ Public method to generate the extension menus. Note: Derived class must implement this method. @return dictionary of populated menu (dict of QMenu). The dict must have the keys 'mainMenu', 'multiMenu', 'backMenu', 'dirMenu' and 'dirMultiMenu'. """ self.__menus = {} self.__addSingleActs = [] self.__addMultiActs = [] menu = QMenu(self.menuTitle()) menu.setTearOffEnabled(True) act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add as Large File'), lambda: self.__hgAddLargefiles("large")) self.__addSingleActs.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add as Normal File'), lambda: self.__hgAddLargefiles("normal")) self.__addSingleActs.append(act) self.__menus['mainMenu'] = menu menu = QMenu(self.menuTitle()) menu.setTearOffEnabled(True) act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add as Large Files'), lambda: self.__hgAddLargefiles("large")) self.__addMultiActs.append(act) act = menu.addAction( UI.PixmapCache.getIcon("vcsAdd.png"), self.tr('Add as Normal Files'), lambda: self.__hgAddLargefiles("normal")) self.__addMultiActs.append(act) self.__menus['multiMenu'] = menu return self.__menus def menuTitle(self): """ Public method to get the menu title. Note: Derived class must implement this method. @return title of the menu (string) """ return self.tr("Large Files") def showExtensionMenu(self, key, controlled): """ Public method to prepare the extension menu for display. @param key menu key (string, one of 'mainMenu', 'multiMenu', 'backMenu', 'dirMenu' or 'dirMultiMenu') @param controlled flag indicating to prepare the menu for a version controlled entry or a non-version controlled entry (boolean) """ if key == "mainMenu": for act in self.__addSingleActs: act.setEnabled(not controlled) elif key == "multiMenu": for act in self.__addMultiActs: act.setEnabled(not controlled) def __hgAddLargefiles(self, mode): """ Private slot to add the selected files as large files. @param mode add mode (string one of 'normal' or 'large') """ names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: continue names.append(name) if names: if len(names) == 1: self.vcs.getExtensionObject("largefiles").hgAdd(names[0], mode) else: self.vcs.getExtensionObject("largefiles").hgAdd(names, mode) for fn in names: self._updateVCSStatus(fn) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/largefiles.py0000644000175000017500000001561512451233372027275 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing the largefiles extension interface. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from ..HgExtension import HgExtension from ..HgDialog import HgDialog class Largefiles(HgExtension): """ Class implementing the largefiles extension interface. """ def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(Largefiles, self).__init__(vcs) def hgLfconvert(self, direction, projectFile): """ Public slot to convert the repository format of the current project. @param direction direction of the conversion (string, one of 'largefiles' or 'normal') @param projectFile file name of the current project file (string) """ assert direction in ["largefiles", "normal"] projectDir = os.path.dirname(projectFile) # find the root of the repo repodir = projectDir while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .LfConvertDataDialog import LfConvertDataDialog dlg = LfConvertDataDialog(projectDir, direction) if dlg.exec_() == QDialog.Accepted: newName, minSize, patterns = dlg.getData() newProjectFile = os.path.join( newName, os.path.basename(projectFile)) # step 1: convert the current project to new project args = self.vcs.initCommand("lfconvert") if direction == 'normal': args.append('--to-normal') else: args.append("--size") args.append(str(minSize)) args.append(projectDir) args.append(newName) if direction == 'largefiles' and patterns: args.extend(patterns) dia = HgDialog(self.tr('Convert Project - Converting'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.normalExit() and os.path.isdir( os.path.join(newName, self.vcs.adminDir)) # step 2: create working directory contents if res: args = self.vcs.initCommand("update") args.append("--verbose") dia = HgDialog(self.tr('Convert Project - Extracting'), self.vcs, useClient=False) res = dia.startProcess(args, newName) if res: dia.exec_() res = dia.normalExit() and os.path.isfile(newProjectFile) # step 3: close current project and open new one if res: if direction == 'largefiles': self.vcs.hgEditConfig(newName, largefilesData={ "minsize": minSize, "pattern": patterns}) else: self.vcs.hgEditConfig(newName, withLargefiles=False) QTimer.singleShot( 0, lambda: e5App().getObject("Project").openProject( newProjectFile)) def hgAdd(self, names, mode): """ Public method used to add a file to the Mercurial repository. @param names file name(s) to be added (string or list of string) @param mode add mode (string one of 'normal' or 'large') """ args = self.vcs.initCommand("add") args.append("-v") if mode == "large": args.append("--large") else: args.append("--normal") if isinstance(names, list): dname = self.vcs.splitPathList(names)[0] else: dname = self.vcs.splitPath(names)[0] # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if isinstance(names, list): self.vcs.addArguments(args, names) else: args.append(names) dia = HgDialog( self.tr('Adding files to the Mercurial repository'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgLfPull(self, projectDir, revisions=None): """ Public method to pull missing large files into the local repository. @param projectDir directory name of the project (string) @param revisions list of revisions to pull (list of string) """ # find the root of the repo repodir = projectDir while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return revs = [] if revisions: revs = revisions else: from .LfRevisionsInputDialog import LfRevisionsInputDialog dlg = LfRevisionsInputDialog() if dlg.exec_() == QDialog.Accepted: revs = dlg.getRevisions() if revs: args = self.vcs.initCommand("lfpull") args.append("-v") for rev in revs: args.append("--rev") args.append(rev) dia = HgDialog(self.tr("Pulling large files"), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgLfVerify(self, projectDir, mode): """ Public method to verify large files integrity. @param projectDir directory name of the project (string) @param mode verify mode (string; one of 'large', 'lfa' or 'lfc') """ # find the root of the repo repodir = projectDir while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("verify") if mode == "large": args.append("--large") elif mode == "lfa": args.append("--lfa") elif mode == "lfc": args.append("--lfc") else: return dia = HgDialog( self.tr('Verifying the integrity of large files'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.ui0000644000175000017500000001034012303676335030755 0ustar piotrpiotr LfConvertDataDialog 0 0 500 143 Convert Repository Format true New project directory: Enter the directory name of the new project directory Press to select the new project directory name via a directory selection dialog Minimum file size: Enter the minimum file size in MB for files to be treated as Large Files Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter MB 1 10 Qt::Horizontal 297 20 Patterns: Enter file patterns (space separated) for files to be treated as Large Files Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok E5SqueezeLabelPath QLabel
E5Gui/E5SqueezeLabels.h
newProjectEdit newProjectButton lfFileSizeSpinBox lfFilePatternsEdit buttonBox buttonBox accepted() LfConvertDataDialog accept() 248 254 157 274 buttonBox rejected() LfConvertDataDialog reject() 316 260 286 274
eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.py0000644000175000017500000000245412451233372031560 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter a series of revisions. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_LfRevisionsInputDialog import Ui_LfRevisionsInputDialog class LfRevisionsInputDialog(QDialog, Ui_LfRevisionsInputDialog): """ Class implementing a dialog to enter a series of revisions. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(LfRevisionsInputDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) @pyqtSlot() def on_revisionsEdit_textChanged(self): """ Private slot handling a change of revisions. """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(self.revisionsEdit.toPlainText())) def getRevisions(self): """ Public method to retrieve the entered revisions. @return list of revisions (list of string) """ return self.revisionsEdit.toPlainText().splitlines() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.py0000644000175000017500000000652512451233372030774 0ustar piotrpiotr# -*- coding: utf-8 -*- """ Module implementing a dialog to enter the data for the repo conversion. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5FileDialog from E5Gui.E5Completers import E5DirCompleter from .Ui_LfConvertDataDialog import Ui_LfConvertDataDialog from . import getDefaults import Utilities import UI.PixmapCache class LfConvertDataDialog(QDialog, Ui_LfConvertDataDialog): """ Class implementing a dialog to enter the data for the repo conversion. """ def __init__(self, currentPath, mode, parent=None): """ Constructor @param currentPath directory name of the current project (string) @param mode dialog mode (string, one of 'largefiles' or 'normal') @param parent reference to the parent widget (QWidget) """ super(LfConvertDataDialog, self).__init__(parent) self.setupUi(self) self.newProjectButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.__newProjectCompleter = E5DirCompleter(self.newProjectEdit) self.__defaults = getDefaults() self.__currentPath = Utilities.toNativeSeparators(currentPath) self.currentProjectLabel.setPath(currentPath) self.newProjectEdit.setText(os.path.dirname(currentPath)) self.lfFileSizeSpinBox.setValue(self.__defaults["minsize"]) self.lfFilePatternsEdit.setText(" ".join(self.__defaults["pattern"])) if mode == 'normal': self.lfFileSizeSpinBox.setEnabled(False) self.lfFilePatternsEdit.setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_newProjectEdit_textChanged(self, txt): """ Private slot to handle editing of the new project directory. @param txt new project directory name (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( txt and Utilities.toNativeSeparators(txt) != os.path.dirname( self.__currentPath)) @pyqtSlot() def on_newProjectButton_clicked(self): """ Private slot to select the new project directory name via a directory selection dialog. """ directory = Utilities.fromNativeSeparators(self.newProjectEdit.text()) directory = E5FileDialog.getExistingDirectory( self, self.tr("New Project Directory"), directory, E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.newProjectEdit.setText( Utilities.toNativeSeparators(directory)) def getData(self): """ Public method to retrieve the entered data. @return tuple containing the new project directory name (string), minimum file size (integer) and file patterns (list of string) """ patterns = self.lfFilePatternsEdit.text().split() if set(patterns) == set(self.__defaults["pattern"]): patterns = [] return ( Utilities.toNativeSeparators(self.newProjectEdit.text()), self.lfFileSizeSpinBox.value(), patterns, ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectHelper.py0000644000175000017500000002054512451233372027724 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing the shelve extension project helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui.E5Action import E5Action from ..HgExtensionProjectHelper import HgExtensionProjectHelper import UI.PixmapCache class LargefilesProjectHelper(HgExtensionProjectHelper): """ Class implementing the queues extension project helper. """ def __init__(self): """ Constructor """ super(LargefilesProjectHelper, self).__init__() def initActions(self): """ Public method to generate the action objects. """ self.hgConvertToLargefilesAct = E5Action( self.tr('Convert repository to largefiles'), self.tr('Convert repository to largefiles...'), 0, 0, self, 'mercurial_convert_to_largefiles') self.hgConvertToLargefilesAct.setStatusTip(self.tr( 'Convert the repository of the project to a largefiles repository.' )) self.hgConvertToLargefilesAct.setWhatsThis(self.tr( """Convert repository to largefiles""" """

This converts the repository of the project to a""" """ largefiles repository. A new project is created. The""" """ current one is kept as a backup.

""" )) self.hgConvertToLargefilesAct.triggered.connect( lambda: self.__hgLfconvert("largefiles")) self.actions.append(self.hgConvertToLargefilesAct) self.hgConvertToNormalAct = E5Action( self.tr('Convert repository to normal'), self.tr('Convert repository to normal...'), 0, 0, self, 'mercurial_convert_to_normal') self.hgConvertToNormalAct.setStatusTip(self.tr( 'Convert the repository of the project to a normal repository.' )) self.hgConvertToNormalAct.setWhatsThis(self.tr( """Convert repository to normal""" """

This converts the repository of the project to a""" """ normal repository. A new project is created. The current""" """ one is kept as a backup.

""" )) self.hgConvertToNormalAct.triggered.connect( lambda: self.__hgLfconvert("normal")) self.actions.append(self.hgConvertToNormalAct) self.hgLfPullAct = E5Action( self.tr('Pull Large Files'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('Pull Large Files'), 0, 0, self, 'mercurial_pull_largefiles') self.hgLfPullAct.setStatusTip(self.tr( 'Pull large files from a remote repository' )) self.hgLfPullAct.setWhatsThis(self.tr( """Pull Large Files""" """

This pulls missing large files from a remote repository""" """ into the local repository.

""" )) self.hgLfPullAct.triggered.connect(self.__hgLfPull) self.actions.append(self.hgLfPullAct) self.hgLfSummaryAct = E5Action( self.tr('Show Summary'), UI.PixmapCache.getIcon("vcsSummary.png"), self.tr('Show summary...'), 0, 0, self, 'mercurial_summary_largefiles') self.hgLfSummaryAct.setStatusTip(self.tr( 'Show summary information of the working directory status' )) self.hgLfSummaryAct.setWhatsThis(self.tr( """Show summary""" """

This shows some summary information of the working""" """ directory status.

""" )) self.hgLfSummaryAct.triggered.connect(self.__hgLfSummary) self.actions.append(self.hgLfSummaryAct) self.hgVerifyLargeAct = E5Action( self.tr('Verify large files of current revision'), self.tr('Verify large files of current revision...'), 0, 0, self, 'mercurial_verify_large') self.hgVerifyLargeAct.setStatusTip(self.tr( 'Verify that all large files in the current revision exist' )) self.hgVerifyLargeAct.setWhatsThis(self.tr( """Verify large files of current revision""" """

This verifies that all large files in the current""" """ revision exist.

""" )) self.hgVerifyLargeAct.triggered.connect( lambda: self.__hgLfVerify("large")) self.actions.append(self.hgVerifyLargeAct) self.hgVerifyLfaAct = E5Action( self.tr('Verify large files of all revision'), self.tr('Verify large files of all revision...'), 0, 0, self, 'mercurial_verify_lfa') self.hgVerifyLfaAct.setStatusTip(self.tr( 'Verify that all large files in all revisions exist' )) self.hgVerifyLfaAct.setWhatsThis(self.tr( """Verify large files of all revision""" """

This verifies that all large files in all""" """ revisions exist.

""" )) self.hgVerifyLfaAct.triggered.connect( lambda: self.__hgLfVerify("lfa")) self.actions.append(self.hgVerifyLfaAct) self.hgVerifyLfcAct = E5Action( self.tr('Verify large files contents'), self.tr('Verify large files contents...'), 0, 0, self, 'mercurial_verify_lfc') self.hgVerifyLfcAct.setStatusTip(self.tr( 'Verify the contents of all large files' )) self.hgVerifyLfcAct.setWhatsThis(self.tr( """Verify large files contents""" """

This verifies the contents of all large files.

""" )) self.hgVerifyLfcAct.triggered.connect( lambda: self.__hgLfVerify("lfc")) self.actions.append(self.hgVerifyLfcAct) def initMenu(self, mainMenu): """ Public method to generate the extension menu. @param mainMenu reference to the main menu (QMenu) @return populated menu (QMenu) """ menu = QMenu(self.menuTitle(), mainMenu) menu.setTearOffEnabled(True) self.__adminMenu = QMenu(self.tr("Administration"), menu) self.__adminMenu.setTearOffEnabled(True) self.__adminMenu.addAction(self.hgVerifyLargeAct) self.__adminMenu.addAction(self.hgVerifyLfaAct) self.__adminMenu.addAction(self.hgVerifyLfcAct) menu.addAction(self.hgConvertToLargefilesAct) menu.addAction(self.hgConvertToNormalAct) menu.addSeparator() menu.addAction(self.hgLfPullAct) menu.addSeparator() menu.addAction(self.hgLfSummaryAct) menu.addSeparator() menu.addMenu(self.__adminMenu) return menu def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("Large Files") def shutdown(self): """ Public method to perform shutdown actions. Note: Derived class may implement this method if needed. """ if self.__adminMenu.isTearOffMenuVisible(): self.__adminMenu.hideTearOffMenu() def __hgLfconvert(self, direction): """ Private slot to convert the repository format of the current project. @param direction direction of the conversion (string; one of 'largefiles' or 'normal') """ assert direction in ["largefiles", "normal"] self.vcs.getExtensionObject("largefiles").hgLfconvert( direction, self.project.getProjectFile()) def __hgLfPull(self): """ Private slot to pull missing large files into the local repository. """ self.vcs.getExtensionObject("largefiles").hgLfPull( self.project.getProjectPath()) def __hgLfSummary(self): """ Private slot to show a working directory summary. """ self.vcs.hgSummary(largefiles=True) def __hgLfVerify(self, mode): """ Private slot to verify large files integrity. @param mode verify mode (string; one of 'large', 'lfa' or 'lfc') """ assert mode in ['large', 'lfa', 'lfc'] self.vcs.getExtensionObject("largefiles").hgLfVerify( self.project.getProjectPath(), mode) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.ui0000644000175000017500000000426112304407200031531 0ustar piotrpiotr LfRevisionsInputDialog 0 0 400 300 Revisions Input true Enter revisions to pull large files for (one per line): true Enter changesets by number, id, range or revset expression one per line true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok revisionsEdit buttonBox buttonBox accepted() LfRevisionsInputDialog accept() 248 254 157 274 buttonBox rejected() LfRevisionsInputDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/__init__.py0000644000175000017500000000076612451233372026720 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Package implementing the largefiles extension support interface. """ from __future__ import unicode_literals def getDefaults(): """ Function to get the default values of the extension. @return dictionary with default values and parameter as key (dict) """ return { 'minsize': 10, # minimum size in MB 'pattern': [], # file name patterns } eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgPhaseDialog.ui0000644000175000017500000000603212313335214023616 0ustar piotrpiotr HgPhaseDialog 0 0 400 186 Mercurial Phases true &Revisions: revisionsEdit Enter revisions by number, id, range or revset expression one per line true QPlainTextEdit::NoWrap Phase: Select the phase to be set for the specified revisions Select to force the phase change Force Phase Change Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok revisionsEdit phaseCombo forceCheckBox buttonBox buttonBox accepted() HgPhaseDialog accept() 248 254 157 274 buttonBox rejected() HgPhaseDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBookmarkDialog.py0000644000175000017500000001512212451233372024343 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the bookmark dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgBookmarkDialog import Ui_HgBookmarkDialog class HgBookmarkDialog(QDialog, Ui_HgBookmarkDialog): """ Class mplementing the bookmark dialog. """ DEFINE_MODE = 0 MOVE_MODE = 1 def __init__(self, mode, tagsList, branchesList, bookmarksList, parent=None): """ Constructor @param mode of the dialog (integer) @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgBookmarkDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.__mode = mode if mode == self.MOVE_MODE: self.nameEdit.hide() self.nameCombo.addItems([""] + sorted(bookmarksList)) self.setWindowTitle(self.tr("Move Bookmark")) else: self.nameCombo.hide() self.setWindowTitle(self.tr("Define Bookmark")) self.__bookmarksList = bookmarksList[:] self.tagCombo.addItems(sorted(tagsList)) self.branchCombo.addItems(["default"] + sorted(branchesList)) self.bookmarkCombo.addItems(sorted(bookmarksList)) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __updateOK(self): """ Private slot to update the OK button. """ if self.__mode == self.MOVE_MODE: enabled = self.nameCombo.currentText() != "" else: enabled = self.nameEdit.text() != "" if self.idButton.isChecked(): enabled = enabled and self.idEdit.text() != "" elif self.tagButton.isChecked(): enabled = enabled and self.tagCombo.currentText() != "" elif self.branchButton.isChecked(): enabled = enabled and self.branchCombo.currentText() != "" elif self.bookmarkButton.isChecked(): enabled = enabled and self.bookmarkCombo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) def __updateBookmarksCombo(self): """ Private slot to update the bookmarks combo. """ if self.__mode == self.MOVE_MODE: bookmark = self.nameCombo.currentText() selectedBookmark = self.bookmarkCombo.currentText() self.bookmarkCombo.clearEditText() self.bookmarkCombo.clear() self.bookmarkCombo.addItems(sorted(self.__bookmarksList)) index = self.bookmarkCombo.findText(bookmark) if index > -1: self.bookmarkCombo.removeItem(index) if selectedBookmark: index = self.bookmarkCombo.findText(selectedBookmark) if index > -1: self.bookmarkCombo.setCurrentIndex(index) @pyqtSlot(str) def on_nameCombo_activated(self, txt): """ Private slot to handle changes of the selected bookmark name. @param txt selected combo entry (string) """ self.__updateOK() self.__updateBookmarksCombo() @pyqtSlot(str) def on_nameEdit_textChanged(self, txt): """ Private slot to handle changes of the bookmark name. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(bool) def on_idButton_toggled(self, checked): """ Private slot to handle changes of the ID select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tagButton_toggled(self, checked): """ Private slot to handle changes of the Tag select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branchButton_toggled(self, checked): """ Private slot to handle changes of the Branch select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmarkButton_toggled(self, checked): """ Private slot to handle changes of the Bookmark select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(str) def on_idEdit_textChanged(self, txt): """ Private slot to handle changes of the ID edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_tagCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branchCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmarkCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark combo. @param txt text of the combo (string) """ self.__updateOK() def getData(self): """ Public method to retrieve the entered data. @return tuple naming the revision and the bookmark name (string, string) """ if self.numberButton.isChecked(): rev = "rev({0})".format(self.numberSpinBox.value()) elif self.idButton.isChecked(): rev = "id({0})".format(self.idEdit.text()) elif self.tagButton.isChecked(): rev = self.tagCombo.currentText() elif self.branchButton.isChecked(): rev = self.branchCombo.currentText() elif self.bookmarkButton.isChecked(): rev = self.bookmarkCombo.currentText() else: rev = "" if self.__mode == self.MOVE_MODE: name = self.nameCombo.currentText().replace(" ", "_") else: name = self.nameEdit.text().replace(" ", "_") return rev, name eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgExportDialog.ui0000644000175000017500000001265112263303010024034 0ustar piotrpiotr HgExportDialog 0 0 456 301 Export Patches true Export Directory: File Name Pattern: Enter the file name pattern for the export files <b>File Name Pattern</b> <p>Enter the file name pattern to be used to generate the export files here. Valid recognized patterns are:</p> <table> <tr><td>%%</td><td>literal "%" character</td></tr> <tr><td>%H</td><td>changeset hash (40 hexadecimal digits)</td></tr> <tr><td>%N</td><td>number of patches being generated</td></tr> <tr><td>%R</td><td>changeset revision number</td></tr> <tr><td>%b</td><td>basename of the exporting repository</td></tr> <tr><td>%h</td><td>short-form changeset hash (12 hexadecimal digits)</td></tr> <tr><td>%n</td><td>zero-padded sequence number, starting at 1</td></tr> <tr><td>%r</td><td>zero-padded changeset revision number</td></tr> </table> Changesets: Enter changesets by number, id, range or revset expression one per line true QPlainTextEdit::NoWrap Press to select the export directory via a directory selection dialog Compare Against Second Parent Treat all Files as Text Omit Dates Use Git extended Diff-Format Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok directoryEdit directoryButton patternEdit changesetsEdit switchParentCheckBox textCheckBox datesCheckBox gitCheckBox buttonBox buttonBox accepted() HgExportDialog accept() 248 254 157 274 buttonBox rejected() HgExportDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/Config.py0000644000175000017500000000053212451233372022403 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module defining configuration variables for the Mercurial package. """ from __future__ import unicode_literals # Available protocols fpr the repository URL ConfigHgProtocols = [ 'file://', 'http://', 'https://', 'ssh://', ] eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/TransplantExtension/0000755000175000017500000000000012557365404024660 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/TransplantExtension/TransplantDialog.ui0000644000175000017500000001326612310372720030457 0ustar piotrpiotr TransplantDialog 0 0 450 382 Transplant Changesets true &Revisions: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop revisionsEdit Enter changesets by number, id, range or revset expression one per line true QPlainTextEdit::NoWrap Repositor&y: repoEdit Enter a repository URL, if changesets shall be transplanted from a repository &Branch: branchesCombo Select or enter the branch to transplant from true false Select to transplant all changesets of the branch Transplant &All Changesets &Skip: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop pruneEdit Enter changesets by number, id, range or revset expression one per line true QPlainTextEdit::NoWrap &Merge: mergeEdit Enter revisions to be merged separated by a space character Select to append transplant info to the log message Append Transplant &Info true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok revisionsEdit repoEdit branchesCombo allCheckBox pruneEdit mergeEdit logCheckBox buttonBox buttonBox accepted() TransplantDialog accept() 231 372 157 212 buttonBox rejected() TransplantDialog reject() 299 372 286 212 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/TransplantExtension/transplant.py0000644000175000017500000000657012451233372027417 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the transplant extension interface. """ from __future__ import unicode_literals import os from PyQt5.QtWidgets import QDialog from ..HgExtension import HgExtension from ..HgDialog import HgDialog class Transplant(HgExtension): """ Class implementing the transplant extension interface. """ def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(Transplant, self).__init__(vcs) def hgTransplant(self, path): """ Public method to transplant changesets from another branch. @param path directory name of the project (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False from .TransplantDialog import TransplantDialog res = False dlg = TransplantDialog(self.vcs.hgGetBranchesList(repodir)) if dlg.exec_() == QDialog.Accepted: revs, sourceRepo, branch, all, pruneRevs, mergeRevs, log = \ dlg.getData() args = self.vcs.initCommand("transplant") args.append("--verbose") if sourceRepo: args.append("--source") args.append(sourceRepo) if branch: args.append("--branch") args.append(branch) if all: args.append("--all") for pruneRev in pruneRevs: args.append("--prune") args.append(pruneRev) for mergeRev in mergeRevs: args.append("--merge") args.append(mergeRev) if log: args.append("--log") args.extend(revs) dia = HgDialog(self.tr('Transplant Changesets'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res def hgTransplantContinue(self, path): """ Public method to continue transplanting changesets from another branch. @param path directory name of the project (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("transplant") args.append("--continue") args.append("--verbose") dia = HgDialog( self.tr('Transplant Changesets (Continue)'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/TransplantExtension/ProjectHelper.py0000644000175000017500000001146712451233372030000 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the transplant extension project helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox from ..HgExtensionProjectHelper import HgExtensionProjectHelper import UI.PixmapCache class TransplantProjectHelper(HgExtensionProjectHelper): """ Class implementing the transplant extension project helper. """ def __init__(self): """ Constructor """ super(TransplantProjectHelper, self).__init__() def setObjects(self, vcsObject, projectObject): """ Public method to set references to the vcs and project objects. @param vcsObject reference to the vcs object @param projectObject reference to the project object """ super(TransplantProjectHelper, self).setObjects( vcsObject, projectObject) if self.vcs.version >= (2, 3): # transplant is deprecated as of Mercurial 2.3 for act in self.actions: act.setEnabled(False) def initActions(self): """ Public method to generate the action objects. """ self.hgTransplantAct = E5Action( self.tr('Transplant Changesets'), UI.PixmapCache.getIcon("vcsTransplant.png"), self.tr('Transplant Changesets'), 0, 0, self, 'mercurial_transplant') self.hgTransplantAct.setStatusTip(self.tr( 'Transplant changesets from another branch' )) self.hgTransplantAct.setWhatsThis(self.tr( """Transplant Changesets""" """

This transplants changesets from another branch on top""" """ of the current working directory with the log of the""" """ original changeset.

""" )) self.hgTransplantAct.triggered.connect(self.__hgTransplant) self.actions.append(self.hgTransplantAct) self.hgTransplantContinueAct = E5Action( self.tr('Continue Transplant Session'), self.tr('Continue Transplant Session'), 0, 0, self, 'mercurial_transplant_continue') self.hgTransplantContinueAct.setStatusTip(self.tr( 'Continue the last transplant session after repair' )) self.hgTransplantContinueAct.setWhatsThis(self.tr( """Continue Transplant Session""" """

This continues the last transplant session after""" """ repair.

""" )) self.hgTransplantContinueAct.triggered.connect( self.__hgTransplantContinue) self.actions.append(self.hgTransplantContinueAct) def initMenu(self, mainMenu): """ Public method to generate the extension menu. @param mainMenu reference to the main menu (QMenu) @return populated menu (QMenu) """ menu = QMenu(self.menuTitle(), mainMenu) menu.setIcon(UI.PixmapCache.getIcon("vcsTransplant.png")) if self.vcs.version >= (2, 3): # transplant is deprecated as of Mercurial 2.3 menu.addAction( self.tr("Transplant is deprecated")).setEnabled(False) else: menu.setTearOffEnabled(True) menu.addAction(self.hgTransplantAct) menu.addAction(self.hgTransplantContinueAct) return menu def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("Transplant") def __hgTransplant(self): """ Private slot used to transplant changesets from another branch. """ shouldReopen = self.vcs.getExtensionObject("transplant")\ .hgTransplant(self.project.getProjectPath()) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Transplant Changesets"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgTransplantContinue(self): """ Private slot used to continue the last transplant session after repair. """ shouldReopen = self.vcs.getExtensionObject("transplant")\ .hgTransplantContinue(self.project.getProjectPath()) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Transplant Changesets (Continue)"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/TransplantExtension/__init__.py0000644000175000017500000000025512451233372026762 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Package implementing the transplant extension support interface. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/TransplantExtension/TransplantDialog.py0000644000175000017500000001144412451233372030473 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a transplant session. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QValidator from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_TransplantDialog import Ui_TransplantDialog class RevisionsValidator(QValidator): """ Class implementing a validator for the revisions line edit. """ def __init__(self, multiRevsAllowed, parent=None): """ Constructor @param multiRevsAllowed flag indicating, if multi revs are allowed (boolean) @param parent reference to the parent object (QObject) """ super(RevisionsValidator, self).__init__(parent) self.__multiRevsAllowed = multiRevsAllowed def validate(self, input, pos): """ Public method to validate the given input. @param input input to be validated (string) @param pos position of the cursor (integer) @return tuple with validation result, input and position (QValidator.State, string, integer) """ state = QValidator.Invalid if input == "": state = QValidator.Intermediate else: state = QValidator.Acceptable revs = input.strip().split() for rev in revs: if ":" in rev: if self.__multiRevsAllowed: # it is a revision range revList = rev.split(":") if len(revList) != 2: state = QValidator.Invalid break for r in revList: if r != "" and not r.isdigit(): state = QValidator.Invalid break else: state = QValidator.Invalid break else: if not rev.isdigit(): state = QValidator.Invalid break return state, input, pos class TransplantDialog(QDialog, Ui_TransplantDialog): """ Class implementing a dialog to enter the data for a transplant session. """ def __init__(self, branchesList, parent=None): """ Constructor @param branchesList list of available branch names (list of strings) @param parent reference to the parent widget (QWidget) """ super(TransplantDialog, self).__init__(parent) self.setupUi(self) self.branchesCombo.addItems(["", "default"] + sorted(branchesList)) self.__mergeRevisionsValidator = RevisionsValidator(False, self) self.mergeEdit.setValidator(self.__mergeRevisionsValidator) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) def __updateOk(self): """ Private slot to update the state of the OK button. """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( self.revisionsEdit.toPlainText() != "" or self.allCheckBox.isChecked()) @pyqtSlot() def on_revisionsEdit_textChanged(self): """ Private slot to react upon changes of revisions. """ self.__updateOk() @pyqtSlot(str) def on_branchesCombo_editTextChanged(self, txt): """ Private slot to react upon changes of the branch name. @param txt contents of the branches combo (string) """ self.allCheckBox.setEnabled(txt != "") @pyqtSlot(bool) def on_allCheckBox_clicked(self, checked): """ Private slot to react upon selection of the all check box. @param checked state of the check box (boolean) """ self.__updateOk() def getData(self): """ Public method to retrieve the entered data. @return tuple with list of revisions, source repo, branch name, a flag indicating to transplant all, list of revisions to skip, list of revisions to merge and a flag indicating to append transplant info (list of strings, string, string, boolean, list of strings, list of strings, boolean) """ return ( self.revisionsEdit.toPlainText().strip().splitlines(), self.repoEdit.text().strip(), self.branchesCombo.currentText().strip(), self.allCheckBox.isChecked(), self.pruneEdit.toPlainText().strip().splitlines(), self.mergeEdit.text().strip().split(), self.logCheckBox.isChecked() ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgImportDialog.py0000644000175000017500000000573012451233372024054 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter data for the Mercurial import command. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QDateTime from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5FileDialog from E5Gui.E5Completers import E5FileCompleter from .Ui_HgImportDialog import Ui_HgImportDialog import Utilities import UI.PixmapCache class HgImportDialog(QDialog, Ui_HgImportDialog): """ Class implementing a dialog to enter data for the Mercurial import command. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(HgImportDialog, self).__init__(parent) self.setupUi(self) self.patchFileButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.__patchFileCompleter = E5FileCompleter(self.patchFileEdit) self.__initDateTime = QDateTime.currentDateTime() self.dateEdit.setDateTime(self.__initDateTime) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.patchFileEdit.text() == "": enabled = False self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(str) def on_patchFileEdit_textChanged(self, txt): """ Private slot to react on changes of the patch file edit. @param txt contents of the line edit (string) """ self.__updateOK() @pyqtSlot() def on_patchFileButton_clicked(self): """ Private slot called by pressing the file selection button. """ fn = E5FileDialog.getOpenFileName( self, self.tr("Select patch file"), self.patchFileEdit.text(), self.tr("Patch Files (*.diff *.patch);;All Files (*)")) if fn: self.patchFileEdit.setText(Utilities.toNativeSeparators(fn)) def getParameters(self): """ Public method to retrieve the import data. @return tuple naming the patch file, a flag indicating to not commit, a commit message, a commit date, a commit user, a strip count and a flag indicating to enforce the import (string, boolean, string, string, string, integer, boolean) """ if self.dateEdit.dateTime() != self.__initDateTime: date = self.dateEdit.dateTime().toString("yyyy-MM-dd hh:mm") else: date = "" return (self.patchFileEdit.text(), self.noCommitCheckBox.isChecked(), self.messageEdit.toPlainText(), date, self.userEdit.text(), self.stripSpinBox.value(), self.forceCheckBox.isChecked()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgRemoveSubrepositoriesDialog.py0000644000175000017500000000406012451233372027154 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to remove sub-repositories. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from .Ui_HgRemoveSubrepositoriesDialog import Ui_HgRemoveSubrepositoriesDialog class HgRemoveSubrepositoriesDialog(QDialog, Ui_HgRemoveSubrepositoriesDialog): """ Class implementing a dialog to remove sub-repositories. """ def __init__(self, subrepositories, parent=None): """ Constructor @param subrepositories list of sub-repository entries (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgRemoveSubrepositoriesDialog, self).__init__(parent) self.setupUi(self) self.subrepositories.addItems(subrepositories) self.__removed = [] @pyqtSlot() def on_subrepositories_itemSelectionChanged(self): """ Private slot handling the selection of entries. """ self.removeButton.setEnabled( len(self.subrepositories.selectedItems()) > 0) @pyqtSlot() def on_removeButton_clicked(self): """ Private slot handling the removal of the selected entries. """ for itm in self.subrepositories.selectedItems(): self.__removed.append(itm.text()) row = self.subrepositories.row(itm) self.subrepositories.takeItem(row) del itm def getData(self): """ Public method to retrieve the data. @return tuple giving the remaining sub-repositories, the removed ones and a flag indicating to delete the removed ones from disc (list of strings, list of strings, boolean) """ return ( [self.subrepositories.item(row).text() for row in range(self.subrepositories.count())], self.__removed, self.deleteCheckBox.isChecked() ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgDialog.ui0000644000175000017500000001013512060166053022636 0ustar piotrpiotr HgDialog 0 0 593 499 Mercurial true 0 2 Output true false 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource resultbox errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgAnnotateDialog.py0000644000175000017500000002436612537064320024361 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the hg annotate command. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os import re from PyQt5.QtCore import pyqtSlot, QProcess, QTimer, Qt, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, \ QLineEdit, QTreeWidgetItem from E5Gui import E5MessageBox from .Ui_HgAnnotateDialog import Ui_HgAnnotateDialog import Preferences class HgAnnotateDialog(QDialog, Ui_HgAnnotateDialog): """ Class implementing a dialog to show the output of the hg annotate command. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(HgAnnotateDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.vcs = vcs self.__hgClient = vcs.getClient() self.__annotateRe = re.compile( r"""(.+)\s+(\d+)\s+([0-9a-fA-F]+)\s+([0-9-]+)\s+(.+)""") self.annotateList.headerItem().setText( self.annotateList.columnCount(), "") font = Preferences.getEditorOtherFonts("MonospacedFont") self.annotateList.setFont(font) if self.__hgClient: self.process = None else: self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, fn): """ Public slot to start the annotate command. @param fn filename to show the log for (string) """ self.errorGroup.hide() self.intercept = False self.activateWindow() self.lineno = 1 dname, fname = self.vcs.splitPath(fn) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("annotate") args.append('--follow') args.append('--user') args.append('--date') args.append('--number') args.append('--changeset') args.append('--quiet') args.append(fn) if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.process = None self.__resizeColumns() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __resizeColumns(self): """ Private method to resize the list columns. """ self.annotateList.header().resizeSections(QHeaderView.ResizeToContents) def __generateItem(self, revision, changeset, author, date, text): """ Private method to generate an annotate item in the annotation list. @param revision revision string (string) @param changeset changeset string (string) @param author author of the change (string) @param date date of the change (string) @param text text of the change (string) """ itm = QTreeWidgetItem( self.annotateList, [revision, changeset, author, date, "{0:d}".format(self.lineno), text]) self.lineno += 1 itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(4, Qt.AlignRight) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the annotation list. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.vcs.getEncoding(), 'replace').strip() self.__processOutputLine(s) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ try: info, text = line.split(": ", 1) except ValueError: info = line[:-2] text = "" match = self.__annotateRe.match(info) author, rev, changeset, date, file = match.groups() self.__generateItem(rev.strip(), changeset.strip(), author.strip(), date.strip(), text) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the hg process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgAnnotateDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.ui0000644000175000017500000001345212306127415026222 0ustar piotrpiotr HgNewProjectOptionsDialog 0 0 562 221 New Project from Repository <b>New Project from Repository Dialog</b> <p>Enter the various repository infos into the entry fields. These values are used, when the new project is retrieved from the repository. If the checkbox is selected, the URL must end in the project name. A repository layout with project/tags, project/branches and project/trunk will be assumed. In this case, you may enter a tag or branch, which must look like tags/tagname or branches/branchname. If the checkbox is not selected, the URL must contain the complete path in the repository.</p> <p>For remote repositories the URL must contain the hostname.</p> true &Protocol: protocolCombo Select the protocol to access the repository &URL: vcsUrlEdit Enter the url path of the repository (without protocol part) Select the repository url via a directory selection dialog &Revision: vcsRevisionEdit Enter the revision the new project should be generated from Project &Directory: vcsProjectDirEdit Enter the directory of the new project. <b>Project Directory</b> <p>Enter the directory of the new project. It will be retrieved from the repository and be placed in this directory.</p> Download all versions of all large files <b>Note:</b> This option increases the download time and volume. true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource protocolCombo vcsUrlEdit vcsUrlButton vcsRevisionEdit vcsProjectDirEdit projectDirButton largeCheckBox buttonBox buttonBox accepted() HgNewProjectOptionsDialog accept() 37 176 38 198 buttonBox rejected() HgNewProjectOptionsDialog reject() 147 177 153 197 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgStatusDialog.ui0000644000175000017500000002101412176511672024051 0ustar piotrpiotr HgStatusDialog 0 0 955 646 Mercurial Status <b>Mercurial Status</b> <p>This dialog shows the status of the selected file or project.</p> Qt::Horizontal 40 20 &Filter on Status: statusFilterCombo Select the status of entries to be shown QComboBox::AdjustToContents 0 3 true QAbstractItemView::ExtendedSelection false true Commit Status Path Commit the selected changes &Commit Qt::Vertical Add the selected entries to the repository &Add Show differences of the selected entries to the repository &Differences Show differences of the selected entry to the repository in a side-by-side manner Side-b&y-Side Diff Revert the selected entries to the last revision in the repository Re&vert Forget about the selected missing entries For&get Restore the selected missing entries from the repository &Restore Qt::Horizontal 40 20 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource statusFilterCombo statusList commitButton addButton diffButton sbsDiffButton revertButton forgetButton restoreButton errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgGraftDialog.ui0000644000175000017500000001702612060166053023630 0ustar piotrpiotr HgGraftDialog 0 0 450 400 Copy Changesets true Revisions Enter changesets by number, id, range or revset expression one per line true QPlainTextEdit::NoWrap Select to give user information User true false Select to use the name of the current user Use current user Username: Enter the user name to be used Select to give date and time information Date and Time true false Select to use the current date and time Use current date and time Date/Time: Enter the date and time to be used yyyy-MM-dd hh:mm true Qt::Horizontal 241 20 Select to append graft info to the log message Append Graft &Info true Select to perform a dry-run of the graft operation Perform Dry-Run Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok revisionsEdit userGroup currentUserCheckBox userEdit dateGroup currentDateCheckBox dateTimeEdit logCheckBox dryRunCheckBox buttonBox buttonBox accepted() HgGraftDialog accept() 231 372 157 212 buttonBox rejected() HgGraftDialog reject() 299 372 286 212 currentUserCheckBox toggled(bool) label_3 setDisabled(bool) 52 193 52 217 currentUserCheckBox toggled(bool) userEdit setDisabled(bool) 180 195 179 221 currentDateCheckBox toggled(bool) label_4 setDisabled(bool) 72 287 69 308 currentDateCheckBox toggled(bool) dateTimeEdit setDisabled(bool) 122 290 120 312 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/0000755000175000017500000000000012557365404024001 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesHeaderDialog.ui0000644000175000017500000000211512060166053030302 0ustar piotrpiotr HgQueuesHeaderDialog 0 0 400 300 Commit Message true true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close messageEdit buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesNewPatchDialog.py0000644000175000017500000001040612451233372030643 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to get the data for a new patch. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QDateTime from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgQueuesNewPatchDialog import Ui_HgQueuesNewPatchDialog class HgQueuesNewPatchDialog(QDialog, Ui_HgQueuesNewPatchDialog): """ Class implementing a dialog to get the data for a new patch. """ NEW_MODE = 0 REFRESH_MODE = 1 def __init__(self, mode, message="", parent=None): """ Constructor @param mode mode of the dialog (HgQueuesNewPatchDialog.NEW_MODE, HgQueuesNewPatchDialog.REFRESH_MODE) @param message text to set as the commit message (string) @param parent reference to the parent widget (QWidget) @exception ValueError raised to indicate an invalid dialog mode """ super(HgQueuesNewPatchDialog, self).__init__(parent) self.setupUi(self) self.__mode = mode if self.__mode == HgQueuesNewPatchDialog.REFRESH_MODE: self.nameLabel.hide() self.nameEdit.hide() elif self.__mode == HgQueuesNewPatchDialog.NEW_MODE: # nothing special here pass else: raise ValueError("invalid value for mode") if message: self.messageEdit.setPlainText(message) self.dateTimeEdit.setDateTime(QDateTime.currentDateTime()) self.__updateUI() def __updateUI(self): """ Private slot to update the UI. """ if self.__mode == HgQueuesNewPatchDialog.REFRESH_MODE: enable = self.messageEdit.toPlainText() != "" else: enable = self.nameEdit.text() != "" and \ self.messageEdit.toPlainText() != "" if self.userGroup.isChecked(): enable = enable and \ (self.currentUserCheckBox.isChecked() or self.userEdit.text() != "") self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) @pyqtSlot(str) def on_nameEdit_textChanged(self, txt): """ Private slot to handle changes of the patch name. @param txt text of the edit (string) """ self.__updateUI() @pyqtSlot() def on_messageEdit_textChanged(self): """ Private slot to handle changes of the patch message. """ self.__updateUI() @pyqtSlot(bool) def on_userGroup_toggled(self, checked): """ Private slot to handle changes of the user group state. @param checked flag giving the checked state (boolean) """ self.__updateUI() @pyqtSlot(bool) def on_currentUserCheckBox_toggled(self, checked): """ Private slot to handle changes of the currentuser state. @param checked flag giving the checked state (boolean) """ self.__updateUI() @pyqtSlot(str) def on_userEdit_textChanged(self, txt): """ Private slot to handle changes of the user name. @param txt text of the edit (string) """ self.__updateUI() def getData(self): """ Public method to retrieve the entered data. @return tuple giving the patch name and message, a tuple giving a flag indicating to set the user, a flag indicating to use the current user and the user name and another tuple giving a flag indicating to set the date, a flag indicating to use the current date and the date (string, string, (boolean, boolean, string), (boolean, boolean, string)) """ userData = (self.userGroup.isChecked(), self.currentUserCheckBox.isChecked(), self.userEdit.text()) dateData = (self.dateGroup.isChecked(), self.currentDateCheckBox.isChecked(), self.dateTimeEdit.dateTime().toString("yyyy-MM-dd hh:mm")) return (self.nameEdit.text().replace(" ", "_"), self.messageEdit.toPlainText(), userData, dateData) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListAllGuardsDialog.py0000644000175000017500000000653712537064320031656 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to show all guards for all patches. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import Qt, QProcess, QCoreApplication from PyQt5.QtWidgets import QDialog, QTreeWidgetItem from .Ui_HgQueuesListAllGuardsDialog import Ui_HgQueuesListAllGuardsDialog import UI.PixmapCache class HgQueuesListAllGuardsDialog(QDialog, Ui_HgQueuesListAllGuardsDialog): """ Class implementing a dialog to show all guards for all patches. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the VCS object (Hg) @param parent reference to the parent widget (QWidget) """ super(HgQueuesListAllGuardsDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.vcs = vcs self.__hgClient = vcs.getClient() self.show() QCoreApplication.processEvents() def start(self, path): """ Public slot to start the list command. @param path name of directory to be listed (string) """ dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qguard") args.append("--list") output = "" if self.__hgClient: output = self.__hgClient.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') if output: guardsDict = {} for line in output.splitlines(): if line: patchName, guards = line.strip().split(":", 1) guardsDict[patchName] = guards.strip().split() for patchName in sorted(guardsDict.keys()): patchItm = QTreeWidgetItem(self.guardsTree, [patchName]) patchItm.setExpanded(True) for guard in guardsDict[patchName]: if guard.startswith("+"): icon = UI.PixmapCache.getIcon("plus.png") guard = guard[1:] elif guard.startswith("-"): icon = UI.PixmapCache.getIcon("minus.png") guard = guard[1:] else: icon = None guard = self.tr("Unguarded") itm = QTreeWidgetItem(patchItm, [guard]) if icon: itm.setIcon(0, icon) else: QTreeWidgetItem(self.guardsTree, [self.tr("no patches found")]) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesRenamePatchDialog.py0000644000175000017500000000526212451233372031325 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data to rename a patch. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgQueuesRenamePatchDialog import Ui_HgQueuesRenamePatchDialog class HgQueuesRenamePatchDialog(QDialog, Ui_HgQueuesRenamePatchDialog): """ Class implementing a dialog to enter the data to rename a patch. """ def __init__(self, currentPatch, patchesList, parent=None): """ Constructor @param currentPatch name of the current patch (string) @param patchesList list of patches to select from (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgQueuesRenamePatchDialog, self).__init__(parent) self.setupUi(self) self.currentButton.setText( self.tr("Current Patch ({0})").format(currentPatch)) self.nameCombo.addItems([""] + patchesList) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __updateUI(self): """ Private slot to update the UI. """ enable = self.nameEdit.text() != "" if self.namedButton.isChecked(): enable = enable and self.nameCombo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) @pyqtSlot(str) def on_nameEdit_textChanged(self, txt): """ Private slot to handle changes of the new name. @param txt text of the edit (string) """ self.__updateUI() @pyqtSlot(bool) def on_namedButton_toggled(self, checked): """ Private slot to handle changes of the selection method. @param checked state of the check box (boolean) """ self.__updateUI() @pyqtSlot(str) def on_nameCombo_currentIndexChanged(self, txt): """ Private slot to handle changes of the selected patch name. @param txt selected patch name (string) """ self.__updateUI() def getData(self): """ Public method to retrieve the entered data. @return tuple of new name and selected patch (string, string) """ selectedPatch = "" if self.namedButton.isChecked(): selectedPatch = self.nameCombo.currentText() return self.nameEdit.text().replace(" ", "_"), selectedPatch eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesQueueManagementDialog.py0000644000175000017500000001527312537064320032222 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog used by the queue management functions. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractItemView, \ QListWidgetItem, QAbstractButton from .Ui_HgQueuesQueueManagementDialog import Ui_HgQueuesQueueManagementDialog class HgQueuesQueueManagementDialog(QDialog, Ui_HgQueuesQueueManagementDialog): """ Class implementing a dialog used by the queue management functions. """ NO_INPUT = 0 NAME_INPUT = 1 QUEUE_INPUT = 2 def __init__(self, mode, title, suppressActive, repodir, vcs, parent=None): """ Constructor @param mode mode of the dialog (HgQueuesQueueManagementDialog.NO_INPUT HgQueuesQueueManagementDialog.NAME_INPUT, HgQueuesQueueManagementDialog.QUEUE_INPUT) @param title title for the dialog (string) @param suppressActive flag indicating to not show the name of the active queue (boolean) @param repodir name of the repository directory (string) @param vcs reference to the vcs object @param parent reference to the parent widget (QWidget) @exception ValueError raised to indicate an invalid dialog mode """ super(HgQueuesQueueManagementDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) if mode not in (HgQueuesQueueManagementDialog.NO_INPUT, HgQueuesQueueManagementDialog.NAME_INPUT, HgQueuesQueueManagementDialog.QUEUE_INPUT): raise ValueError("illegal value for mode") self.__mode = mode self.__repodir = repodir self.__suppressActive = suppressActive self.__hgClient = vcs.getClient() self.vcs = vcs self.inputFrame.setHidden( mode != HgQueuesQueueManagementDialog.NAME_INPUT) self.selectLabel.setHidden( mode != HgQueuesQueueManagementDialog.QUEUE_INPUT) if mode != HgQueuesQueueManagementDialog.QUEUE_INPUT: self.queuesList.setSelectionMode(QAbstractItemView.NoSelection) if mode == HgQueuesQueueManagementDialog.NO_INPUT: self.buttonBox.removeButton( self.buttonBox.button(QDialogButtonBox.Ok)) self.buttonBox.removeButton( self.buttonBox.button(QDialogButtonBox.Cancel)) self.refreshButton = self.buttonBox.addButton( self.tr("Refresh"), QDialogButtonBox.ActionRole) self.refreshButton.setToolTip( self.tr("Press to refresh the queues list")) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) else: self.buttonBox.removeButton( self.buttonBox.button(QDialogButtonBox.Close)) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.refreshButton = None self.setWindowTitle(title) self.show() QCoreApplication.processEvents() self.refresh() def __getQueuesList(self): """ Private method to get a list of all queues and the name of the active queue. @return tuple with a list of all queues and the name of the active queue (list of strings, string) """ queuesList = [] activeQueue = "" args = self.vcs.initCommand("qqueue") args.append("--list") output = "" if self.__hgClient: output = self.__hgClient.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(self.__repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') for queue in output.splitlines(): queue = queue.strip() if queue.endswith(")"): queue = queue.rsplit(None, 1)[0] activeQueue = queue queuesList.append(queue) if self.__suppressActive: if activeQueue in queuesList: queuesList.remove(activeQueue) activeQueue = "" return queuesList, activeQueue @pyqtSlot(str) def on_nameEdit_textChanged(self, txt): """ Private slot to handle changes of the entered queue name. @param txt text of the edit (string) """ if self.__mode == HgQueuesQueueManagementDialog.NAME_INPUT: self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(txt != "") @pyqtSlot() def on_queuesList_itemSelectionChanged(self): """ Private slot to handle changes of selected queue names. """ if self.__mode == HgQueuesQueueManagementDialog.QUEUE_INPUT: self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( len(self.queuesList.selectedItems()) > 0) @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.refreshButton: self.refresh() elif button == self.buttonBox.button(QDialogButtonBox.Close): self.close() def refresh(self): """ Public slot to refresh the list of queues. """ self.queuesList.clear() queuesList, activeQueue = self.__getQueuesList() for queue in sorted(queuesList): itm = QListWidgetItem(queue, self.queuesList) if queue == activeQueue: font = itm.font() font.setBold(True) itm.setFont(font) def getData(self): """ Public slot to get the data. @return queue name (string) """ name = "" if self.__mode == HgQueuesQueueManagementDialog.NAME_INPUT: name = self.nameEdit.text().replace(" ", "_") elif self.__mode == HgQueuesQueueManagementDialog.QUEUE_INPUT: selItems = self.queuesList.selectedItems() if selItems: name = selItems[0].text() return name eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesRenamePatchDialog.ui0000644000175000017500000000730112060166053031303 0ustar piotrpiotr HgQueuesRenamePatchDialog 0 0 400 174 Rename Patch true New Name: Enter the new name for the selected patch Patch Select to rename the current patch Current Patch true Select to rename the selected named patch Named Patch false Select the patch to be renamed Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok nameEdit currentButton namedButton nameCombo buttonBox buttonBox accepted() HgQueuesRenamePatchDialog accept() 248 254 157 274 buttonBox rejected() HgQueuesRenamePatchDialog reject() 316 260 286 274 namedButton toggled(bool) nameCombo setEnabled(bool) 59 106 63 136 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesQueueManagementDialog.ui0000644000175000017500000000522312060166053032176 0ustar piotrpiotr HgQueuesQueueManagementDialog 0 0 400 300 true 0 Queue Name: Enter the queue name Select queue name: This shows a list of available queues (active queue in bold) true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok nameEdit queuesList buttonBox buttonBox accepted() HgQueuesQueueManagementDialog accept() 248 254 157 274 buttonBox rejected() HgQueuesQueueManagementDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesNewPatchDialog.ui0000644000175000017500000001623712060166053030635 0ustar piotrpiotr HgQueuesNewPatchDialog 0 0 400 362 New Patch true Name: Enter the patch name Message: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop Enter the commit message for the patch true Select to give user information User true false Select to use the name of the current user Use current user Username: Enter the user name to be used for the patch Select to give date and time information Date and Time true false Select to use the current date and time Use current date and time Date/Time: Enter the date and time to be used for the patch yyyy-MM-dd hh:mm true Qt::Horizontal 241 20 QDialogButtonBox::Cancel|QDialogButtonBox::Ok nameEdit messageEdit userGroup currentUserCheckBox userEdit dateGroup currentDateCheckBox dateTimeEdit buttonBox buttonBox accepted() HgQueuesNewPatchDialog accept() 119 333 14 333 buttonBox rejected() HgQueuesNewPatchDialog reject() 166 352 45 326 currentUserCheckBox toggled(bool) userEdit setDisabled(bool) 50 184 98 208 currentUserCheckBox toggled(bool) label_3 setDisabled(bool) 22 182 23 204 currentDateCheckBox toggled(bool) label_4 setDisabled(bool) 36 271 20 297 currentDateCheckBox toggled(bool) dateTimeEdit setDisabled(bool) 146 266 145 290 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesDefineGuardsDialog.ui0000644000175000017500000001250512060166053031456 0ustar piotrpiotr HgQueuesDefineGuardsDialog 0 0 400 434 Define Guards true Select patch (leave empty for current patch): Select the patch to show the guards of Qt::Horizontal Patch: 0 0 Shows the name of the patch This shows the list of guards to be defined for the selected patch true QAbstractItemView::ExtendedSelection Select to define a positive guard true Select to define a negative guard 0 0 Enter the guard name true QComboBox::InsertAlphabetically Press to add the guard to the list or change it Add/Change Press to remove the selected guards from the list Remove Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Close patchSelector guardsList plusButton minusButton guardCombo addButton removeButton buttonBox buttonBox accepted() HgQueuesDefineGuardsDialog accept() 222 419 157 274 buttonBox rejected() HgQueuesDefineGuardsDialog reject() 290 425 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesGuardsSelectionDialog.ui0000644000175000017500000000362512060166053032214 0ustar piotrpiotr HgQueuesGuardsSelectionDialog 0 0 300 300 Select Guards true true QAbstractItemView::ExtendedSelection Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok guardsList buttonBox buttonBox accepted() HgQueuesGuardsSelectionDialog accept() 248 254 157 274 buttonBox rejected() HgQueuesGuardsSelectionDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/ProjectHelper.py0000644000175000017500000012675112451233372027124 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the queues extension project helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox from ..HgExtensionProjectHelper import HgExtensionProjectHelper from .queues import Queues class QueuesProjectHelper(HgExtensionProjectHelper): """ Class implementing the queues extension project helper. """ def __init__(self): """ Constructor """ super(QueuesProjectHelper, self).__init__() def initActions(self): """ Public method to generate the action objects. """ self.hgQueueInitAct = E5Action( self.tr('Init Queue Repository'), self.tr('Init Queue Repository'), 0, 0, self, 'mercurial_queues_init') self.hgQueueInitAct.setStatusTip(self.tr( 'Initialize a new versioned queue repository' )) self.hgQueueInitAct.setWhatsThis(self.tr( """Init Queue Repository""" """

This initializes a new versioned queue repository inside""" """ the current repository.

""" )) self.hgQueueInitAct.triggered.connect(self.__hgQueueInit) self.actions.append(self.hgQueueInitAct) self.hgQueueCommitAct = E5Action( self.tr('Commit changes'), self.tr('Commit changes...'), 0, 0, self, 'mercurial_queues_commit') self.hgQueueCommitAct.setStatusTip(self.tr( 'Commit changes in the queue repository' )) self.hgQueueCommitAct.setWhatsThis(self.tr( """Commit changes...""" """

This commits changes in the queue repository.

""" )) self.hgQueueCommitAct.triggered.connect(self.__hgQueueCommit) self.actions.append(self.hgQueueCommitAct) self.hgQueueNewAct = E5Action( self.tr('New Patch'), self.tr('New Patch...'), 0, 0, self, 'mercurial_queues_new') self.hgQueueNewAct.setStatusTip(self.tr( 'Create a new patch' )) self.hgQueueNewAct.setWhatsThis(self.tr( """New Patch""" """

This creates a new named patch.

""" )) self.hgQueueNewAct.triggered.connect(self.__hgQueueNewPatch) self.actions.append(self.hgQueueNewAct) self.hgQueueRefreshAct = E5Action( self.tr('Update Current Patch'), self.tr('Update Current Patch'), 0, 0, self, 'mercurial_queues_refresh') self.hgQueueRefreshAct.setStatusTip(self.tr( 'Update the current patch' )) self.hgQueueRefreshAct.setWhatsThis(self.tr( """Update Current Patch""" """

This updates the current patch.

""" )) self.hgQueueRefreshAct.triggered.connect( self.__hgQueueRefreshPatch) self.actions.append(self.hgQueueRefreshAct) self.hgQueueRefreshMessageAct = E5Action( self.tr('Update Current Patch (with Message)'), self.tr('Update Current Patch (with Message)'), 0, 0, self, 'mercurial_queues_refresh_message') self.hgQueueRefreshMessageAct.setStatusTip(self.tr( 'Update the current patch and edit commit message' )) self.hgQueueRefreshMessageAct.setWhatsThis(self.tr( """Update Current Patch (with Message)""" """

This updates the current patch after giving the chance""" """ to change the current commit message.

""" )) self.hgQueueRefreshMessageAct.triggered.connect( self.__hgQueueRefreshPatchMessage) self.actions.append(self.hgQueueRefreshMessageAct) self.hgQueueDiffAct = E5Action( self.tr('Show Current Patch'), self.tr('Show Current Patch...'), 0, 0, self, 'mercurial_queues_show') self.hgQueueDiffAct.setStatusTip(self.tr( 'Show the contents the current patch' )) self.hgQueueDiffAct.setWhatsThis(self.tr( """Show Current Patch""" """

This shows the contents of the current patch including""" """ any changes which have been made in the working directory""" """ since the last refresh.

""" )) self.hgQueueDiffAct.triggered.connect(self.__hgQueueShowPatch) self.actions.append(self.hgQueueDiffAct) self.hgQueueHeaderAct = E5Action( self.tr('Show Current Message'), self.tr('Show Current Message...'), 0, 0, self, 'mercurial_queues_show_message') self.hgQueueHeaderAct.setStatusTip(self.tr( 'Show the commit message of the current patch' )) self.hgQueueHeaderAct.setWhatsThis(self.tr( """Show Current Message""" """

This shows the commit message of the current patch.

""" )) self.hgQueueHeaderAct.triggered.connect(self.__hgQueueShowHeader) self.actions.append(self.hgQueueHeaderAct) self.hgQueueListAct = E5Action( self.tr('List Patches'), self.tr('List Patches...'), 0, 0, self, 'mercurial_queues_list') self.hgQueueListAct.setStatusTip(self.tr( 'List applied and unapplied patches' )) self.hgQueueListAct.setWhatsThis(self.tr( """List Patches""" """

This lists all applied and unapplied patches.

""" )) self.hgQueueListAct.triggered.connect(self.__hgQueueListPatches) self.actions.append(self.hgQueueListAct) self.hgQueueFinishAct = E5Action( self.tr('Finish Applied Patches'), self.tr('Finish Applied Patches'), 0, 0, self, 'mercurial_queues_finish_applied') self.hgQueueFinishAct.setStatusTip(self.tr( 'Finish applied patches' )) self.hgQueueFinishAct.setWhatsThis(self.tr( """Finish Applied Patches""" """

This finishes the applied patches by moving them out of""" """ mq control into regular repository history.

""" )) self.hgQueueFinishAct.triggered.connect( self.__hgQueueFinishAppliedPatches) self.actions.append(self.hgQueueFinishAct) self.hgQueueRenameAct = E5Action( self.tr('Rename Patch'), self.tr('Rename Patch'), 0, 0, self, 'mercurial_queues_rename') self.hgQueueRenameAct.setStatusTip(self.tr( 'Rename a patch' )) self.hgQueueRenameAct.setWhatsThis(self.tr( """Rename Patch""" """

This renames the current or a named patch.

""" )) self.hgQueueRenameAct.triggered.connect(self.__hgQueueRenamePatch) self.actions.append(self.hgQueueRenameAct) self.hgQueueDeleteAct = E5Action( self.tr('Delete Patch'), self.tr('Delete Patch'), 0, 0, self, 'mercurial_queues_delete') self.hgQueueDeleteAct.setStatusTip(self.tr( 'Delete unapplied patch' )) self.hgQueueDeleteAct.setWhatsThis(self.tr( """Delete Patch""" """

This deletes an unapplied patch.

""" )) self.hgQueueDeleteAct.triggered.connect(self.__hgQueueDeletePatch) self.actions.append(self.hgQueueDeleteAct) self.hgQueueFoldAct = E5Action( self.tr('Fold Patches'), self.tr('Fold Patches'), 0, 0, self, 'mercurial_queues_fold') self.hgQueueFoldAct.setStatusTip(self.tr( 'Fold unapplied patches into the current patch' )) self.hgQueueFoldAct.setWhatsThis(self.tr( """Fold Patches""" """

This folds unapplied patches into the current patch.

""" )) self.hgQueueFoldAct.triggered.connect( self.__hgQueueFoldUnappliedPatches) self.actions.append(self.hgQueueFoldAct) self.hgQueueStatusAct = E5Action( self.tr('Show Status'), self.tr('Show &Status...'), 0, 0, self, 'mercurial_queues_status') self.hgQueueStatusAct.setStatusTip(self.tr( 'Show the status of the queue repository' )) self.hgQueueStatusAct.setWhatsThis(self.tr( """Show Status""" """

This shows the status of the queue repository.

""" )) self.hgQueueStatusAct.triggered.connect(self.__hgQueueStatus) self.actions.append(self.hgQueueStatusAct) self.hgQueueSummaryAct = E5Action( self.tr('Show Summary'), self.tr('Show summary...'), 0, 0, self, 'mercurial_queues_summary') self.hgQueueSummaryAct.setStatusTip(self.tr( 'Show summary information of the queue repository' )) self.hgQueueSummaryAct.setWhatsThis(self.tr( """Show summary""" """

This shows some summary information of the queue""" """ repository.

""" )) self.hgQueueSummaryAct.triggered.connect(self.__hgQueueSummary) self.actions.append(self.hgQueueSummaryAct) self.__initPushPopActions() self.__initPushPopForceActions() self.__initGuardsActions() self.__initQueuesMgmtActions() def __initPushPopActions(self): """ Private method to generate the push and pop action objects. """ self.hgQueuePushAct = E5Action( self.tr('Push Next Patch'), self.tr('Push Next Patch'), 0, 0, self, 'mercurial_queues_push_next') self.hgQueuePushAct.setStatusTip(self.tr( 'Push the next patch onto the stack' )) self.hgQueuePushAct.setWhatsThis(self.tr( """Push Next Patch""" """

This pushes the next patch onto the stack of applied""" """ patches.

""" )) self.hgQueuePushAct.triggered.connect(self.__hgQueuePushPatch) self.actions.append(self.hgQueuePushAct) self.hgQueuePushAllAct = E5Action( self.tr('Push All Patches'), self.tr('Push All Patches'), 0, 0, self, 'mercurial_queues_push_all') self.hgQueuePushAllAct.setStatusTip(self.tr( 'Push all patches onto the stack' )) self.hgQueuePushAllAct.setWhatsThis(self.tr( """Push All Patches""" """

This pushes all patches onto the stack of applied""" """ patches.

""" )) self.hgQueuePushAllAct.triggered.connect( self.__hgQueuePushAllPatches) self.actions.append(self.hgQueuePushAllAct) self.hgQueuePushUntilAct = E5Action( self.tr('Push Patches'), self.tr('Push Patches'), 0, 0, self, 'mercurial_queues_push_until') self.hgQueuePushUntilAct.setStatusTip(self.tr( 'Push patches onto the stack' )) self.hgQueuePushUntilAct.setWhatsThis(self.tr( """Push Patches""" """

This pushes patches onto the stack of applied patches""" """ until a named patch is at the top of the stack.

""" )) self.hgQueuePushUntilAct.triggered.connect( self.__hgQueuePushPatches) self.actions.append(self.hgQueuePushUntilAct) self.hgQueuePopAct = E5Action( self.tr('Pop Current Patch'), self.tr('Pop Current Patch'), 0, 0, self, 'mercurial_queues_pop_current') self.hgQueuePopAct.setStatusTip(self.tr( 'Pop the current patch off the stack' )) self.hgQueuePopAct.setWhatsThis(self.tr( """Pop Current Patch""" """

This pops the current patch off the stack of applied""" """ patches.

""" )) self.hgQueuePopAct.triggered.connect(self.__hgQueuePopPatch) self.actions.append(self.hgQueuePopAct) self.hgQueuePopAllAct = E5Action( self.tr('Pop All Patches'), self.tr('Pop All Patches'), 0, 0, self, 'mercurial_queues_pop_all') self.hgQueuePopAllAct.setStatusTip(self.tr( 'Pop all patches off the stack' )) self.hgQueuePopAllAct.setWhatsThis(self.tr( """Pop All Patches""" """

This pops all patches off the stack of applied""" """ patches.

""" )) self.hgQueuePopAllAct.triggered.connect( self.__hgQueuePopAllPatches) self.actions.append(self.hgQueuePopAllAct) self.hgQueuePopUntilAct = E5Action( self.tr('Pop Patches'), self.tr('Pop Patches'), 0, 0, self, 'mercurial_queues_pop_until') self.hgQueuePopUntilAct.setStatusTip(self.tr( 'Pop patches off the stack' )) self.hgQueuePopUntilAct.setWhatsThis(self.tr( """Pop Patches""" """

This pops patches off the stack of applied patches""" """ until a named patch is at the top of the stack.

""" )) self.hgQueuePopUntilAct.triggered.connect(self.__hgQueuePopPatches) self.actions.append(self.hgQueuePopUntilAct) self.hgQueueGotoAct = E5Action( self.tr('Go to Patch'), self.tr('Go to Patch'), 0, 0, self, 'mercurial_queues_goto') self.hgQueueGotoAct.setStatusTip(self.tr( 'Push or pop patches until named patch is at top of stack' )) self.hgQueueGotoAct.setWhatsThis(self.tr( """Go to Patch""" """

This pushes or pops patches until a named patch is at the""" """ top of the stack.

""" )) self.hgQueueGotoAct.triggered.connect(self.__hgQueueGotoPatch) self.actions.append(self.hgQueueGotoAct) def __initPushPopForceActions(self): """ Private method to generate the push and pop (force) action objects. """ self.hgQueuePushForceAct = E5Action( self.tr('Push Next Patch'), self.tr('Push Next Patch'), 0, 0, self, 'mercurial_queues_push_next_force') self.hgQueuePushForceAct.setStatusTip(self.tr( 'Push the next patch onto the stack on top of local changes' )) self.hgQueuePushForceAct.setWhatsThis(self.tr( """Push Next Patch""" """

This pushes the next patch onto the stack of applied""" """ patches on top of local changes.

""" )) self.hgQueuePushForceAct.triggered.connect( self.__hgQueuePushPatchForced) self.actions.append(self.hgQueuePushForceAct) self.hgQueuePushAllForceAct = E5Action( self.tr('Push All Patches'), self.tr('Push All Patches'), 0, 0, self, 'mercurial_queues_push_all_force') self.hgQueuePushAllForceAct.setStatusTip(self.tr( 'Push all patches onto the stack on top of local changes' )) self.hgQueuePushAllForceAct.setWhatsThis(self.tr( """Push All Patches""" """

This pushes all patches onto the stack of applied patches""" """ on top of local changes.

""" )) self.hgQueuePushAllForceAct.triggered.connect( self.__hgQueuePushAllPatchesForced) self.actions.append(self.hgQueuePushAllForceAct) self.hgQueuePushUntilForceAct = E5Action( self.tr('Push Patches'), self.tr('Push Patches'), 0, 0, self, 'mercurial_queues_push_until_force') self.hgQueuePushUntilForceAct.setStatusTip(self.tr( 'Push patches onto the stack on top of local changes' )) self.hgQueuePushUntilForceAct.setWhatsThis(self.tr( """Push Patches""" """

This pushes patches onto the stack of applied patches""" """ until a named patch is at the top of the stack on top of""" """ local changes.

""" )) self.hgQueuePushUntilForceAct.triggered.connect( self.__hgQueuePushPatchesForced) self.actions.append(self.hgQueuePushUntilForceAct) self.hgQueuePopForceAct = E5Action( self.tr('Pop Current Patch'), self.tr('Pop Current Patch'), 0, 0, self, 'mercurial_queues_pop_current_force') self.hgQueuePopForceAct.setStatusTip(self.tr( 'Pop the current patch off the stack forgetting local changes' )) self.hgQueuePopForceAct.setWhatsThis(self.tr( """Pop Current Patch""" """

This pops the current patch off the stack of applied""" """ patches""" """ forgetting local changes.

""" )) self.hgQueuePopForceAct.triggered.connect( self.__hgQueuePopPatchForced) self.actions.append(self.hgQueuePopForceAct) self.hgQueuePopAllForceAct = E5Action( self.tr('Pop All Patches'), self.tr('Pop All Patches'), 0, 0, self, 'mercurial_queues_pop_all_force') self.hgQueuePopAllForceAct.setStatusTip(self.tr( 'Pop all patches off the stack forgetting local changes' )) self.hgQueuePopAllForceAct.setWhatsThis(self.tr( """Pop All Patches""" """

This pops all patches off the stack of applied patches""" """ forgetting local changes.

""" )) self.hgQueuePopAllForceAct.triggered.connect( self.__hgQueuePopAllPatchesForced) self.actions.append(self.hgQueuePopAllForceAct) self.hgQueuePopUntilForceAct = E5Action( self.tr('Pop Patches'), self.tr('Pop Patches'), 0, 0, self, 'mercurial_queues_pop_until_force') self.hgQueuePopUntilForceAct.setStatusTip(self.tr( 'Pop patches off the stack forgetting local changes' )) self.hgQueuePopUntilForceAct.setWhatsThis(self.tr( """Pop Patches""" """

This pops patches off the stack of applied patches until""" """ a named patch is at the top of the stack forgetting local""" """ changes.

""" )) self.hgQueuePopUntilForceAct.triggered.connect( self.__hgQueuePopPatchesForced) self.actions.append(self.hgQueuePopUntilForceAct) self.hgQueueGotoForceAct = E5Action( self.tr('Go to Patch'), self.tr('Go to Patch'), 0, 0, self, 'mercurial_queues_goto_force') self.hgQueueGotoForceAct.setStatusTip(self.tr( 'Push or pop patches until named patch is at top of stack' ' overwriting any local changes' )) self.hgQueueGotoForceAct.setWhatsThis(self.tr( """Go to Patch""" """

This pushes or pops patches until a named patch is at the""" """ top of the stack overwriting any local changes.

""" )) self.hgQueueGotoForceAct.triggered.connect( self.__hgQueueGotoPatchForced) self.actions.append(self.hgQueueGotoForceAct) def __initGuardsActions(self): """ Private method to generate the guards action objects. """ self.hgQueueDefineGuardsAct = E5Action( self.tr('Define Guards'), self.tr('Define Guards...'), 0, 0, self, 'mercurial_queues_guards_define') self.hgQueueDefineGuardsAct.setStatusTip(self.tr( 'Define guards for the current or a named patch' )) self.hgQueueDefineGuardsAct.setWhatsThis(self.tr( """Define Guards""" """

This opens a dialog to define guards for the current""" """ or a named patch.

""" )) self.hgQueueDefineGuardsAct.triggered.connect( self.__hgQueueGuardsDefine) self.actions.append(self.hgQueueDefineGuardsAct) self.hgQueueDropAllGuardsAct = E5Action( self.tr('Drop All Guards'), self.tr('Drop All Guards...'), 0, 0, self, 'mercurial_queues_guards_drop_all') self.hgQueueDropAllGuardsAct.setStatusTip(self.tr( 'Drop all guards of the current or a named patch' )) self.hgQueueDropAllGuardsAct.setWhatsThis(self.tr( """Drop All Guards""" """

This drops all guards of the current or a named patch.

""" )) self.hgQueueDropAllGuardsAct.triggered.connect( self.__hgQueueGuardsDropAll) self.actions.append(self.hgQueueDropAllGuardsAct) self.hgQueueListGuardsAct = E5Action( self.tr('List Guards'), self.tr('List Guards...'), 0, 0, self, 'mercurial_queues_guards_list') self.hgQueueListGuardsAct.setStatusTip(self.tr( 'List guards of the current or a named patch' )) self.hgQueueListGuardsAct.setWhatsThis(self.tr( """List Guards""" """

This lists the guards of the current or a named patch.

""" )) self.hgQueueListGuardsAct.triggered.connect( self.__hgQueueGuardsList) self.actions.append(self.hgQueueListGuardsAct) self.hgQueueListAllGuardsAct = E5Action( self.tr('List All Guards'), self.tr('List All Guards...'), 0, 0, self, 'mercurial_queues_guards_list_all') self.hgQueueListAllGuardsAct.setStatusTip(self.tr( 'List all guards of all patches' )) self.hgQueueListAllGuardsAct.setWhatsThis(self.tr( """List All Guards""" """

This lists all guards of all patches.

""" )) self.hgQueueListAllGuardsAct.triggered.connect( self.__hgQueueGuardsListAll) self.actions.append(self.hgQueueListAllGuardsAct) self.hgQueueActivateGuardsAct = E5Action( self.tr('Set Active Guards'), self.tr('Set Active Guards...'), 0, 0, self, 'mercurial_queues_guards_set_active') self.hgQueueActivateGuardsAct.setStatusTip(self.tr( 'Set the list of active guards' )) self.hgQueueActivateGuardsAct.setWhatsThis(self.tr( """Set Active Guards""" """

This opens a dialog to set the active guards.

""" )) self.hgQueueActivateGuardsAct.triggered.connect( self.__hgQueueGuardsSetActive) self.actions.append(self.hgQueueActivateGuardsAct) self.hgQueueDeactivateGuardsAct = E5Action( self.tr('Deactivate Guards'), self.tr('Deactivate Guards...'), 0, 0, self, 'mercurial_queues_guards_deactivate') self.hgQueueDeactivateGuardsAct.setStatusTip(self.tr( 'Deactivate all active guards' )) self.hgQueueDeactivateGuardsAct.setWhatsThis(self.tr( """Deactivate Guards""" """

This deactivates all active guards.

""" )) self.hgQueueDeactivateGuardsAct.triggered.connect( self.__hgQueueGuardsDeactivate) self.actions.append(self.hgQueueDeactivateGuardsAct) self.hgQueueIdentifyActiveGuardsAct = E5Action( self.tr('Identify Active Guards'), self.tr('Identify Active Guards...'), 0, 0, self, 'mercurial_queues_guards_identify_active') self.hgQueueIdentifyActiveGuardsAct.setStatusTip(self.tr( 'Show a list of active guards' )) self.hgQueueIdentifyActiveGuardsAct.setWhatsThis(self.tr( """Identify Active Guards""" """

This opens a dialog showing a list of active guards.

""" )) self.hgQueueIdentifyActiveGuardsAct.triggered.connect( self.__hgQueueGuardsIdentifyActive) self.actions.append(self.hgQueueIdentifyActiveGuardsAct) def __initQueuesMgmtActions(self): """ Private method to generate the queues management action objects. """ self.hgQueueCreateQueueAct = E5Action( self.tr('Create Queue'), self.tr('Create Queue'), 0, 0, self, 'mercurial_queues_create_queue') self.hgQueueCreateQueueAct.setStatusTip(self.tr( 'Create a new patch queue' )) self.hgQueueCreateQueueAct.setWhatsThis(self.tr( """Create Queue""" """

This creates a new patch queue.

""" )) self.hgQueueCreateQueueAct.triggered.connect( self.__hgQueueCreateQueue) self.actions.append(self.hgQueueCreateQueueAct) self.hgQueueRenameQueueAct = E5Action( self.tr('Rename Queue'), self.tr('Rename Queue'), 0, 0, self, 'mercurial_queues_rename_queue') self.hgQueueRenameQueueAct.setStatusTip(self.tr( 'Rename the active patch queue' )) self.hgQueueRenameQueueAct.setWhatsThis(self.tr( """Rename Queue""" """

This renames the active patch queue.

""" )) self.hgQueueRenameQueueAct.triggered.connect( self.__hgQueueRenameQueue) self.actions.append(self.hgQueueRenameQueueAct) self.hgQueueDeleteQueueAct = E5Action( self.tr('Delete Queue'), self.tr('Delete Queue'), 0, 0, self, 'mercurial_queues_delete_queue') self.hgQueueDeleteQueueAct.setStatusTip(self.tr( 'Delete the reference to a patch queue' )) self.hgQueueDeleteQueueAct.setWhatsThis(self.tr( """Delete Queue""" """

This deletes the reference to a patch queue.

""" )) self.hgQueueDeleteQueueAct.triggered.connect( self.__hgQueueDeleteQueue) self.actions.append(self.hgQueueDeleteQueueAct) self.hgQueuePurgeQueueAct = E5Action( self.tr('Purge Queue'), self.tr('Purge Queue'), 0, 0, self, 'mercurial_queues_purge_queue') self.hgQueuePurgeQueueAct.setStatusTip(self.tr( 'Delete the reference to a patch queue and remove the patch' ' directory' )) self.hgQueuePurgeQueueAct.setWhatsThis(self.tr( """Purge Queue""" """

This deletes the reference to a patch queue and removes""" """ the patch directory.

""" )) self.hgQueuePurgeQueueAct.triggered.connect( self.__hgQueuePurgeQueue) self.actions.append(self.hgQueuePurgeQueueAct) self.hgQueueActivateQueueAct = E5Action( self.tr('Activate Queue'), self.tr('Activate Queue'), 0, 0, self, 'mercurial_queues_activate_queue') self.hgQueueActivateQueueAct.setStatusTip(self.tr( 'Set the active queue' )) self.hgQueueActivateQueueAct.setWhatsThis(self.tr( """Activate Queue""" """

This sets the active queue.

""" )) self.hgQueueActivateQueueAct.triggered.connect( self.__hgQueueActivateQueue) self.actions.append(self.hgQueueActivateQueueAct) self.hgQueueListQueuesAct = E5Action( self.tr('List Queues'), self.tr('List Queues...'), 0, 0, self, 'mercurial_queues_list_queues') self.hgQueueListQueuesAct.setStatusTip(self.tr( 'List the available queues' )) self.hgQueueListQueuesAct.setWhatsThis(self.tr( """List Queues""" """

This opens a dialog showing all available queues.

""" )) self.hgQueueListQueuesAct.triggered.connect( self.__hgQueueListQueues) self.actions.append(self.hgQueueListQueuesAct) def initMenu(self, mainMenu): """ Public method to generate the extension menu. @param mainMenu reference to the main menu (QMenu) @return populated menu (QMenu) """ menu = QMenu(self.menuTitle(), mainMenu) menu.setTearOffEnabled(True) pushPopMenu = QMenu(self.tr("Push/Pop"), menu) pushPopMenu.setTearOffEnabled(True) pushPopMenu.addAction(self.hgQueuePushAct) pushPopMenu.addAction(self.hgQueuePushUntilAct) pushPopMenu.addAction(self.hgQueuePushAllAct) pushPopMenu.addSeparator() pushPopMenu.addAction(self.hgQueuePopAct) pushPopMenu.addAction(self.hgQueuePopUntilAct) pushPopMenu.addAction(self.hgQueuePopAllAct) pushPopMenu.addSeparator() pushPopMenu.addAction(self.hgQueueGotoAct) pushPopForceMenu = QMenu(self.tr("Push/Pop (force)"), menu) pushPopForceMenu.setTearOffEnabled(True) pushPopForceMenu.addAction(self.hgQueuePushForceAct) pushPopForceMenu.addAction(self.hgQueuePushUntilForceAct) pushPopForceMenu.addAction(self.hgQueuePushAllForceAct) pushPopForceMenu.addSeparator() pushPopForceMenu.addAction(self.hgQueuePopForceAct) pushPopForceMenu.addAction(self.hgQueuePopUntilForceAct) pushPopForceMenu.addAction(self.hgQueuePopAllForceAct) pushPopForceMenu.addSeparator() pushPopForceMenu.addAction(self.hgQueueGotoForceAct) guardsMenu = QMenu(self.tr("Guards"), menu) guardsMenu.setTearOffEnabled(True) guardsMenu.addAction(self.hgQueueDefineGuardsAct) guardsMenu.addAction(self.hgQueueDropAllGuardsAct) guardsMenu.addSeparator() guardsMenu.addAction(self.hgQueueListGuardsAct) guardsMenu.addAction(self.hgQueueListAllGuardsAct) guardsMenu.addSeparator() guardsMenu.addAction(self.hgQueueActivateGuardsAct) guardsMenu.addAction(self.hgQueueDeactivateGuardsAct) guardsMenu.addSeparator() guardsMenu.addAction(self.hgQueueIdentifyActiveGuardsAct) queuesMenu = QMenu(self.tr("Queue Management"), menu) queuesMenu.setTearOffEnabled(True) queuesMenu.addAction(self.hgQueueCreateQueueAct) queuesMenu.addAction(self.hgQueueRenameQueueAct) queuesMenu.addAction(self.hgQueueDeleteQueueAct) queuesMenu.addAction(self.hgQueuePurgeQueueAct) queuesMenu.addSeparator() queuesMenu.addAction(self.hgQueueActivateQueueAct) queuesMenu.addSeparator() queuesMenu.addAction(self.hgQueueListQueuesAct) menu.addAction(self.hgQueueInitAct) menu.addAction(self.hgQueueCommitAct) menu.addSeparator() menu.addAction(self.hgQueueNewAct) menu.addAction(self.hgQueueRefreshAct) menu.addAction(self.hgQueueRefreshMessageAct) menu.addAction(self.hgQueueFinishAct) menu.addSeparator() menu.addAction(self.hgQueueStatusAct) menu.addAction(self.hgQueueSummaryAct) menu.addSeparator() menu.addAction(self.hgQueueDiffAct) menu.addAction(self.hgQueueHeaderAct) menu.addSeparator() menu.addAction(self.hgQueueListAct) menu.addSeparator() menu.addMenu(pushPopMenu) menu.addMenu(pushPopForceMenu) menu.addSeparator() menu.addAction(self.hgQueueRenameAct) menu.addAction(self.hgQueueDeleteAct) menu.addSeparator() menu.addAction(self.hgQueueFoldAct) menu.addSeparator() menu.addMenu(guardsMenu) menu.addSeparator() menu.addMenu(queuesMenu) return menu def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("Queues") def __hgQueueNewPatch(self): """ Private slot used to create a new named patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueNewPatch(self.project.getProjectPath()) def __hgQueueRefreshPatch(self): """ Private slot used to refresh the current patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueRefreshPatch(self.project.getProjectPath()) def __hgQueueRefreshPatchMessage(self): """ Private slot used to refresh the current patch and its commit message. """ self.vcs.getExtensionObject("mq")\ .hgQueueRefreshPatch(self.project.getProjectPath(), editMessage=True) def __hgQueueShowPatch(self): """ Private slot used to show the contents of the current patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueShowPatch(self.project.getProjectPath()) def __hgQueueShowHeader(self): """ Private slot used to show the commit message of the current patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueShowHeader(self.project.getProjectPath()) def __hgQueuePushPopPatches(self, name, operation, all=False, named=False, force=False): """ Private method to push patches onto the stack or pop patches off the stack. @param name file/directory name (string) @param operation operation type to be performed (Queues.POP, Queues.PUSH, Queues.GOTO) @keyparam all flag indicating to push/pop all (boolean) @keyparam named flag indicating to push/pop until a named patch is at the top of the stack (boolean) @keyparam force flag indicating a forceful pop (boolean) """ shouldReopen = self.vcs.getExtensionObject("mq")\ .hgQueuePushPopPatches(name, operation=operation, all=all, named=named, force=force) if shouldReopen: res = E5MessageBox.yesNo( None, self.tr("Changing Applied Patches"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgQueuePushPatch(self): """ Private slot used to push the next patch onto the stack. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.PUSH, all=False, named=False) def __hgQueuePushPatchForced(self): """ Private slot used to push the next patch onto the stack on top of local changes. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.PUSH, all=False, named=False, force=True) def __hgQueuePushAllPatches(self): """ Private slot used to push all patches onto the stack. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.PUSH, all=True, named=False) def __hgQueuePushAllPatchesForced(self): """ Private slot used to push all patches onto the stack on top of local changes. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.PUSH, all=True, named=False, force=True) def __hgQueuePushPatches(self): """ Private slot used to push patches onto the stack until a named one is at the top. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.PUSH, all=False, named=True) def __hgQueuePushPatchesForced(self): """ Private slot used to push patches onto the stack until a named one is at the top on top of local changes. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.PUSH, all=False, named=True, force=True) def __hgQueuePopPatch(self): """ Private slot used to pop the current patch off the stack. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.POP, all=False, named=False) def __hgQueuePopPatchForced(self): """ Private slot used to pop the current patch off the stack forgetting any local changes to patched files. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.POP, all=False, named=False, force=True) def __hgQueuePopAllPatches(self): """ Private slot used to pop all patches off the stack. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.POP, all=True, named=False) def __hgQueuePopAllPatchesForced(self): """ Private slot used to pop all patches off the stack forgetting any local changes to patched files. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.POP, all=True, named=False, force=True) def __hgQueuePopPatches(self): """ Private slot used to pop patches off the stack until a named one is at the top. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.POP, all=False, named=True) def __hgQueuePopPatchesForced(self): """ Private slot used to pop patches off the stack until a named one is at the top forgetting any local changes to patched files. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.POP, all=False, named=True, force=True) def __hgQueueGotoPatch(self): """ Private slot used to push or pop patches until the a named one is at the top of the stack. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.GOTO, all=False, named=True) def __hgQueueGotoPatchForced(self): """ Private slot used to push or pop patches until the a named one is at the top of the stack overwriting local changes. """ self.__hgQueuePushPopPatches( self.project.getProjectPath(), operation=Queues.GOTO, all=False, named=True, force=True) def __hgQueueListPatches(self): """ Private slot used to show a list of applied and unapplied patches. """ self.vcs.getExtensionObject("mq")\ .hgQueueListPatches(self.project.getProjectPath()) def __hgQueueFinishAppliedPatches(self): """ Private slot used to finish all applied patches. """ self.vcs.getExtensionObject("mq")\ .hgQueueFinishAppliedPatches(self.project.getProjectPath()) def __hgQueueRenamePatch(self): """ Private slot used to rename a patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueRenamePatch(self.project.getProjectPath()) def __hgQueueDeletePatch(self): """ Private slot used to delete a patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueDeletePatch(self.project.getProjectPath()) def __hgQueueFoldUnappliedPatches(self): """ Private slot used to fold patches into the current patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueFoldUnappliedPatches(self.project.getProjectPath()) def __hgQueueGuardsDefine(self): """ Private slot used to define guards for the current or a named patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueGuardsDefine(self.project.getProjectPath()) def __hgQueueGuardsDropAll(self): """ Private slot used to drop all guards of the current or a named patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueGuardsDropAll(self.project.getProjectPath()) def __hgQueueGuardsList(self): """ Private slot used to list the guards for the current or a named patch. """ self.vcs.getExtensionObject("mq")\ .hgQueueGuardsList(self.project.getProjectPath()) def __hgQueueGuardsListAll(self): """ Private slot used to list all guards of all patches. """ self.vcs.getExtensionObject("mq")\ .hgQueueGuardsListAll(self.project.getProjectPath()) def __hgQueueGuardsSetActive(self): """ Private slot used to set the active guards. """ self.vcs.getExtensionObject("mq")\ .hgQueueGuardsSetActive(self.project.getProjectPath()) def __hgQueueGuardsDeactivate(self): """ Private slot used to deactivate all active guards. """ self.vcs.getExtensionObject("mq")\ .hgQueueGuardsDeactivate(self.project.getProjectPath()) def __hgQueueGuardsIdentifyActive(self): """ Private slot used to list all active guards. """ self.vcs.getExtensionObject("mq")\ .hgQueueGuardsIdentifyActive(self.project.getProjectPath()) def __hgQueueCreateQueue(self): """ Private slot used to create a new queue. """ self.vcs.getExtensionObject("mq")\ .hgQueueCreateRenameQueue(self.project.getProjectPath(), True) def __hgQueueRenameQueue(self): """ Private slot used to rename the active queue. """ self.vcs.getExtensionObject("mq")\ .hgQueueCreateRenameQueue(self.project.getProjectPath(), False) def __hgQueueDeleteQueue(self): """ Private slot used to delete the reference to a queue. """ self.vcs.getExtensionObject("mq")\ .hgQueueDeletePurgeActivateQueue(self.project.getProjectPath(), Queues.QUEUE_DELETE) def __hgQueuePurgeQueue(self): """ Private slot used to delete the reference to a queue and remove the patch directory. """ self.vcs.getExtensionObject("mq")\ .hgQueueDeletePurgeActivateQueue(self.project.getProjectPath(), Queues.QUEUE_PURGE) def __hgQueueActivateQueue(self): """ Private slot used to set the active queue. """ self.vcs.getExtensionObject("mq")\ .hgQueueDeletePurgeActivateQueue(self.project.getProjectPath(), Queues.QUEUE_ACTIVATE) def __hgQueueListQueues(self): """ Private slot used to list available queues. """ self.vcs.getExtensionObject("mq")\ .hgQueueListQueues(self.project.getProjectPath()) def __hgQueueInit(self): """ Private slot to initialize a new queue repository. """ self.vcs.getExtensionObject("mq")\ .hgQueueInit(self.project.getProjectPath()) def __hgQueueCommit(self): """ Private slot to commit changes in the queue repository. """ self.vcs.vcsCommit(self.project.getProjectPath(), "", mq=True) def __hgQueueStatus(self): """ Private slot to show the status of the queue repository. """ self.vcs.getExtensionObject("mq")\ .hgQueueStatus(self.project.getProjectPath()) def __hgQueueSummary(self): """ Private slot to show a summary of the queue repository. """ self.vcs.hgSummary(mq=True) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListAllGuardsDialog.ui0000644000175000017500000000423012060166053031624 0ustar piotrpiotr HgQueuesListAllGuardsDialog 0 0 400 400 List All Guards true Show all guards of all patches true QAbstractItemView::NoSelection true 1 Qt::Horizontal QDialogButtonBox::Close guardsTree buttonBox buttonBox accepted() HgQueuesListAllGuardsDialog accept() 248 254 157 274 buttonBox rejected() HgQueuesListAllGuardsDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/__init__.py0000644000175000017500000000025112451233372026077 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Package implementing the queues extension support interface. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesFoldDialog.py0000644000175000017500000001233712451233372030023 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter data to fold patches. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem from .Ui_HgQueuesFoldDialog import Ui_HgQueuesFoldDialog import UI.PixmapCache class HgQueuesFoldDialog(QDialog, Ui_HgQueuesFoldDialog): """ Class implementing a dialog to enter data to fold patches. """ def __init__(self, patchesList, parent=None): """ Constructor @param patchesList list of patches to select from (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgQueuesFoldDialog, self).__init__(parent) self.setupUi(self) self.addButton.setIcon(UI.PixmapCache.getIcon("1downarrow.png")) self.removeButton.setIcon(UI.PixmapCache.getIcon("1uparrow.png")) self.upButton.setIcon(UI.PixmapCache.getIcon("1uparrow.png")) self.downButton.setIcon(UI.PixmapCache.getIcon("1downarrow.png")) for patch in patchesList: name, summary = patch.split("@@") QTreeWidgetItem(self.sourcePatches, [name, summary]) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) def __updateOkButton(self): """ Private slot to update the status of the OK button. """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( self.selectedPatches.topLevelItemCount() != 0) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add a patch to the list of selected patches. """ row = self.sourcePatches.indexOfTopLevelItem( self.sourcePatches.currentItem()) itm = self.sourcePatches.takeTopLevelItem(row) curItm = self.selectedPatches.currentItem() if curItm is not None: row = self.selectedPatches.indexOfTopLevelItem(curItm) + 1 self.selectedPatches.insertTopLevelItem(row, itm) else: self.selectedPatches.addTopLevelItem(itm) self.__updateOkButton() @pyqtSlot() def on_removeButton_clicked(self): """ Private slot to remove a patch from the list of selected patches. """ row = self.selectedPatches.indexOfTopLevelItem( self.selectedPatches.currentItem()) itm = self.selectedPatches.takeTopLevelItem(row) self.sourcePatches.addTopLevelItem(itm) self.sourcePatches.sortItems(0, Qt.AscendingOrder) self.__updateOkButton() @pyqtSlot() def on_upButton_clicked(self): """ Private slot to move a patch up in the list. """ row = self.selectedPatches.indexOfTopLevelItem( self.selectedPatches.currentItem()) if row > 0: targetRow = row - 1 itm = self.selectedPatches.takeTopLevelItem(row) self.selectedPatches.insertTopLevelItem(targetRow, itm) self.selectedPatches.setCurrentItem(itm) @pyqtSlot() def on_downButton_clicked(self): """ Private slot to move a patch down in the list. """ row = self.selectedPatches.indexOfTopLevelItem( self.selectedPatches.currentItem()) if row < self.selectedPatches.topLevelItemCount() - 1: targetRow = row + 1 itm = self.selectedPatches.takeTopLevelItem(row) self.selectedPatches.insertTopLevelItem(targetRow, itm) self.selectedPatches.setCurrentItem(itm) @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_sourcePatches_currentItemChanged(self, current, previous): """ Private slot to react on changes of the current item of source patches. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the previous current item (QTreeWidgetItem) """ self.addButton.setEnabled(current is not None) @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_selectedPatches_currentItemChanged(self, current, previous): """ Private slot to react on changes of the current item of selected patches. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the previous current item (QTreeWidgetItem) """ self.removeButton.setEnabled(current is not None) row = self.selectedPatches.indexOfTopLevelItem(current) self.upButton.setEnabled(row > 0) self.downButton.setEnabled( row < self.selectedPatches.topLevelItemCount() - 1) def getData(self): """ Public method to retrieve the entered data. @return tuple of commit message and list of selected patches (string, list of strings) """ patchesList = [] for row in range(self.selectedPatches.topLevelItemCount()): patchesList.append(self.selectedPatches.topLevelItem(row).text(0)) return self.messageEdit.toPlainText(), patchesList eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.py0000644000175000017500000003442512537064321030055 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to show a list of applied and unapplied patches. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, QProcess, Qt, QTimer, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, \ QTreeWidgetItem, QLineEdit from E5Gui import E5MessageBox from .Ui_HgQueuesListDialog import Ui_HgQueuesListDialog class HgQueuesListDialog(QDialog, Ui_HgQueuesListDialog): """ Class implementing a dialog to show a list of applied and unapplied patches. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(HgQueuesListDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = QProcess() self.vcs = vcs self.__hgClient = vcs.getClient() self.patchesList.header().setSortIndicator(0, Qt.AscendingOrder) self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.__statusDict = { "A": self.tr("applied"), "U": self.tr("not applied"), "G": self.tr("guarded"), "D": self.tr("missing"), } self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path): """ Public slot to start the list command. @param path name of directory to be listed (string) """ self.errorGroup.hide() self.intercept = False self.activateWindow() dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return self.__repodir = repodir self.__getSeries() def __getSeries(self, missing=False): """ Private slot to get the list of applied, unapplied and guarded patches and patches missing in the series file. @param missing flag indicating to get the patches missing in the series file (boolean) """ if missing: self.__mode = "missing" else: self.__mode = "qseries" args = self.vcs.initCommand("qseries") args.append('--summary') args.append('--verbose') if missing: args.append('--missing') if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): self.__mode = "" break if self.__mode == "qseries": self.__getSeries(True) elif self.__mode == "missing": self.__getTop() else: self.__finish() else: self.process.kill() self.process.setWorkingDirectory(self.__repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __getTop(self): """ Private slot to get patch at the top of the stack. """ self.__mode = "qtop" args = self.vcs.initCommand("qtop") if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(self.__repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.process = None if self.patchesList.topLevelItemCount() == 0: # no patches present self.__generateItem( 0, "", self.tr("no patches found"), "", True) self.__resizeColumns() self.__resort() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__mode = "" if self.__hgClient: self.__hgClient.cancel() else: self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ if self.__mode == "qseries": self.__getSeries(True) elif self.__mode == "missing": self.__getTop() else: self.__finish() def __resort(self): """ Private method to resort the tree. """ self.patchesList.sortItems( self.patchesList.sortColumn(), self.patchesList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.patchesList.header().resizeSections(QHeaderView.ResizeToContents) self.patchesList.header().setStretchLastSection(True) def __generateItem(self, index, status, name, summary, error=False): """ Private method to generate a patch item in the list of patches. @param index index of the patch (integer, -1 for missing) @param status status of the patch (string) @param name name of the patch (string) @param summary first line of the patch header (string) @param error flag indicating an error entry (boolean) """ if error: itm = QTreeWidgetItem(self.patchesList, [ "", name, "", summary ]) else: if index == -1: index = "" try: statusStr = self.__statusDict[status] except KeyError: statusStr = self.tr("unknown") itm = QTreeWidgetItem(self.patchesList) itm.setData(0, Qt.DisplayRole, index) itm.setData(1, Qt.DisplayRole, name) itm.setData(2, Qt.DisplayRole, statusStr) itm.setData(3, Qt.DisplayRole, summary) if status == "A": # applied for column in range(itm.columnCount()): itm.setForeground(column, Qt.blue) elif status == "D": # missing for column in range(itm.columnCount()): itm.setForeground(column, Qt.red) itm.setTextAlignment(0, Qt.AlignRight) itm.setTextAlignment(2, Qt.AlignHCenter) def __markTopItem(self, name): """ Private slot to mark the top patch entry. @param name name of the patch (string) """ items = self.patchesList.findItems(name, Qt.MatchCaseSensitive, 1) if items: itm = items[0] for column in range(itm.columnCount()): font = itm.font(column) font.setBold(True) itm.setFont(column, font) def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = str(self.process.readLine(), self.vcs.getEncoding(), 'replace').strip() self.__processOutputLine(s) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ if self.__mode == "qtop": self.__markTopItem(line) else: li = line.split(": ", 1) if len(li) == 1: data, summary = li[0][:-1], "" else: data, summary = li[0], li[1] li = data.split(None, 2) if len(li) == 2: # missing entry index, status, name = -1, li[0], li[1] elif len(li) == 3: index, status, name = li[:3] else: return self.__generateItem(index, status, name, summary) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgQueuesListDialog, self).keyPressEvent(evt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesGuardsSelectionDialog.py0000644000175000017500000000356012451233372032230 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to select a list of guards. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QListWidgetItem, \ QAbstractItemView from .Ui_HgQueuesGuardsSelectionDialog import Ui_HgQueuesGuardsSelectionDialog class HgQueuesGuardsSelectionDialog(QDialog, Ui_HgQueuesGuardsSelectionDialog): """ Class implementing a dialog to select a list of guards. """ def __init__(self, guards, activeGuards=None, listOnly=False, parent=None): """ Constructor @param guards list of guards to select from (list of strings) @keyparam activeGuards list of active guards (list of strings) @param listOnly flag indicating to only list the guards (boolean) @param parent reference to the parent widget (QWidget) """ super(HgQueuesGuardsSelectionDialog, self).__init__(parent) self.setupUi(self) for guard in guards: itm = QListWidgetItem(guard, self.guardsList) if activeGuards is not None and guard in activeGuards: font = itm.font() font.setBold(True) itm.setFont(font) self.guardsList.sortItems() if listOnly: self.buttonBox.button(QDialogButtonBox.Cancel).hide() self.guardsList.setSelectionMode(QAbstractItemView.NoSelection) self.setWindowTitle(self.tr("Active Guards")) def getData(self): """ Public method to retrieve the data. @return list of selected guards (list of strings) """ guardsList = [] for itm in self.guardsList.selectedItems(): guardsList.append(itm.text()) return guardsList eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesHeaderDialog.py0000644000175000017500000001433212451233372030324 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the commit message of the current patch. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QProcess, QTimer, Qt, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5MessageBox from .Ui_HgQueuesHeaderDialog import Ui_HgQueuesHeaderDialog class HgQueuesHeaderDialog(QDialog, Ui_HgQueuesHeaderDialog): """ Class implementing a dialog to show the commit message of the current patch. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent reference to the parent widget (QWidget) """ super(HgQueuesHeaderDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = QProcess() self.vcs = vcs self.__hgClient = vcs.getClient() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path): """ Public slot to start the list command. @param path name of directory to be listed (string) """ self.activateWindow() dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qheader") if self.__hgClient: out, err = self.__hgClient.runcommand( args, output=self.__showOutput, error=self.__showError) if err: self.__showError(err) if out: self.__showOutPut(out) self.__finish() else: self.process.kill() self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.process = None def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __readStdout(self): """ Private slot to handle the readyReadStdout signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.process is not None: s = str(self.process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') self.__showOutput(s) def __showOutput(self, out): """ Private slot to show some output. @param out output to be shown (string) """ self.messageEdit.appendPlainText(out) def __readStderr(self): """ Private slot to handle the readyReadStderr signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.messageEdit.appendPlainText(self.tr("Error: ")) self.messageEdit.appendPlainText(out) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesFoldDialog.ui0000644000175000017500000001702512060166053030004 0ustar piotrpiotr HgQueuesFoldDialog 0 0 450 600 Fold Patches true Message: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 1 Enter commit message for the folded patch true 0 2 QAbstractItemView::NoEditTriggers true false false true false Name Summary Qt::Horizontal 40 20 false Press to add the selected entry to the list of selected patches false Press to remove the selected entry from the list of selected patches Qt::Horizontal 40 20 0 2 QAbstractItemView::NoEditTriggers true false false false Name Summary Qt::Vertical 20 40 false Press to move the selected patch up false Press to move the selected patch down Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok messageEdit sourcePatches addButton removeButton selectedPatches upButton downButton buttonBox buttonBox accepted() HgQueuesFoldDialog accept() 248 254 157 274 buttonBox rejected() HgQueuesFoldDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListGuardsDialog.py0000644000175000017500000001020412537064320031207 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the guards of a selected patch. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer, QCoreApplication from PyQt5.QtWidgets import QDialog, QListWidgetItem from .Ui_HgQueuesListGuardsDialog import Ui_HgQueuesListGuardsDialog import UI.PixmapCache class HgQueuesListGuardsDialog(QDialog, Ui_HgQueuesListGuardsDialog): """ Class implementing a dialog to show the guards of a selected patch. """ def __init__(self, vcs, patchesList, parent=None): """ Constructor @param vcs reference to the vcs object @param patchesList list of patches (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgQueuesListGuardsDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.process = QProcess() self.vcs = vcs self.__hgClient = vcs.getClient() self.patchSelector.addItems([""] + patchesList) self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path): """ Public slot to start the list command. @param path name of directory to be listed (string) """ dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return self.__repodir = repodir self.on_patchSelector_activated("") @pyqtSlot(str) def on_patchSelector_activated(self, patch): """ Private slot to get the list of guards for the given patch name. @param patch selected patch name (empty for current patch) """ self.guardsList.clear() self.patchNameLabel.setText("") args = self.vcs.initCommand("qguard") if patch: args.append(patch) output = "" if self.__hgClient: output = self.__hgClient.runcommand(args)[0].strip() else: process = QProcess() process.setWorkingDirectory(self.__repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace').strip() if output: patchName, guards = output.split(":", 1) self.patchNameLabel.setText(patchName) guardsList = guards.strip().split() for guard in guardsList: if guard.startswith("+"): icon = UI.PixmapCache.getIcon("plus.png") guard = guard[1:] elif guard.startswith("-"): icon = UI.PixmapCache.getIcon("minus.png") guard = guard[1:] else: icon = None guard = self.tr("Unguarded") itm = QListWidgetItem(guard, self.guardsList) if icon: itm.setIcon(icon) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesDefineGuardsDialog.py0000644000175000017500000002547712537064320031510 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to define guards for patches. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer, QCoreApplication from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ QListWidgetItem from E5Gui import E5MessageBox from .Ui_HgQueuesDefineGuardsDialog import Ui_HgQueuesDefineGuardsDialog import UI.PixmapCache class HgQueuesDefineGuardsDialog(QDialog, Ui_HgQueuesDefineGuardsDialog): """ Class implementing a dialog to define guards for patches. """ def __init__(self, vcs, extension, patchesList, parent=None): """ Constructor @param vcs reference to the vcs object @param extension reference to the extension module (Queues) @param patchesList list of patches (list of strings) @param parent reference to the parent widget (QWidget) """ super(HgQueuesDefineGuardsDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.process = None self.vcs = vcs self.extension = extension self.__hgClient = vcs.getClient() self.__patches = patchesList[:] self.patchSelector.addItems([""] + self.__patches) self.plusButton.setIcon(UI.PixmapCache.getIcon("plus.png")) self.minusButton.setIcon(UI.PixmapCache.getIcon("minus.png")) self.__dirtyList = False self.__currentPatch = "" self.show() QCoreApplication.processEvents() def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) if self.__dirtyList: res = E5MessageBox.question( self, self.tr("Unsaved Changes"), self.tr("""The guards list has been changed.""" """ Shall the changes be applied?"""), E5MessageBox.StandardButtons( E5MessageBox.Apply | E5MessageBox.Discard), E5MessageBox.Apply) if res == E5MessageBox.Apply: self.__applyGuards() else: self.__dirtyList = False e.accept() def start(self, path): """ Public slot to start the list command. @param path name of directory to be listed (string) """ dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return self.__repodir = repodir self.on_patchSelector_activated("") @pyqtSlot(str) def on_patchSelector_activated(self, patch): """ Private slot to get the list of guards defined for the given patch name. @param patch selected patch name (empty for current patch) """ if self.__dirtyList: res = E5MessageBox.question( self, self.tr("Unsaved Changes"), self.tr("""The guards list has been changed.""" """ Shall the changes be applied?"""), E5MessageBox.StandardButtons( E5MessageBox.Apply | E5MessageBox.Discard), E5MessageBox.Apply) if res == E5MessageBox.Apply: self.__applyGuards() else: self.__dirtyList = False self.guardsList.clear() self.patchNameLabel.setText("") self.guardCombo.clear() guardsList = self.extension.getGuardsList(self.__repodir) self.guardCombo.addItems(guardsList) self.guardCombo.setEditText("") args = self.vcs.initCommand("qguard") if patch: args.append(patch) output = "" if self.__hgClient: output = self.__hgClient.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(self.__repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace').strip() if output: patchName, guards = output.split(":", 1) self.patchNameLabel.setText(patchName) guardsList = guards.strip().split() for guard in guardsList: if guard.startswith("+"): icon = UI.PixmapCache.getIcon("plus.png") guard = guard[1:] sign = "+" elif guard.startswith("-"): icon = UI.PixmapCache.getIcon("minus.png") guard = guard[1:] sign = "-" else: continue itm = QListWidgetItem(icon, guard, self.guardsList) itm.setData(Qt.UserRole, sign) self.on_guardsList_itemSelectionChanged() @pyqtSlot() def on_guardsList_itemSelectionChanged(self): """ Private slot to handle changes of the selection of guards. """ self.removeButton.setEnabled( len(self.guardsList.selectedItems()) > 0) def __getGuard(self, guard): """ Private method to get a reference to a named guard. @param guard name of the guard (string) @return reference to the guard item (QListWidgetItem) """ items = self.guardsList.findItems(guard, Qt.MatchCaseSensitive) if items: return items[0] else: return None @pyqtSlot(str) def on_guardCombo_editTextChanged(self, txt): """ Private slot to handle changes of the text of the guard combo. @param txt contents of the guard combo line edit (string) """ self.addButton.setEnabled(txt != "") @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add a guard definition to the list or change it. """ guard = self.guardCombo.currentText() if self.plusButton.isChecked(): sign = "+" icon = UI.PixmapCache.getIcon("plus.png") else: sign = "-" icon = UI.PixmapCache.getIcon("minus.png") guardItem = self.__getGuard(guard) if guardItem: # guard already exists, remove it first row = self.guardsList.row(guardItem) itm = self.guardsList.takeItem(row) del itm itm = QListWidgetItem(icon, guard, self.guardsList) itm.setData(Qt.UserRole, sign) self.guardsList.sortItems() self.__dirtyList = True @pyqtSlot() def on_removeButton_clicked(self): """ Private slot to remove guard definitions from the list. """ res = E5MessageBox.yesNo( self, self.tr("Remove Guards"), self.tr( """Do you really want to remove the selected guards?""")) if res: for guardItem in self.guardsList.selectedItems(): row = self.guardsList.row(guardItem) itm = self.guardsList.takeItem(row) del itm self.__dirtyList = True @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Apply): self.__applyGuards() elif button == self.buttonBox.button(QDialogButtonBox.Close): self.close() @pyqtSlot() def __applyGuards(self): """ Private slot to apply the defined guards to the current patch. """ if self.__dirtyList: guardsList = [] for row in range(self.guardsList.count()): itm = self.guardsList.item(row) guard = itm.data(Qt.UserRole) + itm.text() guardsList.append(guard) args = self.vcs.initCommand("qguard") args.append(self.patchNameLabel.text()) if guardsList: args.append("--") args.extend(guardsList) else: args.append("--none") error = "" if self.__hgClient: error = self.__hgClient.runcommand(args)[1] else: process = QProcess() process.setWorkingDirectory(self.__repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished: if process.exitCode() != 0: error = str(process.readAllStandardError(), self.vcs.getEncoding(), 'replace') else: E5MessageBox.warning( self, self.tr("Apply Guard Definitions"), self.tr( """The Mercurial process did not finish""" """ in time.""")) if error: E5MessageBox.warning( self, self.tr("Apply Guard Definitions"), self.tr("""

The defined guards could not be""" """ applied.

Reason: {0}

""") .format(error)) else: self.__dirtyList = False self.on_patchSelector_activated( self.patchNameLabel.text()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.ui0000644000175000017500000001164212060166053030032 0ustar piotrpiotr HgQueuesListDialog 0 0 634 494 List of Patches <b>List of Patches</b> <p>This dialog shows a list of applied and unapplied patches.</p> true 0 2 <b>Patches List</b> <p>This shows a list of applied and unapplied patches.</p> true false false # AlignLeft|AlignVCenter Name Status Summary 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource input passwordCheckBox sendButton patchesList errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py0000644000175000017500000010567012451233372025662 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the queues extension interface. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QProcess from PyQt5.QtWidgets import QDialog, QApplication, QInputDialog from E5Gui import E5MessageBox from ..HgExtension import HgExtension from ..HgDialog import HgDialog class Queues(HgExtension): """ Class implementing the queues extension interface. """ APPLIED_LIST = 0 UNAPPLIED_LIST = 1 SERIES_LIST = 2 POP = 0 PUSH = 1 GOTO = 2 QUEUE_DELETE = 0 QUEUE_PURGE = 1 QUEUE_ACTIVATE = 2 def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(Queues, self).__init__(vcs) self.qdiffDialog = None self.qheaderDialog = None self.queuesListDialog = None self.queuesListGuardsDialog = None self.queuesListAllGuardsDialog = None self.queuesDefineGuardsDialog = None self.queuesListQueuesDialog = None self.queueStatusDialog = None def shutdown(self): """ Public method used to shutdown the queues interface. """ if self.qdiffDialog is not None: self.qdiffDialog.close() if self.qheaderDialog is not None: self.qheaderDialog.close() if self.queuesListDialog is not None: self.queuesListDialog.close() if self.queuesListGuardsDialog is not None: self.queuesListGuardsDialog.close() if self.queuesListAllGuardsDialog is not None: self.queuesListAllGuardsDialog.close() if self.queuesDefineGuardsDialog is not None: self.queuesDefineGuardsDialog.close() if self.queuesListQueuesDialog is not None: self.queuesListQueuesDialog.close() if self.queueStatusDialog is not None: self.queueStatusDialog.close() def __getPatchesList(self, repodir, listType, withSummary=False): """ Private method to get a list of patches of a given type. @param repodir directory name of the repository (string) @param listType type of patches list to get (Queues.APPLIED_LIST, Queues.UNAPPLIED_LIST, Queues.SERIES_LIST) @param withSummary flag indicating to get a summary as well (boolean) @return list of patches (list of string) @exception ValueError raised to indicate an invalid patch list type """ patchesList = [] if listType == Queues.APPLIED_LIST: args = self.vcs.initCommand("qapplied") elif listType == Queues.UNAPPLIED_LIST: args = self.vcs.initCommand("qunapplied") elif listType == Queues.SERIES_LIST: args = self.vcs.initCommand("qseries") else: raise ValueError("illegal value for listType") if withSummary: args.append("--summary") client = self.vcs.getClient() output = "" if client: output = client.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') for line in output.splitlines(): if withSummary: li = line.strip().split(": ") if len(li) == 1: patch, summary = li[0][:-1], "" else: patch, summary = li[0], li[1] patchesList.append("{0}@@{1}".format(patch, summary)) else: patchesList.append(line.strip()) return patchesList def __getCurrentPatch(self, repodir): """ Private method to get the name of the current patch. @param repodir directory name of the repository (string) @return name of the current patch (string) """ currentPatch = "" args = self.vcs.initCommand("qtop") client = self.vcs.getClient() if client: currentPatch = client.runcommand(args)[0].strip() else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: currentPatch = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace').strip() return currentPatch def __getCommitMessage(self, repodir): """ Private method to get the commit message of the current patch. @param repodir directory name of the repository (string) @return name of the current patch (string) """ message = "" args = self.vcs.initCommand("qheader") client = self.vcs.getClient() if client: message = client.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: message = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') return message def getGuardsList(self, repodir, all=True): """ Public method to get a list of all guards defined. @param repodir directory name of the repository (string) @param all flag indicating to get all guards (boolean) @return sorted list of guards (list of strings) """ guardsList = [] args = self.vcs.initCommand("qselect") if all: args.append("--series") client = self.vcs.getClient() output = "" if client: output = client.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') for guard in output.splitlines(): guard = guard.strip() if all: guard = guard[1:] if guard not in guardsList: guardsList.append(guard) return sorted(guardsList) def hgQueueNewPatch(self, name): """ Public method to create a new named patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgQueuesNewPatchDialog import HgQueuesNewPatchDialog dlg = HgQueuesNewPatchDialog(HgQueuesNewPatchDialog.NEW_MODE) if dlg.exec_() == QDialog.Accepted: name, message, (userData, currentUser, userName), \ (dateData, currentDate, dateStr) = dlg.getData() args = self.vcs.initCommand("qnew") if message != "": args.append("--message") args.append(message) if userData: if currentUser: args.append("--currentuser") else: args.append("--user") args.append(userName) if dateData: if currentDate: args.append("--currentdate") else: args.append("--date") args.append(dateStr) args.append(name) dia = HgDialog(self.tr('New Patch'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() self.vcs.checkVCSStatus() def hgQueueRefreshPatch(self, name, editMessage=False): """ Public method to refresh the current patch. @param name file/directory name (string) @param editMessage flag indicating to edit the current commit message (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qrefresh") if editMessage: currentMessage = self.__getCommitMessage(repodir) from .HgQueuesNewPatchDialog import HgQueuesNewPatchDialog dlg = HgQueuesNewPatchDialog(HgQueuesNewPatchDialog.REFRESH_MODE, currentMessage) if dlg.exec_() == QDialog.Accepted: name, message, (userData, currentUser, userName), \ (dateData, currentDate, dateStr) = dlg.getData() if message != "" and message != currentMessage: args.append("--message") args.append(message) if userData: if currentUser: args.append("--currentuser") else: args.append("--user") args.append(userName) if dateData: if currentDate: args.append("--currentdate") else: args.append("--date") args.append(dateStr) else: return dia = HgDialog(self.tr('Update Current Patch'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() self.vcs.checkVCSStatus() def hgQueueShowPatch(self, name): """ Public method to show the contents of the current patch. @param name file/directory name (string) """ from ..HgDiffDialog import HgDiffDialog self.qdiffDialog = HgDiffDialog(self.vcs) self.qdiffDialog.show() QApplication.processEvents() self.qdiffDialog.start(name, qdiff=True) def hgQueueShowHeader(self, name): """ Public method to show the commit message of the current patch. @param name file/directory name (string) """ from .HgQueuesHeaderDialog import HgQueuesHeaderDialog self.qheaderDialog = HgQueuesHeaderDialog(self.vcs) self.qheaderDialog.show() QApplication.processEvents() self.qheaderDialog.start(name) def hgQueuePushPopPatches(self, name, operation, all=False, named=False, force=False): """ Public method to push patches onto the stack or pop patches off the stack. @param name file/directory name (string) @param operation operation type to be performed (Queues.POP, Queues.PUSH, Queues.GOTO) @keyparam all flag indicating to push/pop all (boolean) @keyparam named flag indicating to push/pop until a named patch is at the top of the stack (boolean) @keyparam force flag indicating a forceful pop (boolean) @return flag indicating that the project should be reread (boolean) @exception ValueError raised to indicate an invalid operation """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False if operation == Queues.POP: args = self.vcs.initCommand("qpop") title = self.tr("Pop Patches") listType = Queues.APPLIED_LIST elif operation == Queues.PUSH: args = self.vcs.initCommand("qpush") title = self.tr("Push Patches") listType = Queues.UNAPPLIED_LIST elif operation == Queues.GOTO: args = self.vcs.initCommand("qgoto") title = self.tr("Go to Patch") listType = Queues.SERIES_LIST else: raise ValueError("illegal value for operation") args.append("-v") if force: args.append("--force") if all and operation in (Queues.POP, Queues.PUSH): args.append("--all") elif named or operation == Queues.GOTO: patchnames = self.__getPatchesList(repodir, listType) if patchnames: patch, ok = QInputDialog.getItem( None, self.tr("Select Patch"), self.tr("Select the target patch name:"), patchnames, 0, False) if ok and patch: args.append(patch) else: return False else: E5MessageBox.information( None, self.tr("Select Patch"), self.tr("""No patches to select from.""")) return False dia = HgDialog(title, self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res def hgQueueListPatches(self, name): """ Public method to show a list of all patches. @param name file/directory name (string) """ from .HgQueuesListDialog import HgQueuesListDialog self.queuesListDialog = HgQueuesListDialog(self.vcs) self.queuesListDialog.show() self.queuesListDialog.start(name) def hgQueueFinishAppliedPatches(self, name): """ Public method to finish all applied patches. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qfinish") args.append("--applied") dia = HgDialog(self.tr('Finish Applied Patches'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() self.vcs.checkVCSStatus() def hgQueueRenamePatch(self, name): """ Public method to rename the current or a selected patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qrename") patchnames = sorted(self.__getPatchesList(repodir, Queues.SERIES_LIST)) if patchnames: currentPatch = self.__getCurrentPatch(repodir) if currentPatch: from .HgQueuesRenamePatchDialog import \ HgQueuesRenamePatchDialog dlg = HgQueuesRenamePatchDialog(currentPatch, patchnames) if dlg.exec_() == QDialog.Accepted: newName, selectedPatch = dlg.getData() if selectedPatch: args.append(selectedPatch) args.append(newName) dia = HgDialog(self.tr("Rename Patch"), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgQueueDeletePatch(self, name): """ Public method to delete a selected unapplied patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qdelete") patchnames = sorted(self.__getPatchesList(repodir, Queues.UNAPPLIED_LIST)) if patchnames: patch, ok = QInputDialog.getItem( None, self.tr("Select Patch"), self.tr("Select the patch to be deleted:"), patchnames, 0, False) if ok and patch: args.append(patch) dia = HgDialog(self.tr("Delete Patch"), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() else: E5MessageBox.information( None, self.tr("Select Patch"), self.tr("""No patches to select from.""")) def hgQueueFoldUnappliedPatches(self, name): """ Public method to fold patches into the current patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qfold") patchnames = sorted( self.__getPatchesList(repodir, Queues.UNAPPLIED_LIST, withSummary=True)) if patchnames: from .HgQueuesFoldDialog import HgQueuesFoldDialog dlg = HgQueuesFoldDialog(patchnames) if dlg.exec_() == QDialog.Accepted: message, patchesList = dlg.getData() if message: args.append("--message") args.append(message) if patchesList: args.extend(patchesList) dia = HgDialog(self.tr("Fold Patches"), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() else: E5MessageBox.information( None, self.tr("Fold Patches"), self.tr("""No patches selected.""")) else: E5MessageBox.information( None, self.tr("Fold Patches"), self.tr("""No patches available to be folded.""")) def hgQueueGuardsList(self, name): """ Public method to list the guards for the current or a named patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return patchnames = sorted( self.__getPatchesList(repodir, Queues.SERIES_LIST)) if patchnames: from .HgQueuesListGuardsDialog import HgQueuesListGuardsDialog self.queuesListGuardsDialog = \ HgQueuesListGuardsDialog(self.vcs, patchnames) self.queuesListGuardsDialog.show() self.queuesListGuardsDialog.start(name) else: E5MessageBox.information( None, self.tr("List Guards"), self.tr("""No patches available to list guards for.""")) def hgQueueGuardsListAll(self, name): """ Public method to list all guards of all patches. @param name file/directory name (string) """ from .HgQueuesListAllGuardsDialog import HgQueuesListAllGuardsDialog self.queuesListAllGuardsDialog = HgQueuesListAllGuardsDialog(self.vcs) self.queuesListAllGuardsDialog.show() self.queuesListAllGuardsDialog.start(name) def hgQueueGuardsDefine(self, name): """ Public method to define guards for the current or a named patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return patchnames = sorted( self.__getPatchesList(repodir, Queues.SERIES_LIST)) if patchnames: from .HgQueuesDefineGuardsDialog import HgQueuesDefineGuardsDialog self.queuesDefineGuardsDialog = HgQueuesDefineGuardsDialog( self.vcs, self, patchnames) self.queuesDefineGuardsDialog.show() self.queuesDefineGuardsDialog.start(name) else: E5MessageBox.information( None, self.tr("Define Guards"), self.tr("""No patches available to define guards for.""")) def hgQueueGuardsDropAll(self, name): """ Public method to drop all guards of the current or a named patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return patchnames = sorted( self.__getPatchesList(repodir, Queues.SERIES_LIST)) if patchnames: patch, ok = QInputDialog.getItem( None, self.tr("Drop All Guards"), self.tr("Select the patch to drop guards for" " (leave empty for the current patch):"), [""] + patchnames, 0, False) if ok: args = self.vcs.initCommand("qguard") if patch: args.append(patch) args.append("--none") client = self.vcs.getClient() if client: client.runcommand(args) else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: process.waitForFinished(30000) else: E5MessageBox.information( None, self.tr("Drop All Guards"), self.tr("""No patches available to define guards for.""")) def hgQueueGuardsSetActive(self, name): """ Public method to set the active guards. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return guardsList = self.getGuardsList(repodir) if guardsList: activeGuardsList = self.getGuardsList(repodir, all=False) from .HgQueuesGuardsSelectionDialog import \ HgQueuesGuardsSelectionDialog dlg = HgQueuesGuardsSelectionDialog( guardsList, activeGuards=activeGuardsList, listOnly=False) if dlg.exec_() == QDialog.Accepted: guards = dlg.getData() if guards: args = self.vcs.initCommand("qselect") args.extend(guards) dia = HgDialog(self.tr('Set Active Guards'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() else: E5MessageBox.information( None, self.tr("Set Active Guards"), self.tr("""No guards available to select from.""")) return def hgQueueGuardsDeactivate(self, name): """ Public method to deactivate all active guards. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qselect") args.append("--none") dia = HgDialog(self.tr('Deactivate Guards'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgQueueGuardsIdentifyActive(self, name): """ Public method to list all active guards. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return guardsList = self.getGuardsList(repodir, all=False) if guardsList: from .HgQueuesGuardsSelectionDialog import \ HgQueuesGuardsSelectionDialog dlg = HgQueuesGuardsSelectionDialog(guardsList, listOnly=True) dlg.exec_() def hgQueueCreateRenameQueue(self, name, isCreate): """ Public method to create a new queue or rename the active queue. @param name file/directory name (string) @param isCreate flag indicating to create a new queue (boolean) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if isCreate: title = self.tr("Create New Queue") else: title = self.tr("Rename Active Queue") from .HgQueuesQueueManagementDialog import \ HgQueuesQueueManagementDialog dlg = HgQueuesQueueManagementDialog( HgQueuesQueueManagementDialog.NAME_INPUT, title, False, repodir, self.vcs) if dlg.exec_() == QDialog.Accepted: queueName = dlg.getData() if queueName: args = self.vcs.initCommand("qqueue") if isCreate: args.append("--create") else: args.append("--rename") args.append(queueName) client = self.vcs.getClient() error = "" if client: error = client.runcommand(args)[1] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished: if process.exitCode() != 0: error = str(process.readAllStandardError(), self.vcs.getEncoding(), 'replace') if error: if isCreate: errMsg = self.tr( "Error while creating a new queue.") else: errMsg = self.tr( "Error while renaming the active queue.") E5MessageBox.warning( None, title, """

{0}

{1}

""".format(errMsg, error)) else: if self.queuesListQueuesDialog is not None and \ self.queuesListQueuesDialog.isVisible(): self.queuesListQueuesDialog.refresh() def hgQueueDeletePurgeActivateQueue(self, name, operation): """ Public method to delete the reference to a queue and optionally remove the patch directory or set the active queue. @param name file/directory name (string) @param operation operation to be performed (Queues.QUEUE_DELETE, Queues.QUEUE_PURGE, Queues.QUEUE_ACTIVATE) @exception ValueError raised to indicate an invalid operation """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if operation == Queues.QUEUE_PURGE: title = self.tr("Purge Queue") elif operation == Queues.QUEUE_DELETE: title = self.tr("Delete Queue") elif operation == Queues.QUEUE_ACTIVATE: title = self.tr("Activate Queue") else: raise ValueError("illegal value for operation") from .HgQueuesQueueManagementDialog import \ HgQueuesQueueManagementDialog dlg = HgQueuesQueueManagementDialog( HgQueuesQueueManagementDialog.QUEUE_INPUT, title, True, repodir, self.vcs) if dlg.exec_() == QDialog.Accepted: queueName = dlg.getData() if queueName: args = self.vcs.initCommand("qqueue") if operation == Queues.QUEUE_PURGE: args.append("--purge") elif operation == Queues.QUEUE_DELETE: args.append("--delete") args.append(queueName) client = self.vcs.getClient() error = "" if client: error = client.runcommand(args)[1] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished: if process.exitCode() != 0: error = str(process.readAllStandardError(), self.vcs.getEncoding(), 'replace') if error: if operation == Queues.QUEUE_PURGE: errMsg = self.tr("Error while purging the queue.") elif operation == Queues.QUEUE_DELETE: errMsg = self.tr("Error while deleting the queue.") elif operation == Queues.QUEUE_ACTIVATE: errMsg = self.tr( "Error while setting the active queue.") E5MessageBox.warning( None, title, """

{0}

{1}

""".format(errMsg, error)) else: if self.queuesListQueuesDialog is not None and \ self.queuesListQueuesDialog.isVisible(): self.queuesListQueuesDialog.refresh() def hgQueueListQueues(self, name): """ Public method to list available queues. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgQueuesQueueManagementDialog import \ HgQueuesQueueManagementDialog self.queuesListQueuesDialog = HgQueuesQueueManagementDialog( HgQueuesQueueManagementDialog.NO_INPUT, self.tr("Available Queues"), False, repodir, self.vcs) self.queuesListQueuesDialog.show() def hgQueueInit(self, name): """ Public method to initialize a new queue repository. @param name directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("init") args.append('--mq') args.append(repodir) # init is not possible with the command server dia = HgDialog( self.tr('Initializing new queue repository'), self.vcs) res = dia.startProcess(args) if res: dia.exec_() def hgQueueStatus(self, name): """ Public method used to view the status of a queue repository. @param name directory name (string) """ from ..HgStatusDialog import HgStatusDialog self.queueStatusDialog = HgStatusDialog(self.vcs, mq=True) self.queueStatusDialog.show() self.queueStatusDialog.start(name) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListGuardsDialog.ui0000644000175000017500000000624612060166053031204 0ustar piotrpiotr HgQueuesListGuardsDialog 0 0 400 400 List Guards true Select patch (leave empty for current patch): Select the patch to show the guards of Qt::Horizontal Patch: 0 0 Shows the name of the patch This shows the list of guards defined for the selected patch true Qt::Horizontal QDialogButtonBox::Close patchSelector guardsList buttonBox buttonBox accepted() HgQueuesListGuardsDialog accept() 248 254 157 274 buttonBox rejected() HgQueuesListGuardsDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgOptionsDialog.ui0000644000175000017500000000603712060166053024220 0ustar piotrpiotr HgOptionsDialog 0 0 565 78 Repository Infos <b>Repository Infos Dialog</b> <p>Enter the various infos into the entry fields. These values are used to generate a new project in the repository. If the checkbox is selected, the URL must end in the project name. A directory tree with project/tags, project/branches and project/trunk will be generated in the repository. If the checkbox is not selected, the URL must contain the complete path in the repository.</p> <p>For remote repositories the URL must contain the hostname.</p> true Commit &Message: vcsLogEdit Enter the log message for the new project. <b>Log Message</b> <p>Enter the log message to be used for the new project.</p> new project started Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource vcsLogEdit buttonBox accepted() HgOptionsDialog accept() 56 68 51 77 buttonBox rejected() HgOptionsDialog reject() 213 68 205 77 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.ui0000644000175000017500000002103712270250053023616 0ustar piotrpiotr HgMergeDialog 0 0 372 305 Mercurial Merge true Revision Select to specify a revision by number Number false Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 158 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false Enter a tag name true Select to specify a revision by a branch Branch: false Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select to not specify a specific revision No revision selected true Select to force the merge operation Enforce merge Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok numberButton numberSpinBox idButton idEdit tagButton tagCombo branchButton branchCombo bookmarkButton bookmarkCombo noneButton forceCheckBox buttonBox buttonBox accepted() HgMergeDialog accept() 261 244 157 229 buttonBox rejected() HgMergeDialog reject() 329 244 286 229 numberButton toggled(bool) numberSpinBox setEnabled(bool) 48 42 113 43 idButton toggled(bool) idEdit setEnabled(bool) 38 76 125 75 tagButton toggled(bool) tagCombo setEnabled(bool) 52 104 124 99 branchButton toggled(bool) branchCombo setEnabled(bool) 71 127 123 130 bookmarkButton toggled(bool) bookmarkCombo setEnabled(bool) 71 145 121 149 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/hg.py0000644000175000017500000042621512451233372021606 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the version control systems interface to Mercurial. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os import shutil import re from PyQt5.QtCore import QProcess, pyqtSignal, QFileInfo, QFileSystemWatcher, \ QCoreApplication from PyQt5.QtWidgets import QApplication, QDialog, QInputDialog from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog from QScintilla.MiniEditor import MiniEditor from VCS.VersionControl import VersionControl from VCS.RepositoryInfoDialog import VcsRepositoryInfoDialog from .HgDialog import HgDialog import Utilities class Hg(VersionControl): """ Class implementing the version control systems interface to Mercurial. @signal committed() emitted after the commit action has completed @signal activeExtensionsChanged() emitted when the list of active extensions has changed @signal iniFileChanged() emitted when a Mercurial/repo configuration file has changed """ committed = pyqtSignal() activeExtensionsChanged = pyqtSignal() iniFileChanged = pyqtSignal() IgnoreFileName = ".hgignore" def __init__(self, plugin, parent=None, name=None): """ Constructor @param plugin reference to the plugin object @param parent parent widget (QWidget) @param name name of this object (string) """ VersionControl.__init__(self, parent, name) self.defaultOptions = { 'global': [''], 'commit': [''], 'checkout': [''], 'update': [''], 'add': [''], 'remove': [''], 'diff': [''], 'log': [''], 'history': [''], 'status': [''], 'tag': [''], 'export': [''] } self.__plugin = plugin self.__ui = parent self.options = self.defaultOptions self.tagsList = [] self.branchesList = [] self.allTagsBranchesList = [] self.bookmarksList = [] self.showedTags = False self.showedBranches = False self.tagTypeList = [ 'tags', 'branches', ] self.commandHistory = [] if "HG_ASP_DOT_NET_HACK" in os.environ: self.adminDir = '_hg' else: self.adminDir = '.hg' self.log = None self.logBrowser = None self.logBrowserIncoming = None self.logBrowserOutgoing = None self.diff = None self.sbsDiff = None self.status = None self.summary = None self.tagbranchList = None self.annotate = None self.repoEditor = None self.userEditor = None self.serveDlg = None self.bookmarksListDlg = None self.bookmarksInOutDlg = None self.conflictsDlg = None self.bundleFile = None self.__lastChangeGroupPath = None self.statusCache = {} self.__commitData = {} self.__commitDialog = None self.__forgotNames = [] self.__activeExtensions = [] from .HgUtilities import getConfigPath self.__iniWatcher = QFileSystemWatcher(self) self.__iniWatcher.fileChanged.connect(self.__iniFileChanged) cfgFile = getConfigPath() if os.path.exists(cfgFile): self.__iniWatcher.addPath(cfgFile) self.__client = None self.__repoDir = "" self.__repoIniFile = "" self.__defaultConfigured = False self.__defaultPushConfigured = False # instantiate the extensions from .QueuesExtension.queues import Queues from .FetchExtension.fetch import Fetch from .PurgeExtension.purge import Purge from .GpgExtension.gpg import Gpg from .TransplantExtension.transplant import Transplant from .RebaseExtension.rebase import Rebase from .ShelveExtension.shelve import Shelve from .LargefilesExtension.largefiles import Largefiles self.__extensions = { "mq": Queues(self), "fetch": Fetch(self), "purge": Purge(self), "gpg": Gpg(self), "transplant": Transplant(self), "rebase": Rebase(self), "shelve": Shelve(self), "largefiles": Largefiles(self) } def getPlugin(self): """ Public method to get a reference to the plugin object. @return reference to the plugin object (VcsMercurialPlugin) """ return self.__plugin def getEncoding(self): """ Public method to get the encoding to be used by Mercurial. @return encoding (string) """ return self.__plugin.getPreferences("Encoding") def vcsShutdown(self): """ Public method used to shutdown the Mercurial interface. """ if self.log is not None: self.log.close() if self.logBrowser is not None: self.logBrowser.close() if self.logBrowserIncoming is not None: self.logBrowserIncoming.close() if self.logBrowserOutgoing is not None: self.logBrowserOutgoing.close() if self.diff is not None: self.diff.close() if self.sbsDiff is not None: self.sbsDiff.close() if self.status is not None: self.status.close() if self.summary is not None: self.summary.close() if self.tagbranchList is not None: self.tagbranchList.close() if self.annotate is not None: self.annotate.close() if self.serveDlg is not None: self.serveDlg.close() if self.bookmarksListDlg is not None: self.bookmarksListDlg.close() if self.bookmarksInOutDlg is not None: self.bookmarksInOutDlg.close() if self.conflictsDlg is not None: self.conflictsDlg.close() if self.bundleFile and os.path.exists(self.bundleFile): os.remove(self.bundleFile) # shut down the project helpers self.__projectHelper.shutdown() # shut down the extensions for extension in self.__extensions.values(): extension.shutdown() # shut down the client self.__client and self.__client.stopServer() def getClient(self): """ Public method to get a reference to the command server interface. @return reference to the client (HgClient) """ return self.__client def initCommand(self, command): """ Public method to initialize a command arguments list. @param command command name (string) @return list of command options (list of string) """ args = [command] self.addArguments(args, self.__plugin.getGlobalOptions()) return args def vcsExists(self): """ Public method used to test for the presence of the hg executable. @return flag indicating the existance (boolean) and an error message (string) """ self.versionStr = '' errMsg = "" args = self.initCommand("version") process = QProcess() process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') self.versionStr = output.splitlines()[0].split()[-1][0:-1] v = list(re.match(r'.*?(\d+)\.(\d+)\.?(\d+)?(\+[0-9a-f-]+)?', self.versionStr).groups()) for i in range(3): try: v[i] = int(v[i]) except TypeError: v[i] = 0 except IndexError: v.append(0) self.version = tuple(v) self.__getExtensionsInfo() return True, errMsg else: if finished: errMsg = self.tr( "The hg process finished with the exit code {0}")\ .format(process.exitCode()) else: errMsg = self.tr( "The hg process did not finish within 30s.") else: errMsg = self.tr("Could not start the hg executable.") return False, errMsg def vcsInit(self, vcsDir, noDialog=False): """ Public method used to initialize the mercurial repository. The initialization is done, when a project is converted into a Mercurial controlled project. Therefore we always return TRUE without doing anything. @param vcsDir name of the VCS directory (string) @param noDialog flag indicating quiet operations (boolean) @return always TRUE """ return True def vcsConvertProject(self, vcsDataDict, project): """ Public method to convert an uncontrolled project to a version controlled project. @param vcsDataDict dictionary of data required for the conversion @param project reference to the project object """ success = self.vcsImport(vcsDataDict, project.ppath)[0] if not success: E5MessageBox.critical( self.__ui, self.tr("Create project repository"), self.tr( """The project repository could not be created.""")) else: pfn = project.pfile if not os.path.isfile(pfn): pfn += "z" project.closeProject() project.openProject(pfn) def vcsImport(self, vcsDataDict, projectDir, noDialog=False): """ Public method used to import the project into the Mercurial repository. @param vcsDataDict dictionary of data required for the import @param projectDir project directory (string) @param noDialog flag indicating quiet operations @return flag indicating an execution without errors (boolean) and a flag indicating the version controll status (boolean) """ msg = vcsDataDict["message"] if not msg: msg = '***' args = self.initCommand("init") args.append(projectDir) # init is not possible with the command server dia = HgDialog(self.tr('Creating Mercurial repository'), self) res = dia.startProcess(args) if res: dia.exec_() status = dia.normalExit() if status: ignoreName = os.path.join(projectDir, Hg.IgnoreFileName) if not os.path.exists(ignoreName): status = self.hgCreateIgnoreFile(projectDir) if status: args = self.initCommand("commit") args.append('--addremove') args.append('--message') args.append(msg) dia = HgDialog( self.tr('Initial commit to Mercurial repository'), self) res = dia.startProcess(args, projectDir) if res: dia.exec_() status = dia.normalExit() return status, False def vcsCheckout(self, vcsDataDict, projectDir, noDialog=False): """ Public method used to check the project out of a Mercurial repository (clone). @param vcsDataDict dictionary of data required for the checkout @param projectDir project directory to create (string) @param noDialog flag indicating quiet operations @return flag indicating an execution without errors (boolean) """ noDialog = False try: rev = vcsDataDict["revision"] except KeyError: rev = None vcsUrl = self.hgNormalizeURL(vcsDataDict["url"]) if vcsUrl.startswith('/'): vcsUrl = 'file://{0}'.format(vcsUrl) elif vcsUrl[1] in ['|', ':']: vcsUrl = 'file:///{0}'.format(vcsUrl) args = self.initCommand("clone") if rev: args.append("--rev") args.append(rev) if vcsDataDict["largefiles"]: args.append("--all-largefiles") args.append(self.__hgURL(vcsUrl)) args.append(projectDir) if noDialog: if self.__client is None: return self.startSynchronizedProcess(QProcess(), 'hg', args) else: out, err = self.__client.runcommand(args) return err == "" else: dia = HgDialog( self.tr('Cloning project from a Mercurial repository'), self) res = dia.startProcess(args) if res: dia.exec_() return dia.normalExit() def vcsExport(self, vcsDataDict, projectDir): """ Public method used to export a directory from the Mercurial repository. @param vcsDataDict dictionary of data required for the checkout @param projectDir project directory to create (string) @return flag indicating an execution without errors (boolean) """ status = self.vcsCheckout(vcsDataDict, projectDir) shutil.rmtree(os.path.join(projectDir, self.adminDir), True) if os.path.exists(os.path.join(projectDir, Hg.IgnoreFileName)): os.remove(os.path.join(projectDir, Hg.IgnoreFileName)) return status def vcsCommit(self, name, message, noDialog=False, closeBranch=False, mq=False): """ Public method used to make the change of a file/directory permanent in the Mercurial repository. @param name file/directory name to be committed (string or list of strings) @param message message for this operation (string) @param noDialog flag indicating quiet operations @keyparam closeBranch flag indicating a close branch commit (boolean) @keyparam mq flag indicating a queue commit (boolean) """ msg = message if mq: # ensure dialog is shown for a queue commit noDialog = False if not noDialog: # call CommitDialog and get message from there if self.__commitDialog is None: from .HgCommitDialog import HgCommitDialog self.__commitDialog = HgCommitDialog(self, msg, mq, self.__ui) self.__commitDialog.accepted.connect(self.__vcsCommit_Step2) self.__commitDialog.show() self.__commitDialog.raise_() self.__commitDialog.activateWindow() self.__commitData["name"] = name self.__commitData["msg"] = msg self.__commitData["noDialog"] = noDialog self.__commitData["closeBranch"] = closeBranch self.__commitData["mq"] = mq if noDialog: self.__vcsCommit_Step2() def __vcsCommit_Step2(self): """ Private slot performing the second step of the commit action. """ name = self.__commitData["name"] msg = self.__commitData["msg"] noDialog = self.__commitData["noDialog"] closeBranch = self.__commitData["closeBranch"] mq = self.__commitData["mq"] if not noDialog: # check, if there are unsaved changes, that should be committed if isinstance(name, list): nameList = name else: nameList = [name] ok = True for nam in nameList: # check for commit of the project if os.path.isdir(nam): project = e5App().getObject("Project") if nam == project.getProjectPath(): ok &= \ project.checkAllScriptsDirty( reportSyntaxErrors=True) and \ project.checkDirty() continue elif os.path.isfile(nam): editor = \ e5App().getObject("ViewManager").getOpenEditor(nam) if editor: ok &= editor.checkDirty() if not ok: break if not ok: res = E5MessageBox.yesNo( self.__ui, self.tr("Commit Changes"), self.tr( """The commit affects files, that have unsaved""" """ changes. Shall the commit be continued?"""), icon=E5MessageBox.Warning) if not res: return if self.__commitDialog is not None: msg = self.__commitDialog.logMessage() amend = self.__commitDialog.amend() commitSubrepositories = self.__commitDialog.commitSubrepositories() self.__commitDialog.deleteLater() self.__commitDialog = None else: amend = False commitSubrepositories = False if not msg and not amend: msg = '***' args = self.initCommand("commit") args.append("-v") if mq: args.append("--mq") else: if closeBranch: args.append("--close-branch") if amend: args.append("--amend") if commitSubrepositories: args.append("--subrepos") if msg: args.append("--message") args.append(msg) if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if self.__client: if isinstance(name, list): self.addArguments(args, name) else: if dname != repodir or fname != ".": args.append(name) else: if isinstance(name, list): self.addArguments(args, fnames) else: if dname != repodir or fname != ".": args.append(fname) if noDialog: self.startSynchronizedProcess(QProcess(), "hg", args, dname) else: dia = HgDialog( self.tr('Committing changes to Mercurial repository'), self) res = dia.startProcess(args, dname) if res: dia.exec_() self.committed.emit() if self.__forgotNames: model = e5App().getObject("Project").getModel() for name in self.__forgotNames: model.updateVCSStatus(name) self.__forgotNames = [] self.checkVCSStatus() def vcsUpdate(self, name, noDialog=False, revision=None): """ Public method used to update a file/directory with the Mercurial repository. @param name file/directory name to be updated (string or list of strings) @param noDialog flag indicating quiet operations (boolean) @keyparam revision revision to update to (string) @return flag indicating, that the update contained an add or delete (boolean) """ args = self.initCommand("update") if "-v" not in args and "--verbose" not in args: args.append("-v") if revision: args.append("-r") args.append(revision) if isinstance(name, list): dname, fnames = self.splitPathList(name) else: dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False if noDialog: if self.__client is None: self.startSynchronizedProcess(QProcess(), 'hg', args, repodir) else: out, err = self.__client.runcommand(args) res = False else: dia = HgDialog(self.tr( 'Synchronizing with the Mercurial repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() return res def vcsAdd(self, name, isDir=False, noDialog=False): """ Public method used to add a file/directory to the Mercurial repository. @param name file/directory name to be added (string) @param isDir flag indicating name is a directory (boolean) @param noDialog flag indicating quiet operations """ args = self.initCommand("add") args.append("-v") if isinstance(name, list): if isDir: dname, fname = os.path.split(name[0]) else: dname, fnames = self.splitPathList(name) else: if isDir: dname, fname = os.path.split(name) else: dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if isinstance(name, list): self.addArguments(args, name) else: args.append(name) if noDialog: if self.__client is None: self.startSynchronizedProcess(QProcess(), 'hg', args, repodir) else: out, err = self.__client.runcommand(args) else: dia = HgDialog( self.tr( 'Adding files/directories to the Mercurial repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def vcsAddBinary(self, name, isDir=False): """ Public method used to add a file/directory in binary mode to the Mercurial repository. @param name file/directory name to be added (string) @param isDir flag indicating name is a directory (boolean) """ self.vcsAdd(name, isDir) def vcsAddTree(self, path): """ Public method to add a directory tree rooted at path to the Mercurial repository. @param path root directory of the tree to be added (string or list of strings)) """ self.vcsAdd(path, isDir=False) def vcsRemove(self, name, project=False, noDialog=False): """ Public method used to remove a file/directory from the Mercurial repository. The default operation is to remove the local copy as well. @param name file/directory name to be removed (string or list of strings)) @param project flag indicating deletion of a project tree (boolean) (not needed) @param noDialog flag indicating quiet operations @return flag indicating successfull operation (boolean) """ args = self.initCommand("remove") args.append("-v") if noDialog and '--force' not in args: args.append('--force') if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, name) else: dname, fname = self.splitPath(name) args.append(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False if noDialog: if self.__client is None: res = self.startSynchronizedProcess( QProcess(), 'hg', args, repodir) else: out, err = self.__client.runcommand(args) res = err == "" else: dia = HgDialog( self.tr( 'Removing files/directories from the Mercurial' ' repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.normalExitWithoutErrors() return res def vcsMove(self, name, project, target=None, noDialog=False): """ Public method used to move a file/directory. @param name file/directory name to be moved (string) @param project reference to the project object @param target new name of the file/directory (string) @param noDialog flag indicating quiet operations @return flag indicating successfull operation (boolean) """ isDir = os.path.isdir(name) res = False if noDialog: if target is None: return False force = True accepted = True else: from .HgCopyDialog import HgCopyDialog dlg = HgCopyDialog(name, None, True) accepted = dlg.exec_() == QDialog.Accepted if accepted: target, force = dlg.getData() if accepted: args = self.initCommand("rename") args.append("-v") if force: args.append('--force') args.append(name) args.append(target) dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False if noDialog: if self.__client is None: res = self.startSynchronizedProcess( QProcess(), 'hg', args, repodir) else: out, err = self.__client.runcommand(args) res = err == "" else: dia = HgDialog(self.tr('Renaming {0}').format(name), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.normalExit() if res: if target.startswith(project.getProjectPath()): if isDir: project.moveDirectory(name, target) else: project.renameFileInPdata(name, target) else: if isDir: project.removeDirectory(name) else: project.removeFile(name) return res def vcsLog(self, name): """ Public method used to view the log of a file/directory from the Mercurial repository. @param name file/directory name to show the log of (string) """ dname, fname = self.splitPath(name) isFile = os.path.isfile(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgMultiRevisionSelectionDialog import \ HgMultiRevisionSelectionDialog dlg = HgMultiRevisionSelectionDialog( self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir), emptyRevsOk=True, showLimit=True, limitDefault=self.getPlugin().getPreferences("LogLimit")) if dlg.exec_() == QDialog.Accepted: revs, noEntries = dlg.getRevisions() from .HgLogDialog import HgLogDialog self.log = HgLogDialog(self, isFile=isFile) self.log.show() self.log.start(name, noEntries=noEntries, revisions=revs) def vcsDiff(self, name): """ Public method used to view the difference of a file/directory to the Mercurial repository. If name is a directory and is the project directory, all project files are saved first. If name is a file (or list of files), which is/are being edited and has unsaved modification, they can be saved or the operation may be aborted. @param name file/directory name to be diffed (string) """ if isinstance(name, list): names = name[:] else: names = [name] for nam in names: if os.path.isfile(nam): editor = e5App().getObject("ViewManager").getOpenEditor(nam) if editor and not editor.checkDirty(): return else: project = e5App().getObject("Project") if nam == project.ppath and not project.saveAllScripts(): return from .HgDiffDialog import HgDiffDialog self.diff = HgDiffDialog(self) self.diff.show() QApplication.processEvents() self.diff.start(name) def vcsStatus(self, name): """ Public method used to view the status of files/directories in the Mercurial repository. @param name file/directory name(s) to show the status of (string or list of strings) """ from .HgStatusDialog import HgStatusDialog self.status = HgStatusDialog(self) self.status.show() self.status.start(name) def hgSummary(self, mq=False, largefiles=False): """ Public method used to show some summary information of the working directory state. @param mq flag indicating to show the queue status as well (boolean) @param largefiles flag indicating to show the largefiles status as well (boolean) """ from .HgSummaryDialog import HgSummaryDialog self.summary = HgSummaryDialog(self) self.summary.show() self.summary.start(self.__projectHelper.getProject().getProjectPath(), mq=mq, largefiles=largefiles) def vcsTag(self, name, revision=None, tagName=None): """ Public method used to set/remove a tag in the Mercurial repository. @param name file/directory name to determine the repo root from (string) @param revision revision to set tag for (string) @param tagName name of the tag (string) @return flag indicating a performed tag action (boolean) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgTagDialog import HgTagDialog dlg = HgTagDialog(self.hgGetTagsList(repodir, withType=True), revision, tagName) if dlg.exec_() == QDialog.Accepted: tag, revision, tagOp = dlg.getParameters() else: return False args = self.initCommand("tag") msgPart = "" if tagOp in [HgTagDialog.CreateLocalTag, HgTagDialog.DeleteLocalTag]: args.append('--local') msgPart = "local " else: msgPart = "global " if tagOp in [HgTagDialog.DeleteGlobalTag, HgTagDialog.DeleteLocalTag]: args.append('--remove') if tagOp in [HgTagDialog.CreateGlobalTag, HgTagDialog.CreateLocalTag]: if revision: args.append("--rev") args.append(revision) args.append('--message') if tagOp in [HgTagDialog.CreateGlobalTag, HgTagDialog.CreateLocalTag]: tag = tag.strip().replace(" ", "_") args.append("Created {1}tag <{0}>.".format(tag, msgPart)) else: args.append("Removed {1}tag <{0}>.".format(tag, msgPart)) args.append(tag) dia = HgDialog(self.tr('Tagging in the Mercurial repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() return True def hgRevert(self, name): """ Public method used to revert changes made to a file/directory. @param name file/directory name to be reverted (string) @return flag indicating, that the update contained an add or delete (boolean) """ args = self.initCommand("revert") if not self.getPlugin().getPreferences("CreateBackup"): args.append("--no-backup") args.append("-v") if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, name) names = name[:] else: dname, fname = self.splitPath(name) args.append(name) names = [name] # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False project = e5App().getObject("Project") names = [project.getRelativePath(nam) for nam in names] if names[0]: from UI.DeleteFilesConfirmationDialog import \ DeleteFilesConfirmationDialog dlg = DeleteFilesConfirmationDialog( self.parent(), self.tr("Revert changes"), self.tr( "Do you really want to revert all changes to these files" " or directories?"), names) yes = dlg.exec_() == QDialog.Accepted else: yes = E5MessageBox.yesNo( None, self.tr("Revert changes"), self.tr("""Do you really want to revert all changes of""" """ the project?""")) if yes: dia = HgDialog(self.tr('Reverting changes'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() else: res = False return res def vcsMerge(self, name): """ Public method used to merge a URL/revision into the local project. @param name file/directory name to be merged (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgMergeDialog import HgMergeDialog dlg = HgMergeDialog(self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: rev, force = dlg.getParameters() else: return args = self.initCommand("merge") if force: args.append("--force") if self.getPlugin().getPreferences("InternalMerge"): args.append("--tool") args.append("internal:merge") if rev: args.append("--rev") args.append(rev) dia = HgDialog(self.tr('Merging').format(name), self) res = dia.startProcess(args, repodir) if res: dia.exec_() self.checkVCSStatus() def hgReMerge(self, name): """ Public method used to merge a URL/revision into the local project. @param name file/directory name to be merged (string) """ args = self.initCommand("resolve") if self.getPlugin().getPreferences("InternalMerge"): args.append("--tool") args.append("internal:merge") if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, name) names = name[:] else: dname, fname = self.splitPath(name) args.append(name) names = [name] # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return project = e5App().getObject("Project") names = [project.getRelativePath(nam) for nam in names] if names[0]: from UI.DeleteFilesConfirmationDialog import \ DeleteFilesConfirmationDialog dlg = DeleteFilesConfirmationDialog( self.parent(), self.tr("Re-Merge"), self.tr( "Do you really want to re-merge these files" " or directories?"), names) yes = dlg.exec_() == QDialog.Accepted else: yes = E5MessageBox.yesNo( None, self.tr("Re-Merge"), self.tr("""Do you really want to re-merge the project?""")) if yes: dia = HgDialog(self.tr('Re-Merging').format(name), self) res = dia.startProcess(args, repodir) if res: dia.exec_() self.checkVCSStatus() def vcsSwitch(self, name): """ Public method used to switch a working directory to a different revision. @param name directory name to be switched (string) @return flag indicating, that the switch contained an add or delete (boolean) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False from .HgRevisionSelectionDialog import HgRevisionSelectionDialog dlg = HgRevisionSelectionDialog(self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir), self.tr("Current branch tip")) if dlg.exec_() == QDialog.Accepted: rev = dlg.getRevision() return self.vcsUpdate(name, revision=rev) return False def vcsRegisteredState(self, name): """ Public method used to get the registered state of a file in the vcs. @param name filename to check (string) @return a combination of canBeCommited and canBeAdded """ if name.endswith(os.sep): name = name[:-1] name = os.path.normcase(name) dname, fname = self.splitPath(name) if fname == '.' and os.path.isdir(os.path.join(dname, self.adminDir)): return self.canBeCommitted if name in self.statusCache: return self.statusCache[name] # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return 0 args = self.initCommand("status") args.append('--all') args.append('--noninteractive') output = "" if self.__client is None: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) if output: for line in output.splitlines(): if line and line[0] in "MARC!?I": flag, path = line.split(" ", 1) absname = os.path.join(repodir, os.path.normcase(path)) if flag not in "?I": if fname == '.': if absname.startswith(dname + os.path.sep): return self.canBeCommitted if absname == dname: return self.canBeCommitted else: if absname == name: return self.canBeCommitted return self.canBeAdded def vcsAllRegisteredStates(self, names, dname, shortcut=True): """ Public method used to get the registered states of a number of files in the vcs. Note: If a shortcut is to be taken, the code will only check, if the named directory has been scanned already. If so, it is assumed, that the states for all files have been populated by the previous run. @param names dictionary with all filenames to be checked as keys @param dname directory to check in (string) @param shortcut flag indicating a shortcut should be taken (boolean) @return the received dictionary completed with a combination of canBeCommited and canBeAdded or None in order to signal an error """ if dname.endswith(os.sep): dname = dname[:-1] dname = os.path.normcase(dname) found = False for name in list(self.statusCache.keys()): if name in names: found = True names[name] = self.statusCache[name] if not found: # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return names args = self.initCommand("status") args.append('--all') args.append('--noninteractive') output = "" if self.__client is None: process = QProcess() process.setWorkingDirectory(dname) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) if output: dirs = [x for x in names.keys() if os.path.isdir(x)] for line in output.splitlines(): if line and line[0] in "MARC!?I": flag, path = line.split(" ", 1) name = os.path.normcase(os.path.join(repodir, path)) dirName = os.path.dirname(name) if name.startswith(dname): if flag not in "?I": if name in names: names[name] = self.canBeCommitted if dirName in names: names[dirName] = self.canBeCommitted if dirs: for d in dirs: if name.startswith(d): names[d] = self.canBeCommitted dirs.remove(d) break if flag not in "?I": self.statusCache[name] = self.canBeCommitted self.statusCache[dirName] = self.canBeCommitted else: self.statusCache[name] = self.canBeAdded if dirName not in self.statusCache: self.statusCache[dirName] = self.canBeAdded return names def clearStatusCache(self): """ Public method to clear the status cache. """ self.statusCache = {} def vcsName(self): """ Public method returning the name of the vcs. @return always 'Mercurial' (string) """ return "Mercurial" def vcsInitConfig(self, project): """ Public method to initialize the VCS configuration. This method ensures, that an ignore file exists. @param project reference to the project (Project) """ ppath = project.getProjectPath() if ppath: ignoreName = os.path.join(ppath, Hg.IgnoreFileName) if not os.path.exists(ignoreName): self.hgCreateIgnoreFile(project.getProjectPath(), autoAdd=True) def vcsCleanup(self, name): """ Public method used to cleanup the working directory. @param name directory name to be cleaned up (string) """ patterns = self.getPlugin().getPreferences("CleanupPatterns").split() entries = [] for pat in patterns: entries.extend(Utilities.direntries(name, True, pat)) for entry in entries: try: os.remove(entry) except OSError: pass def vcsCommandLine(self, name): """ Public method used to execute arbitrary mercurial commands. @param name directory name of the working directory (string) """ from .HgCommandDialog import HgCommandDialog dlg = HgCommandDialog(self.commandHistory, name) if dlg.exec_() == QDialog.Accepted: command = dlg.getData() commandList = Utilities.parseOptionString(command) # This moves any previous occurrence of these arguments to the head # of the list. if command in self.commandHistory: self.commandHistory.remove(command) self.commandHistory.insert(0, command) args = [] self.addArguments(args, commandList) # find the root of the repo repodir = name while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return dia = HgDialog(self.tr('Mercurial command'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def vcsOptionsDialog(self, project, archive, editable=False, parent=None): """ Public method to get a dialog to enter repository info. @param project reference to the project object @param archive name of the project in the repository (string) @param editable flag indicating that the project name is editable (boolean) @param parent parent widget (QWidget) @return reference to the instantiated options dialog (HgOptionsDialog) """ from .HgOptionsDialog import HgOptionsDialog return HgOptionsDialog(self, project, parent) def vcsNewProjectOptionsDialog(self, parent=None): """ Public method to get a dialog to enter repository info for getting a new project. @param parent parent widget (QWidget) @return reference to the instantiated options dialog (HgNewProjectOptionsDialog) """ from .HgNewProjectOptionsDialog import HgNewProjectOptionsDialog return HgNewProjectOptionsDialog(self, parent) def vcsRepositoryInfos(self, ppath): """ Public method to retrieve information about the repository. @param ppath local path to get the repository infos (string) @return string with ready formated info for display (string) """ args = self.initCommand("parents") args.append('--template') args.append('{rev}:{node|short}@@@{tags}@@@{author|xmlescape}@@@' '{date|isodate}@@@{branches}@@@{bookmarks}\n') output = "" if self.__client is None: process = QProcess() process.setWorkingDirectory(ppath) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) infoBlock = [] if output: index = 0 for line in output.splitlines(): index += 1 changeset, tags, author, date, branches, bookmarks = \ line.split("@@@") cdate, ctime = date.split()[:2] info = [] info.append(QCoreApplication.translate( "mercurial", """Parent #{0}\n""" """Changeset{1}""") .format(index, changeset)) if tags: info.append(QCoreApplication.translate( "mercurial", """Tags{0}""") .format('
'.join(tags.split()))) if bookmarks: info.append(QCoreApplication.translate( "mercurial", """Bookmarks{0}""") .format('
'.join(bookmarks.split()))) if branches: info.append(QCoreApplication.translate( "mercurial", """Branches{0}""") .format('
'.join(branches.split()))) info.append(QCoreApplication.translate( "mercurial", """Last author{0}\n""" """Committed date{1}\n""" """Committed time{2}""") .format(author, cdate, ctime)) infoBlock.append("\n".join(info)) if infoBlock: infoStr = """{0}""".format("".join(infoBlock)) else: infoStr = "" url = "" args = self.initCommand("showconfig") args.append('paths.default') output = "" if self.__client is None: process.setWorkingDirectory(ppath) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) if output: url = output.splitlines()[0].strip() else: url = "" return QCoreApplication.translate( 'mercurial', """

Repository information

\n""" """

\n""" """\n""" """\n""" """\n""" """{2}""" """
Mercurial V.{0}
URL{1}

\n""" ).format(self.versionStr, url, infoStr) def vcsSupportCommandOptions(self): """ Public method to signal the support of user settable command options. @return flag indicating the support of user settable command options (boolean) """ return False ########################################################################### ## Private Mercurial specific methods are below. ########################################################################### def __hgURL(self, url): """ Private method to format a url for Mercurial. @param url unformatted url string (string) @return properly formated url for mercurial (string) """ url = self.hgNormalizeURL(url) url = url.split(':', 2) if len(url) == 4: scheme = url[0] user = url[1] host = url[2] port, path = url[3].split("/", 1) return "{0}:{1}:{2}:{3}/{4}".format( scheme, user, host, port, Utilities.quote(path)) elif len(url) == 3: scheme = url[0] host = url[1] port, path = url[2].split("/", 1) return "{0}:{1}:{2}/{3}".format( scheme, host, port, Utilities.quote(path)) else: scheme = url[0] if scheme == "file": return "{0}:{1}".format(scheme, Utilities.quote(url[1])) else: host, path = url[1][2:].split("/", 1) return "{0}://{1}/{2}".format( scheme, host, Utilities.quote(path)) def hgNormalizeURL(self, url): """ Public method to normalize a url for Mercurial. @param url url string (string) @return properly normalized url for mercurial (string) """ url = url.replace('\\', '/') if url.endswith('/'): url = url[:-1] urll = url.split('//') return "{0}//{1}".format(urll[0], '/'.join(urll[1:])) def hgCopy(self, name, project): """ Public method used to copy a file/directory. @param name file/directory name to be copied (string) @param project reference to the project object @return flag indicating successful operation (boolean) """ from .HgCopyDialog import HgCopyDialog dlg = HgCopyDialog(name) res = False if dlg.exec_() == QDialog.Accepted: target, force = dlg.getData() args = self.initCommand("copy") args.append("-v") args.append(name) args.append(target) dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False dia = HgDialog( self.tr('Copying {0}').format(name), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.normalExit() if res and \ target.startswith(project.getProjectPath()): if os.path.isdir(name): project.copyDirectory(name, target) else: project.appendFile(target) return res def hgGetTagsList(self, repodir, withType=False): """ Public method to get the list of tags. @param repodir directory name of the repository (string) @param withType flag indicating to get the tag type as well (boolean) @return list of tags (list of string) or list of tuples of tag name and flag indicating a local tag (list of tuple of string and boolean), if withType is True """ args = self.initCommand("tags") args.append('--verbose') output = "" if self.__client is None: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) tagsList = [] if output: for line in output.splitlines(): li = line.strip().split() if li[-1][0] in "1234567890": # last element is a rev:changeset del li[-1] isLocal = False else: del li[-2:] isLocal = True name = " ".join(li) if name not in ["tip", "default"]: if withType: tagsList.append((name, isLocal)) else: tagsList.append(name) if withType: return tagsList else: if tagsList: self.tagsList = tagsList return self.tagsList[:] def hgGetBranchesList(self, repodir): """ Public method to get the list of branches. @param repodir directory name of the repository (string) @return list of branches (list of string) """ args = self.initCommand("branches") args.append('--closed') output = "" if self.__client is None: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) if output: self.branchesList = [] for line in output.splitlines(): li = line.strip().split() if li[-1][0] in "1234567890": # last element is a rev:changeset del li[-1] else: del li[-2:] name = " ".join(li) if name not in ["tip", "default"]: self.branchesList.append(name) return self.branchesList[:] def hgListTagBranch(self, path, tags=True): """ Public method used to list the available tags or branches. @param path directory name of the project (string) @param tags flag indicating listing of branches or tags (False = branches, True = tags) """ from .HgTagBranchListDialog import HgTagBranchListDialog self.tagbranchList = HgTagBranchListDialog(self) self.tagbranchList.show() if tags: if not self.showedTags: self.showedTags = True allTagsBranchesList = self.allTagsBranchesList else: self.tagsList = [] allTagsBranchesList = None self.tagbranchList.start(path, tags, self.tagsList, allTagsBranchesList) else: if not self.showedBranches: self.showedBranches = True allTagsBranchesList = self.allTagsBranchesList else: self.branchesList = [] allTagsBranchesList = None self.tagbranchList.start(path, tags, self.branchesList, self.allTagsBranchesList) def hgAnnotate(self, name): """ Public method to show the output of the hg annotate command. @param name file name to show the annotations for (string) """ from .HgAnnotateDialog import HgAnnotateDialog self.annotate = HgAnnotateDialog(self) self.annotate.show() self.annotate.start(name) def hgExtendedDiff(self, name): """ Public method used to view the difference of a file/directory to the Mercurial repository. If name is a directory and is the project directory, all project files are saved first. If name is a file (or list of files), which is/are being edited and has unsaved modification, they can be saved or the operation may be aborted. This method gives the chance to enter the revisions to be compared. @param name file/directory name to be diffed (string) """ if isinstance(name, list): dname, fnames = self.splitPathList(name) names = name[:] else: dname, fname = self.splitPath(name) names = [name] for nam in names: if os.path.isfile(nam): editor = e5App().getObject("ViewManager").getOpenEditor(nam) if editor and not editor.checkDirty(): return else: project = e5App().getObject("Project") if nam == project.ppath and not project.saveAllScripts(): return # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgRevisionsSelectionDialog import HgRevisionsSelectionDialog dlg = HgRevisionsSelectionDialog(self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: revisions = dlg.getRevisions() from .HgDiffDialog import HgDiffDialog self.diff = HgDiffDialog(self) self.diff.show() self.diff.start(name, revisions) def __hgGetFileForRevision(self, name, rev=""): """ Private method to get a file for a specific revision from the repository. @param name file name to get from the repository (string) @keyparam rev revision to retrieve (string) @return contents of the file (string) and an error message (string) """ args = self.initCommand("cat") if rev: args.append("--rev") args.append(rev) args.append(name) if self.__client is None: output = "" error = "" # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished: if process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: error = str(process.readAllStandardError(), self.getEncoding(), 'replace') else: error = self.tr( "The hg process did not finish within 30s.") else: error = self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.').format('hg') else: output, error = self.__client.runcommand(args) # return file contents with 'universal newlines' return output.replace('\r\n', '\n').replace('\r', '\n'), error def hgSbsDiff(self, name, extended=False, revisions=None): """ Public method used to view the difference of a file to the Mercurial repository side-by-side. @param name file name to be diffed (string) @keyparam extended flag indicating the extended variant (boolean) @keyparam revisions tuple of two revisions (tuple of strings) @exception ValueError raised to indicate an invalid name parameter """ if isinstance(name, list): raise ValueError("Wrong parameter type") if extended: # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgRevisionsSelectionDialog import HgRevisionsSelectionDialog dlg = HgRevisionsSelectionDialog(self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: rev1, rev2 = dlg.getRevisions() elif revisions: rev1, rev2 = revisions[0], revisions[1] else: rev1, rev2 = "", "" output1, error = self.__hgGetFileForRevision(name, rev=rev1) if error: E5MessageBox.critical( self.__ui, self.tr("Mercurial Side-by-Side Difference"), error) return name1 = "{0} (rev. {1})".format(name, rev1 and rev1 or ".") if rev2: output2, error = self.__hgGetFileForRevision(name, rev=rev2) if error: E5MessageBox.critical( self.__ui, self.tr("Mercurial Side-by-Side Difference"), error) return name2 = "{0} (rev. {1})".format(name, rev2) else: try: f1 = open(name, "r", encoding="utf-8") output2 = f1.read() f1.close() name2 = "{0} (Work)".format(name) except IOError: E5MessageBox.critical( self.__ui, self.tr("Mercurial Side-by-Side Difference"), self.tr( """

The file {0} could not be read.

""") .format(name)) return if self.sbsDiff is None: from UI.CompareDialog import CompareDialog self.sbsDiff = CompareDialog() self.sbsDiff.show() self.sbsDiff.compare(output1, output2, name1, name2) def vcsLogBrowser(self, name, isFile=False): """ Public method used to browse the log of a file/directory from the Mercurial repository. @param name file/directory name to show the log of (string) @keyparam isFile flag indicating log for a file is to be shown (boolean) """ if self.logBrowser is None: from .HgLogBrowserDialog import HgLogBrowserDialog self.logBrowser = HgLogBrowserDialog(self) self.logBrowser.show() self.logBrowser.start(name, isFile=isFile) def hgIncoming(self, name): """ Public method used to view the log of incoming changes from the Mercurial repository. @param name file/directory name to show the log of (string) """ if self.getPlugin().getPreferences("UseLogBrowser"): if self.logBrowserIncoming is None: from .HgLogBrowserDialog import HgLogBrowserDialog self.logBrowserIncoming = HgLogBrowserDialog( self, mode="incoming") self.logBrowserIncoming.show() self.logBrowserIncoming.start(name) else: from .HgLogDialog import HgLogDialog self.log = HgLogDialog(self, mode="incoming") self.log.show() self.log.start(name) def hgOutgoing(self, name): """ Public method used to view the log of outgoing changes from the Mercurial repository. @param name file/directory name to show the log of (string) """ if self.getPlugin().getPreferences("UseLogBrowser"): if self.logBrowserOutgoing is None: from .HgLogBrowserDialog import HgLogBrowserDialog self.logBrowserOutgoing = HgLogBrowserDialog( self, mode="outgoing") self.logBrowserOutgoing.show() self.logBrowserOutgoing.start(name) else: from .HgLogDialog import HgLogDialog self.log = HgLogDialog(self, mode="outgoing") self.log.show() self.log.start(name) def hgPull(self, name): """ Public method used to pull changes from a remote Mercurial repository. @param name directory name of the project to be pulled to (string) @return flag indicating, that the update contained an add or delete (boolean) """ if self.getPlugin().getPreferences("PreferUnbundle") and \ self.bundleFile and \ os.path.exists(self.bundleFile): command = "unbundle" title = self.tr('Apply changegroups') else: command = "pull" title = self.tr('Pulling from a remote Mercurial repository') args = self.initCommand(command) args.append('-v') if self.getPlugin().getPreferences("PullUpdate"): args.append('--update') if command == "unbundle": args.append(self.bundleFile) # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False dia = HgDialog(title, self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() if self.bundleFile and \ os.path.exists(self.bundleFile): os.remove(self.bundleFile) self.bundleFile = None self.checkVCSStatus() return res def hgPush(self, name, force=False, newBranch=False): """ Public method used to push changes to a remote Mercurial repository. @param name directory name of the project to be pushed from (string) @keyparam force flag indicating a forced push (boolean) @keyparam newBranch flag indicating to push a new branch (boolean) """ args = self.initCommand("push") args.append('-v') if force: args.append('-f') if newBranch: args.append('--new-branch') # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return dia = HgDialog( self.tr('Pushing to a remote Mercurial repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() self.checkVCSStatus() def hgInfo(self, ppath, mode="heads"): """ Public method to show information about the heads of the repository. @param ppath local path to get the repository infos (string) @keyparam mode mode of the operation (string, one of heads, parents, tip) """ if mode not in ("heads", "parents", "tip"): mode = "heads" info = [] args = self.initCommand(mode) args.append('--template') args.append('{rev}:{node|short}@@@{tags}@@@{author|xmlescape}@@@' '{date|isodate}@@@{branches}@@@{parents}@@@{bookmarks}\n') output = "" if self.__client is None: # find the root of the repo repodir = self.splitPath(ppath)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) if output: index = 0 for line in output.splitlines(): index += 1 changeset, tags, author, date, branches, parents, bookmarks = \ line.split("@@@") cdate, ctime = date.split()[:2] info.append("""

""") if mode == "heads": info.append(QCoreApplication.translate( "mercurial", """\n""" .format(index, changeset))) elif mode == "parents": info.append(QCoreApplication.translate( "mercurial", """\n""" .format(index, changeset))) elif mode == "tip": info.append(QCoreApplication.translate( "mercurial", """\n""")) info.append(QCoreApplication.translate( "mercurial", """""") .format(changeset)) if tags: info.append(QCoreApplication.translate( "mercurial", """""") .format('
'.join(tags.split()))) if bookmarks: info.append(QCoreApplication.translate( "mercurial", """""") .format('
'.join(bookmarks.split()))) if branches: info.append(QCoreApplication.translate( "mercurial", """""") .format('
'.join(branches.split()))) if parents: info.append(QCoreApplication.translate( "mercurial", """""") .format('
'.join(parents.split()))) info.append(QCoreApplication.translate( "mercurial", """\n""" """\n""" """\n""" """
Head #{0}
Parent #{0}
Tip
Changeset{0}
Tags{0}
Bookmarks{0}
Branches{0}
Parents{0}
Last author{0}
Committed date{1}
Committed time{2}

""") .format(author, cdate, ctime)) dlg = VcsRepositoryInfoDialog(None, "\n".join(info)) dlg.exec_() def hgConflicts(self, name): """ Public method used to show a list of files containing conflicts. @param name file/directory name to be resolved (string) """ if self.conflictsDlg is None: from .HgConflictsListDialog import HgConflictsListDialog self.conflictsDlg = HgConflictsListDialog(self) self.conflictsDlg.show() self.conflictsDlg.start(name) def hgResolved(self, name, unresolve=False): """ Public method used to resolve conflicts of a file/directory. @param name file/directory name to be resolved (string) @param unresolve flag indicating to mark the file/directory as unresolved (boolean) """ args = self.initCommand("resolve") if unresolve: args.append("--unmark") else: args.append("--mark") if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, name) else: dname, fname = self.splitPath(name) args.append(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if unresolve: title = self.tr("Marking as 'unresolved'") else: title = self.tr("Marking as 'resolved'") dia = HgDialog(title, self) res = dia.startProcess(args, repodir) if res: dia.exec_() self.checkVCSStatus() def hgCancelMerge(self, name): """ Public method to cancel an uncommitted merge. @param name file/directory name (string) @return flag indicating, that the cancellation contained an add or delete (boolean) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.initCommand("update") args.append("--clean") dia = HgDialog( self.tr('Cancelling uncommitted merge'), self) res = dia.startProcess(args, repodir, False) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() return res def hgBranch(self, name): """ Public method used to create a branch in the Mercurial repository. @param name file/directory name to be branched (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgBranchInputDialog import HgBranchInputDialog dlg = HgBranchInputDialog(self.hgGetBranchesList(repodir)) if dlg.exec_() == QDialog.Accepted: name, commit = dlg.getData() name = name.strip().replace(" ", "_") args = self.initCommand("branch") args.append(name) dia = HgDialog( self.tr('Creating branch in the Mercurial repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() if commit: self.vcsCommit( repodir, self.tr("Created new branch <{0}>.").format( name)) def hgShowBranch(self, name): """ Public method used to show the current branch of the working directory. @param name file/directory name (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.initCommand("branch") dia = HgDialog(self.tr('Showing current branch'), self) res = dia.startProcess(args, repodir, False) if res: dia.exec_() def hgEditUserConfig(self): """ Public method used to edit the user configuration file. """ from .HgUtilities import getConfigPath cfgFile = getConfigPath() if not os.path.exists(cfgFile): # open dialog to enter the initial data from .HgUserConfigDataDialog import HgUserConfigDataDialog dlg = HgUserConfigDataDialog(version=self.version) if dlg.exec_() == QDialog.Accepted: firstName, lastName, email, extensions, extensionsData = \ dlg.getData() else: firstName, lastName, email, extensions, extensionsData = ( "Firstname", "Lastname", "email_address", [], {}) try: f = open(cfgFile, "w") f.write("[ui]\n") f.write("username = {0} {1} <{2}>\n".format( firstName, lastName, email)) if extensions: f.write("\n[extensions]\n") f.write(" =\n".join(extensions)) f.write(" =\n") # complete the last line if "largefiles" in extensionsData: dataDict = extensionsData["largefiles"] f.write("\n[largefiles]\n") if "minsize" in dataDict: f.write("minsize = {0}\n".format(dataDict["minsize"])) if "patterns" in dataDict: f.write("patterns =\n") f.write(" {0}\n".format( "\n ".join(dataDict["patterns"]))) f.close() except (IOError, OSError): # ignore these pass self.userEditor = MiniEditor(cfgFile, "Properties") self.userEditor.show() def hgEditConfig(self, name, withLargefiles=True, largefilesData=None): """ Public method used to edit the repository configuration file. @param name file/directory name (string) @param withLargefiles flag indicating to configure the largefiles section (boolean) @param largefilesData dictionary with data for the largefiles section of the data dialog (dict) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return cfgFile = os.path.join(repodir, self.adminDir, "hgrc") if not os.path.exists(cfgFile): # open dialog to enter the initial data withLargefiles = (self.isExtensionActive("largefiles") and withLargefiles) from .HgRepoConfigDataDialog import HgRepoConfigDataDialog dlg = HgRepoConfigDataDialog(withLargefiles=withLargefiles, largefilesData=largefilesData) if dlg.exec_() == QDialog.Accepted: createContents = True defaultUrl, defaultPushUrl = dlg.getData() if withLargefiles: lfMinSize, lfPattern = dlg.getLargefilesData() else: createContents = False try: cfg = open(cfgFile, "w") if createContents: # write the data entered cfg.write("[paths]\n") if defaultUrl: cfg.write("default = {0}\n".format(defaultUrl)) if defaultPushUrl: cfg.write("default-push = {0}\n".format( defaultPushUrl)) if withLargefiles and \ (lfMinSize, lfPattern) != (None, None): cfg.write("\n[largefiles]\n") if lfMinSize is not None: cfg.write("minsize = {0}\n".format(lfMinSize)) if lfPattern is not None: cfg.write("patterns =\n") cfg.write(" {0}\n".format( "\n ".join(lfPattern))) cfg.close() self.__monitorRepoIniFile(repodir) self.__iniFileChanged(cfgFile) except IOError: pass self.repoEditor = MiniEditor(cfgFile, "Properties") self.repoEditor.show() def hgVerify(self, name): """ Public method to verify the integrity of the repository. @param name file/directory name (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.initCommand("verify") dia = HgDialog( self.tr('Verifying the integrity of the Mercurial repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgShowConfig(self, name): """ Public method to show the combined configuration. @param name file/directory name (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.initCommand("showconfig") args.append("--untrusted") dia = HgDialog( self.tr('Showing the combined configuration settings'), self) res = dia.startProcess(args, repodir, False) if res: dia.exec_() def hgShowPaths(self, name): """ Public method to show the path aliases for remote repositories. @param name file/directory name (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.initCommand("paths") dia = HgDialog( self.tr('Showing aliases for remote repositories'), self) res = dia.startProcess(args, repodir, False) if res: dia.exec_() def hgRecover(self, name): """ Public method to recover an interrupted transaction. @param name file/directory name (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.initCommand("recover") dia = HgDialog( self.tr('Recovering from interrupted transaction'), self) res = dia.startProcess(args, repodir, False) if res: dia.exec_() def hgIdentify(self, name): """ Public method to identify the current working directory. @param name file/directory name (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.initCommand("identify") dia = HgDialog(self.tr('Identifying project directory'), self) res = dia.startProcess(args, repodir, False) if res: dia.exec_() def hgCreateIgnoreFile(self, name, autoAdd=False): """ Public method to create the ignore file. @param name directory name to create the ignore file in (string) @param autoAdd flag indicating to add it automatically (boolean) @return flag indicating success """ status = False ignorePatterns = [ "glob:.eric6project", "glob:_eric6project", "glob:.eric5project", "glob:_eric5project", "glob:.eric4project", "glob:_eric4project", "glob:.ropeproject", "glob:_ropeproject", "glob:.directory", "glob:**.pyc", "glob:**.pyo", "glob:**.orig", "glob:**.bak", "glob:**.rej", "glob:**~", "glob:cur", "glob:tmp", "glob:__pycache__", "glob:**.DS_Store", ] ignoreName = os.path.join(name, Hg.IgnoreFileName) if os.path.exists(ignoreName): res = E5MessageBox.yesNo( self.__ui, self.tr("Create .hgignore file"), self.tr("""

The file {0} exists already.""" """ Overwrite it?

""").format(ignoreName), icon=E5MessageBox.Warning) else: res = True if res: try: # create a .hgignore file ignore = open(ignoreName, "w") ignore.write("\n".join(ignorePatterns)) ignore.write("\n") ignore.close() status = True except IOError: status = False if status and autoAdd: self.vcsAdd(ignoreName, noDialog=True) project = e5App().getObject("Project") project.appendFile(ignoreName) return status def hgBundle(self, name): """ Public method to create a changegroup file. @param name file/directory name (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgBundleDialog import HgBundleDialog dlg = HgBundleDialog(self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: revs, baseRevs, compression, all = dlg.getParameters() fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( None, self.tr("Create changegroup"), self.__lastChangeGroupPath or repodir, self.tr("Mercurial Changegroup Files (*.hg)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fname: return # user aborted ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self.__ui, self.tr("Create changegroup"), self.tr("

The Mercurial changegroup file {0} " "already exists. Overwrite it?

") .format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) self.__lastChangeGroupPath = os.path.dirname(fname) args = self.initCommand("bundle") if all: args.append("--all") for rev in revs: args.append("--rev") args.append(rev) for baseRev in baseRevs: args.append("--base") args.append(baseRev) if compression: args.append("--type") args.append(compression) args.append(fname) dia = HgDialog(self.tr('Create changegroup'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgPreviewBundle(self, name): """ Public method used to view the log of incoming changes from a changegroup file. @param name directory name on which to base the changegroup (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return file = E5FileDialog.getOpenFileName( None, self.tr("Preview changegroup"), self.__lastChangeGroupPath or repodir, self.tr("Mercurial Changegroup Files (*.hg);;All Files (*)")) if file: self.__lastChangeGroupPath = os.path.dirname(file) if self.getPlugin().getPreferences("UseLogBrowser"): if self.logBrowserIncoming is None: from .HgLogBrowserDialog import HgLogBrowserDialog self.logBrowserIncoming = \ HgLogBrowserDialog(self, mode="incoming") self.logBrowserIncoming.show() self.logBrowserIncoming.start(name, bundle=file) else: from .HgLogDialog import HgLogDialog self.log = HgLogDialog(self, mode="incoming", bundle=file) self.log.show() self.log.start(name) def hgUnbundle(self, name): """ Public method to apply changegroup files. @param name directory name (string) @return flag indicating, that the update contained an add or delete (boolean) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return res = False files = E5FileDialog.getOpenFileNames( None, self.tr("Apply changegroups"), self.__lastChangeGroupPath or repodir, self.tr("Mercurial Changegroup Files (*.hg);;All Files (*)")) if files: self.__lastChangeGroupPath = os.path.dirname(files[0]) update = E5MessageBox.yesNo( self.__ui, self.tr("Apply changegroups"), self.tr("""Shall the working directory be updated?"""), yesDefault=True) args = self.initCommand("unbundle") if update: args.append("--update") args.append("--verbose") args.extend(files) dia = HgDialog(self.tr('Apply changegroups'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() return res def hgBisect(self, name, subcommand): """ Public method to perform bisect commands. @param name file/directory name (string) @param subcommand name of the subcommand (string, one of 'good', 'bad', 'skip' or 'reset') @exception ValueError raised to indicate an invalid bisect subcommand """ if subcommand not in ("good", "bad", "skip", "reset"): raise ValueError( self.tr("Bisect subcommand ({0}) invalid.") .format(subcommand)) dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return rev = "" if subcommand in ("good", "bad", "skip"): from .HgRevisionSelectionDialog import HgRevisionSelectionDialog dlg = HgRevisionSelectionDialog(self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: rev = dlg.getRevision() else: return args = self.initCommand("bisect") args.append("--{0}".format(subcommand)) if rev: args.append(rev) dia = HgDialog( self.tr('Mercurial Bisect ({0})').format(subcommand), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgForget(self, name): """ Public method used to remove a file from the Mercurial repository. This will not remove the file from the project directory. @param name file/directory name to be removed (string or list of strings)) """ args = self.initCommand("forget") args.append('-v') if isinstance(name, list): dname, fnames = self.splitPathList(name) self.addArguments(args, name) else: dname, fname = self.splitPath(name) args.append(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return dia = HgDialog( self.tr('Removing files from the Mercurial repository only'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() if isinstance(name, list): self.__forgotNames.extend(name) else: self.__forgotNames.append(name) def hgBackout(self, name): """ Public method used to backout an earlier changeset from the Mercurial repository. @param name directory name (string or list of strings) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgBackoutDialog import HgBackoutDialog dlg = HgBackoutDialog(self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: rev, merge, date, user, message = dlg.getParameters() if not rev: E5MessageBox.warning( self.__ui, self.tr("Backing out changeset"), self.tr("""No revision given. Aborting...""")) return args = self.initCommand("backout") args.append('-v') if merge: args.append('--merge') if date: args.append('--date') args.append(date) if user: args.append('--user') args.append(user) args.append('--message') args.append(message) args.append(rev) dia = HgDialog(self.tr('Backing out changeset'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgRollback(self, name): """ Public method used to rollback the last transaction. @param name directory name (string or list of strings) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return res = E5MessageBox.yesNo( None, self.tr("Rollback last transaction"), self.tr("""Are you sure you want to rollback the last""" """ transaction?"""), icon=E5MessageBox.Warning) if res: dia = HgDialog(self.tr('Rollback last transaction'), self) res = dia.startProcess(["rollback"], repodir) if res: dia.exec_() def hgServe(self, name): """ Public method used to serve the project. @param name directory name (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgServeDialog import HgServeDialog self.serveDlg = HgServeDialog(self, repodir) self.serveDlg.show() def hgImport(self, name): """ Public method to import a patch file. @param name directory name of the project to import into (string) @return flag indicating, that the import contained an add, a delete or a change to the project file (boolean) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgImportDialog import HgImportDialog dlg = HgImportDialog() if dlg.exec_() == QDialog.Accepted: patchFile, noCommit, message, date, user, stripCount, force = \ dlg.getParameters() args = self.initCommand("import") args.append("--verbose") if noCommit: args.append("--no-commit") else: if message: args.append('--message') args.append(message) if date: args.append('--date') args.append(date) if user: args.append('--user') args.append(user) if stripCount != 1: args.append("--strip") args.append(str(stripCount)) if force: args.append("--force") args.append(patchFile) dia = HgDialog(self.tr("Import Patch"), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() else: res = False return res def hgExport(self, name): """ Public method to export patches to files. @param name directory name of the project to export from (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgExportDialog import HgExportDialog dlg = HgExportDialog() if dlg.exec_() == QDialog.Accepted: filePattern, revisions, switchParent, allText, noDates, git = \ dlg.getParameters() args = self.initCommand("export") args.append("--output") args.append(filePattern) args.append("--verbose") if switchParent: args.append("--switch-parent") if allText: args.append("--text") if noDates: args.append("--nodates") if git: args.append("--git") for rev in revisions: args.append(rev) dia = HgDialog(self.tr("Export Patches"), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgPhase(self, name, data=None): """ Public method to change the phase of revisions. @param name directory name of the project to export from (string) @param data tuple giving phase data (list of revisions, phase, flag indicating a forced operation) (list of strings, string, boolean) @return flag indicating success (boolean) @exception ValueError raised to indicate an invalid phase """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False if data is None: from .HgPhaseDialog import HgPhaseDialog dlg = HgPhaseDialog() if dlg.exec_() == QDialog.Accepted: data = dlg.getData() if data: revs, phase, force = data args = self.initCommand("phase") if phase == "p": args.append("--public") elif phase == "d": args.append("--draft") elif phase == "s": args.append("--secret") else: raise ValueError("Invalid phase given.") if force: args.append("--force") for rev in revs: args.append(rev) dia = HgDialog(self.tr("Change Phase"), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.normalExitWithoutErrors() else: res = False return res def hgGraft(self, path, revs=None): """ Public method to copy changesets from another branch. @param path directory name of the project (string) @param revs list of revisions to show in the revisions pane (list of strings) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = self.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False from .HgGraftDialog import HgGraftDialog res = False dlg = HgGraftDialog(self, revs) if dlg.exec_() == QDialog.Accepted: revs, (userData, currentUser, userName), \ (dateData, currentDate, dateStr), log, dryrun = dlg.getData() args = self.initCommand("graft") args.append("--verbose") if userData: if currentUser: args.append("--currentuser") else: args.append("--user") args.append(userName) if dateData: if currentDate: args.append("--currentdate") else: args.append("--date") args.append(dateStr) if log: args.append("--log") if dryrun: args.append("--dry-run") args.extend(revs) dia = HgDialog(self.tr('Copy Changesets'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() return res def hgGraftContinue(self, path): """ Public method to continue copying changesets from another branch. @param path directory name of the project (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = self.splitPath(path)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.initCommand("graft") args.append("--continue") args.append("--verbose") dia = HgDialog(self.tr('Copy Changesets (Continue)'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.checkVCSStatus() return res def hgArchive(self): """ Public method to create an unversioned archive from the repository. """ # find the root of the repo repodir = self.__projectHelper.getProject().getProjectPath() while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgArchiveDialog import HgArchiveDialog dlg = HgArchiveDialog(self) if dlg.exec_() == QDialog.Accepted: archive, type_, prefix, subrepos = dlg.getData() args = self.initCommand("archive") if type_: args.append("--type") args.append(type_) if prefix: args.append("--prefix") args.append(prefix) if subrepos: args.append("--subrepos") args.append(archive) dia = HgDialog(self.tr("Create Unversioned Archive"), self) res = dia.startProcess(args, repodir) if res: dia.exec_() ########################################################################### ## Methods to deal with subrepositories are below. ########################################################################### def getHgSubPath(self): """ Public method to get the path to the .hgsub file containing the definitions of sub-repositories. @return full path of the .hgsub file (string) """ ppath = self.__projectHelper.getProject().getProjectPath() return os.path.join(ppath, ".hgsub") def hasSubrepositories(self): """ Public method to check, if the project might have sub-repositories. @return flag indicating the existence of sub-repositories (boolean) """ hgsub = self.getHgSubPath() return os.path.isfile(hgsub) and os.stat(hgsub).st_size > 0 def hgAddSubrepository(self): """ Public method to add a sub-repository. """ from .HgAddSubrepositoryDialog import HgAddSubrepositoryDialog ppath = self.__projectHelper.getProject().getProjectPath() hgsub = self.getHgSubPath() dlg = HgAddSubrepositoryDialog(ppath) if dlg.exec_() == QDialog.Accepted: relPath, subrepoType, subrepoUrl = dlg.getData() if subrepoType == "hg": url = subrepoUrl else: url = "[{0}]{1}".format(subrepoType, subrepoUrl) entry = "{0} = {1}\n".format(relPath, url) contents = [] if os.path.isfile(hgsub): # file exists; check, if such an entry exists already needsAdd = False try: f = open(hgsub, "r") contents = f.readlines() f.close() except IOError as err: E5MessageBox.critical( self.__ui, self.tr("Add Sub-repository"), self.tr( """

The sub-repositories file .hgsub could not""" """ be read.

Reason: {0}

""") .format(str(err))) return if entry in contents: E5MessageBox.critical( self.__ui, self.tr("Add Sub-repository"), self.tr( """

The sub-repositories file .hgsub already""" """ contains an entry {0}.""" """ Aborting...

""").format(entry)) return else: needsAdd = True if contents and not contents[-1].endswith("\n"): contents[-1] = contents[-1] + "\n" contents.append(entry) try: f = open(hgsub, "w") f.writelines(contents) f.close() except IOError as err: E5MessageBox.critical( self.__ui, self.tr("Add Sub-repository"), self.tr( """

The sub-repositories file .hgsub could not""" """ be written to.

Reason: {0}

""") .format(str(err))) return if needsAdd: self.vcsAdd(hgsub) self.__projectHelper.getProject().appendFile(hgsub) def hgRemoveSubrepositories(self): """ Public method to remove sub-repositories. """ hgsub = self.getHgSubPath() subrepositories = [] if not os.path.isfile(hgsub): E5MessageBox.critical( self.__ui, self.tr("Remove Sub-repositories"), self.tr("""

The sub-repositories file .hgsub does not""" """ exist. Aborting...

""")) return try: f = open(hgsub, "r") subrepositories = [line.strip() for line in f.readlines()] f.close() except IOError as err: E5MessageBox.critical( self.__ui, self.tr("Remove Sub-repositories"), self.tr("""

The sub-repositories file .hgsub could not""" """ be read.

Reason: {0}

""") .format(str(err))) return from .HgRemoveSubrepositoriesDialog import \ HgRemoveSubrepositoriesDialog dlg = HgRemoveSubrepositoriesDialog(subrepositories) if dlg.exec_() == QDialog.Accepted: subrepositories, removedSubrepos, deleteSubrepos = dlg.getData() contents = "\n".join(subrepositories) + "\n" try: f = open(hgsub, "w") f.write(contents) f.close() except IOError as err: E5MessageBox.critical( self.__ui, self.tr("Remove Sub-repositories"), self.tr( """

The sub-repositories file .hgsub could not""" """ be written to.

Reason: {0}

""") .format(str(err))) return if deleteSubrepos: ppath = self.__projectHelper.getProject().getProjectPath() for removedSubrepo in removedSubrepos: subrepoPath = removedSubrepo.split("=", 1)[0].strip() subrepoAbsPath = os.path.join(ppath, subrepoPath) shutil.rmtree(subrepoAbsPath, True) ########################################################################### ## Methods to handle configuration dependent stuff are below. ########################################################################### def __checkDefaults(self): """ Private method to check, if the default and default-push URLs have been configured. """ args = self.initCommand("showconfig") args.append('paths') output = "" if self.__client is None: process = QProcess() self.__repoDir and process.setWorkingDirectory(self.__repoDir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) self.__defaultConfigured = False self.__defaultPushConfigured = False if output: for line in output.splitlines(): if line.startswith("paths.default=") and \ not line.strip().endswith("="): self.__defaultConfigured = True if line.startswith("paths.default-push=") and \ not line.strip().endswith("="): self.__defaultPushConfigured = True def canPull(self): """ Public method to check, if pull is possible. @return flag indicating pull capability (boolean) """ return self.__defaultConfigured def canPush(self): """ Public method to check, if push is possible. @return flag indicating push capability (boolean) """ return self.__defaultPushConfigured or self.__defaultConfigured def __iniFileChanged(self, path): """ Private slot to handle a change of the Mercurial configuration file. @param path name of the changed file (string) """ if self.__client: ok, err = self.__client.restartServer() if not ok: E5MessageBox.warning( None, self.tr("Mercurial Command Server"), self.tr( """

The Mercurial Command Server could not be""" """ restarted.

Reason: {0}

""").format(err)) self.__client = None self.__getExtensionsInfo() if self.__repoIniFile and path == self.__repoIniFile: self.__checkDefaults() self.iniFileChanged.emit() def __monitorRepoIniFile(self, name): """ Private slot to add a repository configuration file to the list of monitored files. @param name directory name pointing into the repository (string) """ dname, fname = self.splitPath(name) # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if not repodir or os.path.splitdrive(repodir)[1] == os.sep: return cfgFile = os.path.join(repodir, self.adminDir, "hgrc") if os.path.exists(cfgFile): self.__iniWatcher.addPath(cfgFile) self.__repoIniFile = cfgFile self.__checkDefaults() ########################################################################### ## Methods to handle extensions are below. ########################################################################### def __getExtensionsInfo(self): """ Private method to get the active extensions from Mercurial. """ activeExtensions = sorted(self.__activeExtensions) self.__activeExtensions = [] args = self.initCommand("showconfig") args.append('extensions') output = "" if self.__client is None: process = QProcess() self.__repoDir and process.setWorkingDirectory(self.__repoDir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') else: output, error = self.__client.runcommand(args) if output: for line in output.splitlines(): extensionName = \ line.split("=", 1)[0].strip().split(".")[-1].strip() self.__activeExtensions.append(extensionName) if activeExtensions != sorted(self.__activeExtensions): self.activeExtensionsChanged.emit() def isExtensionActive(self, extensionName): """ Public method to check, if an extension is active. @param extensionName name of the extension to check for (string) @return flag indicating an active extension (boolean) """ extensionName = extensionName.strip() isActive = extensionName in self.__activeExtensions if isActive and \ extensionName == "transplant" and \ self.version >= (2, 3): # transplant extension is deprecated as of Mercurial 2.3.0 isActive = False if isActive and \ extensionName == "shelve" and \ self.version < (2, 8): # shelve extension was added as of Mercurial 2.8.0 isActive = False if isActive and \ extensionName == "largefiles" and \ self.version < (2, 0): # largefiles extension was added as of Mercurial 2.0.0 isActive = False return isActive def getExtensionObject(self, extensionName): """ Public method to get a reference to an extension object. @param extensionName name of the extension (string) @return reference to the extension object (boolean) """ return self.__extensions[extensionName] ########################################################################### ## Methods to get the helper objects are below. ########################################################################### def vcsGetProjectBrowserHelper(self, browser, project, isTranslationsBrowser=False): """ Public method to instantiate a helper object for the different project browsers. @param browser reference to the project browser object @param project reference to the project object @param isTranslationsBrowser flag indicating, the helper is requested for the translations browser (this needs some special treatment) @return the project browser helper object """ from .ProjectBrowserHelper import HgProjectBrowserHelper return HgProjectBrowserHelper(self, browser, project, isTranslationsBrowser) def vcsGetProjectHelper(self, project): """ Public method to instantiate a helper object for the project. @param project reference to the project object @return the project helper object """ # find the root of the repo repodir = project.getProjectPath() while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if not repodir or os.path.splitdrive(repodir)[1] == os.sep: repodir = "" break if repodir: self.__repoDir = repodir self.__projectHelper = self.__plugin.getProjectHelper() self.__projectHelper.setObjects(self, project) self.__monitorRepoIniFile(project.getProjectPath()) if repodir: from .HgClient import HgClient client = HgClient(repodir, "utf-8", self) ok, err = client.startServer() if ok: self.__client = client else: E5MessageBox.warning( None, self.tr("Mercurial Command Server"), self.tr( """

The Mercurial Command Server could not be""" """ started.

Reason: {0}

""").format(err)) return self.__projectHelper ########################################################################### ## Status Monitor Thread methods ########################################################################### def _createStatusMonitorThread(self, interval, project): """ Protected method to create an instance of the VCS status monitor thread. @param interval check interval for the monitor thread in seconds (integer) @param project reference to the project object (Project) @return reference to the monitor thread (QThread) """ from .HgStatusMonitorThread import HgStatusMonitorThread return HgStatusMonitorThread(interval, project, self) ########################################################################### ## Bookmarks methods ########################################################################### def hgListBookmarks(self, path): """ Public method used to list the available bookmarks. @param path directory name of the project (string) """ self.bookmarksList = [] from .HgBookmarksListDialog import HgBookmarksListDialog self.bookmarksListDlg = HgBookmarksListDialog(self) self.bookmarksListDlg.show() self.bookmarksListDlg.start(path, self.bookmarksList) def hgGetBookmarksList(self, repodir): """ Public method to get the list of bookmarks. @param repodir directory name of the repository (string) @return list of bookmarks (list of string) """ args = self.initCommand("bookmarks") client = self.getClient() output = "" if client: output = client.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') self.bookmarksList = [] for line in output.splitlines(): li = line.strip().split() if li[-1][0] in "1234567890": # last element is a rev:changeset del li[-1] if li[0] == "*": del li[0] name = " ".join(li) self.bookmarksList.append(name) return self.bookmarksList[:] def hgBookmarkDefine(self, name): """ Public method to define a bookmark. @param name file/directory name (string) """ # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgBookmarkDialog import HgBookmarkDialog dlg = HgBookmarkDialog(HgBookmarkDialog.DEFINE_MODE, self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: rev, bookmark = dlg.getData() args = self.initCommand("bookmarks") if rev: args.append("--rev") args.append(rev) args.append(bookmark) dia = HgDialog(self.tr('Mercurial Bookmark'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgBookmarkDelete(self, name): """ Public method to delete a bookmark. @param name file/directory name (string) """ # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return bookmark, ok = QInputDialog.getItem( None, self.tr("Delete Bookmark"), self.tr("Select the bookmark to be deleted:"), [""] + sorted(self.hgGetBookmarksList(repodir)), 0, True) if ok and bookmark: args = self.initCommand("bookmarks") args.append("--delete") args.append(bookmark) dia = HgDialog(self.tr('Delete Mercurial Bookmark'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgBookmarkRename(self, name): """ Public method to rename a bookmark. @param name file/directory name (string) """ # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgBookmarkRenameDialog import HgBookmarkRenameDialog dlg = HgBookmarkRenameDialog(self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: newName, oldName = dlg.getData() args = self.initCommand("bookmarks") args.append("--rename") args.append(oldName) args.append(newName) dia = HgDialog(self.tr('Rename Mercurial Bookmark'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgBookmarkMove(self, name): """ Public method to move a bookmark. @param name file/directory name (string) """ # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return from .HgBookmarkDialog import HgBookmarkDialog dlg = HgBookmarkDialog(HgBookmarkDialog.MOVE_MODE, self.hgGetTagsList(repodir), self.hgGetBranchesList(repodir), self.hgGetBookmarksList(repodir)) if dlg.exec_() == QDialog.Accepted: rev, bookmark = dlg.getData() args = self.initCommand("bookmarks") args.append("--force") if rev: args.append("--rev") args.append(rev) args.append(bookmark) dia = HgDialog(self.tr('Move Mercurial Bookmark'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgBookmarkIncoming(self, name): """ Public method to show a list of incoming bookmarks. @param name file/directory name (string) """ from .HgBookmarksInOutDialog import HgBookmarksInOutDialog self.bookmarksInOutDlg = HgBookmarksInOutDialog( self, HgBookmarksInOutDialog.INCOMING) self.bookmarksInOutDlg.show() self.bookmarksInOutDlg.start(name) def hgBookmarkOutgoing(self, name): """ Public method to show a list of outgoing bookmarks. @param name file/directory name (string) """ from .HgBookmarksInOutDialog import HgBookmarksInOutDialog self.bookmarksInOutDlg = HgBookmarksInOutDialog( self, HgBookmarksInOutDialog.OUTGOING) self.bookmarksInOutDlg.show() self.bookmarksInOutDlg.start(name) def __getInOutBookmarks(self, repodir, incoming): """ Private method to get the list of incoming or outgoing bookmarks. @param repodir directory name of the repository (string) @param incoming flag indicating to get incoming bookmarks (boolean) @return list of bookmarks (list of string) """ bookmarksList = [] if incoming: args = self.initCommand("incoming") else: args = self.initCommand("outgoing") args.append('--bookmarks') client = self.getClient() output = "" if client: output = client.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.getEncoding(), 'replace') for line in output.splitlines(): if line.startswith(" "): li = line.strip().split() del li[-1] name = " ".join(li) bookmarksList.append(name) return bookmarksList def hgBookmarkPull(self, name): """ Public method to pull a bookmark from a remote repository. @param name file/directory name (string) """ # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return bookmarks = self.__getInOutBookmarks(repodir, True) bookmark, ok = QInputDialog.getItem( None, self.tr("Pull Bookmark"), self.tr("Select the bookmark to be pulled:"), [""] + sorted(bookmarks), 0, True) if ok and bookmark: args = self.initCommand("pull") args.append('--bookmark') args.append(bookmark) dia = HgDialog(self.tr( 'Pulling bookmark from a remote Mercurial repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgBookmarkPush(self, name): """ Public method to push a bookmark to a remote repository. @param name file/directory name (string) """ # find the root of the repo repodir = self.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return bookmarks = self.__getInOutBookmarks(repodir, False) bookmark, ok = QInputDialog.getItem( None, self.tr("Push Bookmark"), self.tr("Select the bookmark to be push:"), [""] + sorted(bookmarks), 0, True) if ok and bookmark: args = self.initCommand("push") args.append('--bookmark') args.append(bookmark) dia = HgDialog(self.tr( 'Pushing bookmark to a remote Mercurial repository'), self) res = dia.startProcess(args, repodir) if res: dia.exec_() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgServeDialog.py0000644000175000017500000001777412451233372023701 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog for the Mercurial server. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QProcess, Qt, QSize from PyQt5.QtGui import QTextCursor, QBrush from PyQt5.QtWidgets import QAction, QToolBar, QPlainTextEdit, QSpinBox, \ QComboBox from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from E5Gui.E5MainWindow import E5MainWindow import UI.PixmapCache import Preferences class HgServeDialog(E5MainWindow): """ Class implementing a dialog for the Mercurial server. """ def __init__(self, vcs, path, parent=None): """ Constructor @param vcs reference to the vcs object @param path path of the repository to serve (string) @param parent reference to the parent widget (QWidget) """ super(HgServeDialog, self).__init__(parent) self.vcs = vcs self.__repoPath = path self.__styles = ["paper", "coal", "gitweb", "monoblue", "spartan", ] self.setWindowTitle(self.tr("Mercurial Server")) self.__startAct = QAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsMercurial", "icons", "startServer.png")), self.tr("Start Server"), self) self.__startAct.triggered.connect(self.__startServer) self.__stopAct = QAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsMercurial", "icons", "stopServer.png")), self.tr("Stop Server"), self) self.__stopAct.triggered.connect(self.__stopServer) self.__browserAct = QAction( UI.PixmapCache.getIcon("home.png"), self.tr("Start Browser"), self) self.__browserAct.triggered.connect(self.__startBrowser) self.__portSpin = QSpinBox(self) self.__portSpin.setMinimum(2048) self.__portSpin.setMaximum(65535) self.__portSpin.setToolTip(self.tr("Enter the server port")) self.__portSpin.setValue( self.vcs.getPlugin().getPreferences("ServerPort")) self.__styleCombo = QComboBox(self) self.__styleCombo.addItems(self.__styles) self.__styleCombo.setToolTip(self.tr("Select the style to use")) self.__styleCombo.setCurrentIndex(self.__styleCombo.findText( self.vcs.getPlugin().getPreferences("ServerStyle"))) self.__serverToolbar = QToolBar(self.tr("Server"), self) self.__serverToolbar.addAction(self.__startAct) self.__serverToolbar.addAction(self.__stopAct) self.__serverToolbar.addSeparator() self.__serverToolbar.addWidget(self.__portSpin) self.__serverToolbar.addWidget(self.__styleCombo) self.__browserToolbar = QToolBar(self.tr("Browser"), self) self.__browserToolbar.addAction(self.__browserAct) self.addToolBar(Qt.TopToolBarArea, self.__serverToolbar) self.addToolBar(Qt.TopToolBarArea, self.__browserToolbar) self.__log = QPlainTextEdit(self) self.setCentralWidget(self.__log) # polish up the dialog self.__startAct.setEnabled(True) self.__stopAct.setEnabled(False) self.__browserAct.setEnabled(False) self.__portSpin.setEnabled(True) self.__styleCombo.setEnabled(True) self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint())) self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.cNormalFormat = self.__log.currentCharFormat() self.cErrorFormat = self.__log.currentCharFormat() self.cErrorFormat.setForeground( QBrush(Preferences.getUI("LogStdErrColour"))) def __startServer(self): """ Private slot to start the Mercurial server. """ port = self.__portSpin.value() style = self.__styleCombo.currentText() args = self.vcs.initCommand("serve") args.append("-v") args.append("--port") args.append(str(port)) args.append("--style") args.append(style) self.process.setWorkingDirectory(self.__repoPath) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if procStarted: self.__startAct.setEnabled(False) self.__stopAct.setEnabled(True) self.__browserAct.setEnabled(True) self.__portSpin.setEnabled(False) self.__styleCombo.setEnabled(False) self.vcs.getPlugin().setPreferences("ServerPort", port) self.vcs.getPlugin().setPreferences("ServerStyle", style) else: E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) def __stopServer(self): """ Private slot to stop the Mercurial server. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() self.process.waitForFinished(5000) if self.process.state() != QProcess.NotRunning: self.process.kill() self.__startAct.setEnabled(True) self.__stopAct.setEnabled(False) self.__browserAct.setEnabled(False) self.__portSpin.setEnabled(True) self.__styleCombo.setEnabled(True) def __startBrowser(self): """ Private slot to start a browser for the served repository. """ ui = e5App().getObject("UserInterface") ui.launchHelpViewer( "http://localhost:{0}".format(self.__portSpin.value())) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ self.__stopServer() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__stopServer() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process and inserts it into the log. """ if self.process is not None: s = str(self.process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') self.__appendText(s, False) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the log. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__appendText(s, True) def __appendText(self, txt, error=False): """ Private method to append text to the end. @param txt text to insert (string) @param error flag indicating to insert error text (boolean) """ tc = self.__log.textCursor() tc.movePosition(QTextCursor.End) self.__log.setTextCursor(tc) if error: self.__log.setCurrentCharFormat(self.cErrorFormat) else: self.__log.setCurrentCharFormat(self.cNormalFormat) self.__log.insertPlainText(txt) self.__log.ensureCursorVisible() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBookmarksListDialog.ui0000644000175000017500000001152012334163520025342 0ustar piotrpiotr HgBookmarksListDialog 0 0 634 494 Mercurial Bookmarks <b>Mercurial Bookmarks</b> <p>This dialog shows a list of the projects bookmarks.</p> true 0 2 <b>Bookmarks List</b> <p>This shows a list of the projects bookmarks.</p> true false false true Revision Changeset Status Name 0 1 Errors true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close qPixmapFromMimeSource input passwordCheckBox sendButton bookmarksList errors buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.py0000644000175000017500000001317412451233372024173 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a backout operation. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QDateTime from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgBackoutDialog import Ui_HgBackoutDialog class HgBackoutDialog(QDialog, Ui_HgBackoutDialog): """ Class implementing a dialog to enter the data for a backout operation. """ def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None): """ Constructor @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param parent parent widget (QWidget) """ super(HgBackoutDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.tagCombo.addItems(sorted(tagsList)) self.branchCombo.addItems(["default"] + sorted(branchesList)) if bookmarksList is not None: self.bookmarkCombo.addItems(sorted(bookmarksList)) else: self.bookmarkButton.setHidden(True) self.bookmarkCombo.setHidden(True) self.__initDateTime = QDateTime.currentDateTime() self.dateEdit.setDateTime(self.__initDateTime) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.noneButton.isChecked(): enabled = False elif self.idButton.isChecked(): enabled = self.idEdit.text() != "" elif self.tagButton.isChecked(): enabled = self.tagCombo.currentText() != "" elif self.branchButton.isChecked(): enabled = self.branchCombo.currentText() != "" elif self.bookmarkButton.isChecked(): enabled = self.bookmarkCombo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(bool) def on_idButton_toggled(self, checked): """ Private slot to handle changes of the ID select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tagButton_toggled(self, checked): """ Private slot to handle changes of the Tag select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branchButton_toggled(self, checked): """ Private slot to handle changes of the Branch select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmarkButton_toggled(self, checked): """ Private slot to handle changes of the Bookmark select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_noneButton_toggled(self, checked): """ Private slot to handle the toggling of the None revision button. @param checked flag indicating the checked state (boolean) """ self.__updateOK() @pyqtSlot(str) def on_idEdit_textChanged(self, txt): """ Private slot to handle changes of the ID edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_tagCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branchCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmarkCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark combo. @param txt text of the combo (string) """ self.__updateOK() def getParameters(self): """ Public method to retrieve the backout data. @return tuple naming the revision, a flag indicating a merge, the commit date, the commit user and a commit message (string, boolean, string, string, string) """ if self.numberButton.isChecked(): rev = "rev({0})".format(self.numberSpinBox.value()) elif self.idButton.isChecked(): rev = "id({0})".format(self.idEdit.text()) elif self.tagButton.isChecked(): rev = self.tagCombo.currentText() elif self.branchButton.isChecked(): rev = self.branchCombo.currentText() elif self.bookmarkButton.isChecked(): rev = self.bookmarkCombo.currentText() else: rev = "" if self.dateEdit.dateTime() != self.__initDateTime: date = self.dateEdit.dateTime().toString("yyyy-MM-dd hh:mm") else: date = "" if self.messageEdit.toPlainText(): msg = self.messageEdit.toPlainText() else: msg = self.tr("Backed out changeset <{0}>.").format(rev) return (rev, self.mergeCheckBox.isChecked, date, self.userEdit.text(), msg ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgSummaryDialog.py0000644000175000017500000004462612451233372024246 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a dialog to show some summary information of the working directory state. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, QProcess, QTimer from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5MessageBox from .HgUtilities import prepareProcess from .Ui_HgSummaryDialog import Ui_HgSummaryDialog class HgSummaryDialog(QDialog, Ui_HgSummaryDialog): """ Class implementing a dialog to show some summary information of the working directory state. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(HgSummaryDialog, self).__init__(parent) self.setupUi(self) self.refreshButton = self.buttonBox.addButton( self.tr("Refresh"), QDialogButtonBox.ActionRole) self.refreshButton.setToolTip( self.tr("Press to refresh the summary display")) self.refreshButton.setEnabled(False) self.process = None self.vcs = vcs self.vcs.committed.connect(self.__committed) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, path, mq=False, largefiles=False): """ Public slot to start the hg summary command. @param path path name of the working directory (string) @param mq flag indicating to show the queue status as well (boolean) @param largefiles flag indicating to show the largefiles status as well (boolean) """ self.errorGroup.hide() self.__path = path self.__mq = mq self.__largefiles = largefiles args = self.vcs.initCommand("summary") if self.vcs.canPull(): args.append("--remote") if self.__mq: args.append("--mq") if self.__largefiles: args.append("--large") # find the root of the repo repodir = self.__path while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if self.process: self.process.kill() else: self.process = QProcess() prepareProcess(self.process, language="C") self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.process.setWorkingDirectory(repodir) self.__buffer = [] self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.refreshButton.setEnabled(True) self.process = None def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.refreshButton: self.on_refreshButton_clicked() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__processOutput(self.__buffer) self.__finish() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.process is not None: self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): line = str(self.process.readLine(), self.vcs.getEncoding(), 'replace') self.__buffer.append(line) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() @pyqtSlot() def on_refreshButton_clicked(self): """ Private slot to refresh the status display. """ self.refreshButton.setEnabled(False) self.summary.clear() self.start(self.__path, mq=self.__mq) def __committed(self): """ Private slot called after the commit has finished. """ if self.isVisible(): self.on_refreshButton_clicked() def __processOutput(self, output): """ Private method to process the output into nice readable text. @param output output from the summary command (string) """ infoDict = {} # step 1: parse the output while output: line = output.pop(0) if ':' not in line: continue name, value = line.split(": ", 1) value = value.strip() if name == "parent": if " " in value: parent, tags = value.split(" ", 1) else: parent = value tags = "" rev, node = parent.split(":") remarks = [] if tags: if " (empty repository)" in tags: remarks.append("@EMPTY@") tags = tags.replace(" (empty repository)", "") if " (no revision checked out)" in tags: remarks.append("@NO_REVISION@") tags = tags.replace(" (no revision checked out)", "") else: tags = None value = infoDict.get(name, []) if rev == "-1": value.append((int(rev), node, tags, None, remarks)) else: message = output.pop(0).strip() value.append((int(rev), node, tags, message, remarks)) elif name == "branch": pass elif name == "bookmarks": pass elif name == "commit": stateDict = {} if "(" in value: if value.startswith("("): states = "" remark = value[1:-1] else: states, remark = value.rsplit(" (", 1) remark = remark[:-1] else: states = value remark = "" states = states.split(", ") for state in states: if state: count, category = state.split(" ") stateDict[category] = count value = (stateDict, remark) elif name == "update": if value.endswith("(current)"): value = ("@CURRENT@", 0, 0) elif value.endswith("(update)"): value = ("@UPDATE@", int(value.split(" ", 1)[0]), 0) elif value.endswith("(merge)"): parts = value.split(", ") value = ("@MERGE@", int(parts[0].split(" ", 1)[0]), int(parts[1].split(" ", 1)[0])) else: value = ("@UNKNOWN@", 0, 0) elif name == "remote": if value == "(synced)": value = (0, 0, 0, 0) else: inc = incb = outg = outgb = 0 for val in value.split(", "): count, category = val.split(" ", 1) if category == "outgoing": outg = int(count) elif category.endswith("incoming"): inc = int(count) elif category == "incoming bookmarks": incb = int(count) elif category == "outgoing bookmarks": outgb = int(count) value = (inc, outg, incb, outgb) elif name == "mq": if value == "(empty queue)": value = (0, 0) else: applied = unapplied = 0 for val in value.split(", "): count, category = val.split(" ", 1) if category == "applied": applied = int(count) elif category == "unapplied": unapplied = int(count) value = (applied, unapplied) elif name == "largefiles": if not value[0].isdigit(): value = 0 else: value = int(value.split(None, 1)[0]) else: # ignore unknown entries continue infoDict[name] = value # step 2: build the output if infoDict: info = [""] pindex = 0 for rev, node, tags, message, remarks in infoDict["parent"]: pindex += 1 changeset = "{0}:{1}".format(rev, node) if len(infoDict["parent"]) > 1: info.append(self.tr( "") .format(pindex, changeset)) else: info.append(self.tr( "") .format(changeset)) if tags: info.append(self.tr( "") .format('
'.join(tags.split()))) if message: info.append(self.tr( "") .format(message)) if remarks: rem = [] if "@EMPTY@" in remarks: rem.append(self.tr("empty repository")) if "@NO_REVISION@" in remarks: rem.append(self.tr("no revision checked out")) info.append(self.tr( "") .format(", ".join(rem))) if "branch" in infoDict: info.append(self.tr( "") .format(infoDict["branch"])) if "bookmarks" in infoDict: bookmarks = infoDict["bookmarks"].split() for i in range(len(bookmarks)): if bookmarks[i].startswith("*"): bookmarks[i] = "{0}".format(bookmarks[i]) info.append(self.tr( "") .format('
'.join(bookmarks))) if "commit" in infoDict: cinfo = [] for category, count in infoDict["commit"][0].items(): if category == "modified": cinfo.append(self.tr("{0} modified").format(count)) elif category == "added": cinfo.append(self.tr("{0} added").format(count)) elif category == "removed": cinfo.append(self.tr("{0} removed").format(count)) elif category == "renamed": cinfo.append(self.tr("{0} renamed").format(count)) elif category == "copied": cinfo.append(self.tr("{0} copied").format(count)) elif category == "deleted": cinfo.append(self.tr("{0} deleted").format(count)) elif category == "unknown": cinfo.append(self.tr("{0} unknown").format(count)) elif category == "ignored": cinfo.append(self.tr("{0} ignored").format(count)) elif category == "unresolved": cinfo.append( self.tr("{0} unresolved").format(count)) elif category == "subrepos": cinfo.append(self.tr("{0} subrepos").format(count)) remark = infoDict["commit"][1] if remark == "merge": cinfo.append(self.tr("Merge needed")) elif remark == "new branch": cinfo.append(self.tr("New Branch")) elif remark == "head closed": cinfo.append(self.tr("Head is closed")) elif remark == "clean": cinfo.append(self.tr("No commit required")) elif remark == "new branch head": cinfo.append(self.tr("New Branch Head")) info.append(self.tr( "") .format("
".join(cinfo))) if "update" in infoDict: if infoDict["update"][0] == "@CURRENT@": uinfo = self.tr("current") elif infoDict["update"][0] == "@UPDATE@": uinfo = self.tr( "%n new changeset(s)
Update required", "", infoDict["update"][1]) elif infoDict["update"][0] == "@MERGE@": uinfo1 = self.tr( "%n new changeset(s)", "", infoDict["update"][1]) uinfo2 = self.tr( "%n branch head(s)", "", infoDict["update"][2]) uinfo = self.tr( "{0}
{1}
Merge required", "0 is changesets, 1 is branch heads")\ .format(uinfo1, uinfo2) else: uinfo = self.tr("unknown status") info.append(self.tr( "") .format(uinfo)) if "remote" in infoDict: if infoDict["remote"] == (0, 0, 0, 0): rinfo = self.tr("synched") else: li = [] if infoDict["remote"][0]: li.append(self.tr("1 or more incoming")) if infoDict["remote"][1]: li.append(self.tr("{0} outgoing") .format(infoDict["remote"][1])) if infoDict["remote"][2]: li.append(self.tr("%n incoming bookmark(s)", "", infoDict["remote"][2])) if infoDict["remote"][3]: li.append(self.tr("%n outgoing bookmark(s)", "", infoDict["remote"][3])) rinfo = "
".join(li) info.append(self.tr( "") .format(rinfo)) if "mq" in infoDict: if infoDict["mq"] == (0, 0): qinfo = self.tr("empty queue") else: li = [] if infoDict["mq"][0]: li.append(self.tr("{0} applied") .format(infoDict["mq"][0])) if infoDict["mq"][1]: li.append(self.tr("{0} unapplied") .format(infoDict["mq"][1])) qinfo = "
".join(li) info.append(self.tr( "") .format(qinfo)) if "largefiles" in infoDict: if infoDict["largefiles"] == 0: lfInfo = self.tr("No files to upload") else: lfInfo = self.tr("%n file(s) to upload", "", infoDict["largefiles"]) info.append(self.tr( "") .format(lfInfo)) info.append("
Parent #{0}{1}
Parent{0}
Tags{0}
Commit Message{0}
Remarks{0}
Branch{0}
Bookmarks{0}
Commit Status{0}
Update Status{0}
Remote Status{0}
Queues Status{0}
Large Files{0}
") else: info = [self.tr("

No status information available.

")] self.summary.insertHtml("\n".join(info)) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/0000755000175000017500000000000012557365404024241 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.ui0000644000175000017500000002362512302425206027311 0ustar piotrpiotr MercurialPage 0 0 609 751 <b>Configure Mercurial Interface</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Global Options Encoding: 0 0 Select the encoding to be used by Mercurial Encoding Mode: 0 0 Select the encoding mode Consider hidden changesets Log No. of log messages shown: Enter the number of log messages to be shown Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 999999 Qt::Horizontal 41 20 Commit No. of commit messages to remember: Enter the number of commit messages to remember Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 100 Qt::Horizontal 40 20 Incoming / Outgoing Select to show the incoming and outgoing log in a log browser dialog Use Log Browser for incoming / outgoing log Pull Select to update the working directory to new tip Update after pulling Select to prefer unbundle over pull <b>Prefer Unbundle</b> <p>If this option is selected, it will be checked, if a Mercurial changegroups file from a previous "Show Incoming" request exists. In this case it will be applied and deleted. Otherwise a pull request will be sent.</p> Prefer Unbundle Merge Select to enforce usage of the Mercural internal merge tool <b>Internal Merge Tool</b> <p>Select to enforce usage of the Mercural internal merge tool,which leaves conflict markers in the file in case of conflicting changes.</p> Use internal merge with conflict markers Revert Select to create a backup file (.orig) before reverting changes Create Backup Files Cleanup Pattern: Enter the file name patterns to be used for cleaning up (entries separated by a space character) Edit the Mercurial configuration file Edit configuration file Qt::Vertical 388 21 encodingComboBox encodingModeComboBox hiddenChangesetsCheckBox logSpinBox commitSpinBox logBrowserCheckBox pullUpdateCheckBox preferUnbundleCheckBox internalMergeCheckBox backupCheckBox cleanupPatternEdit configButton eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py0000644000175000017500000001304112451233372027321 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the Mercurial configuration page. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from Preferences.ConfigurationPages.ConfigurationPageBase import \ ConfigurationPageBase from .Ui_MercurialPage import Ui_MercurialPage from Utilities import supportedCodecs class MercurialPage(ConfigurationPageBase, Ui_MercurialPage): """ Class implementing the Mercurial configuration page. """ def __init__(self, plugin): """ Constructor @param plugin reference to the plugin object """ super(MercurialPage, self).__init__() self.setupUi(self) self.setObjectName("MercurialPage") self.__plugin = plugin self.encodingComboBox.addItems(sorted(supportedCodecs)) self.encodingModeComboBox.addItems(["strict", "ignore", "replace"]) # set initial values # global options index = self.encodingComboBox.findText( self.__plugin.getPreferences("Encoding")) self.encodingComboBox.setCurrentIndex(index) index = self.encodingModeComboBox.findText( self.__plugin.getPreferences("EncodingMode")) self.encodingModeComboBox.setCurrentIndex(index) self.hiddenChangesetsCheckBox.setChecked( self.__plugin.getPreferences("ConsiderHidden")) # log self.logSpinBox.setValue( self.__plugin.getPreferences("LogLimit")) # commit self.commitSpinBox.setValue( self.__plugin.getPreferences("CommitMessages")) # incoming/outgoing self.logBrowserCheckBox.setChecked( self.__plugin.getPreferences("UseLogBrowser")) # pull self.pullUpdateCheckBox.setChecked( self.__plugin.getPreferences("PullUpdate")) self.preferUnbundleCheckBox.setChecked( self.__plugin.getPreferences("PreferUnbundle")) # cleanup self.cleanupPatternEdit.setText( self.__plugin.getPreferences("CleanupPatterns")) # revert self.backupCheckBox.setChecked( self.__plugin.getPreferences("CreateBackup")) # merge self.internalMergeCheckBox.setChecked( self.__plugin.getPreferences("InternalMerge")) def save(self): """ Public slot to save the Mercurial configuration. """ # global options self.__plugin.setPreferences( "Encoding", self.encodingComboBox.currentText()) self.__plugin.setPreferences( "EncodingMode", self.encodingModeComboBox.currentText()) self.__plugin.setPreferences( "ConsiderHidden", self.hiddenChangesetsCheckBox.isChecked()) # log self.__plugin.setPreferences( "LogLimit", self.logSpinBox.value()) # commit self.__plugin.setPreferences( "CommitMessages", self.commitSpinBox.value()) # incoming/outgoing self.__plugin.setPreferences( "UseLogBrowser", self.logBrowserCheckBox.isChecked()) # pull self.__plugin.setPreferences( "PullUpdate", self.pullUpdateCheckBox.isChecked()) self.__plugin.setPreferences( "PreferUnbundle", self.preferUnbundleCheckBox.isChecked()) # cleanup self.__plugin.setPreferences( "CleanupPatterns", self.cleanupPatternEdit.text()) # revert self.__plugin.setPreferences( "CreateBackup", self.backupCheckBox.isChecked()) # merge self.__plugin.setPreferences( "InternalMerge", self.internalMergeCheckBox.isChecked()) @pyqtSlot() def on_configButton_clicked(self): """ Private slot to edit the (per user) Mercurial configuration file. """ from QScintilla.MiniEditor import MiniEditor cfgFile = self.__plugin.getConfigPath() if not os.path.exists(cfgFile): from ..HgUserConfigDataDialog import HgUserConfigDataDialog dlg = HgUserConfigDataDialog() if dlg.exec_() == QDialog.Accepted: firstName, lastName, email, extensions, extensionsData = \ dlg.getData() else: firstName, lastName, email, extensions, extensionsData = ( "Firstname", "Lastname", "email_address", [], {}) try: f = open(cfgFile, "w") f.write("[ui]\n") f.write("username = {0} {1} <{2}>\n".format( firstName, lastName, email)) if extensions: f.write("\n[extensions]\n") f.write(" =\n".join(extensions)) f.write(" =\n") # complete the last line if "largefiles" in extensionsData: dataDict = extensionsData["largefiles"] f.write("\n[largefiles]\n") if "minsize" in dataDict: f.write("minsize = {0}\n".format(dataDict["minsize"])) if "patterns" in dataDict: f.write("patterns =\n") f.write(" {0}\n".format( "\n ".join(dataDict["patterns"]))) f.close() except (IOError, OSError): # ignore these pass editor = MiniEditor(cfgFile, "Properties", self) editor.show() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/__init__.py0000644000175000017500000000024712451233372026344 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Package implementing the the Mercurial configuration page. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgCommandDialog.ui0000644000175000017500000000751512354033471024150 0ustar piotrpiotr HgCommandDialog 0 0 628 99 Mercurial Command true Mercurial Command: 0 0 Enter the Mercurial command to be executed with all necessary parameters <b>Mercurial Command</b> <p>Enter the Mercurial command to be executed including all necessary parameters. If a parameter of the commandline includes a space you have to surround this parameter by single or double quotes. Do not include the name of the Mercurial client executable (i.e. hg).</p> true QComboBox::InsertAtTop false 0 0 Project Directory: 0 0 This shows the root directory of the current project. project directory Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource commandCombo buttonBox buttonBox accepted() HgCommandDialog accept() 41 103 49 129 buttonBox rejected() HgCommandDialog reject() 173 109 174 128 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.py0000644000175000017500000001132512451233372023636 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a merge operation. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgMergeDialog import Ui_HgMergeDialog class HgMergeDialog(QDialog, Ui_HgMergeDialog): """ Class implementing a dialog to enter the data for a merge operation. """ def __init__(self, tagsList, branchesList, bookmarksList=None, parent=None): """ Constructor @param tagsList list of tags (list of strings) @param branchesList list of branches (list of strings) @param bookmarksList list of bookmarks (list of strings) @param parent parent widget (QWidget) """ super(HgMergeDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.tagCombo.addItems(sorted(tagsList)) self.branchCombo.addItems(["default"] + sorted(branchesList)) if bookmarksList is not None: self.bookmarkCombo.addItems(sorted(bookmarksList)) else: self.bookmarkButton.setHidden(True) self.bookmarkCombo.setHidden(True) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.idButton.isChecked(): enabled = self.idEdit.text() != "" elif self.tagButton.isChecked(): enabled = self.tagCombo.currentText() != "" elif self.branchButton.isChecked(): enabled = self.branchCombo.currentText() != "" elif self.bookmarkButton.isChecked(): enabled = self.bookmarkCombo.currentText() != "" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(bool) def on_idButton_toggled(self, checked): """ Private slot to handle changes of the ID select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_tagButton_toggled(self, checked): """ Private slot to handle changes of the Tag select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_branchButton_toggled(self, checked): """ Private slot to handle changes of the Branch select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(bool) def on_bookmarkButton_toggled(self, checked): """ Private slot to handle changes of the Bookmark select button. @param checked state of the button (boolean) """ self.__updateOK() @pyqtSlot(str) def on_idEdit_textChanged(self, txt): """ Private slot to handle changes of the ID edit. @param txt text of the edit (string) """ self.__updateOK() @pyqtSlot(str) def on_tagCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Tag combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_branchCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Branch combo. @param txt text of the combo (string) """ self.__updateOK() @pyqtSlot(str) def on_bookmarkCombo_editTextChanged(self, txt): """ Private slot to handle changes of the Bookmark combo. @param txt text of the combo (string) """ self.__updateOK() def getParameters(self): """ Public method to retrieve the merge data. @return tuple naming the revision and a flag indicating a forced merge (string, boolean) """ if self.numberButton.isChecked(): rev = "rev({0})".format(self.numberSpinBox.value()) elif self.idButton.isChecked(): rev = "id({0})".format(self.idEdit.text()) elif self.tagButton.isChecked(): rev = self.tagCombo.currentText() elif self.branchButton.isChecked(): rev = self.branchCombo.currentText() elif self.bookmarkButton.isChecked(): rev = self.bookmarkCombo.currentText() else: rev = "" return rev, self.forceCheckBox.isChecked() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/templates/0000755000175000017500000000000012362743715022632 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/templates/logDialogBookmarkPhase.tmpl0000644000175000017500000000050612362747450030101 0ustar piotrpiotrchange|{rev}:{node|short} branches|{branch} tags|{join(tags,', ')} parents|{parents} user|{author} date|{date|isodate} description|{desc} file_copies|{join(file_copies,', ')} file_adds|{join(file_adds,', ')} files_mods|{join(file_mods,', ')} file_dels|{join(file_dels,', ')} bookmarks|{join(bookmarks,', ')} phase|{phase} @@@ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/templates/logBrowserBookmarkPhase.tmpl0000644000175000017500000000051412362730231030311 0ustar piotrpiotrchange|{rev}:{node|short} user|{author|email} parents|{parents} date|{date|isodate} description|{desc} file_copies|{join(file_copies,', ')} file_adds|{join(file_adds,', ')} files_mods|{join(file_mods,', ')} file_dels|{join(file_dels,', ')} branches|{branch} tags|{join(tags,', ')} bookmarks|{join(bookmarks,', ')} phase|{phase} @@@ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py0000644000175000017500000001305312451233372026233 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the Mercurial Options Dialog for a new project from the repository. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot, QDir from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_HgNewProjectOptionsDialog import Ui_HgNewProjectOptionsDialog from .Config import ConfigHgProtocols import Utilities import Preferences import UI.PixmapCache class HgNewProjectOptionsDialog(QDialog, Ui_HgNewProjectOptionsDialog): """ Class implementing the Options Dialog for a new project from the repository. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the version control object @param parent parent widget (QWidget) """ super(HgNewProjectOptionsDialog, self).__init__(parent) self.setupUi(self) self.projectDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.vcsUrlButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.vcsDirectoryCompleter = E5DirCompleter(self.vcsUrlEdit) self.vcsProjectDirCompleter = E5DirCompleter(self.vcsProjectDirEdit) self.protocolCombo.addItems(ConfigHgProtocols) hd = Utilities.toNativeSeparators(QDir.homePath()) hd = os.path.join(hd, 'hgroot') self.vcsUrlEdit.setText(hd) self.vcs = vcs self.localPath = hd self.networkPath = "localhost/" self.localProtocol = True ipath = Preferences.getMultiProject("Workspace") or \ Utilities.getHomeDir() self.__initPaths = [ Utilities.fromNativeSeparators(ipath), Utilities.fromNativeSeparators(ipath) + "/", ] self.vcsProjectDirEdit.setText( Utilities.toNativeSeparators(self.__initPaths[0])) self.lfNoteLabel.setVisible(self.vcs.isExtensionActive("largefiles")) self.largeCheckBox.setVisible(self.vcs.isExtensionActive("largefiles")) self.resize(self.width(), self.minimumSizeHint().height()) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(str) def on_vcsProjectDirEdit_textChanged(self, txt): """ Private slot to handle a change of the project directory. @param txt name of the project directory (string) """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths) @pyqtSlot() def on_vcsUrlButton_clicked(self): """ Private slot to display a selection dialog. """ if self.protocolCombo.currentText() == "file://": directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Repository-Directory"), self.vcsUrlEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.vcsUrlEdit.setText( Utilities.toNativeSeparators(directory)) @pyqtSlot() def on_projectDirButton_clicked(self): """ Private slot to display a directory selection dialog. """ directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Project Directory"), self.vcsProjectDirEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.vcsProjectDirEdit.setText( Utilities.toNativeSeparators(directory)) @pyqtSlot(str) def on_protocolCombo_activated(self, protocol): """ Private slot to switch the status of the directory selection button. @param protocol name of the selected protocol (string) """ self.vcsUrlButton.setEnabled(protocol == "file://") if protocol == "file://": self.networkPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.localPath) self.localProtocol = True else: if self.localProtocol: self.localPath = self.vcsUrlEdit.text() self.vcsUrlEdit.setText(self.networkPath) self.localProtocol = False @pyqtSlot(str) def on_vcsUrlEdit_textChanged(self, txt): """ Private slot to handle changes of the URL. @param txt current text of the line edit (string) """ enable = "://" not in txt self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) def getData(self): """ Public slot to retrieve the data entered into the dialog. @return a tuple of a string (project directory) and a dictionary containing the data entered. """ scheme = self.protocolCombo.currentText() url = self.vcsUrlEdit.text() if scheme == "file://" and url[0] not in ["\\", "/"]: url = "/{0}".format(url) vcsdatadict = { "url": '{0}{1}'.format(scheme, url), "revision": self.vcsRevisionEdit.text(), "largefiles": self.largeCheckBox.isChecked(), } return (self.vcsProjectDirEdit.text(), vcsdatadict) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgExportDialog.py0000644000175000017500000000723012451233372024060 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter data for the Mercurial export command. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot, QDir from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5FileDialog from E5Gui.E5Completers import E5DirCompleter from .Ui_HgExportDialog import Ui_HgExportDialog import Utilities import UI.PixmapCache class HgExportDialog(QDialog, Ui_HgExportDialog): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(HgExportDialog, self).__init__(parent) self.setupUi(self) self.directoryButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.__directoryCompleter = E5DirCompleter(self.directoryEdit) # set default values for directory and pattern self.patternEdit.setText("%b_%r_%h_%n_of_%N.diff") self.directoryEdit.setText(QDir.tempPath()) def __updateOK(self): """ Private slot to update the OK button. """ enabled = True if self.directoryEdit.text() == "": enabled = False elif self.patternEdit.text() == "": enabled = False elif self.changesetsEdit.toPlainText() == "": enabled = False self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) @pyqtSlot(str) def on_directoryEdit_textChanged(self, txt): """ Private slot to react on changes of the export directory edit. @param txt contents of the line edit (string) """ self.__updateOK() @pyqtSlot() def on_directoryButton_clicked(self): """ Private slot called by pressing the export directory selection button. """ dn = E5FileDialog.getExistingDirectory( self, self.tr("Export Patches"), self.directoryEdit.text(), E5FileDialog.Options(E5FileDialog.Option(0))) if dn: self.directoryEdit.setText(Utilities.toNativeSeparators(dn)) @pyqtSlot(str) def on_patternEdit_textChanged(self, txt): """ Private slot to react on changes of the export file name pattern edit. @param txt contents of the line edit (string) """ self.__updateOK() @pyqtSlot() def on_changesetsEdit_textChanged(self): """ Private slot to react on changes of the changesets edit. """ self.__updateOK() def getParameters(self): """ Public method to retrieve the export data. @return tuple naming the output file name, the list of revisions to export, and flags indicating to compare against the second parent, to treat all files as text, to omit dates in the diff headers and to use the git extended diff format (string, list of strings, boolean, boolean, boolean, boolean) """ return ( os.path.join( Utilities.toNativeSeparators(self.directoryEdit.text()), self.patternEdit.text()), self.changesetsEdit.toPlainText().splitlines(), self.switchParentCheckBox.isChecked(), self.textCheckBox.isChecked(), self.datesCheckBox.isChecked(), self.gitCheckBox.isChecked() ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py0000644000175000017500000000764312451233372024037 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the commit message. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt from PyQt5.QtWidgets import QWidget, QDialogButtonBox from .Ui_HgCommitDialog import Ui_HgCommitDialog import Preferences class HgCommitDialog(QWidget, Ui_HgCommitDialog): """ Class implementing a dialog to enter the commit message. @signal accepted() emitted, if the dialog was accepted @signal rejected() emitted, if the dialog was rejected """ accepted = pyqtSignal() rejected = pyqtSignal() def __init__(self, vcs, msg, mq, parent=None): """ Constructor @param vcs reference to the vcs object @param msg initial message (string) @param mq flag indicating a queue commit (boolean) @param parent parent widget (QWidget) """ super(HgCommitDialog, self).__init__(parent, Qt.WindowFlags(Qt.Window)) self.setupUi(self) self.logEdit.setPlainText(msg) if mq: self.amendCheckBox.setVisible(False) self.subrepoCheckBox.setVisible(False) else: if vcs.version < (2, 2): self.amendCheckBox.setEnabled(False) self.subrepoCheckBox.setVisible(vcs.hasSubrepositories()) def showEvent(self, evt): """ Protected method called when the dialog is about to be shown. @param evt the event (QShowEvent) """ self.recentCommitMessages = Preferences.toList( Preferences.Prefs.settings.value('Mercurial/Commits')) self.recentComboBox.clear() self.recentComboBox.addItem("") self.recentComboBox.addItems(self.recentCommitMessages) def logMessage(self): """ Public method to retrieve the log message. @return the log message (string) """ msg = self.logEdit.toPlainText() if msg: if msg in self.recentCommitMessages: self.recentCommitMessages.remove(msg) self.recentCommitMessages.insert(0, msg) no = int(Preferences.Prefs.settings.value( 'Mercurial/CommitMessages', 20)) del self.recentCommitMessages[no:] Preferences.Prefs.settings.setValue( 'Mercurial/Commits', self.recentCommitMessages) return msg def amend(self): """ Public method to retrieve the state of the amend flag. @return state of the amend flag (boolean) """ return self.amendCheckBox.isChecked() def commitSubrepositories(self): """ Public method to retrieve the state of the commit sub-repositories flag. @return state of the sub-repositories flag (boolean) """ return self.subrepoCheckBox.isChecked() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Cancel): self.logEdit.clear() def on_buttonBox_accepted(self): """ Private slot called by the buttonBox accepted signal. """ self.close() self.accepted.emit() def on_buttonBox_rejected(self): """ Private slot called by the buttonBox rejected signal. """ self.close() self.rejected.emit() @pyqtSlot(str) def on_recentComboBox_activated(self, txt): """ Private slot to select a commit message from recent ones. @param txt text of the selected entry (string) """ if txt: self.logEdit.setPlainText(txt) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgLogDialog.ui0000644000175000017500000001170212176740703023311 0ustar piotrpiotr HgLogDialog 0 0 751 649 Mercurial Log 0 3 Log <b>Mercurial Log</b><p>This shows the output of the hg log command. By clicking on the links you may show the difference between revisions.</p> false Select to show differences side-by-side Show differences side-by-side 0 1 Errors <b>Mercurial log errors</b><p>This shows possible error messages of the hg log command.</p> true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P Qt::Horizontal QDialogButtonBox::Close contents sbsCheckBox errors input passwordCheckBox sendButton buttonBox buttonBox rejected() HgLogDialog close() 262 624 271 647 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgSummaryDialog.ui0000644000175000017500000000545712172525422024232 0ustar piotrpiotr HgSummaryDialog 0 0 600 500 Summary Information true 0 2 true 0 1 Errors 0 0 true false Qt::Horizontal QDialogButtonBox::Close summary errors buttonBox buttonBox accepted() HgSummaryDialog accept() 248 254 157 274 buttonBox rejected() HgSummaryDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.ui0000644000175000017500000002166312312353424026233 0ustar piotrpiotr HgRevisionSelectionDialog 0 0 372 250 Mercurial Revision true Revision Select to specify a revision by number Number false Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 158 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false 0 0 Enter a tag name true Select to specify a revision by a branch Branch: false 0 0 Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select tip revision of repository TIP No revision selected true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok numberButton numberSpinBox idButton idEdit tagButton tagCombo branchButton branchCombo bookmarkButton bookmarkCombo tipButton noneButton buttonBox buttonBox accepted() HgRevisionSelectionDialog accept() 257 215 157 223 buttonBox rejected() HgRevisionSelectionDialog reject() 325 215 286 223 numberButton toggled(bool) numberSpinBox setEnabled(bool) 55 44 125 42 idButton toggled(bool) idEdit setEnabled(bool) 41 69 121 68 tagButton toggled(bool) tagCombo setEnabled(bool) 69 94 132 98 branchButton toggled(bool) branchCombo setEnabled(bool) 60 120 117 122 bookmarkButton toggled(bool) bookmarkCombo setEnabled(bool) 25 146 130 149 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/0000755000175000017500000000000012557365404023760 5ustar piotrpiotreric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgUnshelveDataDialog.py0000644000175000017500000000312412451233372030303 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for an unshelve operation. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_HgUnshelveDataDialog import Ui_HgUnshelveDataDialog class HgUnshelveDataDialog(QDialog, Ui_HgUnshelveDataDialog): """ Class implementing a dialog to enter the data for an unshelve operation. """ def __init__(self, shelveNames, shelveName="", parent=None): """ Constructor @param shelveNames list of available shelves (list of string) @param shelveName name of the shelve to restore (string) @param parent reference to the parent widget (QWidget) """ super(HgUnshelveDataDialog, self).__init__(parent) self.setupUi(self) self.nameComboBox.addItem("") self.nameComboBox.addItems(sorted(shelveNames)) if shelveName and shelveName in shelveNames: self.nameComboBox.setCurrentIndex( self.nameComboBox.findText(shelveName)) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public method to get the user data. @return tuple containing the name (string) and a flag indicating to keep the shelved change (boolean) """ return ( self.nameComboBox.currentText().replace(" ", "_"), self.keepCheckBox.isChecked() ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/ProjectBrowserHelper.py0000644000175000017500000000741512451233372030442 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing the shelve extension project browser helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui import E5MessageBox from ..HgExtensionProjectBrowserHelper import HgExtensionProjectBrowserHelper class ShelveProjectBrowserHelper(HgExtensionProjectBrowserHelper): """ Class implementing the shelve extension project browser helper. """ def __init__(self, vcsObject, browserObject, projectObject): """ Constructor @param vcsObject reference to the vcs object @param browserObject reference to the project browser object @param projectObject reference to the project object """ super(ShelveProjectBrowserHelper, self).__init__( vcsObject, browserObject, projectObject) def initMenus(self): """ Public method to generate the extension menus. @return dictionary of populated menu (dict of QMenu). The dict must have the keys 'mainMenu', 'multiMenu', 'backMenu', 'dirMenu' and 'dirMultiMenu'. """ self.__menus = {} menu = QMenu(self.menuTitle()) menu.setTearOffEnabled(True) menu.addAction(self.tr("Shelve changes"), self.__hgShelve) self.__menus['mainMenu'] = menu menu = QMenu(self.menuTitle()) menu.setTearOffEnabled(True) menu.addAction(self.tr("Shelve changes"), self.__hgShelve) self.__menus['multiMenu'] = menu menu = QMenu(self.menuTitle()) menu.setTearOffEnabled(True) menu.addAction(self.tr("Shelve changes"), self.__hgShelve) self.__menus['dirMenu'] = menu menu = QMenu(self.menuTitle()) menu.setTearOffEnabled(True) menu.addAction(self.tr("Shelve changes"), self.__hgShelve) self.__menus['dirMultiMenu'] = menu return self.__menus def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("Shelve") def showExtensionMenu(self, key, controlled): """ Public method to prepare the extension menu for display. @param key menu key (string, one of 'mainMenu', 'multiMenu', 'backMenu', 'dirMenu' or 'dirMultiMenu') @param controlled flag indicating to prepare the menu for a version controlled entry or a non-version controlled entry (boolean) """ if key in self.__menus: self.__menus[key].setEnabled(controlled) def __reopenProject(self, shouldReopen, title): """ Private method to reopen the project if needed and wanted. @param shouldReopen flag indicating that the project should be reopened (boolean) @param title title of the message box (string) """ if shouldReopen: res = E5MessageBox.yesNo( None, title, self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgShelve(self): """ Private slot used to shelve all current changes. """ names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) shouldReopen = self.vcs.getExtensionObject("shelve")\ .hgShelve(names) self.__reopenProject(shouldReopen, self.tr("Shelve")) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgUnshelveDataDialog.ui0000644000175000017500000000512712302372554030276 0ustar piotrpiotr HgUnshelveDataDialog 0 0 400 108 Mercurial Unshelve true Name: 0 0 Enter the name of the shelve true Select to keep the shelved change Keep shelved change Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok nameComboBox keepCheckBox buttonBox buttonBox accepted() HgUnshelveDataDialog accept() 248 254 157 274 buttonBox rejected() HgUnshelveDataDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelvesSelectionDialog.ui0000644000175000017500000000415212302166762031171 0ustar piotrpiotr HgShelvesSelectionDialog 0 0 400 300 Mercurial Shelve Selection true true QAbstractItemView::ExtendedSelection true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok shelvesList buttonBox buttonBox accepted() HgShelvesSelectionDialog accept() 248 254 157 274 buttonBox rejected() HgShelvesSelectionDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/ProjectHelper.py0000644000175000017500000002050112451233372027065 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing the shelve extension project helper. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMenu from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox from ..HgExtensionProjectHelper import HgExtensionProjectHelper class ShelveProjectHelper(HgExtensionProjectHelper): """ Class implementing the shelve extension project helper. """ def __init__(self): """ Constructor """ super(ShelveProjectHelper, self).__init__() def initActions(self): """ Public method to generate the action objects. """ self.hgShelveAct = E5Action( self.tr('Shelve changes'), self.tr('Shelve changes...'), 0, 0, self, 'mercurial_shelve') self.hgShelveAct.setStatusTip(self.tr( 'Shelve all current changes of the project' )) self.hgShelveAct.setWhatsThis(self.tr( """Shelve changes""" """

This shelves all current changes of the project.

""" )) self.hgShelveAct.triggered.connect(self.__hgShelve) self.actions.append(self.hgShelveAct) self.hgShelveBrowserAct = E5Action( self.tr('Show shelve browser'), self.tr('Show shelve browser...'), 0, 0, self, 'mercurial_shelve_browser') self.hgShelveBrowserAct.setStatusTip(self.tr( 'Show a dialog with all shelves' )) self.hgShelveBrowserAct.setWhatsThis(self.tr( """Show shelve browser...""" """

This shows a dialog listing all available shelves.""" """ Actions on these shelves may be executed via the""" """ context menu.

""" )) self.hgShelveBrowserAct.triggered.connect( self.__hgShelveBrowser) self.actions.append(self.hgShelveBrowserAct) self.hgUnshelveAct = E5Action( self.tr('Restore shelved change'), self.tr('Restore shelved change...'), 0, 0, self, 'mercurial_unshelve') self.hgUnshelveAct.setStatusTip(self.tr( 'Restore a shelved change to the project directory' )) self.hgUnshelveAct.setWhatsThis(self.tr( """Restore shelved change""" """

This restore a shelved change to the project directory.""" """

""" )) self.hgUnshelveAct.triggered.connect(self.__hgUnshelve) self.actions.append(self.hgUnshelveAct) self.hgUnshelveAbortAct = E5Action( self.tr('Abort restore'), self.tr('Abort restore...'), 0, 0, self, 'mercurial_unshelve_abort') self.hgUnshelveAbortAct.setStatusTip(self.tr( 'Abort the restore operation in progress' )) self.hgUnshelveAbortAct.setWhatsThis(self.tr( """Abort restore""" """

This aborts the restore operation in progress and reverts""" """ already applied changes.

""" )) self.hgUnshelveAbortAct.triggered.connect(self.__hgUnshelveAbort) self.actions.append(self.hgUnshelveAbortAct) self.hgUnshelveContinueAct = E5Action( self.tr('Continue restore'), self.tr('Continue restore...'), 0, 0, self, 'mercurial_unshelve_continue') self.hgUnshelveContinueAct.setStatusTip(self.tr( 'Continue the restore operation in progress' )) self.hgUnshelveContinueAct.setWhatsThis(self.tr( """Continue restore""" """

This continues the restore operation in progress.

""" )) self.hgUnshelveContinueAct.triggered.connect( self.__hgUnshelveContinue) self.actions.append(self.hgUnshelveContinueAct) self.hgShelveDeleteAct = E5Action( self.tr('Delete shelved changes'), self.tr('Delete shelved changes...'), 0, 0, self, 'mercurial_shelve_delete') self.hgShelveDeleteAct.setWhatsThis(self.tr( """Delete shelved changes...""" """

This opens a dialog to select the shelved changes to""" """ delete and deletes the selected ones.

""" )) self.hgShelveDeleteAct.triggered.connect( self.__hgDeleteShelves) self.actions.append(self.hgShelveDeleteAct) self.hgShelveCleanupAct = E5Action( self.tr('Delete ALL shelved changes'), self.tr('Delete ALL shelved changes'), 0, 0, self, 'mercurial_shelve_cleanup') self.hgShelveCleanupAct.setWhatsThis(self.tr( """Delete ALL shelved changes""" """

This deletes all shelved changes.

""" )) self.hgShelveCleanupAct.triggered.connect( self.__hgCleanupShelves) self.actions.append(self.hgShelveCleanupAct) def initMenu(self, mainMenu): """ Public method to generate the extension menu. @param mainMenu reference to the main menu (QMenu) @return populated menu (QMenu) """ menu = QMenu(self.menuTitle(), mainMenu) menu.setTearOffEnabled(True) menu.addAction(self.hgShelveAct) menu.addSeparator() menu.addAction(self.hgShelveBrowserAct) menu.addSeparator() menu.addAction(self.hgUnshelveAct) menu.addAction(self.hgUnshelveContinueAct) menu.addAction(self.hgUnshelveAbortAct) menu.addSeparator() menu.addAction(self.hgShelveDeleteAct) menu.addAction(self.hgShelveCleanupAct) return menu def menuTitle(self): """ Public method to get the menu title. @return title of the menu (string) """ return self.tr("Shelve") def __reopenProject(self, shouldReopen, title): """ Private method to reopen the project if needed and wanted. @param shouldReopen flag indicating that the project should be reopened (boolean) @param title title of the message box (string) """ if shouldReopen: res = E5MessageBox.yesNo( None, title, self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def __hgShelve(self): """ Private slot used to shelve all current changes. """ shouldReopen = self.vcs.getExtensionObject("shelve")\ .hgShelve(self.project.getProjectPath()) self.__reopenProject(shouldReopen, self.tr("Shelve")) def __hgShelveBrowser(self): """ Private slot to show the shelve browser dialog. """ self.vcs.getExtensionObject("shelve")\ .hgShelveBrowser(self.project.getProjectPath()) def __hgUnshelve(self): """ Private slot used to restore a shelved change. """ shouldReopen = self.vcs.getExtensionObject("shelve")\ .hgUnshelve(self.project.getProjectPath()) self.__reopenProject(shouldReopen, self.tr("Unshelve")) def __hgUnshelveAbort(self): """ Private slot used to abort an ongoing restore operation. """ shouldReopen = self.vcs.getExtensionObject("shelve")\ .hgUnshelveAbort(self.project.getProjectPath()) self.__reopenProject(shouldReopen, self.tr("Abort Unshelve")) def __hgUnshelveContinue(self): """ Private slot used to continue an ongoing restore operation. """ shouldReopen = self.vcs.getExtensionObject("shelve")\ .hgUnshelveContinue(self.project.getProjectPath()) self.__reopenProject(shouldReopen, self.tr("Continue Unshelve")) def __hgDeleteShelves(self): """ Private slot to delete selected shelves. """ self.vcs.getExtensionObject("shelve").hgDeleteShelves( self.project.getProjectPath()) def __hgCleanupShelves(self): """ Private slot to delete all shelves. """ self.vcs.getExtensionObject("shelve").hgCleanupShelves( self.project.getProjectPath()) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelvesSelectionDialog.py0000644000175000017500000000312212451233372031175 0ustar piotrpiotr# -*- coding: utf-8 -*- """ Module implementing a dialog to select multiple shelve names. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_HgShelvesSelectionDialog import Ui_HgShelvesSelectionDialog class HgShelvesSelectionDialog(QDialog, Ui_HgShelvesSelectionDialog): """ Class implementing a dialog to select multiple shelve names. """ def __init__(self, message, shelveNames, parent=None): """ Constructor @param message message to be shown (string) @param shelveNames list of shelve names (list of string) @param parent reference to the parent widget (QWidget) """ super(HgShelvesSelectionDialog, self).__init__(parent) self.setupUi(self) self.message.setText(message) self.shelvesList.addItems(shelveNames) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) @pyqtSlot() def on_shelvesList_itemSelectionChanged(self): """ Private slot to enabled the OK button if items have been selected. """ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( len(self.shelvesList.selectedItems()) > 0) def getSelectedShelves(self): """ Public method to retrieve the selected shelve names. @return selected shelve names (list of string) """ names = [] for itm in self.shelvesList.selectedItems(): names.append(itm.text()) return names eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/__init__.py0000644000175000017500000000025112451233372026056 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Package implementing the shelve extension support interface. """ eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveBrowserDialog.ui0000644000175000017500000001570312474634043030512 0ustar piotrpiotr HgShelveBrowserDialog 0 0 650 574 Mercurial Shelve Browser 0 5 Qt::CustomContextMenu true QAbstractItemView::ExtendedSelection false false true Name Age Message 0 4 Statistics 0 2 true QAbstractItemView::NoSelection false false File Changes Lines added Lines deleted 0 1 Errors <b>Mercurial shelve errors</b><p>This shows possible error messages of the hg shelve command.</p> true false Input Qt::Horizontal QSizePolicy::Expanding 327 29 Press to send the input to the hg process &Send Alt+S Enter data to be sent to the hg process Select to switch the input field to password mode &Password Mode Alt+P QDialogButtonBox::Cancel|QDialogButtonBox::Close shelveList statisticsList errors input passwordCheckBox sendButton buttonBox eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveBrowserDialog.py0000644000175000017500000004154012451233372030516 0ustar piotrpiotr# -*- coding: utf-8 -*- """ Module implementing Mercurial shelve browser dialog. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, Qt, QPoint, QProcess, QTimer from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QTreeWidgetItem, \ QAbstractButton, QMenu, QHeaderView, QApplication, QLineEdit from E5Gui import E5MessageBox from .Ui_HgShelveBrowserDialog import Ui_HgShelveBrowserDialog class HgShelveBrowserDialog(QWidget, Ui_HgShelveBrowserDialog): """ Class implementing Mercurial shelve browser dialog. """ NameColumn = 0 AgeColumn = 1 MessageColumn = 2 def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(HgShelveBrowserDialog, self).__init__(parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.__position = QPoint() self.__fileStatisticsRole = Qt.UserRole self.__totalStatisticsRole = Qt.UserRole + 1 self.shelveList.header().setSortIndicator(0, Qt.AscendingOrder) self.refreshButton = self.buttonBox.addButton( self.tr("&Refresh"), QDialogButtonBox.ActionRole) self.refreshButton.setToolTip( self.tr("Press to refresh the list of shelves")) self.refreshButton.setEnabled(False) self.vcs = vcs self.__hgClient = vcs.getClient() self.__resetUI() if self.__hgClient: self.process = None else: self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.__contextMenu = QMenu() self.__unshelveAct = self.__contextMenu.addAction( self.tr("Restore selected shelve"), self.__unshelve) self.__deleteAct = self.__contextMenu.addAction( self.tr("Delete selected shelves"), self.__deleteShelves) self.__contextMenu.addAction( self.tr("Delete all shelves"), self.__cleanupShelves) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.__position = self.pos() e.accept() def show(self): """ Public slot to show the dialog. """ if not self.__position.isNull(): self.move(self.__position) self.__resetUI() super(HgShelveBrowserDialog, self).show() def __resetUI(self): """ Private method to reset the user interface. """ self.shelveList.clear() def __resizeColumnsShelves(self): """ Private method to resize the shelve list columns. """ self.shelveList.header().resizeSections(QHeaderView.ResizeToContents) self.shelveList.header().setStretchLastSection(True) def __generateShelveEntry(self, name, age, message, fileStatistics, totals): """ Private method to generate the shelve items. @param name name of the shelve (string) @param age age of the shelve (string) @param message shelve message (string) @param fileStatistics per file change statistics (tuple of four strings with file name, number of changes, number of added lines and number of deleted lines) @param totals overall statistics (tuple of three strings with number of changed files, number of added lines and number of deleted lines) """ itm = QTreeWidgetItem(self.shelveList, [name, age, message]) itm.setData(0, self.__fileStatisticsRole, fileStatistics) itm.setData(0, self.__totalStatisticsRole, totals) def __getShelveEntries(self): """ Private method to retrieve the list of shelves. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.buf = [] self.errors.clear() self.intercept = False args = self.vcs.initCommand("shelve") args.append("--list") args.append("--stat") if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) self.buf = out.splitlines(True) if err: self.__showError(err) self.__processBuffer() self.__finish() else: self.process.kill() self.process.setWorkingDirectory(self.repodir) self.inputGroup.setEnabled(True) self.inputGroup.show() self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) def start(self, projectDir): """ Public slot to start the hg shelve command. @param projectDir name of the project directory (string) """ self.errorGroup.hide() QApplication.processEvents() self.__projectDir = projectDir # find the root of the repo self.repodir = self.__projectDir while not os.path.isdir(os.path.join(self.repodir, self.vcs.adminDir)): self.repodir = os.path.dirname(self.repodir) if os.path.splitdrive(self.repodir)[1] == os.sep: return self.activateWindow() self.raise_() self.shelveList.clear() self.__started = True self.__getShelveEntries() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__processBuffer() self.__finish() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.refreshButton.setEnabled(True) def __processBuffer(self): """ Private method to process the buffered output of the hg shelve command. """ lastWasFileStats = False firstLine = True itemData = {} for line in self.buf: if firstLine: name, line = line.split("(", 1) age, message = line.split(")", 1) itemData["name"] = name.strip() itemData["age"] = age.strip() itemData["message"] = message.strip() itemData["files"] = [] firstLine = False elif '|' in line: # file stats: foo.py | 3 ++- file, changes = line.strip().split("|", 1) if changes.strip().endswith(("+", "-")): total, addDelete = changes.strip().split(None, 1) additions = str(addDelete.count("+")) deletions = str(addDelete.count("-")) else: total = changes.strip() additions = '0' deletions = '0' itemData["files"].append((file, total, additions, deletions)) lastWasFileStats = True elif lastWasFileStats: # summary line # 2 files changed, 15 insertions(+), 1 deletions(-) total, added, deleted = line.strip().split(",", 2) total = total.split()[0] added = added.split()[0] deleted = deleted.split()[0] itemData["summary"] = (total, added, deleted) self.__generateShelveEntry( itemData["name"], itemData["age"], itemData["message"], itemData["files"], itemData["summary"]) lastWasFileStats = False firstLine = True itemData = {} self.__resizeColumnsShelves() if self.__started: self.shelveList.setCurrentItem(self.shelveList.topLevelItem(0)) self.__started = False def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process and inserts it into a buffer. """ self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): line = str(self.process.readLine(), self.vcs.getEncoding(), 'replace') self.buf.append(line) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.cancelled = True if self.__hgClient: self.__hgClient.cancel() else: self.__finish() elif button == self.refreshButton: self.on_refreshButton_clicked() @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_shelveList_currentItemChanged(self, current, previous): """ Private slot called, when the current item of the shelve list changes. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the old current item (QTreeWidgetItem) """ self.statisticsList.clear() if current: for dataSet in current.data(0, self.__fileStatisticsRole): QTreeWidgetItem(self.statisticsList, list(dataSet)) self.statisticsList.header().resizeSections( QHeaderView.ResizeToContents) self.statisticsList.header().setStretchLastSection(True) totals = current.data(0, self.__totalStatisticsRole) self.filesLabel.setText( self.tr("%n file(s) changed", None, int(totals[0]))) self.insertionsLabel.setText( self.tr("%n line(s) inserted", None, int(totals[1]))) self.deletionsLabel.setText( self.tr("%n line(s) deleted", None, int(totals[2]))) else: self.filesLabel.setText("") self.insertionsLabel.setText("") self.deletionsLabel.setText("") @pyqtSlot(QPoint) def on_shelveList_customContextMenuRequested(self, pos): """ Private slot to show the context menu of the shelve list. @param pos position of the mouse pointer (QPoint) """ selectedItemsCount = len(self.shelveList.selectedItems()) self.__unshelveAct.setEnabled(selectedItemsCount == 1) self.__deleteAct.setEnabled(selectedItemsCount > 0) self.__contextMenu.popup(self.mapToGlobal(pos)) @pyqtSlot() def on_refreshButton_clicked(self): """ Private slot to refresh the list of shelves. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.inputGroup.setEnabled(True) self.inputGroup.show() self.refreshButton.setEnabled(False) self.start(self.__projectDir) def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the mercurial process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.errorGroup.show() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgShelveBrowserDialog, self).keyPressEvent(evt) def __unshelve(self): """ Private slot to restore the selected shelve of changes. """ itm = self.shelveList.selectedItems()[0] if itm is not None: name = itm.text(self.NameColumn) self.vcs.getExtensionObject("shelve")\ .hgUnshelve(self.__projectDir, shelveName=name) self.on_refreshButton_clicked() def __deleteShelves(self): """ Private slot to delete the selected shelves. """ shelveNames = [] for itm in self.shelveList.selectedItems(): shelveNames.append(itm.text(self.NameColumn)) if shelveNames: self.vcs.getExtensionObject("shelve")\ .hgDeleteShelves(self.__projectDir, shelveNames=shelveNames) self.on_refreshButton_clicked() def __cleanupShelves(self): """ Private slot to delete all shelves. """ self.vcs.getExtensionObject("shelve")\ .hgCleanupShelves(self.__projectDir) self.on_refreshButton_clicked() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveDataDialog.ui0000644000175000017500000000741112302372363027727 0ustar piotrpiotr HgShelveDataDialog 0 0 500 170 Shelve true Name: Enter a name for the shelve Date, Time: Enter the commit date and time for the shelve yyyy-MM-dd HH:mm true Qt::Horizontal 198 20 Message: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop Enter a message for the shelve Mark new/missing files as added/removed Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok nameEdit dateTimeEdit messageEdit addRemoveCheckBox buttonBox buttonBox accepted() HgShelveDataDialog accept() 248 254 157 274 buttonBox rejected() HgShelveDataDialog reject() 316 260 286 274 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/shelve.py0000644000175000017500000002433312451233372025614 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing the shelve extension interface. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import QProcess from PyQt5.QtWidgets import QDialog from E5Gui import E5MessageBox from ..HgExtension import HgExtension from ..HgDialog import HgDialog class Shelve(HgExtension): """ Class implementing the shelve extension interface. """ def __init__(self, vcs): """ Constructor @param vcs reference to the Mercurial vcs object """ super(Shelve, self).__init__(vcs) self.__unshelveKeep = False self.__shelveBrowserDialog = None def shutdown(self): """ Public method used to shutdown the shelve interface. """ if self.__shelveBrowserDialog is not None: self.__shelveBrowserDialog.close() def __hgGetShelveNamesList(self, repodir): """ Private method to get the list of shelved changes. @param repodir directory name of the repository (string) @return list of shelved changes (list of string) """ args = self.vcs.initCommand("shelve") args.append('--list') args.append('--quiet') client = self.vcs.getClient() output = "" if client: output = client.runcommand(args)[0] else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') shelveNamesList = [] for line in output.splitlines(): shelveNamesList.append(line.strip()) return shelveNamesList[:] def hgShelve(self, name): """ Public method to shelve current changes of files or directories. @param name directory or file name (string) or list of directory or file names (list of string) @return flag indicating that the project should be reread (boolean) """ if isinstance(name, list): dname = self.vcs.splitPathList(name)[0] else: dname = self.vcs.splitPath(name)[0] # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False res = False from .HgShelveDataDialog import HgShelveDataDialog dlg = HgShelveDataDialog() if dlg.exec_() == QDialog.Accepted: shelveName, dateTime, message, addRemove = dlg.getData() args = self.vcs.initCommand("shelve") if shelveName: args.append("--name") args.append(shelveName) if message: args.append("--message") args.append(message) if addRemove: args.append("--addRemove") if dateTime.isValid(): args.append("--date") args.append(dateTime.toString("yyyy-MM-dd hh:mm:ss")) args.append("-v") if isinstance(name, list): self.vcs.addArguments(args, name) else: args.append(name) dia = HgDialog(self.tr('Shelve current changes'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res def hgShelveBrowser(self, projectDir): """ Public method to show the shelve browser dialog. @param projectDir name of the project directory (string) """ if self.__shelveBrowserDialog is None: from .HgShelveBrowserDialog import HgShelveBrowserDialog self.__shelveBrowserDialog = HgShelveBrowserDialog( self.vcs) self.__shelveBrowserDialog.show() self.__shelveBrowserDialog.start(projectDir) def hgUnshelve(self, name, shelveName=""): """ Public method to restore shelved changes to the project directory. @param name name of the project directory (string) @keyparam shelveName name of the shelve to restore (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = name while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False res = False from .HgUnshelveDataDialog import HgUnshelveDataDialog dlg = HgUnshelveDataDialog(self.__hgGetShelveNamesList(repodir), shelveName=shelveName) if dlg.exec_() == QDialog.Accepted: shelveName, keep = dlg.getData() self.__unshelveKeep = keep # store for potential continue args = self.vcs.initCommand("unshelve") if keep: args.append("--keep") if shelveName: args.append(shelveName) dia = HgDialog(self.tr('Restore shelved changes'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res def hgUnshelveAbort(self, name): """ Public method to abort the ongoing restore operation. @param name name of the project directory (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = name while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False args = self.vcs.initCommand("unshelve") args.append("--abort") dia = HgDialog(self.tr('Abort restore operation'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res def hgUnshelveContinue(self, name): """ Public method to continue the ongoing restore operation. @param name name of the project directory (string) @return flag indicating that the project should be reread (boolean) """ # find the root of the repo repodir = name while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False args = self.vcs.initCommand("unshelve") if self.__unshelveKeep: args.append("--keep") args.append("--continue") dia = HgDialog(self.tr('Continue restore operation'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() res = dia.hasAddOrDelete() self.vcs.checkVCSStatus() return res def hgDeleteShelves(self, name, shelveNames=None): """ Public method to delete named shelves. @param name name of the project directory (string) @param shelveNames name of shelves to delete (list of string) """ # find the root of the repo repodir = name while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if not shelveNames: from .HgShelvesSelectionDialog import HgShelvesSelectionDialog dlg = HgShelvesSelectionDialog( self.tr("Select the shelves to be deleted:"), self.__hgGetShelveNamesList(repodir)) if dlg.exec_() == QDialog.Accepted: shelveNames = dlg.getSelectedShelves() else: return from UI.DeleteFilesConfirmationDialog import \ DeleteFilesConfirmationDialog dlg = DeleteFilesConfirmationDialog( None, self.tr("Delete shelves"), self.tr("Do you really want to delete these shelves?"), shelveNames) if dlg.exec_() == QDialog.Accepted: args = self.vcs.initCommand("shelve") args.append("--delete") args.extend(shelveNames) dia = HgDialog(self.tr('Delete shelves'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() def hgCleanupShelves(self, name): """ Public method to delete all shelves. @param name name of the project directory (string) """ # find the root of the repo repodir = name while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return res = E5MessageBox.yesNo( None, self.tr("Delete all shelves"), self.tr("""Do you really want to delete all shelved changes?""")) if res: args = self.vcs.initCommand("shelve") args.append("--cleanup") dia = HgDialog(self.tr('Delete all shelves'), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveDataDialog.py0000644000175000017500000000311712451233372027742 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter the data for a shelve operation. """ from __future__ import unicode_literals from PyQt5.QtCore import QDateTime from PyQt5.QtWidgets import QDialog from .Ui_HgShelveDataDialog import Ui_HgShelveDataDialog class HgShelveDataDialog(QDialog, Ui_HgShelveDataDialog): """ Class implementing a dialog to enter the data for a shelve operation. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(HgShelveDataDialog, self).__init__(parent) self.setupUi(self) self.__initialDateTime = QDateTime.currentDateTime() self.dateTimeEdit.setDateTime(self.__initialDateTime) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public method to get the user data. @return tuple containing the name (string), date (QDateTime), message (string) and a flag indicating to add/remove new/missing files (boolean) """ if self.dateTimeEdit.dateTime() != self.__initialDateTime: dateTime = self.dateTimeEdit.dateTime() else: dateTime = QDateTime() return ( self.nameEdit.text().replace(" ", "_"), dateTime, self.messageEdit.text(), self.addRemoveCheckBox.isChecked(), ) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgStatusDialog.py0000644000175000017500000007500112451233372024063 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the output of the hg status command process. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QMenu, QHeaderView, \ QTreeWidgetItem, QLineEdit from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .Ui_HgStatusDialog import Ui_HgStatusDialog import Preferences class HgStatusDialog(QWidget, Ui_HgStatusDialog): """ Class implementing a dialog to show the output of the hg status command process. """ def __init__(self, vcs, mq=False, parent=None): """ Constructor @param vcs reference to the vcs object @param mq flag indicating to show a queue repo status (boolean) @param parent parent widget (QWidget) """ super(HgStatusDialog, self).__init__(parent) self.setupUi(self) self.__toBeCommittedColumn = 0 self.__statusColumn = 1 self.__pathColumn = 2 self.__lastColumn = self.statusList.columnCount() self.refreshButton = self.buttonBox.addButton( self.tr("Refresh"), QDialogButtonBox.ActionRole) self.refreshButton.setToolTip( self.tr("Press to refresh the status display")) self.refreshButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.diff = None self.process = None self.vcs = vcs self.vcs.committed.connect(self.__committed) self.__hgClient = self.vcs.getClient() self.__mq = mq self.statusList.headerItem().setText(self.__lastColumn, "") self.statusList.header().setSortIndicator( self.__pathColumn, Qt.AscendingOrder) if mq: self.buttonsLine.setVisible(False) self.addButton.setVisible(False) self.diffButton.setVisible(False) self.sbsDiffButton.setVisible(False) self.revertButton.setVisible(False) self.forgetButton.setVisible(False) self.restoreButton.setVisible(False) self.menuactions = [] self.lfActions = [] self.menu = QMenu() if not mq: self.__commitAct = self.menu.addAction( self.tr("Commit changes to repository..."), self.__commit) self.menuactions.append(self.__commitAct) self.menuactions.append(self.menu.addAction( self.tr("Select all for commit"), self.__commitSelectAll)) self.menuactions.append(self.menu.addAction( self.tr("Deselect all from commit"), self.__commitDeselectAll)) self.menu.addSeparator() self.__addAct = self.menu.addAction( self.tr("Add to repository"), self.__add) self.menuactions.append(self.__addAct) if self.vcs.version >= (2, 0): self.lfActions.append(self.menu.addAction( self.tr("Add as Large File"), lambda: self.__lfAdd("large"))) self.lfActions.append(self.menu.addAction( self.tr("Add as Normal File"), lambda: self.__lfAdd("normal"))) self.__diffAct = self.menu.addAction( self.tr("Show differences"), self.__diff) self.menuactions.append(self.__diffAct) self.__sbsDiffAct = self.menu.addAction( self.tr("Show differences side-by-side"), self.__sbsDiff) self.menuactions.append(self.__sbsDiffAct) self.__revertAct = self.menu.addAction( self.tr("Revert changes"), self.__revert) self.menuactions.append(self.__revertAct) self.__forgetAct = self.menu.addAction( self.tr("Forget missing"), self.__forget) self.menuactions.append(self.__forgetAct) self.__restoreAct = self.menu.addAction( self.tr("Restore missing"), self.__restoreMissing) self.menuactions.append(self.__restoreAct) self.menu.addSeparator() self.menuactions.append(self.menu.addAction( self.tr("Adjust column sizes"), self.__resizeColumns)) for act in self.menuactions: act.setEnabled(False) for act in self.lfActions: act.setEnabled(False) self.statusList.setContextMenuPolicy(Qt.CustomContextMenu) self.statusList.customContextMenuRequested.connect( self.__showContextMenu) if not mq and self.vcs.version >= (2, 0): self.__lfAddActions = [] self.__addButtonMenu = QMenu() self.__addButtonMenu.addAction(self.tr("Add"), self.__add) self.__lfAddActions.append( self.__addButtonMenu.addAction(self.tr("Add as Large File"), lambda: self.__lfAdd("large"))) self.__lfAddActions.append( self.__addButtonMenu.addAction(self.tr("Add as Normal File"), lambda: self.__lfAdd("normal"))) self.addButton.setMenu(self.__addButtonMenu) self.__addButtonMenu.aboutToShow.connect(self.__showAddMenu) self.modifiedIndicators = [ self.tr('added'), self.tr('modified'), self.tr('removed'), ] self.unversionedIndicators = [ self.tr('not tracked'), ] self.missingIndicators = [ self.tr('missing') ] self.status = { 'A': self.tr('added'), 'C': self.tr('normal'), 'I': self.tr('ignored'), 'M': self.tr('modified'), 'R': self.tr('removed'), '?': self.tr('not tracked'), '!': self.tr('missing'), } def __resort(self): """ Private method to resort the tree. """ self.statusList.sortItems( self.statusList.sortColumn(), self.statusList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.statusList.header().resizeSections(QHeaderView.ResizeToContents) self.statusList.header().setStretchLastSection(True) def __generateItem(self, status, path): """ Private method to generate a status item in the status list. @param status status indicator (string) @param path path of the file or directory (string) """ statusText = self.status[status] itm = QTreeWidgetItem(self.statusList, [ "", statusText, path, ]) itm.setTextAlignment(1, Qt.AlignHCenter) itm.setTextAlignment(2, Qt.AlignLeft) if status in "AMR": itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable) if statusText not in self.__statusFilters: self.__statusFilters.append(statusText) def closeEvent(self, e): """ Protected slot implementing a close event handler. @param e close event (QCloseEvent) """ if self.__hgClient: if self.__hgClient.isExecuting(): self.__hgClient.cancel() else: if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) e.accept() def start(self, fn): """ Public slot to start the hg status command. @param fn filename(s)/directoryname(s) to show the status of (string or list of strings) """ self.errorGroup.hide() self.intercept = False self.args = fn for act in self.menuactions: act.setEnabled(False) for act in self.lfActions: act.setEnabled(False) self.addButton.setEnabled(False) self.commitButton.setEnabled(False) self.diffButton.setEnabled(False) self.sbsDiffButton.setEnabled(False) self.revertButton.setEnabled(False) self.forgetButton.setEnabled(False) self.restoreButton.setEnabled(False) self.statusFilterCombo.clear() self.__statusFilters = [] if self.__mq: self.setWindowTitle( self.tr("Mercurial Queue Repository Status")) else: self.setWindowTitle(self.tr('Mercurial Status')) args = self.vcs.initCommand("status") if self.__mq: args.append('--mq') if isinstance(fn, list): self.dname, fnames = self.vcs.splitPathList(fn) else: self.dname, fname = self.vcs.splitPath(fn) else: if self.vcs.hasSubrepositories(): args.append("--subrepos") if isinstance(fn, list): self.dname, fnames = self.vcs.splitPathList(fn) self.vcs.addArguments(args, fn) else: self.dname, fname = self.vcs.splitPath(fn) args.append(fn) # find the root of the repo repodir = self.dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: if self.process: self.process.kill() else: self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.refreshButton.setEnabled(True) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.__statusFilters.sort() self.__statusFilters.insert(0, "<{0}>".format(self.tr("all"))) self.statusFilterCombo.addItems(self.__statusFilters) for act in self.menuactions: act.setEnabled(True) self.process = None self.__resort() self.__resizeColumns() self.__updateButtons() self.__updateCommitButton() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): if self.__hgClient: self.__hgClient.cancel() else: self.__finish() elif button == self.refreshButton: self.on_refreshButton_clicked() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.process is not None: self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): line = str(self.process.readLine(), self.vcs.getEncoding(), 'replace') self.__processOutputLine(line) def __processOutputLine(self, line): """ Private method to process the lines of output. @param line output line to be processed (string) """ if line[0] in "ACIMR?!" and line[1] == " ": status, path = line.strip().split(" ", 1) self.__generateItem(status, path) def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: s = str(self.process.readAllStandardError(), self.vcs.getEncoding(), 'replace') self.__showError(s) def __showError(self, out): """ Private slot to show some error. @param out error to be shown (string) """ self.errorGroup.show() self.errors.insertPlainText(out) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return super(HgStatusDialog, self).keyPressEvent(evt) @pyqtSlot() def on_refreshButton_clicked(self): """ Private slot to refresh the status display. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.inputGroup.setEnabled(True) self.inputGroup.show() self.refreshButton.setEnabled(False) self.statusList.clear() self.start(self.args) def __updateButtons(self): """ Private method to update the VCS buttons status. """ modified = len(self.__getModifiedItems()) unversioned = len(self.__getUnversionedItems()) missing = len(self.__getMissingItems()) self.addButton.setEnabled(unversioned) self.diffButton.setEnabled(modified) self.sbsDiffButton.setEnabled(modified == 1) self.revertButton.setEnabled(modified) self.forgetButton.setEnabled(missing) self.restoreButton.setEnabled(missing) def __updateCommitButton(self): """ Private method to update the Commit button status. """ commitable = len(self.__getCommitableItems()) self.commitButton.setEnabled(commitable) @pyqtSlot(str) def on_statusFilterCombo_activated(self, txt): """ Private slot to react to the selection of a status filter. @param txt selected status filter (string) """ if txt == "<{0}>".format(self.tr("all")): for topIndex in range(self.statusList.topLevelItemCount()): topItem = self.statusList.topLevelItem(topIndex) topItem.setHidden(False) else: for topIndex in range(self.statusList.topLevelItemCount()): topItem = self.statusList.topLevelItem(topIndex) topItem.setHidden(topItem.text(self.__statusColumn) != txt) @pyqtSlot(QTreeWidgetItem, int) def on_statusList_itemChanged(self, item, column): """ Private slot to act upon item changes. @param item reference to the changed item (QTreeWidgetItem) @param column index of column that changed (integer) """ if column == self.__toBeCommittedColumn: self.__updateCommitButton() @pyqtSlot() def on_statusList_itemSelectionChanged(self): """ Private slot to act upon changes of selected items. """ self.__updateButtons() @pyqtSlot() def on_commitButton_clicked(self): """ Private slot to handle the press of the Commit button. """ self.__commit() @pyqtSlot() def on_addButton_clicked(self): """ Private slot to handle the press of the Add button. """ self.__add() @pyqtSlot() def on_diffButton_clicked(self): """ Private slot to handle the press of the Differences button. """ self.__diff() @pyqtSlot() def on_sbsDiffButton_clicked(self): """ Private slot to handle the press of the Side-by-Side Diff button. """ self.__sbsDiff() @pyqtSlot() def on_revertButton_clicked(self): """ Private slot to handle the press of the Revert button. """ self.__revert() @pyqtSlot() def on_forgetButton_clicked(self): """ Private slot to handle the press of the Forget button. """ self.__forget() @pyqtSlot() def on_restoreButton_clicked(self): """ Private slot to handle the press of the Restore button. """ self.__restoreMissing() ########################################################################### ## Context menu handling methods ########################################################################### def __showContextMenu(self, coord): """ Private slot to show the context menu of the status list. @param coord the position of the mouse pointer (QPoint) """ modified = len(self.__getModifiedItems()) unversioned = len(self.__getUnversionedItems()) missing = len(self.__getMissingItems()) commitable = len(self.__getCommitableItems()) self.__addAct.setEnabled(unversioned) self.__diffAct.setEnabled(modified) self.__sbsDiffAct.setEnabled(modified == 1) self.__revertAct.setEnabled(modified) self.__forgetAct.setEnabled(missing) self.__restoreAct.setEnabled(missing) self.__commitAct.setEnabled(commitable) if self.vcs.isExtensionActive("largefiles"): enable = len(self.__getUnversionedItems()) > 0 else: enable = False for act in self.lfActions: act.setEnabled(enable) self.menu.popup(self.statusList.mapToGlobal(coord)) def __showAddMenu(self): """ Private slot to prepare the Add button menu before it is shown. """ enable = self.vcs.isExtensionActive("largefiles") for act in self.__lfAddActions: act.setEnabled(enable) def __commit(self): """ Private slot to handle the Commit context menu entry. """ if self.__mq: self.vcs.vcsCommit(self.dname, "", mq=True) else: names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getCommitableItems()] if not names: E5MessageBox.information( self, self.tr("Commit"), self.tr("""There are no entries selected to be""" """ committed.""")) return if Preferences.getVCS("AutoSaveFiles"): vm = e5App().getObject("ViewManager") for name in names: vm.saveEditor(name) self.vcs.vcsCommit(names, '') def __committed(self): """ Private slot called after the commit has finished. """ if self.isVisible(): self.on_refreshButton_clicked() self.vcs.checkVCSStatus() def __commitSelectAll(self): """ Private slot to select all entries for commit. """ self.__commitSelect(True) def __commitDeselectAll(self): """ Private slot to deselect all entries from commit. """ self.__commitSelect(False) def __add(self): """ Private slot to handle the Add context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getUnversionedItems()] if not names: E5MessageBox.information( self, self.tr("Add"), self.tr("""There are no unversioned entries""" """ available/selected.""")) return self.vcs.vcsAdd(names) self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus() def __lfAdd(self, mode): """ Private slot to add a file to the repository. @param mode add mode (string one of 'normal' or 'large') """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getUnversionedItems()] if not names: E5MessageBox.information( self, self.tr("Add"), self.tr("""There are no unversioned entries""" """ available/selected.""")) return self.vcs.getExtensionObject("largefiles").hgAdd( names, mode) self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus() def __forget(self): """ Private slot to handle the Remove context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getMissingItems()] if not names: E5MessageBox.information( self, self.tr("Remove"), self.tr("""There are no missing entries""" """ available/selected.""")) return self.vcs.hgForget(names) self.on_refreshButton_clicked() def __revert(self): """ Private slot to handle the Revert context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Revert"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return self.vcs.hgRevert(names) self.raise_() self.activateWindow() self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus() def __restoreMissing(self): """ Private slot to handle the Restore Missing context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getMissingItems()] if not names: E5MessageBox.information( self, self.tr("Revert"), self.tr("""There are no missing entries""" """ available/selected.""")) return self.vcs.hgRevert(names) self.on_refreshButton_clicked() self.vcs.checkVCSStatus() def __diff(self): """ Private slot to handle the Diff context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Differences"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return if self.diff is None: from .HgDiffDialog import HgDiffDialog self.diff = HgDiffDialog(self.vcs) self.diff.show() self.diff.start(names) def __sbsDiff(self): """ Private slot to handle the Diff context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Side-by-Side Diff"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return elif len(names) > 1: E5MessageBox.information( self, self.tr("Side-by-Side Diff"), self.tr("""Only one file with uncommitted changes""" """ must be selected.""")) return self.vcs.hgSbsDiff(names[0]) def __getCommitableItems(self): """ Private method to retrieve all entries the user wants to commit. @return list of all items, the user has checked """ commitableItems = [] for index in range(self.statusList.topLevelItemCount()): itm = self.statusList.topLevelItem(index) if itm.checkState(self.__toBeCommittedColumn) == Qt.Checked: commitableItems.append(itm) return commitableItems def __getModifiedItems(self): """ Private method to retrieve all entries, that have a modified status. @return list of all items with a modified status """ modifiedItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.modifiedIndicators: modifiedItems.append(itm) return modifiedItems def __getUnversionedItems(self): """ Private method to retrieve all entries, that have an unversioned status. @return list of all items with an unversioned status """ unversionedItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.unversionedIndicators: unversionedItems.append(itm) return unversionedItems def __getMissingItems(self): """ Private method to retrieve all entries, that have a missing status. @return list of all items with a missing status """ missingItems = [] for itm in self.statusList.selectedItems(): if itm.text(self.__statusColumn) in self.missingIndicators: missingItems.append(itm) return missingItems def __commitSelect(self, selected): """ Private slot to select or deselect all entries. @param selected commit selection state to be set (boolean) """ for index in range(self.statusList.topLevelItemCount()): itm = self.statusList.topLevelItem(index) if itm.flags() & Qt.ItemIsUserCheckable: if selected: itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setCheckState(self.__toBeCommittedColumn, Qt.Unchecked) eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.ui0000644000175000017500000002601112312353424024147 0ustar piotrpiotr HgBackoutDialog 0 0 372 515 Mercurial Revision true Revision Select to specify a revision by number Number false Enter a revision number Qt::AlignRight 999999999 Qt::Horizontal 158 20 Select to specify a revision by changeset id Id: false Enter a changeset id Select to specify a revision by a tag Tag: false 0 0 Enter a tag name true Select to specify a revision by a branch Branch: false 0 0 Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select to not specify a specific revision Parent true Commit data Commit message: Enter the commit message or leave empty to use the default one true Commit Date: Enter optional date for the commit yyyy-MM-dd HH:mm false Commit User: Enter optional user for the commit Select to merge with parent of the project directory Merge with current parent Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok numberButton numberSpinBox idButton idEdit tagButton tagCombo branchButton branchCombo bookmarkButton bookmarkCombo noneButton messageEdit dateEdit userEdit mergeCheckBox buttonBox buttonBox accepted() HgBackoutDialog accept() 261 450 157 224 buttonBox rejected() HgBackoutDialog reject() 329 450 286 224 numberButton toggled(bool) numberSpinBox setEnabled(bool) 48 42 113 43 idButton toggled(bool) idEdit setEnabled(bool) 38 76 125 75 tagButton toggled(bool) tagCombo setEnabled(bool) 52 104 124 99 branchButton toggled(bool) branchCombo setEnabled(bool) 71 127 123 130 bookmarkButton toggled(bool) bookmarkCombo setEnabled(bool) 57 147 116 147 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.ui0000644000175000017500000002127712313335203023775 0ustar piotrpiotr HgBundleDialog 0 0 450 452 Mercurial Bundle true Revision Select to specify multiple revisions Revisions: false Enter revisions by number, id, range or revset expression one per line true QPlainTextEdit::NoWrap Select to specify a revision by a tag Tag: false Enter a tag name true Select to specify a revision by a branch Branch: false Enter a branch name true Select to specify a revision by a bookmark Bookmark: false 0 0 Enter a bookmark name true Select to not specify a specific revision No revision selected true Base Revisions: Enter changesets by number, id, range or revset expression one per line true QPlainTextEdit::NoWrap Compression: 0 0 Select the compression type (empty for default) Select to bundle all changesets Bundle all changesets Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok multipleButton multipleEdit tagButton tagCombo branchButton branchCombo bookmarkButton bookmarkCombo noneButton baseRevisionsEdit compressionCombo allCheckBox buttonBox buttonBox accepted() HgBundleDialog accept() 270 442 157 229 buttonBox rejected() HgBundleDialog reject() 338 442 286 229 tagButton toggled(bool) tagCombo setEnabled(bool) 72 154 234 154 branchButton toggled(bool) branchCombo setEnabled(bool) 91 181 233 181 bookmarkButton toggled(bool) bookmarkCombo setEnabled(bool) 65 208 235 208 multipleButton toggled(bool) multipleEdit setEnabled(bool) 60 78 141 83 eric-6.0.8/eric/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.ui0000644000175000017500000000547312060166053024020 0ustar piotrpiotr HgCommitDialog 0 0 450 350 Mercurial Commit Message Enter the log message. <b>Log Message</b> <p>Enter the log message for the commit action.</p> true false Recent commit messages Select a recent commit message to use Select to amend the last commit (leave message empty to keep it) Amend the last commit Select to commit sub-repositories as well Commit sub-repositories Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok qPixmapFromMimeSource logEdit recentComboBox amendCheckBox subrepoCheckBox buttonBox eric-6.0.8/eric/Plugins/PluginEricdoc.py0000644000175000017500000001667012451233372017203 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Ericdoc plugin. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, QCoreApplication from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from E5Gui.E5Action import E5Action import Utilities from eric6config import getConfig # Start-Of-Header name = "Ericdoc Plugin" author = "Detlev Offenbach " autoactivate = True deactivateable = True version = "6.0.0" className = "EricdocPlugin" packageName = "__core__" shortDescription = "Show the Ericdoc dialogs." longDescription = """This plugin implements the Ericdoc dialogs.""" \ """ Ericdoc is used to generate a source code documentation""" \ """ for Python and Ruby projects.""" pyqtApi = 2 python2Compatible = True # End-Of-Header error = "" def exeDisplayDataList(): """ Public method to support the display of some executable info. @return dictionary containing the data to query the presence of the executable """ dataList = [] # 1. eric6_doc exe = 'eric6_doc' if Utilities.isWindowsPlatform(): exe = os.path.join(getConfig("bindir"), exe + '.bat') dataList.append({ "programEntry": True, "header": QCoreApplication.translate( "EricdocPlugin", "Eric6 Documentation Generator"), "exe": exe, "versionCommand": '--version', "versionStartsWith": 'eric6_', "versionPosition": -3, "version": "", "versionCleanup": None, }) # 2. Qt Help Generator exe = os.path.join(Utilities.getQtBinariesPath(), 'qhelpgenerator') if Utilities.isWindowsPlatform(): exe += '.exe' dataList.append({ "programEntry": True, "header": QCoreApplication.translate( "EricdocPlugin", "Qt Help Tools"), "exe": exe, "versionCommand": '-v', "versionStartsWith": 'Qt', "versionPosition": -1, "version": "", "versionCleanup": (0, -1), }) # 3. Qt Collection Generator exe = os.path.join(Utilities.getQtBinariesPath(), 'qcollectiongenerator') if Utilities.isWindowsPlatform(): exe += '.exe' dataList.append({ "programEntry": True, "header": QCoreApplication.translate( "EricdocPlugin", "Qt Help Tools"), "exe": exe, "versionCommand": '-v', "versionStartsWith": 'Qt', "versionPosition": -1, "version": "", "versionCleanup": (0, -1), }) return dataList class EricdocPlugin(QObject): """ Class implementing the Ericdoc plugin. """ def __init__(self, ui): """ Constructor @param ui reference to the user interface object (UI.UserInterface) """ super(EricdocPlugin, self).__init__(ui) self.__ui = ui self.__initialize() def __initialize(self): """ Private slot to (re)initialize the plugin. """ self.__projectAct = None def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ menu = e5App().getObject("Project").getMenu("Apidoc") if menu: self.__projectAct = \ E5Action( self.tr('Generate documentation (eric6_doc)'), self.tr('Generate &documentation (eric6_doc)'), 0, 0, self, 'doc_eric6_doc') self.__projectAct.setStatusTip( self.tr('Generate API documentation using eric6_doc')) self.__projectAct.setWhatsThis(self.tr( """Generate documentation""" """

Generate API documentation using eric6_doc.

""" )) self.__projectAct.triggered.connect(self.__doEricdoc) e5App().getObject("Project").addE5Actions([self.__projectAct]) menu.addAction(self.__projectAct) e5App().getObject("Project").showMenu.connect(self.__projectShowMenu) return None, True def deactivate(self): """ Public method to deactivate this plugin. """ e5App().getObject("Project").showMenu.disconnect( self.__projectShowMenu) menu = e5App().getObject("Project").getMenu("Apidoc") if menu: menu.removeAction(self.__projectAct) e5App().getObject("Project").removeE5Actions([self.__projectAct]) self.__initialize() def __projectShowMenu(self, menuName, menu): """ Private slot called, when the the project menu or a submenu is about to be shown. @param menuName name of the menu to be shown (string) @param menu reference to the menu (QMenu) """ if menuName == "Apidoc": if self.__projectAct is not None: self.__projectAct.setEnabled( e5App().getObject("Project").getProjectLanguage() in ["Python", "Python2", "Python3", "Ruby"]) def __doEricdoc(self): """ Private slot to perform the eric6_doc api documentation generation. """ from DocumentationPlugins.Ericdoc.EricdocConfigDialog import \ EricdocConfigDialog eolTranslation = { '\r': 'cr', '\n': 'lf', '\r\n': 'crlf', } project = e5App().getObject("Project") parms = project.getData('DOCUMENTATIONPARMS', "ERIC4DOC") dlg = EricdocConfigDialog(project, parms) if dlg.exec_() == QDialog.Accepted: args, parms = dlg.generateParameters() project.setData('DOCUMENTATIONPARMS', "ERIC4DOC", parms) # add parameter for the eol setting if not project.useSystemEol(): args.append( "--eol={0}".format(eolTranslation[project.getEolString()])) # now do the call from DocumentationPlugins.Ericdoc.EricdocExecDialog import \ EricdocExecDialog dia = EricdocExecDialog("Ericdoc") res = dia.start(args, project.ppath) if res: dia.exec_() outdir = Utilities.toNativeSeparators(parms['outputDirectory']) if outdir == '': outdir = 'doc' # that is eric6_docs default output dir # add it to the project data, if it isn't in already outdir = project.getRelativePath(outdir) if outdir not in project.pdata['OTHERS']: project.pdata['OTHERS'].append(outdir) project.setDirty(True) project.othersAdded(outdir) if parms['qtHelpEnabled']: outdir = Utilities.toNativeSeparators( parms['qtHelpOutputDirectory']) if outdir == '': outdir = 'help' # that is eric6_docs default QtHelp output dir # add it to the project data, if it isn't in already outdir = project.getRelativePath(outdir) if outdir not in project.pdata['OTHERS']: project.pdata['OTHERS'].append(outdir) project.setDirty(True) project.othersAdded(outdir) eric-6.0.8/eric/Plugins/WizardPlugins/0000755000175000017500000000000012451233406016670 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/QRegExpWizard/0000755000175000017500000000000012557365404021377 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardDialog.py0000644000175000017500000006521112451233372025561 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing the QRegExp wizard dialog. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QFileInfo, QRegExp, Qt, pyqtSlot, qVersion from PyQt5.QtGui import QClipboard, QTextCursor from PyQt5.QtWidgets import QWidget, QDialog, QApplication, QDialogButtonBox, \ QVBoxLayout, QTableWidgetItem from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5MainWindow import E5MainWindow from .Ui_QRegExpWizardDialog import Ui_QRegExpWizardWidget import UI.PixmapCache import Utilities import Preferences class QRegExpWizardWidget(QWidget, Ui_QRegExpWizardWidget): """ Class implementing the QRegExp wizard dialog. """ def __init__(self, parent=None, fromEric=True): """ Constructor @param parent parent widget (QWidget) @param fromEric flag indicating a call from within eric6 """ super(QRegExpWizardWidget, self).__init__(parent) self.setupUi(self) # initialize icons of the tool buttons # regexp tool buttons self.charButton.setIcon(UI.PixmapCache.getIcon("characters.png")) self.anycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) self.repeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) self.nonGroupButton.setIcon(UI.PixmapCache.getIcon("nongroup.png")) self.groupButton.setIcon(UI.PixmapCache.getIcon("group.png")) self.altnButton.setIcon(UI.PixmapCache.getIcon("altn.png")) self.beglineButton.setIcon(UI.PixmapCache.getIcon("begline.png")) self.endlineButton.setIcon(UI.PixmapCache.getIcon("endline.png")) self.wordboundButton.setIcon( UI.PixmapCache.getIcon("wordboundary.png")) self.nonwordboundButton.setIcon( UI.PixmapCache.getIcon("nonwordboundary.png")) self.poslookaheadButton.setIcon( UI.PixmapCache.getIcon("poslookahead.png")) self.neglookaheadButton.setIcon( UI.PixmapCache.getIcon("neglookahead.png")) self.undoButton.setIcon(UI.PixmapCache.getIcon("editUndo.png")) self.redoButton.setIcon(UI.PixmapCache.getIcon("editRedo.png")) # wildcard tool buttons self.wildcardCharButton.setIcon( UI.PixmapCache.getIcon("characters.png")) self.wildcardAnycharButton.setIcon( UI.PixmapCache.getIcon("anychar.png")) self.wildcardRepeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) # W3C tool buttons self.w3cCharButton.setIcon(UI.PixmapCache.getIcon("characters.png")) self.w3cAnycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) self.w3cRepeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) self.w3cGroupButton.setIcon(UI.PixmapCache.getIcon("group.png")) self.w3cAltnButton.setIcon(UI.PixmapCache.getIcon("altn.png")) # initialize the syntax pattern combo self.syntaxCombo.addItem("RegExp", QRegExp.RegExp) self.syntaxCombo.addItem("RegExp2", QRegExp.RegExp2) self.syntaxCombo.addItem("Wildcard", QRegExp.Wildcard) self.syntaxCombo.addItem("Unix Wildcard", QRegExp.WildcardUnix) self.syntaxCombo.addItem("Fixed String", QRegExp.FixedString) self.syntaxCombo.addItem("W3C XML Schema 1.1", QRegExp.W3CXmlSchema11) if qVersion() >= "5.0.0": self.syntaxCombo.setCurrentIndex(1) self.saveButton = self.buttonBox.addButton( self.tr("Save"), QDialogButtonBox.ActionRole) self.saveButton.setToolTip( self.tr("Save the regular expression to a file")) self.loadButton = self.buttonBox.addButton( self.tr("Load"), QDialogButtonBox.ActionRole) self.loadButton.setToolTip( self.tr("Load a regular expression from a file")) self.validateButton = self.buttonBox.addButton( self.tr("Validate"), QDialogButtonBox.ActionRole) self.validateButton.setToolTip( self.tr("Validate the regular expression")) self.executeButton = self.buttonBox.addButton( self.tr("Execute"), QDialogButtonBox.ActionRole) self.executeButton.setToolTip( self.tr("Execute the regular expression")) self.nextButton = self.buttonBox.addButton( self.tr("Next match"), QDialogButtonBox.ActionRole) self.nextButton.setToolTip( self.tr("Show the next match of the regular expression")) self.nextButton.setEnabled(False) if fromEric: self.buttonBox.setStandardButtons( QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.copyButton = None else: self.copyButton = self.buttonBox.addButton( self.tr("Copy"), QDialogButtonBox.ActionRole) self.copyButton.setToolTip( self.tr("Copy the regular expression to the clipboard")) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.variableLabel.hide() self.variableLineEdit.hide() self.variableLine.hide() self.regexpLineEdit.setFocus() @pyqtSlot(int) def on_syntaxCombo_currentIndexChanged(self, index): """ Private slot handling the selection of a pattern syntax. @param index index of the selected entry (integer) """ syntax = self.syntaxCombo.itemData(index) self.regexpButtonsFrame.setVisible(syntax in [ QRegExp.RegExp, QRegExp.RegExp2]) self.regexpButtonsFrame.setEnabled(syntax in [ QRegExp.RegExp, QRegExp.RegExp2]) self.wildcardButtonsFrame.setVisible(syntax in [ QRegExp.Wildcard, QRegExp.WildcardUnix]) self.wildcardButtonsFrame.setEnabled(syntax in [ QRegExp.Wildcard, QRegExp.WildcardUnix]) self.w3cButtonsFrame.setVisible(syntax in [QRegExp.W3CXmlSchema11]) self.w3cButtonsFrame.setEnabled(syntax in [QRegExp.W3CXmlSchema11]) def __insertString(self, s, steps=0): """ Private method to insert a string into line edit and move cursor. @param s string to be inserted into the regexp line edit (string) @param steps number of characters to move the cursor (integer). Negative steps moves cursor back, positives forward. """ self.regexpLineEdit.insert(s) self.regexpLineEdit.cursorForward(False, steps) @pyqtSlot() def on_anycharButton_clicked(self): """ Private slot to handle the any character toolbutton. """ self.__insertString(".") @pyqtSlot() def on_nonGroupButton_clicked(self): """ Private slot to handle the non group toolbutton. """ self.__insertString("(?:)", -1) @pyqtSlot() def on_groupButton_clicked(self): """ Private slot to handle the group toolbutton. """ self.__insertString("()", -1) @pyqtSlot() def on_altnButton_clicked(self): """ Private slot to handle the alternatives toolbutton. """ self.__insertString("(|)", -2) @pyqtSlot() def on_beglineButton_clicked(self): """ Private slot to handle the begin line toolbutton. """ self.__insertString("^") @pyqtSlot() def on_endlineButton_clicked(self): """ Private slot to handle the end line toolbutton. """ self.__insertString("$") @pyqtSlot() def on_wordboundButton_clicked(self): """ Private slot to handle the word boundary toolbutton. """ self.__insertString("\\b") @pyqtSlot() def on_nonwordboundButton_clicked(self): """ Private slot to handle the non word boundary toolbutton. """ self.__insertString("\\B") @pyqtSlot() def on_poslookaheadButton_clicked(self): """ Private slot to handle the positive lookahead toolbutton. """ self.__insertString("(?=)", -1) @pyqtSlot() def on_neglookaheadButton_clicked(self): """ Private slot to handle the negative lookahead toolbutton. """ self.__insertString("(?!)", -1) @pyqtSlot() def on_repeatButton_clicked(self): """ Private slot to handle the repeat toolbutton. """ from .QRegExpWizardRepeatDialog import QRegExpWizardRepeatDialog dlg = QRegExpWizardRepeatDialog(self) if dlg.exec_() == QDialog.Accepted: self.__insertString(dlg.getRepeat()) @pyqtSlot() def on_charButton_clicked(self): """ Private slot to handle the characters toolbutton. """ from .QRegExpWizardCharactersDialog import \ QRegExpWizardCharactersDialog dlg = QRegExpWizardCharactersDialog( mode=QRegExpWizardCharactersDialog.RegExpMode, parent=self) if dlg.exec_() == QDialog.Accepted: self.__insertString(dlg.getCharacters()) @pyqtSlot() def on_wildcardCharButton_clicked(self): """ Private slot to handle the wildcard characters toolbutton. """ from .QRegExpWizardCharactersDialog import \ QRegExpWizardCharactersDialog dlg = QRegExpWizardCharactersDialog( mode=QRegExpWizardCharactersDialog.WildcardMode, parent=self) if dlg.exec_() == QDialog.Accepted: self.__insertString(dlg.getCharacters()) @pyqtSlot() def on_wildcardAnycharButton_clicked(self): """ Private slot to handle the wildcard any character toolbutton. """ self.__insertString("?") @pyqtSlot() def on_wildcardRepeatButton_clicked(self): """ Private slot to handle the wildcard multiple characters toolbutton. """ self.__insertString("*") @pyqtSlot() def on_w3cCharButton_clicked(self): """ Private slot to handle the wildcard characters toolbutton. """ from .QRegExpWizardCharactersDialog import \ QRegExpWizardCharactersDialog dlg = QRegExpWizardCharactersDialog( mode=QRegExpWizardCharactersDialog.W3CMode, parent=self) if dlg.exec_() == QDialog.Accepted: self.__insertString(dlg.getCharacters()) @pyqtSlot() def on_w3cAnycharButton_clicked(self): """ Private slot to handle the W3C any character toolbutton. """ self.__insertString(".") @pyqtSlot() def on_w3cRepeatButton_clicked(self): """ Private slot to handle the W3C repeat toolbutton. """ from .QRegExpWizardRepeatDialog import QRegExpWizardRepeatDialog dlg = QRegExpWizardRepeatDialog(self) if dlg.exec_() == QDialog.Accepted: self.__insertString(dlg.getRepeat()) @pyqtSlot() def on_w3cGroupButton_clicked(self): """ Private slot to handle the W3C group toolbutton. """ self.__insertString("()", -1) @pyqtSlot() def on_w3cAltnButton_clicked(self): """ Private slot to handle the alternatives toolbutton. """ self.__insertString("(|)", -2) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.validateButton: self.on_validateButton_clicked() elif button == self.executeButton: self.on_executeButton_clicked() elif button == self.saveButton: self.on_saveButton_clicked() elif button == self.loadButton: self.on_loadButton_clicked() elif button == self.nextButton: self.on_nextButton_clicked() elif self.copyButton and button == self.copyButton: self.on_copyButton_clicked() @pyqtSlot() def on_saveButton_clicked(self): """ Private slot to save the regexp to a file. """ fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save regular expression"), "", self.tr("RegExp Files (*.rx);;All Files (*)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fname: ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save regular expression"), self.tr("

The file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return syntax = self.syntaxCombo.itemData(self.syntaxCombo.currentIndex()) try: f = open( Utilities.toNativeSeparators(fname), "w", encoding="utf-8") f.write("syntax={0}\n".format(syntax)) f.write(self.regexpLineEdit.text()) f.close() except IOError as err: E5MessageBox.information( self, self.tr("Save regular expression"), self.tr("""

The regular expression could not""" """ be saved.

Reason: {0}

""") .format(str(err))) @pyqtSlot() def on_loadButton_clicked(self): """ Private slot to load a regexp from a file. """ fname = E5FileDialog.getOpenFileName( self, self.tr("Load regular expression"), "", self.tr("RegExp Files (*.rx);;All Files (*)")) if fname: try: f = open( Utilities.toNativeSeparators(fname), "r", encoding="utf-8") regexp = f.read() f.close() if regexp.startswith("syntax="): lines = regexp.splitlines() syntax = int(lines[0].replace("syntax=", "")) index = self.syntaxCombo.findData(syntax) self.syntaxCombo.setCurrentIndex(index) regexp = lines[1] self.regexpLineEdit.setText(regexp) except IOError as err: E5MessageBox.information( self, self.tr("Save regular expression"), self.tr("""

The regular expression could not""" """ be saved.

Reason: {0}

""") .format(str(err))) @pyqtSlot() def on_copyButton_clicked(self): """ Private slot to copy the regexp string into the clipboard. This slot is only available, if not called from within eric6. """ escaped = self.regexpLineEdit.text() if escaped: escaped = escaped.replace("\\", "\\\\") cb = QApplication.clipboard() cb.setText(escaped, QClipboard.Clipboard) if cb.supportsSelection(): cb.setText(escaped, QClipboard.Selection) @pyqtSlot() def on_validateButton_clicked(self): """ Private slot to validate the entered regexp. """ regex = self.regexpLineEdit.text() if regex: re = QRegExp(regex) if self.caseSensitiveCheckBox.isChecked(): re.setCaseSensitivity(Qt.CaseSensitive) else: re.setCaseSensitivity(Qt.CaseInsensitive) re.setMinimal(self.minimalCheckBox.isChecked()) re.setPatternSyntax( self.syntaxCombo.itemData(self.syntaxCombo.currentIndex())) if re.isValid(): E5MessageBox.information( self, self.tr("Validation"), self.tr("""The regular expression is valid.""")) else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: {0}""") .format(re.errorString())) return else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression must be given.""")) @pyqtSlot() def on_executeButton_clicked(self, startpos=0): """ Private slot to execute the entered regexp on the test text. This slot will execute the entered regexp on the entered test data and will display the result in the table part of the dialog. @param startpos starting position for the regexp matching """ regex = self.regexpLineEdit.text() text = self.textTextEdit.toPlainText() if regex and text: re = QRegExp(regex) if self.caseSensitiveCheckBox.isChecked(): re.setCaseSensitivity(Qt.CaseSensitive) else: re.setCaseSensitivity(Qt.CaseInsensitive) re.setMinimal(self.minimalCheckBox.isChecked()) syntax = self.syntaxCombo.itemData(self.syntaxCombo.currentIndex()) wildcard = syntax in [QRegExp.Wildcard, QRegExp.WildcardUnix] re.setPatternSyntax(syntax) if not re.isValid(): E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: {0}""") .format(re.errorString())) return offset = re.indexIn(text, startpos) captures = re.captureCount() row = 0 OFFSET = 5 self.resultTable.setColumnCount(0) self.resultTable.setColumnCount(3) self.resultTable.setRowCount(0) self.resultTable.setRowCount(OFFSET) self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Regexp"))) self.resultTable.setItem(row, 1, QTableWidgetItem(regex)) if offset != -1: self.lastMatchEnd = offset + re.matchedLength() self.nextButton.setEnabled(True) row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Offset"))) self.resultTable.setItem( row, 1, QTableWidgetItem("{0:d}".format(offset))) if not wildcard: row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Captures"))) self.resultTable.setItem( row, 1, QTableWidgetItem("{0:d}".format(captures))) row += 1 self.resultTable.setItem( row, 1, QTableWidgetItem(self.tr("Text"))) self.resultTable.setItem( row, 2, QTableWidgetItem(self.tr("Characters"))) row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Match"))) self.resultTable.setItem( row, 1, QTableWidgetItem(re.cap(0))) self.resultTable.setItem( row, 2, QTableWidgetItem("{0:d}".format(re.matchedLength()))) if not wildcard: for i in range(1, captures + 1): if len(re.cap(i)) > 0: row += 1 self.resultTable.insertRow(row) self.resultTable.setItem( row, 0, QTableWidgetItem( self.tr("Capture #{0}").format(i))) self.resultTable.setItem( row, 1, QTableWidgetItem(re.cap(i))) self.resultTable.setItem( row, 2, QTableWidgetItem( "{0:d}".format(len(re.cap(i))))) else: self.resultTable.setRowCount(3) # highlight the matched text tc = self.textTextEdit.textCursor() tc.setPosition(offset) tc.setPosition(self.lastMatchEnd, QTextCursor.KeepAnchor) self.textTextEdit.setTextCursor(tc) else: self.nextButton.setEnabled(False) self.resultTable.setRowCount(2) row += 1 if startpos > 0: self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("No more matches"))) else: self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("No matches"))) # remove the highlight tc = self.textTextEdit.textCursor() tc.setPosition(0) self.textTextEdit.setTextCursor(tc) self.resultTable.resizeColumnsToContents() self.resultTable.resizeRowsToContents() self.resultTable.verticalHeader().hide() self.resultTable.horizontalHeader().hide() else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression and a text must""" """ be given.""")) @pyqtSlot() def on_nextButton_clicked(self): """ Private slot to find the next match. """ self.on_executeButton_clicked(self.lastMatchEnd) def on_regexpLineEdit_textChanged(self, txt): """ Private slot called when the regexp changes. @param txt the new text of the line edit (string) """ self.nextButton.setEnabled(False) def __getPatternSyntaxCode(self, syntaxValue): """ Private method to convert a pattern syntax value into a pattern syntax string. @param syntaxValue pattern syntax value (integer) @return pattern syntax string (string) """ syntax = "QRegExp." if syntaxValue == QRegExp.RegExp: syntax += "RegExp" elif syntaxValue == QRegExp.RegExp2: syntax += "RegExp2" elif syntaxValue == QRegExp.Wildcard: syntax += "Wildcard" elif syntaxValue == QRegExp.WildcardUnix: syntax += "WildcardUnix" elif syntaxValue == QRegExp.FixedString: syntax += "FixedString" elif syntaxValue == QRegExp.W3CXmlSchema11: syntax += "W3CXmlSchema11" return syntax def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate the indentation string istring = indLevel * indString estring = os.linesep + indLevel * indString # now generate the code reVar = self.variableLineEdit.text() if not reVar: reVar = "regexp" regexp = self.regexpLineEdit.text() code = '{0} = QRegExp(r"""{1}"""){2}'.format( reVar, regexp.replace('"', '\\"'), os.linesep) if not self.caseSensitiveCheckBox.isChecked(): code += '{0}{1}.setCaseSensitivity(Qt.CaseInsensitive){2}'.format( istring, reVar, os.linesep) if self.minimalCheckBox.isChecked(): code += '{0}{1}.setMinimal(True){2}'.format( istring, reVar, os.linesep) syntax = self.syntaxCombo.itemData(self.syntaxCombo.currentIndex()) needPatternSyntax = True if qVersion() < "5.0.0" and syntax == QRegExp.RegExp or \ qVersion() >= "5.0.0" and syntax == QRegExp.RegExp2: # default value selected needPatternSyntax = False if needPatternSyntax: code += '{0}{1}.setPatternSyntax({2}){3}'.format( istring, reVar, self.__getPatternSyntaxCode(syntax), estring) return code class QRegExpWizardDialog(QDialog): """ Class for the dialog variant. """ def __init__(self, parent=None, fromEric=True): """ Constructor @param parent parent widget (QWidget) @param fromEric flag indicating a call from within eric6 """ super(QRegExpWizardDialog, self).__init__(parent) self.setModal(fromEric) self.setSizeGripEnabled(True) self.__layout = QVBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.__layout) self.cw = QRegExpWizardWidget(self, fromEric) size = self.cw.size() self.__layout.addWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.cw.buttonBox.accepted.connect(self.accept) self.cw.buttonBox.rejected.connect(self.reject) def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ return self.cw.getCode(indLevel, indString) class QRegExpWizardWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(QRegExpWizardWindow, self).__init__(parent) self.cw = QRegExpWizardWidget(self, fromEric=False) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.setStyle( Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw.buttonBox.accepted.connect(self.close) self.cw.buttonBox.rejected.connect(self.close) eric-6.0.8/eric/Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardCharactersDialog.py0000644000175000017500000006364612451233372027573 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog for entering character classes. """ from __future__ import unicode_literals from PyQt5.QtCore import QRegExp from PyQt5.QtGui import QRegExpValidator from PyQt5.QtWidgets import QSizePolicy, QSpacerItem, QWidget, QHBoxLayout, \ QLineEdit, QPushButton, QDialog, QScrollArea, QComboBox, QVBoxLayout, \ QLabel from .Ui_QRegExpWizardCharactersDialog import Ui_QRegExpWizardCharactersDialog class QRegExpWizardCharactersDialog(QDialog, Ui_QRegExpWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ RegExpMode = 0 WildcardMode = 1 W3CMode = 2 def __init__(self, mode=RegExpMode, parent=None): """ Constructor @param mode mode of the dialog (one of RegExpMode, WildcardMode, W3CMode) @param parent parent widget (QWidget) """ super(QRegExpWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.__mode = mode if mode == QRegExpWizardCharactersDialog.WildcardMode: self.predefinedBox.setEnabled(False) self.predefinedBox.hide() elif mode == QRegExpWizardCharactersDialog.RegExpMode: self.w3cInitialIdentifierCheckBox.hide() self.w3cNonInitialIdentifierCheckBox.hide() self.w3cNmtokenCheckBox.hide() self.w3cNonNmtokenCheckBox.hide() elif mode == QRegExpWizardCharactersDialog.W3CMode: self.__initCharacterSelectors() self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append((self.tr("Normal character"), "-c")) if mode == QRegExpWizardCharactersDialog.RegExpMode: self.comboItems.append((self.tr( "Unicode character in hexadecimal notation"), "-h")) self.comboItems.append((self.tr( "ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append( (self.tr("Bell character (\\a)"), "\\a")) self.singleComboItems.append( (self.tr("Page break (\\f)"), "\\f")) self.singleComboItems.append( (self.tr("Line feed (\\n)"), "\\n")) self.singleComboItems.append( (self.tr("Carriage return (\\r)"), "\\r")) self.singleComboItems.append( (self.tr("Horizontal tabulator (\\t)"), "\\t")) self.singleComboItems.append( (self.tr("Vertical tabulator (\\v)"), "\\v")) elif mode == QRegExpWizardCharactersDialog.W3CMode: self.comboItems.append((self.tr( "Unicode character in hexadecimal notation"), "-h")) self.comboItems.append((self.tr( "ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append( (self.tr("Line feed (\\n)"), "\\n")) self.singleComboItems.append( (self.tr("Carriage return (\\r)"), "\\r")) self.singleComboItems.append( (self.tr("Horizontal tabulator (\\t)"), "\\t")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append( (self.tr("Character Category"), "-ccp")) self.singleComboItems.append( (self.tr("Character Block"), "-cbp")) self.singleComboItems.append( (self.tr("Not Character Category"), "-ccn")) self.singleComboItems.append( (self.tr("Not Character Block"), "-cbn")) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBox.setMinimumWidth(1000) self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton( self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBox.setMinimumWidth(1000) self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton( self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __initCharacterSelectors(self): """ Private method to initialize the W3C character selector entries. """ self.__characterCategories = ( # display name code (self.tr("Letter, Any"), "L"), (self.tr("Letter, Uppercase"), "Lu"), (self.tr("Letter, Lowercase"), "Ll"), (self.tr("Letter, Titlecase"), "Lt"), (self.tr("Letter, Modifier"), "Lm"), (self.tr("Letter, Other"), "Lo"), (self.tr("Mark, Any"), "M"), (self.tr("Mark, Nonspacing"), "Mn"), (self.tr("Mark, Spacing Combining"), "Mc"), (self.tr("Mark, Enclosing"), "Me"), (self.tr("Number, Any"), "N"), (self.tr("Number, Decimal Digit"), "Nd"), (self.tr("Number, Letter"), "Nl"), (self.tr("Number, Other"), "No"), (self.tr("Punctuation, Any"), "P"), (self.tr("Punctuation, Connector"), "Pc"), (self.tr("Punctuation, Dash"), "Pd"), (self.tr("Punctuation, Open"), "Ps"), (self.tr("Punctuation, Close"), "Pe"), (self.tr("Punctuation, Initial Quote"), "Pi"), (self.tr("Punctuation, Final Quote"), "Pf"), (self.tr("Punctuation, Other"), "Po"), (self.tr("Symbol, Any"), "S"), (self.tr("Symbol, Math"), "Sm"), (self.tr("Symbol, Currency"), "Sc"), (self.tr("Symbol, Modifier"), "Sk"), (self.tr("Symbol, Other"), "So"), (self.tr("Separator, Any"), "Z"), (self.tr("Separator, Space"), "Zs"), (self.tr("Separator, Line"), "Zl"), (self.tr("Separator, Paragraph"), "Zp"), (self.tr("Other, Any"), "C"), (self.tr("Other, Control"), "Cc"), (self.tr("Other, Format"), "Cf"), (self.tr("Other, Private Use"), "Co"), (self.tr("Other, Not Assigned"), "Cn"), ) self.__characterBlocks = ( (self.tr("Basic Latin"), "IsBasicLatin"), (self.tr("Latin-1 Supplement"), "IsLatin-1Supplement"), (self.tr("Latin Extended-A"), "IsLatinExtended-A"), (self.tr("Latin Extended-B"), "IsLatinExtended-B"), (self.tr("IPA Extensions"), "IsIPAExtensions"), (self.tr("Spacing Modifier Letters"), "IsSpacingModifierLetters"), (self.tr("Combining Diacritical Marks"), "IsCombiningDiacriticalMarks"), (self.tr("Greek"), "IsGreek"), (self.tr("Cyrillic"), "IsCyrillic"), (self.tr("Armenian"), "IsArmenian"), (self.tr("Hebrew"), "IsHebrew"), (self.tr("Arabic"), "IsArabic"), (self.tr("Syriac"), "IsSyriac"), (self.tr("Thaana"), "IsThaana"), (self.tr("Devanagari"), "IsDevanagari"), (self.tr("Bengali"), "IsBengali"), (self.tr("Gurmukhi"), "IsBengali"), (self.tr("Gujarati"), "IsGujarati"), (self.tr("Oriya"), "IsOriya"), (self.tr("Tamil"), "IsTamil"), (self.tr("Telugu"), "IsTelugu"), (self.tr("Kannada"), "IsKannada"), (self.tr("Malayalam"), "IsMalayalam"), (self.tr("Sinhala"), "IsSinhala"), (self.tr("Thai"), "IsThai"), (self.tr("Lao"), "IsLao"), (self.tr("Tibetan"), "IsTibetan"), (self.tr("Myanmar"), "IsMyanmar"), (self.tr("Georgian"), "IsGeorgian"), (self.tr("Hangul Jamo"), "IsHangulJamo"), (self.tr("Ethiopic"), "IsEthiopic"), (self.tr("Cherokee"), "IsCherokee"), (self.tr("Unified Canadian Aboriginal Syllabics"), "IsUnifiedCanadianAboriginalSyllabics"), (self.tr("Ogham"), "IsOgham"), (self.tr("Runic"), "IsRunic"), (self.tr("Khmer"), "IsKhmer"), (self.tr("Mongolian"), "IsMongolian"), (self.tr("Latin Extended Additional"), "IsLatinExtendedAdditional"), (self.tr("Greek Extended"), "IsGreekExtended"), (self.tr("General Punctuation"), "IsGeneralPunctuation"), (self.tr("Superscripts and Subscripts"), "IsSuperscriptsandSubscripts"), (self.tr("Currency Symbols"), "IsCurrencySymbols"), (self.tr("Combining Marks for Symbols"), "IsCombiningMarksforSymbols"), (self.tr("Letterlike Symbols"), "IsLetterlikeSymbols"), (self.tr("Number Forms"), "IsNumberForms"), (self.tr("Arrows"), "IsArrows"), (self.tr("Mathematical Operators"), "IsMathematicalOperators"), (self.tr("Miscellaneous Technical"), "IsMiscellaneousTechnical"), (self.tr("Control Pictures"), "IsControlPictures"), (self.tr("Optical Character Recognition"), "IsOpticalCharacterRecognition"), (self.tr("Enclosed Alphanumerics"), "IsEnclosedAlphanumerics"), (self.tr("Box Drawing"), "IsBoxDrawing"), (self.tr("Block Elements"), "IsBlockElements"), (self.tr("Geometric Shapes"), "IsGeometricShapes"), (self.tr("Miscellaneous Symbols"), "IsMiscellaneousSymbols"), (self.tr("Dingbats"), "IsDingbats"), (self.tr("Braille Patterns"), "IsBraillePatterns"), (self.tr("CJK Radicals Supplement"), "IsCJKRadicalsSupplement"), (self.tr("KangXi Radicals"), "IsKangXiRadicals"), (self.tr("Ideographic Description Chars"), "IsIdeographicDescriptionChars"), (self.tr("CJK Symbols and Punctuation"), "IsCJKSymbolsandPunctuation"), (self.tr("Hiragana"), "IsHiragana"), (self.tr("Katakana"), "IsKatakana"), (self.tr("Bopomofo"), "IsBopomofo"), (self.tr("Hangul Compatibility Jamo"), "IsHangulCompatibilityJamo"), (self.tr("Kanbun"), "IsKanbun"), (self.tr("Bopomofo Extended"), "IsBopomofoExtended"), (self.tr("Enclosed CJK Letters and Months"), "IsEnclosedCJKLettersandMonths"), (self.tr("CJK Compatibility"), "IsCJKCompatibility"), (self.tr("CJK Unified Ideographs Extension A"), "IsCJKUnifiedIdeographsExtensionA"), (self.tr("CJK Unified Ideographs"), "IsCJKUnifiedIdeographs"), (self.tr("Yi Syllables"), "IsYiSyllables"), (self.tr("Yi Radicals"), "IsYiRadicals"), (self.tr("Hangul Syllables"), "IsHangulSyllables"), (self.tr("Private Use"), "IsPrivateUse"), (self.tr("CJK Compatibility Ideographs"), "IsCJKCompatibilityIdeographs"), (self.tr("Alphabetic Presentation Forms"), "IsAlphabeticPresentationForms"), (self.tr("Arabic Presentation Forms-A"), "IsArabicPresentationForms-A"), (self.tr("Combining Half Marks"), "IsCombiningHalfMarks"), (self.tr("CJK Compatibility Forms"), "IsCJKCompatibilityForms"), (self.tr("Small Form Variants"), "IsSmallFormVariants"), (self.tr("Arabic Presentation Forms-B"), "IsArabicPresentationForms-B"), (self.tr("Halfwidth and Fullwidth Forms"), "IsHalfwidthandFullwidthForms"), (self.tr("Specials"), "IsSpecials"), (self.tr("Old Italic"), "IsOldItalic"), (self.tr("Gothic"), "IsGothic"), (self.tr("Deseret"), "IsDeseret"), (self.tr("Byzantine Musical Symbols"), "IsByzantineMusicalSymbols"), (self.tr("Musical Symbols"), "IsMusicalSymbols"), (self.tr("Mathematical Alphanumeric Symbols"), "IsMathematicalAlphanumericSymbols"), (self.tr("CJK Unified Ideographic Extension B"), "IsCJKUnifiedIdeographicExtensionB"), (self.tr("CJK Compatapility Ideographic Supplement"), "IsCJKCompatapilityIdeographicSupplement"), (self.tr("Tags"), "IsTags"), ) def __populateCharTypeCombo(self, combo, isSingle): """ Private method to populate a given character type selection combo box. @param combo reference to the combo box to be populated (QComboBox) @param isSingle flag indicating a singles combo (boolean) """ for txt, value in self.comboItems: combo.addItem(txt, value) if isSingle: for txt, value in self.singleComboItems: combo.addItem(txt, value) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, True) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb1a = QComboBox(hbox) cb1a.setEditable(False) cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb1a) cb1a.hide() cb2 = QComboBox(hbox) cb2.setEditable(False) self.__populateCharTypeCombo(cb2, True) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) cb2a = QComboBox(hbox) cb2a.setEditable(False) cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb2a) cb2a.hide() self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1, cb1a]) self.singlesEntries.append([cb2, le2, cb2a]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, False) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __populateW3cCharacterCombo(self, combo, format): """ Private method to populate a W3C character selection combo. @param combo combo box to be populated (QComboBox) @param format format identifier (one of "-ccp", "-ccn", "-cbp", "-cbn") """ combo.clear() if format in ["-ccp", "-ccn"]: comboLen = 0 for txt, code in self.__characterCategories: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) elif format in ["-cbp", "-cbn"]: comboLen = 0 for txt, code in self.__characterBlocks: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) def __performSelectedAction(self, format, lineedit, combo): """ Private method performing some actions depending on the input. @param format format of the selected entry (string) @param lineedit line edit widget to act on (QLineEdit) @param combo combo box widget to act on (QComboBox) """ if format == "-i": return if format in ["-c", "-h", "-o"]: lineedit.show() lineedit.setEnabled(True) if combo is not None: combo.hide() if format == "-c": lineedit.setValidator(self.charValidator) elif format == "-h": lineedit.setValidator(self.hexValidator) elif format == "-o": lineedit.setValidator(self.octValidator) elif format in ["-ccp", "-ccn", "-cbp", "-cbn"]: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.show() self.__populateW3cCharacterCombo(combo, format) else: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.hide() lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction( format, entriesList[1], entriesList[2]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction(format, entriesList[1], None) self.__performSelectedAction(format, entriesList[2], None) break def __formatCharacter(self, char, format): """ Private method to format the characters entered into the dialog. @param char character string entered into the dialog (string) @param format string giving a special format (-c, -h, -i or -o) or the already formatted character (string) @return formatted character string (string) """ if format == "-c": return char elif format == "-i": return "" if self.__mode in [QRegExpWizardCharactersDialog.RegExpMode, QRegExpWizardCharactersDialog.W3CMode]: if format == "-h": return "\\x{0}".format(char.lower()) elif format == "-o": return "\\0{0}".format(char) elif format in ["-ccp", "-cbp"]: return "\\p{{{0}}}".format(char) elif format in ["-ccn", "-cbn"]: return "\\P{{{0}}}".format(char) else: return format def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" if self.w3cInitialIdentifierCheckBox.isChecked(): regexp += "\\i" if self.w3cNonInitialIdentifierCheckBox.isChecked(): regexp += "\\I" if self.w3cNmtokenCheckBox.isChecked(): regexp += "\\c" if self.w3cNonNmtokenCheckBox.isChecked(): regexp += "\\C" # single characters for entrieslist in self.singlesEntries: format = entrieslist[0].itemData(entrieslist[0].currentIndex()) if format in ["-ccp", "-ccn", "-cbp", "-cbn"]: char = entrieslist[2].itemData(entrieslist[2].currentIndex()) else: char = entrieslist[1].text() regexp += self.__formatCharacter(char, format) # character ranges for entrieslist in self.rangesEntries: if not entrieslist[1].text() or \ not entrieslist[2].text(): continue format = entrieslist[0].itemData(entrieslist[0].currentIndex()) char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format( self.__formatCharacter(char1, format), self.__formatCharacter(char2, format)) if regexp: if (regexp.startswith("\\") and regexp.count("\\") == 1 and "-" not in regexp) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return "" eric-6.0.8/eric/Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardDialog.ui0000644000175000017500000005572312263274167025565 0ustar piotrpiotr QRegExpWizardWidget 0 0 749 600 QRegExp Wizard true &Variable Name: variableLineEdit Qt::Horizontal Pattern Syntax: Select the pattern syntax Qt::Horizontal QSizePolicy::Fixed 16 20 <b>Undo last edit</b> <b>Redo last edit</b> Qt::Horizontal 40 20 0 0 0 0 <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog.</p> <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog. This dialog will help to edit the range of characters and add some specific conditions.</p> <b>Any character: '.'</b> <p>Select to insert a dot (.) in your regexp.</p> <b>Any character: '.'</b> <p>Select to insert a dot (.) in your regexp. The dot matches a single character, except line break characters (by default). E.g. 'gr.y' matches 'gray', 'grey', 'gr%y', etc. Use the dot sparingly. Often, a character class or negated character class is faster and more precise.</p> <b>Repeat contents</b> <p>Select a repetition condition via a specific dialog. This dialog will help to specify the allowed range for repetitions.</p> <b>Repeat contents</b> <p>Select a repetition condition via a specific dialog. This dialog will help to specify the allowed range for repetitions.</p> <b>Non capturing parentheses: (?:)</b> <p>Select to insert some non capturing brackets.</p> <b>Non capturing parentheses: (?:)</b> <p>Select to insert some non capturing brackets. It can be used to apply a regexp quantifier (eg. '?' or '+') to the entire group of characters inside the brakets. E.g. the regex 'Set(?:Value)?' matches 'Set' or 'SetValue'. The '?:' inside the brakets means that the content of the match (called the backreference) is not stored for further use.</p> <b>Group: ()</b> <p>Select to insert some capturing brackets.</p> <b>Group: ()</b> <p>Select to insert some capturing brackets. They can be used to apply a regexp quantifier (e.g. '?' or '+') to the entire group of characters inside the brakets. E.g. the regex 'Set(Value)?' matches 'Set' or 'SetValue'. Contrary to non-capturing parentheses, the backreference matched inside the brakets is stored for further use (i.e. 'Value' in the second example above). One can access the backereference with the '\1' expression. </p> <p>E.g. '([a-c])x\1x\1' will match 'axaxa', 'bxbxb' and 'cxcxc'.</p> <b>Alternatives: '|'</b> <p>Select to insert the alternation symbol '|'. </p> <b>Alternatives: '|'</b> <p>Select to insert the alternation symbol '|'. The alternation is used to match a single regular expression out of several possible regular expressions. E.g. 'cat|dog|mouse|fish' matches words containing the word 'cat', 'dog','mouse' or 'fish'. Be aware that in the above example, the alternatives refer to whole or part of words. If you want to match exactly the words 'cat', 'dog', ... you should express the fact that you only want to match complete words: '\b(cat|dog|mouse|fish)\b'</p> <b>Begin of line: '^'</b> <p>Select to insert the start line character (^).</p> <b>Begin of line: '^'</b> <p>Select to insert the start line character (^). It is used to find some expressions at the begining of lines. E.g. '^[A-Z]' match lines starting with a capitalized character. </p> <b>End of line: '$'</b> <p>Select to insert the end of line character ($).</p> <b>End of line: '$'</b> <p>Select to insert the end of line character ($). It is used to find some expressions at the end of lines.</p> <b>Word boundary</b> <p>Select to insert the word boudary character (\b).</p> <b>Word boundary</b> <p>Select to insert the word boudary character (\b). This character is used to express the fact that word must begin or end at this position. E.g. '\bcat\b' matches exactly the word 'cat' while 'concatenation' is ignored.</p> <b>Non word boundary</b> <p>Select to insert the word boudary character (\B). \B is the negated version of \b.</p> <b>Non word boundary</b> <p>Select to insert the word boudary character (\B). \B is the negated version of \b. \B matches at every position where \b does not. Effectively, \B matches at any position between two word characters as well as at any position between two non-word characters.</p> <b>Positive lookahead: (?=<i>regexpr</i>)</b> <p>Select to insert the positive lookhead brackets.</p> <b>Positive lookahead: (?=<i>regexpr</i>)</b> <p>Select to insert the positive lookhead brackets. Basically, positive lookhead is used to match a character only if followed by another one. Writting 'q(?=u)' means that you want to match the 'q' character only if it is followed by 'u'. In this statement 'u' is a trivial regexp which may be replaced by a more complex expression; q(?=[abc])' will match a 'q' if followed by either 'a', 'b' or 'c'.</p> <b>Negative lookahead: (?!<i>regexpr</i>)</b> <p>Select to insert the negative lookhead brackets.</p> <b>Negative lookahead: (?!<i>regexpr</i>)</b> <p>Select to insert the negative lookhead brackets. Basically, negative lookhead is used to match a character only if it is not followed by a another one. Writting 'q(?!u)' means that you want to match 'q' only if it is not followed by 'u'. In this statement, 'u' is a trivial regexp which may be replaced by a more complex expression; 'q(?![abc])' will match a 'q' if it is followed by anything else than 'a', 'b' or 'c'.</p> Qt::Horizontal QSizePolicy::Expanding 356 24 0 0 0 0 <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog.</p> <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog. This dialog will help to edit the range of characters and add some specific conditions.</p> <b>Any character: '.'</b> <p>Select to insert a question mark (?) in your regexp.</p> <b>Any character: '.'</b> <p>Select to insert a question mark (?) in your regexp. The question mark matches a single character. E.g. 'gr?y' matches 'gray', 'grey', 'gr%y', etc.</p> <b>Repeat contents</b> <p>Inserts a repetition (*) character into the regexp.</p> <b>Repeat contents</b> <p>Inserts a repetition (*) character into the regexp. That will match zero or more of any character.</p> Qt::Horizontal 635 20 0 0 0 0 <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog.</p> <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog. This dialog will help to edit the range of characters and add some specific conditions.</p> <b>Any character: '.'</b> <p>Select to insert a dot (.) in your regexp.</p> <b>Any character: '.'</b> <p>Select to insert a dot (.) in your regexp. The dot matches a single character, except line break characters (by default). E.g. 'gr.y' matches 'gray', 'grey', 'gr%y', etc. Use the dot sparingly. Often, a character class or negated character class is faster and more precise.</p> <b>Repeat contents</b> <p>Select a repetition condition via a specific dialog. This dialog will help to specify the allowed range for repetitions.</p> <b>Repeat contents</b> <p>Select a repetition condition via a specific dialog. This dialog will help to specify the allowed range for repetitions.</p> <b>Group: ()</b> <p>Select to insert some capturing brackets.</p> <b>Group: ()</b> <p>Select to insert some capturing brackets. They can be used to apply a regexp quantifier (e.g. '?' or '+') to the entire group of characters inside the brakets. E.g. the regex 'Set(Value)?' matches 'Set' or 'SetValue'.</p> <b>Alternatives: '|'</b> <p>Select to insert the alternation symbol '|'. </p> <b>Alternatives: '|'</b> <p>Select to insert the alternation symbol '|'. The alternation is used to match a single regular expression out of several possible regular expressions. E.g. 'cat|dog|mouse|fish' matches words containing the word 'cat', 'dog','mouse' or 'fish'.</p> Qt::Horizontal 573 20 &Regexp: regexpLineEdit &Text: Qt::AlignTop textTextEdit Case &Sensitive Alt+S true &Minimal Alt+M Qt::Horizontal QSizePolicy::Expanding 40 20 QAbstractItemView::NoEditTriggers Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok qPixmapFromMimeSource variableLineEdit syntaxCombo undoButton redoButton charButton anycharButton repeatButton nonGroupButton groupButton altnButton beglineButton endlineButton wordboundButton nonwordboundButton poslookaheadButton neglookaheadButton wildcardCharButton wildcardAnycharButton wildcardRepeatButton w3cCharButton w3cAnycharButton w3cRepeatButton w3cGroupButton w3cAltnButton regexpLineEdit textTextEdit caseSensitiveCheckBox minimalCheckBox resultTable buttonBox undoButton clicked() regexpLineEdit undo() 490 132 487 163 redoButton clicked() regexpLineEdit redo() 526 132 529 163 eric-6.0.8/eric/Plugins/WizardPlugins/QRegExpWizard/__init__.py0000644000175000017500000000022512451233372023476 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Package implementing the QRegExp wizard. """ eric-6.0.8/eric/Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardRepeatDialog.py0000644000175000017500000000467412451233372026730 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog for entering repeat counts. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from .Ui_QRegExpWizardRepeatDialog import Ui_QRegExpWizardRepeatDialog class QRegExpWizardRepeatDialog(QDialog, Ui_QRegExpWizardRepeatDialog): """ Class implementing a dialog for entering repeat counts. """ def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(QRegExpWizardRepeatDialog, self).__init__(parent) self.setupUi(self) self.unlimitedButton.setChecked(True) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(int) def on_lowerSpin_valueChanged(self, value): """ Private slot to handle the lowerSpin valueChanged signal. @param value value of the spinbox (integer) """ if self.upperSpin.value() < value: self.upperSpin.setValue(value) @pyqtSlot(int) def on_upperSpin_valueChanged(self, value): """ Private slot to handle the upperSpin valueChanged signal. @param value value of the spinbox (integer) """ if self.lowerSpin.value() > value: self.lowerSpin.setValue(value) def getRepeat(self): """ Public method to retrieve the dialog's result. @return ready formatted repeat string (string) """ if self.unlimitedButton.isChecked(): return "*" elif self.minButton.isChecked(): reps = self.minSpin.value() if reps == 1: return "+" else: return "{{{0:d},}}".format(reps) elif self.maxButton.isChecked(): reps = self.maxSpin.value() if reps == 1: return "?" else: return "{{,{0:d}}}".format(reps) elif self.exactButton.isChecked(): reps = self.exactSpin.value() return "{{{0:d}}}".format(reps) elif self.betweenButton.isChecked(): repsMin = self.lowerSpin.value() repsMax = self.upperSpin.value() return "{{{0:d},{1:d}}}".format(repsMin, repsMax) eric-6.0.8/eric/Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardCharactersDialog.ui0000644000175000017500000001303012060166053027533 0ustar piotrpiotr QRegExpWizardCharactersDialog 0 0 850 500 Editor for character sets true The defined characters should not match Predefined character ranges Word character Digits Whitespace characters Non-word characters Non-digits Non-whitespace characters Initial name character Name character Non-initial name character Non-name character 0 0 Single character 0 0 Character ranges Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource negativeCheckBox wordCharCheckBox nonWordCharCheckBox digitsCheckBox nonDigitsCheckBox whitespaceCheckBox nonWhitespaceCheckBox w3cInitialIdentifierCheckBox w3cNonInitialIdentifierCheckBox w3cNmtokenCheckBox w3cNonNmtokenCheckBox buttonBox buttonBox accepted() QRegExpWizardCharactersDialog accept() 80 482 80 499 buttonBox rejected() QRegExpWizardCharactersDialog reject() 229 480 229 498 eric-6.0.8/eric/Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardRepeatDialog.ui0000644000175000017500000001703312060166053026703 0ustar piotrpiotr QRegExpWizardRepeatDialog 0 0 331 197 Number of repetitions true true 0 times times times false Qt::AlignRight 1 false Qt::AlignRight 1 and Between false Qt::AlignRight 1 Exactly false Qt::AlignRight 1 Maximum Minimum false Qt::AlignRight 1 Unlimited (incl. zero times) Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource unlimitedButton minButton minSpin maxButton maxSpin exactButton exactSpin betweenButton lowerSpin upperSpin minButton toggled(bool) minSpin setEnabled(bool) 53 43 121 47 maxButton toggled(bool) maxSpin setEnabled(bool) 58 68 117 67 exactButton toggled(bool) exactSpin setEnabled(bool) 53 99 116 98 betweenButton toggled(bool) lowerSpin setEnabled(bool) 52 126 119 124 betweenButton toggled(bool) upperSpin setEnabled(bool) 53 125 282 125 buttonBox accepted() QRegExpWizardRepeatDialog accept() 16 164 16 185 buttonBox rejected() QRegExpWizardRepeatDialog reject() 72 167 72 181 eric-6.0.8/eric/Plugins/WizardPlugins/FontDialogWizard/0000755000175000017500000000000012557365404022112 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/FontDialogWizard/__init__.py0000644000175000017500000000023112451233372024206 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Package implementing the font dialog wizard. """ eric-6.0.8/eric/Plugins/WizardPlugins/FontDialogWizard/FontDialogWizardDialog.py0000644000175000017500000001031212451233372026777 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the font dialog wizard dialog. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFontDialog from .Ui_FontDialogWizardDialog import Ui_FontDialogWizardDialog class FontDialogWizardDialog(QDialog, Ui_FontDialogWizardDialog): """ Class implementing the font dialog wizard dialog. It displays a dialog for entering the parameters for the QFontDialog code generator. """ def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(FontDialogWizardDialog, self).__init__(parent) self.setupUi(self) self.bTest = self.buttonBox.addButton( self.tr("Test"), QDialogButtonBox.ActionRole) self.font = None msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.bTest: self.on_bTest_clicked() @pyqtSlot() def on_bTest_clicked(self): """ Private method to test the selected options. """ if self.font is None: QFontDialog.getFont() else: QFontDialog.getFont(self.font) def on_eVariable_textChanged(self, text): """ Private slot to handle the textChanged signal of eVariable. @param text the new text (string) """ if not text: self.bTest.setEnabled(True) else: self.bTest.setEnabled(False) @pyqtSlot() def on_fontButton_clicked(self): """ Private slot to handle the button press to select a font via a font selection dialog. """ if self.font is None: font, ok = QFontDialog.getFont() else: font, ok = QFontDialog.getFont(self.font) if ok: self.font = font else: self.font = None def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate our indentation level and the indentation string il = indLevel + 1 istring = il * indString estring = os.linesep + indLevel * indString # generate the code resvar = self.eResultVar.text() if not resvar: resvar = "font" title = self.eCaption.text() if self.parentSelf.isChecked(): parent = "self" elif self.parentNone.isChecked(): parent = "None" elif self.parentOther.isChecked(): parent = self.parentEdit.text() if parent == "": parent = "None" code = '{0}, ok = QFontDialog.getFont('.format(resvar) if self.eVariable.text() or self.font is not None: if title or parent != "None": code += '{0}{1}'.format(os.linesep, istring) if not self.eVariable.text(): if self.font is not None: code += 'QFont("{0}", {1:d}, {2:d}, {3:d})'.format( self.font.family(), self.font.pointSize(), self.font.weight(), self.font.italic()) else: code += self.eVariable.text() if title: code += ',{0}{1}{2}'.format( os.linesep, istring, parent) code += ',{0}{1}self.tr("{2}")'.format( os.linesep, istring, title) elif parent != "None": code += ',{0}{1}{2}'.format( os.linesep, istring, parent) code += '){0}'.format(estring) return code eric-6.0.8/eric/Plugins/WizardPlugins/FontDialogWizard/FontDialogWizardDialog.ui0000644000175000017500000001404212247413640026771 0ustar piotrpiotr FontDialogWizardDialog 0 0 377 291 QFontDialog Wizard true Result: Enter the result variable name Title: Enter the title for the message box Parent Select "self" as parent self true Select "None" as parent None Select to enter a parent expression Expression: false Enter the parent expression Qt::Horizontal QSizePolicy::Expanding 30 0 Press to select a font via a dialog Select Font ... Qt::Horizontal QSizePolicy::Expanding 30 0 Font Variable: Enter a variable name Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource eResultVar eCaption parentSelf parentNone parentOther parentEdit fontButton eVariable buttonBox buttonBox accepted() FontDialogWizardDialog accept() 29 281 20 120 buttonBox rejected() FontDialogWizardDialog reject() 85 281 76 119 parentOther toggled(bool) parentEdit setEnabled(bool) 61 156 130 157 eric-6.0.8/eric/Plugins/WizardPlugins/PyRegExpWizard/0000755000175000017500000000000012557365404021567 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.ui0000644000175000017500000005363312263273777026151 0ustar piotrpiotr PyRegExpWizardDialog 0 0 750 700 Python re Wizard true Python Version Python 2 false Python 3 true Qt::Horizontal 535 20 Variable Name: Include import statement QFrame::HLine QFrame::Sunken Qt::Horizontal <b>Comment: (?#)</b> <p>Insert some comment inside your regexp.</p> <b>Comment: (?#)</b> <p>Insert some comment inside your regexp.The regex engine ignores everything after the (?# until the first closing round bracket. The following example could clarify the regexp which match a valid date: </p> <p>(?#year)(19|20)\d\d[- /.](?#month)(0[1-9]|1[012])[- /.](?#day)(0[1-9]|[12][0-9]|3[01])</p> <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog.</p> <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog. This dialog will help to edit the range of characters and add some specific conditions.</p>s <b>Any character: '.'</b> <p>Select to insert a dot (.) in your regexp.</p> <b>Any character: '.'</b> <p>Select to insert a dot (.) in your regexp. The dot matches a single character, except line break characters (by default). E.g. 'gr.y' matches 'gray', 'grey', 'gr%y', etc. Use the dot sparingly. Often, a character class or negated character class is faster and more precise.</p> <b>Repeat contents</b> <p>Select a repetition condition via a specific dialog. This dialog will help to specify the allowed range for repetitions.</p> <b>Repeat contents</b> <p>Select a repetition condition via a specific dialog. This dialog will help to specify the allowed range for repetitions.</p> <b>Non capturing parentheses: (?:)</b> <p>Select to insert some non capturing brackets.</p> <b>Non capturing parentheses: (?:)</b> <p>Select to insert some non capturing brackets. It can be used to apply a regexp quantifier (eg. '?' or '+') to the entire group of characters inside the brakets. E.g. the regex 'Set(?:Value)?' matches 'Set' or 'SetValue'. The '?:' inside the brakets means that the content of the match (called the backreference) is not stored for further use.</p> <b>Group: ()</b> <p>Select to insert some capturing brackets.</p> <b>Group: ()</b> <p>Select to insert some capturing brackets. They can be used to apply a regexp quantifier (e.g. '?' or '+') to the entire group of characters inside the brakets. E.g. the regex 'Set(Value)?' matches 'Set' or 'SetValue'. Contrary to non-capturing parentheses, the backreference matched inside the brakets is stored for further use (i.e. 'Value' in the second example above). One can access the backereference with the '\1' expression. </p> <p>E.g. '([a-c])x\1x\1' will match 'axaxa', 'bxbxb' and 'cxcxc'.</p> <b>Named group: (?P&lt;<i>groupname</i>&gt;)</b> <p>Select to insert some named group brackets.</p> <b>Named group: (?P&lt;<i>groupname</i>&gt;)</b> <p>Select to insert some named group brackets. Usage is similar to standard group parentheses as the matched backreference is also stored for further usage. The difference is that a name is given to the match. This is useful when the work to do on the match becomes a bit complicated. One can access the backreference via the group name (i.e (?P=<i>groupname</i>)). E.g. (?P<foo>[abc])x(?P=foo)x(?P=foo)x matches 'axaxax','bxbxbx' or 'cxcxcx' ('foo' is the group name)</p> <b>Reference named group: (?P=<i>groupname</i>)</b> <p>Select to insert a reference to named group previously declared.</p> <b>Reference named group: (?P=<i>groupname</i>)</b> <p>Select to insert a reference to named group previously declared. Each reference group refers to the match found by the corresponding named group. In the following example, (?P=foo) may refer to the charaters 'a','b' or 'c'.</p> <p>E.g. (?P<foo>[abc])x(?P=foo)x(?P=foo)x matches 'axaxax','bxbxbx' or 'cxcxcx'.</p> <b>Alternatives: '|'</b> <p>Select to insert the alternation symbol '|'. </p> <b>Alternatives: '|'</b> <p>Select to insert the alternation symbol '|'. The alternation is used to match a single regular expression out of several possible regular expressions. E.g. 'cat|dog|mouse|fish' matches words containing the word 'cat', 'dog','mouse' or 'fish'. Be aware that in the above example, the alternatives refer to whole or part of words. If you want to match exactly the words 'cat', 'dog', ... you should express the fact that you only want to match complete words: '\b(cat|dog|mouse|fish)\b'</p> <b>Begin of line: '^'</b> <p>Select to insert the start line character (^).</p> <b>Begin of line: '^'</b> <p>Select to insert the start line character (^). It is used to find some expressions at the begining of lines. E.g. '^[A-Z]' match lines starting with a capitalized character. </p> <b>End of line: '$'</b> <p>Select to insert the end of line character ($).</p> <b>End of line: '$'</b> <p>Select to insert the end of line character ($). It is used to find some expressions at the end of lines.</p> <b>Word boundary</b> <p>Select to insert the word boudary character (\b).</p> <b>Word boundary</b> <p>Select to insert the word boudary character (\b). This character is used to express the fact that word must begin or end at this position. E.g. '\bcat\b' matches exactly the word 'cat' while 'concatenation' is ignored.</p> <b>Non word boundary</b> <p>Select to insert the word boudary character (\B). \B is the negated version of \b.</p> <b>Non word boundary</b> <p>Select to insert the word boudary character (\B). \B is the negated version of \b. \B matches at every position where \b does not. Effectively, \B matches at any position between two word characters as well as at any position between two non-word characters.</p> <b>Positive lookahead: (?=<i>regexpr</i>)</b> <p>Select to insert the positive lookhead brackets.</p> <b>Positive lookahead: (?=<i>regexpr</i>)</b> <p>Select to insert the positive lookhead brackets. Basically, positive lookhead is used to match a character only if followed by another one. Writting 'q(?=u)' means that you want to match the 'q' character only if it is followed by 'u'. In this statement 'u' is a trivial regexp which may be replaced by a more complex expression; q(?=[abc])' will match a 'q' if followed by either 'a', 'b' or 'c'.</p> <b>Negative lookahead: (?!<i>regexpr</i>)</b> <p>Select to insert the negative lookhead brackets.</p> <b>Negative lookahead: (?!<i>regexpr</i>)</b> <p>Select to insert the negative lookhead brackets. Basically, negative lookhead is used to match a character only if it is not followed by a another one. Writting 'q(?!u)' means that you want to match 'q' only if it is not followed by 'u'. In this statement, 'u' is a trivial regexp which may be replaced by a more complex expression; 'q(?![abc])' will match a 'q' if it is followed by anything else than 'a', 'b' or 'c'.</p> <b>Positive lookbehind: (?&lt;=<i>regexpr</i>)</b> <p>Select to insert the positive lookbehind brackets.</p> <b>Positive lookbehind: (?&lt;=<i>regexpr</i>)</b> <p>Select to insert the positive lookbehind brackets. Lookbehind has the same effect as lookahead, but works backwards. It is used to match a character only if preceded by another one. Writting '(?&lt;=u)q' means that you want to match the 'q' character only if it is preceded by 'u'. As with lookhead, 'u' may be replaced by a more complex expression; '(?&lt;=[abc])q' will match a 'q' if preceded by either 'a', 'b' or 'c'.</p> <b>Negative lookbehind (?&lt;!<i>regexpr</i>)</b> <p>Select to insert the negative lookbehind brackets.</p> <b>Negative lookbehind (?&lt;!<i>regexpr</i>)</b> <p>Select to insert the negative lookbehind brackets. Lookbehind has the same effect as lookahead, but works backwards. It is used to match a character only if not preceded by another one. Writting '(?&lt;!u)q' means that you want to match the 'q' character only if it is not preceded by 'u'. As other lookaround, 'u' may be replaced by a more complex expression; '(?&lt;![abc])q' will match a 'q' only if not preceded by either 'a', 'b' nor 'c'.</p> Qt::Horizontal QSizePolicy::Fixed 16 20 <b>Undo last edit</b> <b>Redo last edit</b> Qt::Horizontal QSizePolicy::Expanding 20 20 Regexp: Qt::AlignTop 0 1 false 0 2 QAbstractItemView::NoEditTriggers "^" matches beginning of line, "$" matches end of line Match Linebreaks ASCII Verbose Regexp Case Sensitive true false Observe Locale "." matches linebreaks as well Dot matches Linebreak Text: Qt::AlignTop 0 1 false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok qPixmapFromMimeSource py2Button py3Button variableLineEdit importCheckBox commentButton charButton anycharButton repeatButton nonGroupButton groupButton namedGroupButton namedReferenceButton altnButton beglineButton endlineButton wordboundButton nonwordboundButton poslookaheadButton neglookaheadButton poslookbehindButton neglookbehindButton undoButton redoButton regexpTextEdit textTextEdit caseSensitiveCheckBox verboseCheckBox multilineCheckBox localeCheckBox dotallCheckBox unicodeCheckBox resultTable buttonBox eric-6.0.8/eric/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardCharactersDialog.ui0000644000175000017500000001052412060166053030120 0ustar piotrpiotr PyRegExpWizardCharactersDialog 0 0 800 500 Editor for character sets true The defined characters should not match Predefined character ranges Non-whitespace characters Non-digits Whitespace characters Digits Non-word characters Word character 0 0 Single character 0 0 Character ranges Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource negativeCheckBox wordCharCheckBox nonWordCharCheckBox digitsCheckBox nonDigitsCheckBox whitespaceCheckBox nonWhitespaceCheckBox buttonBox accepted() PyRegExpWizardCharactersDialog accept() 157 476 157 498 buttonBox rejected() PyRegExpWizardCharactersDialog reject() 269 477 269 499 eric-6.0.8/eric/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardRepeatDialog.ui0000644000175000017500000001736312060166053027271 0ustar piotrpiotr PyRegExpWizardRepeatDialog 0 0 331 223 Number of repetitions true true 0 times times times false Qt::AlignRight 1 false Qt::AlignRight 1 and Between false Qt::AlignRight 1 Exactly false Qt::AlignRight 1 Maximum Minimum false Qt::AlignRight 1 Unlimited (incl. zero times) Minimal match Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource unlimitedButton minButton minSpin maxButton maxSpin exactButton exactSpin betweenButton lowerSpin upperSpin minimalCheckBox minButton toggled(bool) minSpin setEnabled(bool) 53 43 121 47 maxButton toggled(bool) maxSpin setEnabled(bool) 58 68 117 67 exactButton toggled(bool) exactSpin setEnabled(bool) 61 114 162 114 betweenButton toggled(bool) lowerSpin setEnabled(bool) 60 143 162 143 betweenButton toggled(bool) upperSpin setEnabled(bool) 61 143 322 143 buttonBox accepted() PyRegExpWizardRepeatDialog accept() 19 190 19 211 buttonBox rejected() PyRegExpWizardRepeatDialog reject() 61 192 61 210 eric-6.0.8/eric/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardRepeatDialog.py0000644000175000017500000000521212451233372027275 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog for entering repeat counts. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from .Ui_PyRegExpWizardRepeatDialog import Ui_PyRegExpWizardRepeatDialog class PyRegExpWizardRepeatDialog(QDialog, Ui_PyRegExpWizardRepeatDialog): """ Class implementing a dialog for entering repeat counts. """ def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(PyRegExpWizardRepeatDialog, self).__init__(parent) self.setupUi(self) self.unlimitedButton.setChecked(True) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(int) def on_lowerSpin_valueChanged(self, value): """ Private slot to handle the lowerSpin valueChanged signal. @param value value of the spinbox (integer) """ if self.upperSpin.value() < value: self.upperSpin.setValue(value) @pyqtSlot(int) def on_upperSpin_valueChanged(self, value): """ Private slot to handle the upperSpin valueChanged signal. @param value value of the spinbox (integer) """ if self.lowerSpin.value() > value: self.lowerSpin.setValue(value) def getRepeat(self): """ Public method to retrieve the dialog's result. @return ready formatted repeat string (string) """ if self.minimalCheckBox.isChecked(): minimal = "?" else: minimal = "" if self.unlimitedButton.isChecked(): return "*" + minimal elif self.minButton.isChecked(): reps = self.minSpin.value() if reps == 1: return "+" + minimal else: return "{{{0:d},}}{1}".format(reps, minimal) elif self.maxButton.isChecked(): reps = self.maxSpin.value() if reps == 1: return "?" + minimal else: return "{{,{0:d}}}{1}".format(reps, minimal) elif self.exactButton.isChecked(): reps = self.exactSpin.value() return "{{{0:d}}}{1}".format(reps, minimal) elif self.betweenButton.isChecked(): repsMin = self.lowerSpin.value() repsMax = self.upperSpin.value() return "{{{0:d},{1:d}}}{2}".format(repsMin, repsMax, minimal) eric-6.0.8/eric/Plugins/WizardPlugins/PyRegExpWizard/__init__.py0000644000175000017500000000022712451233372023670 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Package implementing the Python re wizard. """ eric-6.0.8/eric/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.py0000644000175000017500000006561112451233372026145 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing the Python re wizard dialog. """ from __future__ import unicode_literals import os import re from PyQt5.QtCore import QFileInfo, pyqtSlot from PyQt5.QtGui import QClipboard, QTextCursor from PyQt5.QtWidgets import QWidget, QDialog, QInputDialog, QApplication, \ QDialogButtonBox, QVBoxLayout, QTableWidgetItem from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5MainWindow import E5MainWindow from .Ui_PyRegExpWizardDialog import Ui_PyRegExpWizardDialog import UI.PixmapCache import Utilities import Preferences class PyRegExpWizardWidget(QWidget, Ui_PyRegExpWizardDialog): """ Class implementing the Python re wizard dialog. """ def __init__(self, parent=None, fromEric=True): """ Constructor @param parent parent widget (QWidget) @param fromEric flag indicating a call from within eric6 """ super(PyRegExpWizardWidget, self).__init__(parent) self.setupUi(self) # initialize icons of the tool buttons self.commentButton.setIcon(UI.PixmapCache.getIcon("comment.png")) self.charButton.setIcon(UI.PixmapCache.getIcon("characters.png")) self.anycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) self.repeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) self.nonGroupButton.setIcon(UI.PixmapCache.getIcon("nongroup.png")) self.groupButton.setIcon(UI.PixmapCache.getIcon("group.png")) self.namedGroupButton.setIcon(UI.PixmapCache.getIcon("namedgroup.png")) self.namedReferenceButton.setIcon( UI.PixmapCache.getIcon("namedreference.png")) self.altnButton.setIcon(UI.PixmapCache.getIcon("altn.png")) self.beglineButton.setIcon(UI.PixmapCache.getIcon("begline.png")) self.endlineButton.setIcon(UI.PixmapCache.getIcon("endline.png")) self.wordboundButton.setIcon( UI.PixmapCache.getIcon("wordboundary.png")) self.nonwordboundButton.setIcon( UI.PixmapCache.getIcon("nonwordboundary.png")) self.poslookaheadButton.setIcon( UI.PixmapCache.getIcon("poslookahead.png")) self.neglookaheadButton.setIcon( UI.PixmapCache.getIcon("neglookahead.png")) self.poslookbehindButton.setIcon( UI.PixmapCache.getIcon("poslookbehind.png")) self.neglookbehindButton.setIcon( UI.PixmapCache.getIcon("neglookbehind.png")) self.undoButton.setIcon(UI.PixmapCache.getIcon("editUndo.png")) self.redoButton.setIcon(UI.PixmapCache.getIcon("editRedo.png")) self.namedGroups = re.compile(r"""\(?P<([^>]+)>""").findall self.saveButton = self.buttonBox.addButton( self.tr("Save"), QDialogButtonBox.ActionRole) self.saveButton.setToolTip( self.tr("Save the regular expression to a file")) self.loadButton = self.buttonBox.addButton( self.tr("Load"), QDialogButtonBox.ActionRole) self.loadButton.setToolTip( self.tr("Load a regular expression from a file")) self.validateButton = self.buttonBox.addButton( self.tr("Validate"), QDialogButtonBox.ActionRole) self.validateButton.setToolTip( self.tr("Validate the regular expression")) self.executeButton = self.buttonBox.addButton( self.tr("Execute"), QDialogButtonBox.ActionRole) self.executeButton.setToolTip( self.tr("Execute the regular expression")) self.nextButton = self.buttonBox.addButton( self.tr("Next match"), QDialogButtonBox.ActionRole) self.nextButton.setToolTip( self.tr("Show the next match of the regular expression")) self.nextButton.setEnabled(False) if fromEric: self.buttonBox.setStandardButtons( QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.copyButton = None else: self.copyButton = self.buttonBox.addButton( self.tr("Copy"), QDialogButtonBox.ActionRole) self.copyButton.setToolTip( self.tr("Copy the regular expression to the clipboard")) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.variableLabel.hide() self.variableLineEdit.hide() self.variableLine.hide() self.importCheckBox.hide() self.regexpTextEdit.setFocus() def __insertString(self, s, steps=0): """ Private method to insert a string into line edit and move cursor. @param s string to be inserted into the regexp line edit (string) @param steps number of characters to move the cursor (integer). Negative steps moves cursor back, positives forward. """ self.regexpTextEdit.insertPlainText(s) tc = self.regexpTextEdit.textCursor() if steps != 0: if steps < 0: act = QTextCursor.Left steps = abs(steps) else: act = QTextCursor.Right for i in range(steps): tc.movePosition(act) self.regexpTextEdit.setTextCursor(tc) @pyqtSlot() def on_commentButton_clicked(self): """ Private slot to handle the comment toolbutton. """ self.__insertString("(?#)", -1) @pyqtSlot() def on_anycharButton_clicked(self): """ Private slot to handle the any character toolbutton. """ self.__insertString(".") @pyqtSlot() def on_nonGroupButton_clicked(self): """ Private slot to handle the non group toolbutton. """ self.__insertString("(?:)", -1) @pyqtSlot() def on_groupButton_clicked(self): """ Private slot to handle the group toolbutton. """ self.__insertString("()", -1) @pyqtSlot() def on_namedGroupButton_clicked(self): """ Private slot to handle the named group toolbutton. """ self.__insertString("(?P<>)", -2) @pyqtSlot() def on_namedReferenceButton_clicked(self): """ Private slot to handle the named reference toolbutton. """ # determine cursor position as length into text length = self.regexpTextEdit.textCursor().position() # only present group names that occur before the # current cursor position regex = self.regexpTextEdit.toPlainText()[:length] names = self.namedGroups(regex) if not names: E5MessageBox.information( self, self.tr("Named reference"), self.tr("""No named groups have been defined yet.""")) return groupName, ok = QInputDialog.getItem( self, self.tr("Named reference"), self.tr("Select group name:"), names, 0, True) if ok and groupName: self.__insertString("(?P={0})".format(groupName)) @pyqtSlot() def on_altnButton_clicked(self): """ Private slot to handle the alternatives toolbutton. """ self.__insertString("(|)", -2) @pyqtSlot() def on_beglineButton_clicked(self): """ Private slot to handle the begin line toolbutton. """ self.__insertString("^") @pyqtSlot() def on_endlineButton_clicked(self): """ Private slot to handle the end line toolbutton. """ self.__insertString("$") @pyqtSlot() def on_wordboundButton_clicked(self): """ Private slot to handle the word boundary toolbutton. """ self.__insertString("\\b") @pyqtSlot() def on_nonwordboundButton_clicked(self): """ Private slot to handle the non word boundary toolbutton. """ self.__insertString("\\B") @pyqtSlot() def on_poslookaheadButton_clicked(self): """ Private slot to handle the positive lookahead toolbutton. """ self.__insertString("(?=)", -1) @pyqtSlot() def on_neglookaheadButton_clicked(self): """ Private slot to handle the negative lookahead toolbutton. """ self.__insertString("(?!)", -1) @pyqtSlot() def on_poslookbehindButton_clicked(self): """ Private slot to handle the positive lookbehind toolbutton. """ self.__insertString("(?<=)", -1) @pyqtSlot() def on_neglookbehindButton_clicked(self): """ Private slot to handle the negative lookbehind toolbutton. """ self.__insertString("(?The file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return try: f = open( Utilities.toNativeSeparators(fname), "w", encoding="utf-8") f.write(self.regexpTextEdit.toPlainText()) f.close() except IOError as err: E5MessageBox.information( self, self.tr("Save regular expression"), self.tr("""

The regular expression could not""" """ be saved.

Reason: {0}

""") .format(str(err))) @pyqtSlot() def on_loadButton_clicked(self): """ Private slot to load a regexp from a file. """ fname = E5FileDialog.getOpenFileName( self, self.tr("Load regular expression"), "", self.tr("RegExp Files (*.rx);;All Files (*)")) if fname: try: f = open( Utilities.toNativeSeparators(fname), "r", encoding="utf-8") regexp = f.read() f.close() self.regexpTextEdit.setPlainText(regexp) except IOError as err: E5MessageBox.information( self, self.tr("Save regular expression"), self.tr("""

The regular expression could not""" """ be saved.

Reason: {0}

""") .format(str(err))) @pyqtSlot() def on_copyButton_clicked(self): """ Private slot to copy the regexp string into the clipboard. This slot is only available, if not called from within eric6. """ escaped = self.regexpTextEdit.toPlainText() if escaped: escaped = escaped.replace("\\", "\\\\") cb = QApplication.clipboard() cb.setText(escaped, QClipboard.Clipboard) if cb.supportsSelection(): cb.setText(escaped, QClipboard.Selection) @pyqtSlot() def on_validateButton_clicked(self): """ Private slot to validate the entered regexp. """ regex = self.regexpTextEdit.toPlainText() if regex: try: flags = 0 if not self.caseSensitiveCheckBox.isChecked(): flags |= re.IGNORECASE if self.multilineCheckBox.isChecked(): flags |= re.MULTILINE if self.dotallCheckBox.isChecked(): flags |= re.DOTALL if self.verboseCheckBox.isChecked(): flags |= re.VERBOSE if self.py2Button.isChecked(): if self.localeCheckBox.isChecked(): flags |= re.LOCALE if self.unicodeCheckBox.isChecked(): flags |= re.UNICODE else: if self.unicodeCheckBox.isChecked(): flags |= re.ASCII re.compile(regex, flags) E5MessageBox.information( self, self.tr("Validation"), self.tr("""The regular expression is valid.""")) except re.error as e: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: {0}""") .format(str(e))) return except IndexError: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: missing""" """ group name""")) return else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression must be given.""")) @pyqtSlot() def on_executeButton_clicked(self, startpos=0): """ Private slot to execute the entered regexp on the test text. This slot will execute the entered regexp on the entered test data and will display the result in the table part of the dialog. @param startpos starting position for the regexp matching """ regex = self.regexpTextEdit.toPlainText() text = self.textTextEdit.toPlainText() if regex and text: try: flags = 0 if not self.caseSensitiveCheckBox.isChecked(): flags |= re.IGNORECASE if self.multilineCheckBox.isChecked(): flags |= re.MULTILINE if self.dotallCheckBox.isChecked(): flags |= re.DOTALL if self.verboseCheckBox.isChecked(): flags |= re.VERBOSE if self.py2Button.isChecked(): if self.localeCheckBox.isChecked(): flags |= re.LOCALE if self.unicodeCheckBox.isChecked(): flags |= re.UNICODE else: if self.unicodeCheckBox.isChecked(): flags |= re.ASCII regobj = re.compile(regex, flags) matchobj = regobj.search(text, startpos) if matchobj is not None: captures = len(matchobj.groups()) if captures is None: captures = 0 else: captures = 0 row = 0 OFFSET = 5 self.resultTable.setColumnCount(0) self.resultTable.setColumnCount(3) self.resultTable.setRowCount(0) self.resultTable.setRowCount(OFFSET) self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Regexp"))) self.resultTable.setItem( row, 1, QTableWidgetItem(regex)) if matchobj is not None: offset = matchobj.start() self.lastMatchEnd = matchobj.end() self.nextButton.setEnabled(True) row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Offset"))) self.resultTable.setItem( row, 1, QTableWidgetItem("{0:d}".format(matchobj.start(0)))) row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Captures"))) self.resultTable.setItem( row, 1, QTableWidgetItem("{0:d}".format(captures))) row += 1 self.resultTable.setItem( row, 1, QTableWidgetItem(self.tr("Text"))) self.resultTable.setItem( row, 2, QTableWidgetItem(self.tr("Characters"))) row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Match"))) self.resultTable.setItem( row, 1, QTableWidgetItem(matchobj.group(0))) self.resultTable.setItem( row, 2, QTableWidgetItem( "{0:d}".format(len(matchobj.group(0))))) for i in range(1, captures + 1): if matchobj.group(i) is not None: row += 1 self.resultTable.insertRow(row) self.resultTable.setItem( row, 0, QTableWidgetItem( self.tr("Capture #{0}").format(i))) self.resultTable.setItem( row, 1, QTableWidgetItem(matchobj.group(i))) self.resultTable.setItem( row, 2, QTableWidgetItem( "{0:d}".format(len(matchobj.group(i))))) # highlight the matched text tc = self.textTextEdit.textCursor() tc.setPosition(offset) tc.setPosition(self.lastMatchEnd, QTextCursor.KeepAnchor) self.textTextEdit.setTextCursor(tc) else: self.nextButton.setEnabled(False) self.resultTable.setRowCount(2) row += 1 if startpos > 0: self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("No more matches"))) else: self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("No matches"))) # remove the highlight tc = self.textTextEdit.textCursor() tc.setPosition(0) self.textTextEdit.setTextCursor(tc) self.resultTable.resizeColumnsToContents() self.resultTable.resizeRowsToContents() self.resultTable.verticalHeader().hide() self.resultTable.horizontalHeader().hide() except re.error as e: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: {0}""") .format(str(e))) return except IndexError: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: missing""" """ group name""")) return else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression and a text must be""" """ given.""")) @pyqtSlot() def on_nextButton_clicked(self): """ Private slot to find the next match. """ self.on_executeButton_clicked(self.lastMatchEnd) @pyqtSlot() def on_regexpTextEdit_textChanged(self): """ Private slot called when the regexp changes. """ self.nextButton.setEnabled(False) @pyqtSlot(bool) def on_py2Button_toggled(self, checked): """ Private slot called when the Python version was selected. @param checked state of the Python 2 button (boolean) """ # set the checkboxes self.localeCheckBox.setEnabled(checked) if checked: self.unicodeCheckBox.setText(self.tr("Unicode")) else: self.unicodeCheckBox.setText(self.tr("ASCII")) self.unicodeCheckBox.setChecked(not self.unicodeCheckBox.isChecked()) # clear the result table self.resultTable.clear() self.resultTable.setColumnCount(0) self.resultTable.setRowCount(0) # remove the highlight tc = self.textTextEdit.textCursor() tc.setPosition(0) self.textTextEdit.setTextCursor(tc) def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate the indentation string istring = indLevel * indString i1string = (indLevel + 1) * indString estring = os.linesep + indLevel * indString # now generate the code reVar = self.variableLineEdit.text() if not reVar: reVar = "regexp" regexp = self.regexpTextEdit.toPlainText() flags = [] if not self.caseSensitiveCheckBox.isChecked(): flags.append('re.IGNORECASE') if self.multilineCheckBox.isChecked(): flags.append('re.MULTILINE') if self.dotallCheckBox.isChecked(): flags.append('re.DOTALL') if self.verboseCheckBox.isChecked(): flags.append('re.VERBOSE') if self.localeCheckBox.isChecked() and \ self.py2Button.isChecked(): flags.append('re.LOCALE') if self.unicodeCheckBox.isChecked(): if self.py2Button.isChecked(): flags.append('re.UNICODE') else: flags.append('re.ASCII') flags = " | ".join(flags) code = '' if self.importCheckBox.isChecked(): code += 'import re{0}{1}'.format(os.linesep, istring) code += '{0} = re.compile('.format(reVar) code += '{0}{1}r"""{2}"""'.format( os.linesep, i1string, regexp.replace('"', '\\"')) if flags: code += ',{0}{1}{2}'.format(os.linesep, i1string, flags) code += '){0}'.format(estring) return code class PyRegExpWizardDialog(QDialog): """ Class for the dialog variant. """ def __init__(self, parent=None, fromEric=True): """ Constructor @param parent parent widget (QWidget) @param fromEric flag indicating a call from within eric6 """ super(PyRegExpWizardDialog, self).__init__(parent) self.setModal(fromEric) self.setSizeGripEnabled(True) self.__layout = QVBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.__layout) self.cw = PyRegExpWizardWidget(self, fromEric) size = self.cw.size() self.__layout.addWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.cw.buttonBox.accepted.connect(self.accept) self.cw.buttonBox.rejected.connect(self.reject) def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ return self.cw.getCode(indLevel, indString) class PyRegExpWizardWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(PyRegExpWizardWindow, self).__init__(parent) self.cw = PyRegExpWizardWidget(self, fromEric=False) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.setStyle( Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw.buttonBox.accepted.connect(self.close) self.cw.buttonBox.rejected.connect(self.close) eric-6.0.8/eric/Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardCharactersDialog.py0000644000175000017500000002747412451233372030152 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog for entering character classes. """ from __future__ import unicode_literals from PyQt5.QtCore import QRegExp from PyQt5.QtGui import QRegExpValidator from PyQt5.QtWidgets import QSizePolicy, QSpacerItem, QWidget, QHBoxLayout, \ QLineEdit, QPushButton, QDialog, QScrollArea, QComboBox, QVBoxLayout, \ QLabel from .Ui_PyRegExpWizardCharactersDialog import \ Ui_PyRegExpWizardCharactersDialog class PyRegExpWizardCharactersDialog( QDialog, Ui_PyRegExpWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ specialChars = { 4: "\\a", 5: "\\f", 6: "\\n", 7: "\\r", 8: "\\t", 9: "\\v" } predefinedClasses = ["\\s", "\\S", "\\w", "\\W", "\\d", "\\D"] def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(PyRegExpWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append(self.tr("Normal character")) self.comboItems.append( self.tr("Unicode character in hexadecimal notation")) self.comboItems.append( self.tr("Unicode character in octal notation")) self.singleComboItems.append(self.tr("---")) self.singleComboItems.append(self.tr("Bell character (\\a)")) self.singleComboItems.append(self.tr("Page break (\\f)")) self.singleComboItems.append(self.tr("Line feed (\\n)")) self.singleComboItems.append(self.tr("Carriage return (\\r)")) self.singleComboItems.append(self.tr("Horizontal tabulator (\\t)")) self.singleComboItems.append(self.tr("Vertical tabulator (\\v)")) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton( self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton( self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) cb1.addItems(self.comboItems) cb1.addItems(self.singleComboItems) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb2 = QComboBox(hbox) cb2.setEditable(False) cb2.addItems(self.comboItems) cb2.addItems(self.singleComboItems) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1]) self.singlesEntries.append([cb2, le2]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) cb1.addItems(self.comboItems) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __performSelectedAction(self, index, lineedit): """ Private method performing some actions depending on the input. @param index selected list index (integer) @param lineedit line edit widget to act on (QLineEdit) """ if index < 3: lineedit.setEnabled(True) if index == 0: lineedit.setValidator(self.charValidator) elif index == 1: lineedit.setValidator(self.hexValidator) elif index == 2: lineedit.setValidator(self.octValidator) elif index > 3: lineedit.setEnabled(False) lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: self.__performSelectedAction(index, entriesList[1]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: self.__performSelectedAction(index, entriesList[1]) self.__performSelectedAction(index, entriesList[2]) break def __formatCharacter(self, index, char): """ Private method to format the characters entered into the dialog. @param index selected list index (integer) @param char character string enetered into the dialog (string) @return formated character string (string) """ if index == 0: return char elif index == 1: return "\\x{0}".format(char.lower()) elif index == 2: return "\\0{0}".format(char) else: try: return self.specialChars[index] except KeyError: return "" def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" # single characters for entrieslist in self.singlesEntries: index = entrieslist[0].currentIndex() char = entrieslist[1].text() regexp += self.__formatCharacter(index, char) # character ranges for entrieslist in self.rangesEntries: if entrieslist[1].text() == "" or \ entrieslist[2].text() == "": continue index = entrieslist[0].currentIndex() char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format( self.__formatCharacter(index, char1), self.__formatCharacter(index, char2)) if regexp: if (len(regexp) == 2 and (regexp in self.predefinedClasses or regexp in self.specialChars)) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return "" eric-6.0.8/eric/Plugins/WizardPlugins/__init__.py0000644000175000017500000000024012451233372020777 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the various core wizard plugins. """ eric-6.0.8/eric/Plugins/WizardPlugins/ColorDialogWizard/0000755000175000017500000000000012557365404022262 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/ColorDialogWizard/ColorDialogWizardDialog.py0000644000175000017500000001447012451233372027330 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the color dialog wizard dialog. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QColorDialog, QDialog, QDialogButtonBox from E5Gui import E5MessageBox from .Ui_ColorDialogWizardDialog import Ui_ColorDialogWizardDialog class ColorDialogWizardDialog(QDialog, Ui_ColorDialogWizardDialog): """ Class implementing the color dialog wizard dialog. It displays a dialog for entering the parameters for the QColorDialog code generator. """ def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(ColorDialogWizardDialog, self).__init__(parent) self.setupUi(self) self.bTest = self.buttonBox.addButton( self.tr("Test"), QDialogButtonBox.ActionRole) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.bTest: self.on_bTest_clicked() @pyqtSlot() def on_bTest_clicked(self): """ Private method to test the selected options. """ if self.rColor.isChecked(): if not self.eColor.currentText(): QColorDialog.getColor() else: coStr = self.eColor.currentText() if coStr.startswith('#'): coStr = "QColor('{0}')".format(coStr) else: coStr = "QColor({0})".format(coStr) try: exec('from PyQt5.QtCore import Qt;' ' QColorDialog.getColor({0}, None, "{1}")'.format( coStr, self.eTitle.text())) except: E5MessageBox.critical( self, self.tr("QColorDialog Wizard Error"), self.tr( """

The colour {0} is not valid.

""") .format(coStr)) elif self.rRGBA.isChecked(): QColorDialog.getColor( QColor(self.sRed.value(), self.sGreen.value(), self.sBlue.value(), self.sAlpha.value()), None, self.eTitle.text(), QColorDialog.ColorDialogOptions(QColorDialog.ShowAlphaChannel)) def on_eRGB_textChanged(self, text): """ Private slot to handle the textChanged signal of eRGB. @param text the new text (string) """ if not text: self.sRed.setEnabled(True) self.sGreen.setEnabled(True) self.sBlue.setEnabled(True) self.sAlpha.setEnabled(True) self.bTest.setEnabled(True) else: self.sRed.setEnabled(False) self.sGreen.setEnabled(False) self.sBlue.setEnabled(False) self.sAlpha.setEnabled(False) self.bTest.setEnabled(False) def on_eColor_editTextChanged(self, text): """ Private slot to handle the editTextChanged signal of eColor. @param text the new text (string) """ if not text or text.startswith('Qt.') or text.startswith('#'): self.bTest.setEnabled(True) else: self.bTest.setEnabled(False) def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate our indentation level and the indentation string il = indLevel + 1 istring = il * indString estring = os.linesep + indLevel * indString # now generate the code if self.parentSelf.isChecked(): parent = "self" elif self.parentNone.isChecked(): parent = "None" elif self.parentOther.isChecked(): parent = self.parentEdit.text() if parent == "": parent = "None" resvar = self.eResultVar.text() if not resvar: resvar = "color" code = '{0} = QColorDialog.'.format(resvar) if self.rColor.isChecked(): code += 'getColor({0}'.format(os.linesep) if self.eColor.currentText(): col = self.eColor.currentText() if col.startswith('#'): code += '{0}QColor("{1}"),{2}'.format( istring, col, os.linesep) else: code += '{0}QColor({1}),{2}'.format( istring, col, os.linesep) else: code += '{0}QColor(Qt.white),{1}'.format(istring, os.linesep) code += '{0}{1},{2}'.format(istring, parent, os.linesep) code += '{0}self.tr("{1}"),{2}'.format( istring, self.eTitle.text(), os.linesep) code += '{0}QColorDialog.ColorDialogOptions(' \ 'QColorDialog.ShowAlphaChannel)'.format(istring) code += '){0}'.format(estring) elif self.rRGBA.isChecked(): code += 'getColor({0}'.format(os.linesep) if not self.eRGB.text(): code += '{0}QColor({1:d}, {2:d}, {3:d}, {4:d}),{5}'.format( istring, self.sRed.value(), self.sGreen.value(), self.sBlue.value(), self.sAlpha.value(), os.linesep) else: code += '{0}{1},{2}'.format( istring, self.eRGB.text(), os.linesep) code += '{0}{1},{2}'.format(istring, parent, os.linesep) code += '{0}self.tr("{1}"),{2}'.format( istring, self.eTitle.text(), os.linesep) code += '{0}QColorDialog.ColorDialogOptions(' \ 'QColorDialog.ShowAlphaChannel)'.format(istring) code += '){0}'.format(estring) return code eric-6.0.8/eric/Plugins/WizardPlugins/ColorDialogWizard/__init__.py0000644000175000017500000000023212451233372024357 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Package implementing the color dialog wizard. """ eric-6.0.8/eric/Plugins/WizardPlugins/ColorDialogWizard/ColorDialogWizardDialog.ui0000644000175000017500000003107012247413640027311 0ustar piotrpiotr ColorDialogWizardDialog 0 0 381 481 QColorDialog Wizard true Type Select to generate a QColorDialog.getColor dialog Colour true Select to generate a QColorDialog.getRgba dialog RGBA Result Enter the result variable name Title Enter the dialog title Parent Select "self" as parent self true Select "None" as parent None Select to enter a parent expression Expression: false Enter the parent expression Colour 0 0 Enter a variable name or a colour true Qt.red Qt.darkRed Qt.green Qt.darkGreen Qt.blue Qt.darkBlue Qt.cyan Qt.darkCyan Qt.magenta Qt.darkMagenta Qt.yellow Qt.darkYellow Qt.white Qt.lightGray Qt.gray Qt.darkGray Qt.black Qt.transparent Qt.color0 Qt.color1 false RGBA 6 Enter a variable name Colour Variable Enter the alpha value 255 Enter the blue value 255 128 Enter the green value 255 128 Enter the red value 255 128 Alpha Blue Red Green Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource rColor rRGBA eResultVar eTitle parentSelf parentNone parentOther parentEdit eColor sRed sGreen sBlue sAlpha eRGB buttonBox rColor toggled(bool) groupBox_2 setEnabled(bool) 38 35 45 319 rRGBA toggled(bool) groupBox_3 setEnabled(bool) 212 38 218 442 buttonBox accepted() ColorDialogWizardDialog accept() 29 471 20 280 buttonBox rejected() ColorDialogWizardDialog reject() 85 471 76 278 parentOther toggled(bool) parentEdit setEnabled(bool) 82 241 122 240 eric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/0000755000175000017500000000000012557365404023666 5ustar piotrpiotr././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrooteric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardCharactersDialog.pyeric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardCharactersDia0000644000175000017500000006010012451233372033176 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a dialog for entering character classes. """ from __future__ import unicode_literals from PyQt5.QtCore import QRegExp from PyQt5.QtGui import QRegExpValidator from PyQt5.QtWidgets import QWidget, QDialog, QVBoxLayout, QHBoxLayout, \ QScrollArea, QPushButton, QSpacerItem, QSizePolicy, QComboBox, QLineEdit, \ QLabel from .Ui_QRegularExpressionWizardCharactersDialog import \ Ui_QRegularExpressionWizardCharactersDialog class QRegularExpressionWizardCharactersDialog( QDialog, Ui_QRegularExpressionWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(QRegularExpressionWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.__initCharacterSelectors() self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append((self.tr("Normal character"), "-c")) self.comboItems.append((self.tr( "Unicode character in hexadecimal notation"), "-h")) self.comboItems.append((self.tr( "ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.extend([ ("---", "-i"), (self.tr("Bell character (\\a)"), "\\a"), (self.tr("Escape character (\\e)"), "\\e"), (self.tr("Page break (\\f)"), "\\f"), (self.tr("Line feed (\\n)"), "\\n"), (self.tr("Carriage return (\\r)"), "\\r"), (self.tr("Horizontal tabulator (\\t)"), "\\t"), ("---", "-i"), (self.tr("Character Category"), "-ccp"), (self.tr("Special Character Category"), "-csp"), (self.tr("Character Block"), "-cbp"), (self.tr("POSIX Named Set"), "-psp"), (self.tr("Not Character Category"), "-ccn"), (self.tr("Not Character Block"), "-cbn"), (self.tr("Not Special Character Category"), "-csn"), (self.tr("Not POSIX Named Set"), "-psn"), ]) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBox.setMinimumWidth(1000) self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton( self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBox.setMinimumWidth(1000) self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton( self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __initCharacterSelectors(self): """ Private method to initialize the W3C character selector entries. """ self.__characterCategories = ( # display name code (self.tr("Letter, Any"), "L"), (self.tr("Letter, Lower case"), "Ll"), (self.tr("Letter, Modifier"), "Lm"), (self.tr("Letter, Other"), "Lo"), (self.tr("Letter, Title case"), "Lt"), (self.tr("Letter, Upper case"), "Lu"), (self.tr("Letter, Lower, Upper or Title"), "L&"), (self.tr("Mark, Any"), "M"), (self.tr("Mark, Spacing"), "Mc"), (self.tr("Mark, Enclosing"), "Me"), (self.tr("Mark, Non-spacing"), "Mn"), (self.tr("Number, Any"), "N"), (self.tr("Number, Decimal"), "Nd"), (self.tr("Number, Letter"), "Nl"), (self.tr("Number, Other"), "No"), (self.tr("Punctuation, Any"), "P"), (self.tr("Punctuation, Connector"), "Pc"), (self.tr("Punctuation, Dash"), "Pd"), (self.tr("Punctuation, Close"), "Pe"), (self.tr("Punctuation, Final"), "Pf"), (self.tr("Punctuation, Initial"), "Pi"), (self.tr("Punctuation, Other"), "Po"), (self.tr("Punctuation, Open"), "Ps"), (self.tr("Symbol, Any"), "S"), (self.tr("Symbol, Currency"), "Sc"), (self.tr("Symbol, Modifier"), "Sk"), (self.tr("Symbol, Mathematical"), "Sm"), (self.tr("Symbol, Other"), "So"), (self.tr("Separator, Any"), "Z"), (self.tr("Separator, Line"), "Zl"), (self.tr("Separator, Paragraph"), "Zp"), (self.tr("Separator, Space"), "Zs"), (self.tr("Other, Any"), "C"), (self.tr("Other, Control"), "Cc"), (self.tr("Other, Format"), "Cf"), (self.tr("Other, Unassigned"), "Cn"), (self.tr("Other, Private Use"), "Co"), (self.tr("Other, Surrogat"), "Cn"), ) self.__specialCharacterCategories = ( # display name code (self.tr("Alphanumeric"), "Xan"), (self.tr("POSIX Space"), "Xps"), (self.tr("Perl Space"), "Xsp"), (self.tr("Universal Character"), "Xuc"), (self.tr("Perl Word"), "Xan"), ) self.__characterBlocks = ( # display name code (self.tr("Arabic"), "Arabic"), (self.tr("Armenian"), "Armenian"), (self.tr("Avestan"), "Avestan"), (self.tr("Balinese"), "Balinese"), (self.tr("Bamum"), "Bamum"), (self.tr("Batak"), "Batak"), (self.tr("Bengali"), "Bengali"), (self.tr("Bopomofo"), "Bopomofo"), (self.tr("Brahmi"), "Brahmi"), (self.tr("Braille"), "Braille"), (self.tr("Buginese"), "Buginese"), (self.tr("Buhid"), "Buhid"), (self.tr("Canadian Aboriginal"), "Canadian_Aboriginal"), (self.tr("Carian"), "Carian"), (self.tr("Chakma"), "Chakma"), (self.tr("Cham"), "Cham"), (self.tr("Cherokee"), "Cherokee"), (self.tr("Common"), "Common"), (self.tr("Coptic"), "Coptic"), (self.tr("Cuneiform"), "Cuneiform"), (self.tr("Cypriot"), "Cypriot"), (self.tr("Cyrillic"), "Cyrillic"), (self.tr("Deseret"), "Deseret,"), (self.tr("Devanagari"), "Devanagari"), (self.tr("Egyptian Hieroglyphs"), "Egyptian_Hieroglyphs"), (self.tr("Ethiopic"), "Ethiopic"), (self.tr("Georgian"), "Georgian"), (self.tr("Glagolitic"), "Glagolitic"), (self.tr("Gothic"), "Gothic"), (self.tr("Greek"), "Greek"), (self.tr("Gujarati"), "Gujarati"), (self.tr("Gurmukhi"), "Gurmukhi"), (self.tr("Han"), "Han"), (self.tr("Hangul"), "Hangul"), (self.tr("Hanunoo"), "Hanunoo"), (self.tr("Hebrew"), "Hebrew"), (self.tr("Hiragana"), "Hiragana"), (self.tr("Imperial Aramaic"), "Imperial_Aramaic"), (self.tr("Inherited"), "Inherited"), (self.tr("Inscriptional Pahlavi"), "Inscriptional_Pahlavi"), (self.tr("Inscriptional Parthian"), "Inscriptional_Parthian"), (self.tr("Javanese"), "Javanese"), (self.tr("Kaithi"), "Kaithi"), (self.tr("Kannada"), "Kannada"), (self.tr("Katakana"), "Katakana"), (self.tr("Kayah Li"), "Kayah_Li"), (self.tr("Kharoshthi"), "Kharoshthi"), (self.tr("Khmer"), "Khmer"), (self.tr("Lao"), "Lao"), (self.tr("Latin"), "Latin"), (self.tr("Lepcha"), "Lepcha"), (self.tr("Limbu"), "Limbu"), (self.tr("Linear B"), "Linear_B"), (self.tr("Lisu"), "Lisu"), (self.tr("Lycian"), "Lycian"), (self.tr("Lydian"), "Lydian"), (self.tr("Malayalam"), "Malayalam"), (self.tr("Mandaic"), "Mandaic"), (self.tr("Meetei Mayek"), "Meetei_Mayek"), (self.tr("Meroitic Cursive"), "Meroitic_Cursive"), (self.tr("Meroitic Hieroglyphs"), "Meroitic_Hieroglyphs"), (self.tr("Miao"), "Miao"), (self.tr("Mongolian"), "Mongolian"), (self.tr("Myanmar"), "Myanmar"), (self.tr("New Tai Lue"), "New_Tai_Lue"), (self.tr("N'Ko"), "Nko"), (self.tr("Ogham"), "Ogham"), (self.tr("Old Italic"), "Old_Italic"), (self.tr("Old Persian"), "Old_Persian"), (self.tr("Old South Arabian"), "Old_South_Arabian"), (self.tr("Old Turkic"), "Old_Turkic,"), (self.tr("Ol Chiki"), "Ol_Chiki"), (self.tr("Oriya"), "Oriya"), (self.tr("Osmanya"), "Osmanya"), (self.tr("Phags-pa"), "Phags_Pa"), (self.tr("Phoenician"), "Phoenician"), (self.tr("Rejang"), "Rejang"), (self.tr("Runic"), "Runic"), (self.tr("Samaritan"), "Samaritan"), (self.tr("Saurashtra"), "Saurashtra"), (self.tr("Sharada"), "Sharada"), (self.tr("Shavian"), "Shavian"), (self.tr("Sinhala"), "Sinhala"), (self.tr("Sora Sompeng"), "Sora_Sompeng"), (self.tr("Sundanese"), "Sundanese"), (self.tr("Syloti Nagri"), "Syloti_Nagri"), (self.tr("Syriac"), "Syriac"), (self.tr("Tagalog"), "Tagalog"), (self.tr("Tagbanwa"), "Tagbanwa"), (self.tr("Tai Le"), "Tai_Le"), (self.tr("Tai Tham"), "Tai_Tham"), (self.tr("Tai Viet"), "Tai_Viet"), (self.tr("Takri"), "Takri"), (self.tr("Tamil"), "Tamil"), (self.tr("Telugu"), "Telugu"), (self.tr("Thaana"), "Thaana"), (self.tr("Thai"), "Thai"), (self.tr("Tibetan"), "Tibetan"), (self.tr("Tifinagh"), "Tifinagh"), (self.tr("Ugaritic"), "Ugaritic"), (self.tr("Vai"), "Vai"), (self.tr("Yi"), "Yi"), ) self.__posixNamedSets = ( # display name code (self.tr("Alphanumeric"), "alnum"), (self.tr("Alphabetic"), "alpha"), (self.tr("ASCII"), "ascii"), (self.tr("Word Letter"), "word"), (self.tr("Lower Case Letter"), "lower"), (self.tr("Upper Case Letter"), "upper"), (self.tr("Decimal Digit"), "digit"), (self.tr("Hexadecimal Digit"), "xdigit"), (self.tr("Space or Tab"), "blank"), (self.tr("White Space"), "space"), (self.tr("Printing (excl. space)"), "graph"), (self.tr("Printing (incl. space)"), "print"), (self.tr("Printing (excl. alphanumeric)"), "punct"), (self.tr("Control Character"), "cntrl"), ) def __populateCharTypeCombo(self, combo, isSingle): """ Private method to populate a given character type selection combo box. @param combo reference to the combo box to be populated (QComboBox) @param isSingle flag indicating a singles combo (boolean) """ for txt, value in self.comboItems: combo.addItem(txt, value) if isSingle: for txt, value in self.singleComboItems: combo.addItem(txt, value) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, True) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb1a = QComboBox(hbox) cb1a.setEditable(False) cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb1a) cb1a.hide() cb2 = QComboBox(hbox) cb2.setEditable(False) self.__populateCharTypeCombo(cb2, True) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) cb2a = QComboBox(hbox) cb2a.setEditable(False) cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb2a) cb2a.hide() self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1, cb1a]) self.singlesEntries.append([cb2, le2, cb2a]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, False) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __populateCharacterCombo(self, combo, format): """ Private method to populate a character selection combo. @param combo combo box to be populated (QComboBox) @param format format identifier (one of "-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn") """ combo.clear() if format in ["-ccp", "-ccn"]: items = self.__characterCategories elif format in ["-csp", "-csn"]: items = self.__specialCharacterCategories elif format in ["-cbp", "-cbn"]: items = self.__characterBlocks elif format in ["-psp", "-psn"]: items = self.__posixNamedSets comboLen = 0 for txt, code in items: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) def __performSelectedAction(self, format, lineedit, combo): """ Private method performing some actions depending on the input. @param format format of the selected entry (string) @param lineedit line edit widget to act on (QLineEdit) @param combo combo box widget to act on (QComboBox) """ if format == "-i": return if format in ["-c", "-h", "-o"]: lineedit.show() lineedit.setEnabled(True) if combo is not None: combo.hide() if format == "-c": lineedit.setValidator(self.charValidator) elif format == "-h": lineedit.setValidator(self.hexValidator) elif format == "-o": lineedit.setValidator(self.octValidator) elif format in ["-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn"]: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.show() self.__populateCharacterCombo(combo, format) else: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.hide() lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction( format, entriesList[1], entriesList[2]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction(format, entriesList[1], None) self.__performSelectedAction(format, entriesList[2], None) break def __formatCharacter(self, char, format): """ Private method to format the characters entered into the dialog. @param char character string entered into the dialog (string) @param format string giving a special format (-c, -h, -i or -o) or the already formatted character (string) @return formatted character string (string) """ if format == "-c": return char elif format == "-i": return "" if format == "-h": while len(char) < 2: char = "0" + char if len(char) > 2: return "\\x{{{0}}}".format(char.lower()) else: return "\\x{0}".format(char.lower()) elif format == "-o": while len(char) < 3: char = "0" + char if len(char) > 3: char = char[:3] return "\\{0}".format(char) elif format in ["-ccp", "-cbp", "-csp"]: return "\\p{{{0}}}".format(char) elif format in ["-ccn", "-cbn", "-csn"]: return "\\P{{{0}}}".format(char) elif format == "-psp": return "[:{0}:]".format(char) elif format == "-psn": return "[:^{0}:]".format(char) else: return format def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.newlineCheckBox.isChecked(): regexp += "\\R" if self.nonNewlineCheckBox.isChecked(): regexp += "\\N" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" if self.horizontalWhitespaceCheckBox.isChecked(): regexp += "\\h" if self.nonHorizontalWhitespaceCheckBox.isChecked(): regexp += "\\H" if self.verticalWhitespaceCheckBox.isChecked(): regexp += "\\v" if self.nonVerticalWhitespaceCheckBox.isChecked(): regexp += "\\V" # single characters for entrieslist in self.singlesEntries: format = entrieslist[0].itemData(entrieslist[0].currentIndex()) if format in ["-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn"]: char = entrieslist[2].itemData(entrieslist[2].currentIndex()) else: char = entrieslist[1].text() regexp += self.__formatCharacter(char, format) # character ranges for entrieslist in self.rangesEntries: if not entrieslist[1].text() or \ not entrieslist[2].text(): continue format = entrieslist[0].itemData(entrieslist[0].currentIndex()) char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format( self.__formatCharacter(char1, format), self.__formatCharacter(char2, format)) if regexp: if (regexp.startswith("\\") and regexp.count("\\") == 1 and "-" not in regexp) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return "" ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrooteric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardCharactersDialog.uieric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardCharactersDia0000644000175000017500000001407612161335624033212 0ustar piotrpiotr QRegularExpressionWizardCharactersDialog 0 0 850 500 Editor for character sets true The defined characters should not match Predefined character ranges Word character Digit Newline Non-word character Non-digit Non-newline Whitespace character Horizontal whitespace character Vertical whitespace character Non-whitespace character Non-horizontal whitespace character Non-vertical whitespace character 0 0 Single character 0 0 Character ranges Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource negativeCheckBox wordCharCheckBox nonWordCharCheckBox digitsCheckBox nonDigitsCheckBox newlineCheckBox nonNewlineCheckBox whitespaceCheckBox nonWhitespaceCheckBox horizontalWhitespaceCheckBox nonHorizontalWhitespaceCheckBox verticalWhitespaceCheckBox nonVerticalWhitespaceCheckBox buttonBox buttonBox accepted() QRegularExpressionWizardCharactersDialog accept() 157 476 157 498 buttonBox rejected() QRegularExpressionWizardCharactersDialog reject() 269 477 269 499 eric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardDialog.py0000644000175000017500000010126612451233372032340 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing the QRegularExpression wizard dialog. """ from __future__ import unicode_literals import os import re import sys import json from PyQt5.QtCore import QFileInfo, pyqtSlot, QProcess, QByteArray from PyQt5.QtGui import QClipboard, QTextCursor from PyQt5.QtWidgets import QWidget, QDialog, QInputDialog, QApplication, \ QDialogButtonBox, QVBoxLayout, QTableWidgetItem from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5MainWindow import E5MainWindow from .Ui_QRegularExpressionWizardDialog import \ Ui_QRegularExpressionWizardDialog import UI.PixmapCache import Utilities import Preferences class QRegularExpressionWizardWidget(QWidget, Ui_QRegularExpressionWizardDialog): """ Class implementing the QRegularExpression wizard dialog. """ def __init__(self, parent=None, fromEric=True): """ Constructor @param parent parent widget (QWidget) @param fromEric flag indicating a call from within eric6 """ super(QRegularExpressionWizardWidget, self).__init__(parent) self.setupUi(self) # initialize icons of the tool buttons self.commentButton.setIcon(UI.PixmapCache.getIcon("comment.png")) self.charButton.setIcon(UI.PixmapCache.getIcon("characters.png")) self.anycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) self.repeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) self.nonGroupButton.setIcon(UI.PixmapCache.getIcon("nongroup.png")) self.atomicGroupButton.setIcon( UI.PixmapCache.getIcon("atomicgroup.png")) self.groupButton.setIcon(UI.PixmapCache.getIcon("group.png")) self.namedGroupButton.setIcon(UI.PixmapCache.getIcon("namedgroup.png")) self.namedReferenceButton.setIcon( UI.PixmapCache.getIcon("namedreference.png")) self.altnButton.setIcon(UI.PixmapCache.getIcon("altn.png")) self.beglineButton.setIcon(UI.PixmapCache.getIcon("begline.png")) self.endlineButton.setIcon(UI.PixmapCache.getIcon("endline.png")) self.wordboundButton.setIcon( UI.PixmapCache.getIcon("wordboundary.png")) self.nonwordboundButton.setIcon( UI.PixmapCache.getIcon("nonwordboundary.png")) self.poslookaheadButton.setIcon( UI.PixmapCache.getIcon("poslookahead.png")) self.neglookaheadButton.setIcon( UI.PixmapCache.getIcon("neglookahead.png")) self.poslookbehindButton.setIcon( UI.PixmapCache.getIcon("poslookbehind.png")) self.neglookbehindButton.setIcon( UI.PixmapCache.getIcon("neglookbehind.png")) self.undoButton.setIcon(UI.PixmapCache.getIcon("editUndo.png")) self.redoButton.setIcon(UI.PixmapCache.getIcon("editRedo.png")) self.namedGroups = re.compile(r"""\(?P<([^>]+)>""").findall # start the PyQt5 server part self.__pyqt5Available = False self.__pyqt5Server = QProcess(self) self.__pyqt5Server.start( sys.executable, [os.path.join( os.path.dirname(__file__), "QRegularExpressionWizardServer.py") ]) if self.__pyqt5Server.waitForStarted(5000): self.__pyqt5Server.setReadChannel(QProcess.StandardOutput) if self.__sendCommand("available"): response = self.__receiveResponse() if response and response["available"]: self.__pyqt5Available = True self.saveButton = self.buttonBox.addButton( self.tr("Save"), QDialogButtonBox.ActionRole) self.saveButton.setToolTip( self.tr("Save the regular expression to a file")) self.loadButton = self.buttonBox.addButton( self.tr("Load"), QDialogButtonBox.ActionRole) self.loadButton.setToolTip( self.tr("Load a regular expression from a file")) if self.__pyqt5Available: self.validateButton = self.buttonBox.addButton( self.tr("Validate"), QDialogButtonBox.ActionRole) self.validateButton.setToolTip( self.tr("Validate the regular expression")) self.executeButton = self.buttonBox.addButton( self.tr("Execute"), QDialogButtonBox.ActionRole) self.executeButton.setToolTip( self.tr("Execute the regular expression")) self.nextButton = self.buttonBox.addButton( self.tr("Next match"), QDialogButtonBox.ActionRole) self.nextButton.setToolTip( self.tr("Show the next match of the regular expression")) self.nextButton.setEnabled(False) else: self.validateButton = None self.executeButton = None self.nextButton = None if fromEric: self.buttonBox.setStandardButtons( QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.copyButton = None else: self.copyButton = self.buttonBox.addButton( self.tr("Copy"), QDialogButtonBox.ActionRole) self.copyButton.setToolTip( self.tr("Copy the regular expression to the clipboard")) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.variableLabel.hide() self.variableLineEdit.hide() self.variableLine.hide() self.regexpTextEdit.setFocus() def __sendCommand(self, command, **kw): """ Private method to send a command to the PyQt5 server. @param command dictionary with command string and related data (dict) @keyparam kw parameters for the command @return flag indicating a successful transmission (boolean) """ result = False if command: commandDict = {"command": command} commandDict.update(kw) commandStr = json.dumps(commandDict) + "\n" data = QByteArray(commandStr.encode("utf-8")) self.__pyqt5Server.write(data) result = self.__pyqt5Server.waitForBytesWritten(10000) return result def __receiveResponse(self): """ Private method to receive a response from the PyQt5 server. @return response dictionary (dict) """ responseDict = {} if self.__pyqt5Server.waitForReadyRead(10000): data = bytes(self.__pyqt5Server.readAllStandardOutput()) responseStr = data.decode("utf-8") responseDict = json.loads(responseStr) if responseDict["error"]: E5MessageBox.critical( self, self.tr("Communication Error"), self.tr("""

The PyQt5 backend reported""" """ an error.

{0}

""") .format(responseDict["error"])) responseDict = {} return responseDict def shutdown(self): """ Public method to shut down the PyQt5 server part. """ self.__sendCommand("exit") self.__pyqt5Server.waitForFinished(5000) def __insertString(self, s, steps=0): """ Private method to insert a string into line edit and move cursor. @param s string to be inserted into the regexp line edit (string) @param steps number of characters to move the cursor (integer). Negative steps moves cursor back, positives forward. """ self.regexpTextEdit.insertPlainText(s) tc = self.regexpTextEdit.textCursor() if steps != 0: if steps < 0: act = QTextCursor.Left steps = abs(steps) else: act = QTextCursor.Right for i in range(steps): tc.movePosition(act) self.regexpTextEdit.setTextCursor(tc) @pyqtSlot() def on_commentButton_clicked(self): """ Private slot to handle the comment toolbutton. """ self.__insertString("(?#)", -1) @pyqtSlot() def on_charButton_clicked(self): """ Private slot to handle the characters toolbutton. """ from .QRegularExpressionWizardCharactersDialog import \ QRegularExpressionWizardCharactersDialog dlg = QRegularExpressionWizardCharactersDialog(self) if dlg.exec_() == QDialog.Accepted: self.__insertString(dlg.getCharacters()) @pyqtSlot() def on_anycharButton_clicked(self): """ Private slot to handle the any character toolbutton. """ self.__insertString(".") @pyqtSlot() def on_repeatButton_clicked(self): """ Private slot to handle the repeat toolbutton. """ from .QRegularExpressionWizardRepeatDialog import \ QRegularExpressionWizardRepeatDialog dlg = QRegularExpressionWizardRepeatDialog(self) if dlg.exec_() == QDialog.Accepted: self.__insertString(dlg.getRepeat()) @pyqtSlot() def on_nonGroupButton_clicked(self): """ Private slot to handle the non group toolbutton. """ self.__insertString("(?:)", -1) @pyqtSlot() def on_atomicGroupButton_clicked(self): """ Private slot to handle the atomic non group toolbutton. """ self.__insertString("(?>)", -1) @pyqtSlot() def on_groupButton_clicked(self): """ Private slot to handle the group toolbutton. """ self.__insertString("()", -1) @pyqtSlot() def on_namedGroupButton_clicked(self): """ Private slot to handle the named group toolbutton. """ self.__insertString("(?P<>)", -2) @pyqtSlot() def on_namedReferenceButton_clicked(self): """ Private slot to handle the named reference toolbutton. """ # determine cursor position as length into text length = self.regexpTextEdit.textCursor().position() # only present group names that occur before the current # cursor position regex = self.regexpTextEdit.toPlainText()[:length] names = self.namedGroups(regex) if not names: E5MessageBox.information( self, self.tr("Named reference"), self.tr("""No named groups have been defined yet.""")) return groupName, ok = QInputDialog.getItem( self, self.tr("Named reference"), self.tr("Select group name:"), names, 0, True) if ok and groupName: self.__insertString("(?P={0})".format(groupName)) @pyqtSlot() def on_altnButton_clicked(self): """ Private slot to handle the alternatives toolbutton. """ self.__insertString("(|)", -2) @pyqtSlot() def on_beglineButton_clicked(self): """ Private slot to handle the begin line toolbutton. """ self.__insertString("^") @pyqtSlot() def on_endlineButton_clicked(self): """ Private slot to handle the end line toolbutton. """ self.__insertString("$") @pyqtSlot() def on_wordboundButton_clicked(self): """ Private slot to handle the word boundary toolbutton. """ self.__insertString("\\b") @pyqtSlot() def on_nonwordboundButton_clicked(self): """ Private slot to handle the non word boundary toolbutton. """ self.__insertString("\\B") @pyqtSlot() def on_poslookaheadButton_clicked(self): """ Private slot to handle the positive lookahead toolbutton. """ self.__insertString("(?=)", -1) @pyqtSlot() def on_neglookaheadButton_clicked(self): """ Private slot to handle the negative lookahead toolbutton. """ self.__insertString("(?!)", -1) @pyqtSlot() def on_poslookbehindButton_clicked(self): """ Private slot to handle the positive lookbehind toolbutton. """ self.__insertString("(?<=)", -1) @pyqtSlot() def on_neglookbehindButton_clicked(self): """ Private slot to handle the negative lookbehind toolbutton. """ self.__insertString("(?The file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return try: f = open( Utilities.toNativeSeparators(fname), "w", encoding="utf-8") f.write(self.regexpTextEdit.toPlainText()) f.close() except IOError as err: E5MessageBox.information( self, self.tr("Save regular expression"), self.tr("""

The regular expression could not""" """ be saved.

Reason: {0}

""") .format(str(err))) @pyqtSlot() def on_loadButton_clicked(self): """ Private slot to load a QRegularExpression from a file. """ fname = E5FileDialog.getOpenFileName( self, self.tr("Load regular expression"), "", self.tr("RegExp Files (*.rx);;All Files (*)")) if fname: try: f = open( Utilities.toNativeSeparators(fname), "r", encoding="utf-8") regexp = f.read() f.close() self.regexpTextEdit.setPlainText(regexp) except IOError as err: E5MessageBox.information( self, self.tr("Save regular expression"), self.tr("""

The regular expression could not""" """ be saved.

Reason: {0}

""") .format(str(err))) @pyqtSlot() def on_copyButton_clicked(self): """ Private slot to copy the QRegularExpression string into the clipboard. This slot is only available, if not called from within eric6. """ escaped = self.regexpTextEdit.toPlainText() if escaped: escaped = escaped.replace("\\", "\\\\") cb = QApplication.clipboard() cb.setText(escaped, QClipboard.Clipboard) if cb.supportsSelection(): cb.setText(escaped, QClipboard.Selection) @pyqtSlot() def on_validateButton_clicked(self): """ Private slot to validate the entered QRegularExpression. """ if not self.__pyqt5Available: # only available for PyQt5 return regexp = self.regexpTextEdit.toPlainText() if regexp: options = [] if self.caseInsensitiveCheckBox.isChecked(): options.append("CaseInsensitiveOption") if self.multilineCheckBox.isChecked(): options.append("MultilineOption") if self.dotallCheckBox.isChecked(): options.append("DotMatchesEverythingOption") if self.extendedCheckBox.isChecked(): options.append("ExtendedPatternSyntaxOption") if self.greedinessCheckBox.isChecked(): options.append("InvertedGreedinessOption") if self.unicodeCheckBox.isChecked(): options.append("UseUnicodePropertiesOption") if self.captureCheckBox.isChecked(): options.append("DontCaptureOption") if self.__sendCommand("validate", options=options, regexp=regexp): response = self.__receiveResponse() if response and "valid" in response: if response["valid"]: E5MessageBox.information( self, self.tr("Validation"), self.tr( """The regular expression is valid.""")) else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: {0}""") .format(response["errorMessage"])) # move cursor to error offset offset = response["errorOffset"] tc = self.regexpTextEdit.textCursor() tc.setPosition(offset) self.regexpTextEdit.setTextCursor(tc) self.regexpTextEdit.setFocus() return else: E5MessageBox.critical( self, self.tr("Communication Error"), self.tr("""Invalid response received from""" """ PyQt5 backend.""")) else: E5MessageBox.critical( self, self.tr("Communication Error"), self.tr("""Communication with PyQt5 backend""" """ failed.""")) else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression must be given.""")) @pyqtSlot() def on_executeButton_clicked(self, startpos=0): """ Private slot to execute the entered QRegularExpression on the test text. This slot will execute the entered QRegularExpression on the entered test data and will display the result in the table part of the dialog. @param startpos starting position for the QRegularExpression matching """ if not self.__pyqt5Available: # only available for PyQt5 return regexp = self.regexpTextEdit.toPlainText() text = self.textTextEdit.toPlainText() if regexp and text: options = [] if self.caseInsensitiveCheckBox.isChecked(): options.append("CaseInsensitiveOption") if self.multilineCheckBox.isChecked(): options.append("MultilineOption") if self.dotallCheckBox.isChecked(): options.append("DotMatchesEverythingOption") if self.extendedCheckBox.isChecked(): options.append("ExtendedPatternSyntaxOption") if self.greedinessCheckBox.isChecked(): options.append("InvertedGreedinessOption") if self.unicodeCheckBox.isChecked(): options.append("UseUnicodePropertiesOption") if self.captureCheckBox.isChecked(): options.append("DontCaptureOption") if self.__sendCommand("execute", options=options, regexp=regexp, text=text, startpos=startpos): response = self.__receiveResponse() if response and ("valid" in response or "matched" in response): if "valid" in response: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: {0}""") .format(response["errorMessage"])) # move cursor to error offset offset = response["errorOffset"] tc = self.regexpTextEdit.textCursor() tc.setPosition(offset) self.regexpTextEdit.setTextCursor(tc) self.regexpTextEdit.setFocus() return else: row = 0 OFFSET = 5 self.resultTable.setColumnCount(0) self.resultTable.setColumnCount(3) self.resultTable.setRowCount(0) self.resultTable.setRowCount(OFFSET) self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Regexp"))) self.resultTable.setItem( row, 1, QTableWidgetItem(regexp)) if response["matched"]: captures = response["captures"] # index 0 is the complete match offset = captures[0][1] self.lastMatchEnd = captures[0][2] self.nextButton.setEnabled(True) row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Offset"))) self.resultTable.setItem( row, 1, QTableWidgetItem("{0:d}".format(offset))) row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Captures"))) self.resultTable.setItem( row, 1, QTableWidgetItem( "{0:d}".format(len(captures) - 1))) row += 1 self.resultTable.setItem( row, 1, QTableWidgetItem(self.tr("Text"))) self.resultTable.setItem( row, 2, QTableWidgetItem(self.tr("Characters"))) row += 1 self.resultTable.setItem( row, 0, QTableWidgetItem(self.tr("Match"))) self.resultTable.setItem( row, 1, QTableWidgetItem(captures[0][0])) self.resultTable.setItem( row, 2, QTableWidgetItem( "{0:d}".format(captures[0][3]))) for i in range(1, len(captures)): if captures[i][0]: row += 1 self.resultTable.insertRow(row) self.resultTable.setItem( row, 0, QTableWidgetItem( self.tr("Capture #{0}") .format(i))) self.resultTable.setItem( row, 1, QTableWidgetItem(captures[i][0])) self.resultTable.setItem( row, 2, QTableWidgetItem( "{0:d}".format(captures[i][3]))) # highlight the matched text tc = self.textTextEdit.textCursor() tc.setPosition(offset) tc.setPosition( self.lastMatchEnd, QTextCursor.KeepAnchor) self.textTextEdit.setTextCursor(tc) else: self.nextButton.setEnabled(False) self.resultTable.setRowCount(2) row += 1 if startpos > 0: self.resultTable.setItem( row, 0, QTableWidgetItem( self.tr("No more matches"))) else: self.resultTable.setItem( row, 0, QTableWidgetItem( self.tr("No matches"))) # remove the highlight tc = self.textTextEdit.textCursor() tc.setPosition(0) self.textTextEdit.setTextCursor(tc) self.resultTable.resizeColumnsToContents() self.resultTable.resizeRowsToContents() self.resultTable.verticalHeader().hide() self.resultTable.horizontalHeader().hide() else: E5MessageBox.critical( self, self.tr("Communication Error"), self.tr("""Invalid response received from""" """ PyQt5 backend.""")) else: E5MessageBox.critical( self, self.tr("Communication Error"), self.tr("""Communication with PyQt5""" """ backend failed.""")) else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression and a text must""" """ be given.""")) @pyqtSlot() def on_nextButton_clicked(self): """ Private slot to find the next match. """ self.on_executeButton_clicked(self.lastMatchEnd) @pyqtSlot() def on_regexpTextEdit_textChanged(self): """ Private slot called when the regexp changes. """ if self.nextButton: self.nextButton.setEnabled(False) def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate the indentation string i1string = (indLevel + 1) * indString estring = os.linesep + indLevel * indString # now generate the code reVar = self.variableLineEdit.text() if not reVar: reVar = "regexp" regexp = self.regexpTextEdit.toPlainText() options = [] if self.caseInsensitiveCheckBox.isChecked(): options.append("QRegularExpression.CaseInsensitiveOption") if self.multilineCheckBox.isChecked(): options.append("QRegularExpression.MultilineOption") if self.dotallCheckBox.isChecked(): options.append("QRegularExpression.DotMatchesEverythingOption") if self.extendedCheckBox.isChecked(): options.append("QRegularExpression.ExtendedPatternSyntaxOption") if self.greedinessCheckBox.isChecked(): options.append("QRegularExpression.InvertedGreedinessOption") if self.unicodeCheckBox.isChecked(): options.append("QRegularExpression.UseUnicodePropertiesOption") if self.captureCheckBox.isChecked(): options.append("QRegularExpression.DontCaptureOption") options = " |{0}{1}".format(os.linesep, i1string).join(options) code = '{0} = QRegularExpression('.format(reVar) if options: code += '{0}{1}r"""{2}""",'.format( os.linesep, i1string, regexp.replace('"', '\\"')) code += '{0}{1}{2}'.format(os.linesep, i1string, options) else: code += 'r"""{0}"""'.format(regexp.replace('"', '\\"')) code += '){0}'.format(estring) return code class QRegularExpressionWizardDialog(QDialog): """ Class for the dialog variant. """ def __init__(self, parent=None, fromEric=True): """ Constructor @param parent parent widget (QWidget) @param fromEric flag indicating a call from within eric6 """ super(QRegularExpressionWizardDialog, self).__init__(parent) self.setModal(fromEric) self.setSizeGripEnabled(True) self.__layout = QVBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.__layout) self.cw = QRegularExpressionWizardWidget(self, fromEric) size = self.cw.size() self.__layout.addWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.cw.buttonBox.accepted.connect(self.accept) self.cw.buttonBox.rejected.connect(self.reject) def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ return self.cw.getCode(indLevel, indString) def accept(self): """ Public slot to hide the dialog and set the result code to Accepted. """ self.cw.shutdown() super(QRegularExpressionWizardDialog, self).accept() def reject(self): """ Public slot to hide the dialog and set the result code to Rejected. """ self.cw.shutdown() super(QRegularExpressionWizardDialog, self).reject() class QRegularExpressionWizardWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(QRegularExpressionWizardWindow, self).__init__(parent) self.cw = QRegularExpressionWizardWidget(self, fromEric=False) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.setStyle( Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw.buttonBox.accepted.connect(self.close) self.cw.buttonBox.rejected.connect(self.close) def closeEvent(self, evt): """ Protected method handling the close event. @param evt close event (QCloseEvent) """ self.cw.shutdown() super(QRegularExpressionWizardWindow, self).closeEvent(evt) eric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardDialog.ui0000644000175000017500000005325212263274340032327 0ustar piotrpiotr QRegularExpressionWizardDialog 0 0 800 700 QRegularExpression Wizard true Variable Name: QFrame::HLine QFrame::Sunken Qt::Horizontal <b>Comment: (?#)</b> <p>Insert some comment inside your regexp.</p> <b>Comment: (?#)</b> <p>Insert some comment inside your regexp.The regex engine ignores everything after the (?# until the first closing round bracket. The following example could clarify the regexp which match a valid date: </p> <p>(?#year)(19|20)\d\d[- /.](?#month)(0[1-9]|1[012])[- /.](?#day)(0[1-9]|[12][0-9]|3[01])</p> <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog.</p> <b>Single character of a range (e.g. [abcd])</b><p>Select a single character of a range via a specific dialog. This dialog will help to edit the range of characters and add some specific conditions.</p>s <b>Any character: '.'</b> <p>Select to insert a dot (.) in your regexp.</p> <b>Any character: '.'</b> <p>Select to insert a dot (.) in your regexp. The dot matches a single character, except line break characters (by default). E.g. 'gr.y' matches 'gray', 'grey', 'gr%y', etc. Use the dot sparingly. Often, a character class or negated character class is faster and more precise.</p> <b>Repeat contents</b> <p>Select a repetition condition via a specific dialog. This dialog will help to specify the allowed range for repetitions.</p> <b>Repeat contents</b> <p>Select a repetition condition via a specific dialog. This dialog will help to specify the allowed range for repetitions.</p> <b>Non capturing parentheses: (?:)</b> <p>Select to insert some non capturing brackets.</p> <b>Non capturing parentheses: (?:)</b> <p>Select to insert some non capturing brackets. It can be used to apply a regexp quantifier (eg. '?' or '+') to the entire group of characters inside the brakets. E.g. the regex 'Set(?:Value)?' matches 'Set' or 'SetValue'. The '?:' inside the brakets means that the content of the match (called the backreference) is not stored for further use.</p> <b>Atomic non capturing parentheses: (?>)</b> <p>Select to insert some atomic non capturing brackets.</p> <b>Atomic non capturing parentheses: (?>)</b> <p>Select to insert some atomic non capturing brackets. It can be used to apply a regexp quantifier (eg. '?' or '+') to the entire group of characters inside the brakets. E.g. the regex 'Set(?>Value)?' matches 'Set' or 'SetValue'. The '?>' inside the brakets means that the content of the match (called the backreference) is not stored for further use.</p> <b>Group: ()</b> <p>Select to insert some capturing brackets.</p> <b>Group: ()</b> <p>Select to insert some capturing brackets. They can be used to apply a regexp quantifier (e.g. '?' or '+') to the entire group of characters inside the brakets. E.g. the regex 'Set(Value)?' matches 'Set' or 'SetValue'. Contrary to non-capturing parentheses, the backreference matched inside the brakets is stored for further use (i.e. 'Value' in the second example above). One can access the backereference with the '\1' expression. </p> <p>E.g. '([a-c])x\1x\1' will match 'axaxa', 'bxbxb' and 'cxcxc'.</p> <b>Named group: (?P&lt;<i>groupname</i>&gt;)</b> <p>Select to insert some named group brackets.</p> <b>Named group: (?P&lt;<i>groupname</i>&gt;)</b> <p>Select to insert some named group brackets. Usage is similar to standard group parentheses as the matched backreference is also stored for further usage. The difference is that a name is given to the match. This is useful when the work to do on the match becomes a bit complicated. One can access the backreference via the group name (i.e (?P=<i>groupname</i>)). E.g. (?P<foo>[abc])x(?P=foo)x(?P=foo)x matches 'axaxax','bxbxbx' or 'cxcxcx' ('foo' is the group name)</p> <b>Reference named group: (?P=<i>groupname</i>)</b> <p>Select to insert a reference to named group previously declared.</p> <b>Reference named group: (?P=<i>groupname</i>)</b> <p>Select to insert a reference to named group previously declared. Each reference group refers to the match found by the corresponding named group. In the following example, (?P=foo) may refer to the charaters 'a','b' or 'c'.</p> <p>E.g. (?P<foo>[abc])x(?P=foo)x(?P=foo)x matches 'axaxax','bxbxbx' or 'cxcxcx'.</p> <b>Alternatives: '|'</b> <p>Select to insert the alternation symbol '|'. </p> <b>Alternatives: '|'</b> <p>Select to insert the alternation symbol '|'. The alternation is used to match a single regular expression out of several possible regular expressions. E.g. 'cat|dog|mouse|fish' matches words containing the word 'cat', 'dog','mouse' or 'fish'. Be aware that in the above example, the alternatives refer to whole or part of words. If you want to match exactly the words 'cat', 'dog', ... you should express the fact that you only want to match complete words: '\b(cat|dog|mouse|fish)\b'</p> <b>Begin of line: '^'</b> <p>Select to insert the start line character (^).</p> <b>Begin of line: '^'</b> <p>Select to insert the start line character (^). It is used to find some expressions at the begining of lines. E.g. '^[A-Z]' match lines starting with a capitalized character. </p> <b>End of line: '$'</b> <p>Select to insert the end of line character ($).</p> <b>End of line: '$'</b> <p>Select to insert the end of line character ($). It is used to find some expressions at the end of lines.</p> <b>Word boundary</b> <p>Select to insert the word boudary character (\b).</p> <b>Word boundary</b> <p>Select to insert the word boudary character (\b). This character is used to express the fact that word must begin or end at this position. E.g. '\bcat\b' matches exactly the word 'cat' while 'concatenation' is ignored.</p> <b>Non word boundary</b> <p>Select to insert the word boudary character (\B). \B is the negated version of \b.</p> <b>Non word boundary</b> <p>Select to insert the word boudary character (\B). \B is the negated version of \b. \B matches at every position where \b does not. Effectively, \B matches at any position between two word characters as well as at any position between two non-word characters.</p> <b>Positive lookahead: (?=<i>regexpr</i>)</b> <p>Select to insert the positive lookhead brackets.</p> <b>Positive lookahead: (?=<i>regexpr</i>)</b> <p>Select to insert the positive lookhead brackets. Basically, positive lookhead is used to match a character only if followed by another one. Writting 'q(?=u)' means that you want to match the 'q' character only if it is followed by 'u'. In this statement 'u' is a trivial regexp which may be replaced by a more complex expression; q(?=[abc])' will match a 'q' if followed by either 'a', 'b' or 'c'.</p> <b>Negative lookahead: (?!<i>regexpr</i>)</b> <p>Select to insert the negative lookhead brackets.</p> <b>Negative lookahead: (?!<i>regexpr</i>)</b> <p>Select to insert the negative lookhead brackets. Basically, negative lookhead is used to match a character only if it is not followed by a another one. Writting 'q(?!u)' means that you want to match 'q' only if it is not followed by 'u'. In this statement, 'u' is a trivial regexp which may be replaced by a more complex expression; 'q(?![abc])' will match a 'q' if it is followed by anything else than 'a', 'b' or 'c'.</p> <b>Positive lookbehind: (?&lt;=<i>regexpr</i>)</b> <p>Select to insert the positive lookbehind brackets.</p> <b>Positive lookbehind: (?&lt;=<i>regexpr</i>)</b> <p>Select to insert the positive lookbehind brackets. Lookbehind has the same effect as lookahead, but works backwards. It is used to match a character only if preceded by another one. Writting '(?&lt;=u)q' means that you want to match the 'q' character only if it is preceded by 'u'. As with lookhead, 'u' may be replaced by a more complex expression; '(?&lt;=[abc])q' will match a 'q' if preceded by either 'a', 'b' or 'c'.</p> <b>Negative lookbehind (?&lt;!<i>regexpr</i>)</b> <p>Select to insert the negative lookbehind brackets.</p> <b>Negative lookbehind (?&lt;!<i>regexpr</i>)</b> <p>Select to insert the negative lookbehind brackets. Lookbehind has the same effect as lookahead, but works backwards. It is used to match a character only if not preceded by another one. Writting '(?&lt;!u)q' means that you want to match the 'q' character only if it is not preceded by 'u'. As other lookaround, 'u' may be replaced by a more complex expression; '(?&lt;![abc])q' will match a 'q' only if not preceded by either 'a', 'b' nor 'c'.</p> Qt::Horizontal QSizePolicy::Fixed 16 20 <b>Undo last edit</b> <b>Redo last edit</b> Qt::Horizontal QSizePolicy::Expanding 20 20 Regexp: Qt::AlignTop 0 1 false Text: Qt::AlignTop 0 1 false Case Insensitive "^" matches beginning of line, "$" matches end of line Match Linebreaks "." matches everything including linebreaks Dot matches everything Extended Pattern Syntax Inverted Greediness Unicode Non-named capturing groups do not capture substrings Don't Capture 0 2 QAbstractItemView::NoEditTriggers Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok qPixmapFromMimeSource variableLineEdit commentButton charButton anycharButton repeatButton nonGroupButton atomicGroupButton groupButton namedGroupButton namedReferenceButton altnButton beglineButton endlineButton wordboundButton nonwordboundButton poslookaheadButton neglookaheadButton poslookbehindButton neglookbehindButton undoButton redoButton regexpTextEdit textTextEdit caseInsensitiveCheckBox multilineCheckBox dotallCheckBox extendedCheckBox greedinessCheckBox unicodeCheckBox captureCheckBox resultTable buttonBox ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrooteric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardRepeatDialog.uieric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardRepeatDialog.0000644000175000017500000002053212161362321033117 0ustar piotrpiotr QRegularExpressionWizardRepeatDialog 0 0 331 370 Number of repetitions true Quantifier times times times false Qt::AlignRight 1 false Qt::AlignRight 1 and Between false Qt::AlignRight 1 Exactly false Qt::AlignRight 1 Maximum Minimum false Qt::AlignRight 1 Unlimited (incl. zero times) Greediness Greedy Possessive Lazy Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource unlimitedButton minButton minSpin maxButton maxSpin exactButton exactSpin betweenButton lowerSpin upperSpin greedyButton possessiveButton lazyButton buttonBox minButton toggled(bool) minSpin setEnabled(bool) 53 43 121 47 maxButton toggled(bool) maxSpin setEnabled(bool) 58 68 117 67 exactButton toggled(bool) exactSpin setEnabled(bool) 61 114 162 114 betweenButton toggled(bool) lowerSpin setEnabled(bool) 60 143 162 143 betweenButton toggled(bool) upperSpin setEnabled(bool) 61 143 322 143 buttonBox accepted() QRegularExpressionWizardRepeatDialog accept() 19 190 19 211 buttonBox rejected() QRegularExpressionWizardRepeatDialog reject() 61 192 61 210 eric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/__init__.py0000644000175000017500000000024012451233372025762 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Package implementing the QRegularExpression wizard. """ ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrooteric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardRepeatDialog.pyeric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardRepeatDialog.0000644000175000017500000000545412451233372033132 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a dialog for entering repeat counts. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from .Ui_QRegularExpressionWizardRepeatDialog import \ Ui_QRegularExpressionWizardRepeatDialog class QRegularExpressionWizardRepeatDialog( QDialog, Ui_QRegularExpressionWizardRepeatDialog): """ Class implementing a dialog for entering repeat counts. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(QRegularExpressionWizardRepeatDialog, self).__init__(parent) self.setupUi(self) self.unlimitedButton.setChecked(True) self.greedyButton.setChecked(True) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(int) def on_lowerSpin_valueChanged(self, value): """ Private slot to handle the lowerSpin valueChanged signal. @param value value of the spinbox (integer) """ if self.upperSpin.value() < value: self.upperSpin.setValue(value) @pyqtSlot(int) def on_upperSpin_valueChanged(self, value): """ Private slot to handle the upperSpin valueChanged signal. @param value value of the spinbox (integer) """ if self.lowerSpin.value() > value: self.lowerSpin.setValue(value) def getRepeat(self): """ Public method to retrieve the dialog's result. @return ready formatted repeat string (string) """ if self.possessiveButton.isChecked(): greedy = "+" elif self.lazyButton.isChecked(): greedy = "?" else: greedy = "" if self.unlimitedButton.isChecked(): return "*" + greedy elif self.minButton.isChecked(): reps = self.minSpin.value() if reps == 1: return "+" + greedy else: return "{{{0:d},}}{1}".format(reps, greedy) elif self.maxButton.isChecked(): reps = self.maxSpin.value() if reps == 1: return "?" + greedy else: return "{{0,{0:d}}}{1}".format(reps, greedy) elif self.exactButton.isChecked(): reps = self.exactSpin.value() return "{{{0:d}}}".format(reps) elif self.betweenButton.isChecked(): repsMin = self.lowerSpin.value() repsMax = self.upperSpin.value() return "{{{0:d},{1:d}}}{2}".format(repsMin, repsMax, greedy) eric-6.0.8/eric/Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardServer.py0000644000175000017500000001365112451233372032407 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing the PyQt5 server part of the QRegularExpression wizzard. """ from __future__ import unicode_literals import json import sys def rxValidate(regexp, options): """ Function to validate the given regular expression. @param regexp regular expression to validate (string) @param options list of options (list of string) @return tuple of flag indicating validity (boolean), error string (string) and error offset (integer) """ try: from PyQt5.QtCore import QRegularExpression rxOptions = QRegularExpression.NoPatternOption if "CaseInsensitiveOption" in options: rxOptions |= QRegularExpression.CaseInsensitiveOption if "MultilineOption" in options: rxOptions |= QRegularExpression.MultilineOption if "DotMatchesEverythingOption" in options: rxOptions |= QRegularExpression.DotMatchesEverythingOption if "ExtendedPatternSyntaxOption" in options: rxOptions |= QRegularExpression.ExtendedPatternSyntaxOption if "InvertedGreedinessOption" in options: rxOptions |= QRegularExpression.InvertedGreedinessOption if "UseUnicodePropertiesOption" in options: rxOptions |= QRegularExpression.UseUnicodePropertiesOption if "DontCaptureOption" in options: rxOptions |= QRegularExpression.DontCaptureOption error = "" errorOffset = -1 re = QRegularExpression(regexp, rxOptions) valid = re.isValid() if not valid: error = re.errorString() errorOffset = re.patternErrorOffset() except ImportError: valid = False error = "ImportError" errorOffset = 0 return valid, error, errorOffset def rxExecute(regexp, options, text, startpos): """ Function to execute the given regular expression for a given text. @param regexp regular expression to validate (string) @param options list of options (list of string) @param text text to execute on (string) @param startpos start position for the execution (integer) @return tuple of a flag indicating a successful match (boolean) and a list of captures containing the complete match as matched string (string), match start (integer), match end (integer) and match length (integer) for each entry """ valid, error, errorOffset = rxValidate(regexp, options) if not valid: return valid, error, errorOffset from PyQt5.QtCore import QRegularExpression rxOptions = QRegularExpression.NoPatternOption if "CaseInsensitiveOption" in options: rxOptions |= QRegularExpression.CaseInsensitiveOption if "MultilineOption" in options: rxOptions |= QRegularExpression.MultilineOption if "DotMatchesEverythingOption" in options: rxOptions |= QRegularExpression.DotMatchesEverythingOption if "ExtendedPatternSyntaxOption" in options: rxOptions |= QRegularExpression.ExtendedPatternSyntaxOption if "InvertedGreedinessOption" in options: rxOptions |= QRegularExpression.InvertedGreedinessOption if "UseUnicodePropertiesOption" in options: rxOptions |= QRegularExpression.UseUnicodePropertiesOption if "DontCaptureOption" in options: rxOptions |= QRegularExpression.DontCaptureOption matched = False captures = [] re = QRegularExpression(regexp, rxOptions) match = re.match(text, startpos) if match.hasMatch(): matched = True for index in range(match.lastCapturedIndex() + 1): captures.append([ match.captured(index), match.capturedStart(index), match.capturedEnd(index), match.capturedLength(index) ]) return matched, captures def main(): """ Function containing the main routine. """ while True: commandStr = sys.stdin.readline() try: commandDict = json.loads(commandStr) responseDict = {"error": ""} if "command" in commandDict: command = commandDict["command"] if command == "exit": break elif command == "available": try: import PyQt5 # __IGNORE_WARNING__ responseDict["available"] = True except ImportError: responseDict["available"] = False elif command == "validate": valid, error, errorOffset = rxValidate( commandDict["regexp"], commandDict["options"]) responseDict["valid"] = valid responseDict["errorMessage"] = error responseDict["errorOffset"] = errorOffset elif command == "execute": valid, error, errorOffset = rxValidate( commandDict["regexp"], commandDict["options"]) if not valid: responseDict["valid"] = valid responseDict["errorMessage"] = error responseDict["errorOffset"] = errorOffset else: matched, captures = rxExecute( commandDict["regexp"], commandDict["options"], commandDict["text"], commandDict["startpos"]) responseDict["matched"] = matched responseDict["captures"] = captures except ValueError as err: responseDict = {"error": str(err)} except Exception as err: responseDict = {"error": str(err)} responseStr = json.dumps(responseDict) sys.stdout.write(responseStr) sys.stdout.flush() sys.exit(0) if __name__ == "__main__": main() eric-6.0.8/eric/Plugins/WizardPlugins/InputDialogWizard/0000755000175000017500000000000012557365404022303 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/InputDialogWizard/__init__.py0000644000175000017500000000023212451233372024400 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Package implementing the input dialog wizard. """ eric-6.0.8/eric/Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.ui0000644000175000017500000003477112247413640027366 0ustar piotrpiotr InputDialogWizardDialog 0 0 501 684 QInputDialog Wizard true Type Text true Integer Double Item Result: Enter the result variable name Title Label Parent Select "self" as parent self true Select "None" as parent None Select to enter a parent expression Expression: false Enter the parent expression Text Echo Mode Normal true No Echo Password Default false Integer -2147483647 2147483647 1 -2147483647 2147483647 2147483647 -2147483647 2147483647 -2147483647 -2147483647 2147483647 Step To From Default false Double -2147483647 2147483647 1 2147483647 -2147483647 0 Default From To Decimals false Item Editable true Current Item String List Variable Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource rText rInteger rDouble rItem eResultVar eCaption eLabel parentSelf parentNone parentOther parentEdit rEchoNormal rEchoNoEcho rEchoPassword eTextDefault sIntDefault sIntFrom sIntTo sIntStep eDoubleDefault eDoubleFrom eDoubleTo sDoubleDecimals eVariable sCurrentItem cEditable buttonBox rText toggled(bool) groupBox_2 setEnabled(bool) 74 48 39 411 rInteger toggled(bool) groupBox_4 setEnabled(bool) 247 48 178 489 rDouble toggled(bool) groupBox_5 setEnabled(bool) 364 48 283 567 rItem toggled(bool) groupBox_6 setEnabled(bool) 481 48 448 645 buttonBox accepted() InputDialogWizardDialog accept() 34 674 25 622 buttonBox rejected() InputDialogWizardDialog reject() 120 674 111 621 parentOther toggled(bool) parentEdit setEnabled(bool) 81 253 124 260 eric-6.0.8/eric/Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.py0000644000175000017500000001723512451233372027374 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the input dialog wizard dialog. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QDoubleValidator from PyQt5.QtWidgets import QLineEdit, QDialog, QInputDialog, QDialogButtonBox from .Ui_InputDialogWizardDialog import Ui_InputDialogWizardDialog class InputDialogWizardDialog(QDialog, Ui_InputDialogWizardDialog): """ Class implementing the input dialog wizard dialog. It displays a dialog for entering the parameters for the QInputDialog code generator. """ def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(InputDialogWizardDialog, self).__init__(parent) self.setupUi(self) # set the validators for the double line edots self.eDoubleDefault.setValidator( QDoubleValidator(-2147483647, 2147483647, 99, self.eDoubleDefault)) self.eDoubleFrom.setValidator( QDoubleValidator(-2147483647, 2147483647, 99, self.eDoubleFrom)) self.eDoubleTo.setValidator( QDoubleValidator(-2147483647, 2147483647, 99, self.eDoubleTo)) self.bTest = self.buttonBox.addButton( self.tr("Test"), QDialogButtonBox.ActionRole) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(bool) def on_rItem_toggled(self, checked): """ Private slot to perform actions dependant on the item type selection. @param checked flag indicating the checked state (boolean) """ self.bTest.setEnabled(not checked) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.bTest: self.on_bTest_clicked() @pyqtSlot() def on_bTest_clicked(self): """ Private method to test the selected options. """ if self.rText.isChecked(): if self.rEchoNormal.isChecked(): echomode = QLineEdit.Normal elif self.rEchoNoEcho.isChecked(): echomode = QLineEdit.NoEcho else: echomode = QLineEdit.Password QInputDialog.getText( None, self.eCaption.text(), self.eLabel.text(), echomode, self.eTextDefault.text()) elif self.rInteger.isChecked(): QInputDialog.getInt( None, self.eCaption.text(), self.eLabel.text(), self.sIntDefault.value(), self.sIntFrom.value(), self.sIntTo.value(), self.sIntStep.value()) elif self.rDouble.isChecked(): try: doubleDefault = float(self.eDoubleDefault.text()) except ValueError: doubleDefault = 0 try: doubleFrom = float(self.eDoubleFrom.text()) except ValueError: doubleFrom = -2147483647 try: doubleTo = float(self.eDoubleTo.text()) except ValueError: doubleTo = 2147483647 QInputDialog.getDouble( None, self.eCaption.text(), self.eLabel.text(), doubleDefault, doubleFrom, doubleTo, self.sDoubleDecimals.value()) def getCode(self, indLevel, indString): """ Public method to get the source code for Qt4/Qt5. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate our indentation level and the indentation string il = indLevel + 1 istring = il * indString estring = os.linesep + indLevel * indString # now generate the code if self.parentSelf.isChecked(): parent = "self" elif self.parentNone.isChecked(): parent = "None" elif self.parentOther.isChecked(): parent = self.parentEdit.text() if parent == "": parent = "None" resvar = self.eResultVar.text() if not resvar: resvar = "result" code = '{0}, ok = QInputDialog.'.format(resvar) if self.rText.isChecked(): code += 'getText({0}{1}'.format(os.linesep, istring) code += '{0},{1}{2}'.format(parent, os.linesep, istring) code += 'self.tr("{0}"),{1}{2}'.format( self.eCaption.text(), os.linesep, istring) code += 'self.tr("{0}"),{1}{2}'.format( self.eLabel.text(), os.linesep, istring) if self.rEchoNormal.isChecked(): code += 'QLineEdit.Normal' elif self.rEchoNoEcho.isChecked(): code += 'QLineEdit.NoEcho' else: code += 'QLineEdit.Password' if self.eTextDefault.text(): code += ',{0}{1}self.tr("{2}")'.format( os.linesep, istring, self.eTextDefault.text()) code += '){0}'.format(estring) elif self.rInteger.isChecked(): code += 'getInt({0}{1}'.format(os.linesep, istring) code += '{0},{1}{2}'.format(parent, os.linesep, istring) code += 'self.tr("{0}"),{1}{2}'.format( self.eCaption.text(), os.linesep, istring) code += 'self.tr("{0}"),{1}{2}'.format( self.eLabel.text(), os.linesep, istring) code += '{0:d}, {1:d}, {2:d}, {3:d}){4}'.format( self.sIntDefault.value(), self.sIntFrom.value(), self.sIntTo.value(), self.sIntStep.value(), estring) elif self.rDouble.isChecked(): try: doubleDefault = float(self.eDoubleDefault.text()) except ValueError: doubleDefault = 0 try: doubleFrom = float(self.eDoubleFrom.text()) except ValueError: doubleFrom = -2147483647 try: doubleTo = float(self.eDoubleTo.text()) except ValueError: doubleTo = 2147483647 code += 'getDouble({0}{1}'.format(os.linesep, istring) code += '{0},{1}{2}'.format(parent, os.linesep, istring) code += 'self.tr("{0}"),{1}{2}'.format( self.eCaption.text(), os.linesep, istring) code += 'self.tr("{0}"),{1}{2}'.format( self.eLabel.text(), os.linesep, istring) code += '{0}, {1}, {2}, {3:d}){4}'.format( doubleDefault, doubleFrom, doubleTo, self.sDoubleDecimals.value(), estring) elif self.rItem.isChecked(): code += 'getItem({0}{1}'.format(os.linesep, istring) code += '{0},{1}{2}'.format(parent, os.linesep, istring) code += 'self.tr("{0}"),{1}{2}'.format( self.eCaption.text(), os.linesep, istring) code += 'self.tr("{0}"),{1}{2}'.format( self.eLabel.text(), os.linesep, istring) code += '{0},{1}{2}'.format( self.eVariable.text(), os.linesep, istring) code += '{0:d}, {1}){2}'.format( self.sCurrentItem.value(), self.cEditable.isChecked(), estring) return code eric-6.0.8/eric/Plugins/WizardPlugins/E5MessageBoxWizard/0000755000175000017500000000000012557365404022313 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/E5MessageBoxWizard/E5MessageBoxWizardDialog.py0000644000175000017500000005003212451233372027404 0ustar piotrpiotr# -*- coding: utf-8 -*- """ Module implementing the eric6 message box wizard dialog. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton from E5Gui import E5MessageBox from .Ui_E5MessageBoxWizardDialog import Ui_E5MessageBoxWizardDialog class E5MessageBoxWizardDialog(QDialog, Ui_E5MessageBoxWizardDialog): """ Class implementing the eric6 message box wizard dialog. It displays a dialog for entering the parameters for the E5MessageBox code generator. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5MessageBoxWizardDialog, self).__init__(parent) self.setupUi(self) # keep the following three lists in sync self.buttonsList = [ self.tr("No button"), self.tr("Abort"), self.tr("Apply"), self.tr("Cancel"), self.tr("Close"), self.tr("Discard"), self.tr("Help"), self.tr("Ignore"), self.tr("No"), self.tr("No to all"), self.tr("Ok"), self.tr("Open"), self.tr("Reset"), self.tr("Restore defaults"), self.tr("Retry"), self.tr("Save"), self.tr("Save all"), self.tr("Yes"), self.tr("Yes to all"), ] self.buttonsCodeListBinary = [ E5MessageBox.NoButton, E5MessageBox.Abort, E5MessageBox.Apply, E5MessageBox.Cancel, E5MessageBox.Close, E5MessageBox.Discard, E5MessageBox.Help, E5MessageBox.Ignore, E5MessageBox.No, E5MessageBox.NoToAll, E5MessageBox.Ok, E5MessageBox.Open, E5MessageBox.Reset, E5MessageBox.RestoreDefaults, E5MessageBox.Retry, E5MessageBox.Save, E5MessageBox.SaveAll, E5MessageBox.Yes, E5MessageBox.YesToAll, ] self.buttonsCodeListText = [ "E5MessageBox.NoButton", "E5MessageBox.Abort", "E5MessageBox.Apply", "E5MessageBox.Cancel", "E5MessageBox.Close", "E5MessageBox.Discard", "E5MessageBox.Help", "E5MessageBox.Ignore", "E5MessageBox.No", "E5MessageBox.NoToAll", "E5MessageBox.Ok", "E5MessageBox.Open", "E5MessageBox.Reset", "E5MessageBox.RestoreDefaults", "E5MessageBox.Retry", "E5MessageBox.Save", "E5MessageBox.SaveAll", "E5MessageBox.Yes", "E5MessageBox.YesToAll", ] self.defaultCombo.addItems(self.buttonsList) self.bTest = self.buttonBox.addButton( self.tr("Test"), QDialogButtonBox.ActionRole) self.__enabledGroups() def __enabledGroups(self): """ Private method to enable/disable some group boxes. """ self.standardButtons.setEnabled( self.rInformation.isChecked() or self.rQuestion.isChecked() or self.rWarning.isChecked() or self.rCritical.isChecked() or self.rStandard.isChecked() ) self.defaultButton.setEnabled( self.rInformation.isChecked() or self.rQuestion.isChecked() or self.rWarning.isChecked() or self.rCritical.isChecked() ) self.iconBox.setEnabled( self.rYesNo.isChecked() or self.rRetryAbort.isChecked() or self.rStandard.isChecked() ) self.bTest.setEnabled(not self.rStandard.isChecked()) self.eMessage.setEnabled(not self.rAboutQt.isChecked()) @pyqtSlot(bool) def on_rInformation_toggled(self, on): """ Private slot to handle the toggled signal of the rInformation radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rQuestion_toggled(self, on): """ Private slot to handle the toggled signal of the rQuestion radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rWarning_toggled(self, on): """ Private slot to handle the toggled signal of the rWarning radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rCritical_toggled(self, on): """ Private slot to handle the toggled signal of the rCritical radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rYesNo_toggled(self, on): """ Private slot to handle the toggled signal of the rYesNo radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rRetryAbort_toggled(self, on): """ Private slot to handle the toggled signal of the rRetryAbort radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rOkToClearData_toggled(self, on): """ Private slot to handle the toggled signal of the rOkToClearData radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rAbout_toggled(self, on): """ Private slot to handle the toggled signal of the rAbout radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rAboutQt_toggled(self, on): """ Private slot to handle the toggled signal of the rAboutQt radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(bool) def on_rStandard_toggled(self, on): """ Private slot to handle the toggled signal of the rStandard radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.bTest: self.on_bTest_clicked() @pyqtSlot() def on_bTest_clicked(self): """ Private method to test the selected options. """ if self.rAbout.isChecked(): E5MessageBox.about( None, self.eCaption.text(), self.eMessage.toPlainText() ) elif self.rAboutQt.isChecked(): E5MessageBox.aboutQt( None, self.eCaption.text() ) elif self.rInformation.isChecked() or \ self.rQuestion.isChecked() or \ self.rWarning.isChecked() or \ self.rCritical.isChecked(): buttons = E5MessageBox.NoButton if self.abortCheck.isChecked(): buttons |= E5MessageBox.Abort if self.applyCheck.isChecked(): buttons |= E5MessageBox.Apply if self.cancelCheck.isChecked(): buttons |= E5MessageBox.Cancel if self.closeCheck.isChecked(): buttons |= E5MessageBox.Close if self.discardCheck.isChecked(): buttons |= E5MessageBox.Discard if self.helpCheck.isChecked(): buttons |= E5MessageBox.Help if self.ignoreCheck.isChecked(): buttons |= E5MessageBox.Ignore if self.noCheck.isChecked(): buttons |= E5MessageBox.No if self.notoallCheck.isChecked(): buttons |= E5MessageBox.NoToAll if self.okCheck.isChecked(): buttons |= E5MessageBox.Ok if self.openCheck.isChecked(): buttons |= E5MessageBox.Open if self.resetCheck.isChecked(): buttons |= E5MessageBox.Reset if self.restoreCheck.isChecked(): buttons |= E5MessageBox.RestoreDefaults if self.retryCheck.isChecked(): buttons |= E5MessageBox.Retry if self.saveCheck.isChecked(): buttons |= E5MessageBox.Save if self.saveallCheck.isChecked(): buttons |= E5MessageBox.SaveAll if self.yesCheck.isChecked(): buttons |= E5MessageBox.Yes if self.yestoallCheck.isChecked(): buttons |= E5MessageBox.YesToAll if buttons == E5MessageBox.NoButton: buttons = E5MessageBox.Ok defaultButton = self.buttonsCodeListBinary[ self.defaultCombo.currentIndex()] if self.rInformation.isChecked(): E5MessageBox.information( self, self.eCaption.text(), self.eMessage.toPlainText(), E5MessageBox.StandardButtons(buttons), defaultButton ) elif self.rQuestion.isChecked(): E5MessageBox.question( self, self.eCaption.text(), self.eMessage.toPlainText(), E5MessageBox.StandardButtons(buttons), defaultButton ) elif self.rWarning.isChecked(): E5MessageBox.warning( self, self.eCaption.text(), self.eMessage.toPlainText(), E5MessageBox.StandardButtons(buttons), defaultButton ) elif self.rCritical.isChecked(): E5MessageBox.critical( self, self.eCaption.text(), self.eMessage.toPlainText(), E5MessageBox.StandardButtons(buttons), defaultButton ) elif self.rYesNo.isChecked() or \ self.rRetryAbort.isChecked(): if self.iconInformation.isChecked(): icon = E5MessageBox.Information elif self.iconQuestion.isChecked(): icon = E5MessageBox.Question elif self.iconWarning.isChecked(): icon = E5MessageBox.Warning elif self.iconCritical.isChecked(): icon = E5MessageBox.Critical if self.rYesNo.isChecked(): E5MessageBox.yesNo( self, self.eCaption.text(), self.eMessage.toPlainText(), icon=icon, yesDefault=self.yesDefaultCheck.isChecked() ) elif self.rRetryAbort.isChecked(): E5MessageBox.retryAbort( self, self.eCaption.text(), self.eMessage.toPlainText(), icon=icon ) elif self.rOkToClearData.isChecked(): E5MessageBox.okToClearData( self, self.eCaption.text(), self.eMessage.toPlainText(), lambda: True ) def __getStandardButtonCode(self, istring, indString, withIntro=True): """ Private method to generate the button code for the standard buttons. @param istring indentation string (string) @param indString string used for indentation (space or tab) (string) @keyparam withIntro flag indicating to generate a first line with introductory text (boolean) @return the button code (string) """ buttons = [] if self.abortCheck.isChecked(): buttons.append("E5MessageBox.Abort") if self.applyCheck.isChecked(): buttons.append("E5MessageBox.Apply") if self.cancelCheck.isChecked(): buttons.append("E5MessageBox.Cancel") if self.closeCheck.isChecked(): buttons.append("E5MessageBox.Close") if self.discardCheck.isChecked(): buttons.append("E5MessageBox.Discard") if self.helpCheck.isChecked(): buttons.append("E5MessageBox.Help") if self.ignoreCheck.isChecked(): buttons.append("E5MessageBox.Ignore") if self.noCheck.isChecked(): buttons.append("E5MessageBox.No") if self.notoallCheck.isChecked(): buttons.append("E5MessageBox.NoToAll") if self.okCheck.isChecked(): buttons.append("E5MessageBox.Ok") if self.openCheck.isChecked(): buttons.append("E5MessageBox.Open") if self.resetCheck.isChecked(): buttons.append("E5MessageBox.Reset") if self.restoreCheck.isChecked(): buttons.append("E5MessageBox.RestoreDefaults") if self.retryCheck.isChecked(): buttons.append("E5MessageBox.Retry") if self.saveCheck.isChecked(): buttons.append("E5MessageBox.Save") if self.saveallCheck.isChecked(): buttons.append("E5MessageBox.SaveAll") if self.yesCheck.isChecked(): buttons.append("E5MessageBox.Yes") if self.yestoallCheck.isChecked(): buttons.append("E5MessageBox.YesToAll") if len(buttons) == 0: return "" istring2 = istring + indString joinstring = ' |{0}{1}'.format(os.linesep, istring2) if withIntro: btnCode = ',{0}{1}E5MessageBox.StandardButtons('.format( os.linesep, istring) else: btnCode = 'E5MessageBox.StandardButtons('.format( os.linesep, istring) btnCode += '{0}{1}{2})'.format( os.linesep, istring2, joinstring.join(buttons)) return btnCode def __getDefaultButtonCode(self, istring): """ Private method to generate the button code for the default button. @param istring indentation string (string) @return the button code (string) """ btnCode = "" defaultIndex = self.defaultCombo.currentIndex() if defaultIndex: btnCode = ',{0}{1}{2}'.format( os.linesep, istring, self.buttonsCodeListText[defaultIndex]) return btnCode def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate our indentation level and the indentation string il = indLevel + 1 istring = il * indString estring = os.linesep + indLevel * indString # now generate the code if self.parentSelf.isChecked(): parent = "self" elif self.parentNone.isChecked(): parent = "None" elif self.parentOther.isChecked(): parent = self.parentEdit.text() if parent == "": parent = "None" if self.iconInformation.isChecked(): icon = "E5MessageBox.Information" elif self.iconQuestion.isChecked(): icon = "E5MessageBox.Question" elif self.iconWarning.isChecked(): icon = "E5MessageBox.Warning" elif self.iconCritical.isChecked(): icon = "E5MessageBox.Critical" if not self.rStandard.isChecked(): resvar = self.eResultVar.text() if not resvar: resvar = "res" if self.rAbout.isChecked(): msgdlg = "E5MessageBox.about({0}".format(os.linesep) elif self.rAboutQt.isChecked(): msgdlg = "E5MessageBox.aboutQt({0}".format(os.linesep) elif self.rInformation.isChecked(): msgdlg = "{0} = E5MessageBox.information({1}".format( resvar, os.linesep) elif self.rQuestion.isChecked(): msgdlg = "{0} = E5MessageBox.question({1}".format( resvar, os.linesep) elif self.rWarning.isChecked(): msgdlg = "{0} = E5MessageBox.warning({1}".format( resvar, os.linesep) elif self.rCritical.isChecked(): msgdlg = "{0} = E5MessageBox.critical({1}".format( resvar, os.linesep) elif self.rYesNo.isChecked(): msgdlg = "{0} = E5MessageBox.yesNo({1}".format( resvar, os.linesep) elif self.rRetryAbort.isChecked(): msgdlg = "{0} = E5MessageBox.retryAbort({1}".format( resvar, os.linesep) elif self.rOkToClearData.isChecked(): msgdlg = "{0} = E5MessageBox.okToClearData({1}".format( resvar, os.linesep) msgdlg += '{0}{1},{2}'.format(istring, parent, os.linesep) msgdlg += '{0}self.tr("{1}")'.format( istring, self.eCaption.text()) if not self.rAboutQt.isChecked(): msgdlg += ',{0}{1}self.tr("""{2}""")'.format( os.linesep, istring, self.eMessage.toPlainText()) if self.rInformation.isChecked() or \ self.rQuestion.isChecked() or \ self.rWarning.isChecked() or \ self.rCritical.isChecked(): msgdlg += self.__getStandardButtonCode(istring, indString) msgdlg += self.__getDefaultButtonCode(istring) elif self.rYesNo.isChecked(): if not self.iconQuestion.isChecked(): msgdlg += ',{0}{1}icon={2}'.format( os.linesep, istring, icon) if self.yesDefaultCheck.isChecked(): msgdlg += ',{0}{1}yesDefault=True'.format( os.linesep, istring) elif self.rRetryAbort.isChecked(): if not self.iconQuestion.isChecked(): msgdlg += ',{0}{1}icon={2}'.format( os.linesep, istring, icon) elif self.rOkToClearData.isChecked(): saveFunc = self.saveFuncEdit.text() if saveFunc == "": saveFunc = "lambda: True" msgdlg += ',{0}{1}{2}'.format(os.linesep, istring, saveFunc) else: resvar = self.eResultVar.text() if not resvar: resvar = "dlg" msgdlg = "{0} = E5MessageBox.E5MessageBox({1}".format( resvar, os.linesep) msgdlg += '{0}{1},{2}'.format(istring, icon, os.linesep) msgdlg += '{0}self.tr("{1}")'.format( istring, self.eCaption.text()) msgdlg += ',{0}{1}self.tr("""{2}""")'.format( os.linesep, istring, self.eMessage.toPlainText()) if self.modalCheck.isChecked(): msgdlg += ',{0}{1}modal=True'.format(os.linesep, istring) btnCode = self.__getStandardButtonCode( istring, indString, withIntro=False) if btnCode: msgdlg += ',{0}{1}buttons={2}'.format( os.linesep, istring, btnCode) if not self.parentNone.isChecked(): msgdlg += ',{0}{1}parent={2}'.format( os.linesep, istring, parent) msgdlg += '){0}'.format(estring) return msgdlg eric-6.0.8/eric/Plugins/WizardPlugins/E5MessageBoxWizard/__init__.py0000644000175000017500000000023712451233372024415 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Package implementing the eric6 message box wizard. """ eric-6.0.8/eric/Plugins/WizardPlugins/E5MessageBoxWizard/E5MessageBoxWizardDialog.ui0000644000175000017500000004551712247413640027406 0ustar piotrpiotr E5MessageBoxWizardDialog 0 0 535 681 E5MessageBox Wizard true Type Generate an Information message box Information true Qt::TabFocus Generate a Question message box Question Qt::TabFocus Generate a Warning message box Warning Qt::TabFocus Generate a Critical message box Critical Generate a Yes/No message box Yes/No Generate a retry/abort message box Retry/Abort Generate an "ok to clear data" message box OK to clear data Qt::TabFocus Generate an About message box About Qt::TabFocus Generate an AboutQt message box About Qt Generate a standard message box Standard message box Result: Enter the result variable name Title Enter the title for the message box Message Enter the message to be shown in the message box true Parent Select "self" as parent self true Select "None" as parent None Select to enter a parent expression Expression: false Enter the parent expression Standard Buttons Abort Apply Cancel Close Discard Help Ignore No No to all Ok Open Reset Restore defaults Retry Save Save all Yes Yes to all Default Button 0 0 Select the default button Icon Show an Information icon Information false Qt::TabFocus Show a Question icon Question true Qt::TabFocus Show a Warning icon Warning Qt::TabFocus Show a Critical icon Critical false Select to generate a modal message box Modal Message Box false Select to make 'Yes' the default Yes is default false Save function: false Enter the name of the save function Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource rInformation rQuestion rWarning rCritical rYesNo rRetryAbort rOkToClearData rAbout rAboutQt rStandard eResultVar eCaption eMessage parentSelf parentNone parentOther parentEdit abortCheck applyCheck cancelCheck closeCheck discardCheck helpCheck ignoreCheck noCheck notoallCheck okCheck openCheck resetCheck restoreCheck retryCheck saveCheck saveallCheck yesCheck yestoallCheck defaultCombo iconInformation iconQuestion iconWarning iconCritical modalCheck yesDefaultCheck saveFuncEdit buttonBox buttonBox accepted() E5MessageBoxWizardDialog accept() 52 744 34 604 buttonBox rejected() E5MessageBoxWizardDialog reject() 144 744 126 605 rStandard toggled(bool) modalCheck setEnabled(bool) 82 131 67 705 rYesNo toggled(bool) yesDefaultCheck setEnabled(bool) 95 79 250 705 rOkToClearData toggled(bool) label setEnabled(bool) 388 79 332 706 rOkToClearData toggled(bool) saveFuncEdit setEnabled(bool) 388 79 524 706 parentOther toggled(bool) parentEdit setEnabled(bool) 90 384 142 386 eric-6.0.8/eric/Plugins/WizardPlugins/FileDialogWizard/0000755000175000017500000000000012557365404022063 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/FileDialogWizard/FileDialogWizardDialog.ui0000644000175000017500000003405012247413640026714 0ustar piotrpiotr FileDialogWizardDialog 0 0 604 660 QFileDialog Wizard true PyQt Variant: Qt::Horizontal 40 20 Type Select to create an 'Open File' dialog Open File true Select to create an 'Open Files' dialog Open Files Select to create a 'Save File' dialog Save File Select to create a 'Select Directory' dialog Select Directory Select to create an 'Open File' dialog capturing the selected filter Open File and Filter false Select to create an 'Open Files' dialog capturing the selected filter Open Files and Filter Select to create a 'Save File' dialog capturing the selected filter Save File and Filter Results Name Variable: Filter Variable: Title: Enter the title text Check to resolve symbolic links Resolve Symlinks true Parent Select "self" as parent self true Select "None" as parent None Select to enter a parent expression Expression: false Enter the parent expression File Dialog Properties Start With / Working Directory Enter the working directory or a filename Check this if the contents of the edit names a variable or variable function Is Variable Filters Enter the filter specifications separated by ';;' Check this if the contents of the edit names a variable or variable function Is Variable Initial Filter Enter the initial filter Check this if the contents of the edit names a variable or variable function Is Variable false Select to show an overwrite confirmation dialog Show overwrite confirmation false Directory Dialog Properties Enter the working directory Working Directory Check this if the contents of the edit names a variable or variable function Is Variable Check to display directories only Show Directories Only true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource pyqtComboBox rOpenFile rOpenFiles rSaveFile rDirectory rfOpenFile rfOpenFiles rfSaveFile eNameVariable eFilterVariable eCaption cSymlinks parentSelf parentNone parentOther parentEdit eStartWith cStartWith eFilters cFilters eInitialFilter cInitialFilter cConfirmOverwrite eWorkDir cWorkDir cDirOnly buttonBox buttonBox accepted() FileDialogWizardDialog accept() 29 615 24 488 buttonBox rejected() FileDialogWizardDialog reject() 128 615 124 485 parentOther toggled(bool) parentEdit setEnabled(bool) 70 260 141 260 eric-6.0.8/eric/Plugins/WizardPlugins/FileDialogWizard/FileDialogWizardDialog.py0000644000175000017500000005207412501343671026734 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the file dialog wizard dialog. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFileDialog, \ QButtonGroup from E5Gui.E5Completers import E5FileCompleter, E5DirCompleter from .Ui_FileDialogWizardDialog import Ui_FileDialogWizardDialog import Globals class FileDialogWizardDialog(QDialog, Ui_FileDialogWizardDialog): """ Class implementing the color dialog wizard dialog. It displays a dialog for entering the parameters for the QFileDialog code generator. """ def __init__(self, pyqtVariant, parent=None): """ Constructor @param pyqtVariant variant of PyQt (integer; 0, 4 or 5) @param parent parent widget (QWidget) """ super(FileDialogWizardDialog, self).__init__(parent) self.setupUi(self) self.eStartWithCompleter = E5FileCompleter(self.eStartWith) self.eWorkDirCompleter = E5DirCompleter(self.eWorkDir) self.__pyqtVariant = pyqtVariant self.__typeButtonsGroup = QButtonGroup(self) self.__typeButtonsGroup.setExclusive(True) self.__typeButtonsGroup.addButton(self.rOpenFile, 1) self.__typeButtonsGroup.addButton(self.rOpenFiles, 2) self.__typeButtonsGroup.addButton(self.rSaveFile, 3) self.__typeButtonsGroup.addButton(self.rfOpenFile, 11) self.__typeButtonsGroup.addButton(self.rfOpenFiles, 12) self.__typeButtonsGroup.addButton(self.rfSaveFile, 13) self.__typeButtonsGroup.addButton(self.rDirectory, 20) self.__typeButtonsGroup.buttonClicked[int].connect( self.__toggleInitialFilterAndResult) self.__toggleInitialFilterAndResult(1) self.pyqtComboBox.addItems(["PyQt4", "PyQt5"]) self.__pyqtVariant = pyqtVariant if self.__pyqtVariant == 5: self.pyqtComboBox.setCurrentIndex(1) else: self.pyqtComboBox.setCurrentIndex(0) self.rSaveFile.toggled[bool].connect(self.__toggleConfirmCheckBox) self.rfSaveFile.toggled[bool].connect(self.__toggleConfirmCheckBox) self.rDirectory.toggled[bool].connect(self.__toggleGroupsAndTest) self.cStartWith.toggled[bool].connect(self.__toggleGroupsAndTest) self.cWorkDir.toggled[bool].connect(self.__toggleGroupsAndTest) self.cFilters.toggled[bool].connect(self.__toggleGroupsAndTest) self.bTest = self.buttonBox.addButton( self.tr("Test"), QDialogButtonBox.ActionRole) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __adjustOptions(self, options): """ Private method to adjust the file dialog options. @param options file dialog options (QFileDialog.Options) @return modified options (QFileDialog.Options) """ if Globals.isLinuxPlatform(): options |= QFileDialog.DontUseNativeDialog return options @pyqtSlot(str) def on_pyqtComboBox_currentIndexChanged(self, txt): """ Private slot to setup the dialog for the selected PyQt variant. @param txt text of the selected combo box entry (string) """ self.rfOpenFile.setEnabled(txt == "PyQt4") self.rfOpenFiles.setEnabled(txt == "PyQt4") self.rfSaveFile.setEnabled(txt == "PyQt4") if txt == "PyQt5": if self.rfOpenFile.isChecked(): self.rOpenFile.setChecked(True) elif self.rfOpenFiles.isChecked(): self.rOpenFiles.setChecked(True) elif self.rfSaveFile.isChecked(): self.rSaveFile.setChecked(True) self.__pyqtVariant = 5 if txt == "PyQt5" else 4 self.__toggleInitialFilterAndResult( self.__typeButtonsGroup.checkedId()) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.bTest: self.on_bTest_clicked() @pyqtSlot() def on_bTest_clicked(self): """ Private method to test the selected options. """ if self.rOpenFile.isChecked() or self.rfOpenFile.isChecked(): if not self.cSymlinks.isChecked(): options = QFileDialog.Options(QFileDialog.DontResolveSymlinks) else: options = QFileDialog.Options() options = self.__adjustOptions(options) if self.rOpenFile.isChecked() and self.__pyqtVariant == 4: try: QFileDialog.getOpenFileName( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), options) except TypeError: QFileDialog.getOpenFileName( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) else: try: QFileDialog.getOpenFileNameAndFilter( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) except AttributeError: QFileDialog.getOpenFileName( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) elif self.rOpenFiles.isChecked() or self.rfOpenFiles.isChecked(): if not self.cSymlinks.isChecked(): options = QFileDialog.Options(QFileDialog.DontResolveSymlinks) else: options = QFileDialog.Options() options = self.__adjustOptions(options) if self.rOpenFiles.isChecked() and self.__pyqtVariant == 4: try: QFileDialog.getOpenFileNames( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), options) except TypeError: QFileDialog.getOpenFileNames( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) else: try: QFileDialog.getOpenFileNamesAndFilter( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) except AttributeError: QFileDialog.getOpenFileNames( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) elif self.rSaveFile.isChecked() or self.rfSaveFile.isChecked(): if not self.cSymlinks.isChecked(): options = QFileDialog.Options(QFileDialog.DontResolveSymlinks) else: options = QFileDialog.Options() options = self.__adjustOptions(options) if self.rSaveFile.isChecked() and self.__pyqtVariant == 4: try: QFileDialog.getSaveFileName( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), options) except TypeError: QFileDialog.getSaveFileName( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) else: try: QFileDialog.getSaveFileNameAndFilter( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) except AttributeError: QFileDialog.getSaveFileName( None, self.eCaption.text(), self.eStartWith.text(), self.eFilters.text(), self.eInitialFilter.text(), options) elif self.rDirectory.isChecked(): options = QFileDialog.Options() if not self.cSymlinks.isChecked(): options |= QFileDialog.Options(QFileDialog.DontResolveSymlinks) if self.cDirOnly.isChecked(): options |= QFileDialog.Options(QFileDialog.ShowDirsOnly) else: options |= QFileDialog.Options(QFileDialog.Option(0)) options = self.__adjustOptions(options) QFileDialog.getExistingDirectory( None, self.eCaption.text(), self.eWorkDir.text(), options) def __toggleConfirmCheckBox(self): """ Private slot to enable/disable the confirmation check box. """ self.cConfirmOverwrite.setEnabled( self.rSaveFile.isChecked() or self.rfSaveFile.isChecked()) def __toggleGroupsAndTest(self): """ Private slot to enable/disable certain groups and the test button. """ if self.rDirectory.isChecked(): self.filePropertiesGroup.setEnabled(False) self.dirPropertiesGroup.setEnabled(True) self.bTest.setDisabled(self.cWorkDir.isChecked()) else: self.filePropertiesGroup.setEnabled(True) self.dirPropertiesGroup.setEnabled(False) self.bTest.setDisabled( self.cStartWith.isChecked() or self.cFilters.isChecked()) def __toggleInitialFilterAndResult(self, id): """ Private slot to enable/disable the initial filter elements and the results entries. @param id id of the clicked button (integer) """ if (self.__pyqtVariant == 4 and id in [11, 12, 13]) or \ (self.__pyqtVariant == 5 and id in [1, 2, 3]): enable = True else: enable = False self.lInitialFilter.setEnabled(enable) self.eInitialFilter.setEnabled(enable) self.cInitialFilter.setEnabled(enable) self.lFilterVariable.setEnabled(enable) self.eFilterVariable.setEnabled(enable) def getCode(self, indLevel, indString): """ Public method to get the source code for Qt4 and Qt5. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate our indentation level and the indentation string il = indLevel + 1 istring = il * indString estring = os.linesep + indLevel * indString # now generate the code if self.parentSelf.isChecked(): parent = "self" elif self.parentNone.isChecked(): parent = "None" elif self.parentOther.isChecked(): parent = self.parentEdit.text() if parent == "": parent = "None" # prepare the result variables nameVariable = self.eNameVariable.text() if not nameVariable: if self.__typeButtonsGroup.checkedButton() in [ self.rOpenFile, self.rfOpenFile, self.rSaveFile, self.rfSaveFile]: nameVariable = "fileName" elif self.__typeButtonsGroup.checkedButton() in [ self.rOpenFiles, self.rfOpenFiles]: nameVariable = "fileNames" elif self.__typeButtonsGroup.checkedButton() == self.rDirectory: nameVariable = "dirName" else: nameVariable = "res" filterVariable = self.eFilterVariable.text() if not filterVariable: if (self.__pyqtVariant == 4 and self.__typeButtonsGroup.checkedButton() in [ self.rfOpenFile, self.rfOpenFiles, self.rfSaveFile]) or \ (self.__pyqtVariant == 5 and self.__typeButtonsGroup.checkedButton() in [ self.rOpenFile, self.rOpenFiles, self.rSaveFile]): filterVariable = ", selectedFilter" else: filterVariable = "" code = '{0}{1} = QFileDialog.'.format(nameVariable, filterVariable) if self.rOpenFile.isChecked() or self.rfOpenFile.isChecked(): if self.rOpenFile.isChecked(): code += 'getOpenFileName({0}{1}'.format(os.linesep, istring) else: code += 'getOpenFileNameAndFilter({0}{1}'.format( os.linesep, istring) code += '{0},{1}{2}'.format(parent, os.linesep, istring) if not self.eCaption.text(): code += '"",{0}{1}'.format(os.linesep, istring) else: code += 'self.tr("{0}"),{1}{2}'.format( self.eCaption.text(), os.linesep, istring) if not self.eStartWith.text(): code += '"",{0}{1}'.format(os.linesep, istring) else: if self.cStartWith.isChecked(): fmt = '{0},{1}{2}' else: fmt = 'self.tr("{0}"),{1}{2}' code += fmt.format(self.eStartWith.text(), os.linesep, istring) if self.eFilters.text() == "": code += '""' else: if self.cFilters.isChecked(): fmt = '{0}' else: fmt = 'self.tr("{0}")' code += fmt.format(self.eFilters.text()) if self.rfOpenFile.isChecked() or self.__pyqtVariant == 5: if self.eInitialFilter.text() == "": filter = "None" else: if self.cInitialFilter.isChecked(): fmt = '{0}' else: fmt = 'self.tr("{0}")' filter = fmt.format(self.eInitialFilter.text()) code += ',{0}{1}{2}'.format(os.linesep, istring, filter) if not self.cSymlinks.isChecked(): code += \ ',{0}{1}QFileDialog.Options(' \ 'QFileDialog.DontResolveSymlinks)' \ .format(os.linesep, istring) code += '){0}'.format(estring) elif self.rOpenFiles.isChecked() or self.rfOpenFiles.isChecked(): if self.rOpenFiles.isChecked(): code += 'getOpenFileNames({0}{1}'.format(os.linesep, istring) else: code += 'getOpenFileNamesAndFilter({0}{1}'.format( os.linesep, istring) code += '{0},{1}{2}'.format(parent, os.linesep, istring) if not self.eCaption.text(): code += '"",{0}{1}'.format(os.linesep, istring) else: code += 'self.tr("{0}"),{1}{2}'.format( self.eCaption.text(), os.linesep, istring) if not self.eStartWith.text(): code += '"",{0}{1}'.format(os.linesep, istring) else: if self.cStartWith.isChecked(): fmt = '{0},{1}{2}' else: fmt = 'self.tr("{0}"),{1}{2}' code += fmt.format(self.eStartWith.text(), os.linesep, istring) if not self.eFilters.text(): code += '""' else: if self.cFilters.isChecked(): fmt = '{0}' else: fmt = 'self.tr("{0}")' code += fmt.format(self.eFilters.text()) if self.rfOpenFiles.isChecked() or self.__pyqtVariant == 5: if self.eInitialFilter.text() == "": filter = "None" else: if self.cInitialFilter.isChecked(): fmt = '{0}' else: fmt = 'self.tr("{0}")' filter = fmt.format(self.eInitialFilter.text()) code += ',{0}{1}{2}'.format(os.linesep, istring, filter) if not self.cSymlinks.isChecked(): code += \ ',{0}{1}QFileDialog.Options(' \ 'QFileDialog.DontResolveSymlinks)' \ .format(os.linesep, istring) code += '){0}'.format(estring) elif self.rSaveFile.isChecked() or self.rfSaveFile.isChecked(): if self.rSaveFile.isChecked(): code += 'getSaveFileName({0}{1}'.format(os.linesep, istring) else: code += 'getSaveFileNameAndFilter({0}{1}'.format( os.linesep, istring) code += '{0},{1}{2}'.format(parent, os.linesep, istring) if not self.eCaption.text(): code += '"",{0}{1}'.format(os.linesep, istring) else: code += 'self.tr("{0}"),{1}{2}'.format( self.eCaption.text(), os.linesep, istring) if not self.eStartWith.text(): code += '"",{0}{1}'.format(os.linesep, istring) else: if self.cStartWith.isChecked(): fmt = '{0},{1}{2}' else: fmt = 'self.tr("{0}"),{1}{2}' code += fmt.format(self.eStartWith.text(), os.linesep, istring) if not self.eFilters.text(): code += '""' else: if self.cFilters.isChecked(): fmt = '{0}' else: fmt = 'self.tr("{0}")' code += fmt.format(self.eFilters.text()) if self.rfSaveFile.isChecked() or self.__pyqtVariant == 5: if self.eInitialFilter.text() == "": filter = "None" else: if self.cInitialFilter.isChecked(): fmt = '{0}' else: fmt = 'self.tr("{0}")' filter = fmt.format(self.eInitialFilter.text()) code += ',{0}{1}{2}'.format(os.linesep, istring, filter) if (not self.cSymlinks.isChecked()) or \ (not self.cConfirmOverwrite.isChecked()): code += ',{0}{1}QFileDialog.Options('.format( os.linesep, istring) if not self.cSymlinks.isChecked(): code += 'QFileDialog.DontResolveSymlinks' if (not self.cSymlinks.isChecked()) and \ (not self.cConfirmOverwrite.isChecked()): code += ' | ' if not self.cConfirmOverwrite.isChecked(): code += 'QFileDialog.DontConfirmOverwrite' code += ')' code += '){0}'.format(estring) elif self.rDirectory.isChecked(): code += 'getExistingDirectory({0}{1}'.format(os.linesep, istring) code += '{0},{1}{2}'.format(parent, os.linesep, istring) if not self.eCaption.text(): code += '"",{0}{1}'.format(os.linesep, istring) else: code += 'self.tr("{0}"),{1}{2}'.format( self.eCaption.text(), os.linesep, istring) if not self.eWorkDir.text(): code += '""' else: if self.cWorkDir.isChecked(): fmt = '{0}' else: fmt = 'self.tr("{0}")' code += fmt.format(self.eWorkDir.text()) code += ',{0}{1}QFileDialog.Options('.format(os.linesep, istring) if not self.cSymlinks.isChecked(): code += 'QFileDialog.DontResolveSymlinks | ' if self.cDirOnly.isChecked(): code += 'QFileDialog.ShowDirsOnly' else: code += 'QFileDialog.Option(0)' code += ')){0}'.format(estring) return code eric-6.0.8/eric/Plugins/WizardPlugins/FileDialogWizard/__init__.py0000644000175000017500000000023112451233372024157 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Package implementing the file dialog wizard. """ eric-6.0.8/eric/Plugins/WizardPlugins/MessageBoxWizard/0000755000175000017500000000000012557365404022121 5ustar piotrpiotreric-6.0.8/eric/Plugins/WizardPlugins/MessageBoxWizard/MessageBoxWizardDialog.py0000644000175000017500000003033312451233372027022 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the message box wizard dialog. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QMessageBox, QDialog, QDialogButtonBox from .Ui_MessageBoxWizardDialog import Ui_MessageBoxWizardDialog class MessageBoxWizardDialog(QDialog, Ui_MessageBoxWizardDialog): """ Class implementing the message box wizard dialog. It displays a dialog for entering the parameters for the QMessageBox code generator. """ def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(MessageBoxWizardDialog, self).__init__(parent) self.setupUi(self) # keep the following three lists in sync self.buttonsList = [ self.tr("No button"), self.tr("Abort"), self.tr("Apply"), self.tr("Cancel"), self.tr("Close"), self.tr("Discard"), self.tr("Help"), self.tr("Ignore"), self.tr("No"), self.tr("No to all"), self.tr("Ok"), self.tr("Open"), self.tr("Reset"), self.tr("Restore defaults"), self.tr("Retry"), self.tr("Save"), self.tr("Save all"), self.tr("Yes"), self.tr("Yes to all"), ] self.buttonsCodeListBinary = [ QMessageBox.NoButton, QMessageBox.Abort, QMessageBox.Apply, QMessageBox.Cancel, QMessageBox.Close, QMessageBox.Discard, QMessageBox.Help, QMessageBox.Ignore, QMessageBox.No, QMessageBox.NoToAll, QMessageBox.Ok, QMessageBox.Open, QMessageBox.Reset, QMessageBox.RestoreDefaults, QMessageBox.Retry, QMessageBox.Save, QMessageBox.SaveAll, QMessageBox.Yes, QMessageBox.YesToAll, ] self.buttonsCodeListText = [ "QMessageBox.NoButton", "QMessageBox.Abort", "QMessageBox.Apply", "QMessageBox.Cancel", "QMessageBox.Close", "QMessageBox.Discard", "QMessageBox.Help", "QMessageBox.Ignore", "QMessageBox.No", "QMessageBox.NoToAll", "QMessageBox.Ok", "QMessageBox.Open", "QMessageBox.Reset", "QMessageBox.RestoreDefaults", "QMessageBox.Retry", "QMessageBox.Save", "QMessageBox.SaveAll", "QMessageBox.Yes", "QMessageBox.YesToAll", ] self.defaultCombo.addItems(self.buttonsList) self.bTest = self.buttonBox.addButton( self.tr("Test"), QDialogButtonBox.ActionRole) def __testQt42(self): """ Private method to test the selected options for Qt 4.2.0. """ buttons = QMessageBox.NoButton if self.abortCheck.isChecked(): buttons |= QMessageBox.Abort if self.applyCheck.isChecked(): buttons |= QMessageBox.Apply if self.cancelCheck.isChecked(): buttons |= QMessageBox.Cancel if self.closeCheck.isChecked(): buttons |= QMessageBox.Close if self.discardCheck.isChecked(): buttons |= QMessageBox.Discard if self.helpCheck.isChecked(): buttons |= QMessageBox.Help if self.ignoreCheck.isChecked(): buttons |= QMessageBox.Ignore if self.noCheck.isChecked(): buttons |= QMessageBox.No if self.notoallCheck.isChecked(): buttons |= QMessageBox.NoToAll if self.okCheck.isChecked(): buttons |= QMessageBox.Ok if self.openCheck.isChecked(): buttons |= QMessageBox.Open if self.resetCheck.isChecked(): buttons |= QMessageBox.Reset if self.restoreCheck.isChecked(): buttons |= QMessageBox.RestoreDefaults if self.retryCheck.isChecked(): buttons |= QMessageBox.Retry if self.saveCheck.isChecked(): buttons |= QMessageBox.Save if self.saveallCheck.isChecked(): buttons |= QMessageBox.SaveAll if self.yesCheck.isChecked(): buttons |= QMessageBox.Yes if self.yestoallCheck.isChecked(): buttons |= QMessageBox.YesToAll if buttons == QMessageBox.NoButton: buttons = QMessageBox.Ok defaultButton = self.buttonsCodeListBinary[ self.defaultCombo.currentIndex()] if self.rInformation.isChecked(): QMessageBox.information( self, self.eCaption.text(), self.eMessage.toPlainText(), QMessageBox.StandardButtons(buttons), defaultButton ) elif self.rQuestion.isChecked(): QMessageBox.question( self, self.eCaption.text(), self.eMessage.toPlainText(), QMessageBox.StandardButtons(buttons), defaultButton ) elif self.rWarning.isChecked(): QMessageBox.warning( self, self.eCaption.text(), self.eMessage.toPlainText(), QMessageBox.StandardButtons(buttons), defaultButton ) elif self.rCritical.isChecked(): QMessageBox.critical( self, self.eCaption.text(), self.eMessage.toPlainText(), QMessageBox.StandardButtons(buttons), defaultButton ) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.bTest: self.on_bTest_clicked() @pyqtSlot() def on_bTest_clicked(self): """ Private method to test the selected options. """ if self.rAbout.isChecked(): QMessageBox.about( None, self.eCaption.text(), self.eMessage.toPlainText() ) elif self.rAboutQt.isChecked(): QMessageBox.aboutQt( None, self.eCaption.text() ) else: self.__testQt42() def __enabledGroups(self): """ Private method to enable/disable some group boxes. """ enable = not self.rAbout.isChecked() and not self.rAboutQt.isChecked() self.standardButtons.setEnabled(enable) self.lResultVar.setEnabled(enable) self.eResultVar.setEnabled(enable) self.eMessage.setEnabled(not self.rAboutQt.isChecked()) def on_rAbout_toggled(self, on): """ Private slot to handle the toggled signal of the rAbout radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() def on_rAboutQt_toggled(self, on): """ Private slot to handle the toggled signal of the rAboutQt radio button. @param on toggle state (boolean) (ignored) """ self.__enabledGroups() def __getButtonCode(self, istring, indString): """ Private method to generate the button code. @param istring indentation string (string) @param indString string used for indentation (space or tab) (string) @return the button code (string) """ buttons = [] if self.abortCheck.isChecked(): buttons.append("QMessageBox.Abort") if self.applyCheck.isChecked(): buttons.append("QMessageBox.Apply") if self.cancelCheck.isChecked(): buttons.append("QMessageBox.Cancel") if self.closeCheck.isChecked(): buttons.append("QMessageBox.Close") if self.discardCheck.isChecked(): buttons.append("QMessageBox.Discard") if self.helpCheck.isChecked(): buttons.append("QMessageBox.Help") if self.ignoreCheck.isChecked(): buttons.append("QMessageBox.Ignore") if self.noCheck.isChecked(): buttons.append("QMessageBox.No") if self.notoallCheck.isChecked(): buttons.append("QMessageBox.NoToAll") if self.okCheck.isChecked(): buttons.append("QMessageBox.Ok") if self.openCheck.isChecked(): buttons.append("QMessageBox.Open") if self.resetCheck.isChecked(): buttons.append("QMessageBox.Reset") if self.restoreCheck.isChecked(): buttons.append("QMessageBox.RestoreDefaults") if self.retryCheck.isChecked(): buttons.append("QMessageBox.Retry") if self.saveCheck.isChecked(): buttons.append("QMessageBox.Save") if self.saveallCheck.isChecked(): buttons.append("QMessageBox.SaveAll") if self.yesCheck.isChecked(): buttons.append("QMessageBox.Yes") if self.yestoallCheck.isChecked(): buttons.append("QMessageBox.YesToAll") if len(buttons) == 0: return "" istring2 = istring + indString joinstring = ' |{0}{1}'.format(os.linesep, istring2) btnCode = ',{0}{1}QMessageBox.StandardButtons('.format( os.linesep, istring) btnCode += '{0}{1}{2})'.format( os.linesep, istring2, joinstring.join(buttons)) defaultIndex = self.defaultCombo.currentIndex() if defaultIndex: btnCode += ',{0}{1}{2}'.format( os.linesep, istring, self.buttonsCodeListText[defaultIndex]) return btnCode def getCode(self, indLevel, indString): """ Public method to get the source code. @param indLevel indentation level (int) @param indString string used for indentation (space or tab) (string) @return generated code (string) """ # calculate our indentation level and the indentation string il = indLevel + 1 istring = il * indString estring = os.linesep + indLevel * indString # now generate the code if self.parentSelf.isChecked(): parent = "self" elif self.parentNone.isChecked(): parent = "None" elif self.parentOther.isChecked(): parent = self.parentEdit.text() if parent == "": parent = "None" resvar = self.eResultVar.text() if not resvar: resvar = "res" if self.rAbout.isChecked(): msgdlg = "QMessageBox.about(" elif self.rAboutQt.isChecked(): msgdlg = "QMessageBox.aboutQt(" elif self.rInformation.isChecked(): msgdlg = "{0} = QMessageBox.information(".format(resvar) elif self.rQuestion.isChecked(): msgdlg = "{0} = QMessageBox.question(".format(resvar) elif self.rWarning.isChecked(): msgdlg = "{0} = QMessageBox.warning(".format(resvar) else: msgdlg = "{0} = QMessageBox.critical(".format(resvar) if self.rAboutQt.isChecked(): if self.eCaption.text(): msgdlg += '{0}{1}{2}'.format(os.linesep, istring, parent) msgdlg += ',{0}{1}self.tr("{2}")'.format( os.linesep, istring, self.eCaption.text()) else: msgdlg += parent else: msgdlg += '{0}{1}{2}'.format(os.linesep, istring, parent) msgdlg += ',{0}{1}self.tr("{2}")'.format( os.linesep, istring, self.eCaption.text()) msgdlg += ',{0}{1}self.tr("""{2}""")'.format( os.linesep, istring, self.eMessage.toPlainText()) if not self.rAbout.isChecked() and not self.rAboutQt.isChecked(): msgdlg += self.__getButtonCode(istring, indString) msgdlg += '){0}'.format(estring) return msgdlg eric-6.0.8/eric/Plugins/WizardPlugins/MessageBoxWizard/MessageBoxWizardDialog.ui0000644000175000017500000003174112247145617027022 0ustar piotrpiotr MessageBoxWizardDialog 0 0 535 522 QMessageBox Wizard true Type Generate an Information QMessageBox Information true Qt::TabFocus Generate a Question QMessageBox Question Qt::TabFocus Generate a Warning QMessageBox Warning Qt::TabFocus Generate a Critical QMessageBox Critical Qt::TabFocus Generate an About QMessageBox About Qt::TabFocus Generate an AboutQt QMessageBox About Qt Result: Enter the result variable name Title Enter the title for the QMessageBox Message Enter the message to be shown in the QMessageBox true Parent Select "self" as parent self true Select "None" as parent None Select to enter a parent expression Expression: false Enter the parent expression Standard Buttons Apply Abort Cancel Ignore Save all Save Discard Yes to all Open Reset Ok No Help No to all Retry Restore defaults Yes Close Default Button: 0 0 Select the default button Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource rInformation rQuestion rWarning rCritical rAbout rAboutQt eResultVar eCaption eMessage parentSelf parentNone parentOther parentEdit abortCheck applyCheck cancelCheck closeCheck discardCheck helpCheck ignoreCheck noCheck notoallCheck okCheck openCheck resetCheck restoreCheck retryCheck saveCheck saveallCheck yesCheck yestoallCheck defaultCombo buttonBox buttonBox accepted() MessageBoxWizardDialog accept() 43 529 34 538 buttonBox rejected() MessageBoxWizardDialog reject() 135 529 126 538 parentOther toggled(bool) parentEdit setEnabled(bool) 90 305 140 309 eric-6.0.8/eric/Plugins/WizardPlugins/MessageBoxWizard/__init__.py0000644000175000017500000000023112451233372024215 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Package implementing the message box wizard. """ eric-6.0.8/eric/Plugins/AboutPlugin/0000755000175000017500000000000012557365404016332 5ustar piotrpiotreric-6.0.8/eric/Plugins/AboutPlugin/AboutDialog.ui0000644000175000017500000001124712134513776021066 0ustar piotrpiotr AboutDialog 0 0 580 450 About Eric false 0 0 Sans Serif 11 75 false true false false 0 &About QFrame::NoFrame true A&uthors QFrame::NoFrame true &Thanks To QFrame::NoFrame true &License Agreement QFrame::NoFrame QTextEdit::NoWrap true false Qt::Horizontal QDialogButtonBox::Ok aboutTabWidget aboutEdit authorsEdit thanksEdit licenseEdit buttonBox accepted() AboutDialog accept() 83 423 83 434 buttonBox rejected() AboutDialog reject() 135 420 136 435 eric-6.0.8/eric/Plugins/AboutPlugin/__init__.py0000644000175000017500000000022112451233372020425 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the About plugin. """ eric-6.0.8/eric/Plugins/AboutPlugin/AboutDialog.py0000644000175000017500000011054012451233372021066 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing an 'About Eric' dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import QCoreApplication from PyQt5.QtWidgets import QDialog from .Ui_AboutDialog import Ui_AboutDialog import Preferences import UI.PixmapCache import UI.Info titleText = "{0} - {1}".format(UI.Info.Program, UI.Info.Version) aboutText = QCoreApplication.translate( "AboutDialog", """

{0} is an Integrated Development Environment for the Python""" """ programming language. It is written using the PyQt Python bindings""" """ for the Qt GUI toolkit and the QScintilla editor widget.

""" """

For more information see""" """ {1}.

""" """

Please send bug reports to {2}.

""" """

To request a new feature please send an email to""" """ {3}.

""" """

{0} uses third party software which is copyrighted""" """ by its respective copyright holder. For details see""" """ the copyright notice of the individual package.

""" ).format(UI.Info.Program, UI.Info.Homepage, UI.Info.BugAddress, UI.Info.FeatureAddress) authorsText = \ """\ Detlev Offenbach Project Manager, Maintainer and German translation Andrew Bushnell Multithreaded debugger Alexander Darovsky Mikhail Terekhov Russian translations Julien Vienne French translations Zdeněk Böhm Czech translations Jaime Seuma Spanish translations Serdar Koçdaş Turkish translations Xia WeiPeng Chinese translations Gianluca Italian translations """ thanksText = """\ Phil Thompson for providing PyQt and QScintilla and pushing me into this business. Andrew Bushnell of Fluent Inc. for contributing the multithreading debugger and a bunch of fixes to enhance the platform independence. Alexander Darovsky and Mikhail Terekhov for providing Russian translations. Julien Vienne for providing French translations. Zdenek Böhm for providing Czech translations. Jaime Seuma for providing Spanish translations. Serdar Koçdaş for providing Turkish translations. Xia WeiPeng for providing Chinese translations. Gianluca for providing Italian translations. Shane Richards for Crystal Icons. The Kumula Team for the splash screen. Gordon Tyler Hans-Peter Jansen Ralf Ahlbrink Stefan Jaensch Martin v. Löwis Thorsten Kohnhorst for providing patches to improve eric3, eric4, eric5 and eric6. And all the people who reported bugs and made suggestions.""" licenseText = \ """Eric is {0} You may use, distribute and copy Eric under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, which is shown below, or (at your option) any later version. ------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS""" \ .format(UI.Info.Copyright) # __IGNORE_WARNING__ class AboutDialog(QDialog, Ui_AboutDialog): """ Class implementing an 'About Eric' dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(AboutDialog, self).__init__(parent) self.setupUi(self) self.ericLabel.setText(titleText) self.ericPixmap.setPixmap( UI.PixmapCache.getPixmap("eric.png").scaled(48, 48)) #################################################################### ## ABOUT #################################################################### self.aboutEdit.setHtml(aboutText) #################################################################### ## Copyright, Authors #################################################################### self.authorsEdit.setPlainText(authorsText) #################################################################### ## THANKS #################################################################### self.thanksEdit.setPlainText(thanksText) #################################################################### ## LICENSE #################################################################### font = Preferences.getEditorOtherFonts("MonospacedFont") self.licenseEdit.setFontFamily(font.family()) self.licenseEdit.setFontPointSize(font.pointSize()) self.licenseEdit.setPlainText(licenseText) self.aboutTabWidget.setCurrentWidget(self.about) eric-6.0.8/eric/Styles/0000755000175000017500000000000012060166053013727 5ustar piotrpiotreric-6.0.8/eric/Styles/Pure_Technology_Dark.qss0000644000175000017500000000055312060166053020531 0ustar piotrpiotrQProgressBar:horizontal { border: 1px solid gray; border-radius: 3px; background: white; padding: 1px; text-align: center; } QProgressBar::chunk:horizontal { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #c8ff67, stop: 1 #ace44a); } * { selection-background-color: #BCF952; selection-color: #000000; } eric-6.0.8/eric/Styles/No_Single_Click_Activation.qss0000644000175000017500000000004612060166053021622 0ustar piotrpiotr* { activate-on-singleclick: 0; } eric-6.0.8/eric/eric6_sqlbrowser.py0000644000175000017500000000343712451233372016323 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Eric6 SQL Browser. This is the main Python script that performs the necessary initialization of the SQL browser and starts the Qt event loop. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from SqlBrowser.SqlBrowser import SqlBrowser if len(argv) > 1: connections = argv[1:] else: connections = [] browser = SqlBrowser(connections) return browser def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ] appinfo = AppInfo.makeAppInfo(sys.argv, "Eric6 SQL Browser", "connection", "SQL browser", options) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/E5Graphics/0000755000175000017500000000000012451233406014377 5ustar piotrpiotreric-6.0.8/eric/E5Graphics/E5GraphicsView.py0000644000175000017500000003320512451233372017543 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a canvas view class. """ from __future__ import unicode_literals import sys from PyQt5.QtCore import pyqtSignal, QRectF, QSize, QSizeF, Qt from PyQt5.QtGui import QBrush, QPainter, QPixmap, QFont, QColor from PyQt5.QtWidgets import QGraphicsView import Preferences class E5GraphicsView(QGraphicsView): """ Class implementing a graphics view. @signal zoomValueChanged(int) emitted to signal a change of the zoom value """ zoomValueChanged = pyqtSignal(int) ZoomLevels = [ 1, 3, 5, 7, 9, 10, 20, 30, 50, 67, 80, 90, 100, 110, 120, 133, 150, 170, 200, 240, 300, 400, 500, 600, 700, 800, 900, 1000, ] ZoomLevelDefault = 100 def __init__(self, scene, parent=None): """ Constructor @param scene reference to the scene object (QGraphicsScene) @param parent parent widget (QWidget) """ super(E5GraphicsView, self).__init__(scene, parent) self.setObjectName("E5GraphicsView") self.__initialSceneSize = self.scene().sceneRect().size() self.setBackgroundBrush(QBrush(Qt.white)) self.setRenderHint(QPainter.Antialiasing, True) self.setDragMode(QGraphicsView.RubberBandDrag) self.setAlignment(Qt.Alignment(Qt.AlignLeft | Qt.AlignTop)) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate) self.setWhatsThis(self.tr( "Graphics View\n" "

This graphics view is used to show a diagram. \n" "There are various actions available to manipulate the \n" "shown items.

\n" "
    \n" "
  • Clicking on an item selects it.
  • \n" "
  • Ctrl-clicking adds an item to the selection.
  • \n" "
  • Ctrl-clicking a selected item deselects it.
  • \n" "
  • Clicking on an empty spot of the canvas resets the selection." "
  • \n" "
  • Dragging the mouse over the canvas spans a rubberband to \n" "select multiple items.
  • \n" "
  • Dragging the mouse over a selected item moves the \n" "whole selection.
  • \n" "
\n" )) def __levelForZoom(self, zoom): """ Private method determining the zoom level index given a zoom factor. @param zoom zoom factor (integer) @return index of zoom factor (integer) """ try: index = E5GraphicsView.ZoomLevels.index(zoom) except ValueError: for index in range(len(E5GraphicsView.ZoomLevels)): if zoom <= E5GraphicsView.ZoomLevels[index]: break return index def zoomIn(self): """ Public method to zoom in. """ index = self.__levelForZoom(self.zoom()) if index < len(E5GraphicsView.ZoomLevels) - 1: self.setZoom(E5GraphicsView.ZoomLevels[index + 1]) def zoomOut(self): """ Public method to zoom out. """ index = self.__levelForZoom(self.zoom()) if index > 0: self.setZoom(E5GraphicsView.ZoomLevels[index - 1]) def zoomReset(self): """ Public method to handle the reset the zoom value. """ self.setZoom( E5GraphicsView.ZoomLevels[E5GraphicsView.ZoomLevelDefault]) def setZoom(self, value): """ Public method to set the zoom value in percent. @param value zoom value in percent (integer) """ if value != self.zoom(): self.resetTransform() factor = value / 100.0 self.scale(factor, factor) self.zoomValueChanged.emit(value) def zoom(self): """ Public method to get the current zoom factor in percent. @return current zoom factor in percent (integer) """ return int(self.transform().m11() * 100.0) def resizeScene(self, amount, isWidth=True): """ Public method to resize the scene. @param amount size increment (integer) @param isWidth flag indicating width is to be resized (boolean) """ sceneRect = self.scene().sceneRect() width = sceneRect.width() height = sceneRect.height() if isWidth: width += amount else: height += amount rect = self._getDiagramRect(10) if width < rect.width(): width = rect.width() if height < rect.height(): height = rect.height() self.setSceneSize(width, height) def setSceneSize(self, width, height): """ Public method to set the scene size. @param width width for the scene (real) @param height height for the scene (real) """ rect = self.scene().sceneRect() rect.setHeight(height) rect.setWidth(width) self.scene().setSceneRect(rect) def autoAdjustSceneSize(self, limit=False): """ Public method to adjust the scene size to the diagram size. @param limit flag indicating to limit the scene to the initial size (boolean) """ size = self._getDiagramSize(10) if limit: newWidth = max(size.width(), self.__initialSceneSize.width()) newHeight = max(size.height(), self.__initialSceneSize.height()) else: newWidth = size.width() newHeight = size.height() self.setSceneSize(newWidth, newHeight) def _getDiagramRect(self, border=0): """ Protected method to calculate the minimum rectangle fitting the diagram. @param border border width to include in the calculation (integer) @return the minimum rectangle (QRectF) """ startx = sys.maxsize starty = sys.maxsize endx = 0 endy = 0 items = self.filteredItems(list(self.scene().items())) for itm in items: rect = itm.sceneBoundingRect() itmEndX = rect.x() + rect.width() itmEndY = rect.y() + rect.height() itmStartX = rect.x() itmStartY = rect.y() if startx >= itmStartX: startx = itmStartX if starty >= itmStartY: starty = itmStartY if endx <= itmEndX: endx = itmEndX if endy <= itmEndY: endy = itmEndY if border: startx -= border starty -= border endx += border endy += border return QRectF(startx, starty, endx - startx + 1, endy - starty + 1) def _getDiagramSize(self, border=0): """ Protected method to calculate the minimum size fitting the diagram. @param border border width to include in the calculation (integer) @return the minimum size (QSizeF) """ endx = 0 endy = 0 items = self.filteredItems(list(self.scene().items())) for itm in items: rect = itm.sceneBoundingRect() itmEndX = rect.x() + rect.width() itmEndY = rect.y() + rect.height() if endx <= itmEndX: endx = itmEndX if endy <= itmEndY: endy = itmEndY if border: endx += border endy += border return QSizeF(endx + 1, endy + 1) def __getDiagram(self, rect, format="PNG", filename=None): """ Private method to retrieve the diagram from the scene fitting it in the minimum rectangle. @param rect minimum rectangle fitting the diagram (QRectF) @param format format for the image file (string) @param filename name of the file for non pixmaps (string) @return diagram pixmap to receive the diagram (QPixmap) """ selectedItems = self.scene().selectedItems() # step 1: deselect all widgets if selectedItems: for item in selectedItems: item.setSelected(False) # step 2: grab the diagram if format == "PNG": paintDevice = QPixmap(int(rect.width()), int(rect.height())) paintDevice.fill(self.backgroundBrush().color()) else: from PyQt5.QtSvg import QSvgGenerator paintDevice = QSvgGenerator() paintDevice.setResolution(100) # 100 dpi paintDevice.setSize(QSize(int(rect.width()), int(rect.height()))) paintDevice.setViewBox(rect) paintDevice.setFileName(filename) painter = QPainter(paintDevice) painter.setRenderHint(QPainter.Antialiasing, True) self.scene().render(painter, QRectF(), rect) # step 3: reselect the widgets if selectedItems: for item in selectedItems: item.setSelected(True) return paintDevice def saveImage(self, filename, format="PNG"): """ Public method to save the scene to a file. @param filename name of the file to write the image to (string) @param format format for the image file (string) @return flag indicating success (boolean) """ rect = self._getDiagramRect(self.border) if format == "SVG": self.__getDiagram(rect, format=format, filename=filename) return True else: pixmap = self.__getDiagram(rect) return pixmap.save(filename, format) def printDiagram(self, printer, diagramName=""): """ Public method to print the diagram. @param printer reference to a ready configured printer object (QPrinter) @param diagramName name of the diagram (string) """ painter = QPainter() painter.begin(printer) offsetX = 0 offsetY = 0 widthX = 0 heightY = 0 font = QFont("times", 10) painter.setFont(font) fm = painter.fontMetrics() fontHeight = fm.lineSpacing() marginX = printer.pageRect().x() - printer.paperRect().x() marginX = \ Preferences.getPrinter("LeftMargin") * int( printer.resolution() / 2.54) - marginX marginY = printer.pageRect().y() - printer.paperRect().y() marginY = \ Preferences.getPrinter("TopMargin") * int( printer.resolution() / 2.54) - marginY width = printer.width() - marginX \ - Preferences.getPrinter("RightMargin") * int( printer.resolution() / 2.54) height = printer.height() - fontHeight - 4 - marginY \ - Preferences.getPrinter("BottomMargin") * int( printer.resolution() / 2.54) border = self.border == 0 and 5 or self.border rect = self._getDiagramRect(border) diagram = self.__getDiagram(rect) finishX = False finishY = False page = 0 pageX = 0 pageY = 1 while not finishX or not finishY: if not finishX: offsetX = pageX * width pageX += 1 elif not finishY: offsetY = pageY * height offsetX = 0 pageY += 1 finishX = False pageX = 1 if (width + offsetX) > diagram.width(): finishX = True widthX = diagram.width() - offsetX else: widthX = width if diagram.width() < width: widthX = diagram.width() finishX = True offsetX = 0 if (height + offsetY) > diagram.height(): finishY = True heightY = diagram.height() - offsetY else: heightY = height if diagram.height() < height: finishY = True heightY = diagram.height() offsetY = 0 painter.drawPixmap(marginX, marginY, diagram, offsetX, offsetY, widthX, heightY) # write a foot note s = self.tr("{0}, Page {1}").format(diagramName, page + 1) tc = QColor(50, 50, 50) painter.setPen(tc) painter.drawRect(marginX, marginY, width, height) painter.drawLine(marginX, marginY + height + 2, marginX + width, marginY + height + 2) painter.setFont(font) painter.drawText(marginX, marginY + height + 4, width, fontHeight, Qt.AlignRight, s) if not finishX or not finishY: printer.newPage() page += 1 painter.end() ########################################################################### ## The methods below should be overridden by subclasses to get special ## behavior. ########################################################################### def filteredItems(self, items): """ Public method to filter a list of items. @param items list of items as returned by the scene object (QGraphicsItem) @return list of interesting collision items (QGraphicsItem) """ # just return the list unchanged return items eric-6.0.8/eric/E5Graphics/__init__.py0000644000175000017500000000026412451233372016514 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package implementing some QGraphicsView related general purpoe classes. """ eric-6.0.8/eric/E5Graphics/E5ArrowItem.py0000644000175000017500000001117412451233372017062 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a graphics item subclass for an arrow. """ from __future__ import unicode_literals import math from PyQt5.QtCore import QPointF, QRectF, QSizeF, QLineF, Qt from PyQt5.QtGui import QPen, QPolygonF from PyQt5.QtWidgets import QAbstractGraphicsShapeItem, QGraphicsItem, QStyle NormalArrow = 1 WideArrow = 2 ArrowheadAngleFactor = 0.26179938779914941 # 0.5 * math.atan(math.sqrt(3.0) / 3.0) class E5ArrowItem(QAbstractGraphicsShapeItem): """ Class implementing an arrow graphics item subclass. """ def __init__(self, origin=QPointF(), end=QPointF(), filled=False, type=NormalArrow, parent=None): """ Constructor @param origin origin of the arrow (QPointF) @param end end point of the arrow (QPointF) @param filled flag indicating a filled arrow head (boolean) @param type arrow type (NormalArrow, WideArrow) @keyparam parent reference to the parent object (QGraphicsItem) """ super(E5ArrowItem, self).__init__(parent) self._origin = origin self._end = end self._filled = filled self._type = type self._halfLength = 13.0 self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) def setPoints(self, xa, ya, xb, yb): """ Public method to set the start and end points of the line. Note: This method does not redraw the item. @param xa x-coordinate of the start point (float) @param ya y-coordinate of the start point (float) @param xb x-coordinate of the end point (float) @param yb y-coordinate of the end point (float) """ self._origin = QPointF(xa, ya) self._end = QPointF(xb, yb) def setStartPoint(self, x, y): """ Public method to set the start point. Note: This method does not redraw the item. @param x x-coordinate of the start point (float) @param y y-coordinate of the start point (float) """ self._origin = QPointF(x, y) def setEndPoint(self, x, y): """ Public method to set the end point. Note: This method does not redraw the item. @param x x-coordinate of the end point (float) @param y y-coordinate of the end point (float) """ self._end = QPointF(x, y) def boundingRect(self): """ Public method to return the bounding rectangle. @return bounding rectangle (QRectF) """ extra = self._halfLength / 2.0 return QRectF(self._origin, QSizeF(self._end.x() - self._origin.x(), self._end.y() - self._origin.y()))\ .normalized()\ .adjusted(-extra, -extra, extra, extra) def paint(self, painter, option, widget=None): """ Public method to paint the item in local coordinates. @param painter reference to the painter object (QPainter) @param option style options (QStyleOptionGraphicsItem) @param widget optional reference to the widget painted on (QWidget) """ if (option.state & QStyle.State_Selected) == \ QStyle.State(QStyle.State_Selected): width = 2 else: width = 1 # draw the line first line = QLineF(self._origin, self._end) painter.setPen( QPen(Qt.black, width, Qt.SolidLine, Qt.FlatCap, Qt.MiterJoin)) painter.drawLine(line) # draw the arrow head arrowAngle = self._type * ArrowheadAngleFactor slope = math.atan2(line.dy(), line.dx()) # Calculate left arrow point arrowSlope = slope + arrowAngle a1 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope), self._end.y() - self._halfLength * math.sin(arrowSlope)) # Calculate right arrow point arrowSlope = slope - arrowAngle a2 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope), self._end.y() - self._halfLength * math.sin(arrowSlope)) if self._filled: painter.setBrush(Qt.black) else: painter.setBrush(Qt.white) polygon = QPolygonF() polygon.append(line.p2()) polygon.append(a1) polygon.append(a2) painter.drawPolygon(polygon) eric-6.0.8/eric/eric6.desktop0000644000175000017500000000061412456712102015051 0ustar piotrpiotr[Desktop Entry] Version=1.0 Type=Application Exec=eric6@MARKER@ MimeType=text/x-python; Icon=eric@MARKER@ Terminal=false Name=eric6@PY_MARKER@ Name[de]=eric6@PY_MARKER@ Comment=Integrated Development Environment for Python Comment[de]=Integrierte Entwicklungsumgebung für Python GenericName=IDE for Python GenericName[de]=IDE für Python Categories=Qt;Python;Development;IDE; StartupNotify=true eric-6.0.8/eric/icons/0000755000175000017500000000000011720731724013564 5ustar piotrpiotreric-6.0.8/eric/icons/default/0000755000175000017500000000000012557365404015217 5ustar piotrpiotreric-6.0.8/eric/icons/default/drawCircleFilled.png0000644000175000017500000000105312342633754021121 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¼ÏáPLTEˆˆ ™™™››ž¢¢¢²²²´´·ÆÆÌÕÕÕÈÈ˺º½»»½°°³°°´ÌÌÒ¥¥«««¯¬¬°³³µ¶¶·ÂÂÇÃÃǽ½Ã¬¬°¬¬°¯¯±¯¯²¦¦«§§¬ËËÏ  ¤¡¡¤±±³²²³ŸŸ¤¡¡§ËËÏššŸœœ ®®²¯¯´ÂÂÇÄÄÉ¢¢¥££¦°°³˜˜žššŸ««®««¯ËËÏ——œ˜˜ž®®±¯¯²°°²²²µ³³¶´´¶··º¹¹¼¹¹½ºº½ºº¾½½ÀÀÀÄÁÁÂÂÂÄÃÃÇÄÄÉÅÅÉÇÇÊÍÍÐÐÐÓúõƒ:5tRNS.//559=>>FPhhi‚††’˜˜©©ÍÍÎÏÏÔÔÖÖààäééêêëììÊåGK¯IDATeÁ‰Za†Ñ×6ˆ¨D‘’[¤¾H»²uÿcž1æ?O WŠ $¹Zs8lÖr$ÙI·þäZµÓø sùE<¥¥f%6¬Ì·ö|X¬Ý*äˆNò‘™ U !Ãp/Cx”á ¸–á8—¡ñü»B&ù8ÐQH—µØÑH{žclœ|*à­ŒçôU¾— >{ð+×σÍNç¢7÷."%p%Øú.]AVVÆIEND®B`‚eric-6.0.8/eric/icons/default/sceneHeightDec.png0000644000175000017500000000136412342633755020572 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ0*M'CtEXtCommentCreated with The GIMPïd%nGPLTE¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀ¡¡¡§§¨¸((º’“ÁÁÁÈ45ÏÏÑÕÕÖÚÚÚÚÚÜÛÇÉÜÜÞݵ¶ßßààààààáààââÎÏââãââäãããããåççèèèéééêéêêêêëêëëëëìëìììììììííííííîöEöö÷÷g1÷÷÷þþþÿÿÿ·}w¨EtRNS #*+128:>@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜bKGDlÌ0;¹IDAT•Á=NÃP…ÑonæÅ¦ˆ@ŠDØû_ EšKVxñ ñoCÎá1;½ð×Å÷ïÙbÆ]’}ÑÕ»æÓ-¾›`õÓ=÷û¡OÛSÇFíµdCzêMLc_©<ºfšù1Å¢0Tf)% ³«΢u6…UH<"ñÈNljea« •™$U ÊÄ̹1)»3ÏóÀÈòÀEƒ™Œ³Ùë!3ÝL6j%™ôÁ¿˜éÎ4²eÜýªF†Ð¦ÃIEND®B`‚eric-6.0.8/eric/icons/default/pluginArchive.png0000644000175000017500000000210112342633755020516 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<¾IDAT8Ë••MˆE€¿ª®šéž™dwg“è&°JBÀH„„ˆž‚ò^‡é?~ ,òeƒ1VÊu=Q™a®ÚÂõNÎÖ‘ -Ìe|¬Íb¯`jºÃØ–Œ¡í{A®þòÍ*Cί̹(£WÞyŒ54dŽ©ÞiÝ15AA«î1Ú²{×8:ÛÆµßϬñÞ­{çðe¥Mˆ^9ï„Vݰuσ3W.P—|=¡ô†ygרÀQ¼2âƒrU…ˆ "„î<Ú¦ ëy¶·0µ›Xc¸6ãÿ|û´6>ŠònÉc¡\˜gtÛ½$,•–ˆ V¨)EðáÎÐ`!Q&¯+ç0"ðçÕߘ_è°Ý–8§@dÉ( Þùå2[vnùB9%Ê„pîŸT4“@¢ ¼ËóV@© üº¯­µ2Þ{U9‡Kž)ø@ÐÎÄQi\µT­e”eO™~™ßˆ!âb‰ˆP0 QoR•£YŠ„ˆv¬ªU¿ª¶ž¡éõó33åì÷JDøàµCÏmn¥KðéBµ ÛlÑV]ÒÌb¬Åƒ­Õ™íп¹° dÍÍôºÝnáÜÓo87¹¦¿ÿêÁ‰4Kßè†Q{O£Gj ÆŒ±X[cv®C¿·ˆ÷+ÊûP89ñö'ç^Ú°Ñ¿÷ʇ[Ù‹¶f1·<¶ufgçÈûÝ¥n£ä…ûµÈ}t¦{×/Àñ—>Ùj=›eY’XËü\‡ªÌ”U/¯Ô3Ç>;ÿåÿ~šVÊ»/ìÿbd¤u¤×Ë¥›Ÿ¾sòÂónº]¿)ÀáÔïvýß©þR8áÓ †IEND®B`‚eric-6.0.8/eric/icons/default/chatUser3.png0000644000175000017500000000203312342633754017562 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs¯¯^‘tIMEÚ KTŽ‹ PLTE#Dm=++?00OOQQYYy(yŽ/ŽYYOO==ÎmÎËdËÇWÇl$lv'vc cl$lWW0YYYY‡-‡]]` `j#j‚+‚Ž/ŽÊaÊ©8©ÒxÒËdË^^ÔÔ+~)~¬9¬/ÂHÂÓ~ÓÖ„ÖXX|)|~)~::ÍhÍÚ‘Ú¢6¢–1–£6£‡-‡Ó|Óº>ºÀCÀ‹.‹QQ@@{({ÐqÐi#iÎlÎ{({‹.‹×ˆ×ÂIÂFFÓ|ÓÊ`ÊÐqÐÓ~ÓÇXÇ{({Ó~Óݚݽ?½ÆUÆÖ„Öx(xÙŽÙl$l::==??AACCFFHHKKLLNNUUXX[[]]^^a ac cd!df!fg"gi#ij#jl$lm$mp%pq&qs&sv'v|)|*+‚+‚ƒ,ƒ…,…‡-‡ˆ-ˆŠ.Š‹.‹Ž/Ž0‘0‘”1”–1–—2—™2™š3šœ3œŸ5Ÿ 5 ¢6¢¥7¥©8©«8«¬9¬®9®²;²·=·¸=¸º>º¿@¿ÀCÀÁDÁÃKÃÃLÃÃNÃÅRÅÆUÆÇWÇÈYÈÈ[ÈÊ`ÊËbËÌgÌÍhÍÍjÍÎlÎÏoÏÏpÏÐqÐÐsÐÑtÑÒxÒÓ~ÓÔÔÕ‚ÕÖ„ÖÖ…ÖØŠØÙŒÙÚÚÛ“Ûá¦áä±äÿÿÿ3>þ•QtRNS ##%&')*+28<@@BMMQUY]mnoqrrtuz|„„ˆŠžŸ¬²³ÁÇÈÙÚÚÚÛÞàäääóôôöùüüýýþ<ïÎbKGD®¹k“§*IDATÓc`€n]K -.4 ìUÔÝo/ˆ*Êf’Ó¹hÍT+aé, â™K”H¡«–Dä6÷ôµæ)£ËMO.¬®.(‘AæpnŠŠOOÍtdGµSÁkzmi‡§,º õæ.[:Í]TÞ;µ¼2%@ U”Ç%¾rÚ’¹Ù"(Â&%%½³V¯“eŽ,ÊëžQß3cɪ ~âHšUÙµ]SfÏ[ÙhŒ$lYÑÚ;irocœ#\”Ï'"¹ ®­»«¥,&M.¬Ô›]\ÝP_‘§Öo ŒLÈÎ/*̉Ê1€ k,KŠŠOÉH‰ ž¨pXÑœ•X3Ï–.Ì"iææ¿|áüž®¦¬2sŠ)êj+Šr2€$WNOäIEND®B`‚eric-6.0.8/eric/icons/default/ircVoice.png0000644000175000017500000000143112342633755017466 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<•PLTEÿÿÿ€€@@@333€€ª ¿DD3P@0#­±4:Ê:@Ëi\Hƒm[_OBGN¿wu“‡q^?FÁ‘yf||™YcËiX\iÌh{Óq|Þ”{fz€ÜdxÓ_vÝlƒÕdàs†ÖsŠ×o†Öl‡ç‚䫎sŽs¾¡‡Î®¤·ñ²¾ðq“ß}˜ÛĬ•µ—~ª‹oϺ¤d¢ügŸøh›ïz«ùƒ¥ëƒ«ø…¯ý†¯û†¯ü‡­û‰kLбûŒ²ú±úŽkP޳û´û¶ö”³ù”¹ü•sX–¹ü˜y^˜¸ûœºøœ»û_¾û Àù¢Áû£Âü¤„j¤†j¤Âû©r«‰i«Äú«Çû¬Œr®Èù±m±Èù±Ëû´Íû¶Îú·š~¸Ïú»˜y¼Ÿ†¾ÓüÀÂÎÀÕüÂÕúÄÖøÆÙüÈ×íÈÚüËÎÜѬ†ÑÜõÒ¹¡Ò÷ÒÞúâÔËäȦä˵罒ê•êÅŸëÉ¥ìÉ¤íÆœïÙÂðϬñ×¾ñØÀòѯòÙ¿óÝÇôÜÂôÜÅôßÊôàË1Hå4tRNS#-2÷pÎý!ªÊÿ1Ün¿4„†ifDšñq2«ß¿ÿ¯q;e,ï]Åp¦5£»µžt[ˆ°˜ñYXñYÉ—n̰?¯ß”vËøå½.vµÔ}wp/½/6BfmDhNÆîþYàÛ—y˜Ý¼†‰ŸÔéáµÁrúrŠ {ãí#/ôõ6#FH88=’ÆŠðõõ æ~û›«w²ó„ö^zÊ2è[×›± ƒ½­ý»šÈz™BÀbfƒ†ºhi¬cOƒcâÍn¬ød¼€¬pp_’Á—›û‰Ù‹ÕWÀô”&ÓÉc}ûšÈ2^H¦²ê‡ä7ƒŠÌ+†¬z™BHÆS2^H_g#é¶ú£2ùÃèv°qï÷´'Éù!9_ÉyJÎñÕòÅÕEî,åùõqϾ{À¦ÄÈmh¤ó!·¡ô´5€¸355–oìO%ܽ׺“€€Ñ72(¨PsUþ²¦üÿó’ÏZ1ÖÏÏEûغ¡±ü•pÖV ªÊ@§£=åÊ ÂO6Xö,ˆ–Ñ(©†4P—ÈáîJ‰Æ¸’Œ;ŒU壑N†4U“3÷˜ý¥TÉ2DX/*ù¢¢jÀšæ­“glT„õ¢0bùêwN ¤˜>u j^ ,û‚ª*DÀ(DªÀ¶.•,ª—Š ¡Ô9ª‡ŧ ‘¨ÿf«ÎˆøUw…YÀ˜šFÔØÆT)랯5³•í¦_žÃº›XÆEÕ¶TƒMäžÎÚ[úIÇýÚ},îlEðl`U÷³å¯† ÆÍl; zî¥+Xw»6ËÄ!;²§Â{µ‰‰¾ \³µ¨p°åüö“c cç±¶œeôPŠ×»x¸ZâÑj‰îzŽ¿’$V)óÄõ¤NQÚùÚ<÷$…§sÌ舗hoÚ…Ö„°â+O Ê~×C€Û¨ŽéTÛÒ®½|ŒÃd&QŒY!fÁ(…P(*¡r ÏêTû•ÿô‚TŸ®îGƒ  ”,¢YB³ S-s»>M"b8P$ʳ¾j6”}Ø|À{fú@¡lÿ—cmL‘ÐÒ–IEND®B`‚eric-6.0.8/eric/icons/default/pushBookmark.png0000644000175000017500000000244612342633755020377 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÛ 9‚ßÚ!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“yIDAT8Ë• PTeÇWYv¹€¦â³„XL¸á(øÐÒL$"ØUŒaÚeñ±nùˆ ±_ °¸¡J(HM“‚É#œå±Ðò¦ØçÞ‚‡À¸3¿9÷›{ïïž{Îwvy¼—ôÔA_sºj3qD¡ÀÌ·ãàì}aH¼!8›“²‘]»mËà®Û,‹×»¬‰|¸jƒdOÁ{Øv?}ÚTè[/-§?Ošh¨Ò¢`µ8Ô8xžÅ²Í©Xí•JÙ—±Ò¹îßÁÒ%B9‚x“ åÚ»žè×&’L4„R:ß…ˆh˜,”ƒ?ÿ Ñ1î³3faë+|Sª-ŒÞ8ª3ÄÞÑZ^Ò~kã² &?µÝ÷‡¾ù ý‰@bÊŠü‘§ ÄM¥ÇW ×°í‘ùØñé-.úJ¯c–ó.äfÅ#+õs$Æ,iý @ºž«³ê˜ù¼ªt¦©£”¤Úp Ñ‹ÄëˆõÄFZ/ˆÄN&=p‘Šn/|vâ}謌Åï—m{rN2#'ñN¢ÀS}Õ¬ï¯òM$ZN"EgbÐ$¦º¯…“»„Ë”•H¸½Ç~ÆGQ…°'é6úqLȨ{÷A²¡¬!w&úê×Ìn³‰y$å2f'Ž•FÈïo‘X’žk(&Õ©Lzk–Òî˜4¿6‰ìC®‰l³hÊ`±è¬–|ÀàÝÝ´'%¶¨Ï¶FïÓ×vëhδ°EW™Õ— Æã9š ð\CuMIçÔQÑUÚ±â¶ñÄΚ›öèݦÃ`ÐßÎ@ßeèÌæßh†µ9‰ùÏǯÕÜtžYBè»-ÐU1MùB¨•F¨Ï2BË=Ï4t½—ä½ôjT_1=k0–xkýµWÑ­¶CÛƒ¨Ï™ŠGç…ý…‰‚Õ—{òã…ò_ÏÕÔåÌ€¶Ð º§¶ÐÕØ &Ý¥çøÂÿW¦8T§ â2ƒ¢SÂÇÙ'Ì¥ÄZÎ~OŒtÖä …Å»ÅI&ª'iSž×g™¡ü¿¡ä´ñäÑœìg°?Ò–ûƒéf;K 1ÁŽèfâ=‡ð Ü*S%F-Y+Q1_*N1^/R5a8k4U@u9Q"An&Gy(Iy.Pƒ0S†6W‰7XŠ8ZŽ:c ;W€;^‘<_“>a•Ac•Ea‹EižFk Gl¡Mq§Np¢OtªOy˜PpŸQm˜Qv¬Rw­Rx®Vv¤W}´Y¶Z{­Z}²Z€¶[y¤\¸^„º_„»`†¼b‡½c{Ÿd‰½d‰¿eƒ®gŒÂhÃjƒ¨jÄjÅkÅl‹·nеn‘Ão¸o”Ép”Ép”Êq‰®qНq¾q’Ár—Ër—Ìs•Åt˜Íu•Ãu˜Ìv—ÆvšÏw¶w—Åy³zžÒ|–½| Ô}”¶™Á€›Ã€œÅ€¤Ø¥Ø‚™¼„ Ç†žÁ‡œ»‡ŸÃ‡¡Ç‡£Ëˆ£Ëˆ«Þ‰¥ÍŠ¢ÆŠ¥Í‹¤ÈŒ¯â¢Â¥ÉŽ£ÃŽ§Ë§Ì©Í‘§Ç‘ªÎ”ªÊ”ªË–¬Í–­Î—­Î˜®Ï™­Ì™¯Ðž²ÐŸ³Ò µÓ¡µÔª½Ùª¾Ú«¾Ú¶Çâ¹ËæÁÒìÿÿÿÓhž3tRNS "%6:FIXev‚‰‰”˜›°°³¹ÂÉÉÖ×Ýçèðóúüýþü‰íäbKGDÂýo¾Ô IDATÓc` «Êa ²JêÏOÀåSÉ8pÐ]TTgêþýû]Q9e 7ïÙ»oŸ;3 LTP=sÛŽ»vï¶±spvóV†ˆŠëÖ¬Z·aÓÖíÛ·nÙ¸nÅ\/ ·BPÓ”Ys–¬\³výÚÕËæÍšàÐ /,oî›4mö‚ÅK/œ^—`æ×ðHÌ.©néêïé¨-ÊJŽ ´Â%kä—–[\VQQZj ±RLÛ/:%§¸²¾­½¡"?9Ìê@^EŸ¤¼²ÆÞ‰Æ¦–VîJ0‡3JèÅVuNži‚îy!µàî‹Ì0‚ŠCÊ u¹9–àÑŠ÷Ä <ÒòdE/RY³v÷IEND®B`‚eric-6.0.8/eric/icons/default/trash.png0000644000175000017500000000231312342633755017044 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<‘PLTEÿÿÿ̳¸¼ò}}ò~~½½…9¾÷÷‘‘¿¿äDDÀû¤¤À¡³ ¼½Å ÔÕ¾Ãí Ï9-ºÙ;1Ë(!Ö2*Ç''¾%%ÒEE¿ÇAAÈ ¿È ¿È ¸Ö"¿È ¿ÑNN¹EEÈ ÀÈ ¿ÀÓi11l22m00sv{{""|!!}~""€'',,ƒƒ88ŒŽ""‘''’,,šš66œœ??žŸ""ŸBB¡''¢,,¨©AA¯44¯66°±BB±kk³%%³,,µ,,¶**¶HH·DD¸II¹44º½''¾¾¾rr¿ÀÁÁÁ,,ÁQQÁnnÁssÄ Ä Ç ÇMMÈ ÈÈ11ËË--Ë22ÌÌÏÏ//Ï77ÏAAÏRRÑÒÒÒ,,ÓÔ77ÖØyyÙÁÁÚ==ÚvvÚ¸¸ÛÛ""Ü Ü!!ÜCCÜÝxxÝŸŸÞ!!Þ;;ß##ß''à$$á$$âPPãÍÍä))äÕÕæ++æppçeeç~~è**è..èeeé++ê**ê++êÏÏëCCí..í??íääîBBï33ïããñ66ñqqò¾¾òÞÞó33ó``ô66öïï÷ææ÷ííø99ùññûììüððüññ¬únPtRNS "##***+,..0358;<=>DEFFFHHJJLMNQRTaiqq££¦©©ª¬±¾ÆÊÒÓÓ×ßäêììñùýýýs£HPIDATÁËNQÐsïÌ”‚­TˆF £®ª;6ꆵ&~ª1ñ\š@Lt‰b`ðÑDÀ™ÎãŽç€ÑxÙ¿Ëk@÷¶G;©^Z¿¾<=Ï7—ÆY úÔwý÷ÈðäþJÞµmÛ4MÓV‹9Žú,„(õ}7ÈÑm?øx}•‚>Žn<.+ä¸*W_®ÚãêNýó÷\‰u ×EGÍÉß‹^V#b!.Wòy–©±¿¶¦ç BÄŽ6Ov{´ˆh ] gëýúbzþ=Ÿ(>Ì.Vœ~A„äÇÓ4&“´¡UKèVDhµßÖ.ÝYyXk!Bòlÿá­tþjúé®9$ÅnŠõ·7'Iæoò°…½9d0ëv—cU•uõîëg€ÛÛ1ö)Ï fy‘ Šb°»²i«®«»î?IL”?¡‡IEND®B`‚eric-6.0.8/eric/icons/default/adBlockPlusGreen.png0000644000175000017500000000223112342633754021105 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYsMœÞöœWtIMEÜ '+ë€OïPLTE333555777Š––žž’  –¡¡™§§›©©žªª¥²²ŠØŠŠØŠŒÙŒ¨â¨¨â¨«ã«¬ã¬®ã®«ã«¬ã¬±ä±¯ä¯±ä±£à£¨â¨¨â¨¨â¨ÁêÁÄëÄÅìÅÃëÃÄëÄÅìÅÄëÄÊíÊÌîÌKLKLOTU](y(.‹.9®9FÁFIÂILÃLsÐsŠØŠ´æ´ºèºÃëÃÍîÍÔñÔÖñÖÜóÜâõâè÷èëøëìùìîùîóûóõüõüþüýþýKLNORTUWX]^ ` c !d!!f!"g"#i##j#$m$%o%%p%**,…,0‘01–13š38¨88©88«89¬9:¯:;±;;²;<³<<µ<=·==¸=>º>?½??¾?@¿@CÀCDÁDRÅRxÒx~Ó~ÔÔ‚Õ‚„Ö„…Ö…‡×‡ŠØŠŒÙŒŽÙŽÚ‘Ú‘“Û“˜Ý˜«ã«¸ç¸»è»¾é¾ÁêÁÄëÄÅìÅÇìÇÈíÈÌîÌÍîÍÏïÏØòØÜóÜÞóÞßôßáôáåöåç÷çè÷èîùîñúñ÷ü÷øýøúýúüþüýþýÿÿÿŠÛ^ÆNtRNS Ö××ßààããäääææçêëíñññòòòøøøýýþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþìgËÐbKGD¤Y¾z¹ÉIDATÁC að¯ôþ²¹ê¼ä%½lv5î¹mÞ_SHôܶçw²y7ÆY¸Q¦Y%©d¡žÔíó«MÛƒþ.× ª %[«¡´Î¤—.'=»ÇƒÊ2ÕhìÌꬄ3¦ç:¼¨êи?kQ„ˆ"$ŒÜ>/j¥3«‡-A–‹Äµ°þ¾Ã4µ¾5 µwÅ-Î{·W:­›÷œ;Që˜m'CÑ'öøÃCÓ*Ž3þUNñÄ ”ò4_—Ržx„ßa‰u¹`^ï_JÄÊ÷׿ ÏüЖ¼Rظ8sxù¼Ù÷…î±» ½bk)ùÔ¼´)åI^üûM~LiÐ^°ÂûrÒìÿ9¹Ú—X–¿‡Ÿ Ùá5)å'qyžO >XZ¹er'ê¨<÷aõÏ‘ Ïn\ë]ˆš,ãCðñqy—¿‘vϦüwЇb,„:£ßÂââÆ }®JKÖYq33͘ h,däwl<í9=DD" +däÛêxwç A!¢ #¿«U@¼í9qÆ9gLÏ·5 @Y<-³éŒãʤçvÖ£| Jj ¨Ý¾€Ë×ÝìA€ÿZƒ‹o§ }IEND®B`‚eric-6.0.8/eric/icons/default/greaseMonkey48.png0000644000175000017500000000714412342633755020537 0ustar piotrpiotr‰PNG  IHDR00Wù‡sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< áIDAThÞíZkŒ]ÕuþÖÞçyßó²Çc{fü€x†¿óU ´R$šˆÔDUÕ?u”†J¥’ë"ZâFJU©­PRH°(")m°SŒmžÆÆ6{`Æx<öÌÜçyí½Wœ;wf<¤ØP!õHK÷<ïù¾õ­ÇÞû^bf|’7Oøöÿþ¯7ër}ÑßÜEW˯‘‚Ö|•aôÆØðq€^Ì1M8Ö«ðâ—g}©ï¥KIâíwS°äÝ’ø>Û+t:ºµŸ-e3…NéçÛáeK`Ãk“ªçѨMšFµÖËçT£6ðÃ&À¾ýW?v;¾Bƒ†ÅS^&×Ý?ps®³÷j°Ñ ŒN ãITƒN"03@ Ø^•ócx÷øþ Q™ªøËßü1ÿçÇFà‘»¬/ )þ¹wÍõþÒ+6Ø@Å6Ð FÇP*†IB¨$‚NB¨8€ŠChÃ+ö ÛÑ‹É3'1rüåºI‚ûîù ?ò‘øÁ]ôiùóµ›ïÎø™’°° 60FÁèFÅ0*šC „JB$QJƃ’5ps‹qøÀ³õ8®ÿñ·Â}d~øÔ¡”^5ôéBç²AåÓÒ‚HPz“1`Ö`£`T ­"§$âÉ ‰8U†Èu­‚WZ†ÃûžmRƒ÷üŒG>’2ª•¼¿­k¹ÛÕ·õó'ƒu £C°ŠÀ*tÜ:“FM˜Ì Ä ` b A" :q*(£»ÀQ’ùHúÀCwP‘‰¾¶jÝo»µ‰ÐIFG0:T”ÖØÌì7I蔌Nɰ™& Bj*ãGѹd¥EÂùÜ÷¾HË.;Gà¶|i‘k„•3à&@ÖQ3Þ£–±NI°™Q!i©A3J´À§*è$€ +È—Ú¡~÷²72ôå|±3—å4lˆAlÐѹ¥¶.d²9$I‚Zy•é µéfø(@Ç(¶w¡«g²ù˜5ª“ÆèÈÑ”3’°Š\.ï—ϹÀßè$þÁÝ´Ñ@܈71c3F… Î+×Ý’s¤@Xƒe9¸bpJÝšîD3‘‰09>‚±·_…6 ݽèîL¯1àÖþé‘#xãÀó0†á{+‹ã‡_ Æ«¡­A!Ÿƒe÷`øÐnØN•úÀ ÝKW$ZÀ_®ã?Þ°ï ¸çîëpÃ5½XÔ7Ôòô+'ªØýV‚_Ø…oܹ7 -“Àè»rΜ>7`Ù.ˆžÅÈg%Ö¬ìD¨{©÷Ê þË»w~]™ ø³Iüý»i£°ý­=«¯õç Wô£½­ ç§< ŸbØ–$ª°Ž‘É·§àI$ðÃÇ ¡œ,<øè © ‰ï?º g¦Bœ.>ºh^rÅNaÙˆ£ÂrÇ‹!© Å|–ueÑ¿8ƒ›oýŠ'¤µõþÛiãF‹{Û{Öx]+Vô#I€#ÕÃÀv X¶A€å¸)@ÄOŸÜ X\ßoª#›ŸgÏŽãßþýX®×óÒóH`»,Ç´\Äadea !Ž%Þ>¥‘$€#úzº0°á3žaÜ»€3ojëì¦îE€ñ 6³áåùmHÇOóÔ"Ü¿õV¬îÉb‘㛿-’J„xºh*@<`Û×>‹ÕKÒëߺëz´êhZƒ -aЀ°òié¶ؤXñ4úW ƒ6-ÈcIJR['|Ï4‚ùÙîeÚȵ— T •İ\¿FׯY†Ÿ}çèDƒ•AR a” ƒaCß"<þ·CØÂ`Å IF+$I?Ó ¬Â²»¶%çaa£»g)´Æ²…!dÌh5@šQd×+ ÛõòlÙA-2•z#q1BÕ ‘ÞN!gŸ ét@X6¢0†pR\[ÎÇBSc )FP†öMNŒ2IÉÐ|ü"¤å‚8?~j¦•¤_d[°².ö¾yOüâ9¼t윶<ÜΞ:Ž»v㥣Ga2°|§Unàìéá&> a@Ú)Z_€…pzäm6û„‚yøÈë/áºM·ø®”XÜɨÕfÙ;nA­!Ó—OŒGÿÀͺ>ÛÀ6¬¿7ßx,ÛnüÌæ›pÓÍ×!Ž£4w™[ÞykòVpæ|®-±zEêÔz­Œ]Ï?†‘~xµ“FQ´ãÉý— ˆ \ÏÆŠ~ŒOP*ÄáWw¢cñ2討¾+7bðú[çuÔÔ rYRŠtðÆ0Ì–$d|wν³MíšnEßkaTˆR© Õ³ÿ f×1ˆx $€z£'w>ıÞñ×?ŸíÈó†Û·åÄÒ²¶ÞtãM^÷âÅÔÞVÄ=÷,˜$>5°ýý½pý\³ëŠyÍlf^nÌtàÀ3ÞgÓ4³À¨NMàð›oàÈáC€ßÞUëQ©V!uß>úZ¨Ùá×Ô¼N|ѱз>Om×¾W ±É¨dy)ïˆu×þ]}õ lÛ=§´J"Ѽܘ«Ï#b.J¦Z™Âž=»pìè 9#¥5N0¯”<µm®çãÙwþtÑÒ­_¿Þîë_Õ¬ßbvü3gn.,Øæ(ÐR¢éù™ð›9~ý•ýxùµ×åéò=ßyštiÃi!npýŒ],Àl@ þñÇÏ ­TÄÚ¡ÕèYÜ!%¤ ! …˜O¢é$ÃFih£aŒÁùÉi¼vèÆÏMã«w|®¥Lww7ü·ŽfÊ׸4 ¬uŽã¤£H6 n¹áüâùýصçehcÀÌ0ÌথB¤$Ø0 ÄÍs͉ ˆ°º¯·n¹v^Xù¾×qží¸Žávêw<®ë¦/ f`u®øêí ËI$@: Ù<vÚI6‰k@'`Ӝɩl"˜¸NÂy Édá8Æðj""~Ÿ8_;nƒÃA °1ÍØ7ÍX'0¬B çäÁ¯“’›ŠòEó!%™~šæ3ÄÖÛàˆ>Ôœxë31ÓÉF­ŒF£š&Ù…Ö¬óÌé¢Vk®µÎë…ÏϹoæ¸V™F„ A#?x†£KšÔÌ®z­ÂgÞ{oÞË’™m\ ìÂë¿øŒ½ƒFÌ».yUB3v×j•úØéq$qxçô .îá™ó³äõÅÕ# }çÔêQM3.$öÔj˰ÀKû^€VÉOÎ #Ö±&É ž™ â$Æ‹{žG¢‚0,°÷’ lû)­Ÿ;{æ$Tû÷þ*]Àm•½…¡q±ØÕÞî´•ò–Q!TÀs=Š%ä EäóäòEäò@µZF­\FµZF¥RA¥<…( ›Ë*@¥–ð™©0*'Ù¿Ý;ý©Ç˜¨áè|>¨úÁñãÏD—EIäË„üî̹¾¡â»éH³¶£-g• YI00:] åÖè’[£SšÉfc&T1OL‡Qbh|¸¾tÛ‰zφX‚˦ÀLH)ý(’žeÅ^BäK!¼eÎø•«ògþÐ¥èÇv’lÆv2®mII‚` 7+ŒÖZ±âZ ƒ V¶bûØh£ôOÇë+ö É¡a´1¡mL{^xYr¶oß.ž~úi/tÏ COY–ÇZ»,¥+q=—³ËÝ÷ÖvÈêµY;^+aÚ“L†`ˆD Q ”}d2Î<w¼RÖùóÐ:ÖBD¤u$,+´µcß ˆ>üÿú'¦¡¡!G©’›Ë…®RŽË®v`ŒÃl;¶‰”¥É¶iiŒ‘Ì’, ‘f!„6,µäD1[ $b N D,“$BĵZ-Êåráû…Í%ÿJ¹eËkrrÒíí¶™Œ)+„oKYRJi´–±„± 13 %X e„”Æ0+¥lí!H´ö•N\*!ܼys¼mÛ6ó±ýÐ=“#›7o–£££²X,ÊZ­&}‰LüH8a(À¶m8Ž ’Dg‚@WÚÛuvb ê'žxÂð%€ Oúßmþ‹³ åbéÂIEND®B`‚eric-6.0.8/eric/icons/default/adBlockPlus.png0000644000175000017500000000253212342633754020130 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYsMœÞöœWtIMEÜ2* n`«…PLTE333555777Š––žž’  –¡¡™§§›©©žªª¥²²¤¶¶¤··¤¶¶¤··¥¸¸°ÍͯÍͰÏϱÐвÑѲÏϲÐгÒÒ´ÑÑ´ÓÓ²ÈȳËË´Ë˵Ë˶Ì̽ÞÞ¾ÞÞ¾áá¿ááÀááÀââ¾ßß¾áá¾ââÀááÀââÀááÁääÁååÂååÃååÃææïðñòîïððððððñ òò((ó77õSSõggõiiömmøŒŒù  úÂÂûÇÇüÏÏüØØýÞÞýßßýååýîîþééþððþññþóóþ÷÷þùùþþþÿÿÿìíîïïððððððððð ððññ ñ ñ ñ ññññññññññññ ò,,ó22ó;;ó??ôDDôPPôUUôVVôYYõOOõRRõWWõXXõeeö\\öaaöqqø‘‘ø––øššù––ù¬¬ú¦¦úººûÆÆûÈÈûÉÉûÌÌûÎÎûÐÐüSSüÉÉüÐÐüÑÑüÒÒüÓÓüÔÔüÖÖü××üØØüÚÚüççýLLýSSýUUýVVýXXý[[ý__ýááýääýååýææýççýééýììýííþNNþUUþXXþYYþ__þ``þaaþííþóóþööþúúþûûþüüþÿÿÿXXÿ••ÿ––ÿ˜˜ÿ™™ÿššÿÿ  ÿ¡¡ÿ¢¢ÿ££ÿ¥¥ÿ¦¦ÿüüÿþþÿÿÿŒÃä_tRNS ÖÖ×××ßààããäääææçêëëíññññññòòòòòøøøøøøýýýýþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ;{‚hbKGDÖçµj©ãIDATÁÏkÓPðï{}Iš¾ö™®Ö© :g‡`c‚x'¨à/¶KAÿ€ DóàQÐK™o^zЊ—á<ÈaJ'΢“ Ö)Ó \’6i——äùùÜ/h%_ 3?ÂíL0¤4?/žö{afÎÇž% Z øh†@ÙFÔ¨W ÷¬úÜЪ­ŠüT›Úv3ÔÏë×SDbŒRzH¦Sמì)ˆú d<ì0Ò.lÔ¦<2ø|¶2$œìçI$‹£eJƒ…ûgØ,>úr=U< ¼‰Ž·v‰u( ÃÈQ%›í±\nñ+©Ou(ëáëÑýMúx©Ó÷[­õE¡3(d«+ys¤{Ûµêñe‹‡¿…GD9¤Ý\5ww ûÞ¯YŠ!a{K#Рýîˆ)’« 4LôÒÍWßÛñ’{R…Ïü?°‰d\PŒ/‡§N,ßrç÷'#q2øb渫 Š®ŸÊW+&Iž7æÈD_jIÊ´€¬©ùs=ºíUkÑ#m|3¸öEò¯úütÇ¡¦·uén"ÀÀ¨&w.lv Mî*Ö¯²²]lD÷¦7;," ))ÄBÐWH:{Úë²Xf/¯ù:€ÿÜñŒà?Ή.©~IEND®B`‚eric-6.0.8/eric/icons/default/sceneWidthInc.png0000644000175000017500000000134612342633755020457 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ/¡ÉþhtEXtCommentCreated with The GIMPïd%nDPLTE¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀ¡¡¡§§¨¸((º’“ÁÁÁÈ45ÏÏÑÕÕÖÚÚÚÚÚÜÛÇÉÜÜÞݵ¶ßßààààààáààââÎÏââãââäãããããåççèèèéééêéêêêêëêëëëëìëìììììììííííííîöEöö÷÷g1÷÷÷ÿÿÿ¨O¥/EtRNS #*+128:>@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜bKGDkRe¥˜®IDAT•ÁÁJÃ`…ÑïÞL›¸…‚ú¾ÿã¸pã¢1ZþΘ*Ñfã9¬Óó#·>cûZ³¢¦1öï¡üê“«ãø0mOSE¶»‘›ê©(¿˜ßò£\»Nt»2kÊÌK Ê@3Kn Ll.2°Yã€h6W6™ÇÎ@$K²™KmVH¦qCŠÚŸ¸(H{é龪B²ÎÛ²ßøÉ3ùLyV9û˜BˆÓÐ=œIEND®B`‚eric-6.0.8/eric/icons/default/tabClose.png0000644000175000017500000000163612342633755017466 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¼ÏtIME× .,˜ËPLTE€m¢,,ni j~  c  ƒE‡u¤u%#X†( p$!`"¢<9¡;5ª52ïïïððð /%©5.\.#–RU®<.¯NB°9*²G@´<%´A7´LD·>%¸¹¹LD¼ƒ…½ ½PH¾KD¿\JÀ}€À‚…Á¢¦Ä4,ÄF>ÇULÈÉvwÊ>>ÊKKÊUJËÌIIÌL:ÎJJÎ`PÏ0'ÏZVÏwwÐÑkcÑ¢¤ÒÒYJÒ€Ó\VÔ«¬Ö´´×73×aQ×fZÝhZÞddÞwmÞ²³ßßßààplàpnàààáá2.ââââãããäääåMHæææç†~çÍÍè[VèèèéåæêêêëëëìB;ìÚÛìììî62îîîïçèðäåòòååó†„óîïôˆ†ôïðöññ÷ôõø÷÷úòòúøøúúúûûûüúúüüüýýýþþþÿÿÿØ.ÉG8tRNS &,,-23579:IDAT•Á½JBqÀáßÿ=¯y D©ŒÊ•¾—. ¡µè.º‰†Æ®¢khrk¨!Z‚¨EÅ( û¤t0SžòëdcÏÿÅRáŽzKå/ÁˆÔ³u Sk2"ˆÈ¹uÖ •Ï]9 )"ÖÜæÔiõºœ ÞÐgŒ€¨–ªéR¬¬`zÀ€´ §hhù¹{¹e°@:ÛE·¨šL*À€b¯ämÇtmçƒ_ê–3«õ¶Ï.V6”×,FR­·B8¦µ¶Ë@çQgvü¯ÙûèB|÷øÖeÄúz‰œÜ~¾7âé‡:cB ?0±fÌ7œ/Tÿ-ï¿IEND®B`‚eric-6.0.8/eric/icons/default/editRename.png0000644000175000017500000000056512342633754020006 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<lPLTEÿÿÿˆˆˆˆˆˆˆˆˆˆˆˆˆ‰†ŠŒ‰©ª¨¬­«ÃÃÃÊÊÉÏÐÎÝÝÝöööÿÿÿ«/òtRNS "#+,36=>?FIPSUÙÚ‚`ßãVIDATÓc` ?—Äâ rŠ@N‚ARQI ()J…•e¥¤ePÄ!ÂÊò ÊtÆî¬îÆáKaBÀÄÂÆÁÅÃ'(,*&"ÄÏËÍÉÎÊÌ}$a#EzD+~Ãt.Ø>Ï{«µÐßéìkÓfàùi„ˆI€4MÀÅ`c°1Øl’2$e4*AT$àøŽµØ|Ïû^ç ={~j’¹vödû„™­ÏC$"Ð!VÀUÀVÀV )£I â"T Øè‡6­#¾Ñ¿~É6÷©÷ °ªY÷ å–žs¿Ìš8» ZA(ƒ–Aˈ+ƒ[BmâÄwÑx7x†ŸuRºrm{ƒºÕÏðС·ý2ßOlo~nnG’ ‘Tx(àW¼Š^Àœ¢ûà —Ž²¯y:Kmu1÷U¯2c %®¶¯žŸòS# *ø b†@ï¢ñM´ÔV-ƒ‹„#ÛÅÕ„Œoët}<äS¥­Ó üô¦ù#¹u´Ùd©j@Ò@àƒd¨ƒ´0¸p¿ë£Š¡Ê¡—À&šõR€€„ i H-H$>˜T¨ß7*†*ÅD$”Z#€ðÈ€Ô€d€ðA ˆS¼<—HU Ul¬M~ PQP@¹OzO ׺§Â}ª€… l¤ã©âSÅ%dÅW4I Ž…‹? 'w+µÛ&$£[dΜWŒ´.R‚DÑŒ¯Ø˜‘Tñ©bcŠQ1äÖí˜ü)¥§K£bQ¿¬óØX;ŸîWwÁ×Óµõâ7úAïV6Í“ÌØVC¥°q©L¡Êwm„ OÝ}ç×õjÝ^`kÇaúøß¶‘V˜Ð[–i¬KŠW—w¡ÄCD`Ü‹qú`ÆIEND®B`‚eric-6.0.8/eric/icons/default/vcsUpdate.png0000644000175000017500000000240012342633755017656 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ hXDtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“dIDAT8Ë•UKh\e>wîsî™dæÎd¦¦ j‹¨)¤I-€h( U« âBPW.\¹r!¸rÁMÖÙ´P ¾ÐJK2 ÑÄh‰¦à£i;•dr“y?î§ßù›&YÙ'wîÿøÎw¾sÎD{¶¸¸H$Z8>R¯×Ÿo4¯ö÷÷Ÿ …Ba]וN§Cív›TU%ÏóZ•J¥\(V±w) ^-—Ë›Žã4&'';Œ'ñŸ……£}}}oÃ_ÃA½ÛíR­V`²,¿³ñ›çĈx¥Ré"Í àoSSS®2;;k*Šò²eYïG"‘¾€M("K’Ñ4M€"±îf`¬ëÈôf³ù²ùÛ—œG:/ÀGø §íƒòEÞgÚjµÄ>{oüŒðs`oA›aN‹ø?™1ÿf`° jµz@ Þ÷s0~çõíííÓ|Žmhc"ޏŸ:;_êÕ×ÏÂÏÊgçw&ËåL °Ä7wvv¨œ™1_O_?£^lÀµq]×À¸\D$í"€B¦i mý‹ü¼²T¥¹kwAwo nè2™°éɇÁÅu0"wÙ¹Ú‘™¤R)̰‹E±~õ‡ ]8;Š€êµË_þDÉç\2 ˆ¨ >f:kÉ-Å)³,\Ìh4z¸T©R¹êÑa«Õ]ADÓÄðè¾y\Òx¢ Ãrð“µDQEßrGÜOÓ#g·Ž=é°¯?ô%ô²èYU‚U¹Â,rtö\Y"'×!Çi!E™\¯C…²KŠ|P ÎbífõѸ¼Ö›ï¥GXc .3cvfÌLYŠo—%Jÿì Um09Lf »=l»¤Qúz ½ æáP0:˜/GµzìÑå ÚÉUhk»H»ùêŠMTÈ!ûR°±Æ\Èg'”ÉzôÅ|–äDÿþpøæ5ZT­¹T‚<ü,KtìH»¾¶îÎÈããã è©£w³®ÜÇÜìÜ5q;JI[¥dh=SÚ$Ò#ݹ?4]Ñã\¸EC9XY¹òÁ'<ÒŸÂK`s,mf>00@ñx\dT›ôâÓ1úw.+tŽ„‚¤k É{½ŒO3F™¶ËtêñZ%R.󺼼¼ìáû¹†Ñ 0= Y†àR,£d2)¦0@.©RVÿªÑÃÃX³42 ´§®­oßÉRʺww(î¾ÓétSTk~~¾966v ýúy>Ÿÿí6º#…bZX“*å ¥Lr¶2”Ù5è‘!›ú"ºh»LŽ6þ\ü~0Þ8w4A¿LOO7öÿƒüoK¾¡à±¯^9;ñÌèIº¹‘£Ï¾YºÞ,ýýeg7{Ê\ýÝ£ÐÉõŠ«LZf0þã¯ÿÜÎ;÷ޥ͙ÕÃG ˜Í:‘5¬„»~ÇÛÚÌ~D­Ý9ª\o>ölƒ:/àIEND®B`‚eric-6.0.8/eric/icons/default/module.png0000644000175000017500000000046112342633755017212 0ustar piotrpiotr‰PNG  IHDRíÝâR pHYs  šœtIMEØm…$tEXtCommentCreated with GIMPWPLTEddd¤h£¼O»ÐxxÕQQÙŠØê  ñÈÈÿÿÿˆºñÎtRNS@æØfbKGD ñÙ¥ìgIDATÁ± Ã0Àû ^·ñöÀ"} ÷ƒêTÑØ¹C$`þ&ˆñû€{ïµÀôºê(˜Úþg2µzžï$JÝÎ%‰Q¶uIæÑoëƒèý*k­ïYíØ¢(G ø~¨MÚ(óIEND®B`‚eric-6.0.8/eric/icons/default/mediaPlaybackPause.png0000644000175000017500000000132112342633755021445 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<PIDATÁ=hœeàç}¿ïî¼^™›˜ Tª)»6®n„ >ë¤Í´vжge{¬‡–¸/~!ãJ' çzÎyÓ šJTz~t¨­ñ(Ì_;¢„Éæhnè¢ ¦Õ”‚ ©´­úÕŽ4Wß´NÈ>Y©¾;òŽ%mu¥R•±S¿¸££x÷‹íâ¸~x2uÎEÓ*QP ðŒBÇ?ºjoí|Ç˃YÞ6­aì¦/í€ï}êc'šZÞÃ`v¼'KCÏ{IM©4ÒÓÁ±Ç¢š†–— M–bZyÑP%b gèùOÔÔ½b$-Æ´0vVAòÐ' rä_YT(¼n,-Ä$!Èþ°çOÐwìIÓ~ð—,ƒÂJgÙCAÚi/êªT²†ŽˆZ:‚¤R9¥½2íF]'¦1eFðœB”õý.J»áÃvþ­?{ÁG¦5=AÓ³8õ¿¬£rê?ivÃùx£—7ê~vàÔPÛŒh™1£Òwß]uyãF/d¬~;Y+¬›×ÒPS€ÊØÐ}_)·n­2.uòÁd®ï —L©+Y¥ï¶»šÊGaþæ!ƒÕNÞLkCM¯zÍyÁ:Õ·Âå[G2€÷W\¯f+• …B¡èÚ¸³ 2>hçeK-`ßžÝpïv€§ÝñzíL:IEND®B`‚eric-6.0.8/eric/icons/default/2leftarrow.png0000644000175000017500000000231712342633753020014 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<©PLTEÿÿÿ@fURUp|KPmmTKMVjMWhDEGIKLNOPRSTUVWX_JJc T 6¨$ R  ’ U "f"›^Xc\!`  –’™ž yg1q1–oƇ‹Y¤ ¥ j ƒ­iD†DEƒEHHM’MT—TY£Y\ž\…¿…Bfuy|„†‡‰‹‘’”•—˜š›œŸ ¢¤¥§¨©ª«¬°±²³µ¸¹»¼¾¿ÃÈÊËSqcÓ† R ’••‡ž‘“™ž‘Ÿ£…¢ ®#!¡!"#"–"#“$%œ%%ž%'y')˜))Ÿ)*l*, ,-“-.ˆ..‹.0‚00 01‘1334{44˜47š78u88ž8:–:; ;=‘=?¢?@Ž@AŒAB£BC–CE¢EFœFHHI IJ¡JLLMšMM¥MOšOQ§QR—RR˜RT“TT¨TUžUWWX£XX¨XY—Y[§[^¦^`—`d¡dd®df–ff¯fg§gj±jn²nošou¸uw¯wyºy}¼}„¹„‡Ä‡Ý‚z:YtRNSABINY\qqs{‚…¤¨­´´´´´´´µ¶··¸¸¹º»»¼ÈÉÊËÎÐÙÚÝÞâêëììììíðòòòòúúúûýýþþþþþþþþþþþþþþþþþUÄ×3IDATÓc` 0¢ñYôt€¤ ?Š(—ÍCS&±à;’È¢.LØ ÎÝ».…d zpÿ®…eøÍ«W¤á¢¬§oߺqmYØù³'/ÊÀD¹ÍC/_ºpæÄ±Ãöí>% r9~äÐþ½»vlÛ¼aÍQ9ˆ±â{vnß²qýªKÍ›sP,¬½rë¦ukW/_º`îìYÓ§NZ¨ÖíìèêŒMLË-(,ÈNïQ‚"áë—šWVUSY’“ܧ µRØÉ-&1³¸¶¹¥©º(½_æ@[¿¤ìŠÆ¶îÖúÒÌ jpï°MÉ*ohŸï^Wœ1QáyfyOïê&;ÿü”iÈA%âêSnÆi<#a¦&JÀòÚO¶f`VõX¬… †ú@RÔ‘D,Nhtè Õ IEND®B`‚eric-6.0.8/eric/icons/default/globalVariables.png0000644000175000017500000000223012342633755021012 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ 8–ɬztEXtCommentCreated with The GIMPïd%n=PLTEeÚfÛjÜ"mݬØÿ¯Ùÿ!lÛ)rܶÛý0yß2|à—Èù‚¶ò/yÞ´Þÿ­Úþ&uÝOã'xÜ|®îK‹â[—äžÃò/}Þ0}Þ)wÝTã>‡ß²Þþ´ßþ]”åb˜å{¬éŒ¶ë4àÀæþ%yÚ3‚ÜŸÐøQ‰ß>ÞWä\”åq§ç¿çþ¸ãýU—㉷ën§ç‹»ð7‚à/|Þ2xÛdæjŸçc£êo‘Ý%sÛB‹â%pÙ”¼í¶Öö¡Æï+}Û,~ÛWàÀÛóÓòÿØN1áÚžIO€ùO|>IvUG¿,câý ø à,›vɪY‡~¡w0§ `!=âCcÑ«ÓIÔÿÄ“8C¼.ÒüçtøH‡Ç'ìóIEND®B`‚eric-6.0.8/eric/icons/default/erict.png0000644000175000017500000000745412342633754017043 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœÑIDATíÁyÞeaÀñïóüžßû{ïw÷ÝÝì&»Ù„$›;C(ñÂÐpT‹:´£Žíà8¶ÃÔ©¶ÓNíˆÌÐZ«£ô²í V¼ÑˆDj8‚ ¦„$äÞMv7»Ùû|ïëw=OÓNþ`PûG>®¸âŠÿ·„1ÏI^à·ä±ïÿX¾¸ì°µ®ØË”óIcŠ™dT¼©¥žwÓ&(·K£iAe4ÓÜ|jÃ;7½iá§óüÁÿ‘GvìRÓ“?I¹ÊÏNt÷ÜüÌ5³Å¹U&TNÔï¨7f³ž±£ØÑx2©#˺âVÖvU*e¼º ¦m?~´|&õÍÏÜ¿÷q!0\"xƒÜ{Ï;ô¶¦;—d­Ap qµ6´#Ýqµ°=nÊ´uuX­‹ÛÅt% àÕ‘¶ÇìèóBó4qS +V!ÊÝäæFÌÄè9FN§'õ‰>3°—K——øñþþìÞtÝ›s¾ÞèF#Ë;6¾¥¥-­b]™fÑž]Ak¢YÙÆ¶ãS?²“Ôàó\uÝ~~!¤(O:iÈE§¨åYP+Šh¥Š@®•ZÿÎOß{×ÏnÝùPÀEŠËäô3_n~äÀ;N=ýc3ú-©I‘xæÄ>‘º¦UTÕ$ËS³Ì5µ­½{A‚óÕ^‚I—eašŸÿôaªã–¿”¢I¢DÁd©NbÆÅö|2ÆqBYü«½ê9¸Hñ:½xäAgßΧ¶ã§O Bü¶Ñ§R›6¾Gf³ ÿ¬Ÿ[5‘ØÐÆ`ï‰lsî(FLQˆØØÊe809Ugé›ÞJÏU[ðKƒx‘ußÂÎ &‹ — uW¡MRQÙœoÑržÿ¡x¾÷åOöìøÏG?Rðݧ{V,ÒABŒ »^abt˜bµÎwîˆßûÛw‘Y¹×K#sXdŸFž‹Óóæ­l¹y;k;) ”_Ãë=H­oâ Ô| Ê6'Î+LÐ’uýÖvÕ÷ǽèq‰â7`Œÿ~ïÞ²wßá?«¦›½õ&ÛŽµÒÿìrý<üµûQ¦•|a ѳM¤c¢¢Âª›B–-ÉrüÙ.öŽ2ßô(ÑÅQùM „ÃH§Hy̧îÍ‘j’ 7 ÉÑŒW­Pz©i˜3\¢x¾ô…‘¾ýÚ•qþ:ݵ~MKg»˜è«¢Zó «¸UßõiÔ&FbŒW{‘Ö… ÚHggPÈšGßS³¤z$Fæ8¶w˜%K]ú†|>`2ï¢ìñ…ë D(ñÚ,YÚð2Š×À#>þW·~¸íÝ×Þ³|óË6n¾]\‚ssìâaFæ*øž&Ý" šzM‰gÙt{˜áÐÑ<ÉÐð386Š¡$-± vý%柯‘¯ä#)nh¢R®ƒ ð}Iè†Ò ª¼ŒÅkY>ûÁ`Á²Ï¬}ûû–w®ß&F§òì|ø!æÎôRŸ$»¶•B©ÈDï:„zÙc͵‹ˆ¥y öN³ò¦.ªUE¥Rpi h3ŠñÓ9RiÜ„@$-”­‘¢Ž2>„eôèÒŽ¶¯ìyazšK,^¥ì¾çV?™¾O¬¹~µI¬Ï=ô8'x€n]ãÎwßH#PLÈYVß°S×,\š¦suœ-·¶ Ó®½º‰ÆDFÎ7d.W§§£‰þg‡xñÀž’\— !òDŠy‚ª‹r5Q,üPAÛÈŸ$VÛßÚ¿¯às‰âUxòÙû¯ÿöÃû>1ï¸ëjö±.»škZ,6ÿÓm´t*T9>h³¹ézzO â¼}[7ý'G87Ò`åÛ²øm%šÚm|oŒw1‘DŒ‰ñ"A`±ææn*ù"C/ aj™˜@% Ð2@Xá\S4±ë³÷U¹È#.2ŠWðÜÀWלòþ¦sÓÍÛÖú1~þ Ûï¾…ææ"sá1Ên…©}ƒüüà·üù»¸íúULž˜ ïg³L͸që ìÀfj¨Æ¢žÙMÓÑ”äÄócäaëÍŽ;ÃÒ!• ¨V4Qc°“P<t(£á/ï†/§ø5vü»ÌŸ:úñ–ë7ܾâc=òjq5;¿2Î)=Dbº@0˜ÇóÚ}šl6ÍLß9d¼ %f¹áý‹9sÀAÍ@%)W ÊúÕÍ<¹ë<“é ­×HêýŠ©c9œj=¯I`!lÆ«Û }Uê©„Jüǧþu¬Ì%BÃEŠ_cº9ü€—4LwµZYQ'Â槆)ÎÓS„Ó%¼J…â´Ok{‚ù—òT½If/LRw3¤²pöÀ,Ë7†dÒQ*…:ç{'ÈÍWÙþînºW vÎÒû|™UÝ4uŒ%ˆÄÀóBGö6ÅÄç¿úté¿„âWøúŽ;¯e:û'1k>m%]ŠÄ®Ž3;2Iµï8¥´EfY’z]NJÂZ /¨†EÊEMé\ƒtfž¡:œxj‚l6NƒÝk$‹)´žgþ” -âs~Þb&QcYØŽ¤Ý”O,m‰ýýýæ^àW°ø%N½ðö1¿vw¾mÕ¹ákøÀqÜxŽÁýX^ŽåËc”§f)Mä8¹‚tÖ†HthÜbj²‚ƒÆ]21›ás%Æu¶ÞµˆÛôí+ƒÛÀ4<¢Z C&¦–$a*åìZ¾¼é³_üÎÌ!~ Å/q2(­Ÿ›k~Ïœ±X`:;c{·Þ¸ösýäþ=¼NŠK:(nÚ²zñ W&Ùõèw©LNQª†XB`f$aA“ÎxÄ´`zÆ|Ò‹ âžF0HaPJ"­#À‰g|/¤-iL÷Òô3m÷~ô“ûrX\dÌêÂ8½U;¶hØ•â,a­F½R"fCà *õBцxâ Dà]ƒï¯Ú7HZ´´…¤Ñ0d,Ïlì‰Út]êÞ»ï9Àe"¹èhøŽ•CÍÛÂÉfyê©ÑÑšÀ bxžE@šj¤¥1¡ æCµ¢)•Bòå€JCãi’ —XŽMĉ µÄ|" ÆŠéÌýúÄä>.#ÉE3…¡î‘‰ ][Ö°zËfú^x„¬<Ë‚¤"ÀA­npRHe! Ô# j®& BY„–Àõ …RH¹è#Bd’‰oÞvǪq™).êiY”:›ž'ž~„Ö¬dt°Ž7S#x؞ƒ×”ËP*ØAam¶@"±-AÌ–X¢á \7D!I’IYç{6.Ýqûö}—™ÄÓGö´O ¹Ñxó†Ï>‹™šÁvIM4â62€ˆå£¥@°,m,m°•@E$RZø‚ @†LhcB“ˆžnmƒ¼=1ëTêB$²%Z³*ŸsgrxE…[õÐFâú#4i%@ Òl!±•…’ 0¸nˆCÌÿÒ:“¹…mÓAs*T¹Ì$ýþ]wU·Þr‹®ö÷qx÷Ars–Ç(ƒíR^€­5ј$j„6 Á€hcƒëiBOãk--㪈,*':`£Æu¦% .3˜éûÎ?q¨”j)ÏXøuÐ…§5Â[#èš¡a´‘HaIc”²@üÀ ŸÀÓF[cqkÖRÎH,ßøìI¦£3\^Š‹L#rΟð{½Rx%ô<×ÒP¢ÁÀ2ÆB [ Â@©„±,0Fj_$RÈ0·jNÜž×RK#ûâñØÁt*~`|gïØGváòS\ôÞ·n¿0}æ¾ïdƒM"N<ËgÊ%ÏiTJR›@„ØF‰xDKš@ ŒeI?¢¢ ­DU ¼Ð—%;¢f¢Nd,@žÂ±F O}ãG½yÀðQ\$æôé?>—ö<Ñ“J.h ¢µÊ¬p««R®JíA*ÕŽmù¡atÕ¶£5)Z±Ê~Í+ØÊ™L§ã£žUONT¦¿ôÌ`7˜àev츷{jj~e±Xi }£|Ï#ô<].Î ¿^ •R&Q)]ßsF6²!•(z5·VªªJ™‰ÚOL6ÍW\qÅ+ùoJž–í¹fKñIEND®B`‚eric-6.0.8/eric/icons/default/corba48.png0000644000175000017500000000440112342633754017164 0ustar piotrpiotr‰PNG  IHDR0*z-O-sRGB7ÇMS pHYsaa¨?§i¦IDATXÃÅX PgþÁ!âBV (d‘¯5•’Ìn+ ¨•ª²€Ö&ºT²7«ká–$ÔRŠÄ#¢"š5è("ê ÷ÄJ‚”œ ‰œ*‡€0ÌÙ3=̹¯»™¶‡9fSµ¯þú§çõûßÿõ{ïý^#³ÂTªp.wI³äííÍb±††nݲ¥¨¨¨íáC-Ž›HÒétº»ËE¢Ÿ~1õ¥—¼¼¼|||`¥Ä××~æÎ™ó¨»ËѾÈ1 å¼¹s‘ EDD Ò’&“Ùd!š)“J/¿³2ÆV‹5åQ—;€Tþ¯¼ÂT˜››‹k4MFbÀd¢~Œ]8wŽÍf3õ€áº;;ÝàïOkY¶téÏ­­L(NˆÂGÃxoõjZ¸²Û- )ýýÇ-+•JŸ[…AŽ1oÁB¯Í›6Y,€þ E¯X!‘H˜h¬7·Úžv̰Ü`0|œ<î2÷½ìçaÔ×ÓÃv¡]#Q˜4¶tñÀäNP«” ßÙ³KE"fÐÐOLC1ô?¾}ëÖ­›7»:;uc:Û8cÚé'±x挙ím' è™d$=ý/f7Ñh”ryξ}Ë/ž6mÚx´Nž±k×Óþ~ “Ý…Y{÷¶XÎÇ ™H-㉤««·£}‚yh¥×¯_ CØy€Æô–‘X,~ÐbÙÑä¹ ¼ºZÉç›õz»AóŸêjHÁèEt2?ßNŽ 7ÒnÛ6væ µ—C@”0ø?xP…67×d‰åñ§$ƒ ¥³Ók¶/r…<=+¿û”HµÌÿ=†¶s§Þ` AÛ‚laÊÔT!µ§§¶½Ýd{¸ÌæÞÿ0BÇ:JÎ_!”g™©q”À9„PY` 2)IÆO”'CÆçËù²¤$ùúõ BŠ?þA××Ç d¶ØmL,V¼¶„´€}áBÃØ˜iB`‚©[Œ±Xf„\&„prh­g­å†*(¯»f²Dð8 @ öñ¡×Èy<£u&$ftà€­^Wî”yzb‡I$ȨVcÛ·«­åFSS 6ç8 Ò¡Ìçsó'*>ß0:аuë4Ö¢Äâ­[M6ï $Y»Öõíqµv]Æü«xýu¤ßWGG«­oÈ-šH–œŒ;°­væŒ;ð·ƒ××1dÐâØÇ«Bª5kŒ–(c1,g¿Ú±1œÛÆnHQ S½q£adøù)#6+,TΘN‰*¹\ƒ^ÇÌC ±¦&½ËGŒ>e,1ah²³ VÇÞ’ 5?þˆq¹„——¾«Ëd“g×=ï*B"„J!Ís…åBd™…–ùæœ9XB§ˆ‹SÅÇ«ââ•ëÖ)Ããážž„+°ÚZ“£LMdU‰DÍçi4?ß6®A¬Q|ßsút䕈DT¦¦’5}ß½ 'I£'kY'€Æßʬ,ìí·ÍFƒ‘†~³]tMvv6ÌAÔ6›ÒÔ~hÔëŸ÷ NÊj™âZíhw·ÝÒ ˜e¢RèfAVéD^žýêC*©¬0Z.ÔCRéßvì°UJÛ©¿·w÷®]¿ y• eþüù[>ú¨¥e¼º°z7[æ@NNk{Û¤ 4¥Bñ›—ýj¾­qÔfPbjµú~ssUyy™HÔÐpG.—O¨™þÃ_~ñóõmoks§¦†• ,²[’:¯©'Ի㽇Vûû7ß$jj2Üì:Þ[ÍÓjµÌ`rTð;MÙ诟|Bt^îvtçš Æ0»ŽxaSF[qçßwÒ}Ù¯ÐJ¯ZÓKöC¶îcö_nQòR‰$9)éWn¥©Ò½ aË;·­§¶¶–Æaê¡ZéQ’ {¤>ž¸Ò—)ýüìÔί-_~A Ëe¶QÌ„¢Ñhjªªx<žÝDÕóäI…HtòÄñ" ¨ð¬K€ hbÞz+*,,’Ãâpq¹Q\n$‡´aíÚ“Góîß½«R)™¦Âq¼E,üûë>?"4ôU640—/âp–DFö÷õvvtܼq#ÿرšÊJæauˆ(€ôzÈîFƒ†‰œ©|Z-—Jr¹N§cšnA“I¥j•J¯ÓÑ ËI…Œk´Îý¿è€®””;+(,ï`¶}Û¶òòrHùìÀÀºº:½N_S]ÜÑÞgâôâ… âæf¢ä¸X~€ó×}==p€´Zœ¡ã Æ;w@QsSõwhh¨µµu}||—K˦¥¥AšɪÊJ‹% Ó^.æÀÓ§p$ƒÙl¸fÓ½{éééî:}êñˆOž˜˜çU±´ ¤€ß-[6ø´Ÿ5eÊç{÷þã³Ïþ¼y³ž¬r®”\‚å`§D>OF†‘l™oüPoY³fÑïàI*B ЍÔ'ß‘‘‘¥K–¬xã ZfQTÔªØØá¡!„._”H$YYYpëò%ÐàÀ€\&ób±òå¿æä|uäðËËÊ& htD0oÞ×§OSÁÅÅÅ‚o¾™9cõ½Q222ÍÛûüùóà)ØC$¼ L—»úÝwáâê•ËÀ|ölH¥PÀÅç™™÷:;Ú!ÙlöRÆ<© èÁOâ´ääk5ßVWUmܰ¡±¡˜_æøgÆžÆ; {vï>zäp*ÊÊ‚ƒƒ÷ïÛ@söï_ýóƒÖC_ )--ÍÌÈØÑó¯/¾€Ð™Ô””ÐÐÐúúz»€þ p/ Œ¡Gc]IEND®B`‚eric-6.0.8/eric/icons/default/autoHideOn.png0000644000175000017500000000221012342633754017755 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¯¯^‘tIME× :fÓ õ‹PLTE9k$W¡ÿÿÿ7$UŸ%W£3$TœÆÓç*Q%X¤%>?v˜±Õ 9%W¢t…Ÿ'A\L"P•//U?[ %I%W¢0[%W£ 1H…$UŸ !@"Q–)\¥;j8%W¢ !7 N’!QŠ#Q“%TšIu$U(I3U*Z bˆ¾=R#GyЦÏ3N0^£$Rg1\šƒžÆ(Ks>k«*P†!Fz9cŸAn*Po2a{:džLr§%Om(Om-Oj<[‚Cf“Ms¦0Mg6PsA[s<^t† 1a|4X…Sz¯œ³Ó9[Š@e•Dm”nº!Ap,Fi/P€0Jl2No2V…7Ru9Qq:]ˆ;W};f=`“>Tq>`‘B`FxŸGh—LiLp¦Ou©Qp–Tm‹T~­Ws”Yv–YwœY{«Z~«[}Ÿ[·\‚¸`y•`‰¾a a§a¿bŸb€¡b„¬c”ÂhŽÃiˆ«iŒ¼iŽÄjˆªj¿k‰§k‹³kÅm•Én”Èoްo“Èp”Éq‘´r¯t–¿t–Çt¢Óv˜ÇvšÌvšÏw›ÏwœÐx—·y™¾zžÒ|™µ}ŸÈ}¡Õ~¾ Æ€œ¹€ž»¢Ð¥Ø‚¦Ùƒ£Ä„£À„¦Ï„¨Û…¥È…¦Ì…¨Û†¦Å‡§É‡§Íˆ§Åˆ¨Òˆ©ÏˆªÛˆ«Þ‰¤½‰¦Á‰¨Ç‰©Ì‰©Ø‰ªÐ‰«ÔŠªÍŠ¬Ò‹ªÉ‹¬Ï‹¬Ò‹¯áŒ«ÅŒ«ÊŒ¯á¬Ë­ÌŽ­Ì­È²ä°Ñ‘°Ë‘±Ø’±Ì’±Í’±Ø“±Í•¸ê–¸ê˜·Î™¸Ðš¹Ñ¤ÃØ¥ÃÙ¦ÃÙ§ÅܲÑå²ÒåÄãôÆ¢ñ@UtRNS  "&'-2ABEQ]dhkpuuvvy|‚‹—™«¬®°±ÀÀÉÌÓáâäååæììïïïïïïñññòòôôöúüüýþ À³bKGD Lò"IDATÓc` ðqbäÐ0gÆ1;vÃ]IÁñêõknh¢Üz!W._¾äŠ**m¹òü…‹/zŠ "ÙTü7í;rüä™S%Y> ¬ŠFú’@Q“êó¯Ùuðð¡ý›£Ô 6Îuf³©jî™:{Ѫ»woYÃ`UÙј©®”“[V×=mÎòm{v®[È`›4±)VK#0.-¯¼¥wæ’í'N¯í cЉï¯ñ–`µ OͯŸ0ëúÓ»"ØUM d€VòF%¤5LYqôèÒÉ‘2*ùe·Nßpîla²²w¤,²k'-<°×C”Å›\ºÁmSfÍrÁ@y»ŠÎvgÌàæ7N)u ,ʾöX#MHg|¼)aGë‘1IEND®B`‚eric-6.0.8/eric/icons/default/multiProjectNew.png0000644000175000017500000000256312342633755021065 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ 2b¡¯tEXtCommentCreated with The GIMPïd%nPLTE”RRR¾fff¡„„„xxxeee„„„ttt~~~ŸŸŸ‰‰‰©©©«««nnnfff›››ƒƒƒyyyŸŸŸ———¨¨¨››››››ªªªœyyy“œŠ’œ   ‹‹‹¥¥¥¥¥¥‚”¨´´´›ª•Ÿª˜Ÿ§‹›¯œ° µ¡¶“““‘ ³“£·£ª ¨±¿¿¿¹¹¹£«´œk–Ë{ÆŸ–z›Ä†£Ã£ÂÂÂ–Žšn•Ç”Š’œršÌ›ª¶ÀÀÀ¤°µ»–QÚÇÇÇŸ«¥PŒÙޝz¢ÒÒÒÒ‘®ÈÌÌÌÒÒÒ¿¿¿RŽØsœË½ÀÅÑÑÒŒ£¿ˆ‰«­®°²³¸«°ŠŽ¦¨ž£¬­ • › Ÿªœ´¸œ Ÿ$³$&ž'¼,¢/¦0©012Ž2¤7§:º:=’CºCCÃCD“D§G©L¯LÉN¢aP“êQ”êRÖSÞSµAT‘ßU­€VÏVX–æYšïZõZÐV\¸A^Ÿõ_Ë`×Yc›àg™Õh¤ñjÂik–ÍlžÞl¦òm­ÿpÄiq°ÿrÜYt ØuÍu«êy¥Û{¸ÿ}‘ª}´ý¯ä·ö‚©Ýƒž¾ƒÝƒ„݃†ºû‡«Ú‡¬Ü‡´Þ‡´á‰Ãÿ‹–¡Œ®Ù®ÏÃÿŽ·Øž±®Ï‘§½’¤º“¢µ”ž¥”¥¹–³Ô–³×—£³—¤³—ºß˜®Ê˜Å홲ə½ÕšÃìšÖšš×ššÜšœ¿éœÇ˪³¸Ùž¤«Ÿ·ÆŸ¾Ö ¿Ú¡ÃÙ£®¼£·Ð£È餯»¤Áঽԧ¼Ï¨°»¨²À©³¼«Ëß°³¶°¸½°»Ã±µ»±¹À²´¶µ¸»µÁȹ¿Â¿¿¿¿¿ÀÀÀÀÀÄÊÀÌÍÂÈÎÄÅÅÏÏÏÑÒÓÑÒÔÿÿÿ­5HÅ`tRNS!)+13445<@AF^`deghppww‚†‰‹Ž’𛢢¤¬¬¬¬¬­­­­¸¾ÈËÍÍÑÖÖÖØÚÛÜÝáâãåçéêëìîïðñóóóõö÷÷øúüýýýþ«%bKGDÿ¥òÅdIDATÓc`W4Ma& áÿ"4ØP…uâÏ~ú}祪°î´õ—ní?â®,#ˆ,¬7eÝáÏÿÅE†™q ›žyôêá‹7ß>¾÷E6ZxàÉü5ÇÞ<¢."ÀÖŸ´óÙäÅ{î~ùëåhÎ 6˜¸áþéÛÏß~ýQJ0aã™[î-Ú}nÛÒ¿>œº`V³³÷ŒÞôtí¬Í—<žàh)Ç æR ^qåèÖó¯o–u]¿zíz§3+Xƒ”ߪ‹wÿYݾ}Éÿÿ+w´»1‚„Å=BÃc–ߘP8cÁÔÿÿ箞S, æ“Tp}¨)¯¢µåÿÿŽÞ†|'¨Å|Vóö•&ü‡‚l_¨0¿õ²½å‰0ᜠ¨0§¼–vmJI]óÿÿÝ=u™H¡£š–Zßöÿ_Uº,rÛ&ÕüÿßX™ä†%.©¹YéÎ h@Úäy ]¥%¸iMIEND®B`‚eric-6.0.8/eric/icons/default/logViewer.png0000644000175000017500000000237112342633755017672 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs¯¯^‘tIMEØ6u‰½,bKGDÿÿÿ ½§“yIDAT8Ë••Ûk\EÇ¿gv÷ì-›ÝÜ6Ù솀m16‹&±1¥R/ˆÑÆöÁQA Ø? ೨Ð'Ä¢âƒØ±˜@ñ%ÔØZ¥jm5¦u·i²—l²»Ù\örörÎŒ¿9»¹Vij3'ó™ï|¿™(øï¦PXŽaŽ3w züJÀãÞêu¨Åök¿ð_ycv]þáèèèN§óäÜÜÜykc±µ­­mÈb±ôö…:û.¼ï ªª°Ê°ñ€jç݇hSë*³| °2&ê»êl‰ºÏUUõ®­­}³ººzÈãñÌšàŽŽŽ'GFF.%“I8]^ô¶Ü†ÓÁI'Ñ€T¿iNÈy¸]FX~"ð'´þp{{û§cccQ&èºÞÍ9)F©¤!“µCÔ úh†bö ew °1„À&ü~Äëõž™™©¸\.«Õ*¬V+4MC:kC_{àç¤Ä+ôÛTOc±3¦þÊ5Ûc´îiòÖðù|¯/,,äQ? @иÊV«ÕÊZ¨Ý§^ßßšWðÞÇ}î FjÏôêNÆM°"Y,¹¢(0 É ¯ Š8°½ VV€w?{¿þöB¡ÐJ¥òÎþRb~ƒ¤ÇœÈÐ)kÜ ƒ66(€¾ÂÜQôôø1ñDé£h4ª5WœfŒIõˆ§A@nßíE#yÀ…«Çq+j“§-xûÌæ¡ƒÅ¿SÇ%0IÐÃÒŽXFÀ¨r0«LžÆ÷úËóýÐ}§pìØ]øìLŽ'QÑ1x¼£XG iƒTZçT)Ü„óê^¿”RñSú9LMM!_ĹÉ2œŠ€ Ê1ìÍÀ²â²ä$X# ©,öÙÀ¡“ߥžÇW/AžêTø:î ´¢€^F÷›/ÚƒMÁ¤Ö,9¹ˆl¡²x|=ÖÙ"‘ξäÁSáròyÚ´*”g±m ¦+•Jfòd-dzÊ.´Lù¾œ8Žééi¼úŒ¯XE6gÐ|ý;£K3RŽ4Kžl¦byûäõ®ƒXÔúñý¿ãôIÞz|[t·¬”XFŸÃÎà´p¸lÿx…h¸\.‹/¯×'9½6ª/Ía8˜E¥Lɲ) ­”.›"íbòml<±â y²`SÚ`‚3ÜœÜôœÀÝÅU„;Ó0H‰€Ï!Ъr:MýIËTðûí×Ìã*%p•T›>/¥É[áÆEg-V‚ù[.—Ý[ÉéíÐ ¶Ën× º[šYABy’JnPÖsv[à^®÷ÙæÑÝãB¹¶âEÖÒ CõÃpg sv@-\Ô¾¾r¾Ð ,k8 ÑÕÕeÆ¢÷A´¶ù‘óvÃèG‹Ë Eƒ^ÙD~+[Íçs¹bîN²˜_‹§“ü\¡›€©†£ããã²2ç†Öòe¹¾•(d"±äí/bétf)r/»ùgj9²\J5^h>>???@@@A¢âBBBCCCDDDDGDFFFHHHIIIJJJJ«øKKKLLLMMMNNNN€}OOOP®óRk\SSSS•«S¯øTTTT°ñUUUVVVWWWXXXXrqYYY\´ú]¢Í```bbbcccdddeeeffff«Æggghhhiiijjjkkkkmvkmwllllsnnnpppqqqrrrr†Ír½øsy’t¼ÞuÌu¿öwwwxxxzzzzžâzÃò{{{~~~Äõ€—¢€¢ä€ÅæÄø‚¤æ„„„„Åù………††††”š‡‡‡ˆ¸î‰‰‰‰Èø‹‹‹‹ÈòŒŒŒ¾Ð’Íù“““””””Ìô”Ìù”Î÷–––———ššššÐöœœœÑøžžžž¤¶¡¡¡¢¢¢¢Ñö££££Óù¦¦¦§Òô§Ôö««««Ïí®Î믯¯°°°²²²³³³³À൷¾¶¶¶¼¼¼¼ÔìÁÁÁÂßöÇÜîÈÈÈÈâõÊÊÊÌÌÌÒÒÒÓÓÓÔÔÔØÜãÜÜÜàààâââèèèéééêêêëëëíííîîîïðððððññññóôòòòÿÿÿóë„DtRNS  !"##$$$%&&'(()**+=?@DIIPUU\nvy‘™ÌÑÛÜÜáåæçìòóóóúûýþp(ôbKGDýK “é­IDAT]ÁÍkAàß;3›Iw›¸ÝTcP¡Š ÅR°ö âG¥ˆx**­àÑ?È“wõ  ‚ñ —‚AôTŠxilk’º1iv³™WñÔç!8.gœ3ÆÈ¤´6&J@ÕÉ•âÁB>›ÉÐ(F½îNëiû«ðƒçØgBÙÃ~{󾋔{qZ6Þü `ÂÀEjáTg¿éíí•ÆÆF”–ÍÍÍ)p2F×Rµ%è±ÓFÆœdÌCEv•¼ÙÙYõŒV•¦¦&ÅÚëqIÏ‹!ìsÊôôŒ>¯{ëÐÐaÓ#HIÐÌ<™±"ÖÖÖdrrR±îëë“––ÅJ+dÄH°T¤ý…+ÒÐÐpñ € iÕ x°ÄfZÁÁ GGG*û§§§200 J…%—Kêo±f¢"v/‚þ[’,S¿ßÏ»ê í<º õidU0ólaz788¨,ÐQ1’™ø6€Ã’è^Ò&+¿ÜSUR__/µµµdþ›ÙÒ±¨ás;Œ÷‘9³m&Šàtêb=ËIáøO‘ãGRpWI8ç‘…’©©)Å”ÀÀ‰@í¤êБ‘‘À>E9½‰º é“Èd±2¬h ÝŽ¿[â/±ìÞÍë—¤ë’Ìü°"*‘mmm’÷=êÿ:°>#°”L®µµõwÈGч•ÖKëëëúS¾ i ú%}ïqšÅð?'·îÌÈØØŸ q_¢ãÞÆÙÀöÁððpVž0HèeH|§«+t8yûk#þÇÏFêhßøäÆÇFww÷6þ'ïþ U?Àö?ÀgHb³‡b®?|x5]°éÓ w-·¿½³»±±ñ9Ú|Õ°Å?æã,òäÁV%ôF]]Ý5È-  ¿BÝè+“?¾sp£hþ}öÖÕÚùg•IEND®B`‚eric-6.0.8/eric/icons/default/printPreview.png0000644000175000017500000000255312342633755020427 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs × ×B(›xtIMEÙ  ›lRjýPLTE666:::ˆˆˆ 111aa^êêêÀÀÀ‡‡‡aaa><9³°«ƒƒƒ………sss‰‰‰ÕÔѰ°°ÊÍǧ§§‰‰’‰‰“ŸŸ¦ÔÕÑ‹‹‹ÂÂÆÙÚØÌÌÌŒŒŒÛÛÞãääŽŽŽ¬¬­ËËË==;===‹‹‹•••ÍÐÖåååòòôôôöÿÿÿ l~t…6F³Ô$$$%%$&€Ä'''((())))Q‘**)++*--,333555;;;;‰Ê<51<<<===CCCDDDEEEE—ÛIIIIc‘KKKLKILLLONMPPQSSRSj—UUUX°YYYZq™[[[]§áaa`bfmb«Üeeegƒ¬jjjj±âkkkk¸ðlllmmmnnmnnnppprrrsnlsssttsv~‘wwwxxx{{z|¶÷ƒƒƒƒ¡Ù‡‡‡‡™ˆˆˆˆ¢Èˆ·ÝŠŠŠŠŠ‹ŒŒŒ‘‘‘’“•“¢º””””¤Â–––————Èìšššš·ÞœœœœÏñ§¶žžžŸŸŸ   ¢¢¡¢¢¢££££®Á¥¥¥§ œ¨¨¨«««¬´Â¯¯¯¯´¿°°°°³¼±±±²²²²ºÃ³³³´´´µµ´µµ¶¸¸¸ººº¼¼¼½½½¾½¾ÁÀÀÄÄÆÅÅÅÈÈÎÊÊÏËËËÌÌÐÌÌÑÌÌÒÍÍÍÏÏÎÏÏÏÏÏÕÑÑÕÒÒÑÒÒÒÒÒ×ÒÒØÓÒÐÓÓ×ÔÔ×ÕÕÕÕÕÚÖÖÖ××ÛØØØØØÜÙÙØÙÙÜÚÚÚÚÚÝÚÚÞÚÚßÜÜÜÝÝàÞÞáßßßßßâáááâââââäããæããçæææææéççæèèêéèèéééééëêééëëëëëìììîííìíííííïîîðïïïïïðïïñðððññòóóóôôôõõöööõöö÷÷÷÷øøøùùùùùúúúúûûûûûüýýýþþþþþÿÿÿÿÆ£/“9tRNS%((.0345ÑBIEND®B`‚eric-6.0.8/eric/icons/default/outgoingBookmark.png0000644000175000017500000000241412342633755021246 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÛ 82Ãi¢Š!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“_IDAT8Ë• PTe†¸,V ò‚·b5@PqÃT†±4Y%BØUŒ¡ˆ” Dt£#,FmQ !TBME¬iBB°ÂY. -wâ’À¾}ç8†È™yæ;ÿìžgßýþÿÛåñ&yµÿ,ö쪌Œ4²ûô¹Åi;œüÎý!\:d¦óQ=ÞT¯†žkëU§¡–b;¤‹L'i垃· Ú*¯±^uÜmªRÃÆ<~]ßÝhtÝ;_ÿØáQ× ;þ+Bcn€Òß²\ñ¥éTÄÉí·7`¨åbeépóÏÆî¥`³Õ'´hÄÊå«Tj‰þ³HWªŠ¬5ƒ rœ>•{¯Øü^1¶„ÿvíè›Ñmî”e¼ä°ád¤ ¦¶ï÷ƒ(»r«7ÅÊ·¾…Wp!›òÞ;¿ƒ»Xêu-mìC›OtiKˆ°¹v®êâüŽîÊp(«svÂuiìfÁcG>'emàjO.^ñ>32ÃþótÅ/Ú4Èur[Š…]m¥Þè©Þ‹Æ“jËGoC.%$`ö«Épð9ûH¼>¨€“²•]»nÉá^·Xž¢qt¨Xµ^²€§ÌáUt–bH MGÐ~ø3 PÅ@q>föq Í­ç),ߘ‰ÕyœpTÊ~+ïö5L“Á·•!44¨™W‘¦+Sßôİ:•d 9„Òý.‡ÇÀ`± : p•&r_{41 Û_þË  ÞBï¥C >C䣿ßg®_uÖàÇÎòhÚâI@l'¶¡ª4ÅŠí¸,÷ç˜ç$á6lkD ¶}p…«¤1ÇaŠòSŸù1Rc—u¼-–®ãú¬H4YP›Í´vW’T´x“x-±Žð¢5¡ò†P$ádÒý7‘p›;Ëâ¯ÂV´=÷ãð[–å@áfü$ÞH5ôTæýUíG¢$Ru \€Võ} –¸I¸¤¬tÿÑrD%þ„w£¯ÃæµXÔd[h.%3ÁO<»wÒt#›‹fc¨ÉdsÇ`M, q—˜8V.+;ÞBQ$Hzd¢¡ÐjT Ö;Óé°Ú^‡$ònÙÍ¢)ƒ`iÌ–}íA»ûéüjM$4˜cðÁ‹@—ù¿tŽeæcX¢·Jˆº,Ýæ§ñ<Õ¥Ex¨¢‡z§§g‡ä#ñS/zý›Œ‰ÄªË6éáýFc`0ÜÅ@ÓkôÌÕJJ¬óði‰×¨.Û >4ýôÖLGk J¹šòõÐ^Æ äýgLMâÍMžG¿r.:ïÌBSá Ü=þžjxMñ™`OI _öËI½úÆÂYP_7CßKôÕ[ >[•§uøÿ›ø~¦¶mÝymÔd1(=Æ¿WdŸgºpì{b¥s¦å$ÞððÙ©œLjm‚ý‘6ÝÈøJ71~toG8"‚ÑÄ›„/áA¸z¸èû$G0²©¡˜ÖV„ Áþ¹Nû+G5~¶ úžIEND®B`‚eric-6.0.8/eric/icons/default/comment.png0000644000175000017500000000242012342633754017363 0ustar piotrpiotr‰PNG  IHDRÄ´l;×IDAT8˵•KlTUÇÏ9÷Ü×<î¼:}Rú ¥0Á ”4Á… ¤*&LŒ!ÄèZºqá–¸ÀÄÆ˜u‹&Ftal‰ÆJQ@DÞµ°ítž¹3wfîëÜ{Îq…‘´T6~ë“_~9ß?ÿrÎÁÿ1ø¿¼6ù±° o¢\~Ó1WFÞû"0ŠRdxBâ+j¾¦ÊôÝ×_ŽÔ_MúÇ­žž†·æì¸ä£}É—šÿŒ(èI³eoL$¤ñáØ-ìŒûö|ø“>|„µ.øäɓУ°“C¾=ÖÙ¹‰•S(DÃH‚£±öPàul5²R±rð½Ù?Ž¥nLJ)I \Ì.WŠ ŠjŸIÀ`‹0¿˜[^®– ̱-øÄ`Ëñ±ˆö l©ÔLPÉån7kG¶õ˜õʆW-nø®mG£Q¶îòÆ_ü\X\n¶c5¸÷¾jû8“£½Õš Pp„‹Ñ»A¨gÔáxÍh™¢¶ Û­[u„¼S§NUÓé4øï¸MNNÂ3¿÷i6‹¿‘LîEõSPä^Î2ò¥9„e'Ó:•€˜DÌñì•ê|5s+ÃHsjƒôó¥sß}IWÏÌÌ ¦e«Lêßâ4¢)ÌÚ¢Lî”ÃЭ±ôv¬ÆB#"'œ±f…R³ÒíÙ%—:z$—ŸÃ€Õ`Ã0 cÞTlj÷‹7ŶÔä£. ’ù×å©Î-Êí»<(&D}gi&ï×rN57Ë=£F½ Zó%Iâ°r×"ÕßN;E4L½}XÆ- YŒ4îýp…”Μ >ýÞ*Ö5ÀŒJëö·?:¥ ¿"²ãE5ck¦âèÑ£lll¬‹Ån—Ql'÷|)bõsʧåhêSGdÛ¤ªÝhe™[ù& žÕ4íj)N“5?øLVlr°‹'ìØëeRǃSB =·‘KÉÍ'Ú ·ôUŧˆ‹%M­žyÊ¥SSS|øØ±cÐC]<š»·¤‚¬Q)ÞÏ| Pª&XR{#UE8GÈAí¤¶CLŸ-RD¯¯9kÍ_¼xùN8$²ÓÚ.u‡¸ ŠÜs)#¦À¸3ÌQ"ÌF€™d¦ yk„ÓZÔ'¹€^žGñX×uÁ³¯û … Ô»ÿêÚ·FÍR“.å¹S©óø¡1|‰Ùwuؼšç^UgVùâYÏ èpMãP(ÄVV.ä(ñ§™œ—âÏ¿ÃA5 Z2¼øõäK,šÞ ìçÙk4÷ÅYîf—1Æe¤(5%ÞÅÖ슉‰ :88؈$SK8ú¬Žµ.0LJÔpi Ç0¢µþ-šEùEUÕ;ƒƒƒ­½{÷Ò5Oœ8Á3™Œ_›MPB’›Ä@PfVÖàD/ ©£ÅÔ¡MB@†¼Q/ÚÈÉ/uµ÷Ô»»»éþýûÙž={øcKÈ0 àº1‰ú`„šÌ­| X¹"„A(‚ö2ànn ’r1P¬ãÇ{KgÝÓT.—¡ÛR!ú¥ëK´±p“52‹ª+¯^~šs7 ›ÍKaÉt˜¡ý“K-ë+«Â¯ò¡%„è÷ŸÒ ?šDqAIöÒõºüoÌb¡ñdÑgTIEND®B`‚eric-6.0.8/eric/icons/default/bookmarkNext.png0000644000175000017500000000224712342633754020374 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ69êÒŠôtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ IDAT8Ë••mˆTeÇgžgæîuœuÙÝqu}wvr•]Œ¤ LXÙÂD ÌMI©O%ÔÇ 0 2ˆÄOE_üPzË¢4 Ò^¬\ÚÍV×UwÇyß{gî½O®Éº+¾øsà<ð{ÎsιçÂt{œõ¯¯¿Î^™Ö›ô±ž—z~g3ó¹‹ÌˆÔØÑ=¯»©eÿ»<ÉAÖ¢b±XvçS;{;fwœaëîI’Þ½²eÝ–mv³}ŠÍÌ7ƘZ´Æ®»æ¬Ì®<:ýEÓM͈t±½'Û“q—x2N&IŽî¬ÕkVï²Þ¸'ž,Í.U–X뇇ºhá#÷îÎvgÊn׸E:Ó¶ã;ñ¶¶6ÏÁõ\RsS² mAïðµá^·wˆ?(Ýœe{¶+›ÉUs¸¸¸âR“š´¶·â.®Ê©;XéŽtjtlt‡“vNó'Ãwg²™ÌXq 7→ÂÅ5.Žï„—Ô]ŒYؾÐ.UËÏ”—ªœãG ìø´æI]ÕÉÕs(O¡|… ÚèУQ(´¯Ã3O¡=-Ë»–i­ô;#[/®âßàÙ™`„ó×ùhY ­# \Ž"AG4J)”(t Ñht Oˆ¸´«eÞœvVbëyë|ú¶??{„—ô»Ë‡yÍŸÒt¨“@TE!e!Èù€Yñ4™1ÇógamiiÆ~` vöažŽ·’š$§(46ø1Oyˆ%&¹hŽ©$*Ÿ{çêÈTèÙcÉŠ#W–¯yÎÒmsð®Žñë©Ù¸È!ßx@(ÞPìªDË/N÷p Ø ¿ì×}ÊãmK¤´ÝÔܺdµïÈ€ p¯Œpqð$9wœ ¯ÄÖ€oŒ<$ËMÆ/™by¼<Àûþ‘›:»¿urñC›´Ý Æ¢¸Œ¯ùû·#¬h"Uh§0Ztòå>ÞãÂ-K«˜+ä½ÂÄ\X YF@¦V?¸Ñ4|¿Æ¥‰ËPUæjþÚQ3èmâ µ3P¬ø=g¾ÿÊ©W/!¾ƒb‘Ѓƒ˜:õê(§¾ý„݉¤GNöš7¼'nåÿÇ}9òXcKã±Uý¢b©0ó(`&Á«”Ç0ãÿðÓÏEÞ´“Õãåâ6öø_Þi»ÝœŠC/D†íoJ[ q±«H4¬­qÀ¯À‡µ·=¦³¼å ßmßü@\×ÄÅσHH‚Ðû`TXf»êØç ß×DQía$ µLáX1 ¢·YZwËØˆS‡ Á™O)JÔœ:c­î£qI'Ü78w‰“_§ÖÆü¥/¾zœ‹ûÖÒþÃg|p¶EÖVrœ¾W𞺜(ùxIEND®B`‚eric-6.0.8/eric/icons/default/remsplitHorizontal.png0000644000175000017500000000115512342633755021637 0ustar piotrpiotr‰PNG  IHDRójœ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ðPLTEÿÿÿ¶¶¶ïïðúúú€ººº¿¿ÀÀÁÁÂÃÃÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊËËÌÍÍÎÏÏÐÑÑÒÑÑÓÓÓÕÔÔÕÔÔÖÖÖרØÙØØÚÙÙÚÙÙÛÚÚÛÜÜÝÞÞÞÞÞßßßßààááááááâââããããääååÞßåååååæççèèèéêêêììíðððòòòóóóóóôùùùþþþÿÿÿÿZ0«ØtRNS !#)+34<>FIMNPRSUüüýOŸ ÖIDATÓeÑ;‚0ðk)8(&†ÁŒ&NüN~÷ÎNNÆQIZîjyˆþI—_r\Y0åÐÏYŠptè+—(¼}ÂÄ”`Ú %*¨ïišç¹}™º}„Õ0:Tm}TL$ΕeÊ û÷ÝHœ©¼äµ_=iÁÄ#¨§eð›ù!Ô ÎÒµÚÂt¹Up›˜V]¶º…»úétp¸«?îi½ ®•’5ç%`Ñè$qi Chl¨ŒV,¸Ø«÷¾‡ÞpW0 ‹ñÁ=^ÆgXT=ÌQ„'*z±¬IEND®B`‚eric-6.0.8/eric/icons/default/adBlockPlusGreen16.png0000644000175000017500000000157112342633754021262 0ustar piotrpiotr‰PNG  IHDR(-SsRGB®Îé pHYsMœÞöœWtIMEÜ 8NVú’PLTE”»»”¾¾•¾¾—¾¾¾é¾“Û“”Û””Û”¾é¾“Û“”Û”¼é¼±ä±±ä±²å²±ä±ŒÙŒ‘Ú‘¨â¨«ã«¬ã¬®ã®¯ä¯LXIKLORTW[!d!"g"%p%&s&'v')|)-ˆ-000‘00“01”15 5>»>@¿@FÁFQÄQWÇWXÇX\É\^É^eÌe£à£¨â¨©â©±ä±·ç·»è»¾é¾ÁêÁÄëÄÅìÅÐïÐÒðÒÖñÖÛóÛÞóÞßôßè÷èêøêìùìîùîðúð÷ü÷úýúýþýKLOQRTWX a !d!!f!"g"#j#%o%%p%&q&&s&,ƒ,0‘02™23š33œ37¦78«8:¯:LÃLQÄQTÆTUÆUWÇWXÇXYÈY[È[`Ê`dËdjÍj‡×‡ŸßŸ¢à¢¬ã¬®ã®¯ä¯´æ´·ç·ÅìÅÜóÜîùîñúñôûôúýúýþýÿÿÿò6RtRNS³´´¶¶··¹¼¿¿Âõõõõõõõûûþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþw5­ùbKGD…×jçIDAT Á‡#Qà_É… %£<÷^JÈÙ#›2ï¹82zöºNvedüáîûœU¿¥ KpÀ{N ‘g=@ €jƒPf¡$ãàôŒîiœk:ew5*M9æ­g!vÚÕt+£Ð¢|ÇøZœk/þ._¼ÂСþÐáŵ;q=ûR‹Æý‘ñóui*¼þ¾öX¿>™ŸyîßxZéûŠ6 þhaëo"ºU—Šðá­w>ró9º©N·Å¯”T²I(êÉ]®íH¶’Ç`ds@ †è¶é.àÊÊ£”˜eì€'›'B¤Ü€ °C’s>K®°áþ6¨ ÷¡âIEND®B`‚eric-6.0.8/eric/icons/default/unittestProject.png0000644000175000017500000000215612342633755021136 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ-.ÖJÓtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ÒIDAT8Ë­Ô]h[eÀñÿ{>rÒ4YÒ&­&±tí°µk¥´es8E¯†(®Ât…½(+è¼s‚^xQôBe77«ˆƒUn•0Ôººº®Ó-míÇúvMšsÞœäxÑÏtm™âçâ}Îï¼<ïûÁF”GÁÃÇ`h»…5Ähkkûª¥¥å¥ÒÙÙù]GGG3`n ×ÕÕµuuu}dÆž¼E±û楔KÍÍͧûúú>Ýn½ª§§gÀ4MçaÒ²¬¼ŒÅb@ÕVTªƒÁ`M{{;ÿ%Z[[k€jàÏ­0†aÐë?IuPñß ½Ýçèü²#y½íM޾p’¬ ¦ R¸0 cÛjk½›—dŠš …Òp7oŸ9‹¢ÀZ« GÙWÛ„”–p½¯!¼;Ê¢àV!‘†Û³Pq¬Ò¼Pà%d!#Aæ cƒ´7ÞÝqÇè«)TÈ©QV€dÌ8p9`Ù;ßœuزRÜ»u»¼ð‚Ϫ¶QœÍÂR ’Ë`š jB”î_{·’ÿ3Öá7ÎÏS„ ÀgÀíØ>ûäüâ·Næà³Ç±³+m°…‹ïß—„+›({ Š a´¿›wÞ?‹"6nEá?Ѳ2¦®²þ û[LLàE˜Z,ÖUÉd»k°²Ö‡¿æÀÌ‚#V*„ºòLŒÜÀó÷ç |Ïð ¥÷©/ŠÓX2õdyP}ð®ý€URZ€Ñ$$2v L ï|ÍãÆJ<‹ä2‚´%ÀQxj¯;ØPf¼"  p=« *«¹ºK)`NB|x÷üDü)RË* +L/:,&|†.ö…ŒÆÚ°q"¯Çše¬i`Í 3Óý1ŒþH ç÷!Ÿâ!êÊ5k³tŦ)÷{{ =è‘§"{r2ë¼—« (›qÒÝg8Rp‘Ù“e©² qâHŸ$—ÜTº}|û³•ú¨Û÷L•÷Ø¥Á¥Gó&oìæeÒ«Sçõ€¯ÏýF°z‘ø˜ÎÝI‡†ý6…º‚•Ò‘¦†O3(/Ré‘h ”»ˆúõ†uøÆuÛ^ô‹_â×ø.5ÅÌ‚@Ú.r¶Ä2–¥c[;ÇlÒ¦2è¢o<ì¿g^@xz§Ñ yÕHMT9TQ*êgï;Ñ'öúµá¬+kLë,§5úFM98mM{´á¡9Ù;’±CÞ˜Ó±`(ÂIEND®B`‚eric-6.0.8/eric/icons/default/flashBlock-authorware.png0000644000175000017500000003054412342633754022160 0ustar piotrpiotr‰PNG  IHDR€€Ã>aËsRGB®Îé pHYs  šœtIMEÜ: zòcbKGDÿÿÿ ½§“0äIDATxÚí½yœ$Wuçû=÷FD.µ÷RÝ­nµÔ-ÑHhi$!„A,Æ6‚a3cž±ñ³‡íyïÙ~3Èì˜çÆžá}žÍ`l³ø cÀŒ@€Ð-$Ô’º[KïÕÕ][V.qïyDdUfVfVUSÝj‰¾ŸO|232²*âžßÙÏ=Îóãü8?Îóãü8?Îóãü8?Îóãü8?ΟŠ!Oõüð¥@X{6YaL`D¡Üc2ª 3N™Š ÇSåä;¦¨À“d|tŒMFØå”gO.ØŒe…b `züÞ©‚@¨3 û€­p§WzÛÇÏàe ®6ðb/v·‚HNP¯ÙµùËÂërÒ|59`pŠz˜ö¸ÍÃ×SåÞÿ8Íüyœ¥ñÉõ„5Ïó€W+¼\`W X2áÏðÿ7€Íg-UœÂC_¾P2|÷×N’œÀåB#¼ÖÀ® ër_Ž«P]^ ´r¿Èò“#¹„°@¢8{<|Ú+ÿÎižÀŒq%ðëÀ¿±Â¦\w%b“оƒ[KåAŠ£›(Œ®#¤¸n=¶Phû­k4¨Ÿ:I2_¡1}ŠúôqjÕJ›T1}€!ùÿ’ìþŽŸþü­SÜw§g½_!ð.·Xa¨—x×)Ú°õW<“ Wîfìòg0²s'űuDCƒƒƒØB±ïÿu:i¥BuŠ™˜zàÇLÞ·‡“÷ÿ¹ÉCÄ~‘û¥špÊœ‡Ï+ÜúŽ)î?€•~«…ß~Å #in×ãnp`Í×½ o|1Ÿu#;wŒ`Ãïê=¨GUó÷Ë( ÄDÄ Æ`¬Å%1ñÌ 3pâî»8øÍ¯sì®Û¨ÌWŒEé2¹A„àSþäS>€ÞÆÝ¯(ü^(lïÆñ>?W -[¯ ;^õ lyþ ضø4Å;Þ/kœÖDå`0A€KSææèw¾Í#ÿ㋾ãkÔ‡ÉÁÐM"$ÊãT2|ê\1Ï |h”Ýp«nnêøNÂŒnÜÆÓ^ózvüü«¹äL I‚:÷ÄLžµHâÓ”™ýûyä¾Àßû4S'Ž,¨ˆÖÑ´¼òÕTy×;§ÙóS €÷ cF,ÿ«÷Xa]Ò…ð lØz W¼é-\ô²WPܸM¼[8?k³(k0¤>q‚G¿òüøSÎäáý]fjᔇ?˜qüÙÌžqïõÜÀF…áõÚ!î›:~tÝ&®|Óo²óÕ¯¡06ŠoÄ™?—­jc0…ˆÆÔ4¾ð9îû¯gjjbûéð(¼ò™Dyûœfâ§ãZÿWwr½Sˆ,\öÚ_åŠ7ý*åÍ[pœã„_ê l¡@õØQ~ôÉOðÐÿb·Dj•©r¯~å?œâOy|p”×Â'¬°!Õ¥\¿åéÏäÚ·ÿãϺŸ$™Q÷$ÆZ$8qÏÝÜó‘?áèƒ?\â1 ©òï˜âóOY|xŒÿ`áý"Z =¯` \ñ¯•+Þüë¥2>Žy* E¤µ*÷ÿÅŸsÿßý%ηÛV@•†ƒß~Çú”ÀGÆx—Þ«Šø‘?4¼Žgÿö°õ†qirîwgÀX´AÈáo}“;ßÿæfOµ©„Ü.P§¼ûíSÜú”À‡Çø/ðîθ½SØtñe\ÿ{ÿ‰¡‹wàu~†-™{ôîø£ßçø£{Û@ÐôRå½ï˜âÒ çü÷u#þökþÏúÿƒÂèh&òE~*€*&ŠhLOs÷Ÿü1ÿàö® pÊïžiI g˜ø¿e…yE:‰¿ã97qÍo¿Eø4å§„ômF¯ \óƒ÷¿—G¾ÿn P§¼õíS|üI€qK |Z•b§Î¿èºrÍ;ß…¢',ŠwΘÖf øÐ­éðó‡yÞÜJi|>Iν[¬ ©Mç»ïy•Êl[œ ˆ•Ï\ñK¯=ΚéÍ`-à`Ì[‚â+Z¸êÍï ¸~iíÌUYŸ yr&#>M)®ßÀUo~w}ì=¤~ñ™…@xýÁ˜oÿ÷97gãjà›£­FŸWxÆ«^ÏΟ{5î\Žî5ƒOù«ªfÅ!y‡Ö×3'(pà‹ŸãÇ_ú›6)W'O7¾mŠ{Ï|r=aÕó¥Px齿ãržù¶ß1 g6¡#+%t³:ˆ,{‡1˜0ÂFQfœŠ`¢MSÔ9|šâ |g¹ U0YµÐ™yÞñþŸc¢Üø§²ág×¢¨dMT@ÕóÆ ƒø DV¸ä–›I‚$>#„•>âYóï²*!ï1aH48DaãFŠccFLJ‡°…"’WûûèÞûìw9’ê<õÉ“ÔONR;~œÆôTð6+![Cua‚€K^ózN}äI½vª‚—V=oþâ —c p‡ ;Eÿ%7¼œ¿ðšU}r7*}ôª±–âÆq†vîdð‚ (¬ßqúO¨¯kǙٿŸ¹ýûˆ+• èÙ& 9ðÅϱÿ[_^¢ <®ûGŸP  ðîH¸°“ûÙzÃ‹ðÆªŠ8–@éó}Sgû4Å„!Ã;/aÝWRÞ¶ cíÚYìAÀÀ[¸`+ñ3ŸÉÉ{ïe꾑ÖëH.E:“Z«÷ž­7¼ˆã÷|›ùjeá¹}¦ .Œ•woÂ$ÀG¹,îîäþ§¿ü_³õ†W”Ö•µ’"H®ß.ÜÎøõÏepûö³fGV'Žsô_þ…Ê¡ƒkóu úy&Š8ü­oòà—ÿ®›A8›*×ÿoÓì=mƒó'yàW–ø@(<Çu<ÔÀÀ ;_õÚŒ›óÒì΃ÚãÜ’¿¡ºð¿L°ù†²åE7Q;«ŽD80ÈÈÓv0øÐB˜[óJå~Ϧ½ç(®ßÀ©=w’$ñh& Ã_®ó…³€q•z;ì Ÿ}#cOÛ…K’žD×.ß9Iҭ߉š$†‡¹èç_Íèå—Ÿ9 }9޵–¡íQ[Gå‘ ° ‚•ÎE+‚(ÂÕb¦hóDs#÷Ò—•øâ—ëœ8«6€_„r§î/Âú+¯ÆõÑýM=ß´Ò;?wÕëö"‚X‹Æ1¥M›Ø~Ëk(®ßpN„F/»Œ Tâ‘¿ÿÛ¬¦±) ;žw%jÁyÏú+¯æð÷¿Fì´S ¤Êoo=kàO×±Íß’­¹oãþ ]ÎÆk®Ã§é‚Ïj–ôhúàË|îö›n×IþO‹ccìøÅ7P[wNÅ–¢ÑQ¢á¦øq6?M.ïò\½>7W4¥2ÕÃǨLM.‰G)ì|U™ÿþ?kÌž#¯~¤ÊëBaƒ_jƒ1vÙ•Y¥ãð]Îõ;XÉ5¹ïÓ”xjúœ 0Ž]që¯Þo42Î?ÍgõiÊØeW.!~îlH•× ðža¢‚ácFØÒYË_ ¶>ÿÅ™þm®Ë[±ç–5—ØÎ#Æàj5¦ï¿ C¶m;粌¥Í›˜¾ï¾…òöN£p9› ù‹LÝ7©÷ík <Œ??â¿}£±ºDѪð ežoàwµ‹ôݼƒõϸMPh¶0³ó}÷ﺋý¾ªÁ;4M1Æ‚÷Ì>¸—tv–Á‹/þ‰=kÛ/I**€1hç Vç`Ù÷ÞaÈùCG˜Ÿêf ŽG†¯}¹ÎãgÔ4pK(ØX—úæƒlCs¢ý1è Îw»®Û¹4ú˜ dòŽïR?~Œm¯¾…Òæ-ç Ö]q·;ùÞgaæeÂØ­ï0" ^°É#û—\ 6Qn¾uÆ$ÀF0­›Ö¬a±9¦«ŸCX*-øþ˺o}Ä»¬Ð%ÍEd.ulOdæþŽRÜ´yùˆ[“Væ²|…÷€s“5R'¶\fúþûHgg²ùɠˈþ¶÷¹Q8³ÿÇK<&250úÒ"Ÿúj}åI¢UI€@¸Zài^Ý7ÉJ–­!ÊâþÍÀL×v;×í=}>·œt¸ŽÞ9|cK%Ò¹ûïEíèQ6½øg–ªU*0½ç‡T>F27—/çÊHØB!‹íC´a#×]ÎЮ]§­ZLPÚ8NõÐÁŸ@îïzÎ{¢Á!kð©oûÎe4yZ \ |÷L©€‡Bè"ñ›Ä(”†0"KÄ?1.}|ß%@%¿OSÒ$!(•(âø×¾Býè¶¾ú¢Ñ,28¿oÇ¿ñÏTì˲y-A£$¯hã뾇8yÇwØ~1¼êç¸øâÓAaÃԹ쾓$³zˆüÎ÷º`ð …ÒñÜL6'ÚÆ A¢¼øŒ@/C>zœ6­N:‚8ay$»®éžõàò^€h}`ÓƒÛûç Úÿª›KÐb‰ \fæ¾{‰OL°å•?GåÀ~&o¿-»Ok!M³ˆeš¢"YŒ]¤ Ý& Š˜ô|ê/¹ä×ÞBië¶Õdž‡3U&‚º¼Y9÷7ŸÓZ¢òR™É_ùœ.þè…z,{W–{Z1>>ÁÝ­•‚DÅr=Å}ë9³±›˜×>Àéñ®2‡6CCÔã‘OýEf7“-<™nlÓ¯nû›ªø<â “ÌLsü«_áâ_ù_Vínе¹u/àˆoËðuãxºD?£b¹mîµ©Š³s»?>ÁXYhxÅðÊå&ïÒ%]Ž * i²0¡Ò%ŒÛ‹ƒ•îsÙÏFèšå\"h£Nš&#£YšVW©àkÕ•yÍïÓW™ÃPÙ¿dn–pxdõz@s~n©ŠÖ.L"ª® 6*te ÌS`“W._sÏÊ;[´¡¯9?&2â7u\Çh?÷Oº¿lÞ¿“àA€ $* A°PîÕìïƒsˆ1Ør[.Ÿí”ôÔIq¸ZmÕðFÊf0¨¬@, –äGtÑ ¡< ¸mM`„ËmŽÄVâ/Â{Ĺ…„=Ä¿ô¡®žÑM`1Åâ‡7]§¦Ÿ‰ÞEãît;U%!Êþæ*G27·h'y×®ãV@ü…sÞ/þT—v1ÂåkjêeÈŸMp‰v!þBO]c2Tw¸7]³{ÒðÚ¹µcJe‚¡aL±¸0)& ‰ÆÖQØ´™Ò¦ÍëÖ ¬m͸1D§‘xJNžÌTN’€K³âÏ–Çê5_Ú9y(X/í ȯ¹D/CVb®9N± ìÐ.„_0b’8 Æt¬õÓ.ß™úí'Xbªb E¢uë±årVb ¥ ·3tÅU íÚEaóLsI!õžÆ‰ãÑõ…•Q]-~íí¨zÄ/ªÙÌki¬ s·ã#Ç)Âò­îW&” "ŒÂRâ/ª€Œûµ› =Ôý}ûV‹áØ:¢õ21n #W^Íún¤¼cÇi‰ä³9’Ù’©©Ì¨×s/@ú‹zía¨ï:OÍ7FUÙË÷+^-=”ºYôÍgðü¡š6€¬\êöÓý’¯›+mÙŠBÓ”Á§íbÓ+^EyçNž,£qì8éÜ,8‡«×z6½ZN"4çÚH»êè0ªKƒ–k§¬³B¡“ƒ[@ߨf sHÞ  —{ÓO´óS,QÞ~1’‡f7½ügYÿÂÏI1ßoÌ?rQÅ×ëh£Þ&þµÐ.$W!ÕEFìîZœ²"#eE„+ˆë ·Ë5æQ—t‡äé™Üب@ù¢˜B`pˆ þÍ/2ôŒgðdêÕûc¤-áç~™Ó¥ÜèñùvLÚ=‰@$Û%em 0dM Û¸¾ ñ|fÝv7V$æ;}ÿ\ì—w\‚-•††ÙöËo¢|ÑE<G|r’ÆÑ£ˆnvf!³ÇrßE*xU\<¿ò]@d=†ÖÎ íì•/6€÷øz S(fFÛjgIÚïÛv a‹%¶ÿò›(>I‰0ÿðÃøFßhàæ+§ßMߨãÜb@º]ò4ýÚæ ;ñ›5(ÄsÓÃñÌ#èÄiÓÿÒE8GqóV ›·€*[^ûº'5ñQ¥²÷Ljµ¤S§Ð¸ž%¡ºXúô‰þ) Æ’ÌM/q;‰´šBÏÀHÞ_?7o´ÜD2;IqdÝ‚…«R‚e¼ä~~éâàënxCW^Å“yħNÒ8t$“Å;¢¥] @í’ Q%™\d:ÀuÉ’ukP½¦ “ø ù’Æ>®cLÐ3k#}¤ ÞQºàB‚R™pÝ:Ößôbžìc~ï^|½†«Õp³ÓÙÒµ–‚™åÒäÚîõiLÒ˜[¨X"Mµ%Òªk€–ìx›Øïô¼B:s’htc›Ÿ«½T@ë«zl±LqÛ…¨zÖ½ðEØ'5ñÕ9*÷ÿ B’cGñq=ÏKôáü^´C2s’f5Vsòò•Âm U„aV+Ì{]+¦ÃhõsLjGû[ÿÒ%=ìRŠ›. (•‰ÆÇºz÷šÁ×k«ï=,‚ÖjY™ØàÐi±qèPfý«?ŒQ]ÒoQ¼wáü6P8³Çö0l½Ðæç -è±²²½ W¯Ì8AM øº_27•dv’hxC¾n¯[B§Û|ŠÛ²•¼CWíþ‰=éÜ,õ}û¨ïßOrjW«¡«€n~ž™o~ S(°óýcàŠ+W}•Ý‹¨’œœ$9•wIY¹Дªb ñìä"÷w\¤)zê³}ŠÖÌ84Šô!~ó|\™$,fëñµ¿‘Â ŽŽaK%Ê»vá}£ÁÜß§r×÷IçæòŸ¤}!ÆŠ¬^CýÁ“ž:ÆÈs_Léi«¿Ÿ´2Gõá1QDí±ý¨KÄÿrE²K@ÇÄ•ÉÜJpß‚¦dN¡‘ÓlmPóœ¶ÔŒPìZÔ¢r‰A<}˜ÂضlG+Z»©ŸŽ®Ã‹Ö¯'Ú°qõ>;éøõGÉöñ©Î“>H29¯Íã ðË÷&ôiJù²«¸r7»¯eÓßtZÒ¨zÿýøj77K|ôñ®â¿›P”N×P„xú0^·°5Ò%}ÜÔÿ™·V«ù5¬j(“ÓÆ!â—æHÐ>ÕÑbIçO‘$I÷‚í00ÝP&W$ìVrÑÛ7Q1¢Éç©×fñµ™|)W—eaù‚QG82б–`ãÆ…ÉJ€Êž9 Î1óµ/Q}à.4®bŒAÄä Õüð-&Vv|JPføÆ›1Å"Å—0xݳ·]ÅýTÜK:=¯Õ¨Ø›a¯E µ-ré5/ª¸Ú qmvanMÉÛz.ߛ葜fkÙ‹Š°?èàþ%~|1®NãYøS¼Ë:D´¦\FŒ!ìˆõ9$Ù‡öb EªwßAãȾŒðùÚA¼Ë (ò##@ǹ4Æ„FnúY¢ FF~éÍÙ"Õ•ÝKó~ ª?¼'Óý{ï'­œÊRÚÏ+-¾ýרW§ýzº×bt2¡Í®ß¿æeát¨¦¥¡á.¢ê E×À‡[2¶“H^Ô)vukU|uÍ»%Çæ¾°_q!u1v`=£7¿šÂEƒµŒ¾ü•„cëúö÷éeµÏï}€tj _«1ÿ=™ÞÎû#Jðo{)¼Ö¦ˆóÍ3¤‡µß+”Ÿ`MCÁù¸;ÕvÄ-GüV1ÇuB× ,Ž.-ÅöYµ®É‹:•U¤GM¶)“ CŒ g`Z†PêSTÅ­Ï`äæŸ#X¿ oz á¶ ñ«MØä®cíÞbŠEæ¾ûm\åbÃló À£ª$õiR§í‘½k¿ qüD¾×Ýk€PxÀ)Ç-ÙÚ€•¿-FàªS„Q ®$]µ•@Á”×o$Ižõ<â/= iLÐÅÝTT³…+áð®»kŸ Öb‡¼ñEl=½ ¨ýè^|½Nzê•=·/„·{­wl¾Su ’¸¶°kjk´¯Ihßq®óùò­fއr$ÀkƘüÜ{BáæDû¿ŸŠP ‰kØ´F–¢êÑj†¸Zu « ,^}5é‰ã ^s-& ©ÜþϤSGP—,,c1ÅÂñ )^~ŧ_Žç°Û¶S¾þzìðÈémLi„äØQêíÅDs·ý3¾>…˜B¶ÆŸ^©Ÿ&5š¡¶…v;ÞËh]à”=¯c’ãk Ù‹þý&n¸yµœo:@‘«iÒF kjcH§Nb¢¾RÉúâ¬P«s„n§|ÝõÔ÷ÜÃà3¯aàÊ«H§¦p3‹Á0;0€Á”J ‹3ìØz¢g\ApÑEÙr±ÓÙ½D ê÷܃ Bæ´‡êƒßC$uKŠÜJè¼Ã¥Ìh%6`r‚w+ö ˜Ïóm+5W ¾ž*©d`[ªºÜc7â·^ëÔyêB¬ÅÏÍá dÁ_ <ÑWbÖ¯#~ðAü©“D¥2lÝÖ¶ L±„Y¿ž`ë6ìæ-H¾mÍém]#ˆêîÅÍL£õ3_ýhŠHе²gð>ÍŠg´÷r7éHô¬‰’áë«y‚U î¹·lx8.wÚ#ÏßGt[R¶D:rV.¸é)ìÆM«ˆ›gQ6³y ÅñMøùytv­7Ð$FÂ)`pS,#Å ÝLN3ÍÖâŽ&Ý÷0¦TbêóŸ%9¹c"Tó&‘êQïðªYW›>iÜn Xn¹œ¶øÿ©òðˆ]]ùUàß`þó›ør \î;9œ¥ËÆ—S­R$Mb=Êàµ×‘=†lÏ Â, _dléµ”ÁŽ’£–ÖkiÚ h1øÙâûîÃKÌÝ~sw~ ƒúx‘غ¨Ó;sõ|«ÅßA›:öú€ÖÜ@^øå—YYpU Žgÿ|¢8C÷õ§CüæCT¾;¦X"<¯Öð€÷ºp¸–÷]ÕL¼æíÝ}’,iš÷¾åÚÓ<ÈjóÓûïËR½?ÊÉÏ|$ûûÎgA>íQ?Ñ<×9_=Šm»Ü–„Þ³=\ «ßY,8 Ü¡po(\ÓZ&.¬Î3X5˜èv’É ¢Í[ð‡#;v,Éà=á›ÊæÙEÝûT*øÊ'þì}¸¤ÑsÅn¿fØ+‰ïwZüj#ßOèÞX¹cµ³êõTŸÇ½ar$¼Ìµ„"¡w¡H×¼´Ÿ³¹h³u|Áhe?2‚ÂŒ[Ï…ðÎcìG¦§Á{&?øŸ©} {–Ö£ü]ÎÓ! úê¹eΙø“[Žsûª=ØÓa‚HøÛX™ìÜé²—*è'ÆÄ£d†ÌÌ÷¾Hýû±…æð¡LtçmÕžÐC5k@õØL%«58ùá÷R=pçÒ$M/©ØGršªÓfÜ?Y4üíéÐò´VTþU…Ù_d{ÁðßÁÕt1Eú‹¶C5$îcø%¯Ä©#)•bOÄá’…£‡ ò&Ø'ß÷‡TîûÆo¦3~ßµFúÉhŸƒ.eF¼ò__qŒ¿9kxà o4Ù=ôý¦G¦°S54SžÉüIôø,C?óRlÜ@=4¢(w¥ÎžÈwùkX›§•û¿±dióÒNºKñNb.1 ¥÷o[Å·ƒy¿ñéÊ鵋?m|ºÂ‰_âéa·ë¢ã»¢Ç5mƹmP?øR· <ï„yÇF`qg .¯a¨V¨V°…ñLþþ;©î¿cIÝ}«¾_Âù-¡$XqÊ±ÅøsðéWã“§KÇŸhQýÙ ü² ­F ÝчøFÚÝ¥æß©?ð}¤axþ P‚$¥.Bì¯þŒ©Ïúó–\Âh½NQ‰"ª_þ“ø›$SÛ8¿'§J‹dèP Æ_?õÐË”,î?›(oüt…“OþºÂä¿bKÑp½ïgõ÷‘¶—w¿Ö~|þàIŠÏ{Ñð å4…ºWât16à~‚#õJêõÙŠÊõê°åîØQ¦oý#¦?}+š6²E½Ò£¦ÃÚïïÝÎ++°ú{èþTùÄ+ŽñW?‘Wû“ºÅÿ´…-"Ü z]èo€t7›E’å‹žÅÆßûcŠÏyâ$a6qÌ&Žºsyþ^Ú’*]ª…|v½¡Ëp`‰‹ ø©)æÿî³Ì~êƒ$sÇ–«sånKKû¡í×ùŽk¶_×zx]úwš©áªrýKþdÛÆ­I뤾€7„O&Ú_ôÚ+ˆ%‹¨ö´ÚTª‚ "†î×}óoîØ êqqL5I™Oj±£–$™TPÅ“qµÉ{fn“! ,¥0 ZÊA@1 °Q„"¸£G©ýãÿ ò™¿$>|íFä%ï»±×ùæ9痞󭉲.¿ 2×ï×~æÈ9°q$d[Ç^ZàK“íÚ/Ô) ¬É:Œõ7 óœ>Šz73póë¼åuDW]…Î"tI‚O©s¸|k§ŠÍ`ÄZƒ±YÖ‚Kq§N‘Ü{/õüÿ¨ãH¦mSÈÝ:xôãþ¼R¡+÷¶Iïq~1öß(MɈ=ÿ´¯±6[Ç®Yó´o\ÀÕðM#ŒöRÝ8ݰ6̧¬£õœh¦TY°Ý!Ñök)>ÿ&Š×]OøôË0ããH±”¸µ³w¾5‹ObtzšôñÇI|€äî;‰ø]ÒàË:·‰m+JZ®•Këu¾$¥‹ÔœKÚ%K“G¾Cô;˜öÊ79‡6nŽonå7#áãNW^@X\hàØÓèeÌʹ›]ÃlaS^O0¾ 38ŒËtŒ*:;‹ÎÏá&âgO É,šTs¤D,m-zuðlçxé)î—€BÛ‹Ñ]R_´zéþ–ßY†ç·n:²vÛÇk €É”Ol ¸¡lx}çŽ"½|Þ¬NöÔï/ŠýN—²[SXƒ¦5üÌAâéG²)n­ÆA$s2³ÿ'ö%xϨœvïsض%œ¶6Æ–¶uÿ9o¯¨{zóD$P÷|æ”ãkšÛZëdÙ÷¶1îàk᪦=йª˜ƒP€0,`ÂD}ÏzÏÂ’.[IZµWšŸ^\O{qQ/CÐ÷òZA!—Ì“$îz¿C„çÿ(^òÜCLœÓøöV® „¯Xackc©Î|@«²  NO‰Ð«Um·î¥ýB±¬Ú¥Rg (ºº€Ò< ïEH*ÇÛ\@ßÅUl®tÊ §¼ì‡ùÁšg·ÏTÚü;Û¸%> Ý”v&ŽÂÒ(¶8”­¢Y¦P¢Ó; ÇµÐ¿MýJ$A?‹Ÿ.6€ï¸v)w ¾1G\›î¯÷﹞(oxþ¡Õ{<¡¸c¿#o/$¢¿ÓŒÆv`Zq.·n)0´'çË*U@7¢³à«,µö{q{çµ^•xê‘®Ö¿ÒQ ê”·^ˆŸ±úÎðøþ…¼+Þçµ»øoåÜ0*®ß¹Ð ¹Ÿþï%úû¥g¥Çƒ/·mK§…ßWô þCz¶h"gñÿNõö‹äߎ>6&Úî¶U 6íÛ–ãò¥ßIæîÚGýÄÃ==ÕÌÏO”3ž·ý«Çôo°Ò­QØ“0Ûn¾ÙzÞóõÿýĽðê(ýØ á²X»·žm~7SØõ,L±i²|Aå ‚@²B€åˆÝ+;„h½Fý¡»IZu~  Ì{öÞoý÷où½Û¶}÷;rè«_u9>üS v÷îÝaEÅ;·\üÖƒ÷]ö‹óûÿ¯Í/nNL/ï ,…K_@°u{ÞùÃ÷åún=‹ÖB,+ LÖ‹(9ü8‡¿Mš¯7ì$zkÏÅã)_ÿÌÀ%øñ§_¹÷ÙG¤q×÷ìÙ“dyŸ§]»v@´iÓ¦b’$Ã3¥ÒÈ`šnzë»þݳƒÚkJ†r«Jè–I G¶=ã9˜õ3Ÿ?Ÿàå"‚+ ¯T ÐA56kqj’øþ;Hfo·ð;¬ýP ê™¿Ë ~îÏv\óé™ 8>R«Í„a8{üøñ:?ôÐCéÙPg f×®]vll¬¦i9 Ãïýz[,ŽO‰l¼éø‘ë_Wyø;C¶69¦³X´ /#¼üZìøæ,Éã\f'Hoî—eºßÞ}]žX›¨N#yà≽]-|ßÖx$áðß >í~ý‚ ¿?–¦'\½>aŒ9™$ÉLÕ©©©ÆC=Ô”ggyxïEUÅÖ&Á”¾;¾åÄ}ë6|ãUG¹öeþØ¥¢T»Y‘Ùt¤{ñ'öŒ^LxÙµ˜í;‘Á¡…vóMÑ_ h[t¯×â›¶ÛÈ÷ T€Êî±$ÞC:ý(­®N@™|=ýDJüU³yß—¶ï¸g.'ÇêµØÀï¼xïålÓã¬`qRL¶#ºzpN1þ³=ý±ïÎoM_=±ïÂç›™‘!ƒIé]Sï¦ÅïQì]–`Ë3±—>³í"dh(Ûch¡›æ­ê´§JÐÎb j Úh ssèãîû1éÑâR×{Û{Y\ò6ëðßÓ‘™/Œ_zðàÀàá0Mý€sâAæáÌ«û'Q©±Æ¥Iêœs.‚DÆXêAš&ÇJå¹_¼ûðWg§«¯>¹ÝuÁ|qÐd=}×O#=t7îÐÝvè"즋m;0›¶ CÃÈÀ =»-€À¥Ðh óóèÜ,þøQôà#¸‰Çp³-tÚ{Cëf©ûœCïrƒõ/¬ßyjÿðè”U+¥i¢Pê5–@’4M÷ÞKEØ@ŸjP@K¥’NNNj©TòƘÔ{ßêb¤êÕÏkìl Yïƒ}C#ò¡kã§ÍNÜ<õøàsÍLq½ÅhÓxAExÐÙÇHgC¾-³# ˜Â:$BJÃHi ã¹V¦³ª¡ÚŽƒ I#Nâ`ا¶¤®+ ªX?g7FédXHNFQÚ0ÖUqÞ˜4ðÞYU¨¦@ $"’¨jœ¾¡ªu©‰Hµ)TµÒB’$saV’$©6j©Tª·ÿ¬åž(H‹$°ªFQ†ç\9Š¢’W_öΗ5FL(yõekl‰l×’bNüHU#‰ruæ¯VUD¬ãEăQq ^ºj}5ªjAEU øü³GÕ‰d6I“ð@š>‘XU›ª«î¼«1U æÕW½óóÆšªSã¸f­­&IÒ˜ŸŸE¤“øOY°»ví2¥R)‚ PÕ°P,D õz½("ÅB¡PŒã¸†a1MÓb® b¤ ^#1R0b" ôêÃFŒ¬ˆXU5"bTÕxõbĘnñ¯Þ1*"^U}þêçÕ7‰Ÿ‰“‰W«×†‰Õkƒl»–Zõ$IêQÕF]UëÅb±žº´Ñ¨7bIÒ4MkµZúÐCù'‚øOÚâ8»wï6vttÔFQÔäâ°P(DaFI’Œ1… ¢4M ÖÚÈ9Yk#¯>R¯¡ªFA9#&¬WokÄX¯Þ1Æ«@Œ´·xðê³â1šÁçDwFL)1Iš¦©ˆÄb$1bbç\l­sq4Mcï}# ÃF’$q£ÑˆsÉ‘ÄqœNOO»ññq·gÏO÷£§4è0¸e÷îÝÒB¹\¶Æ˜À{c‚b±zïC¯>T¯¡÷> Ã0ˆÞz1sÎÖZkœsFŒX@¬±â|wÀëwYÜÇ«³Öz眜µv­G. Ò$IcL‰1&©×ë‰÷>5Æ$Þû´Z­º·օÀÔï‰@Oµ077gÆÇÇÍìì¬-—˶P(X ‚ °"µÖ1Æ6Àc›çEÄ:ïŒ5Ö¤ij­µÆ«k¬QUñêE½¶7ô0¢¹øWç7bÔ9çƒ pÎ;oõªêœsH½÷®P(¤Þgª¡y^UÓ4Mª¦FÃU«U7<<ì&&&üÐÐ"Åý¹ €N‰@n(š$Id||ÜÔj5344dÂ0´q› ¬ ¬M“ÔDQd†5ÆXUcŒ ‚À¤ijŒ5V½Š÷^Â0\ ¾jD´ ‚$IÔ£bD½ó.Ÿ¦©÷Þ;Ñœø.Žc„w©sišº(Š|’$nnnΗJ%?11áÃ0ÔǼղB9þœÉöÈ´MP>q2>>.€œ8qB6mÚdœs200`ªÕªIÓT¬µÆ{oÂ(4.uDZ1Ö q#6Þ{) ’$‰4SÒ]}TcÔá0Æh£ÑPcŒAà½zãXÃ0ô6°šÖSïœóq{ï½–Ëeßh4¼sNOœ8á‹Å¢zôèÑ^•ãç׫£WÅ—ìÞ½›©©)Ó$êøø¸‰ãXêõº'MSiÎ9j{^ç²½·­µmD™››Sk­A°pLLLP,}3«911áÂ0Ô±±1¿gÏè_<|NO0O ôz/»wï€Z­&õz}ãÓ4€ .¸@š@éQ)À‘#G ²Ôl†Z,›Y:r®—Ýú\ÿ?zƒ,ŠÇéµ IEND®B`‚eric-6.0.8/eric/icons/default/projectOpen.png0000644000175000017500000000224312342633755020215 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ '³2mætEXtCommentCreated with The GIMPïd%n‚PLTE'''***666888-rÇ+++]]]___`‹À_ˆ»EEEEEEwwwYYYzzz^”ÖXXXYYYZZZ[[[\\\]]]^^^dddWÔJJJv”¹u“¸x•¸jŸàiÝZ¯»»»½½½b›âb›ã¸¸¸ºººU’àx§ßz©ãl áVÚHˆÙ½½½¾¾¾AÐëëëìììdšÜo¦ñ±ò,tÍ/€å1yÔ2æ4‚å5ƒå7„æ<ˆæB‚ÐK‡ÕLŠÙQ†ÈT‘áYÓ[¡ÿ^¢ÿ`–Õ`¤ÿa¤ÿc’Íc¦ÿdšÜešÝk¢ámÕo¤äo¦ðo¦ñt™Èt¦Õt§Õu{‚x¦ßy}‚z¶ÿ{‘§{¨Ý{¶ÿ|ªá|·ÿ}ªß~¥Õ…Œ­å±òºÿ€´á€·ÿ­ã‚‡Œ‚³Õƒ³Õ„—§‡¸ÕŠœ§ŠÃø‹š§‹¥ÈŒ§ŒŸ²Œ¸í޹í¨ÈÁáÂᑵ咣²’Âÿ“¯Õ”½ë”Åá•¥²•Íÿ––––¦²–Ìÿ—¦²—²Ó—¾ë™­È™ºå™Ðÿš¾é›Îÿž±È ¹Ø ºØ ¾æ¡ºÚ¢¸Õ¢Ãꤾݥ¾Ü¥¾Þ¦¿Þ§Àß§Áß§Ç쨼ը½Ö¨Áà©ÝÿªÉíªÏÿ«Ðÿ¬Ýÿ¬àÿ®ÂܯÄÞ¯Øÿ¯ßÿ²Þÿ³æÿ´ÇÜ´æÿµÅصçÿ¶Úÿ·Öÿ·âÿ¸çÿºËÜ»çÿ¾ÊÚ¾ÏܾÙÿ¾Þÿ¿ÊØ¿ÐÜÀÞÿÁËÖÁÍÜÁßÿÃéÿÄåÿÅÏÜÅàÿÆÐÝÇÑÜÈÑÜÈèÿÉÒÞÉçÿÊÓÜËÔÜËìÿÌêÿÍÖÜÎÖÜÎëÿÐÐÐÑÑÑÓÝç×ÛáÚÝáææçæççæèéíííîîîÿÿÿÔj6©5tRNS+,-?AZ\^``bkkkkkkkmp}š›Ÿ¡³ÀÁÊËâäççèêñôøøûüüþþþ#1²PbKGDÕ~¼;=IDATmÁ½JÃPà÷;çKš´ÕÖ¶¨`Ñ¡ (tСˆ“à.X7oÁÑ«pwé(¢³à8 Ré¢(ˆ?µ­éOr’h{B'Ÿ‡ ­ b‚Æ”œ?#ûïÝclRÆ©üp€1š^ÚÅÄÅScB\Õûjuï!eºGS§—HrMð\Ùm!e𸲘AÓÿVˆ1…ÊkÕß‚Oß_'hŒí2³! ‘RQ1¦úIqáõ8^ëÿl4FÛ3Ký3KÌ.» …“ð^ ›3i9ìZ7iúƒ„zΣtèe+~#5‡‰„nï«íE~a4m# ÕMëLJ >¨•€w;å@³V*cZ’¡® ‚F™9ÄòvZ½K˜(í´è’1¡lZß#L$s-lá¿öpm§™¶IEND®B`‚eric-6.0.8/eric/icons/default/fileDesigner.png0000644000175000017500000000165412342633754020331 0ustar piotrpiotr‰PNG  IHDRójœ PLTEÿÿÿ!!!999………†††‹‹‹Œ’’’îîîðððÒÒÒ297@8CCG3H]NX3\v'_bYf‹grKhˆ0n%qˆ.rˆAss©vªv«wG?y©%~‰l~­)~¶Šl€†S€Šm€‹nŒn°!‚ŒoƒÀ…²0†¥/‡¡>‡Æˆ“xˆ¹$‰‰‰‰”n‰µ1‰¶)Š“zŠ«9ŠÅŒ³7ŒÇ¶E’¦e”§r•©c˜«c˜°dž²iž·_ ©”¢ÇS¥¢I¥¦£¥À`¦ÅP©ÎT¬¬¬­Ðj­ÙF®ÌW¯È…²±±³Õ]´ÇŽ´á@µÜ[¶×k·²b·ÜMºåD»æ>¼Z½åV¾èC¿»«¿ãYÁ×—ÁיŰÅÅÅÆÝ™ÈÈÈÈޠɬdËßžÌà¢Î'ÏÒËÒÒÓÓ÷ÓÓÓÕ’'ÖÖÖÖàÄ×snÙÅÅÚ¿ªÛÛÛÝÝÝÞŠàßßäµ,äê×å¶*çèèéÓÑéêêêêèêêêêëëëììììììíêìííííííîîîîîîïïïððððððñññÛÙñòòòòòòóóóæåóóóóôôôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøøøùøùùùùùùúúúøøúúúúûûûûûüüüýýýþþþÿÿÿoçtRNS#&MS\l¦¦±±ºøùþ>ôz#6IDATÁÍnLaàç}¿oNé_UA¦‰öĆk°µu.Á XŠÄžÛ°#±®Å´ RÕÿ©™ž3çxžPÑ@?¯(Ÿ.3E"ù¦T8ù•¥fFD†°I…Ì¿?Æ[ã[kQBH*Dý:/ö^ÛÜÞ YN†aÔv9;ªµi’ Që|qÔ®ý¾ ‘³Ó³6N–™™Aíl¯îÞÿ³³<¬[¨PŠaÞMïMËùîlt;HPÂõæbÚ÷õàKH(™f&ë+Ï•WÏzTwÏ»ƒewãéÅêã‹~• áÅÚñbC………†††‹‹‹Œ’’’ðððÏÛçÑÑÑÒÒÒ®¯±ÀÇÏÂÎÝÃÌÕÅÏÛÆÇÇÆÍÖÆÔãÇÔãÈÈÈÈÖåÉÊÊÉÖåÉ׿ÊÊËÊËËÊ×æÊØçËØçÌÌÌÌÙèͽâÍÍÎÍÚéÎÀãÎÎÎÎÚéÎÛêÏÏÏÏÜëÐÐÐÐÛèÐÜéÐÝëÐÝìÐÞíÑÑÒÑÒÓÑÝìÑÞíÒÂæÒÒÒÒÓÓÒÓÔÒÞëÒßîÓÂçÓÅèÓÓÓÓÔÔÓÞëÓàïÓáðÔÁäÔÄéÔÔÔÔÔÕÔÕÕÔßìÔáðÕÕÕÕÞéÕàíÕâñÖÈìÖÖÖÖÖ×ÖáîÖãò××ØØØÙÙäñÚÉëÚÚÚÚåòÛÛÛÜÜÜÜÝÝÝÝÝàáâáÌÛáááááâååååæææææçèèéééêêêêëëììììíííííííîíîîîîïîïïïïïïðððÉæððððñññËèññññòòñòóòòòòóóóÍêóóóóôôóôõôÎëôôôôôõôõõõõõõöööÐíöÒíöööö÷÷÷Ðí÷Ñî÷Òï÷Ôï÷÷÷÷øøøøøøøùøùùøùúùÒïùùùùúúúÓðúÓñúúúúûûûÔñû×òûûûüØóüüüýÖóýÙôýýýþÚõþþþÿÿÿ«LtRNS#&MSW`lq¦¦±±ºùúþþÈ sÐcIDATÓc`Ä €˜ p0€„¹–O_0wî¼…@°hÑÒeKWñ2ƒ…»óª ‹Ë*ªjjššú›gA…‹ýër=MLR´Cü³;§vσ [)éjÊ«jè+h[Y¹[ûðA„+#[ªê›Ûz&Lœ6cÆ’¹Ë¡ª§—uäË*Fæ8%{8V.Y•óµ0wñòòŠ KˆO‚ O(ìëì6cáÂ¥K—/_¹æÀÖÌI%‘©!f&)‘V­^µ*l!ã`eìªceåjžV4gúÜ…@V­Y³fõr˜êòäÉ¥j6q±YzQS»fB…},Ý\½]­ìüMµ TDy˜ÀÂõ‰ó!F,í)0Ì`,×ìö)¶©éêÎÊk’Ù áÍm.íçmìm$%™&Ì®¥Ó šÑY &Ä‹®UKW¬ºmíš…"ülØ"“—X[jz¸Ö±„IEND®B`‚eric-6.0.8/eric/icons/default/shapesAlignHCenter.png0000644000175000017500000000021112342633755021425 0ustar piotrpiotr‰PNG  IHDR¹Ú„¨ PLTEÿ=ûÝ-tRNS@æØf.IDAT×c``à`ÆÈ0Å!€…‡•‚(j‡R¬‘! Š…ƒ“GÕ6 ­S"îk"ŠIEND®B`‚eric-6.0.8/eric/icons/default/erict-bwi.png0000644000175000017500000000354712342633754017621 0ustar piotrpiotr‰PNG  IHDR00ý 1 sRGB®Îé pHYs  šœ IDATíÁkVeÀñÿóœçœó^÷½ì+»°¹ÈîÊÅå"‹bšy«ÈI£äCM3©ÝüЇ¢ÛLfÂ>5Žö!£i¦É¦±¨&+‹‘@A!QaØ]ÖÝ…Ý}ïç=—çi%ÆYê[ÃïÇeÿ_ŒP’sþ÷Ⱥ%ânJf¬L½¹©I²M NØ9px’3ÿ…{U{ÚäsÍËrݲ­ÑÏËX¨:C–¯*>£rïÜ-ßÿý„ašàŠâ¸HŠÑLS¼¯.ùllãÀ[Ì"E')¾È8Š ‹Ï•¼È?ÄF±€¹x4gSÁØ¡‡ü/Š ß¾cñW¼[öØund6ŸA“G‘¡ŠfÃô1—W˜"IŠ€\BÒ$ñHGÅQa˜¦¸€¯Ê›>-¿vâê±€"†.. H1AD pYÃq ÜÀ †,yNr‰kŽ…œ¦8?Ѷñùo½:ÿ%ÜE‡I\âÔØN@/¯á0†¡• ½¸^' ØØ˜HW9Mq^Ÿßðæ7vÏ?*Zù(’VöR`%I^a9fó(饟 c8TÐÔpP€ ŽršÅy¬»Óûî@OMlà~B¶bãð2.ƒôó¯rYlòŒp×ã2€E’6 cøÓ±_l ˜¦x¯þøÃf±#ŒóuFÑ,d„¥¸ì`¼H™“¬ã¯Ô( ØI–åĨ!‰ÐH“խ›ª€À(αôj¹iÿ­ˆyüŒ 2¬b Oò*=ô1‹§t0Àrz™¤ÅnbŒq 4Uld>}ôÏœaq–fnÚôÖ†ç­ÝÌc„ ]ÌâNŠ4HÑËDdÉRæzòô“Ä!K–ÿ°&|Ö{ôþ!ÎPœ¥±ÁûÔ[Vˆ …^*äIP`”«±h'F‘U¤Lš.šÙÆZ¹–ã4a¡ià˜úöÚï<À;ï²qåøaS‹ítSdˆâ($M\I—µL"9L‹«ðÈRÅÇà£tåã¬ßÍ»X¼ã:;ûPéîk!‹q`­\Ç’:­$uâ7¼À5,ÄÁ,jh¼¨²uà÷pÅ;š–äÖÙÖ›ÜÌzæs” ‡(¡ˆ#©1Ê•„ô³Ÿã,Áf!ŠˆCP?µÅûñç^çŠ3Ú”¾çH+¨pACC,¥H‚ óx–ÝÜA«¹‚.MdÔàÔO‡ŸüÒï¡8cb}{·œ$¦ÄK¬f)%BÒ´cŒ}ØC?‹YEšâ|,ŠDQu›ÿÄŽ­œ‡â´k¬®õz™#ºPä€8ts‚Ažã r´‘åFæÓMƒ Ê¤ñ'ÔS'Ÿ¸ÿM.@qÚë=éõ+U9N1›yLPf’—8B›HQV!AS'˜âËS?yêWÛj\Å´˜µð‰{›äÒ( 6.u<®¢•U¼Í Ðfðû¿ùåß¼Å4Ó¹b¶â£<5&i!Éý䈑$‰ƒD"1„Hbxfdû nÞÆE(¦…+þu•á´ò¤(#hÃFSÇB¢1„h ƒCÙÿÛðw6ï⢸*½¶%5É!\FiÁÃ%¤ÆE¡X„DD@ ßݳï‘Í»˜ñ®ö[sr{‘8@ŒæmA„!$†¤>ä=¶y3¢ ßÙÖ¾ŸSôQ&‹ ŽE• I„ ÂCã F–·üñfHÁhº]ÜÌ$sÉ#PD¤I#1D $@£p°(÷øõ3>3¤Œ¸µ¥36EÍØT¨a# H""š€‰B"Œˆ¼ƒ#̘‚En\”˜ H7ià#€&D£p±Fhoâ­ÑJ’*3¤`Ku¾¾%|",@à¡qh4…m¤ñ}Sk6Õ¼†Q¬é_QšÓœ'†‹ƒ ÆmBÀBa†Åúxx¼²Cm+ía¦8o^K­ÒÒ¶\)cŒX&4BËH`¢Z­~Ê s¨¶«¼ó–¡{Ÿ3S öëþ¥ÌÖÍ™´›’B£ ‰‚À‹ªøªä5†D¿Þg¸{R.‚ ³ówËšœ…傊¥DÂJKÖuR jº–ãSÁHiáÜèGê\"ÁiŸìlíÊ4+å`댈E¡ñµn8ž …cµdÅ®Ýá Íe—½×¿ÚÌÓêkÃÉtIEND®B`‚eric-6.0.8/eric/icons/default/preferences-filehandling.png0000644000175000017500000000207412342633755022652 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<yPLTEÿÿÿ $ #HFG`^_  " " #""%"#%##&$%(&&)'(*((*()+))+**,*+.*+.,-/+,/..0..1./1//1/02./2012113/0300412422423544655734744755766845856877967988:78:89;89;::;:;<89<;;<;<=;<>;<><=>==?=>?>>@<=@?@A>?A?@BAAC?@DABDCCECDHFGIFGMIJMJKMKLOLMQOPSQRTPQVSTWTUWUVXVWYWXZWXZXY[YZ\Z[][\^\]_]^`^_a_`b`acabdbcecdgefvvvxxxzzz|||}}}€€€‰‡ˆŠ‰Š‹‹‹ŒŠ‹”””˜˜˜™™™œœœžžž   ¡¡¡¥¥¥¦¥¦¦¦¦©©©ªªª®¬­®®®®±µ°³¶²²²²ÆÙ³³³³³¶³´·³µ·³µ¸´¶¸µµµµ¶¹¶¶¶¶·¹····¸º»»»ÀÀÀÄÄÄÅÅÅÉÉÉÌÚæÍÚæÎÛçÏÛæÏÜçÐÜèÑÝèÒÞéÓÞéÔàéÕÕÕÖàê××××áë×âëØâìÙãìÚäíÛäíÛåìÜæîÞæîÞçîàèïáêðãëñãëòäëñäëòæìòçíóèîôéïôêïôêðõëðõìñõìñöíñöîòöñõúòõúóöúóöûôöûô÷ûõ÷ûõøúöøúöøü÷ùû÷ùüøúüøúýùúüùûýúûüûüýüýýýýþþþþïªÄ tRNSooßãôýýý]Kvm IDATuÁ±ŽMQÇáß>{]d&"Ñ*I”¢˜D1í”^Î xB1­^RT21G¸gwïµþËLä&|ÿV¨G›ãk S)ÓÓñÎ'Çóƒ[I¡”©Ôi:;ƒ7ãíâµÖ©Öj›jæm ŒXU_±÷4RÂð‡Y6Ï€¼ _10¤¢Ÿ§ìEÈ1vQ¢=†¼¤l ŒŒ2Ú{öîOÇP0Ö{\È$ÕF¤c¸è¢$$™Ê #’×ü-1<¹ªcH\œÜä½ø<10†CÙO€Ì;ŸÇPÍMd¦ZdöcÄ´®5´ Éw±½+Œ~~e™×9"C}Ë60ú—Û7vÏ#…2u6÷öAêßì{ÍKÀÇà+ƒÿø ¾ÁÎåe+~IEND®B`‚eric-6.0.8/eric/icons/default/showPassword.png0000644000175000017500000000110312342633755020422 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<êPLTEÿÿÿ  111666 Z[€13yjjjvvv pq•xy¢ŸŸŸóóóøøøùùÿüüÿÿÿÿ"$c©°°°ÊÊÊÌÌ̈Œÿ‹Žÿÿ“ÿ 14@DºV[úX]ÿ[`ÿ]b÷]bÿ^cø_dþæm™%CtRNS 48:>NXZj|Ž’¦··¾ÄÊÑÖßêñôôõõö÷÷÷øùùùúúüüüüüüüüüýýýýýþþþþlKˆ|IDATÓc` 0óð°"qù¤õut %ù \nuk__c-)._PYÏÌÞÃÕÕÃÁTWU˜‘AÜÙÆÒÜÓÝÅÅÝÛÂÒÖ@–SBÓÄÒÑÃÍÍÃÉÒNEQ¨‡_AMÛËÃÃÇHIC„l*¯¨œ••¼˜’Íìl Ô,ÑBªrìIEND®B`‚eric-6.0.8/eric/icons/default/plugin.png0000644000175000017500000000216612342633755017227 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<óIDAT8Ë•UKlTUþþsoo;ÖÅB‚–ÈS¡Å*âk¡ÑÈ£lŒ7Ä…º2&š¸1&$7&²`a\©+4±ñ‘º`Y"±¨QJÅR í´Óyßó>¿‹ÎÐétñ$îyäÿÎwÿÇwˆ™q·qüçÑ ˜N8òÒ†®­[Šz±6Ÿ˜(ÛÅ7¾xar¦­3ßÕ^ÿqôë ¹_C^åùßò O¯ðÄÜDxëì˵׾?8ØÎGÜ-QÉð‹e[£¼Ê£h XVyäTŽnTº«·µ_ܯ~72ê3écߎ܇n\X:·+›<#¤K!ĥŸ,\­ì:|ôÌH3 `BiìØo©9ÆD„WÎ ¿ó䎣ŸìÞ8 ㄾ®þÐßÙ/ ¦éS(/áC@g”„²^¦².PÅ” ƒÁåå¿Â|nöéVƤuعïÞQÞuÏ>’^By éS‘7‹.…ô)ûJIѸH±„ )’Ž.¡%o_ ëÑPu%H/¡½¬ÕnÏÕ û ¡‚„æŠ%9ujoG!õÁ&â÷yáO]*O+êØ°ec¦Ó†_7ç±nC6¢ÞnpuAf«ã¹ÓÄÌ " ì8yàìó =Z1E4G†[fídœLÎTÜì77ûâº&"ªˆJeuÙ·kÆG­Îܲà6§IãžCq³àœ‡1.BU4g™ÛÄvÍYý"ãÞòà:­p.ø™Ò’¨ZhÜÊW¹åRÃÂ1zZƒþ¥xúœú{@\á6€w¨† EŒç~ ÖÇ´žÈhµhÿ÷`î?.?ö*ûˆÒåIEND®B`‚eric-6.0.8/eric/icons/default/namingError.png0000644000175000017500000000200112342633755020200 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ÝPLTEÿÿÿ +12+12&+,  ###!%'&+,!%&&+,%,,!%+- &+, &+,!%&&+,!%& &+-&+,+12+12!%& &+,!%& !&'&+-+13!!%&+13   +12+13+02 +12   +12&+, +12  +12  !%' &+- &+, !%&!%'&+,&+-+13‡ 9(”tRNS !"#'(**+,,-/123559<>AAACEFHMNPQT`ghmmooppqsttwy„„†Œ‘““•–˜™™¢§«°°°°°°°´¶¸¸¸»¼¿ÄÆÈÈÈÈÎÏÐÑÒÔÕÖ×רØÙÚÞÞàááäåèìíñóõõöøøøøøûûûüüüýþFò;öIDATµÁe7ƒa€á[www×ÄÄÓÝÝcº»™®a&~«çµsæƒs|âºø#¾uü4¬R`Ò;k3Ù‡°Ÿ¸„‰ßåÐM ‚L£‘ñ­ê±ž_Äétá@ë)«ü±ƒÍf zK[´i¬GŸ¦  0ßi\ÚÏ\³¡ø9“/Ñú´<}(tÜoçÀø.F'ö^/¥8MßF‡­©ÕwËôìŸ#,\¹! 3´(•ý¯Ážµ†"$eo!ð^B×µ\.OrÞxhÊ*Ìe~°Ü›£ûCÀ±ræx±†eaçâá›’ž‘šáïíî`kö Ú|7`)êétIEND®B`‚eric-6.0.8/eric/icons/default/fileProject.png0000644000175000017500000000202312342633754020166 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<@PLTEÿÿÿ,,,000ffflllÃÃÃÆÆÆØØØÚÚÚgÁ"nÌ1o½3p½9‘ÿ>€Ò>“ÿA”ÿCzÁC•ÿFz½F{½H˜ÿJ}½J˜ÿL™ÿMÁM‰ÒO›ÿR„½R…½S†½[bk^½_ek_½e“Ìf¥ÿf«ÿhowh§ÿi¨ÿk™½kš½lqwl›½lªÿm«ÿn™Ìn½n¬ÿo—Ìp­ÿqqqq{†r|†sšÌt}†u~†u›Ìv~†v†w†w€†x€†xÌy°ÿ{·ÿ|žÌ|ŸÌ|¸ÿ Ìºÿ€¢Ì€·ÿ€»ÿ‚¢Ì‚£Ì‚¼ÿƒ·ÿ„¾ÿ…¤Ì…¿ÿ‡½ÿŠ§ÌŽ¨ÌŽ­Ò©ÌÇÿ’Èÿ’Êÿ“¯Ò“Ëÿ”¬Ì•Çÿ•Íÿ–Îÿ—®Ì˜Ïÿ™Ðÿœ°Ìž²ÌžÌÿŸ´ÌŸÇÿŸÑÿ¢µÌ¢Êÿ¢Ëÿ¤Ëÿ¤×ÿ¤Ùÿ¦Ûÿ§Üÿ¨Íÿ¨Øÿ¨Ýÿ©Þÿ«Üÿ«ßÿ¬Ðÿ­Ïÿ­áÿ®Ïÿ°Òÿ°×ÿ°Ùÿ²Òÿ²Öÿ³Óÿ³æÿµÔÿ¶×ÿ¸Úÿ¸äÿ¹åÿº×ÿºÙÿ¼Ùÿ½Úÿ¾ßÿÁàÿÁãÿÁêÿÂÜÿÂßÿÂâÿÃåÿÃèÿÄàÿÆìÿÇáÿÇçÿÈÈÈÈæÿÉæÿÊèÿÊêÿËìÿÍéÿÍëÿÎêÿÏíÿÖÖÖÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííøøøùùùÿÿÿÄÍtRNS!&M_`fj­²ÖÖñògH®'IDATÓe½JQFÏÜ{7»›5 !ؤ|;[ÑÞ7PÄÆÐAl-¬l|-¬,L,TBð/q³?ww-Âî†ø•‡oÎÌ€1B›ï²¢¦Ùû¦ ÆÿšwWV؛ĸ7Ìæh?šºŸ[Ý…û+à`;")VÚÁúÚê©Q´7¢ÉCúUºíeßÉ£8UÑÆu=ÚŸaê¥$Ûã»i¤K|Í| Ç­Nãñ8ÙJl¼[à¯Fg¥fK›QX^"¼¿-î4ëNfã$IP€ žz¡‘<ÌlXamF½þ`œey'•D;JI2dì©(Á¦æ8@þ’5'3X)­Gÿ +Iþt½6°A%¹ý÷¥€6șü>Xlñ’ÑKIEND®B`‚eric-6.0.8/eric/icons/default/task_r.png0000644000175000017500000000132112342633755017204 0ustar piotrpiotr‰PNG  IHDR(-S pHYs»»:ìãâtIMEØ LÏzdhPLTEÿÿÿ:˜˜˜<›››———ÎÎÎÍÍÍÎÎÎÏÏÏÐÐÐ2•22–22˜22™22š27—77š7ØØØÛÛÛƒ…ˆŒ…‰ ’•– –™ V Ÿ! #¡$R $™&R#'˜)£*¥+\%-§0˜,1©2•.2™.3–/3«5’/5›/5 $6’06¬6­7œ07© 7­9©0:¯= 3?¡4A¢6B£6D£7E¥7E¶%F¦9H·&I§9Iµ1I¸'K³:L¹+Lº(Mº)NªXÁ/Z°BZ°C]Á>]Á?`Æ3qÍK~ÕS†Ë~”Ô†›Ó—¤Ù›¹¹¹ÆÆÆÑÑÑñóñòôòóõóôôôôöôõõõõöôõ÷ôõ÷õööööøõ÷÷÷÷ùöøøøøú÷øúøùùùùûùúúúúüúûûûüüüýýý&€tRNSWdkp|ÃÄÄÄÄýýýýýýýþþÇ» ÐbKGDˆHÎIDATÁ¿JÃPÆáß÷žï$M Š•"ˆ KGq{޽6ñ¼ÿLÎ*ˆTE§¨ª9ɉÏc… 00Ìð/×Â…‚dvnC°Ž€By"ë÷Ç ºƒÃo³Š¸ìîA¤Ÿ\Ï €POp†œ(·ª1"nhõÔxYq2~»oÑ™ÑþîëM‚.¥T³«Ž½iÊ€êxº¼íŸÕ¼à0š_÷l÷ßG‡J—Åü4,Õ7Ϥ ™]ËŸŠÂÀfjþéI;2 â§*IEND®B`‚eric-6.0.8/eric/icons/default/sceneHeightInc.png0000644000175000017500000000135512342633755020610 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ0ùytEXtCommentCreated with The GIMPïd%nDPLTE¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀ¡¡¡§§¨¸((º’“ÁÁÁÈ45ÏÏÑÕÕÖÚÚÚÚÚÜÛÇÉÜÜÞݵ¶ßßààààààáààââÎÏââãââäãããããåççèèèéééêéêêêêëêëëëëìëìììììììííííííîöEöö÷÷g1÷÷÷ÿÿÿ¨O¥/EtRNS #*+128:>@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜bKGDkRe¥˜µIDAT•Á1NÃ@†Ño~Ob#@Џ÷? E„Q´žÁÞ8Ûà†÷ØfÏOüõéû×0c–äy§‹ý»[|õÁÍÏøxÞOçô(w#†Ë.{ÒS/¢šè¨â#•‡Îª &«ºCŠU¨p•ÎÊ $®ÒiD38¸ ‰-[:ÑD°2‰&‚•$V% •™(TNeæyš¨òžo0“q2;>d¦›Éƒ$“Þø3ÍL ‹EÆìñßEzÇŠ!NIEND®B`‚eric-6.0.8/eric/icons/default/preferences-spellchecking.png0000644000175000017500000000211512342633755023035 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<õPLTEÿÿÿ€@111€++€++ª+’$€ Ÿ 3™3‹.¢..¢.•+555 ’.1110“.–-DDD™,,,,111•,111CCC=== :::6¤-•- Ž+***3¢,.¡,,ž,:::#š+'œ+™-–-***222:::  -DDDDDD2228>9;;; ;;;w1 ˜,(((”,–,“,‘, +’,“,AGC222/ ,2¢,'œ,+ž,—,#š,”,—,‘+“+((( .::::::DDD((( CCC‘,“,”,–, ˜,333 (((;;;;;;z2#š,222;;; , , ‘,“,”,–,˜,#š,'œ,((()))+ž,/ ,1112222¢,;;;DDD‹Ô—‘tRNS  !!""###$)+,.2455<=?@EHKNORTXXZZ[fjmtyz{{||}}~€€€‚††‰ŠŒ—™š›¥¥¬¬¬¯±²²³³´µ¶¸¸»½¾¾¿¿ÀÀÁÁÁÂÂÎÐÒÔÕÖÙÜÝßàááâãããëëíîîó÷øùûûý/›ýù-IDATuÁ;BaÐמ]”½·ìMöÞ’²÷Þ{+Ù{»¤‹…~§ï6êƒ _`¡ã¿Õ-ã×¾°K¸`]øÑ•S~Úž|sÖ¶Ú B* ‘êõúÍæP$]ÜÞ6ÂÀÕfÎÃwD!ÎÈV Œœ‡î‰E.ΨR¹ –à’Xâ‚È vB8ö?ón0¨y$vÃà4ðH,¸Á¤ZEìGõªˆw|©PWjbÖ*Ÿ¦<ðMÙ+kšÂ¥Z­v‚Â/%ï“þGÁ’5Ï'(:>%=+;#51.&Òß›goõ Æ—deØÜ©IEND®B`‚eric-6.0.8/eric/icons/default/class.png0000644000175000017500000000046712342633754017037 0ustar piotrpiotr‰PNG  IHDRíÝâR pHYs  šœtIMEØ(5ºôtEXtCommentCreated with GIMPW!PLTE8r¡;bbQ††dddf—½m´´‚×מ¹Ï¸ÌÛÿÿÿëêCßtRNS@æØfbKGD hÐôVjIDAT×c```q`€Ï)ËÌ-`†GG‡ˆ ˆáÑ(Rb¹† º—§9€"iiI@‹‹ˆqšˆ1ÓÅØÄðœÙál¤èèht1É„v:€t³„ ‚­2D vºÂl[Ä¿yxjCŒcIEND®B`‚eric-6.0.8/eric/icons/default/editPaste.png0000644000175000017500000000165112342633754017650 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<ÈPLTEÿÿÿCCBØØØklj{{{efcbcay|}‚‚ƒƒƒdddsss$$#ÚÚÚÖÖÖWWW~~~nnnsssƒƒƒoooáããŠŠŠ’’’bbb888454ÐÐÏÚÚÙÝÞÝýýý999===>>>@@@FFFHHHJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^```aaabbbcccdddeeefffgggiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvxxxzzz{{{|||}}}———¤¤¤¦¦¦¨¨¨¯¯¯±±±²²²µµµ···¸¸¸¹¹¹ººº»»»¼¼¼½½½¿À¿ÃÄÄÄÅÅÐÐÐÑÑÐÒÓÒ××Ö×ØØØØØÙÙÚÚÚÚÛÛÛÝÝÝÞßßßßßáááäääæææçççèëíìììîîîðððòòòóôôôõõõõõööö÷÷÷÷øøøøøùùùúúúúûüûûûûýýüüüýýýþþþÿÿÿ™œuÄ*tRNS!,-GKNX[\]]^rr’’•¥¨¬¸ÖØááãèôö÷ùúúýýþÏh2$IDATÁ±ŽŒaÐsï|³v'1Íj· ñ *A¢õ Ê-j…Ê£hDÙeÅLföÿîuN'/»ª^¸{vŸOûïÁùéʳuwU½+½»Ä`û0âðhD|¼Dðttíwu׿¤+?`0³z<ˆÖÝ­ûŽø>ºCCÀ..‹Q@(({qqÐ##illÎ(({..‹ˆˆ×IIÂF||Ó``ÊqqÐ~~ÓXXÇ(({~~ÓššÝ??½UUÆ„„Ö((xŽŽÙ$$l:=?ACFHKLNUX[]^ a c!!d!!f""g##i##j$$l$$m%%p&&q&&s''v))|**++++‚,,ƒ,,…--‡--ˆ..Š..‹//Ž0000‘11”11–22—22™33š33œ55Ÿ55 66¢77¥88©88«99¬99®;;²==·==¸>>º@@¿CCÀDDÁKKÃLLÃNNÃRRÅUUÆWWÇYYÈ[[È``ÊbbËggÌhhÍjjÍllÎooÏppÏqqÐssÐttÑxxÒ~~ÓÔ‚‚Õ„„Ö……ÖŠŠØŒŒÙÚ““Û¦¦á±±äÿÿÿòÙáQtRNS ##%&')*+28<@@BMMQUY]mnoqrrtuz|„„ˆŠžŸ¬²³ÁÇÈÙÚÚÚÛÞàäääóôôöùüüýýþ<ïÎbKGD®¹k“§*IDATÓc`€n]K -.4 ìUÔÝo/ˆ*Êf’Ó¹hÍT+aé, â™K”H¡«–Dä6÷ôµæ)£ËMO.¬®.(‘AæpnŠŠOOÍtdGµSÁkzmi‡§,º õæ.[:Í]TÞ;µ¼2%@ U”Ç%¾rÚ’¹Ù"(Â&%%½³V¯“eŽ,ÊëžQß3cɪ ~âHšUÙµ]SfÏ[ÙhŒ$lYÑÚ;irocœ#\”Ï'"¹ ®­»«¥,&M.¬Ô›]\ÝP_‘§Öo ŒLÈÎ/*̉Ê1€ k,KŠŠOÉH‰ ž¨pXÑœ•X3Ï–.Ì"iææ¿|áüž®¦¬2sŠ)êj+Šr2€$WNOäIEND®B`‚eric-6.0.8/eric/icons/default/eric_2.png0000644000175000017500000000364412342633754017075 0ustar piotrpiotr‰PNG  IHDR üí£sRGB®Îé pHYs  šœIIDATHǵViL\×}ï¾Ùa†ÙØ1›‰¡€Á`œÖKãÚŽ”ÔV×®j5]¢¤®Z5ùS©rXiÚªFM°E’¸ ® cÀ6 &̾fX‡avfãíK_3ØQbÈÒ}zz÷Þs¾{Þýνpmm-ô8•[]]Ýæ'H’Ãpü]y¯gÞXECï5šÒž(8ðà€Ó§O£ßwÉ9?»èðF\¡Í`\T¤9hÕï»”N(ùAPÿ—ÚsçÇP h› žãšÚ>š°ù– ¤6cµ0e ¨Jåœ žÆKékØ'xU~ãBZ v–ïÜ¿Y‚xâŸý·±¥ÿúð€+%ý‡SÍ—wþ¦Èá%uCïª-…zsIŽ5Ég£WGmÂ* ™-i_ýB‡ ×ϼ:ÏPXVæhï¥îÖŠó2K¼f+òö•ɼĤÝ=\ p10Ä`NßA<÷7?©3þöÁ1»ÐÔ’¨åù½:9ÂûFý«…:34ëá-Àqg1Ô sLà  Š âèç/Ÿu¨ÒÀ;W¿SÌ'ï,‰Ë~Û´ÖÀL‘Áæ(´NU }- IÔb), RVq‚ÁƒPàk dôkÃ1M¶>¨þ•^‘ú×Ác¹Òª ¢ˆÛÉ'ëÐÉÆåö«S–rNÏøcNç:F¿ø»7åä6&˜qw3Ó¥‡ôSŽÞ©ö¾Î†q‚‘î^hMÝŠR3zŠrß÷®Òá]Ïh‡ÿã-²°(®²ÒÙ·nLikEð(‚Kã×C#öææf%çnë´÷9b‘e„ÝÃË”íl)|FÃPÒb¿;9ÀÕhνßS\¾çë+ùaù¡¡…±ÈúޓЉY…Éä¦] %DƒQxÇóÛnXµ! XÈÊÎy½þS½ÁòVñ°üPÛÒt¨§› àéªYç,v³‡6>¡Rg(`$ =­‘ûwì ÒJ’RÍþèÄïO½òÆWt“tÑ 4Öï7bÑ®0Z0µQÂ$…«×Ÿ¤ òóQ…·¦YˆõïvgT?h>ŒºîÆ;—¤d MÎ2$„BPTŠD% Á<€0@(„·ÞJM/Šo¹ Üt-Hž\¼Ÿ”n†ÕI¬;èˆ ˆˆp`9Q€A$†úGCw}×—õ¢„fnä¦J Cµ8ˆ^•H^â8 ÃFd˜=ñÓWÒsª¿Åy°V\#ƒ£ÑÀLtz†ŠÄ T@ E`‚ % Àð8v>ñhÝ¿± J½“ã!W(å° C¢‘0HÂPÀså DIå‚P®¡3 ³ÙÈI¥(tìâ à) c0É €pÁBäf•Ví=úü‹ÖÔ¬ø ÆFoõ·X­Y{÷ÿŒ ˆ%Òi_ûõ™Þ»wV¾hÈ ’N£Rª´:½I§·äägfo%qtÛd×ÕÿîvÚ·ä—–U2™³6ÞEEZ¬yGޤi´•J%‚ü‘eQU*5˲+AŒ &cúâð(¦Éß¶çéšÚ8º<ž$cÁàCÆ$€Ë‚¯x<®á¾+½Î¹yQâò·–U>y’$—¶~¹K©V’Ó½ž™Å9;‚I»÷þxßNú}SfsšÛë!p^Fèí¾2ØßárÎ…Bn–¢yüóâØ— C·4ëº}-#{[fnåäxÇ`;Š«‹Jž¶M »—ì,Ã#TR¶O¨°/Ôzýbiyýsû@O#€ ž—þÚÖT¯ML©Úue¢²zÛ+¯Kto´M>uꤊêã[b1ÿÔ½Ž…yÛÉSœ±ï›Ÿ›ÄPóÜËÇò‡w.¼zûV*ÄX6º½²¦¯«)A£šŸsÜj»(JXÍÑ—÷=uBÖÓë™6[ò× f£ MÇÈÅ–Æ?³,-‹Ž'$h5z£)ƒÀ ­.¹¢úEQ±Gvg“1M§3"†â(€a‡c˜\ ååUTízöÿ‹µ`ý'Ë„‘ K~nÉ+9täùØ#d£QŸÏã¸<_öI“9“eÅ>8ÛÓsC«Q~wï³F“™$CñG‘+ò ‚ÐÈ„k¸n·ËbI‰ó•V (Ï EÅßò{GËÊPdÈé[ ú  rŽ#o×ýâÓïÁ(.;pèðK_Ì”JÓ4ÃÉ&G¢ÞH$¯§ÁÖ õ¯­K”–Y$£,ÌNü»áLŠ5×ë™íï¾Qsì—F“ed8,§©Ôè æ,À…âÈç¶žëMç÷ü¹\ÃÃH±æÛ0õÂüèÕßÈÌ*u»&{{®Œ¹ëÛ+žÛýÔxowsoW«B¡‘] Ñ`ÍÎÙ%w­i•F_¸­êä©?u}öÉíöC+®?ø'I‰Še$äåç*/µßx¯³£Q©ìÀq Átå;)–|»–[Èàðã¾¾ÿvÇ¥ûSÔIEND®B`‚eric-6.0.8/eric/icons/default/preferences-notifications.png0000644000175000017500000000231612342633755023076 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs „ „ªâcytIMEÚ #¨Æ>/bKGDÿÿÿ ½§“NIDAT8ËÕ•[¨VEÇ3köþ.ç;öCÙ9&–ef­Ô°‹I•dQYD>„`HB=ÕƒùÕCõPQÒå%oI¡TDNqŽ‘ÙÅï–{Cð/Þ~ÓÕd™EëïŒ Z!Z#"h­DqÜæhæUj•t^,óï @ðÙæþz%>üƒŠ€ˆÆˆA¤hŒ Ect/|­5Z"¢ˆRô5ę̂Ʃéî#Ù¡}› @tÝ¥YtŒEkIÄÌLëyÞãVKT+…&B,!¦§'©Ôd‘­6™êÐÒf9Î)Æ~K_£z­NZ«"&A’‘m¤²î Ñ èè Î1=5Aðùà1Ž+³/ˆ"‚I0)J J¤hSAÒ•Tz7ˆO, báð6'ë¶É;]b,Îã&ÆTc—uušÔ1ŠdÆ;•Tˆ’€^i¢/¡,Q¡$–ø]:(JE*©àó[f@#Û¼mÇດ……èˆf2n0•“Îp/‚P*@éˆÞ\—MÅÒuv½{|ú‚eŸ†"{Èv¦P*¡×¢"ˆ*P†@ð¸ŒP´‰¶KÈÛ”¶Ki;Ù4®ÛRÄrƒN뇕ôÜ V=éòöƒ­‰A)t¥†¤U´©€$ ¡,ˆ¾ –XXBa)½ÃÛ.ÞÙ=ÀšcÉ»ñþçÙóìF^~Û{!–«;¿ýL·5Ž/r±—L%¨ 1ƒ'–žà=*¼w 6›ýåHµÑhØv»Ý£bìÀv]³ž¯÷¾þòY—^?Ô>gyÿàP¬7‡TµÖ˜ÀL¥%Tª ”6yïrNh²xñ’¥£cc¯ýãÙ¼kë;lÛ²†+î|tE¥>ë-éâX:lÞŽ.k)ŸwñEcŒ*x‡ÍZ¤Õ…íµ&ž{& /\>þÙ‡»7«½þ)à€ ¯]?<{þÅw'µú2o³³Š¼-.kmO9ðÓèÇoþvè«/Ï[¹néàÜóÓú@£RïŸ:øÅG#£ï¿4rÒï媽ñ_×nÞúno0üÄ_ô[ø¿Êï~ ~àP#‘IEND®B`‚eric-6.0.8/eric/icons/default/sharedEditStart.png0000644000175000017500000000232712342633755021022 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYsvv}Õ‚ÌtIMEÚ SXÏaPLTEXXXZZZ\\\]]]___}}}‚‚‚ƒƒƒ„„„ZZZ[[[€€€UUUcccwww„„„UUUeeeuuu„„„WWW```zzzƒƒƒTTTfffrrr………TTTiiiooo„„„ZZZ^^^{{{€€€[[[~~~VVVbbbvvv‚‚‚SSSkkkmmm………JJJMMMaaabbbeee===BBBJJJKKKOOOQQQRRRSSSTTTVVVWWWXXXYYYZZZ\\\]]]aaadddeeefffiiijjjkkklllqqqrrrtttwww}}}~~~‚‚‚ƒƒƒ†††‡‡‡ŒŒŒ”””———™™™¨¨¨©©©°°°µµµ¶¶¶···¹¹¹ººº»»»ÆÆÆÇÇÇÉÉÉÊÊÊÍÒ ÒÒÒÓÓÓÔ Ô Ô Ô$)ÕÖ"%Ö/3××××9<ÚCGÚÚÚÛÛ"&ÛCFÛÛÛÜÜ?BÜQTÜÜÜÝ Ý.2ÝMOÝÝÝÞ Þ ÞÞ.1ÞDHÞ[^ÞÞÞß7;ßKNßßßàààááááâqsâââã&)ãCFãããä äääå„åååæ æ23æ79æ;=æææçççè è"$èèèé êêêë ëëëìììí<=íííîîîï44ðððñññòÃÄòòòó óÃÄóÆÈóÈÉóóóôÃÄôôôõõõöÔÕöÕÖööö÷÷÷øøøùùùúúúûûûüüüýýýþþþþÿÿÿÿÿë{ö7tRNSEEEE‰‰‰‰££££ÓÓÓÓÛÛÛÛßßååååññññþþþþþï1ebKGDÊó´6æ¬IDATÓ=ÑËnÓ@ÐïŸßr±S'Ó JHQ«e+bÁÞ¹[lŠPA- ªÜK“&uÛcg.ì8¯p@=C[ø"ÄVIõˆZàK<‹‡Jip!nÖ3^ž\h]\T2cüz±õJá–QÿÅä,:÷=›EzûŠQêŠ ÉP^¼I\Ç3‡þó©?ê´âè¿>ô¢Fàx¾Ô;û›³tÇãn³ÿ±¹BpÆIøT»J 1(ããº#²Û©ê½<¢–Š—ƒÞn‡ï[5^|Íã ýÝ èÐg&ªÚØ0v&q§ïg¬é4JÁƒ×èWæ×[a¸q^;„ÌeºÓŽ5 FƲ-/•µˆtžíry kŒd[¦œý£6ú]¹žçòµ±RO1ÉŸÖYeºŸ½å¢ñ)‚ɯW\ 5M6³À¡£/ŒÑ2ÿ£—âdâ“C€5VËýåUc´äØ³î² Ø[«å6½üYÀSQó®\%yQòÇ·+1¯×Íä´b½°Ayz¯ÜÉßP0ƒ^ÜQÆ‚ÈY­ïÁ Y´þ?,ðuØ©Ô^IEND®B`‚eric-6.0.8/eric/icons/default/incomingBookmark.png0000644000175000017500000000250412342633755021216 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÛ 9$.¦&š!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“—IDAT8Ë­” PTeǯ#°¼ŠL@ÐÔB Œ‚ EˆwBá¨ñÖrSFKÄ•ˆõ1ÔÆ"²ˆ˜‚ˆ€¸1ò“&Ei2P–wyšÀʲÿÎÝIFË)ïÌoνwïþî9ç;÷c˜ç<ú~‰ðlILd^äÑYĸô^X6ÞSµýMѩ콵1çù‹½ŽŽÚxæNb¿&Ô?¶"ûy¥Ú]g8ín$A~[ÙO¾#ýÍÑÖ/"Ûƒ}—×B)­dunŽ7=«çÿf»\"2W*$ÅÀ½R · Ò È.zbðúg ÿ5S­®ݶ¿¥P¦å@ÏI‚/ÁÎ'¯¯:¢´ñŽýk¶$šA¼FÄwžV+–œŸß?Ô²Ê~ B’g©PJ²1t- ýW7ˆšbOõ_‰ §ÿÍzRhÝyZ½¸§jé ¬ÁíÛ1Ú•ƒqY)”}lù$Lº÷‚Ÿu˜²ÂÖ;¶°Qgÿ<ðdBÚ:&­w¿Ø{Áq%¥Ít1ך"1.=AÙú²¨Ÿ<@²‹dIÄ@×V # !û‘ü]3¸‚ëSx'ø0ä²*<”–¡ïç´—Û]a® 5¸RZ …”O²h}JÄÐy,Å8’®§òÃ)Fàí5)HLk| §Õ<(¨2åÐyZÔh\Í™ušì0Ö¼™¯Õ8Ð¥l I"ù˜Xˆ?ü›"N>_â“m5X¿½v Þ_C!Ëöd´äõ”ótÍU}.ùFß²í”nïP I¥ñÔS¯DÛ• 4T­C(5çÂ`í¶ ôÅ! ¾r V®{!*JF.×A¼…^¾xrëùÚžgôÆÿlõ#±3‰—bÛî­°öÀÜ5–n|Š™ðÞXŽ5Q¢I|6Ã<—ïaá’WÞÌ_ô¾P¾2²¬bÊ„4 5»E¯b\ìNÓ`†Ò¢÷°ÈšS,>÷ˆ•˜•=³×ì}ö™y.™0´; 4qÌØóÔ,w•èLŒÝq¤é0ÅðæHNõ……ë!,óû.!E*É#ØkVhõn6^vþZ‹¸ Ælg!c–4÷I±ø¬1Æî.UܽiŽà¡0qäÊľÇñV`ª6²/¤}ƒO̰øê3w³ýt_Ÿ…¤bJL€û³U(‡g£¶zì½âH ·ŠA=Tµàñ6P¶wÓ˜`Bc:±½¤ÒÃ`Dgù >ø[̧Õgû´¹ aŸW«`§ÄjÅp7óR¤Î³ö I¥ 7 8PŽàþ­Ùè­æàv¡&¢Âa¿ú(6$Õ!!å¢vÕSK á»Ú ¶NÞzÿ´£‰Ëæ`¤Ã Ís!.7ÄcE_»¦$Í ¡`¯oéò £lÖ;]EÈ–áàÆl´ä©sž)þý„šMûI5Ü*ÐEC&ç׳<½=GwY=þŒú¼¸–®ûÅl;VíSãÚ 5_½ûr–æÌéœj„6a´#R×7&P×ΗŽÄ ‹ð'˜™šzV›ڥߛ³0L°/Î0-5F;‚~3%ô vûœù¨}S2H9°éIEND®B`‚eric-6.0.8/eric/icons/default/compareFiles.png0000644000175000017500000000121612342633754020334 0ustar piotrpiotr‰PNG  IHDRl" pHYs  šœtIMEÔ1Í|ltEXtCommentCreated with The GIMPïd%nPLTEŸ¤¸¨®Â¤«¾©®ÂŒ’¥ÅÉ×or€¨­¸ËÏÚ²¸È‚…’‚†’ƒ‡’„‡“…ˆ”†‰”ÆË×ÐÕàÓ×áÔ×áÈËÙ‡˜’ ‘–¤–š¦˜œ©™ž«šžª›Ÿ«Ÿ£®ÞáèßáèßAEAYyÿaeaž£µ®ª®±´Ãµ¹Æ½ÁÍÁÄÎÉÍØÉÎÛÎÒßÓÖã×ÙäÝàêÝáéßßâìàãîâäîãåïãæîæéñèêôèëòéìóíïøíðöîñöðóúñò÷ñóøòóøóõùóöùôõûôöùõ÷úõ÷ýööúö÷ûöøúøúüùúüùüþúüýüüýüýýüýþüþþýþþþþþÿÿÿ÷š!tRNS:{¤ÊïïïñóóóóóóóóóóôúúúúúúúúúúúötSbKGDV 鉹IDATÓmÐÕ‚@†aìVL D\»°»»îÿRÜeg~Nøöä™wþ†1'„½v‹<ñû}ìšq›‘Œí³Ó  —¯k¹RrhüÜ«ÅB@¢ª¯Æ‰*¯WãèåS4êI2^.Ðãs5tZi‰—Ãr6îw3%m‹üx¹ÔöëùdØ4æÉ1OG¢tÚÈ2R^:ý(è'½oÇÅ4 ÀÑbÙ`ÀïsÌñû€2œüEIEND®B`‚eric-6.0.8/eric/icons/default/history.png0000644000175000017500000000221612342633755017426 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<FPLTEÿÿÿ€€€fff``` uuuLLL<<GÐ͵rtfÍÍÁ97GCAIEBJQOS\Zb„†z…†|““‹—•´¶¡¹»©ÔÓÅÜÚÎçåÙLk¯`¥tRNS "$%%&)))+-444567899:>?@ABDDDEFIJJMOPPQRTXXZZ[\]]^aafghhhikprrssx{~ƒƒ„„––˜£©ª®®®¯¯±±´····¹¹ººº¼¾¿ÁÁÃÃÃÄÄÆÇÇÇÇÇÇÇÈÈÉÉÉÕØÚßäîòöøøøøøøøøøøøùúúúúúúúúúüýýgÅ  IDATÓc``P˜8eê´ù æÍ3{ÖÌ ý}½ò Àå¸nÓ¶ «W.[ëÌÉÍÞ¬ OînOcñib`€ 3eÆøz¸ëJ0  ;fyIJ™È™¢ kxZJJ+š£ óÊHÊꉢ 3(;H+Ùš1  3åÇG3b ³´ñ2` 3†ç2a¶² qÅæÒ ¶CfNvSõ×qbCÖJQ³ˆ4PÑFö‹HZr°EßMX}úÞýöõØ£ s·îܽgW'ª°ø¤Í;¶o\»¢‹.,’ÞXTºhë–õkV-Ÿ‘WØ* LÌ))¯«¯­©®ª¬(+ÎN`Àݬc/­&üIEND®B`‚eric-6.0.8/eric/icons/default/shell_r.png0000644000175000017500000000260712342633755017361 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ 1ȘXbKGDÿÿÿ ½§“IDAT8ËÕKl\gÆñÿ÷ïœ33ž›gÆ—qâLhLlã–©Âj‘£`©4ª`*Ñ X€`ÍŽEX „(b‘îH  Ê¢l ‰"„Ò¤& Q.v|MÝØãŒ=÷9ç|–’4Mônzõè•^áœãÉ|éìÛA0”þZ±yëµÅ¹¯û?PÊ3ž’Aˆôžòð?(ßCžð/³¹7øg«o~ÿÝ×½£x*뻹W_™©Wó³‹g>ã=lwS±ÖVHC€8µk6R¢”Ë{½Œª¥}QøG:Lai(TGjF¬Þ»«¢&~¼Ð! ãá› ¡ÉaµÄ…E¢¤WJI¯ðLØhí¤M[­qW÷ÿÊÏoü˜ûúåcÕYGÚÜ0“ñ)悳`âHr§>‹ìL!tù4, ±ÑÄÚÑëYšuM³©é M;ì°5XgœST†J•èü‰D‡Î§6FHëÆ‚N@Gôð”CbÜPä0¢I$÷™ðÆ‘Ö"õs`ÎZ묵Îhƒ‰zºÝðCJc üCÿ¬!åòŒ‰s`-h÷ØõeÒ«{qWÉ~½IÔÔÄ]¨Ãšð!6‡Ó cl2¬–ˆÄàýlø+Õßž{)¼ö…ñ°”?z=äÕÖ€0Y¶X0!ÄâpTÐN`Ò‡HÌ'á7_Ìå¢~oæÜ|ùµÚqqrd<ô A–3•)ÂN–¸¿ÍF»M*‚T ´Ê`ÄaÆ—`,ÂØOÂ:‰Gµo½x"÷ÆÑéZ¾tü4ȯwyp‡h=áV«ÍD F¤÷áÁ DH ¦$Á:¤5Ïmb¤’-ḏÏ ÅááP¦Ë´lz+!šdzê,ß?óN-ÃâN–Åþ(5¿FkSñpö·!Š:Öè8y¼ñ0Í©b¹ôòÂéò ª<¥:I@²³G!Uã/V¼N0SÌæ%K½6‰q:Qb‰Aé':vÎUT˜:z¬V­Èü$ýH1èjªåA˜ÇÄ=ì ÉTv”&Š$YGÔˆ=)$ž P¤°Æ¡õWÑ×"AvàeÇ0é ¬(åQ} ÔlÑÙØâØD‰Úô ƒtÈð¿-¹A?4 ç‡ÍŽÓÀ#NâÇpàÙJç`¯Õï¢r“ô¢!ú:C»ÄM¢ƒ]ÚŽŒ‘ž!DñåÑ3¼yîg¤²RÇDy’wÛKÉÆÖ¶yÇVn›$ZÝØÜ‰fk­ ¦…ó}´†Kú®uP§µÅ‰J?Ħ[ßlÜkù½† çI'Wýµ¹¶wow·uí\OµAݸ½íÍÍ·ÆòŲ’Òs÷ï¯ÄÈ 3hH5T©0ÂÀˆ¤Óéí^¿zëòÕ÷þ¼ÖOÒÖ9§@V›ÿàÜò#xaaááÕÿvýƒÕøWŸÿâÇß;9.ÖÆ½øö­¥µ­½R‘zéd®^Î}•+W–VoÞ¼û—\¿÷Ã|ãdïÛ?ú©åQóóóvoåÃíNkÿ—ï^^ /7¦FÊË©õèïD{í[^)N•÷Þùõ¥KÍVïýÆ~ô¯âHµÿÙÓ¯8žpþüy777׿xñâêû—ßûS£Ù=21²Ÿ¾ÓéÜ>ØÊʺºº”””œ""”®šš™::•••˜˜˜”‘‘•••——————˜˜˜™™™›››˜   ¡  ¢¢¢¢--—UU£--›qq™))¯RR¦77åååæææîîî¡++°BBºººÄ­­ÎÎΠ--«==¯AA´YYµ\\˜˜˜œEEœŒŒœœœž‹‹žžžŸ<<ŸŸŸ   ¡œœ¡¡¡¢++¢``¢¢¢£££¦ss§55¨77©==©??ª^^«@@«ff¬pp®??®@@®DD®ŒŒ®®®¯AA°BB±DD±VV±ww²FF²……²²²³HH³³³´JJ´MM´\\´€€´´´µNN¶YY¶ee¶††¶¶¶·dd¸QQ¸UU¸]]¸››¸¸¸¹WW¹rr¹€€¹¹¹ººº»]]»»»¼mm½^^½©©½½½¾]]¾ºº¿¶¶ÀbbÀÀÀÁÁÁÂii¹¹ÃÃÃÄ¢¢ÄÄÄÅooÅ»»Å¼¼ÅÄÄÅÅÅÆÆÆÉÉÉÊÊÊ˳³ÌÌÌÎÎÎÐÐÐÒ¸¸ÔÔÔÕÏÏÕÕÕ×××ØØØÙÙÙÚÚÚÝÇÇÞÍÍâââäääæææîîîðððÿÿÿVr|9[tRNS &((,<==BMbbdkqvƒ‡ŠŠŒ•¥¥¦©¸¼¿ÃÄÆÇËÎÐÐÔÕÕÝáááââäèèêêëìíííîðððóôôõùùúüüüýýýýýþþþþþ e[bKGDÊhŽBQIDATÓc`Ó8 'ÆÂޔ߾ýì÷— #8Æ[·îܽkÇvc0‚ã¶pÍÚåk×,t #8vIK7¯ß¸)Ó$Œà8&´­­Ÿº4Å$ ä¬r2윢§®›Ø73Ö™( ä¬l³1ÉÁ:aâìŽ}éJ@a넲®é“–§Z1hÇ5®ªiîÍõV•``ÐŽI,µxr²ƒ I𒬼¦ª@u™°’†öês69KßÊâl5>Fy÷âÚpCI.0ðŒhŠÚ`¤Q‘“¦)Í Ö-XвçÀ–ȹAf Ê 0`1¥³göeý>*â¼BpQ×yòëÖyq²2!D¾žòu¼  €A†=ª08À¾FÀ XT>äk ‚uÝÓ–}€A°¶mF¨©ª0(eEÙa\È‘…ýÙ ]IEND®B`‚eric-6.0.8/eric/icons/default/configureViewProfiles.png0000644000175000017500000000211612342633754022243 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ ,¢¦°ftEXtCommentCreated with The GIMPïd%nPLTEoooŒŒŒBBB)))aaakkk""" kkkÕÕÖ888¥¥¦~~~hhhaaaJJJØØÙggg€€€ÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²««¬¯¯°ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ¡¡¡´´¶µµ¶œœœµµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º¯¯¯»»¼®®®½½¿ÀÀ˜˜˜»»»¿¿¿•••–—˜š›œžŸ¡¡¡§§¨¨¨©ªªªªª«­®°®¯²¶¶¶¸((¸¸¸¹¹¹º’“ººº»»»½½½¿¿¿ÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈ45ÈÈÈÉÉÉÉÉÊÌÌÌÌÌÎÍÍÎÐÐÐÒÒÒÒÓÓÔÔÔÕÕÕÕÕÖÖÖÖ×ÖÖ×××ØØØÙÙÙÚÚÚÚÚÜÛÇÉÜÜÜÜÜÞݵ¶ßßßßßààààààáààââÎÏââãââäãããããåäääåååçççççèèèééééééêéêêêêêêëëëëìëìììììììííííííîïïïòòòõõõöö÷÷÷÷øøøùùùúúúûûûüüüþþþÿÿÿ–Kv[tRNS #*2<AÄÌç ê£5oáöfD? "êÑÏ^DbŒ´¥+Ðçò²¹m}üõú uœ IEND®B`‚eric-6.0.8/eric/icons/default/irc.png0000644000175000017500000000256112342633755016505 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÜ  3'ì{bKGDÿÿÿ ½§“þIDAT¥Á PÎwðïÿIT'«(*½èýÑóxzY”^,/Y¥ˆ•›åý”Pm4Ô¢±œRÞVÔcá¨m‰JÍˈ"®3«ØrÓp·¤ø}wu^®mî¸}>ø•z˜YcFãÌ%x[Hð4— 2¬Íðþܬð^¼¬€áÆøoN#ÐMfcW†AO&p‚÷H)tTrÿpùVÍ0û/á?l1l4ÆÐÃ+ãÌ%¼U†3^ó4ŠDŒýY¯‰eiÌ©=Ȇcü¦þ0Sª2–¿Œúk]0ièñRSôæl‚nZv&˜m^6j×$æÜÚÆö‹¼×UÏ–gרÜqU´<»&Zºêy·³Ž%÷0¤x.ubíîÂÙØo×oZ]µÊógÅÃBÖ=.gfe«š­jV´ªYѪfe«šUŠÄŶ¢úá· >3úÉö]›ø¢›£„^Â-Ò!§AÞøKÎ/áîÆ ,hÚÂÃÍéT7§SÝ”. š¶0ïn*³˜x5BÌ>ëÃI§TÏÇ–¹Ð(Îá&môb¢gˆÛìVRÊ-t÷9Ðáè•û2ú§©\y%ñu"®n"—^ñbTŠ‘5rñé%9ÃÏæôó ºå«…Á,ôâkà„öí²%õ(iS¤¤K±‚>'å >ãÈÙçå\\ç!’îøó‹_™X?+Î…Šè3Œ:;V,¨u`hµœºAFëÑ‹»®’mÿÔݯ¤y¡R¨N(…ÿ)%gžU0沦Šm÷æ‰%ñ"`]¶ŽûŽá«/ˆˆ59-®TøÆ}MUr8ûxèÆá4d+Í« ó•t8ªÞ¥J†V93ê’ŠI·‚¸½9šSÖe ߨ[ÜœÛÉ#ådÙEŠÓ5ä±J2·ˆœûÙïÔS–ÔKíÑͲLB/Ãmöt+ua@¹B̹ `üÏþbǽEôŠßK»6‘ž'˜©îdÊÞv¦ä¶‹õû:˜uò9·|&v ±8­“:®Õ ktÓÚj‹nšaƒ—Ûf;qúy7Æ\v››grõ©”>¬¥öÄKÂtÆmºG·qEæSƤµ‹ÀØ'Üq¼“{Nuñ£å©˜wGôó¯'¬ ‡&Þ°À×=N/Ö4Nfî“h133Ÿp¹.à}]À»UÀ¯C$ †e¼ƒftÒnQ—(¾F…?%ƵL¸I™kùo€¥1°PBhm‘xz,\òãœR7ŽŒL|ŸûÄÄÇÔ4šOÚ¬tLÂz i½ZðÄ5Ò=‘ÄäçB6ù ûz–?F˜~è(K­Õdù°ÂþH†Të7 ¸©³ióB8¬ôz#CIDATÓm‘ÍJÃP…Ï̽éOˆPR)ŠZq£•Š?+Òµ/áK¸ñ5\èÞ—}qÑ¢¸—ýQÚjkkn“Üë"IAéY~s8g†!ÂHOlngÆÌM9¯ü¼0,ÖrJé|zH–ªý‘wˆáxžcl—Ýèë},.Cc@eƒàOÅ•àxª•¢æÅOV&2:º 'Aº ç‰@ ážOUDžfÂ)ž£_<›h¾eÓIEND®B`‚eric-6.0.8/eric/icons/default/stopScript.png0000644000175000017500000000234312342633755020100 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs × ×B(›xtIME× 6Ô iªbKGDÿÿÿ ½§“pIDATÁkl]uðßÿœ{oÛÛ÷·n´cMaέK²¸`D]؈bâ#Ä@˜4|m‰A£È'_1&Ä Äã f–eøHÝÂ\@ «­›lmíëvmooï½çžã©‡1Èe,$\:Ê@ø{b¾—çpž|‹âX½VS£VçlÂïçyõ×$àÅMü¼Àã=]]¹¡ƒm>p@ÛÀQ¤¶¼lþwL:efrR…³Uù1à›9ÑÆg‡FGíxôQM C𦮽ñ†^~Y)Iªú!o€/¿›W:9<42bø¡oˆâ ‚ K‘!#C–e`ñÂ_|Ñb–Í•Ùÿ®@ óX;G·vvzð°zý†æáak×&„úµ²´²&Y[U^X”ÜfejJs±(¿±a}v¶µÎî2/}DÃW鸅ã}´ܱWÒ™i¿ës¶}团ž^×ϼ¦•IÖ”çFFÝzdLÓà Ë'Ojoo·qù²Jšnäo1!ÜΡ¶´… å¦œ••Å¡„ wÏú®«3S®ÏN ŸØgבDž(R¼y«õ¬¡^ZÒÑÑ¡•ÐÄD1âƒíbogŽÖ¾e­]©÷ß<©ýÖ}:úµo¹EtÓ6¥û¿óŒÅ*7–½6ö5mW.Š¯ÏªÏ-JP¥¿Â³…g9ÛÇ›Úè¡Ð4ÚóÞ[hóégNºó.°~£ä/GÙ2}^W9QŸOUX®1Gö»"ĺóˆs„˜gŠ-5#Û—üùÛ‡LOŒÈÒÔóYoùŒ­ý5…îT¾›¸HŒ<¡…ž!G5†”,!Ki¤L/°ë¾¯Û<|€E>ÿÄ1¥F‹´H®ƒ\q òH¨EH1lP¯P¯0uhϘ~úœ(ŠT×JfÇÏÝ÷ÜoÿŽ›,µh4i$@Žú$3eÎg¨ÕY_bzž¦ýcîyê9Q«­•œùÕ½ûÛ{Í_: †?s¿}Owm½Y ë4òï—(Ehü‹SI’±:ÇêZÁî¿%ıÚZÉùŸÔW9ggÿªÉ[? nþÔÝŠƒ»Ý˜¥º”9zŒì=V²·•Û’„Ðh¸~ö„ž½£.þæÑô9-y$4‡ªÙ·_UÜúIü¾õó³ú>QB`éžg)r_bô1þÚ »ÐEþc´tÓÜI¾•\3Qž4#©R™aùŸÄ«É&8ö$¿C5¤ã”¹¾“û"rµ ªe’õ:I•ÚÕUÊÿcù+мA;æøÓ¿LY‡Éß¹²‰ÿÞΊiB}Êëó”g(_eãCâe:Sºh|ÈóOðt…2ˆµ3üç*§?NO?Û‹ä )…„¦:Å]=d ^çGùC•%¤yô`çÜ»‰=MlÄ K+L¼Ë[/p.eUdC3Š(ê¨`u¤ðkØË]Œ‚IEND®B`‚eric-6.0.8/eric/icons/default/designer48.png0000644000175000017500000000574612342633754017713 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB7ÇMS pHYs  šœ ‹IDAThÞíY TT×£6±&699i¢"ŠQe†XDcMMÜQ©¦(ûâZ³¸Å#&¦cŒk1¢Q˜"2ˆ0€¢QÂ* û°Ìöõ¿oy‚JšöôžóÞ»ïÞáûþíþ÷^@ßzL7íÙmJ'Áľ¾¯Ìôɤ¯­Â|¢÷H„LBÄB'zê'qx% JØSð[iÏLêÛÀïLî×úª¿fî³EHœ‚bu| !ño€À3)ð—8ʈÌ÷$¡ôHò‘ öþõÁO7}ŽÀïL3Á ž¦pûÎÁR!üÅB`žÒ7¡…§ˆT ×_C¤ò‰P&ÉIz£wzKò2½÷ð’XwëSMÆ­`rج2GHlÇÀï+D ð¸Ðh©`²\ ÔI÷M,T‘(è9ŸÅÒßMô>ß_ì8šž‡“ÕúD {=~¿‰i¿ÛLÚfÀ˜ûk¿S¢'ÈHH2+Ò·[DJN„Žl"R‹¨ï•Çw¡©&û»î$®»mŸð‡ˆÑjq:W\ôãhÖ?¦3öµ%óÿœ‰q„ŸØÒÞÒ' —.%tœwÀœƒ#áa‰@ñ„HÇ`~”¼£mˆˆÃ}ç’»pDïG¶Ë°x`}~"ŒýbÆ~2ÛNm…<_†—‘{ç22˰7c-Bbœám§z7–¸ùâQðÙÁWdß!‰.µÀüFáõ%fpÝàƒ¢ÛåÐhЮi´jäV]Ah¢—Þ: Ž:Àùss¬ûbwÆj¬K˜Ã²S;]BÀ ýÁKM1îC7TÕU·G®å¿V6–aíÒ´çrn´(ö˜ñNfȸï×o§aIì›d)û®%`ÿζ‘xiÎpœº”Ä׸F…ˆô-˜¹Éaâïxß.•C 3Žx+lú½kœ’\îÛå›É_Ѩ®·`4WσVËWµ4{ù´-þ6½ÝMq,ù„ñ[‹ª ÛRÿ±5.û#Ưð@mc÷-«< Á1¢À·æ2X—¤4éa‡>žðÍñpø†ÖZ¬#7Y@¾,uDÿ LXí •Ze#ÊŒ„Óz ïZŒðÓ?ûó(N6'“›¹c±tœ‘ÄS'Àê¡¿l±D¯Yq%ÿgܪËx/îm.«0?w\?ÃüÇ ¸¢Ì8&骜\Gˆ–V%o®J£Dms%nÖ•–cY¢K,¤%_¸Þ/ϱDSK3DfiBŽáü˜Ÿ¸u$^{ײëò»Á\wŽË&áæÛ|÷kóx +^Ç,»Î#W mÈ;P©T<²1— 柹×/y ‡T~š7Î{×\ÌÜè¬_®ûÊj Ê Gô¥ï°ñ¬7¥\Û®ÊBŽ²Ì o­šµZÍv&/’Ò -7†÷Œ°Åïg Fä9 oܦ„%è9Ã’ '}Yåçàíˆ9‡Ìáe×uAìKÿdà˜µ!€)~: o‘­q1šwÈϺÄ3ÇxãÂ? î¯ó,s¹üWJ£¾Ñ0 1…÷W´[»Î俨P2,86Š‚}"¢xãv$oD!<WnþŠ˜æ|¾°ÝðŸ @S]H&‘<óHüDŽ0[<“×·úžâ‡s¡è».ÄÖ‹Ž\諳«Û¹PgÐ4/uMm¦ªZAÏ‘<œ[…-Þ —÷Ýiâqâ/ÇàKÕ%ËB† î={0Ž$ÅðÆ…žZ„çÝ?šâ£®ª®¯?#Cuìh-*a™x õ÷| ¶7¶]3f œÑªâ/FiÅñ¢r€‘`c]Y¥z)6ý oÜj©z» ê4NóZíÊKWP…ÂÃÑ(Å¢¥¸¤…¾­ éþ@Î-ÐËu0jôuŒ¡]½™‚%Òñ\m¯[ÈFp Yòõtã…²Ëųñ¼{ç,@a7¯¥UÓTU]‹¢¢bäÄFvøü¼ÿ0ò‹Ñ_¤Ò¨Õþt¡)Û­Hƒ¦8{ù@y]>VžšNq +%œ6èJ‰Â[%Æ1…Õ×àÿÃôqrO•q5PGhmqÖk~¾V“Z[_sÅe·›‹´ÔTd“à⮤o߇Êô,(›š·?°õ:2 }æÀÇ7ó(Õ­Ø$ó£:Ɔ[±MCÀù½™P¶qµó…x°Æ‹Ãx~"ë-’Ž¥BКۥþWpœ3¾ïçHCfA{¡JÕ0ŠŠ? (÷k¤É³p>5 ñq'qzoòâÐRS—Ec­¸`Ú}}é@—MC‹²õž@Ž"v˜²s8ž›Ý߯Fð ¶½™Á3Ò‚Vh3nÜ e-þ÷1Þ _…§S:¶á’¯ÄIg·iÕéUêK(*hÉ )£²SC!OÄQQ äò ´44þD?eõH[JVç¼@™$2‘_&¨iCsðâ—˜üÙ,Û¹ŽWJçQµº$v<·ëzþ¯¯bmÄ—è¨ÈÙyG‡seÉÞÌÏÐÜ*ƒºÎM¾9¿”¨RPÄ>‹óG—Cž‘ú†Æë4uäcm)-W™Á~ñÛ¼r™µV¥¥•·îq¯l>Âí‹Ù\—/Ì1

—dœŸÄÁôÃéÊ”À÷U*ª+K³âP&B¡\L¥(‘m…FîEn“ÅvôS¹mí5{€‰ëÛ¥ARáTjC2ˆÀ¾°]ØéßÔh±æŠ< y)GQ˜FÛÁ‹Çq'GF\¬Õ*2Ÿø®hîÕ²òòl77ì …¢$ ŠªâJ™Àöº$Ï ~ˆH$1­[¶lEÊù”z¥²õ õM'ùà¿¡±ó›ŠŠJussË7ô<Êx òÿö?Öþ 6éT¸‹ÏIEND®B`‚eric-6.0.8/eric/icons/default/adBlockPlusGreen48.png0000644000175000017500000000720312342633754021265 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœtIMEÜ &_-UåiTXtCommentCreated with GIMPd.ebKGDÿÿÿ ½§“ ÚIDAThÞµ™pgÇoiûÇît$’¨”Ü"¢ñ#ñ3%³jf ÆQ;U¬®±ƒ1k; -auM ­®aº†ajX†)«Q4~nR!õ#Bü ŠRå>{>ç¾çíeÓ`ïÌ™÷½ï}žs¾ßóœsžó¼7ªÆ§¸¸X¯{®í©Qt£(öðÍõž‡ ë@Åè>räHèÿòÙ³g^·”o‰)¸^0àØ·Ç¶ž¸uâ È~“’[%?K‚sÐ.t¢;hë¹}6nÜè߬8ø;QrùÞeWñ}…»qÿ†»õÃ-•Û?ÜV¹óàŽ»ûà®/|GìwÆ2ùºÐ‰îÇÙ|.žç³ëÊ®ñXÙ•{WÈý‡÷#"\PFþOyt<:Ð…Ntcãq¶ŸêSPP?P ”{ž|rò“Húôt×pTC×ð £WOý©Q¥ïúlôOŸ!è@:Ñ-áTŽ­Ça¨Ö§°°P¯#Œ¨¹ûêî· üÕï¯F–ž^êšLhâ’$»”¡)Ñë°×à÷ ô;À¸mäk*ÜóŒßRÞNÑ±Ì ë5mRš[rj «à“À&¶ƒXªíùµçÖÆŠ¢Á¢°Åȧg>uMÿÚÔÕýmÝ(P“?7Q/ aUÒ&¦©„ÿö¥ñØÆ:Öæq­×¯žê\QºBm\¼{¥ØCµVbïÞ½‚?^~·Ï»e§—ERǧúà <ÛxLcÍw<ŠÇSÇ¥ªpÏ3Æ0‡cŽ‘†H½¾õº±­ó߇Äñ ÃVeÂøj@M‰Ã·Šo/û®Lö£’"~¥Ï+ /ó€Ü€|O›œ¦¿Ñ{yf„Êjpea†NH0[ØÄ6À&°åççW]*w\Þ1D&–øŽ}Á`rÿd5†á`Rb”d ‚„PóÜæ*škÓ)M]³Ítž®šwe¼Ú 7äŠÍ›÷o‰R0=±ÄnÛ¶Í¿ß~iû ÙË™H<.8±@Á[rêÕ«:Ä÷ëS_×ï0€-ÿÞ2ÿ“Òü«¹ ÷ÏuÛÑMWã!3÷Ø\~¦ÂœÅ3\Ç }"Ø`À f°‡êö®›"ƒ‹¤Öê,«&­…ÈûÅïWê$¥íuY«³¢¡!Å‹„HëE­Ýª³«ü±ÁTºNÝS Ò~e{ ;æ´[ÞÎm½¸õ‰sh½‰œD~¬`;ÂF€rE\ãu !m¼°±RKLmîÿU?”X <ÙvY[õœCB«là8 Þ3XÉ+¨GôC’³ã‚„F©¤Bj¬>»a% ^+â!Æt†¥øcÖš,útUrïá=UŠWf}3K=HŒû%SÄV鳫ëüïÎîýï¸Âë…þóÜor5w˜qBÆ~£¡˜?Ð/¯¡ˆMžƒUç V0+¤žIa™¤`K͡Ѻ·ŒâïsO.d­Êró2K¢$¶í¶„¡y”€9À˜ éy´Ò¡vÍëêh$meúîêëŽ~{T €졤IaÙq}$|¨”7Ù0|/ääçh2sÏø._tñë:áƒÈÒú²7e»v+Ú)H6#bšß&š­^’Ì8 BÃ÷÷[r Àè¢/b%±‹€ìJ@v]%Àv­!ä­qÊ2š¾¿{ð]5ÄYvôFû¥“ߨ˜ÆCš{vti‡5ùxN˜–Ì!ü!Ù””¿C€šOw\ßQʹš»÷ÎÞ>0+Äî‰á…% ýÀ›F€òIkb@°"xð`ÀV0ûdS*Â+F€ 0éÐ$<€ˆMÂÃ~c™C3ÆÎ*žQ ÚWIA$È!V€çÌÕ¦ÏÛ‰©Vä ºØáõ,0¨¾‚Fè ˆ ÂŒ`³¨Ó¥NX–K àqk¨÷#ŒX~â x™j ­­6U€¡b(!Ïò]„¡'ñêò¯æë.Ê rÏÁ…ñ$ÆYU„Lß% ‰vÀ>‘þÉ~€Ì`ÅwŽKé*b«çGZ[ª ÆøN©dE¤æj_ŽB–¶×Î^ñt IhçXÇô™NâÚ6+Vˆ°ã9B™¬ž‡EW‚’]Ws1`3ØCñâÃSOU,,©|ßwmŸn,xÀŽ•ìÒ\­~C‚zM ­61Ê\™›˜ Tª)»6®n„ >ë¤Í´vжge{¬‡–¸/~!ãJ' çzÎyÓ šJTz~t¨­ñ(Ì_;¢„Éæhnè¢ ¦Õ”‚ ©´­úÕŽ4Wß´NÈ>Y©¾;òŽ%mu¥R•±S¿¸££x÷‹íâ¸~x2uÎEÓ*QP ðŒBÇ?ºjoí|Ç˃YÞ6­aì¦/í€ï}êc'šZÞÃ`v¼'KCÏ{IM©4ÒÓÁ±Ç¢š†–— M–bZyÑP%b gèùOÔÔ½b$-Æ´0vVAòÐ' rä_YT(¼n,-Ä$!Èþ°çOÐwìIÓ~ð—,ƒÂJgÙCAÚi/êªT²†ŽˆZ:‚¤R9¥½2íF]'¦1eFðœB”õý.J»áÃvþ­?{ÁG¦5=AÓ³8õ¿¬£rê?ivÃùx£—7ê~vàÔPÛŒh™1£Òwß]uyãF/d¬~;Y+¬›×ÒPS€ÊØÐ}_)·n­2.uòÁd®ï —L©+Y¥ï¶»šÊGaþæ!ƒÕNÞLkCM¯zÍyÁ:Õ·Âå[G2€÷W\¯f+• …B¡èÚ¸³ 2>hçeK-`ßžÝpïv€§ÝñzíL:IEND®B`‚eric-6.0.8/eric/icons/default/1downarrow.png0000644000175000017500000000151612342633753020030 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<°PLTEÿÿÿ@fUYUURcmLKr…LQnN‚‰MVNRZainqovz~…„ˆŠ‹]Rm‡ X‹Zeb ˆ…i4r4—¸Æe§e€®T ’ Ÿ}°ž%w&/u/G…GQQV¢VZ¢Z]¡]q®qViy‡•–œžŸ¢£ª«¬¯°²µ··¿ÀÁÃÎÏŒf‚v m£&§&'£''¨)(¦(*¢*+œ+-–-.Ž.../£/0{02†23£35€56¡6:ž:<ž<=š=@–@A¥ACCE¦EH¥HIŸIL£LO¡OS©SW—WW«WZ«Z^«^e°ei²im´mx»xz¯z|½|ŠÇŠl‰ÂyHtRNS ABLOrr~„¤¥©©©©ª¬®¯¯±³µ¶·¹»¼ÐÐÖÛãèëííñúúúûýýýþþþþþþþþþþþþþþþþW2F¼IDATÓc` (&&.!)%-#'¯ ¨¬¢ª& Öîu7wi¬*ÊM43µËÑ s÷÷t¶Ôg…D%$%Ç[šðBLásêëj«/Ë ‰‹¶‚™.ÒÚÝÞP‘ç‘©·”Qí£©2?Å×?ÈF‹á6]׿ê‚4okNdGr9צ{Yò :žß¡®4ÕÓVÝS¢%å²~eTw´Òd v}=laÃÂJŸ8¾g(¯ª•ÁûIEND®B`‚eric-6.0.8/eric/icons/default/preferences-printer.png0000644000175000017500000000171612342633755021713 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<×PLTEÿÿÿˆˆˆŽŽŽŽŽŽªªª¼¼¼ÔÔÔÖÖÖËËËÓÓÓ±±±   ÃÃÃÆÆÆwwwDDD©©©¬¬¬§§§¦¦¦ÈÈÈÎÎÎÎÎÐÓÓÓˆˆˆŸŸŸäää‚‚‚ÜÜÜæææèèèêêêÅÅÅÒÒÒŒŒŒÐÐÐŒŒŒ‹‹‹­­­ÅÅÅÆÆÆwwx‚™™™›››¯¯°µµµ***115888???@@@AAALLLUUUVVWXXYaabbbdccdcceddefffiiijjjkkkmmmssstttuuuvvv„††‰••—››œŸŸŸ¡¡¡££¤§§§¨¨©©©©¬¬¬¬¬²­­­­­²­­³¯¯µ°°°°°¶±±°±±±²²¸µµµ»»»½½½¾¾¾ÀÀÀÁÁÁÂÂÇÃÃÃÄÄÄÌÌÐÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÔÔØÕÕÕÕÕØÖÖÖÚÚÝÜÜÜÝÝàÞÞáßßáääæååèæææææçèèéééêêêëêêìëëìííïîîîîîïïïðññòóóóôôôõõõõõöööö÷÷÷øøøùùùùùúúúûûûûüüüÿÿÿQ:tRNS  &++557?@CGGMQZ`vƒ„šššš­­³µÐÐÐÐÑáââããäçééööùùúüþþît6¯#IDATÁ±RQÐsß¾laÒ(ƒ ¨3–þ’ß`©?åOhM…ŒŠa²Iöe¯çœ- wPAýà( X½Þ4@;_AþÍz=ŒSNã°~ÛCÕÕèÚ.·}lûi,Ël-\}ZmžÎ»E-‘SÛÞž,ßU§‹²ûû/…lýqžŠçgó’]˼«Ýgn®ðá’¯5·´Ä2º6`Ü’µˆ^DŒjL'39®3çõpÄÅ$3SˆˆRo®ZÍ ×X½6díGí±àqÈÖÇËWûnñq7u‡µt?ömv_¯]¾;2”©ü¼2ÔܘÇñNddÉ4‹qC…P#¦È2λô3Œ·{J€Ã„ÿx„9·œ4ÅIEND®B`‚eric-6.0.8/eric/icons/default/ericWeb.png0000644000175000017500000000315012342633754017302 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs.#.#x¥?v IDAT…ÁyŒuðïoæ73oÞ¾kîñlûº»vK»µtÓe TÛP!” µÕÁ„ˆ([­JHPµåˆ¤ â6bÿ¨HÛÈa(E Øn»ìÕ=ß¾Ý}ÇÜoŽ7of~î&51†àçCð1ŽÅâ-¹e_?FÞFc—„ÆÐÇùcyð4‚é+h]ƕꄃ#Ï{†2××_9qî¸ûÆŸ¢<ò´x î—×}òÙê„ÂçGÿÁˆS$¡c£2§CÈH(Í-aU:Àèpmë ÆÏ1–@H$’‰tœüÝ_½<–\õô»?êÉ—‚3®®vÖÕ­<™Ö]'ºµRCiÑF¢sz:o‚Ì'05¦C]úpþõ—L0ýП/ e»šÀcÙo/ !§Õ°.ßíÌB0)azúœ à ¦7â3;âæ›bòŠˆ©ùøxRz:z÷æJÜž”ªö¼S«¾S›(¸àc((—²Cf3ûúŸR¼RfnY!çÎê໓`<2Î&ܰýgॠ¶ä°¤y(Z²¹&& <1Œª°¦³©Ÿã¸œWëÝ6þæóí»7q Uï>3Šî;} vÅ!5&¢=Tó jc6¶^÷âs;×#Œ€“oŒ€Ê"¦ò*ùpRÁbÅ•%&ñØâ;55‘ÞqžëÊÉâê6î^jQ )ÓŠœ‚…ʬ jyHÈ7 ”±qÓ*´g30ý·îÚ‚® «a 1G]àØÌ‚JFg44¯NJ¤R\rnjôÙê%$SqâF–MP­† „ƒ~sEb\‚Q­p’qó Ô0‚KxŒÔÇúvl`©Ö¦Öšïo¡z¥Ô¬-Ž"až¦#&‘2Ó’áñ"^=;ɺ7·‘äª$Ü:0_©¢sMuÇ伞'àœ:ùD6 ø>ÛNõJèÓóPFg #ˆ ‰`ÖCH²H.LV˜Îq¤¥)÷æMø\J!¥d ‚¹%¼ãˆMêþ¤PVÞfvòÚˆ b„D1z¢ú¾å´É ?[²fT €6Èp d»€,‚Äab¼Àb¦Eö=pÇ}ÆÉ—¡¶=°0»³ŒJ$s,H6Hn\,[•À;Tˆ¢mŽrá`„ ß¹µWt,ŒÍk5ž©3QÊ&iö=5ü(–Ýùå£ïŒŸº¤•L¢,L3¿f±T&ÃnÞóÝà/©qµìýʯեü’Å6td/Qd3 ²€ui oœ³ˆ©{LˆçEGYâª=»}|„_yéø/~¾gë‹çý\@Îìí)èkgE‹#•²Î,»NHÄHè‡Ôuÿ×ÊÔˇqðŽ{àì[÷æ‡EåóYÝüggT'Œ,‹%‡D³.hÖصAeêÑ 0 ‚ÿãØ3Çñà·÷ãS½‡á¥eü¶tk㮎®6ZQl®¦h³ížF=œ}w0IJí_+âß• 8lRõIEND®B`‚eric-6.0.8/eric/icons/default/numbers.png0000644000175000017500000000112712342633755017400 0ustar piotrpiotr‰PNG  IHDRn½¤° pHYs¯¯^‘tIME× 8`€{bKGDÿ‡Ì¿èIDAT(Ï•“;oAFÏŒw×ë·cÇF¶ƒ“ €Pn¨Š AGCŸü$*¨è¨@‚Š‚WÅ  )‰D`‚‚¯‰ñc/ÅîÆ‰… fšïΜ¹óÝ«ø¡Bq¦è^iv’èašÂËï ?¨]L=Êef<†»s¤]6Á‡uÝ|ªì.^xcÊ¥… ã÷]{ãK¿…xsÅ\s @fgòïªо‡%åp!0÷¢$œö¥ñlNÔ›ýÎáªÜä•ZÕ!l[ó[Hc¼ÔÊèhÆ™êcù}²Œpo<ó×Ý(+éÎ6=’VÚ‚ŸãðhTm J1 üR'À ä[ §ã˜Ð™«j B8—À„?a³j!aé &©ÚÖƒ[l d\ΞïÁç Ù»\ß Çò«©D>l{€yF©¥ÖQÖxþuMjRÞ!¬,ž’“²à]6*Ö‚ùV?ØÝÉ=œ•¢“ô;¦ƒ7­µÊ¹$Ëͺ{HX!ä=8´%+ÇE=á@xYaõ„”dJâ’—Ä:‹¾ç^d+B§/ÏqB¸u«Û‰Ð'‹úݹÍZØF¥o”· ¿¸KiôÑÐêZ¡QéÚï¹NzïŒ1fƒö¾ÎšTHÑ䇟õ/2«ÕÑIEND®B`‚eric-6.0.8/eric/icons/default/vcsAddRemove.png0000644000175000017500000000255612342633755020316 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÚ òˆtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ÅIDAT8ËUKlU=ó³ØŽÙù´ù:ŽáS†”E£vƒ¨º°bQE]Vˆ5(*êEBbUˆ² Yt–‰X¡¤Q€*Å4à$8qÇñgÆž/÷>ÙVAyÒó›Ï;÷ÜsÏ»#áczzº«££c¬½½ýß …“““í¹¹¹Üí“þþÀ²,ùððpêøøøÍX,öB$išëºpiw i}Í»m,J ù¹Âã‹LDRkšæþ+ðêêêµÁÁÁY ɲŒR©Ä ª*˜Ç’{OFž‡?X@YSFÒx©œÉdÞšœœü¼%7.VVV¾¹éóùBº®sÊ”xžzb£fáÀÞÆ©œFÕ;Å®ý#ü~(‘H|F &½. ½Ì€†a¦¼20OfPJ®í¡æš(Ô*0h­šUÔj5ð^Âxe~~þ"cªüS­Vße ¡$ ۶Ž¢(âºR©ˆ{Ó²a’Ö«‚0Û¤PÙ(7¥¢ Ïç#TiÁê¡"Ân5–6±}²!*”ߎ¶Ž˜÷"ª–§¯a+Uø4²GDžˆ[ýä‚nmmíËf³ K5ÁhK^ÅPt‡--$š-ôžÏÓµ‰¢uаbb<4ÅÓ H¹FB(<³m~y]õëÊ# M© ˜;ý—Õþð~¢º´Y† Ž-ªäaßû™Xj¨ÎY+‹{ÆïH`cݵ§äº.Y.ë¼µµ%ôdm»Ëqlè0tUÃO/†Iä6(V9e¨™.$OBØ‹àœo½ÁV”Ôß7¤ ‡ÃØßßéîíí I^‹¾õü2ŽÊ9(¤¡G4~ò~ÀÙQÀ§VÉÇydKˆäû!K´G‚D¢TÔÇso7¤0˜1Ù¥ ÌA&z&ÐßÀ޾»f ‰ ·]YC›J” ‚q\p_YÚ6ŠÅâÁ;—¾º-€MÓ< Ó•d›±;âñ8è8ƒŽ5[QØ}ÊÃV=œDò°/‡Hø”öJ 6€`0Èï4}L†é –ì^I€%I§Óèééÿ}“  3ñk6¶å°q ¸ØLr¸ Lž-qá¨O)˜åà™)¥'X»®ƒpK }Ôa¶î‘D ÎRÃèííRÔ‹^jÓ©9改ÙpúÃÃÃBŠr¹,¤`m‰‰XÇÂO£è}‡µ'p>v…r¹B¡“|Ðìn7nÜØêêêgPfÆZ%“IôSëî]ì/,@&6Z‰¯¾jõÙ¸öѾàÔTY¾)SË›¥ƒñ)ëÈ<::Âîî.ëëH\¹…zƒB®Qê 1Wî¹ÜVÉ÷%zǦý¡[·^mþ733s€“Ô7„f\¸«WñX*/“FRø̸oÓá&Fõ)R÷)ãX_â››"°ËË˳gÚÚÚž¥/…ÄædqéFր̓œ"Ñä{—@¹Ÿ¹Tl‡ KMËORD¸wg2ú?>M©T*J…{ƒšþµ¾;wâÆÒ’ÄV 3ºÒf•hjui„Ö¼š¦«éú‡Òÿù˜Ò2D6Œ×´CËoú˜þ <<‹ùñžIEND®B`‚eric-6.0.8/eric/icons/default/translate.png0000644000175000017500000000234112342633755017721 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsMœÞöœWƒIDATÁÏkÜeÀñ÷ó|Ÿïw~tf2ÉÔLœcúcµJ[A*k).‚‡^Ïg3àHWÐúz)vEƒÍ×Pê w°Ö’e1c"‚-293Ó9r–»ÐÑ`ó5Nr‡ím./]æ»ù‹t{=î$"Ïoܸøgî ԙnw‡n¿Oš¦Œ¬o¬³²²B·? Š#îiµÀÙ‚V«y²Q«Ý^ç7v-./óÝü<7o22CFÖ76(—J  8õä<|äîÆð ½^­5­Ö#QC´çÑœhð{vu:ò¢ V¯sáÂ<­½-þpø%ßã›KW¹Y”ÑíC• K•Y®wg|î3ù{œÅt íL³™8œ%î?;/”?0ÖZîm·iÔëL4›,--S«Õèìë0UßÃJR!ÔûàÀ °$G”È?4  ”B h "úÉ·³m“e1#ƃ}í½ϵ¯‘Ä13í6rß õƒôù½ä4ާ ?QJaŒá‘cG™_¸ÄÚÚ nßÞÆŸ|ר2P÷2›`caðU·Ì A¡”òßðç,Yž¡8k £ˆ0Šðc‡. c†œ{ýˆGëAQa5ö¸ àl+rŒˆàœ£Ÿ\ߊ¹¶¾Eœ¦Ôj5´Öôµ!ÉA9XN™+Gtüë,Êp¸êóÅv€\‘“'Œ-2qʹ«ð¯/k¼zô'g÷cmA½9ÉG²EkÉŠœ‘V-¥S*éGÓ’q¼bñT D1¦Ùõá’Ï›ó>W»o-ßÃ{çfÙ?3Mêleš®5"L™”*1KÝ‚KIWfÒÌU-%aó„ýá¢â݈/׬(ίUøxm‚ÿ&(>‰húV“ŠGÓ&MŽØŒv,óa¢Lͳؠdd…c%Ñ,öÓðaºí’p¨š±(ºC‹a$"~€ÒIC¤HO)8Å®|mLÁž™ý”5¬…Âç[ðéf‰‘é²ãø„åôL΃՘¥ŠÇ÷ c6CÂ@ È ‹Û¼~‹ Qt¶Å÷½€s[ i–MxªÙc.fË`ð9öâZ÷”âŒ( Jƒ-Q2vf‚Å,àëA…Õ¼B*‚ÂæaœðCOñÙ-Ÿoº†í\£{éüq¥å/Œy›dxZà“ê\«RÝß:iEÀ”À3ü,O‘Hñɽ™ >¡‘½( "ó…^ ›Ã6`c+ÝÖ®-moï½ç!ña/3ã÷»wïN644¼kYV ã(¥rÅbñPww÷©ŽŽÅC’---/,]ºôm˲⌣”²Óé´B\íèèâ!I%£kÏ\·cF˜•°ˆÕ†ù§op]Âr«<’L&›€!’¹öÅW·ÿQX¸XF¦`HŸ\n„l®@Åä³FV­Z|ŸìêêºÍ$IC´ÖxÁ¥€bAL³|á@€nž!;ttô”Öúööö[L‚lˆ ±nZ•ZY è…b®ˆeºÄ¢a£X*‡´ áñÕ«W¯moo?À$ȼmÐS¬aQƒA“М¼'¯%ºÃlËd “CË8®ëXz,»|Ïž=éR©”³mûâþýûm& } ­†q¢I Ó¥¨ jätʵAr^šùÍ)B å¹a“ú— ÃØX©T.\¸° èbRÖPò%N Ès­¡@š°,SãUb€WÆhô}¿1 Ι9sæV ‹ HÓÂ2=¤® µÇ_ƒ‚9 &q{€ëN„´]Ç÷ϯœG._ ¤Š¬©üÀ\þ‡N¾n ÷JhDã…ŠõÃ¥¹‰Æd³™JHz¯’•s™:}û>ÝE*•bËÖí˜B€XðRgw6„@B”ïsð미Óß_–™[·7§Š?`CØoò}ñÖXÕˆ–cQ’õ9jÝ,‰ˆÁÙÑaZ[[i™ßŠãú< ª@å»CøÊ"¾} Séëí ˶¶¶ËüçÈ‘# …®4Á7  7s¥Žã÷*UÐJ×>æ÷î_©ÿþ&)!©T*¸Žƒdß÷½æÚBÅ*\ Uý²1˜5ƒÕp“±,Cš­Áv<2¹2¾rPéÜ?yœoϰó͹hÇuñ<É8gæ·ä>U øÙnuÁ+YaÎÊËF”RxžGÙvq•G¨xŠôÕžÈóÚFgæbËžÀëéA)…dœ½{÷^®pßáÇ—«²Ü fy€R ×s)Ù ÙÇðÍoøèËa¶=[ÁJ¬¡&¹+Ãõ<”RH&`ñ‹Ðwñó&J)úoöñYÛël[oðá¾ë<½d˜»ÙŽžK35ñ9BPJ!™Àµk×Fcuù_¦Ö \ƒRjG¬ÆfÓ3ÓøäÀ%æ5åiœäDÏ"/žO¾P ?6†”åy&éÉËôέMœîÎ’Íô±î±*?þ¹„÷Þo#sì§cœ8~œh$B¹\Æ`’Ö?5‹ÎKw¹u{M«îñÅÏulÞò¾ï344„]© ¥‰RZk$“´rår×X³ô>>???@@@DDDGGGIIIOOOUUU^^^___aabccciijrrr}}}………ˆˆˆŠŠŠ‘‘‘“““”””•••™™™›››žžž   ¡¡¡¤¤¤¨¨¨«««¬¬²®®®¯¯¯°°°²²´²²¸³³³µµµ¶¶¶··½¹¹¹ºº¿»»»¼¼Á¿¿¿¿¿ÄÁÁÁÂÂÇÃÃÃÃÃÈÄÄÅÄÄÈÆÆÊÇÇÇÊÊÊËËÏÌÌÐÍÍÍÐÐÔÑÑÔÒÒÖÔÔØÕÕÙ××ÚÙÙÙÙÙÜÛÛÞÜÜÜÝÝÝÝÝàßßßßßáàààââäããåääæååçæææææèèèêéééêêëêêìëëíîîîîîïððñððòññóòòóôôôôôõõõööö÷÷÷øøøøøøùùùùúúúûûûûûüýýýþþþÿÿÿê!ð.tRNS !$5ævª½ºÝçœRJµ~8:9\µÜŽí®ìÍrêR¢î§ßƒðô׳~èr¤hõåµ×ÈPï\†Ü¥­>üÞÞŸõ]o~@H]Ê‹H]JQëTÛºÔ:ý}½ ‚Ø+IEND®B`‚eric-6.0.8/eric/icons/default/syntaxError22.png0000644000175000017500000000231112342633755020425 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<…PLTEÿÿÿ222  ]%%C6  CQCA  +++ˆ11RRRd  … 2 '''†²N - """(((Â$&† .¾((ž ¡A*I'P HSG= 2(KH5M É }()7/;/¸¾¬XÌÂIThâÌ lQmc!  ! #&)))).../12%444;@++JN32SS44VXX33\_`aaX hnnqrsf>z}g;}}}€!!……34ˆ‰‰‰‰Ž“““šŸŸ ¢¦©©''ª««­­./±¶¸¹ºÀÁ&&Â55ÄÄÆÇÇ ÍÍÍO&Î??ÒÕ!"Õ`&Ö21×ÜÜ;;Þàââ[Vã%%æ;<éêíîñõ "öMOöÂÃúFF¯5w¿ntRNS &),-07789?ABDEFHHKMOQXX[\bdeijkklnovzz€…ˆŒŽ‘“–™›£¤¦¦««°³´¶¶¹¹»ÁÄÇÚÚÜßßããêíøúúûüüþþ»h¬uYSVaÄPÞ 6aƒÔì¢ü¬dCNa¡˜þŠyå ‘ì(ÂÁ¹e3J r|Q„Åc3Ož>uÿ…Œ~¸0“ŒOÒÉó›j×_:ç)æ°Õ4kžuñjWëË fë›;°…™ø]k]¼räôµËËÚm…™`f{¬Ø0iÝ¡³3ç[ì‚d¥×Áî’º=«‹ŠžqG¶Ú6¿°m×–¼ÂµÇÂLŽ«6ï<ºãÄÊ5{·[ „y¬Sª–nݸo÷òêøp¸°œ¥}eӜɖ´Ôù±Ã…uíØ¢;§õuLé`ñ… 3(9 2r„¥OìI ä`’t’€3)ƒbŒYÁÛMÄ`WDŽ[TÌ^CÉ*ofIEND®B`‚eric-6.0.8/eric/icons/default/2uparrow.png0000644000175000017500000000227412342633753017510 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î< PLTEÿÿÿÿn€PC@p{€INj\LNSoj€ŽNNXhDFHIKMOPR^T€UVWXY‘NPZAzAOc7§& ’ ^X Z W Z/o/ Z › ~ ™‘›œc'i' u •mX¤ È ‚ ¦ °j;u;;{;C†CKKO’OX¢XYšY}º}ºetxƒ†‡ˆŠ‘’“–˜™›œž¡£¥¦§¨©ª«¬°²³´¹»½¾ÂÈÉËD~ÒV† f s P e ’••Ÿ‡”–Ÿ™Ÿ…¢ £ ²#"‘##—##¢#%j&%x%&''œ'(Ÿ(* *,’,,™,-‰-.‰..¡.0‚01 12’23z34ž45˜57u77š799;–;=¡=?’?@¢@AABŒBC£CD—DF¢FGœGIII IK¡KL‹LMMN¤NOŠOO›OQ›QR§RS˜SU˜UU¨UVžVX¨XZ¤Z[˜[\¨\_§_b—bd®de¢eg°gh¨hj™jj±jp›pp²pv¹vy°yy»y}±}ˆÆˆøäiZtRNS%((55SX^bdfn…Œ”—𵏏¸¸¸¹¹º»»¼¼½¾¿¿ÀÀÀÀÁÂÃÌÚßàâããååæéîîïóôõöö÷÷ûüýþþþþþþþþþþþþþþþþ2eÛ¥(IDATÓc` 0©1c–\Ø)…)*°©©K]”Ç5x}«—;/ª(»eÈ®5íQž(ֆ߾²#:Æ×ÙZ‰Co]ޛا† ºuáÀæ É陓Ea¢Ün7Îîݰ45;¿¤ØÛƒ"Êfy÷êéÝkdUVW—û9q…õîÝ¿}ùÄŽÕsrÊjkK'˜‚… l¬lÙ¶lVnE]Ë\g;{c¨á¬æa·,™‘SVSïãÈ ³’Q7üܾó§g”WUù›±@…Å^;³gÝì))YyE…9Su ¢w®œÜ¹jæÄ¸¤´Œô”„x1°°ÅÍë—Ο:¶q[wOoÿ¤ió\ÀÂüÒ2²rò ŠJʪêšZÚúÂ¤Æ ŒohÈk;IEND®B`‚eric-6.0.8/eric/icons/default/spellchecking48.png0000644000175000017500000000510312342633755020712 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYsÃÃpMBtIME× ¬‰ÍÝbKGDÿÿÿ ½§“ ÃIDAThÞí™ P“WdzµŠ.)!’ˆb,òá!*‚¼‚¼QA” ‹<„ <ÊÃ'h[¢ Z[mwº­Z×UTÞ VÐ]«c»µµ­n»Ón·ÛÎÎtÝ~ÿ=7NT´V¤ÕïÌoîýÎùŸ“s¾›„K>ïÉx2žŒ'ã±S§N•Ÿ ‰D2Q*•Ú¶æææZqVVV–t„Èd²»é0ß=DÀíz}òýޏNM²}@$jhLŸ>½œ€àh}è:½ztqèzÝ1­þ‰£DñWQ5ª°±±¹nmmý_â;Zã:̘1ã?ň‰„Æ7sæÌ§ ô[™|ás{>²™Gt>XñöööV¶¶¶ š‰Clmggáààp‡–ìÌ7bƒd¿Èb©]Þñº\,·r¤jî–ù†££ã&Tp±„­‰#wÑ2Ý- 8;;ë}ëüs »ÎaZš¯é·‹««ë'...?ÅÖdñ.Ëårjuñ2²½ÆìÔÌ? ì‡ÉƵcV¼»»û³nnn :õ6Z÷1ùbˆÛõ »Ë1?ÍÐÅj æ®RÑ6ú!í=š›<==+<<<@s"½8Ïç3[&³M#è™c³——‹ƒÎÆè µ·öCÖ0ÍKÇl¼½½?#0‚#ÙgÏž}‡®'Ïš5+…øšùH®Ó^$Ó§Ï™3çá>oÞ<†­ˆæÎ ݺ5ÇÖ¤‰eZƒ8f©ai¥‹ý†Ùh}Lw]­×xxMøúú>OpóçÏÇH0qÂ0ÆÏÏŒ{ä¼I0ÍDj´5K×jT§UiM7õ7^mœÉSŒ¢€€€/üýýïZ ó‘æ`` ·kƒ‚‚˜^ÄôúšúëÀ€@Í6òwó3<ßðÄ•/®pÓöN»ÉÛÁ“êãï{„„„ð”J¥}pp0ˆ¦»é˜iH»ŒÅ°Aksûgà)²Í¥">"8Z_1ȱ/8(!!7e•²òñuãÑx¥‘憡<¬äxu¼ï|#}_Ñ×uß#,,¬*44 ,ˆ§©xù☆h7ˆcלÎ]Ћÿ8S“¶ìŽêó†…]ð^á £F#l¿¸kýW+š¾j™oÏÀç ŽWŃoŒoùÏzûDEEýù“Ÿ(¦!-bccŸÖÅÁæ×q=""¢ægn¿“Vû¬ ¨Wƒš·k°{h7ø•|ð6òÞeq1‡bFW¼l»lË̺™8õA+âÄÂy—󰿀·ýþÏ2òFùûöÈlJç.Öâzï??H TbÛ™Jlí¯@eov ÖC\!âž*êš&pÃ(ïü”ª)%–•”¼›ûK±sèExíò€ÛN·AÍéòן̡¨Wx:×¹båÑd®vh+¶œ)£\Äérlê)ÃÆî2¬ï(EÃ@dÛ¦qJ'|4©xÒoÆ•]ñ’ ‹|ñFÖ·«QÞ«Æz¢¼Oíç·À{‡5Š>ÍNTÜ}'ÜkÜ]åUr¤ÿq9÷¹ XºH›§[².5J)÷ÚSh8[ §*;nÒºß~:®dÜ8£2£ÑïTã”2eóTŸÈâŠÚU(êP¡¸+ëºs°¶7Uƒ¥˜]å÷mîš#·Ë†;›ðxÞÃA^ᆴK¹-EX×«ÒÆwæ€åTŸÊAAk6êϾˆYµn¿˜ÿù„uFŒKŒGÿ¡Uë}£¨)ËkÎÀš–4äLC~[ :Ò¡îJGaO¶ äÁ»ÂŠî­š¦Kœ4±ñãyò r[×r9R^_Èm̺‡b:ÓQОŽüSéš|ªæTì<»;æp&jÁ—ÆEÆ“LŠMΡîÙÍϪ¬×[cÕ‘…È>ž„œ–D¨N&"·=k:“ו„Õ=ËQq6 ³ÊÝáZ"?ªy¿¯Vð\׺NwR»rÉû#¸ÒAj¾;I³º# ¹m”çÄsÈjNÀÎ Dí ä„ù¯Å¾°Høp×"µ¸Ì²Ð¹Ç¢±òx,2[c‘u2ÙíKÓUwrzc±éL2<ŠäpÌs:èXàhnŸëø¿Ä½JnÝ9*¶‡t]CúUmqšøôæE¨Ü„„—#¸ÉkDßšæ› Ì ÍÆæŸI¤bjáä·D!µ9é'£Ñ…¬Î(¬êŽFvo4²NGbÙ¥«œ`³Ò þ\ñy*ºü=ÑÈ즘ŽH¤ž Cbs0ê‡7aåï—p¢\ñDyb3ó|ó±ýùÐbµeõôÂiP·E ùD0RÛ”HëT"½'½D¿RCi4–ïôCþP8Òú‘Ú€¬¾0Tç¢îB }}fcsO*RöEpâlÉ÷"•È\’+Ûâ§çiX’æHf¬‘am7ÝÅv_¬èšŒ¾`ä †C=‡Ò‹Ï¡äB6^Z†’¡x[„üþ¬ìðEÐA1ä/óàóªÕ»q’LË›’l ©T%ýe~À5ÏÔn±e†ô{Õ ¨;ý~Ô ‘ÍSÞbeë3ðo€#b"‚N#¨ÅÇø˜„?™â¹=žœ$EÊI3¤2Y®Œ÷‹‹4 í¼Bú‡¬ÈívAÒn‚°.„÷ Ñ'@dŸvï ´Kå)D¶›"åoN¼Ü–)–6Ö¹Ö¿ÎOéIÚ&$Ë-;gØBý¶ ôñuÖÑçL±ð¼–˜·ézšé`Ñ€«^ŸË™-±€E’ÄáW Y®ýЙÇYwMµEée7D]0Á⿘"ö!ât,þ³ñ—&£àÐÍ8?þ—Ý$½]Þ™­lý•»íà­Ä¾D.¶+¶$sÙÆ¦”—:ÿî+ï>z)si>ÿèB±ƒ/»Ww²wãÞ–b©¸—ÿeouvt~¼kç.%’[Å[šÝ´¹Æ=²sã·ÚÓíoA0‹âßt¡ˆðùSkŸzqýcëE¥^AW5Ö±ÑV¯õ\÷ÝqÏõÈçÑBƒdÅLÏÑæâÙ¶iÛCÉt’üDík|ë“^”nY½bµÕhQ˜*`ª† AÌ¢¸Û3ln7ÞòØ––PSˆüD# ±†ŽUŒé1¡ëS3˜iC<É,Š;öðöüXò£GW>¢êN]¦ Ç ¥Æƒ±íkŒoÐZcêS3DÂÌ¢èB‘_.ˆ§ö,]ÐA¥VÚjLÀ`”A;ã4c Ú×ß`|ƒ1†¤“‰`¥Òã‘û×EÝ(¥‰Zk|×ÇJ‹–­4ZhŒ0aÐh¬c±ÂâKŸþÒB€ån …ükxÉÒ2&‘͵Ï@ðp HÀÂDu‚](–‰Ã}v²XÁDŒ  h¢pjóÒ©Ôa$“¥7s…ƒ…7šºÆñ5°¢}9SµªÉŽäM&3:z;[|áå—ºOîxU¾n ªOVj¨*iš`pû¿Ÿ>NcÐåÉM[›äè­£¼Ýÿ=ëN2pö" Aº6?m ¥²36V9yæÜíwœ±=µNý[0ÜÑl ÖUA^_úÞ½ âÉ6"±&®fK4MD©×X¿d­­ â‰Mñ˜¸z3k+¹ÜÂÌðpR0Ó›¤ƒ1ï‡H³wÎÍrý‰>Ú3ƒ))Çè;ÛÇH"Å_n”ç^DÚk¤V×dˆz¯ÙÑôqµ·ÅLŸ2XÝ?±²FõkjÎV¿\¹#ߌÇñTË+9Ú|œJ8D=?ÊÍó]¤fyH±¸s=ã7GŒà¿R^?0r°=ÑÂßå§ãÇ×b¶ÃY±¦öÖ¾N*æ«o¿áçžc68eàɳb­»I æ04<ªSó[B©ÌÄ”FWëV‡¬8ÑsÊ>ÞÙ):î[H¡TfrÚØút âä/§µb.[÷!Ÿ½Í…‹â†<ô´ÁõƒZ:ŽÈb.kÏ?'B!ÏÚº¥Á8(þëÜð=v^r¾ïã4+¦2×±F˜Ñ’•²a‰¶UÖŸ€j |cÅ´±¶A >;{¬?|­@++Bv¥Cy¥C³FuG|¬Iz¢M_~N32N†³Oƒ±S44X33\aX aŠ£c†›dlehYynrXisf>zh†}g;}lŠ}}}……%-…34†¦Áˆ‰‰‰‰ šŒVi‘Vd“““Ÿ ¦­./±¸¼¼‹À**Â\?ÍO&Î??Ð;ÑlMÒÕ`&Ö21ÜÜ?=ÝЀààÎrââ[Vã%%éêíîññÜuòÚoõ "öMOöÂÃùÐFùÖZùÛbúFFúÓOúÕQúÚ`ûÝiüãpþ×KþØLþÜVþÝYþÞ[þâgƒ»)ytRNS &),-778999M-a![Vaþ0‘øôŒÁH6a óìâêÊ¢, a±„yëë«ZãØQ„E¢ÊkWÖT•£K§ž>²|éþ ÑÂpa&ù Ì“çw·´í¼t.5@ *Ìá¦g7aÕÅësf¸ºi™½X˜IˆÑ·yëÅkGÏܾº}¶+£8Ìlÿ»o\¶bɺcÛ|¬ <<·aíÌžîº-gý„÷®n𾍫cá¾ãÖa&Ïͳ¦Nìílßsÿ#BXÀ%wrߤiSœzšËVtJîŸâò•[%…°Ã…Ý*6ní¯üê·ïlÓó] ¾Å j„c c‹xE4B[}õ5AÃÄsõtq23<š¡¶sþΕ£¿<²c³’\â=WÎ }¢¶U!J-ð™Ó¡¢/o“P*ƒWµä ‚]Ì?])M‡<ÇnhEeé7b;dbñn¶IŒìÛ®8»jøâGF-+w'¯n;²Å†˜Äse×øc¸L–ïô÷FuÎþbŒ­©x<ÎɲÁ¿V—¸<Ôøî kúhÆô5½ù'ÆøãºC?§cïYìÔí…šHò*Æø¤ ­~¿ß÷0ç_9N¥R´Z­f[;º®á†cË@yYÍ‘òÌ—¾º]ß’@OÉÐ%0V”5g¾ ”~í8NJ×usC+b‰ß³ê½Àü—Z±D[)’À5dÕ Ða©;öò<4p ²Õ09¿_m¾&üüÍ…»/Úk½ßÇ@òQ:»_'­w}R#u1G ÒX2 œ`¢ô0ÇÕFøxâU˜ŸH8<€Gƒ]cNW9ÀÛá>/ØÄ3µÊ@ªE•Ñj;“v‚G0·È-„<·üŒçd ”"qÃb-^7¦¨=šåvœ‰Òp„#¥ŒK'nZ`d D> ‡é)‹oU<;«Ó•©&ò6À[kÉOrpp4MS0Æ/ùNæÕã÷ýx‰Û/`ŒÏ@¯Ç`_™¡ø¥0~Èq\BQ”­mmmÜút­é8™L‚\{HLŸ•ê£Ô./Ââ],†¯0ÿá8„ 0 Ö©ªxYÓbfKK 9}ú4Ýô¯p„º»ÅH!Ci%WâÃ/ëGwóÞbzœìrOOûê7èco«lŠ®C{½â”ÈVdzPš˜§^”cÄîæôi`æÄ8+§sAÿL-¨Mˆ53ÏqÀŽÚ-‚dRÌ÷oï.2Œøô×8€¨ÇÍ‹ìOƒ‘¦»³—2AÑŒw®^ƒ êî£ãéÞ¶LˆËg§—¥¦H¬­­,æq~¿—e8Œª;í1šœ\Çüoºr=ñ$Q]×ÕùyÕkšÿrõ—~DCóHIEND®B`‚eric-6.0.8/eric/icons/default/wikipedia.png0000644000175000017500000000041412342633755017671 0ustar piotrpiotr‰PNG  IHDRójœ 3PLTE(((<:¬bmàªc¦ï«æmÔµ&|ðrÏäÓ×..¬¨)èÛ¿w'L8ÀbJ›Cpéœ s“Kí‚ ¿V]wìrsÑÆ£‡VlÚº®Ú©»UÛ6:;3·~ú²Ù“`Â{.TU^¹tby{y~RjZÜJŸ¦c w=U-¥¨H·¥üPÕ׊ O]ÍK 5Ò4´Tfû›7ÖZ)†„Û];saŸŒ+Dxב¬ÌKË•Ïoí”ec€ /êÈÉX?#ÑOîøÄqv˜ð¼ôâ™k&ÆyÊ—–àb€ ¯Û¾m˪ÎXùÍ¢œ á•«W¯žßfã,Â…GÚªx!v„(/p3#Æ·°Öð»ôOIEND®B`‚eric-6.0.8/eric/icons/default/bookmarkToggle.png0000644000175000017500000000237212342633754020676 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ9%yKÊttEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“^IDAT8Ë­”[ˆÔUÇ?ç™ëÎÌÎì¬Z»ºËš¨k+•Z.%ÑjŠØ£³z°’Å ƒ¬èA !ìÉ*C‚ˆ¬¡òA ¡í¡Üh7K‡rÝ\÷2{q.;ÿ™ûüo=̘)K.Ñ~œs8ü>ç{~¿s~°@›|fs&zàÿ§Å"tÇûîÕ¯ž¹ÓNÿúüá…Ĉ@=BöFƒwìïP<ËÈÅO•$÷íëBw½ñßâ¤þŽ{IO‡{ñÃ8ü«p¸[ÝXæ±[I·P»Qñ´ï ´íFØY0³x[¶cÇ6d.¼ÔûŸÀ±n¡øŽû;ž²ê«”‘$Ïm[0Š“¯i¿íkºeŽcÐ<ˆ7)ž¶<-;‚¾–„>SÓ`› §°•0¹Ä ¦iL áì·­âÉÂØÇŸ/}‚ÊßàX„ÕåmÕ·z“âi8‚]¨þ(®&d˜»V ­*¶s%º!¨æ.£ç“XV¾bWƒ–1wÚª¤ÞÎû:ö¬mhíA–-„]3f¶ÁK«P—"ÀµËJ^p­ÄV—bYË(‘ý„Lòò9EË©§Ü…©µ Q‰‚mr €«¶R}¨ïÉ €B¿„Œ@r,Gv5“Mœ—ïYþ±ÉñgÓéoqÛÖUP[Q©­¯¹d‚0A ÚX› äfJ©ß?w,>•b§øæÝÀò5íÖÙæ•-ò/is´¦Q+šl©þˆ$bZ+‡O?DÉpàuؼØýö•#å‘©üÖmûs}ÀŽW²#3Iswväk£œ’Àˆ8ˆ4ˆ<ÈeK (¤æªH²ÂºÎ0ë:à †>³Çgò½ÛöçúnxÇÝ{‹ß¦3¥ƒsãfHs fALã`_f@LcÛ)´tšxC¢T8œZ[/7ª•ÎþÁóãÊMà ¤œÙìŸf Ýt‘Ÿ£*¿Œo%ØìÄåR1-A±`‘JìøÔÄ÷qh¾^D(ÈÞü J‘ LKGuèôî:OØÑÓå% 5Ñ RLdž‹³£/Ï ~š™ÜÉ©‚lc£ŸTIô[LWe¦¯Œ7Ueïö³ØÙAÂMA5‡¨¦¢$G^ÏŽõ_¸º9!«’ PI›§ŠhZÅLçì´¼û«—¾$8[}jE³Ü~ø ƲQ.º”ãlß•8óô×A7€Ëº• ÉŸ*$5kH+È‘tÞu|÷›³—¡À[/,;صlîñ5!íÙÑØGd3sÒ“ëG®ê†”›¯mÊ€pÜãëÎ䑎žÈ À]=õÔéÔN)õlp…¶Ý§®/—Í¡WÏ  èðÒåžù*ÿÅIEND®B`‚eric-6.0.8/eric/icons/default/exit.png0000644000175000017500000000220712342633754016675 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs¼ÏtIME×  Ò¡abKGDÿÿÿ ½§“IDAT8˵”]hUÇÿw¾vg“ ©Ð”DJÚ”t &1B¤T$m>ÄX¨il… EQâ"‚R¬ˆ5>åAJéSŸêc¥¡ U$ŠZk“˜Õ¬Yv›(Bö;»3;wf<÷îNŒññ㙽{ï=¿óŸsÎ\à?¾ï ÛCÖ¬1ñÈ\¼¸ß]\<—Ÿ›àÙ¬âuû;óÛòw ·‘LNibÓM®ÎêGVûú ¸î_«û“uWÓPò¼®.½KÇ$8qáÂ`´exµú¯RbG£X[M‹¹g—ãšžÉÔ^‹1¤›š(I { 0ÏûcåŠR;Gco>FyfªŠ²e[`ñòÎæ&ŠÅpøÈâ2|vù2š `'œ …ŽÜ72" ÷õ•+ÇãP A"ñàu0'‹öIªB΂oó™×ú$ÑdŸ6­/By猙 ´dV¤K»óø£h|î4tò¡øtþwŠ™œ­/½þ“KGޤ¾?sÅB£nKøîÂá0 úÒºO<†Û_>#}URýÅ\_hï8 UJûþ+d_=æXâêÙã6ìÓ(½ˆµ˜8×ÖÞ^ƒIN]1åŒùº"Á}ó“ã(~~ ÖO‘|v”zÔB•*^¦ê—*tƒÑèX6~œ_˜ÇæŸàË'Æ¥/SYÀ•ífîŠuzÙÒ‚ªTjïp}êµ4Õ€]ʼڅU¥3UßÃòӣشÄH j¤ž›ãØæ,z­¹»ë~{õhB 6rÈ,ª¸K¦)5%"'¯*­qÚ÷)¸!uF™"ƒÃ½9 ¦Vrßlm°J¥÷Ɇ(5Ú?¹äU-Ã)æœÏù)üŸã–°ÍÜЃ*IEND®B`‚eric-6.0.8/eric/icons/default/download.png0000644000175000017500000000175012342633754017535 0ustar piotrpiotr‰PNG  IHDRójœ pHYs „ „ªâcytIME× ’N "PLTE2")P=uC~I‰ M!P— <&48k7.M : ?*#1_3a$,(,T $F3RVqš¡°Æ-$‡¢Êˆ£Ê0  "CVn’ 6%6d}9j #@0 ;=vEc‘8k9m?\ˆ#Tž)Y 2`¤#:(?B|FƒJŠ M;e£ =e/\4_9l=v>u0MD>lJˆ $;?$<@$C%>D$?D$@G%AG%AH%CJ&DK&DL&EM&GO&IR&JT'KU'KV'LV'MV'NX'NX(OY(P\(R_(Yh*[i*]l+]m+^m*^m+_p+`q+aq+ar+bt,dv,dw,fx,fy,h{-i|,i|-i}-k-k€-l€.nƒ.o….p†.r‰.u/{”0{”1ž2‚ž1…¢2†£2†£3†¤3‡¥3Š©3‹ª3‹«4¬3­4Ž­4’³5’´5’µ5“´5“¶5”¶5”·5”¸6•·5—»6˜»5˜»6˜¼6˜¼7™½6š¾7›À7œÀ7œÁ7Â7Ã7žÃ7žÄ7ŸÄ8ŸÅ8 Æ8 Ç8¡Ç8¡È8¢È8¢É8¢Ê8£Ê8£Ê9£Ë8£Ë9¤Ì9¤Í9¥Ì9¥Í8¥Í9¦Î9J¹ÇÙXIDATÓc˜ ¦´õ3`žÖžÒU]\RÛawN† w§x˜ji™û¦öCø`á)en2¬œ,œ\r>USàÂev¼Œ"FÎŽ: B®Õ0á7>ý„ʶ–ò8M6!ÿ~ˆðÔdiF½\ ».¾4SQ1 "ÜåÉ'’0H»K¸”F ñ÷…kÌX +g̨÷feO,Tg´i iq:µÍèôeoo°b4© —js:µÖ¹s²róù65X…g‚„ëÌÙuËãÅÙy™ÄƒrT˜šÁª{|¹…bË\Â¥ØE Ã&@Ü.Ë ‘Q‘ÔÑ"Â̬”õNŸŸ‹jtAC}¶#ƒuã4¨çk\…™ùÔ-ÍUøÙ˜™ÅB;aAU ÈËÍÈÎͯl-.Óž1cbVˆ­±©}D^S$Ht]>^CdDeFjGlGrIoIqJpNr Ns NxOs PtP~QuQv QwRuRv Rx Sy TxT„UyVzVzW{ W|XŒZ~ Z~Z€[ [’\}\^‚_€ _…_†_™ `…a"aƒ$a…a…a†bž cˆd‹dŒdž"e‚0e„,e…*f…-f‹gŠgŒgŒgŽh‡.hˆ(h‹hš1iŒi«!i«"i¬"jˆ-jjkkl‹-lŒ.lŽ m.n‹7n.n’ n“n”o‹=o”o• p‡CpŒ:p:p˜q•q–sTyb¼mÎæ§?÷Ü©2©Œbˆ1¥4ZiÔÔ5 œ£ù ýˆ2û˜š6IEND®B`‚eric-6.0.8/eric/icons/default/vcsRevert.png0000644000175000017500000000252312342633755017711 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ 4uJ†tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“·IDAT8ËTKˆU=õÿ÷g:Ýé„™‰3&šàÈŒAHâb6""˜¸Ä•‹ÙºsáÆ Q\èz: ¸2 d !!ˆIT0Ãäc>ýîêêêú{o%&YHÜîªzï{îyç>ÇùóçÅz½®:޳Ç÷ý7Ã0-Ô²,Ãx<ÎÁ$I¿óE1æ uù †Ãá”è;Jxeeee"¯­­™²,¿mYÖ§¥Ré o É0Ï,9ˆªª9(U’/30}רÒ£(zªùœ¦×ex‡Ê9NqòಠPÞH‰Ÿ0ã8ŸçØY¿Æ!Š90}DÚÌrY Ä‹øŸó3 xž÷”<_$ædüÎß[­Öa^ÇÀ5ÒÆ¤R8ã“Ò9xÓN}‹*Šª p~g½^ÏÌ lŠÄ7;v‚33fRèYÈST´“ÂÈÏf2™X90mP&…ì’109¦iæÚŸe]°äÃd™˜òû$¦/àŒ¼¡ÙlæÀ\Á`ðò8Èè÷ûy¹s²Ç d2¼MÌ4Ö’'x#g7Åгƒ~ Bð´è2”t JÒÆˆ«Ñ¦úuHÁ,c7$EgµBŠ>1Q¹£t]ÏåàÇý’ô й½i(£i]B}¦»V‡fÎ’"" ·uÕ»°Ù]DÇ?†0VsÏYÙ P…O˜¥àÃaTÜÄì¾eØß!J&¦šËÍ áÉúHÅ(¡:]‡Sm£|ë*®oÞÅé=­ÐX¥˜13&ûAÐ#Jb ¶û Ð,ÙAB䈇‘P#±ë$³¹T¥ç:vMÅBü+ü­ ëÜW0¹óztp*1­±Î€5H™~ %ŽÙ3tÚX6–Ï“¦ 2N]¡Œf(Xg«·ŸvWR´TÇ+~S¾‘¥s¯2ÜWD*I'¬Õ·YZmÒL²ø…! Å÷—[ä²Z=…kRGhiÜÀƒŠ]§žö±ÖìÑ¿7 ÆÒ¼ð*ë6§g—I(0:^å¦[îáæ£ãd³¹+3è´[œxüþöÖ:ùR…ÿÌ/þJ£%Âälåö^Â@2;·FßÁÃLÞ{˜;‚`§lÇAçy8®Ëvdit4ÕÁ~­”‡¿÷Ã#£œ=ûÏBåH%±X  ÿ†I¢(Âx§¹fiàüB‡ë‡³lõ ÞU€EK¥˜ab0$ŸË™€'ÿ1wÞu”ßýæ×5a•vdšb­ÅZ‹n5pýñr̹wNCa„Ù‰çgÜrûOêC½c¸¸®¨øì˜ÀaŽ WëììàΔ[› <4pY?ÇX%Ãx% ”÷ÙèZfWRÞ[Iñ„Ï-Ep=[¿ðe<áãº.Bkå¦R"°X ——> ±ÙdØOíUzJЊ*…€÷fitwÚ±º)YÝJ)„‚ѽ>ÕëÑß?@±XÄ‚#´ÖHùÿVä=çÄ(e¨”|BWdg—bÚ–ÑJžƒ96»šµ­˜ínJ§K%††ÙÜl8B)å¤Rb-X,ÖQX¥ÑnJ¥²^[äs#U.l(ý2wã&ʘc•ÌŽwhËJ3¡¶•0¿°¤êfÇó\÷c~ü‹G¿8fÃÇZºâäÚ„¾àõ÷6øÉ3/óÂì6×öe±€µ†¾‚Ç`Ù'N‹ í(B.ÏØý¹yç¹?={îSþçL>½§}ØÏøbîr‡ïüô/\hxÊ£e¹Þ#‘c ¹ŒËð›´øã~›Fõ×3>sx×Äq~öíÛN8®ÿ­Ã÷=åµr×Ñèh&«%úò.Âcv,¶ÝnË3gÎÔŽ?>?sjºÚÜê_Y³Oò#ðŸ˜úa½ŶÝK­RÒÖjµdzzzáØ±c3GŽù¥ã8wc€àÃã*Ï=ÿâ³­ˆÛß|ã¹S¯¼òVš¦sÀn)Bz2Cl*K{:@« D°Fm+I¼Jq*JÀKÀN¯!Q·!Rµ#SÑW»Y›9]±-_´D`›<`¢DaÏb¸Dc´Ee¨Ie«Ne°Sf—9fš=g´SgµSh­Mi¸Sj´-j»KkµIm±bn´bo;oµbp²Yp¸cq²VqÂ/t¾Ww·_wÆSx¸qxÐ0z¨>z»rz¾e~ÆN€ÁtÄZƒ¼UƒÀ„½V…‚†ÂhˆÀ_ŠÃeŠÃrŠÇƒ‹ÄuŒÁhŒß:ÃkÆW‘Í‘’Ás’Âq’Äs“Âv”Åp•Б—È~™É|žÏ†¡Ï†¤à¢®Ú–ÌË^×8tRNS $';EKS]cnx‡•š ¢­¶¿ÁÆËÕÖÜßßáäçéíîîö÷úûûüýþþþþ}âàY¶IDATÓc` àPÑáÂe×ljÕåDeÓhhiiÖ†òÄD 4«zM}ee£„'“( ¢YÔÊ‹órj ¸Á¢²¾%EÁ ̪…™iÉUF<Åú¥Ñù>âLÊ鱑կ¼P“¥\âü‚²<´²BëLùàöK»‡»yeT$…yçšó#¹K&ÀÕÞÑÁÒ"ÔDŽrþÎÖv¶ñf‚hþPˆòtJ±ÂðµRj™0f`0*ŠÒ)6C0#ÍIŹ@IEND®B`‚eric-6.0.8/eric/icons/default/sharedEditDisconnected.png0000644000175000017500000000255412342633755022331 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYsaaÁ0UútIMEÚ$ÈSl¤bKGDÿÿÿ ½§“ìIDAT8Ë•[h\EÆ3svÏîf¯ÉæR­Mc[/PÙZlc#*µE|ŠŠH…"¢}¨E|)b•D´¥(^Q¼TÔDT¤Û&±Ö[«±í¶›ë^²›³ç6>œMH­âÀ÷0pæ7ßwþ3ÿü‘ËåÄÀ¶™}W߉ÆnEck~:ñÛMÛ:–eõ¯^½úIñ ê¹§r+»»—ÞOvÝšHu^‹%³a3Âh tƒ}¯.þê¤?88˜u]÷[ãð‹Ï^¹!•긽%™XŸH¦W%SmY3Öj¢ZFàn]Ð.CߌòÎû_ulr§FO:tè€ñë—÷>6ÄæD"º<‘joU‘C« ÈB™ C€²%ؽ C×Á=˱á£ìxú]&¦1Fúûû‡âÔЖÁžeÉ-ch••A«„ ƒ ! lðÎ#ô9ðŠà—ùý:<6B©¡³mŽ#ÃS¯–+sF½^û2 àN㻓h¿†`ô4BºB¨HÀÙs>>ŠeÇYÒQgUÉ=w^ÿó£;¾À˜žšúDÏþñ„öªhíá«Úh)@ „”€6A­§f¶>2Š eI‡ghoÕì}~ ~V¾n¾^ò­ËC¶]v}dUI „h „ ªÕ=¶<<ŒíDê2‘°Å—×!¥ ++®Èår@î;8R›˜m/úF{Ó©!EàPŠ ¾TضÏÖGFªÚì$Ú¯òök…$hMWV,¢ù`z6re‚%ƒøMxàÔÀó%Û3×h¡\©àØ%Þ;x±¨j†×t´é¶xŒÎpuN %ªét*%¨Hƒí;¡0“SṵϻoÜD:\­}´ï’ŽqÛgýØr À2* T!CìÚó'£'jŒO¸tv&ymÏ•,é\t·´ßE»Ë»¬¾ð©¿üÁy·B©æÑ #d˜W^/ðÅÐ$ãS—-M±{G–žîÈ"¦Fkí5ÐNöÄì5 àýoÖ‹•šQÊd^¨0o¾7ÎÛ(N™ôt'ØþP'k®N^ØL´žïÌáÛÚåe¹\.$òù¼?U1Æ„a" ! >ú|’ýoŒQœ4éYf2pš›ûZ.d6ÿ­vçÐv¿Q"“v3@ZÎT™Õ'„¦|Rcמߟ6é]ç¾»;¸ë¶¶zà5ðí~£„o—I§Ýà’p½®¿pM(~½½kIÇg¹¥O°uÓ?¡´ž…רâ[Ó¸µ"* -q?ÜžqzJ[ªx_¼ÿi+ëÖu³íÎ,ß,ÉòøÀÊ‹œ¢}´;‡ß¨â[3xõq¤tPa¨ÌµdÜ]!÷âC{—UkÞæðo#ïpùå3\¿.óïñ] ß®âYÓxµó”KÕúÈXüäù̱Ͽ˾¿àY{í^_.%w?³”DܸإïR.Yµ3gª…³ÕÓg µŸNžÖß>Òú­ãŠsÀl>Ÿ÷:x0.»tÉý+ÔøK/,ïð<í'œ™BÑ)ÎÛ§Î#GG­¡üqï80¦•Ï×Á걋ž´yÇI`ù–{Wö§S‘OÕ=öcùÇR¹~Þ¶íŠçy6à4åö"9‹4?÷þhö>hD0ý1IEND®B`‚eric-6.0.8/eric/icons/default/quickFindPrev.png0000644000175000017500000000135512342633755020502 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<lIDATÁ=hœeàç}¿ïîz¦\sÑØ4C”ˆˆƒH‚B‡"DQL×D§R»9ZA(HÚF1C«§LI µèdRšb{þsIL.wßûù<¡À…Fš2&Œc½\³Wε%€óÓ.õ†ºzzÈå*ò–3ç—B >l¦…4·†G +=ô6úÄÅxö£m%Î5Ë[‘¶Q/zL]ŽÂ¡¶mj¨m…± ÛäÐ[8é8í9ý*rAfÜqC©.˜'”ÞŸ.¾ÛöŠI U¹Ü®(tÚ÷³%MÙkŸ,g;ôýÞñQ§õ;¦¦bÏ—ž¹(Óô‡–ÊK7>‹Ý©Ã!^Ö¯¦*³ç²-ý`W]Ÿ×q8ÔŠ½ÉŽ'Uä2û.»§ ®»"ª¨ésJGo2¦‰#ƒ: Ѿ%ìØÁMŸ{¨TT=áHšˆi¼kX ÛÜvßÿúÉ·Z¶$Q&ó´®4ž' AÀ®{6ÝU·ç/»¯A$1­¿+•|àq™c*^5£j@¥ AZi-jé(š>6jÀ ¼á=â¤PØ¥µ<­F-»úuå]tÆŸà]UQ©ëÀ]QZiEë?×èè*œô©gokêêX²G+­dw:ßlÄÙ-§ Š¢ Ï”G$=~qE]xç«Û¡Ä̽¹Ì¼1}j*2PèêøÕEGòÅ«ó„³ÍòVoäÀ fW• J…×ÜT—o…±¯· %˜i– i®£îIOyFð› ›öÕÄÅpöê6„À›Ó.C…BL&“µœYZ%Þj”S&MǺ5«aåZ€ÿDÏûË–Ñ­xIEND®B`‚eric-6.0.8/eric/icons/default/ericSnap48.png0000644000175000017500000001107212342633754017644 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœßIDAThÞÝY åuþúš{zfggïÕî¢ÕJÚ]I Ä! ,a ,Û%|I‘råp…²TR!eL…$vìrpÅ8Ia‹˜`Ìa1:Ð…$+:V‹´§öг»sß3}çýãjeu€9är*½ÕêcþéþÞ{ßûÞ{#àÿöÆYÖþ=ü.ÑmáuþíÅÇ…îLÐÈ¥|–• d€è V—RŠlé¹p&;%sÈOªªÎ¬¼½güº†¯§~g¼üâkâüì/ýЍ…æÓfK<½6–‰/³ ±ÉéÒêKåXHµ$$—Çç3‹›=BHRD¿ßRK¼>/iž“¹~ÿO¾ñÄÞW9ÖoÝ€Ç])ê:¹©5´h|zz§ë×Â#v’£Å#6ÔÉr0PÓ\/„Õqóyiµ^R›:Ì™Ø •Fˆ[.ׂd|ÒŠL cò¬~ÆéôõçožÛËÞ!þ6xûúÁ§OZ»òºoIjfâr´×÷ÜZ]#‹îæ@WZ‚°·ŠËÐâX9É©¡tbü£‡qÍkð«óFÆS}’®9S£¨-f8W¾@ç»xÓü½7>ýÐ[wmÛª_Uξùƒª—ÚÜwòì禣æ­þYÎûfß~Îm˜+ˆ³h÷ÇVÃUü8¤Z/Æ Ðg,6düêçQxµ›þ’GÚ僋þAf³%x£ $UCÀ²p|N×®yåš-¸:¼}âiçþm»îü7v!Ï'§úÎøW÷ÜË¥c!L¼5‚»ƒð®¬ÁèÀ¼¡¬á“°¸9¤$QÁDRÇì\ m×­GÇ5k eG¡:(i¤d†ŒÌ`"g¡¤ˆu>ùRÕæÓûèúÙ¾Öñâ¿¿ò‡iMyPîXÒhê^nêØ9´”òˆLM S(á¹'¶âS÷ –6@QeðÉCh”΂ö ã–uX³ñNtÕ"«{!jE¨GPŒºNœ„¾1–¡£:¤há:qð·¾­~¤°,‹û×Ç~ÓÞýÇ¿Rw4®¿C’ÜaŒìÛƒddÏÿø ˆV©ô(tÝ€ Bv;àâòXv‡Å­!œÞ׌½3SH_k‘ åÔjœ3&À;3ÈMS^¨q8ç‹<"ŠŽ ÓÄLA0xÕ?Ä­mÀ?}çûüƒw_ο–›WtV7Õq‘ÁÄ0I4_€RP )ÊÅx‹'c5¨Å·nð‰È¡(tz5_T1¸+‡ÞÉ8z÷N µMAƒf!•"Z¥ˆ’ž'V4rà jÙ´ZÛ‚ºEü0žø¯îz°æžëm¿aíâžî&IV ÇqðÏc2ž‡¦š«yè^¥"‡€'„Õw7£ì¶pìd ¾›kQÖp6I ò¸Õî¤Ò)$‘*éH9ühXD>W¢—êÐ4†ªƒã ƒô‚Gø 8Úc_Ôk£ëcŸioZ±›šKaÛó[ï@ff¡®0ÒÙ "q˜Pʩ輾n¿ŽsÇTJäy,½£…ebÞ@!¢ <šF%bælþzŠ—¼íÈû&x®DTÔC M2!XæT[}Í÷ŸÿÀ¼´ãÑ»4Ÿü8×yÓrË»”;°õUô=õZÌ"¶Ü³eµÃrò°U2ÑÐ&£i¹kîª/çqýª Ê‘ÊI¤ˆ'Kè¨RÞŒãíCãP鞯ۋ2—‚#“‚NT“U€fppPk$Yü/½Ë¥gîOkÈ€ûž¸é¥—Ž>Ò76qóÐé!NžB§?Ï}åF|ì³KP[_Æè˜Š†¦k0?>±¡iÜt{ r¢I_hy‚E”¢¿:‡pÈAs ;ZÄüùZn©ƒ00ÕAž®9‚g• HÄv£ZtÎéñËý½'žžíµéü¾ràÀ¹uͩӴzã†.ÍÁÍŒõãÎ/oBUUq£9%¹ý£øÕ‘sØôçŸÀ'oZ†Y2øV sñ4Ö®[B@$ÌÑØáF訓è4ú }‡§‘¢µn£§E[­|(äÉót_ò‘Šê¤˜ºið.ã¥Eíž@ï;‰wùûÀÏw|¸ú¦•w/ù£~· Û~8ƒ3æ8¼óiè£)òLÇvœE($#:8 Þ„ÈÅpóg¡ÿ“´ 5ŸGf^C¸Î‹Ä© ê,bçg©ràC‡bhï1]ȧKˆ ™(àÎ{ZвœÃŽ©ç°¬…&å"‡[qÞ ¨ªay<޽A7÷ííΞ¹ß{ðÌ‹[®Ç|èOÜBB| 2ð`¢0ƒØä, ƒ§‘•ûP*qÔx‘ÌɽàB”1‘.C$0NJØ·+Bò L-<•ý0Íg8Ô84Œ%D½: T7j!œÃ2ƒ2÷‹¶j÷7Ÿx%yôJß5‰ÏýG©W+~9U³lsr"*L: Å“Ähß5‰öv7rs1d#I¼s0BʼnBí(f .€¹Ù<-’¡ à–01œÅL¹„u5¢gƒ#Ç)a‰ JVY…ˤ>S§f¢Ê <¼.Îðû¯µ·ÿá»ÏE½ÎwÀ;zvE<^uoœïš»êqþõÓûá;˜´Z&@î ¢iU!YBÞ˜F†*¯ÇpBö2§`YXÂ8é{B2мԋŽk0o䪣(žHA([ÔÛS¢–y¸yNÑ„[t¯-j%Š¥pï'‚³æ{ßyztè½XrÅü§ù¬˜Žò_Vjƒ›ãüȉ)XRõõ4ÿ˜" éšàòR˜5NSAb<‹°Ã #_ÄÌd##2’ˆÕŸ­ÂÍŸ©ÂüŒˆsƒiHšŠèÙ,JqJNƒ[`Åxò¥ÓmZ†¡Lɲ󟻛oýî·ž91ù›rôЏÛÒþSãwžy_81-Bð…Fѽ.€‘ý*ΟG ÁA.°Ò ²39ô&Jp7;±ô†nè‰(–Ý."ÔÉ¡¿/ƒSG¨ÝȈœÎy¢Im1§ UA ¢`ŸcäžZ¹qÃkñðvíýHüeD¶?Þùâ–Œ ×:K —œ¤^ña6MŒ6ÐsqxUã& fhñ ÔîDëæ:„É0Ýn”c"Ó)Ô&=èßib~@ÅÔ™d¿…œÁ•ƒ@œ—©W U›–[Ò“œêx¦ªV~êÏR+ûêö÷Ý\f€sù#˯)e·Œ¿³OŒ¾3DÍYÕ5e&KøïaRÓáB©Z€^g¢þ¶,é¨F~ž¼¼ƒ¤3_FØã‡Ú‹™ƒ Eˆ©óhi° ×.$0ä >βêüÎSë_þì6ü¬uöâž_^L[“‘Éѯ[þæG8.ô½ðmäãÔ`ùŠI)’9‡ˆÚj‘–:rª¬$X<^TásqÄc n'‡T´¦(ž(bRWgP_Om+$‰‡É «¨[­-ÁƒëºªÿÒãçö|عä¢P l9~ò{ó®#‚’w ¼¸¥‰ó$—J²‰š*挆tŠÊ~ÖšÌS+A´&j«95_œaÒôdUf§À”BdÈa™Ê%®[·ššÜ{×­íúÖ—¾vpÏG™/2 ™Õk–/Z¢ð>¼öÊO‘ŸC¶`@`?ÂD©PQ•”*ÜÄßyÒšÀóäqÊ@›èXõq´µu£³«~¿cC8?Þƒ‡^¥9Á@ϲZÚä7›šj#ðG>êH+þï ò”¸÷õ§‡|` Â+;QV£ÃÈ!MCTq£ ÀË~ oúœäX¦¬E“ uŽkïxMMMöΞµ˜››Ãî]Û”T«»Õ}¬ûÏ7ïÿê¹ þ¢8¡užL¿4ÙÛÛ™ÚƒÖ›>†S¯ïÃTïiä9*3ôÒãÂ-™$ñðûápÐLLª–ÍfiNNQßUÂàà ÿ2 uT7ú‡ä×·ûe6xL– F‹ðR/.¿ò6ï1‘£ö%›#9¥¾E„K CQ” MjjjÞÕ€+d›¦i§ШÍÑ $Jxæx2°SSS•#£‹M?vnÄ®YìÏ#‘HÅ!ösØó/¯eǰÑÔ¬q#%,¯ªŠ`– žyÙbÔ,K€ÉIÜÐiȱÁ‰xëâØƒmjØRgÓbáËØÖÛÛ[Á¥¾¾¾rd€Ïž=[¡` ÀŠ+P]] —ËU¹Ç’šå˪U«.¨Öe|zýççû.¤/ žw8=Iw*˪Îr>Ë›–Î,‘þõ8x‹ Ô)É^s»Üµ ó{0;21àÌ›—&.ó>»Ç¢ÃÀ³uÛ·oÇêÕ«é³ilÝú q?Œ'Ÿ|²ò}¶Ž9bff===ré2˜hœ=Û³ýô鸬ª\‡ßW&'ºŠù§òB>WàMM×ý.—é”Íàt³Ì‚ÓåzEÀVfËvnß_¸1Ž3¥²×1NNNbv6KsðRR›f$3Ô[å/<À¾w%9¾¨êîþÔÜ‹/>öBc£¹4ãÍWš%jj†ªš¹LŒÓJEƒ¼m¹"ㆢ©JYU”(g¿Œí¬øØ |é&Ër…Ûì3F -hÿþ¨«›Å½÷ÞF…êL%—XdÙ‘­arû¾æûîû[6ÆM¾ßr¿fC vØIÈ€±¸Ô[캵µµ’̦õ<ðÖ¬YƒX,FÕ×ûï¿¿f¬MÃîîî+ÊèGþ¥\6…_‡ rÍ@±¢Ã<ÇÀÛ»]Ì:;;±sçÎ ’ÊÖ±ˆÕÖÖbÓ¦M8uêT….,yxæ–›7o¾PÈ®X>ì–ËfM[BYȉDå…ìš³‘íŒ ìåëׯ¯D€yŸ¾PÄØÆ®Ùy&“©¬¹å–[.H°W-ù\Î oJÌìÙýŒ­6•6nK—.­È&£ 3„cRʼϾˮí$nnn®D9‚·+õU3 •NÏуÛ`нŒ½¼ÞK$ÏNjvoãÆm?zôhÅFœÛ´byÁ¸ÏîÙ¹dÀ«f@±X ï´±æËöþžgá~i—ÊÚ VÌX7ÊèÂÀ1²ämkk«ÁÀÚÜ· `ѸjàQæE浆†† Þ·¸…€^3@öÔØØXÙíŽÕ.tì™ »X;¯ª»÷ìù/§Ûý§¤"‚ŒWòö» 7—üÿÛEÒ»P‚ísfE[Ãÿ—íüJžõøafhIEND®B`‚eric-6.0.8/eric/icons/default/preferences-template.png0000644000175000017500000000110612342633755022034 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<ÅIDAT(Ï…ÒOHÓaÇñ÷LW ó Œþ°KCC&­Lè\îäA‚nó"Ô¡èx0;Z—AhÕ1(ŠðP.æˆö‡¢²‚-Ö?(e çØ–òûxøMÝÜOå{y>ßïëçáy+…Ç ÇZ8|ÇñÔäšehj’Ž:Ü15I¿=fgÃ#¸V³+<’å¨=>h$rúVs_.c$8`w..™7ïÒ.í·î-™ l·Å‚P2õ¿ä ‰&çÀb1™âtݼ.xÇ£qºè2âGñnŒ[ÜCó•r¹s¸s¸\ž¯¸‡hÙ ‚‰é’¾¦¦KJL\7][G´h^7g48Jë¦XÐÿöGA¿u~ŽPì¡á½ñî¯4öÀ–Øåÿ˜ù¢9ý*ìònq<{\TÔ̪¨çh¶Å4s‚z¹³?ý9ÿéƒøûü¡ŸDÒC/Ûj0ÝÌð­ºïƒõ•ØMªÚIò‰#UŒ‡ öbˆÜÚÿå0%ÄA1öYø ~!¸„É©º3žAœ‚“\¶ðv Á ÆîaBÚ0,ü‡«ø¸Mlå"5ØÉ+"ø¸FÚÂa²äyÉ^ÑX¸yMœµy”Íjs\¾Ÿ¡Ë„IEND®B`‚eric-6.0.8/eric/icons/default/callTraceStart.png0000644000175000017500000000232712342633754020637 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYsvv}Õ‚ÌtIMEÚ SXÏaPLTEXXXZZZ\\\]]]___}}}‚‚‚ƒƒƒ„„„ZZZ[[[€€€UUUcccwww„„„UUUeeeuuu„„„WWW```zzzƒƒƒTTTfffrrr………TTTiiiooo„„„ZZZ^^^{{{€€€[[[~~~VVVbbbvvv‚‚‚SSSkkkmmm………JJJMMMaaabbbeee===BBBJJJKKKOOOQQQRRRSSSTTTVVVWWWXXXYYYZZZ\\\]]]aaadddeeefffiiijjjkkklllqqqrrrtttwww}}}~~~‚‚‚ƒƒƒ†††‡‡‡ŒŒŒ”””———™™™¨¨¨©©©°°°µµµ¶¶¶···¹¹¹ººº»»»ÆÆÆÇÇÇÉÉÉÊÊÊÍÒ ÒÒÒÓÓÓÔ Ô Ô Ô$)ÕÖ"%Ö/3××××9<ÚCGÚÚÚÛÛ"&ÛCFÛÛÛÜÜ?BÜQTÜÜÜÝ Ý.2ÝMOÝÝÝÞ Þ ÞÞ.1ÞDHÞ[^ÞÞÞß7;ßKNßßßàààááááâqsâââã&)ãCFãããä äääå„åååæ æ23æ79æ;=æææçççè è"$èèèé êêêë ëëëìììí<=íííîîîï44ðððñññòÃÄòòòó óÃÄóÆÈóÈÉóóóôÃÄôôôõõõöÔÕöÕÖööö÷÷÷øøøùùùúúúûûûüüüýýýþþþþÿÿÿÿÿë{ö7tRNSEEEE‰‰‰‰££££ÓÓÓÓÛÛÛÛßßååååññññþþþþþï1ebKGDÊó´6æ¬IDATÓ=ÑËnÓ@ÐïŸßr±S'Ó JHQ«e+bÁÞ¹[lŠPA- ªÜK“&uÛcg.ì8¯p@=C[ø"ÄVIõˆZàK<‹‡Jip!nÖ3^ž\h]\T2cüz±õJá–QÿÅä,:÷=›EzûŠQêŠ ÉP^¼I\Ç3‡þó©?ê´âè¿>ô¢Fàx¾Ô;û›³tÇãn³ÿ±¹BpÆIøT»J 1(ããº#²Û©ê½<¢–Š—ƒÞn‡ï[5^|Íã ýÝ èÐg&ªÚØ0v&q§ïg¬é4JÁƒ×èWæ×[a¸q^;„ÌeºÓŽ5 FƲ-/•µˆtžíry kŒd[¦œý£6ú]¹žçòµ±RO1ÉŸÖYeºŸ½å¢ñ)‚ɯW\ 5M6³À¡£/ŒÑ2ÿ£—âdâ“C€5VËýåUc´äØ³î² Ø[«å6½üYÀSQó®\%yQòÇ·+1¯×Íä´b½°Ayz¯ÜÉßP0ƒ^ÜQÆ‚ÈY­ïÁ Y´þ?,ðuØ©Ô^IEND®B`‚eric-6.0.8/eric/icons/default/debug48.png0000644000175000017500000000620612342633754017171 0ustar piotrpiotr‰PNG  IHDR00Wù‡sBIT|dˆ pHYs11·í(RtEXtSoftwarewww.inkscape.org›î< IDAThÞÝZ T”eþæÂÌ0 sá2  Ì00\F¹‰x S+Ô,ÍKj©mînEµëe73ÓÔ<¥®¶²–ÚºYÖzÒ•Ô63o„¦in˜ZyÁkË»Ïûï°ÇÓÙ‚!Åmçœç|ÿõ}ÞÛ÷¾ß "ñsÆÿ†BÈ:•~¶ÀÀÀrŒ†Ÿ*¼F£‰ g;…~*¼´·Ñh\‡yøOÕ¼Z­v † *•*¹3-`p8 `…Ì@îÇý>iµÚÑ‹åטt&¥^¯Vxó„!B¬gí½··ãz qæv“ÉtŠÈëô Æ/Æét~ Ë{ Q†¹º-— Â2Vˆ Bdêtº!ÉÉÉkq<øfP¥¤¤<Üα+<ºlÆŒ ˆùÜCv 䀾Pˆ¢µsç>S$D! ß̬¬¬ž…|4áááËáFû}1 U áì#Äp³+ðw|DDÄ€ÐÐPGôÉbFFÌ#E@@@:Üç*HŒõ'~®'C\\\MddäYÌ-ìÛÀ$`Nj’i„߆à$ ¹KjxMq¶n>νtåû!|?ÜOf³y[óf°¸ÝîÓQQQ‹XûlcpÀÈÌt ÍýM =2JOðq 3ïSRïîæX¬Ñ-ÒØ}€°®]»Ö ˜TP§°Z­™ø5BÀŽÍo:^›Û²l¶™ì1fÒj 9^‚F£&§ÃB+žTüótmDKÕó.^CBJJJçææÀ<´Ó „……%@5g£×–&ìl>é&ú*’ªèˆ]ƒCp1B|^œ,§–A—ŽÄмiÑK9ƒåäälÁhº).”––¶fâPõ'Wêåt`‹’¦NÒSRbMš4‰*++©¨¨ˆl6û9aµ%m †Jódô̯}µGÑ2´_Ð^—˵覸g!,fs’ãTG&—«¡èèh‚[Puu5ÕÕÕQEEÅÆÆr ²aÁ"™LÆ7ÓÀA]\AGA¬üf¥Q¹B¡,—Ë Å˜ä&h‚UhÞ¼yTUUEeee’!#I@ %  .9^Nû'(4ð®ÐààsìßH‹’ ì2ñññäñx$í#Øÿ(Ø$ (•J‰L¨N÷%Æîºð"ĵ 4ºd‚FwxŸ"¸eq°‰* hÿ„ªä¡qƒÒ©¼$Šrn©TÖ'…ÆÞ™B#JœÔÁýp¸™Vjƒ©^h¾+ ÒW£ »££åDGÊ_´}¨O°¡ù}¼ó ,ˆ À“xÔ7ÀÅÛlDWÑ’Ù=¨  €òóóiþœÞÔòuO7Ó\óp ÷T+t-ÞK3}VGHøK ”û+²Êf¡ÿ¶Vhéâïó5pV¥¦óaá´éölÊòfÒ,’×ë¥é^º`¢Æ`=–úB&§:]q%ÓyñŸ ”@p—Ð;ÆhzJh¸ÉIÃúÒÖØˆ\Ø(EGúK ™_†ÔسÕ/y|Yè÷%&IZM‚P«ÃÃ%ç‘B¯N™BÍ«VÓEXaif•&8hPnMÎɦOKúPSA!]IN¡ :ƒTÚ ?þOÓ2h•ÒXí³º pÙxÿN¤àG9ûùeÎ6¨Ù3¯õG¶@•B M %&&ÌLkPm2s/y³¨é®¡ôMÏžT¡—$:hSéjr'5ÝÚ—š`ËN—èg°>ë±uXÏ‚Ä&[ýµ;øE`Í`ËÛ:Äß_⻕ë9cDKzzº´XeÀm>GðJ1€€ä½ìrÓÉÕãš%±1´õ–ÞÔÔïVj*êAW9ââ©Ñ`”bà8ÐI1.#ƒ6YçYèïš⺥ÑB}ËZs4uA`cázB·f¡àÓ§ Øùè:awP}¢“– Ý‘_@Mù…tÖ9ìH £p&ˤ¿*a®\Ç#V¶Ù]ßAàè¶LCw!‹²Û±Š ¤QAëP”†„H§%ÃtÌk¤#ç/Æüƒ´tÉïGÛ Aº®Ç_AÖbò[‰G´n´Û•B´¢7ŒÀ ÕÀíðÙÃ0÷g¸u+‘bÁ¸Þ `)ÐèÄÃGz=½¨ÕÒqvúÐAñ¨•ø<_Ç•«÷ì€ÕX G€cXðöÁ Ð+ß0#L¦üÍ0÷âb:„[Ù 6Å‚q¹lÒP´åƒÀöàÜDT«\2¤ë@†‰ 7K³2Ž L5ÏåéBøYß²Ù¾Ù2y·€Û'#Z÷@Ø\hþ}÷Bœß23àf\"5Kh%2nÄ‚cñÛ””tÐßöÒïZ¨*$dÇn¼ } íÊ , ņAØü=ïÁ¹À‡8¶Öàž¡µÉo%óGø?$¦Z¸ä¾¡Ci¥Í¶î†ÔB×ÐÏRiþ´}äHz“cØ LÀFèKŒ‡P» ý]8>¨ƒÀl©^È“¬a ^Ú>p Í2Ÿmkw¯Ã8'caóvÓëß~»¼œVp6,ìŸ/áë0¾<Çî­~> A¿ Ø,Œl½mÀÛü ”ÜoÅzý|KjÃw_µÕUÙ]i)‚° ·¿lþ°FkA€…Û Ìå8‰pÐçvïïlÅå¸~ê¡—’\MÈNXÐu~m5¶›Š»T¤ÌS(êrgš£öÎΦX¸AÜg)ó€B†Þ…@ìZžÆ|7\‹­±ÃG’¯ù+ð<Îåí‚q~!Ÿ§­1›‘Ž¿‰Wx£ìz÷2¤¾ èwkxgl€nb/oi—7®Üp‰ÅxÔ&ÂÅø`:‚w#®YïÓöZ`5°0J^)NLÏh¾S¡½ zMÍgþ|8iw íT¢4~×·-h¼ÍÞÀ;ܨs“Þ‚/ò¹»ÖKÀã8þ2]îû{ À©µq€x’Èç (|̱•wê ý)¼5ƒ`÷^wxø“±±±lW¨C„úá<½AZÄÐt(0“3ôFb~7Žƒ–{c>x ˜t&Í÷Ž1[šû waJX` +i6÷zP"€+Q›ŸàÖÒw,d´ÐÔ9!$  ¡*Ùm |®2b‹‡ ÅqÐðÒ/€,×ãxŠ?<ãÎýü«Õ: p^oøÿs°Â>îÌZãÂ"DÜ=Býi9’ƽxÔCÀc ðÆ1À­˜ç@Ðá˜W€û± 0J¦ {„fïR·~7Ã;^Aoð\+±½}q{„7¢é˜æv»¿Æò?š¿*^Ü1¨K…êó»Ab“€Ð¬é) ~?­QÙ¥˜ä0à.\{‡PíåF¥5eò{à>“kË@b?¬QОïmíDD¢ÙX5Ð>IÑü· e•¾Ì(ß ¥Ööƒ’ cÀÑi®é%”\óD}¯ÛSúDbm¶×ë=æñxFùÜKá7d‰lÙ|h}8Ò]ì>$PEÚº Ùú2!ÿvªÐш2v#mõ•bBF¹B~±‹ÿ¡­Ú¬((¬­ë,ôÌ#~lûýÂ~ˆÀ]†1ÉÕZ¸pwâ…žB|ÜC§{Ý#—ÿ9UˆÝ.!~Ë¥r{¿óuQQQ÷ÂúüØÂÖÖ¾¦­žô‡Ò®ï^¥êŽ~ m+~Öÿ©òAà_6g¿Aã“tIEND®B`‚eric-6.0.8/eric/icons/default/taskFixme.png0000644000175000017500000000206212342633755017657 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<¯IDAT8Ë­•Mo5ÇgöeJ²É6¨-i¨ˆ(Tp AiŠTàZ¤F•zé'@H‘hŸÎ-('ø=¢‚(Ü*@I8TRPUm M÷ef7;»3Íaf7Ù*X²lyþþù?ÛâœãIå¦ïU€%`N  ÌÛukÀçgR ÷›+ûoúÞ˜À%àòØÉW«S.P¬V‘R‰4 éÞ»G¸²Jce%¸Ž°ôz¢ÛÿþÖ÷€S‹‹ãoŸ%xö(6ÞÁ&)Î*hŠ0…ÉöCê_~Å£o¾Þ8{*Ñ}ÁßùÞ¬ÀêÑÞŸ_XÀv»8UlšàTqi ©Eœ«8UL©D¼q‡û²-¸s¯%vmü½ïM ¬y÷Ù±ùS¸4µ8U:í¦Þ»40pÿ£)û>NSp úà}öiçž;Ù³MÓXžxëÍÙÑ—_Aà [h¡QÄNíÖÚAÝ©mãZ!®aÃ[¯#…"•7ÎŒ›lo0k¯âyfqtnm† ¶"4 ‰k5TuPãz#ÿÞÂF¹¶Ù |lcÌ埊¦âçôó¥™™² ´ÕÄ©E4‹!ªÄ:ÖÚA(âf+àTÕÖM>xË‚à j–>P ,àIÊæì[¯‰sŽŸKR~¨ÊãÌQÍÁá_ïîž¼ç§yZÓíöc¦ À‹]¸bòæ1G%: Á~.%3!ÂõéŽ w´pÕ oŸß døZ ö,œÃúe#¿¿‡o·Í²,_Lš ÀŒV0##˜ €R)ËÈr7éáâ×j¡nl§§;nƒ|_åXìÖþ(Ëi&If½…Žc&&OA©˜+MpÉ/·I·¶À¹>ô‰/ÈÝ@&e`Q …ráøK˜™ü#ÓØFtó7ÒÍMìöÃ:p¸:ÝqÍ}šö,PÎ@¨åí-`yºãþû›÷”¿—b’ràIEND®B`‚eric-6.0.8/eric/icons/default/erict-hc.png0000644000175000017500000000651712342633754017432 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœ ôIDAThÞí™qH£yzÇwïv{Üm]BHÃKBÔ³ÖZ+v¦zv:ÌM§Þ`=ÏólBB.¤i!„MšJHCiriJð$„`=‘ພ©ØJð<±©+Ö*b­ˆg­u]7ë꼟þ±Þ²wlK;3^÷ùBxÿ |žçù>Ïûû=ï+¯¼ÔK½ÔgRuuu¯ŸûÌŸ^~ Ãq#ÿðpý-ط„Z˜ù-àÿoà×`û ¨ªk¬~uídÜž[ó¦²ËBaËóñåÞdeè YµœN™.Nñ|Ök°¼†]pMrû:Ô½ús6½NmûW@üÍ‹ëÊPíb1R£òÖëëÀ1ð!ð?ù9ä =Ð D w¶î‹ãÁ{ÕéD÷mûöWá¬ø+`ØÞûØOQáæ¹Ç>]@' ãŠG 6sR’‘ *®gbwBL®¼vyæõpôöÎÉÁ»ÀÓüɦXBd’UÎÈËã^7±,aeÚZÌ«œóèe‡ÎîÁŽ¥”R1iɯŸô~ñE‚fz.Nó¹ÓâYv*ñq†-ΗԀËd€Cà˜e‡E)pÉÉ!ÖW‚7ÿÚ†=‡µûÏ)9ËìÆ–Ãrq1Þ2ÊŠë /þ¸á|gô/××cÿvʆ¸Å1Ö ‹ÝK˜¬BÎÇÃî»ìQä5.k¢À] (}Š•¬œ¬´q²ûÓùVN3¤´­$™÷(.÷rκºçldàU(m£|{q5ñáù%r›3<êk¡ínwïh‘ËåÔ×KØa›koz7h«„I x¿ l¥ÓU–©¢‹ ¢TÉhlR"“HpGû9ÄÍ|ëZ LyJx(¸1²cC,U­*ƒŒÏ?¡P¼ÏD^ÃDZ`2ÕÈdRE!¡øÍ-Ïšý¯ÿôø.̱u¾òqæYe‹Æ+½T͸m 8ZYa€¹£FææÔŒUDœJ²ù°’ña%ã>Åu1*ý.û~ñÿðËì$o¦$W?^ª”Ìl¸ñö*¹U3׌1Qõ²‘S¼`â §81ÚÚp„ï’®v` w2Zig¢ #•0”3î““sI™r+÷JÅB@x«šlúõg±Îw¶ØþÏO"o°Äû73} ˜#WÔqLú&Ó>|ñ;¤|á%6võkgØØ»Ô’Éß¡û‘À À žt+=ý2Ò1q[Iƒ„„YJÆ#eÄ&§†UÅjRÝù ð3mÀÚ1?5.'×’¤ŠJ›vv ±J˜Òº|ì^Y9ºx‚ÑÙÎÚ©‹]z Äîáq63šê"šj¥rØŽ'ÝA…6ö®ÛÏj¸Ó*`³H‰8$ÄÌrÒ.¨Sñt2,LŸLµuö±P8p#Ò W-l–ÛIZyÐ!Å`o$8ÓAáú1˜¨â¦DˆÎ¾6F?èÆ›ì ¥EÅ£‡J¬za³@Â('h“ÉÅùxý¿ƒBd¯ÜÝð".'MÀ?®cû6âÅ.fî3:ÑF|¤‘‘r©µûóè44?2±I„El¸òã-D²Ýô>Qb²5àp*pX•˜u6ƒœˆC íHÚŒ:äâÆ˜æGçåÆ?É/½øÏ\Ÿ©ªÿÄ#Ò¥f MÄG[qçï0¾ÚÅl¥‹X¨™`¨ƒ@ä.¡D ™ñV&gZX(µ2šRðÉI9ä$l¢v91‡œ´W iˆº¥âr¡ýï¡ÿ÷^äÕPUƒíU`<ÁD+~o¡”†é9 Ñ€†@¨™é™VVÖZ˜˜TÏ(ñ„”x=*\V·IŽK/ãS2*ˆDm D­jÂV9#¾zq¹ .BðÅÁßðGÀÙG'›²û,¾&ì¾flÖ&†ÝF“ 2q€GÀcð9ÄBQ¯œ°CFØ*%j–4ËHÛ¤¤ìR’9a·¿U ‰û¥æPë¿s K'þúfõÁ>0ÉÁé^Ì~5^¿—­‡]AÈ#p)ˆûŒø¤œr¢Ã^ƒ ÿ„¨^FÌ,#fWqxŒi[½x½¨®@W×m¬D¾¼óÑYgöfKSÀ“@ïïÄd×àq6`·8í6 —AŠÇ$Áo”0H šeL2Bf) §‚¤KňOCȦ" • ÔÿëîvWÿm­ýþÄ>e¢l`"[ìA?ÜÑֈɠÆ0¤ÆíPá5 xô2œ)>“§¶×ŸNJØ® êY•x *l½2‚uW¥M"¿p[|xwŸàˆÈÿ|ÉB7Wv‡§KÉV‰vP†©WŠ­W‚yHŠ]/Å©•â×ˈ[¤*Bv5€w@Np°žq‡ôŸ©ã6×z Ö€â„g{ ç1±Ø‰'ÒŒ5ЊӫÁd0è嘇d8õ2Ü&)>ƒ„QJÌ® éTu¨ð›ø|ýÑ×_w5jø>—Ñ/ßZG\;ªˆW‡ìsÎ(3ë± 7à‹4cu©0;0YTr|>³ü£†5Êå$¬J’5Q« ¿NwPŠg@"ºûê®#FÉQu¶ço '½Í |¸¬’$Zh!>y{ìÞD.«’a³€Ý$àt DrüF^Œ QJج fˆZTøõž>™èyRÿÔ§­¯ùu’“„CýÛ³ýoÂʯ=÷FíèÇp<µn¡vÑâjÖ&Œf & §YÓ$`7(ðé¥â°^ΰA&F­ 1jÄ I!ëd¢»OòÔÙ+»t ʱ+߉»›g³ñ.×údÿoÃv=·€rËÒøœ¾æ‰´]š-êký êQ7(ˆ&£ü©Õ(]:¹è?Ö)ž†Lò§‹òjجüÀoR}Ð+/"¦†ã´§e3éëø»´÷îw'c‡*:e¦®îµWnSP÷*`‚\µR¶mgG{Ž#ÃÝïz-š÷Üfå…ì~ÏcÞ‹ÚUç §ò4åRþǨW}”´íe#í¹È½µ±á®ÒDôáßÎôÅ #VøÝB¢¯þÖló)UÁóò2ŸÞÛNk=ýÖRÑ>;—üÁXô~q4pïíÙÄã·Ê£½Ó ™G“‹£¾·œëO­N¢•Yó_,Œkí• ËÀþ’ïîæŠUyšîÿâ+?oì݇åoBåÛâeñÛ—'ÓßÚ] n,8¿¹³äí?­úN7Bx°ìùýý%ÇWwË®;û+î¯lÎY”Åq‡d|¼ëKuuuŸÝ¯‹/õR/õÙÒ×?Õ™·Š-5IEND®B`‚eric-6.0.8/eric/icons/default/erict-bw.png0000644000175000017500000000355012342633754017442 0ustar piotrpiotr‰PNG  IHDR00ý 1 sRGB®Îé pHYs  šœ IDATíÁkleÀñÿó¼Ï{î—^¶–u[×Ëî¬Vr‰"‰#Ä0ƒQ?!‰ã>Ř1AQ>ˆ2]œBP\&² aq¬ƒmÝ…­[×m½°žrzNÏý¼·ç±. a°±¢ßÌ~?.ù?#<ɇþÏɨe¢NB§ƒt´¹˜òçL§m8xý‰%yÎüžUcIÑ”oŸêÉ/Óó×՚tÄŽÅC ¬J¸dôž“~©Ù0Cð uM}ݽ¸9msH Ÿ2!ö2Jï2FŠ`2öIΰ8o>Ò¹<&6ñ'lîÄã‡vº¹‘(—óâ•«7=(VI1¹Åløtá~•ŠgŒAÒ, N‚>š"§ˆãð:hS%`ˆÓÄ !áëÄËs}n`ñ¾váÔ]£ÖnláÑÅ$vш…&ÊMŒã”¹›ë8À.. ‰c ’}?ÙØÏ9ï+®ÎßéYKØÎ³ ÓA‚å¤ð©¡‰bÑÊ)]¬¡Î\âq  E]kÞùÅïù‹³ÆÔÔ w%å~- , Їa”(UF9ŽàVn#Ã1†ÈS!„„M0šüeçÏžá#g5u{·ÊFJHR\É.BQ"CžzȲ–.±›G¨aÆ â[COÝÐ÷}óPœ1`ýíÙ㊣øä# ÒÆBn¤0yÆ™æ †$‰ „!N£ åü?Ìyjã±>ÎOqƲå¥{ÞVGÈÓÌiNЀM’F®¤›,ÿ¤Lx Í<$Q,„Iïmøõ76Ý\å‚,fÔ¬¡û›ï.ÉC”x¸Äˆ0ÅlÒĉ 4ío¬yø‰ç7x| ŠѾçNiÕXÄ89b4’¡B ]ä©S¡‚‹FcPš:3oÛµ­ßÊE(f¨Þ•‹Ï“¡ä(“Ä0އ$J€F"PHKÒ´¿:ÿÇëwrQê*ÿÙLÂa9´ïà y Ÿ€‚f³ÿÅ})wIrŽ)‹ªU’¾Õ¶‡OŮʪ*Õ¦íÓ©QÆó™Í5>!ÁnŸXZhö•‹§ ¢(ÒÒqëÚ7u«P¯VÊ^uKÍ%—|Ô¿áõì†IEND®B`‚eric-6.0.8/eric/icons/default/fileMisc.png0000644000175000017500000000110512342633754017453 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ÉPLTEÿÿÿ!!!999………†††‹‹‹Œ’’’îîîðððÒÒÒÏÏÏÒÒÓÓÓÓÖÖÖÛÛÛÝÝÝçèèéêêêêêêëëëììììììíííîîîîîîïïïïïïððððððññññññòòòòòòóóóóóóôôôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøøøùøùùùùùùúúúúúúûûûûûüüüýýýþþþÿÿÿRv "tRNS#&MS\l¦¦±±ºøùþ>ôz#ÍIDATÓm‘ANÃPCŸí©‹Þ„-÷¿à °)ˆ4iòóYü¤mP½|²Æž‰gꀗüƒËÐy»ØH€ø=ÀùSŽlÉBœÚ¬X±Ý°W¬8vlÉØŽÇ’ÉÎÝp|/ˆœ4Ž­'‰=¸;]°@{·ƒÕÖÜšx¥uáæ–Üh™¦å¸5A$æßþZ¾k] ÚP~¾†ÌóX}?§Äدš†Ò"q»ørõ1\¦-rU]JûéVðxèl)§¾Q¤ÝÓê=>?>? ! " !$!"&#$'%&(''*(),++.,-/./100322534756877:99?>?/..1/0212544656878;9:<;<>==DCDfffmmmnnnutt$"#ppprrrtttvvv®²µ²´¶#!!'&&(&&+*+,*+.,,0..1-.1./1012./2013/0312401444534634655745856877:78:99:9:;89>:;?<=A>?A@AB?@BACC@ADDDIFGJJKMJKOMNPMNPOPQQRROPRPQSPQUSTVTUXVWYWX[YZ][\^\]a_`cbbdbcfdegefuwy~€ƒ‚ˆˆˆ’’’“’“•••———˜˜˜œœœ   ¡¡¡¥¥¥¦¥¦¦¦¦§§§¨¨¨«««¬¬¬­°²¯²µ°°°±±±±²µ±²¶²²¶²³¶²´·²´¸²µ¸²ÆÙ³µ¸´µ¹´¶¹µµµµ¶¹µ¶ºµ·º¶¶¶¶¸º····¹º¸¸¸ººº»»»¼¼¼¿¿¿ÁÁÁÅÅÅÆÆÆËÊËÌËËÌÌÌÎÚåÐÜèÑÝèÒÞçÒÞéÓßéÔßêÕàêÖÕÕÖÖÖØâìÚäíÛäíÞäêÞçîßæìßèïáèðãçìãëñåéîåëòåìòæìòæíóçîóèìðèîóéìðéîôéïôêíðêïôêðõëíóìíñìîóíîñíïóíðôîðòïðôïó÷ðòôõøúöøüøúûúûüüýýüýþýþþþþþGÀ]8tRNSœ º»»ÇÍãäääñññññññññññññññññññññòòòòòòòòòòòöýýýýþþþþþþþéÔò»2IDATÓuѽNQàsï^ð4n¨Cì¬ìŒ•vêÈøXV>ƒ…o`a¡‰?…•&H0 àîÞ½3Çb"‰žòË™)f€?cÀ¹h«CØÈkOïErDz·ÀFÎFWzùà€Ï­¥Æu1~°”pˆªæ¤Â[k"kíðå.V%Ö;a»ÀZcm÷“Ý5|l-Ô¦ê9U δR=„„’èŒÛL³›¢½ï9c5ùxTöre*(9 žŠv;(%L9 M¤~S)Z2.~ŸÃ+&p`˜¿’(´hÏ…>.ùÈh%M¨÷ Uøs=X˜Äª`Ú8¨‡æ¹¯ªd*>N¾ÁA2Ã<邈xñú:à0ê/¿ïæ2¡ ‡!}“òi¦¶Y!)ÇèÁ{ü›_Î+¬%ÝIEND®B`‚eric-6.0.8/eric/icons/default/fileSvg.png0000644000175000017500000000207212342633754017323 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ555LLLCCCIIIxxx{{{LLLPPPnnn’’’““•”””•••–––———˜˜˜ÑÑÑØÙÙßßßÙÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝßßßßßÞÞÞÝÝÝßßßàààâââãããÚÚÚÍÍÍÊÊÊÌÌÌÌÌ̵eÔµkÒ·rÓºZкq׺xÔ¼zÖ½hÖ½zÖ¾~Ø¿wÞÁ„ÜÃ}àÂãÄpÕÄÝÄŠÛÆrÍÈ~ÚË|áÍ¢ÝÏœëѨèÒÒÒÓ~ÈÓ«áÔ`¹ÔçÔ–áÔ­îÔÔÔÕ·èÞÃùÞÈòàààáááâµäâÈûâÊûâÒéãÉüãÊüãËûãÍúäÊýäÌûäÍûäåæåÎýåÏûåÐúåÐûåÑùåÒøåØöæÓùæÓúæççæçèçÒûçÒüçÔùçÕùç×øçççèÓýè×ùèÛøèééèéêéÙùéÚøéÜ÷éÞ÷éßôéêêêÜôêÞöêßöêàöêêêêëëëÊÚëáõëìììììììïìíííéñííííîîîÜèîïïï¼Öïïïïððð×êð×óððððñññÐæñãîñê÷ññññòòòÙìòÝñòòòòóóóóóóôôôäðôóõôôôôõõõõõõöööööö÷÷÷÷÷÷÷øøóüøøøùËãùôýùùùú÷øúøüúúúûÜöûùýûûûûûüüüüýýýþþþÿÿÿwŒÁ;*tRNS0:IM\\]df~€€€€€€ÜÞÞßßßßßßßßßâããããã÷úýýþ×üÑb]IDATÁ±jSaÇáßÿ}ßó¦I0C:((T:vv‰P,ô2¸¹{ ®‚^‚›‹“n½7l—ˆ"XkLÚ“œ$ßçó$ Rß$IHh+êgûݺ#s3¹€W+ÑÝï»»y„\*¥ÛódíùÜ5ݰž’}¹x0jM>ôž'R'¥Ë³ãÛÛÎÑqÿ­…®ªŽX粺i:ï€%O{ß­Úí¦õ£Çੲñôz·n6><94 €½ïΆ›ƒ“ÂÌ}l³ƒÓ 0@aî¼(‹ƒÓJÀ“¹;/?­”·ëµ 7w°¦šÜ«š¶¥-`æ¸-?çÊçWÿ¾~o –ï¯tÿïÇÍÃËI†Ì‹Oyôdy½¿žî ÝyS%ǤüçÇùÏé*AÀ€œ·³É6ºC弘ï  2ðp›qñöº—IEND®B`‚eric-6.0.8/eric/icons/default/preferences-colours.png0000644000175000017500000000336412342633755021717 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs7\7\ËǤ¹bKGDÿÿÿ ½§“fIDAT8ËM•klÕgÇ¿¿çùßÎ¥=-íé…Þb•Ã¥Àdl\ݸ psÂ@^0,ÈH$8]ÌÉX¢‰/4AqKD“HD66 ¬¸A/PVÚÒÓsJÏi{nÿÿù?ÏÏ7›óóæóî›Ï»/áÐ!˜€`0ÑG•$.7+ËäÅ®‡zƒ¢~Þ úFÊý±M êþ¿Ÿ[0þÛÁ+UlRA ãS üd2së2æii¬Z0Þþsf3YTñècûÎKÅXK,~ø¾^9öÐÍß¾hÍ8y¥¼= ÿZˆ¥>Œ"ü| ~^L¨B~Í`¿×Û‘¾¸ñG_?¶ù™ÀÊYÍOLdÄýþ!¾?p£©riI©®ØẨ]¶=Ëšop ÏŠ P ð}Iç§Ú÷gL+w¾gÃÔU/%˲R©,Od|"ñm‡èq§ôC€oDìÀ¹÷}„¢nûÅÉõŽ“i[¼hîܪêUZŒlÆãB.‹¢[ÅbQضEžWÓ§OÇäšú—Êªä ¥ôJ%86‚ÄÞS˜[_M.JsðúåœÙ»æ×N.ã`P)ÖÂÓŠ\¥àú>å JsEE=ùÄ] Z2l;Î  ³'®Õaä-"ï—@‘úrÆÊÕž?ò¨lûèÕ|O§òry™Uн@€¸¢"…ŽDP=u*,\ˆ@ Àª˜'wðÅ¿Ÿ™òôŽ—Ÿ¿pÓúÝ"·¨• |`ŒÉ‰YBa?ÃéÙ»NË©Näbœ1€ÒFd|eëV,ßù¤Š>‘m‘ ÐÇæŠ5îæËĵŽP; ¢ào¦CêÄPî;@$3'Äô+ðøvcƲ¥`U„ë Np8h ®Û€’þã›’«¦Æp–‡H Ìš¸ –j¥ë»Ÿ”Wÿ+²ÑŽ5 lÞÄfÎäªe˨¦¥–”`Ö Ã]‡™¹J$çJæpiù%£|Ë­)ÏMO8zÌgˆ“À+&Z~²ÀŸ=³ñüüùÙOº»ÙgÖZ)æO­5³.¦y´cß>>…Ç:v²?®uæ?ìÿÅißÄ—üþ•Ý`³ÿHrÏ-WÏ+~k­Àšâ¬¼¤?Ùö†µ²,*7MS3+!‡…ûñ¸C'‘Ë{PF0XBÂŒRÛOÚèŒ-?¿o´îÅßôŠ©6V(Â6˜—k.îÑ…žøýþä«ñdŠ™‰0ƒa¨8ì’FDBÆv!Ÿî†ŸéeßK 6¿Àv8U7±¼ü5­‚ƒ À'“`×ÕE×<»âx<~-•JI†ÐÌš¨r-Då:X¢€@ ‡ãº w¼‹¼ÌkràX!N>Õí«˜R/œã-zíÔ¤ƒŽ[¥F˜Ñ×?¸oèÁäóy`ªß éDaXJ‚@&uéD'܉>(7Ç(ZîylÚ1CÅÛ6rBQf­k<ëê¶_ÙûÛÞîèh …ë•!Ir0Qó=˜}?ƒ´J£H Ýája_ôŠ_5c#ÿØþÎé+rí^ Ñ# ‰˜ï*å¡­M±ï×,¨¯¿ÑÜÔTS__ï[–IÌòÁkbB5bT®¤þûŸüóÜ;Ƕۖ詬n­­Û´q¨^þÈ#ßÖÚú”aÛPª”•Òóñ±ÞÞ;¼u}×®7 ¹ÜËù|^Lš4‰˜™rî&=šÎܸ×sî{ö¼x€Þ¹ý›ˆ”ôäºÐQ ="åÜPCƒv„RÂM&y¢³“Fãqÿ°5±n]Ó¬¦¦%áH©K§‡ÚÛ?¸qùò•v£ŽãXZëœçyã²òt˜h¾Ã¼ÑŽDfØ--0b±qß4³©îîÄÝ[·nŸN&¯hYcÒó”ð¿c3'R ›Íæä|f÷¿vá2K\ h"zTXtSoftwarexÚ+//×ËÌË.NN,HÕË/J6ØXSÊ\IEND®B`‚eric-6.0.8/eric/icons/default/pluginRepository.png0000644000175000017500000000251212342633755021322 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ.6ð’tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“®IDAT8Ë•KlUEÇÿsιÏ^ÚÛ^ú)X¹½ "¨‘ÇS£DeatáBâB]¡&&.LLÜè F&nÔÄÈ_„ 1F‹¢i[@Zn)í}¿Î™3sfæsqÛrè—|ùÎL2¿ùŸÿ7sÃÄK'ˆØû›{öíOFWôUDÞ(ŽŽÖ‚üËŸî;3ÿ/~¿å‹3¹ßMÑ/ÒTmš&*iôú¨yõäÓîóßnîý·5ÎpYUÒµÀeE¿OyàÊGÎϱ™Æ|œªj€ù;?wlÓ­ˆ`1ak`Ì̙©L[x·Å•®8þ*“¥Ü𠳇Ÿüj¸ƒCõ›žg·BŸ9:|èÑ{žú`¨sRû 0tDS&IYeY×|Í¡AÄ›š(±š(³º¬B‰ÉÒ93—Ëî¼U1 ®ïÞB™öõŒk_spíYE™W¸ö°8ïûÜZÜÈ'n<„CQKpZ}›FÔCCUÁ5‡Ð|´Xzö›ê ‡o8yð‰C³4Öí`ƒ8³®®Ý€™Öô ¨©Ð§Å± Ë6ðT &¶ÞóÙðv^WXØz0äØÌÕUø†Cš•ƃ0>üe’88&@,€¤:\]'ƒ@¡ ÞñɆwn{åílýªÉù³–cÙ¨©„áKê5•5+‡BŸê˜«V‰(³2V  9ë߈¯ȼµ±÷~ÜÕÙc…Y9™… a¼&ÍTL‚S5àé paÌ…³õÓ²œ¶bö  èzáxþkÇI…‡3©{í߯&0þ“@u6ŒJ‘ÁSm«8VïšC{ºA.\]ƒ¦Œ¶Ø`(”ÈâóÁá+ï]ú¼¥UÚ $Ξl`ˆ’xdã ~•3P6ÇŠøJ(¥0yô*LúG¤Gª` pï-4[h(†ÝzìžÈÈέ}{F2kÓH÷¢è¨ …l¾Ù\]])xÙv°XñN (ìfU6”b4•÷ç—í]>•Üß·»mkòr㇢vºä}#ý½ýHgúÐV{yYÂtUB¸e_#éÂìhËÿ¸éhíÑË öj '^ïŠÅp½pÀkŽe;;&§+ÈlR¨‚"‚ƒ–ÅA–Æý)ŒŸÊÂW´dAkÜÝí°¶PuY9Ö.–cÙ¡ÄØ¥†²”ÂD‘ÃE`w&à„lDa  Ež4KæÒ-¸²è Eï‰8Ÿpµ³nz¾†¬¶‘êé@àkD C,æ )ÆÆ³`Ñ\ÙÒŸÛÄ7G‘°í Øf':JZÑøÎ {ÇÖÕØ¶®ý=íè팡3êàÜÄz}g;}}}€!!……34ˆ‰‰‰‰Ž“““šŸŸ ¢¦©©''ª««­­./±¶¸¹ºÀÁ&&Â55ÄÄÆÇÇ ÍÍÍO&Î??ÒÕ!"Õ`&Ö21×ÜÜ;;Þàââ[Vã%%æ;<éêíîñõ "öMOöÂÃúFF¯5w¿ntRNS &),-07789?ABDEFHHKMOQXX[\bdeijkklnovzz€…ˆŒŽ‘“–™›£¤¦¦««°³´¶¶¹¹»ÁÄÇÚÚÜßßããêíøúúûüüþþ»h¬uYSVaÄPÞ 6aƒÔì¢ü¬dCNa¡˜þŠyå ‘ì(ÂÁ¹e3J r|Q„Åc3Ož>uÿ…Œ~¸0“ŒOÒÉó›j×_:ç)æ°Õ4kžuñjWëË fë›;°…™ø]k]¼räôµËËÚm…™`f{¬Ø0iÝ¡³3ç[ì‚d¥×Áî’º=«‹ŠžqG¶Ú6¿°m×–¼ÂµÇÂLŽ«6ï<ºãÄÊ5{·[ „y¬Sª–nݸo÷òêøp¸°œ¥}eӜɖ´Ôù±Ã…uíØ¢;§õuLé`ñ… 3(9 2r„¥OìI ä`’t’€3)ƒbŒYÁÛMÄ`WDŽ[TÌ^CÉ*ofIEND®B`‚eric-6.0.8/eric/icons/default/notification48.png0000644000175000017500000000514712342633755020575 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYsÃÃpMBtIMEÚ--ps¢'bKGDÿÿÿ ½§“ çIDAThÞíYk¬]EþÖš}^÷ööEé› M_ò.…šb P!P C ñ^Q‰? 5j$AˆŠFMˆ!…I$ƶ1$<©¢Th¥J¹—@KiKôÞÛ{Ïsï™YË3ûœÛR¤½-úçNÎäì3™™ý}k}k­Ùûcm¬µ±=‹Vü_î›/èjïz€ózMrÚåx/ç(t!w1QET B{ c{’$›“Äü¹Þ·î™Ã×¶Ññ,.Ï»òÆ4³_=möô‹/X¼KÏ^€sç`BO㺻Q)'h¦µZ»öÀ–Þíøû+[ñ⦭ѧJ¥â/ë}ë×þÏä+Í»êÖBB?ºáª‹&_óé uöÌ)44\CµÞ‚µ  "°a0J¥*å&ôt¡T,âO/þS}âiÚ¸åþJ¹|W½oÝc£ñÈ1è^tõT›Ùçnºvùé«®»L‡« ®Â{"Ã"€˜Á €&@L ·3†ÑU.aúÔÉxg÷~½ïÁÇèÕ×ßê-—J×z×íûHTæ_uõ”É=kp÷-Z0  V6°yg`& ÎÉŒè  \,bÖô)ذñ_ú½Ÿ>JLæúzߺߟPåùW~qþ©3^}×*ݱkeÖ0 q÷“ȉ1:^ˆßLäóA?¾ ÅBAo_ý ¬ßÓxcýO®…+®?uÖÔ'¾qëuúöνD LàÃ@u<÷“ =ñë I‚Ó&âŽïü †¾Uï[ÿ“QyOa¦wî½ýݳˆ4€8`$ƒ6)€‰†—XÇkÉ`„1 I‚©'MÄm«†ÌúåµÞõÏÚ¥yWì¾éÚKg”K²Î Œ”ðœ|^NìE£€ÅB‚,súýÖH)IÊ çjo>}l…¬çãWßÜ])ÍW)£ÿàpÔ|p;sâoŠ ˜ˆÁTÃq<’uær$3BRL@‹{ºiÙâæå-}ko=sÓ1{ kþåÃËÎ;cܤ ÝäEÀÄm+Q[&‡Z–y¤¬r`<‚\¸]ØýrDÂù¼J¥„û\ƒr¡8SÕíiìøË‡{ {îr€ :—õX1<\‡ t9·*óÐqsLŸà#A†Øˆ… G0Jˆ“Ä›9ïîë¿·õÎ_ï<* Õ·=‡î¹ËW‘ Ä;4[iH—Ñš&¦ÎžÛ)‘Ù´¯ƒG™jÃ^á#€ª ʉP§~¤i ³gLÁîÝ{¿àΣŽ¿‚U0xð D%êžÚ ;à¹í…`ñH(¿Ž^8T*Ôñ€Š€T ª‡>P.$ŸÊ3—,j½ûJïѱØÙ¢F¢Ò¶°1°1ÑÑêl8Ã`2!-æZ™e×?4Ä„   ‹Ámm q ¿´4õôÞtÿÖÿN 4kI\°mÇL7ãº* cÀlÀ†a"â0F&`6y°Éó<¢m`ÒˆOÛ$ ˆê¡Þ*‘£^«‚Ô Ó÷^ÿp ‘xVg' W‡1\­¢R.£T.¡X,˜d"à N‚lrbd@Æ´ Tä‘fÕ0ò€À3µZ {öîà!*ãŽ*¤TªS£%À¨±µ)œw¨7›H’&) )`’l’Þ€Lb°‰úg0D4C0:@ ð‚VÚBš¶P¯70tpÞY¨ ‰Šˆ?*ÙÛ/iñ¤N‰(ÄS1˜’b.õ"pYX eæHÂ$@”Å`fh[礈‡xñ>Ëà]öR©DDzõðÎD¶•'ÏCkàÍbU÷ˆ.SÀ+” €€È´+r`–€Ø@™2( €‹ÙêC®× q’¨qõ€ø¬Ì( Pï ^ q.ÄB…ø ªºÝì:º4JªTqË!ûpà‚2€ ‹<“hÌBhw†’A,@Ô:T@€à4- ñ ÎGÐ*´ÏRx—Bœ ?u$¬|¤ÁISg>dŒ|°€÷Ä¥P—AÅB%ÜLU¨z(€°íŽ Õ0O¼€±Yƒl³†Vc.K¡j ‰Âñ¡³µF>’ÉÁŠŒˆz Rô{ï¦QX{÷lØð™ÃÃÕ׎Ë+¾|?Öÿæ\°òž­Ú¾ÍÅJÏ4۪» â\Ö„ÍšpY.mÂÙVðŽËà%ÈGDÒOd 20lÚ„Kp¶õ!%W*]Xºt©V«Õý›6m:UU[ªÚ~16ê7sûTéò+o{¤kü”U QÛj÷!sˆsð¶Õ!f›g!¹¾Epˆˆ¡â¬Û¨£Õ†mÕâãdKÎ;O½÷FýüW·üûm¸û¡õøñWVŒŽÀ{ÃÏg|KWÞ½$)U.›t ê²”$ævçrBY8Œy ªD¹ä5Cê ”˜"Û¬¢UBÖª¡\鯢³?¡sæ.¤I'O{vÓ¿[»ù…uxoÔo§þVÑwcXvþÊo.+U&~;)w­,wO„1&¡,…³-x—ÎFðÀöš¨ö¿‹´9ôx±ÔS¯ôLX\¨Œ?;)V’R÷x”»& )uLâlkx[Ú¿ãÉ][ŸtGï–—NÈëõ…¿Vô}=,o©Ò²w|¶{Ò´Ï’ÒbU,Rñ';—õÖ¦ðYk§MkÛCþ6¸ç­gv¾þì‘ö½äæû&WëƒSœ­³á®—ÿðÀþü_’/<²õí¤cuµ±6ÖÆÚX;¦öÖ꾑¢êIEND®B`‚eric-6.0.8/eric/icons/default/break.png0000644000175000017500000000141112342633754017004 0ustar piotrpiotr‰PNG  IHDR(-S pHYsÄÄ•+tIMEÔ 0Iç%í}PLTE222222Ó22·22‘22’22”22•22˜22™22œ2222e22c22Æ22Ç22É22Ë22Ì22Î22Ð22Ñ22Ó22Ô22›22œ2222Ž222222’22“22”22•22–22Ú88Ú99Ú;;Ú<<½88¾==Á99Â::Å;;Æ77É<<Ê44®44®77®::®==ë22ëGGì22î44ï22ðllñllñ‘‘ôddôooô‘‘õ22õ44õ<<õJJõXXõooõ””ö@@öQQöRRöaaö””÷YY÷§§øaaøbbø»»ù22ù@@ùQQù””ù§§ù»»úooûbbý‘‘þ33þ44þ@@þTTþbbþììþõõÿCCÿDDÿUUÿ]]ÿaaÿggÿrrÿyyÿ~~ÿ‘‘ÿ––ÿ™™ÿžžÿ³³ÿ´´ÿÈÈÿÎÎÿÒÒÿÔÔÿ××ÿææÿííÿîîÿððÿòòÿõõÿ÷÷ÿùùÿûûÿüüÿÿÿ®¡ý~4tRNS(,55555555VZ€€€€€€€€€€——œœœœœœœœœççççëëëëëëëëîîîî²¢cÄbKGD~?¸AsÒIDATÁíJQ†ÑgŸsÑ3è ,ówÞÿµH"AFF3£ã˜g¿­eñÖ]®& ˆóû>p¨W{‘ ¾¼NXúªU$β»kìªsŒÏ‹ÇtÑI”ùÊUÅ»éœa,ŽŒ‚}ô9y?ó{UŒëŸ$é »qŸõ¶÷àÊ9+‚žäGÒCZóÄ £Sr3›ôZ§þ½KsY=ì§^í_ÕgT­ËÔÊLíyó½ÚGΕ÷ËB°Íö­‘³ë!tçÓ²‘ °t3p¹W{‰‹óx))k'IEND®B`‚eric-6.0.8/eric/icons/default/diffFiles.png0000644000175000017500000000160312342633754017616 0ustar piotrpiotr‰PNG  IHDR(-S"PLTE DED{­Éy–¦j ½fggcghWhMahlajobkq_kr\jt]lz^p€Tevcs…SsBex‰[{Jf|‰ˆ«¿®Áh~‹Q|9wŸ¹‰­·Ž©Ã‹©¾Y„IÃÒ´Ÿ¸È˜·•µÊÕ¢¼ËŸ¬ç°Áä¿Ô®l¡g•u©#z¬$m˜(sž*{ª+m–.z§1Væ2jŒ4Xu4‚°6«6ƒ¹7€±:=H:¸r•A…±D®!GaåG“¿H¢)JgÛNÓ7R±5S×T’¼Uš7V„TVˆ¥XƒTX©=YÀ8[{Œ_ŠL_©C`€Ïc\c½Jddsd{òd|—ewWfá1g•¶hØNkmvkŠäk˜Tl¬SlÝVmxön¿Vo²Xrr~r”ÁréCsˆòuÛdw²dxÍ_yžnzá^zìK{†j{Âe|šl| m|¤h|Úq~í¢géQƒÖ€„£u…Ãn‡£ëˆ»x‰€‰Ÿç‰¤½‰­Œ‰Çv‰Õr‰×‰Š¨|‹‰§»ÎŸŽ¤àϫҪ•˜ˆ•ê‚–Ÿ©šÑ‹›—› à† àš¡©»¡ÆÔ¢Ï¤É”¥¶µ¨³Ÿ¬¬»±Ë¤´Ëشݧµß¥·Öª¸×©¸Ý«¹ø›¼Çè¼Ê­¾ÎÉÀÄÉÀÅÁÀÛíÂźÃêÅÈÙçÉÛåËÞÀÎãòÑãíÒ寨×ÕÝðÓÞ÷Óßíöãóèçòûìôýôýìöûþÿÿýÿÿÿ¾mÂ(tRNS*9FSm{€…†•˜Ÿ¦®²·¼¿ÀÆÆËÒÞÞâãäåôöùùüþþþFYŠUèIDATÓc```V–`c@r[·n^¦"Îín\°qú•ÓY!2sÖOIŒì\ºb‘$ˆ»JA©§8«cI_E“H`ñê-›–O™[ß/˜»°½ròšµ ½%NB µ”àòIÙ¡¥©a­ ոª(C—Üêæ6~€ú¼ù-vŽþy®VÆá| Y3'æÕ$eXé›ð‚fO¯HKðs °1Õ1à ÌèªÍ‰÷rp7×ÕÔã D—Õ¥:Ûzšiihs€]Î$ìãm)%èãaÏ÷§¼(#3 ûA /^-IEND®B`‚eric-6.0.8/eric/icons/default/home.png0000644000175000017500000000164712342633755016664 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ÂPLTEÿÿÿ5<>FJJ.4628848:6<<6<>8>>;=?;;=;>@>UWVVYX9<;:=<).0-23.34/5604416747749:5996986<==;7AEDI`LKGN&NQNX+XVPYa[[V[\\[]\]^^]d]j^``ccccdceffeggfffghhgkih3hhbijflolqsqxysxzuy{q}u>ƒy…†|‰Š€DŽ„‘’‡’F––‹—Iœw?M M ¡ž¡N¤}D¨R©‚H«„J¬S¬b ¯°­³‹P¶R¸Y»[Ã^ÄÆÆÅaÅÇÇÉËËÊÌÉÌhÎÎÎÎÜÎÏÏÏÒÔÔÔÖÖÖgÖÖÔ×ÙÙÜÞÚÞÞÞÞëÿßßßàââàãàáãããããåçççèèçééìììîîîòòòöööøøøüüüþþÿK x0tRNS ||€€€€€€€€€€€€€€€€€€óóûûýýýýýýþþ#vvIDATÓc`Ä LE%l jêJ˜ÂrÚ®®ÚòŒæ6ÈÂRšÞ5u>Z²½UHÂ’úîe••îz¡M-a ßÖn h÷· +€ ‹[xÕ7ƒAƒ›Y LXÄ4 "Lð3… évôÀA—Ž¡0HXÆJuÒ$0YÅX (¬,Ù‡"¤ÁfGMIMMbäfDA­ŒéËššÕžß—35§/*;%77wJRII攢ܢ)±PḾ¶¾üêÆâ¾¢¶¢¾8¨p”¢¢¢)i¥¥y`FT8쀔òòl0#*œ rn­­§‡s'ˆ• vrr 7ƒˆ;k|ÂL̬lì\Ü<|ü¼<Üœìl,L æýr$Ên IEND®B`‚eric-6.0.8/eric/icons/default/atomicgroup.png0000644000175000017500000000023512342633754020254 0ustar piotrpiotr‰PNG  IHDR&¾ƒ pHYsœu©qr‘ PLTE@õ¿¨PtRNS@æØf-IDAT×c`À @² H¶€H&V0—Ñ,€ !"`YˆJ¨.ˆ è`ߙϒü³IEND®B`‚eric-6.0.8/eric/icons/default/empty.png0000644000175000017500000000020212342633754017053 0ustar piotrpiotr‰PNG  IHDRþzþxsRGB®Îé pHYs  šœPLTE§z=ÚtRNS@æØf IDATc XWVIEND®B`‚eric-6.0.8/eric/icons/default/ircUserPresent.png0000644000175000017500000000145012342633755020701 0ustar piotrpiotr‰PNG  IHDR(-SsRGB®Îé pHYs»»:ìãâtIMEØ)¬ª`ܧPLTE€ÿÿUUUII$]P$i"dYC\%t]M]rPtaO<5_sNs_NO’K:kIP–L<‹63kD«œ‹ŒvaŒ~m‘zc™ƒlž‰rVXH”;\™^½¬›[˜[¥Šp«“~e f´Ÿˆb”go­fY˜[´–{^_°“z¤·”´šXšYmµeT¼Ieh­Žr¬½—L•=¾¢ˆÄ¥`«U£déѼj m n s v"r"r%u&y'+{,‡-|-|/†1 2€"3#4%8…'9„)9…(:(:“-<¨+?‰.AŒ1CŽ2C¥8E¹7I8L›>L¤@M¢O­@Q’HQ—@S¡BT™CU«JX£KX¤H[™M_ºRb®Ve©Vi–Xl¡^kPpSšx]¢€g¢…m¥†j²‘w²–y³–y·¡„¸™€¹Ÿƒ»•q½™tĦŽÌ®“罓蹊迗还ëÒ¹ì”íÈœïØÁðÓ·ñÔ·ñÖ¼òΧòѪòÜÆóÜÃóÞÊôÚ¿ôÜÃôãÏÿÿÿM4P7tRNS '(456ACH_cgpwz{Ž¢¤ÁÅÎÐÓØÜÝàãæçèêìíïïóô÷úûüýþþþðÞ bKGDŒl ÒC·IDATÓc`Q}S5NàËÎÌ)7bBÈ—æçs#4*Û;*ÄZÕÍmݵÉš¦Î.3v„³q}K«’- UuebȲ%Yy"H|^ƒ†‚"M.F(WP'51#=96M…ÌJIŠ ðò K0á èFÅy»;»xøGJù¬!þnŽv6¶öNž¾†@6½ðh+ ssKk×e°!Â2ŠêÚªrR,@¨&:Í%˜oIEND®B`‚eric-6.0.8/eric/icons/default/pim.png0000644000175000017500000000254612342633755016520 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÜ:*boubKGDÿÿÿ ½§“æIDATµÁil“uð_„<ð ‹(ЉW ‚‰1ÄDCÔ7`‚øB'‚ ! ˆ/$ r- 8pãpˆecìêÆØÚm×n=ž¶Oõé¶^Oûôzú´Ïÿk—`‚¼ˆŸýGyºØÔ ºSè6;ë8úG*ë=Ô=>Nwòþž¾/v—þ¬Vͤ?i Ó¤vk˜:­Õ—˜ €þ`ÑO÷üØ.<ÕãŒ-7ză#ÉÊ…Ò‡‚#˜‚¶7ô4•L_u•¨Q?Aw4÷д£üƒS\;ËŸöGdK0’Vrù"&å”"z8çºBh1GÐËÅ–Sɱk<ÝbÇ´SmþÙîPj±Él%¹IVÔX¾ "“ËCL$áóàq»Q(2(•…“2z8ÕAvà ^gì,•4ôihÐ-¾‘ʾWUÖ¡ªLL犰‡²èŽãÀÌ> ¡ N—œ'À|²rYY…¬¨°38Öì‡Þ‡‰OT¢2¦!3/&sJõýc8XÏ£üð€²¹JWø¼Ò ®ØofÇ›|P‹E³ˆ¥ È*@:W`ÉtÑx=ÖÝ ôs"Ì|‡¯zæÓ¤kƒc­©\ŸV™Ùªý}ì¢V‡,¯‡­K‹/u`û9¤l…2¼¡øÑ0|1fçxp¼37Ž.[gà :ËÄFšt¦Ý·©PTq®K`[NöÃaÔCI†€¨ Õ±þ¤œ 1¯_€Í5 «+„€eÞ`a‰!‘1ÀÅav †%pBúMÚx¸p4’ÁH …ªz'tÝF5 Äœ8u© ›ªLïY4g_ˆ 9|è0z™aÈ óˆ‡õšlvú`²rÌŠÁâ•üïì0”Ñ·¸‰‹§è,Vßã…ÃÒõ8ZgÀ†VÔÞ±pL‚Ç'À8âÅ/:+ÓvÚÑdpaÀ- É0yÓÐYã8Û|&]‰Õ¤sExÃ9h ~¨n²‚Â8ÚýÐvóÌ7–„Ã3†³€æÁ1¦³ÄÐi—Ðãʰ¶¡(«7øÙùV«k5¡ÁàÞN“Öï¹PžÊæ1‘Ñiò!NBÎÏV„˜È0>”ÆÈhm–8Z‡âh6N°»€!›jZFp¾e˜uY'`â¥^ºéù¨$#8ž@,žbE•AÊä!eHYád‘ydzlÄA{Ÿ µ×Yƒn m½¹½Çêo/[}ýÅ%Ÿè:¸úÜY\7†©|Ã×ÓˆèÑfƒ=ˆ’\^E^aLQÁ2²Šàx.oÆ!;ôýVfv3›g‚Åe`÷¡S"úŽˆV¬Ú´×^q¼ÞW¾å`Õýó¾D7Ý·u÷-Jä¼1!1ÿ¨»Ë‹A‹S®Õê½™Oe P 2ÀŠhê¶+[wý°—J,^¶€ˆ¦ÓíÞûpÍž°˜E4e11›Ã%®þìËš²'ž=JD»Zn˜âÑ”‚_›;Ó»*O·.Y¾æ+"zˆ4ôWÊžy僾!¿ ‡£ÊÊ•+gÏšùÖGë¾Y·­¢²åµÅï®#¢çèèïÌ©¹ÜFIŸÑÊ.7¶ó;÷9S6çñGèn½üæÒ ¯Ý\1oþ«‹ˆhÝ´¯¶SSq²a ÑT ý3~’þW3zLsïì¹*@wã7(*ÔžœcIEND®B`‚eric-6.0.8/eric/icons/default/cooperation.png0000644000175000017500000000233512342633754020250 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYsvv}Õ‚ÌtIMEÚ/`#ÃbKGDÿÿÿ ½§“]IDAT8ËÝT[LUþÎÌÎÞ—ÙáRÜE,Ðmð‚Ùbmµ){‰‘¤ñÁˆŠÆDÅÆ'Ð'4òbÒãŠÄKÔÔ‰m£UjˆP%M-+”ÛréÂ.¸Ëî²—ÙËŒÿ Ë1½<{’/sNΜï|ÿ÷ÿÿa¸³Ál…¹JÈ’·:ÀnCx„ðjkkë}MMMN›ÍƘ:55•½xñâäøøø7´ÿý›Íf¯Õjíokkó`0ÔX,ÆTUÕ÷F£*Š"‹D"èîîÎÎÌÌ<å÷û/¢¹)qoGGÇ+ÍÍÍ<Çqj2™,nm­ASOØìì,úúú¾m£íÔnb”õ÷ôô<]RR¢f2¶›ìVk€®®®«ÑhôÐvR¶²Ãóïvvv¶Sˆêææ&“eDŽt: m®}µuF›§¸±E޳"™ˆ!—‘¡Eçñxª†††$ŠâC·©¦¦æm—ËòÝ\¥‚ÕˆŒ*/´=ŽÚª2ô|vÑЂ½$IªÛí~=|h(ØñNKK ‚Á îNåa´8¶¶Ó/¥2ÜßЈÓ7 ÜiÕ/Ê+ ²¹,(übÎêëëÍD|D#®$µ >ù*3Õ$¡½ý5Ô׺õ?9ŽaqaûöÕQø{LH%SEbÊ‘î55b‰à ‡ÃÓ)œ|ö| ®heV‹ žƒB wÚ£(*Ì6Qt}}>ß_tɆ¶u”ÓÊR#%ňÇãôs®pH)bçz»Ô¶ÖyL-¡ æ¢%Zl.Êúé¥åe¬­…`wºñÄуxJ F*vr¹òù¼þÍf³©JÞ|¯ñLšÂØzùlF#žÔˆy“Åö’ÕYaå˜ ¬âçÑiŒMPë*ƒåðVϬÃh¨)× ÓTrºz²â܃X]šGhîOȉøV^ÓçÚE!9•˜ÍSvyÁ¨µ+–papŒã©F3¸21žK¿ãäïãÓþ„#QJRŠêZ†¼ÂÒ¿n“ª&»¤8+ª¿Ð’—%| Ýx$'§U³­„ f+TƒÑYŠy¿©éßÈ?ê®|gFΣïc‡jÄñÇ1}m””ëyPåÕÌî¬LÄ×fwÖÿ@áÑ¡u’{ÿµ´ú^• •vîï„É**µ^µ¦ñIÅ&UJ»ß » ×Èý·{œã`  0;$ØK]ªxW¹fXÛÜZûidOÝl·4¼^¯Dïí=ÃÃÃ[‡9ŽºOÔÞ(ZR…Ív˜lA$R',ö2XK+Y|m)81ðu[¯öÃÒøe]±áùçZõM^?;7ﯖ3 ,b9¾“È °:ÊÀ¨£“‚FL­n.)§ IÇ|›‘•/¯žûàÌ¢ª¼»ö˜çð©^£èÞ/§’ÈçÒ‘D8øËÊõ‘8Á8©Èé{ŸÏe2™ ôƒ?çr¹Ûkkkå±±1Wð4ù3== ÀCÍÍÍoÐ^æFËó< æóù ï²t]W¿Å¸OùHÄÉf³_1Ðqœ/“““¶aχB¡w#‘È  SªÈš¦@LÓT ÌD}¯`~·˜ék•Je„Ù¼G÷ ƒ‡™ÎÓ´AÙ(KÒ®ƒÊAÞeZ­V•_¬1 y'Æ´ç0ÁŽR›{%-’MòÆò[€É[[[{¤=°“wùžJ¥FeŸÇ©ÍT$ânêbr¨Qßzõ¬êàbò.Òé´­€ £øöúú:Á…™0©ëY—§žQ#YÄPµ)•J!ÌÛŒäg»( f‡À¶m¥mý <ÓsË­XÞ¡P1`éUtF²¸?¶w+% RÜ’fdOLª-…IGG‡– d¥76ñÝ¥œ»Õ†Ñ>‡F=´×&k}~)ŠÏï@B¿Œg…€bb°á›ÈÌ-¥¥$e‘EŠÙÒÒ‚øøL?³ˆàýW箲 ÉÀÁƒÝ~Ø.Ýtq-Ä›}XËãˆL^š…3É2.:ËŠÇãàˆãÊ ƒÔÊn§|ú,?‹&³â•ñÔ§@/ܨá×ËÛg¦tF ηŸrøD é 夯RHÇ Àö\ÜÉúöh ·‚£ªØ¿V]|ø£¶ë2YTÊ58Î'“ÉäcdØ)éKWÈør4aê¬åläFTC]•P|«¡\Ó`ìÄ.©;ÊËÈHBËRçQ²Œ ó¶¶6´¶¶"¹™Á…;Íðëœ0ްۣ©ܑìÔ¼€²µôÿÂfåóÜ9ßìì¬ÃûsÌ/r,»(K7M‹Åbèïã‡ù’1~bÕ-•õà”«˜»Î»D×öø..W«N¯«ÐSSS•ááá«”à䯯ÆO¼´k쎎ˆ­…þ)´MÇB{‹¡ #öÄ}% "Ô°¼ŽÝï+©"®§ôOW'Ì/5Üe ¾ãÕ¦íÛz|—º_Øv. ë8³ÈáXÞÞ·x3‡é?¿Q‡ñÕ «zW`Yoyû÷£ÎæÒ±‘}®ÑÓ°‚(9EÜZwePªËië3‚¾- »ÿóþï’‰bÓ¡¸žeÃrlÜ9º¾Xð/5îýâIv²t˜÷„IEND®B`‚eric-6.0.8/eric/icons/default/syncNo.png0000644000175000017500000000247712342633755017207 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs¯¯^‘tIME× ( ÏjÐbKGDÿÿÿ ½§“ÌIDAT¥Á{LÔðïýî~wÜ!»ã€EPÔ’C1 Äœ‡Ä©H!烗K"$ ÄsPâ yH(šàÔ%¾Ð(0(|€J¼Õñ0Ôtm)¹Êµþp™ùM6ÝØåÌÕçƒñ6€mjµô——Hðì¤u*UXGHHÅüüëUU÷mjzðSmíÝï OuÌ›Z7|¸/*@ØècèíMMá­Ò¼QPÀëùù¼–—ÇþÜ\öðê¦Ml6«„ô=€Ïà¸\\ݱða^¯fgÓ²q/¾·”-æyl~+”m1QüvÍ*vgf²+#ƒ Kù¥N{²°Ç³88(ÊRÛ–,fïºuìÉÌ`ãiZ*€´ý@ð>Àxˆ=,ÔMôþ£%!žmÉÉl]–ÀÏuÚÆ€ÖÊ¿S¦À—ÒÓÙ¹"™Uc=~.Ìó ¬”.GuêïGó\|<ÏÆÅ±1z+Diîk"tsnnK^ÎÖåI¬çq¯˜„g¨6™\??º·qÑ|6ÄÄðTt4ë##YÁjÿWì¼ðT0µ&èuž‹ç Ó ï¼jLKÓ·§¯°´D-äy³™ ááü:,”G'gMh(¿ŠœÏ2Q؆§¶É„¼ú(3OFG±|„öú@+M›7ë/—ä÷uF˜Ù¦ٳyfî,îusúñc©äX¥q*›L¬ðs3`ÐvWû3µæy<6›y2¡VêRRôÝŹ–.ó›¼Èv£‘ßÌ âwÝí À„l`ú¾—=Yi2ñÀïG™€ ¦(¥í«2™XèÇõ@†Ø7gŽþüÊ$Ëå öøû³ËÏ‚,óp¾xã±dÀ©ÔMÃ;;nµ—1 ðÅD9ÎÊ«E:˼ôÌ–ã‰5€¾|‚‡¥g†?û|}ÙçãÃîW'q—§ËíU€7žHœ Dn˜ë r-0ƒ²´ò³›¥–8ˆ\+ %x,Ðou-M¶2v¼°G)e±Z¼ó`À«€€bµÈ€[Ôâ£e€ƒRE¡¨@-r» áFâæR`d¶Z´œµ“± `?À~•”EùÀ+kD!w·Zd¾Ü “ÿà s\,¸ËUÁ4â/õö2¶´¼f+e¾“|` `€•8À5ÏUq¯\–häLU;ñ”Vhåw«¤¬IXí(²à€½ÃdÜ⬈|`e`³ÚQ<}ØQä€Ùz›?co e³Ý•+$`5À€mv2f¹(ÂX‰<Ó´òsÇ< °ÌÕ†qJ鎑°¢°@.¬Ûá©âð4ÀOS]m®dL H-MH˜¹wåÊiŸ$&.ÞðévÏa÷ϨEÖ<¤S0Q#ï˜ØâYÜ!L!d޶}tR)e3À.¥”ÆjØ0ŽmF;'dΆ$à!wßÕÊ[g:<€@ üýÊ[?=!!!]]]MMM !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333443444555666777888999:99:::;;;<;;<<<===>>>?>>@@@BBBCCBDDDGGGIIIMMMRRRTTTWWWZZZZ[Y_`^aaajjjjkiprorrrtttuuuvvvwwwxxwxxx{{{|||}}}€€Ž•„†„…— †††‡††‡‡‡‹ŠŠŽŽÔú’’’’“’’Ñò”””–––˜˜˜š ›››œ¦«žžž¡¡¡¡Òí¡Õó¥¥¥¦¦¦¦Õï§§§¨¨¨©âÿªªªªÑå«­®¬¬¬­­­¯äÿ°äÿ²²±²åÿ´Øí¶»¿¼Úì¿ÑÜÀÀÀÄÄÄÊÊÉÊÎÑÊÖÞÏÏÎÏÏÏÐÐÐÒÒÑÒÒÒÓÓÒÖÕÕÚÚÙæåæììëŸÍ?€ftRNS *--../>@CCDITTUWZ[bbns„„…ˆ’ššŸ¡¡¢¨«¶¶º½¾¿ÅÆÇÈÉÍØØØÙÜÝääååíîòôôõõöûûûûûüýþ¥¯Ó_bKGDaf¸}vIDATÓe‘ÍJÃP…ïÜ›Ÿ6Mb¡V‹‚àOk‘váJpëÞðá| nܸÜ(êF­JÅÔ4MÚ›Ü;¦iÔ…g1Ãù8 à #?ªí­FcòO[ýçÍ_£­¹T°íõ_£ÜC^íVëØœ ž\ß g€åe÷è'i2N6Já ý²Ö1|€"´÷qW`ÚtBPÁá‘Æzó)ÎP†—McoÉ„›n‘vmÆÚ 2s]ÅséU_æiC‡Dnëºjµ‚l³2)°Jàž[µ†·„£RfˆŽMõhã‘H£H«”@K˜î…6Ô´< YÃ3éƧ# ̱©(”Q]Š”‚"‰b|ͰUYQô’QÖŒõ ŒÇ©Ÿa «;ûˆ˜H½$ù”ó$‘ý«'Öéviv 9•‚Ï`ʪ{’Bϱ* À¥BR¡:U¸GŸ`ªšfWjv=»?­=øQñdþ†ŠnÔëðöþÅáßw2é¦ ~0-Ü7%¢˜u´›ÍIEND®B`‚eric-6.0.8/eric/icons/default/watchpoints.png0000644000175000017500000000152312342633755020270 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<ePLTEÿÿÿÛÛÛêêêwwwÿÿÿ¢¢¢°°°ÿÿÿ”””ÿÿÿwwwÿÿÿ†††ÿÿÿwww¿¿¿ÿÿÿwwwÿÿÿÍÍÍøøø°°°ÿÿÿ”””ÿÿÿ†††ÿÿÿ¢¢¢ÛÛÛêêêÿÿÿÀÀÀÿÿÿÔÔÔ÷÷÷–––ÿÿÿ†††ÿÿÿ®®®»»»üüüÚÚÚÞÞÞííí$$$%%%'''(((***,,,999;;;GGGHHHVVVXXX^^^___cccpppsss{{{}}}~~~€€€ƒƒƒ………ˆˆˆ‰‰‰ŠŠŠŽŽŽ———˜˜˜   §§§©©©ªªª«««­­­···¸¸¸¹¹¹ÂÂÂÆÆÆÌÌÌÎÎÎÑÑÑÒÒÒÖÖÖÜÜÜÝÝÝÞÞÞßßßèèèéééêêêëëëìììîîîïïïñññòòòóóóôôôõõõöööøøøùùùúúúûûûüüüýýýþþþÿÿÿØK»ú-tRNS  ))00VVVuuvvxxzz————ÇÇééêêïïöööþþþžª´'IDAT­ÁMNÛP€Ñï]_?Çv’Z„&Š1ª:a¢°ß®¡Š²f‘:ëŒH âX–ý® b œÃGˆ€h”IË»lè» ç_¤¹-y3?OlUn‰ÌoN‹ñC̾Í>Oþ×0¹žBr\ÄÇ L¯'ˆÍ lüeÅ¥2˜¼¦Wô?£øþS«ô¡?ãªTC¹Qx?QM›NcÕTÃß ³AæHŸûÞB2ÑT³ÑS®!®"½wÝØœÓÚ…£6xþ6v_×±ÊAZ;iÝIib`iGNÐNê…ù@u;õYÖ›-ji* {¶ÜÀfiaO«FX/<Èø±æq,àk"ºö߹Ͽ—ìm]ÄÙ» èPšŠwybÛŽñ áygó>™IEND®B`‚eric-6.0.8/eric/icons/default/fileLinguist2.png0000644000175000017500000000164112342633754020445 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ 2z´ÁÊ×PLTEÿÿÿ!!!999………†††‹‹‹’’’îîîðððÒÒÒW)i/|8™:G'}GÒaI(Êco=!G!É`$ÊS$ÔM%]5%Ác&ŠB'Ë]'×D(D2(¬W(ÆQ(Êe(ÒX(ØM)µd)×b*J3*~B*ÀQ*ÐY*Ög+Ák,’D-ŸR-·T/Åk0^>2¾d4^A4€I4¼T5©a5Ïo5Ñp6¼b6Îh7K=7}N7Íi8vM8¢`8´d9µM:„R:ŒU:¬h:Ìq;}Q;Ép;Ír;Íu=Ís?±_K¯YL‚[WC}`tibTxd¨fjgr§CwžT|–d~f¦‚u„_Á…ˆµ˜©‡‘u¿‘}±—«›‘«›¿£œ³¡—±¡­¦¡¹©£—·§Ã¬©¨¬¬¸¨°Â³¸Ì¾¹¿»ºÀ¸¿ÉÀÁËÃÃÊÀËÏÉÌËÍÏÏÏÒÒÔÓÓÓÖÖÖÛÛÛÝÝÝáááäæäæææèèèêêêëëëìììííííîìîîîîïðððððòðñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿK tRNS#&MS\l¦¦±±ºøùþ>ôz#bKGDœq¼Â'/IDATÓm‘ÍJÃ@…Ï™LRh±¤hÒ« Å7ð|_CPp¡/ãÊ¥ àNÁE…”.*ØFÚ4™™Œ‹fJ)žÅ]¾9÷ —Ä’oÇ,V€w« (‡¸ò$d ) A€Ö! U’˜½°þ5iœ²´!8¿ýþy+«‚€XÓóø5hÊÅsH-MoüÑa΃ïx¿BÂ…ð±Û´iÛ„2Žt!rª§óEÞ]b“}é¿ÏLú9%¹iÂ'/µJ´ª÷è>ÒVÅSµÖ>úÖŠ MÙšþáñ‰T…•ŽXköºýr¥ÍµµŽ¦è\„‘É—Þ½ÎJÂaò´«•){s}ŒÂ(ŽïRåV–²¶xÐKå I‚ Üä™rÏ·ŽfµÞNÝÕ&^f 4›ËbIEND®B`‚eric-6.0.8/eric/icons/default/fileDeleteList.png0000644000175000017500000000240112342633754020616 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYsvv}Õ‚ÌtIMEÛ Ÿg!ÏbKGDÿÿÿ ½§“IDAT8˵Õ{LSWðKJ²¿f#‚Kèæ˜°…¶d›ŠŠnÈtTØ¢ÂDÇ‚ ¡…ò–*ÓÉKF„Éd3¢ƒBA%P iË«åÕáõ‡“ì‘ï~÷fí@ÿÚßÜ›s~çsOÏ=§—ÀüYÓpŸa¶v0L+{}Þàj×v9;O.µ·CÆçë6Â9ÔÖVkª»Žn`òéÚU…ìí'æê~ÀBÃ-è¤RÈhàz¸¥bX,Âhz:Ÿšˆ¥°ÇÍmjáÇ:Ìÿ\SU%Œ” çóWájm­‹¡‰:…þà`(ÃÃÁ>¤ÓÎ΂sÅì:ÍݹƒùÛ·8Ôðm E…\¦¥ùè´±áp3ª“¤c4:‚‚ 8t=û÷c &ŠÃ‡ÁZ¸…´1ŒvŒÌVWq ¾àfr²aÈÏÃt~>d¶óxÚ)‰ºØXhŽ* J?? | uBZy<]ËÊ›qŠV›—ã•è ICŸ|zöJøtV¦ 't”P5¡ê ºOIA‹••]³+؎߬¬´S0]rèÌé8è£"aŒ? CL &…Bè÷Û‡qa &23Ѽb¦ÏÜÇ¿PÁ¯ô“…—a”¤Áp*†°/`:~úÀ@èÄÔ¾½¨¡±¶µÑK⢶Òç3ÞDÛg¶´sô¶ÇŽÂD¨Éßâø¤5#¹F…+Í(¥ÄVâCIÌãÛ­l×…"¸ÖlìÀÌìÙƒ9zû‹Ÿ‡¢ä\ ÂÎËPبCvý0Ò¯kZ«Fòµ!HnŒÀ3±.Á—„ëΘEo2ŒNåë‹1GG謭¡çñp/6{såiðUÕb¿{„ÈòA„— ´D‰ãÅ îþÕxÙs¬Éq JÑ)ví‚ÊÉ #66˜$ØHðö¤&Ä]Uã¡føsù¿üõÄ’Ü›#øøë>0!ÍR ZChm·nô9;CÁçCC0;cÓæÍx=¹!¥ƒ~£Ä'—ð/臟´¾çúðAN/¼³åx7£ïçÈáß9bAk •yyᾋ ÚK²µ…–PõîÝØ.@ÀE%åSøãñÒ:YDLµ ng»ñ¦¨ço¾FÇð¶@€vOOܵ³ƒlÓ&t<àà%¡5´ý^IÀŽÜ~¼“Ù·Òz±-UŽ×ÎʱM$Ç¢^¸S›€Ú\Säx1®k™ƒ+hÆUt0ZwîÄÝ-[ÐJøCB»i­«é(³ýÌIZ»“]ˆ¤Y=Y0àñüê,S[Ê 5WÃDvuXÖ˜\Ix‹·7¢ƒrõ_”í÷8qLáQr¼”Ô­© Ò”\\èžmcû¸DËO¬Ú,RNxƒ‡*èÿ¶bÅ1ˆ ûˆ‰S-½œ<÷¬!ì8¯†ïE /ºwÏ‚}Ò ˜/eLL¿Íš}\LX­yñzŸ›„ñ÷ø ýÛy|V>Šˆïµˆ¨ÒBX6 × 5xñj“0fÿÌ#½áG2^åÀÄ«3^8£Q:I†§,òÕ­ÔBá™ëþ ¥ºjdßýIEND®B`‚eric-6.0.8/eric/icons/default/sceneSize.png0000644000175000017500000000140112342633755017650 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ0 vI$‹tEXtCommentCreated with The GIMPïd%nDPLTE¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀ¡¡¡§§¨¸((º’“ÁÁÁÈ45ÏÏÑÕÕÖÚÚÚÚÚÜÛÇÉÜÜÞݵ¶ßßààààààáààââÎÏââãââäãããããåççèèèéééêéêêêêëêëëëëìëìììììììííííííîöEöö÷÷g1÷÷÷ÿÿÿ¨O¥/EtRNS #*+128:>@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜bKGDkRe¥˜ÉIDAT•Á1NÃ@†Ño~Ob#@ŠÈ!¸ÿq(( Hƒ0²­gð® ixëìñ¿>|ûœf,’œ6:ùØ¿ºÅgü8÷ÓvžÒ£ÜŒ4ÞÐpÚdOzêIT3:ªxO害jh¶ªÛ¥sá«Ph$šéPD#V* ŽÄ*p‰kä—ø%qî44á&NAãHâ¢D¡1…ÆÂiÌ<3MÞòf2Žfû»Ìt3Y5H2é…1ÓÂTYT‹oæQ¡TæIEND®B`‚eric-6.0.8/eric/icons/default/designer4.png0000644000175000017500000000220512342633754017606 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB7ÇMS pHYs  šœ*IDAT8ËÅ•kL“WÇ›}Ø>˜ì;îËÜf¨Èµ•¶@32PfêÌ'‹Ü å¶‹îÂŒrCƒ0%ÆŒ ‚3J[°•‚€ TÄ6€ÜÂF£N‘.ri¹”¶ü÷¼…Y²d'9yÞóžs~Ïå}žçåñBÜ^%üÂwOl×'©üû“Ô¢¶$•èÍôD¥É­2åŽM¼=v¹yëðV¤hÄH¾"f2õª„Íäz1l#f’Í$"ùS¨ñin¢õ Àa›û%¹H%h¢RĤöG|­/â>©׋V¦h— Ïæ |οó"pßS0•)…ø¸B€LÍ!ë?ÅW ርñ!¥þ“ÂX…7;#¯‘BvÇk]p JT rÒÊN-\NKÀœcå·Ž#®Öá§…¨6þ‚ÌÆ}HP –½S‰<×§‘«{JùÈ(Ë7Æ&{ýó^´š:ápÙqDì°/?´Å!FáµpŽÒ¯ŠÇÇu“Ïs±»t3bN'³õ)õt t±çËm´Ç“¾/·8U³’c˜>`—‹ô©8X鎈üý,$õ·4¨lS°=ƒ¹y­ÑçyPj œ-Å£ÇÙåí2º¼ ïç†. mø>/ý–íe5G"Zá¹PXþpûp 2ʱ=.ÆñJ²–¥§˜é5VÛgpºÏ…"à¸æñ‡OB‘†ÈK|„¿…¢ñN—e²½üë±Ë`²8²êm>‡™·:Ší7˜ê6Þ_´Ú„Ï|jsÚg%¼ÿb þÚÔØ¨ƒËÊ•ïÿ6þ™Þƒ&O¾ŒYIEND®B`‚eric-6.0.8/eric/icons/default/vcsSbsDiff.png0000644000175000017500000000236412342633755017765 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÝ1 NrQŠ!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“TIDAT8Ë•UÛOcE&þ>é`â`"gÎÊ UPw’/3g¾ù}3óÍoÎÔÕýGijjz©­­íöööV Ú¦}uÏ[Êåò ±X¬q}}}*g …B©R© T*áèè´Mû(GÇ$“É7iÌ¿Šº\®f"ú;)8<—·Ï?‚ÉdÂØØäryH‹ÅNFƒíP 3wfp³ã&Ø.žC,‘ã/lv'Bdâóx×Òúå*¨ÕjˆD"§ <445|àÙ²•ÚÃ/.–i;¤Š[ˆD35| žÇÝ97,“6t÷é`±X¨;‚ðàà`@¯×#ˆ ùÞ$>úÉ?DøýwÁ44À1mƒH:6¸îóϰl2ÃßÑŽÇ×oÀ{{ó‹›Ëô v[·a©Tú€n#Ž£ÈxPöyA’Ƈ¨Ã v= ¹Ò–ìè˜p…l'ä"í9DƒI°¾}(TF(•Jôöö.ÂÄߘÙl&V$ø-®<^Aý¥4¾ÓˆË—.ãÅÕ—!Óê‰é3|ý_üÛí†rØŒ0›‚m ±øñêë_Ôð*­sÿÉäÔ«ôpÊå¹¾aäòOO¦‰qÜ2þ„h"ËÞÉI™ø]Ë›îT/|A,S³»"±² –ªŠb‰º*î× WJ ÑàÚïaš%m$2 ¤ýÃè!cºÅÊ¢H¬.|{ý»ÝçzéÃIPßÜÜü mÿŸÇôOÝèàts¢'oIEND®B`‚eric-6.0.8/eric/icons/default/namedreference.png0000644000175000017500000000025412342633755020670 0ustar piotrpiotr‰PNG  IHDR©þã#PLTE@žÿÿÿ-KÎtRNS@æØfBIDAT×c` ˜”[0(€˜å†‚âe@&[¹x9Éf `Š ˜¢&È0° s!æ20Alc"ìDÌ£”ŽeOÅIEND®B`‚eric-6.0.8/eric/icons/default/transformResize.png0000644000175000017500000000236712342633755021131 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs „ „ªâcytIMEØ ´3Œ©PLTENNNb ÿf¢ÿl¦ÿuvv¾¹¹trt[‰Ï[ŠÒ\‰Ï^ŒÓ^Ó_Ó`ŒÏ`ŽÔ`ŽÕ`ÕaŒÏaÕcÓdÓdÔk‘Éa‹Ìb‹Ësƒˆˆˆµ³µ¾ººÌÊÌÍÉÉ»¼¼ÃÀÀÈÆÆÎÎÎáààéèésttº¸º`bb°°·Á¿Á`deUVVhhh¾ºº¯®°ÈÉй¹¹š˜œ Ÿž¡¥£¦§¦ª©¨ª«««¬¬¬±°µ¼»¾ÎÍÐÎÍÑÏÎÑ—˜Ÿ«­³ÀÁÆÉÇʼ¸¸Á¾¾ÆÄÄÌËËÑÏÏåãåæååÌÉÌ¡ žÑÏÏ´°µ¼½½ÚØÚtqnhŒÂkŽÂggbœÀ¼¼ßÞßaˆÁbˆÂb‰ÂdŠÂEJK­¨§ºµµ¾»»ÃÁÁÈÈÈÕÓÓèèèðïìÿÿÿ`ÿgÿeÿfÿeÿ kÿ,24,€ÿ-35-45-ÿ.ÿ39;5†ÿ6;=7‡ÿ;?A;@?CGHLNPOjZYZ]†Â^†Â`a^d¢ÿefcg¤ÿhÂikgi¥ÿkŽÁlmjl§ÿn¨ÿp©ÿq«ÿwvu‚{{‚~‚…||‡€€ˆ‰‡Š†‡‹ƒƒŠŠ‘‘•“‘—’’—””™™—™š—žŸŸ›œŸ¡¡¡¤žž§¨¦©££©¤¤¬§§­§§³¯¯´®®µµ´¶±±¶²²¸³³¼¸¸½¼¼¿»»À¾¾Á½½Á¾¾Á¿¿Ã¿¿ÃÀÀÅÂÂÆÃÃÉÆÆÉÇÇÌÊÊÍËËÍÌÌÐÐÐÒÒÓÒäÿÔÓÓÕÓÓÕÔÔÖÔÔÖÖÖ×çÿØÖÖØØ×Ù××ÜÝÝáâââààãàâææåççæèçèèéééçåéèçéééêéêêêêëèêëëêëëëìëéìììïïîðïïðððñññòòòøøøùùùúúúûûûþþþÿÿÿÆ1etRNS  --/3379>??EENNbcgkqŠª®²¼ÅÅÅÅÅÅÅÅÅÅÅÅÅÇÇÇÈÍÎÎÎÒÓÓÞßáòòóõöö÷üüüýýýýþþþþþþþþþþ¯XrŸbKGDâÆžVIDATÓc`@Œrª*òlè¢ Zžîz² ,ÌLÈ¢êaI‰¡ÎŠ íÍH¢2þ¯uQb(Ú“ƒe÷:stãÊ8We†ÌÔ ¾@ƒpLJHû(ßËû6­Xï¦T"$Êc—|åÚùs§¶ž<°`Ò’µ †¬@á^Ûׯ^º°»pÖâ¾þi«ý¤ArŠòÚܹuëö‰ÙÅÙUݓ焨íª¶ypïîÍ¥ózJó*¦ÏÕXRýèáýík–/œXž­ uHõ£GÇwm[·rQWY%̱`Õgíß¹yjí„#– Hª/Ü»cFýÌÓU#TsûlÙ0¥iþ­G@`P­ÓÛºì.HðQJ \µT@°·“µ•™±‘‰©¹>\µ†¶8//?¿ 04„9ÄDD"ØÖÐÉ$‡’ u á’C(‘Vp(De¥¥£§ƒù€;zôýIEND®B`‚eric-6.0.8/eric/icons/default/unittestRestart.png0000644000175000017500000000247412342633755021157 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ.;®À¢tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ IDATÕÁIh\eðÿ·½m2K&Ë$±í$iZMm­´ŠX¡E‹ôÐâEð¨ô (xðàÁƒ(^EA=A(e6¥ìͧÄÏLîòG nd¡Âfƒ@¦”ôe8ÏÚ,·°®&c©/'ÛÊ `ÐÅp‡Wž$JFŠèÁåàÕý»Ãñ¢—: 6A­N¦ Y‹ Æ<Á½Õ4 b³ª š†â‚+Æ™î¥T˜¼/,¼Ôiu¶[uŸÀ$%p£ƒ–³§(žÎó}=6-°ÐÅqÛë'J–°D¿íð²ãè)¦'J½*' k¾…v(°Ý!ˆµAj¤©FF0ôÎF‹V¹™Ç¡î0Jf”678ºÞ=»k%y×N`L=A¨žÄ“‡ï®8êúÚsýêþlAªí׿t}øòÔ¹¬›æòáAGĆqZ²…tG 1ªí^P=…¥XâÛN­½G±w×ý(d `”¡é71·x·.þÓ¢-ÛGWOx)ëg  sNXÚØNa[·Ö)¬œƒ±RB|¾ì!;†=Ãet—AAQ,¡<2Šüɜ͹°·/}Ž.Ï£‡]ÄsRêð˜#ˆüQŽ(ôz_,2L[cØC-LÏ\Ãìï3Э02ŒšÀäè$˜L¡”E×|e£¹¸²Ýn4¢8cSÊü0KpsÕÀÀ#¾ßâ0Š¡º^ŵ٫˜@Š3=YäÒMPᬓuTÃ*Rƒ¡k¬ßj5ýtºÖÑÚJ'îøÅ|Ucj<¢«ð^%†¡6w6‘líàL1‹‡¥‡7;H ØCüªK«vü ]E7ýH-ù‘^ÝñÍVµn:s«FÍUµÒ†ŠÍzB¿©ûdc«Ž†i€[¹:1Í5¥æãÆè*ݼ’VØÏ‹ñåè«þô,G×òv\å ÜfÇâfÌE©‹RÓ7S {7¶ŒqÌc¾+Ô€BÚCpi1jx›ñRmD…µa]‚¬Èº¾š3ïõ Bp¬Ø9ÚG?J÷J–ÉY(ÇÐm0à $N}±Ä?%[êŠ\QW0‹6ã%§ äûžÍÛÄ- ãpEe=ˆþdE—Z×c×å/ ÷jA:ªn¹’{‚óƒv–S=¢ &ˆZɼ²Ú Ñ… ™|†óX!ø¯žÇ€[§™KOQH¡©ŽÍ´n˜/“†ú@ çaþ—J(Ÿd$IEND®B`‚eric-6.0.8/eric/icons/default/issueFixed.png0000644000175000017500000000235512342633755020041 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs „ „ªâcytIMEÚ079lÎ0åPLTE+A,F /G:Vi¡+j£+m§-n©-)<*:p®-o¯,': (;(; h¤'(; h¥&lª)l«)Jc Vp ˜¸o›ºs0 1 2 2 2 !3 !4 "4 #5 #6 %7 &8 (; )= +?/F1H3M5O9U>]>^CdDeFjGlGrIoIqJpNr Ns NxOs PtP~QuQv QwRuRv Rx Sy TxT„UyVzVzW{ W|XŒZ~ Z~Z€[ [’\}\^‚_€ _…_†_™ `…a"aƒ$a…a…a†bž cˆd‹dŒdž"e‚0e„,e…*f…-f‹gŠgŒgŒgŽh‡.hˆ(h‹hš1iŒi«!i«"i¬"jˆ-jjkkl‹-lŒ.lŽ m.n‹7n.n’ n“n”o‹=o”o• p‡CpŒ:p:p˜q•q–sTyb¼mÎæ§?÷Ü©2©Œbˆ1¥4ZiÔÔ5 œ£ù ýˆ2û˜š6IEND®B`‚eric-6.0.8/eric/icons/default/spellchecking.png0000644000175000017500000000211512342633755020536 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<õPLTEÿÿÿ€@111€++€++ª+’$€ Ÿ 3™3‹.¢..¢.•+555 ’.1110“.–-DDD™,,,,111•,111CCC=== :::6¤-•- Ž+***3¢,.¡,,ž,:::#š+'œ+™-–-***222:::  -DDDDDD2228>9;;; ;;;w1 ˜,(((”,–,“,‘, +’,“,AGC222/ ,2¢,'œ,+ž,—,#š,”,—,‘+“+((( .::::::DDD((( CCC‘,“,”,–, ˜,333 (((;;;;;;z2#š,222;;; , , ‘,“,”,–,˜,#š,'œ,((()))+ž,/ ,1112222¢,;;;DDD‹Ô—‘tRNS  !!""###$)+,.2455<=?@EHKNORTXXZZ[fjmtyz{{||}}~€€€‚††‰ŠŒ—™š›¥¥¬¬¬¯±²²³³´µ¶¸¸»½¾¾¿¿ÀÀÁÁÁÂÂÎÐÒÔÕÖÙÜÝßàááâãããëëíîîó÷øùûûý/›ýù-IDATuÁ;BaÐמ]”½·ìMöÞ’²÷Þ{+Ù{»¤‹…~§ï6êƒ _`¡ã¿Õ-ã×¾°K¸`]øÑ•S~Úž|sÖ¶Ú B* ‘êõúÍæP$]ÜÞ6ÂÀÕfÎÃwD!ÎÈV Œœ‡î‰E.ΨR¹ –à’Xâ‚È vB8ö?ón0¨y$vÃà4ðH,¸Á¤ZEìGõªˆw|©PWjbÖ*Ÿ¦<ðMÙ+kšÂ¥Z­v‚Â/%ï“þGÁ’5Ï'(:>%=+;#51.&Òß›goõ Æ—deØÜ©IEND®B`‚eric-6.0.8/eric/icons/default/stepOver.png0000644000175000017500000000027312342633755017535 0ustar piotrpiotr‰PNG  IHDR©þã#'PLTEÆÆÆ@/`?€OŸ`¿s߃÷ÿ$“ÿ.—ÿ7›ÿ2ƒñtRNSv“Í8AIDAT×c„öòTG(³”```8½²=ÕY‘A¡)I©˜ Œp7¤2Â]Ve2 Dáj‘ØéÔq̪IEND®B`‚eric-6.0.8/eric/icons/default/pluginArchive48.png0000644000175000017500000000636512342633755020712 0ustar piotrpiotr‰PNG  IHDR00Wù‡sBIT|dˆ pHYs11·í(RtEXtSoftwarewww.inkscape.org›î< rIDAThÞÕZkŒ]×UþöÞçœ{î¹¹wÞã±=ÇÇ„£$JÒ‡§î´ü@üiª‚x”?„$Tˆ‚QTT„Z©DEÿ”®*A@*¢P§1}¸§Mýˆ•øÑ±=Ïû>wîyîµøq_çν3›4…;Ú3{kæì󭵿µÖ·÷ÁÌøÿü1~“^ûƧsÊ‹ž“À² °8ÏB½räÔÇWÞîw‰·e^|QÞzF>©•ZÌËží^Äy|Þ`¼²pê¯àŸŠ7¿ö ^&Ï(î÷YfAk]úñjéûŽm½\Ì[ÿYÊ;?xöÙÓñOÄ€ïüÓïå'Ç'N’’Ëx?„XºÙu·…FÓ3cª³†&‚&Ý$_ ˆþ;f}>rK¾þ»g[§™iß!ÄóÏC¾wvÉ8yêCO¤Sö)–âýâ)qß1CÌXݨ˜uldlÒM"‘é~_AkŠtÿHëø<ëèår½ù­k¯¾YÅÖe:}Žã>÷ÂRêÄ“§ ù±_4 cÙ2SO )óÿÛð¨Ö[ØöH!03‘«»}¢!ðÉ1uŒÔZs…+QÇm]üõß8}ÓÌŒóŸa–qñÀÜDQ¼ ™!Š5ÖK ÀäD¶Á={×ãp"nTR™X_¹rüW_<÷º¶-–V«nñÂk7qtq>4!ä=ß(»Ã¦aàÐlq `ï¤Ìà;c;;aXˆ|Íúæ`ˆ@âÐL sEÔ›>¾òõ×àd2xú±Ø–µ'h/ˆ°Uv³SEX¦Ê6{× °Iðš ™â,„2zM¸å»ˆÂD„X¢g€5×GèÆ”SÂ{?Š(Ö¸xéÇHp(ïczb0înÔk ;eáðñ]S%i¾ ø^W©,2ÙI@H­:šå;`Ž:V›žƒÂø Zî]86Ã4;6!b¬¬¹xs#FÑ `§-g‹0”Ü3Ï‚ïƒæ»ŸÊM!•™3ÁoÖàVî" ¼‘@PHº-FýÆUd qðø“°*ßB&‚”Àá¹"¥DÍ•¸xå6?ðˆa@¼îpw”ÉŒ‚•‡Ž#xnnù¢Ð‡ÖzpŽ„Âä ŠÄÒ„‹jÝÇØÒ2.¿ú (š(Xc(¢†.ÌBÎÆ©gŽ!Š ?|ý=rFýG˜,fûàw¡ÌN¯3ù™£0â0@«¾ÆÖ â8ì¦Ì]Л0 -`)¤˜šÈ`õÒWMÅxð‰âÒ•=*$›©N<1§ôƒ˜‰$q[V-ÎåQª¶ð_þœxø6ÂiäPF6Eèü ¸c¹‹sEHÕ@Uåðòw¯ã‡ǔڀx̰Ǜ: ÃrxuÔ7®£¾ykg¡Jß»f°Ð} Y¨o²˜†ã˜“¡¶¶ ·¹…!Ô7C‚ARói¼ïécÂ.½QÂϼç#¨]} SóÈN0Rše”ï^†[¾Ý+L£ÁSfg¥ö'Ò(KAw µáÙ–›?üw¤3¤ó3pu9®ƒÀª¿ÜiD ¥€”eàñGÀ•oÂ0ç­úÜ»WàVïîYeߺàõ)*uÛ)„ÄŠº“txΤqd¾€’o ãxãV¹ý{&lT}Tt±&¬„ X+{¸½áb3žc­CH¹é¶n~ë׿=|7®zYi'eùßÓHZCR(zALjèx' EYAµZÂÃ'žÂqq° óØö5¶î¾  8D½%E!üôC¸v«@ÀoÕw‘;Þ¥»’z¸FŒ*x‘ìk’DÌÔ›¤kíTÁÁøÔ</Á“ï~µm Q8†µÛ×q«ªÀ­ ¬¯m"›6á6ʨ4<ň¤€AÄ/랶滦ŒNx}„Ìð“1 IÉ03$'ˆ-RJTJk ŠF1ffgñ½oŸÇá±,R˜?R2MLÅwáX\zõ¿0^Lƒ(fº¯,£GÈìdÌÈú…ŒˆÅP£[Ð,C ‰XGÈfóPìáàtRH°f()ÀLÏ9Rà='æ!¥D¬ Ôß>ޤ Ý‹¬NŒ%¡L±ÐÜ_NÒqÜ.(Zk8NÕÊþí_^‚)rñ€&"Äz~š LmöO™x=L™$x $…­X4µS$ •j:ÒxôgÃu뀑‘'¾ä@™c0Ø 0 nfÞR#íB™î3=Í%ÚBL2Ú@c"ër€à¤‘ɉ"¶=’¼6]šî4Ò îRFÓPÊMÝ÷úðí¸e!Dg“.X ÖÄà6¯ˆÛ⌙Ѭmbkc‘B¦,x‘êhòN°'<ß] AGRhG•‘evòè@v Ù‹€ÐD29©Öƒ²wfn¯_½ŒVà¡Y­"mÄýUê¤ÞX4'éÂöfý|Ÿ¤Ìîà»ò§/æ d EÃ\ÛåÛ(ŒÍ¢VÙB¹\Æâ”¬ÝÎZlÛŽ™¸< Èн,´ÿ“ˆA£w=Rªo1ƒcÉ!ì©â< C¢PÈâàtauÌíùyצu»8vy|/”Ù <Ú~êpbÙã4xŠß¸ØœFQ¦PmUa#·ãÌ êd@´K¾æ=U%Ýøníê­@L¬4Ñ€ÖOšàŒ/@)$allª¾Ýñ.÷š”K1C*NðzÊ )Ñýx^Á²3ØvK‚™Yž9†ÖÍ2:-6Voa»ÅÖWo£ì ¿t q²?\e“ªr°Êî^¶“‡“+ Z$ öz• è8 ûÙ¡£5i¤& e*(e`þÀ, é„ÜMnJ¨_z¢Mï­*»2cäù­JÁ²䊳`"Ôª[~½±ýGÿæòzª·ßÌd³‘çm›íÐP}ëÐ,Ý‚°g Œ4<·¡ S*¹¡á¾”ýNW–¼U•Ýí„<“+ÂL9h¹U4*[ìá+¶QùZ¼½ù<³ƒ™B\úËß›I™Ç?WȦ9ŒIZD€2É/Ât …ââr©-;F4…·ðz{< ¼2 8¹ h£^^‡›¾Ž[”·Ïýñ?ß®'8^ÿÂo>`¯›éCéôØßær™÷ÅQ$„*M 6Æ1>;ƒz¥ ‹·1=f´·ÛD¿/:?MËFµ±Fy}äff7Ï[¶‰V³zaøwa}æšmõK_BÄ;pàGÿñ¦Ì_½î•V?¼¹Uz·D”2¸QÚÃÀìÜ2¶Ö?ÉP¨ŽwªÊÝÁ·U £ÕÚæJµvÁ×Ígšˆ>a›Ë:ljH˜¦¥FS¨Û”‘B¥á¢YÝêïe‡ÞÇ ¢XG^}¾Æµµ­~áå[ïãþk_wdBqæùGL'gMj¥ÞN§?“Ë8G•¢íuÑó¾HÄiX¨ÔšhÖ7‡Ásû[¨‰½ ú~¬¼¢†¸’~ä†{ú4Ó~ï$öuçÕñD(„X{á–Êãã84ýwÙYûÓÙ¬³¨XBuDˆCtN9HÇ ŠÁs[ª1¼@—5ë?á@¿d¬-lýù¹sñ½^ªÜ×5«B|ôÙÅÔÒÙI!pÒÎ8ŸÊe2ó–¥ …‚¡„’PÊD¥æ¢åVúâ„AÇ^Ñ’á'uÉ[=ýÒª× áwö¢[!Î<»˜2çÓÓÂ6–Siû“…lvÆ´ HÄRjuþvÌ„ ÒìûÁk±ÀèØ»x=Ziœ=Ëú§~S/„ýÌA;:–ÖÂú%Û±þ,—ËMض…¦ë¡ÙlÀ ‚Zò§ _ñ²²¶Îž½þßùWƒ„%¸<ãæ¦fØÀ‡íTêãZ³ÓôüµDóO¬dÜðî%HßY’†üÚŒ3•š)xÍÐðe«ñvÐå3àüüFì…<Ÿ²uIEND®B`‚eric-6.0.8/eric/icons/default/method.png0000644000175000017500000000067412342633755017213 0ustar piotrpiotr‰PNG  IHDR(-S pHYs  šœtIMEØ Ä ÁtEXtCommentCreated with GIMPWŠPLTE     dddÀ¡.£/¤1̺MͺKоOпOÒ°4ÔÑfÖÓg×»?ØÖjØØmØÙmÛÛnáÎUâÑXãÐVæÁ9çÃ<ìËBìÍEîîwõÞY÷á]øã^ùã^ûédÿúwÿÿ}ÿÿÿÿ‚ÿÿƒÿÿÿ³,®X tRNS**,,.BB®“wbKGD-ÍÚA=|IDATÓÏÙ‚0…áv .Y\PQvxÿ磡à½ûOò%S!þ’Hþ´ lW“îä Øré[×}. Ö qÛ÷uÅÚÁ£jê,Öç¼x?š°á_.,)hÖ8ÇjÖ{L­‡{9iÅ—¼”5Ÿdm>µ6¦=ç ’}iIEND®B`‚eric-6.0.8/eric/icons/default/tCBreak.png0000644000175000017500000000116712342633755017244 0ustar piotrpiotr‰PNG  IHDR(-S pHYsÄÄ•+tIMEÔ /..Î!ÿPLTEVB()-.FIKNST' !"NPQ2367:;<B$%')PSTXY[]^`bdegikmprtvz|€„…•˜™<¬rõ>º­Lu¬^º Î$¢Liɽ}™äŠÁVTÖZd-’vͪB^ƒˆ”RI$f7à³ôŒCÏU.À –³»pá_:B‘rBkIEND®B`‚eric-6.0.8/eric/icons/default/languages/0000755000175000017500000000000012557365404017165 5ustar piotrpiotreric-6.0.8/eric/icons/default/languages/lexerVHDL.png0000644000175000017500000000250512060166056021461 0ustar piotrpiotr‰PNG  IHDRKÖûl pHYs  šœtIMEÜ ,5{Ÿ¦.iTXtCommentCreated with GIMPd.e»IDAT8ËÁKGàzö«º§gz×»ë]+Nœ%‡€¸bNŽP~@€‘¸p‰"\ø ünü”DŠHDQ„d…ãÈòkýšuÏôLOwWwUu½ø>¸(7Í&ä¼UÒ9ˆ¼=Gîy™¤Pë@Š1Ë €ÚY(x u^a” lbægÓ‚Ìçm·ÃÆhkô&qž'²ƒMcÞxëPôàáýWW¯æoü EÝ¿WÏyŒ÷ZIÐ5kRoÞ  D.Žs`’Mey ½7j”»Jâ·1€;X±çž=DzóÚtÖÚ€†9´^—mk¼Ç‡ÇûÆ‚¡Äz³­7­R£€=¹z4Ãîê>„°iô08´^mGÝ­×õ ÄÁaÑì¸c×uj4¢wrDRX)Ū´ÿ¾½–Ê"¬wMwr}6-²]-ZÞ“|šž\Gß./… Æ˜UÕ)©( a·mg¥qË ñå‹É¡d“ ïU!l]« B”Ääôô¡À;²®Úz«‹ÚÞ,^ „L᪔އ4Žú!:_È0`Z‘¦këmß´Žw].ç[=ZŒâfÇ寛з5ꇦãÎAU¯6uݶF ÆZ:*'”“=Ún%z\!ÔÒeÒ¯Ûz\kÕvÁdZ1´Ïu´l¹w‚âIÉ7e©¼éw:ôÐÜlu§‡„ÜùvñìÖ!$6‹®…Ë‹Mß|xó=ÑÙ½^T—UÏ9¡SÉ™à¡ÃÜxN¼í‡ùEUÁž|÷ÕüÉ/O´§B íÚl¶²MÆý$Àq“£$ ¸àM¿S&×zör¾-×W.^™GÏ›q·"€²—K £Væ»;»³³¥àpÇÈÅËÅ“»wÏÏŽž=¯=Nß<…Ëe½ZñÅrÃëžM €,KxíµééiÞ6ÐyÜlÅŸþø¿ß~ðéWß<±Ô(‹„Bä]»UÞ['-Pˆš0‚ p”2Òsòúõ+yæÊu§ ùðï›òçî|H ‚IÄ Á˜d£Ñ0¢, !°Ž’LÒhR–ålö³Ô9ˆ1 ‚ààx?™¶”ù 40(àR†Ž÷N¬Æq‡)Qݸ¤’Å…T[‚|[ Öâ`Coð:ÄÎRàã”…JÛ»,‘”°M½`ÙþÏñãüäGÍÅKeÞŽYׯVZÄ0` #©;@4 é6O×Ñd:¸ÐyãGwíõB9ÍÚéìàý_ÿð›ÁÃg(Œ„ðì­.2Œ1††1F ¤c¿å»ëfà¥4}çÖ›?9X,k2ŸœÒ»ßW¿ÿÝ_>ÿ+'+ÓÏ>~ dÑþ>–ŠÓÐåShÍ%‹É4‹ ·~vôÓ[ï:°+KMÒ?ºÿä{yöPdŔ칥à)Ó–ÅGž16zPb”`À¢[ã1ÆEnÿûÎwƒÙít@çÅ>ↄ˜(¿‹Òz`ܨzûôQ#„gù4ÝónUÃÀE¬HRÜúö›¯-ocÈ9Ç@K0Ê¿ÿ«? ²5ÞAäSF$Çåꢬ¤ƒQhãÅyôâÕ6eÝü)ùú_Ýí¾2NÓdµ¹L’I1½òi V*áõIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerYAML.png0000644000175000017500000000326312060166056021470 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDùC» pHYs  šœtIMEÜ $c•iTXtCommentCreated with GIMPd.eIDAT8ËU•]h”ÙÇÿçýžwÞÌLâ$SܬIÌ¿jÄ`1AÚTˆÄ^Õ5Ú%¢,»K Å ê–\ôb ´P¬°S)%©•¶:æÂ‹ÐµÑÝÓ74¨ù•™yç=çý|z±I ÏåÿïÎó?<†††—/_–°^DÄŽ?þ½ÞÞÞ_ïÝ»÷›;v ÔÜÜL½½½Þ…  ¹\îóÙÙÙCD´!Ãää¤7nÜøö`ttt:66ÖuàÀ/R©TYQ2M3L&“Q:¦¦¦&jmmvîÜž8q‚ÆÇÇßNNNþîÁƒ]ú\.'»råŠ4::À¹sçúóùüµ—/_¶AEQ ª*t]‡a¤ë:TUeŠ¢@Ó4´··cÿþýH&“ó¦i~rêÔ©¿ÀíÛ·%¶átþüùþ{÷îM,..ÖK’Ã0 ë:©ªÊ4M£u8t]‡®ëLUU’$‰µ¶¶¢¹¹ªª®e2™†‡‡ÿ ÒÆóóùüµ¥¥¥zEQÇIÓ4Š¢D´g†a°X,Æb±Y–…D"A¶mS±XD±X¬þüùx6›í…ˆXOOÏÈòòr»¢(0 ƒÀ4MìÚµ ,‹¡R©ü÷õë׬Z­¶(ŠÂ à MÓ ª*<Ï#ÏóX©Tz¿P(ü‚ˆÎÈOž<9ôôéÓ_ú¾¯Çb10ÆP[[Ëúûû188ȺººÐÙÙùàäÉ“¯®®þÉó¼÷cï©ªÊ Ã€išLQ!XµZE¥Ri›››û‡â8Î]×MhšMÓHÓ4vôèQ`Q¡R©ü; ÑT*õLLL|:;;ûÇjµÚi3M“c̶mªV«,‚ØÚÚÚ‡’ã8?0M32M’$±Ý»wãÈ‘#Ã¥R ²,ÿæØ±c_­gÌΜ9óuCCÃx*•B,C,CMM ˆˆU«U¸®-//÷J®ë¾gÓuétšöìÙ˲X¹\€R†_À­[·Ô«W¯*PSSóe2™\[3˲E8çàœ³•••E!›¦ "¢mÛ¶¡±±ŽãÀu]躾bY€x<e2¬ƒßAð/ÏóêMÓ„,Ëð}œsÀÞ½{'+¦iÂ0Dmm-3MÕjœs€çyß÷!Ë2@UÕÈ0Œ@UUÄãq”J%”J%!E„P2™LX.—¥0 ™®ë Üs¸®›ñ\×%!㜰¸¸!Êå29Ž"Ú„ú¾ÆÆÆ¥}ûö}Æ 6Çf6›ýáÊÊÊï}߯_]]Å‹/ù¾Ï„$„€ã8œyž·ÙSß÷‘N§‹¾sçÎ_@ššš’`hhèo---?Éd2ßlß¾uuu°m›•ËeضÍÇ®ë2Çq`Û6B0hjjZêééÙ„;触¦¤ÁÁÁ¦§§»J¥ÒÏ———433cÍÏÏG®ë²õ@áº.yžÇq`YVØÜÜüçîîîÏ®_¿þ5œ>}Zºyóf„‰‰ ÀÝ»wÿo™ÎÎΙœœüíÅ‹çûûûƒ¶¶6Úºu+µµµEÝÝݯûúú²ß'"eCwöìY úúúð?7©5vÑ 3ÊIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerDiff.png0000644000175000017500000000247712060166056021604 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ [ëØ7ÌIDAT8Ë…•_h\UÇ?¿sÎI&É´™´iW¬Û‡ j¬õAhA,lZÚÔª ‚ÊŠŠšÆ*ú$úPEPt%j³«UÜ݇]u¤ÔªIWÅÁ"VD-Jã4&igÒÉÌÜ{Îχ›iªøçÀár9ç~î÷÷=¿óû ‹c÷Ø‹fÇð­0ÿü׿/èî^á‚GAùå!‹LOÏ$7ÝxÃ@{Ñ § àð§GXwÉÅ<ù×g¶_¹ååL&3€bøuê]q£1±oß[7ß{ï]M–4wÜ9r_×=;ïø|Y>¿ªÑˆÑßC6É™L†rùTiô™ç/ÜýÜ“3rðÿï³ñŠËùìÈÄuùŽük! š =óS±NUŒˆÔ'zÖº ‚¤R)_¿öâÿ¾ÿÁ‡k-mm¹îL6ƒ kDÒ'¦£ŸÔ…Ê4T¦ñIÓÑ)Æ÷ˆ d³ÚÚrÝi‚1x¼ªbˆH{ž¤<‡þçaZ‹ÿCKÇRõ«Î£¾þZdh—ïDæ#¢ªx¯>œ.šBÀH.OãøQÜC›‘fˆ‡nQ½tKjÅá·‰^{Juü?t€Lß´Zþ CU1ÍSòÞ`£ˆ0?‹Û5Ùá¥/qwïAæŽ!sßàv¾@xéKÈæp» ó³Ø(JÁ‹ ÓT¬ALÛ2tï(2;Ž“ë]M8>Iû'¯Ò~äuÂñ£äzWããÈìºwÓ¶ á Ku ì½ãðåYН ×ì Û»†Úô ­—˨kÑmÔbj'O‘=g zͰFÅWðåÙôÛ³Ÿñ؇"DÓÒ¨Na/ÛJ¼ÿirGß“V›Q{êk 'Kt¼p5ÒX ¾áVìú«$#Ó8Z~â±kÞïC‚µØž>ˆ"‚‹°­94$ضl® É.‡¸FEAOÆZ4÷sÅ!PE]׿äØaZ·ßOíûmÔOž ÿÁÓ 0?øÙB/­Ë»¨ï} ׿uYPÅûð+‡„–B†þAÜÔgøÒ$ç­ÖÖÂJL¡OMWŸ¶är´¯ìÂ?‰›:¢¡–B„„šŸ ©Vcqk·A{eáÛIiYu>õÞuRï]'-=dá»It|Ú âÖnÃjŒªâÃRV¸°øü¢!!ÛÕÃÂÆäàsè¾]ÔV¯ùÃEÔÞÝ|SiÉÃÆ²]=h¼ªgòX\³2†àQŒs$qܹý4®|xâÑÌWøâÇé¡töÿéÏD›ÉtöêU¬s¨,Ý`­5*èo´ÇÇ}1MSr™¬·»£#¼|öl=‰ŒP*•x¡ã‰&MÚsãÂ…¾IBáâýVkmŠ\>bš\¾Êl6/.[»6xˆeçç…BËÎ{½ßžµÙ:¢>ŸÐårqž~¤c—ËEµ™Üìb šnúÒxjý¯jõR¢éJr}}}«%¬±äæÆèç¯[æ”æ÷92¥Aãöm[ƒgøWÔ~oM›·êË?ß©j¢ÇW¢‰D#ëêê .J%(AîhÍ”›v.+*ûbSRîRA R NÖ½²bG³zjQž}û–eA°,û0íæ¯vglýMp,ñ¥×ÇÆ¼mT<6'y<‚¢i‚ 9$ ‘þ`¨çþ­;÷n^¾nµî,Z2÷²ÑhŒ-7lÝäéÓ™’-[¶ KÜÞÞ½^ÏËFäŽÑ•]-™Zœ ¾üUÐâlt€tð3A 4D__>4Vê¦N8ªœå6l Iü`Ê7í˜µëæø“~·ý.}>q ŠÇ‡X• ¥Z¡AOJãÊlá„%F7›2'Ü|h›rÀa¶Ûí•Jõx°Íf#æ­X·˜;«Êd!"¢‘(úƒ!øïyáoo‡÷÷:l‰RR-ö9,XÐS]]ÉÈȀǃ`Üœ2S+#™ŽŽŸ­ˆGA$¸)Ä£ÒÁòÒ.m´ÞïÐjµP(ÃüÁN§“c>|ò57C¼<à¿s£þ\£Ü_ðY Ó–E$ p) „ùƒõ¦âiÛFc¼»»8’P¸h¾/))é_pcãÉÌÕND’òrpÛº·Ï}3#?ûº·«Kú—›™ yj:(‘¾ú<î¶)roeeelˆ’jŸo{³áۚ⼿wïÞ(‡Ãù¼ßR›T|”wê7Rp·u=ÎN2ÊtJ?ã÷0 )\|™ÍW,KŠÀO…&ûÁ“Þs/}T8¡¢ªª*NÀ,]gâçúqöÓ½9P¦©‘’ÿn\ž®fB‘Dðä,h.@Ó@<D4Ä"ÜCdÀƒP°´DŒ¬Ezt^kµšòÄÄ‚á³, ·Û ‡Ã5Ÿ˜&6Ž\ ‘*|™"¹\. šˆ†#`<ÝèlmæF‚i¿ªÑŒõ—””ô †8EQøù7|[;¶·ŽIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerCSS.png0000644000175000017500000000251112060166055021350 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ ")ç¥Y•iTXtCommentCreated with GIMPd.e­IDAT8Ëu”[¨^W…¿±öþÏ%Im£¹mT°j¡ÔkPÛ"ª/⻊P¤…àKŸ*"Và|(Tª´‚øè‹¨Uj ±ÚK*Msisr=99ÿåì½æ>üZ\0˜k.˜ƒµæšcà‡¹¹›_zl´´ý`YXØRÚ†¦)4mCÓÜ€hgùÕÑÃјÌ$ÃdMè6†›¯ÿÃb·þ½gžüñU=ðÐ7–ÖoÝûü¹å}Ÿ( ó4ó­›A£¦mhÛÖÍ ¨)…¦ŠðjM…£«ŠL²†c#]ãÞ·:zâ–ÕSŠç6>·ýÎSÓÈ’P‘UŠ)B’Ud ¾’fd;"IaƒS"…9T8¹sÿíß,kÍæû²4P$ QIHR@­†µa°$i4…IPÚJCoiµ]º¯M³É#Œ¦LE€™Ñr­&ÂEX"™@ØDxš§É46‹mÓ4Ójlftž±Ú0ªé1`$ÁBcRd §gŸ—ÓöD$v;P®¬w¼s¥cÒ¥lËGjûâ@ï›o¸^C5R[çŠv,4D¤"ÍÖ¹F{æa¢ZQSYMDªm[ÚÁ`Ž«Ãžë‹£dËÒ‡>µ‡GîÚƒmŽüãVûà‰}Ë„ÍSo\âŸk~°o™šæg¯®ðý£§‰šÔdMÚÒжmƒÒ`»öÉpX¹w×Í>rì4—Æ•¯Þ¾Í'=??q£ç¯sèŽÞ1×ò›7.ú÷o]åÑ;wóDŸŽ.ˆ>pŸ– ¥Qƒ ‹LI#´6 =æ¿8~NgW':°cI¿ý×þúïzóòˆOn[Òß\Õýϧn„j—Ê>‰¾  ‘”L+ÒD‚qíÓ/_òìë—ý£Îø&ÙÏÞÿQæKãŸ;K©á§¿ü1“…ºήÎnÆP”4„Uª¥H°•5µ¼8àÞ]7iåz¯/þòoÚ»iÀ·î^Ö¥õžƒO×¶¹¢oßs“Q§ìBÙÙ‡œI;ô¤dNãô%Éçv-ñà¾Ý|éCëüõÜ?üË}zßýüymeÈ‘çNñØ>LΤD’5ɶ¥ÍÌ©„"QÙÃëo¯ñµ»vQÓ¼v~˜‡?³Ì¨N]ÒOz=°Ìê¸çÔ…uܵM$®Aõˆ6jENJȪâú¨røW/ùáÏ~O;ç Ú¿›…Aá©ßöµqeõòº· ~zô,ADB„{:tðë¿p¼Ü±¿]\Ф« »°Jp)V‘˜©ÝSíÛØ"Œ3}cš¨i"twyåŶï:4g†×FLª¡)¸d¢’Ð47ÔŽß¿™Jtú3£À‘(+ý„v<³ÖMË”‚(8zkf8´2Þ»2ÆÆi£× é© eà¬îº ÚáÚê$–!áÄ™ÓV¤°dEÎÆdJ*±e ÷9ÝgLkmõãõIÉ•Wÿ4p?+3d@Ô)j…ÚOã»gý#f1œ´tøâ‰?7ÝxøòÎÍýWÖ·ì½5˜Yè õ Ìú˜9Ûû?â $o°{åw'/ž|é!,..î¹åý;gëGî¡´óü¿åÿMýÞaÔŽ+'Ÿ[½¼òñhtú߯¥^éÞ•IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerCsharp.png0000644000175000017500000000267412060166056022153 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ /+o"ÙIIDAT8Ëe”Klœg†ŸóýßÿÏÅ—ñ%íÚŠsiä–ª8Bi MÔq)7BB,P,Y€‚vÅ–vEB !R"n h)J –››¦ Jš8NìØÛgÆ3žþÛa1×À‘޾s6ï{Ϋ÷;x¿}ã ïÜùÏóPUåƒP@Z€&ª&Š¢?VÖÖ^üôÑ£€©É)F÷réÒ$ccû°@:ŸÏ>|˜L&KE›HŠŠ (Š1 4 ¢(z~iiéÇÇOüþ¥¯}å«ùÑý£\¼x‰±±ýŒOLpèàA `’$q! BÂ0$ØÈ0Œ6ß(Š‚PÊå²ZkÓCCCßÚ½k÷ÏOœ<õÀcÜãÐÁƒ;v ¨1&Ž“DH’dëú›µˆEI’¨çºôön“”—úŒëº™3gÏ~û™§Ÿ¾µsxªŠˆ`€ÍÆZcŒ8ŽÁqÌfmL³÷<d!Ÿçúº´¼D:>Á?ùÜs=?}ígròäÉ&pk"1MV¶@cPk]z{·‘J¥PMˆ“„ÎÎNÊåòÈøøxÀÛoÿC*•5ì`Ä`Œù?)d£J’„L:£;:[òhœÄ²¾¾Ôk5 …e]o ‚ÁˆÈ.ir(bUÅ÷}ñ}¿I§*®ëâ8Žn AÊZqÓn¨*Ç`´¹¶l™YD6ÈÓbŒ1lµ¾5P t‹b×:šqXG6Œ,ÅJ=Œ ãdƒªIkQcDLsˆ 4{?÷ýÿ–"c]4‰dÍ(ù€d\‡´5´¥@ˆ×RÖˆˆàI>À…é½ðúé&p¢ŠëBU.Þ)óÖõ"7 >~¨¤]a¤?áÝ9=Òƒc” V¢¦—|Vky?Ýõü‹/¿Ð=öùÉ ”¿zê»G«¶¥—œ¿Sæø…õÄ#H\TËÙÛu.ÏUyr8ÇC]Y²·òküâÜŠVj¾tÄÛ÷öí|õîÂÜ[g~õ“oUÐu™]©óæõU4,ùrÈP‡á;GùÂGzÐ$`°+E[Ê¥X ˜¸UäÔ•n>©†¢EmO×LÖ1C;>öìžÖ¢3c¹W¬sy~tºC«Uùø¾~ž}lPÃ0Á.ÝÛ²¸ÖáÕÓ÷ôõóËÒס«-­aˆMeTmZr»k«_Ÿƒw-€#%Pª'ôzHÊ5ä².€8"|âCÄqÄ3ûz¤P‹¹4_§¯Í‘$qe¥a¨/ÎÌ­-Îά޾28¶ùã„D!Hšß:ë:Ø #‹1aˆç:,”CfV|¬cü0Æø4ü†™¹|öüâ?Oü¨Y@±ºýí){bc¤£-­Ë•’HJ ùÃdž'vtKb<~ùNTÊÕ½çd¥´NO{J»­TRO}îS‹‹«¯ñþŸšgs¾Pf¨¶ÈÞ¬0YRúûsòîrÀÝ¿Ý5–«‹1ï-Ìóž˜Ûbn52R¯Õð’:)ÎNï߸8U^ž?mµâG€ƒû™6¯X}°0õÞåÉs·—ªâµwc=¹_ )¬Ç”Ê•øÊäù¿”&Žýz®‘í(›®¡{W'®…ïWCÉMŸ{ó•ÿîå—Š7/Œøálii¹ ÒºÅá‘íí}êK_ÜÞ?0Ò™ñ¨7Âø~~þZáï¿9Õ÷yì³ßÜ3òä‘ü•3ïtìêiïî^¾ö¯WÖ¦ÏMñ¿¡ª¢ªFUå{9 0<<Œ}ýrƨª³½`xÔZ;ìölß÷ÑöÖ!rÒíüˆ)ƒIá¼ YIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerOctave.png0000644000175000017500000000220412060166056022141 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  |âÿëptIMEÜ 0Ç9eWIDAT8Ë­”}h•eÆ÷ó¾çcžãñlnS·i¢.[+]AT–¨äŠ,£ +!DüC!ƒ&!‘I(šIY&i¨Ø4Š…ý! ¥”höá4[û:çì|¾ïûÜý1­–"]ÿ=Ïuß×ý<7\»ïàü«'ÿÒ²® ½³™ÿ ={ÚÓýáÜ÷n´ÞüyàÔƒÛ+üþü›NÏ?^y4ðÎ"Dª:¦ù}Å ï÷ zì‚#S–_ánJø*üüåÆÒe¡ÔcÃ…®\ãô¸7Rd‹™Û½Á!ÔFp¿M¿é7> Áˆ³7$õÞCiÐ’ï Où;·ßø×>"ßð„:œC#{Ñ»s}Ò˜íò(¦=ŠYoÖ´± ,²ÃC·Iëµ…Ïò)Í: €¯åääïµÏ 'œüWj|¿¤…´¯¥bdZÊ ŽŸ0´ïròÚ98 `¶>ÂIŽý),ÃkÕË9w¬¬òE÷™îRŒÞ‘!* ÄÍê+^ÆDU‘Aaªtôn'o«(%ÁW¥×>¦Óßø’3$èþ¼…T‚î5ƒóú%ö~F]ŠêÙ¼3ñ­äkDH`¬sŽ\0FA4Ñ!+S6¤»ô¸ŽÛ:‡98@¾jÀ¸í)œIi-h^S’¥©®OͨHŸ(qÄVÑ•kÒΠ(q*‰IBc•$Ejí…æ¹ÔÝˆŠ»ƒ’,#¬YfÑIh@IÉÒIŽK¨ÞÁ`ñIŒ9ˆ¶Á#Ïò¸ZGW‹&"—eü¡6m7i€­dÊTÊ:¢ÆÔxz–3\æ„()î2Ë5êX|1@€j\ŠA¯ž¶I„qTÓ¤“¥^0¡Ÿ|+ß»ÚÑàóÝK.@ÿaêP‡¸q¤ÌæèáMRCц$£! +à(`“X2ÚK§Þ •ЋÌQ¥ëMú«‡X0ääè_樠¸`œ‹Õæ¶ØDÛŒ1ŽA.)š”l0:J CŠ1Ô§Ò”›ú *òèst¬¡¢@^çØÓ9’‡©;>б[Ê{ر¹ûSRj#RZ €R&`1€#JœrD(<³*½×ÈŠ²¶̬%}z ã=,G_ÕÏwzŒYe‚Œ6 UT šSÄ·Þ©éÙ¿X”[&‰åùÀ¹nW±…vVÒ„ò”YÃü-YìRKÈMJ îÄ¢ªXPreE ‰m-’5-³#oæ 0Z‘`%M¬c7Âb Ÿ¬XÍÆw³ïËiïøUÍ–ðL‹ï(^6Ž{ Lí? ^3­7q˜Ÿé`+«GÜo #9@ºÕ'w¯A¶mæÿ›r½\]Ï.2d(Q.oó¬¾ÂUwIö­gN'ÀFzXKõˆ¾?‚Õ»ÚLIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerCoffeeScript.png0000644000175000017500000000253112353777264023315 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÞ 7 nïÂiTXtCommentCreated with GIMPd.e½IDAT8Ë}”[h]U†ÿµ÷>礦É>iðÒ‹MÒ‘ª±¢¥j[ëýEŒ¤A#ÞA+UŸ| >ˆÔ¼´ŠŠ(E|© íCU¢"}¨)ŠO¢­5Ø${[sÎ^3³f|8ILzñ‡a_Öžo†íY'iÓ¦~´¶–¡jˆ¢ÌŒ}û>Æe}×A¡`b¼'ˆâ8BŠññŸ‚¶lyxîÚßÿ ·víú`î›6oÁM7߉ө³sÕÜ}[[ÚÛW <îÖ]u¹mßöÀ‚¤›o¹»›‰²ýû÷dpñ%V kˆ¨â=M=:|`a‘.'b‰ÍÝ;¸ïì~pÛm÷´,ZTÕ Q=U¯×"áàñãÇGJ¥ø±ÂÓ yŒˆ""_0ó·"ü\’”¥(êQžÿ.³EÜ3¸½#v¸;IâGF~9ž¦íå8N~õÞæ}q–÷´Ñ{ïý«Þ—½.Â=ÌôVáB3ûcr²6]­v_ffqž‡ƒD°UÎá5"zöðá_JŸ~ú®g–>"ÚÇ"Ãfö´[èÐUí`ªºÆ wNLü:29Y›îèXµÂLßðd{{)v³­oÝúØ!ðNUëó¾øˆÓáF½q´Ñ(Ž…/DB"Be‘pžu²ÐÙAÂz3\X ¸·<Ÿçc9¸ýöû.UÕ'¼/ž¬OûÊY­•ÍfÖGD—ÑRï©ÊìKÌ"6"j0ó_"2*îû<JÓó¯¢k¼{$)'W*åÎaˆ™÷6Åw¢x3›šøszºòôÞQ "°ÌøÉ3HÓ3;Lιy^¯V»\ž"òäÕ“­¢p‡÷^™™™š›$aÆ=:û°7ËÆÞHÓ®D„ âÖÖs‚jX¡!<´¸íì©éú?Cш¹KU9„77Ìæqæ$êÕjõ ³rR.' Ä(Š ñßk©RýÂÌ–›ê®—¿jjª†ÖB03wš“”÷ÒøøÏŸ·´,qõz¡ÓÓGš¦/]ºÆýQûÄ\Ë…(•zZÒ4nKâx²QÛ{ÿ¯Ì¹h£*ÿE%s655úßévî¹¹(B|ìØOýý÷cÏž/]šÒ#€Ý `-€Öy¾ðsÑî,êè艦¦j ~×ÙÙ‹‰‰,YÒ‹(‚s`f˲fåjµ»Õ̺Tæ³<«Í¬»,µjµ³9sÏ×âÅ+ÇÍaRõîĉcv&ªÕ.’ÐÓ‚› =Ȳ::.€*Ÿ!ÏkHÓäyí”Õð§6h_`ûQIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerBash.png0000644000175000017500000000255612060166055021606 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ ð3S"iTXtCommentCreated with GIMPd.eÒIDAT8Ë•[lTU†¿sÎÜÚivƶL ¡¥(-H„,*ŠA.…R¢b0ê“&<`bâ›ñAÑ@ !Š!ÞH¨`¢˜–p‘R”«µ…–éeJ¡-ÃLçrÎ>—íC[l)ÿ—ì•|Yù×ÚÿV«b`6 ’{KPtÝY– ømãë¯Í)Ÿ^ަª8Žƒ”Îí ¦i"¥¼—Éd’3gÎóó¡šj`ùÝÀǺ#‡ ÇKÃH+–i¢ëi\.¦† rƒôõõ2p+ÊÔieô\ë&ÃçÅ2MTU‘GŽW6mþ`'°a$øþµ/­éýú›ïdb †išŠãXD:;±ôn—d<ŠÏç¡ýJ+é()ÅÏ´²2t=) ™å÷+ßz—†Æ‹* ]CàÙ%Å“0ô”b A2•¤¿÷---¬¬\iZX"M*ÞOÐï&Ö×ÉG;ªé½Þͤ’Rr÷)º®ËââIJCãʼnÀßêXEQÂ@˜·Ë…¥ðÜ’EØŽB"¥­µ•ÆÆ&nt_%ÚÓÁú§&ºÞÆ„ ã‡<—hª àÉqlL!0…AsSz:…Ëí%ÚßÕŽ†eâÍPsºŽ¶‹äO,'˜`׎Ïñed’ÈQ4Mµ HÇAÛ²@QÉÎ `¤btvE°Mƒx Û¶xlîÚ›3ÑÜǦbÁ9¹hšŠ2ì8¦)áRÒÓÙJ8/@´¿GZ8¶/ÓOv o†$(¨Ø¶=ؘ½òê(°˜¦ ¥ñ<º¡»ÞNÛù#XŽB(¯€œÜ·b r|ƒ{ŒªÒtîwlÛFQ”ÿËA+ CgÞüD:®p³ë%ùê~ü‚=×im¾H²ë/ÂùAD:I21À†·ß¹=¼»‚¥ã` ËtG"ôÆ›¶ìű««ªx Û`j›‰ãóIÆoòþÖÝd†¢µõ2ªªŽyë£<B LÒbé •dÔ7]Fk’—À²L’)ÃÐYðô|žY´SÇÕ±e D:EF¦UÓ˜>s6Uo¾‡åÎEÏ,‚P ½i•Ê763­|¶e±`lÇR‹‹Ç))ÉǶm‚Á\b·xvÙr¼RJ5›D‘#Ór¸c©ªšËEUåó47¦¦¦Û²™R:…D"IQQ!×®]c\8Ì“OÌÃíqS¹bMÖSSs×3¯W¹ÚÞÐ~gП;°÷#—š/Ka eéâ…²¿ÿ¦rè×ZB¡ K/dï¾jÜ.7“'?HQa˜ÞÞ>YVö°R{ø˜ÌÏ )«Ö¬ÿ¨ºœ œÛðêºÉ3g”£ªƒ%MÓRbÛš¦ÞÎ)%Š¢’H&9{ößïÙwbÖœóNŸªó5 «˜54Øÿó™ê@=pfdá7nô<Å­8IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerSQL.png0000644000175000017500000000245112060166056021363 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ ìÖ!iTXtCommentCreated with The GIMPm°—‰IDAT8Ë…•=oW†Ÿ¹3—’â÷È !C %ÜÙÒˆ n¶5°Hc®“´IíÂK'¶ÛU©¿°ˆ"ª]0à,G"iŠ‘#z†œOÞ›ÂÒ Ê—`0ç¹ïyϹ÷|à¹ÿþ•f³ùI£Ñøàììì¹çy¯vww'güþGš¦b<ßžN§_:ŽóY½^oض-•R¬V+¤”DQ”Îçó³ÓÓÓŸ®\¹ò­ã8?J)Õ_‚÷÷÷lmm=©×ëkB|ß'MS,ËB©÷q¦i¢µFkMµZ`>ŸÇÇÇ_ݼyó¿?{ölïúõëÿ2 ­5Y–¡”BaH)B¦)Zë|Ͳ,”R¼|ùrïöíÛŸçàÝÝÝ;·nÝú_| !RR«ÕÐZãû>J©üRæ1ûûûwîÝ»÷ƒEÑ×a¾Oá\]–eyêY–±X,r[”R˜¦‰išAo†á7À{ðl6«{ž‡mÛ¿-"RJ¤”¹z€8Žóõ,˰, ­5ç™L&k@¹\¾6h49Ü0 ²,# C”RyRJ Ãà¢I’äPß÷) ›9Xkû¾@»ÝFkM±XÄ0Œ<ý‹"]¨»ØÇu]Ç¡V«EAP(hµZX–uÉŠ0Žc¶··B0 ‡t:Â0äììŒ,ËÐZc–eÑï÷™Íf ®^½Êb±`¹\R(œ$ɉeYI)ñšÍflllÐívY­VdYFÇ,—K´ÖT*lÛÆ¶mJ¥Ó锃ƒ<Ï# ß>|ø1€y~úôé“ÍÍÍ«µZí«ÕʨV«lnnÒn·q]Û¶) dYFš¦ôz=,Ëâôô”~¿¯ŽŽŽ¾üøñ?ÿr4ݽ{·í8Î;;;nܸ±],…뺆ÁÅxÒZÓh4Ôh4úåùóçÿ™L&ßíííÍþvæýÙ0¶…Ýózüò¡aú+ù ‹-ÃiAMIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerPOV.png0000644000175000017500000000240612060166056021370 0ustar piotrpiotr‰PNG  IHDRKÖûlbKGDÿÿÿ ½§“ pHYs  šœtIMEÜ  ›‹]“IDAT8ËUS[h\U]ûÜ{çf^™d’N&I“LÒ¢æ!Ô´¡bÕ"¤`M£ÅúQ-R”þ ‚Я"¢¨à‡–J+­Òb)¥jlEšGÓ´y4¯&iÒIM:Ì{î=gû1iÄý·?ÖÚkïµ6  ZRI"f% IZ|¾b‡´‹·3«S÷ÝNGEq¦ŠWrž¨§>ãrv¼(¯4òØÂ¡ÛR³Äëa%!-¯§HæÓ3—Ó‘Ù©Xx%¯Øð¹â•¥ËõÁŠ@E}:sÓ£Þ²â\<·,Ö¥’%.׿†z$¢‹—¯öÜ6¾š†;·…tÓ^ _ï¿rñï¾=mKí­PZ/ÙØ`VmžœÍF’ºF$¼•‹ÿñû¯ÿ„ï¿öÆ5 !ÙèBl|0èËí~çýÅxâë£ï¥WGö?kÜ›9[Yú²!J5VÌÏ/n¾u¨€._ëÿ2zçÇäÄù±sÇBþü‡Ç¾¾c^›¼Uä_x°x[Ë»„‚XkÁêºÖííz‘/d³+£¿œò Ùx »åí®Òâ…Þ>«©Üд}ïTŒõµéøR2¶L¦CÀ`ºÜšÃ—…¥äHï,„tj5ØÒœ*<;Q·©6Põ„F¡L2–HÎ)§CWDL@€’’@BèÅåÓþâDsï%‰3IiÕ[¼U_x®ÔåÜ‹¦S+î@}6/„"0¨@© Mè$H+ýTwÇLßžúæøÕÞ¡¥Ç·>ïq”YwôÏžó§5wu º‘SY ¬Û¶‰XY™ŸU~èÒ™­[Ê??þiϹ>Ëð=½ïÙæ–]ɹ©ßNŽÝ¸b6vÖ¶t¤3ºŽŒN â\.ç̓±¨ß Ÿv'^·g[kIhGÍc S#?Ÿûê“ùþñòÚ¶WŸ;RQ¼51 ÃÖ‰µu·¶¶ž=sú¯“§^ïnñ˜táÄw—®çÊC;V³+㣠Ûnhî|áðÇ›Z›i’•@…d)@Ù–a:÷ïï¬Î›ÙÈ\lp`rxÚ6çS^§^¹qûÞ®ƒOvuù=ÞÂÚ:»$”&€ @V©xlcm‰)~ºÐoš>z÷°ÇW]UQ]USCÀźi“&”ÒB‘*p° @Ü›¹é‘é™ù‘ë¥#G·µwà¿R,±]S€RÀŠX JY0íåøýÉžÁÛ»;âÀ Dšh€ÆHIbH “ŒùLìŸbg¨ëÀ›3 .$€×Ï I°Fnybyv$’öµï;䫨ËÛ…"0 ¼}X:t²ÅZKdÅúúz›v½²mÏ‹H кï€Ö!!•FkBïLŒ;ª6·utÈ)µö= 0þ7`f¥3ë¬eV1;3¦ ¯‘Œ…—*ŸYÍó݉qÖ!”0¤A€-$“,à‡óÓé´BÂag8n/°Q—¸;YRôUµÌ/… Ò0,“y#§ÈÖ”¾.ˆˆHÓ´ Õ3óìÊ£WIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerProperties.png0000644000175000017500000000264212060166056023062 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ $0Ƕ/IDAT8Ë…•]hTGÇÿçîݽîG\›fÍnWZTÔFC±¢•‚>)-†VêS±¨Ñ‚>UŠ}°¥´>ù`K‹B…Z¤mˆ¡Å‡~‰­E”•Øcb²ÙÄd7»›{ïÞ;gÎôÁlˆ–¶æÌ0¿sæðŸ3ÀvæÌ™'—pêÔ)jÌOœ8ñüÉ“'›þÑ£GqäÈ‘œ¡¹Î¶mÛÐÙى˗/Çwk­×‰Èg»víº ÇÿHký>3Eäô¡C‡>Æ¿Ø,¸¿¿K—.ÅáÇcmmm,Ëz•™¡µvÃ0¼ÅÌf^¬”B†0ƨd2ùÌÁƒ'ŒŽŽ¤R)ÔjµGà³gÏbçÎýıcÇng2™ç‚ €ˆ@D µ†R A˜z½nÂ0´Œ1?„aøÞÝ»wXÕÙŒÏ;‡íÛ·cNͶ¦ÓéNÛ¶ÉCžçaxxØ”ËeˆÖ˜#‘H¡V«arr²A•™my§»»ûÛ-[¶Àùóç“̼Ck½Tk½Çó4300€_½D<€bFÔ¶‘J%‘Íf‘ÉdŒïûŒ1ÐZCDª"²æâÅ‹ý6h­w‹Èq3ƒˆL¡PÀ… ¨X‡â "Ëø¾?¯^ ”¢¦¦&ӀΔj~µZ}@¿½ÿ~KDÞl@™Ùcðûï¿Qa´ˆéZížw1ëA" sòa¾jŒ¼°råJ²,ËA@àû~¹··÷°'&&žêëë{6ŸÏÃ<2*•Jxøpuß¿ãyî‡n0æ)Å <Ï»)¢w•ËåMÙl–¦§§!"H¥R7\×€H¥RiÒZoªÕj‹s¹”R˜šš¢{+¾«”:`|f,Ë2Æhß÷'›››×çóùT¹\6J)[²dIßýû÷oY###‘îîîOGF —Â0$¥Ù¶t:ööö~X»ví¬jD„17üFïD£Qh­ÖÚÔëuÇuݯ׬Yó‰½páÂêøøø­\.׫o¨×ë°m­­­ ¢¼~õêUìÙ³‡ÇA"‘…U«VåÃ0D£Æ3HD6ÑŒv_p‰YEƒ 4ZkT«UB,û*™L8}út¥‘õæÍ››ÚÚÚ>wçíëׯ£Z­BD0G!'mp]÷ Çq¢õzf†ëºT,ˆ½ED¯8pà{ÇqîE"‘V˲^cæ|OOJ¥’±, 3ÓÔÔ<ÏûÑ€+W®H{{;R©<Ï£B¡ß÷!"¦R©P-‰Db‡ã8€jµŠb±×u AkMZk¸®{×÷ý_<Ïû‰ ¿²qãÆóét:Ý×ׇX,†l6k”RÄ̆™©ñf´s_|ÑÓÓ³¯Q®0sY)• ‚à¹ááá fŽ0³“H$ÀÌdŒ™mFƘ†:07X†_–J¥+ø•Jepllì×u¿s]·—ˆ–·´´,PJ!1ZëÙÞ`Y·‰D"H&“÷FGG»`{Noî‘PJ],—Ë)¥¾%"[kmD„FGG¡µfÇqÊ–eeš››P´´´üxíÚµY˜õoÍzzúgÇqŠÉdÌL¥R ¥RéË ^ö}ÿ¥ ö1ó„Öz”™wtuu}{÷îÅÿÚúõëwlذ¡{ÅŠƒ¹\®ëÉD–/_žY´hQºáoݺõ¿Ý`þüù­ñx<>£ À²eËf¿µÕ«W¬[·nöÐßöVæ{ÅãIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerFortran.png0000644000175000017500000000212012060166056022330 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ “ÕêÝIDAT8Ë…”Ík\U‡Ÿ÷œ3“ÜÔL#4ÓŒH“†TÝ»+êÆ­]v!tÙ¿¢«@…ºìBTpU—RÜtцRM"© Û ‘ÈPk:7{>^37ÜIý8p¸wsžó¾Ïû»W²,ãã+WX¿~÷Ο¯#2=(¼ˆ("ªŠŠ"* 4!"‡{0tïß¿ßX\\D¦§§ét:ˆ7oÞ|yyù#BcDQAUI)¡ªVŒ©=yüø›Ë—/ø«W¯Š£²NÎÍYZ:õÁÄDáH)`­%¥DQ¨»QURŒ(Ðïõþ¾|³ÙÄ Û.#¢ÎYœ«‘R"¥„µ!ÏsŒ1ÌÌÌ ªôz=RJd““Ä”‘TzÆ*N)Å”1FbŒ”—>|ø jµ ÚëõdooO12??ÏÚÚY–@œs8-{Þ¤¥Ï”õzï=wïÞåÞ½{¥ IIIš`*ËXYY!˲$€qÕ¡¤”ðÞ“R¢Õj±¼¼L³Ù$„ ›[Û"Æjð^òü9,4›Íãív»ûàÁsTÅÜ{ªröìY–––˜%Ï;´÷~cw÷W²ú$ožY#ÏxôèÑùÂ[ív{ïܹsã*J ÆRŒ$UT•©©)ÖÖÈ;ÏiN½ H?qüÕS\¸xA§gfå«/¿¨mmm]l4ß­¯¯{SW+.¡!zý>>D—^0ÿä•zdæøqY=½ÂêêêvŒ±~éÒ¥Ö(a/;®„ÿ0³Fd= ðž^‘ðâ(ç­Vë‡;wî|Z¯Õwñ¸i¥Ê*´Ün–èÄÐE©ÕêdY‹¢øùÆg7ôÚµkvLE%v‡OcŒcÔZ‹uN•¤Áw5x¯¨âœ+5Z`jô•êXÜŽÂG`1Æ`ŒÁX'ƒö»¹x_ v¬iU¯î¿ •Š±ÖŠµhýnGƒOˆ€1f¬Ër¹ÿŽW ƒ×A7—Pø¨Ñ±*;üñTà‡.½¨")xR å¨ÿ½â*¨únŒÁ:GòÎ3ÕÐQ´×íH¿›äQQuc­5Î9\­†Œ:8¼D¡›?4‚ ¾èü ìÖ–Ã3ÆŒƒEä¥\§˜PDФœ˜{ƒåw?$¤HkñN4_‰PWúPÕqûûû¿ìîîn;ç D‚üÃP's¼}á#Ä:Žk÷ Û}òdòéÓ§Û@Ðétpý~ÿððíÛ·¿ÝÜÜü>„ ZkRÄÀÉù¯/ž†iÿñ#¿ïîˆ t:ý|ëÖ-ý. ?\ÌÏÕóIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerLua.png0000644000175000017500000000246412060166056021451 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ %%¡RƒyÁIDAT8Ëu•[hTW†¿uÎ\â$Ñ1Éx‹«–(Úª© -J-µ­¤‚X$…@|‘"bΞ±x©Ø—æÍ¾ø¢/"V¼•"DŠ "U1õ–ÔKˆ—¨119‰™™3{õaNãô¡ 6çìsöþ׿þµ÷ZBhƉ¾ï“Édð©Ü;"ÁO ÛJ–lcÌ8°çy®ˆÔ[K<“1wÞ®ó¦ƒLFTÍ}€³g=in¦ª¯û U€‚ ÈM)eâyfáØ˜þµ:ãØl] ’dô:NÂ?†;SAŠØð»c( ¸®»ÀÓ.L‚]Vœo-Ä€l/ÈJÇ)›j­=”OG>sŒ18ŽãZ«~È2 ògT5|TwîüTÏûÏ[5=Oܲväe,™ |2ÇZs#âyž€¼—ÉèpçqÐz<-ÆØ³çsÙ±ãcXµêBmm¹ÛÚz²#—ëž ‡OíÞmf{YGDªtCÚ5gå­@X¬‚5kæ…¼À]·n>ÕÕ•U0m?@uµö&2äëê4‚l P°¥¢¹Üzz^½IQ¦Guh( ¸_ƒ©imMgAç8€ÓÚšîñf€.Vµ$“•ÄãQ å 8 ޶¶žáÚµ§åÖ­´´œ’ Èît`n1ù;T„“‰@|¶o_)'NÜæÒ¥‡@TBöâ8Q<ècÑ¢_X¸°Ž'O†åÙ³ÁÐ)Ú\T¥Þ ã±`I&'G„²iÓû¬]Ûˆµ/hoÿ P¦L©`Û¶8|¸‰¹sk€µô9ªš ³>RB>_PkCXjkË©®žäih¨"•ªàôé»9r“7¬_¿°Äãn€ëêdGDôôi¯Ò÷A®ƒ  ¾ŸSÈ9|?¯×ÑÑ€XÌåС/I¥ÊõÞ½WÄb®Ã‰D¬+Lìh¼zuüfŸ–º®HSS#©T##y¹rå±¶´|(¾Ÿcùò™Œ$QjjÊeéÒúðá @ðÛÀÀ÷=!NÁ]±bEL•™.t¼€Ž‹ðÉwý“òùB¡PPÇqDÏŸ¿+ÝݯñýGvÒÕÕ/©¬Œë™3]rùòcý&¸ø²­Í› ŒH±øxåÙ¬TìÛgú"‘Ìâ È_ËÛ+íJ1ÇEÍ!Bñ¤¨¿[aoû¬Y»"7:5"ÒçcDDFËÊt @´]qÝÈ2‘h¿H‘H¨SDÁUˆ†uÕâw+ìmhnvˆÈ€1Æ:€cä¦ç™ù…‚÷‡ ªü¬ª½%W[Š,u8¦J£ªihk3ïªêmc̘11Æ`­%“É`Œ)mæùÁƒéWaµ«æ…‡? ÒtéX½ÚÄ–,a†ª¾ñ)¶*H§ÓXkI§ÓcbªZ¡*“Óéù÷D¾áÿ¬­ÍÌÑ7"âc†J[Üz^éÓ󼔈ä€:U^«j¥ªXÇaL„rU})"qcÌãRÀí¿/Š™®àvIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerPython3.png0000644000175000017500000000240112060166056022263 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYsììŠnýrtIMEÜ gE(ÂŽIDAT8Ë••[lU†¿=gÚSŠÔ–Z +ˆLP_THã›F0^ž4c¢¢F¼ÅKb‚Fcb|ðò€D¹hQ©¨¹¬wk±­ ´”–ô´=çÌ™Ykù0çÔÆ”×ËÚ™Éþö¿þµgã?bÑ‹ŸN6Ñ) µÊlv°7 u{ûáïÎâò„ãSfGB:V·±0w!à²×¾zóÞTUT"T‘%”(¸®á•†sÇ:p2 óêr®œésw>ó÷Qb4è’µÛ'$¥{ZvðŽ_RÚ_4¦¬FE0DDS®›ÑpôÀsíC™ÝGØ»°’’2cù®Ÿ“¡× ,i­12çO7%Ë&4ªJ¬XEUœç<&Î[´8_ºT“6PÒŒðGG¨ï‹0çÎ'ß“(DDP3TÅLĉ*jŽHòÞ,nsƪ#udéöxÙ«õ|ùÔR?ÿÉ%höÒL6(íïh¾9<_©D”UϾvÌøÉ7ŠÄê«{~äêÖ·L¥ß‰ºdoF»öô°v_†íîÖ—w๒ÒïMuFacÜ4AUÐ(nœD‘™FNEHõPzxÝÞǨ®M÷1ÐÔÁ@ûÙ¾®{á•3¼hÝ·‰+–=ðµšÎ7gÃà߈ÁTœŠ"¢„~))éßùú󳮟15·ÔXWso§R×f‹Ùï(z“©º‘*¥Í7-ÿ\3Åy ¦eçBŠ%æjWÎ/Î):¯˜»üÚ—ê®4É Ä SU§f˜*f†ª—ðéjûãè¶g/šO€† !UIü$¾)ü‰™6¬n8[d2͇vTøý]˜EP@[Pò7¯3¯fúøEDXˆiHêTɯ¤ï´vûÙtêLrly¾dAU,7”J-å­u‡ê–<„WVŒY|-ŠÕI9D9ˆ²1TB\‘òó¶2!lðØíŸýýëߦ\s&—¬æº›ê7¿¼}飊9U0 óÐ蟵…à+ý}|÷a3=íƒlÉx»¼>ýÅoùl}ú’Ù·÷LP§ µsÒj8pÃ*5±ö"ÚövÐÚp‚s­)¢ê±æÕVß´mÎyƒ=˜™3QL…â"O1‹I’Íq¶¢€€ˆtuU«®`თ¹æ“™-ÀÁáOºéýÇ6M½aùàØÊÉw™ØÅEÓR}H"±Ê–öÞÖÆzx„ *ŒIZIñ”¤Ÿ:Ù›õ=ÇßÚØµ8;ÚØLÞ¯ûV,¸jƸýHÞG Q Õ#ÊÅÖäù›¿8óЊ'Žo W˜Çÿžn™8N£¸ì oE€g9 JÚþ<ßµ¡®³'‰Ö™éù=é|¶hÔ±¹çÛS¿ÇV†,‰jü±ïØ}O·¬Øwx s$ld\ðr¬ná깳ƾQ”ÂõRðˆñÑγ[ï]óÇZ éóïj>~}öÊIÞÜÊòDUgw¶ûÏÎ\çc¯µ×‡M@;ý_p!@Q¾±.ïex!`!þØå(:åÒ€IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerGettext.png0000644000175000017500000000247311472551664022365 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<¸IDATµÁÉoWÀáß¾Ùw°ñ½Ž‡Øq”Æ J@‚¶¸RE  * ì‘Ø³aâ`6¨,ÊU©Ø”º´RA¢-J‰Bh“bw¾ßt΋]°Aê&Ï£D„GAóˆXÎ=û½×í«?x¦æ#ú΋I–„ i-dI䇣iï‡?úùádë[#>¤D„Õo<ÿÐÕNÂ${Y™h' Í™6ÖA¸Øne3qd­Ñ«ÓÑdmýòR:“Ä,‹)¦u-̵3^xñ·wØÿ“˜ägÕÖ7o[Îå¹ûX>Õeµ›Ò´ŽõnJ¿ôä£ s©ææÕŒ²¨¡.iúÓ¢DD÷ T[_ýZ Ë Õ‰£áœRxQ<¾ÑiÖr±ÛàþþŠœaá9èU¼ö×a`8-ÍÄ’O ¼¢¥Ôò³]-*é }”- ý˜Vb8ì9¢4æÞ^Ÿ+ó¾*ùê“s|÷+±q!¡ö¢;—áê‚““ZiD+g:ÚAWÕ#ŠÑˆ8ÑFñôµ.ƒ ’È }Å—7W¸±šñÚC’$æb'c>UÄV‘çÍÀqz6D4è k5Õ²‡‚V“++ §×VZ\]jðÔc³|ÿ…·XŸØX›§rŠýã1¹¥M&ìýsÀxZ‚ÍÐâpØem¤\×F£µ§è3v 3Iˆq%×–Rš‘§Ó 9i6¯¯E!_Ú\cR8´V: î>øcB”x¼+Á׫:ÐjÅjƒÑÜ”Éðq%»‡ÜzþUÞ;èã¼áÓ <}c•4Øzã!ÍÄòøBÄÎÐ0*=ÚX¼wü‡wÉÆqÜ ÓYê*Çû çJ¶ÿ¼Çò|/šÛ[;,.u98>ñí_0ßžaµ›òÌ'ŒJÅËwŽø×é4NqêJµh•™6)ÚXØ9Ëyî³—0ï÷9™*²$æáƒ¬44»Ç=>ÿÄ23IÀî8ä÷oÜCTÀ¸ÖDÆ lHQ” ›Æa; y!¤Qˆw5Îdüø×»|ñ© \^NxpÐçÉ_d®qi±…3!ûeÂÖïÞæ¤7 X¦>‚VóÚ£gãÈ¢¸ºFe)ôrǯ^¿O9pq>¦7®xó½3Ž5ïç-þøÎ.xû]¼XDYDYPQe“9{ÖŸ$“á#>À•wh7%¯j~ò›»|á‰5^ùË)Q’±¶Ñ¿ÝysüÒK¿šéÙ€üd¬œó‚Æ›ÌJóJ+½p½²¹l:Î%¨«RàÅ“&­æ v‡n4úàhgpYýýìäþ;G?ýå[÷ë2ß˼߯ëz_DŽëºö€*Š¢‰ÈêÐû\mnn>çQ×ÛË7°IÓ¹Ò¹"ŸïÞ{w:êïŠÈ~]×u]ÿcvv¶w÷î]„ÿþuëÖ-µ½½­‡Ã¡â4 ÙÞÞ@øœã#R"£ðo…e;dÒlÇ4IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerPascal.png0000644000175000017500000000224112060166056022124 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ 1 ºIüÖiTXtCommentCreated with GIMPd.eIDAT8ËuUMk]U]ëœsßGò’ š÷ÄA¡E„fÐNAM‰ƒjQ'-¥‚Ðß 3k±X¨‚ƒL:©-(M ­:"(´Ð"‚’¦)~Ô¶¯¤É}÷|,÷¾vOÎárYgíµ×Þ›ÐétÌ¡ƒßkw:ã¨"¥„”$ÁZ k-¶…T¾œ>}úý¹¹¹5@»ÝÎ.^¸ðçÄÄÄ®£bŒôEAŠ1ÒZ‹V«ç2 $ $$J‚±V{öî_XX¸çO‘„1F’ç¹ ïAJI)%…G–Õ@p!Iàà"$H6`A!C”ÍcL(¼Ç$c-Y1VŘc³®Ê&`ë”çX[ËAÖº2k×õ6Æ ’@ "1`¼ UÚ Q¯ÕUjf@RÆXc$…H˸!ë팵Œ1ª_ôY«Õ`H¹ÌÑYë\æD’Ð&ze!KŒíRHÂÊÊ Bh6›pÖ€ÓRo „c Œ!¨*ËRl`Cá6÷û}¤‚GŒQ1$ Y–‰jõ¼/°¼,5uÔjõõô%i«ÏÍ€m¿ßG !x¤ €õR:g)‰€ ”øðáCôzH’Uóp Ç6Æ1Ę䬃ŒDCøJßB÷¥1êâô×øû¯%M¾ò*^žÜ’Ú(ÃfW”mLïƒH23.³Ê²Œ†„÷!u»]þðýj6j¼s÷+LNî“1†U{?ÚÇ’$8cc„ ÄJg 0Ö`ñæ"îÞïÌ¿]Ez½¾Å}•ƪ!CØ Ô:‚ Œ± 1X]]Åàéöh?5Šg:OâúõkðÞÇïýúnÀ¶9ÔD½Qû@á½ÖÖÖ`EA‚à½Ç§Ÿœ‚C!C Ài¨i1õÙ)<ÿÂK:xè0RJòÞ§MŒ³¬†ÑÑQŽŒŽadd„­V‹õFY-#Höz=.Ý\ÄâÒ?t™Ãs»Ÿe­–±·œã·ë×x¿Ûå—çÎ}`y[ñ¬µh6ˆ1 ( Âðð†’ÐÆkû÷ãìçgáƒðß½ßqôè»X^YÅŽ;ðóÌÌ/SSS‡oß¾å …à‘RRkx‚ 2!Ã;GŽ`çÎ]š>Ý]xómäyŽË—.]ùøäÉóóó÷·ÛM‚/ ZçÔl4YÎ/­w,Êɦ‰‰Ýœ[Ø£"_e?ÏñÍåË¿~pìØëóóówëãm̳ºSÆÆF1ùâ$úýÓÓÓ?}tâÄ[³³³÷¶þo6νÁj¨:I$AcDc4Ø™ËÔi·qõÊÕo?<~üG®3Ž1¦3gÎ|Ñï fóÖ¥©jÁÆqëÖ­Ù™™™©¥¥¥U<&þYVXt†®ïIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerRuby.png0000644000175000017500000000276312060166056021653 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ 6¶o¶ý€IDAT8Ëm”]ˆgÇ3ÏóžÝ“Mö#aÓ¤jZE­-Œ– Š¥Ñ,FñÂ""©zSñ¶ˆ"h¢*b%¤Æ²©¨ýŠI.L¡RiP6iÚlšÍ&›Ý={vÏ9ïyŸñb«âÜ só›þóáÿÄ¿ž’‰]·ÿÔWŸ8´}íìé]õM¿ÜØö¶]þ¦·ëêù™¸øôSô.\HAÈ +êÿVªûÑ÷–{'ä¡§º©'§H½ÞGÎÿðû:yvoš½x«ö»Ôlxß{ÙôµïÚÓÓÕìï¦}h¢-dÅyúÞ-”…Ûÿ_ðåcG9óÕ}<0¸òÌÑOÍ;ú›ÅÏå…Ô (×…æ¸å—‡mex¬ö‘oú¥ÎÔ¬Ù T¥ç•ê)`f<úž|g-ðò#_¿öð¯µpòű°ÒC< bâćmøà‡ò¦ÉE±r-¶/]ŽeÈêTƒœÙâ>ÛRùÊó'xéáýû¯¾ðÇÇ×.^Á@kbëÍ×—3Cüè&|£–oLvñÂŒo:MÝÂrí‹h…Ÿ?{Z&ï˜2€s?}ìžøùÏzsW½s$DÔÌ$#ëÌh’Œß~§µg.¸Õ™×,‹ŠˆÔ'¡Ì VÍÕƒIÐßÞ1¥—ŽÙ3û§éƒK³Þ1‹¸l&Y# T=Í£ÖØùÜYYµÎjnÈÖ.ƒõËA1͉TÅzJsþ¤ªßÿÃ}w?Ú~ùŒs€¨8Ì@Ä0Ta‘ÜzàûÒïöâÜë³j‘‚A°Ê$Ѐºü†ªº®¿ÿÂçöÎ;·»Û7’3Ö'ÍY•3UÛ÷=ÈŽ‡¾hR¸ÜY«„dC2â+Tû¢W ©­3GO–ËKßZY^¥R(T†aª’b&D˜¼{JÞñ‰)ÊãG¨]yUê­º "¢².D3& cÉ 5¿ÔZ^x¿è' 1@ 5\Ȩ‡mwíææï¦{òÏÒ^¼.1áU5FGQ1KšMê!£°äã›÷Lze0TpyèÅ,9e £[ìØó6Ædíã'tVL3ó.SæB|‘(JT‘¡*ⲑ`ÉûáábËî»ÏÃì›òF: ÛqçmrûýŸ7{åï,¼øœ„A‰5Þ:fÓ”%«JDˆèz‰,ùÞ3O¶ÆïÙ“µµAõÔq‘ZÝû`|ç=Ÿ´×~ü˜›;ò´ú:ªõ#†‰"†dÑP‡ˆx2ê QóÔD–üÂÑíÍÛnI7?ümÛüé{–txb¼X8{fpþ©#Ú h£é’«¢y1qà<à…ZÌ"Z×,‚^eH-tÑÏ_¼Ò¼vè`¾­lûB“ZgIÚ‹×9ÿì—‚‰o"!%W¢D$‹H¬“¥qjêÅPŒd™¬J£ðlqÅ ¿œ}spn¦6òø/غ}Tb¯$ BZ~}^’ª¨Ë`&@Ä D´ƒÇgË8§F×Ì©0ŠBÃöF³ã×D[`rýÒ‚ ‡‰™tÖbèRCf&"fë^Ì uƒ ” U²*oXLCÕöx³|†5unl±LÔ®us«pnq-²™¨‘ FFH@ËÄ&ÄËFï¨ަw6îêò¯A¹ª¤GZ‰… ÞŒãIåRD®uƒ–q»æ|Æüºÿ˜ˆlTÏfõÒòŽÚ[àšSižñ¡ÿè­²Jî¿»Ág‘ŸDÕ©èݶvÊä^ NµfÞÖ`΃8*„yI¨%Ф4PêIi™ÏcÍzÿ]㣫ó¡:ýÒj»/‡&G>H*ÝÔ‰Ã*æ¾O‹Í‹Y]ÑëKÙr?`K•兺Ы;]Jf×jN{­¡zþðM[«ÑF£sðÜ+ËÿœÕø$âè¬ IEND®B`‚eric-6.0.8/eric/icons/default/languages/readme.txt0000644000175000017500000000012612060166056021151 0ustar piotrpiotrIcons where downloaded from official sites of the languages and various other places. eric-6.0.8/eric/icons/default/languages/lexerTCL.png0000644000175000017500000000215012060166056021342 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ -˜ÙµéiTXtCommentCreated with GIMPd.eÌIDAT8Ë­ÔKlTeðÿ¹÷Σ3C›¡ Mj0 Qj4#M шU6jA]¹@Iµ8ã†Ä¤ˆl¬©1U‹i $„&Ò†´@«`mÑB;Ú—eÚék¦ÓÒéŒÓ¹ó¸÷~¦Å&¢ôìÎñËÉwN>Â=Öž·›`q©ä»°±È.êk^¼7ðO»ñì[§èμêX;€þ öúñ.°ŒŽÛK:.ÕUåò—|-Å^¯Ë~êÈžY8#åÝÃï6Ü@<‘AcÍ®\¶·ú̦´ž> „¨ðx\yE^W'_­?]wtN»ôÈ7~Ôxâïo{èlyZOÈ,ë!’Ë:g;<¶Â¢;Ÿö©ÿŠ6 ¢vÿã¹þÄ…`Þæ¯VCQ?aŒ•F‚3Á,S2.ȳnÝÆÅЪtv‰ ‡E„Ú×Ëå5χ~?¨ÙÔŠo¾BDÒÈdd†Y B kÈ|»»p÷ª°!$ÂÑ”Ò|¸LÀÍÃÛL‹½Ç…¬"‚CQÄ!5› N·[±Lœ3)2 2“~ðpuC?ŽU•€ø¬5à .¤^ÎÌGD[¥àŒÁ²¸ä\ÁîpHUÓ¤¢ÙU²‰p"4øc¯ÖucåÛKp¥o—‡â8þÆŸKò5lŸOž ýŠ$pÆ`š&„„’ˆ )¥”@v»ƒÌì2ôÅéÛ‘±¾ÿÖû¹V¾½ ì~êÜÔ¾Fÿ–DÊ:©ªJ¥Ó¡‚sÃ0%H%Î9‘E2˳©Å©_;&ýíM†ïÔ`(’Ρ‡¿ê/N¼NÓÔ ‡MAJÓâP‰AÂnWaeu$‚Éùà`ßÌеssãý߈¬8ÚÇ-Ãôþ¾mò‹Ž‰õ±x¼$g¯8Žç<.;¤2™¶HQ5¸í 4bÈ.G O£áàõ©Ñ¾ö€ÿZ7€É;w¥–¤2Y©3ÛÁ‚|õÍ‚<²i*âI“ÜN ,0}Áš ür30Øwqrøúw‘ÐÌ€Ø ´þ¾‡)6àtz¡•¹iƒÇërË2§¦‘'OEl9§L‚%çÓÃ?ßò÷t\½tá2€[Ä øhY¥2ÒÛ&WPÈfãÐî÷h ñÐÆ¢­Ñh²Ø2²#ÉØœ …Äè@ïOÝç.N§zÄW»ù‘Þ6±ZN0±$½ãc!_d6äìjm®¿Úyš¦#1`€ù¿þÕ‘)ssÛ÷cGOÖ·àÆZUÏÀü®º/Ï¿°¦(Ô7œwüµ¤ôÉ5õqsT_[°õ’{+÷a­ëÎúè`´+ íIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerCPP.png0000644000175000017500000000324612060166055021350 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ iݺµ3IDAT8Ë=”KlT÷Æ¿ó¿ÿû˜;ñŒÇÆ6–…X8 &Æ&!²0¡©* @ª„ªªÝ°im·U• R”¦OeÕJY¶iš:Hå™8‰1Áo=žëyØwæÎ;÷ñïó­Ï÷Ó9ß‘>"IƒïZ "ÏŒ}}ððá3€v: ðŠïû®ëºëÕjõ‹|¾p'·k§»º{¥òÎó}š]Cµj²Ò®YKÞ¸ l{ü/ý‘8îˆÅ~s8öÚ¥áá“ííí>c DDŒ1pλ+•Ê›“““?[XNošª’mÛà'b¤äômsô­¡ 74-ðêÕ«Wÿ<4ôÆ•þþ~hš†R©„X–Ïó ª*Âá0òù<¶r9\z÷]´µ·Ã®Ù/fK¾]¨üɧ8œ>ýÖ/{{{®¼0Šååe躎H$"VVVÈ4Môõõ¡££™L¾ï‘,ËhTEÁ7ßL#™LŠ¡¡“´¿½U±ÍÝ8ïíí=ÞÚÚúSY–¡ë:Ö×בN§qáœ;wŽ?~ŒB¡€ÑÑQ466bjj ù|^¸® ˲P.—±³³‹h4 MÓP«W\×s‚¼¥¥å{]×aY–0 ccc¸téTUE4…išPUMMM8þ477 ""EQP,‘ËåÐÓÓ#c”ɬ#jå²ÁRkÏñÙäíôÿðÁ{ðlV-®( º{ºáy>B¡ˆˆ4MC0@ss3º»» i#“ïûT­š´´¼Šÿgbýæ¿sêµ°€ !@D(–v úv AȲLžç¡þ"_!Ï÷÷Š L’ j,.­`vöÉÌ¿ÿ}×±ÿ `d‰ÿüW¿fü¥•ç“®ç^4*•Ó ¡ GD>c’`Œˆ1&“ˆˆ„¢ÈØÝ5è«é¯õéä—wï}~ë#ö6•% Žç/¯­ûð÷ß[ûþU…¼Û2;<Ï%! |@ì]ç8ŽH§×³;…ÜWR{qÊ\‚ãz`LÂÿï3•I4(IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerJavaScript.png0000644000175000017500000000255312060166056022775 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ $wó'¡iTXtCommentCreated with GIMPd.eÏIDAT8Ëu•_ˆGÆï|ó³›?›ÝþI²HÛØÆ6…@½-X‰‰E¥T0H/rQ½iAüSJÁ^HÁ+Á[‹E¬ÅªˆBT¼PK 6´Ù¦!YÙÀîæœ³çû¾™÷}¼8›‚ÎðÎ3óòðÌ;ðÌŒ<þô…{?²Û÷Ž>Î-5ùH“³7¹U“[Rn­ÉK MnÈ£1ÑutÛ;ôýE^‰Zéå{Û£æ××?oÿâøœÿôÐöÞÉ%šñM;"·còhDÊcšvDÊk3ÑõøöMeèðRˆ:P‡&8—ï:x%Ÿ±å¯Ü;µçfÔ$hlSN('RÛ@ßã·¦1(3 ßÇš¹ qjs÷¼œ]žb{ë;?àÎÇ>Êé—¾ɸò“ŸY 5¦œpwÜZÝ’ÌXØQ ñd¸‚2ŸSë@D€-·L6.ëâ§žäÖ¿78ýÃïq×ÙG&»ÔnÎ0ïp¹<*5œä‹ÛDJÔ®£ý0¥ÌfÐf|ö–ÖŽðçsçpâé§è÷fTƒZzJ?0¸/„#7p[Tî “)¥FÇ×9ðÀ ¨ryéy»ï+O±wc•J³v„¢À#(tÃ`]­t^È%œH" "Á|6¥N'䔸äÏʱÇÕ¿üÍþó7¸úêotÿ…ó¶þé3¤6såå_âfôî5BUa5‚\j!R"å†a>§›L•ÉôÎïþÀÛ¯ÿžë/ÿŠ~w¢¿>ûM®_z“ÕS'¹úêo¹öÊkâð!«^å ª‚*ðÙsŸyücÿ|ëÃ*{3K2rJ$ŒØ›“ªËF#k,]§Ú#Š XÆrC "©Jæ ò|6Kóé„df0(0 /¹mÇ>*6jQ›‘„öóDPB"¾y2ÅÑ¡Gã1® 0L¶¨1$`·?0!„®ý9Â2H¤M‹‹Ýê ¹Ôð„©*„BE0€¤~±‘z¤žP¯¯ àîu<¦ÙX=ôÎê¡Ã_¸s¨«çƒ5’å5û!K–ö×)ÜRÈš÷ã6G–kØüàô¯c«× Ÿ¸÷á奎º>ÑÂhñ/Ü>÷ÿozŸ$CP ¶ü»ÊsÿŒaeR¿÷'IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerTeX.png0000644000175000017500000000302712060166056021424 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ  Í«”ö¤IDAT8ËM•Kl•ÇÇgf¾{¯¯¯ÁÁ6Ø57¼ÂË ‰Ri¡H$U¥,ªFIª.’.Ú®š¶jÕE¥*«–JQBR©eÑ4-]AT5Ä„’P`^1_pÀÛà{¯ïóûfN¶QG:›#ßüçÌÌù˦g~Îñ÷yhùfÓ¶­[:{–-±¨*ªÜ_Š¢>'ï=ªŠ¢$Þ›;ãwkG¼SÞ9È'/ÿèÝÖ®|}ÙÒîí¹æ¬‰ˆ¢Êl1 J$ñxP{ï%ñIjªP,?¾i㮩JØ!sjvýõÝnþÖ£ï®[»~6¨V3:u&BPD 9!F¨×L—kDn¦bôæ>?:Øø`_ßs6ê~íÙPjYSOw|?7¯sÍíñ*gÿ{“¦LŠ…í-8çˆ"‡sŽL&M¥šÐ70Lÿ‘*ÕórGÇ8wñk]Ü5OÐØöô_¶!½öu›.æ†/×W÷Ÿ¼³Ì2ÍùË·´Z-³é‘Å„ $IBð41»ß?Ëoõ!C·n³|iŽ=}_réò5zW·ŠI20pø¸Åu_ë0û•+/iéÈmùÙ+ðÊKO0?gYØÚ„Kg±¢X šx²MŽqm¢Ìá£yâ$ððC9ž{z1 ;ÈøDÁ=vôˆ£¸ïô÷~ü’{ç½Ô!ñBwW’ÉqðJQ™Z¢TžŒUV¶9ݰ4+¿ùé&Nœ¹©{þuIžzl3½ëz´P àí?ý#A]™û§9mùèbI^ýûU>;=DáÖUŽœ»Æ¾ÁëR­Ö0"¬[½@p†ÃÇ')Uæ¦p?ùåÎ4ªér%¦RKe~Ö‘M[n~]¡m½góÊnZÇYSãô…1~–çÙ§‘MÃÞ=C¬h¯¾¸‘(ŠA1Þ=´¢u‰ëíìH“ÿªH±P”&'j³ŸßJñÖ±*cÅ—´êLJóœ<;šåmº}ë*ºl¡oà’žýŠ(² " Œýeô/ÿþòÖo÷>ݹ¨z½dñA%¨²n^™åóc4ŽÔBy~û*Ý£½½UzzZøgO3S…iéhËP*UpÖ0û´Åï<³jtcï*,h'‰|½ÎT]ÑØÐÙšæ…'äâ¤pi"ðäê.z×vQ®R‘cåŠE€Pž®sìÄïçÀP(…Ôͱ»Tª M)ÇDE™ºwf[dpTÉžšb¬¤„F™ ]m¤Rõº`­%•n"“I#s­ˆã˜òt™¤QǘNÛº+<Öaê–5–tgHGŽØŒ1DΡ€µï=•jÍÔjµä>Øû@˜6I€–<¾º]sÙÅb\Ed3\ic-årUïŠbD0F(—+œ9ûÅÝ‘‘|þ>8xªbŒÀ9‹Š•X-icq.B¬#¨ˆs–Òt™;ãbÄ’$1ÅRI†® shà“þ»ãcÿ1÷j@D1(‚JP ‰ BµRáÂ…‹Ôk V,ïaaûÑà958xá@߆ïƒ5¨„ðS}6=³ÉLÌœÄéøÄ8ù|žÄ'Z*e$¾ýn¼óöÎ7€CÌý<€F;g-Xc°Öгk-ÎYœsc$•JaŒH¥\–+Ã×ø÷¾Gÿ¸cÇâFm/PpªŠˆ0ywjrbòóZš±ÖJ˜u I’ÇR©Ö:2™&†®\åüù/Îí|ëÍ7“¸þ>Pˆ¬Á½öëß \¹z}â“ç‹ÓÓOæš³^D‚1V1ƨ5VDDS©ˆ©BQO¾sêä‰þO>Ú |:§4²–Ø{Üp~4¼·ë/·lûî‹)ñ[êÕò7¼ODUÂŒ¡ÎÚ“ˆDZ޸1:65y{™kgä,qâ1Æò?…Ú*…Y¤IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerBatch.png0000644000175000017500000000275612060166055021754 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ  y—ò{IDAT8ËUMoY=·\nÇ1Iœ8±ËmhÓòEä RƒDK°èhZbÇb4‹ù°=»Þ!X²„”i¤V+¤[H$E!IçÃáØ”?ªì¸(»^U½;‹Ž#ÍŒZs¤§§÷tu®Î=ï¾ )%@J fîìÄÌtëÖ-ü'0s™‡˜yªZ­~·¼¼ü·ùùù¾ÏcÿÌ q_8êºîX¥RùfggçX©TJ–J¥øNq'2Â÷ßÿåÏÇŽûy}}Pz¤Ö34L>ŸÏ†ñe±Xì-•J( ¨V«0 –eÁqضãÇãÊ•+~ž˜˜¨ §,˺¿³³ó®ë]º®ãýû÷¨V«¨V«0Mív®ë2AQ”N¹XUUê …Ðh4è]áÝÈçjÕZ­–´m{üþýûØÚÚ‚çy‹Å¸Ùl¢ÙlâèÑ£¨T*‡Y×uø¾ßñ¾ïÃó}4›M˜†1ÆÌ ÉJ¥eeee“™?$ ø¾/gggùܹstöìYhšFÃÃÔL&1::J7nÜ ÞÞ^BÀó<¸®ËضmÔëõ4€(hšåîÝ»U!D9•J™‘N§éáǘŸŸ'!–——Çáº.jµö÷÷áºnÇX’RÂqìíí%hÐl6¡êº¾ßh4Þhš6.„ f³‰L&ƒh4 ˲Ïçá8jµ‘L&1== EQ°´´Ó4!„€a݆adü&„€»»»Û}}}èêê³gÏ022‚`0ˆ|>fÆ‹/°¹¹‰T*…ááa‹E¼~ýÙl³³³\©T`šæ(ÑïÏ­\.¯& ô÷÷£T*ñ£GÈó¼O ãº.Úí6._¾Œd2 Ã0 ¥D `Ïó¨\.s¥R¡Z­vž?®(P(¶™$¥$UU¡ª*ˆ¾ïÃqÄb1tww£Õj¡^¯#—Ëa{{†a N#ãÞ½{³×¯_¸zõª @«Õj]ºtéf­V oll°¢(äû>\×áâÅ‹Èf³ ",..bnîŸØÞÎA×uضM@€JÚßh4D¡P˜W™D´kYV1‹õwäû¾V«MÓN§aÛ6J¥—–ày.B_ÑjÙ”Ëå …8‰3ƒ™7@¹sçN'ÛZ__„ì8î±±±!êõ:‚ªŠžž¢€ˆ8 ²”Á`B:tèëNçu6âñ8E¡v» ¬( vwwiuuCCC‡Ã!íÇØØ˜’ÍfqäÈär9ùøñcBaÿ˜žž.«º®3躾zøðaD"ÚÛÛcð<D$3™ Y–EDD©Ôa\»v 333¶aoVVVðöíÛñz½®v|ñ~üˆF£ÁŽãàÁƒôôéSײ¬}Y­VUÛ¶íïïoÖëõ_>ýÇ“““_ݾ}{YÓ´UU‡a𿻹¹¹êÚÚÚqÏó¢žç!B!¥”Š¢(°, ív[ú¾¯!~ØÚÚú;¹j‡xmmí‹W¯^ýtâĉÁB¡ðëË—/ŸTU-poÞ¼ùo„„Híÿ2TR333?uuu™¦ Ó4 …B…ÞÞÞoƒÁ ‰D®.,,üxþüùߣ{zzðGqêÔ©¿ž>}úm*•ú@¦¦¦fÇÇǧðÿ`ppðóc4txóIõ™3g¨»».\À¿õ/~ocbIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerPython.png0000644000175000017500000000173512060166056022211 0ustar piotrpiotr‰PNG  IHDRÄ´l;¤IDAT8•”Oh\UÆ÷½73™™dšÒióbQˆ’¤j M-QiEŠ EªPÄ­¸×M×Õ­.ª ¨à¢ÝèF0¨…Vª[ºiÑ©¨¤ÿb“™¦™éÌ{÷žs]ÌL2†>¡Îæ\¾ß=|ßåï=Yç³oÎ=rm¹µëæí”F¢à…R䙌Ë<=¾í×gŸœú3Kk²À‡©#Nªèt#±¤Nñ"•BÀ–Rxq/~ôö«K÷ÒY/ªú™±jyú•=1ÖAÛ*-«¬&ÊõZÂÅëéåF2“¥².1å‘¡“£¢@QÝXÂ\MÊ÷ —rúò"g[¤ÙvuxU¼ ªÒ‹dɳÁEÚŸz«±Ê ê¨Ip´TU A|ßîæ†0aåøÔÞskà¾8Umú™‹óI¹aé s¨"‚ªAÅàUºw¬Ìçãx¸vtû¦?C+-¼ ö¬o¬ú÷¯¬È>+ªÙè§ôªgƒàUqÖ’¶W)mm‚ZŠìXš}ëùêο ¾üþÂþ»:Y÷ÎkçkõƒúCóª»ò†¡ i·’b¾P91wåÌþè¯[«ÕV¢±Èz =½ ^Ö«×ȇ0' F7AP‹ñIëqóÎl5º¹’ÒHè&¾žº¡*#CDàCTz“†ì88y™ábÔvÊ[r4(G·ˆB£¬M£"uL?ðÚî#›VŒÃÀ{Œñ¦ÍæRƒ|bÔ‚wëp‰@îmß\`¹ ^P¯¨W¬„žª³çá„a÷ÿyuà-Hæ{“ºnÏ¢lA¢1‚Ƕ/• á‚ïó7.9ÆãZê}(iÇKI@»%Éz^R ÜúËrþÅ<º»ÉòÊ…B/£ÃýXk‰ãøZ ÆX8oksãfà‰J.“*ó)q·üÌ^{´'žusdGOº³ÇGÄgë .~´Áƒõ ß:žq=(±°°L£¹ï¦§F…sk­sÎ ‡pÞì±^ïëíÍ-|¶ÀãªfËô‹Á‰YNO‘h+ÊÕ}ÒLõr»³Ó¬‹W‡4/}ñͰ)Ö76)MŽc B ¥dƒ (ìÆYî‡ãŽÑÓLNϰ»1·Ú \©µ5NNåé¦òÌdžKÓdS{&J*|ßÇ÷}”TxVxÁdiZÿàÄ™à|pw¹â>x¸%æ¶ ÕƒÄõ¦¤+ø¾"—RLi7܃د5ØÞ©;ßó„T%¤SJ ¥$Î9áeÓéã‡JS`GÞ"Yü¨ÅM퉃 ÓãáKɤßv‡‡ ûTêuqøÐÙLc°Ö"¥ÂžRŠ(êÒétIbM6Ýñá€LlyåhŽùƒÖ¡‚¢_ï’Ôžòtwƒ|ÿ¹Þ ž <Ÿ”ç' JJœOkhm ÈJ‹yÎ&•òùúfk{—rù1åò=äÔ‹§Ÿ,aœdeõ)WøÒ©Y!ð)…ðjõúâ“¥/›Î£dzgÛc(°SmR^}ÊÂÇ4=z„c³³ä{‹„QB£¾Ç^½FÖ·xJ¡”G»Ó•QioîÎwVWËùÒDé»ù|±Ø‰¬q®Ó޹ñé}ws™ãµo|‘±I,ÊíTë¢V«PÝÙrÒYQ(ô±¹]¡†Ü½w¿¾ºZ.«]¿ÖüøÃ«WÆ&§Æ{{³_m·ÛdsY­¹}现¦Ã‰“'8ŽãÄ3FP,H¥Ó¾/t’à©333A Úaˆ1F„a(—V¸ü׿­¿yáÂÏ“8ú#Ððœs!¨Õ÷j»µ>zó9œBDQ„„”$Z†mâ8&“É"•G*•æÉâ2óó÷ï½ý‹·ÞÒI÷O@ÀWï‡?þ©ìâòÓ÷µÑç÷[­WsÙŒBX)•“R)¥SR !„ ŸFs_Üš»]™ûôæGø÷ßמ“úJ‘ƒ·T^·¿}÷âã—_ûæ÷a^îvÂqc´pç°88ÇówI’¸µµõ­Fmç°ú\§ï)mRñ†âTñtŽOWIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerMakefile.png0000644000175000017500000000245712060166056022447 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ ,"îô­“iTXtCommentCreated with GIMPd.e“IDAT8ËUKl”Uþιÿ¼ÊtJ’R¡ÐĶ&Xj`cÄàҺШ!ºCMºP7²‘Æ@ƒhP$Á( Ƹ2,PâŠ%¨–:ÓÎ?mçŸÇÏqñO§- älîMnîwÎýÎw¾K˜ÇŸØÔÙÕ¶Û1N1†(îdŪµ2”Ù¿sçS¿ÔŽ~vœž{ö=üÑ'›úû9ßH°Xþ/f6Œ¼›—ŸÎ]èÛµëùŸûœœÎÎv ½½ÝûêãõœËå}bbà~ê •D¢ÞééíÞ`ëš¶ÕäléÛ,ï¼{ ¡¥¥¹£àá8!3{a6TD4naJ†)xE´¬hî8ðÞÁ†Gûû\ C Ÿ™g)Šf¨@A€Ju?¿Ö¹Ü1ùñº¸ rDT™Ã@,V¯TB:›ÕìT¿^„WòÕ‰Ö«a ì°† +”ÊbĪJ5³SMQ! Ó•›.ŠÿþžØ(ÙJM ÝÈÑd|5ÚWw!—Ÿ¢HÈA4‚o¥Z?U1tXE¡"ˆD£HŽkS%‰UZš<¡Ãå(I: +7ëõdC‘÷)Y¨h±R“+ëˆG`ä ¾ÕYÚˆ D!‡19]¤µ¹/(,|UÙA™­_âר‹ˆÊ q8DßdÊho{€¼p”Τ\:s-O¥ŠÀ1 V‘9è: * &Ò¯d5nF°vÝ* ÆÃ£à;gqkzFO¦§ñÚ÷—P4¬]k0hÃø15EaU©u3  kÖ Ú[–â·?Ô8>ŒÍ—É/»pJEìÅ«HÅúèõåŒ17ŒŸþ£Ö%õ¸:žCÇ2L ­)Ñ T¡Ìˆ±tiÃÎ1võ}púÞܰ›¶Õ]Cv¬Y¶ô¢5V¦Áñˆ6Ý.£5ÃæUKPšqɆ¨@•æ©BV‚!™rVê] {`"aÜhêFkä]ÊLê ÔÄ(º,®G/^'w¦„džiAÅU TD "È_©`¹ãÑåÑÛ8rî"š¡Ô°˜ö]¹ƒÉhÙ™"ÑD/ ቮåð*º y5[QÃ5‡(©bûƒ+ œAaŠpðÂ?˜`]´ÿôeõŠ|º½ [;š/ù(ûB"ºXP "4PŠcO¯_‰)¯Œ¿Î¦Q¼Õ¿gF]š(ùèjª‡[ôaU@`TíkŽcUÌe0DJ) ù²%'žm`"…ô£»‘æJòE«ôó0«¸ b+1ר ùƨ °c Y«˜¶¶zF0Lµ;ªJ³Zv ;‘µ¾ï;D„€ ÕyöHUºÛ üSï6{…¢RñÉIן:õï}{›Ng’^¡cŒ%2HxnÝë]{%c¬W("Î$ß|cÀýúä·ìd'² ###‹Ÿïlos¢±hÀû}} „©©iII*um\×Õ†}èÃ#V¼RWëaæê“éžžX«žW»µÿå—^¨}¦ÿÓÂ_"£øIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerCMake.png0000644000175000017500000000222012060166055021675 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ ±ë•IDAT8Ë­“[lTU†¿}®3œ)e:…‘‚‚ÃE)’`)Œ…¤ŠQK JåÒ@L#BbCŸ”0ñÒŒ „‹&Æ¢(`%úDµ"Œ¥0L)C§·sÎÌ9Û‡Ž  +ù“•µ²¿µöŸ½áâýíû®å±‚(w%¶nÝÀÊê ¥Eã¦Lû¿Ð1c®ç×ï=µ¶øáooõ¬r³fMàí_>å2î¡nfæ8(ØgwÞ²EÐÑQX—ê+ by6ÌuÝ;×Ö6P_ÿaEç•Ðt'+½Œ5ÔŸO€bU½=ðâūٶm%éôĺT ¤DI›¢HÔ˜fÀ/ž÷Ÿ›Ý°¾{÷»¹m?­L$‚e®ëcÛRØzDMÓœ7VÓʼòòÛ÷¸­-òò•+ ™Œ'דýjXêACÞgš< ½ ¼5ðºu¯ €?ªH&ógôõe²®ëaÛ=ä£ 2 ¯Ä²ªFéúTÄMÁÕÕkèíÝ,.\]é’Ä÷}Õu}[Š«î`!‚A᫊cY,DêŽM˜ hBܼ`Á*öìÙÁί­Ý5ÿÜ9ã1ÇÉbÛžp]èîê¡°”Ð`º®˜†A,®,gM:yÒ»TVÆßá×ÀMM ˆ\£µµpC*%ñýŒt!;;ÓÌ™}žšU÷â›ùèª&Mc”e±zĈõ‘æf²Rþ¼téJ°|yCe"a–Ù¶“q2>}v’… ÛXT'{²šTB!LMC7 98ð¦…ÃUåe7ô¸ªj¶Ý :’÷Ô'Y[UN—XñüeñøŒ<ÎÇS"Ù•²0 ]×EFQÄøü|æ þ*ÀñXLQs·Öªª^¤®®‘)S„¿vmãü¯*¸Ý0dôÅýmN¨#¿Ma·©ëd¬zÀè:š¦)º®S>1>ŸYrøpóœh”掎>“X¬éÈéc¡ÒÂ)§¥³ãq¦¨z@KjLŠOfBÛ£l8â25ÞF:¤®¢¨ ŠªòI{ûçËŽ­ü‹¥.Y²‚––ã,z¡aî¯?n ÎüŽîÞñ¼6Hƒâ(xš'‘‹¢%rŒÑ3ôöKyožî[ª)õ€.ºZÜÒÕµÿ¾¾vuXáNñûÙ÷ˆ‹ööÎ9íxÿ-™¤[`YžA?à@*èò̓bÇè³´½˜¾"ÆöçÉ¡ƒÂBþÈÏÚÏïú"6kÀégf×/¾øì©]?U7a÷ûẲ@ús²A±Á÷m 6þjËâPÊ+Í?V|Ÿºü•Ÿ|È8mjÌ|L /õrÜœ²àgŸ¬ÂÏZ7›Ä †YfhÒ°!RÀÂøÁ]ŽÕåcÅŸw×™%ÍT8IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerIDL.png0000644000175000017500000000253112060166056021333 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDùC» pHYsaa¨?§itIMEÜ 'ÜvI§æIDAT8˵•[LÔGÅÏö‚,–îvW÷].@”l­µU“\)uEC±5>ИJLš6jLEASJjBƒEIÃC£öbŒ†Ö¦¢ÆKËEªeÁ W#{avNPbš>´d2™™/_~3ç|3ÀÿÙb¢£)‹Á ×«4€:**J½cÇugg§š¤š¤úînõÞ={Ô¶ØX55uFF†úHe¥¥Û¶ÍLž¯ü[À];wŠ ±11€Å))&£qµN§+ààÌÏÏw^¿~ÝIÒIÒyûÖ-ç{ÅÅΩ}•Jµ!Ón÷Heeì$±‚É£`bbB”Òìʽ^oŠÉd‚Ãá€Ýn‡Ùlž†˜3gòòóñ¢^úúz<|ô@ŠÔJ)U&½^Àüyób\ŒŽŽfCCÿ©=s†q±±L]²„‡Ü””¨@À‚ðp@{GÇX¬Íæ;°?Çß]%§Æ5v;ªªª´ WÚÛý ÷ûŸ×jËžO_½Ðô㨠§©îö÷ó“²2®ÊÊäÊÌLnßµK¶»\$)§b~¾z•e'ës¦òŒ<›t|a²ñÉþŠæ@w÷T¼ìêí¥=7—“”S]®LOçÍ®®éÄãCCt:øƒÇ`0Ï õ64¼>j04ù7n¤ôû§Q~/-å1€ÇÖiµ<¡Ñ° G^KI‘EEôJ_N}ññô¤¥ÝõÔÔ¬x ¶úF<½%% ’R’2Ð×G_Z ZmhH!$úéè¤>€>Ž›ÍíY¿þc¡ŒŽnA_Ÿ^ èõã“7¯GG1kl,4 ŸOJŠ‚Y€"Bê+P`^/DooÜî!­Öt¹|ùI†‡.—†€aqq¸o±   Kº„€KQèR©ØE²W£¡°ZA‹…A‹…2<\“ 25õkUvvÈR~2âIzú¾À¦MÃìïŸïׯFf¾ÉD€iS&òMŽ÷î•lkcàòe¿ýŽãk׸×å|î! ÏÙíJù¾ÍÚÚ¦­&I®ýR&¦,–*½ž"2RÆ%'Ë}UU2ðŒÝzþäµãÇ·ÎtÄ0N "f'|XZzÃÕÓ3£ÂºïÝãW§N±®¾žíOm&Irhd„‡Že^é¶uŸ­zØÜ µ.9ÆÙ³·ð¸}**ú<@Uu5"""¶˜Ø&*S•¥Œã£íÛÑÙÕ…ÔW^ˆYaüæÎP„Éd°paR€_0++‹ÍÍÍ !<))evbb‚­­­t8À¥K—òD]]có¹sée»wë§_7ÓKF!B§óÄX­ç‡ݧOŸö>Âæ÷7ã­Œ M¦P¹£¥© Ÿ×Ô éüy€yî\Å`0„ùý¹aZímÕ°úµlïìĪåo ÞwõT„i5aŸ'q©õ'Ô×Ö¢ ¨p©¥¹yy€w22 k\ ­V«öA_ŸV%ÄÀ ×g¯ûϾº/ª«C:¬X¶ µf ''‹¤ÄD1?>^D™çŠüÜ·Åo7o ’‚¤èêèÅ……Âb6‹y6›ˆ³XÄFg¸ÐÒ,¾?{V|V^ø ^VÅ®H€25IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerD.png0000644000175000017500000000223312375423214021106 0ustar piotrpiotr‰PNG  IHDRÙ±\ƒgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ pHYs  šœÿIDAT8Ë=”Iˆ]E†¿Swx÷õë!Cw§ÓID’,”@‚Á‘5(£ "ˆ.tã&nt£Kn"8@ ݸt"!08Øš¡ÍÐ=½ô{Ý÷Ý©Îqq_\UQPýõñŸ_8z¬ùÆlÃCbfjffÜ]QE½ULSõ˜öÏq•÷îj¯8qòÌÙ÷Ãך¼}0â÷ó9¼ ’×HpqŒ‹H U‰•%VUhY¢EŽf¾(pqŒ„VV Œ ³cxô½ô‰CÓáŽ(8ÿuݳ×6ïÛ q£¾„ø¬G67ÇÚÕ¿É—©ÒŸgTÝâ¤ªØøÀƒìzýMæ¿ùÚ¶ÿñ›Û˜öž ã8Nʼ`÷±—ÙòØA|š"Q,`†æ=egU–/œçæçŸRv;¶éð3„­AYýów‹7ÊØCX¿2E9uß¾3šªº(ÆTÑ£7s ÌL$šM©º]²¹Y0°»Â` Ý¿‡Æè¸™÷ŒOoÜDÐl‚s˜¯çÀäËKˆsˆˆiU‘-ÌÛíÓ§(VVТÀªZ845‚¤‰D¡˜±1pB44B9Ò¥\m£YÉ–­€àÓTnœü˜ôæM©4ïAUÕÂ`õ·½·> ѲŠ- ´È\1yäyccHÒýgÊz³3™V¥Ë‹ø4…<BÌÐ"¯ãÕOo$͸FŒKšŒx„ñ‡ƒ|q‘•Ÿ.ÔîG84Lsb’lažrú¶¶^£Ð<ÇÔK?L:ŒV%b ͉I\3Aœ#››åöW_P´—%Hš˜ª ‚ˆÐºw'…¯ð3¿ 8ŸõÀÀÅ ÌŒÖÎÝÿž™Ö“w§Mçò%–~8G±¼„‹cª4­Kª®¡i–!ˆ ‹^š aáü÷¶vý*Z–à¤.¡0ÂT©ºz³35CŒpên-‹Z“»>”"] ƒ"¼•gÛƒûÏ|'«Þ×3F„­A«…‹"@ ÀÕyÇg=l}í¥ Ö÷ VLwÖ™º~™Œ¼·;÷LnzJDrój`˜:=°^CµF£¾Þ{ßï誮*Kw¹´o§,8ýæf^О–ò}IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerPerl.png0000644000175000017500000000270412060166056021627 0ustar piotrpiotr‰PNG  IHDR_%.-bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ 9.Ð÷¬iTXtCommentCreated with GIMPd.e(IDAT8ËU‘[lTe…×ΙNg:C;Ó–«´Ò/ØŠ€ÕCúš€BLP !(C `‚ø¢ÔˆŠhà…D–€(PJ¡"(`ï·émZ:mçÒ¹žsþsûpjXok¯/+{“PÔ·B3boÈšæ¥B¸”uAt4åûäMëßÙù€sN!œƒcx¬mC”ެ‰…c}×ú°{o¤þ^C1‰z£¯¬œ?€ µÕW‰S=®l6–aefH¢×Οmnz¸ ÀBß`ëf#£éÑýÐfZ)kœ›‰-·RÈõí YñžŸŽ}ñÑV²§ùĉ¯…ŠŠ]LjokëböÈÔ¢¹9ų Ý¢dÀà‡ýù8ôù»Ö©®;ì®  Ü„ÛÅÄ¢Åöí)çƒ)ž)a—Í«N7\Êv›+*v±ý;÷ âÅÓ·+/ýÑRYðD‰4sŽs‰=SG$šDÃåÁS­÷‡ë¨f½°ÎV î¯ PȲÊMS'î<ÓMlŒQØ&, E/¯ê©­«ïºÞpƒ‹4±ë¶ÆÙë3\1»ešÄêÇ»¾r'3/ïÓ¤öÙQ¡È §š ÃЈp ¦a€1ƒÛ³˜CpX//{úõšåå×B¹Ë?‹0…%¬@Rƒq…Í}ž­$S«ÆôÆRU ":1Áã‰(%A4=ÅUšâT“AšâpÏðüÞ÷@Šök Ô½«{ùïU–Ó˜Ÿi§¶¤(³!*r àœpŽôã ÀNè&`s$« p8…ø@œ©y[Ø'jxØV—Pž©A™¦™\¡TOjÊœš2¨!CÕe®h2Wu™SC&ÔLU“‘”S`¢•ûæÚm¹âÅ›uX^° u7ðßäWózʨ¥œaŒ1“˜‚Át¢ëg°ÀE“èL'¦iAU-’”MÑ䣅$“Rvqg¾u7p!ù.¶¿ÿ¥¬õÍû;®Å=‰”žkwÛ¦ˆNCYˆ„D§ÉeÅ‚£:R Î%·‰ _`‡àš©“ŽÆd¤é ýF—YLºµ?ÐÐy¾Ø´pöÚysÚkÂbw¡¯ÑòÙühÆk‰%£Ã)´^«KKKò¹³ñ ?ÖcøòšrçbQ«ý¯ G€Ö¨wø|xkcyÚ¢eøÏoÞ¬Ö±†æÆÑ3³ôò½‰ñ,+1`\ºlÑÍà(G{G°aKΩOMê66ŸX0 >s®§½Ý;>œ„Sƒ¹Âa†þûÉ+Ÿ>p•ëÞK0=È+àŠè‚”¤ nÚ¾â=@D{Xãdú“Þ¶ìÇÀ÷1ÔÓCß~àœKQµ$èãÿ$ǵëà‘ nYr&Œì‰ÜÑp¬44ÂôáÛÊUB•UbŠ“Þž¸«ÀäÛ}-1“mC‰Þãñ˜s¬M> À€BׂÎv­¿mé+e/ô{ç ÝOÐ Y4ÍËp>^·¡âQÓ›\Â2”­=ôc§ÏG:KEj±;˜ù¼»m0Ôraà`:sdå0É¡äÌ@ž}ÁÿO‘VcðÊÂ'*¾¯¼SùTØ» `x”çµÆ;7öð¾Âk÷êűÆH?tw5½¥ò¿ú0«|õ"ïcÓòägûîþÒx¼Ï?X•­åœOϫΜœV;PûLÇ˜Ï µ‡ö¨·Ìc鬺ú¬³³·Kømº]€yû¸Q¡IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerMatlab.png0000644000175000017500000000215312060166056022123 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ - ÂZ4(øIDAT8Ë­•mh•eÇ×}žç<ÏÎÛsÎÙ‹ÇéærN75wf’b¹¦BJÔ‡$¡„H± “EoÑ×À>„„š•`aD/ˆ…)Ñ2­Šºi`®•/D¶7çë^ÎvžçêÃtC$Úõé¾àº~\×ÿæþßp‡±8†ÔÇGÎÓ#Ü}¬ˆË-¹®à çqÍ« Y°2¹cRAQ!÷TÏ05‘èŽmsÐí ¹ dì;€ÏžIví3#Iíü†'⮞|=ú*º6ÁöQY2c=·µ‚?·ÿ ªi¿nÖÊ$îBÄr#pKИqÃÀw‹ß¼ð €Ü¿þÙúXazCÌK¬´Î:L˾&ãær,r|‰¥!éB$¡È ˆ"Æ€S—„XøƒÏÞ`Å&N(\ðRãsÅÕÓWJàϵDê¹H®§GËfÏ\—Ô—»È„Á²F¦u ˜ø ¾ùu ¬öÖ‚1n:•ˆ—fžöÊ&Ïg&à A " Þ©6²>Bà Ð< õAî åÐíÏCBYDŽCêïî¹|ú«¯·yåŽíº‹,Ë’`0ÇÒ¿ç;|ä˜DmH8ˆç"‘„]D]t0‡\êAþîF:û@cÃù p<”®šÆ@o/g›~lºÞÕ½/QR´,ïÞµO¿ðË› ü°…‰…!jƒ%`BXhßrª“ßš»ØÝ=LÎ…r¢§á¨ã5n|çæ…¦JçÕ5„¶tÔÁ‡ ¸7m£eq$‡¸‹Æ£h89q=ëòè¨GÃ[)xó/ÈÞb®•K26n昵*DKY {b!zàXhÔBÎ prm+Y@—G°÷ö“ÐØØ®Œ÷ò2À?€ëŠùhÞDÖeЄV9ßIÇ‹‡¨½]ïeaC+ÌÚÆª×+:n@Ú o—Ì‚© JëË1†?kgÉèÚ’E6´Þ¨»Qÿ ˜~h¹-?þy«4_=hô—w9ùÔBª´Š»ü‡>?²øÀ®‚FÀøþuä¿zþfIT1n¬š²IEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerHTML.png0000644000175000017500000000243412060166056021471 0ustar piotrpiotr‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs  šœtIMEÜ  j2MiTXtCommentCreated with GIMPd.e€IDAT8Ë”O¨^WÅëÜû½ï½¤‰I¬y©TmiÑI R¥õÏĉgB©Ô?¢¡UŠ:‹3„‚tàHÄ‚J­4Ä’’’JcxÉËÓ¾¿ßûîwïÙ{9¸ï5uæÃÝgß{×Yg½—¾ùô“'Žkøöj;ÿôtI÷4“–Ò64“†2ihÚf\·-¥iXlm1ßÛѸ&YƒÅÀl-Žü~W+?þÉó¿ÜÔן~òø‡ÚÙ_mn?²´$ÚåÆÍr«f:¡L[7ÓVe©AmƒJqînÉ}çèªr²«ÎEU,‚¡O¿\ï{ýºO>ZŽ?sŽ[7Å.EV*²YP#«È*8÷7qÛ(6¤‘Ac\|"ÿùÐR«voH$DA!I¤FŒ9än[Ê*2Â$8…Sd ¨zϰýx‹ã˜»ÃP<æs¾ƒr(FœØó`:q&Î{¥m›öÏ>BöøcCvûf˜£Æ”F”Vv 1OÇi×»ñ¤m)ýöÛ ·P3QY>&'”å“R»¢2=Ž4UY>!˜J“¨Lå¡¢¥{ò åÈ)¹†rWÛ¶´“É„ØØä}_x–•Ó÷ó¯_|‡G~øG6þð<÷>ñE$ðŸ—~ΩǾÄìÊ‹Ü~á9>ðPYbíWßåÌSçùÇW?JF5h›–Ò¶Us¤coÛÞ¾ð_zê>lûês÷¿ûS´'ïwݯLNœ6f”Àv ƒ³YÃ’hK)ãåz¤–‰%)ûž¦È’Tã¡÷ä䪚•{}'crŠ!ˆ!5ÇS)äãg?åœid°ß9†Ä¶³Oç"í¡cغã£=A·vݤ³}g ÇDMSðX޶´}õ¢®œIÊaì¦1NEŸ20¿ñºŽŸý,ÝÍk2(† FµEM¢†œ¦Ø&Sˆ½-æoþ€¨ÃX~ѱ°™¿u•£<Ëþ7Àãw`b1Cà!)™”Hj<‚ÇAS„©uŒkw“ÝëW@böÖ5Àdš2=‡Ÿý|íGÔ!èúJóɇøòûwÖV£³›o2»v‰ùö;¯½BÌvévgì\~…:ßg¾¹Ãæ…ß1[_çíW_d¶~‡íËØ]¿ÃþÆ{·×عz‘µc«·ôýÏæÕ­_:7N‹ŽìfV9°‹‚%„@ÂkÓ6JƒÓv¢HÈ´3ÑßΜûk;ô¶˜ïΠïLc‘2™Ð½ËIüúa2<‚’Ÿ‹EOÛÍçÔímpZE4ETÛHB¶ÃŒß1°qD޶’9¾‰´ûEO»µ»×eŒeå0N›"Àv„»šÑ¥$lTsÜ[iHÛFÚ]ô]ym/_š >8hÚ8L†Éj2’¨&ªÉ YMã:LdRÒ£Ëö¥åòÌnöºþrwêôçdïT›ñ?¶|(åè¨#ß|W<’57Е ¿nN_¿xsã+XYY9³úÞ“ß{pEµò”ÿsÚ·ÁôoÌý§Û›[?˜íÏoü ^N8¼ÅÞIEND®B`‚eric-6.0.8/eric/icons/default/languages/lexerXML.png0000644000175000017500000000204212060166056021360 0ustar piotrpiotr‰PNG  IHDRójœ RPLTEø€(ÿÿÿø€0ø¨`ø Xü”Lø°hø°pø˜Pø@ø Pøx øˆ8ðp üüüø˜Hø¨høx(ø¸xøˆ@øHø¨Xøˆ0èhðhø `øpøpüìàüäÔè`ø¸püàÌüðìüôððpüÜÈüèàè`üØÄðPüàÐüðäü”PüÜÌü¤hø€8ü¼ø HøxüäÐüèÜüèØüÀ”ø8ø¨lø°`ø˜@üÀ˜øœ\ðhøp üôìüЬü´€ü˜Xø°tüؼø¸€ü hø¨pø døœXðpü¤pøÈ¨ø¸øÈ ðHðXø˜Tðhð@üLð`(üœ`øÐ¸ü¸ˆøˆHü¨tø€ üøôüÔ´øÌ°üÜÄðx ð€HøPü”TøÄ ø˜XøÔ¼ü¸Œð`ðx(ü lüøøü¬xøx0ðp@øÈ˜øÀˆø¬tðPð` ðp(üœdø°€ø hø¸ øÐÀüàÔðh0ø°xðh ü˜\ø¸ˆð`ø¤høØÈüȬü°€ø¤døˆPð€8øàØð€PðXð`øÀ ðhðXðPü°„ü¬|øœ`ðPø”TðxHðh(øÐ°øÐ¨øÀø¨xðˆ`ü¼˜ø0ø¬pø˜8ø°|ø¸„øÀ˜øÈ°ðHø°ˆðp8øXü¨xðx0øØÀø pøÀ¨øàÐðˆ8è8ð`øààð€0ø°ð¨ˆø”Pð €øèàèHè0øðèð˜xøÈ¸ø˜püôôðxPð˜Xð€@ðh8üPðPø¸˜ðXâsbKGDˆH pHYs  šœtIMEÜ  =ÔmFVIDATÓeÑÍJÃ@à{g’ÉϤ“¦5Åj v  [¬‚¶ÒvQªéF)þ"Ô®ÜØ¥ oàÆEºv勸^ÞI<À|aCÝï÷µ¾ÑÉpð~:™w»Ý·&Bs{á8N±¸Ã¹emÆFˆZ˜s^µÆn¦ÄMR!мJeßp@<…ºc´h&\7ë2vO#BÐBS×µÃTÙ9ìr£´àÛvH Œ•áŽ{AT ÃèzÈÛpÇØ)`Gã ‚¸WGbø‚‰ï#b¨(UÎ ¾ï+Õ u¢Î7s.…aQFÔV_W%àÖ§’:y ÃRJâù¬"‰n½ñ­À°RH|@_Q™‡^é2É‹ç&• çy .Zée®­’\»V•ôÀ?<~ê'ë¥så>¼Í‘2á‰ê¹^©îÈŒ˜ŠÚ‰ª@U„‹B¥*(Qß7$o4[ßñ%["•”Jv’9†îfÉÍ,™¹1ÅÔažÌ<™fÈ@fS˜IJµ‡q~è±Üä&™*``@NŽ`ýTPPJ†Å‚+ÐBuE5@!Pk¥i‘Í=pp3ÌÌ@êÚŠh„Q¡›JÍ  †¸F)Ûî´Õ¼­”NV¥Jµ%ÀS ßÛíuïNG{Xéûk§6>8²ÕõLwŒOfòÌÅò 7!ŽØ©‡—súy¥Ö°RƒÒ9er3h8Ø+DˆÃ±qÖíÉo>Äê©L™‹?=·ÃÅËÇíÖæ„ÉNÇÅÏçê•]ÿÊYúYµÙ^åWßû'wߘR,è Œ<á9'3îF׉ɤR«xù[ÜØÜçü£«D…ýwzö· ¥í$èÛàÅgï‚Ãù®0Ýë)%èKEîî„‚J d†î]Ÿiçs|ÀâQ”Œ¨Òô Eº}mªé»Ìûª®º¾"‰ŒUAÈ"¬ñØÓ§9óðˆ«¿ÜåÂhÍ>þÅ“DóIØì°àÙ쉯åô‡–øÃ ÛÔSE} ":‰QU™¡Ñ)øÝO·xùùmš‘ëõ—Þå?y…¨!Rc¤ãÒ•ïÞàÕw±%èû /A ‘C‹ ¨#$R/}‹Í+;¬ –œ;×ZþusÆÅÏœ —¨E¼ðÌ-n¿>ai=C² ¯"ÂÈQƒPP.£ªÚò¸! ÑSX^Ï6:æ ÆÆÊzF.F« KfJP JW º"æ]GúÄ#O}ýp{ýÌ`žÌ§U;[-·^;°é^ûû3Ýxußv·flÝ™róêÛw§Üøëæ}µ (±@ׇ6&%w¥G&Ü3mNz~ýÜ]FK†Ãd"øÍÞ¦%Ü·ÞØ×`èöæßîk¸’À¡Ô F¨Ré«1›uä¾ï¸¿×ÒÍ ¹Ñ,%º²Xu_2„ihVyÙ-X¬q *,ŠjÌç3òááÜÛI%èqÏ€Q)ø‘ ™"Ž¿##¿''Ä$$ÌÐÑONÓÕ   !!!"""#$&&&----0'!6 888>>>?AAAD E##GGGGIIIN( RD9RRRTTTUUUX(YVT]]]`?%dH0fbagGGgREic`l4ooopVFtG!w8xDxxx{]C|A ~H:ƒƒƒ………‰‰‰ŠŠŠŽŽŽ`4“““–88šb9¤rK°LK°W=±™‚¸¸¸ºFD¾LK¾TTÀÀÀÁJEÁKFÅ ÆhgÊLDËÒSSÒ``ÖWVØØ][Ø^]ØqpÙddÛÛQQßááZZáhhâäOOä‹äŽŒåæ~}惂ççjhçèaa蜚蠞衠ê^]ëëZYíZZîÿÿÿã0K°utRNS #'++,,,,--.11134BCJYff‚„•›ª¬®®®®®µµ¸¹ÀÁÄÆÇÍÍÍÐÑÑÑÑÑÑÒÒ×ÙÙÜßééêìðððòòõõö÷÷÷øøùùùùúûûûüüýýýþþþþþþþþþþþþþþþþþüÈÕbKGDç¶kj“hIDATÓc` 5`V0Óf`Ö5S`F– ÎL6ad4IÎŒ’ 2I™¦6Vx©©{U4f˜J1ADÙ ýVÌ.O^·.¹|öæC6°°Räú-»×Ô6ww7×®Ù¿e}¤HTÜ#­gr_ÇŒš²²š“&÷¤yˆ30°Û'®Ý°qqSý´èèiõM‹7nX›hÏΠ:¯µ²náôê6_ß [ç/¬«ìݡȠŸÔ0uÉ‚öYU}!‡`õž3{;[¦lÛ>§«4ÅÂûÁýkw9{츃^|ÿÜ¥Ëf¦»)sHz^¿uóÔåó'rŒdƒV._´jS¬*ÐQB>wïÜ»zé@˜,‹NxÖ®ì.cåŠ=}r:N‡…UÞÀÕ\…$*èpîÆ³ÇÝ%P‘ߺàä•ÀÛŠm…µòÚIÛ–Í×FsʵâcàµÌwC1ED“Hrkˆ2A×›ÌÈ7IEND®B`‚eric-6.0.8/eric/icons/default/chromium.png0000644000175000017500000000576312342633754017561 0ustar piotrpiotr‰PNG  IHDR00Wù‡ ºIDAThÞÕZ lÕþçÚÃÞõb'±’u.ÇI(Ji€Ô¢F¨¨-A)¡!*B ¨ª(¨4½h„r´€TZ Di j\iÁ$Ä„p8‡I°ÛøÜsÎþÿ›7ÇîÎ:6¢Héyfwfg¾ï?¿÷Æ‚eYp&o"œáÛO@vAø¬÷Vozj¶,‡W ’²o4i?…Ãâ÷Ç?¦Ñ‰ºMCߥkÙ;~¶öˆ{Á$7'ô÷`òÄ5›ÿ´N…nDyEÿâ^’‹Y"NÃ4؃MÜÛ뺚{pû}ß{‚è}QD´ø”pt³(J’,L€ó~t/Ëy2ÿ„„t4¦aWÕ̽/Üýã%òY—ßúP"¯|R–Cʲ ŠlÜ`¼ûXŒ{¦e¢c"¡i蚺;“YûòC·>]hM–€xÙ­[×DÊ+%±"ƒHÀý#„ß –‡Äò¸{C‰ÂÉ2!›Ín˜£ÙÔèúö‡o~~‚dVÝ,Ú—>n/qŒB¹fí¦=À™@-äXÿ–míë$E™AÝU’H$ΆÎÎC ©(!y\K-IÔÃu_[çàÞó€&C)ºÒ0’Öó3ù!òÐü{'Ç04mÆêåû×}kÅ’­þ„.DŠÄ«o’%ÉevS?ÞCCàæ4…”¢ '‹ßqÍpakô f¡íÝ85¢AF5Šª2‡Íõå°¨1ctL•ôÝ^B²èT=*ÈP]]{ž"¹‘ ÊáêÛ·xÁW.ÝFPߨ?¦­§·::ÞfV$ë„Â!—`9‚ÿÅ—BÃÔ*xy_?t÷gÐs"óžÈ–w,Xã±4M‰ÀÅ‹kAÃãƒ'’X,v]HQšØ %1¸©fs*´¿ôs6m\{ÀâÀýó©~Ö«@(êC0­~ Ô××±P0 ÃÉ+·¯9¦O©„¿ì:ö$H¯Ñu¼Ž†fïï»zSðüë½ ts}zFš˜±ˆa$Q ¼³Í_¸ø*Â4¡QBeåËIWæÍK U%–«:uɬ ËZØx±ã$ôbèHÝàÀÙ0Ø^wöüüÉ¡,ìÜs*"2>aŒØÊÊãË k œ”´ˆ‚¨««âÐØØÀk8°VÿõesáØ©4úxÔÏ@ZßpÉèl˜ÌOBw_*£ò¤„ÃÑ–RdQ Mð"«„’m]8of$ê«ã°¨¹þ{èS;døp­¯y!ärÒ~ÿ‘aŒ};îO«ÿy$H¡ÐtñóæÇþ†p“ö‚yóæ°ãºÚ#Ò…q¯;Öw¾2l2>"Ù#˜äMiü}Æ[ÎëÊ>½b‹®âéIbV;ö1,FëÓµ£i +–ˆZ†—<^Ï…i턞£{H´õä˜¹È 9}"³0W[ }À¹€"Z‚ý¡ $Q‰lm]€§rì:-I¥ÕlÓ.®ÌÎÓB<퉀e'´iMlVïDEaëÈ#àH[o‹-àÝúºH °›‘ÕUJL¿RuDžYÚ,ð€¢ˆì9ôûÓ[Þó`I~¥hq´/ì 2R5…ŸYW»GØw’èÍÒÄYêÜÛd¢Ö&‘˜³?›°¾K¾´,-—=i„”z²*], xѲgk*†KJ‚–¦ ØÛ5ä‚}ú%HôùChy ud{6>xûw*„drì#Jû«™K}HµšZ?=Ä2=Í´½ß›eójàlì¨Y¬49üm–†0Ø÷¦{LžKLA*gN(qMž3©Tº—j}l¨¯CGéêNó|3¥ ípzGT¸éÊÓ>6X20ã7‹ÈL­ ×'X쫺uÚØwÂŒÊqßÉŽR´Ã{Ûv: fŒ íÕG¬[®_ ³Pmæ[ÝŸñ}G×Üqõ…¸õÂ$&·¤O}ï™pËywÓŒL,{²V^S*$¡âÚÀ¬)ahU +$ôú3ˆš×>aàZbãWººCðïx†0úC¨pNÁÑxÃÖ7^+ÅêBä1ß ¢è-­”Z +‹ö$&j[¸ó„fcÉœÁÞE ª­ÏW}ÎbÆ!ëžúîª9+ðôqš8¸ µ³Šc¨·kßc´¸Ä4<ÝŒky6)q>›fÉä¦ÊòÉ {2Ðy" Çs <ÓóÓ¢EàýuÞ‰wO–§$OãLð½}o=FØ8ÆqW%¢8®ûõ+Ï—WÖ,‰FÂv.pËzÁ^/*X™ð—6®>ÙÔ¯š_Åf{EV÷É 'lüX: ýû7\yμì„3©/åÚr8>Ýóâ#›qæ•Êaì1ëάÊ?Ÿ*:ÞaýÃYï¡D4ðæŽ§îݰ—ÉOyµÑ?ï—|…Þó°"TÍþòÍsÎÿƪøY K‘X‚„*Ëhª‹ÙJŠ[?“9šNèéÞ¿·í¯¯îk¡ /æOñ:ÿ{ÍD$Ä;w5Z~á Ob@ÑxhP7Mra–áòà {Ѹ˜ÌA+üX*ñ¢ÆàCãÃøÜþÕàLÝþž¼d£Ó¢ÉIEND®B`‚eric-6.0.8/eric/icons/default/minus.png0000644000175000017500000000123412342633755017057 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<bPLTEÿÿÿÿÿÿÿÿÿ’â÷vvуƒ“äïÀ``•Ýö““ᯯ•›çé› ¥¦))§00©«22¬­® ±² µ¶ ¹¹¹::» ¼^^½¾  ÂIIÂaaÅkkÆÆ ÉMMÉaaÉeeÊË Ë$$ÍÍSSÎMMÏ ÏhhÑSSÑrrÒÒ ÔMMÕnnÕ’’ÖÖ ÖSSØXXØmmØÙXXÚÚMMÛ ÛSSÛYYÛccÛkkÛÜ[[ÜjjÝMMÝYYÞQQÞSSÞYYÞß ßà§§áSSâNNâã ãTTäSS䌌åSSå\\å``åll匌æ00æSSçTT猌玎èYYèll苋茌éZZ錌륥ì99ô††þýý¢otRNS ##:?µµ»ÌØØíñööööäîïNIDATÕÁ1 1Ð?3™$«b·`gëÝ<ç±lÅë‚…I4‰K°ïa˜ð‡ Xß¿˜°þø¥í÷)fÛëÐy6F2*ªã]Ì?cH¹PB»Ž›K4hƒi”m¥Î•ü<©Åƒt_Ø7‡RbÁëU‰ ˆ÷D"̬¬*NÝ!LÔõ41ñ_åj\IEND®B`‚eric-6.0.8/eric/icons/default/drawRectangle.png0000644000175000017500000000072312342633754020507 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ®®±ÁÁÅœœ¡žž£ŸŸ£¡¡¥¢¢§££§¥¥©§§«§§¬ªª­««°¬¬¯®®±°°´´´¹¸¸½½½ÁÁÁÆåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ¢ÒítRNSââØ:Öä¦IDAT•Á1N@ÁêÑYr`ÿÿ‰& CÜíøRBªüHÌß½_ñ÷×ìÚ]ë­|~þ3ìQ”Þb¿–ÃŽ›I¾,ÃV”iÙGËá9\›dož ·šò²zÖåðnqåÁáYƒÛn®<9ì¸5n^Ú–Ã4¸µ¬ì<J îÒ*£qk\+;¢†[›MÂÜîf‹Ãxn›ó8/·Ö¢ß¾ûX?óçLOR€âO–IEND®B`‚eric-6.0.8/eric/icons/default/task.png0000644000175000017500000000134612342633755016672 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<hPLTEÿÿÿ:˜˜˜<›››———ÎÎÎÍÍÍÎÎÎÏÏÏÐÐÐ2•22–22˜22™22š27—77š7ØØØÛÛÛƒ…ˆŒ…‰ ’•– –™ V Ÿ! #¡$R $™&R#'˜)£*¥+\%-§0˜,1©2•.2™.3–/3«5’/5›/5 $6’06¬6­7œ07© 7­9©0:¯= 3?¡4A¢6B£6D£7E¥7E¶%F¦9H·&I§9Iµ1I¸'K³:L¹+Lº(Mº)NªXÁ/Z°BZ°C]Á>]Á?`Æ3qÍK~ÕS†Ë~”Ô†›Ó—¤Ù›¹¹¹ÆÆÆÑÑÑñóñòôòóõóôôôôöôõõõõöôõ÷ôõ÷õööööøõ÷÷÷÷ùöøøøøú÷øúøùùùùûùúúúúüúûûûüüüýýý&€tRNSWdkp|ÃÄÄÄÄýýýýýýýþþÇ» ÐÏIDATEÁÏ.QÀáß½sf&2!EDˆø³¨°åMú}ÐG`Ï‚µ=¡B‚‹¦IͽsÎÑ ñ}!Fü0Ré‰q¸ßÁíÑØœeõöB1æ6Ÿs+„VeZZ™7z/\Ü5ÚÌDºêaýI=4C”‚SÁùÓ]ë‰}!]Þwê.?ÒÕëÖ±‚‘¨H7;Gb ®éÖûv÷~Ð/\°\MÇöµ»WsKÛŸæÍZmÌ™`Ô«_‘hϳx²L‰g Uä_V¾ªiì hsIEND®B`‚eric-6.0.8/eric/icons/default/preferences-mail_generic.png0000644000175000017500000000103612342633755022641 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<½PLTEÿÿÿž¶Ó¤·Í¥¸Í«¾Ö­ÀÖ³ÇÞ¹ÆÕ½ÌݾÎáÀÍÛÀÒåÁÔéÉÔáÏÞñÑÚåÒÝèÕÞéÕàïÖãõØÝãØáìÙâëÚåôÛàçÛäîÛæõÝæñÞçòßéöâèîäìöåéíéêëéï÷êìíëëëííííòøïïïðððñòòñóöòòòòõøóóóôõõõõõõøùöøùøøøûûûüüüüüýþþþ ÀåÁ tRNS /0=>?€Ü¾IDATmÁÂ0À÷¡ÀÃݽ¸K‚´ÈýE:Ã0P² ±‚XA`!ˆ8N,Äq"ˆ_ï®q°ÒóCz‚íZñ|ùr.ÖÚ]·Ÿ›Ÿ>æ¹¾ëœåêþ­ZžgVv±1ÙÖ,@p'Óõº“JŽ—‚[c”YíJù|i·ÊŒ¶A­õ°pPJ J©Ca¨µ&èyÝúåK½ëyýæÔÿ1múÇ[ȱA$Ï?¢´ˆB`!+ˆÄê7ñ1zIYIEND®B`‚eric-6.0.8/eric/icons/default/pluginUninstall.png0000644000175000017500000000256612342633755021125 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ- •ïztEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ÚIDAT8Ë“[lTU†ÿ}Ιé\:tÚ½P°-—Z°´^AÁˆMD$5Æ5šh|1š˜˜˜Hâƒ(>™è H0`Pb0>й—…^æÒéÜÎÞçìËòa¦ÁâJþì½V²¿ýg¯µî ^=´" b›{ú6ÆCÍMS^ªt.30—©×·õ ^Áÿ—®Ü5˜ÎOþmÆ“#«nuÌ<Ï,ꜽ’:fu2®9„æàÚµ2~ \¹àÚÅt]nM_$ˆƒÁ@Èò8ÝuÛSH †¢ÊkOó ¨˜Ù‹²{Ã! ‡G.qh&!}cÝ6ˆ0‹PÒù0s³\xTv(h:ðáÁ² \•‡ÔÄfÀkwv?ÈÓþ0 Z÷›•tÂpø¦âÒ¸ðŒ€¨8ó‰Ã‡dˆIøT@IÀÉ@*”Áo]ºéµÞ7?)\5I1j9–¼JÃ3|ÆGegå•CABCPã¹1…Ã@Æ’ÊÓùn{dI{ÇûËïFKmƒd!$ýxÄá· GYŠùà4—ŠpuŠÑý.T<ó_ …°–¤úÌSvS¤W¹]©¿y$˜}]¡Ô¿” EwUlçÓVt’£  ¸Šè¹U`oò ¥ Ž¡1ÐO}Îc"¢ElûE‚P!€À$ ½Éjª5Þûe!³@‘AÞ³BØŒƒ‹lúpJnm-¹ÅA'͈âß´d8+¤?ÙŠ<%³ ­b`“ºñ#V¸Ì¬q÷!´œbÓ;˜\ñ¦G&‚K`úNñpiÚæ¢R± ¡ç=% údVXå<6‰ÏP Œ¡ù4ì´àÇaÁÍa[‰ 9Û*@(xp˜–ÀBVõE˜mCç¾þ¼âæÈÀ7:„Žv¾ÐLÇ0» Ú@E˜m4ØÚܦެÁ¯_Àú D~Å9BÈ•5À DS§ Œ]¸réehƒ{-¸ñ54€ÔûZZ éR% vØP¦€Øäi><ÿ=—¯}ËÉ窼{6d¿®¬_P®»­4tÉ|:10í£Ìuø©µÈÅÕ]váËË®Ý\tcÊG8ÛÀoé®Ò Nqüð™Gäš‚^.Øê¼{_Î)ÁªçJjö4òj<üÙÓ}Þzç ³õ^{ãÏŸgQÅ[ø¶TYb"‘Ü×l0%¼ ÈMÎ]èqî£eøã´×ËÐN±YÓ*`ýl°õø!»P{ ÅŒ‡MÅPøJ‡"º¾Ýƒä>ògW·f A«[‡_y5Ûøªñ{1?~Ä>äg1zþh×ÙuïÒÎÁ—`uüÄ n\¿¬T8t¥A¥Ž!¥A4%ûˆ.w„­„nݰýÉ.({|y™¿£ðˆK¡ËŒIEND®B`‚eric-6.0.8/eric/icons/default/pluginArchiveSnapshot.png0000644000175000017500000000232212342633755022243 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<_IDAT8Ë…UKL\Uþι÷Θ)ƒSЈ‚š4°Ú†„Ø… wMºmLLì²q§&ºªw.êÊ 66iZ$>RâcB€@fxÌfîÜǹ÷úŸÓaÒ?óÏÍ=ïÿþïÿϹ,<ÏÖî¡Çerƒü×ìäíêóö°VÀö=Þ"¿F~…<òtʧ= ¥JíÞ¬¡³™Kï}±Ý˜€ÒFãÎÙÛ†z“sžüÿbÏóaÙ.\! ±ïÁu]ØŽµmYÖ¶eϺ®óã»·~ø‡Íܽ9R·‚¯äz­Ò2-‡@hý˜ w›.N¿×MóuèÙd¢=±½{€ÇËb%MfáE6¢‘0â±ð1h+'ûÔ>á9ÂçK{j^/^LÀ¶,ü½”Gù°X4¤‰.mtÎqL 332*–à86\Ëá\N™ð*¦‡åm¾/0ØŸB²#?1Œ­ƒÓi?•!ÒÙ‹dß%˜G%l¯þN„Ì〾ï0Ýs}Ö€T°‡}çvK&º»¢àTSm}™$*G Û%d.D‘¸HÍÂtäÿýéT ©ó3ͦC&\ÝÐ öQ8êB$ìbßçðЦ9n`0×Mcgeî {÷°|¶Ãu€å 5èèzÔvØÛxŒpP† tl¡£j†Ãü™‚ì‚éð˜ëP;Q?K÷À *?@wgôC3 é:vö„Ú¼Z¨bú/ͳ¥ÓÜK]>^íyp® ?`2Šd,íòRé@²«Ej .OÃâz;ÅC<œ/";8„‰‰ ´··cjj ®® »èéç>`lúÎû×¾“ëº|½‘¶:DßÏîcc³ˆH$ƒæ¸¦!#•JaggŒ1âÆc`nnŽúX 7Ý1­{ž§Z¤)E\óè¸ZøöÞ.._¹ŠÜˇ(•JJwÛ¶aš&–——Ñßßîîn´¾¾®|ddDš›{tM§ 樔ñD&@ºƒiºb²¶¶†­­-lll “É(öÙlV‘˜™™¡žõ‘ËåÐÓÓƒÅÅE: èÞ`zÝ6«>c×·Õb tâÂqÅL£Ô£Ñ¨JYšÊ(W2¬¬¬ Z­*id&étZÉQ©T(;Ëç×?¾7Õpüš²|OÀnÔjµs/#ÉNTf × `xxX–Aš"Ë¿ïü|÷Æ'÷£•ºýYT¯¹¦ék~Ò¤žRk™v,SÒ "‘H ™Lª,Ëåò3à¦}ôÕo·o~þ0dØùoZ]¡RCÉvll ›››XXXPdÑd6Rº3ÀM»õõ£‚s>-RsÉH‚P099‰ññq¥»oÖEIÒŠ™Ä•ìNZ(RãÅbQé-‹(ßÕå^¯«þ–A©vËoÞèèèÒñj>Ÿ—›b³F=/ÈU4H»ŽÑX•í6KA¾üâÞ Ç™¯EbIEND®B`‚eric-6.0.8/eric/icons/default/forward.png0000644000175000017500000000211112342633755017363 0ustar piotrpiotr‰PNG  IHDRójœ pHYs „ „ªâcytIME× ƒ/ÒyPLTE3aÿÿÿÿÿÿ4d9kq-Yš2`¤7_>g "<[!G}Do« - 6 > $F %G$A'I-U4a4b.S*;/C4^5K:n5\6ZTª#ö;±{ÿƒ{÷íÙµsûƽF2a‡¹³¯Ú°yë–Më—/˜3er˜ŠHصm¬…KW¯^½lѼžâ´P_=Q °GbVEcG_WK]YvzRtH®PØ3"5¯¼¶¡©¾º¼ #%>ÊL‰ä¿Èäܪö©3&õ·ÖådÆHC¬T³±¶²´pž?}bsea°ªŠ/]Ö,™Öo,ˈêy·mkgÆj‹£‡‰×ŽNSytQθp}I,®¬ È@.¹X[1ì¡IEND®B`‚eric-6.0.8/eric/icons/default/unhighlight.png0000644000175000017500000000063512342633755020242 0ustar piotrpiotr‰PNG  IHDRl" pHYs  šœÉPLTE@ @/`?€OŸ`¿0_BsßWŸƒ÷+?lÀ<_ÿ$‚ß$“ÿ&C`'S.—ÿ0x¿1•÷7l 7›ÿ<žÿAàE£ÿHe€I†ÀO¨ÿQ¤÷W­ÿ]¯ÿ` f´ÿy®ßzž¿€†Åÿ‹ÇÿÆ÷Êÿ”Ìÿ•½ß™ÏÿÐÿžÑÿ¦Õÿ§Öÿ¯Ö÷¯Úÿ°Ûÿ¹ßÿ¾âÿÀÂäÿÇçÿÌéÿÑìÿÕîÿÙñÿãõÿëúÿðüÿòýÿÿFÉ[ÈtRNS@æØfmIDATÓc`Àìíl­-ÍŒtT•dœÌ1U8™«á³±²051Ô×TŠ ñ¦tµÔb²âÂ|¤ê56ÐÓÖŠ)+ÊK‰’l/DLANZRL€—‹ƒ‰4½ `1 A~nN6VfF! 7ÎȦcbIEND®B`‚eric-6.0.8/eric/icons/default/certificates.png0000644000175000017500000000234312342633754020372 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs „ „ªâcytIMEÚ 1ÌIäµPLTEÿÿ+Œ oŽ ¦ ÑÑ©ª«¨©ª§ «°‹Œˆ‰Š„ƒŽÀo½©© Î GIüqrørsöuuö€ô‚„ô…‡ö†‡öˆ‰öŒŽôó’“õ•–ó˜™ó›œôžŸô ¢¥¡¢¥¡£¤¤¦¤¦¦¨¤§¨ó§©¤¨©ñ¨ª¤ª¬ò«®¤¬·¹­¯ó¯ ²tJ··¸·º¼¸¹ºº»¼½¾¾¾ÀÂÃÂl^ÂÂÃÃ0ÃÃÃÅÅÆÅÆÇÆÆÇÈÇÈÈÈÉÉÉÊÊÉÌðÊÊ MË ËËÌÍÍÎÍÎÎÏš{ϧ_ÑÑÒÓÒÒ— ÒÓòÒÔïÔ› Ôœ ÔÕÙÔÖïÕÕÕÖÖØñØÇ°ØÐÆØØÙÙ§ÙÛðÛÛÜÜÜÝÝ˳ÝàïÞÁpà¶Aà¹"á"âãäãäåä½ÁäåíååÆ\åÇYåʈåååçÄPèÛÊèêìèëíéÈUéêìéëìéëîêçáêèìêîòëììëíïëîïëîðëñðìÐ[ìêîìîïìöùíîðíîñíòñí÷úîïïîïðîðñîñíïòòïùüïÿÿðìæðìéðñóðòíðùûñÔ2ñÙ0ñòóñòôñóëñõøñûþò òòóòóôòôíòôõòôöóôõóõõóõöóøýóýÿôôõôõöôöëôøúõõöõööõö÷ööööö÷ö÷÷ö÷øöùü÷ã?÷å?÷÷÷÷÷ø÷øø÷øù÷ùî÷ÿÿøéGø÷øøøøøùùøùûøúûùøúùþÿúûýúüÿûÿÿýþÿþðFþÿÿÿõŠÿÿÿ ²Šæ.tRNS$%%&'()\–P—^š•¾ó0<ãgPx¸ëäí³g¯¿rå䕳wŽìÛ·k×CeÞG[‚ýã[#C³[ÃÓƒbkж¬{T}mù®6Ù¿gå®#ûö®éëž¶ôPõý… .+Ë[¤.šÚðôñƺü ЇfΪ¶³2¼:þü™³Ë7]¸~¾i1Põ±)SlåŠ_ÌŒÿãøß^¿ ¼ýéÝúðƒøbúÝãŸÏDUAÅ!*8UDuŠÊ®7++X)”bä’ÍŠQ,cÅxíÊå pÀ¯Ÿü>ûêðu7›-ˆA¨œ#!z%8%z%z!xũЅÃ'[×[6]>CÍý)ŸOŸ¬Î¾BDPD@DAE¨£c^ö*¥ Š˜ðì4qëQ˦Ë8‚ƼóHä…_r.äb”bTNYíö§žiåw´N9nO6#—–«½B7NûLtÂbêѬÀú…°}*è™×žºRêJ™G•it´}AE¸ra˜ŒíXèÇÂbê8?ó4}f}4ì¨_C7d !8ˆ^©¼c¯rì×0æ5,÷f0fHYØ›8Ú>3¤‚a@TþN,ä²»¨*Á뎴¢/Ô±0<3úQ¡Œ”…íh䲫ª¿ 6 ¼F¼z¼:¢wÄ+÷œ™f‚®fD„"TfÑèµpÑe^¾ø 7oÞü¢ïûo<Þ)“¨L'Êlê˜ÖÊ^™—†J*H;ßU„T^˜Ì&¤”03Ì ÕŠù|NÓ4Ÿ:ç>ñTªJ©¢ƒ¼ b¬V+êº&çLJ‰qϪm[Æqdú¾g†³~îA=8¢»Y,€‰g»m¸ÿð1Fº®£m¶]G×ut]Ã8&®¾ö*óÙï=9'êºFDÌ `#SÍJa4øþÖ¾¼û*‹i`^Ï™UǃuÇOG#cÊ|vñ>ËÅ’¦9åéÑSbˆ¬VçÌ#PE¡/™¡8¶9³-JoR¢˜QÌÈÖ›ÌíǬÀ{Wg\>¨pvÈO×¼ùÆ›\»v»÷î1ôƒ©ˆà½ Ú1ÓåL;&ºl䔸ý8q¸î¹ýKË÷R2®\ˆ¤’ytÔ!"„à999áÙñ1ï¾ó.cÕ *8DvLøÑ¨c2”âPU&µ²ØT…¶dž'úm棥ªj.°Ùl8<ðÖ?7v=©ëåêâ׋¹ãüÒs°òœ[zê‰Òv…£ç ï„1.]z‰îÓo{ÌÌäߢéúõëÓÕjÕl6'¨*ªçÞ{bŒ Ð6-9gœsŒiàùñ ]בsþÃÿ[Æô}ߥ”¾Z,–çK)äœÉ9Ó÷=m»,¥R:{Ë9#"¨ê ù¿ÂôODŽ lúÕIEND®B`‚eric-6.0.8/eric/icons/default/preferences-project.png0000644000175000017500000000202312342633755021666 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<@PLTEÿÿÿ,,,000ffflllÃÃÃÆÆÆØØØÚÚÚgÁ"nÌ1o½3p½9‘ÿ>€Ò>“ÿA”ÿCzÁC•ÿFz½F{½H˜ÿJ}½J˜ÿL™ÿMÁM‰ÒO›ÿR„½R…½S†½[bk^½_ek_½e“Ìf¥ÿf«ÿhowh§ÿi¨ÿk™½kš½lqwl›½lªÿm«ÿn™Ìn½n¬ÿo—Ìp­ÿqqqq{†r|†sšÌt}†u~†u›Ìv~†v†w†w€†x€†xÌy°ÿ{·ÿ|žÌ|ŸÌ|¸ÿ Ìºÿ€¢Ì€·ÿ€»ÿ‚¢Ì‚£Ì‚¼ÿƒ·ÿ„¾ÿ…¤Ì…¿ÿ‡½ÿŠ§ÌŽ¨ÌŽ­Ò©ÌÇÿ’Èÿ’Êÿ“¯Ò“Ëÿ”¬Ì•Çÿ•Íÿ–Îÿ—®Ì˜Ïÿ™Ðÿœ°Ìž²ÌžÌÿŸ´ÌŸÇÿŸÑÿ¢µÌ¢Êÿ¢Ëÿ¤Ëÿ¤×ÿ¤Ùÿ¦Ûÿ§Üÿ¨Íÿ¨Øÿ¨Ýÿ©Þÿ«Üÿ«ßÿ¬Ðÿ­Ïÿ­áÿ®Ïÿ°Òÿ°×ÿ°Ùÿ²Òÿ²Öÿ³Óÿ³æÿµÔÿ¶×ÿ¸Úÿ¸äÿ¹åÿº×ÿºÙÿ¼Ùÿ½Úÿ¾ßÿÁàÿÁãÿÁêÿÂÜÿÂßÿÂâÿÃåÿÃèÿÄàÿÆìÿÇáÿÇçÿÈÈÈÈæÿÉæÿÊèÿÊêÿËìÿÍéÿÍëÿÎêÿÏíÿÖÖÖÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííøøøùùùÿÿÿÄÍtRNS!&M_`fj­²ÖÖñògH®'IDATÓe½JQFÏÜ{7»›5 !ؤ|;[ÑÞ7PÄÆÐAl-¬l|-¬,L,TBð/q³?ww-Âî†ø•‡oÎÌ€1B›ï²¢¦Ùû¦ ÆÿšwWV؛ĸ7Ìæh?šºŸ[Ý…û+à`;")VÚÁúÚê©Q´7¢ÉCúUºíeßÉ£8UÑÆu=ÚŸaê¥$Ûã»i¤K|Í| Ç­Nãñ8ÙJl¼[à¯Fg¥fK›QX^"¼¿-î4ëNfã$IP€ žz¡‘<ÌlXamF½þ`œey'•D;JI2dì©(Á¦æ8@þ’5'3X)­Gÿ +Iþt½6°A%¹ý÷¥€6șü>Xlñ’ÑKIEND®B`‚eric-6.0.8/eric/icons/default/irc48.png0000644000175000017500000000765312342633755016670 0ustar piotrpiotr‰PNG  IHDR00Wù‡gAMA¯È7Šé pHYsHHFÉk> vpAg00ÎîŒWbKGDÿÿÿ ½§“ŸIDAThÞí™i¬]Wu€¿=œñŽo´Ÿ§gûyHŒc'!ÆG¡ (Šê@+U¤Vê€*(?‚*­*µ*?h+UAM¡´ Å)$¨8ÄvÏ~öýæ;ßsϰwœëx Žˆ´YÒÒ9÷êj¿õ­i¯½¼"¯È¯¶ˆ—g™ U„A¾f»k1u Ðü°$VâÉ JlA° Å6¤CÚ BXah‰y2.™Is‘ZgÀ5œ¹øK8°Œi†Pâ Žx3!)2!ʪê–]¯P )†Ž£H“Œf·K»Ù%nôb[Ïê4í$ûC"óQú}Vš‹„®åÜü/àµ;aµƒÅMhñ.Šò} ‹Û䘮ß<ÌþñÜ>¶››‡Æ ‡)»Ù0¤Ã¥Î2§kÓ<}é4ǦÏ2;µH2ÓëÚKæ[KþƒNòeNÌœglÀ2½ò2Ú–R¼›²ú#6«[õVWïÙ¾ßØqˆ»7ÜÊxq¾rB`¬,öš…R¬…ž‰™í,ñÄâ1¾1ùÇ'ÏÓ=™ä\ï¹l)þÍè!† k|ïìÏ ðÆYlÇ“É&ç}ìÖáØ¦a~ë¦7òέw2`­ÅXó’þ˜)+QoÏ=É—'¿Ãôô2£½^÷tûëv5ú$ÇçŽ1\€åöÏ´¦ºæÓÝÛÁXÜFI}ž½Þ;¸ÅunÛºOøMÞ¼y?®ôLDlz$6~I›=¡¥`Wu3¯ØÌŠZ¦µ¾£UÁÝ“4ÌëLèarõž†Ì¼„¼id€µû(ëd_p€ÍwŒŽóÑÛßÁæâ0™Í^Ö¨„b)ZåÁ3ßàxcŠÆÙŒ¥GWO'[æø¥G¨úPï½èú Šìz ꯹Å?À‡ÍÅ>tË \šéÚËÚ½‹³xœéÎÞM-†vÍÎHw þ.w¬†G.þ ÷l(–øÎ‡˜ðîaÜò¢<[Ÿ£àB¨¬µýoöl¯ú]n´%Ê"–¢e¦Z³L·/±ÚkàÈaÁÝÔ^=ßìý)ߟûc6̵_Ä·MÀH ‰½…uî×xmeœPöí·øZ³wh„C¶°k`˜²ë#…ègû{ÖO'¦¸ ÑbILL#n°-°-PÄYбc™Ô@ФœøÒüZëÉ¥ßç3¿Â{~‘Œö p ›¼‹MÞã!–Œ“µyfÚ ŒC&*l)Wö „ÚÑ)äó^Î#dÈlFbb¢¬C+­ÓHj´Ó©M±Vàk«$™Íkõ2@’œrÆúý•³gêïá½-›¤æÂ@­[bÀ¹›çšêvø<-pµ¥™´xn­Ådk†’£)¹%×!ÐG ”! – k )ƒè;Ãw ú-8oÙµW¼o@KHEÂú!Ó#ÞkzƒÞ6ÜcœkÞ¨,;BAn#TÏ{_Kð¸*z |-ðtþ.eJbZ)Ä6‡u$8R ¥BKOúH©‘(D?J›aLJjS2“šŒÄX ±1T5…w]/;xÿ–c|êÙ(@Ù®,¡D¿½å†» \Mnt_ý>@"põeH#5Žrq¤–.Jº(¡‘Båi&/w;ƒ±™MIML’ÅÄi$‰EŠ2¥À/;JŒòÉgàSâÒ‚´ùÂýâsä€ë£à=ŸVW@\%q•‡§Bà*-}´rq´F EÚStj’ÆŠ Uƒ^Ûbl†ôcÜR¿ÚÆ+µpüqÖCI‰’0B¼Hgd¦C’¶ÈìÒ"OuU®Rï*ãs§<]ÀÓ!® ñ”ëø˜žÇü3§¾ïsîX‘µ…2i\Bê%ózK³“¶NÒÈ"c{æØxû,…])I7Љ³&ö0ˆ·Þ —Al–‰Ò)ÑMÇн’Ï \y­ñׂh|]À×E|]ÄÓ'„$äôw üÏWªLÝÈÀð8{÷޲÷×ËlÝèR-+<7÷j/¶¬52.ÎÆ<{ªÉ±#—8úßç(o<ÉZ­Ý¡Û^殿ï·ûûÀ¾"|a|ì§վ¡…»+„Ê8:è¼Ë^~ú:÷µ"p øºL KN‘À-²z¡Ä7??ÀÑ#;غ{÷þÚ:Üì0\-íåíåZ#ú©›ÁR~|2á›-pêè±4[=}˜dþ~š{„ðKç[× s«1LGÐÉšBqŸ¿¡Tò}ß÷²ÿiãkï„øºD蔜2¡[aò‡<øé-L-ÝÅ}︼­ÊŽ1°ÆÒîZZ\ÛÝ+Ú‰òg³két-ËæÁ­{*x#[åTspWÜMïFß¼@÷á“ø-ÉäUqàR²hÆ´¯î,Œñ•¹ÒyÔµ]È×Þ5Æý2“?àÁ&hûoà=÷náÎ]¥&78Ê ½^Û]Ëb[°Ô†FÒØÐŽ,­®Åd†ñQIet„ó­Ñ¡¸Ýó4þõ9ü½–tñªqz*†¡¡žœÉ’ä€Wõ7—FB<™ýTûôµÂ×§„ï”)x%ê³¾ðÀ8óæuÜuG…}›Ý:]K'âµA­ kÊåνšLIÎÏÒÈÒéA;‚nd :ð¹Ð*™NûVDå?7ÅÊ?\wH ÜW¬Ùݳq;:䆪£}ˆkö_ t‘À)áÉ2ßüçQž>uQQ4ë3Ì,u¨µ q"ISIÔË nwò4éFÐéA¯ݶ¡T‘¼ç äb]r~*£õÁZ3eau…ٖŨ¡AºkUf?òm½]♫jŽöàL2e*öt§Ö¾MþèÐX•À5¸Âà)§C]ÄwJ¼+S¾ò/;ˆ Øl–N”°P™\Š9¿”0_³4»’D(üªƒqkMC§mèD–¸k8?oÕ¼áU’'ÏÁ¥ù”åFÊ™K~tn‘“3Ë$I l€^gŒ¤þîxø“÷_w"‹-T$œNÎe¾yª¾Ò¢l¼ºnPVªžOúý¶Y"tK{|€yø€iôªª@l|Öº.³5.y|òƒ.wíU> Óó–fÍH°Ö°,E’{ït2ÁC'<3Ýcj5¢Õ3ä[x Ê<Ÿöä2Çï}ádú§kÝä=íÁê²·­|pº9ó'ÅÆGÞòþÛ¼ò ƒÊ4J:ù¨€ËütˆqÊÛAHd!B)=¡$«mð¨ešó‘B©|H3X;#81¯žx¥€î’B*!¬Ñrá`ÝêM@¡õ O!÷×á5rEa6îÖå’Åö"¤®¢¤Æõ:H‰›{F8 \„,€ "@*í*Ö:ð‰ËgœZŠUñüÖd²<ø–a÷lZ¯8?ãc31$B”'‰•[FèàÚ#åÕòŒ ÐâÏÇ÷Ž}dß¡MJÛŽâ„c˜^»È³ÍpbòŽsF0ydˆÒ.ž/p}ð€À˜|.çéd…¥P„Ä)%½È'MÀõ ¶9ÉÂЦWüŽÎ[©`–¿–wwëùÔ׎uãvÒ‹I3^‹Ó•ô<+æKüˆ:GÙ½{Âôn/ ¦©ƒÒ¹ñA~~Ž'ؾ>~_¾—üÝãpjdÈLS.À®u°Ô†V*(-±¦?ˆ „ð ‹õù =:g lv@øzwË!êö¤édŸY‹VšD¶NÌ*-–h²€ah ;? Ñt-io:,³…ß® M÷ ûZ?ÈÓ(,äáÖù{± Jæ©“epp ŒÂWç÷j…¢@É+gîRU’4çHVž:EýÈc¬{kÊÂ᫾”æÏÿ2OÇs•¾°Ôž„íÙöÅÏ6N»¹:aKÃ,~A(žBÓÀ?ý mƒ¥Ü»ÆÂ°oß“{ÿÓ =Lîyc-^ 0ñ2SÇŸhØ¥G"m<ÃÂḙ»Òƒ²¾áöEïL:A¤pö³óYåÀjše¯Ý4«!Ž“úÞ÷òN“Ù|š-{Pt`]Þ¹6Wá«'àÙ•+÷0 ›®rñéÇ£è엾ȷ>‹7¼LÖ¹!ÀK“ÆIØôNXzäD¢FÛÝøŽÊPP+„/€0„JT¨øPò èæ¡OÍÃs+W<'%x~ÆÚ¥Î>ùzçäÿù¯ý Öœ»lüËÐ8Åm†™ÿ<žÈ‘çÖÖ:ãI’nöåº!¢¤êó¼V¼~Ü<Ä m¨õ®„;¬aN¬8áàV4&[ed›Wäù—ÿ~Á$‰2ÙÁ%tEXtdate:create2009-09-13T13:10:08+02:00GáÁ#%tEXtdate:modify2009-09-13T13:10:08+02:006¼yŸtEXtSoftwareAdobe ImageReadyqÉe<IEND®B`‚eric-6.0.8/eric/icons/default/ircUserAway.png0000644000175000017500000000146412342633755020167 0ustar piotrpiotr‰PNG  IHDR(-S pHYs»»:ìãâtIMEÜ 1Ý£–ë°PLTEÿÿÿ€@@@DD3P@0€""" '''ª((i\HƒmX_OBCCCšhb‡q^šƒ¸QdsaV†¿CµOƒ«<Øv!e5uUEIN ì.ETNÓgIEND®B`‚eric-6.0.8/eric/icons/default/select.png0000644000175000017500000000260312342633755017204 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¯¯^‘tIME×  1;gÓ‚fôPLTE...555666777GGGOOORRRLLL<<<111888wwwrrr~~~žžžsssuuunnn}}}šššlllyyy¹¹¹vvvsss‘‘‘™™™¥¥¥¯¯¯sssuuu‚‚‚ŸŸŸ{{{|||zzz€€€„„„‡‡‡ººº½½½ŒŒŒ‡‡‡ººº„„„•••‹‹‹ŠŠŠ“““°°°´´´›››ŸŸŸ•••———ŸŸŸÀÀÀÁÁÁÖÖÖ×××°°°ºººÆÆÆÇÇÇÉÉÉÊÊʯ¯¯¶¶¶¹¹¹ºººÕÕÕÙÙÙÛÛÛäää¼¼¼ÁÁÁ¿¿¿ÄÄÄÅÅÅÏÏÏÔÔÔßßßèè躺ºÀÀÀÁÁÁËËËÌÌÌÔÔÔ +Y +Z,Z4c4d3_5a:i;k"Bs$Ev%Fw&Gx'Hy'Hz/O~0Io1Jp2Kp4Ms5NtCg›GkžKo¤Lp¥Nr§Od†Vn’[p‘bu“iŽÃl}—m m‘Æp‚p‚žp”Éy‹¥{‹¤~¨§€ €¡Ž¢„•¯„œ¿‡”§ˆ«Þ‰•¨Š—¬Œš®²¥Ã“­Ñ•¡³•¡´•¢¶•¢·—¡±›¨»Ÿª¼ ¬¾¥°Á¦®¹§­¶§®¸¨¯º¨²Á¨²Ã¨½Ü©®·©´Äª¸Í«±»¬³½¯ºË¯Çê±¶½±·Á±¸Â²¼Ê¶¿Í·½Å·Àκ¿ÆºÀʽÃ̾¾¾¾Äο¿¿ÀÀÀÀÊÙÁÅËÂÅÊÃÃÃÄÄÄÅÅÅÅÉÏÅÉÐÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËËÏÕÌÌÌÍÍÍÎÎÎÎÎÏÏÏÏÐÐÐÑÑÑÑÕÚÒÙâÓÓÓÔÔÔÔÕÕÕÕÕÖÖÖ×××ÚÚÚÚÚÛÚÜàÛÛÛÛÜÜÝÝÝßßßàààáááâââääåæææçççèèèéééêêêìììíííîîîîîïïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøÿÿÿghdtRNS  %&'<===CCGGGGGHHHQSTTTUWWYYacdzzzzz{}~~~‡ˆ‰¦§§ªª«««÷÷øøùùùùùùúúúúúúúúûûüüüüüüüþþþþþþ^2Â<bKGDû¢j6Ü¥IDATÓc`€}e Àäýý»3аWò¯_ÉÜ r"0Qõà#×oß¾~q³5 Ñ€ˆ ~þþýÇw è§ïß½}$–ˆ~õíׯgwí<öüÍëO¢d!ÊM¿üuuùÖí[VÌ:ðâñ-c¨Ùvž]°zÑÂùs§÷ì¸}Á,ÈÊãq÷Þ´9³nœ:¡³­ùÌ9?^%Ϥëw¶uu¯ÿõîáÒö†ºU—¯'z)2èqæÒÍu“¦l~òôéƒ3á’`a±ÐSç.]¹~ãÆ­Ûwîܹu9T¢\+,ÂÒÞ(~ÝÙÉ*2LàâòŒŒü ·nÅó32*È Ä[À;þìqɨia¡Éãò©¿Prïä,IEND®B`‚eric-6.0.8/eric/icons/default/vcsLogin.png0000644000175000017500000000242312342633755017511 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ*3îtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“wIDAT8Ë}”OLcUÆ¿¶¯--´Úê¨a&³0¢Ž‰“ 3‰:ê¸"î̬X°7!&¸q#KCâÆ gãÂ1fƘÀ%„Á†£c‚%@ÿÿyïõý©ß¹íkbæ%‡Çë½÷w¾óÝs¯g}}ÝŸN§C±X,£ëúÕf³9›H$^ìëë‹…ÃaÍu]8Žƒ`0Ó4íZ­V-•JÛ»‰D¾¯V«¹ÓÓÓæää¤+<ŸüY[[ë!àRÿã}N ·Z-4  oyü~¿ú_‚óÔ…˜•JåK&úœ w¦§§ mee%ªiÚ;½½½ÅãñQYÀAT™}> …B ÊJÔï^bó÷0+ýÀ²¬—XÍ'¾©ðËy“1*呲=¨,dâGJmÛVãÝUÈ7Ï1ÞV`ÂnЛ§¥,É$y‹bù_ÀTz½þ+dÜK,Éä[~?99™yNÒ›(K‘ŒJ—EÝþzUxUyp ù…B!ªÀ„ ÒüèÙÙºá¢L”x~zöxu ‡ µ7†aô*0—™)ÈvQ ³CF•·ÞBï]©”Q©V0qáüµFla„Êæ ÌÌ- ÙmÉ(J†‡‡X*°=|—`î:666pýÝëÁÝ»kjÞññ1ŠÅ"‚유lWƆ°x)-%oÉNßÕ„¿ŽðĹsàáØð°´´„ÃÃC\¾üŠ¥"fff0;;‹©©)TkUe…Ÿ¥©D¥=== .JÅKçóylÝ»‡J¹ŒÉW^Åüü<±°°€l6‹+W®âö;¸uë5Ïê4ºŸj#T”ô²@¥DiAG8Ì„ÓÓ¯c``@ÍY\\Tð¹¹9ìíîáÚ[×°³³ýý,üR²tÏòòòªL0’òƒl†D&“A"ªaÿ§¯áZâ±8Z®Ã1 z :ìÓS /‹ò¡¡!¤R)ävNâÒ@ö—<Ì+ju©VÊÿ…‹=RI«å"°¹¹iòþÜåE´G¥OÒ–§>Ùõ­o¿ÀýÍ_ñó9”Œ2é$7² ³:@dzCÞâ½í@çM vkuuÕ{À£ùOÐm^Ú;cب×û®á EJBó;o;*›z;§Tº†WŠ€}xÌsãåØÇÏž_t¹@qSà°Ý\†c7Û] dc½»Ä ´ÈÛB{إߦ^åÛ…%@ný*©º¥€V×ÚÇ‚« c}û·\™jbmE¼&Õõ)ïö÷ÿ=¦ƒþ‡& >èÜœIEND®B`‚eric-6.0.8/eric/icons/default/updateLocal.png0000644000175000017500000000247312342633755020167 0ustar piotrpiotr‰PNG  IHDRójœ pHYsvv}Õ‚ÌtIMEÞ *1¡¶bšPLTE€a I¶Iÿÿÿ[bs|w€~ˆmv§´[b^fdl|†dlkt[bdlqz[bdlfn“ž[bu~[bU\^fy‚š¦U\[b§´‘œY`[b^fdl«¸[b§´|†[bY`¥²­º^fqz[bmv¸Ækt[b]d^f¶Äfn[b[b¶Ä^fu~dlw€¼Ê]ddldlÃÒbj¿Îkt‚Œ]du~^fÉØ ¬^fÉØqzox^fkt^f^fktqzœ¨dl^f„ŽÔä[bÔäÐàfnbjhpu~^fu~fn“žÇÖ`hqzÌÜy‚jrœ¨Ùês|Ûìy‚–¢^f`hhps|`hkt]dmv]d`h|†~ˆ„Ž¢®W^Y`[bbjqzw€‰”£°­ºY`[b^f`hbjdljrktmvqzs|u~w€y‚z„|†~ˆ€Š‚Œ„ކ‡’‹–˜‘œ“ž” –¢˜¤š¦žª¥²§´©¶«¸­º²À¶Ä¸Æ¼Ê½Ì¿ÎÃÒÅÔÇÖÉØÊÚÌÜÎÞÒâÔäÖæ×èÙêÛìÝîßðáòãôåöæøèúêüíÿíÿíÿíÿîþ îþ îþ îþîþîþîþïÿïÿïÿ ïÿ$ðÿ&ðÿ+ñÿ4ñÿ=òÿD:Ê^6‹tRNS #$&))00357;AIILMORXYZZ\cklmstz{}~‡Œ”›§©«­°±±µ·¸¸º»»¾ÀÁÂÊÍÑÑÓÕ××Ûââæææèëëìîïïððñòóóôôõõ÷÷ùûýýýýþþþþþþþþþb¦Œ–bKGD LòIDATÓc`Æ  ”m@zcg^´» ˆÇÖ/Zsèú»·/î(w–”Î óvœ¿·»’vÍ ‡­º~nÝ“§Ýœ 6l¿péÒåm 'ôÎXuæ €„EËvž5¯ŠJ(TB¡”BG…BY jT¨PBZÙá8gΘvb¦~•ÚH)B ”@+R %:Òh4:Òˆ@ D-6ô‘Meͤf†51Kq °öÀ›Ó}¾Ûô™_—a¡?¤ž ieÂ,tËúÓù&´¨–B4Q="ªGt:YH#51k-· )ÃΔ“(z·ÓÑ!Í?I!%‘DZ!2IH%¸VžåÓ-_ñÅS×±pð€dœL”H§ÂÆŸ|$¦ˆ­ëë;ÖQ«õõKæRIÑå8"™Láz>Õf •È0ÁÃ*uÿ7ûðº£K –—kÍ9a•&ø>³VmWÔju|×à 8T ‚«ÅËöZâÛWÀj€…A†h,-ÿæÖ›Ïð>׸‹&ˆ`A qþ³üò­Ç(.vÌSÛÞ˜³ÁRÔLÛ TÉâCÂMX¿±P_¡NyK Ý©ÕÖßüE¯ÀY*g‚³Á¨à̪”Ç;>;]$²&@äÙ ;AŒ¨™ hì2–1p¾i6çĵ›XÚîÚA¡d38µÈ(%ã&€SÅó«O‰†´‰bâýO!<ÒáÒ¼I:—”î*DUy‰:\Dž‚µKĸ"‡`Jû³ú«½ fã¤(•=æ–)æ-¡i?×É~G«^e:•Ô]²ÒoÜ=ç1T­œ®þ÷J( ºeJ9ðú_ç®øê†G IEND®B`‚eric-6.0.8/eric/icons/default/projectNew.png0000644000175000017500000000250412342633755020045 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ &(‘G|otEXtCommentCreated with The GIMPïd%nñPLTE”¾'''***666888¡+++]]]___EEEEEEwwwYYYzzzXXXYYYZZZ[[[\\\]]]^^^dddœ“œJJJ‚»»»½½½œŸ–£–Žš”¸¸¸ ™ ººº¤–«¥½½½¾¾¾ëëëìì숉«­®°²³¸«°ŠŽ¦¨ž£¬­ • › žªœ´¸ )Ÿ$³$&ž'¼,tÍ,¢/€å/¦0©01yÔ12æ2Ž2¤4‚å5ƒå7„æ7§:º:<ˆæ=’CºCCÃCD“D§G©K‡ÕL§oL¯LÉQ†ÈSµAT‘áVÏVYÓZÐV[¡ÿ\¸A^¢ÿ`–Õ`¤ÿ`×Ya¤ÿc’Íc¦ÿjÂik¢ámÕo¹{pÄirÜYt™Èt¦Õt§Õu{‚y}‚z¶ÿ{‘§{¶ÿ|·ÿ~¥Õ…Œºÿ€´á€·ÿ‚‡Œ‚³Õƒ³ÕƒÝƒ„—§„݃‡¸ÕŠœ§‹š§‹¥ÈŒ§ŒŸ²¨ÈÁáÂᑵ咣²’Âÿ“¯Õ”Åá•¥²•Íÿ––––¦²–Ìÿ—¦²—²Ó™­È™ºå™ÐÿšÖšš×ššÜš›Îÿž±Èž½ã ¹Ø ºØ¡ºÚ¢¸Õ¤¾Ý¥¾Ü¥¾Þ¦¿Þ§Àß§Áߨ¼Õ¨½Ö¨Áà©Òé©ÝÿªÏÿ«Ðÿ¬Ýÿ¬àÿ®ÂܯÄÞ¯Øÿ¯ßÿ²Þÿ³æÿ´ÇÜ´æÿµÅصçÿ¶Úÿ·Öÿ·âÿ¸Ûø¸çÿºËÜ»çÿ¾ÊÚ¾ÏܾÙÿ¿ÊØ¿ÐÜÀÞÿÁËÖÁÍÜÁßÿÃéÿÄåÿÅÏÜÅàÿÇÑÜÈÑÜÈèÿÉÒÞÉçÿÊÓÜËÔÜËìÿÌêÿÍÖÜÎÖÜÎëÿÐÐÐÑÑÑÓÝç×ÛáÚÝáææçæççæèéíííîîîÿÿÿ¼ŠÕ2tRNS+,-Z\^``kkkkkkkmpww}ÀÁËÑÖØÛÜÝââääêìñóøøüüïxÈÎbKGDúÕmJrIDATÓUM/Q†ßsïö¶„©´!â;aAÒ° aaKÂï`ï'H$+¬D¬HÄÊÊÎJ$$6>BmµÚS3sïÔBGyWïyòää䌈‰zÊžWo‚ËÎ3€Ù@ÕqČɟJ­~SKß2~³úPù)Œ­ŸÞYóó ™fÃ9dánúÌ7K¾ÍyÛÈ禃I•íï6™zó-_»æØ¤ ~ÅW£ {zXpƒjJÕ̆}µßÙ^X¶Ò®5Õ°?Ê=ýî^”%‡œëÍT;³ü|AÌ*Ü'š¸[Ímt­DG'O.^>ój«À^ëHŸÏÍ^ŽMö’ ‚ìjéÝÛq^À¦D¯% Hp)‚@•ôm¢¼Ûo*.H»6{üˆÀ/WŽ` ˜‘ãª%ãú ¼ÄH¶†ÃDÎŒË],R¡˜__!¾è*7EƒTPg?IKEçµ’#üÉ`JKîéâþatÈ8³ü,ð ûq’#±vÝ:IEND®B`‚eric-6.0.8/eric/icons/default/colorPicker.png0000644000175000017500000000205012342633754020174 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ******PPQ‰‰‹@W;De?kSvvw¤¤¦kŒS††ˆ¯¯±Z‡Q‘‘“¹¹»˜˜š¿¿Á?n:‰¹hz¨_ŸÃÃŽ½¾––™b“S‹ºi¡¡¢ÆÆÉy§d¢¢¥b“REv@c•Sää奥¨t¥^­­°a–RÖÖÙ©µ§Dm<ÅÅȃ”~‰¹h„²c{±b²²µŽÀjeVââäÛÛÝ´´·ƒ§k³³µM}D±²´±±´êê쯯²¡¨Ÿp©[±±´«Ù‹`”X±±³ññò²²µµµ·ááãêêìv¬^ôôôÊÊÍÎÏÎÕÕØøøøPtHljºº½Z“OK€IAn=Dx@hŠ`¹¹¼ÀÀÃ>m:M…HY‚Ge‹Lf‰Ll¥Ym¦Ztœrt­^w®_}²d¸fºe‚¸dƒ»f„š†µx†¸jŒÀiÄk»oÈn‘Èq’Áq“ÆošÅ{›Ïw±›Ïz È‚¡Í‚¦Ðˆ®Î¥®×¶Þ˜Áã§ÂÂÅÇÇÉÉÉËÉÉÌÍÍÏÍÍÐÎÎÐÏÏÒÐÐÓÑÑÓÑÚÔÒÒÔÒÒÕÒÛÕÓÓÖÔÔÕÔÔ×ÔÜ×ÖÖØÖÖÙ××ÚØØÚØàÛÙÙÛÙÙÜÚÚÜÛäÝÝÝÞÞÞàßßàáéãããäèèééïêíííïóðóôómR`ÇktRNS "(()-.11357:<=>>?@AABDGGNRXehijks}‡‹”•šž¢£¤­¯²´º»½¾ÀËÍÓÔ×ÚÛÜáåêîõõõö÷ùùùúûûûüýþþþþþVÂÜIDATÓc`Äòz,Œ è‚Ü.­}Á Â]=½NhÂüŽí å(Â"†žõMÍu•ÅVÈÂr!ÝIù-µ%®œÈ¶iEÕey5ѦÌ(.±IÌN-(Í5fdDf¶^PÕ–ShÁ,Ìî¶xÆÌ¸Œô]F$a^¿E³çl̲÷6aD ›?Áúds˜^ˆ°xÂÜ…K×E1¢ËÄÌ^²ru¸>#аjÔôk—…*1¢DN[µa^#аYü”5›¦úŠ2¢ »O™µy‚—jH2¨ÇöOžè̃ê >“2ý-ÙÐ#ƒÁÎC›3>ù¤5´t´4ÕT”e%%Ä„ù¸X™ÆB"‘*ÄîIEND®B`‚eric-6.0.8/eric/icons/default/uiPreviewer.png0000644000175000017500000000225512342633755020236 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØÚ´SvtEXtCommentCreated with The GIMPïd%nŽPLTE¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀÂ297A8CCG4H]OX3]w'`bZgŒhrKhˆ0nŽ%rˆ.rˆBs©tt©vE?v«v«x©%~®)~¶€†R‚±!ƒƒƒƒÁ…r…²0‡¦/‡Æˆ¢>‰¹$ŠŠŠŠ”oж1Š·(‹”{‹¬9‹ÆŒ´7ŒÈ¹G‘š€“§e•©s•ªd™«c™±dž³iž·`¡¡¡£ÈS¥Àa¦¢J¦¨¤¦­˜¦ÆP§§¨©ÏT¯ÍW¯ÚG±±°±Ôm²Ë‡´×]µÈ޵â@¶Ý\·²a¸((¸ÝM¹Ûoº’“ººº»æD»ç?¼Z¾æW¿»ª¿êCÀäYÁÁÁÃÚ™ÅܜDZžÈ45ÈÈÈʬfËà¢ÌãžÏ&ÏÏÑÏã¡Ïã¥Ó·Ւ'ÕÕÖØrnØÚÔÙÄÃÚÚÚÚÚÜÛÁ«ÛÇÉÛæÉÜÜÞݵ¶ÞŠßßààààààáààââÎÏââãââäãããããåå¶-æ·+æææççèèèéééêéêêêÕÒêêëêëëëëìëìììììììíìòßíííííîðñîñññòÝÛõèçööööö÷÷÷÷øøøùùùüúúüüüýýýþþþÿÿÿJEtRNS #*+128:>@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜bKGDÙw w8+IDAT•ÁÏJQàß9s5ËD“´YTHí"lDOP‹^©m­{€ÈˆÂû;I Ó¡ÑîÕë=Í¡Mmú>üV*ø-VùS)‚)$96*ª0¹K;6Ú3fœ´lô5èˆrf7ÆÜöhÙ5 JÔáæªV«­ç1#Q€ÖxIß]«[x¡0¼¸œ±·1#ŒŒ=lwD˜FÆ âò”ú¼‚BÆ%]õ~lZC €cFfªí[ýÕô{íg¤˜‘qóù$r.¸?×HŒ™ájXšk6ƒÃÄ oMÙ¾”Þ›€YÁ;ºèéjCßB`R°JÇ:Prö¢‡û9DJ:ÁŸI@ˆˆê%QDL^™‰ùÿBÄ)bœ'.õ »K‰[JˆEIEND®B`‚eric-6.0.8/eric/icons/default/sharedEditCancel.png0000644000175000017500000000134012342633755021104 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<_IDATÁ1h\eàïïÝ]®wœw¦Ák‡TÉT$!898¸DAM×Á­ƒT‡‚ƒSÀ΢¡¦Ì*â"tJÕ¢P4CŃäz^.ïÞûý¾p«U.[ ‹°÷ì&÷oœ"€›+nOº¹‰ 2™Š¬çÚÍ€ÁGr³\¢eÚeÑߎ¢!ÙJ®Ò‡q£ŒgO½àÕe(œ9õ½C-µ£0«O“ÍóÙ±×\ÕV‘ ‚R¡eÕCß)g«›6ч+Å·}¯[ÒR•É$ ;3ô³{:Ò7>Û ´â£§Ý+ÞÕQ•K‘ ˆH¸ã7Í^˜ËòåI—WµÕä¶ ŒL”Rk)½éSgÝl9›,ÍxNE¦414pâ?9R‰Šš†K³”•‹çfŒ‰±‘§N 傪(¨¨ºâPe1)r—Õ=öĉ<Ñ7%R©—äÊ…¬T"ˆþtìØ±=kZ"‚ (•’r?øK‘H¤*ê¦ÕU¤ˆå~Rî%zÆ jêšÚ.jkª J…¡D¹—•»‰ž¶ …Ä”BjJCåFþ(wÃ;­øhÔ½ê}m $¢‚à…¡/ü¨Þ séÃñ7ÉÚ‘Kf¤š.hjh¨›21ò‹/Õ…÷îü"V¿š¬§6Ìk¨©HA!7ö«Ï˶¶7kø`2;ò²5MU© *ŒÜõƒºì(ÌÝ'D°Ú‰›åúXÝó^4'øÝCC5ÉV¸¾Ý‡¼µâvÑ- ¤R©´çÚ½€ðv+.[²hûöì†ûwOøRBôÝô3pIEND®B`‚eric-6.0.8/eric/icons/default/notcovered.png0000644000175000017500000000320712342633755020076 0ustar piotrpiotr‰PNG  IHDROc#" pHYs7\7\ËǤ¹ vpAg\Æ­ÃbKGDÿÿÿÿÿÿ X÷ÜäIDATHÇ­•iPgÇŸÝ•%b@„1ÁD.‰  d D €r eD;”CSD¡KDލPñ¨”JE±* rTA£…ŽŒFheê;¨­¢Ž)­Bâv7»ýÒ™~pÚç÷á7óf“çÿ^àVrq°ÚY¬Æ¹¿­Ý³V½V=8äóRœ$NhÒ,Ó,RøSü)ÔŸ €*³‘&ñ0$ ;T…ªàí+¸>xkðV€ðêð ð ÔÖÙÏy•óª/KØUìëìë<1ë »‡ÝC=‰0T\˜LÒ$iu£¡Í¡Í؆³F™ÌËíÃlγ­­Ñ¾KëÓé´bàtö`ö z³e½wšw±ësS[QA>à„ïðÔðÀ˜AÚ Šv“»ÉoUJÌZÌZZ 9œbNqÄÇ%ææó­Nñ>€];l²m²!è;ý;ùíÀ!yûêJ|&y&¸?3:3й{®7ˆôÙÒL< Ï"ˆÌNö${’ˆ®~±`÷‚Ýω¦m®]ößm&¼½â>z“r¸P)Œ$r[·ù)üÆË]§£XQ,ÃöË«ÒÓgŒWž+‹”E³«{ ·m+ú=曘uˆ:w䣦_»S”!ÊÀ>¬WZ”X” —¿:śǛGYýˆ~àÊË í„Šî»»ë5Òd<#·àuf}Þæ»ò] mã¾Õ¾ÕÆÌ®&ÙEÙE"ïÌ™˜Ø˜X‚hJNÈJÈ"n¶m1n1ÄeoEª"õWMŸNž/Ïo¾}R%T Õ‘Ÿ”dRÐ{If *¢µ³ÚY€æ^]˜. ó]r`Ñ‹E/ôפYxžC8Åîbw½IÜÿx>o> êâ\,],‰×G2űâXbo}d y ù“ò3½Ñ¢œkÓÊãEñ¢\ÍYåê«Oˆ½¿ÞÔ0Ðs‚îW„N£Ó <²ÙÚÝÚP¼©­¨ÚÑ3Ú3Š ]ÔN:'ݨój#î‰{NYN'¡A³]ĵàZä¸fÎ-˜[ؽï¢c©céòüKÇ Ž,ËÛaeaeuvAk‚Ö@po~AyA9ÀГ²±²1(ÒˆWˆW Û÷ì2åp.gnÈ ¼.¼ &,Î>Η.œZ˜¾0}ˆ5—‡*PÅ¢5,6ý‚ẚå™å!ѼZä(r@·I!Œ|ÈSä$r"·S#«‘!Ó—.¤Ö§ÖcªöAÚ -òm%¾÷e|º_½ÚjÒjГd»8r @PP ÕH÷K÷ãCö+ìýìý®"H’Ç_ó÷uÝìÏÉàdÌ9§\ba¾üÌթéµmrxìðn½—`zŒµ2’~¾ê “* ¸OòïåùÊËÎËÀ÷O‰‹ÄÿѦۦͦM'C½?Ä©Dv#»É÷àØ06Œ,ÅôsŠçÄî2ï3ïƒÿ^‹ùnýø¼D ])ø$‚N›Ï|nÛN›Çà2kg6Â9ûOg8XšŸ¼{"zTXtSoftwarexÚ+//×ËÌË.NN,HÕË/J6ØXSÊ\IEND®B`‚eric-6.0.8/eric/icons/default/close.png0000644000175000017500000000234312342633754017032 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs × ×B(›xtIME× 6Ô iªbKGDÿÿÿ ½§“pIDATÁkl]uðßÿœ{oÛÛ÷·n´cMaέK²¸`D]؈bâ#Ä@˜4|m‰A£È'_1&Ä Äã f–eøHÝÂ\@ «­›lmíëvmooï½çžã©‡1Èe,$\:Ê@ø{b¾—çpž|‹âX½VS£VçlÂïçyõ×$àÅMü¼Àã=]]¹¡ƒm>p@ÛÀQ¤¶¼lþwL:efrR…³Uù1à›9ÑÆg‡FGíxôQM C𦮽ñ†^~Y)Iªú!o€/¿›W:9<42bø¡oˆâ ‚ K‘!#C–e`ñÂ_|Ñb–Í•Ùÿ®@ óX;G·vvzð°zý†æáak×&„úµ²´²&Y[U^X”ÜfejJs±(¿±a}v¶µÎî2/}DÃW鸅ã}´ܱWÒ™i¿ës¶}团ž^×ϼ¦•IÖ”çFFÝzdLÓà Ë'Ojoo·qù²Jšnäo1!ÜΡ¶´… å¦œ••Å¡„ wÏú®«3S®ÏN ŸØgבDž(R¼y«õ¬¡^ZÒÑÑ¡•ÐÄD1âƒíbogŽÖ¾e­]©÷ß<©ýÖ}:úµo¹EtÓ6¥û¿óŒÅ*7–½6ö5mW.Š¯ÏªÏ-JP¥¿Â³…g9ÛÇ›Úè¡Ð4ÚóÞ[hóégNºó.°~£ä/GÙ2}^W9QŸOUX®1Gö»"ĺóˆs„˜gŠ-5#Û—üùÛ‡LOŒÈÒÔóYoùŒ­ý5…îT¾›¸HŒ<¡…ž!G5†”,!Ki¤L/°ë¾¯Û<|€E>ÿÄ1¥F‹´H®ƒ\q òH¨EH1lP¯P¯0uhϘ~úœ(ŠT×JfÇÏÝ÷ÜoÿŽ›,µh4i$@Žú$3eÎg¨ÕY_bzž¦ýcîyê9Q«­•œùÕ½ûÛ{Í_: †?s¿}Owm½Y ë4òï—(Ehü‹SI’±:ÇêZÁî¿%ıÚZÉùŸÔW9ggÿªÉ[? nþÔÝŠƒ»Ý˜¥º”9zŒì=V²·•Û’„Ðh¸~ö„ž½£.þæÑô9-y$4‡ªÙ·_UÜúIü¾õó³ú>QB`éžg)r_bô1þÚ »ÐEþc´tÓÜI¾•\3Qž4#©R™aùŸÄ«É&8ö$¿C5¤ã”¹¾“û"rµ ªe’õ:I•ÚÕUÊÿcù+мA;æøÓ¿LY‡Éß¹²‰ÿÞΊiB}Êëó”g(_eãCâe:Sºh|ÈóOðt…2ˆµ3üç*§?NO?Û‹ä )…„¦:Å]=d ^çGùC•%¤yô`çÜ»‰=MlÄ K+L¼Ë[/p.eUdC3Š(ê¨`u¤ðkØË]Œ‚IEND®B`‚eric-6.0.8/eric/icons/default/passwords.png0000644000175000017500000000206512342633755017754 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<àPLTEÿÿÿ555–––šššppp¨¨¨ BBB××ׂ‚‚ÌÌÌÛÛÛ àáà ÎÎÎ 111ÔÕÔ999áááÉÉÉFFFJJJÙÙÙ¡¡¡ÔÔÔpppØØØÒÒÒ{{{ÀÀÀ›››ÊÊÊšššhhhdddÓÓÓ{{{ÆÆÆÎÎÎèèèppp™™™ÓÓÓÏÏÏôôô•••±±±¾¾¾ÇÇǯ¯¯ÎÎά¬¬­­­kkk’’’«««¬¬¬ccc¦¦¦©©©ÀÁÀêêêÃÃÃÂÂÂÎÎÎÄÄÄÆÆÆËËËÐÐÐ×××àààááá„…„£¤£¬¬¬³´³¶¶¶ººº½½½¿¿¿ÃÃÃÅÅÅÈÈÈÉÉÉËËËÎÎÎÏÏÏÐÐÐÑÑÑÒÓÒÓÓÓÔÔÓÔÕÔÕÕÕÖÖÖ×Ø×ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßßààààáàáááâââããããäãäääåååæææçççèèèèéèéééêêêëëëìììííííîíîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷úúúD¼ctRNS ##*-666=?ACCDFHHIILOOfu|ƒ††‘––­µ¸¹¹»ÃÅÈÌÌÎÎØÝÞáâãçêñññòòôôõõõõö÷÷÷÷úûûüþþþþþþÈÈámXIDATÓ]ÑKKBQàµÏ9W½WM襑aHÙÛlÙ°ßýÂE ¢ˆ *|D¡’¦™¨ø¸zÏišº‡›{/" #4-­[1¢ÿÑcä»<ÂÎèþýfÁcgCJc»ëy·`CÛÞ™¥øjnBX­A^<‡ò“š<Î °Þ~ZøòÚÔIªÔeŰÕr¾ >¡NyK Ý©ÕÖßüE¯ÀY*g‚³Á¨à̪”Ç;>;]$²&@äÙ ;AŒ¨™ hì2–1p¾i6çĵ›XÚîÚA¡d38µÈ(%ã&€SÅó«O‰†´‰bâýO!<ÒáÒ¼I:—”î*DUy‰:\Dž‚µKĸ"‡`Jû³ú«½ fã¤(•=æ–)æ-¡i?×É~G«^e:•Ô]²ÒoÜ=ç1T­œ®þ÷J( ºeJ9ðú_ç®øê†G IEND®B`‚eric-6.0.8/eric/icons/default/openQM.png0000644000175000017500000000246712342633755017134 0ustar piotrpiotr‰PNG  IHDRójœ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<÷PLTEÿÿÿdx©Sez¦ÚršÉ ... 111s¥äq¡Þh æh æ[—ãZ–ãj›ÙNŒÜL‹Ûc—ØY–å~¬éAƒÕW”ã@‚Ôƒ¯èZ–åZ–ãáââ[–ã[—ã[’Õ\—ã]˜ã^”×7zÎc™Úfœà6zÍiŸäl¢èéêêêëëìììíííîîîîïïïððððððñññññ_˜ár¦äs¦ä-rÇ-sÈ/tÉLs¢a™àbšàeáfá)d®)g¡*g+iq+m´,qÃ,rÇ-nb/tÉ65u9K•>NAjœBQG\Ha!M_ NQkPxP‚*Q_5Uf1Um$VNbXÔYs9Y‰‹Z‘Õ\p4]q8^hY_€§`—Ûcx5dšÞgžâh—wh™0hŸéi†ªiˆ­i êk çk£ïm¥ñp†³p‘7p’Ÿq Fq°(rŒ¬rޝr¦ís’,t¨ðuªóx­õyY°y•y›oy«ñy¬ñz9{zµ{“®{“±{¡‘{¾*|­í}˜°}®ñ}¯ð}°ó~°ó~¸³'€–¯€®ä€°ñ‚¡«‚±+‚´õƒš³ƒ¤«ƒ©@ƒ¯;ƒ³õ„¸…³ì†©Ð†´î†µðˆ´ˆ¦…‰´é‰¶ò‰È.‹¹ó‹¾7®Êµæ·ê»öË4޹ìŽÑ·é¹ì¸êÄ;‘¸â‘ºî’ºî’¼î’Í9“Í<”¼è”¾ó”Õ•~¼•ºå•Ó/–¾ê–Ì-—½è—¿ì—À옼蘿ê˜Ãø˜Å#˜Ô/š¿ïšÂî›Áð›Âî›Ï6œÇ+·0Âè¡Çø¡Èù¡Éø¢Éú¢Êú£Åì¥Ç,¥Ì"¥Ó(¦Æì¦Ò+¨Èí«Ñù«Ñû­Óüâäææèéçéêèêëêëìêëíëìîïïïðñññòòòòòòóóóóóóôôôôôôõõõõõöööö÷÷÷÷÷øøøùùùúúúûûûüüüýýý_KHtRNS $(;üŸ¨Eq!T9xjAG`+ƒõÑ«H23Õ` ppóm¹âÍ9gÎdÒ—2ÅÀ2s5“Iz¾l:’93 7Àƒ~¦rf&ˆvp&3BÔR 3™„Î"ÐZ‡s¡4_XÙRI-õÚzŠÁè}çagsçx¹ù„CÿbÕÍ>‡b~wåÁÜë¬j?Úû~¸°çOíP ¾ÝɇÑònü®{;›Z3µÂâ^/亜ígwãÕ«ŠüÔW®7­—Ž“[ß]_?èÓt•Ÿ]ëMªîÆ×í{vúqíä ´âc —擤Õ~üëe(7ŸZœ$I?ª|nù„èÏM>ÜrÎYîÇY§KíÆxû™ñÇ,‹V„ñ—*Ï„yþÊðžöwû Ð÷jIEND®B`‚eric-6.0.8/eric/icons/default/warning.png0000644000175000017500000000123612342633755017373 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<APLTEÿÿÿÿ™ÿÌè¢ÿ¢ü±ü¹ù¸ú²ý¹ú¶û·ù´÷²ö¯èyézó¤ó£ð‘ð’û³ ú® éwê|úµ ù² ÷´÷° ænò©ôªåfë‚ð™ ðšû¹@¼GÃIËn6Ëo8ÌV"Î[)ÜrÝuæêê€ö¼ö¾÷º÷ÀùÁ+úÁ3û½8û¾RûÁHü»Jü¾RýØ$ýÛ&þÉþËEþËxþÒjþÓ¥þÔþÜþæ ÿÌgÿÎÿÎKÿÑÿÒeÿÒ€ÿÒÿÔ9ÿÕ@ÿÕQÿÖÿÖRÿÖ¥ÿ×ÿ׫ÿØÿÚ®ÿÜÿàÿâÿãÿãÿäÿåÿæÿæÿçÿèÿéÿêÿìÿíÿïÿñÿòÿóÿôÿ÷eôw%tRNS UW\cko{~‰‹“–—™¦¨çéêêìíñòööö÷øúúþi•1žIDATÓc`À8XQùl*æì(¢ÁŽbÈ|N«Ð@K.$Io u{)ŸÛÂKUÕÕŒ. í੦æn'ãóšúhjùú˜ðAøŒò¶n:ÚþANrL`!£°ðˆè˜˜HcAŸEÙ9:!EW7#-ÅE‰( b”š©§Ÿ•ž’`( ·Ž‹MLNINŠŒ²‘ (*À,?¦·{}|ôŠDÅIEND®B`‚eric-6.0.8/eric/icons/default/coverageProject.png0000644000175000017500000000210112342633754021037 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ"'(Ëî¸tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“¥IDAT8Ë­“]hU†ŸsæÌÌþ6wSÓ"1š ‰­Á‹Rˆš b# Š  ˆÚkñF$Ô ’ 6Þ(*ô"X£Ñ^„†Ä$M¡ ¥ÙFóßÍnvfv~¼È&鯤Fñ…ïf¾3ÏùøÎû 6u/pì^©íë³££ã\[[[Ë¿€ÒÝÝýmWWW+`m nhhèèííýÐ4Í=%MqçáÇYimm=944tv»~mÿ˜eYÁnʶí’j·BP—L&ë;;;ù/joo¯ꀫ[Á˜¦É`Ù ê’÷Ä¡,ƒ>§û³®È˯qäØ <,a`šæ¶ªõ]N/:ÊI% Uû.ðÖ;§‘ÖW}÷¾*jjÄq ïÀå¡A„ˆí –RÒ`)óP}´“Š$b6@ú€ .8îæ¿;N V KhàkPk€l¬0°Ý³¶í3ã}¸QˆE …x4µyØó`%ÙU°,ДBˆŠ;ƒ{û>þOm€_íY¤:á CÜ„‰ó|òÑ%‡_ó$4?ÏlÆct¶ÀµEÓP<ðÆwg1b‡þȽ+–?ÆOp4NÓtf†§›y|?”G᧯N£IbÓ®UM¯pq$MeB§zo˜šŠ“ó“óŽùFnxrÁ95·êÿPòx#7á@ âaxæ¥N"! $L¤³ôüxT\G7t’qƒcVòå¯3LgùàþøÃV?åo¢¬K¸±Ê€zÂk |øåêÛGÓ‹–‡åæ(Í10•åfV€" 7èyûÅ¿5 r˜Z†,°WB\‚. ïÊ2 Yv}$•ea¾ÿýãs.Y_'àúRÚÑR Ö@“ÅÒÖ¦u,8k;þs²ŽOH˜2àɺrŽJÑòé$£×]!±<(ø*!o+ò6°R¥ŠDÃ8èd<Å|A§gpËdܵïŽ0”q«¼î‚ ø–´>VwB2 Tdñf©(ttÓG™_—$oz´|1u±ģŕeX:‰P%K¾‰x4ß ¹&B_ÚÆ–z #Äù ððû ÿ˜&Û xöºÏ™KSóV}ÅÇ?/¡)˜!}Ûexĸ’Àá]g5´Gãà 8øÜ¡ÊÚÃ!CúRÍ:½–Ï91É»)û/ÓÝÊÌrIEND®B`‚eric-6.0.8/eric/icons/default/siteinfo-general.png0000644000175000017500000000075012342633755021161 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYs  šœŒIDAT(Ï“AKA†Ÿo2&Ù4F#ŠŠŠA<ÁÖƒ^=¼ùú—¼÷ZêèA¨{)HK¢=i0Ó°‰dWت“ée7™AÚ8§YxæåùÞ™rÿ_‚0ÃÕp—cÚš»l“s#QÈ1O P(ž³¥‘t8y»°^ýÔÚ_,y‡ZšX@ ¼2³±ôýasµ¢]ø~ á¬4{^™ÚíÁϼ—\oc³½“¼5µµôçþÝZeÌ…?ž}Ë4p’O£ø÷yô¾QðºùÑI“S_ ^O^wöæË^r1þ2èc¨A#É÷.’Û¢Ÿ ªs4˜Y5­^î¿ ‘"e“7ãÆ«Î‘§=Û›¸vïj­‚W]3 èhÈBeu¶½Y.y&÷'—ɟ›§Ýv¯õU{ÉÞàR\0 CˆoÿùPˆÈ³ #‰µ™¹<ù›²$ÖhÂ~m¬š++´ˆh%ÐÇÚG¬}´–¾5ñCPÆyÉ‹w\ýHŠ…ÙÏs_IEND®B`‚eric-6.0.8/eric/icons/default/ircOwner.png0000644000175000017500000000142512342633755017516 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<’PLTEÿÿÿ€@@@333ª€€ DD3P@0‹€ª((­//i\HƒmX_OBž@Jšhb‡q^š>ïÙÂð66ð77ð@@ðJJðNNðVVðϬñ22ñEEñFFñggñ×¾ñØÀò==òVVò[[òkkòѯòÙ¿óIIóNNó[[ó__óffóÝÇô;;ôJJôKKôOOôeeôÜÂôÜÅôßÊôàËõBBõLLõUUöIIöPPö]]öddøFF«,¿3tRNS#-2$ mjbã ‚à3Z›YØi"8ìýÓK¢ ¼N5µÎLpf­À¼ªju$CŽ“r=ø‘Ømý‚¬Xí527ÖEâ2 úxZºˆ²B¹LR:9^®Ž¾iÚ2l`•âʢĄø„¬Â5Ÿ»>»¡ 5.*.%¿©™( ÐZ^–SZ×(Ðw¯H  uÓÂ%,«¨¤,/)À ä¾$>¶[•bIEND®B`‚eric-6.0.8/eric/icons/default/securityMedium32.png0000644000175000017500000000321512342633755021102 0ustar piotrpiotr‰PNG  IHDR szzôsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î< IDATXÃÝ—_lÕÆwfÿû_m§Šã„R•Ô´RK£$j«V- ÒJImZ‘@Uh¥ªH„G¤Šà¾ª´$@«´ PJpb"PLŠŒY»vìÅ®íõÚ;»³3;;sOfÒDVBl‚„Ô+Ý—™{Ïùî9ç~÷;JDø,‡Ág<® €RÊPJ]µ¦@)¥€T4[¢ÏÀ\Y«AYõâÀ¦—^~©'Ÿ_ð<ÏÓAÈòò²wìµW_6ñ5Ù\¥c4tuuuX¨T*âyžø¾/""¾ï‹ëº2üþp¡³³³ h8Ý«9N›º»Ÿxa|bÜ+—ÅZš‘សɩg¾)o=ó-9ñs±­9±,K&'ÏÖöí{üHä•€\²”Rf´¹ñÞ=÷îÞµsç/·lÙ²1™LàÌdòÔƒÄý93!Är|³/~¯›xë”Ê%†††f½úZ÷ž, *"Á‹P)•¬¯¯¿î¡_=ôðöm[ØÑÑÑ’J¥Ú!æìÜßh©Z› .JAÅ…E %Eºý6Ò×ÿšš§â8211^|·÷é§ž~´\.‹Hõ²”Rq`ÛÑ£ííøJGF)…¸³ØSÏQ™~‘´¹Hk4ÕC: ‰XÀ R…b ”jÍÄ?ÿ#‚–Njªϯ1>öo÷¾û~ñ _Djç}Æ.q1NŸó›2zb/²|š¦Œf}4¤!“†Dâ&ü¡· ÑŠ{vÌ’1À4!ËYÂZzŽÒÌ Øæ×øÀÝÍÙ‰³>Xél% ––—‹¾_ûœ”Çi­×¬k‚L ’ 0 0ã  øã‰ x¾âž]³˜$Ä“N€ijœâŽãàVÝrÄúã˜P…åÂ’¬o'“‚T2<±a€Ï!ñèŽDÇ$¨D. ÷Ô¥ÀH´"Zã:«±˜Ïç ±ôFTäD€R‘J„óBÒ@Eˆa^çëÐ"Øår°W2å¥x<˜Ÿ[ȉ*s !W€œ_‹ø0¾"‘‰è[,\{~º²­ŠEkVóélvl°d•´$¯C)V»2@ÅÂI b¦&“Ðq@™¡U‘0¶Þ€SqeròÃwV†ÿrjSSSo ¿Ÿ«&¾ŽJ]‹–p§¨ QPIøÒF—Í×8¨T#\#ZCÍlç#k‹ùü|.—{¨]@tGGÿõvÿ€pn Spv1Bž¼þZ‡¯~¡‚¤£úPáµ×ÏT·áš©©é3ÀèÅ÷ÿJzÀ>ÞsâÈä¹sN%s *–&Ð >H: ¿¹kŠ‡ïžŠÂþÓ5Ð>`¤8[º¥BÁëëûçaÀ^‹ ñ<Ï{{hðݬ§ÖQ«û.~è@jáë¿ýŽ­l¿s+8 h´F  ß`ÉÎ0?¿0áyÞiÀ[5ÑÀÜÉ“oôÚ¶-¥úN”‘@üÐI`ƒv.ªZ‚2èJÀP &Êß¡âTdðÌP0Ù\“$sF†G^èø¨¤nÀiÝ…¸:ìÛ?@ßS6VN¦ù)ùvfgþ³ÍfΚ5aT0ïýéù?ÿea!¯çb?ÁoÜøTÁwÀ¯€oC­FDûà¤n¢öÛXVQNõõÞ»Tñ­V”‡‡GûDZa_,4>™/ÿ¯Ø'Ê»:±™ªwP© ÙìèXv$û{ ø‰U±ˆøÀØÁƒÏî{½÷䢣[±6üš¿h.°¤€4ÞH®î–:ÆF³Å¾ü0ٸ숭B·:®ë¾²ïñîõ õÞ|Ó-uÁúßÑÐü&fuPÔÌûÛY\r;í>ôüc®ëþýãr¿&YIñõmmm{îàþ¼kgS*•Æ4LD¯æaY½'zí'ŸÜÿD.—ÛU¾|j}A¢¸ùöÝ·ïݱãÖÍ Æ'ÆkÇ{ŽO:tx/Ð ,­¶?XScHíÀ`[ô«f"ñ¹j£ê“4§Q;»¨†|À¿Ù|êþ¯ºãÿ€ámš8IEND®B`‚eric-6.0.8/eric/icons/default/linguist4.png0000644000175000017500000000231712342633755017651 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB7ÇMS pHYs  ÒÝ~ütIDAT8Ë­•{L[uÇëþ0Ñ833È1!NÃÜÊ ´‘8‰#t! n@P”%„ˆa`À.åmYy²….›£ímyt8Væ€ÊÃ)C"!㥠2„ðl¿þî-ÉÜXÔ_rrzóûÝÏùöÜsÎÅú ÀÓÄv{öá]/ÏÌýábŠ/¢¸AÄëy/¿ã1À=mýíyšÖÒÞ†ôßÊ›rjªgç–<í'Ž8¤¼"{ÑFbMˆ©çƒWøWâ;ˆ¯">•X 0Xã¸kúÏ©—«;*ïæ·„£ð!Jî¡lBñuTæÌùþñác,–ßÞeß6bkyé¹41#’Z:# Ù_‹Ò»ŽWX²Gs›BQÕ#Äå¾À¿YäM\µ\b±Žð+dCj´C¥DyÄ56NWs­wÇ)-›ñôžØà) VÞª€¼QÈ€4½FËÚ@Ý’‡ pL ­” ò $jÐ1dÁäü=Ôõ]@ŒÁ Q:W„_æáãëþ(mÍDªî*îÚo‚p¾S}§fS±¬Ž€rg¼¯cm XXžÕV ùÝv¿¡Wœá›î‰£H»‚²[9ø¬æ$ ,G¡îögÀå]¨š141² ®çÁ5å5ÜîþôºÔ•vÚK¨üªšyŽÓœD.UŒ5ÛÍb¤Þ †ºM±¨i©–_C~«/òÌ24÷XÎÙ«b,6¸Â#ùMü>;+‘™nÁÑ'H‹°²F±éIØlVÌ.ÌàlSB¯íëï™è–ÈMRd›lí?w¤‘£¬-àÓÚCðI`eÅŠ•µ%¤6! bÂr$ ø “ùT)–­ ø¤þ8S9Q:Îàí¾F£ÆrqðÞäè{[+}ìÿ¬`À,®Î#ùFÀpÉ(´*,ÛæñaíaDRÈŒÞ3Ó?Æ‘íÝ·Ð*V5¨CÀ+¶œ©{"£;]×c»2YÏýso®ƒE$Ç^)Þ˜y@çØÊäøX¹¢ Ï0à,C²uÅ$óˆ¯ó!`7®—<^|,XVÇ…[Š3:û~`@ew’À“ïAæ•BæYz1yT¬XE<%D¤Žnî“€ùœñ%© è—?z!)“`|jS #,uABùYfodjòfNU³·ÓG·¬÷ç 2©±°¸Ä@ÆçaeZ;°˜‹ü¦d¨¿KÃG¦ÃˆÖ¹mÞœîx'Ï Iê,l¼ŠXÒÒô¼ €(…˜>¯çMH(þîm‹ô<©ãÀ#…ïz¸î'%"ªØ'RÒ>â=éª0‹´Ü´§‚²Ãéâø’ƒˆª·q®Y‚OoùCJ>®”|r,’s£b#¯ü çGß-~Ž«¥ dës—™½@àË"ÊmìíÁÖH-§’À’ˆBï')عý¥å»7LPÄ&Š;È‹H&>€x¶HÇ}^@9üû ñø—gâ o=Åú×_l‹ŽFÍÐi°IEND®B`‚eric-6.0.8/eric/icons/default/addBookmark.png0000644000175000017500000000231712342633754020144 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsbbË<tEXtSoftwarewww.inkscape.org›î<LIDAT8Ë”[l”EÇg¾ïÛ{wÛíè…‚b j"AµFK@#‘`bh'£"ˆFLˆ¾hÔ >Q^¼¼F«1  ) `­-»Û+í¶Ý{¿ýv|بË$“IΜùå?ÿ9sDkÍŒ±Ží wõªÒSìÇÃNe¨"V¤V»µ;6ë*Pø–>Ò-Ú;GÛe½+üÀ‰‘©„ùp¬wü¾¦u¥[k·Â €G/åøÅã=”³V·éáyÁÑvñ‰á¿Xº«a͹/×Ô³±q#±~¬?Àk¿½DEíŽõüÌ™®3}@½ºÞóÖ´6|žŠsYF‰TF虺ÄP¢ózµd'cúuU\µ®EXì6çQûé«ÛZÒÆ‘“o  Í©Ž“,ôx`8›ŠyW».22ÑC,—E»4(¶ßÖŠh»xÅ,¹Pv×[¾ò{ þð,‰kôÞÿ·ÎüPpB ™7hEŒÓßðˆoáÓeÞÊûÁÀr‘ÍÌë›2Á â1£ír7b¾k›[L_]ÈUÖŒlÂô”cˆÝ:G¹ßÃ`ÓþƒBÄ þ8œÛSTÿħðOœE ^SÑ’ú¶•H+†Q@t œ8ؽ À‚ÍŽªF^ï"½$.ï •ž°&ãP°a§®®Pñ„u,ŸŠ!Ä‘ÜiÈu@¾& 0 z˜]ÕK©÷À+ã0˜½îËÀÙL@“¯”çGãgåо*Ϻ‰S VlYZ´ ±»5­tÆS„¡ü-}'ø39 Y°FAòa( ‡øúªÉ æW‹Öš÷—6ÞSW8S¹ü™ª`M)8W@ÛÓ@U\´v>‹r8¥ÛŽãÇE¹*¡Í»Š§ºÏg{£ÉM›vOþz½ÜNæß°¤Öü)¼ìqÓî±7ˆ«8P1¦‚Ř ’›ÐÄ:éî¾ô‹­¯Nº¥WœÿÊõfUuÍû•+—cšßTD ¾"HT)ù|Cæ¯ËC?örrÏõ7ƒ£í"bò+W(w0 Zæ¨Ô™˜|¤Çè?w2¶tK*2ë£üçTH ŸBÆÁÈ#z.ḛ̀)äúPØ·ôœÿ‚Ë”B¹'À°gïÌ©”kÀ;/11üI0d–Rg ”¡¥§¯QÜWîq@ûç—ƒ Ü`£‹TTH÷M‘›Èc˜à©t¨3p•¥Xˆ¶¢íbD6kçvàp!7Lf(DnÌ!K眱„>Oz¿xìš²Ñ©çªÆ*ëÜ%9|‹MÐ%6ãiñD 5'8kT>Nô÷#ñBgeA´eJˆ¶T , (à3ë/š$ IEND®B`‚eric-6.0.8/eric/icons/default/poslookbehind.png0000644000175000017500000000030012342633755020555 0ustar piotrpiotr‰PNG  IHDR©þã#*PLTE žÿÿÿ—EÞitRNS@æØfDIDAT×c` ‚€„©ì¦((p„L+eï œ½{÷ƒ ¬ àE ¦ìÝ»H¢R¦4”)!(7lØ\$Ûp0*¯´c2IEND®B`‚eric-6.0.8/eric/icons/default/shell.png0000644000175000017500000000246412342633755017041 0ustar piotrpiotr‰PNG  IHDRÄ´l;ûIDAT8˵•Éo]W‡¿sÏ}÷¾ÉïÙÏÏñÇn§¥B8”šT˜  V¨ ±@Í– ,`Ó bA¶HìAH´€Ä‰(¥ˆUUµC;Á™OÏožîpîXT•lÒßðé§oóÎ9þø?þýÞ·g+þ|Þ“Õt Y NƒÕ“iLf0Æb­A« £ ZkT¦¸óðМœôÞûËÛÛïìïýàö#âJA~­”“˾gk‰?Ây ÖZ¬µ¸Ìà2‡3kVitf°Æ YÎÕ2!ì$B´GÅKõüóµPJËHtÅ.®r+ŒÐXía´Àhc<”¤™Å'O½<Ç—>ÏÛ×wÏýö7ï=¼ñˆ8S&:Ž ™<Î1·M±~Ì-ï]nê´:0 F=÷ {ºRLU¦øÉW~Ê”_ýOc­ŒsV;MZêö÷Ý7 ’†‘€¡ƒ…N&/Ρ³ŒDŒV¡ÿ[ìéÌà ‡ï[ ?™E¦UÈ$žBeçS’‚“äSI2ŠÈÒ±(äbï§ßÿ†÷Öµ×Ĥ°„%A,‡l©7ù]ò3¥&qA¡ TÚpn–s§iHEZ ™ ÎÐùÛë¤{Ú³§ož}÷úûÅÝÍ?ÇŸûê×͇¡(ÈdÄÃ`“áĈ(SÄ}CÔÛ€xâ˜OžšäÔÜ<‹+ Qdõ¹K矚øÇ[wý÷÷O~¹4]ÞÙkº¾Ñ!$Nú¢Ë8ÓD}GÔ‚èÒdCÐŽúÕ|…\YS<‘ÂRe:\4?ÿ…Ãñý;OÔz Ðõmæ@8œ„Ø8†}ǨãD-PCˆT Ôõ"ºGGïpzv’z­B­:‘{î¹µÕ¿îœlTó® üÝW*EPÀ¤‚£}A¿)È"‡Ž!CÜ…e;Á¥Ê ßzå›Håc ÃQ;­!ÛMªƒ¬?óÄ VÎè'ëá¶o´ÅYGC{ÏE‚N>X»š†<_Y॥‹TƒIð$¢gf¡FÚ;á Ýtû'sûà 'G]׌gÖΖ^ðµ62ð}o2¬²è¯¢Š“s¤Vó)“°^žãâÜ*©óI©Í! C†ÆC”í1ÓI:÷N†½á±/EÙÏT–Ÿž(É ËŸà;µï¡ŒÆX0Ú7»,n¾ÉlP†ò$ƒA™y¸’ *¨"rQ=wöL½sS‹W7wÙÚºÕøøãÖµíí‡O•ŠÁ¼ÖgX'°Ö:5¶Þ¥0­äÏ’›µCÂb•v£ÅQ»ÍƒÎî8!_ð©Mƒµ¥ÙµîÃí—WË­kéÇV^õ{ýèW>n9„5Ϭˆ³HËã°³6]çë÷o¬x…ir& Ÿ/c}CÁ({–²Õ¢}|6Ûýä°9Š_ùÆñëºù`B¥:4Z; <8áb/˜¿õbY¾8!;§&§¦BzÅ/UòÒ䡘s½ù×Ý£ÑýýÎîÖƒÁA£Ñ@<΃¼tN~ÚYûòÓ§ÅÆÆgVŸ\Zž¯Ëò,ió6öéνVëï¤?÷üÜkOöËw¯^½jýǹ™°PÜÑ™úQclÞ¸~£ý¬¿=^Áq2êµæM–ÞMRþ)ü`³\™<¼|ù²oñ‡,ÌÔËSôWœsõX‹4¶®¬wØÌÂ{íõõu{åÊ•.þ(üQ(зäzIEND®B`‚eric-6.0.8/eric/icons/default/grid.png0000644000175000017500000000022212342633755016645 0ustar piotrpiotr‰PNG  IHDRþzþxsRGB®Îé pHYs  šœPLTE¥g¹ÏtRNS@æØfIDAT×c`‚úÿ>>AAAD GGGIIIK( N( RD9RRRTTTUUUX(YVT]]]_<"`-`?%dH0fbagREic`l4ooopVFtG!w8xDxxx{]C|A |ePƒƒƒ………‰‰‰ŠŠŠŽŽŽ`4“““šb9šc:¤rK©yU±™‚¸¸¸ÀÀÀg¹FtRNS #'.3CYf‚„•›ª¬®µµ¸¹ÀÁÇÍÍÍÏÐÒ×Üßéêðòõõ÷÷øùùùúûûüüýýýþþþþþþþþaÚ´”+IDATµÁÏR‚@à» 躘„Šb9Ú4Õ%/šéÐtê‘}„êÒTdS˜‚¤K.ÿ7¹õõ}ð0T°Ù§2Öé(©„ •æØiækŵ< Ȱº&Š‘Ñê0™”™ÀÚ g]©!¾½˜«‡çsª‹0€9¸9cÈßãa Fìèä]l€a³gRdýšó¤+9³ŽõëÚ2IÀm7>^HÇ6=áV÷Ò}Y´ÈZzy3±Õ‡7~:„Ò™5Ì=Sêô{cò5£”Ða&MT¬2w+ÝÚÆê•!.q½ìy,\ïÕßl ¹_®Úé£"áÔ âˆ`)âe ¢å¶ˆp‹p2½[ûìè³`2½ÿ P™ÑHy´… e†öÍ£ *~ÁðW~2àƒ9Û…ŽIEND®B`‚eric-6.0.8/eric/icons/default/listBookmarks.png0000644000175000017500000000237212342633755020554 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÛ6êz!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“MIDAT­Ákh•uÀñï﹜۰é,wapo…k:ÃÕ‹ÄfO £ü-܃Á]$â´Y‘†UåõË?MYÝ3¨ü¥ù©3o¾Î]ÜA"NX¬è¶Xã«bÚP ˆaøD&/ÁË÷¼›<½ªŠ;nJÄ`.ðb.°"õGêž«ˆÖu î5Àíƒ;„¶&8ï{WE‚G´ÊïÉ]ÚúåÔ—p¸IqZëC;Ú²ÀŠ4”*æbÇîÇ Ua ˆw´Ê/ Ú±ÑÁf\O(e.àfQ*ëhgà„òþøV9CäJœ_¢+ZÇMéÀ4¢sàgÀOƒö” *Ç " 0Ê ÔŒ¶§¢” ¼™î/H ^8e%3ö¾p®·UH"Nh˜ ¨=´^%GÄçMhec= …[f~º—ùõò%…Òš’¯q}§Àó5¾Ö”|MÈ./ZŒU.fÄ@R`zÜ ¹Á¶lREÅkí<Ùåß4oíîãÀÙ,±HpºÅX†]ŽLƒé2ZÒ¡‚b;aÞÞ3ˆãk”ÃA° (ú-ÃYϵ«±0˲` · ½iÞt‰•m1Ö?=¥ÃXû}šµûÓ`pÒb¬*Œ  ¸hß&×#ä%Z݃œ ·±éhž]¿:DlÁ6…ëJ¾¦àj²>X[-ƪTÎ…þrœŸ|oždÒñG2úàòÚçÞÉ=¶¬2d'•”‡ –p]ÑÓ¤…‡b¤È!”·Ýb”¢kv^’ž£ƒIõ[2gÆG²¡mËV_€ÃÐÝžôÜ]“-jêÇ›ÄB&(.ú\ëóHyÆ!ö³|Üè 3 ~oE´=•ÅØ¸3sˆa Dƒê9!½¿$RÝ4¿2®3ñt.;Ò=4RØÌÎW¶“¹–Ü?V—ëbäÒí;IEND®B`‚eric-6.0.8/eric/icons/default/reload.png0000644000175000017500000000241312342633755017172 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ˆIDAT8˵•klUÇï÷£ÓéîvwûŒmÁ] ‹Ûª‰DÒ@ZºÝn»¥´Û÷+mÑRé+…I4 …ÚH•@¨´h-%* j⇆ýƇÆ#(4Ęîß»k¦|Äøá—Lîœó›3çÌÜKÿƒGߨ# i$;h½¾-}ÎÓëYÈéÍ eueÝr´:¾¡Uô0)&+ÌËÿ(ÿÑb®ŽxcbÉy9åGÊÑýa7v±{¿Þ‹ÏÐ1Þ‚Á5Æ]º™ì#^ÇxŒV‘éõƒëç–ˆI€Èb5ÿqj[J¨ù½fìùrÏ_~ȳ»žñåÜw|½¾qh#¬-,K•ü%O¿:Ñ}±{}3}è™îY²Þ;Ó‹ú“õ(-EÏÅXÍÅb¥J(qÖÚC-ã-hlÐv¶ ÞÜ€Œö (B±gÙýÙ¨«EëùÖ(çþ$®!6*&åDÓ7«wóä#x<!0@rS2¨—‚/ä lâBR¡ _Ó…Ò¬`ÝÈ:ßgñŒ3Œ± Ìz#*6ëåWR›RàñÝÇQç_Ä>áNܹ"s€ðñMDÒâVÑËßãÚ)èе'ÖÂ7ÁrN3Nø˜8&*Ž ªŸº;\È{#/‚k› ´Bö wx?oY4`/ñÈ>þ†ÐÇ*¡H;ž†¼I–wšq4±µzTS¦Ìeöd"wWn„p?¥M<¤Rþµ¤ŠPÄÍ l_Ùu5 ¹Ÿä"ç\–¿µÖV(•bT¬ø¥ß].¬Ø¾î—Ü`~Xbý­|@,$×Xâ«XÏ«ˆAR…¾ŒB(å 8uò™H, ¦²WüM)S —ëЪ5¹D Qßbñ¢‡ W"‰¶r•·Ö«ÿ¥¿ðcxú¤Œ€41ºbZ$ð~:ñ(1-"+- šChäL)À©²Oãƒ]$f½ü\õ `{CDJ^%Ð%hâ<õß’j ‰K(æ¦ô×¥|ù Íí§ËXŽÓìS ½Aäî‹Å2ngL©Òɤ{X Ô!)ƒ&›²|›õï“å‘"òv+%ÂõÄã¼ãˆ¾ËVÕ!1Ÿåä&tËåv!*f}6Y;æµt¤, £Vp"q§øv}ÁÖ¤-$vX},á¦ëdüµ´c–)s0nXé²ë[,Íê3K¶Mâ'UfP ‰ûÙdËpŽÆ€%bå)ÖœI„çl2²?HŒà9›ÄÖ’n±{³éÇ,“)ï˜ûm­úÛlË~è~ÌsÓ©ÛM؆5¤5á~׎5ãIxòBÜ—íXvÕÁ}9«ÙÚSãI·Wr|»¬ßv™øÈ¾òP1ë¡ÊÓKöf}Á}ÈŽ¬±¬™J‚ëJ-¶IDATÓc`aMu~$ mfjë.Šà3Ù˜[:k!8]+êšj |‰•õ­mIÌpíªÆæ $C%ÊjJ8ìË«­Y‘í5¶01@â2 —Z¥ˆ±A¹L2:ñY ùEº²ì`U¨œÜ‚¼ìL5ŸÇÁ3.9-#=#56<”( èèà#Ô³ ñóöõ÷õrsÒÂ-"§¤¬¢ %ÈäHS$ØãBïQIEND®B`‚eric-6.0.8/eric/icons/default/poslookahead.png0000644000175000017500000000030112342633755020367 0ustar piotrpiotr‰PNG  IHDR©þã#*PLTE žÿÿÿ—EÞitRNS@æØfEIDAT×c` 0 ‚à `2I2ÏÞ½{‡Q9|âÝ‹¦àEAYA æÝ»‘D×"˜{¡ÌFAA  `s!V ÙFÖ0-a{}+lIEND®B`‚eric-6.0.8/eric/icons/default/vcsLock.png0000644000175000017500000000231512342633755017331 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØëÃêïtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“1IDAT8ËUKHkWÝç~ãM¢&QÉì@œ½J+öMĉ“ -­P¤"-ÅNwZœ«H¥4tV°¨Pê¨UZ)O‚X¬Å_4Æ|ÌçÞ·Ö¹¹ÁÒIéæmïÍ9箽öÚ{Ÿ§¤m{{{F¿“L&ŸU«ÕwëõúLooïÛ‰D"麮åû¾´Z-±m[›¥»»»ß°—ëêêú±T*ý}uuUŸ˜˜ð‰§øgww7€·zzz¾€‚ƒnR©T4˜išÂß4Ã0ô;çôˆ<Þß߇@_#àïSSS5k}}ݳ,ëƒx<þeww÷s~€M ¨#+¥AÇÑ ÈD¯G Œu™Î7wÍWØÎYøé¼΃4¦òCÖ \ßßß—••9::ê‘……}8ïk`€} mÞ`Z"ŸdÌwƒ…”ËeÙÞÞ–¥¥%AÊý%“ÉÈÍÍ ¥”|>/‹‹‹2<<ü‚¤œÁA©¢uR§4Ò÷ââBÖÖÖäööVfffdzzZ ²¹¹)¹\N666dvv6©–†øÞõõµ<'Ûf³ÙÑskkKNOOe||\æææ´<\'óùùy9>>–ÃÃC988èÑEÆÇE¤ZC»h6tˆÀ B ù<99G&''u7p­G£TÐWjµš\^^êN³À. ŒÝ@¶ÙlV<ÏÓЊÅ"[Jë>44¤×È”"2±XLg@pÍQHË¥–dÁ'e¡v‘˜ Ì‚E, :+‚”ÝB"$35cHq‹‡i1*uå“ 'Áøä‚ñ £vŒ$á7­ö¨ÕÕÕW`šÁâÓåf__Ÿ ꪓQú^ZU%准¢M¢ [õö›Òl &à™Î$¥ïY¶e~K¸É¨t²!S(NkÝRÞ+I¥ÿÊå¹Ü€Ï]ÅJ‰Ý"sE¼n‘d ÀƒJ#šù|ï眼ÒtÀ4ôhl|Œ¸`þµ©8§ÐË,‹kûsp_ €i(ql%®%úiÛlÓðN±PÅ3) »‚FYHV^[™ÍÌ*|á›A_ƒÐZ z„õƒÞç—?d¯2u‚±XèGÝŸti߃Jü—Àß¾WàÔ¤}ûé= s¤Wà÷øñ‚E$ó]@f@ÍûÑ KtÕyÇðƒ%%›a&1^^^.웳³³ÏÎÏÏF;d̨ Àa aÉ$tCùZ¥ãZÿ0ï™YWkgg§166v À—èÏP´˜fQÌ8ÖTÆýE<û-WZÕG/ói˜H›ÅëBmº qR£0O¬hºÐÏllŽÛOmïØ_¿~ÜVð‰ JtÐ#æ† :ßXòMýCŽèÑ+#ü<9oÈÿ0¥þí† :­F{ >ãNr!8´cIEND®B`‚eric-6.0.8/eric/icons/default/chatUser5.png0000644000175000017500000000203312342633754017564 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs¯¯^‘tIMEÚ!¼AÞæ PLTE#Dm=++?00OOQQYYyy(ŽŽ/YYOO==ÎÎmËËdÇÇWll$vv'cc ll$WW0YYYY‡‡-]]`` jj#‚‚+ŽŽ/ÊÊa©©8ÒÒxËËd^^ÔÔ+~~)¬¬9/ÂÂHÓÓ~ÖÖ„XX||)~~)::ÍÍhÚÚ‘¢¢6––1££6‡‡-ÓÓ|ºº>ÀÀC‹‹.QQ@@{{(ÐÐqii#ÎÎl{{(‹‹.×׈ÂÂIFFÓÓ|ÊÊ`ÐÐqÓÓ~ÇÇX{{(ÓÓ~ÝÝš½½?ÆÆUÖÖ„xx(ÙÙŽll$::==??AACCFFHHKKLLNNUUXX[[]]^^aa cc dd!ff!gg"ii#jj#ll$mm$pp%qq&ss&vv'||)*+‚‚+ƒƒ,……,‡‡-ˆˆ-ŠŠ.‹‹.ŽŽ/0‘‘0””1––1——2™™2šš3œœ3ŸŸ5  5¢¢6¥¥7©©8««8¬¬9®®9²²;··=¸¸=ºº>¿¿@ÀÀCÁÁDÃÃKÃÃLÃÃNÅÅRÆÆUÇÇWÈÈYÈÈ[ÊÊ`ËËbÌÌgÍÍhÍÍjÎÎlÏÏoÏÏpÐÐqÐÐsÑÑtÒÒxÓÓ~ÔÔÕÕ‚ÖÖ„ÖÖ…ØØŠÙÙŒÚÚÛÛ“áá¦ää±ÿÿÿd¯U{QtRNS ##%&')*+28<@@BMMQUY]mnoqrrtuz|„„ˆŠžŸ¬²³ÁÇÈÙÚÚÚÛÞàäääóôôöùüüýýþ<ïÎbKGD®¹k“§*IDATÓc`€n]K -.4 ìUÔÝo/ˆ*Êf’Ó¹hÍT+aé, â™K”H¡«–Dä6÷ôµæ)£ËMO.¬®.(‘AæpnŠŠOOÍtdGµSÁkzmi‡§,º õæ.[:Í]TÞ;µ¼2%@ U”Ç%¾rÚ’¹Ù"(Â&%%½³V¯“eŽ,ÊëžQß3cɪ ~âHšUÙµ]SfÏ[ÙhŒ$lYÑÚ;irocœ#\”Ï'"¹ ®­»«¥,&M.¬Ô›]\ÝP_‘§Öo ŒLÈÎ/*̉Ê1€ k,KŠŠOÉH‰ ž¨pXÑœ•X3Ï–.Ì"iææ¿|áüž®¦¬2sŠ)êj+Šr2€$WNOäIEND®B`‚eric-6.0.8/eric/icons/default/vcsCommit.png0000644000175000017500000000244412342633755017674 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEع’štEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ˆIDAT8Ë•UKL\Uþîkî÷0Ãmi7¥’Zm…À†M%F&š¸2®]7ÆÄ• ÅÄ5šXõcH,‚!’ Miik°J¡V*òšažw÷Îø‡ÞÉW=ÉÏ™{Ï9ßÿýßÿ‹†ÇcqqQÏf³¡x<~ÌuÝ—Æë©Tê¹X,·mÛlµZð}–e¡^¯{år¹txxxKÖ.‡Ãá«¥Ri{oo¯111Ñ"žÆ?óóóŽ\H&“—$Þv»ÝFµZU`†a€Ïº®«ß Ù§Ö„H½X,~!‰>•„«“““5szz:bšæ«ÑhôD"qŽdQªÌš¦@B¡•JÔû 1å½-•¾Ùl6Ǥš÷eù²)¯I9/KœãF–€ò $î0õ“@.—‹(`K‹ø‘ýý}tƒ“™zòuà Õ›Z­UÀr¸ ™,±‹"°8‘HDi æ¦×Â/·K˜].`r,ñ§4ê.HL@ÙÜš–Ìm»ÍŒd200 €YG¡Pè°¼ÿW 7K:ëkè‰kˆ[yJ œÓ~Ì@ÃÇ„™M-¹À™ÙE÷Ž®fìì`úÛ?‘Ig0!›IáÊì.JOq‡È¤È “o(gjIpVBG¸n _ÏçàˆE-ü³W©t8Ñ ~¸¾FhÅÄËʳº° ¨Åˆ^&(ЂG upókmô÷&°Ÿs±»_U³c›xt`ã§ž¯±/V qH c3AÓé´jÚo›Ì-—êÉ¢\mÀ4ôŽL­VÑh ¿?ªàx¶§Nꆦ9)7$,3Ô—#“ÉÈæ(äþck»€™Ÿ¥ã~ 1l6}tߣŸåêaaƒ¥µ”GuÑÄ"cJÁÑ4:²£X\-ã×ͶÈauÀÚ­vgnñš 0åÛÎøñF#i½wÜÍŠž¶xwˆºÒÇ4;%¸³îâ£Ï×`Za)ß„¡SCãH Á&`½á¡\©á°è¢êÖ±½×4mÇ)óJ,QÖãÂ2Cæ}}}èííÅg3pkmËÈç ’ÀÂØ…ÓGW[’X"'5¾·¾¥Øûr;-ËÔÒ©øóÆÒÒR]¾ŸwäCtW˜JWOJhlܳgOââx?Ɔ5\KbåöNA2î ¶`‡øÕÓ°µ±‚G½»¶^ù¤X³?L¦z¾TÝš››kŽŒŒ¬‹_¯äóùiš/îȦ#ÑtBÓ"v½) ³×vpF€S I Z÷ìÆ­ÍgOÕ'†W¾ûàÞþýovÌ !SSSl7¯ÛÂãøÿ|{Užw‰¨ô¢ÖDÕòài±ê•kÚakãÝŽeL<ÉÐL¥i£áÃ5š¨‹õ<±›c‡¤‘>Z][Ÿ¸'slå«ï—Ïëÿˆ¾òQ’faðDÿꃇwãâ_I²…–ö›IEND®B`‚eric-6.0.8/eric/icons/default/firefox.png0000644000175000017500000001250012342633754017363 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœtIMEÛ («+å˜bKGDÿÿÿ ½§“ÀIDAThÞµšy$W}ç?ïåYU]ÕçL÷LÏÑs#i¤’Ñè@屯 i ØX++°Ìáõ.6ج¯ C y ¯-aŒ0XÄ‹Á t¢Ë#É!Í¡95ÝÓÇtWב•Ç{ï·d4Z!XoFü"3»*«¿ß÷;Þ÷÷^*~†cà¼ß£óÄÇÊ›­PƒƒqÃüF8TÝV+?Åñ¶0 Va)åFa«±müx¼føÉ^î]nGŽÝõƒöÌç¯OÊùÛoÜÊžÛý§Æ¢ø8ÎÿàëãÈ»º:9zÙÈÔÊó¶n[Ãú©•¬šdr¸J#öƒ¾GCË—zK‡öÎýËþ~òÞ"Ë¿6óµßú!€¾êS¸ïüöÿÑY¿IöÔg¨œó¾«£8º¥160µòÂíÕ‹®<›ó¶­£ù²9Òª¢A±é?ïJ“Ô‰êXá_OvùÊ={dÿÝ{—³Vþ@5Ôï:ü¥w_õ–Ï0sç»~vÙí—Ýxéç® þ÷¼@âŒwŽ{Aø™J-ºvtj#ë^}¡¼úŠ­jr¼Ž¯„ÉP1æÃ)§þ£$b+M«xìèvî ðÓy ýÜk*JéMÑ wï ¶¾ƒbßßl»ñÆ >^­×FF¦^)ãÛ6qÑë·ªÑU&<Æ«£žÂÓ - (J@8)Í d¢ÈD8ØÌxô±ýL%åâM±úö÷»|ñîw?÷lüžÞ¥ÿ£¨Üú/ûšw.C7ìþ‘ôé7½O_X²²öDɯ%ø-oÿ”Öüm©‘¡‰³d ±J­Y?ª°Bk9!w /òIÌ ¹¹+-!³Bæúf…Ô:2+ W}ÖŸ9ÅSáfõßvÎȯsrïGG¯¼â*û­ÏîýÚ›Ïþ$ð²à_B ró£ôþòU]·¸É̵®”7õ¶/#rsàÁÀÐ*qEy <¥i/õ0 s„wÞÂЇ^Gåc¿Lž´É­#¡pBá ¡°Bæ=çèYK§°L·3ÚÝœ¡£Ìž¡~á÷çÔªê!¹û#­µ»ÞðÆWܹ»ñîǯ_óÇÿËŽÀá[ÏgùîË_ž€Yê^_L/ŽØc ›?õƳŸvÖ¾ÕBPWâ×ÈŒ£°Ž…%ÃÖÿ–«>u-çüÓŸb–f™ù÷D9^j}Oô,¦–T„fR°ÜÉh-§¬[Q¡;¼k>ªÖô³|á}'¨½÷-|ãÐè»öåßZúÖ%¯šúÝlj6¬z^ïô›æï¬­ØfïwíbwKq²­·š“cí^Áêõ õkgü» .ï04 ¹êûÁögvI‡xPóµko§z湈s(‚Bú lr=¹^ÁÞÙ.…f{4—rÚ‹s{ò‰_«’dw߀˧f¸à,'Ï„gzòøžµÅ1û†¿~â­ß†o;ù²I<ûÖÁÉí#y·Ø’fo}…áM\¦ÈŠ ªxÕ6±<÷ø!òÂ14l¹gËÛèüÆ­¬¨‡D bOSÑ _)”ë sÂ|¯`ÿ|‡4³ä¹¡Û5¤-CÒ4´ç{Ì>ñ»þz?v3j21”¯]ˇ>¼ÈŽ{ÿ™Ë?vþΕ?_ù’U™ªò¥!´4›ú3dz‘e¯f`mÖ´aéxFw®Ewz–Ö¡Ìí?Œ±–¨¦bøÁ¦_ ¬ú¤NÈz: ÐEÑ:"(_S‹ª!Y*‰à¬¦1Y'ˆˆ&6ð–÷?Äë/>ÎèæI\’8Äü^ÇF§˜ûáÉke^_~ üKF4QㇳȎ³DÉÑæ†Úkï? à,}ïQ£ÁÇóvQÏæ31=«D@,º$ 5Ê‚öÕ ¾s‚ B&îbÛìÃ(ž†ö ¸ÿ7îdõ•oÂZƒ°N0 ÂBf í IGXzvëÔ6nàáï>ËÌÒõ!â‰:­= í¯Üº¨”׃±-¿÷òy«>#,þɪX÷KÙB†Í’¢lD¤”ʧQJPZ!Ú×(Î §¥ˆêu¦Þñv¾=¸Ù…çëÀ9¡0®´\(,§Iš=æžØ>看[Ã7w=Ã{.ͱËm[ý ̸ëV8œDã„"·ä©%Ï…h²LX>|Œ,M ¢½Ï์{KxߥélJ¼ Sàؤƒ+š“/"°üW'ôœyu–‹«œhP^©_(Á:ÕO™~áÕJ£CŸ æ³â¼óÄgþ©#|ôø4fbŠm«WÓM Ε^´º³K,9ŽÉ tc†G`xõZºö!Ö ~pÀ¡¡XÌð+Џ‘!¶ƒÉ«·p­ÿŸØi|¿Ð—‘ZÑs àp(DpZ¡´†RC ¯àW"¼ZŒ,ìâ™EÇ»Þ@wb3c—l¦6:DN@ÞµÐ÷ É &@â ÉÜv±Ih¡È Ò#‡gñÒo¹tœÏ)ÀvRLËbbK&àûØvŽKl|éÕGo:~ÍÖÛü¾Xßî´Šm&åhi]FˆJ¡< (O£B¿Ô"¼JD8P#¬„<|Â2·þ<Öl[G/3¨Ü¢P ­§÷‘w:øƒƒIBÞíbÒŒ4M±Ý.b †<͹ìÌÅÕuÒ¶Ã$Ÿ?A8ž5$±œxNâ$ïürë‡ßþìÖø6“Ìå.rÄ+­P~9òÊ×èÐ#¬Gµ«¼jÌà`@P93öæ&È’íi”Vè~Ø W­Qœ%ÀDʉ úBMn…§Ÿl3"Ç÷ßñýÆv¨_ÊCûÛxqÌèY ¹óQºô€êç¼âÀŸÚBqhºÖ Ÿ=^zÇZÄIIÄ9\Q`ó6ɪ`[ ^lðª;ß%PF=t Î oTÅê×)ñ³ç{'¿~|؈A¤Ÿ¸®Ô-e8xй™ŒæÉ‚ZB_¨Bcý Ñø âp…ÅY‡:…üt­Ø÷D¸f3brÒãGÁ–^xÞNcÀ¦¸n‚ĘÖ|93¦-¤›ptFxÎ qÆUñ2G[_{.ÚEÕˆÅÁ˜²Ö{ªŸÀ~é•^ÇP‹„jEh!ðáÍŸã[3¤Þx9±¹¼|æÔ³ÏçÏǹˆ ”ÆYÆ "à\RÎ!&§¢:˜N`xÅâªbl«…Î2¾pw•ÛÞÿ,ÃKÇ—ŸHrßtri‘#Ît‘ A¨ph”W¥ðqÔ+P‰…ÐÂVÇþŒ;ø³îõÌ«‘~Ø(Påì\W t𠚺A»ˆH\€]˜Á¥i™—âÊ‘wç,¯Çpжs"o ”‡µ—ì²áÆk +ö²´ßîO¿·ÜóÛ{–°FÌ—ÍÛt#ld©Á«éþ¸•ÕH)¨U‘"â"_pVxMíiÖÿÝ‹x¢ØD[ª¬ðšœïàò§9gE‹ÊšUôV®ã¾åÜrÏûD£*uls¾Ÿåèw[)½i†uA ›[Tï ~Mp­›LRPM2–¤ð|·{ò6ÁïîY³øNÚ2=¿Ö‹Ô)“ *Ï+sÂÓŠúGá A@Bo.AÆX6y÷ð·éØ#š@ **C!´ç¡3ßÂ_äõ¯Òè Z¼ç›gÑY*+ž˜¼¬>ÆAë$¿yŠͽmÐétQ&Ãö,EÛà2C:oÄ‹¤­|yÀßxÇ´ÓlóæÌR1žåƒ²‚² ç 2›ŒHÂ@£ŸN3áÙyX³¡JXjž”b‹rÈ¡È –0sd‰ÇÚÇSl£›§¸¨™;Џ²„™á²í‹øi×ÊñÇBLÇâÒ‚¢U`3Á$…ؤP{V$;à?z¦Ï…?48‘y³8Û¢¥ÛvJ‡ë4q ±…àW<‚ø.â <êCнßï1{,cÅêˆúˆO–ág ¹¥™zü}s;Ý%ôâQ|­ðµÁõÚØ^¯”*"°Üãæ×.,ä˜Ü ”Æ&Ó3-ƒÂQ,çÊfJëÿHå…:wÿf5añgÚVK;1jí† iá^áU4~¬ñC…ÅÏR”*ç‡nOxèþ”(T„±&ˆ4q~ |¯7Éßô.f¾¶ ÂJ™´}eŠ)°óû!l@ÚbCõw¿ÿƒä˜Ôy(Ò…œ¼U âèÍfØÞ`úŠÛš•©Ñû6{\vÀž¸kJîEä5y&Ò\vÊŽê#òJ9´ö°až1ˆªƒ—]rë=ôÚysŒaþµ˜$ÆQ °$YYëqvÀPYYvµžåí÷¨ç) àÙ9LÇ•£Þ)°©…EOLsSœ|`cTýó;³ç \~Àö›+ù0Öݯ´V󳕚OkÑ0öíú‹¤ B<]¶šA¤yÇU–?|t=÷ž˜¯^f{ Y(ºwÀfÌ‚5LmZÏ‘d ¬šå†Í{ñ'×c[mlRô¥»Pt,b ë:¾³£ºrã0§À¿¨¡¹k½&+äñ ð¾ëa_›£èö,ÖÆPˆH†=u„}™á)ÄÁDœñéKž¡]ä¾é!þæ™ìë­¥áä35ûºÂuŒÔ vþÒn<·›íã]†FèÈ'9±„K,Ú+W‹¶% „¯ìYÇR{›®õýüã]œøêŸ2q͇^ ðóG@òUöÓÕX_’v]˜”1ŽCzlÜZ¡@@ ‡ˆÂs|Ay ¥!ÔÂh”qÝÔ ‘Køâ¾“\L˜!tñ•°vÈpÉ:Ë;.NY-9ƒuKe Æ÷Åñ%²¼Ø‡jL¾ØAŽ]LJøÂÉײóæ#¬<«ý1€‰k>ôò«Ó_ðwvswͲQ’Qž‚5ë*Œ¯Ð>?/ÔxB÷=¡4ålŒjKäš),ôÊJ3Ru¬vEâHS>a^ é¶ ERPÝ4A¾Ð$î°”…ÜÑÛ!7½¹£ÎÝnï3‹½«ÕÆ·§þ–ÿúR_×\3ë¸sŒP+ÿX3—•Ë…+Jy¶lª0<ê£+Ú/TøA)øž'¡J][ž-ZI)¬Ã`-h²ª‚‚5†´]0xÞ8‚Oó±i¢aÅ๠†T<Û¸8zóž»?ðÅš_w|aÄ;Ã×j×BÏÕƒ(O)œ°ycÄȘ¨²´ªôBPJpíQöª¿2ÚW·(Aùe·¥^¿Ü*mgò[wÍÜžˆ]–¥>óÓîŸ £!`eß&€UÀÄ^¡¯¼°ªÎð´ ­¬8´8ÂâŠ/~ˆ <ÁÓŽ0t*ШH¡cWQø5 ¦B›Ï·Yþè·³ÿõå§ÜƒÀI`8Ñ¿N~§ö" ŒöIŒ÷σëCÖ]7¢·ï¨©Mk+ze•7< •å ¾qEQ‰@G il¨I=U´Dµç –·Ü‰GÙg¿òdöTô0Ì÷G¿ûràÒz@F€±>¡a >ê3².R#Û˜<”Ò;³ªGϪ«Õ“1+ŒRîNØÇ—IÛ©¬+$¹“4µô–3iusiÍ>Ø“}[êÇ~ö£÷g}WÂ;È@ß+  Þ¿¯žÊ—þwu?éÔi×–r£&zýÑm÷c½Ý·nÿsó£’ößâeï´äŽú€+ýë¨ÿwÿ4ê…W%0@јéi–÷?ÿ‰€ÿ[¼­¢N]ï4À§?õû§Êý‹^›è›;í³Ÿúøß8ØX«èh§ÎIEND®B`‚eric-6.0.8/eric/icons/default/cookie.png0000644000175000017500000000210112342633754017166 0ustar piotrpiotr‰PNG  IHDRÄ´l;IDAT8Ë­”MhTWÇ÷½73™ÉhÒhLǯ ‰ Ó4ˆB‹#]$ûZKã²Ëv+Áq'EÈÒUk-i%ºh+mihÑ,Ô606:‰3™I&™¯LÞ|½yïÝûºhˆ¤I©.ç,îÿÇáÏ9G°ƒH-†ãàýüÃ& Î|pYMo§1vúO#‡«€f·Õh;‹L ‘)±»U£PX¿vI‹¿”Ž+w—lÚfc·û:~¢/üÇí^ð<~*¬"„ñá'sm=Ö·û›ü8±¯oè:5ýÃdž”Æû¥+’¶3ý¿<.-<Åj;8;ÆRòF½A—òøÏVLLLD•Rッ” kñ®šI(¿Bç®]èzb¯Å¯]¸°m›L&ƒ¦iŸ]½z5ýBðÄÄÄ(ÐÝÝÝ=‡/ìëíE÷Ò¬¢r9‚¡ ØwäÈéH$rÚu] Ã@)U½råʬeYÕD"1û°Rjˆ‡Ãaο{Àcõë[l¬WØûöYR7oÒª7blll«»©©©ÉT*…Rj8Ãæ´sñâEïܹwˆF£èºßïß™¹…»w(|ù?f–芿EÿÉ“Kêáúöƒ¯Ëj?×׋¬W©®eÉÌÏÑ©;ô 9{Ÿüb’PÀÇè©8ûŽp¯¼L%û_$BøÄIî%ðë·_Ñ?ãÕÁ­¶ýÜTh‚ÂJ–€l°'lPY^ ZZcfú6¥Ì<‘ž0N%Ë›ç>bqv†òÂ}dô0ËÃǹóý-ҩǘµ&Ù|ZÓ~¶y‘L„Õ:Ân¢aàI‹F½†[Im<§I!—¦ïÐõô=3O³Q§Z.3?÷šp)ËÌ?^¤´Qa£)/VÃD)xÂCƒòÒcPÀ'mf¾ùÛÌcYõz•uótmËÆu%š¦£y~ ý·R:—kŽþ~-»m7kø|£ÃGñ¤OMƒÊêBÙ8ŽBI‰]¯"¥Ž­ é Z®—†vcËã™§­ÄÑãFW9Ÿ­¬< oow¼Õhà´-\»EÛj¡\‰Ó¶qé(OCJ{Z¢c)0Ûr¶P6[ ò¢8íðvrRgÒÖ b;áÈà~ì6t}°Sk½áC*k%'ü(Î-¬Ôþ ¬ tl¾ z.‡6Ϭ4Öf¶6k hlfç/cíZ›ðˆIEND®B`‚eric-6.0.8/eric/icons/default/localVariables.png0000644000175000017500000000123012342633755020643 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ 8*ªÊH«tEXtCommentCreated with The GIMPïd%näPLTE±±³ÙÙÚÙ×ØÆÆÇÊÊÌËËÌÐÐÑÔÔÕ··¸»»»¼¼½½½¾¼¼¼¼¼½ãÒÓåäåååææææææçççèãÒÓååæææçççè»»¼»¼½¼¼¾ÂÂÃÃÃÄÅÅÇÈÄÆ½½¾ÏÇÈÀÀÁÀÀÂÀÀÂÂÂÃÂÂÃÅÅÇÇÇÈÊ£¤Ì}~ÐÐÑÑÎÐÑÑÓÒ…†ÒÒÓÓ¬®ØÒÓØØÙÙÙÛÚÚÚÚÚÜÞÞàßßàààáááâââãååçææççççççèííîïïððððððññññòòóóóóôôôþþþÿÿÿ ÿ-æ(tRNSz~ž·¸¸¸¸¾ÅÅÅÆÉÊÊÊÊÊÊËËËËÐÓÕ×××רØÛÞââäñ˜bëTbKGDKi …PÝIDATÓ]Î×RAEÑmÀœs‡cÎqd´ÿÿ|˜èqWõ˪۷.£ÕåZ£¾V¯7jÕêêÒÊâSOí$I’vûíöõþæb€ÉëË—¼ç³Ç«»ó]&Z_¥Z;Tº¿¥ºÛ÷C©þV‰íœíˆm)ã)â\Cï©`[ÙûY ¶dKXЏ©<$*½ŒC –~$,ÆßÓ4M­N'M¿-}ž‚ÅÈÌÜìü‚µ¾±¹gëød,²,l,ÑäKÙ)8b18Ä*iø"ü#Ú‘ñÐ%ø\~E)혀5IEND®B`‚eric-6.0.8/eric/icons/default/preferences-viewmanager.png0000644000175000017500000000177212342633755022537 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<wIDAT8Ë…•Mh]UÇ3çÜ÷^“gk“¦ÆÐÆ* …T ¸µtáB¡HE?@QÁ…í¢ ]¸(hucA¤¸ÐºPKuQ)‚­B-V‹±æ£iJbÓH“æã½ûÞ=ãâÞ÷ò>’8ÜÃ̹wæþÌœ™+;öý<âTû¢("ç=mÚ{rQÔ¤#ï°ý½=2Î*â±ÐE°¼%‚©ÐªC"U‚A… FAë` ñ»£Âž{ûpÎá½Ã9÷UEE!B b’$áÜD…&úXøºu‘ôn,à½gvÉPçðÞãœC€j’ ˆ@‚ˆ°X*mzú£¥^ï>‹©Ù"²èD„_FØûÙ8ªZwh h²Ýµ#ï—)š5þWA(Åÿ•æ`l…•I§©í­Å2łùtyçp>àUÓw™VUœ NuÁ©¦uQåj9—2¯=ÜÇ]·v¥5€L×Vêk$I’5Óö'?-ež™ˆÈªZD832Ï鿯ՉŒ_)7dÉ´ †`fX–‘ÕÀeß§ç13Ÿ˜äñC²÷È…P@ ßü¢ì·±~3Áî»{Y}O ÍrøÄ×wzö?zccAÑËsqøc|Ž‹Ó‹È aÛæÓsNŸŸ% ¸j¼ñù*ÂÛOôsÃz߯Ø=úÝ™÷Ÿ?xüø_ÿþk+èRžZdcÑóîS·`•$0_N(DBÎÃØt)MeÃ@G¿|åõÑ£¯>¦=oµ99ÍË3xS'N! †Sá…›Y(Þùv’7]ª6²V3 fVѨ4VØÌxòžn=s3gGç)ÅUÌ ã¹zØ²Ž¿&—¸³¿£±!øµ­3¯ÜÖ[`f¾Â¯.Òוãöþ>ü~ŠÈ)»ÖsÇÖB(¤½¬­ÛzúÉ¡9:rŽ-Ýy.L—85”Þã™ù Ûº#Ü^l‹Içñªc!uxdpíØ@>.ÏÆŒüSâ¥]=<{^À,´§BZ€[O­IΧMôâÎMÄU#„@¤  f`-ÀÕ`Ä•U«·±ˆÔ§XPÌŒ¸šf3Â,=,˜‘$ÐX¼…‰³Wö1›]Ê­<³½:¼:\ö3Xþ–Ç»t–“ÄÃR¯¤HËïŸÏ&žÔ@Xîò•mi å…«3ÿ£ö‹òGz÷IEND®B`‚eric-6.0.8/eric/icons/default/vcsTransplant.png0000644000175000017500000000156212342633755020572 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs  šœtIMEÛ ýFÐ!iTXtCommentCreated with The GIMPm°—§PLTEÅÅÅÆÆÆ aaagggžhJ………ºs–––ŸŸŸããã\ÐÐР  ¬¬¬Ž)———'×±j “““•••+á– Ë„çççèè躺º”””9D9•••˜˜˜•••——————˜˜˜™™™›››L‡g   ¢¢¢DhMåååæææîîºÎÎÎ  K,ÜŒ;ߟwë³Ìüô}-Ž8ƒ,1 ®OÏq×~»TÛÎiÙw%ß…%á‹,Þˆ-á›1ÝŠ?Ù‡DÚ•FÜžH¿ŽHÞ§L·ƒRÕUÙUÛ§UݯVܨYÛ“ZÜ‘]Ýœaá¸gãªoç¶pæªrè·tª™{š‰|ì¹~îÚí¾…ï¾‘óË’ô옘˜œœœžžžŸŸŸ   ¡¡¡¢¢¢££££÷Ú®®®²²²³³³´´´¶¶¶¸¸¸¹¹¹ººº»»»½½½¾¿¾ÀÀÀÁÁÁÃÃÃÄÄÄÅÅÅÆÆÆÉÉÉÊÊÊÌÌÌÎÎÎÐÐÐÔÔÔÕÕÕ×××ØØØÙÙÙÚÚÚâââäääæææîîîðððÿÿÿñ&ì7tRNS %===\bbdkŠŠ¡¥¨³¸ÆÇÈÐÐÐÝááæèèêëìíííðððøüüüýýþþþþþ´áÁ\bKGDŒl ÒCÔIDATÓc` ?`ä•ÑïÖ—æeBåðë¶wtuvèñ30°IŠÂ9²-m­ÍM² \fšpŽvYUueuU™–T|B–Ni%„à’ZÑP[Weaägäd*3¨§äUçz9ú†„…GF†¹[äVd¨2h$Ö”øX;¸xúz»Úš”Ô¥ª1(¥”gVFÙ›„º9ÙX9éŠ ɹ5ùE•iâbΡ± 0§œAu^±¡<»U¢œÃÀÂ-(,Àà ô#³‚3XúªDÕW RIEND®B`‚eric-6.0.8/eric/icons/default/greaseMonkeyScript.png0000644000175000017500000000272512342633755021550 0ustar piotrpiotr‰PNG  IHDR D¤ŠÆ pHYsHHFÉk> vpAg ‡úœ1PLTE˜˜˜™™™ššš›››žžžŸŸŸ   ¢¢¢©©©ªªª«««®®®¯¯¯³³³»»»ÀÀÀÄÄÄÿÿÿ      ƒƒƒ            ¡¡¡PPP                  |||   žžž                           ¢¢¢         ŸŸŸ   ¤¤¤   ———            žžž         ˜˜˜œœœ¡¡¡£££¤¤¤¥¥¥¦¦¦¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³µµµ¶¶¶···¹¹¹ººº»»»¼¼¼½½½¾¾¾¿¿¿ÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúÄóƒÕdtRNS !!#%%')/00345799BKNQUW[orx{„‡Š“–—¢°´µºÃÛäêêóöKwô÷bKGD{¼l1IDAT8Ëm“ÝOS1‡ßöìÂÜd, ‰!˜hH€„Äh üÃ^y#‰Ñx7^¡„94€snçtçc=m½€É9²^5oŸ6OÛß‹UÈšõ;Ç™‚È-‹ÖÆ–é~™>¾)Qhmn9ë=idJ9`o}Ói5 Z}2°û|Û‚¾™W¿&»Ï^¸$Øå¿'J´IÀò糃 À¥ÛÉë§- WÚ4šiß=^­µ\(~ÜI¨j+íÿ͵E¾’+!’œ5•ö¸uhl£bU\ú"±rKë…ïvv¡3$BJÍp¦“—#cÿ¬^œMH­âÀ÷0pæ7ßwþ3ÿü‘ËåÄÀ¶™}W߉ÆnEck~:ñÛMÛ:–eõ¯^½úIñ ê¹§r+»»—ÞOvÝšHu^‹%³a3Âh tƒ}¯.þê¤?88˜u]÷[ãð‹Ï^¹!•긽%™XŸH¦W%SmY3Öj¢ZFàn]Ð.CߌòÎû_ulr§FO:tè€ñë—÷>6ÄæD"º<‘joU‘C« ÈB™ C€²%ؽ C×Á=˱á£ìxú]&¦1Fúûû‡âÔЖÁžeÉ-ch••A«„ ƒ ! lðÎ#ô9ðŠà—ùý:<6B©¡³mŽ#ÃS¯–+sF½^û2 àN㻓h¿†`ô4BºB¨HÀÙs>>ŠeÇYÒQgUÉ=w^ÿó£;¾À˜žšúDÏþñ„öªhíá«Úh)@ „”€6A­§f¶>2Š eI‡ghoÕì}~ ~V¾n¾^ò­ËC¶]v}dUI „h „ ªÕ=¶<<ŒíDê2‘°Å—×!¥ ++®Èår@î;8R›˜m/úF{Ó©!EàPŠ ¾TضÏÖGFªÚì$Ú¯òök…$hMWV,¢ù`z6re‚%ƒøMxàÔÀó%Û3×h¡\©àØ%Þ;x±¨j†×t´é¶xŒÎpuN %ªét*%¨Hƒí;¡0“SṵϻoÜD:\­}´ï’ŽqÛgýØr À2* T!CìÚó'£'jŒO¸tv&ymÏ•,é\t·´ßE»Ë»¬¾ð©¿üÁy·B©æÑ #d˜W^/ðÅÐ$ãS—-M±{G–žîÈ"¦Fkí5ÐNöÄì5 àýoÖ‹•šQÊd^¨0o¾7ÎÛ(N™ôt'ØþP'k®N^ØL´žïÌáÛÚåe¹\.$òù¼?U1Æ„a" ! >ú|’ýoŒQœ4éYf2pš›ûZ.d6ÿ­vçÐv¿Q"“v3@ZÎT™Õ'„¦|Rcמߟ6é]ç¾»;¸ë¶¶zà5ðí~£„o—I§Ýà’p½®¿pM(~½½kIÇg¹¥O°uÓ?¡´ž…רâ[Ó¸µ"* -q?ÜžqzJ[ªx_¼ÿi+ëÖu³íÎ,ß,ÉòøÀÊ‹œ¢}´;‡ß¨â[3xõq¤tPa¨ÌµdÜ]!÷âC{—UkÞæðo#ïpùå3\¿.óïñ] ß®âYÓxµó”KÕúÈXüäù̱Ͽ˾¿àY{í^_.%w?³”DܸإïR.Yµ3gª…³ÕÓg µŸNžÖß>Òú­ãŠsÀl>Ÿ÷:x0.»tÉý+ÔøK/,ïð<í'œ™BÑ)ÎÛ§Î#GG­¡üqï80¦•Ï×Á걋ž´yÇI`ù–{Wö§S‘OÕ=öcùÇR¹~Þ¶íŠçy6à4åö"9‹4?÷þhö>hD0ý1IEND®B`‚eric-6.0.8/eric/icons/default/vcsRepoBrowser.png0000644000175000017500000000201512342633755020707 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ"ò~þðtEXtCommentCreated with The GIMPïd%nPLTE¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀœœœžžžŸŸŸ   ¡¡¡¢¢¢¤¤¤¥¥¥§§§§§¨¨¨¨©©©®®®±±±²²²³³³´´´µµµ¶¶¶···¸((¸¸¸¹¹¹º’“ººº»»»¼¼¼¾¾¾ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÆÆÆÈ45ÈÈÈÉÉÉÊÊÊÍÍÍÎÎÎÏÏÏÏÏÑÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÕÕÖÖÖÖÙÙÙÚÚÚÚÚÜÛÇÉÛÛÛÜÜÜÜÜÞݵ¶ÝÝÝÞÞÞßßßßßààààààáààâáááâÎÏâââââãââäãããããåäääåååçççççèèèèèèééééééêéêêêêêêêëêëëëëëëëìëìììììììííííííîîîîðððñññôôôööööö÷÷÷÷øøøúúúüüüÿÿÿ4½&iEtRNS #*+128:>@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜bKGD«Ég(IDAT•ÁÏJaÆáß{¾oÌD¦Y˜ APpkW½ï²Ðho¡B!ÍR°¢Æü&3çt>·vÓçá¿h>å½—|rÌ8¾Ù¡ZÏ¿šüG×6û¢iÚ×ïíúu³ }ºå½o9òµÀÛ{µÉ î"Dz‚èm·H‡v|R –‘)wuȵãyw} D¦øõ0&=+Â÷|"S4“:úÝöŒAm¼ÙÞ·c“U›}n™BYÛêÉ'†ŒeÞ¸çªî« R¦0%﻾ Å,;$QÍ3£X^‚÷n£« @Êôåâáý‡éÍÌ)ÇÏK:÷Ý%c%O""K¦¢63™ýæß$È y>ø -yxÆrÀëIEND®B`‚eric-6.0.8/eric/icons/default/zoomTo.png0000644000175000017500000000246612342633755017223 0ustar piotrpiotr‰PNG  IHDRójœ pHYs „ „ªâcytIME× (3>>vvv__`111‰‰‰}~~777ˆˆˆ555®®¯œœ———333011‘µ¶·EEE¥¥¥—îý¡¡¡ëüêü‰èüzz{UUVäú~äú|ãú«««VVWtàùwáùsàùmÞøqßøjÜ÷qÞøfÚ÷vàøcÙöcØö]ÔórrrVÑóUÑóVÑòWÏñTÐòQÍñ]ÕôTÍðÃÄÅLÄëLÁéKÀéJ¿èLÂékkkI½èyÞøÅÅÇF³áE±à‡‡‡D¯Þxyz‚âùA¦ØD©Ú@¥ØA¥Ù¯¯¯†åùŠåù=šÑ[¹ã<˜Ð€ƒŒŒŒÊÊÌ8ŒÇËÌÍ^²ÞiÝ÷rÞøyÞøyÂåAÇ‚Þö¿¿¿~Ãå2|º€€€¼¼½}}~†††g§Ò~~~ŽÆåQÂÌÌÌ/k«»ß‡Ûô{{{›››ŠŠŠ*d£•Âß•Þõºº»vvvg¡Î>>???BBB)))%%%%%%''',,,///222666;;;>>>AAA¿¿¿ÇÇÇ¿¿¿ÒÒÒÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌ$$$''',,,---...///00/0001101111212212222323323334434445545556656767767777878878888989989:9::9:;9:;:;;:<<;<<<<=;==<=><=>==?=>?<>?=????@>?A?@A?@A@AB@ABABCABCBCDBDECDFCEEDEFDEGDFFEFGEFHEFHFGHFGIFHIFHIGHJGIJHIKHJKHKLILMJLMKMNLNOMOQNPROSSQSTRTVRUVSUWTVXUWYUY[WZ\X_`^|||~~~†††‡‡‡ˆˆˆŠŠŠŒŒŒ““’———šššœžœ¤¤¢¥¦¤¬¬¬­­­­®­¯¯¯³³³···ººº»»»¼¼¼½½½½¾¼¿¿¿ÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊÌÌÌÍÍÍÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÖÖÖ×××ØØØÚÚÚÜÜÜÝÝÝÞÞÞàààáááäääèèèëëëïïïí@·Ÿ5tRNS #012Ybcefgimmmm~ƒ„„†‡ˆ‰Š‹Œ²´···¸¸¸¸ö÷ûûýýýýýýlóDX IDAT]ÁMnA…ÑïUW»­ „2†ÙëaHl&,(aÆ1dŽû§Þ½tl ¡œDá1¹ÒL x™¦››]éJ+ÛJ½ûö½Òmn{µ¶,mY%䇷Tð³çÙ”óiÇÑÙ~ÊT@~ l÷‡?2–£øZ»\î~ß§d¦€µï_ïw‡)%ÎLs½ýÜ´JóÀ¦‡_N¯žN·J.L<*?Í÷)q&S9S-•æÂ;­Uš3C°RÊ”¸(R*3%þ©@ÛÓ´Ì“8sŠãÍ|¥¾xsŽutë®_cÙÎC«KqëǾÝ@…Ó ç&ºá8¶Çxb½W/»èÀ`Lzÿ+¨5þcÚÈö$å'ŽgœõùÔÙëwÖ¯³öZþéšÐúyùSúey÷Í¿þ–|}â±³YLÚõ¬ÖÍB fºØïÕƒ¼ŽÛÍÖ\^Й+ôõßuãîéËGÿ]ý—ðЃ™•¥¿ËfTª4Ôxuuù²•fu«NÌ1ÇF<¥jËÅrÓÙ¬²'Ö¦’˜¹œ=W¬(}¸}2÷¿>ï3 þp÷çvYIx]~l}iÝôüü%"Ž/#mîH,{«©¹ezõ)†zMávºä©ÔûÿÐG_¸õ‘ûâ_(À‰§¿Ø÷ÐÁƒM|~Ç ÿlrì’›Ä\¹Î#ÜGõä)š K”v Ðh5Y׈ޑ„¾ýì½ûîà¹O¯:ÁΞuRì,mã²~ƒ+ÿèýô™dèrdÊâÊâ>N;H'Œ¹á¦qΛå̬ϖw•ˆ[‡-~}žkev&ÅâB“86ØþÞq:õ&Ó¯N£{!…”ÀŒ¦€‰’1ÂHªE7óØ=wOw¿/g!„þ©ÏŸûÓío—ÃÏŽ]ñÞ›vD¶X8’›?y }}MªÉ[´ƒåç¦xù•sÜò¯ßÃû÷meéè"§_X¡\mpíu›°b‹òt5›S”^u8÷Z…‘b–£/ÍSךëÞkàËlJè,B·£pµÆÊB;!V‰t“¿Y7™~jüÌ›ø‰WþsáOþTÿ¾]·múíÍòRq)|yãjšL¥A¾ýØy–ò.“xgMÊoÕpºjU‘Á@X bEèY #íšæ“3ó'ÿöÌ·P³¡*@¥/ù0«?œ_;`”„‡ÍVË34ÕK™$•a§C³10œaõÍ:Ýp‰• KxA\ Þ>¸Âäî„BÞ¥Óð8j‘Új—›og|›à‰¹N½Ôfë8Ä …‚6v Â0Ñé´ýL1%~ÿOŸjÿQ>þX€¿xðÎ=TJŸH«y#Ð$ÍLw•Ù%º§ÐÊ&²xž Ÿ•$½aì‘$MÚMEëŒO¾°Ê´GŸ\¤TJãã3¾]²ÎÏ¡Ô*«ÇƒvÄùUƒåLLÁ”hÃÀr$^¢U1/þvCê ÷>\{õÇùù#³ÐñWÿ«õVÔûd}pëk3ËÆÌÁ#éSGÏb„5&'S´Ë+´k{q‘|ÉÛåᦠÊKVPHYÌœi±à{\zûÊØ‰_½†,7²÷S(îgÝúýDzÍöQ¥l3ÉçÇ&'‹÷üÁ×–_ûI*ù‘8·.©Vû>P•'µ;F¸ð­#œÿò1–NkJ[ ò;ŠŒ]:@)oÑIæiéÄ!Ÿ¼Ø:`1=Õ`ÕJÛœf`r7£™+Nö±~ãzz’v; N¢(¡ø”Ö„ Žï' šºÛlTÏ/µçüÊLø‰Iæ‡"p¿úªÙX–Ÿ †Š-L˳oÌ¡­eFF(“n£ËغnFâEŽ Xn1`;$ ³mΞMè¹6ÞµžTæCl^{¯ØÏäÄËòr›V'àØÉ2µz ˆI”ZY¢42šÛ5°fô¶vëéµ_<$?Àþý›¿;Wþ̹3Ï gDc¶‹"ËÐð#ãþb—úBƒ¸Ù#®ù$«3§j”W{4,ÁèÛéTïÙw†ø;6^ÍæÍk¹üÊÔÇO–1l“© pŠ#%FÖÒlô0-Zèü@ž¾á¼Õן, å„Ñecõeõ"\ð"Àâ©;¯½¼FôëIå´!¦Ï E}%¢?™G/Ôˆê!åó/=»ÄRç“UŒ]ÛÇÄ#ô_:D)ÎâÔ$ù±oïš­€V/bbÓa¢É3´{1gçêôü˜Ò@–Á‘"µ¶ÔÛ1EF¢Q÷ ¼@ŒNÊÙ'}ýõå‘çàXøc>ûÅûw¬¶ÝÏ¿}æðhå­—™Ÿ©£ Îì2¦bʉIÝNááR 5Ö³uÏ”'9ñR…™CFj%¼Üoqǯdf¾NNjٺm„B)ƒ*¼(¡åÅŒŽqÓ&33Uv”Æ” Ëq¨Õ{tü HD1Eß@–n7Ü£¥›iU×¾ Gƒ˜×³Æ‹³KŸÃk­Ö åÒ[éµBtâ“S^dÒŒMò)AÉQd‚ˆh©Çò©*í…UúŒ„ɾÉí\wãÕtz!+ |!Ëõ×o¢Ñ Èflº€g_>ÏüJ7íÐêhÃà¥C³>Vfi¥ÃÒr›F3Ä0Ú´(ä]+¦D»ì 9ãµ·7Ô?ÈBŠÌø¡ÃÇ>Ðq_1‚ŽÍÀÄz¼™ ´Ë/¯ìS¨…ˆFÝÀ–¬ß,¨×:´èt nCkuˆëß·iJ—{´: n\G* 9›j+â•ãeÞ<»Â ×LÒé„`È8"›6¨¹ëÇK,UšaB/f7çf1®Ìš Éúâg¿Ø,sêŒÐ¼bï¶u›™å±‡ÿŠÎR™V7Á½,IŠ|!$¥•Y˜@JM*-H‡ ›ÁñËð#¥¡Úèqà†-lÛ2H­éSn„±fßž ®C+¼{÷ã0ˈN$p2.©ŒI+P$QD· $ØRR]íè¹óU®ºrݤiš:ÑþÝi¿ûû¾q±²û’ù4Éo9wâ:åX·:Í’^¯Ó"eA:^‰@+MÚ†´ Â×d, œÝŒl¼•P»”JYR‡[oÚJ½Ò ¶e „ åE¤R6¥¾ §gª(!9v~•Xi²‹¹•±ÒR"¤Àv,²ù–c‹á5}Ó‘ôrÖÃËKOw$ÀáäÝ[§ûnJ–úäñ'ÿ7#Œ8EÄäéú …N½èbµØj%ÔÛ1_Q$¶÷°Úq± Ë1è…1Qr1yk^¤èx1–)îÏS MŽœ[ÆNYŽI3T()°SX&X^“hÁš ƒôE¦/‹4ÍËÂ$Ï÷}Z˜ËéñÙÅÖÚ±½ÛÉ6yóÕ‡(É*A6¢]‹ÑZÐó*6Èd5¦ :IHH ½dj3MC5ZSàð©erù=?BiPRâ8yÇ¡ëE,T4¼DJ’Dc˜‰@KŽ„1±Ö )×D'èL!-ê•Ú»R9÷ °¹M®˜Äѧ¢½¼ÈÜ”Çñ·{øQˆ*l©qÒŠX(Zíˆn7&ôa Aóe—X9)xáÐ,ož^ÆvMÚ^„”SJR¶ÁP_€s "¥Ø¾¡ý‹)´i¡ma›Û@XÒ2¶i¸i››qS8Y—(æ@¢lÃÄSo|g¸<¸é¾!fÞ~]^Æ b2Y…›Ib ƒmD() C`Ci‚À&ÓŸ£D´"…‘f+¦Z\µk”¿üæ1voÄMÙøQB¥á!L“|Ú ›±ñ4´—:%A&£ ÑéÚ äÈ¥-`¹J1 ¶4Þ>ºât-F§ÂVr•!µ ÃÀP~"QS †ÖJXJÄRKShí¥Š‰7MS„†V­/þ׫­€K¶óÂTûž>Åu»F™mÅ«x`J,ËÄt$‰Vh¥!‘ Bktœ€Ð©HeRø~Ìw¿{– åÑïJ½Rö…RñQ)”2¾þç÷7gO¿ÏÎ9þ¤¥„熶 G:ŽmSÇR˜‘-‰2¶¦RÂsá;ŽÙɤRu7c/‡a’ôôDÆÉ m „ma§lN•»ÜyãoÎ÷hDÐßçâºû6âº&žâb)aHLC"tB’(„´Ð y× ò"êµ.Ê Q'ÂND¯Ý½§Û¶O˜Oøè'vóÈ‘j> Åæ\vh Žq{t;F§Ý•*Šãœë*Ç2¢DıЪkYnOJ§—JE“Õà=Km/“* ,Ç1Éå\*€Ãi¦Z݊χ÷sÍD‰f ¥äñ·«œZnÓè„ÄJ!µDéiŒ-üvÀôjWh‚$ÂtlDèi)ĉvõóêµÐÎw”|ðî¿^³Fmif:ýI¤Í(,‘„¡j7WDäõÓ4uÊ6RQøZűÒÒw,o¼Õ)¶¢Ñ«êÍžYp z~D6ã0·ÚcíX‘®Q,ºL ¤h1íH&1{Ç‹ìÍñÊLƒÓóu¼Daš&}.­Z‹ss 2¶ ô5Z:e Z^ø`¯U~èL|×]ÿa˜}'ýÒ_;°[<ôÌñW~ë}ƒk«Aw§/ryß‹°,‹V; ' bËdóÆ™lŠuÅU?Á2$Z@/VHC°e8ÃŽ—¹•.ý6¼z|‘ó•®e’x:VÚ6µÐIû~øÕ…SÍwÜÜýQvrúbŸõŽkÆ"/tßÕ #±•ÂNYÄ„e›¾ò.©´MÆ!/Ö!B(-–ŒåS´{/¯`I/Dû‘Öq"2¬.µ]š«þ±Ž¾Úý…|⎛Ä>øüâ¯ß|i,ÂþšçfÇÂt-Ó6ñ˜®E,%£E—¬m`C ¶$kKl!¨w#þê…)ÂfD¨0Ñ4A$ÚåÆY¿Þú=¯þG§®öú³Co_œW=wèÈá{>ûщo¨÷L·#LŒ´­× ‚v¢±‹‘‚Ú¼KÁ1(:’”)p Iµå3¿Òfv¾†× 04Z¾/Ãjs.n¶~§6ÿí§ üƒ äl{÷ï¸çÎ[7|*z÷o+˜S‰ÐZJâXé3•®>[íQ° k  ~¬™kxÔÚ)©t>ã m[Ž-„Š¸ÚšV›¿³2ó_·ÔÏ=¡ùYlͦ«Îj­Ï}â3¿ûíB»7—úøØø`)=šÁÈ¥ôP)#.Hi/Ò”ðÄåVHÛ µ)a"ôRÝ'­.×ÕÆË^¥þ…•éG‡ÿ;¡ÿÿtÕàW²Û¯Ü»ÏÈæ?¦Ò黬á’9²iˆk/Ó»6ö!…•v@»J÷:˜>¿Âé£sĵæ]ïËå©¥‡+³œ‡9õKºì±Q¦FïÊeû2›LÛ¸ÍH¹¿™+å¶òŒŽ™_õˆÃÕí´»ò‚g¤ŽïÓ±x5åW*o½ù߃·Uú>.Œ¾¢)ÒYÓÊg ·/Ϻñ~æ«]’P¡»üf[Óó´Â…s ~–÷þÊ´é3Û“±¹IEND®B`‚eric-6.0.8/eric/icons/default/stepQuit.png0000644000175000017500000000034112342633755017540 0ustar piotrpiotr‰PNG  IHDR©þã#PLTEÆÆÆ?€OŸ`¿s߃÷€Àÿ$÷ttRNSv“Í8pIDAT×=Î1€ …ág@6XHÜ<qsö º»èÌâz…WJÁ.|ùC :T\è…v£Î‘s§£4 èyn~wá$ñ¨õJ”Ç¢D›9(µßb‰…^£p¦3Îçy¬‹BPzãiU¾Ç¶7IEND®B`‚eric-6.0.8/eric/icons/default/editRedo.png0000644000175000017500000000236612342633754017471 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<sIDAT8˵”ËoTUÇ?ç>æÙigÚéÊ Ð´”‡0Šƒ ÃB.ŒîÜXþ &jâ‚hÔ‚ nHPƒÆ˜A AcÄá¡4¥4:”v:m§óºwî=÷¸hi(TÃB¿É/'99çóûžs~ç'”R¬¥ôpªØ éå¸\^Ïf†²síÓ2CYO¬N§^š8ÚÒÝÒ6‘Šocc4IĈ0Wg$•[ùqr÷ ž«ÞÎ eO¤‡SÀñe#ﯧ‡SqàÓP4øêŽ]Oˆõ‘813DÐ4¨©2AÑ€+uf"S•9F®\Vs³¥“À¶dϺ¾C}¯ðÉ©*+àeh¦sK׆¾ý4û|¸Øü›L îúÍ]CAwG‚Ьrᇟ•ñÀº£í›º6ô&zqå"÷jÞ*ˆ!|xH<%WæE4t6t$ñ”¢ê.à.#e·¯™AßK›)Ô¦Q,B9+ÏDõ.“µ)å3›Xlc ¼™ á%Ê(@¡0ÍÆ¥¤ƒŸm£ƒƒ±j`‘šSÀÅãj)‹-k$ƒ›hóÅ10)¸yòö$H—ÞHq_3((<Ñ`œ‹?]TpÀ E@©ÊÌR6M#[¾¡Úq¶ûÄÄèM5kOZ(ðü'ûŸwÔ_Ü«ÞÆD# ‘J!•‡ .]¡ F›DÞγèV¼E·âܩ޵ !¬RbôÚÈœmY¯+¥¢ ÕgYÖly±H³/JTàÈ2®tp¤Mݳ‘Ê]§Ûš›™(ç*%Y™*ÉÊØt=¥ßØâÞº1®€·2CÙ㙡l8ÖÞÝoêTxV‰V_;aÑ€òj²DÁ™Æñì•ÇTºdAo*Á¼R”mÏ®\ßîÛ©ßóë@#€‚5~îˆP¼i—Ürý@ØóËy£4 TTm×šÔ ½[:ò à@f({8ðòωÖõac¦¶ ÃzX…ðùÀÉ•,ðûìBñÙÞ–ÎÐoª4X@u–ÂÉxcë;ÅBéãôp àËÌP¶tc²«ÑâÎYUr,Y|ÞzĶ\ªÕlšê ILfË/tëv`úT³‰5üÛìrí!Õž½‡{¾êÜ™8“ìè×ëãÒPBé>;ókêaðêîu­ õûº{Gùs~Í´ƒšY¿Ï}˜ôâÍ~KÄtD]HoF6yÚ˜ý§7YžuCºOjž»fJ)öîÙ)4q¨­+&Îû¯}¯‡´RH÷9!ͬ5³Ð ËÔtW¼³{ÇV¹KkÙýÓê0À3ï%b¡í‰ðæˆøvü‚ é>wnuÓñk†gÍûnψâ1´ª ‡Î Ç“úto®º(ÃºÏ ë¦ h¦úz÷}|_Oÿ²O¤Û»ó9oK4¨ •yõÅ΋ ýGð!ÿIôƒ#ûðvIEND®B`‚eric-6.0.8/eric/icons/default/ircJoinChannel.png0000644000175000017500000000275112342633755020617 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs „ „ªâcytIMEÙ-/&*rbKGDÿÿÿ ½§“iIDATuÁ{ŒTWÀáß9÷ܹw^»³;³°–ê‚”v µB+¶Ak­4VŒ­ ©¨ Mÿhbb05b%>ÓþŒ­©Ii(`hJBŠB åÑF-»uËòP²»3;»;ï™;÷œãhÆdcê÷ þíc3õxÎKßùóT|.0§ÁËzòC´}ÿ¯Ù̺[âû6Ÿ›^}6W» à ‚mvò2-‚òúwM·3±wMzßµ"§&*$}×É…ŸÏ}õ–“´|üÐm/ßÝùlà ŽÜ(q¥àÇb{þpÏ·h‘|”z}ÕÈT1×’{{;yþÞfË5Ù¬ÖÖÐveªøðÅB“¨Šðøm]|¹/Î¥\y mŠy¾÷Þì’½ç'?3Yn<üÙEIò5MÓ@¶pðò (gWÞ߸4ƒåC] ŠE Ák¦›®‡ñ£_ºyTÑöô™©Öö¨£çâ­UCîÎÄ(5-ÖÂØt™N×¢„ÞhÑiYšŽRÖ‚ZhéTp½P¡ÛaÉ#‡ Ax@Ð{eøÕŸ­ìݸbA7R@Õ*Úb-D•Äs$ŽÐÆ0Y7hmq°DH,Óå2?~÷Ÿ(Úªµ ãr¾N*¦±„!@jŒ° ÀÖ‚µk%ÆZBm˜ ÂX_¬0Si hZ_™­Öñ¤$@P ÁJAÄUx ÁX Ú@Õ€6 ø®ƒ«,'&*‰u h“ÛßÉØ|vog9ÿÐúW‹%ƒŸ@(Éõ‰›ì9vÕ¨#%ý}ižúÊZ*MH*Ëó¿jDª›R<5 ›$mfÓêéÈõ«_›óSÍLf-hÁèxŽ‚—™u%fc©Ä¬ß±«¿¯b²3e²¢P ?7gUBWjÝú‡_xM1O¸øÎ¡¸ "ñx'#q-Œ^Ë"‘§ô/ÖUø·-o­¼-ÓÃ]ñ«ìÝ@‡gý§¿^ß?²èŒùÁ!mŠùšÁýwôvp³.À PbºXAù±3pr4¥µ;oÍ,àWo¯`ÿ£'ÀÂwO?¾2b4îËtuQ ˜Ÿ@è‚à4-¶Q]Ýs䇡äS'WË‚KÙ‹®µv˜BThQí8yî>rþÆ2tH$ÖM!°(#˜¿‰g BWýÍob­dIß"¢.˜äY@P/i¶¿6œîðŸvÑ"žÛ?<¸øSwMè(~ÌÃx”Áu]‹çbÜîdÇɧ(ò8V‘ˆÄxé›;°À–CωZI¥}KƒÁÎ¥ÛDúGÂHâv'Œ&ˆÆ}ü¸‡ó‰ø.R€ç@\Á_Îvñ›G^¤J途CˆƒÀu<çó9ôÁa†{ E:3©×0Q¬1„¡Fƒ#Àu!"Áu¡T-óÎø»”e™T2Qxq«â¡oÜA*Á[‡ÇÈø;ÑØù$ÿ¥hQ‰xIÎÍR­Fñ Úó•ú±Ú®§s´t¾ð§bM‡=U˜k‚Õš\¥Œr@;†ÆÎ'™OÑÒxoøa〗%ÝG}árDS_ÀŠS´çÇ6ŽœÛ“Lg|å} õ§™ÊLdó)þ‡ -öÄvZVk 쩾±)Ë<±'¶/¾ˆ‹‡–ÿvà²ÿv_âV{£qõ—¥ç[˜ç_±>jË$%IEND®B`‚eric-6.0.8/eric/icons/default/class_protected.png0000644000175000017500000000073512342633754021106 0ustar piotrpiotr‰PNG  IHDR(-S pHYs  šœtIMEØ&ú8? tEXtCommentCreated with GIMPWœPLTE  hhhppp8r¡:aa;bbQ††^^^cccdddfƒƒf—½m´´‚×ךª·ž¹Ï¨··³´³¸ÌÛ¹¹¹ººº»¾½ÅÅÅÉÉÉËËËÓÓÓר×ÙÙÙÜÜÜÝÝÝÞÞÞßßßàáàáááäääæææéééêêêëëëíííðððñññõõõÿÿÿ8Î tRNS#ADIOÃØç 0?bKGD37Õ|^‹IDATÓU× D±ÌÕÅ’hìÛÿœaÀì{æÎœ…1€5cÈu£u"Ð>ñB¸Î¡T@ˆº+)¤ON"×ç¹V"Ê&Ÿë7Y‰¶›Ã»­³õrµõ¢u‘ßlYõ“µ˜ž.ÕàoÆ®<Úg+,…›Ñ9ߣô·§=Öï A ÙÏxÙ`IEND®B`‚eric-6.0.8/eric/icons/default/breakpoints.png0000644000175000017500000000225112342633754020244 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<vPLTEÿÿÿ@3+trrec^`c©°Ž¹--‹ÂJJ†Ìeen‚¥ ž ¥ª«±³Ñww~ œ z u dl q k l t €2!‡=,‰@0j j ¥¬¯°²²¸¸½½½¾¾¿ÀÂÃà ÄÆ'%ËÎzxÏa^ÒÓa_ÔÔsrÔzxÕÕˆ†ÕŠˆÖÖÖÖÖUS×××× × ×|zØØØ Ø1-Ø30ØrpÙÙ ÙnmÚÚÚ1-Ú}|ÛÛƒ‚ÜÜcbÜ›šÝÝOKÝ}|݉ˆÞÞÞQNßßXVßqpß{zßžà.)àsqà}|à᫪≈⌋ㆅ㈇ä@=äomäzyåwtå~{å‚€åŽåœœå®­æKIæ[Yæ…„æŒ‰ææššçQN炀瑑皚è€è~éqpé}|銉锔麺éÀÀêfcꉈêŒêê–•ê——ê™™êꢡëljë룣ì€ì››ì  ì¤¤íusížží¡¡íÇÇ簾着ﳳð®­ð¸¸ñ©©ñ­«ñ²±ó±±õÒÒöÍÌöÏÎöÕÕ÷ÑÐ÷ÖÖøØØùÙÙùääúÚÚúããúæåûææüêêýôôýõõþøøþùùþüüÿÿÿÂx0tRNS9:;GHIJKÕØÛåééëëìííîîîîîîîïïðòóôøúúúúúúûü¨ò÷iIDATÓc`ÀYÙÀ€•Y”™_HDLALD€I”C~ýñ£GÜ7[Žƒ!*;kï®­V-žÜQ#gâ”îܶníÊ…3'µ×UgKr2mãT*_¾hûêùófôliÈËð“âÙË"èÛß·ùÂÙ+¦ï¼x¬,ÉËU(Ì*œ_[òâÅ3s÷\¼xqI–‡·0+HX4­ªyÊ©‹ÏEwt—GŠ‚…%âK›–N;¼¸iΚe•n`aESç¸Æ®@Ñó-*¢]ÌÁÂʆvî¡­ ÅOÇ&'¸Û*ƒ…UŒü§ÅzÅSBìU@Â,âN»/^l+ôá»'fí/JN°Pç#·†yTXJfNAN`J²µ&74Pxô,’Ó333Ó“môx™`AÈÄ«o“˜˜ã¨ÏÇ„p&^U-m]m5dQ\‘†An{³èÛéIEND®B`‚eric-6.0.8/eric/icons/default/opera.png0000644000175000017500000000555012342633755017037 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœtIMEÛ (VIâbKGDÿÿÿ ½§“ èIDAThÞí™{ŒõuÇ?gæÞ½»÷®×6ë]Û˜W)”‡q0?"‘Ò’òP$@ ‘P (…&M QTª˜@y„$ŠE„DI ‰ªn«6OµÁv‘*„²µ±€ñîzïî½wf~sgÎé3³{÷îûkPóGGÍof÷žs¾çœß÷wÎïoÀe÷Ü7ç›ÞýüÑ^úÄ“ËùýÇ^ÝòºøÅ/6Jµö.KÚo—fpšÅñÑÔG <_)û£Ôú_Àã7Û)ï¿|ïÿ)ûÁŽkÖ·¯ÂìÖhœÂø8L5ÁR0ÃLÌ5À`U? Bm”4}¿ôm;Tºécñ @ï¼ ®ùÞ©o%}jç/n¶©ÆÕ4›LNªf ’‹7…TÑ4ÅT‘T1M V@­Kÿ)•¾êßpý¯Ú½‘ò׿öúH·ÿ¶Oeãï=ú9 ‚[9|¸Fƒ©¡`f‚)žø$.äµû©b kV3|ü&zûª¤í6¨åRÃ+—`xØIo廥O~â÷W7SùòCÇ ù»m”îÜFºýžµ¬zœúä>l&¨ ™õˆ™%Îñ»göÈ3ÿñïÚl'“Àƒž>ß[}úY[üÍgŸc•JS• D~'‰18(²npDþþâÊWÚ_w==ßzxå’OÝFé‹ÛIïúÂFVü”ññ­Öl"YN›N{³Gö«OÊK{÷½”Àƒ-øùìè‡M5¸ 78<ü¶ ÿìÏ­V«‰¥†™"f˜hjT*"ëPŸ¸ªçߨí>p5•<¶|í[þšò—$>óm=Þ ×pxìD¢(ó™ñ–ï{>¿þ—§ø¯ß½¸'†+>ç“y/ ÷·NZwéÅqÉŒ÷³‰^8ÃðDdÆPG^:§wçÎÂK.£ïŸžZ~¡õ^ù–[vÛTc+AË)Œ.@x‡¼Ì;wN—ÜO/&ó>8¹~sþ™glØ|ê¤i‚™vƒ1@dÆQÙ»¹úËŸ½¶»8€ðÝïÉRèò÷ŸiIr¥6¦Ì\”y)÷”ãÈ‘„!GŽ`°à†%¬)ÿóX½Ñ ™NhÚûà¢,•ÂÐhCÓϸ qÒI³ä•f­¶¡ËÊßÛN£ ÉÌ¢cÓœ­ùXIã¶5 þm9ËÿæÌsûƒØµ\ÔJå2¨aÌÐ2jÅäÂ)÷Ü\ï-=¸êÀö‚¨ýë?¼óâÇç[Ð2uN4vYx‹;rX¡.&‰" \pàáex.SµSÝ„áLÞG1åéÏDÃâ ZÃrÜðEݲJs‹žô«HÓŽ•2ã|錄*í0 IÓ×yWÕ‰~¾’—ÀÇÒT{àÄgFZä{ÇîÔ¡í‚,”¦*–AièRL°¢}<–†ÜÀu¤PgÒÝ¸Ž’j.€DÕL(ÚÚÙ 0_h96ÅJåÎèÎwÍ3Ag³’-À™¥ † Ú‘ïÚ¢“£ÅxŠ—é ]éÚ9².±´…³q…uÖíñ.ŠÓ\š€/+Ä‘ÿ–Hµ›.»™'ó¼!{‰€:O9˜ ëèòÆ| *²HY~”ôé0UŒ£<ãЪU® ‚¹b³PŒ…³»ó¯3œ…_2Ô’øˆBÕ"ÓY‘.tÌJY3<Á$ú æ¯F·™ˆÛ©=›á̈ògqßcÕé¿—a@º˜a‰éSò`Š™©âT³qþÞ=n«=;IÚZ´˜k‰î*%ÄBŸtsq§—(‰gfåÇË— @`0Îç@']jGÔAŸ`²ëMÜâ<ýe5aÂyTç0A1£WdÈ7+­ –èéuU\—s´K—‚õÍ ôgGí‰/«7Ãö¨¥F¨j³Â8OXÓlôä+–aùOò½ƒœ2‘Ë sùa·®l,fì»Ýl×’šúºèqVd‰S5—çgq U  .ÇõïË–Óa'¬ T ÓtZ¦S%Îç[bF à1†~`ÛÑì¨V¹¶6[¦w¨2ã³9Þ U ²p_ðK0þ§3ŠßDf–æeƒv-’€U€Û}W¾qpTWäüÚRûj¢:«J'K„])4‘ýìÜpÜ{—²Mß±ËÒÌ —‚æ¹¥ÁòÍŒmKÝØøH;uª_”4TµPu:O£Žª’ŠP‚Ï,ÅûïÍ"u)°q¢¨Ìç;@+½x¼ˆ=¿mG-¾"þ£ \]ÏöÒe¾~ul Ô§àœ+aßQ°Þ*ìiˆœñ¬ÙPAˆRãUÓúH¢¿}‚ä'ûàç@ò)ÒZ ˆeE ± X oî‡S7!o9Î:OüSN¯¯ôˆP.zí¬× ™&{,Ý¿ žßí‚à€?9©µXâvå±öã=@X æÀÖ ›ÖÁP/¬G`ô98Ãhnä‘Üà[%óîÿ¯?úëË·T[9ÔIEND®B`‚eric-6.0.8/eric/icons/default/cameraPhoto.png0000644000175000017500000000123412342633754020165 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿÉÉÉ€€€ÊÊÊQQQtttxxxzzz€€€‚‚‚ƒƒƒˆˆˆ˜˜˜œœœžžžŸŸŸ¡¡¡¦¦¦ªªª«««­­­°°°±±±²²²³³³´´´µµµ¹¹¹ººº»»»¼¼¼½½½¾¾¾¿¿¿ÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÓÓÓÕÕÕÖÖÖØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝßßßàààáááâââãããäääåååæææçççèèèéééëëëìììíííîîîïïïðððñññòòòóóóôôôöööùùùúúúûûûüüüÞαotRNSàììA¤‰ðIDATµÁËNÂ@àÿÌœv*XCP"ñ–ƒ‰á£û,¼%.j\h+Ð±Ì sìÒ°çû°C„ÝUw‚úÛî7Œiu9L tlüûWþRGй‡#  š4&“¹ŽíÛËD<4Ä*+ŠŠpš?¯ÏWmïk©c$ý!Róñ,¯óÙxA‰R‘Ѻ¥[j$fÏETÙ×N÷Kt`ÝûÞ‡ÈÁ;fK?À£ÓÇ‘0)Úßšˆ/D ™º¬µî¸Ùxî]9[®ÖT…YP™tš,Ê`Û:`‡þág;–ɬêIEND®B`‚eric-6.0.8/eric/icons/default/actionsToolButton.png0000644000175000017500000000260512342633753021417 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<IDAT8Ë•{LSWÇþ÷ø‡Éæ65¸¸¨K¨ÌdËÄ(ƒaZÝÂ&B@TSÁ1ÅAfµ8:†A2Š”0`iyZ,Êk€  ȣ*¯R (¥´—ö·ß!l!'ùæÞß½ç÷¹çœßãÚ€ÍzÂñ—÷gQÑ£ã¸Ú›ÖõY² µ3*êJdxøÅ@¼ßŒ::=­3á{HLdßBÛµïÞ½Ìßñz€ÌÙø]©´Ab6S0:ªÒ íæì|àûÑÑÉ%0‡“ÎÅg‡ K -0=­Õ£ýÙFÀ»}}~1Œ`2Q077o&!"ŠZ£ÑdÑëç‰]UUß>îk‚q|¼}ûîäöîÝ644fDÌÌ衽½‚ÈÊʃ§Op'JƒanÝâðÐÇupÇŽ]_àõÿÁ8>|ð °lnÎh©«kn›œÔpEðìÙ ¸téE@pðy`2Ï/Ý3™çƒF3z½ÁZU%­Ç#1ŒŒ(uÈòX >ÖÙ)ŸP«gÈÖA«ÕƒDR11ñg=qÂwÁÓÓÛâîÎ0yy²„„\X¸r%RRÒajJ‹>Fô™¥rÚræÌÙÛdÕÿiöö[~ÌδLL¨a`à5$'§AllE§79òUò¶m;ßÇy[\\>÷ñôüúµ¿?sÍNêêZ >ííò™C‡Ü~Ã9þ+WLRÌ5##§fxXO == Nžô£ÜÜè>«ØÖËëäðõë,3æ7(cxl½ä‚ÉÇ—çØìNH¸Y—'=Þ§éï†Ç%””Jùø|÷l­ðö>åa.-­>±öÆö+¡l6ç,‹•D  RM#T,Vz?2®¾] _òùù]Ý݃”H$…û÷ allb©„++Ÿ˜Yj‹]Îf'ga ÿIKË fgõVò¾¨¨ D" ÔÕ=Çõji´O“W‚Ã9œ¿äBa-žm™º¤¤Æüða9Œ«–V>??Q¤:::©©)µö3 ÈÏOŠÅMÖ’’Úù]»œxKÝo¼ßÁa+Ï×7HjkkÇ¥Ó½Ë%’FJ (…¶¶ÜîFd±X@§›ÁR@yy%6 Z’ïvvv\í ÀÃñYçÞnBGP!¤¿:88òe²¶¹žžAÉš°º$ Wâ±T#¬Ÿ5@WW¼|ùÂÂ"ê–‚ecó-ê4jëZmÓ=..¾].W`â÷¼½Wß½{·K©TšU*öÉHhhh—Ý÷æÍ~¤YK²j#ýØÙÑÑQtçÎò€€ †åôáËåòYN C‚v™#І]]W£ýÓFMGQËy¹•š››«J¥4­j9÷ýQ$PçPë‚×ø™’^ˆ*BÅ ìÖóù.›kÊ(wHIEND®B`‚eric-6.0.8/eric/icons/default/ircOp.png0000644000175000017500000000145012342633755017000 0ustar piotrpiotr‰PNG  IHDR(-SsRGB®Îé pHYs»»:ìãâtIMEØ)¬ª`ܧPLTE€ÿÿUUUII$]P$i"dYC\%t]M]rPtaO<5_sNs_NO’K:kIP–L<‹63kD«œ‹ŒvaŒ~m‘zc™ƒlž‰rVXH”;\™^½¬›[˜[¥Šp«“~e f´Ÿˆb”go­fY˜[´–{^_°“z¤·”´šXšYmµeT¼Ieh­Žr¬½—L•=¾¢ˆÄ¥`«U£déѼj m n s v"r"r%u&y'+{,‡-|-|/†1 2€"3#4%8…'9„)9…(:(:“-<¨+?‰.AŒ1CŽ2C¥8E¹7I8L›>L¤@M¢O­@Q’HQ—@S¡BT™CU«JX£KX¤H[™M_ºRb®Ve©Vi–Xl¡^kPpSšx]¢€g¢…m¥†j²‘w²–y³–y·¡„¸™€¹Ÿƒ»•q½™tĦŽÌ®“罓蹊迗还ëÒ¹ì”íÈœïØÁðÓ·ñÔ·ñÖ¼òΧòѪòÜÆóÜÃóÞÊôÚ¿ôÜÃôãÏÿÿÿM4P7tRNS '(456ACH_cgpwz{Ž¢¤ÁÅÎÐÓØÜÝàãæçèêìíïïóô÷úûüýþþþðÞ bKGDŒl ÒC·IDATÓc`Q}S5NàËÎÌ)7bBÈ—æçs#4*Û;*ÄZÕÍmݵÉš¦Î.3v„³q}K«’- UuebȲ%Yy"H|^ƒ†‚"M.F(WP'51#=96M…ÌJIŠ ðò K0á èFÅy»;»xøGJù¬!þnŽv6¶öNž¾†@6½ðh+ ssKk×e°!Â2ŠêÚªrR,@¨&:Í%˜oIEND®B`‚eric-6.0.8/eric/icons/default/breakpointToggle.png0000644000175000017500000000252112342633754021223 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ ¾5SftEXtCommentCreated with The GIMPïd%nôPLTE"-=@3#9#:4[ 9trrec^`$;"3M,Ho;]{e|ž,De2Y©.Hn°Ž¹--‹ÂJJ†Ìeen‚¥ ž ¥ª«±³Ñww~ œ Nj’z u dq I %k t 2!€2!‡=,‰@0j 0Mw=Fij p»w—Ä8Z‹@^‹DJmLp¥M5PMc†Om–On–Qu§R\~V{°Wk‘X}²Y}°Zyž[z\~£\¶]~¢_} a§a…´a†µg';g†«hˆ¯hŒÂhÃi~«i€­j‹°m´n‘µq®q®|ŸÓ}H`~œ¶~¢Õœ¶•!/•³Ê𠛥¥¦!¬¯°²¸½½ÀÃà ÄÆ'%ÌxÌÇÖÍÖãÎzxÏa^ÒÓa_ÔsrÔzxÕÕˆ†ÕŠˆÖÖÖUS××× × ×|zØØ Ø30ØrpÙÙÙ ÙnmÚÚÚ}|ÛÛƒ‚ÜÜcbÜ›šÝÝ}|݉ˆÞßßXVßqpß{zßžàsqà}|à᫪≈⌋ㆅ㈇ä@=äomäzyå~{å‚€åŽåœœå®­æKIæ[Yæ…„æŒ‰ææššç‚€ç‘‘çššè€è~éqpé}|銉锔麺éÀÀêfcꉈêŒêê–•ê——ê™™êꢡëljë룣ì€ì››ì  ì¤¤íusížží¡¡íÇÇ簾着ﳳð®­ð¸¸ñ©©ñ­«ñ²±ó±±õÒÒöÏÎöÕÕ÷ÖÖøØØùÙÙùääúÚÚúããúæåûææýôôýõõþøøþùùþüüÿÿÿÃx)4AtRNS .9:;GHIJR{Œ¥«¬¼ÕØØÛåééëëìííîîîîîîîïïððòóøùúúúúúúûüüüýýþî0“bKGDû¢j6ÜmIDAT•Á½nÓP€á÷ûŽ[;?$M(©¨R5¡JA°!&&.n†kà;—ÀÆÈ@‚ˆ¶ÂjÒ¤víÄ?Ç>Ðçá¿—LÐñT›ËÚžg˜öþa|¾˜ŸMßLÚ†ß `Ã×óUÏâoW•ÚÚ~v#ͳ4I–Y}ï}aižŽ“nžÖU¶&vï°(P¼îãAØìJÓÝÞ~¸^Ú']PD‡‹xS¼I:¾Fó–ïÖ4«¼ƒ‚µ;}8 ý ¥ `rëzï2 îîF8òNf@sl1[(ÓdkãC¢ô¦3[¬’òÛ…5àÊ4ߨTÁsáz§¡£pÅEyů\Õ•³¾ÿiƒpI»#OE\]µäsdAø‹ßÑ(ãŸ~ ¾¢J½WÖ‘IEND®B`‚eric-6.0.8/eric/icons/default/preferences-highlighter-association.png0000644000175000017500000000230712342633755025035 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¯¯^‘tIME× ¡‚ë}¬PLTE~~~ŒŒŒˆˆˆ‰‰‰•••–––zzzvvvvvvhhh„„„²²²¼½½ÃÃÃËËËÌÌÌÎÎÎÇÈÈÖ×רÙÙÚÛÛÛÜÜÜÝÝÝÝÝÂÂÂÎÏÏÏÏÑÑÒÒÒÓÓÕÕÖ×ØØØÙÙÙÙÙÚÚÚÍÍÍ×××ÚÚÚÜÜÜÝÝÝÙÙÙÃÃÃÎÎÎÝÝÝàààãˆ3ã«tä‘AãäääåååååââââââåååëëëìììíííÏÏÏ×»»ÍÎÎàáá ?»?°KÖNÏNÅ!XÖ&Hš(e­*H™,i°2X¤3Qœ3i°4`Ÿ8bª:lÝ>Qš@lÐDl¯Fh«Gr×L†ÂQ1bR•ËUÒY”ËZq°^v§_•Êew°e…¾eŠÝjƒ²y™ã~¾…‘¿…”À†´Û‡¤Î‰fˆ‰¿â›Ã”Âä•®Ó–›Áš¤È¡³Ý¥¯Ï¨Ã㩷תÙ󬮼ܳU2ºÚï¾¾–qÀ‚ƒÀÇÓÂÛìÂàêÃÛçÅÅÅÅÙßÇÈÌÈÍÔÉÈÊÉÉÉËÍ×ËÍÜÌÊËÌÔæÏÌÌÏ׿ÐÓ×Ñ””Ó”jÓÓÓÓÕàÕÉÉÕÕÕ×ÕÜÙÙÑÑÙÙÙÚÎÎÛÛÛÝÝÝÞÞÞÞßàêàààààâéàèòáááâרâãããããäääæççç˜çççè««èèèèéééêêêêëììííí–›íííï‘‘ïïïïðððððñññò¥xòóóóôôôôôôõõõõõõõööˆ6ö¨sö´ŠöÀŒö÷÷÷‹5÷»Œ÷÷ø÷øúø6øôôøøøùŽ4ùùùúШúúúû‘3û²oûÁˆûûûü”3ü—6ü´oü·süüüýš:ý?ý¹xý»|ýýýþþþÿÿÿ&jÀHtRNS 0255;;?BGIPz{|ªªª­­­­­­­³µµµµµµµµµ¶¶¶¶¶·¾ÂÂÂÄÄÄ××רâââââñòôô?¸[bKGDã±®ŠMIDATÓc```„À(!'¯ ¨¤¬,‰"Á¤ºeZyVéÒýúL(Âê½ÅE‰QI‹ P…5rꪃ² Q…Õ‚s âýÃRYY€f“fDHJlhS»µ­-/LX«Ä/­"cåÖ{öí?pP&¬}º0:/yã®þšÊÃçÏ Â„u.žY6±sM¦·o@ãäspaÝËw^Ÿ³=ÆË3®º~'pʏ@ts¤‡O~íÞcGœ¼pÅ‚ª‡owzxY×”Sg¯Þ¸y÷žL˜û‰Žî¶†ã—®Ýº}ÿ%\xÏå;ÍXµ|ÉÂy‡®›Ã„yìœÜVÍœÔ7aù3˜03°Ë®nnY1wúlSf” —^ÝÚ¾vÓâY&¨ÂRëæOݶc½«0jDÉœ¿¾yá|1Ôd702ÔSB‹VF& 4Ûq‘ÑTt‘IEND®B`‚eric-6.0.8/eric/icons/default/LICENSE.oxygen0000644000175000017500000000377512060166055017536 0ustar piotrpiotrThe Oxygen Icon Theme Copyright (C) 2007 David Vignoni Copyright (C) 2007 Johann Ollivier Lapeyre Copyright (C) 2007 Kenneth Wimer Copyright (C) 2007 Nuno Fernades Pinheiro Copyright (C) 2007 Riccardo Iaconelli Copyright (C) 2007 David Miller and others This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library. If not, see . Clarification: The GNU Lesser General Public License or LGPL is written for software libraries in the first place. We expressly want the LGPL to be valid for this artwork library too. KDE Oxygen theme icons is a special kind of software library, it is an artwork library, it's elements can be used in a Graphical User Interface, or GUI. Source code, for this library means: - where they exist, SVG; - otherwise, if applicable, the multi-layered formats xcf or psd, or otherwise png. The LGPL in some sections obliges you to make the files carry notices. With images this is in some cases impossible or hardly useful. With this library a notice is placed at a prominent place in the directory containing the elements. You may follow this practice. The exception in section 5 of the GNU Lesser General Public License covers the use of elements of this art library in a GUI. kde-artists [at] kde.org eric-6.0.8/eric/icons/default/preferences-html5.png0000644000175000017500000000234312342633755021256 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<`IDAT8˵UÍO\UÿÝ÷Þ̼ù°„”26Q#¸-ƒ+”JÔhcHHl;BÁN¢+Ò­‰F‰ \˜Æîl‘Æ•…Ä.TX¡ ìZhTHiI¡Úe”™÷®çœ÷f†?@çåp/÷Ýû»çã÷;Oi­ÑÐô\€ÂóÓ¿^ŸÉ©W:MØvèU¥ D"a„ílÛƒ¡ ‚A²@–eÁ0 (2íº`‡ÇCób±ˆ••»¸¿ºŠíDc±ŸÕ“‰g³tK2M™i™•¹o \™WÖù—ά`cýýœ<ÆUöŸ< ?GïµÊ{Ù³çýæÖyú …”iÃåfXrj<WŸ|øÂa›<õ½2L2*pŠ ÃK¿RJÂOg2¸víº¤À+.'8bþ—EX=ò¨YW_R* 2•Œ ¤œÇuÏ屺¶ŽEKK›¼‡ò«Nóªª}8°?6F¾‚åjG;EÚ¤ð\Mà\Í^ºâ {Å–#бÑQdÿÊâĉ^Ô‹ƒ1Q]]}Åè,UÃrŠ®æƒ†æðµTYk.tQ.Ÿ£Í os¸rå'´¶µÉE‘Hă¥Hc±(bшV£èžË!Ròwww…*ÛÛÛâ]:ÁððE  ½˜vKK7‘hj¹sŸÑúGX^^F”.pWòÏxœ‹A¸º¦ÏÑL:±±ËøqjJ(ÖÿÖÛº°ð›”è^\XÀÅ _`vvoôõáµ£GQ÷xDÈGdq~ø A“ ´yôò×’¯îîœLB ƒ 8?7‡§do*•BWW¾ÇääÆi<žLb`à´0DRË™gÂH]7nÌ ;z{ûpæÌ;x8/«oqqO:DaeoíZ¼ÙßÎÎNd³YLOO{Äó9Î U 9°pöìûx¾£çÏŽ#G^Æ¥K#”¯"$0«æË‘a¼ôâ B{{;?Årú˜ž8ÖsjóæÒ-}{ù޾ó{ZgVîêï¾ÿA“'š<Ó¯wwëLfE×ÔÔh*¨ÞÚÚÖ'S)M²gbrR?x°¡×Ö×õêêšþóÞ}}úÝ´HÚ0Lᯈ„¬¹¹­­-˜™ÁÜÜ<®^F]]=âñZ¡XS"ªÁáÃíÄ-âQ.‰ˆDmøì¶JR•Gyføjk£;(5CCŸ"‘h,7á¹CSÊ•Â;JKŽK©4!_ï¥Æ##{C“ÉãÒ …¢ß´»²·4–»™œµ¼9+ ¯‰è^§£fEc}ý²Î]¬ì†¹(ZR¢ýËÄãÍ¿7¹ "Kù‘S.õ iH|Ð0*)òÃÔ¾g{Û©\B–Ïç±EêåFÿ ½O†ˆ¯¶mӗÖ‡E®üUáõP(äQ‰°Y²,‚·ƒbçYËç vL©ÿí›ÇÀ&—›Áí=Þ3–æ¼/O–#ûÇ·]äµ^üzY$b’ÙIEND®B`‚eric-6.0.8/eric/icons/default/wordboundary.png0000644000175000017500000000021212342633755020436 0ustar piotrpiotr‰PNG  IHDR&¾ƒ PLTEžÿÿÿ;f·tRNS@æØf,IDAT×c` „ h­b`euÐÿÇÀÂ"E $+)**$€ê1× 4Í»ÉIEND®B`‚eric-6.0.8/eric/icons/default/securityHigh32.png0000644000175000017500000000317012342633755020541 0ustar piotrpiotr‰PNG  IHDR szzôsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<õIDATXÃå— L•eÇß{)¼:*‘̘5?#–nnb4SˬÓÑœ¨)"‚ò¡H \.Á%ñÊÇ…àWB" ¨WDD RPÓA((!¢ðï<¼OÔè%µÖz¶ßîÝûqÎÿ9ÏyÎs^€ðo"ü§Ð2þQ4$ÄH˜À1ä×$/T— ³¬ì¬ã­­·{hôõöö¢½½½çXŽ6ŸÝcÏT©¶§ñhŒxš¡ë£S'g'¬ìC7¾q-·š‘\šŒ1Š1„"ŠP 0 5ÅþóûÑÜÜ„Ÿ.×ã@ÚMŽŽŽ™ nKO'Lµ…¿Ü?)+;³µ®¾¶ïÚõFÔ6Ôà‹8[H6I „’Ó"•H#öá$~Ø&Ø¢¬ªå8[\Ô·/IÓæåí•F6ßa¶Ÿ(€'ÙôÌÌôßjëªq©¾ù¥'à· ÆžÆ6 ¢ó8"…È&rˆCÄ>?†>†X½ ´©ÈËË…6ç(ÔêÈûÌöãI:˜€"Õ;ÚòOåÂÚë=H—I!8“a"„ˆæ3ÎàÎOÇx$ö;ˆb½é*)&»¿‹ï”p^ëtÙ~š¶ö–ò ÿkÇóŽâu+ɘÈÇóÐ!NEü7[6&žòcýßJ|-`ôW£!WøÃaåŠffûñ\,ëÇnðp«b¦l˜üç새H"‘Ïþw~Ž($²„U„áæ½›;‚\ŒÂD— oŻŗ™íÇwÅ`IøšýŠ¥L€b„5 ¿Š¯µ–8C”åb‚/ãá‘ãÑŸ LÀtO+ølÍg%̶.»À`îÜ9I9'ŽÀ%ÚY@ɧ¨‡ÝvÃ:ÙZ\û¢JŒB@YÀ€så9eÿŽè_2w |çc‹ßf̘ñ>« º5nÜ8ï´ô”^Uò6NdÈ›œäˆN:z:`•j%ξX€o¡ï€óí¥Û!hèzŒ . X£X O¯ }fff›™m]°`-Wø]ÏÍ×â-Ÿ7!xR2)Fã|óù~GmÚ05i*¼ó½œG–EBÈ$§ µ¸ߨ<ßÊáà`ÿ ³9Ø91T%4žo3/#7O‹5ñN<„þÊg¬2Få­Ê~‡;œÇ–ÄŠËr†ï–+ßøŽy2Î –ß(*>÷7±ºóY& bÒeó2¼‹¯=‰´³‡jGV;9¶0OjRžÖ[ZZDdfì-*=Oã?ë¼R<ýú·[,J˜X-?Šû± Ѭúõ™[˜Ç •|º x‰˜²v­SeqI!rJ´x[5IÄ«£’G…f>1|"4‰PǨYé­cï2ÏÔ’±â!“ɾ  jý±¼™e˜•0 ‚?/6œ™;gB“«ÁÁôpswm§w+<G; ŒŒŒ6FE‡wÖÔ^De]ÔQpÍpźÌuˆ:…âò³8YO™¯¼OÏú°wté ‡Ó”šÒ i¯®©Â•†Ë¬ÿCccêê/¡´¬JeH'•\oÃ$ϵ-ç"ŒˆÅvKí.îIÜ}¿èlaoQQa¯fob·½ýòKìFò¢¾ ˜1ž°%‚9¶üšl¸'ÏòI¦Ï»ÝQü¿ôÿ÷qú<ø3Ã|h ¿)‰IEND®B`‚eric-6.0.8/eric/icons/default/unittest.png0000644000175000017500000000213612342633755017605 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ,w)ÞtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ÂIDAT8ËíÒKkœuðçü/ïm&sk’ikÛ¤J/Ѫ¥`…zEhE]¸7îu¥(¸PpáJ?€ úüV·êBZ„h›¤šÒÉLÒI&3ï;ïå9.Bã­®Ág}ÎÃáþk¡¿øìÓO µz¥*˧²,keÙ´*J묗ÖZºöáGï¿ `ø»{ê^è[—º4é¯IRob74«ñ˜ó’­£™If4a† ýǰP:Ø]ùêPÒM6î„å¤]¥©²YG ±¾)ëG­ãÏL¼÷¾'üÎåEAÀÁ _{q!ŽÎŸ<\Í•E¦~–ÓBÊÊPsíº;YèÜ´Äfe‘:f{–†¾ûÒ B†BÈ·Ÿ;W¾pêHz¸A–;lÖ:PSj&”•¾;UZÿMe1tŒò/áמ'g‹š@ñÐÒBöúé£ùÄD Ñ„°¹C0Fb&$ e¢U²Ü3&+ù¶g쨰ø#¬•“Jú¶îâ©ûò…Vb"0h<% Ç„”æ@e‘”âÄ|ëèg5ÕÉz(Z‚ßýøÍ‹Ý@z6ŒÔBù3Ò.vÛ®QVi€I®1œJÏÈrcxùô±8¨šqh”Ò=IŸÑÄB¸1 ¨?ŽRСÓô(M…‘E@G í0ºµãž°MÔ<£³<(öà$Q—gbnÎ5íÑ.ÏKÓ 5ÅÃ1a+«C@'±H4PÕ€º ¬ZÞžw8ÜИ¯«ûgkªé=7—ÅÇ êuýêLÌÑ\ËÏ7¢¼;„ÆÍ¾@Јp¼›c>Î!,£ÔM¡“B>uX\X 0[“A;‘‡J‹ÄÞÅâlc)‰Ì\¤rLK`{\áFÑ©;´†à½6#'Ñ5;!úc‹Í‰3Њfk²µ__ìþtk8вw›Œ/¯~¸Í`À9½;£ÀNX"-=®ÜHQX†ēқýV¬Š÷¶vÜáÈ¿~K>½8‡öóg>ÿÚÃZ‚µ2ÖÖ(X#a­€±Œ´p¸´Ô€$àZ/ÏÖ†Õò¯ðVõE¨}};õ7ú#^]éó£•ác«ß¼òݸµÚq:`K®"˜ ¨*‡4'^ß¶nTøñ·ëÓ‘ §îæÆØþ–=%¡"ÍÛâ¾ üX>^>pu-oîp /¼%rÖ“µYL¬MK?þ~#ß%`£t¼>­¸‡ÿó¯äÑ·ùÿ•«4IEND®B`‚eric-6.0.8/eric/icons/default/taskNext.png0000644000175000017500000000232512342633755017527 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ6Ï&±žtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“9IDAT8Ë••]lUÇwæîNw·»K±tÛB)µÛm‹¶P!QÑ(‚@$J€ƒáÁåU¥$Vä…ˆ}5&ÄGb¬"Z¿ž ¡ A–BwS>6m¤Û¯ÝîÌî̽>li´m°žäŸIνùÍ=sþs.ÌmìÛòá–1vðÞ?Ór—ü¾í¶kìf9‹c^¦ÀÁÖÚÖ%[;¶žä5ΰ à÷û‡^?Ô¾"²âwv°éÿƒ È{yÚ×´‹=›ö¼X¸Ìn–k­uÁWàÈÁ#‰Žós+šæ¼LûÛmqG9£Aâ ñXúAúP¡X°ÚW·]ኖD‹i kK2”l¢’î¢nM´Æ³NG;àC464lÏVUUa»6Žë«Ž‰ºªºöÔ_©n«ÛßL=œ`¢)ÏLgppp„CAIJše8ÊÁñJ²‹6VÈ¢aEC,=œ>h7ØWè'õHp<OãNIbF88ÚÁöìÒKŠZh±²fe`j:ûFvÕÔ47¸”:>§y¢hÉ3˜®‰é™˜ÊDjYz"11‘ž,­¹&ҕ≦ÕRšò“»{ï­çŽ:0Œ``ìyÇ0Ò˜¦‰)L¤’H$RI„+0éHQ[QCØ ï°]L*ĸ8¯o¹»8Caž´Ö,$¥=ý_sôÇ£|s³¥¸‹è¥é*ŒèÒÇÜí AäCH©>f¼¥ùòú>¸ð>kc|º£4˜ž‰o$>Àqï«GM·X+zSçxyÕ6zSç8yõ#^ª{‘Î ]m ÑHmFïN¬á„—ú¯y,”Rüzç®ç®ð˸ž½ÌºÊu{¶‹šP-Z—ª© ®à„Zô "þ$Íá’ê"ÍáfNoþœêP ZkŠÅ"¹\ŽB¡0Ê"C>l–Á»k;¹þ‰ µ›10fOjÛ6CCC©‘‘‘Ï N¥R¿ÍÚKkž²^Àu¹Ç½ÙMŽãŒÝ¿¿{bb¢g±à¿aaóù!øŒ3IEND®B`‚eric-6.0.8/eric/icons/default/pluginInstall.png0000644000175000017500000000244512342633755020556 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ,Ž][ütEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“‰IDAT8Ë•MlUÇÿwfÞô½¾––¶ôµ…ÒÖP>šb¥EÑb 1¨D 1  eaˆ‰&&,Œº€D7¬ŒÆM%u!MV%©)ŸöƒÖ–¾¯¾7ïÍÜ™¹ÇÅ{-maA¸É?çΙÜßýçž;g`èØñ-{öÕF››rAʽžtDêo÷\šÀÃŽƒ¿öº”Ö?CãÎ]ÏݤÁ™AýÞ¹WÝ×Ù’¸ßë¸,Ò^G¸,ãgàI\úHúI6Uœ­¤¼l0û@à×~~¬OI",Є6h=u)}a}ÜÞepéKŽksÿ!]GÚlûË?ôÔ!Ä?{௶ºÿÇž£;yåĆ•=•CM´^×WÔsa\yð‡Ò¦­ Ëœ`ŽÂ<âFöо“œ|f¹cº³kU­_ÑŸâðWž‘ SàÒWæó¾Ïù|âàÚƒ‰§µ÷…Pˆš`(Ê<¸â/ƒÊ€…¹_r¯9|ÍŸ8¡6îkT2ƒà*ç.L/–‡€J}šö"€ajxÒPÄÀÏõ÷<ÅÓá³­Ëd®ÊÃס.»ÔíÃ/; ‰#‡`ˆ „T€« à¤!$Jà§¿îþäðãï~9b\t$?8Ý?5c†5­€UDH#*Û·!÷ðÓŠ©–8|IðÅ]²¤öUko°Á"eì`˜Ó_ÚÇŽîu?míŽTÈ‘&ÀnÈÂ+¨nºƒ¾È-y\nk€ÐBBE Òp‡Ð„Œ/ë\©³Ékbùï®{ÃíoÞîw–:† P=_‰÷½‹ëµP<²€±L€[dwY­§§xòŒõ¶]Á: –ªî& pF-¬l QôÔ-%–Þ•7 A J“Çk|I®}ADìÚ3s!˜@vh5LÁó©^}ºê-ä\©—kΕ:[ŽóòB‚$T-éÇ3ý©õ«ô³¹ÏåùºSõ÷wÖõ­9—¦eN ¸÷hæSBç0|ó~?cºÿ°Rì<ýøÅêîzIEND®B`‚eric-6.0.8/eric/icons/default/showPrograms.png0000644000175000017500000000260512342633755020422 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<IDAT8Ë•{LSWÇþ÷ø‡Éæ65¸¸¨K¨ÌdËÄ(ƒaZÝÂ&B@TSÁ1ÅAfµ8:†A2Š”0`iyZ,Êk€  ȣ*¯R (¥´—ö·ß!l!'ùæÞß½ç÷¹çœßãÚ€ÍzÂñ—÷gQÑ£ã¸Ú›ÖõY² µ3*êJdxøÅ@¼ßŒ::=­3á{HLdßBÛµïÞ½Ìßñz€ÌÙø]©´Ab6S0:ªÒ íæì|àûÑÑÉ%0‡“ÎÅg‡ K -0=­Õ£ýÙFÀ»}}~1Œ`2Q077o&!"ŠZ£ÑdÑëç‰]UUß>îk‚q|¼}ûîäöîÝ644fDÌÌ衽½‚ÈÊʃ§Op'JƒanÝâðÐÇupÇŽ]_àõÿÁ8>|ð °lnÎh©«kn›œÔpEðìÙ ¸téE@pðy`2Ï/Ý3™çƒF3z½ÁZU%­Ç#1ŒŒ(uÈòX >ÖÙ)ŸP«gÈÖA«ÕƒDR11ñg=qÂwÁÓÓÛâîÎ0yy²„„\X¸r%RRÒajJ‹>Fô™¥rÚræÌÙÛdÕÿiöö[~ÌδLL¨a`à5$'§AllE§79òUò¶m;ßÇy[\\>÷ñôüúµ¿?sÍNêêZ >ííò™C‡Ü~Ã9þ+WLRÌ5##§fxXO == Nžô£ÜÜè>«ØÖËëäðõë,3æ7(cxl½ä‚ÉÇ—çØìNH¸Y—'=Þ§éï†Ç%””Jùø|÷l­ðö>åa.-­>±öÆö+¡l6ç,‹•D  RM#T,Vz?2®¾] _òùù]Ý݃”H$…û÷ allb©„++Ÿ˜Yj‹]Îf'ga ÿIKË fgõVò¾¨¨ D" ÔÕ=Çõji´O“W‚Ã9œ¿äBa-žm™º¤¤Æüða9Œ«–V>??Q¤:::©©)µö3 ÈÏOŠÅMÖ’’Úù]»œxKÝo¼ßÁa+Ï×7HjkkÇ¥Ó½Ë%’FJ (…¶¶ÜîFd±X@§›ÁR@yy%6 Z’ïvvv\í ÀÃñYçÞnBGP!¤¿:88òe²¶¹žžAÉš°º$ Wâ±T#¬Ÿ5@WW¼|ùÂÂ"ê–‚ecó-ê4jëZmÓ=..¾].W`â÷¼½Wß½{·K©TšU*öÉHhhh—Ý÷æÍ~¤YK²j#ýØÙÑÑQtçÎò€€ †åôáËåòYN C‚v™#І]]W£ýÓFMGQËy¹•š››«J¥4­j9÷ýQ$PçPë‚×ø™’^ˆ*BÅ ìÖóù.›kÊ(wHIEND®B`‚eric-6.0.8/eric/icons/default/openNewTab.png0000644000175000017500000000151612342633755017771 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<†PLTEÿÿÿªÿÍÿÒÕUãUãsãàbð¼ì‡ìˆÔHÑDÉC ?"ÔS æŠæ8¢Aöµ£B ê³ìšì˜ ¼j ñ°$ìªò²*æ¥é•ÈÈÈÓ ÑÑÑùÉ0÷¾ö¾÷À÷¾!çùÉ/ë§&ó»öÁ1øÌBðºñ¹ò¾ó¾ûûûüüüÚ¨”Û¨‰Ý½±ÞÀµßßßàààâââää俥Uæææç¥(è®5èèèéÉ·êêêëëëì§ìììíªíº›íàÚíííîîîïâÜïïïðíëðððñññòññòòòóÔÉóóóô¾ ôÇôÓÂôôôõõõöÝÒöööøÎøååûôíüúíüüüýýýþýýþþþÿÝÿÝÿÞÿßÿà%ÿâÿâSÿã<ÿåTÿçcÿèTÿëuÿëvÿëwÿìqÿð‹ÿñˆÿô›ÿÿÿEqD@tRNS  4589BCKLMfw€€‚ƒ˜™››ÂÃÑÔÖ×ÚÚâãçéëììîïñôôùúûüüýþþ®‘9ÍîIDATÓc```bdae`c@¼ª,ÆBŠÒ¨‚Ì| F꥚Â\œÈÂŒ*¦UU–úÚ"<¢b ÊgÑ(¯®««1“Ô±³Ï{=Y²چúÊbsµ Èg``ÒÊÏ/ÌÏ7‘—Ëu‰—I !ÊV6EEE¶Öº yHÂìJqé%A ©ÁIa×’uênM•y‰~¶ZÌpaáÖîö†Š\ÿ °ÐLe˜(ŸSoW[}iNpxdLt„…D”˸¿§³¥¶(+4*.!>ÖÊ„,¬ÝçnîÚXSVš–žajfŸ­ ’—”–‘•WPTRQUd˜~(”è0OZIEND®B`‚eric-6.0.8/eric/icons/default/configureImport.png0000644000175000017500000000242412342633754021101 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs7\7\ËǤ¹ÆIDAT8Ë•[L#eÇÏ73…2½p] Å°„kR0‘Da/ J|…àƒû@¢‰òßx0†Íâ(h ‘º®FÂ. â B¸–‹–;”¶ só|41 ÝiN¾é×o~s.ÿsJà1®êêjmU$Idö÷öYQ¬VË‹õ‰—ŒFCLˆÙü™(‰ï˲ÂÔÖÖ*äq ‚ hƲ,q»OTƒÁørbbR»íFº@–¨]•••oàqq||œLMMÆØd2A@@¨ªJVWWU¯×—œžž~·¼¼Ìlàõ ‹BB_'„ˆ¿ÌÌßçç!..Náü!88˜ASq«¦´´48$$>|°làù*[æ-¥§§‡¹™‘¡à>¿¿ÿ¿`žçatt&''ú½±±1?11dYŽÓéÞ|ëmQVV¦`TÌÔôô—‡‡‡·¯LENNÄÆÆBJJ `¨Ô˜ððpÂ`0ȱMMMÍxT7==ŵ··ßDé¶×çs’« àt:áôô¸   i}}ÝžŸŸ_Ž‘(ñññÌÚÚ :E¼¢-1 Þ3†_Ë ½½½àr¹´cÑXÜ–wwwŸG~ýº ª¢JT,ÔËbø*ž'v{÷ÁÜÜ£[ÿÉqnn.`H°±±¡yº¹¹©A÷ööžµÙlßJ’dŒŠŠ¢0ØÙÙa!,, :ã[]]yçìLXø¸°°š››!@DXl z¡ßឥ&c‘ØîîîôxÓs£R–––~Z\\üÏ,bÌ?©(**‚††­Úº¿¿ÏbSÈGGGO'''÷y<ž` eÛÚÚ¼ýýý¯:ŽûøBnnnNÚ)xUUUtFÕÀÅÅÅP__O›@ë0„±ççç²ÛíÎIHHèÔ„ÍŠ7AÂG%I^øéRSS5§†åÕ5O(¯3T¿’C***€POëêê49ÑY€ʸ>ã899‰ÈÈÈïÍ›d5Î8—ÕÿUÒÚŸnøðµ‚RŽÎ S{«Ïçc±šý=V:"33SÂŽãÜ—zèá uà²Ë+(ºR‡áj³CgF£Œ…H‹ŒŒìÂEfeeiÐÏ¿²ºƒ_T7öÎÂàŠ±å‘tÞ¿ïZ(„°ÇÉX0ª":--M2›Í\ggçîÀIŽYåP×±®£ËíL#žûèg‘‚9ªEÔ¥¼µµ•Œá;nÅ‘ð\WW—khh¨$ ÷…yã5žø²˜ú@½"h`Ì™²½½f±XP ‘yyy&Ÿ³ÛíÛ###%ѯ¡|ÀIˆðÄYʼnpk`„ÚpÔ}€ÛÉÎξ¦×ëiø›ccc%¸÷æ›3é™Ms haüLo1éÙM Œº}sú^kk«·¥¥åz;<<\€¿­X­V¢Óé¤@Vœ×ëÔ§üe¬zNy¤Q^q¨/¦ÂØÑÑÃÌygffæ÷“hçi]ɧÿÀîÆëPàTn*5ÐV†Þ++þÇÙãÕݥϚššQ¹ËËË+ú׳³³NTH4M5­*_˜taâ¦ù ¶–£*½þ%IEND®B`‚eric-6.0.8/eric/icons/default/vcsGraft.png0000644000175000017500000000156212342633755017507 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs  šœtIMEÛ ýFÐ!iTXtCommentCreated with The GIMPm°—§PLTEÅÅÅÆÆÆ aaagggžhJ………ºs–––ŸŸŸããã\ÐÐР  ¬¬¬Ž)———'×±j “““•••+á– Ë„çççèè躺º”””9D9•••˜˜˜•••——————˜˜˜™™™›››L‡g   ¢¢¢DhMåååæææîîºÎÎÎ  K,ÜŒ;ߟwë³Ìüô}-Ž8ƒ,1 ®OÏq×~»TÛÎiÙw%ß…%á‹,Þˆ-á›1ÝŠ?Ù‡DÚ•FÜžH¿ŽHÞ§L·ƒRÕUÙUÛ§UݯVܨYÛ“ZÜ‘]Ýœaá¸gãªoç¶pæªrè·tª™{š‰|ì¹~îÚí¾…ï¾‘óË’ô옘˜œœœžžžŸŸŸ   ¡¡¡¢¢¢££££÷Ú®®®²²²³³³´´´¶¶¶¸¸¸¹¹¹ººº»»»½½½¾¿¾ÀÀÀÁÁÁÃÃÃÄÄÄÅÅÅÆÆÆÉÉÉÊÊÊÌÌÌÎÎÎÐÐÐÔÔÔÕÕÕ×××ØØØÙÙÙÚÚÚâââäääæææîîîðððÿÿÿñ&ì7tRNS %===\bbdkŠŠ¡¥¨³¸ÆÇÈÐÐÐÝááæèèêëìíííðððøüüüýýþþþþþ´áÁ\bKGDŒl ÒCÔIDATÓc` ?`ä•ÑïÖ—æeBåðë¶wtuvèñ30°IŠÂ9²-m­ÍM² \fšpŽvYUueuU™–T|B–Ni%„à’ZÑP[Weaägäd*3¨§äUçz9ú†„…GF†¹[äVd¨2h$Ö”øX;¸xúz»Úš”Ô¥ª1(¥”gVFÙ›„º9ÙX9éŠ ɹ5ùE•iâbΡ± 0§œAu^±¡<»U¢œÃÀÂ-(,Àà ô#³‚3XúªDÕW RIEND®B`‚eric-6.0.8/eric/icons/default/editUncomment.png0000644000175000017500000000252512342633754020542 0ustar piotrpiotr‰PNG  IHDRÄ´l;IDAT8˵Ó{LÓWðÒÒ-…ZZ ¥€´´ÓQ-ˆ Õ - ‚ ”–Á»Éœ| :PAf– ”¡ · T Õ:p,<¦a(0œÒÅúX‹@(ÔZgeÓd>FäÝää—{òË'÷žïï‡ÄÿQïôRlš–³G{A°©ýB¨¼5Û“e?æ'|Töñ•â(¹rÁ¼á€¸ïˆ)ùªðÕº„}-:Éþ–å‚Ä:ÇŒ õμơñ¤´Zµ,½Î~Þ0?¾ÎCž×“YÚ Ùwî™tÿ9ŸÙå/*U?TߟJÞsB+Û{ÒaÞðêä¦ð¸¬[Í…¿ðã²Ô«6d/léØžRü‡ªäÖ˜aµh[óšèTê¼áàTնȬ‡Ó»~`pÊÝ–IEdjŽJ ‡aÏ¥ñ§®‹ÃÒÙ¼uVï 3ƒ¯¿¿DÔ"Ü?X^0 +ÜŠ+Xšœ'ʸ’)”êGÙ_rö:Áqá•ãç„ßu Ûö™hÓ·Fœ1Þ®XwÀ/{@½*w¸Wtöù ¸~$uSFQþ`O|õ 7¦‘?'Ìð/§ÐVœºè³õ†žŸý‚Jõ ¨™~ápw÷‚Ïá>= áÕÏ@Xô3º€zRË * ›¶en&Y36å2>ÈêfŠ›tžÀËv7OØU»%õ¸‡ÇÁëˆÖè!®Z’s×ÖC|–ê¾Þ{N˜Åb¡p8 ‰DÆPøßw8%ÝÆç÷& q¯©·ƒü“š.zò¯–´ ó¦^ö ‰„w ã¹c§¯¡&Á&þ± kã—L´]Ì$Eë»|×^QW‹ÉÍñbÝ Rq­ææ+^îßü»,ȼÎÈþi6R]/)q‘£4óLšÛ~rM@݈:ÿ8”ùIu 9¥é.ÓRëNOOEÿî]†6,VøLñn Sü¯m¢%)íd#·È[£ÄÍØÆ d¶g©OÀºà VžMÑq8½RòÔÑ«VÑáÉkêÿ,nÆÆBwL´¡…Zñ lÍ.æYs+*Æ÷LR?ÕÁ‚Ô)ÀËÇ©³€Û€ê¡ÀOšoŠ@óeh²³àº bæÁ–-pG$‚Û ´s8—6åKŽba(±-Ù©jëðþ)Ëô€õœ’1ýÀ0Âט (ðO˜`mÊfÉà¡($&B—ûúú(”J%‚J¥Z˜’þ°Fõ/ÌJE—Æå+SïÄò@¬ÔÉ=ÿê/þ|ý TCññðÄTÝ¡¡£x<é¿Ãcm@[PB—7aËo*GYzy#mä á `¼oÀ)Wu×ÙþD"a‡A33PÓéÐìèx¹ám'ž-»Å¹x¢ÛéBùó!«µmS8^UÖù åòm®Åzd9­ž¼Î`@/ j ZÝÝŸjœœ …‚›&¼ÑÑQqþõÿ ó!Î>ó˜íú>ѧì>Î5}—¹SI;ÞÌö;=83×,-¡Ó„688(ª­¬HõvvŠnÚf:½’Í6T½þUÌ–¥ÝNš´-ßÊ«¢Ë‚±½mµ6Äœ’éaFΨÇ,©ú]`å[uÉÝýy½½âì‹kÏ>«)…‚É4T P·Ž"**ÊÌ …Bb±Xº««+šL&ã0Œ«)@@°)Á`|Ë^ÎòŚݗüëÏû æ†ù‹Œ¯TIEND®B`‚eric-6.0.8/eric/icons/default/1rightarrow.png0000644000175000017500000000146312342633753020177 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<›PLTEÿÿÿ€EkxNPj{MRk~MXf}`cQ U a•€ – [ ^lt|e`  „` ‡ ‰ “’™›œœœf(k( |—  i³r‘®œ q!8{8DDJ–JM–M€¼€tƒˆŽ‘“—šœž¢¤¦©«®±³´º»½¿ÂÃÊÒÖQ©a‰q ^ ¤#§#&§&'p'(¤(+›++¡+,’,-¢-/Œ/0£03„34¢47~77 7:œ:=˜=?£?A”AB¥BF‹FF¥FI¤IL£LO OQ§QT©TX«X[«[^«^c®cg±gj³jn´nu¸uy¼y{»{†¹†‡Å‡¢ n?tRNS55<@cemt˜› ¨º¼ÅÆÈÐÒÖæèêëëëëìììííîïïïïñòó÷÷øúýþþþþþþþþþþþþÚšˆà¿IDATÓc`À± ‹Š1cVn—fÃ"¬Ða§Ï…),ßÒÚfÅÇ„.,ÓÐØÔ\&‚nluMm]½­;ª°\qiyEe•7аRVN^AaQ‰µ%?²ªÉ)ié™Ù¹ù©BHÂ*^žî.q ñ±Ñ‰ÂHÂjþ>ÎöƦȆ¨‡‡z»:ð X©ìëf¦Èê@­¨ˆ ' 4ïh‡…˜Xbx^ÇÏÜ3¨t“48±¬¸$+ùß;$ƽz<IEND®B`‚eric-6.0.8/eric/icons/default/clearLeft.png0000644000175000017500000000165412342633754017632 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<ìPLTEÿÿÿ <<<444**' >@>TTT €€€563..->?=342    !!!""""#"$%$%%%''&''''(&))(+,+,,,...00/444555777787999<<<=><>>>>?=@A>AAAAB@BB@CCCEEEFGEGGGHHHKKKLLLLMJOOOQQQSTQTTTTURTUSTUTUUUXXWXYVYZW[[[[\Y]]]^^^`a^bbbcccdecdedfhdggghhhhihlmimmmnolppppqnssssuquuuvwswwwxxxyyy€€€ƒƒƒ‡‡‡ŠŠŠŒŒŒ•••–––¸¸¸¼¼¼ÃÃÃÆÆÆÍÍÍÏÏÏÑÑÑÙÙØÛÛÛÞÞÞàààáááãããéééëëëìììíííïïïðððòòòóóóôôôõõõöööøøøúúúûûûüüüýýýþþþÿÿÿŠþ]ˆ$tRNS &&@Bbeˆˆ­­²ÃÆÊÌÐ×íîúúúûüý…‡ÏIDATÓc`8À-í  ‚Q™ÜæÊòÒâÚº¼bß80ÍOy}÷Ap‰f"B•µUN~«AG&‘ëÙ[”áñ³ªf~úw!¹·á± ÂcŒM!žÆs¿â$w‘hfŽŽÔ¯Š×-EøýàöS6áY<óêìÌùÕop’;H4:º-Ö°B¨@¼"PBJ—ȸE8f×;鳫ª¹ÁD3˜<‰Póu¤î‰È„ç*£"ìn@‚ï‚}_×KžÄuëB„Žúž¹«puëöÚç±"ÍLEèÑ©óu¤>¬œN öÚ¨F N'øxŸïÍ»4¾çƒàƒa(^œk²dö!‹äIÏÉî󬛊ÎfÎE–Ï(Ÿ¸¥<„_7n?ø.à‚gƒW`áÚFæÍÖ’áöÿtœýŸÔ!ü¹+ßé½|Z§s½áµ‚4ÂjßðLðmÓ4É,þ«hfQîŸHc2ÊEr×_úØ¥Ê÷üò”.óh¼¶a·pÁ/‚„ŽgÓÛWDJÁp®ë€E±÷‰¶í=Ýéàjýê†d©esü•PhÇ©Ž­÷ ø67âô¤‚ØŽ¾$›÷ÉäJh%.“s8pè*Éö–ýl Õ¾V&ÒúY¤©nœÞ]Õø´.«º~u_6ÑÒÚHÑ@)…ëJœ2­$·yžÏ¹ß;Q8 88Ñh¹W?±úgů÷ØËy–v² £Ç#U7ÅÒNÔ‹ÕPUctM­%ƒ„ r=ŸŠXEÉre:“—ɾÜvÅ0ë—xGð½wÃ51¡ÃÆ×d1‹GÏ%2B0ÈqaËsRGB®Îé pHYs  šœtIMEÜ9;’RbKGDÿÿÿ ½§“7IDATxÚí½{˜$Wu'ø;çÞˆÈG=»««ZýR7-%5Œ x–—Y{gÇØ¬wg1ßg±Œ…xÓ€m°`ì5ØØÞÏ0Æ^/àݵÀ `,R’ºÕzõ»]¯¬|DĽ÷ìq#22+«»º»ºõêø¾ø2++32ãžß=çw÷\àòqù¸|\>.—ËÇåãòqù¸|\>.—ËÇåãòñ”8èI‡zsÁèf$v ¢ÆÁn¬j°¶÷}Jζàx dªi¤K§qëµ/à‰rüî;¦P­ì…¸›A¸N®ÑŒBPPV«ÁŸw0: ´ ´‘‡Át‚ƒ ¾íÎ!üöïO_Àãáøƒ[ë ê ÐúÅ÷"ˆìó$”"Îe§H÷3åçG„zŸ3g§8ÀZs3 ºÄwÀ˜¯BÚðÖ5/àR¿þÚ×l>¿q¯ñ^h­¬øÅ<˜ÅÙÐc!‡¿ÃÁã߯_üyzÅ–¿s'ü˜~‚› •‚³~†Ÿå³"½çÙ4@ù<Ûè1g&ÅX Â÷áäo€ô³¸õ÷Ž^ÀF·ï¿š^àW ÔT¦ŠÝ`Aæv6»5æŒÜUk˜ªÔ0U0„ØR©¢¢u÷DèƒÙN4ÁtÜÁt§´[€õ ƒd‚^ D™f ¬ðù3ܶÿG—p>Çûßõø60¿J w1@èÎfZ Œ04<ŠLLâYSø‰Í¸jt›ª †Â¥Ïøµk°’$h¤1æÛ<¸´€ŸžÃÝsÓøæÜ VK@ûÙ¯ƒ!žµ 8÷y¤îv¼ý}?¾ €õÿéÛà-ý´…1«g{y– ãåWìÄKwíÆÍ“ÛpÕØF£ BV°âàDàD 8ä,ö‚@`ʳS#qKq..âΙøÊ‘Gðå“G•F¯vè× ZÆ.ò ý ~ë÷Ž_À ã£¯ ÐÜñk ÷ÛÐÁ®‚ÏY}µ†ïØ_ºj/^°mv @+ã¬sp³ó‚ó)A1C3ÃX‹c+Ëøæ‰cøìƒ‡ðÕcd&#÷!=áßEýØ'ðúÇY||àCïÚâÛ¡ÔË!žÍ÷ûç†Ç&ðÚ½ÏÄ+¯¾Wm‚fFê,¬“Çäg+&œïðâ<>ø >vè^´æº&¢÷¬ý2Ä݆[ßwÏSïÞÏv¯«÷Bñ&¤fõŒÁÔ–­xóõ7âçv_-ÕšºƒŒÿýGwczöT7–P> X7g þ(Þ³ß=õpûþIü1´zUfÓ]¯·z|ÞyÃsðKW_ƒñ¨‚ØZ8y¼ˆ}0"¥°wðÙÃñÞ߃,Ìg¤°ÌØkc? ¡ÿ€ÛöÏæ ÓÇì®Ý¶ï|öóqóÖ+zR÷D>341¾7}¿w×·qÿ‰£ÝÙŸZÎÍÀØ[pÛ{?ÿäÀíïú hý!¢¢ç ^}ÝMxýõ7¡h$ö‰-øþ#TŒVjðÑ~ŸüÑ÷3MWæŠA cnÅmïû“'>ø®Û õ  {o-02Š?|î ñ¯vìBê"‚'ãAD˜ðõcGðÿåÀòR¯I`cÞ†·¼ïö'>øî÷C«·­ÊÌYƒ+§vàöç¿OGÇ<ŽŠÖxhi·}û<:} (G's¯ÁØà-ïyûÜ4ÿÁjá[Ü|åUx÷Í?±¨‚ÄÙ§@uЧ;BVXŒ;xÏßÂ>Ø« ¸·â-ûoâàC¿ó(õ8¡~áÿôž½x×Í?…ÐG𞊇fFb-Þwç?ã[XûFÜúÞ?}âàößy%õ7pRéþów_w<ç§ŠxýSùÈó ¿ÿ½Æ·9<¤öW/–wpqð¡wÝV_ñ–žÚ;kñœ+¯Â;žý“~æ ˜žÒò‡@3!±¿×wð½~s  nÎþìňlüðß¾ _R×÷øùÖâi[wàwŸûÔ ãOqÙ÷pÍ„VjðÛÿòM瀡|ô§ÿ;LÖêH»,õGÀŒ™V¯ÿÖ×€•åÞ8AIúiìøÑÿ‚ÿé³vÃLІÞÁOþòëè·®ŠðÞùìçcÏÈXÏ¿|®>sBìÅ7NË&N1tÔuXÜ<¼ãÎÇŸø£ý7ÀáŸ@4Öèq¿üÌg᯾‰µO"µ-YZò" Ç|íH)ü߇â³÷ÞÝ«˜‘E0~oÞàñ€¾6@sû? P/ëIéZ‹Ý[wà·oz.y‚ ÜI&tE„P)Ô‚U¥*&‚Á‰f©s  Zà øÝïÿ íçRû¨ÿù(*Ñ2:+Û_€{…/Dþ×§_ €ž°vßyÁ×t€+j5lÂd­^”Ì ¯¦­|æ{ÑJ;`º°¹¥™ñê§_‹÷.ÌiÚ5©´zV¶¿À_<öàï ¸ô»`ÚÙ«ú-^rõ3ñ+W_‹Ô=ñT¿õvyKµ†gnÚŒ§Žc4ªœñ3‰µø¿Ý‹…¸E>´+|æðýøo‡ïí­.bœÏÃ|çÉÇV¸äm‚=¬_ÁKvìBÇšÇ}G¯®ŒG° ¯ZÕdA»Ç6c4Š60èCgðù1AD@Dø7W=}„Ÿ«lÉ’\Œ ­l"ìÛŒG¦÷jlœ_…ìÿ¼mÿ±Kåþ-‚pbUE/nÜ´©gÂGèýo£¾÷Ñú®îUÿÏí¹ ×mžÜ8÷FØQߦ Û6ã‘™ýˆ‚`’ü[tñðîý!àþúóø"@¥Šmõa$ÆâÜ–mœE•SYýSßÛ\ß5ä¬3Ÿ¼»vÃļhû® ¾"†sëŽÖ£Ö?FÎ ¶Õ‡Jè´û¸€€‡wïÿS¼grq0bŸèV-ßÁT}¥Î-êGƒ‚Î0Xrt°WÓÃQ„Ÿßsõ†lšiŠ¥¤ƒ¶1èX ù°ñ.ç¢Y¥0UÆt»ÕgÀêŒ˜çøÆÅ€S¯D¤’Õa諆†áD®»Ê‡òlÊêYé#ƒÞ+k8 ThÉÄY„gmÙrNŸ[Šcüý£dI#dÂB^oö<›Å9Ìb#îÌša (™׳ è¤&€ÈUˆAˆÎeZ>òæ HöôØêUóëz;x¦¯ÊcÐöÒƒwºÑµ¼b§×<àŒ.câ,ž¿õ Ôu°®˜[~•¯ž8†ãí&VHd½öœŠ øß(F• ­4EÇÙRµp‰GÈÙ‚DR /±c ç’=øÈ›+ÀÙ[ݯÓÔ&ë!nå!#Eæ²XéqIz‰;•^så®ë¹V9D,>–ŠÃ¿óJ¼xûγˆoµÒ½¢VǺ3³,' ¾rì( M„×ÿÄ ¸¢^ëõ8Öô–‹qŒ“­&ÌÏá‡ósªA€$%ueHŸ6Ä\ÉPP¯Æ,®Ác™ÌptcÀÁ8©åHå¹BY¦e-¬À£sŸ+¹l=®›¿dûì +€M• ®:7.£®ß>™%\ܰi3^pŶóúνûiøÊÑGñ¼¡¢,ÆñjÙ§âÏæ)´¬ÉÆ‹Ð;–E>Dªà`ËÆØ¢h ð= O[ë«adðl”ÒìÎo’¨ïþ»¾®P㢺&¯0ºX-dYaç7Ož@èßK¶í8ïïd/ßµwŸžÃ·§O! †P¦% R'<’5@±‘Ó«r1}cÉjÓzã:Ba4 ­=¶=vȘě€Ì(¢c>Vn‘¿ž™ E œóupžËXaÏsø½º˜‡çqdyš{†‡qÝæ‰ó¾\.’›&¶½‡É›‰b6Ò7ž¾ìÜä E¨« Ê^”RçF7Ð ”z¶0Áõ’®2‘3‰õK¾Iºê)Ÿù¹M§¾È]y­™SD—¤¸ü®éi@”^¸u*Z_°ÆÙ\©@+åõÁ”—ŽQYó¹è BiH¶R¼š_åæ@)ÀØúÆ€½N$ü…Æ¢i ªJùBÜ®»nh·œ³—ê!1Ýï8h0”wØèŒñ³ 9˜Kqçç1a(ñìÉ© þ>0„PD€‹ˆ)­‘(’ÞÐ9²ÉÕ6Ö§~ÑçP %™m\ ˆ¿t›Îa.I°½ZÍÒ£„ŒÝçV£ø¡²ÊƒTF°sà:|¶ê€ƒóóXŽc(®ß´[ªu¸ mQJÀJšÀy®›ødÂuk‡ÉÅõŒ›"Â\gö±§x†Öζn\(xÀÌ/kfã¦*ÕŒæ?ˆK³»Ç¤UÑÀ¼¬B EÝH\Ï•–=D€{çf²ïf…›·n]ÃG?÷«·…‚@àƒeNÀyÕSÛ,}Å2~C) 0wV‡Ê œ1$r¡8“ð=ŸLb´¬.Ǫ ¶+%Á—#f>_@Q¶RE ÀÈúia£‹Ãˆ‹Ž-/!$ÆÖ¡!\5¶ ²A+šgÛ-°ÿýyzÚ–c%e"_n á_$ÂØ ǽܫ?pŽ€]Ñ@µO½JÖàHÜÁîJ .7ANzâýAåU»"Iöœü`‘,®ø‘Œ‹táá¥tL EÀõ›· Òn# Bb'pÎeìÆ3þÕñt;§—"¤ àHÜñëØ»Šå˜J D€[_MÀ:57‹-Zʧœåw}XÓé ‰ª}¦žJA P&LlÆ3X$›ýþJ‚BÈY,@{æñù5">çl œÜ7;å Û žü J¸œ‹G@bkpr¥ªRXHbXg€` dnoáúSwÝBJi7{ÉtO€ ½á`PsãÀ²ë¤ùAÂ|wËG⻢(ˆ?¶;pZÈ«ûLèì»n(OüØóìÿMY<0µÍ4Y³ƒxÞ3TjÝ4AáT³ãeÄØ9<‚Zb9ŽWV*ZC­S13fZ+h$ *LˆMêÙÔàòî]Ÿç—«~‘8 ÿ_€ ô3­0/mž‡• Jæãç3º/ ™Ï˜Ö V€¸ëÿû¹­Oòr xõÏþ†Ùk† ¤lk–»gNá¾Ó³…™ Rj%Gæ¿Þ{-vŒÁ­[ý:=c³¢s­>uÏz¹™'`­ñËϼ#A´î…/G–—àœCÀŒ•$†-´\7}”k·Ê¶;´­ÚÍnÈÜa 2FÀó€Xf¡© F%[òRžù6Y´óí6&ju8qŸG¼Ð•H—ðù“<ë/ïM‚† RŒ"‚Ĥ…à©PÉ»Þ36ŽmÃ#ë^–F”-êx`þ4"VYƒ'Ä~ê<‘'£vŽa$ŒÖ½G‘‡‡—Pe…¶3h%JºÝ’Ä,“Œ ÒÜï—Ì<Îw:€1Ý1æÒ‡ûAÙÿ6bÙÀŠ ªÏÍEÏ¢kÌüü1qsJc,Ì 5IIØ]õÏ%ág€È߈L¯4 }"*7ùüØR«£¢"Œçú¢³Î…)Š,Ì£Ç5c®ÕÊ„_2)›ª5T´F Œë'·zm{v0óí6N5WPQ síœX(ïÿ«¾«äÉjçC㉿×ù8âNÖ ” x?˜‡ÅLf€7½©ƒ?yÿÃ`µ'cõ¹ð¹Wøý¥J&™±UÞ¾gª=€êO¡Ä¤«˜([Æå,YX,\ż!“8Á–Z »FF!"¸zÓ&ì…±v]žP¶]ÅÁ¹Y„Š‘Xƒ‡æO#¶®èÒ5†Ø6< ‚`÷ø8¶ øõ]Ÿãá¥k*ÆB»%R&‚ò†Dùµ’i<‘,:oÒLõKn"õVZå ` ãMoêà·Þ¼AÉ E‡{Z”ô Ÿú„Ÿÿ¸v M“f¶-™_KRò …½Ï5‰  ÂL(ªZá[)…ZâÙWl/â&‚³ŸLŒã+˘k7)Ó­g3/įöyúæ Tƒ‘ÖØ·õ Ð:¯ŸU|p~Uf¤Æ`1îÚ!P”EY2²§D Ͱb Ðj­&¢ÞLõÆfrbˆ¬™ãA¨õ…‚ÏÁµ¦ûº‘<^­ö©¿JÇ#VN “BûT^ø” ]¤>‹·ÿÒßK8Iî];±ãÕj–³ŸÚŠ-µzdY×iÃÁÙYh"Xgq¢±\”9Ï'¶Ö‡'¸fó$¶ÕG®óú àT³…v U`f¥kLqÏJÄs)q ìžµ–Ó‰¯Gè·ôŽë*\¸rßňÞ…Ô¬!|,üR²ât§ D˜ Bh"/x*fBåüxf@Ù_»e ž6¶ F,vŽáú-SHÌúR(fœj60Û\AExxa­$ÍøƒsØ62‚k'²‰zû¶^Q€k]ä œ>í—‹;œXn@KfV´*O.óx$+¬=ÆX*¯ú)l_©}ÙKF¡îÚx°» i(5å ×'ü2“ì¶„!B¥ =/È…ÎÔM SžUöOŒ0®›œÂ5[àà0TñÜm;@>_¾n(‹àÁùÓP¤`ÃÑ¥E0²\ûŽÑQ·ñ@‘àü —÷fôÎ,|¡J„€€@èƒA‰1X¶ÃJ£ª5˜ãQ[‡†ŠËe‚Ž0Y¯c²V÷{;l®Õ°oò é©5ëβ.-Ì#T $ÁC‹§±stÏØ2…©ú0œ80ž¹e [ëÃHÌú¯¯™1Ónb®ÙD= qïì f[­¬®QÊ¥n`Ú&EÓZÄ>ßQEÎñmé®7>£& Fo‰ݱ^xîé`J¿ŠT ˆôÀÒ°jýÂ' Âh[ƒÔY0{ÇÇñÒ=Wù¸I¡œ´ifìÇÓFÇÁB%á¬ï´Â±Æ2Zi‚Hk,ÅüôÎݘ†ò+›G¢ ž¾y£A„8Y/f`¸kqÿìŒw]Q4H­CÇZÄÎúÊ òkÙsöcÚdIµ³™ƒüIj@üÕÏæG;8€ª<<ÅÌëSQ¥£ BÀ^øè¾öÑÁÜå3bÅŽ>6À &FEkŒELÕ‡PS©É P×[$&(f´¬Á‰Æ2*:Ø>< iflÅöá°:IzN׵Ɖæ2Z&E5p`ú$Úmg^Flg‘ø} Ý27룙9Ñ…5¿]}sVÓP¶õœM@›\<Üö–&þäö/Bñ3ГäU…U"TˆöÍüÐß8£ÌrLÙúÂ@1D€«Æ7aÈ{ « $Ö¢m’RFðL«l{KM‚€ptaìkäÑÜP)lªV±©RC@„41…€ä¬ÕQoQÌh‹ÁÉFuâØò"î:~©³0ÖÁ9ñ?FS–]Ïãiyð®[@e•TŽ2åÞê59u“Ò*e­G_<—î çQÀŸ‡ILYñ߯záGë>{0kfT<É #qpâШr×»F°hÌvZh›‘p|i[GFÁD¸rl URHEg½žDßû­pdñ4@ê,¾þȃh¤©¯&´Oƒg…².ãÐEM@¦ñòë:e "çûµå ¶>¬iqÎ;‹;æ—¾‹-õ¢aÒUÂÍüJŸÚ?£ð}®_3#Tâý}kí €Hk´Äât«…ZàðÜ,î™>3¾©p5;¾ÁÓ9__µjÓ­ÄÆ øÖƒàÈÒB¥²k–ª¡¥´ä͉dN¾ ^•myy9¼tID{-> 5&0ßúî¹ÞùÙ¼gÐ_eûÜöî‚Í^ø¡/åÒDÐ9áë>³>4gd/ B¤5*Jû^~6sÏã4Öf7¨"àÓˆ;øÒáCˆAÈœmöpžßc¬A†X±)V’#QÌÍâ;G bö9ެ’9ö¼Gû׳ BÉç=¨øŒ AýÄ }Y\0È=ç9˜¿:×ç§ ´‹4}˜'Êê°ê…ø‚ä7Ü7óÉ?æ%ß’™­ŠKžïÖñ"€V Q5Â\§…P)ÄÖâK‡îÇb»…­Cu„Zy J°Öá\êˆD€jÁ)Âr+ÆpâÑÅE|ñÐA¯Ñ¸¨òùO*\É•OýÅus ì…«½&ßp2ãÛï2I2‡ÐþíùŒÕù•Ù½î­Ç|AÐÃø á{ÕßÏöò3?Ÿ yâ…‰ (3‘޳rΧ1ŠÃC5,§ 41´b|ùÐ}xpþ4"¥ü÷(DZgésëÖumë¯_ CèJ€å¸ƒZ`¡ÝÁçïûšIM L\ÜOfæØ¯k`_ù”U9é¼öÑK±þY)|® 4¡ ÓÕ~Ú£@üi/\ ƒI_¦zàP¾°PýÝlù›"¦"¥[TÿP6Žš*Z?§Ž£’Í”z5ÂðpM“B3ÃøÜ½?ÄݧN! XçÀJ!TÚk¢Ìÿ—õ cC5Õ+Iµ0ÄÌÊ þúÀ]˜^i Ъ”/Ȧ|¶H²DDŠuŽc?õóÿ1•jDšòäCÈù41Áç)`cš°øØùŠñü mßøæÃÉg¡„„Âî%»Ÿ³`.«}tcÿä…Ïù¬`B¨3@c Œ±g=ÓÔÀZ‹Ñ¡FG‡8ëg:áÿ½ïǸóØ1Zuk ‰jÐk€ô¬×O!LŒ #ªEH­ÁPa¡ÝÆùÁ÷0ÝXAEébõRnê•)׆þ=þ}ùdèšÅr¹[w"iÍ@…2b@‚¿ÅßüãóãîbÞ_Mù*¬FqrA– :ò›S%µO…è%ÅY ¢4„$a=£«—3÷¡jã£Ð¡Fj-jAˆùv Ÿ9ð˜>…(Ð…ÛÈpPÄY¯?Êrv@çÓ¼/at¨†Íc#¬sŠ*¸oæ>u÷]˜^i"TùÒ-ñ.$cý™ É^'_æ$#¿ÎÚBX*ØCOºW‹döß»†!†ib–áâ\ˆ/ ·Üz¿þØBú7u’ô¨ý®=£"¦Ð­ùgþ$âÌ 3‘à$ÃX[T•]/ñ kÕ›ÇF02TÏ̆Q¤qïô >sàû8¾¼äùuKéˆpæm€´ ñ‹DÀJa¸VÅÄØjµ ¬_ÎåXðGÂç~|Í$AT¨ý.aË{dЫ}ï÷;Bƒàüøl|,‘ÿ;+ïB*Ÿ ÊV‡aÓŽ?¿á­;¨C> Òô•Z©ÊIêïQi¥šþüuFæú±/tÑÌuö“"Yh݈3#  U±itõ*È‹jf¬Ä1¾pÿ½øÒ჈S‹HÝ*êR‚)'›D„bÄÆf«˜Q‹" ׫F­Òm‰1ãTcŸÿññÝcG2gȯ–¾—–uúµDYñ‡Cw¡´ƒ8)BùÆ“T*íËIEý õ•Q¡bØ4=jY>p¡ò»`œºåM'wÿù‡ß«™ÿ\‹-X,—=ã§b‰T®2õÏÐâ Ë¿3¢0D¨†ª• ê• êÕJõ6k2ÎáÎcGð…ƒ÷âÑ…Eœ±|¢²Ëì¯KY½žöתVqí•Û3·1 hµJë´Óßzðaü×îÇéV ¡/sèjënó¯úsKfØ%ïWœ‡Ùf3Äå]ÈüûX2âÈ^ý3!‹&‚ ÌPƾ×Üò¦“9 ²•O’$¿¢ÃàeÊÏÚ¼À£\ÂMåŠ^ÿ¿zÆtÌJã‡'Oâ›>„ææ/Ü Ò’µ¾nFÎxJÒ4Â`xàõg›+øÁñãøö‘‡qty šU¯¡¤(Y£îæþQòÂUÿ%>ÛéÄú<@Þ‰,ºE¦=²dY·ZJÂ&‰ÿq•OžÚÙmÞòºôº?ûã[Ùò?1óœô¨z5@õsI8™ß¼z«5@úq.,⇧Žã¾™i̶Vwã"¢¡â쨘eÂgCl æZ+8±¼ŒMŸÄƒ§Oc©ÓöÉ (QËírþœ _§çJjÞÿ'z o¤è|âm¾BÎ Ó€nÅ·R 0f‘!·¼åuéFÈnC—Û>ûãò¿©0üS²¾º]ö?HõU_Õk¬ÅóvîÂ/_ÿ,‚ÄX´MŠ•8ÁB»…¹V'——qª±ŒFÈC@ Š»|#—xO‹žéŸ |= ±}d´'²×Lb4â-“¢“¦pÉôoÑ­øf(ŠT¥´’¨û<ïäJÝÎă€Vš¢mLÑÿÈ"ßÏWGùGç›o9­`“ô wÿûßøÏ%3½‘Ø1>õñ“Ks/ÔQð*øA,«õø¸y.œ‰î9u?š>ÕfßêÍ™Ç(…Њƒ°j³†®à©´çDwñDÇ:=·j&䨔z æ-wqͧŠd‰+t5Š”º»°ÿ›ýÿ]n”¯ýéYêÇ’{ RÔ ÿÓu"MâO_9>õñ»7Pf¾à~ß'?69dðèëɿԫ ¡n¥O­V³È¥Aù}w= XˆÄ…& Õ$e=£Ñ}“C·£W±Ò]PZà!=À‰ôÄPjr™'E²UËN±f‹Þmg¬4ÒÄü0 ðÒ;^}Ë Ï€üùÇndÍ_RL[ÈbªÜÝóѯrÓ§š0^«Bëu©':†R(¹Ð}uóDPÍSn?;`ݯô¾§¿â'vv.=汇®9¾F—ùßÎÿo±ÝêQÿý{ ;‡*±v¶cÓŸ½óµoüÁFËê¢5ÞzÑ_|ì•:Ðà ‰!P*¸•¢s„-õZA´úŸƒ¦¨=EoL¡ÇÕËÛöÔ,àë©õ(µr•Ò2,ékñ›ÏyéiiëÅ/ÝÖ±ùÇ:Æ`¶Ùìy¿õ¶Þϳâ@êØÔþê¿~Ëç/†œ.jçµ—üåGßÀ*ø ˆ½­ÏÃÂe5NÞîNÖ‡²Ê˜œ—ÞW6]SQNÓj§¯4È9ìåå¶uý ,‹÷ úH`/_èªûî̯!œfVVŠÙŸƒ »²ž•މµé¿þš×ÿéÅ’ÑEo½÷ò¿üØm*ÿ€œ <¹'BE ýxµŠÍµZ@{â%WemУò©‡Îà®™Vì ÇË€¶­ECè>ÜH&(7ŽÎ®3×na±Õ.‚?Å{‹™âÛ+“¾õ«¯¹åö‹)ŸKÑ{?û‰¿x¨·‘ïŽE«²`TÄ ¦F†1U‹DL_{H¥ä ’'Ô×,“Jí hÕmže+*ô÷õ—2 ŠV.Ýýú9AÙMt¥¤ÒR§SFar­€Âîç½5Ƥ¿ÿ¥_{Ý;/¶l. àç>ùg·i~€"çzÏ¥½}¥°cdCQÔÝ'”€Ä¿¿¬È©WãSW[¬Rø´ŽÛ)ê z÷¹,‘»3>wÑç¬$ Ž--f5ÒË¤È .Mßö…×¼îöK!—Køù¿ü³ß £ðv&ŽÄÚn5ŒO#çÂÓŠ±stc•j±u••õøþ«ÐÓ@f - 54@©Î¾lë©ë¿õôxîÒ¿2NJ@æà/vÚ8º¸˜­/ôDÏõ“Cf8HœÆÉmÿðš×}øRÉ„.á÷÷?|üc¯ ‡+VJoc À%dõ»Fư¥^ï±ßùÿ©ŸèQ9H=äpÐ-Ó™TŸFptíyyOƒâQJ…½"˜m­àèÒR±¸Tr—¯¤(аÆÌ¦+Íßüûÿ†O£Ôæb F]"0ÞµkWpç_ÿõ}OÛ÷¬ïéÑ¡çê0š€Ëjør²€¸`¬RE¨4˜³Ìaÿ©Ë“*½¦¾_1ƒKg÷õ×'ÊÞC쿟ŠKвÏpéóì#•âÇ—q¢Ñ(2}e“”øª0€K’ûã‡ýõø­Û¾¸k×.½´´tD>1@x÷îÝz×®]µé¿ÿ‡Y­Õwôää•A­º‡™J=»f‰°’Äh$1êaˆá(‚ö¥^Š´â^a“*AA)†^‚, ”êò`P!äì±”üoêG«ì·,w:x`~óöà,3H)$‹‹_]üÚ×o=ú‰¿úñžnÐaºééiw©4]*õ¿wï^ œššª¤i:b;ÑJµ25öŠ—ýÏÃO¿ú9Œjb²Õ4èó3ኡìÇpXñ )åúi•ÊÏ+€F‚d`ƒvê*6´)õøAɽËÓß$Æ£‹ó8¹ÒÈÚ*‚ âVùûÐ .Nš+þÜÒ—¾ò7vgZU*KA,OOOw$‡2—êRÍþÍ›7óøø¸Žã8RJÕÀ<Å£Í÷ͦˋ zl|*É5ç~?u `#‰1ÛÌzùÔÃCQ„€u–$âlök?ëƒÂ<ø×Kÿ+þ^uR÷9õš®x‘hVh¦ YœÇ§ç°ÐiõŽyÊ7O 3ˆñôôñù¯}ãs‹w|ûŸ%Ô±ÇDÇqœÔëuÓétìéÓ§/‰иćsŽD„”V @S=ª6î;<ÛyäØ×FŸó¬›FŸµïêpd8„gÌT û±/á~dq'W–0UÆöÑ1LÔêY¨'䊯 ßKZ èþ]TAQ;ply3++Yw1ÊÊÖÊš¡Èû+…di9Y¾çžÃKß»çûi»3Çõ¨ @+­ØYGÎ9ºÔò¸äèfìXˆ'º’ˆs§¿õG›÷=`6ýäsv_³wTת,Ö"¯¸-ؤßÈñDc'› …lÆÔð06Uª¨èš¹+­É“³ª«n$°œy4ΡcRœnµ1½ÒÀÉFͤS씪‰zº‡æ³ž•‚iµ]ãнK ßùÞÑÎüéã* ®„äÄI1p‰.)Â0VlMj¬µÖj­S±’@!ÐQa˜¦ËKÿõËÇk÷ü°µéægoºúi]­[׳€3_hšI‚Ãó§ñÐâ<*A€ñJ5;«5ŒFTÐ›Š³µœw~ÇñÄtlŠ¥NŒ…v ó6ÛmtÒƹîºPwÿOí‰3uŸ¶ciÞÿ`çôߟoŸ<µ 7T¦:bq’¦Ôcs¶R­X­´<Ù ¤Z­ÊÜÜœT«UÇÌÆ9èSˉkXQ¬–¡T¨˜uçä):ñÿ}!©^±µ>¾ïú¡‘½WWôÐP¶tÎÙ’R§Âc±±8ÑXÁ‰FD ¥²r®j TŒHkDœÕ fÙG íW9ÇÖ 6‰uh§ :©•¬ÿP†¦,P•ùûÎF+¦±â–8ÜY¸ûÀJçÔt"-è&5,[gW4‰© ãœ‹EÄÄØ-¶¥Z­Ê“É (4÷Í7ßT*•¨ÓéÔÃ0qâ6˜0ÉÄS¶ø¿Ç¸a&®[cªì\MNTF÷^Syæ5Õê–Í /˜,kC\.év-ÉûZçÝ79ߦooêŒíKQÉS4,ëÙ ]z’@"â£ljЙ=.Þw°Ý8t°ÏÌw#VZ·¸&7,˜0ëÄM˜0ÇÄóI’,W*•f§Ó‰ï¼óÎÔ§Ü“€÷îÝ«Ò4êõz% á0 G´Ö›¬³›L0ñm0."#†ÔTÅÚÈ9èJ%ªïØ^Ù{u}xÏ••pl\«0ÈÜ?ß­«›  ¢ K±MO"©ãz¶q‘rk\ÉÐA”ñ 'ˆÌÊÃG:Ën6ï˜N'fæ””Š´´4ˆhÀ‚ˆÌ;qsæ«ÓƘù$I–“$Yi6› âC‡Ù<ôdâR­VettÔ´Z­´^¯·(cbbrâĉ³ŠTâmdÀ €!"ª‘Ö*bÒ°qøá`éƒp¨T·NU†÷ì®Õvî¨T'&B]«)ÖÚ/éÆf¥¯Érérü|³j!_æ”õa¸4EÚlÙÎìé¤yôXgå‘GZíSÓd¥•2qJšR†ùïïˆHËßCÀ2€E'nÀ</Xg—‚ hAÐŽã8˜˜0I’\ÕÿX$ƒÈ‡ƒu½^×£££áÊÊJutt´`ȉaâQ"µÎŽ*V#†üYGÖE­*"€È‰ ™XÃmÓZ)­GÇÂÊäD¥¶m[%šØUFÇÂ`lT«(TÄJ\,,¡žØ¾Xg,¬ME#.NlgiÉ$ I|z!n<ÑéÌÌtÒ¥åÄZk³ÖƉ3Lœˆ‰(ŸùíˆW¬³ËŠÕ’ˆ,9qKL¼ `eii©944Ô^ZZJšÍ¦9r䈹T³ÿ’gK9•ƒ ÝnW¢(ªAPKÓt(‚á\ðD”?ÖD¤&"U"ªˆD$"¢PDdm 4Äik‹q ­ÃPq¨`hH#êV´®T‡¯NlÜq¶Ó±¶Õ2éJ3MWVŒ3©5qbá`H³UŠˆ ²‚Ý”ˆRI¼àcéQ›ˆZ¹‘•iš6‚ XIÓ´Çq«Z­vJ·—Êö?V ’&Põz]‹HX¯×à "km- êWsÖÕXq‰kªN\M±ª¨¨xá‡"QèÍYà•ˆhʉcrBN„áeõ›ŽÜ»q¶–ƒY˜È “0±`‰È [žg5÷0^ð %"R¨~ël›‰[ÚN\ËY×dÅ-&n%IÒVJµÒ4›ÍfBDýÂÒš€U Ø»w/W«U­µÖ"D•(ÔJGN§BD•(Š*I’Tƒ ¨c*Þ Dĉ“˜"&N\P€fb¿4Ÿ”ˆ0±ˆ°GLEßûž,€ç˜XˆÈ‰ˆóÙv¾ârá)§R'.'11%â$hk­;išvÂ0lÇqÜ‘N¥Rékâ¸'D”cL»Ý6‡r…ð+”A@ûöíã™™566¦Â0ÌgqEQA˜¦iÄÌ‘Ö:4ÆDJ©ÐZ*¥B'.'ˆ„ZkíA ™8Ÿý €bbåÄ1³ó³Ÿ ÷ etŸ‰ÅÁy¡[&ÎA`&N1†ˆbJ™8±Ö&J©ÄZ›h­ccL✋ƒ ˆÓ4Mâ8N¼æH“$1‹‹‹vrrÒÞsÏ=eÁËc!<† (‚zûöí£µZM1³vÎ̬+•Jàœ œ¸@œι0‚@!ôòÉÄÚZ«(¥[k™˜R¬È:;°3Šb嬳™÷ïÄ*¥œµÖ°J©åÓk“¦iÊÌ9 RfN;Nêœ3Ìœ:çL«Õ²%Áçw—*÷ÿxÀšf¡Ñhðää$///«Z­¦¢(RD¤µÖŠˆ4­²5âš™UÇš™Uþ:)ë,+VlŒQJ)vâH±b!'ޤocEÊ콑Xg‹µÖi­­uÖ)VND¬ÍºI眢È8—™†üu1Æ+"&ŽcÛjµìÈȈ™™qÃÃÃî±T÷gôkx¢ÈišÒää$·Ûmæ T’$¬µVJ+eRÃarÇŠ™•ˆ3+­5c˜+qBÎ9 ‚ ¾Hˆ$Aš¦ÂÌBL⬳ZkgŒqÎ9KDâ…o“$q:ÐÎk16 C—¦©m4®Z­º™™9r¤ÌìÓÿ¸É®‘3è ?p499Ihvv–¦¦¦ØZKõz[­cH)ÅÎ9€­±”$ ³Ê2EIœ°sŽ¢(¢4M)OIôQ™Å‚™%ŽcafÑZ;'N’$‘ œÒJLÇ8k­K’Ä9ç¤V«¹8޵Vfgg]¥RròäÉAÛ ‡³îñz Ø­º XXXà\¨“““œ$ @§ÓáÉÉIc(?­µ4<<Üs¿ÖZBFz„Òh4D)%Zë✙™A¥RqyVsffÆ@2>>îî¹çœAØòx`ŽœPA+KÛ¥Çw®œ›[^Û¾ÐÅÎÞ,løðѽk§w¯[WYßÜÒP6Ù ,ÌfùàÆ¹}ç–×56Õù9qALáv‹¸}áÀæÙÅU55Þü0+ƒî\>¼muZNAiÉ4Q„ÿ%Ž^9¶cU[JFÖDu¤`a2=µkMw|’¯ 3rp±[„ì]ßåéÀŒ<®Á›:¼ÜyуW(`kk¯f°K.é‘ÂLªFÌ ä¼ZiL/PB¿IEND®B`‚eric-6.0.8/eric/icons/default/attribute_class.png0000644000175000017500000000040112342633754021106 0ustar piotrpiotr‰PNG  IHDRíÝâRsRGB®Îé pHYs  šœtIMEÛf/±iTXtCommentCreated with GIMPd.ePLTE8r¡f—½ž¹Ï¸ÌÛÿÿÿBË·ÁtRNS@æØfbKGDaf¸}/IDAT×c` 0 @¢chˆ#˜!ââ¢f›8AÆJpT±°"º9 ØŒ!ïJ·=IEND®B`‚eric-6.0.8/eric/icons/default/preferences-styles.png0000644000175000017500000000167612342633755021560 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¯¯^‘tIME× [ž{øPLTENœÃ÷÷÷ÿÿÿ   ÑÑÓÿÿÿUUU©©©½½¾D•¶©©©ÓÓÓWXY­ÉÖ§§§ÙÙÙÀÓÜÄÖÞÆØàØÚÛÜÜÜÜÝÜŽzz®žž±••èèééééêêêêêëëëëëëììììììííííííîîîîîîïïïï___<<<ªªªlllOOO¥¦¦lol%@G}}…‰……ІXqw¥¥¥x‰r|~}Œ‘~‘~Ž‘VWVããä½ÓÝÇÇÈÈÈÊÑÑÒÑÑÓÒÒÓÔÔÕÖÖ×ÙÙÚÛÛÜÝÝßßßáááââââ+œÇ0¥ÊL…»LмM½M”¾M™¿PŸÁg”¿¤¾Ì¥¾Ì¦¿Í¦Å×§ÀͨÁÍU†Vctwcde–ee™eežfkºÜsÊêuv~~~¤µ…ˆ†ŽÈâ“““••••Ëã¡¡¡¢¢¢§­®§Ü𨨨ªªª¬¬¬¯¹°°¹±°º±°ßñ°àñ±º²±»²±àñ³ºµµµµµÂι¹¹»Ç×¼ÉÙ½ÏàÂÓåÄÄÄÊÊÊÌŽŽÌæéÏÏÏÒÒÒÓ‘’Õ£¨ÙÙÙÛÛÛÛÛÜÝÝÝßßßààááááääååååååæææçççèééêêêêìììììíííîîîîîîïïïïïïððððððññññòòòööö÷÷÷øøøùùùüüüýýýÿÿÿåÁ˜NXtRNS (++/444444444444jqw‡Ž“œ¢§¬¬´¸º»»»»íõö÷÷÷÷÷÷÷÷÷÷÷÷÷þþþþþþþþþþþþþþþ,¯¾œbKGD§À·+èIDATÓmÐAK1à÷&YdA,Ѝä E¡Wÿ¿Ó!½¥Ý‹§¶âEºÙIƃvwÛî\òø^HögDd_ýÀ@€Ë9çc÷ÉüãÇOÖ E„f9Å÷+§Å³?©›¤Å›ÙzÔDKÁ[è7¯äÞÄújÕõß¹Ëóów¸^Ž1°ýzËþà9W“mŒ=ž…rÙñ×ú·qzÏ®Ü%pP’ªG¶z›n 6üæK»«±ö¶ŒÂœ@p@Ú4äÄ i¥²½š•¥óOýʺXR¯)&œ-ýϱ_>cät¥ˆ“IEND®B`‚eric-6.0.8/eric/icons/default/flashBlock.png0000644000175000017500000000255312342633754020000 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÜ!,¬´ubKGDÿÿÿ ½§“ëIDAT8Ë}•{PÔUÇ?,‹ì¢äXjd6™Ï1˜JRËrFÇÌqŒ13Ÿù~ѨeâÛÔ€Ä@-34ŒßL¾“D1eRDM!Ø]]t—½÷ôÇþÖ ÇÎÌýçÞßïsÏ9ßsÏÿ·@ `B€æ€ÕØ3Óg/‰HÝžõaZÖOË32m¯gÚlÖ'Òž³;ÓnÂözÈ«‡ü °ý óuëñÎÌùkV¦ïÉ-;”úvƾ|gò¦´¥Û3~èð0Kxá0Ä4B£€<º4ÈßmÂ<…󖨻S´Ö""úJy¥JÚ¸mcZzzÿ@Í>hðHˆ¬‡óÂìpµŽ•žØ=lÔÝâSgÅÕØ(J)­µ­µ”\º®â×~»jsê–—š:l¯*ðži'\þúÏaç~±ãêõ iôxDk-J)ív»Ån·ëâó—¼ËbÄ'$´{H sGh_ E~/ÜŸïúRNЈ) &åœ,ñÅm„ïºï–“»È¥¨žßÂ_s6mVÊÂE‹ÃõÖš SšæóÔ ‡^=ûu_½iïEñ™­ÅÙàÖ 2Ô†ÁQ6J@2M¦ó[zãK+& åpH=”dÁ' ¼↺où¾¨äªÒ>“F¯’õiÝ«6ΚÂ.¿3¡¯O20o€¡þƒi0h›ïicïžÅª.:¬í‡ˆˆ9þ»ŒŸ÷ÕÁÈ>zOž½xpDxxŸFh‹ð•Q÷—Â:i€jày ¡0Úmüà5™¤|×.©¿ë”ü úç‚ω¢R•œvXb“Rb+!W@ê h`­›€TC1˜ÀÔ¹_ßýøš ñZ­Rž‘!õN‡h¥DDd_N‘Ä%®O*…­ℳ¡Ðº)øð¬‘wÆÍZ8øëÜÌ9ªÝ­Z=| ¦§K­Ý.JyeoΉ]“œx RÄg[`K)$ ˆ ª€v­CŸ2óãSwVܾ#N—KÊóòÄWf³ÎŸ¿Dï;V$‰[²ey\R\%äâó§"È£ýâÍ…€ei\Ê„ï²rµW)QJÉý—Þœ²UU[B<þo7¾507jü´IºtéÓ÷šŠ´ñµp¶kÔ˜‹3k«k"Z´ˆèê:‡L]´áBÌËcpÀ{ÂÒ3ðÿ² ÐË_nhj¾Ûdšg¨¯×Î\T{³²Æ÷ÈD‹ˆHÚþ‰Ž‰›X#¡»®ùsÁN $Àx Lž<£ý§1ñYeýú«Â•ñÞò·Dk­µÒ"¢¥¼âŽÄÄ¥æuijDز#ôvÁ-_qCÝ7ûzµÏ¢FMéjË>Vꪯ—Ë%^¯W‹ñ*¯v5Ü—˜„ԪΑ}ÞžÚÝ.Âv Zƒý0Ù/ÚC9vzWÛ‚+4}ãV•l™ã(k|á/ȾY·á´×è F?©Ýà _4ÿÚ°áã;í;r겟øÀí‘_ ÿmc£î@³4mNþu ²‡BÐü1(ÀŒèyVoú±èhÁ¹šô½¹e+’Ò³ÇÍ\8uB§Î=OÁœ*Øe‡ã(¨‚½Å°ê 7„jöÄ·òóe¡«Ö¥F/‰]?}ÙÊ/_yÄ-š S«1H›C5Ø(©€'1ÿa*eºgOÖIEND®B`‚eric-6.0.8/eric/icons/default/editReplace.png0000644000175000017500000000206312342633754020145 0ustar piotrpiotr‰PNG  IHDRójœ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<+PLTEÿÿÿ µ¹¼ÉËÌÀÃÃÆÉÉÃÆÆøøø Œä€Ùã™ì€ÙÙÚ’å€Ø€Ù‡ÝñžòŸó¤ó€Ù‚ڇ݌à£òä±üãã‘ãîƒÚ‘äí£ðÄÿì”åˆá˜è î¾ÿ–æœêžì¨ó…ÙµþŸè!ŒÞ!à"‰Ø"œò#Ü$†Ô$ˆÜ%‹Ø%§ô)‘Ô/“×2”Ö4ŽÑ5q§6p¨6qª6ˆÇ7º7‘Î9tª9v¬=q—=sœA…¸Br—E¢äH‡´HáL•½M½O|ªP}¬P¬Q®R®R¯R‚¯U‚±Yh~b…¬h‰±ls~ušvu}v~ŠyŽ™Ÿ   ¡¡¡¡¡¡¢¢¢¢¢¢£££££¥¥¥§§§©©©©Õñªªª¿×ôÊËËÑÒÓ×××àààâââçèèéêêêëëëëìëììììììíííîîîîîîïïïððððððññññññòòòòòòóóóóóóôôóôõôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøùùùúúúûûûûûüüüüýýýþþþÈžl)tRNS "#$+,1369=?FGINPQRSU[]ŠÜãóõ÷üÂ}žµTIDATuÁ;nSA…áÿœ™±cˆIô€Dƒ”=°h” +a J „—RErŽáÚIlß;ƒŠ†ïÝ þ5œ²Ùx< V0Rûþ”¥³&Ï+¥ë0ª"β¬ á'RûAÁ!”ƒß7³¥,ÀÂÁ Š!„ñ~J­Vƒ{FçÇoÞ7©£ÁàÚë~Î[¯?¼–c2bؽ}¶ó­ßù±ß*Á– ö­òuëûæé¥X"™{k?»ÃµY)2 R;WS·,êbI@#¾ì•õS¦¹H¬°&oªù`4¨‹Èu‘%-î¸Ùn—ºtÊYö℘ͻÉR™¦—'#LyhÄJýëâóE¿A\¸,Ò3[ªz¯½9ˆ•këOe!ƦG5 V:W̹29ÎüŸp´ÃJR]çf)7Í_ÇO„¯1Ó–IEND®B`‚eric-6.0.8/eric/icons/default/ircDisconnect.png0000644000175000017500000000251212342633755020513 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÜ (wbKGDÿÿÿ ½§“×IDAT•Á TÓð/Ró(^I)‡Z 52í¥h†=eâS©Æ!ˆq¼q‰\7rø`†"Æ@`²qð…¢óàHñ©) úD¦`"ÿ_3Åx&EŸFÃ^(×rɨcaˆ^Ð8èŒÇX‡q€®6å»ñbå:aF¡0M”ÕµÓÿFtò6Æ+´0Œ¯ä4/Z~1;®ü’(V~aXQSò¾‚êʪžq.ù L-^Ž‘ØøïÂp&<‘‘ûúÈÝÇ:úršÔ$nR“¸©—D ÷)QÙLŠZÊ=(&[)€iu‚ÌÏ}¤ç.†Ê[(éx¥œ$aÃSÚÕ0@‰¿0©ê§àâó»·wõ—«<ha4Þç8oñÉiìßÝðWÞ¢¨ª&¾þ ®êc"jû˜§(®¶‡¾ Ͼ¬3{1#qOÈCeµ üÁ¶ åû43áÇ’¯ì& íLpÍÆ¿º— <ú„uÈ&AÞ ÃuÆ.Dr+ðÉÄŠK/X@Ïh­ûN·ì¦~u/¹´WÙA/eÃSö º›¬bK/5Yo‚áZóñ:R™G¶´èvˆ€Ÿ@ßãõí&ò;¬&'ÉUÚšßÂ|WÑM<Å=Z»£¤mÊÇØ²9é0†8§ŸâlI;!ÞW¾>#+{k©¼BsüýnNš0n:4pù{Ñir+¿Kvâ+Ä_#Ûü›´|»¨ñÍ©ó0Ä2²ˆ…çÞvL:ôÓŽC\r±=1Göè XL¿-]f承M4²äE[§žzêTÚIVYWhEHÁí9+¬hã;a…4æaëe€WV]lM%œP?ÿ ¹FÞY2– ^f'‹²ãÌŸkég•ÚH_eœ'ÀdhL3^©gñ¯ÚÐàÄTrüНPæ¹'[ÝIv¤‡¸ÂÊ6½µÞh¤äEËÊi_ê~²\m΃†± ü#»âI3 L1ÜöZ҆ƪ°ÂM>ÅW)ù,‘°® S´“¯¼|•]í\¨Ù–Tœ#/+È“JÉw»_Ûl} <7ÀLcð‚wi x†XÐø‚/áºI›)JÕGáª~&Z¥füd7ÈSv‹\Ë:×Ìzú^$!¾ß¶sïL×݈×pºDxɽŽXÐ0 Êç:Š/ÿ¨šü?`Žô2¡5½ƒÅ­ä\ØFÎe¿'Z¦6üÌ2 #‘A‚Ú¯­mƒ—.3ã˜`€ÙæÐ0¯à&VaD,h™?×pžîÔil,Œ‚eD>þSãíÇBD,"³fxëCLfs »d#&,Æ3“¦La4þáp=„ÀIEND®B`‚eric-6.0.8/eric/icons/default/pim48.png0000644000175000017500000001034612342633755016671 0ustar piotrpiotr‰PNG  IHDR00Wù‡­IDAThÞíZyl÷u~3;»;{Ÿ¼u¢nY´,J²å–¥AR9¨k×iݦq›?’nÒÂA´•$j´úG 7pRmÒ¦mÒÖmÊ:-ê0%E)QÔÉS¤¸¯å.wwvgfgú½ß.Ò± V“ …ápwó›w|ß÷Þ›•dÛ6}dú€ÿ|àPÞí;Ñ,U,›Ì q¶¨‚¿ù=£v6ÅÙª®©­ïó¹R…¥ë ƒH²d9 ²m‰T§LŠCŸóo G®`R×Ôàìv*ÒÆ€ê|°!ä~¬ W “9ý¥/?Õž»g:ZC?µþå‡<–m·<Ê#ñ€kgKLÝÕv¯øœ~·Ë!‚÷ý·ýXú­ŸY¨â CÖñ>‘Ç)‡½ªcK@U:ãAׇön‰wøTe}ЫÈ8Ó̼A2RSÔ-ê›§=›¢´"¦~ô½þ¯UèÏþu Uu8·Òžº »³­ÞÛÑQq`¥JAÝ´(_ªÃo% TÀߨXÀIkê=tgª8væúÌæ/<Ù^¸ïà× ÐM±ÎL·¹y' °+p=üñÎú ñ ;ñ»ÉãªbŸƒ&ö2-ñÛÀ“FÒ9ÁD¦Œ³Œõ2¥²:Eý®•ªKîÀÒ³÷•ÿ|æn€lÚìu+ÛÂÊÜ º6Äü.'ÃAªÚ+œœ›ËÑœ©S<«:±°‰]%³x—‘‚ˆßI4U¢Uu*ýõ¡1jÅù³¿´R û\ݳK3`ˆHUÈ4EÔšðò—"ïö©ŽÛÚBE|®fàWRaÀÒÝ0aôKeRU/ݦæ¦FìY!‡C¡Eèâ$ãÒ©œ.ðß È¬Œª4—7h×Ú ¥ætìeQ]ÈõaFä=gàÒ`FÁ­@évŸ[yÄãw<ì÷0Ùœq¿ê §ò“%„Ó´•Jš8  „"”N%…Á& #쇽˜†ã½9ꢉ™¹ \(Ñ@²x‰S‰¬nõàpÝ ¿¼fê]Hæ}Àù˲;%YúPÄïÚæu;6øÜAÔ¤eÆ–aL7™,ÒPª@û;¨1â¦ááaR…Ö­_OƒƒC „ijjš|þÊ#+ŠÅâ >Ô8A„û°‘ ¬F×Çót~`Ž>³o«–àGPUâ—c–¿¹ÌoÙü‰M/ù\Ên¨Â ÅÁppÈË fe˜È”h0‘§át‘îÎh”AšYAJHñº&?"¨’Ï룹l–îÞM  R¼¾‘~?Bm[UñG¿êDõ+Sا:!ZW R+ì0_„0<ñD}®¨º·½3ÂsCÉÑåTÞ**"T©ZMý*U¢òZdÛ£P4Fþp’(S(ÃX〡¸àPZ&ÝvÕ|—S¡|V£2ôŸ+5;À"ÅAàåìÔlï_ý×ô…ýí‹(Ù¢¦ší¹¢IoöNBÎ ”„”Í ë  Ò©_.R‘¼TrƉ+¥†ôºÝlA'ŸÏ/ÈÏžYVUjm«"B]󒸙$>—x $Z’lš™¥äxŠJä¡`8&2+-‰©V¶X¡Pd¹ /‡@äÎÀÐÖ0ðÇuõO }fY y2‘R±HO?(ÑÎ5ˆ !QÑ”éÒÀ õZIG•UAºœf §[A:Žw9|b‚Vñ.‰JŒß y‰t]‡ó%22"®ÐÔL2ª÷2d×ú%þU†B^på‘¥ȉÙâ[©¹²xÒN[W…‡€E/ ®—èñ6‹žØ&Ù‰´:|"¥›£yª+ö‹ÔrÊmX;6­U ‡,î,ɲÈb¡X T*E¹\ŽRÉ%q¤q0¬*hE+­i_GQÔ .œÈ›p¤„*ŒXùÂ~ç¾e˜×ŒîáT¾´qE@å7Ö·ø ½%¡ å²I>E§WxaJ\m ››ImŽÐXª‹nÏäHòF…ô1g¸hée],K 1MÈ*ü:‰P<ñ 6˜€¥¤xH]À0¬äJ,x¸q @ pÍI,ÝlS<à~±Ø &滀ßÇcA·Ð®²LLÂÁ5ÁãvÒÏÓþnâB&*ÔÜÒLþ¡eæ5 z]"’• “Y§ÕàW¢‰ñ11¨pG›˜ÊR¾£¨Öõ—p’Õ&kÈ45JAë™ÌÃJm&á¿e¹Êô0f‹¦¨úØ2ÒÙr×ɱ\a¹Œën‹ÿ©k„]ßAu±¨hqÝpê£*õŽ¡d˜à ñ>­P³B¡(êˆê PEv‘/"‡·@n¼–¡HT‹² 0H<;µ8ð‹j-NÈ0‚#Ö2îC%4„yï²nT3ìÞ[ÉbrûÚh_†¼qèEœÒ‹·ÒBy\ÞYk8`ª´º9Hm+$!.@Éé< ¥y,„Þ‡#äöA„Š“Ãt¥úâ豼.´ \­9Û2Þàù£ÚÉJÂ6=3;MS“IÊ¢Q¬óK´aë·¾qèNÓ²™øËß¾ðú+¿»ó)©ÖÌM a¿Bãú·®ëôôžvÚÜZ‡m‘z‡ÃQM+·>¸™^FwªCßse(“W^,Wþ3Øç^‰…Ì–uŸíå Շ܀ "pRA¸›œ¦¡±e3ÓTFËáFÅŽÅ(¯£5-èÃPNôOþŠR͔Ďا¼~rö7v>Ç ÁZÍM>R÷ù'·RK}P•%t¡dRY¢aC5„ŽÆÜB¡ŠeS@€1\,[KºÏZ”±WÜ©ƒ|³ ¥“ã4™œ ÜÜ´Ž;ÐLíë6’×õ¤:4™bÚ ‚‡!sŸÂÆsÅÆÉ µíº0˜7ãkŠPÉú¿µ•K¿SàPt˜•êdÅÆ3lQ³j½=ŒÊk¦à·bM­/â=þ\æ(B¦6Os€Æèt¡¥‚P®¦–U´±ci'½:Rº9ZpíÞ–%Hwµ7²äØjŒ™{•%“™/›¸5z¡o`l÷Úíkªƒ„IÉyjŽûµ¸PYb¯ö)ÂøZ÷(I´({ÕF®YÀ­ò˜Éåil"MiLhåb†ŠA!ªUkÖS´q5z0Î^¾6{ò[¯_ì>>’º–$g¬éþüoöÿÚãNŽ#ÀƒÁ³SƒÂÐAôÙ>•³úÛÝç/½ð4ÀA/ªi²ç󈨉ƒª’¶˜»ªÜ÷skÀMOt<ÄpæÑ}NM¦h,¡Ò2VÖ5Q¼n Š[ˆ\.=Ñœþâ¸xêø¡ÁüÄõY1ºq'ƒ˜Éve.äušh¹¡€"`—F ŽžëÏþ÷ï½´£¦\jÏù“—RÙÏ=Û’)öR]ÄWíïk­­½Ø¤SMâHÀ‡“èr¡oG”f§e´¬ âG¿³rU+…cõ £W8mË E–éž g'~çë‡ù¹(gµ­Gv<ñÔÆ?ùÚ×?¹jU›gxŸ§ìÜ¥í2†–††zZ¹ry>Jg*t®÷êÌ¡ÃG†.ô^›ò™ßÚñ‡¿½/ÄQ¯ö5U8kÜr(˜Txt¸“ÌÒ¹ž¾â‰®SÃÝ]ov%®¿ýG¹ÆM!ïÿ›ïfؾ gnß™B_‘0lgÄ*„T0̨/mÚ¼•"a? 'óæwß83~äÈ‘¡s§ß™¾6 tó|ZN¦'õß{î#÷jm†ש<>½9š¦Sg/Î?vtðR÷‰Þ™;7Î㺾ڬ›]0Ú¾‡'Ïït€¿D(L ÷Môô;|\¤âuuè{<âIu6%:Ýý£±_}ö7ÿe61”©LJ†Ÿöµk£_=ðùuAYÈèL¨çêpåøÉ·ÓǾyåbwOizäR ÏãK~_ßÐ` Y>f3'Ï]ÿõj£?Dâi;bÕ1 9¦Ñ¡[Ó0>Åõ£¦ŒÏ¾-»?¶öèÁ×_Tç§®j‡½5qâØ‘7.Ÿ»lk³=XsG¢¬¥ð]jÇûúЉŸ=Nžï>}'o|j£O©‚—÷_xâÀ]žyæÙÕí–P°L 0ã¿óüó/¢éŸ1<{Ÿ{ák #}§Í±=£T)^Ç%·q¤`Øü}ÿbapXzðà oKÇ«—†EfmÑ6ø€¥h%–ýܞȚ_ú㯾¦(Jë’myŠY‰Ã¿lz¯Cy=&Š©ç/ßÔ¶·íòT›·IP-.õGOœš8zäÐí+çNöù©ž…TÃò|íøÙ|KÉD¦ŠvåðÃûŸØ¹E• ê¾x5ÿæác#'Žîèï¹BzöÖÖ 7ËÊóN,¿TÜëÏ{~GC0óy>ݰááv9{wr¨¯tfNð¸€ëJÿ¾'~WjQƒY-KyŒ~ZFÝ— üâ¿üŸþ]EdÉdIEND®B`‚eric-6.0.8/eric/icons/default/editCut.png0000644000175000017500000000110612342633754017322 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<ÅIDAT(Ï…ÒOHÓaÇñ÷LW ó Œþ°KCC&­Lè\îäA‚nó"Ô¡èx0;Z—AhÕ1(ŠðP.æˆö‡¢²‚-Ö?(e çØ–òûxøMÝÜOå{y>ßïëçáy+…Ç ÇZ8|ÇñÔäšehj’Ž:Ü15I¿=fgÃ#¸V³+<’å¨=>h$rúVs_.c$8`w..™7ïÒ.í·î-™ l·Å‚P2õ¿ä ‰&çÀb1™âtݼ.xÇ£qºè2âGñnŒ[ÜCó•r¹s¸s¸\ž¯¸‡hÙ ‚‰é’¾¦¦KJL\7][G´h^7g48Jë¦XÐÿöGA¿u~ŽPì¡á½ñî¯4öÀ–Øåÿ˜ù¢9ý*ìònq<{\TÔ̪¨çh¶Å4s‚z¹³?ý9ÿéƒøûü¡ŸDÒC/Ûj0ÝÌð­ºïƒõ•ØMªÚIò‰#UŒ‡ öbˆÜÚÿå0%ÄA1öYø ~!¸„É©º3žAœ‚“\¶ðv Á ÆîaBÚ0,ü‡«ø¸Mlå"5ØÉ+"ø¸FÚÂa²äyÉ^ÑX¸yMœµy”Íjs\¾Ÿ¡Ë„IEND®B`‚eric-6.0.8/eric/icons/default/resourcesCompiler48.png0000644000175000017500000001124412342633755021607 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB7ÇMS pHYs  ÒÝ~üIIDAThÞ­šËYvÞ÷|Te«X,Ylv7{Ø3šõ i @ Ù Û Ù´ò_ ¶ @ðÀÞi­V^Ê0$X€lHÙ°ÇmÌhFîôL“ì&ÙE²Þ™••ÏxÝ{‘‘•ÕÍiÙ€TEfĽçÜûï|çDª_ÿWßûݬ¨Þw•_ÀñÿáP€ü_ÞÇî]}V)e#k¥‰ý…úó¿ýÓ=ýâ6Ë«÷¿ûþ›ï|ãÁÞžµ6H|¨z”R_2FDA¡@©/~Y?¯FkXŒB¸6Fsm­]^K(­Q Bú§Ÿòƒ>?t>üåëÁVÎûíý­;ÿâ½·c£˜çÆŒ6 ®OÜ""(¥ÐZ£”"ø@íÂ;Ò kíÕ"H=îêá'H MSBxïÐJƒ¼«˜gYïû?~zRV>~­Zk7OÜÁÁKDi$(hµZXc !E³¥ˆH}†€óž$‰‰Œe6Ÿ£µ&N¬1õ}‘pÞQ•‚àœGDH’ïk£Ó4!ø@!MPPU¾*™L¦NkíŒy= ­RJªªª 0Q½ZDzÌÈó‘)« Ô» 6$PeUÑétêöïUU¡µÆ{OX@¬VQ”Ë,« WUL§Š¢¸vï—hð¨”"Š,Z›¿ÆP–%Uåˆã­ÕrV­5JkZ­y^P- PZ£P0ÆEõk-ZkªªÂƒµ–ªª–ó×;ýÕt`£Œ®0¦¨Æóv»…ˆ u=¨Ö­5!²,Zk¢(Z:Þ8*ÞãدÇ7K£›ØRJQUeYï„1õ"v;]’$ùjdeUCh]{ܬd3¡H ªIbjöj»kH5«BÀƒ[À¦ËÕ8²¼§™sVÍb,ç6ú ¶¯9´j(M®j!,œÒˆ€s©ïók- –5FÆq¼„Kc|‰Æ±æÞÕù”ºb®ê¸j>W_¡ÆPcìr7’$YEZëåB@€(Šq.[h3q^ä ¦IÐZ/– 5D¬YÉ'`¬Eª 瑵˼ÓÅ?M±²ËÕК(Š–Ž5Öà·ù®,Ë%$‚,°M½úÖ´ªçQ‹}7Z u²cq•¡©“൴­~~ 4¬2L¸kÌ’B›àjpB Š"¬µdY¶Ämó|C³^„¼ôñ ˜Ö¤à™7Ž IÇóy†YŽ#Ë|òóbÀ®L'„ÆÍbEŠ"§ªôÂhµ¤¹8Ž¿”‘­1ØÈR–Õr·Ò4áðxÊÇO^ðäóSÊÒ‘Ä6Šñ"$‘åþM¾y›;·61Æ.Rájiò•ZÕ<ÆZd¨W˜f¹;"urj¨Î9·HÿBd4E^¬R(£±ÖE–óË9/_ñ†9¢³Ý"îl£#ä#fóŒW¯26Öר¿}ƒ8Š@s³¬¤(½cB%_¹K‰°âqÃûÖše€zï—÷4Ž—•c>Ë™ç%ôÖÚ´Òc *ýQÆl2â—ïŸsçf:qœóÏ&ü‡ËùpNQÔì4Ï ..G úL¦3í½7_Ôc¯u *K”ÖXkkFXàûu´×<Ón¥¸ ü÷}J6:g{=¢wëûwvÙÞÔ G9ÓÌ£”bxürܧôõ´±vŒÔ ”z‹ÜÁp\°µ‘òèé1ÿ“'l's'£t|9íγÂý|‰¢µ’ŒíÓÐèjR²¶z¥ \Nr†£Ý0g+2TÓSž>+øÌ¦$Êcó÷×K‰qÓŠbvQ'¡N—¤›p/-ÑÅ9Ÿ~VñØÄœžžÓfÂÃm˜ybóít{ûÛÕoüÉNÿò·&×Yh¡Ôš$\á¼Yí8Ž— ,Т𙴦rž‹ËKNNÎè%÷;†[þìœ'g—œÍ#înÂv4§·>¦º8ßÃ6Y¾Õ#é®ñ޹d^qqzÁáØÐ*¾qËó­=MÈDöÃö@Ô?¹!ƒéýßüÞGU ÿûÿø=¹ÊÖb²W)½¤S³ Ðj‘dÒ4fYÎé`Ì«/˜œ½àáú”[霶/ÙO…wº”ªÃzì PŽÙW`4J Þè|ÀvG³×Bz“~–"å”C&ç%ïl(z¿oüàÈýÚ£ÁÌ?Íã5àû@vMŠ„E!¡–2âJ#ùk N)¨œçÅñˆÙñcÖDzµ^‘TB¥AˆuL¢cŒöøbB˜pEŽH…6uÁ"Rá²Kl(0Ŧgl„˜à+T5cæf´"E¼Cøú¥º#OÔ{c¯Íß-P@ð~›ºiò@£Ú¼&¡•fž;B1"Î_RTd0qŠ"(DR',”ªÉê«òÓeøjN™Pæh1¶A$àÊ9“ÒQú R‘nêÛ;(³ ‘þ’œVJ]O­V‹²,)ŠâZ¶Ö¢•¢ÓNyðÆMϾÁÇý1Û“ï³Û𱽡‰¬Bi €^ÈVe5z!ÊTcADjÉ#ñ J!!”â;QŸ½5GWÅT¥€/ÎS8á|\òjqœ÷˜Æ»ÈÆ.Ýt£®—Ë1ƒâœ|zÌÜ]â\É­Í„vlÐF¡Œe£• Úíè¿ØÐŠ7Æÿòî~ü¿÷êKZ¨Ñ> Þ›^­”œóœö‡œ¦ô/3Ƴ=°³h§ã R­0+òÅPÝÄo¼Åý{_gëÖ>k½M”RLÆ—ôO^pzð3†ù3:Õ9ÝJˆcHBTÀF†n’ªýí¨}TÚw‡£ìŸíÿãsÑkq~kÝ,Pëï–iœh¨?Ó̳ŒGO98xÁh<ÂD)÷72nmhL¨ûAP¡Á!̽bf¶Ð›_c÷ö·ùÎûï±g‡^·…1†áxÆó»|hÚÌO,³20wÖhcë*‘€±ZÝÙNºo†ô[ßõz/Ò.ÍJyt1Ó_ÓBjQ WUEÇ×´¿VвòÚ “ĤiVï¢V BsòÉ”|zˆ„@U:Æ£·6ýB_¥®¯Fkô¢2 !Ô )Œ5¤í¸ÖEªNDAšâiA‘&bÃD˜œe õefÓZa‚«e¼Ñlô":±Å-;µtÑÊ UÝ»6Q¹@‹¬j!¹ÖÐú*Îh¥é_æ|8¸ÀKD§p£—²±“&«k-e£­¨Co’¡üœéܱѱ¶6H‚`Œ&Œ§%RM饭n« |U³Ÿ0/=ãiÅp\’ŽÄzN. k¶–eßåª3ßoC­Š"K§s˜·8?é0) 7ÖoïØ@kb[SbÕfw='^Ÿcö¶è¶c”Òˆ¼ ̲’W'}BÞgw-#nµQ!G…ºY\–ÑÜ˧GÎvä|ÂfG«Q¤¦Ö0½j-ÚºÞì†Ö5–—IMÀjÍþn—lú«ôÛè©]~ÎX3//"«QІ8ЏwSóÙð˜~¢(ˇÜÝݦ·–‚Àhšsx2àñ§OØ0ç¼¹M]—c4ÊhB˜—ÊŸg냾Ù?<_£©C*:~d)~jW«þºWãtõ¥CÓ™KÓ˜¯½¹ËÎö“¹çr’qþ2¥<Rú òÊÓµ4%U²Ý-ÈÉPÓ1—ƒ#Fã JE‹T…¸[­1·Ûs¶:º* JЋ& 2(qvsâŸLÝ;(ñ—Vg)£••^Pch“ÌV3±RŠ$Žxcï&_‹#ÅËÓ!º3^LvÀ$ÃK°Jy”d$fÂ[z½œ£Ñ1'ƒãy½¶pkñ·;cÃΈ݄²ÌPÚƒÕHX4?M,>Úši›Ï»Çýik=­´6FÎÇÖ§J6Z…ÞÛ‰Ôý=Qwwb½½«¨]“BU8£JÏÊpp”ÉÁ‰'—­j£ ÷n–¶×ÎãÜÙП÷F/²·ž«›ÿ£ÈJ±ÊB„81xå«LùԳ˸˜ã2›¤®ÊSïŠD¼‹%+L} ˜ÖÎÚúÆ»O‡·~yZÈÛ=;XŸûö|\ôÆ™KŠ–µŽ§U<œ‡4PõÚmkÖÖk°gUàÕYåò\_žȯÙZ–ÙÛ—ó`ýlpº¾Ñÿø]¯Ï²äîÑÔo‡BÚŸiäGŠþÛ¿ÿÞô+º×1- Yœˆ³ÀTŸÝc1m¯ÃšÌ£èîdΣiž®˜¤±¾q1[»ƒUo}çÝY·Ó1¦Ó©5d·c0Q䆛gƒèQÀ>q÷i¦º½Ô·L4]W¡sœU;߯Bò‰ ñÿúÁŸý~þÚæîhG/ŒLNÄ‹k»8ÍâT@6<}z µ Óø-Upãx<üðòìŧóñÉhmkS­ýW6¶¢-Q¹ÌòŠÃÓz¢²¬e䢸uy8mý8v¯þúùÿþãÇí·owoݸkߌJŸ|~:½ùW?üóßÿŸ_Ù~Í!Ô?þÐ@Qwy+è… 7:ÿüYYLNmÜŽçãÁ¬Ê§E𕟠ú7o~óm”¶Ÿì'ŸLxuV÷FïìXlÚ‹DˆÒÄž^}öý—½ÚèþâšÄÝODE^ì˯|GöÃàW±¸v‹gôŠP®Êe28|añU–'¦zUùÖã'g»Ñ|Úk]@Á…T·ÛÉ«?J"xyü³ >ÿ |þAqç×ÿxvxö«?ýŽü¿8°êÄÏsL_Û«ÿYùÌ7÷G*;ÏÝö'‡ßÔZë¶ÝÔ­8ÚÈHfF•?K͸¿'4ÿëïäÿÐOvþPFï6}¹IEND®B`‚eric-6.0.8/eric/icons/default/fileSaveProject.png0000644000175000017500000000202612342633754021010 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ %P„tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“zIDAT8Ë”ÏkœEÆ?ó¾ïîf—dã&«󣉲‰bQ-½ˆT0ú/x*xó&r*¼ ô$âÁ«zÉ¥"íÙõ-M$VÝHÒnÒn³ûînò¾3ß™ñ°›6Tiw}``†yøðÌĄ̃·VßlNÏÎŒ¿úÚëœ:5€PŠ Pô§Ôþªñí7—ˆ[ÍøË¯¿ç!ŠT Ægff©,-³ðô3Xë8¦+¥P ™(`d¤À7~çÇï«E¡¨Ýn³»{k F„øP?`ñ 9R­i6HÒ„G‚£("ŸÏã<8ïqÎÝÃyïñ¾·ÒbÑb±¸ãS= ìœÃ9‡1Âabè¦æ~VØÚ"‚µv°uXR#ëNl:ÕƒzÆ:´¬Xœ³ƒ%±¤ZpΓ‰Â‰ý½J¬ó$Ã$¶Ö²_¿ÉçÈ ²ul-"B6›etlŒ0 ÿeJÓ”¸ÕÂZK†XkY[[ûôAŸ1¦½µµõÙúúúf$}ð“SS,?·Œ1†‰‰ Êå2*À{jµW._&nÇò¬çÏŸG¿œ¾DÄT«ÕB«Õz/cHÓ¥ûûûl\¿Î+gΰ¸´DXkkÜ%›ÉbÅbŒAD¨ÕjÿÕ@¦R©¼],¿Œ1>MR´ÖÄ­˜½zF£AÇÐh4hµšhc°Ö(…÷žêÏ›”&Ë”&Ëüôë&Û훹T»PÈÂH¢¨Gð´#0Wáâ…wW†ÐFÝñÝNŽz·ÀÆÕ*çOä¿]­"èJŽNÒ»ãÑ P¥ÝÔó·žæ…RžÉñsìhK&„Å—Ï1Vš#88BÌN¯ãa+¥8JáÆXY˜ctŠ#` tº ä½>±RŠLµýnS ‰€ëû†ê¥È…‰@ 4°Ó†½Øÿ“xj\1½³EØ€XƒÔ{×Ê9èv¡ÝðÙâp×ëõ?;[W>z)$ýqBåþؽÖóþ·5ø Ö=ÐÄIEND®B`‚eric-6.0.8/eric/icons/default/warningPrev.png0000644000175000017500000000225212342633755020227 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÚ%Q(tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“IDAT8Ë”]ˆ”UÇç¼ï;ß;3ËŽî‡ëbn’‰in~„¢±Ñ¢ùQ­²ˆ`Ð×M7BT‚]AÑABäEÖ¦D¡7aáE’)«‹nµ;ÎÌî|ìÌœó>]Ìä®î8çžßóžsÎÚ鎎F/í>±ûçÿíïåXöHv&5š:roˆ^º‡]½ÑÞËÇ_9¾éÊ­+Ë؉Ë^NlùplÇX&_ÈÝæ.=¶apãûF]íi¦òS†ƒô„mx|ߎ}ëWö¯$?•µ0tqðN\â|þôOÞ²u‹*5J˜šAItF;yr$ GÉÍæ0Ê,Z÷Bðóô„ ïÙµg}w7¹rã|ñéèÏl|d£ŒºS½ƒ­Y‚Û੎XÇWÃ[‡3‘d„\9‡UƒÁŠeðÑAЦ¨LÃ`ë;oIGÒK€ñÆòT÷û›Ö>î6œFS‘c1Ú`•ÅŠÅøë[Œ1؆ÅÖ-ñXü>=Þ‰KVŸîK÷z¸oR½¤Œ¬g±®Å8¦™ ¥ú.Üúk-ÝN7è…h×í÷.ÆWoN„ÊŒ1øaÑ‚ÑãŒj©nµEA”àkŸ? WA)rb=qû•BÒè$µ¢@ðh–ì´^¿ʵ ¨…е¹ÖØVéª|_“Pbƒu-„ZÀ(ÍÉÖL´Öx9ër0ã.zyøü™úPÃD—Åv(P6hÑ4ÖÅš0¼¦ÒQNõ<ÇþìrÅ_+—.ðéâ_úÿ½R©¼ßéðæâ‘„ [e{@°™Äëð  ¼HãöÅíz†×Sµ ïïÛs•bi}Ý·vºš÷qw*蹺‚ò_4°nÙ&:ÏäÅX9•i^z° }ÄÚ­òÚ\áÎ8EG¼š'T9¨LWçú.»•Ãj€P²‡ëãg¹þÝ9B)­Â+ÆæÏÒû`wûŒ†¼cž¥¤N&fÓ66ràhgþ‹xùø¶ä*pgqM ×ÖÁûLn÷kÎööló„y;÷÷Ì N.PÊÌuÒçà>–ÎqB>¢'ˆ&Ä3H`tQ±ô±Òz–¶M€ölñ­Êº°ø~8ë¹ß¬õBµl(Ø:JÿŽ“@ùÀï{Cи¥hsÔ¿ æ}¹Y'½N¢&Qóךo8´Æ€AìlXU/ù7çÅ_­ÛWgk¯9©`¯ÓU¢(2ÿ6Nþ›8¤€ ÊÉTE§‚+¼¢yµ].Óïª)r•H!"RD¤Š˜Ž˜ G¤‚H‘\DäöC2sÒ›rÛûuu~æÔäÑÆ_õšÒ-ßÀ6ÿóŸ *p3 ñ¹«¿ò çNIEND®B`‚eric-6.0.8/eric/icons/default/up.png0000644000175000017500000000214412342633755016351 0ustar piotrpiotr‰PNG  IHDRójœ pHYs „ „ªâcytIME×   >’yPLTE5f:pAz? !D $J $HB|'N1]6f=r "E %K (P,V/\2b9nj Eh Gz#Dt$Gm&Kh)J{)Qx,N/Mx0R„1Lp6X‹8V|9\@c•B`‡BfšEižFf‘Ju­Lr¤Mr§Nm”OtªPlŽPn”Ps¤RsžV{²X}´YxžZz¡[y›[}©\¯\‚¹]{ž]ƒº^} _¦`€¨`…»`…¼`†¼a€¡b¥c‚¦c…²cˆ¾d…¬d‡¶e†®f†ªg†«h…¥h†¦h‰±h‰²hŠ·hŽÃi†¤iˆ­i‰®iŒºiŽÃjНj‹´jŒºjÄk‰©kŠªk‹¯mŒ¬m‘¸m’Çn‹¨nŒ¬n­n®n‘µn’Çn“ÈqŽ«q•Êr¬s­s—Ìt‘®t‘¯t˜Ít™Áu™ÍušÎvšÏyÒzžÒ{ŸÓ|™³|™´| Ô}™´}š´~¢Ö£Ö¥Ø„¨Û…¨Ü…©Ü‡ªÝˆ«Þˆ¬ßЍÀŠ©Â¯È’´æ’µç”¶è•¸é™·Î§ÆÛÿÿÿw ˆþGtRNS !$3;DJ[`z|ƒŒ— ¡«¯¸¾ÃÈËÒ×Ùäêñòúûûûûüüþþ\wlqbKGDÒàØ®°IDATÓc`€Yy,@ÂÜR‹°Îâ-z˜¢*n/檡‹ÊXºpá´­"š°AÛI Xi&Ž"ªž¶{÷¾ý{vçi#‹*ØL[³~ã¦õë–ºª"D9MŠ&Ì_´|Ų«¬åàÂ)uí}Óg/œÑßÑiÌU²+®hìž4gÎäަʂHMˆ¨”ERNiu甹3{jJ2’cœ”ÁÂZQñ©Yùeµ-­õå…Ùé‰ ¦`aÝ8o¯æ©KVÍër÷ô ‰Õ‡˜ÂÂÊÆîSµ± uÑð¯´\¾ 3ð°‹1 v”ñ}dF"©‘±XÆA×ý\£Æ¼ñ•ç?¨x˜šS˜[*߇U±X*†mÀ¸î³Áér¥îÆ™+i5Ê&SûOIZ|ÅRƒË1WOêa©Ž–}ˆùÑ<¸áÃé0I"Îtîo‰Ì°”`äqFÑ$>b)o][8I?vŽÕ»‹Š3â”ó{ö›ŽxÃ>ЋL‚W‚¾?j ?[aýzÅ›Ó}ˆƒ>Çú/œ½šQNï-}f K Mêõ)ÿÛPRpJ eãŒ@Ê5JÓ¹#Ýw& —$c¸&b¯éþ#z~“~³é7‰ wÒ¹­£”?Á1ŽßÇ>ÖàUºn ÀY~EþÄãà—ø6~¶œ´‚ÿ9‚³Ø—+ÀþNçŠR*×ËVaeÂdV1FÉ–Š·ˆ_º Ã&`K¢V<çô´ÔÇLým‡°JùNнÔK’L{;S°ù„Ûó)Þ"8Kˆ5GÌà"ÂÍ»¿—7˜¿Û]¬—ÛãÔÕ“p ¶Æ¦ãV¬ºÀo9a ¿‰È/ÊÇsš»ÜŽ <Ö l¥º˜3’ÛX=ˆã ¨mÇ`«5©³‘qã lwYÁ'ÙA´ÏsŸæÂÄɶSV°0Ç•â«è”˜ÀEÀh¸ËxðŠòDdzr‹Ó‘Sr ±—~ÄŠd!ì¤úÂSgÞu:dDÏôXXæþå;à°{.VÄšaW†€Uª³ŒlH (~p§¨CF¦×:xoÞ ÌßìŽÂÒÔ×=è¯ùQU[¸ü]4V4úºƒ¬ñ[s# ôçÂ;žä>Îñc ½¼§#!òŸߟ¬t‘¬ÐIˆKxĘ 2#õ O×¶  p9aúxë 5Ìݸ4¼££ãéÓ§8zmÓû<¶÷õ¾Š!¢±¸UZʶñK_ŠÅ‰ŸárI6–‡/$x|S,Ù¹?·íl¤ÈRŒ¥67ƒgŒ nÝ¿}…>§Ù€!ÛûC†Æ\C\/þMµÇë*°6v-Ä[—âjÑ ˆ]ËÈßuÙoô«aÆ:'T×ÔÑ|~æDjcƒ\‚K·²à+óÿdxDN£¯9vŸ³f;4_ Tœ Ü}·#Í ®û-ðS^*3‰Ø¬=Fù©Azè5M +ö®WQ¾¶¾™ß`öÐpÒÀ§‰(¯¬P>¿v/ ?(ZÓ·±:üö~]C-3WÂ&j8æEŒïOÌCAi&RóNÀ;Êîa³± Ä_G›ÐÈk}9BvdöÏb«œ”§g‘éñ´;”Cz[Œû¸P4ê»áèi17ŠoªäßM‡Û¡ pHàÂÜo$^ª!ôçØfÖy‚oe.°Ø:–ÓÐá{¿¾¡áÙ°ðÐx¸'šP¬p± a,"ó6áÂ-yyÆõóeÇò’±2r VH'#à¼ÛO[c}Š\ö›"èx 3xEЧÞí@áBCiB[< *G¯‡BD9]"ãÁ– ¿wç¨C´e‰JÏ_Ìðq@éÃû¨©«Uº×ƒÊ»¸õèdŸ¤X0aS«­L_™t®¤²` 5ó¿…eÒÏh ³†§ŒJ‡½æˆ;‹GOÊåßQ)ªÚ`²G?‘æø.`ÿqs?˜³s£?bË—ÃFè+Rè%B€½)Qpþñ›vþAÕ],M2ƒ],މLæÒ—óã¼[þ¤fUðÉÍX.5[Ø$¸í·AâÅ#õôÊ’·[U…m0ÙcVˆ>Þœ1@鿊£®¾A™^Êœî|Èšnƒ ëú9W–+Û½–†‰+­°6âåýºú:džCrž ±ƒ±0a< Šl$‘òNùg/Pt¿ø´WŒ+´ã°Væ‰ìßrËèU÷Ös€˜ž¾G=¬ûaGüƃÏ{70‚–û sø·ËJ”íJ+ Á[Ƈú\}åýÚºìNó—Ằâ³nJå7 –rOæ?HÕÉ¥*uæ¶©=Š{ËÒ™ L‡‹öfìÕǪÂSãZì¡TÈd‘æÃÇ£äÁ]e»ŠÚ2Œóú CÅ£•÷™wƒÎ{a^Ì6~$Mƒ¹!uHÊÝòÂÀËTdæ2yyu›.Ó%˾çe¨TÖ–c{Ú" bÎHƨ4·ž2aÄ3UªiÁý'ÅLºúžD»ÓS»ŽÞÉœ³*Õu•4Py´r¡ö´:à@qävx|Ö±ëaÜ.Oª;`b (é@›1Ði’Œ~.q<ùÄà^ÿyaŠ ÞÞ"ˆÛÊBŠ ..»Ó,McŒç8h‰Çt €~O;ÇêÿB˜4:;”‹7gÀª°-Z€ÕrÜÊ….·œmÉ'/àÙ@66µÈ¢ó¶³õL£øT°©ÃØÝZ¥]Á½4èxŒÄ‡’±/ q"bmwMŒpœ„úúz+¤ür€FP=63Öêm£3¯y*mŽÿvƒÝÔY×R0îÇsÏ »ÏL‰`¼vz 4qã¶j1—wç,[Id4bsñ¯™T±îS­X#ò|¡áÚOŵÖ›¡…ùѺìT·4ÎÄtñú5lŒño1TÐä\ q¼øk´ñº`0Î]ÍzÀ•w°úøLh-Ø*6Òo¦À&À ¢ÀiX ›ÄÎ¥» q‚nˆ.ƒÀs3g«ÊæÇ/eÙ˜±{zÏŒU-ê¥sEɬuƮ׆š ™×rž¥×ªJ”Ü¿{åw±ñ”[Õv €"M ÒÅ+Vjø.bG«Š² è*Ò¯dQpÖ7³Îcx¦Lcký¹\¼1}ï^šZÕ8zX}>'mÙnP¬*|â3 }f~ˆ€¤ƒh¨oh·D~TU†mi‹!jšN2ïNß«‹K‡Áv§dTçgSµsi¼þ‚ÜǰqêÚ K˜lMWm,ܽÇ.ÊQUS­¢|æ­¬;!b{^±´¢\Va‹eܦµ$¶×™• Å:R·4¦d°æ‚ë=ÿž: Ù¿æ«øe|Y‘CÙµ¡®®Ø96ê~ÄÌ}TäYôÅf©jf*üã ¶qÃ7Ç„u~\ç—)Y Äw’÷íVF˜6šnTûÐ\™É(-³¿'²ù]‘ãŸ' ¨k²1ÍÈ $ц¯t+€b¥nJ .Þ˜¦Ž¯¾£Y–jPŸ)<Ôy€¸Æåw‡ÃjŠ›jª«P¦0@,Є­Ÿá§Âp½4×ïgã@ÎFvUî¹.Ä÷a>\¨÷ 6Ppzç¥(2ó"õ0mïÇ°æ³ ¸L†i©¨r£ã0_¹EE€õô¼€þçFrŸwþô.á_ÙPÀ4.»SÞ?Ô¸‡Æn5%(Ý¤Ž”-§ùo6IˆƒÔh%][S¯Ò³!y›³§Ušmö±æ?j ×cÆìäœäzö+Éy:O"ŸföÄœé]»Xî[v2î«Æ²¶;Û ÀB=Šc¡Žÿ¶ÐÆsN=XBÏ3H¹=äJë¨7ÅbÏ”Òà0—¨Ñ½^ê.ù«fï¿Ã1U;Ø_¬Éº»Ë߸ËH=YÓ´Ëx„d=]ÛÑïhRx¸£Œÿþ×Mzþ=öúGö}{Ó?ØÅ¦’‚;H\ `¹ÁûXƒ×èúo¢è?Çßïø?ÒÒI+0v,IEND®B`‚eric-6.0.8/eric/icons/default/sync.png0000644000175000017500000000226412342633755016704 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs¯¯^‘tIME× 'Ih@bKGDÿÿÿ ½§“AIDATÁ]¨ÖwðÏ÷÷ÿ?o:5Í—s±kŤè2Õßà^÷úÅR°þÅ´~íÄç<·ðÙV2È™œÉÈ€I¯ìÝÞþtî¤ÙX¹Otj)·@$ªR{ÿŒ ÿÈ¢¹6¤>+‰IEND®B`‚eric-6.0.8/eric/icons/default/projectSourcesPy.png0000644000175000017500000000172612342633755021255 0ustar piotrpiotr‰PNG  IHDRÄ´l;IDAT8Ë••Oh\UÆ÷½73™™d’ÒióbQˆ’¤j M,QiDŠ EªPÄ­¸×M×Õ­.ª ¨à"ÝèF°¨…VªSºiÑ©¨¤Mb2Ó43yïÞs®‹™IÆê¹ðmÎåüÞáû.çï=½Î'_Í=tmµ±÷æí”Z¢à…B䙈‹<9¶óç§Ÿü½W¯é>rül9qJE§k‰%uŠ!@(å¶ ˆ{þƒ7_^ù¯þ ×UýÉÑrqú¥©ë i•†UÖåz%áâõÚôj-9Ù«?êu‘ˆ)d˜)Šê½*RÜ2X\Ê™ËËœûe™zÓaÔáUñ*¨J .–Áyš{«±Š ê¨Hp¬TUúsA<÷×oõw3˜°4;¹ÿàÂø½ÏN—ë¾ïäÅ[I±fi7fPDUƒŠÁ«´'nYÑŸÍÆñP娮ÁßC#ͽ§6À7Öý»WÖ䀕U‡Üë§tÔ±Aðª8kI›ëvÔA-ù@v¯Ì¿ñlyÏûߟ{aæ.ùCN6½óÚzZÝ îмjË®¬a hÚV’ÏæJ'®œ‰þXZ/7E6éxèUð²©N ÂdœÐÝI@-Æ[$­Æõ;óåèæZJ-¡øfê^„b¨ — QQéL²{$âÐÄe†òUPÛ’·d¨QŒ–ˆB£lL£"uLß—ðʾ ÃkÆa à=ÆxÓd[¡F6H1jÁ»M¸D w‰vm˱ÚLP/¨WÔ+÷—BŽLV™zðaØ~^Ax Ò†ùΤ®]³(Û‘h”à‘]C+Å\¸è»ü ޱ¸Ò‚zßJÚòRж$ùGÍKJŽ¥O3ùáSÁsOí??:ðÉ—ŠYrYÓšÒ»®Ô»$÷Ö,Þßî™ôG_µÀøÈÀÑ[Õ»c¿.»ñÈD;tMÑ4ºv“è»´á§·tîðQÏÕÛãuš8ú¯µùõ™ï…™ì¥RéÜøÃãx»¯ÕìPux—¾½ v n1ÜûýG[ÚÇ\}í"^öuäÅâUpf;T üKÁž¹É-íc×R+8£ ‰ 9ü 8ÍöÜn=Á·*;ë"­)»Cʘ î¯/ 1Ïrc¢¾ep5=|­:>[³ñb-í§™†4l 7@Ôøq±Zë›­ñðá-ÿó:gá§3a2_Λ«¨ÏR—\fbeì±×Ïÿ_ßßÜkÆaÉ9µIEND®B`‚eric-6.0.8/eric/icons/default/taskPrioHigh.png0000644000175000017500000000222712342633755020323 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<¬PLTEÿÿÿUUUÿÿª@@@ÿÿÿÿÿ™ÿÿÿÿÿÿÿÿÿK¹(0-™×†§ßƒÄƒF²4J¥€N»)iÇDkÄSM¥K`³`:£Eµ$#…Íw›×Џä§Pµ@F§¯Ú¯†”=°!Q½+U¿-ŒŽ…ŠŒŽ  ‘ ’ “ “ “ ’ •”˜ –“ ˜š™“œ›› ž"œ$ % (¡*™**£+¢!+¥,¤,¤!,¥,¥/§0š00¨1 -2¦&2¨ 3 5¦,5ª7­8­ :­!;¥;<­&=¯&>¯'?¨=?°$A°-A±)B²'B³%C­9C²)D±-D³*F´*G¶)G¶,H¥EHµ,J·,J¸*K´9L¹-M¹/O³ES³LS¶LS¼2U¹MU½2WºJY»OYÀ3YÁ3Z¸P[¼F]¸T]»T]½T]¾Q^±^^²"a´`aÀUb¿ObÁRbÁSbÂPc¼YcÂWd¸cdÁKdÃPeÄVg¹agÃYgÄUi·ii½giÁWiÄMjÆXlÂdmÆ\mÇ[nÉ\oÇ\pÂ`pÂerÂnrÃfrÇbsÉatÈduÄhvÆhwÄswÅhwÆiwÇgwËZxÌfyÆsyÊhzÇqzÍg{Ãs€Ít€ÑnÑn‡Õs‡ÕtŠÏvÉŽ‘Úz”Ô€–Г—Г—Ò’—Ó‘˜Ô’œà‚žØ•ŸØ•¡Ú—¢Ø›¢Ù˜¤Ú›¦Üž¦å‰§Ûž¨Û¡©Ü£ªÜ¡¬Ý¤¬àš­Ù«®Þ¢®Þ¦¯Ý¦°Þ¤°Þ¦°à©²ß©´à¬´á«·à®¸â®»ä±¿ä¸Àð¤Âæ¹Âð¨÷üöýþýÚª'tRNS ##09:?HSµµºÁÊÌØØØßßéíïññöööööö¹ïaL*IDATÓeнJAð™ýº½œ\b,|ÁB6b!‚o`oeaãCYÙˆµØi#Aü@ LôŽÜ]n³»c‘;‹Ëtóc÷?Ìp¨ªÝ?(3U'þùzBnßTÎjÞ²Q+>õÍ×3“BïÍ6™ìhM6³¼Y`ï-º:è`BÞÛùÄ@ƒˆ»ÛŒ .L)ryÊ@ N~qåv<"ˆìÖˆ#çËvÅÒCy‡(•òF¥kÅ7ÉqOЋËqí(Ò:š ï³¼ã—w6™ÖQ Ø¥Ý#pd}øs†aÜcˆœµ_Ãõs&Wâ"EñƒTªiyS¹œóÄC“Ë´ÄÂ-.Ÿp‰‹L#JBÛ ‘ýî÷')Þ`÷¾A|õ©ž‰õ·ŽnÛ4ϪîFRy8C‚,œIEND®B`‚eric-6.0.8/eric/icons/default/runProject.png0000644000175000017500000000252712342633755020065 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ+² ¶tEXtCommentCreated with The GIMPïd%nîPLTEfffqqq~~~µµµÿÿÿ†††”””„„„———žžž,,,˜˜˜ŸŸŸ000FFF¶¶¶³³³°°°ÁÁÁÉÉÉ]]]555   ªªªffflllžžž¤¤¤¤¤¤ÃÃÃÆÆÆ‘‘‘¸¸¸ÂÂÂØØØÁÁÁÍÍÍÒÒÒÚÚÚÞÞÞÃÃÃÉÉÉÉÉÉÞÞÞÄÄÄÉÉÉÏÏÏáááÒÒÒÝÝÝgÁ"nÌ1o½3p½9‘ÿ>€Ò>“ÿA”ÿC•ÿFz½H˜ÿJ}½J˜ÿL™ÿMÁM‰ÒO›ÿR„½R…½[bk^½_eke“Ìf¥ÿf«ÿhowh§ÿi¨ÿk™½kš½lªÿm«ÿn™Ìnœ¼n½n¬ÿp­ÿqqqqv{q{†r|†t}†u~†u›Ìv~†v†w…w†w€†x€†y°ÿ{·ÿ|ŸÌ|¸ÿ Ìºÿ€»ÿ‚¢Ì‚£Ì‚¼ÿƒ·ÿ„¾ÿ† Á‡ž¾‡½ÿˆ¡´Ž¨ÌŽ­Ò©ÌÇÿ’Èÿ’Êÿ“Ëÿ”¬Ì•Íÿ˜Ïÿšž¢œ°ÌžÌÿŸ´ÌŸÇÿŸÑÿ ®´ µÂ¢Ëÿ£ÂÔ¤Ëÿ¤×ÿ¤Ùÿ¦²Á¦Ûÿ§Üÿ¨Øÿ¨Ýÿ©²·©Ñå«ßÿ¬Ðÿ®Ïÿ¯¸Ã°Òÿ°×ÿ³¾È³Óÿ³æÿ´¾Ê´æÿ¶×ÿ·È׸»½¸Úÿ¸äÿ¹åÿºÀÆ»½¾»¾Á¼¾¿¼Ùÿ½¿Á¾ßÿ¿ÖåÀÆÍÁÅËÁãÿÁêÿÂßÿÂâÿÃÈÎÃåÿÃèÿÄÄÄÄÅÆÆÆÆÆìÿÇÇÇÇÉËÈÈÈÉÉÉÊèÿÊêÿËËËÌÌÌÎÎÎÎÏÐÎéÿÎêÿÏÏÏÏíÿÐÐÐÑÑÑÑÑÒÒÒÒÒÓÕÓÓÓÕÕÕÖÖÖ×××ØØØÚÚÚÛÛÛÛÛÜÝÝÝÞÞÞÞßáßßßßàáàààáááâââããããäåäääåååæææççççèêèèèéééêêêëëëìììíííøøøùùùÿÿÿE'k¹AtRNS !&5:MOU_`efffjjstuv{|…Ÿ­²º¼¾ÁÖÖÜáæçñòòòòóõõöö÷÷ùúþþóÕšubKGDùLdWðyIDATÓM‘;OÂP†ÏùN[¨-RD D&Gu1n&L&î&&Îý!þÜ4ÆŸ`âàbŒ“ˆ"!¦(ÐÓ =ÇSnú-oòäÍûÝ0BšŠÑ¼ÜþX$$­Vþ(:rƒ Îè¡0ÅÉl3¼X|ž[£°­O;r“»3ô¿n·'!J=]Ò_®£Ü6ò•iK<² KƹDPnõ_ñlDZxm9“9u_š¹‘,ËÀ<õ0NgnÌÐ&q‘Pæ‘9¾™OÁÀ6R÷†“t^{»ôt¯»°OÔ¬d„ÛVsFãB†p}—Ådè§QKÓL—SzŒWû+òû°ì‡ 0¼×hˆ¡åÓõôqàŵˆ#4¬W¿ífQ jZ—^fóc7Àî× GŸcÞQ²‰,¡D ”âf'•86Í1Æ€‰ø’C¬®„tØ‹¶ì{¨2â¥bÛH°CGQ@à‡Ù’=˺ðÓ‰µŽ«/À8©á¶årô /БDYyùeIEND®B`‚eric-6.0.8/eric/icons/default/callTraceStop.png0000644000175000017500000000134012342633754020461 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<_IDATÁ1h\eàïïÝ]®wœw¦Ák‡TÉT$!898¸DAM×Á­ƒT‡‚ƒSÀ΢¡¦Ì*â"tJÕ¢P4CŃäz^.ïÞûý¾p«U.[ ‹°÷ì&÷oœ"€›+nOº¹‰ 2™Š¬çÚÍ€ÁGr³\¢eÚeÑߎ¢!ÙJ®Ò‡q£ŒgO½àÕe(œ9õ½C-µ£0«O“ÍóÙ±×\ÕV‘ ‚R¡eÕCß)g«›6ч+Å·}¯[ÒR•É$ ;3ô³{:Ò7>Û ´â£§Ý+ÞÕQ•K‘ ˆH¸ã7Í^˜ËòåI—WµÕä¶ ŒL”Rk)½éSgÝl9›,ÍxNE¦414pâ?9R‰Šš†K³”•‹çfŒ‰±‘§N 傪(¨¨ºâPe1)r—Õ=öĉ<Ñ7%R©—äÊ…¬T"ˆþtìØ±=kZ"‚ (•’r?øK‘H¤*ê¦ÕU¤ˆå~Rî%zÆ jêšÚ.jkª J…¡D¹—•»‰ž¶ …Ä”BjJCåFþ(wÃ;­øhÔ½ê}m $¢‚à…¡/ü¨Þ séÃñ7ÉÚ‘Kf¤š.hjh¨›21ò‹/Õ…÷îü"V¿š¬§6Ìk¨©HA!7ö«Ï˶¶7kø`2;ò²5MU© *ŒÜõƒºì(ÌÝ'D°Ú‰›åúXÝó^4'øÝCC5ÉV¸¾Ý‡¼µâvÑ- ¤R©´çÚ½€ðv+.[²hûöì†ûwOøRBôÝô3pIEND®B`‚eric-6.0.8/eric/icons/default/endline.png0000644000175000017500000000054212342633754017342 0ustar piotrpiotr‰PNG  IHDRójœ pHYsvv}Õ‚ÌtIMEØ"zÍþlPLTEÿÿÿˆˆˆˆˆˆˆˆˆˆˆˆˆ‰†ŠŒ‰©ª¨¬­«ÃÃÃÊÊÉÏÐÎÝÝÝöööÿÿÿ«/òtRNS "#+,36=>?FIPSUÙÚ‚`ßãbKGD#*bl:WIDATÓc` ?—Äâ rŠ@N‚ARQI ()J…Q„d¤¥d•1…•ä•é,Œp Vwãð%Ž0¡ `dfeçäæåäãáâ`cab‚$aÖÓêIEND®B`‚eric-6.0.8/eric/icons/default/chatBanKickUser.png0000644000175000017500000000236712342633754020734 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs¯¯^‘tIMEÙ73,MùbKGDÿÿÿ ½§“wIDAT8Ë¥•YLTWÆïȦFÄb‹( XÛFªhei¡@aʾ d€aØ–ʰ¯ KYE Ã.ƒÀ,ÈÀ ”©#0Ò5t"mÂK“>”4iZùzƇ¾PÛ'9¹7÷&¿ó?ÿó}ß¡¨ÿ túi†Ÿ_.30P–-Íf29™±±§¨£ nBÂ¥x:ýyJx8„ÅÅô÷cz|­55›eŽÍ¡ 5<—˜¸B*E%—‹±¾>¬étøygóÓÓiŠÒÒh÷57;çÅǃ­¯¶¤äUµK øvm Ë‹‹h,+ƒÏïÀ`Ùðp?%ì°0TççCÔÚŠÉáaÈGG1ØÙ AA:ª«??0X)‘|ÔÓÐ}+ò““QGzÜQW÷j QÇ磿¥ÅåÀ`IO±F¡ø©"'¬ä&$€Ÿž~Z SSq_$Úêon6<Ô.«TÕêßJ32ÐZQ\¾»ªÑ|x$ÉÍI¥\ÕÔ‰ôSzïÚjk«Ž•ÉÜ:›š~gGF"—Å—Í+"éqq{%¹¹1‡‚#˜IvX*,/Y«Z-äÄ œ¤$”3»ëû…J•ø]AÁÍN[[ƒÿV)µ…¤¯ÂÒRÈÄb¬h4ØÞÜÄä¹ÄJÄù¾Mz¿E”³Q_ÇáaÒ3g¼Üÿ *1éíý5l½»© 2¢]Ý×ñT*….!O¸y}ê&w ¼ûNÇÌug¥–-#æñ¹·‚ñ:ðWJef‡Òìlt56b’ØÃ9æBƒ°’™…"·1wW¤’6}‘•%ÛYÎGF@ ù'ž¿ÔQ”Å?‚LL,±£¢PF4Ü.@,aœl]‚Q—ëX @Ip †˜±/µŸùaÞßý6/¤ä_×Ås¼}PqoïÙ¡îî?Äqz34LèmkC#r? ¦¥@D*׺Þš§'žø|Œw7ˆì.(Š(êf¯ó5´¼m5µ¬V(üªªåë‹Búdk½}ÍþÞ¸sñ<Ú“Ùh'Öåh‹uGG¬ÛÛCbm±›DQVie'8n€ò“†óûݶ¸XP_Y‰//$“dÓçD ¡*º?ê (Ը߂ðƒkX!ïߣð̘†§4 wMV3L 2šMŽ¡ØÌèÎ~™É勳³ˆ F0ëÓGtËOL„ÐÔwOBeHÃ3n¸z_úzcÀÑhè13Þk?i–‰ç>03(ÈjaffC;?ÉaFPèdwÄ8Øaˆ@H¥‚Ë–‚xxx;Ïê¬NCZ0A,xÃxÒž¢ö_n7nÐ\]¯¶ÔÖŠ”SS;¤5/µj5æˆóLIÑŠû¦†X>~ ®Ø@çteï›7M1G*-47Q’RÍ^kW''ÊÛÅå„‹‹C€››?ÉŠl^jj%/%¥’žígm™Zjqbtà‚ù’KçŸ×[šÊCOG¼OQÛú/[žr°ßÊ<IEND®B`‚eric-6.0.8/eric/icons/default/autoHideOff.png0000644000175000017500000000207412342633754020123 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¯¯^‘tIME×  "¸åœ==PLTE5ÿÿÿ$= 98±Ï:/nˆ¯ lŠ·;Tw«8ZŒ&Y¦(Z¦5&U#UŸIn¦!O“/& :4% &K &K(L g“ÆoË(23]j (N 7 8 = 9G…H…+ !@ ,h¤-_w-ax:bœ:c;d ;e¡c‡í¬ ™'3áó‚Ôlf÷ÙÌ­èŸ0ˆ•Ç+ŲËPt¶ùSùÈ›ËCöB6¬!+Ì!3LLHŸO‡qʈäÓÉH:–ׂ ä1òv7zwÌgü^ŽaºÉ!;¬ÏY‘y*–I L3´˜ŽÔ‹©0,¸œÍ vÌî€úŒª*ÇÓ@j£nD‚»b¾ rr®CtW4$ƒÃäyªóT TKT—6~_¢:Guœ ö¸¤.êͯ¢/êÕ­A¥(i‘ˆ$@ÃTcá TW©®S½Iõ:Õ Õ<Õiùxˆ°øî r‡âFk[¶¬“‘mg¢&£P“m‘²èßË:eÐæh¡wÀ¹$Ýû¹í“¸e£q¿n=ªÉ) ˜ ˆñÅÀérÂåvAkÑ‚;Ì{’ƒÖ¤ {Á½AÈ3ânÑ´úÞð$ù¡QÙ·Š>%TnºÐÞÞ³Ù ÞÂCè t àÍ|Ø‚¿Ãÿ§Á`¸LÓ.*É¡£8—ÃWð«}ý}Çìì,<ŒF# Âb5óB¡&&&Ðßß¿f·Û?H$6ƈ r§Öh4ç+**n755¡µµ•••ÈÍÍ…Õj…R©JE¸f^UUUx†Í² Ë2FX.—÷dg?òK“PÚjšê°»­ÈÊÊÏó·™XͼÚc3l–eX–1"ÀÛ¶m»YZ˜¿^d3¡®8u%v8óíÈËÍaP8Žß™XÍ<Öc3l–eX–1"7–Æ~“•¦E±1ÏÔ[0¹§ ö$<¬U®ÓÏüÞí'T³šyBv"¦å­3£,] kšŒŽW*^qæòwö”¤â@¹ ¥è)Ö‹ZM?ªTªRRRR“““SXÍ<Ö{: ‚ ØW…*‡ùcD€ …7Ïfù~àñªõ‰þjŒï«;jKÿàyÓU K»;Çjæ±›a³,òŒ±Ù«ÆÇÇ7ôI7r¬·Ì¦ô¯õzýyµZmÑétÿ¼QV3õØ ›e–eŒ¿­­ppw{wIEND®B`‚eric-6.0.8/eric/icons/default/greaseMonkeyTrash.png0000644000175000017500000000211212342633755021353 0ustar piotrpiotr‰PNG  IHDR(-SsRGB®Îé pHYsvv}Õ‚ÌtIMEÜ9,ðõÎRPLTE¶¹¼½¾¿¿ÌÎÏ**Ñ++ÒÓÔÔ¾ÁÁ¼“¾©¾±ÀµÁºÿyyÿyy »¸½»¿½åbbÆVV»ÑÅ1 ¼& ¹Ó!ÉÍccãkkD = ÉÄ%%¦ ÓppÚrr»ÈÀæ.+Íô<8³''“!!Ý#!ï41¾ÂÊÎ ÂÐ Ž‘‰Œ“((”((Àl&&†++†--¼ ¾¿ÀÒ..×wwÙÚÚIIÛÛ%%ÜÜCCÝLLÞßâãkkå§§ë::÷f""h##k&&o$$r''{|…™¨**©44««00¬66­55°$$±²''²aa´dd¶77·44·99¹PPº»$$¼¼½¿¿¿Á))ÁXXÁ––‰‰ÃÃÄ Ä##ÅEEÆÈÉ ÉÊÊÊssÌÍÎŽŽÏ¤¤ÐÔ¡¡ÖÖ……ÙAAÛÜÜàÊÊá00æGGçººçØØè ëZZì,,ìVVìí$%í’’ñ'(ñ--ñÀÀó))ó--ô11ôƒƒõ((÷&'ÿAAÿÿÿVRMGstRNS  $'-4:>?BBCFHKLLZZZ[^aprrry{¨¨ÍÎÚÛÜÜÝããèïõùùúúûûüþþþþþþþþþþþþþþþþþþþþþþþþQp­bKGDÅc +wòIDATÁ½K1àß›¤&÷ÑC¨Š *·éPA‘Îþ¥ââà"ˆ“îÄE(Øâà}ä.½$¯ÏC…·(óT“kšOdŠÜ¤3 Êð«}Ô¸žÍy{1¥ú#W#dÙò8ˆÕ‘ü.5´btg_¥«vGa}Ø£®Ó'ÓùÏé>×$¢ô[/©XF bïoEK< *Ý9„GCÛ+ 8°êàåe¦‹ûÍļG@ø‡ß„%íüõ=b,ê´vùJ„( ðäÙ,OÃ9@ëÖߥ½¼n:». ¡ØÇê a/Iì87ä«·­û²¼séZJ‚IEND®B`‚eric-6.0.8/eric/icons/default/certificateImport.png0000644000175000017500000000243312342633754021402 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs „ „ªâcytIMEÚ 8/(>WâPLTE&-ÿ5&  a8\m4WgÏÑ+Sv©ª¨©ª°¬‹Œˆ‰‡&8 „& Q  >b“C`Ge…p–¿uœÆ+k821t6€ ;‡ ; A I¤D•Nª/O/<0K0L4@Q£S¥"nà$oß'Ch)kÐ)rá1a¤1pÎ3Kn7f«@d–EcŽGIüGbˆGf’NiˆOjŠQw¯RmŠRx°Tr—Us—VpWfÛXw¢Yx\z¥^„»a­c‚­e‚žhƒžiƒžl†©m”Ën•Ëqrøuuövuø|žÓ€ôž¸‚„ô‚‘»†‡öˆ‰öˆ¥¼‰¥¼Žô‘ô’“õ’´è“¶é˜™óžŸôž½Ò ¢¥¤¦¤¦§¨¦¨¤¦ÃÖ¨©ñ¨ª¤¨Åת¬ò«®¤­¯ó··¸·º¼¸¹º»Ûí½¾¾ÀÂÃÃÃÅÄÂÀÄÄÆÄáðÅÆÇÅØ÷ÇÈÈÇäòÈÉÉÈÛöÉÊÊÉÌðËËÌÍÍÎÍÎÎÑÒÓÒÓòÒÔïÕÕÖÖØñØØÙÙÛðÜÜÝÜáçÞãêÞùÿÞúÿâàõâãäãäåãýÿäåíçÿÿèêìéêìéëìéëîëíïëîïìîïíîðí÷úîïðîðñîñíïòòïùüðùûñòîñòóñòôñõøñûþòòóòóôòôíòôõòüÿóóòóõõóõöóýÿôôõôõöôöëôøúôýÿõõöõööõö÷ööôööööö÷ö÷÷ö÷øöùü÷÷÷÷÷ø÷øø÷øù÷ùî÷ÿÿø÷øøøøøøùøùùøùûùøúùþÿúúøúûýûÿÿüú÷ýùóýúõýþÿþÿÿÿüõÿüöÿÿøÿÿùÿÿüÿÿýÿÿÿ¹Sfs4tRNS $%&'AFTUYY[bduvwz{~‰ŒŒ•™ŸŸ¢¢£°´¹ÀÊÔûýþþþþþt§ {bKGDõEÒÛrIDATÓ•‘»NQ†ç°³À ÆeWïcì,…V¾±³ðA¬mô 1¡õ¼`°0Þ€EesÜûž=G´òÖ8_1ÉŸÉÿ'ÿüoð@*FŰè—ü²_öÊÞˆ?ì„jç õÅBÐÂs4Jò<·ïvS.\ZJ¬Zi ]uNùÈë¢nûù5d[7/g9ˆGË6°‹¬Îrú½¸•±&7–ÑD+Ip¦Yì”·w‚Ç[´­Ä¸Ä!Šœ– I‹(&÷1é5ØÛþõ|o ¿ÊlfoÌSGᥔe*&™9¤dühõL³Ÿz4=ÉÜzÚ5¨Y—¦ßžš«œÜÉ("&†jh¸ ¦‡¥èá!ßÎe3!^ÜTÑ\’Ç:üδª’ðDgo—LÚzW.¼h} ­Ú7i>Y ùÖýBr]Ôà €o²”˜—IÔ`¤¯²ötæÜ¿_8¤}®wLž¶'§dIEND®B`‚eric-6.0.8/eric/icons/default/chatUser1.png0000644000175000017500000000203312342633754017560 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs¯¯^‘tIMEÚ¿ØS– PLTE#Dm=++?00OOQQYY(yy/ŽŽYYOO==mÎÎdËËWÇÇ$ll'vv cc$llWW0YYYY-‡‡]] ``#jj+‚‚/ŽŽaÊÊ8©©xÒÒdËË^^ÔÔ+)~~9¬¬/HÂÂ~ÓÓ„ÖÖXX)||)~~::hÍÍ‘ÚÚ6¢¢1––6££-‡‡|ÓÓ>ººCÀÀ.‹‹QQ@@({{qÐÐ#iilÎÎ({{.‹‹ˆ××IÂÂFF|ÓÓ`ÊÊqÐÐ~ÓÓXÇÇ({{~ÓÓšÝÝ?½½UÆÆ„ÖÖ(xxŽÙÙ$ll::==??AACCFFHHKKLLNNUUXX[[]]^^ aa cc!dd!ff"gg#ii#jj$ll$mm%pp&qq&ss'vv)||*++‚‚,ƒƒ,……-‡‡-ˆˆ.ŠŠ.‹‹/ŽŽ00‘‘1””1––2——2™™3šš3œœ5ŸŸ5  6¢¢7¥¥8©©8««9¬¬9®®;²²=··=¸¸>ºº@¿¿CÀÀDÁÁKÃÃLÃÃNÃÃRÅÅUÆÆWÇÇYÈÈ[ÈÈ`ÊÊbËËgÌÌhÍÍjÍÍlÎÎoÏÏpÏÏqÐÐsÐÐtÑÑxÒÒ~ÓÓÔÔ‚ÕÕ„ÖÖ…ÖÖŠØØŒÙÙÚÚ“ÛÛ¦áá±ääÿÿÿtÛ AQtRNS ##%&')*+28<@@BMMQUY]mnoqrrtuz|„„ˆŠžŸ¬²³ÁÇÈÙÚÚÚÛÞàäääóôôöùüüýýþ<ïÎbKGD®¹k“§*IDATÓc`€n]K -.4 ìUÔÝo/ˆ*Êf’Ó¹hÍT+aé, â™K”H¡«–Dä6÷ôµæ)£ËMO.¬®.(‘AæpnŠŠOOÍtdGµSÁkzmi‡§,º õæ.[:Í]TÞ;µ¼2%@ U”Ç%¾rÚ’¹Ù"(Â&%%½³V¯“eŽ,ÊëžQß3cɪ ~âHšUÙµ]SfÏ[ÙhŒ$lYÑÚ;irocœ#\”Ï'"¹ ®­»«¥,&M.¬Ô›]\ÝP_‘§Öo ŒLÈÎ/*̉Ê1€ k,KŠŠOÉH‰ ž¨pXÑœ•X3Ï–.Ì"iææ¿|áüž®¦¬2sŠ)êj+Šr2€$WNOäIEND®B`‚eric-6.0.8/eric/icons/default/chrome.png0000644000175000017500000000734112342633754017205 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœtIMEÛ (¶œõübKGDÿÿÿ ½§“aIDAThÞíZi\Õuþνïu÷¬šE3V$#1$„AqÂbRªBb;¥8N*Å›ÄI(Re»Ê?\®Tll*Ž“JbW*!.\€#aÊà€ („±T"-£I3£Yzfzyï.çäÇ}ÝÓ3aYØñ^Õ›÷¦{úõùÎù¾³Ü;ÀûÇûÇ{:è½>à3«—æ7.éíîin^Ù×Þ¼¥¥ÿH¬u¿&êQJ˜ÎºÓÆØ·J•dÇÉReÛh99üê©á±¯JYô7]s{gkË-…||}.Ÿ[¢ã¤uöT "€™àâ<Ä{xcaŒ}'Iì‹¥òÓ~<ð8ÿ ðÍ5+q×¾ÃøÁ†ËnZÛÝõp®)·RGQ" WJHR  ÀââYà<‰g°ó`瓘Ãoïß¼gßóßX±÷yçܽø³XßÜÔýHÿê‡Vt´?Gº‡Âç)xY Ì”]kÆB¼‡8qŒ, ÔøyѨ§'Ž·níì¸àµâÔk/—+ÕŸ[þsY>v춯ýÀõ«;ÚinÊ÷“V€VBJ"R ¤‚×A  áñ"€$–Ê à}xÝyhV©¦o NMÿÉ–ÃG_|´w>>2|þ^\º×?ާ.Z¶ùò®ÎÇâ\®ŠZ‘ @JŠ@D€Reö @$à©E ðö>D…30NÌdŒ-½9^¼óÖS'·¿Ð{n:ÿ<±xñ–õÝ]ÏF¹Ð$¤ˆ 5HKkÞ‡Ê,˜9õ(ã"ÁÜ F+x&g-vOLþÆí£ÃÛÎ;O_°øúþíOE¹¨•jm0¸æ}ÍD¨_#-Y$²ˆpÊsøÝ×£#ÄLƸÒ[ÓÓ¿yëøÈ‹?“ˆûÖ, ǨwãÂÎÇ QÔ' „fy³~cÈãàDœ 7УvÏ€›1jâö’½/€/¢@ù6¥¯"ö5UŽzn¦ÇRºøþþ¿Û°ßnŽB"„ÕgÙp_Ï<õ $uo 3Äež÷á>d&ÜÌß×À…Ï BD$±Ö=)jÿüTñûç}yÝUïWº†-O("r¥„¼N †×¹,ô€u€qáê<İ™÷Ï;¬4¼&À„]¹ÑD;¿ë+çÚÍc¾ëâî‡ÓØqc§ôïž&6ÍZ¬@ä!*ã8 ‚”$ã½X 0#Z½ zI_h%&Þ+ïD*I¦îšS 3™7{lP§€Âº‚ã‡ð&^ÀÒwpõ#nóÑ b‘Ckši÷í¸úå""ä)û¦†/¢zë —ô¡eëÇÑ|Ûo[ÛÁ΃”‚ÒšK¨¾ó(’ãÿ ˜c Å ” B ”( "Í’»èÛ×Ýé=+…º®éj^rmß_FMÑ DÚ ö_Ú‚¿\DT žU ez3 @Ë=w¡û¯¿„ñK¯ÄÀ‰GJØ}"Áÿž¬âàpãB[ïF\°òN°hj"%ÐY"Óh%ˆ´G1âØ#вSyÒ$‘R0‡ûm{Þ‘FWýÑ*Ä‘^¾tÓ’W¢¦x± ªkš]%Üý·Ç‘æ ±ÒhÒ: ÐöÈW¿á<¿w¯œ†e@k­ ‚g†÷ŒX®]ÓŽ®]7¾rè“ MÐCk†Ò\·ˆHæpC¡Rá“ßzÒndïþéß̉ÀÄO&зyñ• –µß§ˆ ò9±`ª3Fï±*zN;øŒFZ)šî½ù;ïÀoŒá©]ãY¦ Y—Yà=ÃysŒªõ8< Ç‚þ‹.‡Îyäù%èÈCéŒBD •¼.ˆ´BÛȨæS_Ã3°Ž–ÅÍ7‡^fàÁvÜØ…Š éÓxã=ÔÒ¥hýíxr` O Œ!"À9ë©uHŒGjÕâLL¼õdž®P<[Å‚5 ÀäÐÀÐç\Õ$VÀÙ*|pUm5¥¦ i T¬rP Vâõâ«Ø9ù*” "…˜bÜÚ3ŒEù4ãx0>¬ye´ñáôFÁ§ÎFd…ç^©|À䯯‹å¬#e:–€Lì?Ö±®ki¡­°DR1j³o Qj‹ˆ³µ¡HA‘±BHÍ„rx`Ù´Å.3<*eÄ+0k8­†³Z\ÓÞCæß~ç‹ãHóO_VÑÍWN–÷t\Òµ%Š¢îí³¶ªÎ6ªµ Ù}}l`$;0ÁxÂïõÃGºÆÁ¬3ã‰U¼†÷Qð¼Õp&›F46ÁøÆÄÝÅ2ŸN̙߼Ä2§£I)ZX8Rèi¾%Ò*ªfäÛPæk@j÷õ? ‚· Ç +ã2>¿l?ëÙ†³»e¼ Ç¥‘¸4¢r‰*Ïþ¸|ï7¿_úŸÄÌ òçº?à‹oŽ£v} iQëZ)¢o„@R_µÉì¥9µ‚‚vœÀ3𥾷ѩýŒÑ>Õ ¶*¤JÚH¬‰©RVxüG“ðÿX|@r^qGÎM Œ¢UïmêiÙLŠràëDš?Ì,KV…ÀFÀBøhó(6µŽ{N«ÀFÁ; ¶¬‰`Ó@›ÒUÿÑħü—â“‹»u2]•óÛ¡áÄ#j]q÷Ø µG{¢öÂ*Ò]aé/#ÃR 0êKƒâÞ ò¸§ãtÁÁ[ v œÑÅÙÎF°i$ÆÄdÓˆFGýÁg_™¼ï¯¾U|fa»ªYÞÓ;µwâÈôÑ©mº§Ð¡›r—CˆÄCÄ ÁÄgSa–qØ Œ%ÜœǦBÆFpVÃgWk"8Á¤‘Ø4¢´Bxk°úïþóé{¿ýÃÒë*•T~®{dÎWìäè+C?äí‰Ú󗪕Q­N°‡ˆ‰8 ´x‡/tœDjƒ±Öj8‰M"²FÃT5Ò*™‰¢?òÄKŸ¹ëë§¿V,óu8ç­×óÙf¥¬é^ö‰5·µ\Ðzs®-wuTˆE±‚R¡j8è<- Ux!¦Lkå*Oº×žHž»ïFž0ÀÙ2þö‰ã®<ìxªä¢Ž\GËòö ½Í«›—µÝ_P¸Bå£ÕZlç§;§‘ƒÀ± 52QªúƒÃæCÉ N؃»+§Žq€YÞñÑ÷ÿ¿SŸ% A ΢eô¤†áÖgv,œHhN~©ÿjp–gÒNOXX[fgn|„››žŸŸ¥¥·½¾ÁÃÊÍÏÐÒÓÓÔÖÚÛÜÞââãääååååææçèéììííîïïõöøûýýþþþr—Š‘bKGD︰â¡}IDAT­ÁKjAðÿWýu=™WˆL`|I@qáB¯ AÄ“x —Að^AqáJ0 Á8£ Í0ïžêéêªòþ~P©]ç®|“³xÑ|_û:$J×?;Ͼr-dj]ñòË¢ dÝè¡´h“‡£üôê/ Ý[B›A^†6@íãóKîv¯sÍvñ÷BÏëÔ+;îPŽÒD @Óˆ ¶é^±U(‰rÆvÙ×~ÕèAW%d€DôËé®ç\o(uoaB"ât=¾žskU"Mí ® Ãí4k©ÀLÔÅånå¡Ô„˜±[ƒ• [²½ƒ~å(ómγZZp!” swܦB–veN¸~ÿWE` {ãgÒ*«4ƒüÆ‚Û Ö|}ßÚ9ûÙÏ‹ÑëBîO®âF$.ˆB³ojuüŠWyr#µß´•Ò°ÑZß<ÿL0îðþÁ½‡áC‘=±Ÿ>^̪š6¥»søøÅ6ÿZL6Mñ_ü@°„+å]3IEND®B`‚eric-6.0.8/eric/icons/default/fileD.png0000644000175000017500000000157512342633754016756 0ustar piotrpiotr‰PNG  IHDR(-S pHYs  šœtIME× $x²vó!tEXtComment(c) 2004 by Manfred Nowaka¾gïPLTE  8===CG''JJJKGGLLQRCCRFFRIJSSS00S23SONSPPWY[[('abb"!ccg)*m! uHHuTUu[Z|aa…))‹mm‘:9‘‘‘’‰‰žnožžžŸŸŸ ab£££¤¤¤¥~~¦KL§;<§II©©‘‘­¢£­­­®§§¯š˜°FF±::±~~±Š‹±±”“±±±²@?²tt²‡†²˜—´54´©¨´´´µ¨©µµµ·>>¸@@¸¬«¹¹¹ºCEº³³ººº¼''½@@½¼¼¾¼¼À22ÀJKÁBBÁ¿¿ÁÁÁÃÂÃÄONÄ|{ij³Ä¶µÅVVŰ°Å¶·Æ<;ÆABÇ77ÇACÈÈÈÉ,-É9:ÊHHË:9Í65ÍKJÏ44ÕHGÖ<;ÖQQ×()ØÁÂÙÙÙÚ99Þ;9ÞÞÞßUTá==ághãâãääåäååäåæååäåååæ..æææç''èQRéBCê>?ëžžëÍËëÐÐëëê쪫ìÛÛìåäìééìêêìëëí)(í)*í;<í<;íHHídd퉇íáâíííî//îNOî]^îîîïqrúúúûûûüüüýýýþþþÿÿÿa±ôIDATÁ±JBa€á÷ÿΗÇL¶ØÖÑ ÑVsƒC›Þ@m-ÝBµ6®AÔÐ „Ð-R$hx´:ùŸÿëyÜ…€Ã€†“Y5µ?)5c@¥z·¿äÎÞj{åÓè@Z‡ÃX?6¶.óöò±! ê\¡Þ8êèªï ™/,D–ïÜä!ØW$csù“‚„²€Å‰Ï*fqn€NýÌõ\1ÄüØw:Jû5`àÓ4ßT`<üd”=˺‚ %`W•éKowNy¿M2«Ý?绽µ&Îǯ] æ?C¡Õp¨´¯=àd»¾"À?F—j ò¢W”IEND®B`‚eric-6.0.8/eric/icons/default/ircConfigure.png0000644000175000017500000000226212342633755020345 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs¯¯^‘tIMEÙ2-áïý|PLTE./- ?@>ghertpprnBDAstrtts=><¦§¥uvs]_[••”€€™š—„†ƒ~ ¡Œˆ+++OOM:;9XXWrspFGE}~|‹‰¡¡Ÿ…ˆƒsuqAA@„…€º»¹¹¹¸>@?rtp_`]opo¥§¥PPMTUS³´±<<:µ¶´Š‹ˆ‡ˆ‡@@@qro}tvr¦§¤sssHHG¡¢Ÿª«©TUSŸ¡ÃÛœš554…†„ÀÁ¿A@@‰Š‡’•–˜”žŸ€‚~ZZYxyw·¸¶ÍÍÌ“•™š—ssrçè燉…œœ©ª¦ˆˆ‡’”‘¤¦¥ÀÁ¿ÚÛÚ˜™•««ª­®«®¯¬¶¶µÍÌÌ'./()()*).0..35/0/2327867878989:9<=;AAAEEEGGGILNIOPOPNQUUTUUX[X`dcfgehiiikkoqmsvwwzzyzy{|y€„…ƒ…†„‰Šˆ˜››™š™šœ˜›œš›£¥¤¤¥£¦§¥·¸·ºº¹ÂÂÂÃÃÂÃÄÂÆÇÃÇÈÅÈÈÅÍÎÌÐÐÏÒÓÑÓÔÒÔÔÓ×Ù×ÚÚÙÝÝÜÞÞÝßßÞßàÞßàßãäâååäçèçèéèééèëëêëìëììëíííïïîððïññññòñôôóôõôõõôùøùýýüÿÿÿöv¡«}tRNS !"#$&'(12257GHPSZ]]^abbkqqrwwxzz~~““”›Ÿ ¥«¬¬­¯³´¹»»¼ÀÂÄÅÆÆÇÊÑÑÒÓ×ÚÛÛÝßàâììñòöööøøúúûûüýýýýýþþþþþþ\G…¯bKGDÓ—ßž&&IDATÓc`@ŒòN1 >zœ (€Q7ïÒ™[«ìXQ„¥2_<_g£ÌŒ"l´éȹ ΢¨j˜]W>uÖ„U”7iÁÁc'ý8€L$a…Ê…ëNÝå/®èä‹Í+fÍ=´MFÍÎp„0OäªIK›×îÛ¸h{B±æîmí+'ÏØ³cq…·\T#kÃéySg/;¸%×Sæ«’‰Ýë÷–¦'Új ÃDùÜçwN˜Vf¦"#Äw¸tÄ”¦Žþj7Id_3ª¦tÕ6¶. Dö›i~[C}ÝôX%dos;,ŸÓ×ÒÔ›ª†n–iÆêÉ==9†\(í+Ȩ?³Øž5ÜB£dY­Ë=ÄЂS«0È%ÛKM”I'8Ä\ =ìYX©±¯yIEND®B`‚eric-6.0.8/eric/icons/default/taskPriority.png0000644000175000017500000000222712342633755020433 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<¬PLTEÿÿÿUUUÿÿª@@@ÿÿÿÿÿ™ÿÿÿÿÿÿÿÿÿK¹(0-™×†§ßƒÄƒF²4J¥€N»)iÇDkÄSM¥K`³`:£Eµ$#…Íw›×Џä§Pµ@F§¯Ú¯†”=°!Q½+U¿-ŒŽ…ŠŒŽ  ‘ ’ “ “ “ ’ •”˜ –“ ˜š™“œ›› ž"œ$ % (¡*™**£+¢!+¥,¤,¤!,¥,¥/§0š00¨1 -2¦&2¨ 3 5¦,5ª7­8­ :­!;¥;<­&=¯&>¯'?¨=?°$A°-A±)B²'B³%C­9C²)D±-D³*F´*G¶)G¶,H¥EHµ,J·,J¸*K´9L¹-M¹/O³ES³LS¶LS¼2U¹MU½2WºJY»OYÀ3YÁ3Z¸P[¼F]¸T]»T]½T]¾Q^±^^²"a´`aÀUb¿ObÁRbÁSbÂPc¼YcÂWd¸cdÁKdÃPeÄVg¹agÃYgÄUi·ii½giÁWiÄMjÆXlÂdmÆ\mÇ[nÉ\oÇ\pÂ`pÂerÂnrÃfrÇbsÉatÈduÄhvÆhwÄswÅhwÆiwÇgwËZxÌfyÆsyÊhzÇqzÍg{Ãs€Ít€ÑnÑn‡Õs‡ÕtŠÏvÉŽ‘Úz”Ô€–Г—Г—Ò’—Ó‘˜Ô’œà‚žØ•ŸØ•¡Ú—¢Ø›¢Ù˜¤Ú›¦Üž¦å‰§Ûž¨Û¡©Ü£ªÜ¡¬Ý¤¬àš­Ù«®Þ¢®Þ¦¯Ý¦°Þ¤°Þ¦°à©²ß©´à¬´á«·à®¸â®»ä±¿ä¸Àð¤Âæ¹Âð¨÷üöýþýÚª'tRNS ##09:?HSµµºÁÊÌØØØßßéíïññöööööö¹ïaL*IDATÓeнJAð™ýº½œ\b,|ÁB6b!‚o`oeaãCYÙˆµØi#Aü@ LôŽÜ]n³»c‘;‹Ëtóc÷?Ìp¨ªÝ?(3U'þùzBnßTÎjÞ²Q+>õÍ×3“BïÍ6™ìhM6³¼Y`ï-º:è`BÞÛùÄ@ƒˆ»ÛŒ .L)ryÊ@ N~qåv<"ˆìÖˆ#çËvÅÒCy‡(•òF¥kÅ7ÉqOЋËqí(Ò:š ï³¼ã—w6™ÖQ Ø¥Ý#pd}øs†aÜcˆœµ_Ãõs&Wâ"EñƒTªiyS¹œóÄC“Ë´ÄÂ-.Ÿp‰‹L#JBÛ ‘ýî÷')Þ`÷¾A|õ©ž‰õ·ŽnÛ4ϪîFRy8C‚,œIEND®B`‚eric-6.0.8/eric/icons/default/preferences-interface.png0000644000175000017500000000152512342633755022166 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ÒIDAT8˵•=o1ÇßK.Õµ…*¢@C$Ž~‚l(ªTUbf肉µC՘؂ª~…,e`©"E¢K¥ªC“’´¨yéÝùÎæ±}oášC-9Oì³Ïßû|„s÷Q ñsxxèÙ¶]°, …‚¬º®!DFMÓ’(úâ’xž£Ñ677‰û¾Ïœiš ø®:L)…J¥N'UŒÙäèÏ?,—V@Ó4ì!øCÇv€íÛf£(7ƒ>ì½~ dÁ²a­<»\Ã%c«&+‘U%:‘ŠEâ?K©Y3`t<Ÿ%“%L¹‚ë ‘ 䊢1Êȃc¯|Êp8ÂxTvHh ©þ(1& ˜3ÆRp\\TlyL& 2P.!J5OT‹¶Oyþ¸ÅÅGnœ*åsKÿ…ר ózÂæƒ… †{¬ü”^g 0Ç~¡u2„çbî\pÿW¶‚i0 ¥T‹–*– b£I|•Ï4ñá¦ÑŠôÉsPDKMáz®'1ÄHy¬vUT.‘R¤6,Œ¢.á)T‹ÒEгEœÀw%È©SêS¨èyLG—½µoI걨t,æÖòà““øøvŠE|µñ–ûŸK¨ÝnC³Ù„^¯—_\\H`|uf¯Ëìÿ»ÀŽãÀùù9¸®›<#ÿrÑ·Z­¯õzýÕx<†n· ÕjÕØÙÙ Í™,O&“2ª*a³„ e\ZZz¿½½ýUøA˜™N§ßðÙÇEõôôt°»»Ëf¬ÀÚÞþþ‡ÎÆÆú³Z‰³ðÉd|S‹µü¨\t]Ϩ=¯Ã`0Xqœ—ï0¾é÷^›VáÒ÷‚+Ê‚¡a?!ç;нMc‡‰A’e£¾¶¶fnmm=¬TÖí££ö~%¦âÈ‹k8Sƒ(úȤä¾>¦¿Aû?4¤ÉIEND®B`‚eric-6.0.8/eric/icons/default/templateViewer.png0000644000175000017500000000216212342633755020722 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ïIDAT8˵•KOWÅ“E?@ÛMÔ/À颫.ºŠÔlºH¥ìªîZuY5RÔ¦ Á€Á@pxpŒÁØŒmü~à1üÂÌÃì€=¿sú¿ã‡‚²¨Ú+GÿæÜó?WsÀŽhÝ#Ý'=ø—bÿ½'±>óèÙˆP½@ý¼‰ò‡&ŠÕKäÄ d„s윜!žû€ðaÁýÖÒU8SX·E˜"%,o ·eÎü˜ÖÝGOÞqË&šMàT¨€†a÷aqϰwzŽÔû3$ógØ+œã Ô@’îCô²µÝ*¬±Òs~ <ªR õZÊ~%²G9Ä’iˆäz?'À»± çÄf*‡øQ邨ÚàlþÛÀª¡¡2÷÷õ#Š¢\o rÖ„ÕåC¡v‰÷• L¼Õbpl +î ('4›7ÁèOûS+Y¦XdÀ´¾üþ—akê å¼ÝA¶PƒÍ·…,9ó„w¡z£Áªj½£³˜5$§; ¼“ß}øÇ—È—/pL2»HçhHÁVý1,Ú˜18ñ΀ÁÇïÂÎÃM`s|KÆ'e±r¥–f(ÃäQ&÷&ÂE$h`±cjÅQF_ó– ‘n ö9ŽÊ€G”Ê ËXÑÛ4MŸ)Ec-ˆçškA73u¬ÔÀïUá£Ê¹Û1Øâ¢<¸§§ç«¿ÙÜ‘l„óEiëëИ|˜Ö;à‰߀v²µ'Dبϖ¨pÌóügkV"‡5hWyleª’ÃY£k©"^²¬¥$(Û¾3!À¾M"§Ḻ%"Èf,¶ê6 'HÎiÓ^§“6G™ªæÌ0ÐÀþRÍâÉÐ “F<½„?G4丳X¥TE±|¥x1š±yˆއ'%H§J¡^¤‘GŸZçã‹xúR µ1€ÇSÒýk½ŸŽ¶ [·/¾ûyÀÌ­g¤ü˜†ßš0Í­cŠG oèªu%ñjу g|¥ó`ÞǼ=S¸(Ÿñ¿Ïœ‰\©V…,¡>>GGGVVVaaafffwwwxxx{{{ÏÏÏÒÒÓÓÓÓÖÖÖÛÛÛÝÝÝäääæææçèèéêêêêêêëëëììììììííííííîîîîîîïïïïïïððððððññññññòòòòòòóóóóóóôôôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøøøùøùùùùùùúúúúúúûûûûûüüüýýýþþþÿÿÿæ6ÓtRNS#&MS\l¦¦±±ºøùþ>ôz#IDATÁAjAÐ÷}›Œ\ŠÁx7.¼‚7öºr%fa4`&`HìéÎôTù^(L ЗBûtÈäçVpÿ'²efD†pNAFËl™B’-k[«ªþVU% ùûÝÅõþûÕÝó_½¯SRÈýëý‰.‘0ì–®o$€Ñ/G·Í=PÐ0zÿ‘›%§ Œm=¼X”³@AºËþeL/k\ó!)ðz×Þ¸ñ€Çñ*ÚEŠðößü´¿£ 23§‡Û¹ÝnëH"¬óá}—“Ù@ZâÛÍáHÀè§ý6‘»g•Ñήó"˜€±m ü#bFœ|*IEND®B`‚eric-6.0.8/eric/icons/default/findWordNext.png0000644000175000017500000000211112342633754020331 0ustar piotrpiotr‰PNG  IHDRójœ pHYs „ „ªâcytIME× ƒ/ÒyPLTE3aÿÿÿÿÿÿ4d9kq-Yš2`¤7_>g "<[!G}Do« - 6 > $F %G$A'I-U4a4b.S*;/C4^5K:n5\6ZTª#ö;±{ÿƒ{÷íÙµsûƽF2a‡¹³¯Ú°yë–Më—/˜3er˜ŠHصm¬…KW¯^½lѼžâ´P_=Q °GbVEcG_WK]YvzRtH®PØ3"5¯¼¶¡©¾º¼ #%>ÊL‰ä¿Èäܪö©3&õ·ÖådÆHC¬T³±¶²´pž?}bsea°ªŠ/]Ö,™Öo,ˈêy·mkgÆj‹£‡‰×ŽNSytQθp}I,®¬ È@.¹X[1ì¡IEND®B`‚eric-6.0.8/eric/icons/default/exceptions.png0000644000175000017500000000231012342633754020100 0ustar piotrpiotr‰PNG  IHDRójœ pHYsììu85tIMEØ4 Ó‰²PLTEÿÿÿu¦å‹­Ô|ªåÏÔÙÐÔÚèÖ×êØÙu¦å|ªåäÍÎÉÂÎÜÓÖÓÞéäâå·ÆÝØÞä½½½ãÎеÂÒ¶½Æ¶½ÇÖ’“ÙÀÄÛÂÆè°¯ê°°ÙÈÎÚËÐݪ«Þ«¬ÐºÁѼ«­ºÄªªÄ««â››ãఱᱲÔ}Ô~ا«Û°³··Žç”“蕔݉‰ÎffÏffÒ…„Ò׊ŒÙyxÖllↄㆅÑxxooopppuuuvvv†††‡‡‡ˆˆˆŒŒŒŽŽŽ•••———˜˜˜›››¡¡¡½½½¾¾¾ÀÁ Ãà ÄÄ Ä ÅÅÆ ÆÇÇ É11ÊÊ23Ê32Í*)Î65ÎEEÏÏbbÐbbÑÑJJÑccÒ;:ÒZYÓddÔBAÔEDÕÕ;9Ö;9ÖOMÖON×eeרÙ:7ÙVUÙeeÙjiÙŽŽÛXVÛqpÛÙÙÜÜNLÜ_^Ü……ÝC@ÝOMÝffÝmlݧ§ÞC@ÞffÞonÞÞÞßßB?ßonßÁÁßÝÝà{yà”’à  áIEá}{áááââgg⌌âÄÄã<7ãYVã–•ã––ã¡¡ã°°ã´³ãããäähhäµ´ä¾½åääåå忢¢æÝÝæææççÒÒçÛÛçææçççèiiè·¶èççèèèééii飣鿿éééêééêêêëë‹ë¬¬ëêêëëëì¢¢ì££ì¤¤ì¶¶ìÆÆìààìììíjjíœ›í««íííîîîïkk便着ïïïð©©ðððñ©©ñ××ñññòllòîîòòòóllóóóôôôõmmõõõööö÷mm÷÷÷øïïø÷÷øøøùùùúúúûûûÙþ2;tRNS !",1?BBHLLbbgg}}‚‚†ŸŸªª®®½½ÁÁÆÆÎÎÝççêêíòóóóû@½ EbKGDˆHUIDATӕνJÃPðû•›ä&±Ioc R,A¥‚‚¢¸8¸‹n‚“«›oánâæ ˆT´ikš6ýHÄjlÄÿp8çÇápø#…Ë+çg i“á÷€7ßJ™Dѱ ào6ݺ¡ÕÝœ8Ê21v$FÉ.ïËÀƒšLÅc7Åæêu˜ ·1~³Ã°ég+œŒ±„YŠæÀ}{È|¼VÖLˆòꌯë)#¶f–°‰`–Zls,ey¢»A0'„+Ò|×b_¬¹EÝFX˜ÅÎ-Nif+ „ ÍÅëÊçßjÞØòP Ç3âf;©>í¬¬lc(À׳óg$º -3€ ':„‚*ŠœRe¼VÁ …Rï¶£"‚Ði"Õ‚FT»Ó=¸äö€"+ºeê ªV^ê­ O‰/zX1¸ÏPÜ ¸õT{î|ð¯|\YXÝ6¿IEND®B`‚eric-6.0.8/eric/icons/default/vcsChangeLists.png0000644000175000017500000000254212342633755020647 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs  šœtIMEÜÂçs!iTXtCommentCreated with The GIMPm°—©PLTEÅÅÅÆÆÆlll„ÎÒ¿¿¿ÚÚÚÛÛÛ„„„¢¢¢nnnjjjĆʊçççèèèËËËjjjvvvÃÃÃÄÄÄŸŸŸßßßÞÞÞ‡‡‡xxxĆȈ„ÎwwwÚÚÚÛÛÛÊÊÊËËËĆȈ‘‘‘•••ØØØÄ†~~~„Β’’‹‹‹ŽŽŽÖÖÖÖÖÖ”””µµµµµµ•••”””’’’••••••£££–––˜˜˜¥¥¥”””–––•••ššš’’’›››omišššèèè›››œœœÎéééÎÒÚ•ôôô¼¼¼nlh‘‘‘“‡“““•••–––˜˜˜™™™ššš›››œœœžšžžžŸŸŸ   ¡¡¡£££¤¤¤¥¥¥§§§¨‹T©©©ªªª«««¬¬¬­­­®®®±±±²²²···¸šZ¹¹¹ººº»»»½½½Á [ÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎϦWÐŽÒÓÓÓÔ‘ÔÔÔÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜ–ÜÜÜÝÝÝÞÞÞßßßà™àààáááâšâââãããäœäääåååææææçççèèèê êêêì¡ìììíííî¢îîîïïïð¤ð´tñññò¥òòòô¦ö¨öööø©ùùùú«ûûûü¬þ­ÿ®ÿ¯ÿ°ÿ°ÿ± ÿ² ÿ³ÿµÿµÿ¶gÿ·ÿ·ÿ¸!ÿ¹1ÿº%ÿ»)ÿ¼-ÿ½/ÿ¾1ÿ¾Aÿ¿CÿÀ)ÿÀ9ÿÀGÿÁ;ÿÁ=ÿÂKÿÃAÿÃCÿÄEÿÅGÿÅIÿÆKÿÆMÿÆYÿÇOÿÈ]ÿÉUÿÔ_ÿÿÿ²v?ZUtRNS  !!7>OXX[fgn|||””›ŸŸ¥¥°°·½¾ÀÃÃÃÊÍÏÐÒÓÓÔÖÚÛÜÞââääåååææçéììííîïïóøûûûûýþ½••“bKGDâÆž¤IDATEÁËjAàÿÔ9ÕÕ—¹´“I4nL Y!>C⇄¬|wnÝ*¸Ôgð\¹0 "1‚3F4š8é[õ¥Êâ÷@&ŒÒÍð‘sò¢>ùmkë@0ÉøÎC—w⡼õË‹ÂRo<†k¡8`ë{ˆrÏfg<î7¶îz¯BgÛ¶mºzçàB®¤…"rÄUå{âʹ•c‰¢, ï™=@p=‘k $NŠNHõðŠÈ{4ÍR×E§Ñ~¹—×*yÓ×¼Æya‘9¸'kkë)¹dVžðf2&Tzôa/ÞI"h½ªù±La¨ìºÙÅÀùFó|c”])Pi[©ü‰â¾D8‚køij€Pägu;ò…áR¦Í‘cT­dþ˪›&z9@øÑ+ ¯¸éådýU©ü’EäÕgFkËùér±[™Óke>}}Fø+Øz2E´z‘ãëÓÃŽð¾¾»ot[>ÿ­á¿ñ(’¶º¼ð× Â³~ÃIEND®B`‚eric-6.0.8/eric/icons/default/preferences-editor.png0000644000175000017500000000235012342633755021511 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<eIDAT8Ë•KH£wÅc­ˆŽV«àÊZt'(Å™ꨵPµ/ÝÈT¨Á…ݹ² ]tÑ"îZ¥TÆ´+ ÝŒŒµŠkÑ;Æ$“hŒy¿¿GÞÉé½ÿ1R1ø‡<¾ürî9÷ÞO@óª‡ù sssƒ»»»F7}V•ý¾¬¬ì›ÖÖÖĵ/ƒÔÖÖ–ÏÎÎ~¶³³óÈd2Iv»=ãr¹àv»áñxàõz166ö9_?444UWWg*))ÑÒo_ÏB^«¨¨xcff¦kkkU¯×‡-KÆjµÂf³Ááp€ óù|ƒ…BÐjµë•••U¤T·¹¹íè蘿T¼¶¶ö@°ë`6›Á¯z~~§Ó)f “Âa(a?9̬¨Åªªª@aaáZOOÏ­Kðâââ4Ot]B©l¡Òëq#àq"ì÷@ù JDä¢Ñ(b±VVV2ÅÅźÒÒÒÇTù½K+ù©««ë.ƒOöa5À~fËn…ÏuŽ Ïƒ0+TD"K$HÄãð{ÝèîîFMM=//oúJF¿i±˜a=1ÃaÜ¡”‚áÒ%I¢’%Då ɨ‚dLA*Áèè(ÚÛÛQ^^þŒ%¹À”z’ƒr™öàs’R¯rÐ •¼Œ©’P™L&‘J¥N§±±±! T-¦¦¦®uÕX³··wf?;Ç|¿ßY~¶ô$4©L'""¸?úïÞ¹ƒááaXáκ¾ð[¶ÀgÕ# @!µQ *®†É‰JW‘Éd„Ú‰‰ ´µµ¡··Wt ÈøVNpggç]·Ë ¿í’Ç&‚ʖϰ,tG»…÷:ÚÑÓÓ…ŸDT•E‡½•L îÕP(Å}BD‘ o“Q™,P‘¢À" «ljjÂÈȈ²>ãããƒ7 hÂ’RÀÕ¡' ¤+j9´ÉÉI´´´ ¯¯Ï z(!ÿ‹AQdloo¯ßÖÐ([e™Jó[… И Ýþ¼ßÙ),xðÃ÷P Æáòõ|NOOÿðJ‹,--}'K4U.Ùå§ š"å÷ï÷£±±PUUL!·#W¦° ìçYà50È?ІÜH0kÃÞÎc˜ÿDÿ§÷ðôo­è™††‡‡‡ˆ;ãøø8FÌÚœŠ9@…ÊŠq›y-Hr›Qx ?=Àúo“Øx´"‚b xãYŒz<×Óâ2ñŽÉäçç·Ü. ÎH ÃN¡˜“Ÿøò l®.Cö»`6ü‹gÿ<^÷v›UŒ?³3¶jø&°Æ`0Xã´^3)ceé<üýW  ïb¶÷ ¿§u ¬®®îWWWæôø"Àé8m®dÈ!³úl¯fû–¡´«#ËËËKÍÍÍŸÐf{›xEtòr*ÎÈà„DšÚ{™Æ©æç翪¯¯o @¹¸ýh^rkËq¯+£{ÜÆÂÂÂ×·oß~çU ¹Î+*˜Œ¬êIEND®B`‚eric-6.0.8/eric/icons/default/fileResource.png0000644000175000017500000000203712342633754020354 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î< PLTEÿÿÿ $*,999<>C………†††‹‹‹Œ’’’ðððÏÛçÑÑÑÒÒÒ®¯±ÀÇÏÂÎÝÃÌÕÅÏÛÆÇÇÆÍÖÆÔãÇÔãÈÈÈÈÖåÉÊÊÉÖåÉ׿ÊÊËÊËËÊ×æÊØçËØçÌÌÌÌÙèͽâÍÍÎÍÚéÎÀãÎÎÎÎÚéÎÛêÏÏÏÏÜëÐÐÐÐÛèÐÜéÐÝëÐÝìÐÞíÑÑÒÑÒÓÑÝìÑÞíÒÂæÒÒÒÒÓÓÒÓÔÒÞëÒßîÓÂçÓÅèÓÓÓÓÔÔÓÞëÓàïÓáðÔÁäÔÄéÔÔÔÔÔÕÔÕÕÔßìÔáðÕÕÕÕÞéÕàíÕâñÖÈìÖÖÖÖÖ×ÖáîÖãò××ØØØÙÙäñÚÉëÚÚÚÚåòÛÛÛÜÜÜÜÝÝÝÝÝàáâáÌÛáááááâååååæææææçèèéééêêêêëëììììíííííííîíîîîîïîïïïïïïðððÉæððððñññËèññññòòñòóòòòòóóóÍêóóóóôôóôõôÎëôôôôôõôõõõõõõöööÐíöÒíöööö÷÷÷Ðí÷Ñî÷Òï÷Ôï÷÷÷÷øøøøøøøùøùùøùúùÒïùùùùúúúÓðúÓñúúúúûûûÔñû×òûûûüØóüüüýÖóýÙôýýýþÚõþþþÿÿÿ«LtRNS#&MSW`lq¦¦±±ºùúþþÈ sÐcIDATÓc`Ä €˜ p0€„¹–O_0wî¼…@°hÑÒeKWñ2ƒ…»óª ‹Ë*ªjjššú›gA…‹ýër=MLR´Cü³;§vσ [)éjÊ«jè+h[Y¹[ûðA„+#[ªê›Ûz&Lœ6cÆ’¹Ë¡ª§—uäË*Fæ8%{8V.Y•óµ0wñòòŠ KˆO‚ O(ìëì6cáÂ¥K—/_¹æÀÖÌI%‘©!f&)‘V­^µ*l!ã`eìªceåjžV4gúÜ…@V­Y³fõr˜êòäÉ¥j6q±YzQS»fB…},Ý\½]­ìüMµ TDy˜ÀÂõ‰ó!F,í)0Ì`,×ìö)¶©éêÎÊk’Ù áÍm.íçmìm$%™&Ì®¥Ó šÑY &Ä‹®UKW¬ºmíš…"ülØ"“—X[jz¸Ö±„IEND®B`‚eric-6.0.8/eric/icons/default/shapesAlignTop.png0000644000175000017500000000020712342633755020644 0ustar piotrpiotr‰PNG  IHDR¹Ú„¨ PLTEÿ=ûÝ-tRNS@æØf,IDAT×c`ÀVÀ5Ô14”…Á‘‡•*Q @B4 Ù´ $˜XIEND®B`‚eric-6.0.8/eric/icons/default/moveBookmark.png0000644000175000017500000000233212342633755020360 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÛ ÍÒ¸!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“-IDAT8Ë”[leÇç›Ùûv×ÝÒ¦@…^‚ܤ"Oˆ4JEÅx—Àðdâ-¼  ‰1QáÅD$bÄø q111$\ˆ@0}ibèöF¡Ý-»;»³sù|˜†H¬-ú%'™9ß|¿ùÏ9ç?pkâÂöÍž]»º?óyûÇýÂsáÄ¿=/÷Íçè>˜ÜpR{Ž5]<_)‡Ö¬~¸ëÈþÜÙ[{Öÿ/p>G\ŒDߎìÓÙl­5¶mS*•´íÖ¥÷ð©3þˆµ‘cuûïçÌ{¼7ÖÒÓ‘Œ&ijiFû>ŽãÏ1>1Ž¡ ñg8dΡv½o{+½x ¾ùí!Êätÿ *vÊØÅ¡^gÿÄ+E>GL̆¾Ì²÷:ã«Á-ƒ(0lýj/ýåa絎%onÿ9?+8ŸC€UÀ㈱ÁŒ/~,¾ðÙLÃÂÄhœ[hs¥ñ xž;bþíÓLâÁ+£ùÞ£ëm»ÎçXŽ˜{B Ë7˜ñ¶t8³ŠPj f´C@ÜAÐ6ø6¸….!td)Ž+|X¼„´·sýÜiÝN}lBëëGÏ_»,ƒ9~oèØÑ•líÁ0|DWÀ+7@ðÀwÀ¯LKÐBÝÓ|dÁÍtÑBÝ­S«Õ°,‹“ßÀ,”B?Å*Ã]B±û@û€ð-Шé{DÐ>ôŸ»†Z»Œ£7˜œ*à9.¾öñ=cÍÊygÃôD"©…‘Lâ¸@tÄq)UªTk6µzª]'™jæ¥]8r‚Q©bœ¦[5è¿l]´ ÀŸ¤;W¶ù½MKŸoNµÜÞŸJ$hšZ×(P)0š@¢Tl‡WŽœ¢µn°³u 60\~jËÎÒ¯w¦âôñÍ‹ç›?fØh&²# + ! I9• r*…=¥¾x@_Í[¯o~§t€ ˜Á:xÌØþ„o›îíM±æ(c¤ R¦‚T=(•x  \7ÎÍËß20XølÓÛå=3$ŸCÄLºóºV¨Hj´Ì2ú ˆc;¹trxÉËVël–N‹WH 7ÈèÙŒêàÛyŽšë_‘Q¡4*2†s÷ŽžÙý*| 6'11e0ä.¥^”¡¥§?#ØW‘" sAP‘à ½•!ÁÊ×±§\ ¢Ma’máLàJ  :”ÏaÜÿ"Þ¿³¾=NõF{Òö(lo²¤Ïʱï“Q§%3Qµy²©-Ò`_d‚Ö(q(Z·2#¸æ}Ê-0tÎæfÁï/TŒÜd9úõ¶÷'®‚Ào,Ú½jÑíægì­£Ñ'“1/TµÝÑJͬ‚û6ÁÔÛ½£¡»XFí;\ºħŸ8o©ö<ÍnYZ[«yýï 89{ËŒ$a˜PIEND®B`‚eric-6.0.8/eric/icons/default/multiProjectProps.png0000644000175000017500000000224712342633755021436 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ /YyNJtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ IDAT8Ë­•ÛOÛeÆËc¢ÿ€ñÂxcb¼Á8ãÍļÙÐãÅP¶ÌA@ÁP2èZZz Çµ? ôÜþZZz^KiGÛ-g§E‡ljÌd3²öñUof¢ پɓ_Þ›OÞ<ï÷y~ŒÆÆÆçY,VŸÏ7<,.—+íèèx§´´4—q”‘J¥•Ñhôçééi<¬D"qßn·vvv>w$°X9B±5¬HCÃáò`"‚ÒCk B£·Ç”Jå«G³¤fǼ 4 ­Bb»¹ŽKx\…Ì~ÙͶ¶6NSSSmUUÕ›ÿ Ì‘Y p×qA¿‹^çWc˜M¥‰æ0;›Ê¤R©ßˆîWeeå ‡«´V£^„Æ9ƒQÚ É ­Å =†@ ›} V9;<·‰-§ æ©hãgÒM°MË Ì”sã¨W-7âƒÅ†@1¾Ú^¹ù.‡Ãé'¶¼WSSó:±æéÁ}*‡á”`]î} ûæPÊYÀYê\¶¯CéœÄx „àÄ|ÁH& þ …VÆÇÇý===¯æ^3œäï¢Ù¨+Òs»–1â†ÅåƒßïÿKÃÃÃà ‹% izŸ¢(ÖØ_ã4~$ü_;ïAé_ÀÉ<.Ö ¢ht(ü8/ŒãO‡àd:£V›¡ B™ÚV^^žóà|†@®å^”N,ti RÝØ­ÒÞ¥—ìPW7qAžDó€ í¦ H¼sPz’ˆÄ¦J‚'R„ˆß9ÿz[ãFkkë+$}oÿ©¡¡¡Þ“ìå»ÕF`0|\Ó4˜}PÝÎÀì‹àÖÎffÓ)©ÈV<û“N§;{гòSG~‡€¿é£`£ˆ]‹a‡@···™Œ‚7 N’K;ÔêiµÚÏ¿L|wQÚã™b÷¿’Å3çÛèWš1•¸ŽôÜ<¦â ¬¬¬Âãõþ^]]ý~IIÉS××׿,‰>!¶œQ©T]5Ñ­e¿¢Ç»‡Ñè×7`™\Åé”ùùù¬ÓéÜ ;]\QQ‘sèàŒŽŽÿBOžVî¡;”…i3 ëM€Jg!±/í ÷3$êwJÊÊÊòÖëõÇ›å“ÉóŠu–-(c[PD·Àuoá[ý(5L‚r;N?ðù|7ÚÛÛß%Ý÷H0éáI»µ÷Iuê¥N-Ñü-¡J§(ôênfoÅb)!½Fú;ãv»7ÉO£¨¸¸øãq‡¤/ßl6Ÿ0™LápxŸ|×kkkß*((È{l¸Z­Î%q/"Íwƒ"=$E'wFzHwEž[X3k@¡_^8R/`8 _UyGŸ^qE{HŠTŠQŽV®hUL{IK‘WM‰Q¯hŒRvEX¬h¬wDÆŒY5>$>%C'S1^7_8c;k?oBwGyGyH{J {LˆS”d+–X–Y˜[]Ÿa z_¤b§c§e¨f«f¬h®i¯j±i±p!³k³mµlµmµn µt*¶n·m·n¸o¹pºpºq»q»}@¼r½r½s¾r¾s¿tŇLϦ‡Ð¡|鹛뷗ìÅ­ñϽô¾¢ôÁ¦õÅ­öȰö̵öϺöм÷Ѿ÷Ò¿øÔÁøØÇù×ÅùÚÊùãÖüêáÿÿÿ-ÅãhtRNS  !#&,/134457?@OR]bddffghinrv}Ÿ§²·¸¹»ÂÄËÍÏÕ×ÙÚÛÝããäæçëîïïñòö÷ùúûûüüüýþþþþþƒåc|IDAT•Ác[Cà7-Û¶mÛ¶mcÙ¶[Zë<ÙÖlg Û—®«û¦ÿs ðõö´&IÅó›-J4¢ö#øV"Oߌ³»¹«Ûö¢rþ¥í]½s`¥*Ðäê܄ږæžis Å´%€Y;jìkmêÜòt‰ÁX¿¿¾k(ëhãN ]†ˆ²ölž~Ü^>œ—ûDTÖõÛ9îBhåìåêæùb >XMßÄÜ€(,fÿñéõm|¼hYbù‚µ³xr<8à G›„lv mƃ„t 7 ‰—bJ,­$~­Æ9)“ˆYÍШ" ?Ó‚C_ô,óy“à üªøX’`éfšáj¨®BR”8Dªšô·O¢”…5Ö­”GIEND®B`‚eric-6.0.8/eric/icons/default/zoomReset.png0000644000175000017500000000250712342633755017717 0ustar piotrpiotr‰PNG  IHDRójœ pHYs „ „ªâcytIME× ~H=ÍÄPLTE333 +++@@@GGG]]]‘‘‘ppp667 ššœ‰‰‰566qqqbbclll™™™gggYYZŽŽŽeee„„…§§§UUV½½¿tuu```èû¿ÀÁ~ãù«¬¬mÝø{âùhhhiÜ÷wàù``asÞøƒåùsÞø_Øö]×ö_×ölÜ÷kÛöZZZWÔôhhi³³³UÒólllTÐòQÍñ\Òó]ÑòSÌð²³´KÄëMÁéKÁéJ¾èMÂêVVVI¾çtÝ÷{{{E³áE±ßY»ÚŸŸ D¯ß¿¿¿PPPwwwB¨ÚoppA¦Ù\ÁèÈÈÉB¢ÕK«ÙÈÉÊŒàõJJJV®Ü_»ã9Ç7‹Ä¦§§ÆÆÆvÁå‚ÝõÌÍÎOžÒ3»N™Ì9‚¾~~„Ææ‹Œ‡Ã䉉Š,l­ÌÌÌ…Æç>}¶‘)f§ÄÄÄX—·|¼á•Úò&_¡'_ Ž]•Å“ÑëœÆßAr­Kr©‘‘’¡ÀØb“Á‰Å壤¦ËË̉Ï뀹ݦ§©G‹Q~³•±Ì«Û𽾿¨ÚïØÙÙ”•˜¤¤¤²³´.Q‹¡¼““”byž.T”Ÿ­ÁLž¬®²Fo¦`u™k—²™™™o¢Ê«ÎÞßàC\y‰£— °+Jˆ8]š{¢È4RŒœŸ¦»ÆÐ‹—“ŸŽŽŽ¼ÀÇ6P†?Wƒs–“—¡âããK_‡QcŠyƒ—z„˜{…›‰Ÿ› ¬ly”nnnsss{„˜º¼¼àáâ*V.^ 2g 3j 5m :wMŸY¸=nSœ.\ƒ1d”;iŒ>m?p”K}kkklll‘˜™™¤¦¦µ··ÄÆÆÆÆÆÐÑÑÚÛÛÿÿÿýjÏtRNS  /02=BCQTTWYY]]^bffgghhijklllnopppqstttuuvyyzz}}€€ƒƒƒ„†ŠŒŽ‘’“”•——™››œ ¢¢¤¦©©ª¬¬®°°²´µº»½¿¿ÁÂÂÅÅÊËËÌÍÎÏÓÖÝÝÝÞááääåææçêêëëìîîïïïðððñòòóóõõõõöö÷øøøùùùúúúúûûûûüüüüüüýýýýýýýþþþþþþÁ9VabKGDë¿Ý&¸.IDATÓc`À „´óSô$Q™ f?¼÷ÐÉeÞœH¢L'ölÚ¼zÍò-G³9Âê6N4kâô¾ÞÅG<á¢üÝë:ÛWÞ»ÓTÝ6ŽLXaÇ”‚Œ†¥woç%¤·ìÓ† ŸiŽO½u3Ø+´pELØñXe¤›•åë¶þ™‹b`Â*;ëœMô¯]2µöÉZï–ZØëj¨{õ¢…MPÍ69˜0[܆b?ÛËW.œwOZP w¡xë’"_;#säig'È"ü#S±»§<·´cûÌSÏg+!Ä5ËúçM®5“H»ÿl­#B‚[XZ”+úÁÓƒN¬!Ìxúɹ( qûý_å`F‰ÎÖ‡/«D0Å•W=zQ% çîRŵòj àBk¥#3-4IEND®B`‚eric-6.0.8/eric/icons/default/shapesAlignBottom.png0000644000175000017500000000020612342633755021345 0ustar piotrpiotr‰PNG  IHDR¹Ú„¨ PLTEÿ=ûÝ-tRNS@æØf+IDAT×c` 0††‚) d` uñX¡<åa¥  `,Àj ÆÊ $A ¦wIEND®B`‚eric-6.0.8/eric/icons/default/preferences-calltips.png0000644000175000017500000000250012342633755022033 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¯¯^‘tIME×  :/‚¬}¸PLTEPPP€€€ŒŒŒÁÁÁÇÇÇÍÍÍÿÿÿv{ƒ¥¦©ekuglw>GV@HXW^j]blSZf?GVU[gRXc5>N EMZ #(SQO'*2DLZEMYŠŠŠ;CRKQ]?FRLS`FLW™›ž¤¤¤©©©   ªªª”•—–˜›±±±U[fŽ’¢££¡¤¨¥¥¥IPZCKYˆŠ’“•™™š£££­­­GP_•••;BP;CQ‘‘’žžž¡¡£W_mº»»{~…~Œ———}„Ž„†Šª¬®NT`_fs‘‘‘Œ” žŸ uyx‹‹‹Œy‡Šsv}………‹•¡p~†W]iNUb—˜šˆˆˆfks^dm¡£§w‚cgosŽcgnV^ohv   hlt´µ¹¼½Àš¢®š£®ÈÊË©²·ÂÂÂNTaGPb[`iwz}“•™1:K•º½ÁÁÃÆNT`ÈÈȈ—·º¿¯¹½mry•ž–˜œšœ ÃÅÈÉËω•ž¡§´·½¸º¾ÂÄÈMVgltv¶¸½»ÂƵ¾Â¿ÁÄgotÒÒÒ¼¿Æ¾Àƨ­¶ÇÊЮ°³ÆÉÎS[l²¶¼·½Ã½¾Á²º¿ËÌÎÜÜÜ“›ž¢©¸¼ÃahvFOa¥©±ª°ºœš¥©°ÂÂÂÞÞÞÜÜÝŸ¥±¨¬´–œ©¥©²ÚÚÛž¤±£§°ÓÕØ¨®ºª°¼ÂÆÍ¤«¶•£âãåqxˆš¡¯¤²–œ«px‡¢¦®—¦877…‹—ÝÞá&%#ÏÒØy€qxˆu|´¸Àíîî¶»Ä66600/ììî´¹Â468;;9QQPåæèÝßâHKO888BBBTW\VY]jknspmtrntsqurnuro{xu|x‘—šŸ¯®®ËËÊÙÙØÛÛÚäøzzÖtRNS  %(((,,--357778899:;;;<<=>>>>>>??@@@@@BBDDDEEEEFGGHHIIIJLLLNOPPQRSSTUUVWWWYYYZZZ\\]`aaabbbbcghhikkkkmpqqrrrtvvwyy{{||~ƒƒ‡‡ŠŠ‹““””˜›œž¡¢¤§©©ªª¬°°º½½½¾ÄÆÉÎÏÏÐÒÔÖ×רØÙÙÚÛÞßßàâããäçééêîôNbKGDaˆë,IDATÓc`€&1Ûêz?IÀ]xèʹS—÷•ò!‹rLß¹lãÊëÎ_ÄeL=¶­eMkzÉžý':™á‚ g•…øÇ¬Z¿{×é½ÒpaÅys½=&/Ù¼iëÑ“.paû©Âc¯ž¿vÖþpa‡Æ*§À‰m™5 fôm7ƒ +§ØYwO›9{Jû¤ü9*paáJGÓŠŽžÞæ¦,«$ ¸0›y˜±O^my®—!+Âá–º9Ù®ÎñâÈÞTˆÓÑNN4Ñ RcGæŒ6ÒO Ö‹âE +U7ÍHwO uTQ™¢âþ®º y4a¡ ·nÞx|U M˜çÈÃûwŸ_A>pïö£gEÑ„¹vÜyðäéYtÕ r¯_;£Á€d—.W‚slhÍ­WMIEND®B`‚eric-6.0.8/eric/icons/default/sharedEditSend.png0000644000175000017500000000134012342633755020610 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<_IDATÁ¿k\uðÏ÷½w9+gÎ6mš!ÕŠ8 $ ¤‚Ô! KT4Ä? Cq°S)Eq˜ÁQCD0ƒƒ¥tÌbH,:™"êi-g~™¼¼{ßçç*ÜjÅ ãaÌ(6ªukÉêü>¡psÊbo°ÐÓC&S“u\»¹*ðq;.ÄÙ#´œ5¤ò§§öÑ”,%×?éB¨0ß®6óá}—½æœ† ¥ûØÑRß #·ºdÐ[8ÎMzE¿šLD¥–i܇ûÌ*M•ßu½e\KŸ=$ T8qä'ËÚÒ·?_I÷Zñ‡Ã3—Mê÷Œº‡»¤.dR‰¶¿tÔ^¿ÿURLœ ò†~u}RlùÌ&©š†¦wp2XL$½ñÜs.¨É¤¹øÂ‚¤jêš.ÊõÆ“8vj@®”ÈÚÓõÀ‡~DPÓç’Sq,‰£…!uO<ñ¯§þ±ëS‹Ž¤R/)ÄÑ,Šà7[þvâ¼óúDQ”Å0ô»JHeê™sæ]AOe[7’¸žèÈ•J5Mmg½ëŽ+ˆJ¥‰¸žÅµDÇ~… ÏpÃU@¥pì±D\KâªÎ¾w,W(5½é¶«€R!·ìN\Måßn'3».H¼`RDQáØÏ¾Ö>¸½*LÓ›MÍÑTW“‚R!÷‹/Ê–îÎ*Ì´«ÍÞð±WÍ8£O*¨”ŽÝóPC¶Fît ˜nW q6×ð¼½,øÕ¶Gê’¥pýnBà½)‹å`©T"•J¥×–WB€÷[Õ„qcF±aÝZX½·Àÿhó³ÍØLHIEND®B`‚eric-6.0.8/eric/icons/default/greaseMonkey.png0000644000175000017500000000256212342633755020362 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<ïIDAT8˵•Kl”UÇÿ÷ñ}ý¾o¦Óés:´%Ð ÔXZ¤Ú²AŒ¨ÆL C⺀š¨»6`¢!AŒ Æ…DbŒ U£¦1­¡…Ò鋾¦ÓÒRÚŽÓÎ÷¾×EÁ„êÊ›ÜÕ9çwOÎÍÿˆ”ÿÇá«?8Ì_ ÀaHY#µlB0>øøø9¯íQµäaŸ>HJeŸ¨VU5@)¥RJH)!„€ë8 ˆùÂ?pü _Π+Ÿ"„Rú ç¼Þ0Œç”Òû!0J¡*Á TU¾•v¾µ•Ðÿx¾J Ý ªêŠ1„,]JCSc¤<«¾¶êŒ[[ vHQ”€¦éØR]‡P8 ·qôźH<þD%ò Š01>„Ñ¡^èš\LÛMssCg³³Ks„ä)%N!µ7š×i€T×õŒÊ-5(ÛP× „Àul! êB¡p†‘Á›èuA+Üê±¼J¯‰tGÛÙ^T^7ÀBƒ­µ Ó~­ªÝ»¹n÷‹jo×E®ª*6?¹®àxó³>:w GŸ¯‚/¼}v§>ý/?W #˜-Z¦eÑÂu•4¨ŠHìJ[5(»Ì9Ñ›«vìÕ ŠëhOOL @š„$#½”)PT†¡þNä‡3À˜ª©0oOÂ2%æï0D6®#kKmeðÚOû¸åxûÖmØL»{Ò0Ó>˜†ôg°°¸€ìܾ>Õ7iÁL$áÛ>¾l~9AÆa™&3× 9>&‹()YCº._¬¦¼m ÷º(+50ô@>„¡ Ãq(áLdä†Ð35%¡³wgá:Tpæ#RÀ”ªê`;J½xbløpfXcÅÅ é»ö #€ÒM•ç€P†¢5…à†ÐQT¡ „2ø¾‡…ä,S3ÈÈÎF:™ÝÎúÊgN)%ÞÚGj¹šÑœ¥zM™ºBwìj CÓ6­"É!lI$’À‡€ï Œ!Ö?Чê*Ðs³SN%}9ïe_ÞVÿô'»öëz@Òg±q]׋v7©ãûoÏcfj–eÂ2Máƒsœ+È-ˆ`ÿKGQ`˜¸yµ³)1uðdÇ€X®®!Áp>r ¯{LÍ(aê’ö¤€”ÒKÛ†ks0áÂL›y쇃%F…ežëB#^r!!u1ϵaÛ&¤ð¬û`ºÌ ~ó<ß½Õ BùÒ'úH(܉ǰ°öðû=°À~,¤hqÇê¾ÒŽþ«-)‘¼ŠÁ—0=÷·cDjÎÜ… Àb---ÿæ¾ñÞwfQp6Τ½gfbˆß‹Ò¥ŽW %NÍb:C¬ãF:ŸI[I;|²OÙþ§“N›åååo…5^˜¨úqgö­WJCsï›ãcù3ÓšÊ)TÎSR×^ÄÜäR¦o§m?5¼ýnwrý/»]v^0h566:äŠ ²mÛ6@–G½œ]ÃBª³SçþF?šUXF=gnlàzÿ¬¥\é˜)ýÊôéœ"e2•*¼;0Ðf¯ºš ¢¢BU”|ƒ±”îPªKßÏhjhÌ«¯¯)<~âÄ_Ì÷-w~>FÍöövoyý?-Q$@¥þö%IEND®B`‚eric-6.0.8/eric/icons/default/deleteBookmark.png0000644000175000017500000000235412342633754020657 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÛvœœê!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“?IDAT8Ë•“{L[UÇ; Ú](C¥…ò’È2Y"“à {À6£ÃÌ` Œ13ƒTŒÎ°E%!’YÂÝÌ`ãQâP–¹‰C·È°‚P ímo¡--°BÇ£_÷Ê3x“OÎ9÷žó9¿ßïœ+­ò±ßÎQ;µEE­aaâ•Ê#JewŸJ5¢£ñ-âíÁ„ÑÿyŒõ¢­ÃWŸž±´mÄ­•Ûœ•…±š8«ªø>›žŽ&¹| 3<eÖŸÔ˜µV‘,DoùÔ?DmI_Œ¨Í¢î%19åCø ùˆùh ))誖hDÕ%!~=çýqt€Çvœ„$á^%^L{çÙGì'²…»Êß>rþ@o|_ˆtÇhÏ[:)…ƒÓ|3p‰Ó’Ôz˜jšAâç‰tâE\<æ]Ôî­´T¸»|IŒÛ¶ ÿîn|ª£@ùÒ#×ëF•Dmh ˜¹ß›I¢gH@íf"™p;Õ=•H£)zëËtT¶Ñ#€ó}¸‡Þƒ®a½çJóú’w÷ÎYŸ"sk8fLÏ‘LµˆH"†Ä´™-…P“˜6päÒ¡—€ý6í•Òòå~Š5¬fíœ[ŸD ÃH Xå<Ä“p ¼€þ: »Ò/,3]{0ŽR ùÇbÖÿ 9&z «ó1¯$Žâ®îk‚q|¼}ûîäöîÝ644fDÌÌ衽½‚ÈÊʃ§Op'JƒanÝâðÐÇupÇŽ]_àõÿÁ8>|ð °lnÎh©«kn›œÔpEðìÙ ¸téE@pðy`2Ï/Ý3™çƒF3z½ÁZU%­Ç#1ŒŒ(uÈòX >ÖÙ)ŸP«gÈÖA«ÕƒDR11ñg=qÂwÁÓÓÛâîÎ0yy²„„\X¸r%RRÒajJ‹>Fô™¥rÚræÌÙÛdÕÿiöö[~ÌδLL¨a`à5$'§AllE§79òUò¶m;ßÇy[\\>÷ñôüúµ¿?sÍNêêZ >ííò™C‡Ü~Ã9þ+WLRÌ5##§fxXO == Nžô£ÜÜè>«ØÖËëäðõë,3æ7(cxl½ä‚ÉÇ—çØìNH¸Y—'=Þ§éï†Ç%””Jùø|÷l­ðö>åa.-­>±öÆö+¡l6ç,‹•D  RM#T,Vz?2®¾] _òùù]Ý݃”H$…û÷ allb©„++Ÿ˜Yj‹]Îf'ga ÿIKË fgõVò¾¨¨ D" ÔÕ=Çõji´O“W‚Ã9œ¿äBa-žm™º¤¤Æüða9Œ«–V>??Q¤:::©©)µö3 ÈÏOŠÅMÖ’’Úù]»œxKÝo¼ßÁa+Ï×7HjkkÇ¥Ó½Ë%’FJ (…¶¶ÜîFd±X@§›ÁR@yy%6 Z’ïvvv\í ÀÃñYçÞnBGP!¤¿:88òe²¶¹žžAÉš°º$ Wâ±T#¬Ÿ5@WW¼|ùÂÂ"ê–‚ecó-ê4jëZmÓ=..¾].W`â÷¼½Wß½{·K©TšU*öÉHhhh—Ý÷æÍ~¤YK²j#ýØÙÑÑQtçÎò€€ †åôáËåòYN C‚v™#І]]W£ýÓFMGQËy¹•š››«J¥4­j9÷ýQ$PçPë‚×ø™’^ˆ*BÅ ìÖóù.›kÊ(wHIEND®B`‚eric-6.0.8/eric/icons/default/vcsCheckout.png0000644000175000017500000000242412342633755020207 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØöÛi™tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“xIDAT8Ë•U[LUþæ¾;{½Á‚, Hl”4’‹F¬˜ÔÄߌÆŸ|öÕ'Œ1ñ…} 1%ÞÒ4ÔÆÔš¥S-µ¤–´Eº,{™½ÍìÎþÿ¡ƒ Oölþ9ç|ÿ÷ÿwf%<KKKr*•Ò#‘HO½^©Ñh¼ÑÙÙùd8ކ¡zž‡V«MÓà8Ž[©TÊÅbñÍ̓ÁËåry{ww·1>>î1žÄ_ x¢££ã]Š7i¡±¿¿Z­&ÀEßóeYüæ ubŽˆ8–e£DÓ”ð÷‰‰ [™™1UU}5 }F‡yM @‘Y’ˆ®ë”*ÏýÄ LÏ ªô­f³ù4Uó!MϪp–Êy™b˜òà²}PÞH‰™º®+æ9Ú«à{ÂxœbRØÛ¤M?—Å@¼ˆ¯Ì˜30±@µZ="Ïû‰9ßóól6;Æë8AÚ˜T g<,ƒ7µëëWáWåƒsð=Èçó¦&°8‰oær9´ƒ33fâëéËãWÔN€aˆÞضÀ´¹D™4²‹b`rLÓÚúùúuþ ¾¸}^[†¦c²÷4NY'cj®-€)ó>w›32“t:-€¹¥RI<Ÿ»u¯MÂPt´/Ü,Û0c&tbO¬ _ŠmÒùD!_YKjªð-;‚ËlÙ.²ÕlÇÆ@¹ /¤žYY™žÿ„ô§éÕT¢fTøXST!‹íÚBçè} OUâJä+®JY^^vèýy^D«Ä´dÉPH¬kww·8…²+A·e\-­"Ó“A8@®1LqêdúllmàÄß©Œž~/ê8·¸¸ØÝšŸŸoŽŒŒÜ&¿~S(.ÑK»EîHS3CôLªÐqÏÄzQ^ÛÃZx ©~Ä‚Q芆õì]Tç6¿Äèšì ¥ššjþƒüïq*Å@ðÂøk§ŸéÆÍÜ:æç.ÿ†Õê+øÅÚn_ª<ðVÃAÆXß •ÆÍp(ùóÍ«wÝ?­÷±P¼v|éÃóèÕï{;³}oÄ]µ>BÁý÷÷ø²üˆ,µ!»šIEND®B`‚eric-6.0.8/eric/icons/default/adBlockPlus16.png0000644000175000017500000000202112342633753020267 0ustar piotrpiotr‰PNG  IHDR(-SsRGB®Îé pHYsMœÞöœWtIMEÜ ! `;èPLTE”»»”¾¾•¾¾—¾¾°ßß®¼¼®¾¾­½½®½½®¾¾±ßß²ßß®¼¼®½½²ÞÞ³ÒÒ´ÓÓ´ÒÒ´ÓÓµÓÓµÔÔµÒÒβ²Ï­­ÐÆÆÐÇÇÑÃÃÑÇÇÑÉÉÒÉÉÒÊÊñòó êëìíîîïïïï**ððððð ð ðð%%ññ ñ""ñ%%ò55ò::ò==óó<<óHHôôppô||õ__õaaõggõöooövvö||÷uuøººøÏÏùµµùÓÓùääú¸¸úÛÛûÀÀûÄÄûÈÈûËËûòòüÐÐüÜÜüßßüææýççýèèýîîýïïýððýôôýõõþ þþúúþÿÿÿÿ::ÿüüÿÿÿѼ¼Ò¿¿ÒÇÇÒÈÈÓÊÊÔÉÉîïïðððððð ð ð ñò00òEEó;;óBBóNNóRRóUUôõmmõooõrrõssõttõuuõwwõxxõyyörröuuövvö€€÷……ù ùúúúúú½½úÂÂúÅÅûûûüÑÑüääþþòòþóóþõõþøøÿÿ??ÿzzÿššÿýýÿÿÿkJ×?ltRNS³´´¶¶¶¶¶··¹¼¼¿¿¿¿Âõõõõõõõõõûûûþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ¶“bKGD¬Weò‹ IDATÓc``a`,TTPP,äar@Hrbꌙ3gdôˆ300300u¨hh†J?Ë.Ùo¯SSV\\R­eß.ÁÆ 0AÙº¶ØÂ¦ÁÔ ÎVµ—¡ E}iX‘Oö’H«Å«Wä0(NÓÏ^¦ãe—íßì·JšAiª‹ÿœF·ì賤Ù+¥¦øÎ Ÿìš<)ÆqaœÇt¹¹ÁYk‚<³ÝêÕæÉ3äf˜·,ðNKµŒmR_”ÏÀ=AE«Ø¸ª¼²¨´BO¥—“M´ÃI¯ÜÈ°ÌØD·µ[„èV¾N°Ó55Tº9€\&±žåóæÏ›·¼O˜$ÂÆ“' y\ >:ÿI°f_%IEND®B`‚eric-6.0.8/eric/icons/default/restart.png0000644000175000017500000000241312342633755017410 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ˆIDAT8˵•klUÇï÷£ÓéîvwûŒmÁ] ‹Ûª‰DÒ@ZºÝn»¥´Û÷+mÑRé+…I4 …ÚH•@¨´h-%* j⇆ýƇÆ#(4Ęîß»k¦|Äøá—Lîœó›3çÌÜKÿƒGߨ# i$;h½¾-}ÎÓëYÈéÍ eueÝr´:¾¡Uô0)&+ÌËÿ(ÿÑb®ŽxcbÉy9åGÊÑýa7v±{¿Þ‹ÏÐ1Þ‚Á5Æ]º™ì#^ÇxŒV‘éõƒëç–ˆI€Èb5ÿqj[J¨ù½fìùrÏ_~ȳ»žñåÜw|½¾qh#¬-,K•ü%O¿:Ñ}±{}3}è™îY²Þ;Ó‹ú“õ(-EÏÅXÍÅb¥J(qÖÚC-ã-hlÐv¶ ÞÜ€Œö (B±gÙýÙ¨«EëùÖ(çþ$®!6*&åDÓ7«wóä#x<!0@rS2¨—‚/ä lâBR¡ _Ó…Ò¬`ÝÈ:ßgñŒ3Œ± Ìz#*6ëåWR›RàñÝÇQç_Ä>áNܹ"s€ðñMDÒâVÑËßãÚ)èе'ÖÂ7ÁrN3Nø˜8&*Ž ªŸº;\È{#/‚k› ´Bö wx?oY4`/ñÈ>þ†ÐÇ*¡H;ž†¼I–wšq4±µzTS¦Ìeöd"wWn„p?¥M<¤Rþµ¤ŠPÄÍ l_Ùu5 ¹Ÿä"ç\–¿µÖV(•bT¬ø¥ß].¬Ø¾î—Ü`~Xbý­|@,$×Xâ«XÏ«ˆAR…¾ŒB(å 8uò™H, ¦²WüM)S —ëЪ5¹D Qßbñ¢‡ W"‰¶r•·Ö«ÿ¥¿ðcxú¤Œ€41ºbZ$ð~:ñ(1-"+- šChäL)À©²Oãƒ]$f½ü\õ `{CDJ^%Ð%hâ<õß’j ‰K(æ¦ô×¥|ù Íí§ËXŽÓìS ½Aäî‹Å2ngL©Òɤ{X Ô!)ƒ&›²|›õï“å‘"òv+%ÂõÄã¼ãˆ¾ËVÕ!1Ÿåä&tËåv!*f}6Y;æµt¤, £Vp"q§øv}ÁÖ¤-$vX},á¦ëdüµ´c–)s0nXé²ë[,Íê3K¶Mâ'UfP ‰ûÙdËpŽÆ€%bå)ÖœI„çl2²?HŒà9›ÄÖ’n±{³éÇ,“)ï˜ûm­úÛlË~è~ÌsÓ©ÛM؆5¤5á~׎5ãIxòBÜ—íXvÕÁ}9«ÙÚSãI·Wr|»¬ßv™øÈ¾òP1ë¡ÊÓKöf}Á}ÈŽ¬±¬™J‚ëJ—Ù>—Ú?ŽÖA…ÇA—ÕB‹ÅDŠËD–ßG—ÕGšâI…ÀI‘ÔIžåKËL‡ÂMŽÍQ’ÐR†¾T”ÑVÄXÃY™ÔYÙ^¥ã_›Ë`¨æ`ªég¼i’¾i Òj”Áo¥ØržËs¦×t£Ñu¥Òz£Ìz­Ýz³æz¶ê€£É‚­Õ‚¹ê‡µÞŒªË»ä½æ‘¿è“ÁꕲЗ´Ò™¶Õ›µÒ´ÌžµÍŸµÏ¢ºÑ£ºÒ£¾×¤¿×§ÂÚ¨ÃÛ±ÂÕ½ÌÝÁÐáÊÕãËÖäÐÙäÒÖÛÓØÜÕÙÞ×ÛàÝäíÞÞÞßæîààààåéááááåêåååéééêêêëëëïïïôôôõõõööö÷ùûùúüýýýÿÿÿJ–÷ËLtRNS "*+./01?@ABCHQST`abbfiu~€€€ƒƒŽ—™ž£ª¬®®²¿ÀÂÃÃÌÎÎÚÛííîîîïïóóž8æ”IDATÓc`À˜øE$ää$Eø™E9e5LìÜÝíL4d¹à‚ŒBJVïß½sëÎÝûVJÂŒPa!M—×VÍ1eöŠ ·u„ &(¹Ü;Ö»e×ÎÛ×7í¿é¦Â ¶MÖêÁñÎöœ<½{õÊŠ7meAöòk<¾Ñ²dñÂKW=Ù7kfÁ¹Ûzü@a“ûk;¦Mž8µgÝ“3 ñK¯›‹…%íîN¯­)ÏKŒ:õdSxdpÛe) °œûê’œä¸è ON‡øú„]õ” ß‚ï}2/,ì!6äÎtp̶ƒ áö«öÒ`+ï®)ÎIKʘ¿fD\²°sòðrs°1CŒ—?™ Ot‚aIEND®B`‚eric-6.0.8/eric/icons/default/runScript.png0000644000175000017500000000241712342633755017721 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ*"x?tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“sIDAT8Ë•”]ˆUUÇûœsÏûuæ’3ã1Åoç%Ò†J¢ F¢,*B„> | zADÃ×@)|°—Š^²"²D°žÔ GÌïiFGõŽwæÜ9_{¯ÝÃ;ŠL‚ ÖË~ø±øý×^Šyê­=Gº ¿ˆ‘Á0ÉHµ`ÁÁäÝ“ýÊ—¿y‡ÿ)g¾G{hYWið™†8¢L˜N„±zÂé±pðn˜âåÍ÷˜UZXɱ¦7Às‘‡Û0R7¥ÇòÛÙ Ž› k”h¬V "¦7†Çˆ÷ÛLjPr F4uãìjE„rÞ©ýùÇŸv8S¸¹ Ê <óâÈxï7¿v5mÇ¡ÓãI)Ì@ŒaJÄŒ1ˆ(Ä(¬˜Ù‰[*ʾ_«Uë»u^Qš ˜_›¶Ÿo˜õ™qј‡}šv·5¬:ËHãiŠÝMŒ‚cúoŸùèåî§¾øÀ™¡0¤Í}wVZ«õ èÁЬHK—¯¨Ig;)øùàë«ÿÙàEIV3æ~ m‡V ÖÜïö;€ïºZBÙ»&ÉP6䓵æÔp€&íÄï§n¡ä …çx`]Ä´'uéïõZs–ja$kµÍÈRònµ«’cP¢ìKxgm… ¥Q °¥,ؘå{S>ÃEÍ;JOå¢S03-p!b b±ÂâÀåíu“ ,¿†ëÎFlD3ÝTLëUܘ¬K¾¥Ï0qy‚f:ŠÍõqsJz¼RÞ½iEjm¿µ"¬ªÕ[PkÁÑ÷’~le#NQry·€`Ñ:‹Ïèp|ÁÎ;=gYÕ;ì`ç’J>y_µ¦´z.u¡9uƒ0l/t’ó‹cÐZ“ó‹ä U°)W®\½»{÷ní­î­|2>9³ê„^í)¯ÛAn"i'’ ’a­fìVùâݰgA¹d«Q9Fg„Ñ ÁK}ÇõˆâDJ¥ÒsûöíVíŸòóá£CnÎ6‚cëkûöb³µ-°FDóÃÉõW{—<ýd¹RÍ‹E&ïŒÝ>waìC×uéïïßS.—W4 €èâÅ‹ÇçnÅ«C/Ø‘Znmk•«é𦖥IDš/âyŽmù|^ÇQ333ÖZ‹ïû„ahÓ4•ù¯›Ñ¸¤-°Ñ`3Ö-:ÅùÛš¦ûžçá—ç—,™ùÜZ«*•ÊR¥F#¾|ùòwããã_Í ¯÷4û:Gpl†š]þ¾Î˜;ÍkÜÎ"â8Ïì„˃ Àó<Œ1Ôëõ,Žã;vìøËüþ{[~ŠS¿ÇsZ¦¥,&#É\êÙJRw…ÅŠîȲB±èDQGQ9ŽãÇ{{{OªGë«Üà&Ã]õ/b}.ÜZÜÝtÖŽ^¿wºZ­®\¹r‹RŠK—.};==}¢»»»óÌ™3ßoß¾}”Ç­mÛ¶¹@yóæÍ¯8pàÔþýû‡7mÚô.гuëÖ9µÿµ³ß׆›×ßIEND®B`‚eric-6.0.8/eric/icons/default/mediaPlaybackStart.png0000644000175000017500000000134012342633755021466 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<_IDATÁ¿k\uðÏ÷½w9+gÎ6mš!ÕŠ8 $ ¤‚Ô! KT4Ä? Cq°S)Eq˜ÁQCD0ƒƒ¥tÌbH,:™"êi-g~™¼¼{ßçç*ÜjÅ ãaÌ(6ªukÉêü>¡psÊbo°ÐÓC&S“u\»¹*ðq;.ÄÙ#´œ5¤ò§§öÑ”,%×?éB¨0ß®6óá}—½æœ† ¥ûØÑRß #·ºdÐ[8ÎMzE¿šLD¥–i܇ûÌ*M•ßu½e\KŸ=$ T8qä'ËÚÒ·?_I÷Zñ‡Ã3—Mê÷Œº‡»¤.dR‰¶¿tÔ^¿ÿURLœ ò†~u}RlùÌ&©š†¦wp2XL$½ñÜs.¨É¤¹øÂ‚¤jêš.ÊõÆ“8vj@®”ÈÚÓõÀ‡~DPÓç’Sq,‰£…!uO<ñ¯§þ±ëS‹Ž¤R/)ÄÑ,Šà7[þvâ¼óúDQ”Å0ô»JHeê™sæ]AOe[7’¸žèÈ•J5Mmg½ëŽ+ˆJ¥‰¸žÅµDÇ~… ÏpÃU@¥pì±D\KâªÎ¾w,W(5½é¶«€R!·ìN\Måßn'3».H¼`RDQáØÏ¾Ö>¸½*LÓ›MÍÑTW“‚R!÷‹/Ê–îÎ*Ì´«ÍÞð±WÍ8£O*¨”ŽÝóPC¶Fît ˜nW q6×ð¼½,øÕ¶Gê’¥pýnBà½)‹å`©T"•J¥×–WB€÷[Õ„qcF±aÝZX½·Àÿhó³ÍØLHIEND®B`‚eric-6.0.8/eric/icons/default/importShortcuts.png0000644000175000017500000000204712342633755021160 0ustar piotrpiotr‰PNG  IHDRójœ PLTE3vÇ3vÈa‹¿`‰ºKKKOOOGGGu“·w”·jžàiÜdddfff‹‹‹ŽŽŽbšábšâ™™™ššš¤¤¤•••ššš………¡¡¡®®®   ¡¡¡«««¢¢¢¤¤¤¦¦¦¨¨¨‘‘‘ªªª²²²“““«««²²²•••˜˜˜U’ߘ˜˜ššš©©©U’ßžžžl áŸŸŸ§§§¨¨¨¦¦¦³³³´´´l à±±±²²²´´´w¤ÚHˆÙw¤Û‹¦ÅÁÁÁÇÇÇA€ÏBÏÏÏÏÑÑÑÒÒÒÓÓÓÔÔÔÖÖÖ×××y¥ØÖÖÖ×××ÙÙÙÜÜÜàààáááãããd™Ûn¥ðo¥ð~°ñ~±ñØØØÙÙÙÜÜÜÞÞÞâââešÜo¦ð|©à|ªà}©Þ±òš¸ªÞ«Ýƒž¾…®ÞŒ·ìŽ¹ì’’’“¼ë”¼ë–¾ë™½èš¾éœœœœ°Ê¡Ãꢢ¢¥¥¥¦¦¦§§§§Æë¨¨¨©©©ªÈì¬Åã®Çå±±±´´´···¹¹¹¾¾¾ÅÅÅÉÉÉÓÓÓÔÔÔÖÖÖ×××ØØØÚÚÚÛÛÛÝÝÝÞÞÞßßßàààâââãããæææéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýÿÿÿó:X–itRNS "&./347>ACvyšœŸ¡¢£º½ÊËÍÎÒÔÖÝÝÝÞÞÞßààáâââãããäåææææççèèèèéééêêêêòôôôùúûûûüüüüüüýýýýýýýýþþþþþþþþþþ¼¡vQNIDATÓuʱnA…áÿÎÜï†uÀ(‘±©©.Ê €ò‘xx hà9((hè‘(¨©"%QB„ˆ×E»ž;ë¡p,Òpºóé—0-€U,–A€xi:Ú ßô0z÷Ú|ú’Tê˜wd¡Q+ñªóG…Áá/ÎSrá<§dOÏÌ8òõ–%§½7Kî*LÌ(7O'&æ¶Ó ÖÎYŽ Õžè¨¯æÞoEKã.¸ÞýjÄôþí äÃQ|þªy Ç;RÞ¯ËE­|;ß¾§zrÌH¼?­J­Q(›Ùà‚6Ù›=çQÅ^÷mx²Ž=© Jnw‹ŸN^´»×Ù.³à8xþLàÇw 7ÊðÊ›Å-Çv àx5Ó¼^õø'€®¹qÆ?¾šé†Û;|q°©ÃÙ6Ýðj ÀúNŠ çØðÿý#æˆúOaIEND®B`‚eric-6.0.8/eric/icons/default/konqueror.png0000644000175000017500000001332612342633755017756 0ustar piotrpiotr‰PNG  IHDR00Wù‡gAMAÖØÔOX2tEXtSoftwareAdobe ImageReadyqÉe<hIDAThÞµ™y°žW}ß?ç<ë»ß÷î«®vK¶$ãÝ€¼b›ºÁ˜PBZAÇ’@¦ÐN: IJÒNC&ãLÁØØu°q°1`HXäpŒl#ËÖ¾\é^é^é.Ò]ÞíÙÎÒ?eqbÐöÌœyÞyæ9ïóý>ç÷ûþ–#¬µü²£Ñ€/œ„ã›gg >‡´u$Ò·XO¡•ƒI-‹õP)®p”ÁÚ°ÍS߈]wû¾!èëýù1ˆ_–À–á¡£ˆ3b´qÒ e ¾T¶ÞnÄãJ›>m­§µu¥ í®Ó²àÕB4t48Ò‚ÊÐÓ‹˜º}ÇZì¯öƒøÿA`ø‚‚#ó?ÃÑ˸8/Õ«ÏžZ¹mq©ýæ•åèÒ(ÊÆ2Ch-Xk1Æú¢-y®TôŽŽÕ¿54Xû¾ªzF8EôÑ}]æíýH੃ð«ÃgA‚«¼@bm'Û´|zqÇÌÌÊ»;z( =¼ÀGz.Ò8RÐI í̦Š,ÉÐq YFOQžë¨|gýæ¡ÿA-Ü“X„T(,ꄇù7û¾‹ùC@ãÏÀWûåa¤Âu27i-ç"M¦ Jt¦ˆÓŒ¨“vbœ(¢ì‹•-— Þ×»vðó‘çUã ’®ôÍG°¿yˆÂ/I`¢ y14„£pðJÂŒŸ9tö÷žZyG©Z¢Ü]¡Z-P)zøRÐQ´!Õi-íT³Re°&¿¯2Mšdˆ4Au":Ë-ÖWžßòÆ ÑEÿp¦0%Ab|ÔÎìÕ=¿É|¸ŒX5“Ì ‡ î˜uGöœúìñùø²¾þ½=UªÕž'ÆMœYe°Úëüš(C+5D©¦“2mÐÆP”RÅÊr›ÎRƒÑîÂÑ+oØü›Bðr¶‚ªôMoD¼‰½ªú ˆ2x÷×îœñ€°%(Õ¤Ÿzuú3 ñÕõþ:£ýÊåe¡(-®5$Ú⑎Óh'ËÍGi‹Ò†TiRePÆ`.Ó©"i¶i/5¬úS×ܲõý ØëZ’È!iÏ£?w5v ü÷åÏúú_I ±Ùãà54¥nŸ¾Ùcs4µ˜\Ý7ÒÍÈp•°ºP÷!pÀPó ìBÙª®°¸Â"h“ƒÍ´ÍÉ(‹Öc F€ }*µ"§Úã'÷ÿ“n‘8£ [xn?âaïµ*©yxðÄè Ž|—‹í÷?Ó¼uõª.¶®®2ÖãS¡äBñ྆ 0V„5AÕƒ‚#(»`Å ÅZKjràÚä$„±ø®À \ÜbÈˇæ®X8<óÁ  ¨] …&î×ö ~rêïqº¯‹ÞÀCÇÁ©#d„Ÿн˜‹;w[.2Ô_¦¿Ë#” -h« P‘0×¥-Ž…ÌBÍRÐL¾È¯)¦DÚâIXЖԂã;ĮË/Nì¼a°ç™8`Yƒyhuùˆà§ì@SÂOêЦí¡]lœYùõ¥H÷m«ÐUõñ\Ð@Gƒ.*ÃÚhm1’ –"C+±tRK;8ª¾ ¯ );¬­¹„R` r¥Jµ%Î Oâú.‹­ÄŸ?6½£ìRS.…®gÂEÌú?cöN㿳tî·7Òú•iJ‡çE¹u êܶn¸L¥’!é¤àÊ<ÜK à_Ѓ.âÌÒIÁáoçvßJs0ÖÒ[tˆ3Írd@¢ Ž€Nf(.ÍØáÈá™G6­ºüŠ€¨cQŸ@ÿκ×!¦Šù¾÷‘7oùï C¤×›,¡‘BúØÔ¥7_@ɃÐi`Iƒk,¡ ©-ÀõÀ3!s’€¶jK”YÚ‰¦âAÉ¥âA#ÊXlAàI’<'_8·Ü)4Î,Üæ­y)…¨'&ù›Ĕ±ÿÄ„”ïòÀì¤ûÔ7¾¡¢˜Í‰‡–&–¡e\|G¢tÄXð$ø„.ø®!ˆŒ ­s"±#Àu-Ž“§¥OP%ž4ËlSÓJa¸âqéPM}!{CZ‰Âq‘²4Ï­l %ý*#p;¸ç3Äœ}øîOsâù“»+ÃcrνÈ8æÄllÚZâûXQk0RKgèä2ªEX ‚È "‰´h,7|èÊ «»–Е$ 暆VjIµ%p$™K¾ ggWÖxÊŽZC¨úâïu›x$Ñ(«ÁýÄ¢844Ô¾xóættd¤Rv|)…Ébg~nÖz½aÒí˜p!3b.2ŒTsGn«†F‰†©6ÌE0å¦fm S–fq–ƒ·6·{+$R‚µa-æxeAY‹ÁRòm•':Ó~ýÑDûGƒÛ§ÐîÄñÏlذþ˜³\ÏÃs$ei¨•+(¥¢Xø“•’§ÂfºVÅ ”â<](º9ئÊcá!PÚæŸ(ˆ\v…G¬!q¥Å"Ð ”±Hò¬VhAà„ç`¬%J4ZYÇ2ÛѴㆧŽJ³ù2£¿çâ¶Ûù¯?õôÏìzöƒ«W¯ûÒ—¶ÒUíe¸¯›b¹²‹pÊ-–²²h®m´;ÈZ‘L¸œOr5?Ä-•O `Ö Œ¶Ä2VƒcÁ¹Í;ŽD`p$XRä»å]0§$³dV“ÄŠñЇ#RÛìÄ¢«ä\yªÕÉŒ5æš»óT¢•eÙÑÅÅ¥ý{ö¼<;q|Ât\ƺ+lÛº5gÓBõðÚž ÓYi£¢¡ ÆX´…3xÑÍ}À¹sÆZY6eÊ -‰ D”Ò4cM'ÕD©!J Í$¯Ü„ÍwEkÖ°¶7 J[c¨ùrÚþzݸ¾ÚçR®h“6®¯ßpý[Ò$¦TërwŸ<ÿ#;ºíüE}…ÁÓg‡šFR }„ÈÃxfç>Þ…˜Põ ù×N/(”1HkHSM–åu²‡%Í I¦ÑÚàI¦óÊη„e˰ÇÂü ž2bUO©|ë*ç¶-ƒIûÚáà sÝu×™S§N5}W\q;w¾÷Žáááþ,I¨×»‚ÅH;Ø.¼Zëë m{ó±¹È…Kà9òC¦A)²Ls¾£h'¥5%ÇJ(9–Pæ€,ZŒÑm(HK𰆲 OàIAÍÌ/vXßãSu[öüÜ+±n¨‹KÆûz¶ùæíçÎÎ\åLNNÒÓÝmo¾åæ÷Ýwßg>³~ýúµQamÞþí­®>x¶±ÿ4=s— –z;ç–†SmyÃ`H¤,+¡2È2â8#K2TšÅŠ(Ñœke$©&Q–@XcPZ KQZ,.†P€0†v¢Yjg,6bê>\³6h?yL–uälbM‰ZÁÚb¹`‘b•˜››-÷ôt?è8޿ʲ”$IPJ‘e)Q¦h§–½óÉÔçŽ?WèÙÄÒÝçæ‡ÞuÕ _9‘ñìt‚¡â奤2er?pIjB ’²/ˆ3Kš)´ÒcF' £4–4UDí˜^Gñ/®Zž˜>{nÿsë¯X5à]»õbºýßûÖW²áÁ~=¾j¬ã<þøãfÍÚµ;7oÞ¼Akã8x®‹%W¥ å@vÕ\=úÒ/g¥®Ö†’^µëÀBpl>&Niª ËH¢fy÷ËjÄ3±Ú€Ñ` JYkÈ2C q¢I”ÁŠ4[1e›ò/¯îtª=/ØûSoO¯ºî²­bÃhs§xñ…;Zi÷ɯ>ùçN£Ñ0S§N±ó½;ïv]—™3Óìß¿=÷#NOO³qý”ÖTuê[çÏÿŸÀQgË–-ÌÏÏ·92èÞ› aH­VEJ‡……ØO¥RfÝÚµc±Z‡e«ÖÏ·Œžuj'¯Xß­ÇU9·°âœYhÒ‰b E7¾®8Bà9’DY&3^Yi§¬4bÒNݯ¹~]Õ^{ÅÚÙn÷ž‰ö¦s§ß ¦o½óêÍ÷W|zk}ñáþè‡ÏÝ <m:O>ù$?þ¸i4Ë#£Ã·tÚíâÞ—÷ê]ß¶õÒ‹?™÷<ϸžSXÆÇFñRZøZ÷¥í´ÿdä¯úú¶­ª1V¾‰"§ÙŒ˜_‰iGŠ$˵=ŠIªH¢Œ¤“àd ã%Ë›ÖTíÕ[GWÒÞÑc/·ü= µ¯Ú:½É›yçöõ=×ô•=ʸÒ28Ø/vïÞ}ïÒâÒžñññøÛßþ¶ÖZÞûÞ÷òÈ#t¹ž{‡ÊÔ¯u`8„7Þ´ýîÛßvÛÆ5k×sÑÅo e _ÔœXv˜n:Ì%nœ……¥Þš¯ª2õDk¹´¼´4Ú‰ÛI´Œ2‹¶’bÁ£Rô©•C]¯Wb–‹¢0wªÃéfGÏV²%=¦f×m)4Þ4^sJõ‚ Vøn4 …ãÇÿàcÿþ?ÜþÙÏ~.ºñÆóæîþýûÙ¶m›k­6‘Õ9àñÄòCüÐkÛëÏ>û,{÷îàæ›o¦^¯³k×.vîÜécz€m;þíŽ>ðùûo›_X Uš8S4K#Ì75Ë™ÇBËr¾Ñìh¢T“e cò¸àCàJž¡â[j¡¥^€þªGÅ·Ø´MÜn°ß>ýÚ®ÄöíÛÙ¾}ûk:-;vìÀu]}Ï=÷,´ÛíÝo½õÖL纑'oå‚ÃÊÑãüð©oÐ=0ÌÀ؆k=˜®"‰(+QÊâI‰Õ)V+ Ž¡àŠž¥äKΜžàäùš+ËfÏO^>´ëûÿ{¾Z­®»ímo]U,8·8ÏÒ—ÎýéŸüÙïÎÍ;ýöÛøùùî¸ãvïÞ½êĉ‰‹Å¡f³‰ÒRJæxìKqðÐ!<Ï£Z뢻·—ZW7]õªõ:aÒU)S«TYl,ƒÑHkÂà{=úXûù¿yþÀäÉ©]FóÇ^{U±X¼îîwÞµeph`áÁÏ?ü‡KKKßÞ°aCs×®]fttô§´×_g¸®Kš¦ÃO~í‰Úµ×\kGFÇD(š­&_}â þêÛ=3}úôD___}Õª±aGØZèJׄ.&° ½ì}é9ŠA‰o¾¥ÅE„È«®r©ÄÉ“_õ•ýŸ&/ˆÀ‘N§³÷‹ùX]qØZûŠçy­O}êSfttôgœ¼ÎPJÑn·›O}ýkæè±#âŠË¯à —¾'¿ñ4O<ñÔùW÷¾ükìsós òÀþƒ#…Ba¬T.öU«Õîáá¡Þžžž^‹Ý8>>^ؾý-”ŠE”ÖXkðý€7Î|篿û|†Ù]wÝeK¥>øàqàl~Ði;—\rIúÈ#ØË/¿üŸ9àx±zõj€S¯¼¼ïÊ¥ÊV¯_ýÒÞ—xô±ÇÓƒû÷ÑûpìBFQTˆ¢(<·p¾pbâdÞ´iãomÛ¶õ¶³gϰnݺ×HãèèÈÞÿýìØ±€»îºK=üðÃ+Zk6oÞ̇?üa^k?/}ìc<ðÀÉÉ©ÏNMzþàƒwÞtËM·ž>yâ…,M޽å-oiß}÷Ý>|8~ñÅ—±oß>‘¦©NNNN ¸®s}'j­…V«eµÑ"Ic¦§§çjµÚß½óÎ;ïäÎ;ïüÙÀ¬µ?÷|衇¸è¢‹=ÀÅÀ zã7Šf³ùOÖ:tˆ/ùËAà[ÞóëïþîÓõ”ýÏÿ]û‡Ÿø¸ýìýŸ±÷üÆûŸpg¼\.‹3gÎüB˜~¡‡­µ´Z-î»ï>nºé&Â0”…BAÞrË-¯ þη¿ýíµ‘Ñ‘_{ç»ÞñƒË.¿ôém—nýóõÖ߬Ü{ï½÷Æó /ø‡sff†™™²,ûgŸýæ7¿I©Tr€0 ÀŸþô§) ÿ‘‡?¢nqIEND®B`‚eric-6.0.8/eric/icons/default/audioVolumeMuted.png0000644000175000017500000000127312342633754021216 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsbbË<tEXtSoftwarewww.inkscape.org›î< PLTEÿÿÿŸŸŸŒŒŒššš‡‡‡™™™———ÿzzz’’’^^^ggg___ggg\\\dddaaallllll~~~NNNTTTUUUWWW[[[]]]aaaccchhhnnntttyyyzzz{{{‚‚‚ƒƒƒ………ŒŒŒŽŽŽ“““”””———™™™šššŸŸŸ¡¡¡¥¥¥§§§©©©¬¬¬¯¯¯°°°±±±´´´µµµ···¼¼¼½½½¿¿¿ÀÀÀÂÂÂÄÄÄÉÉÉÊÊÊÍÍÍÎÎÎÐÐÐÕÕÕÖÖÖ×××ÙÙÙÜÜÜÝÝÝÞÞÞàààãããæææçççèèèéééêêêëëëîîîïïïñññóóóôôôúúúûûûüüüýýýÿÿÿÿÅžghtRNS!!FFvv€¨¨××ìì÷÷ûûþþé°ÓâëIDATÓc` $$$0™xã%1DYøÕâ#¤ÑEÙÝã£dÑD9„ýbƒâ#åPE¹E#â#­âCåQ ï£í¡€•Žó÷µUŽ´SdàädcùÐÐÐXG¹`cÎ8N  «Xéꪊ{k©•ÆETtuu]Œ45ÅÜ´‘„åmlllõAª=M ‘ööö6344Ôòu@²ä@%Sss™`/Tïp‰XÚÉ…‡È£yž]ÈÂZ>ÐW=¨XŒ½Ýd1–™OÁÕI3yìí$‰Ž4T9»&Ó¤ÎlIEND®B`‚eric-6.0.8/eric/icons/default/ircNormal.png0000644000175000017500000000140712342633755017654 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<ƒPLTEÿÿÿ€€€€@@@333ª€€``DD3P@0Q]tNUy}ƒš„‰ži\Hƒm[_SB€…Ÿ‡t^‹……t€š‘yf’‹ˆ•›°iX•š²§®Â”|f«¯»­¯¸¤«¾²·Æª±Ä´ºÊ­´Æ®´È«±Æ´ºÉÀÄЫŽsŽs¾¡‡Î®ÒÔÝÚÚâ½ÃÓ¿ÄÕĬ•µ—~ª‹oϺ¤‰kLŽkP•sX˜y^_¤„j¤†j©r«‰i¬Œr±m·š~»™y¼Ÿ†ÌÐßÎÊÎÎÓßѬ†Ò¹¡ÕĵÖÙäÛÖÚáâêáäëäȦä˵äéïåÕÈåçíåèïç½’çêïçêðèêîééðéëòê•êÅŸêëïëÉ¥ìɤìíòìíóìîòìïóíÆœííòíîòîîóîðóîðôïÙÂïïôïñõïñöðϬðñõðòõñ×¾ñØÀññöñòõñòöñóöñó÷ñõøòѯòÙ¿òòõòô÷òôøóÝÇôÜÂôÜÅôßÊôàËôôø·¢B4tRNS#-2-¶IDATÓc`!Mu~$ mfjë(Šà3Ù˜[Úk!8"óªÓ |®ÑùuõnLpí˜òšZ $C%‚²Ë|8ì"­Y‘í5¶01@â2 ûûZ¹‹±A¹Ì2:¡^žÎa º²ì`U¿´ªâªªªÒØ85ŸÇ)¸¸²¤¸¨8'<$( èX‘•›“™“š_(Ôs‰*ÈHIII ðÐÂ-"§¤¬¢ %Èä-]$©å8ífIEND®B`‚eric-6.0.8/eric/icons/default/historyClear.png0000644000175000017500000000247412342633755020403 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<¹IDAT8Ë•{L›eÆ0%13èÆ8dMfö‡nn.L'Á$…ÆÒN®í¸”Ò¥”RZ Ð¯ ++—VZp !ËfH4Œ±š`4ŠD·,Š‹Ó9û­°ÁvÕò}¸Ž¦£ã‹0|g†Ðtˆ¬£w¡sàWP¿Ï?_º7^¿Çell2Q`ÙÑÖMÄ8DO2ÝÏ6qÔí¦©ygòÝé™ìžÑÞ¹&Î6ãêÍ4âüÇ™ú³ºÂ³kûL‹ëÌYçjôÔÔ,óÞúƒzC×-´`KWhk+/‘iS©ËÜ8.ìdzLá ÓSZìuýs c3À°vÚuB±ÀñywOÃìÂJïܶÎRÝÓXFz×ÇâxmÛ¿¡ŒÁå#yb][K~ÿVn>¬¶V°uYÀÜjžÓu Y_Œ ŒžÆˆ¶àÄîðrŒŒûJÒ|)–—ŽI¤B`±S@€—S]ƒôõµÀËÍÁA¢œ{buE¶»½QßmÁA¦ðËaRÀ¦üc¸r22@ìS,ø8ƒEâB(,ʇ„¤8ÈççBÏз/‘òßi4¦ã¦÷­FºÃãÚ¬¡Ñʽ‚3(›J£^ÃÛrxYš–ñ‰']¦$¤@(\{7²‘ÚG.!Ä‘¼–ßqX^w½AŽébms#åïÀð¨õà°P †€àˆõC¡Ìɘ,E;©Ùñ ‚8¤ˆcmÇâØK¾ÅìMê eûAIŒ/¨Ùo‚QgåÑ®•|–1}A•â’ØÝ;¿óÇaÄñ â8°™N£=‡zåÚ BE£âQ‘¨£¨·P~¨](ïÒD•nø[ »IEND®B`‚eric-6.0.8/eric/icons/default/printPdf.png0000644000175000017500000000237712342633755017523 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYsvv}Õ‚ÌtIMEÚ2c‹2µPLTEªªªˆˆˆ¤¤¤ˆˆˆˆˆˆ¨¨¨;;;ˆˆˆŠŠŠ–ŸŸ§¿¿ÄÊËÇÓÕÑר×ÛÛÜÜÜßÝÝßóóó¥¥§³³´$$++"%%%&&&&&''''((())))111133222677999?@@@ADDDEEEGGGIIIKLLOHHOOOPPPUUUVVX^^^___aabbbdccceWWiijlm pJIrrrummzzz{rr}}}€‚‚… ………ˆ ˆˆˆŠkkŠ……ŠŠŠ&%ŽŽŽYY‘‘‘“““””””•••–——‘‘™CC™™™››››œžžž   ¡¡¡¡£¤¤¤¤¦hi¨¨¨¨¨« «««¬98¬¬²­­" ®®®¯¯#¯¯¯°??°°°±‘²+(²@?²²´²²¸³³³´´TSµµµµ¶¶&"¶¶¶··½¹¹¹ººº¿»;9»»»¼¼Á¿^]¿¿¿¿¿ÄÁÁ-(Á^[ÁÁÁÂÂÂÇÃÃÃÃÃÈÄÄ Ä/*Ä@=ÄÄÅÄÄÈÅ Å:6ÆÆÆÊÇÇÇÈ#É.)ÊRNÊÊÊË-(ËËÏÌÌÐÍ’ÍÍÍÏSPÐÐÒÐÐÔÒÒÖÔÔØ××ÚÙÙÙÙÙÜÛÛÞÜÜÜÝÝÝßßßßßáàààââäããåæææææèèèêéééêêëêêìîîîîîïððñññóòòóôôôôôõõõööö÷÷÷øøøùùùùúúúûûûýýýÿÿÿá .tRNS !$5Õ?W¢·±ÙN¢þ¬^³ëp¸É»Ïí›;E’¹¥Ë °b%‚ü åÉc[Ý*?p?Ï÷A¬$PÍ@óéHf5e•€Xy_S®‚?z £ ŒX¹ó9âøõ ±ewK‚1§ä®´aB±v%Kck<÷OÖö¯º`ÃñõÅ3½F¤¢àõc— w><µ‘QQ þö¥g€8ºÛ²‘1*£ ^ÅV€k;@P£65ªâ}íCQy_ÿZq˜$§²ëýIEND®B`‚eric-6.0.8/eric/icons/default/rss16.png0000644000175000017500000000157512342633755016712 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs  šœ PLTEí•OöžWå™Lî™UÌfÓfÓfñšHõšDí}íí‘=ñ‘=énîrêpæoæmßoço×ißmãmçmØhàpãpúË¡ûÍ£ç‡é2òòõõú«bûº}û»€ü¼ô’ô•ô™ôôŸõ”õ—õ›õžõŸ÷‰÷‹÷‹÷ø€ ø‚ øƒø†ø‡ø‰ù ùŽ'ù–9ù™>úFú¡Nú©Zû¯gü³nü¶süº}ü»}ýº}ý»}þþ‘ þÊÿ…ÿˆ ÿŠÿŒÿÿŽÿÿÿ‘ÿ‘ ÿ’ÿ”ÿ•ÿ—ÿ˜ÿ˜ÿ™ÿÿžÿŸ ÿ ÿ  ÿ¡ÿ¢ÿ£6ÿ£;ÿ¤ÿ¤ÿ§Gÿ¨ÿ©!ÿªÿª%ÿ«Fÿ¬ÿ¬@ÿ¬Xÿ­Vÿ¯Oÿ¯aÿ¯bÿ°Vÿ°bÿ±Fÿ±Vÿ±Zÿ±bÿ²Vÿ²bÿ³Iÿ³Jÿ³Vÿ³bÿ´ÿ´Lÿµ ÿµ%ÿµRÿµVÿ¶pÿ¸6ÿ¸nÿ¹uÿº#ÿ¼ÿ¼Hÿ¼Lÿ½}ÿ¿.ÿ¿‚ÿÂUÿÃGÿÊÿÄ7ÿÆyÿˆÿÎ^ÿÏxÿÐÿÓ•ÿÖ—ÿÙ‹ÿÞ–ÿà³ÿâÁÿã²ÿìÁÿìÇÿíØÿôáÿøìÿøîÿøñÿùìÿúöÿüõÿüù5•¥(tRNS###889:::<<=>?@@AAAABBBÚÚÝÝþþþþþþþþ@êÁ|ÖIDATEÁ1NÃ@Ð?³cÇØ B€‚¨RÀ (#¥áÄ4€Š‚Ž $@àH‰lì5;Þ!ïh"øC´$e~Œ xnß$Íæ7Ý>e"³eÀhÙ ›Ç?#![œ 4j„±Ù±­ÕD5g,‰ŸÄ³ú=îQÕT?"ÔßååÕAòð­¡‚sÅt¾8z”iþe@l7 ÖV®»î°Èœ0ƒá7Õ½žútæ³7——»~§ã„™‰á28})bC«:„úÕÓ¤¤Œ¶Ûj†Bº/é:ü”ß\×ték÷IEND®B`‚eric-6.0.8/eric/icons/default/editDelete.png0000644000175000017500000000231512342633754017774 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ—Ÿ§¯·¿Ç›¦ÅŸ¡¡¢££¤¤¦§¨¨©ª«º»¿ÂÃÄÄÄÅÅÆž¢­¯±±²´¹¼¼¿ÀÄÆÆ¶¹ÈÊÌ%%Í**³%%´..µ%%½66¾¾¿>>ÀÀBBÁ$$Ã22ÄÄÄ88Ä==ÄBBÅ$$ÅBBÅDDÆÇÈÉÉ,,ËË::ËHHÌÌ??ÌCCÍJJÏÐÑÑYYÒÒ??ÒCCÒRRÒSSÓDDÓIIÓKKÓffÔÔZYÔnmÕÖXXרØEEØPPÙBBÙDDÙIIÙXWÙvvÚÚLLÚWWÚlkÛ~ÜÜÝPPÝmmÝ||Ý€ÞÞÞÞKKÞ~}Þ‚ßDDßEEßIHßMMßVUßWWßàà‰‰ááPPáooá‚ጌ℄⌌ãããVVäHGäUUä‚‚äåoo充勋匋æFFæsræ懆çççOOçUUçljçzyç燆狋çŽèèQQèedèkiènn苉薕蜛ééHGé^]éts邀镔隘飡êêNNêUUê\[ꀀꎌ꣡ꫪë뙘뤣쑑ííXXí~}í«©í¶¶îllïffשׂﴳððbañññedñÃÃôz³_=tRNS ÀÀÀààààààààààààààààààààààààààààááááááááááááááááâââããä×¶ižYIDATÓc`À عر1­îš@9ìª'¬aLË ×§*±CDÛªM!L›k—˜® ä°«ôUÅg´™Ä¹.^9¾cûöEjìì*Sês“£³S¸€Âlòí§·oX¶m¡¢ÂÜÉ•…iYeÆl SØä&ì_·tÍÚõ æ÷Ö•”6±Aìd“wlÍ’Õ{¶ÎšÔÕ3Í€ æBV™}{·l>²jåì9ë YþaÕ?u~÷áC»6±@e`Ñk]|îæ«—Žš³ ‰j´L\~òìÉå3»uáâ,ZIù53vÞºwcçŒæ ¨8³tdlBùă·7N,ÏI×d‹Š{ÅäõKJ­hÊ‹ —‰sÚ»;zDd¦Š13‹&Ö&Dxø:p…™„\\‚£D˜€LÁ°¸Oa&)LüÎn~&ŸWˆÄN&;^“ÛV æBFF,L,œá1tRNS 678?@BGLVqstuvwÎÎÎÓÓÕרÜÝàââçèéêðòòþþ€I¡·IDAT­ÁM.aÇáßÞ·éèT›ÖB‘°p ½@—.à®á. vn VŽ AtZÆôÃô1´aÂÖóˆµkkfäñ£ºÕë¤Rxu?3|3ÝÃæ|7ýæäÙR)y-¦töjÉœü±-o6€lv÷d—¢EÕ–ýØ8[¯GäàÜ÷¼cêAà!±"cYR©åÌeµÒãFc7¶ 8áöú¥fÀÈ¥‰Oà=A¥=xsMÃÑЂ>¹}3Œ.Ì»›>¦$–Zõa©±}6Á‚ÄJ¹Û…Éz$ŠD΂"g‘‘ø”ñEä,hN‘G΂Ï_²¾ø%NøΧLµâ ¯IEND®B`‚eric-6.0.8/eric/icons/default/fileDelete.png0000644000175000017500000000231512342633754017766 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ—Ÿ§¯·¿Ç›¦ÅŸ¡¡¢££¤¤¦§¨¨©ª«º»¿ÂÃÄÄÄÅÅÆž¢­¯±±²´¹¼¼¿ÀÄÆÆ¶¹ÈÊÌ%%Í**³%%´..µ%%½66¾¾¿>>ÀÀBBÁ$$Ã22ÄÄÄ88Ä==ÄBBÅ$$ÅBBÅDDÆÇÈÉÉ,,ËË::ËHHÌÌ??ÌCCÍJJÏÐÑÑYYÒÒ??ÒCCÒRRÒSSÓDDÓIIÓKKÓffÔÔZYÔnmÕÖXXרØEEØPPÙBBÙDDÙIIÙXWÙvvÚÚLLÚWWÚlkÛ~ÜÜÝPPÝmmÝ||Ý€ÞÞÞÞKKÞ~}Þ‚ßDDßEEßIHßMMßVUßWWßàà‰‰ááPPáooá‚ጌ℄⌌ãããVVäHGäUUä‚‚äåoo充勋匋æFFæsræ懆çççOOçUUçljçzyç燆狋çŽèèQQèedèkiènn苉薕蜛ééHGé^]éts邀镔隘飡êêNNêUUê\[ꀀꎌ꣡ꫪë뙘뤣쑑ííXXí~}í«©í¶¶îllïffשׂﴳððbañññedñÃÃôz³_=tRNS ÀÀÀààààààààààààààààààààààààààààááááááááááááááááâââããä×¶ižYIDATÓc`À عر1­îš@9ìª'¬aLË ×§*±CDÛªM!L›k—˜® ä°«ôUÅg´™Ä¹.^9¾cûöEjìì*Sês“£³S¸€Âlòí§·oX¶m¡¢ÂÜÉ•…iYeÆl SØä&ì_·tÍÚõ æ÷Ö•”6±Aìd“wlÍ’Õ{¶ÎšÔÕ3Í€ æBV™}{·l>²jåì9ë YþaÕ?u~÷áC»6±@e`Ñk]|îæ«—Žš³ ‰j´L\~òìÉå3»uáâ,ZIù53vÞºwcçŒæ ¨8³tdlBùă·7N,ÏI×d‹Š{ÅäõKJ­hÊ‹ —‰sÚ»;zDd¦Š13‹&Ö&Dxø:p…™„\\‚£D˜€LÁ°¸Oa&)LüÎn~&ŸWˆÄN&;^“ÛV æBFF,L,œž¿ÝŽ§Ñ‰ÍèÆvô¢ýèÅvtc#:±íøíæÓ$µ®Ïœ…$ ¡H2IBe 7?÷þÙâèøÄ©®@@ I’dâŒzQYpL’@¨T’pßH*Ví4´[@èêšÏ²ƒUËúúÈd2™L&“a ´¡¥¢ØiW5Ÿýk·¦Œ*d*d¨û¦OÜðÐ’=^PX·æº¡mlÛ²|·ìçúk‹»ÏïûÉkÞ1î€:z^6ã°ÉU Ë­«—:碽ôèj55:5’&MúÙº†d]Ó¹·ÊÕo®\||[™@²£qtê£wß{ëøR}"VXñ öu—ï|ûݽË[÷m €$×°+oŒï«¿¢ê=l?.»:¶”ÿ¥ê>=)-ZoIEND®B`‚eric-6.0.8/eric/icons/default/fileSaveVisiblePixmap.png0000644000175000017500000000222012342633754022152 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚Ì2IDAT8˵”]L\EÇÿ÷ÞÝ ËǺ(ÆR`A ©hë£&&mMlÔ^°ÄŸjÄbÕÄ÷&6¡ôÁ£¨MŒFl|©Q /Ä`±(,´+lÑ¥”mYvïÝû1ã9³w—];äpgvæüÎΜMJ‰ûÑBüï™cÇoär¹NÝÐqþýshoʆ]Ó ñMW_Æ`“AŸšN–ܬÅkgހ𺻻SŸ|:µ_óV¾sll Ë++ˆÕÙˆÞ= ³1š ’ &E ‡¿ÁFÝ îý'ž=ß÷qå»+meÅBŒ_GÏàhŒ¿ƒ±FZB12 p+dí¢¼’Ì0™I¾­ÉC"‘P`!än*8Ïžç©:9i>;Õí@M3°¼ ü’ i¨Ì@å†×W“Eql2ØVYqoO¯ À[Ï^¶, †Öþ8±(z¢˜[ðHüf^SA†„8¥V)öEµb†ódvtŒY ¡—Shnþ ­èðr1ü¹ ¤sR)4 X«KDt¯׃4j)«óƒwà‹kå¯>â£aÓÁ휻¢y©Î´–{ž„î»Ú)”ÁRübN^,Cëã6æ–\lÿ£¡§÷e5wí÷I ¨«³¨«§s@1Xq*sÌQ„ï'nPîjLç°².púÕI$×Q(ë¶ïÐ9<Ôü>œ<LjF£Å À%Ū€8/>§ƒìû~Dzã^ÅA*4¦÷?Þ';ÚÛËÈí­-,%–Ô»pôØi5oÃukÕœi°'ú~þéc,,, «3Žxg'*^ËÔÍ~½zU+—ß¼R»pq ˜ŸŸÇÌÌ fgŸFæîA5m˜ÇÀÀcÁ¥Ï/Á²òH®þ…ö¶ýAuTT—Šëºeð)~ïwá8"‘&&ÎW=‰¥'€w¹±±;™LÙß÷½j°WfG+—SÎ¥÷ºcÙ|öá£?ö7 C±vÁt“ÜŠT(ãÛHªóùü=P¶K/û?L¸šZ«¸ T€¶eé¡R­âÀ²m˜¾‰l6{”Ͳ-ZkÇ4ŸÝÞ®V¬kÆëT ãÑÆFgÐÙ7ß‚Cp>Ømrø/”åwr°-.íÊ5M¬¯¯Wƒ7–/Æ;:°u'3NéÒ©¬ÌÝû¼µ¥-µ›rœ‚ê[–U†C¹rßö/#5ȉ. IEND®B`‚eric-6.0.8/eric/icons/default/zoomIn.png0000644000175000017500000000250112342633755017175 0ustar piotrpiotr‰PNG  IHDRójœ pHYs „ „ªâcytIME× (£{O´ÁPLTEIIIMMM (((]]]lll+++>>>vvv__`111‰‰‰}~~777ˆˆˆ555®®¯œœ———333011‘µ¶·EEE¥¥¥¡¡¡zz{UUVåú«««„äûVVWtàùtàù{áúmÞøkÝ÷~áùxßùcÙökÜ÷cØö`ØöbØörrrVÑòWÏñTÐòWÒóÃÄÅLÁéMÄìKÀékkkI½èÅÅÇE±à‡‡‡D¯ÞxyzA¦ØD©Ú@¥ØA¥Ù¯¯¯=šÑ<˜Ð\ºãhÆêD~¬tÒð€ƒŒŒŒD„¸ÊÊÌ8ŒÇËÌÍ_³ÞyÂåAÇ}Þø¿¿¿~Ãå†Ýö2|º€€€¼¼½}}~†††g§ÒÌë~~~.v°ŽÆåQÂ%`ŠÌÌÌ/k«5|²»ß{{{-i’Äæ›››ŠŠŠ*d£•Âߺº»vvvg¡Î§ãö,õÆõ¤ˆÐĽ\0á–¥±%ÇO\¹xìhy`óva˜pÏ‚à¼s._:¶Ð§z‡4L¸lQˆ«­Åµ«æVN^saÂîÛÒ â„‹³Î[^“’?}õŠ/“ùê|›¦ÍïŒTSzïE‘("˜xÄ$xYûîôz#ÍIDATÓm‘ANÃPCŸí©‹Þ„-÷¿à °)ˆ4iòóYü¤mP½|²Æž‰gꀗüƒËÐy»ØH€ø=ÀùSŽlÉBœÚ¬X±Ý°W¬8vlÉØŽÇ’ÉÎÝp|/ˆœ4Ž­'‰=¸;]°@{·ƒÕÖÜšx¥uáæ–Üh™¦å¸5A$æßþZ¾k] ÚP~¾†ÌóX}?§Äدš†Ò"q»ørõ1\¦-rU]JûéVðxèl)§¾Q¤ÝÓêPvúB%áAÝà ‡€z*bбŽpør-àíÅŸ·%6G˜C3ü«~Ù,œ°Õñ½éF µºÅZ‡>ñ„²Ãª.‚Jý éå“SøƒÚÀ ŠÞøûY"`½+Á­,0jPÄlZ]̯£G‘Åû+× (»ë:eP_¨%~³º¥cB)AbÀõ.ள‚‡^öéâ¡cê© x! 7•pËh9~7ï Ú'`»U‰m‡Ö¹ÙÂÍÅϺ…læôƯ$|µ—'Ç’…+oz¥Ñ “©t.ª aºÙoÏ.øzYc°uJbÐ…’uÞ8™â°™…Åy^iLMò¤3eŽ?ðâø!ÉÓNÖ\ I](‹ÎÄ F“]‘uÎæ gœõ4¡1è¯Ë”Ÿ^pá{Wx{˜3³BÐÆþº›X*ÀT =)‘•žÄ ùdm'p'ätö£üÖÄ“ÀgÌH1 YuÉ“Ü$3ØÙÑ(¥·‚Èæ¤»€¥ Ü ¡ñú²äh¨§_¡_R†‰:Ôç,ì&Þ;,ÞYÚ83§tfûÀÓÍ ¶¶ôØãöï<]§?’ëæÀO<¿ž‚ÉñQ4ݹ…úϬ¡x¸½­Êæææ7óüè~HÎ z++®.¦ º!ØW.òØ _F“(â×@ùkZêkPYrÕç7AºßC¯¢(TUU]eáŠÂà$z¡j0Eù—†µc¤~·ŠEÅFi†Gj‡GlˆHm‰HnŠIn‹JqJrKr2Mo2Mp,Bg,Bh-Bh-Di.Dj.Gk.Gl.Gm/Gm{Ç}ÇwÈq¼`°j¸c´e³]±e·g»X£T£O£O£ÿ˜ë˜ìšï¢õ¤ù–îžõ¨þ “õ ‘ö “ù šþ—ÿë‡õƒö„ù‡þˆÿ}õ÷„ÿ"xø"zö"{ø"}û"~þ"‚ÿ$tô&}ÿ*lð*oñ-sô-sõ-xú/{ÿ6yÿ;yÿOmñOpôO{ýO{ÿSsõSvöSwùU}ÿY€ÿ_‚ÿj÷j€ù{‘ÿ|ÿ‡‘ø‡’ù›§ÿ¥®ÿ«²ÿ¯¶ÿ´ºÿÏÒÿÚÛþÜÞÿÞàÿâäÿåæÿëëþëìÿïðÿóôÿ÷øÿùúÿýÿýüƒº‡2tRNS(,55555555VZ€€€€€€€€€——œœœœœœœœœçççëëëëëëëëîîîîÉ£WbKGD2@ÒLÈÜIDATÁMKBA€áwæÌýP°2Í JZÔVh-‚þÿª„VºiS`:wn©sNö<Ž=ššZÌÉ­»çEcÉcÉ¿;›·&ÈÅC «ª¹³¸Î"—÷EÑûÉêw:Š+M»v U¢ïýǯOAÛ–ÍiuŒo^>ÑN°m‚í¸¦yŠ`tó u€¢Š€J}„ö¯Šf۴ɽ áºH³Y*o*•\÷|æIÛÞò‹øæ\÷|ì%’ór…]#ÃªÜ ¼/¢ ä•?ï¯óhæ5ÕucÆôvkò LtKIEND®B`‚eric-6.0.8/eric/icons/default/deleteShape.png0000644000175000017500000000252112342633754020146 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ÇPLTEÿÿÿ<<<;;;...---...***QORLXGJFACZ@]@_ c##:f&&i)(n/-%%%o2/r42~JHecIII```bbbkkkD67fXX———fffmmmrrr|ooZIIœœœÏÏÏÓÓÓÖÖÖÚÚÚ†”­­­§‘‘Õ¿¿ÖÀÀØÂÂÙÃÃÜÆÆ¯žž°±²´¹¾Ã%%ÄÅ++Ç33ÉÏ Ø% Þ61ÞÉÉàËÊâÍÌåÐÏçÓÒî·µñññòåå¡””¡¡¡¢••¢¢¢É:9ÎA@ÑIGØOMÜWTà_[äfbévtðÆÅôìì}lmrr……††‡ˆÜÔÔÞÖÖߨØáÚÚâÜÜäÞÞæßßèââêääìæå¿¿ttÁÂƆÄÅÆÇÈ%%ÉÉ@@É••Ê--ËË22ËEEËËÍÍLLÏRRÏVVÐ99ÑÒ Ò¨¨Ò±±Ó¯¯Ô\\Õ$!ÕBA× ×µµ×ÁÁØccÙ¶¶ÙÉÉÚ,'ÚIGÚÄÄÛÁÁÛÉÉÜÝjhÝÊÊÝÝÝÞ0,ÞPNÞÅÅÞÞÞßßßàËËàÚÚàßßàààá ápnáááâXUã71ãÜÜãããävsäääåååæææçIDç_[çÝÝçççèèèéƒêêêëææíííîîîïïïlûhþŸtRNS  !&)+-.013678<=@BBCDEGITgl™œŸ¥¨®¯¯°°±±²³³³´´µ¶·ºº»½¿¿ÀÀÌâæææèëìîîîîñó÷÷÷÷ùùúûûûûûûüüüüüüüüüüüüüüüüüüüüüüüýýýýýýýýýýýýýýþþþþþþþþþþþþþþ:zä€QIDATÓc` ˆ†bˆ û÷õ7G1¢Š ùõ>~>¡-ÊŒ YTЧçÖ½yo[¢Í‘Ô xwŸ¿1÷åë7M­Á,pQ~¯®c§çÞð¤þQC \˜Ï£sß¡Ù.\®»}½*f8{Ƕ=³ÎìºÛþP»[Å cHƒèÎ…YDbv!AÈZ\ ‚0Àq‘EÈBÌFpe‚ŠD]˜E¢Qdј5£mÛöGÕœs«[fÈ&äÑ·«ªë½óÎ9÷Þ×Fjc{{Ûjmm %‰G…Bá£R©ôEssóñx<‡Ïó¤Z­Šëºr_¹»»ËÞÜÜüŠwÏÖ²Ùìß———¥¡¡!x†_¼ßÔÔô-âKL û¾/ù|^ÁlÛ>sX–¥÷ ÌÓw r{{û#6úþ6<<\t£Žã|‹Åfs^* îlŒ‚„B!½+Y[[“˜@• „GFF¾ŠF£ýPóËž9ør>F<&CÊ®ƒ’6ÖûÃÃC™™™‘ýý}U:‡›®®®ÊÊÊŠLOO÷¶´´|¢Àû,Þ¡,.¦T^ɘ÷ 999‘©©)9::’žž•ÎÎN9==•ååeÙÚÚ’J¥"“““ƒÜÀixEÒ¬¤3Z÷wiiIŽ¥··Wæææ$N«2>÷÷÷Ëìì¬ìííIWWW‹æ`)˜½ººRÏŠÅ¢Ê$c2¥=ŒÍÍM•>11!ȇÎ)—ËzEndllLßÄ”1ègà¢\T Y£B‰PoëÕp}}­€ÝÝÝšHÚDÆæÆ¨&d…Ò}'°hE{{»ÓŽL&£WÚB@VsCŽ“\fwwW|ÌÂ\D&dA[˜Ìd2ù0Ð.Σ*ZEP®©+Äoáº×`bGE"µƒW2CRUj.—ÃbtcÉ,‹ä勬GeJ»È¾X(àZ*h©.,,A@mðGQ‹ÒÑÑ¡I!+»"Õ‚‘Ü]~–Áª,Ær¥\*ã}E*å’X¶H*–GíUËúózBØdÌ c2¥©TJÙ$£G’Lý.ù‹sù y“·$ŸesˆD <Ú(’€k©#ñw?³Ÿ?ožd罂ܘ¦é3k”@?iE2FÕž8vN®'‘Î l`[FB®‘°#zu]6XPE¼qaºM¯Xô˜ bæu䨻ü˜à†wA<·àµñaü0&Xb¡—¾Ïú¥t‚1Yšu†ÔÎA#^€K`ß«+zR«w}t¶ôSÄ->dɼ­­MHô¼5^?a”‚@ó ËÚfØ©3žŸŸÏìû³³³oÎÏÏFKûdÌ]¹›%€%“ ,ã© F÷ñÕÿ€0Ï™Y³µ¾¾^îëëû€Ë(øŸ´*˜¶#™1üfÒá=‰º/Qr¯P«Î Jj6d3y ÈM£%¡ä{h04Ký¯ õÌ“ý±U‹‡ñ×/ã5ß°ÁˆV£ÎÜ2þÃGþã0oÙQÿwõØXÁƒÿÆ|KþÇ0æßaÿ¡Ô8^cÞX¼Ætª_IEND®B`‚eric-6.0.8/eric/icons/default/eolMac.png0000644000175000017500000000252712342633754017131 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÜ 6!Ъâ¿bKGDùC»äIDATÁ[hÞgÀñïïù?ÿ÷ó9iÓœÚÔ„ª8V(–Ê´Z »è º«¡Þx¡W^MÑ ñJPæèAEd»Qç•´‚Ð9jÙ‚]zp&Mš&íÛú&ïÿø<ÏÏdÝtÈDôó‘?ÿ½àÊÝ4º×,LáaŸP¯õW˜è‰ÙÈàê›×åÅg³33]>øãSSG®_ºt±DmÙC%¶ˆßÕÑø_µ··ø-ÐàªXU~üÆöìµûùxV†`„€ õH>t°Æ±¡šÜm–¸é¶G?ùÊ÷¦þúëïý™sç_~å•']À?llT$ª×ª!2ò–ˆ¬ÛŸ½• e!úå¡îê^᱊5ĶZÕx0—S'çì™3¼ôÒ… 8³³»Kµ^å=6ŠØóÝ×®ÍËÎ?(º†ÛÍG‡;c"!(6®`"KYälìxÚ: Í¥yXã«Ï¾¾~ÞÎΊ¢@ö)JðáØÌøx‡õÎiQFIVh§Q‰"«wIš[ôŽŒÑÞ3@£ÑäêÅ_qâÃG9yòYá¹yóÝ]]<8ŠaOšûÔäy©iVj+s$Y)Nª\ûÓøÝO_àþ½UB±ôö .Ìñ̹sˆ–—–xñ/péâEªU‹%„€B(œÇfYIjU0Z l5îsÿ΂$I®[Í‚…7/ËÇf§ubêûZIÂíÅE™œšR¼ª„Øç¼ï6Ë RaMËM&Ÿüƒ³Zëe}m;×^×Ïñ<=ƒì$9ƒƒ<ÿoêàÐ ÍÝçœîöxÔ9Ͳ‚T"bµƒ„Phm`‚Ž‘£8 qç±K#Š#¶¶Qkkã©Ó§qΑ¤)"Â{¼÷xï°iVc‘à1"ª šä ±1ÕÛÌLfòð41ÐÙÝãím67·0F1¼Ÿ÷盤®44[BP ªظR°¾¼@·ÀÜ•×X¾=‚Äu†GF¨V«xÁ!"ˆ@q>P›´Z@PÞ!¶Â>õ‰ˆ±š™:—¯¯É•ï\ÐíÓº¹ðÃqh|Bò¢ÐZ­FP•,ÏÀ‡ ^6K2û„}åîU¨ô).ÐväµÉZ³5÷{dóô÷öÐÑÕ«H“Å…¿ ƒƒÃâGQÅfY ˆ &ÒtåéÊQÿaâžQl×¶£­´SÇÓ×ÛÃüü<—_çÖyî,ßæ3gŸfðôŠ2CE±Ešñ˜ ƈé>¤¦c•|ý¦”E5q ±±"-.±RKyõÕße…E®³Ç>ÂØäi%)®ô(*JÀiÆû(Q/•cç©ùL}ón§–‰â=Î6èê®qòÔSŒMMëÀÐ0q¥Jš&ÚJRÙªJØ2Ë0<& Z¦-Àv@¥oH0b븲ªmíosüÄÇ!®Ën³©ÚJPE@y‡bëóLÚ•þEx—©tàÊÚƒMVï®Ð74Jžç¢ªü›š†€õEÖRä/ OàùAŠ­™­-i›{ãjøÄ§RïÞ{ÞU5ªz+Ë‹Ìú"]GìçTLåH»¨sÌïÜZÿÂË¿øùÌÉO~öÛÃFË•å¥ ( ‚:çVŸ;¶àÿpøÿÅ?{³¦ÎŸÙÁjIEND®B`‚eric-6.0.8/eric/icons/default/2rightarrow.png0000644000175000017500000000231512342633753020175 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<©PLTEÿÿÿ@:f\Rr|yLPoIlLUjŽMXiCEGHJKMMPOQRSUUW ”_d R S -m-‚ ’š U V ›^Wcœ `F~F ƒ›––™}j1r1™  · ‘i³­q¤mDDE…EH}HM˜MT›TY¢Y\œ\…¿…Ruxy€„…†‡‰’”•–˜™›œŸ¡¢¤§¨©ª«¬®°±²³µ¹»¼¾¿ÂÃËÌÒÖb~rÉ … \ ‰ŒŒ{ˆ‹‘‰šœ£™¡|¤‡ ‹#!¥!"‡#"‘"#­&%˜%%£%(y()Ÿ)) )*t+,¡,-›-...•.000£01‹13£34†44”47~77š77 7::; ;=™=?£?@‰@A”AB¥BC‘CE¥EF™FH˜HIžII¥IL£LM•MM¤MO OQ§QR’RR”RT–TT©TUšUVVX XX«XY”Y[ª[^«^`”`dždd®df•ff±fg¥gj³jn´no˜ou¸uv¬vy¼y}½}‡Å‡À»²˜TXtRNS!BBIPYYrs{ƒ‡¤§­¶¸¸¸¸¸¸¸¹¹¹º»¼½¾¿ÀÆÈÊÐÐÑÚÝÝÞßêëìììíïðñòòòúúúûýýþþþþþþþþþþþþþþþþþ¿Ûͺ2IDATÓc`À ±ŠòY I%}6TaÉ;A¢L &¬¸P„¥®ß;§Ëfü0ÜYYXúÊÕ›aæwï?eFË\­‡°@öÔî};qæÂ¥Ë!fÜ0a¹£k6lÞºc×Þý‡v„ +œ3oÑ’å«Öoܶ}çž1ˆŠ 'Mž:}öÜKW¬^»nÓ–•Ú`aåžèø”¬¼‚üœÔÄÎ®Žˆ>°°JoLRvQEueInJl¤§8ÄÕþ¸´‚ª†æÆšÂÌDWG!¨•j2Šk»ÛZê˲}mx`T›—^趸½µ®t†;Ü;êSb’ýìš¼<$Xž×˜5ËôÜÛE9¨4ç»Ë³0XδçE X~[ ©eÄÉ@.8ªgÜ›·|fIEND®B`‚eric-6.0.8/eric/icons/default/flag.png0000644000175000017500000000071612342633754016640 0ustar piotrpiotr‰PNG  IHDR%3sRGB®Îé pHYs  šœtIMEØ#¸/…¿ÆPLTE:::???BBBDDDFFFFGGGGGIII[[[gggkkkqqrqrqqrrrqrrrqrrrwww‚‚‚‚‚‰‰‰Õ*Õ!,Ö#.Ö%1Ù)3Ù+6Û.7Ü0:Ý ÝÝÝÞ2=Þ6>ß'ß)ß".ß6@ß:Dâ0:ä>Hä?Hå@IæMVæPWçËçËè^fèÍèÍéÎéÎ êÏ#êÏ$ëÑ'ëÒ)ùÚùÚùÛùÜùÜ ùÜ#ùÝ%ùÝ&ÿÿÿLq\ÿbKGDA‰ÞlNIDATmÁ1‚@DÁ?Ìhà! ¼ÿÙ4ðÁ²Ýâƒhµ*2ù£âƯWɽ'4õ¤ÍlÎRY ‡ @Ù“ÉŒÔâqÝÕ»Z§Þj•8™S¬¥µ1šU² € ÀU²Á˜/³3VÝ/Q-%™‘U²Y%'#«ú“p0»0ñnOoø-IEND®B`‚eric-6.0.8/eric/icons/default/windowRestore.png0000644000175000017500000000135112342633755020577 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<,PLTEÿÿÿ¶¶¶ïïðøøøúúúuQ“wK”xMš€X«•t­—v­˜w±~²·{{ºººÂ³šÃÃÃÅÅÆÉÉÊÊÊËËËÌÍÍÎÎ::ÏÏÐÏÏÑÑÑÒÒ¾ÀÓǵÓÓÔÓÓÕÔ|}Ô±²ÔÔÕÔÔÖÕÕÖÖÖ×××ØØØÙØØÚÙÙÚÙÙÛÚÚÛÜÜÝÝÝÞÞÞÞÞÞßßßßßßàààááááááâââããããäÔÕääååÞßåååååæææçççèèèéêêêêêëëëìììíîîïðððððñóóôöôñùùùýüûýýýÿÿÿüeWtRNS !#)+34<>FIMNPRSUüüýý_ñÿIDATÓu‘‰NÂ@†×ï³XÏ)ÐRETD¬w«P­­VÔz[˼ÿ;8+«˜_²™äËŸ9²,‘”ÛH&˜´òÕÆ²ÄäÏÿñ¯~ïÝÜ~ÈL~¿\w×ué]×ÖìúáöêéWkßúãØÚ±v+>éÀ¬Ä0mÒÏ Ìéáê9lTI¿!ê )!·¡¢ŽxÕÔ¨\‘Ž•k@¡vç"jšë´jðfe¡c˜õQç&%12Õ™¢‘E‘δÌP)4uöÿ9YÄMÒ/?ó2“–‚àÁ÷ûâìôd¯T,lmä%ÖåÓºÑÛ?8<:>9=;¿07351624Ð×ó Ûs ·óûIEND®B`‚eric-6.0.8/eric/icons/default/plugin48.png0000644000175000017500000000614612342633755017405 0ustar piotrpiotr‰PNG  IHDR00Wù‡sBIT|dˆ pHYs11·í(RtEXtSoftwarewww.inkscape.org›î< ãIDAThÞÍ™kŒ]×UÇëœsï÷Œgìqópܸ¶Ûµ›ÐÚ¦@ U)IQUTh">ý( @ˆJ¨Ÿª*¨RÚ* -|H@á娀¦´$uMâàG]Û™xâñŒÇã;sç±÷Z|8çÞ9wîx|§j®tî9÷œ}öþÿ×ú¯µ×ÞWÌŒïÇç£Ï¾mxÆfönÞ™éU„1@¾‰ð䟾÷Ä•ïvù~øå/¿ígÌôs “û§~€ýÓ?Èí£ûPŒëíE–ã›sœ½ñ T'&ŸFøí?߉mƒ‰¾×àñŸïû ?°ã‡ùÕcÈDu’L3RŸ’j†M)JŽ3ñ1ÿt鯣¯^þâo‰—aà×_WüÜSoªŒ¯x¦'>ûÐ3¨)mׯ©Ã©#Ólýl¯žáÊ0O¾üiæëÏ£™Ýû¥Ÿ>ù?Û3ø^¤¼?3&vBÕÓÌš¤>!ñ ‰®ŸSMI|B¬1W[W™o­à y§ˆðºÄ; ÔÃ×¾ÆSŸ&ñq¼ŸjÒ½—“ˆyaéyæçñfxg1 ¯–/´ŸÅˆwVà/Î=I˵rà>!õ1©&dš×1«Ù*Ç/ÿS!˜—Ë—¾rýï¶;f°-‰lq<û›çãºÿL50¼Ö¹–,’jaùÒ‘jJêÚ¾‰ùU*b$kîÉsO/¶ò¡Doà yôoïý(bZ€âIÄŒ‘»]Lî$ƒC•±à=àÝ·?D+kâ,bgëìÍ‘iÊ™ë'9µøUÚ醴Q®©Ú2BÈóU±ƒTà[õKñcÿùØ™ì–D„÷ÿÕÑ#Õ‰èTfp`æ»j³Ä®MÛ5hû6cÑ“C»¯Lð¦©Ã¼yÇQM¹‘¬hL¦§Î|~.‘yÃð˜ªí ‘®r¥1GË5‰]‹ÄÅľM¢ fŠš‘ú„ÓË/’¸&šØG¾ü¡??È< ªìófDC;øÄ}§)ÞE1Sœy2ÍÈ|J¢1WÛ d–‘i†W×}ž§NGfûŽKïàÖjÆH4Lµ:BX©1lŠ¡xõdêÈ,Ï\*/¾úê9p™G°{äNbߢ™5rY”¤Q¶¬+Àæ¿ûïûü]ËûXÞŒë8s².±¬{î¯UÔÀ{ Ô#Þ`fxg7 ½9œú.€ò€=$6€ôëdÄ™3o…Gºm;ÄŠ÷ÌáqxËpdTƒHÌÀkžn"`š0U$ñy*ìîû¬ÜC¨$pñ›x§Kˆõ¶‡#†Q¯&ƒzo ™“µ)Íó¹/Y¶;¨––€õµÕ~29Ø<Ðs°‡v®‹> Ígmµ[sE¾#÷ÀXeœÔ·É,éRßíË2(fÝʯ%ÉôÈLj… h.¡cÀ6ƒ±Ê‰µ ¹½¯[Ùw¯½nF¢°rIVe‹ûÒ½Nÿ&Êlm–DcίB Ôn¥ÙNdÖµpˆØ· ëú^ବ¥û]—ãuàŽ<¨9ФܵþTmæZß&ÕDD¼æØ‚MÊ…àþO˜ºï÷Þ4QŒ4 J(T‚ ÎR2MÉ,éÎRœ%Åüâ{ž%øâpä‡'í^çÏc4ÿmçãÕ1f†v²˜ÌñJë JJba¦Öï‘c¿{rúØøgª<ªPù±/»ÐšOþH";4\­rçè¹Ô<‹'ëïÉ.ùÑë‰i”õ]Ò¸âòþpf(• ÔT–’yZ¾ @•„b’K(ÏB9ÉõR™::þ´TyðCG?ÌþÉ{xâÅOí{¥Ï Æ{ïþ)Ú¾QXÌoÞœuA®÷½$J×➈0Mh‹ùø‚dšÇF•Š€ "ˆWAÍмêqøŽ'ÿŠD<øÎ»ßÎ÷ÿ›§ùýwü1߸ò5N.žà}{>ÀÅÖÿzug _€Ìz¬ìÍ¡æ×¯q( ‡C8Íhk“WÛg1<&Âõž…Å cd(db<`d$”(‚fKñ€z2€¨cýp$üHm8à×Þò̵ÎÐt+8GfñÐ]?Ébú*±6ðÅìéqâzÀºžÔÙ—]ð˜(Õ BªJÛ7XŠçðæòº>0@¤ÕV3ÚKÙsÙì\r[í=õf¸GpÝÊÔÅvnå¿ë_´ãªrprtg7²k]k­ú&+«8uh¼e½z¦_ï¾+ˆ$Àù6-¿FÝ-£æ»uq(€`b+kJæpó_xíãõêóÀ'w=<{hxßÈ‘p$œŠ_O.>µð_¾å—Á¾_ºó.»m|§1žd=“¡æMËÅá5ë L-¥Ht$ºFÃÕi¸ ífºpãºWL 1S¤ÑR\âçê/Ô/«€,=³¸]½÷¾»¦¨E`"jÆ–c´R«Ðe.b]9ˆlNĶüÙ« À{“fs'g–®±ÔZfb(ä­wìæÈôaþæÔ¿³XOæ®|ìå£ÀšYØýów<2ù£Ó636 ©7..µXj¦ìÝ1ÂÞ™ZØFQ ß¶¹qm{)Ò‰š0¤TÙ=>ÉPXåôÊ ^^ºÊ©ù&ñÙÆÃ+rḙeQ‘gÛWÿrþ+áLõSzD»ÑNÃ@ s†óæÌ7†Â1§]»÷jû{KÛLJ&ËÙY&ªSœ«_¢•­bÀÌh• h"³ÕŸþMD\”+O2`åµÇ/~nò'v½4vÿä dTÛº´úËÿ:ñã;¹>R{¤LÑòkyê“ο¹Ìm°Ø³nS¸¯”Þ1±¡V5x PÚQ@E¤\­_ú—úñ¥¯iÌÁ؃3÷·“³ ™·|Ú,e7ÛÑlûR*O ›½`fB% bPéY—H$@½d¤aU®;3Ð*™_O_åÎÒ†lÍÈz'†¾ÌoÕ(@ƒ`:ºglÂi\6içDÄ—Re¨‰ÖÕÀ¨’©v5 &=Š °·&°i*3ÌÀ¢ ¯ZÃû&÷¹3¹è& ­\J˜Ï¬íÍ’„º¦Ú6uWl+›—>V¤ê ðf0QÙ;èÞ(ªxõB%"óX'ël¬×úkº›L ¶¹ô¶ªL I¾œ d#àM=F$5RgÝI¬gû¾ÏŽ›=íkSBn¶9r^MÔ@EFõ€™7õfÔ‚R§ë5žÉ-s~‡ƒÈæÓÅM°õ' Ã$Sð0:ÈΜð¦ðÒÒgRv}H,/‹7ÊHJ2ê“YŸÊlyCœuÈÈÀð _ ¾yååé{ðtF6ºÝÕª#˜n‚PHsZ¤VÜ.[§ûË͞ϷHÞlwÜÙßPï°Tù™•*D4U.%¦zZ´ïë¯jßô*œä–$ppI86TÀÈ,¤#Ñz¿H—n”¦&O° ýÛ†áÑ!tF~Äj ¯ÚlíQÒétóº>ö—Οú¶·ýL€¤"$TE`x_ GÞ(B‡îU1ù©…K1‰ä¼… -ˆ;v¢½ín„C!ø|>U׌FaÖÈÞP§Þªõ Ò!0Œ1¨ !{Cbú˜ Útür¯Íä˜ú,£ûJž¨ÍgðÞÉç0;éÅ¿ùK3 GN þCÔ6Šgjî5.¡R@¸© ñó6\º;~kÁU-0þ‰…©º¬@êjvpmJyáäÉ“Éh4ŠoÄP__¯es©®m™ßÕãÚÝr·QãöqHŒ×ÀÁ‘6$Y˜+. ½™þ`fÂy)—-^^;̾BóóóåîîîSŸþböìñüt]X t?ìnÛØf(uL“°8(Y’&F ‰÷ßL¿zõ"õèã | ±¶éëë““““K©…ìH&UÜìpÚ4u¦¨<òd5j+UÊ%ÐéOrñƒƒ™×qu_v9“Á-àk›½{÷’Çã))Š’dŒ]–¥šu›t…!Ÿ”öáw2_ÿû­ô‹Éëî·ÇÇÇo)ýŽz{{-Ã0‰Ø„U¤lôyLù¸U~ëo‹Ÿ¿ûFò9ƒ‡r¸-ߎ¤X,†öövU×ÕÈÆ.ãÜ??]_zåïá=ýÞ†¡n ƒÚíâlm}'šVñz½U¡vû…-[̆ƒïdŽ’Ô?\YYYÄ÷åv' 0ÇSmF0ª£££ø>7]­ÿ¾-Ôªà±ðƒIEND®B`‚eric-6.0.8/eric/icons/default/plus.png0000644000175000017500000000222712342633755016712 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<¬PLTEÿÿÿUUUÿÿª@@@ÿÿÿÿÿ™ÿÿÿÿÿÿÿÿÿK¹(0-™×†§ßƒÄƒF²4J¥€N»)iÇDkÄSM¥K`³`:£Eµ$#…Íw›×Џä§Pµ@F§¯Ú¯†”=°!Q½+U¿-ŒŽ…ŠŒŽ  ‘ ’ “ “ “ ’ •”˜ –“ ˜š™“œ›› ž"œ$ % (¡*™**£+¢!+¥,¤,¤!,¥,¥/§0š00¨1 -2¦&2¨ 3 5¦,5ª7­8­ :­!;¥;<­&=¯&>¯'?¨=?°$A°-A±)B²'B³%C­9C²)D±-D³*F´*G¶)G¶,H¥EHµ,J·,J¸*K´9L¹-M¹/O³ES³LS¶LS¼2U¹MU½2WºJY»OYÀ3YÁ3Z¸P[¼F]¸T]»T]½T]¾Q^±^^²"a´`aÀUb¿ObÁRbÁSbÂPc¼YcÂWd¸cdÁKdÃPeÄVg¹agÃYgÄUi·ii½giÁWiÄMjÆXlÂdmÆ\mÇ[nÉ\oÇ\pÂ`pÂerÂnrÃfrÇbsÉatÈduÄhvÆhwÄswÅhwÆiwÇgwËZxÌfyÆsyÊhzÇqzÍg{Ãs€Ít€ÑnÑn‡Õs‡ÕtŠÏvÉŽ‘Úz”Ô€–Г—Г—Ò’—Ó‘˜Ô’œà‚žØ•ŸØ•¡Ú—¢Ø›¢Ù˜¤Ú›¦Üž¦å‰§Ûž¨Û¡©Ü£ªÜ¡¬Ý¤¬àš­Ù«®Þ¢®Þ¦¯Ý¦°Þ¤°Þ¦°à©²ß©´à¬´á«·à®¸â®»ä±¿ä¸Àð¤Âæ¹Âð¨÷üöýþýÚª'tRNS ##09:?HSµµºÁÊÌØØØßßéíïññöööööö¹ïaL*IDATÓeнJAð™ýº½œ\b,|ÁB6b!‚o`oeaãCYÙˆµØi#Aü@ LôŽÜ]n³»c‘;‹Ëtóc÷?Ìp¨ªÝ?(3U'þùzBnßTÎjÞ²Q+>õÍ×3“BïÍ6™ìhM6³¼Y`ï-º:è`BÞÛùÄ@ƒˆ»ÛŒ .L)ryÊ@ N~qåv<"ˆìÖˆ#çËvÅÒCy‡(•òF¥kÅ7ÉqOЋËqí(Ò:š ï³¼ã—w6™ÖQ Ø¥Ý#pd}øs†aÜcˆœµ_Ãõs&Wâ"EñƒTªiyS¹œóÄC“Ë´ÄÂ-.Ÿp‰‹L#JBÛ ‘ýî÷')Þ`÷¾A|õ©ž‰õ·ŽnÛ4ϪîFRy8C‚,œIEND®B`‚eric-6.0.8/eric/icons/default/class_private.png0000644000175000017500000000077612342633754020574 0ustar piotrpiotr‰PNG  IHDR(-S pHYs  šœtIMEØÜá¥tEXtCommentCreated with GIMPW´PLTEáË^âË^âË^Šiv+++808ɘÒܪà­++--"771PP7778r¡;aa;bb=XYOOOQ††Y_ššdddecdf—½l³³m´´‚×מ¹Ï¸ÌÛ»Œ¿Ê—˘˘ÒœÒÔ¦ՠרܪݫݬâ®ã¯ä±õÎöÏ÷Ïüç@üè>üè?ý×1þè>ÿêSÿÿÿº”Œ tRNS +/>ýýýý”D™àbKGD;9ôl“IDATÓUg‚0DÏÞÎÑèŠ!Ø{Åúÿ˜ûmßÜÌÛ# P.ðý2Ý×:%Ðaì\×tÏ‹‘nÔ=¥`ÔL™G±RN¸Ó抵JÉ]Çésj•Ü Ê+§å§Vúìæ‹Ã/± ïÍz£õ´3¨ô8.7—Wd53ˆ Ái½½¾3ßçÕþöýŽÏ ¶Q'AIEND®B`‚eric-6.0.8/eric/icons/default/filePixmap.png0000644000175000017500000000235412342633754020025 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<ýPLTEÿÿÿUUUBBBTTTnnn^^^••••••–––———hhh{{{………ÈÈÉÎÎÎÖÖÖ×××ÛÜÜÜÜÜßßßãããÖ××××ÙÙÙÙÙÚÚÚÚÚÚÛÛÛÛÛÛÜÜßßßàààâââçßÎçßÐéáÎêâÏëãÐìãÐìãÑíäÒîåÓîæÔïæÔïçÕðçÕñèØ«««§¤¡        !!!"## # $!$$$%%%%%&&&&('%)+ +(+++,++-"/.-1112223!3+4+"4,4446$61-81!9-999<*<7=:/===>:)C4EEEH5$NA#O/O>P1P1S1X4YJ]O^5b6 dSe8 h9 hV!jUl?nWs_sg"tssu^'wb{H|Mc€H…q‡j‰M‰r ŠvŒtZt$‘}"•V˜‚›››œ€! ŸŸ   ¡Ÿ›¤££¤¤¤¦¦¦§¦Ÿ§§¦¯¬˜°«š±±±¿µ”Àkø˜ÌÌÌÍs͉ÎmÎÎÎÐmÐÐÐÕzÙ *ÙÙÙÝwሠç²Cç´Aê{ìŸ ì§ ì¸'í‘í˜íœí¯,õõõ÷ÏP÷ÐP÷ÑP÷ÒP÷ÓPÿ„ÿ…ÿˆÿŠÿÿŽÿÿÿ’ÿ“ÿ”ÿ•ÿ–ÿ—ÿ—ÿ™ÿšÿ›ÿÿŸÿŸ ÿ¢ÿ£ÿ§ÿ§ÿ§ÿ¨ÿ¬ÿ¬ ÿ®ÿ¯ ÿ´ÿ¶ÿ·ÿ¸ÿºÿË,ÿÌ,ÿÍ,ÿÎ"ÿÎ,ÿÏ,ÿÐ,ÿÓ(ÿÓ-ÿÖ0ÿÖJÿÖ^ÿ×/ÿØ-ÿÚ,ÿÛ,ÿä,ÿæ/ÿæ8ÿìQÿðKÿðctq±¦6tRNS .Ffp€€€„©¼ÓÓÜâââââãããããããããããúúúúúúúúúúúúúúûþ*ú„IDAT­ÁA.CQàsþû¿¾¶hRI#‰¹˜X‰Íˆ©UX‹„D0²-¥ïö½{ß=ˆ‰‘‘ïà *‚øMPr›ìÈø $A|ž;ÂåßA—Õ)œ•IêU¤Aàݘj‘hŒMg2º¹‹p´á„«Üe@õÔš[›s•’ÁP¹óMôÁ±š,iQê8ø°$ð8 íû‡Š3pkn‘®IõÝ!ä@µ·3Ý‹åKöÔ¥äõ4Áu“Ƶ6â[Sw%è`vý!|ÃûÚhu®ÆýÉÁüi-˰ªÕ·ŠOkÌ^Ï–‚kUE+UˆÓõpíÇó÷Ðv/zY°Ü–`ê¯îc@Ž2üPÉ­ð… ~þò N•™,·„¼IEND®B`‚eric-6.0.8/eric/icons/default/goto.png0000644000175000017500000000100312342633755016666 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<‚IDAT(ÏcøÏ@³Ý#¸âKh’QªiUEKêàŠýìþïDRèÄè×õ?íÑÿºo\PÅs +^ä÷ªø‡TñE¸â»Íp¥¦NÿáŠwˆ€Ä”˜õßÀ{ÃÃY“Ñô’âíp7óØå{¿*Þ€)šá¦ÿáŠ×YƒÄD•„Á‘"¹"]®X–Eó.’â ˆ"‹•žè;b‰nMgÓÝPÅ‹‹A"l6"ÿ•þëÿ·ÛámŒ%m8%ø}‰jOc„ðØv@ÿöÖGR,X&Û¯Éâø !´²‡*îAr«€à;Ùÿš7MS8ÝÇ–V|׎Yq»à âÿ@ú£F½ˆ™Rœ>Š ¬W¡ŠÏ91Lü¬›ÀŠÿšš‘SXù'È®Ñt"2[103p13H3¨0è2˜180x2ø1±;ƒ-ƒ ƒ6ƒƒ?;#Ö¸Ì!>R¶IEND®B`‚eric-6.0.8/eric/icons/default/drawCircle.png0000644000175000017500000000162712342633754020010 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs¼ÏtIMEÙ 缃ƒPLTEˆˆ ™™™››ž¢¢¢²²²´´·ÆÆÌÕÕÕÈÈ˺º½»»½°°³°°´ÌÌÒ¥¥«««¯¬¬°³³µ¶¶·ÂÂÇÃÃǽ½Ã¬¬°¬¬°¯¯±¯¯²¦¦«§§¬ËËÏ  ¤¡¡¤±±³²²³ŸŸ¤¡¡§ËËÏššŸœœ ®®²¯¯´ÂÂÇÄÄÉ¢¢¥££¦°°³˜˜žššŸ««®««¯ËËÏ——œ˜˜žÌÌÎ×××ÛÛÜÝÝÞÞÞßáááååæèèéíííîîïðððððñõõõúúú®®±¯¯²°°²²²µ³³¶´´¶··º¹¹¼¹¹½ºº½ºº¾½½ÀÀÀÄÁÁÂÂÂÄÃÃÇÄÄÉÅÅÉÇÇÊËËÌÍÍÐÐÐÓÙÙÛÛÛÜÝÝßÞÞßßßßâââããâãããäääåååæææçççèèèéééêêéêêêëëêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõõõöööö÷÷÷øø÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ $¢CtRNS.//559=>>FPhhi‚††’˜˜©©ÍÍÎÏÏÔÔÖÖààäééêêëììþþþþþþþþþþþþþþçVV­bKGD€e½žh>IDATÁMK”QÐóÜ{ç)?ÌÛTDà*ˆ "ˆ6ýr7­ZØ¢f‹’5rÔšûtÀ ˜˜ŽÃÖtÝ|¼XLGh ì>owZÇþù;¨pÿC6T=Úäòåé_TýËjùdx+e´B°q8;QËê«7‘2J‘·‹­Ù¯ÛÒ×W3j­pSse£7ÓÈ(í¶§ËB›jVW„¢öNf¦«š ”,5¥e‘r¢˜_!KÔDˆr3WŒ{ID)Q#C)¾ŽJ»Ø ˆhQˆ(Ó{Zíãpò(I‡Og?zQ†H"J­%"âîQUåâ:f@v쟥Šë«›ƒÇ"Ký8ß?F…Ëß³qgÿög_N!@äæÚÚ¶ã«ùy$L€ à?£å}Ÿ+Á96IEND®B`‚eric-6.0.8/eric/icons/default/vcsRebase.png0000644000175000017500000000153512342633755017645 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs  šœtIMEÛ +!C9æ!iTXtCommentCreated with The GIMPm°—’PLTEÅÅÅÆÆÆaaagggÌZ………ð–––ŸŸŸãããpÐÐР  ¬¬¬°———)ë||‚“““•••ÿ00çççèèèþ ººº”””E99•••˜˜˜•••——————˜˜˜™™™›››–LL   ¢¢¢pDDåååæææîîºÎÎÎÊû22ÿ66ÿ__ÿ››˜˜˜œœœœžžžŸŸŸ   ¡¡¡¢¢¢¢£{{£££®®®²²²²³³³´´´´¶¶¶¸¸¸¹¹¹ººº»ss»»»½½½¿¾¾ÀÀÀÁÁÁÃÃÃÄÄÄÅÅÅÆÆÆÉÉÉÊÊÊÌÌÌÎÎÎÐÐÐÔÔÔÕÕÕÖII×××ØØØÙÙÙÚÚÚÞâââäDDäääæææîîîðððñþþþ22þIIþMMþUUþWWÿÿ ÿ++ÿ--ÿ//ÿ00ÿ22ÿ66ÿ99ÿ;;ÿ==ÿ??ÿAAÿYYÿaaÿddÿiiÿrrÿ{{ÿÿÿÿº\7tRNS %===\bbdkŠŠ¡¥¨³¸ÆÇÈÐÐÐÝááæèèêëìíííðððøüüüýýþþþþþ´áÁ\bKGD…×jçÔIDATÓc` ?`ä•ÖÏЗâeBåðë&§¦§¥êñ30°IŠÂ9²ÑÑñ‰ q1² \efšpŽv@HhphH€–LcS‹Ž0„àbécœoZßP]U™ ä8*3¨[¹‡ºx¥åÔæÔÕå•:»xÙ«2h˜{…yúÅ&e•TT×T—ZxúEX«1(Yy:y;™Ôæ–gÛ9¶Š –®aÞÁ6âb¥¹ 0§œA¨»¯¡<»[³œÃÀÂ-(,Àà ô#³‚3XeÉ4¦mƒò Ÿ0m·ÛjÞŸßq~Mìsh3Æ´ÄMɘÏ ©Õj¯IÁu;0ƒñó—¹ÀQhãC*Œx’:‡úõµ³°³²Áé|'B¡àSÀ‹@|ßáá¡ôƒ“™ØzÚòØõ CÕÆ4M¿Æá"¹Ð. ˆÀèñù|J[û ÇÚ£Gò|eENø3+G¢óó’?^1FqMŒÈ=:«Íˆd’H$03 •J%5Ÿ]]•©7ĉ€ýöËò²˜ñ¸Ò;f¢£áÀÌ –l)¦LYXÌp8üp­\ ™6ÝD".œkÖ¢ˆCnÞ("RŽÔEU}ËŽ`šžù¼8°Öo¶þÐWÐ˪gAV÷ÔÅ S 2:ÝQ(H@m¸Æâ ‰`§¥`½tZܨBúS7oNRc7\#c:“©êë‡%ŸJ‰…TŠŠwÀºwÌPÕÏaœë=x ]óáÊØØ·N0- Ý:íˆF£‚+.Ή ib>84$Ñ‘‰ãÝëNœ;'HD4Ô¡´¿/ÿ<}º¥CäÐl)hÔ˜…Œ]¹"V6+¹û÷eŒíËa[º›ÐßDQ9–QäÎøxÃL§µ™™™ô4лÔ•}Ìf'û0˜ºÐFÙ©g2â ÎÇW·‡QY›ÐßB9çç·¾ÚÚúŽWú{xl.ƒe”̇‡‡e Ì ­#W¯JîåK¥³7äuUÏ6ë*ΰ ë—.UõHd™óÚææ¦…ïg¢0…,I¸#Íâ`Ë[h¢S(P}{[âgΈs.ÞLHÆÖËííÉ‹Dâ¹™LÞò„ÃwR©TK…][[kMOOÿ…~ý¡X,þ„vÅLàÒø1ç(ƒ¹/™”,ÚÎÍ£gÏŠ ©¶+ìîÊÆîîÏÍ‘‘k2:úÛÂÂBóääÿÚ§"Áq‘ß¹~ýÝøÔ”ž=“_ïÝ{òg«õÁ’È«þ½Ú›ÿ»pQ$£W«³^¿èïÇ÷^‹·E¶Oï}#`Ú‘\Ìã1ó™Ìtnÿ›EVž †§÷ýC ‰¹îOIEND®B`‚eric-6.0.8/eric/icons/default/xbel.png0000644000175000017500000000524612342633755016665 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYsÃÃpMBtIMEÜ9+»·?:bKGDÿÿÿ ½§“ &IDAThÞÍšmŒeÇgæÞ}éËv[hiiYÚ%Ò‚~ òk_X Ôh¢Q&š@4~À/ÆHLùâK£!C$±$ðC1*¶RŠˆ@éÒÚJ»ÝÝn÷íî™;ó<ÇóÌܹ·Û½»[ŒLòdÎ̽óÌùŸó?/Ïs¯pö!€ïÎÂÿÿP7Œ;Ÿ¥lóu7°èú˜ú±f¥¦/{À%ªº—Ø!"×8 f&8pæôiÄóPÀÉMáKÁ)žWw‘µ¨ïãÍœžW¿g ¸¹j>¯µ–e\ëÕ|”Îix~݈*d Tóˆïçߛђ,¾ÍÞ£Z¿V¥$’Ë…ùd¶r…2Ë‹ªš+™½P}<û€qÊzÖ¦ Š`USï¹we2ª3NUjÁ»t<‘:2«dJ,%³¤ç¼ ¤`ÜEË[Õ܈sàû~ @$õ@ÿŸPÏ«s¿ ØY‡µéœ€Í(ér¶õ}ÄZ|‘ºìyØ™•T¤®`“œ‹ÝÎy¸ø¡`qu =gˆ¹xÎÄór~z/³¬qùìkÍãOµ¥Þf žCÎÍtx3f GQE\ÊÀó¼ôžHƒœ_vô ª{î ºûvìèyìHÁkÅ9Ï’ÿ[ÅÔŒiÛË(T两…eÁ&SLì¾…Žµ·Ò¾î6&vß‚M¦rcäžNvJeÖoE!o†H9ê(D1  ÷2“"0±ëfÚ.¾V/DV/¤mÍF&vÝœRÊóêJM'i[Ìxs¦Ð4ÔɬŸq¼AvÏ„Gž¥&£t\~’$1t\~#‰_!|ïwù¼Í  ù9}çK!©· EK{^ZÔœœWPF_ù:]=›¡lÑDÑDÁ7,îÙÄèÞo`­i˜7¯%E¹ÉóŽ-p°ÈÅL.~®ªLì{é^CÛš^$¶ £¼æR¼ {ÿÇCùsyfj’­µ­Sòl<à,\’ÉÅôi*ÇyûÇ,ë݈šš˜ÆG,ëý,cï=MÊÏjc«ù÷°™e`2pªŠu‹’r©D- £ûvìøÁæÍù¹íNg;#޳­yà:år™©Jehk_ßwÞ|óÍ_œ/mfü¸^Ïó0ÆhEz}g;}}}€!!……34ˆ‰‰‰‰Ž“““šŸŸ ¢¦©©''ª««­­./±¶¸¹ºÀÁ&&Â55ÄÄÆÇÇ ÍÍÍO&Î??ÒÕ!"Õ`&Ö21×ÜÜ;;Þàââ[Vã%%æ;<éêíîñõ "öMOöÂÃúFF¯5w¿ntRNS &),-07789?ABDEFHHKMOQXX[\bdeijkklnovzz€…ˆŒŽ‘“–™›£¤¦¦««°³´¶¶¹¹»ÁÄÇÚÚÜßßããêíøúúûüüþþ»h¬uYSVaÄPÞ 6aƒÔì¢ü¬dCNa¡˜þŠyå ‘ì(ÂÁ¹e3J r|Q„Åc3Ož>uÿ…Œ~¸0“ŒOÒÉó›j×_:ç)æ°Õ4kžuñjWëË fë›;°…™ø]k]¼räôµËËÚm…™`f{¬Ø0iÝ¡³3ç[ì‚d¥×Áî’º=«‹ŠžqG¶Ú6¿°m×–¼ÂµÇÂLŽ«6ï<ºãÄÊ5{·[ „y¬Sª–nݸo÷òêøp¸°œ¥}eӜɖ´Ôù±Ã…uíØ¢;§õuLé`ñ… 3(9 2r„¥OìI ä`’t’€3)ƒbŒYÁÛMÄ`WDŽ[TÌ^CÉ*ofIEND®B`‚eric-6.0.8/eric/icons/default/quickFindExtend.png0000644000175000017500000000134012342633755021007 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<_IDATÁ¿k\uðÏ÷½w9+gÎ6mš!ÕŠ8 $ ¤‚Ô! KT4Ä? Cq°S)Eq˜ÁQCD0ƒƒ¥tÌbH,:™"êi-g~™¼¼{ßçç*ÜjÅ ãaÌ(6ªukÉêü>¡psÊbo°ÐÓC&S“u\»¹*ðq;.ÄÙ#´œ5¤ò§§öÑ”,%×?éB¨0ß®6óá}—½æœ† ¥ûØÑRß #·ºdÐ[8ÎMzE¿šLD¥–i܇ûÌ*M•ßu½e\KŸ=$ T8qä'ËÚÒ·?_I÷Zñ‡Ã3—Mê÷Œº‡»¤.dR‰¶¿tÔ^¿ÿURLœ ò†~u}RlùÌ&©š†¦wp2XL$½ñÜs.¨É¤¹øÂ‚¤jêš.ÊõÆ“8vj@®”ÈÚÓõÀ‡~DPÓç’Sq,‰£…!uO<ñ¯§þ±ëS‹Ž¤R/)ÄÑ,Šà7[þvâ¼óúDQ”Å0ô»JHeê™sæ]AOe[7’¸žèÈ•J5Mmg½ëŽ+ˆJ¥‰¸žÅµDÇ~… ÏpÃU@¥pì±D\KâªÎ¾w,W(5½é¶«€R!·ìN\Måßn'3».H¼`RDQáØÏ¾Ö>¸½*LÓ›MÍÑTW“‚R!÷‹/Ê–îÎ*Ì´«ÍÞð±WÍ8£O*¨”ŽÝóPC¶Fît ˜nW q6×ð¼½,øÕ¶Gê’¥pýnBà½)‹å`©T"•J¥×–WB€÷[Õ„qcF±aÝZX½·Àÿhó³ÍØLHIEND®B`‚eric-6.0.8/eric/icons/default/drawRectangleFilled.png0000644000175000017500000000044612342633754021631 0ustar piotrpiotr‰PNG  IHDRójœ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<BPLTEÿÿÿ®®±ÁÁÅœœ¡žž£ŸŸ£¡¡¥¢¢§££§¥¥©§§«§§¬ªª­««°¬¬¯®®±°°´´´¹¸¸½½½ÁÁÁÆØ]™ÐtRNSââØ:ÖäVIDATÓ•Ð1€0 CÑŸp„àþ'!ö6éÀfÊO–#*1ð]ì Ž[x;qH]HêÜ•;8„r€CSn°€å·þÒ•_³ÙCªíÚÈŒ l~’ZQüÉþ¯ºIEND®B`‚eric-6.0.8/eric/icons/default/taskPrioLow.png0000644000175000017500000000123412342633755020202 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<bPLTEÿÿÿÿÿÿÿÿÿ’â÷vvуƒ“äïÀ``•Ýö““ᯯ•›çé› ¥¦))§00©«22¬­® ±² µ¶ ¹¹¹::» ¼^^½¾  ÂIIÂaaÅkkÆÆ ÉMMÉaaÉeeÊË Ë$$ÍÍSSÎMMÏ ÏhhÑSSÑrrÒÒ ÔMMÕnnÕ’’ÖÖ ÖSSØXXØmmØÙXXÚÚMMÛ ÛSSÛYYÛccÛkkÛÜ[[ÜjjÝMMÝYYÞQQÞSSÞYYÞß ßà§§áSSâNNâã ãTTäSS䌌åSSå\\å``åll匌æ00æSSçTT猌玎èYYèll苋茌éZZ錌륥ì99ô††þýý¢otRNS ##:?µµ»ÌØØíñööööäîïNIDATÕÁ1 1Ð?3™$«b·`gëÝ<ç±lÅë‚…I4‰K°ïa˜ð‡ Xß¿˜°þø¥í÷)fÛëÐy6F2*ªã]Ì?cH¹PB»Ž›K4hƒi”m¥Î•ü<©Åƒt_Ø7‡RbÁëU‰ ˆ÷D"̬¬*NÝ!LÔõ41ñ_åj\IEND®B`‚eric-6.0.8/eric/icons/default/html.png0000644000175000017500000000630412342633755016673 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYsÃÃpMBtIMEÚ µ}!ObKGDÿÿÿ ½§“ DIDAThÞÍš[Œ]×YÇßÚû\æ>c{&3¾Ö¹:M*S»¶“4I‹•¶*J_x‘@Ð „ (â&QÁˆ§H ¦*K‘Š ¥´$MH­ÇIê²=¶k/ãñxfΙsÙ—µ>Ö:ûOìgœJÙÒÑœ³/k—ÿ÷ÿ.k„>8‡îFÞ%äÐÐÐX½^ߌ~@”P`qhhè|½^_Xy1^ñ;ª×ëÛTõm>`‡ˆìj€]M‚å¹67&BQ$¸BÅ £(ª ªá>Á©‚ ¾S w†¿0NÀ(FD çyc‘°¾*ê6m*äZË]Xã…ƒ‚™7¢ ^#TDý‹ ΋"þšª£x!êD^xoEР°1ÁD"8‘›Â½Xê&. ‹‹ˆ Æ`4üV‡¢Aa‚ézpê í UÂêO¨Oy7á:ˆ¬„ñ*¨ ƒ ‚ /1ˆhp˜ *¨x¥L°jG vv(í\WGgAï9#ƬSñ‚Š1…›Á+¤ø—@w½YÅ(¹óV÷V Bv,¬áy#^Ñ"†ãñ¸Å9‡‰#ÖòÁ0|VBPTpLd‚¥U}|€™.6Aý9¯µuþ)#ØU»ñ°Ntá#»ž-Ø¥³´/T]¬¢ FˆŒ`Œ ×C¢ÓN”wÓ³"×Y^ëtÓw‘'Ö!U¬z–cpΑ;W`_¬Ó"éhx±¿¦ÝòB}“èõú%† PÕÀ<­Së¼5"õù88G ¢Š1&™vñp«]2ô¬ÓÍ" Šjo‚ë„•÷’/8·X ¯RJøÕ­õ ‡)ÔD>Ñt¼m Ì í%ÿÞÒÏçε¨v¦ª† /]9Ö!ÿÒÜZÄxš‹#o9gµ€§µ뮳yÀ²P*J‘ALwÍ<Ëq­ E ¦êÂWäÖZ‘xÕN"$¨,ˉŒ¡TŠBº…]÷M’$YáM ¥º ÔE¦'y®Kt<&³Ü[½›ÀÎ'+Õ"g”J†Ã‡ÏðÍO°íÞ;hfp-Q¦k)ƒ±°Ønra¾Á÷ÞœerÈð›¿ò›ÆCÞÈ}\9×…Ò-(`Vmä:5z@qž[²ÜbmO¥\6üÃ×Þà?ߺÌ#Ÿþ0û¾ àlÕÉ ìܽ†û‰û+Ll%ëëçKñ¼ñÒ14km·2Un/VvKç¹+Ž86ÄQDž{þuÚ¥*Ûª nÄFºsœÓm¨/5™kçŒLŒ±|u‰£ÿs‰ŠÀ»¦øò¡ÃüÙ"îy`‚è^Ci«AŒàÔadíÙ‚YKx 4Zr(Ö:ˆMD©sôè9®¶``b”‘­Ù65FTŽ96Ÿ°”ª¨§ç–™YJI0´œPO}£CüöËßFÏ:òïXšÏg´_±Ø‡©JAëV@DŠšžžÀˆøÌÿ½|Š“£4Ëe>±k‚¨C©ÌÞ¸{j„‡ï¿ƒZî Ž«¢åˆ¥fÂÜü2§N^†¾2Ͼþ}bè”ôyGö5E—nC_"tó¹ %¯ˆæ8Ž˜~ç2_¸k+OEöVé}M$"ô•#>25ÌÉ+ šNHfkN„¨cŰýî)&¶nâ»ÍËœš~M-‘—'ä§dg“Û„×÷«NÌ”c²“KLžj0Ú_&ÉJÜynk”4WÔÁƾ©u\¬§4S‡DŸÍáì™YƧ6Péïgxr˜¾÷Mþü¹?å­3G°Í:éò"YÒ^_KOØÁ¿ õ½:¡ñâ9Jí >7ÀàòËà }bh´Û –b.×R..4Ù=ÙÏ´ZÎü¸º. «Õ&2Ä%CÿÀY¹ÂÓŸü4wT&È––`ªŒ¹§´NÒn¡¥¾ÃF"Á]NI0ƒÄ‚Äòó›Ò>ú^¹t…ÏÉ ‡Ž\`û†>úJ†Ø:b”ŠªÏÂYÎù¢-Š0‘`"NéßÉH^¡]»Êè/leøó[ÉYG"÷ži´ˆ_JùËç°Çg1ƒeŒÖòFÊ1h”ð»W~Èëå羕ó™]œœ­3»Ðæ­³‹ XZjaÛ)6ËQ«`•f£M9ŽÈ u”ÓyRcòwo µÔ$Ïr²,Ë€å×7UÀHQ¬ qíŸþ—«ÿr„¸¯Âèæ=8Dt‘“õEž¹øC’‘>ú6 ñ_Çf8?ÛàÀýãüàø,Æ)KIFÖJ±i¹Es‹Z‹¨rìõØFÂÄX‰Gîcò/÷áTiÔ´[-FGF8tèÐ7€ÙyᦠDqŒµÖ³§,·Ô— S›÷’¶#TkD;'§ÚÔžm08PÆ$¢pþÜ5––|êÃSLŒö1}a‘—ŸÁ%9šZÈ’+š+zƒ¼Ñ€F•O<ûqjµívÂr½Îö;¸¶°pòé§Ÿþ2põ=A¨TŠ|Íc=^£RDµ: YBj3šµ9âÞÉM|¶o€_hR.Ç Tb–“”ùÙ”ý܃´3Ë@ywoá__þ?Þ|çi£…d¶™¢í”þ(bÇŽ2ÕŠ#IRÆÆÆØµkÿ}äÈ¥O<øEà½GJ¥1›;&ñAjo\¦5;FŠ1›¶ß‡ˆòÔ@Ìç‡Çùó'Xª]#î+Q©–鋱¹%¡YÎÞ¶ð¿z²§W|7‹'í6 ¼öê«ó?óä“¿*"GTµ±V©S xTU_mµZÅ-~â`q ‡g˜å,‹‡ÏbúcLäûdƒåmñ×V©!uðSNñk¿´$³4›9æ–ùÂÏÞEžåˆq…ÊÓ‘¥)i’Ðl6uzzº~ð‰'~YD^TÕúº‹¹ÿG‘`L çÞÊÆÇ·“'0÷Ý\þÆ;ÔÞ:GÔ“™Ù²œCšmÎLÏqöÌîÜ9ŽT#FûbLðlgâæœ#Ï2²4¥ÙlêÌÌLóàO|Ñó’s®~[ M¯“D ŠLè…GL~æ~6î#$óu.üó1ôÍ3Œž¾ÊBßÕ;60º±ÊئaÊ•2³ 5Î]©S)—Éò -hže$IB³ÑЋ/¶?þØc¿aŒù–s®vK«A¨3qëí3W6~ç÷LlˆTyî«ßçÙŽÓ¬rð§ïc|c?ggÌœ_ॿùyœÍ°Ö^'üììl²ÿ¡‡~Ëó‚snñ–wnnª@³YŒ?ÞÕiw”R ±Â|È÷³Jµqüø ÇÞžáâÜ2Îæmð¿ÿI;! · »z5Ý»oßïcþ1¯·ª@¼Ö`«˜WöÌÙè9ç;ôî SÕ÷ µ$c˶1&7“çFƒ™ó3ˆÒ4%MSZ†Î/,ä{÷í{ÆsÈ9·ð^÷ÎÌ;kŤÌÝlF)=¶žª¢Öa­#Ï,yf±ar$ ­fS—––òîÙóŒ1æïsóëÙü‹okퟢÉyw¶ÿŸ¨êWTõêz…_B…W´R™Þ8Ð0ÒbNÔ¾Ñl2>>®/^t>öØ¥Iòwªzåv„_;B¢Y1®»aèŠè|œµdiJµZÕÆòrþèã©^¯ÿ­ªÎ½à«n³Ò3îösO ªìõÎJ9çü¦‡¿¦\ºtéòž½{}yyù+·ƒùµŽدïÓa­Õ£G68ðuà³"2ø¾ÿ ÂÊß•Jek’$›{@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜bKGDÙw w82IDAT•ÁÍJaà÷œùÆ™Ñlú1ÍH7Ad›Â v-[uE]EwDе)(!„´úsœé;ÍgѦ6=þFóSø-T™ñ@„”@ÞlŽÔSnŸI7uŒ8N¢Û$ŒÞû¢tR}Ák!ÊÉ4D WÀ°y÷Z­ÍœmïB·EIÁp}œäÝ«óL{1oQ0ng ÎE×.ùRÂ0N²¾¾ï”£d RÂ0ÚŽÖäÎù­)WÁÐ1ÑD‡“8˜¬ÐÌ0öbmWÜÞ03jÀ`cK59»:½ê* ‹aXõËS;àåM…1c̪•ûÎsqÃÁ¬ðÅ[ë…¥:cŒH!A+V)À7"%+£K‰ŠyQDL†ËÌÄÜ¿qŠØ mˆN}ªt½05EIEND®B`‚eric-6.0.8/eric/icons/default/drawBrush.png0000644000175000017500000000153412342633754017667 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<˜PLTEÿÿÿUUU‘‰x´h´h´h´h YM.¯¯¯UE´h000A5===WJ(///' KKK´hF;UUU***jjjsssSJ4!!!´hkkk¦¥¢°°°ŸŽi###cR UEUUU¦¥¢ ©©©```Á®‚˜˜˜kkk¶¡nxxx¼§x222 {{{–––))) """$$$%%%&&&))),,,...333444555:::;;;AAABBBJJJTTTkkkxe,~zq˜…M›”…¡’i£\§”W³œgË»ŽÍ»×Ì­ÚÍ©àØÄ™‚atRNS  "&'-01234677;>ACEFHJMV[egiqss|„‹™ ¡¡£¨©«¯²¸º»ÂÃÊÊÓ×ÙÜÞÞäææçéêëíïðñõøùûüüþÌZßÅÉIDATÓc`ÀÖ~º˜‚ 6q‰˜¢ñU¡Ò¢ÚQ™eN¢ªáEéžœè¢RAå¹1Zè¢">E…ö袼îåežBh¢.…¥ ú芳ËKòÑDE óÂäÑ[¥çde˜¢‹ŠE¤¤¥Ù2¡ ›§&%;2£‹Ê…TÆZ²£‹²ººšaŸG¿ †¨dp{ º¨Rdk[½š —atsK£š¨€CSCmµ·ºœ2:Fzšêj*ÊŠ²â‚ü<ÜlŒ‰'ä („8IEND®B`‚eric-6.0.8/eric/icons/default/vcsRepo.png0000644000175000017500000000130712342633755017346 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<FIDATÁ¿nàïÎçÄÒ&MR”Òª£6 O€„ o€C;³ÃÂЉ'¨@b1Ñ¡/€*±”*$$hiKcÇ®Câгsöùr?¾/ Ó¶·q¸V!„eÚÿðÉÃÁxZVQFULËÁøÉÃáË4„„ßíçyÌb1ŒA bÃ8Œ<òèç¿Ü !$Ÿ¼óq"Tj©DSj)ÔRjÚÚþìæÝwwWÓ#‰Ú¹°Q_þúÝøëO€$wÞ²›ö¨_xùýøÙ&¯ ÓIEND®B`‚eric-6.0.8/eric/icons/default/step.png0000644000175000017500000000026212342633755016677 0ustar piotrpiotr‰PNG  IHDR©þã#$PLTEÆÆÆ@/`?€OŸ`¿s߃÷ÿ$“ÿ.—ÿ7›ÿIÉ ãtRNS@æØf>ÀCC‹..Q@{((Ðqqi##Îll{((‹..׈ˆÂIIFÓ||Ê``ÐqqÓ~~ÇXX{((Ó~~Ýšš½??ÆUUÖ„„x((ÙŽŽl$$:=?ACFHKLNUX[]^a c d!!f!!g""i##j##l$$m$$p%%q&&s&&v''|))**++‚++ƒ,,…,,‡--ˆ--Š..‹..Ž//00‘00”11–11—22™22š33œ33Ÿ55 55¢66¥77©88«88¬99®99²;;·==¸==º>>¿@@ÀCCÁDDÃKKÃLLÃNNÅRRÆUUÇWWÈYYÈ[[Ê``ËbbÌggÍhhÍjjÎllÏooÏppÐqqÐssÑttÒxxÓ~~ÔÕ‚‚Ö„„Ö……ØŠŠÙŒŒÚÛ““ᦦ䱱ÿÿÿâ­EQtRNS ##%&')*+28<@@BMMQUY]mnoqrrtuz|„„ˆŠžŸ¬²³ÁÇÈÙÚÚÚÛÞàäääóôôöùüüýýþ<ïÎbKGD®¹k“§*IDATÓc`€n]K -.4 ìUÔÝo/ˆ*Êf’Ó¹hÍT+aé, â™K”H¡«–Dä6÷ôµæ)£ËMO.¬®.(‘AæpnŠŠOOÍtdGµSÁkzmi‡§,º õæ.[:Í]TÞ;µ¼2%@ U”Ç%¾rÚ’¹Ù"(Â&%%½³V¯“eŽ,ÊëžQß3cɪ ~âHšUÙµ]SfÏ[ÙhŒ$lYÑÚ;irocœ#\”Ï'"¹ ®­»«¥,&M.¬Ô›]\ÝP_‘§Öo ŒLÈÎ/*̉Ê1€ k,KŠŠOÉH‰ ž¨pXÑœ•X3Ï–.Ì"iææ¿|áüž®¦¬2sŠ)êj+Šr2€$WNOäIEND®B`‚eric-6.0.8/eric/icons/default/ericSnap.png0000644000175000017500000000306512342633754017473 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœÚIDAT8Ë}•}lõÇ¿¿»óí»ø%~kBZ ¥YQ‹hË…Pù!Æ ªe T´ ©Tl¢ZSiºxoÅˈ¥ :Äú²7­…–:ÄÕÚ4I iì8uœØŽãœ}öí»ß~wÐ ÑG:Öùû|ŸÏóîGp=pûåkäUá_ŒŒÞJfð¯CÀ=/߀c‡©DÎüQÙZò,´DÉ .™æx½aýð¶÷£÷¡ÝØñâ‘o[{©ìÚnÂÉzýǯgî«[Q#<`ÿ¡,LÓD*žB!cQSáI‹[š©Ãú–ñŽ÷¶à‰ŸîB Ûöê]°¼#ªª˜¼~UgsDñ»%‡ãGªX܃50“M,½Þ² ‹Gu„ÿØwî½{—“à£þ×nëHjÛ‚Ñ@8ÂÌèizsO'iä»@&R7ÐÖqäð( &*{uÐ\òu‹€çÒ¬iïûÜ;œÏþió2÷W¾-s¡•É/@õµë_zâ±?3Ѧ­µé/ñbZ<>øÙÖøÀÞ^nôxúÕN¬HíË<0‰ˆ¡ýiÄ¢©„F—Ä‘Eªw,v+\ˎߘ/~s˦6ìz-Ë(žÜÀÂSc£‰Oú"sGÿBEŸLI@£ÖÀ\Q‡‡o¢V² 2? — jǥ“oØÜù}›+œ°â$¨T»¢1´"Š%BUº©BäypŒñí÷ýwüdRã#Øòð­õ›º¼õ›ÝÙWžÌ£× F¢(¾Ÿ;wŽÌÎÎN ý_–8öÅsSiø¼&¼2)k*³=7`Ó/vÁ®JÓT\¼xÝL«Umó™3£››Í:8ŽC½^‡ÇãÅæx~~‚ HÂ|fœH²ËŽ%:1LÑ„V£h€(·1³´££´('(xâbóìB àc#È£T*9w¿ßOUU%ö6rùtó3F-sò$Œ¼†òœeö°Õñz½(W*0 µZÍvø¥ÓiGÌvk'’e““i±]Û—%³0–ìUa•~óˉ±<|½á´*^Çe³Óu­­­ÇááaD£Qüûä úã ¬^}"‘0²Ù¬ãÜ6 ü¼óRz 3øV®2F\Éð\!ODbZ¹Jµxñ%K¶Š¢°œ1¤6„ÿ:d›W.;Î}Gœ wv.„$‰ MÀæë<óÍJS:Çýü  5æ§ÎàŽŸ=Uïq0 ­µ›£( sqyàÀ$ ƒ­p»Ý SÕiZOOòù¼]•$ìÙó(|ð–%h¯¢qþ,êÕJ]×eçÕhs³d—ºtéR ²Ñšt‹Etww;“¡išƒ‹\è?{_mñù6±n;²/»T[Ünh¡Ppš‡áóùØâ¸044dŸ$\Høwß}½««k‚•+Ùg‡ùÖ‹åü°ÏlZ\¬:ó?ï“ÑGâúAßIEND®B`‚eric-6.0.8/eric/icons/default/vcsLog.png0000644000175000017500000000253412342633755017165 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ´‡ÿ”tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ÀIDAT8Ë…T[heýfgf7{™½ä²»5±¦Œh} H‰ ­B¥"}k­¢à›Ï¾ *_´ø y1/!ø y(¬`ÛÔBn’6Æfï»3»³Ù™Ýõœ?Ùà“øwvþËù¾s¾óýš?+++¡¡¡ eY§\×}©Õj½•L&'b±˜ …ŒN§#ív[LÓ”ÃÃCßq»R©¬am.ÿlÛö?ù|¾555Õ!žÆŸååå><—H$ÞǸŒ¡n·+FCéº.üæÔìSkHä°V«}@_#àÓÓÓMcvv6bÆ«Ñhô£x<>ÎXT€*²¦)`0¨@ÁDÍ÷ó!0½âyÞY°ùËs^W0ƹ‘i÷@yO2õ}_­sü—¿ñ ÆE °·¡ÍiÒ"7ñÍŒ¿übF~úqQ‰¤Ä­„zëº!µZ£*U¼]·!~ÛWyÆó½ËšhEz|ˆ‚$AÕbTÐaqåááÇdh(-6@®½sUDGàP¨Ol»&ÕjYܦ«Æ§Ÿ}"^Ë—3c£ÎÆÆÆU©÷CüH¡PèD:'™ H6“•€ÇOÈ¥7ßTª_ ù‚ܹÑ'OI8–’L6#£££‹Æ$ê(í¶ UdhÂ.Šá‰D"J[]é« Š+^>/ããã²··'õúE‰iJRvwH±XT,C^Уî²ërp’n`¶ÙlV“A8ÜG¨yJÅ3àÈȈè^Nòv@šÍ¦”Ëåž UE èÃÆ«OKñ0ea1S©”ªºçùгª²ª×ë[J__4mK>_Rsd8r©€A¿Œl‚ì(n¦|ScÕ·Qm_2èþþ>ºÏP®ß•\./èPÞ¡+Ö8ˆ¡3cfÌL Úßß/Ü×=nÊG}Yè¶ÒÛWlòЊZˆMƒLK(\ƒ€½N¢Í¨ú_œº£@Ɇ£×…|QšnSíc0kÀ:TC zO >¤ÏB’¾eÅ• Ƈ”™]6“ï°©‚”®ÒŽºö(cè3ðÛô/©÷ ‘ËåTú¾§sŽ1H @‘T< ïª9zŸ’¸ÆžF_a,ÂNEfÖ´Ùàà úÏ y·’&Û}llìäâI&¢ø>#½s¦uËÝVë333UÈð-ºé¬ô hu¹‘ÑÓé4.ž„ª6µ$Ç©"YW’ñL ²™ª)ÀüF©Xºuw}ý•5–––¼ÉÉÉ-ΣƒQ´62Ì‚bôþîžvïÞŸ299!ïß—\qGVX¢aKJ•²lýµÞÜÜÚþ¼Zq>ØÞÜy1WÈÝ…|kš<âyáÜ…+¿¯Þ|-Ô ^Ê<‘>ÿü¹³×‡ÓÑp Ž©I®ð°qó×Õw×V×çž}zb~sgã·ÙøÎø?Ðþ䀎ÂéPB“ÚoÛOnÙ ª qퟺüOP]pÔ{ÉTÒ$¼¸|·|œÌ‰eóßâþ<ÞºIm…°Ê·Îp†Y ÂdXw/"¡Ù[kãÀÎÏç𡹰âJ‡E^Îf÷¦òÇÈóÛ:žàE eR¦çfo݆l]mt ç¢k•Ry;'ã ÿ­Å›èÆÝ2â­ÝàŒŸ?ÖÒ=ü4g;¹8Y©ÎP±IAÂOذ`¸3;=f¯F{9Mð¯!„Î#4v?ŠšCE*Ö¸ÃÃkÖñqrþMéHŸ"4•šìºB&fFœ°oGO­ýÓqõs:dæ5Ù`°Î ›Ó8ÊźÓ8ÍŠíºõ…΂Uö^Ἡܾ=u˜ãñ÷K7kwØi,=ä8_[Dûp6Îed6,¹ÃƒÆýmº–.MåËó^<ñ_y,‚O’®oìõÔ í’MÚâ!üë hè ÂÆsIQûÞLúÖô­?«úƒÔæô+²Åë’miDÐ ¥siJgÓÐxÙZ³N‹×“(GGYmM¿#n™üfkgSÖ–±¶†~—6º!­­bí,ÖÞMY[ÈÚ⻉[«å*ˆ±â©üh8há,æB¼°1‹¯Uî¤+ÜðüjÁ!òÍñý»+‹IEND®B`‚eric-6.0.8/eric/icons/default/qthelp.png0000644000175000017500000000240712342633755017224 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÜ 0uôåbKGDÿÿÿ ½§“‡IDAT8Ë•yLTWÆÇR1Á[‹+¡ìÌ ¤mlÕn¡MÓF ˆË2 òGÓH‰ÚÒ%±(††`l ¤ZffXÄ"A0,Ê:Œ¬Ã*ˆÈ"KÞ×3oœÑ¡„´Þäæ¼»ýÎ}çÞó]ŽÉ'68{w8íOvu‹.òuÈyn‚ž½Xág•Ï5å¯ÃGNXa€ÓòxÎxaRgåZž\ÍŸ™} ØõKï'ÀKƒµåù}[ñð! iÿ Áy¶8[{òƶ»ÕêaÜìÕÖ>Í5•&îb­êÙÿ~A ^rZ’ñi® Ò®§1÷BªìBM×(š'‘}£íCw3Ba~ÈÂ9S© _žÇ(^<°ÍεGjM,.©$Ù4üRçÐį×ÕÃLóà=&¿^ 8šÏ"p¦̲ ì–D:ùWÀ9°Ewå[`ñ¶%–—µcgpDæL‡çFvÇk㪞x§ôVÏrëÐ}Fªì„ÑuóüÞ±¿%° ÑÙ>x&˜# AĶ¥]§±ÃßK´å õeìOòBD'Â$.ßÎ-¬¼µ¿»¡ƒhì-7Jq›¬Ð32ÄÂÊÌÑõ›[šÁ¥¯cO¬#2/²c #Q’¼Š¸²7“dÊîžJ:À* EaÃí‰î±IK£”RJ‹ ½aíŒì  ˜˜e!<߃Ƹ¬†„ä9ÒUsEõ¥Tý8)©íbzÇñgu»v‰í¿´‚U6²âopü6³`†YAºò¸.ËŒU‘^LâÕ$d^kÃùê6h&fŽi™ ìëÕ·’°ï«P¬PF L©!’ûéµA¯ÙÌçR÷•À‹V>äÿç‘û’Énœš[0!F¿cÁ#yÔÂCr\àn7޽Æ*Ú#™ì!xe¤Ì'/L¶çÃê©ôÄ¢:¤^n@çÈDçjuÓ‚˜¯Û™N—H&s…2~$9´¥ºúŸËüØ'‹vhRÜÔ}§¢}ʾq¦R¥l´Ë1 Ó«‰À¥´0‹%L$óóø/¯7TªÒrj; ­SA5|ïªÑ„“å{7>í“Ip³¦þQ·ÖqwúÞ¤ïÿ!`×@Ѐ8IEND®B`‚eric-6.0.8/eric/icons/default/textencoding.png0000644000175000017500000000065412342633755020424 0ustar piotrpiotr‰PNG  IHDR(-SœPLTEøLÞ3tRNS 45DSVWpswxˆŒŽ‘”—›œž£©³¹ºÁÌÐÑÚÛÜàâåéìîñóõ÷úûüýþÎ>ºŒIDATuÁ‹@€Ñʺ_BÈ-VRní¿ïÿn“1fœÃSw{TNׯhš>-¶c•ú àG{rÈœ|Þ®(ÄÚû9sò x»b?W4¾%G­ù†Ä&-ùÐBãKVãM™”‘0“‚—š¹ùô-(IxÚŠw ŒmtdˆÅ‰z@+ÆY-ùãmÈ 0ò胷IEND®B`‚eric-6.0.8/eric/icons/default/iconEditor.png0000644000175000017500000000262612342633755020031 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœ;IDATµÁilUðÿ{ófwvv{m»Ê}¤‘£ðŒAC0AAŘXZ&(Aùà@55&F MÔÔ3ørˆAKl‚”–B·Ýí¶Ý£;;»3;;Ç{ÖÐĨ‘þ~WiË–&JÃ5dÊ´Z¹J1CN•mfj¹*R™÷=ùH›ŽqÿÁÖ×7«Êºrcsd+¿‚"+ “®³DqJR;,÷_B­ìG¢;Ó›´Ö¶;vžá_<ßÔ H 7äóîŽ,ßiÎÕÍŸÆÔº¥HbÀï§QeóúQìÏÕ»FðÖ «"= ÿàÆú:½bþcÁgú»£5£ÃIÌjÌBY5ÆàBÓ«I$<˜½Y¤{m9¡ –© 10ü—>Ü8Ÿ³é¯¶!›ŽãD×WÈÄ œTO–T̽…‘ŽÝ†ìhç õä‘+ P… ¼¼ltç·Q!á/žÞtý »vaKpú õõØ]¤µaTT‚4ÜV!•/QŠý? •g\(”\w­šÓ&WÏ2\á­ß{†ò‚ÅÕ{Uu ²;(Ô°Fnºë\êb¨˜ÆPŽN}®A3 ?Š‚j‚ ¤TzèæyÛL+–`˜pòÈ6_õšÔ¹5JY2rñW1j&‰kÊ!2YB¬#M!ІrÏ`ÈÆó"ÌmB I–Ûšo_v­š8QK¹3&|_tfeMçY³ï˜äd‡…”"C²×RÐBÚ P2]d‚³†]äOiÖBƒ¬ÒÖµK—‡Hýs_9:zät"ð)ŸwÏü(³ªÈz±ÙVê D¦2·¢%d/fLR°z¦ÞBQ+‰µö¬Ó}0bªª´mJùœÃëÉ«Û:úôö}Q7LaÜdfN:ÞSÜ4t¬>+/\£HN^$ˆ,ª€rRgJðŸÏãìKD”r¢M›/\æÕ(™Z†ÿÖ¼vö;ý§:XëoÞÖš†[:ðS;Èû_R dóàhâÍSŸ´€˜:˜_†Ÿä .àr0îÂÍqA ÈŽíÛ1ÜÕ ÙtDj¨HX JÁ–=ý¿¼¼OËtŒcsf|£9óÁx–CE)éU¶QäL8¶€pd?… *ªÊT’äªËü¨­­‘B¾pð»÷›íqée-_Ð19ÌŒ'óËÌlŠLržnsH\@ŒÁŒ8žD\Ë6»uSˆü³2ŽèÈzD>‚£0Ù¥<ã TK'«³Ãç8× KÓàc\ppO€€À'K„;Å‚*õÜxÓb4.&Õ  wøŽg¡zVIkjj¢˜À´´gé dûbȧ,H.‡Ÿ>F Qî86wd—UV|ÓúCײ}ƒŠ%†ñ+R¶ 2j/rv´vµЂq¬L³/Òd¦ƒK‚õ aÁOÀFJ„1ÃsHV ²³L¦mJ¨jßœ;V¾zøœŒ¬)ÇLópˆ ?úЂqìá»›s»Þ{ê9f˜+Ò#iÅÐǸŸp×/S‹0Y÷<9¢k6Þ¿í#Þx¨¾¾J¨&ƒ™'@·¤<&þD0áÀÁ]>#gm4.Û²Ï'?áMÍos\áëo¢¢m'Ò™"öìUï(€ â{áí[‹q Ö¬~ÜÆ çÒEÛ4à- ÄظÌ!®-pÃUÚ½ûƒÑ舰,”2 €) yþ_å´©:î†Ç}IEND®B`‚eric-6.0.8/eric/icons/default/eric256.png0000644000175000017500000007755412342633754017124 0ustar piotrpiotr‰PNG  IHDR—¾‹ä6sRGB®Îé pHYs.#.#x¥?vIDATìÁy”¥eaèëßû{Þ»æêy¬†nš±eTAÀˆ¢",çhnTÔèÍ21ƒz9çœh41ƒFM<™L£¢[™h z®®êªêš÷¼¿ù®ç{׺g­Ü³²@ÝÏC_________________________________________________________________________________________________________________ß/ Aßó‚RJX–…Ö˲ø_ ! Ï1‚¾çcŒ¥”¶m„šÿE²ºì½¶£;—YÝu+ËGF%Êò¬±îîs®~€g ï9Ëè¬8wüQgqi®4ú„Ûh7œvsUíºøÒ—[Ž*Ô›uzÝúˆ•äjŠr`ÜÕ•ÉÝ«í©AÇU©Ðù(ç–ºåòÐcÃ#[ö:ÝoårµÎ ׿?¨ ü úžŒ1£!Ä"?‚¾gÅcö¾è‘\yzav¢7]­­ZÅ[´–%)UA*Y:¶Jåƒa˜Š^”&š|¡`´ÂvlG)ÂTkŠ.eÖ“³!…09Fm¬…[J¾E}I„Žq}WWÕ È6Ü98~Ö·¯ß~Yñ ôýLcì{ïþºÿÃ~Ïuæ]váå/™9=½qvuq{œFg…Q´;Œã¼VÚ“+S•*lßÅv”‚BÙP©*–—Z4ë=е<~¾€e[ËAf)~NE]jÃ…‚Âsº¸ªÈš!òN'÷å¬ X3îÓŽÚmI+º¡$[ÑDóq¨wLìþû‰mÛ>úš·þeÂ3DÐ÷Œ1&øÖ?Y»÷¡û¶Œoذ[jsñòÊò†DËQ„(÷5iÇÑJ[ü”幸yÛ³AlË¡P)086Œí9,.,±R¯#UÄàøÂ–ä¼¥UK T‡|I‘ó»ø…KAÁòpòMj ßr©aóÀÕØÙVVæ©V:“,ÕçqÌ NÖbátD¯­Vkc7}ö³Ÿÿ¢¨]Üå è{Zf<²ñ[ÿö•ž˜:ñRËóÇ3²µ8bsbt.É”¿nËzAD«ˆ¼W¦`ÏçÉ|rÅ¥r‘&vMP)Uqp°â¡Àý÷ÜÅ o|K«ÇÉÒ”b!ç„dI@Ͱ Çøô†yðáyr£9=ð6QÉòŒé&‹ÝCÌ7gˆíC±RdP°q8G6}’ö‰ƒtÛ³,œœ&&ŒYE2íÐUå±5Ô­!ƒÝÊaº1¹Ì"çT”bå ›:©ƒöód­ ;Ì()C.ÖH#AKlWa§PÒ‰¡è‚ra%R¢¦ca ž&‡_b¼së'ÿø]ïŸ]š¿n©ÙXséå—zgœs1¿éo¹}ù{l?ã4êu—»Ø~ÄÜÔa^ü–² ,œ¤4œ#J‘‰”Œ +óˆZå¢OTÙ°Ù'œŸcuq·š13pšÄ÷éIèu,D¬‘~†ã® º]t s£Ú·‚HѺMWÛØ•2cÊ,Îõ8oËv†kd¥qÔC»Ò¶H2(¹>–pñmI¥¤h™¡•&Ó’LJtfˆ3ƒA •…– £Áโv»ë<ñä ÁÓäðK¨¾2Yºã›ÿòêúÇ¿üÕV_ã‹î¯½çíXn޼÷&NϬpû]{‰’ž»–#‹m®8ï\°‡~ô¯|ÓKI–Wâ.‰¬ UD–´[ ®tÒp$h±0ÕD¦Gxõ[^͉xnØÀòSDìP$GÐ [=¬‚‹*ûD6ôV#šË2îR*úhY¤gçÙºm-Í¥Œ §‘XØ‘"Ó! ~ÁEc‘¤’Z)LÁÑW*â !î¦\‹œ+H A"RBi2(±À·…ÑJ- ¾æi²ù%òý[ÿ®ðêk.ùÕÛ¿só'O}›U,ž7²q£½~û·~ýÇüåÿ=Ýv‹›¿r+ÇŽœàÖoþ·¼“^¥ámØ7ÝFjêò¾ßÎèšAŠƒ ›ÏÎS,T‰;‚^CS)qÙeqô±<úøä’uŒÖlœØÂÓ>•b•Í[6R-ÚXiˆ£»*~õZr›š˜RÛOh6›ø¥ ç¾ð%ìÚv9c£g³uË,O¶ùêç¾ÏÑg¦tO­0õÈS,<þ$ÓâôþIìFÆåçžCýD‹¬rî¶*žkèd6;6ŸÅÆ-;HCÃÄÎaV—ç ‚|•µ›d½H­sdI†Šbt⤒‚z ¥0.al‘Ä‹T4Æ©LoýÆÿòÁ?ü½‡ÿèc_0< ¿àŒ1Õ¿ýó÷½ïÞ{÷¾74jÌò»“¢^DœF¼õ½¿Ac5æÄñS4Wê Œ ÒI2núð˜;óª7þçœÿyèV6l?ƒÁý£˜šÃŸÿÙ_phòAªg°Ú®3¾e·è“+ùœ^šâää$Ã%Ÿ3vTq†S_axÜgv²K½blA«­9ïâ5üÚ¯¿».`}y ×^qwüh/'L18\ãâëw2}—;~¼×¾üå —z>6^=Md««äÉ0!5^Ù‹ðtFNÒž&I ŽåÑ ¥|j¾H=iщB„ Å¢ç"i–GGªR¸Âð4 ~A:ô˜s÷_ÞÚ:=ó+­Õkc„EÞ%Õ§V¦44„Ö;/¸ˆGîÝÏ·¿øMT&ùô§?Á—¾tìÝËŸüý?Ôᩃûh,göä}¨´KµbÓª7è´#6œ·–WüÆ•Øp*2È8chtˆ-›\¾ÿ/ßCF«¼õÿ\Ïk*u Eª]>ó™cœwѯ¼þ ŽNYTòëX7¼‹Aw-ŸxŒ[¾÷¾»÷Þòöw³ øRpö¦ 3³4Ú'YX HâGeÐëÒS6Vm€,ˆ‘eä´&‰ Žm#¥‹T.OM…´zŠó¶U(ê½¥5Cƒ.­½oxËuozÝ{¾´ÂÓäð èÇ?¸yËm·|ê­õÆò[âLŸÑ36VÎGøyp®zÍké1_¿ùkœ±çb¢ CtÙ¸}#ûÇÃ{÷³û¢ò¯~¥ù‹§§:§‘YPx®åXäJ6;/ãüËG˜=½H£ÙB8EÖnÚH­¼†›ÿüËŒŒÕxͯïdh8áT{;ߤêŒ1à¯CêÜ{´Cr`šÐ‰ÈåNâ6c]aÛϾ„M ÛyU©Á+^ý+ØžGÒ˜~ðfVZ ˆ´‹ !h…t–bœNÊк«K-<¥ÉÆ" ÝØP­z òí»˜œ°€F16d±nÔ£Tph‡)òúÚ×½Oóž/ñt9ü‚ùÆ—ÿú¬ÛnýÊŸúŽûŠ N]f”†ð«ƒP(1¶y3ªº†{ø-.zÙÕ òÈ=÷³aÓ•‚`ifž\ÞçÔÑC¤mE}y…4 ñ]›8ŠIS‹b¹@„¨Æ0çnx-ªy/;·ù¬ÙÈÁÇòõ¿ø*ç^¸–+®[ö1NÍM‘«¥Ø9‡J¡B'*щ\NMv8çqQa•Ûdn““½e[O» ;wlààâ1ægVf÷¹ƒŒn‘Lí_e×–NoRÇåÐÉ%l7¥#UׯH!,Gò¬t$ߺ}–…•˜¼ g¬ÍSpXéDš‰¬Ø„¡æ‚ Öž, _\7ƈŸ2< ¿ ²¤î|ÿÛ·\÷ØC?ü­j¥rE£ÐhŒíZφ3'… ÝTÐ w~÷Nîýî]¼ÿáÃoû]s‹¬ÝP­X»i”åÓ ´’4–çˆz=,Ûebû™?ñCš¤ØŽ X)óÔÃ'¹íæ{9÷…ÛyìÇ÷ð{oáÀ}OòÆ÷ÞÀ»ß{“3÷ÑI:ÔÖ†b±B J*ÇæMxü‰‡™™n¢Ç;8:¡X6˜–Ài/SU¼gšá0O³›²Ôm²Ò;€HB YÊ¡™i‘óŠžÇ‘Éˆò›RAà ›Lb¥ Ò˜SË15¸ükè´ʶE©ê°Öʳ¼b4Ì¥!…B¹Ä3Äá@#ìä¿õå¿ù½S“‡ßV¯ÇÛŽ›d~¡Ž†ìø³u.xÙÕ¤¢H'‰1N…jy„¯þå?S.I«Fƒ²o8ubJlWÐjÏc ‰áÄ‘:– ÂhŒDABe¨Lcù_ÿÌç8þð:œR̆1‡M¯ßÉ›ß8Áü©ûˆÂi p:ä\ƒ—æpÒ{š±¡.í™6½ãuFŠ#$´bÜ$ *BDj:&Œ˜_Á´L>ÆJ#j&£%5njÑ:á ‡‚—Qq@EŠPâ–z“·_—'_uñ¼”š›á%\Ÿ^"À”|—ßó[Ƙœ"æirxž3Æä¿ùÿýOïß÷ð»öí?Z89·B¡ReÝö ÖnÞLµRâàOqóÇþõgœÉÐÚ5DiwÜô.Î8{'ØÇ'÷ãAJ«c°\©$BrÅ"Ñ$¶Ïšb aÍMŸÀiwñÉÑmw°ÉRqϡӊ¨ Ét/F hD‚nOÑëf”ŠÅ’‹_qQ¢ # ® ™e0qŠÒÛ18žAKˆ’žhžÏc•CÎg>ñ;¸ã÷¼gn±åŸwѼõýW‘]OuÓ&ÖmØÂ±Xš›çàÁ£ÜwïOxòàC”×É{ì»÷D–’+ç鮆tÛ)µá«ø—¼_ Šb4¥A£Áß42ÍØ¼m˜âš.'—ް¦:H~4OýPÈSGfɬUÖŒ**CyJN…vW9¶m3=Óö*T‡,fZl zÌÈÄ:±Ñ™Fô ƒc%~r÷ãLœ5Ž^iáÔ¢ŽÂ2.¹nLQ‚í î*Œg0®E©œ£+SÚÊP.yÇB¥ ÏhcÀDÊ`ÑË2XŽ&N4ÆÒ†gˆÃó”‰ÃʧþúÃvß¿ÓÞ:d¿ú7_ËØÖ­ÄVgp Ie€§:3ø*bph€± ¶ñö]@sižO}ì8úÈ16o_ËÂä,Y¨°pˆ‚ˆM;}6ès'›ÄaŠççH¢!(UÊ'#‰S°,ν|Í– XFÛ"[OœÍ³Ð^"?X`µ—`$C•Æ/#Œ" •gÛœqîß»‚Š ^êaê‘ÚØ–E*†· ÿ@Òj=[[ÔjETG#•ÇÉÙ€'·ÈUl}ŒkÅ’íÛJ¬ÔcºQÊHÞ#_­5Ú’DãØ6ƴѸž° ¶- €ààð±J¹’gÃÖFÂÂ\ŒåJGàç\„%±]›4†¡ {®ØB;Ã+àåáø“0w2Âð0©‹¯âê<–# »Ø¸´pxñ+ÎçáÝEw±Gq°JVO¨}èÆ!Xl·¹ú•gs×·gçÖQ<Û¢·œ07ÝâÐdÇ ­ Pöñ=AÉ7¬6#j>NN°²ÒêD x:3X–À÷l¢0ñ ¶eÈ2 yo™TÂulÃÓ`ñ<3Õ:íÿéÿÍ›–£æ»v\±‡‘³¶C©‚]®R]C¡<€°‡(WXŒš,6˜Y<ÅÜÜ4vYpÅ5WáXÍ¥6·ofx|˜4ËÈ— a³²Ø#•ÛÓŒ¬±³)Õ–øyH“Œ(ŒŽÖ(Uó³m ’¹É„ÖŠ ³’Ò\îI ãç± y•'Ô9„—'³´ãÐîeŒ¬­2¸ÆãÉ»§®–±EZ¨úE\- 3Ô*ؖéMöïŸç‘‡gyêh0ÕlØ2Jelg°‚(æðK.£ã")QFR®Ø4A”á8ÏøžMš¤4XÂ`´FkƒRzep°vH¡\Ç6¤è»¬Áw-&vçÈlÉéUFs¤Fáø‚^œE)*K1ZáØšZÍ&èIT&°,[@”i[ ŒŽ R˜t݆séÊ*Çàþ£§è¬Öi¯®‚cqä©Ã˜"8Û/Ý¥Œ#{¡R…ãØ„]ÇrÐÚ`YEÔS„=Å»?x k¶¸ë‡?b`¤ÈØú–¨pjršÓÇÙ˜§ö ÄÈFá*0ÛHah¯v©‹Q‚s/YÃwWxèߟâú×ïÁw]º« ÊNžÆéwï?IÎv¸îµ0¶¹ÊìÜ*ÆÒÈ4aܘ›^mX·®Dœf(%±¡‘©Â±ž-ÈRM©`#3ƒRຠµÁó,”4 ”‹S¯ºámGyß?ñLpx0Æ8ÿõ¦·½Ï)†Úºó Kz%¼\ ¿<ŽqJäkëI”±mTfX™›â‘½·srß#,=Œ#†Še.|ÑE\úºëÀþå 4»mGÆBw%›/ÜÈ®­[xàŽ'8}r“A˜& J¦K!,ÁëÞu ½t„}dãD™V£ÇäSÝÕ%~ý½/"Zí2y`Ù¨‘°ˆæö€"èønFÔS¤™% PËyÕëÏæ«Ÿ}ˆûî8Äe/ÞB©äóØ=ÇÙïi"-yã›.$7Xàɹœœ`uµ‰éEx9ÁæM9Z‹õÓ-rE‡bÑ&í)´Ò8„†ZÉ¥Ù–t:¾çâ;¶eЙÀHAënm¼öo#ë^¼Â3Äáyà‹·|â×t9ý/£gn+­ l—L¸¨|§\cI%8ƇNc{È=_üWN>þùbŽgOðª7¾Š+_t %ß¡Rªº‚ã‹SÜzó7ø?nz;‘èd†´P.øÐ§näßõ×X©”–”*5ŒIé´{¼òÆ1¾{Ëð 6ÅÁ"gœ_¡\.âdcœµÛÃû3ùð;çxüÎ.¸rÊLÐA™„L4?¥R)õVÂÄ–^sýNn½ù:KQÆpô@_Z åÀ‚…•:m’)™ qLJÔI‚õ5‹E%é)®pÈû‚4´°Ñ ahÀ£Q—t"Åø¨‡íÙÈX ¶e56nÚ~Âð ±yŽ{ìп]øãGîþ›Áµ#kba³ˆƒ.ø$¬|™r©BQÛýÉ=Üõ?>ÏÝ7‘du…+/ÝÛßð*nü¯ïfãÖAzÝytÖ%K#¤° ”fvö4­•ã[G©Ö Ä­.s‡WÈU<¦N³çêmìÚ3Ì–ÝU.¼j½l”G2…Uˆ‰SÍøÆn5Oœe½„Ú€Çjk™+_2Áƒ?YâÀƒKlÚ:„VY– ”D$2H :“ mcÚ’ZÎ'‹3žxl™S§º¬[_abó ÒƒÙ…Âá(ê§Û©1a†¥HÔäòŽ-è¶3J¾P!Á2eåzŠm[T*.ÊÚ`iC³­Èç‹{?ðßþòo?ù©UÌ·|‡>Š0’W]{5×\u/¼ülÂî óñI'¢\ƒœpIµ¦¹óȽóßÄ¿}å<þï³}÷(5¿ÆÐ%ëIÉhÔ[H«‹)ZäÍj§ÉÈÖµhK1y¨ÃöÝãĉ‡]qð<Ì"V“F ì?z’ßú¯{¸ñÚyݻž«|4_ÙèL CÌOÙàfc ÓŽi/ô(ä|,[°ë¼qÎ>o=–1lÌYÜõݧXÞ²iG¡¶‘Ò$õ¡0©ðmc a'£àÚXÐÅ#¡\qÒTb+CѱÉù´«µ‘oŽoyiÂÀ#~ÊðŸàðuÏ÷þnäôâ¡~ë;w_vñ®âôRQð°Ê= XOçÀÞo2ùè!\asãÞÈK_}5#;*´½6÷DZ˃&¤œË°¥9ãqð‰iîÿá}¼õ7‡ßõûüøû_áîÛ¾E’Fdù<«Ó ããçÇè¶|ÇÂ÷kdá8ùb¹Ã’5kŠØn‘Hö(øƒc‚ '–>Ó“«ìÜnqå+ÎäG·£0è°aw‰¼ë2`{d6(´BB”)²ÕærÀ¡‹lÚ4È•¯ÚC;i§=L’rþ•›xâžYŽî«3>ž§8lãûY=¡q= Ëh a Ñä-A1Ú²²0ƒ+mÂFDk©Ë¡Ã+´ÒŒ]çÓõ4‚&J%ø¾Aw#.~q‘cJV–B‚¦E­lQ­xHmˆ¥"'H+Õ”|A¦%Qõ<§ëRâHâjCµd‘e†N`NÖKŸýЧ­óB˜Ÿ²Å‚à9æÉƒû6î_üþŸí»ñº²¿>ÿøC‡™;~ dž,‰ˆÓ„0 yÍÛÞÌËÞ~=µá ™Ó"£ŽkǧC,Ûd"ÆÆ TWfèVÈp.Çä‘þèƒ_ãWÞú".ºæ|êA€[†RÞ"W.b¢5 ©~íòwa‰‰­›©+HÓ¤ÙËX˜_åºíf¥’+x ä|Ïó ˆÛR8–À¤†’[bîɘ/|úq6l¯qÖžqüA­ìàÄÝxÚaq¡Í#û癜 ¸ø¥8ó²1Ú4@ŨfŒ 2„Öx@Õ8„f~*cu5Ápl°N ãžGmÀÂ/B7I‘Zd‚ §ql‹JQàØÇÕt»šœçýÕ-·ßó‡"ÿ‚ÿƘ’¢Ç‚ÃsÈ©c“ŃÝ;ßvÏ}]¿y÷%þîs/çÅ×߀…¡œË#ãˆaÛá‹·|‰Âº!DÙ¦#{à)Ç#U1*6h#Òd1ŽÈ¨:X)–ëqÏ]O’&ë7UY˜š…ŠK*FH¹˜§×šáìË^ÏÎ ·3b’8Õ,/ž&J¬.'\úòM€œUd¨ZÁ!&M"•a[ [lÇ"êe„quÛjìº`”Ó'[´–»T„/«ZD­€N«ÍÜT—¥Õ˲ñó–•’v$–6DíI¡`53L¦ð=‹ãG|–ê a$q}AÔVxžaèö A¥ê0¿˜âº‚œ/ð=‹Lj‚ž!“âÀ+_uù?‹ü Bþ7„=þ“žCî|êK7´ÝôƒÃÛýüæ!NÆÓTk£Ô Ã(×Á¶r XeZÝ:‹³ Îtö¢M‚«t’@”`+…Tš,ÕH;"KRœ$£=»Âá'ç9ë‚“Òjö(¹Er%A!'°uÆH±Âjë$O=t˜K_º‘=/¸„úB‡êÚUþá“& _ØÛ‚8Cx@f@ ´eÐJ‘¥ ‹ŸJ4zÄ5¯ÞÁWÿþQæ§ä Z½ ¤`y¹Åâbƒ8ÒlÞ9ÀÔ‰€ù¹ƒ›,Œ1ÈTâjPÊv3,¥Ñ©¦Ù68R6y[¯8`H©”X‰…×±è¶È{‚bÒT¢tºfé¬?ý¹ý ?#ÏßÚûùëšiôÑ•Ž.Mì +;Èœ$*¶i˜:-Ý¡GDG6 â. 1õ¤ASµh&-Za›v; Ý h5"zËA#¡³Ð\ê€2ì½í',²y¢BÆÝN ‘ÂÙçOpû×fËÆ"A+C*­HСÆ69×!‰hC$,-´Y\èrä©&UÅ9—Ô¸àÅC8y7g£‘h§«–Ne,LÇä}Fd SMi`0„†4ßÌ×5ÝÀ02dáú`´Eœ@` ° jã¸î÷.yÁÖ›~ç=ÁÏųè†ß¾¦ óöï¹c¼„TFKHÓ!ÍšØ,iQeòXè¨'C”áç<:+ ºÓ‹°Ú$>µŒYl@£é´±d‚J#ºÝ6A3ÆssL]Æ66CCUâ^JIT¢0‰ÂD Jl•qzåAP)— ÊЫМUX¢ÉÜÜcŒml°óœ÷ÜÑ`nR"Û)Y;…@ãace‚¬§‰¢×Y\hqâx“ÙÙ¥ªK.ïãU4V9À÷cÊåÎiͤB§¿lcû’â‹Â"Q¾] ’D¦HRd’@d8¹ÿ$CkËŒ¯«à9 1H¥pmÐ(B)ɤ¡T(²f]•ûïì²iËReÛ`T† K§ %Xšv’eaQK“/ƒI S„6~l’ _8Î??r”L) cc%LQ QF «+§çBŠó.,âúƒÌN/‘f¬”^G"{9>Ew±MÞ(Ê( –!îõ“§h‘¨Œ¢ï3ud–©£óœuÖ2ËF£T†‘)F%Xi‚ekœ¢áÐã]l˦V+á[yìeT (mC¥8ÀÉcmâ^Œgƒ-,LfHãŒf#áäd“ùÓk×ç¸èŠÎ8»D¦rì Amax“Æ6‹¸™’… QG‘·lâ®ÍübŒÀ"_m|„¤ÇâJ×£}æöÒg¯¸úÒO¿ü׿¶Ê³ÀæYpñ•­—?>òbóÕ%gÓ6;æö›o¥>½ÊygO¼da[c¯†3¸~L}¦ŽN 7üê¼Þ_©`{9èÐ@¦IÛ *°±3—ærÈÜtˆïkYip„…e@% 2°øŽ…ïÚd©áäLB§g¸äìA6¬ÏqèDË1$™â¼ÝŽœˆÍé¥ôè»ßyíû?ðñ{¾80¾+á9Àæçè÷ýÚºç=Û.zÝ@£ÙcòÀC8ëžg“µ@uR=ö…\Æž«†8û¼u ”Ù×Éÿ›=8ú5- üü»ïçyßÿömgë³ö¾Ñt-;¢Šµ·D4.S®cªt!1J˜˜rÔX¸Ä8Î80jœ¨¨Œ¨ ¨€ˆB Ý@/ôrúôÙ·ï|û÷ßÞ÷}žç¾C“*§¬J2Kw›>×Åïÿú_²qy››^tÞ00¨k–öö jÌ ±RŠmN,,ö u ¥B*ÆÙ“k,í«QUbPr2*„ WA5F™&&Û™Ã×,püñ1MSèUQ#™qùÒœÚáÆÛùºo¼×ÿƒë©GûøíýƒÅÀ±;+ªž¢¥¦dÒ$3ÛnÉS¡Ù5"©'f”ÖY)Âg°äÔQô•^ x¦SãÂjfЋÜ}ë2¹g.ŽÑý!Üt}Å©s—®Èûð¾íÛ÷ÿöŸ¾õ­ouþŽ|ޏûÁ·ÿÑý¯ÓÅ;¾ äyÜñ¢›ù¢×\Ç©+Óî6ôd™v§ay%sþì .ž4gмîeK4mÁ0ÚΘ4‰lÆp(Ü~Sß!|èå¯úÊúÞü;ü§?ÿBþ® |¼åøì–jïýÄùÕ¼ræòIK›ì?X{üýö2}‰¬Û"ˆÑµ‰A?Q÷ªWÈ$¦iÆÖî˜ܸ‡ÛnÝÇß÷8óqÇÒ¢`]ƺL¨‚Ð5‰ÙN‹7™&è`qXóè£Ûlou,/ …ñ¬áÜ¥ 'NM9{qΤ“>_ý†Wqáâ«—æ¼æ 7rôù{)Öi;% `>kX_kÈ­}‰ÿÙ[ësŽÞ<$¢H2<hk y^HMÁ‹a)£8 ýÀ¨î±Ôësi5qö|Ë-×õ9¸#ÄÂŖ鬰´¸þX'mÏÓžw½ô ÿ‹úþýûø;.ò9 ½¯ÿŽK,üäCïe¾zêš%6N­³Œa)llì`s@´sgaïQÖÒc‡ý+™ºrÖלÍõ† s–G¾ç»îäío˜÷_ó…¯>ÈâhÀ…í! ËK}ê@1cg;3Ÿ5h€ç¿`'NlóÀñM\„YcC7-pÃm×°¼¼Àѽ7òš¯}ÿûÏ|ˆcÏ[bñHËW6¸¦/ˆÀÆ…†éªA®©‰\¼²Åöú„ºŠÔê̶^)1’ë„Ô€¸0ì 1:]9;Mׯ, àŽkæ]K1°¸ æóÌG>¹õ±W~á+~í¥/¿ý_¿á;Þ1ãY@x†ýÙƒïß{q4¼øØ¥µÞž—¸ððû¹øÀ}¹i6Ùfpåq†K&¹Ï£öMg…¶®; ×Vâ•ÄhÖ2YÛ!K¤_WtS¡ìN_Üe¼‘ÙÞPNŸS÷ ^,î°thÈòQc°XÞßgÿуšY¡äe²=§ž;³IBÚÈ»?}?ÛëSpH»‰ñùÌá#Cf;ÆdRèÕ5“M£í¬°z\ Ê|J*bGÀhRF€Q_XYô+lt“Äx7qèšÈþkgW;æôúpÍÞ@Ûf6/¾øæƒúÒ¯ùÚ{É·}ÅGD^]xž!î®?òÏßøo.^š}S^x>G¾`‘Ý‹;´Èê#'9óà§Hã+ŒÚ1áØM× ÃEÆmÇ™Óän-u0öè‹PZØ(ÂÎŽAº¹2›AŒ‘‹«-ÉœC×/±th@5 \sËýFÝB¥tmƲ¡*Ìv3©s¼¥Æ3òLÙ|"qêÓkÄZxñkÑ« F¡W›0Ùm¹r¡¥™er ³m#¡ª äB¿F}XX, ”J¡dCjÚ©±° ÔýÀ4뻉º ,õÝ›iY½íÚ¿óc¿úÄÿ,2\çYLx†Üwö—_; ×¾+ n\ù“{OsâÔÙ»_ ­2?¿Éú©Kø|B+SöìíÑÍ;Ò4SeïÊ€'Þ`´È]Á$‘Íé»9ÒÎ 1aiqÁ Oꔿþð)z£È‘;ö±ïæ%zËÃ…KeÈpØCÕ Á™Mæœ=±ÆÆå1»Û ¹3Ú Ì§™Ü³ƻ۸+Ë#—…ñî”Å…@¬ m2ý¾ÒïG–jêfóĨVz=Œ(‚#ªP¡d#»C( CŸùTO:쇃ûAcfÞ ¾ùöü³ÛGƒÏ‘gÀÙÍWÛ\û]õ®gãò}]—‘}}†+jG‡‹xVº&#­ 1’¶ ÉœÑ00XˆQȂ͜Z0n˜Ï._Üàì©mNŸÚ8Ë{aq!rëÝ˼àE¸éÐOÜ?´ÉæúV„£G~ +°0€.u˜%°Èhàô"5ºÎÙ!Š "€`Eh͉uE#0n[B4^|KI.ƒý·ýú ÏÉOçþÆc?þ6áóð xï#ïX®‡+kºüòªÕ~‚û?öA.=q/g™K+tã€]%OÆÌµ{„´Þ`»™nZ1I¤1òJ¤·ñž³0¬ö*°Ït·ãÔ§79÷Äû-JYس@n2i™O[š¦c>mrÍ¡>£Q$Dci)Rõ«çvˆÞQ:c2+ ¢²»±ä”ÎÈÉi¦€;îNq!›ƒÐ%G¢Bà(B1'wN ŠVŠÕJ°B3Ï; \¿¿žÜtçkþ—ïüþðgE$ñyDxšù؇¿ùèϽ;,ßýÚCÇîw×yôÔC9p3ƒþ¿÷ó?Îlã<ûöp…ÄpäìY„¥Ðç‰K‘vxøÄ„"¶¡ ÐVbǰV‚ Ö:³qfº“Q” ‘ÙÔX[oôkP!ëœáBE¯§,,Dý¾RJ¡¤L×J6fóL])ÖfrÁ;ÀA±ÆñâÄ ääTApœV DpÈæª(Ä  à˜ óZ%n¼®¢ªb{äÈ«Þüã?õÞ_ãóLàivð+¯?±»þÝûn¸{ÔN_~„Gºzpˆ…¥½ÌvÎséÔ †£ Ìi·ÆÌ.OÑóD;/lì$.®Mis¡7p&Û‰<-Ä6é˜lµÌ·;¦[-µÀóoYâºCBÎ,ô„åa@K¦C7,³oÿa¿Â‹ÐÎùĘO`6†f ©J§¤™àIIP²ÒÎ!w³cÅqŠý˜LŒ êV T•RWJ£ mW˜w™¥…½¥=ûÚ»^üúûáÿñ¿("…ÏC‘§ÙjHß¾¸ÿ–½s¶6ÎqæÔýtÍ.;;—Ù»R³²ÿ()GÆÓ–Á2ÜÀˆIT®\n¨úB¨œ6%êžqç (^èli§…Ú…FœÁ bi1²0 ,Ž„L!·ûE¬8McÌ&ÎÖn¦Ð2Ÿ ÍÍZUØ{è0£å&;kXH '‰¥~ͬW°ЪP # +™íç–c}¦;FnfB!0OŠ7FSøŒD¯†ë°.ÓŒ¹ÛWZ4¹s‚" Rb€9^„äNJFÀ©ƒ A1qpGEpÀLШ4ɉ!U!DÀ ™‘[£Ë…~O˜µ…\ Un¹¡&{agæç¾òu_ü oúÞù6)|‹<úýÅ«Ítì܃Ÿâ‰ã÷sà ná…w¾ˆ½çÏÙnfe° ÛpíõG¸ÿÃ1m™3Ý|®tMG¯(±fEˆ£Šé¬# ÅŒ­I±.Ó¡™a0Pfb˜ÌRŒœŒœ•åHa2.X1#Šƒ@TÁ͉•Ó«œ*(¥m瘪 *DQr.¸ ƒ~$tVw§d'§?Pœý{"שÀFú'_ù²×üÈ›¾÷Þ#"…Ïs‘§É}gß=Ø™Lß {ûÜþú×pýMw“ûʉ{Oòèý Ý÷®Ð‹‘~¯Çdc‚·OÆÊžŠn'1Þm©‚’kŦ !²Þ$R*hå\»OYÛ蘌 q@„éˆ8u­”l8ÐïFµ0ª¢‚ô¯s¼€â”ä¤ä¨;1€bBÉNÉ€*B¿D`š*(Ž‚FPpˆµUg>ËìÝX)MknΕ»_þE?üƒ?üî?ã9 ò4é/÷%êK÷E•»žw”=‡ûª¦Ç]·ÝÍÃ÷¼—³›ìž9C·é‡>,(%£Rˆµ²·Û )B+;^ +rh‰}XØ#,ÆŽá^g+@Û  ¤]ž„~Œ„ H š`ÚÄ3Á Jçˆê|–˜£"äâä Ñ#àÄ18QÀ Š9¹d‚ ¥U­$R1ª(DrrÚ¦PWÊp ìY®€²qðèóßòƒ?úÇïã9"ò4ÙióklP®;]eMVÆ+ z#¢ŒØsÇKxá—“ÝKhžšŒÎ;ýøÃ”Ô¢ÑNF}eï55³qGpèZÇèè÷…º$;k3¡ß TÊA„¹3vÇ´ *´a‚!|† ŽcAø¬l`îDP*sPP˜'Ç\Tˆ"tÉÏ}ˆVŒù̱YaT7탛oWRß/éÊËßü#oþÀo‰HÇsHäiÒ„öëçÙësWNSr ìîΨz#K+,:Àêê%öì[bÿ±HÞÜbïùEžx`‹*UíL&‰€zÐMU¥ŒÇ‰¶ýžçÐ)4 NJ†›ãnF0ì+•B¡dÇ;!¨€@)`Ùœ\@˜AWœ J¿rã€cYA\Q’;]ç<);/Ü(ÉXª„GŽìwv&>^ÙsýO~ß›?ð›"RxމãÝšl‘¶+dSlƱ»ìE8þ‰ Úy&j 5†™1ìGr\É9 sJ2,;•@¥B¥‚âdsÜAT¨¢ ’(²€Šƒ"ÄÀgnPpD !%#%#ªPE%ˆÓu†‹Ñ¶† Œz¼s ƒrÃ/~ÜÇUÿ^ä)ØÎ†ÍTn<¼ÍÖêIîzÙ ¸ööÿŽGøëgïcº{†Éê}& ÚEÑ+3r™$ÑEªAZûì¿Æ™'GFQTÉ…ÔfØm170s'ÇLÁ‹#@ Š â<É T8˜ƒdÈ1((¸¢JvÇ pH’ÀÀzµ ¸“‹QŠƒ€ˆÕq…iýб}8vÃq®ú["OÁúx'n­í.;³¥ãmnáí¾ãZ¦>áöí£Y”>øqNÞû(ƒÑâX›()#[—:fU¢m3]"‚VJÓf<;¤‚¥LÀ©+°ìHTzª¤`€U @P!Fâ”âà ¢9O2„b b¨ Å¡æ˜CU êBJFIN›AŒÏ²ìu4mnøÂ@Óʾa^YYZ½ÿcïÚæª¿%òll^áòù5[=³îÓé\N?ÍNþ]._¼ÀÒ¨b)fØÇÎEÆ/xUÈYˆ±bu­¥2…’R B—3ž ‚£¢BˆŠˆPWJ…Rœ( 8¥8–sÇ ‚( Ž*(ˆ;"‚ãÔpwR6æ-¸ATPÃÄ!DÔÂtîŸ÷šúý8YXŽ-—ÝjpÓ¾·ýtïòþÈ_®ú¬ÈSpèè1ά].;Ü|×¾ù.]ø8ÌwÙÚ踼½ËÒRäu_u÷ýÕc<ø‰ xqR'X×(D#ðb@ç úÄ~@J.t‘³SæÆâ¢3ìÌ¡ÃÌ@œÏT æXÜA\•bÙ™MŒ„ZÀ¼ ^P/ʼn‚ `ý¾ØhX5uÝÛ©,^,³du_6Ÿë{ÂUŸy jéÙ·Ü\ö~žßxÇ2X2ýøŸ1ݼŒJnN-5ãL¯Žì]Òv†#Ô½ ¨Jb²Ý2i¥sT„væX2æî˜9Ù P×Êž¾EH]!eGÜ æà*€:%9nBžä„' – ˜€ 9A1§m^D ¡˜“‹Ìg8¯£–y’¶7Ð˶CXog»7Ô½={€K\õY‘§@‘å•=ñ…¯yµP ØÚ:MHÛç¶uƒ—)¹‰äù€Õ³-9G°@±–9æ:sÈPE%Möõ™O2IU¼ ‚‹3ă, )C6çIn€B%Bˆ‚»<ò$GP¼€m6ºÖ©*¡M…\œåa…Z"e#™#â¨â ˆâË jªâ]–yÐ0u—Ýt¢6sÛù¾}‡î<}ü]k7Üöõ™«ˆ< ½~wyãÊÚæÅË7lNç²½sŽ[o49µ~æ‘Í—n¬mpåÊIn]é8tx…Õ‹W˜í6ÌfÎtw†!jDC@ÜAãP¬ÌPBT¬8M[Qw¼8C6'u½ ¼mvž$„Z@UP\œbTˆA1‡’'¥b´3ÇŠA×îN¨ÄU¤h”®×‹mqOmò®îõ&ƒA½CÜ–Ï ÕEw9Ÿ³­—.wÓÉÎJUÕ³s'Þ;½ö–¯0žÃ"OÁËïzÕäžOÿÕ_ož>û5[›{××.0ؽ‚·3ýeÔ…’ͼ!§B×´¨êªB©wAÌ(nN'NÈ“zµ’RvºlD ªXqJqp!8Ž»#ª Íq* Ï / ÜÜÁ sŠˆ«`u¥¨´ˆtîq&JS×1õ{q ô¢ÆúJ¬Â™lr:›_Èm3nf³íÜ5Yµ.üÐÇy®‹<R‹ÿó·ÿìÎlóJzþ]·²~áQþÄÔ3Í4SZ(¹ð¤ Jñ‚:„b¤®¡k7ÌħVl@]5DPq(ÜPÌ„¢,;x…«RJ!gET”” /N.îVœ~<öÄMÍECDÖ5† Ëu¨æU е^¿w®Žá´ 'p=ßueÖ¶íæ?û©?j¸êoDž¢Ûoyþ‰‡?ðž­s8xðà56½0òÙîVH¹J"u²!99¹“BF× àT•PÕ" €œŒœœR!F¥K†9ÔQQs'ˆ" ˆ î+ÅæMÂÝ©*E6eÌ  âý(®¢¦Šíˆ>wt&ÈŽªŽ¹ “~¯Ù\VUã9Q} “ÕªWmìÛÛ›ýÔ¿¼×¹êo‰¸X憺ôâH¦Y¨»0εi:µœˆ}—ÔAj)µD• ã3Lpã3¢øgH"U *`Öb1 "N1<Cu ŠºæÓPb²ˆÖ¸j1o¬Hmæ%TÒVQÛ :­£î¸ƒ6Dß5c¬.Å® ºê.‘‹.²±²<\ÿ¥ßø¸qÕÿ+áiòŽ_ûÉ_Ú_üæfº•7¶6òd<×ÙtªÍ¼mÓôº¶­Ú¶•Ô–˜º,99”B£Òfsý j¢ˆŠ‹àQÁˆ©"x1<DUp÷€IU¯ªà¸t¢Úuw£RášEt&Pã2ñIˆU½„¨»uŒ3fÅÜB ë&¬áºDVµªN ²­ÈZ¿®š_ýÝûŒ«þ?Ež&×ìß÷/ÚæÊ]©âèpÐkÌ\Ý\1á.uUÏ{õ Ê}ë•b1uYR—‹xCÎIJqÕT Ž Ž€Z.*ŀU‚»PpDÅ%FÍà â®HŒ1Ç[8Ô1¹!†™¸Kg‚ЈjƒNUu¬ª“JuË ›.lŠ„µâ¾a«®«Ëÿê÷u\õ%ò4¹ñú[iæëŠÌ¿6¥n–r&wuíÆnŒÕ ¥Ü‹¡,êBošR®J×JÊm!«§œƒ¹‡R nŽ›GL‹¨‹EÅ«L…l^JPAÜÍU¤ˆÊT5–´˜SE­&¢š“Õ§‚VÉ‹µæÒ¹1¡ 1Nc »!ÄŸi37vÍ™†6]u;ˆn¹åɯþö½WýGžFþÞ_yþ¥ÿøÊÖÖÞvÞ̺.Éî¸éÏÇó¥\|±Šuµét:2·.ÍÆýœ›ÔKÎ¥N]’¶MêfžSvÀ#‚ ¦ u]å*†+µÏÀÜ 7EÜpïTc[×Õ¸ªÄ¬A§)ĪCÄŠ¹—bŽ16ó9"I5lWUÜ 1&U™›1ÑIPÙ™»3®b˜þâ¯ýEáªÿ$‘§Ñ‘^qf§]ÿÓѼy´”YÕ«ÊPGaÇÑJ ¥3+C³bÃ^,w‚´]ÓôJI¡mæ!u%gTB«A1­ëJBÐ7M©­c[îÔæÀwÚ´«4(h6hCˆÆÐ”b¥˜«ïÜÙ13 “XU;‚ÏDt£Lc¬ff>¯«0Û¯~`ÎUÿY„§Ù½÷ýÉÊé÷¼vwº{p2™„œÓp6K‹©³žjÑЕ’C›š¨.9à9ç¤%uê^,§Ìt: %uB˜EÜ{ªQê*ƒ´þ1`¨+¥ÕÆÝÚÒ¥RÌDC˜‹\4¨h’ sÕ8wè@æ9—hN[²•ÃŽ sQ™•bÈ*Úõü­oû£ÂUÿÙ„gÀÇîùã[.]|èÈx<Œg“~×´‹]²ž{HH%'I©«JΡªûó€[×Ìc:oæ3m›FçóI¯k[k«$j ±ª,„H dmÜ.DmÌJI]çmÓÖæ–ÔQEDL«z¢ZÍÍ,8ažÍhDI@+îVÜ‹"VÕ1ýä/¾§åsà›¾éȵGïù¯F ·^¸xåC»“í?|ç;·vøòáß;º¹y~i{g³îºfж)¦Î{HhÍ‘R²–Ò©¸ºjЈä\’t]«©3Ì$§VÌŠ¨h ªEU¨ªZcPB šE%ƒuf–Û¶•Ô5ÁÍÍÝQÕV5š9¹ª{SQ3¤¸› ¤œKéõjŸÍ_\øýô» Ï<ù®ï>ôå/xþßsËuw~ÕM7ßTýõ½Ÿ˜?ñØ_>ôÈé?ïæßûÀ¶.ò,'ìWÌ[+ýAE}8¬}{w.?þ3¿o|Ž}ë·õWn<¶ï ·Þúª·ÜyÛ]Gúõ"ŽZzäxóà#}ôOŸü‡?½ùë§O3ãYJxÝ{ÏïU›k:™Ž©+åõ_÷C-Ïao|ÓÞöí¹þ-¯xÙ ¿áŽ[îZJóB1Ã)wýƒþ6íòð£ŸÞüý?þЛû·.ü ppže"Ï —¾ò¿L\õYÿ䟼.ʱŸxÙ‹_ö-wßq§¤ÔQõZ#%à¨*f™~H“¨yxç%À06x–‰\õ¹ ½þÞï~ù _ùÍ/ºëN™Î¦€áâ8AƒÁ —OñÁÿåø]ÿöK<0½ØÏ³TäªgÜ÷ÿÀáï|É‹¾à;¾à®;Ãd6£”BB ‚½ºÏcOçwßýÁõ?x÷§O¯¯å `€ó,¹êõ?½õy¯ºùÚ½õ•_ðºCMÓ`f¸ÃlÖ1ZC$„Àïùpþwïýè•¿øðÅ‹ëkylë)oñž÷}¸yûo¼ÿÜ_|põÌdb-p¸¸x8ϳPàªgÔý÷gùè‰êÞO=zx}íb5™Ž5Æ$KK{t{w›w¾û½ïøõž~ô‘és:àðiàSÀÇó€ó,$üÿOøŒøFª……›®Û áæˆ VŠýÓ·^< OáßsþÃä{ÿÑ})ÉŠc ¢ŒFe÷çnc pþî¾xõ`ÀÑá°Þ|Kñ¶[Ž »®ØŸÿÅé­+«y LG€€ÇÇ€-þÓ o|Ó¡÷ï¯þ¯öà<Èïó>ìûûyžï÷û;÷·÷kØÅA€H‚‹&EËVe–e‹‰.ˉkM“ÈÎLÿH:m2m6$N“iœ±c×’b«²nS)ñ/HÜ×.Àbï{ç÷zžO‘3¤%RÔT+fú{½Tk›lT{îÉú™ [Ô´ä´¢œÓTÖ'¯Î,4ŽTÊñêç>·´ÀRüýÞ‹ùþ÷Q¿ñ®±_ÌîÙÓF½R?¸¾Ü{kWoЯh¿«i÷´‚Ô‚SKkµhùù‹ç/?›WúÅþG—/ñ£Ôb†‡‘ÿògXnxà¼$…$…ý;ÚFl¶=ÓÝv¶—zîÛ·w¨mlâÊ…ÿôÿ‹ HáUïx^½»w¶ä ö]{G÷ÞìüŽJ $Öb“˜È®\žž}æêõù'ÿëçžo®8l†€a È zzüÊÞ=mWÏœ^;±°œ.–·ðއðn¹¯VÛ²Óx‘rÎËoÝÚvÏЖM;}]¼/ô[Jâ¹4Ûø­Z+ŠŽ®6æ—&Óé™å¥å•©=qò}íkóS@Èðø9øä'1ƒ›GZ‹Ýï{ÛÁ-{²¹Ì­Åþ®Ö–€L¿.$a1×ÖV$—ÉFÚ(ÒŒÙFñÞöÒ…‡¯]¸ò‰…váÒÚÿsäHmžW¨ï=úiwîÌÅ?SjñÒ÷½ï_sÃñ—Nþ±³…öîάñ}{g±ØßQ*´ÐÖÖÒÕÕÞÇ©ß~qjêø¹b‘•ßøP{­µ­}SW—,eîõ3…’Ænêî<´kÇ-%ßÓ(ã!6EŒñ@ÒMs‹‹o?sñü'<ï…?ýË¿˜ûÏÀ ¼JäaïÔéZDªòŸ_üÎwÊ×××í,¨ÉÞÌn1¦sóopÏèÖÝ;Goéé³÷<óØñkÿæO®Ì`y¿üÙÛ6ßßÓ›{°¿wx¤µÔyWK¾-h„]ÅŽ-ƒÛt&ðHS!Ib¬”‚ç„Z5Â& ÝÃÞð–]}?ýØ—'ÂÇ€#@ÈOÉãgìßýñŽJµ|d {÷Ã}#]­[Œñ‡Æ&)©u„¶B¥R'IRœs(Iâ@AÆcxóþâ¶M»öu´žúWIúì½çÏ×þÇõu.nüüËŸÞµçÀ¿ßÔû€ZY©ÖZ[²}OÆ+j+)išG V,ˆ`ŒF¬EœàûAáÄÁ¥ã mÝî+o™š½f®_繉É­$¾­½£kSk¾?ÈJMâRDQÅ1ÎYÀqÓüê¹ÂÐæÁ~Ï;÷võ•Z:2.5A£ShÉRjÉ')õ0BÄ¡APOãRE*–ÄZD ¯s çœÝ¹°<ÎÍ%SÀÊ¿ˆîîË¿·¯sûÇG‡îÝ“Ï ì̽;‹™M£…ܦ¡Þ®MÙŽ¶ÖÀ×ÙÀ9G½ž0qíšûò#§¥\¶eà4°Âë|ìã-Ûo?¸ÿŸïÞqÛ¿<´ÿÎ6õl+:ë©Z-deyÏ×tt”hiÉÇ)qâðŒA­AƒKQ¢ð}Ÿlá¹c/Ègÿꉩ矟ŸŠc0œb~J†Ÿ‘ýl¹»½´÷F†>ØÛµY‡aO ^`°Îa< ð‰lŒÒ!(ß7(å“Úãþɞߺÿm÷ü/÷øÍ½£·E ÕJ•(IÈæ||Ïgóæ~ÖÊ+œ»8¯WW¥µµE·‹øžÁ÷<ÒÔ"ÎVšÖ–^8~L>÷…'¦^8²t- %Æ€q` ˆù)~þÏÿ0º½TÜõÇ»†o{ ³½‡4°Ö¢•B+ƒïù8,/}6ýú7¾»úÕG^X:{ñbcµ¼`Œç¼öÖ^U*åqÎa“”›ŒVˆRä2E ÅLËÂâUïìÙò°\¯¹Ò•++éÂâT®¯/hÚ¶ÝK%IR¬Ð£5Zi¬Më5b¢("“Èç²ÐÑÚÊì O¿p,Z[[–î®’ÉçJHêPœsˆ8œÁaŒ­¥ææ¯ÏœŸ®×Ý0W¯KëøåõÞL ïØ>XlokÊ%I, °Öa­C” —&®§O¾t-ŽåûÀi Î ýX÷¯:pÏ¿¹ûÐ}[ ªR®R®Ö0Æ£T*Ïåˆl•#ß>üì_?ºøÙ¿zúÚágO®ÎÏϘFc]·´ä¼ÖROgpNpÖ‘Ëf¿v^þò¯zò©ÙkQ$ p8œ®ÂOɰÁþ·ÿLÔøÃ½»}d°w‹Ž“k"(°Þ˜æ±ÇŸªüÅ矚|ò‰…kç.”—OZZ>öÒäòÜâ5[j J;wŒ¨õr ‡àg G[z»zTµ¾X:{þút¹ì.å$!½~=Lë•îᡎÖζ^%J+ KÆ4jÎ:üŒ&“ Èf7v=Ž9 œ’÷¿¿{ó÷ïù‡Þ}â©òj­!› ÈfJm%fæøÛGŸ\ÿ“?{zâ¹ç§WVlca!Y>sv~ùØKcå³/5¯Kó²½½*—-Fe¾úÈS+ó¥ aH œN'€Ó@Â0l°;íxß-;îú»Fn-†qD’$ˆFk‚ ƒ“„o÷{küŸ»­$©DÀ,p- eõúd=l„‹ÁèhwiSß&…8¢("à?år§Ï]®_Ÿl\ŽÔ—•¶v=|Ûþ=qÜ ÐZˆÂ›X ÅùBß÷ˆÂ”"Èæ9zâˆýóÏ?2ùÍG&&WW\mmÕ.Ÿ;¿´¶´:l,¶ ôoR‡Rk­5ÖZ´Öø~@’ˆ{ê™—–“ËÀ0Hµjë~6ܾkt ·³½KYkÑD‚#Œb¬‹9}þû«‡Ÿ™r޳À¹ßû½ŽÌÐÐÐÿzÛÞƒ)ø]JiG>-dQ@’•j™/?ò½õ/~éèÕ«W’U \NZËT¥âÜÄåjíøË3µó—.ÖÂhÍïîl N9þùg_ŸO+À9àp8 Dl ôÑ äöìÜþð¾={;ã$ÆÙ¥4ÆSÆ'<{ú©ðK_}inn6©ËÀE` ¸´Å1G-Ï=óü÷ß724Ò‘ZA¬u(¥PZpÖÑÙ6 /ÓlÎÇÅjņgÎO\\žïêêìSQbSÔ|. ›õˆãgQŠB¾À‰3Gíç¿ð½ÉÇ¿·pÝ9`8Ûhˆ~îù™¹[o9ýÎÝ»oétVpN°Î¡•Â9ÇMIšÐÕî›Íùþsçj%@ pÆZŠgÏ,>yáÒ…íÛ·í(:ÏC¬HŒs‚K!Èe(—“zš’ò*m¼{G¶ìúð¦Þjee•ÖŽ<Î i’b(íøæ£ß+ù+Ç®MN¦«Àp ¦€0ôÕjÒwìh¹ïÚÕFž}v¬e­Úññp˜N'€S@ÌòØ@Ûwøõ÷n¹ß÷óTk”Rø¾Ai…1†±+çÜ¿òìôñãµ9`8 Œ€k@ؾ¶f«/œºå¿yhýÎÖÖ<àc­Å J)âP†"Ð h Æ­¥tõJùūׯÝÞ×=˜ `­€™ÀPo$ˆs8 A&ǵéë|õ‘æÿÞÂuçˆÓÀE`H Y[ZŽ÷»Tu:ç£È(„\1§ÚÛ y­}çè¸T©$/_¼41óÐ/×F†8IhÔcDƒr ”!ŽRnX{öò·ìyxÿþmÕj m.uDaŠ6?Èðý“/»o<òòÜäd²,'€“ÀI`ðÐ ôà ɕÇfGn \Ƴ@ÌóØ ðÛ²¥­¿3н½+ CD@ NpJqaüzí¥ã+ @ ÎoÚ”9}à`!‘Rw·°ºšÎ¾øb½Mk»Z«Õ >Gn$ðr"Xg)ä2ˆÓ¾F7­óo/ÜÝѺý½…L åU2¾AœX²~'u^õzD#Þ€är,ã7ŒVáë6±ŠlÖãôÙ+ÑØ…j˜Æ€KÀYÀòª­[õhGgßVk5Iáp àe žç!VÈårLÏL¹z-v@þ®FÆ÷ÊÖZêµ8N(• ¤N0¢HbÂãéÞ¾¾ímÝT«e²¹ ÆóˆS‹µB Ž3g§³sq˜.cÀ omXåçÄcƒdsm›ºÚ7F!Æ(|_F–$JPJá)ŸB.ƒ¥<Ï(­5Æ\bh¸kSn2Æ '8üÀ¥ˆã”4M1Æ€gX]™–Jµfy#£¬f2*ò}Ÿ4H°6ÅC§8¾ç“$!'Ï]*/,¥à2p,¯QC[>4¼u[§“4žG¢,žñP(Œ18I9{áòúü|² ,ëü]Q.çU³¸Td}D XA´B”ÂñŠƒK»¶ tÝâû m4 P(’4Åz¸ÎÙ‹ãk•Š­“À%`‚_@š 2Ðïg EO!B£Q­Fˆ¾oÈä2žGàyhOcÅ¡” ΂ç) p Dáy¾Ÿ¡Ï“Ëæ(ò^kA)Ÿ™…rýÊD­ÌèïÇŠSá&…žñÈä²LÎÎÚ“§¦ÖD¨sÀ8°Ìë|äáâ}#;Fß½¹oc@ks´Æ‰Ãó4™L–“gθ^YwŽˆ€E@x§‹ŽL. Ÿñq´V(i’¢y…ö”îêÜì%Ö!ÆSˆm4ï³²RMÏŸ_\a˜&”_@àþƒÑn•úûЭ4I’ÇŽÞž¢@¡Ú¥+¤Î^࡜Ã¥Ε2q»…¥icÅ’ñ³ttøºPè"ŸS”+‹("bÞ€6 ­£@ùh­Aâ¿O]oT€E`Xâu>õ÷ömÝþ?Œ íÙZm„Äq "ØÔ"Ja´ ©yùô¹Êùóë À°8~˜m ŸH¢%' YR+d2š›úz2Òâ¾ñPHJkКJ=¢\N-0Ì+ü‚òØWç– ½«;·Æ‘" #|ßǺˆZQÌåH­âøÉíáçÏ­j_k¬8´g°Ö!P gˆÂ²œ,.TË×§Â(‰SnÊž)¶vt f;Ú ³gÏèûöŽÔÕZ ? "àÅ–'NŸ–¯|íÈü©sµy`˜æÇ Ú@ÅĉqxÆ'Èøø¾!´áß7hOs„QD;Ò4%› (är€ŠÀ ü‚òØ" =Eˆ(!ÈúDQ‚R ¡§3ïwvøÞúZ48ÞZ,U^e- (öôú¥w>4ÔyqlÖ?v´by¥@iHâ”r¹ŠKÏ7¾A‰fa¾&/­•EX急¢ý¶m[sdx佃½Û÷ ôn!Š#D­Áó4ÆxøYLÎpø…'Ò/õÅÅ'ž˜ºZ­º0 LWá‡ø0Tܱ»ö…\ö±u6ˆÇFP §bÄ9¢$!ÅM"Š8 éîÞlÝÜe&&¦Ÿ&Ç[k @ðn íýïéºï]¿zû¯å‹-Z þ7=» ˜*Ü qœÒˆrÙ,AÖÇ3Š›”Òh­ÑÚùííFî¾»¸ûv¿½£ÔõÀ¦‘ÝÛ·îÐkë¢0 Qœ "¸ÔQÈgX«¬qü™á_~ቫ§^ª.E 0Œ“@7 (Ak Nãy†0LHãŽöv ¹@iük—£¶r-"—Ó´¶Èä|”€sàC.›Ã(ÅFøèG»ïÙ¿ç§öï:ô÷.^X]þô?~z˜®1?% ©'¨õu'Ñ (,`CkÈj5$ã+vŒºž?¢Û£È].ó“q¼êᇙëéÛü±Cûîù‡÷Üu_ÿãÏ<3û·Ž4ð·@…D µ#KK!‡Ã')Iê'(eikÏêßúÍÝ›z;ºÛ¶ í( t–‚L–(JhÔë¤i„Â#NRõ˜R1C±Pàêô%þ懟:|eîÊD¸ ÄÀ5àp˜àÇÊ<@DðM£S.Wq©BÇÔlت”¦»«D-l$ë,b@[kÖlÞ–/MN5´s(þ?øô§ êáà¯Þº{÷û­wÝ·¹¿—ÿüä‹•ãÇWx ˜b~Jàó_[˜ßsç–±$‘=¹¬àp‰Ãó<Œ1‹Y2^›Ú2ÜÞÖry`>¢¸¤ü„þðŸnÚÖÛÝÿû[G?qçÁ{{fæ¦Ü#ßyqùúd4Lò:IÅ Nâ„›¬³( µØÅßõá– Z´öImD'–Ä ZŒgÈz­ ~Æä=׿ÒÃÏ^X»2!Ë@8 ŒcÀI Á›n~À9‡Ñãi’8Á9 Šl6Ôêúu”?Šm8À!Îa­Å:Mog¯Ú¿o¨ãØÑ•LJ'0?¡÷½¿7_«ûx÷¡·ýw÷ܱ¿·­ÔÇñ3ÏGßüö©¤^—]Ày6ˆÇYšO"œ"ð}Â8&<´çáœC)EÇl,¼½ëŽï<:ÿ$RÞÂ}¦¯³’-üöîÑÑmî½ëÖ]J9ÅÉsçêÏ=;Õ¡ ”y{ïÙC¾¨Hâ„Ô%ܤ4­QJ‘X‹Ñ†$µàR”í)tjPZò ±©ÅxŠJ9$—ɳo÷!ï«ô}õëÇÏœ®¾Çr 8 \~ ñ@Dpâp8`”BðŒÆËx(4‹‹éìÕÉÅÙ»ïdZ+ŒÑ(¥¸I÷í(=uøì¡3§/”·¦>ú±ÎC£#C¿?ºuä·î8pW.I-Ž˜—Ž¥ÓÓaXl!sK³—ç–'í`Ïv“X‹o ÊYœs€"IböíÞ§x`btl|õÀåËñ%à,oâÿéPVˆoSƒ¿{`ËÞس/«´&‰"*õ*/½t©^­JLÓ@™W ŽBA)npâ0Æ Î‚R(m¨GKÔk)Û6E)Ö&¤Î‘$”€3 '‚(­0½V>òþ_oÙÔßwèÛ=3ýÔÓÓ_YXpW€”·ó Fy(¥À‚”Rä²Y?Pø>T*®~áòµ‰rev[´)q)Ö:”†Ô9\šphÿmÁ;º´ÿÚµ“;*e{ ¸Æ›S¿û»]#Ý=ÝïÙý##{övw R+Wðý€kSWåñ§/,¬­¥ëÀ0Dlј¸\þÌùñÕ¾®á.O”Q(mðŒ&M…(Šˆ£,÷Ýu°Ó þþóÇN˜°á>ÿ­o­]àuþÙ?ì÷½»½Ð÷áîîmïÚºµ¯·k³ ¬)[¸zu<}þÅ+ †[&€k@™W­\©ôÉ–dP{ °b@0(&ƧäO?ÿÕ{ïº=¸çÎýÅ­›·Aj,žÖh­ÐZã¢(&I-Õre4žñxð—î÷K-™ö÷í|æ¹ËùÒKá_ ?Fk)ƒÑci N@‰`´¬oÈd4å²³ίž>}fòþ·ÝÙí5ê Ö:”RØ8¥´‹¼ãí·mIâèwŸzfÌO“øÿ>ž2?äw>Õ¹§ëøðžÝ;ß»cëŽ}C[wxN„¸QljCk8þò¹ÆÅ±µ%jÀù|PøžR!I#’4±Ôê ù|@603;ÅË''×¢ˆ0Ìu^Gë\¦Tܤ´qàR‡s ÏDðL@>ãËõÉèâÂÂbþì¹ÕÍÇŽw?ôà¾Î»î¸­¸y`+i’°²º‚2š®îVœuT«uÊk5´°žÐÖÚ­Þ÷îwtwuüO=/zêð¿\ZJÆáu>òpog.ÛuGK¡ œ€œ­!MHioíÊöô¶t\¹²ÌÚšŒ=ñÔ¹çFG·þÊÛÌùÎ!âÐÜ Ö¦$‰£­Ô©ÞýkÛÚïºcß»–æï½r}¶‚Z™Ë½=ùLÛÖÛoÛ¥²~JµÊÊJ™L& ›õhÔBÚJ%¦æ'݉ӳëÖ²\.e6ˆaãØ™™ÈOÝâ@w¿7°e`›—¦°^.sSGG (­ˆã”ZµF­¢å{ž2Æ(ß3ªZp.EÄ‚¬u4j ÙœO6—çùã/†_ûÚ™ëÕª›N/+¼ÎÛïnÙ>´uä· ùbP­Õp©CihÄ •jEž|îÄÂü\ôp¹Vsk—/Wë§Î\MËå%ËI¶«£Wת1­müÀC)4 a#&ŽSl’à{yöíÞ“ëèvµ¶Å·¢jnz*¹X^50@ûÁ}~hëp—s)b-‚€¥žgP<ñÔ‰åk“å3À¹¥¥T×ÃåáRÉëÙ¶][g £ëq‚gS/«û7åF‡v´nØ>ØÕ>ØVÌ·¨|1G’$ „$q41q˜"VÈçröØêwQuÈÃnÏ®‡²ibèì(¡”&ŠbRkÉf<²9ƒÂó5µjL¥RÅ÷=â8Å9npˆ(D£5ZyTª«œ;=Q^ZJëÀp ˜ã‡ ð|ÃÚr…lÁ'—óq"xÊ ”¦¿¿¤wŽ”ZO\G„ÇmÀöù9;õÅ/ºpiz×»~e²ÿöÛv¶Þ®jÕF„8Gk[¥ÀhˆP.×ÃÛöy¿õÁ-[.n>}û_ÿÕô¿Ù½»eï@ë€s)Ö:У@¡IR‹³߃®.Uzß9ÆŸ{vùkÈ9Ïø;¼ï6xqcÓ”4u$©Ek…ˆC‡!.uT*u*ÕîÞ´hçpVÑV*¢Ú Æ(|?`}}…ïŸ_¯V]˜æ€2Ècã0 Œ=öèê·£ð»ú-lÛ³k{Ëöo3a=A+KÆóðƒR”#I™œ&“Í… ÅbŽ ðÐZ#ÕjH.Íd¹:3™;1¹¦RæY æ‡lë/ÑÑQ s´¶fÑhRëÐZ£µ¢%»™îÎá¼1×ý4ÅÏ×ÍaÈÈѣ共±§wÞsÏÙMxïúà]·í÷óÙ<ÖZP@êÎAkk‰8L¸i÷ÎQì¿uk·ùàôTãÄáÃ+GóùüÀŽÎö­yƒŸÑn‡Òß9´Vt;Õ­ûFZ¿óètk½î ÀX»îǾ»²úÕtaijÓ]wÜQÚ<°MyD46ME*q–z˜FŽîîJ­ŠÕ•9»¼œH§h-Dé:©]ÀÓ†©ëåôÄË×—Ò”5`˜Ècc-gïé§×8yòÙ;<³íÖÝçZr9ž^ÏïjoiÉg»ÑÊ£­¸ógÊKK± 2míù|NnpBì1¥™]XK'&U`˜x‹åDg/UðáÕ£jua!IÖ׊EC[{@oo[±Z[±@7МVI`XY]uKßúÖÂÎñË_«¾ã—OwÝvà–öþžn•Éyˆ@šZ4 "ÔCGÇLMOF—'Vk/_^:|xe°\½ã`KàKLÏ.Ååõ”(µ(¥0D­­íy2•f³¦P¯»^à4pÉZò'OTÓé©Ãwí½ålïí··í¹¥¯Ø–ïÅ96šz´ÊÔôõêÕ«•¸V±dòÂh•Åù•òô|T‹ê‚uŽÔ)p)Fy8ëÜäLT€y` ¦Øx Øö#JÑ¥5žç¡û»²9´â&áúlXÇhÍ[²–x8 <¤üÁAú[‹¥R®Ä¿´¸Ú4ÅY Æð­m^V+ÅÒRrøð$àxEFMÀ¨ç©[º»ƒ¶ÖVC.ã!Z¸I©UTÊ1Q$4Â$]_s‘,_¾ñ©ßxÈiÿ3/^éX^K’4u(^¡åi²Yƒ¹8V» ü ð·@ ìnv(Å®À£¯½ÓÏ)¥ÑZEšB¹œ„aè,¯#‚) ¼±8< R6ÇÆ`œWÔ€ë" [K§µ¨«Óa诰À"`­å'sÀ å LO“LSžX"kù•å”:€˜i`;°ž¦²:;mž¥Ðüx5` XªÜð_¾0s8 ¼ˆáÍ%¼&N`Q„å(aËÜ\Ò tò£V€¯` Xâ¥À 0 ¤l0Ÿq`Øœ4ºv^#À2°¤üdB`…7'À ð¯XP@ÐÊ+ü(*À)`¸lÚyk°¬ @ƒW¬/‹@…7'À:¯±Àe`˜ú^ Ä* @ƒ×8` XáY`…ŸÅÏžâ5(ñÆÖá''¼9 ´ñw•Ë+Zx~<(ñ“‹¯  Àòæ°ÆR€´ðæª@Â~ÎM?/Š×MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMÿ¿ðÿI7>Ú®6èIEND®B`‚eric-6.0.8/eric/icons/default/gotoBrace.png0000644000175000017500000000220312342633755017626 0ustar piotrpiotr‰PNG  IHDRójœ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ)))>>>BBBfffrrr"""///)))KKK///BBBƒƒƒˆˆˆ>>>///T½ƒƒƒT½NNN"""KKK‚†‹T½T½ZZZKKKT½KKKT½555~~~555~~~///)))ˆˆˆ)))%AT½T½tuvT½///BBBT½)))"""BBB555>>>ƒƒƒT½>>>rrrT½fffƒƒƒNNNZZZ>>>YYYT½T½///T½T½T½BBBT½fffT½rrrKKKYYYƒƒƒI¢ƒƒƒ~~~>>>uuu555T½T½555T½T½Uº555///ƒƒƒT½T½))))))///ggguuuM¬9~>>>"""T½KKKT½///<„T½NNN~~~T½T½>>>rrr~~~T¼)))T´"""#X¬(Q“)))///5559W†>>>BBBBWyDLZKKKNNNUY_VcyYYYZZZfffgggrrruuu~~~B¼9^—tRNS !"$$%+-/134456;=@@@ABBCDFGIILMNNOPRW^`eopttvxyz}‡‡‡Œ’“”œŸ ¢£££¤¤¨¨©¬¬²´·¸¹»ÇÊÊËÎÎÎÑÒÕÕ×ÙÝÝÝÝÞáâäééëìîîðôöùúûûûýýÊâNIDATÓc`Ä ˆæ‹j,ÄfI_µv}0†°ß2 p.º0W+H¸ &¬”f¢„3!¬¡«×¬ëfpKˆ]4wÉÚõ>áÄå@á –úí*•‹–Î\Ù$6] ž¢XæËÙµhÙÂ9`w3—€…óì'H0ˆzw¬˜jv_žl_$-ÏÀ Qæ® 0Ö&%·™300$Õ‚U[…SØ{³fÌžŸ¯ËÝ Ͼ06FÆÞ ð$m†°/#£,H²¦(ÎÀZÃÈ Õ3«ÎK¬'®yÆì†â8F†é³æ-p ÛL´öàg`™hÃÈP ®`…„}i Ð ¥ Œ 9ÓgM3€F‰N§:ƒz§PX<2ÛS Ž Ž @aF!9e5-C;'W'[c=MU%1&Ø©i„_öVäIEND®B`‚eric-6.0.8/eric/icons/default/eric.png0000644000175000017500000014376412342633754016664 0ustar piotrpiotr‰PNG  IHDRáá>³ÒzsRGB®Îé pHYs.#.#x¥?vÇ™IDATìÁ ´žçAØùÿó¼ë·ß}¿ÚeÙ–d9R¼ÄvœÝN‚¡¤!%ì=f 3PÚž¶d:…&¥t! Iœ`²ÇŽã8¶c;±,Ë’µëj¿÷ê®ßw¿õ]Ÿeœ¶§gæ ô”Ñ|¿}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ßC¬µÂZ+ø$èëû.±Ö þ+!,ß}}ßÖZÁ ø¿BþÖn¸s/+ðd¹8`Ls²Ñ¸\3R;F“b8ÜÜÿÚw¼Àg}}ßÖZ ¸€!DÊ«^9þø;übH»¹0Ù¢v§³2*»¡¶1PæU™íMœ?wdßFw)Dæy1¨%*“Q©PiTkC§FG7ÛºcßÉýû¿ÿiþ–ôõý5ºtöðë£îêèÕÅ‹ÅFcmg¯ÛmEÝ) Ä«z6ªú•€,M‹ín%‰“‚ã8¤¹)P¼ª¨•'œÄuÂØ-9:Ëm7N¬«}°~*ªTWJ¥ÚáJuxa× Žß°ûŽ3Ó“7¾Äß2‚¾¾¿‚ãg½åâ©mV}xyáÒ@ÒÞ¸AYgùxš5ý\'(mŠeßi´{×)5£,Æ zI†ë¹…,W®'1Öà‡ÃãP­: ŠzxÂ’$u/2”ÎÉS‡,(%p¿S¬–¯V+åhªºéK·îÿ‘§·]wÏSü-!èëûKœ>{hß©¹Ãû–ço©7Ö·¶{ e$ci’‹8Í&-º¬5kBmth”¢TìQ(J”¶ÄQF/Õä¹"S‚B©€5!%Žëà¸k3ÀฒrEQ®mP LRp«”X\>Nm0¡<ÜÂ+føI’Z«†(qp!]’!ŠéÈ·œ`èÅÛïúàŸß´ÿû¾Æ5NÐ×÷:øø­K‹çg¯,_ZÚXÝœdñuy–GirK’f™Ñ¦ ±hký\t®ŽÄñ< rƒp S3 ¨¯wX_na]Am°Œp}¤#)–Ë´›=\Wà’,êâ8–ÑÀÏqÜ%¯„KŒ2\áåCGqÝŒ{}FG¹„8ÉÙhh¢²âÈâlx¤ë–¨§6Šaé[·¿îž?ú¡¿÷›q ô}O:yüÛÛ——/ì9wáÌŽ³gOnNš B¿¬”ÙÜŠU-2ZëP+«A8W‚#øË« ס4P" ÂJ é94Ö×X]Y!Kc&·L`È©”‰; ½vDè{ÄqDÁWx¡Eš&^¥r†ƒC`|ŒìQ(GLŒ 8öŒ¥¾èóú×¼›àzŽŸCéŒá)ëlÐh­±¾±LT_ µºNÊ…0)ûáã7ì½å·îWxŠk” ï{ÂÁç}͹3GgçÏÏ.®.¿Þ œqmÙšçfÔH‘p”±~šç²>ˆ€ïp‰ë¹x…€ X }dàây>¾ïã>##C‡ªÄQ̹Ós¬5Ú”‡P:¢P.Ñj­}*å2+‹KTBN§ƒï´ ‹P(¶ K“Êžë*BK)t6S0“¤­1ò¸F®cÂЯŅ+s¬×ø¡fzD0^\<ßæü¥6ë+iâ ÷ŸúÐ?{ÿ‡þ÷'¸ úþ»tèÙǶž>}ìu§O¾róF«y··#¸¢èÞpt£”ê`•ÉMÓ4[Z­×÷(95JîaâßÃ/)‚RÀÔÌ$›¶ÍRЏx¨<Å8†ögÎ_Â:€”%æ¯gËö­¤é¯¼|ˆ€œ(NÈâ©©¬“›Öœ§P2åi'£HŽÄçÜ©×V¸íÀ^†‡&8}´ÎÊòXC–×ɳkr´ÎP©&Ž4&Rèu ½®¡ÝÔ4›yrÛM[¿øŸúåÿ妻~ô ×—¾¿õ®\¹Pµj‘ªç0&]zËòü:x!Úí t†ÎÀs% q‹Í3lžS. <ëÒL5‰†L´W )(:-=0wnþÀÚ¹'€ ®!.}׬sNï:wæðÍô¿q÷¹ ÷ØQª¹SÓ7L0½ešÝ·ÜÁöéë¸ÜXf­¾N¹8„ —LÄ¥KWHº×A¨›$“c£œj±ÈÍ¥½,ͯ5zÌ l&KI–Ô H¬§0äH YÚ£7‰;]´éš<ê‚¶àÒܸÌwl¹m’’w•åS‹|ù”¡RuÙèJc^ÿæýìºawó(G·inD„eK¹PB“ mŠŽ’Nˆï)J¦m6a” ÍÈÐßÓxhtšb´Å‹-CÖ%s-‘gp°òL¡5„¾,·ÛÑžf}m+pŒkˆKß5çܹ#›O;ùÞ~ò·?pùÂ¥áÁÚðôôö=”‹U玻ïàŽ[ÞB˜[=Oqp}ù9õ2ãSSˆ’‡ã‡¬' *)$å¢Ä'Æ!c¨R v0ÁZêm©Y`·P$’aÁà› bZôÒ)qÚ¢³Ö¦×h¡»†’,0P Ù´yIÌù¹S4º«´óŒ­F$ZR_0\jF\^Ñ!Øþ?íbç›8ýí5ôpHQ8¸n‚NK±$)KIÒŒp|A×\¹šÓÊ<Ï+pr‹Š ™Vø¾¥ŒÓMƒ‡ $ –V¢‰1’BÁAif/îàãÒwÍ8{úðìùó‡ïúô§ÿå÷Ÿ¸\·_ F·ïåÖ¯£ZšåêâáÀ>ï±Æ*K W9~öK<ñå/rûn#3k¤©![)U0=¬Ô¤i—Š—Pp3RYD»C<Þda)¢6»…¹ü …ÊfLa”1:TiSÏsµqŽi’‘¢#ƒt%år…aŠÌ•IsΞy™|õ2Z­Ñ¼t™úêU,òˆg]ºF“ËÀì -Yâjqžö$È|tžágß•„l’¡¥¢T+²Þ5t” Å"QW¡b›h J ‚Ô`Эð\Cn5n"(j° Ò"}‰Ú]C'ÒA·—lâãÒ÷7îìÉÃ;ÏŸ?zÏç?÷‘{NϹ)·lÙuã>ö¼öVN¹ÌŸ?øg\½Ú¦Û¨U‡ñŠ%F7181Æç?ù¦oØÉknÚÇÃý,S{·bQÄÅe)"€ÀÉp| ÀG7 ¾Ëʹu’Ȳý†ygúÅpè{T«¦E£Ñ!A“K£$E¿¡$§GËwi¬_e9Ž©Ç—.’^…Ðz´Ò¡%k©ezz˜ KMÖ—ºì¨S-—Ñ¥QÌQÝ\õ$"pÈ"ÐÆA Ÿ<¡ &Ép´ÁÁx'Õ¤iŽQ‰ÁK¢x•DJÖ€åß“€ç ´24Ûí.×—¾¿1W.œ-{驟ÿô¿þ™…•«÷F™r‚"·ß¾ûßû#|ôÿüþío}‚¡¡aîÿþ÷Ñê8tÚ‹\º¼Á·Ÿy„B¥B§±Æì;ß« •b‘ÀJ„cIí26OHrEªsth1E2‡4)aÈp ø¤ô´—ºˆB‹v¸€?°Ž[€ª‹J¢¶ÅD ™‡™+‰’:ñzÄøè,ë-Xo40i0(áâ·Ýº›¹/¿@¯k œ"åb‰^!† BŤÄ8’LYâ B/ T.’&)Aà¢sƒJI'G(EI@ѱ8€Î íD“)Cn,CžKTfÁ 'ÁÚÒF£UããÒ÷7â‰G>yË#ú‘ן™›{[3JîvB¿88>ʽï~µ‘aþÉ/ý ¾ðàã ŽòÉO}†z]±uçnØZ`±÷Þù.;Š_*rø+_ç 5·¿óN8¸8jCŠÉbLw3œŠO` ¤Ýœ³I—úRÂÊ•&aé÷àS<ûÄAV——¨”‹üîGþ-kküú‡ÿ€ŸûùH”Ü‚Âÿüá?æW~öûH²:ë K|âŸþ/>„Ï@*=F0ù kíËž¦XasÖ®ôHºŠ¸–±k×õlšŒxñ¹#´æW¸ÿý¯gvwFKQoh´rð|Ÿ¡±Q&Ç ôZë$QGµ ܘÃO£yµ…sGFœÔ)Uòþ‰Ÿ¤ÝŠpƒ!†G7ãzeþ×ßúüª³Äã?H¡Tà+>ÆÕòüÑ?akÉ¥Uë°zuƒÜ¤Äq¤ÏÄÎílžÙÃÜ™ˆKgæåþû†ë¦öñÑßý=>ñÜã”|IÉ7”™£0ÜPR Ùºe‚›nÞÉ›î8Àü¹5>óÀW¹ðÒyöß<Éô­“¼¼cMÀƒ*þÀ;®ß…‰4g®œ#i5p\Ÿò”,ÎðEµèÒÓ’…Å6:W¸„²ˆTC®¹Æ×à8ã 2c‘Â!Ë]’âÌ"-ø2eŽÅu%dš,Õ nÞ¼mžkŒKßwÍ¡gÝrè…¯þè³Ï<þv_gü"ŽïÐÓ–8ÊÈlN–[îýïç o»—Oþþøß~‘<ËY[[gǾ븸8ÏO~ðýÌ]a÷kîá®·þ8;®ÛÉ7€ßúÍo302ÂèÔ4¥0ã̱³<ôУ,¬]fbÿ‹KKŒnbhr¿\À tâ:ÇNÇXM;Ôˆ¸rq ª7!I¨8í•+|”Ÿ’Ç9I’XEA@[l Qy¹rI£k)C•2­ž&NZ´“ƒ%ø$‘Š+'g¶Þ´h­¯²\#\ú¾+øÃ_;ðäßüÇõfý-ÝLÕDè"}e ÍÈì8Öñ ü…J•¯}õI._¼DÔ‹ÑÚ0<>ÊÏ|èïóƒ?ü÷yéùgøà/~˜·¿ûçxâ‘oóŇž£Û¼ÂÒây6V“§1rУ:P&‰"^xæ$¥3—¹óoezÛÖÑx5$IŒ°¿pãkÆé6WùÜ?N·¸çGǸù@ |ÂúJü¢Ï¥…˜?yð ×ïå=oßK#Y^hFk£Ü°õ6nØz'/½po½t˜?ûÄ×Y_orß»ßÃï}#_}ðÚID˜5±I‚ŽºxyN«—âZÆ r ‘&C!]CÁ—D ¤±"Ë¤Š’#ˆR‹ï9ä©D:CŸËË)GÎ-3T.qÃæ2B84z)('×0Ps‰3Ó˜œš>}ÝMooZk×—¾¿V¯yöúǾøñûžûÖS÷»^ðz%]‘†.Zº(-H•bhv üñŸàùC/ñâ·2Ùê2;;ÃúòYÔ¡T-±õúM¼ïƒ?³_ÿcc„a‰ýî?§±Ö£Q_¦U¿H·½ŽÊ[8®Äs}„#x¡dr{·½ÿfâ¨K;ŠHò„r­J}-æ.¯½ãNÎ<ij+yÇ{÷qÇ›†‰zK,¤M¨ÄøT ìM@¥Ë‰«9Ÿqž EYD¶^dÜlbª´…ÙÛ®£;Oþ:7îšá]÷¿“òØ{vn¡žµ9òµo‚1 •Zä¹¢ÕìaRC´‘Ò¶†R¢qË=z¸Öh t.°¹C76dZÒI,Sãø¾ÇS/®süR—L7R–Ú’ñ!‡ñaŸRÕÇXK7…(LnÚÕ²öy0\C\úþÚ|îSÿêýŸûÄ¿ú;Qܽ¯Z+‹v”ÑŽsÂr‘b©„[.á ÜxËmø¥*çÎ_dñÊ»R•±²°‚t$år‘áO}ù$;n¾™G¿ðy†Ffh¬6X_ÇÚk~¥ Q342Hõ@„§¨ú¸¡$2i¯K²–Qª ³ç®›9~ð_ûä“Tk!ïþЙšÉ˜¿¼ŠhŒ«K.`Px¤¹d#Jè(KiªH+kC)Á¨„¼³L»ghZ*gç®iîû;HÜ”ùó§¹c÷Î,ŸçïþÝ·qâØ1L+åü•6[·T¸r±…6ë[¯óéµÒXQq%%Gà 0®¤×ÓDÊ2<28Xàk/48r±‹µ†Àø®$Ê ‹ M;QŒ ¸ ”]º‘Âó&fnL¸¹ôýµøw¿óæ¹§žøÉbX|­'YXi’ù‚ñQ¼r§XÁx!å‰ ª[öòÐWŸaa©Å;?ø#ÜuÇ>üó¿Bsm…Í[‡)øWÏ_ÀX…çKŽ<ý ¦•õ…c8ŽC7)•*$i&'Kx•¥\+ÑXkѼ챵ôÔ`?:ƾ!¾ë3;´™?ùìC<óðó¸ew¿cCÓ=âäÝh‘ˆ…Ð#7…R•H×hçe¢<`þB›¹SMö½Sqc¼!E»·NÏQ_?Œg ”BÅÚBƒvtŽ‹sK,´¯’gšýCK î`cÂ!—ñé*FZòŠåB¶Î•Ë)«‹)=×à:/p‰»›Y\Ï%<ªc!õNÆGþì"õ–Bk‹ïÀè Ë®©¹kXoǬmätÒŒJGÑîhìŸYyÇû~ù›Öþ’Ã5Æ¡ï¿ÊÙ“‡_³i\ÿôúÒü‡*ÕÚÍykëMr¦wÎ2»c+CãñŠe’Ì2¿°Äá§ŸåÂñÓ¼å=ïä#ÿô_òÜŸ¢P ‰Ñš-×m¥E4×»x~€Õg½n ,ìÞs3IÑéÔ€tÀhƒà¸ili¶ƦÇçÌÑÓ<ûØAþÝoþßüò·¸ùŽ}üÌ/¼‹ñÑË+çˆó:•ᯒâ;•R IãE1ÁÒå„ssKÈÀc|÷ ‹+‹$2Fû)I#&‰RâfŒ/ÚRΞXB‡%º½œúz-4õ¹WXXh°qu×w8u¶Aid*°‰fc)e¹•£=ðA k,™†$74bÍåå˜\k¦Æ}^¿Œ±A¢ÃÌx‰BQ2<R.J*%—bà%Š™©±ôè™Õ?r^õ«¿ú«\+\úþÊ>ÿؽ?ø{ï×YòÏ)o>7·Â•ÅU´²ˆšÏRž°+Ùw×.Ú\=u…v»Ëè¦íø~…Kñ ÷~“%„eÏ5Dí6Ó“5ç.1fG8øŽ ÓlvÛHò´ÇÙ/¢”"ô=Ò4C)K' †Æéõb¾ðÑ?äÏ?ý Ç]ŠÁèxÅÜ~÷$?öc7!õ‹We*µÆëàú¾±ø©OHf ×(Ê…UÒõÍ +T£=”ºÃø®ÅQ¢.žÉ)š„PÕIzšFŽŸç¬¶[¤&E5ÖØ[ÓÄ݈²Öh4‹)e×G¯jÜŸŽJ±8Ê*pFÒŽ5®By‚ò€ÇÔ¶¥ŠG r‚¢!ï(¤ÛÅ+tcCΫ\¨•BÂÀ%ðÜÆòüÜìÄìγ\c\úþJø“ïzþñ?ùýÚ“ç®z‡^9G«c d™"Ö |â(ïx’7¿ÿ}Œo¿ŽQÚ­”N’ð û}vïÛIã ¾ø±OrêÅWHµbU€(\ânŒÊs\Ç YžòþãŸù“ýÒ©Å•ëK›†xëÛîcóõ×ã–Ët•Kyhb3-cXY>KÑ1ŒOLRugسm„ýoº“õ«<úÅÏsäù—¸å­{ñ𠓨Xcs°Z sM»]çÆ×Ž’e9ÍFÄj´Šø EÒ4C °€ ¥"ÂS$I‚R „`ÇÍãÈ¢Ãʲ¤XDK R ,ë:+­UüŠ $+4b ¾Á.ÆÄ•å® ×וLo­påB—KÇÛl¹M⦲‘ƒëKòNÅ37Nò̳ghµ"JCo5f`¸Èð`ÙKhwb†+6ê¾px™ŽÂ­9”öîO|î£?«Š3ÃÛ§ ¶N"ÆGÑ~e@P@Š8Aˆ+óèÇÿÇáý[÷ “;¦8BÕ (WÇPF’g’ÁÁ)cùìh‹­ ×Õ R¸£‘ŽÄ÷Câ(!M qOcŒaÏmìÜ3΋ÏgfÇ7îŸBA±XEusÎ8Åâ™5§‚×àÉ zh FiŒÏsÈ}KÜÖäÝBy¨L04^åÀ]3<ùÐIŽ=޻߲›r5ÄÁ¡½ÚÄ’áB‘Õ« Žž[aþ|“‘Ñ·Ý»—™™A¯6K¡PèõèOYYZ'Ï …ªO8çŠ^”ø’<¬Áwiªp#Z[Œ28®ƒÕe)® Ž‚W lè»k““3g¹F¹ôý¿<þøçn{ø+ÿGã;vìÛ¶×-Rt%¥ê8d!ÕòAa#}ÂhÇ¥i Q1Í^›¶IH $çW™ûòs¬ž:Go}ƒ¸Ùk( H!I’”zcÐ-â¤yãæìºgÂ–ή¥×õ0Ê#î¹ %Va­A8iªÉ3ÃÞÛ¶ó»|€c¯œæ±G.rø™+\8±Ààp¤ëcÀA²tE …bNÖT$xE^•áHƒF“gš(ÉQ‰ÁÁ ]AInÓ6æO­2jÅé«ì¼~k0®ôÈ–2N¿p…çV(pニ©MÃÔMD¯ 8š«køhf®+³t¡ÎêJ‘E¤¢ˆïKòL#„A ‹#!O5‹‚‚/È•%Ï-¹2hmq]k4X‹ëJ¬‘¨ÌØ¡¡ ;oxÍY®Q.}ÿÏ|ìöÏ<ðÛÿ|jÛè [¶ÓÓ·\BH[,“*GJäyŽô<ò4E¦†æÅ9N¼ð,—^9Æúù l,-â#Õ££#¼ýíoæ¦}7166Æ3ß|†¯<ú(^rXÅs<²X 8[ï½ïnÉóOaþüŽ…4N0Ú‚£°F#Ëwì»k†_ÿ7ïã™§Ÿæâ¹F& ”%ÝvDÜMh­§ìÞ?ÍOüìøù¿÷§,^¬sõd…Ýo¨¢3CÖЄRD]²,!ô IbЙAFÈ3L¬©J¼ñÞëxxõ/<}«r¶m¡Xô™;~•#O.°ºá„’;_·ƒ©­#\¼²F“…’G}£Iž*Dœà Áè¨O¥µ˜V½‡ë;”Ë.ž'H»ŠLi\RJ„…ZÉ£ÕÑD±Få–0ðð=‰ë£*GbÓÔÌKå¯î¼áMëBÃ5È¥ï?9tø‰[¾ôØ'þÑà–á·oßDÂS¨ÐÍn±„ö}dµÊ†/!qð 5ÄkuÎ>û /}å.¾r”¸Ó¡P)269Ìo{=?ô÷ƒÑLŒR.–QÜ3z'/Îqè‡x÷ÞbzºÊ±WVÁ3¨^&¨„$QÊz3ædžÈUÄÁÓs|à§÷ñøŸ]âÒ‰eŽ<íqÓëJdyNž*´“àû )ÐP­-5†ÎzÄÖ̓ìÛ7ÆáÃK¼ôÂ2Ý(G Ù<]Á’FšpöâcÅ!’4C„–õ¥6~`H¬ÅÏ ˆcETð 2d‰¦*F|¬#0©AJW",X ®#p\‰t63!B 2K/ÑùÔxíÈíwßw’ßx’k•Kß¿÷äóûõ/?õµž™rR×§Þ‹irZQƒÒÐ:ËÑÝ&îÏH¥Æê‘c<ùàƒœúöó¤Í#8°gïyç›Ù»}–êæ’Á„æÆËÿðkÿo?ÿ"O=ü%^ùêQ¦6׋.Õ¡aªƒCÄÝ5ºíáÚíºlp¤%Nr”ÒŒN→ Ç»l¿a–,Ñôz."¸¡‹2>ž—ÓΛønß8yz‘÷ÿÔõ<ûÕy.nðÒÓKì¾mWAÁ­,Rƒ–‹B \‹› $­ íŒæjrA+Š%‡í»'Øyãž”h£–ë-.žkqüðãÓ.ÂZ0ºŒ&` =,d™!0ßi-I¤(.¾”XÐ ²Ô"… ô çe ž…Àu¨–ç©ý¯½ëi>}Š¿ŒµV°ü pù÷èCÿúM‰Úø±§ž9|ý-ï}#­F›à•PPÎ4­cg8ùâW8ø$ÍåuJ…"÷ß÷ý¼á­odpS‰‰#4Lƒƒ½92'¡X‹©È7PH@ÿ{p¤é}vþû;žçyï·Ïéé¹GsH3ÖeY—eù@2.,°9Ìal ¸86%8°ìf‹b³BRáÍR,ìš,‰1v0—Œ ¶ñ%˺GÒH3š«gº§¯·û½žëw®!U[µU»›ä/J’?ŸÐ ¥šÔ<ýÔÎ?½B(SÞtÿÛ9qèŸúÈ9÷Ø“-&IÙ*Û—Öpµ Õ[‚ ÉÇ%‰’ôzÆTD»H³ÝbëJÁÖª@‰¾ÛÄÅ›;ºí6v…1C #hÈ&ƒë»,ôRü–ã|èÚY^x|‡F_±|¢Må¡tU‚“ॠ(ˆ„Ls‡VS˵‹» ¶ n<¹Äݯ&xFvJíSsâÎý¤™äųcòAÎÂBƒlV’¶4BHŒ*D¼(-!¬§¡ÞGF#OÖ—$Z¡¢@Šë"1@PV'"‘HD@è(§Oîûè¼ïwÎñÿ#Æ(H ð÷@ó ö±OüîCYVÿä/þóÿó-ׯo‘|êE^Pš !­åZÝO\^gå…+P9öíÝÏ÷þÀ»¹ûu·sèè^:³ ¶'k¬ŒÎSfœª ‡kXŠª¦t´"KÀ ‘\|a…žyЬÙåÒÕ‡™›ÛÇò‰o{ðè,g}Š«kS¦•eãÒ&¶pÌô;8SS5*˰#K+k0Ü”#GÚ–4º)(ˆp d½”¬±&ÃIGe‚§Ï¬ñ†·ÞÊΦâO?ð0—žÙ¡Û×´º i*í 2’5ÑKB-Ð^€‰T»%õ¸bccÂÅ«C½”ïZ"´ ãјÜåD† Ö9žÒnw9÷ø.Û›f¢h¶$s=M3U!ð.‰dB:…5,ˆqÞ“ûˆ–‚~7c7·Tu@H¨J‡Ð‘V[D@zAQùiúÓwÜ÷àÇùýsüˆ€äï‰æêÓ_úýï¹¼ºùÎËgÖØÞòäcÅW?þ$R)ªb‚Ò”" ¨ª’'ŽòÆw¿…ûÞôݸŒnÖóU(+h8™9’ŠФX) Îjƒ›Tô²è)_þ›/°µ¶Áƒï>ñá#¿ò§|õsøÄ ‡fÒN;D±I1ª¸°~rd¹ã;öÑ;(ص9.1´ƒF£Qµ#Ž ?K°‘Ò9””TA°5\ç oëóÌ“3\:»ËÕ³cݰ@+“XZ@FDN%˜„,4(‡–ÑNÁµµ]ž~n‡(áÆ[æ‘óŠÍp"ÉÆ"\ÀXOUÖ( ÇNfÌdm®^)mÂp×RM,½^‚’ü/"&„×( ó-MÖxéÉKGå!qŠÁÐbC$ÓB@Ehàˆ"°u|äèÑ=ÿÛ;ÿáo]å?Cùš£äï‰æè¯þð·œÛúê}áá•ûn¾ùvý®ý<ûäs¬œ{žv·C9Ú!µ†I>!¦Šù©Äé^N4S?ÄVSÈ ZzxŒó8àÎ"i ñäE ÎB&9óľôù'iwRn»ïœ›0-J¨“ 2éÌ·hÍ7 ðÓÿøÇ8óWÏréésL‡¶g YÒ ª)Ue–¹¥¯~Ã!®]ÜE´5"‘$™F0µ@ $¨#Šˆ ‚sÏmpÃ=ÜóÚ¬¼0âú•œ½‹}òÝ‚¤ ‰È5ø±%†’’|lX¹6àÙçvÙÞ±>1ËÑÓ a™æÈ€ŽžbR*Oš¼õlo:z) ·umÖ×+F#OY8BŒ4R ê2*Xli²–F¥‘iíif”`{\c,d© ‘ Z-‰ PÖ!#y§³ýÆ—¿û½ï;óëø>þ+$@ÅßÍ+Ì—ý‹Ó+ÅÓßþèc/ܽpÃQ}ãën#¸Ynyýg˜Ÿ_ÀŒÆ@`OÚà™³gøÿñƒ„401Sd4J´L ÁQº@p6x¼ñ$Ú£µiž3_áÚ‹Cîù¦È4l]['´4ªfl)¨¨«1™¬ÙÙœpûþÜpúÃ5öö µd{0¢4»Xã,w?xáÆ˜Pyú t{)‰0ØÚà#J’A J Ê‚S¬®Ž9t²ËÉ[xñ™m†ƒÕ 4…ÀàŒ&xO5­(òœávÁʵœ²ö(%Q©&ÊáJrG5u¨H.RM<»DÒL¢‘Þ—á$ƒ¡a’[´U„„Hš‚±g6DÚmJ»»­Ii"ÐR`\$zAU„T¼æî;þì¾ozßÿ„þžh^aÎ^ÿêO ˜¾»½´'ÛwêÖªmÖ,­¬‹ e*i7;,¥s\Ù¼À¥Ë9¾v™}ò«$'C q„࡬ÁYdˆ8"¶„àA&!b‡Z©Æ '\¹4 I3î¼ÿ(;ƒ!ymhÊR+Ò4 µ@É@J`q¦Íöø g~ŽåC3Ü|ç!칉k—6í5&ÜüÞ D ÖìYêSÙR( 6F04É×DbXˆ>¢”“šnÚâõagmÄê•!Y+’eScFqì ¦loíÖÔ–¶ØÚ´L§%×Çd=œ÷¤6HðàJª=‰„Pyv'–Ô)"-5­²$AI¨¼'Ö m ²ç#ND´x©ëˆ” $ôZŠ#ƤŒŠ@]Ç•ÛnÞó?ý/þæ^B$¯ ¿ùûÿô—F®xgE;ÛêuK‘kÇHŽ©gKŠVÅ…üY±¦ Ü6ƒÑ6y1E´%µvŒCÁØåLLÎ4/™æ†inÉóšzä©§[8òqÎp{—é¸DùÌÇŸá™'.sèx—c7.1Ž!ÔxWâŠojDðøiA±=¢ƒf´±Ád{ÊaüŸTì94˯»·¾û„ˆl_Ÿ²8סjš*à¦Æ8‚ ü'‚À•WêÜCxÁD6VGÌÏ6¹÷þcH!X¿:f´Y0Ùª™Ž`c}ʵ•;»%1 ,kqò޽$̈́ݭ’Ýí‚྄*\ Vo<¾ô˜Üc ‡w#"êÒ“O-ùÄ’O ®v¤…óTÆ¡5dZ’*EY&¹CDH5H€€³ÉÄSaõÀRïýáŸúµñ£y…øÀŸÿÚO\ž¬~·©³Þn^²y? )´‚¢#|te›¬ÙARƒL>8†Ó]vË!¨¨±€ÊŠ ªáO J„´PYt°Ø"òÜ㌷ܹ‡«/ÐRÐl62!‘‘PªÊ`rƒ)Z³°ëVÊÓh²NAQm`Œäü…š×~Ãmôf;¬^˜°wq†Íµ! I–QW ïñÙÜöÉÏ}â-çW®­iȬ?.ªŸ›ÐÙ“¢¥#ÁvR;¨mAˆ¡>)ç»LËÆÕÔÎR;‹5ŽºòTcC55ÔÍ#ÕÔPN*êÒ³¾:`4,h6SZ`{uH3KÑRQMjli¨v+ìÄ@áQ6¡'öpæ+Ï“è@k6 ;EØÅë)yÙVÜÿ÷“-ÎlŒ£î@™ãÊš`<¡Žp•ÇW‘è"ÞD¢h"¸H#U¸Ò°¹¾Ãâb“ƒz”ãÀåóCV¯1²ïH£¯ê³|¼Cg&›1œºsެ•rýҔ뗦˜©Å•\Dº6‚‰à#*@ôg"ÞDED†H#…V"¨Ë@^ i Ƭ Ô&"¥@I’ç"B‚sªåž™ìÞþ}ä­ïù• ^‚$¯_<ó‰wœyö܃yidkf†™ý{pü'Í,£&§Ó̘ïw ÔH„CÅÔ"í^ [ÖØªÄL òÝ6/ˆÎàÁVk Þ¬óxãðu œ:ŠÍµ UQÓj'´ ’,Á˜H>*™îæL·s¦;%õ°ÂWŽXægRÎ?»†’’$´ÛŠ#½ù^ÂÊ…u^ÿæ{Ñ©ä±/\áoi$ÎxbÀE¢à""°mD)ŒqD€ÀpwÊdRÐh¤X#)KG£)9r|–“7/±¸Ô£?פÓUÄXqø¦½¹ùȲ¾R` ©<΄ ˜xœ‰Áyp¬ ÞGŒ xÉËÀpê©L$ËI"°>#_‘J8±&Bc!¾x÷Ý7þá{~úƒgy‰Ò¼Ìýò~âû·Ùü¾[ßxGSÏ,’ÌuÉ£Ù4›Š4Õ¤XB˜‚“Ìè)€¡@f#£Ñ6Íí&"U¤)”;»H-‰Rv °ŽXÕ()€·&䂘%\»°K¢{ö÷('ލ4S* €€ª´Èè('áÁOÈ·Ö¸üü6J ææ2²L1BÀyÇözÎÂÁœÛ_{’g=Ë­·Mh§‘Ѥ$6i+EIL$±¤Q$Zâ*´W×ìJòiÍhTó³ƒ-ËüÞ”{˜eù಑PÚ@DÅ' zÍ{ö§l\‚ÝuO¯ëÉšžBB§)!ªÒÓV "˜2’¥ … ÚHm"D"¬n8 é´@§€µ‹D$ÁƒT!ÎÃpêi¤âK÷Ýsâ£?÷oŸø(/a’—±úýozqóùŸºíŽWï[:°—"ŸRÚ½ŒF+EII$ €L&¤RƒS¡ƒ#”–()È·ÇÔà çV­mÒIT5v8ÁÛ  Á[ª¼ÀÔ%¦¬lŒÉ'ù°`cm—v7ãÄÉe@â­'T–P;\刕ÃWWX|eñ.çüåg(KC³™’ˆÅH¡iRO#£]tf¹¾vŽøñ7#…â+³N](ÆO92T×;б¡šZLéI´F"p>à½c:.ÙÜš°µ5æêÕ —/M Böh²|¢‰¥Ä‡šn7¥•¥À{&ƒ1ÇO4i¶4ÓqÅpË`ÊHYF#Çhä©K¨M$FþNY°; XÖÁõgwi¤‚…9R0­#>D 5¸‰!â”utY"ÿúÞ{Nüë_üçþ /qš—±Oùc?røu§o’³3ÙêöÌ<@{!e<ݤ©kúÌ@š:£‰Æ˜’`©lP!ÉÒ¡ãí&×4ŠdïLh+A"!ÔOD!ˆʼ¦6žh"3ý>ƒ+cæÛdiJ™[¢RF„àk"x. D@¶&\ÛXÃÖ–v{†Xw˜¬DÒv“ÑN¤1[PSÊé”Ùݾõ{ð¡÷_F[Å잌½‡Iï¡‘%(• Wx¢xp¦¦È ;ƒ‚µk£¡£?«YÚßfc5„Ç'²¤E"$±„J µÃ”5ÁO9°o†~7% Žv3Ag¡"© uå‘”ç¡6).Àdìqöï‘Ìö*D)‹@^EÚ™¤ÙP”•g”;œc:ÛÕõúûnüwþ·¿ýè/þö½¼Ôi^¦ÞÿÁŸû…¿xü¯¿á{ß’­Ÿß&˜HÚNQÚ£ОÍ@k¬qX©Hhàd ôºš =äY òAεç®2³§^ì€`-0!HÐJàƒ§´G'é¶›<²Àåç/¡Á¾=|t "BBô–‹ð‚'JO’Q÷)¶ˆ8çHRˆ&"ÄÊ‚—¼øì5nºy}×xñ˜ý¶ Ò°´Ô"˜@lbŒ4)R Ši‰q޲¨ÙÞ,ÙØ(qγ´Osçkç9ûlÂêÊÆ‚‘ Ӊŕ)‰LÑQPU0d£àð¡;[¶öT¨ˆ™ ÕQAÐÖ¸¤ Ê š‰ ßÓt:ç#ƒ‰ÅXÈ ï©]$MäôÄáöŸÝrúøï}ÛÿÚW¿7çe@ó2ôð£{ã¿ÿ“_zÃáÃG—-ÞÉ꥿"SM4ž¼Ø$ít@T!Ã!)€@ ¤€ÜÒ4 TOÓšÍX9³F9Ì9|ã"'N.±wO—N"1Á¬£öŽ@’H,WD³Áöæ6W.lÐî$ìÛߣª-ø@¢4¥wÈ‚€ÒH"JRBUXÊq$Ñ ºÖ$> ­Å›šLƒ)—ÎoòÍß~ïÿ‹l¬–oÑ!Òíe´[„€fÄÇ€±–á¨äò•1ÅÔÓÕœ¸¹ÃâÞ„c¯jóüyƒ1Žº’TÞ ½Ei‰Ü(ûPyŒ/8vx–óg†cO1†D ¤„Šˆ ‚@¦‚¸ñÚ©ÄyAˆ‘4‘¨D1­";#G@Òë(jã¨*ÏØEºM}íØÁÖG_{ÿÝø¾Ÿþ‹Ïÿ£u?/Š—¡×=°ï—¯­?÷Щ›ïåô©·pîì“4{ IOR›)él›$Ô>ÁÛ€³%QTX)«1Ó2')%O?ö å(g~vŽíõÖ.ì°yuÈàúùp‚Ž‚è=ƒ1EU£š '"1B3Ix\:»ÎÜB‹ÅÅ6umpÁ“$ë<Á;‚÷g!8„wˆÑÍ%<ÿô„Ý™„fKã=xç1n›DKб@I…un¿Éòž½ ‡ÓI…³ž,•H)BP׎<7¬­•\º4&„Ⱦƒ ^sÏ 'oéÑŸO8x¸Ã¥ Š gG4º½Ç%Ø€Œ‘ \‰ÞarÇtä©ò€Ššà`k`)ë@Ö€FC‰xi$ ·à<´2‰q‘iÑZÐï'“Âa4Û)–f<±LJOªÅö©šÿîÞ×Þù;ïùï>õ/3š—™Gÿãû>ðÇÿü–ù…y—éÓåÜ™‹\¾vŽ{ßq;3‡›4» l¨©L RA­Èkm[´¶À›œŽËø›?ûûìá‡þ»xü+Oð—þ —Ï]æÂÎÕs»4[ëÌ-&ôæš MrS›’^«ÍÎd—+/¬“$‚¥½Œ©qÁC„²®A €÷Do‰8$#Uɺ’DRä†*/ó U>E«„@ÄÕfÖ¢Ê-Î{&YÍ‘“‹ôçŽòÕϾÈ`»`õjA»eXÚÛf’[Ö·*ÊÊÑlKn¹«ÇM7ÏЛUX¬ xéHÛ •(|ðT¸à°Dt)ˆÖœÇ—FAž;9ÇöîV®OYCÐNÁˆR‚#i&h$ŠÚEDЉ$I4EéðzÝ„V«É¨¨˜”~Wmž<Úü7¿úÖ÷?ôý¿}žŸ9ÎËâeæÁ·ÏþäÙíµ×³÷®fóÈIŠÎ ›£¾øŸáÜcç9yò8{{‡˜®Y‰W1ÕÍŽg¸µF±Fsá‘'xáɸëÍ'ÙÞ]çàñßðÐqnzUþ\S;Fã‚ñpÊhT²»Q²³:¦Þ)¬±±2b~¾Ës„°.â‚%D‡‚%`‰Ñ©BI I[Š+F”•£ÛÕèT’¥£Ùò”cÇL/ÅV) ©%«WháXî7°Ö3Î-»cÇõ ÇÚFMî,ûnL¹û-ËÜx÷"ݽ \Ã@Ë 4$½„ë—çŸá§ßnÒ”)®\Ä:Ë$¯ xÒTCÄÔ½£ÛÒÄ)K&ÒÌ"™‚DD´†D ¼¼d¶—!Q˜:Ðm+Bç˜íi¼‹l *š™,ï8µøé7}ã7ýî÷ÿÄGŸúW¿ò‘—!ÅËÈ3çþòmO_ùwïëC'âá‡{û\˜\åÔ='9vd‰/~øoxì“Oa&‚}Ý膣(†æE|àëšÝMìVÆLg/_þÓ#“À-¯9ÈÎö€k®²30·§Í±g¹ñT‡ã§ú9Öe®ß ÚH=©Ù¾Z²z¡`ýê`yo!¡ªÖ9D b4Dbm‹³ ݦBiI’Hò"°±I´àÈþ&>z¬u4š0.,e8}¬ÍL7áʪ¡¬cuçm‡~ù{Þû?üö›Þþ3Ïò2§x™xþù}×Ù‹üo¶§ýöâÁ›Øwê.^<ÿ,ÃÉ.ÝN“<ßáÖÛOóÍ="ðÕÏ=ÊsŸ‘'ÿêY†»ÛÜúÚÃìŸ[Æ KŽì»G>ý®œ»Ì]œÆ–5Î[leðÖ¡4D癌J¦“ gÎyªÒ¡4¼éذÇm€ÞlFÒ$Ío=QE@(I‰Ö ˆÞÓH “š­ÍœáŽ%úˆN$™RäSCŒ‘¦òÄ h6Î;W®…çø©>.*ÆCϱ[º»3Á…wÎ8‚=Þ9l)'fÚäü™1ƒÍœ4•ôz )$®˜2àm„(.âl„J â\$MJJz-Íê†am3°g.á†Z V7*º]‰óªò¼õMK4RÉÇ?·kk¾éæ_xÏ?ø¥ÿã5oxÏU^/ßùƒ7ÿ矽t÷¨<Ô¸¶: /v([±t$²Éõ¯ eÊkßr‚#§çI”c<ÚåÊS›<ò‘‹l_ãÆ£KtJŇ~ç“ <{÷ÏP•)"Ñ{B ÑLèÍ7ivR´Vø°"PÖŽqi©æÌÓjãÙ¸ƒ) m$4šR4‘D 2-IuDÅHôaýL ¼¤•(VWK©ba®ÅînEÖPôºyipº3šëkÏž°µ]Ó™¼ù¡}Üz×~>÷é5Œ•Üzß,‹Ç#¾Òx£ñ¥G:A´;1„RK‰Ž ÛëS6VKbˆ4 ‚ úˆF¢…@D7D/ÐB(I#Ueé¹|­f0 ì[Èxím󴻊ç_œÒîÂd@Fn>Õd8ò|î‘¡MõÄ»Þù ÿâ?ú+xâ–·ìð ¡xxô™Ï¾îÓO|èÝiçØé}§¾‰gŸ|œ3_~Ù47ÉbJ= „qÍtœóÜc0;›qßCX:œqËÍG(F†3_ºÈ>þŸýÄ£Œw¦<µHÚ’èDÑÊ2Úý”F3AJˆ1Òhj¤T¥ÁO·Û ;Ód¸“Óî7ÙÜ(ØZÑžQ$ ’$ÑÔµ¥.-ÍL#d$Ñ‚$%Ȉa-¾rTy`y±ÅÚjÉ`PÓÌ4δ#YCç–ÇqíjžýMÞð¦½<øö%¾ónæÌ3ŽOþÙ´V,OiÌ”l |‚­¾Ž¸ÒRN ¾„ZaKOðÕ•Š2÷dZ‘¥h$ÁE¼H!h7Y*±6"¢ •ICÏê†7îpxo—ÑÔ±º>%ð5Ò#•àÄ š²|þ‘Üö{úþñOþÈ¿~ë;ÿÙ'÷¾}Ê+ˆæeà Oÿù›Ÿ]“·½æÁÓ4ö.ñÐ÷¾3½Â‹Õ‹lo\bR/ÐQ{2a2.Ñ™ãâ¥ó\¹4¦˜æœ8xœïÿ‰;Xyì&Î<±Æùç¯P^7ت&!¢˜²"Ë2š-—šºr…Á[2Ðé60Ñ3Ý­(+C§,8t4åÒ¹ÀxÓmkêÊAíè÷Z$ÝWÒD’È€0žˆÐ1êŒbj¨ª@–E–ööØ ¸ºž³¼Ü!f‚iÅê‹9ÃONðà›—xý›—™mâÓÀõ]Ó‰Z³‚™=MPM™ò¸Ü`ó€ð[x‚õà,¶Òh›ÒL¦ÁámDÀGêÁ{Z‰ Q‚ºô4SÅþ…Ã]˳/”YœÕì[lÒk'ì9Ó©C("Òï&ô:’ñ$òÔsµ½ãUsøãïûýÞ·üÌcðoy¥Q¼Ä=÷ügßñ…ç?üO’=·,g½%ÆEÊþƒ-nº±Ïúh•íÝ5šºO¢úT£)Űbi_ds}ƒz2AâÙ¼8ekuÄ‘åÃÜvû!¾ù­¯æ³ŸyŠÝ’WÝu„v7EˆHHÒL"øi´òiBÐîfìŽJö-w™k›%íV‚Ö -Á¢ ˆ"¢DÄOô¼GÄ@]2©pN²reB¿ßá®»pî€++WVJV¯Ö¨,p÷ëyû»rÏ÷£SX[›Pù@Ôšð ÃÝšå£-Zýˆ †"(¦;–bdÞcÖ[ª‰@ń͒éÄ’$‚VS h DbÀûÈ|/E"yî|ÉÕë–V¦8°”°g>¥ÕÔŒ§†‘AkA§#ˆ„ \»nyqÅMï»kïïüÜ¿üƒyË=ïyŽW(ÅKÜßýªÿYÚsßåmÕ†¼¾ÂÒ^E§1eR®`†×É\†¬5»×¶hD6a´;"iÕÈ4"…Ä Ë(/™¸)º3ûÚ<õðÅxÈâB†ÚM”­ ™*¤$‰D'á øˆ÷k<¡r,uR\YséܘVš°o±+=©$€p‘T ”ˆ¤‰DňŒP”Á® )£ J§¸¼>åóopuÕP™ÀüAÍ­÷/ðÐ{póëæ‰mKjF6g8©I„˜å¯ÿäí©ýÙ)%¾Œ¸Ò#L O=®1¹Ážºpq¥ÃC>õÄhe‚f"I„@ %éw4“±ç™s†i8q°Á±ý-„)#Æ[\ð´Úc=É#I"jºíìÌ·ë[ý‡Þ÷¿uìÆ7^åLóç;ã[¶VK¶¯[Ú‹mdêM¶ÙÓV4µÄä5ùæ€^·Go¡O¾ãØXÙF%PV…§›6hvS”ÕÙ9uÇ2¼í&>ý'gqþ¯¹ç !zú³MÒV†N>‚Dâm (*  ” 2žfC1ÞÉ9th†'¦\¹0FÅ@§¡"ˆ¨˜ée€ÇGp,ÎZòÒ1šH®oÔ\¸“e’-OUEöÝÐà¶{–9p£æàñú“QEYÔ¨T¢p"ÆD6FS¦£š"1Fœ‹Ô¹ÇIA¡ D!zRÁG¬ X'AÐï$ô»ïýN1`]d~V“(xáÅŠíaàðRÊM‡šŒ§ŽÒ©d”¢ðøØÚ,Î ^ýª6Ó©ßÒºóï}ïO}ðÍßúOþ©ŸÿS^é4/aôøû¶úÕ {×¹T~…Ý­Ëô—s¤>À¥‹Sªí«ìO,ƒÌPÖÐÍ9•PÛ[DPD>É %¡†)¥žðßs‚Ž6|ò£çxäsyã7%‘ Á•‘é´"­^ÂL+cš—L¶J¤–¨T1”he¸ñÈ,ÓAÍpP c¤*ÊÂ’—ˆ2"Tdšƒ’ÁÀSæ ´béð,{–:¬}æ*BŽß»À‘×ì¡È12†Ñõ)*•@`´m¨kG4šv"Ù¼b)F)Ž+°# ÚCt¸2€‰H^GDˆ„:PL+5L±4+¤tÒ´ Ua8sqBˆ‘ÛO¦Ìv%¹Éiw$J;FãHm#›»)á×µ)k~,ß8uÓܯþì?ûàNÞúÀu¾îïh^Êæ¶Þ°;¨¿úůpåây&4;š¢¨1ëc”5ÌÏ·¨‹”­Õ12•ˆt)Þ ÚÝZ9‰#Ë4Á'Ô¥ÅXÇöƘ'¯¼í§9r¬ÇïýöãüÙ‡Îsû] :2CšH:ýi#…˜N*êÊ‚˜Ú1šÔt™–ì[jó¥+kkNsÌ/´H›šª6l¬çl eh¶‹Ë óó 4š]¾õ÷ó+¿ðaì40¨Á‰[ö$ŒvJ¤Œ´ç¦¤4×l@ °u`íÚS[¤4; Îx‘F… ð62-=¸1Òë)¼‰ÔU ÕPX "B³‘rñê„Õ튥Í­'›•agd9~(cgd8Éá-ÌÍhî½½ÅòÞ”§ž›µMÿ™ïùžû?ôîø¿ÿñþý'wùºÿ›æ%ê|ìÇÚûn<ýøåu6Ç%ÂLÈ\»ê¶- -‘ƒœbc‚%”å˜hùý´¬#Øš–žÒok²Ì1™8†;šiîÀi¾òÙ§Ù»·ÏþÈi>ô¡ó<õ•-&ƒœÓ§¹e<*q!Ðl&t;)M-‘‰¦Š‘ÁvM]UXïh5^ýšYVVÆ\Ý,XÛ-16R[@Efö$;2Ëü6ÍVÆlc‰ƒÐ;Úg튃4rúþeŠPSïL˜o@–IêI`´QSm;Œ‘d¤$Û“)×/í¤‰&zê‘Q#S2 </ðVàŒ@DPB€A(AQx¢ ò’k›cbŒÜx0a¾¯¸¾Ói -k\plîxú8u¤ÃáC]¶5ŸýâðÉn'ýüoü›_úÃûÞò¾/þ÷¿x’¯ûÒ¼DÙ™äÇ7Ö¶l¯]çþï|+ë—æ¹üè£ ×GdG™L &›CfBA·×G55+×*d£A¾’Ù=l)‰>RŽk\æ‰."Qd‰B8h4/žßb~¾ÍþàÍ|ñ‹W8óô€Çòë9Ò§ÝNh5R 2•Xë 1"<$J Ô…gm=§®=µ DÍŽb®—°g¹ÃÞf˜Û×¥G$Ab47œØÇïÿ/IžÌíËXÜßcp}—Å]Ê¢ ªÀ%õØ! )ȧž`#RTl¬NRÒle8ïÁE«<Ñzb^(HSB "”¥GĈ’DK6GŽõA`¾«9~ #Mi9y¤OŽ•õ‚­Gk8u4c8±|õ×}mùÄ;¾åôü‘Ÿù÷ŸZ>tû_÷ÿJóô—ìg·û÷xêìsìº{á3$ ’¶š¥Þ‰Lò)¢ÆXÑ;ÛX™òÄc+¤MÏbg/ãQ¤¿ØG5P_Á9 Î`}d&(HS¦ÓšÕµ‚ù¹£Á˜ÑÆ„[OÍãJÇsÏy~2àðáý~F]y´„~7cZ[v‡5£ÜRŽªô "iS2³q×7ÎÓèf´[ä…¡D°…'&Ýi53à {ö6ùò§®à«ÈÜþ&:õèïŒI2‡ ¢=¤hR2lá±»qìVSFƒ ¥2Z­o'h$2H|å‘„— ¤! “&H/@ÀêfÅ4Üt(áà²DIK¿'PIde³ ¶°w>áÐÞŒ — Ÿ´¦ÛáÅCÒϾ÷‡ü7¿ù]¿úôÿô›·óuÿß4/A^ñ–ë«{Ãõ«¸ï0㕳èFŠ© ›×Ç$³’îìYncW†„:ÐYl]`°¾‹°çi4úœ{n‹F&˜Ÿót[[[ªÜSNJ¬©H¢¤•IÊÂàÔed{«àÔÉEæû-}|ƒgŸ‘$‚n/!ÄÀdâñ>¢4$ I·Ÿ°¸¿Io&cïKºè†fTX¢„¤•"Is¦Mi"£QÁp}‚ÎçέáLàoU…ãú¥]:Kï#Þ8bˆèx˜ŽU鉕BêÈx;PNø;’ˆ«"興žJd¨(ñ.àCD h$%ØÖ8ï9}4cyOŠÖ‘Ia8¿bð1Òn –æ™–<}¶$Ï#¯}UûùWß}äWïÛÏ}êæ;¿û _÷Ÿ¥y‰ùó§÷Ÿ>¾vî†Ïöaf÷w‘ÃE¦×.ràä œ~Õ­|êƒÊœ ̦žÔ*æ“ëOŒ0¾äö£ól=gž9K”P‘ÌÌ%4ë@£­Q;–´pôŒawà MÖN¨ µ N›×Ãñ„íÝŠÍM td06dEw¡ÍìBƒÖ’D/zÒ† ÑÖ´æšøÙŒMé°ÆPH„L· b»$I2Š©!T0Pð™‡)Æ+”žv¢™¬äì;Ð! ÙÝ(qR‘&š|©*pÔE`ó¢ÀW¦[D¨%ADRA ÔÖ#ˆh-è4½¶¢‘ ‚©¦`< ¹¸a˜–F¦h´¡×‡ /•t£pßôšå¿ùÛ~à·îx×/ý?ÿÝ|ÝÍKÈ£Ï|iîýŸüõïÚ˜QCêÕ´æoÇTÓ³t`žb|ŸÞaƒ€Wf,š'¦Mö,µ¹Iìe}mŒ™ä\Ù¨5RÂLŒ´›’˜G¼‡apŒ¯\- êRç‚)At½Ù”¹½m²^‚J½å.sD×’¤)bˆ›Ž"*‘„:2Í Ñ ¢çïä;SòQ‰7‚ÁаòÂ6®öÈDÐî¤5ÒK6× )ˆ ˆ>2 6 Ó±ÅÛˆ­ãÿÅœÇüšž…}ÿ^×}?Ïo}—óžmfÎlW†ñ‚ƒÍ›ÅÆ µìV²(T.M•D‘¨Ôü‘4"RU•JE"%IJ@E‰*«P’–t¡”Da©‰© ¼Œg<Û™™³½çÝ~ïoyžç¾¯ëê9CÔþÝðkéý|X/Ü“±2c½6r†&#˜Ìó±2j%0 ÖÓ$EPxðRf>KÔ€ÃÃÂfc˜m£ìÌ”iÝÆêŽüÜÓo¿ö¿|üÓ?ñ³ï|æ‡^âÜÿ'Â7‘ßüÊgþá~m>•§—v¾~gÌ¿ð/]Ý}Ã(­ X¾z‡ƒ·©ËCYã1pñòºUe>Q{c2mØõ„Ãà Û[Êf]Ib4­pzâ´#a£™ÍÚÀ•&+óéPfóËÓ¯~é6æÁ…g\yb‡‡çä±Òlgf툱5ŒÇ-©!€ –Êr±b½ìØ,{–‹¡3jÔ°^õ,Oº»-ËãaX“rbooÆåvIiÃñÑŠÉÆãŒ™±<(ƒ!£QfkÖ2i3ËUÏz]Š1m•íŒà$ ÚFQP@"‚HMP«ÑjÃöxÂÝãn¨Œ'Îx\½¤ÌfÁ­;Þ7£ñ¿ú®ïúÞŸûËóW~žsÿF2ßD¶/÷™ÏÞ³“õA^Y¾Âòhz®^Sú^½C98¡n*mžÐl%¢-´Ó†åñš®ë +ÈÌó„nQØž´<üМÓÅ@Ï@Ó “ËÆÅ«cŽV™2À°q¢Âd<”+ìñõ¯P=MÓ݆Ô*fFV0aDCK‚!@Œû6G/é€×_>áä`CŒÜ€WèW ¢L·®=¼‹_Jܺs“õºãädÁz½d<3£_Ãtš‚& W1›fD…&'T„íùˆê ¥¯d…ÇLÈ*`A­L²2'œӵ1„ÓŒÍÊѪpx:ÐHðàÅĵÅ*·îØñ]ù_?ùé¿ñSßûýísœû7–ù&ñ»ÏýüOÝ9ivó°Ë|gÂòxÍí—n w–´O?Èúîk¼øû/32ãÂìn-ëœ …“õ†ííĸ õ´#ðúó+šÚraÒrëze½qäbËl:¢Î*wª0½8g{2fyÔ¡*ÐÁòt ¶Nï' Cn•Ñ$ÓäŒzÂVSAlÕ1ÔÊÉÑ‚›¯qûÖŠý¥M­&æsØÚvwF<ü¦Þôæ]Þñ¦)Þw|þ S¾þ\åè pzêHÀ|.H»;8ÔŒsG± ï‚¾ðܳ ’PA€F•œQ¡/N¢ŠÒ‡P©¤ḑÂÓoΔbÜ<}õ{?ò±ŸúÄø_ÿ£¯=y̹ÿ_„o¿öìg^˜^}Ûo¡&¸y|Àç?û›í¿Àþ«_åÖóÈúà”®Œ™¦9åTá ”]‡Ó%£Æ¹vAÉ¥Ðß-ÄÆèW‰”3w—A©NÙNŒ&Ù`2Êlo©ëÊhÔ0·l6•î¸ðü—ïr÷æš­½.Ï”ÐV™íL „ºìH½ÑmÊPèºB¿) °s¡åÊÕ)óíÌdœÐää.ì´„ƒ[Kj×1A·2–kcÒ*u–‹ >8Pû ï@"p ¡š² ÀPP¬BN Šæ•@UÈI‰,D£dœ¡7¼\I\»™Ì÷~õcÿîö÷žùØ_ùUÎý‰È|øÇ¿÷³?}»›î\­»´³ Ç«»ÜYÜàñ§ÞλÆßÎrù,ÿâ¼ôůqùÑ-XÙ?^³>èirËD2£öŽõN“àòµ1bc^xñÑDj`pðÝ‘“a´ÙЯ{&£}OY(Þ'774}᡽–Ù¬¡-px{Íé²°š¬hÇ#Ö›5Õ{$AÎÂh¤ì=8f>OlmgrÌzºScè n£œœ£ÃMˆ1AÜ„pÈžYoœQ„¾w„ ÍŠ€Q«Ó&a”AˆÂU² ÷%’ÒXÕÂt<Р¬š«ÿìÿâOþØ{ŸùÔïqîOLæŒûݯüËOý«;ÿü#³K^<©•¹±ØÜâk_ý—¯^#]z;<övž|×·pãÅ×hF L‘ƱuÏðêKÁìÁ è]°Ý$öOŒqÛ±Ò³1¡mL­†¡´c¥JåÔ¾QJo¬O V‚q“xâÑ „r|80,×H5´VÖ'•aÕCæ{ {'LÆ wç>UXÕ±XuTÀ,èz')´ C/x…¦¬ƒ¡8Y”&+ëÞ)%ðÁIYÈ’ ˜ãMN`NAUpJ " æ`¤B“…& ¨P=ªËõ@(ÌæÂ㎘ÍG”ØûÜÿðùï}æS¿Ç¹?Q™3îW¾ðkO-.¿ý¡-b+scx…WŸçxñ:ͼe2}+é 2Û{”ÜNÙ¿³`{®ì\ÑõÝYÒ÷•;«JV''8Ö l6ؽؠ)ؿճœ&¨£Ä†‚™‘rÆ*Œ¶]šðÀ•)pèqpÅjPÀÁ*0ôŽ„3)nND3xGD!$¼„ 9 MR9 Xx¬;£/AÎÁå‹0›gVË`ï'?ÿïÿÐþ7Þû¾ïÿ,çþÄ%ΰÏþáo_}±Üý[Û\{¬™î ãÂ;/pãåX3ÏH2e>Ëh]óÚ _cy|DÓ$rvæIØÉJ“”õ¢R‹3µl†Ê¦wœàk-O>9¥ÃpØ`ŒChD,ÈMf2kÙÞ±saÄî…–ÉDYn ë~ *“-AÚ ƒvhcTq†0ÊPÙlzún ÖJ*e¨XuÂZŒ:^$î± êXuÌ‚„$T @EÈYpúfÜ# ™@ˆT…6+M›ÈYQ‚{"‚¡8C1Š9 »»páDj¸öø“_ÿÁOÿø¾çÛ¾ÿŸsîOEæ ËWO>ò¶í]'ðT~¨ŒFBqgè Ǿš¹z¹áà¤ãpá˧ßsí7~àÓçÇŸzú£¿Ã¹?5™3l>k>4ÙèÖÑ«¯pý·¾ÆÝÛì^ÝáÊ#Wyék/q÷ÅWуY{™S±··ÍöÎ6§‡'Ì&N¶àÆbMh¢¸3g¹Í€(é#ÑÕ¡::rF²cÓ¬‚Šâšè †ÎI ¹ÑX0 –ËJ¸ƒVƒap†Áh³’†êÔ˜‚á„{"P”{<‚6CÎШ€”‚"BÒ iÂÝ)F91n•jP# î ª9¤’!%¡/A±`{®\½˜ÙÚJ´#Q³¼öð•_üOÿÝÏ<õôG‡sª2gÔs×?;î­¥ëf‹[·XÜ~‹»»¼ë½ßÆlw›£['¼þÜK ó¬Ž×ÔC˜ŽWºÊáCN»žI›å€´93˜3¬œÑHÑ’£&¡‘±MeãFaÝ–£·x8Cg @.Á¨U†Apw„À Ì÷³ m”ÝEEX­‚¡°À" +àA8ˆY Ú$ š "‚U°TAR‚F•¤Ð( ƒª‚ Gp P…¤B;Rju`gK¹²—ÙÛKÔˇ{äø‹?ò³û©§?öçþÔeΨÃzó‡·™}ëH•+—¶yÓ[þ?ú6&»ÒkåÉÇßÎË¿÷Uî¼ò›“9{Ûsæ³))2ãqËfѱ4§¤¤Œw2¬Œõª°:­ä¤Œ²r\ m 4%N†B©á´3áÒž²\V+¥‚"Âzí¸"ж VF#eÔ M’+¢B+BÊÁR TÜñÂPç|Ü7Úš Í‚"BD0´YP <*¢3   I°êt]e:Sv·šátiÔêeïò…ò—äïÿäSOìEÎý™ÈœQí,G›§£«­Â›®²sÚÑ„Á2“ÒòÖkïà÷wë/>G9°Î ëe%ŒóÂ:M4 ò8±=rv–w+Y„è”åÂi[3EzmA3‡i˜Ía*pº JD7¨!” T!åD«ŠŠ ’ ¨³Ì\ˆ|€’€„pŸ 6Õ@]‘P )¨HT ’] T`4Up#šV0Ìr² ÷õƒQ'ee4RRf“„ЧýGé?þ™Ÿ{êé?ÿ"çþÌdΠ/^ÿíǺÙí§–êÛ7õ”zV«†ÐjKœ|ùžþîï¡´§´£Ìpº¤;ØžŽµÁ݆•¶ã6°Y ÌFÊîÅ1 ¥3ÔIB`F;Rš,¤Üa±‚I#Œ'Mà. ÂP ¬ÂjmT3Tè‡$uˆ"ÀõqîÏTæ Z¤£uÚ_:ðS¾žî0´Ê®^FWc¦£–Q;ƒF¹ø–ðÈf× ³Ù@‹1ê{7Yì¯Ø¿s—Qr“P†M!š ƒ¤0Æã lœâFëN„%„E'¬“’³`Ôê³²aHv$‚Ô:$ \Á†@k Š€G@@˜’‡êA1H*ˆBjus,@ÌÀ#ðMŠDÁNûÀ" 6!a¤¶£öAé胙(»cã-{Á[¿Uñ‰ñõãþ?þCç'¿û;ÿ—8÷g.s íðͳ퓣–7o‘héjÁý6ýâe´±uá2®8·¯_g2 ®=¼GÈ´pé‘)‡ÆêtMkAj E¥/F!%XŸVÆM"¥Äz]è‡`4 T…” I`5(5ˆj Ü‚ˆ œ{‚œa4¦cEJ‚À2PUAÜÁ=ð 0 ª($ÌsÈ*ä$˜n&¨ÎT@T!Bðj`ÜãfŽ˜9^6Û[‰‡¯6ŒfÎs7`“ô_|àCÿßûáKœû†ÈœA}ö'ÕG{}¿ÀŽ—qÒ»—w1†œ.·XuFéôÃ’;¯î³9>dkZQïiv¶.&j1Ö›‚¯+m‚œa¨‚pOUF[-‰LßoèûÂúÔ)Õ);[”ÿ‡Aà$…éD”œ0 IÉ£@Dü¿²T HM£„‚ª@@_š¬$ P’àƒ”‚œ…¶QZÌÀ<ˆóBX€ I mƒq [;NÍÊËGPÚüùg¾ï“Ÿù¡¿ôó¿Á¹o˜Äó«ÏþoÿÉA^|Ž.îE?âÕgo±ÿÒ>Ù‚Ò­úÝéš—Ÿ}ïá‰wü9$2¯|é:‡¯ßEÂY/Vœì/X/ ë!AsbÔ$D•F“IC“Ñ m‚¶QRr7Ç!ªDÚVi[!'! ºÎé{Ç<0ƒZÁjP J †Tw@@4 ªBÎJÛ(£VQÀ ¡ÉBÓ*.àˆ IADÐ$¤¤¨*¢ŠŠ ¢R0n ¡c>ƒ‹{ŠŒ‚»k!Mgw>ôÑüÃÿè¯þòÏpî*sÆ,êòË?9jÇlàÊÖ‚ýnŸ“[GŒW•MwÄrÙÓNwxÏû?ÀO½—­ù%^ýê]žÿÜg¹Õ3™ÃjwÂxºÃhä¬×6'K¼:´JÓ€&èúJï“©rß”XAõ@ˆ@ÜyC)§SAÌM.lÌÁƒŒpŸoˆà$DÀJ1ªM#ä ¢ „* €@›•ûÅÂ÷À<ˆ\*j ¥aœ…éÈÑ–æ0kï\{ê=?óáþõ¿ÿ”sßX™3fãöa|B?´ì]¸Ì{¿ý»èÖ§|é÷‹ÛÏßbè\|ð"þ¾ñèÛßÄ̓ç™nx×ûÞÆpx£×_eœaçÂV4OÀ{ºž¨5ؘ#­B€;*‚Ôâ8AVð€&)Y…jÎÐ;eT  Ð*Єà¥8‚¬¨Á=Á=$î‹€Rœj) )¡B“…&óÀ*opUÐ$ˆr` ƒAÛB)ÁTùDipN–AŒ•KìþÚ'ÿ­ùÌ;ßùKÎ}Ã%ÎßüÒgÿöK›ÏD3ÇÓ‰ ãñ6{\¦ïŽ8¸u›¹Â3ßóì]¹À­;·è–j֯؞ ôKl½a>i@[º>6=e0",ˆp4`µ(ƒS‹1£§‚¾wJAÓIf4RÄrF­’³Ü'˜A8B)A#   "¸Gî¡–`(A¨ M’ š„<…, BPUET@3¨¬¥8æŽâˆâ°ŒR`4K\y|ö[ÿħÿ‹?ÿÑ¿þUÎ ™3äöòõ½ôòs4³‡Ù»¼EóPKá6“ ÎSßóWÞ:!ùš2¬øý?ø•fKiʪg:)<òpp»VûK6EØXàC%pšÖ‘ï "H(N„¢*XÜAhe<‚èGšFi%ÌQ…¨AR¨x² hP „{"pŠMêà€ €(ÿšCõ %ADèKm’*A8´M"©°ÞT†Þ°Âaè€Çi!5Êl6]¿ïÛ¾ï—>õ‰¿÷Ι3¤ÆäöÁ!Ü0úÕ.ãí–˜¬YôLÚ̵'â•ç¾Æ _{…åò&yäèé¬R–kRç<²·Í•wîòG¿sÊÉzMñÀª¡!$QG܃é¬ÁÌñ$Å„’’ô˜f@ $À«c(E@“„œð˜AhUÐ$d‚" 'È*¨p@ ) â.EzC"#úÁp P¨X T„ÙD™Ü(Mγ€$¨ ¸¥ÕEHÂr‚„ tS,ÀN7Îì¿ó¾oÿÄ)çΤ̱öõN× ;‹ƒºn ÕØ¹0áøØè6k–'',Ît¦TOcºNX®Æ Êæt@¥ƒ8%bàʛǂ7˜¥8““жІY„9Õ`Ü@“…jA)—¼°ÿÄ[>ð9øgœ;›2gÄf]ß¶Y‘ï¼pÊÁ­C®>´Ç·¾ÿCì¿åƒ¼üü1\ÿÞp¸< t…iÓ!–˜oMJ:éú5š 1šfšICãcFÙh.B a½ªŒ¶H¤IÜ'¥RŠ#«‚ FŠ A˜f¡ €[ @RH)ƒ âÐ ÜgÂ=Ì!©²¢‚¨B@ (.8x@“A‚{³À=0ƒPr ’‚ ¬’Æt«‰+]ýµÇß}“sgVæŒXoúíÅÝusóîZ–G'\ØnyàáG˜<þÍ•Çxü]oEëk¼úÕÏóê—^fñÚ2‰) Ö²,H)„VÜ+]#ì×Gû=ÃàhVj€Œ•”3}1:²Å #¥@é5ˆ¬ä,¨UP@4IÈ 4 ’€G"$PUÁTU¡:H@JÂ( A-Xî !ÐW§Ö ÉAN‚”*d Rkç­Í÷¦¶sáÂkßþrîÌÊœwOwöOšÕÝàhÿÝKsž¼û:EYß}‘q[¸°=cü¦7G_~é§›55oÈÎP*ꊦÌɆº3D‚nS0MŠÕ‚õ†ªà }%Ú€Ô(šmQ!g…†âARAÄ„{Ìs ©  *à  š@D‚¤‚&!‡Ð¶‚ôƒS R#¸V ðÀ ˜ ª  æÐð &"6¥²5w“¶šõGßÛ¦'¾å‰ø¹ÿþYçÜ™“9#ÖËe÷ÆQ¿>¨ÍfÓ³Xt¼ôÜsl|Éáþ]F²54¾azÎ9™3bïòâøè”{˜·¿ÿ}'¬_¡ñ[·^_á}Ç|žyßæhÎç~cÅíKˆÀMú&B#Ž ¨:á !PqÐ,äQ¸9¥8VjmœÑXÈS¥ÍŠf[ ük"(‚&A ÜÁ]ˆP„{$E ‰"Iðô) #qÇ0 x¨š!©P $ ªƒh"æ³d£Q]ª¥Ã&åƒÍbyéòUýŸÎ~è9wædΈÉd:<ôÄ#u2ºÌÛßõÞýî÷ó_üß¹}ý&X¡I™ìÕð*”¾PŠñðc[t«žZPÜ•†¦iiµà]Ïz]éŠã:Cg„ƒhÕ·¤ÐŒ Éà¥8fAx@xÂ=Hà„sЈ(„ „Xó€è‡@"Ðaàxî Šm†e¸Ã¨…Q#a.u¨”f¤k+~Ü´r¬ªCé—zñ/ÿò/ü­Õü{?êœ;S2gDã¾ÿ™gÚ‡®}:Cëlm]d<ŒY1ÐQú%DOÙ³;ßc}R¸ñâ@bŠe¨´S¥*µlð ’7°b 'ã6Ñ/ A)G`m+h«ŒGÊ… êÁ08]IÁÂA’„ႈ""¡ B8`n!49‘<(ÕÇ=h“$šÑ <<¨ˆ” m5DÔºÊ Mî"8U‰Ó,zÒätÔ¯N/Lç;ך¬Ç@ǹ3%sF$²¯©‘·ZªC­T©ƒqr¸"µ^ ª•åbà ÏÞÁMÙl f–AŒÍ¦°Þ! :''e<ÎXWháòÞ˜åb AÈ-¤$DªB!ðʤT…ñHÉ”˜5@ÂA$PÍT TH$î³UABˆ"@€¾:µMVB‚npîÛ™·d1ÊP)]q PIDÎP!fc‰¶Uw'†ÊFD69ë t£šz‘Ô…É’ §O,û×ÿÚ|°ÿ»?ûçÎŒÌÑ 7O^?ìNvïÌ–k×wÑÅ)ïxËÃäͯ½z0º~`1[[cT3x¦lŒa¨˜;h@‚¤BBIM¢Fœœ¯Áñá†é8#Vœpp,@Tw4T ªH0  P €ˆ`uL ‚bPÞ¨¹éTQu܃Ñ(J°©•Å+lj@¹!T%T‰”ÄŠ‡çFÍB£b@Òz6iŽEó¢FZVãPˆÃ¨~ Èrºb—ßü–wþø]þÓûçÜ™9#&yòÅXØ'—ëå¥n¹âàÆ-tu‡Ggc.^ÞåÎí}–§ëU¥ïœõÊp-JB4‘“Rè½ÓG¥¢d̹/'ÁsG$ QÀ]H€"Á0î€@›܃!€@ © €¨(BN‚ª€Y@€˜;›Mào…2^AR–È™H"–[©m£5{Tj šR7ŒNÚ6­„´@óI;…Üä®Y,Ä|è»õ4iÌ÷v.-ÿÇ_ü‰þßùÁ¿œû†Ëœ[íôÕq_o¿rýM¯¿~“ƒÕ;ã%69e>u¶çsÊ:0mÑ\ wú:àTœŠH (I”$-"c¢M‰$âT ÷`p§M 9ƒ‡ @Tˆp,‚" 4IÐ ˜ƒ;ˆ€"¼!%AUxƒ@ˆ"" îàîàB`&¸Aõ@"‚jPJI…S3epÓ"’»ÜŠmz+Êl6:EäÔIGMjŽSÒW#äÐŒÛ~·ÃjJ麵lo_Þî{«¢ÉsßpÂò“ÿÝOüÒ ú}×Ýë¯_§®^ãê䄨…»·×¬Nzjq"Âè6e¨ÅúŠ49“sBB¯D^Üqs¼:A΂(÷¨’P³ X`5˜d…&áA˜ IAœà¾œ„¤‚(D€ B›¡+Nß;ä,(`àÕ< !©DÊjM’N’ö@UeÈ9õ½¦f´6YN@o¦œOš¦ÙO*û)ékãQ¾3´«ÙtºžÌæÇ³íù0šÎc2ÛþÊ_ý™Â¹3!s†ŒMýîú˜'Ÿz}wÀ³/².w‘úMÅ x ÜÞ€C P Ucè*ePÜ@DÁ¹Çr5„„Ep… €!ˆ€ ‚Â}€Cxà&ˆeŠ)"¨@B! Ì ªV#D„Q£‘³âjŠ‹h¯"Ç’d!’ D©Žä&w)¥‚êä¸iÛ;)é~›õ5 ^'ä¦YÔZm1 Ãéõ~½çÜ™”9C.ì\üƒ/¿üÒwß|é:;;;qñÒE^=¤t”ℵV Ü…ŒZ«Ax IH"˜µ5@%HIhš„h â¨ IÀ<ðâÔ˜÷) "ä¤Xu D„& I "H" €€ˆ  "´­!t½aî¨M#`Õ)î„A“…6iDŽH¢!ª®*®Y ʆÐNDNEt-B2ˆ†EЫè²öÍâDDsÎÏ{ÄMBO$项¯ÿÛ_úòšsgZæ yèÁÇž½|ýëwn½|ýJÞN1›mEÝz¾9‘®œÊЭ%R©Q×Nª ¬A‰A±ZH#g2†ÑØ6 à ŒœAî Pp•‰ÿ›=8¶ü< ;ÿ}ž÷ýýÎ9wßz_Ô{ËÚemF–lY6¶ ØxCŽ™Ša¦f†)òÇ05ƒ§RÌT¦(H ’P•™3¶Èƶ°lÙ²vÉÚzSïÝ·o¯w_Î=çü–÷}Ÿiaœ€…C‘ª+»?Aƒ!‰o‰`f„($b†Ä ˜§Š ˆª‚(WfÆŸ!šQ‡Ú‚%AÄ0DÓ$^Í103óNMD¢ŠTâµ'ªÁTº•%*Qí)R$K¥s®'°ªê–¼êl–å³Nå’Yšu‹†Í tÿàO'®Yó„5æw?ûÿüþ±Ó>4³8›÷ºKI«B$UÒ«W¥Óéh( )Ëš^»"ÃE'¤Ò¨Bñ|fXòÄÚRÄH  b ª €K†ª‰€%HшœÞ%Kˆ‰ä¹â½`€"’ÌL’bb1™„d&Žàœr•zçHÑT„¤¨¨0Rˆ–bJ–y_ç^+ОˆD­L­çÔõbJªÚU‘¶ª›uKNÜR–eW|î/‹èRJaÚDÚŸùâÑU®yÓð¬1‡[nfoŸ]?=ÝMKÅŠ Q2ÉɹB•¾©J­¢$³\Å÷Þ…˜¨£E§ÞwÉ1Y´”j3"&]U­ZY–-"ïüŠ`¥z×Åf¬¤d•:·¢¢í$tœI;ÅP„:ô¸æMOXÃùÜoþ÷3Kçî[\YmTEY„êª Y§[åE§è«ë4`F#óY%âRU•yQ”MzuÑi„ºÌ±T!ÆäSLÒë>%–ˆ!&3SA¢H"8‡„,÷Ñ;ê$y§1ĨFJ†˜G¨0 ".xï:Îù*Æ8 â‚ˆVâ´“ÌpÞ× Ñ@c²˜R2H;¥dˆí¨÷sÞipÎÕê¤L‰ÂUA 6"=3JYzÿ꟩¹æû‚g Ývh±s¹¿™å›ÅÄ\ˆ)†"óûy³Ì2zªÞ©ød–ÐL)õ‹Pä~8ÕU/Ï%"©.Ë&Éó†Æºv!BU‹™E§®RÌ©:sêÌ;1ç½eÞUª")ѺΜjQB] ‰j)bháœ+T$yïgTB7漯œs1Uˆ3|Š–Tu1ÆX¤„Šh©^Wœ÷Fi&¥§Z€ö€RDj ó;Ÿz²Ë5ßW„5î‹_ü§ï›½¸¯ª«¾ÕN×u;½–¥äªÊòRޏ¦%fCTUÕ0RR¬²Q‘R uåC¨}¨k_U½ê –’‰Š©¸ž`*ÈUê2ç|ÞÈK…a¤P;0qÞ/ ¸d&‚YJVÇ’aæœ+E´ÈT½ÔfÔ¢Z¨s¥ª+cJvU!zÐÕ”,¤½¨ëzçÛ"ÚERZ«JRƒT@ODêþ{—\ó}dzÆmÚt׳u¯J«Ý•Ífšy—iJ±UuQÔ-‹Ú¶d^¯ ¡Ê˺R5IBJ™sUQ §NšÍf4#†ºÖn·£uUx§Z›É*b©¡¢êœªŠwYm€k¶*çC,†‰JPÕ"¥R¸ª΄¤ê ’)ª ¨”ª¾ÑRÍ’ˆöœÎôBH朶E´*Q)’ª$CF”¿õ¯K\ó}Ixxî™/ì™›;±®ÛYît{Ú+{P×}eY·R'ø\ÔÕ)FRŠR×U–bTUŸò¼±j¡ÊêªtÎùnŒ¥+‹ÒêªÒ²ì6ʲ,Õ`µSU§ê¼ó8¯R‹‚ö ©AUjQ©bŒcˆeQú”¢*1å*Ñ(Î÷œÏ: ¤”Ôp…ˆ…-ô’¥TQÀL–0‰"ÄßüW_)Y#>ô¡ ê¿zËþ­]¸|åàÉÅcÏ=Û~˜Ú\ó·âyÈ›#§ÇFwÔ"—WŒ¥–¨úàË–SïB°Ó ´—|&¡N]FJ•S4¨ªˆkI#o3 U¥-ðÁ9$¥$€Ã’˜™ŠHðê*Mr•sNÕ9s‚šsE5¨Zˆ)U"b"bÁÇ\#ŠHÀ )ÌÈU})ªµˆv1'EÔ’‹˜E‡&3«Í0I"f8á×çÏJÖˆûî#»kb]þ«wÜrÏ;Þþ¶·¶¦&/ßñÂ+>ºyÓä §O/~éòe¾:3SžVÄ5ß3áMâ…çitV§‡;•¾^¯£EYäu]JY…¼ª’`˜¡QHÔ!x33‡)r•M`ÎbB¬I±¦ÛíjÙ뉈õRŒ–Ì 3ñJ.¢QÕyç48çDU^—THV¥«b CSŠ)†¤1ÅÌ»l!˜‰š™¨ºuUJ&‚Dƒdf€ðý‹/–¬a{öïß?ú[÷Ý{ÓÞvóÛnØ{U] î*§'Oóê‘£sO>}àp·#_xþù•/W€%®ùžo"Ï>ýp³Ýži•eá{½NV–¥ ¡ªŠ"d)RBRJ„ÒUÞ®J)šSÞe˜Y ÅšC,Ë2VeORŒ)„ZR ˜%õNQQ'*8çð¢"’ˆ W™¨XŒ¡Ž!XŠW…h†!ââ¯ýö#%WýÏ¿øù'¿óUãM衇6Ü<1Fž9žyñy>¼òâ+§ž¹t®zøðñîW€+@—kÞð&óÄ×~¿Ñ+Véõº”UIŒ5?ùÓ¿ZrÍß©Ÿxhýö÷þ“÷?xÇÞöÝØ¨«!T¸J¨c@œóˆc#ôªEŽŸ>ÎÏ>ÿèoþÆñÿx8t¹æ»ò¼É¼ãÁŸ.¹æ¿¨Ÿxhâã}æÿúà}÷ßtç­wQ‡‘HŸó$ KBÃ<®®#Ëíë'6³q]Iæ^Ý ¼ˆÀ<0Å5ß•çšk¾Ã>0ñŽ ã~í‡ßýàž›¯¿‘•ö "‰”ŒUŒÞ+ªŽFÞ ¦‚^}š?úü7VŸyö|Æx®yCžk®ù¶þFêï¹ç¶]·ßt Ë+‹¨Þg„Á9%Æ„s ªŽ,oðÕ¯~)=õÌ¡¹C‡Ús§N €çšï‰çšk¾E>øãë~ù{ïùØÛï¹[‹^ 3Ã,àœàœ#¥Äëœz¼Ï©c/>ú þí>uñ¥»gÌ0`Xâšï‰çšx}/Œÿïwßvëÿpß=øºTʪäu"Pד ò̑eM.\9ÁW¶zä‘C—î]0#sÀ0\–¸æ y®ùA'O=ÙÜõsÿõMz÷»îßÊj{UQ¥,+Ê²Æ ÷ã½§ÙèçkO~•G¿þõÙçž]¾|î\µÀ·\N³Àyà%`kÞãštÚn‡ëzåÜÖ‹Ó§†V»Ó}Cƒ ßß7Lž7„ꄾV?ÑyòÙÇëÏüÑ3‹O?½pöòåz¨€óÀyàð4p˜áš¿‘ãštl¸t©n½öZ{èÐá³ñÄ™³Öî̵’™¸F›‘Á 2>>ÊâòúÈ#õ¿ûƒgO<¸zqq1À,0 œÎÏ'6×|O„k~Ð)p+ðN`°N„‘;ó¹áƾÑí›vnÚ:ÌÅK³ñ‰'NÍ8Ð;`8LçƒÀE ð_ÐÇ?0~ûªÕj–È2cd¤IJÆŸ({PV%F#}æÓ Çù–.k”ð}졇¶LüOÿð~ ³ý¿þ/ÿù¿Ù¸nhÏð¸»Î©#Ö‘*@¯·:wøPû±™™bùرzH@àïØG?:6S»qýþ Z-Ç'?ya‘o |~ê§šëúúG)Vë÷4úúïÀ”$†ÄDJBŒf³ +ONž]Ô~d¼‘Ÿ|ø+óÏ%Ðåoé÷®¿¸RMl”M£cn¬ªdÇøðuï¸í¶u·ÌÌÎ/=ü¹cÿìàÁîqà5 ËwñÁ6ÆClþìÇ>|ç¯_œªOmØì6ìÞ±op µ‘N·bHôÂeΜ¼|èÈ¥•“§g»p¾øÂ™3Õ!`¨xcL[€ë€MÀ:`` å[ÒÄDVnܘ·ßõàÄ…ç¿¶pà…ÃíÇ€ èò·ôŽn‰‘;SJü7ŸøØÃSÎpúÜÙ§·nܾa÷žu;·ß0ÜÌÆñN ©ÀÑ¥DŒç uŽº®d||˜Å•Ë,ÎÕ\œžäĹg^ú§¿yú÷.]*¯mÖÏ›—üÒ/m¿¯ ÿHî7ŒŽø›Ç‡wî+WŽUý}wݲYî¿ëÆ;«²Ÿuë†I1ÐëDpÞ¢ûw¾ödÛf–Nl}å-Gœ}æLïQà8Ðá»3`X.ë½€Û¸1Û[×Ök6õò®ÝÍmÛ6OìÚ·xó¾]7m›X¶å /}þ…ÃíœN]¾G?ñãcw5ZòÑ‘‰‰í£cÙž­vÝ:Ð?ÁÄÈz&FÖó¶»îxûu›÷Q×ÔeA#’rÌPÃ+¤‰DÌÝ¢$.Ô¤TS×ÊÐÐ7ÜÉÌÜ•ÝUuâFÀ€.p¨Y280D]B0bŠTUM§½LŒ}}91¯³P¢CMY€óÊPë:yàÞí~vÿ¹Ý[®;ðËO<~äÈSÏ-ÿ³™™òpˆãë·søà§þÍßÿè;®ª^#ßÜ™ë´{ô¶ÂÇ?ü÷~mx`sêɲ>Sšµ'†@J1øÕî*¾‘²í¦f“tÿýc[o¹¹õ‰¡‘Mïoåëš›7ö˶Í7¶ò-¬vzˆE6m\o8Êr•¢ªˆUÄg (e¯ÄeŽÒz¼nxpŒ¼ïÇüuÛ7Ý64òhöÙO_ô33u8tø¶G¹/O©÷3CC}Cu `†q•…“gwÏÌ4ß§¬kŽ¶Ø²­Ù?1ºkhxp”f¶ŽÃ§?WŸ½ØíÞŒ+ÀÞÀÛÞF¶eëÄÍÜýüžÝ[Þ¿w׎ÝoÙ¿Ÿf>Á@ßEY2·°B]úÃôŠF$ÄH]'TÁçJ¨Î Î+1Ï”!Ë"Ý^E³Y‘ûHà÷ÿøÓö¹/è®®†MÀE ÅâyùÕO/.òÆëw}l÷®½Û®Ûr±RB,a¥Ó¡.kÁİ”p^ !’˜Î )Qù6#Ä’TÁ¦õ{Øý}ÃÊÀÍ-}ef¦üc@€ã?òþÿq÷;ß9ò+™nŠïyà7&ýÓÕ<ëG‡Q*DX"EX)"!öP…”@ÄPúÙ¾©%;vf{wïÚ¶ó¾·ÝrÝ {÷¹±‘1ù0½¢¤(JVVVñ™266‚o@UEM4Ã;GŒ 0œWD…P¢ µté»¶Üăo_ºñÊ¥¯}ü›ßlçSSe¼tùÇÿø•Ýÿ'îû_Þ÷àƒ×uº%f çTÁ̸ëÖÀ@ÿ^‡QQºÝ‚²,¨ëÄÒâ 3sÝúôùî° 8ÎßàC½«¯O?rËÍ»>zýž}{wn¾¡d‘Õv—…Ùeze(Œ 04Ò %£Û„ñž«”º6œWÄ)!&êh8…” ç@0œs4Z_}òqþäá—/½úrçlY[Æäx“øGÿhó‹C¿}ËMoý¹»n}pddx ¡Tu‰ª` ÃPE’¢N‰1cDUȽÃRŒ`‚ˆ " R „ÚØ¼i“TqvâÒå¥Îü|ÝæwáB‘uzÓ}seýº±uÎ,Ñ×§T±Ä,!€¨b)êšdIPªBHJÏ»•ÎRßCüÐÄm×ߤÄnI¯êÑn·)Š‚ÑÑFFúÉrO#UYÍðNq^0¼ó8/¤d$TATˆÉ0"Ã×Ñ×j®¿xå¼?;Ù›°ØÊŠÝØéÍß6:’mݹm¿z×É“b†ÓÄ µ&UeTeIzTuX"¦D¨„©‹gëÇŸ8{¹ÓIçKÀ9`‘ÿÄýXkâî{Æ>¶sûöùÎwÜûþzë;ÖmÙF§SÒî¬S¤,EY10ÐdÝúQúú[ˆ:êÚ1¢ª¨STð™Ã’a€ˆ*†àTidfÊŸ}íIþäsO_9t¸3Õ馘¦)à"Xo;w2´oÿèo¼í®w~âÎ[ß)X¢({H2ò¦'óK DÎ5hæMšýŽf_¤™ b¦¤”0 f†Ët¢~þ…É uÍàpˆ|ÛOþÔÄí±ÎㇼÿÇßûÀû[Îè]ªº¦×«ˆ$Tã€âó&¢O=û¬ýág>·òGŸÿÆ¥g^xaåâÌdf©ÎÇF†èoÑjôS$ÆD"aRЍs öóÍC/ðé?~lúå—V&;TÓÀ9`x8ÖÏÚ–/,ò‹ÜûîpëMwCDI$ €QLjFÅ{O³Õàðу<öÄ“«ß|áÜÌ©SÅ|¯Œq`Ðg{wöoß9ѺçŽÝ·ßt¿Ë\NuI1ò:õ— )1Ú««Ü|ã[ÜÝ}ðŽãGÚGç—ÒàYÀ‡@}ìhÇf¦‹›~ÞýÌOLŒn¡Wô¨CDDðê0 q•Ä(ÊH#1##ý¨*EYcNÙ0:BÿþOŽÏ0‘’'T%&BJ D3p>#o¾úÄ×í³ü•…gŸŸžzù•ΕÕNªËÒVÛ+±;9UÌ<¸°<·8íF‡ýðM7\O++òÌ‘å „„ˆ`&„h¤\GVòCG'Ëééú2°FßëÙòêJݧžMû÷nÕŒ""NÀ@0ª)»%Ýn…a 4ì§ÑÌ(ª ïu™g¡}‡¿øèêßeú‰'–O9²<÷ÚÑ©Îù‹¯™óÙÀ×_OUפQçpNÁÀ0ÌŒAT0¯ÊÐð?u4œ8¹xÂŒ0œÚÀàâB(–W–×ohl¸å†[´Û-PÅ©"€¨BžeÔ!‘çžW®_zåâ…ºæ0 \"W½÷}ÿôžwíû¹wÞw_ÿÒ|—…åUBék5j28ÐGQš¹§Ùèãñçžá?ýÈ̾páìÙ³Õ|QX ´‹Nœ¿x¡ì<¸Ô>räÂÊ /èÌ.œuÞ§ææÍã4óaT„N¹Èy.~ùËgÎMO×m`8 œ^Ž%kŒcÚ¼™w¾uË'¸÷}÷ l¦¬+0#¥HJÆëT!Ë2úûûyþå'ãÿý»ž}æÉåÉK—«Ð.“ÀY`¨ââüòž¾zð†}׋wŠ÷J!DTÌ€„:‡Š02ÚÒc'ŽöŸ9Õ=¢uIà"¥åÐî•s7ìŸX·iãN­BŠ ˆc¢(J¼w µèkµÈ›KÐé–TuÍ`?Hƒ“§ðŸ}tþwïèÉsçª930³¼œf/_®m©=ÝjöíÞ±‹¯ê”À@U0PuJ¦}¼rð•âàá¹+)q¸\–­k¤o Üyó ;úú‡5b0PÀ€”Œª½@d†¯=ùÙƒ{WRâ<0 \âG>:öÐ]wìùä{üáe·EQ– 4è£ÙÈ…¢¨©ŠÈú ã<ýü7ù÷òՅ翹097W಼9ÜHreØlßö†€;sº8vääÔ[n»åí.ó Ì B©ËÈè†~2ï(Š€•BÉ §yÞDZ³ßà³?>ógΞ_\Œ Ì§[X3,.yý—n¿õ¦Mòl!T¤bF2CD !`yîP5pÆžý 70 Ë‹ÆwˆÀEàÂÊJ=vlîЫG½óÝïø{Zt*²L0Rˆ B¬#1œ: gqÑ–B°Èwèïgý@_ßÏßqë}[ZÙF.Í\ax´EƒªˆÔu$¦Dˆ‘V_‹'žÿŸúôWçX™š «À 0\®S@Ø ôÀh»mC¯¼²:777Õ=|è6ÜxÓóÙäÔL}n²Z0#óÀà%àP±FyÖ {îÜ{Ó ¹ïž·feaTUðÞ¡*XJdyN»w™¯=ýèÒc_¿xîâ¥j˜.ÓÀià0°Œ}À=1’:4}âðá£#ïºÿº<ÆH–9Ì ¨CTLi5œ˜±hžo™°ue%:òÚÉó³ïšÛ=Ð×GUVTU:¥ — N½^8±2²Li6ú¹xåÿé3_øâ•³KK©Ìg€9`X6^¹Rõ\¿t¹Ø°{‡REg„`˜%^×È!& °”®Û6>´}sÿúÅŶúPKÀË@ÿÙ3Ŏ¾ãÝ÷ß3”åýXŒT1c"Ö‰˜1ýý –;P«–€À·½õޱÜqûÞ»÷íÜÅÒÒ I Ï3ê*PÇ@æ3bŒ4²½ªÇãO¾Ú~î¹¥³ ¡,SÀYà5à°8àÐ솀õÀúóç‹™ ®¬ÿÆ“WFR3jà 0Ì“@ÁæY{ü[nh½ï†ý×ßÞ×ÜB{u ÌÀeU SAòâ ¯¤G¿|iúô©bè3À1àpXà[Ú€ç[tf¦87µüÖn¯—7ÁŒXEPp^Qu¼ÎHTeMÞPTñüUÓÀsU•²‹—ªóó‹gvÞ©"óÌH1Ñj5ˆ1QU!!Òj5HVóØ7ž/¿ò•™KKK©Ìç)à0pXö™ˆÎXÀ¨SÄ‹¢ ))ªŠä™#…„`˜­¾ˆ9`Øœ.ó-sÀ™Ù~òôÌÔùË37nÛ´GºeA F¨½²Æ{¥®"B"u•¸j ˜憇ºù–áßýÖ;†C ¡¦Ùð8½ª"¥„YMŒ¡Ç“ß|">óìùÙÅÅÐæ€)` 8¼¬ò—:€—`;°XgF7FÖ9P³ÀIà`5γö oX7ñ¡Ý;÷÷z]ÀIX‚„ 8@x]U:zrþøñÞ4°œf)à5 Ë,'Ø’®êt Rªìü‘HCUˆµaÎÀøn ˜f/]ì>qæøíûwÞ9\:AÔcÄb"Ï=ÉŒªJÖp 4ûàëO}™G}åÊ… Õ0œ¦€CÀ«À*`À!@GFü[ #FÉyG]GD")AL‰V#ÃB2´ÌN/XÙK寪óÝnšºt%¾¶²\ßè·)%ÌŒ²¬qÞÑhd@M³™á€ß¶ÌßzÛðG÷lßõžë¶Ói—ĔȜGPU3£Ñp  °´z'ž>:sè`g hgsÀàU`•¿Ê€%` ˜&·=à4©æcó¬1üàúvïØzϺ‘ëXXZA,¯‹!S°DŠFàüT'õ÷«úLW†ýüà ¿øÞ÷ _é÷vÛ¥+î#’5ú±ˆªÃ9à T…å•ÎΡÑfžeÊâbI«ÕÄ;ÅD%˜xïñÞñ àòìl=9u®ˆÉ”ºª‰Á@@D#wŽ¡¡^ CptºÓ<÷òÁ…Ç{¸ L/G6i8µecƒFÓ¨C$Ë<Î)½^…ˆ`–p 1e]b ¼opìt{iò|ožïn¸T¡¨ªœ:òL)z}} ò†G$ ¥Äwºùæ|htÔìú=û«íšn·‡ˆ*ÂÀ`'Uh62î•êÕWfÌ3Àà% Í߬.]àó—*àPð&àY[†‡GíGÖoɪÊðÞ“bàuN Dp!ê•ÀÛïÝ?q÷]»Zͼ±¿Ñ'Užúû3ÆFrq2´}hpªâK‘#†a˜Ñíö¤ªjÐÈëb°DÑ- 1ò°¤ÊjŒR4B2‚^”¼™£êP¯P%ꘄ¾¾&MÏ>sivu5UÀ`8œÚü'n¹µ¹eÃÆ‘;7n‚ÄUFYVTUÀ{ÅÌðY†˜á³ ¯J£•s~ª¦ –€À_/ó>³ì*1)ëŠj97=<£‰fžA‚PG„¿Ô^µí×ï~Ë-{wÝÀÂÂ1>÷xïYrÔuB2OJš©ÏŸ/ÛÀ p¸ œVùϳ,óWožµCöïÏ7¬{`ÝØ†|eµÍÀ`N·“Ì1%Ì 3å·½ßå¹Rõ˜%ª2åÍNŒdPGT CÔ“B…1&œwt{%F†s ¦„* âHfÔVÑY ¤Ä™Ïs½¤N£óÐÈr H1a"BUFª:¢ªøL1*Žz-,.¦.°\.G€%þª¦7NŒ]·AlíÕyTïAD”FÓ¡êx]ª#yÞÇÅ˧Y˜›é‰° ̈üÇ"0“eÒŽ)ë@Õ«1¾þŒ˜Ã0¾ÓبÛ9±~À‰zšÍŒ8§TU¢®†ÑÈZLN°WŸš/ËÔfYàE` 0þóobžµC—Âz¥‘ of¹½Læ'ŠfŽ"u(Ëç.s¨3RìQ”‚wŠ(T! Þã‚'˜£!˜ÎED †ˆàœÐhd¸1b€˜ úšJ¨ WÍR¥NáTÎIÏ ¨:|îI)‚sD¨C@b–ȲËíe^zõüü… Õ"0LG€‹üõ²½û‡~øÖ›w­W©É2sŠsJJÎ)^‘«ÌUZ­ŒÃGÏÔÇO´çb$KÀ`žïBLˆÉ1Ò××@ÅQW5"RB=¤”@øöïºÿ¦·l73DÌÈœCB]c("à½ãÔ¹3vn2,™Q À%`0~)kÈÀ@.Û¶5¤™gä™Rô*BˆX4Ê¢¦,k²ÌÑlfäNidž,Ëð*„˜ˆ œ%¥„:%˯ шÑ03RÄŒ” Eh6s|æq–Œ¢J¨x¦gg©S 3ei‘¿AN³HÑ AÀŒˆ€ˆÐ×jqâìQÎ_œïX¦ @Í_ãþw >°gçæ÷íݽ,á½#ÆHŠ EDI€ˆ’eY–±¸¸À¡Ã¯UUm%P$ ñ]$ŒXE²†§Õʉ±Æ$¡^ñª8…d€ñ¤ØÚ¸iý>RªHIÉ0 H\¥ *„8yêìü•ËÕ"0ô€y`…Pž5dd¤Ñܰ%§Ì;ê˜h¯ö@ †GúÉ-CDÀâATqÁ Lˆ!"™§¡Jˆ‰ˆr•cBÕÓÈÎ)¹­f“ªªq>#Ï '©jº½’±Ñ–– ÎM–«@ä{`"ààÄcj`y‡*¨xœÏ8q|ºwâx1Ì @èò׸í¶|ÛØ¸|üí÷Ü>ÞÈXé® €ŠÃHˆ@ŒSOž)Šà ;À«¯ÌÌL‡e`è=¾ z½šh‘ÞyªP„ R$!ň÷Ê_èëóÊU1%L ÏN•d†óð>#†ÄäT/ÄHY`ˆü€ò¬zçÞÁwŒ¬ÛbLŒ˜"fFQÖŒH?N!Fï=y®ˆ"F]GRJôõ5A”,w”½š~EE¨cÄ©âìðï,÷Þîžž}3Ø7b!H€7p‘HA)–lÉ2-ÛŠd¹¼$Q•_ã‡äÅ•‡äÝ/©ÊkR•J•å$¶dG%Šâ IÄÌ3ÀlÝÓ3½ÝõœR Eq)•]ãRŸFDp–¹8uº•çR] \Vù%<@ßäØà~üÈ‘¯ïØv»Zm¶q…Ë d™C¼' ”Aá<¸¬Ë /¿Þ¹p¾»d@˜áƒ(P úªeò,%ËrD@iœ@Q8‚À`ÅÏML„X£Fi´Q€ïÑZsS^8DEžsCh  ¿¡,kǘ/dS 'T’äyAQ8J¥ˆÛ åj ÎS«ÍóÜÑŸ¦q[œ¶¥@œ¶wÇÞÍîÜGd«Ô–(_±ä΃F)ânеš0 ¨”ÊdYÊ·¿ûŒûÎ÷Ž^:w6n4y ¬Wyà0·à=ˆRh­p…GkµŠ¸“ÐnÆŒ  l¦nÔ"3`te5§ÙŽÁ ¥j‰RP*ˆ7¹ÂS*…äYH¨,ÿÔþð«ãwgYöç?pðkwßùøÐ÷ŸùñõãÇ_[æ€W+€c °¬!^9â¼²/œÇ‰G¼ÇZR ç ¥°Ö¢8ÆXÒ,¡Ùn32:ˆÂའ•…Å„rR©FˆÎy ç) Q 'V˜À04jŒR(þI|á _ìø«¾÷ =ÂR­Î«¯n×Ýœ®3€c °¬! ÉÕ…ÅÙxëäƒå0´8ç@ ð€Iš#…'/­vÌž][K»w l;}ºk(+üš¾ù;þ$­>µ}Ó¦¿|äÁ'†oÛyÏý1/¼xµµ°õ††0<Fyn( ‡÷Ap¢(œC ‡B¾ðùO<|pç亷ôm!° ï¡Û‰“„( pÎsSQxÚ­˜,uYA¹2>ZÅ–“ç_à|ëé¥W^Y^Yq] à2°,'ן€R ¥ÆD-Ž04(Ñn%´›1Þs“æ†å†GY‚4Kq΂Gï)rÂÑ×WfÿÛG·m»615•jÀ ~MòåÉõ —c÷íc_}ôð‘C{o;Àr=åÙ£/úãÇk­vÛ †5Ʋ†œ8ߺ<=Óí}×ã‡öÞÂêj^~½yêdsÈø6 JBžxQ8PÜà=Rx”ç…uC{X?bCOž§ä© xÐP.ˆ(Dc-A K¹,disQŠ4+HÒ.ó ­´Ñp  ,3Àà*p hò±@/¼C(¼Ç{1/€R(£ïøÿòUj+çzTRP€ ç¹Éhʰ}Ó52úÂØÔcÀmÀu Á¯'ªKû?>ñØ‘û™GÑg'È‹œ$_æøñ‹õ âE f ²¬!IR°p-u64èXƒ‡c ðŠÂ#^„{öo?spឣ¯´ÎU@žOèßýåm;VVV¿´mËäݱ玻ï=ðˆjuºyÁÙ §ü˯\®­®º XV€Œ_P­„ˆ²¼qh­PJ£´`…VP¸ç<) E„” ­A ¼ÖŒÖh¥ð²ÌR$qŽ61Õ¾*wíyŒ¯ünsr`àõ¥S'“³F>,¯×„OHk¼­Aœ`4c)PZEm?77[œ;{náS»·érQhJ)Dc4&ÐBš&ìݵM?xxëÖ+Ó—vÔjÅ4Ð4ø}å÷Çþt綉§vïÝúÄC‡>ÞÑ;ô÷÷óÖÅKœ?7Ÿx–€U a ±¬í Ð+Êú,ËW0A€Ë2Á ¸©ðà¼C­iî9xð^ýÂkg·]¼ÔÝZ¯»°Ìñ1}éKØ‘Áõ_J[þ?¸sô¾ƒJûöÞN`C²,F£0!´Q ¥%wSòÜÑí¤4IÒÅå)w8Èèhert仿ý“ŸÌŽ_¹Òýß33ù€% åc4X£ñ^ðÜàQ‚(…R c "0VçX¼6“]:~âô]_xb«’ ¼÷8'hxHóƒ—”¾r•/>ùùakÝ#?zfÎ.Ì'vz:ý1°¤ü’æ­ßÙ¥óµ‰uÃð©îÛ~çÞýa_¥J‘9<1ˆÇhÀi¼÷;q,šê.Šu :€°†XÖòdwúĉËWöíšÞµ{ç^ºqW8PkMšzºÝ k5µZƒR¹ÂÃ÷=nݼþÀÙó§7_ž®ãü¥ég–ëòêà ^Ž!Šô]ÖO<µgçæÍ;¶Ý6¾~Ý6òÌe ­f­y›RŠ( Xi^àØ›¯4®\‰WÐjÀ2 ¼×%µ¿¿KÅO^ÖX!/ à½`­AÛÆ”»Ï=?ñâ¥öŸ=5öàýûÖ¾çŽÒá{ïÃXKÇäyx‡µ£®ðtã„À(â8&Ë4Õjk Z+ºq‡õãÛøúï}ubrìä—þáû?\Zj˜$ápH¹…( Pʓ瞷i0(nÒZ#xŒe ÃÃÕüÌòôtòÆë'.¾ïÐ}›ÆFÆh·Zxñ(¥1FQÒJ)ŒV¤i‡‘¡m|í+_[·~â/Ÿ>}úîã'§žœ»®þöê•äU`H¹áɧ†n=Q¾aKðÅûö}z÷Ûw³aýf²4Æ)‚P8ÁåiZ`­¡ˆ[{e1»ž·€e`˜–Yc,k‡æÅÓgë'O=»åÀ‡¢,ÏqΡ57hrWÐ\ma´býúa|!$YÎÜÜ•h3O¹k8ÍV†ß|ëÌ7º]÷GQdD)0(J}›7n Ë¥1Ò¤K ¢ $Ý(ŒµhÆœ9·È /4–Ûmß:0 ´y¿ª1¥h¤ºă(0à2‡B¡ÆZ1k5¥(@)â¹¹ìÚâ"ã×gOÖ_ãÂÄé³çG>õÐý¥=·mÃÚ2I’r“XivH“Œ›F°A@ÜMi5¼x††úÐÆ±²ƒ·yøÖM¸Ooß~jÃk¯Íþä•£ÿÌ‹|ˆ;£þÉI{hlÄøxˆ 4ÍÕIœ³nbPJ¡BÃûËëÖƒss97¼l6KÀøÉÉÒ•é©m..íxôÓWÖݳÿÎ`Ƕíô÷÷Ójµ¸©(<^T*õܳ?iîévc@ðÞc äNÈŠ„’.!"(­ñâÈs!'£ÓIévR¢@Sí/‘¦9Ê{œïZ)†G‚ À( BNœy+W;]P%@Xƒ kOÀp§ããééNÖM¯ôGÝ?X­ªje”á±~ð‚ ( ‡÷£4Z+”6Ü”XJQH·“’$9ÎyŒ6X«ˆ¢€¨â½ÆjËØøˆÂF~òÒ›?øÁâlûàp¸ ¤|°¡ßyjý»wܳ/îd« È=7)£°ÆžRЇ“"xéè™Æâb~XŽu b NSq³3iûÊÕwm~J¢r§²cûvUûɲœ"/0Ö`­Q« ç'”Êiš±²Ú%Ë[6læÞƒû‡7n? í¢9q¢•-  Þxòß<ùÙ#‡¬ŠHÒ­5Öµïc4Õ>ÃâòTxáâò|«åÎWëÀx»íUc5–ËS—J^7Ê;¶®×¥h­@”RXhM) qˆ€Ñk I’Óm'ä¹gt|˜¡Á!ŒŽ‚Õô•+ T)WJå.¥2Ø @Hùî_î>ý£ËW;˜.瀌5ȲöÀÞáëõÜ~ûïëjvæÇÉC‡ÏŽÝ}ðPÿÀà]ZDã²c T 1:ÀhZ! ânï5"kª¥åJ„Ö¼Ç{ˆIpFc”Fiay9åøñÕåz=o+À*0 4ùc£Ê%K• #‡Öe,ˆG  ¥Rˆ £ƒ› BãÀPÎsÀp8ÇòÔåduff~rv¶µýê•ÆÄC÷ßÛ·kçNJÑyž¡”Æ‹ d¹Ã……0P”ÊDýÕ HŠse¶lê' ÂMÀ>ޑѦõ•r_ßz¬ ¨–•JˆsçÖ„¡G”âmƒýClÞ°ßÅI ŒÛ—€³@ùÚlÆü\­½X{ißµkË:|¨ºkû>#B]Æ{Oᔢˆ¡ÓmÐéxVVcŒÉ ÔÊ0³p”ù¥Fv}&õívJž+ 'EF’]E¡P( ¯åè+‹õZ-ï]`˜:¬Q–µ).`WW½<óL½uòdsÇw^ݹãåjµ_3<06”‡+ƒƒ&˜ 0%<ŠB–äÌù©ÆÔtœ‰¢’fl,bt4ÄZs¼Má@)¼€ä‚ Z Ý®bæj³ ´€ÐV¸…éé¶'yÙÅI[¥n)n·ÒÕz£ ÙʰV3û螉];ö•úúÊôW,Jñ¶Â ^RŠ"w´ÛyxóÏ®ž?ŸÅ+«äµc«Ü°8hnØ`€¨2G}¹ð‹óm §Iâ ¥Æ<7ˆG+… 4ƒƒ%l¸,ÃÃÁàâb1Þq°€q}òD7žŸ;Yñè¥‰ÛÆ*wÝ52:¹n§ ìÎ9´Òh£Iâeæ–/´g®vÚ yæ‚€öìOšý€â†ª 6® ªÐ¼QŠé+q3+ÄñëY–€«@ƒ[øïÿíÒQc¦\î×w—ÍÏå>Àð°) ¥z=oóá®u ìjÀäÂBÞYXX™<ýÖñårù ;4lé¯ZŒÕ à=oóâ)RO£™“¥Bš FÑév}Æ»¿àGÿwfõ¥§ÿ¦1³°Ú<7Õ]ÉrxŠwoÓZš¾ª¦…rþ|ó^mà @)°²´T´—–šõžoöo~vvÐûÊXÖPž<Ó4›.nµ\‡ËÏ­Õp Xf ³¬m1pH¨ãÀÐÇ ÍvA³]”AÞoÈøÕµe`H¸…K—ÒpyG¬ðK G£áú>>Zœ–€Iàn ,ÏÏç‹À:¦ÒŸLè °Ä/ø›ï,<¯<&NÝ< ÜR—<ï׎ ÀA  ¬£33Y0 h>XhóÁÀ2àùh)p¸´YÃ,k_ œV€-Àf Ÿw•1 Êû­5 ãW7 ´¸5<0¬òލ+¼W?0”€6àùp¨  ì6@ 0|2 tx X6Ä]—m  Ô€ |aËsRGB®Îé pHYsr É÷tIMEÜ:;=i|#bKGDÿÿÿ ½§“[tIDATxÚí½ °lÛYö¯îÝóÜ}Æ{ÏÞÈ = $À %01abÛÁWÊÆ"e›`§JT\)bÀØŠ\.•Tˆ 4a1>„°¤'½ñÞwÏ=÷L=O{w÷Þ+ß¿†=ôpÎyOOO¢HKûõ¹=ìÞ{ýÓ÷KЫõxô›‰žý+/ßzìkéî3Ðÿh¼•¨Ås™ÊÍeÒiáAÇÒ—D‰\&C'Måb^ûè ù׿ýëåW~Åk¤Àç^͇”’Þÿá‹_xïo‹§^8ã‰KóÅ‚fó9ÞR¤¹‹¹\’æA ÇÝQBäáýó«sìßz+=¸û¯¼VŸ‹‡CŸçG®û™X<‘N‘ppð?ñ·”àwÓ©eÓªKôßþùÄ[“Ÿë6 'ë÷>Eÿøgþ˜Íz]ð# &pý)I"Ð÷”¸G<2yI~ÌÕ¯Çñ&}ì|Ñ·¼3|ç_H™º/ôGüÿçøõþEÜÓî7â7›ãË^æZ½ÂŒüª3/J§KÎÁuÊUJ4þè{ÂE{µÕøçëqŽûm™û-}å÷7Óâð>Q³Á/¾jêÿ Â|Žî‰”9Ò†ÑãÇ:æ—±çøá£},ÌñY=Z_`‹õÊ>ÞøF¢'Ÿ\ÿÞä–½’ø´˜Ïˆ2DoýAzÛÿø/é­oÿ²ÏF‹‰nVˆÊ%ÊUd2E€… ¤ÉzÉ‚Œi’0È’øßKÌ Ñ!–0C?/p°AgâÏðø9Þ„qçœ~㫾ŽJ_óWi~ÿœfϽï¼ÁêÉ?`3<¢‡Z’Þý“ ðY©ö";8ò |ƒÊ[ ~½‘iÖöªÅ|³ÏÕóÙLÓqÒE0@.•üy09‚ŸµI°æ!þ@ðŸÑ @¬”7 dà-þÄÍ;×ë ÇÓŽ[*S»Ò¥QLð\ßwqxF+¼,Sñî믣ï¿îiáyÛ_û3d¾â;ˆ~ÿW¢Á©y¨z|Ö÷h¶ÀÚd„>üâkéÇßýW^¢†‚ZO=Ú 'U+U¢b®õ^¤ŒS¤Z¥U.«µr©Þ¬•w+ÅB£ PÈe›']H¥R9¸6ƒ¥ùg4˜@¤"˯þX›m1·Ï~L}?ðæ :õfÉÔ 'Ón·Z9ém5zãñî€7Û4_L@¸ ¹ngª †ä1côÇW5?Þùàÿ†uü½§i<# fæ«ÏãX2 ×±æ÷å ȼå;Í•e"*hqÒ¦¯úò7Ð{ü'H¼>óRÏX ÚªPæfƒöZ×(›Ùá›™|v꽜TËň^ªUŠ¥V­Ò¬– •R!_ÄQÁûy'rððŽP1ëi‘¼}ÓT2Ðø/à Îb,ü`áÍæîhêGwÒM†ç½aª`<OÇøw 2³ŒðÁòƒ¾xN'í#rÁ'Œ¦/ͼK_ÿþúà“Ÿ¦ò¤Fó©¤éŸâ9ýÃ_þ5K©T2¶ü¤H? Ÿþ%?‹£Ÿq‡ê;-jÕwjÍÚíb>·—Í:[xÞ‡tW2 0¨ €È— °•R­TÌáß>rYŽ:à‡À¸¦Tø,Œ f™ t „Zy ü€ öU`„O¸YHÄ.@ýϻÉW-wz£ÉÿžáõÁl±pa&ðÎìÁÄŸº³ããÔ¨“?¥n½Mô™Sœ}¬@å•M·è£ò#ôõïz94‡:b¥Ô5Öï Á¼ÿdŒ û'°° [ªO#¹£N.dèÿþä3W=#lúkZ”‡í(›´Ó<¨VJ»ñ½­zõv©Û…}o• ¹–þl6“¡sx ñÔ¨–©RÌ«¿ñ:° f€\– ­¤¸@1@JD1M~i,–úÅb!ðìó͈£|°ÿÀþÓÌhâeêÕiüÖ€6 ñÔ#˜ðÉb†c2žº§SoÞžLÝ“v¹¸×kÖŽ‡ã­:ß=¤É´ŽêÑüãmƒ.|üÚés$§Yš– ýƒ…Æš‡ÙÕ¯.ÓâU3_þZlúCÚÚߦ½Ó÷ÔoÿÒK êàŽpÎÍ:íÜ<€ß¡baoREÞƒ^ßÞiÖ®×XÝCÅ㹚Ïe)ŸË€Oò{¯H$ðw_ÏÉOSÏ0êȤ “ÀÏö*%®‰¾Šè|€´Ðæ>p þ†»J[fÀ{s‚Ä3¿6u=bm0O‡lÎzƒû½áä¬?žŸuwðc¸‘§tÿðF}reÀÁ²Çÿ6r÷ê4ÁõtzÀžÅ‚Œü+ŸgÉÊSU3Yz\T®J|ã¿?¼E¹z‹êÕìÞÖCÞk°ë×¶Õ[õJi à®¶Ûª·šÕr¡^-:xÆ}ç áYõÌ„ÎBÒþÔ3K¹&zZL !ýpñ„Lk€[L Bµµ &ðÉ÷}á‚°co&¦ÞBLgsá3&€IÀ—s1ãÕËEF‰`Ž€à(FaFè ÆU`ƒbw0bFFïUF…}öL€!Ž ,Ž<6qýú)úÐOŸ_%žÀkúMïø.º+šq-~êó`ÞôN¢?ü·Ñ¿Û¸öl’ïC"\ªiºëϯ®S¶P¡R©I{;7 Ú÷Ñ›µ‡Áûl_Á×ÀU<¿Óª¾^-’ž'¶ñ¬,°ci·|ÇÄ6Æ#%À¿(…„[ÂÛÏñº³ÔÃÇSê¼ÉîŽ@ȉG#RÏŒÁ! 'E…Lšj…,ÕŠ9ª”ÙÌ8J£°†`¦aá©39ÝA©Â«‹…6دWŠ-˜ŠƒñÄ}p^Êo330N [÷`C:´ðŸº( D‡¸îy¿ÃŠC`­çÞÅ4zE€Oü¦ïÖ ÛÐþõ]*@â|Ï¥;ùÅ«H~JoJÕ]‡*¥ýF­ü(~ H~’~«Q)·`ÏkÛZ£Áá·3”<¿¢Rùlß9-ÌÃ`Å'Pj\*uHƒæ¥Ö5Ll~‰ÏÁ@©>§í<«v;êà8Lè¤?¡ó¡G½)Ô:$œ™©˜s¨QÌÒ~½È¡BÅ€9ÖBÐ<|nÖchÆ$œª0UÏá8g`Šçz4ni*ùñdfä¨çÍØ¥}@£é)ô@`‚JÁºÅûä{ÿ}h®½é{É©dÉ`=Ë|Q­¤ïõ%ÿå™ë>AŠX„B¶ ¯@|þ­*ÑC[Ôj>„Õ¹¢ÞÚkÕ«WËûpã¶€öÀÕ@_vŸ`ô 6_I>/,K<Ûy>€z‡ZOŽRÇoAI(â3CHõo~Šø)ãâ)m.µ‡ÝfõÝMéAgHǽ =ÀqÇ©bh†y j J`€JŽ†îœæÐýlNØÔdJ¨z¯DàµT¯3F)³– ÆeáùïF»?,v…*˜·Xd·ÁÈÛ¸¾b?›­áK%z‘SÛÏB­ÊÁE$¾ž·íߦ^1M\?9)ÚŸ°p€T¨Kú$G]wàâ¹—Úmå.e²;0 ×·wZ_Œ¹màa¸pÛòÊÞV#³]¯Âó«L€ZÀζî¼VßX`=,8X"+ôijРò´´(jÉס~0Ûve¶Xê»#º{6dÂË£¾K÷qœç4ð æ >P ßw}òÚc`“Ik ™fyp´»É š†fb&PXf…™ïf Wës¥|¶aæbØ Ò¯L`Üf'›ÉÑèÆ} M¸Ž¿sb"‹kÐa+S 30/±‡ÌV©y…`Ñå À'80AžÃÚ®(“Oþ)zî?{™ä ÐÙkP¡p€ãF¹Rº ‚1lù-Hú5 ½ØþK<˜į(—ŽÕ¿Võiµ¸L<…Ò7±M°Æ¦ÜÃ<¼ˆì»’|€o}É O!ù«ûþ’?¢Û#zþlDGNGs:/¨?“~|y¡ÍÈ`†ïa‘ø1„(d¸0E¨ørçf •N;Š!˜¦SŒs9£½²ÊEåžJÏM˜œ*pÉdòŽãäGLR©<þ“¥î Ÿè^×VDûý¿÷¯Âû.ýwSYähîÔ¡¯½v¯,z‰&¸ +Y-f¨æ,® ö!ʴݤZs?]«\¡Ç¿ô+p½XÌßÚߪIµ\¼ÕªUv›7w[úþV#{}‡c>U%õlëÙ½sí³³Æd–úAºØŠØ­c‰2V~ÃiÍoâ{&ÅÇZcâͱ8]¨ËîpÊ’/ž‡Êgɱ3…Ê÷èp•‰÷ܼJ¥•ÛWà"2Ú˜á7§ø§ m2[°F ˜¹”;aâKBãO©ýAÆ4h7•‰ÏA*À‚2¨á½4Ež ·j‡õ“Œ“÷Üí*ܧÏ .ž`©‡•º#Áöþ~wLÏžŽä½žKÇù8Ÿ²3K Ÿ3Æ)G«‘T*Š“ñÉ9 àÄJI»J»(ÜáÛëÕ&J‚/S][6«ãZí;L|heâ²Ð-œÎäÀüy< ivâÍYkBm=‚s=70*‰ÇSïûezʘñÖï£<›ÀóhúqKxÚ˜J¾ÜLë”ÛƒDì pñåjÿaE|øn· ÎÃñ(ìýCû­ÆÃ;­¾Hïo7Ì l~’u)YRÐ$/$KûíZÕ[ o¼{ý,­¸ÛkâïsЇAIÕ+”¯íýÓ¡Rù÷ºz¡ãÒÉhA¬òG>\Y>#l¸’ü(† ‘5?ƒÊ™”¬Àá©@í³WPȦutQ(Se<)Ùeæå« š$ÜÇ+R‚ñÌ›pôwU ÷WDço¤s`*‰çŒ3v~³6SÔ/àlŸè]d ßùÐÒ.-úpa©þY`€Ì‡Ù±ÅÍ.êuJß)\† ö_sÎeoÕA|ûusÀ¶\ßm]‡È]ƒÊ¿¶Ó€½¯)ßžã÷ÆŸçåb‰ÒѪå 6To+qC«¯Šx”Ô+R¥´& ô¸<{4u R¯P>ÛûgNJå?Ø»äŒ5"Oâ·EZg‡™ø–Á9ò'YŠ%ˆPooS´×k¿šƒK˜§´V¹ÕžÍ°‡ÝOi&eè £ŒÊè3JfÁ·Ç× ³¯ˆÏ·§ÂÔZ3À:y`…2^s`J¥ü„ÓÙrP-g‚Ùv†žê@ 7Q`þÅ"%0àOM ùÙ—Ç\ÉÃÙÜ£¯~ôËèÿGÿ-ýZ÷}oó§.Hßî6q×`ßbɇj`ïÆþv}ë`·•c{& hª•Š ó+„¢)ݺs"ÉÙËÙ Åg&áÔ€]?.á Øc¤ÿ = ;çCczæl ¤?£6Ðr{Æ ¶ópcÓ 4Úæ è…^*Â2Ôr)º^qh¿’£õ4ŠðˆŠÄ:ñ”J§-[~\T)M Šƒbo¦V!lþÙtJ»¹F‹åðÑí”R$'Þl‚õY }³¶@ü£Å¦ôòÏüãï¡7S™þNûgéCO~5¥ê7ž{ÿKc.ãR ¸ôÿü£ÆE¶.öó b]iîÃggÕÿp³^¹½Ý¬@Õ3ñË7÷¶”½g¤_ÇÂq$l^ RìÞ©µÑYß¿$hÉð½Ö\~ŸÒ‹¦ÀÛ#ýÒ=ä¿â?Õ’ÿbÏ£sWÒx‘ñYLM|&ž•z&¼ôd”±šYAu§ìЭFž®Õ tÄ?h–¨Y)Bƒå ²6ðH h¤pFÝ#ÀüÀLëæöZÛ±Òš½;E}N°{³Ög†uò¦Íê€:·Áw‚uq‚¿.´Í ?Fû¿õ4ìVÖ0À& ðÈ7ÈŒŸzî×Ã7¸†OßÉÿpñªå íAºQ}ÿø÷_´·Õx.Þõ»­ì´àêUU8—ƒ%B»v6v¥;{DX§% áCƒfíôguttÓK¸îŒ:ƒ µ™ðzúx@Ï@ú¡ïÆ>MÙ{¦XX8ѽÉg©/BåCÓS þ~9âg@ø<¼Ÿí‚Xòwj%…ì3Ü©”q„ÒZòVÔ=éÓj¯…ñ¤ŽRS¦‚ÉdàÜGG×*„š@P6iTá·!ýs˜ ÁxãÞlÇ JEA£›iê~øÁ&Ï`_¼èûÞIô¯ÿ.ÎôDòM¦¹¡µ'zØ0ºCßø–EíHúÈ3¯£O}àÂ@@_vÆðhª¿tK¡}øøPýy¶÷Jò›ÚÇçü<ÏLÉR“F GÚãÈhSÝB)½ŒZŠ„°y|írtïADïŒÅ½l>\<¨}1]¤4ÑYêYÔìyhd ´YáSįçí– õÍíƒè× öo6Ë¢Y)(µ_ƒýwàÖ±ÝÆç Í}|u ¤ÑFKªÿéø«ôoè{ ßˆõ¬7¢N¯}Ó½û]‚þé/|7ýØÞyAUîí-*—*Õ2GønƒøpóëÛ zùÚv#TûUC|.¼Ä¥”»ÕOñõ1•ÚÚä/#°øP)²)]Ò‚3z*´«‰©‡›¤ßõ$Mã×3ñ' °½÷Jò™øUGÒNÁ¡]ØûHýC[%¿É/ÑžÙcÉå2àù¬ŠöXµ/MeyšP×%ex'Ú!°o*P`:£ÎŸ °Fp) Æ,j!ñfó2ˆ¿ÃMÜ>ž§)Á|Fæ×çþÖß Áó^óéå+`€vÇ\»O?õÃq‘æ¤N¥ܽæCÛ»­/jÕ*_Â>½[ðó¡öxÄ!^Îà٬ܛ¨K×á[±—ÚæGÄ¡JˆƒWý‚Ú¶Î羄Ÿ/ØÕ»w®UÿsPûwº®ˆ®Ç]vÕÒÚÈH£‡5ÒŽdÅ‘¢ê¹]L‹Û°õõ<$¾D··+Jå7`ºpHV÷"¥}ynüäò1)q kµ¬“g ò±ˆE¯"¿Sp¹íà÷lY¤¿¡Q¥íø{Æf¯mÑ™Ýô¨]ƒ9¦×¥’çþÑ¢¿ô .fn×âÇb6S¥ cü™bE¥tË¥•Rá¡F­| ®§t9ÂçÐVCÛ|¥Ú8¬nÔ¾ÂjR«CA ¢K»xqâ/3AÊ æÀdþ8«7˜¸’ਠµßÊ£Çøø)(v#ùdí?Ûk ø2Ÿò©‘MIvñªYùèVQÜh•éz³, ök |!—XÓçð%_?ÄD#|©3‘¡ú‚† b† cj“ãÃ^JW§Œ›è`TººŸ‹Suh¹}.?csÐ)ºPcšÏ¦€ƒý ‹Jn\#Çtâ.º€{õtaoæ²¢vèÂR“*%.Ú€Ï_ºµeíþV#ÇAïÖ+Eÿ~a÷NðM*Hbz#ºåCahW£c©Kº8ÎrKöhê ~JõwûÐ|ðøÄŒ]=àqL ˆqó(` ø÷µàÃ\+§éF-G·[Ezt·J× 2wê%±Uåf£¬Šå³ä« w*sØ.PJDÄz@Eh¦â £¤â‹ìÍé0·oÜ_>WZB!!8‚MçÜ÷Mëù"hyšÜ^©Øz³`蘢ÓõáÙr™ryíÆië<úø7Q¾¢O|ü×T£¦z|Íß¼¤†ïaøt;7µÊ£ úã»­Ú# üÔ‰Õ>gõÀŠƒãç[5o%Y£/„V‹1âÇ~FWS˜ÜQÀ/­ ;9Ú¦AߘîÃåSþ~{L/ö=:/¨7çÎŽ”nÍŽ‰$;› }МÆ¿‡Ôðh*PûUÚ‚ÍWE\ëÆ ÂTzÀÄúC(Bk_ÂÔ´ùIC|ËŠÉÍiU(m:_]©ÊfB ”„73P•G³yÄϰ MáâcÓA63¡ö£0ÏÎ7Õúõmÿö¿\­Ðyöé_WÄ'z)¢ôö·ùE^üŸF«PÈíAõ_o@ p>ê_¥tðqlŸœÔÑ~¾ªµ“:®¯¹¾[¡Ç÷ëòön®mÕÔ= 1iNE‹”’Ðt¾J)›tt˜ŽîA.©¶§@,U$‹˜iS¬)UDd^;sYUƒœeŽr šw z zj* øê…Ò&ª½ù‰GÕùfꢹómêH%b9æñ¶¯þò J·oÖ±:;eü8.b¿Y+oùW™ðŠøœ²ï*2ûÉòÂY¡ °7à S°š`‰ø„¼Â®’­ðµ®$vô'žh\:yÔÂ$@fAi›&SFÜ2>ˆ/ªñH«@ ¾xt¯N·vêb£”0…yŽUÀt0bÆTÉ\_h"{+9 }/q×U¬+½1°­…ÑuÂÖ=øª@Uƒ6^KÎÖ 4«jTÊU˜^X¨â>„íU+;Š6ŠF«7<¡û1?ÙIÒÚ¡Æ[ôÔŠy¢'ýším_Ïí¶ÚiÔÙiÕnìíýôÕu”¯¬$̹aÆÞÔåE:9½‰ûz&¡ `uÌð¬Gîœ: ü™‘þödAÃËÑQ¥˜ÚÏ:U8¦ŸOÑÃ,=²U Gw*ôðn G [RU¿œ²åH¡’„ÔTIªöP•)SºBÄL€±ø‰€±xñlv,üË~êP’ª%Èf•IšB3™*dg.®å߇ˆÃâ—Š{ » >pTXÕMÅkA9¨ûó긜+¦ê£X¿ˆi‰¬¬ˆf‚¨«—©$Up„[´4™qó†$/ ¥ú}ì±¶_1€¯2{•¬ V1 X¤=øù­:W"ÉÉdÔ¯ÎU™—ŽU…oBó+ê=y;kµÙF-GÉ{±_ tŒ@OV\ûÀah®£`MÀGµ\à&”-hæ]€ó=jKUe­Î@X%®jšÄ‚ý¯'pí){£ÕÚ±÷@t~¹Þ¨–ò@¢Êî›Z}âÖI S›oÍ{u8LÆ<Ÿh6ˆCë„¶_—t« ˆª œÌ¸t›ëþ8¦—‚ÂW c@¥éòx©œÔ(f¨YÎ+°Z.YòY¿ª˜<ÀREåLˆ>LíëàT•’±¥´~,Ö!íÔ‘˜Ë»×°€_ V¶ÚïØ„ˆµ,®©ÔÈ3àØ œeÜKGoטê•]*ï7íÖ<þIŒÖN>“œû;bCWAæôdóZ½Uã,ß-¨üë»ÍZ‹Uÿ–Qýˆ°PÛzk™êÝ0„‘Gª”y2G6ãlƒëZÜðX¯ÓªW¶ŸË¡”ÛÇîׂëõƒ(*JW!¾H¸„+6Ñ?æÉuP†$®:|]žØ/bƒÑ‘„ãÅG2ÿí—FÐØý¬a±ZÅA |Ý»PØŠ›\Sº?‘CÕ\^™LC£U@VÖq¶ñ&NXV4\ÃL!°o™Ïl¬ö-ðLžl>» ÷c?°¢Wu玶ÿ£l+R&-y¤ÂDb_KâØuØ5Œ‡Omn ~9ê2'dJµá鈞J°èH›*$#oEÐ’».Ã2ž„:Iìbþ-Â{I¸ûRÄl?­Þ³ÜXön„N<êô3c7®©d®À`‰ËÓ Uh€àƒ½L.»‹4´·Z=y&Ê´±Ö/% é´(óXhÿ(ÛüR^w¸± ±Šœ×ñô赉¡5p:‘6aëÂFPív UQ¬ß1°pb†«táä3hœ˜!<\ ¸KØ¥­û%b\ºà/ý-Öý;~oî_ˆõ>ÑúU3eçÚ»R '逵ã>ÌXœ^¯€AÊ8u.™)“âÈÒn½¾9öÏãX'm‘É›¾üœirP…µc[äO"†h““7W%`õïÍ×z©>°h_d[…ÉÆ `å\HÿÞÆÁdÆ)dIüùBå󅎶éµ¥_ÄÍË×¶ü·\RyË÷kÊ.º!—Ú{Mt©=˜P4¥ÉÔj:ˆAÿ)›Ð¯sYäÅ '6hpՉđöi(n‘g(-Ó³ @›pA¥/ʥѭ†¦åø[ùäëÞ| W‘LF¾U«–ŠUÅÆÓ¸Ô ^w¿ ¨Õþçb–w\Ýë›NŧÕt> Ìœ!d´oʺ)X˜ø~`0‚è¸G°7œªHw ÛÁªS' #Žr¥Ìû¥?l­d‹Å%¸òði2lÒTU³6d7ÓŒ ”¾QÓ4]ÃëÑÿ µ¶¶rê^³ZÞkÖ*MžÃ§IhqL¦Í¯jýu`IŠx[W¤ö„‘HdÒŒä[&PË£ûé­sT/fu›v.%JŽ\ß§ƒ:A”3É–1Ü€îØ£Ó—T¿`ì v)U·ŽÆ"æq$Uu¬ôK&b3rÝ}Š%¯þŠ&P^$ø Áð­GÀSI ™­K F˜d{9ж[ªgóêA<“¥w¿ÐÄIà¤2Ž\¨2º JK¿BY›µZTùJrÓG6›µ]¸¦"”RÐ@ D˸–J!KÕ|šÊYA…4;½…º;%L¿Ÿ*PqþáTRgLÐ.õÀ œPR•J)Í\Ž‘*¢Íêÿr½dC÷RlŠ6½¤bÄá²eLx˜£›øæ C¶¢ðŠ…:eÊ%š¯Mô¬‹þåx W'¬ñì]¨•R j…Á/<a‚2Ë&` ù¯Þ¤Œkz™|Ýb‰˜/­½‹P=;ÁÊ s< !£4ÔriëÏqù?& $c¿'U°Š“GýÉLàéI`S=’LrÚœ†ž€Xby­_óÕ@îEL°f]b2UOPw t½öÌŠÚMϲ• ÙL¸ †ÅªP.—_'ðë ›)ŠlFM݆ji€ðp/Pª—_¤Dš´-ÜK(ED¶\®,bb¹6YWûM)£³Žõ«Z=ÆÍrŽvªyÚű]ÎPÚ èX%D‡.ã¥Ð` pb­À‘A;ÙLIÍ~EЪĴÄÍd×Ñ{=Þ­Md±€O˜&UÝ/,t‡†y*Qä⭞ȓ¡+:#ù =íþHŽ'SÉÕË*q”Vñ™Š¢°2–ê\‹îeDö/@®Eü2ñš”kYF.E”D´n2,¹·ÓЙ>j6r:•Ñfˆ¾’ÕM‘«ôvÖ3ñNE»iH©‘&ÙŒå.Ó«#2n×%‰åŒVX +‚Òr«ü—:ी·î 1…7¦·Þ†}¹ÒX‹Šã9'Î5üךe¡&|¶Ÿ]áÂçïÏU’È6H›yðaòÏ' *t¦Trà=dÓ²’Ïžô±VË6˜†ûÕ=Š(e¾NxI[†ú¤L”ƃ‡65,Ã;^KþÕ¤Nrð°Du‘LÐF0}Œ ò˜ü"Þ+ê|€Ì^Ôö*’³H6/)S‹o{ÚS¦ÓÇJªëuGÚ¹Õ0ˆXFü–âI÷°²ÌÎT®§PéÐTZwÔVKyÑR-Û8àÚ5 Ž øL3c6z HJµ…ç8Ïè°+ZClWxÚGNt4Ma .” ‚TTh£Î±@Å’¨‹D cBr-ãl2-bõ¤¹4ÝÒ<¼Ù(%@î2T²²Î`0MZý³)Lž@èÛæŠ¯¾ëà xò°;–÷Ú#yÜÉþh"=o¦À‚áVG›aJáEÇ4w¬TpÕˆ%D­†ŒîôÂl LJ:M2¬_„2id¬"ºÃM¥ø`jˆ:ë=é(®Q@dìèm_R¦<+f2æëë[–aA†ÖèºIZFå³"júvY®KÅI’a ½49{5=,¥wéL«Î™œhBLÝŠªŽi¦bì-ˆ§¼r±Èh¡ËÂ#L%Uå(ל Æ Ô(ö©ÌßàV²wÁ#1²8¯Þc@¨ ‘›JB$@šLv}ȵ¹÷¸Ä‹5è_lðÄZOšd¢fюʉ7Ψ-rT=h š¾P¬ž6,¥ÃÊ£D˜ŠÔ XøÈXˆG¬†| †‘=ˆÊ¨…ÁLfâ%ÙfJ=Qƒ·™MK¸>0%•å;²ïŽ]êOç²=öÄdΕJj>‹Pmb1Éâròöd&zSÑ,e“=ŠŠ.taíÂýy÷Ðí`O rJVD\1¶#×e–Cá‰åÜ`)lÍ¡n± R4”ɽ/5aDBm$Ú¶“þ±ý¼”ëc¡ª ýiIËå ,‡A2ÜÕ-’ÀÀ…øª0„/ˆGµpqÄv½ @X¡km—³¢Ên¡P ÅÂtÛrµQÇÄÙÈãùâ°=¤šλ…iÙ6Û„-á_ëÃË(”poÖóƒ `Bï ¹š"ÑBº.iã"„°© –7h€hŒ OIKÅOžèmˆŒž‰GX·MÄ{(Ât¶öÙÂxšßè 5N,…‰â ýMß f`.›d  à’´ƒmW&®à‘°çƒ©Šþñ¬o®›D¢m•{Óá«ÀP/ñ àZ1+rZÈLÚ™lFjø ^&²H`˜èZÃÑaRÊç&‘½ˆá%!—³a+9A¤Pýˆ}Ì_j{IÊÌ Ð$$ïÒ™Ì ¬æT-dd 0›qd4ÍÓL&5³ŽìàXh7©àe¬¢Ï8†ÖŸÒ’ñê±ÈÍ[Ž,Ë *’8Ê> ¹1ʸ–â§HÇ^R2–›O8ù–£ãm¶]:ò)Œ ³XÒ†û"woÉNPbfïs`Pž"P`MpRDy<6®,À-äco.{ÓÍ}Èß×-ñjpÚ´©ø‡ì¾àCr)…ïÄ6'Í1öŒÔ¦ÀÆ*#€SÙ".¶2"¦ˆ!ËñÏŠe¢¯&TårjQÆ™%ˆ_‡A8êÎ’iÑ+xQ s`åTý@ËÊ-³E‘ÛP7Ä‚ÿFdtÍ2t!bÞ¤L¤‚—Âå‰3Eu›zF /g‹…äÉ] ]s¹œêZÚmTåµVEî7Š´UÊPYÍ« Ôh8•(2¡fZ2.=z¼}Œ<îªdƒJÉèT§qT@jnÜ6Z%.ymk d„¥Œ§Ó–H¿$ý±€qLQL ~ÄÀIpQÁíz  ‡4ù!çx¿ Ó'x¡fu,xDK½”×DZ¤¦Œ<ÚŸh]†(Þ%°’Þiêõ¹´&žˆ-™!ÛA ›ÒÍùä«Í°5ô]Ëë %jët’sÞ@ œµ<8AÏè[—‰$%½‹ò‹$»„ª>꣫铒‰‘\Q±,Ëq  d´0‘ËBN6«%qÍ­òFò¬?˜¶~:¤¯Ú‰Øˆ]8˜iŽ;ïBÒóp ïuFªêHWåÂ- ­ÙÐÙÀ<^d ®â-Ñ'¨Æl¾Hq =WÐò¸Ô”‰PÂ"HI‰1*ñ!JbÙ†Éä°=¹4\øÂ8Õ5M-¢ËsX]O ÆÞ›€FpyRÙbaÆÉ™d‹—ñp}²~ÂdMã ž(I ±êÁ(˪;˜ì0nfFžÚWÏ“qo8îôG“c·?<¦v÷œèùµ»Š¤>ø¡§Ö… a/îö©Ûïâ$}cØ9ÿ«˜ÙÜ7-Iñ6*JˆÊÄÓR<Ÿ(æ/Ĥ<^ï–싳L„(VY*W*‘¤´^®UQBÞÔYÍÙ+Èz¹(Y4ŠYYÉ¥89¨Y'0‡3Hº_·¹a[ëWkîÛ ‹ŒÆÅ,qYëÉäe¯•¬Ññíèìf”<<ۺ㋅f‚±ËÌ9¨2Íúà†.-ûš¦kàßüêûÅïüöók¦UNGÔëö‡£é„pgfH±B¿~`] ‘ðÜ%­öøÉ%¯@&<2±ßÎ’§Tý‰´J\š–ÒÖß³/½ÕO"t[›‚*ð@½”SÝÅÓf®µV;¢¾M¤ç -ÌäåðxFNRÒÒR¸w9(WÌb2@”0&—j¶•Q³X@¡úgã)h6žéö@üîhc2è“/¼(~ìçQÐêž´øÒó]ÞhÊÅ. ÊŒàáÄ9¶3¬þøGÕNGÉds82D«Ä•-ÏÚÛÜ‘QµhýR̘$ÍÁjZK†£kL ×´PsYÁme\ðÁ%`e0@Þb<7%ßœU‚ÆÓÉ‚÷ôÅs8d*¾o@Ô C79 îÄ +Wâ R.…ˆ#ä/Œ¶\®“Sá_µ©”š›è)û±ý·uåp܆&ï’ ¾ŽX­Ïf›6ˆ÷êÇ€r1Çr*"ÈC–°Ž’ŠjEe¬ÎŒR”Q¸Œ•Ž‘Œo¹–4%v³LZù¸¾‘ñÐËš$Q<­IæF[K¯:j¹©2“Q“F²jäM ´…cníéR+žGR-Ç•6%L[žL½üX`ÚŒç1ðX,|Ó²w iÕ Z †$2fR.•AÅúe‚q’9q¹d×Å×e¼'*G²Fá!×åÛåʤ‘øõÆŸ—ÓÜ Og È5ÄN6 JZvmmû—Í(µÏB¨4|?~wv&8fšá¦†Dïèx ž¯¢wã—~hEžÑQ?“®·K…}ÇI×sÙ Ï ,s ~IM QCíÈXÉ•ˆ‡ûä,ÕyÇ»\Ó¥¶®VjÓëë»“í©”Ôþ¼-'g/F§OõáÇöXnÚŠ¦>E7‚’“ÌbÃ2cý«‰±`9Ö!c3TìúÉh³=ÛYÅ&~˜ø,ù.Ti÷†íNx¿7Ýôwé¼{D£»ëÖ„ÇÅÛ‰á΄š~hãPä§KÝÜÉ ^=j¾ÂïA ìö+ãüp\¦‰š¬6ŒHÙà†ƒ¡°ÄhO¶Š.ê5NŽÝCD.ÕTË|ÇêÊä—`')“‰B‹žõæ“ ì(Âsˆ—ƒ[ìÚEãn’qÝx+vØw!–Kä劶KÀÇØŒåO›ŠÀbtëa_¦¾É”Ù3PÙÿÖ.Ž^4=ÿ©7<¡áÿxmð'1.ž«iy“„ „°ùþÎÎÛ|r'ƒÑä|0š2ÀoyV½JqâŪ*îWv»”«Áu¥_2ø¡e5¾œ#XêÑ[ÎP¬fA©OãZÆGÎ9pÂ(š]¨EŒ´,i;¢VÕ¦ì˜Úä0Ë„‰J¨ødJ$ùÔ)µwÏ…hæ³™F­RÜ*s<<²ÎS:xNšaÏ›D§D<£ªÐyêÎ…LvÈŠx¡çZÄ¿,’ruüº”ËåÁ/¤O\:u]ÕüyΪϽ±K#¾´)ðˆµT…Ö*Œ¨Ãõ¬d3*7š—h'¦Å @(!á‰òv¦„mq‹ÍÈDåÅU*æ¯Tÿ4Týxîõ£#xewa^ Nÿè“§´i¿ ~|Ë÷D›F©(!«Þ“éeÌ2¦É´-§…c Ïà´SH½Óëåb¶¤öÛÓ#dòÜ<‘V:_¨í¢Bx+’RØt°I}—Ø{/ Z—+‘c¡±ÎͱsµÛ·¾RùsŽ•L0œ&\÷'xë¹y`º’–cn¦Ò˜÷VÊ3ð˜Z̬găM".ÉñZ¾5Ä+jŸd"–`æþÖ¦zO#?´ý¬yAø´14¿{:M¸êàî6]°‡°züáilÛ¸É\×à ç—1ÀŒ<¯ãÈÿ>ÿ ÔO Ym— <›VåÚyTYVUt‡€*F†í¬hß2‚HêN`‚pñÕà_¢&/²›$D8ÕŒÕþÒÓîè¸ÝWmà§ý1`¦¦ˆêx˜XíÂQL$@ô4•rz„L1Ÿ13“uF=`µÜ™µ.÷Kj_Æ‘ªêX«~wà/Û}&>{aÝá˜>ç0&Þì>üÂ}ºhË8ëzaä?E½ßñÿ£úGÛ\Äßÿõߨü“6Þ»?;k¿pÞ>wÖ¼xÒéœvú ŒD•Mâ(!#ì@/H8D*ˆÛº ’– æc+~vÔ?ûîÊgâ]KA¤‚Õ(x®Ý›ºž„ÄЃóÝypNÏ=hËçOºò°U:ö$7ƒèv5ŵ™Ñ ÉrNŠ* x£˜—ÍJåOãTC$˜Éì¼DÞó׊V0Î+…÷!e2¦!âv?æw‹ú9ÓÇ.à°ötÖ,Î{ƒüý"ÌÀsÞy÷:<ºOÓ?n¯#Ý÷ÿÒ¯ªó¬mÏ_VG¬ Ä¥¦ùë£ùä&Þq‰îöh08M§Gýñä¸ñ08ïÕ…1w2@™©J™ˆ‹9u)ÂzÎ(„VJk–#-ÅÌe¢Ô~9F¤@“`ДV­TKàK×ó 2ÇüÝ;íÒ‹8îƒøç#WŽ<_W}Pln€*1Ö¹¾lZHž$V-d©¼S-$×ðÌb.ÊPABCø Œ*Ùäd„vcœ,a1K!Âqoú0¶_À¿WÑ>¶ý|ÀÝ„Ÿ'“ÐÆG4A¯ö4Vüä3êù5MJD‡›¿r¢g>þ¡Èؾõ¯]d Æ4è¶=wÿx”™Þïç²[ úv1ŸËA5–Ø ðÆŽ!ºšY§›-D£¬ “B2ÖÙu ņ¥…»‰I¢M|ÍgRvŒ½à&Q¶û$›+x`LÖR÷κtĿ׈Óþ„ÇÈÐL9A±¦tÌXñ„Ÿ@|Õ$Ú(åµôóÂì–b“†øÊ{-×5Äm~ÒHF cd+çXØ ²qý¬YcÀo âÃå›Á¼æ>¦~·­*¹6<þàž[íu^|úCá?J_ù=òOù°/ÏŸÓÉν·(â ù\¶¬æø§Ó»@Çõh”P£Kµ‹%B"0¤K­vD XêÔ=×)LX÷¤Ý?Äó3g½áS“áø3t÷ÞóDOs÷:šÿsüÎãùGŸ¹Gÿü+¾ ô5›ƒu/)ùÀ?¡o¿ž¦'öÂ=åGDÏÓøÆá4•Êõ§P)Žk' !Ig` Ê ˜üUfØ‚”Fè6Ò#µ·˜H¥Úa…—‡EÅv^VQ‰€Ë7×€ ‹Ç¾þÝ“Ý=ëñCÂæ½…÷z€–)!¶ÅŸšÇ’Ï£c¯5Ët½U¥ýfZµ ’ª±ìd¶ËY˜¢Ðdm_¢ÑUÈ(/,â²6•â3~—ݽ»Ï\¥Å’Ïjÿ” >˜Ð}|ˆ{»3Mï@ò» Üë§æçéw¿ÿttô'º,°U_£ù¦hqŸýjüªoÅkŸðC›ò‡ä-ÎÈñrÃ\&?œ¸uµmpg ¡þóv‹7þ´ 焉q§Q×þs¢QÒ˜’? ´\­+x$Ìæ‹AßáyOÞ9ë©Ù§Ã)‰óÀÚp µæVLi’Õ\Zl—ót½Éͤ5º¾U§–|¿\6Ë*Z×@úÑ&ÙBP¼è@КbÐx`‹Ìx÷tXNgÔþܪýˆßWÒg·mì>ã.Žà’‹5j»Hõ¿øG¢é DoÿVý³ŸÐÏLóç~Ý0€ùcåñ5ÿÑÛþ'n’§òc´/Þ@k::¥ÎC~0¾.O³N^µfóX‘T*ƒµÝuËÒô¯³™¨âf³ÚŽÊTÔÞoŒºðÅfÃÙ²ÚT¤(œ$Âj˜[ú˜ðZrF°÷m:„»÷âYj¿KÇý)õ\.Zèh¼ƒÃlê@í×r÷ ÒÃ;uºµÃª¿ÕßPÒ_.ê¡JYøAXmÈp“îrJ¤z£N)»Æ – Iߨ}W¹z,ùZÁÄ#0óéI§ÿ8ài0ÁS‹ûgÏPçÁ‹ fû¢\ÿ òwé¡'~BÓiùáÿ3z3FóÍcâî³2pé¿ú‘ÿƒþT~†~¦æoˆ'Ö×Ò ]êV2ÓkÛU'íòfY¸eN¢¬[±½xÑX@¢DÊI‡X›³¨‰8ÿR[¡ñ•lŽŽÕ>Ûüc¸J/ÀÍcÀÇjÿˆÏÓÁÜE8 2ò+3C€»ƒXí@íß„½¿ Âï·jjwnú¤U­™±t‰lQ9WbâQT"¢ØXZ—_·ó|Õ>ÈÀO\ÙÃhÿܨ}Øýƒl‡ýáø0ÁóovòÄïnªõû9÷è¹"ý7?ôóP}¢jþâlàÆwžûóGŸ>ú'uzóOþ ò'îB:%Ùí`UŽ&Þ<“N»Nq4-*Û§ötY?ðs ßÇ™TKR v´ƒ¨ÚjïÕ+<]DŒ§îtâθÍ|áÎf¼Ç} @'¯êë9_€Õ(ærUSCÃÜš´…—¦¨_èaN,mió‰@!fÎOEw8V¿÷Û}y؈£ÞD©ý™ç‹0Ä+b%^jûVûiÁ­âPûˆ_ÞÚmŠÛ»M«ö_ÿºž¼æ…¥æ&BaDÊØü(4-¬‹'ubG5–®åçÐ9k.VûÇç]Ò?f›Äÿ\4~fíÙÞIûSÄU>ýÞ‰Zã‹ú”Gy0þ¢_„Š`Ð÷ˆyçÉ—Ê¡K@ó)ØÐa°©z8öøÄº+'yP.fÌÍü9× qÏ:Ž-,àžÓÌ,ìõ²ÏC^åJi¦2‰~`†1õ„]æl@¹01¬B¹@¥3„ï´Ï£]æ¼]¨"™ŠÕ÷›š¿šsŒÚ¯(wïÖN¨¿®ˆ_*ÔèY5.ÍÌGR{÷ªmʃ˜÷*³~ャÜ4u|ÖsUY=.èàð4®÷¬7Ðh¿Ó÷¡ö»ç½á9>0ÁÓÃñô¹©7êí. NN7õ÷%Òàoý>,X¼W.õ.¥îxc‚c¦çaGy}ñ·Ò7¼ã;é>nçSïûåµA'¢§‡ÔÇâyÍìDš±tϹaÁ÷=–?<×g ?Ë9n^Þ½Z*¨<‚Þ™Dï’JŒMN޳›Hø\ª?SßÇ“ÉßJ¦ZK?o3·¿A7Aük!ñój䬪½WÆn…3mXrͤ‡hR7?¥Tý‹Íéë"N]r¦Rº\ÉÉ>7§2ÒÌ ö!èýûìê Þ…"xÊc›ï÷iгÄ÷×-øk¾î;èú,Eßþ6‚ÏKc•éË-Iþ×j °ôÁŽ á8Ì’ d|˜ÎÐ<{aÊèô“]zºƒUo޼Zmp8›»•R¾Ií3CÀ¦íM]¯âר†§ergeåk«íÏT¬]©Ì l±2fa!}5è}«ác­Á=©ÉáœzgMôtM§%‰w™®ç³°÷%ºÿ«ý#~ â µ9&«}SyËø…ÁžobÁºAX¶vË≷n!Sº­/ ÄܺÍ*d¾Mìœtzý3]Ðy ðLo8¹3šL_G@û]|lóï÷/,Ô€‹z/›£éõ"€xäºÙ%öðš^Ý$æÐÄoÑ|•;ž]Á<à˜SÿÖ •†sÖÁ”A´çÁ€CR‰ë•X…3 âÞý4·Ÿç³`iÖV½rŽF¨¸))Íf˜o¦Aˆ™+¥Ûƒ? -àr[ Kœ·+®7Ë0#ŒAH-s•wñŽåŽqm}mG³9ó-Õç«¶mµ0ñÖoBí"6W!êOÿVSAšUº ©7®žlÖÊJíƒÕ”ÍçYøæzWs±Ñ°Ññ5Ìo‰nK·Uß¾ îtM%\½9þöFã3ýy0Ç]Üÿépüi»÷ÉCå¿p~Q[×7¼ö¯Àußxâ¯Ò¨7¦Qa®6‡ÃI>Óîþ¯|– °|‚Bưü‚ÒeAg™ÕŠ—žp÷#GÔËŽˆtç7¼n©Ð©”‹mže{¸é€ðz»x.õ+¥ÛI޾UT†.;çÂÓœ®Â 8ˆiU;e±ªm”Õ3aç:¼ç]Ö0œ f îý«ã\»õ2Gø$Ûü½¦öóË:Ä«DÜ7Á%=WÅ#JÚx­êõÔp…î=ˆkSj–é×c©·¥ÛšÑ=0À˜+y¸˜.ÞØÿgtVozOÇö™ðîಆŽE9MÝ¢Tû(Ó 4)dWƒ‚—ÿe˜Š’öjÜêœÚ”ÓÑUÌßÐ °ôÓ jWyÞx8›õñ@€ÙÙÔíÃL`#[@Ç5,\ƒ'|jÕl€¿Ù>ëPr6¥À¢£AbZÍþɇÃÒP‡\»ÇÃyš—{3>¨ò¼Àš ­žvRR•=ŽÉíK ¬¹I…­ª+>½í3$’áMVõz|Œ«€^g8RH¿¯`¤†m€ÚíÞðî€+y&î‘ÊçƒTVO'vF—•só=¼á¿&Þ Ô ¤Ýõeí]-^Ò§ßôN¢?Œ•Ž?üuP;@›®¤Ü .–q¼=û›ÿî’}Qòyv´›´³u#ŸÏí•ò¹k­jåáR!·¢ì€8×àTáä›Õ °AQiöŠfkUy¤ªrt£ÿé”gäLÕ(7&>›¶å\ÂÍ;€0¾àÁÏìuðy2*$"Ûpifì®Ôê‡DØ-k ªÖì…îÑè:}í’öU¤‹:Ãñ~ -÷àïy.ãšq%ÏiûžÊç«”î§/ôÛû ÿ%¹¸‡Ó¾GÞ!<³n|+ñÌû7ÓèÕË'®7MùªGe‘£ì?œš¢Ô>(¤{Á½z°ïm#õçÁ˜íüÑÄ›͹€s8<¥~¯m*y&tùÝñÒô •“'ÉË»`_>1^q°ö,>3IHÁ‹‡Ó«˜kLÀÆÏ"—4¸Ñõ$½\ö´WÈ!v†Soo<õ¶!Å×a/ *÷$ò–èª(Ck‚¬:Ø4(Æ€V`íÀq„L^msË•B‚#“I+M Õ=é _~Ô$Ķ ±Ã±Y²õX˜…¿âû>RÚe¦Ô>lr¿š"6™BùxCîŸmF÷Ág0 ÇíþÑý1¾pJ‡G‡º€S•`Í®dyq7o};ͯ;*$ÍkþJ<ÄËþæ¿®e<ô  À\„·‚Ãn·L¯Cêíöö:Ñä¨Q09½×±rÍœØ`ËdÛY¬ÁÓ&¬LpÉ3RÏÏ\íu½y{ây'}w¸Ìr¢:v¦Ób&ªtûÒ²«úì{éÇúÿ¥Ì Ð2Çðï¬q‹köðîo^@‹WC,ÿàAìÀ¡¹ñœd9E_wcïªgtÉûØ}ø g0%:~íéh«ÙÕ«;ƒÚôê{„ßÁ÷AÈ l¸.—£d€æK090AL“)˜®s¦yÃô+ÆJÿ$-õ%DcfŸ–Õ¾a€9a‚̽áx ›>¡gx}ÀQNžÌ<Àßçx>õGwàøŸÒ÷ê}âÔtìÌ®º o{d—²•åÇ¥p=cª]³A¹ hñª›€%Ax‚¦˜Sð»Cúá¿ÿË?¥’xýUO0ÓÇ'\:¿Õ¥É~{<›÷Çç>à}ÓÉev¡ÒËêb¥Xh ùΤ&þ?sÅr!W)ÈÃõsôÓΛ]°¦h3üÛnIÇ1$˜ x…Á‚cPõÐæ{*ÃþpÜ#ŒÕÕÉ´ËÒÏ£tæÞâ'èà‹çtÞ;¢ñI®Ýð²€Îò£5ûK÷_“ÿÉ´T°¦R­í+ý¯ÈYÖê:±ýÕD7jD¯¯Ñ7~5}ÿþwô…x ×w­D9¨—´¨à_%ø» ø~Eèwø…¥V˜.b½V)îB#4 !ªÀMØúhŸƒKX0{èr8Ñ>«ív—Ú lrŸKU9éé+˜<#Éã&l>ÏN†VwÙ¥;ïM`ó‰§qñ,Þ@Nh:ë ëBivÄ¿?¦+:hÿ?ÿžŸþ9zð䇉þ´¯óùœÒµkyéš¾`m2IªT2=òf\,TׇÞE‰öéÿ¢kWˆ›´•câœþÞjPµQ£zµáÔ+{ì1‚ê̬!@üðž·PçHOFí¤­vÓŒ1€ö¡íBœp™«¸… 9h2«§&o{óy6¾7žxOàä!Œýn_bS¥ÔžAô‹Ë9›€Þ7Óý:=Е<\”£ê21¤zò§”C¯ÖCI«JCÆM—÷ã$xˆKö‰YnhKKËç½½½7{zzt}}}›ûûûoS{Çâ‘Z/!÷¼°‡Is;ŽAwÉ .}}+·u­×_‡VWW¶··;š››Îk õmmmç]GF{­¡4Ô½or¤}u_ça÷9½5¯´íÙ»g>-- ‹‰‰‰ÈËËCmm­Ãh4æ²é………îÔÿ©©©iË}©ÞÛ“3?VDþ[嶆Hh<ˆ¸O2¡½˜†/ËlP t³ 2™ b±±±±5UUUÐëõ?Z­ÖüüüºÊÊÊOïKã×yéÜ!áxÀYBÏmGÄG{±õB*ÂÏ&~åR…ð "@À‹ Å•‚‚‚+ÑÑѳeeeV×$û„sûÖw=Rüļß) ¤ïÅ€ÒàÌØXIE4Ö½­†{a <·‰ Þ€ˆˆ¶bÄÅÅÁl6C£Ñ<î*µø‰ikÕÑjï‘kß [µ¼*ž_¹êÜNþ—õÙ W˘ªB”!”[^n2™‹ÝŽ–pG¥Á 9œi`)`ye°6K »Îž€ñ:®„ʪELL /_$¦6Ñcή(š}´dÓÝU'Bx{NXõëOÂ뤫韷°½b?¿b&fØÛµ>{AAÕë(9,ŽÜxÇ#+Æú ô§CšŽÆÆR|Y—¯Ö¡u ™™´c´Zètº%«G$é¥Ré¯ò9įná÷›CñZn·–aêú÷°Ùlèèè`BöçÔjuúR^¶™§ýýýqáÒEl:iÄsmG]8ØzŠ"5¦¯wcjj t6 )) *•jN©T>³\¹7»»»£¼¼¶[6(ßMÀ+×Þp᥮ãPŸ1Ãn·£³³“ßj‰dN.—xÐáô@  ü5ò‹¾= Y…¢ÓZOEBH…!>£Eéµ³¼”Š4çaåþ&’‰¹””LLL`ffw§Æô7°×æbf¼‡tr!,,Ì)}Šû‡aqss›ËÊÊÂää$îô5âVÕ³ø}ì*X !**Ê)MçþeðòììlübŸÄìxéèè(¿_ÿ«ÔEž““ƒ‘‘twwóçÀ‚t÷aa9÷õõ…§§§Sú4÷?Å.b˜!RFäA°Z—!„†0;‰”X;}j‰HBEÈ !$|‰5 .·?χDÿj8Ë’IEND®B`‚eric-6.0.8/eric/icons/default/editUndo.png0000644000175000017500000000233312342633754017477 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<XIDAT8Ë•IŒUE†¿so½ûÆ iºDŽ *1ÒQ£ÄD Æ9qI¢é…®Ô… ãÂ…‘D7.\`\±pL€Ä)¨¨Ðh36ðhz ¯ûM÷Þª:.ºÑVÐÿä$•œœ¯N:§JT•½;%èPÏíÝ)ó{€u³vë¬ëÀÛ×? S\A²çM^^~ïÐó{wÊ£ÈÛ]‹óóÛç:æ-%W\´F¨Mž£26Éø¹xL½îèÐÝW×7<øl¡|ô=F†¦·uå¶­¼¥¨´‰°´ § ÕÙˆ\3Å×'I.îcè`™ZÕ~<×? sÁzû½ÓÇøù/Q.º› ý:DbþKê#ÜäAF‡÷súX|Faý%¸ÀÆHa]Ý[°¹>N@ç@QøÛU$Hq- –vcÓ—”‡“w€í‚:|ìÀ´£ÂÌZÀ'-ê'Ž^%C2ózÈõ®$¿x90»IØEÏ’µLŒnÛ»SžèÐ]²çMtý¦ðæD@ ™>ÏÔ©ýø¤I©Óå=JRõÔO{2íËh[{A&3{"Osú~?T¹¬4^ÎZBp­ ÕÑo1EG±×sjÈ“ÔmK¢|˜[|c§NëÔ`"mk6ƒÌÔ,’5äJû;[5wO0Sc‹M[8×Âû˜8)”À=õº×Ò U] Ú‘4í“'ޤ–bë#IcxкfS]³‰O ä llk”Æè Éô9œmµ÷QêÝ@ÐÓC¡SYÐuïöhÒ? »€gO*f‘ØxìøkÔϸF½bkn²T4·àX¥‘®è(=…N ‘²×ôÂx™›ç´Ãî$ö‰3’WÛ:ak•6 MCÕÏÏ£;!^o¦ê<Ò8Ôz- ¹Õ„´‡h"úW»M¯Ì,@¬-'Ž7D‚¢ó¶©}1€7¿¨¿[.EŒ~Š­!a)ޤ»î¡‹z…ÙxÚɤ͠œÅúV5‘I+øÙü3bá§Gß0¢‘:W™,кäûôu)š­&äB)ÀÖÌûY£X—j¾`ÚZMðÓeàhF4cÔ]üð7]ÁÅŠó¿~_}À„l7†ÎöŽð×é©hpQ~¤JN ‡uYÉr›8€—5“A3¯‘ñ+Ó¡ÝËdþ¼jXO$Ÿø6>‰s'®í-ލM M”hBƒÍ©SW«ñCòùe`¢Í„¬~fRVmÖÃ^ï1éWõØulÜØ7†uYMmÁ¡ä¦–J`º+åæ'ªìzêU­Šªr5üâ†ñ^H­‘4ÍJœFq­•o²d¼Rí8?æÊÏ¿¥ÿzÝ®B7ÝwØúz`g(Q%Ê„~a_%]ÔâPÏwnú¥9ÉUg>>CCCWWW†††...333;;;BBBLLLUUU]]]^^^///AAAUUUYYY111222888>>>OOO^^^fffggg222555;;;CCCTTTUUUWWW]]]111444>>>@@@WWWYYY]]]ccc,,,...///111222333444555666777888999:::;;;===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNNNOOOOPPPPPQQQQRRRSSSTTTUUUUUVVVVVVWWWWXXXYYYZZZ[[[\\\]]]^^^^^____```aaaaabbbbbbccccdddeeefffffgggggghhhhiiijjjjjkkkklllmmmnnnooopppqqqrrrrrsuuuuuvvvvvvwxxxyyyyyzzzz{{{||~}}}}}~~~€€€‚‚ƒƒƒƒ„„†………†††ˆˆˆ‰‰‰‹‹‹ŒŒŒŽŽŽ‘‘’’’’“““•••–––———˜˜˜™™™›››œœœžžžžžŸ   ¢¢¢¥¥¥¥¥¦¦¦¦«««««¬¯¯¯°°°±±±²²²µµµ···»»»¼¼¼ÃÃÃÃÃÄÄÄÄÅÅÅÒÒÒÓÓÔÕÚ;AtRNS$$$$$$AAAAAAAPPPPPPPŸŸŸŸŸŸŸŸÎÎÎÎÓÓÓÓÓÓÓÓÜÜÜÜÜÜÜÜíííííííí¡:ˆÚIDATÓc`iƒ‚Ú²"=i`W±¯éÉí¨(ÏË·Sb…‰ò˜×§ÌÌ›ZßWÑXTœkÁåÕ(èÍÝœºbFáüòŠÚâLu^(›YoÚªÚ…[Ò×ÏÏŸÔÝX—ŸaÊVnØ4[ܾµIk6–×NÉ‹Î(Pd`µQ¹9îPWÎu‰½;¦eU5ÆÅ;3Ȥ­ 8’—¢>rϖؤE“3“êÛS%ôË–”.ܾúxjÒºƒÕóÚ|:tâúë¶§í]™´ìôÜÌÙ{§…Öö4úz2øÏ ßÝYvjzÔ‚3+ Š6­¯Š©™[áÄYØp´®ðÔò¸ªcû'$µ,ÚPàåáÊTU¶ìpxÝÉ­ÅåËw-¯-ènOöqdÐ /ȵ!:ûàÉŽôÞ]ëó2Ëc½5¤ÂãÒj#ë»óã.m/L(Éssvc´OÎ/kNh,ŠIÏÌò÷óõr±äg`PðÎîN-(ˆ‹ÍˆËLN u—† ‹qdRL^c|BTzzlh¨‹›—(¹ÕBŠ ó s#’#"ý¢ÝT9!Îež’ãçiÈ‹fy›ð¸ðè¨Ð`?+9F¤Ø’ÐvrqqÔ€ðàa¬X‹ëƒIEND®B`‚eric-6.0.8/eric/icons/default/audioVolumeHigh.png0000644000175000017500000000165712342633754021025 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsbbË<tEXtSoftwarewww.inkscape.org›î<³PLTEÿÿÿ¨îUª‚䟟Ÿ¿õ8λî]Ù^×8ÎÄ]ٗ猌ŒšššÄŽç–é[Ø8·‡‡™™™è¨îYØ8ÎÄ———‚äXÙ8Î8ÎÆÄ/Í]Ùzzz’’’ÄÇŽè¨î‚ä^^^ggg]Ù•é8ÎYÙ/ÌÄÇ___ggg\\\dddaaallllll~~~NNNTTTUUUWWW[[[]]]aaaccchhhnnntttyyyzzz{{{‚‚‚ƒƒƒ………ŒŒŒŽ„qŽŽŽ“““”””———™™™š}Cššš¡¡¡¥¥¥¦v§§§¨¨¨©©©¬¬¬¯¯¯±±±²v´´´µµµ···¼¼¼½½½¾~¿¿¿ÀÀÀÂÂÂÄÄÄÉ…ÉÉÉÊÊÊÌÌÌÍÍÍÐÐÐÕÕÕÖÖÖ×××ÙÙÙÜÜÜÝÝÝÞÞÞàààãããæææè¥èèèéééêêêëëëì¶BîîîïïïñññóóóôÂôôôúúúûûûüüüýýýÿÝÿöÈÿÿÿ? Ê‹?tRNS  !!*+.;=FFLUafgvvwŽ““™¨¨¾ÀÄÄÇ××Þäçèéêêìì÷÷ûûþþAv·ü#IDATÓc` 1Yõ'9’ÌH¢þÚ]€ 6]^¸¨¸U~é„.7“QÞ€**gSÓÛ0¡ÓÈf`PS„ˆjصOèL›ÐâÁÀÀa(ÅÀi$ÈÀœ™Ù3aBU`w™'P Ÿ1ƒ’ CÌ„ zZk«³|:³½$˜”¤U"úûû» 32¢Üã}´UD´D5‚š››+ÓÂÃý*C„L¸Ì¸M|ëêê²"ƒƒ½ìKB‘„=:::âÂAªË qéëë‹‚@çê\$+A!䘔æÚXä@P·M͈uokBöÈZ§¤{ÔW£yžAÌ2Þ«²=¨øÍ=‹ 0–E/'3pE*8wKµb©W÷IEND®B`‚eric-6.0.8/eric/icons/default/projectSourcesRbMixed.png0000644000175000017500000000065512342633755022217 0ustar piotrpiotr‰PNG  IHDRójœ –PLTEÿÿÿííí000”5,•7.—A8¨8-¶·Ìá·°ê%ðB-ô,ö4öÜ×÷@,øH,ù_Eù†tù¬ ùØÑùãÞùêèùîìúL0úY?ú†pú™†ú úµ©ú¹­úÒÊú×ÑúÛÖûK4û×ÑûØÑûñðüH/ý_DýôóþA'þD*þM:þW<þcMÿ;!ÿbLN»»itRNS)¸Ä\²ÃIDATÁËNÂPÀ9§lñABÕ…ÿÿgÜ»ÑD.J"H°½·ÎD€€Ý€0ð ðàÆ¯O@ô€öK§”»³H0è¬Õï$ :kU+âúƒV ŽÐ#½½`l-ê-W^%X1?°ÁÆKš-&U)‰“7˜¡ˆ€­g.¾\Tµ–Ƚ³f2STŒ‚yR¢Nš†¦9ˆ‘ ÚÎÎ •B) €ãJˆÿ‘a?Èù×|’IEND®B`‚eric-6.0.8/eric/icons/default/shapesAlignLeft.png0000644000175000017500000000020512342633755020772 0ustar piotrpiotr‰PNG  IHDR¹Ú„¨ PLTEÿ=ûÝ-tRNS@æØf*IDAT×c`b&ÑP0%Àˆ…‡•‚*j‡›V €É#‚‚j›ZPΡi;äIEND®B`‚eric-6.0.8/eric/icons/default/ircCloseChannel.png0000644000175000017500000000302612342633755020761 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs „ „ªâcytIMEÙ&"º­Í3bKGDÿÿÿ ½§“–IDAT8ËuUYLTgþîí^”}aÃEDQÛ‚U JJ©µD¬[ClklûÔøÐ´ú`Ò¾4icjÅ«I­ÒÁB”Hi«±VÑ"Û@gæ² ³¯=ÿeQ;ÉÉ¿{–ï|ç ‡ÿù]7ŠQüú‡3gD—ÓÙÊóü©—/_Ÿ}¯­¨ˆÉÌÉ©øñüùú»»;8Ž«£ëoÊkkÝì]ñ<£KJT@àfAqñBQ#Àó™©éé{ôZmcÛ½{ÿ2ÌÔԣ˲³ËRuºyAH “ÓÒâ ÍÍWØ;ÿ<ÃÁ`0§¯»;>ètbeVöî߿߯†Bù³:ƾ¾"ëÐ⢣±© «ss!Œl™}W>mðì±c©íwîäLNLl]®×ƒ @0€4>Ž?[[¡àù”w¶m{“TÕädyJZ¼^/%Ä£µ¹==¾ƒ¥¥èîæœáÊ'Ö¯X·®É44¤±;Ð-^,¢·þ~(U*p<ÿ™ 9%¡`~r¬P(0d4B¡VëW¬YÓBßUq³†ßß¹óì»v•e,YBñø|ð‘a¦ T«¡ Ã<7­N…E çÔ”œ]@¡œŽqxd—*+Ÿ@a·Û#­&’ââdEö1[™±€› íñÈNX £le3 xH‡Ýu¶·ƒ |b8 NÙíà(-ÚË)2ì8Š„EÃÍ:cÅ¥÷€ß?m|&ZÕÐà ü|sPì).ÖÅ.EFEåm *ë32dìz{{ÑÔØ8g”9¡¬vïÛÁÅœŸ:~ºÁ畤æèVe0XÈS¾$I®(¢ŸÒcÞ;;;!Y­÷Ç$)‘ í«È¹ì€Š ‹Å‹ÙŒQ«uó°Ù¬—¤¨ õõß>C7Ò^¥1&6VNUEéuwu1¬[kF˜JéæÍ+uééPj4àH矇Òi©6üÏå1!O§ÓÁCüå «ÕŠ V¥ò7ö¾£°0’t–§L›a‰žÇÙzëRCƒÿ* "Àü¯PˆÏtaœ›””$ó—öèíé™.T0Ø6ãø¥Èèh~ü«/á8YŽ Ñm``€é´u9²DÈßxË›šR}‘F÷ÙáÃÙÁwݾ­'ÜÄ’’EA¡¦T®]CgG£œÓ P½ü¨K³³°a‰Ih®«ÃŨÆ{Ï[V‹/ëëó7n«¨æönß~wcnn¶×å‚FYÚ²QšlÃá¡= ¨©IT´:ü Í0/<v.ˆúö(ÿ-˖Ѫ„]ÂýÚŸQ¬ÐëË#4ŽÏtC¶Ê^Òl€ò©³ŠŒ'½Š®+„F-àínD *,5Px˜ô:pÏpõŠÛfßÁ'''K ÇÐ é™0ª±ólçÉBN˜#ÖÚ«Ož‚y~$¤13`‘à6K0t¡©íw“sÊYúõ©²óÑ£í9Š(j-HÖE*"~sK LÄÑÙbγèýí²2x©h«ªž^ømîizE ˆà•6*F8=|]SÓO ‰‰´‰‰Ä^êy6|z©Ú4?¾ Is8:âôh:ñ×6<ŒeûÐÙŒšâ"`Š‚0éÆÒ– ÑÍG8™n ±±nž"uЬpS$¬ Œ†_[[:4°@«u2(þ8JÅëëƒÆæ‚%1\¾Æ*—·Þ¢‡zÂŽ,ŽÏZ¸vM“üפQ©z¨ò,cc‹=„q)ýγÇO½êôú³·—7óšTrºY‰¤.Ö‚$ùÍg+í_¤¿ÿFïAzñ ð3¯­þÐí ¼¹ß‘‹Óìöºd$MçÈ¡9zÎ>޳Ç(ÓæÜÔåw.zå¡àç^_©®lz×µ4]Ò¤Ç^»M½`2‘Ï`)ÃGŽ`dLÌŒ‰Œ5VïÜbymƒ‰æ¤scu÷äÞ¯ŸÙû?ð7¹YýðÓÝÍ£ÓÖù¥)~òÖ5y&l“™²IÎÎóøçqÜ%í!ì»)››+ÜÝÞËE²ìö'[¯?ÛPÿݰ¶—Ü\š«[çO7±mE³d±8™çìÑ ’Á='de»ÃW«tÆš8õ|o@×Ež«•– €8ÿsç§9¿?ýå5<%ùd§GÑT4Š&’ÁL5Ëf œ;f£´„¶KÏÑóztÀR©JµRÄiõËõï\ù.€¶Ûx¥´¾µù‡³ÇgDd)~öÖ_Y»szÁdªlRÌHMc»ѬÔlé’N”¶<®Ÿàù.µråÕÕ§ßøóÞÒÑ´ •¬.Œb–ß½{“~„® ¤€mÇã~7àÖÖ˜RÎ ˆeK’ÍHNÏfxbÑ QË0ñS° &hz6ñÓjø/Ù¹Ÿ­ï0öC„!ÄçŸÒvC&Šúã„'› %!Nà^¼ë@ªãR2šbb¢F¯?xBÊî¾!Lc‡ª() ã”0Nˆâ”8Iñ‚?ˆ¨Ú×FÉ8IÁqáÖ}Èh)ǧóH%qÑò˜tǃ3yK1QÈqéšEÆAÌ8Œñ£„‘àŽîì…)£¼‚¢L†ŒbA½h1Ä'´©Ç^úÁ¡Éºr½ˆ0Ž(f%7ï´0u Ci(M¦)~àG’¬¡ãúA࣠Øîk´:mR4º¡3 Â0Výcw8:;[:DÙÒ˜:fQμý—eL%‘Òü0âÕw4f0ùx½‡5™lLóï­ÙÂ4–•P/Ùtq_ålãvßuÏÆQBßÓФɗæÜñ&·×wØØíòè\‘¹šE«ð÷µè¸!~”°ºërF׺M6[$ Zû=jÅÜ?ÔöÞàŠ­»ßZ˜‘¡È0€œÓäñGæ1—B^ýÕ?ûé)H’/Šx³ŸFe!$«Npb×sWÕ°^ ´¡»u¯•?<«€[Øé©Cè·ù`­CÞTJ"… ISü(Áõ"öÞ_çâ׈’˜n·CFSncƾ¦uo¼é½vu}»í8Ïתe¤JfH„ 8ý.›Î˜(øQÊ8LˆS‰®g¨Øyê¥?æ~{ˆÛîóÈâìÅË/Vßÿ<Ýæ¾}åz½RyêÄ©)ìl‘œn1YÒxïÆ6ƒ±ÇØ£˜$M‘BQ ËÈ·Lò†N¿ïc[Æ»¿ýþÌWÿ'Ý‚XasçþšqñäRÂt%`¡ZÇz´ÉÝ}Vß§ï…œš1(ewZ}O‘Š–3 ðƒžªé/<0è/þ©šÑ¢·Kõäì‘&³¥9Õó4l‰©CJÂlYP/Jnl$|´æòÑÊFFOe£ W¿wÜyh5}ù‹–Š/ ”f6ÕJ™’C×3ddÈhì±ãŒé ýa±h¾|ýG'ß|h5 !, ÔTùȼ}òkOéÅù3Ên,èf¥"„*ôÓáÎÆp÷öÍö§ü[Ðݸ ì[@/MÓà?+¡—ZyñsIEND®B`‚eric-6.0.8/eric/icons/default/open.png0000644000175000017500000000206212342633755016665 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<@PLTEÿÿÿdx©Sez¦ÚršÉ ... 111s¥äq¡Þh æh æ[—ãZ–ãj›ÙNŒÜL‹Ûc—ØY–å~¬éAƒÕW”ã@‚Ôƒ¯èZ–åZ–ãáââ[–ã[—ã[’Õ\—ã]˜ã^”×7zÎc™Úfœà6zÍiŸäl¢èéêêêëëìììíííîîîîïïïððððððñññññ_˜ár¦äs¦ä-rÇ-sÈ/tÉLs¢a™àbšàeáfá,rÇ/tÉAjœXÔZ‘Õ_€§`—ÛdšÞgžâhŸéi†ªiˆ­i êk çk£ïm¥ñrŒ¬rޝr¦ít¨ðuªóx­õy«ñy¬ñz¬òz­ò{“®{“±|­í}®ñ}¯ð}°ó~°ó€–¯€®ä€°ñ€°ò‚´õƒš³ƒ³õ…³ì…µö…µ÷†´î†µðˆ´‰¶òŠ·ó‹¹óµæ·ê»ö޹ì·é¹ì¼÷¼ø¸ê‘ºî’ºî’¼î”¼è”¾ô•¿õ–¾ê—¿ì—À옼蘿ê˜Ãø™Äùš¿ïšÂîšÄù›Àð›Áð›ÂîœÁðÅõžÆö¡Èù¢Éú¢Êú£Åì£Ëû¤Êô¤Ëû¤Ìû¦Æì¨Èí«Ñû¬Òü­Óü­Óýâäææèéçéêèêëêëìêëíëìîïïïðñññòòòòòòóóóóóóôôôôôôõõõõõöööö÷÷÷÷÷øøøùùùúúúûûûüüüýýýBXYHtRNS $(;?Œ¿ÃEéVF¼)¥Ô©ü‰Çɴă€œ ›ìéCtÕN×/¼Ì©»å4ž"§E߯•åé¢~Ü"RŽawÙ +Pžéf³õ¿(³ç23 Ý,€ªÊÑºé¹æ£ä6êf¹â³ÒÔb^a>Ém#ü§ôåaÍY`!ÃpêIEND®B`‚eric-6.0.8/eric/icons/default/callTrace.png0000644000175000017500000000046112342633754017616 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEÜ   ™Ê(ÓÈAÁØù:EMûVÑË‹ò?õó$+¿4¤ÆÙפƈôAR¼µ\ƒMŽȶ{ ¾¥kÞ¿À›úÀ^ A—¾&7? 2’ö—IEND®B`‚eric-6.0.8/eric/icons/default/continue.png0000644000175000017500000000027112342633754017547 0ustar piotrpiotr‰PNG  IHDR©þã#PLTEÆÆÆOŸ`¿s߃÷VÉ­¶tRNSv“Í8TIDATÁQ „@°w§€’Ì?dlpÀÿfh@༄îÞš(Þ‹‘cØ¡¤~Ü0)€IL NL Ç¢Dñ¡­î&p>° à„ðœ÷î˜.´IEND®B`‚eric-6.0.8/eric/icons/default/cooperation48.png0000644000175000017500000000555212342633754020430 0ustar piotrpiotr‰PNG  IHDR00Wù‡sBIT|dˆ pHYs11·í(RtEXtSoftwarewww.inkscape.org›î< çIDAThÞíZ{pTg?{{÷™„$¨IÄ@Ic H)bK)£åÑL©þá£VâŒÃÃA-ÐÎ`+:v¨Ô‰UtmÑ‘™Zª…¡BG^R°@x$R! !›ÇfóØWv÷®¿óíÞtY6…ÀL§½3'ßÝ»ßã÷;ç|çœooLÑh”>ΗDóKÍÉL&“ÍtÈ,HD†„ á¤Ö©†…tÝÖš·ëB]‚æÈãûÌf³²xñbš1cåçç“Åb!I’¸éºN—.]¢}ûöÑ‘#G(‰ðâ » –º»B`44Ë!ÏBæ/\¸Ð´lÙ2š>}ºÍ@…B!2æç–I(ŠBV«U<ëèè +W®Ð™3ghÛ¶mäõzßÇã*Èߢ#–6€(Góš¦i׬YC”MÝÝÝ ©¿¿_‘ÿ‚Œªª‚“Û¹s'mÙ²…ç9¯×ÛÁQ#€Æ£yíŠÍ›7k<“ÇãšNudn£ÈÌÌî¶cÇa¸Øøjúøo‹&ÍsæÌÉb Ùíva~,0b€#íò²²„W¯^M§OŸ>‰ÇËЧé–üwÐlß°aƒ¼téRjkk®’Àtú}eY&‡ÃAì¦çÏŸoÃã…x~&-¿ Í‹[·n¥™3gRKK˨k|¨>l &±víZÞì­xüE<¿<" òbUUPggç¨i?ÞLbýúõÔØØÈàçbœkHô%4{7nÜ(•••‰s'5=l¹Ï#•••Üÿ-È“ƒfâx´ùë¢E‹xöù; ÐÓ s×£dV‰>?Ñ2dÈ-//§]»v-Æ¥˜÷í”À—ÿFXøÊ+¯ˆH3Z®Ø‡#ÌÉ?ÏŸH÷N)¦ïUÌ£_€Ö¼¸Js‚CÎ`·Í|(IàåݾråJr¹\ar´\¡þº´Ì|***¢ªï>By¹ßegب0¿‚žš!]©¸¸˜Ë‘||\Á¡=Ù…69Nš'ÓÃs不Ëg8 —c8[ǯ9À\–hUü'77—üþÔ™Û²SAq9œöA´cÓO,,¢—à×›9íB1‘@*"I¤æ'˜Ç¡ŠË„T“tèciéåô¯ÎÀÑ£G %GZY׸¸¶JµvrÍ”p=¨ÄÞÃîÅ5W“[Kc JH³Ú) °‘ ŸBýAœ‚É 0Ž;FœÌl6Û€˜ºº†ÕîH5md1€ýß9xšVoýɪNÎq…¤x$ä'ÄtÝG¾žäé®ÀÆ“ÞÞ^!‰—ýb =óÜxúõóß¾Éä† &æ‘AªÝäp+5š{Ýðu E›„çP¸ßO½®Ts4Tˈ@6G™ÐšdÞ´&F³†(ä÷Ð_ªž§s.Ñ›¿ù ¢•$"04i„^¾çHfLl‡žËf·PëE#,ý¤‡úÉ×ÝIžÖF¬£'kU p< ´Ú¤hVˆd³•$ÜË ÷í½´¸ò甕‘AšÅB_[4‡–/˜!@óÁ~óöPM‹‡,òt_ÁZ÷ô£¤™ÍÃ7îe šôÁu|†ûô¸š¨×íJéŠfÍUTù7óULpÝïí`¶9IZÆ4VHÕ ÃÝ>¶kPüÌÆ ³x£GпÏê >„Ý÷š½ôþ¦×é³ãshÅcÓiViá `ûÄVPŸG€÷´6¤òùx«“4[æÁžŽ¦öÄRâÏQ]Ž}M+#öC¦˜²ù¢ìç #Á¬QDSÐLv«E¾ì ç£hGC<¬E)bµÍWiÓkõ4iüz`j=[ñ°cüÐeœ}E‹ñ~Ou·]CÈìO ^x[V.Æ*¿H>‘ýòãH8$u··3'Ta˜H†HJÑAÅþ€K(Ü* ``Ø…˜n)ÜÑhì^±‡¢° ÿ°«Î=Lûý¦Ñ·–Í£©Èî‰a·9ÈÝÒ0H3‘9Á>&dE;Ñ~µfÏ 0¨y·K@‚zÚ¯“=3[€–3¨ÐTlƒó½ Z ‡#ÚcòyýloŽ[-*ÀD[ÃasÛj¬ÑáïÑÔÒûé ~ŽV­X úœ¯¿˜:j! [ÙdËÌÅÞs’ßÛùÓÁÎÄëøD±òðõzH‚¦9…K Ryœƒgywÿ1š7s’pŸŽn:sš¼Í$ôh$îz±G˜DD$£.W35z—ì̦7w>.¢NÝ‘ÝnkFY¹ð},íßá¾vñŸƒþ*A|èüÙP?s&I){ä)ÊÌʦ+ÖÑõsûY÷1‹êÑx~ÐÓ®`pDA‹-šCª-C¸r¹éÌû÷éº?0®‹þÃ?"Ýõ·®jv²"1p3Z•CºÙŽ ÛNÌêj¹\3ä  ÄÜL½¸eUP™…Æ3…¿«©ªÚw²ÅƒWëV&ƒî—¹"4g!ŽQ¯Å{JV¡Y Àf¡µ‰ØÎ9ˆý\F¤S‘PÙm€¤¯±f¹ëâ©Cé¾bʯ¨¨pTWW‹—©ˆrÎ⣨£/a¿ÄÀr©"˜¢YP°h¤ 6[‚„„h§ša áþa2±`øÜLuIEND®B`‚eric-6.0.8/eric/icons/default/attribute.png0000644000175000017500000000036012342633754017725 0ustar piotrpiotr‰PNG  IHDRíÝâR pHYs  šœtIMEØ!VjÈ(tEXtCommentCreated with GIMPWPLTEdddmmm”””»»»îîîÿÿÿÿ StRNS@æØfbKGDaf¸}/IDAT×c` 0 @¢chˆ#˜!ââ¢f›8AÆJpT±°"º9 ØŒ!ïJ·=IEND®B`‚eric-6.0.8/eric/icons/default/fileModified.png0000644000175000017500000000134412342633754020305 0ustar piotrpiotr‰PNG  IHDRójœ _PLTEÿÿÿ³Ž‚f !!!999OJ9xr]………†††‹‹‹Œ’’’@4 °šPœ‡A5+ ?5îîîðððÒÒÒ`S,i]7n_-na8{j3†s7Œx:”‚I—n£C¨˜dª’G±œU¹·±»º¸Ä´€ÅµÈÀ­Ê¶vÏÏÏÐȰÒÒÓÓÓÓÕ»fÖÖÖÛÛÛÝÝÝáÅmâΉãÐåßÌæÎçèèéמéêêêêêêëëëììììììíííÜ¥íîîîîîîïïïâ¸ïïïïðððíáððððñññå¼ññññòòòòòòóóóòîóòðóóóóôôôôòôôôôõõõëÇõõóõõõõöööñÞööõöööö÷÷÷÷÷÷øøøøøøøùøùùùùùùúúúùõúùøúúøúúúúûûûûûüüüýýýþþþÿÿÿx¾tRNS##† aTgÉ–#tÄȇÝ|<£!D!Â~ó{»ÿ², Ñ92pøuq;~nwKáávó!îdãî!>¿›iXö‡«ífFBžtfD=ýv¿™!‚©,óD€ÿÌTx^{k¯IEND®B`‚eric-6.0.8/eric/icons/default/syncToc.png0000644000175000017500000000243212342633755017347 0ustar piotrpiotr‰PNG  IHDRÄ´l;áIDAT8Ë}”Ûk]ÇÆ3{ŸÛ>GG·#ËŠEvêUª))qK/ ¡RHý hB(„<ä=o})mÿˆBZÒ´¡)¸%„Ö”àB ‘[ST'Žc7±ËÖ]Gç²Ï¾ÍÌš>H±Á]°˜y™ß|³¾Q¿øåσíöV¨K””& KZ™Â ¹™ñøÇ«Qy.,…óJ1„*Ú^íÞ4™ùÍß¾Õåÿ”zõõ—ž›˜Ÿ+WKO)¥¾¢•jV£Jet¢YnM ¶šQslH5Q§ˆ]÷ƒ÷®&ýëÆ¯=¼ó½ï|wû•W~â¿öÆBÿ©ÌTNÍÌÚ±‘V†¥¶7:•\{)‚"¬j)7*åj])E÷Ýå.n¬Ü]¹`$GħbügÏ>¿sîÅs÷/ ¾úÌäÏÖ†.…õòh¿jZ ԼР(¨¸ªŠŠ€zê|=0÷ËãEüÈ©‘ Ñ*­TS?®F¥Æîþûò®ÿèÅsæKp(ÞÓK:ÁZv}üÑ™cèÆ‚  €°'À¸ªî™>Ýdút“Õ[íÖG—¾˜»÷ßí&Ü{ïÂÄi‡RP"Ü+4U§ ¡Ñ¤¶OæûP$y¬¬êá‡^<Þ)ò¢`õu‰ ‰‚Ž×Ÿd´rœªn •&³1=³Åíþ©ëê2IÖÃØü€y¡xsc IÖ'P!­hš“Ãßäxck-[ñ N ãõcÌ =JŒÑÎî±›Þc}ޱ‡(/ c i1 * s,šeº1Ïík,­¾Oßl¢”¢¢ÌO~Ÿ¹©oÓÇØ¬“ä1Æ™C‹ÚSl,Y> ÑçX}–ÍÞ ‹Ëf-½*)´VR¢_Ìãñ€"3)™I°@?¤Ø{ÄiŒu¤yBYÕ®Nòáê_¸Û¿ ´Õ <"ž‹ŸÿžÜü#¥ Š!+Œ êÃ``Œ#·)N™IXí~F7ß ()”z`ºÏ‘è1æÊvºÂŸ6~…sæ øþ(¬#3>^û€îíx²ª‘ä]DY°µ`ˆÉæ Öú·ÈŠ ëü!æyp¢±ÖQØ ­žÍx}Š/v¯1(ºL ?Ω‰o°Ñ»ÍÅ›osskëjˆ8ÔÅN!Vc-gXïÞâBÿ7”uÄÓ½Àìä·8Ñú:µ°ÁÎà‹Ëïryù]>Ù¼DáSï…àa0^á\€8±´Óuð ü[ãÂ_ÿžŸ={6>þ¼WN‡·þð;}õã¥Êno§²¹¾QíìöjÖÚ@Ä+/^‹e-‰H(ï=^¼”ˆ÷ƒ8ÉÓ$˵ÖYE………ø?ŵ"½*>IEND®B`‚eric-6.0.8/eric/icons/default/altn.png0000644000175000017500000000120312342633754016655 0ustar piotrpiotr‰PNG  IHDRa~e pHYs  šœtIMEÔ3¯Boâ&PLTEZ \ TÐeZ *–9Q T V W Y Z \ ] al rv€);·LA½RC¿TDÀTDÀULÈ\NÊ^[×lfj prv"{&YÕj`Ûq^_;·LHÄY i k l‚‰"’'”-$ 5%¡6&¢7'£8(¤9)¥:*¦;2ªB2®C5±F6²G6²H7³H:¶K>ºO?¶O@¼QB¾SC¿THÄYIÅZKÇ\OË`PÌaQÍbSÏdTÐeUÑfVÒgXÔiYÐiYÕjZÑjZÖk]ÙnaÝrbÞscßtdàuhäyiåzkç|lè}mé~oë€rìƒ}öŽ~÷ÿÌ×4¸é*tRNS €€¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ÏÏÏÏÏÏÏÏïïïï²¹™bKGDa²°L†­IDATÓc`1%4 (Š$&1ŠŒp!§??wWG;9¸:'_/owG]v˜KltLD˜­‘>B'¨éÉ¡Ù(¨'„î ~9 w›ª ºˆl¼4šJx‚¦¤”„¸\JdX\THh°½LˆÃ?<ÈÃÙÚÖÒT&Īìæienbbl¨ÅÀÄ  Œ fê||¼Ü\ãY… ÐÝÅ*Ϧ­ÿ­»IEND®B`‚eric-6.0.8/eric/icons/default/projectClose.png0000644000175000017500000000230012342633755020353 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ %œ³tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“$IDAT•Á}hÔuÀñ÷çûûÞí¶›ns®mÎM›'SÁ|˜ÊHMAa… ED‰õ‡Y©ýUIe˜Ë GJƒ¤"ó†d8‘ÌKÐÒéæ¼ÍÍÝîv÷»ßÓ·kÙí¡×KÈknnžYRR²> Íg®ë^I¥R?œ>}z€ èX,VÐÚÚº±µµõµªªªZîþK"‘èíììÔ###ŸÇãñãÐÍÍÍmmm-]ºt–RŠñˆ«©©©²,ëÑÞÞÞ®x<~žqhÏóV(¥V (/1-"\Lø|y&Kc…¢¢nſ牭ó¯Ž?fÁÊ 8Œ:Ëæ*D„‰hòFÃu»œØŒj*« 7ü‡Žý‚¶@€òºÔ64‘ËA÷µ’ñs4ž<Ù¶O©E19Û˜_sðÝóÐÏZD„”mè„Qhjigz"!P®¶ ÙÁ[d;^gäÊÚ7mº¯¤¾^<Û¦¿«Ë¹|ôè¥7††^ÊóÍ àjòDÀÁñ!‘†Â4xÊ4DǶéß³ƒšø)š6o"R2M0!Íœ5kÂÅÑè¢ßÚ;0<_+AD°”!d8²’>ô»Ð—…¾GŸøŠš»0mõrl+ƒ8OªçÖÜ: c1f74T‰¼ò*”+òD%‚¥À²@[`Y`€À€/üâå*ƒozp‹ÂÔ=´‘ŠrÂk×R½a#©ìV:I©R±"X¯EƒÁ"9àñ@È&AkÆx>D~ï"¬3&Ïruÿ#8Êâ­/ø§Þyu|:£Ðø‘4iòÏŽðÌ:ŸBíAXƒÖ Âc Ï8( ¸„bøF7s–·à¦É\¦rfwÄꇰCXwuuuîÙ½ãI&±:›yÚq˜;”ŒPúÀ·?È¥#oQ6o÷<÷çvöCÏI‚Àx ® S´ž­Rì”Æ™¡•ŸpûÂaüKPTʬû? ñóq®îÞKîº×sÖ S´ j7ÀgJÓ"õe©H-÷ÐEà›R’ç2—;é³k춘¢³^«bjÈ® ¬tÒÝÛè>?™ xÿ'xó[H ÿÚµ÷–RhWPä|¸Ð} Ç~„Qòþ°²—’@}ÞIEND®B`‚eric-6.0.8/eric/icons/default/configure.png0000644000175000017500000000400712342633754017705 0ustar piotrpiotr‰PNG  IHDR”$°x pHYs7\7\ËǤ¹ vpAgÜÅéXbKGDÿÿÿÿÿÿ X÷ÜdIDATHǵ×yPWðßLáPYE]#jy °@`1‚¢Èx,cˆ€ŽH¢n´d% *Dآ܈$˜„à lˆÀŠG'"x   dWŽ·ýµ›­=ªv“˜ôç/MÍô|çu÷ë7D¿Ðxø ÒS6*Ë•ÉDþJk¿ÛR÷ ·ÓËˈ\Ÿ»~îjmò±r‹Òcí³ yXiø‘ˆÑw®îÕÆšÅº3öçñ©ý©ã¥ýŽKê!J¼X’˜+•°—é¾zÑ8 ò›$ñ~D>r+Ÿ‘’z÷."…RáªÐ÷†¥„ Ÿùt0×4ç1Öœ›’ºP—±ƒ‚Y&Ç„b:VbAªýºvOíG’ ɃÉÉmRóW.¼µˆÖÍ¢wå 9àpÊá¬Ã"y‘üKyµiDÌ”˜×cÆJ[ êÑÊs6fgUè]0ÿ­ÍxÇÅdSœYüa±ƒ´fx„oÕµ¾h=d™nžn”®›`üÊ…ÿD¶‘@KÄ7ü±ÅÐß—Ý—Õ—ÅXï@ï`ïcêxuª:§íá(#þã°{Å_­™®qÔÌ- ‰ÛWwGü™›ýa Ú·ˆ|“€Þÿ÷WIë3ºàÊÑŽ&`lhÏvÀEk¯µÓÚ1¶o>¤• ¯×©l\Ò¸ð⛲»9£rŒrä…yŠ‚ÈÂzÆv¥GÆDöµ•ýô¢ë€hxÛ¦½våÛÌ£ü R…ÂqÏ–©ÀØ÷/·As6ø’{k8/Œñõõ¡¶6Õê¢*Zû§Òò/.”½Ç&åýPèsÜ”±õ³×V¤¯þñE뀨³ˆZŠ€tÏ›Qv7piÙÇ€(ᯰ8ü««Ðsâòz`ì»vJø>GfÀÀ‚Þ›¼Vvµý`{BûÞ!ˆi sV1’Rû‰]wæ õŠ·=ºÌ|þoѹa@¤u¢‹÷€ôÎ,¢\pû³í€Ÿ7oÁ¢ ŠÑÐ[sâ`¬KCжÚÞÐ ŒÝ ŒõåÛÔü¨ùq3?gì ݵm׿¾«Þ»½×yOykÇRíÒÃKÿGQù jš DõéÕl¢üÛÀ…fo¢¤›àÔ]Y =£J4À_“` ³3Kˆ…n³¤ËPd‘þ7¸f´?®T}à2—å.n.n¦÷æ¶ð.ñóø9Å)Å×Ò‘ÿUtÙU jÐ_T¤_³ˆŠF·>LjՀcüÉÕðdl‰/ðE¿…ãÔÀXüð\îê ˈ€È"d§Kò'ºM”O´çoâ"ßDß Š^»mðZÉã€[Ç|ÿ¥èÑ9 :ë ¤_5ø¢ÆÀ­Ì þfª{—*ºYÉL`ì&ÁÞ¾¨ôz/ò]¼€¿t¬A6< ÊÄ\º¸I^ûARí¹ ˆ¼›€ôh™ˆ*<¨2H¿<ø¢G€›§i¢£`kY=º—_Ôº¯_ôÅÀ/Я¿Vƒ&ö]?àŸ<›a¤“çv8¾×Frñ>ã«ûÌz*ìÏØ@Ó`†VØŸž+äÔBNIÒøž:Ä«'Nd†c…48/¤®ø>Y…¸LµþçÙò¢U~3ádÏ<PY+a¡xꦹË>‡Jaßá…yâ©tt×tÏ„´=+äïï i™(¤©øE¦‹ÿŸ\'~ñ§Q€£ ©÷‰X|ø’»ûv?þh¨ v"zTXtSoftwarexÚ+//×ËÌË.NN,HÕË/J6ØXSÊ\IEND®B`‚eric-6.0.8/eric/icons/default/flashBlock48.png0000644000175000017500000000775512342633754020165 0ustar piotrpiotr‰PNG  IHDR00Wù‡gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<IDAThÞ­Z \Žwû¿zzŠt’ñÆ^Þ™a´é­ÏØÛÞ÷Ï^l¡‘Î=ŸŠNRQ:¬",§UÓÐZD†aC3Ò¹t~êéúÿ~w¿§Ý=îyw\Õ}º¾×ï:|¯ëwü=‡u"b"D4™ àý¬Á΋Ø=jJ÷k°ëÑ!¢ÇD›ý]wÏߦ´˜÷R]"úD ˆ %2Œ'CØß i)Ô™óÁÃEËþó¶·ßܸý‡þ}$å”Mê©,¯“?mŒŽ™8ìï¡Æ¢É”Öc Ž"bDĘÈD"o™Âúû"㈌&2‚Ý7t”Ñä±[ìœ>”íótñMÝw<38æèÅ]q)y¾É„ì;’“|"m]òÑã3Ø*©ý7W(N­9’È›D&G¬¼Yö à"ÒPUp³àè)‡ÿ {ãc£‰ÿ4ý`þ§ WYJ¤¾á‡®Fw¦ùHú/xìô%¯½ûb>~Õà+?Ú`~=Àí)IÝ© ÷*@Ä·ë#V˜£¡¡1Ï÷ã%q[-\j%§cÅÓJljjÂöö6ììx^yú3¹¼‹;÷GÁ#”&>Þ±k¯$2:Æ”¥\ÑËVƒ¹!qºy­åªïhüàðWÔ:“Y5b2Ñôã¥ËWlô¾’pügyMM¶µµq.CTVœ*LÏuttp×Q÷zPTŽn eîÒ í~;æ¾ €"ÛЀ1`¦r:äK9@&ÉkŸkß&2†¹¾¢6˜}²ä½•›<ƒãN6UÖ6rÊuɉòÝ]}½…)OonnæÜëIE%>}ø¯ß¸+sFN;ƒw™¾Ì…DìZE'ϨR¾à©VóÉu3Xq2àU×3gÏmí¼ÓÍ%àÀÂҪ>Êö:8Ïe(¸šºÌ¿_„×Ó20ÛɳóÜòÕ-ß/XTkca_îù£ê/rj=£3Î/ ÎZ€<â3²bfÀ–—s?óŽ‹68Gdgäü&ïìN‘ŠƒZ¿¸ü)<‘…‡×nîº5arû­Aíõ"õÎgj"ùÍ¡ÃÛ-Öoˆøfýúl…Ū¬O-øÍ8/ò{¾Ðà&ÎoÂè¡?{®©ñºm!q?TW×?cI¥›ï3=BŽNR´ro Gh2nqßóôÚÈÑ¥Bïq2äôX##R‚`8[e5UÖGs}Ò$¥ËH°³•0Zkí¼ÎÚ#ææ…¼û¤¨v 3ååx!ïO´õIÄM.¡®î~þ+´uV5Ô)¿ƒÎZ²¼[ibaTF$äûÃiàÊj”@Rä¥ó˜ªêÛPø%À"Ó‹×nñMÙõmzËÓê†çó;ï¸~§m¼âÑÖ+ª8*&Þ^[[›¾i$û ½# †e9=e7³´it `‡@Ž—Ù,'çç’ØðR‚X®Ìjþ¢ð5[v”žÊÊÅV’ »ºº”@ôü\ú¨ ½ÃSp³{Leô·¼fΜ9–%ꊳ‘UU~~ÀŸŒÙ廑û…úïD¡‚E+09÷Ž‚"Ÿp¢ „@Ô Ðj“n–´åݼõõõ\>ç@Èÿòûæ¶vŒ;q­½b:¢âGNŸ1óm¦”óñI–BÏê1äH¾©1÷yãs€„¬ °-ÝŒ? `K(B» ;éà”T,--%9½¶„‚ïç M¶–& µOTÞZK›åb ·¦¾;wò‡ ¿½ø³ÓgÍžK5ƒX<_ùÙ”²“sc™Ç¨+üŸ.Ãt;å(U&ç¦2ÅuصÔZÆû‰•T;ÙàÁxÿèQ¢kkk{W¢¼¢wì9†ÜbÑÆ'þ¾µçÞ4;Ÿèc®ûOº$œ²õÜ›% Ž533[xø¼@,æ²Æh0K< Šfìm€hådÑ%e-á/Zì÷7÷X:Ñ,H3ôôðþÁƒXRÒ¢•·Â² <™y•4,y˜qñ7<}á6fþò;þrã>¦dýж~Ihï]feeµB °V…A'óâ€Sˆc¡ÊKÉKŠÈW´”½Û`c«†F›ˆ.--ü3!‹ŠŠ°ªª°…¬†ŒãC}3Ô£ªôIC·€øb;;»¯ŒÄbS!—&•s‹jPnèrL •Uùâ\1Óå•pH†ïÏýp‰ËÒÕyÏtt…éô€øgd$¢¦¦Z è9>©AߨïQ_ììì²V,Ï*¨de–1—¨Àe g©ë €#j:JÅCY`¤“gï×¶õ‡‚÷bûˆÂt[C BC9ÕÕÕ\/  ¢ôq J#S€„bWW×uÀ,!2Iûo–‰´”ÜÜT Yqµ :5P¾8Àž¹2 äbGaþKĽ©ç±²² ËÊÊ0?;[…AˆDXìå…$&ªú€(å\(Ý‚¿%.älN]Hh`°à æBZü O3ŽòÅ„íR âÞÚ¡?Ø`ñ×xûI7î‘.«걬¼ósr°yÊ•ü©ÔÑ‘QYYÉõÄc.ˆSIÇ• þÚ@,6*˜´^±š4ŸFÇÝØ/@¢Òؠʀ7TâßÑ#h•OÜDbý¦–VŽÓ|ßÐЀ=ÂüÜ\|6mšJ9ÿZ‰ñG~Äã§Á¬K¿cÚ¹[ètý¢Ëíì¶í ­ê•Ó¨¢Î$GùšȹðsÛû&¦“ýc“‚’d7ó‹ûp{ÚY566r ®f_ÀÂñ“T‚H›iŠëœ»-%aU!—VnôNµuò\0áGÙ¡B=ˆr!SP‰ti„^ °Š27×ütÉgoú†&„Øø$Ô:y[‰ë(7( g/]ÃMv~øû8Õ rÇŽ»±ÒÜÂåÿVš¯ú×òUfóLÿg޾¾þl¡˜¤ÅV™J(È­¬“„RiÀ Vi䌷°÷‹/òŽ8†…Ÿ*õ·Èõ¼D=˜’…æÛCí<²JF*T5©#4óGè)P”¶Ls‹W ]K´ÿŠÍaûô½tú: Z¹N;Y3ê{K¿øò#ßÝIYÛ|÷ËÏ_½Gø¼ï<ª{ÓbAéôØõ]×FÇàŒO/ý’¥i)ÀYU+Q¡ÛÓ¢šÐòù€‡Œe5Hí¹v’ŽQ„ æs&ó|îè–ºAÝ~ôôUâ:²¿:¬nÞpÝV¦Ÿ¿‰V±Uö®þΚššãYó?µàU *È{Hã²EèÜõžŒ¨p±PKÉQŠ_bŸ‹~‘H½Êò×u¡mû¿ÏÆÚ†f^ƒò|ÃBi4*·Kc.[nÚ:Ÿ=[åïÉtJý‚!Ùs©³ à±qOO2\Õh…„ž††¦ñìZf­jjµ½„L$’ß7±e×7ö]G~ÈÆêºÆ¶Š”£¥þ|7ºGW¹û‡KHµVðMV9Bi[• éÁ¬¯'´GÀ ´¶;8Ù:H–ZÙ{Ť›šuƒÖëêw_yÏDþ½'æ\¾uõ ¯çOú9î—V’|žŒŽ¾û2Ì-,gñhˆˆ?õ£Áz`ß+ °Ü?L•õ9rñx×Êa§d³ûž²} )]w?YŠy›ðÚg°¤¨„K‹4=Ê9<»{|Ÿ®JSKFÌD —°|/ÿs]fyogG—e4ÚJÎ}š@u0d«'Ú¡áRéVG¯÷l]C¼¾K;÷èéÓ*¬(,Šۿ‘f¤ŽÈrÊ L’å$ÑU¡“æ”Ìë¸Ö>¼rí1cÇ3ßÄÛ¸¬hKiÛx˜tÔ¿U ÅÌ“ÿ`ž!§rš6Û%3¼wKÓ2/?¡J ÚÙ¢§g ÛWy9›"SÅ));›{ ×lh·ÜægY£ÃfùWR¾ÀVGÏŽÒ=;^@1M®¨¬ÁCGOcðæ·G>–©©ÑØýºÊÓ‰·` K—CXq¿Ê¶*–Ööÿtð—¦e]­ÉºThjnÅB#‚¢Nàî¯lä¥# k䯱áǧ鎌&ŒbýÉÀþlj÷ñ6×w¼Ã<Ó³¯=îë.ˆ5 -x¯  OŸÏÃ=‰é2I`B‘ÕfŸ3gߟwN&5½Žâ”8ÒQægÄ\F‡—mÔú³¬iïê;}³$ØÓ/*¹"'ï.æ\¿‡©?åbâ‰s²Ð„“Ò°äjI@|æ&{ÿà­Nžæ3f›L××7˜<_,ž™°½à¸Ð&77訡çhæ!„>Œî13†kÄè¯ßx½l7Oé›^A‘kì|£ÎxíJ¸áÆÙ/*ÉÑ+4Ì' Òwç®èÍŸ/_3Kß`ØÈAÚÚŠï3˲´9A1C%E`º ÀBV°¦0…{h#™Ÿë*)þÚßA¨»J< öÆ0 Ž:´= ,ÞsGHäzÿàOí]Þ]¶lÙ艓Þ2Ø`ˆ6[b1óQÅ&Ú ÿCá<ÊÖgJkñžó_)®ü‡B]æƒx[Gê/SSúrEƒ÷ _øŸÛ¨ÿ]Jÿ?y’ž˜áòIEND®B`‚eric-6.0.8/eric/icons/default/editor.png0000644000175000017500000000235012342633754017211 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<eIDAT8Ë•KH£wÅc­ˆŽV«àÊZt'(Å™ꨵPµ/ÝÈT¨Á…ݹ² ]tÑ"îZ¥TÆ´+ ÝŒŒµŠkÑ;Æ$“hŒy¿¿GÞÉé½ÿ1R1ø‡<¾ürî9÷ÞO@óª‡ù sssƒ»»»F7}V•ý¾¬¬ì›ÖÖÖĵ/ƒÔÖÖ–ÏÎÎ~¶³³óÈd2Iv»=ãr¹àv»áñxàõz166ö9_?444UWWg*))ÑÒo_ÏB^«¨¨xcff¦kkkU¯×‡-KÆjµÂf³Ááp€ óù|ƒ…BÐjµë•••U¤T·¹¹íè蘿T¼¶¶ö@°ë`6›Á¯z~~§Ó)f “Âa(a?9̬¨Åªªª@aaáZOOÏ­Kðâââ4Ot]B©l¡Òëq#àq"ì÷@ù JDä¢Ñ(b±VVV2ÅÅźÒÒÒÇTù½K+ù©««ë.ƒOöa5À~fËn…ÏuŽ Ïƒ0+TD"K$HÄãð{ÝèîîFMM=//oúJF¿i±˜a=1ÃaÜ¡”‚áÒ%I¢’%Då ɨ‚dLA*Áèè(ÚÛÛQ^^þŒ%¹À”z’ƒr™öàs’R¯rÐ •¼Œ©’P™L&‘J¥N§±±±! T-¦¦¦®uÕX³··wf?;Ç|¿ßY~¶ô$4©L'""¸?úïÞ¹ƒááaXáκ¾ð[¶ÀgÕ# @!µQ *®†É‰JW‘Éd„Ú‰‰ ´µµ¡··Wt ÈøVNpggç]·Ë ¿í’Ç&‚ʖϰ,tG»…÷:ÚÑÓÓ…ŸDT•E‡½•L îÕP(Å}BD‘ o“Q™,P‘¢À" «ljjÂÈȈ²>ãããƒ7 hÂ’RÀÕ¡' ¤+j9´ÉÉI´´´ ¯¯Ï z(!ÿ‹AQdloo¯ßÖÐ([e™Jó[… И Ýþ¼ßÙ),xðÃ÷P Æáòõ|NOOÿðJ‹,--}'K4U.Ùå§ š"å÷ï÷£±±PUUL!·#W¦° ìçYà50È?ІÜH0kÃÞÎc˜ÿDÿ§÷ðôo­è™††‡‡‡ˆ;ãøø8FÌÚœŠ9@…ÊŠq›y-Hr›Qx ?=Àúo“Øx´"‚b xãYŒz<×Óâ2ñŽÉäçç·Ü. ÎH ÃN¡˜“Ÿøò l®.Cö»`6ü‹gÿ<^÷v›UŒ?³3¶jø&°Æ`0Xã´^3)ceé<üýW  ïb¶÷ ¿§u ¬®®îWWWæôø"Àé8m®dÈ!³úl¯fû–¡´«#ËËËKÍÍÍŸÐf{›xEtòr*ÎÈà„DšÚ{™Æ©æç翪¯¯o @¹¸ýh^rkËq¯+£{ÜÆÂÂÂ×·oß~çU ¹Î+*˜Œ¬êIEND®B`‚eric-6.0.8/eric/icons/default/preferences-python.png0000644000175000017500000000172612342633755021552 0ustar piotrpiotr‰PNG  IHDRÄ´l;IDAT8Ë••Oh\UÆ÷½73™™d’ÒióbQˆ’¤j M,QiDŠ EªPÄ­¸×M×Õ­.ª ¨à"ÝèF°¨…VªSºiÑ©¨¤Mb2Ó43yïÞs®‹™IÆê¹ðmÎåüÞáû.çï=½Î'_Í=tmµ±÷æí”Z¢à…B䙈‹<9¶óç§Ÿü½W¯é>rül9qJE§k‰%uŠ!@(å¶ ˆ{þƒ7_^ù¯þ ×UýÉÑrqú¥©ë i•†UÖåz%áâõÚôj-9Ù«?êu‘ˆ)d˜)Šê½*RÜ2X\Ê™ËËœûe™zÓaÔáUñ*¨J .–Áyš{«±Š ê¨Hp¬TUúsA<÷×oõw3˜°4;¹ÿàÂø½ÏN—ë¾ïäÅ[I±fi7fPDUƒŠÁ«´'nYÑŸÍÆñP娮ÁßC#ͽ§6À7Öý»WÖ䀕U‡Üë§tÔ±Aðª8kI›ëvÔA-ù@v¯Ì¿ñlyÏûߟ{aæ.ùCN6½óÚzZÝ îмjË®¬a hÚV’ÏæJ'®œ‰þXZ/7E6éxèUð²©N ÂdœÐÝI@-Æ[$­Æõ;óåèæZJ-¡øfê^„b¨ — QQéL²{$âÐÄe†òUPÛ’·d¨QŒ–ˆB£lL£"uLß—ðʾ ÃkÆa à=ÆxÓd[¡F6H1jÁ»M¸D w‰vm˱ÚLP/¨WÔ+÷—BŽLV™zðaØ~^Ax Ò†ùΤ®]³(Û‘h”à‘]C+Å\¸è»ü ޱ¸Ò‚zßJÚòRж$ùGÍKJŽ¥O3ùáSÁsOí??:ðÉ—ŠYrYÓšÒ»®Ô»$÷Ö,Þßî™ôG_µÀøÈÀÑ[Õ»c¿.»ñÈD;tMÑ4ºv“è»´á§·tîðQÏÕÛãuš8ú¯µùõ™ï…™ì¥RéÜøÃãx»¯ÕìPux—¾½ v n1ÜûýG[ÚÇ\}í"^öuäÅâUpf;T üKÁž¹É-íc×R+8£ ‰ 9ü 8ÍöÜn=Á·*;ë"­)»Cʘ î¯/ 1Ïrc¢¾ep5=|­:>[³ñb-í§™†4l 7@Ôøq±Zë›­ñðá-ÿó:gá§3a2_Λ«¨ÏR—\fbeì±×Ïÿ_ßßÜkÆaÉ9µIEND®B`‚eric-6.0.8/eric/icons/default/multiProjectOpen.png0000644000175000017500000000233512342633755021232 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ èr§ntEXtCommentCreated with The GIMPïd%nšPLTERRRfff„„„xxx-rÇeee„„„ttt~~~ŸŸŸ‰‰‰©©©«««nnnfff`‹À›››_ˆ»ƒƒƒyyyŸŸŸ———^”Ö¨¨¨››››››ªªªWÔyyyŠ’œ   ‹‹‹¥¥¥¥¥¥”¨v”¹´´´u“¸x•¸jŸàiÝ›ª•Ÿª˜Ÿ§‹›¯œ° µ¡¶“““‘ ³“£·£ªž¦± ¨±¿¿¿¹¹¹£«´b›âb›ãk–Ë{Æw›Åz›Ä†£ÃÂÂÂn•ÇŠ’œršÌU’àx§ß›ª¶z©ãÀÀÀl á°µ»QÚÇÇÇPŒÙޝHˆÙz¢ÒZ“ÜÒÒÒ‘®ÈÌÌÌÒÒÒ¿¿¿AÐRŽØsœË½ÀÅÑÑÒdšÜo¦ñ±òŒ£¿CƒÐKŠÙP“êQ”êRÖSÞT‘ßX–æYšïZõ^Ÿõ_Ëc›àdšÜešÝg™Õh¤ñk–ÍlžÞl¦òm­ÿo¦ðo¦ñq°ÿs§ät ØuÍu¤Úu«êx¦Üy¥Û{¸ÿ|ªá}‘ª}ªß}´ý¯ä°ñ±ò·ö€¬â‚©Ý‚«Ýƒž¾†ºû‡«Ú‡¬Ü‡´Þ‡´á‰Ãÿ‹–¡Œ®ÙŒ¸í®ÏÃÿŽ·ØŽ¹íž±®Ï‘§½’¤º“¢µ”ž¥”¥¹”½ë–³Ô–³×—£³—¤³—ºß—¾ë˜®Ê˜»å˜Å홲ə½Õš¾éšÃ윿骳¸Ùž¤«Ÿ·ÆŸ¾Ö ¿Ú¡ÃÙ¢Ã꣮¼£·Ð¤¯»¤Áà¥É즽ԧ¼Ï§Ç쨰»¨²À©³¼ªÉíªÖø«Ëß°³¶°¸½°»Ã±µ»±¹À²´¶µ¸»µÁȵÌ๿¿¿¿¿¿ÀÀÀÀÀÄÊÂÈÎÄÅÅÆÎÓÏÏÏÑÒÓÑÒÔÿÿÿ7_gdtRNS!)+13445yåÜ?Q$aÓ‚é{ókçŸ^´0HU„ &l”>á@FÉäm—®Åù¸XsÄӚw,ÝrðÔå«@¥6ËîÞ^$;?$<@$C%>D$?D$@G%AG%AH%CJ&DK&DL&EM&GO&IR&JT'KU'KV'LV'MV'NX'NX(OY(P\(R_(Yh*[i*]l+]m+^m*^m+_p+`q+aq+ar+bt,dv,dw,fx,fy,h{-i|,i|-i}-k-k€-l€.nƒ.o….p†.r‰.u/{”0{”1ž2‚ž1…¢2†£2†£3†¤3‡¥3Š©3‹ª3‹«4¬3­4Ž­4’³5’´5’µ5“´5“¶5”¶5”·5”¸6•·5—»6˜»5˜»6˜¼6˜¼7™½6š¾7›À7œÀ7œÁ7Â7Ã7žÃ7žÄ7ŸÄ8ŸÅ8 Æ8 Ç8¡Ç8¡È8¢È8¢É8¢Ê8£Ê8£Ê9£Ë8£Ë9¤Ì9¤Í9¥Ì9¥Í8¥Í9¦Î9J¹ÇÙXIDATÓc˜ ¦´õ3`žÖžÒU]\RÛawN† w§x˜ji™û¦öCø`á)en2¬œ,œ\r>USàÂev¼Œ"FÎŽ: B®Õ0á7>ý„ʶ–ò8M6!ÿ~ˆðÔdiF½\ ».¾4SQ1 "ÜåÉ'’0H»K¸”F ñ÷…kÌX +g̨÷feO,Tg´i iq:µÍèôeoo°b4© —js:µÖ¹s²róù65X…g‚„ëÌÙuËãÅÙy™ÄƒrT˜šÁª{|¹…bË\Â¥ØE Ã&@Ü.Ë ‘Q‘ÔÑ"Â̬”õNŸŸ‹jtAC}¶#ƒuã4¨çk\…™ùÔ-ÍUøÙ˜™ÅB;aAU ÈËÍÈÎͯl-.Óž1cbVˆ­±©}D^S$HtPLTEÿÿÿ€@111€+3™3‹..¢.555111DDD,,,111111CCC=== :::***:::***222::: DDD222CEC8>9:<; ;;; (((AGC222(((:::DDDDED((( CCC 333 (((;;;;;;222;;; ((()))111222;;;DDDÿ K '_tRNS !"##$+,.2455<=?@EHKNORTXXZfmt{}€€€‚††ŠŒ—š›œ¥§¬¬¬±²»½ÁÎÐÕÖ×ÙÜÝßããëëíîîó÷ùûýôòEžøIDATmÁåB†Ñçµ±»;ÁNìîÀÄÑ}÷nãç ¼ÈCyH—pà8Îåz9£ÇOŽƒð%¯“ÞŽ-¥§†Ò·«1tº“n'î=îìÑs5>Ë©’Ô2o¾½ªû.2™Ìïó4ŸLßítdŠ[² °vsøRG-ž§‹Ÿ»ñ™‡­þ×ÇÍx¡ó`åÌó¼«&ú<ÏCˆe|“˜ ™¾ˆI 0À b’03f&’øO!äãW¥¾¡?”ƒB„*ô £µmÝÃcã#ƒ½]í­õ5ÑÒ”èù}Š(µýðd}IEND®B`‚eric-6.0.8/eric/icons/default/adBlockPlus48.png0000644000175000017500000001224612342633753020306 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœtIMEÜ$[XÚiTXtCommentCreated with GIMPd.ebKGDÿÿÿ ½§“ýIDAThÞ­Z åu~wϹsìì½bW»ÚCZ­.™ÃâH•BT@ÄP¤RàNì˜à²ÁÆ"²ñCRe ()D€9DI”A¤ t"t¬ŽÝ‹v¥½ïÙ¹»ûÏ÷þîY‰C¶0´ÝìLOÏßß{ï{ß{ï úÇÑ£GiÖ¬YtòäIÍëõzú ‰#‡£¦¦Ænii¡¦¦¦ þ®q¡7îÚµK?xð ×0Œ¿ðx<ßþ"|dçï¹P{€÷Ü·šmÛÃ8ŸÂÚ¯|–ŸµxñbúÊŽÍ›7O¾îèèø«þþþöx<.“ɤL¥R2ɨ3“ͪ3Ëg.Ç^UgÖ½–ÿœïåïñ÷ùäµxM^ûóžù¥öFþ8qâÄm}}}§'&&dšAÁm9¸ÓÄi¹§-ÏØî=¦{fùļ¯Ékó3>ïÙç;þ`Ì8@óçÏW¯[[[oF£‚Á C×å™moÓþÇ~-CÃàA3ƒi¤i¸d}j1MªÏÕ=‘Ô Š‹è’ïÞ'§^óu2-K$‰ÞñññïÖ××?ÿi _(>üðCš7o­Y³F¿úê«ïˆD"¿ <ãìÙñ®8¶j%•vž jŸAvÒ&£@#inÐ}‚,\øËhí´$#¨‘•±t"3a“Ò(ÑÛNÇY)4Ý Š+®”ü <þ±¶¶6cûöíÞÊc¹àä­Þ³g/‹Ý‡Wcá* Þíß³‹ZV>@cG(ð‘ÆKè‚|ì¬$;c«e\c ¹1›¯8 â„‘™Q\Ól²mIcé,%fSÓÃ?¥²E‹É²mBŽœBnüpddä¥Ë.»,s¾H蟾°{÷nZ¸pá$øP(´2Ôèõ¾÷ž<òà÷E¨õ(ä× –H”°ˆ€á×ÈÖId•$,œ× q½oºº…Ï=| Æxa­Õs†Îìû 22}:+t¡¦iͺ®Üu×]­Àd1¶§Ÿ~úüäåëñÇ×›››ocð~¿¿ÎWP@][·Ê–Ü/¢§Ú©8P\×=é@¦ (ÂÑ`ïêl €ë~¼Ç„…û¼Ì%çsÍÀëŒöjŽQ8ƒÉÞ>êܵGxkjeQãLð³8kkk[n½õVùþûïÓÚµk?K!–­åË—«×Ç¿ œà«|!úhó&ÙöТt°›Â!¯+3ü`¡Ð@!OL'ÉJI‡Bn •«æ0þÉ ºèø Ædú-•¶‰p| 6Å-Š'sÔWRIõ«~&§/_.²‰¥ÓéSHì‡×«2`ëÖ­´lÙ2u•ö×L›ÓÛ¶Ëü«˜šè£ ÇPuxŽó9®ùœ’ˆ-|ãtP˱•òk¤Ã}6Y)[ÑÆÄ:F‰P‰›p’ÛÊÙ¤ˆ9‹Î˨aõ¯ NW +—#Ô V§ûPè6œ‹Y Ó *£À:tè6Håã žìÝ-~ÿ{¢´¯“¢¯"™»†â2+ï1XO\œq(£Á0{D’9ѵ XyŽ—IÙa|§„•I’™´H"& ¡*õèX†Ë.¦ÆŸÿB–.\$PC”cccÿ2gΜx]Æ®"°eËoiiéÍÿ+ð~*ÀË¡}{ʼn‡H±®V k>ÅuMp@sÔ%- ækœ`dÂá´ð1…4&7t¶ˆ£PYD ~G½ŠRÒÇje!  !TÈÆÚ㔡á©uÔ°r5_² ¡H$g`Äý¯\ýõY}ݺu:š¨[@›ŸÂóUÈzÙÿþ{¢õ‘‡)ÜzŒ ý‡ãaÐI+rœù0 ét²1".T$ø3#ÀùÀ:Ôab#½%ºÊÁ¹ƒïJPÈSª):Ùˆ*+GW â~6ï½H$»§›º!M­WUIà‹ © ë^²dÉq}ÆŒ¡ ü;´~¾×ï§îmÛ¨}õ*øX8àxž ®xéV…JyjƒÅ£ X…ȹßÃtÂ뀣:"‡{üü—CÀ*‚:®Ø–«‡¦Sä8oÐk¨ˆ¡s„½Ôsä0M£ÈŒ:ncè­JÀœ—ŒöööBV¤ãF¸Zv?ñ[íh£H  €°TÊñ è‘źNøõ  ¸ÀƒX.ƒÂÃGP&L%=œ¯Ä4¤Bn@9€ œÈ"qsøŽÇT¹`# Vˆ ò!„Ul¢~ `ê~â Q¹ì: ¬‚13v•Îkš¦`®â¢$ C“Uå„—¬xš¢Ëo¢¢»ÿó³RîÐ~J<÷ éæ0¼Œ0ø0¾áÿ[÷“gÑ"ÚT2‰ŽäðÙ”Ûþ™ûö;™éA„Åøë"Oc3Úšv3‘¢lWo{‡Æ·o¡°®Q87Á©¤°2fÆn ) ´¼BrâàÔáe[s““‹¤3°ôj*¸j™“ˆüðâ2Jn}“èÌ 9çƒÍOA‚´ªz 4_ª’7?¨þ†xWÜCÙW×Rö…'ÉnUßÍ Ö5‘oþåŸýðÝ~7l~…ºý7'éÙ!¸Î˜»†Åä€!D²Ó\`¸ø@ê¦_L¾Æz'!™B8=åådÔ΀&º—ù»,2'Éu•ú¼47£&´!m‡qÏ„KàŒ•* 9lp PȇC²WNi§‘¿~&Ip1—ÉPúO£a¢+–’(« ­Ôjß(@úm2ƒèuМÙÎÈsû÷PY3(‚åämžÏC QêÝ]á㪌Â%uG:ÝÊG†×&Ú¦`´BâS`™¾‰‘Aг10i€åòJ8Ÿ(Cä©o$½¸T}vzÿ*ê%:ÚB $™ó€Q¡[µ{ÆI/S’ê.y5æªqÕM­À<ŽcüÜóø*º¨ûi ©)év¼k;ŒŠ)DÍóÈ?c…ïü[Ò¢…Š6f6GÙŽÕÎØÒ:|ç£ÀÍwŒFEcî\’˜Ø£=˜£#9x»‹[SÅìydVÏ¢T"Jð˜#q^€Ñ9 (HìµlV%X^Q(½á0-¾ë^Ê ¶‘=ÖB™N›²1‹Ì´é‚òÄn¿‡è§dC²2ŒÙpè… ˜eû°êNÆT˜'“˜ß7(„Þ´X”üu³HC/”EQ'bªòÑDße>þˆä¬fòÖ7Pff% T'qx Æg•)ÎhúÌ“Ð8”UҔ˗P¬ªòÛDÙ›î¡ÜÎû pNï#ugVPXrY5W8¢“)ê=|N¯š.ÂdÇr|®Ó's@ºr±”ÎÓ¦)=NCÇ+¯ºŽ| .%/ú…,‹œÐ|hÞgÍ'kû^´—ð:S [sZ h=C4 J¡šÏüöƒBᢦ…”ó@ÓÓ ²<\@O3èþÇiäã<×¢ôØ0·µÓà›¿§ŠÞ.ò669Ï—üâ. XÛ¥© &ÐRÑ g»¦@%;ª5®+£/½`ž&= ˆ7É (#Ê#‚Ò”0i¼§‡ìñ1²JQ‹‹)[iîÆ{͉Zž=o½AÖ+0º•&}dŒ¦‚b!¦N.[úlÐäv*ŒoæLÕûØÈ~]*'áäÁI~ó鯟Eé¢ Êö}L¹ÚËÃg¦7AÚ઴Ÿ"3ëɈFá SÉr|"AÅ<¼øX4l•3\½£ÉQªï%3#ԄLj5/:RÎ mR‚>›yâ- »¤ŒŒY³¡$&uwÓîg×ÒPÇIÕ»CåÈWX@³ÿüª^¼m´—²W\Ebc»¢R!ö"ä»÷;$ÒiŒŽÜ¦Ù$ "ŠëñÞˆÁ0ÉB~3@ªç2nݽmîɤ¼Âç6>çÌâ{' å¹9 ÞäCƒê¨ƒûu ÈVß´‰¦á¡\Ò=ìµR臲s瑜öÝðg”Ûøª*Œç½‹GG“¼7Ütvï€içÒôðSÿAÓ £É^$i«•5éDn©y2“†3CðæSŒ äÖ=OõOÏE£ Œùs)ÏeîÔñT26D‘ˆ3Ðp³'y#êÄ J ²H’Q^IñX%™£ Ê$ð=TOV“¼WøaV×ÇÆéÔÛ[ȳei) ]-"àΟM$œÙAGC…ªnóxš¶UN*qN}¢ÏËîêÜ^Bz.®§ ¶Õ?qªé±*GV[<ú‘Ófð͹–£tø7‘ ^ëxH¹‰OR÷¦ôÑA4]PᦃíøeNž¤`gUy –ÝŒ™ ®—ž§ìŽíjŒ,m9@AË¥²K/®Ò󀯺ʭ´j&Pæ ìT*O&äñûÄ”oþ½ÅHÙýÔBâS8¹Ó=h4­'2¿Fþ±Aò¼ö å°žŽÅ½%•#ÁwߦŒeªÍ^ÞbQnI`þÅ=P06Ô¶LnØV×ÁÒ·¾ÛA%Dņ¼šxÓw*ø/¤3Iå·þYJËŒ•13v¡ðO™2ÅfÇ CAð¿¬yŽ ö“ÑyŠ|œ¸ný`›¹ÙãgÞ.Œ=ƒ!Û—áÑÏCE…ܬ £c  GÂtÍšMÈ¡‰\~N ILPÍ Üë÷-!p“+:|ûúu4õÞÐHñ±1ÑÒÒÒ»wïÞgwîܹOO§ÓúñãÇ¡õ¹`08»¸¸8à+¯a‘íê¢úü ÈQsÄB¨ù û\-t”B®8»pfÆ‘=¾ŸU„'µeb9ް¸Úz„ÒvÕò.R§H™j{௹–¦>ø#Ókø7ñÁŒ¼ñÆk6lذqtttYjÃëÀ§}>_: Í.-+ xKK)2wžL··‰ä©SÊë,‘¼¯)ÜÒÏ xg;X#Ý^*—æÝ7©(ÀÉÇÀs)[BNT'’9PÆdeÑÝûlg=FD¯¼‚¦­\%EuµH$“bß¾}£›7o~rݺu¿æ<.®»ªÄ³TîðáÃ~¿?#šJJKýà–ˆ4Ï•‰#GD¦¯[ñÚÎ{Éõ*7ÓîvaΉÿ. <̪ŊʹWóMg‘å2¿ çx[*ÅᾈòÐü…4}õ£R««ñ8¹àŸzlœ£¬ºùòjaU!Œød‘õ…ÑhAhzˆÌ™#-GDêL·2Àù¥å좌²y©c0\SlÓW,9yƒa‹³ÀMµ†¥î /XH5?û¹4šf‹áþ~Ú¿ÿÀ›o¾¹výúõÿÃ!°Ž:ôŸÜ^Ïa;vì4ò!#j#¡‚p¸v†(œ‰L¶‚NHlE•Ò™à¸NyóïmEÕž{ÈÉ‘œtù/ÕN4?•“8or‚[i /¿àðMb]8ßóÖ[o=Îÿ‚s†ÁóOkçûƒÙaâÆLggg›˜Q‰„¡N¢pÞ™í<%âm'í á*“å´¾ @•ÍMHéȆñ“¬¼–S T2Kg~àûK®]FÓWýDê ÍP_{žÁ?»iÓ¦W‘ÀXyÌ¥ûù¡qÇY:›†Ýš¦e¥%%þò2Å“é:Cñö6Õ`q%–nûìô„r²«U¸†(°LÛU&Ûíoؼ/½îšþãóà.ÆÇÆø—¢-[¶ü×믿þÊÈÈH|æþÄtŽè&Ò©ÖÖÖ.D"ëõz›**+þ²rAxÓP¦‰Ž'9.…œÌg.vrÅ1™•U¤ \EB*ÃK®¹†j~ôé5µ2©„¾+©|õÕW_<ÇóÙ/úK}|Ïd2]/¾øâƒVs­XºtiaQCƒä‘¨HrpJƒò¼ÚXSUONn³ä~Íï(¨¡Ä}œ>.þη¥·±†‡†ÅŽ;F‘°O¼üòËϹ ?—ó_èwbg³LpÃÆë²+V|ãÆoüÇ¥_ûZjÃaiÆ'Öðãù¹_@; “ñ¸€Úìx÷Ýaxþ·7ndðý.xó-ûÇþ­„úwîB„…Ÿ` dâÞE‹UD¢QAR~¹ Àav8ß»uëÖ5xÆ ç€Ï}%ÿØÃ](ÎCb½‚Å­žžžH_Î1rmýÍF¬ýÓ†Ÿu!à/„BŸgp-G Àó~cÒþ„u&}üœ I1ˆ|ãúqç§Ž ;þ,®Wqþ÷XIEND®B`‚eric-6.0.8/eric/icons/default/taskPrev.png0000644000175000017500000000227212342633755017526 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØç$ tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“IDAT8Ë••[l”EÇß|ßîvïÝRSº´YHì¶*) à‹\R(4F !†^ôA#ቘˆM0Æ J‚/Å_4¡”Š5%FšTÐÖm(¥Øí¶ewÙÝo.>t©@kZ'9ÉdrÎïüÏÉ™˜ËÚF<Ø<·¹sóOwœoewÍΚ‘XGlçÝ!bVhkë‚u¿í}~ïòÞÁÞZZpØÊÑÖæÖ·w¬Ù1/3–Ùqw˜3 t÷ÒäÒ·:Ú;á e†$ÛXàWþîö5íK&’Ê€5=tfp a>Øðð†gW­^eeÝ,²(1¶‰T«m}´µ*è’žH#-9cÝÓÁO³À¿»mmÛ’x"N:—Fj‰6šÄ¢Ä¼æû›DZ£7GQE…ßÀOñde¨òÓõ«×Ï D¤si”¥H”Q$'—ã–t%ª¤PEU jðvöÔÆâo.`™ãÚî¤"[!…DY eRK”VH)Q®B•áPø?zÜ‚C8Z_U·½±>I¶”µ¤‘(B9 iËÉeÕ·àJ+”RÄí8ˆéhÇIx¾O†VFüÆrcH)Ñ~)$Ò‘H«¬ºÜcŒeÐBsiì2X–æ.Å⯫)òc9DL *&bPAa ø“%Ûåé€\1ÖtŶŽê#nB.ßm’®‹ªP– q‡ìŠìâpÓa>¹ð‘¢Ÿ˜QeB„,Ÿ7²ÂïéCßv×=^×ÖS}qÑ¿™^¯†¢¡}n¾hEA%-[’$‰f£¬b%_×~Fýü*j"Â>c7 ¤®²¼¯•³ú,£ÑŒ±§ÀçÌw¥¥ò¼/æÛZá«ð•ó÷Õ4qpË!0Ì ЩŽ_Ï?(´]ÔFs²¯›“}Ý(­øâÏ㸰ŸµõOðÎúƒXFLUâÌéÙ_H-|.qYk½øÌÀ)zr?óÍÀ)z²çYV½Œ}«ß 6Çó?~Û–…Eçch 7ѧ¤1ÜÈ»ëŽ0?X‹1×uÉår”J¥´3W譂ݽÎWOóH|1¥´P(J¥ú‡‡‡ß›3¸¿¿ÿ—Û“4ûÖPLK®peʧX,fwý¤”þ‹¾;áIEND®B`‚eric-6.0.8/eric/icons/default/vcsSummary.png0000644000175000017500000000122712342633755020077 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsœu©qr‘;IDAT(Ïu“ÍNQʼnÐ&<Š;7µÐE7DÙØ†ø†M ÒùPB Ô¢R-bµ­5 0cYôC¤Å–B±eü€.'M"9žùCCqNføß{Ü{î¹3&SÇe1õÙmvÛXŸÅlºîBÖŸ‹ku½qþâzC«çâg·ÐÓ*Öª®ãÎQÅN¨sþžB§ªúþÐ4¹\C5˜ºè7UCj©ÎÝ® ‚Ÿ(u…+Ð`ŒGú& (àˆðW.¡Hýhÿù˜½Æx0!ð슢,oøLå)£þ(#*î«{´v Pª< $‰Ì¿¶ÂÑULVž*‡CŠ€*Ú\m+…=,â)ÜeJxðŠ6ò8Ä'X¡ æàÄ (ûª lºØ±ÍMi‚f9_’‘}gŸn,ÁùK`o1„eqs±Ö¦âXá½.uˆUa¸¿ ìJψ5:l¡óÔ ÞJ+-6üpì Т4ñÓ]e>LqåÇ­4¼G!¼àLž®pˆ±ÍÓ†§ °[™Æ3<F¦kxŽ(Ÿ; ñ=m„á  Wºå9o “´a¤qÂŒƒH>•4¼´±ˆ‰Cm÷œ)ÆèBœé€)ÄÙŠã%ÞaƒÛ[E³·ß»‰â,w¼Àe3<±M‰n»L;Ç‚´a/^y£Gަ[´qÌȶÀk¼a]båjŽø;¾•;7‡ÇåDs—ÉÄU”>7š³åÑñ»7®ý-æÁ^ë€u`°÷ÿö¢ªKþ6ÄñÛIEND®B`‚eric-6.0.8/eric/icons/default/documentNewView.png0000644000175000017500000000154512342633754021053 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEÝ æƒ\ŠiTXtCommentCreated with GIMPd.eVPLTE111tuuuuuuvvvvvxxxyyyGGG111:::;;;LLL[[[GHHqqqrrrrrrtuuuuuuvvvvvrrruuuxxxyyy€€€‡‡‡ˆˆˆ‡‡‡‰‰‰ŠŠŠtttzzzºººººº»»»ÃÃÃÛÛÛÛÛÜ´µµ·¸¸¸¸¸¹¹¹»»»ÂÃÃæççêëëëíííîîîîîïððñññóóóôôôôõõõõõõöööööö÷÷÷÷÷øøøùùùúúúûûûüüüýýýþþþ¶¶¶·¸¸¹¹¹ººº»»»½½½ÝÝÝæççêëëëííìíííîîîîîïïïïððððððòòññññòòòòòòóóóóóóôôôôôôõõõõõõõööööö÷÷÷÷÷÷øøøøøøùùùøøùùùùúúúùùúúúûûûûüüûýýüüüýýýþþþþÿÿÿÿÿ«ÚÏDtRNS9=ACCJKvvwyyyy{|~~‹ŒŒŽ’¸ÂåêìíýýþþþþþþþþþþþþþþþþþþþþþþþþþþþþæÍ#bKGDq¯\âIDATÓ}‘=K\a…Ÿ3sîGI#)$…&$±ñ‡Xû'ó?Ä*‰ K ù h ïêzwÝ7Ž+"âts`ž9gž-¡öÕÆ®4Ý SmN+e Å}óy-/û˯oCJÊæj ¤JéºnÚºýéQ6úÕ/$“úuiº¬í«O#{àˆ°.¯ô˜€”Où¤Î‡ÒYUöKDH¶™•]·58)‰HÛ6b”%)¥Lg 2Ö¾‰Éô½M¬âTÒCœØ=W„MîQ¾`Â쇒‹ã2[Ž‡ÇÆÁÑž±ú£îÝÙŸ9¦ÜÞR™˜H±Úší~û;W|Yý¿“‹†”f¿m2Ú7ß/®‡§(õMÇ õR;P¤n Œ)IEND®B`‚eric-6.0.8/eric/icons/default/multiProjectSave.png0000644000175000017500000000226612342633755021232 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ !öR6tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“IDAT•ÁOlSuÀñïï½_Û·þYÛ• °Û`› $ĈÌfp51LŒõ(LôDÑgO^ØI&pXŒDÔ艓-C Ç”m}mWÛ÷ï÷{?Y"Éb2Ÿ8qâD¹T*}è8Îkh­kÍfóëéé鋚Ç$‡††ïÙ³ç˜ã8ÖÐZû•JÅ!nLLLÜç1I-³c—núù Ëôw;äsiþ¸}tg·<].—·÷yLöØkïýue×n™éÂ’1µÚ2nm/4ÜEªìýû÷ï~HNMMÝaƒ¤%ÆT2O+¡Ù™7ŒìÚ0OÁ@\­V/cÞŸcd)+ÄK›rr…¤ZÆ­B³Öı#òÙ´ÕlµSF$0°otttl||ü 6@6|‹+Íž*Yl†Ÿïè.äèKÝe›c³°XÃÈQ:¦îŽœ=N__o9Š-ˆoLN_1–@Žc¾úòsîÎÏ·åâÜïã}Íoð!m¥_cñ^=°²í|–r±F.réÎXüR]bxx˜¡ÄQÌ*!@B„NBR*mâöìlZž:uêÿ8wîÜ.!D$mˆ-–&Z¼…Öš0 IH‹¿¼€UÆ€Œ1‰N ÏóˆÂÉq«ÜŠç¬\MqÛºçÚÉ ½Åz¦œGÚcÀ‹µ6« †UÆ€œ¤$Œ"”RHÖ˜œœ¼´c¨ö± d*'¶EÁη]a÷7dZk”R´ýÇaRoÔ |“L¡”Âfƒr™lÅ‚±bWWÇèè ôlîÁu]\×¥^¯3sc†¹;sxž‡ïûêo’ Éj²VIEND®B`‚eric-6.0.8/eric/icons/default/adBlockPlusDisabled.png0000644000175000017500000000222312342633754021555 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYsMœÞöœWtIMEÜ *0Eâ;‘ãPLTE333555777Š––žž’  –¡¡™§§›©©žªª¥²²­­­­­­®®®¾¾¾¾¾¾¿¿¿ÀÀÀÁÁÁÀÀÀÁÁÁÂÂÂÂÂÂÃÃý½½¿¿¿¿¿¿ÀÀÀÁÁÁÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÎÎÎÏÏÏÐÐÐÑÑÑÐÐÐÒÒÒÓÓÓÔÔÔwwwxxxyyywwwxxxyyyzzz{{{|||}}}•••¤¤¤®®®¯¯¯±±±ÂÂÂÌÌÌÞÞÞáááåååêêêíííîîîñññóóóõõõ÷÷÷øøøúúúûûûþþþÿÿÿvvvwwwxxxyyyzzz{{{|||}}}~~~€€€‚‚‚ƒƒƒ„„„………†††‡‡‡ˆˆˆ’’’———™™™œœœ¢¢¢£££¤¤¤¥¥¥¦¦¦§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯³³³ÄÄÄÇÇÇÉÉÉÊÊÊËËËÌÌÌÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÚÚÚàààáááâââãããäääåååæææçççèèèéééêêêëëëïïïðððñññòòòóóóôôôõõõøøøúúúüüüýýýþþþÿÿÿ´2/‚UtRNS Ö××ßààããäääææçêëëíñññññòòòòøøøøýýýþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþU ´õbKGD ^Ó¾ ÈIDATÁ CAà7ó> Ué°Ã´´ˆÈ¤uˆN»,‹,ݘCC;É(ÚrÓh)­<²(5e~jKÏGZv¼§'õ(ÛY ¥=oZÓËœ?àBu€Z4weUVÆSí£nT h>œÕˆ(BDš}Èz@éʪaw÷ÙG\@K{VÓ¸A‚;bÄ9cŸ*ðÌ©úS󱿘N§BÆËtæÅ™9&ãKò#O K)¯òM)åå©^x-–Ø”KúÃèJê×Xûù~c1s~‹¥î-lO†‡®[½©~ã_2~ø§ÙÌú”|¥GK%ÙÏ‹[?dáõIøß±Åâ³Ò¬ý3[L¬Êå±·>ø3áu)åq÷óÈÌðó•µ [>xß\7ò¿ÿž¿}çúöýÉ[ß YÇЛ¾$ŸŒ|éRië /.>`æixòjRÄhbl<™å±GãB¨…V(mY-H1=fèº!È0‚ZnÏ.ÀÕi÷…HPD8+(Ìu4upï·5A!¢ -·¯ 5@ܶÊ8ãœ3¦æ:šP  ¢ ®¶yÓúÏ,ìmDå”ÕAñôtûÝ=­.Ôø¯M‘ÙmØèIEND®B`‚eric-6.0.8/eric/icons/default/projectSourcesRb.png0000644000175000017500000000063412342633755021225 0ustar piotrpiotr‰PNG  IHDRójœ PLTEÿÿÿ”5,•7.—A8¨8-¶·Ìá·°ê%ðB-ô,ö4öÜ×÷@,øH,ù_Eù†tù¬ ùØÑùãÞùêèùîìúL0úY?ú†pú™†ú úµ©ú¹­úÒÊú×ÑúÛÖûK4û×ÑûØÑûñðüH/ý_DýôóþA'þD*þM:þW<þcMÿ;!ÿbL/ckŸtRNSv“Í8¹IDATÁ±NƒPÐsojb!i¤urñÿÿÆÕEMš`-©À{žHÀÈ€Àу«/@F €kgÛúÙ$uåûÄFFÑŠ¸?AbÔjÁDØ; έªì¹ó*ÁŽ3ð­Z/iUUÅV³7X¡Š€Þ37ŸnŠRI0y§a±R‘À$X[” 0‰_þ¨  _ÍT LP Àu§D€ó 8 ¥9ãIEND®B`‚eric-6.0.8/eric/icons/default/bookmarkPrevious.png0000644000175000017500000000222712342633754021270 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ8 ËÆltEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ûIDAT8Ë•MhTWÇ÷¾7™yóò’LŒùbb­‰­1 ƨH, ‰©¶j” ní¦jÝTh)B¡*´tÓE¡]H‹‹ -JK­ÅH)Ö¢MZ±mð#œÉ|ä%3óî}·‹‰dlgsyçwþçpÞ9P¢Íu/ï9µç—eï{9Þr´åab4qteˆ|"t„nÇäÉc'û®ß½Þ À 6{93Ô;tzlÇXÓlfvle˜ýèñMÝ›ÞÝ7jˈdzvZqˆvG;ãûvìÛØ•ìbvzDeèãÁƒØx|¾{óî#[¶ˆ¹`UTËÔ5»Í׆¶ 5ºŽK*—B õغ+ÁhwpÆGvŽllK¶‘òS¨PšäšdSï³½F¡Dz!.j¢D«¿Ì µ gw ìjŠ×ÇIù)´Ð(ÚhºŸë&«²B ]Ò肦1ÞøðaN´&ÚÞëÛð¼XAY‘¥QR¡…F :Ô(¥ÐF—4^­÷=ĦEžélì8ÜÓÙÍ\iN(£Ð¶5ÊR勪Áu¨ÑZÓfµ¬DÛv22Ñí­ë¯sêÈø”R„Nˆ‘%ÊV(±¨z±-Æ2œé(a8vû&!À¬Pl#ÿ¹7Å|ÆG&$²Abê ÚÕà.àÊ%[p*&éë!xeö;Þ•Š¥ºl_5Î[_oD0ÊRh[ClèRNP_öfŽÄVáôlÇéÞÊh}‚¤G¬òÏ»€âs0Oþm§ËUQ'b/*¬¡œÀê Öƒsé(«{öÃB ZÖàlt`òÓšæ¥àå%¼f Ç/-[Öåc9AôÇoä%«¬Zš" Ú× ïxº¹]|p›™?/?•U…\ iÞ©”×IFî÷^ƒ»î¡3ï¥fzúb;`4X ,–1`B ´Ð~ŽÛW¿-VŽö‡LïúR™ô8YËÜËfQÙÆ÷1ªº€ `–xX~'ðѺDff:k=vW\!äBø[-ëçDb[ßõ?dkûjìH BªåŽ£¡!ð0ùÃ× ¹|a½õ¿Ûí§ðÇÌæâµ¿œØKÏü}+Ò±¶ ak°„9Ð1s70÷'øíâÕ`.¼8üA8)ªZôoÅ’Ÿå‚›ûwÕG¢1ñ™GDʽ5Ð>œÿFÞÙûQØYÝ¢x·0åùaZè ˆ4"6ð@4€¬é‚p¡T2NõäÑ\ZDl–#"P’°‚ð€(HV«º ²ÄŒ0Â0u~?K>›§Tñ8Ñ-»qŸZ ¡ªö4-±ô]&ÆÏ[Û³÷õÅ|žWO\àÀéAZ/}ÅÇ“ÍbÐOsåÑ÷ÿö"¾°;>ÊIEND®B`‚eric-6.0.8/eric/icons/default/preferences-pluginmanager.png0000644000175000017500000000216612342633755023061 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<óIDAT8Ë•UKlTUþþsoo;ÖÅB‚–ÈS¡Å*âk¡ÑÈ£lŒ7Ä…º2&š¸1&$7&²`a\©+4±ñ‘º`Y"±¨QJÅR í´Óyßó>¿‹ÎÐétñ$îyäÿÎwÿÇwˆ™q·qüçÑ ˜N8òÒ†®­[Šz±6Ÿ˜(ÛÅ7¾xar¦­3ßÕ^ÿqôë ¹_C^åùßò O¯ðÄÜDxëì˵׾?8ØÎGÜ-QÉð‹e[£¼Ê£h XVyäTŽnTº«·µ_ܯ~72ê3écߎ܇n\X:·+›<#¤K!ĥŸ,\­ì:|ôÌH3 `BiìØo©9ÆD„WÎ ¿ó䎣ŸìÞ8 ㄾ®þÐßÙ/ ¦éS(/áC@g”„²^¦².PÅ” ƒÁåå¿Â|nöéVƤuعïÞQÞuÏ>’^By éS‘7‹.…ô)ûJIѸH±„ )’Ž.¡%o_ ëÑPu%H/¡½¬ÕnÏÕ û ¡‚„æŠ%9ujoG!õÁ&â÷yáO]*O+êØ°ec¦Ó†_7ç±nC6¢ÞnpuAf«ã¹ÓÄÌ " ì8yàìó =Z1E4G†[fídœLÎTÜì77ûâº&"ªˆJeuÙ·kÆG­Îܲà6§IãžCq³àœ‡1.BU4g™ÛÄvÍYý"ãÞòà:­p.ø™Ò’¨ZhÜÊW¹åRÃÂ1zZƒþ¥xúœú{@\á6€w¨† EŒç~ ÖÇ´žÈhµhÿ÷`î?.?ö*ûˆÒåIEND®B`‚eric-6.0.8/eric/icons/default/internet_explorer.png0000644000175000017500000001244212342633755021477 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs.#.#x¥?vtIMEÜ1‹\ðiTXtCommentCreated with GIMPd.ebKGDÿÿÿ ½§“yIDATÍÁže¹ðñÿu?å-»ûnMÛ@zO‘( €¡ƒô„FDDQQÔAT ßÇ€ 9H$€ŠI€”tB )¤mß}·¼íyžû¾Î†Á&C9úùÏï'ü›•ûw’®Ã~÷«rQÇs®¯¯^Ë{ŽSsnܵïð¨P¯Q)±1òk’ìÄ»¥¼÷žQŸZUþ—ˆ:®=TúzϲùgÙ¾–#£Þ~ÊùÞ=ΚÕÖÔnw…®mÎÏÕ©sÐ(ŽIÕ­õ¦\xªðoÐÛöµÃf³_±í{ÓÃ8¾E÷¬<Äå7 ©”,šw¦áf+é­Þ‡Ô3lø±eÞÒ«vÝ7s¢ö·®0¹æŸñ¯´rÕ:Þ‰ªz·¾áç1Hõj í¿oŒv~ùîdÃ…Zy¼QËOVÅ=OŒ[±{å·Fò–Öç¿È»yýד?»í×S_þÅT•cO>sòÖí;FU*•áùRÕ™?}R¦ªJ½ ÊË·®ýÿ3½¾6iý®v¼•íúKʙÕ9zéc Ú÷ü¥4{ïe×Ò‹Žw¼°ÎçÿÁ?»o_uû]ÃÏÆ>ñÇÇ¿arC6¼yȉ'žÔøšm1ŒL&ƒŸª&+[i²yÒ-+Ñh…bž«ɲÍCüƒÆNRXÊ~?\<™÷žü›ä® 1ÿŒ >óyþî–;æ8ü#', Fè„#>¦7ýçýîÅõ¯éË›·ëÚ­»tÃö}ºi×>mÛ÷¤F¯~Q‹OÕÊÓkÏ’iúÒ†•ºtÍwå ·inúIš›xÜúÁå Ú°­…ý^Û±—w²»sÓ®{f¬þA'Ÿ5‡§˜«®¹¾á±E‹®ìèê¾~XóÁ̾h®{ÌÑ ¾x¾O*àû)r飽Ôt.ÂölFü˜¶àXv4ýŠ ‰â Î9Ê•²>²èiyfÉ2HâukúæÚ¥<à›î¸Ÿo^þÞ®uÑI“’þžï ÿ€é:ŽM/¯àò¯\}äü… ïŒw虳ÏgæQG“«k@|Ÿt*E†ˆŸa\}ÓÂçð÷> ®Ozy5¼‚½5Ÿ!"$I*ÖÅ1QálÌžÝ{tù³ÏË_V¼XÑPs÷®UO}MDh½úÚ81'üƒŽ<þô£Ö®[ó” sõŸºì2†5V/?H†a’I[fMØÆd¯Êö˜t‚JÄKî+ìOÁ)8…(±Ä‰%Šc*qDÅT*eâRQ׬^+Ë-Ña¹ªEŸøìyç/[úçdÃÒûø»¶Gfý[œ'ü7Ì:íl–/^ÄQÇŸ6míºõË‚êúagúªë‡@büÏKQSå˜ÔÜÆÓ»i,ZÊÛG˜K‘,ï›Í&f Î9lb‰mDEÄqBd-± ± ±µ`-¯mܤYü´ä<~ѽqéÕ"’ܹ`³G.ðè›M¥²Dxs>y ÿî®úöwGß}߉H û虳µªi¸à§‘ @%dÜð^ŽŸ¶žMšHzï.’öçëÒ8*Ü·ûS¼Í£‚Ú›DØ$&I"§$â£AšÄK‘˜€D…8ް¥~ÞØ¸‘¿­ø“†×ßöêò_æÂƒªúÃÆN^ÑÑÝôÔãNÓºƒÆ‰¤2à…$2ë}œõÁW8ô ìÞ€k¿® õ,·nü8ÉЏlŒsj-Nç¸0‹fkp~ç…$Î q—‹TòºgÍ*éY¿:™uÄ´Kž}øÎxá=üþ¡'™{þŒ™zØ'vïiùmnÌ!2ì™hÅ!ÙŒð‰cw0kZ ×G®u'IÛÂÆF$ÿ¹z7½üaâ|åB &ç× âWgªê›TÓU"©jÔ °NÖAÇ$QBTè'ên¡åOËÈäÛן~üQ³Ö¾²%¿õ/‹ØOxªj†¼»s€æ¦#Ž…lÖ«bäЄ/¶“‰#º˜;gï»óç×­þÄç¿Í²‡ïà@Ëõ}¾|ó½<ýËï·¤Z÷Üù®ÅBB¥dIÊ—XpŠZ‹*`<$]-„Y^^µæ]ð¹¯bx[¶n=¢.#c†+W_ÐM]•Å3>8øãě⥿:À§Àœûgã6¬ëÛûƒæÿúFÞÍ/¯þDDª3/°oGL6K’@%²”ŠŠý%’r„:‡Z‹RYݽ§uꊵër çýŸw¡ª©ÚæÑÓ1¡Ö7¥åгûð!Ž™r.ñÆ…·à5ÖaB¸á¹ ¬Ø1„êhGeÆ”ñ•¾ÞB(锸0 ~€ú!x¼<<g+DÑ]ÛwFõ§ôµu\¢”Êe$*ãiŒ(—¦$±6¸úë×~Xîó.N?ïº$NÅdå3çgÚäaceÌÈdZ7uþ™`H~Ö°~—ᦕ‡â´H¡™e¯¿ç>ìA®–TM5©L/ 0žžž¾CœÄuÙ¾Bšt5˜>pu1û¹Øb‹¨”E`Â$©Ì–û¼‹\±LÝEs™yHHb=ª3!Óê†RZw;Am ~•‰º¹ø‰‹É÷yH±ÍT§“Tö˜¤i4IãÁT²5”Âñ=ÄócPß ž ¢8dt†B÷â…¨µ –ý4Qpœ¢±«D¼žÞþ òy7’­šõ‘¡5'›#N åc3>J²õ |¯„—­&ôú¹|ñɼÚ1 ©¼ŽÚ©j„橘‘3 ¦õ ±ç!xŒÆ€0 ªà\R|4õUÔ*âê,ØÔYZ[[|Þ‹æðCB7û¬¡žuBâ„CÆO"×ßJܱSàe”g¶5sÏ–£¤¢2¤ªÐ¡ƒf`êê1aˆ ¼ÀÇ ¼ÀÇóãx bÏ/…xY @ÕC%@AÕ NP« €œT} É2L0‡k®:zvS}˜Qª³Y¦44Pxe~u/c(+\ÿÒ©D‡–Pc ~2b’É¡*8UœkkIâ°1$‘bËŽ¤œ#âB [(a‹e\¡€ë@KE\¡€– h©¥TJÇ –æáCG¨ªïsñOÀ%ÏO*¶\çy†„‰#‡ìxŠÄ«àgÒ„^™û6Ê‹{EâhA¶3b &)à÷ÉÕV‘<ÏÃxˆâ{‚ï ‚ FPkQUœµDq„5 ±$”µBäqbH¬&Ô&8ÍCT,½½Á>)>P«‚]¸$ a* (G̨wD»·àW¼´co§á Ï_RDK}ˆçCã8Ìј‡®‰'¯z4US»[Å1ˆ1(ƒDØÏˆA°(ªˆD¨E\ê0j‘(Apˆ³ˆ³hƒÅÕWcíx©®ª^—MYçs ·è»ªñ? 4•Êȇ§ÖàµmF´/“B’"W¬ø jª¡œ‡8‚lfȼÐÇ KIÛn_ÿø¼åü¶ô‰Gñy‹K^DÜÀAhárP•ÉbT3°|>A£ñ-Ïì˜À³íG ’ •u£ñsux¡‡6Œ â}{Ç«êráýìÞ³7›ÏwMɦҦÅ8k Ct*Mà8UT ðSXg)WD ¿XÜy茩>ƒ4YøGàâ%—‚mPUd܈ú_X„ cü´!ª8îÜt"E[ I â ¤j1u#ð2~ÊÃŽžN¼oÕ"2ï¢/ŸùÞËq]9·Å:ÏUA‹}G8§¸(FK½P€¤ QʽåÁ–3fôEÀŸAâ&[Fã¶^Ë \DÒ¹—¸e5a½Á1kvÄvi…$ªFàe«ðB?à5¥[«ÏùÒ÷zØm?øúú Ç]Äë+ä@Oº”ïÌ=Ö|ãWOœ>éÒËhkç°å„¤\&*–©ôõcz¡Ø }¸Ö¿AË:jS¥Î›×?&"MÖñ&×þ3E}UTW¢ôúˈ¯HJ ’˜+ž b@â¼R݈—öð#†Tc£¦>tª¹ûEÿüɧ‚×W<Èò•«y»ã?ýM¶>s×ß»ô¨ì„ç·”3”ÔÑ_‰é/U(&”Ëë|œ©Æi'PèV*y¦OŸt»ˆTæ^r% g7B[^-d¡$h‚í\M~ù(dê•Ek†ðɧ¾†Œšžt‹ðGŽ'Ý\O«"ÈúÔdCL˜Öî'+fíÒîIcFÌíli]=ýÉ•¿îìŠÎþð¤ôüÇWÈÄÉ?»¹£tKãìË´i’$²Ør[¨`K ¶TÁ•#\©‚öµ"-ëUßxIêS}¥ž]›²¼Åg?-\&ƒQ’ÎÍDÅ~¼ÑÞ’Ê­O4@q‡jy´­uHª“ßC „¾!ð ÙP¥úü‹é™<½aËËË—¦ë¼/lÜ·µ}_ÛîÅLÉM9|ÜκæáͧŸL’Í‘ªDØ8A@•7)  å~4¿G¼¤ñSÆ\±j×&[¼ŒsN;ßÙ×Ò¢ÇFÁC+{©´·c] <#IRózKouHßÎQ4ì/¨@*‹zˆ1¾'¾G&4d³ÊˆcfjeæaÒוã¢ò˜ƒ¬E<fHçj‰¨Ä‰ØÄ`Œ`EÀ´R„üN¤wC«W~èˆÃ~?¤©‘sN;ý|ÁÕ)þ‡ÁC¥íÛºp¾ ŠZWóÜÜÏ}çöŸÜt㚸m£ žjºN¼ DƒÁÁðȆ\Æ“êŸptªJ¢JC9VÊ–Þ²Ãõ<b ‚CA.Ž!¿[iÛ"(Ì<â#—üê§7”y£„ãÓFxh¡‹b×^¬‡F%­=ê±ÿûóÖuê1ŸJÛbö­éÛ‡Z‹:Þ$b1xžÁ7‚g UC]Ö04ç1¬Æ§©Æ£&#„¾!0‚1#‚1Â~ªŠZÅ–´§ö¬’TÔS8÷ì“.y|þ¯¶Ìœu>ogÀœð h…Jg'‰‹°¨$®¾4þô‡ždÐ#¿¹yþ‘‡OºˆØ"¥žœ@bAÃáOñ–3>ýMþô‡Ûî>êC3N¨Õ~Ñ]«5jm§Òѯq_™R)¦Y¢Äa¬ëÀ:%±Bb«`¬SUâØ%JRŠIú‹Äµ-»Ð/h.ÚçÎ<ùÈ“×<{ÿ zúá_s ƒxðBÐ2q X«˜š‰Oó–'¸‰™§|Ž?=òËç>{ñ¹£†ø½KÃ=¥²s›ßè wO·¶· ÐÞY¡£/¡³?¡sÀÑU´t÷YzŠ–ž‚£{ÀÑS´t÷Etõ”èmë§Ôš×Òî⯈¿çùddº°øë_ùôÐwþèO'^ð5Þ~/ø !hêacÞä„£æl‚Gù»UKçñ©+Ä-×]±ûÁ¥«ÎûÁœÐkw}«õüqÅüH‰:‡Ph¨Ö®†¬ì©ËP]"›öð|ƒ*ı£PJè/3ÐS Ò]¤ÒÕ¯®c„½;Éi~q®ÎܼxáO–OªjOûkY|ïy7¾b–‹„'©&"’“EÅ *ˆ*¹ƒN2à··~—3¿t32³¤ªOõµ§æœ8~ÚK›Û¿ÑÛÙÿ™|G­_¬ªÑ|6“ Õ }#(ƒ‡«ÄjK‘Øb××E=Rãî?óÌ)?ëhi_¿àæ/¹Iõ·ñÑO~‡Å÷þ˜÷"j»Æ#ñ£P™–ºéþãW¥cË_qA§^uêôãºtëª_0qæWy?ª·4¿üè–ùk·uO¸£åü÷«Gô­© ýZt`ú‡fýö:¿¼et½[öðusžáŸå\^Ôv\¦®%¯ÉNUÝ銯|Ám¾Ýr‹ÑWïó8ï íõGy»òÀ³ž>ãÖü‚CöΘ§ž5ƒ·QÕ:Õ¸VU³¼ƒöî^þi÷úÎu|ËÙ–>u»ÕŸÑ7n«Õ-7ÝòóÀnûí¡ªÂþ *Å??·ÿ¹³·Ï¡-÷ŽÛÐñìŽlÿÝTaPÏ?NG~€mkíæ_EÔv#^n@E2_T’¯ŠÈØÂæÛ‚Ö?Þˆ³ "JºaŒM×|Úd³{=-c©:Áöí[éÚCÇ›½ƒŽüáèóŸ™Ï ¶ç®dØñ·ò?A¤¶ñpyEjº?ö“J4«oýÝ£òklˆ;6ã¬Cd &SÆß„ —šúQÏŽýä ‹EÄòo ¼E“.Äod?g;SbüFuѤ¨ëoã+=ÛKû^ )´t™ºéíÉî•k5ûëç,éωq Ú÷Òõ4u=ÿÓþ ƺdjg{IEND®B`‚eric-6.0.8/eric/icons/default/siteinfo-security.png0000644000175000017500000000147512342633755021420 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<•PLTEÿÿÿ‰‰‰³³³›››£££¸¸¸žžžºººÄÄÄ———§§§£££»»»»»»¾¾¾¾¾¾ÍÍÍÁÁÁššš¢¢¢«««¿¿¿ÉÉÉÆÆÆÈÈÈ“““   ªªª‘‘‘ššš¸¸¸˜˜˜   ¦¦¦¹¹¹»»»™u9›u4›w;žžžŸy0¢|;¤~+¤¤¤¨¨¨¬†=¬¬¬·Ž!¸“?¾¾¾ÀÀÀÁÁÁȕʗʗ˘Ì™Í™͚͚Í©7ΚΛϜММÓžÓŸÔ Õ£Ö¡Ö¤ץأأئØÌuڥۦܦܦÞ¨àªàªá«ãÂ,ä³å´æµç¶é»ê¼ë½ëÔWì¾í¿îàrñÂñÂòÃóÄöÖ+øØ+ùÕùÕùÕû×ýôtýôwÿöt0ïù=tRNS "#+,36=?DFFGGIPSUwy}‡ˆÇÊÊÍìììììïôõúúúúûüýþþþþþþ•ú«!ÑIDATÓc`€QU=}uq4 dãniáb­Œ**af¥ÀÁ.oj&‰"¬âª¢äÔP„uÌY@³‰.а„ÖðF6„К^¨ÂFZ MØBk# —åy8;ÚÙÚ;¹y†V¦"„ëªóü}ƒ¢3‹›Z‘„ë« B¢â3J[…k‹âýÂ’sJÚP…ƒ}#“²J›Ñ„S"Âcӳ˱ çb®@U]S˜ˆM¨:<8& ‹0¦jl€‰‹‡O@HDJFVZLXŸ—›“•¨£J÷¥Ô7aIEND®B`‚eric-6.0.8/eric/icons/default/editCopy.png0000644000175000017500000000134512342633754017506 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î< PLTEÿÿÿ µ¹¼ÉËÌÀÃÃÆÉÉÃÆÆøøøŸ   ¡¡¡¡¡¡¢¢¢¢¢¢££££££¤¤¥¥¥¥¦¦§§§©©©ªªªÊËËÑÒÓ×××àààâââçèèéêêêëëëëìëììììììíííîîîîîîïïïïïïððððððññññññòòòòòòóóóóóóôôóôõôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøùùùúúúûûûûûüüüüýýýþþþª‚¶×)tRNS "#$+,1369=?FGINPQRSU[]ŠÜãóõ÷üÂ}žµIDATuÁÁNSaFѽ¿s¢$’èL£sæ¾ÿX§> HC[ ÒÞÿzÛ‘×’wWüëá‰Esu½¯ØJЋoO,öÓxÝzY}õ¶¡Gm?ï+¶’Ozñ}Ûªì§aÄ¡4ô¨êQ©,4¬ !UIUª’2hHµ=ê,ŠBCÏmªºÓQ@h 1Õ]U‚h(CÏ]U"¡AK’*%ÈIC2Q"rÒ@D+‘1„f!AŒ8ïïþÜ?Ó@€ÈÂyw³úý¼&Ì?¢ 'ÇÛË»Ãý„¼}/«¯‰·¿7¯P6›Íåú£yù¹»=ròæC8›wƒÿ“tR'+Ç1-Æ4ýTüNÚÞ>ÏËIEND®B`‚eric-6.0.8/eric/icons/default/preferences-typing.png0000644000175000017500000000107512342633755021540 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<¼IDAT•Á½RQ€á÷ûöìn~ÈÆ(3 Ba¡•cÉØzVz މ㌕…q¨lÇŸÑÇQDA1 Yöœœc²rÉóH`zÊ ˆ2…àÁHöèIû2¥}õvãçºÛ7Wk†Ò}¹ú†•;m¥4Â-l^Í™HéÏov” aïúý%y£ˆÊ)}d(±dÔHÄp@•Œ& [láp( }IÀá°Ô$ç9¯±XbaLÁsH‹CiÈ€‹ÅQ—mj¬`±¤L ¬É*aÈH–qŒ¹FŠb c†ã/eOÓhè.˜Ý“?½R‹í¨ðEN~ì"•SW§9"‚rëEw1¡Tðøó½%Ï„ðôÛíÅ”ÿ~Úõ5C oE X ¢ K: ¡B–\¢‚bÎ"2eÌpÌ>Mæ0Äú‘g@ŠJD—* * ŒÕåWpxZ²CA„Å‘I(°8ª€2¦ì3$'«,‡‘¯ °X¿üº~GáHX&áO¥ÍEŽœá=Á„ Ÿ>puJUsø{®Á¹^¯Óê;J•œ÷Q¦¼¦§Ì@™2ƒƒ°£Ü©'ÙÑIEND®B`‚eric-6.0.8/eric/icons/default/sceneWidthDec.png0000644000175000017500000000135112342633755020435 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ/4zr7¾tEXtCommentCreated with The GIMPïd%nDPLTE¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀ¡¡¡§§¨¸((º’“ÁÁÁÈ45ÏÏÑÕÕÖÚÚÚÚÚÜÛÇÉÜÜÞݵ¶ßßààààààáààââÎÏââãââäãããããåççèèèéééêéêêêêëêëëëëìëìììììììííííííîöEöö÷÷g1÷÷÷ÿÿÿ¨O¥/EtRNS #*+128:>@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜bKGDkRe¥˜±IDAT•ÁANQEÑûÝŒ&$â&Üÿr8qÀÄØ‘`>Uò1H”žxó´¹çÚ[¬žjD⨨ÝÒû˜†—P¾ÉÙçt·[vÙn&~xÜ/k ¢üh~Ë×r­úc±.3§L׸h@™Î³f` ÈZpÒÈde3Ç6™Á·h6 Óep ²é‚‹ÛÌL㊵=pR ,¶ÒÃmU…du£mÙÏü‹ä#¹Sv•G_§C†1SÿIEND®B`‚eric-6.0.8/eric/icons/default/splitHorizontal.png0000644000175000017500000000116412342633755021133 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ¶¶¶ïïðøøøúúú·{{ººº¿¿ÀÁÁÂÃÃÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊËËÌÍÍÎÎ::ÏÏÐÏÏÑÑÑÒÑÑÓÒ¾ÀÓÓÕÔ|}Ô±²ÔÔÕÔÔÖÖÖרØÙØØÚÙÙÚÙÙÛÚÚÛÜÜÝÞÞÞÞÞßßßßààááááááâââããããäÔÕääååÞßåååååæççèèèéêêêììíðððððñòòòóóóóóôùùùþþþÿÿÿ1 ütRNS !#)+34<>FIMNPRSUüüýý_ñÿ·IDATÓuÑׂ@@ѵ÷¾ºvÁ®Ø+ŠŠ6ìÿÿ±ñÂx“I&çm2È&ºÂ6„Sw]IŒÈm¹Þý’¶²´é®Î‘Ó<+¢(ª³˜eøm¯–>¨|ä:œÖ€kpíÑZå}K¯²|UÞ=&ãÇg»°/V¾ÉÚ6„¹sæ:Ì ÌU˜Ë0aÎÃLÃÇSá„$ðÓ ;ì7ëLµR*äh*ŽÑŸ§ýËh¶:\_ E‚~¯Ûi·˜ O·1q©86àIEND®B`‚eric-6.0.8/eric/icons/default/preferences-highlighting-styles.png0000644000175000017500000000244012342633755024211 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¯¯^‘tIME× á,nµÁPLTEzÿÿÿ‡ªKHEEE[‚=IUaxV1DDD‡zA‹Œ$°$$=IUaipwx1@@@…444cF'''}`RR$C…‡622_4!  1+++†BBB  !  JJJOOOWWW$0:B#C!EEG^^^```ggglllnjj[UUEg__ ..444ºII¾YY¿aa¿cc¿gg¿ll¿qqÀiiÀooÀssÀuuÀww   !!!"""###$$$%%%)))***---. ...///222666777:::===@@@BBBCCCDDDHHHQEETOOUUUZPP\\\cf..fffkkkl]]nAAppps t<ÕýÖ¦=€þ¹´‘U–ò¢ïÝ3àyƒw÷Ѩ3lIEND®B`‚eric-6.0.8/eric/icons/default/selectRectangle.png0000644000175000017500000000127212342633755021032 0ustar piotrpiotr‰PNG  IHDRójœ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<>PLTEXZ\`be3688<@9<@:=A;>A;?B<>AAD?ADACGGJOKMPKNPNPSOPSOQTOQUORTPT[QSWQTWQTXQUXRUZSUXSVZSWZTV\TWYUWZUX[UX\UY[VX]VY_VY`WY\WZ_XZ\Z\_Z\a]`c_ae_bjbdgbehbekfimilrprvvw{wy}~‚‰‚‡…ˆ‹Ž”’–¥•™¦—›§˜œ§š§ ªŸ£® ¤¯¢¥¯¢§´¤§®¤§¯¨ª±¨«²ª®º¬®µ¸¼Í¹»Á¹¼Åçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ¾f€•tRNSõõ^j×µîIDAT•ÁÑŠÌaàç÷ú¤¦Éˆ´Kœ8[ŠÙM¹W.À‰[pŠ”É0Íì~¯¹‚}—UO¸{ôÜË[w^99:±dÏím¹zó«¿±ë7Ý­Ûˆô¯Ï_ V£f計Ãïï?>$$*MŸw3,ÊÔÑ3Ý ®Ÿ&55:¹È' Z™é¦XÔB4SÞÞ Ø\«$UÄ~Gñí}-’ eÁ°HR˜MZŠÁú4e&ejñƒÙ’b&‹¢šJRU‘x·að`…b&eÆÅΟñèþ ¯ï=<óô Ãb¿ÿÊŸíO‡Ýví|º¤ƒOããIEND®B`‚eric-6.0.8/eric/icons/default/method_class.png0000644000175000017500000000074112342633755020373 0ustar piotrpiotr‰PNG  IHDR(-SsRGB®Îé pHYs  šœtIMEÛõ¶ñƒiTXtCommentCreated with GIMPd.ePLTE         *" //  +&-.($,-*(8r¡;bb=9Q††f—½m´´‚×מ¹Ï¸ÌÛÿÿÿñ;ÌtRNS**,,.BBÜÜÜÜÜÜÞÞììììîîîîòòôôöüobKGD*S¾Ôž…IDATÓÎÇà PLNìô^ åÿ03rËÞÞŽ4³Bü ¬ºnZURm¼¿uJÖöέ |cïRìË÷âB4Øn1_Çøx‘µVÃèÂ;ëF èCŠyÞ)[ày°9Ï[,pÏÌÆe),s‘¯ÇIM{åÊiÖìtœ|ýtx ‹xìÇÄIEND®B`‚eric-6.0.8/eric/icons/default/breakDisabled.png0000644000175000017500000000071112342633754020436 0ustar piotrpiotr‰PNG  IHDRµú7ê pHYsÄÄ•+tIMEÔ / ƒíbKGDÿ‡Ì¿ZIDAT(ÏMËJÃ@†'ïàCdÑU /a÷]¸±m¬Y+u#M;+¼P¥ŠxAk-ñ²p!‚â"ê¶n« t!´jµüžLSÉ|Læ$ߟ™Ã0 WŸáyÎyŽ;<ÃÓCcááêóÍK\\À•¶Џú\ó!à25ˆ¸úló ¯x§Ùçæ#iù_ßÐ=¼ÐÚ g޸ƴLšÌåUÜã]€„èQÕÅ-N°»Èò|çľHü@»(‹Œó2<Å>¥·”.`–`Y^†â?*ðƒÿ@R0‡P"<ÕE›ð#5¬KH–á+ÔLYéöˆŽj²L_—,ÉIAÔIxê(ª:­ë˜hEcÌÐl3+·Q¡m+~µ‰ÉÖðˆ1D7ih)ŠTqbi¥ƒË64Ëtd GŠCÚa*¬û‘„9^´D’ˆ‹Q ô®¶Rט™›IEND®B`‚eric-6.0.8/eric/icons/default/warning22.png0000644000175000017500000000253712342633755017544 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs „ „ªâcytIMEÚ !§ÐnùôPLTE¶ûàÿªÿ¯ÿ¶ÿ¿ÿãÿÿÿ®ÿåÿÓÿÄÿÎÿºÿÛÿËÿßÿÜÿîÿìÿÑÿßÿËÿòÿÊÿ÷ÿîÿËÿÚÿÍÿÑÿ×ÿÐÿÑÿÎÿËÿÌÿÄÿÉÿÅÿÇÿÆÿÄÿÅÿÂÿÃÿÄÿÂÿÃÿÂÿÃÿÄÿÆÿÅÿ½ÿßRÿÁþ±ÿËÿ¸ÿ½ý¬öœÿ¿þ¾ÿºý»ÿ·û¶þ¼ù®ü´ü¹õŸú²ñŠìv÷©ø¬ ó–üªîæmü°ù±÷Ã%÷Æ)ùÃùÌúÄ4úÐ%ûÌ(ýÞ±ýäÂþ×’þØÿÚ£JKp rEBwMI|MH|XX}NK! " _^„jjŠpoŽz{“€˜‹Ÿ’“¾¯žÇ¶¤×·غÜHÝEÝFÝGßNçxéê‡êØë‰ìŒìŽìÝíí‘ï› ð ó¦óªôßõ¬õ¯õâö¢÷¾ø«ø°ø»ù³,ù¸2ù¿9ùÀ<ú»Eú¾4ûÃ@ûÃGûñüÝžüóþÓ`þÔ‡þÖxþ×þÛþÜhþå<þèÿÐnÿÑAÿÑZÿÒGÿÕ.ÿÖ2ÿ×ÿ× ÿ×'ÿ×dÿÙÿÙ5ÿÙPÿÙWÿÙnÿÙÿÛ«ÿÜÿÜ;ÿÝ›ÿÞÿßÿß4ÿ߆ÿàÿàBÿàsÿà°ÿáÿábÿâÿâ`ÿâ·ÿãÿãÿã;ÿãƒÿã²ÿäÿäMÿä˜ÿåÿåqÿåÌÿæÿæÿçÿç'ÿç4ÿç^ÿèÿèÿèHÿéÿé×ÿêÿê(ÿëÿëÿìÿì(ÿíÿîÿî(ÿî@ÿïÿïÿðÿð'ÿðAÿñÿñ(ÿòÿò(ÿóÿó(ÿôÿô(ÿõ(ÿöÿö(ÿ÷ÿøÿúÿüÿÿÿ…þ(êbtRNS "&+36>@CILMNSSTTTUUVVVVWY\dgkqx€Ž‘ŸŸ¬¶¸ÂÄËÍÏ×ÚàáäêòóøùýþþþþþþþþþþþþlŽ‹bKGDû¢j6ÜvIDATÓ]‘Ë.a†¿ÿ0™†¶ÓF'¨ Z– A7ˆ6Bl]+;W!±röâH¬$H$$„î-0S©¦Óÿ`Ñ–Ö·yß÷ɳûúOëò‹Œ\Ú«þÇ*_Ø™uö?ÌǦÞ^—Ÿ+ÝI»Á&×6ëW¶S°EzÚiã%wÀÆvqîT®m绳;8m^!¨²eõÛº½:Á„$ªf;_¶µq[¡`¥0 ZÏÛ¡í¶*˜†ô»dÌíÙ©BDâsѽå,:xȆD Lp"ý¸O$} R+Ö·ôP‹!&ý| À£¶nÄtÍ›!ÞgâÁyªy™Å"ÓU-VFÉFË÷ŽÝw{ñÄ“b„"ÆAÅ=TŠ/J¦Õ¢ÍíÖT|´Œ¬f£]ÏΟ|¾!3܇ˆJ11ÁiúUQ/Ÿ7ohx)=©P çl<{öH›—­’”  ÎG”Ç‚Ôp„K,%q$¤Y{ùóäåí®ËIEND®B`‚eric-6.0.8/eric/icons/default/sqlBrowser.png0000644000175000017500000000140212342633755020064 0ustar piotrpiotr‰PNG  IHDRn½¤°sRGB®Îé pHYs¼ÏtIMEÙ 0 ÔqÂKbKGDÿ‡Ì¿†IDATÁMoTeÐóÞ{Û™‚4Z ØÒÒ`€…h$îEW†¥1aÇÒÄ?ãopQcb$¥05 XJ§ TFʧeÚù¸÷ñœÈår*¥R @íÜô¥ Ó'‡“#{ãÏŸõ[Åò_¿~ùæ¢vÔ¿þìνÍjè""""¢Œa c³úõÞŸª>ž¿ÝŽ§Ñ‰ÍèÆvô¢ýèÅvtc#:±íøíæÓ$µ®Ïœ…$ ¡H2IBe 7?÷þÙâèøÄ©®@@ I’dâŒzQYpL’@¨T’pßH*Ví4´[@èêšÏ²ƒUËúúÈd2™L&“a ´¡¥¢ØiW5Ÿýk·¦Œ*d*d¨û¦OÜðÐ’=^PX·æº¡mlÛ²|·ìçúk‹»ÏïûÉkÞ1î€:z^6ã°ÉU Ë­«—:碽ôèj55:5’&MúÙº†d]Ó¹·ÊÕo®\||[™@²£qtê£wß{ëøR}"VXñ öu—ï|ûݽË[÷m €$×°+oŒï«¿¢ê=l?.»:¶”ÿ¥ê>=)-ZoIEND®B`‚eric-6.0.8/eric/icons/default/profileScript.png0000644000175000017500000000245212342633755020554 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ()5œ+5tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ŽIDAT8Ë•”Ík\e‡Ÿû1÷f2sÇPÓÉM¬Õ´öÃ…Zc[ –*õƒŠVZT\ ú.Ü)í^Q\¸« u‘)VEM7*¦µ&¢´&i:I“™Éd&wîÇ9¯‹IÚ ±à³9‹‡Ãó{ßc±N=ÿÎ×½y—S*º·§$™bD°J¾ÍíÝÎOHöôû¯=7Ï”½ÞPÕŒ öö I3h§J”*K±2U›jî]hÆ#Ü¢Üõ†±X…¾ ÇŽþ®­¨þ»…+U)üo°d _^œcô÷9Zí K3Œ*FUéÀEøßà<íLªa lA4£*ö±U ªRôíðû3'wÙ œ\€å”N í9xåøÝ¿èm™®‘±™¸ÐLAEhd‚Š "¨Z¨X••;*Šž†=ÕcwÜö'`%þ³ÀÐ ðô’ykbQNÅF5CþíSV{Uƒ`TÉÒ”¤½D÷ÆhJÞ–×Ï¿úäÆûÞû À^&(“›îŒvžÖZÐÚÐŒjG—gtš¬tœ÷üÒ‡—Ç¿ÞàFqŠÜ dÕ¡QÁÈÍ^x<ÆÝ« 1hŠeR$©…­Æ…^·¯&~3u#BÁQúJ®í‚qPYÝÔag¿Ë¡éÉ×@ÓN›”M îlDZµ&iÁÒŒ½1/îªÒwÛ"¶•aY€1X–"‚.ƒmy4–7à¹)®©ãš•Æ&®-m>0222éæs FP£¨Qî,9¼ð`¡-Ó8ÎJÄFA3’$¥Ñàru+sU‡å¶ÁË)ýRÊù jÙ}X9¿oajaÐ-øNŨ†«~ÃnØV;PcÀhFš$T73µ¸‹ùjŒïùEŸÙ¹9&§ÛÜ}×nŒHk¦²0Y­×ÆÝÁ÷ôø5órº’|©Ð…ïY-¬8ÌXhLTvàû†î¿O7À¶™™™á·óçè¿#´ûú‹?gªööþàõBïÇŸëå‚‹VÐ$B“Nâc4æÒ䆥ȶmÛPch7˜$a9Šðþ8å2Žë200`UkõÝŸ~òéK7nÅáCN˜+¯t4˜ÎS²MFÒ®—mÛÂïêÂîî¦ÇL^¸ÀýG’ó}, (ÖÔôÕBe¶²iÝ{,’Æ–Ž7›æZ¥‚Á`T)‡!ϼñ&9ÏÃŽëR­×ˆãxìð3‡ß^~>¡-ÊŒ YTЧçÖ½yo[¢Í‘Ô xwŸ¿1÷åë7M­Á,pQ~¯®c§çÞð¤þQC \˜Ï£sß¡Ù.\®»}½*f8{Ƕ=³Îì>ÀÀBBÁ$$Ã22ÄÄÄ88Ä==ÄBBÅ$$ÅBBÅDDÆÇÈÉÉ,,ËË::ËHHÌÌ??ÌCCÍJJÏÐÑÑYYÒÒ??ÒCCÒRRÒSSÓDDÓIIÓKKÓffÔÔZYÔnmÕÖXXרØEEØPPÙBBÙDDÙIIÙXWÙvvÚÚLLÚWWÚlkÛ~ÜÜÝPPÝmmÝ||Ý€ÞÞÞÞKKÞ~}Þ‚ßDDßEEßIHßMMßVUßWWßàà‰‰ááPPáooá‚ጌ℄⌌ãããVVäHGäUUä‚‚äåoo充勋匋æFFæsræ懆çççOOçUUçljçzyç燆狋çŽèèQQèedèkiènn苉薕蜛ééHGé^]éts邀镔隘飡êêNNêUUê\[ꀀꎌ꣡ꫪë뙘뤣쑑ííXXí~}í«©í¶¶îllïffשׂﴳððbañññedñÃÃôz³_=tRNS ÀÀÀààààààààààààààààààààààààààààááááááááááááááááâââããä×¶ižYIDATÓc`À عر1­îš@9ìª'¬aLË ×§*±CDÛªM!L›k—˜® ä°«ôUÅg´™Ä¹.^9¾cûöEjìì*Sês“£³S¸€Âlòí§·oX¶m¡¢ÂÜÉ•…iYeÆl SØä&ì_·tÍÚõ æ÷Ö•”6±Aìd“wlÍ’Õ{¶ÎšÔÕ3Í€ æBV™}{·l>²jåì9ë YþaÕ?u~÷áC»6±@e`Ñk]|îæ«—Žš³ ‰j´L\~òìÉå3»uáâ,ZIù53vÞºwcçŒæ ¨8³tdlBùă·7N,ÏI×d‹Š{ÅäõKJ­hÊ‹ —‰sÚ»;zDd¦Š13‹&Ö&Dxø:p…™„\\‚£D˜€LÁ°¸Oa&)LüÎn~&ŸWˆÄN&;^“ÛV æBFF,L,œ?FIPSUÙÚ‚`ßãVIDATÓc` ?—Äâ rŠ@N‚ARQI ()J…•e¥¤ePÄ!ÂÊò ÊtÆî¬îÆáKaBÀÄÂÆÁÅÃ'(,*&"ÄÏËÍÉÎÊÌ}$a#„P`±Vl·ÇšÎxÝS*2äŽ5ý`WUy/L\=$ƒÞRg¬í¬W )ÉA”«šuÇš8Ö·dP¸4“ß>ô–ºª>™Lâ¡A¹®cG~µ¢&}ûÚjú°¿{ñ’'dR‰šûJo¬}št§GxÓ²Žm‰®y URÑït§“^½í¤g”dR?û <²kѾTIY¿Qm½z§:†µåAÓmk8ò¯{.Ù”ôyNGœÊâd×ie]¿yà¾Ì‘}M]¸bPêß‹“YD÷Ü5îÀ®¿´”å ¢(‰[Áß (9é}ç$JNxÖ§PØÄ­$n&Úr¹Â\@Å W|æiQ.·+7“¸‘hx¤£«pÞy0àe_E¡«åO‰¸‘Äuÿ|«¥íI3€q×"×Õ¶â1¸žÞi³“Ìí5,•ê†EQWË]Ÿ«ï}õK(0ûEo>µ`B¿²’äºÚ~w]G¶|sP`®Vl÷ÆZ^3g@ŸTPȵÜò£Šl/L|}H(Àl­XŠómÏ÷¢à;v)K–ÃÅ›‡ ïθ‘är9R©TÚpae 8W-¦ÕM™Ä–MaýV€ÿ.ùsúÎX/IEND®B`‚eric-6.0.8/eric/icons/default/anychar.png0000644000175000017500000000236112342633754017352 0ustar piotrpiotr‰PNG  IHDRójœ ¬PLTE +12 \³ yÝ „ê  „í`¹…í###!%'&+,!%&~å‚ì&+,!%+-  &+,!%& ~çìg c¹rÕ‚ìrÒ&+-&+,9S8N )4:!%&mÎwÚ †ì !&'&+-+13!!%&yájÇ„ì  4K +13+02   &Jl +12 +12 éìxàì 3_‰6i™  !%' &+- ,=JnÐpÒsØtÚvÜwÝwßyâzâ{ä}æ€ëpÓvÛ vÍÛ…ãˆç!%&!%'!~Ñ!„Ú"‚Ù&+,&+-&,-+13-692–ë5=B5DO>>AAACFHMNPQT`gmmooppqsty{{{{„„†‡Œ‘“––˜™™›§«°°°°°°°°°°´¶¸¸»»»»¼¿ÄÆÈÈÈÈËÎÏÐÑÔÕÖרØÙÚÛÞÞááäåèìíîîñòòóõõööøøøøøûûûüüüýý Y7IOIDATÓc`` ”gÀ..…^F {E&ˆÑd`Ô€–›¿@Ä0­ª2EÒ¼%œÐ߸Q HÅÍóXŠ'´G!3€TÂL([ÑÖJg;;¦®ˆ¼f @Ò,A×mÖ3´¶›;lWa`H^ÜiËÀPÒ 5:h—ä?žê…š@ÞäR¨p딲²E é½³A¼úyB`QÕ½1ŽŽYû”$Ræy|å{[<Å€ ÿCÊ †‡}Rç[YN¿~âÈ¥©aö um@9–žZ†´£@pêÊã'-‰Bñ˜Ç™sç¯^»pñ¬ŠpÎÎý—ÜÚ³¡_50uûŽßº}z’z ‹»ç&z €XÌœ¼"ÒŠ:&–fÆÚêrRÂÜŒ–BlFŸ=ÔIEND®B`‚eric-6.0.8/eric/icons/default/changesetSign.png0000644000175000017500000000154112342633754020506 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs × ×B(›xtIMEÛ &‡yÛzPLTENNN222}}}´³´_^_ºººÏËÏ^[[———ÜÜÜ‰ŠŠ×ÔÖާ¨¨âàà”ÕÓÕœ›œ‡…†°°°ÍÊÍÀÀÀÙרàÝáëè躺º¼»»£££æãäµ´´æäåsppÌÊ˼»»ÇÆÆ¬©©Ù××ÜÚÛ„€€»¸¸º¸·»¹ºÙØÙÜÚÛ¢ŸŸ¨¥¤ÍÌ̶±±½¹º‰ˆ¡œ¬¦¦ÇÄÄÊÇÇ‘Œ‹“ŒŒ“”ŒŒ˜‘‘˜˜¢œœ£žž¥žž¦¢¢º··½ººÑÏÎÿÿÿ9-ÜptRNS  !#$$&+-./01459:<<=>?BCDFGIOPRTTTVV[^`lnpssy|ššŸ ¤µÎÏÔÖØÙèéêñö÷÷ùûþþþþþh' bKGD}¦±ÉäIDAT­ÁeWƒ`€Ñ[Dt*ïÜÌs¶³»»»»fÇW8nêa½—­ËâX‰œâÖqõ:‡[Ò^d;·ù‡›fÜJÏž—‰cãî0[Ñ #ß'üéÄŒ¼œ÷ûR±UyO‘i"Wï?Íâ°‚hº!¤Ð$M,Þï¤J(`è2ȃa ¯Èl¼þh‡`O@ðÅ?Q‚#yó}UèËÂV9¤ðmúí¨Kà°ÂQÇc8*øeév›aæ!ªþâ È©©ëné4‰Y;Ésaª·¶<‘y»eêø¨&dþjnUùgŸÅÿ"˜MýIEND®B`‚eric-6.0.8/eric/icons/default/cBreakpointToggle.png0000644000175000017500000000246512342633754021335 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ 1ïëS\tEXtCommentCreated with The GIMPïd%nÙPLTE"-=@$4#9#:4[ 9tBr@r@f:d8^5`6$;"3M,Ho;]{e|ž,De2Yªc.Hn±qŽT¹|-ŒVÂŽJ†RÌ fnC‚S¥f žb ¥d«g¬i²m³oѪw~Pœ` Nj’zNvNd@rHJ?%lGuY€h!i!ˆq,Št0jF0Mw=QijFp»w—Ä8Z‹@_‹DWmLp¥MNPMg†Om–On–Qu§Re~V{°Wo‘X}²Y}°Zyž[z\~£\¶]~¢_} a§a‡´aˆµgV;g†«hˆ¯hŒÂhÃi†«i‡­j‹°m´n‘µq®q®|ŸÓ}q`~œ¶~¢Õœ¶•³Ê–l/›k›l ¥j¦m¦o!¬e°h°t²s¸y¾‚ÀqÃuÄsÇ„%Ì­ÌÏÖÍÖãΫxÏ¡_Ò|Ó£_Ô©rÔ®xÕµ‡Õ¶‰Ö~ÖÖ Tׄד1×±{ØØ€ØØ…Ø­pÙن٪mÚ€Ú±|ÛµƒÜܧbÜÁšÝ³}ݺ‰Þƒß§W߯qß³{ßÄà„à³rà´|à¿á˫⻈⽌㺅㻇ä >ä³nä¶zå¹{å¼åÀåÆåέæ¦Jæ¬Z滄æÀŠæÁæÅšç½çÂ‘çÆ›è»€è¼~éµqéº}鿉éÄ•éÕ»éØÁê³d꿈êÁŒêÃêÆ˜êÇ–êÇšêÉžêÌ¢ë¶kë¾ẹ̈콀ìÉœìË ìͤí»síËŸíÌ¡íÜÇîΤîÒªîÓ¬îÔ°îÕ²ïЧïÑ«ïÕ³ðÕ®ðظñÒ©ñÔ«ñ×±óÖ±õæÓöåÎöèÖ÷é×øêØùëÙùðåúìÚúðäúòæûòçýùõþûøþüúþýüÿÿÿHètåAtRNS .9:;GHIJR{Œ¥«¬¼ÕØØÛåééëëìííîîîîîîîïïððòóøùúúúúúúûüüüýýþî0“bKGDòÛ¶ŽxlIDAT•ÁONaÀáß÷~_Û S[RIMŒÁ„Äk7žÀxà<péέ;€1bŒÑ°‘ª…j‡™Îßo^aéÂ…ÏÃ1\±AäDV–Mý;÷\2\²áΫÍFU›ã§'™,`ÃÑ‹­"KãùIüà}æ,Hwûù­´È“$YæÍý£²V,fuül7é©úüî4ñ{Çe‰àz‡ÓþõYÑý­‡-ïŸô@02üow'½½A¸ßÒ–€€”ÞV¸{}˜M[@@ÀV•ößXø>l'„“ö5 f#h^N í B°Þ/¿U#@Œ Ö· `Œ´ÁÛ³ð«‡Æ³ oæ¯O« 6þóêæO‹úôFøåæá$˜Î¢@ êòli¡J“a÷S,Dçgu™%Õ׋ڂVi1XGËvʇE†´¼¨Öœj³&çƒÎÑ<Ãé£ïš‹ éD²Èù§?r‘¤||‘ IEND®B`‚eric-6.0.8/eric/icons/default/privateBrowsing.png0000644000175000017500000000110312342633755021104 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<êPLTEÿÿÿ  111666 Z[€13yjjjvvv pq•xy¢ŸŸŸóóóøøøùùÿüüÿÿÿÿ"$c©°°°ÊÊÊÌÌ̈Œÿ‹Žÿÿ“ÿ 14@DºV[úX]ÿ[`ÿ]b÷]bÿ^cø_dþæm™%CtRNS 48:>NXZj|Ž’¦··¾ÄÊÑÖßêñôôõõö÷÷÷øùùùúúüüüüüüüüüýýýýýþþþþlKˆ|IDATÓc` 0óð°"qù¤õut %ù \nuk__c-)._PYÏÌÞÃÕÕÃÁTWU˜‘AÜÙÆÒÜÓÝÅÅÝÛÂÒÖ@–SBÓÄÒÑÃÍÍÃÉÒNEQ¨‡_AMÛËÃÃÇHIC„l*¯¨œ••¼˜’Íìl Ô,ÑBªrìIEND®B`‚eric-6.0.8/eric/icons/default/ircAway.png0000644000175000017500000000070412342633755017324 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<¨PLTEÿÿÿ """ '''<<<===CCCDDD:::;;;AAAEEEAAAFFFLLLMMM^^^PPP```ccc‚‚‚†††€€€„„„‘‘‘ŸŸŸ”””   www‹‹‹ŒŒŒ’’’­­­°°°½½½âââäääæææëëëìììíííîîîïïïðððñññòòòóóóôôôõõõöööúúúv^/ tRNS '(,LRdjvxy€…Š’”˜™ž«ÕרÛààãã’s¿1bIDATÓc``ÀÄ'ÂÏ‚Äç2U0á‚ó%ÌÍTtÌdYa<úf†ÊZ¦B0Q5]%EuUq˜¯ž‰®¦†¶±0ÜI3yv¸©œÒFªÆrÜHö2 ˆ ²10hÓ[nªIEND®B`‚eric-6.0.8/eric/icons/default/flashBlock-flash.png0000644000175000017500000002542012342633754021071 0ustar piotrpiotr‰PNG  IHDR€€Ã>aËsRGB®Îé pHYs  šœtIMEÜ8"}Œ8bKGDÿÿÿ ½§“*IDATxÚíxÕµÇL -@CŒ»eË’{/ÉS%’‚ÍãÅ!y„ð !ÍtB›8NB „f‚Cq/r·ä"ɶ´½÷®=ïügîHW£™ÕJ^Í÷ý¾Y­fî=çÎ=sïÌje±toÝ[÷Ö½uoÝ[÷Ö½uoÝ[÷Ö½uoÝ[÷Ö½uoÝÛÁ°­êc9æËÞ–>_ô¶Œçý Þ_±¤·e–ø8ÇöÁ¹Ý @Ûg§YNå@VpoãýóÌbd=ï}¼O0´¢…ÖôµÐjx¿Ã18Vœƒs£-ÑfúèVz?Ù>=ÍreêÒÞ–»x¿ˆæä×¹U"È+y¿œYÆðû KÚA;n™8w¥hk•ÚF} /ôÉÉ06tGbn/~Ór$‹_ÉA˜ËT3ÙÕ"@Z —t!è}¡Oô-l˜ ›`[w„ºn´÷eñÿ—YÍbgµ’½T7rЂ÷e,)°Í¥â’‚d€M° 6ÂÖîˆi「`±ŸärìÔt³ÀÈı«KëÆ ¢M•hëgÒö«¯¤×ý°x¿Ã18çà\}{fýÊ•¶ÂfØÞÁNn<éÎÂÎã^£ŠÚîÇ1UÃ{SÍÓž»ï"ÏÂ^¹‚Û·SÚn£l8DM©”BN‡ö>ŽÁ±8ç¢ ´…6Ñöò>íWˆå}š'•a>n|éŽhÛç§Yz³€óˆ Ê_Ö§¹c¤Ö̼ˆl=BÁ/>§TcƒèD‚šbQÊF” ) PÆï£ŒÏ›ÃÇ✋6ÐÚDÛè}¡Oô-Û²LW´D€/ð ¾uG8Ï䎅ºž…Ú³V\ß—õ1üÊ~‡QÍ¥ç“óùg)¶y“4û´ÇM)—³K@Ûr_è6ÀؤO $ÂZ5öÀÇîÉ¢ncF³0‹äk¼>ðËDyß}Ç/)¼l)¥œJ{=”vØ)em¤ô>$%@ß°¶À&ØV5ì´Vó™•bŽ_áó!x*³ÎBÝÌÂøÖömY³/×­ß×ó¤ÌöèCÛ²™Ò,6Jqr÷nJîÚµÀ¶À&؆ª`{äAÅfù~‚œkÕ{>ø ÕeÝ),ÆÂÕÒ ˆWUv 5þñ^Šsà1â’uu”ع³ɯ„°¶ÂfØ^UÖ³U",o[ B‹C*øìô8¾Æo¬êÛ6ðŠ8ü~ý?¢ÈŠåÊKlÛFñêꑨ)í[éŸm†íaö¡nÎlŧe‰^¥Îw6r’Œ=$‚ÏŽ^ÎÙïY+EŸ–IßæicÈËK/,Ãâ[·PlÓÆø€d€Oðm™äóri‚Ès¿žy°üŸrð“«û¶]BõÑÕ«”ò]WÕŠØDÔÅ'ö >®ìÛ:ñ—‹Ë´Fkðoç,WÔèƒ_Uz29žzœbÖStÍjаP!úéð >ÂWø¼\§Å*•´:Ø–yhOÔ4gµ‰ß¦ eäë ŠV­U–Rz"0aà+|†ïÚG9 Ä °Šà³s·‹eO+àlõŒiüðŠ,_FáÏ?£ðŸ°¯ð¾Cƒ:]V¶,o?ÐGþÍœÍJÙ×Û…gRð“Eb1BŸþû#ˆ=û  Å FâÁR¨ÁŸÉÁO¬îÛÚ)ìkί¤àïSèߟPðãŠFh,2Ь4Y!i¤Ý'€†Üê€˸Åò¦%øçœNwÿI!.Á½GÁ÷ÿeJè ØЀµ€&Ðf¥N/¡¡š(×üSØØMë ‚¿eÒ0òÿãoŠÓwÞ¦À?ßiEð `kM  4’“-7AÛý:øojéÁF.ÜØ¯ÅxíÏúÁ'ûÅç‡ýoþ£™@,]iŸ_´FÐJÖ@Sh ÷çÑÓ:ݧm•e o»÷n ¼ý&ùÿö×¼4þ¾°5<Š iÇïfÿY#hµ¦_ë„ý:u>uÓ~|ž¬ŒâëU J÷Qkìëg_¥”7ß_æ„¿ŠH›ö¼N¿þ… ¨ûó[ý¾Ù>ÎÏÇ€B}WÎ{ãïT?ëûm>º¾VÕ4­÷«à¯ïk9’ üeJü­“ÊÉûÚËä÷Šº7Á× üû¶ß?ÿUò¿þš ~f¡÷Þ¥/éâUk)YSC©º:JÛ¬”ܶM=ÕÙžO E«W_¢­ËZi „ÆŸ@óý&Ø 9ú©†Ê¬ã÷ì¸Guê¥ç ÆWDü{As; %ø¼ÆÈüg1%·o§l0@¹tšŒ6|ÄLKžŽø¯ÀçA»*IW- 6¨I0gý½Ø¸†uRàE©¢ÚË. ïË/ç¹gÚÅÛ |]Í &ÿ+/’ŸƒŽDriޝ«R>/XÈ–q»ÈÇç#i¼Ï?ÛÊö‚4aí ájýÀR÷ Ð~ýOlî×:ø`cɱäzøOä~ö)r?ý„‚§“x¿|0?ÀÏIàÑòÞSG6%PA0žy² _Ý2¬4„–k¥6«Uà‰¯ú†Oª’¯±ëê+Ƀà?þhAx:·+xb®2ú•K?òþ¿(ãqSg¶ŒË©´áã¥çÉÇšívwh-em‘BóbðUÎüç!5ê¤Ñï¸ÿäšû0¹yÐwxöl¯ïÏO+£ÄV­¤\6KÝ”àJ‚$psÛfþåÓÈÉçAK¹ hˆÊ;ï«ý#ùZ['_K€ºKÎ%×£‘óO÷)¸ ÀÝ<]Áƒ÷“Ë´£Ÿ–¬©¦½Ý”à„î‡h¶¿=œв–5•ÙZ1àŸ£Ì¾ÿÃ6à©-ýZ¯±¡¿…lwü‚œœµÎ?ÞkŠ«@ÜEÆcÄ}¿'—h?F?—k,㊱eœòq .TDíÁçBSh[¥l[Ô üÔ¾.ý}ØÏ)D6Ò6^÷;YPǽw7ãlWpß’—G˜|ëøbmJpU.^ÒÉ~´§‰C4…¶²Ö`½šÄd_Žþ[µÑ¿NÇî~W5ú·wæÅywû¸ À½7üöòðèòc”>õ8%x¦_ÌMI¬(çï~“××|ZÙ±gM¡­¬µ–¢ ܺO‚¿­¿å(îl& š!ë›NÖ_üŒìwýšìwþª œÀU$Ü,¼ŸK¿gþ‘EårÅON,àädÓûc¤‡Ý ÖÚBcý Û¤&À:Äf_Œþ vv½.øx½mì Õ‰_ßfˆ£œĵ—øxíçà„̧¦XŒŠ½eq@$˜ô4°çÚÖ°Æë$Í¥×YĦË€;š[Ý¿uð5ê.˜Nvž¬Ø8S5ìyp˜à쮎pÛ-äùÝ]àÒìgÒ»w'à‘0¥ëë)¹qÅy ]ü©’`JÜ~«¡¯övh¥%k õ &œs»4ø|­9Ž;«Fù× ÀDà!žFÙX\ûÏojƒ£œ]„˶ÑÿØ#äüQŠ}öŸ½ :o§È¿Þ¥¯ ”€s»:./~žzy¯$¶°©=-ì&@[h¬i.¾Mê%¹1êÊò?•Ñ:× ›XÈzÃud»åF²ÿôSyp¶ƒ«Üt=yïù 8PÁ—_ &µñvEða øs&ïƒ÷“—'—žù+üžgñ?û‰âƒ£Ìt³Öo`i“âç bÔ•åÿ.”9ðžºôëd½ñGdûÉœVØMp´ƒ³\ís³ˆýfofý©­[(ðÜ3àÑàà{ÿð;rýòçJ’)6r 4€û6óÕž½žÐx+k-Ç@Kqi¾«K‚Oe–ø“Erl”Ø>ª/ÙØ8ëõ×’Í»Ž<8 ÀÕ~4‹¼<òu?<ÿUÊ% ~rý: pYÇÂÇ£—çœÙ*:ûòùg7ÁH;«oc­åÁ§Ø FˆUÑ€;ëÉ;7ë¿IìwN,#Ûÿ›¬ÿs‚Í» ŽpˆËŒë~¨$ÿч”Q›\WÕ©à§kk•Ëð¢´#èÿ}u+ ñÇž½nV h ­7êâ \†ÕJàD¬º"*å€k¯5ê¦R}U+l:ìíà0ÁymçpiÌúyx"†Ñµ?épð›BA ¿ò¢Ò†ï÷pû?0ìÓ‘Ç|¾Û h£'k\ËZëc!'bUôà†oÝÖ¿mà7 ê*Ç«Fò,UM‡ýšü8òàÜ ü÷ÿž‚\ºã™ùçrýèC¥ôûñ¤£þ‡W¶éÃÌîö|Ökd5ƒ5†Ö›tqРFÜÚ ðÂŽ­`³œgŒU l¼êr²þÀÛf6c7ÁQÎàW}‡<\þCýÏ>¥Ü¡ëð]½]»”‘Ü|v^y19¿9¿w)94øç|v›ùlÓa¦Ÿ¢-k ­5ÝõI°C]!¼Pô 7¾À(ø¸]ÏY Y «6½&8;Ë÷›_+Á½óåšš7} †×ú8 ä9„‡—tžøµWH:Çw/ies{¾jšX¥½L+M9p¹•õ—“ F­Ò‹‹:ÄצsãõÕý[‹DÝÔÔÈŽ7^~Q+¬¶<Ø pˆ33/Tª@ˆ'~a`ª¦F *—ô‚ÀÄoçN qéá¶1ªÈ3O¶†+ôü³JuP.ܧf›‘_ùtõj4‚5®›2¼Yw}"ˆÕõ«î«úZúr£þ­ýƒ÷ë&S ¼ìü6XuØ °çÁa‚³.9‡¼<2üf¼þšrÏ¿C À$–.¡è?þFQ|_H!n?ˆ‡>¨—ž§ØgæÍY##k ­eýõÕ±BÌŠy x7žØ¢ >¯Q7njàÅçP£„Õ›»ŽK ÙFðÁû(üç§)±by‡ƒ¯É˜Ã—‡¬ÇMa®¨.”ý‹Ïn¶ÍÈ/›FÉ:6µ¬µ¦»>ıW´àŽfpƒ¹-&ÁµÃOU ½ðL…FÖ‹Z°åÁn€Ãg{\PIžÙßW‚yéyÊx=K€væY¿Â/üY¹¸x¾á¸pºbŸ‘/f~Ëúèµk€Æ;YkYû-ýÚ$B1+f¸b{ãàW v 9Ž.˜ÎT*4JX °`7ÀQ N#Î;ƒ<ù‹¼øÅ?þ°ã/09²>/…9Á0páÚ~…b“‘?F~éÓ¨£¡™éŠÖÕº('À6õç+Š™³ë´~µfžÛZhόөáÜi :¬ØtØ p˜àlSÈué sP¢œ™úz%XMM¹â" òÊ‹Ê<Ãõ ÈÁ};LüÑûl5AÖ®ACkY}ˆXÍ.ZpI™…FÍ‚u{*ÆRÃ9S¨áìÉÔh€U‡MÂ~Ž9Ž<8͘>ž|×Ϧè«/QŒ'iÊ·‡ç´¦â¢%÷ƒKë²óÈ~ÖļþØt¾ëuÑëÖ ÁÚBãmBs³$@¬³¢&@½AÔè`רÔpÖ$j8s‚B£„Õ›»œùàÝw/Eyd&—/£¿©k€ç‘×^VÀÊqŠ}F¾È¾ši"ëÖ ÃÚֳƲîFIPôàÆ•0 ¼Fm)ÏXøTA£„UÂf€Ý‡ ÎJÎE‰Ñ—_ ØüW)ë°+êʈr?˜k¸0Aåþ&¾ù-ëÒ¨CÖÚBcMo£D@ˆX7v 4.û˜$â6dÃÔáÔ0m”B£„U‡í cì::œíàS‡Qà¶[(¶`>%>|Ÿš°Tã`u ZüeE8á\˜”ž>B±Uï‹-²6²n {X[h,ën”EOn|¶–fÁ×`/QX%˜F «›„ÝGœfL)'7”(Oþ⯿Féšj5HÙ¦®!§&@쯯+—¯<lƒf§‘_²ßzMd½dXSh«im”Z VˆY1àŠÚ-™Ôrç “†*4JX °Mn‹]Âa€Ó—Æ„ò_w5Åyâ—xûMÊD£”ᑚá*Ð%ðÄ2ã÷Süo¥(Ï\çN%ÇÄ!ÍöÚuèý5ÒEÖ­Abç@Uãí’îF•`çe_¼e w4ƒ;Émk'ø;»†}SMBƪÃ&a×áÐá,ˆÁäšRF‘'æ* Z»†D”Îd 'ÛAÅp«˜ç.¬N8 eÛõ¾É~ë5ÑkÖXKhºs@‹ÖfI ö¹íżÄã†Ûó_N€:ÜÛŸÆ—P£„UÂ&aŸ`ŒÃ§—̘¾äûî%”xë J¾ó–ò ).Ó©L¦ ÒÙ e’)ÊÄ”I´%mD2©üùxüÍPŒç.^:Æ h¶×Ì7›NYY3h-¡©¦o¾$¯«qE}ÄYå×& f#Ô v îA,D#¯aÕa“°K8ƵÆY®±ýÈÅýE{X ~zÍjh%SéÂHsÄã”úì3J~ô%}dHÂ>>Á}Æ.PæNND½²6²&zاú’Ц²ÎfI°C-ÿÅ}„G‹Üx}í€Â‚°Ý3ôxjÓG÷Q°JØ$ìŽÑ½ qšàÓ[ùΑ§ÿ»Sò½*¤=JpIOpp !ÉÉ’©ßEITwß¡ä?ßîÜg‚/;îéãÈ1ª—¡v¯²²6š^Ðn7kX§ÓÖ, ”¥¸:H‹û8.àFcvÙ^ðë$°ÙSv"YGÆôR°`7À!á”pòmrsÄž~‚’ü‹Ò|íOðˆŽs9'’‘äcS_~©œùÃïÈé ò_~aÁøÀeç)UÈ©³ßÈ?#¬¬´«—ôÌ—Z" FˆUÑ?Ì¿Ð0°cÁ0¨¡ì²Žü6YGœÚŒMÂ>²‡FµŒË7öå_§ ÏüJ™þÒ<+q@c|-/®i—S)ý)ɾ³'‘«ìxr ?™Ü¸$œÃTš_ëlvè|’}•5µid­ YýÀ I$@ƒº,îGÂÄRðÖ=;|†!G±s=É6ü[ÍØ%:œ#Œqé)?¼ÓFR’'aÉ?¤ þÉ4‹ ŽO¯_GÉOQô¡ûÉ=ì$ô7ÈÍíá2ÁÌf½o²ß²VÀA+M7}´—»Õ(þ‡B9»*w¶üzƒàï–h,±µü$²ñH±3Ú^Æ!áÖz„éq—Ož±})þÜ3”Zü)e–/¥D4Fáhœ‰F,A)@9?…¯nç2î);–<ܾwA® ²O²¯6Ц¡¤E/y™U‚“CĪè À÷äÆõùrð÷q”~lå'’K·†C©Ã%áÆð¨w•I^ž]㺟þò Jþ™ò_bTü? Á¤‚;Y„kLmžÑŸ7øVÎtûЯ‘¯u¾Þj8%\ÍK®¡Ç0G“kHróÞÑtJ.˜OéeK)óåç”±Û(È#ß Œ/¡x(D™Ë)³t …¯½Š<¥=8ŽÏ‹;®²ÖÈþÈ~ÚNP4€š.šVù’ Î$ Ô{]ó§aظñ»¬ƒ:9ò%© -G³ƒìlæhr 9\ÁÉ píõN.¥àfRüéÇÕQà¯Z¡ücg?f?HÞ@¨ p¬?£Lmeð¿ˆß~“|£{‘wèQä-;¦Ü¨‰ªâÔûÄ{ ø ß5-€> öt°  ĨËþ:˜/S¹ÃLgƒ/;k•°1vÆ1ø0r–¡,í¢ü‰bø?ê¼ú%ßø;¥þ³˜Ò«WQ¬\AÙm5 ÈÃ#Ùå »¸8âÁ Ò–‘ëg“wÈaä+;šƒnŽgh[Ü:\N‘t;ûh×ùŸ/ ­‚ bÔ¥_Á™V ÃÌfû…Ž|9ø6) fà©ÏþC™M)³®Š2Uk›ÉnÜÀ£¶–â|½G ·{ýdw{ÉáñŒññ% »s§Òf ßÕ?ìò•N¾¡G¶Ák‚G‡»´5˜§à’åÌÉ]ÒâŸæo1“`ziîÚ/ˆÀÆÌ…ñ ¾ÑÈ7 ¼R—áä'Sºj eöPÒn§˜ÓIaºßÑ +Ýêrw ›×GI·KM.^þ…/;—|C,ì#Ô$Ðámíð4Ãó®"n¸‹îÂ' }ØŠ”6õÒܵ_# ‚Èjt&øÖ<ÁWàeY†Ñöù¨Þá¢]Àî¤z›ƒv1»ùµÆGáàø _6šøòKHâÑÕà—f|•üC€…<ƒUpw‰ŠKÁ×Ð'ÀÞ$~y(ôÏ"6ûäkâ8ãÖÁX³àï)°ì¸yÒ—âI^SõV y<´³ÑFµ{A`gƒM¹4qUÉÖTSš“,0êòqý>^PÒ‚G‡[G{Ià(b ÄÄ|ß|Mœ¸'p«}Pᓾ|e_E Ë)Ìðs;¶S zw#Õì%Õõ JI󥤉ƒ ¹tùJtÁ/1Çk@¾d0JG;Õ@Ÿ…¬ ìê%yß|Q¤H€>ܱ§¡Á·|€1i|Sw]86Õî¦-ugSí.ÚÑh§„×K¹Ú”Û³›âwþªMð(4ö6 lHyÐ5¨IàALöé÷s§OÁ™Bgüyƒ_Ò„Â6LШqù=^Z·½Ž6ì¨ïÛê¸X)Ás‰Üî]”³Û(õü³àà‘7Œ.M ³$°v œj%Þ·_-ªÀp6(Ú8¨ðÒo6ò]:‘¼ÃO¢ O‰ƒåu{hÕÖí´¦zG‡X»u­Ú²])ÿI¿ŸÈÚH9^EdðÿK-¦ Phbìm"¸JŒ'‡©âç(bñ•üÏ6bÙ›à+×|I$ˆæñ ÊnÝBÄK57'À²Õ´rSMÁ¬ØPMËy_gµSÿÔÉé ¦€ŸÒ æS¨ük䀵ÇÞ$ƒ>)ŒÂUÀ±½p©Ž^µ|USÆ„¬ƒ:|—x±¤‚Hþ‘=)»}ÍÉëöÏÖn¤%U›ÚåKæ >¶Š+€—¯÷„àû¼Ê—;¥žy‚B<òCÜGhHçê0KŠ6+ˆÁ’ƒÛ&³I 4q" µ|•ð„§Äàž¥žiðŨñóÒ wé(&'À¢Uôéªõ¦|²²Ja)WŠÝ6¥#"üg¯X”r6¾þßöS sÀ:C{‰`VÚM‘…L ’À£VÞ¯öŸFacƒz±A ŽG¿SwÝ—@*0º5ñ„ ²9]ôþ—«è£¥k>\ºš>X²Zy|Âɱzs 5Ø”ŠF‰â1&N¹TŠ2ŸF±s&QxpK@#íPh"´©‚ŽV‚ÎT‡š ÐÞ²?llÈ8RhðåPÄ`ἈۗšxÒF™ ÖIo~º„Þû|}À_´|-}¾f#Ïîky´Û) SS2Iðø{=^ç'o½™"e=ÔÀ–îa!A‰æDð 4=í–qG“À¥>EÜ?þq$6üSÎÈO¼%mÀQÀèWo­ª@¨Àøþ”sØñל< ãäp{Éë P0¦ÿ¬ü§Nü7¯¦&é{Ü2Ô´a=%ïøEG~³%ðCU¢$b@!Ið ´[ɾÒ?=`pa·å—Ûýë_ÇbcCG1gJ?@Ylõ%ub‰2ko÷»c1e´§_y‘ß»„¢ÃOP¯ìpäÞ1 ,’JþR•6ÏØgù2PHï µeܸ,Ýä.i?ø.iÉüeG“èQ ¡=(4a€òœ¾içŽVdW® Ì;oQ걇)qË 1™"#NVF¤2Ú¹äGËlEl/з);ªa‰AA@BóSùÜÁC¤|IàVKÿþùïãÅÇÆz°¡ 1.dôkkcù±Ìñ(?N!8¬… x .;¢¹ Gøu„ß‹ðï¢:b&ć›cvŽ¾íˆ aAHBóCó ~ûìÉsËXŸ˜TrðBcËþ¼±S§°Á›|%…_IŒ|Éá'*!AX"2B%*k‡x'ÉצÜDB³3$¡ù£ùç~2_Ž2¼9dT|jUÝm-ÂÆ™:–q{JÚ®ùõ €‰#fþA^ûGöl&4J%,ˆHD1‰¸Dbtñ‘Û—ûJhöi6k>È~)ˆGÐ^“;„rxÔŸÝÐÔr mœ±3ÙÁ„§Ä|ôk·J‘á!^þ…Æö¦° b@T“ˆk!¡#¹—ÈmÉýÈýG%ôöj¾„Aö¾êo%€ø]ZZĸ™Ìy À«K\ã0ù OØLd¢JT3 .‘HêHuý¹ ZFöD%4û5B LÉI ÞËñœêf˼qÜîÜâ Ñè× À3ãðéÃ(„5Ø7ø¨}Î@Ÿ­ˆ©×ýÛ-ÃÆIð@@8ÝêÚ/ß/Çô¢è™ã(Z9º™˜D\$MHMoMºƒèÏ7êC³!.¡ÙÕaŸB£OmóA}Àë€zƒè>ËÁ´‰Jó6ý~éJdÒ`Š;…bgO¤¸‰sT’‚”DÚàg=ŒŽ5kWë[³ÅÈΘ ʾ„Ù§€Á§äïçœËÈ7˜þŒL›_{¯”ý‹Ï¢ø…• Aò¢Ö¤$Ò‚L µ-÷§·E³Q³9Ø\‚FO ¥*TßKB£ƒ1öø[µÃ-MtXíËU,‚;:Ä<B‚èä!”¸üBæJÌ<Ÿ’‚”i‰ŒDvæy{…Ü–Ö¾Qÿšm ØÌ¶Ã‡ÁM䈨OÝÐ)ZYºèïû¾¢ Ñç¼ó޶ü>êÓcOvjâºçéA]à1n”¯›É+ÿ‹’×\I©«.kEZÑ‘•hÚ ävô}¤%d›’€mM°Í°=,|1J¢Lüj  ´Q4b­„fU9zôèc'Nœø Ë¥—òË¡%ø¾ÅÊ3xƒÑ¯%~‡2É‹¦SjÎ,JÿèJÿÏÕÍdÙ}ˆÖgZGŠmƒ ¶6‡…!) ´Ð|ÛÁ@ hm ´:˜@)i¥¥¥G1ÇWTT|kÊ”)ƒÊÏ:kì”ŠŠ Þí{Ìë\c‰!mGsãûQŠGWúç?¡ôÏn¤ôÍsšÉèÈJ4uùüŒrß°%Å6¥f}—âlcó‡K  òñu?ú^¿ãæCE ÖÚ@#hu0]àD85yòäÆ*;[:iÒ¤©“*+/+›>}Î/ʇ¼¸¡¿Å–G¿œ1Aòô2uôßqeþý)ó«ŸSVÐd@®¯µÑ@Ÿè›m€- ¶)&Ùj”šðõ¶ò!/ 9ûì9ÐZ@hDô8(`ìØ±ßæýЩ§OÆ\ÁÜ2¦²òþŠÓ§¾þÔ ooÝ3Ð’J•¶QN€¸ ÁÇ$' Ì/§ì¿¤ì}÷*4ýþnjºç®Vä:A“Yn[ë}¦¹oؠ٤%¨œaxøßà#|…Ïð]h0 šm˜6mÚéÌåìüOyÿÀ”iÓæ™>ýÃË'Œßøfÿý¼.nJ—¶Ó'€ ÉǤÊ{Pæ¬ñ”½~e¬G¤ÜÓSîɹ”{üÊ=ö0åæ>DÄïŽUÎÁ¹hƒÛB›h;Ã}¤¹/ô©Ù`–1xøŸà|„¯ðYø~9´8$€¯qdzÓ=y²3˜KÞä3Î8ãÞÿ˜¸‡yþŒiÓÞ\Q±tBeåæÙcFY?ì\7F2¥ªÐ1ƒà+ @¤‡Z(;¡?5ñº¼é†k)w÷”{è~¢gž zé9¢×^ÊŽácqÎÍrh+Ãm¢m­/­o£$À6ã9ÈûìÃ5ìËDö ¾ÁGø Ÿá»Ð`246Ðè`KeÀ³Û#ËËË7nÜ7'L˜0€¯{cØùsÙék˜_1òϯ3±8+'UTl™XQQíè‘®·úŸsñ(Ê–ªÂjÂË –À1YA­©ÌB¹Ñß šØŸ¨r$ÑySˆÎŸJtÅ…*x÷ð;>Çâ­Œ@kß(CZúu²­°™“Øà |‚oð¾ Ÿ¯Ðš@h­ÆeàœåÇp†ŸÄûÞ,H¹˜\Æ\Ï?ÿ†y‚YÀ|Èï-áý:°f|eeýãÇÙŸ)éª`Ic„冪b§u 1J€¡êñd‚ö{íœ|  ßãØÛžfa+læÀ×ÀáˇÂ7øøø,|Ÿ- ‰Ð昃ñ>@óe`àÀ'Œ1¢'gû@.}£yœÅ"\ÉÜaøç¹Ì«üú-æf)SÅ׋-c§Oß>}ê”Ý?Qî|cÀI‘Ú– F¡Àl;Á§h/ ²Rõ°¶À&Øa+l¶Ã‡·à|Á¿>Ãwh-  ´9Ëó½”6døðáÃOâlÿ6ƒëÞ8ål1¾žE¹¹Ÿß{zš:YzK”ÎϘ<^ª&TTlâVsî”ɵ?9ÌúÚÀSükôˆód+«¨Lbè^"µ•U'tYô…>Ñ7l€-° ¶ÁFaëG"‰áÃÓ𠾉‘…ðy4€ÐÚHåÿ J€æ*Я_¿£qãÌ?™³þ4b3–ŘÎûKY¤Y˜óþN!Ú“ÌËÌ_™wD)]Œ²:…ÅæÉÕšq••ë§TTl¾tâ„í· /ÛóbI/×¢þÇ7°ÄyîæåV9}@ Q'z9œãàsÑÚzÛDÛè}¡Oô D‰_ Û`£°õea;|¸Sø4 > _ÇÂwh-  ´9G›¹€œœñ½xTÂbŒÄ ÞŸ'–F³Y°›0jx„ÜÃû‡ø½§xÿ"3Ÿ_ÿ]$ÄûÌ"€Kï<—Œž>}9­Õ<ã®:wê” ß?nËÍ£†oÿ¿ò!u÷¸û±Ò~ Fàw8Ç✋6Ð/ß–£mô!‚>ß6À–ù°MØø°Õì&ø"|:Oø_Kà».øÝµßø© ”eee'‹»ƒý¸–‰j€#X!|‡¾šùnšAïÆ¨bÁãß=ÇûWD2o0oóûïM;ãŒx„~Ä“±9xŸp©þ÷˜ÊÊOGMŸ¾˜ùŽÅøŽÁ±8ç¢ ´…6EÛ E_¯ˆ¾Ÿ¶Ü/lC™¿6Ãvø |Ádo,|„¯ð¾ÿ0ËA¾5'&Ñ7l€-Â&Øv¦°uô‡O·á+|¾‡Zðå$8Lp„œx4Š2)ÖÇ $‹= Ë&t¢¸•\ÉïÜÏü—XWc†ý}11éºVT9b•ñc± kƒøféspŽ8wÚB›b¥r™è }ž` l‚m°¶ŠJÖ[ø_¾® üÒ„ï ~ÞË‚éX¬‹±<%OÊ0cî‡G§bõPÎB@‰ÅˆÃ-UƒY™¶XgÏÀÈDÀP–ùõE F¬ ÞÃïp Ž£y†¸O¶*Ð6ú£—(ŒðrØ›`l„­°¶ÃøŸÕrß™ŠŽÄäHK<'Ç(¬ârNÁõTÜUì+n/—àžºxØTÎûá|Ì(Q5ƈ æ87Aï‰{cEBa4B¢­¡h} /ô‰¾alM° 6ÂV-èb‚w¤äW÷ˆ/0—/=SÜ,9MÄDêD-)ð0ÁÀS5FŒÆ>üs_ŒN\‹h„ö{‹sp.Ú@[hS$]O-Øè6Àñi§c`£˜ÜÊeþðîÀï}24'„EýxYs…Ъ®±eW|øDI”b,¹p-–A þ}‹s´£-´©µ¯nm„‹`ëÞô.H9—ÊêZ¥«…¤ž={89Qôh¿×Ž—ƒ¬jid!õ¸AЈÀÿ?É(Aæ„%IEND®B`‚eric-6.0.8/eric/icons/default/taskTodo.png0000644000175000017500000000253712342633755017523 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs „ „ªâcytIMEÚ !§ÐnùôPLTE¶ûàÿªÿ¯ÿ¶ÿ¿ÿãÿÿÿ®ÿåÿÓÿÄÿÎÿºÿÛÿËÿßÿÜÿîÿìÿÑÿßÿËÿòÿÊÿ÷ÿîÿËÿÚÿÍÿÑÿ×ÿÐÿÑÿÎÿËÿÌÿÄÿÉÿÅÿÇÿÆÿÄÿÅÿÂÿÃÿÄÿÂÿÃÿÂÿÃÿÄÿÆÿÅÿ½ÿßRÿÁþ±ÿËÿ¸ÿ½ý¬öœÿ¿þ¾ÿºý»ÿ·û¶þ¼ù®ü´ü¹õŸú²ñŠìv÷©ø¬ ó–üªîæmü°ù±÷Ã%÷Æ)ùÃùÌúÄ4úÐ%ûÌ(ýÞ±ýäÂþ×’þØÿÚ£JKp rEBwMI|MH|XX}NK! " _^„jjŠpoŽz{“€˜‹Ÿ’“¾¯žÇ¶¤×·غÜHÝEÝFÝGßNçxéê‡êØë‰ìŒìŽìÝíí‘ï› ð ó¦óªôßõ¬õ¯õâö¢÷¾ø«ø°ø»ù³,ù¸2ù¿9ùÀ<ú»Eú¾4ûÃ@ûÃGûñüÝžüóþÓ`þÔ‡þÖxþ×þÛþÜhþå<þèÿÐnÿÑAÿÑZÿÒGÿÕ.ÿÖ2ÿ×ÿ× ÿ×'ÿ×dÿÙÿÙ5ÿÙPÿÙWÿÙnÿÙÿÛ«ÿÜÿÜ;ÿÝ›ÿÞÿßÿß4ÿ߆ÿàÿàBÿàsÿà°ÿáÿábÿâÿâ`ÿâ·ÿãÿãÿã;ÿãƒÿã²ÿäÿäMÿä˜ÿåÿåqÿåÌÿæÿæÿçÿç'ÿç4ÿç^ÿèÿèÿèHÿéÿé×ÿêÿê(ÿëÿëÿìÿì(ÿíÿîÿî(ÿî@ÿïÿïÿðÿð'ÿðAÿñÿñ(ÿòÿò(ÿóÿó(ÿôÿô(ÿõ(ÿöÿö(ÿ÷ÿøÿúÿüÿÿÿ…þ(êbtRNS "&+36>@CILMNSSTTTUUVVVVWY\dgkqx€Ž‘ŸŸ¬¶¸ÂÄËÍÏ×ÚàáäêòóøùýþþþþþþþþþþþþlŽ‹bKGDû¢j6ÜvIDATÓ]‘Ë.a†¿ÿ0™†¶ÓF'¨ Z– A7ˆ6Bl]+;W!±röâH¬$H$$„î-0S©¦Óÿ`Ñ–Ö·yß÷ɳûúOëò‹Œ\Ú«þÇ*_Ø™uö?ÌǦÞ^—Ÿ+ÝI»Á&×6ëW¶S°EzÚiã%wÀÆvqîT®m绳;8m^!¨²eõÛº½:Á„$ªf;_¶µq[¡`¥0 ZÏÛ¡í¶*˜†ô»dÌíÙ©BDâsѽå,:xȆD Lp"ý¸O$} R+Ö·ôP‹!&ý| À£¶nÄtÍ›!ÞgâÁyªy™Å"ÓU-VFÉFË÷ŽÝw{ñÄ“b„"ÆAÅ=TŠ/J¦Õ¢ÍíÖT|´Œ¬f£]ÏΟ|¾!3܇ˆJ11ÁiúUQ/Ÿ7ohx)=©P çl<{öH›—­’”  ÎG”Ç‚Ôp„K,%q$¤Y{ùóäåí®ËIEND®B`‚eric-6.0.8/eric/icons/default/drawFill.png0000644000175000017500000000265012342633754017472 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<%IDAT8Ë•{L“g‡_$*ÞFÜ S ‹ŠË Ž0£#Ñ‘]î9$3Ë@]²°Í騼$†i‚   —NPl«((-"B©€–›Rn–Q-—@W,ÅRm!¥íoç% tóKžö»ä}ÞóÓsʰWÁÖ6¾KÄÄ~o-}A'¾þϵÿ#N%¤aMÕ‹%ׯT%Ë0&ÉÒoõÍ”“|åk‰YFÆ"&1‘È—_ÿÕ˜ŸWÜjP¶ªmÍÍM())AZZbbbú‡pìÛuB¿pvzá.vvÓÏL´ìÕb‘è8‰¥óÅb™Bý°H¯×[L&úúúÐÚÚŠ²²2ˆÅbÄÆÆ")) µµµ‰$îbB)}Kfˆéɤ—ß::: ¿¸ž.áâIÖ¿4âùBáæ› õƒ´:ƒa"Úööv( Èd2dff"++ ÏnfV•íb¢|Šö81{š˜5²åDàÝæ»'®FGãzh(²7mœ ÆŸûöáš@€<‰d"ÒîînPšÐ¯{­bϸ8ù‚÷42‘á5á¤+w"—žý1ÄTää„Ë´ŸH${‰0ºO›=¡(F#xªFžT¤ڋÎú“•õìÌV’J' äâ¹”#ð÷µ“DFp¹ˆ8鿆³AA¸—›‹ÑÑQØl6X,Œè›³¶!ž*¶CþefÎ â\¼ˆ#n„…¬(-uqAÖ²e¸ºmªsrxž §³V KgìC5€Õ€±Géè©>ªU°t.Í%ÖN娉˜EñûÞX¾|\ÕÜ «ÕŠññq¼xØ-`¨ FÝy 5‡Áª½H»¨hƒ: )w¢Bze?I=+ž,ˆ8¸ÿ[wÆÓ³£¥¥Eg6›§Iú«­}O‹ß@gC¿|ÌíѰ?•Á1\‹æWÿfpuýž´Î\ú!匬@¼r¥º°°ðPOOÇ3±Ípözo W,…®p.ä·alÁ¨æ$¬ýE0?ÎAÿ½xxxg‰wpñš)qêËûxwøøøÌ©««S L‹z¼m'ÆjW`°t1ç1tùÁ¨ü¦îtŒô\„þþ!ÔKZMŒíåb'"„8rBËDÞÞ<=—.]Ú®R©À[úyŽ5p4­Iît>jE ¡­Øˆû`l@«L‚¼¼|<ÍÅÅcú¬ ÜœòòjŸ<ŸE³A®Ñh`·ÛŸ§äQ¬÷VA_üº%ÎP\ðDï-Ð6üÕ_ ¼nðÅ3Æ]¢»»jê\ ÔÔÔXyë>7[`oÙÃmOôä-@M:C{Ñçèn¯DUUUoTTÔû/Ç›çÌñyá ˜D"¹Æçoaþóãµ È`”¯Bo¡4Õ{ðw¯MMM½‘‘‘^kÐs"""¼rssG¨˜ƒ‰·2oiƒr?´2tuu9(eaaa+¦¥u+cï$x{GÖÄÅ•7$$¨•ÉɪôôšúÊwïnŒfì`\LL*K;½*ÚÚÚ&xðà„•)))ßñÚÌøIe¬¸”/›7K–@îá;4Ê]]qËٙόÞo ?E,JcCCC¿"ább1{†øc~)ŒNsr’œ_½Zž¨Èز¥:~ýú쟖.ô`ì#ZèGøÄÇħÄg“|2ù̇p#æòÚü Ä Öo`Ê0\IEND®B`‚eric-6.0.8/eric/icons/default/eolWindows.png0000644000175000017500000000300612342633754020054 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÜ 69ÃÆzébKGDùC»“IDAT…ÁhœwÀñ÷÷û|Ÿ{î.w¹»ä’4mÓ˜æ'•–é\ÚU*kÑÉ` ë°Â:Q‰L†¢Eÿ(›t¥•RÙÿqÑÖMpÛVuVêœKÖfe±ÙÚ¤Mh–¤¹»ä~æîž_o´LözñŸsÇ)@ΜᣜÅGPÜu8Ê' óèìïï7l £Q]¼xñÖõééɯÀ2-Ÿþ²²6z%˜ú)ÿåá£Ql -§ïGßžl"ñÌfÏÛ×ÓÙ™ˆø>7_{LüŽ~ÿúKˆçðÀiÝOбCÚS¨®¬ÈSûÅ<Ø Æ8 ßÿVe=Ôm ñle ,.är0îÀF1óÞ5¥ž^BXã.á.óðkÐ@pÊ÷G-o CL,™ŒP­²1=­ò¥ ¥9+®Žír¬¡áçíÕ†ücæj#ŸJG"ã÷vô´'ÂÁù…jÌ6sGŒF±=Hñ8áÊ ¥¹9Éæg>Æ•z‡~b¸ÇÚ2¸=±{ »yöàC©E%uÇ 6¶¯•J=7çåU“uZ |ÒÑhÇAù>ùyn¯¬P¢P\ê§b§t禬Åðö CÙmCmÚÒªÌíb@¡(¸®ÿ。“JmóDö!‚¥@YZ…kÊ·WÉ•J(ÀÓ,T²z8P&›ŽŽuH›êD‡5‚PTµæ²Zh,¹.—L-="£À^Ëóh©­-¯„*¤Q\³#žëƒê…-L­w©/Ç0©öÉH7Žn' 7ØðCÜ  Ñ Þ8Þ[5ïÜ÷XÈä9Ú![ÂTÇæ×gzû.ÅÒé|h›F0=½µX9Øí×·ªzÔјÂv’¢u–f¨PÒ¤á6ñE°þ»û&srò\HËÙ½_/4wÝûVûƒŒÝ³{tlG¯nÌÐ/þya5qöì_Ÿÿåå εÞx(1¸&£*¤ðƒ IU'P!¥ªO¨IZ -݇_¸xÏgõÜ·m÷þí¨þ8uðª!U7ÎÄÐ#;ÿýÝû¿ù#}àÚ/þŸjnÛ'n*SªYv“ò†ŽøåZSUsk—/ü±ð-†–ZvèãÉhlO—í¢ e5·æ‡¹åºf½Þõh×+{¿º“û,ü®î¾Uzwu[¾ U¹.árnD ë{ªå—NüŠÚå¹et‡ãì%™"ã D¼ÖÈÅš^_.[˜ß»âg_g¯N~#µi®)mSM]¨Ø;ñÍ>«t‘0àÎn^/ZfÇ£Ïv˜HdÌÄmMhx°œ÷Xš/áWýp ¾réÁΩ!¢$ÉÄaëÈ ãlt(‚¬CÍ@ÝšeÉ]¢¥»ÔD¯vj °Ûv¶KdÐÄö|U+{êÖ|Y­-®ƒmyc¹«=ÉJQd—ˆ=¤ƒ ¼:zqç:-Rp­%üØmmxT+uÞ{¿Âôb•k·‰°tú]‹(qb€Ó'èm"8"‚àH½ÚtÀÙ¤Éûb"â~AUnÕý¥ÈÛËÒöærD­JÕK/¯zãÍîÌA~æPäƒXôâDÁQÖA¤nu•¢7C‹ü³ ¬'Á˜ ñœS¼QÎ_šº:ñ·çnrWçÁã}²çñϺ7#úý#xÄDwƒSˆA‘GÈΡLó2¯2K‹ª!-Šÿ!"(¥ø°ð'MVFiãCä¼R´Èø†ª™>Û3 IEND®B`‚eric-6.0.8/eric/icons/default/preferences-orbit.png0000644000175000017500000000150112342633755021337 0ustar piotrpiotr‰PNG  IHDR(-S pHYs  šœtIMEÕ  IU>tEXtCommentCreated with The GIMPïd%n‰PLTEÀÀÀÀÀÀÀÀÀÀÀß'ð‰õ©ÀÀÀÀÀÀÀßâ%å,õ¨ö¶%ŸÀÀÀÀDÀÞîxô¥×" À°ÀÀÀÀÀÀ ·]%tÀÀÀÀÀºÀÞ ê.ìSðyó”YXJsT!qYA|]Gy_(h`@wfkk%Nn?mo#xIcy€U_]^ˆST›¹¾¿u*ÆÇÒ±!Ói!ÔÕLÞÞzßãäæçèUèvé´ðññòô»ôÌõùþÿÿÿÿ(ÿBÿ^ÿaÿÀÿÁÿØÿÚÿÛÿÜÿàÿáÿéÿìÿîÿðÿÿÿûôv=_uc]¶Ÿgt˜›´(HJem„³kdqL ØëòT'ߨ’‚Ä`s°€U”w@JiQ^|| D@ßÁ%¹¸0/-=7¬EÈÔÞ?<.)!=??‡Èç4”—°q ‰ÏÍÏ)0a`·õ ŽÉÌó„ÍdÔ•ÌÍ•x ^”7ÖQãGö$+2'›)fùBáIEND®B`‚eric-6.0.8/eric/icons/default/relayout.png0000644000175000017500000000252312342633755017572 0ustar piotrpiotr‰PNG  IHDRójœ pHYsvv}Õ‚ÌtIMEÜ 8EùsÞ¬PLTE€a I¶IÿÿÿnŠ˜„Ènrz–x‚nxˆnz|°nŒnhr’ºhnÈ®lnrxÎnÈ–nlÆÐrˆn„Ü‚nprÚ|nnÚrŒzâpxzêv悜pŒròÀrðˆ†r‚rr‚ˆ¼xržþnþú|v~ŒrŒ|°îtˆö’€¼ÿŠþ ’´rt~Št‚p„pt–˜žÂjlnvˆ¦ÄÐlnrtvxz€‚„ˆŠŒŽ’”–˜šœž ¤¨ª®°²´¶¸º¾ÆÈÊÌÎÐÖÚÜâäæêìîðòôöøüþþ þ þ þþþþþþIIþMMÿÿÿÿÿÿ ÿ""ÿ$$ÿ&&ÿ))ÿ++ÿ--ÿ//ÿ00ÿ22ÿ44ÿ99ÿ??ÿAAÿFFÿYYÿaaÿii(LXð‹tRNS #$&))00357;AIILMORXYZZ\cklmstz{}~‡Œ”›§©«­°±±µ·¸¸º»»¾ÀÁÂÊÍÑÑÓÕ××Ûââæææèëëìîïïððñòóóôôõõ÷÷ùûýýýýþþþþþþþþþb¦Œ–bKGD Lò–IDATmÁKkQà÷œóÍ™Ì$š¤i'ñR«âAtãÎ"þ€ ;]Hÿœ¸SZPJº+-ˆ¨`‚¢%©É8“´™2™Ìí³³ïó…óXX][n\‰ŽÆþ·oþíÇíO¯–$gC¯ûñ+Î(¹¹¬=zÕ0 «—îèÊ yåõ…İâ1€ÎMã-@@gæ=? ¥æ*'íûý/ ä¡Âí…É"ǃõ N%Ÿ/e2ý• Þ¿ëŽWÔ¬Å%23ÒÇÙ†øHLEñ͘(¤< •`âƒé©‰4©‰ZBÒšÅr“,°”î²ì­ÝËÙs?g|С-0Édf’ù~™|™ù†¡”b¥Ûø‘¸å©ö7£ÑðË5Åè`8–/ªÓ·n¦Oίk7++Å2+Á¯¾1z`ÝÚè±î'×ð—/¦É+Ðt–mÃ#Ø îô•ä‘?;tè±á}oŸøcÛÖ¶Dgw 2YS—æ0u5‡öÎ&”ó%pÔ†/ìƒeZ¸òû_Éb&»yöæçåÿìƒèž×F'·%ZUÍ‚ä^ðaCw3LË‚?â‡#p¸‘Ì£¦Q$žéjCò¯:÷Á¯ï}±³£q ¬šhëh/p`ç.§I@E31“ZÀÝy ÙŠƒ¹ù õMõÝ]‰ƒ¬ë¾²)Ã">tv4@µ)L†Å »âB¨¸U›B¥,L–AM7‘]0 R‘–†ÃËÂ÷î)uÅ¢V§šB`ضKáXÝB*WE¾f€Š ‚øD”…ô¢¹5 O$$ÄzÞߺ~çÀXŸª;Ìéó)dŠ*\†Ëý"’™y<ššCpD6/•¯QâÐñDRÀÍÀîE[œÜ¾3¿3©C¦fbêZ›âeœ¿žEDöC³\Ã^´Pó– S·“Vx¿UÓX†z—Àõ²/—)ª`}"LÇÅ™«´¯“‘)k¸ªAu\8 pDeÁ±±ª:GXŽ—À›zš'æ~LT5™RºŒ‚n¢hR(D„#ð°)çcáº&\Ç…$Ù F©Œ€Si:“Kr|ìãÝ—bû$¯‡Çs˜Î›Ê!¼7ÃÞíè\+Cð{!„ƒ Ád9ˆšf¡¦Ô`¨&xÇúvɉ¸q¶,g§¦¸[¨¡}ý*$Údx$‚Gð\G-²ÙBZYÅôt ÔBåÖ­™Ï*ËÞcjÔ=¨ây˜º…ëé æJ(x$ت¶´Öc®b” X†­Vì+>³gß²ìÞC)‘x9×ÒeäT«ýZÃÖydXšFäÁ±µÛ©ÁÛWÓ­“'ßý>ŸœÝÑl«•5Q?#>8‹ªK1«è  ^á)Í›å‹3{ÒÓCG»lŽŽ^ä¿øò‡dýÚijëýbÍÌÅ‚UV0{-­ß»0sŽäæv9ýÉò5™RúȾ}ûQqxdòæÄ©):8xtããİxD‹Çã=Š2¶Ù'ô–FcMñx¼wÿþý‘‡ÅÝ—Š—xžß¢iš£ëº#˲tüøñ Ë\ ¶mÃqX–|>wahh蔮뮪ªN"‘¸1<<üÍ²ðØØØxooï+–õR*•Ëå–=QWW!XÜ›Íf¿ëïïß½,ÜÓÓó4Ã0þÍ=/IR ¯¯ïSJ)G)…ëºXÛÚÚ~ûïãÅ’ããã¿,®ÿÞ}sù5áüIEND®B`‚eric-6.0.8/eric/icons/default/syntaxError.png0000644000175000017500000000145512342633755020271 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<ƒPLTEÿÿÿ76 * $$$!   FJ   F ---BAph"Jpa cIi X Vpi'FLX i‰/0N§bzÛ99¯'+%‡00WÙ,,0 S=è5pgÖ !) +.&1""W33]G:cjkI8mqu}KL~wpˆŽ““•™šŸª ««%&¬²³ ´¶ººÇÉÕÝÞ66ä[Uéïð ð ö8:ù34ø¸PtRNS ##)1334778==EEJQTU[]ccttvy~…•–¥¨®°´·¼ÁÇÍÍÕØßäçéííõúüýýýþþþ9¬xˆÀIDATÓc`&ÉÂ"@„œ3##¿Œ8\€]KITLQƒ .À¦kéæjªƒ$`âèmÄ ¶öM ÷²à€ ÙøWÇFÕù˜ñTÔœòj#òÔUÁ*8¹=²k+«ê Ü98!ZKãÃJrC =y¡fp¸$‡¥d8³BdmÓËË*ŠsìD ÚzA)©Y™Ê&}«¸˜èsiM°€‚$#‹±£½!3ƒ¼DÈÌ`H…E èúcÇCIEND®B`‚eric-6.0.8/eric/icons/default/preferences-autocompletion.png0000644000175000017500000000253612342633755023273 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<©PLTEÿÿÿmmmÿÿÿ€€€È±ÿ€QQÿf3___£££°°ãq9bbbY(###Ôž¥M!êu5­­­WWWæ¬.¼ª¡ír5ú†îw3&"ö”ÝÈ'''ãËëà7TTTcccè•ét2ÛÛÛé£+++m; ©†è{.J’kK """ÐÐÐáááìr1PPP'''ššš ¬_ Û†Íi(䨃îÞï xxx………o`SË©жJ·{Xës0HHH%%%êr0ó£«A ÅngggÆœó˜ ›8ä~Dw4ìGéuøÚ-ÿÓr>ö  «YË[$$$ñ© ÷Í÷»~~~å}Dù¼3éÅÒ°ûº7í†2ê~+ ûØCù²çyÊ^_.ës1ʨ1ûæù¾úÑ@@@ûŽýà–ës1û£þ²þÝqÏLës1]\\¥¥¥øË>ýî;BBB‚‚‚õŽ KKKÿ»¹Y ÿÆ"""ý’çhý°ÿÑÿÜþ°)ˆˆˆþÃ/úÌ3ÿàÿá"ÿé7 í~ów m^QÇPÿÀ¢¢¢ÿ¹ÿÐ"!!!666@#ZZZ˜˜˜×××áááé…"ës1îy-ðñq ò†,û­.ÿ ÿÃ/ÿÒUMÊ×2ËtRNS  "&'(*,-..//122346::;<=??ABBBCDDEGJJKLLLLMQQSTTUUWXY[\]_``bfgiioopprrwxz{||‚„…†‡Ž‘‘”™™œœ  ¡§§©©ª¬¬®²¹º»¼¼¾¿ÀÀÂÂÊÌÌÐÑÔÖÖ×ÙÚÚÚÛÞææèéêêëìîóóóõõõõ÷øøùûûûûüüüýýýþþþþe¬ÏpPIDATÓc`„›Æà žT̨H˜#™Q"57?ìÄLF&NiÛ¶}Ë…@†¨U9z»­º¾bnë@ pé_¹ò€Pצk»ÀÂÓ÷ë10ÖîÔ’Ì»Õlâ¹öR4P”}Ú©:†¬‡íŒ¼ª…±^Ýgf22Tl;ÙÀÀÈ0åQ #£ˆ‚’™iDÚé#}[Ì·³÷XoŠ¿¦Seÿ¢£wÍb€x'jÙîû·nß¹yïðÖ W– ù’Á¯«3'ÃÊÞ'ýøU]4ϳJé8'Í»X&ÌÈ-kÙxz%“±š0²0£ ŠKöžËŽsoÉ£3ŠêÆÏ:×1y±;ª0ƒ˜MýéÍ2Œ¨ÂŒ¬Š‰›.„3¢ 3r™Ì8=S˜‘¿àìAqLaFÅէ˰3Ö¬H’‹Sjƒ>|fIEND®B`‚eric-6.0.8/eric/icons/default/editToggleComment.png0000644000175000017500000000173112342633754021337 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs  šœtIMEÛ  k˃ÑPLTEÿÿÿ./0ÿ -ÿ 8'ÚNg¶ 5",L4K{â .FuÜ5¬+©BƒïA¸$@Œ,8š‹} $Y $Z 7¿‡­ë 1¶_ò2EzÔ5—0jÍ&¢Jd’Wu¿*«5©|¦õK˜öJ—ñHíGé VìÛUQ_v±&‚Uh‰ióÂÄÈÐJJS§Kï’Áì^K¨—ÒÿA“C´³ ,AÊÇixF­àKFlð!kì=–î>xÇH5HŸì^T·4³9ÿIÿMâMô?²Zâ^û Lð gÿW÷JæUæh÷Aë[û"kâ.rÒ8vÔ@›ùBöU¬ÿ\¬ÿj£ôoµÿ»g|½ ÐWWÖÜPPÞTRß à[[å ꣠쉆íZZ²†n¿ttRNS!!"((+1447CCDJKOQTTT[[\]```abbcddnwz{|ƒ„…‡‰––—™ŸŸ¥¨©­®±²¸¿ÁÁÂÅÆÎÑÒÒØØÙÚÚÝÝÝÞÞàááèëîïòõöüýþþþþþþþ;FKvbKGDˆHIDATÓc`!Aap*‘ìAþœn‘è¢ 2©~ ÉÑè¢ ½Æf=&h¢ÒÖÁ]>!Ý^r¨j½Û;óÛ:Š lQD¤<[Ó\òMEQDØŒZÌÕêmXPEÅ=bêÂ’jÂ]Á¢phd7U—–WTED‘| _¨_ Ä2ɲ–*•Vs‘|à˜®ã©Eñ˜"‡¤+H-ªà.ùÀ97ÑT5@>P-¶cæ2Dù 4eF–{ÄDm$¿}ÐÜ7sÊ´>dƒ}à›3k2#J8} Ü1uÒôx^$Qì ûc™â&h1 DA>Ð5àaàÖdÑ­RËt]nIEND®B`‚eric-6.0.8/eric/icons/default/projectViewer.png0000644000175000017500000000202312342633755020551 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<@PLTEÿÿÿ,,,000ffflllÃÃÃÆÆÆØØØÚÚÚgÁ"nÌ1o½3p½9‘ÿ>€Ò>“ÿA”ÿCzÁC•ÿFz½F{½H˜ÿJ}½J˜ÿL™ÿMÁM‰ÒO›ÿR„½R…½S†½[bk^½_ek_½e“Ìf¥ÿf«ÿhowh§ÿi¨ÿk™½kš½lqwl›½lªÿm«ÿn™Ìn½n¬ÿo—Ìp­ÿqqqq{†r|†sšÌt}†u~†u›Ìv~†v†w†w€†x€†xÌy°ÿ{·ÿ|žÌ|ŸÌ|¸ÿ Ìºÿ€¢Ì€·ÿ€»ÿ‚¢Ì‚£Ì‚¼ÿƒ·ÿ„¾ÿ…¤Ì…¿ÿ‡½ÿŠ§ÌŽ¨ÌŽ­Ò©ÌÇÿ’Èÿ’Êÿ“¯Ò“Ëÿ”¬Ì•Çÿ•Íÿ–Îÿ—®Ì˜Ïÿ™Ðÿœ°Ìž²ÌžÌÿŸ´ÌŸÇÿŸÑÿ¢µÌ¢Êÿ¢Ëÿ¤Ëÿ¤×ÿ¤Ùÿ¦Ûÿ§Üÿ¨Íÿ¨Øÿ¨Ýÿ©Þÿ«Üÿ«ßÿ¬Ðÿ­Ïÿ­áÿ®Ïÿ°Òÿ°×ÿ°Ùÿ²Òÿ²Öÿ³Óÿ³æÿµÔÿ¶×ÿ¸Úÿ¸äÿ¹åÿº×ÿºÙÿ¼Ùÿ½Úÿ¾ßÿÁàÿÁãÿÁêÿÂÜÿÂßÿÂâÿÃåÿÃèÿÄàÿÆìÿÇáÿÇçÿÈÈÈÈæÿÉæÿÊèÿÊêÿËìÿÍéÿÍëÿÎêÿÏíÿÖÖÖÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííøøøùùùÿÿÿÄÍtRNS!&M_`fj­²ÖÖñògH®'IDATÓe½JQFÏÜ{7»›5 !ؤ|;[ÑÞ7PÄÆÐAl-¬l|-¬,L,TBð/q³?ww-Âî†ø•‡oÎÌ€1B›ï²¢¦Ùû¦ ÆÿšwWV؛ĸ7Ìæh?šºŸ[Ý…û+à`;")VÚÁúÚê©Q´7¢ÉCúUºíeßÉ£8UÑÆu=ÚŸaê¥$Ûã»i¤K|Í| Ç­Nãñ8ÙJl¼[à¯Fg¥fK›QX^"¼¿-î4ëNfã$IP€ žz¡‘<ÌlXamF½þ`œey'•D;JI2dì©(Á¦æ8@þ’5'3X)­Gÿ +Iþt½6°A%¹ý÷¥€6șü>Xlñ’ÑKIEND®B`‚eric-6.0.8/eric/icons/default/yahoo.png0000644000175000017500000000043312342633755017043 0ustar piotrpiotr‰PNG  IHDRójœ TPLTECCCUZZZaeeempppy{{{…‡‡‡‘’’’žªìììòó’’ô‡‡õppõ{{öeeøNNøOOùCCÿFüZüzž_—Tý#+G'| Æ«é°JŽõÿ/b’¦hJ´õzaz¶Çóþ»øÊfóæ À,9 3žÝeÏþ€ÆÇý!¦‹·u¾Ë:•ïb4Ýe¦!k;˜¹ZHÇÊàž/ÔgHznY¤ÃgÀÌ”#dj@@ß ¿¦ö[§W^²lÈ×÷gìa)Z7Ô1co"dk¥i–ú³”ÑG°Ï•@2y *• S#-, 35ÒŽI&a—}Leú°R™œÝ:©öøµ)qŒ5\ÍÝ­ìLõú”ŸÓ”O‘ø0q*é%x<( ÌÍÉ`––À$ý³³³P*•ðz½PÍRí™ó•ÈRƒek'4ý{q­Š{2\q-û°®w;–4Ÿ’œÄ†0:1rss‘ŸŸÅéóX¸õòòò ¡PÆ !!•ÉZŽ ­¦á×!ú†ÛtWWH꣪ ýéh (ãà±_‡H$Baa!ÊÊÊ`×Öª®FQQŠ‹‹!‘Hàq̸Ak˜ñ,ŒÔñÆK“"ïWåGI/o›‡22¾Œ€ý[˜Íæp=M&#}ƒÓÄ9¨Õê𽀫!Çg°N„¤£è¾“rÏ>UqÐtƺ}ò©+^‚Ë!Ã0ð9Eô‘v„ñ9Ç\BöãÔ’G!ÿ!Á=PÉÛ¹êÑ´GY=RzÆJ/w<‡ë`Ï )§ÜÁ–s%ö<]oƒ{f/Z#gV]yÔÓuÝ)A¯üA’&[þŽ=ùOl%ñvÌ·D(Ö'è…cIK[®;î/¬Ä~?®;xå|̵DÖ?l¸º˶XÀÏ%hóÆÀ§âÁ.áÀ1Í¡•I1_4Á ãSr oÞh_Kü´¾÷QÝ|,{’á’ñaÆc¾ë9ªéï#-š6Ìà ði¥8øu‰Xh‹¼½–ø)M;&QT][ ù.Ú9PÛÒúE•û_žL)˜¸ÈUv¥Ñ…³8²æˆÝt_qúî=¬¡jnÓ`%¯½½<þXMñÖ˜ûm‹¥‰ÏÐ*«¯cˆk8÷̘ŽM—H"ÒˆGˆ'‰Lbñ*q8Ddû‰g‰]ÄÄCD GD~†TÚÌš#IEND®B`‚eric-6.0.8/eric/icons/default/preferences-search.png0000644000175000017500000000165712342633755021501 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<¤PLTEÿÿÿ.../// ;;;,,,777777???111CCCTTTuuuSSRUTS<62‹‹‹KKKPPPWWW BBBJJJQ;)rrr„{sŸ‘ƒ   !!!"""#$&&&----0'!6 888>>>AAAD GGGIIIK( N( RD9RRRTTTUUUX(YVT]]]_<"`-`?%dH0fbagREic`l4ooopVFtG!w8xDxxx{]C|A |ePƒƒƒ………‰‰‰ŠŠŠŽŽŽ`4“““šb9šc:¤rK©yU±™‚¸¸¸ÀÀÀg¹FtRNS #'.3CYf‚„•›ª¬®µµ¸¹ÀÁÇÍÍÍÏÐÒ×Üßéêðòõõ÷÷øùùùúûûüüýýýþþþþþþþþaÚ´”+IDATµÁÏR‚@à» 躘„Šb9Ú4Õ%/šéÐtê‘}„êÒTdS˜‚¤K.ÿ7¹õõ}ð0T°Ù§2Öé(©„ •æØiækŵ< Ȱº&Š‘Ñê0™”™ÀÚ g]©!¾½˜«‡çsª‹0€9¸9cÈßãa Fìèä]l€a³gRdýšó¤+9³ŽõëÚ2IÀm7>^HÇ6=áV÷Ò}Y´ÈZzy3±Õ‡7~:„Ò™5Ì=Sêô{cò5£”Ða&MT¬2w+ÝÚÆê•!.q½ìy,\ïÕßl ¹_®Úé£"áÔ âˆ`)âe ¢å¶ˆp‹p2½[ûìè³`2½ÿ P™ÑHy´… e†öÍ£ *~ÁðW~2àƒ9Û…ŽIEND®B`‚eric-6.0.8/eric/icons/default/drawLine.png0000644000175000017500000000061712342633754017474 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOàtEXtSoftwarewww.inkscape.org›î<xPLTEÿÿÿ14614614614625725836847958:59;7:<8;=9<>:>@;?A=AC>BE@DFBFICHJEJM14625725836847958:69;7;=8<>:=@;?A=@C?BE@DGBFIDHKFKNIMP`%tRNSpqrstuvwxxzz{||}~€‚ <ìX|IDATÓmÑ7Â0AsN œe›ÿÿ÷§-§]B°ãþet¿r¼×ý]Óy}@—˜Ît1í “q+è`_@{cÝ Úic'ÐVi3‚6Ré´Rõ ²--hAo2JY ú¦”V ¯GKœñhArœÓ?ð„ã|ÒßûIEND®B`‚eric-6.0.8/eric/icons/default/changesetSignList.png0000644000175000017500000000241312342633754021341 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs × ×B(›xtIMEÛ/›7­c¦PLTENNNtØ222}}}´³´_^_nÑÂUºººifQÏËÏ^[[vÞtØ———^¹ÜÜÜ‰ŠŠ×ÔÖާ¨¨âààvß”ÕÓÕœioe›œ‡…†°°°Y’ÍÊÍtØmÎÀÀÀÙרàÝáëè躺ºtÙ˜¯©qšÈz§Øš¼â`¼¼»»¦¸¡£££æã䘹ߵ´´æäåsppÌÊËp›°¼»»wÙpÕtÙjÊÇÆÆ¬©© yÚÙ××ÜÚÛ„€€»¸¸tÆW’ÏvÚº¸·»¹ºÙØÙ!tÄ‚ÛrØÜÚÛ‚Û¢ŸŸ¨¥¤ÍÌÌrʶ±±½¹º+~͉ˆ¡œ¬¦¦ÇÄÄÊÇÇhÊhÐlÎlÐxÕxÑzÕwÔ}Ò }Ò$|Î$ƒÙ%}Î%€Ó&{Î'zÏ(}Î(~Î)~Ï*{Ì,x¹,~Ô-€Ï-…×-†×.c”/€Ï0‰Ú2w¿7„Ñ8ƒÍ<ˆÑ<Ù=Ù>†Î?€¼@‡ÎA‡ÏEŠÐE‘ÚGˆÎIŒÐL‚´NÑP‘ÓQÐT’ÒV“ÓV›Ý[Ý_—Ò`™Õa˜Óf›Ôi£ài¥àjÕj¤Øn¤Øo Öo¡Õr¢Ùu£×z¦×z§Ø|­Ù}¨Ù}¨ÚªÚ‚­Ü†®Ûˆ±Ü‘Œ‹“ŒŒ“”ŒŒ•¸á˜‘‘™¼âš¼â˜˜¢œœ£žž¥žž¦¢¢¸Î亷·½ººÉÚëÑÏÎõîè÷ïèøïèúõðúõñÿûøÿü÷ÿÿÿ´›¦²€tRNS #$$&/1459;<<=>BCFIMOPRTTVV``cnpssyƒƒŠŠŠŒ™šš›Ÿ ¤¯µÀÄÄÅÎÏÓÔÖØÙÜæçèéêïðññöö÷÷øùûýþþþþþ „HœbKGDá_ϦRIDATÓcH®ñdÀ"N•©`¶¨½âE˜%ãT*qŸ³õÆX„5*.…a³4ödžŸ‚¢¢”Œ„'BØér¥ ;˜©- $„U•”Õts.zAèé0ˆ+(J0º2ñ2ŸNc Šj)ú‡p;X22HJðÔÝ4g`бÖò[|àü¹=«Ôx@zY“®G ØÛÆd9väÐþ£sœ!fz\+²’`Yqxßî[·lÚš¯ –/¹àÂÀ0eïû÷ï?xðàøÚ ˆòÐÑ ý›×¯[½rÙÒEó–dB„õ«s9¦®¹zîîš\õRT©(Cûü¹³&ôMœ4­§«*,–®)ÐØ°óö- ¸s°!fަ3››Z;{{;Z›šÜ‘‚̶°mú‚åËÎh‰çBJ“ìÙ·oÛÐ IJ¾)ÅqnÌ ÿärlb«þIEND®B`‚eric-6.0.8/eric/icons/default/preferences-application.png0000644000175000017500000000261512342633755022532 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs¯¯^‘tIME× ) fü6œbKGDÿÿÿ ½§“IDAT8ËÕ•ý•GÇ?3ÏÜ÷Ý\Àíåe±µ(]ººH\‰ •5@ˆ]¨4 ¦âM4þ¢&’`5iŒIšÔ61jQ£?4*±¦¾µ©ml–Baº°…}»»{ßžû<÷™™ã{1ìŸà$ß9“Ì™ïœ9'ç;ðÿ6ÔÓ?=–ýùïþ¤+)C`Ú :”Ö¥ € ˆ÷xïñÖáœÅY‡³-\’à¬åñýÛ½úÂO×#O^¡ÐJ¡”B)-´é@‰ "ˆxÄy¼w‹¶Mì­Å9‹O,R¯X³P …Œ¦•XHçAîz´c MŒ÷ˆ÷ˆw‹‘;‡8‡8 ÞqûÊ(s·RÚ[ÇÞõ9W:ÄÚ¶“Cìž”†AœÃß;>>ñLMЬ[L®ˆ… )­Z¿]¾;ýíY‘ΦÐé4õf‚ˆ¥PÞâ’oc“%¢guŠ·«5 ¶ÉñP:E`Ò(¥A-^‡÷¤!Žšd tE¥R£Ç8çÁÃäØ8OØÌ#»¢V«ó“çsêìu´sëKÂàƒŽ¤V&ªL-ÌÐ\˜cëZÃ3>NÁG,TbâØSì,¢‚I$\#ãê íÜB¡ÐÁc_ý}ó:Ë—eÑÒj°¦X¦{ÙMTºˆJu¢L‚ ÿ¹Á…‘‹ìï_‰‘„Zäq¢X–Í25YC§ólܰ–jµJ¥ZaMi9I“ ,jðk?“T&…ˆ[ÌvB¥ (Esî=†>¼‚m[xæØëŒ]¹AGàÈ¥5WÞáŸßÄæ>°ÁüBÄÙׇ1ÎZ”V 4 óÖ‚ò€BçKœ¼X¥¿Æ7ý_ÿÑ8ãó-Öuw±} ‹-ý½Œ\fv¦L©t •:g^y ãm‚×íVP‹_²VõPóë¿M&çøÅ“Ÿå‰Ã§èÐvn\ÍèÕ« _b®3ú—óܘnAjÁ}ŸØ÷”ÉÀd R‹Ð&…4®1}ó&µò$u.\'‰C¾õøÒÉ,>sŠˆ׿ v\›ï¤©º0Æ`šåwIRZ´A™ a$T«-S$³| d\B¹!üóìßà½Û³œ|õ"Ÿìk°"Ò¼'Ã[áJDå1Aî}&h7„ଥ<1M£ÞÀ{Atj± Z³« *V8vì4ûÙÌ—vÜä¹£×™nåyw\VqîrÓ\˜#H@E1³Sóx(mPhDUìè$©ÎÒœŸ!g<…´´áɧíê#Ýå¥Ó/±{hÿ87ALáwrªÌΡ:Ÿ{¨ƒ«—àÂÔzBµüPÿẔz>%m=[‚ƒÊ‘#GäžõrèÐ!éíí]²ŸÏ oý ©]ü ”ßX%ßþbQº7lußàsä×n]zÎ,ùöìÞÝ›ÉfçœÙ20°í?o¼ùʉ'®±D\•ÚÖãKGž´CÝ=]TÂ/¦'Uÿ¾ïvesâ¨E¥\Áù;ù ØÛŸÝ»©¯wk†úÆø¸=yþ{Åî¾PDþ§ÇˆU§ÌÖì‰ýßùJãé{7d ®j£ ´a0Ž­‹: 2™hf¶…Í$ŠZ.zõÔoÇJ+ ëÞ¹üö­çó³™ì˜mÆ6jF­¨µ¢0Š£0Œ¢Øªpd¬v~êÚìèšœÝøò¿äðáÂ…¸^îIEND®B`‚eric-6.0.8/eric/icons/default/preferences-cooperation.png0000644000175000017500000000233512342633755022550 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYsvv}Õ‚ÌtIMEÚ/`#ÃbKGDÿÿÿ ½§“]IDAT8ËÝT[LUþÎÌÎÞ—ÙáRÜE,Ðmð‚Ùbmµ){‰‘¤ñÁˆŠÆDÅÆ'Ð'4òbÒãŠÄKÔÔ‰m£UjˆP%M-+”ÛréÂ.¸Ëî²—ÙËŒÿ Ë1½<{’/sNΜï|ÿ÷ÿÿa¸³Ál…¹JÈ’·:ÀnCx„ðjkkë}MMMN›ÍƘ:55•½xñâäøøø7´ÿý›Íf¯Õjíokkó`0ÔX,ÆTUÕ÷F£*Š"‹D"èîîÎÎÌÌ<å÷û/¢¹)qoGGÇ+ÍÍÍ<Çqj2™,nm­ASOØìì,úúú¾m£íÔnb”õ÷ôô<]RR¢f2¶›ìVk€®®®«ÑhôÐvR¶²Ãóïvvv¶Sˆêææ&“eDŽt: m®}µuF›§¸±E޳"™ˆ!—‘¡Eçñxª†††$ŠâC·©¦¦æm—ËòÝ\¥‚ÕˆŒ*/´=ŽÚª2ô|vÑЂ½$IªÛí~=|h(ØñNKK ‚Á îNåa´8¶¶Ó/¥2ÜßЈÓ7 ÜiÕ/Ê+ ²¹,(übÎêëëÍD|D#®$µ >ù*3Õ$¡½ý5Ô׺õ?9ŽaqaûöÕQø{LH%SEbÊ‘î55b‰à ‡ÃÓ)œ|ö| ®heV‹ žƒB wÚ£(*Ì6Qt}}>ß_tɆ¶u”ÓÊR#%ňÇãôs®pH)bçz»Ô¶ÖyL-¡ æ¢%Zl.Êúé¥åe¬­…`wºñÄуxJ F*vr¹òù¼þÍf³©JÞ|¯ñLšÂØzùlF#žÔˆy“Åö’ÕYaå˜ ¬âçÑiŒMPë*ƒåðVϬÃh¨)× ÓTrºz²â܃X]šGhîOȉøV^ÓçÚE!9•˜ÍSvyÁ¨µ+–papŒã©F3¸21žK¿ãäïãÓþ„#QJRŠêZ†¼ÂÒ¿n“ª&»¤8+ª¿Ð’—%| Ýx$'§U³­„ f+TƒÑYŠy¿©éßÈ?ê®|gFΣïc‡jÄñÇ1}m””ëyPåÕÌî¬LÄ×fwÖÿ@áÑ¡u’{ÿµ´ú^• •vîï„É**µ^µ¦ñIÅ&UJ»ß » ×Èý·{œã`  0;$ØK]ªxW¹fXÛÜZûidOÝl·4¼^¯Dïí=ÃÃÃ[‡9ŽºOÔÞ(ZR…Ív˜lA$R',ö2XK+Y|m)81ðu[¯öÃÒøe]±áùçZõM^?;7ﯖ3 ,b9¾“È °:ÊÀ¨£“‚FL­n.)§ IÇ|›‘•/¯žûàÌ¢ª¼»ö˜çð©^£èÞ/§’ÈçÒ‘D8øËÊõ‘8Á8©Èé{­»¶¶¹®¾çPU~¦¯6ƒ¼gÞâÉS–LíljmkïèZ½ÿÀÁÊ@e6-ÿÒ…‹ôööõO˜8i㉓§ÎÅð20ðï]5köœ•sçÍß°ïØñ f" KE­#—Ï\¶býö»÷={>ÕVâBG'$à¨u¸…GÁÅ‹)ièavÈq±w¾q0ᨋnIÕ˜Âq]ÉWÝlKl.aæ¶Bv·•,7 z“žñ†™åIEND®B`‚eric-6.0.8/eric/icons/default/grayscale.png0000644000175000017500000000042112342633755017673 0ustar piotrpiotr‰PNG  IHDR6šq0PLTE€À€ÿ000XXX€€€€€€  ¤®²ÃÀÀÀÀÿÿª…ËÓtRNS@æØfIDATÓc`@Œi`a¿¸÷òŸÑC»÷ÝüÇzP6Hø] „ ~êxÌ ‡<„°AÂ~Ïœ±AÂï2œ9s€ñ±"Ć [PðÝ»¬wÕïd€Zx¾{¶îù¾WP6Hx5ˆÍp,¼Â ƒÕ30‚…_AØ`aˆzF°0D=#Xª, e ‚˜ èeçŸ.…IEND®B`‚eric-6.0.8/eric/icons/default/projectSourcesJavaScript.png0000644000175000017500000000255312342633755022732 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÜ $wó'¡iTXtCommentCreated with GIMPd.ebKGDÿÿÿ ½§“ÏIDAT8Ëu•_ˆGÆï|ó³›?›ÝþI²HÛØÆ6…@½-X‰‰E¥T0H/rQ½iAüSJÁ^HÁ+Á[‹E¬ÅªˆBT¼PK 6´Ù¦!YÙÀîæœ³çû¾™÷}¼8›‚ÎðÎ3óòðÌ;ðÌŒ<þô…{?²Û÷Ž>Î-5ùH“³7¹U“[Rn­ÉK MnÈ£1ÑutÛ;ôýE^‰Zéå{Û£æ××?oÿâøœÿôÐöÞÉ%šñM;"·còhDÊcšvDÊk3ÑõøöMeèðRˆ:P‡&8—ï:x%Ÿ±å¯Ü;µçfÔ$hlSN('RÛ@ßã·¦1(3 ßÇš¹ qjs÷¼œ]žb{ë;?àÎÇ>Êé—¾ɸò“ŸY 5¦œpwÜZÝ’ÌXØQ ñd¸‚2ŸSë@D€-·L6.ëâ§žäÖ¿78ýÃïq×ÙG&»ÔnÎ0ïp¹<*5œä‹ÛDJÔ®£ý0¥ÌfÐf|ö–ÖŽðçsçpâé§è÷fTƒZzJ?0¸/„#7p[Tî “)¥FÇ×9ðÀ ¨ryéy»ï+O±wc•J³v„¢À#(tÃ`]­t^È%œH" "Á|6¥N'䔸äÏʱÇÕ¿üÍþó7¸úêotÿ…ó¶þé3¤6såå_âfôî5BUa5‚\j!R"å†a>§›L•ÉôÎïþÀÛ¯ÿžë/ÿŠ~w¢¿>ûM®_z“ÕS'¹úêo¹öÊkâð!«^å ª‚*ðÙsŸyücÿ|ëÃ*{3K2rJ$ŒØ›“ªËF#k,]§Ú#Š XÆrC "©Jæ ò|6Kóé„df0(0 /¹mÇ>*6jQ›‘„öóDPB"¾y2ÅÑ¡Gã1® 0L¶¨1$`·?0!„®ý9Â2H¤M‹‹Ýê ¹Ôð„©*„BE0€¤~±‘z¤žP¯¯ àîu<¦ÙX=ôÎê¡Ã_¸s¨«çƒ5’å5û!K–ö×)ÜRÈš÷ã6G–kØüàô¯c«× Ÿ¸÷á奎º>ÑÂhñ/Ü>÷ÿozŸ$CP ¶ü»ÊsÿŒaeR¿÷'IEND®B`‚eric-6.0.8/eric/icons/default/toolbarsConfigure.png0000644000175000017500000000151312342633755021413 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ»»»AAAoooQQQddd\\\aaapppvvvxxx444~~~hhhŒŒŒ»»»»»»ŒŒŒˆˆˆ›››ªªª¶¶¶ºººÇÇÇÏÏÏÑÑÑ‚ƒƒŒŒŒŽ”•••••———™™™›››œœœžžžžžŸ¥¥¥§§§¨¨©©ª®ª«¯«««­­­¯¯°°°°²²²¹¹¹ººº»»»¼¼¼½½½¾¾¾ÀÀÀÀÀÁÁÁÁÂÂÃÃÃÃÄÄÄÅÅÅÇÇÈÈÈÈÍÍÍÎÎÎÐÐÐÒÒÒÔÔÔØØØØØÛÙÙÛÝÝÝÝÝÞßßßâââããäããæääæääçææéççéççêèèèééêééëééìêêêêêëêêìëëììììììîíííííîííïîîîîîðïïðïïñððñññòññóòòóòòôôôõôôöõõõõõö÷÷÷÷÷øøøøùùùúúúúúûüüüýýý´·Š+,tRNS "#+,3=FFNPQRRSSSSSSU‚¿ÅÞßæçûûûûûûû›ÌYöIDATÓc` !PrÆJ Ša±±±qqñÈ \‘Á9!¡<%!!! ’@À™Á955Ù655 2A ÒHß/(œƒ òb ­<òóÂ…EÕÙEEÅP`a^RRbËà\V–aWöÞ‘žz Ε`PUf! >Ö: Îuuµu`P__ïæ›ÜªkÃàÜØ˜ëÐØØ^®ÑÆ&QN ŠY-pàïd_ZÛœ­ˆìySçè Gˆç@B=J[#ÌÄÕBµ¤1DET5¥0DUÜ5$1ƒ]ŽAYE€‰…ƒ‹GA^VLFˆŸ—›“•™rdG¬IEND®B`‚eric-6.0.8/eric/icons/default/preferences-exporters.png0000644000175000017500000000163312342633755022261 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<’PLTEÿÿÿ~~~%%&‚‚‚„„„„„„gggggg‡‡‡ˆˆˆÚÚÚ„„„„„„¸¸¸‚‚‚~~~òòò¥¥¤öööÄÄÅÇÇÆðððôôôÉÊÉÊÊÉ¥¥¥¦¦¦©©©¬¬¬­­­­®®°°°²²²³³³µµµ···¸¸¸¹¹¹»»»¼¼¼½½½¿¿¿ÀÁÁÔÔÔÖÖÖ×××××Ø×Ø×ØØØÜÜÜààààááâââããããäåååååææåæçææææçèçèèèééèéêéêêêëëëìììíííîîîîîîïïïïïïððððððññññññòòòòòòóóóóóóôôôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøùùùúúúûûûüüûüüüýýýþþþÿÿÿt7‡>tRNS "#$+,369;=?FIOPRSSUVWghituyz€ª«ÅÆÐÐÐÑÒØÛåèëìñòööøø» g1IDATÁËjSa…áw­õ•Ít¢c)"Ž:r$^^©N:òœX¢‰ “›ãþ·>ºX­€ê^9¶‘$ x»ŠÄ–dKb~=2@‘X²-ý>]t&–’¤*G_ŸÆJ%U©ÊÑÕÑÝzéÎâ¤'Ó›íòå˜ÑB^'qlË–\ ÛqÅxÓ?(œ$‘€‹úSØv$ôiÓ÷}{xþn»þZر$üLðqsþþvÿ#Û#ÔnžÖýg(l !òïçbw–$âð÷þ¯õ @ƒ8|»=ÙÍ—F ËÕóï³i($ˆv}|9›(°ßMfÓ=xø0Œ§“= “{ØÞ4á8ŽËå¾ ýІ6´ÿ¿âcîQ=IEND®B`‚eric-6.0.8/eric/icons/default/back.png0000644000175000017500000000201412342633754016620 0ustar piotrpiotr‰PNG  IHDRójœ pHYs „ „ªâcytIME× 4$z,IPLTE3a6h*S%F-Y+Q1_*N1^/R5a8k4U@u9Q"An&Gy(Iy.Pƒ0S†6W‰7XŠ8ZŽ:c ;W€;^‘<_“>a•Ac•Ea‹EižFk Gl¡Mq§Np¢OtªOy˜PpŸQm˜Qv¬Rw­Rx®Vv¤W}´Y¶Z{­Z}²Z€¶[y¤\¸^„º_„»`†¼b‡½c{Ÿd‰½d‰¿eƒ®gŒÂhÃjƒ¨jÄjÅkÅl‹·nеn‘Ão¸o”Ép”Ép”Êq‰®qНq¾q’Ár—Ër—Ìs•Åt˜Íu•Ãu˜Ìv—ÆvšÏw¶w—Åy³zžÒ|–½| Ô}”¶™Á€›Ã€œÅ€¤Ø¥Ø‚™¼„ Ç†žÁ‡œ»‡ŸÃ‡¡Ç‡£Ëˆ£Ëˆ«Þ‰¥ÍŠ¢ÆŠ¥Í‹¤ÈŒ¯â¢Â¥ÉŽ£ÃŽ§Ë§Ì©Í‘§Ç‘ªÎ”ªÊ”ªË–¬Í–­Î—­Î˜®Ï™­Ì™¯Ðž²ÐŸ³Ò µÓ¡µÔª½Ùª¾Ú«¾Ú¶Çâ¹ËæÁÒìÿÿÿÓhž3tRNS "%6:FIXev‚‰‰”˜›°°³¹ÂÉÉÖ×Ýçèðóúüýþü‰íäbKGDÂýo¾Ô IDATÓc` «Êa ²JêÏOÀåSÉ8pÐ]TTgêþýû]Q9e 7ïÙ»oŸ;3 LTP=sÛŽ»vï¶±spvóV†ˆŠëÖ¬Z·aÓÖíÛ·nÙ¸nÅ\/ ·BPÓ”Ys–¬\³výÚÕËæÍšàÐ /,oî›4mö‚ÅK/œ^—`æ×ðHÌ.©néêïé¨-ÊJŽ ´Â%kä—–[\VQQZj ±RLÛ/:%§¸²¾­½¡"?9Ìê@^EŸ¤¼²ÆÞ‰Æ¦–VîJ0‡3JèÅVuNži‚îy!µàî‹Ì0‚ŠCÊ u¹9–àÑŠ÷Ä <ÒòdE/RY³v÷IEND®B`‚eric-6.0.8/eric/icons/default/rss22.png0000644000175000017500000000167212342633755016705 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYs  šœ\IDAT¥ÁMˆ]gàçýι÷¦3é˜hµ?¤)…¨) Rqí^ .‘V–Ò…PZ,èÆ…›®Å…«  ¦ Z(ÑÚJbíÄ6ÒIšL2™¿sï=ßë½™E¨‹éó„™|Z¹räу»[9ˆa ûppTrRNŽ^ýÍf<£F>­l|â{_Êecõ˜¬Åmªÿ&{²”Ìü7é&Ï¿ôâ3¿nWîX¾óÃ|²=öЩr瑽}‰"—>ú`®¾fyyùåöÀ¥sƒü§c1lÃhA¤}É 6Þ¼ø×»ûÕsÃvg{³ÚºRŒoˆbßÙT1Þ.e²mL„¬Lw˜´>˜P##&¢Ý™ z&»”ÖE&;#Ñ–‘¨µ†é.Mq›°'nI$ÒíJCí•©hÍ%úމ=@A¸%H$**ÒLÐ.H1m·«˜›vÜõ0÷}•í5®þƒ­ ô»HÒ-i¦¡²‘ëçå•·ìD[†"ûÝpíßÜŠ{>I3BÐïrù oýœeD³Hb2æÆ;l¬qu•i¥ ¥­¹~,×ÿÅŸŸåo?âȽÿ8÷~–{>Ï¡“¼ö,僚Æö%¦=ÓdÜ3uSÆP-MtSQÌEP°pˆ<Ê%VË¿Æ_¾IÝá‘o0(Œ/P:š)MÏ ´A„¹ÖLFÐ'ç±çÈÊæyÎþ˜w~Ê Yþ!û¯|•ñ&S·TTDÈR̵f2š)—Ïðò·X8ÄÉ/±ü}†¸ø ÖçîÏqôaÞÅM‰Š‚ÆL Ìs\~•ó¿äìOøÓWØ\áÁ¯sÇaÞÿÍ"w¢Eƒ  Лй Ž>Â_âS/°}·Æâý,=À櫞   öJ¨Q̵抙`ñ8K÷ÑeÀä Í[kÔŽhý_%̵ÙÇ ³%WO‹ß}™ÉEºë\ƒ¿—«g¨cÎ>ÅÆTT$*’D6C5#G­lo¤î ¥K–Žœn½ñîihG\~õ×iPðæ‹TÔE*BºöxvÝ¥µ¾×µ7ι¶tøúú·»o·¥c‚b¦ üoiO¥¦œt×¶·»®¯X3¿ÿŒöC'7Fe*ìCmå¸×õ+Öûƒé_}`\ü–©žIEND®B`‚eric-6.0.8/eric/icons/default/documentFind.png0000644000175000017500000000221212342633754020337 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEÜ &u¥9Ÿ!iTXtCommentCreated with The GIMPm°—1PLTE  !!! 999………†††&&&‹‹‹Œ’’’444 71-2-)332CCCîîîðððE6*FFFjjj@<:kkkoZGIIIÒÒÒ """%***+++,,,.,,.../#///0#000666765;;;=1)>" >>>@@?A%A=;DDDE:4GGGH?9H@:I:.JJJMIEMKGNHENKHOKJP>3P?4QQQR3RSSS4TTTVRQVVVWSP[[[\[[]\\]]]^\[_\[b?!bTEddde>j;jjjjkkllllmlmK/mmmoonpBp[Hssstttv:vvvw< yyyzzz{{{P,€Q-mOŽkKŽŽŽ“b<–fB˜™™™™™   ®®®³´´´´´ÄÄÄËÌÌÏÏÏÑÑÑÒÒÓÓÓÓÕÕÕÖÖÖØØØÚÛÛÛÛÛÝÝÝàààêêêìììîîîðððññññòòòòòòóóóóóôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøøùùùùùùúúúúúúûûûûûüüüýýýþþþÿÿÿ±AzËî~/»Ú;ÚRÍŸº¡¿=ê'£;>Z{OS-9`2î…¦¥Ny¸Ý’¹ÉÛÜcQAàEª4TTD„Ú–5QDdU-}–† ˆ°¼v¾~µª- ц««<ÞÍæµò—eáîš³óeM•5_z9yóÝ嵯ߧ'°44A¿NgކñxWð¿)O~ÝÃkðJIEND®B`‚eric-6.0.8/eric/icons/default/stopLoading.png0000644000175000017500000000253512342633755020214 0ustar piotrpiotr‰PNG  IHDRÄ´l;$IDAT8Ë­•[hTGÇÿs.{=»Ù$Fúac/©šX$D‹×ú"¡ê*¡¥y( |¡D_ÅÚÆ¥DŠEèE-Xìƒéƒ©IÔ’ìæ²Ä`n›dïgΙ~³ÑÕÖúÖÃ9Ì™ùÍÿûÏ7ß0!ÞöÌMMa!‘`œs°}r´¦i𢴢â­sµw´´´(á[·‚k8?°Ì0«VyÝÁ â®¬Tô²2ÅL$ììä¤=?4”z>5H&oŽîÛ7ÑÓÓc¿Îa¯+nmmeë×CïƉšÝ»?:ò””($‘1R Ea‚saårÈ$ÖèñØíÛ×f2_'Ž_¹rE¼¡˜ J  mp»NVïÙs¤jïÞjŸa¨äD>OØ–A ÔtÛÖVlÝZ͹y̼{WˆD®¶^P®ž9sŒ_¼XµÎá8YûþžBÛÞ«óWT¨"™„õ²-.ß\~§RPEóùªªµø¸ž|Ø}är-477/YÑáñ„ÂLœ\»}ûñê;kJW†TEú¤ª°3ˆt$· Ö¢”ÒRp›ÔoјÅé)>ÑÛöövXâjg:—óQnæ†N›šjŒ²rº(sõjè¡•:$œšjøà©î5k º\óóp9ZÅúõµÁúú’%™°S؇W65…|RU¤’`.'œuup74À³i´PÌ4¡ÈÓØXèó7o…;\ Eú>;§®«ËC’UÜ}y”sMÑÅA‰°::ÄÌè°Lú¥P_x¨RíHÝü^ähö¸£6Ù ÓÖ.¯=wv¤XÝd5úËíNLüòklÂci¨r©ð²É K§K&¿`Koù" ˆ;!ú©TJhŽk—êÏîèèoúööv¶ÐÕUçPÍOÃql£Æ–,Šœ …šÜX9^û‚öeÍç±´ÕÍ-ý’·­mèÂ… â?oùœ:uŠÍwuÕ0;wÜáÖŽû*üÝ"pz<רzräÉŽùç +»ùÖÌÚßmmÑóçÏ‹·^Mÿçeú7à[¹»¤ßÍIEND®B`‚eric-6.0.8/eric/icons/default/updateRemote.png0000644000175000017500000000247712342633755020374 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYsvv}Õ‚ÌtIMEÞ !·Êé_bKGDÿÿÿ ½§“ÌIDAT8˵UkP”e>\䢃›be˜V… aš-•N аˆ.&â‚·×…¸-¬@Œ ²¨ˆÀ”·4/P^B¥!*ÆA tŸÎ÷Q:€6ÕL?žy¿ïývŸsÎó>ç¼€þ<öCx™|”Hq¼ü´ˆ:wVÑý]Õ¤+(§Þä,j ‰¤\9ÙŒüŸ´Vúxb&{/VE}»k m=„^<>¸¢n¼:¢G'Áéï ñt{Õ:ÊX¾’ž`Lå`u§.Qç(bþ‘±"†}’KºÝ8‘ìïáˆÊzÒÉ×ÓÅ5atùÌ5Bbª@5‚˜#6|Q3”á-¼0¶¼oýÈý›ªLxKAE‹£•B¦f\ê„?aޝ/Ò·¸°¦`‰ ¿ Cþþä( #æRÆr)·›®ºî AÈ@™F`íà+#øø“ŽŸu³Dpî‚ YÎT túàäóKBR–.uâ5ù°÷/Â,Y^ PŒuÚ_ÊAB¶ï8N"dÅ*º¿…S@hí"QŠë„ŸnÓpbvÁ—ê†øêÁ#¬ õÛPyú ö2/w x(J1mÑ6C;Ÿ|ÎÚ%éÈÌ#Ô!&Tøc?áòuÑ)äèÌ/5Nβ<Ô}ƒœ}§D|Þp~À%0–žé†s—Γ0qËöI èj&f{ü[‚°Ï"ö×èë fŽAn±f-S#£¼ªâzl*>Œ¬Š£¾™xú(c;éÒñÑ›ôºC"õD>p¬Ý0¤ùʵC+7Õn‘Ø?Fcá0i`±l"–É%°{?5ZDçV‹PÕÚ.LYùÍ kÿ—Íg‡ÚT64O&% ¾ÃäMG·´tuη•YpðJ‚³o Þ^“Èœ}WïC˜º [«á¬¾ï죂ÓR%<ƒ³›YÑ’ذ3&s†`ʺa}õOqUÌuñQB– \µ !©I¯ÂúL-êý¼Vs€jm*ѹ¥ Ú¸+`/•e1‘–ý,­¨£™ì+M)=Å3ÅŒ]¡ÿàð^š7ÿ¤ûª4øÅïD jV§0Ñf-V(«°$ªó‚¶ÁÁ;Ön‘°p|·}…Ü µx/U76Qbí âC—2¹ÛÏš[ú!ñ‹³§Z=3óMËòl,.Ĉ=X«…÷Ç5XS…w%X ßK'o„'š»ÑÜNßñ Ò²E³™<¢î$}ÀÞv~ …ñ”9¢.¯¸HR§¿îYJ’Cž~ÁǸ¥Qܳ÷ ‡2{¼h­ö>±1z/üL-L^ÉVËTeÐÖzæ°yldnm ¬ÓíÍÛ݃2þÙDæŸE”æ<6ä…Wd Þò²Çe÷= wš‘àj7Ýbò³<£p7–1±É¨A¯?v²Ÿ´©å û;Š­Ç‘\v ›w·!¶°Ó\ñë<áXˆó¡ó7±)úù yûѳ½A %Ï‘Ýk‹Bu9û;‘{¨ ó}ãP~P7ÍÅ)t›0ØBsôp2¡BBÿèj"#‹yÒ^lP7`ší¤VöêUî´;Ü wù¹ƒ3¬çÒ7r–þõ7çäëMÿõ2ýØÿx‘Ÿ+IEND®B`‚eric-6.0.8/eric/icons/default/configureExport.png0000644000175000017500000000250112342633754021104 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs7\7\ËǤ¹óIDAT8Ë•MLTWÇÏ{ï 3à ‚Ì`*H2)à­[Á&u&6éGÒ–´Ëbº¨ º«M4¡‹&®MJJ„ZSA@ ¨M%¨PŠ– 0˜ùz_ýßKCjLÅ—\îœû{çüÏÿ$z‰§©©I|†Aš¦ÊË¡¡æ>¯×sÎãÝý¶ÃaÏÏr:¿U5õ ]7äææfCzh2™KQ)]3ívÇ;EEÅm¾WËœD&)’ÙqæÌ™÷®JÃÃÃ’¼833“ÒÒÒÈ4MÉï÷›±X|YYÙ N»ÍJºšlô]I’Ô?GG¥¿Ÿ>¥ÂÂBƒm^]]%—ËÅ—„ebëóS§N¹²²²èáÃv›í#_ÅãêÕ«òkååöm7oÝúz[°Íf£{÷îÑ£G þ÷… jŠŠŠH×ubÌbyÿƒ£¡¡Á@UòðÈÈápøô ¥¨®®¦‚‚*))!”Ê—œmáUØív½¶¶¶àâÅ‹­µŒŒ ³¶¶¶Ÿ’ªv:¤A‡††(Ðúú:³ŒŒ mzzº³¦¦¦•{÷î•§¦¦¨¿¿? âÉóäï‹%’4p»÷{éÿ ]]]´°° 4FÓlëKKKo"û_öìÙ“‰†šp‰‰F¡¡1囈—:;^yòä¯#Ïi|ðàABI433#2ÐP(tÌçó]Ó4ͱk×.£ÅÅE9==Ün7­¬¬HH&î÷O~œH$ÇŸ?~œZ[[ â‘‚K¡÷Þè1=ùùtøõc¤È2M‚\r’Y:-†Â´´&Ý”(º¶žÁdå^¤lëêêèüùóâ"pèòò²‚Îëâ02£WŠŠi_q ¥4aârøæ’ÈjQ({çNÈ6IN—sÓÇõõõÔÒÒBñx\€#‘ˆ’J¥tHQ M»tC§ö-L¢õ¸ºU!ü…‹CüòÅ•!âqœÃx¦gÏž›|†jeZ€_»×ÖÖÜL&QBÕh1²±P?ÈšÆHÕ4Òàïîînb|lll`üM šÁ3-ÏËË»Nﬨ¨@¬Î0|(†l1d8ç8'Ç“*©x±0ç±h4*fJW×´477·]έ¬¬Ôp™®k"›DŠ\ë ›RpIøw°2ñXþ0./w\GÃ|999½pE^UU•æt:Ù•+W–eÎÌ”Ÿ¾jþlÛ«iú&˜{¾Ôçææö£ü^À½¸ ¦ëèèX8 ÁÿÐ+ËEÎLçs0œ¡.’…1!…Ã*F0,õx<·á†ÜC‡i˜¬³³3x÷îÝ“¨è1—RѪ*Š„#´Ã½ƒÞ8ztkø_ÿõ:õöôÃn§”ºéP} 9KKKM«ÕÊËŸíë뫃$¡;ãJÀBÜF7ûúèþï÷‰÷†_¤ùùyJ&`/E!Tá7}ÎàÛOðéåË—c—.]z€, îܹS‹ï&½^¯d±X´d*µ¨;OŸÃiéi„¹!<Ï+á2ðßMñ¯ë_)`¯B8!)ííífs£££aì#XDíö棦R-˜Y'NÖã°FÂ\ ô‡Ï ‘5Ì(lÁ çn"“IŒÀïÆÆÆŒ±ž—Š»j68÷>ßš˜òóC|©/XüXLî%ž¸ÜÇIEND®B`‚eric-6.0.8/eric/icons/default/tabDuplicate.png0000644000175000017500000000111212342633755020320 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ØPLTEÿÿÿ """$$$$$$ÈÈÈÑÑÑûûûüüü‰‰‰¦¦¦¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²»»»¼¼¼ÍÍÍÚÚÚÜÜÜßßßàààáááâââäääæææèèèêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõöööûûûüüüýýýþþþÿÿÿ˜XJtRNS BCFJKLMTUWXY[\w{|âçþþï“xÁ»IDATÁÁJ‚QÀùŽG$±UµÚF´jÝûC>Aô Š¥¢?âm&tÆm"æ•W|ßö°üØO›ƒ²‚CŠ®‡1†1Æzñ^@‚f Âì÷:8Mwç©©%àg¬ë¯}“¦çð¶iÀµ¬àj.ÛD"Í饀D[f¢%j B3—€PçϽ$I’$Izü]% Ñ€Ð@€¢‘º€Ðp d€ã?D/!2‹„IEND®B`‚eric-6.0.8/eric/icons/default/cBreak.png0000644000175000017500000000141512342633754017113 0ustar piotrpiotr‰PNG  IHDR(-S pHYsÄÄ•+tIMEÔ '°Ÿ›Ÿ€PLTE2\2\Ó\·\‘\’\”\•\˜\™\œ\\e\c\Æ\Ç\É\Ë\Ì\Î\Ð\Ñ\Ó\Ô\›\œ\\Ž\\\’\“\”\•\–\Úe Úg Új Úl ½e ¾m Ág Âi Åj Æd Él Ê_®_®d ®i ®m ë\ë|ì\î_ï\ð­*ñ­*ñÒOô£$ô°-ôÒOõ\õ_õl õõ”õ°-õÔSör öŠöŒöŸ"öÔS÷•÷ãjøŸ"ø¡"øî‡ù\ùr ùŠùÔSùãjùî‡ú°-û¡"ýÒOþ]þ_þr þþ¡"þýÚþþëÿvÿxÿÿšÿŸ"ÿ§&ÿ´/ÿ»6ÿÀ;ÿÒOÿÖUÿØYÿÜ_ÿê{ÿë|ÿô›ÿö¥ÿø«ÿø¯ÿù´ÿüÏÿýÜÿýÞÿýâÿýÿÿþåÿþëÿþïÿþóÿþ÷ÿþùÿÿÿõ• i4tRNS(,55555555VZ€€€€€€€€€€——œœœœœœœœœççççëëëëëëëëîîîî²¢cÄbKGDH¿qåÓIDATÁÝNÂ@…ÑïÌŒTEL0‚?1¢×òþÏB$ñ¦FŒ’”b¡tÎv-ˆ7îr5Y`@|½-€¿ýæ Ä—·'Ö¾i‰ËÕÙÝ5uísŒÏ«û4>JLú+Wfó¹ÝDštÅv\Î’™Ýô|Źúi°a’zøöTÛ܃+ç¬6ð$?’¹âŽá‰“’›Ù£g'/‡ä1—å(_ìÝeí_õgÔ^ãÔÊLm_}o‘¾ö¢ !«¶ï l°¼Á©ïÖd€¥ÙÐå^$þY‰~?ûª8IEND®B`‚eric-6.0.8/eric/icons/default/vcsTagLocal.png0000644000175000017500000000240612342633755020130 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÞÔÎ!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“fIDAT8Ë­•L”eÇŸ; â‰'p7Àãø#pwpˆ€S$’²„ÑŸ-61Ù(E”aS f¶QTˆÅi5ŒH1‹`àÖIƒÄŸãЫ á¾=Ï›°¨·|·ÏÞçyÞ÷ý<¿ç÷üy yWww÷ž¡¡!íèè¨nppðÇá$ííí_ôõõi{{{Ãûûû ´œø¿¤555îÆ¶¶6Éj[KKËÅŽŽŽúÄÇÇÇdddô%''¯¤¦¦"%%qqqÈÏÏGCCƒ1222½WTTħõñÖÖVÙ†ÒuDD„A¡P@©T" nnnpqqATTTmuu5ärùOiiiâ‚‚‚¦ªªªËJUaaaú!àííÍ W‘H$× ¯ÑŽ—233(//O{ )Ö V«A£ÀÈÈÊÊÊàéé www³ˆ¡R©   » ¥t¸*™Lf`ÕÕÕajj ÓÓÓ8ÞU ÇÊPØ‘­áüV”ÅI†Êìï+¥Ã‹’J¥\Nëëë111Á¡Õján^é.ÁáoO¯Ãú5_ø)¤÷”úøøDúûûߢ)@ccãš”1>>ŸR%²¯ÁsG×aþ¢$Êí‚ÿ”zyy)E"Ñ-*FSS&''¹¬ñó0|ßFâç/`ï—¹ëxäжEò’³É¿¤NNNr¡P¸ ‹ÑÜÜŒ™™ÌÎÎâúh47® ¥ë.µÃíU1äÒy1sül§ràq5%Šm‹¢s†-f½ƒƒ)ÎÍÍA§Óá æg¤0/ÁªÔæ¥>ý(៤­ÁêžMK¼—6{.ٜݾX¿·•‰Ûø|>***8)ÎÏÏC¯×£¶ëNJàüN8¼Þ†_]‚Ÿäd;>Nå`eÖÎÞ1;)9*4ò޹Ÿ`âïÌÌÌ Ñh8á ~›Óbâ«·QP ‹ßU@TËIüëvswVgÂ-oúÁ¤ø CŽË$;‰¤Ø»pGåNRRÆÆÆ°¸¸ˆ?ôSÐsº†< }ûÎ>M¯{€®ç#àQ¥âFàùžšëо2ˆ‰WÈS[»I¼ ðïó—Âãñîdeeq÷k¿ÓÕÏâ÷Ñë0¨»Ôó}®°«ARšC.,-«i ÑÞ$±6é”Íÿ\œ<''óº,MÜ»ØVV( ަ+ä°ëm–WÕ§û±S“˜–g¸ Ü|Âë6‰~ì8‘[[ÞkpòÜÜ\ £§§‡;hû2á“ýd‡U™Ó¹°e¶v3¿ÎGê•—Y:Œ$Òº–DXYltT¤°œÛÚÚÂÒÒò/)!Ü“Ð-V$}ëUe^×1¨?{ä c/íÐñA{(C”aJòúS_  Cÿ‘Iéú½I»î'b ·¦¸RÄ” Šš²›’tVÞILy1ä€Ã)R(ü…ÄÙKmgÛR,îºx,4ŠÂ( IEND®B`‚eric-6.0.8/eric/icons/default/vcsSwitch.png0000644000175000017500000000170712342633755017706 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ lôe2tEXtCommentCreated with The GIMPïd%næPLTEÅÅÅÆÆÆ :!O’aaaggg9W………En¦akx.Lp–––ŸŸŸããã,SmQx¬~˜½ÐÐÐÐÐР  ¬¬¬4ZwGg’,Lj———'AZ/Ikeˆ·“““•••Il“çççèèèwšÀ]dnººº‹‹Œ”””¦­·Ns VlŠ•••˜˜˜•••——————˜˜˜™™™›››}žÃ   ¢¢¢Xz¥mŠ«nw†_‡°Œ«Ét®m¾‰§ÂUužåååæææîîîp‹¨ºººÎÎÎMq¢^„¹m‘Ãq˜Êz™¼ˆ§Æ,Lv8X†;^‘?]„@`GbƒJi“Ko¥LhŽQt¦Xy¢Y´]v–a|¤b{Ÿd‰»f‹¿kˆ­l‘Äl‘Æm‘Änvq‘·r«y—¹}Œ ~žÄ€ Äˆ’ƒ¤É„¥É…¦Ëˆ“£‰©É‹¶Ž®Í–¦˜˜˜šºÔœœœžžžŸŸŸŸªº   ¡¡¡¡©´¢¢¢£££®®®¯°±²²²³³³³¶»´´´¶¶¶¸¸¸¹¹¹ººº»»»½½½ÀÀÀÀÁÃÁÁÁÁÅËÃÃÃÄÄÄÅÅÅÆÆÆÉÉÉÊÊÊÌÌÌÎÎÎÐÐÐÑÒÓÔÔÔÕÕÕ×××ØØØÙÙÙÚÚÚâââäääæææîîîðððÿÿÿ~&ãhLtRNS 8==LR_bbdmq|€ŠŠŒŒš¥³³¹ÆÇÉÐÐØÙÝáááâèèèèêëìíííïððòòõöøúûûüüüüýýýþþþþþþPKiÝbKGD¡)ÔŽ6æIDATÓc` ?`äWrZà¤ÈÏ„Êv˜3wþ¼¹Ž"B²\,0Ž0ƒê´i3gÏš1]UÂZYPs*”Ã`ÖÑ×ßÛ_™c)cWdbSÖ äôu˜2è—öL™8)"ÙÙÂ;?×+6¯{â¤ÉÕz F%ýu-þ)éYÙ™iIa‘u-=U Æ…-šÛ}B£ãbƒý|£šÛ'•2è–4wÕ´Ù›{Ä»»…¤6Ô´ôVè0È×Ohj-HT‘¶õÔÒΨrzËå8Õ]úÛ\58Ä­x¸Õ V^1)Q>6Ivf8gð‡ÛOŸkÐmÐIEND®B`‚eric-6.0.8/eric/icons/default/projectFind.png0000644000175000017500000000225412342633755020176 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ &=û…/tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“IDAT8˵”;l[eÇß½×ï8‰í8¶óhi$DŠ N¨ZÓ‡ˆ‰­!: v``AbèT ñ€v ¨¢E X¨„ŠR*Ôª¦-iBÛ¸u'×öõõ}2¤©@ÂMÎò ß9ÿóÓ90==ÝÕÑѱ×ãñ ±A˜¦¹P­V¿=wîÜòýò”ÑÑQ_&“y*“ɼ•L&û×?„ÿY°´´”Ïf³Šªª's¹\³¥ðôôôðîÝ»_˜ššê‘$©%Áz£ÞÞÞ¤,ËÏçóù_s¹Ü¥––em“$é±Ó§OËl.ä±±±Ã0Z »®Z&å;³b(‰6(æ¾ãµW_º‹ ï¼ÿ!ÃÛöbZ ™ ‡Û}®ë†î;c!º%1oôÓêaK?xK û*‹×’€hÿ0NÎÐÐáæâm·Úr÷„׿'á‘Àv Pƒ¾ÏѶ È€eBEËÝiÃy)B\tµ@9¿‚TcÊm xÖ-jš Ðê:[;C›#žy À{û d d$ ÖK]À¶ÁqÀÅG¬Í³9â+K6§Î7ŽKăPÊ}ÃË/î¿—ôÑñOI?‰aAÝpxdPÚqÝp¹¥Ç¦H$¡¹rÏÏü‚"¯QǶŒÐ¿uœfnæï`;Í UÝåF¢!ßñ í!ðßu…i®ƒé€i»¸ˆÍºd!0lXªA –ü¸l®^¾À×Ç û¨” ñ`08Ü××w4ÆK¥ÒÁ¹¹¹Ù ,¹xäµ&† $TtÍ¡x}ï¿ø§Qæ·k‹Ø¶õt01MsÏàà WUÕCÁ`ð MÓæGZ¿’÷¡Èk¯ 8.ü~ág¾|û03½ìܹpI§ÓÛvíÚµOQßää¤8pàÀ³étú§p8üø?|ìbÔÿbuÙÄo0 ± Šj¹ÈŸ~@<äennŽR©D$!›Í000Àìì,ÑhTJ$ݱXìP­V»ª<Üççð›€bâõ€WYNž:EÈ\Á´ ÇB‘%*• ‰DÂìJ¥âííI¡©+˜zS<4:²GUÕWÄÄÄÄÄöíÛŸhµÝìÙ³¯wúH ';DÀçåNÍ"w£HW<® !œåb±m| ›ž°M×ù£°ê«Æ%åòÝh%œìŠŒ·;".KÄd“r­V7î,à ÀmÔ«û½Õfª¿ÝÏŠ×Ï¢­ £a6¼Á‘hjj|( »Šâ P ¤š·Jõ7-Û>â8Î×Êt…„¢( v(©ß,kÇ6Ö4íJÕ’Cu%ÚýgÕSº8_8¡7›ï …z­VsÁàµÂjÓ¿*:㋚G½8_ø,Ÿ¿}”ÿ+þ4–±5i>©IEND®B`‚eric-6.0.8/eric/icons/default/tabCloseOther.png0000644000175000017500000000160112342633755020460 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¼ÏËPLTE€m¢,,ni j~  c  ƒE‡u¤u%#X†( p$!`"¢<9¡;5ª52ïïïððð /%©5.\.#–RU®<.¯NB°9*²G@´<%´A7´LD·>%¸¹¹LD¼ƒ…½ ½PH¾KD¿\JÀ}€À‚…Á¢¦Ä4,ÄF>ÇULÈÉvwÊ>>ÊKKÊUJËÌIIÌL:ÎJJÎ`PÏ0'ÏZVÏwwÐÑkcÑ¢¤ÒÒYJÒ€Ó\VÔ«¬Ö´´×73×aQ×fZÝhZÞddÞwmÞ²³ßßßààplàpnàààáá2.ââââãããäääåMHæææç†~çÍÍè[VèèèéåæêêêëëëìB;ìÚÛìììî62îîîïçèðäåòòååó†„óîïôˆ†ôïðöññ÷ôõø÷÷úòòúøøúúúûûûüúúüüüýýýþþþÿÿÿØ.ÉG8tRNS &,,-23579:b÷îÝ©D"ñªeY«XÀ÷ýœã8GΟ??800às‹ÔªU«¶¯_¿~§eYqð}ßžžÖBˆËSÜ"å«Ú¾Ó£n,Â,+“±¨ÍMb×%­j™ ©Tª ˜â}¿°ãÌܺnY†T¹Ü,ÙܥРŸ½Nf&môöövÿK ³DJ ÖÏŒQùtÅ4=ëÚºc…ì‚L&3¨µ~¹¿¿ÿ*K µB<¼¼LTÍaz³d3àä,£J¬Ö–N¡Ö"„†M[¶léëïïÿŒ%PyWrѩᶄ¤IhNŽÇIÆ£´†¯Ñf¤¯çÐ*NµZ±ôÍlÏž={¦ …BÎuÝKtY„ :[¶©Ô¦FÇ—Ô¨fŠQ“œ7ÍšŽVÂ! ß«ÚõÏH)+•Jéááá×!¡„h …@Q ™<²¶B84­ŠÔx%L$xE @c¦i¶·´´< ±eH!,ÃCéZ{\˜´' ânšÑJ„i·ŽeÕ?Ùzïjrù9&f˨šúP(uò?”¨ä':Cc¿‡g5^Ø©¿QèL6¦:ŒÖ¤bl4CVuÒмœß y,»™xGœü…aô·‡×r uÙÕúb¾Û ×ùÑsg÷D[¬r*âÍ~g~uÄImGÌeµ>5C](`y&!çó8ýïSâ îè¹³±{ÇŽÍm=t_,‘ØVžšz¢Ïu§„Ñ P{÷îá?ÇŽ['„¨*)ðô©^ÿ“¦è2Æ>ÞGÓØºŸ}+í)Úz{ÍÚHäö_¿ürÿ›7àkÉAxѹRÍÜ¥byæŠ;™õ‚kÕ&ìÔF&N¡N’ºk-Ñû6áEÜ™K8éŒö•ÔtuѲzõr[ˆ·öBB²À¹sçN¯ñϾÑQ>óZlîòÕ²—Ζ òª÷ûã$d _§©Ú&+ŸßÅ\2ùÀ4oÛŽSÊbÌç‰KÙeã‚E=z´g0ÓyÀ©é¾ûöÕ6ÉgÚh&h¸G‘oH²bçç´¬ßDàœýô=äW!ÆÊܘôI¼-Y„”’x¸Jž!ȣܪ˜d¹9y#l¡u@éÆ(µ %ÌŸLƒElܸ1‘¥Hƒ‘·ÝkÍS'RvÁ±«õµO¾É†§_aôû‘¬Ùö"¿ž!HSœÄ+,Ñx½IòŽXÓÚ|è0¹‘oð¯;Ί§>aæç“üýî~Ê^ú2l,ÑKк ŽHÅý¢³^XI‡HÂCÙàë8ùá"ÁhÅÍûìÛï,Ñ/0\n è’Y·¹ Œù˜¿ ¥ß\Ô”Ÿ/ü >8ó‚[#ŸƒÖ‡á¹88;=479367ƒ…ˆƒ…ˆlnr…†‰cegtuyÂÂÇqsv‚„„\^aegj\^aÂÃËvwy™›£ŠŒ•@BE@CFADFBEHqsvikmkmodfhNPSMOR’–€„AEHCFIqru‚„ˆbdhtuySUXKNRMPTjknRTV\^aIDAT}ÁÁNa…á÷œ˜:€´X j‚…+.ÀÄÄ+ñJ¼3·º„µZT†M•a:ó9­.Ïÿ%VÖŠý½ žo+,‰¥Í'îvÚé·øñùšN¤{åÓæñýˆa~™Ä-$ЃéÉɨOàbw¯þºßºIä[¯ú¯#²5ÁA}\ÞÖ‰|Ü{Ê ‚‡¿ªòÎlÃd;%Ä¢ôv0ÛGJvâÚÑ/0ÅP!' $Ûã3̇HîH"ZA+G4&H0@(€ T×ßÍÑ—É–Âæì'f>)É yZÝ`Êê4èX]Uטv:W€äd«³5i½lgò¦=„h›EÓÆ[dTÕœËÙÅàn?•‘- ±tž×³j¤÷“æüÝm ˆ•õÁÆú)Çó›«šÿø MV| 3ÐqIEND®B`‚eric-6.0.8/eric/icons/default/syntaxErrorGoto.png0000644000175000017500000000241212342633755021114 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØšTtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“nIDAT8Ë•”MlTUÇwÞ›ÏΛv:3ý ¥¥0¶@[0†‰LÐ EDEAÆ…‰qåM4Æ…‘ecjÀ€DvÆ&5¸(„2h;LÛaÚa>Þ»3ï½ëbH…’ÔòONNrnò»9÷üï¥z‘×w}´kž=|ðpYß«ÿ:øÞàöÑÁ äy¬RåðÀª¦Ý›wÁK|ÏtŸÏ—:2rd¨3Òù{Øùä`˜ŽÉÐð8°óÀ›ÁæàeöÑ¡”RUo•c‡E7§6Ÿ_ÚÑRiUz94˜LJWj ‘ìI¶fr™#ÕZÕ?´~(d [ô§ú5¿ðïºÙp³—8g˜Ä]x 5,ÉRIð"Öõ¬ ZŽjiiÁ²-¤-imk«[VMÌM¼lØg¸JqypŠC©ÞT2_É#‘H!©ŠªH´'®D:õ°jþ?==­™læ°ÕcýÉ5&–'SÉdö~é‘õ‰T˱ê—Ô$J(ÑÕÞ,VJo”Ö+Œ1 Ô'¾dx¢¦ÕÈ×òh¶†æhh®†®ôzFGCCwôú™­¡ÛºØÐ»^×5ýóɃSOsÇ}{lÆ3qÇ©M¨Š¸>?Ž©L4 nD“_—MÓЄ†îêèè讎°éA—ºXmÇð¯û¯÷,‚‹Åâ_F<þV[¶»{w»faXp»Ïþ¯#¨&P­¬!JwÁÅ]p ‡ àyØÇÊÄžîêî¾è¥û7?à üÊÐøP@Çç`k6Â/TcwT•òi{¬¶í‘²ÿ…ùáv­³Ê1Ê¥f¢i-k"@ÓƒÜ?à…`(è6Ä » ÇÕ w„?¨-º" µ5þí¾{õ¶§{ÿ¡×˜¼9Î|Z¢ß+sç9…7êÅ »uÙž£ n“ÂÖŠÅùÒ~¾v¿]j·Äˆ¯á§OªÕ­GmSœ)¢Mü05ËÞ[U®e#J®é ù:Ô,h•í”sÖÊBq+_©Ë˜Ë0ŒWÂáðŽµÆê±hXø„—fOœjNìíçr<Î Ù°²FM+p6÷ÁkyMÍNϳ®—6ò%·—ºV/‹ç‘nn>¹IJ„®óÎÜ,¾þµ8éiD¹L¥£Wªõ÷ÊV³ˆÌGT0g83ù™ÏÔÇöñå¶›µBï—JÞQMc[ ÀiF/]aCzaی؎OSO[­ïL°4“ɾÊ2ÐÅŸw JY˜m­V[\¥°K%²•2 >ÓJÑgs{êVÌ ¶d' Ïó©3ñûXˆD"›.(¦6V«-§,‹ÐgÛôIIÁãátÅÌ8Ê·Í…IV(@±=-k§~‰Åž’¹^!+EM)Ntw¾{>š¦¹b°]]]¡ •â7ý¹ù‹JqU)~Æ#úfr?_Qö@;O -‘Hlwg¬P(L¤qOÆñ$ÈiZæ–)¿;[³Žš¦9í÷ûñ|>Ÿ] ø_c,þƒ?F`âIEND®B`‚eric-6.0.8/eric/icons/default/projectSources.png0000644000175000017500000000166012342633755020741 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<¶PLTEÿÿÿ!!!999………†††‹‹‹Œ’’’îîîðððÒÒÒ¶¶¶ÀÂÄÂÃÄÃÄÇÄÅÈÆÈÊÇÉËÇÊÍÈÈÊÈÊÌÈÊÍÈËÍÊÍÏËÌÌËÌÏËÍÏËÎÐÌÎÐÎÎÎÏÏÏÏÑÓÐÐÐÐÐÒÑÒÒÒÒÒÒÔ×ÓÓÓÓÓÕÔÔÕÔÖÙÖÖÖÖ×ÙÖÙÛ××××ØÚØØØÙÙÙÙÚÚÛÛÛÛÜÜÜÜÜÝÝÝÞÞÞÞßáÞàâÞáäßßßááááäåâåèãäæäæèäæéäçêååååçéææææèëçèèçéëçéìèèèéêêêêêêëëêëíêíðëëëëììëìîëíïììììííìïòíîîíîïíñôîîîîïïîïðïïïïððïðòïòöððððññðó÷ññññòòñóóñô÷òòòòóóòõøóóóóôôóôöôôôôôõôõõô÷ùô÷úõõõõööõöøöööö÷÷ö÷ùöøú÷÷÷÷÷ø÷øøøøøøøùøùùøúüùùùùúúúúúúûûûûûüüüýýýþþþÿÿÿd­ãtRNS#&MS\l¦¦±±ºøùþ>ôz#KIDATÓm‘=KÃ`…ÏýÈ›˜6 BiEAGAÝŠ.:뢓“?ÁÍÍ_ã*88èâª"Å¢FÚR¤Õ˜š4qh‚(=ãÃáá\.†Eù“PÈQÀ"øPÚ÷Ê«‰€00è­qØcÛ¶1¶-7xYÍ}¹=#i•ÀÖëÕ/o$vÛθ÷åsÌ+Ý™«M¶¢â&gAWUoϘxƒÁ±‚2Œy~;÷ëC å%ÇËÛÚ˜™Þ)¹j¡õ=ñÛVi\~{µ Øuò6—ìÙf&œƒÑ€RÒë¾Gù’uÑ3ªêÃpþû4Møl繈N!v¿øq/H¶¹òPïÄOý®àFaB€µv¼è—gg¦¦à&wAîÆ–T˜ˆúv½é²%\°”™HJ½ ¢?OKã9’5«cDŠ»iIEND®B`‚eric-6.0.8/eric/icons/default/debugProject.png0000644000175000017500000000245012342633754020341 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ' gdvtEXtCommentCreated with The GIMPïd%nÊPLTE¥¥¥§§§«««QQQ¡¡¡¡¡¡˜˜˜”””,,,000$$$IIIffflllÃÃÃÆÆÆ´´´’’’¹¹¹•••¼¼¼»»»ØØØŽŽŽÚÚÚ¶¶¶ÎÎÎÔÔÔÙÙÙÜÜÜÝÝÝgÁ"nÌ1o½3p½9‘ÿ>€Ò>“ÿA”ÿCzÁC•ÿFz»Fz½H˜ÿJ˜ÿL™ÿMÁM‰ÒO›ÿR…½S†½[bk^½_½`cddƒ¬e“Ìf¥ÿf«ÿh•´h§ÿi¨ÿkš½l™½l›½lªÿm«ÿn™Ìn½n¬ÿp­ÿqqqq{†t}†uu›Ìvwxxˆy°ÿ{·ÿ|…‘|ŸÌ|¸ÿ~€ƒ~ޤ Ìºÿ€·ÿ‚ƒ¢Ë‚¢Ì‚¼ÿƒ·ÿ„½ý„¾ÿ†¼ý‡ˆˆ‡‰Œˆ‰Š‰‰‰Š‹‹‹‹ »‹©Ñš¢Ž‘Ž’Ž¨ÆŽ¨ÌŽ­ÒŽÆþ‘“•’£²’Çþ’Êÿ““““¥¹“«Ë“¯Ò•°Î•Çÿ•Ìý•Íÿ–›ž–Ëý—šœ—œ —Ÿ¨˜Ïÿ™±Ê™Ðÿš¢¦œ°Ì²ÌµÌ¹âŸÇÿ    ½ã¡Êþ¢¦©£­µ£Øþ¤×ÿ¥§©¥§ª¦¦¦¦¨©¦©¬¦Ûÿ§§§¨¨¨¨×þ¨Ýÿ©ÞÿªÚý««««ßÿ¬Ðÿ­­­­ºÂ­Êâ­áÿ®®®¯¯¯°±²°±³°×ÿ°Ùÿ²ãü²äý²åþ³Óÿ³æÿ´´´µ¶¸µ·¸¸äÿ¹¹¹¹åÿ»»»ÁêÿÅÄÄÅëþÇÇÇÇçÿÈÈÈÈèûËËËÎÎÎÐÐÐÒÒÒÓÓÓÔÔÔÖÖÖÙÚÚÛÜÜÜÜÜÜÜÝÝÝÝÞÞÞßßßàààààááááâââãããäääåååæææçççèèèéééêêêêêëëëëìììíííîîîóóóöööøøøùùùûûûýýýÿÿÿkÓ"«+tRNS!&00369MOO_`fjqw­²ÖÖçèéêëíñòòõûûûûý‚übKGDíV¾ƒ„IDATÓc```F(`‘8†$Y¡Â"JWਈBD9¥^ÂÁ+ æ óŸ Fçø!— \+ìßÊÉsj˜ÐXy*|EG?jzHhd眹ñw¤^ _Ó1òˆ®]²÷àš's'Ç^… ßбð+ïX¸}çÖþ›§¯A…ojëšå×x¸w=cu*|  æï»yeõÅ7÷æÝ¸¾mퟶ`Ó¼ÅWß^<Óݾ£ã6eZĉÏ__<vwÑAˆð]ýŒU½)§^Ü>qýÑ®=§øÁÂ÷t ]³7¯-iŸ1³úᥠĘ@Â÷uL<ãªfï?|üè¤Òg6¨ò10…è˜û&ÕÍÚ¶sçò-ÍeÏ®lPäŠó?Ô± Lo[ºsçÎe­-Å…OµÖ+ðU?Ö± ÊêY ^×—™ì\ÿTs…7ÿm=3[¯€€G;Sã#Ê5É0ð?EŸŠÉßSŸÊÀÆ ظdo¨&êÈ>!¾IEND®B`‚eric-6.0.8/eric/icons/default/preferences-api.png0000644000175000017500000000216212342633755020775 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ïIDAT8˵•KOWÅ“E?@ÛMÔ/À颫.ºŠÔlºH¥ìªîZuY5RÔ¦ Á€Á@pxpŒÁØŒmü~à1üÂÌÃì€=¿sú¿ã‡‚²¨Ú+GÿæÜó?WsÀŽhÝ#Ý'=ø—bÿ½'±>óèÙˆP½@ý¼‰ò‡&ŠÕKäÄ d„s윜!žû€ðaÁýÖÒU8SX·E˜"%,o ·eÎü˜ÖÝGOÞqË&šMàT¨€†a÷aqϰwzŽÔû3$ógØ+œã Ô@’îCô²µÝ*¬±Òs~ <ªR õZÊ~%²G9Ä’iˆäz?'À»± çÄf*‡øQ邨ÚàlþÛÀª¡¡2÷÷õ#Š¢\o rÖ„ÕåC¡v‰÷• L¼Õbpl +î ('4›7ÁèOûS+Y¦XdÀ´¾üþ—akê å¼ÝA¶PƒÍ·…,9ó„w¡z£Áªj½£³˜5$§; ¼“ß}øÇ—È—/pL2»HçhHÁVý1,Ú˜18ñ΀ÁÇïÂÎÃM`s|KÆ'e±r¥–f(ÃäQ&÷&ÂE$h`±cjÅQF_ó– ‘n ö9ŽÊ€G”Ê ËXÑÛ4MŸ)Ec-ˆçškA73u¬ÔÀïUá£Ê¹Û1Øâ¢<¸§§ç«¿ÙÜ‘l„óEiëëИ|˜Ö;à‰߀v²µ'Dبϖ¨pÌóügkV"‡5hWyleª’ÃY£k©"^²¬¥$(Û¾3!À¾M"§Ḻ%"Èf,¶ê6 'HÎiÓ^§“6G™ªæÌ0ÐÀþRÍâÉÐ “F<½„?G4丳X¥TE±|¥x1š±yˆއ'%H§J¡^¤‘GŸZçã‹xúR µ1€ÇSÒýk½ŸŽ¶ [·/¾ûyÀÌ­g¤ü˜†ßš0Í­cŠG oèªu%ñjу g|¥ó`ÞǼ=S¸(Ÿñ¿Ïœ‰\©V…,¡õɘÔl}òÁ‡j“&DáÁôÑP ¥6­VÛX¨°»²ËÂ2Ë–™sæxf¨iZZ·góefÎäûÍÿ»œo'Y¯!âíó^îù°gìýƒ8^9T™ö‡v‘ŠB÷co­·ö×ožh½9w³ÚÞ{Š€žëÞÕýigYv)Ûÿ°›Rz¼9ÞüI_oŸ"©ÙêkÜÌ}¾·³wg]¬ÙD ] ¶ùñÕ¾§÷½¾{Ïn¢è—yIؾÖÝÑòº½Èä2 „>2îàW„"¸Ïïß»g$A&/œM “›ˆmŽ•ízj§·XX[cpŠ_qð!<ð¾îÚÓUæ)õØPFŒ3Ä›âX¦Ë„âYg`wBžPða¼_Œ|ÜÚØ¢²±®HP‰Úp l)g¦¸Rq5˜ ÷ûüɱ•ÏJé\4T{¸!‡¦k„Š`™*‘éúî©þncˆÈKñ´¢ÄÔŸâþúgJÜ%XÊ/ÙjL· .q[-U¨]  åAû¬y'å0…©3YÄú-ÛËãÿÄb“ƒÃÃÌå uÜ‘u´­.å!%H ¼„ƒyÅ{%¼B‹`Óª ïN5a öU”ÖÄ@ȺHÎ9ÿž5—Æ¿›K$N®TVþ~dd„Êf©ù¥£MþòÒíÔ0À\Œp|°pÌpáéFÙ:„ò®n8êê ÔÔØ¦ óÅêˆJH=M¥Â«Éä­CííiÓ"Ê |£·Ô[åë:s2b)µ,JxïÖv õ"ܲRE iÀ°²È2ˆß·Ã!«†×ÓéŠÅTê·ûò¹ù‘¦å_’êŠß#ra½‘®Ù2 Z®ŠŠ”¸ +Öͺ{DQr:›\®—¦9 ?PÊq~ÛhÖ‡‰K9ôËV•<^œ 㺠áh+ ‰¾­#£´¨ª`^½ ãìY˜W®@ÊfåÛ”&6ž¼Ï0³öV¾QÇÚt¹G4!™ŒU%`f¸sâqˆªŸ:>=-LÁ;ݾ€Á?  ‘“jÁaZùäSS¶3_^¶šÔîûcàv‹ÊÜoe¾žÅÿY?š£o+Z4Þ è:°e pô(ˆP‹ë×T dÇÈ›7Cšœ„”NÃÒüp£è<Þªy/æd‰šN1lA¢Q@„¾eDÜKbOnj²‹›•eš'$%ýóˆFÓ:‘ª.W½[×e’ó÷‘bE1; $“0¯]ܦ”ŽþÂù™¢àƒKZ.w“V%)îU'â ÙyµÌ:Tóó˜_^6&4í‡1JOOú|—Š‚¿½qƒhkËäs¹[†iVª>_½â÷ËL¤Æ°LU‘,ŒË £cwïžžôx~~¶·W#xÂuf`@Vffœ’4À%i›h)Âïµ–ÆXòOJ¿ÿËåïêëÓŽ;Æÿ‰ï|ÌBlIEND®B`‚eric-6.0.8/eric/icons/default/docstringError.png0000644000175000017500000000203712342633754020733 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î< PLTEÿÿÿ $*,999<>C………†††‹‹‹Œ’’’ðððÏÛçÑÑÑÒÒÒ®¯±ÀÇÏÂÎÝÃÌÕÅÏÛÆÇÇÆÍÖÆÔãÇÔãÈÈÈÈÖåÉÊÊÉÖåÉ׿ÊÊËÊËËÊ×æÊØçËØçÌÌÌÌÙèͽâÍÍÎÍÚéÎÀãÎÎÎÎÚéÎÛêÏÏÏÏÜëÐÐÐÐÛèÐÜéÐÝëÐÝìÐÞíÑÑÒÑÒÓÑÝìÑÞíÒÂæÒÒÒÒÓÓÒÓÔÒÞëÒßîÓÂçÓÅèÓÓÓÓÔÔÓÞëÓàïÓáðÔÁäÔÄéÔÔÔÔÔÕÔÕÕÔßìÔáðÕÕÕÕÞéÕàíÕâñÖÈìÖÖÖÖÖ×ÖáîÖãò××ØØØÙÙäñÚÉëÚÚÚÚåòÛÛÛÜÜÜÜÝÝÝÝÝàáâáÌÛáááááâååååæææææçèèéééêêêêëëììììíííííííîíîîîîïîïïïïïïðððÉæððððñññËèññññòòñòóòòòòóóóÍêóóóóôôóôõôÎëôôôôôõôõõõõõõöööÐíöÒíöööö÷÷÷Ðí÷Ñî÷Òï÷Ôï÷÷÷÷øøøøøøøùøùùøùúùÒïùùùùúúúÓðúÓñúúúúûûûÔñû×òûûûüØóüüüýÖóýÙôýýýþÚõþþþÿÿÿ«LtRNS#&MSW`lq¦¦±±ºùúþþÈ sÐcIDATÓc`Ä €˜ p0€„¹–O_0wî¼…@°hÑÒeKWñ2ƒ…»óª ‹Ë*ªjjššú›gA…‹ýër=MLR´Cü³;§vσ [)éjÊ«jè+h[Y¹[ûðA„+#[ªê›Ûz&Lœ6cÆ’¹Ë¡ª§—uäË*Fæ8%{8V.Y•óµ0wñòòŠ KˆO‚ O(ìëì6cáÂ¥K—/_¹æÀÖÌI%‘©!f&)‘V­^µ*l!ã`eìªceåjžV4gúÜ…@V­Y³fõr˜êòäÉ¥j6q±YzQS»fB…},Ý\½]­ìüMµ TDy˜ÀÂõ‰ó!F,í)0Ì`,×ìö)¶©éêÎÊk’Ù áÍm.íçmìm$%™&Ì®¥Ó šÑY &Ä‹®UKW¬ºmíš…"ülØ"“—X[jz¸Ö±„IEND®B`‚eric-6.0.8/eric/icons/default/preferences-rbDebugger.png0000644000175000017500000000234112342633755022273 0ustar piotrpiotr‰PNG  IHDRójœ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<PLTEÿÿÿ•7.2227.ž7- „;3 ]%%C  CQCA  +++ˆ11RRR … 2 '''†²ñB-- """(((Â$&† ¾((ž ¡×2*'P G= 2(ºYRH5M É ²'7/;/«°8,¸¾¬‘5,ÌÂI²LA¿PDŽ4,—1'âÌ lQmcæÊÅ!ôD. ! )))...2%444644@++N32S44X33\aX nsf>}g;}}}€!!……34‰‰,‰‰‰Š2$“““Ÿ Ÿ*)¦©)ª%«­./±µDD¸¸44¹3$Á&&Â55Â6$ÍO&Î??ÒÒ Õ`&Ö1Ö21ÜÜ;;ÝÆÂß*àáÐÎââ[Vã%%ä'éêíîðaWðdTññËÈôJ.õ "õJ4õ£™öMOöO9öÂÃ÷;"÷P5ùbHùxdù…où—…ù½³ù×ÒùØÒùßÚùçäúFFúN7úV;ú€kú¤”úǾúÖÐúÜÖúëéû`FüM5üZCü\DüePüwgü†vüîëý`JæR­¼qtRNS &&))),-.7789ABDEFHHKMOQXX[\bdijkklnovzz€ƒˆŒŽ“–™›££¤¦¦«°³´¶¹»ÁÃÇÚÚÜßßããããçíîîõ÷úûüüýþþþ3ÿHIDATÓc`F(`Bæ3è2C¸ì:(Ê4ô”@-Ya.S5u~>M3VaîðظÞ@6a£”œâÂì$cNa¡ÈæŠÞò¢ê0va ü²öÒ¢<_añ¨¬õËÚZmÍ æ‡ 3É{'®Ý2§ªfæÎÍÑžbPa;móºÎmëïéï2´pd 3ñ1ºUNܶņ³{&7Ø2 3ÁÌö˜:«eî¾íÝ+'¹"Y鵤©vÝÉ£}%6º# [ÏŸ²úôå »{f¬2A39ÍÞuêî¥ãGoZ`‰æ±É½rõ̉‹Ç®O e +ZEì¸sûÖͽ˦ú±Ã…õíÙâÜ»~hé´ iQ¨0ƒŠ‹ G̹k¦§Ë1É8KB„™T™˜} æ%K100²+#B$€$„»cæ| ZIEND®B`‚eric-6.0.8/eric/icons/default/viewProfileEdit.png0000644000175000017500000000223012342633755021022 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ ;w/’'tEXtCommentCreated with The GIMPïd%ndPLTEšvšvÁ§T¤”a¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±áߨ°°±°°±°±²q±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶–z$µµ·¶¶¸¸¸¹ñ½µµ·ºº»ÕÈ ··¹»»¼¹¹º»»¼ùÇ'½½¿ª¢ŠÀÀÂß¼H‹…qëÀ1À£Gh[5ÿæÇd±¯¨´³±ÔÒË%#%%%&&&'&%+*)-+'.,'0.%73*;7(?;/A?;EEEFA1JD-WO5[Q2dY4g\8l^4n8‡wCx5z7–•”¡I¡¡¡¤…­§š°Ž"°®¬²±¬¸((¹ŸOº’“ífƯgÆÃºÏ±RÏÏÑбNÒ°FÒÀ‡ÒÔÔg*ÖºcÖÈŸ×ɡڶCÚΤÚÚÚÚÚÜÛ³/ÜÜÞݵ¶Ý½SÝÜÚß×Äßßààààààáá³áÀwááãâ¾NâÇqââäãº8ãÁSãÙºããåä»;äÀPåÂQåÅ^åäãæ¿Dççèè¶èÀAèÊmèèéééêéêêêãÌêêëêëëëëìëìììá¼ìììììííäÃíííííîîÁ0ïÄ<ñìÜòòòóí×õÇ0ööööö÷÷÷÷øÊ5øõéúË3ûùóûûûüÌ4ýüúýýýþþþÿÿÿ,G·ZtRNS ##*+128:>@CDEX\]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÃÅÇÊËÌÎÎÎÎÎÎÏÏÑÑÓÕ×ØØØÛÛÜÝÞààäçêìîïïñòö÷üýþþþɆl,bKGDË„³p+IDAT]ÁÍJaà÷œï$3j!j¡)•¥Ò6(B‰ ]Cmºï+A¢MPЦED”FÔ6­üƒü™“Îh˜ÏC˜ßíS‚ÛT¨'ÿY;½ì§\H"„ œ!»Æ5_AÀ¢CåràøÆßr^=xú3;ÿÒl«8?ñ*F: f¿ÞŠ@Eyƒà¹Ú*é¥YoU4€ç2_êlò’2Ê»Ï6Öì”Á€ FÞ×O¾WR«> )Ãó-Öb‘¤—%pu¯«Õhzy®>3\ç¡V(—œÇˆa i¿ VbÆÐY¸Õ´0FF0ôÖ´ Šþl˜]àÿ‹ÞõàêÂ3Ó⬪ 3“ÅlȘ'"f6dx€Oßq~6Ä_Ï*xç÷IEND®B`‚eric-6.0.8/eric/icons/default/preferences-general.png0000644000175000017500000000257312342633755021647 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs7\7\ËǤ¹bKGDÿÿÿ ½§“íIDAT8Ë•• LSWÇÏëÃiäcs8§Ûg\œNM&0fœ8#ÅIøj-é7-Õ…¶´ ´…Ò‚”iKA)òá¢à¢ÃÉæ¦ £ &š,‹âÂÆÜ–Hæ(¯w÷UpÉü“üsß»ï½ß¹÷ÜsÎxãòvC¶" ~¾ý8œõÄþÛc·­-Ö)k­5N—}iÓaàqöЋƒ_Ÿ!è=ÙKtm•Z™sùò÷hllÌûÃðjvšPªr£ ‹´³×X€D*†›ˆˆ ƒO7G…t?ö7EQ>p¦LzrKôæü<˜ÅNž=¸ºº Ä"à ¸d|B¤óvK»Žu¢‰‰ ïÈÈȽï‡. _.FOï bVP—«Ä!Ä팃ŠJ‘ÄŠcYIÿÁú:tâ>uóÖÍÉ2“ñƒò 3ØêlÄé¾ÞçƒÝn78°Ù¬€A C‰Ž¾^y¢§Ûƒ \ îÞE§}$W™óáWçeV›ÅôLhK‹ÚÚ[¡­­ìözüæ¢ßد¿À¹óýµ5µ$“˧vÆ'xoݺIý¢ƒÂŽ=ø$‹xOŠÄB8ÜÜM‡}£³ÁN´w´‘nìèÂ…îèèÊérM1SR),Ô}¼]úîÛ) vVf*sÐ™ó˜ …|ߨÙý%tuw‚¥¶†Aß#4Ež:}ªRž%GÑ[£=ׯ_óêK ˆÇçßïê꼃w7´}û6:Ïü§íNõ‰ÉJ‚ðˆuP±ßL_½‚·~vI­Õr6vG,þIHL@W®\níë;µqÛk׬ñŸaèõ:",<ì?h:—!8<ì&” dË‘f¨;h]¯TåÝ^½f5ò›ã÷ )9õõ1´´¶Ab2nÜøÆÇóŽD’Áð÷÷‡àà`€·—-…£òµJPkòh8QYUÁ¼4¸‚2…"Áäòw—{|+mm?’c*7AOoy¶ÿ cÓ¦("66öÑIÒh8,Zô<Œ!Ù cÁ«þ°1jýül…¼‘Ëç¢È#=¡+B=ÉÌdœRõ’2³èƒÄå‹Õ{†ÌåOÈ®Ïb¢aÃ'ëAž½‡LKOÁñM ÉÊÞ;”)ËDLs2f[Ì_ÀCÕ5û¹FS)4¸œ¤ÃQUU¸Ì«¡¼ü))+•e€¡´˜ÔªqÉ vä(²îiµ¤V«'EbµW.£ ¥º”£¬uµdÌÖÍôÎ@£QA>ÖSíÚÈðÃÜÍ2$"$Û#£ =Æ‹;•Ç>©X_U*H:\‘‘á¾Ì‘fŠŸ]²©iì€}¶‘)f§ÄÄÄ“Ùñ|¼á&_¡'_ Ž]•Å£ãö”ÔîªäöœÆßAr­Kr©‘‘’¡ÀØb“Á‰Åå‡Ï죤¦ËËÌ€¹Ý¦§©G‹Q~³•±Ì«Üñ½¾¿¨ÚïØÙÙ”•˜¤¤¤²³´.Q‹¡¼““”byž.T”Ÿ­Á¬®²Fo¦`u™™™™o¢Ê«ÎÞßàC\y‰£— °+Jˆ8]š{¢È4RŒœŸ¦»ÆÐ‹—“ŸŽŽŽ¼ÀÇ6P†?Wƒs–“—¡âããM˜"Z›K_‡QcŠyƒ—z„˜{…›‰Ÿ› ¬ 2`@kH{QŒ!a«#h¹$mÃly”nnnsss{„˜º¼¼àáâCxeÃU’!uÖ"i¶kkklll‘˜™™¤¦¦µ··ÄÆÆÆÆÆÐÑÑÚÛÛÿÿÿûC}¡ÛtRNS  /02=BCQSTTWYYYY[]]^^^bddffgghhhijllmnpqsttuvvvvz{}€€ƒ„†ŠŽ‘’“”——™››› £¤¦¦©©ª«¬­®®®¯°°²´µº»½¿¿ÁÁÂÂÅÅÉËÌÍÎÏÐÑÔÖÝÝÝÞááäääææçêêêëìîîïïïðððñòòóõõõöö÷øøøùùùúúúúûûûûüüüüüüýýýýýýýýýþþþþþþþþþþþþþRä'ÑbKGDì!¹³.IDATÓc`À „ôòRÌ$Q™-æž9qàøÕU~œH¢Lág÷oݶnýêí§²8‡·Ìš>ʜɓVœô‹òOØØ×ÚÝS×ÕRß¹d¡LXa÷Ì‚ÌÜâü¢ä´öƒú0a›mñÇ._¹tñÂùˆ’5¡0a×Ó5QGïÜ»÷ö¹ôå10aÕ=Ma¾Î¶æÖŽÞþ›ÜaÂRËúc=¬ ´tLœ‚vÊÁ„Ùâ6—Úªhšz&.-ç…»P¼cei€ƒ±¥WÒì›Ódþ‘©Þ7±*§¢w×¼k/(!Äu+§.žÑh'‘úàùmF„·°´(WôÃgGÜX1B˜=èúÓ[‘<â,.‡ž¼ÎÀŒ£^ÕŠ`Š+¯}ü²K*.Ú«†-jåÕP¹lSÍÓbIEND®B`‚eric-6.0.8/eric/icons/default/neglookahead.png0000644000175000017500000000027412342633755020350 0ustar piotrpiotr‰PNG  IHDR©þã#'PLTE žÿÿÿôiËtRNS@æØfCIDAT×c` 0 ‚Ãn `2 2÷œ9sšQY¬ñÌA(-#ˆÁ?=????@>GIIJJKKMJNNNVVVZ\Zbcajkilllmmmuutx{xz|z|||€€‚‚‚ˆˆˆ‹Œ‹žžž¨¨¦¬¬¬±±±·¸¶¿¿¿ÁÁÁÂÃÃÇÇÇÈÈÈÉÉÉÉÊÈÊËÍÐÑÑÐÑÓÕÕÕÖרÚÛÚܪÝÝÝÝÞÜàââáâáââáâãâä³ääãåæææ²æ¾ç¸è¹è¿èÂê¹ê¾ë¿ ìììíÖRîÅðÆðÌñññóÓFõÚDöØöÚ6ööö÷Ú'ùÝùùùúàúäý¿œ³?ÌtRNS  !""%'(,,,4569:?@ABEGIMTXY[\]_jjkoy{€††ŠŒ‘•–—™šœ££¥ª±²³´µ·»¾ÁÃÅÉÍÎÏÒÔ×ÚÛÝÝÞáââããåæççèèèéêêëììîðñòóôõõõõöøúûûûûûûüüüýýþþþþþþþïï©üsIDATÓc``dd@FCNƒ)5V!lÐpöJ¿aõúz3L”­úòÃÖ=&ŽÂ“§Ý™ F{øN‡ Äcï›lgö;òð™=?HœË²mªXœ5÷èµ+½^)9¬`žiãlgùÊ37o:||ïþ0°0‹~ÝEf– Kk.¬?0£EêfíŠóþn‡nزkJ±.ÜeÌêùg2÷­Ü]j«ÄÅ„ð“jÓ©å[³¥9˜‘=ÍÀ¹cʼn®4#À·sÉꉞ·‹ ‹ %o[¼ª9æÞÇ'ñšCDÓ7.ZÚinVîýÛ9Ž0e Ö-œßmÇÊ,xõËY>÷)T­]0o’ 0Ko<}u3$®V»gÙÜéÞÜà Ô¨¹óàÍÝ |·O á…:_¥ìþ­—·­ØŠäez¢…áÞ’Ë»ÿx‚kTyI’’w¥2:\Y€Ñàé$Á„Ë|Ì }av&Å<îIEND®B`‚eric-6.0.8/eric/icons/default/eolLinux.png0000644000175000017500000000244012342633754017522 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÜ 6§gBbKGDùC»­IDATÁ}LÔà‡SD3“Y™3…È5Aáw/¼ j1^dÓÝp¾ädçl)•bBηa¤Ho`"j"  ¤S@T ‘Ð! Š7AiÔÄ@AvÇï¾ŸŽÆ™µœéóàIêëëag4_‹Š‹‹Ó†‡‡Á ððp<“ÀÀ@ØÅÆÆ†&%%Õ¦¤¤0!!¡þüùe>>>: RÏC³téÒÓ‰‰¸mÛVFFGG388¸ÌÙÙyž×øñãÜ’’›¶¾ƒ 6›w·Ç¿†þþþmnnn ž×D7÷7ÖoØreSâz~öÉ Ëž}Ù–„¤dê ú›®“&øc¢(xFz—VÌ­ÊM3°±`œ9oÓxËGËü©3™&ºû`PHHžJ«Õâq\O÷]G¶ÀÌ<¨«_¡¯`™â7ˈAaaaxª™3g‚$ì}yæ×2Yúªù·ìÉܼ²?hÆl†Ì|»(2*j(l¦OŸŽ§ŠŽŽ†§—ϲŒ½Ùî\»HÓÅ,µúÜIÉ-(Tc-¦¿Á FDD1H«Õâqqq X·vmkKË š…ý¦öûÒÐl’¦Æ«²sçNÕÓÓ“:îV`` 6z½O ;EQö§§§“Õbî“î?îÊÛ­b2™¤¸¸XæÎ›gõôô¤V«=éíí=6¾¾¾ø/³#`€·—‡>&&ævyy9mÔÞÞ^vwwK{{»ÔÔÔH]]¤¦¦Ê´iÓ¨( EY­Nï óóÂ#]»á:ã}ØyxNÙ¼}{2{zz¨ªªôôô°««KÚÚÚ¤¢¢Bª«/ÊÑü#œ=ku: }GØøùz;àqñ‹4°ñ ˆò™êØ|(ûm¬{{¥··W:;;Åd2IYY©TU×Jù5³`! zµú #€ÛhØLš¬8`@€¾ ìvĹ/þfÝël¨Ê¤Õl±Hww·tttHccƒ”–—¦ºór©$C–/[ Î}GÉeFÃ&yùéÀ,¼¬!/`ãÇ€l¤pˆ¨«à$‡°_Š@9ò ¬¼¹q²ñÃ(9zü¬4\½BÓÍf¶wXØr)UX a5„õ^­• Ö|ŵ#FÁμ CåÒX J (e +AÖÂÚós÷ËâÒs,,*âÖÍ)ÌÜäEVAX‘ùJþ0ʧt&;€ºC%[¤”PNrd9ÈnY,sÞ[~'|ÎÜ&?ï©w&Œ"Ïü”, %Ó)O¾x)L]çúl¬)ø›ìÂK”þc˜/¹È<Üã PÍÁ¥OÃ0€÷‘£}ß¼ž62™Å ‹Akã—ýG\G`u‡³¨ñ@ñL°¾ÐvíCLçÞ!“ñ/lÃðûÙˆè)À,ë ƒ ¿î(é/j0èOÂEž†ÏãÀIEND®B`‚eric-6.0.8/eric/icons/default/browser.png0000644000175000017500000000164612342633754017415 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<ÚPLTEÿÿÿ¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææç°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀÂ<Û<„à=‚Ø=„ä?…ÜE‡Ö^›ð_aa_šæbžðbŸõe ôgiig¢õhžájlll¥ôz{{€‚‚‚ƒˆ‰Š•––˜½æ˜½çš¿ç›¿çœÀç·ÙŸÁé ¡¢¡¡¡¡Ãç§§¨¨½Ú¬½ÔµÊã·ÃÖ¸((¸ÄÓº’“ÀÔìÁÁÁÁÂÂÂË×È45ÏÏÑÕÕÖÚÚÚÚÚÜÛÇÉÛÜÜÜÜÞݵ¶ßßààààààáààâááááâââÎÏââãââäãããããååî÷ççèèèéééêéêêêêëêëëëëìëììëòøìììììííííííîïõúôøüöö÷÷÷÷÷ùýøøøøúüúüýûýýÿÿÿÇÓEtRNS #*+128:>@CDE]aˆ§¨¨¨¨©ª¹¹¹¹»½ÀÀÂÅÇÊÌÎÎÎÎÎÎÏÏÑÑÓÕרØÛÜÝààäçìïÄ詜íIDAT•ÁÁJa†ÑçýæofDk‘n$‚Z·­ÝDÐUÖ ´it-ƒm” 4ÒÆù¿TœAÈMçð/ê÷ø«é·‘Xr|šÙwZä÷Aq|©ÍßÓ|^zˆåAAÃz³ÌÛxðdøx2`›¿yð~V)}*£.öØè»>[´ö»ù ÀÏó‹[µ8¢áÈΆ·NlÑÈk×µÊkJØfÆ.I`í!¥<ÏÙ ~~u½ÈÙH,±&‰/N©I’K¸›a]jRðQ\O&ÉÄH:ì¸{L+¹™Éì•Ý$[’­(®x\úéKWçÙŠ*!IEND®B`‚eric-6.0.8/eric/icons/default/method_private.png0000644000175000017500000000126012342633755020735 0ustar piotrpiotr‰PNG  IHDR(-S pHYs  šœtIMEØ*¼ÏååtEXtCommentCreated with GIMPWPLTEcL$áË^¸¦LŠivzcg   +++    808C;@ɘÒܪà­ddd»Œ¿À¡.£/¤1Ê—˘˘̺MͺKоOпOÒœÒÒ°4Ô¦ÔÑfÕ ÖÓgר×»?ØÖjØØmØÙmÛÛnܪݫݬáÎUâ®âÑXã¯ãÐV䱿Á9çÃ<ìËBìÍEîîwõÎõÞYöÏ÷Ï÷á]øã^ùã^ûédüç@üè>üè?ý×1þè>þþ~ÿêSÿúwÿÿ}ÿÿÿÿ‚ÿÿƒÿÿÿ>Çp@!tRNS **++,,./2;>>@BBrr‘ýýýýD‚0VbKGD^Öa»ÇIDATÓMçRAgÙãɸf%(A²¢ ‘¤ÂÞÿ5ØÛº«b~MwUWÍ„ÒÞxE,.|{BD‰"B.Œs¦Ä©ƒN¤`àÈT"ä:<&Wk€‡Ñßsú²¼”\ßlúp¤É‹™†Êb»5^ Ñwã6÷6£=]½')FÍûüû/ýu¯d2jÝ;ÿý2ÃÏkèŒ8*kUãñÆdÒìúŠ¥x¨Úm]Êñð¡j§õ Ó­úÀþŽñcÀÏlÜ7/¹¸\IEND®B`‚eric-6.0.8/eric/icons/default/rescan.png0000644000175000017500000000241312342633755017177 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ˆIDAT8˵•klUÇï÷£ÓéîvwûŒmÁ] ‹Ûª‰DÒ@ZºÝn»¥´Û÷+mÑRé+…I4 …ÚH•@¨´h-%* j⇆ýƇÆ#(4Ęîß»k¦|Äøá—Lîœó›3çÌÜKÿƒGߨ# i$;h½¾-}ÎÓëYÈéÍ eueÝr´:¾¡Uô0)&+ÌËÿ(ÿÑb®ŽxcbÉy9åGÊÑýa7v±{¿Þ‹ÏÐ1Þ‚Á5Æ]º™ì#^ÇxŒV‘éõƒëç–ˆI€Èb5ÿqj[J¨ù½fìùrÏ_~ȳ»žñåÜw|½¾qh#¬-,K•ü%O¿:Ñ}±{}3}è™îY²Þ;Ó‹ú“õ(-EÏÅXÍÅb¥J(qÖÚC-ã-hlÐv¶ ÞÜ€Œö (B±gÙýÙ¨«EëùÖ(çþ$®!6*&åDÓ7«wóä#x<!0@rS2¨—‚/ä lâBR¡ _Ó…Ò¬`ÝÈ:ßgñŒ3Œ± Ìz#*6ëåWR›RàñÝÇQç_Ä>áNܹ"s€ðñMDÒâVÑËßãÚ)èе'ÖÂ7ÁrN3Nø˜8&*Ž ªŸº;\È{#/‚k› ´Bö wx?oY4`/ñÈ>þ†ÐÇ*¡H;ž†¼I–wšq4±µzTS¦Ìeöd"wWn„p?¥M<¤Rþµ¤ŠPÄÍ l_Ùu5 ¹Ÿä"ç\–¿µÖV(•bT¬ø¥ß].¬Ø¾î—Ü`~Xbý­|@,$×Xâ«XÏ«ˆAR…¾ŒB(å 8uò™H, ¦²WüM)S —ëЪ5¹D Qßbñ¢‡ W"‰¶r•·Ö«ÿ¥¿ðcxú¤Œ€41ºbZ$ð~:ñ(1-"+- šChäL)À©²Oãƒ]$f½ü\õ `{CDJ^%Ð%hâ<õß’j ‰K(æ¦ô×¥|ù Íí§ËXŽÓìS ½Aäî‹Å2ngL©Òɤ{X Ô!)ƒ&›²|›õï“å‘"òv+%ÂõÄã¼ãˆ¾ËVÕ!1Ÿåä&tËåv!*f}6Y;æµt¤, £Vp"q§øv}ÁÖ¤-$vX},á¦ëdüµ´c–)s0nXé²ë[,Íê3K¶Mâ'UfP ‰ûÙdËpŽÆ€%bå)ÖœI„çl2²?HŒà9›ÄÖ’n±{³éÇ,“)ï˜ûm­úÛlË~è~ÌsÓ©ÛM؆5¤5á~׎5ãIxòBÜ—íXvÕÁ}9«ÙÚSãI·Wr|»¬ßv™øÈ¾òP1ë¡ÊÓKöf}Á}ÈŽ¬±¬™J‚ëJÀÁÂÁÁÂÃÕAÅkpÅÅÅÅÅÆÅÆÆÅÇÇÆưˆÆÆÆÇÇÈÈÈÈÉÉ É6=ÉÉÊÉÊËÊÌÍÊÍðËËËËÌÌËÌÍÌ Ìœ3ÌÍÎÏKPϼ¤Ð·…ÐÐÑѳ·ÒÔïÓ¡ÓÔÕÔÖïÖÖ×ÖרÖ×ö׺‚Ø¥/ØÏÒØÙòÙÙÜðÚª6ÚìïܺQÝàïÞ˭߲߳<ß´à¶?à½JàààáÓÖááãáãäâÞÖã¼ãØËä½ äåçå ååååæíæÚÊçèéèÊ]èêìéêëéëìéëíéëîêëìêìîëëëëììëíïëíðìäÙìîïìïóìõùíîïíîðîîîîøûï ïÔfïðñïñìïñòïúýðÔ0ðððððñðñòðñóðñôðòõðõÿðúÿñÚwñññññòñòóñòôñóíñöýñúüòÛnòòôòóôòôêòõíòüÿóôõóôöóõ÷óõøóöùóþÿôôôôôõôõöôõ÷ôþÿôÿÿõ÷êõ÷ùõùûöö÷ö÷øö÷ùöúý÷ß>÷÷õ÷÷ø÷ùî÷úý÷úþøøùøÿÿùè>ùùùùúúúüþûìHûíWûÿÿüüüüÿÿýÿÿÿÿÿ JÓFIMNPRSUüüýý_ñÿÁIDATmÁ±JA€áçæ¸ IRXV>…ï_hk#‚u°Ð&šÍÝ$;£•˱ߗº¥0å]Ìî˜z\¤Õý§(¿†6™¾_œ=eÿšsß÷¹ïwö¼m?†—‚ûsãÏê°ž—+CñLæŸIf×¢øM“‹²FA9•4*¡Â*…·yb,¾…AÆÊ(\3õ„PáŽPQ0ç„[.»Ûâ%ÜÜ#üG˜¥n)Lù†º„ˆ4rÔ¦rð£âþ ªk_FAâë‹IEND®B`‚eric-6.0.8/eric/icons/default/editBookmarks.png0000644000175000017500000000237712342633754020532 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<ÄPLTEÿÿÿ³r꺳rD†DÌ“†®kÌ“®knjnj@@וç¦ߣÔ••F™L—PšRÂ~ÒÃ~ÒÙšÚ›Ö•ë³ë³ç«ç¬˜MÕ”˜J²k¾x¾y¬d²m­f¨^—H˜KЛM£W§`иs›PQ¢Y¸t•M˜NÝ£SÌÝ£Í ³oLj³pÉ‹ ¦cÏ’‘O¤`ϓ՚ “T–SÊŒÎΖ!ÓŸ,Õ› ß« ã®ã¯íÁ6íÂ7 ^»w¿sÎΤҙÓ’ Ô– ԜԜ՞ ؚ؜٣ݩÞ¨3Þ©5ß«à­:á±>æ¨æµæ¾ ê¹ë«ë®î¿<îÃ]ïÇ_ðÀñÏ_òÒcôÉeõ´õÑyõÓtö°ö±ö²ö³öÇgöÊmöÎmö×wöÙxöÚyöò‡÷·÷½÷½÷½9÷¿÷À÷Ã÷Çe÷Éa÷Ìg÷ÎZ÷Îs÷Ïa÷Ðg÷Ðm÷Ðs÷Ñm÷Ñs÷Óm÷Ós÷Ôm÷Ôs÷Õx÷Öm÷Ös÷×m÷×w÷Øm÷Øs÷Ø}÷Ùm÷Ý|÷Þ|÷ß|÷â÷ã÷ï…÷óˆøÀøÁøÂøÅøÈøÏUøÒgøÓaøÔZøÔgøÕ}øÖgø×aø×gøØgøØsøØwøÙgøÙsøÚføÚmøÚsøÚwøÛmøÛsøÛwøÜPøÜwøéƒøé„øïùÉùËùÎùÏùÐùÑùÙBùÙ^ùÚaùÛgùÜaùÜgùÝaùÞaùçúÒ4úÓúÔúÖúØúÙúÚúÛXúÜIûÛûÝûÞûßûáüäüæüèüêýòž(kVtRNS !%,/6hzŽ’”›œª°³³µ¶¼¾ÅÇÉÍÖÖáâäåèëëëíïðñññòôôõõö÷úúûûüüýýýýþþþþþþþþþþþþqý€ KIDATÓc` ˜ä™°+†„*aŠ µ¬ ¶.Y¹²Ô]T&åÄñãÇeQä<›–/_±¢9@E*Ä.©ïQ¹dé2 hÌŒ÷0–æb`à±M-Ü:{þîƒGŽÁ‘ƒ»¥Ùó2°:–M˜0mÖÜ]ÁÞ…sgL©pæ``ð©«o˜:sÞâý‡í_0gúä)~R ÃÕ}{ú&mÙ±çòÕ«—wnÛ8Ù_l'£IBïÄMÛ/]¹~íʾ ±Ì·p:ôo¾øàèà 7»[óœ¸aÎV‹)o_{úüí[g×w&iÁ}£YÝvêÖ£§Oî[§ ÖI¬]}æþóW/ŸÝ9•n6̪Ysöñ“¯_Ü;k6˯êJóv󊺻¾Ø.láb%ÎÆ"féžc ÑU凰ø”õDñD,LeƒÂÅãIEND®B`‚eric-6.0.8/eric/icons/default/vcsAdd.png0000644000175000017500000000242012342633755017126 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ5Ý4;tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“tIDAT8Ë¥TMh\U=óþæ/“™ÌdÚ1&µ5I•¦TÓ.R ÄBiw""îÅ[‘š+qáB²±q#u!$E‰’JbMcmú“d&Îd23™÷3óžß¹ô…ºQ/|3ï½{ïù¾s¾soÇÌÌŒ–Ïç­T*õD³Ù|ÙuÝ72™Ìó©h4jø¾v» Ó4á8N«^¯×vvvæeîJ<ÿ¾V«m”J%wllÌ'^„?ÓÓÓ1x.N¿'ñ¦,ŒA€½½=¦ë:øÎ¡išzfÈ:5'…8»»»_I¢Ï%áÂøø¸mLNN& Ãx%™L~ØÙÙ9Ä 2©UæHDX–¥@…‰ú&&°| Ó·<Ï6ÉôC^:$†¸ƒ´CPn”Äû•¶Z-5Ï8È‚ï‚qRâ’°·E›#¤E .â?+æ3¥ 4G¤à|˜˜ÉøÎïÅbñ4×8'Ú$„ 3îSgpÓA}C!«œÁwP.— XÀ²"~b{{ÁY+ õ å ,€C0TolÛN*`Ù\•L¦ØEX‚D"¡´ 7†ÿ÷£óhå·°Ðúƒ‘³8²ýÜb ,L@Ù\[Kæ€Án3#+) ˜ 8ªÕê~•kÆÏ8›:仨‹ì%ø•~J œ<¬ÀÃwHeQjÉ Rfv6³««ë`ޝ†ÍÖMd´<äñ—3^ÿØ>Ca ¥¨È&‹'*‹)9øO-¥©Ê·tÃáêßÅŽÓ€æ§Du©1¥/+ÏJ#.&;L)Èì VM͹iߎº WÖ6¼R’@Ó-‚©Ã‚ˆ%jhÔØ’Й•ÁŠY)¬¼†•Ö~iÿÀöA5h‹ ŽÁöšˆ ðº1‡½]èlIÚƒS³ög/òä•…®%•æ¨3G.—ƒqÜh_ÃÑÜSè‹åÅg-Åæ¨6.Ï.v½*Rº‹‘ìyè]¦$5Å×Ä53~Ó½z٦ȡ‡Rp9Y½Œ‹úkxüÝðe³†(tüíb§÷ƒß &â° o«Í;èÇq<–––[\Zoql?A>NOMOPMY[W^_\ŒŽŠSSSrrrUUUopmRSP]^\LLJmnjŽŽ`a]}NNMsuryzwŽŒ[]Zlmi™š˜ŒŒŠ}}}oply{x³³³zzzuwsvvv`a^»»»qso‚ƒ£££{}xlll“•‘ƒ„‚’’    ¡žtuqŽŽŒppm†ˆ…ghdrrqsuqvxt‡ˆ†qso{|ywyt–˜•}y|yz|wËËËlni|~{}–—”suq«««˜˜—ÉÉÉÌÌÌÄÄÄÊÊÊ×××jjiÏÏÏ··¶·¸¶ÝÝ݃ƒ±²°¨©§ÞÞÞ¹¹¸áááž ²³±ºººÞÞÞááቋˆ¹º¸åååmokÂÂÂäääçççëëë“”‘’°°®ÉÊÈ\][kljpqn–—• !!! $%$'''))()*))-/...389CDBFGFNPNRRQTWXXXXY[Y]^]bc`cdcfgfgigijijljlllmnnvwvxxwyyyy||~~~€€Žšœšœž›žžž©©©«««¬¬«®¯¬±±°±±±¹º·ÀÀ¿ÀÂÁÆÇÆÎÎÎÏÏÏÑÑÑÔÔÓÖÖÕÜÜÜÞÞÞàààáááâââããããäãääãäääååäåæäåæåæææçççèèèéééêêêëìëìììíííîîîðððñññòòòóóóôôôõõõûûû´’ ŒtRNS  ##&&)+,-.012233569ABNRVVYjjjn{€ƒ„†ˆ’““–šœ  ¥¥§±²µ¹¹»¾ÁÆÈÍÏÑÒÒàááââãäåååæèèéêëìíîîïïðòóóóôôõõõööö÷øùûüýþþþþ87q›XIDATÓc`Bb¥ù~lL hÂÑÇo·'›  ›n?uÝ‚“ ]8hËÉ3\LèÂ|åë]ôabRBöÚºzíé¶ð"7a¡Š•“gíÛµ.OYØ xóΩkvìÏ1F6ÛºeÊ„sµIi!zHV2zwõöu[i¦64TºÃ…E"gôô·š1Ù>zø`LX7eú¤‰5FLLgÎ9Ü6¯Ÿ9}Z¡6åtáòùM`açÎEóç$*0±hhy^¾vùlHX@I>A’¯Ã;[„:YVyšCc‹n‹£•¯À•³Æ @qTT]UU^ ,Z€¡¹Ÿ½ÍQr‘Ps”_ep`epA`‡‘®Ãs‹y†BbŠ`’>`—?`‹@a‰@c—AbŠAe™C`ŠEd’Ef›FjŸGk Hf“Hl¡In£Jh‹Jl’Jn¤Kp¥Lp¦NkˆNs¨Oo¢Pr–Qv¬Rw­Sx­Ty¯UsŽ[y”[}¡[€¶[¶\€´]¶^{–_‚´`‚³a†ºb†ºc‡»c‡¼f‰½j¬l½o‘Ãp¨q’Ãq“Äsš´u–Åw–Åxœ¸|œÊ€žÌ Í‚§¿ƒ¡Î‡¢Ì‡¤Ð‡§»ˆ¨»Šª¾Œ£È§ÎªÔµËŽµÌ°Â”°Ø”´Å•°×•µÆ–°×˜¸ÈµØŸ¹Þ¢»à¤·Ö²Éê¹Îíÿÿÿ6 u:TtRNS ##%&')*+28<@@BMMMQUY]mnoqrrtuz|„„„ˆŠžŸ¬²³ÁÇÈÙÚÚÚÛÞàäääóôôöùüüýýþÃÜObKGDç¶kj“2IDATÓc`€}kn4 âš0i×!'!TQVûˆŽíןž°eA–i¼ãÌÝkÓ¤Q„ÕgFw®Þ{`C*аüÁÈ≠ôÍEæt[›œ]QÞèÂj§¢ï©e³·øÈ¡»ÐàÜÍÇÑEüjç-ª Ö@åu/˜òþÕ.oQaó¹Ó÷Ÿ}üìB‹²(ŸWÃ’=§o?z¸&PIX{ió­ÇÎ_|²»È IØ®°nÎú}‡î[™ãÈå÷+é_¼qÛÖu³Òê…áÂ*;ÃÓ›¦.X±|N{R¾\ØpsHL^sï” m¹aÝFpa­;¥¡ñYeUe™QG4á‚Î6U§$&¦V®ºä f“²ô ºwåò­ Iv„™¹Ä•õLMt•ĸ˜À]lyB¥>IEND®B`‚eric-6.0.8/eric/icons/default/editReplaceAll.png0000644000175000017500000000155712342633754020605 0ustar piotrpiotr‰PNG  IHDRójœ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<†PLTEÿÿÿ µ¹¼ÉËÌÀÃÃÆÉÉÃÆÆøøøƒÛ†Ü„ۇܜë—ç—ä"‚É#’â%Ð'ˆÒ*ŽÝ+™Ë-‰Ì4ŠÉ5‘Ï5žÙ6ŽÌ=€¸G|¢gŸÒ„¤¹†¦»ˆ™¦ˆ§·‹©¹Ÿ   ¡¡¡¡¡¡¢¢¢¢¢¢£££££¥¥¥§§§©©©ªªª¹ÒæÀÙêÅÖâÅÝðÇàñÊËËÊÚçÍÝèÑÒÓÑÓÖ×××רÛ×ãêàààâââæñøçèèéêêêëëëëìììììíííîîîîîîïïïïïïððððððññññññòòòòòòóóóóóóôôóôõôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøùùùúúúûûûûûüüüüýýýþþþXí)tRNS "#$+,1369=?FGINPQRSU[]ŠÜãóõ÷üÂ}žµ5IDATuÁ½nA…á÷œùV›€%"DGHÜ%Ôô\bh¹„tB:*Hƒñ°7qŒwfØMEÃóˆ[3þõó‚A0{¾±Fj.lré~騹竀TŽýhc+$|_j_®|z•»óýTl‰1ûQ¹MÉÉ4à»õd]')%;É`pÚ™v}Ž4°„Q¿ôMЇ%@€Ÿ|Øï#ÞÞy(’LÔx¿>λ'O ‚) {ï{™çÖb`D’äë:‘°’Û©k¥Ï „ó¾IQ¯¾n^_€‹g–j÷yçÍå9¦¾²bÔŸÝ<Ú~ˈémѼ°e¡Õé»íâ$¶ËåòƧDzëÃîl ˆÑdÏ\«ÝïÂÿ ‡Fú¾äAÉù/ n].–æUIEND®B`‚eric-6.0.8/eric/icons/default/attribute_private.png0000644000175000017500000000074412342633754021465 0ustar piotrpiotr‰PNG  IHDR(-S pHYs  šœtIMEØ;«1RtEXtCommentCreated with GIMPW¨PLTEcL$Šivzcg+++ 808C;@ɘÒܪà­cccdddeecmmm”””•”“–•’»Œ»»»¿Ê—˘˘ÒœÒÔ¦ՠרܪݫݬâ®ã¯ä±îîîõÎöÏ÷Ïüç@üè>üè?ý×1þè>ÿêSÿÿÿb: _tRNS++/2;>>@rr‘ýýýýïœbKGD70¸¸G}IDATÓ]ÌG1ÁÂ{/ ï‹ýÿÓ8Òö­òÐP5¦F°¢iwL)Ó‚¦ ¡’£A£¯‡ð\OgÛw—~·7¸CùÂu—,wïEÒýbuz Þ{UÒÃ|s~‰ªªZù?‰sª6g30D&Q£Lÿöº” HG3IEND®B`‚eric-6.0.8/eric/icons/default/preferences-icons.png0000644000175000017500000000200412342633755021332 0ustar piotrpiotr‰PNG  IHDRójœ pHYs × ×B(›xtIME× 4+L'¬ PLTE"""$$$%%%%%%ßßßæææÅÅÅÑÑÑõõõóóóþþþþþþþþþþþþÿÿÿAÐJ½ìL‚¼RÆíRÓõTÞúVz°VÛø\¸èd­ÍdÎòk‘¿nŠ·o‚šz„Œ|®K‚·Q„z†´U‡ŠŽ‰ÚAŒ~Œ„ޱpš©‘“z”µr•¤¿–––————Êe˜›n™ëOšššÚfžìXŸ¤pŸ§—¢¢¢£££¦õ`§x©§ôa©ª£««««¶¡¬ «¯º¢¯îv°°±±:±±¶À²g°²ùr´r²´¿<µh·µ¸•¶¸­·›µ·¿f¸¸¸¹Áa»[¼¼ÀɽÆT¾¾¾¿¿¿ÀÀÀÁÁÁÃÃÃÆ¶ÆÆÀÆÆÆÆÇÇÇÉÉÉÊÊÊÌÌÌÍÍÍÍÕOÎÓgÒLÖÒ_ÕÒÒÒÓÓÓÔÖÍÖÖÖÖÙÒ×××ØØØÚÚÖÛÛÛÞÞÞáá‹áâàâââäääæææççŠçççèèèéééêêêìrïìììíuðíííîîîïïïïððððððópññññôvòŽöòòòóóóôˆøôŽøôôôôõõõ‹ùõõõööö÷÷÷øøøù÷ù÷’ùùùúúúÿÿÿƸ%?.tRNS  (,3678BCENWˆŒ•–œ®ËÚðôûüýþþ6×»>bKGD°Cd®Ä=IDATÓc``bçáãG¼L Œ\Êšº(@K…‡‘YD}öÌþ‰Ó–­\µzÝúE3f¬\¯-ÆÂÀ*®13ÏÊÒ³(¸~ZfRJé¢ Rl ¬’-&fz‰ë ,aúÔܦ 2`á #S}7pLýòÅ ÅPá^kCcóxpAÚ’áíPáÕ5Ž6¡‹@Â뢜]ŠÖC…×­GPáõį[Exõª‹` {Z§@TNnî˜8*¼0ÖÁÇ£$Ú”“•Þ n± ŒpŠŠ®ÌH?7¿*\m–ì ]Y»vM]6TxŽ}@œkáúUKçUùNèvo Kh¬Ÿâ]²~ÝŠ…sfUzù7NÔ‘fc`UÝ€ÔÄYydå•‚œ0Ö˜9…Q€7 02¡FF¤°¡´øÎeIEND®B`‚eric-6.0.8/eric/icons/default/flashBlock-director.png0000644000175000017500000002625512342633754021616 0ustar piotrpiotr‰PNG  IHDR€€Ã>aËsRGB®Îé pHYs  šœtIMEÜ:4»nïÈbKGDÿÿÿ ½§“,-IDATxÚíyœegYç¿ïûžsîV{WWoéÎÞI€¤I f¢ŒŠ€Îà€ŒÂàøF` •%¸ŠÊŒ Š" ¨#ã HDI„Èì„l¤“t'½Tu×~·sÎû>óÇ{nÕ½Uw«JU¥ú|>çS·oß{î9ïó{~Ïú¾/œ;ÎçŽsǹãÜqî8wœ;ÎçŽsǹãÜqî8wœ;¾)õL@y+†Ø†e†QÊØ4€¥‚fË †SÌsF}€ê9<]„};ȳǵÀe— ¸a(y  ;\ÀAŒPA1‡ðЇ€Ð|…‡ÕANÀÙ ðŸ£D«ø7 @3A¡É„*Í_ZȨ ,kYÇ$ŠChn#åsT¹K½Ÿò9l•ÐßHÈ.®^Žã¥hö`–„í6ùt(R,ŽÃh> ü '¸CýÉ9l†àßÉ^B^‰â5À5 ¶OËŠ³×ˆ4ŸýÂû¸á£$|R½›cç°‚?ÈsPü(ðv,i¹t´m¢o"(ì†ü6ˆ ?A~ù HkP; ñ"ÔÎ@õ8Tc–@&Ùµ:C5±ƒåð—ÿSÝÄ7Î`=‚¿™g£yšW`ì¨í²ä¸AÜÛŸ;®‚ñgÁÈÅPƒÜ€~ïþÃi̓ ¾Õi˜}Nß §î‚©¯Á ¨7Eª++,àøk·¨›¹çú£ú=„¼Åë0 “¶Ñöf-ˆ`ÏwÂß »ž£A~L΂¸ìÌœéaT¦ÊJÒþÔl µ9˜9'¾ þ<ñ°·²ÃÊÑ Ë‡Iø€z7Oœ@'çn7¯Ãñß Ù×Vð ú/{_ û_罆ö€ À¥ËBß”ÑÊÀ °)Ì?ÿ3þ8ö÷Pi2í€pÍ/qœŸ-ÎâY¹™hnÁðâ%o¾ùhPüØ.¸âá²—ÃØÅ™ ûžzàM? ü Ü÷˜>µl"VšXþÇÛÔÍú¦€Dãøq ïF3FÚF㘸žûF¸ä»¡8î…îl.ý£ÎÀPž‚‡þú]˜|tÙ9l>À1åh~WÝ´éÁëÙ9ÈÂÿÀðêUZß°ñ£Ûàš7Áe¯„üØzoþ”cAÉAmø$Üù›03½ÚGXfƒ¡ø)u“ß4ƒ\üW­²„6óæŸý#põëa`'¤ñdx6!cD°xîü=¸çO ncB å.,¯S7óõg<ä ߇âChÆ[(¿Á{À¿y+ìº\ƒêŸÆGÃi<ñUø—À‡–µ¿Õ$Lbù1õ‹üõ3r3?IÀ¯¹…v™fø¸ú }ØõL:LI¾þ!8ô‡žéô “uRÞ¢næ·Ÿq›yïT‹ð-04ßönØw£×ú³ÝÎ?ÿ@‡pôóð…wÂü|«IЦ¼]ÝÌ-ÏÈ»y/†·¯Já¦ÀîýðÂ_‚‘‹|î›áò0{nÿïpü°7Íñéä÷©wòާ=ä oCóþU·À…ß ßú óMП²ìðèê³ðÅ_†G¾ØÊ 8~NÝ´¹L°©#.ïâ'0ü‚Z%üKn„ë>KÙ¦|S:ð¾Îï‡>¿ Áò&õ‹|ðiy¯ÀðQ„ü*á_ôB¸þç–óõßÌG£ÎpÇûáÈíí@PÃòšÍŠ6r3Wcø ší-½w¸ðz¸îm^øb¿‰h¿‹9P¾t Ô;w´1!”'áóÿ ª­y‚Hø÷óŸÕGÙ0»lèìç ˜Â—ìæ¯y ¶AZ='èN‡Ký]óøâA&7T4 ¯f?·¿sÖ1€ä*àó(FVeù®|•/á>Ó²{›u˜<ðWp÷_®Î ³Àê&î:kuêþ†ïZm÷/ƒkß–uÚÈÓO#ûÉJjã›E6Ò2‹ƒ¯ÜâE«ýÏr‚·M%cvñZô á ¾ªwÙ«=Ìžnv_F/ñ}„½Ž¹G¡6³± Ð\öŸàÌ»<ý7T5 ßÅ.^ üþSÎò^v‘ò%{Wåø/{ \þJßÀñ´sÌ<ëUPÚÞû³G> §ïóBÛPSÂýŸ„>³ºf #à:õN<µ ðvBö®rü#Ø÷íÖ7¯Go³ÐW†R|ñf$´Äù1<þPŽ—ÕÕA6æo~ê)€äràu«‚ÎD%ßÌñô›äµÙô1<"¾Ž!)8ÙðÛ *ù±¼ç“­ãèsh¯“ƒü®º‰ûŸÞAÈЪ˜ ‚Ï…¤æß§!”ñg?HªžÔ&ö)ß‚®[X`ˆ„w¯ÝrÈ/s%ŽÿH;–ÜuƒeÜÓ5ì >1ÓM§µ ›dêLÎ郷¶¾ï󯔛×?ñdý `ùQŠ«<ÿ<°ý@ÖÀùzÖmv´j£Ë·g¨h!.{ šMé]çÇôØ­~V’jï€ÂoÚ2ÈAÎCxu[Û?z䆷6é£:ØÏõÿþÔ/XõT„ºVɾ·)ÝLÖéèepâÕ¾¼Zò~uo 8¾ŸˆñUiŒ]™5s¦[§Í²‘  ¼VQq}R[kz^Ùv8Æ®„“¬~öqb¾øõM€$ÂñC«˜®Aÿƒ»›4bµy= èë÷µ7]á@ŸËàêÙÌä>žy½÷%Îm¿~‰ZAZðCrª›ˆ7—,×pU[ \9O"ñ#} Z6JãÛ1\êÛÔúÀ‚Ïuè =6ŠÄú±¸ª®€á*R®nß\^Á´ÍBî[C¥O&u°Ä“ƒ¤ÞæösÔç<à•êž Ú håÇxêÑÕ×ö«¤¼bS ¿J‰E^Ú¶m€ÂDFÿv}Ân7`뉭×ídÓµ†üP¿U;96krYy/jãL‚ˆcÓæ{~ý„—ʯr“úÙþ×,Z,p†KÛÒDƒ™÷/kx'ííT@”uhz?­²¤•ÉõÏÕºÌR–>ï¥ç=Z?Æ~šÙJ3 ¹”®îØ(¾ƒ€ -ýçŠ ¦ý \õ ü^‚^º}V´¿ÿh°?ˆ…Êi#ή€ô ȵB)?Öq¥4ß±)Å{¸¡£F†£YÙ7]Ÿ d«ì{7 9rùQŸ ìÇLüE%€¬ã÷e-÷hüXK¥½b)n”÷¨ ?ãÒ?ÜÌ8!:&ºÂ8·ÚR]„,}²C¿&áIÄøû/Nd ,½ìÿ$óÒå(@Öâ£^ë•Ír²9Ú/­ *ìüŒ <¸m3 {¦ªÙR+`-,Ðîûqîd¨Q‘W¡ è¥èçX|܇©.õ ðd?éÃ/p=2Ž*“ÕF:r9 á⎧𱳳,­è$=´\­Q“W™éOËúe¥‚6Þ„ œ—EÒ,ª:•“Yägæ¯éÇ•ñJÑI›»Ýgs7ò*¦Ì"Õ%½#x!/#Ïý½—ºïÆÑŒtÌ¿«ì—›!µF!·{/dùæ úthK[Ì“Ðú•#'F÷÷Oÿé¢l}E5”¥ì}éÃÈ$*µéeSÚ– ¤uìW~F3Bqè½^qÙŽPhøJ¨f7m»§c¥O7‘Dym’lH'>Sü_mL~ ûM¾¨¿Ï>”u‘iÿŠ2°RTZg÷ØÅAl$ÐlÚšSèĶÚ:žj•ÓX dûÆÆPäºVàÒ²¾K;£³§“—-œ ‚Ég¶‚σ¡K`ì2¤0¹!_² ‹ *Ý£©#›´±ðˆg#w^ÜÂÕa×·"—~o“râËðÀ_d×O[³ŠÒ¢ÝÙXwu¨sÀØÆEŽa‚kû¬dƒt¾5RmB:éðºñ…p¢¡e:.î€×!»®ó¡™É­-³·á©Âì~ë °ø˜7IÉâR¾J«PÚíÁÛë˜~0£ö +c) HüX« ÐÌEÊðÆ@S¢¹ÝMµ@}¹,º–x\Ä·_ç·{Zwu¿¬û߃ì¹ò#KfuÃÛ®×KsG žõÿH+­ë4„¯3&‰²ûïvïZ¡j3+è_ÚçDüX«.YTÉlà«6,f¶Éä[³nˆÏjwzm’v߀ìÿ¤´#úÙ6©D¡fî_Ny»•_T.‹PRœèƒYT¨,Æo.+·€@ƒ«µÎVBfµÑµ:ÄåÍBMfÀLdÙ±áˆKi·O¥j —¾wáwgNÑÙ9›HÙfîc²Aq+ë‘E.Êx¶°­?Œgý÷át3£4‡€ñLeZßók¾ê üÆQ; ¹m3UÍhUJ»|Ì­sÈ•oð¶ÞÉÙ;•Lk˜?•'ü}§ žúD·fDMè…•Cr#=”_¡lâC?,ç“[@üwÓu„ÁÁ:°ý( ^÷¥L{ç¤ù½½YUËÁ³~ÙuâÎþ9„zú¾¬d2o¼iý»Fö/È"“ˆ‘®€ö~„ªŸñ¬ââÕ ºäÆ~ŒW†}jýLÐß|fɶaë”PMÊú$Kð5×ü:†hòcþõ…ß‹=︳^øYÏß™¯gÚ¿¶œÙì†ã–ø ~ F.Fú(+«ÊT¶H¦Ê’K®uÌûåÔ'—wJéf’U&³ tË+#ŽlP= ¹±ÎN  ``¸mÏÁ^ô½^óEÖÞFjøIÎÉןÚ()‡ÅG²}Îdioݤ©â's@‘Ë}øß- A•ŸÈê *K¨µñcK­ož=¬úë ì7 œCVXšNþ@’±@n‚–‰¡ êK rñ÷áL¬í_èZgI6‡r5H*(»Þu‡ÉâL©çŒ¥A¾s9 ϰzâ«…hÄû Ñ(nè|ÄIW|)æY6)®¶ ¦f”Ô'ýØj–wGëDý‚ ™ÛH˜ÆÏJËw~ãoe6Kè˜V¯_(íô´¶ýyØÑ˲ôgo'Yé%)zîaôì=0wj§²L\²öZ€XЏ+ tŸÓ§Pi ÎÜé=ûê)OÿÙ¢¾ËáŸò9 ±0r.òϧºÙÿ:,>êY¥šEÍ«A@ìÇ´“ó·õLfæNUùŽ6‡¾@å(ÏoB²õ“-¢aÀáv½'ºr…Òfî0úèÿ¹û½—¬š6î”oˆÆý¸&®Çv#½¶ŸÑjö(?á·zr™þ›MInbùù&žˆt/)ƒ®œ„Ú”¿n}f¹Ò×\$ªmµýíBëÖ篲¡ANSeÍh‹/Ð-4¬Á)ˆÆ—S»ùqÿ … ìð%¸>´_kMxüVxôo¼Ðt൦~’9?/ÏÖÛ'ŸÚÖðs¼¢ ìy/Á:éIÿ‡žºÃS{Zñt¬²}m¤Q°0p¾Eqvø²ÞϧÑÜC™ç/O³Ô_ذ;õÓ«gw‹®<)Í2ÍéÀORãWxÍ…-6½—)¨Ö@ÏB0àßkL·º”¤LH8y<ò‰,SÃô!¿«gÃVª6M[M‰aàÒ,O‘ 罘$·é5‹YLùq˜½t*÷ûŽÜæ¡ ¹]PÜÎ";¿ « =¯m\ Ó÷x³R9•åš1™÷c¸ŠÅ:Äÿap<§èkíý¾\è¬Åøá¥OwË®ò!õÞ~´AJ{±¢‘Î' ŸA=þ}(™ƒSÿ‹‡ÁUÛäŸء› ºå÷H 7c×x;=rÉöoÃ¥q÷{A)…™üB6ã¹åG›ì\v*`ôY¾­¬´—tÛóz_…®MBåqŸ­žð Åz6°ó~캅Ýí¢0/£‡ûéZ["H¸¯ãª.~Aƒ LL´Á&k{”H5fúî¬ï8}¤ÓH¶¶mæt¶¿À—MŽtß+H$Z¦Ú.ÚTÃì]¾ìò\lÚczœRD¶Šš¾ LÊA2íÙ)ž]Þ›¸×ü‰v¾@šÉjÃà¸Å)v¬Bœê‘RdË­8puDœO+tmšl¬Ôfö>¢¾é I ƒß ¥½àbdÏK©À%ýÌ_ ˆªÇ`ö>oqæËœò4/Ùü‡âE°ëÅþÙ¢Qâó^Fbé]ËP!ÁÂ=Þû×Yô‚Oé/ÕÛ. Ô@Ê©µ0@ÿi´·pÅ¡¥u- ^‹T@££Æ:‡s‚“ö§å£­ ´tÁk\³ímI•ÚL0Y=bàrØ÷*¼pÈž—P{qšàÄuü]'‚s`”#8ýÏ~tÓE˜ýjVž®{[=r œ÷rß½ ‘î{U5Œ³iïk“`ÎÜéKᵓ0{·_ôÁµÇ~Ç›Sâ-ýEkb ònCñâ5 _5ΗHUº€s‚8›}L­¢8' ÉÐå„Ó‡|såÎWöTMjÒ`@á»Fž½D·n׋)>—$®gi²î䡃ˆ|ù^Ÿö Špês>3Ùõ·]C—{³ìù”Ã=¸¤Þ½ #>²É—‚rÖ®wüï½æë‰Õ‡çß™ÝÖï¼ÀµW5Ÿ#%E5}¯[Abe~ÚUÁ c♬×CšªM™\›Å­„»¿Ægà¶_ë+ˆsw{Ÿ Q41y† ¿.„âžå1?A2~‹Áy¤õ¸¿!š¢ÌcÎÜásúÕS¾kâE0x ”ÎÏÌR ƒRßþí,ª1$©·OB­¨©U3õàù#¾¼lÚ¶¬ ÉSR4Ÿ[‹H×Z¾ áA W¬Jõ„Ã/¦0x ª>…‘„ĹŽs@Q [QÃ×3¨jö^g—Î˺ƒë™º†Ëëù5ü†h7ô*…˨Ú×úª” 4ù™/úœ¿}I÷¢Îæÿe`8Œ¾Šrñ2j‰B¤Þsʃˆ„9 s_ƒê¤¿öÉ¿oÌëo¯Íì~»”°·ÿ¢Ö¶Œüš ~–²ü ŸÆpEÏ„P;p,]7B0w/ìú·˜òJÛ.bºîúšŠsT“˜ Ê7]®4˜{mTªëä£Õ•FÁcÁ,áôW—×Ö!‹Án¦kAÓ"•þÖ XQ{*† •¿æ[Èuý¹j{•v»ùÍÿo€„»¨ò¥M€º‰X~ ¹ºk›x§÷Ê›gŒc>¼ˆZ­îg|õMÖ½ô¹?ˆ@†Œç«ä澚y¡Á’oálJ’.ïz©úúýæH†JEÆ’Ã>ÕÀ‘?…éV;~ë5²äC|d­k®-ÐÚ÷ðqN¯Ú½S*¸™ÎÀ©/@nS9Êöp”"µ–Ô¹ 9m‡sé3Ö‘¤ì,”),ÜéoÎÖá‰ÿíµÔøý.­móý^§u$Ö1XˆØÁcèÊcy»ìoYUSé•ßïÖðéµÿ4–¯G”ë€z+£ùØôs³ªé|ô|,(Q¨aǀ‰¦Öøfž©%µŽb!ÇÞÒ"…ʾÊ' <øk0ÿ5Ÿù3D<0×rý4µX'Œ 䨩¡ÊG!ƒ©/ÀC¿½<êë©©´{š©·®}àõ3€ë”r šU×_¬ Ü÷K«r §²k8À¢ˆ“ÔaƒÏ$M‰“‹bb8ÏÞÂÂê£>É”ÌÀ½ï„éo€)ùúAÇ ^ }_?Eë€óFBv¨£¨xÚwúG¸÷½>a©ÛŒ¼Zqö2¥ÍŒšRÆñ{ë㺠~š{>I¸h¦­©»áÞ_ó·À(ǹp[H†Ô’”$MIí“?‚O­0T*pÉxÀDpÌ@4 ÷ÁÝ?s™]VÆoïnò8¡¯ë×’Ä÷¸¸d[ʰóµ‚pûK¸÷—[ã}Õ½”gåkï®|\ýôúö Xo¸|¤¼ÍËÑ µ8'ªÏ×G?:ÏýE dP&¹lû'˜œY¤'(”w¼×â}/ÕÜ}Eod ÈŽ¡€ápÑgUàiÿèŸÁ‘_õ˜F•Ùd1¿q1¤IŠ[é¡6]?C¶ °sHSRó~õð Õ)¸ïðøß-ƒž^¿ë#äëTô™¿yà}OF„O êg¸_~›ðæ–R1=h¬™Žý­o~8ð.ØG`ËìŒØ>0ÈÔ¢ãÌBr¥FêR”øµ"y&Ë££”" Š…<#9¶ J¦îC”OÏòöþô?/'Q–îÑxV2Î q’ µZ*7(¥0AÀ@©ÀØ@Žm%MÁÔ|r ã{NÜ ÷¿·5ÍÛ΃W]BéRlH.æÃêÍ<ð”€ï#æövÌv{Pœü'X|<ëçá¼&OÞÕÙ;bØ3:H%b¡š°XK©Ç)Ij[‚=c Qh(D¹€R^“J’¬4ðmió÷Ãc†ãiÔÍWß“=tˆ6†( ÉEQPÈ… æ Avýlmú²îì¿Âƒ„“Ÿn,àÜyŠüJÚï”âm oû‘{rÚß ƒk>äwx=ÿkÕ¬•^¶¬±4_sü»ýF¸äGaÇ |ÜÜ(ù*²I^›[ –V‘F“IÏ+íûêf¾ÿL~ât‡'wÀ¶຿ N…8ñ××J²µ„g’Fi;ž3wÀcS·Ü»ßL÷tø+°´ì®Ð~=isŸöý¯êO~ãÈÙé0äIø¢l÷ÐnÔ߹ͧ?ÓŸ‡á°ëe°ó;|.·m)K§VfûDXê± ÚwG%=„/K–h ËKÔøúFËjÓ_—ßç>Šoë®üwq¡e îµA¿Õ³µ°ÁZp–>ÿ®únš–ºei=jX^£^¿öf§~Ão-­VÑM³C²É•ªÁo”ö?ôï¯ Y£eÛép …`y“z=Ü,múÆîò¼€÷·D혠` piçˆ`=ÎàzOê—ú× Ͽú Tmk¨Û^ó!åçÔá–͔Ϧ@þ÷ðöŽDͯw@n÷röo-ô¯ž¤àéùëç½vPêÃÂTg­oþ{Ôð ›-›-À„¼Æ†ÝjÜCA´¥9xjƒ…¿U>€4¹ññ”ŸàzÚ|!åíê‡7Wó·éïóf“ã4¹¥4h;á`h?äw·‚€>ý€Í@?Ñ@³ðkÇaþpËj2«XÀŽº­ó¶àõüæVÉDmáï¨âÕ"Çß ^5\â7 ؾT7è”ѺØ/êÐ<ºkÂV1@ÛÏd7µø Ì?Ü™òùý„©¹2oÞý!ù‹Êוê`>- ½ï‚—˜Ç®—Ûú]7|Ë>ù­ Ïå$]BC€Òv¹Ö7iHÚ»eêl0*ðõ‰Ù¯@yª³ÖgÂOëÜÿåÇÔ›^ø¿xÛyƒw¨£~&[M_<Ñl!è ÎöŽ)üôó§Ä¥ÿråΙóKE.ìš(J*?ávÈíÈ6²º}Ø´“HŸg¯ï¨.ÿîùÚ·’Q;3·B­ÒlY¹aj–ÏÝòÙ‹ßòº?á=Ï¿èÎ çÜ©S§Ü3‰ öïßÑŽ;òI’ ®†GóéŽ÷¾ôË?xã%õï r;š„‡”΃‘ë ·=Ûh½©à¾RÂ~^6ñi˜ù(?ÞÝÙ ©S¾í¡Â_½ãÓÏÿèL-85ž¯Î…a8êÔ©>|8Ý ˜­ÒþmÛ¶éÑÑÑ ^¯çŒ1żއ” ‡?q×Þ©ãsÑÌÅcÓ;F‡êÎóP½ì‚ï³Ï/uïø3Êzú£å×Se§îãTý¼ŸófÉä 9³wÀôíP›ï HíGüÈ)žøÀ?\úW·Üþì/sR/¨j])U¯×ëq©TJkµš=sæÌ–0@ÀÎ9%"ÊFCŒ—(|úÁ]SwÿǺú‘k¾ÿê“—Œ µÝ­ÑH9÷,>àŽ~¾_©#ȴ̶7½úïúñÈ–ß#P9s_…rÓ:~ÍóüizÀìñÇ¿¾ó¡|ýÂ;çjáé‰RµF;ë”sNmµ<¶KC©´âÄÉ`dUâ´û;.{ì3ìIøº÷~çåóÃùº­ÔäÅ£~ð#`àx6öùÆO[ö£DÖȦ娆DµŸŽžÎCåQX¼ïôóûdÅ=­¼ŒZ÷wÍýÑ—.=öðôÀù(uƒ‘UN¥qà©Y,{KE‘h£mš¤ÖZkƒ HÄJŒ¡n 6¥ÉãóÅ…›?ýÜ'>~h¶òÚëûÖ‹«ù\>Û¯H:xþ 0s'ÌÞ™U÷ú•< A´Ë”<(TÐ= h,3cËÞäÄ' zªBíXkOó"X+·wÕP«"_|¸Pû“/_:}ÏÉ‘£ea Jñ ÂÔÅI¬•¤ijs6_ÈÛÀ[º/Ζ…0qG…B!¯µÔZDQ´Ý:»Øì4ÚLã"2š¤z@Åçìœ-}ßs¸aÿ|~h kÑ>BÁ&Aà7¤2C`†}ß> L¶p¥õMË`ç| y2ç»uÚcbÿì÷çq·ª}â_/X¼÷äpY •0p‹J©à´uv8 œ0ÚœŠãxÊ97ëœ[¨V«µ(ŠâC‡Ù­·4píµ×†ù|>W«ÕJQ 9qcÀ80¡•ÞlÏþ=êÄ j¥Kqª Ω܅Ûó/ºâdéEÏ:^¸h;¡ iõ´U|B?A×®61|S„" ™"¹õÞÝÕ[ïÛY~äÌ@Mk©G«:qe­ô0œ¦œ¸SÀ$pZ+=Çñ|>Ÿ/×jµúW¾ò•d«ò[™ Ôû÷ï7I’äJ¥R>Š¢(І‚ ³ÎnƵÒãJ©1`TD†€A R§r‰5á`¾ž»æ¼¹ü û—¾å‚¹ü®QÕØMέ}€‚>„½2_ߨ¶'fH¿üØpí¶v—ï||¸¶PËÕCc“@K¿ŠDXPJÍ3"2íÄNmΤi:Çñ|Ç‹år¹†aýðáÃès#ƒ§ …BA†‡‡ÓJ¥’”J¥*`R›­´râĉ³F™o#ËÀ"0 ”*††|hl>NMtûCãámnÇêá³v-äŸwÁTñÀÞÓù Ç%,b–rë«¢Óöõí>ÓÜ­lÊØGN«øÐ±ñÚ×Ý^¹÷Ä`mz1—(%I¸¤ÙìþUMD*Ù3,óÀ¬7Lk¥g¬³sa–Ã0¬Öëõd||<ãxK¿§¢¤½oß¾ T*ÃÃÃÑââbaxx¸ 8qCZéa¥Ô°uvØh3 dg (É9'.ekuZ‚\ ÁŽ¡jtñÄBþY»çóçoŸÍí®F;Gò9L.DA¶¾YÐ! ÌÚ´Ó©'H­Ž=9Kzb®?65R¿÷øPíáÉÁÚ©ùB\OURc\ªÄ¦Zé¨+¥š_mñ¢uvÞh3'"sNÜœVzXœ››+ Tçææâr¹œ=z4Ý*íßj,×öí3 T«Õ|.—+†aXL’d ÃÁ†à•R¿E)ŠHA)•r"’SJE"få” X«tšj£µ Š‘3ùКm¥8®‡Cù8,$¦sm{Æ«uíª¡¯Eéé¹\r¦¥µÄØJ¬­s: g(I=(¥‰3Á×E¤¦”ª*¥* ‘Å’$YÃp1I’J½^¯ …Z“ð·¬ðT@51)•JˆD¥R) Ã0g­-FQTpâŠÎº¢6º¤•.'®h´)àw-ÉgÂD$RJE _?ûkD$e¬ (åZœRNPÖïä´Ê%¢¢´ˆÖ8­DŒòSŽ”Ré²! ÒLð±R*‘†éªYg«Zé Puâ*κ²6º¢•®Äq\5ÆT’$©—ËåX)µRøÏX° û÷ï×…B!‚ ‘0—ÏE rµZ-¯”Êçr¹|Ç…0 óišæ33SZåÄI¤´Êi¥# tâÂ&Zi¥”­”Ò"¢8¥•Ö팀ç´Ò¢”r"ⲿ°Îo+²¤ùZéHœ¸XœÔ•V±8©ã—ªAPK’¤EQµ^¯×D¤–Ïçk©MëõZ=VJ%iš¦Õj5=|ø°{*„ÿT Å7?pà€žœœ4###&Š¢†‡¹\. Ã0J’$§µÎA¥iš3ÆDÖÚÈ9q‘8 E$ ‚ È@h¥À8q0ZiãÄi­´vâü¼!Õ:é߉𙹠.ºÕJ7@©V:IÓ4UJÅJ«D+[kccLl­ƒ ¨§i;çêaÖ“$‰ëõzœ1GÇq:;;k'&&ì¡C‡íg<£ÀŠ:Ÿ:pà€j¡X,­uàœ µÖA>Ÿs¡Š“Ð9…aKBo>µÒµÖÆ£­µZiå×ÿÐFYgÛúFgõ {:±Æg­u€5Æ, ù̘ M’$ÑZ7‘h­“Z­–8çR­uâœK+•Šm|Cà®[õá™ €ŽfaaaAOLLèùùyS,M.—3J© £” €Àc€@kmêõz µ6÷•RÆ:«6:MScŒÑNœ2ÚhQNœ'-Ï®´’ŒþÅ:ë´Òb­uAXë¬3Ú8±ÖZ ¤Î9›ËåRç¼ih¼/"iš¦VDÒz½n+•в“““nppÐ=•t6`%#9Š:I511¡«ÕªÔaš8ŽuÆƤIª£(ÒõzÝh­ˆ(­µ ‚@§iªµÑFœ(çœ ÃpIø"+ ”4@$‰h­Ei%Î:KÓÔ9ç¬RJ2áÛ8Ž]Φ֦ij£(rI’Ø……W(Üää¤ ÃPŽ=ÚìÙ?¥ÖT»$b—(8511¡555¥vìØ¡­µªT*éJ¥¢Ó4UÆíœÓaj›ZDZÖF+@ÅõX;çT.—SI’øéŸÊ®Zk±X´ÖR¯×Ek-A8'Nâ8–0 Œ¤µÔYk]ÇÎ9'ÅbÑÕëug­•©©)—Ïç'N§}œUZw¶æ©033£B˜˜Ðq+€Z­¦'&&HÓT5Nk­ly^k­Â; -BYXXcŒA°tNNN’Ïç]£ª999éÂ0”ÑÑQwèÐ!º[Îöæiº•w8 ªÕªªÕjKŸ¦©ؽ{·heåE‘?~\‚À—fÃ0”|>/…BA2®[ùˆ³]ðãÿ'kÂi8"IIEND®B`‚eric-6.0.8/eric/icons/default/chatKickUser.png0000644000175000017500000000234412342633754020306 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs¯¯^‘tIMEÙ 8,)„ÓbKGDÿÿÿ ½§“dIDAT8Ë¥”yLÓgÇ dAɈ»§À¢‚‹Ã!l+.Cª¡È®ŠÜÁB¡à¯\åj +¥´\[-¬0G¥ð“à ´²qeƆîpjt,ìøËxD’áwoYL–3È›<É/ïïy?ï“ïû<_ŠzÉJ }#.((7)$„Ɉ$%eŸ·¦¶²r“’ö%‡†ÞI‰Auq1ú4 kµ¨¯¨¸Uš•eÿJPé¹sftJÊ©šFo[æçæ°|ÿ>Ƈ‡Q-M¥§›m¬V*ݼèhT—”¬U;=1›óó˜1¡*/‡â(Úl¶ßnÚÚyáÂ[íÍÍÇ“‰+$ƒPSV†VÔ¶·cˆ8[ŸTŠÞö˜<â £³3®:9áú šl¬~­ßjZW95äplPr’“לØ$ÔÞÑÜŒ–˜(Lú»`ÒÜ Š‚‘Äì.\8à€'Û,°ÁA±Ý»½/€}ÜÝÍNøúºÔËd­#ýýKDšÕI½#äñÔÞ,ÜJä"cÿÞÕöÚÚ¥‰DMrIyž2|©¥åDEíXWWWŠÍbYc±ÉAËù| RÙîê:éèEþ9˜r¼þ;dV¯Z¸çmÍsè?6Æp@L~&IEND®B`‚eric-6.0.8/eric/icons/default/fileShortcuts.png0000644000175000017500000000132012342633754020555 0ustar piotrpiotr‰PNG  IHDRójœ PPLTEÿÿÿ!!!999………†††‹‹‹Œ’’’îîîðððÒÒÒ¥¥¥¯¯¯¸¸¸¼¼¼½½½¾¾¾ÀÀÀÁÁÁÂÂÂÃÃÃÅÅÅÆÆÆÇÇÇÈÈÈÈÉÉÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÓÓÓÓÔÔÔÕÕÕÕÖÖÖÖÖÖ×××××ØØØÙÙÙÛÛÛÜÜÜÝÝÝÞÞÞÞßßßßßßàààààáááâââãããäääåååæææççççèèéêêêêêêëëëëëëììììììííííííîîîîîîïïïïïïððððððññññññòòòòòòóóóóóóôôôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøøøùøùùùùùùúúúúúúûûûûûüüüýýýþþþÿÿÿƒž¹½tRNS#&MS\l¦¦±±ºøùþ>ôz#IDATÓm‘KNA„«ª{x„G"1Ä„+½ˆ'ñbÅ–ºr!‚‘h"2Î0LO· ¦ÑjùåOU¥~Çd4Ì?è·€¹Î%º1Öo”•DŠ z{ˆV2’öX5¦ý,è˜ÀY…K HˤãÓNÿÕ´w‹FÄ´ö©5Ø GÍçnß ÑDP‘‡àl–wÅC ^à'¾4ÓP2^sÒ9ÞΧá´OÖÞ֮ќx³úrÉáZJòÙ<µiX®¯ƒ÷¨ò<ɪê§íØæB"‰ê;۽߅P”DÕf5kÍ\ô;'‰"›_%å¶ŠMö‹ûÝ–ãǼŒ‘µ‚w —•ˆSµ+‘¦7.²²6üû´à\Ì9¦G h­[ÃIEND®B`‚eric-6.0.8/eric/icons/default/fileMultiProject.png0000644000175000017500000000126712342633754021212 0ustar piotrpiotr‰PNG  IHDRójœ nPLTE```cccNNNPPPttteeefffŸŸŸ›››yyyŸŸŸ¢¢¢£££¤¤¤¦¦¦¨¨¨©©©ªªª«««¥¥¥………ÇÇÇÈÈÈ»»»½½½@†ßAƒ×BˆàD‰ßE‰àFŠà\‹Ã^œì_•Öd¦ÿh©ÿjªÿlšÒl«ÿvžÐx™Ä|ˆ—€¶ì€¶ÿ§Ð‚¨×ƒ—ƒ¦Ò†’¡†•¦‡¯Úˆ¬Ðˆ­Þˆ®à‰™¢Œ—ŸŒºìÆÿš¦¹ÓÄÿ‘Êÿ’ž®’´Ð“©Ã”´à•²È•¸Ð—¹Ð—Çì˜Éÿ™«Ä™·ßš¸à›Í쟭¶Ÿ¸ÖŸ¹È »ß¡Ò줻ץÚÿ¦Åé§±¹§»Ç©±·©¼Õ©½ÉªÁÞªÄÚ«Òÿ¬»Ç­ßÿ®ÀÕ®âÿ¯Ýÿ°²³°ÉÞ±Â×±ÃÕ³æÿµÆÕ¶ÌÞ¶çÿ·ÈÕ·×ÿ¸ÉÕ¸Ñ麺º»»»»âÿ½ÚÿÂÉÌÅäÿËÍÏËëÿÌÎÏÌÐÒÍÐÒÛÛÛ!–-ntRNS()Uac‡‡šœœœœœœœœœÓØÛÜýýjòø ÝIDATÓc```bãvFdÀ,^ ,(Â’y /ʼn"Ì£¨¥]Rfàéă"Ì+­fâbaé`$†b>ŸŒ’Žm†ùüA©áùæ (›'aš/ §Ši¾ ¬ŠG,¦ùBòªÖa˜æ +hØGbš/¢®iê 3ß?:Û‹,ÌÊÅÅ% 5ß'ÐÝJŸî˜ùY9éñ)üpa˜ùå6Q~pa˜ùɹ…a˜ù¥ÅÙÞ‚(! 2?.31ÆYEd~BZ°¹0Š0È|W7G=Caù`ÀÊÀ‡~Cw°—IEND®B`‚eric-6.0.8/eric/icons/default/ircConnect.png0000644000175000017500000000250712342633755020017 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÜ  =“ÊbKGDÿÿÿ ½§“ÔIDATÁyX“ðïËœäõäÓ!ü¥e‚ó)¯2CÉ$CT¹!ÃÁ86Ç5¨„r EÆ! QƒGAóÁ)úP&b "È©"*ﯥàC˜,Á‰ò®1e=#8~‰q—×3ñ™j½´Œì©ñCZ–åÁ¤#«0Öñà‘~ÿ'UQ옖‘Õ- ;@o²=¥î²*ÿ!(.õ½Ðh©iâ±\ßLE~G´DÚ´déòõxëØ Œ¬ªß±¯¤!Aª¹wòFlPn­8]UV¬CY9 GD5[@§íñÆÛ"ƒY`Fq7'{eÖÆÊjÛ{ýÜMé—:I~¥‡’jÚhÉU*¯¬!µJIÛì3p¡³Ààmã­Ô`”…Xc!,l¸YÚ8œv©“2‰’µD)Úa’5EÔ Rˆò2‰%úl¬­vaÄ´·¦1Ë,¤cÍÛàãªi|š¤}FÂâ;/b*;XiÝÐpxÍŸlDõ»ï2ËFÿÔK_ù¾€)<†gí‚×–¹Db”õóf<'‰3€ùß*¸q®›Âj†X?u…ºÏ†U°Âsý¬ÿÙ'tðò y*ª¸&ÐᚬcÜã‹ð’™¯ Ûå×üÃÔŸ¯½Sqça@RA…"'«]šYJþ¥-xn€¼T·Y_Í=Ö÷ô#Ö»¼D•=d“W À:sVØ2kÜCñÒìùKŒ°‹ÌÝ/Ì¿JIÚg}º•¤jòót½aáPî­yØïsºŸ\ra=Tͬ[i7»ûT/ÙD©®ú‹ c¸r³ž¹Û^`‹TQΉg<¥gþèI¾ØI!¥wÙðê¿ü o ™»G`åÇöÁÉ; [ɳ¬¶Êo°[•ͬC~ ­̨#è|jÃ|î ,2gð çëàô#’ª.J»I[ÕAA%wIXù˜v¶´,´ìÝao“#×ÐîâVr*êdm³#‹ð¢¦÷š~@#V¸Š†F ^áZîIH .@’º[7ÄFžigùê»Ä¯xD®ÊÛO%éêÁlÙáçâ”®Mò_Y›4--v‘Äa"³ç/fð wµoJ2¿ô…U’¨ªŸ ¯`E?¶±^ùM´ëd7¹å6’‹(þÞÜéZ䕺Ò÷¨f–ÁË1!Îl#xN1ûóî_e?ñOõ°üŠ¾á€³Ù=%-䦸Ež¯K®Âs‰ `&Fl+𚣣£txïÂpトò e=9©;黊'äUÖEÞå½äSÑÇzݧíª{´Q¦¥U9 Œñ —ã_”¹Ç¹Ðá ×äSåù ÄϪ£mª6rÕt‘kq¹—õ’kQ;YE—üþ‰cxòŒ9óV`œ‘'0¡Ðˆh‘"/ŸJ U›ðhéÎxíª ã7Mä7ÍE9Í_ø½öŽÑgöŒ³ÄΊŠOq8*ÏîGDµÚmsP[[®Xî,+ŽþŒõý™޾9€iÇR‚ ù„_&¦鎎‘Þž;ïCKsÌĈ£–9 ‘K„ÿdk·eƒ›»Göc“M˜$«0%&cÓ‰ˆ!"Œâp§b”Þ”©X`å‚Éúd£^>½4FçIEND®B`‚eric-6.0.8/eric/icons/default/filePython2.png0000644000175000017500000000203712342633754020130 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<@PLTEÿÿÿ$$$***883999DDD¿¿¿ÆÆÆÎÎÍÏÏÎÐÐÏÑÑÐ/f”/f•2i˜2j™3k™4mœ5j—5nœ5n5ož6mš6qŸ7qŸ7r 8r¡8s¢9t£9u£9u¤:v¥;w¦z©>{ª?{«?|¬@|­AtžA}®A~¯B¯C€±D‚³E‚³FwŸF„µY’½\Œ±e–»f—½išÀx£Æ{Ÿ½|¦Ç°Ê”³Ë•µÏ™´Éœ¹Ðž¹Ï±ÃÓ±ÄÔ¸ÌÛ»ËÙ¿ÏÜÃÒÞÄÄÄÉ¿˜ÉÖàÊÊËË×àÎÎÎÔ·OÖµ=ÖÖÖßàááââáâããäääåååææææææççæêíçèèèèèèééèéêééééêêêêêêëëêëìëëëëììììííííííîíîîíïðîîîîïïïïïïððððððññññññòòòòòòóóóñçóóðóóóóôôôå¬ôïÖôðÜôòçôôôôôõôõõõíÈõïÛõðÖõôïõõõöÔ\öç¢öõñööö÷Ýs÷Þ€÷áƒ÷ä‡÷å’÷æ•÷æ™÷÷÷øÎ:øÐ@øÐCøÑAøÑCøÒDøÓGøÓHøÔJøÔKøÔRøÕNøÕQøÖOøÖQø×RøØUøØVøØføÙWøÙXøÙYøÙ`øÚZøÚ[øÛ\øÛ]øÛ^øÜ_øÜ`øÜaøÝcøÝ|øÞføßgøßhøßmøàjøámøánøáoøøøùùùúúú•ÿ§øtRNS"1589;=Gäæ÷÷úúVi #4IDATÓmѱJAàæö6‰AH¢ HÐBAˆ ÁJð•¢¾ƒ¯àØû¶B°A4`N%1w3»·ÙmÄ­–ŸùÙàßCÙ?&ÈG“Œ˜ˆˆÎΠ×b©LÄÜ`dLLó™#»™GŠLEs*²8`pȈ3q…S}³¹5­˜ff³“±¹•`Àh&þž8'"ê)7ʃÈTx¯ªêêm{î)qð*ª®ÞêXÑ6Ò ºÞ;„…])«~JgA¥{Ôn!ìÍ~”RšÚïºÖÖª_"n5q¾k¤3ô"¥ç7Â’ÑØ·P­ž[Ÿ¾æk+ °e%=Wœ•_>>'žeÕÀ•jü@954V\Ê"U²zŽ—0Ò‘ÃñxåMåþÛ¥Öñò Š\‡e~‘îIEND®B`‚eric-6.0.8/eric/icons/default/windowFullscreen.png0000644000175000017500000000133612342633755021261 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î</PLTEÿÿÿ¶¶¶ïïðøøøúúúœ°@@±CC¶OO·PP·{{ºººÃÃÃÄppÄqqÅÅÆÇxxÉÉÊÊÊËËËÌÍÍÎÎ::ÏÏÐÏÏÑÑÑÒÒ¾ÀÓÓÔÓÓÕÔ|}Ô––Ô±²ÔÔÕÔÔÖÕÕÖÖÖ×××ØØØÙØØÚÙÙÚÙÙÛÚÚÛÜÜÝÝÝÞÞ°°ÞÞÞÞÞßß²²ßßßßßàààááááááâââããããäÔÕääååÞßåååååæææçççèèèéêêêêêëëëìììíîîïðððððñóóôøïïùððùùùýùùýûûÿÿÿ²›étRNS !#)+34<>FIMNPRSUüüýý_ñÿ÷IDATÓc`Ç¢ì "²‰@F„A<Î/ |ƒ‚}MýcÅÄcHØÝ.ºØ½£ ŽTB÷¼’†8ƒˆtXXH€¯—›“½•±¡¾®Ž–†”ŽHØXØ8¹yù…%$Å„øx¸8X™Ït7[‘¤¼IEND®B`‚eric-6.0.8/eric/icons/default/virustotal.png0000644000175000017500000000200112342633755020131 0ustar piotrpiotr‰PNG  IHDRKÖûlsRGB®Îé pHYsˆˆÈ¥†tIMEÛ†’K~“IDAT8Ëm”Oh\UÆ¿sîŸ÷æÎÌ›4µi©i”b & -!.²h]îu/¢ bE»P7BE´VJ³QDº—.ªàÆÔšEIPªUSš6šjµ¤f’LÞ¼wÏq‘h’‰gqáþù~÷|pïGªªªD„Í5qmÑðÚâú.AP]¥ŽïÝQ±WæsKØÓð”Ï/Ý:>vÝ;C 1PQˆ(3é¹á]¶UÊ#MM'¢”Çîé:yp·0ûÔ&“W«¹|­æCpÎ3ƒÈ;öÎaÃýôý{»’ŽûG'æžÿ溩yÇÔTñʾŒ^¸¯+ªš—KLÈK,¶gܱEÿúص—ÇG––L9J,w•j¡@AŠåâ—gúúWÎ\9~öº ­mD…Dˆ è-D±ÔfÕ«ÏîÉ|‡ÿ£Ÿ\|ç«_±½UDA)rýÎ’Z3džz³Îà:üÞä»_^Fwy‰• ¬”`†êÉ¢™µÁðÔÑý½[‚ïñ7Ï~zf õ€æ ˆ _‚ ª…®ÙÝ»¯Aÿ¿ËE¼pù¦1 &ðêH›-®Õ¾ìSqžiÉ#n IEND®B`‚eric-6.0.8/eric/icons/default/changesetSignVerify.png0000644000175000017500000000220112342633754021665 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs × ×B(›xtIMEÛütƒ:4PLTENNN222}}}´³´_^_HºººÏËÏ^[[M———TÜÜÜ‰ŠŠ×ÔÖNާ¨¨AMâàà”ÕÓÕœPE@›œ D ‡…†°°°gÍÊÍ k ÀÀÀÙרàÝáëè躺º#v#¼»»a £££æãäµ´´æäåsppa$wÌÊËTQS¡N€¼»»IZÇÆÆ¬©©Ù××ÜÚÛ„€€»¸¸Iš<(ˆ"º¸·»¹ºÙØÙJ8L9ÜÚÛ@3>l!Q‚6Q„+¢ŸŸ¨¥¤ÍÌÌD;6‹-¶±±C’6U‰?½¹º4~)M²"W³0_¹2g·Phº3lºRo·es·e~¾{ŒÄt‰ˆ¡œ¬¦¦ÇÄÄÊÇÇC‚3Gs+JÀK¼_¦M`Æc¤Ee°Pg¦2j³-l§Cl¿8mÛ"q³Nu¹Yy·[»i¿f‚ÄZƒ¿i‹Â}Ì‘‘Œ‹’Éz“ŒŒ“”ŒŒ”φ˜‘‘˜ÎŠ™ÎŒ˜˜¢œœ£žž¥žž¦¢¢ªßŸº··½ººÑÏÎÿÿÿ:»(“tRNS  !#$$&,-./0145779<<=>BCDFGIKOOPPRTTTVVY\^`npssyƒ—ššŸ ¢¢¤¬°°±µ»ÆÎÏÔÖØÙåçèéêëðñóöööö÷÷øùùúûûþþþþþþþþþþþþþþþþ€ÛÊDbKGD»Ô¶wL'IDATmÁƒWàßåµ\·ÚÚµŒµlÛ¶mÛ¶mÛË]{½W×÷¡b.ÿÈw‚Ékþ%L²5âJ0¥Ü.ºÉ´ï)ÿ(¹jÔ`ó)J—Kò”ð#òy0˜« +M#„±uých"!tøI8ÅÃYi×UòØN柰¼ pHÇ…O@ègNâ /Î4¹ò÷lµuHX†³!•ðÖâC‚&ò&ôêŠT!¡ßù š… j_oŠA˸È¢RA‰€Þ»óûÐìgc×NólìbZ/§Ïšmñ-§K«ÿhê°Ì¿éxrfÉRÚÕfé›ûC'c.øááž»32º;<Þî‹ßJ·VWÖ—ñWÁö^G˜ ÛBAû®G=»9 †IEND®B`‚eric-6.0.8/eric/icons/default/method_protected.png0000644000175000017500000000116212342633755021255 0ustar piotrpiotr‰PNG  IHDR(-S pHYs  šœtIMEØa|^tEXtCommentCreated with GIMPWPLTE      àáà ÀÀÀÊÊÊÎÎÎŠŠŠÀÁÀdddgggnnn³´³ºººÀ¡.£/¤1ÅÅÅÉÉÉËËË̺MͺKоOпOÒ°4ÓÓÓÔÑfÖÓg×»?ררÖjØØmØÙmÙÙÙÛÛnÜÜÜÝÝÝÞÞÞßßßàáàáÎUáááâÑXãÐVäääæÁ9æææçÃ<éééêêêëëëìËBìÍEíííîîwðððñññõÞYõõõ÷á]øã^ùã^ûédÿúwÿÿ}ÿÿÿÿ‚ÿÿƒÿÿÿöE[ítRNS#**,,.ABBCDIO¸¹Îë÷0yà§bKGDU“¸3«IDATÓMŽUÂ@‡e î>8ÁÝÁ]ï6ZyÝS]5òü¼Æ™Î“«‘ãéÖÉC(%Ê5IÕâ@tI*ÌÏ„ždÜé":ÌñbÜÿ~u¤ï „­•Ãöç÷{5‘Ûh¹I¢çÏ÷k_e,±„TWn÷Ý*õn`ù²Î¢Õj,å$N«½(3Ó‡\sê§‹ µVFìz­êFtêü†Êk+&_IEND®B`‚eric-6.0.8/eric/icons/default/irc128.png0000644000175000017500000003441412342633755016742 0ustar piotrpiotr‰PNG  IHDR€€Ã>aËgAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<8žIDATxÚí½wœ\×uçù½á½ŠÑÈ` ¤¨@‰b˜‘([ö8ìÊÏZ²=žÏzÖ­í9ìh¼ög¼ÎcËrԎǶ,ëcK²W–-ŽlŠ’˜$&€ˆŒn4:§Š/Ü»Ü[U¯ ”Фúáó>ïUºª^ßùpÏ9OXkYß¾q7¹þ¬`}[Àú¶€õmëÛ:Ö·u¬oëXßÖ°¾­`}[Àú¶€õmëÛëwÓk=)„xõ~ã»ö(’´ l¶aÙŠ`èF…@h-u , °ó€ÁØY` k/`ì’ô4Íø,µæggâÌß½.·ì °Xk9øU€·ß(0f ÃíÀí ®GˆìJ@Î]QfçEÄ'2GÑõ\¶†á,ÆǤGIÌAÑW˜_9ÇÔRóõŠW7ÞzýàmÀ=ñf¤Ø‹¥  Æ M P¸=î(qç«/Á ÿ÷‘…¦ßSÜžX÷$ [o«¤ö$iúeóEVê_à…Éq y-âÕ€»®»Ë»A~ ‚·0t„( è“Ð# W@Y@Á½„q;ä%dc¼ÛcX F@ ¨ëö% KjbÕò–ì ±y‚8ù,•Æßplòðš3¯Ü}Cˆ1ïñ/‘â~,¤€µN“{ +Ø aP:¡+ 2;S¯ dHoXâšâa¹Jº€]%D6a®±ÄB³Âd}–¥¨BÝD¤iÃ)µÔ*d*+À\Š5Øé»ls@ ÀVˆÓGiÄŸd|þo˜]™÷̰€·ë»¯ÁÊ÷"ø~àæ¶¦ç KÓ°QAŸ€° Ä1È=¹^nèÛÂmvsmßFv÷ma[y” ù>BHM 5J¨5”R`1DiBl"“°Ð\áÌÊ$§*“¼°tŽC §9²t†¹æÍ´Zˆ X4˜É„t<ÁL¥Î|Ï©=M3þÿXª~”ãÓGOñêe…¯Þ~Ý.àâû1ë4iH [µ£xx£‚7ôoåžûxËÈöm¸–áB?½A)$±IH­!µÆi¼å"Í¿Øtö] B …"ƒ¥×YŠ*<¿pš'¦ñøÌ!öÏg>^F*E.‘ ¤‹)éé˜ätŒ™M©Ð0‹4“X¬ÿÇ.<å‹ýÆÀÛw_⇑â‡0 ‘Zç¤mÖ°+€Qå´?I!Š@jnØÎý[ßÄý›oç–¡kéÏ•±ÖÒLcŒ5 Wº–UH¤„R£¤¢×9¹<ÁÓOóÙñ'Ø¿pœJÒ æÑJa#Cr!!:Ÿ‰œß [£}šÙʯszöyàUE¼2¸÷:µ?â§í$ŠvjØ:ÍÇ >n¢ÃïÚò¾k×=¼ýš½ å{‰MJ”ƤÖ|}²dB¢¥"'C*q•gæŽñ×g¾Àƒ_fº±H.È£ Ò¹„æáÍ#MlÕ8 X3K¥ù‡¾ð!ñÌ«ÅG¸úxûî7"ùU„¸‡Ø;u»ØB¿r6?57 se¾}ûüëßÅ­C»ÐRQOšk°\ͽâ?–ÿRHr*@ 8¾tŽOœ|¿=ûE¦›+Z;<Ï%ÔÔin8?A ˆ’C,Ö~Ãþ¨´â‘×îÛ-1ö'‘â¿RÀâlû-9Øà4…ÔBPÜ¿õÞË·sÛ†k±iÌ«½OA •FKÍñ¥s|üøßñwg¡šÆäƒ"h‰OÅTž¨Ò<Ùh%ÝVšÊ¡ ?G#>ïÅ×î½vð»ñMÄz$ìËÁÎÐ%V Ö@ÒäÚ¡í|`ß{xç–ÛBÒH#ï¼ ^›û®¡ PBòÔÌ!~ÿùOñôÜQ ˆT9Ðk,õc V«Ì%.ŸÑLqaù'85÷ úõð ®<îÝõN„øïX¶a€ì+@¯ìdØÒ¤à}×ÝÇûoý6F }Tã†û2¯¹¯!y•£׸ĉÏòg' abB]ÂJ YJX|d™Úóuw­Ö.2SùyOXð¹È×(îÛõoâ·IÉûòpCÎisêß;‰*öóÁ7~7ߺý¢4&6)¯§MIE^…<>ý¿}ðÏ8[¹@!(aeÂXy®Ê—–±5š”¹ÚG80ù‹À…WÒA¼r¸oçO Å/“XèUpg ®Ñ..n½mÜ`÷†müÂïå–¡íT¢úkŒî_žY(ê<Õi>|ðã<={˜‚.€ ±*-¨7™ýì<ñLìœãùú'yæüOã>­üÀ};ÿo¤øYbë²ww– O9áÓþoäïüF }ÔÒ&ß[N…T¢¿wø“<:õ,¡ RcT*¢…˜ ÿ0OãTB ‹xjâýÀÙWÂ9üÚðÏv|)~…ØÂ¦ÞV†œìP>@ÒäŽk®ç—Þú¿ÑŸ+ÒHâ×ο„R“Ø”þ_¼ð yb¥Âª„š¸špþ¯g¨Ÿ¬»ßn®þž™üpúj3Á×€¾ãß!ÄGH,ll _t»1IÄžámüú]ßC®D3ùFÜ©©' ~÷ùOðÜüqB‚]@„q-eü3ÓÔNxLU>ÆsÓ?ë™ yõàŸo¿)þžØæ àí=k~š0RîçÃw¿—-åAß Âom¡ XŠWøýç?ÉéÊ$ åjW‚!q-áì_MQ;YƒPÎ,ý*/Ìÿ60yµ¢ƒ¬ÌõeÿÕ;¶oñ1R›§OÁ[Ê÷a^ç •æÇo{'›Ë½Tâ*ß0¼¿*Y$…D EdšB°oÃn&ªÒbÀ&U¬äÊ[¿e˜“Ÿ˜$š%›{~„åæ LU?Ì]í<ÁåàþíkË&àÍeçõÇ«¾›Iù®=wrׯ,5«X,Â~ãˆ] ‰ŠÄ&Ì6–8[=Ïé•qN¯œg%®‘SXÖXLRÅÊJÃy¶}ë'>yÓ°%võý43µ0ö)Ÿ,ú:ÀÚâÛ0ö•`,¸XøR2U[âØÂ$[zú‰LJbÌëZì²%t1Û\âôÊ9ÎTÆ™¨MQ‰ë¤Ö P!ÑJ`|„l…ÀƒI«ôп³ÄÆ{‡`Já.ö ½Ÿƒ³Ž_Mà¥}€wl½)ž%±#l áî¾îÌÕ[Ó_,ó®m7rÿ¶ÝŒ{ˆyÝAøZ%4©MX‰W8WàÔÊY.Ô§¨% ¬(©\ÙŸËølxû0ÆbUò®ìñè_Œ³th öÏ~€Ùú§€é+i ^žøÎ­¿ âýîëƒÁ Û&e ØÃ;¶íæ[v1Vê!ñ@°¯¹zJ%ÆjI•óµIÎVÏ2]Ÿ¡–ÖÁ ¤PD§HÙú=#pký¹í<— a"_¤r¡Æ¡ž!mXh>Ë“S? <‹«^|…pÿ–±ŸÄöpcnïY›ú/ùIlÊp¹‡»6nåm×lcs¹%%±I1¯•?%ÖZêiÙæ ãÕqfšÓT“ÖZ”ЮÊ(£éÖvÛš/.f·[, ýˆœæäƒ˜øü "å¹¹ÿ‡ÉÚúÐÐ^i¼”ðcXÛCIÂîÂËZÅ€R%$ËÍsò_œ8ÎÍC#Ü1º™ÝýÃô„yg5LŠÅòõƃ¾s挵4ÓóÑ,Óõ)fšÓÔ’ƒмÒm¡“6«`¬[ µÂ?öN 1 ¥'K+0&Å&5DØË¦72}`‰x9Vl*“µ‡€™+É/ €û7 x/©…­9(ë—¦þŒðµt%Râ¼c)IlÊÓ3ã<7?ÁX±ÌuýÃ\?0–ž>Š:‡‚Ô¯Ù ûÕÈÕ‰¶– Oñ‰I‰Ò& ñ ÍYæ¢9icS¤P䔡ÚB^ Öv„mH“¾¯X7¤rG!Ýs©XÓ„$¡g8Ïè­}Œ?4 ƒá ô…ob):ÁU¨1|1øƒäl/\öǶª¦e[ø ZG!R#,4«35!#¤6q ­¤Ç¢½8"¹ºy3‡µ#Déš1¿¼ Go-Ú¾äß]"bXKøîÜi¸ )w”-Pmó ü®Ú PmÁ;t ò‚¤!¨-IÆOœ?®94`úŒfþ¼baR‘4i &ÎxÇË©,NqthQÚRJèk²a{þÍ5†¯]fx÷…:ùRƒ8VDMA’Ÿ4ˆQ&P‚¨»Njk›$¶Éî,^†I7RO»ÖZž~;¾—Öz±äÅv_¾HÒhm³ 2@¡½ÐµÓzJ`h'|©3&À Ý¥’$—4ªŠ©4G 9þdȉg–§$iMø0ØQ=º¥ªó¥r²;YhRÀ’4\I\s^1¤Ä)úHJ–â@ÌØ Ë\só[ï˜aä†9 ½U’T5BTƒÔRYôÝÅ‘iÚ WxüÌ%`N¨Æ®äÛ»k µ1kE-ଙ ZÃl\h¤Ð(á ´€ZåèŒ pl ”$W`“/ìÿ§þ1ÇÉg5ñ‚`` TP ¡Ð¹~û ,C¡Å":Ô¹¨ # i£Jl£µ:4*¯@sKשÍHNN pòs#ŸãKŸÊ³ÿ¡æ4®î2o ¿¥(ŒAÏ(rhˆþ<ÛÆÛÆ`ë0 ÷Â` zKÐWè®°‘jQžÅ*,Õ`z&æa|NLfæ¢ùyXšúTÎcë+ÌË3øzžú³Ýlºuž}ß;Ï†ÛÆ™Ÿw&¥/˯Ìj`3}‚’LHRÍBÊ2µ]yx•qú²`k¼.³L /öVkô…¯ðeöܳ€,…Êœ{€àê òEE+žø«ÿôÑÇžÔPM!—À@ úvAÏ6ÜÂÀH‘½;û¶ÃÞ­–kÇ,}Å”|hÉÎ$»Jžµ—I²JÒJ¤6"A­)8=£921ÆþÓc<ùÂ^Æ'›0{VNÃòYlu‰ñÇÿòù-×ÐlÂÈ3†É•Ó~%ðŠV­]¸9_æöž§Áîf[qÛÚZ´°®ÒGúA­s¯­Z9ÁkÕýºþ±ZãoñÏ{aë‹|‚Œ°³‚Ýz®eû Pªå8Èå5Vübž>RâàCâÔeÔ{†aè:èßEq¸‡7]wßhy󵆑~K!ô#Œ’ް¿îtr#ZB¨ÝûÎUûOK¾xTðè˜:ß„…³°p' i@ç tÁPyäV>ûK`¾¬\í¢PÉ»~‡¢ú!ru÷&T!@[ƒ%!P!yÁéV YtEJ¼–ky±àµìvø´ÚÚ¯eèé>p´Í„~©G37ò™—øüŸçÆ-¢#vôèÝÎð¨â›öÁý·&쵄šÞñ6öêµ5¹%lKÎsðÔ’à Ï+xFpè4°< Ó`î”+Å“ìì’þ+Õ?úšf ]^Uð½÷1þOR£Ô¾ × A Ó%P)Ýä¥V :+øÕ`hýßU,Ñ ™Ñü-²P*@·ØAh” }d œæå"ŸüÅSG$ä#è·Aÿn†6Þ}«å[nOÙ4d‰SG _ÂTáY0§¡Ú„GK>ñ˜âØ9 r1ùvá4>•žùSVþàçH羪YC—[^ä[>GÀ¢?OþîÍè@¡mÒfÑjÕÒj©|Þ2ŒÖkZu‡†AÆ!tï'œ`Uè„,C´g§ù-fPä üåo”yà#E7t²"6Þ‚¹QÈñÍ·Þó–”-,Qq*^5Sü¤t~ÆJ< øÔcŠùEK/`ÇŸ„꜋:Ò¹çh>üŸ¨=øˆ÷ ì•€à®Þïc4ø#R#ro%í *5hâ‹è^¯öVû6ÐÊ9†Z­òÚž¿¬Îj¿ Ð"̘° íÍ@±°4ò‡ÿ¹ýFˆþ1Ø~¶0Êæ ð}÷ļy·%MY+ÏõêØ¬û-ò!œž†>¬yò„„¤†8ûvæ¨_:lÎÑxüƒ¬üù§p³†Ì•„¢ûû>OÀ>Ù—§çÞ­ùmc´M»Y €.@d4; ÷#2ЗÐQÊ×2ô`hi}ˆVÎè J%Íì¹<¿ùÃ}œýŠ‚rн¶¼+s¼qWÊ¿º7e¸ÇRÁ¾Fš“rÚ¥bþêËŠO?©I È™ƒ˜3ƒ‰AØGžåÿ0Ëeð½œÖ0ÅåïfSø§Ä©(ÜTåïž-!óEX™ÆÿHš`—.0ûÿšøü#>uü¢¸Ü1 «þ1ÅòTß];9Ï|oޱ7mFÊ<ÒDZ÷£Q:iÐlJTÈîç»ÓÇn}¾½hÓ^ãÏv´÷ŽÓ÷Ä%üãä#ÄÈ͈ћ0‰e¸<Å·ÝÞƒ1Í8ÍÜGàêÃ@bé“)ç )à}oé¼–øåàž ‘=MúeJú²¿“%Šwì,rjjšç'¯AõŽ ·¾sêAŽÑÿ=dæ×~xþ¥Öôe*,òDí?swieqÇâs“„ÍØm‘¶€L"­ù:»‹AÐU³Ÿ9 _§/e«|KµG­¨öÒn÷s¹P³4ãê4F Ž"7½É}Ñæ9¤žäÉFí+²¡¯H>ÐHéªsŒ½ú]ÈC"!µ‚<0¾?þÎNÈûo‚¥ýñ2ÓG%ô(Ħ7ƒÖØhÒ3L-¦ž:=…ÍC=l,³q°‡¾B­$©±.ä+N–>"¶KÃgæ~ôÎÔ ~â]ð?%8=²Õ4}kÐK5#Z_·ZI* GÆ—0Ñ4–<¨mȱÛ1+ØÆ‚ |Ïû¨üÓç1¥ë#øjEÙ¼•Ûó%d#6¾q3[ß¼•@IDÒDE+(R´ݾÀ*»ïÒÂ>Ìó6>hÙ~‘kûÎ!tç…|ÈÌÙ"?ó¾!ê 1bì&ä–·‚I0µX³ÜnáîLhp÷A.d¬¯—MC½l*ÓW 2`¸ —Ù}¼] WDL5Ð\rüÀÛà½oîüŸãðÁÏ@±ÑÛˆ°R¼˜Ü´D©áÔô<ûO_`n±Ú®¾‘…[A/vþ4æÌ?9›»ü·gá/8– ¿º1q­ÆÙøqÿž›s¦(¶âI-b÷½»ÈŠˆ @F+ˆ´áïÑ(Ú÷jìö|A¶”†¶à·–t[Ï…¡âáÏ©O è/#†÷º–h¢[ø­ØIàRPĉäÜls³ ¾,2ÒWdó@‰yzóZvœ6{9AûeŒÔ•QÌ@Qð‰'C®…;¶»çoÙ ßy|â‰edÓt¿_¶GêqÊÙ¹eŽMÎ2»¸ì¾›n=Å6O#Ô^Dÿ6ÄÂ&ìÊ8”ÞôN–þîӘƤÏ~M& »hôTüyªæßñÆüoÒ#o˜>pžærƒ=.Ñ^D â"ZveÐB®áß§';¥Ý(­ê¬ð5Ö,Ï<þ?ó&ˆ¾ë…H"l2y H!Zw™T $©ULÎÇLί Â:J96öåé (ç$‚z°"5Iº*×–b=B%)ö%©DÔ%ùÃÇ4×A¯ŒÂw½ž8-˜ŒC¹z«ÁÿF‚ÔXV ã UÎÌ.³R«ƒMAåœY·©ÿ…M°ñ,"7Œ¼[9:BùÎûY~èÒ+ ¬0>Æçëÿ†;ó¿Â°~ÛÒ™žþÔ~n¸oÛönDçúI-!’š¯nβAw©¶;÷åªRnù¼â™‡òÌžÕ·ˆ¾îËÄÀ4ºµág„/Z>Üû"Ý!‘L-ÃÔrŒÒ†¾¼b¬O1vc‰[· ¶ Ašú®œ‚ÊK®’´½øf,b®É™Pñ×ûïó¦ œƒoÛ ¿7¯‰%¢aHZd˜«%\Xj2[mƱ¿œœzе¾È¦~ ÀbãID0ŒèÙùAh.Biß[Y~è/‰µêô×äé@…ªy–ÏÕþ=oÍÿ4[ô{š•F°ÿo1n‘½÷\Kÿ†äsȤ†h,wÌB»=Kv„j›ÇQI VòÜ—óèDF 5˜dz•öËŒðµï¶Ð« 2ÿÏ}>(Œ•Ì׋‘bà ð/n…û®ï¾ðSæbú8±íi øé`—rìRJ¾ñOÇrÜ¿FzÜ+÷^ÿpÏœç »Æµµ'w´9H”’,ÌjläB½ïÓtT'4‚ì¢:ϵ˜ £ý‚ŒcØê”®.ÆŠ9øâq89ëœ?[å«4! p Ñ´g Ùvr%3MןXëÞ»R‡¥*›†›7ú…–¶ BoŸ@†­³-¿D:oÕ' Ù¬­mÓšL%„kV"™Gè"¶9 ª\z<\UtLÂÛsÓlR?€´= îúö[ظsI£]žm5c·ïáÛtûèý¼ ¥$‰d«.Îÿ­Ÿ<è¾Ôï s „rÓ…j ^*' Öt+àô84"W9”@¥LÏ9íWêI!ÛÚÖõœÔªpa•;6Ú=eÈ ŽÖ(¬ñ@ðæÉ ïðeg!ÚCªøR¤ˆAç1AÞáFò¸Ñ2ú•l•¿‰°÷%ÜòιnßfâFŒY™F&M„*ø¼@§52ƒ+’aŠ,Wyù(µ ³T`„v¶1K‰mï?+xíµ^;Ë'µë9P¾ËKuj…KpjÜ2>Õio phMËå3?ü%²x-°~DlW|ºPwe+—Ó›‡Rr¡* ¤©Àí€`]³mÑ¢M;BàØÀ+‡© QÞ‰‘ùÀk¿zeðÞÂ/!ùAš ;ß°•Û﹎4±Øê"ª ZÔߢ³Ö +ýÔD*&å„°r”ЄeÓΔ%PR¡°Vw@d€ÐÈžKÙÖx•¾g€Ö¹Æj¦Ì"#ùÕÎâEÂ÷{ê_«4]ÃH =y(æ!ð½­Yi &•˜ÔçT³ °­öÏ{¶QJû9‰Ÿ9S¼¿'¯>Þ›ÿÊþ$Í„±ëGyó·ìE(IR[„ÚZvÒ]ÂÐÊ=VIX²äËMò¡"OŽxò¹“?q† ‡nƒpÌ5á’ U€P!ÖšnÍϘNTà´_*×ö-×¾Z€–ַ̂Ƞ½_Bý3ƒM»à.ÙbLwÞ ]­ÿÑ€n˜d*iª3ÔïÝ#2ã"|÷V¸‡¦éé¡™x'Ý\]¼/ÿH~™f†xÛwÞN$µ¨Ì 1nŸ¿ã¦ B‚|ž '_ É¥@¡,W<þì)¾ôðQ>&Dïk¶Š ('Mbßgµ^w‡„B!•@ëŒàÕÚ@h·°©nÍ—«„ŸE¸z¤`—ðýlk:âs9Ÿ„\µ¬ ~&Ÿæ?Çd>3IýÍ·ý<#Û²IH¥Ñ&MRlZs_:]ªùP=½zøÞܯ#ì%ômàÍߺ|)GÒ¨!ê A„aŽ —'—/ËäršBÞ¢­Uš=5Á¡ýçxnÿ‹S~Ñ#Ô TƒpJ¢š!±€x ¥6 Ã"Q£Þ-|±Zø¥;?pö˜Õü¶?Ð~–þ¥_»È4³v€p1 ´‡I[ÑvqÀò¡ 7ïVD[[=v¯3Ö‘ÒÍÊšý4QX¯ù"m¢ÃÒ¨†Iêî‹6Ï/øø?ºòøW¹)¿ƒäûiÆ íåMßz+¥Þ"Iœ耠#a  CM>(MRšÍ„é‰EΟãÜÉN¼0ÃÊB¢ ¶,ØžKOs"}½¸ÌÎéïBl6Íy„ÜE˜/Ѩ®´}:_Ç$H®­Àj? ÅÊk¾ÖP.ˆŽ/ ;)í/Rl3 µ ¤ P€b7j4_#¸ÏHÅŵ-$©Ä¦:‹š\¡@@£1ïËÆ1TLKkU}møÞpÆ~ÉÛ1–könæöwÝJ¹'0…kISK­ÙdfižÊB…ÙgW˜šX¤º\'mÄ.^ ” f]aÜNq:>ɤ9†å,p‚f:A$F(Š÷$0 A>$ȉši;ìËj~[ø>±ÓÖü5˜@f…¯w\£« J½Ê9–:=Yt´¿Û0ÆÑ{©#ånÇq±áœ¤û?&]EÿtÏCv.^ î”JyW§Ü‡G3Uêg&}Ï@ãÊà{Ã;‘ü)‚¤†òpÃÛ†?œÇÝQ{ÞSW£íÁN~úsìÚ~îl.¡<¼‘boj5%‰¥ÿ•ë4Z%|µT ¢íù+í~ð}°s¨ûò¿pÊå tèGÕ]¦ @À†>·xýpçÿÍV˜ª ÐZ …½Hó³ò·>¦i“X!•¥o@¢X^ÇÄUʲðè ¿¼¸VÓËÀè^Œø9$?º*ëeLb\|ƒ²$6"&¦A†­Ó FÕ¬°Ì" v–š'fÞW©Ì{tÎøÇ+¸{å5Ö,f\~v‰xî“¶üTsé·–ýùøXrø° hcäÁá¦E«ÎãUçQæo¾ºí©¿?dž»þ;å뺾8Auî›·0|djÂW¬òò•òÍ ßkþjŸ „Úeëš™N»Ôú–ö Ãd£{±˜‘2Ü4[:ïwrÆa¡æ×TÖî·¦suÿP­…&iABIPY¨°8q̽QõÈ sŽxv5W¢&0õ”]Ï<6™=Íh±¹ŒÚÚ¯v‹8ûÑßáúŸü_Q=×Í}Žòàå¾"ËÌ핽ÕL¾¾Dn@xÿONÂSç»/"ñ÷ùÑAgÈÕj#½o )ŒyÏÿžÝfâ±³n]`±aÎk?P‰Vg»W­‡F}CD–éH›u&åìŸ> ö(ð‚g^®l†Ò¿¾ÛÊÑižüFîû“´Y §Ž?Ãö}o¡wÐÝ dqÞ-ˆd}ÙŽÄ¥Cÿ^€ÑZ&Ùã}Zca¶á–q[“Ò×€±,ý9ÊÃÛ¶»U¿viø8µà"ái˜Œ9IÛo×=ØX)ôÁà{åü©£Tf&ÕL|úVŽÀÝpròJ5†¼Ú¶˜¿ûùáß§ßû«sç™|á9¶íÝÇàèP°¼hÛ±}GÈâ"fX †ª œ\ðÂɸîwV¢Sê¾–¦¤z áæ¸s[wÜÿȘoÀRa&ñô¿Öʲn±™B_?ô ¹õü‰sLxÞ]Èòó3œýøãÀÓÀQ^âæÓ¯eT8ôs¿Ä¾_ßCyç;æÇO CÍö›ofpryÁÊ¢Êߊñ/iT÷y;RðdšZ²ãì.€Ô:ô(Ø6ï¾¾“ù3þñ8\¨À…šû\kü}Dw¨×Q¤±ô züÐщããœyîi÷‡ÑT…>ôÖ<í0ûR&X¾Æ`€ŽþÚûiLŸy\ð{NCoý!ì€÷Ü=™°ï‘³ptfšÎ‹#•®ï“qL‡†CÃîo.œçÄ3O¹êC³Òàèoø×C>è|ѧÎÃC'1YuL§.K˜&=ií±Û…„b ‚œ{ýÄœØеy%Ë žÿÕÇX:ø%à½í_æ Îx-lEÊ;÷qýø0åo IèaÏ›nep´ÇUã4 QwB <ÚÚ®»Ï鄸Z®= }u–®?wo‡¢Ÿ,*L®À£ç`¹ 3 ?„Ò@d<2‚Oˆ#?¶8çJŤ„ÊrÌó_yž‰£§ÜÑt•Ãzœ¥CÏø„Ú%©ÿõ ]ºž›~òÜ÷.’„°Xd÷¾ÙqãÖvµMÔ€4Î$|2Lh¥ÓþÐW·„¨‹'™¶Çã^¶f3‰Æ@Ã806.Bˆü|¦q‹ iJºd“”ÞÓ?=ËÁDZ<3ïP¹rlŽÃ~ŒÚ¹/_žã2n,ùz¸!°Û¸á?üGFï~„y¬etûFöÜq=Ã{]•Mâ@¤Þœ½½½•B 2ûjÝ·¨ëJÔx§ÎøÛµf5¼Ö·µ?íìMß;ÄNó{Šnq(JàÀãG9òäÑÖMˆ :ͱ<‚‰žó Ÿ¥ËÉ»|­ÝÁ¯ö­œäÈoýK‡²õ;ßOyëΩÓç™›šcÇ [¹ñö ÜŧN0±íÌòÕÁ·Ø ðcì² køÙTpjÜý€S ±ÿ9ºïih3ÿßàV­vÀ©Ô]¡¨ÖPê)8/CIˆ—›œùÔ3˜èq¯ù'y™Ã"_Ï ÷p{þÏaøÎoF•J$)…¾»ölfÏÞ-\3Zr:¦sSG¿ÀéÁ–/eö`«KÀvò©q£~ã4¾5’6«ýÍ̱™ºÔs»åá@º\¿pðÉSxä ùfç8ò»ÿ³_ùôå„{ßH&€Uå%`3ƒ·Þ˶ïünÙAHjŠ9v^;ÊÞ½›Ø¹}ˆþINu’ØÂvß½¤Í*3å,‚,ZsZH}M@l\ùW#¹˜þ›Iq⢖8r~J®à$|è©S|ô ûRÉò4çþö§8ùgåé߬àÒl0ìdøÍÿŒÍßü¿0¸w/2»âü¡ =\¿{˜›®fÇæ~{5=?_.¾KiöÆYkÕ´AY08aW#X‰ AÃß“#ò‚o!q¶?‰„9·[ ‡Ÿ=Í¡/r‚´IéG~™ç~í÷½˜¬àÒl6Ûºí­l¼÷Ý Þz ù‘~§ªî61ýý®ÝÚÏ®­ýlßÔËŽe†üàˆRÁÅõ¾µ´}M‘] Ìdó¢* ¨6 ó+1Jkz{µÈ?ïÁP –@=qìÐH:a;6ÃN3ÊécØÿØsÄÍ&Hi˜öc<ùŸÆçþãu¼8 Þ?ØBÐ{×Ü{/#w¼‘Þ][ ûËîN`žM}Õò؆"×l(06˜g°7d '¤¿ÐWÒÝU;MÃÜJÄâJÄÜRÄøló³u&§« öå¸çM›¹ã¦QF‡KH?"¾ÚtŒPÜzj±;oFÎ Dþ¨—P ¦Î/óìcÏR]\vñëòñ‡8ðëïgåÔ ¼Èx¸otdú€a` aß.Fßr{öPÞ¶‘âÆ!t1JÚÌ}bèÎÙUïÚZLZ­:g!uAP¹iç7\»ëv18PBj‰‘­ù~OÜã†ß›Q·ÉY^ª³ÿ+Y˜œr ¨Oæä_þgþú¿d×py>BÁƒaFÉ na`Ïnzwl¡86Bn¨—\™ '߆\ãDzÖbSKRˆVš4çk4f+4*ôíd`Ï&d>t,cÑ…€ CE¶Œõ2:ÚÇÀ@‰¾þ:’"]Wõ•4Þ´|k]vóðÃŒŸ:ã”hyš³üGÿhMçp/ †V7mWø:à÷>„îAúQ¹A¹—ü`Ù·ñúîV)h.E4j˜¨AR¯¸*~Oé¿a;ïyƒ7ÝHyë(2¶C€P’b1¤\ÎS(æÉr¨@£‚ÀuN+w·‹D!ÆHÆOŸcüô)ßÇÕ¸ð¥ÿÆ3¿ò;¸šËd_ݦ¼©Èîáûê²ÀVù[“N\äµ±Œ[èݱ‡á7ÜJßî”·ŒRéG]µ¡]£±P­š¸‰»Í­©qÓé3–Ùý籟ü ®Ò:^À•õ!ÚÀ¯gKåìz†éó‘É0L~Ã&úví gÛ&Š£C„}er=¥<ºº»wå5V¸–j™é1ZKv•ñ¯ðŸÿç|¨ÛŒÐ×ðêRË)yvèõÀèó )!u –AäÑ…<…ášÂpBhÂþR¥]Ì!EØ”âågxü¿ü,pÆZÛ\À«ßì„sãúc9¶öpçuÆ<-âFÆ·ÖV×ðÚf V™ŸÖðµê˜}܂ъµ6~Q¬oß8›\ÿ Ö°¾­`}[Àú¶€õmëÛ:Ö·u¬oëXßÖ°¾­`}{½oÿ?κ¼åpg7HIEND®B`‚eric-6.0.8/eric/icons/default/fileSaveAs.png0000644000175000017500000000236012342633754017746 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<mIDAT8˵”LUeÇ?ﹿ’$A)5Ó"\F„®ÐõÓ,[?pZ” c™¦•V[馩-GÓÍY­6×2Üt5µ–•³MSû¡I» )Ê/÷È=Üûž÷}ûãÂdýWïöìÙywžÏùî{žçÆþã˜S:»¡»»;ËòX,}y>?h @ "–B‘.›Ö¯C+MNNÎù”á;ᬪª*êêë)¸½ˆ«èʾ,…ˆå®n‡ºÓ§PJ±oÿ¾t @kÍÆMù³¶éºXBÄC Ê`¤Ã…—–PÿÄ|œßNà±@ºš`0H0DkÓo…1×uÑZc Ïg±ïhÝPãŒ!»s)&3À°Ã ì).æÎšÝx§¢µFk1º¬µ&B>Æ„%ðy÷MϽ’ÉéƒËÈIiâáo$ÓÃ’;¤ä‡Å‹)>ò J)”Rh¥+ÖZ#„@)uùöxà p¸á3ÉÛÏ“o»;ÕNt¼dúÉXg&!•ŽAµF3X±R*Ö'â2cbFÚüš y_òJ5üôk˜ÔänÖ—C䪻h+\„6ú_»ÊЕ¶ ;O1;e=[j${itä"Õ¯z±E6»Oñàìl´6(¥bœ­ÑJÄß9’û<ã¼Û9x¤ƒk ]­ìX yD »jâ¶©7q]ZRÅê1ƒkcP½R*´ 1.¼™`]+·zèê¼Èº ‹ìt?ÛÏbtÖroœ‚u1€Û+¬ÏcaŒaÚÍSMVVVÜSfÍâ,ûG¬MâRG JšYx¯ŸŠÍ×ÒÒ5œœñ9x<ž!ÙØØÈÑc?‹^ÅýV¼0·›¬ëg0¯¼–ˎìÉ-TÌõSùAõMùyéTÓwô Ÿ§Mü¢dr Å3Ëx¬|g›$¹©¼[îeõŽŸ„ü¼L|>_üý¡3tÅ€¸®KfJ3•ÏϧbÅvþh¤&¶R½ÌâÓï®áÈ™‘¬\õ4¥¥¥qeåÏ•cÛ¡Xmz¬=ÕÀQJ1"¡-oLeù[ŸðýqÃpˆ­Ë¢8êeóç0gN´··ÇWÀØ´4ÚÚ¼tvt ¥ì»Ä—G^&À†ê½ì9dHô»¼¿¤“Æ‹^^|Ï!77—²²2¤”„ÃalÛÆ¶m””` ƒ+%¦wÐâà™3&ÈYËW'²ñz kžj&11À㫆%QYY‰ã8„B¡8Ô¶m"RöNœAº.£FŽƒ½w—"ó¬]^ÄÁ;)ºeó^K$mìBB¡˜—ÃéqˆDzbÏRb‡Bq°x«j~ò¤)“:3R;EWëï´^òàI-Áø3ˆÊhl•ZÖ¨”’š/vÑ}ù2aÇaxRB.µÿÍ_çÎ ¯‹÷77ì‹îÛ¼kÿ¹Qg›lkÁ¢iøýNÿü÷îÚ+[ìBSÑhÇqbø¼ÝT.¼gųÞjŒá¿Œ h×4tÇ¿IEND®B`‚eric-6.0.8/eric/icons/default/1leftarrow.png0000644000175000017500000000154212342633753020012 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<¶PLTEÿÿÿ&fR]YURjrLKrƒLQo‚ŠD}DMVNRZaiQmqqvz}…„ˆŠ‹^Rl‡ XY• a d ‡ƒg4r4˜Ç¾e§elp§ K … ”¯ž!%q&1o1G„GQ–QV¢VZŸZ] ]q®qGZiy}‡Œ•–œžŸ¢«¬¯°µ¸¿À€§Wuh  ­ »eÆž&¤&(¡(*š**©,+”+,¦,-r--Œ-.„./¡/1Ÿ12~22ž24t46›69—9=“==Ÿ=@Ž@A£ACˆCD¢DH HIŸIKžKO›OS§SW–WW¨WZ¨Z^§^e¯ei±il±lxºxz¯z|¼|ŠÇŠ‚ˆuáJtRNS@AJOpq}„“¤¥©©©©ªª¬®®¯±³µµ·¹»¼ÐÐÕÛãëëíîñúúúûýýýþþþþþþþþþþþþþþþþË×ÇïÈIDATÓc` 0båÖÁ"ÊoÚ/ƒ!È$ê2ÑS]”]«}BŸ¥š(žGoO·›$ª¨€‰{WgG[³бbN®­-MõµÒH¢šE u5ÕU¥e²QVçÊò’₼ܜB9„0›¡­WrjJb@HXš’!œÚ™Þ>¾þÁQéŠÈV2Ë[Yû†FÆe(¡:PÐØ.(<&!KÍ;¼FöaÑñæªèžçÒÉNеPÃ*Gu,+d–¯-øô…HF¯)²ü-JIEND®B`‚eric-6.0.8/eric/icons/default/findNext.png0000644000175000017500000000247212342633754017507 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ &(…XtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“žIDAT8Ë“mLSWÇ·uÒÂÚj­¤¼(c±—Z©À@^¤´´`S(´ÀŠh¢– CâP— Ñ-ÅéŠ|«sS·Ì¸,eïÙK²ìÓöa¶3~ÝܡesDîç™,ã¶›ü“'ÿó~ç<çÞËØ½‡u¸º~a[Ùà?my“|ÞÒoùšùYû_ƒÅ&àqKÌËfY ““­ *oD>Ž sGæO|ÓÚÿv²xïD/ö_Ýàñ ~ÅWtJE@ñýØçcýhT² ÚîèÁO=‹ïˆî@ϹìšÛ…Î3Òº'ÖÝJnK¾µ/¾Ãïcäƒ8GË•³UÿìfñŽhü'ýLÐkGÇÅiÃðô¼ÙƒÞk½_cïÛ{ÑzªŠ–å‰ n`qÔšc5pœpÀ5å‚çœÞY/š/5£õõV´_iGèr]WºÐzºUÒti~dMº÷F÷NxQø\!l/Ù`ÚQ:]ŠŠXªgªQ;W 眞9¶Îl…/æƒwÒ+éÃé ,Àž¾?ØËæÝ“nd>›‰ì±lO‘?™ÓyḬ̀ÎXQ-+û•ÐWê¡oÓCˆñÓ]âþÔò©‡‹ªÍ î÷êt=ºú¦Ëí‚Ûã†~‡ì ЛõK^¸? åvåòuðiÔ/k¤ÔçÕ¿²™g% Œ~ ƒÁðj øsÛ¶m0›ÍÍ"üÝ~´ô´@´ˆKÞÐЂ»‚Ðú´Ð ¬ÁêÃ)ßñŸ;{%h’L&³Ùíöûúú"‘¦¦¦ÐÐÐ£ÑˆŠŠŠ%QM^,Ãøø8v÷í†èo )B 1¨‚ èÒÒÒ¢‡ãv0D(B]]JJJ`µZ¡R« V«%ªÉ«¯¯_ÊP–z¨— à”””ÅÅú›ákl@[K¶w†PPP€¢¢"ˆ¢x›D5y]|2”¥ê%FxíÚµó5›Ë+m&4U£©Úg9ÿØK6eee¿“¨&Ö(CYê¡^b$žX‘ümQžUÆTn¶à•îÍh±gâ½z‘ù¿ÛO¹>¡š<qNõÖâP“[òհ楃 `ZuÕY"Þé®ÎÅ“µéxf³;«²¤Ç¬¦´Zí‹999¹ÙÙÙ9T“GkûËW#\±ýE¨/3ß!FX¥RyKm–›×/Ž÷5"Ò|5ˆ¢é2‡åÝÍQM­Q†²ÔC½ÄXé«Ph4š€!+óMÖ‚fSþ7YYYQNgIOO—ÝÍQM­Q†²ÔC½Ä¸—ûÇóE…¡IEND®B`‚eric-6.0.8/eric/icons/default/dirClosed.png0000644000175000017500000000132312342633754017632 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<GPLTEÿÿÿ(FNd‰²v«àf‰±€±î~°ìu©êu©ëk¡èj¡è_šå`šåU’àU’àj›ÙKŠÛJŠÚc˜ØX”ãX•ãa—×AƒÕ|«æAƒÕY–労éZ–åZ–ä[–ã[–ã:}Ð\—ã]˜ä9|Ð[’Õ]˜ã^”×_™ä_˜â`šãc™Ú°ê‚±ê3wÌZ’Ö\“Öa˜Ûašâb›â3wËWÔXÔXÕX‘ÔX‘ÕY‘Õ-sÈ.tÈXÔc›áeœáfâhŸâ,rÇ.tÈXÔfŸìgŸìi ëo§òp§ñw¬ôw¬õx­õ}°ô²ö„¶õˆ¹÷г䋻öŒ¹é¼ê¾ù‘¿÷’¿÷˜¾î˜Ãõ˜Äõ˜Äù›¿îžÈ÷ŸÅîŸÈ÷¡Éú¢Äì¢Èð¤Åì¦Æì§Æì¨Èí«Êí­ËîXvõ\FtRNS %*.8;JY\]^u€˜¡¶¼ÎÒ×áãéíííîîðððòóõö÷÷÷øùùùùúúúúûüüüüüüýýýýýýýþþþþþþþ›,A»¬IDATµÁ½JQ†áwæ|»X;%¥ˆ—`+xí–Ö6zBÀ 1âOöìα“­}þ‘ÁÙÜ?, N/ 'Û¯˜Óü§ 7X¯ùÑî6T KÍÀnŽøë ãÇk‘M·—z_Œ,¦½v™õoú( 2/Ÿ: ndæ£fy#3Ÿ]7“…Âû©±d*¡X)HÌW¡:”ŽLCUø¾‘™WÕí9¿=„ÑõFãô ÍŸ:¼EÆIEND®B`‚eric-6.0.8/eric/icons/default/ircHalfop.png0000644000175000017500000000143112342633755017632 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<•PLTEÿÿÿ€€@@@333€ª€ ` DD3P@0]U/v+7w2i\HƒmX_SBDwLx…j‡t^R•>S—@U˜A[œJ^ If¢Tg£Ti£Wi¤Vi§[l¦Ylªdm¡em©]oµ`r­`v¯ev¶gw¼my±i{±q|±l}±m~²o~´t€³oƒµs…·u‡Àzˆºy‹kMŽkP“À‰”ÂŒ•sX–Àˆ–ÉŒ—Á‰˜y^˜Á‹˜ÂŠœÈ`Ƥ„j¤†j©r«‰i«º ¬Œr¬Ò£¯Ì¬²l²Òª´Î¬·š~¸Å¯»™y¼Ÿ†Ð­Ѭ†Ò¹¡ÞÕÁäÇ£ä˵缑꾑êÅŸëÉ¥ìʧíÄ—ïÙÂðΩñ×¾ñØÀòѬòÙ½óÝÇôÜÄôÜÅôßÊôàËÚú4*4tRNS#-2“Z>”[[[\@˜\]\]]]^C—aEœbG™bbbbd^ccceIžeeefLœgggiN¡iiijPŸjjjmS¤nU¢qqqrX¥rX§uuuv[ªv^§xxxy`«zaªzb¬|c®|||~f¯~g­~g¯f¯‚j°‚k±†p³‡qµ‰s·‰s¸Št·ŠŠŠŒv¹‘‘‘”””¢¤ ¤¤¤¬¥¹¬¬¬®®®±±±´´´´¶²¶¶¶¸¸¸¼¼¼½½½¾¾¾¿¿¿ÀÀÀÁÁÁÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÉÉÉËËËÎÎÎÐÐÐÑÑÑÓÓÓÔÔÔØØØÚÚÚÛÛÛÜÜÜÝÝÝäääéééñññôôôÿÿÿÇ-rÝ tRNS>ARTjz{}~—œÌÍÝáïúûûþþþþþþå• ‘bKGD|Ѷ _ÞIDATÓc` '`Å&È%ˆM”/(H²00ðGØÃA¸¿Ÿ|@ ƒdNFfVnVfVffv¤·Èù²3˜§&%$ë'ÅÇÆÄjÄIyxÊzyÉH 3:åd»g$¦$$Ù$p»º1°¹ºH0h—‡䇿åg§¥gk1p 008;:2¨TF—•F•”D•W(ÁÌà`kË XST] FUU5 `WÚY[3ˆ× c°°•…¥˜ò‚…ÍLLÐ|É"Œôô°…€®Ž6aMu5lÂbª¢XDqÇ W6¯ã ~AIEND®B`‚eric-6.0.8/eric/icons/default/projectProps.png0000644000175000017500000000254012342633755020417 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ '"h‰¤0tEXtCommentCreated with The GIMPïd%núPLTE___bbbyyyHHH~~~˜˜˜¢¢¢000RRR|||VVV¤¤¤JJJ'''***666888„„„+++---]]]___qqqppp‘‘‘???¯¯¯‚‚‚xxx¦¦¦nnnvvv°°°mmmEEEEEEwwwYYYzzzaaaEEEXXXYYYZZZ[[[\\\]]]^^^ZZZdddYYYJJJfffiii‚‚‚wwwppp»»»½½½ŠŠŠŒŒŒ´´´ŸŸŸ½½½®®®®®®···ººº¸¸¸ººº¹¹¹®®®¿¿¿ººº½½½¾¾¾ÃÃÃÓÓÓëëëìììÏÏÏ×××···ÕÕÕ,tÍ/€å1yÔ2æ4‚å5ƒå7„æ<ˆæK‡ÕQ†ÈT‘áYÓ[¡ÿ^¢ÿ`“Ó`–Õ`¤ÿa¤ÿc’Íc¦ÿk¢ámÕt™Èt¦Õt§Õu{‚y}‚z¶ÿ{‘§{°à{¶ÿ|·ÿ~¥Õ…Œºÿ€´á€·ÿ‚‡Œ‚³Õƒ³Õ„—§‡¸ÕŠœ§‹š§‹¥ÈŒ§ŒŸ²Ž·Ü¨ÈÁàÁᑪ̑µå’–™’£²’Âÿ“¯Õ“¶ß”–—”šŸ”Åá•Íÿ––––¦²–Ìÿ—¥±™«·™­È™ºå™Ðÿ› ¥›Îÿœ«´ž±ÈŸ£§ ¹Ø ºØ¡ºÚ¤¾Ý¥­¸¥¾Ü¥¾Þ¦¿Þ¦×õ§Àß§Áߨ»Ñ¨½Ö¨Áà©Ýÿª®²ªÏÿ«Ðÿ«Øí¬Ýÿ¬àÿ®ÂܯÄÞ¯Øÿ°Ãܱ²´²½Æ²Þÿ²åþ³´¶³ÆÜ³æÿ´ÇÜ´æÿµÀεÂӵŨ¶Úÿ·Íí·Ðê·Öÿ·âÿ¸¹º¸çÿ¹ËܺËÜ»çÿ¾ÊÚ¾ÏÜ¿ÊØ¿ÐÜÀÞÿÁËÖÁÍÜÃéÿÄßþÄåÿÅÇÉÅÏÜÆÇÈÈÉÌÈÊËÈÑÜÊÍÑËÌÍËÎÒËÓÙËÔÜÌêÿÍÕÛÍÖÜÎÖÜÐÐÐÑÑÑÒÒÓÒÔ×ÓÝçÖÝå×ÛáÚÚÛââããåæææçæççæèéçèèèèéíííîîîÿÿÿ:£ÞYtRNS &+,,-7>?CCDEEHJJKZ\^``ajkkkkkkklms}ˆ‘”˜¥ÀÁÂÂÜÝÝÞßßàâäëììöøøûüüüýýþþõK›bKGDýK “é^IDAT]ÁÍ.Qà÷;çkËŒ¦šéø‰¿ ") Ë®l\‚àF¬‰ pÂÂØXKÄÂÆD¤" cJ;ƒ3çLÕTÏC(8y|«yhãn·¸ ¾,Ií#Á®•C‚`| *M,àÇþå)‚WΟ¯–—W®íÔë:£©ñÞa×6…ÌÏ'†ÐÆRW&†ûdTQµߘš:jœ?˜—Ø„6ÆâlŠS’bs|Û5”B‚˜÷ܾêÌÆŒë£ÅfxšÇ­N=8í;“["@i&©¼ë²Óµ[ª™Á@h´4‰A"z8pdO¿z¡´B‹'H¦°þè^Šà©/æð…Á$eG:¶ò;–*[£¦a0ýF7ž…àù^Í7r%ªÖF9ê¶³R Ö¯jÊofŠÚ„ Þür—rꕈ«Uü*¶Ç#Oâ¯Èr2Jâ¾gN‰ÿŒ ÙO?I†WÁ§½åIEND®B`‚eric-6.0.8/eric/icons/default/vcsBranch.png0000644000175000017500000000311212342633755017632 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÚ µ¿’ótEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“¡IDAT8Ë…U[lTU]÷1sçÎgçÕvÚÒ©í°±´ E)‘G5J5|`H%щ&Äø¡høiˆøQ BbbªDR%±$4A J+}Oíc:Óδ3wæÎ}ŒçÜRcâNNÎÌ>묽ö>{3xØÊYûJ=¾ñÉ×oöÇÉø[»÷{‰Õ{<ž&ê’J¥‡º»»ãXm ^•öVohžãÊ̪¿ÚÄG«Ÿm¹¸­iKÙÏ¿\—O´~ßPßè´ÙlÃ0 ë:, òù¼šN§S‰D¢? ‹îŽÆø'ÊÚÜkïTVV•]½qùMþaÜ µ›Ž:ÊKˆèwÚ{/Ù׫Àó<(05ŽãP,-Ä'Pðí½½§e×v=F¡®òqz~FgUÎÉÞíüäËKþÂN»ÝŽdn—gc—09£@°Z­ ÌžÅû_uâàµNLûÓ\¨<$™"RÊr‘+üníúèù[ÉÛÛ3!ùB‹rªªbÆÆékßšPP*C6'ãû›? óÊq|1wYŸ_‰r>‡¤’ÂÒ|JV–³¢)ÅhbâÝ˹[°‡J’—Á³,M…hq~ä2vµ¡º´ ñ\g‡.àóþ¯‘pËüN€($+9è†C.bAIKŒÁÇ8<ã +Þó%ÄÉu% œ¸sþp>w ²y¢íÌÌ4 ¬ †cQ%¸9ûh‘ ¹=[­M‰­R ¬°@ì°[EØÉNF{ålslBµÄÀè ²wÐ\ß‘¼~·äB|:ލÆfæ1xTÍÊ×Ólï '3à/¶ÈÀ*Záµ¹àW–ÅfÁbbvÎ#¯ã|ö'´Ô7# ùtøÀi‘ÑñrhÖå+°C؈#:¬½=¬˜u,IRÛMÊ'Ù‡èƒ`I-[D Fii)ø)+ÆcðK}./ú§ðbÕ()a)„¦Ò‰`.H1M`òÊ–s¹\.7Š©d[„ÓáÀ––– i^b¶ãËÌ|ó[/Ö†êPÂ8-„á {‘ÍfQÚK–“d%IÇBÄÆ©gHU°ä™h«|ñxÜì4q䯔íÆ^~'niCØRÙ¿áÆÈȈéç DÉÄÌݤç¢u~=6kQ* êêê‰D Š"†††àóùÌæC/ ›ZM–ãããÈd2f/¡£££žÀ“““]äà ª#m4óóóˆÅb¦#=D•‚–!Õž®‰‰ †oúVTT˜»¢(˜íZéú÷ìðáÃà:ªi86ÙÒ$R@z@–eS eG&™LšÉ¥—<Ý=tèPÔìÛ÷ûúúºªªªÊ\.W3dœN'ÈoSʆÑžL/¢-µ¦¦ÆdŠÐè Áñ#GŽ<÷Ïœú—µ··ûü~ÿëµµµ«A`)°Ù?î'ÊœÌ@cfff|ppð3’¸{zzVÀÿ±ŽŽZ—ÕD×Ƚ #Ûø ÓUö7të¢ø‹©|´IEND®B`‚eric-6.0.8/eric/icons/default/drawEllipseFilled.png0000644000175000017500000000075712342633754021327 0ustar piotrpiotr‰PNG  IHDRójœ pHYs¼ÏÃPLTE””—™™™››¡››£©©²ªªªªªÆ³³³½½Â¾¾ÅÌÌ̱±³ÉÉγ³´ÊÊ̯¯°ÁÁÆ¥¥©®®²®®±¤¤¨±±³²²³ÈÈÌ««®»»À¼¼À§§«³³¹¨¨ª´´¹¤¤©¤¤ªžž¢žž£°°³±±²ÈÈÌÈÈά¬¯ÀÀÅÁÁů¯²ÈÈÌ›› ——žœœ¡ššž¬¬¯¯¯±¯¯²°°³±±´³³·´´¸¸¸¼¼¼¾¿¿ÃÀÀÃÂÂÇÃÃÇÄÄÈÈÈÌê .K1tRNS//00??DDGH‹‹‹¤¤¦¦ÄÄÅÅÉÉÉÉâââññøùûü¬Q“•IDAT­ÁÕ‚P@Ñm]ÅÄ»ÅöXÿÿU23‚¼º¤ð(¾ÒäÓÕû½š5 ¤qe(.žâyÌ‹dp$iÙâso’ÂÑyI€Ýâå‹ü8WbЗ°–-°‘0”DJ{ù±¯&€öM®] ÃË …#ŠnÅs2u¢¸4²µÉòpXŽëy4¾Åÿ|ºË+(iIEND®B`‚eric-6.0.8/eric/icons/default/fileSave.png0000644000175000017500000000207412342633754017464 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<yPLTEÿÿÿ $ #HFG`^_  " " #""%"#%##&$%(&&)'(*((*()+))+**,*+.*+.,-/+,/..0..1./1//1/02./2012113/0300412422423544655734744755766845856877967988:78:89;89;::;:;<89<;;<;<=;<>;<><=>==?=>?>>@<=@?@A>?A?@BAAC?@DABDCCECDHFGIFGMIJMJKMKLOLMQOPSQRTPQVSTWTUWUVXVWYWXZWXZXY[YZ\Z[][\^\]_]^`^_a_`b`acabdbcecdgefvvvxxxzzz|||}}}€€€‰‡ˆŠ‰Š‹‹‹ŒŠ‹”””˜˜˜™™™œœœžžž   ¡¡¡¥¥¥¦¥¦¦¦¦©©©ªªª®¬­®®®®±µ°³¶²²²²ÆÙ³³³³³¶³´·³µ·³µ¸´¶¸µµµµ¶¹¶¶¶¶·¹····¸º»»»ÀÀÀÄÄÄÅÅÅÉÉÉÌÚæÍÚæÎÛçÏÛæÏÜçÐÜèÑÝèÒÞéÓÞéÔàéÕÕÕÖàê××××áë×âëØâìÙãìÚäíÛäíÛåìÜæîÞæîÞçîàèïáêðãëñãëòäëñäëòæìòçíóèîôéïôêïôêðõëðõìñõìñöíñöîòöñõúòõúóöúóöûôöûô÷ûõ÷ûõøúöøúöøü÷ùû÷ùüøúüøúýùúüùûýúûüûüýüýýýýþþþþïªÄ tRNSooßãôýýý]Kvm IDATuÁ±ŽMQÇáß>{]d&"Ñ*I”¢˜D1í”^Î xB1­^RT21G¸gwïµþËLä&|ÿV¨G›ãk S)ÓÓñÎ'Çóƒ[I¡”©Ôi:;ƒ7ãíâµÖ©Öj›jæm ŒXU_±÷4RÂð‡Y6Ï€¼ _10¤¢Ÿ§ìEÈ1vQ¢=†¼¤l ŒŒ2Ú{öîOÇP0Ö{\È$ÕF¤c¸è¢$$™Ê #’×ü-1<¹ªcH\œÜä½ø<10†CÙO€Ì;ŸÇPÍMd¦ZdöcÄ´®5´ Éw±½+Œ~~e™×9"C}Ë60ú—Û7vÏ#…2u6÷öAêßì{ÍKÀÇà+ƒÿø ¾ÁÎåe+~IEND®B`‚eric-6.0.8/eric/icons/default/shapesAlignRight.png0000644000175000017500000000020712342633755021157 0ustar piotrpiotr‰PNG  IHDR¹Ú„¨ PLTEÿ=ûÝ-tRNS@æØf,IDAT×c`Áê¢X<0yX)¨¨v( t€(AåA…"Ì´ Çjy»IEND®B`‚eric-6.0.8/eric/icons/default/chatUser6.png0000644000175000017500000000203312342633754017565 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs¯¯^‘tIMEÚ!¯-F° PLTE#Dm=++?00OQY)y(0Ž/YO=nÎmeËdWÇW$l$'v'!c $l$W00YY-‡-] ` #j#,‚+0Ž/bÊa9©8xÒxeËd^€Ô++*~):¬9//HÂH~Ó~„Ö„X*|)*~):iÍh‘Ú‘6¢62–17£6-‡-}Ó|>º>DÀC/‹.Q@){(rÐq#i#lÎl){(/‹.ˆ×ˆJÂIF}Ó|`Ê`rÐq~Ó~YÇX){(~Ó~šÝš?½?VÆU„Ö„(x(ŽÙŽ$l$:=?ACFHKLNUX[]^ a !c !d!"f!"g"#i##j#$l$$m$%p%&q&&s&'v'*|)+*++,‚+,ƒ,-…,-‡-.ˆ-.Š./‹.0Ž/001‘02”12–13—23™24š34œ35Ÿ56 56¢67¥79©89«8:¬9:®9<²;=·=>¸=>º>A¿@DÀCEÁDKÃKMÃLNÃNSÅRVÆUWÇWZÈY\È[`Ê`cËbhÌgiÍhkÍjlÎloÏoqÏprÐqtÐsuÑtxÒx~Ó~ÔƒÕ‚„Ö„†Ö…ŠØŠÙŒÚ“Û“¦á¦±ä±ÿÿÿßdGQtRNS ##%&')*+28<@@BMMQUY]mnoqrrtuz|„„ˆŠžŸ¬²³ÁÇÈÙÚÚÚÛÞàäääóôôöùüüýýþ<ïÎbKGD®¹k“§*IDATÓc`€n]K -.4 ìUÔÝo/ˆ*Êf’Ó¹hÍT+aé, â™K”H¡«–Dä6÷ôµæ)£ËMO.¬®.(‘AæpnŠŠOOÍtdGµSÁkzmi‡§,º õæ.[:Í]TÞ;µ¼2%@ U”Ç%¾rÚ’¹Ù"(Â&%%½³V¯“eŽ,ÊëžQß3cɪ ~âHšUÙµ]SfÏ[ÙhŒ$lYÑÚ;irocœ#\”Ï'"¹ ®­»«¥,&M.¬Ô›]\ÝP_‘§Öo ŒLÈÎ/*̉Ê1€ k,KŠŠOÉH‰ ž¨pXÑœ•X3Ï–.Ì"iææ¿|áüž®¦¬2sŠ)êj+Šr2€$WNOäIEND®B`‚eric-6.0.8/eric/icons/default/preferences-helpviewers.png0000644000175000017500000000167512342633755022571 0ustar piotrpiotr‰PNG  IHDRójœ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<øPLTEÿÿÿGGGJJJ¨¨ªÕÕÖØØÙÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²FFFAAA°°±±±²²²³³³³°°°ææçœœÀÀÀÉÉɵµ·¶¶¸··¹½½¿ÄÄÆÌÌÎÐÐѵµ¶rrr´´¶¢¢£µµ¶oooµµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º»»¼½½¿ÀÀÂÇÇǽ½¾_¶ `´ b¸ h¿u‚Ú!„Ú#‹â$wÀ$Ð&‡Û(ã*ŠÚ,xÁ.ˆÕ0x¾F™ßO—ÓRŸâU–ÎU–ÑdšÐm©ànªÝy¬Ø{§Ó‚£Ä‚¬Õƒ£Å‹¬Î°ÑŽ²Ô‘ºá’°Î“¸Ú”¹Ü›·Ôž»×ž¿àŸ¿ßŸÂà¡¡¡§§¨¸((º’“¿Ê×ÀÀÀÀÌØÁÁÁÁÁÂÆÑÜÇÇÇÈ45ÈÔàÉÉÉÉÖáËØåÏÏÏÏÏÑÐÐÐÐÝéÑÑÑÒßëÕÕÕÕÕÖØØØÙÙÙÚÚÚÚÚÜÛÇÉÜÜÜÜÜÞÜæñݵ¶ßßààààààáààââÎÏââãââäâèðãããããåççèèèééééééêéêêêêëêëëëëìëìììììììííííííîöö÷÷÷÷ÿÿÿ{«îJDtRNS #*+266è/Wä2Ü–;p.A‚° 16…‚ôõ-µçˆ  ÑH;Wø/ÕÓ[kAˆJ€å‘Ûé¢wG cóÅg­(|þT,¶Û™iØÇ)~èpÛµLÍ ¿ÙÂÔúÄÒ7¢‰MŒhrB4T|ËæDˆ/p Š£q$‰µ—«jŽ8Ȣ飸ɤÌPó]â÷#}ÿ˜¡BGóbýÚZgË£fÞÎòÀµç@ÞO"WŠ´‹ ‰H§mfÊøzå¸éMSqB>‹ f—ƒ›Äº÷/© &¬ UÏ:ú–{,T¾ŸqDuDKIEND®B`‚eric-6.0.8/eric/icons/default/preferences-vcs.png0000644000175000017500000000130712342633755021017 0ustar piotrpiotr‰PNG  IHDRn½¤°sBITUìF pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<FIDATÁ¿nàïÎçÄÒ&MR”Òª£6 O€„ o€C;³ÃÂЉ'¨@b1Ñ¡/€*±”*$$hiKcÇ®Câгsöùr?¾/ Ó¶·q¸V!„eÚÿðÉÃÁxZVQFULËÁøÉÃáË4„„ßíçyÌb1ŒA bÃ8Œ<òèç¿Ü !$Ÿ¼óq"Tj©DSj)ÔRjÚÚþìæÝwwWÓ#‰Ú¹°Q_þúÝøëO€$wÞ²›ö¨_xùýøÙ&¯ ÓIEND®B`‚eric-6.0.8/eric/icons/default/vcsLogout.png0000644000175000017500000000221512342633755017711 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ6  †…tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ñIDAT8Ë}TK‹cEýnß›¤óêGn:öˆŠÊlÆ´›…^½q!(¸wÃàÂ!èÆ_àÆ ôÆÙ¸Fºm0>°Çg¡³_LÒ&Ü侞óu*“¡ ¾TêVÕùÎ9õUY2k‡‡‡Kåf³y!‚Wã8~kmmíÅF£Ñ¬T*Nžç’e™”J%‰¢(L&ÞÉÉÉænV«Õ/=Ïû§ßïÇ;;;9ñ,þ,à…ÕÕÕwoca¥( ñ}_ÁlÛŽÙ–––ô?ëtD¢ñxü)}Œ„·wwwCgoo¯æ8Îõzý½•••ËÜ€IÔÌ–¥ årYA¡D¿›ÄÆ÷ ”^K’ä Ô|ˆé›Þ„œ×—¹² (7"ñœiš¦:ÏXTÁ10žG¼®À»ož¢,q{2情L§Ó3VpÞ$f2Žù½×ë]å:»ð¦)Ì8—Îà¦E £Ê€38&Á`PS`€µ`~íøøXÁÉŒLŒŸÆ£h‘0ôlÂ0¬+06©„rQ £B¤V«©·f㣬 K&m"1€r*0 .`FnØÜÜT`*`FgÀØPã‚*áp¨ ´rŠß³ ½ä72;s}}ý 0›)C”§zJPî1 ñ­b¬bS™7jyyYí`O/q¨s©aã:ÚE@SüFiThÍ"‰SÅD‰Lh™AÖá&SŽTÊ5´Â”mà !à•ŒÇe„ͬ 2&S%^_~ÿá ñ'c)x)2^ŽLû{‚Ë’%’D¡dq‚}±di„qÐ~ç¥ê ޼䖑ݥ,6×uÕÃûÝ[réÙg¤ºÚ’Ø÷$KbIãj$‘O IBôáTüñ¿âlÏ–k<)¾m¬`£$d³Q•é¸/½?•`ãüR€gI¤¡àq )Á£Ó>„myžŠ½½½½?+¨Ý‹ôÕxJï\ë'ˆ?øI~þñi¹È=e›Fìƒóp®" ñ‚D¯ôGˆ1|¾ –.™w:i·Ûò×í{Òn=K¯ÄrôíPâÀÃ]Ο2'™Ï’(kŒq bw»Ýïçêõ3Ôç-<Úªc3ÃFÝŠ¬Z£%?æb1Ø&l1MX@MŠ‹I`KÎi×_n~på¹§ßXj>‘°"O•ÍJÉ16oIÐ!^ ç<à~ÇÁDû$fNæÁºFIKñÈÞs=?üæè·¿G`ÓTBEþð©dÿ?¸S ¢L¾úZ8 ˜ƒ ÁIEND®B`‚eric-6.0.8/eric/icons/default/preferences-security.png0000644000175000017500000000147512342633755022101 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<•PLTEÿÿÿ‰‰‰³³³›››£££¸¸¸žžžºººÄÄÄ———§§§£££»»»»»»¾¾¾¾¾¾ÍÍÍÁÁÁššš¢¢¢«««¿¿¿ÉÉÉÆÆÆÈÈÈ“““   ªªª‘‘‘ššš¸¸¸˜˜˜   ¦¦¦¹¹¹»»»™u9›u4›w;žžžŸy0¢|;¤~+¤¤¤¨¨¨¬†=¬¬¬·Ž!¸“?¾¾¾ÀÀÀÁÁÁȕʗʗ˘Ì™Í™͚͚Í©7ΚΛϜММÓžÓŸÔ Õ£Ö¡Ö¤ץأأئØÌuڥۦܦܦÞ¨àªàªá«ãÂ,ä³å´æµç¶é»ê¼ë½ëÔWì¾í¿îàrñÂñÂòÃóÄöÖ+øØ+ùÕùÕùÕû×ýôtýôwÿöt0ïù=tRNS "#+,36=?DFFGGIPSUwy}‡ˆÇÊÊÍìììììïôõúúúúûüýþþþþþþ•ú«!ÑIDATÓc`€QU=}uq4 dãniáb­Œ**af¥ÀÁ.oj&‰"¬âª¢äÔP„uÌY@³‰.а„ÖðF6„К^¨ÂFZ MØBk# —åy8;ÚÙÚ;¹y†V¦"„ëªóü}ƒ¢3‹›Z‘„ë« B¢â3J[…k‹âýÂ’sJÚP…ƒ}#“²J›Ñ„S"Âcӳ˱ çb®@U]S˜ˆM¨:<8& ‹0¦jl€‰‹‡O@HDJFVZLXŸ—›“•¨£J÷¥Ô7aIEND®B`‚eric-6.0.8/eric/icons/default/securityLow32.png0000644000175000017500000000321112342633755020417 0ustar piotrpiotr‰PNG  IHDR szzôsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<IDATXÃå— P”UÇÙE×…¡˜Š1ÆH1‰@0'QS˱ò‘#&Æ2â *¡“#+X«©XÊKyãºËQ‚¼â‚ˆ—®¨¼”ýwîúÉ”º¤Ö4Ý™ßì7{ÏwÎÿžïÜóÝO €Ú¿‰ÚZ >ã@ƒGhÚÄ4mî?ÞK@c<¡/M”¦uuuÒP A.—¦¤Ê²Ø³yá¸U¿²šFYyigoo/(8>|6Øo?ªª«n­Zµj5³U5ªžÀVvà€Ô•Æ+ƒwîÈq»µy›7ãìœ9H¶°@¡ƒî¶·£§§W¯6=ðóÛÇec³„ŒXÐ$ôì6Ù9IÏܸv½ím¨Š<…0½7K·RΑCH‰X==ÔEE¢­­—êÓjkk»“ùà|©«$€©ÖÒÒ2v¹EH%]uõ5Šæ–&4ÖV#þKKóxÊ€%D3q“¨%2ˆ6gi‰ÊâB”——"¿ OzÛy‡sù|ù~ª®ÈæJ$ ÷kêªP[_âì œÚø-ütuq„ÌÏED#ÑMôíD ‘I„‡´µqrýWHFff:d©É‹û˜ï'‹t$Šýogå¤C4œø|x’ Ç¥¼’¸Aô â—2"•áOì¡{]ÍfâG_l²·»Ë|?K{ö&"O·æ´Ìdl{ý5ì&“ â$‘B4¹¸ ÒÔtXÀ!g00@óîݸ@×g‰„7ád½AKšS¦LÙ—5ãÿ“R€øOJÕyH£•ÞêÆã1ÐÙÄ÷ÍÐ0¯œgãxÛoÄwÎÛúúú»˜oU°0_äáÚ’‘)Ã~ƒ·Hf§Ø^ç‘€q<$Í0Äýk-ÃúI@ül3\ÖTG Í'sEðædxxŠ`ccý;ó9Ò{b´N¨»|ŲÓé$ ÜÞN¹¥ØŠRH€ìÝè»yc80ãñ5ËB> m0øÅJ¸ïuÃâÅ eÌçXZ±P ¬þõpoFB444pœ5!ccô·µ §=Ö‘sÍÿ*ÂÌTY°ÁB!ü©ø¶nÛ2@¾¬™Ï±`鎛KÏ]ÈDØÒ%8J¦ÅÜ6dÁS?0G»ž:õ5L"8—ö¸(³ul®|öyÁjÝÚæk´ƒËÓÞ„¯›û&¥H©GÄ8, ”!H3Ÿ‰*zÞÍ“ÆãºŽ Ç#Ò_Bs¬_„‘íÑNlû)ŒŒŒ˜¯1¿Ž¹b\äé%ºžWƒ¤mŽø…Ì#‰$ª…\zÖ%TõeB>Š|dQC’ðkÔkøùûb£m;óñ´Cʳκ&&ÆiüÐÅ‚ó|ö)B¸¦”HÁR‰4Ú÷2ú•pÝRòÉÇ8vä ë~ #c£C£ŸªÆæööv¿æ¢(]†èw¦+ËD,÷‚Šá¶iœ¡!CC >$f­·ŽÝË|<בŒ5¡Pøµ—·gWqiʤ§‘¸h‘2á\Çc¿I "',ñ ±pÜê §{lFj<G{Aéêèèì :xà^uM%ê+ÊQ,Âù-Ä¡ìb>²ÏeQåûô‘í÷ìUÎ…c9”êÑp÷Þç-¯ª®À•ÆvþCSS#êêkQt©>>Þ÷¨åzpÇ0Þ =–s"tˆ5Vë¬*O„ïËËÏÊËË é·¶^_Ëæ8ÞËú.`"„ÄTÂ’ðâ°äþŽõãäy>ÉÜiW“»æÿÿ>N_f§¹Y?æ+IEND®B`‚eric-6.0.8/eric/icons/default/certificateDelete.png0000644000175000017500000000223712342633754021334 0ustar piotrpiotr‰PNG  IHDRójœ ¬PLTEŒ oŽ ¦ ÑÑ©ª«¨©ª§ «°‹Œˆ‰Š„ƒŽÀo½©© Î GIüqrørsöuuö€ô‚„ô…‡ö†‡öˆ‰öŒŽôó’“õ•–ó˜™ó›œôžŸô ¢¥¡¢¥¡£¤¤¦¤¦¦¨¤§¨ó§©¤¨©ñ¨ª¤ª¬ò«®¤¬·¹­¯ó¯ ²tJ··¸·º¼¸¹ºº»¼½¾¾¾ÀÂÃÂl^ÂÂÃÃ0ÃÃÃÅÅÆÅÆÇÆÆÇÈÇÈÈÈÉÉÉÊÊÉÌðÊÊ MË ËËÌÍÍÎÍÎÎÏš{ϧ_ÑÑÒÓÒÒ— ÒÓòÒÔïÔ› Ôœ ÔÕÙÔÖïÕÕÕÖÖØñØÇ°ØÐÆØØÙÙ§ÙÛðÛÛÜÜÜÝÝ˳ÝàïÞÁpà¶Aà¹"á"âãäãäåä½ÁäåíååÆ\åÇYåʈåååçÄPèÛÊèêìèëíéÈUéêìéëìéëîêçáêèìêîòëììëíïëîïëîðëñðìÐ[ìêîìîïìöùíîðíîñíòñí÷úîïïîïðîðñîñíïòòïùüïÿÿðìæðìéðñóðòíðùûñÔ2ñÙ0ñòóñòôñóëñõøñûþò òòóòóôòôíòôõòôöóôõóõõóõöóøýóýÿôôõôõöôöëôøúõõöõööõö÷ööööö÷ö÷÷ö÷øöùü÷ã?÷å?÷÷÷÷÷ø÷øø÷øù÷ùî÷ÿÿøéGø÷øøøøøùùøùûøúûùøúùþÿúûýúüÿûÿÿýþÿþðFþÿÿÿõŠÿÿÿ¹éÂtRNS@æØfbKGDˆH pHYs „ „ªâcytIMEÝ %›X¸îlIDATÓc`@Á ¢ §Ńƒã±ˆ@gBI0l1°èã‡_˜YXÿø1ƒìÃ'N¿~õüµsç4ã㞈÷z,T}à@YDrlUtJQ’Tʶ¤€TßÛ~ìÆ©S\¼xìâ©›wïÞ¾ýžÃý>1MaA~!)þQ•ùWߪ¾¼dûÞ½îÙ¹lûÁÝ»VvwL^t¨úμyóg/RóæOª}ô`]õ]¹ýÓ¦WX›ë]š3gδ%ëÏ^9S¿¨úðĉ–n;L—æèLœ’Vž›—•¾ ¨zmOÿ!ý3‹MS{Këúºf%ÌTd`Ø<ÁÓHGÛ8n•¡SM§w{[hê> ê…¾®îŽ®ö66¶®Îv^Á…ñ+€ªo/?½çjhÍnHlf`aP‚Ce•À­ êšjÒèÙÊÀ`‚ª™ X˜%2¢e­KñÔIEND®B`‚eric-6.0.8/eric/icons/default/unittestRerunFailed.png0000644000175000017500000000250312342633755021724 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs  šœtIMEÛ +Pwk!iTXtCommentCreated with The GIMPm°—bKGDÿÿÿ ½§“–IDATÕÁKŒÜuÀñïïñÌfgwö5mq»¬ í kÑ–‡ I ’†.¨7ãI < áqE=Š“¸䢠é*)úØÖMîtwºÙ™ÿüŸ¿ßÿçz" õèçÃÿÁ—øýï^»/ðô‹¶•;§ùõãKûk~1^ Ê»”²ß²Zö„;$Áõž/Öû! fü’Åó ]ðç’í½¥êTøž½~ü­†š^ªÉ{~5(?Œ¼ôÓå'ÆjåøÌxúõÐËHó²x¦¶o"§3h!LF–¨[²÷o½Ã?!úê„õHI1Œ\\!>ñÇ|:ËZÝ _0òÚ“ßü Y+¹©ÝÙfØool•¾Çf¯Äo¶¹£2Uˆ^/X;ò3¢ýócȺë8©¨Í¶ÑR’íôJ³ðÊ‹hF¢H~£"¢°”¡NIrÍ0+¸Ø£û,­ÈÁŸ-‰]¦ Ì{ï¼ûX‡RÐ^Z¤óðqleÀ$#+«»—¯m z½,¯ûµÇ9#8¿æpø(áã>²”Ú':û)êÝwØ­³~ïïyP‚^ïÐ^9ÇÔùÏHs‡bdaÚïïÆåénÏd×·i‡ZÔ÷HV:Ë‹ãLÖ,ò»ÔeÅôÙOø—dGš\žkpm%á‘Ü"§gÐW®¢?ù”–sŠ‘ÉHïÆ™½gÕÚvì6;;.¹°æì…Ne+'½;…œþ0Ã$&D%ø¬¦ÝÉÄÚ·¶óÞ?ö›o«|õ·®<ù²oWÕãš‘«[yG+tè¹m_»u)¸•n!+ÝÔÇ«ikcÓ Mù­¹~5Óð¡ž:â ¶wy,»òÃĤßî“›R\;-ÅGUåV&J„à…'š¯Î ”§j g™ëŽF”ãs’dóïv°uª §4·ÈDüÉ$Ü üˆ™v@4-hÔ[øŒ€¬:Êæzû²G+ñ8-¹E‡ºýˆW6©¿ÎöŽ¡ª ÒÐ`¶ óÏÖ†5‡bÁÿèLÄL3á±õñh YÀéØãDßãM {(Áý _1/y’—IEND®B`‚eric-6.0.8/eric/icons/default/google.png0000644000175000017500000000106112342633755017176 0ustar piotrpiotr‰PNG  IHDRójœ pHYs:ÊduhtEXtCommentCreated with GIMPWPLTEŒŒ%y%¤+ž , 4µ 4µ 0¦ 1¨ .¡ 4® 9š5¸2¤5˜;­6©>˜<–7Ÿ>¨@”CœEO¼ \Ê!Hž(U´+P ,R¤.U¼:´&HiÏXo½n†¯n’ás”鎺€Ç„”¯ˆ›ÇŒœ·‘¨Ý‘«ä“›¸œ¯Ö ­Ñ¥»ò³»ì·Ëï¸Åó¼Éñ¿ÑöÃÐòÄÕøÅÐêÇØùËÎÞüÛäöàãêåèøåë÷åíýæíõèïöêíôêî÷ìòøïòøòôöóõøõøûõøýöøøùûþùüýûüüüýÿýýþýþþþþþþþÿþÿÿÿÿÿŽÍztRNS@æØf IDATÓc` VD0á0ðssrö1¬‘„M”øØ9Ø…tÌ‘… Å4ì’F2Ì.H¦‚êö`“\= QC¸p¨‚6a_Yq¬Â<¢Ø„C¤ØFIMNPRSUüüýOŸ ãIDATÓeÑ?kAðÙ?*$œ B0Jº¤ -ü©òݧ³H•&¦M0föœÙÌ®Üé®î~pÇžŽ-ÔÙ oF/µ:dï xÓº1r° íÇá@DzþÂû¯W}±mBÿýôØ Ï‚²йw< ”øÞ·Dä•ðNP(X¡U#w |ɽBLÝ_·&=ß ?î3î3“uú2A~8 eʼ(4Û®»Ð~I©WzH•2 ˜éh|9 G¤´Á _õÖ«ß#ßð¶œÃuÌ’?­³)ÃÇÜÁÿ{¨†üp*SIEND®B`‚eric-6.0.8/eric/icons/default/notcoveredPrev.png0000644000175000017500000000227512342633755020737 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ)iï¨tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“!IDATÁohÔeÀñïóüž»ßïî·»Ýmsk·Ù–éÌf §•@4.—¦9EÂèU¾Îz“/ Fô¢WDŠd ¢ÈW$.ƒ\ÒÅÌlÓéÜíÎín»Ýïy~OZ É}>ÌË.2~·?°¥gË/Ì´•ýu{ëFÓÝé½<@2—.66ú¿xãÀª ×.Ôs×[9ÒÙÞùÑžõ{ªsùÜ x”.ö¯hYña÷¶n%#’áܰf 1;¾mý¶¶æ¦frÃ9Ì¢x˜ (|Þñ\Ç««×¬… €žÖXÇ&küšóë:«ü˜Ov<‹$³(ô 1bÇ»6vµeš2d‹Yt¨ mHÓMÕíO·[cSc˜iƒ‹ ’Y3mç…TEêØ¦5›ªã•q²Å,F4c -Ë[¸­o hLÙ`J†ªxHfQÜ·›·ëÓ™ƒ«ZWªÀ ÄØÔÆ1h©1Âàýà‘kÏa+,:0Aˆ) ̢؀¢NYXÕ¸{é å‚ÐVc"£ ÚÑÇP/" -ÆŒ1„ÚÐ ê‘BÈÝ;e´²3ÜßRM‘ŸZKžOÆ’ä‹y´Ö„±+-Zj´Òh¡qo(Ü#×aËXFP’‚Ð ¹8þ¡„ͽ½!3(ò¯ëW™Ì‘i‰LIlÒb| Àb°T.&u¶Lë9CCMœò"¡È¥–•2û:–½¯­-¹©Tzøôé¢Ò—ƒµú)},ñXåŽÉ\íh< ø€VX RøÔkYåUãE«pUµùuuß ¥( õ™rùÉ)4ŸØL¼köµsC¢€ø€ä_‚’P Bå ¼("±7‹—ûúö}èÐKŽsÞá¾Û_^¡uÓîVÏõÜrdZ| R§Ó$‡Æ©Q‚j×%º”Êc…¢°Ñh´&“i[´xñÊé+W&3}lNL¾YhsÓ~_M´vɨ X0:à.a,z²D.—'(M£k}¦*"ÙgóöƒñK—N~ÛßáS³ˆhP_ٸݩ—É@,|?Cãå¬M-Sz¼UªáØ”˜Ž œê*þ>;ò=_Úîù¢µU8<Ìo„œ ²ÖqÒ‘êuŽÂP"÷z? T‘T‹€*ÄR§á}e+’ê•ßäûbBI<^3¶·‚o/68( ÿÃü7éEUwIEND®B`‚eric-6.0.8/eric/icons/default/webSearch.png0000644000175000017500000000242412342633755017631 0ustar piotrpiotr‰PNG  IHDRójœ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<‹PLTEÿÿÿUUU¿¿¿sss¿¿¿ ]]]GGGDGGSSS–––“íü”íüVVVˆèü…æüˆéübbb~äúmmm€€€|âúzâúyãú›››oßørßø­°°VVVnßøjÛø­­°iÛøfÙöbÚöeÚöpÜø˜˜šaØödÚöSSS`ØöYÕöVÕôPÒôOÒòOOOOÉîOËîNÊïTÎñMÆíŸŸŸfffY[[¢¢¢KÀékÚõTÉî^ÏðH¼æLLLG¸ãuwwG³âsÙôC¬ÞA©ÛHHH€àø@¤Ö? Õqß÷¥¥¥?œÔ_Àè<šÒrss=–Ñ|âùBBB]³à¬¬­§¨ªtËêr×òY®Úd´ÜlnnhÙõmÜø¬¬¬ äö|Ùô€€€F‰Ãq²Ø••–AˆÅ³çô/p¬}~~wÐïŒÈç²Üí²´µžž Öðƒ„„†ÃÃÃm¥Îq­Ø€ƒ~~¢àõŽÌéºÚèÈÈÈ"Qœ¥Ýò#N™³Ëß=©¨¤«))®?=²FD²ee³€³¨§¶´¯¸LI¸\[ºNKº¸²¼¼¹½YY½¼º¾XT¿´±¿¾»ÂŒŒÂ½¹ÂÁ¾ÅÄÀÆnkÆ–’ÇĽÈÇÂÈÇÃÊ||ÊÉÄÊÊÉËÉÀËÊÅÍ~|ÍÎÈÈÏÎÈÏÎÉÐÍÄÓ‡Ó‰ÔÒÌÕÓÍÕÓÎÖÔÎ×™’×ÕÎÚŸ™ÚØÑßÝÖâÞÖäâÚääãæãÚæãÜêçÞìÜÓïÕÏïìãòÜÕôñçøìäùöëùø÷ÿûðÿþý†—:ÂtRNS@æØfÕIDATÓc`À 8¸¸¸QD˜¹N!V8`ƒ ñ'['8¹%˜F&ˆC…³’}²B¢²Ü3²” BB…9&†±i…þù…ÊP!‘ªRUUýܪðŠ*u¨o€‹ªªŽ«•³«LU±E`¹ªª««–ª4TH4ZÕÆCU5)]ÛK*Ä£këèí f`lä'âK,НÊRUÍ„/\RZ’j©ªjf. H‰óL ð±‹Q€»« ¨1¯:¢²Z*Ä­§"©'%£'¡©'bbçDXV2,‘;¼êúIEND®B`‚eric-6.0.8/eric/icons/default/siteinfo-media.png0000644000175000017500000000237712342633755020632 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYs  šœ¡IDAT¥ÁÍn•×€áw­½¿sŽíslŒ]Œù³BB)E-Œ¥êTu–èµ4³N‘:¯”YZUê Q¤…Bþ Æç÷Û{¯µzP‘zyáÿ ü4kÈg¿ÿìö›7þ8HƒmÞu¦ïíLôï9º,{uÞ!ï8Ì¥ïÖa©vúõÝoþü»?ýå« lìmì~:ÿrö‡yÂR©M0‰2ཹNçûåõFe͈ЛÞwS¥À/OvFÀ§Ø\¯Ò¬K"€ ¢€ˆ¸Œ»iRnè“H ¬ÈJjYïL‡QGR;[jÍΛЇ‹WeoÑV[2èF9“SN"‚8‡Ý£îq…:“/=FЈ8=>¤$ï„SJ( ét0Z-Ó´¬[]óí$¶ÏNN¢ªdy]÷Óž>ò!‘,D[ÁÛ.œ³¦É[ +„;Þ‡’Y[-ª°0ÑÜ f]ŽiêýEú¡ù™¼Á0ÍÙ’W¹ÆY)áq*Ò¬ Ž/{½ºeJ«„·(=H¤,ª¤¥¡ÙI-‰¦QZIÖ¯ù±]AÝó3ƒ'9õC™ë¤½é*=÷v£}xd¹³PܨµÆInåõYi¬eÖ겡}s5!»‰& Q~–òÒ<Þ”šv¤Ë4h³¸¿e¶õ‘Ť‹L#N‹Å]íÏ]kz` YË€Áë ú ?'î‡N6¼“¨BÄDɬY…äà¸F˜ô¶Ê…Åfoe”}•F,ò¦^þ°Æ¥OÈ×·Ñ‘ Û£­!¢bF„ã^…µ HD4i~:š–þÜ­[;*†5¾/ý¯ÆøÕ»\1¿F^íóñð9%/ÃiB¸°9Q9Œ ˆ…Iß-Ëôp+8øxcQžoëâK¶—=®=•î­Ê«3&»&zë6Ú%Fÿ£!¢Ä}¢¬M«rrtvp{ ySÁÅxcË[ üꡆ<ÖÍô?’Òîºo-ü‹¯h}QDEÐÖÙå_êäâ q¯˜-b~塵_e ì^‹M—Ûƒôì1vp=òìJÈçßDyôCøbáÑZP+´Æ;’A³F4q¡ ·þæN‚D+ázˆËë åÁTâ :ƒqäz5Ò?ŸÒνu?š¸îïD®$óN4Ü*xô¾¸ÞGo‹”BXûš1ëBÿñ,ÕÇ%mï°²y1º“Uø4ŒúÄ˳ûÖ2 áUÜ áà›+V—³¸™ˆXÅjƒRY“»û©û׿£þæFëRÂZ¨«°çC;/C@2`Ö^Îh.¢Ú§—­Nv:jAð†ûŠñŽ|žrð´¶£CËnø›ç2,ÇÓwîlïOwR7ÞM<¯›ßíuªDPñÜ’œÉ´h¬þövØ>>¿J]g†c,fvò÷¿Ö;À±L€€-~š9ð0ý/¥Æ ²¼IEND®B`‚eric-6.0.8/eric/icons/default/whatsThis.png0000644000175000017500000000311012342633755017675 0ustar piotrpiotr‰PNG  IHDRÄ´l;sBIT|dˆ pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<ÅIDAT8Ë•yP“WÅ?Ç;*¨ 2T±ŠŒ¶Ô©Z:jdÜZ¡à‚ÚÊŠ "¤*ŰÆTв…%…°ƒ,¬MeÃNv ûj 9} Ö;ÍÌùçÝwßÍ}çÝG >“ɼ‘À}+VTL\>Ÿ_R••YXÉÍ#q¶R±±±3å+5ãbRRRF…=KY…{—4Uåf+êÚ†Pß>ŒWyي½Ë”±”vXXØÿ |ûøžŒÛ7[ŸY.ž8~†¾ëÛ!Wb`x#o€1ÉKŒ„Ú©Ö×)R¬½WaµHí?Á| ]½tkƒæXOôû›c‚çäyAR'DKK šE4½,x§TëʸrßSÃeîGÁY»— Ÿ¸™ƒvÈ÷¢ÌÑíö øqäbI ’Š^@,CôÐcžšª¸rßð}[”دÎfîÒ÷«³_‰‚ð›ð®aÔ{Ë&£÷þ%iiƒ£ ¡éê«3™ò6§¹ÀÙ@î·ïÀ*¿i`®¹ž‘Àr±,7ÈqtŒ_ÓFòá%ý¶_¯ßo`` NNŸÖÚÞï p'³Q9¯ÐØ,VÔT»LmYXqš… î™ÐwÎÂæK\H¥Rd^;ˆG4„y9ËX,–Éäì[õ´ççÍ*/ʯRhr˜++´Ð]ñ/811ÑeddTaäÈDŽ V144„´’j,wJƒùPIE-ë^AëŠÇ§Lª>Žîn©´°°°R 7óHVµÆÚ7 ===è`xN^µ0±WÃÃ÷ŸF‡Z¬NïöØð}»kÑ{N 5¶Ú“d|Þ5Ñ™kV^^ž°PKÝúÒñÃÂö ŠÊê u„ʆ…¢R!$ µcÄQjïnƒÁø-$$8'ï»OûúüwO  `c ^ÐDëÉ98s6@ñ•}ÐÄ&{ú„Ý ?Åg!Æç4FGGñq‰M"ŽþšŠˆD"ƒiCˆT¾‘vÞ©¸Àv¬Ãcªßà…›Bj~‰õ¸žØ„„h6rýmzjºÛExQ/ÁŸÏ088H†S«ØÈÈH{ÆAOþŠ~°•q©ðøjEOÐ>LfÐ ®­A…(/«ðœ„¿“àºÛÈí]þþþîä<ÖÍþèÓ¤¼yG¶;&4î-±5’õ•ñåÊ׃<"–ÈÓéÞ²xû/[·éª««ï&°DzDs¦MòÓP.-"Ò'ZEd¢¡¡±åرc~îîî¥á‘]É©éÝt:½ÊËË+†Ä¶“=J™½­T™·€HKé¤aÒ’e/39IEND®B`‚eric-6.0.8/eric/icons/default/openUI.png0000644000175000017500000000203012342633755017116 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<¥IDAT8˵•ÏoUEÇ?gfî¯÷úZÚ"j *( Wš&4¤„¸daL\º!1Ñ•1ñopçÖ(q)®ÔƬ4"B†€Òú"ôç{íëí}÷ÎŒ‹¾W^ûðGŒNrnιÉ|æ;gÎÉï=ÿÇ2;ˆÈ~`¨þCŽf½÷3 NÏÌŒÅq‹Ji-SÁ¶SGFFÞ:Áï»3¾TϾ{Q†0¥¶ ÒÝ:¤ ¬µVíê¶‚jZD–ïÂÚÿ7}#àáÍj=å°ÛÎæ”ã/|Ê+=Ïì#/¦¨­}Kšíamõ>;‹V=H³åêi¥ µ|eìò½]&ƒâæýÜïéMpÎa èíRÔÒ‚F³Q{ŠÙq•ŒîÏÞ»\¹QÇÓ ü懕:˜@³PM‰BS˜R­k….ÇkV;J±A+EÚȘ¹!Úѻ۰<“:! 4α¥×:(Ç!&0,VÑ¥8ZW•$ZÐ¥’J”bÁhXm®±?¨‘„âIbM)gº’hEUÊÑ}t8âÀ’„žr¬Ð ²¼NÎòËË<}üW.|±ÈüâƒáG/Ƴ—>Ǻ‚$„$°$C º»?P•DOiq:Ò9±)ˆ£)Œ¬÷ ½¶ÆjVå»óˆ÷<¤¯av1v÷ ÷®¹¯ Ò9 §»KzÒ$²q»¡”JB(,xI$ÄI ðØ0gømÍòl„éçcÂÛ÷Ø÷úÇø}G·•™Ö Ä«rànÉæ¯=€µÖ:Î/2tð Yuš¹ëéÊIt˜Ó/FLN|ÃÍž‘þ—жØQ¿ c„HÖ¯šé«?]<0ú–K’ÝÞMÝ•QŠ|˜¡Þ ¢(Aé€k—¾bvê$•ÝKôtWú¶ï©$ ÷èÆõŸÅ{ˆ.uujüÛ9'àÖ×Ö~óÞO´ÀPùf¨V½÷ÅCh'ôÛmuIEND®B`‚eric-6.0.8/eric/icons/default/safari.png0000644000175000017500000001214212342633755017171 0ustar piotrpiotr‰PNG  IHDR00Wù‡sRGB®Îé pHYs  šœtIMEÜm¡?¥iTXtCommentCreated with GIMPd.ebKGDÿÿÿ ½§“¹IDAThÞÕZ pTužþ^ßWÒI:Iw:M’p_r£Ã¥"8ø;*%޵:µ;;µ:[Så:;;ãÔV­U»#Ö"ÈêÈ "x ¢¡0B’tξï×ýöû¿HÕnmÔQq¦^õëôë÷~Ç÷û~ßïÿGÂmxíÛ·Ï”J¥~‡Ý‹%_£Ñì2›Íoßwß}i|Ï/Íí¸‰,Ë»<¸sãÆñÐC=8<<<) -»víšôÞŽŽŽò¾þ~ïöíÛ¯ßú[AAÁnfcü‡~dþ¾Ð}טŒÆátZq+Š¢{çÝýžŒ’™5ØßçI$’CZ­Vþ¾¸-)Þ¶}ÇÆÁÁÁån·Ë›“;åÃ?l?tèÐêÖÖ+ÿ/¯üpý”qU•V®\‰H$’ÊÊʺi2™’,nm,ËD£QV¾fÖÆ™ÊÊÊÃO=õÔµÿuvíÚµˆÆþ´¨È½Öé,Ô*ÒÈë¿\Gˆ!“É(iâž9þ¼ÒÞÞÞÖÝݽsêÔ©ÿ´víÚÈÿ˜O>ù¤¦´´ô®òòò¦L™2Ñ©S¡’ˆ´ßïÑ#N¯Ó ßaB~ŽoO/z{½,ú(JJJPìv+Åt<KŸ}öÙ…S§N=³wïÞC_e›öëŒg4t}ôÑëׯß(Œ'Æ•ýû÷K[·n…ËU„%‹ï„gL9èE{w&k„IP–`bt+ËÜÈs8c·Ã’•“Å _ ŽŸxÙF ˜?g2œ…9¸Ø| þ`PbíHìì kËÅ÷EÌÞUÂóê·v€ìñæc=öo(‘•Ý»wKt÷®^éÓ§âý-hhÆ=Ëæ`âÄRXhlZ«U‹±eÅe8ó²`±ŠÈ‚çù;ÊJÐèMxïƒ&Ö‰>°5Ô¦ÖëF"C)óçÏÏ!9,t»Ý×[¿±¤¶¿Û°aÃÆ3fè…é”Nœ8Ž …Ö`Ã?o?»îšÅµw°H ˆ§% …â˜QS«YÎÁ0º¼~d™ H¥$“2RršÚ‰”ªÑ"ËfÅø e¸é àÀáV<ü£%è¾Ù…x"! _"L1sæL;™©ŠŸÐ)ߟìÀÒ¥KWÐ_ÕÖÖæPœ)„‘T__Ç7>ŽþÁ(öhźuµ(r9‘H%‘&χãI´÷‡q£ÇRg.j,uë)2‘©™LZežyì þ8³fa¦qïà>Üé«G"4ˆ×œ«Ö:鸖ÁÈ0¢¤ØuiRÒ×֣ƒp*//S£/j2F4× _VÄuôPЗâ%t*¨2-3|e%yÇ©cd•IDÄc¤Ã8Ä2#Qšämi;ÏS”ZÜW5* õ¸?ò.–ÄŽ!àà”¡ –ñHèmêï#4<!<€¯?Àz”ã$”(`]FƒÝYè¦G)‰­ºéÓ§£««KJ²ŠÈr­ÞìNQïlBBÑ0R:‹–TI#A£•ËFVJIà Ä`'ï züþŸãÒ&}øiv=ÆO¡£OFOÌŒ]®EP,¢‡2@*–€>‡Íb€‰úɤ5¨Áa¢Dj§ü|JTª ³áÕBhž¸/^T%on®­×}pæ›É0I$&LKd-gaò»4ÁûÃaU>ü`þ8¼}ú:^?~ÃaæÉÍxûà‘¯àÆ É„{rÂgñÀÀûi$ ›ƒÐ |Œc\Y¨ðØ1ìc÷‘›(ŸR_0¦Ú" -V:DŽêuùXa8 YÕî:F¸«?Š”d!}a?ÿ™ð°LÍCœ$$2™Šäw’¢Åû§;Ð6˜?Åý8ˆâÔu´°ð‡ü8›= åu÷aáøid ]‡`8wv Htô(:¨h½l˜½>oÕ·¡â"²¿XX³fÍè_YÔ §$jAâ¿`4¡ÍÂ,4_ IãS„QFíº¡£§æÑ™(•õ„ñ.ºk_(ew”`y±Ž*tš)¹Ó¯þýÌÐi~5yVÌ(ÅÕž0ö~ʉìòzú“÷÷ì²"Ø '%ÎúȨµ$‚ËqT…Ò¨í!fñÎl0B:(é8Ú»¢úƒZ1hfX ò¡3˜y2GXÆ}s=X· GZ¼p¹mxúÞ û-ÈáàÓ—n„¦ºõmQø*g#c0âÙýÍ8Ý€˜Ò‚ÙRtzH.Rnˆ`bÓ”ˆNJðŒd¤#“]*•ÝÊu¶åbhaä3Œ¶-c¾><±º†#c ÕeSwÃÔ8ë–ccݸì&ÖPß<ŒͪÀdâÙ«Mà Sna#9—ÉDZÊÉp•a˜=¡©Ÿã&!jÌe”s =¦™·£v’àïIBŽ1«d&%ƒQ›EÑ72Ù m%œÕá¡8¾XAà»…vܹº‡rr“'zPé)„rô¦ÒP—;gÛ$Îl&–Nq¢Æ‹u}KK3ˆ44tøñýx䌩•E'¤)§µ,^3¡7"øÀgj9z CO~—- ÃÄ,[­F¢3£ÎØB¥Šý2ùy³±r `¤aTªKs°|¾ ï G£™cKœª}±ÊÞÎ0EVŸµâðåA‹rXÀ:¦ŸÑ¤³ÜQŒ»+­h¸p!6¥kÝ>\"•.¸óNRc\V>õÆq¤Ó‹‰…X¢ *êhža 4ƒ¢Ö”IB§„á´KœŸMèêR#/–dš››Gw€‘?G'V©Ë#ápv›²7jáC4ØÝ0€Ë½AØÜBLzb“#>K ¬x|¾ íW¯¡¥½/ šM¸M«ÆsÝê@ÿ&¾Š8Ø!|YˆaŸßŠÂ%OËÔR‚Ý$ÂHKš[­UŸ;80¨. pNQò¨R‚Jôƒ'N ²²R‹S~¿z£«¦Ûá—I]¶t² gçAO¸¨©68ê°éž2„¼]8Ý܆oèÃCú-%87(#DXiÔÙ&4Àf6¢tÀ@¦# ud¡D\"ËÑ! g½’Àª©VÊo'ÕÅ2±xFÅÐ2ªmmm;;;YYYêÒ ×ëU‹«ÜiÅ‚r:M#tFÂ…‡†r€‡Ã!àЧÍxùÜ ‚…“`+*e0±6tØu)H?vœ!5Ë¢áÑh­á‹ƒ™xØØSÊò-ÈÖ„aãýÔØà †}~oÁ ™¿ûËHû[©7D'VIJ ©BâÛ­‡IÃt3òâÒ¡ÔiÁºÒ4Þ;ö9¶4ø! Sa1$–ô©%Ì.S¶RªÑ¦ÄNC­U?‹™XË÷ ;xZÑ!L)4d#b(Ä_Í7°ÏhÔ?±à%©Àÿøñã·ŽêÛ´LÑ´[À¨ººZÕÞÓÓ…Ù¨rY°dJdÉ >Tà^¤þ/g±ãŸà¥Æ(ò&̓‰ÎŠºÐoEW#ÿÁ5Ί`+ Eð>3¨fA§~ŽF)Q¢2!B†ãç_ÏdW¶Ø000€††±Þªˆsvâ=[·nüÒ™xÇŽM,à·çŠ&¡=ºYÐB ®©Ñ¡ÒÁ¥“ГuVV™±¯þ,ÞìÒÀ=sôY¹*õ Ã5„„F¸AŸŽrŽ8‡¿…Cë@VDÓÔª –ä#f-;´ ¥»Ü1¬šì`MÄTȈ€ŠY*YÔéŽS§N¥¿jY%A¬9R®ãl¬¯¯¯W8ƒJ‚¾ò¹p¢h*ÐÙìˆ vâbØŒÙsfqøYѨ]S8 S°Ïõ³)Ìö訑4ðù$Ž å¹«V5Á`ãJ±3Ç‚˜QÁS³³Tnêbà^{í5‘E̼xkô_žþùäW® ­ZµªçÂ… nÑ3éˆtìØ1±Š¬ªÁ"GŠLqt Çp™ÔjsyˆwÊꭞ̢1~Ä -bQ CýüxŽuSY²„–N c ,lJ‰dqŸ9âÃ\ÿ“©dQáúȂ۷mP÷ØÄ¼l®?ommmûÚ…­óçÏËì ,âÚÉ“'»ˆ;åã?–ªªªè³kÃXKœC¼7â&¤HV‡ÚU4ìÈ" ‚ì…žÒ›´hëb|@,‘Ô¢‡’Õá”Ù…5”à¼>ЉU%<<ÑbÿÙ²e‹À¾"VèD¦ñ¿a1¿ñ'¯Ì±hì¬þå'N´ˆ.(°(V‘ŬŸ—ƒšì$J˜›¡ Âj#¤Á Gz£ ºtHe"QðCÞAep®7ü ÌœÒË981‰AülR6•eƒò‡”éà /¼€ÆÆF¡{$±6Dø¼ÿòË/ÿÍ«¯¾*£µQ²ÐµÚÚZÛ¹sçæ”——ë åøñã’Ýž­fžmGYž RÈ×DRÌNÐZ-¤Ü¨ªo´]êC^±î|-¦L¡nL2Éx¤B‹ŸLw"/ËÌI-6Ò÷ó¿û sÅd2I4\lCš={öÚÍ›7G¿õþÀœ9sžfx–NØD7 ^‹/––.]*l5# ºd,‚áxÍQ’2|AkŒ?Œ+fæ((³è‘oÖ Ïf%K‰ÄÔ^Cˆâõ×_ÊTáÀ"ŒPþ„™_F¢ßy‡¦®®nܳ‡£L¨UÁ l,Òjb!`\Õ8uËÈj53­”ËrZI ’ÐJ:UqÊéâ< ãåA¡"HBÌáG°«pÌþûóæÍû3²Pä¶m1­^½zvSSÓ&Fh­넎‹¿4\bv0vìXˆBYq¹\ $žÎòB$¡p…H²@h±ê×ÑÑI…™«ð·ê†nþ} kï·$å¶l1ýç×’%KìLùz6¹§é@•hïbŠ<-–#Å™ØÐYº5 ÝÚfúJè10±¿¨‹·+W®°Gw²óÿžÔyú{Ýf=sæŒfýúõùÄþø÷Äi¡XQ#é-cU*%­ çDFAEdˆc¡DrP5¯ÿÿþ 9þ ûÏ7Ú/þNÝ+W®ÔPjèW¬X1“†âLÊ鱑կ¼P“¥\âü‚²<´²BëLùàöK»‡»yeT$…yçšó#¹K&ÀÕÞÑÁÒ"ÔDŽrþÎÖv¶ñf‚hþPˆòtJ±ÂðµRj™0f`0*ŠÒ)6C0#ÍIŹ@IEND®B`‚eric-6.0.8/eric/icons/default/changeNext.png0000644000175000017500000000251312342633754020010 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEÜ &Ù¼˜q!iTXtCommentCreated with The GIMPm°—bKGDùC»«IDAT8Ë••Kl”U†ŸóŸ3óÏ¥JmKéÐZ:i¡ƒ D"*QÀ(D!Ä…‘…š¸×È‚•.$&$&.4‚‰‚Á â°‚¬•‹-m¥—±Ðé0™Îüÿü—ã¢h´(Õ7ys’ï$ÏùN¾“÷ÀL=ÊSk_Y{Çyé¯eõ„ú´ãùŽn6ÑÀqS¥Ì®¶…móÖw® äA@0LìÞ¼;›û‰ÇYóÿÁ”¼ÉåI±uÍÖíáùá³l¢Ak­Ë2{ví©êLt~2óF3%oª´²£#Ñ·}›ÈÜñæx]*Ú]vÊf²=q…+–$–HS˜k¢­ÜÆa†ñÿ¸-Ñ/ØlmCÑÒܶ<+R[[‹åZØ®MÝ‚:±¨vQrp|p£Ûææ"ù[ƒìH´&â™b[Ø”EYÔÔ×`û6¶7m˱0£&ͱæºÔXj—ÕlýÀ%o Ž'âñ±Ü¶aO[Ü06¶¶±cx‘'ƒt%Ò“H_¢´š^QH$ÊSÓ{®D¹J,mmWJª×†·¬dÈßy3Aïõ>Jº„! a”¡R"…Dù …Bù á Û@ÙJ,¬ª§Ò¬ÜÖkö6ÿcÇ)+…å—ÀÄ ÿ!p€0rJ" ?ëãg}*"•Â0z.þšËæËÅtÖš:×3`Ú}tõ¢H ˜pò±sdvY mÊp¦óïT&m‡J „Á z¸ÒE˜BÏmªÒS•SºœûÄÈè¸{æô×2d†ypÍ:/“ÍË/.ãÅ®ç8±å[úù¡þYåzZ•à­®pâl‘%ñ†ÇÒ¬_Qb² 8tLðË¥aò¹<±†©kVµ•fï8 `°¦sTÜQ{…äRƒK}±œ [âÕgáÔ·£¢¿;;$½¿`—£Æ¬àï¾ÿ±˜Í¤UUUµžW½”ó—'0ƒâ·¡^÷d×Y ¹œªªš¯«k¦÷Âf£èí;ïÎþØaó¥ÀIEND®B`‚eric-6.0.8/eric/icons/default/method_static.png0000644000175000017500000000074012342633755020554 0ustar piotrpiotr‰PNG  IHDR(-SsRGB®Îé pHYs  šœtIMEÛ%Y ÃiTXtCommentCreated with GIMPd.ePLTE         *" //  +&-.($,-*(=9@@@mmmwww”””¬¬¬»»»ÛÛÛîîîÿÿÿîüÞ=tRNS**,,.BBÜÜÜÜÜÜÞÞììììîîîîòòôôöüobKGD*S¾Ôž„IDATÓÎÇà PLNìôÞ@¢üÿÆ`&CnÙÛÛ‘fVˆÿ#äU×M«JªMŒ·NÉÚÑû”oì}ŠÝaù^\˜Û-æë/f¶Öjœ{§bÝH½K1Ï;g < 6çy«“î‰È£±,…e.òõ8©i¯T9ÍšŽ“¯?f –Ÿ¯ŸIEND®B`‚eric-6.0.8/eric/icons/default/databaseConnection.png0000644000175000017500000000145612342633754021515 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<tPLTEÿÿÿÿÿÿªªª$$I$ŸŸŸÙÙÙ¢¢¢®®®±±±µµµUD!!!xU£££‹c }h$¨¨¨ccc”k ”qjR ²²²¥¥¥ÈÈÈÂÂÂbbbÞÞÞ­PpTnU!’m$Á±´´´Ã¦%Æ ¨›‚ÄÄÄ‘‘‘ÇÇǹ¹¹¼¼¼¾¾¾ÁÁÁ̳h›k ›p°œt½½½ÌÌÌ×××ÎÎÎÑÑÑÕÕÕË—8ٗ塀¹¹ÂÂÂÝÝÝø¬÷´/ø°"½½½ÂÂÂ÷÷÷ÁÁÁÒÒÒÓÓÓÔÔÔÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝßßßàààâââãããåååæææèèèéééìììíííîîîïïïðððñññòñìóóóôôôõõõööö÷÷÷ùùùúúúûûûüüüÿÔd®XtRNS  $&'),.136>?HIKMOPQQWY^opss‚‰– ««²·»¼½½½½ÌÒÒÛìîîïïïñññõùúûûüüþþþ‚srgÈIDATÓc`”@ÄD›¨³¯,º—ˆ“&º¨ {¸‹·¡%,êU^d d"‰z”W'çë2…˜³ÃE< Ê⊫s,ƒ,¢|nYé…%1…•ñÙŽl#Ì2J’Sò £s+R‘ì“ H+MHÊÉÊʶBvvXJIl|vvºŠ£ ü"‹câ“íQýbã›g‡"(¤o­Ç­ìi‹ªVT…Hòê Š²pðˆIÉ)(©©«*)ÊËHós²2v((v%DIEND®B`‚eric-6.0.8/eric/icons/default/characters.png0000644000175000017500000000204312342633754020041 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<ïPLTEÿÿÿ*/1.46.46*/1 $% $%''..66.46.46.46%*+.46.46%*+%++055*/1%*+ $$%)+%)+$%%*+ %*+%*+%*+  $%  $&&*+*01$%*/1*01*/1 */1 $% $%%*+*/1  $%%*+%*+*01*/1 $%*/1 $% $%%*+*/1*01k‰‘<œtRNS  !!"##%&'())*+,-./00033557<=>???FHIKNQRTUVZ]``dfgjmpqsy€„ˆŠŽ“–ž ¡¥¥¨­¯°°°°°°²³´µ··¾ÀÀÁÄÅÆÆÍÍÏÑÓÔ×Úêëëìîîïïððððóöùùùúûûüüüýýþþ4&_¾þIDATµÁÓBƒ€Ño-{YËÆ²µls¹åå-Û¶Õƒöo]¬‹.ëþ™­ ¿ˆZZ Â@.·«uòÛ{²0ØïD`ZThÄ9MÁjµP?Š^BãpG%P·ûTôí£Óòp1ÒÛ,w¯Ìýâ(ynuFÇÿ¥¸áÑNf›a~˽šKÇø× DšëR09ÕðmaC¡¸™¢íêÁΞ:žï‹JåÚKêà‚±·*b§o?î'ˆðEŽ4Z ,ý¬ø#bk'7Ÿ°¸ä ynvzbLˆ·«ÄLô h;—R¥IEND®B`‚eric-6.0.8/eric/icons/default/stepOut.png0000644000175000017500000000027712342633755017375 0ustar piotrpiotr‰PNG  IHDR©þã#'PLTEÆÆÆ@/`?€OŸ`¿s߃÷ÿ$“ÿ.—ÿ7›ÿ2ƒñtRNSv“Í8EIDAT×c`` 3Ê`// „2ࢠpµ@úôÊöTgE ˆXm#‚É^žê( V LŠ@Ü™¼ Ö>¥IEND®B`‚eric-6.0.8/eric/icons/default/mailSend.png0000644000175000017500000000234512342633755017464 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs „ „ªâcytIMEÙ  w¡mö…PLTEŽ“šŒœ<<<’“___“©…ŽÃÅÃÌËÌ¥§ÞÞÞš£­4¾4¡à¡£á£ÎÈÎÿÿÿƒ™œ¡¢§©«­¯±³½À©­²Æ Ž ª —¬µÈÊ‘¿›Ê›Ë ‚"œ#—$ $&‚&¶&(„(¢)º*,š,À.¥.2¡2£5µ57Ä9£>º>Tµ5Y³8`Ø_bÇbfÙajÂanÁcqÝ\tàuwß\yyzˆÕˆ‰Š‹ãŽãŽ›››œœœœÕœÖ   £Ú£§§§­­­¯¯¯±±±²²²³´´····¸¹¸¸¸½½½½¾¾¾¾¾¾¿¿ÀµÀÀÀÀÁÁÁÄÄÄÇÇÇÊÊÊËËËÍÎÏÎÎÎÐÐÐÒÍÒÔÔÔÖÖÖÙÓÙÚÚÚÛÛÛÜÜÜÝÝÝÞßááóåããããîãåãåååååçêåèêæèëççíèêìèêíéÞééééééîëàëëìîëíïííííïðíððîíîîîîîïðïïïïðòïñõïòõðïïððððñòñññññòñòôòñòòòòòóôòô÷óòóóóóóôõôôôôöøõõõööööøú÷÷÷÷øúùùùùúüúúúûúüüõüüýþýýýýþþþþþþÿÿÿöÿÿùÿÿûÿÿþÿÿÿÿ‡ §u/tRNS &(,-=@TUWY^aacdhs’±ÀÃÊÕÛÜáäæçîîúýþþþþþþþ—ÙËbKGDÖçµj©žIDATÓeÑ;k“Q€ñçœó?oÞ\Ì­Òë/d(ÒÁÅ‚¤.ZAqë$NÎÙüý™Ä¡“ƒ‚‹’N­â **š’Ë›Kcbš7Éq«CŸñ·>Š“¬›ÌEbj6”3'šZH¦nuî~ßìô•ž9ó´\°™•Ç üØùoÞ)ŽCÍÊçM=‚ ü+Qï·¡?h6<ì‰ ³ûn p%؈ Ñ,£"1À $~î“0ºøýIzúœ’ízmK!Çådæûõ¦ÞXTq·kw¬ cKA]A{ÜË}RÉW™J«‡‰ùñòh” ïGï=×þzÕ¼Ði/œÖª‡]—[º‘pBLU¾;L-ˆžF®MöÆqkL-XŽ”L8MÜuÕcE°Ü—³s+²›nµðÀ¢ÑÆH´»=ÜXÌ?nw£bŒF¸Vû?Wóõ!o×^.»™ ϯ 7Ó=Hè^zsXñ=A°ýËóm,€¡½Ú|)Ь­ÿÁûÿn~ým•Üát×U$éNsÿë}—r6úþ¨IEND®B`‚eric-6.0.8/eric/icons/default/repeat.png0000644000175000017500000000070412342633755017205 0ustar piotrpiotr‰PNG  IHDRl"ÀPLTEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIIIAAA """'''111555666;;;===>>>@@@DDDHHH[[[]]]aaacccdddfffiiikkkmmmoooxxx|||‚‚‚”””A—êtRNS ÝßæóöúûûîûÁžIDATÁ‰"ÀY‘PмE,jIî£-GèÿÿÊ €z@ýWõ€Ëõêøîý±€³õâ¦L>› •ås’òbÈr’\Mǯi ÕF·¹½¿>ýÚEŠ[^'!ÚÍ÷ôÛy$ägÖ"„¤y*¬Òí€MçoìÍ«:@ox´ßÿݘ õÓUIEND®B`‚eric-6.0.8/eric/icons/default/chatBanUser.png0000644000175000017500000000235512342633754020127 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYs¯¯^‘tIMEÙ&犗§bKGDÿÿÿ ½§“mIDAT8Ë¥•kL›UÇ߃ lÝÅHtÑ ‰èÀ ™Ã„MpPeÂ`ÐQ.[ ”RŠ\F  ¡£Pî£0è…K¹·PºBéÊ€ ¨fâ2 (J²ðÑ/.$ÆéßS?áTà$OÞœ79¿ç9Ïå(ê?VZtôVDD^JT”—˜8ž›’"à_¾ìFíe ÙlÏÔè赌øxÈJJ0¤VÃ8<Œ¦ªªÕR>ÿØ® B!-?-ÍFÀäçcP¥ÂòÒ6Ö×qÇh„L,ž»ÆåÒv ¾U[ûƒk¶´Ã ¬V|·¼Œ…™Ô——CZXøÞŽÁ£jõ%Qf&¸/¢ª°Êæfèûú018ˆ…7Š‹ÑTQÁÜ1xB« &Q#ÉD!—‹’ã›55[vC,†L$B—\î¿c°V¡pž_—äå‡/ÒÓ!ÊΆˆÇC ±áÎÎ:ëêœvUÀy“)dÑlÞÔ46B’›‹2>ͰŽ=[°XNï©å¦ôú|³N«Á°eúÞ^4K¥•{‚GGƒÚäòß2“’P@ò\d/fb"²Ùì?ÅAÒ® z­–>¨V?åh-i­©±1|9?ÃÐò8r8ÏÌEEg6FFN=þoð䨨¡²ë×1ÞߥÙY¬=y‚ÕUÜ%ÿ—üDZðçöv¬H¥¿/E2tzšç¿B‡»»÷uuýZ‘[õõ0ÞµÍÍaõÁ|•ÉÅ·%bÌÄ~͹0èN˜¬gBÛ¸ÌÅ0r{éÔ Áfƒ_N†¢ŒDÖ!—o Æ=‹Öì,؈M±.¡¿µ¼ädˆsrª‡<Þ(¾s +‹…‰À€µVŠrýGðøààbÉ­Ü*•b « F¥·ç ƒ‰Ü@ÝÒ‚,R ø›÷íÐH|}6ÇáPºaoƒöttÑ(Ï“ÉÄge¡®¬ ʦ&¨³y˜8Þˆ“–êj¨„9ø&*¶à ôð\ª¦QŸvûD‡×qÕö¢éõŒºÊJ$1¦¦n)‘I4±Ðþ¶'n’o›L†–˜(<üÄ|¼¡}×ÃVDQ‹)ÊSê∪—tÛÀsÓÓ×j%Ä…†n ]'* PÅJB«#j>FMhæ\ð½ Êw< áñDö³Å®ŽÌg”Ó÷5l›tºl«É„T¢±Î!ðü+W`WºÊWÜжßFÕCG¹ò1hHšÚxɤ`õô}_7çz©>{ª?{«?|¬@|­AtžA}®A~¯B¯C€±D‚³E‚³FwŸF„µY’½\Œ±e–»f—½išÀx£Æ{Ÿ½|¦Ç°Ê”³Ë•µÏ™´Éœ¹Ðž¹Ï±ÃÓ±ÄÔ¸ÌÛ»ËÙ¿ÏÜÃÒÞÄÄÄÉ¿˜ÉÖàÊÊËË×àÎÎÎÔ·OÖµ=ÖÖÖßàááââáâããäääåååææææææççæêíçèèèèèèééèéêééééêêêêêêëëêëìëëëëììììííííííîíîîíïðîîîîïïïïïïððððððññññññòòòòòòóóóñçóóðóóóóôôôå¬ôïÖôðÜôòçôôôôôõôõõõíÈõïÛõðÖõôïõõõöÔ\öç¢öõñööö÷Ýs÷Þ€÷áƒ÷ä‡÷å’÷æ•÷æ™÷÷÷øÎ:øÐ@øÐCøÑAøÑCøÒDøÓGøÓHøÔJøÔKøÔRøÕNøÕQøÖOøÖQø×RøØUøØVøØføÙWøÙXøÙYøÙ`øÚZøÚ[øÛ\øÛ]øÛ^øÜ_øÜ`øÜaøÝcøÝ|øÞføßgøßhøßmøàjøámøánøáoøøøùùùúúú•ÿ§øtRNS"1589;=Gäæ÷÷úúVi #4IDATÓmѱJAàæö6‰AH¢ HÐBAˆ ÁJð•¢¾ƒ¯àØû¶B°A4`N%1w3»·ÙmÄ­–ŸùÙàßCÙ?&ÈG“Œ˜ˆˆÎΠ×b©LÄÜ`dLLó™#»™GŠLEs*²8`pȈ3q…S}³¹5­˜ff³“±¹•`Àh&þž8'"ê)7ʃÈTx¯ªêêm{î)qð*ª®ÞêXÑ6Ò ºÞ;„…])«~JgA¥{Ôn!ìÍ~”RšÚïºÖÖª_"n5q¾k¤3ô"¥ç7Â’ÑØ·P­ž[Ÿ¾æk+ °e%=Wœ•_>>'žeÕÀ•jü@954V\Ê"U²zŽ—0Ò‘ÃñxåMåþÛ¥Öñò Š\‡e~‘îIEND®B`‚eric-6.0.8/eric/icons/default/multiProjectViewer.png0000644000175000017500000000126712342633755021575 0ustar piotrpiotr‰PNG  IHDRójœ nPLTE```cccNNNPPPttteeefffŸŸŸ›››yyyŸŸŸ¢¢¢£££¤¤¤¦¦¦¨¨¨©©©ªªª«««¥¥¥………ÇÇÇÈÈÈ»»»½½½@†ßAƒ×BˆàD‰ßE‰àFŠà\‹Ã^œì_•Öd¦ÿh©ÿjªÿlšÒl«ÿvžÐx™Ä|ˆ—€¶ì€¶ÿ§Ð‚¨×ƒ—ƒ¦Ò†’¡†•¦‡¯Úˆ¬Ðˆ­Þˆ®à‰™¢Œ—ŸŒºìÆÿš¦¹ÓÄÿ‘Êÿ’ž®’´Ð“©Ã”´à•²È•¸Ð—¹Ð—Çì˜Éÿ™«Ä™·ßš¸à›Í쟭¶Ÿ¸ÖŸ¹È »ß¡Ò줻ץÚÿ¦Åé§±¹§»Ç©±·©¼Õ©½ÉªÁÞªÄÚ«Òÿ¬»Ç­ßÿ®ÀÕ®âÿ¯Ýÿ°²³°ÉÞ±Â×±ÃÕ³æÿµÆÕ¶ÌÞ¶çÿ·ÈÕ·×ÿ¸ÉÕ¸Ñ麺º»»»»âÿ½ÚÿÂÉÌÅäÿËÍÏËëÿÌÎÏÌÐÒÍÐÒÛÛÛ!–-ntRNS()Uac‡‡šœœœœœœœœœÓØÛÜýýjòø ÝIDATÓc```bãvFdÀ,^ ,(Â’y /ʼn"Ì£¨¥]Rfàéă"Ì+­fâbaé`$†b>ŸŒ’Žm†ùüA©áùæ (›'aš/ §Ši¾ ¬ŠG,¦ùBòªÖa˜æ +hØGbš/¢®iê 3ß?:Û‹,ÌÊÅÅ% 5ß'ÐÝJŸî˜ùY9éñ)üpa˜ùå6Q~pa˜ùɹ…a˜ù¥ÅÙÞ‚(! 2?.31ÆYEd~BZ°¹0Š0È|W7G=Caù`ÀÊÀ‡~Cw°—IEND®B`‚eric-6.0.8/eric/icons/default/drawEllipse.png0000644000175000017500000000142212342633754020175 0ustar piotrpiotr‰PNG  IHDRójœ sRGB®Îé pHYs¼ÏtIMEÙ +VPÒJPLTE””—™™™››¡››£©©²ªªªªªÆ³³³½½Â¾¾ÅÌÌ̱±³ÉÉγ³´ÊÊ̯¯°ÁÁÆ¥¥©®®²®®±¤¤¨±±³²²³ÈÈÌ««®»»À¼¼À§§«³³¹¨¨ª´´¹¤¤©¤¤ªžž¢žž£°°³±±²ÈÈÌÈÈά¬¯ÀÀÅÁÁů¯²ÈÈÌ›› ——žœœ¡ššžÐÐÒÒÒÔ×רßßàßßááá⬬¯¯¯±¯¯²°°³±±´³³·´´¸¸¸¼¼¼¾¿¿ÃÀÀÃÂÂÇÃÃÇÄÄÈÈÈÌÑÑÓÒÒÕÕÕÖ××ÚÚÚÛßßàààáââáâââãããääååååæææçççèèèéééêêêëëëìììíííîîîîîïïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùùùúúúúûûûüüüýýýþþþÿÿÿîiÁ87tRNS//00??DDGH‹‹‹¤¤¦¦ÄÄÅÅÉÉÉÉâââññøùûüþþþþþþF<ÎbKGDm»­þIDATÓ­=OÂPFÏûÞ{ÛÄ b0&bLLüÿ¿ÁÙÉD LÈW[[Úû:°™¸q¦'gzràr$†è—éÍ0™²:íª¦_žõ H柳†`iìN«u9(p¤Õí3YêŸö†Å]³ÉZO={š·]ÔÎ95³¹ZXàüøñE!8Á +’¤¬µÍkSç]À0±Ø¨yçÉ_EZ‹£u‘YÄ#Š3ÌèA9¾ NUÑÅ•­4¨*NE\ØG%§ €`bºüZEGòÝü|ÎÀD}/>–Y+ ñz2eùí®9nÖ[ç½êª?Jrõ¡Ú÷ªÿÃ^„_ß±dý~ò©ÝIEND®B`‚eric-6.0.8/eric/icons/default/coverageScript.png0000644000175000017500000000233712342633754020710 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ# ¯´JZtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“CIDAT8Ë•”Oˆ•UÆç|ÿwÆo2³uT¨Ô¡Æ@ l!BP©‰P+W-’  mZÛ Aˆˆ(t‘ZfhT‹(Ìü3f〈“:ã½ÎxǹßýÎyO‹;×äøÂ³y?žçœWÑb^x÷HWÖçk±2XMRêFpÖ¢±#MgÎûkžyïµ­ãüÇèVKw°·+?¸y &5PK…éT¸—Ë '.WoV“ƒüÏø­–‰Uùî¶€å=E|-ˆÜ+ËHÙæïlMoÎÜàØÐ ¦j%'‚‹ˆmÀ­å¾ÁYj¸TâÈk‹CÙê]M ˆPˆtüÃñ/wgô$^ІòŠûžxzä.xÏC]S.sðÄh’¯¦ Ö2i,b-ÖZDbNìŒãF…0Œãöò®…¥ €bº= Ü_¹íÞùs®K­FÄ`ïÍÓ6ÕŒÁâD0iJ½v›Üü)”¬¶+ÆN½ºqþ£{¿ÐwÈn2v6;'§54·4'Òˆ+T´å©Ï(ɆQqÿð¹#ëüé$­-¤™¡‹³³jîBÖÄ ÿ*Ø$E¹[¯ÄS“§»üjÒl|¶ug-yOè.*|íƒóÛtê±¢ÇgÓò3´g+ iC.% JÞ¿ÞÈXÍiZ¬E‰að„í«Ët—&ÐÊ àJ9´ªÑ‘«ê:JRpfn}°wàlâ,âq¢¢Ç¶5ú®ày3;1àR’Ä2r3á¿úùnøa¦mžÈŸfãâs¬í#õz~>ò®9‘¸™oœƒeq¹uœm@%%5†£b ­¥Xêå©Uy–,Èqq¼Æùñ•?yµòëh^þ)Ò½íþa»Û|1…ªáÒ™9­×97–gÿÙµø…>ü0¢³-ä¹ÇcâRDF”æ=ÔÑY*¼YÊgûüþž¶7F+w–¿aú}åÏ×È5¤^BêÙ¦Sç JÌYÞóO²¨»#Дk–𙢣0ÆÏÃUF« ”¦­}$˜N^TÍŸòÕᣛ¼ |²X,[¿¿—®n€ "gêo-ýxç+Ù\g—ïi4ŽÁÅYD`h,¥*N)Œ(®LسªÕ­p#;Nàìj\ó)œMyð£×O;È‘vìÙ²—»ØòáE¾¿dpÊ£f!5Úò[k@’†ll‚’„RÎQ'`ÒúŒ§Ÿüv €š(&Mc_W!Î'Z‚GË ¦¬m¸œ[Þæ¾Ó¨ ?ÂùÐ3ÇQ{8?„ ‚ üèó–àJÒûüß•þ}Õ4¾V­¨Õ=¦Ó ›±bÞ-Cùš KslX’#ò/phï<ï³–÷xÕúãÀŽá“ûÖ{É鮬º„¸Xô¶ë%Cµh»GúØñõÞ+x¾G!Ô’N»A )îwÞ¾€·R9Ù–ÑnkƧ$ŽJ"ú‹šp§.²«+ù.´*rû¡·IEND®B`‚eric-6.0.8/eric/icons/default/projectForms.png0000644000175000017500000000255012342633755020403 0ustar piotrpiotr‰PNG  IHDRÄ´l;/IDATÁmlÔõÀñïïÿpw½£í])w­+ôR-¥‚í–’±4˜McX%¾WsÑÄh·7ÄdnÌž\HF²ìdFÇ|ax³‰ÒQÝ”µZfLj W‹GË•w宽ÞÓÿé÷ÿe!Ä&Ë>¡”b˶Hûžç#nܨŸ¯.«‰™Iï#ûRofbbÂçÿ$”RlÛÙptÏþæïí¸·Ûó¨Ô]Y*x—K}T+©ñ…i99ý—è³³³.ÿ#ѱµáÎè\xt8úæÝèšBááH‡JÝ¢lÙ”ª¶,œÅʪwÆ*«‰Åùáìá™OÎ×Y‡¡Ô&!DPÓt”lDú „)|6FñF…ˆK]&ÝÍU§¶yµVßWê·Ôƒ×óß%ñÃ£ÏæŽñ% Ö4S°ƒ›Ø®ÄÔ &¿k"&Z¶t+”/¸œ‚óãù+:­wX²"´Â]ý%>}?È¥O]ô°Mâž2ùŒó…sáÓ]Éáîjå·ÞÕŒ±QS]]¦1¸…Âòs–ÓçìÅÜœ7ï{\B,ìÙóHsç]?³¦^gyÖáܻsÑïþ४PÜB(¥ØÚ›4žª~çó3öÒÙÑêf_® !4M»¦ëz1 V~õËÞÞÛöLêüØôÌÈÈÉßM”ߨIá !ìP(´šL&«###ngg'(¥PJ‘Ëåèéé D"‘Öp8œˆÅbM]]]Á½{÷jÇŽííí¡½½¿ßÔ;ü x8!„ø¹¦iCÁ`0ÙÑÑ:xð PJa°&“J¥œS§N¢Ñ¨àVcccÎÉ“'_°m;®ëz\)"@UÓ´œ¦iV0ôûúú7üÙN¢û“ÛÅ<IEND®B`‚eric-6.0.8/eric/icons/default/profileProject.png0000644000175000017500000000222612342633755020715 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ) ùç[tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“úIDAT8ËÓKlTeÀñÿ½ß}Ìë¶-C[J´P D¢Æº2te4¡1!¦‰ ´‰‰°0Qh‚&ºpÑèʸ)& HÀÄ Ä46°h:¤€P¢(Åv:N;sßßuÑ,X=ÉY{÷äÜsÅ3@7 °öø¸»Za 1ûûû¿=tèоÿ€244ôÃàà`/ଠïÚµ«ÿÌ™3Ÿ™¦ÙPWTžÞ¼çys½½½Ç²Ùì—«Õ·ßt'ZKº®[—###7í£°£©©içÀÀÿ'úúúv;€‰ÇaLÓd´ñ ;š<Ú,hŒÁèÅoúz°9Ðÿ.Ýo$ À ÀS LÓ\õƒÚÒ,ï=üu]4§¡ydZ/òþG'PUXõÆÖMl}® ÏÛƒ±ì(Š’z2¬ª*1%nÏ@GÏ™4¤S7@•@¾ž?/xôî;ˆk /¦"@ ðÕ`Þ§ ‘FnðäÍY†]·Êô¯—’J@* V„öèá0„¹*Ì×Àq@hŠ’y:|åø–5m”)%Qa²{÷îæ£GjBû}ßwd$o-Ãïœ,Ò‘öhŽƒeÂí‘ïøê‹OëÐÃï£ûµ}$T·:KxÄcGŽ9ÜÐÐhÊÀ߯kâÇ?ïMºËð¿/–K·ê~ÞølN‡W÷ˆAÌM…ùB޹?Æ¡ÇKÏ¿€!%šeª255¥\·ZÚÚì–ÖÖÑPÊÛêJXWa²w à„)€º°!3“wQÀ¶mÈ(©Tˆ<šmcÝ{ö×¶3VƒõºÐDê°Põán&ç¡äƒÁÜLŽD"‰Ð4 MC˜&×Ο§R«‘Édhhl¤­­Mñ\ïåÓ§N¿] êbŠ…n= ”fgQT3#µ~=¶®sïúu2–…nš!°R–R­V“¹¹ö:XS@]k+vØŽ4¦s9""")É´´°÷ø‡è†AÄÂNË%\×ëÙÛóy,TPWâ+®5ÙÞÉÄo¿“Ëå±Cצjš„aH±X”¥Ry¾T.—gË¥ºË»ãöâÕ¥`%G®[–œ>û=oõ¾‰nÄ- Û¶©ÕjÑÄ Y­VO]¾üÓÉöööPz …Â…»¸(Š(‹\½r•éÜ4-7²!“Á¶mf>,„RžÍf³ŸäóùçΓ Ð¼²†kVEÑu]7;žíغ!³a[:Nû¾_1 ãB¥RùelllÖ¶m/‚àoÄ ØMœ^úIEND®B`‚eric-6.0.8/eric/icons/default/fileSavePixmap.png0000644000175000017500000000174612342633754020650 0ustar piotrpiotr‰PNG  IHDRÄ´l;sRGB®Îé pHYsvv}Õ‚ÌtIMEÜ (4¨N„ÆbKGDÿÿÿ ½§“fIDAT8˵”¿oU€¿÷voÏcs!Fvb'²À©p$Z$òГ‚L0¿HFÔ@…(hèBK‰ø!$$¬s0ŠÁ¹ ·w·{ûÞ›¡¸õå.'h S¬vWzß~3;3FU¹Dk ÀX `Œc@«{À¿Íðü /!AX[[;øøÓOÎÄý¼vss“Ýë×iœ(˜ÿë*É\ ˆUPP©t¨uÝœ“~Äå§/BàÚW×NŒE„í¶Ydž|”è÷‰ö-Ä ˆSø³ Y1Ô;Ö¬ ˆ œò4›MBˆèR¨*Þ{DkÁ ©Ã…¨/Àî ø¦ ¥¢ ˜áŒ€Ñ¡œˆ UZ#ãóëçQUCö ´rÃ\T°¸qÒ´9¬­_ÀQß Ô"EƒÂÐ8Ȥ±ˆ`Œ¡Ýµl>ƒØùò€……/X¼ßâ{ ~>‚?zŠQH"eÆ*©-yî’­Ê ˆê¤qc Ý>ûI‰˜M÷•ÜêYŠAŒ1 AÆFx¯Øàx¦;UþÁ FƒÅ.>.Ì7Jv÷àë”,Oˆ"Ké!Ô¡ºBrÆk¬"HÕˆê³ØšbC5ÚÝN,&®THgÓ© ? öc`U%ïõðÞs¼¯aÎ9¼÷xï Î*Šâ#Š"BÕC°ÜX)T>LYÒï÷§ Þ{Î6šóž¥åenìµ[)òÜÆq À`0À¹’¼(HBB–eSPï=y‘3ÃgçÈ:Ick¢oµZÛóss6Žc²,ãêÖË”®DDèt:SPçýn"/pe‰K'ÁͽÝÏ­®ÒºÝÞF±;;;$Irgþ«]{wKþvxHYÈó|¬Å½Ñ€Ü‹ømàd¥¶ÑâIEND®B`‚eric-6.0.8/eric/icons/default/projectSourcesPyMixed.png0000644000175000017500000000175512342633755022246 0ustar piotrpiotr‰PNG  IHDRÄ´l;´IDAT8Ë••_ˆTUÇ?çÞ;3;3»ãÊNí5)ØBÇJew“ÐÂ(B‰Þ{/_z±^íÁ¡Âô%_C°°?¤Qø²C­„P±þÙZmQwÆ™{ïùýNwfw\vü^~‡ïçþø~Ï=Ç8çè·¾øúüSWoµ¶ÍߎiD N(ŽJXä…MþþÒóõÓš~àGΕógTtª%ÄVq"x¥œÇHÁ¿ˆØW¾ûÆâZz¯ßUÝôX¹8µ2$±ÐN”V¢,EʵZÄ̵ÆÔ­F4ÝOôÛˆÄG‡2T6”4XlÌ7—nòã7i¶-F-N§‚ª¤pœ§ý¹K4L€¢'ˆZjâêU•ÁœžÿéôÞ]üÌÆ/ŸØ±{nüñɳ妘žù'*6: *‚ˆ jP18•ÎÄ©ƒÙl×m\÷'`hŹ×a÷ä2øú’ûèòÙ™ˆ‡ªEVû)ÝêÚ 8Ul’·—(<ÒMÈ{²eqö—Ë[?ùÖû껋»î‘ßkeÅ;§éÑêõ†æTS»²†¡ q§¢|6W:1wùÜ®àïKåV¤¡ÈJ ] NVªÛÈú0F ó h‚q ×ÃæÝÙr0'¦ÑI|%u'BÑWFK†À Àù¨t'õÙ²!`oåÃù:h’–KÈРÜ ðQŒ²<Š`Ô2õXÄ›ã5F×ÝÁ3cç0Æá™6ë ²^ŒÑœ]Kr`ãú·ÚêuŠ:åñ’ω:“O^Ç÷;çÏ)¨—€t`®;©íô”$Ã{fãðb1ç/¸ÂeSXK¡Î¥@‰S/%í”D÷õœÄä¸ñe&?zÆ{åÅƆƒ³n9ùR1K.kÒ)íI½§du/Á9ø×xö­$0Æ0ýý¯ñ¶Ÿ<üÞ$€Wyסqµ‘Ũ­.ûéº{¸QǕۛ›2\9`zãññqpô؉Ý;ÃOà’ñTlQµ8¸¶ vÁßöÃgkÞǽÀÕkæÔöûr’àT°fOêxînÕÛz~â¡îãôRg4"²C´GÓ*¼†Õl_©P­VMµZ]¶effÆœ>¶çg‘tÊÞ2¦†ýï´f¹Ùª4^kÕ£±}Wë›7’p¡ÒŽ}ZÉ-;DÐúe¡Þ8Þàé}}ß¼µš½ïàÜo'vùÑl9o® .KS6`3•ÅMϽ}áA.þi&ÁÓŒ,W^IEND®B`‚eric-6.0.8/eric/icons/default/bookmark32.png0000644000175000017500000000301312342633754017672 0ustar piotrpiotr‰PNG  IHDR szzôsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ˆIDATXÃÅ—[lgÇçûfvvíuì8qnuBjÇ!‚$E´ J%„Jz{ •¨Ä‚„P% "Rmsyª¢*ˆ{@}áòBTT¢@!€RCA’&n“Ø)Ž]œÄëÄÎ^f¾ïð°ãì®»‹ë@ËHÍ™ËùÎÎí;#ªÊÿó0ÿºH·~·ªXøqözîú3ªp9»¿ëáÒñ7ÍOÛ|%Ô‘lß}¹è­÷ç*¡ŽL~þÙù¿! Õ:ùI»Éˆ9Ù=ðA1]hS˜Um¬ÝþÄØ‘±§ì6aoHc'¬¾|ý°¯ì#ý°¹+nÏw®ï¿—ŽÛ߆â€Ë ׯÏpùåçë…ëtT¼ü|í ÷§TKƒƒ(ÔŒ¦DÆžñÊ£Î2PÉQçºÚ»¶íÜ@Ô³(Z3Üê»4}(9â+“禹Qx…kS§°¥Jl½ž7p¸ÿ3î P•+G$˜:jN™u½ýÝ›÷ëÚHصQZ®ú¤KK½á%².Ê!Þdp…iгÓÌþë%*O_rkü6–µºzÕÌŽ÷~ œ©e†©©Ë–VDšN¡õ×$»ž—Ž|ƒxzb³Ùý¸^ñ…ùù¹ G«ÙìÔCSÔËê€%×­îÕë{ª”fÏSºôJiÏA4 ÄþýçNü•òÜYð êð hõ¬šÊ¤çzÐâ~ ÕÆµœ/þö‡„ÎT À®/øßeKþ«gþvWžDRñ ¢U@*K‚bù¦Nº–†gÿø#2¥Ê×w ùgËPDŽ4ϱ&ÏÎý°A7bëò!EӤ䵱×4ÞU´sæO¿ 29þüÃþRÃ}@ļpÐŒ†»Þ±sßû0¶Rb^›œÿ‰”R*áæÆ85zŒäjü½Ã~7ª¾y'TõûB¿§8Y¸:=q¬!Æ* ,´†YÄaa.ý wá0ÿœxâL<»W7Ÿˆ՛ϙ;ÆŽN\X½qäÚo¯ñ“ZÄ(ñóàn€+"•9ÜüiˆËUî1Ü…ñ½f#½“Ç7iŵ=à™‹[ß¹ªwCO74ð› A‚RDôZC#R_­DÐ¸Š™Y˹ã:óž/ùõ41Ör&ôžJ\¾Åê@¢ÔŽM½Ô%%Õ¤Ÿ—”—‚Sp·â¡Ôy5`A‚ê™0•3u÷Ò,’ôë߬£8§vÅâ2]™(ÍtCµ$I„udÓØWsV¤f\DmP)“_Ñ<0 R)ÓEuå––¢˜Ô+!H¦‰R9LIÚô=L”‹d†‡šïŸÍ’!(—2Ñ’Ú¦Fæ¦7R„µÔ Q‰k=ø´ A¹¬„•4–‹¸4n9ùÏÉã°°ÛwÃî» ýowÈ’ÝÏ H¦åôК@â«u›œ3— c£ÊÙç£N¯ïà‹qžra‚/?ûw·ãÄV1û4lêõ˜DѬ›“%Ãr† óq.gmI…W§áÜo”…)WÊurhæ'<6ª‹ý\ä—C ™OêçG~ê>krÒ±}¯eãfˆò]pÊ“Àà²3áÍ>$Ï~ºý÷>Ý=sæ*ùÎÙˆO}àÛüšå~§EägŸ`—ï_/°km_§„Þ8ð•ùwi]iµžˆÈPÚOAYá|½~½·–ÿ¯IûÄtëûIEND®B`‚eric-6.0.8/eric/icons/default/projectInterfaces.png0000644000175000017500000000115512342633755021400 0ustar piotrpiotr‰PNG  IHDRójœ PLTEÿÿÿ!!!999………†††‹‹‹Œ’’’îîîðððÒÒÒ %%%555666<<<>>>GGGVVVaaafffwwwxxx{{{ÏÏÏÒÒÓÓÓÓÖÖÖÛÛÛÝÝÝäääæææçèèéêêêêêêëëëììììììííííííîîîîîîïïïïïïððððððññññññòòòòòòóóóóóóôôôôôôõõõõõõöööööö÷÷÷÷÷÷øøøøøøøùøùùùùùùúúúúúúûûûûûüüüýýýþþþÿÿÿæ6ÓtRNS#&MS\l¦¦±±ºøùþ>ôz#IDATÁAjAÐ÷}›Œ\ŠÁx7.¼‚7öºr%fa4`&`HìéÎôTù^(L ЗBûtÈäçVpÿ'²efD†pNAFËl™B’-k[«ªþVU% ùûÝÅõþûÕÝó_½¯SRÈýëý‰.‘0ì–®o$€Ñ/G·Í=PÐ0zÿ‘›%§ Œm=¼X”³@AºËþeL/k\ó!)ðz×Þ¸ñ€Çñ*ÚEŠðößü´¿£ 23§‡Û¹ÝnëH"¬óá}—“Ù@ZâÛÍáHÀè§ý6‘»g•Ñήó"˜€±m ü#bFœ|*IEND®B`‚eric-6.0.8/eric/icons/default/projectSave.png0000644000175000017500000000213412342633755020211 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ (4ªq)tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“ÀIDAT8Ë••Ýk\EÆ3gö#ÝMö#ýH›¤¨IÚÒ(¦mšØ–*+i1/…jñB‹zÑ ¼ôJü ê‚b‘"¢AP­µ7¹ð¢ˆ‚ .íMc#IÓlwó±gvΜ3^œÝ€hš87gà}ßç}Îó>3#FFF¶çr¹Ó‰D¢MVÓ+++×nܸ±ø <µÿþT©T:S*•Þéêêêm„ÿY°°°0755¥–——?/—Ë GFFÆÆÆ^Ú#¥ÜA«Qwww—çy/ÍÍÍý\.—ÝØZ;,¥|bbbÂckË;pàÀ¨1æ°1°s.³ÈîÔõj†¾NØ•…»åïyãÂ+Mªðî10|šÀB=¯½#åœËùfŠd¤€bï<6НaæÏ¿ˆÜʆ3XŽõ“$$„̯Bω³ì,@vx€ à~¬€Cnª—BàˆÐËó,ÍU‘«`j°”•hY –W áC}MÓŸÏlñèÃm¼ÿ¼BIð$xH ­R„!D8Rtf[c|s!äËŸ|vHvlƒ{嫼vþÅõ¤/]fßÑqŒ…5qø!¹)cqîܹ ãçß~ïÃÛ{|7»`æ—I’ ”³Žü0ùÝ=Ý1±ÆB<éHxqãÀw CXŽÀhPžÂ9ÐÆr÷~½9T÷é¤ÂÖÚ–c­ZŽP^üuÍ¢°ÉØZK]Ø(Z’sÍü†Á–0 [>v˜µ µÅ€´aÀ¯Rq± càÀ¬iC>“^Žpà‘ƒ5Ø&0À£=iÞ<Ò¦’ bG¨X–«¯ÂÙ?¦yëõW7õp†ˆÁÁÁÁcÇŽ=½Yrù·ß/v‹är9Ú;Úÿ_ZªP«VQJQ«Õ[¼*9zdØòyž93NµZ¥P(ròÉ“Í?rL~;ÉÕ+WÈf2ÔëuÔVM£ö}´¯¹þÝ5zöîåÐáC4 ͘RahqÎý`c*¾ïµöÉò$SIÑZcŒ¡Z«ÒЗLa­e«¯í™ì¼n4ž*‹mÇŸ`ç®T**• Õj•[7oqgæ¾ï£µ¶kÁ°ƒ9 ‰¥IEND®B`‚eric-6.0.8/eric/icons/default/taskWarning.png0000644000175000017500000000231012342633755020210 0ustar piotrpiotr‰PNG  IHDRójœ pHYsììu85tIMEØ4 Ó‰²PLTEÿÿÿu¦å‹­Ô|ªåÏÔÙÐÔÚèÖ×êØÙu¦å|ªåäÍÎÉÂÎÜÓÖÓÞéäâå·ÆÝØÞä½½½ãÎеÂÒ¶½Æ¶½ÇÖ’“ÙÀÄÛÂÆè°¯ê°°ÙÈÎÚËÐݪ«Þ«¬ÐºÁѼ«­ºÄªªÄ««â››ãఱᱲÔ}Ô~ا«Û°³··Žç”“蕔݉‰ÎffÏffÒ…„Ò׊ŒÙyxÖllↄㆅÑxxooopppuuuvvv†††‡‡‡ˆˆˆŒŒŒŽŽŽ•••———˜˜˜›››¡¡¡½½½¾¾¾ÀÁ Ãà ÄÄ Ä ÅÅÆ ÆÇÇ É11ÊÊ23Ê32Í*)Î65ÎEEÏÏbbÐbbÑÑJJÑccÒ;:ÒZYÓddÔBAÔEDÕÕ;9Ö;9ÖOMÖON×eeרÙ:7ÙVUÙeeÙjiÙŽŽÛXVÛqpÛÙÙÜÜNLÜ_^Ü……ÝC@ÝOMÝffÝmlݧ§ÞC@ÞffÞonÞÞÞßßB?ßonßÁÁßÝÝà{yà”’à  áIEá}{áááââgg⌌âÄÄã<7ãYVã–•ã––ã¡¡ã°°ã´³ãããäähhäµ´ä¾½åääåå忢¢æÝÝæææççÒÒçÛÛçææçççèiiè·¶èççèèèééii飣鿿éééêééêêêëë‹ë¬¬ëêêëëëì¢¢ì££ì¤¤ì¶¶ìÆÆìààìììíjjíœ›í««íííîîîïkk便着ïïïð©©ðððñ©©ñ××ñññòllòîîòòòóllóóóôôôõmmõõõööö÷mm÷÷÷øïïø÷÷øøøùùùúúúûûûÙþ2;tRNS !",1?BBHLLbbgg}}‚‚†ŸŸªª®®½½ÁÁÆÆÎÎÝççêêíòóóóû@½ EbKGDˆHUIDATӕνJÃPðû•›ä&±Ioc R,A¥‚‚¢¸8¸‹n‚“«›oánâæ ˆT´ikš6ýHÄjlÄÿp8çÇápø#…Ë+çg i“á÷€7ßJ™Dѱ ào6ݺ¡ÕÝœ8Ê21v$FÉ.ïËÀƒšLÅc7Åæêu˜ ·1~³Ã°ég+œŒ±„YŠæÀ}{È|¼VÖLˆòꌯë)#¶f–°‰`–Zls,ey¢»A0'„+Ò|×b_¬¹EÝFX˜ÅÎ-Nif+ „ ÍÅëÊçßjÞØòP Ç3âf;©>í¬¬lc(À׳óg$º -3€ ':„‚*ŠœRe¼VÁ …Rï¶£"‚Ði"Õ‚FT»Ó=¸äö€"+ºeê ªV^ê­ O‰/zX1¸ÏPÜ ¸õT{î|ð¯|\YXÝ6¿IEND®B`‚eric-6.0.8/eric/icons/default/nonwordboundary.png0000644000175000017500000000023212342633755021153 0ustar piotrpiotr‰PNG  IHDR&¾ƒ PLTEžÿÿÿ;f·tRNS@æØfŸŒ’Žm†ùüA©áùæ (›'aš/ §Ši¾ ¬ŠG,¦ùBòªÖa˜æ +hØGbš/¢®iê 3ß?:Û‹,ÌÊÅÅ% 5ß'ÐÝJŸî˜ùY9éñ)üpa˜ùå6Q~pa˜ùɹ…a˜ù¥ÅÙÞ‚(! 2?.31ÆYEd~BZ°¹0Š0È|W7G=Caù`ÀÊÀ‡~Cw°—IEND®B`‚eric-6.0.8/eric/icons/default/fileRuby.png0000644000175000017500000000245112342633754017506 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<âPLTEÿÿÿ555LLLCCCIIIxxx{{{LLLnnnJJJ’’’““•”””•••–––———˜˜˜ÑÑÑØÙÙßßßÙÚÚÚÚÚÚÛÛÛÛÛÜÜÜÜÝÝÝÝÝÝßßßßßÞÞÞÝÝÝßßßàààâââãããÙÙÙÍÍÍÊÊÊÊÊÊÌĮ̀3.ª/*ª1'¬3*­/+­1*­3+®,*®-*®0+®4*¯1)¯3*¯;0°9)±.(±1)²+*²:*³;-´.'´1(µ/*µ7&¶('¶,*¶7&·,)¹.&¹2,¹4,º8/º@1º@:ºWN»-(»26»74»:<»bg¼&-¼2,½-5½55½HA½]W¾H8¿<9¿GIÀ2&ÀRLÀsuÁ51Á>%Â72ÂQ=Ã1,Ã<$ÃbcÄF.Ä`gÅ:$ÅIIÇc^È8#É'&ÉjgÉÊÊÊ6#Ê=8ÊbaÍS@Ín_ÍÍÍÎ8$Î81Î9$Î}ÏF:ÏG6Ï~ˆÏ‰ŒÏŸ£ÐG?Ћ‹ÐÎÎÑOBÒ?'ÒueÒ¡£ÓqjÔA7Ö@5×VC׋ק¬Ø–žØ¤¥Øµ¸Ù””Ùž¡ÙÖÖÙÙÙÙÚÚÚkXÚƒ~Ú‹ÚÛÛÛuiÛÑÓÜcLÜÕÖÜÝÝÝoZÝ~rÝÞÞÞÐÓß²¹ßÝÝßààà‹}àààá~nâ²·âÐÔâÛÜâãããÀÆãááäååäåæåž–åËÍåææææææççæçèçääçèèèææèèèèééèéê鸯éêêêæçêêêêëëëëëëìììåæììììíííÏÓííííîîîȽîçèîììîîîîïïïçèïèéïéêïïïïðððììðïïððððñññìíñíîñïïñððñññòìíòïïòòòòóóóæèóóóóôôôóóôôôôõõõïðõõõõöööööö÷÷÷ôô÷÷÷øøøùööùùùúøøúúúûúúûûûüüüýüüýýýþþþ¶ÚB*tRNS0:IM\\]fk~€€€€€€ÜÞÞßßßßßßßßßâããããã÷úýþþ†S‚©ƒIDATÁÍjQ€á÷;ç;“L“I[›bƒ1º)TDÑ ¸ÐnñÜ^ƒ× Þ… ®³ŠK! 1mZƒÖQ“Tò339ÇçB@!JŒˆˆ ‚óó ¥×¡j)‰T¬w(Bt2jN­Ö:Fœ ¢Vjk,Îæ£qéQC`À¸ÍÝË{Ûa5íœöž}²PÀåãYºªTo¿‹Þ°q{2XõÿÝx[¿ (•ðïáz÷x¦ k¸ô×çAQ”öfA+u#€â­ÊÚaûæÇØI¼a  €uߟnVGVZ_óõ+€2ý6|Òí½÷Û>ÖK`{a1=ÜO7¾¦²“g ˜¨ÙÛ÷KmîÖ®ôþx²€lüxyVÄÉúït~ë燇sPÚÏ]¹5Ë%ïŽó—G0bêyú$Ÿ¾x0\P`£ŸuúYùKvÿdé% ¶®š;Åľ:*<€ÀZÃâýùdüs`‰ýÀY4IEND®B`‚eric-6.0.8/eric/icons/default/callReturn.png0000644000175000017500000000035512342633754020041 0ustar piotrpiotr‰PNG  IHDR¤à“dsRGB7ÇMS pHYs  šœPLTE;Ã;Ã;Ã;Ã;Ã;Ã;Ã;Ã;Ã;Ã/8ôY tRNS €¿Ïï‹©5SIDAT×c```+a€¶i`:--cf!˜5¦;ÀX3PÅ@ê Ðô"›î PK&ŒÅ>³-- ,T 2 Äb cAÅ”Äaêô‚ͶH!>@‹{IEND®B`‚eric-6.0.8/eric/icons/default/dirOpen.png0000644000175000017500000000123212342633754017321 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<&PLTEÿÿÿdx©Sev«ày¤×q˜Ç s¥äq¡Þh æh æ[—ãZ–ãj›ÙNŒÜL‹Ûc—Øa—×Y–å¬éAƒÕW”ã@‚Ôƒ°èZ–åZ–ã[–ã[—ã[’Õ\—ã]˜ã^”×7zÎc™Úfœà6zÍiŸäl¢è_˜ár¥äWÔs¦ä-rÇ-sÈ/tÉXÔa™àbšàeáfá,rÇ/tÉXÔZ‘Õ`—ÛdšÞgžâk çk£ïm¥ñuªóx­õ}°ó~°ó€®ä®ã‚´õ†µðŠ³ä‹¹óµæŽ¶æŽ¹ì’ºî’¼î“»î”¼è—¿ì˜¼è˜¿êš¾éšÂî›Âî¡Èù¢Éú£Åì¦Æì§Çì¨Èí­Ëî„bºJ:tRNS %)8DJMNy{¢¤ÄÇ×ßáíîïïððññòóööùùùùúúúûûûüüýýþþþþþþþþëm°d IDATӭϽÂ0 à³st‚¥;báàýgF¤²QÑô' #tÄã§ÓÙþ0Ôàúxý0ÍÞ`{Ÿ>Ö4 `¨ë¯è¥ Za‘ÕËbz,YŽë…³=åvŠêyÇ.¶)1µì¬¼zr\Ù9MÏ`ŒäÝ&0V¶Xé"S妌égÍ«uæài3Ný ârEš¼ ¼$Íñ ‹e6'º*IEND®B`‚eric-6.0.8/eric/icons/default/breakpointNext.png0000644000175000017500000000247012342633754020723 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØÿuxtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“œIDATÁIl”e€á÷[fïqÚéPÊØéHªDñ‚1†Qj\P,‘r$ˆ&ÜL\âÁxиÔ‹Œ^¼CLôàr1,V±jÜ(](Ž£]fþvþïß>Á`BÆ>ÿr'»¶=³mŽíäú^ýɆƸ"ÿƒ¤ÇžÁžÁåwl¼ã%vð.·¡9/WFîZÕ¹ê;¶³…+´“Ð [ ]?$vnÙ9œZ‘å>Šö¸˜ÀÐÕÝ%zó½C“õÉ»ƒÁà0?ÑäŠvvW*åÙ¥Y # žðÄÕ…«1‘Á„\ß%‘IPZUêªÖª{Ü’û5?3ÉEŠvv—+år­QÃHƒ‘# F c nèb"ƒñ VX±º°:Õ\rqÖ4—ø‘#œ§i'¾ò™õgQB… )´Õ¨H¡Ñ(:Ô¨P¡…´X7pÖJ¿8óð™›8=*¸hbÿ~é~ûméíìå‹W]ëúX-ø3c8Öçpn…EJ…Ž4:Ôh_#==ÐjA«==Ï#´¦;žax¦[~Z1@Á²Är«t¼Ùh4ïáèy.ÒÖÚÕIHÈZ ‚r9èï‡nàÛÙI4:JðÎ;D““äé…. ,4šãî¼³•טæ: CĹs`-LOÃÌ C¥‚¢'ð^~;5QÄ6PUöÏùúÇödp/ïâÑF‡Aõ:v~”‚D¡5ÖZþ–NC*BðøRÒ2+ž·ÏOó¤"X\„F ¾>ƒ±1d¹Lâ‰'ˆ¯]KL4ÐU_ò\ð4—¡=)Ï4…ðcñxL®[‡èí…'àõ×¹@<þ8¢TB¬_O41Á¬gÂŽVò®@=ØÛ{Ö¢O&Rž§ÄÜ|ñ¢^Gxœ> µÑØ¿9Ž?„Ÿ}cí¡cÕê$—¡vlÞ<ï4?‡B¬ŒIYIÏÍ)áûJA*¾OX­R]XðGçÓcAðÊ©ŽŽ£¿LMy\†Üùþû¡S(üx:^o4>¬…¡×Êdp³YZÙ,K™ gÂÐ?¾°ðùQÏ{õT:}äÖ;®@pÑ¡]»”žž¾6!å.+e9ap°v2O&“ÇoàçÀ–+ø uÇ xÿz)IEND®B`‚eric-6.0.8/eric/icons/default/exportShortcuts.png0000644000175000017500000000234512342633754021167 0ustar piotrpiotr‰PNG  IHDRójœ ÊPLTE" !KKKOOOGGGdddfff‹‹‹ŽŽŽ™™™ššš¤¤¤•••ššš………¡¡¡®®®   ¡¡¡«««¢¢¢¤¤¤¦¦¦¨¨¨‘‘‘ªªª²²²“““«««²²²•••˜˜˜˜˜˜šššžžžŸŸŸ§§§¨¨¨¦¦¦³³³´´´±±±²²²# !(&'ÁÁÁÇÇÇ" ÏÏÏÑÑÑÒÒÒÓÓÓÔÔÔÖÖÖ×××ÖÖÖ×××ÙÙÙÜÜÜàààáááãããØØØÙÙÙÜÜÜÞÞÞâââ $ !/,-2/0512534633645845856967:78<9:=;<>:;><=@>>A>?B@@BAACABECDFCDFDEGFGHEFKHIKIJKJJLIJPNOQPQUSTVSTZXY[YY[YZ[ZZa_`feeifglmpmnpqrurqsrrtttuvttvvxvvyvwy{{}|}}{|}|}~|}€€€‚‚‚…„„……‡‡‡‡‰‰‰ŽŽŽ’’’œœœ£££¥¥¥¦¦¦§§§¨¨¨ªªª±±±´´´···¸¸¸¹¹¹¾¾¾¿¿¿ÄÓáÄÓâÅÅÅÅÔâÆÔâÇÕãÇÖãÈËÏÈÖäÉÉÉÉ×äÊÊÊËÍÑÌÌÌÌÎÑÌÏÑÍÏÒÎÐÓÏÑÓÏÛæÑÝèÓÓÓÓÞèÓÞéÔßéÕàêÖÖÖ×××ØØØÚÚÚÚãìÛÛÛÛäíÜåîÝÝÝÝæîÞÞÞÞæîßßßßçïàààâââããããêñåìôææææìôçíôèîôèïóééééïõêêêëëëëðöìììíííîîîîóöïïïððððô÷ññññôøòòòóóóôôôõõõööö÷÷÷øøøùùùúúúüüüýýýÿÿÿ£|EßQtRNS "&./347C^vy¢£º½ÍÎÒÔÖÝÝÝÞÞÞßààáâââãããäåææçèèèéééêêííùúûûüüüüüüýýýýýýýþþþþþ H.PyIDATÓMÎ;kQ†ñç.;ÎÌF·P‚ ñR{í­, Vi-l¬ü¶B¾‚•­¢‚–k„€ÑBL!q³ÎÌî93çb¡à¾å¯xxe4Ñ@ #€ÁNc·ŸÃ½T·Ÿjûï‚‘âwžÊ±^ÙZ”²ß®XA¡ßÏBÐúm!èöÓ›!X0ä¾òF›`½2j_®{£ÀП¾á‡FÎú æúÒíÝRlŠ)\9׺ꇰ±)§Ž[QõµÇ€Û}@íî•À£™ÉÑN=vµ1íPe}~(*£@}=SÌþ+N‰6/ëʈ”·îÞÜ«®Z”‰³åCԃפ+“í%JD?7Ž¿¿›Ë‡) ).üHnžMîvØ‘ö;¤”ëï@ö†x1´}†”B\œƒœc—"ÿ9¶Ïù·uNydüR¯sï·\ytøa<¬GÜp°9‰ÑÛ˜P-‡‰õ+ï|¿ù˜·.æ&æ.¦Ÿü Óµa‹<ŽIEND®B`‚eric-6.0.8/eric/icons/default/preferences-helpdocumentation.png0000644000175000017500000000210112342633755023737 0ustar piotrpiotr‰PNG  IHDRójœ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<CPLTEÿÿÿ(FNd‰²v«àf‰±€±î~°ìu©êu©ëk¡èj¡è_šåAAA`šå===U’àU’àj›ÙooolllKŠÛJŠÚc˜ØX”ãX•ãa—×AƒÕ|«æAƒÕY–労éZ–åZ–ä[–ã[–ã:}Ð\—ã]˜ä9|Ð[’Õ]˜ã^”×_™ä_˜â`šãc™Ú°ê‚±ê3wÌZ’Ö\“Öa˜Ûašâb›â3wËWÔXÔXÕX‘ÔX‘ÕY‘Õ-sÈ.tÈXÔc›áeœáfâhŸâ_¶ `´ b¸ h¿u‚Ú!„Ú#‹â$wÀ$Ð&‡Û(ã*ŠÚ,rÇ,xÁ.tÈ.ˆÕ0x¾F™ßO—ÓRŸâU–ÎU–ÑXÔdšÐfŸìgŸìi ëmßm©ànªÝo§òp§ñršÐw¬ôw¬õx­õy›Éy¦ày¬Ø{§Ó}°ô²ö€©Õ‚£Ä‚¬Õƒ£Å„¶õ†¤É†¥Êˆ¹÷Š³ä‹¬Î‹»öŒ¹é°ÑŽ­ÔŽ²Ô®Õ¼ê¾ù‘©Ã‘ºá‘¿÷’°Î’¿÷“«Å“¸Ú”¹Ü—®Ì˜¾î˜Ãõ˜Äõ˜Äù›·Ô›¿îœ¯Æ¯Ãž»×ž¿àžÈ÷Ÿ¿ßŸÂàŸÅîŸÈ÷¡Éú¢µÍ¢Äì¢Èð¤Å쥷̦Æì§Æì¨Èí«Êí­ËɹÂ͹ÄÒºÆÕ½ÈÓ¾ÊÚ¿Ê×ÀÉÔÀÌØÀÌÚÆÑÜÈÔàÉÖáËØåÐÝéÒßëÜæñâèðP”a¹OtRNS %*.8;JY\]^_fnu€…Ž˜¡¶¹¼¿ÎÒ×ÚÝáãéíííîîðððòóõö÷÷÷øùùùùúúúúûüüüüüüýýýýýýýþþþþþþþšYã$IDATµÁ¿JÃPàß¹9÷4iSp R°èd© tÑÑA©>‹£"¾€¡tü3I‹Eq¨Z¬1éÍÍ™¤ÅÙïÃ?" ~tŸ æ1PÛ÷P¿N<RÈU„çP´Zø•Ÿ Àƪ‚"> "j¡àƒK Ô h­)­iB°©mƘN’i:ã„$ËÉœ9×Þ“Iê¥JøÙçÌÞëÛk¯½Ö:Àÿôþ£Dr‘B‚ ÄNgÂívûdYÎ///CÿÿINR€ÔAJº$IJ8Ž„Ëåê$HÜãñ($¿ÏçiÁ!Š"ÆÇÇûWVVÆe2 ’ÑK¶m§,ËJÐdœÞÛ ÒJ‰y½^4iä%h-LÓä*—Ë0 ƒ?ÓÊΘe€aÚb0¤À#›[îÃJ0 [!ˆ cQºÝ¸mn ;,Ø®” ó¾–ba/|FSs6ƒñ«Ö Ön Ç&xk§Ëб'ÆÚòü¼¢&±^°Ã;‡„yç¾ÇŸ·àƒ_žÅD¡›/ý3ü¯Þ6BávÛ¡==¢›ý…{Â={ïªe¿B@øšN•ѺŽÌ ÇO^DÅ—FÕµmŽß Zg‚ܸ¡æÈ ìY¤Ü/–ºqpBuÇ:\ž?°EU-%Ý«A—Ûqâôf¯ë°bOÁX/`»zsh7Fæ-ßÄæ™±¦ß‚‡bêòRÖ¨­Ât*üBBr·ý‰<^{.Æ‹ç½÷aNzŸü8­n7nHÜð¶q튠rKÃ<üä£u­"EŒ t"l* PVؤÁ»5ìÞD=°ŸÊøú‡L/(¸«û-Øôž{MĵJÇY®¶õÌ¡ôIôú#µï Q®º¨ ‹'Û ¯GÇÀ®>;} c?]EæZ3ù=Ø™Ì#»%ÎtÐRU9/mÔ}hxßÓžà¶Ž¨ö/ÙÁ$Ââ¹,ò÷p‹†Ç.ÁãoÃ䌀‹“Lfºm+WÅü¶TÅ©BQúøÜ¤ú©¼¶*¥üB8þà½Ýçuó°8› ¸N½ÇªÛù:¬+Ï?Vœ^­´Îž<“<2õóì®WÞ y Ã5¶´´ôs8ƒ&…Ü¥ñT§0¸V“÷pÎý!ªÊÿ1Ün¿4„†ifDšñq2«ß¿ÿ¯q;e,ï]Åp¦5£»µžt[ˆ°˜ñYXñYÉ—n̰?¯ß”vËøå½.vµÔ}wp/½/6BfmDhNÆîþYàÛ—y˜Ý¼†‰ŸÔéáµÁrúrŠ {ãí#/ôõ6#FH88=’ÆŠðõõ æ~û›«w²ó„ö^zÊ2è[×›± ƒ½­ý»šÈz™BÀbfƒ†ºhi¬cOƒcâÍn¬ød¼€¬pp_’Á—›û‰Ù‹ÕWÀô”&ÓÉc}ûšÈ2^H¦²ê‡ä7ƒŠÌ+†¬z™BHÆS2^H_g#é¶ú£2ùÃèv°qï÷´'Éù!9_ÉyJÎñÕòÅÕEî,åùõqϾ{À¦ÄÈmh¤ó!·¡ô´5€¸355–oìO%ܽ׺“€€Ñ72(¨PsUþ²¦üÿó’ÏZ1ÖÏÏEûغ¡±ü•pÖV ªÊ@§£=åÊ ÂO6Xö,ˆ–Ñ(©†4P—ÈáîJ‰Æ¸’Œ;ŒU壑N†4U“3÷˜ý¥TÉ2DX/*ù¢¢jÀšæ­“glT„õ¢0bùêwN ¤˜>u j^ ,û‚ª*DÀ(DªÀ¶.•,ª—Š ¡Ô9ª‡ŧ ‘¨ÿf«ÎˆøUw…YÀ˜šFÔØÆT)랯5³•í¦_žÃº›XÆEÕ¶TƒMäžÎÚ[úIÇýÚ},îlEðl`U÷³å¯† ÆÍl; zî¥+Xw»6ËÄ!;²§Â{µ‰‰¾ \³µ¨p°åüö“c cç±¶œeôPŠ×»x¸ZâÑj‰îzŽ¿’$V)óÄõ¤NQÚùÚ<÷$…§sÌ舗hoÚ…Ö„°â+O Ê~×C€Û¨ŽéTÛÒ®½|ŒÃd&QŒY!fÁ(…P(*¡r ÏêTû•ÿô‚TŸ®îGƒ  ”,¢YB³ S-s»>M"b8P$ʳ¾j6”}Ø|À{fú@¡lÿ—cmL‘ÐÒ–IEND®B`‚eric-6.0.8/eric/icons/default/projectUserProps.png0000644000175000017500000000240112342633755021252 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ%.n=¯tEXtCommentCreated with The GIMPïd%nÄPLTE˜˜˜|||„„„qqq‘‘‘444aaa,,,000EEE[[[fffffflllŒŒŒ~~~ÃÃÃÆÆÆ˜˜˜ØØØÚÚÚ···gÁ"nË"nÌ1o½3o»4k­9‘ÿ;‘ü>€ÒA”ÿCzÁFy¼Fz½F{½J}½J˜ÿKÃMÁM‰ÒQ¶R…½S†½[bk\”Ý\™ç^½_ek_½e“Ìf«ÿh§ÿkš½lš»l›½m«ÿn™Ìn½o—Ìo«ûpœ×qqqq{†sšÌsž»t}†u›Ìv~†v†w€†xÌy}€y°ÿzžz¤Ö{·ÿ|žÌ|ŸÌ Ìºþ€¢Ì€·ÿ»þ‚¢Ì‚£Ì„¾ÿ…¤Ì…¬Ô…¿ÿŠ‹ŒŠ§Ì¤´²å¿íŽ¨ÌŽ­Ò•™£»Æú’£¯’Èÿ“¯Ò”¬Ì•Çÿ•Íÿ–Îÿ—®Ì˜Ïÿ™Ðÿœ°Ìž²ÌžÌÿŸª·Ÿ´¾Ÿ´ÌŸÆþŸÑÿ¡«³¢µÌ¢Êÿ¢Ëÿ£Öý¤Ëÿ¤Ùÿ¦»Ì¦Ûþ§°¼¨Íÿ¨Øÿ¨Ýÿ©±¼©Þÿ«¿Û«Üÿ«ßÿ­¸Å­Ïÿ­áÿ®Ïÿ¯¶¾¯·À°Ùÿ±²³±³µ²Òÿ²Öÿ²ãû³Óÿ³æÿ´´´µµµµÔÿ¶¶¶¶×ÿ·¹¼¸½Ã¸äÿ¹ÏܹÏÞ¹åÿº×ÿºÙÿ¼¾Á¼Öì¼Ùÿ½Úÿ¾ßÿÁàÿÁêÿÂÜÿÂßÿÃÃÃÃÃÄÃåÿÃèÿÄàÿÅÆÆÅëþÆÇÇÆÈÊÆâõÇÇÇÇáÿÇåþÇçÿÈÈÈÊÊÉÊëþÌÎÐÍÎÎÎÎÎÏÏÏÑÒÓÒÔÕÓÓÓÕÕÖÖÖÖÖÖ×ÙÙÙÚÚÛÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííøøøùùùÿÿÿðê<±%tRNS!&&7?MNOPPQU_`afjj}ˆ­²ÂÔÖÖçñòþåÁbKGDë¿Ý&¸iIDATÁ;kSqÐóËý÷6%Ú&¶i¥V°gQêäPp'´“8ø™ü ÅÁŠÁŠ‚EÄ:TíCû †ä&7¹žŸN $dí5ÜÞ)I˜o!ãÓ»õ¹wWwziýxºLBÚž9ßüðwVE‘ý½¹ùí‡Y˜Yînj²ýÏK §òªèt‹BžR±µÝZÜï@BŒþ•Ç‹76?¾)‹A? $Ä3ÕÎDy¹Q¾¿Hˆ»­s“«ó¯¯~ôÊÁ#$ÄQãBëd²¹ùóàþI÷y †°·;ÛþuØü}¯(»e !ªÖÒ¥­o«ëÙQYô5TS«+oׇ13U¯WµÎÍ+_^ž­u:Žë©Û$Ñøtëõúlžcô}Ô,©6Qoo¬MeÙòìpoHõ3ÙßÇUç`,cØï÷†ÔøÓ^zQUˆùQQ• 7UP üŠÉˆjñÂ!ãIEND®B`‚eric-6.0.8/eric/icons/default/preferences-help.png0000644000175000017500000000245112342633755021155 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<¯PLTEÿÿÿ'''***,,,sssvvvrrrwwwwww{{{iiicccººº²²²¸¸¸§§§ÑÑÑŸŸŸÄÄÄÍÍÍÜÜÜÌÌÌÐÐÐÄÄÄÀÀÀìììôôôÝÝÝéééôôôàààáááÜÜÜÝÝÝ]´a¹a¹ _¶ f½ g¾ jÁc·k¿oÂ\¦lÀpÄj½xÏ|Ó}Óc«€Øn¼yÈÔ‚Ù„Ü zÈ ‚Ø „Ü!n·!‚Ô"j²"wÂ"‚Ö"‰à#q¼#„Ù#‰à$h­${È%Ï%Œä%å'|Ä'…Ô(‰Ý*s¼+Ü,Ü-€Ë.â.‘æ/|Æ0È3}Å5É6tµ6ˆÉ7„Ê7ŠÉ8r®9r®;˜ç<‘Ú>—Ù>—Ú?ŽÖA…ÇA—ÕB‹ÅDŠËD–ßG—ÕGšâI…ÀI‘ÔIžåKËL‡ÂMŽÍQ’ÐR†¾T”ÑVÄXÃY™ÔYÙ^¥ã_›Ë`¨æ`ªég¼i’¾i Òj”Áo¥ØržËs¦×t£Ñu¥Òz£Ìz­Ýz³æz¶ê€£É‚­Õ‚¹ê‡µÞŒªË»ä½æ‘¿è“ÁꕲЗ´Ò™¶Õ›µÒ´ÌžµÍŸµÏ¢ºÑ£ºÒ£¾×¤¿×§ÂÚ¨ÃÛ±ÂÕ½ÌÝÁÐáÊÕãËÖäÐÙäÒÖÛÓØÜÕÙÞ×ÛàÝäíÞÞÞßæîààààåéááááåêåååéééêêêëëëïïïôôôõõõööö÷ùûùúüýýýÿÿÿJ–÷ËLtRNS "*+./01?@ABCHQST`abbfiu~€€€ƒƒŽ—™ž£ª¬®®²¿ÀÂÃÃÌÎÎÚÛííîîîïïóóž8æ”IDATÓc`À˜øE$ää$Eø™E9e5LìÜÝíL4d¹à‚ŒBJVïß½sëÎÝûVJÂŒPa!M—×VÍ1eöŠ ·u„ &(¹Ü;Ö»e×ÎÛ×7í¿é¦Â ¶MÖêÁñÎöœ<½{õÊŠ7meAöòk<¾Ñ²dñÂKW=Ù7kfÁ¹Ûzü@a“ûk;¦Mž8µgÝ“3 ñK¯›‹…%íîN¯­)ÏKŒ:õdSxdpÛe) °œûê’œä¸è ON‡øú„]õ” ß‚ï}2/,ì!6äÎtp̶ƒ áö«öÒ`+ï®)ÎIKʘ¿fD\²°sòðrs°1CŒ—?™ Ot‚aIEND®B`‚eric-6.0.8/eric/icons/default/viewProfileDebug.png0000644000175000017500000000225212342633755021167 0ustar piotrpiotr‰PNG  IHDRójœ pHYs  šœtIMEØ,*É;Õ¼tEXtCommentCreated with The GIMPïd%nLPLTE^^^dddQQQPPPBBB¨¨ªÕÕÖÇÇÇÀÀÁ¿¿ÁÄÄÅÉÉÊÒÒÒÎÎб±²°°±±±²²²³³³³°°°°°±°°±ææçããä°°±°°±°°±°±²±±³²²³µµ·¶¶¸··¹½½¿ÄÄÆ··¸ÐÐÑËËͳ³´µµ¶´´µ´´¶µµ¶µµ·¶¶¸¸¸¹µµ·ºº»··¹»»¼¹¹º´´´»»¼’’’•••’’’½½¿ÀÀ¼¼¼’’’ÎÎÎÔÔÔÙÙÙÜÜÜ€€‚‚ƒƒƒƒ‡ˆˆˆ‰Š‰‰‰ŒŒŒŽŽŽ‘‘‘•••œœœŸŸžŸŸŸ   ¡¡¡¤¤¤¥§©¥§ª¦¦¦¦¨©¦©¬§§¦§§§¨¨¨«««®®®¯¯¯°±²°±³±??±±³²²²´´´¸¸¸¹¹¹¹¹ºº’“»»»»»¼¼±±¼¼¼½»»ÂÂÂÅÄÄÅÅÅÆÆÆÈÈÈÊÊÊÊÊËËËËÌÌÌÎÎÎÏÏÑÐÐÐѱ±ÒÒÒÓÓÓÔÔÔ××ÙÙÙÛÚÚÚÚÚÜÛÛÛÜÜÜÜÜÞÝÝÝÞÞÞßßßßßààààààáààâáááááãâââââäãããããåäääåååææççççççèèèéééêéêêêêêêêëêëëëëëëëìëìììììììííííííîîîîóóóõõõõõöööööö÷÷÷÷úúúüüüýýýþþþÿÿÿñ^pVtRNS #*+012478:>@CDE]až§¨¨¨¨©ª¹¹¹¹»½ÀÀÁÂÅÇÊÌÎÎÎÎÎÎÏÏÐÑÑÓÕרØÛÜÝààäççèêììïúûûûûþ§7übKGDÊhŽBYIDATÓeMKBA†Ï™™«Iy“¬îݘ´ÈÒJ²´w‹vþ¶ý˜~@Ëv­JZE!‚ˆ^•J#èCèΜæ~ag1sÞ‡—÷ÌS%ÔüÞ1cÓÔ[Ø>Çï˜Íè<ˆpmùÅ56s ³>ýÅÃÜ—çÞÆS7 ·TÖ. §9IZ±Ð+a\ _ ìÑW•j±ám‚}yè&­.ñ¦!c‚ L”íp"‹°6;NB¥³¿á_¡Ôö Ê÷Ç!r=D+IDB+ô+ÁÓmDt\_¨”ò$ùçOF‡WYIEND®B`‚eric-6.0.8/eric/icons/default/debugScript.png0000644000175000017500000000260312342633754020177 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ&(Ü6-tEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“çIDAT8Ë¥”_lUÆ¿™Ùévv¶»[ºÛNû'@ ¥Ô¥áEIMŶE #ˆ‰&&>`ôÅÄD’FcHH /¼ÀÒB!&Å ( M[L¥Ò‚-Ým»-ÛÝíÎÎÜ;ž™µ@ÌJB¼Éɽ¹3÷7g¾ïœ+ Ïhÿö|Pq¡‹3Þ˜Ô dM‹1ˆ`ð¹E”x¤+`æ–ï?yk ÿ1Ä|›œ['ªƒjckƒÃ2Ç<ÅœÎq/®£ï^²q:©ŸÀ†+ߦε¬HFm¹.‘Ó‡þ wâL}j03³èù=†Þ¡R7aÐ" w‚à$ÍSƒdZ× Z«"#pœ‰û€öìu‹ÚON~Q(& ÉE$ß‘†u¯Þy>pôL0ežè×Õ$‘ìƒ “3Œq„ý©Å!>š²tŒLe0 Ü¥À+Ëšˆï_ì¿EóY÷VZ4<ÿ5g}só[o0‘2!Ø?’NfWã*š*4TJtJ@ÿà ~ŽºazÊ Ï'à ¥(ŠÈVL~üZhuÇ9§*ÒPšMöH;GKÆŒí=Ã4ÑuËÀPtª§ÛÛ[ÑT%¢€ÍÁ§ ô®Nà,…®¸}·ÿ8¿ÁÏë†Ælðc±ÖŸ„L…h×®œ¤é!øpdÁ`mo¾Ž¥r ^×='(ÁžËÎh©ø #ER_pü‘ëå|‹««1 ‰ä¯%AO§¡ºe;ðš%>”[-Ñ4ËHBuEs 9mÏvi%õ,Vz-¬.M๊12ÑDßMuïÂãQ‹M"TBelΓo,¶ƒQ,+2íY¶¸Ïú$ø¥±–àâ€Q’ñâËͨªªÂèèÒéyø Ô¶†“ŒhkLs”»:VÝÒÉ -è«y€æ0püÜUly£ekëè÷Á£:PÛA Ó WánôOT”L:F v#zTVʺ󪮳"¬‡íêS PµDÁæõ³8{æ4âñH’„ûQgí.p£¬´&—1œlǽ©"Ò9Ke*ྐྵ1[¹ê=Ãɸ¦¼èÓñ™ôòá˜Yã\!ªæ nêþuÏKŠV|½—¾Ão¿T’¶¾ŒâŠg~½¬½½}—´rE­50xCvpÓ<2b‰þXÚ³ü³…§ÏþØ,É/ù|¾ÞõÚ,ž­,Û» jý+·Ìù© ÆÒHzã;;w}(ÏḬ̀IUÕÃÃÛöíÛwùرcÒ¶mۘﮰî|ÐGZOpšLˆ•$ÁÝË\Z„¡i\мÂwìÜ#ÎÎβþþ~ÉëõÆGFF6íÝ»÷Š Ï{ÛåED†dýr  Ãà^¤C_£¶~+ÂÏôŒ>|8á÷û¥5kÖ°¹¹¹EË–-ëêìì|ÁÎ8/x<^š²áv–¹vÍ…,ÄÁ§O‚§QQYíîîÞL Y^WWg’4AMÓºi¯^ÊÞµóýS™lA©K5Ãä^N0¨ø³”±hF'dÇÇ}þåÁ!Ã0z)ZÃá°—ü1GGG‹@‹ð¤Ëúvÿ‘ ’~#¨jž¤X9L¹vª&¼ç¢ý|÷îÝÒ¡C‡XKKK¸©©©»­­-4==m^»vÍ…ÿ;l¸=·¶¶ÖwttLD"ëúõëÆßƒèÓL«©IEND®B`‚eric-6.0.8/eric/icons/default/newWindow.png0000644000175000017500000000133612342633755017710 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<VPLTEÿÿÿ”¾ˆ¡œ“œŽ‚œŸ–£–Žš”¤–«¥÷÷÷ˆ‰«­®°²³¸«°ŠŽ¦¨ž£¬­ • › Å ªœ´¸ÅÉŸ!¾!$³$&ž'¼'Ä')È)+É+,¢/¦0©011Í12Ž2¤7§:º:=’CºCCÃCD“D§G©L¯LÉSµAVÏVZÐV\¸A`×YjÂipÄirÜYsÂtƒÝƒ„݃ŠÞŠŽáŽšÖšš×ššÜšÈÈÉÏÏÑÕÕ×ÛÛÝààáààâääæèèéèøèèùèññòõõöúýúüþüüÿüÿÿÿb5£tRNS-15pwwËÑÖØÛÜÝâêìñóü[ØÕpÒIDATÓc`@L\â’ü<Ì (€MÔ'1>!Ñ[„ Èa„AÏèðˆO1&Vv(àÓ  *, Ñçf`—Î…g-w·ÂB/GmaŽÌœœt00”)„u ŽŒ¤¤T00–… kH1p¤¥@µ‚Ka¡¯ŸªGj2D))Úzš)ó2pÀtæ[ÉëY:™ÊÙq" fÛ«(jê¨)[dq æÅº™;Ä¢ ÃÁ`fÇ&ÌŽ ÀΊiH€2µ‰ú\*IEND®B`‚eric-6.0.8/eric/icons/default/rss48.png0000644000175000017500000000506612342633755016716 0ustar piotrpiotr‰PNG  IHDR00Wù‡sBIT|dˆ pHYs  šœ ØIDAThÞÕ™ÛoÕÇ?çÌìxo^_’ØÁع‘&$…ôp HD«Þx£ijÕ§¨ÏýÚòÚ¾Uj¢JU_úPŠ*UzQ ˆ–K B $$±ã8¶×ë½ÎÎÌùõáÌxg×kÇ–¸#íΙsÎü¾¿Ë÷÷;gàÿüRéuòîÌ ™Ñ1œì¶í´Œªµ»Ç}VWÑC¢¬–Öµ²Yœ#š˜ ¸ë8¡Yà·ßÄ9rèðDv|üp¡4vDBVÅÕ*#`6,˜î3K÷§ã¸b²¥PeÇjAcá• 2ÿÆß^üËÌѧ‰ÜDó3®™=]Œ yÕZDoÝ ‘bn>͘¢EiVaáüZü ¨}ëþ.@6ƒfþ¬KTs(”P¥m›Cø×  ¢´‡Ôç]síýLÎ €–ƒ–VE+P4!jo>Â7!d󨨭¤µ¬¬ Ik†…DHÙ7Ûï×4…0‘•9Ð ‰¹Þ>Ä„›€¢À`”“P,¦ˆ[61•Jz±Ì.@»‰FPH Ø´…T»iq¸éü.b D›×…,ˆÎå8Jº,°Yt¨ÝHÅ@ËK¼Kì u!uûõê#¹ÄBét;‘e!cnÌ*%„깿¹Ab@£P~”ïZ[ 6&¸êѸ\Ç ý–žvÝ’]ЀŽz\H'o@»‹|Ê2U6Ø—™œ æêy¨]€k'`þ ¨ƒ°s/Aãœî=i­PØû¾oû*–žûèÍ ºçwÅ zU²\íBJw&ä·@i ãö¹W‚¡ÝöÿmGáÊßáýãpõE´.ÃÌ 0“ƒö`ÛØv4/Býr·ðÑ®"küÆ.dúSÚxŠ]Ho ,pópë—áîŸÂ?€LÞÎ[| ®< õ:c§‡ÑCÖ÷” N"XŸ¦úµë¸JÌ”hhñ œ:ïýüyÈ Ai7ìø* °™³¸v=•ÁÂ?¬;•ÿ  ~ Ê…¡; ´^¶INõÔ;½VPkPë¹$4šLXzš—L¼¬u«ò[–u&â. â¶cÌÂòÛàOÃҫм¹ÝàÂà~(î†Ê;ý…×}ö½åºRëÒ(Ý<ë—-&¦÷›ö¾q‚9›v~ËºÓø#0÷<´§¡=kÁÔNCvʾ¦¸J{¡úÎjÎOƒ0ëX aÈ5Žêã< º‘g‡ad?Œ†‘ÛÁ´Ùrþ5˜~ªglà»E½ÛÒ§LêglÈOAnªãÿýdþ”‚¥¿$É` ÂïÀÖCPþ7œþ9”O‚©ÂÒ) bô°SØ £±FëÐ8Û©NÝdJýý>¿ôé×zUuáöV]‹–vÂÞÇa÷cvSQ˜°ÏÞþ!,Ÿ†öÔRl“ßÞhœÅÐ< Äœ¢µ’Z‡á®×ßëâi:]J¬|¤š‚ü¸­Õêù¼ jAPéŒ÷¶€[ˆ5Ò¶±”Ú=ðé6ü…Ut0Õ³VÀÈ€¿—~e† ËX‰ðf áûlò “CŒ` b”/€j„ ½Á(dÀ„QÆñF§P‹i[•l°:©@âê—l’G7p6š¶šIEä …„B8ª9‚zC‚ |³Õ _ÙêR[P¾„Ÿu[¯»…ʉ"2ÚÜ¥iç'ÒJ‰=ðRkP¶êÏãêF)rgÆ ‘š(Zl„†7[¾ÿLÕ7'Z—ð»ÞóÜWÙÎŽBŽ{s^æ~íxƒ*l¸bDmè”ñõ\)'†aTõÛÑ+uŸåY.~íO=^x—1²‘C!“Å ÛhA%'Ÿõå9ˆ ×Ã-ÚND9Z¿Ä&ý€ñ ®ÿfú¨nu aKIEND®B`‚eric-6.0.8/eric/icons/default/flashBlock-java.png0000644000175000017500000002730212342633754020716 0ustar piotrpiotr‰PNG  IHDR€€Ã>aËsRGB®Îé pHYs  šœtIMEܨ !IbKGDÿÿÿ ½§“.BIDATxÚí½{”\W}çûùí}Ωª~·ZêÖÃ’-Y6–bK6¶Â#b ¹wÍš8Læ2!$äf%—๬b’I Ž“»²BÈ w&ÌÀe˜É8NîZw&<‚!1Æø!¿dɲõt¿ÔïzœsöþÝ?NuwUwUuU«%£íuV·Kçt½ßßû·®Œ+ãʸ2®Œ+ãʸ2®Œ+ãʸ2®Œ+ãʸ2®Œˆ!¯øÞu¨@ê‡HãDm?†.ÜŠû,à)"n†T¦¢Q3É'.]À÷ËøÅWPˆ®ÇË!D^ºØH?ª]@+`Lãç½§eDЍÎ'@Ž¡ú,F¦å/Ÿ½€—Ãxÿ¾nJöÖ¾¯oD8 c­ €zð‹7+h'«R]ˆÉžuNQÆ€Ãyç¾FÁáOŸ^¸€K5~é@HÁ¿µ?…÷?ÈõÖà<¨^ä°U ’:‡êQŒùâþ†’y$¹€‹1þ[vbÓ·cÌÏ¢¼k,Þƒ×Æ3ªýX«ÀÐ6"R½Lv­5LU¥8ïÅû/à‚ûø·º€¿|ðF"ýŽ5#™XׯÓX$²K«†]A=ƒìèêgK¡Þ¨Àæž~òA´ r31?Ã\\b¼4Ë™â ÌOA×ü= b3€Ô"L«¯`ªÀq~ô¿Ë¿ã3‡¿wëïÙÿC˜àƒ¹kz—Å»¬6Ü|•@¹n6mÚÆk¶]ÇÍÛ¯cÿÖÝ\;´MÝýôæ ôäº2·å4f¾Rd®Râü Ç'ÏòÔK'xüìsKœþ1ŸyêÌ45îì»Áÿ.ÖîÂUÅyíº4û¬{;®½;oz#?ºç W l!0©OqÞá/’!hD°Æ.}×ééq¾õüaþú{ðÕcßÍT†1jí1YœÁù“`þ’ûìËÅX|yà½7Dì½XûVÐŒÃYAx”MûùÅ›ßÂOø1ön¾ŠÀZ—âVÞ‰†5†Ð¤Îqlâ4÷?ñ÷üåcÇÔ艪·Ôkc²ÏûŸ¨û þ½Ã?ØøW¿o8߯"ÁG0²‰tExÎ;PÏŽ7p×k~ŠŸü¡×³¥{€¤Êéú2^Xc mÀØÜ4ÿã©à“ý-gÎ<“q¿±+cÁëy|ú{l~û§ùƒß÷?xøå}Ã䢃1ïX2æ–)iBÏð5üÆëÞÎÛ¾™ÁB•4¹hâ}#ÕD.™*Ísßá¯qïƒ÷Q{lXo#,Þ‘Jü/ùÌÓc?8xÏWÊ_bí%®_|“4|ï>ôOøå×ýS¶õn¢âR¼ú…bijçæÎóé¸Ï÷¿gÞƒ ëo ,8wÇ»ùóýòðÞ›~šÀü[ŒÙŒ«ázUp ?´çVî~ÓÏqhç¾L¿«çûwhÕh´|÷Ô3ÜóõÏóäóT¥,ÛÏ.}ŸzâþW.~ýà¯cù0¹:‘ïSr¼ûµwòž×ßIW˜'v ¯¤ÙbRæ/þñ~>ûàýVêDc@}Ïø³ÃöÊÀû~á@Ðz‘lÚÎßñKܾ÷Õ$>E½òJ"Bh¾qìQ~ó+ÿžôüÙz•`EQîæ“‡ï}åà×|œÀ޽ʽKcö캉{Þö+ìÚN9ùAù âÄäYîþò¿ãù“Odáêš°4Æ@êîáÏŽ|èûï;øA¬ù£Õ¾}Âk^õ#|øŽw3ï!v Òêu¾ì¿6nQ"2]šç£_ý,=û«C1úßâSWÈE&þ¯aÌ'Á¯ûoØ;¿óã?OdBRuë{Uy9[Û~60–Ø'üë¯þ'¾ùÔ7êA €EýûøäáO}ÿà×nº“0ø§Ö’O^¿ï |èMïZŠ×_Ìè"™%‹y†ýsüãÓß„ ¬! e’ôg/–wpq–ë½o!ä˳¥Nô»„C¯z=¿ýc?GhCœº/ Å/ù×t^ X±$.ác_ÿ<ýÇeI KÞÁ8 o»q‚Àû÷ 㣯`íM8WGü½Wà#?þ¿ÓåH½oüå¯ä2Umþq` Ÿ‡¿ò8vòH½:°R÷6¾ƒ?ÝØˆáÆ.÷O¿ÝrÕ±ÏÚwÔEø| [ùôOü:#=$nm¯¯ H‚,´–Ñùi~õKS£õ9„ÀBâ¾Èé½?Ç_ßç6êýì†Îö-á¯ØßÂWÓ¸Bá üîí?Ïž¡m”«ñü†M~¥\kÌ)ñ޾|W nçgɰEõ ¹‘ž‰Q}øå'ÞÓÔ|c–õ¾Ÿð3?|'wîãú¢{/I šEh:÷Fd]È!ÿíÉoðߺ¿>Z(ÔO#þvþô‰#/üÒ^ùÿì[–E¿—pí®ùо:[À—ñž°@=7W)‘º´* ;™¶àUùØ7¿À‰SOd¥gõöÀß1¯ÿëF•²B½Á/`õ-8]Nyª‡|ï¼éÇA2ñvóe@Ž‚€Ã]{ C]ým?Yq1óä·(%e¤6ñÓnŒÀZÞuàÇùÈø ×lNrózå€ÿûòÛï;° «ŸGLÝ}Êûoçµ»ö»dÃõeëË7¾ÖúoÕ3¨csׇ®ÚG`,Ö˜¶®³³>w,[ ßùÜSï(ôRNÏˤÀbÉzÆ`·phä‹|gtþòJcï&0;IkS»Gxóž[¨¤qûEÂýÒ¦,§3QœzÇÎþ-U}Þþ8:q’Ä¥ÆÖ«¾ÞÁ{Ï›÷ÜÂWNÙñ¬$}ño„v'šÞ üËË'þÏ7`̧PrKD¨nɺó‡ÞÄ«6ï$NÓ¶¸Ùq–õEðPðªˆ?rÍzs]m/K1)ó÷Ï?NÅ%¨jV\ó¾Úæ;8õˆ<–g^:Z_Q¤"ûxíðßðíщË#D>DhúHkªwÕAÿ07o»ŽRã›íÉ“ µ^cQœz¶÷1Ò½©£g_œå|y+†Tõ‚$“óž›w\ÇýÏÃÌxÐE÷Úô‘ø¿pép×›0öŸÕUõTköß´c?¹ "öIÄ“õû"D‰KÙ³iÖ˜Žž}jô‰KQcìCèP(älÄ›vìçë3_Ï„öRRMAÌÛùÀ-÷ò'=yi`åW°Ò•½D ÷ú¸yÛ^*®‰îï„ó7’ØíJ Í 7<Ù€½CÛ;úšÙÊ'¦ÏU¹·ƒ= -nó.ææm{ùú‰G 2ŸÙºè.˜n’ô=Àû.~ãÖ«ÐôK¿¥Ixöl¹šþ|Éâ~º•Ð¥HàýpõÊŽÞÍ w(þŸ?–éÒµ¤+k :pëÔПïaÏ–«yþÔÕý‰Õû2¼ƒß¸õø¿9}i éÏ›ë,ÿj%ËÍûI}Jª­'ß4Ö¯ëäÞ T‹yú½CW˜öídE9òÒqõ¨£­T·h»sSnÞÍógž¬_Â`3Iú3ÀŸ^||øºˆ¢yW] Óbà§0Àö¾¡Lü¯ÚÐ×&w_ˆØßcÐ ¤B ¸aËÕ=;]šãù©³$>Åã;Ö÷«þ§úé°½w PšÉÂìµ·ªy¾îS|ô¹øâ`!ÿD4ÿÛû·³Qã¨ßZáP¹@ °QRÀXRŸ°g`Û{7wôè3'™©ÌeÛżkún «Ë)䂈íý[8[œZÞX²¨¬`!ÿà›ÆÜI –Të $°»¯~µîk‡øÚ!(.ÂD!õŽý[vc¤}ë_ÃçŽá5‹â%êš¿·v äì1Âî¾aΞ;Ú@ ˆ%6w^\¼_7ðK –8ÓCc¤{Ø'«}_]ƒ“µá"&ˆ¬D¹ dÿð5=ûÒÜǦOƒØ§«™`]„_ñÏ>a¤{¨ºaÖÔ¸ß ÂOðþ}î¤gQ‡À@Ìu¨®&D˜£7W v+D_'z_;±. nÐl1ÔPñ × ^ÅHOgÖÿ÷ÆN0—ÈYKìÒå5Ø0)¡7_€0— Vrzc®ÃÛÀƒ&z3«¬ò=ˆRŸ®MôVœ¾&`¤3)ÐnBOf¹غ·u‰úŠ‘zÇc/e‰ŸØyŸ6~Z×ùž5 1Pèòüjæ±&ÀGo¾8¨ ü®{ãÒ#µ܇a¤a£&rADâéJPÖ0ö´u×#5.@`b#phÇ¾Žž]Ê‘ñcXR—6/|iŠ턜j$¤,‹‹Œ9Gðá>`ƒ`ý­Ø€%÷OjÞZKê]ë ¬¡ó/“õŸ3!©÷líâú¡={bê'gÇ@ ¥¤´š:•Tº¶J­]Ü4R/-E³&–iz+ðÀÆ@;¥þx ˆá½’ª[î׳aW–IÉ:D#B †Ø§Üºíz A®#<öÒ³”Ó„ÀX*.YŽ€vÂÕkÙu•VŠ÷+h 5’4kmÛ¶krmû·âŒÎûåø·vȽÚÄhÔ m¬kWCE(‡¶ßÐÑŸ/¥1=‡5†ŠK¨øæ\¥`{~umñ÷ ×Òf)j{¸ëPq»rkõk*>©WméþÕÃFf3§ŠÈÄ.aßðµììi»§´<ÉéÙ ¬Ši™TìvÒç°Æý*JŠ_͈‹¦Y¶ü»¹ëP¾V÷í +ÝŒÊ@CâW:u™ XÜéÛLÜKƒ-}(¾áB›š?íÉÛˆÀXïxýU7bDÖl$YûE¾tGVîUJã,ùÓŽ%ߎîoú¶ñ;Ö¯á’nNm ÔnA|a¹êÊ/ö]Ro@x][\¨ Ðêï×ÄÒjG>ˆP”‘žŽìm_¸ˆ°—xrüV, I‰Ø'Ëåßy-Å}ƒº@1­ds©-]š³‚P o·lŒÛ„J®•ØžNcRõõF` bh»ÜÞR ȺÕE(–BQñ)·ŽÜ@_®»î‡cSg8»0‰Ã\R#þ×áß‹v’i·â~€ÞµËnSø~l u]ºWHRZ"YJÊj㤎^+'  >XGÆPÕÓ—ïÆŠ! ~t绎œ{¶ÚƒØQr•¬µ®Ï¯_›èˆ‰G)%¥š ìëˆà\ÿÀvc…ÕYÀå8•2‰K#­­ûµÜ¾F¨Ðˆ}ažÔ;nÙÍÕýÛ²½m€Èˆ°—yr⡱ÌT¨øƒ4&Ü:üþV6‚z…¸¼\"¾ÒT²¶õ©íÞ8HÍ+54\…¢‹ÉK´ºBš \Öú,{P7°.@QúÃ.¢ "õ)?zÕŒ¾Ý~Ã"›:Íhq#†™xç=~…þm#ÚסDÊ.†´Ü8Ž¢u4Ùà\€4!þ"|ÊDežív§Úkb-—q-C±…õ ƒQªÊöž! ïé8YóØèsx<Î;fÓò²õ¿¢ågZkÿ •ùê¶ñ s;€mñ5–þhy–áB_ ’&i© ¤µÐî7Yô9ú¢.Ÿòúí7ÒuµÍýKÖÿäó„&`²ËXq†ÀΗ疥]GÜ­í{5ŸÇ.òlͺ˲ô’õØWm*ÙÎÔ&Ä_ŠÅœ.ϰ³Ð_g4×áÒÚÝÛˆ<ÁRƒ %oC† }ÄêxÍðulëêø¬ÇGŸÃ+”}ÂùdCµ ?·UK9maê2øN—g²3ŒDÖ¶‡L{MvÚ4Ý^Zå…)â|wÁiN0m“ÀÚF/¡¥L©çšžÍlf¤Þ¾ó`ö|›"Àˆa¶¼À“Ï“ NÏM³à*X̺úËÜá[ÎStymëBÀº"Ø&5†Ž¸…€‘œj–éÖÞ@RäTiŽ…ÞºmQºÊgmQ7ØnڸɢiO42;º‡HñÜ´y×ìÈJ·ÛTÆOM¾ÀDi–P,gKSYñ«ø6Å~{÷4²Ý§Js빿nMkÔSEÍÌÚÁyðDò«ŒUR@ñ £Kh,sq‘ñxEëªã›ŠðÚ÷×fnqs—1u??±üp³Ðò:T°öüÆ qãXSÉ×Í®™HcÆç'îÊl•æ f Ô\E®mCÔê~ g,{z·âQö nç†M»²Ý»mv-²Ærv~œ£ÓgÈÙˆ§NQt)a‹ºÅ:øˆjâêÕŪ¾ÿøüä²îo´fµê c‰ÛÀŠ b0A¿ŸÆ0¸4™VRò,caÈP®—tÅF1ÖÊ´°´ƒbQ”¼cßVò=$>åM;o!” ýžEdÛÅ}–Ø%8ï8±õcˆWYóëpóVávYb˜,ÏBe¶¾HVÖ:M1˜Ø8|âá2¾õ†Ýøµˆ_óûÂy&MHo˜[UÅ¢´á&6Œ´^ÅZIãú‚ýƒY™×ÞÜ8´g‰ûÛ5þ¦*sž8NW˜ã©ó§MŠ„bÚÒ÷í¸y¢«]Dƒ0™aá|sϨŒ€—|âáòFÆ8ŽÈ›AÛ#þâ›Í3׳‰B¯jc¢µäúÂT· îeS¡ŸÄ%¼i׫ H4m›û­1?ÎLeƒðôìÒ5õ“®IøVÿn’ÌŸÏôGSï o7pÞAU°>]¯ë׋ P “” ýQW]Ëm†êU„×ÎcÞqCÏ07oÞó)7mÞþþ]5«„¹¤ÈãOÓxæü‹¼XšÓ¤õKC"7W ü}ƒÇ ÕÀžÅcDÚ Ð-Ú‹´ÚPÿ©´Çù+FªPœÎv åºW'2¹€Õ 'm7~¨óRvwmáÙy+9‘"îØy+Þiõô±öFΆ<<~œ©xÁðèù²wòÚ–KºŒm¾5`EöЗ ž_!•z‰ÓLb úŒV€Jáiòñ(FFPm“ø+~¯Ìe‡%zÀFMäÅH‹G¸· ­rý<8Çî¾­ü³k^KoÔCùÉk^ÃPØOìÚýF„yWâщçè ò<1y‚‹õÆXG>³Í¢UWÙÅÙv¯4^íêÕ²x+Ð8¥Rh[´¿ÿù£N ÆÊb¿Õï>†…i(ÍOªlRsË®îÍY\—d Cš©š\ê²{½ç¶-×òÎëng°Ð‡ˆðÖ·±¯÷j*i\Íù¯}yU¬Og>.áP¾5þl K»u\µÒ@—çí(ÏAq:›kmȽ¡]ÕBÃa>úàÄÆK€Êïéomêÿwb¦ àÊÙIa¾ÚþL €w^;(¼8÷ÏLŸáÙ…qâHÓÕÆ@˜ãºÞ­¼adû6íÂWn|ëÎ[xUïNJq¥Ê(íYþV„óéG&ÓåùÖÙïqn¾Ú¨q­ÜA³¯ð¾f4kùšV2Ž_ì ÞÈØ[Åñ+¶ƒ­4S} Ý} åkM—žë˜ø+¤>+npqv@‚ I5OÞ†lÊ÷±½wˆÞzŤÂDiš—ŠSŒ•g(»è l- °½gˆá¦ºÁc¸ÐÏëGnb$¤T©Ðé£GFâU™‰‹üí¹ï5ç¾NJ ½OãLzßœðkúû ìŸTSR¾ÖÉ\;@_éå®ç0²oÙZñWˆ4Up•Œ#Äà4Û§KW®‹|Ñ—ïbïàŽ¥µ¡ï(½a×õï`oïUXg(UÊï2ŽlÀ©ò8'çGé sü×ãàÊ3ÕÃüšÉ©†Vž¯ª(WUe‹û+×"|³$Y#{ ÓÿÏÑW:rñp÷Ó üþ«¿„5û–'±F\~-â×JQÀc«{õ{£.îØ~sI‘™t©ò³I‘Øg-X­òAް›Í…ì·Ä儤ê­w¡F “pxô½aÇÆñí±gªýxt…éÞ¤@Q5k˜åÓ*Ç»e}¯²"²¢¢Qx¼ég5^Rvð¤þKÜÝ~wνÈý8½ Ûèë"~­aÈÙˆ$vIÀ°dkצ¬~O2C-K6e›9¼÷Ä¥e-ôr…ˆÇ§‘ªg!©ð—'È8¶¶WÐb4R} a]æªgé„4՚ЬÔXö’ÝÓˆ£iÅõkH‚쮎Oë~î!¤÷apËR›Ø"~•;"R°9ò&D½'IS’)ƒ•fÈZÁB$⺠yNVF+M“3!Ÿ<úwÌMŸÎ¼_³ýºÎ§×æ¡éF±{špoÇ*`ÅgÖ@âŽàçꔜ¦cd}è>·ôd+°ñe…!)Ù¢ämHΆٹ‚^I\ÖxÂÕ\«þß­¾’6®JâmÀŒ,p|ö=a¿}áùî©ïT­õ4ãÞUm]®ÐXzïÄ–µ~—ŸKcpM¦’Lÿ Ÿë´Gàú$@$Eì~+›WY¢ŸF "ä‚B‘³QÖvιÕÛ®6`¨*ù(ÂRŽÏœa êægóŸ~);šiµ¬‹D®[7ËjÖgíš”Éiû^€7“¿ZϘu­Üo?r#_$0kËÚfb¿.€a–9©Úm$æÈ!Î+©s%)¡ {„Fé <;s’}俀ƫÞi™ÓÖøÌ˜jó†&÷/}nÚ ¢­­#_ä£÷ ^¿0é_¿ˆ‘îU¡áFµÍD™¬00älH>ˆˆlˆK3`£$€hV1ÕßÓEa äLiœî Às³§yßß…òÌò!Mkm\iYêÞ†ž—÷Ô6zmý}K;€üiúë&ãºWòwô>é É«6ˆ˜zN1RMàdÀ{K݆\i’’¤)›ú{( †ŒW¦é »xvæ?ÿà§¡8–ÝÛŠsM+îo$ Z<Óè‚:·x ÷:þŠ?xüÉõ’ñÂN Ñäã$òSé[•¹[Sï×0¤>¡Q°… GÎZJ.%N’ŽÏìYɸÞ+]ù[‡ñÏ\Rb ßÍ×O?Æ/?øi(NfÑÈF‰®Vù)í%Ÿß4 ßJk¿•=`?‹Kî¹^>|äþðÖϘ»Hšå­iÍšz´›€\QB0ç+T‡1÷‡Ñê¹?¹ `dË ›†z(KõJO”çsÏ|…?úŸ²jÛ ¿¬#Z¦š›|Öª¨¥ÚCa5p´e å¿Yç?Ëï~öò ŸÜC,wbegÃÝÃkºˆµQfÖæƒLXcH’”Jc­©Þ-­H¾”ÑC„®|ŽíCƒlêÃDBìSzL7§KãüácŸã¯ŽUÃæµ5×Ö”‹6·ZÕ16üÝ®ÞÊÕ(E,mH+øSè…qÿÆàGÎññÛ>‚Èg–÷ëËÚ®a­+ËAcL¦lØÜßG¹Ta¡\¡’$8×<]¹ˆ¾6öÑß߃ Î{" 0ÄÜwü>ôøÿÃÄÌ‹`s¬Ù£PWpj³H°¶û{MHYÛtõVnËâþá÷Žœ»üèÿ#ÓÑ?'4oiÜG°•e·I=cé‰ tGy—²cëfvŒl¦’$KÊ•˜b¹B©TÁ{O…äs]¹ˆB!Gw!O˜¥µM@1­ðåSóožüþþì£Õ·ºÚKë®âøM)Z¤ª>] ß6÷÷›¢Ü@ìÿŽñÜÒm Þ{$áž[?€Óo`d aÉTS@hµ×M¶ãµ¤)/̾Ķž!òA´r­{øNUæ8W<ÏC£OóÕ³ñ¥Ñ#LÎ/—m§†ÛI÷j -D¿¶ø»•ù,¾²»ÈÊgÿß©ÿ5~û‘?ß(’m,þóÛ-/¾øyBûŽU-å›y6€|ý†S­fØÔeyø°‹ý=[ØÙ5ÄÎîÍìê!WåäbRæLq‚ÓÅI^(ŽóÌÜXVd‚ϸ]Ì…Í©Ý]¾ºÆýÚ@•”¦«éâ&¯½?0»/²ûêŸã_Üç^ž¸ç‡‡ý ¹©îDц¡úKa + Ó&^„,·ŒTm‰fQ¼@S®Öö¤ÀâË%e(M­ ­?ñO rwgl#ÉuqZ0ÿá¡[ÈñeD¶¬r W•‘)D]˜Âàòté § —dFXúºæsð S×VYs®qbÞÆï>üØFOéâ-×=‡îÄÊ€|ÃÝD+{ ôŒÐåq ï]þ U?• ˜©¶Î#¬ýoÕÔlü˜KJ07¶4ÚÀX„2N–»¾ÿbébò Ü{è×°òITeE«Ö®BT`¨ob©.ˆ®UtÚˆðr ¸Ÿµöüi“ýþ‚Weræ$%êj"¹•"Š×÷ñÁ‡?u±HtqðG·}ÐüQ}“É"UèÞÄ5=# ¤€¬D3š:é«#Ñ5ø:y-o«©ÔÅè­ðÂÜh¶áseŸՕćØÿú<|èãrw‚Öéá¨ÿ*®í¬ÙÂÕ|·Q[œ/ÒÞ*´Ý¬™5÷÷52 ­Ž§HgN7Ñ÷5ÇÇøÍïüÎÅ&Í¥ÀŸÜöA¬¹Dhtà,…¶íf[¾yf;FŸ´˜âzf©MX_Û 5*ñÏ•gxéü‰åM Ú¦* ½›ßº¸œépïßE(÷"äšz(Ø€C{ÙUØT­ù§ýòó•‘¹ ™a«hÞ XTV '‹Sœš®é®ö?ð#m̰U¬ ­®-ºy™jÏðæÇxpì鬾p±¥ëÊgç8§_Ûýpðœm)~E@¹þúë É'IÒW(»þ´ùæëâw²Kš@ºpMê ª§côìäÍ›_ÅpaE—¨j¶uZ.`–Ú&‹Éºy•føÚijÌNŸÌDþRƒÁ¡@ fSò×oøvø… T-åíL†³£££e >zôhz)ÔÀ¥€¹þúëíàà`.MÓ®0 û½÷CùÀK™-§÷ðšã7¹Ÿdˆ½e…w°8Ø<;7íáuC{ÙVDÄàð«;~Êΰ¥±—õÌ´bQõœ+NñíÉcœœz¾ÚÊÝ®.×ðLræÚ'ì¿ú¾“æ/§nÌ3™$ÉLÅ©©©ÊÑ£Gkv¢\¼p‰‡÷^TUl`My ;NÚñá—ì×Þ¾zòz¿—¢US—Œ×ИSãOqjú8}Wñơ빶w+½QVàáÔW›Ò鯨KŸ Fd©5ì\RäøÜ9¾9ùS³§!©T«€íêØ‚d¯Î<ñÐQsìúgƒG؉R΀ÀÖxçÅ{/—š—˱£€zõêB£ø/ÎÔôÈ~·3½Ú÷“³š$Kû„éóÇù§O@~ý»88p ×tÐuUƒÎz-6„ôí¶†C²]j"1*iÂlRäù…³ž~§¦^„òTµºÇT·7›Êøà¤Ìx*8Õ;-gÒP½ ]Z‡‹¯î/?¢(RcK“Ô9ç\‰:±T€rjÒ=ÏÜ뿜™zN‹Oìw›¸Jóä: H D <ÅS/MòÔ舺éëÞ¾žövoe{×}a7=AŽ\ËZÙ¯ËÀH½§’V˜O+ÌÆ œ-Nrlþ%žže¶8ñ²~_<¾µÑvîŒðÊi)x*8?p^¦Ôè\j”Šz%$MSç½wùBÞ6ÐWÐB¡ Z(¼1&õÞW€²)zõ À¼5vV…È‹çEÞð­ žrÝÏ\§=éNÍÓ]•¿~…åo̲‚M˜žã¡éã<´È™a7äzèµy¶„]ôEØöp>™Gf“ãI‘¹´œuꊪ[¿]”ÅAãØ@µÂ">8%å}ÏÉüÀ¤]ŠÎê‚ˆÌ Ì:ïæ1RÊÞûŠª¦•rÅO—¦µP(è+2pèС0ŸÏçÊårwE}^ý&`30lÄŒ[ªÿ?èÕ÷1ÝÆQÈÍõ‘?s뻆ƒT}:Oó8B]f"VëZn²v©–.ß–Ó’ ¿@iÇ v¡w–² o(yõ FÌ0Lã^ý(0L1çã8žÍçó år¹òðÃ'—*`/¡´‘žž¦§§ˆˆªk¬60ª*ŠfÑ3/"NpjHÕFI†G¥´íy[ê5•¹ ¸CCHëÊ##™q¶¸qÓ¬¸–Ĺ]þݺl˜‘4:!ŽS×¶S[ÏÉLË‚·Ì«0 ̈Ȕˆœ‘ `Ò«ŸÎ[c§½ó3•Je¡R©”&''“$I’ÉÉI)¸ÿRÛZ(´¿¿?-‹Iwww °©K­#^½zõΊ«:r˜zD¤ KÞ!yë4>+áÈiVò„3›5v«ïšÑ<Dä±°*˜ÚÎî›U'oÕÈ/WåòŽâ¾Q)o?g‹ý“RΕIÔxÑÄeAʪZ¬Îa˜¦½ú)à¼3å¼› Ãp! ÃR¥RI6oÞœÆq¬—Šø—:$€ÙµkWÐÝÝô÷÷Góóó…þþþn Ç«ï3búE¤ßy×oízªW7P ªšr^}dÅÆà 4 (vi47àó“›ÉO£G#zˆ°„"[åàFµýH5s²n3ŽyRæ$š¡24A¹wÚ”»ŠKJŠ!õ†Ô©K˜¨ˆH(U¯EÏ;ïf­±3ª:ãÕÏ1³ÀüÌÌÌBOOOiff&^XXHOž<™^ ÿÿr`Éصk—]A©TÊçr¹®0 »’$é ðw‘ð"²ø³KU»Tµ "y §ª9‰T5B %/Æx¬ |€uØJ— Ê]&Œ#Ä9¬ — ÛX}ãr“æJ>ÉmjSu&ŕԜõ*¤UyˆH¢ªq•ðU-‹HIDŠ‹@Uç$É\†óI’+•J±P(”kˆÉr— R# lwww ªQwww†aÎ9×EQÁ«ïòÎwkº˜. àÕwYc @ÈW‰©j$"QU…ÕŸVU‹Š‘¬$ÍHV‹õ#Ñs—j['#Ù¢ÙЍWp"™M²Hx ­>‘XUUWÙyW2bŠ@É«/zçŒ5E#¦ÇqÉZ[L’¤²°°‹ÈJâ¿bUÀ*\ýõ¦P(Aªæò¹(°A®\.çE$ŸËåòqÂ0̧iš¯ªœÉ©×HŒäŒ˜½ú°c+"VUˆU5^½Y ȶjª÷FŒŠˆWU_ýéçÕ/?#&¯>V¯1«× PJA”“$)GQTªT*eU-çóùrêÒJ¥\‰E$IÓ4-•JéÑ£Gýå þå@-äàÁƒfllÌ Ø(й8ÌårQ†Q’$9cL.‚(MÓœµ6rÎEÖÚÈ«Ôk¨ªQAÖ«·€5b¬WoŒãÕ fÅ!Ç^³`FŒVà«DwFÌ"R 5b’4MS‰ÅHbÄÄιØZ;çâ *išÆÞûJ†•$IâJ¥W%GÇq:==톇‡ÝáÇk ¯—ƒ\F,…O<(‹@èêê²Æ˜À{c‚|>zïC¯>T¯¡÷> Ã0–ˆ^{1sÎÖZkœsFŒX@¬±â¼klëw™‡ïÕYk½Ë¶#;kíj¯ª$H“$IŒ1‹€HŒ1I¹\N¼÷©1&ñÞ§ÅbÑÕ^kLO.ñ/7šª…¹¹93<¯€ž;wNèwåeÈu/×Ñ(º¿h<255e‰:<M³Ã޶oß.‹@Y9¢(R€³gÏ*@d©Ù0 5ŸÏ/fé¨p­ÒD¼Ü ¿8þdº ÍÔ,IEND®B`‚eric-6.0.8/eric/icons/default/projectSaveAs.png0000644000175000017500000000226712342633755020504 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ ()aMtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“IDATÁßOÕeÀñ÷çù>‡IÐL8µÉL1i 3œµÚ¼pÍ‹´Ö7µùäºé¢KËÕ²fffVF“õã‚Ò%KË–tf[Ô@à(ppÎáû}žïPÝÅ×K˜Ç—””4E"‘UÌ!‚îÑÑѯ;::’ÌB×ÔÔä766>ÙØØøjEEE5ÿþÏÀÀ@o{{»N§Ó§‰Ä3Ðñx<¶}ûöµµµË”RÌDD˜RYYYáyÞs½½½?'‰ëÌ@c6+¥9{ö¬Çüxk×®­ó}ÿaà:3Ðιh’¥ùߎDYUKŠ`0ñ /·¼À47޽ClsLÞ}Åùι(³Ð"BÎ(ºüjJ£ËX^ yw»yï|;yP‹ªc<øPÙÜú«Ð""ÌF3IDQ`C胪­{¸!-0 gÀø À¡˜‹!¹t?÷zGPcà§à^èÓ‚Ò£0‘…ÌxŽÕ¥QD„Ùh&Õ­,äh³F+ðx(Â?`-„!8ò)+Š0-"ܰ|r5K¬\Q¾î&Úxñà~þó¬Ù²ßÀ¸²é…ˆ0Ù·o_Ë΃‡ß|û§B¶o\ʺ ¸õk+y´„.µž¡²ª’Ý{ö≀"(lrêäôÞ¾Ñ"‚ Œæ7ïÁ¢(¬Ûú4ÅQ(ˆ€ |qâ«c«Y[ƒ„LeÓd?ýˆÐPºw?ee‹éîêZ ™$ž¾…1(£a¡†NÀZ‹ïûD´b,;Áç`ü×é¸ö= ?ï¡Z4Ùl–À÷Ñ"‚ˆà)GÄðd( éühOãä|Ãàp†ÐúØþ3\ùî_¹KËóQ†‹¢øA€1Å$A‰à)ð<Ðx8 t`¬µcÈäkУ?¼ñ§ÚR<»ÃïÚAIíL`°Ö¢E‡Ã"• (0 >dS 5ÓŒk- Ïù”ën’=òÚûIš·e)(o °rE%Æ`­E3iCU‡ž°ꀼäiÐD˜æœ³–Û=Ý;|€æ&Å+Gÿä±õI† 9w¹ŸÅåo!"L±Ö"ë'Õ××oc‰ÎßÄVÓüÔŽŸîdI´‡šjhûm+VÄH¥Ó¤FFÐZ“J¥æik¼Öµì©àâµ!†»y|ÓçYÏK‡SZZJë—­´]¸@Q4J&“A1OM.çjç7oõñLýÇ¿*f×aÈ;wÈe³hía­Á9‡fžêêNvÒ°á ç.V³rÍ2Š‹‹Ä÷}FR#Lär¸¼|Œ1hæéÒ—ýÜh¿’h\?ܰc ]]]A€µ–¾Þ>††‡ñ”‡sÎü òØÊ‚ÿ^AqIEND®B`‚eric-6.0.8/eric/icons/default/new.png0000644000175000017500000000174012342633755016517 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<æPLTEÿÿÿ”Û¤¾¡²11-11,>>>+œ½™¯œœ«Ÿ›¹Žµ”­­­¢¢¢•™¤§«ÁÁÀÃÃÂÆÆÅÇÇÆˆ‰«­®°²³¸«°ŠŽ¦¨ž£¬­ • œ Å œ¬´¸ÅŸ ½ &ž'¥''¼(È(*¹*,¢/¦/¨/11Í12Ž2¤7§:º:=’CºCCÃCD“D§G©L¯LÉSµAVÏVZÐV\¸A`×YjÂipÄirÜY‚Ë‚ƒÝƒ„݃ˆÝˆŠÙŠšÖšš×ššÜš¸¸¹ºººÁÁÁÄÄÄÆÆÆÌÌÌÍÍÍ×××ãäååææåæçåõåæçèçèèèééèéêéêêéíéêëëëìììíííîîîîîîïïïïïïððððððññññññòòòòòòóóóóóóôôôôôôõõõõõõöööööö÷÷÷÷÷÷øø÷ù÷÷ú÷øøøùùùúúúûûûüüüýýýþþþÿÿÿhUßw*tRNS "&47>?@IPpqstwËÎÑÓØÜßââäåæèêðñ÷÷úúZ˜B6IDATÁ=rqÐó{žÿÍ%ŒÁ :“Fg :PÙ•eø¨Î*=…QYC˜ ƒð†0ɽ÷uN ç—gê×|°’å@]¸}i“ì¿Ý?ɹû骖¬ÞŸ½¸ºãÍøþîÓP]¤êãtùdÅ:gvކîNª*_×»gþ,¦ÕÖÐtUÕÏéÜåÙé¡ÓUÕ•@jHWWWe»_lŸºçu~¬KUww÷ÖÕúUƒîÕf]ºªº¶uãÊfš˜ö¾|=ª»{‘XÜŸŸ÷ñzú¶ªª‰¸¶óáËÁb÷èçÆPÕ•DdëNR5BD U‰Dļ™¡Ò ‘éãfž_žÀ !Äîuóão¡$6+óÓ½?`Hb3ÏO>þÍö~ǯö²\8þà?Ë d¸C^IEND®B`‚eric-6.0.8/eric/icons/default/vcsDiff.png0000644000175000017500000000303212342633755017306 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs  šœtIMEØ3ø[vtEXtCommentCreated with The GIMPïd%nbKGDÿÿÿ ½§“~IDAT8ËU]lSe~ÚžÓžþ­]O×µûé6Æ~ØØ8² 1Ñ.LŒÆÄK.¼ÀÄ+ï¼Q¹0܈»PLàÊ2ã\¦L¶9 ¶6¶vý=§=çô´¾oeÄxÅ—<=m¿ï{¾ç}Þ÷ýŽOÆØØ˜µ¦¦Æîõz#ù|þ°®ë'ü~¿Çãñ:¡T*Á4Mˆ¢MÓŠ¹\.›J¥nÑÜy§ÓùC6›]Y__ׇ‡‡KÌgák×®IDÐçóùÞ%œ¤…Žr¹ UU+d6› ü›‡Õj­|gкÊ Ñ2™Ì×tÐçtàÔ Âèè¨K„WÜn÷UUUݼ&+„•“-– ‰Ýn¯R$•ÿ7fbúßA‘¾eÆsÍG4}^ ‚×(œc„n^ȃÃÞ$åqµˆéD µ ¦¡!à´¡Ö-ÂjÁÓ(xql'¯ÙÛäM”Ãb"^ÄOVÌß™XU5ôG#èûQ0L¬¤Ì'²0´ì–ª„\¶­Z[[ä'Ëä‹BំÎ`R†¢hˆgçñh.ƒžþ¸ðJvf‰*b#§!¦*(T$uÈg¯Ï" ù®x<Žÿ’³Úb±XQ‘/hjëDæáFÏ}‚hs zwA® Ã-‰°‹^n7<~9°[þK Íi2\¤r©11U\.–ð!RIÜœõ;qpûT]¸;³ˆ+—¾ElñB‘:lëDSG ¤%•NW ¤®Ìàls5°Úp8\!înïE‰ËlcUhA–6MèW°ŠOáÞZ¾ö]8R<Š•; &¹‰³Ÿ|Œ¶! îÝoZΜ9³@Š|TrNg—É!Ê&j«¢¨‹†a”u(FéBºi Žû˜3n#†9ÀtÀkDÕ÷À\BKfU¶"IDvî(I’*vð“=ÖD°07Ëß_"å%´v¶ ­§.‡„ˆÙÙÅÂòÊ>+~/þˆ 8h´ Û“ï›$Tp©ÈjÙ &d“:1uëEÔÖí![²È+øæÜ(9U!7†ŽöãFæ+èÞ|¥.*¿G.Ìö™ì±`cÅ VÌY纆Y‹áAIÇ삈™Ùýpû†ÑЙ ¾ 5¯¢uåMÔøe¬ˆ¿áŽù+í+bKù“;oƒg'¥2×,Y–A-ŽÆ­*îÏK¸5mC2iC_%ת`6VÄÄäqx1ü’J™•‡B!ƒA¤$ºåè>ZZ]D<·[¨ÙÂlj‰G—ánÚ ÓÖ1‚¡¡$7 f2@}дktÞ&åÓÔÚ dK#Á Ï2®ÇH(ëH7P¦¤˜”Äd:‰t& Ý¡Âðð^3Õ7*6j$B³:Ð-‹‰J¶®^½j Ü# .&“ÉËti›TábCÒ›m°æ¡sÈ(iÊ ŠNP@À%#v·†Ý T£D–èèIqaóÕDÈ7{Špã pòô¡S¡æÐ«ž°{·([EVlÚtèy:(Ï6™ˆ Š!DšÄ©X’m!Xéž¶˜<ÃðúÝòá7önÙQ?¢ûÔ— ÁLh6÷º«ðåË?õ÷ìjyáÈȈj÷M;C ½~L?ñÿ†xhdÿ®}Çvxj#§^ÿßKOæl-[ZûúvôþÁ™ø"»¿IEND®B`‚eric-6.0.8/eric/icons/default/preferences-graphics.png0000644000175000017500000000204012342633755022017 0ustar piotrpiotr‰PNG  IHDRójœ sBITÛáOà pHYsaaÁ0UútEXtSoftwarewww.inkscape.org›î<øPLTEÿÿÿ‡ |&°!¢ } L52E0.E0.£££t E0.‡ K75š"~ h C.,$­ h _MKH-+y nyyyX=:?,*— E0.C/-3'&E hF21hWUE0.€’fkk¶«K20^LJN:8ÔÊVCAE hii°Îr s °’ SVV“ sa^h ±i^…–h «ÏoXVi^"ÓÉ}‚‚µªx m– Œ$¬™}lj† oqqm‘in fMKpgf»»»^DAÌÌÊ} t’q Z>;lRQv^\àׂ”t ØØØÞÀ¡ƒ ËÌÌ¢ÍÍËÀÕÖÖr } †  ™!£$¬&¯x m‡ }’ — Œ¦›®±µ«ÄºÎÎÍÏÔÉÞãÙêêêÎÑtRNS  !$$%%%%'(*+,,----//00336689<“=¢fí$,Lx H^óC¸¶‰ zq#AÈìR˜¤P*$4ÅvMš˜™(%4Ô.‡[;ؘ*%þŒªO B}­h°êÝQ·¥z™«$4ض¿d¹f§#ó/EfßwÖßã¬*<ØN‚§ïª—‹óGKeÉÑÃA.ÄÍ?Þ7€çðÕe«¾¶Tyò²ŸI+¯OZ¸ŽÝ\7ëAÅ×Ç^Äl~¾Õnã·Mº@ùón&±õ]‹Ì»FYq²”2~ýXœ8\%M™”IEND®B`‚eric-6.0.8/eric/icons/default/bookmark16.png0000644000175000017500000000143312342633754017700 0ustar piotrpiotr‰PNG  IHDR(-SsBITÛáOà pHYs»»:ìãâtEXtSoftwarewww.inkscape.org›î<’PLTEÿÿÿ¾€¾€Óœ·wÓœ·wÞ¦@Þ¦@ʼnʼn¸n·qΔÑ‘ä¦ã§šPšMšLRê³ê´Ñѳj³oԖؚؚ Å‚¬cÇ… Õ—›Y¨d­i“T­f©e¬g®j°nªf^Ä„ Á~Ó”×›#ØŸ!Ú¢%᪂ á©ðÉLðÊMգؖíÁYï¼Tð²ðÈ`ñ¯ñ¿SñÈeòÇTòàóËgóÐiô§ôËkôÜõ¬õ½ö·öÈöÉnöÏn÷º÷»÷½÷Æ÷ÊY÷Ë0÷Ìf÷Ñn÷Ón÷Óv÷Ôy÷Õn÷Öv÷Öy÷×n÷Øv÷Ý}÷Þ}÷ß}÷æ÷ï†÷ï‡øÄ øÇøÈøÑ\øÑføÔiøÖfø×\øØføØnøÙnøÙvøÚnøÚvøÛvùÌùÍùÐùÑù×HùÙfùÚfùÛSùÛfùÜ\úÒúÓúÚûßûâüì‰ðË;tRNS'.ADEU‘–¬±²¹ÆÊÏÖÞãæææçèééìììííîîïïòôö÷÷øøøùúúúýý.÷ì2´IDATÓc`ÀÄ%Pù‚–VBÈ|vÓ´T NŸYÎ=%Å]žÂã—”5¶MLJNv0Q–``à6t‹ŽŠ-*)--Iˆó4âa`T°óˆŒ/,..ˆ‰pVbb``1p Ïέ®«ÉÏqÑgÂkš•W_[ækÆ1VÚ>0½¼¡"ÓGj«¢cPYSKs£ŸT@Ã;¸Ò˵µ)C* åa£«¢®g¢ Õáb`àVÃæm?U%¼'¡ÉIEND®B`‚eric-6.0.8/eric/icons/default/clearRight.png0000644000175000017500000000236512342633754020015 0ustar piotrpiotr‰PNG  IHDRÄ´l; pHYs7\7\ËǤ¹bKGDÿÿÿ ½§“gIDAT8ËÕUKL\UþϽó‚y1¼S„‚4$„*°€…®0©¬(ÐÆ-%±Ó•”¤ KèuÝXcY54mÜè‚ °!$ŠèÌ@ ¼fF†×À̽÷øý×a5.\˜8Éû8ç~çÿ¿Ç¹Dÿ·Ÿ¸ÙÝET\T,ž¿x.b±©ªJRJ ËôD]×ÉíöPkk«|26&«.U‘Ó•I§§§ôäÛ±¿W½SI†aÕbM=ùíoqa1=é£Ö«¤…<^Y­VšU¶6· ¹6›U¡Ppõ¹Ün³#¦¢ºú²ŒÇã¼~øò§—Ž/¿úâ¿YYYyÖÁf³¢Ó$YÎJç›p8L/^½½½æ¤ÁÁAZ[[3+®¯¯§îîn …(?Ñ@Ußõë7òWCk7‡††Œ¾¾Ï„Åb•\5‹VqFvNvÇíqõ÷÷Ë’’%33SÔÕÕ‰ùùyQQQÁ‹™´åççóY,--é^÷ÊÁÁ~Ýøø³\SÈÈl†4°ÏçëÁçúúºlnnv»œN'œM:àäÈȈ@wŠÛíÖ\.wU,¶÷>(ú8gºgfeeõ@u'*”Á`P455™â±Ç- ´Ä4 ¿ßÏôÈããcãš×ë}+^M$ß+Âài`¬x[7t'ª+++‹Pmm­éqæ˜y¦‰‰ M1‰3ƒ'ÑqÁÖÖÖx6Ê:¦ÅÓ4M¬†V)h©­­ZZZˆSÈ0}‰Š»ººÜÒÌÌ ÓÄt ˆl`aõè舽þÝ%Ñ}ÚϹXu¼J€ê›››­IË……ɼò=!çæædMM‘Ê»P`:®?ý»=#<…ËÊJåää¤~xx(!Ž ÚÞ~MÞºý‰dQѪDgÆ£G£~Õ=-q¼ÿ1ƒ(f’è\@\Y¾¬[>_VæÒ«Wìqpp@Ÿ?¦ðíîìR ðšêäôô´xð`H·Ùí*ÄûEtâý§ŒËNûs¤ ŠŠŠ.U–ç2ÝÕÕÕ‚ÝŽ„MWhÏÞÞ]¸PŒÀ¬J„Â7ð¬ódPÆ)8] Z-6²Ùmêöö¶`åአÞhŽ ¶›¡%55 ý Ð6¼Ç[  wŽ[Kyy9¡¥ìôõÔÔôe¨| ªG“vË„;¶œZZZ5ïA“ Îfûÿýc]x>R‰ü‚ø|ÙØp4º{·‰Z&dßL¬‰Ä©&ˆ†Š§ òb£ÇhÅawHãü€ÿÝ7ïWTF2¢ì_hÆ"zTXtSoftwarexÚ+//×ËÌË.NN,HÕË/J6ØXSÊ\IEND®B`‚eric-6.0.8/eric/Preferences/0000755000175000017500000000000012557365404014721 5ustar piotrpiotreric-6.0.8/eric/Preferences/PreferencesLexer.py0000644000175000017500000001761512451233372020535 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a special QextScintilla lexer to handle the preferences. """ from __future__ import unicode_literals from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor, QFont from PyQt5.Qsci import QsciLexer import Preferences import Globals class PreferencesLexerError(Exception): """ Class defining a special error for the PreferencesLexer class. """ def __init__(self): """ Constructor """ self._errorMessage = QCoreApplication.translate( "PreferencesLexerError", "Unspecific PreferencesLexer error.") def __repr__(self): """ Special method returning a representation of the exception. @return string representing the error message """ return repr(self._errorMessage) def __str__(self): """ Special method returning a string representation of the exception. @return string representing the error message """ return self._errorMessage class PreferencesLexerLanguageError(PreferencesLexerError): """ Class defining a special error for the PreferencesLexer class. """ def __init__(self, language): """ Constructor @param language lexer language (string) """ PreferencesLexerError.__init__(self) self._errorMessage = QCoreApplication.translate( "PreferencesLexerError", 'Unsupported Lexer Language: {0}').format(language) class PreferencesLexer(QsciLexer): """ Subclass of QsciLexer to implement preferences specific lexer methods. """ def __init__(self, language, parent=None): """ Constructor @param language The lexer language. (string) @param parent The parent widget of this lexer. (QextScintilla) @exception PreferencesLexerLanguageError raised to indicate an invalid lexer language """ super(PreferencesLexer, self).__init__(parent) # These default font families are taken from QScintilla if Globals.isWindowsPlatform(): self.__defaultFontFamily = "Courier New" elif Globals.isMacPlatform(): self.__defaultFontFamily = "Courier" else: self.__defaultFontFamily = "Bitstream Vera Sans Mono" # instantiate a lexer object for the given language import QScintilla.Lexers lex = QScintilla.Lexers.getLexer(language) if lex is None: raise PreferencesLexerLanguageError(language) # define the local store self.colours = {} self.defaultColours = {} self.papers = {} self.defaultPapers = {} self.eolFills = {} self.defaultEolFills = {} self.fonts = {} self.defaultFonts = {} self.descriptions = {} self.ind2style = {} self.styles = [] # fill local store with default values from lexer # and built up styles list and conversion table from index to style self.__language = lex.language() index = 0 for i in range(128): desc = lex.description(i) if desc: self.descriptions[i] = desc self.styles.append(desc) self.colours[i] = lex.defaultColor(i) self.papers[i] = lex.defaultPaper(i) self.eolFills[i] = lex.defaultEolFill(i) self.fonts[i] = lex.defaultFont(i) # Override QScintilla's default font family to # always use a monospaced font self.fonts[i].setFamily(self.__defaultFontFamily) self.defaultColours[i] = lex.defaultColor(i) self.defaultPapers[i] = lex.defaultPaper(i) self.defaultEolFills[i] = lex.defaultEolFill(i) self.defaultFonts[i] = lex.defaultFont(i) self.defaultFonts[i].setFamily(self.__defaultFontFamily) self.ind2style[index] = i index += 1 self.colorChanged.connect(self.setColor) self.eolFillChanged.connect(self.setEolFill) self.fontChanged.connect(self.setFont) self.paperChanged.connect(self.setPaper) # read the last stored values from preferences file self.readSettings(Preferences.Prefs.settings, "Scintilla") def defaultColor(self, style): """ Public method to get the default colour of a style. @param style the style number (int) @return colour """ return self.defaultColours[style] def color(self, style): """ Public method to get the colour of a style. @param style the style number (int) @return colour """ return self.colours[style] def setColor(self, c, style): """ Public method to set the colour for a style. @param c colour (int) @param style the style number (int) """ self.colours[style] = QColor(c) def defaultPaper(self, style): """ Public method to get the default background for a style. @param style the style number (int) @return colour """ return self.defaultPapers[style] def paper(self, style): """ Public method to get the background for a style. @param style the style number (int) @return colour """ return self.papers[style] def setPaper(self, c, style): """ Public method to set the background for a style. @param c colour (int) @param style the style number (int) """ self.papers[style] = QColor(c) def defaulEolFill(self, style): """ Public method to get the default eolFill flag for a style. @param style the style number (int) @return eolFill flag """ return self.defaultEolFills[style] def eolFill(self, style): """ Public method to get the eolFill flag for a style. @param style the style number (int) @return eolFill flag """ return self.eolFills[style] def setEolFill(self, eolfill, style): """ Public method to set the eolFill flag for a style. @param eolfill eolFill flag (boolean) @param style the style number (int) """ self.eolFills[style] = eolfill def defaultFont(self, style): """ Public method to get the default font for a style. @param style the style number (int) @return font """ return self.defaultFonts[style] def font(self, style): """ Public method to get the font for a style. @param style the style number (int) @return font """ return self.fonts[style] def setFont(self, f, style): """ Public method to set the font for a style. @param f font @param style the style number (int) """ self.fonts[style] = QFont(f) def language(self): """ Public method to get the lexers programming language. @return language """ return self.__language def description(self, style): """ Public method to get a descriptive string for a style. @param style the style number (int) @return description of the style (string) """ if style in self.descriptions: return self.descriptions[style] else: return "" eric-6.0.8/eric/Preferences/ShortcutDialog.ui0000644000175000017500000001077712060166053020213 0ustar piotrpiotr ShortcutDialog 0 0 539 134 Edit Shortcut Press your shortcut keys and select OK Qt::NoFocus Select to change the primary keyboard shortcut Primary Shortcut: true Qt::NoFocus Press to clear the key sequence buffer. Clear true Qt::NoFocus Select to change the alternative keyboard shortcut Alternative Shortcut: false Qt::NoFocus Press to clear the key sequence buffer. Clear true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource keyEdit alternateKeyEdit buttonBox primaryButton toggled(bool) primaryClearButton setEnabled(bool) 80 23 178 24 alternateButton toggled(bool) alternateClearButton setEnabled(bool) 98 56 247 66 buttonBox rejected() ShortcutDialog reject() 92 96 100 117 eric-6.0.8/eric/Preferences/ViewProfileSidebarsDialog.ui0000644000175000017500000001040712060166053022276 0ustar piotrpiotr ViewProfileSidebarsDialog 0 0 608 177 Configure View Profiles true Select the windows, that should be visible, when the different profiles are active. Qt::AlignVCenter &Edit Profile Left Sidebar true Right Sidebar true Bottom Sidebar true &Debug Profile Left Sidebar Right Sidebar true Bottom Sidebar true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource eprtCheckBox epltCheckBox ephtCheckBox dpltCheckBox dprtCheckBox dphtCheckBox buttonBox buttonBox accepted() ViewProfileSidebarsDialog accept() 56 208 56 229 buttonBox rejected() ViewProfileSidebarsDialog reject() 146 215 146 234 eric-6.0.8/eric/Preferences/ProgramsDialog.py0000644000175000017500000003414212537064320020200 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Programs page. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os import re from PyQt5.QtCore import pyqtSlot, Qt, QProcess from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QApplication, QTreeWidgetItem, QHeaderView, \ QDialog, QDialogButtonBox from E5Gui.E5Application import e5App from .Ui_ProgramsDialog import Ui_ProgramsDialog import Preferences import Utilities class ProgramsDialog(QDialog, Ui_ProgramsDialog): """ Class implementing the Programs page. """ def __init__(self, parent=None): """ Constructor @param parent The parent widget of this dialog. (QWidget) """ super(ProgramsDialog, self).__init__(parent) self.setupUi(self) self.setObjectName("ProgramsDialog") self.setWindowFlags(Qt.Window) self.__hasSearched = False self.programsList.headerItem().setText( self.programsList.columnCount(), "") self.searchButton = self.buttonBox.addButton( self.tr("Search"), QDialogButtonBox.ActionRole) self.searchButton.setToolTip( self.tr("Press to search for programs")) def show(self): """ Public slot to show the dialog. """ QDialog.show(self) if not self.__hasSearched: self.on_programsSearchButton_clicked() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.searchButton: self.on_programsSearchButton_clicked() @pyqtSlot() def on_programsSearchButton_clicked(self): """ Private slot to search for all supported/required programs. """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.programsList.clear() header = self.programsList.header() header.setSortIndicator(0, Qt.AscendingOrder) header.setSortIndicatorShown(False) # 1. do the Qt4/Qt5 programs # 1a. Translation Converter exe = Utilities.isWindowsPlatform() and \ "{0}.exe".format(Utilities.generateQtToolName("lrelease")) or \ Utilities.generateQtToolName("lrelease") exe = os.path.join(Utilities.getQtBinariesPath(), exe) version = self.__createProgramEntry( self.tr("Translation Converter (Qt)"), exe, '-version', 'lrelease', -1) # 1b. Qt Designer if Utilities.isWindowsPlatform(): exe = os.path.join( Utilities.getQtBinariesPath(), "{0}.exe".format(Utilities.generateQtToolName("designer"))) elif Utilities.isMacPlatform(): exe = Utilities.getQtMacBundle("designer") else: exe = os.path.join( Utilities.getQtBinariesPath(), Utilities.generateQtToolName("designer")) self.__createProgramEntry( self.tr("Qt Designer"), exe, version=version) # 1c. Qt Linguist if Utilities.isWindowsPlatform(): exe = os.path.join( Utilities.getQtBinariesPath(), "{0}.exe".format(Utilities.generateQtToolName("linguist"))) elif Utilities.isMacPlatform(): exe = Utilities.getQtMacBundle("linguist") else: exe = os.path.join( Utilities.getQtBinariesPath(), Utilities.generateQtToolName("linguist")) self.__createProgramEntry( self.tr("Qt Linguist"), exe, version=version) # 1d. Qt Assistant if Utilities.isWindowsPlatform(): exe = os.path.join( Utilities.getQtBinariesPath(), "{0}.exe".format(Utilities.generateQtToolName("assistant"))) elif Utilities.isMacPlatform(): exe = Utilities.getQtMacBundle("assistant") else: exe = os.path.join( Utilities.getQtBinariesPath(), Utilities.generateQtToolName("assistant")) self.__createProgramEntry( self.tr("Qt Assistant"), exe, version=version) # 2. do the PyQt programs # 2a. Translation Extractor PyQt4 self.__createProgramEntry( self.tr("Translation Extractor (Python, PyQt4)"), Utilities.isWindowsPlatform() and "pylupdate4.exe" or "pylupdate4", '-version', 'pylupdate', -1) # 2b. Forms Compiler PyQt4 self.__createProgramEntry( self.tr("Forms Compiler (Python, PyQt4)"), Utilities.isWindowsPlatform() and "pyuic4.bat" or "pyuic4", '--version', 'Python User', 4) # 2c. Resource Compiler PyQt4 self.__createProgramEntry( self.tr("Resource Compiler (Python, PyQt4)"), Utilities.isWindowsPlatform() and "pyrcc4.exe" or "pyrcc4", '-version', 'Resource Compiler', -1) # 2d. Translation Extractor PyQt5 self.__createProgramEntry( self.tr("Translation Extractor (Python, PyQt5)"), Utilities.isWindowsPlatform() and "pylupdate5.exe" or "pylupdate5", '-version', 'pylupdate', -1) # 2e. Forms Compiler PyQt5 self.__createProgramEntry( self.tr("Forms Compiler (Python, PyQt5)"), Utilities.isWindowsPlatform() and "pyuic5.bat" or "pyuic5", '--version', 'Python User', 4) # 2f. Resource Compiler PyQt5 self.__createProgramEntry( self.tr("Resource Compiler (Python, PyQt5)"), Utilities.isWindowsPlatform() and "pyrcc5.exe" or "pyrcc5", '-version', 'Resource Compiler', -1) # 3. do the PySide programs # 3a. Translation Extractor PySide self.__createProgramEntry( self.tr("Translation Extractor (Python, PySide)"), Utilities.generatePySideToolPath("pyside-lupdate"), '-version', '', -1, versionRe='lupdate') # 3b. Forms Compiler PySide self.__createProgramEntry( self.tr("Forms Compiler (Python, PySide)"), Utilities.generatePySideToolPath("pyside-uic"), '--version', 'PySide User', 5, versionCleanup=(0, -1)) # 3.c Resource Compiler PySide self.__createProgramEntry( self.tr("Resource Compiler (Python, PySide)"), Utilities.generatePySideToolPath("pyside-rcc"), '-version', 'Resource Compiler', -1) # 4. do the Ruby programs # 4a. Forms Compiler for Qt4 self.__createProgramEntry( self.tr("Forms Compiler (Ruby, Qt4)"), Utilities.isWindowsPlatform() and "rbuic4.exe" or "rbuic4", '-version', 'Qt', -1) # 4b. Resource Compiler for Qt4 self.__createProgramEntry( self.tr("Resource Compiler (Ruby, Qt4)"), Utilities.isWindowsPlatform() and "rbrcc.exe" or "rbrcc", '-version', 'Ruby Resource Compiler', -1) # 5. do the CORBA programs # 5a. omniORB exe = Preferences.getCorba("omniidl") if Utilities.isWindowsPlatform(): exe += ".exe" self.__createProgramEntry( self.tr("CORBA IDL Compiler"), exe, '-V', 'omniidl', -1) # 6. do the spell checking entry try: import enchant try: text = os.path.dirname(enchant.__file__) except AttributeError: text = "enchant" try: version = enchant.__version__ except AttributeError: version = self.tr("(unknown)") except (ImportError, AttributeError, OSError): text = "enchant" version = "" self.__createEntry( self.tr("Spell Checker - PyEnchant"), text, version) # 7. do the pygments entry try: import pygments try: text = os.path.dirname(pygments.__file__) except AttributeError: text = "pygments" try: version = pygments.__version__ except AttributeError: version = self.tr("(unknown)") except (ImportError, AttributeError, OSError): text = "pygments" version = "" self.__createEntry( self.tr("Source Highlighter - Pygments"), text, version) # do the plugin related programs pm = e5App().getObject("PluginManager") for info in pm.getPluginExeDisplayData(): if info["programEntry"]: self.__createProgramEntry( info["header"], info["exe"], versionCommand=info["versionCommand"], versionStartsWith=info["versionStartsWith"], versionPosition=info["versionPosition"], version=info["version"], versionCleanup=info["versionCleanup"], ) else: self.__createEntry( info["header"], info["text"], info["version"] ) self.programsList.sortByColumn(0, Qt.AscendingOrder) QApplication.restoreOverrideCursor() self.__hasSearched = True def __createProgramEntry(self, description, exe, versionCommand="", versionStartsWith="", versionPosition=0, version="", versionCleanup=None, versionRe=None): """ Private method to generate a program entry. @param description descriptive text (string) @param exe name of the executable program (string) @param versionCommand command line switch to get the version info (string) if this is empty, the given version will be shown. @param versionStartsWith start of line identifying version info (string) @param versionPosition index of part containing the version info (integer) @keyparam version version string to show (string) @keyparam versionCleanup tuple of two integers giving string positions start and stop for the version string (tuple of integers) @keyparam versionRe regexp to determine the line identifying version info (string). Takes precedence over versionStartsWith. @return version string of detected or given version (string) """ itmList = self.programsList.findItems( description, Qt.MatchCaseSensitive) if itmList: itm = itmList[0] else: itm = QTreeWidgetItem(self.programsList, [description]) font = itm.font(0) font.setBold(True) itm.setFont(0, font) if not exe: itm.setText(1, self.tr("(not configured)")) else: if os.path.isabs(exe): if not Utilities.isExecutable(exe): exe = "" else: exe = Utilities.getExecutablePath(exe) if exe: if versionCommand and \ (versionStartsWith != "" or (versionRe is not None and versionRe != "")) and \ versionPosition: proc = QProcess() proc.setProcessChannelMode(QProcess.MergedChannels) proc.start(exe, [versionCommand]) finished = proc.waitForFinished(10000) if finished: output = str(proc.readAllStandardOutput(), Preferences.getSystem("IOEncoding"), 'replace') if versionRe is None: versionRe = "^{0}".format( re.escape(versionStartsWith)) versionRe = re.compile(versionRe, re.UNICODE) for line in output.splitlines(): if versionRe.search(line): try: version = line.split()[versionPosition] if versionCleanup: version = version[ versionCleanup[0]:versionCleanup[1] ] break except IndexError: version = self.tr("(unknown)") else: version = self.tr("(unknown)") else: version = self.tr("(not executable)") QTreeWidgetItem(itm, [exe, version]) itm.setExpanded(True) else: itm.setText(1, self.tr("(not found)")) QApplication.processEvents() self.programsList.header().resizeSections(QHeaderView.ResizeToContents) self.programsList.header().setStretchLastSection(True) return version def __createEntry(self, description, entryText, entryVersion): """ Private method to generate a program entry. @param description descriptive text (string) @param entryText text to show (string) @param entryVersion version string to show (string). """ itm = QTreeWidgetItem(self.programsList, [description]) font = itm.font(0) font.setBold(True) itm.setFont(0, font) if len(entryVersion): QTreeWidgetItem(itm, [entryText, entryVersion]) itm.setExpanded(True) else: itm.setText(1, self.tr("(not found)")) QApplication.processEvents() self.programsList.header().resizeSections(QHeaderView.ResizeToContents) self.programsList.header().setStretchLastSection(True) eric-6.0.8/eric/Preferences/ToolGroupConfigurationDialog.py0000644000175000017500000001537012451233372023072 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a configuration dialog for the tools menu. """ from __future__ import unicode_literals import copy from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtWidgets import QDialog from E5Gui import E5MessageBox from .Ui_ToolGroupConfigurationDialog import Ui_ToolGroupConfigurationDialog class ToolGroupConfigurationDialog(QDialog, Ui_ToolGroupConfigurationDialog): """ Class implementing a configuration dialog for the tool groups. """ def __init__(self, toolGroups, currentGroup, parent=None): """ Constructor @param toolGroups list of configured tool groups @param currentGroup number of the active group (integer) @param parent parent widget (QWidget) """ super(ToolGroupConfigurationDialog, self).__init__(parent) self.setupUi(self) self.currentGroup = currentGroup self.toolGroups = copy.deepcopy(toolGroups) for group in toolGroups: self.groupsList.addItem(group[0]) if len(toolGroups): self.groupsList.setCurrentRow(0) self.on_groupsList_currentRowChanged(0) @pyqtSlot() def on_newButton_clicked(self): """ Private slot to clear all entry fields. """ self.nameEdit.clear() @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add a new entry. """ groupName = self.nameEdit.text() if not groupName: E5MessageBox.critical( self, self.tr("Add tool group entry"), self.tr("You have to give a name for the group to add.")) return if len(self.groupsList.findItems( groupName, Qt.MatchFlags(Qt.MatchExactly))): E5MessageBox.critical( self, self.tr("Add tool group entry"), self.tr("An entry for the group name {0} already exists.") .format(groupName)) return self.groupsList.addItem(groupName) self.toolGroups.append([groupName, []]) @pyqtSlot() def on_changeButton_clicked(self): """ Private slot to change an entry. """ row = self.groupsList.currentRow() if row < 0: return groupName = self.nameEdit.text() if not groupName: E5MessageBox.critical( self, self.tr("Add tool group entry"), self.tr("You have to give a name for the group to add.")) return if len(self.groupsList.findItems( groupName, Qt.MatchFlags(Qt.MatchExactly))): E5MessageBox.critical( self, self.tr("Add tool group entry"), self.tr("An entry for the group name {0} already exists.") .format(groupName)) return self.toolGroups[row][0] = groupName self.groupsList.currentItem().setText(groupName) @pyqtSlot() def on_deleteButton_clicked(self): """ Private slot to delete the selected entry. """ row = self.groupsList.currentRow() if row < 0: return res = E5MessageBox.yesNo( self, self.tr("Delete tool group entry"), self.tr("""

Do you really want to delete the tool group""" """ "{0}"?

""") .format(self.groupsList.currentItem().text()), icon=E5MessageBox.Warning) if not res: return if row == self.currentGroup: # set to default group if current group gets deleted self.currentGroup = -1 del self.toolGroups[row] itm = self.groupsList.takeItem(row) del itm if row >= len(self.toolGroups): row -= 1 self.groupsList.setCurrentRow(row) self.on_groupsList_currentRowChanged(row) @pyqtSlot() def on_downButton_clicked(self): """ Private slot to move an entry down in the list. """ curr = self.groupsList.currentRow() self.__swap(curr, curr + 1) self.groupsList.clear() for group in self.toolGroups: self.groupsList.addItem(group[0]) self.groupsList.setCurrentRow(curr + 1) if curr + 1 == len(self.toolGroups): self.downButton.setEnabled(False) self.upButton.setEnabled(True) @pyqtSlot() def on_upButton_clicked(self): """ Private slot to move an entry up in the list. """ curr = self.groupsList.currentRow() self.__swap(curr - 1, curr) self.groupsList.clear() for group in self.toolGroups: self.groupsList.addItem(group[0]) self.groupsList.setCurrentRow(curr - 1) if curr - 1 == 0: self.upButton.setEnabled(False) self.downButton.setEnabled(True) def on_groupsList_currentRowChanged(self, row): """ Private slot to set the lineedits depending on the selected entry. @param row the row of the selected entry (integer) """ if row >= 0 and row < len(self.toolGroups): group = self.toolGroups[row] self.nameEdit.setText(group[0]) self.deleteButton.setEnabled(True) self.changeButton.setEnabled(True) if row != 0: self.upButton.setEnabled(True) else: self.upButton.setEnabled(False) if row + 1 != len(self.toolGroups): self.downButton.setEnabled(True) else: self.downButton.setEnabled(False) else: self.nameEdit.clear() self.downButton.setEnabled(False) self.upButton.setEnabled(False) self.deleteButton.setEnabled(False) self.changeButton.setEnabled(False) def getToolGroups(self): """ Public method to retrieve the tool groups. @return a list of lists containing the group name and the tool group entries """ return self.toolGroups[:], self.currentGroup def __swap(self, itm1, itm2): """ Private method used two swap two list entries given by their index. @param itm1 index of first entry (int) @param itm2 index of second entry (int) """ tmp = self.toolGroups[itm1] self.toolGroups[itm1] = self.toolGroups[itm2] self.toolGroups[itm2] = tmp eric-6.0.8/eric/Preferences/Shortcuts.py0000644000175000017500000002721012451233372017262 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing functions dealing with keyboard shortcuts. """ from __future__ import unicode_literals from PyQt5.QtCore import QFile, QIODevice, QCoreApplication from PyQt5.QtGui import QKeySequence from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from Preferences import Prefs, syncPreferences def __readShortcut(act, category, prefClass): """ Private function to read a single keyboard shortcut from the settings. @param act reference to the action object (E5Action) @param category category the action belongs to (string) @param prefClass preferences class used as the storage area """ if act.objectName(): accel = prefClass.settings.value( "Shortcuts/{0}/{1}/Accel".format(category, act.objectName())) if accel is not None: act.setShortcut(QKeySequence(accel)) accel = prefClass.settings.value( "Shortcuts/{0}/{1}/AltAccel".format(category, act.objectName())) if accel is not None: act.setAlternateShortcut(QKeySequence(accel), removeEmpty=True) def readShortcuts(prefClass=Prefs, helpViewer=None, pluginName=None): """ Module function to read the keyboard shortcuts for the defined QActions. @keyparam prefClass preferences class used as the storage area @keyparam helpViewer reference to the help window object @keyparam pluginName name of the plugin for which to load shortcuts (string) """ if helpViewer is None and pluginName is None: for act in e5App().getObject("Project").getActions(): __readShortcut(act, "Project", prefClass) for act in e5App().getObject("UserInterface").getActions('ui'): __readShortcut(act, "General", prefClass) for act in e5App().getObject("UserInterface").getActions('wizards'): __readShortcut(act, "Wizards", prefClass) for act in e5App().getObject("DebugUI").getActions(): __readShortcut(act, "Debug", prefClass) for act in e5App().getObject("ViewManager").getActions('edit'): __readShortcut(act, "Edit", prefClass) for act in e5App().getObject("ViewManager").getActions('file'): __readShortcut(act, "File", prefClass) for act in e5App().getObject("ViewManager").getActions('search'): __readShortcut(act, "Search", prefClass) for act in e5App().getObject("ViewManager").getActions('view'): __readShortcut(act, "View", prefClass) for act in e5App().getObject("ViewManager").getActions('macro'): __readShortcut(act, "Macro", prefClass) for act in e5App().getObject("ViewManager").getActions('bookmark'): __readShortcut(act, "Bookmarks", prefClass) for act in e5App().getObject("ViewManager").getActions('spelling'): __readShortcut(act, "Spelling", prefClass) actions = e5App().getObject("ViewManager").getActions('window') if actions: for act in actions: __readShortcut(act, "Window", prefClass) for category, ref in e5App().getPluginObjects(): if hasattr(ref, "getActions"): actions = ref.getActions() for act in actions: __readShortcut(act, category, prefClass) if helpViewer is not None: for act in helpViewer.getActions(): __readShortcut(act, "HelpViewer", prefClass) if pluginName is not None: try: ref = e5App().getPluginObject(pluginName) if hasattr(ref, "getActions"): actions = ref.getActions() for act in actions: __readShortcut(act, pluginName, prefClass) except KeyError: # silently ignore non available plugins pass def __saveShortcut(act, category, prefClass): """ Private function to write a single keyboard shortcut to the settings. @param act reference to the action object (E5Action) @param category category the action belongs to (string) @param prefClass preferences class used as the storage area """ if act.objectName(): prefClass.settings.setValue( "Shortcuts/{0}/{1}/Accel".format(category, act.objectName()), act.shortcut().toString()) prefClass.settings.setValue( "Shortcuts/{0}/{1}/AltAccel".format(category, act.objectName()), act.alternateShortcut().toString()) def saveShortcuts(prefClass=Prefs): """ Module function to write the keyboard shortcuts for the defined QActions. @param prefClass preferences class used as the storage area """ # step 1: clear all previously saved shortcuts prefClass.settings.beginGroup("Shortcuts") prefClass.settings.remove("") prefClass.settings.endGroup() # step 2: save the various shortcuts for act in e5App().getObject("Project").getActions(): __saveShortcut(act, "Project", prefClass) for act in e5App().getObject("UserInterface").getActions('ui'): __saveShortcut(act, "General", prefClass) for act in e5App().getObject("UserInterface").getActions('wizards'): __saveShortcut(act, "Wizards", prefClass) for act in e5App().getObject("DebugUI").getActions(): __saveShortcut(act, "Debug", prefClass) for act in e5App().getObject("ViewManager").getActions('edit'): __saveShortcut(act, "Edit", prefClass) for act in e5App().getObject("ViewManager").getActions('file'): __saveShortcut(act, "File", prefClass) for act in e5App().getObject("ViewManager").getActions('search'): __saveShortcut(act, "Search", prefClass) for act in e5App().getObject("ViewManager").getActions('view'): __saveShortcut(act, "View", prefClass) for act in e5App().getObject("ViewManager").getActions('macro'): __saveShortcut(act, "Macro", prefClass) for act in e5App().getObject("ViewManager").getActions('bookmark'): __saveShortcut(act, "Bookmarks", prefClass) for act in e5App().getObject("ViewManager").getActions('spelling'): __saveShortcut(act, "Spelling", prefClass) actions = e5App().getObject("ViewManager").getActions('window') if actions: for act in actions: __saveShortcut(act, "Window", prefClass) for category, ref in e5App().getPluginObjects(): if hasattr(ref, "getActions"): actions = ref.getActions() for act in actions: __saveShortcut(act, category, prefClass) for act in e5App().getObject("DummyHelpViewer").getActions(): __saveShortcut(act, "HelpViewer", prefClass) def exportShortcuts(fn): """ Module function to export the keyboard shortcuts for the defined QActions. @param fn filename of the export file (string) """ # let the plugin manager create on demand plugin objects pm = e5App().getObject("PluginManager") pm.initOnDemandPlugins() f = QFile(fn) if f.open(QIODevice.WriteOnly): from E5XML.ShortcutsWriter import ShortcutsWriter ShortcutsWriter(f).writeXML() f.close() else: E5MessageBox.critical( None, QCoreApplication.translate( "Shortcuts", "Export Keyboard Shortcuts"), QCoreApplication.translate( "Shortcuts", "

The keyboard shortcuts could not be written to file" " {0}.

") .format(fn)) def importShortcuts(fn): """ Module function to import the keyboard shortcuts for the defined E5Actions. @param fn filename of the import file (string) """ # let the plugin manager create on demand plugin objects pm = e5App().getObject("PluginManager") pm.initOnDemandPlugins() f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.ShortcutsReader import ShortcutsReader reader = ShortcutsReader(f) reader.readXML() f.close() if not reader.hasError(): shortcuts = reader.getShortcuts() setActions(shortcuts) saveShortcuts() syncPreferences() else: E5MessageBox.critical( None, QCoreApplication.translate( "Shortcuts", "Import Keyboard Shortcuts"), QCoreApplication.translate( "Shortcuts", "

The keyboard shortcuts could not be read from file" " {0}.

") .format(fn)) return def __setAction(actions, sdict): """ Private function to write a single keyboard shortcut to the settings. @param actions list of actions to set (list of E5Action) @param sdict dictionary containg accelerator information for one category """ for act in actions: if act.objectName(): try: accel, altAccel = sdict[act.objectName()] act.setShortcut(QKeySequence(accel)) act.setAlternateShortcut(QKeySequence(altAccel), removeEmpty=True) except KeyError: pass def setActions(shortcuts): """ Module function to set actions based on new format shortcuts file. @param shortcuts dictionary containing the accelerator information read from a XML file """ if "Project" in shortcuts: __setAction(e5App().getObject("Project").getActions(), shortcuts["Project"]) if "General" in shortcuts: __setAction(e5App().getObject("UserInterface").getActions('ui'), shortcuts["General"]) if "Wizards" in shortcuts: __setAction(e5App().getObject("UserInterface").getActions('wizards'), shortcuts["Wizards"]) if "Debug" in shortcuts: __setAction(e5App().getObject("DebugUI").getActions(), shortcuts["Debug"]) if "Edit" in shortcuts: __setAction(e5App().getObject("ViewManager").getActions('edit'), shortcuts["Edit"]) if "File" in shortcuts: __setAction(e5App().getObject("ViewManager").getActions('file'), shortcuts["File"]) if "Search" in shortcuts: __setAction(e5App().getObject("ViewManager").getActions('search'), shortcuts["Search"]) if "View" in shortcuts: __setAction(e5App().getObject("ViewManager").getActions('view'), shortcuts["View"]) if "Macro" in shortcuts: __setAction(e5App().getObject("ViewManager").getActions('macro'), shortcuts["Macro"]) if "Bookmarks" in shortcuts: __setAction(e5App().getObject("ViewManager").getActions('bookmark'), shortcuts["Bookmarks"]) if "Spelling" in shortcuts: __setAction(e5App().getObject("ViewManager").getActions('spelling'), shortcuts["Spelling"]) if "Window" in shortcuts: actions = e5App().getObject("ViewManager").getActions('window') if actions: __setAction(actions, shortcuts["Window"]) for category, ref in e5App().getPluginObjects(): if category in shortcuts and hasattr(ref, "getActions"): actions = ref.getActions() __setAction(actions, shortcuts[category]) if "HelpViewer" in shortcuts: __setAction(e5App().getObject("DummyHelpViewer").getActions(), shortcuts["HelpViewer"]) eric-6.0.8/eric/Preferences/ToolGroupConfigurationDialog.ui0000644000175000017500000001513412060166053023052 0ustar piotrpiotr ToolGroupConfigurationDialog 0 0 475 391 Configure Tool Groups true false Delete the selected entry <b>Delete</b> <p>Delete the selected entry.</p> &Delete Alt+D Add a new tools entry <b>Add</b> <p>Add a new tool groups entry with the name entered below.</p> &Add Alt+A &Group name: nameEdit false Change the values of the selected entry <b>Change</b> <p>Change the values of the selected entry.</p> C&hange Alt+H Qt::Vertical QSizePolicy::Expanding 87 20 Clear all entry fields <b>New</b> <p>Clear all entry fields for entering a new tool groups entry.</p> &New Alt+N false Move up <b>Move Up</b> <p>Move the selected entry up.</p> &Up Alt+U false Move down <b>Move Down</b> <p>Move the selected entry down.</p> Do&wn Alt+W Enter the menu text <b>Menu text</b> <p>Enter the menu text. Precede the accelerator key with an & character.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource groupsList nameEdit newButton addButton changeButton deleteButton upButton downButton buttonBox accepted() ToolGroupConfigurationDialog accept() 20 365 22 387 buttonBox rejected() ToolGroupConfigurationDialog reject() 143 370 145 391 eric-6.0.8/eric/Preferences/ShortcutDialog.py0000644000175000017500000001406212537064320020220 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog for the configuration of a keyboard shortcut. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, QEvent, Qt from PyQt5.QtGui import QKeySequence from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_ShortcutDialog import Ui_ShortcutDialog class ShortcutDialog(QDialog, Ui_ShortcutDialog): """ Class implementing a dialog for the configuration of a keyboard shortcut. @signal shortcutChanged(QKeySequence, QKeySequence, bool, string) emitted after the OK button was pressed """ shortcutChanged = pyqtSignal(QKeySequence, QKeySequence, bool, str) def __init__(self, parent=None, name=None, modal=False): """ Constructor @param parent The parent widget of this dialog. (QWidget) @param name The name of this dialog. (string) @param modal Flag indicating a modal dialog. (boolean) """ super(ShortcutDialog, self).__init__(parent) if name: self.setObjectName(name) self.setModal(modal) self.setupUi(self) self.setWindowFlags(Qt.Window) self.keyIndex = 0 self.keys = [0, 0, 0, 0] self.noCheck = False self.objectType = "" self.primaryClearButton.clicked.connect(self.__clear) self.alternateClearButton.clicked.connect(self.__clear) self.primaryButton.clicked.connect(self.__typeChanged) self.alternateButton.clicked.connect(self.__typeChanged) self.shortcutsGroup.installEventFilter(self) self.primaryButton.installEventFilter(self) self.alternateButton.installEventFilter(self) self.primaryClearButton.installEventFilter(self) self.alternateClearButton.installEventFilter(self) self.keyEdit.installEventFilter(self) self.alternateKeyEdit.installEventFilter(self) self.buttonBox.button(QDialogButtonBox.Ok).installEventFilter(self) self.buttonBox.button(QDialogButtonBox.Cancel).installEventFilter(self) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def setKeys(self, key, alternateKey, noCheck, objectType): """ Public method to set the key to be configured. @param key key sequence to be changed (QKeySequence) @param alternateKey alternate key sequence to be changed (QKeySequence) @param noCheck flag indicating that no uniqueness check should be performed (boolean) @param objectType type of the object (string). """ self.keyIndex = 0 self.keys = [0, 0, 0, 0] self.keyEdit.setText(key.toString()) self.alternateKeyEdit.setText(alternateKey.toString()) self.primaryButton.setChecked(True) self.noCheck = noCheck self.objectType = objectType def on_buttonBox_accepted(self): """ Private slot to handle the OK button press. """ self.hide() self.shortcutChanged.emit( QKeySequence(self.keyEdit.text()), QKeySequence(self.alternateKeyEdit.text()), self.noCheck, self.objectType) def __clear(self): """ Private slot to handle the Clear button press. """ self.keyIndex = 0 self.keys = [0, 0, 0, 0] self.__setKeyEditText("") def __typeChanged(self): """ Private slot to handle the change of the shortcuts type. """ self.keyIndex = 0 self.keys = [0, 0, 0, 0] def __setKeyEditText(self, txt): """ Private method to set the text of a key edit. @param txt text to be set (string) """ if self.primaryButton.isChecked(): self.keyEdit.setText(txt) else: self.alternateKeyEdit.setText(txt) def eventFilter(self, watched, event): """ Public method called to filter the event queue. @param watched the QObject being watched @param event the event that occurred @return always False """ if event.type() == QEvent.KeyPress: self.keyPressEvent(event) return True return False def keyPressEvent(self, evt): """ Protected method to handle a key press event. @param evt the key event (QKeyEvent) """ if evt.key() in [Qt.Key_Control, Qt.Key_Meta, Qt.Key_Shift, Qt.Key_Alt, Qt.Key_Menu, Qt.Key_Hyper_L, Qt.Key_Hyper_R, Qt.Key_Super_L, Qt.Key_Super_R]: return if self.keyIndex == 4: self.keyIndex = 0 self.keys = [0, 0, 0, 0] if evt.key() == Qt.Key_Backtab and evt.modifiers() & Qt.ShiftModifier: self.keys[self.keyIndex] = Qt.Key_Tab else: self.keys[self.keyIndex] = evt.key() if evt.modifiers() & Qt.ShiftModifier: self.keys[self.keyIndex] += Qt.SHIFT if evt.modifiers() & Qt.ControlModifier: self.keys[self.keyIndex] += Qt.CTRL if evt.modifiers() & Qt.AltModifier: self.keys[self.keyIndex] += Qt.ALT if evt.modifiers() & Qt.MetaModifier: self.keys[self.keyIndex] += Qt.META self.keyIndex += 1 if self.keyIndex == 1: self.__setKeyEditText(QKeySequence(self.keys[0]).toString()) elif self.keyIndex == 2: self.__setKeyEditText( QKeySequence(self.keys[0], self.keys[1]).toString()) elif self.keyIndex == 3: self.__setKeyEditText(QKeySequence( self.keys[0], self.keys[1], self.keys[2]).toString()) elif self.keyIndex == 4: self.__setKeyEditText(QKeySequence( self.keys[0], self.keys[1], self.keys[2], self.keys[3]).toString()) eric-6.0.8/eric/Preferences/__init__.py0000644000175000017500000031452412554665654017052 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Package implementing the preferences interface. The preferences interface consists of a class, which defines the default values for all configuration items and stores the actual values. These values are read and written to the eric6 preferences file by module functions. The data is stored in a file in a subdirectory of the users home directory. The individual configuration data is accessed by accessor functions defined on the module level. The module is simply imported wherever it is needed with the statement 'import Preferences'. Do not use 'from Preferences import *' to import it. """ from __future__ import unicode_literals try: basestring # __IGNORE_WARNING__ except NameError: basestring = str import os import fnmatch import shutil import json import sys from PyQt5.QtCore import QDir, QPoint, QLocale, QSettings, QFileInfo, \ QCoreApplication, QByteArray, QSize, QUrl, Qt, QLibraryInfo from PyQt5.QtGui import QColor, QFont, QPalette from PyQt5.QtWidgets import QInputDialog, QApplication from PyQt5.QtNetwork import QNetworkRequest from PyQt5.QtWebKit import QWebSettings from PyQt5.Qsci import QsciScintilla, QsciLexerPython from E5Gui import E5FileDialog from E5Network.E5Ftp import E5FtpProxyType from Globals import settingsNameOrganization, settingsNameGlobal, \ settingsNameRecent, isWindowsPlatform, findPythonInterpreters, \ getPyQt5ModulesDirectory from Project.ProjectBrowserFlags import SourcesBrowserFlag, FormsBrowserFlag, \ ResourcesBrowserFlag, TranslationsBrowserFlag, InterfacesBrowserFlag, \ OthersBrowserFlag, AllBrowsersFlag class Prefs(object): """ A class to hold all configuration items for the application. """ # defaults for the variables window varDefaults = { "LocalsFilter": "[]", "GlobalsFilter": "[]" } # defaults for the debugger debuggerDefaults = { "RemoteDbgEnabled": False, "RemoteHost": "", "RemoteExecution": "", "PassiveDbgEnabled": False, "PassiveDbgPort": 42424, "PassiveDbgType": "Python", "AutomaticReset": False, "Autosave": True, "ThreeStateBreakPoints": False, "SuppressClientExit": False, "BreakAlways": False, "ShowExceptionInShell": True, "PythonInterpreter": "", "Python3Interpreter": "", "RubyInterpreter": "", "DebugClientType": "standard", # supported "standard", "threaded", "custom" "DebugClient": "", "DebugClientType3": "standard", # supported "standard", "threaded", "custom" "DebugClient3": "", "DebugEnvironmentReplace": False, "DebugEnvironment": "", "PythonRedirect": True, "PythonNoEncoding": False, "Python3Redirect": True, "Python3NoEncoding": False, "RubyRedirect": True, "ConsoleDbgEnabled": False, "ConsoleDbgCommand": "", "PathTranslation": False, "PathTranslationRemote": "", "PathTranslationLocal": "", "NetworkInterface": "127.0.0.1", "AutoViewSourceCode": False, } debuggerDefaults["AllowedHosts"] = ["127.0.0.1", "::1%0"] if sys.version_info[0] == 2: debuggerDefaults["PythonExtensions"] = ".py .pyw .py2 .pyw2 .ptl" # space separated list of Python extensions debuggerDefaults["Python3Extensions"] = ".py .pyw .py3 .pyw3" # space separated list of Python3 extensions else: debuggerDefaults["PythonExtensions"] = ".py2 .pyw2 .ptl" # space separated list of Python extensions debuggerDefaults["Python3Extensions"] = ".py .pyw .py3 .pyw3" # space separated list of Python3 extensions # defaults for the UI settings uiDefaults = { "Language": "System", "Style": "System", "StyleSheet": "", "ViewManager": "tabview", "LayoutType": "Sidebars", "SidebarDelay": 200, # allowed values are "Toolboxes" and "Sidebars" "LayoutShellEmbedded": 0, # 0 = separate # 1 = embedded in debug browser "LayoutFileBrowserEmbedded": 0, # 0 = separate # 1 = embedded in debug browser # 2 = embedded in project browser "BrowsersListFoldersFirst": True, "BrowsersHideNonPublic": False, "BrowsersListContentsByOccurrence": False, "BrowsersListHiddenFiles": False, "BrowsersFileFilters": "*.py[co];*.so;*.dll", "LogViewerAutoRaise": True, "SingleApplicationMode": False, "CaptionShowsFilename": True, "CaptionFilenameLength": 100, "RecentNumber": 9, "TopLeftByLeft": True, "BottomLeftByLeft": False, "TopRightByRight": True, "BottomRightByRight": False, "TabViewManagerFilenameLength": 40, "TabViewManagerFilenameOnly": True, "ShowFilePreview": True, "ShowFilePreviewJS": True, "ShowFilePreviewSSI": True, "ViewProfiles2": { "edit": [ # saved state main window with toolbox windows (0) QByteArray(), # visibility of the toolboxes/sidebars (1) # left, bottom, right [True, True, True], # saved states of the splitters and sidebars of the # sidebars layout (2) # left splitter, vertical splitter, left sidebar, # bottom sidebar, right splitter, right sidebar [QByteArray(), QByteArray(), QByteArray(), QByteArray(), QByteArray(), QByteArray()], ], "debug": [ # saved state main window with toolbox windows (0) QByteArray(), # visibility of the toolboxes/sidebars (1) # left, bottom, right [False, True, True], # saved states of the splitters and sidebars of the # sidebars layout (2) # left splitter, vertical splitter, left sidebar, # bottom sidebar, right splitter, right sidebar [QByteArray(), QByteArray(), QByteArray(), QByteArray(), QByteArray(), QByteArray()], ], }, "ToolbarManagerState": QByteArray(), "PreviewSplitterState": QByteArray(), "ShowSplash": True, "SingleCloseButton": False, "SplitOrientationVertical": False, "PerformVersionCheck": 4, # 0 = off # 1 = at startup # 2 = daily # 3 = weekly # 4 = monthly "UseProxy": False, "UseSystemProxy": True, "UseHttpProxyForAll": False, "ProxyHost/Http": "", "ProxyHost/Https": "", "ProxyHost/Ftp": "", "ProxyPort/Http": 80, "ProxyPort/Https": 443, "ProxyPort/Ftp": 21, "ProxyUser/Http": "", "ProxyUser/Https": "", "ProxyUser/Ftp": "", "ProxyPassword/Http": "", "ProxyPassword/Https": "", "ProxyPassword/Ftp": "", "ProxyType/Ftp": E5FtpProxyType.NoProxy, "ProxyAccount/Ftp": "", "PluginRepositoryUrl6": "http://eric-ide.python-projects.org/plugins6/repository.xml", "VersionsUrls6": [ "http://die-offenbachs.homelinux.org:48888/eric/versions/" "versions6", "http://eric-ide.python-projects.org/versions/versions6", ], "OpenOnStartup": 0, # 0 = nothing # 1 = last file # 2 = last project # 3 = last multiproject # 4 = last global session "DownloadPath": "", "RequestDownloadFilename": True, "CheckErrorLog": True, "LogStdErrColour": QColor(Qt.red), "NotificationsEnabled": True, "NotificationTimeout": 5, # time in seconds the notification # is shown "NotificationPosition": QPoint(10, 10), } iconsDefaults = { "Path": [], } # defaults for the cooperation settings cooperationDefaults = { "ServerPort": 42000, "AutoStartServer": False, "TryOtherPorts": True, "MaxPortsToTry": 100, "AutoAcceptConnections": False, "BannedUsers": [], } # defaults for the editor settings editorDefaults = { "AutosaveInterval": 0, "TabWidth": 4, "IndentWidth": 4, "IndentationGuides": True, "UnifiedMargins": False, "LinenoMargin": True, "FoldingMargin": True, "FoldingStyle": 1, "TabForIndentation": False, "TabIndents": True, "ConvertTabsOnLoad": False, "AutomaticEOLConversion": True, "ShowWhitespace": False, "WhitespaceSize": 1, "ShowEOL": False, "UseMonospacedFont": False, "WrapLongLinesMode": QsciScintilla.WrapNone, "WrapVisualFlag": QsciScintilla.WrapFlagNone, "WarnFilesize": 512, "ClearBreaksOnClose": True, "StripTrailingWhitespace": False, "CommentColumn0": True, "OverrideEditAreaColours": False, "EdgeMode": QsciScintilla.EdgeNone, "EdgeColumn": 80, "AutoIndentation": True, "BraceHighlighting": True, "CreateBackupFile": False, "CaretLineVisible": False, "CaretLineAlwaysVisible": False, "CaretWidth": 1, "ColourizeSelText": False, "CustomSelectionColours": False, "ExtendSelectionToEol": False, "AutoPrepareAPIs": False, "AutoCompletionEnabled": False, "AutoCompletionCaseSensitivity": True, "AutoCompletionReplaceWord": False, "AutoCompletionShowSingle": False, "AutoCompletionSource": QsciScintilla.AcsDocument, "AutoCompletionThreshold": 2, "AutoCompletionFillups": False, "CallTipsEnabled": False, "CallTipsVisible": 0, "CallTipsStyle": QsciScintilla.CallTipsNoContext, "CallTipsScintillaOnFail": False, # show QScintilla calltips, if plugin fails "AutoCheckSyntax": True, "OnlineSyntaxCheck": True, "OnlineSyntaxCheckInterval": 5, "OnlineChangeTrace": True, "OnlineChangeTraceInterval": 500, # 1000 milliseconds "AutoReopen": False, "AnnotationsEnabled": True, "MiniContextMenu": False, "SearchMarkersEnabled": True, "QuickSearchMarkersEnabled": True, "MarkOccurrencesEnabled": True, "MarkOccurrencesTimeout": 500, # 500 milliseconds "AdvancedEncodingDetection": True, "SpellCheckingEnabled": True, "AutoSpellCheckingEnabled": True, "AutoSpellCheckChunkSize": 30, "SpellCheckStringsOnly": True, "SpellCheckingMinWordSize": 3, "SpellCheckingDefaultLanguage": "en_US", "SpellCheckingPersonalWordList": "", "SpellCheckingPersonalExcludeList": "", "DefaultEncoding": "utf-8", "DefaultOpenFilter": QCoreApplication.translate( 'Lexers', 'Python Files (*.py *.py2 *.py3)'), "DefaultSaveFilter": QCoreApplication.translate( 'Lexers', "Python3 Files (*.py)"), "AdditionalOpenFilters": [], "AdditionalSaveFilters": [], "ZoomFactor": 0, "PreviewHtmlFileNameExtensions": ["html", "htm", "svg", "asp", "kid"], "PreviewMarkdownFileNameExtensions": ["md", "markdown"], "PreviewRestFileNameExtensions": ["rst"], "PreviewQssFileNameExtensions": ["qss"], "VirtualSpaceOptions": QsciScintilla.SCVS_NONE, # All (most) lexers "AllFoldCompact": True, # Bash specifics "BashFoldComment": True, # CMake specifics "CMakeFoldAtElse": False, # C++ specifics "CppCaseInsensitiveKeywords": False, "CppFoldComment": True, "CppFoldPreprocessor": False, "CppFoldAtElse": False, "CppIndentOpeningBrace": False, "CppIndentClosingBrace": False, "CppDollarsAllowed": True, "CppStylePreprocessor": False, "CppHighlightTripleQuotedStrings": False, "CppHighlightHashQuotedStrings": False, # CoffeeScript specifics "CoffeScriptFoldComment": False, "CoffeeScriptDollarsAllowed": True, "CoffeeScriptStylePreprocessor": False, # CSS specifics "CssFoldComment": True, "CssHssSupport": False, "CssLessSupport": False, "CssSassySupport": False, # D specifics "DFoldComment": True, "DFoldAtElse": False, "DIndentOpeningBrace": False, "DIndentClosingBrace": False, # Gettext specifics "PoFoldComment": False, # HTML specifics "HtmlFoldPreprocessor": False, "HtmlFoldScriptComments": False, "HtmlFoldScriptHeredocs": False, "HtmlCaseSensitiveTags": False, "HtmlDjangoTemplates": False, "HtmlMakoTemplates": False, # Pascal specifics "PascalFoldComment": True, "PascalFoldPreprocessor": False, "PascalSmartHighlighting": True, # Perl specifics "PerlFoldComment": True, "PerlFoldPackages": True, "PerlFoldPODBlocks": True, "PerlFoldAtElse": False, # PostScript specifics "PostScriptTokenize": False, "PostScriptLevel": 3, "PostScriptFoldAtElse": False, # Povray specifics "PovFoldComment": True, "PovFoldDirectives": False, # Properties specifics "PropertiesInitialSpaces": True, # Python specifics "PythonBadIndentation": QsciLexerPython.Inconsistent, "PythonFoldComment": True, "PythonFoldString": True, "PythonAutoIndent": True, "PythonAllowV2Unicode": True, "PythonAllowV3Binary": True, "PythonAllowV3Bytes": True, "PythonFoldQuotes": False, "PythonStringsOverNewLineAllowed": False, "PythonHighlightSubidentifier": True, # Ruby specifics "RubyFoldComment": False, # SQL specifics "SqlFoldComment": True, "SqlBackslashEscapes": False, "SqlDottedWords": False, "SqlFoldAtElse": False, "SqlFoldOnlyBegin": False, "SqlHashComments": False, "SqlQuotedIdentifiers": False, # TCL specifics "TclFoldComment": False, # TeX specifics "TexFoldComment": False, "TexProcessComments": False, "TexProcessIf": True, # VHDL specifics "VHDLFoldComment": True, "VHDLFoldAtElse": True, "VHDLFoldAtBegin": True, "VHDLFoldAtParenthesis": True, # XML specifics "XMLStyleScripts": True, # YAML specifics "YAMLFoldComment": False, } if isWindowsPlatform(): editorDefaults["EOLMode"] = QsciScintilla.EolWindows else: editorDefaults["EOLMode"] = QsciScintilla.EolUnix try: # since QScintilla 2.7.0 editorDefaults["CallTipsPosition"] = QsciScintilla.CallTipsBelowText except AttributeError: editorDefaults["CallTipsPosition"] = 0 editorColourDefaults = { "CurrentMarker": QColor(Qt.yellow), "ErrorMarker": QColor(Qt.red), "MatchingBrace": QColor(Qt.green), "MatchingBraceBack": QColor(Qt.white), "NonmatchingBrace": QColor(Qt.red), "NonmatchingBraceBack": QColor(Qt.white), "CallTipsBackground": QColor(Qt.white), "CaretForeground": QColor(Qt.black), "CaretLineBackground": QColor(Qt.white), "Edge": QColor(Qt.lightGray), "SelectionBackground": QColor(Qt.black), "SelectionForeground": QColor(Qt.white), "SearchMarkers": QColor(Qt.blue), "MarginsBackground": QColor(Qt.lightGray), "MarginsForeground": QColor(Qt.black), "FoldmarginBackground": QColor("#e6e6e6"), "FoldMarkersForeground": QColor(Qt.white), "FoldMarkersBackground": QColor(Qt.black), "SpellingMarkers": QColor(Qt.red), "AnnotationsWarningForeground": QColor("#606000"), "AnnotationsWarningBackground": QColor("#ffffd0"), "AnnotationsErrorForeground": QColor("#600000"), "AnnotationsErrorBackground": QColor("#ffd0d0"), "AnnotationsStyleForeground": QColor("#000060"), "AnnotationsStyleBackground": QColor("#d0d0ff"), "WhitespaceForeground": QColor(Qt.darkGray), "WhitespaceBackground": QColor(Qt.white), "OnlineChangeTraceMarkerUnsaved": QColor("#ff8888"), "OnlineChangeTraceMarkerSaved": QColor("#88ff88"), # colors for the marker map "BookmarksMap": QColor("#f8c700"), "ErrorsMap": QColor("#dd0000"), "WarningsMap": QColor("#606000"), "BreakpointsMap": QColor("#f55c07"), "TasksMap": QColor("#2278f8"), "CoverageMap": QColor("#ad3636"), "ChangesMap": QColor("#00b000"), "CurrentMap": QColor("#000000"), "MarkerMapBackground": QColor("#e7e7e7"), } editorOtherFontsDefaults = { "MarginsFont": "Sans Serif,10,-1,5,50,0,0,0,0,0", "DefaultFont": "Sans Serif,10,-1,5,50,0,0,0,0,0", "MonospacedFont": "Courier,10,-1,5,50,0,0,0,0,0", } editorTypingDefaults = { "Python/EnabledTypingAids": True, "Python/InsertClosingBrace": True, "Python/IndentBrace": False, "Python/SkipBrace": True, "Python/InsertQuote": True, "Python/DedentElse": True, "Python/DedentExcept": True, "Python/Py24StyleTry": True, "Python/InsertImport": True, "Python/InsertSelf": True, "Python/InsertBlank": True, "Python/ColonDetection": True, "Python/DedentDef": False, "Ruby/EnabledTypingAids": True, "Ruby/InsertClosingBrace": True, "Ruby/IndentBrace": True, "Ruby/SkipBrace": True, "Ruby/InsertQuote": True, "Ruby/InsertBlank": True, "Ruby/InsertHereDoc": True, "Ruby/InsertInlineDoc": True, } editorExporterDefaults = { "HTML/WYSIWYG": True, "HTML/Folding": False, "HTML/OnlyStylesUsed": False, "HTML/FullPathAsTitle": False, "HTML/UseTabs": False, "RTF/WYSIWYG": True, "RTF/UseTabs": False, "RTF/Font": "Courier New,10,-1,5,50,0,0,0,0,0", "PDF/Magnification": 0, "PDF/Font": "Helvetica", # must be Courier, Helvetica or Times "PDF/PageSize": "A4", # must be A4 or Letter "PDF/MarginLeft": 36, "PDF/MarginRight": 36, "PDF/MarginTop": 36, "PDF/MarginBottom": 36, "TeX/OnlyStylesUsed": False, "TeX/FullPathAsTitle": False, "ODT/WYSIWYG": True, "ODT/OnlyStylesUsed": False, "ODT/UseTabs": False, } # defaults for the printer settings printerDefaults = { "PrinterName": "", "ColorMode": True, "FirstPageFirst": True, "Magnification": -3, "Orientation": 0, "PageSize": 0, "HeaderFont": "Serif,10,-1,5,50,0,0,0,0,0", "LeftMargin": 1.0, "RightMargin": 1.0, "TopMargin": 1.0, "BottomMargin": 1.0, } # defaults for the project settings projectDefaults = { "SearchNewFiles": False, "SearchNewFilesRecursively": False, "AutoIncludeNewFiles": False, "AutoLoadSession": False, "AutoSaveSession": False, "SessionAllBreakpoints": False, "XMLTimestamp": True, "AutoCompileForms": False, "AutoCompileResources": False, "AutoLoadDbgProperties": False, "AutoSaveDbgProperties": False, "HideGeneratedForms": False, "FollowEditor": True, "FollowCursorLine": True, "AutoPopulateItems": True, "RecentNumber": 9, "DeterminePyFromProject": True, } # defaults for the multi project settings multiProjectDefaults = { "OpenMasterAutomatically": True, "XMLTimestamp": True, "RecentNumber": 9, "Workspace": "", } # defaults for the project browser flags settings projectBrowserFlagsDefaults = { "Qt4": ( SourcesBrowserFlag | FormsBrowserFlag | ResourcesBrowserFlag | TranslationsBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "Qt4C": ( SourcesBrowserFlag | ResourcesBrowserFlag | TranslationsBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "PyQt5": ( SourcesBrowserFlag | FormsBrowserFlag | ResourcesBrowserFlag | TranslationsBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "PyQt5C": ( SourcesBrowserFlag | ResourcesBrowserFlag | TranslationsBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "E4Plugin": ( SourcesBrowserFlag | FormsBrowserFlag | ResourcesBrowserFlag | TranslationsBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "E6Plugin": ( SourcesBrowserFlag | FormsBrowserFlag | ResourcesBrowserFlag | TranslationsBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "Console": ( SourcesBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "Other": ( SourcesBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "PySide": ( SourcesBrowserFlag | FormsBrowserFlag | ResourcesBrowserFlag | TranslationsBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), "PySideC": ( SourcesBrowserFlag | ResourcesBrowserFlag | TranslationsBrowserFlag | InterfacesBrowserFlag | OthersBrowserFlag), } # defaults for the project browser colour settings projectBrowserColourDefaults = { "Highlighted": QColor(Qt.red), "VcsAdded": QColor(Qt.blue), "VcsConflict": QColor(Qt.red), "VcsModified": QColor(Qt.yellow), "VcsReplaced": QColor(Qt.cyan), "VcsUpdate": QColor(Qt.green), "VcsRemoved": QColor(Qt.magenta) } # defaults for the help settings helpDefaults = { "HelpViewerType": 1, # this corresponds with the radio button id "CustomViewer": "", "PythonDocDir": "", "Python2DocDir": "", "QtDocDir": "", "Qt4DocDir": "", "Qt5DocDir": "", "PyQt4DocDir": "", "PyQt5DocDir": "", "PySideDocDir": "", "SingleHelpWindow": True, "SaveGeometry": True, "HelpViewerState": QByteArray(), "WebSearchSuggestions": True, "WebSearchEngine": "Google", "WebSearchKeywords": [], # array of two tuples (keyword, # search engine name) "DiskCacheEnabled": True, "DiskCacheSize": 50, # 50 MB "CachePolicy": QNetworkRequest.PreferNetwork, "AcceptCookies": 2, # CookieJar.AcceptOnlyFromSitesNavigatedTo "KeepCookiesUntil": 0, # CookieJar.KeepUntilExpire "FilterTrackingCookies": True, "PrintBackgrounds": False, "StartupBehavior": 1, # show speed dial "HomePage": "eric:home", "HistoryLimit": 30, "DefaultScheme": "file://", "AdBlockEnabled": False, "AdBlockSubscriptions": [], "AdBlockUpdatePeriod": 1, "AdBlockExceptions": [], "OfflineStorageDatabaseQuota": 50, # 50 MB "UserAgent": "", "ShowPreview": True, "DownloadManagerRemovePolicy": 0, # never delete downloads "DownloadManagerSize": QSize(400, 300), "DownloadManagerPosition": QPoint(), "DownloadManagerDownloads": [], "AccessKeysEnabled": True, "VirusTotalEnabled": False, "VirusTotalServiceKey": "", "VirusTotalSecure": False, "SearchLanguage": QLocale().language(), "DoNotTrack": False, "SendReferer": True, "SendRefererWhitelist": ["qt-apps.org", "kde-apps.org"], "NoCacheHosts": ["qt-project.org"], "RssFeeds": [], "SyncEnabled": False, "SyncBookmarks": True, "SyncHistory": True, "SyncPasswords": False, "SyncUserAgents": True, "SyncSpeedDial": True, "SyncEncryptData": False, "SyncEncryptionKey": "", "SyncEncryptionKeyLength": 32, # 16, 24 or 32 "SyncEncryptPasswordsOnly": False, "SyncType": 0, "SyncFtpServer": "", "SyncFtpUser": "", "SyncFtpPassword": "", "SyncFtpPath": "", "SyncFtpPort": 21, "SyncFtpIdleTimeout": 30, "SyncDirectoryPath": "", "WarnOnMultipleClose": True, "ClickToFlashEnabled": False, "ClickToFlashWhitelist": [], "PimFullName": "", "PimFirstName": "", "PimLastName": "", "PimEmail": "", "PimPhone": "", "PimMobile": "", "PimAddress": "", "PimCity": "", "PimZip": "", "PimState": "", "PimCountry": "", "PimHomePage": "", "PimSpecial1": "", "PimSpecial2": "", "PimSpecial3": "", "PimSpecial4": "", "GreaseMonkeyDisabledScripts": [], } @classmethod def initWebSettingsDefaults(cls): """ Class method to initialize the web settings related defaults. """ websettings = QWebSettings.globalSettings() fontFamily = websettings.fontFamily(QWebSettings.StandardFont) fontSize = websettings.fontSize(QWebSettings.DefaultFontSize) cls.helpDefaults["StandardFont"] = \ QFont(fontFamily, fontSize).toString() fontFamily = websettings.fontFamily(QWebSettings.FixedFont) fontSize = websettings.fontSize(QWebSettings.DefaultFixedFontSize) cls.helpDefaults["FixedFont"] = QFont(fontFamily, fontSize).toString() cls.helpDefaults.update({ "AutoLoadImages": websettings.testAttribute(QWebSettings.AutoLoadImages), "UserStyleSheet": "", "SaveUrlColor": QColor(248, 248, 210), "JavaEnabled": websettings.testAttribute(QWebSettings.JavaEnabled), "JavaScriptEnabled": websettings.testAttribute(QWebSettings.JavascriptEnabled), "JavaScriptCanOpenWindows": websettings.testAttribute( QWebSettings.JavascriptCanOpenWindows), "JavaScriptCanAccessClipboard": websettings.testAttribute( QWebSettings.JavascriptCanAccessClipboard), "PluginsEnabled": websettings.testAttribute(QWebSettings.PluginsEnabled), "OfflineStorageDatabaseEnabled": websettings.testAttribute( QWebSettings.OfflineStorageDatabaseEnabled), }) if hasattr(QWebSettings, "OfflineWebApplicationCacheEnabled"): cls.helpDefaults.update({ "OfflineWebApplicationCacheEnabled": websettings.testAttribute( QWebSettings.OfflineWebApplicationCacheEnabled), "OfflineWebApplicationCacheQuota": 50, # 50 MB }) if hasattr(QWebSettings, "LocalStorageEnabled"): cls.helpDefaults["LocalStorageEnabled"] = \ websettings.testAttribute(QWebSettings.LocalStorageEnabled) if hasattr(QWebSettings, "DnsPrefetchEnabled"): cls.helpDefaults["DnsPrefetchEnabled"] = \ websettings.testAttribute(QWebSettings.DnsPrefetchEnabled) if hasattr(QWebSettings, "defaultTextEncoding"): cls.helpDefaults["DefaultTextEncoding"] = \ websettings.defaultTextEncoding() if hasattr(QWebSettings, "SpatialNavigationEnabled"): cls.helpDefaults["SpatialNavigationEnabled"] = \ websettings.testAttribute( QWebSettings.SpatialNavigationEnabled) if hasattr(QWebSettings, "LinksIncludedInFocusChain"): cls.helpDefaults["LinksIncludedInFocusChain"] = \ websettings.testAttribute( QWebSettings.LinksIncludedInFocusChain) if hasattr(QWebSettings, "LocalContentCanAccessRemoteUrls"): cls.helpDefaults["LocalContentCanAccessRemoteUrls"] = \ websettings.testAttribute( QWebSettings.LocalContentCanAccessRemoteUrls) if hasattr(QWebSettings, "LocalContentCanAccessFileUrls"): cls.helpDefaults["LocalContentCanAccessFileUrls"] = \ websettings.testAttribute( QWebSettings.LocalContentCanAccessFileUrls) if hasattr(QWebSettings, "XSSAuditingEnabled"): cls.helpDefaults["XSSAuditingEnabled"] = \ websettings.testAttribute(QWebSettings.XSSAuditingEnabled) if hasattr(QWebSettings, "SiteSpecificQuirksEnabled"): cls.helpDefaults["SiteSpecificQuirksEnabled"] = \ websettings.testAttribute( QWebSettings.SiteSpecificQuirksEnabled) cls.webSettingsIntitialized = True webSettingsIntitialized = False # defaults for system settings sysDefaults = { "StringEncoding": "utf-8", "IOEncoding": "utf-8", } # defaults for the shell settings shellDefaults = { "LinenoMargin": True, "AutoCompletionEnabled": True, "CallTipsEnabled": True, "WrapEnabled": True, "MaxHistoryEntries": 100, "SyntaxHighlightingEnabled": True, "ShowStdOutErr": True, "UseMonospacedFont": False, "MonospacedFont": "Courier,10,-1,5,50,0,0,0,0,0", "MarginsFont": "Sans Serif,10,-1,5,50,0,0,0,0,0", } # defaults for Qt related stuff qtDefaults = { "Qt4TranslationsDir": "", "QtToolsPrefix4": "", "QtToolsPostfix4": "", "PyuicIndent": 4, "PyuicFromImports": False, } # defaults for corba related stuff corbaDefaults = { "omniidl": "omniidl" } # defaults for user related stuff userDefaults = { "Email": "", "MailServer": "", "Signature": "", "MailServerAuthentication": False, "MailServerUser": "", "MailServerPassword": "", "MailServerUseTLS": False, "MailServerPort": 25, "UseSystemEmailClient": False, "MasterPassword": "", # stores the password hash "UseMasterPassword": False, "SavePasswords": False, } # defaults for vcs related stuff vcsDefaults = { "AutoClose": False, "AutoSaveFiles": True, "AutoSaveProject": True, "AutoUpdate": False, "StatusMonitorInterval": 30, "MonitorLocalStatus": False, } # defaults for tasks related stuff tasksDefaults = { "TasksFixmeMarkers": "FIX" + "ME:", "TasksWarningMarkers": "WARN" + "ING:", "TasksTodoMarkers": "TO" + "DO:", "TasksNoteMarkers": "NO" + "TE:", # needed to keep it from being recognized as a task "TasksFixmeColor": QColor("#FFA0A0"), "TasksWarningColor": QColor("#FFFFA0"), "TasksTodoColor": QColor("#A0FFA0"), "TasksNoteColor": QColor("#A0A0FF"), "ClearOnFileClose": True, "TasksProjectAutoSave": True, } # defaults for templates related stuff templatesDefaults = { "AutoOpenGroups": True, "SingleDialog": False, "ShowTooltip": False, "SeparatorChar": "$", "EditorFont": "Monospace,9,-1,5,50,0,0,0,0,0", } # defaults for plugin manager related stuff pluginManagerDefaults = { "ActivateExternal": True, "DownloadPath": "", "UpdatesCheckInterval": 3, # 0 = off # 1 = daily # 2 = weekly # 3 = monthly "CheckInstalledOnly": True, # list of plug-ins not to shown in the repo dialog "HiddenPlugins": [], # parameters for housekeeping "KeepGenerations": 2, "KeepHidden": False, } # defaults for the printer settings graphicsDefaults = { "Font": "SansSerif,10,-1,5,50,0,0,0,0,0" } # defaults for the icon editor iconEditorDefaults = { "IconEditorState": QByteArray(), } # defaults for pyflakes pyflakesDefaults = { "IncludeInSyntaxCheck": True, "IgnoreStarImportWarnings": True, } # defaults for tray starter trayStarterDefaults = { "TrayStarterIcon": "erict.png", # valid values are: erict.png, erict-hc.png, # erict-bw.png, erict-bwi.png } # defaults for geometry geometryDefaults = { "HelpViewerGeometry": QByteArray(), "IconEditorGeometry": QByteArray(), "MainGeometry": QByteArray(), "MainMaximized": False, } # if true, revert layouts to factory defaults resetLayout = False # defaults for IRC ircDefaults = { "ShowTimestamps": True, "TimestampIncludeDate": False, "TimeFormat": "hh:mm", "DateFormat": "yyyy-MM-dd", "NetworkMessageColour": "#000055", "ServerMessageColour": "#91640A", "ErrorMessageColour": "#FF0000", "TimestampColour": "#709070", "HyperlinkColour": "#0000FF", "ChannelMessageColour": "#000000", "OwnNickColour": "#000000", "NickColour": "#18B33C", "JoinChannelColour": "#72D672", "LeaveChannelColour": "#B00000", "ChannelInfoColour": "#9E54B3", "EnableIrcColours": True, "IrcColor0": "#FFFF00", "IrcColor1": "#000000", "IrcColor2": "#000080", "IrcColor3": "#008000", "IrcColor4": "#FF0000", "IrcColor5": "#A52A2A", "IrcColor6": "#800080", "IrcColor7": "#FF8000", "IrcColor8": "#808000", "IrcColor9": "#00FF00", "IrcColor10": "#008080", "IrcColor11": "#00FFFF", "IrcColor12": "#0000FF", "IrcColor13": "#FFC0CB", "IrcColor14": "#A0A0A0", "IrcColor15": "#C0C0C0", "ShowNotifications": True, "NotifyJoinPart": True, "NotifyMessage": False, "NotifyNick": False, "AutoUserInfoLookup": True, "AutoUserInfoMax": 200, "AutoUserInfoInterval": 90, "MarkPositionWhenHidden": True, "MarkerLineForegroundColour": "#000000", # Black on "MarkerLineBackgroundColour": "#ffff00", # Yellow "AskOnShutdown": True, } def readToolGroups(prefClass=Prefs): """ Module function to read the tool groups configuration. @param prefClass preferences class used as the storage area @return list of tuples defing the tool groups """ toolGroups = [] groups = int(prefClass.settings.value("Toolgroups/Groups", 0)) for groupIndex in range(groups): groupName = prefClass.settings.value( "Toolgroups/{0:02d}/Name".format(groupIndex)) group = [groupName, []] items = int(prefClass.settings.value( "Toolgroups/{0:02d}/Items".format(groupIndex), 0)) for ind in range(items): menutext = prefClass.settings.value( "Toolgroups/{0:02d}/{1:02d}/Menutext".format(groupIndex, ind)) icon = prefClass.settings.value( "Toolgroups/{0:02d}/{1:02d}/Icon".format(groupIndex, ind)) executable = prefClass.settings.value( "Toolgroups/{0:02d}/{1:02d}/Executable".format( groupIndex, ind)) arguments = prefClass.settings.value( "Toolgroups/{0:02d}/{1:02d}/Arguments".format(groupIndex, ind)) redirect = prefClass.settings.value( "Toolgroups/{0:02d}/{1:02d}/Redirect".format(groupIndex, ind)) if menutext: if menutext == '--': tool = { 'menutext': '--', 'icon': '', 'executable': '', 'arguments': '', 'redirect': 'no', } group[1].append(tool) elif executable: tool = { 'menutext': menutext, 'icon': icon, 'executable': executable, 'arguments': arguments, 'redirect': redirect, } group[1].append(tool) toolGroups.append(group) currentGroup = int( prefClass.settings.value("Toolgroups/Current Group", -1)) return toolGroups, currentGroup def saveToolGroups(toolGroups, currentGroup, prefClass=Prefs): """ Module function to write the tool groups configuration. @param toolGroups reference to the list of tool groups @param currentGroup index of the currently selected tool group (integer) @param prefClass preferences class used as the storage area """ # first step, remove all tool group entries prefClass.settings.remove("Toolgroups") # second step, write the tool group entries prefClass.settings.setValue("Toolgroups/Groups", len(toolGroups)) groupIndex = 0 for group in toolGroups: prefClass.settings.setValue( "Toolgroups/{0:02d}/Name".format(groupIndex), group[0]) prefClass.settings.setValue( "Toolgroups/{0:02d}/Items".format(groupIndex), len(group[1])) ind = 0 for tool in group[1]: prefClass.settings.setValue( "Toolgroups/{0:02d}/{1:02d}/Menutext".format(groupIndex, ind), tool['menutext']) prefClass.settings.setValue( "Toolgroups/{0:02d}/{1:02d}/Icon".format(groupIndex, ind), tool['icon']) prefClass.settings.setValue( "Toolgroups/{0:02d}/{1:02d}/Executable".format( groupIndex, ind), tool['executable']) prefClass.settings.setValue( "Toolgroups/{0:02d}/{1:02d}/Arguments".format(groupIndex, ind), tool['arguments']) prefClass.settings.setValue( "Toolgroups/{0:02d}/{1:02d}/Redirect".format(groupIndex, ind), tool['redirect']) ind += 1 groupIndex += 1 prefClass.settings.setValue("Toolgroups/Current Group", currentGroup) def initPreferences(): """ Module function to initialize the central configuration store. """ Prefs.settings = QSettings( QSettings.IniFormat, QSettings.UserScope, settingsNameOrganization, settingsNameGlobal) if not isWindowsPlatform(): hp = QDir.homePath() dn = QDir(hp) dn.mkdir(".eric6") QCoreApplication.setOrganizationName(settingsNameOrganization) QCoreApplication.setApplicationName(settingsNameGlobal) # Avoid nasty behavior of QSettings in combination with Py2 Prefs.settings.value("UI/SingleApplicationMode") def syncPreferences(prefClass=Prefs): """ Module function to sync the preferences to disk. In addition to syncing, the central configuration store is reinitialized as well. @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("General/Configured", True) prefClass.settings.sync() def exportPreferences(prefClass=Prefs): """ Module function to export the current preferences. @param prefClass preferences class used as the storage area """ filename, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( None, QCoreApplication.translate("Preferences", "Export Preferences"), "", QCoreApplication.translate( "Preferences", "Properties File (*.ini);;All Files (*)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if filename: ext = QFileInfo(filename).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: filename += ex settingsFile = prefClass.settings.fileName() prefClass.settings = None shutil.copy(settingsFile, filename) initPreferences() def importPreferences(prefClass=Prefs): """ Module function to import preferences from a file previously saved by the export function. @param prefClass preferences class used as the storage area """ filename = E5FileDialog.getOpenFileName( None, QCoreApplication.translate("Preferences", "Import Preferences"), "", QCoreApplication.translate( "Preferences", "Properties File (*.ini);;All Files (*)")) if filename: settingsFile = prefClass.settings.fileName() shutil.copy(filename, settingsFile) initPreferences() def isConfigured(prefClass=Prefs): """ Module function to check, if the the application has been configured. @param prefClass preferences class used as the storage area @return flag indicating the configured status (boolean) """ return toBool(prefClass.settings.value("General/Configured", False)) def initRecentSettings(): """ Module function to initialize the central configuration store for recently opened files and projects. This function is called once upon import of the module. """ Prefs.rsettings = QSettings( QSettings.IniFormat, QSettings.UserScope, settingsNameOrganization, settingsNameRecent) def getVarFilters(prefClass=Prefs): """ Module function to retrieve the variables filter settings. @param prefClass preferences class used as the storage area @return a tuple defining the variables filter """ localsFilter = eval(prefClass.settings.value( "Variables/LocalsFilter", prefClass.varDefaults["LocalsFilter"])) globalsFilter = eval(prefClass.settings.value( "Variables/GlobalsFilter", prefClass.varDefaults["GlobalsFilter"])) return (localsFilter, globalsFilter) def setVarFilters(filters, prefClass=Prefs): """ Module function to store the variables filter settings. @param filters variable filters to set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Variables/LocalsFilter", str(filters[0])) prefClass.settings.setValue("Variables/GlobalsFilter", str(filters[1])) def getDebugger(key, prefClass=Prefs): """ Module function to retrieve the debugger settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested debugger setting """ if key in ["RemoteDbgEnabled", "PassiveDbgEnabled", "AutomaticReset", "DebugEnvironmentReplace", "PythonRedirect", "PythonNoEncoding", "Python3Redirect", "Python3NoEncoding", "RubyRedirect", "ConsoleDbgEnabled", "PathTranslation", "Autosave", "ThreeStateBreakPoints", "SuppressClientExit", "BreakAlways", "AutoViewSourceCode", "ShowExceptionInShell", ]: return toBool(prefClass.settings.value( "Debugger/" + key, prefClass.debuggerDefaults[key])) elif key in ["PassiveDbgPort"]: return int( prefClass.settings.value( "Debugger/" + key, prefClass.debuggerDefaults[key])) elif key in ["AllowedHosts"]: return toList( prefClass.settings.value( "Debugger/" + key, prefClass.debuggerDefaults[key])) elif key in ["PythonInterpreter", "Python3Interpreter"]: interpreter = \ prefClass.settings.value( "Debugger/" + key, prefClass.debuggerDefaults[key]) if not interpreter: pyVersion = 2 if key == "PythonInterpreter" else 3 if sys.version_info[0] == pyVersion: return sys.executable interpreters = findPythonInterpreters(pyVersion) if interpreters: if len(interpreters) == 1: interpreter = interpreters[0] else: selection, ok = QInputDialog.getItem( None, QCoreApplication.translate( "Preferences", "Select Python{0} Interpreter").format(pyVersion), QCoreApplication.translate( "Preferences", "Select the Python{0} interpreter to be used:") .format(pyVersion), interpreters, 0, False) if ok and selection != "": interpreter = selection if interpreter: setDebugger(key, interpreter) return interpreter else: return prefClass.settings.value( "Debugger/" + key, prefClass.debuggerDefaults[key]) def setDebugger(key, value, prefClass=Prefs): """ Module function to store the debugger settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Debugger/" + key, value) def getPython(key, prefClass=Prefs): """ Module function to retrieve the Python settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested debugger setting """ if key in ["PythonExtensions", "Python3Extensions"]: exts = [] for ext in getDebugger(key, prefClass).split(): if ext.startswith("."): exts.append(ext) else: exts.append(".{0}".format(ext)) return exts def setPython(key, value, prefClass=Prefs): """ Module function to store the Python settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key in ["PythonExtensions", "Python3Extensions"]: setDebugger(key, value, prefClass) def getUILanguage(prefClass=Prefs): """ Module function to retrieve the language for the user interface. @param prefClass preferences class used as the storage area @return the language for the UI """ lang = prefClass.settings.value("UI/Language", prefClass.uiDefaults["Language"]) if lang == "None" or lang == "" or lang is None: return None else: return lang def setUILanguage(lang, prefClass=Prefs): """ Module function to store the language for the user interface. @param lang the language @param prefClass preferences class used as the storage area """ if lang is None: prefClass.settings.setValue("UI/Language", "None") else: prefClass.settings.setValue("UI/Language", lang) def getUILayout(prefClass=Prefs): """ Module function to retrieve the layout for the user interface. @param prefClass preferences class used as the storage area @return the UI layout as a tuple of main layout, flag for an embedded shell and a value for an embedded file browser """ layoutType = prefClass.settings.value( "UI/LayoutType", prefClass.uiDefaults["LayoutType"]) if layoutType in ["DockWindows", "FloatingWindows"]: # change old fashioned layouts to the modern default layoutType = prefClass.uiDefaults["LayoutType"] layout = (layoutType, int(prefClass.settings.value("UI/LayoutShellEmbedded", prefClass.uiDefaults["LayoutShellEmbedded"])), int(prefClass.settings.value("UI/LayoutFileBrowserEmbedded", prefClass.uiDefaults["LayoutFileBrowserEmbedded"])), ) return layout def setUILayout(layout, prefClass=Prefs): """ Module function to store the layout for the user interface. @param layout the layout type @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("UI/LayoutType", layout[0]) prefClass.settings.setValue("UI/LayoutShellEmbedded", layout[1]) prefClass.settings.setValue("UI/LayoutFileBrowserEmbedded", layout[2]) def getViewManager(prefClass=Prefs): """ Module function to retrieve the selected viewmanager type. @param prefClass preferences class used as the storage area @return the viewmanager type """ return prefClass.settings.value( "UI/ViewManager", prefClass.uiDefaults["ViewManager"]) def setViewManager(vm, prefClass=Prefs): """ Module function to store the selected viewmanager type. @param vm the viewmanager type @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("UI/ViewManager", vm) def getUI(key, prefClass=Prefs): """ Module function to retrieve the various UI settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested UI setting """ if key in ["BrowsersListFoldersFirst", "BrowsersHideNonPublic", "BrowsersListContentsByOccurrence", "BrowsersListHiddenFiles", "LogViewerAutoRaise", "SingleApplicationMode", "TabViewManagerFilenameOnly", "ShowFilePreview", "ShowFilePreviewJS", "ShowFilePreviewSSI", "CaptionShowsFilename", "ShowSplash", "SingleCloseButton", "SplitOrientationVertical", "UseProxy", "UseSystemProxy", "UseHttpProxyForAll", "TopLeftByLeft", "BottomLeftByLeft", "TopRightByRight", "BottomRightByRight", "RequestDownloadFilename", "LayoutShellEmbedded", "LayoutFileBrowserEmbedded", "CheckErrorLog", "NotificationsEnabled"]: return toBool(prefClass.settings.value( "UI/" + key, prefClass.uiDefaults[key])) elif key in ["TabViewManagerFilenameLength", "CaptionFilenameLength", "ProxyPort/Http", "ProxyPort/Https", "ProxyPort/Ftp", "ProxyType/Ftp", "OpenOnStartup", "PerformVersionCheck", "RecentNumber", "NotificationTimeout", "SidebarDelay"]: return int(prefClass.settings.value( "UI/" + key, prefClass.uiDefaults[key])) elif key in ["ProxyPassword/Http", "ProxyPassword/Https", "ProxyPassword/Ftp", ]: from Utilities.crypto import pwConvert return pwConvert( prefClass.settings.value("UI/" + key, prefClass.uiDefaults[key]), encode=False) elif key in ["LogStdErrColour"]: col = prefClass.settings.value("UI/" + key) if col is not None: return QColor(col) else: return prefClass.uiDefaults[key] elif key in "ViewProfiles2": profiles = prefClass.settings.value("UI/ViewProfiles2") if profiles is not None: viewProfiles = {} profiles = json.loads(profiles) for name in ["edit", "debug"]: viewProfiles[name] = [ QByteArray.fromBase64(profiles[name][0].encode("utf-8")), profiles[name][1][:], [] ] for bs in profiles[name][2]: viewProfiles[name][2].append( QByteArray.fromBase64(bs.encode("utf-8"))) else: # migrate from the old ViewProfiles settings try: profiles = prefClass.settings.value("UI/ViewProfiles") except TypeError: profiles = None if profiles is not None: if isinstance(profiles, basestring): profiles = eval(profiles) viewProfiles = {} for name in ["edit", "debug"]: viewProfiles[name] = [ QByteArray(profiles[name][4]), profiles[name][5][:], [] ] for b in profiles[name][6]: viewProfiles[name][2].append(QByteArray(b)) # correct some entries while (len(viewProfiles[name][1]) < len( prefClass.uiDefaults["ViewProfiles2"][name][1])): viewProfiles[name][1].append(True) while len(viewProfiles[name][2]) < len( prefClass.uiDefaults["ViewProfiles2"][name][2]): viewProfiles[name][2].append(QByteArray()) else: # use the defaults viewProfiles = prefClass.uiDefaults["ViewProfiles2"] # Remove unused setting prefClass.settings.remove("UI/ViewProfiles") return viewProfiles elif key in ["ToolbarManagerState", "PreviewSplitterState"]: state = prefClass.settings.value("UI/" + key) if state is not None: return state else: return prefClass.uiDefaults[key] elif key in ["VersionsUrls6"]: urls = toList( prefClass.settings.value("UI/" + key, prefClass.uiDefaults[key])) if len(urls) == 0: return prefClass.uiDefaults[key] else: return urls else: return prefClass.settings.value("UI/" + key, prefClass.uiDefaults[key]) def setUI(key, value, prefClass=Prefs): """ Module function to store the various UI settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key == "ViewProfiles2": profiles = {} for name in ["edit", "debug"]: profiles[name] = [ bytes(value[name][0].toBase64()).decode(), value[name][1][:], [] ] for ba in value[name][2]: profiles[name][2].append(bytes(ba.toBase64()).decode()) prefClass.settings.setValue("UI/" + key, json.dumps(profiles)) elif key == "LogStdErrColour": prefClass.settings.setValue("UI/" + key, value.name()) elif key in ["ProxyPassword/Http", "ProxyPassword/Https", "ProxyPassword/Ftp", ]: from Utilities.crypto import pwConvert prefClass.settings.setValue("UI/" + key, pwConvert(value, encode=True)) else: prefClass.settings.setValue("UI/" + key, value) def getIcons(key, prefClass=Prefs): """ Module function to retrieve the various Icons settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested Icons setting """ dirlist = prefClass.settings.value("UI/Icons/" + key) if dirlist is not None: return dirlist else: return prefClass.iconsDefaults[key] def setIcons(key, value, prefClass=Prefs): """ Module function to store the various Icons settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("UI/Icons/" + key, value) def getCooperation(key, prefClass=Prefs): """ Module function to retrieve the various Cooperation settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested UI setting """ if key in ["AutoStartServer", "TryOtherPorts", "AutoAcceptConnections"]: return toBool(prefClass.settings.value( "Cooperation/" + key, prefClass.cooperationDefaults[key])) elif key in ["ServerPort", "MaxPortsToTry"]: return int(prefClass.settings.value( "Cooperation/" + key, prefClass.cooperationDefaults[key])) elif key in ["BannedUsers"]: return toList(prefClass.settings.value( "Cooperation/" + key, prefClass.cooperationDefaults[key])) else: return prefClass.settings.value( "Cooperation/" + key, prefClass.cooperationDefaults[key]) def setCooperation(key, value, prefClass=Prefs): """ Module function to store the various Cooperation settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Cooperation/" + key, value) def getEditor(key, prefClass=Prefs): """ Module function to retrieve the various editor settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested editor setting """ if key in ["DefaultEncoding", "DefaultOpenFilter", "DefaultSaveFilter", "SpellCheckingDefaultLanguage", "SpellCheckingPersonalWordList", "SpellCheckingPersonalExcludeList"]: return prefClass.settings.value( "Editor/" + key, prefClass.editorDefaults[key]) elif key in ["AutosaveInterval", "TabWidth", "IndentWidth", "FoldingStyle", "WarnFilesize", "EdgeMode", "EdgeColumn", "CaretWidth", "AutoCompletionSource", "AutoCompletionThreshold", "CallTipsVisible", "CallTipsStyle", "MarkOccurrencesTimeout", "AutoSpellCheckChunkSize", "SpellCheckingMinWordSize", "PostScriptLevel", "EOLMode", "ZoomFactor", "WhitespaceSize", "OnlineSyntaxCheckInterval", "OnlineChangeTraceInterval", "WrapLongLinesMode", "WrapVisualFlag", "CallTipsPosition", "VirtualSpaceOptions"]: return int(prefClass.settings.value( "Editor/" + key, prefClass.editorDefaults[key])) elif key in ["AdditionalOpenFilters", "AdditionalSaveFilters", "PreviewMarkdownFileNameExtensions", "PreviewRestFileNameExtensions", "PreviewHtmlFileNameExtensions", "PreviewQssFileNameExtensions"]: return toList(prefClass.settings.value( "Editor/" + key, prefClass.editorDefaults[key])) elif key in ["PythonBadIndentation"]: value = prefClass.settings.value( "Editor/" + key, prefClass.editorDefaults[key]) if value in ["true", "True"]: value = 1 elif value in ["false", "False"]: value = 0 return QsciLexerPython.IndentationWarning(int(value)) else: return toBool(prefClass.settings.value( "Editor/" + key, prefClass.editorDefaults[key])) def setEditor(key, value, prefClass=Prefs): """ Module function to store the various editor settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Editor/" + key, value) def getEditorColour(key, prefClass=Prefs): """ Module function to retrieve the various editor marker colours. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested editor colour """ col = prefClass.settings.value("Editor/Colour/" + key) if col is not None: if len(col) == 9: # color string with alpha return QColor.fromRgba(int(col[1:], 16)) else: return QColor(col) else: # palette based defaults here because of Qt5 if key == "EditAreaForeground": return QApplication.palette().color(QPalette.Active, QPalette.Base) elif key == "EditAreaBackground": return QApplication.palette().color(QPalette.Active, QPalette.Text) else: return prefClass.editorColourDefaults[key] def setEditorColour(key, value, prefClass=Prefs): """ Module function to store the various editor marker colours. @param key the key of the colour to be set @param value the colour to be set @param prefClass preferences class used as the storage area """ if value.alpha() < 255: val = "#{0:8x}".format(value.rgba()) else: val = value.name() prefClass.settings.setValue("Editor/Colour/" + key, val) def getEditorOtherFonts(key, prefClass=Prefs): """ Module function to retrieve the various editor fonts except the lexer fonts. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested editor font (QFont) """ f = QFont() f.fromString(prefClass.settings.value( "Editor/Other Fonts/" + key, prefClass.editorOtherFontsDefaults[key])) return f def setEditorOtherFonts(key, font, prefClass=Prefs): """ Module function to store the various editor fonts except the lexer fonts. @param key the key of the font to be set @param font the font to be set (QFont) @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Editor/Other Fonts/" + key, font.toString()) def getEditorAPI(key, prefClass=Prefs): """ Module function to retrieve the various lists of api files. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested list of api files (list of strings) """ apis = prefClass.settings.value("Editor/APIs/" + key) if apis is not None: if len(apis) and apis[0] == "": return [] else: return apis else: return [] def setEditorAPI(key, apilist, prefClass=Prefs): """ Module function to store the various lists of api files. @param key the key of the api to be set @param apilist the list of api files (list of strings) @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Editor/APIs/" + key, apilist) def getEditorKeywords(key, prefClass=Prefs): """ Module function to retrieve the various lists of language keywords. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested list of language keywords (list of strings) """ keywords = prefClass.settings.value("Editor/Keywords/" + key) if keywords is not None: return keywords else: return [] def setEditorKeywords(key, keywordsLists, prefClass=Prefs): """ Module function to store the various lists of language keywords. @param key the key of the api to be set @param keywordsLists the list of language keywords (list of strings) @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Editor/Keywords/" + key, keywordsLists) def getEditorLexerAssocs(prefClass=Prefs): """ Module function to retrieve all lexer associations. @param prefClass preferences class used as the storage area @return a reference to the list of lexer associations (dictionary of strings) """ editorLexerAssoc = {} prefClass.settings.beginGroup("Editor/LexerAssociations") keyList = prefClass.settings.childKeys() prefClass.settings.endGroup() import QScintilla.Lexers editorLexerAssocDefaults = QScintilla.Lexers.getDefaultLexerAssociations() if len(keyList) == 0: # build from scratch for key in list(editorLexerAssocDefaults.keys()): editorLexerAssoc[key] = editorLexerAssocDefaults[key] else: for key in keyList: if key in editorLexerAssocDefaults: defaultValue = editorLexerAssocDefaults[key] else: defaultValue = "" editorLexerAssoc[key] = prefClass.settings.value( "Editor/LexerAssociations/" + key, defaultValue) # check for new default lexer associations for key in list(editorLexerAssocDefaults.keys()): if key not in editorLexerAssoc: editorLexerAssoc[key] = editorLexerAssocDefaults[key] return editorLexerAssoc def setEditorLexerAssocs(assocs, prefClass=Prefs): """ Module function to retrieve all lexer associations. @param assocs dictionary of lexer associations to be set @param prefClass preferences class used as the storage area """ # first remove lexer associations that no longer exist, than save the rest prefClass.settings.beginGroup("Editor/LexerAssociations") keyList = prefClass.settings.childKeys() prefClass.settings.endGroup() for key in keyList: if key not in assocs: prefClass.settings.remove("Editor/LexerAssociations/" + key) for key in assocs: prefClass.settings.setValue( "Editor/LexerAssociations/" + key, assocs[key]) def getEditorLexerAssoc(filename, prefClass=Prefs): """ Module function to retrieve a lexer association. @param filename filename used to determine the associated lexer language (string) @param prefClass preferences class used as the storage area @return the requested lexer language (string) """ for pattern, language in list(getEditorLexerAssocs().items()): if fnmatch.fnmatch(filename, pattern): return language return "" def getEditorTyping(key, prefClass=Prefs): """ Module function to retrieve the various editor typing settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested editor setting """ return toBool(prefClass.settings.value( "Editor/Typing/" + key, prefClass.editorTypingDefaults[key])) def setEditorTyping(key, value, prefClass=Prefs): """ Module function to store the various editor typing settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Editor/Typing/" + key, value) def getEditorExporter(key, prefClass=Prefs): """ Module function to retrieve the various editor exporters settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested editor setting """ if key in ["RTF/Font"]: f = QFont() f.fromString(prefClass.settings.value( "Editor/Exporters/" + key, prefClass.editorExporterDefaults[key])) return f elif key in ["HTML/WYSIWYG", "HTML/Folding", "HTML/OnlyStylesUsed", "HTML/FullPathAsTitle", "HTML/UseTabs", "RTF/WYSIWYG", "RTF/UseTabs", "TeX/OnlyStylesUsed", "TeX/FullPathAsTitle", "ODT/WYSIWYG", "ODT/OnlyStylesUsed", "ODT/UseTabs"]: return toBool(prefClass.settings.value( "Editor/Exporters/" + key, prefClass.editorExporterDefaults[key])) elif key in ["PDF/Magnification", "PDF/MarginLeft", "PDF/MarginRight", "PDF/MarginTop", "PDF/MarginBottom"]: return int(prefClass.settings.value( "Editor/Exporters/" + key, prefClass.editorExporterDefaults[key])) else: return prefClass.settings.value( "Editor/Exporters/" + key, prefClass.editorExporterDefaults[key]) def setEditorExporter(key, value, prefClass=Prefs): """ Module function to store the various editor exporters settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key in ["RTF/Font"]: prefClass.settings.setValue( "Editor/Exporters/" + key, value.toString()) else: prefClass.settings.setValue("Editor/Exporters/" + key, value) def getPrinter(key, prefClass=Prefs): """ Module function to retrieve the various printer settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested printer setting """ if key in ["ColorMode", "FirstPageFirst"]: return toBool(prefClass.settings.value( "Printer/" + key, prefClass.printerDefaults[key])) elif key in ["Magnification", "Orientation", "PageSize"]: return int(prefClass.settings.value( "Printer/" + key, prefClass.printerDefaults[key])) elif key in ["LeftMargin", "RightMargin", "TopMargin", "BottomMargin"]: return float(prefClass.settings.value( "Printer/" + key, prefClass.printerDefaults[key])) elif key in ["HeaderFont"]: f = QFont() f.fromString(prefClass.settings.value( "Printer/" + key, prefClass.printerDefaults[key])) return f else: return prefClass.settings.value( "Printer/" + key, prefClass.printerDefaults[key]) def setPrinter(key, value, prefClass=Prefs): """ Module function to store the various printer settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key in ["HeaderFont"]: prefClass.settings.setValue("Printer/" + key, value.toString()) else: prefClass.settings.setValue("Printer/" + key, value) def getShell(key, prefClass=Prefs): """ Module function to retrieve the various shell settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested shell setting """ if key in ["MonospacedFont", "MarginsFont"]: f = QFont() f.fromString(prefClass.settings.value( "Shell/" + key, prefClass.shellDefaults[key])) return f elif key in ["MaxHistoryEntries"]: return int(prefClass.settings.value( "Shell/" + key, prefClass.shellDefaults[key])) else: return toBool(prefClass.settings.value( "Shell/" + key, prefClass.shellDefaults[key])) def setShell(key, value, prefClass=Prefs): """ Module function to store the various shell settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key in ["MonospacedFont", "MarginsFont"]: prefClass.settings.setValue("Shell/" + key, value.toString()) else: prefClass.settings.setValue("Shell/" + key, value) def getProject(key, prefClass=Prefs): """ Module function to retrieve the various project handling settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested project setting """ if key in ["RecentNumber"]: return int(prefClass.settings.value( "Project/" + key, prefClass.projectDefaults[key])) else: return toBool(prefClass.settings.value( "Project/" + key, prefClass.projectDefaults[key])) def setProject(key, value, prefClass=Prefs): """ Module function to store the various project handling settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Project/" + key, value) def getProjectBrowserFlags(key, prefClass=Prefs): """ Module function to retrieve the various project browser flags settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested project setting """ try: default = prefClass.projectBrowserFlagsDefaults[key] except KeyError: default = AllBrowsersFlag return int(prefClass.settings.value( "Project/BrowserFlags/" + key, default)) def setProjectBrowserFlags(key, value, prefClass=Prefs): """ Module function to store the various project browser flags settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Project/BrowserFlags/" + key, value) def setProjectBrowserFlagsDefault(key, value, prefClass=Prefs): """ Module function to store the various project browser flags settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.projectBrowserFlagsDefaults[key] = value def removeProjectBrowserFlags(key, prefClass=Prefs): """ Module function to remove a project browser flags setting. @param key the key of the setting to be removed @param prefClass preferences class used as the storage area """ prefClass.settings.remove("Project/BrowserFlags/" + key) def getProjectBrowserColour(key, prefClass=Prefs): """ Module function to retrieve the various project browser colours. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested project browser colour """ col = prefClass.settings.value("Project/Colour/" + key) if col is not None: return QColor(col) else: return prefClass.projectBrowserColourDefaults[key] def setProjectBrowserColour(key, value, prefClass=Prefs): """ Module function to store the various project browser colours. @param key the key of the colour to be set @param value the colour to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Project/Colour/" + key, value.name()) def getMultiProject(key, prefClass=Prefs): """ Module function to retrieve the various project handling settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested project setting """ if key in ["RecentNumber"]: return int(prefClass.settings.value( "MultiProject/" + key, prefClass.multiProjectDefaults[key])) elif key in ["OpenMasterAutomatically", "XMLTimestamp"]: return toBool(prefClass.settings.value( "MultiProject/" + key, prefClass.multiProjectDefaults[key])) else: return prefClass.settings.value( "MultiProject/" + key, prefClass.multiProjectDefaults[key]) def setMultiProject(key, value, prefClass=Prefs): """ Module function to store the various project handling settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("MultiProject/" + key, value) def getQt4DocDir(prefClass=Prefs): """ Module function to retrieve the Qt4DocDir setting. @param prefClass preferences class used as the storage area @return the requested Qt4DocDir setting (string) """ s = prefClass.settings.value( "Help/Qt4DocDir", prefClass.helpDefaults["Qt4DocDir"]) if s == "": s = os.getenv("QT4DOCDIR", "") if s == "": s = os.path.join( QLibraryInfo.location(QLibraryInfo.DocumentationPath), "html") return s def getQt5DocDir(prefClass=Prefs): """ Module function to retrieve the Qt5DocDir setting. @param prefClass preferences class used as the storage area @return the requested Qt4DocDir setting (string) """ s = prefClass.settings.value( "Help/Qt5DocDir", prefClass.helpDefaults["Qt5DocDir"]) if s == "": s = os.getenv("QT5DOCDIR", "") if s == "": s = os.path.join( QLibraryInfo.location(QLibraryInfo.DocumentationPath), "qtdoc") return s def getHelp(key, prefClass=Prefs): """ Module function to retrieve the various help settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested help setting """ if not prefClass.webSettingsIntitialized: prefClass.initWebSettingsDefaults() if key in ["StandardFont", "FixedFont"]: f = QFont() f.fromString(prefClass.settings.value( "Help/" + key, prefClass.helpDefaults[key])) return f elif key in ["SaveUrlColor"]: col = prefClass.settings.value("Help/" + key) if col is not None: return QColor(col) else: return prefClass.helpDefaults[key] elif key in ["WebSearchKeywords"]: # return a list of tuples of (keyword, engine name) keywords = [] size = prefClass.settings.beginReadArray("Help/" + key) for index in range(size): prefClass.settings.setArrayIndex(index) keyword = prefClass.settings.value("Keyword") engineName = prefClass.settings.value("Engine") keywords.append((keyword, engineName)) prefClass.settings.endArray() return keywords elif key in ["DownloadManagerDownloads"]: # return a list of tuples of (URL, save location, done flag, page url) downloads = [] length = prefClass.settings.beginReadArray("Help/" + key) for index in range(length): prefClass.settings.setArrayIndex(index) url = prefClass.settings.value("URL") location = prefClass.settings.value("Location") done = toBool(prefClass.settings.value("Done")) pageUrl = prefClass.settings.value("PageURL") if pageUrl is None: pageUrl = QUrl() downloads.append((url, location, done, pageUrl)) prefClass.settings.endArray() return downloads elif key == "RssFeeds": # return a list of tuples of (URL, title, icon) feeds = [] length = prefClass.settings.beginReadArray("Help/" + key) for index in range(length): prefClass.settings.setArrayIndex(index) url = prefClass.settings.value("URL") title = prefClass.settings.value("Title") icon = prefClass.settings.value("Icon") feeds.append((url, title, icon)) prefClass.settings.endArray() return feeds elif key in ["SyncFtpPassword", "SyncEncryptionKey"]: from Utilities.crypto import pwConvert return pwConvert(prefClass.settings.value( "Help/" + key, prefClass.helpDefaults[key]), encode=False) elif key in ["HelpViewerType", "DiskCacheSize", "AcceptCookies", "KeepCookiesUntil", "StartupBehavior", "HistoryLimit", "OfflineStorageDatabaseQuota", "OfflineWebApplicationCacheQuota", "CachePolicy", "DownloadManagerRemovePolicy", "AdBlockUpdatePeriod", "SearchLanguage", "SyncType", "SyncFtpPort", "SyncFtpIdleTimeout", "SyncEncryptionKeyLength"]: return int(prefClass.settings.value( "Help/" + key, prefClass.helpDefaults[key])) elif key in ["SingleHelpWindow", "SaveGeometry", "WebSearchSuggestions", "DiskCacheEnabled", "FilterTrackingCookies", "PrintBackgrounds", "AdBlockEnabled", "AutoLoadImages", "JavaEnabled", "JavaScriptEnabled", "JavaScriptCanOpenWindows", "JavaScriptCanAccessClipboard", "PluginsEnabled", "DnsPrefetchEnabled", "OfflineStorageDatabaseEnabled", "OfflineWebApplicationCacheEnabled", "LocalStorageEnabled", "ShowPreview", "AccessKeysEnabled", "VirusTotalEnabled", "VirusTotalSecure", "DoNotTrack", "SendReferer", "SpatialNavigationEnabled", "LinksIncludedInFocusChain", "LocalContentCanAccessRemoteUrls", "LocalContentCanAccessFileUrls", "XSSAuditingEnabled", "SiteSpecificQuirksEnabled", "SyncEnabled", "SyncBookmarks", "SyncHistory", "SyncPasswords", "SyncUserAgents", "SyncSpeedDial", "SyncEncryptData", "SyncEncryptPasswordsOnly", "WarnOnMultipleClose", "ClickToFlashEnabled" ]: return toBool(prefClass.settings.value( "Help/" + key, prefClass.helpDefaults[key])) elif key in ["AdBlockSubscriptions", "AdBlockExceptions", "ClickToFlashWhitelist", "SendRefererWhitelist", "GreaseMonkeyDisabledScripts", "NoCacheHosts"]: return toList(prefClass.settings.value( "Help/" + key, prefClass.helpDefaults[key])) else: return prefClass.settings.value("Help/" + key, prefClass.helpDefaults[key]) def setHelp(key, value, prefClass=Prefs): """ Module function to store the various help settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key in ["StandardFont", "FixedFont"]: prefClass.settings.setValue("Help/" + key, value.toString()) elif key == "SaveUrlColor": prefClass.settings.setValue("Help/" + key, value.name()) elif key == "WebSearchKeywords": # value is list of tuples of (keyword, engine name) prefClass.settings.remove("Help/" + key) prefClass.settings.beginWriteArray("Help/" + key, len(value)) index = 0 for v in value: prefClass.settings.setArrayIndex(index) prefClass.settings.setValue("Keyword", v[0]) prefClass.settings.setValue("Engine", v[1]) index += 1 prefClass.settings.endArray() elif key == "DownloadManagerDownloads": # value is list of tuples of (URL, save location, done flag, page url) prefClass.settings.remove("Help/" + key) prefClass.settings.beginWriteArray("Help/" + key, len(value)) index = 0 for v in value: prefClass.settings.setArrayIndex(index) prefClass.settings.setValue("URL", v[0]) prefClass.settings.setValue("Location", v[1]) prefClass.settings.setValue("Done", v[2]) prefClass.settings.setValue("PageURL", v[3]) index += 1 prefClass.settings.endArray() elif key == "RssFeeds": # value is list of tuples of (URL, title, icon) prefClass.settings.remove("Help/" + key) prefClass.settings.beginWriteArray("Help/" + key, len(value)) index = 0 for v in value: prefClass.settings.setArrayIndex(index) prefClass.settings.setValue("URL", v[0]) prefClass.settings.setValue("Title", v[1]) prefClass.settings.setValue("Icon", v[2]) index += 1 prefClass.settings.endArray() elif key in ["SyncFtpPassword", "SyncEncryptionKey"]: from Utilities.crypto import pwConvert prefClass.settings.setValue( "Help/" + key, pwConvert(value, encode=True)) else: prefClass.settings.setValue("Help/" + key, value) def getSystem(key, prefClass=Prefs): """ Module function to retrieve the various system settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested system setting """ from Utilities import supportedCodecs if key in ["StringEncoding", "IOEncoding"]: encoding = prefClass.settings.value( "System/" + key, prefClass.sysDefaults[key]) if encoding not in supportedCodecs: encoding = prefClass.sysDefaults[key] return encoding def setSystem(key, value, prefClass=Prefs): """ Module function to store the various system settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("System/" + key, value) def getQt4TranslationsDir(prefClass=Prefs): """ Module function to retrieve the Qt4TranslationsDir setting. @param prefClass preferences class used as the storage area @return the requested Qt4TranslationsDir setting (string) """ s = prefClass.settings.value( "Qt/Qt4TranslationsDir", prefClass.qtDefaults["Qt4TranslationsDir"]) if s == "": s = os.getenv("QT4TRANSLATIONSDIR", "") if s == "": s = QLibraryInfo.location(QLibraryInfo.TranslationsPath) if s == "" and isWindowsPlatform(): transPath = os.path.join(getPyQt5ModulesDirectory(), "translations") if os.path.exists(transPath): s = transPath return s def getQt(key, prefClass=Prefs): """ Module function to retrieve the various Qt settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested Qt setting """ if key == "Qt4TranslationsDir": return getQt4TranslationsDir(prefClass) elif key in ["PyuicIndent"]: return int(prefClass.settings.value( "Qt/" + key, prefClass.qtDefaults[key])) elif key in ["PyuicFromImports"]: return toBool(prefClass.settings.value( "Qt/" + key, prefClass.qtDefaults[key])) else: return prefClass.settings.value("Qt/" + key, prefClass.qtDefaults[key]) def setQt(key, value, prefClass=Prefs): """ Module function to store the various Qt settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Qt/" + key, value) def getCorba(key, prefClass=Prefs): """ Module function to retrieve the various corba settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested corba setting """ return prefClass.settings.value( "Corba/" + key, prefClass.corbaDefaults[key]) def setCorba(key, value, prefClass=Prefs): """ Module function to store the various corba settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Corba/" + key, value) def getUser(key, prefClass=Prefs): """ Module function to retrieve the various user settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ if key == "MailServerPassword": from Utilities.crypto import pwConvert return pwConvert(prefClass.settings.value( "User/" + key, prefClass.userDefaults[key]), encode=False) elif key in ["MailServerPort"]: return int(prefClass.settings.value( "User/" + key, prefClass.userDefaults[key])) elif key in ["MailServerAuthentication", "MailServerUseTLS", "UseSystemEmailClient", "UseMasterPassword", "SavePasswords"]: return toBool(prefClass.settings.value( "User/" + key, prefClass.userDefaults[key])) else: return prefClass.settings.value( "User/" + key, prefClass.userDefaults[key]) def setUser(key, value, prefClass=Prefs): """ Module function to store the various user settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key == "MailServerPassword": from Utilities.crypto import pwConvert prefClass.settings.setValue( "User/" + key, pwConvert(value, encode=True)) elif key == "MasterPassword": from Utilities.crypto.py3PBKDF2 import hashPassword prefClass.settings.setValue( "User/" + key, hashPassword(value)) else: prefClass.settings.setValue("User/" + key, value) def getVCS(key, prefClass=Prefs): """ Module function to retrieve the VCS related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ if key in ["StatusMonitorInterval"]: return int(prefClass.settings.value( "VCS/" + key, prefClass.vcsDefaults[key])) else: return toBool(prefClass.settings.value( "VCS/" + key, prefClass.vcsDefaults[key])) def setVCS(key, value, prefClass=Prefs): """ Module function to store the VCS related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("VCS/" + key, value) def getTasks(key, prefClass=Prefs): """ Module function to retrieve the Tasks related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ if key in ["TasksFixmeColor", "TasksWarningColor", "TasksTodoColor", "TasksNoteColor"]: col = prefClass.settings.value("Tasks/" + key) if col is not None: return QColor(col) else: return prefClass.tasksDefaults[key] elif key in ["ClearOnFileClose", "TasksProjectAutoSave"]: return toBool(prefClass.settings.value( "Tasks/" + key, prefClass.tasksDefaults[key])) else: return prefClass.settings.value( "Tasks/" + key, prefClass.tasksDefaults[key]) def setTasks(key, value, prefClass=Prefs): """ Module function to store the Tasks related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key in ["TasksFixmeColor", "TasksWarningColor", "TasksTodoColor", "TasksNoteColor"]: prefClass.settings.setValue("Tasks/" + key, value.name()) else: prefClass.settings.setValue("Tasks/" + key, value) def getTemplates(key, prefClass=Prefs): """ Module function to retrieve the Templates related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ if key in ["SeparatorChar"]: return prefClass.settings.value( "Templates/" + key, prefClass.templatesDefaults[key]) elif key in ["EditorFont"]: f = QFont() f.fromString(prefClass.settings.value( "Templates/" + key, prefClass.templatesDefaults[key])) return f else: return toBool(prefClass.settings.value( "Templates/" + key, prefClass.templatesDefaults[key])) def setTemplates(key, value, prefClass=Prefs): """ Module function to store the Templates related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key in ["EditorFont"]: prefClass.settings.setValue("Templates/" + key, value.toString()) else: prefClass.settings.setValue("Templates/" + key, value) def getPluginManager(key, prefClass=Prefs): """ Module function to retrieve the plugin manager related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ if key in ["DownloadPath"]: return prefClass.settings.value( "PluginManager/" + key, prefClass.pluginManagerDefaults[key]) elif key in ["UpdatesCheckInterval", "KeepGenerations"]: return int(prefClass.settings.value( "PluginManager/" + key, prefClass.pluginManagerDefaults[key])) elif key in ["HiddenPlugins"]: return toList(prefClass.settings.value( "PluginManager/" + key, prefClass.pluginManagerDefaults[key])) else: return toBool(prefClass.settings.value( "PluginManager/" + key, prefClass.pluginManagerDefaults[key])) def setPluginManager(key, value, prefClass=Prefs): """ Module function to store the plugin manager related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("PluginManager/" + key, value) def getGraphics(key, prefClass=Prefs): """ Module function to retrieve the Graphics related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ if key in ["Font"]: font = prefClass.settings.value( "Graphics/" + key, prefClass.graphicsDefaults[key]) if isinstance(font, QFont): # workaround for an old bug in eric < 4.4 return font else: f = QFont() f.fromString(font) return f else: return prefClass.settings.value( "Graphics/" + key, prefClass.graphicsDefaults[key]) def setGraphics(key, value, prefClass=Prefs): """ Module function to store the Graphics related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ if key in ["Font"]: prefClass.settings.setValue("Graphics/" + key, value.toString()) else: prefClass.settings.setValue("Graphics/" + key, value) def getIconEditor(key, prefClass=Prefs): """ Module function to retrieve the Icon Editor related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ return prefClass.settings.value( "IconEditor/" + key, prefClass.iconEditorDefaults[key]) def setIconEditor(key, value, prefClass=Prefs): """ Module function to store the Icon Editor related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("IconEditor/" + key, value) def getFlakes(key, prefClass=Prefs): """ Module function to retrieve the pyflakes related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ if key in ["IncludeInSyntaxCheck", "IgnoreStarImportWarnings"]: return toBool(prefClass.settings.value("Py3Flakes/" + key, prefClass.pyflakesDefaults[key])) else: return prefClass.settings.value( "Py3Flakes/" + key, prefClass.pyflakesDefaults[key]) def setFlakes(key, value, prefClass=Prefs): """ Module function to store the pyflakes related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("Py3Flakes/" + key, value) def getTrayStarter(key, prefClass=Prefs): """ Module function to retrieve the tray starter related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ return prefClass.settings.value( "TrayStarter/" + key, prefClass.trayStarterDefaults[key]) def setTrayStarter(key, value, prefClass=Prefs): """ Module function to store the tray starter related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("TrayStarter/" + key, value) def getIrc(key, prefClass=Prefs): """ Module function to retrieve the IRC related settings. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested user setting """ if key in ["TimestampIncludeDate", "ShowTimestamps", "ShowNotifications", "NotifyJoinPart", "NotifyMessage", "NotifyNick", "EnableIrcColours", "AutoUserInfoLookup", "MarkPositionWhenHidden", "AskOnShutdown"]: return toBool(prefClass.settings.value( "IRC/" + key, prefClass.ircDefaults[key])) elif key in ["AutoUserInfoMax", "AutoUserInfoInterval"]: return int(prefClass.settings.value( "IRC/" + key, prefClass.ircDefaults[key])) else: return prefClass.settings.value( "IRC/" + key, prefClass.ircDefaults[key]) def setIrc(key, value, prefClass=Prefs): """ Module function to store the IRC related settings. @param key the key of the setting to be set @param value the value to be set @param prefClass preferences class used as the storage area """ prefClass.settings.setValue("IRC/" + key, value) def getGeometry(key, prefClass=Prefs): """ Module function to retrieve the display geometry. @param key the key of the value to get @param prefClass preferences class used as the storage area @return the requested geometry setting """ if key in ["MainMaximized"]: return toBool(prefClass.settings.value( "Geometry/" + key, prefClass.geometryDefaults[key])) else: v = prefClass.settings.value("Geometry/" + key) if v is not None: return v else: return prefClass.geometryDefaults[key] def setGeometry(key, value, prefClass=Prefs): """ Module function to store the display geometry. @param key the key of the setting to be set @param value the geometry to be set @param prefClass preferences class used as the storage area """ if key in ["MainMaximized"]: prefClass.settings.setValue("Geometry/" + key, value) else: if prefClass.resetLayout: v = prefClass.geometryDefaults[key] else: v = value prefClass.settings.setValue("Geometry/" + key, v) def resetLayout(prefClass=Prefs): """ Module function to set a flag not storing the current layout. @param prefClass preferences class used as the storage area """ prefClass.resetLayout = True def shouldResetLayout(prefClass=Prefs): """ Module function to indicate a reset of the layout. @param prefClass preferences class used as the storage area @return flag indicating a reset of the layout (boolean) """ return prefClass.resetLayout def saveResetLayout(prefClass=Prefs): """ Module function to save the reset layout. @param prefClass preferences class used as the storage area """ if prefClass.resetLayout: for key in list(prefClass.geometryDefaults.keys()): prefClass.settings.setValue( "Geometry/" + key, prefClass.geometryDefaults[key]) def toBool(value): """ Module function to convert a value to bool. @param value value to be converted @return converted data """ if value in ["true", "1", "True"]: return True elif value in ["false", "0", "False"]: return False else: return bool(value) def toList(value): """ Module function to convert a value to a list. @param value value to be converted @return converted data """ if value is None: return [] elif not isinstance(value, list): return [value] else: return value def toByteArray(value): """ Module function to convert a value to a byte array. @param value value to be converted @return converted data """ if value is None: return QByteArray() else: return value def toDict(value): """ Module function to convert a value to a dictionary. @param value value to be converted @return converted data """ if value is None: return {} else: return value def convertPasswords(oldPassword, newPassword, prefClass=Prefs): """ Module function to convert all passwords. @param oldPassword current master password (string) @param newPassword new master password (string) @param prefClass preferences class used as the storage area """ from Utilities.crypto import pwRecode for key in ["ProxyPassword/Http", "ProxyPassword/Https", "ProxyPassword/Ftp", ]: prefClass.settings.setValue( "UI/" + key, pwRecode( prefClass.settings.value("UI/" + key, prefClass.uiDefaults[key]), oldPassword, newPassword ) ) for key in ["MailServerPassword"]: prefClass.settings.setValue( "User/" + key, pwRecode( prefClass.settings.value("User/" + key, prefClass.userDefaults[key]), oldPassword, newPassword ) ) for key in ["SyncFtpPassword", "SyncEncryptionKey"]: prefClass.settings.setValue( "Help/" + key, pwRecode( prefClass.settings.value("Help/" + key, prefClass.helpDefaults[key]), oldPassword, newPassword ) ) initPreferences() initRecentSettings() eric-6.0.8/eric/Preferences/ProgramsDialog.ui0000644000175000017500000000350412060166053020160 0ustar piotrpiotr ProgramsDialog 0 0 700 570 External Programs false true Path Version Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() ProgramsDialog close() 155 546 123 505 buttonBox rejected() ProgramsDialog close() 253 552 207 505 eric-6.0.8/eric/Preferences/ConfigurationPages/0000755000175000017500000000000012557365404020510 5ustar piotrpiotreric-6.0.8/eric/Preferences/ConfigurationPages/ApplicationPage.ui0000644000175000017500000001624312060166053024101 0ustar piotrpiotr ApplicationPage 0 0 589 563 <b>Configure the application</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select, if only one instance of the application should be running Single Application Mode Select to show the startup splash screen Show Splash Screen at startup Open at startup Select to not open anything None Select to open the most recently opened file Last File Select to open the most recently opened project Last Project Select to open the most recently opened multiproject Last Multiproject Select to restore the global session Global Session Check for updates Select to disable update checking None Select to check for updates at every startup Always Select to check for updates once a day Daily Select to check for updates once a week Weekly Select to check for updates once a month Monthly Reporting Select to use the system email client to send reports Use System Email Client Error Log Select to check the existence of an error log upon startup Check for Error Log at Startup Qt::Vertical 571 21 singleApplicationCheckBox splashScreenCheckBox noOpenRadioButton lastFileRadioButton lastProjectRadioButton lastMultiprojectRadioButton globalSessionRadioButton noCheckRadioButton alwaysCheckRadioButton dailyCheckRadioButton weeklyCheckRadioButton monthlyCheckRadioButton systemEmailClientCheckBox errorlogCheckBox eric-6.0.8/eric/Preferences/ConfigurationPages/EditorFilePage.ui0000644000175000017500000004234612316317306023672 0ustar piotrpiotr EditorFilePage 0 0 600 1032 <b>Configure file handling settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Open && Close Select, whether breakpoint belonging to an editor should be cleared, when the editor is closed Clear Breakpoints upon closing Select to reread the file automatically, if it was changed externally Reread automatically when changed externally Warn, if file is greater than Enter the filesize, a warning dialog should be shown. KB 1 16384 16 1024 Qt::Horizontal 40 20 End of Line End of Line Characters Select Unix type end of line Unix Select Macintosh type end of line Macintosh Select Windows type end of line Windows/DOS Select whether the eol type should be converted upon opening the file. Automatic End of Line Conversion Save Select, whether trailing whitespace should be removed upon save Strip trailing whitespace upon save Select, whether a backup file shall be generated upon save Create backup file upon save Autosave interval: Move to set the autosave interval in minutes (0 to disable) 0 30 5 Qt::Horizontal 1 Displays the selected autosave interval. 2 QLCDNumber::Flat 5.000000000000000 Encoding Select to use the advanced encoding detection <b>Advanced encoding detection</b> <p>Select to use the advanced encoding detection based on the &quot;universal character encoding detector&quot; from <a href="http://chardet.feedparser.org">http://chardet.feedparser.org</a>.</p> Use advanced encoding detection Default Encoding: 0 0 Select the string encoding to be used. Default File Filters Open Files: Qt::Horizontal 40 20 Save Files: Additional File Filters <b>Note:</b> Save file filters must contain one wildcard pattern only. true Select to edit the open file filters Open Files true Select to edit the save file filters Save Files 0 0 0 200 true true Add... false Edit... false Delete Qt::Vertical 20 40 File Preview Extensions of HTML files: Enter the filename extensions of HTML files that may be previewed (separated by a space) Extensions of Markdown files: Enter the filename extensions of Markdown files that may be previewed (separated by a space) Extensions of ReST files: Enter the filename extensions of ReStructuredText files that may be previewed (separated by a space) Extensions of QSS files: Enter the filename extensions of Qt Stylesheet files that may be previewed (separated by a space) Qt::Vertical 435 20 clearBreakpointsCheckBox automaticReopenCheckBox warnFilesizeSpinBox lfRadioButton crRadioButton crlfRadioButton automaticEolConversionCheckBox createBackupFileCheckBox stripWhitespaceCheckBox autosaveSlider advEncodingCheckBox defaultEncodingComboBox openFilesFilterComboBox saveFilesFilterComboBox openFiltersButton savFiltersButton fileFiltersList addFileFilterButton editFileFilterButton deleteFileFilterButton autosaveSlider valueChanged(int) autosaveLCD display(int) 272 58 420 55 eric-6.0.8/eric/Preferences/ConfigurationPages/HelpDocumentationPage.ui0000644000175000017500000002253012263305553025261 0ustar piotrpiotr HelpDocumentationPage 0 0 526 894 <b>Configure help documentation</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Python 2 Documentation Enter the Python 2 documentation directory <b>Note</b>: Leave empty to use the PYTHON2DOCDIR environment variable, if set. true Press to select the Python 2 documentation directory via a dialog Python 3 Documentation Enter the Python 3 documentation directory <b>Note</b>: Leave empty to use the PYTHON3DOCDIR environment variable, if set. true Press to select the Python 3 documentation directory via a dialog Qt4 Documentation Enter the Qt4 documentation directory <b>Note</b>: Leave empty to use the QT4DOCDIR environment variable, if set. true Press to select the Qt4 documentation directory via a dialog Qt5 Documentation Enter the Qt5 documentation directory <b>Note</b>: Leave empty to use the QT5DOCDIR environment variable, if set. true Press to select the Qt5 documentation directory via a dialog PyQt4 Documentation Enter the PyQt4 documentation directory <b>Note</b>: Leave empty to use the PYQT4DOCDIR environment variable, if set. true Press to select the PyQt4 documentation directory via a dialog PyQt5 Documentation Enter the PyQt5 documentation directory <b>Note</b>: Leave empty to use the PYQT5DOCDIR environment variable, if set. true Press to select the PyQt5 documentation directory via a dialog PySide Documentation Enter the PySide documentation directory <b>Note</b>: Leave empty to use the PYSIDEDOCDIR environment variable, if set. true Press to select the PySide documentation directory via a dialog Qt::Vertical 479 41 python2DocDirEdit python2DocDirButton pythonDocDirEdit pythonDocDirButton qt4DocDirEdit qt4DocDirButton qt5DocDirEdit qt5DocDirButton pyqt4DocDirEdit pyqt4DocDirButton pyqt5DocDirEdit pyqt5DocDirButton pysideDocDirEdit pysideDocDirButton eric-6.0.8/eric/Preferences/ConfigurationPages/NotificationsPage.py0000644000175000017500000000712312451233373024463 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing the Notifications configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QPoint from PyQt5.QtWidgets import QApplication from .ConfigurationPageBase import ConfigurationPageBase from .Ui_NotificationsPage import Ui_NotificationsPage import Preferences import UI.PixmapCache class NotificationsPage(ConfigurationPageBase, Ui_NotificationsPage): """ Class implementing the Notifications configuration page. """ def __init__(self): """ Constructor """ super(NotificationsPage, self).__init__() self.setupUi(self) self.setObjectName("NotificationsPage") minX, maxX = self.xSpinBox.maximum(), self.xSpinBox.minimum() minY, maxY = self.ySpinBox.maximum(), self.ySpinBox.minimum() desk = QApplication.desktop() for screen in range(desk.screenCount()): geom = desk.availableGeometry(screen) minX = min(minX, geom.x()) maxX = max(maxX, geom.x() + geom.width()) minY = min(minY, geom.y()) maxY = max(maxY, geom.y() + geom.height()) self.xSpinBox.setMinimum(minX) self.xSpinBox.setMaximum(maxX) self.ySpinBox.setMinimum(minY) self.ySpinBox.setMaximum(maxY) self.__notification = None # set initial values self.enableCheckBox.setChecked( Preferences.getUI("NotificationsEnabled")) self.timeoutSpinBox.setValue(Preferences.getUI("NotificationTimeout")) point = Preferences.getUI("NotificationPosition") self.xSpinBox.setValue(point.x()) self.ySpinBox.setValue(point.y()) def save(self): """ Public slot to save the Notifications configuration. """ Preferences.setUI( "NotificationsEnabled", self.enableCheckBox.isChecked()) Preferences.setUI("NotificationTimeout", self.timeoutSpinBox.value()) Preferences.setUI("NotificationPosition", QPoint( self.xSpinBox.value(), self.ySpinBox.value())) @pyqtSlot(bool) def on_visualButton_clicked(self, checked): """ Private slot to select the position visually. @param checked state of the button (boolean) """ if checked: from UI.NotificationWidget import NotificationWidget self.__notification = NotificationWidget( parent=self, setPosition=True) self.__notification.setPixmap( UI.PixmapCache.getPixmap("notification48.png")) self.__notification.setHeading(self.tr("Visual Selection")) self.__notification.setText( self.tr("Drag the notification window to" " the desired place and release the button.")) self.__notification.move( QPoint(self.xSpinBox.value(), self.ySpinBox.value())) self.__notification.show() else: # retrieve the position point = self.__notification.frameGeometry().topLeft() self.xSpinBox.setValue(point.x()) self.ySpinBox.setValue(point.y()) self.__notification.close() self.__notification = None def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = NotificationsPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/PluginManagerPage.ui0000644000175000017500000001643112264534441024374 0ustar piotrpiotr PluginManagerPage 0 0 528 436 <b>Configure plugin manager</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Plugins download directory: Enter the plugins download directory Select the plugins download directory via a directory selection dialog Download Housekeeping No. of generations to keep: Enter the number of generations to keep for each plugin 1 9 Qt::Horizontal 252 20 Select to keep generations of hidden plugins Keep generations of hidden plugins <font color="#FF0000"><b>Note:</b> The following settings are activated at the next startup of the application.</font> Select to enable external plugins to be loaded Load external plugins Check for plugin updates Select to disable update checking Never Select to check for updates once a day Daily Select to check for updates once a week Weekly Select to check for updates once a month Monthly Select to check only already installed plugins for updates Check only installed plugins for updates Repository URL: Shows the repository URL true Press to edit the plugin repository URL Edit URL true Qt::Vertical 435 121 downloadDirEdit downloadDirButton generationsSpinBox keepHiddenCheckBox activateExternalPluginsCheckBox noCheckRadioButton dailyCheckRadioButton weeklyCheckRadioButton monthlyCheckRadioButton downloadedOnlyCheckBox repositoryUrlEdit repositoryUrlEditButton eric-6.0.8/eric/Preferences/ConfigurationPages/PluginManagerPage.py0000644000175000017500000001075312451233373024406 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Plugin Manager configuration page. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_PluginManagerPage import Ui_PluginManagerPage import Preferences import Utilities import UI.PixmapCache class PluginManagerPage(ConfigurationPageBase, Ui_PluginManagerPage): """ Class implementing the Plugin Manager configuration page. """ def __init__(self): """ Constructor """ super(PluginManagerPage, self).__init__() self.setupUi(self) self.setObjectName("PluginManagerPage") self.downloadDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.downloadDirCompleter = E5DirCompleter(self.downloadDirEdit) # set initial values self.activateExternalPluginsCheckBox.setChecked( Preferences.getPluginManager("ActivateExternal")) self.downloadDirEdit.setText( Preferences.getPluginManager("DownloadPath")) self.generationsSpinBox.setValue( Preferences.getPluginManager("KeepGenerations")) self.keepHiddenCheckBox.setChecked( Preferences.getPluginManager("KeepHidden")) period = Preferences.getPluginManager("UpdatesCheckInterval") if period == 0: self.noCheckRadioButton.setChecked(True) elif period == 1: self.dailyCheckRadioButton.setChecked(True) elif period == 2: self.weeklyCheckRadioButton.setChecked(True) elif period == 3: self.monthlyCheckRadioButton.setChecked(True) self.downloadedOnlyCheckBox.setChecked( Preferences.getPluginManager("CheckInstalledOnly")) self.__repositoryUrl = Preferences.getUI("PluginRepositoryUrl6") self.repositoryUrlEdit.setText(self.__repositoryUrl) def save(self): """ Public slot to save the Viewmanager configuration. """ Preferences.setPluginManager( "ActivateExternal", self.activateExternalPluginsCheckBox.isChecked()) Preferences.setPluginManager( "DownloadPath", self.downloadDirEdit.text()) Preferences.setPluginManager( "KeepGenerations", self.generationsSpinBox.value()) Preferences.setPluginManager( "KeepHidden", self.keepHiddenCheckBox.isChecked()) if self.noCheckRadioButton.isChecked(): period = 0 elif self.dailyCheckRadioButton.isChecked(): period = 1 elif self.weeklyCheckRadioButton.isChecked(): period = 2 elif self.monthlyCheckRadioButton.isChecked(): period = 3 Preferences.setPluginManager("UpdatesCheckInterval", period) Preferences.setPluginManager( "CheckInstalledOnly", self.downloadedOnlyCheckBox.isChecked()) if self.repositoryUrlEdit.text() != self.__repositoryUrl: Preferences.setUI( "PluginRepositoryUrl6", self.repositoryUrlEdit.text()) @pyqtSlot() def on_downloadDirButton_clicked(self): """ Private slot to handle the directory selection via dialog. """ directory = E5FileDialog.getExistingDirectory( self, self.tr("Select plugins download directory"), self.downloadDirEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: dn = Utilities.toNativeSeparators(directory) while dn.endswith(os.sep): dn = dn[:-1] self.downloadDirEdit.setText(dn) @pyqtSlot(bool) def on_repositoryUrlEditButton_toggled(self, checked): """ Private slot to set the read only status of the repository URL line edit. @param checked state of the push button (boolean) """ self.repositoryUrlEdit.setReadOnly(not checked) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = PluginManagerPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorStylesPage.py0000644000175000017500000005030512451233373024304 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor Styles configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QColor, QPalette from PyQt5.QtWidgets import QColorDialog from PyQt5.Qsci import QsciScintilla from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorStylesPage import Ui_EditorStylesPage import Preferences class EditorStylesPage(ConfigurationPageBase, Ui_EditorStylesPage): """ Class implementing the Editor Styles configuration page. """ def __init__(self): """ Constructor """ super(EditorStylesPage, self).__init__() self.setupUi(self) self.setObjectName("EditorStylesPage") from QScintilla.QsciScintillaCompat import QsciScintillaCompat, \ QSCINTILLA_VERSION self.foldStyles = [ QsciScintilla.PlainFoldStyle, QsciScintilla.CircledFoldStyle, QsciScintilla.BoxedFoldStyle, QsciScintilla.CircledTreeFoldStyle, QsciScintilla.BoxedTreeFoldStyle, QsciScintillaCompat.ArrowFoldStyle, QsciScintillaCompat.ArrowTreeFoldStyle, ] self.edgeModes = [ QsciScintilla.EdgeNone, QsciScintilla.EdgeLine, QsciScintilla.EdgeBackground ] self.wrapModeComboBox.addItem( self.tr("Disabled"), QsciScintilla.WrapNone) self.wrapModeComboBox.addItem( self.tr("Word Boundary"), QsciScintilla.WrapWord) self.wrapModeComboBox.addItem( self.tr("Character Boundary"), QsciScintilla.WrapCharacter) self.wrapVisualComboBox.addItem( self.tr("No Indicator"), QsciScintilla.WrapFlagNone) self.wrapVisualComboBox.addItem( self.tr("Indicator by Text"), QsciScintilla.WrapFlagByText) self.wrapVisualComboBox.addItem( self.tr("Indicator by Margin"), QsciScintilla.WrapFlagByBorder) if QSCINTILLA_VERSION() >= 0x020700: self.wrapVisualComboBox.addItem( self.tr("Indicator in Line Number Margin"), QsciScintilla.WrapFlagInMargin) if QSCINTILLA_VERSION() < 0x020800: self.caretlineAlwaysVisibleCheckBox.hide() # set initial values try: self.foldingStyleComboBox.setCurrentIndex( self.foldStyles.index(Preferences.getEditor("FoldingStyle"))) except ValueError: self.foldingStyleComboBox.setCurrentIndex(0) self.marginsFont = Preferences.getEditorOtherFonts("MarginsFont") self.marginsFontSample.setFont(self.marginsFont) self.defaultFont = Preferences.getEditorOtherFonts("DefaultFont") self.defaultFontSample.setFont(self.defaultFont) self.monospacedFont = Preferences.getEditorOtherFonts("MonospacedFont") self.monospacedFontSample.setFont(self.monospacedFont) self.monospacedCheckBox.setChecked( Preferences.getEditor("UseMonospacedFont")) self.linenoCheckBox.setChecked( Preferences.getEditor("LinenoMargin")) self.foldingCheckBox.setChecked( Preferences.getEditor("FoldingMargin")) self.unifiedMarginsCheckBox.setChecked( Preferences.getEditor("UnifiedMargins")) self.caretlineVisibleCheckBox.setChecked( Preferences.getEditor("CaretLineVisible")) self.caretlineAlwaysVisibleCheckBox.setChecked( Preferences.getEditor("CaretLineAlwaysVisible")) self.caretWidthSpinBox.setValue( Preferences.getEditor("CaretWidth")) self.colourizeSelTextCheckBox.setChecked( Preferences.getEditor("ColourizeSelText")) self.customSelColourCheckBox.setChecked( Preferences.getEditor("CustomSelectionColours")) self.extentSelEolCheckBox.setChecked( Preferences.getEditor("ExtendSelectionToEol")) self.initColour("CaretForeground", self.caretForegroundButton, Preferences.getEditorColour) self.initColour("CaretLineBackground", self.caretlineBackgroundButton, Preferences.getEditorColour, hasAlpha=True) self.initColour("SelectionForeground", self.selectionForegroundButton, Preferences.getEditorColour) self.initColour("SelectionBackground", self.selectionBackgroundButton, Preferences.getEditorColour, hasAlpha=True) self.initColour("CurrentMarker", self.currentLineMarkerButton, Preferences.getEditorColour, hasAlpha=True) self.initColour("ErrorMarker", self.errorMarkerButton, Preferences.getEditorColour, hasAlpha=True) self.initColour("MarginsForeground", self.marginsForegroundButton, Preferences.getEditorColour) self.initColour("MarginsBackground", self.marginsBackgroundButton, Preferences.getEditorColour) self.initColour("FoldmarginBackground", self.foldmarginBackgroundButton, Preferences.getEditorColour) self.initColour("FoldMarkersForeground", self.foldmarkersForegroundButton, Preferences.getEditorColour) self.initColour("FoldMarkersBackground", self.foldmarkersBackgroundButton, Preferences.getEditorColour) self.editorColours = {} self.editorColours["AnnotationsWarningForeground"] = \ QColor(Preferences.getEditorColour("AnnotationsWarningForeground")) self.editorColours["AnnotationsWarningBackground"] = \ QColor(Preferences.getEditorColour("AnnotationsWarningBackground")) self.editorColours["AnnotationsErrorForeground"] = \ QColor(Preferences.getEditorColour("AnnotationsErrorForeground")) self.editorColours["AnnotationsErrorBackground"] = \ QColor(Preferences.getEditorColour("AnnotationsErrorBackground")) self.editorColours["AnnotationsStyleForeground"] = \ QColor(Preferences.getEditorColour("AnnotationsStyleForeground")) self.editorColours["AnnotationsStyleBackground"] = \ QColor(Preferences.getEditorColour("AnnotationsStyleBackground")) self.eolCheckBox.setChecked(Preferences.getEditor("ShowEOL")) self.wrapModeComboBox.setCurrentIndex(self.wrapModeComboBox.findData( Preferences.getEditor("WrapLongLinesMode"))) self.wrapVisualComboBox.setCurrentIndex( self.wrapVisualComboBox.findData( Preferences.getEditor("WrapVisualFlag"))) self.edgeModeCombo.setCurrentIndex( self.edgeModes.index(Preferences.getEditor("EdgeMode"))) self.edgeLineColumnSlider.setValue( Preferences.getEditor("EdgeColumn")) self.initColour( "Edge", self.edgeBackgroundColorButton, Preferences.getEditorColour) self.bracehighlightingCheckBox.setChecked( Preferences.getEditor("BraceHighlighting")) self.initColour("MatchingBrace", self.matchingBracesButton, Preferences.getEditorColour) self.initColour("MatchingBraceBack", self.matchingBracesBackButton, Preferences.getEditorColour) self.initColour("NonmatchingBrace", self.nonmatchingBracesButton, Preferences.getEditorColour) self.initColour("NonmatchingBraceBack", self.nonmatchingBracesBackButton, Preferences.getEditorColour) self.zoomfactorSlider.setValue( Preferences.getEditor("ZoomFactor")) self.whitespaceCheckBox.setChecked( Preferences.getEditor("ShowWhitespace")) self.whitespaceSizeSpinBox.setValue( Preferences.getEditor("WhitespaceSize")) self.initColour("WhitespaceForeground", self.whitespaceForegroundButton, Preferences.getEditorColour) self.initColour("WhitespaceBackground", self.whitespaceBackgroundButton, Preferences.getEditorColour) if not hasattr(QsciScintilla, "setWhitespaceForegroundColor"): self.whitespaceSizeSpinBox.setEnabled(False) self.whitespaceForegroundButton.setEnabled(False) self.whitespaceBackgroundButton.setEnabled(False) self.miniMenuCheckBox.setChecked( Preferences.getEditor("MiniContextMenu")) self.enableAnnotationsCheckBox.setChecked( Preferences.getEditor("AnnotationsEnabled")) self.editAreaOverrideCheckBox.setChecked( Preferences.getEditor("OverrideEditAreaColours")) self.initColour( "EditAreaForeground", self.editAreaForegroundButton, Preferences.getEditorColour) self.initColour( "EditAreaBackground", self.editAreaBackgroundButton, Preferences.getEditorColour) self.enableChangeTraceCheckBox.setChecked( Preferences.getEditor("OnlineChangeTrace")) self.changeTraceTimeoutSpinBox.setValue( Preferences.getEditor("OnlineChangeTraceInterval")) self.initColour("OnlineChangeTraceMarkerUnsaved", self.changeMarkerUnsavedColorButton, Preferences.getEditorColour) self.initColour("OnlineChangeTraceMarkerSaved", self.changeMarkerSavedColorButton, Preferences.getEditorColour) self.initColour("BookmarksMap", self.bookmarksMapButton, Preferences.getEditorColour) self.initColour("ErrorsMap", self.errorsMapButton, Preferences.getEditorColour) self.initColour("WarningsMap", self.warningsMapButton, Preferences.getEditorColour) self.initColour("BreakpointsMap", self.breakpointsMapButton, Preferences.getEditorColour) self.initColour("TasksMap", self.tasksMapButton, Preferences.getEditorColour) self.initColour("CoverageMap", self.coverageMapButton, Preferences.getEditorColour) self.initColour("ChangesMap", self.changesMapButton, Preferences.getEditorColour) self.initColour("CurrentMap", self.currentMapButton, Preferences.getEditorColour) self.initColour("MarkerMapBackground", self.markerMapBackgroundButton, Preferences.getEditorColour) def save(self): """ Public slot to save the Editor Styles configuration. """ Preferences.setEditor( "FoldingStyle", self.foldStyles[self.foldingStyleComboBox.currentIndex()]) Preferences.setEditorOtherFonts( "MarginsFont", self.marginsFont) Preferences.setEditorOtherFonts( "DefaultFont", self.defaultFont) Preferences.setEditorOtherFonts( "MonospacedFont", self.monospacedFont) Preferences.setEditor( "UseMonospacedFont", self.monospacedCheckBox.isChecked()) Preferences.setEditor( "LinenoMargin", self.linenoCheckBox.isChecked()) Preferences.setEditor( "FoldingMargin", self.foldingCheckBox.isChecked()) Preferences.setEditor( "UnifiedMargins", self.unifiedMarginsCheckBox.isChecked()) Preferences.setEditor( "CaretLineVisible", self.caretlineVisibleCheckBox.isChecked()) Preferences.setEditor( "CaretLineAlwaysVisible", self.caretlineAlwaysVisibleCheckBox.isChecked()) Preferences.setEditor( "ColourizeSelText", self.colourizeSelTextCheckBox.isChecked()) Preferences.setEditor( "CustomSelectionColours", self.customSelColourCheckBox.isChecked()) Preferences.setEditor( "ExtendSelectionToEol", self.extentSelEolCheckBox.isChecked()) Preferences.setEditor( "CaretWidth", self.caretWidthSpinBox.value()) Preferences.setEditor( "ShowEOL", self.eolCheckBox.isChecked()) Preferences.setEditor( "WrapLongLinesMode", self.wrapModeComboBox.itemData( self.wrapModeComboBox.currentIndex())) Preferences.setEditor( "WrapVisualFlag", self.wrapVisualComboBox.itemData( self.wrapVisualComboBox.currentIndex())) Preferences.setEditor( "EdgeMode", self.edgeModes[self.edgeModeCombo.currentIndex()]) Preferences.setEditor( "EdgeColumn", self.edgeLineColumnSlider.value()) Preferences.setEditor( "BraceHighlighting", self.bracehighlightingCheckBox.isChecked()) Preferences.setEditor( "ZoomFactor", self.zoomfactorSlider.value()) Preferences.setEditor( "ShowWhitespace", self.whitespaceCheckBox.isChecked()) Preferences.setEditor( "WhitespaceSize", self.whitespaceSizeSpinBox.value()) Preferences.setEditor( "MiniContextMenu", self.miniMenuCheckBox.isChecked()) Preferences.setEditor( "AnnotationsEnabled", self.enableAnnotationsCheckBox.isChecked()) Preferences.setEditor( "OverrideEditAreaColours", self.editAreaOverrideCheckBox.isChecked()) Preferences.setEditor( "OnlineChangeTrace", self.enableChangeTraceCheckBox.isChecked()) Preferences.setEditor( "OnlineChangeTraceInterval", self.changeTraceTimeoutSpinBox.value()) self.saveColours(Preferences.setEditorColour) for key in list(self.editorColours.keys()): Preferences.setEditorColour(key, self.editorColours[key]) @pyqtSlot() def on_linenumbersFontButton_clicked(self): """ Private method used to select the font for the editor margins. """ self.marginsFont = self.selectFont( self.marginsFontSample, self.marginsFont) @pyqtSlot() def on_defaultFontButton_clicked(self): """ Private method used to select the default font for the editor. """ self.defaultFont = self.selectFont( self.defaultFontSample, self.defaultFont) @pyqtSlot() def on_monospacedFontButton_clicked(self): """ Private method used to select the font to be used as the monospaced font. """ self.monospacedFont = self.selectFont( self.monospacedFontSample, self.monospacedFont) def polishPage(self): """ Public slot to perform some polishing actions. """ self.marginsFontSample.setFont(self.marginsFont) self.defaultFontSample.setFont(self.defaultFont) self.monospacedFontSample.setFont(self.monospacedFont) pl = self.annotationsWarningSample.palette() pl.setColor(QPalette.Text, self.editorColours["AnnotationsWarningForeground"]) pl.setColor(QPalette.Base, self.editorColours["AnnotationsWarningBackground"]) self.annotationsWarningSample.setPalette(pl) self.annotationsWarningSample.repaint() pl = self.annotationsErrorSample.palette() pl.setColor(QPalette.Text, self.editorColours["AnnotationsErrorForeground"]) pl.setColor(QPalette.Base, self.editorColours["AnnotationsErrorBackground"]) self.annotationsErrorSample.setPalette(pl) self.annotationsErrorSample.repaint() pl = self.annotationsStyleWarningSample.palette() pl.setColor(QPalette.Text, self.editorColours["AnnotationsStyleForeground"]) pl.setColor(QPalette.Base, self.editorColours["AnnotationsStyleBackground"]) self.annotationsStyleWarningSample.setPalette(pl) self.annotationsStyleWarningSample.repaint() @pyqtSlot() def on_annotationsWarningFgButton_clicked(self): """ Private slot to set the foreground colour of the warning annotations. """ colour = QColorDialog.getColor( self.editorColours["AnnotationsWarningForeground"]) if colour.isValid(): pl = self.annotationsWarningSample.palette() pl.setColor(QPalette.Text, colour) self.annotationsWarningSample.setPalette(pl) self.annotationsWarningSample.repaint() self.editorColours["AnnotationsWarningForeground"] = colour @pyqtSlot() def on_annotationsWarningBgButton_clicked(self): """ Private slot to set the background colour of the warning annotations. """ colour = QColorDialog.getColor( self.editorColours["AnnotationsWarningBackground"]) if colour.isValid(): pl = self.annotationsWarningSample.palette() pl.setColor(QPalette.Base, colour) self.annotationsWarningSample.setPalette(pl) self.annotationsWarningSample.repaint() self.editorColours["AnnotationsWarningBackground"] = colour @pyqtSlot() def on_annotationsErrorFgButton_clicked(self): """ Private slot to set the foreground colour of the error annotations. """ colour = QColorDialog.getColor( self.editorColours["AnnotationsErrorForeground"]) if colour.isValid(): pl = self.annotationsErrorSample.palette() pl.setColor(QPalette.Text, colour) self.annotationsErrorSample.setPalette(pl) self.annotationsErrorSample.repaint() self.editorColours["AnnotationsErrorForeground"] = colour @pyqtSlot() def on_annotationsErrorBgButton_clicked(self): """ Private slot to set the background colour of the error annotations. """ colour = QColorDialog.getColor( self.editorColours["AnnotationsErrorBackground"]) if colour.isValid(): pl = self.annotationsErrorSample.palette() pl.setColor(QPalette.Base, colour) self.annotationsErrorSample.setPalette(pl) self.annotationsErrorSample.repaint() self.editorColours["AnnotationsErrorBackground"] = colour @pyqtSlot() def on_annotationsStyleWarningFgButton_clicked(self): """ Private slot to set the foreground colour of the style annotations. """ colour = QColorDialog.getColor( self.editorColours["AnnotationsStyleForeground"]) if colour.isValid(): pl = self.annotationsStyleWarningSample.palette() pl.setColor(QPalette.Text, colour) self.annotationsStyleWarningSample.setPalette(pl) self.annotationsStyleWarningSample.repaint() self.editorColours["AnnotationsStyleForeground"] = colour @pyqtSlot() def on_annotationsStyleWarningBgButton_clicked(self): """ Private slot to set the background colour of the style annotations. """ colour = QColorDialog.getColor( self.editorColours["AnnotationsStyleBackground"]) if colour.isValid(): pl = self.annotationsStyleWarningSample.palette() pl.setColor(QPalette.Base, colour) self.annotationsStyleWarningSample.setPalette(pl) self.annotationsStyleWarningSample.repaint() self.editorColours["AnnotationsStyleackground"] = colour def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorStylesPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/MultiProjectPage.ui0000644000175000017500000001165212263306064024261 0ustar piotrpiotr MultiProjectPage 0 0 494 359 <b>Configure multiproject settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Workspace Enter the name of the workspace directory <b>Workspace Directory</b> <p>Enter the directory of the workspace. This directory is used as the default for opening or saving new files or projects.</p> Select the workspace directory via a directory selection button Master Project Select to open the master project automatically upon opening the multiproject Open master project automatically XML Select, if a timestamp should be written to all multiproject related XML files Include timestamp in multiproject related XML files Recent Multiprojects Number of recent multiprojects: Enter the number of recent multiprojects to remember Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 5 50 Qt::Horizontal 40 20 Qt::Vertical 20 40 workspaceEdit workspaceButton openMasterAutomaticallyCheckBox multiProjectTimestampCheckBox multiProjectRecentSpinBox eric-6.0.8/eric/Preferences/ConfigurationPages/EditorHighlightersPage.py0000644000175000017500000001474512451233373025452 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor Highlighter Associations configuration page. """ from __future__ import unicode_literals import os from pygments.lexers import get_all_lexers from PyQt5.QtCore import Qt, pyqtSlot, qVersion from PyQt5.QtWidgets import QHeaderView, QTreeWidgetItem from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorHighlightersPage import Ui_EditorHighlightersPage import Preferences class EditorHighlightersPage(ConfigurationPageBase, Ui_EditorHighlightersPage): """ Class implementing the Editor Highlighter Associations configuration page. """ def __init__(self, lexers): """ Constructor @param lexers reference to the lexers dictionary """ super(EditorHighlightersPage, self).__init__() self.setupUi(self) self.setObjectName("EditorHighlightersPage") self.editorLexerList.headerItem().setText( self.editorLexerList.columnCount(), "") header = self.editorLexerList.header() if qVersion() >= "5.0.0": header.setSectionResizeMode(QHeaderView.ResizeToContents) else: header.setResizeMode(QHeaderView.ResizeToContents) header.setSortIndicator(0, Qt.AscendingOrder) try: self.extsep = os.extsep except AttributeError: self.extsep = "." self.extras = ["-----------", self.tr("Alternative")] languages = [''] + sorted(lexers.keys()) + self.extras self.editorLexerCombo.addItems(languages) pygmentsLexers = [''] + sorted([l[0] for l in get_all_lexers()]) self.pygmentsLexerCombo.addItems(pygmentsLexers) # set initial values lexerAssocs = Preferences.getEditorLexerAssocs() for ext in lexerAssocs: QTreeWidgetItem(self.editorLexerList, [ext, lexerAssocs[ext]]) self.editorLexerList.sortByColumn(0, Qt.AscendingOrder) def save(self): """ Public slot to save the Editor Highlighter Associations configuration. """ lexerAssocs = {} for index in range( self.editorLexerList.topLevelItemCount()): itm = self.editorLexerList.topLevelItem(index) lexerAssocs[itm.text(0)] = itm.text(1) Preferences.setEditorLexerAssocs(lexerAssocs) @pyqtSlot() def on_addLexerButton_clicked(self): """ Private slot to add the lexer association displayed to the list. """ ext = self.editorFileExtEdit.text() if ext.startswith(self.extsep): ext.replace(self.extsep, "") lexer = self.editorLexerCombo.currentText() if lexer in self.extras: pygmentsLexer = self.pygmentsLexerCombo.currentText() if not pygmentsLexer: lexer = pygmentsLexer else: lexer = "Pygments|{0}".format(pygmentsLexer) if ext and lexer: itmList = self.editorLexerList.findItems( ext, Qt.MatchFlags(Qt.MatchExactly), 0) if itmList: index = self.editorLexerList.indexOfTopLevelItem(itmList[0]) itm = self.editorLexerList.takeTopLevelItem(index) del itm QTreeWidgetItem(self.editorLexerList, [ext, lexer]) self.editorFileExtEdit.clear() self.editorLexerCombo.setCurrentIndex(0) self.pygmentsLexerCombo.setCurrentIndex(0) self.editorLexerList.sortItems( self.editorLexerList.sortColumn(), self.editorLexerList.header().sortIndicatorOrder()) @pyqtSlot() def on_deleteLexerButton_clicked(self): """ Private slot to delete the currently selected lexer association of the list. """ itmList = self.editorLexerList.selectedItems() if itmList: index = self.editorLexerList.indexOfTopLevelItem(itmList[0]) itm = self.editorLexerList.takeTopLevelItem(index) del itm self.editorLexerList.clearSelection() self.editorFileExtEdit.clear() self.editorLexerCombo.setCurrentIndex(0) def on_editorLexerList_itemClicked(self, itm, column): """ Private slot to handle the clicked signal of the lexer association list. @param itm reference to the selecte item (QTreeWidgetItem) @param column column the item was clicked or activated (integer) (ignored) """ if itm is None: self.editorFileExtEdit.clear() self.editorLexerCombo.setCurrentIndex(0) self.pygmentsLexerCombo.setCurrentIndex(0) else: self.editorFileExtEdit.setText(itm.text(0)) lexer = itm.text(1) if lexer.startswith("Pygments|"): pygmentsLexer = lexer.split("|")[1] pygmentsIndex = self.pygmentsLexerCombo.findText(pygmentsLexer) lexer = self.tr("Alternative") else: pygmentsIndex = 0 index = self.editorLexerCombo.findText(lexer) self.editorLexerCombo.setCurrentIndex(index) self.pygmentsLexerCombo.setCurrentIndex(pygmentsIndex) def on_editorLexerList_itemActivated(self, itm, column): """ Private slot to handle the activated signal of the lexer association list. @param itm reference to the selecte item (QTreeWidgetItem) @param column column the item was clicked or activated (integer) (ignored) """ self.on_editorLexerList_itemClicked(itm, column) @pyqtSlot(str) def on_editorLexerCombo_currentIndexChanged(self, text): """ Private slot to handle the selection of a lexer. @param text text of the lexer combo (string) """ if text in self.extras: self.pygmentsLexerCombo.setEnabled(True) self.pygmentsLabel.setEnabled(True) else: self.pygmentsLexerCombo.setEnabled(False) self.pygmentsLabel.setEnabled(False) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorHighlightersPage(dlg.getLexers()) return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorAutocompletionQScintillaPage.ui0000644000175000017500000000753612060166053030000 0ustar piotrpiotr EditorAutocompletionQScintillaPage 0 0 506 257 <b>Configure QScintilla Autocompletion</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select this, if single entries shall be inserted automatically Show single Select to enable the use of fill-up characters to autocomplete the current word <b>Use fill-up characters</b><p>Select to enable the use of fill-up characters to autocomplete the current word. A fill-up character is one that, when entered while an auto-completion list is being displayed, causes the currently selected item from the list to be added to the text followed by the fill-up character.</p> Use fill-up characters Source Select this to get autocompletion from current document from Document Select this to get autocompletion from installed APIs from API files Select this to get autocompletion from current document and installed APIs from Document and API files Qt::Vertical 456 51 acShowSingleCheckBox acFillupsCheckBox acSourceDocumentRadioButton acSourceAPIsRadioButton acSourceAllRadioButton eric-6.0.8/eric/Preferences/ConfigurationPages/PythonPage.ui0000644000175000017500000001072412060166053023115 0ustar piotrpiotr PythonPage 0 0 482 473 <b>Configure Python</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Encoding String Encoding: 0 0 Select the string encoding to be used. I/O Encoding: 0 0 Select the string encoding used by commandline tools. Source association Enter the file extensions to be associated with the Python versions separated by a space. They must not overlap with each other. true Python 2: Python 3: Python 2 Interpreter Please configure the Python 2 interpreter on the 'Python 2 Debugger' page. true Qt::Vertical 464 41 eric-6.0.8/eric/Preferences/ConfigurationPages/EditorCalltipsQScintillaPage.py0000644000175000017500000000412612451233373026560 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the QScintilla Calltips configuration page. """ from __future__ import unicode_literals from PyQt5.Qsci import QsciScintilla from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorCalltipsQScintillaPage import Ui_EditorCalltipsQScintillaPage import Preferences class EditorCalltipsQScintillaPage(ConfigurationPageBase, Ui_EditorCalltipsQScintillaPage): """ Class implementing the QScintilla Calltips configuration page. """ def __init__(self): """ Constructor """ super(EditorCalltipsQScintillaPage, self).__init__() self.setupUi(self) self.setObjectName("EditorCalltipsQScintillaPage") # set initial values ctContext = Preferences.getEditor("CallTipsStyle") if ctContext == QsciScintilla.CallTipsNoContext: self.ctNoContextButton.setChecked(True) elif ctContext == QsciScintilla.CallTipsNoAutoCompletionContext: self.ctNoAutoCompletionButton.setChecked(True) elif ctContext == QsciScintilla.CallTipsContext: self.ctContextButton.setChecked(True) def save(self): """ Public slot to save the EditorCalltips configuration. """ if self.ctNoContextButton.isChecked(): Preferences.setEditor( "CallTipsStyle", QsciScintilla.CallTipsNoContext) elif self.ctNoAutoCompletionButton.isChecked(): Preferences.setEditor( "CallTipsStyle", QsciScintilla.CallTipsNoAutoCompletionContext) elif self.ctContextButton.isChecked(): Preferences.setEditor( "CallTipsStyle", QsciScintilla.CallTipsContext) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorCalltipsQScintillaPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorSpellCheckingPage.py0000644000175000017500000001164312451233373025536 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the Editor Spellchecking configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorSpellCheckingPage import Ui_EditorSpellCheckingPage import Preferences import Utilities import UI.PixmapCache class EditorSpellCheckingPage(ConfigurationPageBase, Ui_EditorSpellCheckingPage): """ Class implementing the Editor Spellchecking configuration page. """ def __init__(self): """ Constructor """ super(EditorSpellCheckingPage, self).__init__() self.setupUi(self) self.setObjectName("EditorSpellCheckingPage") self.pwlButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.pelButton.setIcon(UI.PixmapCache.getIcon("open.png")) from QScintilla.SpellChecker import SpellChecker languages = sorted(SpellChecker.getAvailableLanguages()) self.defaultLanguageCombo.addItems(languages) if languages: self.errorLabel.hide() else: self.spellingFrame.setEnabled(False) self.pwlFileCompleter = E5FileCompleter(self.pwlEdit, showHidden=True) self.pelFileCompleter = E5FileCompleter(self.pelEdit, showHidden=True) # set initial values self.checkingEnabledCheckBox.setChecked( Preferences.getEditor("SpellCheckingEnabled")) self.defaultLanguageCombo.setCurrentIndex( self.defaultLanguageCombo.findText( Preferences.getEditor("SpellCheckingDefaultLanguage"))) self.stringsOnlyCheckBox.setChecked( Preferences.getEditor("SpellCheckStringsOnly")) self.minimumWordSizeSlider.setValue( Preferences.getEditor("SpellCheckingMinWordSize")) self.initColour( "SpellingMarkers", self.spellingMarkerButton, Preferences.getEditorColour, hasAlpha=True) self.pwlEdit.setText( Preferences.getEditor("SpellCheckingPersonalWordList")) self.pelEdit.setText( Preferences.getEditor("SpellCheckingPersonalExcludeList")) if self.spellingFrame.isEnabled(): self.enabledCheckBox.setChecked( Preferences.getEditor("AutoSpellCheckingEnabled")) else: self.enabledCheckBox.setChecked(False) # not available self.chunkSizeSpinBox.setValue( Preferences.getEditor("AutoSpellCheckChunkSize")) def save(self): """ Public slot to save the Editor Search configuration. """ Preferences.setEditor( "SpellCheckingEnabled", self.checkingEnabledCheckBox.isChecked()) Preferences.setEditor( "SpellCheckingDefaultLanguage", self.defaultLanguageCombo.currentText()) Preferences.setEditor( "SpellCheckStringsOnly", self.stringsOnlyCheckBox.isChecked()) Preferences.setEditor( "SpellCheckingMinWordSize", self.minimumWordSizeSlider.value()) self.saveColours(Preferences.setEditorColour) Preferences.setEditor( "SpellCheckingPersonalWordList", self.pwlEdit.text()) Preferences.setEditor( "SpellCheckingPersonalExcludeList", self.pelEdit.text()) Preferences.setEditor( "AutoSpellCheckingEnabled", self.enabledCheckBox.isChecked()) Preferences.setEditor( "AutoSpellCheckChunkSize", self.chunkSizeSpinBox.value()) @pyqtSlot() def on_pwlButton_clicked(self): """ Private method to select the personal word list file. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select personal word list"), self.pwlEdit.text(), self.tr("Dictionary File (*.dic);;All Files (*)")) if file: self.pwlEdit.setText(Utilities.toNativeSeparators(file)) @pyqtSlot() def on_pelButton_clicked(self): """ Private method to select the personal exclude list file. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select personal exclude list"), self.pelEdit.text(), self.tr("Dictionary File (*.dic);;All Files (*)")) if file: self.pelEdit.setText(Utilities.toNativeSeparators(file)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorSpellCheckingPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorHighlightingStylesPage.py0000644000175000017500000004656612451233373026650 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor Highlighting Styles configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QFileInfo, QFile, QIODevice from PyQt5.QtGui import QPalette, QFont from PyQt5.QtWidgets import QColorDialog, QFontDialog, QInputDialog, QMenu from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorHighlightingStylesPage import Ui_EditorHighlightingStylesPage from E5Gui import E5MessageBox, E5FileDialog import Preferences class EditorHighlightingStylesPage(ConfigurationPageBase, Ui_EditorHighlightingStylesPage): """ Class implementing the Editor Highlighting Styles configuration page. """ FAMILYONLY = 0 SIZEONLY = 1 FAMILYANDSIZE = 2 FONT = 99 def __init__(self, lexers): """ Constructor @param lexers reference to the lexers dictionary """ super(EditorHighlightingStylesPage, self).__init__() self.setupUi(self) self.setObjectName("EditorHighlightingStylesPage") self.__fontButtonMenu = QMenu() act = self.__fontButtonMenu.addAction(self.tr("Font")) act.setData(self.FONT) self.__fontButtonMenu.addSeparator() act = self.__fontButtonMenu.addAction( self.tr("Family and Size only")) act.setData(self.FAMILYANDSIZE) act = self.__fontButtonMenu.addAction(self.tr("Family only")) act.setData(self.FAMILYONLY) act = self.__fontButtonMenu.addAction(self.tr("Size only")) act.setData(self.SIZEONLY) self.__fontButtonMenu.triggered.connect(self.__fontButtonMenuTriggered) self.fontButton.setMenu(self.__fontButtonMenu) self.__allFontsButtonMenu = QMenu() act = self.__allFontsButtonMenu.addAction(self.tr("Font")) act.setData(self.FONT) self.__allFontsButtonMenu.addSeparator() act = self.__allFontsButtonMenu.addAction( self.tr("Family and Size only")) act.setData(self.FAMILYANDSIZE) act = self.__allFontsButtonMenu.addAction(self.tr("Family only")) act.setData(self.FAMILYONLY) act = self.__allFontsButtonMenu.addAction(self.tr("Size only")) act.setData(self.SIZEONLY) self.__allFontsButtonMenu.triggered.connect( self.__allFontsButtonMenuTriggered) self.allFontsButton.setMenu(self.__allFontsButtonMenu) self.lexer = None self.lexers = lexers # set initial values languages = sorted([''] + list(self.lexers.keys())) self.lexerLanguageComboBox.addItems(languages) self.on_lexerLanguageComboBox_activated("") def save(self): """ Public slot to save the Editor Highlighting Styles configuration. """ for lexer in list(self.lexers.values()): lexer.writeSettings(Preferences.Prefs.settings, "Scintilla") @pyqtSlot(str) def on_lexerLanguageComboBox_activated(self, language): """ Private slot to fill the style combo of the source page. @param language The lexer language (string) """ self.styleElementList.clear() self.styleGroup.setEnabled(False) self.lexer = None self.exportCurrentButton.setEnabled(language != "") self.importCurrentButton.setEnabled(language != "") if not language: return try: self.lexer = self.lexers[language] except KeyError: return self.styleGroup.setEnabled(True) self.styleElementList.addItems(self.lexer.styles) self.__styleAllItems() self.styleElementList.setCurrentRow(0) def __styleAllItems(self): """ Private method to style all items of the style element list. """ for row in range(self.styleElementList.count()): style = self.lexer.ind2style[row] colour = self.lexer.color(style) paper = self.lexer.paper(style) font = self.lexer.font(style) eolfill = self.lexer.eolFill(style) itm = self.styleElementList.item(row) itm.setFont(font) itm.setBackground(paper) itm.setForeground(colour) if eolfill: itm.setCheckState(Qt.Checked) else: itm.setCheckState(Qt.Unchecked) def on_styleElementList_currentRowChanged(self, index): """ Private method to set up the style element part of the source page. @param index the style index. """ try: self.style = self.lexer.ind2style[index] except KeyError: return colour = self.lexer.color(self.style) paper = self.lexer.paper(self.style) eolfill = self.lexer.eolFill(self.style) font = self.lexer.font(self.style) self.sampleText.setFont(font) pl = self.sampleText.palette() pl.setColor(QPalette.Text, colour) pl.setColor(QPalette.Base, paper) self.sampleText.setPalette(pl) self.sampleText.repaint() self.eolfillCheckBox.setChecked(eolfill) @pyqtSlot() def on_foregroundButton_clicked(self): """ Private method used to select the foreground colour of the selected style and lexer. """ colour = QColorDialog.getColor(self.lexer.color(self.style)) if colour.isValid(): pl = self.sampleText.palette() pl.setColor(QPalette.Text, colour) self.sampleText.setPalette(pl) self.sampleText.repaint() if len(self.styleElementList.selectedItems()) > 1: for selItem in self.styleElementList.selectedItems(): style = self.lexer.ind2style[ self.styleElementList.row(selItem)] self.lexer.setColor(colour, style) selItem.setForeground(colour) else: self.lexer.setColor(colour, self.style) self.styleElementList.currentItem().setForeground(colour) @pyqtSlot() def on_backgroundButton_clicked(self): """ Private method used to select the background colour of the selected style and lexer. """ colour = QColorDialog.getColor(self.lexer.paper(self.style)) if colour.isValid(): pl = self.sampleText.palette() pl.setColor(QPalette.Base, colour) self.sampleText.setPalette(pl) self.sampleText.repaint() if len(self.styleElementList.selectedItems()) > 1: for selItem in self.styleElementList.selectedItems(): style = self.lexer.ind2style[ self.styleElementList.row(selItem)] self.lexer.setPaper(colour, style) selItem.setBackground(colour) else: self.lexer.setPaper(colour, self.style) self.styleElementList.currentItem().setBackground(colour) @pyqtSlot() def on_allBackgroundColoursButton_clicked(self): """ Private method used to select the background colour of all styles of a selected lexer. """ colour = QColorDialog.getColor(self.lexer.paper(self.style)) if colour.isValid(): pl = self.sampleText.palette() pl.setColor(QPalette.Base, colour) self.sampleText.setPalette(pl) self.sampleText.repaint() for style in list(self.lexer.ind2style.values()): self.lexer.setPaper(colour, style) self.__styleAllItems() def __changeFont(self, doAll, familyOnly, sizeOnly): """ Private slot to change the highlighter font. @param doAll flag indicating to change the font for all styles (boolean) @param familyOnly flag indicating to set the font family only (boolean) @param sizeOnly flag indicating to set the font size only (boolean """ def setFont(font, style, familyOnly, sizeOnly): """ Local function to set the font. @param font font to be set (QFont) @param style style to set the font for (integer) @param familyOnly flag indicating to set the font family only (boolean) @param sizeOnly flag indicating to set the font size only (boolean """ if familyOnly or sizeOnly: newFont = QFont(self.lexer.font(style)) if familyOnly: newFont.setFamily(font.family()) if sizeOnly: newFont.setPointSize(font.pointSize()) self.lexer.setFont(newFont, style) else: self.lexer.setFont(font, style) def setSampleFont(font, familyOnly, sizeOnly): """ Local function to set the font of the sample text. @param font font to be set (QFont) @param familyOnly flag indicating to set the font family only (boolean) @param sizeOnly flag indicating to set the font size only (boolean """ if familyOnly or sizeOnly: newFont = QFont(self.lexer.font(self.style)) if familyOnly: newFont.setFamily(font.family()) if sizeOnly: newFont.setPointSize(font.pointSize()) self.sampleText.setFont(newFont) else: self.sampleText.setFont(font) font, ok = QFontDialog.getFont(self.lexer.font(self.style)) if ok: setSampleFont(font, familyOnly, sizeOnly) if doAll: for style in list(self.lexer.ind2style.values()): setFont(font, style, familyOnly, sizeOnly) self.__styleAllItems() elif len(self.styleElementList.selectedItems()) > 1: for selItem in self.styleElementList.selectedItems(): style = self.lexer.ind2style[ self.styleElementList.row(selItem)] setFont(font, style, familyOnly, sizeOnly) itmFont = self.lexer.font(style) selItem.setFont(itmFont) else: setFont(font, self.style, familyOnly, sizeOnly) itmFont = self.lexer.font(self.style) self.styleElementList.currentItem().setFont(itmFont) def __fontButtonMenuTriggered(self, act): """ Private slot used to select the font of the selected style and lexer. @param act reference to the triggering action (QAction) """ if act is None: return familyOnly = act.data() in [self.FAMILYANDSIZE, self.FAMILYONLY] sizeOnly = act.data() in [self.FAMILYANDSIZE, self.SIZEONLY] self.__changeFont(False, familyOnly, sizeOnly) def __allFontsButtonMenuTriggered(self, act): """ Private slot used to change the font of all styles of a selected lexer. @param act reference to the triggering action (QAction) """ if act is None: return familyOnly = act.data() in [self.FAMILYANDSIZE, self.FAMILYONLY] sizeOnly = act.data() in [self.FAMILYANDSIZE, self.SIZEONLY] self.__changeFont(True, familyOnly, sizeOnly) def on_eolfillCheckBox_toggled(self, on): """ Private method used to set the eolfill for the selected style and lexer. @param on flag indicating enabled or disabled state (boolean) """ checkState = Qt.Checked if on else Qt.Unchecked if len(self.styleElementList.selectedItems()) > 1: for selItem in self.styleElementList.selectedItems(): style = self.lexer.ind2style[ self.styleElementList.row(selItem)] self.lexer.setEolFill(on, style) selItem.setCheckState(checkState) else: self.lexer.setEolFill(on, self.style) self.styleElementList.currentItem().setCheckState(checkState) @pyqtSlot() def on_allEolFillButton_clicked(self): """ Private method used to set the eolfill for all styles of a selected lexer. """ on = self.tr("Enabled") off = self.tr("Disabled") selection, ok = QInputDialog.getItem( self, self.tr("Fill to end of line"), self.tr("Select fill to end of line for all styles"), [on, off], 0, False) if ok: enabled = selection == on self.eolfillCheckBox.setChecked(enabled) for style in list(self.lexer.ind2style.values()): self.lexer.setEolFill(enabled, style) self.__styleAllItems() @pyqtSlot() def on_defaultButton_clicked(self): """ Private method to set the current style to its default values. """ if len(self.styleElementList.selectedItems()) > 1: for selItem in self.styleElementList.selectedItems(): style = self.lexer.ind2style[ self.styleElementList.row(selItem)] self.__setToDefault(style) else: self.__setToDefault(self.style) self.on_styleElementList_currentRowChanged( self.styleElementList.currentRow()) self.__styleAllItems() @pyqtSlot() def on_allDefaultButton_clicked(self): """ Private method to set all styles to their default values. """ for style in list(self.lexer.ind2style.values()): self.__setToDefault(style) self.on_styleElementList_currentRowChanged( self.styleElementList.currentRow()) self.__styleAllItems() def __setToDefault(self, style): """ Private method to set a specific style to its default values. @param style style to be reset (integer) """ self.lexer.setColor(self.lexer.defaultColor(style), style) self.lexer.setPaper(self.lexer.defaultPaper(style), style) self.lexer.setFont(self.lexer.defaultFont(style), style) self.lexer.setEolFill(self.lexer.defaultEolFill(style), style) @pyqtSlot() def on_importCurrentButton_clicked(self): """ Private slot to import the styles of the current lexer. """ self.__importStyles({self.lexer.language(): self.lexer}) @pyqtSlot() def on_exportCurrentButton_clicked(self): """ Private slot to export the styles of the current lexer. """ self.__exportStyles([self.lexer]) @pyqtSlot() def on_importAllButton_clicked(self): """ Private slot to import the styles of all lexers. """ self.__importStyles(self.lexers) @pyqtSlot() def on_exportAllButton_clicked(self): """ Private slot to export the styles of all lexers. """ self.__exportStyles(list(self.lexers.values())) def __exportStyles(self, lexers): """ Private method to export the styles of the given lexers. @param lexers list of lexer objects for which to export the styles """ fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Export Highlighting Styles"), "", self.tr("Highlighting styles file (*.e4h)"), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fn: return ext = QFileInfo(fn).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fn += ex f = QFile(fn) if f.open(QIODevice.WriteOnly): from E5XML.HighlightingStylesWriter import HighlightingStylesWriter HighlightingStylesWriter(f, lexers).writeXML() f.close() else: E5MessageBox.critical( self, self.tr("Export Highlighting Styles"), self.tr( """

The highlighting styles could not be exported""" """ to file {0}.

Reason: {1}

""") .format(fn, f.errorString()) ) def __importStyles(self, lexers): """ Private method to import the styles of the given lexers. @param lexers dictionary of lexer objects for which to import the styles """ fn = E5FileDialog.getOpenFileName( self, self.tr("Import Highlighting Styles"), "", self.tr("Highlighting styles file (*.e4h)")) if not fn: return f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.HighlightingStylesReader import HighlightingStylesReader reader = HighlightingStylesReader(f, lexers) reader.readXML() f.close() else: E5MessageBox.critical( self, self.tr("Import Highlighting Styles"), self.tr( """

The highlighting styles could not be read""" """ from file {0}.

Reason: {1}

""") .format(fn, f.errorString()) ) return if self.lexer: colour = self.lexer.color(self.style) paper = self.lexer.paper(self.style) eolfill = self.lexer.eolFill(self.style) font = self.lexer.font(self.style) self.sampleText.setFont(font) pl = self.sampleText.palette() pl.setColor(QPalette.Text, colour) pl.setColor(QPalette.Base, paper) self.sampleText.setPalette(pl) self.sampleText.repaint() self.eolfillCheckBox.setChecked(eolfill) self.__styleAllItems() def saveState(self): """ Public method to save the current state of the widget. @return array containing the index of the selected lexer language (integer) and the index of the selected lexer entry (integer) """ savedState = [ self.lexerLanguageComboBox.currentIndex(), self.styleElementList.currentRow(), ] return savedState def setState(self, state): """ Public method to set the state of the widget. @param state state data generated by saveState """ self.lexerLanguageComboBox.setCurrentIndex(state[0]) self.on_lexerLanguageComboBox_activated( self.lexerLanguageComboBox.currentText()) self.styleElementList.setCurrentRow(state[1]) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorHighlightingStylesPage(dlg.getLexers()) return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorSyntaxPage.ui0000644000175000017500000001242212214657150024272 0ustar piotrpiotr EditorSyntaxPage 0 0 400 412 <b>Configure Code Checker settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select, whether source files should be checked automatically for syntax errors <b>Automatic Syntax Check</b><p>Select to enable the automatic syntax checker. The syntax is checked, when a file is loaded or saved or the programming language of the editor is selected.</p> Automatic Syntax Check true Select to enable the online syntax checker <b>Online Syntax Check</b><p>Select this to enable syntax checks while typing. The check is performed, if typing is interrupted for the configured timeout period.</p> Online Syntax Check true Timeout Interval: Enter the timeout for the online syntax checker <b>Timeout Interval</b><p>Enter the timeout interval for the online syntax check. The check is performed, if typing is interrupted for the configured timeout period.</p> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter QAbstractSpinBox::PlusMinus s 5 Qt::Horizontal 205 20 PyFlakes Select to include a PyFlakes check after the syntax check Include PyFlakes Checks after syntax check Select to suppress star import warnings Suppress star import warnings Qt::Vertical 20 108 eric-6.0.8/eric/Preferences/ConfigurationPages/HelpAppearancePage.py0000644000175000017500000001170412451233373024522 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Help Viewers configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_HelpAppearancePage import Ui_HelpAppearancePage import Preferences import Utilities import UI.PixmapCache class HelpAppearancePage(ConfigurationPageBase, Ui_HelpAppearancePage): """ Class implementing the Help Viewer Appearance page. """ def __init__(self): """ Constructor """ super(HelpAppearancePage, self).__init__() self.setupUi(self) self.setObjectName("HelpAppearancePage") self.styleSheetButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.styleSheetCompleter = E5FileCompleter(self.styleSheetEdit) self.__displayMode = None # set initial values self.standardFont = Preferences.getHelp("StandardFont") self.standardFontSample.setFont(self.standardFont) self.standardFontSample.setText( "{0} {1}".format(self.standardFont.family(), self.standardFont.pointSize())) self.fixedFont = Preferences.getHelp("FixedFont") self.fixedFontSample.setFont(self.fixedFont) self.fixedFontSample.setText( "{0} {1}".format(self.fixedFont.family(), self.fixedFont.pointSize())) self.initColour("SaveUrlColor", self.secureURLsColourButton, Preferences.getHelp) self.autoLoadImagesCheckBox.setChecked( Preferences.getHelp("AutoLoadImages")) self.styleSheetEdit.setText(Preferences.getHelp("UserStyleSheet")) self.tabsCloseButtonCheckBox.setChecked( Preferences.getUI("SingleCloseButton")) self.warnOnMultipleCloseCheckBox.setChecked( Preferences.getHelp("WarnOnMultipleClose")) def setMode(self, displayMode): """ Public method to perform mode dependent setups. @param displayMode mode of the configuration dialog (ConfigurationWidget.DefaultMode, ConfigurationWidget.HelpBrowserMode, ConfigurationWidget.TrayStarterMode) """ from ..ConfigurationDialog import ConfigurationWidget assert displayMode in ( ConfigurationWidget.DefaultMode, ConfigurationWidget.HelpBrowserMode, ConfigurationWidget.TrayStarterMode ) self.__displayMode = displayMode if self.__displayMode != ConfigurationWidget.HelpBrowserMode: self.separatorLine.hide() self.nextStartupNoteLabel.hide() self.tabsGroupBox.hide() def save(self): """ Public slot to save the Help Viewers configuration. """ Preferences.setHelp("StandardFont", self.standardFont) Preferences.setHelp("FixedFont", self.fixedFont) Preferences.setHelp( "AutoLoadImages", self.autoLoadImagesCheckBox.isChecked()) Preferences.setHelp("UserStyleSheet", self.styleSheetEdit.text()) self.saveColours(Preferences.setHelp) from ..ConfigurationDialog import ConfigurationWidget if self.__displayMode == ConfigurationWidget.HelpBrowserMode: Preferences.setUI( "SingleCloseButton", self.tabsCloseButtonCheckBox.isChecked()) Preferences.setHelp( "WarnOnMultipleClose", self.warnOnMultipleCloseCheckBox.isChecked()) @pyqtSlot() def on_standardFontButton_clicked(self): """ Private method used to select the standard font. """ self.standardFont = \ self.selectFont(self.standardFontSample, self.standardFont, True) @pyqtSlot() def on_fixedFontButton_clicked(self): """ Private method used to select the fixed-width font. """ self.fixedFont = \ self.selectFont(self.fixedFontSample, self.fixedFont, True) @pyqtSlot() def on_styleSheetButton_clicked(self): """ Private slot to handle the user style sheet selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select Style Sheet"), self.styleSheetEdit.text(), "") if file: self.styleSheetEdit.setText(Utilities.toNativeSeparators(file)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = HelpAppearancePage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/SecurityPage.py0000644000175000017500000001043212451233373023456 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Security configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from PyQt5.QtWebKit import QWebSettings from .ConfigurationPageBase import ConfigurationPageBase from .Ui_SecurityPage import Ui_SecurityPage import Preferences class SecurityPage(ConfigurationPageBase, Ui_SecurityPage): """ Class implementing the Security configuration page. """ def __init__(self, configDialog): """ Constructor @param configDialog reference to the configuration dialog (ConfigurationDialog) """ super(SecurityPage, self).__init__() self.setupUi(self) self.setObjectName("SecurityPage") self.__configDlg = configDialog # set initial values self.savePasswordsCheckBox.setChecked( Preferences.getUser("SavePasswords")) self.masterPasswordCheckBox.setChecked( Preferences.getUser("UseMasterPassword")) self.masterPasswordButton.setEnabled( Preferences.getUser("UseMasterPassword")) if hasattr(QWebSettings, "DnsPrefetchEnabled"): self.dnsPrefetchCheckBox.setChecked( Preferences.getHelp("DnsPrefetchEnabled")) else: self.dnsPrefetchCheckBox.setEnabled(False) self.__newPassword = "" self.__oldUseMasterPassword = Preferences.getUser("UseMasterPassword") def save(self): """ Public slot to save the Help Viewers configuration. """ Preferences.setUser( "SavePasswords", self.savePasswordsCheckBox.isChecked()) Preferences.setUser( "UseMasterPassword", self.masterPasswordCheckBox.isChecked()) if self.dnsPrefetchCheckBox.isEnabled(): Preferences.setHelp( "DnsPrefetchEnabled", self.dnsPrefetchCheckBox.isChecked()) if self.__oldUseMasterPassword != \ self.masterPasswordCheckBox.isChecked(): self.__configDlg.masterPasswordChanged.emit("", self.__newPassword) @pyqtSlot(bool) def on_masterPasswordCheckBox_clicked(self, checked): """ Private slot to handle the use of a master password. @param checked flag indicating the state of the check box (boolean) """ if checked: from .MasterPasswordEntryDialog import MasterPasswordEntryDialog dlg = MasterPasswordEntryDialog("", self) if dlg.exec_() == QDialog.Accepted: Preferences.setUser( "MasterPassword", dlg.getMasterPassword()) self.masterPasswordButton.setEnabled(True) self.__newPassword = dlg.getMasterPassword() else: self.masterPasswordCheckBox.setChecked(False) else: self.masterPasswordButton.setEnabled(False) self.__newPassword = "" @pyqtSlot() def on_masterPasswordButton_clicked(self): """ Private slot to change the master password. """ from .MasterPasswordEntryDialog import MasterPasswordEntryDialog dlg = MasterPasswordEntryDialog( Preferences.getUser("MasterPassword"), self) if dlg.exec_() == QDialog.Accepted: Preferences.setUser( "MasterPassword", dlg.getMasterPassword()) if self.__oldUseMasterPassword != \ self.masterPasswordCheckBox.isChecked(): # the user is about to change the use of a master password # just save the changed password self.__newPassword = dlg.getMasterPassword() else: self.__configDlg.masterPasswordChanged.emit( dlg.getCurrentPassword(), dlg.getMasterPassword()) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = SecurityPage(dlg) return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorSearchPage.ui0000644000175000017500000001276112060166053024213 0ustar piotrpiotr EditorSearchPage 0 0 576 596 <b>Configure editor search options</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Search Markers Select, whether markers for all occurrences of the current word shall be shown Highlight all occurrences of current word Select, whether search markers shall be shown for a standard search Highlight all occurrences of search text Select, whether search markers shall be shown for a quicksearch Highlight all occurrences of quicksearch text Timeout for current word highlighting: Enter the time in milliseconds after which occurrences of the current word shall be highlighted Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter QAbstractSpinBox::PlusMinus QAbstractSpinBox::CorrectToNearestValue ms 100 5000 100 Qt::Horizontal 40 20 Marker Colour: 100 0 Select the colour for the search markers. Qt::Horizontal 40 20 Qt::Vertical 558 231 occurrencesMarkersEnabledCheckBox searchMarkersEnabledCheckBox quicksearchMarkersEnabledCheckBox markOccurrencesTimeoutSpinBox searchMarkerButton eric-6.0.8/eric/Preferences/ConfigurationPages/HelpWebBrowserPage.ui0000644000175000017500000005673112152656672024553 0ustar piotrpiotr HelpWebBrowserPage 0 0 616 1224 <b>Configure web browser</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select to use a single help browser window only Use single web browser window Select to enable suggestions for web searches Show suggestions for web searches Select to save the window size and position Save size and position upon exit Select to show a page preview when the mouse hovers over the tab Show preview when hovering tab Select to enable the browser's workaround for broken sites Enable workaround for broken sites Startup On startup: Select the startup behavior Show Home Page Show Speed Dial Show Empty Page Home Page: Enter the desired home page Press to set the current page as the home page Set to current page Press to set the default home page Set to default home page Qt::Horizontal 160 20 Scheme Default Scheme: 0 0 Select the default scheme <b>Default Scheme</b><p>Select the default scheme. This scheme is prepended to URLs, that don't contain one.</p> false Privacy Select to enable Java Enable Java Select to enable JavaScript Enable JavaScript Select to allow JavaScript to open windows JavaScript can open windows Select to allow JavaScript to access the clipboard JavaScript can access clipboard Select to enable plugins in web pages Enable Plugins Qt::Horizontal QSizePolicy::Fixed 20 19 false 8 0 Select to activate the Flash blocker Use ClickToFlash on Flash plugins Qt::Horizontal 308 20 Qt::Horizontal Select to enabled the "Do Not Track" feature Tell web sites I do not want to be tracked Select to send referer headers to the server Send Referer header to servers Qt::Horizontal 40 20 Press to edit the list of whitelisted hosts Edit Referer Whitelist ... Security Select to enable XSS auditing <b>Enable XSS Auditing</b> <p>This selects whether load requests should be monitored for cross-site scripting attempts. Suspicious scripts will be blocked. These will be reported in theWeb Inspector's JavaScript console. Enabling this feature might have an impact on performance.</p> Enable XSS Auditing History Remove history items: 0 0 Select the period for expiration of history entries After one day After one week After two weeks After one month After one year Manually On application exit Browser Cache Enable disk cache Qt::Horizontal 40 20 Press to edit the list of hosts exempted from caching Edit Exempted Hosts ... Policy Select to prefer the network Keep cache in sync Select to prefer cached data Use cache whenever possible Select to use cached data only Offline browsing mode Cache size: Enter the maximum size of the disk cache Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter MB 1 999 Qt::Horizontal 410 20 Web Search Language: Select the language to be used for web searches QComboBox::AdjustToContents Qt::Horizontal 450 20 Printing Select to print background colours and images Print background colours and images Navigation Select to enable the spatial navigation feature <b>Enable Spatial Navigation</b> <p>This enables or disables the Spatial Navigation feature, which consists in the ability to navigate between focusable elements in a Web page, such as hyperlinks and form controls, by using Left, Right, Up and Down arrow keys. For example, if a user presses the Right key, heuristics determine whether there is an element he might be trying to reach towards the right and which element he probably wants.</p> Enable Spatial Navigation Select to include links in focus chain <b>Include Links in Focus Chain</b> <p>This selects whether hyperlinks should be included in the keyboard focus chain.</p> Include Links in Focus Chain Select to enable support for access keys Enable access keys Qt::Vertical 479 121 singleHelpWindowCheckBox webSuggestionsCheckBox saveGeometryCheckBox showTabPreviews quirksCheckBox startupCombo homePageEdit setCurrentPageButton defaultHomeButton defaultSchemeCombo javaCheckBox javaScriptCheckBox jsOpenWindowsCheckBox jsClipboardCheckBox pluginsCheckBox clickToFlashCheckBox doNotTrackCheckBox sendRefererCheckBox refererWhitelistButton xssAuditingCheckBox expireHistory diskCacheCheckBox noCacheHostsButton cacheKeepButton cachePreferButton cacheOfflineButton cacheSizeSpinBox languageCombo printBackgroundsCheckBox spatialCheckBox linksInFocusChainCheckBox accessKeysCheckBox pluginsCheckBox toggled(bool) clickToFlashCheckBox setEnabled(bool) 89 422 145 465 eric-6.0.8/eric/Preferences/ConfigurationPages/DebuggerGeneralPage.py0000644000175000017500000002733712451233373024705 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Debugger General configuration page. """ from __future__ import unicode_literals import socket from PyQt5.QtCore import QRegExp, pyqtSlot from PyQt5.QtWidgets import QLineEdit, QInputDialog from PyQt5.QtNetwork import QNetworkInterface, QAbstractSocket, QHostAddress from E5Gui.E5Application import e5App from E5Gui.E5Completers import E5FileCompleter, E5DirCompleter from E5Gui import E5MessageBox from .ConfigurationPageBase import ConfigurationPageBase from .Ui_DebuggerGeneralPage import Ui_DebuggerGeneralPage import Preferences import Utilities class DebuggerGeneralPage(ConfigurationPageBase, Ui_DebuggerGeneralPage): """ Class implementing the Debugger General configuration page. """ def __init__(self): """ Constructor """ super(DebuggerGeneralPage, self).__init__() self.setupUi(self) self.setObjectName("DebuggerGeneralPage") t = self.execLineEdit.whatsThis() if t: t += Utilities.getPercentReplacementHelp() self.execLineEdit.setWhatsThis(t) try: backends = e5App().getObject("DebugServer").getSupportedLanguages() for backend in sorted(backends): self.passiveDbgBackendCombo.addItem(backend) except KeyError: self.passiveDbgGroup.setEnabled(False) t = self.consoleDbgEdit.whatsThis() if t: t += Utilities.getPercentReplacementHelp() self.consoleDbgEdit.setWhatsThis(t) self.consoleDbgCompleter = E5FileCompleter(self.consoleDbgEdit) self.dbgTranslationLocalCompleter = E5DirCompleter( self.dbgTranslationLocalEdit) # set initial values interfaces = [] networkInterfaces = QNetworkInterface.allInterfaces() for networkInterface in networkInterfaces: addressEntries = networkInterface.addressEntries() if len(addressEntries) > 0: for addressEntry in addressEntries: if ":" in addressEntry.ip().toString() and \ not socket.has_ipv6: continue # IPv6 not supported by Python interfaces.append( "{0} ({1})".format( networkInterface.humanReadableName(), addressEntry.ip().toString())) self.interfacesCombo.addItems(interfaces) interface = Preferences.getDebugger("NetworkInterface") if not socket.has_ipv6: # IPv6 not supported by Python self.all6InterfacesButton.setEnabled(False) if interface == "allv6": interface = "all" if interface == "all": self.allInterfacesButton.setChecked(True) elif interface == "allv6": self.all6InterfacesButton.setChecked(True) else: self.selectedInterfaceButton.setChecked(True) index = -1 for i in range(len(interfaces)): if QRegExp(".*{0}.*".format(interface))\ .exactMatch(interfaces[i]): index = i break self.interfacesCombo.setCurrentIndex(index) self.allowedHostsList.addItems( Preferences.getDebugger("AllowedHosts")) self.remoteCheckBox.setChecked( Preferences.getDebugger("RemoteDbgEnabled")) self.hostLineEdit.setText( Preferences.getDebugger("RemoteHost")) self.execLineEdit.setText( Preferences.getDebugger("RemoteExecution")) if self.passiveDbgGroup.isEnabled(): self.passiveDbgCheckBox.setChecked( Preferences.getDebugger("PassiveDbgEnabled")) self.passiveDbgPortSpinBox.setValue( Preferences.getDebugger("PassiveDbgPort")) index = self.passiveDbgBackendCombo.findText( Preferences.getDebugger("PassiveDbgType")) if index == -1: index = 0 self.passiveDbgBackendCombo.setCurrentIndex(index) self.debugEnvironReplaceCheckBox.setChecked( Preferences.getDebugger("DebugEnvironmentReplace")) self.debugEnvironEdit.setText( Preferences.getDebugger("DebugEnvironment")) self.automaticResetCheckBox.setChecked( Preferences.getDebugger("AutomaticReset")) self.debugAutoSaveScriptsCheckBox.setChecked( Preferences.getDebugger("Autosave")) self.consoleDbgCheckBox.setChecked( Preferences.getDebugger("ConsoleDbgEnabled")) self.consoleDbgEdit.setText( Preferences.getDebugger("ConsoleDbgCommand")) self.dbgPathTranslationCheckBox.setChecked( Preferences.getDebugger("PathTranslation")) self.dbgTranslationRemoteEdit.setText( Preferences.getDebugger("PathTranslationRemote")) self.dbgTranslationLocalEdit.setText( Preferences.getDebugger("PathTranslationLocal")) self.debugThreeStateBreakPoint.setChecked( Preferences.getDebugger("ThreeStateBreakPoints")) self.dontShowClientExitCheckBox.setChecked( Preferences.getDebugger("SuppressClientExit")) self.exceptionBreakCheckBox.setChecked( Preferences.getDebugger("BreakAlways")) self.exceptionShellCheckBox.setChecked( Preferences.getDebugger("ShowExceptionInShell")) self.autoViewSourcecodeCheckBox.setChecked( Preferences.getDebugger("AutoViewSourceCode")) def save(self): """ Public slot to save the Debugger General (1) configuration. """ Preferences.setDebugger( "RemoteDbgEnabled", self.remoteCheckBox.isChecked()) Preferences.setDebugger( "RemoteHost", self.hostLineEdit.text()) Preferences.setDebugger( "RemoteExecution", self.execLineEdit.text()) Preferences.setDebugger( "PassiveDbgEnabled", self.passiveDbgCheckBox.isChecked()) Preferences.setDebugger( "PassiveDbgPort", self.passiveDbgPortSpinBox.value()) Preferences.setDebugger( "PassiveDbgType", self.passiveDbgBackendCombo.currentText()) if self.allInterfacesButton.isChecked(): Preferences.setDebugger("NetworkInterface", "all") elif self.all6InterfacesButton.isChecked(): Preferences.setDebugger("NetworkInterface", "allv6") else: interface = self.interfacesCombo.currentText() interface = interface.split("(")[1].split(")")[0] if not interface: Preferences.setDebugger("NetworkInterface", "all") else: Preferences.setDebugger("NetworkInterface", interface) allowedHosts = [] for row in range(self.allowedHostsList.count()): allowedHosts.append(self.allowedHostsList.item(row).text()) Preferences.setDebugger("AllowedHosts", allowedHosts) Preferences.setDebugger( "DebugEnvironmentReplace", self.debugEnvironReplaceCheckBox.isChecked()) Preferences.setDebugger( "DebugEnvironment", self.debugEnvironEdit.text()) Preferences.setDebugger( "AutomaticReset", self.automaticResetCheckBox.isChecked()) Preferences.setDebugger( "Autosave", self.debugAutoSaveScriptsCheckBox.isChecked()) Preferences.setDebugger( "ConsoleDbgEnabled", self.consoleDbgCheckBox.isChecked()) Preferences.setDebugger( "ConsoleDbgCommand", self.consoleDbgEdit.text()) Preferences.setDebugger( "PathTranslation", self.dbgPathTranslationCheckBox.isChecked()) Preferences.setDebugger( "PathTranslationRemote", self.dbgTranslationRemoteEdit.text()) Preferences.setDebugger( "PathTranslationLocal", self.dbgTranslationLocalEdit.text()) Preferences.setDebugger( "ThreeStateBreakPoints", self.debugThreeStateBreakPoint.isChecked()) Preferences.setDebugger( "SuppressClientExit", self.dontShowClientExitCheckBox.isChecked()) Preferences.setDebugger( "BreakAlways", self.exceptionBreakCheckBox.isChecked()) Preferences.setDebugger( "ShowExceptionInShell", self.exceptionShellCheckBox.isChecked()) Preferences.setDebugger( "AutoViewSourceCode", self.autoViewSourcecodeCheckBox.isChecked()) def on_allowedHostsList_currentItemChanged(self, current, previous): """ Private method set the state of the edit and delete button. @param current new current item (QListWidgetItem) @param previous previous current item (QListWidgetItem) """ self.editAllowedHostButton.setEnabled(current is not None) self.deleteAllowedHostButton.setEnabled(current is not None) @pyqtSlot() def on_addAllowedHostButton_clicked(self): """ Private slot called to add a new allowed host. """ allowedHost, ok = QInputDialog.getText( None, self.tr("Add allowed host"), self.tr("Enter the IP address of an allowed host"), QLineEdit.Normal) if ok and allowedHost: if QHostAddress(allowedHost).protocol() in \ [QAbstractSocket.IPv4Protocol, QAbstractSocket.IPv6Protocol]: self.allowedHostsList.addItem(allowedHost) else: E5MessageBox.critical( self, self.tr("Add allowed host"), self.tr( """

The entered address {0} is not""" """ a valid IP v4 or IP v6 address.""" """ Aborting...

""") .format(allowedHost)) @pyqtSlot() def on_deleteAllowedHostButton_clicked(self): """ Private slot called to delete an allowed host. """ self.allowedHostsList.takeItem(self.allowedHostsList.currentRow()) @pyqtSlot() def on_editAllowedHostButton_clicked(self): """ Private slot called to edit an allowed host. """ allowedHost = self.allowedHostsList.currentItem().text() allowedHost, ok = QInputDialog.getText( None, self.tr("Edit allowed host"), self.tr("Enter the IP address of an allowed host"), QLineEdit.Normal, allowedHost) if ok and allowedHost: if QHostAddress(allowedHost).protocol() in \ [QAbstractSocket.IPv4Protocol, QAbstractSocket.IPv6Protocol]: self.allowedHostsList.currentItem().setText(allowedHost) else: E5MessageBox.critical( self, self.tr("Edit allowed host"), self.tr( """

The entered address {0} is not""" """ a valid IP v4 or IP v6 address.""" """ Aborting...

""") .format(allowedHost)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = DebuggerGeneralPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/DebuggerRubyPage.ui0000644000175000017500000000433012355747621024233 0ustar piotrpiotr DebuggerRubyPage 0 0 400 170 <b>Configure Ruby Debugger</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Ruby Interpreter for Debug Client Enter the path of the Ruby interpreter to be used by the debug client. Press to select the Ruby interpreter via a file selection dialog Select, to redirect stdin, stdout and stderr of the program being debugged to the eric6 IDE Redirect stdin/stdout/stderr Qt::Vertical 20 40 eric-6.0.8/eric/Preferences/ConfigurationPages/InterfacePage.ui0000644000175000017500000005024112263306015023531 0ustar piotrpiotr InterfacePage 0 0 557 1121 <b>Configure User Interface</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Browsers Select, if folders should be listed first in the various browsers List folders first in Browsers Select to hide non public classes, methods and attributes in the browsers. Hide non public members in Browsers Select to sort file contents by occurrence Sort contents by occurrence Select to show hidden files in the various browsers Show hidden files Filter out files: Enter wildcard file patterns separated by semicolon. Files matching these patterns will not be shown by the file browsers. Log-Viewer Select to show the log-viewer upon new output Show upon new output Stderr Colour: 100 0 Select the colour for text sent to stderr Qt::Horizontal 319 20 Qt::StrongFocus Select, if the caption of the main window should show the filename of the current editor Caption shows filename true Filename Length Enter the number of characters to be shown in the main window title. 10 999 10 100 Qt::Horizontal 31 23 Style: Select the interface style Style Sheet: Enter the name of the style sheet file Select the style sheet file via a file selection dialog Dockarea Corner Usage Top Left Corner Select to assign the top left corner to the top dockarea Top dockarea Select to assign the top left corner to the left dockarea Left dockarea Top Right Corner Select to assign the top right corner to the top dockarea Top dockarea Select to assign the top right corner to the right dockarea Right dockarea Bottom Left Corner Select to assign the bottom left corner to the bottom dockarea Bottom dockarea Select to assign the bottom left corner to the left dockarea Left dockarea Bottom Right Corner Select to assign the bottom right corner to the bottom dockarea Bottom dockarea Select to assign the bottom right corner to the right dockarea Right dockarea Sidebars Delay: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter ms 2000 100 200 Qt::Horizontal 396 20 QFrame::HLine QFrame::Sunken Qt::Horizontal <font color="#FF0000"><b>Note:</b> All settings below are activated at the next startup of the application.</font> 0 0 Language: languageComboBox 0 0 Select the interface language. The interface language can be selected from this list. If "system" is selected, the interface language is determined by the system. The selection of "none" means, that the default language will be used. Layout: 0 0 Select the layout type. Sidebars Toolboxes Shell Select to get a separate shell window separate window Select to embed the shell in the Debug-Viewer embed in Debug-Viewer File-Browser Select to get a separate file browser window separate window Select to embed the file browser in the Debug-Viewer embed in Debug-Viewer Select to embed the file browser in the Project-Viewer embed in Project-Viewer Tabs Show only one close button instead of one for each tab Qt::Vertical 537 41 Reset layout to factory defaults uiBrowsersListFoldersFirstCheckBox uiBrowsersHideNonPublicCheckBox uiBrowsersSortByOccurrenceCheckBox uiBrowsersShowHiddenCheckBox fileFiltersEdit lvAutoRaiseCheckBox stderrTextColourButton uiCaptionShowsFilenameGroupBox filenameLengthSpinBox styleComboBox styleSheetEdit styleSheetButton tlTopButton tlLeftButton trTopButton trRightButton blBottomButton blLeftButton brTopButton brRightButton delaySpinBox languageComboBox layoutComboBox separateShellButton debugEmbeddedShellButton separateFileBrowserButton debugEmbeddedFileBrowserButton projectEmbeddedFileBrowserButton tabsCloseButtonCheckBox resetLayoutButton eric-6.0.8/eric/Preferences/ConfigurationPages/HelpDocumentationPage.py0000644000175000017500000001702412474352635025305 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Help Documentation configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QUrl from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_HelpDocumentationPage import Ui_HelpDocumentationPage import Preferences import Utilities import UI.PixmapCache class HelpDocumentationPage(ConfigurationPageBase, Ui_HelpDocumentationPage): """ Class implementing the Help Documentation configuration page. """ def __init__(self): """ Constructor """ super(HelpDocumentationPage, self).__init__() self.setupUi(self) self.setObjectName("HelpDocumentationPage") self.python2DocDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.pythonDocDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.qt4DocDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.qt5DocDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.pyqt4DocDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.pyqt5DocDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.pysideDocDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.python2DocDirCompleter = E5FileCompleter(self.python2DocDirEdit) self.pythonDocDirCompleter = E5FileCompleter(self.pythonDocDirEdit) self.qt4DocDirCompleter = E5FileCompleter(self.qt4DocDirEdit) self.qt5DocDirCompleter = E5FileCompleter(self.qt5DocDirEdit) self.pyqt4DocDirCompleter = E5FileCompleter(self.pyqt4DocDirEdit) self.pyqt5DocDirCompleter = E5FileCompleter(self.pyqt5DocDirEdit) self.pysideDocDirCompleter = E5FileCompleter(self.pysideDocDirEdit) try: import PyQt5 # __IGNORE_WARNING__ except ImportError: self.pyqt5Group.setEnabled(False) pyside2, pyside3 = Utilities.checkPyside() if pyside2 or pyside3: self.pysideGroup.setEnabled(True) else: self.pysideGroup.setEnabled(False) # set initial values self.python2DocDirEdit.setText( Preferences.getHelp("Python2DocDir")) self.pythonDocDirEdit.setText( Preferences.getHelp("PythonDocDir")) self.qt4DocDirEdit.setText( Preferences.getHelp("Qt4DocDir")) self.qt5DocDirEdit.setText( Preferences.getHelp("Qt5DocDir")) self.pyqt4DocDirEdit.setText( Preferences.getHelp("PyQt4DocDir")) self.pyqt5DocDirEdit.setText( Preferences.getHelp("PyQt5DocDir")) self.pysideDocDirEdit.setText( Preferences.getHelp("PySideDocDir")) def save(self): """ Public slot to save the Help Documentation configuration. """ Preferences.setHelp( "Python2DocDir", self.python2DocDirEdit.text()) Preferences.setHelp( "PythonDocDir", self.pythonDocDirEdit.text()) Preferences.setHelp( "Qt4DocDir", self.qt4DocDirEdit.text()) Preferences.setHelp( "Qt5DocDir", self.qt5DocDirEdit.text()) Preferences.setHelp( "PyQt4DocDir", self.pyqt4DocDirEdit.text()) Preferences.setHelp( "PyQt5DocDir", self.pyqt5DocDirEdit.text()) Preferences.setHelp( "PySideDocDir", self.pysideDocDirEdit.text()) @pyqtSlot() def on_python2DocDirButton_clicked(self): """ Private slot to select the Python 2 documentation directory. """ entry = E5FileDialog.getOpenFileName( self, self.tr("Select Python 2 documentation entry"), QUrl(self.python2DocDirEdit.text()).path(), self.tr( "HTML Files (*.html *.htm);;" "Compressed Help Files (*.chm);;" "All Files (*)")) if entry: self.python2DocDirEdit.setText(Utilities.toNativeSeparators(entry)) @pyqtSlot() def on_pythonDocDirButton_clicked(self): """ Private slot to select the Python 3 documentation directory. """ entry = E5FileDialog.getOpenFileName( self, self.tr("Select Python 3 documentation entry"), QUrl(self.pythonDocDirEdit.text()).path(), self.tr( "HTML Files (*.html *.htm);;" "Compressed Help Files (*.chm);;" "All Files (*)")) if entry: self.pythonDocDirEdit.setText(Utilities.toNativeSeparators(entry)) @pyqtSlot() def on_qt4DocDirButton_clicked(self): """ Private slot to select the Qt4 documentation directory. """ entry = E5FileDialog.getOpenFileName( self, self.tr("Select Qt4 documentation entry"), QUrl(self.qt4DocDirEdit.text()).path(), self.tr("HTML Files (*.html *.htm);;All Files (*)")) if entry: self.qt4DocDirEdit.setText(Utilities.toNativeSeparators(entry)) @pyqtSlot() def on_qt5DocDirButton_clicked(self): """ Private slot to select the Qt5 documentation directory. """ entry = E5FileDialog.getOpenFileName( self, self.tr("Select Qt5 documentation entry"), QUrl(self.qt5DocDirEdit.text()).path(), self.tr("HTML Files (*.html *.htm);;All Files (*)")) if entry: self.qt5DocDirEdit.setText(Utilities.toNativeSeparators(entry)) @pyqtSlot() def on_pyqt4DocDirButton_clicked(self): """ Private slot to select the PyQt5 documentation directory. """ entry = E5FileDialog.getOpenFileName( self, self.tr("Select PyQt5 documentation entry"), QUrl(self.pyqt4DocDirEdit.text()).path(), self.tr("HTML Files (*.html *.htm);;All Files (*)")) if entry: self.pyqt4DocDirEdit.setText(Utilities.toNativeSeparators(entry)) @pyqtSlot() def on_pyqt5DocDirButton_clicked(self): """ Private slot to select the PyQt5 documentation directory. """ entry = E5FileDialog.getOpenFileName( self, self.tr("Select PyQt5 documentation entry"), QUrl(self.pyqt4DocDirEdit.text()).path(), self.tr("HTML Files (*.html *.htm);;All Files (*)")) if entry: self.pyqt5DocDirEdit.setText(Utilities.toNativeSeparators(entry)) @pyqtSlot() def on_pysideDocDirButton_clicked(self): """ Private slot to select the PySide documentation directory. """ entry = E5FileDialog.getOpenFileName( self, self.tr("Select PySide documentation entry"), QUrl(self.pysideDocDirEdit.text()).path(), self.tr("HTML Files (*.html *.htm);;All Files (*)")) if entry: self.pysideDocDirEdit.setText(Utilities.toNativeSeparators(entry)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = HelpDocumentationPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/PrinterPage.py0000644000175000017500000000704412451233373023277 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Printer configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from .ConfigurationPageBase import ConfigurationPageBase from .Ui_PrinterPage import Ui_PrinterPage import Preferences class PrinterPage(ConfigurationPageBase, Ui_PrinterPage): """ Class implementing the Printer configuration page. """ def __init__(self): """ Constructor """ super(PrinterPage, self).__init__() self.setupUi(self) self.setObjectName("PrinterPage") # set initial values self.printerNameEdit.setText( Preferences.getPrinter("PrinterName")) if Preferences.getPrinter("ColorMode"): self.printerColorButton.setChecked(True) else: self.printerGrayscaleButton.setChecked(True) if Preferences.getPrinter("FirstPageFirst"): self.printFirstPageFirstButton.setChecked(True) else: self.printFirstPageLastButton.setChecked(True) self.printMagnificationSpinBox.setValue( Preferences.getPrinter("Magnification")) self.printheaderFont = Preferences.getPrinter("HeaderFont") self.printheaderFontSample.setFont(self.printheaderFont) self.leftMarginSpinBox.setValue( Preferences.getPrinter("LeftMargin")) self.rightMarginSpinBox.setValue( Preferences.getPrinter("RightMargin")) self.topMarginSpinBox.setValue( Preferences.getPrinter("TopMargin")) self.bottomMarginSpinBox.setValue( Preferences.getPrinter("BottomMargin")) def save(self): """ Public slot to save the Printer configuration. """ Preferences.setPrinter( "PrinterName", self.printerNameEdit.text()) if self.printerColorButton.isChecked(): Preferences.setPrinter("ColorMode", 1) else: Preferences.setPrinter("ColorMode", 0) if self.printFirstPageFirstButton.isChecked(): Preferences.setPrinter("FirstPageFirst", 1) else: Preferences.setPrinter("FirstPageFirst", 0) Preferences.setPrinter( "Magnification", self.printMagnificationSpinBox.value()) Preferences.setPrinter("HeaderFont", self.printheaderFont) Preferences.setPrinter( "LeftMargin", self.leftMarginSpinBox.value()) Preferences.setPrinter( "RightMargin", self.rightMarginSpinBox.value()) Preferences.setPrinter( "TopMargin", self.topMarginSpinBox.value()) Preferences.setPrinter( "BottomMargin", self.bottomMarginSpinBox.value()) @pyqtSlot() def on_printheaderFontButton_clicked(self): """ Private method used to select the font for the page header. """ self.printheaderFont = \ self.selectFont(self.printheaderFontSample, self.printheaderFont) def polishPage(self): """ Public slot to perform some polishing actions. """ self.printheaderFontSample.setFont(self.printheaderFont) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = PrinterPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/IrcPage.py0000644000175000017500000001674012451233373022374 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing the IRC configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_IrcPage import Ui_IrcPage import Preferences class IrcPage(ConfigurationPageBase, Ui_IrcPage): """ Class implementing the IRC configuration page. """ TimeFormats = ["hh:mm", "hh:mm:ss", "h:mm ap", "h:mm:ss ap"] DateFormats = ["yyyy-MM-dd", "dd.MM.yyyy", "MM/dd/yyyy", "yyyy MMM. dd", "dd MMM. yyyy", "MMM. dd, yyyy"] def __init__(self): """ Constructor """ super(IrcPage, self).__init__() self.setupUi(self) self.setObjectName("IrcPage") self.timeFormatCombo.addItems(IrcPage.TimeFormats) self.dateFormatCombo.addItems(IrcPage.DateFormats) # set initial values # timestamps self.timestampGroup.setChecked(Preferences.getIrc("ShowTimestamps")) self.showDateCheckBox.setChecked( Preferences.getIrc("TimestampIncludeDate")) self.timeFormatCombo.setCurrentIndex( self.timeFormatCombo.findText(Preferences.getIrc("TimeFormat"))) self.dateFormatCombo.setCurrentIndex( self.dateFormatCombo.findText(Preferences.getIrc("DateFormat"))) # colours self.initColour("NetworkMessageColour", self.networkButton, Preferences.getIrc, byName=True) self.initColour("ServerMessageColour", self.serverButton, Preferences.getIrc, byName=True) self.initColour("ErrorMessageColour", self.errorButton, Preferences.getIrc, byName=True) self.initColour("TimestampColour", self.timestampButton, Preferences.getIrc, byName=True) self.initColour("HyperlinkColour", self.hyperlinkButton, Preferences.getIrc, byName=True) self.initColour("ChannelMessageColour", self.channelButton, Preferences.getIrc, byName=True) self.initColour("OwnNickColour", self.ownNickButton, Preferences.getIrc, byName=True) self.initColour("NickColour", self.nickButton, Preferences.getIrc, byName=True) self.initColour("JoinChannelColour", self.joinButton, Preferences.getIrc, byName=True) self.initColour("LeaveChannelColour", self.leaveButton, Preferences.getIrc, byName=True) self.initColour("ChannelInfoColour", self.infoButton, Preferences.getIrc, byName=True) # notifications self.notificationsGroup.setChecked( Preferences.getIrc("ShowNotifications")) self.joinLeaveCheckBox.setChecked(Preferences.getIrc("NotifyJoinPart")) self.messageCheckBox.setChecked(Preferences.getIrc("NotifyMessage")) self.ownNickCheckBox.setChecked(Preferences.getIrc("NotifyNick")) # IRC text colors self.initColour("IrcColor0", self.ircColor0Button, Preferences.getIrc, byName=True) self.initColour("IrcColor1", self.ircColor1Button, Preferences.getIrc, byName=True) self.initColour("IrcColor2", self.ircColor2Button, Preferences.getIrc, byName=True) self.initColour("IrcColor3", self.ircColor3Button, Preferences.getIrc, byName=True) self.initColour("IrcColor4", self.ircColor4Button, Preferences.getIrc, byName=True) self.initColour("IrcColor5", self.ircColor5Button, Preferences.getIrc, byName=True) self.initColour("IrcColor6", self.ircColor6Button, Preferences.getIrc, byName=True) self.initColour("IrcColor7", self.ircColor7Button, Preferences.getIrc, byName=True) self.initColour("IrcColor8", self.ircColor8Button, Preferences.getIrc, byName=True) self.initColour("IrcColor9", self.ircColor9Button, Preferences.getIrc, byName=True) self.initColour("IrcColor10", self.ircColor10Button, Preferences.getIrc, byName=True) self.initColour("IrcColor11", self.ircColor11Button, Preferences.getIrc, byName=True) self.initColour("IrcColor12", self.ircColor12Button, Preferences.getIrc, byName=True) self.initColour("IrcColor13", self.ircColor13Button, Preferences.getIrc, byName=True) self.initColour("IrcColor14", self.ircColor14Button, Preferences.getIrc, byName=True) self.initColour("IrcColor15", self.ircColor15Button, Preferences.getIrc, byName=True) # Automatic User Information Lookup self.whoGroup.setChecked(Preferences.getIrc("AutoUserInfoLookup")) self.whoUsersSpinBox.setValue(Preferences.getIrc("AutoUserInfoMax")) self.whoIntervalSpinBox.setValue( Preferences.getIrc("AutoUserInfoInterval")) # Markers self.markWhenHiddenCheckBox.setChecked( Preferences.getIrc("MarkPositionWhenHidden")) self.initColour("MarkerLineForegroundColour", self.markerForegroundButton, Preferences.getIrc, byName=True) self.initColour("MarkerLineBackgroundColour", self.markerBackgroundButton, Preferences.getIrc, byName=True) # Shutdown self.confirmShutdownCheckBox.setChecked( Preferences.getIrc("AskOnShutdown")) def save(self): """ Public slot to save the IRC configuration. """ # timestamps Preferences.setIrc("ShowTimestamps", self.timestampGroup.isChecked()) Preferences.setIrc( "TimestampIncludeDate", self.showDateCheckBox.isChecked()) Preferences.setIrc("TimeFormat", self.timeFormatCombo.currentText()) Preferences.setIrc("DateFormat", self.dateFormatCombo.currentText()) # notifications Preferences.setIrc( "ShowNotifications", self.notificationsGroup.isChecked()) Preferences.setIrc( "NotifyJoinPart", self.joinLeaveCheckBox.isChecked()) Preferences.setIrc("NotifyMessage", self.messageCheckBox.isChecked()) Preferences.setIrc("NotifyNick", self.ownNickCheckBox.isChecked()) # Automatic User Information Lookup Preferences.setIrc("AutoUserInfoLookup", self.whoGroup.isChecked()) Preferences.setIrc("AutoUserInfoMax", self.whoUsersSpinBox.value()) Preferences.setIrc( "AutoUserInfoInterval", self.whoIntervalSpinBox.value()) # Markers Preferences.setIrc( "MarkPositionWhenHidden", self.markWhenHiddenCheckBox.isChecked()) # Shutdown Preferences.setIrc( "AskOnShutdown", self.confirmShutdownCheckBox.isChecked()) # colours self.saveColours(Preferences.setIrc) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = IrcPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorAutocompletionQScintillaPage.py0000644000175000017500000000501712451233373030007 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the QScintilla Autocompletion configuration page. """ from __future__ import unicode_literals from PyQt5.Qsci import QsciScintilla from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorAutocompletionQScintillaPage import \ Ui_EditorAutocompletionQScintillaPage import Preferences class EditorAutocompletionQScintillaPage( ConfigurationPageBase, Ui_EditorAutocompletionQScintillaPage): """ Class implementing the QScintilla Autocompletion configuration page. """ def __init__(self): """ Constructor """ super(EditorAutocompletionQScintillaPage, self).__init__() self.setupUi(self) self.setObjectName("EditorAutocompletionQScintillaPage") # set initial values self.acShowSingleCheckBox.setChecked( Preferences.getEditor("AutoCompletionShowSingle")) self.acFillupsCheckBox.setChecked( Preferences.getEditor("AutoCompletionFillups")) acSource = Preferences.getEditor("AutoCompletionSource") if acSource == QsciScintilla.AcsDocument: self.acSourceDocumentRadioButton.setChecked(True) elif acSource == QsciScintilla.AcsAPIs: self.acSourceAPIsRadioButton.setChecked(True) elif acSource == QsciScintilla.AcsAll: self.acSourceAllRadioButton.setChecked(True) def save(self): """ Public slot to save the Editor Autocompletion configuration. """ Preferences.setEditor( "AutoCompletionShowSingle", self.acShowSingleCheckBox.isChecked()) Preferences.setEditor( "AutoCompletionFillups", self.acFillupsCheckBox.isChecked()) if self.acSourceDocumentRadioButton.isChecked(): Preferences.setEditor( "AutoCompletionSource", QsciScintilla.AcsDocument) elif self.acSourceAPIsRadioButton.isChecked(): Preferences.setEditor( "AutoCompletionSource", QsciScintilla.AcsAPIs) elif self.acSourceAllRadioButton.isChecked(): Preferences.setEditor("AutoCompletionSource", QsciScintilla.AcsAll) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorAutocompletionQScintillaPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorTypingPage.ui0000644000175000017500000004026512244705561024267 0ustar piotrpiotr EditorTypingPage 0 0 543 531 <b>Configure typing</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Programming Language: 0 0 Select the programming language to be configured. 0 0 0 Qt::TabFocus Select to enable Python typing aids Enable Python typing aids true Select to insert a closing parenthesis Automatic parenthesis insertion Qt::Horizontal QSizePolicy::Fixed 20 20 false Select to skip matching braces when typing Automatically skip matching braces when typing Qt::Horizontal 131 21 Select to skip a ':', if typed next to another ':' Automatic colon detection Select to indent to the brace level after typing 'return' After '(' indent to its level Select to insert the matching quote character Automatic quote insertion Select to dedent 'else:' and 'elif' to the matching 'if' Automatic dedent of 'else:' and 'elif' Select to dedent 'except' and 'finally' to the matching 'try:' Automatic dedent of 'except' and 'finally' Qt::Horizontal QSizePolicy::Fixed 20 20 false Select to treat code as Python 2.4 code Python 2.4 style 'try:' blocks Qt::Horizontal 261 20 Select to insert the 'import' string Automatic insertion of the 'import' string on 'from xxx' Select to insert the 'self' string when declaring a method Automatic insertion of 'self' when declaring methods Select to insert a blank after ',' Automatic insertion of ' ' (blank) after ',' Select to dedent 'def' statements to the last 'def' or 'class' Automatic dedent of 'def' statements Qt::Vertical 507 20 0 0 Qt::TabFocus Select to enable Ruby typing aids Enable Ruby typing aids true Select to insert a closing parenthesis Automatic parenthesis insertion Select to skip matching braces when typing Automatically skip matching braces when typing Select to indent to the brace level after typing 'return' After '(' indent to its level Select to insert the matching quote character Automatic quote insertion Select to insert a blank after ',' Automatic insertion of ' ' (blank) after ',' Select to automatically complete a here document Automatic completion of here document Select to automatically insert '=end' after entering '=begin' Automatic insertion of '=end' after '=begin' Qt::Vertical 20 40 Qt::Vertical 519 20 languageCombo pythonGroup pythonInsertClosingBraceCheckBox pythonSkipBraceCheckBox pythonColonDetectionCheckBox pythonIndentBraceCheckBox pythonInsertQuoteCheckBox pythonDedentElseCheckBox pythonDedentExceptCheckBox pythonDedentExceptPy24CheckBox pythonInsertImportCheckBox pythonInsertSelfCheckBox pythonInsertBlankCheckBox pythonDedentDefCheckBox rubyGroup rubyInsertClosingBraceCheckBox rubySkipBraceCheckBox rubyIndentBraceCheckBox rubyInsertQuoteCheckBox rubyInsertBlankCheckBox rubyInsertHereDocCheckBox rubyInsertInlineDocCheckBox pythonInsertClosingBraceCheckBox toggled(bool) pythonSkipBraceCheckBox setEnabled(bool) 99 114 116 144 pythonInsertClosingBraceCheckBox toggled(bool) pythonSkipBraceCheckBox setChecked(bool) 196 114 198 137 pythonDedentExceptCheckBox toggled(bool) pythonDedentExceptPy24CheckBox setEnabled(bool) 69 279 80 305 eric-6.0.8/eric/Preferences/ConfigurationPages/TasksPage.py0000644000175000017500000000473712451233373022747 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Tasks configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_TasksPage import Ui_TasksPage import Preferences class TasksPage(ConfigurationPageBase, Ui_TasksPage): """ Class implementing the Tasks configuration page. """ def __init__(self): """ Constructor """ super(TasksPage, self).__init__() self.setupUi(self) self.setObjectName("TasksPage") # set initial values self.tasksMarkerFixmeEdit.setText( Preferences.getTasks("TasksFixmeMarkers")) self.tasksMarkerWarningEdit.setText( Preferences.getTasks("TasksWarningMarkers")) self.tasksMarkerTodoEdit.setText( Preferences.getTasks("TasksTodoMarkers")) self.tasksMarkerNoteEdit.setText( Preferences.getTasks("TasksNoteMarkers")) self.initColour( "TasksFixmeColor", self.tasksFixmeColourButton, Preferences.getTasks) self.initColour( "TasksWarningColor", self.tasksWarningColourButton, Preferences.getTasks) self.initColour( "TasksTodoColor", self.tasksTodoColourButton, Preferences.getTasks) self.initColour( "TasksNoteColor", self.tasksNoteColourButton, Preferences.getTasks) self.clearCheckBox.setChecked(Preferences.getTasks("ClearOnFileClose")) def save(self): """ Public slot to save the Tasks configuration. """ Preferences.setTasks( "TasksFixmeMarkers", self.tasksMarkerFixmeEdit.text()) Preferences.setTasks( "TasksWarningMarkers", self.tasksMarkerWarningEdit.text()) Preferences.setTasks( "TasksTodoMarkers", self.tasksMarkerTodoEdit.text()) Preferences.setTasks( "TasksNoteMarkers", self.tasksMarkerNoteEdit.text()) Preferences.setTasks( "ClearOnFileClose", self.clearCheckBox.isChecked()) self.saveColours(Preferences.setTasks) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = TasksPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorExportersPage.ui0000644000175000017500000004511412244707111024777 0ustar piotrpiotr EditorExportersPage 0 0 537 531 <b>Configure exporters</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Exporter Type: 0 0 Select the exporter to be configured. 0 0 0 Select to export in WYSIWYG mode Use WYSIWYG mode Select to include folding functionality Include folding functionality Select to include only used styles Include only used styles Select to use the full pathname as the document title Use full pathname as document title Select to use tabs in the generated file Use tabs Qt::Vertical 507 21 0 0 Select to export in WYSIWYG mode Use WYSIWYG mode Select to include only used styles Include only used styles Select to use tabs in the generated file Use tabs Qt::Vertical 498 136 0 0 Magnification: Select the magnification value to be added to the font sizes of the styles 20 Qt::Horizontal Displays the selected magnification value 2 QLCDNumber::Flat Font: Select the font from the list Pagesize: Select the page size from the list Margins Select the top margin in points (72 pt == 1") 288 Select the left margin in points (72 pt == 1") 288 Select the right margin in points (72 pt == 1") 288 Select the bottom margin in points (72 pt == 1") 288 Qt::Horizontal 40 20 Qt::Vertical 20 21 0 0 Select to export in WYSIWYG mode Use WYSIWYG mode Press to select the font for the RTF export Select Font Qt::NoFocus Font for RTF export Qt::AlignHCenter true Select to use tabs in the generated file Use tabs Qt::Vertical 451 21 0 0 Select to include only used styles Include only used styles Select to use the full pathname as the document title Use full pathname as document title Qt::Vertical 507 21 Qt::Vertical 519 21 exportersCombo htmlWysiwygCheckBox htmlFoldingCheckBox htmlStylesCheckBox htmlTitleCheckBox htmlTabsCheckBox odtWysiwygCheckBox odtStylesCheckBox odtTabsCheckBox pdfMagnificationSlider pdfFontCombo pdfPageSizeCombo pdfMarginTopSpin pdfMarginLeftSpin pdfMarginRightSpin pdfMarginBottomSpin rtfWysiwygCheckBox rtfFontButton rtfTabsCheckBox texStylesCheckBox texTitleCheckBox rtfWysiwygCheckBox toggled(bool) rtfFontButton setDisabled(bool) 57 83 59 117 rtfWysiwygCheckBox toggled(bool) rtfFontSample setDisabled(bool) 216 86 217 115 pdfMagnificationSlider sliderMoved(int) pdfMagnificationLCD display(int) 174 86 331 91 pdfMagnificationSlider valueChanged(int) pdfMagnificationLCD display(int) 140 87 332 96 eric-6.0.8/eric/Preferences/ConfigurationPages/GraphicsPage.py0000644000175000017500000000330512451233373023410 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Printer configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from .ConfigurationPageBase import ConfigurationPageBase from .Ui_GraphicsPage import Ui_GraphicsPage import Preferences class GraphicsPage(ConfigurationPageBase, Ui_GraphicsPage): """ Class implementing the Printer configuration page. """ def __init__(self): """ Constructor """ super(GraphicsPage, self).__init__() self.setupUi(self) self.setObjectName("GraphicsPage") # set initial values self.graphicsFont = Preferences.getGraphics("Font") self.graphicsFontSample.setFont(self.graphicsFont) def save(self): """ Public slot to save the Printer configuration. """ Preferences.setGraphics("Font", self.graphicsFont) @pyqtSlot() def on_graphicsFontButton_clicked(self): """ Private method used to select the font for the graphics items. """ self.graphicsFont = self.selectFont(self.graphicsFontSample, self.graphicsFont) def polishPage(self): """ Public slot to perform some polishing actions. """ self.graphicsFontSample.setFont(self.graphicsFont) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = GraphicsPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/DebuggerGeneralPage.ui0000644000175000017500000006227412445005221024661 0ustar piotrpiotr DebuggerGeneralPage 0 0 643 1600 <b>Configure general debugger settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Network Interface <font color="#FF0000"><b>Note:</b> These settings are activated at the next startup of the application.</font> Select to listen on all available network interfaces (IPv4 mode) All network interfaces (IPv4) Select to listen on all available network interfaces (IPv6 mode) All network interfaces (IPv6) Select to listen on the configured interface Only selected interface false Select the network interface to listen on Allowed hosts Qt::Vertical 20 40 false Delete false Edit... Add... 0 0 Passive Debugger <font color="#FF0000"><b>Note:</b> These settings are activated at the next startup of the application.</font> Enables the passive debug mode <b>Passive Debugger Enabled</b> <p>This enables the passive debugging mode. In this mode the debug client (the script) connects to the debug server (the IDE). The script is started outside the IDE. This way mod_python or Zope scripts can be debugged.</p> Passive Debugger Enabled false Debug Server Port: false Enter the port the debugger should listen on <b>Debug Server Port</b> <p>Enter the port the debugger should listen on.</p> 1024 65535 42424 Qt::Horizontal 91 20 false Debugger Type: false Select the debugger type of the backend Qt::Horizontal 91 20 Remote Debugger false Remote Execution: execLineEdit false Enter the remote execution command. <b>Remote Execution</b> <p>Enter the remote execution command (e.g. ssh). This command is used to log into the remote host and execute the remote debugger.</p> false Enter the hostname of the remote machine. <b>Remote Host</b> <p>Enter the hostname of the remote machine.</p> false Remote Host: hostLineEdit Enable remote debugging This enables the remote debugger. Please enter the hostname of the remote machine and the command for the remote execution (e.g. ssh) below. Remote Debugging Enabled Path Translation Select to perform path translation Perform Path Translation false Local Path: false Enter the local path false Enter the remote path false Remote Path: Console Debugger Enter the console command (e.g. xterm -e) <b>Console Command</b> <p>Enter the console command (e.g. xterm -e). This command is used to open a command window for the debugger.</p> Console Command: Select to start the debugger in a console window (e.g. xterm) Start debugger in console window Environment for Debug Client Select, if the environment should be replaced. <b>Replace Environment</b> <p>If this entry is checked, the environment of the debugger will be replaced by the entries of the environment variables field. If it is unchecked, the environment will be ammended by these settings.</p> Replace Environment Environment: Enter the environment variables to be set. <b>Environment</b> <p>Enter the environment variables to be set for the debugger. The individual settings must be separate by whitespace and be given in the form 'var=value'.</p> <p>Example: var1=1 var2="hello world"</p> Start Debugging Select, whether changed scripts should be saved upon a debug, run, ... action. Autosave changed scripts Debug Client Exit Select, whether a reset of the debug client should be performed after a client exit Automatic Reset after Client Exit Select to suppress the client exit dialog for a clean exit Don't show client exit dialog for a clean exit Breakpoints Select to change the breakpoint toggle order from Off->On->Off to Off->On (permanent)->On (temporary)->Off Three state breakpoint Exceptions Select to always break at exceptions Always break at exceptions Select to show exception information in the shell window Show exceptions in Shell Local Variables Viewer Automatically view source code when user changes the callstack frame in the callstack viewer. Automatically view source code Qt::Vertical 20 28 allInterfacesButton all6InterfacesButton selectedInterfaceButton interfacesCombo allowedHostsList addAllowedHostButton editAllowedHostButton deleteAllowedHostButton passiveDbgCheckBox passiveDbgPortSpinBox passiveDbgBackendCombo remoteCheckBox hostLineEdit execLineEdit dbgPathTranslationCheckBox dbgTranslationRemoteEdit dbgTranslationLocalEdit consoleDbgCheckBox consoleDbgEdit debugEnvironReplaceCheckBox debugEnvironEdit debugAutoSaveScriptsCheckBox automaticResetCheckBox dontShowClientExitCheckBox debugThreeStateBreakPoint exceptionBreakCheckBox exceptionShellCheckBox autoViewSourcecodeCheckBox passiveDbgCheckBox toggled(bool) passiveDbgPortLabel setEnabled(bool) 121 467 107 498 passiveDbgCheckBox toggled(bool) passiveDbgPortSpinBox setEnabled(bool) 219 467 205 498 remoteCheckBox toggled(bool) execLineEdit setEnabled(bool) 294 568 587 630 remoteCheckBox toggled(bool) execLabel setEnabled(bool) 160 568 128 630 remoteCheckBox toggled(bool) hostLabel setEnabled(bool) 147 568 86 599 remoteCheckBox toggled(bool) hostLineEdit setEnabled(bool) 263 568 587 599 selectedInterfaceButton toggled(bool) interfacesCombo setEnabled(bool) 587 107 307 137 passiveDbgCheckBox toggled(bool) label setEnabled(bool) 78 467 410 498 passiveDbgCheckBox toggled(bool) passiveDbgBackendCombo setEnabled(bool) 257 467 484 497 dbgPathTranslationCheckBox toggled(bool) dbgTranslationRemoteEdit setEnabled(bool) 74 700 241 731 dbgPathTranslationCheckBox toggled(bool) textLabel1_18 setEnabled(bool) 54 700 56 731 dbgPathTranslationCheckBox toggled(bool) textLabel2_9 setEnabled(bool) 104 700 89 762 dbgPathTranslationCheckBox toggled(bool) dbgTranslationLocalEdit setEnabled(bool) 273 700 353 762 eric-6.0.8/eric/Preferences/ConfigurationPages/HelpViewersPage.py0000644000175000017500000001032212451233373024102 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Help Viewers configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QButtonGroup from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_HelpViewersPage import Ui_HelpViewersPage import Preferences import Utilities import UI.PixmapCache class HelpViewersPage(ConfigurationPageBase, Ui_HelpViewersPage): """ Class implementing the Help Viewers configuration page. """ def __init__(self): """ Constructor """ super(HelpViewersPage, self).__init__() self.setupUi(self) self.setObjectName("HelpViewersPage") self.customViewerSelectionButton.setIcon( UI.PixmapCache.getIcon("open.png")) self.helpViewerGroup = QButtonGroup() self.helpViewerGroup.addButton(self.helpBrowserButton) self.helpViewerGroup.addButton(self.qtAssistantButton) self.helpViewerGroup.addButton(self.webBrowserButton) self.helpViewerGroup.addButton(self.customViewerButton) self.customViewerCompleter = E5FileCompleter(self.customViewerEdit) # set initial values hvId = Preferences.getHelp("HelpViewerType") if hvId == 1: self.helpBrowserButton.setChecked(True) elif hvId == 2: self.qtAssistantButton.setChecked(True) elif hvId == 3: self.webBrowserButton.setChecked(True) else: self.customViewerButton.setChecked(True) self.customViewerEdit.setText( Preferences.getHelp("CustomViewer")) def save(self): """ Public slot to save the Help Viewers configuration. """ if self.helpBrowserButton.isChecked(): hvId = 1 elif self.qtAssistantButton.isChecked(): hvId = 2 elif self.webBrowserButton.isChecked(): hvId = 3 elif self.customViewerButton.isChecked(): hvId = 4 Preferences.setHelp("HelpViewerType", hvId) Preferences.setHelp( "CustomViewer", self.customViewerEdit.text()) @pyqtSlot() def on_customViewerSelectionButton_clicked(self): """ Private slot to handle the custom viewer selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select Custom Viewer"), self.customViewerEdit.text(), "") if file: self.customViewerEdit.setText(Utilities.toNativeSeparators(file)) @pyqtSlot() def on_webbrowserButton_clicked(self): """ Private slot to handle the Web browser selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select Web-Browser"), self.webbrowserEdit.text(), "") if file: self.webbrowserEdit.setText(Utilities.toNativeSeparators(file)) @pyqtSlot() def on_pdfviewerButton_clicked(self): """ Private slot to handle the PDF viewer selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select PDF-Viewer"), self.pdfviewerEdit.text(), "") if file: self.pdfviewerEdit.setText(Utilities.toNativeSeparators(file)) @pyqtSlot() def on_chmviewerButton_clicked(self): """ Private slot to handle the CHM viewer selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select CHM-Viewer"), self.chmviewerEdit.text(), "") if file: self.chmviewerEdit.setText(Utilities.toNativeSeparators(file)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = HelpViewersPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/ApplicationPage.py0000644000175000017500000000745312451233373024123 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Application configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_ApplicationPage import Ui_ApplicationPage import Preferences class ApplicationPage(ConfigurationPageBase, Ui_ApplicationPage): """ Class implementing the Application configuration page. """ def __init__(self): """ Constructor """ super(ApplicationPage, self).__init__() self.setupUi(self) self.setObjectName("ApplicationPage") # set initial values self.singleApplicationCheckBox.setChecked( Preferences.getUI("SingleApplicationMode")) self.splashScreenCheckBox.setChecked( Preferences.getUI("ShowSplash")) openOnStartup = Preferences.getUI("OpenOnStartup") if openOnStartup == 0: self.noOpenRadioButton.setChecked(True) elif openOnStartup == 1: self.lastFileRadioButton.setChecked(True) elif openOnStartup == 2: self.lastProjectRadioButton.setChecked(True) elif openOnStartup == 3: self.lastMultiprojectRadioButton.setChecked(True) elif openOnStartup == 4: self.globalSessionRadioButton.setChecked(True) period = Preferences.getUI("PerformVersionCheck") if period == 0: self.noCheckRadioButton.setChecked(True) elif period == 1: self.alwaysCheckRadioButton.setChecked(True) elif period == 2: self.dailyCheckRadioButton.setChecked(True) elif period == 3: self.weeklyCheckRadioButton.setChecked(True) elif period == 4: self.monthlyCheckRadioButton.setChecked(True) self.systemEmailClientCheckBox.setChecked( Preferences.getUser("UseSystemEmailClient")) self.errorlogCheckBox.setChecked( Preferences.getUI("CheckErrorLog")) def save(self): """ Public slot to save the Application configuration. """ Preferences.setUI( "SingleApplicationMode", self.singleApplicationCheckBox.isChecked()) Preferences.setUI( "ShowSplash", self.splashScreenCheckBox.isChecked()) if self.noOpenRadioButton.isChecked(): openOnStartup = 0 elif self.lastFileRadioButton.isChecked(): openOnStartup = 1 elif self.lastProjectRadioButton.isChecked(): openOnStartup = 2 elif self.lastMultiprojectRadioButton.isChecked(): openOnStartup = 3 elif self.globalSessionRadioButton.isChecked(): openOnStartup = 4 Preferences.setUI("OpenOnStartup", openOnStartup) if self.noCheckRadioButton.isChecked(): period = 0 elif self.alwaysCheckRadioButton.isChecked(): period = 1 elif self.dailyCheckRadioButton.isChecked(): period = 2 elif self.weeklyCheckRadioButton.isChecked(): period = 3 elif self.monthlyCheckRadioButton.isChecked(): period = 4 Preferences.setUI("PerformVersionCheck", period) Preferences.setUser( "UseSystemEmailClient", self.systemEmailClientCheckBox.isChecked()) Preferences.setUI( "CheckErrorLog", self.errorlogCheckBox.isChecked()) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = ApplicationPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/ConfigurationPageBase.py0000644000175000017500000000774712451233373025270 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the base class for all configuration pages. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QIcon, QPixmap, QColor from PyQt5.QtWidgets import QWidget, QColorDialog, QFontDialog class ConfigurationPageBase(QWidget): """ Class implementing the base class for all configuration pages. """ def __init__(self): """ Constructor """ super(ConfigurationPageBase, self).__init__() self.__coloursDict = {} def polishPage(self): """ Public slot to perform some polishing actions. """ return def saveState(self): """ Public method to save the current state of the widget. """ return def setState(self, state): """ Public method to set the state of the widget. @param state state data generated by saveState """ return def initColour(self, colourKey, button, prefMethod, byName=False, hasAlpha=False): """ Public method to initialize a colour selection button. @param colourKey key of the colour resource (string) @param button reference to a button to show the colour on (QPushButton) @param prefMethod preferences method to get the colour @keyparam byName flag indicating to retrieve/save by colour name (boolean) @keyparam hasAlpha flag indicating to allow alpha channel (boolean) """ colour = QColor(prefMethod(colourKey)) size = button.size() pm = QPixmap(size.width() / 2, size.height() / 2) pm.fill(colour) button.setIconSize(pm.size()) button.setIcon(QIcon(pm)) button.setProperty("colorKey", colourKey) button.setProperty("hasAlpha", hasAlpha) button.clicked.connect(self.__selectColourSlot) self.__coloursDict[colourKey] = [colour, byName] @pyqtSlot() def __selectColourSlot(self): """ Private slot to select a color. """ button = self.sender() colorKey = button.property("colorKey") hasAlpha = button.property("hasAlpha") if hasAlpha: colour = QColorDialog.getColor( self.__coloursDict[colorKey][0], None, "", QColorDialog.ShowAlphaChannel) else: colour = QColorDialog.getColor(self.__coloursDict[colorKey][0]) if colour.isValid(): size = button.iconSize() pm = QPixmap(size.width(), size.height()) pm.fill(colour) button.setIcon(QIcon(pm)) self.__coloursDict[colorKey][0] = colour def saveColours(self, prefMethod): """ Public method to save the colour selections. @param prefMethod preferences method to set the colour """ for key in self.__coloursDict: if self.__coloursDict[key][1]: prefMethod(key, self.__coloursDict[key][0].name()) else: prefMethod(key, self.__coloursDict[key][0]) def selectFont(self, fontSample, fontVar, showFontInfo=False): """ Public method used by the font selection buttons. @param fontSample reference to the font sample widget (QLineEdit) @param fontVar reference to the variable containing the font (QFont) @param showFontInfo flag indicating to show some font info as the sample (boolean) @return selected font (QFont) """ font, ok = QFontDialog.getFont(fontVar) if ok: fontSample.setFont(font) if showFontInfo: fontSample.setText( "{0} {1}".format(font.family(), font.pointSize())) else: font = fontVar return font eric-6.0.8/eric/Preferences/ConfigurationPages/EditorAPIsPage.py0000644000175000017500000002555612451233373023627 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor APIs configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import QDir, pyqtSlot, QFileInfo from PyQt5.QtWidgets import QInputDialog from E5Gui.E5Application import e5App from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog, E5MessageBox from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorAPIsPage import Ui_EditorAPIsPage import Preferences import Utilities import UI.PixmapCache class EditorAPIsPage(ConfigurationPageBase, Ui_EditorAPIsPage): """ Class implementing the Editor APIs configuration page. """ def __init__(self): """ Constructor """ super(EditorAPIsPage, self).__init__() self.setupUi(self) self.setObjectName("EditorAPIsPage") self.apiFileButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.prepareApiButton.setText(self.tr("Compile APIs")) self.__currentAPI = None self.__inPreparation = False self.apiFileCompleter = E5FileCompleter(self.apiFileEdit) # set initial values self.pluginManager = e5App().getObject("PluginManager") self.apiAutoPrepareCheckBox.setChecked( Preferences.getEditor("AutoPrepareAPIs")) import QScintilla.Lexers self.apis = {} apiLanguages = sorted( [''] + list(QScintilla.Lexers.getSupportedLanguages().keys())) for lang in apiLanguages: if lang != "Guessed": self.apiLanguageComboBox.addItem(lang) self.currentApiLanguage = '' self.on_apiLanguageComboBox_activated(self.currentApiLanguage) for lang in apiLanguages[1:]: self.apis[lang] = Preferences.getEditorAPI(lang)[:] def save(self): """ Public slot to save the Editor APIs configuration. """ Preferences.setEditor( "AutoPrepareAPIs", self.apiAutoPrepareCheckBox.isChecked()) lang = self.apiLanguageComboBox.currentText() self.apis[lang] = self.__editorGetApisFromApiList() for lang, apis in list(self.apis.items()): Preferences.setEditorAPI(lang, apis) @pyqtSlot(str) def on_apiLanguageComboBox_activated(self, language): """ Private slot to fill the api listbox of the api page. @param language selected API language (string) """ if self.currentApiLanguage == language: return self.apis[self.currentApiLanguage] = self.__editorGetApisFromApiList() self.currentApiLanguage = language self.apiList.clear() if not language: self.apiGroup.setEnabled(False) return self.apiGroup.setEnabled(True) self.deleteApiFileButton.setEnabled(False) self.addApiFileButton.setEnabled(False) self.apiFileEdit.clear() for api in self.apis[self.currentApiLanguage]: if api: self.apiList.addItem(api) self.prepareApiButton.setEnabled(self.apiList.count() > 0) from QScintilla.APIsManager import APIsManager self.__currentAPI = APIsManager().getAPIs(self.currentApiLanguage) if self.__currentAPI is not None: self.__currentAPI.apiPreparationFinished.connect( self.__apiPreparationFinished) self.__currentAPI.apiPreparationCancelled.connect( self.__apiPreparationCancelled) self.__currentAPI.apiPreparationStarted.connect( self.__apiPreparationStarted) self.addInstalledApiFileButton.setEnabled( len(self.__currentAPI.installedAPIFiles()) > 0) else: self.addInstalledApiFileButton.setEnabled(False) self.addPluginApiFileButton.setEnabled( len(self.pluginManager.getPluginApiFiles(self.currentApiLanguage)) > 0) def __editorGetApisFromApiList(self): """ Private slot to retrieve the api filenames from the list. @return list of api filenames (list of strings) """ apis = [] for row in range(self.apiList.count()): apis.append(self.apiList.item(row).text()) return apis @pyqtSlot() def on_apiFileButton_clicked(self): """ Private method to select an api file. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select API file"), self.apiFileEdit.text(), self.tr("API File (*.api);;All Files (*)")) if file: self.apiFileEdit.setText(Utilities.toNativeSeparators(file)) @pyqtSlot() def on_addApiFileButton_clicked(self): """ Private slot to add the api file displayed to the listbox. """ file = self.apiFileEdit.text() if file: self.apiList.addItem(Utilities.toNativeSeparators(file)) self.apiFileEdit.clear() self.prepareApiButton.setEnabled(self.apiList.count() > 0) @pyqtSlot() def on_deleteApiFileButton_clicked(self): """ Private slot to delete the currently selected file of the listbox. """ crow = self.apiList.currentRow() if crow >= 0: itm = self.apiList.takeItem(crow) del itm self.prepareApiButton.setEnabled(self.apiList.count() > 0) @pyqtSlot() def on_addInstalledApiFileButton_clicked(self): """ Private slot to add an API file from the list of installed API files for the selected lexer language. """ installedAPIFiles = self.__currentAPI.installedAPIFiles() if installedAPIFiles: installedAPIFilesPath = QFileInfo(installedAPIFiles[0]).path() installedAPIFilesShort = [] for installedAPIFile in installedAPIFiles: installedAPIFilesShort.append( QFileInfo(installedAPIFile).fileName()) file, ok = QInputDialog.getItem( self, self.tr("Add from installed APIs"), self.tr("Select from the list of installed API files"), installedAPIFilesShort, 0, False) if ok: self.apiList.addItem(Utilities.toNativeSeparators( QFileInfo(QDir(installedAPIFilesPath), file) .absoluteFilePath())) else: E5MessageBox.warning( self, self.tr("Add from installed APIs"), self.tr("""There are no APIs installed yet.""" """ Selection is not available.""")) self.addInstalledApiFileButton.setEnabled(False) self.prepareApiButton.setEnabled(self.apiList.count() > 0) @pyqtSlot() def on_addPluginApiFileButton_clicked(self): """ Private slot to add an API file from the list of API files installed by plugins for the selected lexer language. """ pluginAPIFiles = self.pluginManager.getPluginApiFiles( self.currentApiLanguage) pluginAPIFilesDict = {} for apiFile in pluginAPIFiles: pluginAPIFilesDict[QFileInfo(apiFile).fileName()] = apiFile file, ok = QInputDialog.getItem( self, self.tr("Add from Plugin APIs"), self.tr( "Select from the list of API files installed by plugins"), sorted(pluginAPIFilesDict.keys()), 0, False) if ok: self.apiList.addItem(Utilities.toNativeSeparators( pluginAPIFilesDict[file])) self.prepareApiButton.setEnabled(self.apiList.count() > 0) @pyqtSlot() def on_prepareApiButton_clicked(self): """ Private slot to prepare the API file for the currently selected language. """ if self.__inPreparation: self.__currentAPI and self.__currentAPI.cancelPreparation() else: if self.__currentAPI is not None: self.__currentAPI.prepareAPIs( ondemand=True, rawList=self.__editorGetApisFromApiList()) def __apiPreparationFinished(self): """ Private method called after the API preparation has finished. """ self.prepareApiProgressBar.reset() self.prepareApiProgressBar.setRange(0, 100) self.prepareApiProgressBar.setValue(0) self.prepareApiButton.setText(self.tr("Compile APIs")) self.__inPreparation = False def __apiPreparationCancelled(self): """ Private slot called after the API preparation has been cancelled. """ self.__apiPreparationFinished() def __apiPreparationStarted(self): """ Private method called after the API preparation has started. """ self.prepareApiProgressBar.setRange(0, 0) self.prepareApiProgressBar.setValue(0) self.prepareApiButton.setText(self.tr("Cancel compilation")) self.__inPreparation = True def saveState(self): """ Public method to save the current state of the widget. @return index of the selected lexer language (integer) """ return self.apiLanguageComboBox.currentIndex() def setState(self, state): """ Public method to set the state of the widget. @param state state data generated by saveState """ self.apiLanguageComboBox.setCurrentIndex(state) self.on_apiLanguageComboBox_activated( self.apiLanguageComboBox.currentText()) @pyqtSlot() def on_apiList_itemSelectionChanged(self): """ Private slot to react on changes of API selections. """ self.deleteApiFileButton.setEnabled( len(self.apiList.selectedItems()) > 0) @pyqtSlot(str) def on_apiFileEdit_textChanged(self, txt): """ Private slot to handle the entering of an API file name. @param txt text of the line edit (string) """ enable = txt != "" if enable: # check for already added file for row in range(self.apiList.count()): if txt == self.apiList.item(row).text(): enable = False break self.addApiFileButton.setEnabled(enable) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorAPIsPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/HelpVirusTotalPage.py0000644000175000017500000000702512451233373024600 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing HelpVirusTotalPage. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from .ConfigurationPageBase import ConfigurationPageBase from .Ui_HelpVirusTotalPage import Ui_HelpVirusTotalPage import Preferences class HelpVirusTotalPage(ConfigurationPageBase, Ui_HelpVirusTotalPage): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(HelpVirusTotalPage, self).__init__() self.setupUi(self) self.setObjectName("HelpVirusTotalPage") self.testResultLabel.setHidden(True) from Helpviewer.VirusTotalApi import VirusTotalAPI self.__vt = VirusTotalAPI(self) self.__vt.checkServiceKeyFinished.connect( self.__checkServiceKeyFinished) # set initial values self.vtEnabledCheckBox.setChecked( Preferences.getHelp("VirusTotalEnabled")) self.vtSecureCheckBox.setChecked( Preferences.getHelp("VirusTotalSecure")) self.vtServiceKeyEdit.setText( Preferences.getHelp("VirusTotalServiceKey")) def save(self): """ Public slot to save the VirusTotal configuration. """ Preferences.setHelp( "VirusTotalEnabled", self.vtEnabledCheckBox.isChecked()) Preferences.setHelp( "VirusTotalSecure", self.vtSecureCheckBox.isChecked()) Preferences.setHelp( "VirusTotalServiceKey", self.vtServiceKeyEdit.text()) @pyqtSlot(str) def on_vtServiceKeyEdit_textChanged(self, txt): """ Private slot to handle changes of the service key. @param txt entered service key (string) """ self.testButton.setEnabled(txt != "") @pyqtSlot() def on_testButton_clicked(self): """ Private slot to test the entered service key. """ self.testResultLabel.setHidden(False) self.testResultLabel.setText( self.tr("Checking validity of the service key...")) if self.vtSecureCheckBox.isChecked(): protocol = "https" else: protocol = "http" self.__vt.checkServiceKeyValidity( self.vtServiceKeyEdit.text(), protocol) @pyqtSlot(bool, str) def __checkServiceKeyFinished(self, result, msg): """ Private slot to receive the result of the service key check. @param result flag indicating a successful check (boolean) @param msg network error message (str) """ if result: self.testResultLabel.setText( self.tr("The service key is valid.")) else: if msg == "": self.testResultLabel.setText(self.tr( 'The service key is' ' not valid.')) else: self.testResultLabel.setText(self.tr( 'Error: {0}') .format(msg)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = HelpVirusTotalPage(dlg) return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorKeywordsPage.py0000644000175000017500000001056312451233373024632 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the editor highlighter keywords configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorKeywordsPage import Ui_EditorKeywordsPage import Preferences class EditorKeywordsPage(ConfigurationPageBase, Ui_EditorKeywordsPage): """ Class implementing the editor highlighter keywords configuration page. """ def __init__(self): """ Constructor """ super(EditorKeywordsPage, self).__init__() self.setupUi(self) self.setObjectName("EditorKeywordsPage") # set initial values import QScintilla.Lexers from QScintilla.Lexers.LexerContainer import LexerContainer self.__keywords = { "": ["", "", "", "", "", "", "", "", "", ""] } self.__maxKeywordSets = { "": 0 } languages = sorted( [''] + list(QScintilla.Lexers.getSupportedLanguages().keys())) for lang in languages: if lang: lex = QScintilla.Lexers.getLexer(lang) if isinstance(lex, LexerContainer): continue keywords = Preferences.getEditorKeywords(lang)[:] if not keywords: keywords = [""] for kwSet in range(1, 10): kw = lex.keywords(kwSet) if kw is None: kw = "" keywords.append(kw) self.__keywords[lang] = keywords self.__maxKeywordSets[lang] = lex.maximumKeywordSet() self.languageCombo.addItem(lang) self.currentLanguage = '' self.currentSet = 1 self.on_languageCombo_activated(self.currentLanguage) def save(self): """ Public slot to save the editor highlighter keywords configuration. """ lang = self.languageCombo.currentText() kwSet = self.setSpinBox.value() self.__keywords[lang][kwSet] = self.keywordsEdit.toPlainText() for lang, keywords in self.__keywords.items(): Preferences.setEditorKeywords(lang, keywords) @pyqtSlot(str) def on_languageCombo_activated(self, language): """ Private slot to fill the keywords edit. @param language selected language (string) """ if self.currentLanguage == language: return if self.setSpinBox.value() == 1: self.on_setSpinBox_valueChanged(1) if self.__maxKeywordSets[language]: first = 1 last = self.__maxKeywordSets[language] else: first, last = 10, 0 for kwSet in range(1, 10): if self.__keywords[language][kwSet] != "": first = min(first, kwSet) last = max(last, kwSet) self.setSpinBox.setEnabled(language != "" and first < 10) self.keywordsEdit.setEnabled(language != "" and first < 10) if first < 10: self.setSpinBox.setMinimum(first) self.setSpinBox.setMaximum(last) self.setSpinBox.setValue(first) else: self.setSpinBox.setMinimum(0) self.setSpinBox.setMaximum(0) self.setSpinBox.setValue(0) @pyqtSlot(int) def on_setSpinBox_valueChanged(self, kwSet): """ Private slot to fill the keywords edit. @param kwSet number of the selected keyword set (integer) """ language = self.languageCombo.currentText() if self.currentLanguage == language and self.currentSet == kwSet: return self.__keywords[self.currentLanguage][self.currentSet] = \ self.keywordsEdit.toPlainText() self.currentLanguage = language self.currentSet = kwSet self.keywordsEdit.setPlainText(self.__keywords[language][kwSet]) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorKeywordsPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/CooperationPage.ui0000644000175000017500000001657712060166053024132 0ustar piotrpiotr CooperationPage 0 0 508 540 <b>Configure cooperation settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Server Select to start the server automatically Start server automatically Server Port: Enter the port number to listen on 1025 65535 1 42000 Qt::Horizontal 326 20 Select to incrementally try other ports for the server Try other ports for server false No. ports to try: false Enter the maximum number of additional ports to try 10 1000 Qt::Horizontal 326 20 Connections Select to accept incomming connections automatically Accept connections automatically Banned Users QAbstractItemView::ExtendedSelection true false Delete the selected entries from the list of banned users Delete Enter the user and host of the banned user false Add the user to the list of banned users Add autostartCheckBox serverPortSpin otherPortsCheckBox portToTrySpin autoAcceptCheckBox bannedUsersList deleteBannedUsersButton bannedUserEdit addBannedUserButton otherPortsCheckBox toggled(bool) label_2 setEnabled(bool) 54 140 51 169 otherPortsCheckBox toggled(bool) portToTrySpin setEnabled(bool) 142 140 161 169 eric-6.0.8/eric/Preferences/ConfigurationPages/IconsPreviewDialog.py0000644000175000017500000000203112451233373024603 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog to preview the contents of an icon directory. """ from __future__ import unicode_literals import os.path from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QListWidgetItem, QDialog from PyQt5.QtCore import QDir from .Ui_IconsPreviewDialog import Ui_IconsPreviewDialog class IconsPreviewDialog(QDialog, Ui_IconsPreviewDialog): """ Class implementing a dialog to preview the contents of an icon directory. """ def __init__(self, parent, dirName): """ Constructor @param parent parent widget (QWidget) @param dirName name of directory to show (string) """ super(IconsPreviewDialog, self).__init__(parent) self.setupUi(self) dir = QDir(dirName) for icon in dir.entryList(["*.png"]): QListWidgetItem( QIcon(os.path.join(dirName, icon)), icon, self.iconView) eric-6.0.8/eric/Preferences/ConfigurationPages/PrinterPage.ui0000644000175000017500000002162212060166053023256 0ustar piotrpiotr PrinterPage 0 0 446 568 <b>Configure printer settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal QFrame::NoFrame 0 Colour Gray Scale QFrame::NoFrame 6 0 First Page First Last Page First Printername: Magnification: Qt::NoFocus Header Font Qt::AlignHCenter true Press to select the font for the page headers Header Font -10 10 -3 Colour Mode: Qt::AlignTop Page Order: Qt::AlignTop Qt::Horizontal 251 20 Margins Enter the top margin in cm. cm 1 9.900000000000000 0.500000000000000 Enter the left margin in cm. cm 1 9.900000000000000 0.500000000000000 Enter the right margin in cm. cm 1 9.900000000000000 0.500000000000000 Enter the bottom margin in cm. cm 1 9.900000000000000 0.500000000000000 Qt::Horizontal 40 20 Qt::Vertical 428 61 printerNameEdit printerColorButton printerGrayscaleButton printFirstPageFirstButton printFirstPageLastButton printMagnificationSpinBox printheaderFontButton topMarginSpinBox leftMarginSpinBox rightMarginSpinBox bottomMarginSpinBox eric-6.0.8/eric/Preferences/ConfigurationPages/ShellPage.py0000644000175000017500000000764412451233373022731 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Shell configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from .ConfigurationPageBase import ConfigurationPageBase from .Ui_ShellPage import Ui_ShellPage import Preferences class ShellPage(ConfigurationPageBase, Ui_ShellPage): """ Class implementing the Shell configuration page. """ def __init__(self): """ Constructor """ super(ShellPage, self).__init__() self.setupUi(self) self.setObjectName("ShellPage") # set initial values self.shellLinenoCheckBox.setChecked( Preferences.getShell("LinenoMargin")) self.shellWordWrapCheckBox.setChecked( Preferences.getShell("WrapEnabled")) self.shellACEnabledCheckBox.setChecked( Preferences.getShell("AutoCompletionEnabled")) self.shellCTEnabledCheckBox.setChecked( Preferences.getShell("CallTipsEnabled")) self.shellSyntaxHighlightingCheckBox.setChecked( Preferences.getShell("SyntaxHighlightingEnabled")) self.shellHistorySpinBox.setValue( Preferences.getShell("MaxHistoryEntries")) self.stdOutErrCheckBox.setChecked( Preferences.getShell("ShowStdOutErr")) self.monospacedFont = Preferences.getShell("MonospacedFont") self.monospacedFontSample.setFont(self.monospacedFont) self.monospacedCheckBox.setChecked( Preferences.getShell("UseMonospacedFont")) self.marginsFont = Preferences.getShell("MarginsFont") self.marginsFontSample.setFont(self.marginsFont) def save(self): """ Public slot to save the Shell configuration. """ Preferences.setShell( "LinenoMargin", self.shellLinenoCheckBox.isChecked()) Preferences.setShell( "WrapEnabled", self.shellWordWrapCheckBox.isChecked()) Preferences.setShell( "AutoCompletionEnabled", self.shellACEnabledCheckBox.isChecked()) Preferences.setShell( "CallTipsEnabled", self.shellCTEnabledCheckBox.isChecked()) Preferences.setShell( "SyntaxHighlightingEnabled", self.shellSyntaxHighlightingCheckBox.isChecked()) Preferences.setShell( "MaxHistoryEntries", self.shellHistorySpinBox.value()) Preferences.setShell( "ShowStdOutErr", self.stdOutErrCheckBox.isChecked()) Preferences.setShell("MonospacedFont", self.monospacedFont) Preferences.setShell( "UseMonospacedFont", self.monospacedCheckBox.isChecked()) Preferences.setShell("MarginsFont", self.marginsFont) @pyqtSlot() def on_monospacedFontButton_clicked(self): """ Private method used to select the font to be used as the monospaced font. """ self.monospacedFont = \ self.selectFont(self.monospacedFontSample, self.monospacedFont) @pyqtSlot() def on_linenumbersFontButton_clicked(self): """ Private method used to select the font for the editor margins. """ self.marginsFont = self.selectFont(self.marginsFontSample, self.marginsFont) def polishPage(self): """ Public slot to perform some polishing actions. """ self.monospacedFontSample.setFont(self.monospacedFont) self.marginsFontSample.setFont(self.marginsFont) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = ShellPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/IconsPage.ui0000644000175000017500000001136512263305742022716 0ustar piotrpiotr IconsPage 0 0 539 371 <b>Configure icon directories</b> QFrame::HLine QFrame::Sunken Qt::Horizontal <font color="#FF0000"><b>Note:</b> These settings are activated at the next startup of the application.</font> false Press to delete the selected directory from the list Delete false Press to add the entered directory to the list Add Enter a directory to be added Press to select an icon directory via a selection dialog false Show Qt::Vertical QSizePolicy::Expanding 20 209 false Up false Down Qt::Vertical QSizePolicy::Expanding 20 170 List of icon directories true iconDirectoryList upButton downButton deleteIconDirectoryButton iconDirectoryEdit iconDirectoryButton showIconsButton addIconDirectoryButton eric-6.0.8/eric/Preferences/ConfigurationPages/__init__.py0000644000175000017500000000026012451233373022607 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Package implementing the various pages of the configuration dialog. """ eric-6.0.8/eric/Preferences/ConfigurationPages/VcsPage.py0000644000175000017500000000601212451233373022401 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the VCS configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_VcsPage import Ui_VcsPage import Preferences class VcsPage(ConfigurationPageBase, Ui_VcsPage): """ Class implementing the VCS configuration page. """ def __init__(self): """ Constructor """ super(VcsPage, self).__init__() self.setupUi(self) self.setObjectName("VcsPage") # set initial values self.vcsAutoCloseCheckBox.setChecked(Preferences.getVCS("AutoClose")) self.vcsAutoSaveCheckBox.setChecked( Preferences.getVCS("AutoSaveFiles")) self.vcsAutoSaveProjectCheckBox.setChecked( Preferences.getVCS("AutoSaveProject")) self.vcsStatusMonitorIntervalSpinBox.setValue( Preferences.getVCS("StatusMonitorInterval")) self.vcsMonitorLocalStatusCheckBox.setChecked( Preferences.getVCS("MonitorLocalStatus")) self.autoUpdateCheckBox.setChecked( Preferences.getVCS("AutoUpdate")) self.initColour( "VcsAdded", self.pbVcsAddedButton, Preferences.getProjectBrowserColour) self.initColour( "VcsConflict", self.pbVcsConflictButton, Preferences.getProjectBrowserColour) self.initColour( "VcsModified", self.pbVcsModifiedButton, Preferences.getProjectBrowserColour) self.initColour( "VcsReplaced", self.pbVcsReplacedButton, Preferences.getProjectBrowserColour) self.initColour( "VcsUpdate", self.pbVcsUpdateButton, Preferences.getProjectBrowserColour) self.initColour( "VcsRemoved", self.pbVcsRemovedButton, Preferences.getProjectBrowserColour) def save(self): """ Public slot to save the VCS configuration. """ Preferences.setVCS( "AutoClose", self.vcsAutoCloseCheckBox.isChecked()) Preferences.setVCS( "AutoSaveFiles", self.vcsAutoSaveCheckBox.isChecked()) Preferences.setVCS( "AutoSaveProject", self.vcsAutoSaveProjectCheckBox.isChecked()) Preferences.setVCS( "StatusMonitorInterval", self.vcsStatusMonitorIntervalSpinBox.value()) Preferences.setVCS( "MonitorLocalStatus", self.vcsMonitorLocalStatusCheckBox.isChecked()) Preferences.setVCS( "AutoUpdate", self.autoUpdateCheckBox.isChecked()) self.saveColours(Preferences.setProjectBrowserColour) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = VcsPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/DebuggerPythonPage.py0000644000175000017500000000776612451233373024615 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Debugger Python configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_DebuggerPythonPage import Ui_DebuggerPythonPage import Preferences import Utilities import UI.PixmapCache class DebuggerPythonPage(ConfigurationPageBase, Ui_DebuggerPythonPage): """ Class implementing the Debugger Python configuration page. """ def __init__(self): """ Constructor """ super(DebuggerPythonPage, self).__init__() self.setupUi(self) self.setObjectName("DebuggerPythonPage") self.interpreterButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.debugClientButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.interpreterCompleter = E5FileCompleter(self.interpreterEdit) self.debugClientCompleter = E5FileCompleter(self.debugClientEdit) # set initial values self.interpreterEdit.setText( Preferences.getDebugger("PythonInterpreter")) dct = Preferences.getDebugger("DebugClientType") if dct == "standard": self.standardButton.setChecked(True) elif dct == "threaded": self.threadedButton.setChecked(True) else: self.customButton.setChecked(True) self.debugClientEdit.setText( Preferences.getDebugger("DebugClient")) self.pyRedirectCheckBox.setChecked( Preferences.getDebugger("PythonRedirect")) self.pyNoEncodingCheckBox.setChecked( Preferences.getDebugger("PythonNoEncoding")) self.sourceExtensionsEdit.setText( Preferences.getDebugger("PythonExtensions")) def save(self): """ Public slot to save the Debugger Python configuration. """ Preferences.setDebugger( "PythonInterpreter", self.interpreterEdit.text()) if self.standardButton.isChecked(): dct = "standard" elif self.threadedButton.isChecked(): dct = "threaded" else: dct = "custom" Preferences.setDebugger("DebugClientType", dct) Preferences.setDebugger( "DebugClient", self.debugClientEdit.text()) Preferences.setDebugger( "PythonRedirect", self.pyRedirectCheckBox.isChecked()) Preferences.setDebugger( "PythonNoEncoding", self.pyNoEncodingCheckBox.isChecked()) Preferences.setDebugger( "PythonExtensions", self.sourceExtensionsEdit.text()) @pyqtSlot() def on_interpreterButton_clicked(self): """ Private slot to handle the Python interpreter selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select Python interpreter for Debug Client"), self.interpreterEdit.text(), "") if file: self.interpreterEdit.setText( Utilities.toNativeSeparators(file)) @pyqtSlot() def on_debugClientButton_clicked(self): """ Private slot to handle the Debug Client selection. """ file = E5FileDialog.getOpenFileName( None, self.tr("Select Debug Client"), self.debugClientEdit.text(), self.tr("Python Files (*.py *.py2)")) if file: self.debugClientEdit.setText( Utilities.toNativeSeparators(file)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = DebuggerPythonPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorCalltipsQScintillaPage.ui0000644000175000017500000000617412060166053026546 0ustar piotrpiotr EditorCalltipsQScintillaPage 0 0 406 369 <b>Configure QScintilla Calltips</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Context display options Select to display calltips without a context Don't show context information Select to display calltips with a context only if the user hasn't already implicitly identified the context using autocompletion Show context information, if no prior autocompletion Select to display calltips with a context Show context information Qt::Horizontal A context is any scope (e.g. a C++ namespace or a Python module) prior to the function/method name. true Qt::Vertical 388 20 ctNoContextButton ctNoAutoCompletionButton ctContextButton eric-6.0.8/eric/Preferences/ConfigurationPages/TemplatesPage.ui0000644000175000017500000001413312320555017023571 0ustar piotrpiotr TemplatesPage 0 0 532 541 <b>Configure Templates</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Groups Select, if groups having entries should be opened automatically Expand groups automatically Variables Separator: 0 0 Enter the character that encloses variables 1 Qt::Horizontal QSizePolicy::Expanding 40 20 Input method for variables Select, if a new dialog should be opened for every template variable One dialog per template variable Select, if only one dialog for all template variables should be shown One dialog for all template variables Tooltips Select, if the template text should be shown in a tooltip Show template text in tooltip Template Editor Press to select the font to be used for the code editor Editor Font Qt::NoFocus Template Code Editor Qt::AlignHCenter true Qt::Vertical 20 40 templatesAutoOpenGroupsCheckBox templatesSeparatorCharEdit templatesMultiDialogButton templatesSingleDialogButton templatesToolTipCheckBox eric-6.0.8/eric/Preferences/ConfigurationPages/TemplatesPage.py0000644000175000017500000000477312451233373023620 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Templates configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from .ConfigurationPageBase import ConfigurationPageBase from .Ui_TemplatesPage import Ui_TemplatesPage import Preferences class TemplatesPage(ConfigurationPageBase, Ui_TemplatesPage): """ Class implementing the Templates configuration page. """ def __init__(self): """ Constructor """ super(TemplatesPage, self).__init__() self.setupUi(self) self.setObjectName("TemplatesPage") # set initial values self.templatesAutoOpenGroupsCheckBox.setChecked( Preferences.getTemplates("AutoOpenGroups")) self.templatesSeparatorCharEdit.setText( Preferences.getTemplates("SeparatorChar")) if Preferences.getTemplates("SingleDialog"): self.templatesSingleDialogButton.setChecked(True) else: self.templatesMultiDialogButton.setChecked(True) self.templatesToolTipCheckBox.setChecked( Preferences.getTemplates("ShowTooltip")) self.editorFont = Preferences.getTemplates("EditorFont") self.editorFontSample.setFont(self.editorFont) def save(self): """ Public slot to save the Templates configuration. """ Preferences.setTemplates( "AutoOpenGroups", self.templatesAutoOpenGroupsCheckBox.isChecked()) sepChar = self.templatesSeparatorCharEdit.text() if sepChar: Preferences.setTemplates("SeparatorChar", sepChar) Preferences.setTemplates( "SingleDialog", self.templatesSingleDialogButton.isChecked()) Preferences.setTemplates( "ShowTooltip", self.templatesToolTipCheckBox.isChecked()) Preferences.setTemplates("EditorFont", self.editorFont) @pyqtSlot() def on_editorFontButton_clicked(self): """ Private method used to select the font to be used by the code editor. """ self.editorFont = self.selectFont( self.editorFontSample, self.editorFont) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = TemplatesPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EmailPage.ui0000644000175000017500000001726212060166053022667 0ustar piotrpiotr EmailPage 0 0 422 512 <b>Configure Email</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Outgoing mail server (SMTP): Enter the address of your mail server Outgoing mail server port: Enter the port of the mail server Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 65535 25 Qt::Horizontal 118 20 Email address: Enter your email address Signature: Qt::AlignTop Enter your email signature false Select to use TLS Use TLS Select to authenticatate against the mail server Mail server needs authentication false Username: false Enter your mail server username false Password: false Enter your password for accessing the mail server QLineEdit::Password Press to test the login data Test Login Qt::Vertical 20 40 mailServerEdit portSpin emailEdit signatureEdit useTlsCheckBox mailAuthenticationCheckBox mailUserEdit mailPasswordEdit mailAuthenticationCheckBox toggled(bool) textLabel1_15 setEnabled(bool) 39 350 49 377 mailAuthenticationCheckBox toggled(bool) textLabel2_7 setEnabled(bool) 74 350 16 403 mailAuthenticationCheckBox toggled(bool) mailUserEdit setEnabled(bool) 105 350 193 377 mailAuthenticationCheckBox toggled(bool) mailPasswordEdit setEnabled(bool) 176 350 243 403 eric-6.0.8/eric/Preferences/ConfigurationPages/IrcPage.ui0000644000175000017500000007012212070332312022341 0ustar piotrpiotr IrcPage 0 0 522 1022 <b>Configure IRC</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Enable to show timestamps Show Timestamps true Time Format: 0 0 Select the time format to use Date Format 0 0 Select the date format to use Select to show the date in timestamps Show Date Colours Network Messages: 100 0 Select the colour for network messages Nick Names: 100 0 Select the colour for nick names Server Messages: 100 0 Select the colour for server messages Own Nick Name: 100 0 Select the colour for own nick name Channel Messages: 100 0 Select the colour for channel messages Join Channel: 100 0 Select the colour for join channel messages Error Messages: 100 0 Select the colour for error messages Leave Channel: 100 0 Select the colour for leave channel messages Timestamp: 100 0 Select the colour for timestamps Channel Info: 100 0 Select the colour for channel info messages Hyperlink: 100 0 Select the colour for hyperlinks Enable to allow coloured text in IRC messages Allow Colored Text in IRC Messages true 0: 0 0 4: 0 0 8: 0 0 12: 0 0 1: 0 0 5: 0 0 9: 0 0 13: 0 0 2: 0 0 6: 0 0 10: 0 0 14: 0 0 3: 0 0 7: 0 0 11: 0 0 15: 0 0 Enable to show notifications Show Notifications true <b>Note:</b> Notifications will only be shown, if the global usage of notifications is enabled on the notifications configuration page. true Qt::Horizontal Select to show a notification for join and leave events Join/Leave Event Select to show a notification for every mentioning of your nick Mentioning of Own Nick Select to show a notification for every message Every Message Select this to enable the automatic lookup of user information for joined channels Enable Automatic User Information Lookup (/WHO) true false Max. Number of Users in Channel: Enter the maximum numbers of users in a channel allowed for this function Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 999 Qt::Horizontal 174 20 Update Interval: Enter the user information update interval Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter s 30 600 10 Marker Select to mark the current position, when the chat window is hidden Mark Current Position When Hidden Marker Foreground: 100 0 Select the foreground colour for the marker Marker Background: 100 0 Select the background colour for the marker Shutdown Select to confirm a shutdown operation while still connected to an IRC server Confirm Shutdown When Connected Qt::Vertical 20 130 timestampGroup timeFormatCombo dateFormatCombo showDateCheckBox networkButton serverButton channelButton errorButton timestampButton hyperlinkButton nickButton ownNickButton joinButton leaveButton infoButton textColoursGroup ircColor0Button ircColor1Button ircColor2Button ircColor3Button ircColor4Button ircColor5Button ircColor6Button ircColor7Button ircColor8Button ircColor9Button ircColor10Button ircColor11Button ircColor12Button ircColor13Button ircColor14Button ircColor15Button notificationsGroup joinLeaveCheckBox messageCheckBox ownNickCheckBox whoGroup whoUsersSpinBox whoIntervalSpinBox markWhenHiddenCheckBox markerForegroundButton markerBackgroundButton confirmShutdownCheckBox eric-6.0.8/eric/Preferences/ConfigurationPages/GraphicsPage.ui0000644000175000017500000000375412060166053023401 0ustar piotrpiotr GraphicsPage 0 0 440 334 <b>Configure graphics settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Press to select the font for the graphic items Graphics Font Qt::NoFocus Graphics Font Qt::AlignHCenter true Qt::Vertical 20 40 graphicsFontButton eric-6.0.8/eric/Preferences/ConfigurationPages/EditorAutocompletionPage.ui0000644000175000017500000001204312060166053026001 0ustar piotrpiotr EditorAutocompletionPage 0 0 506 294 <b>Configure Autocompletion</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select this to enable autocompletion <b>Autocompletion Enabled</b><p>Select to enable autocompletion. In order to get autocompletion from alternative autocompletion providers (if installed), these have to be enabled on their respective configuration page. Only one alternative provider might be enabled.</p> Autocompletion Enabled false General Select this to have case sensitive auto-completion lists Case sensitive Select this, if the word to the right should be replaced by the selected entry Replace word Threshold: Move to set the threshold for display of an autocompletion list 10 2 Qt::Horizontal 1 Displays the selected autocompletion threshold 2 QLCDNumber::Flat 2.000000000000000 Qt::Vertical 456 51 acEnabledCheckBox acThresholdSlider valueChanged(int) lCDNumber4 display(int) 304 114 465 116 acEnabledCheckBox toggled(bool) groupBox setEnabled(bool) 103 43 114 64 eric-6.0.8/eric/Preferences/ConfigurationPages/TasksPage.ui0000644000175000017500000001671212060166053022724 0ustar piotrpiotr TasksPage 0 0 586 475 <b>Configure Tasks</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Tasks Markers Bugfix tasks: Enter the tasks markers separated by a space character. Warning tasks: Enter the tasks markers separated by a space character. Todo tasks: Enter the tasks markers separated by a space character. Note tasks: Enter the tasks markers separated by a space character. Tasks Background Colours Bugfix tasks: 100 0 Select the background colour for these tasks. Qt::Horizontal 40 20 Warning tasks: 100 0 Select the background colour for these tasks. Todo tasks: 100 0 Select the background colour for these tasks. Note tasks: 100 0 Select the background colour for these tasks. Tasks Handling Select to clear global file tasks when the file is closed Clear global file task when file is closed Qt::Vertical 20 40 tasksMarkerFixmeEdit tasksMarkerWarningEdit tasksMarkerTodoEdit tasksMarkerNoteEdit tasksFixmeColourButton tasksWarningColourButton tasksTodoColourButton tasksNoteColourButton clearCheckBox eric-6.0.8/eric/Preferences/ConfigurationPages/CooperationPage.py0000644000175000017500000001012212451233373024125 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the Cooperation configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QRegExp from PyQt5.QtGui import QRegExpValidator, QValidator from .ConfigurationPageBase import ConfigurationPageBase from .Ui_CooperationPage import Ui_CooperationPage import Preferences class CooperationPage(ConfigurationPageBase, Ui_CooperationPage): """ Class implementing the Cooperation configuration page. """ def __init__(self): """ Constructor """ super(CooperationPage, self).__init__() self.setupUi(self) self.setObjectName("CooperationPage") self.__bannedUserValidator = QRegExpValidator( QRegExp("[a-zA-Z0-9.-]+@" "(?:(?:2(?:[0-4][0-9]|5[0-5])|[01]?[0-9]{1,2})\.){3}" "(?:2(?:[0-4][0-9]|5[0-5])|[01]?[0-9]{1,2})"), self.bannedUserEdit) self.bannedUserEdit.setValidator(self.__bannedUserValidator) # set initial values self.autostartCheckBox.setChecked( Preferences.getCooperation("AutoStartServer")) self.otherPortsCheckBox.setChecked( Preferences.getCooperation("TryOtherPorts")) self.serverPortSpin.setValue( Preferences.getCooperation("ServerPort")) self.portToTrySpin.setValue( Preferences.getCooperation("MaxPortsToTry")) self.autoAcceptCheckBox.setChecked( Preferences.getCooperation("AutoAcceptConnections")) self.bannedUsersList.addItems(sorted( Preferences.getCooperation("BannedUsers"))) def save(self): """ Public slot to save the Cooperation configuration. """ Preferences.setCooperation( "AutoStartServer", self.autostartCheckBox.isChecked()) Preferences.setCooperation( "TryOtherPorts", self.otherPortsCheckBox.isChecked()) Preferences.setCooperation( "AutoAcceptConnections", self.autoAcceptCheckBox.isChecked()) Preferences.setCooperation( "ServerPort", self.serverPortSpin.value()) Preferences.setCooperation( "MaxPortsToTry", self.portToTrySpin.value()) bannedUsers = [] for row in range(self.bannedUsersList.count()): bannedUsers.append(self.bannedUsersList.item(row).text()) Preferences.setCooperation("BannedUsers", bannedUsers) @pyqtSlot() def on_bannedUsersList_itemSelectionChanged(self): """ Private slot to react on changes of selected banned users. """ self.deleteBannedUsersButton.setEnabled( len(self.bannedUsersList.selectedItems()) > 0) @pyqtSlot(str) def on_bannedUserEdit_textChanged(self, txt): """ Private slot to handle the user entering a banned user. @param txt text entered by the user (string) """ self.addBannedUserButton.setEnabled( self.__bannedUserValidator.validate(txt, len(txt))[0] == QValidator.Acceptable) @pyqtSlot() def on_deleteBannedUsersButton_clicked(self): """ Private slot to remove the selected users from the list of banned users. """ for itm in self.bannedUsersList.selectedItems(): row = self.bannedUsersList.row(itm) itm = self.bannedUsersList.takeItem(row) del itm @pyqtSlot() def on_addBannedUserButton_clicked(self): """ Private slot to add a user to the list of banned users. """ self.bannedUsersList.addItem(self.bannedUserEdit.text()) self.bannedUserEdit.clear() def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = CooperationPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/QtPage.ui0000644000175000017500000001474412413527702022232 0ustar piotrpiotr QtPage 0 0 642 614 <b>Configure Qt</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Qt Translations Directory Enter the path of the Qt translations directory. <font color="#FF0000"><b>Note:</b> This setting is activated at the next startup of the application.</font> <b>Note:</b> Leave this entry empty to use the QT4TRANSLATIONSDIR environment variable or the path compiled into the Qt library. true Press to select the Qt translations directory via a directory selection dialog Qt Tools The tool executable is composed of the prefix, the tool name and the postfix. For win, the extension is added automatically. true Qt-Prefix: Enter the prefix for the Qt tools name Qt-Postfix: Enter the postfix for the Qt tools name 1 0 This gives an example of the complete tool name designer pyuic / pyside-uic Options Indent Width: Select the indent width (default: 4) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 2 16 4 Qt::Horizontal 448 20 Generate imports relative to '.' Qt::Vertical 496 20 qt4TransEdit qt4TransButton qt4PrefixEdit qt4PostfixEdit pyuicIndentSpinBox pyuicImportsCheckBox eric-6.0.8/eric/Preferences/ConfigurationPages/HelpInterfacePage.py0000644000175000017500000000551712451233373024370 0ustar piotrpiotr# -*- coding: utf-8 -*- """ Module implementing the Interface configuration page (variant for web browser). """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QStyleFactory from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_HelpInterfacePage import Ui_HelpInterfacePage import Preferences import Utilities import UI.PixmapCache class HelpInterfacePage(ConfigurationPageBase, Ui_HelpInterfacePage): """ Class implementing the Interface configuration page (variant for web browser). """ def __init__(self): """ Constructor """ super(HelpInterfacePage, self).__init__() self.setupUi(self) self.setObjectName("InterfacePage") self.styleSheetButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.styleSheetCompleter = E5FileCompleter(self.styleSheetEdit) # set initial values self.__populateStyleCombo() self.styleSheetEdit.setText(Preferences.getUI("StyleSheet")) def save(self): """ Public slot to save the Interface configuration. """ # save the style settings styleIndex = self.styleComboBox.currentIndex() style = self.styleComboBox.itemData(styleIndex) Preferences.setUI("Style", style) Preferences.setUI( "StyleSheet", self.styleSheetEdit.text()) def __populateStyleCombo(self): """ Private method to populate the style combo box. """ curStyle = Preferences.getUI("Style") styles = sorted(list(QStyleFactory.keys())) self.styleComboBox.addItem(self.tr('System'), "System") for style in styles: self.styleComboBox.addItem(style, style) currentIndex = self.styleComboBox.findData(curStyle) if currentIndex == -1: currentIndex = 0 self.styleComboBox.setCurrentIndex(currentIndex) @pyqtSlot() def on_styleSheetButton_clicked(self): """ Private method to select the style sheet file via a dialog. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select style sheet file"), self.styleSheetEdit.text(), self.tr( "Qt Style Sheets (*.qss);;Cascading Style Sheets (*.css);;" "All files (*)")) if file: self.styleSheetEdit.setText(Utilities.toNativeSeparators(file)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = HelpInterfacePage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/ProjectPage.ui0000644000175000017500000002356512060166053023251 0ustar piotrpiotr ProjectPage 0 0 602 685 <b>Configure project settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal XML Select, if a timestamp should be written to all project related XML files Include timestamp in project related XML files Search new files Search for new files recursively Select whether a search for new files on a project open should be performed. Search for new files on open false Select whether the found files should be included automatically. Automatically include found files Debugger Properties Select, whether a project debugger properties file shall be read on opening the project Load debugger properties upon opening Select, whether a project debugger properties file shall be written on closing the project Save debugger properties upon closing Sessions Select, whether a project session file shall be read on opening the project Load session upon opening Select, whether a project session file shall be written on closing the project Save session upon closing Select whether all breakpoints should be saved to the session file. Save all breakpoints Automatically compile Select, if changed forms should be compiled automatically upon a run action changed forms Select, if changed resources should be compiled automatically upon a run action changed resources Python Variant Select to determine the Python variant from the project language Determine Python variant from project language Recent Projects Number of recent projects: Enter the number of recent projects to remember Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 5 50 Qt::Horizontal 40 20 Tasks Select to save the project tasks automatically Save tasks automatically Qt::Vertical 584 20 projectTimestampCheckBox projectSearchNewFilesRecursiveCheckBox projectSearchNewFilesCheckBox projectAutoIncludeNewFilesCheckBox projectLoadDebugPropertiesCheckBox projectSaveDebugPropertiesCheckBox projectLoadSessionCheckBox projectSaveSessionCheckBox projectSessionAllBpCheckBox projectAutoCompileFormsCheckBox projectAutoCompileResourcesCheckBox pythonVariantCheckBox projectRecentSpinBox projectSearchNewFilesCheckBox toggled(bool) projectAutoIncludeNewFilesCheckBox setEnabled(bool) 50 133 73 190 eric-6.0.8/eric/Preferences/ConfigurationPages/EditorPropertiesPage.ui0000644000175000017500000011047212364674072025154 0ustar piotrpiotr EditorPropertiesPage 0 0 558 2611 <b>Configure lexer properties</b> QFrame::HLine QFrame::Sunken Qt::Horizontal All Lexers Properties Select to include trailing blank lines in a fold block Fold compact (except CMake, Python) Bash Lexer Properties Select whether folding of comments shall be possible Fold comments C++ , C# , IDL, Java and JavaScript Lexer Properties Select whether folding of comments shall be possible Fold comments Select whether folding at else statement should be possible Fold at else Select whether folding of preprocessor directives shall be possible Fold preprocessor directives Select, whether the line containing the opening brace should be indented Indent opening brace Select, whether the line containing the closing brace should be indented Indent closing brace Select to use case insensitive keywords Case insensitive keywords (C/C++ only) Select to allow '$' characters in identifier names Allow '$' in identifier names Select to style preprocessor lines Style preprocessor lines Select to highlight triple quoted strings Highlight triple quoted strings Select to highlight hash quoted strings Highlight hash quoted strings CMake Lexer Properties Select whether folding at else statement should be possible Fold at else CoffeeScript Select whether folding of comments shall be possible Fold comments Select to allow '$' characters in identifier names Allow '$' in identifier names Select to style preprocessor lines Style preprocessor lines CSS Lexer Properties Select whether folding of comments shall be possible Fold comments Select to activate HSS support HSS support Select to activate Less CSS support Less CSS support Select to activate Sassy CSS support Sassy CSS support D Lexer Properties Select, whether the line containing the closing brace should be indented Indent closing brace Select, whether the line containing the opening brace should be indented Indent opening brace Select whether folding at else statement should be possible Fold at else Select whether folding of comments shall be possible Fold comments Gettext Lexer Properties Select whether folding of comments shall be possible Fold comments HTML Lexer Properties Select whether folding of preprocessor directives shall be possible Fold preprocessor directives Select to enable folding of script comments Fold script comments Select to enable folding of script heredocs Fold script heredocs Select whether HTML tags should be case sensitive Case sensitive tags Select to enable support for Django templates Enable Django templates Select to enable support for Mako templates Enable Mako templates XML Lexer Properties Select to enable styling of scripts Style scripts Pascal Lexer Properties Select whether folding of comments shall be possible Fold comments Select whether folding of preprocessor directives shall be possible Fold preprocessor directives Select to enable smart highlighting of keywords Smart Highlighting Perl Lexer Properties Select whether folding of comments shall be possible Fold comments Select to enable folding of Perl packages Fold packages Select to enable folding of Perl POD blocks Fold POD blocks Select whether folding at else statement should be possible Fold at else PostScript Lexer Properties Select whether folding at else statement should be possible Fold at else Select to mark tokens Mark Tokens PostScript Level: Select the PostScript level Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 9 3 Qt::Horizontal 40 20 Povray Lexer Properties Select whether folding of directives shall be possible Fold directives Select whether folding of comments shall be possible Fold comments Properties Lexer Properties Select to allow initial spaces in a line Allow initial spaces Python Lexer Properties Select whether folding of comments shall be possible Fold comments Select whether folding of strings shall be possible Fold strings Select whether folding of triple quoted strings shall be possible Fold triple quoted strings Select whether text should be autoindented after a ':' Auto indentation after ':' Select to allow strings to span newline characters Strings may span newline characters Select to allow Python v2 unicode string literals (e.g. u"utf8") Allow v2 unicode string literals Select to allow Python v3 binary and octal literals (e.g. 0b1011, 0o712) Allow v3 binary and octal literals Select to allow Python v3 bytes string literals (e.g. b"bytes") Allow v3 bytes string literals Select to highlight sub-identifiers defined in keyword set 2 Highlight sub-identifiers Highlight bad indentation: 0 0 Select whether bad indentation shall be highlighted Ruby Lexer Properties Select whether folding of comments shall be possible Fold comments SQL Lexer Properties Select whether folding of comments shall be possible Fold comments Select whether folding at else statement should be possible Fold at else Select whether only BEGIN blocks can be folded Only BEGIN blocks can be folded Select to enable Backslash Escapes Backslash Escapes Select if words may contain dots Words may contain dots Select to allow '#' as a comment character Allow '#' as comment character Select to enable quoted identifiers Enable quoted identifiers TCL Lexer Properties Select whether folding of comments shall be possible Fold comments TeX Lexer Properties Select whether folding of comments shall be possible Fold comments Select to treat comments as TeX source Treat comments as TeX source Select to treat \if<unknown> as a command Treat \if<unknown> as command VHDL Lexer Properties Select whether folding of blocks at a parenthesis shall be possible Fold at parenthesis Select whether folding of begin blocks shall be possible Fold at begin Select whether folding at else statement should be possible Fold at else Select whether folding of comments shall be possible Fold comments YAML Lexer Properties Select whether folding of comments shall be possible Fold comments Qt::Vertical 467 21 allFoldCompactCheckBox foldBashCommentCheckBox foldCppCommentCheckBox foldCppAtElseCheckBox foldCppPreprocessorCheckBox cppIndentOpeningBraceCheckBox cppIndentClosingBraceCheckBox cppCaseInsensitiveCheckBox cppDollarAllowedCheckBox cppStylePreprocessorCheckBox cppHighlightTripleQuotedCheckBox cppHighlightHashQuotedCheckBox cmakeFoldAtElseCheckBox foldCoffeeScriptCommentCheckBox coffeeScriptDollarAllowedCheckBox coffeeScriptStylePreprocessorCheckBox foldCssCommentCheckBox cssHssCheckBox cssLessCheckBox cssSassyCheckBox foldDCommentCheckBox foldDAtElseCheckBox dIndentOpeningBraceCheckBox dIndentClosingBraceCheckBox foldPoCommentCheckBox foldHtmlPreprocessorCheckBox foldHtmlScriptCommentsCheckBox foldHtmlScriptHereDocsCheckBox htmlCaseSensitiveTagsCheckBox htmlDjangoCheckBox htmlMakoCheckBox xmlSyleScriptsCheckBox foldPascalCommentCheckBox foldPascalPreprocessorCheckBox pascalSmartHighlightingCheckBox foldPerlCommentCheckBox foldPerlPackagesCheckBox foldPerlPODBlocksCheckBox foldPerlAtElseCheckBox psFoldAtElseCheckBox psMarkTokensCheckBox psLevelSpinBox foldPovrayCommentCheckBox foldPovrayDirectivesCheckBox propertiesInitialSpacesCheckBox foldPythonCommentCheckBox foldPythonStringCheckBox foldPythonQuotesCheckBox pythonAutoindentCheckBox pythonStringsOverNewlineCheckBox pythonV2UnicodeAllowedCheckBox pythonV3BinaryAllowedCheckBox pythonV3BytesAllowedCheckBox pythonHighlightSubidentifierCheckBox pythonBadIndentationComboBox foldRubyCommentCheckBox foldSqlCommentCheckBox sqlFoldAtElseCheckBox sqlFoldOnlyBeginCheckBox sqlBackslashEscapesCheckBox sqlDottedWordsCheckBox sqlHashCommentsCheckBox sqlQuotedIdentifiersCheckBox foldTclCommentCheckBox foldTexCommentCheckBox texProcessCommentsCheckBox texProcessIfCheckBox vhdlFoldCommentCheckBox vhdlFoldAtElseCheckBox vhdlFoldAtBeginCheckBox vhdlFoldAtParenthesisCheckBox foldYamlCommentCheckBox eric-6.0.8/eric/Preferences/ConfigurationPages/DebuggerPython3Page.py0000644000175000017500000001001312451233373024653 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the Debugger Python3 configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_DebuggerPython3Page import Ui_DebuggerPython3Page import Preferences import Utilities import UI.PixmapCache class DebuggerPython3Page(ConfigurationPageBase, Ui_DebuggerPython3Page): """ Class implementing the Debugger Python3 configuration page. """ def __init__(self): """ Constructor """ super(DebuggerPython3Page, self).__init__() self.setupUi(self) self.setObjectName("DebuggerPython3Page") self.interpreterButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.debugClientButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.interpreterCompleter = E5FileCompleter(self.interpreterEdit) self.debugClientCompleter = E5FileCompleter(self.debugClientEdit) # set initial values self.interpreterEdit.setText( Preferences.getDebugger("Python3Interpreter")) dct = Preferences.getDebugger("DebugClientType3") if dct == "standard": self.standardButton.setChecked(True) elif dct == "threaded": self.threadedButton.setChecked(True) else: self.customButton.setChecked(True) self.debugClientEdit.setText( Preferences.getDebugger("DebugClient3")) self.pyRedirectCheckBox.setChecked( Preferences.getDebugger("Python3Redirect")) self.pyNoEncodingCheckBox.setChecked( Preferences.getDebugger("Python3NoEncoding")) self.sourceExtensionsEdit.setText( Preferences.getDebugger("Python3Extensions")) def save(self): """ Public slot to save the Debugger Python configuration. """ Preferences.setDebugger( "Python3Interpreter", self.interpreterEdit.text()) if self.standardButton.isChecked(): dct = "standard" elif self.threadedButton.isChecked(): dct = "threaded" else: dct = "custom" Preferences.setDebugger("DebugClientType3", dct) Preferences.setDebugger( "DebugClient3", self.debugClientEdit.text()) Preferences.setDebugger( "Python3Redirect", self.pyRedirectCheckBox.isChecked()) Preferences.setDebugger( "Python3NoEncoding", self.pyNoEncodingCheckBox.isChecked()) Preferences.setDebugger( "Python3Extensions", self.sourceExtensionsEdit.text()) @pyqtSlot() def on_interpreterButton_clicked(self): """ Private slot to handle the Python interpreter selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select Python interpreter for Debug Client"), self.interpreterEdit.text(), "") if file: self.interpreterEdit.setText( Utilities.toNativeSeparators(file)) @pyqtSlot() def on_debugClientButton_clicked(self): """ Private slot to handle the Debug Client selection. """ file = E5FileDialog.getOpenFileName( None, self.tr("Select Debug Client"), self.debugClientEdit.text(), self.tr("Python Files (*.py *.py3)")) if file: self.debugClientEdit.setText( Utilities.toNativeSeparators(file)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = DebuggerPython3Page() return page eric-6.0.8/eric/Preferences/ConfigurationPages/ProjectBrowserPage.ui0000644000175000017500000001655112165575642024630 0ustar piotrpiotr ProjectBrowserPage 0 0 617 497 <b>Configure project viewer settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Colours Highlighted entries (Others): 100 0 Select the colour for highlighted entries in the Others viewer. Qt::Horizontal 40 20 Visible Project Browsers Projecttype: 0 0 Select the project type to be configured Select to show the sources browser Sources Browser Select to show the translations browser Translations Browser Select to show the forms browser Forms Browser Select to show the interfaces (IDL) browser Interfaces (IDL) Browser Select to show the resources browser Resources Browser Select to show the browser for other files Others Browser Select to make the project browsers highlight the file of the current editor. Highlight file of current editor Select to follow the cursor line of the current editor Follow cursor line of current editor Select to populate entries automatically when following the cursor line of the current editor Populate entry when following the cursor line Select to hide sources generated from form files Hide generated form sources Qt::Vertical 599 21 pbHighlightedButton projectTypeCombo sourcesBrowserCheckBox formsBrowserCheckBox resourcesBrowserCheckBox translationsBrowserCheckBox interfacesBrowserCheckBox othersBrowserCheckBox followEditorCheckBox followCursorLineCheckBox autoPopulateCheckBox hideGeneratedCheckBox eric-6.0.8/eric/Preferences/ConfigurationPages/MasterPasswordEntryDialog.py0000644000175000017500000000733212451233373026177 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter or change the master password. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_MasterPasswordEntryDialog import Ui_MasterPasswordEntryDialog class MasterPasswordEntryDialog(QDialog, Ui_MasterPasswordEntryDialog): """ Class implementing a dialog to enter or change the master password. """ def __init__(self, oldPasswordHash, parent=None): """ Constructor @param oldPasswordHash hash of the current password (string) @param parent reference to the parent widget (QWidget) """ super(MasterPasswordEntryDialog, self).__init__(parent) self.setupUi(self) self.__oldPasswordHash = oldPasswordHash if self.__oldPasswordHash == "": self.currentPasswordEdit.setEnabled(False) if hasattr(self.currentPasswordEdit, "setPlaceholderText"): self.currentPasswordEdit.setPlaceholderText( self.tr("(not defined yet)")) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) def __updateUI(self): """ Private slot to update the variable parts of the UI. """ enable = True error = "" if self.currentPasswordEdit.isEnabled(): from Utilities.crypto.py3PBKDF2 import verifyPassword enable = verifyPassword( self.currentPasswordEdit.text(), self.__oldPasswordHash) if not enable: error = error or self.tr("Wrong password entered.") if self.newPasswordEdit.text() == "": enable = False error = error or self.tr("New password must not be empty.") if self.newPasswordEdit.text() != "" and \ self.newPasswordEdit.text() != self.newPasswordAgainEdit.text(): enable = False error = error or self.tr("Repeated password is wrong.") if self.currentPasswordEdit.isEnabled(): if self.newPasswordEdit.text() == self.currentPasswordEdit.text(): enable = False error = error or \ self.tr("Old and new password must not be the same.") self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) self.errorLabel.setText(error) @pyqtSlot(str) def on_currentPasswordEdit_textChanged(self, txt): """ Private slot to handle changes of the current password. @param txt content of the edit widget (string) """ self.__updateUI() @pyqtSlot(str) def on_newPasswordEdit_textChanged(self, txt): """ Private slot to handle changes of the new password. @param txt content of the edit widget (string) """ self.passwordMeter.checkPasswordStrength(txt) self.__updateUI() @pyqtSlot(str) def on_newPasswordAgainEdit_textChanged(self, txt): """ Private slot to handle changes of the new again password. @param txt content of the edit widget (string) """ self.__updateUI() def getMasterPassword(self): """ Public method to get the new master password. @return new master password (string) """ return self.newPasswordEdit.text() def getCurrentPassword(self): """ Public method to get the current master password. @return current master password (string) """ return self.currentPasswordEdit.text() eric-6.0.8/eric/Preferences/ConfigurationPages/EditorStylesPage.ui0000644000175000017500000016570312306405225024276 0ustar piotrpiotr EditorStylesPage 0 0 591 2019 <b>Configure editor styles</b> QFrame::HLine QFrame::Sunken Qt::Horizontal <b>Note:</b> Fonts and colors of the syntax highlighters have to be configured on the syntax highlighter styles page. true Colours Select to set the colour of the edit area different to the default style Override edit area colours false Edit area foreground: false 100 0 Select the foreground colour for the edit area. false Edit area background: false 100 0 Select the background colour for the edit area. Fonts Select, whether the monospaced font should be used as default Use monospaced as default Qt::NoFocus Default Text Qt::AlignHCenter true Press to select the default font for the editor's text Default Text Font Press to select the font to be used as the monospaced font Monospaced Font Qt::NoFocus Monospaced Text Qt::AlignHCenter true Margins Select whether line numbers margin should be shown. Show Line Numbers Margin Select whether the fold margin should be shown. Show Fold Margin Select to show unified margins (like eric4 < 4.3.0) Show unified margins Folding style: 0 0 Select the folding style to be used in the folding margin <b>Folding style</b> <p>Select the desired folding style to be used in the folding margin.</p> <p>The available styles are: <ul> <li>Plain - simple plus and minus symbols</li> <li>Circled - circled plus and minus symbols</li> <li>Boxed - boxed plus and minus symbols</li> <li>Circled Tree - circled plus and minus symbols and flattened tree with rounded corners</li> <li>Boxed Tree - boxed plus and minus symbols and flattened tree with rectangled corners</li> </ul> </p> Plain Circled Boxed Circled Tree Boxed Tree Arrow Arrow Tree Margins foreground: 100 0 Select the foreground colour for the margins Margins background: 100 0 Select the background colour for the margins Foldmargin background: 100 0 Select the background colour for the foldmargin Foldmarkers foreground: 100 0 Select the foreground colour of the foldmarkers Foldmarkers background: 100 0 Select the background colour of the foldmarkers Press to select the font for the editor line numbers Line Numbers Font 200 0 Qt::NoFocus 2345 Qt::AlignHCenter true Qt::Horizontal 40 20 Selection Select to use custom selection colours <b>Use custom selection colours</b><p>Select this entry in order to use custom selection colours in the editor and shell windows. The colours for the selection foreground and background are defined on the colours page.</p> Use custom selection colours Select, if selected text should be colourized by the lexer. Colourize selected text Select to extend selection to end of line Extend selection to end of line Selection foreground: 100 0 Select the foreground colour for the selection. Selection background: 100 0 Select the background colour for the selection. Caret Select, whether the caretline should be highlighted Caretline visible Select, whether the caretline should be highlighted even if the editor doesn't have the focus Caretline always visible Qt::Horizontal 40 20 Caret width: Select caret width (1, 2 or 3 pixels) 1 3 Qt::Horizontal QSizePolicy::Expanding 40 20 Caret foreground: 100 0 Select the colour for the caret. Caretline background: 100 0 Select the background colour for the line containing the caret. Debugging Line Markers Current line marker: 100 0 Select the colour for the current line marker. Error line marker: 100 0 Select the colour for the error line marker. Braces Select whether matching and bad braces shall be highlighted. Highlight braces Matched braces: 100 0 Select the colour for highlighting matching braces. Matched braces background: 100 0 Select the background colour for highlighting matching braces. 100 0 Unmatched brace: Select the colour for highlighting nonmatching braces. 100 0 Unmatched brace background: Select the background colour for highlighting nonmatching braces. End of Line Select whether end of line shall be shown Show End of Line Wrap long lines false Mode: Select the wrap mode for long lines Qt::Horizontal 400 20 Indication: Select, how wrapped lines are indicated Edge Mode Qt::Horizontal QSizePolicy::Expanding 211 20 Qt::Horizontal QSizePolicy::Expanding 201 31 100 0 Select the colour for the edge marker. Background colour: 11 0 Move to set the edge column. 0 160 80 Qt::Horizontal 10 1 0 Displays the selected tab width. 3 QLCDNumber::Flat 80.000000000000000 Column number: Mode: 0 0 Disabled Draw Line Change Background Colour Zoom Initial zoom factor: Move to set the initial zoom factor -10 20 0 Qt::Horizontal 5 Displays the selected initial zoom factor 3 QLCDNumber::Flat 0.000000000000000 Annotations Select to enable the display of annotations Show annotations Warnings Press to select the foreground colour Foreground Press to select the background colour Background Qt::NoFocus Warning: There might be an issue. Qt::AlignHCenter true Errors Press to select the foreground colour Foreground Press to select the background colour Background Qt::NoFocus Error: There is an issue. Qt::AlignHCenter true Style Press to select the foreground colour Foreground Press to select the background colour Background Qt::NoFocus Style: There is a style issue. Qt::AlignHCenter true Change Tracing Select to mark changed lines Mark changed lines Timeout for marking changed lines: Enter the time in milliseconds after which changed lines will be marked Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter QAbstractSpinBox::PlusMinus QAbstractSpinBox::CorrectToNearestValue ms 100 5000 100 Qt::Horizontal 40 20 Unsaved changes colour: 100 0 Select the colour for the change marker for unsaved changes. Saved changes colour: 100 0 Select the colour for the change marker for saved changes. Whitespace Select whether whitspace characters shall be shown Show Whitespace Whitespace size: Select the size of the dots used to represent visible whitespace 1 10 Qt::Horizontal QSizePolicy::Expanding 40 20 Whitespace foreground: 100 0 Select the foreground colour for visible whitespace Whitespace background: 100 0 Select the background colour for visible whitespace Various Select to show a minimalistic context menu Show minimal context menu Marker Map Errors: 100 0 Select the colour for error markers Warnings: 100 0 Select the colour for warning markers Bookmarks: 100 0 Select the colour for bookmark markers Breakpoints: 100 0 Select the colour for breakpoint markers Tasks: 100 0 Select the colour for task markers Changes: 100 0 Select the colour for change markers Coverage: 100 0 Select the colour for coverage markers Current Line: 100 0 Select the colour for the current line marker Background: 100 0 Select the background colour for the marker map Qt::Vertical 558 20 editAreaOverrideCheckBox editAreaForegroundButton editAreaBackgroundButton defaultFontButton monospacedFontButton monospacedCheckBox linenoCheckBox foldingCheckBox unifiedMarginsCheckBox foldingStyleComboBox marginsForegroundButton marginsBackgroundButton foldmarginBackgroundButton foldmarkersForegroundButton foldmarkersBackgroundButton linenumbersFontButton customSelColourCheckBox colourizeSelTextCheckBox extentSelEolCheckBox selectionForegroundButton selectionBackgroundButton caretlineVisibleCheckBox caretlineAlwaysVisibleCheckBox caretWidthSpinBox caretForegroundButton caretlineBackgroundButton currentLineMarkerButton errorMarkerButton bracehighlightingCheckBox matchingBracesButton matchingBracesBackButton nonmatchingBracesButton nonmatchingBracesBackButton eolCheckBox wrapModeComboBox wrapVisualComboBox edgeModeCombo edgeLineColumnSlider edgeBackgroundColorButton zoomfactorSlider enableAnnotationsCheckBox annotationsWarningFgButton annotationsWarningBgButton annotationsErrorFgButton annotationsErrorBgButton annotationsStyleWarningFgButton annotationsStyleWarningBgButton enableChangeTraceCheckBox changeTraceTimeoutSpinBox changeMarkerUnsavedColorButton changeMarkerSavedColorButton whitespaceCheckBox whitespaceSizeSpinBox whitespaceForegroundButton whitespaceBackgroundButton miniMenuCheckBox edgeLineColumnSlider valueChanged(int) edgeLineColumnLCD display(int) 492 1144 544 1148 zoomfactorSlider valueChanged(int) zoomfactorLCD display(int) 206 1265 555 1269 editAreaOverrideCheckBox toggled(bool) TextLabel2_2_2_2_2_12 setEnabled(bool) 75 117 75 137 editAreaOverrideCheckBox toggled(bool) editAreaForegroundButton setEnabled(bool) 201 115 209 140 editAreaOverrideCheckBox toggled(bool) TextLabel2_2_2_2_2_11 setEnabled(bool) 313 112 348 141 editAreaOverrideCheckBox toggled(bool) editAreaBackgroundButton setEnabled(bool) 447 117 489 142 eric-6.0.8/eric/Preferences/ConfigurationPages/EditorSyntaxPage.py0000644000175000017500000000453212451233373024310 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Editor Syntax Checker configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorSyntaxPage import Ui_EditorSyntaxPage import Preferences class EditorSyntaxPage(ConfigurationPageBase, Ui_EditorSyntaxPage): """ Class implementing the Editor Syntax Checker configuration page. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(EditorSyntaxPage, self).__init__() self.setupUi(self) self.setObjectName("EditorSyntaxPage") # set initial values self.onlineCheckBox.setChecked( Preferences.getEditor("OnlineSyntaxCheck")) self.onlineTimeoutSpinBox.setValue( Preferences.getEditor("OnlineSyntaxCheckInterval")) self.automaticSyntaxCheckCheckBox.setChecked( Preferences.getEditor("AutoCheckSyntax")) # pyflakes related stuff self.includeCheckBox.setChecked( Preferences.getFlakes("IncludeInSyntaxCheck")) self.ignoreStarImportCheckBox.setChecked( Preferences.getFlakes("IgnoreStarImportWarnings")) def save(self): """ Public slot to save the Editor Syntax Checker configuration. """ Preferences.setEditor( "OnlineSyntaxCheck", self.onlineCheckBox.isChecked()) Preferences.setEditor( "OnlineSyntaxCheckInterval", self.onlineTimeoutSpinBox.value()) Preferences.setEditor( "AutoCheckSyntax", self.automaticSyntaxCheckCheckBox.isChecked()) # pyflakes related stuff Preferences.setFlakes( "IncludeInSyntaxCheck", self.includeCheckBox.isChecked()) Preferences.setFlakes( "IgnoreStarImportWarnings", self.ignoreStarImportCheckBox.isChecked()) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorSyntaxPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/ViewmanagerPage.py0000644000175000017500000000626512451233373024125 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Viewmanager configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Application import e5App from .ConfigurationPageBase import ConfigurationPageBase from .Ui_ViewmanagerPage import Ui_ViewmanagerPage import Preferences class ViewmanagerPage(ConfigurationPageBase, Ui_ViewmanagerPage): """ Class implementing the Viewmanager configuration page. """ def __init__(self): """ Constructor """ super(ViewmanagerPage, self).__init__() self.setupUi(self) self.setObjectName("ViewmanagerPage") # set initial values self.pluginManager = e5App().getObject("PluginManager") self.viewmanagers = \ self.pluginManager.getPluginDisplayStrings("viewmanager") self.windowComboBox.clear() currentVm = Preferences.getViewManager() keys = sorted(self.viewmanagers.keys()) for key in keys: self.windowComboBox.addItem( self.tr(self.viewmanagers[key]), key) currentIndex = self.windowComboBox.findText( self.tr(self.viewmanagers[currentVm])) self.windowComboBox.setCurrentIndex(currentIndex) self.on_windowComboBox_activated(currentIndex) self.tabViewGroupBox.setTitle( self.tr(self.viewmanagers["tabview"])) self.filenameLengthSpinBox.setValue( Preferences.getUI("TabViewManagerFilenameLength")) self.filenameOnlyCheckBox.setChecked( Preferences.getUI("TabViewManagerFilenameOnly")) self.recentFilesSpinBox.setValue( Preferences.getUI("RecentNumber")) def save(self): """ Public slot to save the Viewmanager configuration. """ vm = self.windowComboBox.itemData( self.windowComboBox.currentIndex()) Preferences.setViewManager(vm) Preferences.setUI( "TabViewManagerFilenameLength", self.filenameLengthSpinBox.value()) Preferences.setUI( "TabViewManagerFilenameOnly", self.filenameOnlyCheckBox.isChecked()) Preferences.setUI( "RecentNumber", self.recentFilesSpinBox.value()) @pyqtSlot(int) def on_windowComboBox_activated(self, index): """ Private slot to show a preview of the selected workspace view type. @param index index of selected workspace view type (integer) """ workspace = \ self.windowComboBox.itemData(self.windowComboBox.currentIndex()) pixmap = \ self.pluginManager.getPluginPreviewPixmap("viewmanager", workspace) self.previewPixmap.setPixmap(pixmap) self.tabViewGroupBox.setEnabled(workspace == "tabview") def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = ViewmanagerPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/PythonPage.py0000644000175000017500000000443312451233373023134 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Python configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_PythonPage import Ui_PythonPage import Preferences from Utilities import supportedCodecs class PythonPage(ConfigurationPageBase, Ui_PythonPage): """ Class implementing the Python configuration page. """ def __init__(self): """ Constructor """ super(PythonPage, self).__init__() self.setupUi(self) self.setObjectName("PythonPage") self.stringEncodingComboBox.addItems(sorted(supportedCodecs)) self.ioEncodingComboBox.addItems(sorted(supportedCodecs)) # set initial values index = self.stringEncodingComboBox.findText( Preferences.getSystem("StringEncoding")) self.stringEncodingComboBox.setCurrentIndex(index) index = self.ioEncodingComboBox.findText( Preferences.getSystem("IOEncoding")) self.ioEncodingComboBox.setCurrentIndex(index) # these are the same as in the debugger pages self.py2ExtensionsEdit.setText( Preferences.getDebugger("PythonExtensions")) self.py3ExtensionsEdit.setText( Preferences.getDebugger("Python3Extensions")) def save(self): """ Public slot to save the Python configuration. """ enc = self.stringEncodingComboBox.currentText() if not enc: enc = "utf-8" Preferences.setSystem("StringEncoding", enc) enc = self.ioEncodingComboBox.currentText() if not enc: enc = "utf-8" Preferences.setSystem("IOEncoding", enc) Preferences.setDebugger( "PythonExtensions", self.py2ExtensionsEdit.text()) Preferences.setDebugger( "Python3Extensions", self.py3ExtensionsEdit.text()) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = PythonPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorKeywordsPage.ui0000644000175000017500000000471512060166053024615 0ustar piotrpiotr EditorKeywordsPage 0 0 462 422 <b>Configure syntax highlighter keywords</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Language: 0 0 Select the language to be configured. Set: 1 9 Enter the keywords separated by a blank languageCombo setSpinBox keywordsEdit eric-6.0.8/eric/Preferences/ConfigurationPages/EditorFilePage.py0000644000175000017500000002705112451233373023702 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor File Handling configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QListWidgetItem, QInputDialog, QLineEdit from PyQt5.Qsci import QsciScintilla from E5Gui import E5MessageBox from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorFilePage import Ui_EditorFilePage from Utilities import supportedCodecs import Preferences class EditorFilePage(ConfigurationPageBase, Ui_EditorFilePage): """ Class implementing the Editor File Handling configuration page. """ def __init__(self): """ Constructor """ super(EditorFilePage, self).__init__() self.setupUi(self) self.setObjectName("EditorFilePage") self.__showsOpenFilters = True self.openFileFilters = \ Preferences.getEditor("AdditionalOpenFilters")[:] self.saveFileFilters = \ Preferences.getEditor("AdditionalSaveFilters")[:] self.fileFiltersList.addItems(self.openFileFilters) self.__setDefaultFiltersLists() self.defaultEncodingComboBox.addItems(sorted(supportedCodecs)) # set initial values self.autosaveSlider.setValue( Preferences.getEditor("AutosaveInterval")) self.createBackupFileCheckBox.setChecked( Preferences.getEditor("CreateBackupFile")) self.defaultEncodingComboBox.setCurrentIndex( self.defaultEncodingComboBox.findText( Preferences.getEditor("DefaultEncoding"))) self.advEncodingCheckBox.setChecked( Preferences.getEditor("AdvancedEncodingDetection")) self.warnFilesizeSpinBox.setValue( Preferences.getEditor("WarnFilesize")) self.clearBreakpointsCheckBox.setChecked( Preferences.getEditor("ClearBreaksOnClose")) self.automaticReopenCheckBox.setChecked( Preferences.getEditor("AutoReopen")) self.stripWhitespaceCheckBox.setChecked( Preferences.getEditor("StripTrailingWhitespace")) self.openFilesFilterComboBox.setCurrentIndex( self.openFilesFilterComboBox.findText( Preferences.getEditor("DefaultOpenFilter"))) self.saveFilesFilterComboBox.setCurrentIndex( self.saveFilesFilterComboBox.findText( Preferences.getEditor("DefaultSaveFilter"))) self.automaticEolConversionCheckBox.setChecked( Preferences.getEditor("AutomaticEOLConversion")) eolMode = Preferences.getEditor("EOLMode") if eolMode == QsciScintilla.EolWindows: self.crlfRadioButton.setChecked(True) elif eolMode == QsciScintilla.EolMac: self.crRadioButton.setChecked(True) elif eolMode == QsciScintilla.EolUnix: self.lfRadioButton.setChecked(True) self.previewHtmlExtensionsEdit.setText( " ".join(Preferences.getEditor("PreviewHtmlFileNameExtensions"))) self.previewMarkdownExtensionsEdit.setText( " ".join( Preferences.getEditor("PreviewMarkdownFileNameExtensions"))) self.previewRestExtensionsEdit.setText( " ".join(Preferences.getEditor("PreviewRestFileNameExtensions"))) self.previewQssExtensionsEdit.setText( " ".join(Preferences.getEditor("PreviewQssFileNameExtensions"))) def save(self): """ Public slot to save the Editor File Handling configuration. """ Preferences.setEditor( "AutosaveInterval", self.autosaveSlider.value()) Preferences.setEditor( "CreateBackupFile", self.createBackupFileCheckBox.isChecked()) enc = self.defaultEncodingComboBox.currentText() if not enc: enc = "utf-8" Preferences.setEditor("DefaultEncoding", enc) Preferences.setEditor( "AdvancedEncodingDetection", self.advEncodingCheckBox.isChecked()) Preferences.setEditor( "WarnFilesize", self.warnFilesizeSpinBox.value()) Preferences.setEditor( "ClearBreaksOnClose", self.clearBreakpointsCheckBox.isChecked()) Preferences.setEditor( "AutoReopen", self.automaticReopenCheckBox.isChecked()) Preferences.setEditor( "StripTrailingWhitespace", self.stripWhitespaceCheckBox.isChecked()) Preferences.setEditor( "DefaultOpenFilter", self.openFilesFilterComboBox.currentText()) Preferences.setEditor( "DefaultSaveFilter", self.saveFilesFilterComboBox.currentText()) Preferences.setEditor( "AutomaticEOLConversion", self.automaticEolConversionCheckBox.isChecked()) if self.crlfRadioButton.isChecked(): Preferences.setEditor("EOLMode", QsciScintilla.EolWindows) elif self.crRadioButton.isChecked(): Preferences.setEditor("EOLMode", QsciScintilla.EolMac) elif self.lfRadioButton.isChecked(): Preferences.setEditor("EOLMode", QsciScintilla.EolUnix) self.__extractFileFilters() Preferences.setEditor("AdditionalOpenFilters", self.openFileFilters) Preferences.setEditor("AdditionalSaveFilters", self.saveFileFilters) Preferences.setEditor( "PreviewHtmlFileNameExtensions", [ext.strip() for ext in self.previewHtmlExtensionsEdit.text().split()]) Preferences.setEditor( "PreviewMarkdownFileNameExtensions", [ext.strip() for ext in self.previewMarkdownExtensionsEdit.text().split()]) Preferences.setEditor( "PreviewRestFileNameExtensions", [ext.strip() for ext in self.previewRestExtensionsEdit.text().split()]) Preferences.setEditor( "PreviewQssFileNameExtensions", [ext.strip() for ext in self.previewQssExtensionsEdit.text().split()]) def __setDefaultFiltersLists(self, keepSelection=False): """ Private slot to set the default file filter combo boxes. @param keepSelection flag indicating to keep the current selection if possible (boolean) """ if keepSelection: selectedOpenFilter = self.openFilesFilterComboBox.currentText() selectedSaveFilter = self.saveFilesFilterComboBox.currentText() import QScintilla.Lexers openFileFiltersList = QScintilla.Lexers.getOpenFileFiltersList( False, withAdditional=False) + self.openFileFilters openFileFiltersList.sort() self.openFilesFilterComboBox.clear() self.openFilesFilterComboBox.addItems(openFileFiltersList) saveFileFiltersList = QScintilla.Lexers.getSaveFileFiltersList( False, withAdditional=False) + self.saveFileFilters saveFileFiltersList.sort() self.saveFilesFilterComboBox.clear() self.saveFilesFilterComboBox.addItems(saveFileFiltersList) if keepSelection: self.openFilesFilterComboBox.setCurrentIndex( self.openFilesFilterComboBox.findText(selectedOpenFilter)) self.saveFilesFilterComboBox.setCurrentIndex( self.saveFilesFilterComboBox.findText(selectedSaveFilter)) def __extractFileFilters(self): """ Private method to extract the file filters. """ filters = [] for row in range(self.fileFiltersList.count()): filters.append(self.fileFiltersList.item(row).text()) if self.__showsOpenFilters: self.openFileFilters = filters else: self.saveFileFilters = filters def __checkFileFilter(self, filter): """ Private method to check a file filter for validity. @param filter file filter pattern to check (string) @return flag indicating validity (boolean) """ if not self.__showsOpenFilters and \ filter.count("*") != 1: E5MessageBox.critical( self, self.tr("Add File Filter"), self.tr("""A Save File Filter must contain exactly one""" """ wildcard pattern. Yours contains {0}.""") .format(filter.count("*"))) return False if filter.count("*") == 0: E5MessageBox.critical( self, self.tr("Add File Filter"), self.tr("""A File Filter must contain at least one""" """ wildcard pattern.""")) return False return True @pyqtSlot() def on_addFileFilterButton_clicked(self): """ Private slot to add a file filter to the list. """ filter, ok = QInputDialog.getText( self, self.tr("Add File Filter"), self.tr("Enter the file filter entry:"), QLineEdit.Normal) if ok and filter: if self.__checkFileFilter(filter): self.fileFiltersList.addItem(filter) self.__extractFileFilters() self.__setDefaultFiltersLists(keepSelection=True) @pyqtSlot() def on_editFileFilterButton_clicked(self): """ Private slot called to edit a file filter entry. """ filter = self.fileFiltersList.currentItem().text() filter, ok = QInputDialog.getText( self, self.tr("Add File Filter"), self.tr("Enter the file filter entry:"), QLineEdit.Normal, filter) if ok and filter: if self.__checkFileFilter(filter): self.fileFiltersList.currentItem().setText(filter) self.__extractFileFilters() self.__setDefaultFiltersLists(keepSelection=True) @pyqtSlot() def on_deleteFileFilterButton_clicked(self): """ Private slot called to delete a file filter entry. """ self.fileFiltersList.takeItem(self.fileFiltersList.currentRow()) self.__extractFileFilters() self.__setDefaultFiltersLists(keepSelection=True) @pyqtSlot(bool) def on_openFiltersButton_toggled(self, checked): """ Private slot to switch the list of file filters. @param checked flag indicating the check state of the button (boolean) """ self.__extractFileFilters() self.__showsOpenFilters = checked self.fileFiltersList.clear() if checked: self.fileFiltersList.addItems(self.openFileFilters) else: self.fileFiltersList.addItems(self.saveFileFilters) @pyqtSlot(QListWidgetItem, QListWidgetItem) def on_fileFiltersList_currentItemChanged(self, current, previous): """ Private slot to set the state of the edit and delete buttons. @param current new current item (QListWidgetItem) @param previous previous current item (QListWidgetItem) """ self.editFileFilterButton.setEnabled(current is not None) self.deleteFileFilterButton.setEnabled(current is not None) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorFilePage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/DebuggerPython3Page.ui0000644000175000017500000001410612355747621024660 0ustar piotrpiotr DebuggerPython3Page 0 0 455 449 <b>Configure Python3 Debugger</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Python3 Interpreter for Debug Client Enter the path of the Python3 interpreter to be used by the debug client. Leave empty to use the default. Press to select the Python3 interpreter via a file selection dialog Debug Client Type false Enter the path of the Debug Client to be used. Leave empty to use the default. false Press to select the Debug Client via a file selection dialog Select the standard debug client Standard Select the custom selected debug client Custom Select the multi threaded debug client Multi Threaded Source association Enter the file extensions to be associated with the Python3 debugger separated by a space. They must not overlap with the ones for Python2. true Select, to redirect stdin, stdout and stderr of the program being debugged to the eric6 IDE Redirect stdin/stdout/stderr Select to not set the debug client encoding Don't set the encoding of the debug client Qt::Vertical 435 21 interpreterEdit interpreterButton standardButton threadedButton customButton debugClientEdit debugClientButton sourceExtensionsEdit pyRedirectCheckBox pyNoEncodingCheckBox customButton toggled(bool) debugClientEdit setEnabled(bool) 368 194 332 219 eric-6.0.8/eric/Preferences/ConfigurationPages/EditorCalltipsPage.py0000644000175000017500000000550612451233373024577 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor Calltips configuration page. """ from __future__ import unicode_literals from PyQt5.Qsci import QsciScintilla from QScintilla.QsciScintillaCompat import QSCINTILLA_VERSION from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorCalltipsPage import Ui_EditorCalltipsPage import Preferences class EditorCalltipsPage(ConfigurationPageBase, Ui_EditorCalltipsPage): """ Class implementing the Editor Calltips configuration page. """ def __init__(self): """ Constructor """ super(EditorCalltipsPage, self).__init__() self.setupUi(self) self.setObjectName("EditorCalltipsPage") if QSCINTILLA_VERSION() >= 0x020700: self.positionComboBox.addItem( self.tr("Below Text"), QsciScintilla.CallTipsBelowText) self.positionComboBox.addItem( self.tr("Above Text"), QsciScintilla.CallTipsAboveText) else: self.calltipsPositionBox.hide() # set initial values self.ctEnabledCheckBox.setChecked( Preferences.getEditor("CallTipsEnabled")) self.ctVisibleSlider.setValue( Preferences.getEditor("CallTipsVisible")) self.initColour("CallTipsBackground", self.calltipsBackgroundButton, Preferences.getEditorColour) self.ctScintillaCheckBox.setChecked( Preferences.getEditor("CallTipsScintillaOnFail")) if QSCINTILLA_VERSION() >= 0x020700: self.positionComboBox.setCurrentIndex( self.positionComboBox.findData( Preferences.getEditor("CallTipsPosition"))) def save(self): """ Public slot to save the EditorCalltips configuration. """ Preferences.setEditor( "CallTipsEnabled", self.ctEnabledCheckBox.isChecked()) Preferences.setEditor( "CallTipsVisible", self.ctVisibleSlider.value()) self.saveColours(Preferences.setEditorColour) Preferences.setEditor( "CallTipsScintillaOnFail", self.ctScintillaCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020700: Preferences.setEditor( "CallTipsPosition", self.positionComboBox.itemData( self.positionComboBox.currentIndex())) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorCalltipsPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorSpellCheckingPage.ui0000644000175000017500000003033412263305053025515 0ustar piotrpiotr EditorSpellCheckingPage 0 0 578 666 <b>Configure editor spell checking options</b> QFrame::HLine QFrame::Sunken Qt::Horizontal <font color="#FF0000">Spell checking with PyEnchant is not available.</font> QFrame::NoFrame QFrame::Plain 0 0 0 0 Select to enable spell checking Spell checking enabled Defaults Default language: Select the default language Qt::Horizontal 353 20 Spell checking options Select to check strings only Spell check strings only Minimum word size: Move to set the minimum size of words to be checked 1 10 Qt::Horizontal QSlider::NoTicks 1 Displays the minimum size of words to be checked 2 QLCDNumber::Flat 1 Colours Marker Colour: 100 0 Select the colour for the spelling markers. Qt::Horizontal 348 20 Personal lists Personal word list file: Enter the filename of the personal word list Personal exclude list file: Enter the filename of the personal exclude list <b>Note:</b> leave these entries empty to use the default <b>Note:</b> valid for all newly opened editors Select the personal word list file via a file selection dialog Select the personal exclude list file via a file selection dialog Automatic spell checking Select to enable spellchecking Automatic spell checking enabled Amount of lines to autocheck at once: Enter the number of lines to check per go. Higher values increase checking speed but decrease GUI responsivenes Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 10 999 Qt::Horizontal 40 20 Qt::Vertical 558 231 checkingEnabledCheckBox defaultLanguageCombo stringsOnlyCheckBox minimumWordSizeSlider spellingMarkerButton pwlEdit pwlButton pelEdit pelButton enabledCheckBox chunkSizeSpinBox minimumWordSizeSlider valueChanged(int) lCDNumber display(int) 248 131 545 131 eric-6.0.8/eric/Preferences/ConfigurationPages/EditorSearchPage.py0000644000175000017500000000445412451233373024232 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the Editor Search configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorSearchPage import Ui_EditorSearchPage import Preferences class EditorSearchPage(ConfigurationPageBase, Ui_EditorSearchPage): """ Class implementing the Editor Search configuration page. """ def __init__(self): """ Constructor """ super(EditorSearchPage, self).__init__() self.setupUi(self) self.setObjectName("EditorSearchPage") self.editorColours = {} # set initial values self.searchMarkersEnabledCheckBox.setChecked( Preferences.getEditor("SearchMarkersEnabled")) self.quicksearchMarkersEnabledCheckBox.setChecked( Preferences.getEditor("QuickSearchMarkersEnabled")) self.occurrencesMarkersEnabledCheckBox.setChecked( Preferences.getEditor("MarkOccurrencesEnabled")) self.markOccurrencesTimeoutSpinBox.setValue( Preferences.getEditor("MarkOccurrencesTimeout")) self.initColour( "SearchMarkers", self.searchMarkerButton, Preferences.getEditorColour, hasAlpha=True) def save(self): """ Public slot to save the Editor Search configuration. """ Preferences.setEditor( "SearchMarkersEnabled", self.searchMarkersEnabledCheckBox.isChecked()) Preferences.setEditor( "QuickSearchMarkersEnabled", self.quicksearchMarkersEnabledCheckBox.isChecked()) Preferences.setEditor( "MarkOccurrencesEnabled", self.occurrencesMarkersEnabledCheckBox.isChecked()) Preferences.setEditor( "MarkOccurrencesTimeout", self.markOccurrencesTimeoutSpinBox.value()) self.saveColours(Preferences.setEditorColour) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorSearchPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/IconsPreviewDialog.ui0000644000175000017500000000316112060166053024571 0ustar piotrpiotr IconsPreviewDialog 0 0 596 541 Icons Preview true QListView::Free QListView::LeftToRight 100 50 QListView::IconMode Qt::Horizontal QDialogButtonBox::Ok iconView buttonBox accepted() IconsPreviewDialog accept() 155 519 161 538 eric-6.0.8/eric/Preferences/ConfigurationPages/TrayStarterPage.ui0000644000175000017500000000521612060166053024120 0ustar piotrpiotr TrayStarterPage 0 0 482 473 <b>Configure Tray Starter</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Icon Select to use the standard icon Standard Icon Select to use the high contrast icon High Contrast Icon Select to use a black and white icon Black and White Icon Select to use an inverse black and white icon Inverse Black and White Icon Qt::Vertical 464 41 eric-6.0.8/eric/Preferences/ConfigurationPages/EditorCalltipsPage.ui0000644000175000017500000001354012510743004024552 0ustar piotrpiotr EditorCalltipsPage 0 0 406 369 <b>Configure Calltips</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select this to enable calltips Calltips Enabled false 0 Visible Calltips Move to set the maximum number of calltips shown (0 = all available) 20 Qt::Horizontal 1 Displays the maximum number of calltips to be shown 2 QLCDNumber::Flat Calltips Position Select the position for the calltips Colours Background colour: 100 0 Select the background colour for calltips. Qt::Horizontal 40 20 Plug-In Behavior Select to show QScintilla provided calltips, if the selected plugin fails Qscintilla provided calltips are shown, if this option is enabled and calltips shall be provided by a plug-in (see calltips sub-page of the plug-in) and the plugin-in doesn't deliver any calltips. Show QScintilla calltips, if plug-in fails Qt::Vertical 388 20 ctEnabledCheckBox calltipsBackgroundButton ctScintillaCheckBox ctVisibleSlider valueChanged(int) lCDNumber5 display(int) 102 109 384 126 eric-6.0.8/eric/Preferences/ConfigurationPages/CorbaPage.ui0000644000175000017500000000427412263304372022670 0ustar piotrpiotr CorbaPage 0 0 589 490 <b>Configure CORBA support</b> QFrame::HLine QFrame::Sunken Qt::Horizontal IDL Compiler Enter the path to the IDL compiler. <b>Note:</b> Leave this entry empty to use the default value (omniidl or omniidl.exe). Press to select the IDL compiler via a file selection dialog. Qt::Vertical 20 81 idlEdit idlButton eric-6.0.8/eric/Preferences/ConfigurationPages/NetworkPage.ui0000644000175000017500000004146212263306134023271 0ustar piotrpiotr NetworkPage 0 0 591 769 <b>Configure Network</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Downloads Download directory: Enter the download directory (leave empty to use the default location) Select the download directory via a directory selection dialog Select to ask the user for a download filename Request name of downloaded file Download Manager Cleanup Policy Select to never cleanup automatically Never Select to cleanup upon exiting When exiting the application Select to cleanup after a successful download When download finished successfully Select to use a web proxy Use network proxy true true Select to use the system proxy configuration Use system proxy configuration true Select to use an application specific proxy configuration Manual proxy configuration: false false Manual proxy settings false HTTP-Proxy: Enter the name of the HTTP proxy host Port: Enter the HTTP proxy port Qt::AlignRight 1 65535 80 Select to use the HTTP proxy for all Use this proxy for all protocols HTTPS-Proxy: Enter the name of the HTTPS proxy host Port: Enter the HTTPS proxy port Qt::AlignRight 1 65535 443 FTP-Proxy Hostname: Enter the name of the FTP proxy host Port: Enter the FTP proxy port Qt::AlignRight 1 65535 21 Proxy Type: Select the type of the FTP proxy User Name: Enter the user name for the proxy authentication Password: Enter the password for the proxy authentication QLineEdit::Password Account: Enter the account info for the proxy authentication Press to clear the saved passwords for the Http(s) proxy Clear HTTP(S) Proxy Passwords Qt::Vertical 571 21 downloadDirEdit downloadDirButton requestFilenameCheckBox cleanupNeverButton cleanupExitButton cleanupSuccessfulButton proxyGroup systemProxyButton manualProxyButton httpProxyHostEdit httpProxyPortSpin httpProxyForAllCheckBox httpsProxyHostEdit httpsProxyPortSpin ftpProxyHostEdit ftpProxyPortSpin ftpProxyTypeCombo ftpProxyUserEdit ftpProxyPasswordEdit ftpProxyAccountEdit clearProxyPasswordsButton manualProxyButton toggled(bool) groupBox setEnabled(bool) 77 310 83 507 httpProxyForAllCheckBox toggled(bool) label_4 setDisabled(bool) 229 386 109 412 httpProxyForAllCheckBox toggled(bool) label_3 setDisabled(bool) 245 386 106 463 httpProxyForAllCheckBox toggled(bool) httpsProxyHostEdit setDisabled(bool) 311 386 269 412 httpProxyForAllCheckBox toggled(bool) ftpProxyHostEdit setDisabled(bool) 307 386 304 463 httpProxyForAllCheckBox toggled(bool) label_5 setDisabled(bool) 517 386 485 412 httpProxyForAllCheckBox toggled(bool) label_7 setDisabled(bool) 482 386 474 463 httpProxyForAllCheckBox toggled(bool) httpsProxyPortSpin setDisabled(bool) 557 386 557 412 httpProxyForAllCheckBox toggled(bool) ftpProxyPortSpin setDisabled(bool) 554 386 546 463 eric-6.0.8/eric/Preferences/ConfigurationPages/DebuggerRubyPage.py0000644000175000017500000000441412451233373024240 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Debugger Ruby configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_DebuggerRubyPage import Ui_DebuggerRubyPage import Preferences import Utilities import UI.PixmapCache class DebuggerRubyPage(ConfigurationPageBase, Ui_DebuggerRubyPage): """ Class implementing the Debugger Ruby configuration page. """ def __init__(self): """ Constructor """ super(DebuggerRubyPage, self).__init__() self.setupUi(self) self.setObjectName("DebuggerRubyPage") self.rubyInterpreterButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.rubyInterpreterCompleter = E5FileCompleter( self.rubyInterpreterEdit) # set initial values self.rubyInterpreterEdit.setText( Preferences.getDebugger("RubyInterpreter")) self.rbRedirectCheckBox.setChecked( Preferences.getDebugger("RubyRedirect")) def save(self): """ Public slot to save the Debugger Ruby configuration. """ Preferences.setDebugger( "RubyInterpreter", self.rubyInterpreterEdit.text()) Preferences.setDebugger( "RubyRedirect", self.rbRedirectCheckBox.isChecked()) @pyqtSlot() def on_rubyInterpreterButton_clicked(self): """ Private slot to handle the Ruby interpreter selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select Ruby interpreter for Debug Client"), self.rubyInterpreterEdit.text()) if file: self.rubyInterpreterEdit.setText( Utilities.toNativeSeparators(file)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = DebuggerRubyPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/ProjectPage.py0000644000175000017500000001044312451233373023257 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Project configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_ProjectPage import Ui_ProjectPage import Preferences class ProjectPage(ConfigurationPageBase, Ui_ProjectPage): """ Class implementing the Project configuration page. """ def __init__(self): """ Constructor """ super(ProjectPage, self).__init__() self.setupUi(self) self.setObjectName("ProjectPage") # set initial values self.projectSearchNewFilesRecursiveCheckBox.setChecked( Preferences.getProject("SearchNewFilesRecursively")) self.projectSearchNewFilesCheckBox.setChecked( Preferences.getProject("SearchNewFiles")) self.projectAutoIncludeNewFilesCheckBox.setChecked( Preferences.getProject("AutoIncludeNewFiles")) self.projectLoadSessionCheckBox.setChecked( Preferences.getProject("AutoLoadSession")) self.projectSaveSessionCheckBox.setChecked( Preferences.getProject("AutoSaveSession")) self.projectSessionAllBpCheckBox.setChecked( Preferences.getProject("SessionAllBreakpoints")) self.projectLoadDebugPropertiesCheckBox.setChecked( Preferences.getProject("AutoLoadDbgProperties")) self.projectSaveDebugPropertiesCheckBox.setChecked( Preferences.getProject("AutoSaveDbgProperties")) self.projectAutoCompileFormsCheckBox.setChecked( Preferences.getProject("AutoCompileForms")) self.projectAutoCompileResourcesCheckBox.setChecked( Preferences.getProject("AutoCompileResources")) self.projectTimestampCheckBox.setChecked( Preferences.getProject("XMLTimestamp")) self.projectRecentSpinBox.setValue( Preferences.getProject("RecentNumber")) self.pythonVariantCheckBox.setChecked( Preferences.getProject("DeterminePyFromProject")) self.autosaveTasksCheckBox.setChecked( Preferences.getTasks("TasksProjectAutoSave")) def save(self): """ Public slot to save the Project configuration. """ Preferences.setProject( "SearchNewFilesRecursively", self.projectSearchNewFilesRecursiveCheckBox.isChecked()) Preferences.setProject( "SearchNewFiles", self.projectSearchNewFilesCheckBox.isChecked()) Preferences.setProject( "AutoIncludeNewFiles", self.projectAutoIncludeNewFilesCheckBox.isChecked()) Preferences.setProject( "AutoLoadSession", self.projectLoadSessionCheckBox.isChecked()) Preferences.setProject( "AutoSaveSession", self.projectSaveSessionCheckBox.isChecked()) Preferences.setProject( "SessionAllBreakpoints", self.projectSessionAllBpCheckBox.isChecked()) Preferences.setProject( "AutoLoadDbgProperties", self.projectLoadDebugPropertiesCheckBox.isChecked()) Preferences.setProject( "AutoSaveDbgProperties", self.projectSaveDebugPropertiesCheckBox.isChecked()) Preferences.setProject( "AutoCompileForms", self.projectAutoCompileFormsCheckBox.isChecked()) Preferences.setProject( "AutoCompileResources", self.projectAutoCompileResourcesCheckBox.isChecked()) Preferences.setProject( "XMLTimestamp", self.projectTimestampCheckBox.isChecked()) Preferences.setProject( "RecentNumber", self.projectRecentSpinBox.value()) Preferences.setProject( "DeterminePyFromProject", self.pythonVariantCheckBox.isChecked()) Preferences.setTasks( "TasksProjectAutoSave", self.autosaveTasksCheckBox.isChecked()) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = ProjectPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorGeneralPage.py0000644000175000017500000000750312451233373024400 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor General configuration page. """ from __future__ import unicode_literals from PyQt5.Qsci import QsciScintillaBase from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorGeneralPage import Ui_EditorGeneralPage import Preferences class EditorGeneralPage(ConfigurationPageBase, Ui_EditorGeneralPage): """ Class implementing the Editor General configuration page. """ def __init__(self): """ Constructor """ super(EditorGeneralPage, self).__init__() self.setupUi(self) self.setObjectName("EditorGeneralPage") # set initial values self.tabwidthSlider.setValue( Preferences.getEditor("TabWidth")) self.indentwidthSlider.setValue( Preferences.getEditor("IndentWidth")) self.indentguidesCheckBox.setChecked( Preferences.getEditor("IndentationGuides")) self.tabforindentationCheckBox.setChecked( Preferences.getEditor("TabForIndentation")) self.tabindentsCheckBox.setChecked( Preferences.getEditor("TabIndents")) self.converttabsCheckBox.setChecked( Preferences.getEditor("ConvertTabsOnLoad")) self.autoindentCheckBox.setChecked( Preferences.getEditor("AutoIndentation")) self.comment0CheckBox.setChecked( Preferences.getEditor("CommentColumn0")) virtualSpaceOptions = Preferences.getEditor("VirtualSpaceOptions") self.vsSelectionCheckBox.setChecked( virtualSpaceOptions & QsciScintillaBase.SCVS_RECTANGULARSELECTION) self.vsUserCheckBox.setChecked( virtualSpaceOptions & QsciScintillaBase.SCVS_USERACCESSIBLE) def save(self): """ Public slot to save the Editor General configuration. """ Preferences.setEditor( "TabWidth", self.tabwidthSlider.value()) Preferences.setEditor( "IndentWidth", self.indentwidthSlider.value()) Preferences.setEditor( "IndentationGuides", self.indentguidesCheckBox.isChecked()) Preferences.setEditor( "TabForIndentation", self.tabforindentationCheckBox.isChecked()) Preferences.setEditor( "TabIndents", self.tabindentsCheckBox.isChecked()) Preferences.setEditor( "ConvertTabsOnLoad", self.converttabsCheckBox.isChecked()) Preferences.setEditor( "AutoIndentation", self.autoindentCheckBox.isChecked()) Preferences.setEditor( "CommentColumn0", self.comment0CheckBox.isChecked()) virtualSpaceOptions = QsciScintillaBase.SCVS_NONE if self.vsSelectionCheckBox.isChecked(): virtualSpaceOptions |= QsciScintillaBase.SCVS_RECTANGULARSELECTION if self.vsUserCheckBox.isChecked(): virtualSpaceOptions |= QsciScintillaBase.SCVS_USERACCESSIBLE Preferences.setEditor("VirtualSpaceOptions", virtualSpaceOptions) def on_tabforindentationCheckBox_toggled(self, checked): """ Private slot used to set the tab conversion check box. @param checked flag received from the signal (boolean) """ if checked and self.converttabsCheckBox.isChecked(): self.converttabsCheckBox.setChecked(not checked) self.converttabsCheckBox.setEnabled(not checked) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorGeneralPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorPropertiesPage.py0000644000175000017500000005620712451233373025164 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor Properties configuration page. """ from __future__ import unicode_literals from QScintilla.QsciScintillaCompat import QSCINTILLA_VERSION from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorPropertiesPage import Ui_EditorPropertiesPage import Preferences class EditorPropertiesPage(ConfigurationPageBase, Ui_EditorPropertiesPage): """ Class implementing the Editor Properties configuration page. """ def __init__(self, lexers): """ Constructor @param lexers reference to the lexers dictionary """ super(EditorPropertiesPage, self).__init__() self.setupUi(self) self.setObjectName("EditorPropertiesPage") self.languages = sorted(list(lexers.keys())[:]) # set initial values # All self.allFoldCompactCheckBox.setChecked( Preferences.getEditor("AllFoldCompact")) # Bash self.foldBashCommentCheckBox.setChecked( Preferences.getEditor("BashFoldComment")) # C++ self.foldCppCommentCheckBox.setChecked( Preferences.getEditor("CppFoldComment")) self.foldCppPreprocessorCheckBox.setChecked( Preferences.getEditor("CppFoldPreprocessor")) self.foldCppAtElseCheckBox.setChecked( Preferences.getEditor("CppFoldAtElse")) self.cppIndentOpeningBraceCheckBox.setChecked( Preferences.getEditor("CppIndentOpeningBrace")) self.cppIndentClosingBraceCheckBox.setChecked( Preferences.getEditor("CppIndentClosingBrace")) self.cppCaseInsensitiveCheckBox.setChecked( Preferences.getEditor("CppCaseInsensitiveKeywords")) self.cppDollarAllowedCheckBox.setChecked( Preferences.getEditor("CppDollarsAllowed")) if QSCINTILLA_VERSION() >= 0x020500: self.cppStylePreprocessorCheckBox.setChecked( Preferences.getEditor("CppStylePreprocessor")) else: self.cppStylePreprocessorCheckBox.setEnabled(False) if QSCINTILLA_VERSION() >= 0x020600: self.cppHighlightTripleQuotedCheckBox.setChecked( Preferences.getEditor("CppHighlightTripleQuotedStrings")) else: self.cppHighlightTripleQuotedCheckBox.setEnabled(False) if QSCINTILLA_VERSION() >= 0x020700: self.cppHighlightHashQuotedCheckBox.setChecked( Preferences.getEditor("CppHighlightHashQuotedStrings")) else: self.cppHighlightHashQuotedCheckBox.setEnabled(False) # CMake self.cmakeFoldAtElseCheckBox.setChecked( Preferences.getEditor("CMakeFoldAtElse")) # CoffeeScript if "CoffeeScript" in self.languages: self.foldCoffeeScriptCommentCheckBox.setChecked( Preferences.getEditor("CoffeScriptFoldComment")) self.coffeeScriptDollarAllowedCheckBox.setChecked( Preferences.getEditor("CoffeeScriptDollarsAllowed")) self.coffeeScriptStylePreprocessorCheckBox.setChecked( Preferences.getEditor("CoffeeScriptStylePreprocessor")) else: self.coffeeScriptGroup.setEnabled(False) # CSS self.foldCssCommentCheckBox.setChecked( Preferences.getEditor("CssFoldComment")) if QSCINTILLA_VERSION() >= 0x020700: self.cssHssCheckBox.setChecked( Preferences.getEditor("CssHssSupport")) self.cssLessCheckBox.setChecked( Preferences.getEditor("CssLessSupport")) self.cssSassyCheckBox.setChecked( Preferences.getEditor("CssSassySupport")) else: self.cssHssCheckBox.setEnabled(False) self.cssLessCheckBox.setEnabled(False) self.cssSassyCheckBox.setEnabled(False) # D self.foldDCommentCheckBox.setChecked( Preferences.getEditor("DFoldComment")) self.foldDAtElseCheckBox.setChecked( Preferences.getEditor("DFoldAtElse")) self.dIndentOpeningBraceCheckBox.setChecked( Preferences.getEditor("DIndentOpeningBrace")) self.dIndentClosingBraceCheckBox.setChecked( Preferences.getEditor("DIndentClosingBrace")) # Gettext if "Gettext" in self.languages: self.foldPoCommentCheckBox.setChecked( Preferences.getEditor("PoFoldComment")) else: self.gettextGroup.setEnabled(False) # HTML self.foldHtmlPreprocessorCheckBox.setChecked( Preferences.getEditor("HtmlFoldPreprocessor")) self.htmlCaseSensitiveTagsCheckBox.setChecked( Preferences.getEditor("HtmlCaseSensitiveTags")) self.foldHtmlScriptCommentsCheckBox.setChecked( Preferences.getEditor("HtmlFoldScriptComments")) self.foldHtmlScriptHereDocsCheckBox.setChecked( Preferences.getEditor("HtmlFoldScriptHeredocs")) if QSCINTILLA_VERSION() >= 0x020500: self.htmlDjangoCheckBox.setChecked( Preferences.getEditor("HtmlDjangoTemplates")) self.htmlMakoCheckBox.setChecked( Preferences.getEditor("HtmlMakoTemplates")) else: self.htmlDjangoCheckBox.setEnabled(False) self.htmlMakoCheckBox.setEnabled(False) # Pascal if "Pascal" in self.languages: self.pascalGroup.setEnabled(True) self.foldPascalCommentCheckBox.setChecked( Preferences.getEditor("PascalFoldComment")) self.foldPascalPreprocessorCheckBox.setChecked( Preferences.getEditor("PascalFoldPreprocessor")) if QSCINTILLA_VERSION() >= 0x020400: self.pascalSmartHighlightingCheckBox.setChecked( Preferences.getEditor("PascalSmartHighlighting")) else: self.pascalSmartHighlightingCheckBox.setEnabled(False) else: self.pascalGroup.setEnabled(False) # Perl self.foldPerlCommentCheckBox.setChecked( Preferences.getEditor("PerlFoldComment")) self.foldPerlPackagesCheckBox.setChecked( Preferences.getEditor("PerlFoldPackages")) self.foldPerlPODBlocksCheckBox.setChecked( Preferences.getEditor("PerlFoldPODBlocks")) if QSCINTILLA_VERSION() >= 0x020600: self.foldPerlAtElseCheckBox.setChecked( Preferences.getEditor("PerlFoldAtElse")) else: self.foldPerlAtElseCheckBox.setEnabled(False) # PostScript if "PostScript" in self.languages: self.postscriptGroup.setEnabled(True) self.psFoldAtElseCheckBox.setChecked( Preferences.getEditor("PostScriptFoldAtElse")) self.psMarkTokensCheckBox.setChecked( Preferences.getEditor("PostScriptTokenize")) self.psLevelSpinBox.setValue( Preferences.getEditor("PostScriptLevel")) else: self.postscriptGroup.setEnabled(False) # Povray self.foldPovrayCommentCheckBox.setChecked( Preferences.getEditor("PovFoldComment")) self.foldPovrayDirectivesCheckBox.setChecked( Preferences.getEditor("PovFoldDirectives")) # Properties if QSCINTILLA_VERSION() >= 0x020500: self.propertiesInitialSpacesCheckBox.setChecked( Preferences.getEditor("PropertiesInitialSpaces")) else: self.propertiesInitialSpacesCheckBox.setEnabled(False) # Python self.pythonBadIndentationComboBox.addItems([ self.tr("No Warning"), self.tr("Inconsistent"), self.tr("Tabs after Spaces"), self.tr("Spaces"), self.tr("Tabs"), ]) self.pythonBadIndentationComboBox.setCurrentIndex( Preferences.getEditor("PythonBadIndentation")) self.foldPythonCommentCheckBox.setChecked( Preferences.getEditor("PythonFoldComment")) self.foldPythonStringCheckBox.setChecked( Preferences.getEditor("PythonFoldString")) self.pythonAutoindentCheckBox.setChecked( Preferences.getEditor("PythonAutoIndent")) self.pythonV2UnicodeAllowedCheckBox.setChecked( Preferences.getEditor("PythonAllowV2Unicode")) self.pythonV3BinaryAllowedCheckBox.setChecked( Preferences.getEditor("PythonAllowV3Binary")) self.pythonV3BytesAllowedCheckBox.setChecked( Preferences.getEditor("PythonAllowV3Bytes")) if QSCINTILLA_VERSION() >= 0x020500: self.foldPythonQuotesCheckBox.setChecked( Preferences.getEditor("PythonFoldQuotes")) self.pythonStringsOverNewlineCheckBox.setChecked( Preferences.getEditor("PythonStringsOverNewLineAllowed")) else: self.foldPythonQuotesCheckBox.setEnabled(False) self.pythonStringsOverNewlineCheckBox.setEnabled(False) if QSCINTILLA_VERSION() >= 0x020600: self.pythonHighlightSubidentifierCheckBox.setChecked( Preferences.getEditor("PythonHighlightSubidentifier")) else: self.pythonHighlightSubidentifierCheckBox.setEnabled(False) # Ruby if QSCINTILLA_VERSION() >= 0x020500: self.foldRubyCommentCheckBox.setChecked( Preferences.getEditor("RubyFoldComment")) else: self.foldRubyCommentCheckBox.setEnabled(False) # SQL self.foldSqlCommentCheckBox.setChecked( Preferences.getEditor("SqlFoldComment")) self.sqlBackslashEscapesCheckBox.setChecked( Preferences.getEditor("SqlBackslashEscapes")) if QSCINTILLA_VERSION() >= 0x020500: self.sqlFoldAtElseCheckBox.setChecked( Preferences.getEditor("SqlFoldAtElse")) self.sqlFoldOnlyBeginCheckBox.setChecked( Preferences.getEditor("SqlFoldOnlyBegin")) self.sqlDottedWordsCheckBox.setChecked( Preferences.getEditor("SqlDottedWords")) self.sqlHashCommentsCheckBox.setChecked( Preferences.getEditor("SqlHashComments")) self.sqlQuotedIdentifiersCheckBox.setChecked( Preferences.getEditor("SqlQuotedIdentifiers")) else: self.sqlFoldAtElseCheckBox.setEnabled(False) self.sqlFoldOnlyBeginCheckBox.setEnabled(False) self.sqlDottedWordsCheckBox.setEnabled(False) self.sqlHashCommentsCheckBox.setEnabled(False) self.sqlQuotedIdentifiersCheckBox.setEnabled(False) # TCL if QSCINTILLA_VERSION() >= 0x020500: self.foldTclCommentCheckBox.setChecked( Preferences.getEditor("TclFoldComment")) else: self.foldTclCommentCheckBox.setEnabled(False) # TeX if QSCINTILLA_VERSION() >= 0x020500: self.foldTexCommentCheckBox.setChecked( Preferences.getEditor("TexFoldComment")) self.texProcessCommentsCheckBox.setChecked( Preferences.getEditor("TexProcessComments")) self.texProcessIfCheckBox.setChecked( Preferences.getEditor("TexProcessIf")) else: self.foldTexCommentCheckBox.setEnabled(False) self.texProcessCommentsCheckBox.setEnabled(False) self.texProcessIfCheckBox.setEnabled(False) # VHDL self.vhdlFoldCommentCheckBox.setChecked( Preferences.getEditor("VHDLFoldComment")) self.vhdlFoldAtElseCheckBox.setChecked( Preferences.getEditor("VHDLFoldAtElse")) self.vhdlFoldAtBeginCheckBox.setChecked( Preferences.getEditor("VHDLFoldAtBegin")) self.vhdlFoldAtParenthesisCheckBox.setChecked( Preferences.getEditor("VHDLFoldAtParenthesis")) # XML self.xmlSyleScriptsCheckBox.setChecked( Preferences.getEditor("XMLStyleScripts")) # YAML if "YAML" in self.languages: self.yamlGroup.setEnabled(True) self.foldYamlCommentCheckBox.setChecked( Preferences.getEditor("YAMLFoldComment")) else: self.yamlGroup.setEnabled(False) def save(self): """ Public slot to save the Editor Properties (1) configuration. """ # All Preferences.setEditor( "AllFoldCompact", self.allFoldCompactCheckBox.isChecked()) # Bash Preferences.setEditor( "BashFoldComment", self.foldBashCommentCheckBox.isChecked()) # CMake Preferences.setEditor( "CMakeFoldAtElse", self.cmakeFoldAtElseCheckBox.isChecked()) # C++ Preferences.setEditor( "CppFoldComment", self.foldCppCommentCheckBox.isChecked()) Preferences.setEditor( "CppFoldPreprocessor", self.foldCppPreprocessorCheckBox.isChecked()) Preferences.setEditor( "CppFoldAtElse", self.foldCppAtElseCheckBox.isChecked()) Preferences.setEditor( "CppIndentOpeningBrace", self.cppIndentOpeningBraceCheckBox.isChecked()) Preferences.setEditor( "CppIndentClosingBrace", self.cppIndentClosingBraceCheckBox.isChecked()) Preferences.setEditor( "CppCaseInsensitiveKeywords", self.cppCaseInsensitiveCheckBox.isChecked()) Preferences.setEditor( "CppDollarsAllowed", self.cppDollarAllowedCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020500: Preferences.setEditor( "CppStylePreprocessor", self.cppStylePreprocessorCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020600: Preferences.setEditor( "CppHighlightTripleQuotedStrings", self.cppHighlightTripleQuotedCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020700: Preferences.setEditor( "CppHighlightHashQuotedStrings", self.cppHighlightHashQuotedCheckBox.isChecked()) # CMake Preferences.setEditor( "CMakeFoldAtElse", self.cmakeFoldAtElseCheckBox.isChecked()) # CoffeeScript if "CoffeeScript" in self.languages: Preferences.setEditor( "CoffeScriptFoldComment", self.foldCoffeeScriptCommentCheckBox.isChecked()) Preferences.setEditor( "CoffeeScriptDollarsAllowed", self.coffeeScriptDollarAllowedCheckBox.isChecked()) Preferences.setEditor( "CoffeeScriptStylePreprocessor", self.coffeeScriptStylePreprocessorCheckBox.isChecked()) # CSS Preferences.setEditor( "CssFoldComment", self.foldCssCommentCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020700: Preferences.setEditor( "CssHssSupport", self.cssHssCheckBox.isChecked()) Preferences.setEditor( "CssLessSupport", self.cssLessCheckBox.isChecked()) Preferences.setEditor( "CssSassySupport", self.cssSassyCheckBox.isChecked()) # D Preferences.setEditor( "DFoldComment", self.foldDCommentCheckBox.isChecked()) Preferences.setEditor( "DFoldAtElse", self.foldDAtElseCheckBox.isChecked()) Preferences.setEditor( "DIndentOpeningBrace", self.dIndentOpeningBraceCheckBox.isChecked()) Preferences.setEditor( "DIndentClosingBrace", self.dIndentClosingBraceCheckBox.isChecked()) # Gettext if "Gettext" in self.languages: Preferences.setEditor( "PoFoldComment", self.foldPoCommentCheckBox.isChecked()) # HTML Preferences.setEditor( "HtmlFoldPreprocessor", self.foldHtmlPreprocessorCheckBox.isChecked()) Preferences.setEditor( "HtmlCaseSensitiveTags", self.htmlCaseSensitiveTagsCheckBox.isChecked()) Preferences.setEditor( "HtmlFoldScriptComments", self.foldHtmlScriptCommentsCheckBox.isChecked()) Preferences.setEditor( "HtmlFoldScriptHeredocs", self.foldHtmlScriptHereDocsCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020500: Preferences.setEditor( "HtmlDjangoTemplates", self.htmlDjangoCheckBox.isChecked()) Preferences.setEditor( "HtmlMakoTemplates", self.htmlMakoCheckBox.isChecked()) # Pascal if "Pascal" in self.languages: Preferences.setEditor( "PascalFoldComment", self.foldPascalCommentCheckBox.isChecked()) Preferences.setEditor( "PascalFoldPreprocessor", self.foldPascalPreprocessorCheckBox.isChecked()) Preferences.setEditor( "PascalSmartHighlighting", self.pascalSmartHighlightingCheckBox.isChecked()) # Perl Preferences.setEditor( "PerlFoldComment", self.foldPerlCommentCheckBox.isChecked()) Preferences.setEditor( "PerlFoldPackages", self.foldPerlPackagesCheckBox.isChecked()) Preferences.setEditor( "PerlFoldPODBlocks", self.foldPerlPODBlocksCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020600: Preferences.setEditor( "PerlFoldAtElse", self.foldPerlAtElseCheckBox.isChecked()) # PostScript if "PostScript" in self.languages: Preferences.setEditor( "PostScriptFoldAtElse", self.psFoldAtElseCheckBox.isChecked()) Preferences.setEditor( "PostScriptTokenize", self.psMarkTokensCheckBox.isChecked()) Preferences.setEditor( "PostScriptLevel", self.psLevelSpinBox.value()) # Povray Preferences.setEditor( "PovFoldComment", self.foldPovrayCommentCheckBox.isChecked()) Preferences.setEditor( "PovFoldDirectives", self.foldPovrayDirectivesCheckBox.isChecked()) # Properties if QSCINTILLA_VERSION() >= 0x020500: Preferences.setEditor( "PropertiesInitialSpaces", self.propertiesInitialSpacesCheckBox.isChecked()) # Python Preferences.setEditor( "PythonFoldComment", self.foldPythonCommentCheckBox.isChecked()) Preferences.setEditor( "PythonFoldString", self.foldPythonStringCheckBox.isChecked()) Preferences.setEditor( "PythonBadIndentation", self.pythonBadIndentationComboBox.currentIndex()) Preferences.setEditor( "PythonAutoIndent", self.pythonAutoindentCheckBox.isChecked()) Preferences.setEditor( "PythonAllowV2Unicode", self.pythonV2UnicodeAllowedCheckBox.isChecked()) Preferences.setEditor( "PythonAllowV3Binary", self.pythonV3BinaryAllowedCheckBox.isChecked()) Preferences.setEditor( "PythonAllowV3Bytes", self.pythonV3BytesAllowedCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020500: Preferences.setEditor( "PythonFoldQuotes", self.foldPythonQuotesCheckBox.isChecked()) Preferences.setEditor( "PythonStringsOverNewLineAllowed", self.pythonStringsOverNewlineCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020600: Preferences.setEditor( "PythonHighlightSubidentifier", self.pythonHighlightSubidentifierCheckBox.isChecked()) # Ruby if QSCINTILLA_VERSION() >= 0x020500: Preferences.setEditor( "RubyFoldComment", self.foldRubyCommentCheckBox.isChecked()) # SQL Preferences.setEditor( "SqlFoldComment", self.foldSqlCommentCheckBox.isChecked()) Preferences.setEditor( "SqlBackslashEscapes", self.sqlBackslashEscapesCheckBox.isChecked()) if QSCINTILLA_VERSION() >= 0x020500: Preferences.setEditor( "SqlFoldAtElse", self.sqlFoldAtElseCheckBox.isChecked()) Preferences.setEditor( "SqlFoldOnlyBegin", self.sqlFoldOnlyBeginCheckBox.isChecked()) Preferences.setEditor( "SqlDottedWords", self.sqlDottedWordsCheckBox.isChecked()) Preferences.setEditor( "SqlHashComments", self.sqlHashCommentsCheckBox.isChecked()) Preferences.setEditor( "SqlQuotedIdentifiers", self.sqlQuotedIdentifiersCheckBox.isChecked()) # TCL if QSCINTILLA_VERSION() >= 0x020500: Preferences.setEditor( "TclFoldComment", self.foldTclCommentCheckBox.isChecked()) # TeX if QSCINTILLA_VERSION() >= 0x020500: Preferences.setEditor( "TexFoldComment", self.foldTexCommentCheckBox.isChecked()) Preferences.setEditor( "TexProcessComments", self.texProcessCommentsCheckBox.isChecked()) Preferences.setEditor( "TexProcessIf", self.texProcessIfCheckBox.isChecked()) # VHDL Preferences.setEditor( "VHDLFoldComment", self.vhdlFoldCommentCheckBox.isChecked()) Preferences.setEditor( "VHDLFoldAtElse", self.vhdlFoldAtElseCheckBox.isChecked()) Preferences.setEditor( "VHDLFoldAtBegin", self.vhdlFoldAtBeginCheckBox.isChecked()) Preferences.setEditor( "VHDLFoldAtParenthesis", self.vhdlFoldAtParenthesisCheckBox.isChecked()) # XML Preferences.setEditor( "XMLStyleScripts", self.xmlSyleScriptsCheckBox.isChecked()) # YAML if "YAML" in self.languages: Preferences.setEditor( "YAMLFoldComment", self.foldYamlCommentCheckBox.isChecked()) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorPropertiesPage(dlg.getLexers()) return page eric-6.0.8/eric/Preferences/ConfigurationPages/EditorTypingPage.py0000644000175000017500000001575112451233373024301 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Editor Typing configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorTypingPage import Ui_EditorTypingPage import Preferences class EditorTypingPage(ConfigurationPageBase, Ui_EditorTypingPage): """ Class implementing the Editor Typing configuration page. """ def __init__(self): """ Constructor """ super(EditorTypingPage, self).__init__() self.setupUi(self) self.setObjectName("EditorTypingPage") # set initial values self.pageIds = {} self.pageIds[' '] = self.stackedWidget.indexOf(self.emptyPage) self.pageIds['Python'] = self.stackedWidget.indexOf(self.pythonPage) self.pageIds['Ruby'] = self.stackedWidget.indexOf(self.rubyPage) languages = sorted(list(self.pageIds.keys())) for language in languages: self.languageCombo.addItem(language, self.pageIds[language]) # Python self.pythonGroup.setChecked( Preferences.getEditorTyping("Python/EnabledTypingAids")) self.pythonInsertClosingBraceCheckBox.setChecked( Preferences.getEditorTyping("Python/InsertClosingBrace")) self.pythonSkipBraceCheckBox.setChecked( Preferences.getEditorTyping("Python/SkipBrace")) self.pythonIndentBraceCheckBox.setChecked( Preferences.getEditorTyping("Python/IndentBrace")) self.pythonInsertQuoteCheckBox.setChecked( Preferences.getEditorTyping("Python/InsertQuote")) self.pythonDedentElseCheckBox.setChecked( Preferences.getEditorTyping("Python/DedentElse")) self.pythonDedentExceptCheckBox.setChecked( Preferences.getEditorTyping("Python/DedentExcept")) self.pythonDedentExceptPy24CheckBox.setChecked( Preferences.getEditorTyping("Python/Py24StyleTry")) self.pythonInsertImportCheckBox.setChecked( Preferences.getEditorTyping("Python/InsertImport")) self.pythonInsertSelfCheckBox.setChecked( Preferences.getEditorTyping("Python/InsertSelf")) self.pythonInsertBlankCheckBox.setChecked( Preferences.getEditorTyping("Python/InsertBlank")) self.pythonColonDetectionCheckBox.setChecked( Preferences.getEditorTyping("Python/ColonDetection")) self.pythonDedentDefCheckBox.setChecked( Preferences.getEditorTyping("Python/DedentDef")) # Ruby self.rubyGroup.setChecked( Preferences.getEditorTyping("Ruby/EnabledTypingAids")) self.rubyInsertClosingBraceCheckBox.setChecked( Preferences.getEditorTyping("Ruby/InsertClosingBrace")) self.rubySkipBraceCheckBox.setChecked( Preferences.getEditorTyping("Ruby/SkipBrace")) self.rubyIndentBraceCheckBox.setChecked( Preferences.getEditorTyping("Ruby/IndentBrace")) self.rubyInsertQuoteCheckBox.setChecked( Preferences.getEditorTyping("Ruby/InsertQuote")) self.rubyInsertBlankCheckBox.setChecked( Preferences.getEditorTyping("Ruby/InsertBlank")) self.rubyInsertHereDocCheckBox.setChecked( Preferences.getEditorTyping("Ruby/InsertHereDoc")) self.rubyInsertInlineDocCheckBox.setChecked( Preferences.getEditorTyping("Ruby/InsertInlineDoc")) self.on_languageCombo_activated(' ') def save(self): """ Public slot to save the Editor Typing configuration. """ # Python Preferences.setEditorTyping( "Python/EnabledTypingAids", self.pythonGroup.isChecked()) Preferences.setEditorTyping( "Python/InsertClosingBrace", self.pythonInsertClosingBraceCheckBox.isChecked()) Preferences.setEditorTyping( "Python/SkipBrace", self.pythonSkipBraceCheckBox.isChecked()) Preferences.setEditorTyping( "Python/IndentBrace", self.pythonIndentBraceCheckBox.isChecked()) Preferences.setEditorTyping( "Python/InsertQuote", self.pythonInsertQuoteCheckBox.isChecked()) Preferences.setEditorTyping( "Python/DedentElse", self.pythonDedentElseCheckBox.isChecked()) Preferences.setEditorTyping( "Python/DedentExcept", self.pythonDedentExceptCheckBox.isChecked()) Preferences.setEditorTyping( "Python/Py24StyleTry", self.pythonDedentExceptPy24CheckBox.isChecked()) Preferences.setEditorTyping( "Python/InsertImport", self.pythonInsertImportCheckBox.isChecked()) Preferences.setEditorTyping( "Python/InsertSelf", self.pythonInsertSelfCheckBox.isChecked()) Preferences.setEditorTyping( "Python/InsertBlank", self.pythonInsertBlankCheckBox.isChecked()) Preferences.setEditorTyping( "Python/ColonDetection", self.pythonColonDetectionCheckBox.isChecked()) Preferences.setEditorTyping( "Python/DedentDef", self.pythonDedentDefCheckBox.isChecked()) # Ruby Preferences.setEditorTyping( "Ruby/EnabledTypingAids", self.rubyGroup.isChecked()) Preferences.setEditorTyping( "Ruby/InsertClosingBrace", self.rubyInsertClosingBraceCheckBox.isChecked()) Preferences.setEditorTyping( "Ruby/SkipBrace", self.rubySkipBraceCheckBox.isChecked()) Preferences.setEditorTyping( "Ruby/IndentBrace", self.rubyIndentBraceCheckBox.isChecked()) Preferences.setEditorTyping( "Ruby/InsertQuote", self.rubyInsertQuoteCheckBox.isChecked()) Preferences.setEditorTyping( "Ruby/InsertBlank", self.rubyInsertBlankCheckBox.isChecked()) Preferences.setEditorTyping( "Ruby/InsertHereDoc", self.rubyInsertHereDocCheckBox.isChecked()) Preferences.setEditorTyping( "Ruby/InsertInlineDoc", self.rubyInsertInlineDocCheckBox.isChecked()) @pyqtSlot(str) def on_languageCombo_activated(self, language): """ Private slot to select the page related to the selected language. @param language name of the selected language (string) """ try: index = self.pageIds[language] except KeyError: index = self.pageIds[' '] self.stackedWidget.setCurrentIndex(index) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorTypingPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/HelpInterfacePage.ui0000644000175000017500000000466212263305625024356 0ustar piotrpiotr HelpInterfacePage 0 0 557 152 <b>Configure User Interface</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Style: Select the interface style Style Sheet: Enter the name of the style sheet file Select the style sheet file via a file selection dialog Qt::Vertical 537 41 styleComboBox styleSheetEdit styleSheetButton eric-6.0.8/eric/Preferences/ConfigurationPages/EditorHighlightingStylesPage.ui0000644000175000017500000002112212440571010026601 0ustar piotrpiotr EditorHighlightingStylesPage 0 0 550 592 <b>Configure syntax highlighting</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Lexer Language: 0 0 Select the lexer language to be configured. Style Element QAbstractItemView::ExtendedSelection Select the foreground colour. Foreground Colour Select the background colour. Background Colour Select the font. Font Select end of line fill. Fill to end of line Qt::Horizontal Press to set the current style to its default values to Default Qt::Vertical 20 51 Select the background colour for all styles All Background Colours Select the font for all styles. All Fonts Select the eol fill for all styles All Fill to end of line Qt::Horizontal Press to set all styles to their default values All to Default Qt::NoFocus Sample Text Qt::AlignHCenter true <b>Note:</b> The tick in the list above indicates the entrie's 'fill to end of line' setting. true false Imports all styles of the currently selected language Import styles false Exports all styles of the currently selected language Export styles Imports all styles of all languages Import all styles Exports all styles of all languages Export all styles lexerLanguageComboBox styleElementList foregroundButton backgroundButton fontButton eolfillCheckBox defaultButton allBackgroundColoursButton allFontsButton allEolFillButton allDefaultButton eric-6.0.8/eric/Preferences/ConfigurationPages/EditorGeneralPage.ui0000644000175000017500000002325212146416015024361 0ustar piotrpiotr EditorGeneralPage 0 0 559 593 <b>Configure general editor settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Tabs && Indentation Tab width: tabwidthSlider Move to set the tab width. 1 20 4 Qt::Horizontal 1 Displays the selected tab width. 2 QLCDNumber::Flat 4.000000000000000 Indentation width: indentwidthSlider Move to set the indentation width. 1 20 4 Qt::Horizontal 1 Displays the selected indentation width. 2 QLCDNumber::Flat 4.000000000000000 Select whether indentation guides should be shown. Show Indentation Guides Select whether tab characters are used for indentations. Use tabs for indentations Select whether autoindentation shall be enabled Auto indentation Select whether tabs shall be converted upon opening the file Convert tabs upon open Select whether pressing the tab key indents. Tab key indents Comments Select to insert the comment sign at column 0 <b>Insert comment at column 0</b><p>Select to insert the comment sign at column 0. Otherwise, the comment sign is inserted at the first non-whitespace position.</p> Insert comment at column 0 Virtual Space Virtual space is the space after the last character of a line. It is not allocated unless some text is entered or copied into it. Usage of virtual space can be configured with these selections. true Select to enable a rectangular selection to extend into virtual space Selection may access virtual space Select to allow the cursor to be moved into virtual space Cursor can move into virtual space Qt::Vertical 535 101 tabwidthSlider indentwidthSlider indentguidesCheckBox autoindentCheckBox tabindentsCheckBox tabforindentationCheckBox converttabsCheckBox tabwidthSlider valueChanged(int) tabwidthLCD display(int) 384 81 415 82 indentwidthSlider valueChanged(int) indentwidthLCD display(int) 384 110 410 110 eric-6.0.8/eric/Preferences/ConfigurationPages/EditorHighlightersPage.ui0000644000175000017500000000733012060166053025423 0ustar piotrpiotr EditorHighlightersPage 0 0 400 361 <b>Configure syntax highlighters</b> QFrame::HLine QFrame::Sunken Qt::Horizontal true false true Filename Pattern Lexer Language Filename Pattern: Enter the filename pattern to be associated Press to add or change the entered association Add/Change Lexer Language: Select the lexer language to associate Press to delete the selected association Delete Alternative Lexer: Select the alternative lexer to associate editorLexerList editorFileExtEdit editorLexerCombo pygmentsLexerCombo addLexerButton deleteLexerButton eric-6.0.8/eric/Preferences/ConfigurationPages/NotificationsPage.ui0000644000175000017500000001224712060166053024447 0ustar piotrpiotr NotificationsPage 0 0 507 300 <b>Configure notification settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select to enable notifications Enable Notifications Auto Close Timeout: Enter the timeout for closing the notification Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter s 1 10 Qt::Horizontal 40 20 Position X: Enter the X-position the notification should be shown at Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter -10000 10000 Y: Enter the Y-position the notification should be shown at Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter -10000 10000 Press to select the position visually, release to get it Visual Selection true Qt::Vertical 20 142 enableCheckBox timeoutSpinBox xSpinBox ySpinBox visualButton eric-6.0.8/eric/Preferences/ConfigurationPages/MasterPasswordEntryDialog.ui0000644000175000017500000001135512060166053026160 0ustar piotrpiotr MasterPasswordEntryDialog 0 0 450 300 Master Password true <p>Enter your master password below. This password will be used to encrypt sensitive data. You will be asked once per session for this password when the data needs to be accessed for the first time.<br/><br/><b>Note: If you forget the master password, the encrypted data cannot be recovered!</b></p> true Qt::Vertical 20 28 Current Password: Enter the current password QLineEdit::Password New Password: Enter the new password QLineEdit::Password New Password (again): Repeat the new password QLineEdit::Password Shows an indication for the password strength color : red; true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok E5PasswordMeter QProgressBar
E5Gui/E5PasswordMeter
currentPasswordEdit newPasswordEdit newPasswordAgainEdit buttonBox buttonBox accepted() MasterPasswordEntryDialog accept() 248 254 157 274 buttonBox rejected() MasterPasswordEntryDialog reject() 316 260 286 274
eric-6.0.8/eric/Preferences/ConfigurationPages/IconsPage.py0000644000175000017500000001360012451233373022722 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Icons configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QListWidgetItem from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_IconsPage import Ui_IconsPage import Preferences import Utilities import UI.PixmapCache class IconsPage(ConfigurationPageBase, Ui_IconsPage): """ Class implementing the Icons configuration page. """ def __init__(self): """ Constructor """ super(IconsPage, self).__init__() self.setupUi(self) self.setObjectName("IconsPage") self.iconDirectoryButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.iconDirectoryCompleter = E5DirCompleter(self.iconDirectoryEdit) # set initial values dirList = Preferences.getIcons("Path")[:] for dir in dirList: if dir: QListWidgetItem(dir, self.iconDirectoryList) def save(self): """ Public slot to save the Icons configuration. """ dirList = [] for i in range(self.iconDirectoryList.count()): dirList.append(self.iconDirectoryList.item(i).text()) Preferences.setIcons("Path", dirList) def on_iconDirectoryList_currentRowChanged(self, row): """ Private slot to handle the currentRowChanged signal of the icons directory list. @param row the current row (integer) """ if row == -1: self.deleteIconDirectoryButton.setEnabled(False) self.upButton.setEnabled(False) self.downButton.setEnabled(False) self.showIconsButton.setEnabled( self.iconDirectoryEdit.text() != "") else: maxIndex = self.iconDirectoryList.count() - 1 self.upButton.setEnabled(row != 0) self.downButton.setEnabled(row != maxIndex) self.deleteIconDirectoryButton.setEnabled(True) self.showIconsButton.setEnabled(True) def on_iconDirectoryEdit_textChanged(self, txt): """ Private slot to handle the textChanged signal of the directory edit. @param txt the text of the directory edit (string) """ self.addIconDirectoryButton.setEnabled(txt != "") self.showIconsButton.setEnabled( txt != "" or self.iconDirectoryList.currentRow() != -1) @pyqtSlot() def on_upButton_clicked(self): """ Private slot called to move the selected item up in the list. """ row = self.iconDirectoryList.currentRow() if row == 0: # we're already at the top return itm = self.iconDirectoryList.takeItem(row) self.iconDirectoryList.insertItem(row - 1, itm) self.iconDirectoryList.setCurrentItem(itm) if row == 1: self.upButton.setEnabled(False) else: self.upButton.setEnabled(True) self.downButton.setEnabled(True) @pyqtSlot() def on_downButton_clicked(self): """ Private slot called to move the selected item down in the list. """ rows = self.iconDirectoryList.count() row = self.iconDirectoryList.currentRow() if row == rows - 1: # we're already at the end return itm = self.iconDirectoryList.takeItem(row) self.iconDirectoryList.insertItem(row + 1, itm) self.iconDirectoryList.setCurrentItem(itm) self.upButton.setEnabled(True) if row == rows - 2: self.downButton.setEnabled(False) else: self.downButton.setEnabled(True) @pyqtSlot() def on_iconDirectoryButton_clicked(self): """ Private slot to select an icon directory. """ dir = E5FileDialog.getExistingDirectory( None, self.tr("Select icon directory"), "", E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if dir: self.iconDirectoryEdit.setText(Utilities.toNativeSeparators(dir)) @pyqtSlot() def on_addIconDirectoryButton_clicked(self): """ Private slot to add the icon directory displayed to the listbox. """ dir = self.iconDirectoryEdit.text() if dir: QListWidgetItem(dir, self.iconDirectoryList) self.iconDirectoryEdit.clear() row = self.iconDirectoryList.currentRow() self.on_iconDirectoryList_currentRowChanged(row) @pyqtSlot() def on_deleteIconDirectoryButton_clicked(self): """ Private slot to delete the currently selected directory of the listbox. """ row = self.iconDirectoryList.currentRow() itm = self.iconDirectoryList.takeItem(row) del itm row = self.iconDirectoryList.currentRow() self.on_iconDirectoryList_currentRowChanged(row) @pyqtSlot() def on_showIconsButton_clicked(self): """ Private slot to display a preview of an icons directory. """ dir = self.iconDirectoryEdit.text() if not dir: itm = self.iconDirectoryList.currentItem() if itm is not None: dir = itm.text() if dir: from .IconsPreviewDialog import IconsPreviewDialog dlg = IconsPreviewDialog(self, dir) dlg.exec_() def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = IconsPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/ShellPage.ui0000644000175000017500000001572312140200431022673 0ustar piotrpiotr ShellPage 0 0 587 538 <b>Configure Shell</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select whether line numbers margin should be shown. Show Line Numbers Margin Select this to enable calltips Calltips Enabled Select to enable wrapping at word boundaries Word Wrap Enabled Select this to enable autocompletion Autocompletion Enabled Select to enable syntax highlighting Syntax Highlighting Enabled max. History Entries: Enter the number of history entries allowed 10 1000 10 100 Qt::Horizontal QSizePolicy::Expanding 40 20 Select to show debuggee stdout and stderr Show stdout and stderr of debuggee Font Press to select the font to be used as the monospaced font Monospaced Font Qt::NoFocus Monospaced Text Qt::AlignHCenter true Select, whether the monospaced font should be used as default Use monospaced as default Press to select the font for the line numbers Line Numbers Font 200 0 Qt::NoFocus 2345 Qt::AlignHCenter true Qt::Vertical 20 40 shellLinenoCheckBox shellACEnabledCheckBox shellSyntaxHighlightingCheckBox shellWordWrapCheckBox shellCTEnabledCheckBox shellHistorySpinBox eric-6.0.8/eric/Preferences/ConfigurationPages/EditorAutocompletionPage.py0000644000175000017500000000412112451233373026016 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Editor Autocompletion configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorAutocompletionPage import Ui_EditorAutocompletionPage import Preferences class EditorAutocompletionPage(ConfigurationPageBase, Ui_EditorAutocompletionPage): """ Class implementing the Editor Autocompletion configuration page. """ def __init__(self): """ Constructor """ super(EditorAutocompletionPage, self).__init__() self.setupUi(self) self.setObjectName("EditorAutocompletionPage") # set initial values self.acEnabledCheckBox.setChecked( Preferences.getEditor("AutoCompletionEnabled")) self.acCaseSensitivityCheckBox.setChecked( Preferences.getEditor("AutoCompletionCaseSensitivity")) self.acReplaceWordCheckBox.setChecked( Preferences.getEditor("AutoCompletionReplaceWord")) self.acThresholdSlider.setValue( Preferences.getEditor("AutoCompletionThreshold")) def save(self): """ Public slot to save the Editor Autocompletion configuration. """ Preferences.setEditor( "AutoCompletionEnabled", self.acEnabledCheckBox.isChecked()) Preferences.setEditor( "AutoCompletionCaseSensitivity", self.acCaseSensitivityCheckBox.isChecked()) Preferences.setEditor( "AutoCompletionReplaceWord", self.acReplaceWordCheckBox.isChecked()) Preferences.setEditor( "AutoCompletionThreshold", self.acThresholdSlider.value()) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorAutocompletionPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/TrayStarterPage.py0000644000175000017500000000450112451233373024133 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the tray starter configuration page. """ from __future__ import unicode_literals from .ConfigurationPageBase import ConfigurationPageBase from .Ui_TrayStarterPage import Ui_TrayStarterPage import Preferences import UI.PixmapCache class TrayStarterPage(ConfigurationPageBase, Ui_TrayStarterPage): """ Class implementing the tray starter configuration page. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(TrayStarterPage, self).__init__() self.setupUi(self) self.setObjectName("TrayStarterPage") self.standardButton.setIcon(UI.PixmapCache.getIcon("erict.png")) self.highContrastButton.setIcon(UI.PixmapCache.getIcon("erict-hc.png")) self.blackWhiteButton.setIcon(UI.PixmapCache.getIcon("erict-bw.png")) self.blackWhiteInverseButton.setIcon( UI.PixmapCache.getIcon("erict-bwi.png")) # set initial values iconName = Preferences.getTrayStarter("TrayStarterIcon") if iconName == "erict.png": self.standardButton.setChecked(True) elif iconName == "erict-hc.png": self.highContrastButton.setChecked(True) elif iconName == "erict-bw.png": self.blackWhiteButton.setChecked(True) elif iconName == "erict-bwi.png": self.blackWhiteInverseButton.setChecked(True) def save(self): """ Public slot to save the Python configuration. """ if self.standardButton.isChecked(): iconName = "erict.png" elif self.highContrastButton.isChecked(): iconName = "erict-hc.png" elif self.blackWhiteButton.isChecked(): iconName = "erict-bw.png" elif self.blackWhiteInverseButton.isChecked(): iconName = "erict-bwi.png" Preferences.setTrayStarter("TrayStarterIcon", iconName) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = TrayStarterPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/ViewmanagerPage.ui0000644000175000017500000001403512060166053024100 0ustar piotrpiotr ViewmanagerPage 0 0 406 315 <b>Configure viewmanager</b> QFrame::HLine QFrame::Sunken Qt::Horizontal <font color="#FF0000"><b>Note:</b> This setting is activated at the next startup of the application.</font> Window view: windowComboBox 0 0 Select the window view type. The kind of window view can be selected from this list. The picture below gives an example of the selected view type. Preview of selected window view This displays a small preview of the selected window view. This is the way the source windows are displayed in the application. false Qt::AlignCenter Qt::Horizontal false Tabbed View Filename Length of Tab: Enter the number of characters to be shown in the tab. 1 100 40 Qt::Horizontal 81 20 Select to display the filename only Show filename only Recent Files Number of recent files: Enter the number of recent files to remember Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 5 50 Qt::Horizontal 40 20 Qt::Vertical 388 20 eric-6.0.8/eric/Preferences/ConfigurationPages/HelpAppearancePage.ui0000644000175000017500000001531412263305125024504 0ustar piotrpiotr HelpAppearancePage 0 0 499 547 <b>Configure help viewer appearance</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Fonts Press to select the standard font Standard Font Qt::NoFocus Times 16 Qt::AlignHCenter true Press to select the fixed-width font Fixed-Width Font Qt::NoFocus Courier 13 Qt::AlignHCenter true Colours Background colour of secure URLs: 100 0 Select the background colour for secure URLs. Qt::Horizontal 141 20 Images Select to load images Load images Style Sheet User Style Sheet: Enter the file name of a user style sheet Select the user style sheet via a file selection dialog Tabs Show only one close button instead of one for each tab Select to issue a warning, if multiple tabs are about to be closed Warn, if multiple tabs are about to be closed Qt::Vertical 479 121 standardFontButton fixedFontButton secureURLsColourButton autoLoadImagesCheckBox styleSheetEdit styleSheetButton eric-6.0.8/eric/Preferences/ConfigurationPages/EditorAPIsPage.ui0000644000175000017500000001343312263304755023607 0ustar piotrpiotr EditorAPIsPage 0 0 462 422 <b>Configure API files</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select to compile the APIs automatically upon loading Compile APIs automatically Language: 0 0 Select the language to be configured. false APIs List of API files true Press to delete the selected file from the list Delete Press to add the entered file to the list Add Enter a file to be added Press to select an API file from the list of installed API files Add from installed APIs Press to select an API file from the list of API files installed by plugins Add from Plugin APIs Qt::Horizontal Press to compile the selected APIs definition Compile APIs 0 false Qt::Horizontal Press to select an API file via a selection dialog apiAutoPrepareCheckBox apiLanguageComboBox apiList deleteApiFileButton apiFileEdit apiFileButton addApiFileButton addInstalledApiFileButton addPluginApiFileButton prepareApiButton eric-6.0.8/eric/Preferences/ConfigurationPages/MultiProjectPage.py0000644000175000017500000000542612451233373024277 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the Multi Project configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from .ConfigurationPageBase import ConfigurationPageBase from .Ui_MultiProjectPage import Ui_MultiProjectPage from E5Gui import E5FileDialog import Preferences import Utilities import UI.PixmapCache class MultiProjectPage(ConfigurationPageBase, Ui_MultiProjectPage): """ Class implementing the Multi Project configuration page. """ def __init__(self): """ Constructor """ super(MultiProjectPage, self).__init__() self.setupUi(self) self.setObjectName("MultiProjectPage") self.workspaceButton.setIcon(UI.PixmapCache.getIcon("open.png")) # set initial values self.openMasterAutomaticallyCheckBox.setChecked( Preferences.getMultiProject("OpenMasterAutomatically")) self.multiProjectTimestampCheckBox.setChecked( Preferences.getMultiProject("XMLTimestamp")) self.multiProjectRecentSpinBox.setValue( Preferences.getMultiProject("RecentNumber")) self.workspaceEdit.setText( Utilities.toNativeSeparators( Preferences.getMultiProject("Workspace") or Utilities.getHomeDir())) def save(self): """ Public slot to save the Project configuration. """ Preferences.setMultiProject( "OpenMasterAutomatically", self.openMasterAutomaticallyCheckBox.isChecked()) Preferences.setMultiProject( "XMLTimestamp", self.multiProjectTimestampCheckBox.isChecked()) Preferences.setMultiProject( "RecentNumber", self.multiProjectRecentSpinBox.value()) Preferences.setMultiProject( "Workspace", self.workspaceEdit.text()) @pyqtSlot() def on_workspaceButton_clicked(self): """ Private slot to display a directory selection dialog. """ default = self.workspaceEdit.text() if default == "": default = Utilities.getHomeDir() directory = E5FileDialog.getExistingDirectory( self, self.tr("Select Workspace Directory"), default, E5FileDialog.Options(0)) if directory: self.workspaceEdit.setText(Utilities.toNativeSeparators(directory)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = MultiProjectPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/NetworkPage.py0000644000175000017500000002015412451233373023302 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the Network configuration page. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from E5Network.E5Ftp import E5FtpProxyType from .ConfigurationPageBase import ConfigurationPageBase from .Ui_NetworkPage import Ui_NetworkPage import Preferences import Utilities import UI.PixmapCache class NetworkPage(ConfigurationPageBase, Ui_NetworkPage): """ Class implementing the Network configuration page. """ def __init__(self): """ Constructor """ super(NetworkPage, self).__init__() self.setupUi(self) self.setObjectName("NetworkPage") self.downloadDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.downloadDirCompleter = E5DirCompleter(self.downloadDirEdit) self.ftpProxyTypeCombo.addItem( self.tr("No FTP Proxy"), E5FtpProxyType.NoProxy) self.ftpProxyTypeCombo.addItem( self.tr("No Proxy Authentication required"), E5FtpProxyType.NonAuthorizing) self.ftpProxyTypeCombo.addItem( self.tr("User@Server"), E5FtpProxyType.UserAtServer) self.ftpProxyTypeCombo.addItem( self.tr("SITE"), E5FtpProxyType.Site) self.ftpProxyTypeCombo.addItem( self.tr("OPEN"), E5FtpProxyType.Open) self.ftpProxyTypeCombo.addItem( self.tr("User@Proxyuser@Server"), E5FtpProxyType.UserAtProxyuserAtServer) self.ftpProxyTypeCombo.addItem( self.tr("Proxyuser@Server"), E5FtpProxyType.ProxyuserAtServer) self.ftpProxyTypeCombo.addItem( self.tr("AUTH and RESP"), E5FtpProxyType.AuthResp) self.ftpProxyTypeCombo.addItem( self.tr("Bluecoat Proxy"), E5FtpProxyType.Bluecoat) # set initial values self.downloadDirEdit.setText(Preferences.getUI("DownloadPath")) self.requestFilenameCheckBox.setChecked( Preferences.getUI("RequestDownloadFilename")) policy = Preferences.getHelp("DownloadManagerRemovePolicy") from Helpviewer.Download.DownloadManager import DownloadManager if policy == DownloadManager.RemoveNever: self.cleanupNeverButton.setChecked(True) elif policy == DownloadManager.RemoveExit: self.cleanupExitButton.setChecked(True) else: self.cleanupSuccessfulButton.setChecked(True) # HTTP proxy self.httpProxyHostEdit.setText( Preferences.getUI("ProxyHost/Http")) self.httpProxyPortSpin.setValue( Preferences.getUI("ProxyPort/Http")) # HTTPS proxy self.httpsProxyHostEdit.setText( Preferences.getUI("ProxyHost/Https")) self.httpsProxyPortSpin.setValue( Preferences.getUI("ProxyPort/Https")) # FTP proxy self.ftpProxyHostEdit.setText( Preferences.getUI("ProxyHost/Ftp")) self.ftpProxyPortSpin.setValue( Preferences.getUI("ProxyPort/Ftp")) self.ftpProxyTypeCombo.setCurrentIndex( self.ftpProxyTypeCombo.findData( Preferences.getUI("ProxyType/Ftp"))) self.ftpProxyUserEdit.setText( Preferences.getUI("ProxyUser/Ftp")) self.ftpProxyPasswordEdit.setText( Preferences.getUI("ProxyPassword/Ftp")) self.ftpProxyAccountEdit.setText( Preferences.getUI("ProxyAccount/Ftp")) self.httpProxyForAllCheckBox.setChecked( Preferences.getUI("UseHttpProxyForAll")) if Preferences.getUI("UseSystemProxy"): self.systemProxyButton.setChecked(True) else: self.manualProxyButton.setChecked(True) self.proxyGroup.setChecked( Preferences.getUI("UseProxy")) def save(self): """ Public slot to save the Networj configuration. """ Preferences.setUI( "DownloadPath", self.downloadDirEdit.text()) Preferences.setUI( "RequestDownloadFilename", self.requestFilenameCheckBox.isChecked()) from Helpviewer.Download.DownloadManager import DownloadManager if self.cleanupNeverButton.isChecked(): policy = DownloadManager.RemoveNever elif self.cleanupExitButton.isChecked(): policy = DownloadManager.RemoveExit else: policy = DownloadManager.RemoveSuccessFullDownload Preferences.setHelp("DownloadManagerRemovePolicy", policy) Preferences.setUI( "UseProxy", self.proxyGroup.isChecked()) Preferences.setUI( "UseSystemProxy", self.systemProxyButton.isChecked()) Preferences.setUI( "UseHttpProxyForAll", self.httpProxyForAllCheckBox.isChecked()) # HTTP proxy Preferences.setUI( "ProxyHost/Http", self.httpProxyHostEdit.text()) Preferences.setUI( "ProxyPort/Http", self.httpProxyPortSpin.value()) # HTTPS proxy Preferences.setUI( "ProxyHost/Https", self.httpsProxyHostEdit.text()) Preferences.setUI( "ProxyPort/Https", self.httpsProxyPortSpin.value()) # FTP proxy Preferences.setUI( "ProxyHost/Ftp", self.ftpProxyHostEdit.text()) Preferences.setUI( "ProxyPort/Ftp", self.ftpProxyPortSpin.value()) Preferences.setUI( "ProxyType/Ftp", self.ftpProxyTypeCombo.itemData( self.ftpProxyTypeCombo.currentIndex())) Preferences.setUI( "ProxyUser/Ftp", self.ftpProxyUserEdit.text()) Preferences.setUI( "ProxyPassword/Ftp", self.ftpProxyPasswordEdit.text()) Preferences.setUI( "ProxyAccount/Ftp", self.ftpProxyAccountEdit.text()) @pyqtSlot() def on_downloadDirButton_clicked(self): """ Private slot to handle the directory selection via dialog. """ directory = E5FileDialog.getExistingDirectory( self, self.tr("Select download directory"), self.downloadDirEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: dn = Utilities.toNativeSeparators(directory) while dn.endswith(os.sep): dn = dn[:-1] self.downloadDirEdit.setText(dn) @pyqtSlot() def on_clearProxyPasswordsButton_clicked(self): """ Private slot to clear the saved HTTP(S) proxy passwords. """ Preferences.setUI("ProxyPassword/Http", "") Preferences.setUI("ProxyPassword/Https", "") @pyqtSlot(int) def on_ftpProxyTypeCombo_currentIndexChanged(self, index): """ Private slot handling the selection of a proxy type. @param index index of the selected item (integer) """ proxyType = self.ftpProxyTypeCombo.itemData(index) self.ftpProxyHostEdit.setEnabled(proxyType != E5FtpProxyType.NoProxy) self.ftpProxyPortSpin.setEnabled(proxyType != E5FtpProxyType.NoProxy) self.ftpProxyUserEdit.setEnabled( proxyType not in [E5FtpProxyType.NoProxy, E5FtpProxyType.NonAuthorizing]) self.ftpProxyPasswordEdit.setEnabled( proxyType not in [E5FtpProxyType.NoProxy, E5FtpProxyType.NonAuthorizing]) self.ftpProxyAccountEdit.setEnabled( proxyType not in [E5FtpProxyType.NoProxy, E5FtpProxyType.NonAuthorizing]) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = NetworkPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/HelpVirusTotalPage.ui0000644000175000017500000001045512060166053024562 0ustar piotrpiotr HelpVirusTotalPage 0 0 485 409 <b>Configure VirusTotal Interface</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Select to enable the VirusTotal interface Enable VirusTotal Service Key Enter your personal VirusTotal service key (s. <a href="http://virustotal.com">VirusTotal &copy;</a> for details): true true Qt::AlignCenter true Qt::Horizontal 40 20 false Test Service Key Qt::Horizontal 40 20 Select to use secure (https) connections Use secure (https) connections Qt::Vertical 20 74 vtEnabledCheckBox vtServiceKeyEdit testButton vtSecureCheckBox eric-6.0.8/eric/Preferences/ConfigurationPages/EditorExportersPage.py0000644000175000017500000001700012451233373025007 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Editor Exporters configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QFontDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorExportersPage import Ui_EditorExportersPage import Preferences class EditorExportersPage(ConfigurationPageBase, Ui_EditorExportersPage): """ Class implementing the Editor Typing configuration page. """ def __init__(self): """ Constructor """ super(EditorExportersPage, self).__init__() self.setupUi(self) self.setObjectName("EditorExportersPage") # set initial values self.pageIds = {} self.pageIds[' '] = self.stackedWidget.indexOf(self.emptyPage) self.pageIds['HTML'] = self.stackedWidget.indexOf(self.htmlPage) self.pageIds['ODT'] = self.stackedWidget.indexOf(self.odtPage) self.pageIds['PDF'] = self.stackedWidget.indexOf(self.pdfPage) self.pageIds['RTF'] = self.stackedWidget.indexOf(self.rtfPage) self.pageIds['TeX'] = self.stackedWidget.indexOf(self.texPage) exporters = sorted(list(self.pageIds.keys())) for exporter in exporters: self.exportersCombo.addItem(exporter, self.pageIds[exporter]) self.pdfFontCombo.addItem(self.tr("Courier"), "Courier") self.pdfFontCombo.addItem(self.tr("Helvetica"), "Helvetica") self.pdfFontCombo.addItem(self.tr("Times"), "Times") self.pdfPageSizeCombo.addItem(self.tr("A4"), "A4") self.pdfPageSizeCombo.addItem(self.tr("Letter"), "Letter") # HTML self.htmlWysiwygCheckBox.setChecked( Preferences.getEditorExporter("HTML/WYSIWYG")) self.htmlFoldingCheckBox.setChecked( Preferences.getEditorExporter("HTML/Folding")) self.htmlStylesCheckBox.setChecked( Preferences.getEditorExporter("HTML/OnlyStylesUsed")) self.htmlTitleCheckBox.setChecked( Preferences.getEditorExporter("HTML/FullPathAsTitle")) self.htmlTabsCheckBox.setChecked( Preferences.getEditorExporter("HTML/UseTabs")) # ODT self.odtWysiwygCheckBox.setChecked( Preferences.getEditorExporter("ODT/WYSIWYG")) self.odtStylesCheckBox.setChecked( Preferences.getEditorExporter("ODT/OnlyStylesUsed")) self.odtTabsCheckBox.setChecked( Preferences.getEditorExporter("ODT/UseTabs")) # PDF self.pdfMagnificationSlider.setValue( Preferences.getEditorExporter("PDF/Magnification")) ind = self.pdfFontCombo.findData( Preferences.getEditorExporter("PDF/Font")) self.pdfFontCombo.setCurrentIndex(ind) ind = self.pdfPageSizeCombo.findData( Preferences.getEditorExporter("PDF/PageSize")) self.pdfPageSizeCombo.setCurrentIndex(ind) self.pdfMarginTopSpin.setValue( Preferences.getEditorExporter("PDF/MarginTop")) self.pdfMarginBottomSpin.setValue( Preferences.getEditorExporter("PDF/MarginBottom")) self.pdfMarginLeftSpin.setValue( Preferences.getEditorExporter("PDF/MarginLeft")) self.pdfMarginRightSpin.setValue( Preferences.getEditorExporter("PDF/MarginRight")) # RTF self.rtfWysiwygCheckBox.setChecked( Preferences.getEditorExporter("RTF/WYSIWYG")) self.rtfTabsCheckBox.setChecked( Preferences.getEditorExporter("RTF/UseTabs")) self.rtfFont = Preferences.getEditorExporter("RTF/Font") self.rtfFontSample.setFont(self.rtfFont) # TeX self.texStylesCheckBox.setChecked( Preferences.getEditorExporter("TeX/OnlyStylesUsed")) self.texTitleCheckBox.setChecked( Preferences.getEditorExporter("TeX/FullPathAsTitle")) self.on_exportersCombo_activated(' ') def save(self): """ Public slot to save the Editor Typing configuration. """ # HTML Preferences.setEditorExporter( "HTML/WYSIWYG", self.htmlWysiwygCheckBox.isChecked()) Preferences.setEditorExporter( "HTML/Folding", self.htmlFoldingCheckBox.isChecked()) Preferences.setEditorExporter( "HTML/OnlyStylesUsed", self.htmlStylesCheckBox.isChecked()) Preferences.setEditorExporter( "HTML/FullPathAsTitle", self.htmlTitleCheckBox.isChecked()) Preferences.setEditorExporter( "HTML/UseTabs", self.htmlTabsCheckBox.isChecked()) # ODT Preferences.setEditorExporter( "ODT/WYSIWYG", self.odtWysiwygCheckBox.isChecked()) Preferences.setEditorExporter( "ODT/OnlyStylesUsed", self.odtStylesCheckBox.isChecked()) Preferences.setEditorExporter( "ODT/UseTabs", self.odtTabsCheckBox.isChecked()) # PDF Preferences.setEditorExporter( "PDF/Magnification", self.pdfMagnificationSlider.value()) Preferences.setEditorExporter( "PDF/Font", self.pdfFontCombo.itemData(self.pdfFontCombo.currentIndex())) Preferences.setEditorExporter( "PDF/PageSize", self.pdfPageSizeCombo.itemData( self.pdfPageSizeCombo.currentIndex())) Preferences.setEditorExporter( "PDF/MarginTop", self.pdfMarginTopSpin.value()) Preferences.setEditorExporter( "PDF/MarginBottom", self.pdfMarginBottomSpin.value()) Preferences.setEditorExporter( "PDF/MarginLeft", self.pdfMarginLeftSpin.value()) Preferences.setEditorExporter( "PDF/MarginRight", self.pdfMarginRightSpin.value()) # RTF Preferences.setEditorExporter( "RTF/WYSIWYG", self.rtfWysiwygCheckBox.isChecked()) Preferences.setEditorExporter( "RTF/UseTabs", self.rtfTabsCheckBox.isChecked()) Preferences.setEditorExporter("RTF/Font", self.rtfFont) # TeX Preferences.setEditorExporter( "TeX/OnlyStylesUsed", self.texStylesCheckBox.isChecked()) Preferences.setEditorExporter( "TeX/FullPathAsTitle", self.texTitleCheckBox.isChecked()) @pyqtSlot(str) def on_exportersCombo_activated(self, exporter): """ Private slot to select the page related to the selected exporter. @param exporter name of the selected exporter (string) """ try: index = self.pageIds[exporter] except KeyError: index = self.pageIds[' '] self.stackedWidget.setCurrentIndex(index) @pyqtSlot() def on_rtfFontButton_clicked(self): """ Private method used to select the font for the RTF export. """ font, ok = QFontDialog.getFont(self.rtfFont) if ok: self.rtfFontSample.setFont(font) self.rtfFont = font def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EditorExportersPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/DebuggerPythonPage.ui0000644000175000017500000001401612355747621024575 0ustar piotrpiotr DebuggerPythonPage 0 0 455 449 <b>Configure Python Debugger</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Python Interpreter for Debug Client Enter the path of the Python interpreter to be used by the debug client. Press to select the Python interpreter via a file selection dialog Debug Client Type false Enter the path of the Debug Client to be used. Leave empty to use the default. false Press to select the Debug Client via a file selection dialog Select the standard debug client Standard Select the custom selected debug client Custom Select the multi threaded debug client Multi Threaded Source association Enter the file extensions to be associated with the Python2 debugger separated by a space. They must not overlap with the ones for Python3. true Select, to redirect stdin, stdout and stderr of the program being debugged to the eric6 IDE Redirect stdin/stdout/stderr Select to not set the debug client encoding Don't set the encoding of the debug client Qt::Vertical 435 21 interpreterEdit interpreterButton standardButton threadedButton customButton debugClientEdit debugClientButton sourceExtensionsEdit pyRedirectCheckBox pyNoEncodingCheckBox customButton toggled(bool) debugClientEdit setEnabled(bool) 368 194 332 219 eric-6.0.8/eric/Preferences/ConfigurationPages/EmailPage.py0000644000175000017500000001424412451233373022703 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Email configuration page. """ from __future__ import unicode_literals import smtplib import socket from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QApplication from E5Gui import E5MessageBox from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EmailPage import Ui_EmailPage import Preferences class EmailPage(ConfigurationPageBase, Ui_EmailPage): """ Class implementing the Email configuration page. """ def __init__(self): """ Constructor """ super(EmailPage, self).__init__() self.setupUi(self) self.setObjectName("EmailPage") # set initial values self.mailServerEdit.setText(Preferences.getUser("MailServer")) self.portSpin.setValue(Preferences.getUser("MailServerPort")) self.emailEdit.setText(Preferences.getUser("Email")) self.signatureEdit.setPlainText(Preferences.getUser("Signature")) self.mailAuthenticationCheckBox.setChecked( Preferences.getUser("MailServerAuthentication")) self.mailUserEdit.setText(Preferences.getUser("MailServerUser")) self.mailPasswordEdit.setText( Preferences.getUser("MailServerPassword")) self.useTlsCheckBox.setChecked( Preferences.getUser("MailServerUseTLS")) def save(self): """ Public slot to save the Email configuration. """ Preferences.setUser( "MailServer", self.mailServerEdit.text()) Preferences.setUser( "MailServerPort", self.portSpin.value()) Preferences.setUser( "Email", self.emailEdit.text()) Preferences.setUser( "Signature", self.signatureEdit.toPlainText()) Preferences.setUser( "MailServerAuthentication", self.mailAuthenticationCheckBox.isChecked()) Preferences.setUser( "MailServerUser", self.mailUserEdit.text()) Preferences.setUser( "MailServerPassword", self.mailPasswordEdit.text()) Preferences.setUser( "MailServerUseTLS", self.useTlsCheckBox.isChecked()) def __updateTestButton(self): """ Private slot to update the enabled state of the test button. """ self.testButton.setEnabled( self.mailAuthenticationCheckBox.isChecked() and self.mailUserEdit.text() != "" and self.mailPasswordEdit.text() != "" and self.mailServerEdit.text() != "" ) @pyqtSlot(bool) def on_mailAuthenticationCheckBox_toggled(self, checked): """ Private slot to handle a change of the state of the authentication selector. @param checked state of the checkbox (boolean) """ self.__updateTestButton() @pyqtSlot(str) def on_mailUserEdit_textChanged(self, txt): """ Private slot to handle a change of the text of the user edit. @param txt current text of the edit (string) """ self.__updateTestButton() @pyqtSlot(str) def on_mailPasswordEdit_textChanged(self, txt): """ Private slot to handle a change of the text of the user edit. @param txt current text of the edit (string) """ self.__updateTestButton() @pyqtSlot() def on_testButton_clicked(self): """ Private slot to test the mail server login data. """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() try: server = smtplib.SMTP(self.mailServerEdit.text(), self.portSpin.value(), timeout=10) if self.useTlsCheckBox.isChecked(): server.starttls() try: server.login(self.mailUserEdit.text(), self.mailPasswordEdit.text()) QApplication.restoreOverrideCursor() E5MessageBox.information( self, self.tr("Login Test"), self.tr("""The login test succeeded.""")) except (smtplib.SMTPException, socket.error) as e: QApplication.restoreOverrideCursor() if isinstance(e, smtplib.SMTPResponseException): errorStr = e.smtp_error.decode() elif isinstance(e, socket.timeout): errorStr = str(e) elif isinstance(e, socket.error): try: errorStr = e[1] except TypeError: errorStr = str(e) else: errorStr = str(e) E5MessageBox.critical( self, self.tr("Login Test"), self.tr( """

The login test failed.
Reason: {0}

""") .format(errorStr)) server.quit() except (smtplib.SMTPException, socket.error) as e: QApplication.restoreOverrideCursor() if isinstance(e, smtplib.SMTPResponseException): errorStr = e.smtp_error.decode() elif isinstance(e, socket.timeout): errorStr = str(e) elif isinstance(e, socket.error): try: errorStr = e[1] except TypeError: errorStr = str(e) else: errorStr = str(e) E5MessageBox.critical( self, self.tr("Login Test"), self.tr("""

The login test failed.
Reason: {0}

""") .format(errorStr)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = EmailPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/CorbaPage.py0000644000175000017500000000345512451233373022704 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Corba configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_CorbaPage import Ui_CorbaPage import Preferences import Utilities import UI.PixmapCache class CorbaPage(ConfigurationPageBase, Ui_CorbaPage): """ Class implementing the Corba configuration page. """ def __init__(self): """ Constructor """ super(CorbaPage, self).__init__() self.setupUi(self) self.setObjectName("CorbaPage") self.idlButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.idlCompleter = E5FileCompleter(self.idlEdit) # set initial values self.idlEdit.setText(Preferences.getCorba("omniidl")) def save(self): """ Public slot to save the Corba configuration. """ Preferences.setCorba("omniidl", self.idlEdit.text()) @pyqtSlot() def on_idlButton_clicked(self): """ Private slot to handle the IDL compiler selection. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select IDL compiler"), self.idlEdit.text(), "") if file: self.idlEdit.setText(Utilities.toNativeSeparators(file)) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = CorbaPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/InterfacePage.py0000644000175000017500000002371112451233373023553 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Interface configuration page. """ from __future__ import unicode_literals import glob import os from PyQt5.QtCore import pyqtSlot, QTranslator from PyQt5.QtWidgets import QStyleFactory from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_InterfacePage import Ui_InterfacePage import Preferences import Utilities import UI.PixmapCache from eric6config import getConfig class InterfacePage(ConfigurationPageBase, Ui_InterfacePage): """ Class implementing the Interface configuration page. """ def __init__(self): """ Constructor """ super(InterfacePage, self).__init__() self.setupUi(self) self.setObjectName("InterfacePage") self.styleSheetButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.styleSheetCompleter = E5FileCompleter(self.styleSheetEdit) # set initial values self.__populateStyleCombo() self.__populateLanguageCombo() self.uiBrowsersListFoldersFirstCheckBox.setChecked( Preferences.getUI("BrowsersListFoldersFirst")) self.uiBrowsersHideNonPublicCheckBox.setChecked( Preferences.getUI("BrowsersHideNonPublic")) self.uiBrowsersSortByOccurrenceCheckBox.setChecked( Preferences.getUI("BrowsersListContentsByOccurrence")) self.uiBrowsersShowHiddenCheckBox.setChecked( Preferences.getUI("BrowsersListHiddenFiles")) self.fileFiltersEdit.setText( Preferences.getUI("BrowsersFileFilters")) self.lvAutoRaiseCheckBox.setChecked( Preferences.getUI("LogViewerAutoRaise")) self.uiCaptionShowsFilenameGroupBox.setChecked( Preferences.getUI("CaptionShowsFilename")) self.filenameLengthSpinBox.setValue( Preferences.getUI("CaptionFilenameLength")) self.styleSheetEdit.setText(Preferences.getUI("StyleSheet")) if Preferences.getUI("TopLeftByLeft"): self.tlLeftButton.setChecked(True) else: self.tlTopButton.setChecked(True) if Preferences.getUI("BottomLeftByLeft"): self.blLeftButton.setChecked(True) else: self.blBottomButton.setChecked(True) if Preferences.getUI("TopRightByRight"): self.trRightButton.setChecked(True) else: self.trTopButton.setChecked(True) if Preferences.getUI("BottomRightByRight"): self.brRightButton.setChecked(True) else: self.brTopButton.setChecked(True) layout = Preferences.getUILayout() if layout[0] == "Sidebars": index = 0 elif layout[0] == "Toolboxes": index = 1 else: index = 0 # default for bad values self.layoutComboBox.setCurrentIndex(index) if layout[1] == 0: self.separateShellButton.setChecked(True) else: self.debugEmbeddedShellButton.setChecked(True) if layout[2] == 0: self.separateFileBrowserButton.setChecked(True) elif layout[2] == 1: self.debugEmbeddedFileBrowserButton.setChecked(True) else: self.projectEmbeddedFileBrowserButton.setChecked(True) self.tabsGroupBox.setEnabled(True) self.tabsCloseButtonCheckBox.setChecked( Preferences.getUI("SingleCloseButton")) self.initColour( "LogStdErrColour", self.stderrTextColourButton, Preferences.getUI) self.delaySpinBox.setValue(Preferences.getUI("SidebarDelay")) def save(self): """ Public slot to save the Interface configuration. """ # save the style settings styleIndex = self.styleComboBox.currentIndex() style = self.styleComboBox.itemData(styleIndex) Preferences.setUI("Style", style) # save the other UI related settings Preferences.setUI( "BrowsersListFoldersFirst", self.uiBrowsersListFoldersFirstCheckBox.isChecked()) Preferences.setUI( "BrowsersHideNonPublic", self.uiBrowsersHideNonPublicCheckBox.isChecked()) Preferences.setUI( "BrowsersListContentsByOccurrence", self.uiBrowsersSortByOccurrenceCheckBox.isChecked()) Preferences.setUI( "BrowsersListHiddenFiles", self.uiBrowsersShowHiddenCheckBox.isChecked()) Preferences.setUI( "BrowsersFileFilters", self.fileFiltersEdit.text()) Preferences.setUI( "LogViewerAutoRaise", self.lvAutoRaiseCheckBox.isChecked()) Preferences.setUI( "CaptionShowsFilename", self.uiCaptionShowsFilenameGroupBox.isChecked()) Preferences.setUI( "CaptionFilenameLength", self.filenameLengthSpinBox.value()) Preferences.setUI( "StyleSheet", self.styleSheetEdit.text()) # save the dockarea corner settings Preferences.setUI( "TopLeftByLeft", self.tlLeftButton.isChecked()) Preferences.setUI( "BottomLeftByLeft", self.blLeftButton.isChecked()) Preferences.setUI( "TopRightByRight", self.trRightButton.isChecked()) Preferences.setUI( "BottomRightByRight", self.brRightButton.isChecked()) # save the language settings uiLanguageIndex = self.languageComboBox.currentIndex() if uiLanguageIndex: uiLanguage = \ self.languageComboBox.itemData(uiLanguageIndex) else: uiLanguage = None Preferences.setUILanguage(uiLanguage) # save the interface layout settings if self.separateShellButton.isChecked(): layout2 = 0 else: layout2 = 1 if self.separateFileBrowserButton.isChecked(): layout3 = 0 elif self.debugEmbeddedFileBrowserButton.isChecked(): layout3 = 1 else: layout3 = 2 if self.layoutComboBox.currentIndex() == 0: layout1 = "Sidebars" elif self.layoutComboBox.currentIndex() == 1: layout1 = "Toolboxes" else: layout1 = "Sidebars" # just in case layout = (layout1, layout2, layout3) Preferences.setUILayout(layout) Preferences.setUI( "SingleCloseButton", self.tabsCloseButtonCheckBox.isChecked()) Preferences.setUI("SidebarDelay", self.delaySpinBox.value()) self.saveColours(Preferences.setUI) def __populateStyleCombo(self): """ Private method to populate the style combo box. """ curStyle = Preferences.getUI("Style") styles = sorted(list(QStyleFactory.keys())) self.styleComboBox.addItem(self.tr('System'), "System") for style in styles: self.styleComboBox.addItem(style, style) currentIndex = self.styleComboBox.findData(curStyle) if currentIndex == -1: currentIndex = 0 self.styleComboBox.setCurrentIndex(currentIndex) def __populateLanguageCombo(self): """ Private method to initialize the language combobox of the Interface configuration page. """ self.languageComboBox.clear() fnlist = glob.glob("eric6_*.qm") + \ glob.glob(os.path.join( getConfig('ericTranslationsDir'), "eric6_*.qm")) + \ glob.glob(os.path.join(Utilities.getConfigDir(), "eric6_*.qm")) locales = {} for fn in fnlist: locale = os.path.basename(fn)[6:-3] if locale not in locales: translator = QTranslator() translator.load(fn) locales[locale] = translator.translate( "InterfacePage", "English", "Translate this with your language") + \ " ({0})".format(locale) localeList = sorted(list(locales.keys())) try: uiLanguage = Preferences.getUILanguage() if uiLanguage == "None" or uiLanguage is None: currentIndex = 0 elif uiLanguage == "System": currentIndex = 1 else: currentIndex = localeList.index(uiLanguage) + 2 except ValueError: currentIndex = 0 self.languageComboBox.clear() self.languageComboBox.addItem("English (default)", "None") self.languageComboBox.addItem(self.tr('System'), "System") for locale in localeList: self.languageComboBox.addItem(locales[locale], locale) self.languageComboBox.setCurrentIndex(currentIndex) @pyqtSlot() def on_styleSheetButton_clicked(self): """ Private method to select the style sheet file via a dialog. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select style sheet file"), self.styleSheetEdit.text(), self.tr( "Qt Style Sheets (*.qss);;Cascading Style Sheets (*.css);;" "All files (*)")) if file: self.styleSheetEdit.setText(Utilities.toNativeSeparators(file)) @pyqtSlot() def on_resetLayoutButton_clicked(self): """ Private method to reset layout to factory defaults. """ Preferences.resetLayout() def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = InterfacePage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/HelpViewersPage.ui0000644000175000017500000001021412263305671024071 0ustar piotrpiotr HelpViewersPage 0 0 613 634 <b>Configure help viewers</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Help Viewer false Enter the custom viewer to be used false Press to select the custom viewer via a file selection dialog Select to use a custom viewer Custom Select to use Qt Assistant Qt Assistant Select to use the Eric Web Browser Eric Web Browser true Select to use the configured web browser of the system System Web Browser Qt::Vertical 479 121 helpBrowserButton qtAssistantButton webBrowserButton customViewerButton customViewerEdit customViewerSelectionButton customViewerButton toggled(bool) customViewerEdit setEnabled(bool) 592 94 231 109 eric-6.0.8/eric/Preferences/ConfigurationPages/VcsPage.ui0000644000175000017500000002233412060166053022367 0ustar piotrpiotr VcsPage 0 0 619 572 <b>Configure Version Control Systems</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Close VCS dialog automatically, if no error occured Commit Select, if files should be saved before a commit Save files upon commit Select, if project should be saved before a commit Save project upon commit Status Monitor Select the interval in seconds for VCS status updates (0 to disable) sec 3600 Qt::Horizontal 40 20 Select to monitor local status only (if supported by VCS) Monitor local status only Select to enable automatic updates Automatic updates enabled Colours VCS status "added": 100 0 Select the background colour for entries with VCS status "added". VCS status "conflict": 100 0 Select the background colour for entries with VCS status "conflict". Qt::Horizontal 40 20 VCS status "modified": 100 0 Select the background colour for entries with VCS status "modified". VCS status "replaced": 100 0 Select the background colour for entries with VCS status "replaced". VCS status "needs update": 100 0 Select the background colour for entries with VCS status "needs update". VCS status "removed": 100 0 Select the background colour for entries with VCS status "removed". Qt::Vertical 512 81 vcsAutoCloseCheckBox vcsAutoSaveCheckBox vcsAutoSaveProjectCheckBox vcsStatusMonitorIntervalSpinBox vcsMonitorLocalStatusCheckBox autoUpdateCheckBox pbVcsAddedButton pbVcsModifiedButton pbVcsUpdateButton pbVcsConflictButton pbVcsReplacedButton eric-6.0.8/eric/Preferences/ConfigurationPages/ProjectBrowserPage.py0000644000175000017500000001501612451233373024624 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Project Browser configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Application import e5App from .ConfigurationPageBase import ConfigurationPageBase from .Ui_ProjectBrowserPage import Ui_ProjectBrowserPage import Preferences class ProjectBrowserPage(ConfigurationPageBase, Ui_ProjectBrowserPage): """ Class implementing the Project Browser configuration page. """ def __init__(self): """ Constructor """ super(ProjectBrowserPage, self).__init__() self.setupUi(self) self.setObjectName("ProjectBrowserPage") self.__currentProjectTypeIndex = 0 # set initial values self.projectTypeCombo.addItem('', '') self.__projectBrowserFlags = {'': 0} try: projectTypes = e5App().getObject("Project").getProjectTypes() for projectType in sorted(projectTypes.keys()): self.projectTypeCombo.addItem(projectTypes[projectType], projectType) self.__projectBrowserFlags[projectType] = \ Preferences.getProjectBrowserFlags(projectType) except KeyError: self.pbGroup.setEnabled(False) self.initColour( "Highlighted", self.pbHighlightedButton, Preferences.getProjectBrowserColour) self.followEditorCheckBox.setChecked( Preferences.getProject("FollowEditor")) self.followCursorLineCheckBox.setChecked( Preferences.getProject("FollowCursorLine")) self.autoPopulateCheckBox.setChecked( Preferences.getProject("AutoPopulateItems")) self.hideGeneratedCheckBox.setChecked( Preferences.getProject("HideGeneratedForms")) def save(self): """ Public slot to save the Project Browser configuration. """ self.saveColours(Preferences.setProjectBrowserColour) Preferences.setProject( "FollowEditor", self.followEditorCheckBox.isChecked()) Preferences.setProject( "FollowCursorLine", self.followCursorLineCheckBox.isChecked()) Preferences.setProject( "AutoPopulateItems", self.autoPopulateCheckBox.isChecked()) Preferences.setProject( "HideGeneratedForms", self.hideGeneratedCheckBox.isChecked()) if self.pbGroup.isEnabled(): self.__storeProjectBrowserFlags( self.projectTypeCombo.itemData(self.__currentProjectTypeIndex)) for projectType, flags in list(self.__projectBrowserFlags.items()): if projectType != '': Preferences.setProjectBrowserFlags(projectType, flags) def __storeProjectBrowserFlags(self, projectType): """ Private method to store the flags for the selected project type. @param projectType type of the selected project (string) """ from Project.ProjectBrowserFlags import SourcesBrowserFlag, \ FormsBrowserFlag, ResourcesBrowserFlag, TranslationsBrowserFlag, \ InterfacesBrowserFlag, OthersBrowserFlag flags = 0 if self.sourcesBrowserCheckBox.isChecked(): flags |= SourcesBrowserFlag if self.formsBrowserCheckBox.isChecked(): flags |= FormsBrowserFlag if self.resourcesBrowserCheckBox.isChecked(): flags |= ResourcesBrowserFlag if self.translationsBrowserCheckBox.isChecked(): flags |= TranslationsBrowserFlag if self.interfacesBrowserCheckBox.isChecked(): flags |= InterfacesBrowserFlag if self.othersBrowserCheckBox.isChecked(): flags |= OthersBrowserFlag self.__projectBrowserFlags[projectType] = flags def __setProjectBrowsersCheckBoxes(self, projectType): """ Private method to set the checkboxes according to the selected project type. @param projectType type of the selected project (string) """ from Project.ProjectBrowserFlags import SourcesBrowserFlag, \ FormsBrowserFlag, ResourcesBrowserFlag, TranslationsBrowserFlag, \ InterfacesBrowserFlag, OthersBrowserFlag flags = self.__projectBrowserFlags[projectType] self.sourcesBrowserCheckBox.setChecked(flags & SourcesBrowserFlag) self.formsBrowserCheckBox.setChecked(flags & FormsBrowserFlag) self.resourcesBrowserCheckBox.setChecked(flags & ResourcesBrowserFlag) self.translationsBrowserCheckBox.setChecked( flags & TranslationsBrowserFlag) self.interfacesBrowserCheckBox.setChecked( flags & InterfacesBrowserFlag) self.othersBrowserCheckBox.setChecked(flags & OthersBrowserFlag) @pyqtSlot(int) def on_projectTypeCombo_activated(self, index): """ Private slot to set the browser checkboxes according to the selected project type. @param index index of the selected project type (integer) """ if self.__currentProjectTypeIndex == index: return self.__storeProjectBrowserFlags( self.projectTypeCombo.itemData(self.__currentProjectTypeIndex)) self.__setProjectBrowsersCheckBoxes( self.projectTypeCombo.itemData(index)) self.__currentProjectTypeIndex = index @pyqtSlot(bool) def on_followEditorCheckBox_toggled(self, checked): """ Private slot to handle the change of the 'Follow Editor' checkbox. @param checked flag indicating the state of the checkbox """ if not checked: self.followCursorLineCheckBox.setChecked(False) @pyqtSlot(bool) def on_followCursorLineCheckBox_toggled(self, checked): """ Private slot to handle the change of the 'Follow Cursor Line' checkbox. @param checked flag indicating the state of the checkbox """ if checked: self.followEditorCheckBox.setChecked(True) def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = ProjectBrowserPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/QtPage.py0000644000175000017500000000655512451233373022246 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Qt configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .ConfigurationPageBase import ConfigurationPageBase from .Ui_QtPage import Ui_QtPage import Preferences import Utilities import UI.PixmapCache class QtPage(ConfigurationPageBase, Ui_QtPage): """ Class implementing the Qt configuration page. """ def __init__(self): """ Constructor """ super(QtPage, self).__init__() self.setupUi(self) self.setObjectName("QtPage") self.qt4TransButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.qt4TransCompleter = E5DirCompleter(self.qt4TransEdit) # set initial values self.qt4TransEdit.setText(Preferences.getQt("Qt4TranslationsDir")) self.qt4PrefixEdit.setText(Preferences.getQt("QtToolsPrefix4")) self.qt4PostfixEdit.setText(Preferences.getQt("QtToolsPostfix4")) self.__updateQt4Sample() self.pyuicIndentSpinBox.setValue(Preferences.getQt("PyuicIndent")) self.pyuicImportsCheckBox.setChecked( Preferences.getQt("PyuicFromImports")) def save(self): """ Public slot to save the Qt configuration. """ Preferences.setQt("Qt4TranslationsDir", self.qt4TransEdit.text()) Preferences.setQt("QtToolsPrefix4", self.qt4PrefixEdit.text()) Preferences.setQt("QtToolsPostfix4", self.qt4PostfixEdit.text()) Preferences.setQt("PyuicIndent", self.pyuicIndentSpinBox.value()) Preferences.setQt("PyuicFromImports", self.pyuicImportsCheckBox.isChecked()) @pyqtSlot() def on_qt4TransButton_clicked(self): """ Private slot to handle the Qt4 translations directory selection. """ dir = E5FileDialog.getExistingDirectory( self, self.tr("Select Qt4 Translations Directory"), self.qt4TransEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if dir: self.qt4TransEdit.setText(Utilities.toNativeSeparators(dir)) def __updateQt4Sample(self): """ Private slot to update the Qt4 tools sample label. """ self.qt4SampleLabel.setText( "Sample: {0}designer{1}".format(self.qt4PrefixEdit.text(), self.qt4PostfixEdit.text())) @pyqtSlot(str) def on_qt4PrefixEdit_textChanged(self, txt): """ Private slot to handle a change in the entered Qt directory. @param txt the entered string (string) """ self.__updateQt4Sample() @pyqtSlot(str) def on_qt4PostfixEdit_textChanged(self, txt): """ Private slot to handle a change in the entered Qt directory. @param txt the entered string (string) """ self.__updateQt4Sample() def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = QtPage() return page eric-6.0.8/eric/Preferences/ConfigurationPages/HelpWebBrowserPage.py0000644000175000017500000002776612451233373024563 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the Help web browser configuration page. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QLocale from PyQt5.QtNetwork import QNetworkRequest from PyQt5.QtWebKit import QWebSettings from .ConfigurationPageBase import ConfigurationPageBase from .Ui_HelpWebBrowserPage import Ui_HelpWebBrowserPage import Preferences import UI.PixmapCache class HelpWebBrowserPage(ConfigurationPageBase, Ui_HelpWebBrowserPage): """ Class implementing the Help web browser configuration page. """ def __init__(self, configDialog): """ Constructor @param configDialog reference to the configuration dialog (ConfigurationDialog) """ super(HelpWebBrowserPage, self).__init__() self.setupUi(self) self.setObjectName("HelpWebBrowserPage") self.__configDlg = configDialog mw = configDialog.parent().parent() if hasattr(mw, "helpWindow") and mw.helpWindow is not None: self.__helpWindow = mw.helpWindow elif hasattr(mw, "currentBrowser"): self.__helpWindow = mw else: self.__helpWindow = None self.setCurrentPageButton.setEnabled(self.__helpWindow is not None) defaultSchemes = ["file://", "http://", "https://"] self.defaultSchemeCombo.addItems(defaultSchemes) self.clickToFlashCheckBox.setIcon( UI.PixmapCache.getIcon("flashBlock.png")) # set initial values self.singleHelpWindowCheckBox.setChecked( Preferences.getHelp("SingleHelpWindow")) self.saveGeometryCheckBox.setChecked( Preferences.getHelp("SaveGeometry")) self.webSuggestionsCheckBox.setChecked( Preferences.getHelp("WebSearchSuggestions")) self.showTabPreviews.setChecked( Preferences.getHelp("ShowPreview")) self.accessKeysCheckBox.setChecked( Preferences.getHelp("AccessKeysEnabled")) self.javaCheckBox.setChecked( Preferences.getHelp("JavaEnabled")) self.javaScriptCheckBox.setChecked( Preferences.getHelp("JavaScriptEnabled")) self.jsOpenWindowsCheckBox.setChecked( Preferences.getHelp("JavaScriptCanOpenWindows")) self.jsClipboardCheckBox.setChecked( Preferences.getHelp("JavaScriptCanAccessClipboard")) self.pluginsCheckBox.setChecked( Preferences.getHelp("PluginsEnabled")) self.clickToFlashCheckBox.setChecked( Preferences.getHelp("ClickToFlashEnabled")) self.doNotTrackCheckBox.setChecked( Preferences.getHelp("DoNotTrack")) self.sendRefererCheckBox.setChecked( Preferences.getHelp("SendReferer")) self.diskCacheCheckBox.setChecked( Preferences.getHelp("DiskCacheEnabled")) self.cacheSizeSpinBox.setValue( Preferences.getHelp("DiskCacheSize")) cachePolicy = Preferences.getHelp("CachePolicy") if cachePolicy == QNetworkRequest.PreferNetwork: self.cacheKeepButton.setChecked(True) elif cachePolicy == QNetworkRequest.PreferCache: self.cachePreferButton.setChecked(True) elif cachePolicy == QNetworkRequest.AlwaysCache: self.cacheOfflineButton.setChecked(True) self.printBackgroundsCheckBox.setChecked( Preferences.getHelp("PrintBackgrounds")) self.startupCombo.setCurrentIndex( Preferences.getHelp("StartupBehavior")) self.homePageEdit.setText( Preferences.getHelp("HomePage")) self.defaultSchemeCombo.setCurrentIndex( self.defaultSchemeCombo.findText( Preferences.getHelp("DefaultScheme"))) historyLimit = Preferences.getHelp("HistoryLimit") idx = 0 if historyLimit == 1: idx = 0 elif historyLimit == 7: idx = 1 elif historyLimit == 14: idx = 2 elif historyLimit == 30: idx = 3 elif historyLimit == 365: idx = 4 elif historyLimit == -1: idx = 5 elif historyLimit == -2: idx = 6 else: idx = 5 self.expireHistory.setCurrentIndex(idx) for language in range(2, QLocale.LastLanguage + 1): countries = [l.country() for l in QLocale.matchingLocales( language, QLocale.AnyScript, QLocale.AnyCountry)] if len(countries) > 0: self.languageCombo.addItem( QLocale.languageToString(language), language) self.languageCombo.model().sort(0) self.languageCombo.insertSeparator(0) self.languageCombo.insertItem(0, QLocale.languageToString(0), 0) index = self.languageCombo.findData( Preferences.getHelp("SearchLanguage")) if index > -1: self.languageCombo.setCurrentIndex(index) if hasattr(QWebSettings, "SpatialNavigationEnabled"): self.spatialCheckBox.setChecked( Preferences.getHelp("SpatialNavigationEnabled")) else: self.spatialCheckBox.setEnabled(False) if hasattr(QWebSettings, "LinksIncludedInFocusChain"): self.linksInFocusChainCheckBox.setChecked( Preferences.getHelp("LinksIncludedInFocusChain")) else: self.linksInFocusChainCheckBox.setEnabled(False) if hasattr(QWebSettings, "XSSAuditingEnabled"): self.xssAuditingCheckBox.setChecked( Preferences.getHelp("XSSAuditingEnabled")) else: self.xssAuditingCheckBox.setEnabled(False) if hasattr(QWebSettings, "SiteSpecificQuirksEnabled"): self.quirksCheckBox.setChecked( Preferences.getHelp("SiteSpecificQuirksEnabled")) else: self.quirksCheckBox.setEnabled(False) def save(self): """ Public slot to save the Help Viewers configuration. """ Preferences.setHelp( "SingleHelpWindow", self.singleHelpWindowCheckBox.isChecked()) Preferences.setHelp( "SaveGeometry", self.saveGeometryCheckBox.isChecked()) Preferences.setHelp( "WebSearchSuggestions", self.webSuggestionsCheckBox.isChecked()) Preferences.setHelp( "ShowPreview", self.showTabPreviews.isChecked()) Preferences.setHelp( "AccessKeysEnabled", self.accessKeysCheckBox.isChecked()) Preferences.setHelp( "JavaEnabled", self.javaCheckBox.isChecked()) Preferences.setHelp( "JavaScriptEnabled", self.javaScriptCheckBox.isChecked()) Preferences.setHelp( "JavaScriptCanOpenWindows", self.jsOpenWindowsCheckBox.isChecked()) Preferences.setHelp( "JavaScriptCanAccessClipboard", self.jsClipboardCheckBox.isChecked()) Preferences.setHelp( "PluginsEnabled", self.pluginsCheckBox.isChecked()) Preferences.setHelp( "ClickToFlashEnabled", self.clickToFlashCheckBox.isChecked()) Preferences.setHelp( "DoNotTrack", self.doNotTrackCheckBox.isChecked()) Preferences.setHelp( "SendReferer", self.sendRefererCheckBox.isChecked()) Preferences.setHelp( "DiskCacheEnabled", self.diskCacheCheckBox.isChecked()) Preferences.setHelp( "DiskCacheSize", self.cacheSizeSpinBox.value()) if self.cacheKeepButton.isChecked(): Preferences.setHelp( "CachePolicy", QNetworkRequest.PreferNetwork) elif self.cachePreferButton.isChecked(): Preferences.setHelp( "CachePolicy", QNetworkRequest.PreferCache) elif self.cacheOfflineButton.isChecked(): Preferences.setHelp( "CachePolicy", QNetworkRequest.AlwaysCache) Preferences.setHelp( "PrintBackgrounds", self.printBackgroundsCheckBox.isChecked()) Preferences.setHelp( "StartupBehavior", self.startupCombo.currentIndex()) Preferences.setHelp( "HomePage", self.homePageEdit.text()) Preferences.setHelp( "DefaultScheme", self.defaultSchemeCombo.currentText()) idx = self.expireHistory.currentIndex() if idx == 0: historyLimit = 1 elif idx == 1: historyLimit = 7 elif idx == 2: historyLimit = 14 elif idx == 3: historyLimit = 30 elif idx == 4: historyLimit = 365 elif idx == 5: historyLimit = -1 elif idx == 6: historyLimit = -2 Preferences.setHelp("HistoryLimit", historyLimit) languageIndex = self.languageCombo.currentIndex() if languageIndex > -1: language = self.languageCombo.itemData(languageIndex) else: # fall back to system default language = QLocale.system().language() Preferences.setHelp("SearchLanguage", language) if hasattr(QWebSettings, "SpatialNavigationEnabled"): Preferences.setHelp( "SpatialNavigationEnabled", self.spatialCheckBox.isChecked()) if hasattr(QWebSettings, "LinksIncludedInFocusChain"): Preferences.setHelp( "LinksIncludedInFocusChain", self.linksInFocusChainCheckBox.isChecked()) if hasattr(QWebSettings, "XSSAuditingEnabled"): Preferences.setHelp( "XSSAuditingEnabled", self.xssAuditingCheckBox.isChecked()) if hasattr(QWebSettings, "SiteSpecificQuirksEnabled"): Preferences.setHelp( "SiteSpecificQuirksEnabled", self.quirksCheckBox.isChecked()) @pyqtSlot() def on_setCurrentPageButton_clicked(self): """ Private slot to set the current page as the home page. """ url = self.__helpWindow.currentBrowser().url() self.homePageEdit.setText(bytes(url.toEncoded()).decode()) @pyqtSlot() def on_defaultHomeButton_clicked(self): """ Private slot to set the default home page. """ self.homePageEdit.setText(Preferences.Prefs.helpDefaults["HomePage"]) @pyqtSlot(int) def on_startupCombo_currentIndexChanged(self, index): """ Private slot to enable elements depending on the selected startup entry. @param index index of the selected entry (integer) """ enable = index == 0 self.homePageLabel.setEnabled(enable) self.homePageEdit.setEnabled(enable) self.defaultHomeButton.setEnabled(enable) self.setCurrentPageButton.setEnabled(enable) @pyqtSlot() def on_refererWhitelistButton_clicked(self): """ Private slot to edit the referer whitelist. """ from Helpviewer.Network.SendRefererWhitelistDialog import \ SendRefererWhitelistDialog SendRefererWhitelistDialog(self).exec_() @pyqtSlot() def on_noCacheHostsButton_clicked(self): """ Private slot to edit the list of hosts exempted from caching. """ from Helpviewer.Network.NoCacheHostsDialog import \ NoCacheHostsDialog NoCacheHostsDialog(self).exec_() def create(dlg): """ Module function to create the configuration page. @param dlg reference to the configuration dialog @return reference to the instantiated page (ConfigurationPageBase) """ page = HelpWebBrowserPage(dlg) return page eric-6.0.8/eric/Preferences/ConfigurationPages/SecurityPage.ui0000644000175000017500000000716612060166053023451 0ustar piotrpiotr SecurityPage 0 0 400 300 <b>Configure security settings</b> QFrame::HLine QFrame::Sunken Qt::Horizontal Passwords Select to save passwords Save passwords Select to use a master password Use Master Password Qt::Horizontal 40 20 false Press to change the master password Change Master Password... DNS Select to enable DNS prefetch Use DNS prefetching to improve page loading Qt::Vertical 20 113 savePasswordsCheckBox masterPasswordCheckBox masterPasswordButton eric-6.0.8/eric/Preferences/ConfigurationDialog.py0000644000175000017500000010624012554464472021227 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a dialog for the configuration of eric6. """ from __future__ import unicode_literals import os import types from PyQt5.QtCore import QMetaObject, pyqtSignal, Qt, QRect, pyqtSlot from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import QSizePolicy, QSpacerItem, QWidget, QTreeWidget, \ QStackedWidget, QDialog, QSplitter, QScrollArea, QApplication, \ QDialogButtonBox, QFrame, QVBoxLayout, QTreeWidgetItem, QLabel from E5Gui.E5Application import e5App from E5Gui.E5LineEdit import E5ClearableLineEdit from E5Gui import E5MessageBox from E5Gui.E5MainWindow import E5MainWindow from Globals import isMacPlatform import Preferences import UI.PixmapCache from eric6config import getConfig class ConfigurationPageItem(QTreeWidgetItem): """ Class implementing a QTreeWidgetItem holding the configuration page data. """ def __init__(self, parent, text, pageName, iconFile): """ Constructor @param parent parent widget of the item (QTreeWidget or QTreeWidgetItem) @param text text to be displayed (string) @param pageName name of the configuration page (string) @param iconFile file name of the icon to be shown (string) """ super(ConfigurationPageItem, self).__init__(parent, [text]) self.setIcon(0, UI.PixmapCache.getIcon(iconFile)) self.__pageName = pageName def getPageName(self): """ Public method to get the name of the associated configuration page. @return name of the configuration page (string) """ return self.__pageName class ConfigurationWidget(QWidget): """ Class implementing a dialog for the configuration of eric6. @signal preferencesChanged() emitted after settings have been changed @signal masterPasswordChanged(str, str) emitted after the master password has been changed with the old and the new password @signal accepted() emitted to indicate acceptance of the changes @signal rejected() emitted to indicate rejection of the changes """ preferencesChanged = pyqtSignal() masterPasswordChanged = pyqtSignal(str, str) accepted = pyqtSignal() rejected = pyqtSignal() DefaultMode = 0 HelpBrowserMode = 1 TrayStarterMode = 2 def __init__(self, parent=None, fromEric=True, displayMode=DefaultMode): """ Constructor @param parent The parent widget of this dialog. (QWidget) @keyparam fromEric flag indicating a dialog generation from within the eric6 ide (boolean) @keyparam displayMode mode of the configuration dialog (DefaultMode, HelpBrowserMode, TrayStarterMode) @exception RuntimeError raised to indicate an invalid dialog mode """ assert displayMode in ( ConfigurationWidget.DefaultMode, ConfigurationWidget.HelpBrowserMode, ConfigurationWidget.TrayStarterMode ) super(ConfigurationWidget, self).__init__(parent) self.fromEric = fromEric self.displayMode = displayMode self.__setupUi() self.itmDict = {} if not fromEric: from PluginManager.PluginManager import PluginManager try: self.pluginManager = e5App().getObject("PluginManager") except KeyError: self.pluginManager = PluginManager(self) e5App().registerObject("PluginManager", self.pluginManager) if displayMode == ConfigurationWidget.DefaultMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function create to # create the configuration page. This must have the method # save to save the settings. "applicationPage": [self.tr("Application"), "preferences-application.png", "ApplicationPage", None, None], "cooperationPage": [self.tr("Cooperation"), "preferences-cooperation.png", "CooperationPage", None, None], "corbaPage": [self.tr("CORBA"), "preferences-orbit.png", "CorbaPage", None, None], "emailPage": [self.tr("Email"), "preferences-mail_generic.png", "EmailPage", None, None], "graphicsPage": [self.tr("Graphics"), "preferences-graphics.png", "GraphicsPage", None, None], "iconsPage": [self.tr("Icons"), "preferences-icons.png", "IconsPage", None, None], "ircPage": [self.tr("IRC"), "irc.png", "IrcPage", None, None], "networkPage": [self.tr("Network"), "preferences-network.png", "NetworkPage", None, None], "notificationsPage": [self.tr("Notifications"), "preferences-notifications.png", "NotificationsPage", None, None], "pluginManagerPage": [self.tr("Plugin Manager"), "preferences-pluginmanager.png", "PluginManagerPage", None, None], "printerPage": [self.tr("Printer"), "preferences-printer.png", "PrinterPage", None, None], "pythonPage": [self.tr("Python"), "preferences-python.png", "PythonPage", None, None], "qtPage": [self.tr("Qt"), "preferences-qtlogo.png", "QtPage", None, None], "securityPage": [self.tr("Security"), "preferences-security.png", "SecurityPage", None, None], "shellPage": [self.tr("Shell"), "preferences-shell.png", "ShellPage", None, None], "tasksPage": [self.tr("Tasks"), "task.png", "TasksPage", None, None], "templatesPage": [self.tr("Templates"), "preferences-template.png", "TemplatesPage", None, None], "trayStarterPage": [self.tr("Tray Starter"), "erict.png", "TrayStarterPage", None, None], "vcsPage": [self.tr("Version Control Systems"), "preferences-vcs.png", "VcsPage", None, None], "0debuggerPage": [self.tr("Debugger"), "preferences-debugger.png", None, None, None], "debuggerGeneralPage": [self.tr("General"), "preferences-debugger.png", "DebuggerGeneralPage", "0debuggerPage", None], "debuggerPythonPage": [self.tr("Python"), "preferences-pyDebugger.png", "DebuggerPythonPage", "0debuggerPage", None], "debuggerPython3Page": [self.tr("Python3"), "preferences-pyDebugger.png", "DebuggerPython3Page", "0debuggerPage", None], "debuggerRubyPage": [self.tr("Ruby"), "preferences-rbDebugger.png", "DebuggerRubyPage", "0debuggerPage", None], "0editorPage": [self.tr("Editor"), "preferences-editor.png", None, None, None], "editorAPIsPage": [self.tr("APIs"), "preferences-api.png", "EditorAPIsPage", "0editorPage", None], "editorAutocompletionPage": [self.tr("Autocompletion"), "preferences-autocompletion.png", "EditorAutocompletionPage", "0editorPage", None], "editorAutocompletionQScintillaPage": [self.tr("QScintilla"), "qscintilla.png", "EditorAutocompletionQScintillaPage", "editorAutocompletionPage", None], "editorCalltipsPage": [self.tr("Calltips"), "preferences-calltips.png", "EditorCalltipsPage", "0editorPage", None], "editorCalltipsQScintillaPage": [self.tr("QScintilla"), "qscintilla.png", "EditorCalltipsQScintillaPage", "editorCalltipsPage", None], "editorGeneralPage": [self.tr("General"), "preferences-general.png", "EditorGeneralPage", "0editorPage", None], "editorFilePage": [self.tr("Filehandling"), "preferences-filehandling.png", "EditorFilePage", "0editorPage", None], "editorSearchPage": [self.tr("Searching"), "preferences-search.png", "EditorSearchPage", "0editorPage", None], "editorSpellCheckingPage": [self.tr("Spell checking"), "preferences-spellchecking.png", "EditorSpellCheckingPage", "0editorPage", None], "editorStylesPage": [self.tr("Style"), "preferences-styles.png", "EditorStylesPage", "0editorPage", None], "editorSyntaxPage": [self.tr("Code Checkers"), "preferences-debugger.png", "EditorSyntaxPage", "0editorPage", None], "editorTypingPage": [self.tr("Typing"), "preferences-typing.png", "EditorTypingPage", "0editorPage", None], "editorExportersPage": [self.tr("Exporters"), "preferences-exporters.png", "EditorExportersPage", "0editorPage", None], "1editorLexerPage": [self.tr("Highlighters"), "preferences-highlighting-styles.png", None, "0editorPage", None], "editorHighlightersPage": [self.tr("Filetype Associations"), "preferences-highlighter-association.png", "EditorHighlightersPage", "1editorLexerPage", None], "editorHighlightingStylesPage": [self.tr("Styles"), "preferences-highlighting-styles.png", "EditorHighlightingStylesPage", "1editorLexerPage", None], "editorKeywordsPage": [self.tr("Keywords"), "preferences-keywords.png", "EditorKeywordsPage", "1editorLexerPage", None], "editorPropertiesPage": [self.tr("Properties"), "preferences-properties.png", "EditorPropertiesPage", "1editorLexerPage", None], "0helpPage": [self.tr("Help"), "preferences-help.png", None, None, None], "helpAppearancePage": [self.tr("Appearance"), "preferences-styles.png", "HelpAppearancePage", "0helpPage", None], "helpDocumentationPage": [self.tr("Help Documentation"), "preferences-helpdocumentation.png", "HelpDocumentationPage", "0helpPage", None], "helpViewersPage": [self.tr("Help Viewers"), "preferences-helpviewers.png", "HelpViewersPage", "0helpPage", None], ## "helpVirusTotalPage": ## [self.tr("VirusTotal Interface"), "virustotal.png", ## "HelpVirusTotalPage", "0helpPage", None], "helpWebBrowserPage": [self.tr("eric6 Web Browser"), "ericWeb.png", "HelpWebBrowserPage", "0helpPage", None], "0projectPage": [self.tr("Project"), "preferences-project.png", None, None, None], "projectBrowserPage": [self.tr("Project Viewer"), "preferences-project.png", "ProjectBrowserPage", "0projectPage", None], "projectPage": [self.tr("Project"), "preferences-project.png", "ProjectPage", "0projectPage", None], "multiProjectPage": [self.tr("Multiproject"), "preferences-multiproject.png", "MultiProjectPage", "0projectPage", None], "0interfacePage": [self.tr("Interface"), "preferences-interface.png", None, None, None], "interfacePage": [self.tr("Interface"), "preferences-interface.png", "InterfacePage", "0interfacePage", None], "viewmanagerPage": [self.tr("Viewmanager"), "preferences-viewmanager.png", "ViewmanagerPage", "0interfacePage", None], } self.configItems.update( e5App().getObject("PluginManager").getPluginConfigData()) elif displayMode == ConfigurationWidget.HelpBrowserMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function create to # create the configuration page. This must have the method # save to save the settings. "interfacePage": [self.tr("Interface"), "preferences-interface.png", "HelpInterfacePage", None, None], "networkPage": [self.tr("Network"), "preferences-network.png", "NetworkPage", None, None], "printerPage": [self.tr("Printer"), "preferences-printer.png", "PrinterPage", None, None], "securityPage": [self.tr("Security"), "preferences-security.png", "SecurityPage", None, None], "0helpPage": [self.tr("Help"), "preferences-help.png", None, None, None], "helpAppearancePage": [self.tr("Appearance"), "preferences-styles.png", "HelpAppearancePage", "0helpPage", None], "helpDocumentationPage": [self.tr("Help Documentation"), "preferences-helpdocumentation.png", "HelpDocumentationPage", "0helpPage", None], ## "helpVirusTotalPage": ## [self.tr("VirusTotal Interface"), "virustotal.png", ## "HelpVirusTotalPage", "0helpPage", None], "helpWebBrowserPage": [self.tr("eric6 Web Browser"), "ericWeb.png", "HelpWebBrowserPage", "0helpPage", None], } elif displayMode == ConfigurationWidget.TrayStarterMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function create to # create the configuration page. This must have the method # save to save the settings. "trayStarterPage": [self.tr("Tray Starter"), "erict.png", "TrayStarterPage", None, None], } else: raise RuntimeError("Illegal mode value: {0}".format(displayMode)) # generate the list entries for key in sorted(self.configItems.keys()): pageData = self.configItems[key] if pageData[3]: pitm = self.itmDict[pageData[3]] # get the parent item else: pitm = self.configList self.itmDict[key] = ConfigurationPageItem(pitm, pageData[0], key, pageData[1]) self.itmDict[key].setData(0, Qt.UserRole, key) self.itmDict[key].setExpanded(True) self.configList.sortByColumn(0, Qt.AscendingOrder) # set the initial size of the splitter self.configSplitter.setSizes([200, 600]) self.configList.itemActivated.connect(self.__showConfigurationPage) self.configList.itemClicked.connect(self.__showConfigurationPage) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.rejected) if displayMode != ConfigurationWidget.TrayStarterMode: self.__initLexers() def accept(self): """ Public slot to accept the buttonBox accept signal. """ if not isMacPlatform(): wdg = self.focusWidget() if wdg == self.configList: return self.accepted.emit() def __setupUi(self): """ Private method to perform the general setup of the configuration widget. """ self.setObjectName("ConfigurationDialog") self.resize(900, 650) self.verticalLayout_2 = QVBoxLayout(self) self.verticalLayout_2.setSpacing(6) self.verticalLayout_2.setContentsMargins(6, 6, 6, 6) self.verticalLayout_2.setObjectName("verticalLayout_2") self.configSplitter = QSplitter(self) self.configSplitter.setOrientation(Qt.Horizontal) self.configSplitter.setObjectName("configSplitter") self.configListWidget = QWidget(self.configSplitter) self.leftVBoxLayout = QVBoxLayout(self.configListWidget) self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0) self.leftVBoxLayout.setSpacing(0) self.leftVBoxLayout.setObjectName("leftVBoxLayout") self.configListFilter = E5ClearableLineEdit( self, self.tr("Enter filter text...")) self.configListFilter.setObjectName("configListFilter") self.leftVBoxLayout.addWidget(self.configListFilter) self.configList = QTreeWidget() self.configList.setObjectName("configList") self.leftVBoxLayout.addWidget(self.configList) self.configListFilter.textChanged.connect(self.__filterTextChanged) self.scrollArea = QScrollArea(self.configSplitter) self.scrollArea.setFrameShape(QFrame.NoFrame) self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scrollArea.setWidgetResizable(False) self.scrollArea.setObjectName("scrollArea") self.configStack = QStackedWidget() self.configStack.setFrameShape(QFrame.Box) self.configStack.setFrameShadow(QFrame.Sunken) self.configStack.setObjectName("configStack") self.scrollArea.setWidget(self.configStack) self.emptyPage = QWidget() self.emptyPage.setGeometry(QRect(0, 0, 372, 591)) self.emptyPage.setObjectName("emptyPage") self.vboxlayout = QVBoxLayout(self.emptyPage) self.vboxlayout.setSpacing(6) self.vboxlayout.setContentsMargins(6, 6, 6, 6) self.vboxlayout.setObjectName("vboxlayout") spacerItem = QSpacerItem( 20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) self.vboxlayout.addItem(spacerItem) self.emptyPagePixmap = QLabel(self.emptyPage) self.emptyPagePixmap.setAlignment(Qt.AlignCenter) self.emptyPagePixmap.setObjectName("emptyPagePixmap") self.emptyPagePixmap.setPixmap( QPixmap(os.path.join(getConfig('ericPixDir'), 'eric.png'))) self.vboxlayout.addWidget(self.emptyPagePixmap) self.textLabel1 = QLabel(self.emptyPage) self.textLabel1.setAlignment(Qt.AlignCenter) self.textLabel1.setObjectName("textLabel1") self.vboxlayout.addWidget(self.textLabel1) spacerItem1 = QSpacerItem( 20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.vboxlayout.addItem(spacerItem1) self.configStack.addWidget(self.emptyPage) self.verticalLayout_2.addWidget(self.configSplitter) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.Apply | QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Reset) self.buttonBox.setObjectName("buttonBox") if not self.fromEric and \ self.displayMode == ConfigurationWidget.DefaultMode: self.buttonBox.button(QDialogButtonBox.Apply).hide() self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False) self.verticalLayout_2.addWidget(self.buttonBox) self.setWindowTitle(self.tr("Preferences")) self.configList.header().hide() self.configList.header().setSortIndicator(0, Qt.AscendingOrder) self.configList.setSortingEnabled(True) self.textLabel1.setText( self.tr("Please select an entry of the list \n" "to display the configuration page.")) QMetaObject.connectSlotsByName(self) self.setTabOrder(self.configList, self.configStack) self.configStack.setCurrentWidget(self.emptyPage) self.configList.setFocus() def __filterTextChanged(self, filter): """ Private slot to handle a change of the filter. @param filter text of the filter line edit (string) """ self.__filterChildItems(self.configList.invisibleRootItem(), filter) def __filterChildItems(self, parent, filter): """ Private method to filter child items based on a filter string. @param parent reference to the parent item (QTreeWidgetItem) @param filter filter string (string) @return flag indicating a visible child item (boolean) """ childVisible = False filter = filter.lower() for index in range(parent.childCount()): itm = parent.child(index) if itm.childCount() > 0: visible = self.__filterChildItems(itm, filter) or \ filter == "" or filter in itm.text(0).lower() else: visible = filter == "" or filter in itm.text(0).lower() if visible: childVisible = True itm.setHidden(not visible) return childVisible def __initLexers(self): """ Private method to initialize the dictionary of preferences lexers. """ import QScintilla.Lexers from .PreferencesLexer import PreferencesLexer, \ PreferencesLexerLanguageError self.lexers = {} for language in QScintilla.Lexers.getSupportedLanguages(): if language not in self.lexers: try: self.lexers[language] = PreferencesLexer(language, self) except PreferencesLexerLanguageError: pass def __importConfigurationPage(self, name): """ Private method to import a configuration page module. @param name name of the configuration page module (string) @return reference to the configuration page module """ modName = "Preferences.ConfigurationPages.{0}".format(name) try: mod = __import__(modName) components = modName.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod except ImportError: E5MessageBox.critical( self, self.tr("Configuration Page Error"), self.tr("""

The configuration page {0}""" """ could not be loaded.

""").format(name)) return None def __showConfigurationPage(self, itm, column): """ Private slot to show a selected configuration page. @param itm reference to the selected item (QTreeWidgetItem) @param column column that was selected (integer) (ignored) """ pageName = itm.getPageName() self.showConfigurationPageByName(pageName, setCurrent=False) def __initPage(self, pageData): """ Private method to initialize a configuration page. @param pageData data structure for the page to initialize @return reference to the initialized page """ page = None if isinstance(pageData[2], types.FunctionType): page = pageData[2](self) else: mod = self.__importConfigurationPage(pageData[2]) if mod: page = mod.create(self) if page is not None: self.configStack.addWidget(page) pageData[-1] = page try: page.setMode(self.displayMode) except AttributeError: pass return page def showConfigurationPageByName(self, pageName, setCurrent=True): """ Public slot to show a named configuration page. @param pageName name of the configuration page to show (string) @param setCurrent flag indicating to set the current item (boolean) """ if pageName == "empty" or pageName not in self.configItems: page = self.emptyPage else: pageData = self.configItems[pageName] if pageData[-1] is None and pageData[2] is not None: # the page was not loaded yet, create it page = self.__initPage(pageData) else: page = pageData[-1] if page is None: page = self.emptyPage elif setCurrent: items = self.configList.findItems( pageData[0], Qt.MatchFixedString | Qt.MatchRecursive) for item in items: if item.data(0, Qt.UserRole) == pageName: self.configList.setCurrentItem(item) self.configStack.setCurrentWidget(page) ssize = self.scrollArea.size() if self.scrollArea.horizontalScrollBar(): ssize.setHeight( ssize.height() - self.scrollArea.horizontalScrollBar().height() - 2) if self.scrollArea.verticalScrollBar(): ssize.setWidth( ssize.width() - self.scrollArea.verticalScrollBar().width() - 2) psize = page.minimumSizeHint() self.configStack.resize(max(ssize.width(), psize.width()), max(ssize.height(), psize.height())) if page != self.emptyPage: page.polishPage() self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True) else: self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False) # reset scrollbars for sb in [self.scrollArea.horizontalScrollBar(), self.scrollArea.verticalScrollBar()]: if sb: sb.setValue(0) self.__currentConfigurationPageName = pageName def getConfigurationPageName(self): """ Public method to get the page name of the current page. @return page name of the current page (string) """ return self.__currentConfigurationPageName def calledFromEric(self): """ Public method to check, if invoked from within eric. @return flag indicating invocation from within eric (boolean) """ return self.fromEric def getPage(self, pageName): """ Public method to get a reference to the named page. @param pageName name of the configuration page (string) @return reference to the page or None, indicating page was not loaded yet """ return self.configItems[pageName][-1] def getLexers(self): """ Public method to get a reference to the lexers dictionary. @return reference to the lexers dictionary """ return self.lexers def setPreferences(self): """ Public method called to store the selected values into the preferences storage. """ for key, pageData in list(self.configItems.items()): if pageData[-1]: pageData[-1].save() # page was loaded (and possibly modified) QApplication.processEvents() # ensure HMI is responsive def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Apply): self.on_applyButton_clicked() elif button == self.buttonBox.button(QDialogButtonBox.Reset): self.on_resetButton_clicked() @pyqtSlot() def on_applyButton_clicked(self): """ Private slot called to apply the settings of the current page. """ if self.configStack.currentWidget() != self.emptyPage: page = self.configStack.currentWidget() savedState = page.saveState() page.save() self.preferencesChanged.emit() if savedState is not None: page.setState(savedState) @pyqtSlot() def on_resetButton_clicked(self): """ Private slot called to reset the settings of the current page. """ if self.configStack.currentWidget() != self.emptyPage: currentPage = self.configStack.currentWidget() savedState = currentPage.saveState() pageName = self.configList.currentItem().getPageName() self.configStack.removeWidget(currentPage) if pageName == "editorHighlightingStylesPage": self.__initLexers() self.configItems[pageName][-1] = None self.showConfigurationPageByName(pageName) if savedState is not None: self.configStack.currentWidget().setState(savedState) class ConfigurationDialog(QDialog): """ Class for the dialog variant. @signal preferencesChanged() emitted after settings have been changed @signal masterPasswordChanged(str, str) emitted after the master password has been changed with the old and the new password """ preferencesChanged = pyqtSignal() masterPasswordChanged = pyqtSignal(str, str) DefaultMode = ConfigurationWidget.DefaultMode HelpBrowserMode = ConfigurationWidget.HelpBrowserMode TrayStarterMode = ConfigurationWidget.TrayStarterMode def __init__(self, parent=None, name=None, modal=False, fromEric=True, displayMode=ConfigurationWidget.DefaultMode): """ Constructor @param parent The parent widget of this dialog. (QWidget) @param name The name of this dialog. string @param modal Flag indicating a modal dialog. (boolean) @keyparam fromEric flag indicating a dialog generation from within the eric6 ide (boolean) @keyparam displayMode mode of the configuration dialog (DefaultMode, HelpBrowserMode, TrayStarterMode) """ super(ConfigurationDialog, self).__init__(parent) if name: self.setObjectName(name) self.setModal(modal) self.setWindowFlags(Qt.Window) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.cw = ConfigurationWidget(self, fromEric=fromEric, displayMode=displayMode) size = self.cw.size() self.layout.addWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.cw.accepted.connect(self.accept) self.cw.rejected.connect(self.reject) self.cw.preferencesChanged.connect(self.__preferencesChanged) self.cw.masterPasswordChanged.connect(self.__masterPasswordChanged) def __preferencesChanged(self): """ Private slot to handle a change of the preferences. """ self.preferencesChanged.emit() def __masterPasswordChanged(self, oldPassword, newPassword): """ Private slot to handle the change of the master password. @param oldPassword current master password (string) @param newPassword new master password (string) """ self.masterPasswordChanged.emit(oldPassword, newPassword) def showConfigurationPageByName(self, pageName): """ Public slot to show a named configuration page. @param pageName name of the configuration page to show (string) """ self.cw.showConfigurationPageByName(pageName) def getConfigurationPageName(self): """ Public method to get the page name of the current page. @return page name of the current page (string) """ return self.cw.getConfigurationPageName() def setPreferences(self): """ Public method called to store the selected values into the preferences storage. """ self.cw.setPreferences() def accept(self): """ Public method to accept the dialog. """ super(ConfigurationDialog, self).accept() class ConfigurationWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(ConfigurationWindow, self).__init__(parent) self.cw = ConfigurationWidget(self, fromEric=False) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw.accepted.connect(self.accept) self.cw.rejected.connect(self.close) def showConfigurationPageByName(self, pageName): """ Public slot to show a named configuration page. @param pageName name of the configuration page to show (string) """ self.cw.showConfigurationPageByName(pageName) def accept(self): """ Public slot called by the Ok button. """ self.cw.setPreferences() Preferences.saveResetLayout() Preferences.syncPreferences() self.close() eric-6.0.8/eric/Preferences/ViewProfileToolboxesDialog.ui0000644000175000017500000001042312060166053022516 0ustar piotrpiotr ViewProfileToolboxesDialog 0 0 608 177 Configure View Profiles true Select the windows, that should be visible, when the different profiles are active. Qt::AlignVCenter &Edit Profile Left Toolbox true Right Toolbox true Horizontal Toolbox true &Debug Profile Left Toolbox Right Toolbox true Horizontal Toolbox true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource epltCheckBox eprtCheckBox ephtCheckBox dpltCheckBox dprtCheckBox dphtCheckBox buttonBox buttonBox accepted() ViewProfileToolboxesDialog accept() 56 208 56 229 buttonBox rejected() ViewProfileToolboxesDialog reject() 146 215 146 234 eric-6.0.8/eric/Preferences/ShortcutsDialog.ui0000644000175000017500000001056712060166053020373 0ustar piotrpiotr ShortcutsDialog 0 0 800 500 Keyboard Shortcuts &Filter: searchEdit Enter the regular expression that should be contained in the shortcut action Filter on Select to filter based on the actions &Action true Select to filter based on shortcut or alternative shortcut &Shortcut or Alternative Qt::Horizontal 40 20 This list shows all keyboard shortcuts. <b>Keyboard Shortcuts List</b> <p>This list shows all keyboard shortcuts defined in the application. Double click an entry in order to change the respective shortcut. Alternatively, the shortcut might be changed by editing the key sequence in the respective column.</p> true Action Shortcut Alternativ Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
searchEdit actionButton shortcutButton shortcutsList buttonBox buttonBox rejected() ShortcutsDialog reject() 78 490 77 477
eric-6.0.8/eric/Preferences/ViewProfileDialog.py0000644000175000017500000000574212451233373020646 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a dialog to configure the various view profiles. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_ViewProfileToolboxesDialog import Ui_ViewProfileToolboxesDialog from .Ui_ViewProfileSidebarsDialog import Ui_ViewProfileSidebarsDialog class ViewProfileDialog(QDialog): """ Class implementing a dialog to configure the various view profiles. """ def __init__(self, layout, editVisibilities, debugVisibilities, parent=None): """ Constructor @param layout type of the window layout (string) @param editVisibilities list of flags giving the visibilities of the various parts for the 'edit' view profile (list of boolean) @param debugVisibilities list of flags giving the visibilities of the various parts for the 'debug' view profile (list of boolean) @param parent parent widget of this dialog (QWidget) @exception ValueError raised to indicate an invalid layout """ super(ViewProfileDialog, self).__init__(parent) self.__layout = layout if self.__layout == "Toolboxes": self.ui = Ui_ViewProfileToolboxesDialog() elif self.__layout == "Sidebars": self.ui = Ui_ViewProfileSidebarsDialog() else: raise ValueError( "Illegal layout given ({0}).".format(self.__layout)) self.ui.setupUi(self) if self.__layout in ["Toolboxes", "Sidebars"]: # set the edit profile self.ui.epltCheckBox.setChecked(editVisibilities[0]) self.ui.ephtCheckBox.setChecked(editVisibilities[1]) self.ui.eprtCheckBox.setChecked(editVisibilities[2]) # set the debug profile self.ui.dpltCheckBox.setChecked(debugVisibilities[0]) self.ui.dphtCheckBox.setChecked(debugVisibilities[1]) self.ui.dprtCheckBox.setChecked(debugVisibilities[2]) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getVisibilities(self): """ Public method to retrieve the visibilities configuration. @return tuple of two lists giving the visibilities of the various parts ( two lists of boolean) """ if self.__layout in ["Toolboxes", "Sidebars"]: return ( # edit profile [ self.ui.epltCheckBox.isChecked(), self.ui.ephtCheckBox.isChecked(), self.ui.eprtCheckBox.isChecked(), ], # debug profile [ self.ui.dpltCheckBox.isChecked(), self.ui.dphtCheckBox.isChecked(), self.ui.dprtCheckBox.isChecked(), ] ) eric-6.0.8/eric/Preferences/ToolConfigurationDialog.ui0000644000175000017500000002605312263306412022037 0ustar piotrpiotr ToolConfigurationDialog 0 0 591 487 Configure Tools Menu true Add a separator <b>Add separator</b><p>Add a separator for the menu.</p> Add &Separator Add a new tools entry <b>Add</b> <p>Add a new tools entry with the values entered below.</p> &Add Alt+A Select the output redirection mode <b>Redirect output<b><p>Select the output redirection mode. The standard error channel is either not redirected or shown in the log viewer.</p> Enter the arguments for the executable <b>Arguments</b> <p>Enter the arguments for the executable.</p> false Move up <b>Move Up</b> <p>Move the selected entry up.</p> &Up Alt+U false Delete the selected entry <b>Delete</b> <p>Delete the selected entry.</p> &Delete Alt+D Clear all entry fields <b>New</b> <p>Clear all entry fields for entering a new tools entry.</p> &New Alt+N Enter the filename of the executable <b>Executable</b> <p>Enter the filename of the executable.</p> false Move down <b>Move Down</b> <p>Move the selected entry down.</p> Do&wn Alt+W Qt::Vertical QSizePolicy::Expanding 105 22 Enter the menu text <b>Menu text</b> <p>Enter the menu text. Precede the accelerator key with an & character.</p> false Change the values of the selected entry <b>Change</b> <p>Change the values of the selected entry.</p> C&hange Alt+H &Icon file: iconEdit Ar&guments: argumentsEdit &Menu text: menuEdit Qt::Horizontal Enter the filename of the icon <b>Icon</b> <p>Enter the filename of the icon.</p> &Redirect output redirectCombo &Executable file: executableEdit Select the icon via a file selection dialog <b>Icon</b> <p>Select the icon via a file selection dialog.</p> Select the executable via a file selection dialog <b>Executable</b> <p>Select the executable via a file selection dialog.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource toolsList menuEdit iconEdit iconButton executableEdit executableButton argumentsEdit redirectCombo newButton addButton changeButton deleteButton upButton downButton separatorButton buttonBox accepted() ToolConfigurationDialog accept() 62 465 62 486 buttonBox rejected() ToolConfigurationDialog reject() 177 466 178 486 eric-6.0.8/eric/Preferences/ToolConfigurationDialog.py0000644000175000017500000003251212451233373022053 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a configuration dialog for the tools menu. """ from __future__ import unicode_literals import copy from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtWidgets import QDialog from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5MessageBox, E5FileDialog from .Ui_ToolConfigurationDialog import Ui_ToolConfigurationDialog import Utilities import UI.PixmapCache class ToolConfigurationDialog(QDialog, Ui_ToolConfigurationDialog): """ Class implementing a configuration dialog for the tools menu. """ def __init__(self, toollist, parent=None): """ Constructor @param toollist list of configured tools @param parent parent widget (QWidget) """ super(ToolConfigurationDialog, self).__init__(parent) self.setupUi(self) self.iconButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.executableButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.iconCompleter = E5FileCompleter(self.iconEdit) self.executableCompleter = E5FileCompleter(self.executableEdit) self.redirectionModes = [ ("no", self.tr("no redirection")), ("show", self.tr("show output")), ("insert", self.tr("insert into current editor")), ("replaceSelection", self.tr("replace selection of current editor")), ] self.toollist = copy.deepcopy(toollist) for tool in toollist: self.toolsList.addItem(tool['menutext']) for mode in self.redirectionModes: self.redirectCombo.addItem(mode[1]) if len(toollist): self.toolsList.setCurrentRow(0) self.on_toolsList_currentRowChanged(0) t = self.argumentsEdit.whatsThis() if t: t += Utilities.getPercentReplacementHelp() self.argumentsEdit.setWhatsThis(t) def __findModeIndex(self, shortName): """ Private method to find the mode index by its short name. @param shortName short name of the mode (string) @return index of the mode (integer) """ ind = 0 for mode in self.redirectionModes: if mode[0] == shortName: return ind ind += 1 return 1 # default is "show output" @pyqtSlot() def on_newButton_clicked(self): """ Private slot to clear all entry fields. """ self.executableEdit.clear() self.menuEdit.clear() self.iconEdit.clear() self.argumentsEdit.clear() self.redirectCombo.setCurrentIndex(1) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add a new entry. """ menutext = self.menuEdit.text() icon = self.iconEdit.text() executable = self.executableEdit.text() arguments = self.argumentsEdit.text() redirect = self.redirectionModes[self.redirectCombo.currentIndex()][0] if not executable: E5MessageBox.critical( self, self.tr("Add tool entry"), self.tr( "You have to set an executable to add to the" " Tools-Menu first.")) return if not menutext: E5MessageBox.critical( self, self.tr("Add tool entry"), self.tr( "You have to insert a menuentry text to add the" " selected program to the Tools-Menu first.")) return if not Utilities.isinpath(executable): E5MessageBox.critical( self, self.tr("Add tool entry"), self.tr( "The selected file could not be found or" " is not an executable." " Please choose an executable filename.")) return if len(self.toolsList.findItems( menutext, Qt.MatchFlags(Qt.MatchExactly))): E5MessageBox.critical( self, self.tr("Add tool entry"), self.tr("An entry for the menu text {0} already exists.") .format(menutext)) return self.toolsList.addItem(menutext) tool = { 'menutext': menutext, 'icon': icon, 'executable': executable, 'arguments': arguments, 'redirect': redirect, } self.toollist.append(tool) @pyqtSlot() def on_changeButton_clicked(self): """ Private slot to change an entry. """ row = self.toolsList.currentRow() if row < 0: return menutext = self.menuEdit.text() icon = self.iconEdit.text() executable = self.executableEdit.text() arguments = self.argumentsEdit.text() redirect = self.redirectionModes[self.redirectCombo.currentIndex()][0] if not executable: E5MessageBox.critical( self, self.tr("Change tool entry"), self.tr( "You have to set an executable to change the" " Tools-Menu entry.")) return if not menutext: E5MessageBox.critical( self, self.tr("Change tool entry"), self.tr( "You have to insert a menuentry text to change the" " selected Tools-Menu entry.")) return if not Utilities.isinpath(executable): E5MessageBox.critical( self, self.tr("Change tool entry"), self.tr( "The selected file could not be found or" " is not an executable." " Please choose an existing executable filename.")) return self.toollist[row] = { 'menutext': menutext, 'icon': icon, 'executable': executable, 'arguments': arguments, 'redirect': redirect, } self.toolsList.currentItem().setText(menutext) self.changeButton.setEnabled(False) @pyqtSlot() def on_deleteButton_clicked(self): """ Private slot to delete the selected entry. """ row = self.toolsList.currentRow() if row < 0: return del self.toollist[row] itm = self.toolsList.takeItem(row) del itm if row >= len(self.toollist): row -= 1 self.toolsList.setCurrentRow(row) self.on_toolsList_currentRowChanged(row) @pyqtSlot() def on_downButton_clicked(self): """ Private slot to move an entry down in the list. """ curr = self.toolsList.currentRow() self.__swap(curr, curr + 1) self.toolsList.clear() for tool in self.toollist: self.toolsList.addItem(tool['menutext']) self.toolsList.setCurrentRow(curr + 1) if curr + 1 == len(self.toollist): self.downButton.setEnabled(False) self.upButton.setEnabled(True) @pyqtSlot() def on_upButton_clicked(self): """ Private slot to move an entry up in the list. """ curr = self.toolsList.currentRow() self.__swap(curr - 1, curr) self.toolsList.clear() for tool in self.toollist: self.toolsList.addItem(tool['menutext']) self.toolsList.setCurrentRow(curr - 1) if curr - 1 == 0: self.upButton.setEnabled(False) self.downButton.setEnabled(True) @pyqtSlot() def on_separatorButton_clicked(self): """ Private slot to add a menu separator. """ self.toolsList.addItem('--') tool = { 'menutext': '--', 'icon': '', 'executable': '', 'arguments': '', 'redirect': 'no', } self.toollist.append(tool) @pyqtSlot() def on_executableButton_clicked(self): """ Private slot to handle the executable selection via a file selection dialog. """ execfile = E5FileDialog.getOpenFileName( self, self.tr("Select executable"), self.executableEdit.text(), "") if execfile: execfile = Utilities.toNativeSeparators(execfile) if not Utilities.isinpath(execfile): E5MessageBox.critical( self, self.tr("Select executable"), self.tr( "The selected file is not an executable." " Please choose an executable filename.")) return self.executableEdit.setText(execfile) @pyqtSlot() def on_iconButton_clicked(self): """ Private slot to handle the icon selection via a file selection dialog. """ icon = E5FileDialog.getOpenFileName( self, self.tr("Select icon file"), self.iconEdit.text(), self.tr("Icon files (*.png)")) if icon: self.iconEdit.setText(icon) def on_toolsList_currentRowChanged(self, row): """ Private slot to set the lineedits depending on the selected entry. @param row the row of the selected entry (integer) """ if row >= 0 and row < len(self.toollist): if self.toollist[row]['menutext'] == '--': self.executableEdit.clear() self.menuEdit.clear() self.iconEdit.clear() self.argumentsEdit.clear() self.redirectCombo.setCurrentIndex(0) else: tool = self.toollist[row] self.menuEdit.setText(tool['menutext']) self.iconEdit.setText(tool['icon']) self.executableEdit.setText(tool['executable']) self.argumentsEdit.setText(tool['arguments']) self.redirectCombo.setCurrentIndex( self.__findModeIndex(tool['redirect'])) self.changeButton.setEnabled(False) self.deleteButton.setEnabled(True) if row != 0: self.upButton.setEnabled(True) else: self.upButton.setEnabled(False) if row + 1 != len(self.toollist): self.downButton.setEnabled(True) else: self.downButton.setEnabled(False) else: self.executableEdit.clear() self.menuEdit.clear() self.iconEdit.clear() self.argumentsEdit.clear() self.downButton.setEnabled(False) self.upButton.setEnabled(False) self.deleteButton.setEnabled(False) self.changeButton.setEnabled(False) def __toolEntryChanged(self): """ Private slot to perform actions when a tool entry was changed. """ row = self.toolsList.currentRow() if row >= 0 and \ row < len(self.toollist) and \ self.toollist[row]['menutext'] != '--': self.changeButton.setEnabled(True) def on_menuEdit_textChanged(self, text): """ Private slot called, when the menu text was changed. @param text the new text (string) (ignored) """ self.__toolEntryChanged() def on_iconEdit_textChanged(self, text): """ Private slot called, when the icon path was changed. @param text the new text (string) (ignored) """ self.__toolEntryChanged() def on_executableEdit_textChanged(self, text): """ Private slot called, when the executable was changed. @param text the new text (string) (ignored) """ self.__toolEntryChanged() def on_argumentsEdit_textChanged(self, text): """ Private slot called, when the arguments string was changed. @param text the new text (string) (ignored) """ self.__toolEntryChanged() @pyqtSlot(int) def on_redirectCombo_currentIndexChanged(self, index): """ Private slot called, when the redirection mode was changed. @param index the selected mode index (integer) (ignored) """ self.__toolEntryChanged() def getToollist(self): """ Public method to retrieve the tools list. @return a list of tuples containing the menu text, the executable, the executables arguments and a redirection flag """ return self.toollist[:] def __swap(self, itm1, itm2): """ Private method used two swap two list entries given by their index. @param itm1 index of first entry (int) @param itm2 index of second entry (int) """ tmp = self.toollist[itm1] self.toollist[itm1] = self.toollist[itm2] self.toollist[itm2] = tmp eric-6.0.8/eric/Preferences/ShortcutsDialog.py0000644000175000017500000004670212537064320020411 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog for the configuration of eric6's keyboard shortcuts. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, QRegExp, Qt, pyqtSlot from PyQt5.QtGui import QKeySequence from PyQt5.QtWidgets import QHeaderView, QDialog, QTreeWidgetItem from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .Ui_ShortcutsDialog import Ui_ShortcutsDialog import Preferences from Preferences import Shortcuts class ShortcutsDialog(QDialog, Ui_ShortcutsDialog): """ Class implementing a dialog for the configuration of eric6's keyboard shortcuts. @signal updateShortcuts() emitted when the user pressed the dialogs OK button """ updateShortcuts = pyqtSignal() objectNameRole = Qt.UserRole noCheckRole = Qt.UserRole + 1 objectTypeRole = Qt.UserRole + 2 def __init__(self, parent=None, name=None, modal=False): """ Constructor @param parent The parent widget of this dialog. (QWidget) @param name The name of this dialog. (string) @param modal Flag indicating a modal dialog. (boolean) """ super(ShortcutsDialog, self).__init__(parent) if name: self.setObjectName(name) self.setModal(modal) self.setupUi(self) self.setWindowFlags(Qt.Window) self.shortcutsList.headerItem().setText( self.shortcutsList.columnCount(), "") self.shortcutsList.header().setSortIndicator(0, Qt.AscendingOrder) from .ShortcutDialog import ShortcutDialog self.shortcutDialog = ShortcutDialog() self.shortcutDialog.shortcutChanged.connect(self.__shortcutChanged) def __resort(self): """ Private method to resort the tree. """ self.shortcutsList.sortItems( self.shortcutsList.sortColumn(), self.shortcutsList.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.shortcutsList.header().resizeSections( QHeaderView.ResizeToContents) self.shortcutsList.header().setStretchLastSection(True) def __generateCategoryItem(self, title): """ Private method to generate a category item. @param title title for the item (string) @return reference to the category item (QTreeWidgetItem) """ itm = QTreeWidgetItem(self.shortcutsList, [title]) itm.setExpanded(True) return itm def __generateShortcutItem(self, category, action, noCheck=False, objectType=""): """ Private method to generate a keyboard shortcut item. @param category reference to the category item (QTreeWidgetItem) @param action reference to the keyboard action (E5Action) @keyparam noCheck flag indicating that no uniqueness check should be performed (boolean) @keyparam objectType type of the object (string). Objects of the same type are not checked for duplicate shortcuts. """ itm = QTreeWidgetItem( category, [action.iconText(), action.shortcut().toString(), action.alternateShortcut().toString()]) itm.setIcon(0, action.icon()) itm.setData(0, self.objectNameRole, action.objectName()) itm.setData(0, self.noCheckRole, noCheck) if objectType: itm.setData(0, self.objectTypeRole, objectType) else: itm.setData(0, self.objectTypeRole, None) def populate(self): """ Public method to populate the dialog. """ self.searchEdit.clear() self.searchEdit.setFocus() self.shortcutsList.clear() self.actionButton.setChecked(True) # let the plugin manager create on demand plugin objects pm = e5App().getObject("PluginManager") pm.initOnDemandPlugins() # populate the various lists self.projectItem = self.__generateCategoryItem(self.tr("Project")) for act in e5App().getObject("Project").getActions(): self.__generateShortcutItem(self.projectItem, act) self.uiItem = self.__generateCategoryItem(self.tr("General")) for act in e5App().getObject("UserInterface").getActions('ui'): self.__generateShortcutItem(self.uiItem, act) self.wizardsItem = self.__generateCategoryItem(self.tr("Wizards")) for act in e5App().getObject("UserInterface").getActions('wizards'): self.__generateShortcutItem(self.wizardsItem, act) self.debugItem = self.__generateCategoryItem(self.tr("Debug")) for act in e5App().getObject("DebugUI").getActions(): self.__generateShortcutItem(self.debugItem, act) self.editItem = self.__generateCategoryItem(self.tr("Edit")) for act in e5App().getObject("ViewManager").getActions('edit'): self.__generateShortcutItem(self.editItem, act) self.fileItem = self.__generateCategoryItem(self.tr("File")) for act in e5App().getObject("ViewManager").getActions('file'): self.__generateShortcutItem(self.fileItem, act) self.searchItem = self.__generateCategoryItem(self.tr("Search")) for act in e5App().getObject("ViewManager").getActions('search'): self.__generateShortcutItem(self.searchItem, act) self.viewItem = self.__generateCategoryItem(self.tr("View")) for act in e5App().getObject("ViewManager").getActions('view'): self.__generateShortcutItem(self.viewItem, act) self.macroItem = self.__generateCategoryItem(self.tr("Macro")) for act in e5App().getObject("ViewManager").getActions('macro'): self.__generateShortcutItem(self.macroItem, act) self.bookmarkItem = self.__generateCategoryItem( self.tr("Bookmarks")) for act in e5App().getObject("ViewManager").getActions('bookmark'): self.__generateShortcutItem(self.bookmarkItem, act) self.spellingItem = self.__generateCategoryItem( self.tr("Spelling")) for act in e5App().getObject("ViewManager").getActions('spelling'): self.__generateShortcutItem(self.spellingItem, act) actions = e5App().getObject("ViewManager").getActions('window') if actions: self.windowItem = self.__generateCategoryItem( self.tr("Window")) for act in actions: self.__generateShortcutItem(self.windowItem, act) self.pluginCategoryItems = [] for category, ref in e5App().getPluginObjects(): if hasattr(ref, "getActions"): categoryItem = self.__generateCategoryItem(category) objectType = e5App().getPluginObjectType(category) for act in ref.getActions(): self.__generateShortcutItem(categoryItem, act, objectType=objectType) self.pluginCategoryItems.append(categoryItem) self.helpViewerItem = self.__generateCategoryItem( self.tr("eric6 Web Browser")) for act in e5App().getObject("DummyHelpViewer").getActions(): self.__generateShortcutItem(self.helpViewerItem, act, True) self.__resort() self.__resizeColumns() self.__editTopItem = None def on_shortcutsList_itemDoubleClicked(self, itm, column): """ Private slot to handle a double click in the shortcuts list. @param itm the list item that was double clicked (QTreeWidgetItem) @param column the list item was double clicked in (integer) """ if itm.childCount(): return self.__editTopItem = itm.parent() self.shortcutDialog.setKeys( QKeySequence(itm.text(1)), QKeySequence(itm.text(2)), itm.data(0, self.noCheckRole), itm.data(0, self.objectTypeRole)) self.shortcutDialog.show() def on_shortcutsList_itemClicked(self, itm, column): """ Private slot to handle a click in the shortcuts list. @param itm the list item that was clicked (QTreeWidgetItem) @param column the list item was clicked in (integer) """ if itm.childCount() or column not in [1, 2]: return self.shortcutsList.openPersistentEditor(itm, column) def on_shortcutsList_itemChanged(self, itm, column): """ Private slot to handle the edit of a shortcut key. @param itm reference to the item changed (QTreeWidgetItem) @param column column changed (integer) """ if column != 0: keystr = itm.text(column).title() if not itm.data(0, self.noCheckRole) and \ not self.__checkShortcut(QKeySequence(keystr), itm.data(0, self.objectTypeRole), itm.parent()): itm.setText(column, "") else: itm.setText(column, keystr) self.shortcutsList.closePersistentEditor(itm, column) def __shortcutChanged(self, keysequence, altKeysequence, noCheck, objectType): """ Private slot to handle the shortcutChanged signal of the shortcut dialog. @param keysequence the keysequence of the changed action (QKeySequence) @param altKeysequence the alternative keysequence of the changed action (QKeySequence) @param noCheck flag indicating that no uniqueness check should be performed (boolean) @param objectType type of the object (string). """ if not noCheck and \ (not self.__checkShortcut( keysequence, objectType, self.__editTopItem) or not self.__checkShortcut( altKeysequence, objectType, self.__editTopItem)): return self.shortcutsList.currentItem().setText(1, keysequence.toString()) self.shortcutsList.currentItem().setText(2, altKeysequence.toString()) self.__resort() self.__resizeColumns() def __checkShortcut(self, keysequence, objectType, origTopItem): """ Private method to check a keysequence for uniqueness. @param keysequence the keysequence to check (QKeySequence) @param objectType type of the object (string). Entries with the same object type are not checked for uniqueness. @param origTopItem refrence to the parent of the item to be checked (QTreeWidgetItem) @return flag indicating uniqueness (boolean) """ if keysequence.isEmpty(): return True keystr = keysequence.toString() keyname = self.shortcutsList.currentItem().text(0) for topIndex in range(self.shortcutsList.topLevelItemCount()): topItem = self.shortcutsList.topLevelItem(topIndex) for index in range(topItem.childCount()): itm = topItem.child(index) # 1. shall a check be performed? if itm.data(0, self.noCheckRole): continue # 2. check object type itmObjectType = itm.data(0, self.objectTypeRole) if itmObjectType and \ itmObjectType == objectType and \ topItem != origTopItem: continue # 3. check key name if itm.text(0) != keyname: for col in [1, 2]: # check against primary, # then alternative binding itmseq = itm.text(col) # step 1: check if shortcut is already allocated if keystr == itmseq: res = E5MessageBox.yesNo( self, self.tr("Edit shortcuts"), self.tr( """

{0} has already been""" """ allocated to the {1} action. """ """Remove this binding?

""") .format(keystr, itm.text(0)), icon=E5MessageBox.Warning) if res: itm.setText(col, "") return True else: return False if not itmseq: continue # step 2: check if shortcut hides an already allocated if itmseq.startswith("{0}+".format(keystr)): res = E5MessageBox.yesNo( self, self.tr("Edit shortcuts"), self.tr( """

{0} hides the {1}""" """ action. Remove this binding?

""") .format(keystr, itm.text(0)), icon=E5MessageBox.Warning) if res: itm.setText(col, "") return True else: return False # step 3: check if shortcut is hidden by an # already allocated if keystr.startswith("{0}+".format(itmseq)): res = E5MessageBox.yesNo( self, self.tr("Edit shortcuts"), self.tr( """

{0} is hidden by the """ """{1} action. """ """Remove this binding?

""") .format(keystr, itm.text(0)), icon=E5MessageBox.Warning) if res: itm.setText(col, "") return True else: return False return True def __saveCategoryActions(self, category, actions): """ Private method to save the actions for a category. @param category reference to the category item (QTreeWidgetItem) @param actions list of actions for the category (list of E5Action) """ for index in range(category.childCount()): itm = category.child(index) txt = itm.data(0, self.objectNameRole) for act in actions: if txt == act.objectName(): act.setShortcut(QKeySequence(itm.text(1))) act.setAlternateShortcut( QKeySequence(itm.text(2)), removeEmpty=True) break def on_buttonBox_accepted(self): """ Private slot to handle the OK button press. """ self.__saveCategoryActions( self.projectItem, e5App().getObject("Project").getActions()) self.__saveCategoryActions( self.uiItem, e5App().getObject("UserInterface").getActions('ui')) self.__saveCategoryActions( self.wizardsItem, e5App().getObject("UserInterface").getActions('wizards')) self.__saveCategoryActions( self.debugItem, e5App().getObject("DebugUI").getActions()) self.__saveCategoryActions( self.editItem, e5App().getObject("ViewManager").getActions('edit')) self.__saveCategoryActions( self.fileItem, e5App().getObject("ViewManager").getActions('file')) self.__saveCategoryActions( self.searchItem, e5App().getObject("ViewManager").getActions('search')) self.__saveCategoryActions( self.viewItem, e5App().getObject("ViewManager").getActions('view')) self.__saveCategoryActions( self.macroItem, e5App().getObject("ViewManager").getActions('macro')) self.__saveCategoryActions( self.bookmarkItem, e5App().getObject("ViewManager").getActions('bookmark')) self.__saveCategoryActions( self.spellingItem, e5App().getObject("ViewManager").getActions('spelling')) actions = e5App().getObject("ViewManager").getActions('window') if actions: self.__saveCategoryActions(self.windowItem, actions) for categoryItem in self.pluginCategoryItems: category = categoryItem.text(0) ref = e5App().getPluginObject(category) if ref is not None and hasattr(ref, "getActions"): self.__saveCategoryActions(categoryItem, ref.getActions()) self.__saveCategoryActions( self.helpViewerItem, e5App().getObject("DummyHelpViewer").getActions()) Shortcuts.saveShortcuts() Preferences.syncPreferences() self.updateShortcuts.emit() self.hide() @pyqtSlot(str) def on_searchEdit_textChanged(self, txt): """ Private slot called, when the text in the search edit changes. @param txt text of the search edit (string) """ for topIndex in range(self.shortcutsList.topLevelItemCount()): topItem = self.shortcutsList.topLevelItem(topIndex) childHiddenCount = 0 for index in range(topItem.childCount()): itm = topItem.child(index) if (self.actionButton.isChecked() and not QRegExp(txt, Qt.CaseInsensitive).indexIn(itm.text(0)) > -1) or \ (self.shortcutButton.isChecked() and not txt.lower() in itm.text(1).lower() and not txt.lower() in itm.text(2).lower()): itm.setHidden(True) childHiddenCount += 1 else: itm.setHidden(False) topItem.setHidden(childHiddenCount == topItem.childCount()) @pyqtSlot(bool) def on_actionButton_toggled(self, checked): """ Private slot called, when the action radio button is toggled. @param checked state of the action radio button (boolean) """ if checked: self.on_searchEdit_textChanged(self.searchEdit.text()) @pyqtSlot(bool) def on_shortcutButton_toggled(self, checked): """ Private slot called, when the shortcuts radio button is toggled. @param checked state of the shortcuts radio button (boolean) """ if checked: self.on_searchEdit_textChanged(self.searchEdit.text()) eric-6.0.8/eric/Debugger/0000755000175000017500000000000012557365404014204 5ustar piotrpiotreric-6.0.8/eric/Debugger/ExceptionLogger.py0000644000175000017500000001131312451233373017643 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the Exception Logger widget. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QMenu from E5Gui.E5Application import e5App class ExceptionLogger(QTreeWidget): """ Class implementing the Exception Logger widget. This class displays a log of all exceptions having occured during a debugging session. @signal sourceFile(string, int) emitted to open a source file at a line """ sourceFile = pyqtSignal(str, int) def __init__(self, parent=None): """ Constructor @param parent the parent widget of this widget """ super(ExceptionLogger, self).__init__(parent) self.setObjectName("ExceptionLogger") self.setWindowTitle(self.tr("Exceptions")) self.setWordWrap(True) self.setRootIsDecorated(True) self.setHeaderLabels([self.tr("Exception")]) self.setSortingEnabled(False) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.itemDoubleClicked.connect(self.__itemDoubleClicked) self.setWhatsThis(self.tr( """Exceptions Logger""" """

This windows shows a trace of all exceptions, that have""" """ occured during the last debugging session. Initially only""" """ the exception type and exception message are shown. After""" """ the expansion of this entry, the complete call stack as""" """ reported by the client is show with the most recent call""" """ first.

""" )) self.menu = QMenu(self) self.menu.addAction(self.tr("Show source"), self.__openSource) self.menu.addAction(self.tr("Clear"), self.clear) self.menu.addSeparator() self.menu.addAction(self.tr("Configure..."), self.__configure) self.backMenu = QMenu(self) self.backMenu.addAction(self.tr("Clear"), self.clear) self.backMenu.addSeparator() self.backMenu.addAction(self.tr("Configure..."), self.__configure) def __itemDoubleClicked(self, itm): """ Private slot to handle the double click of an item. @param itm the item that was double clicked(QTreeWidgetItem), ignored """ self.__openSource() def __showContextMenu(self, coord): """ Private slot to show the context menu of the listview. @param coord the global coordinates of the mouse pointer (QPoint) """ itm = self.itemAt(coord) coord = self.mapToGlobal(coord) if itm is None: self.backMenu.popup(coord) else: self.menu.popup(coord) def addException(self, exceptionType, exceptionMessage, stackTrace): """ Public slot to handle the arrival of a new exception. @param exceptionType type of exception raised (string) @param exceptionMessage message given by the exception (string) @param stackTrace list of stack entries. """ itm = QTreeWidgetItem(self) if exceptionType is None: itm.setText( 0, self.tr('An unhandled exception occured.' ' See the shell window for details.')) return if exceptionMessage == '': itm.setText(0, "{0}".format(exceptionType)) else: itm.setText(0, "{0}, {1}".format(exceptionType, exceptionMessage)) # now add the call stack, most recent call first for entry in stackTrace: excitm = QTreeWidgetItem(itm) excitm.setText(0, "{0}, {1:d}".format(entry[0], entry[1])) def debuggingStarted(self): """ Public slot to clear the listview upon starting a new debugging session. """ self.clear() def __openSource(self): """ Private slot to handle a double click on an entry. """ itm = self.currentItem() if itm.parent() is None: return entry = itm.text(0) entryList = entry.split(",") try: self.sourceFile.emit(entryList[0], int(entryList[1])) except (IndexError, ValueError): pass def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("debuggerGeneralPage") eric-6.0.8/eric/Debugger/StartRunDialog.ui0000644000175000017500000002410512354033152017432 0ustar piotrpiotr StartRunDialog 0 0 488 271 Start running true Command&line: cmdlineCombo 0 0 Enter the commandline parameters <b>Commandline</b> <p>Enter the commandline parameters in this field.</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false &Working directory: workdirCombo 0 0 Enter the working directory <b>Working directory</b> <p>Enter the working directory of the application to be debugged. Leave it empty to set the working directory to the executable directory.</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false &Environment: environmentCombo 0 0 Enter the environment variables to be set. <b>Environment</b> <p>Enter the environment variables to be set for the program. The individual settings must be separated by whitespace and be given in the form 'var=value'. In order to add to an environment variable, enter it in the form 'var+=value'.</p> <p>Example: var1=1 var2="hello world" var3+=":/tmp"</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false Uncheck to disable exception reporting <b>Report exceptions</b> <p>Uncheck this in order to disable exception reporting.</p> Report &exceptions Alt+E true Select to clear the display of the interpreter window <b>Clear interpreter window</b><p>This clears the display of the interpreter window before starting the debug client.</p> Clear &interpreter window true Select to start the debugger in a console window <b>Start in console</b> <p>Select to start the debugger in a console window. The console command has to be configured on the Debugger-&gt;General page</p> Start in console Forking Select to go through the fork without asking <b>Fork without pausing</b> <p>Select to go through the fork without asking making the forking decision based on the Parent/Child selection.</p> Fork without pausing false Select to debug the child process after forking <b>Debug Child Process</b> <p>Select to debug the child process after forking. If it is not selected, the parent process will be debugged. This has no effect, if forking without pausing is not selected.</p> Follow Child Process Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Select directory using a directory selection dialog <b>Select directory</b> <p>Select the working directory via a directory selection dialog.</p> qPixmapFromMimeSource cmdlineCombo workdirCombo dirButton environmentCombo exceptionCheckBox clearShellCheckBox consoleCheckBox forkModeCheckBox forkChildCheckBox buttonBox buttonBox accepted() StartRunDialog accept() 35 237 34 150 buttonBox rejected() StartRunDialog reject() 154 237 150 148 forkModeCheckBox toggled(bool) forkChildCheckBox setEnabled(bool) 121 190 265 191 eric-6.0.8/eric/Debugger/DebugClientCapabilities.py0000644000175000017500000000064212451233373021247 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module defining the debug clients capabilities. """ HasDebugger = 0x0001 HasInterpreter = 0x0002 HasProfiler = 0x0004 HasCoverage = 0x0008 HasCompleter = 0x0010 HasUnittest = 0x0020 HasShell = 0x0040 HasAll = HasDebugger | HasInterpreter | HasProfiler | \ HasCoverage | HasCompleter | HasUnittest | HasShell eric-6.0.8/eric/Debugger/StartDebugDialog.ui0000644000175000017500000002630612354033113017716 0ustar piotrpiotr StartDebugDialog 0 0 488 300 Start debugging true Command&line: cmdlineCombo 0 0 Enter the commandline parameters <b>Commandline</b> <p>Enter the commandline parameters in this field.</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false &Working directory: workdirCombo 0 0 Enter the working directory <b>Working directory</b> <p>Enter the working directory of the application to be debugged. Leave it empty to set the working directory to the executable directory.</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false &Environment: environmentCombo 0 0 Enter the environment variables to be set. <b>Environment</b> <p>Enter the environment variables to be set for the program. The individual settings must be separated by whitespace and be given in the form 'var=value'. In order to add to an environment variable, enter it in the form 'var+=value'.</p> <p>Example: var1=1 var2="hello world" var3+=":/tmp"</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false Uncheck to disable exception reporting <b>Report exceptions</b> <p>Uncheck this in order to disable exception reporting.</p> Report &exceptions Alt+E true Select to clear the display of the interpreter window <b>Clear interpreter window</b><p>This clears the display of the interpreter window before starting the debug client.</p> Clear &interpreter window true Select to start the debugger in a console window <b>Start in console</b> <p>Select to start the debugger in a console window. The console command has to be configured on the Debugger-&gt;General page</p> Start in console Select to trace into the Python library &Trace into interpreter libraries Alt+T Select to not stop the debugger at the first executable line. <b>Don't stop at first line</b><p>This prevents the debugger from stopping at the first executable line.</p> Don't stop at first line true Forking Select to go through the fork without asking <b>Fork without pausing</b> <p>Select to go through the fork without asking making the forking decision based on the Parent/Child selection.</p> Fork without pausing false Select to debug the child process after forking <b>Debug Child Process</b> <p>Select to debug the child process after forking. If it is not selected, the parent process will be debugged. This has no effect, if forking without pausing is not selected.</p> Follow Child Process Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Select directory using a directory selection dialog <b>Select directory</b> <p>Select the working directory via a directory selection dialog.</p> qPixmapFromMimeSource cmdlineCombo workdirCombo dirButton environmentCombo exceptionCheckBox clearShellCheckBox consoleCheckBox tracePythonCheckBox autoContinueCheckBox forkModeCheckBox forkChildCheckBox buttonBox buttonBox accepted() StartDebugDialog accept() 59 282 43 179 buttonBox rejected() StartDebugDialog reject() 127 282 118 180 forkModeCheckBox toggled(bool) forkChildCheckBox setEnabled(bool) 164 229 276 228 eric-6.0.8/eric/Debugger/DebugServer.py0000644000175000017500000016544512451233373017002 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the debug server. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSignal, QModelIndex from PyQt5.QtNetwork import QTcpServer, QHostAddress, QHostInfo, \ QNetworkInterface from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from .BreakPointModel import BreakPointModel from .WatchPointModel import WatchPointModel from . import DebugClientCapabilities import Preferences import Utilities DebuggerInterfaces = [ "DebuggerInterfacePython", "DebuggerInterfacePython3", "DebuggerInterfaceRuby", "DebuggerInterfaceNone", ] class DebugServer(QTcpServer): """ Class implementing the debug server embedded within the IDE. @signal clientProcessStdout(str) emitted after the client has sent some output via stdout @signal clientProcessStderr(str) emitted after the client has sent some output via stderr @signal clientOutput(str) emitted after the client has sent some output @signal clientRawInputSent() emitted after the data was sent to the debug client @signal clientLine(filename, lineno, forStack) emitted after the debug client has executed a line of code @signal clientStack(stack) emitted after the debug client has executed a line of code @signal clientThreadList(currentId, threadList) emitted after a thread list has been received @signal clientThreadSet() emitted after the client has acknowledged the change of the current thread @signal clientVariables(scope, variables) emitted after a variables dump has been received @signal clientVariable(scope, variables) emitted after a dump for one class variable has been received @signal clientStatement(bool) emitted after an interactive command has been executed. The parameter is 0 to indicate that the command is complete and 1 if it needs more input. @signal clientException(exception) emitted after an exception occured on the client side @signal clientSyntaxError(exception) emitted after a syntax error has been detected on the client side @signal clientExit(int) emitted with the exit status after the client has exited @signal clientClearBreak(filename, lineno) emitted after the debug client has decided to clear a temporary breakpoint @signal clientBreakConditionError(fn, lineno) emitted after the client has signaled a syntax error in a breakpoint condition @signal clientClearWatch(condition) emitted after the debug client has decided to clear a temporary watch expression @signal clientWatchConditionError(condition) emitted after the client has signaled a syntax error in a watch expression @signal clientRawInput(prompt, echo) emitted after a raw input request was received @signal clientBanner(banner) emitted after the client banner was received @signal clientCapabilities(int capabilities, string cltype) emitted after the clients capabilities were received @signal clientCompletionList(completionList, text) emitted after the client the commandline completion list and the reworked searchstring was received from the client @signal passiveDebugStarted(str, bool) emitted after the debug client has connected in passive debug mode @signal clientGone(bool) emitted if the client went away (planned or unplanned) @signal clientInterpreterChanged(str) emitted to signal a change of the client interpreter @signal utPrepared(nrTests, exc_type, exc_value) emitted after the client has loaded a unittest suite @signal utFinished() emitted after the client signalled the end of the unittest @signal utStartTest(testname, testdocu) emitted after the client has started a test @signal utStopTest() emitted after the client has finished a test @signal utTestFailed(testname, exc_info, id) emitted after the client reported a failed test @signal utTestErrored(testname, exc_info, id) emitted after the client reported an errored test @signal utTestSkipped(testname, reason, id) emitted after the client reported a skipped test @signal utTestFailedExpected(testname, exc_info, id) emitted after the client reported an expected test failure @signal utTestSucceededUnexpected(testname, id) emitted after the client reported an unexpected test success @signal callTraceInfo emitted after the client reported the call trace data (isCall, fromFile, fromLine, fromFunction, toFile, toLine, toFunction) @signal appendStdout(msg) emitted when a passive debug connection is established or lost """ clientClearBreak = pyqtSignal(str, int) clientClearWatch = pyqtSignal(str) clientGone = pyqtSignal(bool) clientProcessStdout = pyqtSignal(str) clientProcessStderr = pyqtSignal(str) clientRawInputSent = pyqtSignal() clientOutput = pyqtSignal(str) clientLine = pyqtSignal(str, int, bool) clientStack = pyqtSignal(list) clientThreadList = pyqtSignal(int, list) clientThreadSet = pyqtSignal() clientVariables = pyqtSignal(int, list) clientVariable = pyqtSignal(int, list) clientStatement = pyqtSignal(bool) clientException = pyqtSignal(str, str, list) clientSyntaxError = pyqtSignal(str, str, int, int) clientExit = pyqtSignal(int) clientBreakConditionError = pyqtSignal(str, int) clientWatchConditionError = pyqtSignal(str) clientRawInput = pyqtSignal(str, bool) clientBanner = pyqtSignal(str, str, str) clientCapabilities = pyqtSignal(int, str) clientCompletionList = pyqtSignal(list, str) clientInterpreterChanged = pyqtSignal(str) utPrepared = pyqtSignal(int, str, str) utStartTest = pyqtSignal(str, str) utStopTest = pyqtSignal() utTestFailed = pyqtSignal(str, str, str) utTestErrored = pyqtSignal(str, str, str) utTestSkipped = pyqtSignal(str, str, str) utTestFailedExpected = pyqtSignal(str, str, str) utTestSucceededUnexpected = pyqtSignal(str, str) utFinished = pyqtSignal() passiveDebugStarted = pyqtSignal(str, bool) callTraceInfo = pyqtSignal(bool, str, str, str, str, str, str) appendStdout = pyqtSignal(str) def __init__(self): """ Constructor """ super(DebugServer, self).__init__() # create our models self.breakpointModel = BreakPointModel(self) self.watchpointModel = WatchPointModel(self) self.watchSpecialCreated = \ self.tr("created", "must be same as in EditWatchpointDialog") self.watchSpecialChanged = \ self.tr("changed", "must be same as in EditWatchpointDialog") self.networkInterface = Preferences.getDebugger("NetworkInterface") if self.networkInterface == "all": hostAddress = QHostAddress("0.0.0.0") # QHostAddress.Any) elif self.networkInterface == "allv6": hostAddress = QHostAddress("::") # QHostAddress.AnyIPv6) else: hostAddress = QHostAddress(self.networkInterface) self.networkInterfaceName, self.networkInterfaceIndex = \ self.__getNetworkInterfaceAndIndex(self.networkInterface) if Preferences.getDebugger("PassiveDbgEnabled"): sock = Preferences.getDebugger("PassiveDbgPort") # default: 42424 self.listen(hostAddress, sock) self.passive = True self.passiveClientExited = False else: if hostAddress.toString().lower().startswith("fe80"): hostAddress.setScopeId(self.networkInterfaceName) self.listen(hostAddress) self.passive = False self.debuggerInterface = None self.debugging = False self.running = False self.clientProcess = None self.clientInterpreter = "" self.clientType = \ Preferences.Prefs.settings.value('DebugClient/Type') if self.clientType is None: import sys if sys.version_info[0] == 2: self.clientType = 'Python2' else: self.clientType = 'Python3' # Change clientType if dependent interpreter not exist anymore # (maybe deinstalled,...) elif self.clientType == 'Python2' and Preferences.getDebugger( "PythonInterpreter") == '': self.clientType = 'Python3' elif self.clientType == 'Python3' and Preferences.getDebugger( "Python3Interpreter") == '': self.clientType = 'Python2' self.lastClientType = '' self.__autoClearShell = False self.clientClearBreak.connect(self.__clientClearBreakPoint) self.clientClearWatch.connect(self.__clientClearWatchPoint) self.newConnection.connect(self.__newConnection) self.breakpointModel.rowsAboutToBeRemoved.connect( self.__deleteBreakPoints) self.breakpointModel.dataAboutToBeChanged.connect( self.__breakPointDataAboutToBeChanged) self.breakpointModel.dataChanged.connect(self.__changeBreakPoints) self.breakpointModel.rowsInserted.connect(self.__addBreakPoints) self.watchpointModel.rowsAboutToBeRemoved.connect( self.__deleteWatchPoints) self.watchpointModel.dataAboutToBeChanged.connect( self.__watchPointDataAboutToBeChanged) self.watchpointModel.dataChanged.connect(self.__changeWatchPoints) self.watchpointModel.rowsInserted.connect(self.__addWatchPoints) self.__registerDebuggerInterfaces() def getHostAddress(self, localhost): """ Public method to get the IP address or hostname the debug server is listening. @param localhost flag indicating to return the address for localhost (boolean) @return IP address or hostname (string) """ if self.networkInterface == "all": if localhost: return "127.0.0.1" else: return "{0}@@v4".format(QHostInfo.localHostName()) elif self.networkInterface == "allv6": if localhost: return "::1" else: return "{0}@@v6".format(QHostInfo.localHostName()) else: return "{0}@@i{1}".format(self.networkInterface, self.networkInterfaceIndex) def __getNetworkInterfaceAndIndex(self, address): """ Private method to determine the network interface and the interface index. @param address address to determine the info for (string) @return tuple of network interface name (string) and index (integer) """ if address not in ["all", "allv6"]: for networkInterface in QNetworkInterface.allInterfaces(): addressEntries = networkInterface.addressEntries() if len(addressEntries) > 0: for addressEntry in addressEntries: if addressEntry.ip().toString().lower() == \ address.lower(): return networkInterface.humanReadableName(), \ networkInterface.index() return "", 0 def preferencesChanged(self): """ Public slot to handle the preferencesChanged signal. """ self.__registerDebuggerInterfaces() def __registerDebuggerInterfaces(self): """ Private method to register the available debugger interface modules. """ self.__clientCapabilities = {} self.__clientAssociations = {} for interface in DebuggerInterfaces: modName = "Debugger.{0}".format(interface) mod = __import__(modName) components = modName.split('.') for comp in components[1:]: mod = getattr(mod, comp) clientLanguage, clientCapabilities, clientExtensions = \ mod.getRegistryData() if clientLanguage: self.__clientCapabilities[clientLanguage] = clientCapabilities for extension in clientExtensions: if extension not in self.__clientAssociations: self.__clientAssociations[extension] = clientLanguage def getSupportedLanguages(self, shellOnly=False): """ Public slot to return the supported programming languages. @param shellOnly flag indicating only languages supporting an interactive shell should be returned @return list of supported languages (list of strings) """ languages = list(self.__clientCapabilities.keys()) try: del languages[languages.index("None")] except ValueError: pass # it is not in the list if shellOnly: languages = \ [lang for lang in languages if self.__clientCapabilities[lang] & DebugClientCapabilities.HasShell] return languages[:] def getExtensions(self, language): """ Public slot to get the extensions associated with the given language. @param language language to get extensions for (string) @return tuple of extensions associated with the language (tuple of strings) """ extensions = [] for ext, lang in list(self.__clientAssociations.items()): if lang == language: extensions.append(ext) return tuple(extensions) def __createDebuggerInterface(self, clientType=None): """ Private slot to create the debugger interface object. @param clientType type of the client interface to be created (string) """ if self.lastClientType != self.clientType or clientType is not None: if clientType is None: clientType = self.clientType if clientType == "Python2": from .DebuggerInterfacePython import DebuggerInterfacePython self.debuggerInterface = DebuggerInterfacePython( self, self.passive) elif clientType == "Python3": from .DebuggerInterfacePython3 import DebuggerInterfacePython3 self.debuggerInterface = DebuggerInterfacePython3( self, self.passive) elif clientType == "Ruby": from .DebuggerInterfaceRuby import DebuggerInterfaceRuby self.debuggerInterface = DebuggerInterfaceRuby( self, self.passive) elif clientType == "None": from .DebuggerInterfaceNone import DebuggerInterfaceNone self.debuggerInterface = DebuggerInterfaceNone( self, self.passive) else: from .DebuggerInterfaceNone import DebuggerInterfaceNone self.debuggerInterface = DebuggerInterfaceNone( self, self.passive) self.clientType = "None" def __setClientType(self, clType): """ Private method to set the client type. @param clType type of client to be started (string) """ if clType is not None and clType in self.getSupportedLanguages(): self.clientType = clType Preferences.Prefs.settings.setValue( 'DebugClient/Type', self.clientType) def startClient(self, unplanned=True, clType=None, forProject=False, runInConsole=False): """ Public method to start a debug client. @keyparam unplanned flag indicating that the client has died (boolean) @keyparam clType type of client to be started (string) @keyparam forProject flag indicating a project related action (boolean) @keyparam runInConsole flag indicating to start the debugger in a console window (boolean) """ self.running = False if not self.passive or not self.passiveClientExited: if self.debuggerInterface and self.debuggerInterface.isConnected(): self.shutdownServer() self.clientGone.emit(unplanned and self.debugging) if clType: self.__setClientType(clType) # only start the client, if we are not in passive mode if not self.passive: if self.clientProcess: self.clientProcess.kill() self.clientProcess.waitForFinished(1000) self.clientProcess.deleteLater() self.clientProcess = None self.__createDebuggerInterface() if forProject: project = e5App().getObject("Project") if not project.isDebugPropertiesLoaded(): self.clientProcess, isNetworked, clientInterpreter = \ self.debuggerInterface.startRemote(self.serverPort(), runInConsole) else: self.clientProcess, isNetworked, clientInterpreter = \ self.debuggerInterface.startRemoteForProject( self.serverPort(), runInConsole) else: self.clientProcess, isNetworked, clientInterpreter = \ self.debuggerInterface.startRemote( self.serverPort(), runInConsole) if self.clientProcess: self.clientProcess.readyReadStandardError.connect( self.__clientProcessError) self.clientProcess.readyReadStandardOutput.connect( self.__clientProcessOutput) # Perform actions necessary, if client type has changed if self.lastClientType != self.clientType: self.lastClientType = self.clientType self.remoteBanner() elif self.__autoClearShell: self.__autoClearShell = False self.remoteBanner() self.remoteClientVariables(0, [], 0) self.remoteClientVariables(1, [], 0) else: if clType and self.lastClientType: self.__setClientType(self.lastClientType) else: self.__createDebuggerInterface("None") clientInterpreter = "" if clientInterpreter != self.clientInterpreter: self.clientInterpreter = clientInterpreter self.clientInterpreterChanged.emit(clientInterpreter) def __clientProcessOutput(self): """ Private slot to process client output received via stdout. """ output = str(self.clientProcess.readAllStandardOutput(), Preferences.getSystem("IOEncoding"), 'replace') self.clientProcessStdout.emit(output) def __clientProcessError(self): """ Private slot to process client output received via stderr. """ error = str(self.clientProcess.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.clientProcessStderr.emit(error) def __clientClearBreakPoint(self, fn, lineno): """ Private slot to handle the clientClearBreak signal. @param fn filename of breakpoint to clear (string) @param lineno line number of breakpoint to clear (integer) """ if self.debugging: index = self.breakpointModel.getBreakPointIndex(fn, lineno) self.breakpointModel.deleteBreakPointByIndex(index) def __deleteBreakPoints(self, parentIndex, start, end): """ Private slot to delete breakpoints. @param parentIndex index of parent item (QModelIndex) @param start start row (integer) @param end end row (integer) """ if self.debugging: for row in range(start, end + 1): index = self.breakpointModel.index(row, 0, parentIndex) fn, lineno = \ self.breakpointModel.getBreakPointByIndex(index)[0:2] self.remoteBreakpoint(fn, lineno, False) def __changeBreakPoints(self, startIndex, endIndex): """ Private slot to set changed breakpoints. @param startIndex starting index of the change breakpoins (QModelIndex) @param endIndex ending index of the change breakpoins (QModelIndex) """ if self.debugging: self.__addBreakPoints( QModelIndex(), startIndex.row(), endIndex.row()) def __breakPointDataAboutToBeChanged(self, startIndex, endIndex): """ Private slot to handle the dataAboutToBeChanged signal of the breakpoint model. @param startIndex start index of the rows to be changed (QModelIndex) @param endIndex end index of the rows to be changed (QModelIndex) """ if self.debugging: self.__deleteBreakPoints( QModelIndex(), startIndex.row(), endIndex.row()) def __addBreakPoints(self, parentIndex, start, end): """ Private slot to add breakpoints. @param parentIndex index of parent item (QModelIndex) @param start start row (integer) @param end end row (integer) """ if self.debugging: for row in range(start, end + 1): index = self.breakpointModel.index(row, 0, parentIndex) fn, line, cond, temp, enabled, ignorecount = \ self.breakpointModel.getBreakPointByIndex(index)[:6] self.remoteBreakpoint(fn, line, True, cond, temp) if not enabled: self.__remoteBreakpointEnable(fn, line, False) if ignorecount: self.__remoteBreakpointIgnore(fn, line, ignorecount) def __makeWatchCondition(self, cond, special): """ Private method to construct the condition string. @param cond condition (string) @param special special condition (string) @return condition string (string) """ if special == "": _cond = cond else: if special == self.watchSpecialCreated: _cond = "{0} ??created??".format(cond) elif special == self.watchSpecialChanged: _cond = "{0} ??changed??".format(cond) return _cond def __splitWatchCondition(self, cond): """ Private method to split a remote watch expression. @param cond remote expression (string) @return tuple of local expression (string) and special condition (string) """ if cond.endswith(" ??created??"): cond, special = cond.split() special = self.watchSpecialCreated elif cond.endswith(" ??changed??"): cond, special = cond.split() special = self.watchSpecialChanged else: cond = cond special = "" return cond, special def __clientClearWatchPoint(self, condition): """ Private slot to handle the clientClearWatch signal. @param condition expression of watch expression to clear (string) """ if self.debugging: cond, special = self.__splitWatchCondition(condition) index = self.watchpointModel.getWatchPointIndex(cond, special) self.watchpointModel.deleteWatchPointByIndex(index) def __deleteWatchPoints(self, parentIndex, start, end): """ Private slot to delete watch expressions. @param parentIndex index of parent item (QModelIndex) @param start start row (integer) @param end end row (integer) """ if self.debugging: for row in range(start, end + 1): index = self.watchpointModel.index(row, 0, parentIndex) cond, special = \ self.watchpointModel.getWatchPointByIndex(index)[0:2] cond = self.__makeWatchCondition(cond, special) self.__remoteWatchpoint(cond, False) def __watchPointDataAboutToBeChanged(self, startIndex, endIndex): """ Private slot to handle the dataAboutToBeChanged signal of the watch expression model. @param startIndex start index of the rows to be changed (QModelIndex) @param endIndex end index of the rows to be changed (QModelIndex) """ if self.debugging: self.__deleteWatchPoints( QModelIndex(), startIndex.row(), endIndex.row()) def __addWatchPoints(self, parentIndex, start, end): """ Private slot to set a watch expression. @param parentIndex index of parent item (QModelIndex) @param start start row (integer) @param end end row (integer) """ if self.debugging: for row in range(start, end + 1): index = self.watchpointModel.index(row, 0, parentIndex) cond, special, temp, enabled, ignorecount = \ self.watchpointModel.getWatchPointByIndex(index)[:5] cond = self.__makeWatchCondition(cond, special) self.__remoteWatchpoint(cond, True, temp) if not enabled: self.__remoteWatchpointEnable(cond, False) if ignorecount: self.__remoteWatchpointIgnore(cond, ignorecount) def __changeWatchPoints(self, startIndex, endIndex): """ Private slot to set changed watch expressions. @param startIndex start index of the rows to be changed (QModelIndex) @param endIndex end index of the rows to be changed (QModelIndex) """ if self.debugging: self.__addWatchPoints( QModelIndex(), startIndex.row(), endIndex.row()) def getClientCapabilities(self, type): """ Public method to retrieve the debug clients capabilities. @param type debug client type (string) @return debug client capabilities (integer) """ try: return self.__clientCapabilities[type] except KeyError: return 0 # no capabilities def getClientInterpreter(self): """ Public method to get the interpreter of the debug client. @return interpreter of the debug client (string) """ return self.clientInterpreter def __newConnection(self): """ Private slot to handle a new connection. """ sock = self.nextPendingConnection() peerAddress = sock.peerAddress().toString() if peerAddress not in Preferences.getDebugger("AllowedHosts"): # the peer is not allowed to connect res = E5MessageBox.yesNo( None, self.tr("Connection from illegal host"), self.tr( """

A connection was attempted by the illegal host""" """ {0}. Accept this connection?

""") .format(peerAddress), icon=E5MessageBox.Warning) if not res: sock.abort() return else: allowedHosts = Preferences.getDebugger("AllowedHosts") allowedHosts.append(peerAddress) Preferences.setDebugger("AllowedHosts", allowedHosts) if self.passive: self.__createDebuggerInterface( Preferences.getDebugger("PassiveDbgType")) accepted = self.debuggerInterface.newConnection(sock) if accepted: # Perform actions necessary, if client type has changed if self.lastClientType != self.clientType: self.lastClientType = self.clientType self.remoteBanner() elif self.__autoClearShell: self.__autoClearShell = False self.remoteBanner() elif self.passive: self.remoteBanner() self.debuggerInterface.flush() def shutdownServer(self): """ Public method to cleanly shut down. It closes our socket and shuts down the debug client. (Needed on Win OS) """ if self.debuggerInterface is not None: self.debuggerInterface.shutdown() def remoteEnvironment(self, env): """ Public method to set the environment for a program to debug, run, ... @param env environment settings (string) """ envlist = Utilities.parseEnvironmentString(env) envdict = {} for el in envlist: try: key, value = el.split('=', 1) if value.startswith('"') or value.startswith("'"): value = value[1:-1] envdict[key] = value except ValueError: pass self.debuggerInterface.remoteEnvironment(envdict) def remoteLoad(self, fn, argv, wd, env, autoClearShell=True, tracePython=False, autoContinue=True, forProject=False, runInConsole=False, autoFork=False, forkChild=False, clientType="", enableCallTrace=False): """ Public method to load a new program to debug. @param fn the filename to debug (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @param env environment settings (string) @keyparam autoClearShell flag indicating, that the interpreter window should be cleared (boolean) @keyparam tracePython flag indicating if the Python library should be traced as well (boolean) @keyparam autoContinue flag indicating, that the debugger should not stop at the first executable line (boolean) @keyparam forProject flag indicating a project related action (boolean) @keyparam runInConsole flag indicating to start the debugger in a console window (boolean) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) @keyparam clientType client type to be used (string) @keyparam enableCallTrace flag indicating to enable the call trace function (boolean) """ self.__autoClearShell = autoClearShell self.__autoContinue = autoContinue # Restart the client try: if clientType: self.__setClientType(clientType) else: self.__setClientType( self.__clientAssociations[os.path.splitext(fn)[1]]) except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False, forProject=forProject, runInConsole=runInConsole) self.setCallTraceEnabled(enableCallTrace) self.remoteEnvironment(env) self.debuggerInterface.remoteLoad(fn, argv, wd, tracePython, autoContinue, autoFork, forkChild) self.debugging = True self.running = True self.__restoreBreakpoints() self.__restoreWatchpoints() def remoteRun(self, fn, argv, wd, env, autoClearShell=True, forProject=False, runInConsole=False, autoFork=False, forkChild=False, clientType=""): """ Public method to load a new program to run. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @param env environment settings (string) @keyparam autoClearShell flag indicating, that the interpreter window should be cleared (boolean) @keyparam forProject flag indicating a project related action (boolean) @keyparam runInConsole flag indicating to start the debugger in a console window (boolean) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) @keyparam clientType client type to be used (string) """ self.__autoClearShell = autoClearShell # Restart the client try: if clientType: self.__setClientType(clientType) else: self.__setClientType( self.__clientAssociations[os.path.splitext(fn)[1]]) except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False, forProject=forProject, runInConsole=runInConsole) self.remoteEnvironment(env) self.debuggerInterface.remoteRun(fn, argv, wd, autoFork, forkChild) self.debugging = False self.running = True def remoteCoverage(self, fn, argv, wd, env, autoClearShell=True, erase=False, forProject=False, runInConsole=False, clientType=""): """ Public method to load a new program to collect coverage data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @param env environment settings (string) @keyparam autoClearShell flag indicating, that the interpreter window should be cleared (boolean) @keyparam erase flag indicating that coverage info should be cleared first (boolean) @keyparam forProject flag indicating a project related action (boolean) @keyparam runInConsole flag indicating to start the debugger in a console window (boolean) @keyparam clientType client type to be used (string) """ self.__autoClearShell = autoClearShell # Restart the client try: if clientType: self.__setClientType(clientType) else: self.__setClientType( self.__clientAssociations[os.path.splitext(fn)[1]]) except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False, forProject=forProject, runInConsole=runInConsole) self.remoteEnvironment(env) self.debuggerInterface.remoteCoverage(fn, argv, wd, erase) self.debugging = False self.running = True def remoteProfile(self, fn, argv, wd, env, autoClearShell=True, erase=False, forProject=False, runInConsole=False, clientType=""): """ Public method to load a new program to collect profiling data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @param env environment settings (string) @keyparam autoClearShell flag indicating, that the interpreter window should be cleared (boolean) @keyparam erase flag indicating that timing info should be cleared first (boolean) @keyparam forProject flag indicating a project related action (boolean) @keyparam runInConsole flag indicating to start the debugger in a console window (boolean) @keyparam clientType client type to be used (string) """ self.__autoClearShell = autoClearShell # Restart the client try: if clientType: self.__setClientType(clientType) else: self.__setClientType( self.__clientAssociations[os.path.splitext(fn)[1]]) except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False, forProject=forProject, runInConsole=runInConsole) self.remoteEnvironment(env) self.debuggerInterface.remoteProfile(fn, argv, wd, erase) self.debugging = False self.running = True def remoteStatement(self, stmt): """ Public method to execute a Python statement. @param stmt the Python statement to execute (string). It should not have a trailing newline. """ self.debuggerInterface.remoteStatement(stmt) def remoteStep(self): """ Public method to single step the debugged program. """ self.debuggerInterface.remoteStep() def remoteStepOver(self): """ Public method to step over the debugged program. """ self.debuggerInterface.remoteStepOver() def remoteStepOut(self): """ Public method to step out the debugged program. """ self.debuggerInterface.remoteStepOut() def remoteStepQuit(self): """ Public method to stop the debugged program. """ self.debuggerInterface.remoteStepQuit() def remoteContinue(self, special=False): """ Public method to continue the debugged program. @param special flag indicating a special continue operation """ self.debuggerInterface.remoteContinue(special) def remoteBreakpoint(self, fn, line, set, cond=None, temp=False): """ Public method to set or clear a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param set flag indicating setting or resetting a breakpoint (boolean) @param cond condition of the breakpoint (string) @param temp flag indicating a temporary breakpoint (boolean) """ self.debuggerInterface.remoteBreakpoint(fn, line, set, cond, temp) def __remoteBreakpointEnable(self, fn, line, enable): """ Private method to enable or disable a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param enable flag indicating enabling or disabling a breakpoint (boolean) """ self.debuggerInterface.remoteBreakpointEnable(fn, line, enable) def __remoteBreakpointIgnore(self, fn, line, count): """ Private method to ignore a breakpoint the next couple of occurrences. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param count number of occurrences to ignore (int) """ self.debuggerInterface.remoteBreakpointIgnore(fn, line, count) def __remoteWatchpoint(self, cond, set, temp=False): """ Private method to set or clear a watch expression. @param cond expression of the watch expression (string) @param set flag indicating setting or resetting a watch expression (boolean) @param temp flag indicating a temporary watch expression (boolean) """ # cond is combination of cond and special (s. watch expression viewer) self.debuggerInterface.remoteWatchpoint(cond, set, temp) def __remoteWatchpointEnable(self, cond, enable): """ Private method to enable or disable a watch expression. @param cond expression of the watch expression (string) @param enable flag indicating enabling or disabling a watch expression (boolean) """ # cond is combination of cond and special (s. watch expression viewer) self.debuggerInterface.remoteWatchpointEnable(cond, enable) def __remoteWatchpointIgnore(self, cond, count): """ Private method to ignore a watch expression the next couple of occurrences. @param cond expression of the watch expression (string) @param count number of occurrences to ignore (int) """ # cond is combination of cond and special (s. watch expression viewer) self.debuggerInterface.remoteWatchpointIgnore(cond, count) def remoteRawInput(self, s): """ Public method to send the raw input to the debugged program. @param s the raw input (string) """ self.debuggerInterface.remoteRawInput(s) self.clientRawInputSent.emit() def remoteThreadList(self): """ Public method to request the list of threads from the client. """ self.debuggerInterface.remoteThreadList() def remoteSetThread(self, tid): """ Public method to request to set the given thread as current thread. @param tid id of the thread (integer) """ self.debuggerInterface.remoteSetThread(tid) def remoteClientVariables(self, scope, filter, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param framenr framenumber of the variables to retrieve (int) """ self.debuggerInterface.remoteClientVariables(scope, filter, framenr) def remoteClientVariable(self, scope, filter, var, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param var list encoded name of variable to retrieve (string) @param framenr framenumber of the variables to retrieve (int) """ self.debuggerInterface.remoteClientVariable( scope, filter, var, framenr) def remoteClientSetFilter(self, scope, filter): """ Public method to set a variables filter list. @param scope the scope of the variables (0 = local, 1 = global) @param filter regexp string for variable names to filter out (string) """ self.debuggerInterface.remoteClientSetFilter(scope, filter) def setCallTraceEnabled(self, on): """ Public method to set the call trace state. @param on flag indicating to enable the call trace function (boolean) """ self.debuggerInterface.setCallTraceEnabled(on) def remoteEval(self, arg): """ Public method to evaluate arg in the current context of the debugged program. @param arg the arguments to evaluate (string) """ self.debuggerInterface.remoteEval(arg) def remoteExec(self, stmt): """ Public method to execute stmt in the current context of the debugged program. @param stmt statement to execute (string) """ self.debuggerInterface.remoteExec(stmt) def remoteBanner(self): """ Public slot to get the banner info of the remote client. """ self.debuggerInterface.remoteBanner() def remoteCapabilities(self): """ Public slot to get the debug clients capabilities. """ self.debuggerInterface.remoteCapabilities() def remoteCompletion(self, text): """ Public slot to get the a list of possible commandline completions from the remote client. @param text the text to be completed (string) """ self.debuggerInterface.remoteCompletion(text) def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase, clientType=""): """ Public method to prepare a new unittest run. @param fn the filename to load (string) @param tn the testname to load (string) @param tfn the test function name to load tests from (string) @param failed list of failed test, if only failed test should be run (list of strings) @param cov flag indicating collection of coverage data is requested (boolean) @param covname filename to be used to assemble the coverage caches filename (string) @param coverase flag indicating erasure of coverage data is requested (boolean) @keyparam clientType client type to be used (string) """ # Restart the client if there is already a program loaded. try: if clientType: self.__setClientType(clientType) else: self.__setClientType( self.__clientAssociations[os.path.splitext(fn)[1]]) except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False) self.debuggerInterface.remoteUTPrepare( fn, tn, tfn, failed, cov, covname, coverase) self.debugging = False self.running = True def remoteUTRun(self): """ Public method to start a unittest run. """ self.debuggerInterface.remoteUTRun() def remoteUTStop(self): """ public method to stop a unittest run. """ self.debuggerInterface.remoteUTStop() def signalClientOutput(self, line): """ Public method to process a line of client output. @param line client output (string) """ self.clientOutput.emit(line) def signalClientLine(self, filename, lineno, forStack=False): """ Public method to process client position feedback. @param filename name of the file currently being executed (string) @param lineno line of code currently being executed (integer) @param forStack flag indicating this is for a stack dump (boolean) """ self.clientLine.emit(filename, lineno, forStack) def signalClientStack(self, stack): """ Public method to process a client's stack information. @param stack list of stack entries. Each entry is a tuple of three values giving the filename, linenumber and method (list of lists of (string, integer, string)) """ self.clientStack.emit(stack) def signalClientThreadList(self, currentId, threadList): """ Public method to process the client thread list info. @param currentId id of the current thread (integer) @param threadList list of dictionaries containing the thread data """ self.clientThreadList.emit(currentId, threadList) def signalClientThreadSet(self): """ Public method to handle the change of the client thread. """ self.clientThreadSet.emit() def signalClientVariables(self, scope, variables): """ Public method to process the client variables info. @param scope scope of the variables (-1 = empty global, 1 = global, 0 = local) @param variables the list of variables from the client """ self.clientVariables.emit(scope, variables) def signalClientVariable(self, scope, variables): """ Public method to process the client variable info. @param scope scope of the variables (-1 = empty global, 1 = global, 0 = local) @param variables the list of members of a classvariable from the client """ self.clientVariable.emit(scope, variables) def signalClientStatement(self, more): """ Public method to process the input response from the client. @param more flag indicating that more user input is required """ self.clientStatement.emit(more) def signalClientException(self, exceptionType, exceptionMessage, stackTrace): """ Public method to process the exception info from the client. @param exceptionType type of exception raised (string) @param exceptionMessage message given by the exception (string) @param stackTrace list of stack entries with the exception position first. Each stack entry is a list giving the filename and the linenumber. """ if self.running: self.clientException.emit(exceptionType, exceptionMessage, stackTrace) def signalClientSyntaxError(self, message, filename, lineNo, characterNo): """ Public method to process the syntax error info from the client. @param message message of the syntax error (string) @param filename translated filename of the syntax error position (string) @param lineNo line number of the syntax error position (integer) @param characterNo character number of the syntax error position (integer) """ if self.running: self.clientSyntaxError.emit(message, filename, lineNo, characterNo) def signalClientExit(self, status): """ Public method to process the client exit status. @param status exit code as a string (string) """ if self.passive: self.__passiveShutDown() self.clientExit.emit(int(status)) if Preferences.getDebugger("AutomaticReset"): self.startClient(False) if self.passive: self.__createDebuggerInterface("None") self.signalClientOutput(self.tr('\nNot connected\n')) self.signalClientStatement(False) self.running = False def signalClientClearBreak(self, filename, lineno): """ Public method to process the client clear breakpoint command. @param filename filename of the breakpoint (string) @param lineno line umber of the breakpoint (integer) """ self.clientClearBreak.emit(filename, lineno) def signalClientBreakConditionError(self, filename, lineno): """ Public method to process the client breakpoint condition error info. @param filename filename of the breakpoint (string) @param lineno line umber of the breakpoint (integer) """ self.clientBreakConditionError.emit(filename, lineno) def signalClientClearWatch(self, condition): """ Public slot to handle the clientClearWatch signal. @param condition expression of watch expression to clear (string) """ self.clientClearWatch.emit(condition) def signalClientWatchConditionError(self, condition): """ Public method to process the client watch expression error info. @param condition expression of watch expression to clear (string) """ self.clientWatchConditionError.emit(condition) def signalClientRawInput(self, prompt, echo): """ Public method to process the client raw input command. @param prompt the input prompt (string) @param echo flag indicating an echoing of the input (boolean) """ self.clientRawInput.emit(prompt, echo) def signalClientBanner(self, version, platform, debugClient): """ Public method to process the client banner info. @param version interpreter version info (string) @param platform hostname of the client (string) @param debugClient additional debugger type info (string) """ self.clientBanner.emit(version, platform, debugClient) def signalClientCapabilities(self, capabilities, clientType): """ Public method to process the client capabilities info. @param capabilities bitmaks with the client capabilities (integer) @param clientType type of the debug client (string) """ self.__clientCapabilities[clientType] = capabilities self.clientCapabilities.emit(capabilities, clientType) def signalClientCompletionList(self, completionList, text): """ Public method to process the client auto completion info. @param completionList list of possible completions (list of strings) @param text the text to be completed (string) """ self.clientCompletionList.emit(completionList, text) def signalClientCallTrace(self, isCall, fromFile, fromLine, fromFunction, toFile, toLine, toFunction): """ Public method to process the client call trace data. @param isCall flag indicating a 'call' (boolean) @param fromFile name of the originating file (string) @param fromLine line number in the originating file (string) @param fromFunction name of the originating function (string) @param toFile name of the target file (string) @param toLine line number in the target file (string) @param toFunction name of the target function (string) """ self.callTraceInfo.emit( isCall, fromFile, fromLine, fromFunction, toFile, toLine, toFunction) def clientUtPrepared(self, result, exceptionType, exceptionValue): """ Public method to process the client unittest prepared info. @param result number of test cases (0 = error) (integer) @param exceptionType exception type (string) @param exceptionValue exception message (string) """ self.utPrepared.emit(result, exceptionType, exceptionValue) def clientUtStartTest(self, testname, doc): """ Public method to process the client start test info. @param testname name of the test (string) @param doc short description of the test (string) """ self.utStartTest.emit(testname, doc) def clientUtStopTest(self): """ Public method to process the client stop test info. """ self.utStopTest.emit() def clientUtTestFailed(self, testname, traceback, id): """ Public method to process the client test failed info. @param testname name of the test (string) @param traceback lines of traceback info (list of strings) @param id id of the test (string) """ self.utTestFailed.emit(testname, traceback, id) def clientUtTestErrored(self, testname, traceback, id): """ Public method to process the client test errored info. @param testname name of the test (string) @param traceback lines of traceback info (list of strings) @param id id of the test (string) """ self.utTestErrored.emit(testname, traceback, id) def clientUtTestSkipped(self, testname, reason, id): """ Public method to process the client test skipped info. @param testname name of the test (string) @param reason reason for skipping the test (string) @param id id of the test (string) """ self.utTestSkipped.emit(testname, reason, id) def clientUtTestFailedExpected(self, testname, traceback, id): """ Public method to process the client test failed expected info. @param testname name of the test (string) @param traceback lines of traceback info (list of strings) @param id id of the test (string) """ self.utTestFailedExpected.emit(testname, traceback, id) def clientUtTestSucceededUnexpected(self, testname, id): """ Public method to process the client test succeeded unexpected info. @param testname name of the test (string) @param id id of the test (string) """ self.utTestSucceededUnexpected.emit(testname, id) def clientUtFinished(self): """ Public method to process the client unit test finished info. """ self.utFinished.emit() def passiveStartUp(self, fn, exc): """ Public method to handle a passive debug connection. @param fn filename of the debugged script (string) @param exc flag to enable exception reporting of the IDE (boolean) """ self.appendStdout.emit(self.tr("Passive debug connection received\n")) self.passiveClientExited = False self.debugging = True self.running = True self.__restoreBreakpoints() self.__restoreWatchpoints() self.passiveDebugStarted.emit(fn, exc) def __passiveShutDown(self): """ Private method to shut down a passive debug connection. """ self.passiveClientExited = True self.shutdownServer() self.appendStdout.emit(self.tr("Passive debug connection closed\n")) def __restoreBreakpoints(self): """ Private method to restore the breakpoints after a restart. """ if self.debugging: self.__addBreakPoints( QModelIndex(), 0, self.breakpointModel.rowCount() - 1) def __restoreWatchpoints(self): """ Private method to restore the watch expressions after a restart. """ if self.debugging: self.__addWatchPoints( QModelIndex(), 0, self.watchpointModel.rowCount() - 1) def getBreakPointModel(self): """ Public slot to get a reference to the breakpoint model object. @return reference to the breakpoint model object (BreakPointModel) """ return self.breakpointModel def getWatchPointModel(self): """ Public slot to get a reference to the watch expression model object. @return reference to the watch expression model object (WatchPointModel) """ return self.watchpointModel def isConnected(self): """ Public method to test, if the debug server is connected to a backend. @return flag indicating a connection (boolean) """ return self.debuggerInterface and self.debuggerInterface.isConnected() eric-6.0.8/eric/Debugger/EditBreakpointDialog.py0000644000175000017500000001341412451233373020575 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to edit breakpoint properties. """ from __future__ import unicode_literals import os.path from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .Ui_EditBreakpointDialog import Ui_EditBreakpointDialog import Utilities import UI.PixmapCache class EditBreakpointDialog(QDialog, Ui_EditBreakpointDialog): """ Class implementing a dialog to edit breakpoint properties. """ def __init__(self, id, properties, condHistory, parent=None, name=None, modal=False, addMode=False, filenameHistory=None): """ Constructor @param id id of the breakpoint (tuple) (filename, linenumber) @param properties properties for the breakpoint (tuple) (condition, temporary flag, enabled flag, ignore count) @param condHistory the list of conditionals history (list of strings) @param parent the parent of this dialog (QWidget) @param name the widget name of this dialog (string) @param modal flag indicating a modal dialog (boolean) @param addMode flag indicating the add mode (boolean) @param filenameHistory list of recently used file names (list of strings) """ super(EditBreakpointDialog, self).__init__(parent) self.setupUi(self) if name: self.setObjectName(name) self.setModal(modal) self.fileButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.filenameCompleter = E5FileCompleter(self.filenameCombo) fn, lineno = id if not addMode: cond, temp, enabled, count = properties # set the filename if fn is not None: self.filenameCombo.setEditText(fn) # set the line number self.linenoSpinBox.setValue(lineno) # set the condition if cond is None: cond = '' try: curr = condHistory.index(cond) except ValueError: condHistory.insert(0, cond) curr = 0 self.conditionCombo.addItems(condHistory) self.conditionCombo.setCurrentIndex(curr) # set the ignore count self.ignoreSpinBox.setValue(count) # set the checkboxes self.temporaryCheckBox.setChecked(temp) self.enabledCheckBox.setChecked(enabled) self.filenameCombo.setEnabled(False) self.fileButton.setEnabled(False) self.linenoSpinBox.setEnabled(False) self.conditionCombo.setFocus() else: self.setWindowTitle(self.tr("Add Breakpoint")) # set the filename if fn is None: fn = "" try: curr = filenameHistory.index(fn) except ValueError: filenameHistory.insert(0, fn) curr = 0 self.filenameCombo.addItems(filenameHistory) self.filenameCombo.setCurrentIndex(curr) # set the condition cond = '' try: curr = condHistory.index(cond) except ValueError: condHistory.insert(0, cond) curr = 0 self.conditionCombo.addItems(condHistory) self.conditionCombo.setCurrentIndex(curr) if not fn: self.okButton.setEnabled(False) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_fileButton_clicked(self): """ Private slot to select a file via a file selection dialog. """ file = E5FileDialog.getOpenFileName( self, self.tr("Select filename of the breakpoint"), self.filenameCombo.currentText(), "") if file: self.filenameCombo.setEditText(Utilities.toNativeSeparators(file)) def on_filenameCombo_editTextChanged(self, fn): """ Private slot to handle the change of the filename. @param fn text of the filename edit (string) """ if not fn: self.okButton.setEnabled(False) else: self.okButton.setEnabled(True) def getData(self): """ Public method to retrieve the entered data. @return a tuple containing the breakpoints new properties (condition, temporary flag, enabled flag, ignore count) """ return (self.conditionCombo.currentText(), self.temporaryCheckBox.isChecked(), self.enabledCheckBox.isChecked(), self.ignoreSpinBox.value()) def getAddData(self): """ Public method to retrieve the entered data for an add. @return a tuple containing the new breakpoints properties (filename, lineno, condition, temporary flag, enabled flag, ignore count) """ fn = self.filenameCombo.currentText() if not fn: fn = None else: fn = os.path.expanduser(os.path.expandvars(fn)) return (fn, self.linenoSpinBox.value(), self.conditionCombo.currentText(), self.temporaryCheckBox.isChecked(), self.enabledCheckBox.isChecked(), self.ignoreSpinBox.value()) eric-6.0.8/eric/Debugger/BreakPointModel.py0000644000175000017500000002527612451233373017601 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Breakpoint model. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QAbstractItemModel, QModelIndex class BreakPointModel(QAbstractItemModel): """ Class implementing a custom model for breakpoints. """ dataAboutToBeChanged = pyqtSignal(QModelIndex, QModelIndex) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QObject) """ super(BreakPointModel, self).__init__(parent) self.breakpoints = [] self.header = [ self.tr("Filename"), self.tr("Line"), self.tr('Condition'), self.tr('Temporary'), self.tr('Enabled'), self.tr('Ignore Count'), ] self.alignments = [Qt.Alignment(Qt.AlignLeft), Qt.Alignment(Qt.AlignRight), Qt.Alignment(Qt.AlignLeft), Qt.Alignment(Qt.AlignHCenter), Qt.Alignment(Qt.AlignHCenter), Qt.Alignment(Qt.AlignRight), Qt.Alignment(Qt.AlignHCenter), ] def columnCount(self, parent=QModelIndex()): """ Public method to get the current column count. @param parent reference to parent index (QModelIndex) @return column count (integer) """ return len(self.header) def rowCount(self, parent=QModelIndex()): """ Public method to get the current row count. @param parent reference to parent index (QModelIndex) @return row count (integer) """ # we do not have a tree, parent should always be invalid if not parent.isValid(): return len(self.breakpoints) else: return 0 def data(self, index, role=Qt.DisplayRole): """ Public method to get the requested data. @param index index of the requested data (QModelIndex) @param role role of the requested data (Qt.ItemDataRole) @return the requested data """ if not index.isValid(): return None if role == Qt.DisplayRole: if index.column() in [0, 1, 2, 5]: return self.breakpoints[index.row()][index.column()] if role == Qt.CheckStateRole: if index.column() in [3, 4]: return self.breakpoints[index.row()][index.column()] if role == Qt.ToolTipRole: if index.column() in [0, 2]: return self.breakpoints[index.row()][index.column()] if role == Qt.TextAlignmentRole: if index.column() < len(self.alignments): return self.alignments[index.column()] return None def setData(self, index, value, role=Qt.EditRole): """ Public method to change data in the model. @param index index of the changed data (QModelIndex) @param value value of the changed data @param role role of the changed data (Qt.ItemDataRole) @return flag indicating success (boolean) """ if not index.isValid() or \ index.column() >= len(self.header) or \ index.row() >= len(self.breakpoints): return False self.dataAboutToBeChanged.emit(index, index) self.breakpoints[index.row()][index.column()] = value self.dataChanged.emit(index, index) return True def flags(self, index): """ Public method to get item flags. @param index index of the requested flags (QModelIndex) @return item flags for the given index (Qt.ItemFlags) """ if not index.isValid(): return Qt.ItemIsEnabled return Qt.ItemIsEnabled | Qt.ItemIsSelectable def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get header data. @param section section number of the requested header data (integer) @param orientation orientation of the header (Qt.Orientation) @param role role of the requested data (Qt.ItemDataRole) @return header data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: if section >= len(self.header): return "" else: return self.header[section] return None def index(self, row, column, parent=QModelIndex()): """ Public method to create an index. @param row row number for the index (integer) @param column column number for the index (integer) @param parent index of the parent item (QModelIndex) @return requested index (QModelIndex) """ if parent.isValid() or \ row < 0 or row >= len(self.breakpoints) or \ column < 0 or column >= len(self.header): return QModelIndex() return self.createIndex(row, column, self.breakpoints[row]) def parent(self, index): """ Public method to get the parent index. @param index index of item to get parent (QModelIndex) @return index of parent (QModelIndex) """ return QModelIndex() def hasChildren(self, parent=QModelIndex()): """ Public method to check for the presence of child items. @param parent index of parent item (QModelIndex) @return flag indicating the presence of child items (boolean) """ if not parent.isValid(): return len(self.breakpoints) > 0 else: return False ########################################################################### def addBreakPoint(self, fn, line, properties): """ Public method to add a new breakpoint to the list. @param fn filename of the breakpoint (string) @param line line number of the breakpoint (integer) @param properties properties of the breakpoint (tuple of condition (string), temporary flag (bool), enabled flag (bool), ignore count (integer)) """ bp = [fn, line] + list(properties) cnt = len(self.breakpoints) self.beginInsertRows(QModelIndex(), cnt, cnt) self.breakpoints.append(bp) self.endInsertRows() def setBreakPointByIndex(self, index, fn, line, properties): """ Public method to set the values of a breakpoint given by index. @param index index of the breakpoint (QModelIndex) @param fn filename of the breakpoint (string) @param line line number of the breakpoint (integer) @param properties properties of the breakpoint (tuple of condition (string), temporary flag (bool), enabled flag (bool), ignore count (integer)) """ if index.isValid(): row = index.row() index1 = self.createIndex(row, 0, self.breakpoints[row]) index2 = self.createIndex( row, len(self.breakpoints[row]), self.breakpoints[row]) self.dataAboutToBeChanged.emit(index1, index2) self.breakpoints[row] = [fn, line] + list(properties) self.dataChanged.emit(index1, index2) def setBreakPointEnabledByIndex(self, index, enabled): """ Public method to set the enabled state of a breakpoint given by index. @param index index of the breakpoint (QModelIndex) @param enabled flag giving the enabled state (boolean) """ if index.isValid(): row = index.row() col = 4 index1 = self.createIndex(row, col, self.breakpoints[row]) self.dataAboutToBeChanged.emit(index1, index1) self.breakpoints[row][col] = enabled self.dataChanged.emit(index1, index1) def deleteBreakPointByIndex(self, index): """ Public method to set the values of a breakpoint given by index. @param index index of the breakpoint (QModelIndex) """ if index.isValid(): row = index.row() self.beginRemoveRows(QModelIndex(), row, row) del self.breakpoints[row] self.endRemoveRows() def deleteBreakPoints(self, idxList): """ Public method to delete a list of breakpoints given by their indexes. @param idxList list of breakpoint indexes (list of QModelIndex) """ rows = [] for index in idxList: if index.isValid(): rows.append(index.row()) rows.sort(reverse=True) for row in rows: self.beginRemoveRows(QModelIndex(), row, row) del self.breakpoints[row] self.endRemoveRows() def deleteAll(self): """ Public method to delete all breakpoints. """ if self.breakpoints: self.beginRemoveRows(QModelIndex(), 0, len(self.breakpoints) - 1) self.breakpoints = [] self.endRemoveRows() def getBreakPointByIndex(self, index): """ Public method to get the values of a breakpoint given by index. @param index index of the breakpoint (QModelIndex) @return breakpoint (list of seven values (filename, line number, condition, temporary flag, enabled flag, ignore count)) """ if index.isValid(): return self.breakpoints[index.row()][:] # return a copy else: return [] def getBreakPointIndex(self, fn, lineno): """ Public method to get the index of a breakpoint given by filename and line number. @param fn filename of the breakpoint (string) @param lineno line number of the breakpoint (integer) @return index (QModelIndex) """ for row in range(len(self.breakpoints)): bp = self.breakpoints[row] if bp[0] == fn and bp[1] == lineno: return self.createIndex(row, 0, self.breakpoints[row]) return QModelIndex() def isBreakPointTemporaryByIndex(self, index): """ Public method to test, if a breakpoint given by its index is temporary. @param index index of the breakpoint to test (QModelIndex) @return flag indicating a temporary breakpoint (boolean) """ if index.isValid(): return self.breakpoints[index.row()][3] else: return False eric-6.0.8/eric/Debugger/DebugUI.py0000644000175000017500000025501212525420526016037 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the debugger UI. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal, QObject, Qt from PyQt5.QtGui import QKeySequence from PyQt5.QtWidgets import QMenu, QToolBar, QApplication, QDialog, \ QInputDialog from UI.Info import Program from .DebugClientCapabilities import HasDebugger, HasInterpreter, \ HasProfiler, HasCoverage import Preferences import Utilities import UI.PixmapCache import UI.Config from E5Gui.E5Action import E5Action, createActionGroup from E5Gui import E5MessageBox from eric6config import getConfig class DebugUI(QObject): """ Class implementing the debugger part of the UI. @signal clientStack(stack) emitted at breaking after a reported exception @signal compileForms() emitted if changed project forms should be compiled @signal compileResources() emitted if changed project resources should be compiled @signal debuggingStarted(filename) emitted when a debugging session was started @signal resetUI() emitted to reset the UI @signal exceptionInterrupt() emitted after the execution was interrupted by an exception and acknowledged by the user @signal appendStdout(msg) emitted when the client program has terminated and the display of the termination dialog is suppressed """ clientStack = pyqtSignal(list) resetUI = pyqtSignal() exceptionInterrupt = pyqtSignal() compileForms = pyqtSignal() compileResources = pyqtSignal() debuggingStarted = pyqtSignal(str) appendStdout = pyqtSignal(str) def __init__(self, ui, vm, debugServer, debugViewer, project): """ Constructor @param ui reference to the main UI @param vm reference to the viewmanager @param debugServer reference to the debug server @param debugViewer reference to the debug viewer widget @param project reference to the project object """ super(DebugUI, self).__init__(ui) self.ui = ui self.viewmanager = vm self.debugServer = debugServer self.debugViewer = debugViewer self.project = project # Clear some variables self.projectOpen = False self.editorOpen = False # read the saved debug info values self.argvHistory = Preferences.toList( Preferences.Prefs.settings.value('DebugInfo/ArgumentsHistory')) self.wdHistory = Preferences.toList( Preferences.Prefs.settings.value( 'DebugInfo/WorkingDirectoryHistory')) self.envHistory = Preferences.toList( Preferences.Prefs.settings.value('DebugInfo/EnvironmentHistory')) self.excList = Preferences.toList( Preferences.Prefs.settings.value('DebugInfo/Exceptions')) self.excIgnoreList = Preferences.toList( Preferences.Prefs.settings.value('DebugInfo/IgnoredExceptions')) self.exceptions = Preferences.toBool( Preferences.Prefs.settings.value( 'DebugInfo/ReportExceptions', True)) self.autoClearShell = Preferences.toBool( Preferences.Prefs.settings.value('DebugInfo/AutoClearShell', True)) self.tracePython = Preferences.toBool( Preferences.Prefs.settings.value('DebugInfo/TracePython', False)) self.autoContinue = Preferences.toBool( Preferences.Prefs.settings.value('DebugInfo/AutoContinue', True)) self.forkAutomatically = Preferences.toBool( Preferences.Prefs.settings.value( 'DebugInfo/ForkAutomatically', False)) self.forkIntoChild = Preferences.toBool( Preferences.Prefs.settings.value('DebugInfo/ForkIntoChild', False)) self.evalHistory = [] self.execHistory = [] self.lastDebuggedFile = None self.lastStartAction = 0 # 0=None, 1=Script, 2=Project self.clientType = "" self.lastAction = -1 self.debugActions = [ self.__continue, self.__step, self.__stepOver, self.__stepOut, self.__stepQuit, self.__runToCursor ] self.localsVarFilter, self.globalsVarFilter = \ Preferences.getVarFilters() self.debugViewer.setVariablesFilter( self.globalsVarFilter, self.localsVarFilter) # Connect the signals emitted by the debug-server debugServer.clientGone.connect(self.__clientGone) debugServer.clientLine.connect(self.__clientLine) debugServer.clientExit.connect(self.__clientExit) debugServer.clientSyntaxError.connect(self.__clientSyntaxError) debugServer.clientException.connect(self.__clientException) debugServer.clientVariables.connect(self.__clientVariables) debugServer.clientVariable.connect(self.__clientVariable) debugServer.clientBreakConditionError.connect( self.__clientBreakConditionError) debugServer.clientWatchConditionError.connect( self.__clientWatchConditionError) debugServer.passiveDebugStarted.connect(self.__passiveDebugStarted) debugServer.clientThreadSet.connect(self.__clientThreadSet) debugServer.clientRawInput.connect(debugViewer.handleRawInput) debugServer.clientRawInputSent.connect(debugViewer.restoreCurrentPage) debugServer.clientThreadList.connect(debugViewer.showThreadList) # Connect the signals emitted by the viewmanager vm.editorOpened.connect(self.__editorOpened) vm.lastEditorClosed.connect(self.__lastEditorClosed) vm.checkActions.connect(self.__checkActions) vm.cursorChanged.connect(self.__cursorChanged) vm.breakpointToggled.connect(self.__cursorChanged) # Connect the signals emitted by the project project.projectOpened.connect(self.__projectOpened) project.newProject.connect(self.__projectOpened) project.projectClosed.connect(self.__projectClosed) # Set a flag for the passive debug mode self.passive = Preferences.getDebugger("PassiveDbgEnabled") def variablesFilter(self, scope): """ Public method to get the variables filter for a scope. @param scope flag indicating global (True) or local (False) scope @return filters list (list of integers) """ if scope: return self.globalsVarFilter[:] else: return self.localsVarFilter[:] def initActions(self): """ Public method defining the user interface actions. """ self.actions = [] self.runAct = E5Action( self.tr('Run Script'), UI.PixmapCache.getIcon("runScript.png"), self.tr('&Run Script...'), Qt.Key_F2, 0, self, 'dbg_run_script') self.runAct.setStatusTip(self.tr('Run the current Script')) self.runAct.setWhatsThis(self.tr( """Run Script""" """

Set the command line arguments and run the script outside""" """ the debugger. If the file has unsaved changes it may be""" """ saved first.

""" )) self.runAct.triggered.connect(self.__runScript) self.actions.append(self.runAct) self.runProjectAct = E5Action( self.tr('Run Project'), UI.PixmapCache.getIcon("runProject.png"), self.tr('Run &Project...'), Qt.SHIFT + Qt.Key_F2, 0, self, 'dbg_run_project') self.runProjectAct.setStatusTip(self.tr('Run the current Project')) self.runProjectAct.setWhatsThis(self.tr( """Run Project""" """

Set the command line arguments and run the current project""" """ outside the debugger.""" """ If files of the current project have unsaved changes they""" """ may be saved first.

""" )) self.runProjectAct.triggered.connect(self.__runProject) self.actions.append(self.runProjectAct) self.coverageAct = E5Action( self.tr('Coverage run of Script'), UI.PixmapCache.getIcon("coverageScript.png"), self.tr('Coverage run of Script...'), 0, 0, self, 'dbg_coverage_script') self.coverageAct.setStatusTip( self.tr('Perform a coverage run of the current Script')) self.coverageAct.setWhatsThis(self.tr( """Coverage run of Script""" """

Set the command line arguments and run the script under""" """ the control of a coverage analysis tool. If the file has""" """ unsaved changes it may be saved first.

""" )) self.coverageAct.triggered.connect(self.__coverageScript) self.actions.append(self.coverageAct) self.coverageProjectAct = E5Action( self.tr('Coverage run of Project'), UI.PixmapCache.getIcon("coverageProject.png"), self.tr('Coverage run of Project...'), 0, 0, self, 'dbg_coverage_project') self.coverageProjectAct.setStatusTip( self.tr('Perform a coverage run of the current Project')) self.coverageProjectAct.setWhatsThis(self.tr( """Coverage run of Project""" """

Set the command line arguments and run the current project""" """ under the control of a coverage analysis tool.""" """ If files of the current project have unsaved changes""" """ they may be saved first.

""" )) self.coverageProjectAct.triggered.connect(self.__coverageProject) self.actions.append(self.coverageProjectAct) self.profileAct = E5Action( self.tr('Profile Script'), UI.PixmapCache.getIcon("profileScript.png"), self.tr('Profile Script...'), 0, 0, self, 'dbg_profile_script') self.profileAct.setStatusTip(self.tr('Profile the current Script')) self.profileAct.setWhatsThis(self.tr( """Profile Script""" """

Set the command line arguments and profile the script.""" """ If the file has unsaved changes it may be saved first.

""" )) self.profileAct.triggered.connect(self.__profileScript) self.actions.append(self.profileAct) self.profileProjectAct = E5Action( self.tr('Profile Project'), UI.PixmapCache.getIcon("profileProject.png"), self.tr('Profile Project...'), 0, 0, self, 'dbg_profile_project') self.profileProjectAct.setStatusTip( self.tr('Profile the current Project')) self.profileProjectAct.setWhatsThis(self.tr( """Profile Project""" """

Set the command line arguments and profile the current""" """ project. If files of the current project have unsaved""" """ changes they may be saved first.

""" )) self.profileProjectAct.triggered.connect(self.__profileProject) self.actions.append(self.profileProjectAct) self.debugAct = E5Action( self.tr('Debug Script'), UI.PixmapCache.getIcon("debugScript.png"), self.tr('&Debug Script...'), Qt.Key_F5, 0, self, 'dbg_debug_script') self.debugAct.setStatusTip(self.tr('Debug the current Script')) self.debugAct.setWhatsThis(self.tr( """Debug Script""" """

Set the command line arguments and set the current line""" """ to be the first executable Python statement of the current""" """ editor window. If the file has unsaved changes it may be""" """ saved first.

""" )) self.debugAct.triggered.connect(self.__debugScript) self.actions.append(self.debugAct) self.debugProjectAct = E5Action( self.tr('Debug Project'), UI.PixmapCache.getIcon("debugProject.png"), self.tr('Debug &Project...'), Qt.SHIFT + Qt.Key_F5, 0, self, 'dbg_debug_project') self.debugProjectAct.setStatusTip(self.tr( 'Debug the current Project')) self.debugProjectAct.setWhatsThis(self.tr( """Debug Project""" """

Set the command line arguments and set the current line""" """ to be the first executable Python statement of the main""" """ script of the current project. If files of the current""" """ project have unsaved changes they may be saved first.

""" )) self.debugProjectAct.triggered.connect(self.__debugProject) self.actions.append(self.debugProjectAct) self.restartAct = E5Action( self.tr('Restart'), UI.PixmapCache.getIcon("restart.png"), self.tr('Restart'), Qt.Key_F4, 0, self, 'dbg_restart_script') self.restartAct.setStatusTip(self.tr( 'Restart the last debugged script')) self.restartAct.setWhatsThis(self.tr( """Restart""" """

Set the command line arguments and set the current line""" """ to be the first executable Python statement of the script""" """ that was debugged last. If there are unsaved changes, they""" """ may be saved first.

""" )) self.restartAct.triggered.connect(self.__doRestart) self.actions.append(self.restartAct) self.stopAct = E5Action( self.tr('Stop'), UI.PixmapCache.getIcon("stopScript.png"), self.tr('Stop'), Qt.SHIFT + Qt.Key_F10, 0, self, 'dbg_stop_script') self.stopAct.setStatusTip(self.tr("""Stop the running script.""")) self.stopAct.setWhatsThis(self.tr( """Stop""" """

This stops the script running in the debugger backend.

""" )) self.stopAct.triggered.connect(self.__stopScript) self.actions.append(self.stopAct) self.debugActGrp = createActionGroup(self) act = E5Action( self.tr('Continue'), UI.PixmapCache.getIcon("continue.png"), self.tr('&Continue'), Qt.Key_F6, 0, self.debugActGrp, 'dbg_continue') act.setStatusTip( self.tr('Continue running the program from the current line')) act.setWhatsThis(self.tr( """Continue""" """

Continue running the program from the current line. The""" """ program will stop when it terminates or when a breakpoint""" """ is reached.

""" )) act.triggered.connect(self.__continue) self.actions.append(act) act = E5Action( self.tr('Continue to Cursor'), UI.PixmapCache.getIcon("continueToCursor.png"), self.tr('Continue &To Cursor'), Qt.SHIFT + Qt.Key_F6, 0, self.debugActGrp, 'dbg_continue_to_cursor') act.setStatusTip(self.tr( """Continue running the program from the""" """ current line to the current cursor position""")) act.setWhatsThis(self.tr( """Continue To Cursor""" """

Continue running the program from the current line to the""" """ current cursor position.

""" )) act.triggered.connect(self.__runToCursor) self.actions.append(act) act = E5Action( self.tr('Single Step'), UI.PixmapCache.getIcon("step.png"), self.tr('Sin&gle Step'), Qt.Key_F7, 0, self.debugActGrp, 'dbg_single_step') act.setStatusTip(self.tr('Execute a single Python statement')) act.setWhatsThis(self.tr( """Single Step""" """

Execute a single Python statement. If the statement""" """ is an import statement, a class constructor, or a""" """ method or function call then control is returned to the""" """ debugger at the next statement.

""" )) act.triggered.connect(self.__step) self.actions.append(act) act = E5Action( self.tr('Step Over'), UI.PixmapCache.getIcon("stepOver.png"), self.tr('Step &Over'), Qt.Key_F8, 0, self.debugActGrp, 'dbg_step_over') act.setStatusTip(self.tr( """Execute a single Python statement staying""" """ in the current frame""")) act.setWhatsThis(self.tr( """Step Over""" """

Execute a single Python statement staying in the same""" """ frame. If the statement is an import statement,""" """ a class constructor, or a method or function call then""" """ control is returned to the debugger after the statement""" """ has completed.

""" )) act.triggered.connect(self.__stepOver) self.actions.append(act) act = E5Action( self.tr('Step Out'), UI.PixmapCache.getIcon("stepOut.png"), self.tr('Step Ou&t'), Qt.Key_F9, 0, self.debugActGrp, 'dbg_step_out') act.setStatusTip(self.tr( """Execute Python statements until leaving""" """ the current frame""")) act.setWhatsThis(self.tr( """Step Out""" """

Execute Python statements until leaving the current""" """ frame. If the statements are inside an import""" """ statement, a class constructor, or a method or function""" """ call then control is returned to the debugger after the""" """ current frame has been left.

""" )) act.triggered.connect(self.__stepOut) self.actions.append(act) act = E5Action( self.tr('Stop'), UI.PixmapCache.getIcon("stepQuit.png"), self.tr('&Stop'), Qt.Key_F10, 0, self.debugActGrp, 'dbg_stop') act.setStatusTip(self.tr('Stop debugging')) act.setWhatsThis(self.tr( """Stop""" """

Stop the running debugging session.

""" )) act.triggered.connect(self.__stepQuit) self.actions.append(act) self.debugActGrp2 = createActionGroup(self) act = E5Action( self.tr('Evaluate'), self.tr('E&valuate...'), 0, 0, self.debugActGrp2, 'dbg_evaluate') act.setStatusTip(self.tr('Evaluate in current context')) act.setWhatsThis(self.tr( """Evaluate""" """

Evaluate an expression in the current context of the""" """ debugged program. The result is displayed in the""" """ shell window.

""" )) act.triggered.connect(self.__eval) self.actions.append(act) act = E5Action( self.tr('Execute'), self.tr('E&xecute...'), 0, 0, self.debugActGrp2, 'dbg_execute') act.setStatusTip( self.tr('Execute a one line statement in the current context')) act.setWhatsThis(self.tr( """Execute""" """

Execute a one line statement in the current context""" """ of the debugged program.

""" )) act.triggered.connect(self.__exec) self.actions.append(act) self.dbgFilterAct = E5Action( self.tr('Variables Type Filter'), self.tr('Varia&bles Type Filter...'), 0, 0, self, 'dbg_variables_filter') self.dbgFilterAct.setStatusTip(self.tr( 'Configure variables type filter')) self.dbgFilterAct.setWhatsThis(self.tr( """Variables Type Filter""" """

Configure the variables type filter. Only variable types""" """ that are not selected are displayed in the global or local""" """ variables window during a debugging session.

""" )) self.dbgFilterAct.triggered.connect( self.__configureVariablesFilters) self.actions.append(self.dbgFilterAct) self.excFilterAct = E5Action( self.tr('Exceptions Filter'), self.tr('&Exceptions Filter...'), 0, 0, self, 'dbg_exceptions_filter') self.excFilterAct.setStatusTip(self.tr( 'Configure exceptions filter')) self.excFilterAct.setWhatsThis(self.tr( """Exceptions Filter""" """

Configure the exceptions filter. Only exception types""" """ that are listed are highlighted during a debugging""" """ session.

Please note, that all unhandled exceptions""" """ are highlighted indepent from the filter list.

""" )) self.excFilterAct.triggered.connect( self.__configureExceptionsFilter) self.actions.append(self.excFilterAct) self.excIgnoreFilterAct = E5Action( self.tr('Ignored Exceptions'), self.tr('&Ignored Exceptions...'), 0, 0, self, 'dbg_ignored_exceptions') self.excIgnoreFilterAct.setStatusTip(self.tr( 'Configure ignored exceptions')) self.excIgnoreFilterAct.setWhatsThis(self.tr( """Ignored Exceptions""" """

Configure the ignored exceptions. Only exception types""" """ that are not listed are highlighted during a debugging""" """ session.

Please note, that unhandled exceptions""" """ cannot be ignored.

""" )) self.excIgnoreFilterAct.triggered.connect( self.__configureIgnoredExceptions) self.actions.append(self.excIgnoreFilterAct) self.dbgSetBpActGrp = createActionGroup(self) self.dbgToggleBpAct = E5Action( self.tr('Toggle Breakpoint'), UI.PixmapCache.getIcon("breakpointToggle.png"), self.tr('Toggle Breakpoint'), QKeySequence(self.tr("Shift+F11", "Debug|Toggle Breakpoint")), 0, self.dbgSetBpActGrp, 'dbg_toggle_breakpoint') self.dbgToggleBpAct.setStatusTip(self.tr('Toggle Breakpoint')) self.dbgToggleBpAct.setWhatsThis(self.tr( """Toggle Breakpoint""" """

Toggles a breakpoint at the current line of the""" """ current editor.

""" )) self.dbgToggleBpAct.triggered.connect(self.__toggleBreakpoint) self.actions.append(self.dbgToggleBpAct) self.dbgEditBpAct = E5Action( self.tr('Edit Breakpoint'), UI.PixmapCache.getIcon("cBreakpointToggle.png"), self.tr('Edit Breakpoint...'), QKeySequence(self.tr("Shift+F12", "Debug|Edit Breakpoint")), 0, self.dbgSetBpActGrp, 'dbg_edit_breakpoint') self.dbgEditBpAct.setStatusTip(self.tr('Edit Breakpoint')) self.dbgEditBpAct.setWhatsThis(self.tr( """Edit Breakpoint""" """

Opens a dialog to edit the breakpoints properties.""" """ It works at the current line of the current editor.

""" )) self.dbgEditBpAct.triggered.connect(self.__editBreakpoint) self.actions.append(self.dbgEditBpAct) self.dbgNextBpAct = E5Action( self.tr('Next Breakpoint'), UI.PixmapCache.getIcon("breakpointNext.png"), self.tr('Next Breakpoint'), QKeySequence( self.tr("Ctrl+Shift+PgDown", "Debug|Next Breakpoint")), 0, self.dbgSetBpActGrp, 'dbg_next_breakpoint') self.dbgNextBpAct.setStatusTip(self.tr('Next Breakpoint')) self.dbgNextBpAct.setWhatsThis(self.tr( """Next Breakpoint""" """

Go to next breakpoint of the current editor.

""" )) self.dbgNextBpAct.triggered.connect(self.__nextBreakpoint) self.actions.append(self.dbgNextBpAct) self.dbgPrevBpAct = E5Action( self.tr('Previous Breakpoint'), UI.PixmapCache.getIcon("breakpointPrevious.png"), self.tr('Previous Breakpoint'), QKeySequence( self.tr("Ctrl+Shift+PgUp", "Debug|Previous Breakpoint")), 0, self.dbgSetBpActGrp, 'dbg_previous_breakpoint') self.dbgPrevBpAct.setStatusTip(self.tr('Previous Breakpoint')) self.dbgPrevBpAct.setWhatsThis(self.tr( """Previous Breakpoint""" """

Go to previous breakpoint of the current editor.

""" )) self.dbgPrevBpAct.triggered.connect(self.__previousBreakpoint) self.actions.append(self.dbgPrevBpAct) act = E5Action( self.tr('Clear Breakpoints'), self.tr('Clear Breakpoints'), QKeySequence( self.tr("Ctrl+Shift+C", "Debug|Clear Breakpoints")), 0, self.dbgSetBpActGrp, 'dbg_clear_breakpoint') act.setStatusTip(self.tr('Clear Breakpoints')) act.setWhatsThis(self.tr( """Clear Breakpoints""" """

Clear breakpoints of all editors.

""" )) act.triggered.connect(self.__clearBreakpoints) self.actions.append(act) self.debugActGrp.setEnabled(False) self.debugActGrp2.setEnabled(False) self.dbgSetBpActGrp.setEnabled(False) self.runAct.setEnabled(False) self.runProjectAct.setEnabled(False) self.profileAct.setEnabled(False) self.profileProjectAct.setEnabled(False) self.coverageAct.setEnabled(False) self.coverageProjectAct.setEnabled(False) self.debugAct.setEnabled(False) self.debugProjectAct.setEnabled(False) self.restartAct.setEnabled(False) self.stopAct.setEnabled(False) def initMenus(self): """ Public slot to initialize the project menu. @return the generated menu """ dmenu = QMenu(self.tr('&Debug'), self.parent()) dmenu.setTearOffEnabled(True) smenu = QMenu(self.tr('&Start'), self.parent()) smenu.setTearOffEnabled(True) self.breakpointsMenu = QMenu(self.tr('&Breakpoints'), dmenu) smenu.addAction(self.restartAct) smenu.addAction(self.stopAct) smenu.addSeparator() smenu.addAction(self.runAct) smenu.addAction(self.runProjectAct) smenu.addSeparator() smenu.addAction(self.debugAct) smenu.addAction(self.debugProjectAct) smenu.addSeparator() smenu.addAction(self.profileAct) smenu.addAction(self.profileProjectAct) smenu.addSeparator() smenu.addAction(self.coverageAct) smenu.addAction(self.coverageProjectAct) dmenu.addActions(self.debugActGrp.actions()) dmenu.addSeparator() dmenu.addActions(self.debugActGrp2.actions()) dmenu.addSeparator() dmenu.addActions(self.dbgSetBpActGrp.actions()) self.menuBreakpointsAct = dmenu.addMenu(self.breakpointsMenu) dmenu.addSeparator() dmenu.addAction(self.dbgFilterAct) dmenu.addAction(self.excFilterAct) dmenu.addAction(self.excIgnoreFilterAct) self.breakpointsMenu.aboutToShow.connect(self.__showBreakpointsMenu) self.breakpointsMenu.triggered.connect(self.__breakpointSelected) dmenu.aboutToShow.connect(self.__showDebugMenu) return smenu, dmenu def initToolbars(self, toolbarManager): """ Public slot to initialize the debug toolbars. @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) @return the generated toolbars (list of QToolBar) """ starttb = QToolBar(self.tr("Start"), self.ui) starttb.setIconSize(UI.Config.ToolBarIconSize) starttb.setObjectName("StartToolbar") starttb.setToolTip(self.tr('Start')) starttb.addAction(self.restartAct) starttb.addAction(self.stopAct) starttb.addSeparator() starttb.addAction(self.runAct) starttb.addAction(self.runProjectAct) starttb.addSeparator() starttb.addAction(self.debugAct) starttb.addAction(self.debugProjectAct) debugtb = QToolBar(self.tr("Debug"), self.ui) debugtb.setIconSize(UI.Config.ToolBarIconSize) debugtb.setObjectName("DebugToolbar") debugtb.setToolTip(self.tr('Debug')) debugtb.addActions(self.debugActGrp.actions()) debugtb.addSeparator() debugtb.addAction(self.dbgToggleBpAct) debugtb.addAction(self.dbgEditBpAct) debugtb.addAction(self.dbgNextBpAct) debugtb.addAction(self.dbgPrevBpAct) toolbarManager.addToolBar(starttb, starttb.windowTitle()) toolbarManager.addToolBar(debugtb, debugtb.windowTitle()) toolbarManager.addAction(self.profileAct, starttb.windowTitle()) toolbarManager.addAction(self.profileProjectAct, starttb.windowTitle()) toolbarManager.addAction(self.coverageAct, starttb.windowTitle()) toolbarManager.addAction(self.coverageProjectAct, starttb.windowTitle()) return [starttb, debugtb] def setArgvHistory(self, argsStr, clearHistories=False): """ Public slot to initialize the argv history. @param argsStr the commandline arguments (string) @param clearHistories flag indicating, that the list should be cleared (boolean) """ if clearHistories: self.argvHistory = [] else: if argsStr in self.argvHistory: self.argvHistory.remove(argsStr) self.argvHistory.insert(0, argsStr) def setWdHistory(self, wdStr, clearHistories=False): """ Public slot to initialize the wd history. @param wdStr the working directory (string) @param clearHistories flag indicating, that the list should be cleared (boolean) """ if clearHistories: self.wdHistory = [] else: if wdStr in self.wdHistory: self.wdHistory.remove(wdStr) self.wdHistory.insert(0, wdStr) def setEnvHistory(self, envStr, clearHistories=False): """ Public slot to initialize the env history. @param envStr the environment settings (string) @param clearHistories flag indicating, that the list should be cleared (boolean) """ if clearHistories: self.envHistory = [] else: if envStr in self.envHistory: self.envHistory.remove(envStr) self.envHistory.insert(0, envStr) def setExceptionReporting(self, exceptions): """ Public slot to initialize the exception reporting flag. @param exceptions flag indicating exception reporting status (boolean) """ self.exceptions = exceptions def setExcList(self, excList): """ Public slot to initialize the exceptions type list. @param excList list of exception types (list of strings) """ self.excList = excList[:] # keep a copy def setExcIgnoreList(self, excIgnoreList): """ Public slot to initialize the ignored exceptions type list. @param excIgnoreList list of ignored exception types (list of strings) """ self.excIgnoreList = excIgnoreList[:] # keep a copy def setAutoClearShell(self, autoClearShell): """ Public slot to initialize the autoClearShell flag. @param autoClearShell flag indicating, that the interpreter window should be cleared (boolean) """ self.autoClearShell = autoClearShell def setTracePython(self, tracePython): """ Public slot to initialize the trace Python flag. @param tracePython flag indicating if the Python library should be traced as well (boolean) """ self.tracePython = tracePython def setAutoContinue(self, autoContinue): """ Public slot to initialize the autoContinue flag. @param autoContinue flag indicating, that the debugger should not stop at the first executable line (boolean) """ self.autoContinue = autoContinue def __editorOpened(self, fn): """ Private slot to handle the editorOpened signal. @param fn filename of the opened editor """ self.editorOpen = True if fn: editor = self.viewmanager.getOpenEditor(fn) else: editor = None self.__checkActions(editor) def __lastEditorClosed(self): """ Private slot to handle the closeProgram signal. """ self.editorOpen = False self.debugAct.setEnabled(False) self.runAct.setEnabled(False) self.profileAct.setEnabled(False) self.coverageAct.setEnabled(False) self.debugActGrp.setEnabled(False) self.debugActGrp2.setEnabled(False) self.dbgSetBpActGrp.setEnabled(False) self.lastAction = -1 if not self.projectOpen: self.restartAct.setEnabled(False) self.lastDebuggedFile = None self.lastStartAction = 0 self.clientType = "" def __checkActions(self, editor): """ Private slot to check some actions for their enable/disable status. @param editor editor window """ if editor: fn = editor.getFileName() else: fn = None cap = 0 if fn: for language in self.debugServer.getSupportedLanguages(): exts = self.debugServer.getExtensions(language) if fn.endswith(exts): cap = self.debugServer.getClientCapabilities(language) break else: if editor.isPy2File(): cap = self.debugServer.getClientCapabilities('Python2') elif editor.isPy3File(): cap = self.debugServer.getClientCapabilities('Python3') elif editor.isRubyFile(): cap = self.debugServer.getClientCapabilities('Ruby') if not self.passive: self.runAct.setEnabled(cap & HasInterpreter) self.coverageAct.setEnabled(cap & HasCoverage) self.profileAct.setEnabled(cap & HasProfiler) self.debugAct.setEnabled(cap & HasDebugger) self.dbgSetBpActGrp.setEnabled(cap & HasDebugger) if editor.curLineHasBreakpoint(): self.dbgEditBpAct.setEnabled(True) else: self.dbgEditBpAct.setEnabled(False) if editor.hasBreakpoints(): self.dbgNextBpAct.setEnabled(True) self.dbgPrevBpAct.setEnabled(True) else: self.dbgNextBpAct.setEnabled(False) self.dbgPrevBpAct.setEnabled(False) else: self.runAct.setEnabled(False) self.coverageAct.setEnabled(False) self.profileAct.setEnabled(False) self.debugAct.setEnabled(False) self.dbgSetBpActGrp.setEnabled(False) def __cursorChanged(self, editor): """ Private slot handling the cursorChanged signal of the viewmanager. @param editor editor window """ if editor is None: return if editor.isPyFile() or editor.isRubyFile(): if editor.curLineHasBreakpoint(): self.dbgEditBpAct.setEnabled(True) else: self.dbgEditBpAct.setEnabled(False) if editor.hasBreakpoints(): self.dbgNextBpAct.setEnabled(True) self.dbgPrevBpAct.setEnabled(True) else: self.dbgNextBpAct.setEnabled(False) self.dbgPrevBpAct.setEnabled(False) def __projectOpened(self): """ Private slot to handle the projectOpened signal. """ self.projectOpen = True cap = self.debugServer.getClientCapabilities( self.project.pdata["PROGLANGUAGE"][0]) if not self.passive: self.debugProjectAct.setEnabled(cap & HasDebugger) self.runProjectAct.setEnabled(cap & HasInterpreter) self.profileProjectAct.setEnabled(cap & HasProfiler) self.coverageProjectAct.setEnabled(cap & HasCoverage) def __projectClosed(self): """ Private slot to handle the projectClosed signal. """ self.projectOpen = False self.runProjectAct.setEnabled(False) self.profileProjectAct.setEnabled(False) self.coverageProjectAct.setEnabled(False) self.debugProjectAct.setEnabled(False) if not self.editorOpen: self.restartAct.setEnabled(False) self.lastDebuggedFile = None self.lastStartAction = 0 self.clientType = "" def shutdown(self): """ Public method to perform shutdown actions. """ # Just save the 10 most recent entries del self.argvHistory[10:] del self.wdHistory[10:] del self.envHistory[10:] Preferences.Prefs.settings.setValue( 'DebugInfo/ArgumentsHistory', self.argvHistory) Preferences.Prefs.settings.setValue( 'DebugInfo/WorkingDirectoryHistory', self.wdHistory) Preferences.Prefs.settings.setValue( 'DebugInfo/EnvironmentHistory', self.envHistory) Preferences.Prefs.settings.setValue( 'DebugInfo/Exceptions', self.excList) Preferences.Prefs.settings.setValue( 'DebugInfo/IgnoredExceptions', self.excIgnoreList) Preferences.Prefs.settings.setValue( 'DebugInfo/ReportExceptions', self.exceptions) Preferences.Prefs.settings.setValue( 'DebugInfo/AutoClearShell', self.autoClearShell) Preferences.Prefs.settings.setValue( 'DebugInfo/TracePython', self.tracePython) Preferences.Prefs.settings.setValue( 'DebugInfo/AutoContinue', self.autoContinue) Preferences.Prefs.settings.setValue( 'DebugInfo/ForkAutomatically', self.forkAutomatically) Preferences.Prefs.settings.setValue( 'DebugInfo/ForkIntoChild', self.forkIntoChild) def shutdownServer(self): """ Public method to shut down the debug server. This is needed to cleanly close the sockets on Win OS. @return always true """ self.debugServer.shutdownServer() return True def __resetUI(self): """ Private slot to reset the user interface. """ self.lastAction = -1 self.debugActGrp.setEnabled(False) self.debugActGrp2.setEnabled(False) if not self.passive: if self.editorOpen: editor = self.viewmanager.activeWindow() else: editor = None self.__checkActions(editor) self.debugProjectAct.setEnabled(self.projectOpen) self.runProjectAct.setEnabled(self.projectOpen) self.profileProjectAct.setEnabled(self.projectOpen) self.coverageProjectAct.setEnabled(self.projectOpen) if self.lastDebuggedFile is not None and \ (self.editorOpen or self.projectOpen): self.restartAct.setEnabled(True) else: self.restartAct.setEnabled(False) self.stopAct.setEnabled(False) self.resetUI.emit() def __clientLine(self, fn, line, forStack): """ Private method to handle a change to the current line. @param fn filename (string) @param line linenumber (int) @param forStack flag indicating this is for a stack dump (boolean) """ self.ui.raise_() self.ui.activateWindow() if self.ui.getViewProfile() != "debug": self.ui.setDebugProfile() self.viewmanager.setFileLine(fn, line) if not forStack: self.__getThreadList() self.__getClientVariables() self.debugActGrp.setEnabled(True) self.debugActGrp2.setEnabled(True) def __clientExit(self, status): """ Private method to handle the debugged program terminating. @param status exit code of the debugged program (int) """ self.viewmanager.exit() self.__resetUI() if not Preferences.getDebugger("SuppressClientExit") or status != 0: if self.ui.currentProg is None: E5MessageBox.information( self.ui, Program, self.tr('

The program has terminated with an exit' ' status of {0}.

').format(status)) else: E5MessageBox.information( self.ui, Program, self.tr('

{0} has terminated with an exit' ' status of {1}.

') .format(Utilities.normabspath(self.ui.currentProg), status)) else: if self.ui.notificationsEnabled(): if self.ui.currentProg is None: msg = self.tr('The program has terminated with an exit' ' status of {0}.').format(status) else: msg = self.tr('"{0}" has terminated with an exit' ' status of {1}.')\ .format(os.path.basename(self.ui.currentProg), status) self.ui.showNotification( UI.PixmapCache.getPixmap("debug48.png"), self.tr("Program terminated"), msg) else: if self.ui.currentProg is None: self.appendStdout.emit( self.tr('The program has terminated with an exit' ' status of {0}.\n').format(status)) else: self.appendStdout.emit( self.tr('"{0}" has terminated with an exit' ' status of {1}.\n') .format(Utilities.normabspath(self.ui.currentProg), status)) def __clientSyntaxError(self, message, filename, lineNo, characterNo): """ Private method to handle a syntax error in the debugged program. @param message message of the syntax error (string) @param filename translated filename of the syntax error position (string) @param lineNo line number of the syntax error position (integer) @param characterNo character number of the syntax error position (integer) """ self.__resetUI() self.ui.raise_() self.ui.activateWindow() if message is None: E5MessageBox.critical( self.ui, Program, self.tr( 'The program being debugged contains an unspecified' ' syntax error.')) return if not os.path.isabs(filename): if os.path.exists(os.path.join(self.project.getProjectPath(), filename)): filename = os.path.join(self.project.getProjectPath(), filename) else: ms = self.project.getMainScript(normalized=True) if ms is not None: d = os.path.dirname(ms) if os.path.exists(os.path.join(d, filename)): filename = os.path.join(d, filename) self.viewmanager.setFileLine(filename, lineNo, True, True) E5MessageBox.critical( self.ui, Program, self.tr('

The file {0} contains the syntax error' ' {1} at line {2}, character {3}.' '

') .format(filename, message, lineNo, characterNo)) def __clientException(self, exceptionType, exceptionMessage, stackTrace): """ Private method to handle an exception of the debugged program. @param exceptionType type of exception raised (string) @param exceptionMessage message given by the exception (string) @param stackTrace list of stack entries (list of string) """ self.ui.raise_() self.ui.activateWindow() QApplication.processEvents() if exceptionType is None: E5MessageBox.critical( self.ui, Program, self.tr('An unhandled exception occured.' ' See the shell window for details.')) return if (self.exceptions and exceptionType not in self.excIgnoreList and (not len(self.excList) or (len(self.excList) and exceptionType in self.excList)))\ or exceptionType.startswith('unhandled'): res = None if stackTrace: try: file, line = stackTrace[0][:2] source, encoding = Utilities.readEncodedFile(file) source = source.splitlines(True) if len(source) >= line and \ "__IGNORE_EXCEPTION__" in Utilities.extractLineFlags( source[line - 1]): res = E5MessageBox.No except (UnicodeError, IOError): pass if res != E5MessageBox.No: self.viewmanager.setFileLine( stackTrace[0][0], stackTrace[0][1], True) if res != E5MessageBox.No: if Preferences.getDebugger("BreakAlways"): res = E5MessageBox.Yes else: if stackTrace: if exceptionType.startswith('unhandled'): buttons = E5MessageBox.StandardButtons( E5MessageBox.No | E5MessageBox.Yes) else: buttons = E5MessageBox.StandardButtons( E5MessageBox.No | E5MessageBox.Yes | E5MessageBox.Ignore) res = E5MessageBox.critical( self.ui, Program, self.tr( '

The debugged program raised the exception' ' {0}
"{1}"
' 'File: {2}, Line: {3}

' '

Break here?

') .format( exceptionType, Utilities.html_encode(exceptionMessage), stackTrace[0][0], stackTrace[0][1]), buttons, E5MessageBox.No) else: res = E5MessageBox.critical( self.ui, Program, self.tr( '

The debugged program raised the exception' ' {0}
"{1}"

') .format( exceptionType, Utilities.html_encode(exceptionMessage))) if res == E5MessageBox.Yes: self.exceptionInterrupt.emit() stack = [] for fn, ln, func, args in stackTrace: stack.append((fn, ln, func, args)) self.clientStack.emit(stack) self.__getClientVariables() self.ui.setDebugProfile() self.debugActGrp.setEnabled(True) self.debugActGrp2.setEnabled(True) return elif res == E5MessageBox.Ignore: if exceptionType not in self.excIgnoreList: self.excIgnoreList.append(exceptionType) if self.lastAction != -1: if self.lastAction == 2: self.__specialContinue() else: self.debugActions[self.lastAction]() else: self.__continue() def __clientGone(self, unplanned): """ Private method to handle the disconnection of the debugger client. @param unplanned True if the client died, False otherwise """ self.__resetUI() if unplanned: E5MessageBox.information( self.ui, Program, self.tr('The program being debugged has terminated' ' unexpectedly.')) def __getThreadList(self): """ Private method to get the list of threads from the client. """ self.debugServer.remoteThreadList() def __clientThreadSet(self): """ Private method to handle a change of the client's current thread. """ self.debugServer.remoteClientVariables(0, self.localsVarFilter) def __getClientVariables(self): """ Private method to request the global and local variables. In the first step, the global variables are requested from the client. Once these have been received, the local variables are requested. This happens in the method '__clientVariables'. """ # get globals first self.debugServer.remoteClientVariables(1, self.globalsVarFilter) # the local variables are requested once we have received the globals def __clientVariables(self, scope, variables): """ Private method to write the clients variables to the user interface. @param scope scope of the variables (-1 = empty global, 1 = global, 0 = local) @param variables the list of variables from the client """ if scope > 0: self.debugViewer.showVariables(variables, True) if scope == 1: # now get the local variables self.debugServer.remoteClientVariables(0, self.localsVarFilter) elif scope == 0: self.debugViewer.showVariables(variables, False) elif scope == -1: vlist = [('None', '', '')] self.debugViewer.showVariables(vlist, False) def __clientVariable(self, scope, variables): """ Private method to write the contents of a clients classvariable to the user interface. @param scope scope of the variables (-1 = empty global, 1 = global, 0 = local) @param variables the list of members of a classvariable from the client """ if scope == 1: self.debugViewer.showVariable(variables, 1) elif scope == 0: self.debugViewer.showVariable(variables, 0) def __clientBreakConditionError(self, filename, lineno): """ Private method to handle a condition error of a breakpoint. @param filename filename of the breakpoint (string) @param lineno linenumber of the breakpoint (integer) """ E5MessageBox.critical( self.ui, self.tr("Breakpoint Condition Error"), self.tr( """

The condition of the breakpoint {0}, {1}""" """ contains a syntax error.

""") .format(filename, lineno)) model = self.debugServer.getBreakPointModel() index = model.getBreakPointIndex(filename, lineno) if not index.isValid(): return bp = model.getBreakPointByIndex(index) if not bp: return fn, line, cond, temp, enabled, count = bp[:6] from .EditBreakpointDialog import EditBreakpointDialog dlg = EditBreakpointDialog( (fn, line), (cond, temp, enabled, count), [], self.ui, modal=True) if dlg.exec_() == QDialog.Accepted: cond, temp, enabled, count = dlg.getData() model.setBreakPointByIndex(index, fn, line, (cond, temp, enabled, count)) def __clientWatchConditionError(self, cond): """ Private method to handle a expression error of a watch expression. Note: This can only happen for normal watch expressions @param cond expression of the watch expression (string) """ E5MessageBox.critical( self.ui, self.tr("Watch Expression Error"), self.tr("""

The watch expression {0}""" """ contains a syntax error.

""") .format(cond)) model = self.debugServer.getWatchPointModel() index = model.getWatchPointIndex(cond) if not index.isValid(): return wp = model.getWatchPointByIndex(index) if not wp: return cond, special, temp, enabled, count = wp[:5] from .EditWatchpointDialog import EditWatchpointDialog dlg = EditWatchpointDialog( (cond, temp, enabled, count, special), self) if dlg.exec_() == QDialog.Accepted: cond, temp, enabled, count, special = dlg.getData() # check for duplicates idx = self.__model.getWatchPointIndex(cond, special) duplicate = idx.isValid() and \ idx.internalPointer() != index.internalPointer() if duplicate: if not special: msg = self.tr("""

A watch expression '{0}'""" """ already exists.

""")\ .format(Utilities.html_encode(cond)) else: msg = self.tr( """

A watch expression '{0}'""" """ for the variable {1} already""" """ exists.

""")\ .format(special, Utilities.html_encode(cond)) E5MessageBox.warning( self.ui, self.tr("Watch expression already exists"), msg) model.deleteWatchPointByIndex(index) else: model.setWatchPointByIndex(index, cond, special, (temp, enabled, count)) def __configureVariablesFilters(self): """ Private slot for displaying the variables filter configuration dialog. """ from .VariablesFilterDialog import VariablesFilterDialog dlg = VariablesFilterDialog(self.ui, 'Filter Dialog', True) dlg.setSelection(self.localsVarFilter, self.globalsVarFilter) if dlg.exec_() == QDialog.Accepted: self.localsVarFilter, self.globalsVarFilter = dlg.getSelection() self.debugViewer.setVariablesFilter( self.globalsVarFilter, self.localsVarFilter) def __configureExceptionsFilter(self): """ Private slot for displaying the exception filter dialog. """ from .ExceptionsFilterDialog import ExceptionsFilterDialog dlg = ExceptionsFilterDialog(self.excList, ignore=False) if dlg.exec_() == QDialog.Accepted: self.excList = dlg.getExceptionsList()[:] # keep a copy def __configureIgnoredExceptions(self): """ Private slot for displaying the ignored exceptions dialog. """ from .ExceptionsFilterDialog import ExceptionsFilterDialog dlg = ExceptionsFilterDialog(self.excIgnoreList, ignore=True) if dlg.exec_() == QDialog.Accepted: self.excIgnoreList = dlg.getExceptionsList()[:] # keep a copy def __toggleBreakpoint(self): """ Private slot to handle the 'Set/Reset breakpoint' action. """ self.viewmanager.activeWindow().menuToggleBreakpoint() def __editBreakpoint(self): """ Private slot to handle the 'Edit breakpoint' action. """ self.viewmanager.activeWindow().menuEditBreakpoint() def __nextBreakpoint(self): """ Private slot to handle the 'Next breakpoint' action. """ self.viewmanager.activeWindow().menuNextBreakpoint() def __previousBreakpoint(self): """ Private slot to handle the 'Previous breakpoint' action. """ self.viewmanager.activeWindow().menuPreviousBreakpoint() def __clearBreakpoints(self): """ Private slot to handle the 'Clear breakpoints' action. """ self.debugServer.getBreakPointModel().deleteAll() def __showDebugMenu(self): """ Private method to set up the debug menu. """ bpCount = self.debugServer.getBreakPointModel().rowCount() self.menuBreakpointsAct.setEnabled(bpCount > 0) def __showBreakpointsMenu(self): """ Private method to handle the show breakpoints menu signal. """ self.breakpointsMenu.clear() model = self.debugServer.getBreakPointModel() for row in range(model.rowCount()): index = model.index(row, 0) filename, line, cond = model.getBreakPointByIndex(index)[:3] if not cond: formattedCond = "" else: formattedCond = " : {0}".format(cond[:20]) bpSuffix = " : {0:d}{1}".format(line, formattedCond) act = self.breakpointsMenu.addAction( "{0}{1}".format( Utilities.compactPath( filename, self.ui.maxMenuFilePathLen - len(bpSuffix)), bpSuffix)) act.setData([filename, line]) def __breakpointSelected(self, act): """ Private method to handle the breakpoint selected signal. @param act reference to the action that triggered (QAction) """ qvList = act.data() filename = qvList[0] line = qvList[1] self.viewmanager.openSourceFile(filename, line) def __compileChangedProjectFiles(self): """ Private method to signal compilation of changed forms and resources is wanted. """ if Preferences.getProject("AutoCompileForms"): self.compileForms.emit() if Preferences.getProject("AutoCompileResources"): self.compileResources.emit() QApplication.processEvents() def __coverageScript(self): """ Private slot to handle the coverage of script action. """ self.__doCoverage(False) def __coverageProject(self): """ Private slot to handle the coverage of project action. """ self.__compileChangedProjectFiles() self.__doCoverage(True) def __doCoverage(self, runProject): """ Private method to handle the coverage actions. @param runProject flag indicating coverage of the current project (True) or script (false) """ from .StartDialog import StartDialog self.__resetUI() doNotStart = False # Get the command line arguments, the working directory and the # exception reporting flag. if runProject: cap = self.tr("Coverage of Project") else: cap = self.tr("Coverage of Script") dlg = StartDialog( cap, self.argvHistory, self.wdHistory, self.envHistory, self.exceptions, self.ui, 2, autoClearShell=self.autoClearShell) if dlg.exec_() == QDialog.Accepted: argv, wd, env, exceptions, clearShell, clearHistories, console = \ dlg.getData() eraseCoverage = dlg.getCoverageData() if runProject: fn = self.project.getMainScript(True) if fn is None: E5MessageBox.critical( self.ui, self.tr("Coverage of Project"), self.tr( "There is no main script defined for the" " current project. Aborting")) return if Preferences.getDebugger("Autosave") and \ not self.project.saveAllScripts(reportSyntaxErrors=True): doNotStart = True # save the info for later use self.project.setDbgInfo( argv, wd, env, exceptions, self.excList, self.excIgnoreList, clearShell) self.lastStartAction = 6 self.clientType = self.project.getProjectLanguage() else: editor = self.viewmanager.activeWindow() if editor is None: return if not self.viewmanager.checkDirty( editor, Preferences.getDebugger("Autosave")) or \ editor.getFileName() is None: return fn = editor.getFileName() self.lastStartAction = 5 self.clientType = editor.determineFileType() # save the filename for use by the restart method self.lastDebuggedFile = fn self.restartAct.setEnabled(True) # This moves any previous occurrence of these arguments to the head # of the list. self.setArgvHistory(argv, clearHistories) self.setWdHistory(wd, clearHistories) self.setEnvHistory(env, clearHistories) # Save the exception flags self.exceptions = exceptions # Save the erase coverage flag self.eraseCoverage = eraseCoverage # Save the clear interpreter flag self.autoClearShell = clearShell # Save the run in console flag self.runInConsole = console # Hide all error highlights self.viewmanager.unhighlight() if not doNotStart: if runProject and self.project.getProjectType() in [ "E4Plugin", "E6Plugin"]: argv = '--plugin="{0}" {1}'.format(fn, argv) fn = os.path.join(getConfig('ericDir'), "eric6.py") self.debugViewer.initCallStackViewer(runProject) # Ask the client to open the new program. self.debugServer.remoteCoverage( fn, argv, wd, env, autoClearShell=self.autoClearShell, erase=eraseCoverage, forProject=runProject, runInConsole=console, clientType=self.clientType) self.stopAct.setEnabled(True) def __profileScript(self): """ Private slot to handle the profile script action. """ self.__doProfile(False) def __profileProject(self): """ Private slot to handle the profile project action. """ self.__compileChangedProjectFiles() self.__doProfile(True) def __doProfile(self, runProject): """ Private method to handle the profile actions. @param runProject flag indicating profiling of the current project (True) or script (False) """ from .StartDialog import StartDialog self.__resetUI() doNotStart = False # Get the command line arguments, the working directory and the # exception reporting flag. if runProject: cap = self.tr("Profile of Project") else: cap = self.tr("Profile of Script") dlg = StartDialog( cap, self.argvHistory, self.wdHistory, self.envHistory, self.exceptions, self.ui, 3, autoClearShell=self.autoClearShell) if dlg.exec_() == QDialog.Accepted: argv, wd, env, exceptions, clearShell, clearHistories, console = \ dlg.getData() eraseTimings = dlg.getProfilingData() if runProject: fn = self.project.getMainScript(True) if fn is None: E5MessageBox.critical( self.ui, self.tr("Profile of Project"), self.tr( "There is no main script defined for the" " current project. Aborting")) return if Preferences.getDebugger("Autosave") and \ not self.project.saveAllScripts(reportSyntaxErrors=True): doNotStart = True # save the info for later use self.project.setDbgInfo( argv, wd, env, exceptions, self.excList, self.excIgnoreList, clearShell) self.lastStartAction = 8 self.clientType = self.project.getProjectLanguage() else: editor = self.viewmanager.activeWindow() if editor is None: return if not self.viewmanager.checkDirty( editor, Preferences.getDebugger("Autosave")) or \ editor.getFileName() is None: return fn = editor.getFileName() self.lastStartAction = 7 self.clientType = editor.determineFileType() # save the filename for use by the restart method self.lastDebuggedFile = fn self.restartAct.setEnabled(True) # This moves any previous occurrence of these arguments to the head # of the list. self.setArgvHistory(argv, clearHistories) self.setWdHistory(wd, clearHistories) self.setEnvHistory(env, clearHistories) # Save the exception flags self.exceptions = exceptions # Save the erase timing flag self.eraseTimings = eraseTimings # Save the clear interpreter flag self.autoClearShell = clearShell # Save the run in console flag self.runInConsole = console # Hide all error highlights self.viewmanager.unhighlight() if not doNotStart: if runProject and self.project.getProjectType() in [ "E4Plugin", "E6Plugin"]: argv = '--plugin="{0}" {1}'.format(fn, argv) fn = os.path.join(getConfig('ericDir'), "eric6.py") self.debugViewer.initCallStackViewer(runProject) # Ask the client to open the new program. self.debugServer.remoteProfile( fn, argv, wd, env, autoClearShell=self.autoClearShell, erase=eraseTimings, forProject=runProject, runInConsole=console, clientType=self.clientType) self.stopAct.setEnabled(True) def __runScript(self): """ Private slot to handle the run script action. """ self.__doRun(False) def __runProject(self): """ Private slot to handle the run project action. """ self.__compileChangedProjectFiles() self.__doRun(True) def __doRun(self, runProject): """ Private method to handle the run actions. @param runProject flag indicating running the current project (True) or script (False) """ from .StartDialog import StartDialog self.__resetUI() doNotStart = False # Get the command line arguments, the working directory and the # exception reporting flag. if runProject: cap = self.tr("Run Project") else: cap = self.tr("Run Script") dlg = StartDialog( cap, self.argvHistory, self.wdHistory, self.envHistory, self.exceptions, self.ui, 1, autoClearShell=self.autoClearShell, autoFork=self.forkAutomatically, forkChild=self.forkIntoChild) if dlg.exec_() == QDialog.Accepted: argv, wd, env, exceptions, clearShell, clearHistories, console = \ dlg.getData() forkAutomatically, forkIntoChild = dlg.getRunData() if runProject: fn = self.project.getMainScript(True) if fn is None: E5MessageBox.critical( self.ui, self.tr("Run Project"), self.tr( "There is no main script defined for the" " current project. Aborting")) return if Preferences.getDebugger("Autosave") and \ not self.project.saveAllScripts(reportSyntaxErrors=True): doNotStart = True # save the info for later use self.project.setDbgInfo( argv, wd, env, exceptions, self.excList, self.excIgnoreList, clearShell) self.lastStartAction = 4 self.clientType = self.project.getProjectLanguage() else: editor = self.viewmanager.activeWindow() if editor is None: return if not self.viewmanager.checkDirty( editor, Preferences.getDebugger("Autosave")) or \ editor.getFileName() is None: return fn = editor.getFileName() self.lastStartAction = 3 self.clientType = editor.determineFileType() # save the filename for use by the restart method self.lastDebuggedFile = fn self.restartAct.setEnabled(True) # This moves any previous occurrence of these arguments to the head # of the list. self.setArgvHistory(argv, clearHistories) self.setWdHistory(wd, clearHistories) self.setEnvHistory(env, clearHistories) # Save the exception flags self.exceptions = exceptions # Save the clear interpreter flag self.autoClearShell = clearShell # Save the run in console flag self.runInConsole = console # Save the forking flags self.forkAutomatically = forkAutomatically self.forkIntoChild = forkIntoChild # Hide all error highlights self.viewmanager.unhighlight() if not doNotStart: if runProject and self.project.getProjectType() in [ "E4Plugin", "E6Plugin"]: argv = '--plugin="{0}" {1}'.format(fn, argv) fn = os.path.join(getConfig('ericDir'), "eric6.py") self.debugViewer.initCallStackViewer(runProject) # Ask the client to open the new program. self.debugServer.remoteRun( fn, argv, wd, env, autoClearShell=self.autoClearShell, forProject=runProject, runInConsole=console, autoFork=forkAutomatically, forkChild=forkIntoChild, clientType=self.clientType) self.stopAct.setEnabled(True) def __debugScript(self): """ Private slot to handle the debug script action. """ self.__doDebug(False) def __debugProject(self): """ Private slot to handle the debug project action. """ self.__compileChangedProjectFiles() self.__doDebug(True) def __doDebug(self, debugProject): """ Private method to handle the debug actions. @param debugProject flag indicating debugging the current project (True) or script (False) """ from .StartDialog import StartDialog self.__resetUI() doNotStart = False # Get the command line arguments, the working directory and the # exception reporting flag. if debugProject: cap = self.tr("Debug Project") else: cap = self.tr("Debug Script") dlg = StartDialog( cap, self.argvHistory, self.wdHistory, self.envHistory, self.exceptions, self.ui, 0, tracePython=self.tracePython, autoClearShell=self.autoClearShell, autoContinue=self.autoContinue, autoFork=self.forkAutomatically, forkChild=self.forkIntoChild) if dlg.exec_() == QDialog.Accepted: argv, wd, env, exceptions, clearShell, clearHistories, console = \ dlg.getData() tracePython, autoContinue, forkAutomatically, forkIntoChild = \ dlg.getDebugData() if debugProject: fn = self.project.getMainScript(True) if fn is None: E5MessageBox.critical( self.ui, self.tr("Debug Project"), self.tr( "There is no main script defined for the" " current project. No debugging possible.")) return if Preferences.getDebugger("Autosave") and \ not self.project.saveAllScripts(reportSyntaxErrors=True): doNotStart = True # save the info for later use self.project.setDbgInfo( argv, wd, env, exceptions, self.excList, self.excIgnoreList, clearShell, tracePython=tracePython, autoContinue=self.autoContinue) self.lastStartAction = 2 self.clientType = self.project.getProjectLanguage() else: editor = self.viewmanager.activeWindow() if editor is None: return if not self.viewmanager.checkDirty( editor, Preferences.getDebugger("Autosave")) or \ editor.getFileName() is None: return fn = editor.getFileName() self.lastStartAction = 1 self.clientType = editor.determineFileType() # save the filename for use by the restart method self.lastDebuggedFile = fn self.restartAct.setEnabled(True) # This moves any previous occurrence of these arguments to the head # of the list. self.setArgvHistory(argv, clearHistories) self.setWdHistory(wd, clearHistories) self.setEnvHistory(env, clearHistories) # Save the exception flags self.exceptions = exceptions # Save the tracePython flag self.tracePython = tracePython # Save the clear interpreter flag self.autoClearShell = clearShell # Save the run in console flag self.runInConsole = console # Save the auto continue flag self.autoContinue = autoContinue # Save the forking flags self.forkAutomatically = forkAutomatically self.forkIntoChild = forkIntoChild # Hide all error highlights self.viewmanager.unhighlight() if not doNotStart: if debugProject and self.project.getProjectType() in [ "E4Plugin", "E6Plugin"]: argv = '--plugin="{0}" {1}'.format(fn, argv) fn = os.path.join(getConfig('ericDir'), "eric6.py") tracePython = True # override flag because it must be true self.debugViewer.initCallStackViewer(debugProject) # Ask the client to send call trace info enableCallTrace = self.debugViewer.isCallTraceEnabled() self.debugViewer.clearCallTrace() self.debugViewer.setCallTraceToProjectMode(debugProject) # Ask the client to open the new program. self.debugServer.remoteLoad( fn, argv, wd, env, autoClearShell=self.autoClearShell, tracePython=tracePython, autoContinue=autoContinue, forProject=debugProject, runInConsole=console, autoFork=forkAutomatically, forkChild=forkIntoChild, clientType=self.clientType, enableCallTrace=enableCallTrace) # Signal that we have started a debugging session self.debuggingStarted.emit(fn) self.stopAct.setEnabled(True) def __doRestart(self): """ Private slot to handle the restart action to restart the last debugged file. """ self.__resetUI() doNotStart = False # first save any changes if self.lastStartAction in [1, 3, 5, 7, 9]: editor = self.viewmanager.getOpenEditor(self.lastDebuggedFile) if editor and \ not self.viewmanager.checkDirty( editor, Preferences.getDebugger("Autosave")): return forProject = False elif self.lastStartAction in [2, 4, 6, 8, 10]: if Preferences.getDebugger("Autosave") and \ not self.project.saveAllScripts(reportSyntaxErrors=True): doNotStart = True self.__compileChangedProjectFiles() forProject = True else: return # should not happen # get the saved stuff wd = self.wdHistory[0] argv = self.argvHistory[0] fn = self.lastDebuggedFile env = self.envHistory[0] # Hide all error highlights self.viewmanager.unhighlight() if not doNotStart: if forProject and self.project.getProjectType() in [ "E4Plugin", "E6Plugin"]: argv = '--plugin="{0}" {1}'.format(fn, argv) fn = os.path.join(getConfig('ericDir'), "eric6.py") self.debugViewer.initCallStackViewer(forProject) if self.lastStartAction in [1, 2]: # Ask the client to send call trace info enableCallTrace = self.debugViewer.isCallTraceEnabled() self.debugViewer.clearCallTrace() self.debugViewer.setCallTraceToProjectMode(forProject) # Ask the client to debug the new program. self.debugServer.remoteLoad( fn, argv, wd, env, autoClearShell=self.autoClearShell, tracePython=self.tracePython, autoContinue=self.autoContinue, forProject=forProject, runInConsole=self.runInConsole, autoFork=self.forkAutomatically, forkChild=self.forkIntoChild, clientType=self.clientType, enableCallTrace=enableCallTrace) # Signal that we have started a debugging session self.debuggingStarted.emit(fn) elif self.lastStartAction in [3, 4]: # Ask the client to run the new program. self.debugServer.remoteRun( fn, argv, wd, env, autoClearShell=self.autoClearShell, forProject=forProject, runInConsole=self.runInConsole, autoFork=self.forkAutomatically, forkChild=self.forkIntoChild, clientType=self.clientType) elif self.lastStartAction in [5, 6]: # Ask the client to coverage run the new program. self.debugServer.remoteCoverage( fn, argv, wd, env, autoClearShell=self.autoClearShell, erase=self.eraseCoverage, forProject=forProject, runInConsole=self.runInConsole, clientType=self.clientType) elif self.lastStartAction in [7, 8]: # Ask the client to profile run the new program. self.debugServer.remoteProfile( fn, argv, wd, env, autoClearShell=self.autoClearShell, erase=self.eraseTimings, forProject=forProject, runInConsole=self.runInConsole, clientType=self.clientType) self.stopAct.setEnabled(True) def __stopScript(self): """ Private slot to stop the running script. """ self.debugServer.startClient(False) def __passiveDebugStarted(self, fn, exc): """ Private slot to handle a passive debug session start. @param fn filename of the debugged script @param exc flag to enable exception reporting of the IDE (boolean) """ # Hide all error highlights self.viewmanager.unhighlight() # Set filename of script being debugged self.ui.currentProg = fn # Set exception reporting self.setExceptionReporting(exc) # Signal that we have started a debugging session self.debuggingStarted.emit(fn) # Initialize the call stack viewer self.debugViewer.initCallStackViewer(False) def __continue(self): """ Private method to handle the Continue action. """ self.lastAction = 0 self.__enterRemote() self.debugServer.remoteContinue() def __specialContinue(self): """ Private method to handle the Special Continue action. """ self.lastAction = 2 self.__enterRemote() self.debugServer.remoteContinue(1) def __step(self): """ Private method to handle the Step action. """ self.lastAction = 1 self.__enterRemote() self.debugServer.remoteStep() def __stepOver(self): """ Private method to handle the Step Over action. """ self.lastAction = 2 self.__enterRemote() self.debugServer.remoteStepOver() def __stepOut(self): """ Private method to handle the Step Out action. """ self.lastAction = 3 self.__enterRemote() self.debugServer.remoteStepOut() def __stepQuit(self): """ Private method to handle the Step Quit action. """ self.lastAction = 4 self.__enterRemote() self.debugServer.remoteStepQuit() self.__resetUI() def __runToCursor(self): """ Private method to handle the Run to Cursor action. """ self.lastAction = 0 aw = self.viewmanager.activeWindow() line = aw.getCursorPosition()[0] + 1 self.__enterRemote() self.debugServer.remoteBreakpoint( aw.getFileName(), line, 1, None, 1) self.debugServer.remoteContinue() def __eval(self): """ Private method to handle the Eval action. """ # Get the command line arguments. if len(self.evalHistory) > 0: curr = 0 else: curr = -1 arg, ok = QInputDialog.getItem( self.ui, self.tr("Evaluate"), self.tr("Enter the statement to evaluate"), self.evalHistory, curr, True) if ok: if not arg: return # This moves any previous occurrence of this expression to the head # of the list. if arg in self.evalHistory: self.evalHistory.remove(arg) self.evalHistory.insert(0, arg) self.debugServer.remoteEval(arg) def __exec(self): """ Private method to handle the Exec action. """ # Get the command line arguments. if len(self.execHistory) > 0: curr = 0 else: curr = -1 stmt, ok = QInputDialog.getItem( self.ui, self.tr("Execute"), self.tr("Enter the statement to execute"), self.execHistory, curr, True) if ok: if not stmt: return # This moves any previous occurrence of this statement to the head # of the list. if stmt in self.execHistory: self.execHistory.remove(stmt) self.execHistory.insert(0, stmt) self.debugServer.remoteExec(stmt) def __enterRemote(self): """ Private method to update the user interface. This method is called just prior to executing some of the program being debugged. """ # Disable further debug commands from the user. self.debugActGrp.setEnabled(False) self.debugActGrp2.setEnabled(False) self.viewmanager.unhighlight(True) def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ return self.actions[:] eric-6.0.8/eric/Debugger/BreakPointViewer.py0000644000175000017500000003760012451233373017774 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the Breakpoint viewer widget. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, qVersion, QItemSelectionModel, \ QSortFilterProxyModel from PyQt5.QtWidgets import QTreeView, QAbstractItemView, QHeaderView, QMenu, \ QDialog from E5Gui.E5Application import e5App class BreakPointViewer(QTreeView): """ Class implementing the Breakpoint viewer widget. Breakpoints will be shown with all their details. They can be modified through the context menu of this widget. @signal sourceFile(str, int) emitted to show the source of a breakpoint """ sourceFile = pyqtSignal(str, int) def __init__(self, parent=None): """ Constructor @param parent the parent (QWidget) """ super(BreakPointViewer, self).__init__(parent) self.setObjectName("BreakPointViewer") self.__model = None self.setItemsExpandable(False) self.setRootIsDecorated(False) self.setAlternatingRowColors(True) self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setWindowTitle(self.tr("Breakpoints")) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.doubleClicked.connect(self.__doubleClicked) self.__createPopupMenus() self.condHistory = [] self.fnHistory = [] self.fnHistory.append('') def setModel(self, model): """ Public slot to set the breakpoint model. @param model reference to the breakpoint model (BreakPointModel) """ self.__model = model self.sortingModel = QSortFilterProxyModel() self.sortingModel.setDynamicSortFilter(True) self.sortingModel.setSourceModel(self.__model) super(BreakPointViewer, self).setModel(self.sortingModel) header = self.header() header.setSortIndicator(0, Qt.AscendingOrder) header.setSortIndicatorShown(True) if qVersion() >= "5.0.0": header.setSectionsClickable(True) else: header.setClickable(True) self.setSortingEnabled(True) self.__layoutDisplay() def __layoutDisplay(self): """ Private slot to perform a layout operation. """ self.__resizeColumns() self.__resort() def __resizeColumns(self): """ Private slot to resize the view when items get added, edited or deleted. """ self.header().resizeSections(QHeaderView.ResizeToContents) self.header().setStretchLastSection(True) def __resort(self): """ Private slot to resort the tree. """ self.model().sort(self.header().sortIndicatorSection(), self.header().sortIndicatorOrder()) def __toSourceIndex(self, index): """ Private slot to convert an index to a source index. @param index index to be converted (QModelIndex) @return mapped index (QModelIndex) """ return self.sortingModel.mapToSource(index) def __fromSourceIndex(self, sindex): """ Private slot to convert a source index to an index. @param sindex source index to be converted (QModelIndex) @return mapped index (QModelIndex) """ return self.sortingModel.mapFromSource(sindex) def __setRowSelected(self, index, selected=True): """ Private slot to select a complete row. @param index index determining the row to be selected (QModelIndex) @param selected flag indicating the action (bool) """ if not index.isValid(): return if selected: flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) else: flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.Deselect | QItemSelectionModel.Rows) self.selectionModel().select(index, flags) def __createPopupMenus(self): """ Private method to generate the popup menus. """ self.menu = QMenu() self.menu.addAction(self.tr("Add"), self.__addBreak) self.menu.addAction(self.tr("Edit..."), self.__editBreak) self.menu.addSeparator() self.menu.addAction(self.tr("Enable"), self.__enableBreak) self.menu.addAction(self.tr("Enable all"), self.__enableAllBreaks) self.menu.addSeparator() self.menu.addAction(self.tr("Disable"), self.__disableBreak) self.menu.addAction(self.tr("Disable all"), self.__disableAllBreaks) self.menu.addSeparator() self.menu.addAction(self.tr("Delete"), self.__deleteBreak) self.menu.addAction(self.tr("Delete all"), self.__deleteAllBreaks) self.menu.addSeparator() self.menu.addAction(self.tr("Goto"), self.__showSource) self.menu.addSeparator() self.menu.addAction(self.tr("Configure..."), self.__configure) self.backMenuActions = {} self.backMenu = QMenu() self.backMenu.addAction(self.tr("Add"), self.__addBreak) self.backMenuActions["EnableAll"] = \ self.backMenu.addAction(self.tr("Enable all"), self.__enableAllBreaks) self.backMenuActions["DisableAll"] = \ self.backMenu.addAction(self.tr("Disable all"), self.__disableAllBreaks) self.backMenuActions["DeleteAll"] = \ self.backMenu.addAction(self.tr("Delete all"), self.__deleteAllBreaks) self.backMenu.aboutToShow.connect(self.__showBackMenu) self.backMenu.addSeparator() self.backMenu.addAction(self.tr("Configure..."), self.__configure) self.multiMenu = QMenu() self.multiMenu.addAction(self.tr("Add"), self.__addBreak) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Enable selected"), self.__enableSelectedBreaks) self.multiMenu.addAction(self.tr("Enable all"), self.__enableAllBreaks) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Disable selected"), self.__disableSelectedBreaks) self.multiMenu.addAction(self.tr("Disable all"), self.__disableAllBreaks) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Delete selected"), self.__deleteSelectedBreaks) self.multiMenu.addAction(self.tr("Delete all"), self.__deleteAllBreaks) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Configure..."), self.__configure) def __showContextMenu(self, coord): """ Private slot to show the context menu. @param coord the position of the mouse pointer (QPoint) """ cnt = self.__getSelectedItemsCount() if cnt <= 1: index = self.indexAt(coord) if index.isValid(): cnt = 1 self.__setRowSelected(index) coord = self.mapToGlobal(coord) if cnt > 1: self.multiMenu.popup(coord) elif cnt == 1: self.menu.popup(coord) else: self.backMenu.popup(coord) def __clearSelection(self): """ Private slot to clear the selection. """ for index in self.selectedIndexes(): self.__setRowSelected(index, False) def __addBreak(self): """ Private slot to handle the add breakpoint context menu entry. """ from .EditBreakpointDialog import EditBreakpointDialog dlg = EditBreakpointDialog((self.fnHistory[0], None), None, self.condHistory, self, modal=1, addMode=1, filenameHistory=self.fnHistory) if dlg.exec_() == QDialog.Accepted: fn, line, cond, temp, enabled, count = dlg.getAddData() if fn is not None: if fn in self.fnHistory: self.fnHistory.remove(fn) self.fnHistory.insert(0, fn) if cond: if cond in self.condHistory: self.condHistory.remove(cond) self.condHistory.insert(0, cond) self.__model.addBreakPoint(fn, line, (cond, temp, enabled, count)) self.__resizeColumns() self.__resort() def __doubleClicked(self, index): """ Private slot to handle the double clicked signal. @param index index of the entry that was double clicked (QModelIndex) """ if index.isValid(): self.__editBreakpoint(index) def __editBreak(self): """ Private slot to handle the edit breakpoint context menu entry. """ index = self.currentIndex() if index.isValid(): self.__editBreakpoint(index) def __editBreakpoint(self, index): """ Private slot to edit a breakpoint. @param index index of breakpoint to be edited (QModelIndex) """ sindex = self.__toSourceIndex(index) if sindex.isValid(): bp = self.__model.getBreakPointByIndex(sindex) if not bp: return fn, line, cond, temp, enabled, count = bp[:6] from .EditBreakpointDialog import EditBreakpointDialog dlg = EditBreakpointDialog( (fn, line), (cond, temp, enabled, count), self.condHistory, self, modal=True) if dlg.exec_() == QDialog.Accepted: cond, temp, enabled, count = dlg.getData() if cond: if cond in self.condHistory: self.condHistory.remove(cond) self.condHistory.insert(0, cond) self.__model.setBreakPointByIndex( sindex, fn, line, (cond, temp, enabled, count)) self.__resizeColumns() self.__resort() def __setBpEnabled(self, index, enabled): """ Private method to set the enabled status of a breakpoint. @param index index of breakpoint to be enabled/disabled (QModelIndex) @param enabled flag indicating the enabled status to be set (boolean) """ sindex = self.__toSourceIndex(index) if sindex.isValid(): self.__model.setBreakPointEnabledByIndex(sindex, enabled) def __enableBreak(self): """ Private slot to handle the enable breakpoint context menu entry. """ index = self.currentIndex() self.__setBpEnabled(index, True) self.__resizeColumns() self.__resort() def __enableAllBreaks(self): """ Private slot to handle the enable all breakpoints context menu entry. """ index = self.model().index(0, 0) while index.isValid(): self.__setBpEnabled(index, True) index = self.indexBelow(index) self.__resizeColumns() self.__resort() def __enableSelectedBreaks(self): """ Private slot to handle the enable selected breakpoints context menu entry. """ for index in self.selectedIndexes(): if index.column() == 0: self.__setBpEnabled(index, True) self.__resizeColumns() self.__resort() def __disableBreak(self): """ Private slot to handle the disable breakpoint context menu entry. """ index = self.currentIndex() self.__setBpEnabled(index, False) self.__resizeColumns() self.__resort() def __disableAllBreaks(self): """ Private slot to handle the disable all breakpoints context menu entry. """ index = self.model().index(0, 0) while index.isValid(): self.__setBpEnabled(index, False) index = self.indexBelow(index) self.__resizeColumns() self.__resort() def __disableSelectedBreaks(self): """ Private slot to handle the disable selected breakpoints context menu entry. """ for index in self.selectedIndexes(): if index.column() == 0: self.__setBpEnabled(index, False) self.__resizeColumns() self.__resort() def __deleteBreak(self): """ Private slot to handle the delete breakpoint context menu entry. """ index = self.currentIndex() sindex = self.__toSourceIndex(index) if sindex.isValid(): self.__model.deleteBreakPointByIndex(sindex) def __deleteAllBreaks(self): """ Private slot to handle the delete all breakpoints context menu entry. """ self.__model.deleteAll() def __deleteSelectedBreaks(self): """ Private slot to handle the delete selected breakpoints context menu entry. """ idxList = [] for index in self.selectedIndexes(): sindex = self.__toSourceIndex(index) if sindex.isValid() and index.column() == 0: idxList.append(sindex) self.__model.deleteBreakPoints(idxList) def __showSource(self): """ Private slot to handle the goto context menu entry. """ index = self.currentIndex() sindex = self.__toSourceIndex(index) bp = self.__model.getBreakPointByIndex(sindex) if not bp: return fn, line = bp[:2] self.sourceFile.emit(fn, line) def highlightBreakpoint(self, fn, lineno): """ Public slot to handle the clientLine signal. @param fn filename of the breakpoint (string) @param lineno line number of the breakpoint (integer) """ sindex = self.__model.getBreakPointIndex(fn, lineno) if sindex.isValid(): return index = self.__fromSourceIndex(sindex) if index.isValid(): self.__clearSelection() self.__setRowSelected(index, True) def handleResetUI(self): """ Public slot to reset the breakpoint viewer. """ self.__clearSelection() def __showBackMenu(self): """ Private slot to handle the aboutToShow signal of the background menu. """ if self.model().rowCount() == 0: self.backMenuActions["EnableAll"].setEnabled(False) self.backMenuActions["DisableAll"].setEnabled(False) self.backMenuActions["DeleteAll"].setEnabled(False) else: self.backMenuActions["EnableAll"].setEnabled(True) self.backMenuActions["DisableAll"].setEnabled(True) self.backMenuActions["DeleteAll"].setEnabled(True) def __getSelectedItemsCount(self): """ Private method to get the count of items selected. @return count of items selected (integer) """ count = len(self.selectedIndexes()) // (self.__model.columnCount() - 1) # column count is 1 greater than selectable return count def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences( "debuggerGeneralPage") eric-6.0.8/eric/Debugger/StartProfileDialog.ui0000644000175000017500000002144112354033132020264 0ustar piotrpiotr StartProfileDialog 0 0 488 196 Start profiling true Command&line: cmdlineCombo 0 0 Enter the commandline parameters <b>Commandline</b> <p>Enter the commandline parameters in this field.</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false &Working directory: workdirCombo 0 0 Enter the working directory <b>Working directory</b> <p>Enter the working directory of the application to be debugged. Leave it empty to set the working directory to the executable directory.</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false &Environment: environmentCombo 0 0 Enter the environment variables to be set. <b>Environment</b> <p>Enter the environment variables to be set for the program. The individual settings must be separated by whitespace and be given in the form 'var=value'. In order to add to an environment variable, enter it in the form 'var+=value'.</p> <p>Example: var1=1 var2="hello world" var3+=":/tmp"</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false Uncheck to disable exception reporting <b>Report exceptions</b> <p>Uncheck this in order to disable exception reporting.</p> Report &exceptions Alt+E true Select to clear the display of the interpreter window <b>Clear interpreter window</b><p>This clears the display of the interpreter window before starting the debug client.</p> Clear &interpreter window true Select to start the debugger in a console window <b>Start in console</b> <p>Select to start the debugger in a console window. The console command has to be configured on the Debugger-&gt;General page</p> Start in console Select this to erase the collected timing data <b>Erase timing data</b> <p>Select this to erase the collected timing data before the next profiling run.</p> Erase &timing data Alt+C Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Select directory using a directory selection dialog <b>Select directory</b> <p>Select the working directory via a directory selection dialog.</p> qPixmapFromMimeSource cmdlineCombo workdirCombo dirButton environmentCombo exceptionCheckBox clearShellCheckBox consoleCheckBox eraseCheckBox buttonBox buttonBox accepted() StartProfileDialog accept() 20 150 23 173 buttonBox rejected() StartProfileDialog reject() 116 154 116 171 eric-6.0.8/eric/Debugger/WatchPointViewer.py0000644000175000017500000003751712451233373020025 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the watch expression viewer widget. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QModelIndex, qVersion, QItemSelectionModel, \ QSortFilterProxyModel from PyQt5.QtWidgets import QTreeView, QAbstractItemView, QMenu, QHeaderView, \ QDialog from E5Gui.E5Application import e5App from E5Gui import E5MessageBox import Utilities class WatchPointViewer(QTreeView): """ Class implementing the watch expression viewer widget. Watch expressions will be shown with all their details. They can be modified through the context menu of this widget. """ def __init__(self, parent=None): """ Constructor @param parent the parent (QWidget) """ super(WatchPointViewer, self).__init__(parent) self.setObjectName("WatchExpressionViewer") self.__model = None self.setItemsExpandable(False) self.setRootIsDecorated(False) self.setAlternatingRowColors(True) self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setWindowTitle(self.tr("Watchpoints")) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.doubleClicked.connect(self.__doubleClicked) self.__createPopupMenus() def setModel(self, model): """ Public slot to set the watch expression model. @param model reference to the watch expression model (WatchPointModel) """ self.__model = model self.sortingModel = QSortFilterProxyModel() self.sortingModel.setDynamicSortFilter(True) self.sortingModel.setSourceModel(self.__model) super(WatchPointViewer, self).setModel(self.sortingModel) header = self.header() header.setSortIndicator(0, Qt.AscendingOrder) header.setSortIndicatorShown(True) if qVersion() >= "5.0.0": header.setSectionsClickable(True) else: header.setClickable(True) self.setSortingEnabled(True) self.__layoutDisplay() def __layoutDisplay(self): """ Private slot to perform a layout operation. """ self.__resizeColumns() self.__resort() def __resizeColumns(self): """ Private slot to resize the view when items get added, edited or deleted. """ self.header().resizeSections(QHeaderView.ResizeToContents) self.header().setStretchLastSection(True) def __resort(self): """ Private slot to resort the tree. """ self.model().sort(self.header().sortIndicatorSection(), self.header().sortIndicatorOrder()) def __toSourceIndex(self, index): """ Private slot to convert an index to a source index. @param index index to be converted (QModelIndex) @return mapped index (QModelIndex) """ return self.sortingModel.mapToSource(index) def __fromSourceIndex(self, sindex): """ Private slot to convert a source index to an index. @param sindex source index to be converted (QModelIndex) @return mapped index (QModelIndex) """ return self.sortingModel.mapFromSource(sindex) def __setRowSelected(self, index, selected=True): """ Private slot to select a complete row. @param index index determining the row to be selected (QModelIndex) @param selected flag indicating the action (bool) """ if not index.isValid(): return if selected: flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) else: flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.Deselect | QItemSelectionModel.Rows) self.selectionModel().select(index, flags) def __createPopupMenus(self): """ Private method to generate the popup menus. """ self.menu = QMenu() self.menu.addAction(self.tr("Add"), self.__addWatchPoint) self.menu.addAction(self.tr("Edit..."), self.__editWatchPoint) self.menu.addSeparator() self.menu.addAction(self.tr("Enable"), self.__enableWatchPoint) self.menu.addAction(self.tr("Enable all"), self.__enableAllWatchPoints) self.menu.addSeparator() self.menu.addAction(self.tr("Disable"), self.__disableWatchPoint) self.menu.addAction(self.tr("Disable all"), self.__disableAllWatchPoints) self.menu.addSeparator() self.menu.addAction(self.tr("Delete"), self.__deleteWatchPoint) self.menu.addAction(self.tr("Delete all"), self.__deleteAllWatchPoints) self.menu.addSeparator() self.menu.addAction(self.tr("Configure..."), self.__configure) self.backMenuActions = {} self.backMenu = QMenu() self.backMenu.addAction(self.tr("Add"), self.__addWatchPoint) self.backMenuActions["EnableAll"] = \ self.backMenu.addAction(self.tr("Enable all"), self.__enableAllWatchPoints) self.backMenuActions["DisableAll"] = \ self.backMenu.addAction(self.tr("Disable all"), self.__disableAllWatchPoints) self.backMenuActions["DeleteAll"] = \ self.backMenu.addAction(self.tr("Delete all"), self.__deleteAllWatchPoints) self.backMenu.addSeparator() self.backMenu.addAction(self.tr("Configure..."), self.__configure) self.backMenu.aboutToShow.connect(self.__showBackMenu) self.multiMenu = QMenu() self.multiMenu.addAction(self.tr("Add"), self.__addWatchPoint) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Enable selected"), self.__enableSelectedWatchPoints) self.multiMenu.addAction(self.tr("Enable all"), self.__enableAllWatchPoints) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Disable selected"), self.__disableSelectedWatchPoints) self.multiMenu.addAction(self.tr("Disable all"), self.__disableAllWatchPoints) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Delete selected"), self.__deleteSelectedWatchPoints) self.multiMenu.addAction(self.tr("Delete all"), self.__deleteAllWatchPoints) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Configure..."), self.__configure) def __showContextMenu(self, coord): """ Private slot to show the context menu. @param coord the position of the mouse pointer (QPoint) """ cnt = self.__getSelectedItemsCount() if cnt <= 1: index = self.indexAt(coord) if index.isValid(): cnt = 1 self.__setRowSelected(index) coord = self.mapToGlobal(coord) if cnt > 1: self.multiMenu.popup(coord) elif cnt == 1: self.menu.popup(coord) else: self.backMenu.popup(coord) def __clearSelection(self): """ Private slot to clear the selection. """ for index in self.selectedIndexes(): self.__setRowSelected(index, False) def __findDuplicates(self, cond, special, showMessage=False, index=QModelIndex()): """ Private method to check, if an entry already exists. @param cond condition to check (string) @param special special condition to check (string) @param showMessage flag indicating a message should be shown, if a duplicate entry is found (boolean) @param index index that should not be considered duplicate (QModelIndex) @return flag indicating a duplicate entry (boolean) """ idx = self.__model.getWatchPointIndex(cond, special) duplicate = idx.isValid() and \ idx.internalPointer() != index.internalPointer() if showMessage and duplicate: if not special: msg = self.tr("""

A watch expression '{0}'""" """ already exists.

""")\ .format(Utilities.html_encode(cond)) else: msg = self.tr( """

A watch expression '{0}'""" """ for the variable {1} already exists.

""")\ .format(special, Utilities.html_encode(cond)) E5MessageBox.warning( self, self.tr("Watch expression already exists"), msg) return duplicate def __addWatchPoint(self): """ Private slot to handle the add watch expression context menu entry. """ from .EditWatchpointDialog import EditWatchpointDialog dlg = EditWatchpointDialog(("", False, True, 0, ""), self) if dlg.exec_() == QDialog.Accepted: cond, temp, enabled, ignorecount, special = dlg.getData() if not self.__findDuplicates(cond, special, True): self.__model.addWatchPoint(cond, special, (temp, enabled, ignorecount)) self.__resizeColumns() self.__resort() def __doubleClicked(self, index): """ Private slot to handle the double clicked signal. @param index index of the entry that was double clicked (QModelIndex) """ if index.isValid(): self.__doEditWatchPoint(index) def __editWatchPoint(self): """ Private slot to handle the edit watch expression context menu entry. """ index = self.currentIndex() if index.isValid(): self.__doEditWatchPoint(index) def __doEditWatchPoint(self, index): """ Private slot to edit a watch expression. @param index index of watch expression to be edited (QModelIndex) """ sindex = self.__toSourceIndex(index) if sindex.isValid(): wp = self.__model.getWatchPointByIndex(sindex) if not wp: return cond, special, temp, enabled, count = wp[:5] from .EditWatchpointDialog import EditWatchpointDialog dlg = EditWatchpointDialog( (cond, temp, enabled, count, special), self) if dlg.exec_() == QDialog.Accepted: cond, temp, enabled, count, special = dlg.getData() if not self.__findDuplicates(cond, special, True, sindex): self.__model.setWatchPointByIndex( sindex, cond, special, (temp, enabled, count)) self.__resizeColumns() self.__resort() def __setWpEnabled(self, index, enabled): """ Private method to set the enabled status of a watch expression. @param index index of watch expression to be enabled/disabled (QModelIndex) @param enabled flag indicating the enabled status to be set (boolean) """ sindex = self.__toSourceIndex(index) if sindex.isValid(): self.__model.setWatchPointEnabledByIndex(sindex, enabled) def __enableWatchPoint(self): """ Private slot to handle the enable watch expression context menu entry. """ index = self.currentIndex() self.__setWpEnabled(index, True) self.__resizeColumns() self.__resort() def __enableAllWatchPoints(self): """ Private slot to handle the enable all watch expressions context menu entry. """ index = self.model().index(0, 0) while index.isValid(): self.__setWpEnabled(index, True) index = self.indexBelow(index) self.__resizeColumns() self.__resort() def __enableSelectedWatchPoints(self): """ Private slot to handle the enable selected watch expressions context menu entry. """ for index in self.selectedIndexes(): if index.column() == 0: self.__setWpEnabled(index, True) self.__resizeColumns() self.__resort() def __disableWatchPoint(self): """ Private slot to handle the disable watch expression context menu entry. """ index = self.currentIndex() self.__setWpEnabled(index, False) self.__resizeColumns() self.__resort() def __disableAllWatchPoints(self): """ Private slot to handle the disable all watch expressions context menu entry. """ index = self.model().index(0, 0) while index.isValid(): self.__setWpEnabled(index, False) index = self.indexBelow(index) self.__resizeColumns() self.__resort() def __disableSelectedWatchPoints(self): """ Private slot to handle the disable selected watch expressions context menu entry. """ for index in self.selectedIndexes(): if index.column() == 0: self.__setWpEnabled(index, False) self.__resizeColumns() self.__resort() def __deleteWatchPoint(self): """ Private slot to handle the delete watch expression context menu entry. """ index = self.currentIndex() sindex = self.__toSourceIndex(index) if sindex.isValid(): self.__model.deleteWatchPointByIndex(sindex) def __deleteAllWatchPoints(self): """ Private slot to handle the delete all watch expressions context menu entry. """ self.__model.deleteAll() def __deleteSelectedWatchPoints(self): """ Private slot to handle the delete selected watch expressions context menu entry. """ idxList = [] for index in self.selectedIndexes(): sindex = self.__toSourceIndex(index) if sindex.isValid() and index.column() == 0: idxList.append(sindex) self.__model.deleteWatchPoints(idxList) def __showBackMenu(self): """ Private slot to handle the aboutToShow signal of the background menu. """ if self.model().rowCount() == 0: self.backMenuActions["EnableAll"].setEnabled(False) self.backMenuActions["DisableAll"].setEnabled(False) self.backMenuActions["DeleteAll"].setEnabled(False) else: self.backMenuActions["EnableAll"].setEnabled(True) self.backMenuActions["DisableAll"].setEnabled(True) self.backMenuActions["DeleteAll"].setEnabled(True) def __getSelectedItemsCount(self): """ Private method to get the count of items selected. @return count of items selected (integer) """ count = len(self.selectedIndexes()) // (self.__model.columnCount() - 1) # column count is 1 greater than selectable return count def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("debuggerGeneralPage") eric-6.0.8/eric/Debugger/ExceptionsFilterDialog.py0000644000175000017500000000635712451233373021170 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the exceptions filter dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_ExceptionsFilterDialog import Ui_ExceptionsFilterDialog class ExceptionsFilterDialog(QDialog, Ui_ExceptionsFilterDialog): """ Class implementing the exceptions filter dialog. """ def __init__(self, excList, ignore, parent=None): """ Constructor @param excList list of exceptions to be edited (list of strings) @param ignore flag indicating the ignore exceptions mode (boolean) @param parent the parent widget (QWidget) """ super(ExceptionsFilterDialog, self).__init__(parent) self.setupUi(self) self.setModal(True) self.exceptionList.addItems(excList) if ignore: self.setWindowTitle(self.tr("Ignored Exceptions")) self.exceptionList.setToolTip( self.tr("List of ignored exceptions")) self.okButton = self.buttonBox.button(QDialogButtonBox.Ok) @pyqtSlot() def on_exceptionList_itemSelectionChanged(self): """ Private slot to handle the change of the selection. """ self.deleteButton.setEnabled( len(self.exceptionList.selectedItems()) > 0) @pyqtSlot() def on_deleteButton_clicked(self): """ Private slot to delete the currently selected exception of the listbox. """ itm = self.exceptionList.takeItem(self.exceptionList.currentRow()) del itm @pyqtSlot() def on_deleteAllButton_clicked(self): """ Private slot to delete all exceptions of the listbox. """ while self.exceptionList.count() > 0: itm = self.exceptionList.takeItem(0) del itm @pyqtSlot() def on_addButton_clicked(self): """ Private slot to handle the Add button press. """ exception = self.exceptionEdit.text() if exception: self.exceptionList.addItem(exception) self.exceptionEdit.clear() def on_exceptionEdit_textChanged(self, txt): """ Private slot to handle the textChanged signal of exceptionEdit. This slot sets the enabled status of the add button and sets the forms default button. @param txt the text entered into exceptionEdit (string) """ if not txt: self.okButton.setDefault(True) self.addButton.setDefault(False) self.addButton.setEnabled(False) else: self.okButton.setDefault(False) self.addButton.setDefault(True) self.addButton.setEnabled(True) def getExceptionsList(self): """ Public method to retrieve the list of exception types. @return list of exception types (list of strings) """ excList = [] for row in range(0, self.exceptionList.count()): itm = self.exceptionList.item(row) excList.append(itm.text()) return excList eric-6.0.8/eric/Debugger/DebugViewer.py0000644000175000017500000005201212451233373016756 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a widget containing various debug related views. The views avaliable are:
  • variables viewer for global variables
  • variables viewer for local variables
  • call trace viewer
  • viewer for breakpoints
  • viewer for watch expressions
  • viewer for exceptions
  • viewer for threads
  • a file browser (optional)
  • an interpreter shell (optional)
""" from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, \ QSizePolicy, QPushButton, QComboBox, QLabel, QTreeWidget, \ QTreeWidgetItem, QHeaderView import UI.PixmapCache import Preferences from E5Gui.E5TabWidget import E5TabWidget class DebugViewer(QWidget): """ Class implementing a widget conatining various debug related views. The individual tabs contain the interpreter shell (optional), the filesystem browser (optional), the two variables viewers (global and local), a breakpoint viewer, a watch expression viewer and the exception logger. Additionally a list of all threads is shown. @signal sourceFile(string, int) emitted to open a source file at a line """ sourceFile = pyqtSignal(str, int) def __init__(self, debugServer, docked, vm, parent=None, embeddedShell=True, embeddedBrowser=True): """ Constructor @param debugServer reference to the debug server object @param docked flag indicating a dock window @param vm reference to the viewmanager object @param parent parent widget (QWidget) @param embeddedShell flag indicating whether the shell should be included. This flag is set to False by those layouts, that have the interpreter shell in a separate window. @param embeddedBrowser flag indicating whether the file browser should be included. This flag is set to False by those layouts, that have the file browser in a separate window or embedded in the project browser instead. """ super(DebugViewer, self).__init__(parent) self.debugServer = debugServer self.debugUI = None self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__mainLayout = QVBoxLayout() self.__mainLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.__mainLayout) self.__tabWidget = E5TabWidget() self.__mainLayout.addWidget(self.__tabWidget) self.embeddedShell = embeddedShell if embeddedShell: from QScintilla.Shell import ShellAssembly # add the interpreter shell self.shellAssembly = ShellAssembly(debugServer, vm, False) self.shell = self.shellAssembly.shell() index = self.__tabWidget.addTab( self.shellAssembly, UI.PixmapCache.getIcon("shell.png"), '') self.__tabWidget.setTabToolTip(index, self.shell.windowTitle()) self.embeddedBrowser = embeddedBrowser if embeddedBrowser: from UI.Browser import Browser # add the browser self.browser = Browser() index = self.__tabWidget.addTab( self.browser, UI.PixmapCache.getIcon("browser.png"), '') self.__tabWidget.setTabToolTip(index, self.browser.windowTitle()) from .VariablesViewer import VariablesViewer # add the global variables viewer self.glvWidget = QWidget() self.glvWidgetVLayout = QVBoxLayout(self.glvWidget) self.glvWidgetVLayout.setContentsMargins(0, 0, 0, 0) self.glvWidgetVLayout.setSpacing(3) self.glvWidget.setLayout(self.glvWidgetVLayout) self.globalsViewer = VariablesViewer(self.glvWidget, True) self.glvWidgetVLayout.addWidget(self.globalsViewer) self.glvWidgetHLayout = QHBoxLayout() self.glvWidgetHLayout.setContentsMargins(3, 3, 3, 3) self.globalsFilterEdit = QLineEdit(self.glvWidget) self.globalsFilterEdit.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) self.glvWidgetHLayout.addWidget(self.globalsFilterEdit) self.globalsFilterEdit.setToolTip( self.tr("Enter regular expression patterns separated by ';'" " to define variable filters. ")) self.globalsFilterEdit.setWhatsThis( self.tr("Enter regular expression patterns separated by ';'" " to define variable filters. All variables and" " class attributes matched by one of the expressions" " are not shown in the list above.")) self.setGlobalsFilterButton = QPushButton( self.tr('Set'), self.glvWidget) self.glvWidgetHLayout.addWidget(self.setGlobalsFilterButton) self.glvWidgetVLayout.addLayout(self.glvWidgetHLayout) index = self.__tabWidget.addTab( self.glvWidget, UI.PixmapCache.getIcon("globalVariables.png"), '') self.__tabWidget.setTabToolTip(index, self.globalsViewer.windowTitle()) self.setGlobalsFilterButton.clicked.connect( self.__setGlobalsFilter) self.globalsFilterEdit.returnPressed.connect(self.__setGlobalsFilter) # add the local variables viewer self.lvWidget = QWidget() self.lvWidgetVLayout = QVBoxLayout(self.lvWidget) self.lvWidgetVLayout.setContentsMargins(0, 0, 0, 0) self.lvWidgetVLayout.setSpacing(3) self.lvWidget.setLayout(self.lvWidgetVLayout) self.lvWidgetHLayout1 = QHBoxLayout() self.lvWidgetHLayout1.setContentsMargins(3, 3, 3, 3) self.stackComboBox = QComboBox(self.lvWidget) self.stackComboBox.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) self.lvWidgetHLayout1.addWidget(self.stackComboBox) self.sourceButton = QPushButton(self.tr('Source'), self.lvWidget) self.lvWidgetHLayout1.addWidget(self.sourceButton) self.sourceButton.setEnabled(False) self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout1) self.localsViewer = VariablesViewer(self.lvWidget, False) self.lvWidgetVLayout.addWidget(self.localsViewer) self.lvWidgetHLayout2 = QHBoxLayout() self.lvWidgetHLayout2.setContentsMargins(3, 3, 3, 3) self.localsFilterEdit = QLineEdit(self.lvWidget) self.localsFilterEdit.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) self.lvWidgetHLayout2.addWidget(self.localsFilterEdit) self.localsFilterEdit.setToolTip( self.tr( "Enter regular expression patterns separated by ';' to define " "variable filters. ")) self.localsFilterEdit.setWhatsThis( self.tr( "Enter regular expression patterns separated by ';' to define " "variable filters. All variables and class attributes matched" " by one of the expressions are not shown in the list above.")) self.setLocalsFilterButton = QPushButton( self.tr('Set'), self.lvWidget) self.lvWidgetHLayout2.addWidget(self.setLocalsFilterButton) self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout2) index = self.__tabWidget.addTab( self.lvWidget, UI.PixmapCache.getIcon("localVariables.png"), '') self.__tabWidget.setTabToolTip(index, self.localsViewer.windowTitle()) self.sourceButton.clicked.connect(self.__showSource) self.stackComboBox.currentIndexChanged[int].connect( self.__frameSelected) self.setLocalsFilterButton.clicked.connect(self.__setLocalsFilter) self.localsFilterEdit.returnPressed.connect(self.__setLocalsFilter) from .CallStackViewer import CallStackViewer # add the call stack viewer self.callStackViewer = CallStackViewer(self.debugServer) index = self.__tabWidget.addTab( self.callStackViewer, UI.PixmapCache.getIcon("step.png"), "") self.__tabWidget.setTabToolTip( index, self.callStackViewer.windowTitle()) self.callStackViewer.sourceFile.connect(self.sourceFile) self.callStackViewer.frameSelected.connect( self.__callStackFrameSelected) from .CallTraceViewer import CallTraceViewer # add the call trace viewer self.callTraceViewer = CallTraceViewer(self.debugServer) index = self.__tabWidget.addTab( self.callTraceViewer, UI.PixmapCache.getIcon("callTrace.png"), "") self.__tabWidget.setTabToolTip( index, self.callTraceViewer.windowTitle()) self.callTraceViewer.sourceFile.connect(self.sourceFile) from .BreakPointViewer import BreakPointViewer # add the breakpoint viewer self.breakpointViewer = BreakPointViewer() self.breakpointViewer.setModel(self.debugServer.getBreakPointModel()) index = self.__tabWidget.addTab( self.breakpointViewer, UI.PixmapCache.getIcon("breakpoints.png"), '') self.__tabWidget.setTabToolTip( index, self.breakpointViewer.windowTitle()) self.breakpointViewer.sourceFile.connect(self.sourceFile) from .WatchPointViewer import WatchPointViewer # add the watch expression viewer self.watchpointViewer = WatchPointViewer() self.watchpointViewer.setModel(self.debugServer.getWatchPointModel()) index = self.__tabWidget.addTab( self.watchpointViewer, UI.PixmapCache.getIcon("watchpoints.png"), '') self.__tabWidget.setTabToolTip( index, self.watchpointViewer.windowTitle()) from .ExceptionLogger import ExceptionLogger # add the exception logger self.exceptionLogger = ExceptionLogger() index = self.__tabWidget.addTab( self.exceptionLogger, UI.PixmapCache.getIcon("exceptions.png"), '') self.__tabWidget.setTabToolTip( index, self.exceptionLogger.windowTitle()) if self.embeddedShell: self.__tabWidget.setCurrentWidget(self.shellAssembly) else: if self.embeddedBrowser: self.__tabWidget.setCurrentWidget(self.browser) else: self.__tabWidget.setCurrentWidget(self.glvWidget) # add the threads viewer self.__mainLayout.addWidget(QLabel(self.tr("Threads:"))) self.__threadList = QTreeWidget() self.__threadList.setHeaderLabels( [self.tr("ID"), self.tr("Name"), self.tr("State"), ""]) self.__threadList.setSortingEnabled(True) self.__mainLayout.addWidget(self.__threadList) self.__doThreadListUpdate = True self.__threadList.currentItemChanged.connect(self.__threadSelected) self.__mainLayout.setStretchFactor(self.__tabWidget, 5) self.__mainLayout.setStretchFactor(self.__threadList, 1) self.currPage = None self.currentStack = None self.framenr = 0 self.debugServer.clientStack.connect(self.handleClientStack) self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode") self.sourceButton.setVisible(not self.__autoViewSource) def preferencesChanged(self): """ Public slot to handle the preferencesChanged signal. """ self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode") self.sourceButton.setVisible(not self.__autoViewSource) def setDebugger(self, debugUI): """ Public method to set a reference to the Debug UI. @param debugUI reference to the DebugUI object (DebugUI) """ self.debugUI = debugUI self.debugUI.clientStack.connect(self.handleClientStack) self.callStackViewer.setDebugger(debugUI) def handleResetUI(self): """ Public method to reset the SBVviewer. """ self.globalsViewer.handleResetUI() self.localsViewer.handleResetUI() self.__setGlobalsFilter() self.__setLocalsFilter() self.sourceButton.setEnabled(False) self.currentStack = None self.stackComboBox.clear() self.__threadList.clear() if self.embeddedShell: self.__tabWidget.setCurrentWidget(self.shellAssembly) else: if self.embeddedBrowser: self.__tabWidget.setCurrentWidget(self.browser) else: self.__tabWidget.setCurrentWidget(self.glvWidget) self.breakpointViewer.handleResetUI() def handleRawInput(self): """ Public slot to handle the switch to the shell in raw input mode. """ if self.embeddedShell: self.saveCurrentPage() self.__tabWidget.setCurrentWidget(self.shellAssembly) def initCallStackViewer(self, projectMode): """ Public method to initialize the call stack viewer. @param projectMode flag indicating to enable the project mode (boolean) """ self.callStackViewer.clear() self.callStackViewer.setProjectMode(projectMode) def isCallTraceEnabled(self): """ Public method to get the state of the call trace function. @return flag indicating the state of the call trace function (boolean) """ return self.callTraceViewer.isCallTraceEnabled() def clearCallTrace(self): """ Public method to clear the recorded call trace. """ self.callTraceViewer.clear() def setCallTraceToProjectMode(self, enabled): """ Public slot to set the call trace viewer to project mode. In project mode the call trace info is shown with project relative path names. @param enabled flag indicating to enable the project mode (boolean) """ self.callTraceViewer.setProjectMode(enabled) def showVariables(self, vlist, globals): """ Public method to show the variables in the respective window. @param vlist list of variables to display @param globals flag indicating global/local state """ if globals: self.globalsViewer.showVariables(vlist, self.framenr) else: self.localsViewer.showVariables(vlist, self.framenr) def showVariable(self, vlist, globals): """ Public method to show the variables in the respective window. @param vlist list of variables to display @param globals flag indicating global/local state """ if globals: self.globalsViewer.showVariable(vlist) else: self.localsViewer.showVariable(vlist) def showVariablesTab(self, globals): """ Public method to make a variables tab visible. @param globals flag indicating global/local state """ if globals: self.__tabWidget.setCurrentWidget(self.glvWidget) else: self.__tabWidget.setCurrentWidget(self.lvWidget) def saveCurrentPage(self): """ Public slot to save the current page. """ self.currPage = self.__tabWidget.currentWidget() def restoreCurrentPage(self): """ Public slot to restore the previously saved page. """ if self.currPage is not None: self.__tabWidget.setCurrentWidget(self.currPage) def handleClientStack(self, stack): """ Public slot to show the call stack of the program being debugged. @param stack list of tuples with call stack data (file name, line number, function name, formatted argument/values list) """ block = self.stackComboBox.blockSignals(True) self.framenr = 0 self.stackComboBox.clear() self.currentStack = stack self.sourceButton.setEnabled(len(stack) > 0) for s in stack: # just show base filename to make it readable s = (os.path.basename(s[0]), s[1], s[2]) self.stackComboBox.addItem('{0}:{1}:{2}'.format(*s)) self.stackComboBox.blockSignals(block) def setVariablesFilter(self, globalsFilter, localsFilter): """ Public slot to set the local variables filter. @param globalsFilter filter list for global variable types (list of int) @param localsFilter filter list for local variable types (list of int) """ self.globalsFilter = globalsFilter self.localsFilter = localsFilter def __showSource(self): """ Private slot to handle the source button press to show the selected file. """ index = self.stackComboBox.currentIndex() if index > -1 and self.currentStack: s = self.currentStack[index] self.sourceFile.emit(s[0], int(s[1])) def __frameSelected(self, frmnr): """ Private slot to handle the selection of a new stack frame number. @param frmnr frame number (0 is the current frame) (int) """ self.framenr = frmnr self.debugServer.remoteClientVariables(0, self.localsFilter, frmnr) if self.__autoViewSource: self.__showSource() def __setGlobalsFilter(self): """ Private slot to set the global variable filter. """ filter = self.globalsFilterEdit.text() self.debugServer.remoteClientSetFilter(1, filter) self.debugServer.remoteClientVariables(2, self.globalsFilter) def __setLocalsFilter(self): """ Private slot to set the local variable filter. """ filter = self.localsFilterEdit.text() self.debugServer.remoteClientSetFilter(0, filter) if self.currentStack: self.debugServer.remoteClientVariables( 0, self.localsFilter, self.framenr) def handleDebuggingStarted(self): """ Public slot to handle the start of a debugging session. This slot sets the variables filter expressions. """ self.__setGlobalsFilter() self.__setLocalsFilter() self.showVariablesTab(False) def currentWidget(self): """ Public method to get a reference to the current widget. @return reference to the current widget (QWidget) """ return self.__tabWidget.currentWidget() def setCurrentWidget(self, widget): """ Public slot to set the current page based on the given widget. @param widget reference to the widget (QWidget) """ self.__tabWidget.setCurrentWidget(widget) def showThreadList(self, currentID, threadList): """ Public method to show the thread list. @param currentID id of the current thread (integer) @param threadList list of dictionaries containing the thread data """ citm = None self.__threadList.clear() for thread in threadList: if thread['broken']: state = self.tr("waiting at breakpoint") else: state = self.tr("running") itm = QTreeWidgetItem(self.__threadList, ["{0:d}".format(thread['id']), thread['name'], state]) if thread['id'] == currentID: citm = itm self.__threadList.header().resizeSections(QHeaderView.ResizeToContents) self.__threadList.header().setStretchLastSection(True) if citm: self.__doThreadListUpdate = False self.__threadList.setCurrentItem(citm) self.__doThreadListUpdate = True def __threadSelected(self, current, previous): """ Private slot to handle the selection of a thread in the thread list. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the previous current item (QTreeWidgetItem) """ if current is not None and self.__doThreadListUpdate: tid = int(current.text(0)) self.debugServer.remoteSetThread(tid) def __callStackFrameSelected(self, frameNo): """ Private slot to handle the selection of a call stack entry of the call stack viewer. @param frameNo frame number (index) of the selected entry (integer) """ if frameNo >= 0: self.stackComboBox.setCurrentIndex(frameNo) eric-6.0.8/eric/Debugger/__init__.py0000644000175000017500000000044012451233373016303 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Package implementing the Debugger frontend. This package implements the graphical debugger. It consists of the debugger related HMI part, supporting dialogs and the debug server. """ eric-6.0.8/eric/Debugger/DebuggerInterfacePython3.py0000644000175000017500000012441412451233373021406 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the Python3 debugger interface for the debug server. """ from __future__ import unicode_literals import sys import os from PyQt5.QtCore import QObject, QTextCodec, QProcess, QProcessEnvironment, \ QTimer from PyQt5.QtWidgets import QInputDialog from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from . import DebugProtocol from . import DebugClientCapabilities import Preferences import Utilities from eric6config import getConfig ClientDefaultCapabilities = DebugClientCapabilities.HasAll def getRegistryData(): """ Module function to get characterising data for the debugger interface. @return list of the following data. Client type (string), client capabilities (integer), client type association (list of strings) """ exts = [] for ext in Preferences.getDebugger("Python3Extensions").split(): if ext.startswith("."): exts.append(ext) else: exts.append(".{0}".format(ext)) if exts: return ["Python3", ClientDefaultCapabilities, exts] else: return ["", 0, []] class DebuggerInterfacePython3(QObject): """ Class implementing the Python debugger interface for the debug server. """ def __init__(self, debugServer, passive): """ Constructor @param debugServer reference to the debug server (DebugServer) @param passive flag indicating passive connection mode (boolean) """ super(DebuggerInterfacePython3, self).__init__() self.__isNetworked = True self.__autoContinue = False self.debugServer = debugServer self.passive = passive self.process = None self.qsock = None self.queue = [] # set default values for capabilities of clients self.clientCapabilities = ClientDefaultCapabilities # set translation function self.translate = self.__identityTranslation self.codec = QTextCodec.codecForName( str(Preferences.getSystem("StringEncoding"))) if passive: # set translation function if Preferences.getDebugger("PathTranslation"): self.translateRemote = \ Preferences.getDebugger("PathTranslationRemote") self.translateLocal = \ Preferences.getDebugger("PathTranslationLocal") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation # attribute to remember the name of the executed script self.__scriptName = "" def __identityTranslation(self, fn, remote2local=True): """ Private method to perform the identity path translation. @param fn filename to be translated (string) @param remote2local flag indicating the direction of translation (False = local to remote, True = remote to local [default]) @return translated filename (string) """ return fn def __remoteTranslation(self, fn, remote2local=True): """ Private method to perform the path translation. @param fn filename to be translated (string) @param remote2local flag indicating the direction of translation (False = local to remote, True = remote to local [default]) @return translated filename (string) """ if remote2local: return fn.replace(self.translateRemote, self.translateLocal) else: return fn.replace(self.translateLocal, self.translateRemote) def __startProcess(self, program, arguments, environment=None): """ Private method to start the debugger client process. @param program name of the executable to start (string) @param arguments arguments to be passed to the program (list of string) @param environment dictionary of environment settings to pass (dict of string) @return the process object (QProcess) or None """ proc = QProcess() if environment is not None: env = QProcessEnvironment() for key, value in list(environment.items()): env.insert(key, value) proc.setProcessEnvironment(env) args = [] for arg in arguments: args.append(arg) proc.start(program, args) if not proc.waitForStarted(10000): proc = None return proc def startRemote(self, port, runInConsole): """ Public method to start a remote Python interpreter. @param port portnumber the debug server is listening on (integer) @param runInConsole flag indicating to start the debugger in a console window (boolean) @return client process object (QProcess), a flag to indicate a network connection (boolean) and the name of the interpreter in case of a local execution (string) """ interpreter = Preferences.getDebugger("Python3Interpreter") if interpreter == "": E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

No Python3 interpreter configured.

""")) return None, False, "" debugClientType = Preferences.getDebugger("DebugClientType3") if debugClientType == "standard": debugClient = os.path.join(getConfig('ericDir'), "DebugClients", "Python3", "DebugClient.py") elif debugClientType == "threaded": debugClient = os.path.join(getConfig('ericDir'), "DebugClients", "Python3", "DebugClientThreads.py") else: debugClient = Preferences.getDebugger("DebugClient3") if debugClient == "": debugClient = os.path.join(sys.path[0], "DebugClients", "Python3", "DebugClient.py") redirect = str(Preferences.getDebugger("Python3Redirect")) noencoding = Preferences.getDebugger("Python3NoEncoding") and \ '--no-encoding' or '' if Preferences.getDebugger("RemoteDbgEnabled"): ipaddr = self.debugServer.getHostAddress(False) rexec = Preferences.getDebugger("RemoteExecution") rhost = Preferences.getDebugger("RemoteHost") if rhost == "": rhost = "localhost" if rexec: args = Utilities.parseOptionString(rexec) + \ [rhost, interpreter, os.path.abspath(debugClient), noencoding, str(port), redirect, ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:]) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) # set translation function if Preferences.getDebugger("PathTranslation"): self.translateRemote = \ Preferences.getDebugger("PathTranslationRemote") self.translateLocal = \ Preferences.getDebugger("PathTranslationLocal") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation return process, self.__isNetworked, "" # set translation function self.translate = self.__identityTranslation # setup the environment for the debugger if Preferences.getDebugger("DebugEnvironmentReplace"): clientEnv = {} else: clientEnv = os.environ.copy() envlist = Utilities.parseEnvironmentString( Preferences.getDebugger("DebugEnvironment")) for el in envlist: try: key, value = el.split('=', 1) if value.startswith('"') or value.startswith("'"): value = value[1:-1] clientEnv[str(key)] = str(value) except ValueError: pass ipaddr = self.debugServer.getHostAddress(True) if runInConsole or Preferences.getDebugger("ConsoleDbgEnabled"): ccmd = Preferences.getDebugger("ConsoleDbgCommand") if ccmd: args = Utilities.parseOptionString(ccmd) + \ [interpreter, os.path.abspath(debugClient), noencoding, str(port), '0', ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) return process, self.__isNetworked, interpreter process = self.__startProcess( interpreter, [debugClient, noencoding, str(port), redirect, ipaddr], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be started.

""")) return process, self.__isNetworked, interpreter def startRemoteForProject(self, port, runInConsole): """ Public method to start a remote Python interpreter for a project. @param port portnumber the debug server is listening on (integer) @param runInConsole flag indicating to start the debugger in a console window (boolean) @return client process object (QProcess), a flag to indicate a network connection (boolean) and the name of the interpreter in case of a local execution (string) """ project = e5App().getObject("Project") if not project.isDebugPropertiesLoaded(): return None, self.__isNetworked, "" # start debugger with project specific settings interpreter = project.getDebugProperty("INTERPRETER") debugClient = project.getDebugProperty("DEBUGCLIENT") redirect = str(project.getDebugProperty("REDIRECT")) noencoding = \ project.getDebugProperty("NOENCODING") and '--no-encoding' or '' if project.getDebugProperty("REMOTEDEBUGGER"): ipaddr = self.debugServer.getHostAddress(False) rexec = project.getDebugProperty("REMOTECOMMAND") rhost = project.getDebugProperty("REMOTEHOST") if rhost == "": rhost = "localhost" if rexec: args = Utilities.parseOptionString(rexec) + \ [rhost, interpreter, os.path.abspath(debugClient), noencoding, str(port), redirect, ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:]) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) # set translation function if project.getDebugProperty("PATHTRANSLATION"): self.translateRemote = \ project.getDebugProperty("REMOTEPATH") self.translateLocal = \ project.getDebugProperty("LOCALPATH") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation return process, self.__isNetworked, "" # set translation function self.translate = self.__identityTranslation # setup the environment for the debugger if project.getDebugProperty("ENVIRONMENTOVERRIDE"): clientEnv = {} else: clientEnv = os.environ.copy() envlist = Utilities.parseEnvironmentString( project.getDebugProperty("ENVIRONMENTSTRING")) for el in envlist: try: key, value = el.split('=', 1) if value.startswith('"') or value.startswith("'"): value = value[1:-1] clientEnv[str(key)] = str(value) except ValueError: pass ipaddr = self.debugServer.getHostAddress(True) if runInConsole or project.getDebugProperty("CONSOLEDEBUGGER"): ccmd = project.getDebugProperty("CONSOLECOMMAND") or \ Preferences.getDebugger("ConsoleDbgCommand") if ccmd: args = Utilities.parseOptionString(ccmd) + \ [interpreter, os.path.abspath(debugClient), noencoding, str(port), '0', ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) return process, self.__isNetworked, interpreter process = self.__startProcess( interpreter, [debugClient, noencoding, str(port), redirect, ipaddr], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be started.

""")) return process, self.__isNetworked, interpreter def getClientCapabilities(self): """ Public method to retrieve the debug clients capabilities. @return debug client capabilities (integer) """ return self.clientCapabilities def newConnection(self, sock): """ Public slot to handle a new connection. @param sock reference to the socket object (QTcpSocket) @return flag indicating success (boolean) """ # If we already have a connection, refuse this one. It will be closed # automatically. if self.qsock is not None: return False sock.disconnected.connect(self.debugServer.startClient) sock.readyRead.connect(self.__parseClientLine) self.qsock = sock # Get the remote clients capabilities self.remoteCapabilities() return True def flush(self): """ Public slot to flush the queue. """ # Send commands that were waiting for the connection. for cmd in self.queue: self.qsock.write(cmd.encode('utf8', 'backslashreplace')) self.queue = [] def shutdown(self): """ Public method to cleanly shut down. It closes our socket and shuts down the debug client. (Needed on Win OS) """ if self.qsock is None: return # do not want any slots called during shutdown self.qsock.disconnected.disconnect(self.debugServer.startClient) self.qsock.readyRead.disconnect(self.__parseClientLine) # close down socket, and shut down client as well. self.__sendCommand('{0}\n'.format(DebugProtocol.RequestShutdown)) self.qsock.flush() self.qsock.close() # reinitialize self.qsock = None self.queue = [] def isConnected(self): """ Public method to test, if a debug client has connected. @return flag indicating the connection status (boolean) """ return self.qsock is not None def remoteEnvironment(self, env): """ Public method to set the environment for a program to debug, run, ... @param env environment settings (dictionary) """ self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestEnv, str(env))) def remoteLoad(self, fn, argv, wd, traceInterpreter=False, autoContinue=True, autoFork=False, forkChild=False): """ Public method to load a new program to debug. @param fn the filename to debug (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam traceInterpreter flag indicating if the interpreter library should be traced as well (boolean) @keyparam autoContinue flag indicating, that the debugger should not stop at the first executable line (boolean) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) """ self.__autoContinue = autoContinue self.__scriptName = os.path.abspath(fn) wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestForkMode, repr((autoFork, forkChild)))) self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( DebugProtocol.RequestLoad, wd, fn, str(Utilities.parseOptionString(argv)), traceInterpreter)) def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False): """ Public method to load a new program to run. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) """ self.__scriptName = os.path.abspath(fn) wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestForkMode, repr((autoFork, forkChild)))) self.__sendCommand('{0}{1}|{2}|{3}\n'.format( DebugProtocol.RequestRun, wd, fn, str(Utilities.parseOptionString(argv)))) def remoteCoverage(self, fn, argv, wd, erase=False): """ Public method to load a new program to collect coverage data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam erase flag indicating that coverage info should be cleared first (boolean) """ self.__scriptName = os.path.abspath(fn) wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}@@{2}@@{3}@@{4:d}\n'.format( DebugProtocol.RequestCoverage, wd, fn, str(Utilities.parseOptionString(argv)), erase)) def remoteProfile(self, fn, argv, wd, erase=False): """ Public method to load a new program to collect profiling data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam erase flag indicating that timing info should be cleared first (boolean) """ self.__scriptName = os.path.abspath(fn) wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( DebugProtocol.RequestProfile, wd, fn, str(Utilities.parseOptionString(argv)), erase)) def remoteStatement(self, stmt): """ Public method to execute a Python statement. @param stmt the Python statement to execute (string). It should not have a trailing newline. """ self.__sendCommand('{0}\n'.format(stmt)) self.__sendCommand(DebugProtocol.RequestOK + '\n') def remoteStep(self): """ Public method to single step the debugged program. """ self.__sendCommand(DebugProtocol.RequestStep + '\n') def remoteStepOver(self): """ Public method to step over the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepOver + '\n') def remoteStepOut(self): """ Public method to step out the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepOut + '\n') def remoteStepQuit(self): """ Public method to stop the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepQuit + '\n') def remoteContinue(self, special=False): """ Public method to continue the debugged program. @param special flag indicating a special continue operation """ self.__sendCommand('{0}{1:d}\n'.format( DebugProtocol.RequestContinue, special)) def remoteBreakpoint(self, fn, line, set, cond=None, temp=False): """ Public method to set or clear a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param set flag indicating setting or resetting a breakpoint (boolean) @param cond condition of the breakpoint (string) @param temp flag indicating a temporary breakpoint (boolean) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1}@@{2:d}@@{3:d}@@{4:d}@@{5}\n'.format( DebugProtocol.RequestBreak, fn, line, temp, set, cond)) def remoteBreakpointEnable(self, fn, line, enable): """ Public method to enable or disable a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param enable flag indicating enabling or disabling a breakpoint (boolean) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format( DebugProtocol.RequestBreakEnable, fn, line, enable)) def remoteBreakpointIgnore(self, fn, line, count): """ Public method to ignore a breakpoint the next couple of occurrences. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param count number of occurrences to ignore (int) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format( DebugProtocol.RequestBreakIgnore, fn, line, count)) def remoteWatchpoint(self, cond, set, temp=False): """ Public method to set or clear a watch expression. @param cond expression of the watch expression (string) @param set flag indicating setting or resetting a watch expression (boolean) @param temp flag indicating a temporary watch expression (boolean) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1}@@{2:d}@@{3:d}\n'.format( DebugProtocol.RequestWatch, cond, temp, set)) def remoteWatchpointEnable(self, cond, enable): """ Public method to enable or disable a watch expression. @param cond expression of the watch expression (string) @param enable flag indicating enabling or disabling a watch expression (boolean) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1},{2:d}\n'.format( DebugProtocol.RequestWatchEnable, cond, enable)) def remoteWatchpointIgnore(self, cond, count): """ Public method to ignore a watch expression the next couple of occurrences. @param cond expression of the watch expression (string) @param count number of occurrences to ignore (int) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1},{2:d}\n'.format( DebugProtocol.RequestWatchIgnore, cond, count)) def remoteRawInput(self, s): """ Public method to send the raw input to the debugged program. @param s the raw input (string) """ self.__sendCommand(s + '\n') def remoteThreadList(self): """ Public method to request the list of threads from the client. """ self.__sendCommand('{0}\n'.format(DebugProtocol.RequestThreadList)) def remoteSetThread(self, tid): """ Public method to request to set the given thread as current thread. @param tid id of the thread (integer) """ self.__sendCommand('{0}{1:d}\n'.format( DebugProtocol.RequestThreadSet, tid)) def remoteClientVariables(self, scope, filter, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param framenr framenumber of the variables to retrieve (int) """ self.__sendCommand('{0}{1:d}, {2:d}, {3}\n'.format( DebugProtocol.RequestVariables, framenr, scope, str(filter))) def remoteClientVariable(self, scope, filter, var, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param var list encoded name of variable to retrieve (string) @param framenr framenumber of the variables to retrieve (int) """ self.__sendCommand('{0}{1}, {2:d}, {3:d}, {4}\n'.format( DebugProtocol.RequestVariable, str(var), framenr, scope, str(filter))) def remoteClientSetFilter(self, scope, filter): """ Public method to set a variables filter list. @param scope the scope of the variables (0 = local, 1 = global) @param filter regexp string for variable names to filter out (string) """ self.__sendCommand('{0}{1:d}, "{2}"\n'.format( DebugProtocol.RequestSetFilter, scope, filter)) def setCallTraceEnabled(self, on): """ Public method to set the call trace state. @param on flag indicating to enable the call trace function (boolean) """ if on: cmd = "on" else: cmd = "off" self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestCallTrace, cmd)) def remoteEval(self, arg): """ Public method to evaluate arg in the current context of the debugged program. @param arg the arguments to evaluate (string) """ self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestEval, arg)) def remoteExec(self, stmt): """ Public method to execute stmt in the current context of the debugged program. @param stmt statement to execute (string) """ self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestExec, stmt)) def remoteBanner(self): """ Public slot to get the banner info of the remote client. """ self.__sendCommand(DebugProtocol.RequestBanner + '\n') def remoteCapabilities(self): """ Public slot to get the debug clients capabilities. """ self.__sendCommand(DebugProtocol.RequestCapabilities + '\n') def remoteCompletion(self, text): """ Public slot to get the a list of possible commandline completions from the remote client. @param text the text to be completed (string) """ self.__sendCommand("{0}{1}\n".format( DebugProtocol.RequestCompletion, text)) def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase): """ Public method to prepare a new unittest run. @param fn the filename to load (string) @param tn the testname to load (string) @param tfn the test function name to load tests from (string) @param failed list of failed test, if only failed test should be run (list of strings) @param cov flag indicating collection of coverage data is requested (boolean) @param covname filename to be used to assemble the coverage caches filename (string) @param coverase flag indicating erasure of coverage data is requested (boolean) """ self.__scriptName = os.path.abspath(fn) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}|{2}|{3}|{4}|{5:d}|{6}|{7:d}\n'.format( DebugProtocol.RequestUTPrepare, fn, tn, tfn, str(failed), cov, covname, coverase)) def remoteUTRun(self): """ Public method to start a unittest run. """ self.__sendCommand('{0}\n'.format(DebugProtocol.RequestUTRun)) def remoteUTStop(self): """ Public method to stop a unittest run. """ self.__sendCommand('{0}\n'.format(DebugProtocol.RequestUTStop)) def __askForkTo(self): """ Private method to ask the user which branch of a fork to follow. """ selections = [self.tr("Parent Process"), self.tr("Child process")] res, ok = QInputDialog.getItem( None, self.tr("Client forking"), self.tr("Select the fork branch to follow."), selections, 0, False) if not ok or res == selections[0]: self.__sendCommand(DebugProtocol.ResponseForkTo + 'parent\n') else: self.__sendCommand(DebugProtocol.ResponseForkTo + 'child\n') def __parseClientLine(self): """ Private method to handle data from the client. """ while self.qsock and self.qsock.canReadLine(): qs = self.qsock.readLine() if self.codec is not None: line = self.codec.toUnicode(qs) else: line = bytes(qs).decode() if line.endswith(DebugProtocol.EOT): line = line[:-len(DebugProtocol.EOT)] if not line: continue ## print("Server: ", line) ##debug eoc = line.find('<') + 1 # Deal with case where user has written directly to stdout # or stderr, but not line terminated and we stepped over the # write call, in that case the >line< will not be the first # string read from the socket... boc = line.find('>') if boc > 0 and eoc > boc: self.debugServer.signalClientOutput(line[:boc]) line = line[boc:] eoc = line.find('<') + 1 boc = line.find('>') if boc >= 0 and eoc > boc: resp = line[boc:eoc] if resp == DebugProtocol.ResponseLine or \ resp == DebugProtocol.ResponseStack: stack = eval(line[eoc:-1]) for s in stack: s[0] = self.translate(s[0], True) cf = stack[0] if self.__autoContinue: self.__autoContinue = False QTimer.singleShot(0, self.remoteContinue) else: self.debugServer.signalClientLine( cf[0], int(cf[1]), resp == DebugProtocol.ResponseStack) self.debugServer.signalClientStack(stack) continue if resp == DebugProtocol.CallTrace: event, fromStr, toStr = line[eoc:-1].split("@@") isCall = event.lower() == "c" fromFile, fromLineno, fromFunc = fromStr.rsplit(":", 2) toFile, toLineno, toFunc = toStr.rsplit(":", 2) self.debugServer.signalClientCallTrace( isCall, fromFile, fromLineno, fromFunc, toFile, toLineno, toFunc) continue if resp == DebugProtocol.ResponseThreadList: currentId, threadList = eval(line[eoc:-1]) self.debugServer.signalClientThreadList( currentId, threadList) continue if resp == DebugProtocol.ResponseThreadSet: self.debugServer.signalClientThreadSet() continue if resp == DebugProtocol.ResponseVariables: vlist = eval(line[eoc:-1]) scope = vlist[0] try: variables = vlist[1:] except IndexError: variables = [] self.debugServer.signalClientVariables(scope, variables) continue if resp == DebugProtocol.ResponseVariable: vlist = eval(line[eoc:-1]) scope = vlist[0] try: variables = vlist[1:] except IndexError: variables = [] self.debugServer.signalClientVariable(scope, variables) continue if resp == DebugProtocol.ResponseOK: self.debugServer.signalClientStatement(False) continue if resp == DebugProtocol.ResponseContinue: self.debugServer.signalClientStatement(True) continue if resp == DebugProtocol.ResponseException: exc = line[eoc:-1] exc = self.translate(exc, True) try: exclist = eval(exc) exctype = exclist[0] excmessage = exclist[1] stack = exclist[2:] if stack and stack[0] and stack[0][0] == "": for stackEntry in stack: if stackEntry[0] == "": stackEntry[0] = self.__scriptName else: break except (IndexError, ValueError, SyntaxError): exctype = None excmessage = '' stack = [] self.debugServer.signalClientException( exctype, excmessage, stack) continue if resp == DebugProtocol.ResponseSyntax: exc = line[eoc:-1] exc = self.translate(exc, True) try: message, (fn, ln, cn) = eval(exc) if fn is None: fn = '' except (IndexError, ValueError): message = None fn = '' ln = 0 cn = 0 if cn is None: cn = 0 self.debugServer.signalClientSyntaxError( message, fn, ln, cn) continue if resp == DebugProtocol.ResponseExit: self.__scriptName = "" self.debugServer.signalClientExit(line[eoc:-1]) continue if resp == DebugProtocol.ResponseClearBreak: fn, lineno = line[eoc:-1].split(',') lineno = int(lineno) fn = self.translate(fn, True) self.debugServer.signalClientClearBreak(fn, lineno) continue if resp == DebugProtocol.ResponseBPConditionError: fn, lineno = line[eoc:-1].split(',') lineno = int(lineno) fn = self.translate(fn, True) self.debugServer.signalClientBreakConditionError( fn, lineno) continue if resp == DebugProtocol.ResponseClearWatch: cond = line[eoc:-1] self.debugServer.signalClientClearWatch(cond) continue if resp == DebugProtocol.ResponseWPConditionError: cond = line[eoc:-1] self.debugServer.signalClientWatchConditionError(cond) continue if resp == DebugProtocol.ResponseRaw: prompt, echo = eval(line[eoc:-1]) self.debugServer.signalClientRawInput(prompt, echo) continue if resp == DebugProtocol.ResponseBanner: version, platform, dbgclient = eval(line[eoc:-1]) self.debugServer.signalClientBanner( version, platform, dbgclient) continue if resp == DebugProtocol.ResponseCapabilities: cap, clType = eval(line[eoc:-1]) self.clientCapabilities = cap self.debugServer.signalClientCapabilities(cap, clType) continue if resp == DebugProtocol.ResponseCompletion: clstring, text = line[eoc:-1].split('||') cl = eval(clstring) self.debugServer.signalClientCompletionList(cl, text) continue if resp == DebugProtocol.PassiveStartup: fn, exc = line[eoc:-1].split('|') exc = bool(exc) fn = self.translate(fn, True) self.debugServer.passiveStartUp(fn, exc) continue if resp == DebugProtocol.ResponseUTPrepared: res, exc_type, exc_value = eval(line[eoc:-1]) self.debugServer.clientUtPrepared(res, exc_type, exc_value) continue if resp == DebugProtocol.ResponseUTStartTest: testname, doc = eval(line[eoc:-1]) self.debugServer.clientUtStartTest(testname, doc) continue if resp == DebugProtocol.ResponseUTStopTest: self.debugServer.clientUtStopTest() continue if resp == DebugProtocol.ResponseUTTestFailed: testname, traceback, id = eval(line[eoc:-1]) self.debugServer.clientUtTestFailed( testname, traceback, id) continue if resp == DebugProtocol.ResponseUTTestErrored: testname, traceback, id = eval(line[eoc:-1]) self.debugServer.clientUtTestErrored( testname, traceback, id) continue if resp == DebugProtocol.ResponseUTTestSkipped: testname, reason, id = eval(line[eoc:-1]) self.debugServer.clientUtTestSkipped(testname, reason, id) continue if resp == DebugProtocol.ResponseUTTestFailedExpected: testname, traceback, id = eval(line[eoc:-1]) self.debugServer.clientUtTestFailedExpected( testname, traceback, id) continue if resp == DebugProtocol.ResponseUTTestSucceededUnexpected: testname, id = eval(line[eoc:-1]) self.debugServer.clientUtTestSucceededUnexpected( testname, id) continue if resp == DebugProtocol.ResponseUTFinished: self.debugServer.clientUtFinished() continue if resp == DebugProtocol.RequestForkTo: self.__askForkTo() continue self.debugServer.signalClientOutput(line) def __sendCommand(self, cmd): """ Private method to send a single line command to the client. @param cmd command to send to the debug client (string) """ if self.qsock is not None: self.qsock.write(cmd.encode('utf8', 'backslashreplace')) else: self.queue.append(cmd) eric-6.0.8/eric/Debugger/StartCoverageDialog.ui0000644000175000017500000002147712354033066020436 0ustar piotrpiotr StartCoverageDialog 0 0 488 225 Start coverage run true Command&line: cmdlineCombo 0 0 Enter the commandline parameters <b>Commandline</b> <p>Enter the commandline parameters in this field.</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false &Working directory: workdirCombo 0 0 Enter the working directory <b>Working directory</b> <p>Enter the working directory of the application to be debugged. Leave it empty to set the working directory to the executable directory.</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false &Environment: environmentCombo 0 0 Enter the environment variables to be set. <b>Environment</b> <p>Enter the environment variables to be set for the program. The individual settings must be separated by whitespace and be given in the form 'var=value'. In order to add to an environment variable, enter it in the form 'var+=value'.</p> <p>Example: var1=1 var2="hello world" var3+=":/tmp"</p> true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLengthWithIcon false Uncheck to disable exception reporting <b>Report exceptions</b> <p>Uncheck this in order to disable exception reporting.</p> Report &exceptions Alt+E true Select to clear the display of the interpreter window <b>Clear interpreter window</b><p>This clears the display of the interpreter window before starting the debug client.</p> Clear &interpreter window true Select to start the debugger in a console window <b>Start in console</b> <p>Select to start the debugger in a console window. The console command has to be configured on the Debugger-&gt;General page</p> Start in console Select this to erase the collected coverage information <b>Erase coverage information</b> <p>Select this to erase the collected coverage information before the next coverage run.</p> Erase &coverage information Alt+C Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Select directory using a directory selection dialog <b>Select directory</b> <p>Select the working directory via a directory selection dialog.</p> qPixmapFromMimeSource cmdlineCombo workdirCombo dirButton environmentCombo exceptionCheckBox clearShellCheckBox consoleCheckBox eraseCheckBox buttonBox buttonBox accepted() StartCoverageDialog accept() 28 176 28 201 buttonBox rejected() StartCoverageDialog reject() 113 177 113 199 eric-6.0.8/eric/Debugger/DebuggerInterfacePython.py0000644000175000017500000012500012451233373021313 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Python debugger interface for the debug server. """ from __future__ import unicode_literals import sys import os import re from PyQt5.QtCore import QObject, QTextCodec, QProcess, QProcessEnvironment, \ QTimer from PyQt5.QtWidgets import QInputDialog from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from . import DebugProtocol from . import DebugClientCapabilities import Preferences import Utilities from eric6config import getConfig ClientDefaultCapabilities = DebugClientCapabilities.HasAll def getRegistryData(): """ Module function to get characterising data for the debugger interface. @return list of the following data. Client type (string), client capabilities (integer), client type association (list of strings) """ exts = [] for ext in Preferences.getDebugger("PythonExtensions").split(): if ext.startswith("."): exts.append(ext) else: exts.append(".{0}".format(ext)) if exts and Preferences.getDebugger("PythonInterpreter"): return ["Python2", ClientDefaultCapabilities, exts] else: return ["", 0, []] class DebuggerInterfacePython(QObject): """ Class implementing the Python debugger interface for the debug server. """ def __init__(self, debugServer, passive): """ Constructor @param debugServer reference to the debug server (DebugServer) @param passive flag indicating passive connection mode (boolean) """ super(DebuggerInterfacePython, self).__init__() self.__isNetworked = True self.__autoContinue = False self.debugServer = debugServer self.passive = passive self.process = None self.qsock = None self.queue = [] # set default values for capabilities of clients self.clientCapabilities = ClientDefaultCapabilities # set translation function self.translate = self.__identityTranslation self.codec = QTextCodec.codecForName( Preferences.getSystem("StringEncoding")) self.__unicodeRe = re.compile(r"""\bu(["'])""") if passive: # set translation function if Preferences.getDebugger("PathTranslation"): self.translateRemote = \ Preferences.getDebugger("PathTranslationRemote") self.translateLocal = \ Preferences.getDebugger("PathTranslationLocal") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation # attribute to remember the name of the executed script self.__scriptName = "" def __identityTranslation(self, fn, remote2local=True): """ Private method to perform the identity path translation. @param fn filename to be translated (string) @param remote2local flag indicating the direction of translation (False = local to remote, True = remote to local [default]) @return translated filename (string) """ return fn def __remoteTranslation(self, fn, remote2local=True): """ Private method to perform the path translation. @param fn filename to be translated (string) @param remote2local flag indicating the direction of translation (False = local to remote, True = remote to local [default]) @return translated filename (string) """ if remote2local: return fn.replace(self.translateRemote, self.translateLocal) else: return fn.replace(self.translateLocal, self.translateRemote) def __startProcess(self, program, arguments, environment=None): """ Private method to start the debugger client process. @param program name of the executable to start (string) @param arguments arguments to be passed to the program (list of string) @param environment dictionary of environment settings to pass (dict of string) @return the process object (QProcess) or None """ proc = QProcess() if environment is not None: env = QProcessEnvironment() for key, value in list(environment.items()): env.insert(key, value) proc.setProcessEnvironment(env) args = [] for arg in arguments: args.append(arg) proc.start(program, args) if not proc.waitForStarted(10000): proc = None return proc def startRemote(self, port, runInConsole): """ Public method to start a remote Python interpreter. @param port portnumber the debug server is listening on (integer) @param runInConsole flag indicating to start the debugger in a console window (boolean) @return client process object (QProcess), a flag to indicate a network connection (boolean) and the name of the interpreter in case of a local execution (string) """ interpreter = Preferences.getDebugger("PythonInterpreter") if interpreter == "": E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

No Python2 interpreter configured.

""")) return None, False, "" debugClientType = Preferences.getDebugger("DebugClientType") if debugClientType == "standard": debugClient = os.path.join(getConfig('ericDir'), "DebugClients", "Python", "DebugClient.py") elif debugClientType == "threaded": debugClient = os.path.join(getConfig('ericDir'), "DebugClients", "Python", "DebugClientThreads.py") else: debugClient = Preferences.getDebugger("DebugClient") if debugClient == "": debugClient = os.path.join(sys.path[0], "DebugClients", "Python", "DebugClient.py") redirect = str(Preferences.getDebugger("PythonRedirect")) noencoding = Preferences.getDebugger("PythonNoEncoding") and \ '--no-encoding' or '' if Preferences.getDebugger("RemoteDbgEnabled"): ipaddr = self.debugServer.getHostAddress(False) rexec = Preferences.getDebugger("RemoteExecution") rhost = Preferences.getDebugger("RemoteHost") if rhost == "": rhost = "localhost" if rexec: args = Utilities.parseOptionString(rexec) + \ [rhost, interpreter, os.path.abspath(debugClient), noencoding, str(port), redirect, ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:]) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) # set translation function if Preferences.getDebugger("PathTranslation"): self.translateRemote = \ Preferences.getDebugger("PathTranslationRemote") self.translateLocal = \ Preferences.getDebugger("PathTranslationLocal") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation return process, self.__isNetworked, "" # set translation function self.translate = self.__identityTranslation # setup the environment for the debugger if Preferences.getDebugger("DebugEnvironmentReplace"): clientEnv = {} else: clientEnv = os.environ.copy() envlist = Utilities.parseEnvironmentString( Preferences.getDebugger("DebugEnvironment")) for el in envlist: try: key, value = el.split('=', 1) if value.startswith('"') or value.startswith("'"): value = value[1:-1] clientEnv[str(key)] = str(value) except ValueError: pass ipaddr = self.debugServer.getHostAddress(True) if runInConsole or Preferences.getDebugger("ConsoleDbgEnabled"): ccmd = Preferences.getDebugger("ConsoleDbgCommand") if ccmd: args = Utilities.parseOptionString(ccmd) + \ [interpreter, os.path.abspath(debugClient), noencoding, str(port), '0', ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) return process, self.__isNetworked, interpreter process = self.__startProcess( interpreter, [debugClient, noencoding, str(port), redirect, ipaddr], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be started.

""")) return process, self.__isNetworked, interpreter def startRemoteForProject(self, port, runInConsole): """ Public method to start a remote Python interpreter for a project. @param port portnumber the debug server is listening on (integer) @param runInConsole flag indicating to start the debugger in a console window (boolean) @return client process object (QProcess), a flag to indicate a network connection (boolean) and the name of the interpreter in case of a local execution (string) """ project = e5App().getObject("Project") if not project.isDebugPropertiesLoaded(): return None, self.__isNetworked, "" # start debugger with project specific settings interpreter = project.getDebugProperty("INTERPRETER") debugClient = project.getDebugProperty("DEBUGCLIENT") redirect = str(project.getDebugProperty("REDIRECT")) noencoding = \ project.getDebugProperty("NOENCODING") and '--no-encoding' or '' if project.getDebugProperty("REMOTEDEBUGGER"): ipaddr = self.debugServer.getHostAddress(False) rexec = project.getDebugProperty("REMOTECOMMAND") rhost = project.getDebugProperty("REMOTEHOST") if rhost == "": rhost = "localhost" if rexec: args = Utilities.parseOptionString(rexec) + \ [rhost, interpreter, os.path.abspath(debugClient), noencoding, str(port), redirect, ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:]) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) # set translation function if project.getDebugProperty("PATHTRANSLATION"): self.translateRemote = \ project.getDebugProperty("REMOTEPATH") self.translateLocal = \ project.getDebugProperty("LOCALPATH") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation return process, self.__isNetworked, "" # set translation function self.translate = self.__identityTranslation # setup the environment for the debugger if project.getDebugProperty("ENVIRONMENTOVERRIDE"): clientEnv = {} else: clientEnv = os.environ.copy() envlist = Utilities.parseEnvironmentString( project.getDebugProperty("ENVIRONMENTSTRING")) for el in envlist: try: key, value = el.split('=', 1) if value.startswith('"') or value.startswith("'"): value = value[1:-1] clientEnv[str(key)] = str(value) except ValueError: pass ipaddr = self.debugServer.getHostAddress(True) if runInConsole or project.getDebugProperty("CONSOLEDEBUGGER"): ccmd = project.getDebugProperty("CONSOLECOMMAND") or \ Preferences.getDebugger("ConsoleDbgCommand") if ccmd: args = Utilities.parseOptionString(ccmd) + \ [interpreter, os.path.abspath(debugClient), noencoding, str(port), '0', ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) return process, self.__isNetworked, interpreter process = self.__startProcess( interpreter, [debugClient, noencoding, str(port), redirect, ipaddr], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be started.

""")) return process, self.__isNetworked, interpreter def getClientCapabilities(self): """ Public method to retrieve the debug clients capabilities. @return debug client capabilities (integer) """ return self.clientCapabilities def newConnection(self, sock): """ Public slot to handle a new connection. @param sock reference to the socket object (QTcpSocket) @return flag indicating success (boolean) """ # If we already have a connection, refuse this one. It will be closed # automatically. if self.qsock is not None: return False sock.disconnected.connect(self.debugServer.startClient) sock.readyRead.connect(self.__parseClientLine) self.qsock = sock # Get the remote clients capabilities self.remoteCapabilities() return True def flush(self): """ Public slot to flush the queue. """ # Send commands that were waiting for the connection. for cmd in self.queue: self.qsock.write(cmd.encode('utf8')) self.queue = [] def shutdown(self): """ Public method to cleanly shut down. It closes our socket and shuts down the debug client. (Needed on Win OS) """ if self.qsock is None: return # do not want any slots called during shutdown self.qsock.disconnected.disconnect(self.debugServer.startClient) self.qsock.readyRead.disconnect(self.__parseClientLine) # close down socket, and shut down client as well. self.__sendCommand('{0}\n'.format(DebugProtocol.RequestShutdown)) self.qsock.flush() self.qsock.close() # reinitialize self.qsock = None self.queue = [] def isConnected(self): """ Public method to test, if a debug client has connected. @return flag indicating the connection status (boolean) """ return self.qsock is not None def remoteEnvironment(self, env): """ Public method to set the environment for a program to debug, run, ... @param env environment settings (dictionary) """ self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestEnv, str(env))) def remoteLoad(self, fn, argv, wd, traceInterpreter=False, autoContinue=True, autoFork=False, forkChild=False): """ Public method to load a new program to debug. @param fn the filename to debug (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam traceInterpreter flag indicating if the interpreter library should be traced as well (boolean) @keyparam autoContinue flag indicating, that the debugger should not stop at the first executable line (boolean) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) """ self.__autoContinue = autoContinue self.__scriptName = os.path.abspath(fn) wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestForkMode, repr((autoFork, forkChild)))) self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( DebugProtocol.RequestLoad, wd, fn, str(Utilities.parseOptionString(argv)), traceInterpreter)) def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False): """ Public method to load a new program to run. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) """ self.__scriptName = os.path.abspath(fn) wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestForkMode, repr((autoFork, forkChild)))) self.__sendCommand('{0}{1}|{2}|{3}\n'.format( DebugProtocol.RequestRun, wd, fn, str(Utilities.parseOptionString(argv)))) def remoteCoverage(self, fn, argv, wd, erase=False): """ Public method to load a new program to collect coverage data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam erase flag indicating that coverage info should be cleared first (boolean) """ self.__scriptName = os.path.abspath(fn) wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}@@{2}@@{3}@@{4:d}\n'.format( DebugProtocol.RequestCoverage, wd, fn, str(Utilities.parseOptionString(argv)), erase)) def remoteProfile(self, fn, argv, wd, erase=False): """ Public method to load a new program to collect profiling data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam erase flag indicating that timing info should be cleared first (boolean) """ self.__scriptName = os.path.abspath(fn) wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( DebugProtocol.RequestProfile, wd, fn, str(Utilities.parseOptionString(argv)), erase)) def remoteStatement(self, stmt): """ Public method to execute a Python statement. @param stmt the Python statement to execute (string). It should not have a trailing newline. """ self.__sendCommand('{0}\n'.format(stmt)) self.__sendCommand(DebugProtocol.RequestOK + '\n') def remoteStep(self): """ Public method to single step the debugged program. """ self.__sendCommand(DebugProtocol.RequestStep + '\n') def remoteStepOver(self): """ Public method to step over the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepOver + '\n') def remoteStepOut(self): """ Public method to step out the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepOut + '\n') def remoteStepQuit(self): """ Public method to stop the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepQuit + '\n') def remoteContinue(self, special=False): """ Public method to continue the debugged program. @param special flag indicating a special continue operation (boolean) """ self.__sendCommand('{0}{1:d}\n'.format( DebugProtocol.RequestContinue, special)) def remoteBreakpoint(self, fn, line, set, cond=None, temp=False): """ Public method to set or clear a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param set flag indicating setting or resetting a breakpoint (boolean) @param cond condition of the breakpoint (string) @param temp flag indicating a temporary breakpoint (boolean) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1}@@{2:d}@@{3:d}@@{4:d}@@{5}\n'.format( DebugProtocol.RequestBreak, fn, line, temp, set, cond)) def remoteBreakpointEnable(self, fn, line, enable): """ Public method to enable or disable a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param enable flag indicating enabling or disabling a breakpoint (boolean) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format( DebugProtocol.RequestBreakEnable, fn, line, enable)) def remoteBreakpointIgnore(self, fn, line, count): """ Public method to ignore a breakpoint the next couple of occurrences. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param count number of occurrences to ignore (int) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format( DebugProtocol.RequestBreakIgnore, fn, line, count)) def remoteWatchpoint(self, cond, set, temp=False): """ Public method to set or clear a watch expression. @param cond expression of the watch expression (string) @param set flag indicating setting or resetting a watch expression (boolean) @param temp flag indicating a temporary watch expression (boolean) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1}@@{2:d}@@{3:d}\n'.format( DebugProtocol.RequestWatch, cond, temp, set)) def remoteWatchpointEnable(self, cond, enable): """ Public method to enable or disable a watch expression. @param cond expression of the watch expression (string) @param enable flag indicating enabling or disabling a watch expression (boolean) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1},{2:d}\n'.format( DebugProtocol.RequestWatchEnable, cond, enable)) def remoteWatchpointIgnore(self, cond, count): """ Public method to ignore a watch expression the next couple of occurrences. @param cond expression of the watch expression (string) @param count number of occurrences to ignore (int) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1},{2:d}\n'.format( DebugProtocol.RequestWatchIgnore, cond, count)) def remoteRawInput(self, s): """ Public method to send the raw input to the debugged program. @param s the raw input (string) """ self.__sendCommand(s + '\n') def remoteThreadList(self): """ Public method to request the list of threads from the client. """ self.__sendCommand('{0}\n'.format(DebugProtocol.RequestThreadList)) def remoteSetThread(self, tid): """ Public method to request to set the given thread as current thread. @param tid id of the thread (integer) """ self.__sendCommand('{0}{1:d}\n'.format( DebugProtocol.RequestThreadSet, tid)) def remoteClientVariables(self, scope, filter, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param framenr framenumber of the variables to retrieve (int) """ self.__sendCommand('{0}{1:d}, {2:d}, {3}\n'.format( DebugProtocol.RequestVariables, framenr, scope, str(filter))) def remoteClientVariable(self, scope, filter, var, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param var list encoded name of variable to retrieve (string) @param framenr framenumber of the variables to retrieve (int) """ self.__sendCommand('{0}{1}, {2:d}, {3:d}, {4}\n'.format( DebugProtocol.RequestVariable, str(var), framenr, scope, str(filter))) def remoteClientSetFilter(self, scope, filter): """ Public method to set a variables filter list. @param scope the scope of the variables (0 = local, 1 = global) @param filter regexp string for variable names to filter out (string) """ self.__sendCommand('{0}{1:d}, "{2}"\n'.format( DebugProtocol.RequestSetFilter, scope, filter)) def setCallTraceEnabled(self, on): """ Public method to set the call trace state. @param on flag indicating to enable the call trace function (boolean) """ if on: cmd = "on" else: cmd = "off" self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestCallTrace, cmd)) def remoteEval(self, arg): """ Public method to evaluate arg in the current context of the debugged program. @param arg the arguments to evaluate (string) """ self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestEval, arg)) def remoteExec(self, stmt): """ Public method to execute stmt in the current context of the debugged program. @param stmt statement to execute (string) """ self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestExec, stmt)) def remoteBanner(self): """ Public slot to get the banner info of the remote client. """ self.__sendCommand(DebugProtocol.RequestBanner + '\n') def remoteCapabilities(self): """ Public slot to get the debug clients capabilities. """ self.__sendCommand(DebugProtocol.RequestCapabilities + '\n') def remoteCompletion(self, text): """ Public slot to get the a list of possible commandline completions from the remote client. @param text the text to be completed (string) """ self.__sendCommand("{0}{1}\n".format( DebugProtocol.RequestCompletion, text)) def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase): """ Public method to prepare a new unittest run. @param fn the filename to load (string) @param tn the testname to load (string) @param tfn the test function name to load tests from (string) @param failed list of failed test, if only failed test should be run (list of strings) @param cov flag indicating collection of coverage data is requested (boolean) @param covname filename to be used to assemble the coverage caches filename (string) @param coverase flag indicating erasure of coverage data is requested (boolean) """ self.__scriptName = os.path.abspath(fn) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}|{2}|{3}|{4}|{5:d}|{6}|{7:d}\n'.format( DebugProtocol.RequestUTPrepare, fn, tn, tfn, str(failed), cov, covname, coverase)) def remoteUTRun(self): """ Public method to start a unittest run. """ self.__sendCommand('{0}\n'.format(DebugProtocol.RequestUTRun)) def remoteUTStop(self): """ Public method to stop a unittest run. """ self.__sendCommand('{0}\n'.format(DebugProtocol.RequestUTStop)) def __askForkTo(self): """ Private method to ask the user which branch of a fork to follow. """ selections = [self.tr("Parent Process"), self.tr("Child process")] res, ok = QInputDialog.getItem( None, self.tr("Client forking"), self.tr("Select the fork branch to follow."), selections, 0, False) if not ok or res == selections[0]: self.__sendCommand(DebugProtocol.ResponseForkTo + 'parent\n') else: self.__sendCommand(DebugProtocol.ResponseForkTo + 'child\n') def __parseClientLine(self): """ Private method to handle data from the client. """ while self.qsock and self.qsock.canReadLine(): qs = self.qsock.readLine() if self.codec is not None: line = self.codec.toUnicode(qs) else: line = bytes(qs).decode() if line.endswith(DebugProtocol.EOT): line = line[:-len(DebugProtocol.EOT)] if not line: continue ## print("Server: ", line) ##debug eoc = line.find('<') + 1 # Deal with case where user has written directly to stdout # or stderr, but not line terminated and we stepped over the # write call, in that case the >line< will not be the first # string read from the socket... boc = line.find('>') if boc > 0 and eoc > boc: self.debugServer.signalClientOutput(line[:boc]) line = line[boc:] eoc = line.find('<') + 1 boc = line.find('>') if boc >= 0 and eoc > boc: resp = line[boc:eoc] evalArg = self.__unicodeRe.sub(r"\1", line[eoc:-1]) if resp == DebugProtocol.ResponseLine or \ resp == DebugProtocol.ResponseStack: stack = eval(evalArg) for s in stack: s[0] = self.translate(s[0], True) cf = stack[0] if self.__autoContinue: self.__autoContinue = False QTimer.singleShot(0, self.remoteContinue) else: self.debugServer.signalClientLine( cf[0], int(cf[1]), resp == DebugProtocol.ResponseStack) self.debugServer.signalClientStack(stack) continue if resp == DebugProtocol.CallTrace: event, fromStr, toStr = line[eoc:-1].split("@@") isCall = event.lower() == "c" fromFile, fromLineno, fromFunc = fromStr.rsplit(":", 2) toFile, toLineno, toFunc = toStr.rsplit(":", 2) self.debugServer.signalClientCallTrace(isCall, fromFile, fromLineno, fromFunc, toFile, toLineno, toFunc) continue if resp == DebugProtocol.ResponseThreadList: currentId, threadList = eval(evalArg) self.debugServer.signalClientThreadList( currentId, threadList) continue if resp == DebugProtocol.ResponseThreadSet: self.debugServer.signalClientThreadSet() continue if resp == DebugProtocol.ResponseVariables: vlist = eval(evalArg) scope = vlist[0] try: variables = vlist[1:] except IndexError: variables = [] self.debugServer.signalClientVariables(scope, variables) continue if resp == DebugProtocol.ResponseVariable: vlist = eval(evalArg) scope = vlist[0] try: variables = vlist[1:] except IndexError: variables = [] self.debugServer.signalClientVariable(scope, variables) continue if resp == DebugProtocol.ResponseOK: self.debugServer.signalClientStatement(False) continue if resp == DebugProtocol.ResponseContinue: self.debugServer.signalClientStatement(True) continue if resp == DebugProtocol.ResponseException: exc = self.translate(evalArg, True) try: exclist = eval(exc) exctype = exclist[0] excmessage = exclist[1] stack = exclist[2:] if stack and stack[0] and stack[0][0] == "": for stackEntry in stack: if stackEntry[0] == "": stackEntry[0] = self.__scriptName else: break except (IndexError, ValueError, SyntaxError): exctype = None excmessage = '' stack = [] self.debugServer.signalClientException( exctype, excmessage, stack) continue if resp == DebugProtocol.ResponseSyntax: exc = self.translate(evalArg, True) try: message, (fn, ln, cn) = eval(exc) if fn is None: fn = '' except (IndexError, ValueError): message = None fn = '' ln = 0 cn = 0 if cn is None: cn = 0 self.debugServer.signalClientSyntaxError( message, fn, ln, cn) continue if resp == DebugProtocol.ResponseExit: self.__scriptName = "" self.debugServer.signalClientExit(evalArg) continue if resp == DebugProtocol.ResponseClearBreak: fn, lineno = evalArg.split(',') lineno = int(lineno) fn = self.translate(fn, True) self.debugServer.signalClientClearBreak(fn, lineno) continue if resp == DebugProtocol.ResponseBPConditionError: fn, lineno = evalArg.split(',') lineno = int(lineno) fn = self.translate(fn, True) self.debugServer.signalClientBreakConditionError( fn, lineno) continue if resp == DebugProtocol.ResponseClearWatch: self.debugServer.signalClientClearWatch(evalArg) continue if resp == DebugProtocol.ResponseWPConditionError: self.debugServer.signalClientWatchConditionError(evalArg) continue if resp == DebugProtocol.ResponseRaw: prompt, echo = eval(evalArg) self.debugServer.signalClientRawInput(prompt, echo) continue if resp == DebugProtocol.ResponseBanner: version, platform, dbgclient = eval(evalArg) self.debugServer.signalClientBanner( version, platform, dbgclient) continue if resp == DebugProtocol.ResponseCapabilities: cap, clType = eval(evalArg) self.clientCapabilities = cap self.debugServer.signalClientCapabilities(cap, clType) continue if resp == DebugProtocol.ResponseCompletion: clstring, text = evalArg.split('||') cl = eval(clstring) self.debugServer.signalClientCompletionList(cl, text) continue if resp == DebugProtocol.PassiveStartup: fn, exc = evalArg.split('|') exc = bool(exc) fn = self.translate(fn, True) self.debugServer.passiveStartUp(fn, exc) continue if resp == DebugProtocol.ResponseUTPrepared: res, exc_type, exc_value = eval(evalArg) self.debugServer.clientUtPrepared(res, exc_type, exc_value) continue if resp == DebugProtocol.ResponseUTStartTest: testname, doc = eval(evalArg) self.debugServer.clientUtStartTest(testname, doc) continue if resp == DebugProtocol.ResponseUTStopTest: self.debugServer.clientUtStopTest() continue if resp == DebugProtocol.ResponseUTTestFailed: testname, traceback, id = eval(evalArg) self.debugServer.clientUtTestFailed( testname, traceback, id) continue if resp == DebugProtocol.ResponseUTTestErrored: testname, traceback, id = eval(evalArg) self.debugServer.clientUtTestErrored( testname, traceback, id) continue if resp == DebugProtocol.ResponseUTTestSkipped: testname, reason, id = eval(line[eoc:-1]) self.debugServer.clientUtTestSkipped(testname, reason, id) continue if resp == DebugProtocol.ResponseUTTestFailedExpected: testname, traceback, id = eval(line[eoc:-1]) self.debugServer.clientUtTestFailedExpected( testname, traceback, id) continue if resp == DebugProtocol.ResponseUTTestSucceededUnexpected: testname, id = eval(line[eoc:-1]) self.debugServer.clientUtTestSucceededUnexpected( testname, id) continue if resp == DebugProtocol.ResponseUTFinished: self.debugServer.clientUtFinished() continue if resp == DebugProtocol.RequestForkTo: self.__askForkTo() continue self.debugServer.signalClientOutput(line) def __sendCommand(self, cmd): """ Private method to send a single line command to the client. @param cmd command to send to the debug client (string) """ if self.qsock is not None: self.qsock.write(cmd.encode('utf8')) else: self.queue.append(cmd) eric-6.0.8/eric/Debugger/CallStackViewer.py0000644000175000017500000001604612451233373017600 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing the Call Stack viewer widget. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QFileInfo from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QMenu from E5Gui.E5Application import e5App from E5Gui import E5FileDialog, E5MessageBox import Utilities class CallStackViewer(QTreeWidget): """ Class implementing the Call Stack viewer widget. @signal sourceFile(str, int) emitted to show the source of a stack entry @signal frameSelected(int) emitted to signal the selection of a frame entry """ sourceFile = pyqtSignal(str, int) frameSelected = pyqtSignal(int) FilenameRole = Qt.UserRole + 1 LinenoRole = Qt.UserRole + 2 def __init__(self, debugServer, parent=None): """ Constructor @param debugServer reference to the debug server object (DebugServer) @param parent reference to the parent widget (QWidget) """ super(CallStackViewer, self).__init__(parent) self.setHeaderHidden(True) self.setAlternatingRowColors(True) self.setItemsExpandable(False) self.setRootIsDecorated(False) self.setWindowTitle(self.tr("Call Stack")) self.__menu = QMenu(self) self.__sourceAct = self.__menu.addAction( self.tr("Show source"), self.__openSource) self.__menu.addAction(self.tr("Clear"), self.clear) self.__menu.addSeparator() self.__menu.addAction(self.tr("Save"), self.__saveStackTrace) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.__dbs = debugServer # file name, line number, function name, arguments self.__entryFormat = self.tr("File: {0}\nLine: {1}\n{2}{3}") # file name, line number self.__entryFormatShort = self.tr("File: {0}\nLine: {1}") self.__projectMode = False self.__project = None self.__dbs.clientStack.connect(self.__showCallStack) self.itemDoubleClicked.connect(self.__itemDoubleClicked) def setDebugger(self, debugUI): """ Public method to set a reference to the Debug UI. @param debugUI reference to the DebugUI object (DebugUI) """ debugUI.clientStack.connect(self.__showCallStack) def setProjectMode(self, enabled): """ Public slot to set the call trace viewer to project mode. In project mode the call trace info is shown with project relative path names. @param enabled flag indicating to enable the project mode (boolean) """ self.__projectMode = enabled if enabled and self.__project is None: self.__project = e5App().getObject("Project") def __showContextMenu(self, coord): """ Private slot to show the context menu. @param coord the position of the mouse pointer (QPoint) """ if self.topLevelItemCount() > 0: itm = self.currentItem() self.__sourceAct.setEnabled(itm is not None) self.__menu.popup(self.mapToGlobal(coord)) def __showCallStack(self, stack): """ Private slot to show the call stack of the program being debugged. @param stack list of tuples with call stack data (file name, line number, function name, formatted argument/values list) """ self.clear() for fname, fline, ffunc, fargs in stack: if self.__projectMode: dfname = self.__project.getRelativePath(fname) else: dfname = fname if ffunc and not ffunc.startswith("<"): # use normal format itm = QTreeWidgetItem( self, [self.__entryFormat.format(dfname, fline, ffunc, fargs)]) else: # use short format itm = QTreeWidgetItem( self, [self.__entryFormatShort.format(dfname, fline)]) itm.setData(0, self.FilenameRole, fname) itm.setData(0, self.LinenoRole, fline) self.resizeColumnToContents(0) def __itemDoubleClicked(self, itm): """ Private slot to handle a double click of a stack entry. @param itm reference to the double clicked item (QTreeWidgetItem) """ fname = itm.data(0, self.FilenameRole) fline = itm.data(0, self.LinenoRole) if self.__projectMode: fname = self.__project.getAbsolutePath(fname) self.sourceFile.emit(fname, fline) index = self.indexOfTopLevelItem(itm) self.frameSelected.emit(index) def __openSource(self): """ Private slot to show the source for the selected stack entry. """ itm = self.currentItem() if itm: self.__itemDoubleClicked(itm) def __saveStackTrace(self): """ Private slot to save the stack trace info to a file. """ if self.topLevelItemCount() > 0: fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Call Stack Info"), "", self.tr("Text Files (*.txt);;All Files (*)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fname: ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Call Stack Info"), self.tr("

The file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) try: f = open(fname, "w", encoding="utf-8") itm = self.topLevelItem(0) while itm is not None: f.write("{0}\n".format(itm.text(0))) f.write(78 * "=" + "\n") itm = self.itemBelow(itm) f.close() except IOError as err: E5MessageBox.critical( self, self.tr("Error saving Call Stack Info"), self.tr("""

The call stack info could not be""" """ written to {0}

""" """

Reason: {1}

""") .format(fname, str(err))) eric-6.0.8/eric/Debugger/EditWatchpointDialog.py0000644000175000017500000000747412451233373020630 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to edit watch expression properties. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_EditWatchpointDialog import Ui_EditWatchpointDialog class EditWatchpointDialog(QDialog, Ui_EditWatchpointDialog): """ Class implementing a dialog to edit watch expression properties. """ def __init__(self, properties, parent=None, name=None, modal=False): """ Constructor @param properties properties for the watch expression (tuple) (expression, temporary flag, enabled flag, ignore count, special condition) @param parent the parent of this dialog @param name the widget name of this dialog @param modal flag indicating a modal dialog """ super(EditWatchpointDialog, self).__init__(parent) self.setupUi(self) if name: self.setObjectName(name) self.setModal(modal) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) # connect our widgets self.conditionEdit.textChanged.connect(self.__textChanged) self.specialEdit.textChanged.connect(self.__textChanged) cond, temp, enabled, count, special = properties # set the condition if not special: self.conditionButton.setChecked(True) self.conditionEdit.setText(cond) else: self.specialButton.setChecked(True) self.specialEdit.setText(cond) ind = self.specialCombo.findText(special) if ind == -1: ind = 0 self.specialCombo.setCurrentIndex(ind) # set the ignore count self.ignoreSpinBox.setValue(count) # set the checkboxes self.temporaryCheckBox.setChecked(temp) self.enabledCheckBox.setChecked(enabled) if not special: self.conditionEdit.setFocus() else: self.specialEdit.setFocus() msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def __textChanged(self, txt): """ Private slot to handle the text changed signal of the condition line edit. @param txt text of the line edit (string) """ if self.conditionButton.isChecked(): self.buttonBox.button(QDialogButtonBox.Ok)\ .setEnabled(self.conditionEdit.text() != "") elif self.specialButton.isChecked(): self.buttonBox.button(QDialogButtonBox.Ok)\ .setEnabled(self.specialEdit.text() != "") else: # should not happen self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) def getData(self): """ Public method to retrieve the entered data. @return a tuple containing the watch expressions new properties (expression, temporary flag, enabled flag, ignore count, special condition) """ if self.conditionButton.isChecked(): return (self.conditionEdit.text(), self.temporaryCheckBox.isChecked(), self.enabledCheckBox.isChecked(), self.ignoreSpinBox.value(), "") elif self.specialButton.isChecked(): return (self.specialEdit.text(), self.temporaryCheckBox.isChecked(), self.enabledCheckBox.isChecked(), self.ignoreSpinBox.value(), self.specialCombo.currentText()) else: # should not happen return ("", False, False, 0, "") eric-6.0.8/eric/Debugger/DebugProtocol.py0000644000175000017500000000452412451233373017323 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module defining the debug protocol tokens. """ from __future__ import unicode_literals # The protocol "words". RequestOK = '>OK?<' RequestEnv = '>Environment<' RequestCapabilities = '>Capabilities<' RequestLoad = '>Load<' RequestRun = '>Run<' RequestCoverage = '>Coverage<' RequestProfile = '>Profile<' RequestContinue = '>Continue<' RequestStep = '>Step<' RequestStepOver = '>StepOver<' RequestStepOut = '>StepOut<' RequestStepQuit = '>StepQuit<' RequestBreak = '>Break<' RequestBreakEnable = '>EnableBreak<' RequestBreakIgnore = '>IgnoreBreak<' RequestWatch = '>Watch<' RequestWatchEnable = '>EnableWatch<' RequestWatchIgnore = '>IgnoreWatch<' RequestVariables = '>Variables<' RequestVariable = '>Variable<' RequestSetFilter = '>SetFilter<' RequestThreadList = '>ThreadList<' RequestThreadSet = '>ThreadSet<' RequestEval = '>Eval<' RequestExec = '>Exec<' RequestShutdown = '>Shutdown<' RequestBanner = '>Banner<' RequestCompletion = '>Completion<' RequestUTPrepare = '>UTPrepare<' RequestUTRun = '>UTRun<' RequestUTStop = '>UTStop<' RequestForkTo = '>ForkTo<' RequestForkMode = '>ForkMode<' ResponseOK = '>OK<' ResponseCapabilities = RequestCapabilities ResponseContinue = '>Continue<' ResponseException = '>Exception<' ResponseSyntax = '>SyntaxError<' ResponseExit = '>Exit<' ResponseLine = '>Line<' ResponseRaw = '>Raw<' ResponseClearBreak = '>ClearBreak<' ResponseBPConditionError = '>BPConditionError<' ResponseClearWatch = '>ClearWatch<' ResponseWPConditionError = '>WPConditionError<' ResponseVariables = RequestVariables ResponseVariable = RequestVariable ResponseThreadList = RequestThreadList ResponseThreadSet = RequestThreadSet ResponseStack = '>CurrentStack<' ResponseBanner = RequestBanner ResponseCompletion = RequestCompletion ResponseUTPrepared = '>UTPrepared<' ResponseUTStartTest = '>UTStartTest<' ResponseUTStopTest = '>UTStopTest<' ResponseUTTestFailed = '>UTTestFailed<' ResponseUTTestErrored = '>UTTestErrored<' ResponseUTTestSkipped = '>UTTestSkipped<' ResponseUTTestFailedExpected = '>UTTestFailedExpected<' ResponseUTTestSucceededUnexpected = '>UTTestSucceededUnexpected<' ResponseUTFinished = '>UTFinished<' ResponseForkTo = RequestForkTo PassiveStartup = '>PassiveStartup<' RequestCallTrace = '>CallTrace<' CallTrace = '>CallTrace<' EOT = '>EOT<\n' eric-6.0.8/eric/Debugger/VariableDetailDialog.ui0000644000175000017500000000564512060166051020527 0ustar piotrpiotr VariableDetailDialog 0 0 800 350 Variable Details true true Qt::Horizontal QDialogButtonBox::Ok Name: true true Type: Value: Qt::AlignTop true false qPixmapFromMimeSource eName eType eValue buttonBox accepted() VariableDetailDialog accept() 19 260 22 280 buttonBox rejected() VariableDetailDialog reject() 106 258 106 280 eric-6.0.8/eric/Debugger/CallTraceViewer.ui0000644000175000017500000000637012060166050017546 0ustar piotrpiotr CallTraceViewer 0 0 400 528 Call Trace Press to start tracing calls and returns Start Press to stop tracing calls and returns Stop Qt::Horizontal 40 20 Press to resize the columns to their contents Resize Press to clear the call trace Clear Press to save the call trace as a text file Save true false From To startTraceButton stopTraceButton resizeButton clearButton saveButton callTrace eric-6.0.8/eric/Debugger/Config.py0000644000175000017500000000527412451233373015763 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module defining the different Python types and their display strings. """ from __future__ import unicode_literals try: from PyQt5.QtCore import QT_TRANSLATE_NOOP # Variables type definition ConfigVarTypeDispStrings = [ QT_TRANSLATE_NOOP('Variable Types', 'Hidden Attributes'), QT_TRANSLATE_NOOP('Variable Types', 'None'), QT_TRANSLATE_NOOP('Variable Types', 'Type'), QT_TRANSLATE_NOOP('Variable Types', 'Boolean'), QT_TRANSLATE_NOOP('Variable Types', 'Integer'), QT_TRANSLATE_NOOP('Variable Types', 'Long Integer'), QT_TRANSLATE_NOOP('Variable Types', 'Float'), QT_TRANSLATE_NOOP('Variable Types', 'Complex'), QT_TRANSLATE_NOOP('Variable Types', 'String'), QT_TRANSLATE_NOOP('Variable Types', 'Unicode String'), QT_TRANSLATE_NOOP('Variable Types', 'Tuple'), QT_TRANSLATE_NOOP('Variable Types', 'List/Array'), QT_TRANSLATE_NOOP('Variable Types', 'Dictionary/Hash/Map'), QT_TRANSLATE_NOOP('Variable Types', 'Dictionary Proxy'), QT_TRANSLATE_NOOP('Variable Types', 'Set'), QT_TRANSLATE_NOOP('Variable Types', 'File'), QT_TRANSLATE_NOOP('Variable Types', 'X Range'), QT_TRANSLATE_NOOP('Variable Types', 'Slice'), QT_TRANSLATE_NOOP('Variable Types', 'Buffer'), QT_TRANSLATE_NOOP('Variable Types', 'Class'), QT_TRANSLATE_NOOP('Variable Types', 'Class Instance'), QT_TRANSLATE_NOOP('Variable Types', 'Class Method'), QT_TRANSLATE_NOOP('Variable Types', 'Class Property'), QT_TRANSLATE_NOOP('Variable Types', 'Generator'), QT_TRANSLATE_NOOP('Variable Types', 'Function'), QT_TRANSLATE_NOOP('Variable Types', 'Builtin Function'), QT_TRANSLATE_NOOP('Variable Types', 'Code'), QT_TRANSLATE_NOOP('Variable Types', 'Module'), QT_TRANSLATE_NOOP('Variable Types', 'Ellipsis'), QT_TRANSLATE_NOOP('Variable Types', 'Traceback'), QT_TRANSLATE_NOOP('Variable Types', 'Frame'), QT_TRANSLATE_NOOP('Variable Types', 'Other') ] except ImportError: # Variables type definition (for non-Qt only) ConfigVarTypeDispStrings = [ 'Hidden Attributes', 'None', 'Type', 'Boolean', 'Integer', 'Long Integer', 'Float', 'Complex', 'String', 'Unicode String', 'Tuple', 'List/Array', 'Dictionary/Hash/Map', 'Dictionary Proxy', 'Set', 'File', 'X Range', 'Slice', 'Buffer', 'Class', 'Class Instance', 'Class Method', 'Class Property', 'Generator', 'Function', 'Builtin Function', 'Code', 'Module', 'Ellipsis', 'Traceback', 'Frame', 'Other'] eric-6.0.8/eric/Debugger/EditWatchpointDialog.ui0000644000175000017500000001435012060166051020576 0ustar piotrpiotr EditWatchpointDialog 0 0 402 234 Edit Watch Expression true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Qt::Horizontal QSizePolicy::Expanding 211 20 Enter an ignore count for the watch expression 9999 Ignore Count: Select, whether the watch expression is enabled Enabled Select whether this is a temporary watch expression Temporary Watch Expression Variable: Expression: true false Enter a variable and select the special condition below false Select a special condition created changed Enter the expression for the watch expression qPixmapFromMimeSource conditionButton conditionEdit specialButton specialEdit specialCombo ignoreSpinBox temporaryCheckBox enabledCheckBox conditionButton toggled(bool) conditionEdit setEnabled(bool) 63 21 143 21 specialButton toggled(bool) specialCombo setEnabled(bool) 56 45 123 73 specialButton toggled(bool) specialEdit setEnabled(bool) 81 46 122 47 buttonBox accepted() EditWatchpointDialog accept() 16 202 16 217 buttonBox rejected() EditWatchpointDialog reject() 87 203 87 218 eric-6.0.8/eric/Debugger/EditBreakpointDialog.ui0000644000175000017500000001325512354033037020562 0ustar piotrpiotr EditBreakpointDialog 0 0 428 229 Edit Breakpoint true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Select, whether the breakpoint is enabled Enabled true Select whether this is a temporary breakpoint Temporary Breakpoint Enter the filename of the breakpoint true 0 0 Enter or select a condition for the breakpoint true Enter an ignore count for the breakpoint 9999 Qt::Horizontal QSizePolicy::Expanding 250 20 Enter the linenumber of the breakpoint 1 99999 Qt::Horizontal QSizePolicy::Expanding 200 20 Linenumber: Filename: Condition: Ignore Count: Press to open a file selection dialog qPixmapFromMimeSource filenameCombo linenoSpinBox fileButton conditionCombo ignoreSpinBox temporaryCheckBox enabledCheckBox buttonBox accepted() EditBreakpointDialog accept() 21 179 21 201 buttonBox rejected() EditBreakpointDialog reject() 97 187 97 204 eric-6.0.8/eric/Debugger/VariablesViewer.py0000644000175000017500000006254012451233373017647 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the variables viewer widget. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import Qt, QRegExp, qVersion, QCoreApplication from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView, \ QMenu from PyQt5.QtGui import QTextDocument # __IGNORE_WARNING__ from E5Gui.E5Application import e5App from DebugClients.Python3.DebugConfig import ConfigVarTypeStrings from .Config import ConfigVarTypeDispStrings import Preferences import Utilities class VariableItem(QTreeWidgetItem): """ Class implementing the data structure for variable items. """ def __init__(self, parent, dvar, dvalue, dtype): """ Constructor @param parent reference to the parent item @param dvar variable name (string) @param dvalue value string (string) @param dtype type string (string) """ self.__value = dvalue if len(dvalue) > 2048: # 1024 * 2 dvalue = QCoreApplication.translate( "VariableItem", "") self.__tooltip = dvalue else: if Qt.mightBeRichText(dvalue): self.__tooltip = Utilities.html_encode(dvalue) else: self.__tooltip = dvalue lines = dvalue.splitlines() if len(lines) > 1: # only show the first non-empty line; # indicate skipped lines by <...> at the # beginning and/or end index = 0 while index < len(lines) - 1 and lines[index] == "": index += 1 dvalue = "" if index > 0: dvalue += "<...>" dvalue += lines[index] if index < len(lines) - 1: dvalue += "<...>" super(VariableItem, self).__init__(parent, [dvar, dvalue, dtype]) self.populated = True def getValue(self): """ Public method to return the value of the item. @return value of the item (string) """ return self.__value def data(self, column, role): """ Public method to return the data for the requested role. This implementation changes the original behavior in a way, that the display data is returned as the tooltip for column 1. @param column column number (integer) @param role data role (Qt.ItemDataRole) @return requested data """ if column == 1 and role == Qt.ToolTipRole: return self.__tooltip return super(VariableItem, self).data(column, role) def attachDummy(self): """ Public method to attach a dummy sub item to allow for lazy population. """ QTreeWidgetItem(self, ["DUMMY"]) def deleteChildren(self): """ Public method to delete all children (cleaning the subtree). """ for itm in self.takeChildren(): del itm def key(self, column): """ Public method generating the key for this item. @param column the column to sort on (integer) @return text of the column (string) """ return self.text(column) def __lt__(self, other): """ Special method to check, if the item is less than the other one. @param other reference to item to compare against (QTreeWidgetItem) @return true, if this item is less than other (boolean) """ column = self.treeWidget().sortColumn() return self.key(column) < other.key(column) def expand(self): """ Public method to expand the item. Note: This is just a do nothing and should be overwritten. """ return def collapse(self): """ Public method to collapse the item. Note: This is just a do nothing and should be overwritten. """ return class SpecialVarItem(VariableItem): """ Class implementing a VariableItem that represents a special variable node. These special variable nodes are generated for classes, lists, tuples and dictionaries. """ def __init__(self, parent, dvar, dvalue, dtype, frmnr, scope): """ Constructor @param parent parent of this item @param dvar variable name (string) @param dvalue value string (string) @param dtype type string (string) @param frmnr frame number (0 is the current frame) (int) @param scope flag indicating global (1) or local (0) variables """ VariableItem.__init__(self, parent, dvar, dvalue, dtype) self.attachDummy() self.populated = False self.framenr = frmnr self.scope = scope def expand(self): """ Public method to expand the item. """ self.deleteChildren() self.populated = True pathlist = [self.text(0)] par = self.parent() # step 1: get a pathlist up to the requested variable while par is not None: pathlist.insert(0, par.text(0)) par = par.parent() # step 2: request the variable from the debugger filter = e5App().getObject("DebugUI").variablesFilter(self.scope) e5App().getObject("DebugServer").remoteClientVariable( self.scope, filter, pathlist, self.framenr) class ArrayElementVarItem(VariableItem): """ Class implementing a VariableItem that represents an array element. """ def __init__(self, parent, dvar, dvalue, dtype): """ Constructor @param parent parent of this item @param dvar variable name (string) @param dvalue value string (string) @param dtype type string (string) """ VariableItem.__init__(self, parent, dvar, dvalue, dtype) """ Array elements have numbers as names, but the key must be right justified and zero filled to 6 decimal places. Then element 2 will have a key of '000002' and appear before element 10 with a key of '000010' """ keyStr = self.text(0) self.arrayElementKey = "{0:6d}".format(int(keyStr)) def key(self, column): """ Public method generating the key for this item. @param column the column to sort on (integer) @return key of the item (string) """ if column == 0: return self.arrayElementKey else: return VariableItem.key(self, column) class SpecialArrayElementVarItem(SpecialVarItem): """ Class implementing a QTreeWidgetItem that represents a special array variable node. """ def __init__(self, parent, dvar, dvalue, dtype, frmnr, scope): """ Constructor @param parent parent of this item @param dvar variable name (string) @param dvalue value string (string) @param dtype type string (string) @param frmnr frame number (0 is the current frame) (int) @param scope flag indicating global (1) or local (0) variables """ SpecialVarItem.__init__(self, parent, dvar, dvalue, dtype, frmnr, scope) """ Array elements have numbers as names, but the key must be right justified and zero filled to 6 decimal places. Then element 2 will have a key of '000002' and appear before element 10 with a key of '000010' """ keyStr = self.text(0)[:-2] # strip off [], () or {} self.arrayElementKey = "{0:6d}".format(int(keyStr)) def key(self, column): """ Public method generating the key for this item. @param column the column to sort on (integer) @return key of the item (string) """ if column == 0: return self.arrayElementKey else: return SpecialVarItem.key(self, column) class VariablesViewer(QTreeWidget): """ Class implementing the variables viewer widget. This widget is used to display the variables of the program being debugged in a tree. Compound types will be shown with their main entry first. Once the subtree has been expanded, the individual entries will be shown. Double clicking an entry will popup a dialog showing the variables parameters in a more readable form. This is especially useful for lengthy strings. This widget has two modes for displaying the global and the local variables. """ def __init__(self, parent=None, scope=1): """ Constructor @param parent the parent (QWidget) @param scope flag indicating global (1) or local (0) variables """ super(VariablesViewer, self).__init__(parent) self.indicators = {'list': '[]', 'tuple': '()', 'dict': '{}', # Python types 'Array': '[]', 'Hash': '{}' # Ruby types } self.rx_class = QRegExp('<.*(instance|object) at 0x.*>') self.rx_class2 = QRegExp('class .*') self.rx_class3 = QRegExp('') self.dvar_rx_class1 = QRegExp( r'<.*(instance|object) at 0x.*>(\[\]|\{\}|\(\))') self.dvar_rx_class2 = QRegExp(r'(\[\]|\{\}|\(\))') self.dvar_rx_array_element = QRegExp(r'^\d+$') self.dvar_rx_special_array_element = QRegExp(r'^\d+(\[\]|\{\}|\(\))$') self.rx_nonprintable = QRegExp(r"""(\\x\d\d)+""") self.framenr = 0 self.loc = Preferences.getSystem("StringEncoding") self.openItems = [] self.setRootIsDecorated(True) self.setAlternatingRowColors(True) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.scope = scope if scope: self.setWindowTitle(self.tr("Global Variables")) self.setHeaderLabels([ self.tr("Globals"), self.tr("Value"), self.tr("Type")]) self.setWhatsThis(self.tr( """The Global Variables Viewer Window""" """

This window displays the global variables""" """ of the debugged program.

""" )) else: self.setWindowTitle(self.tr("Local Variables")) self.setHeaderLabels([ self.tr("Locals"), self.tr("Value"), self.tr("Type")]) self.setWhatsThis(self.tr( """The Local Variables Viewer Window""" """

This window displays the local variables""" """ of the debugged program.

""" )) header = self.header() header.setSortIndicator(0, Qt.AscendingOrder) header.setSortIndicatorShown(True) if qVersion() >= "5.0.0": header.setSectionsClickable(True) else: header.setClickable(True) header.resizeSection(0, 120) # variable column header.resizeSection(1, 150) # value column self.__createPopupMenus() self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.itemExpanded.connect(self.__expandItemSignal) self.itemCollapsed.connect(self.collapseItem) self.resortEnabled = True def __createPopupMenus(self): """ Private method to generate the popup menus. """ self.menu = QMenu() self.menu.addAction(self.tr("Show Details..."), self.__showDetails) self.menu.addSeparator() self.menu.addAction(self.tr("Configure..."), self.__configure) self.backMenu = QMenu() self.backMenu.addAction(self.tr("Configure..."), self.__configure) def __showContextMenu(self, coord): """ Private slot to show the context menu. @param coord the position of the mouse pointer (QPoint) """ gcoord = self.mapToGlobal(coord) if self.itemAt(coord) is not None: self.menu.popup(gcoord) else: self.backMenu.popup(gcoord) def __findItem(self, slist, column, node=None): """ Private method to search for an item. It is used to find a specific item in column, that is a child of node. If node is None, a child of the QTreeWidget is searched. @param slist searchlist (list of strings) @param column index of column to search in (int) @param node start point of the search @return the found item or None """ if node is None: count = self.topLevelItemCount() else: count = node.childCount() for index in range(count): if node is None: itm = self.topLevelItem(index) else: itm = node.child(index) if itm.text(column) == slist[0]: if len(slist) > 1: itm = self.__findItem(slist[1:], column, itm) return itm return None def showVariables(self, vlist, frmnr): """ Public method to show variables in a list. @param vlist the list of variables to be displayed. Each listentry is a tuple of three values.
  • the variable name (string)
  • the variables type (string)
  • the variables value (string)
@param frmnr frame number (0 is the current frame) (int) """ self.current = self.currentItem() if self.current: self.curpathlist = self.__buildTreePath(self.current) self.clear() self.__scrollToItem = None self.framenr = frmnr if len(vlist): self.resortEnabled = False for (var, vtype, value) in vlist: self.__addItem(None, vtype, var, value) # reexpand tree openItems = sorted(self.openItems[:]) self.openItems = [] for itemPath in openItems: itm = self.__findItem(itemPath, 0) if itm is not None: self.expandItem(itm) else: self.openItems.append(itemPath) if self.current: citm = self.__findItem(self.curpathlist, 0) if citm: self.setCurrentItem(citm) citm.setSelected(True) self.scrollToItem(citm, QAbstractItemView.PositionAtTop) self.current = None self.resortEnabled = True self.__resort() def showVariable(self, vlist): """ Public method to show variables in a list. @param vlist the list of subitems to be displayed. The first element gives the path of the parent variable. Each other listentry is a tuple of three values.
  • the variable name (string)
  • the variables type (string)
  • the variables value (string)
""" resortEnabled = self.resortEnabled self.resortEnabled = False if self.current is None: self.current = self.currentItem() if self.current: self.curpathlist = self.__buildTreePath(self.current) if vlist: itm = self.__findItem(vlist[0], 0) for var, vtype, value in vlist[1:]: self.__addItem(itm, vtype, var, value) # reexpand tree openItems = sorted(self.openItems[:]) self.openItems = [] for itemPath in openItems: itm = self.__findItem(itemPath, 0) if itm is not None and not itm.isExpanded(): if itm.populated: self.blockSignals(True) itm.setExpanded(True) self.blockSignals(False) else: self.expandItem(itm) self.openItems = openItems[:] if self.current: citm = self.__findItem(self.curpathlist, 0) if citm: self.setCurrentItem(citm) citm.setSelected(True) if self.__scrollToItem: self.scrollToItem(self.__scrollToItem, QAbstractItemView.PositionAtTop) else: self.scrollToItem(citm, QAbstractItemView.PositionAtTop) self.current = None elif self.__scrollToItem: self.scrollToItem(self.__scrollToItem, QAbstractItemView.PositionAtTop) self.resortEnabled = resortEnabled self.__resort() def __generateItem(self, parent, dvar, dvalue, dtype, isSpecial=False): """ Private method used to generate a VariableItem. @param parent parent of the item to be generated @param dvar variable name (string) @param dvalue value string (string) @param dtype type string (string) @param isSpecial flag indicating that a special node should be generated (boolean) @return The item that was generated (VariableItem). """ if isSpecial and \ (self.dvar_rx_class1.exactMatch(dvar) or self.dvar_rx_class2.exactMatch(dvar)): isSpecial = False if self.rx_class2.exactMatch(dtype): return SpecialVarItem(parent, dvar, dvalue, dtype[7:-1], self.framenr, self.scope) elif dtype != "void *" and \ (self.rx_class.exactMatch(dvalue) or self.rx_class3.exactMatch(dvalue) or isSpecial): if self.dvar_rx_special_array_element.exactMatch(dvar): return SpecialArrayElementVarItem(parent, dvar, dvalue, dtype, self.framenr, self.scope) else: return SpecialVarItem(parent, dvar, dvalue, dtype, self.framenr, self.scope) else: if self.dvar_rx_array_element.exactMatch(dvar): return ArrayElementVarItem(parent, dvar, dvalue, dtype) else: return VariableItem(parent, dvar, dvalue, dtype) def __addItem(self, parent, vtype, var, value): """ Private method used to add an item to the list. If the item is of a type with subelements (i.e. list, dictionary, tuple), these subelements are added by calling this method recursively. @param parent the parent of the item to be added (QTreeWidgetItem or None) @param vtype the type of the item to be added (string) @param var the variable name (string) @param value the value string (string) @return The item that was added to the listview (QTreeWidgetItem). """ if parent is None: parent = self try: dvar = '{0}{1}'.format(var, self.indicators[vtype]) except KeyError: dvar = var dvtype = self.__getDispType(vtype) if vtype in ['list', 'Array', 'tuple', 'dict', 'Hash']: itm = self.__generateItem(parent, dvar, self.tr("{0} items").format(value), dvtype, True) elif vtype in ['unicode', 'str']: if self.rx_nonprintable.indexIn(value) != -1: sval = value else: try: sval = eval(value) except: sval = value itm = self.__generateItem(parent, dvar, str(sval), dvtype) else: itm = self.__generateItem(parent, dvar, value, dvtype) return itm def __getDispType(self, vtype): """ Private method used to get the display string for type vtype. @param vtype the type, the display string should be looked up for (string) @return displaystring (string) """ try: i = ConfigVarTypeStrings.index(vtype) dvtype = self.tr(ConfigVarTypeDispStrings[i]) except ValueError: if vtype == 'classobj': dvtype = self.tr(ConfigVarTypeDispStrings[ ConfigVarTypeStrings.index('instance')]) else: dvtype = vtype return dvtype def mouseDoubleClickEvent(self, mouseEvent): """ Protected method of QAbstractItemView. Reimplemented to disable expanding/collapsing of items when double-clicking. Instead the double-clicked entry is opened. @param mouseEvent the mouse event object (QMouseEvent) """ itm = self.itemAt(mouseEvent.pos()) self.__showVariableDetails(itm) def __showDetails(self): """ Private slot to show details about the selected variable. """ itm = self.currentItem() self.__showVariableDetails(itm) def __showVariableDetails(self, itm): """ Private method to show details about a variable. @param itm reference to the variable item """ if itm is None: return val = itm.getValue() if not val: return # do not display anything, if the variable has no value vtype = itm.text(2) name = itm.text(0) if name[-2:] in ['[]', '{}', '()']: name = name[:-2] par = itm.parent() nlist = [name] # build up the fully qualified name while par is not None: pname = par.text(0) if pname[-2:] in ['[]', '{}', '()']: if nlist[0].endswith("."): nlist[0] = '[{0}].'.format(nlist[0][:-1]) else: nlist[0] = '[{0}]'.format(nlist[0]) nlist.insert(0, pname[:-2]) else: nlist.insert(0, '{0}.'.format(pname)) par = par.parent() name = ''.join(nlist) # now show the dialog from .VariableDetailDialog import VariableDetailDialog dlg = VariableDetailDialog(name, vtype, val) dlg.exec_() def __buildTreePath(self, itm): """ Private method to build up a path from the top to an item. @param itm item to build the path for (QTreeWidgetItem) @return list of names denoting the path from the top (list of strings) """ name = itm.text(0) pathlist = [name] par = itm.parent() # build up a path from the top to the item while par is not None: pname = par.text(0) pathlist.insert(0, pname) par = par.parent() return pathlist[:] def __expandItemSignal(self, parentItem): """ Private slot to handle the expanded signal. @param parentItem reference to the item being expanded (QTreeWidgetItem) """ self.expandItem(parentItem) self.__scrollToItem = parentItem def expandItem(self, parentItem): """ Public slot to handle the expanded signal. @param parentItem reference to the item being expanded (QTreeWidgetItem) """ pathlist = self.__buildTreePath(parentItem) self.openItems.append(pathlist) if parentItem.populated: return try: parentItem.expand() self.__resort() except AttributeError: super(VariablesViewer, self).expandItem(parentItem) def collapseItem(self, parentItem): """ Public slot to handle the collapsed signal. @param parentItem reference to the item being collapsed (QTreeWidgetItem) """ pathlist = self.__buildTreePath(parentItem) self.openItems.remove(pathlist) try: parentItem.collapse() except AttributeError: super(VariablesViewer, self).collapseItem(parentItem) def __resort(self): """ Private method to resort the tree. """ if self.resortEnabled: self.sortItems(self.sortColumn(), self.header().sortIndicatorOrder()) def handleResetUI(self): """ Public method to reset the VariablesViewer. """ self.clear() self.openItems = [] def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("debuggerGeneralPage") eric-6.0.8/eric/Debugger/VariablesFilterDialog.ui0000644000175000017500000000703212060166051020725 0ustar piotrpiotr Detlev Offenbach <detlev@die-offenbachs.de> VariablesFilterDialog 0 0 386 338 Variables Type Filter <b>Filter Dialog</b> <p> This dialog gives the user the possibility to select what kind of variables should <b>not</b> be shown during a debugging session.</p> true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok &Locals Filter localsList &Globals Filter globalsList Locals Filter List <b>Locals Filter List</b> <p>Select the variable types you want to be filtered out of the locals variables list.</p< QAbstractItemView::ExtendedSelection Globals Filter List <b>Globals Filter List</b> <p>Select the variable types you want to be filtered out of the globals variables list.</p< QAbstractItemView::ExtendedSelection qPixmapFromMimeSource localsList globalsList buttonBox accepted() VariablesFilterDialog accept() 14 319 15 332 buttonBox rejected() VariablesFilterDialog reject() 84 317 84 336 eric-6.0.8/eric/Debugger/WatchPointModel.py0000644000175000017500000002336212451233373017615 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the Watch expression model. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QAbstractItemModel, QModelIndex class WatchPointModel(QAbstractItemModel): """ Class implementing a custom model for watch expressions. """ dataAboutToBeChanged = pyqtSignal(QModelIndex, QModelIndex) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QObject) """ super(WatchPointModel, self).__init__(parent) self.watchpoints = [] self.header = [ self.tr("Condition"), self.tr("Special"), self.tr('Temporary'), self.tr('Enabled'), self.tr('Ignore Count'), ] self.alignments = [Qt.Alignment(Qt.AlignLeft), Qt.Alignment(Qt.AlignLeft), Qt.Alignment(Qt.AlignHCenter), Qt.Alignment(Qt.AlignHCenter), Qt.Alignment(Qt.AlignRight), ] def columnCount(self, parent=QModelIndex()): """ Public method to get the current column count. @param parent index of the parent item (QModelIndex) @return column count (integer) """ return len(self.header) def rowCount(self, parent=QModelIndex()): """ Public method to get the current row count. @param parent index of the parent item (QModelIndex) @return row count (integer) """ # we do not have a tree, parent should always be invalid if not parent.isValid(): return len(self.watchpoints) else: return 0 def data(self, index, role): """ Public method to get the requested data. @param index index of the requested data (QModelIndex) @param role role of the requested data (Qt.ItemDataRole) @return the requested data """ if not index.isValid(): return None if role == Qt.DisplayRole: if index.column() in [0, 1, 4]: return self.watchpoints[index.row()][index.column()] if role == Qt.CheckStateRole: if index.column() in [2, 3]: return self.watchpoints[index.row()][index.column()] if role == Qt.ToolTipRole: if index.column() in [0, 1]: return self.watchpoints[index.row()][index.column()] if role == Qt.TextAlignmentRole: if index.column() < len(self.alignments): return self.alignments[index.column()] return None def flags(self, index): """ Public method to get item flags. @param index index of the requested flags (QModelIndex) @return item flags for the given index (Qt.ItemFlags) """ if not index.isValid(): return Qt.ItemIsEnabled return Qt.ItemIsEnabled | Qt.ItemIsSelectable def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get header data. @param section section number of the requested header data (integer) @param orientation orientation of the header (Qt.Orientation) @param role role of the requested data (Qt.ItemDataRole) @return header data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: if section >= len(self.header): return "" else: return self.header[section] return None def index(self, row, column, parent=QModelIndex()): """ Public method to create an index. @param row row number for the index (integer) @param column column number for the index (integer) @param parent index of the parent item (QModelIndex) @return requested index (QModelIndex) """ if parent.isValid() or \ row < 0 or row >= len(self.watchpoints) or \ column < 0 or column >= len(self.header): return QModelIndex() return self.createIndex(row, column, self.watchpoints[row]) def parent(self, index): """ Public method to get the parent index. @param index index of item to get parent (QModelIndex) @return index of parent (QModelIndex) """ return QModelIndex() def hasChildren(self, parent=QModelIndex()): """ Public method to check for the presence of child items. @param parent index of parent item (QModelIndex) @return flag indicating the presence of child items (boolean) """ if not parent.isValid(): return len(self.watchpoints) > 0 else: return False ########################################################################### def addWatchPoint(self, cond, special, properties): """ Public method to add a new watch expression to the list. @param cond expression of the watch expression (string) @param special special condition of the watch expression (string) @param properties properties of the watch expression (tuple of temporary flag (bool), enabled flag (bool), ignore count (integer)) """ wp = [cond, special] + list(properties) cnt = len(self.watchpoints) self.beginInsertRows(QModelIndex(), cnt, cnt) self.watchpoints.append(wp) self.endInsertRows() def setWatchPointByIndex(self, index, cond, special, properties): """ Public method to set the values of a watch expression given by index. @param index index of the watch expression (QModelIndex) @param cond expression of the watch expression (string) @param special special condition of the watch expression (string) @param properties properties of the watch expression (tuple of temporary flag (bool), enabled flag (bool), ignore count (integer)) """ if index.isValid(): row = index.row() index1 = self.createIndex(row, 0, self.watchpoints[row]) index2 = self.createIndex( row, len(self.watchpoints[row]), self.watchpoints[row]) self.dataAboutToBeChanged.emit(index1, index2) i = 0 for value in [cond, special] + list(properties): self.watchpoints[row][i] = value i += 1 self.dataChanged.emit(index1, index2) def setWatchPointEnabledByIndex(self, index, enabled): """ Public method to set the enabled state of a watch expression given by index. @param index index of the watch expression (QModelIndex) @param enabled flag giving the enabled state (boolean) """ if index.isValid(): row = index.row() col = 3 index1 = self.createIndex(row, col, self.watchpoints[row]) self.dataAboutToBeChanged.emit(index1, index1) self.watchpoints[row][col] = enabled self.dataChanged.emit(index1, index1) def deleteWatchPointByIndex(self, index): """ Public method to set the values of a watch expression given by index. @param index index of the watch expression (QModelIndex) """ if index.isValid(): row = index.row() self.beginRemoveRows(QModelIndex(), row, row) del self.watchpoints[row] self.endRemoveRows() def deleteWatchPoints(self, idxList): """ Public method to delete a list of watch expressions given by their indexes. @param idxList list of watch expression indexes (list of QModelIndex) """ rows = [] for index in idxList: if index.isValid(): rows.append(index.row()) rows.sort(reverse=True) for row in rows: self.beginRemoveRows(QModelIndex(), row, row) del self.watchpoints[row] self.endRemoveRows() def deleteAll(self): """ Public method to delete all watch expressions. """ if self.watchpoints: self.beginRemoveRows(QModelIndex(), 0, len(self.watchpoints) - 1) self.watchpoints = [] self.endRemoveRows() def getWatchPointByIndex(self, index): """ Public method to get the values of a watch expression given by index. @param index index of the watch expression (QModelIndex) @return watch expression (list of six values (expression, special condition, temporary flag, enabled flag, ignore count, index)) """ if index.isValid(): return self.watchpoints[index.row()][:] # return a copy else: return [] def getWatchPointIndex(self, cond, special=""): """ Public method to get the index of a watch expression given by expression. @param cond expression of the watch expression (string) @param special special condition of the watch expression (string) @return index (QModelIndex) """ for row in range(len(self.watchpoints)): wp = self.watchpoints[row] if wp[0] == cond: if special and wp[1] != special: continue return self.createIndex(row, 0, self.watchpoints[row]) return QModelIndex() eric-6.0.8/eric/Debugger/VariableDetailDialog.py0000644000175000017500000000205512451233373020540 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing the variable detail dialog. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_VariableDetailDialog import Ui_VariableDetailDialog class VariableDetailDialog(QDialog, Ui_VariableDetailDialog): """ Class implementing the variable detail dialog. This dialog shows the name, the type and the value of a variable in a read only dialog. It is opened upon a double click in the variables viewer widget. """ def __init__(self, var, vtype, value): """ Constructor @param var the variables name (string) @param vtype the variables type (string) @param value the variables value (string) """ super(VariableDetailDialog, self).__init__() self.setupUi(self) # set the different fields self.eName.setText(var) self.eType.setText(vtype) self.eValue.setPlainText(value) eric-6.0.8/eric/Debugger/VariablesFilterDialog.py0000644000175000017500000000626512451233373020755 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the variables filter dialog. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog, QDialogButtonBox from Debugger.Config import ConfigVarTypeDispStrings import Preferences from .Ui_VariablesFilterDialog import Ui_VariablesFilterDialog class VariablesFilterDialog(QDialog, Ui_VariablesFilterDialog): """ Class implementing the variables filter dialog. It opens a dialog window for the configuration of the variables type filter to be applied during a debugging session. """ def __init__(self, parent=None, name=None, modal=False): """ Constructor @param parent parent widget of this dialog (QWidget) @param name name of this dialog (string) @param modal flag to indicate a modal dialog (boolean) """ super(VariablesFilterDialog, self).__init__(parent) if name: self.setObjectName(name) self.setModal(modal) self.setupUi(self) self.defaultButton = self.buttonBox.addButton( self.tr("Save Default"), QDialogButtonBox.ActionRole) lDefaultFilter, gDefaultFilter = Preferences.getVarFilters() #populate the listboxes and set the default selection for lb in self.localsList, self.globalsList: for ts in ConfigVarTypeDispStrings: lb.addItem(self.tr(ts)) for filterIndex in lDefaultFilter: itm = self.localsList.item(filterIndex) itm.setSelected(True) for filterIndex in gDefaultFilter: itm = self.globalsList.item(filterIndex) itm.setSelected(True) def getSelection(self): """ Public slot to retrieve the current selections. @return A tuple of lists of integer values. The first list is the locals variables filter, the second the globals variables filter. """ lList = [] gList = [] for i in range(self.localsList.count()): itm = self.localsList.item(i) if itm.isSelected(): lList.append(i) for i in range(self.globalsList.count()): itm = self.globalsList.item(i) if itm.isSelected(): gList.append(i) return (lList, gList) def setSelection(self, lList, gList): """ Public slot to set the current selection. @param lList local variables filter (list of int) @param gList global variables filter (list of int) """ for filterIndex in lList: itm = self.localsList.item(filterIndex) itm.setSelected(True) for filterIndex in gList: itm = self.globalsList.item(filterIndex) itm.setSelected(True) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.defaultButton: Preferences.setVarFilters(self.getSelection()) eric-6.0.8/eric/Debugger/CallTraceViewer.py0000644000175000017500000002216012451233373017563 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing the Call Trace viewer widget. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QRegExp, QFileInfo from PyQt5.QtWidgets import QWidget, QTreeWidgetItem from E5Gui.E5Application import e5App from E5Gui import E5FileDialog, E5MessageBox from .Ui_CallTraceViewer import Ui_CallTraceViewer import UI.PixmapCache import Preferences import Utilities class CallTraceViewer(QWidget, Ui_CallTraceViewer): """ Class implementing the Call Trace viewer widget. @signal sourceFile(str, int) emitted to show the source of a call/return point """ sourceFile = pyqtSignal(str, int) def __init__(self, debugServer, parent=None): """ Constructor @param debugServer reference to the debug server object (DebugServer) @param parent reference to the parent widget (QWidget) """ super(CallTraceViewer, self).__init__(parent) self.setupUi(self) self.__dbs = debugServer self.startTraceButton.setIcon( UI.PixmapCache.getIcon("callTraceStart.png")) self.stopTraceButton.setIcon( UI.PixmapCache.getIcon("callTraceStop.png")) self.resizeButton.setIcon(UI.PixmapCache.getIcon("resizeColumns.png")) self.clearButton.setIcon(UI.PixmapCache.getIcon("editDelete.png")) self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSave.png")) self.__headerItem = QTreeWidgetItem( ["", self.tr("From"), self.tr("To")]) self.__headerItem.setIcon(0, UI.PixmapCache.getIcon("callReturn.png")) self.callTrace.setHeaderItem(self.__headerItem) self.__callStack = [] self.__entryFormat = "{0}:{1} ({2})" self.__entryRe = QRegExp(r"""(.+):(\d+)\s\((.*)\)""") self.__projectMode = False self.__project = None self.__callTraceEnabled = Preferences.toBool( Preferences.Prefs.settings.value("CallTrace/Enabled", False)) if self.__callTraceEnabled: self.startTraceButton.setEnabled(False) else: self.stopTraceButton.setEnabled(False) self.__dbs.callTraceInfo.connect(self.__addCallTraceInfo) def __setCallTraceEnabled(self, enabled): """ Private slot to set the call trace enabled status. @param enabled flag indicating the new state (boolean) """ self.__dbs.setCallTraceEnabled(enabled) self.stopTraceButton.setEnabled(enabled) self.startTraceButton.setEnabled(not enabled) self.__callTraceEnabled = enabled Preferences.Prefs.settings.setValue("CallTrace/Enabled", enabled) @pyqtSlot() def on_startTraceButton_clicked(self): """ Private slot to start call tracing. """ self.__setCallTraceEnabled(True) @pyqtSlot() def on_stopTraceButton_clicked(self): """ Private slot to start call tracing. """ self.__setCallTraceEnabled(False) @pyqtSlot() def on_resizeButton_clicked(self): """ Private slot to resize the columns of the call trace to their contents. """ for column in range(self.callTrace.columnCount()): self.callTrace.resizeColumnToContents(column) @pyqtSlot() def on_clearButton_clicked(self): """ Private slot to clear the call trace. """ self.clear() @pyqtSlot() def on_saveButton_clicked(self): """ Private slot to save the call trace info to a file. """ if self.callTrace.topLevelItemCount() > 0: fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Call Trace Info"), "", self.tr("Text Files (*.txt);;All Files (*)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fname: ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Call Trace Info"), self.tr("

The file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) try: f = open(fname, "w", encoding="utf-8") itm = self.callTrace.topLevelItem(0) while itm is not None: isCall = itm.data(0, Qt.UserRole) if isCall: call = "->" else: call = "<-" f.write("{0} {1} || {2}\n".format( call, itm.text(1), itm.text(2))) itm = self.callTrace.itemBelow(itm) f.close() except IOError as err: E5MessageBox.critical( self, self.tr("Error saving Call Trace Info"), self.tr("""

The call trace info could not""" """ be written to {0}

""" """

Reason: {1}

""") .format(fname, str(err))) @pyqtSlot(QTreeWidgetItem, int) def on_callTrace_itemDoubleClicked(self, item, column): """ Private slot to open the double clicked file in an editor. @param item reference to the double clicked item (QTreeWidgetItem) @param column column that was double clicked (integer) """ if item is not None and column > 0: columnStr = item.text(column) if self.__entryRe.exactMatch(columnStr.strip()): filename, lineno, func = self.__entryRe.capturedTexts()[1:] try: lineno = int(lineno) except ValueError: # do nothing, if the line info is not an integer return if self.__projectMode: filename = self.__project.getAbsolutePath(filename) self.sourceFile.emit(filename, lineno) def clear(self): """ Public slot to clear the call trace info. """ self.callTrace.clear() self.__callStack = [] def setProjectMode(self, enabled): """ Public slot to set the call trace viewer to project mode. In project mode the call trace info is shown with project relative path names. @param enabled flag indicating to enable the project mode (boolean) """ self.__projectMode = enabled if enabled and self.__project is None: self.__project = e5App().getObject("Project") def __addCallTraceInfo(self, isCall, fromFile, fromLine, fromFunction, toFile, toLine, toFunction): """ Private method to add an entry to the call trace viewer. @param isCall flag indicating a 'call' (boolean) @param fromFile name of the originating file (string) @param fromLine line number in the originating file (string) @param fromFunction name of the originating function (string) @param toFile name of the target file (string) @param toLine line number in the target file (string) @param toFunction name of the target function (string) """ if isCall: icon = UI.PixmapCache.getIcon("forward.png") else: icon = UI.PixmapCache.getIcon("back.png") parentItem = \ self.__callStack[-1] if self.__callStack else self.callTrace if self.__projectMode: fromFile = self.__project.getRelativePath(fromFile) toFile = self.__project.getRelativePath(toFile) itm = QTreeWidgetItem( parentItem, ["", self.__entryFormat.format(fromFile, fromLine, fromFunction), self.__entryFormat.format(toFile, toLine, toFunction)]) itm.setIcon(0, icon) itm.setData(0, Qt.UserRole, isCall) itm.setExpanded(True) if isCall: self.__callStack.append(itm) else: if self.__callStack: self.__callStack.pop(-1) def isCallTraceEnabled(self): """ Public method to get the state of the call trace function. @return flag indicating the state of the call trace function (boolean) """ return self.__callTraceEnabled eric-6.0.8/eric/Debugger/DebuggerInterfaceNone.py0000644000175000017500000003232212451233373020735 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dummy debugger interface for the debug server. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject ClientDefaultCapabilities = 0 ClientTypeAssociations = [] def getRegistryData(): """ Module functionto get characterising data for the debugger interface. @return list of the following data. Client type (string), client capabilities (integer), client type association (list of strings) """ return ["None", ClientDefaultCapabilities, ClientTypeAssociations] class DebuggerInterfaceNone(QObject): """ Class implementing a dummy debugger interface for the debug server. """ def __init__(self, debugServer, passive): """ Constructor @param debugServer reference to the debug server (DebugServer) @param passive flag indicating passive connection mode (boolean) """ super(DebuggerInterfaceNone, self).__init__() self.debugServer = debugServer self.passive = passive self.qsock = None self.queue = [] # set default values for capabilities of clients self.clientCapabilities = ClientDefaultCapabilities def startRemote(self, port, runInConsole): """ Public method to start a remote Python interpreter. @param port portnumber the debug server is listening on (integer) @param runInConsole flag indicating to start the debugger in a console window (boolean) @return client process object (QProcess), a flag to indicate a network connection (boolean) and the name of the interpreter in case of a local execution (string) """ return None, True, "" def startRemoteForProject(self, port, runInConsole): """ Public method to start a remote Python interpreter for a project. @param port portnumber the debug server is listening on (integer) @param runInConsole flag indicating to start the debugger in a console window (boolean) @return client process object (QProcess), a flag to indicate a network connection (boolean) and the name of the interpreter in case of a local execution (string) """ return None, True, "" def getClientCapabilities(self): """ Public method to retrieve the debug clients capabilities. @return debug client capabilities (integer) """ return self.clientCapabilities def newConnection(self, sock): """ Public slot to handle a new connection. @param sock reference to the socket object (QTcpSocket) @return flag indicating success (boolean) """ return False def flush(self): """ Public slot to flush the queue. """ self.queue = [] def shutdown(self): """ Public method to cleanly shut down. It closes our socket and shuts down the debug client. (Needed on Win OS) """ self.qsock = None self.queue = [] def isConnected(self): """ Public method to test, if a debug client has connected. @return flag indicating the connection status (boolean) """ return self.qsock is not None def remoteEnvironment(self, env): """ Public method to set the environment for a program to debug, run, ... @param env environment settings (dictionary) """ return def remoteLoad(self, fn, argv, wd, traceInterpreter=False, autoContinue=True, autoFork=False, forkChild=False): """ Public method to load a new program to debug. @param fn the filename to debug (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam traceInterpreter flag indicating if the interpreter library should be traced as well (boolean) @keyparam autoContinue flag indicating, that the debugger should not stop at the first executable line (boolean) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) """ return def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False): """ Public method to load a new program to run. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) """ return def remoteCoverage(self, fn, argv, wd, erase=False): """ Public method to load a new program to collect coverage data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam erase flag indicating that coverage info should be cleared first (boolean) """ return def remoteProfile(self, fn, argv, wd, erase=False): """ Public method to load a new program to collect profiling data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam erase flag indicating that timing info should be cleared first (boolean) """ return def remoteStatement(self, stmt): """ Public method to execute a Python statement. @param stmt the Python statement to execute (string). It should not have a trailing newline. """ self.debugServer.signalClientStatement(False) return def remoteStep(self): """ Public method to single step the debugged program. """ return def remoteStepOver(self): """ Public method to step over the debugged program. """ return def remoteStepOut(self): """ Public method to step out the debugged program. """ return def remoteStepQuit(self): """ Public method to stop the debugged program. """ return def remoteContinue(self, special=False): """ Public method to continue the debugged program. @param special flag indicating a special continue operation """ return def remoteBreakpoint(self, fn, line, set, cond=None, temp=False): """ Public method to set or clear a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param set flag indicating setting or resetting a breakpoint (boolean) @param cond condition of the breakpoint (string) @param temp flag indicating a temporary breakpoint (boolean) """ return def remoteBreakpointEnable(self, fn, line, enable): """ Public method to enable or disable a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param enable flag indicating enabling or disabling a breakpoint (boolean) """ return def remoteBreakpointIgnore(self, fn, line, count): """ Public method to ignore a breakpoint the next couple of occurrences. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param count number of occurrences to ignore (int) """ return def remoteWatchpoint(self, cond, set, temp=False): """ Public method to set or clear a watch expression. @param cond expression of the watch expression (string) @param set flag indicating setting or resetting a watch expression (boolean) @param temp flag indicating a temporary watch expression (boolean) """ return def remoteWatchpointEnable(self, cond, enable): """ Public method to enable or disable a watch expression. @param cond expression of the watch expression (string) @param enable flag indicating enabling or disabling a watch expression (boolean) """ return def remoteWatchpointIgnore(self, cond, count): """ Public method to ignore a watch expression the next couple of occurrences. @param cond expression of the watch expression (string) @param count number of occurrences to ignore (int) """ return def remoteRawInput(self, s): """ Public method to send the raw input to the debugged program. @param s the raw input (string) """ return def remoteThreadList(self): """ Public method to request the list of threads from the client. """ return def remoteSetThread(self, tid): """ Public method to request to set the given thread as current thread. @param tid id of the thread (integer) """ return def remoteClientVariables(self, scope, filter, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param framenr framenumber of the variables to retrieve (int) """ return def remoteClientVariable(self, scope, filter, var, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param var list encoded name of variable to retrieve (string) @param framenr framenumber of the variables to retrieve (int) """ return def remoteClientSetFilter(self, scope, filter): """ Public method to set a variables filter list. @param scope the scope of the variables (0 = local, 1 = global) @param filter regexp string for variable names to filter out (string) """ return def setCallTraceEnabled(self, on): """ Public method to set the call trace state. @param on flag indicating to enable the call trace function (boolean) """ return def remoteEval(self, arg): """ Public method to evaluate arg in the current context of the debugged program. @param arg the arguments to evaluate (string) """ return def remoteExec(self, stmt): """ Public method to execute stmt in the current context of the debugged program. @param stmt statement to execute (string) """ return def remoteBanner(self): """ Public slot to get the banner info of the remote client. """ self.debugServer.signalClientBanner("No backend", "", "") return def remoteCapabilities(self): """ Public slot to get the debug clients capabilities. """ return def remoteCompletion(self, text): """ Public slot to get the a list of possible commandline completions from the remote client. @param text the text to be completed (string) """ return def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase): """ Public method to prepare a new unittest run. @param fn the filename to load (string) @param tn the testname to load (string) @param tfn the test function name to load tests from (string) @param failed list of failed test, if only failed test should be run (list of strings) @param cov flag indicating collection of coverage data is requested (boolean) @param covname filename to be used to assemble the coverage caches filename (string) @param coverase flag indicating erasure of coverage data is requested (boolean) """ return def remoteUTRun(self): """ Public method to start a unittest run. """ return def remoteUTStop(self): """ public method to stop a unittest run. """ return eric-6.0.8/eric/Debugger/ExceptionsFilterDialog.ui0000644000175000017500000001054312060166051021137 0ustar piotrpiotr ExceptionsFilterDialog 0 0 464 385 Exceptions Filter <b>Exception Filter</b> <p>This dialog is used to enter the exception types, that shall be highlighted during a debugging session. If this list is empty, all exception types will be highlighted. If the exception reporting flag in the "Start Debugging" dialog is unchecked, no exception will be reported at all.</p> <p>Please note, that unhandled exceptions are always highlighted independent of these settings.</p> true List of exceptions that shall be highlighted true false Press to add the entered exception to the list Add Enter an exception type that shall be highlighted false Press to delete the selected exception from the list Delete Press to delete all exceptions from the list Delete All Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource exceptionList exceptionEdit addButton deleteButton deleteAllButton buttonBox buttonBox accepted() ExceptionsFilterDialog accept() 26 309 26 325 buttonBox rejected() ExceptionsFilterDialog reject() 85 310 85 324 eric-6.0.8/eric/Debugger/DebuggerInterfaceRuby.py0000644000175000017500000010616012451233373020761 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Ruby debugger interface for the debug server. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, QTextCodec, QProcess, QProcessEnvironment, \ QTimer from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from . import DebugProtocol from . import DebugClientCapabilities import Preferences import Utilities from eric6config import getConfig ClientDefaultCapabilities = \ DebugClientCapabilities.HasDebugger | \ DebugClientCapabilities.HasShell | \ DebugClientCapabilities.HasInterpreter | \ DebugClientCapabilities.HasCompleter ClientTypeAssociations = [".rb"] def getRegistryData(): """ Module function to get characterising data for the debugger interface. @return list of the following data. Client type (string), client capabilities (integer), client type association (list of strings) """ if Preferences.getDebugger("RubyInterpreter"): return ["Ruby", ClientDefaultCapabilities, ClientTypeAssociations] else: return ["", 0, []] class DebuggerInterfaceRuby(QObject): """ Class implementing the Ruby debugger interface for the debug server. """ def __init__(self, debugServer, passive): """ Constructor @param debugServer reference to the debug server (DebugServer) @param passive flag indicating passive connection mode (boolean) """ super(DebuggerInterfaceRuby, self).__init__() self.__isNetworked = True self.__autoContinue = not passive self.debugServer = debugServer self.passive = passive self.process = None self.qsock = None self.queue = [] # set default values for capabilities of clients self.clientCapabilities = ClientDefaultCapabilities # set translation function self.translate = self.__identityTranslation self.codec = QTextCodec.codecForName( str(Preferences.getSystem("StringEncoding"))) if passive: # set translation function if Preferences.getDebugger("PathTranslation"): self.translateRemote = \ Preferences.getDebugger("PathTranslationRemote") self.translateLocal = \ Preferences.getDebugger("PathTranslationLocal") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation def __identityTranslation(self, fn, remote2local=True): """ Private method to perform the identity path translation. @param fn filename to be translated (string) @param remote2local flag indicating the direction of translation (False = local to remote, True = remote to local [default]) @return translated filename (string) """ return fn def __remoteTranslation(self, fn, remote2local=True): """ Private method to perform the path translation. @param fn filename to be translated (string) @param remote2local flag indicating the direction of translation (False = local to remote, True = remote to local [default]) @return translated filename (string) """ if remote2local: return fn.replace(self.translateRemote, self.translateLocal) else: return fn.replace(self.translateLocal, self.translateRemote) def __startProcess(self, program, arguments, environment=None): """ Private method to start the debugger client process. @param program name of the executable to start (string) @param arguments arguments to be passed to the program (list of string) @param environment dictionary of environment settings to pass (dict of string) @return the process object (QProcess) or None """ proc = QProcess() if environment is not None: env = QProcessEnvironment() for key, value in list(environment.items()): env.insert(key, value) proc.setProcessEnvironment(env) args = [] for arg in arguments: args.append(arg) proc.start(program, args) if not proc.waitForStarted(10000): proc = None return proc def startRemote(self, port, runInConsole): """ Public method to start a remote Ruby interpreter. @param port portnumber the debug server is listening on (integer) @param runInConsole flag indicating to start the debugger in a console window (boolean) @return client process object (QProcess), a flag to indicate a network connection (boolean) and the name of the interpreter in case of a local execution (string) """ interpreter = Preferences.getDebugger("RubyInterpreter") if interpreter == "": E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr("""

No Ruby interpreter configured.

""")) return None, False, "" debugClient = os.path.join( getConfig('ericDir'), "DebugClients", "Ruby", "DebugClient.rb") redirect = str(Preferences.getDebugger("RubyRedirect")) if Preferences.getDebugger("RemoteDbgEnabled"): ipaddr = self.debugServer.getHostAddress(False)[0] rexec = Preferences.getDebugger("RemoteExecution") rhost = Preferences.getDebugger("RemoteHost") if rhost == "": rhost = "localhost" if rexec: args = Utilities.parseOptionString(rexec) + \ [rhost, interpreter, os.path.abspath(debugClient), str(port), redirect, ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:]) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) # set translation function if Preferences.getDebugger("PathTranslation"): self.translateRemote = \ Preferences.getDebugger("PathTranslationRemote") self.translateLocal = \ Preferences.getDebugger("PathTranslationLocal") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation return process, self.__isNetworked, "" # set translation function self.translate = self.__identityTranslation # setup the environment for the debugger if Preferences.getDebugger("DebugEnvironmentReplace"): clientEnv = {} else: clientEnv = os.environ.copy() envlist = Utilities.parseEnvironmentString( Preferences.getDebugger("DebugEnvironment")) for el in envlist: try: key, value = el.split('=', 1) if value.startswith('"') or value.startswith("'"): value = value[1:-1] clientEnv[str(key)] = str(value) except ValueError: pass ipaddr = self.debugServer.getHostAddress(True) if runInConsole or Preferences.getDebugger("ConsoleDbgEnabled"): ccmd = Preferences.getDebugger("ConsoleDbgCommand") if ccmd: args = Utilities.parseOptionString(ccmd) + \ [interpreter, os.path.abspath(debugClient), str(port), '0', ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) return process, self.__isNetworked, interpreter process = self.__startProcess( interpreter, [debugClient, str(port), redirect, ipaddr], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be started.

""")) return process, self.__isNetworked, interpreter def startRemoteForProject(self, port, runInConsole): """ Public method to start a remote Ruby interpreter for a project. @param port portnumber the debug server is listening on (integer) @param runInConsole flag indicating to start the debugger in a console window (boolean) @return client process object (QProcess), a flag to indicate a network connection (boolean) and the name of the interpreter in case of a local execution (string) """ project = e5App().getObject("Project") if not project.isDebugPropertiesLoaded(): return None, self.__isNetworked, "" # start debugger with project specific settings interpreter = project.getDebugProperty("INTERPRETER") debugClient = project.getDebugProperty("DEBUGCLIENT") redirect = str(project.getDebugProperty("REDIRECT")) if project.getDebugProperty("REMOTEDEBUGGER"): ipaddr = self.debugServer.getHostAddress(False)[0] rexec = project.getDebugProperty("REMOTECOMMAND") rhost = project.getDebugProperty("REMOTEHOST") if rhost == "": rhost = "localhost" if rexec: args = Utilities.parseOptionString(rexec) + \ [rhost, interpreter, os.path.abspath(debugClient), str(port), redirect, ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:]) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) # set translation function if project.getDebugProperty("PATHTRANSLATION"): self.translateRemote = \ project.getDebugProperty("REMOTEPATH") self.translateLocal = \ project.getDebugProperty("LOCALPATH") self.translate = self.__remoteTranslation else: self.translate = self.__identityTranslation return process, self.__isNetworked, "" # set translation function self.translate = self.__identityTranslation # setup the environment for the debugger if project.getDebugProperty("ENVIRONMENTOVERRIDE"): clientEnv = {} else: clientEnv = os.environ.copy() envlist = Utilities.parseEnvironmentString( project.getDebugProperty("ENVIRONMENTSTRING")) for el in envlist: try: key, value = el.split('=', 1) if value.startswith('"') or value.startswith("'"): value = value[1:-1] clientEnv[str(key)] = str(value) except ValueError: pass ipaddr = self.debugServer.getHostAddress(True) if runInConsole or project.getDebugProperty("CONSOLEDEBUGGER"): ccmd = project.getDebugProperty("CONSOLECOMMAND") or \ Preferences.getDebugger("ConsoleDbgCommand") if ccmd: args = Utilities.parseOptionString(ccmd) + \ [interpreter, os.path.abspath(debugClient), str(port), '0', ipaddr] args[0] = Utilities.getExecutablePath(args[0]) process = self.__startProcess(args[0], args[1:], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be""" """ started.

""")) return process, self.__isNetworked, interpreter process = self.__startProcess( interpreter, [debugClient, str(port), redirect, ipaddr], clientEnv) if process is None: E5MessageBox.critical( None, self.tr("Start Debugger"), self.tr( """

The debugger backend could not be started.

""")) return process, self.__isNetworked, interpreter def getClientCapabilities(self): """ Public method to retrieve the debug clients capabilities. @return debug client capabilities (integer) """ return self.clientCapabilities def newConnection(self, sock): """ Public slot to handle a new connection. @param sock reference to the socket object (QTcpSocket) @return flag indicating success (boolean) """ # If we already have a connection, refuse this one. It will be closed # automatically. if self.qsock is not None: return False sock.disconnected.connect(self.debugServer.startClient) sock.readyRead.connect(self.__parseClientLine) self.qsock = sock # Get the remote clients capabilities self.remoteCapabilities() return True def flush(self): """ Public slot to flush the queue. """ # Send commands that were waiting for the connection. for cmd in self.queue: self.qsock.write(cmd.encode('utf8')) self.queue = [] def shutdown(self): """ Public method to cleanly shut down. It closes our socket and shuts down the debug client. (Needed on Win OS) """ if self.qsock is None: return # do not want any slots called during shutdown self.qsock.disconnected.disconnect(self.debugServer.startClient) self.qsock.readyRead.disconnect(self.__parseClientLine) # close down socket, and shut down client as well. self.__sendCommand('{0}\n'.format(DebugProtocol.RequestShutdown)) self.qsock.flush() self.qsock.close() # reinitialize self.qsock = None self.queue = [] def isConnected(self): """ Public method to test, if a debug client has connected. @return flag indicating the connection status (boolean) """ return self.qsock is not None def remoteEnvironment(self, env): """ Public method to set the environment for a program to debug, run, ... @param env environment settings (dictionary) """ self.__sendCommand('{0}{1}\n'.format( DebugProtocol.RequestEnv, str(env))) def remoteLoad(self, fn, argv, wd, traceInterpreter=False, autoContinue=True, autoFork=False, forkChild=False): """ Public method to load a new program to debug. @param fn the filename to debug (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam traceInterpreter flag indicating if the interpreter library should be traced as well (boolean) @keyparam autoContinue flag indicating, that the debugger should not stop at the first executable line (boolean) @keyparam autoFork flag indicating the automatic fork mode (boolean) (ignored) @keyparam forkChild flag indicating to debug the child after forking (boolean) (ignored) """ self.__autoContinue = autoContinue wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( DebugProtocol.RequestLoad, wd, fn, str(Utilities.parseOptionString(argv)), traceInterpreter)) def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False): """ Public method to load a new program to run. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam autoFork flag indicating the automatic fork mode (boolean) (ignored) @keyparam forkChild flag indicating to debug the child after forking (boolean) (ignored) """ wd = self.translate(wd, False) fn = self.translate(os.path.abspath(fn), False) self.__sendCommand('{0}{1}|{2}|{3}\n'.format( DebugProtocol.RequestRun, wd, fn, str(Utilities.parseOptionString(argv)))) def remoteCoverage(self, fn, argv, wd, erase=False): """ Public method to load a new program to collect coverage data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam erase flag indicating that coverage info should be cleared first (boolean) @exception NotImplementedError raised to indicate that this interface is not supported """ raise NotImplementedError("Interface not available.") def remoteProfile(self, fn, argv, wd, erase=False): """ Public method to load a new program to collect profiling data. @param fn the filename to run (string) @param argv the commandline arguments to pass to the program (string) @param wd the working directory for the program (string) @keyparam erase flag indicating that timing info should be cleared first (boolean) @exception NotImplementedError raised to indicate that this interface is not supported """ raise NotImplementedError("Interface not available.") def remoteStatement(self, stmt): """ Public method to execute a Ruby statement. @param stmt the Ruby statement to execute (string). It should not have a trailing newline. """ self.__sendCommand('{0}\n'.format(stmt)) self.__sendCommand(DebugProtocol.RequestOK + '\n') def remoteStep(self): """ Public method to single step the debugged program. """ self.__sendCommand(DebugProtocol.RequestStep + '\n') def remoteStepOver(self): """ Public method to step over the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepOver + '\n') def remoteStepOut(self): """ Public method to step out the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepOut + '\n') def remoteStepQuit(self): """ Public method to stop the debugged program. """ self.__sendCommand(DebugProtocol.RequestStepQuit + '\n') def remoteContinue(self, special=False): """ Public method to continue the debugged program. @param special flag indicating a special continue operation (boolean) """ self.__sendCommand('{0}{1:d}\n'.format( DebugProtocol.RequestContinue, special)) def remoteBreakpoint(self, fn, line, set, cond=None, temp=False): """ Public method to set or clear a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param set flag indicating setting or resetting a breakpoint (boolean) @param cond condition of the breakpoint (string) @param temp flag indicating a temporary breakpoint (boolean) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1}@@{2:d}@@{3:d}@@{4:d}@@{5}\n'.format( DebugProtocol.RequestBreak, fn, line, temp, set, cond)) def remoteBreakpointEnable(self, fn, line, enable): """ Public method to enable or disable a breakpoint. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param enable flag indicating enabling or disabling a breakpoint (boolean) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format( DebugProtocol.RequestBreakEnable, fn, line, enable)) def remoteBreakpointIgnore(self, fn, line, count): """ Public method to ignore a breakpoint the next couple of occurrences. @param fn filename the breakpoint belongs to (string) @param line linenumber of the breakpoint (int) @param count number of occurrences to ignore (int) """ fn = self.translate(fn, False) self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format( DebugProtocol.RequestBreakIgnore, fn, line, count)) def remoteWatchpoint(self, cond, set, temp=False): """ Public method to set or clear a watch expression. @param cond expression of the watch expression (string) @param set flag indicating setting or resetting a watch expression (boolean) @param temp flag indicating a temporary watch expression (boolean) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1}@@{2:d}@@{3:d}\n'.format( DebugProtocol.RequestWatch, cond, temp, set)) def remoteWatchpointEnable(self, cond, enable): """ Public method to enable or disable a watch expression. @param cond expression of the watch expression (string) @param enable flag indicating enabling or disabling a watch expression (boolean) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1},{2:d}\n'.format( DebugProtocol.RequestWatchEnable, cond, enable)) def remoteWatchpointIgnore(self, cond, count): """ Public method to ignore a watch expression the next couple of occurrences. @param cond expression of the watch expression (string) @param count number of occurrences to ignore (int) """ # cond is combination of cond and special (s. watch expression viewer) self.__sendCommand('{0}{1},{2:d}\n'.format( DebugProtocol.RequestWatchIgnore, cond, count)) def remoteRawInput(self, s): """ Public method to send the raw input to the debugged program. @param s the raw input (string) """ self.__sendCommand(s + '\n') def remoteThreadList(self): """ Public method to request the list of threads from the client. """ return def remoteSetThread(self, tid): """ Public method to request to set the given thread as current thread. @param tid id of the thread (integer) """ return def remoteClientVariables(self, scope, filter, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param framenr framenumber of the variables to retrieve (int) """ self.__sendCommand('{0}{1:d}, {2:d}, {3}\n'.format( DebugProtocol.RequestVariables, framenr, scope, str(filter))) def remoteClientVariable(self, scope, filter, var, framenr=0): """ Public method to request the variables of the debugged program. @param scope the scope of the variables (0 = local, 1 = global) @param filter list of variable types to filter out (list of int) @param var list encoded name of variable to retrieve (string) @param framenr framenumber of the variables to retrieve (int) """ self.__sendCommand('{0}{1}, {2:d}, {3:d}, {4}\n'.format( DebugProtocol.RequestVariable, str(var), framenr, scope, str(filter))) def remoteClientSetFilter(self, scope, filter): """ Public method to set a variables filter list. @param scope the scope of the variables (0 = local, 1 = global) @param filter regexp string for variable names to filter out (string) """ self.__sendCommand('{0}{1:d}, "{2}"\n'.format( DebugProtocol.RequestSetFilter, scope, filter)) def setCallTraceEnabled(self, on): """ Public method to set the call trace state. @param on flag indicating to enable the call trace function (boolean) """ return def remoteEval(self, arg): """ Public method to evaluate arg in the current context of the debugged program. @param arg the arguments to evaluate (string) """ self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestEval, arg)) def remoteExec(self, stmt): """ Public method to execute stmt in the current context of the debugged program. @param stmt statement to execute (string) """ self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestExec, stmt)) def remoteBanner(self): """ Public slot to get the banner info of the remote client. """ self.__sendCommand(DebugProtocol.RequestBanner + '\n') def remoteCapabilities(self): """ Public slot to get the debug clients capabilities. """ self.__sendCommand(DebugProtocol.RequestCapabilities + '\n') def remoteCompletion(self, text): """ Public slot to get the a list of possible commandline completions from the remote client. @param text the text to be completed (string) """ self.__sendCommand("{0}{1}\n".format( DebugProtocol.RequestCompletion, text)) def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase): """ Public method to prepare a new unittest run. @param fn the filename to load (string) @param tn the testname to load (string) @param tfn the test function name to load tests from (string) @param failed list of failed test, if only failed test should be run (list of strings) @param cov flag indicating collection of coverage data is requested (boolean) @param covname filename to be used to assemble the coverage caches filename (string) @param coverase flag indicating erasure of coverage data is requested (boolean) @exception NotImplementedError raised to indicate that this interface is not supported """ raise NotImplementedError("Interface not available.") def remoteUTRun(self): """ Public method to start a unittest run. @exception NotImplementedError raised to indicate that this interface is not supported """ raise NotImplementedError("Interface not available.") def remoteUTStop(self): """ Public method to stop a unittest run. @exception NotImplementedError raised to indicate that this interface is not supported """ raise NotImplementedError("Interface not available.") def __parseClientLine(self): """ Private method to handle data from the client. """ while self.qsock and self.qsock.canReadLine(): qs = self.qsock.readLine() if self.codec is not None: line = self.codec.toUnicode(qs) else: line = bytes(qs).decode() if line.endswith(DebugProtocol.EOT): line = line[:-len(DebugProtocol.EOT)] if not line: continue ## print("Server: ", line) ##debug eoc = line.find('<') + 1 # Deal with case where user has written directly to stdout # or stderr, but not line terminated and we stepped over the # write call, in that case the >line< will not be the first # string read from the socket... boc = line.find('>') if boc > 0 and eoc > boc: self.debugServer.signalClientOutput(line[:boc]) line = line[boc:] eoc = line.find('<') + 1 boc = line.find('>') if boc >= 0 and eoc > boc: resp = line[boc:eoc] if resp == DebugProtocol.ResponseLine: stack = eval(line[eoc:-1]) for s in stack: s[0] = self.translate(s[0], True) cf = stack[0] if self.__autoContinue: self.__autoContinue = False QTimer.singleShot(0, self.remoteContinue) else: self.debugServer.signalClientLine(cf[0], int(cf[1])) self.debugServer.signalClientStack(stack) continue if resp == DebugProtocol.ResponseVariables: vlist = eval(line[eoc:-1]) scope = vlist[0] try: variables = vlist[1:] except IndexError: variables = [] self.debugServer.signalClientVariables(scope, variables) continue if resp == DebugProtocol.ResponseVariable: vlist = eval(line[eoc:-1]) scope = vlist[0] try: variables = vlist[1:] except IndexError: variables = [] self.debugServer.signalClientVariable(scope, variables) continue if resp == DebugProtocol.ResponseOK: self.debugServer.signalClientStatement(False) continue if resp == DebugProtocol.ResponseContinue: self.debugServer.signalClientStatement(True) continue if resp == DebugProtocol.ResponseException: exc = line[eoc:-1] exc = self.translate(exc, True) try: exclist = eval(exc) exctype = exclist[0] excmessage = exclist[1] stack = exclist[2:] except (IndexError, ValueError, SyntaxError): exctype = None excmessage = '' stack = [] self.debugServer.signalClientException( exctype, excmessage, stack) continue if resp == DebugProtocol.ResponseSyntax: exc = line[eoc:-1] exc = self.translate(exc, True) try: message, (fn, ln, cn) = eval(exc) if fn is None: fn = '' except (IndexError, ValueError): message = None fn = '' ln = 0 cn = 0 self.debugServer.signalClientSyntaxError( message, fn, ln, cn) continue if resp == DebugProtocol.ResponseExit: self.debugServer.signalClientExit(line[eoc:-1]) continue if resp == DebugProtocol.ResponseClearBreak: fn, lineno = line[eoc:-1].split(',') lineno = int(lineno) fn = self.translate(fn, True) self.debugServer.signalClientClearBreak(fn, lineno) continue if resp == DebugProtocol.ResponseClearWatch: cond = line[eoc:-1] self.debugServer.signalClientClearWatch(cond) continue if resp == DebugProtocol.ResponseBanner: version, platform, dbgclient = eval(line[eoc:-1]) self.debugServer.signalClientBanner( version, platform, dbgclient) continue if resp == DebugProtocol.ResponseCapabilities: cap, clType = eval(line[eoc:-1]) self.clientCapabilities = cap self.debugServer.signalClientCapabilities(cap, clType) continue if resp == DebugProtocol.ResponseCompletion: clstring, text = line[eoc:-1].split('||') cl = eval(clstring) self.debugServer.signalClientCompletionList(cl, text) continue if resp == DebugProtocol.PassiveStartup: fn, exc = line[eoc:-1].split('|') exc = bool(exc) fn = self.translate(fn, True) self.debugServer.passiveStartUp(fn, exc) continue self.debugServer.signalClientOutput(line) def __sendCommand(self, cmd): """ Private method to send a single line command to the client. @param cmd command to send to the debug client (string) """ if self.qsock is not None: self.qsock.write(cmd.encode('utf8')) else: self.queue.append(cmd) eric-6.0.8/eric/Debugger/StartDialog.py0000644000175000017500000002242012451233373016763 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the Start Program dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog import Utilities import Preferences import UI.PixmapCache class StartDialog(QDialog): """ Class implementing the Start Program dialog. It implements a dialog that is used to start an application for debugging. It asks the user to enter the commandline parameters, the working directory and whether exception reporting should be disabled. """ def __init__(self, caption, argvList, wdList, envList, exceptions, parent=None, type=0, modfuncList=None, tracePython=False, autoClearShell=True, autoContinue=True, autoFork=False, forkChild=False): """ Constructor @param caption the caption to be displayed (string) @param argvList history list of commandline arguments (list of strings) @param wdList history list of working directories (list of strings) @param envList history list of environment settings (list of strings) @param exceptions exception reporting flag (boolean) @param parent parent widget of this dialog (QWidget) @param type type of the start dialog
  • 0 = start debug dialog
  • 1 = start run dialog
  • 2 = start coverage dialog
  • 3 = start profile dialog
@keyparam modfuncList history list of module functions (list of strings) @keyparam tracePython flag indicating if the Python library should be traced as well (boolean) @keyparam autoClearShell flag indicating, that the interpreter window should be cleared automatically (boolean) @keyparam autoContinue flag indicating, that the debugger should not stop at the first executable line (boolean) @keyparam autoFork flag indicating the automatic fork mode (boolean) @keyparam forkChild flag indicating to debug the child after forking (boolean) """ super(StartDialog, self).__init__(parent) self.setModal(True) self.type = type if type == 0: from .Ui_StartDebugDialog import Ui_StartDebugDialog self.ui = Ui_StartDebugDialog() elif type == 1: from .Ui_StartRunDialog import Ui_StartRunDialog self.ui = Ui_StartRunDialog() elif type == 2: from .Ui_StartCoverageDialog import Ui_StartCoverageDialog self.ui = Ui_StartCoverageDialog() elif type == 3: from .Ui_StartProfileDialog import Ui_StartProfileDialog self.ui = Ui_StartProfileDialog() self.ui.setupUi(self) self.ui.dirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.clearButton = self.ui.buttonBox.addButton( self.tr("Clear Histories"), QDialogButtonBox.ActionRole) self.workdirCompleter = E5DirCompleter(self.ui.workdirCombo) self.setWindowTitle(caption) self.ui.cmdlineCombo.clear() self.ui.cmdlineCombo.addItems(argvList) if len(argvList) > 0: self.ui.cmdlineCombo.setCurrentIndex(0) self.ui.workdirCombo.clear() self.ui.workdirCombo.addItems(wdList) if len(wdList) > 0: self.ui.workdirCombo.setCurrentIndex(0) self.ui.environmentCombo.clear() self.ui.environmentCombo.addItems(envList) self.ui.exceptionCheckBox.setChecked(exceptions) self.ui.clearShellCheckBox.setChecked(autoClearShell) self.ui.consoleCheckBox.setEnabled( Preferences.getDebugger("ConsoleDbgCommand") != "") self.ui.consoleCheckBox.setChecked(False) if type == 0: # start debug dialog self.ui.tracePythonCheckBox.setChecked(tracePython) self.ui.tracePythonCheckBox.show() self.ui.autoContinueCheckBox.setChecked(autoContinue) self.ui.forkModeCheckBox.setChecked(autoFork) self.ui.forkChildCheckBox.setChecked(forkChild) if type == 1: # start run dialog self.ui.forkModeCheckBox.setChecked(autoFork) self.ui.forkChildCheckBox.setChecked(forkChild) if type == 3: # start coverage or profile dialog self.ui.eraseCheckBox.setChecked(True) self.__clearHistoryLists = False msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_dirButton_clicked(self): """ Private method used to open a directory selection dialog. """ cwd = self.ui.workdirCombo.currentText() d = E5FileDialog.getExistingDirectory( self, self.tr("Working directory"), cwd, E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if d: self.ui.workdirCombo.setEditText(Utilities.toNativeSeparators(d)) def on_modFuncCombo_editTextChanged(self): """ Private slot to enable/disable the OK button. """ self.ui.buttonBox.button(QDialogButtonBox.Ok).setDisabled( self.ui.modFuncCombo.currentText() == "") def getData(self): """ Public method to retrieve the data entered into this dialog. @return a tuple of argv (string), workdir (string), environment (string), exceptions flag (boolean), clear interpreter flag (boolean), clear histories flag (boolean) and run in console flag (boolean) """ cmdLine = self.ui.cmdlineCombo.currentText() workdir = self.ui.workdirCombo.currentText() environment = self.ui.environmentCombo.currentText() return (cmdLine, workdir, environment, self.ui.exceptionCheckBox.isChecked(), self.ui.clearShellCheckBox.isChecked(), self.__clearHistoryLists, self.ui.consoleCheckBox.isChecked()) def getDebugData(self): """ Public method to retrieve the debug related data entered into this dialog. @return a tuple of a flag indicating, if the Python library should be traced as well, a flag indicating, that the debugger should not stop at the first executable line (boolean), a flag indicating, that the debugger should fork automatically (boolean) and a flag indicating, that the debugger should debug the child process after forking automatically (boolean) """ if self.type == 0: return (self.ui.tracePythonCheckBox.isChecked(), self.ui.autoContinueCheckBox.isChecked(), self.ui.forkModeCheckBox.isChecked(), self.ui.forkChildCheckBox.isChecked()) def getRunData(self): """ Public method to retrieve the debug related data entered into this dialog. @return a tuple of a flag indicating, that the debugger should fork automatically (boolean) and a flag indicating, that the debugger should debug the child process after forking automatically (boolean) """ if self.type == 1: return (self.ui.forkModeCheckBox.isChecked(), self.ui.forkChildCheckBox.isChecked()) def getCoverageData(self): """ Public method to retrieve the coverage related data entered into this dialog. @return flag indicating erasure of coverage info (boolean) """ if self.type == 2: return self.ui.eraseCheckBox.isChecked() def getProfilingData(self): """ Public method to retrieve the profiling related data entered into this dialog. @return flag indicating erasure of profiling info (boolean) """ if self.type == 3: return self.ui.eraseCheckBox.isChecked() def __clearHistories(self): """ Private slot to clear the combo boxes lists and record a flag to clear the lists. """ self.__clearHistoryLists = True cmdLine = self.ui.cmdlineCombo.currentText() workdir = self.ui.workdirCombo.currentText() environment = self.ui.environmentCombo.currentText() self.ui.cmdlineCombo.clear() self.ui.workdirCombo.clear() self.ui.environmentCombo.clear() self.ui.cmdlineCombo.addItem(cmdLine) self.ui.workdirCombo.addItem(workdir) self.ui.environmentCombo.addItem(environment) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.clearButton: self.__clearHistories() eric-6.0.8/eric/Dictionaries/0000755000175000017500000000000012060166051015057 5ustar piotrpiotreric-6.0.8/eric/Dictionaries/excludes.dic0000644000175000017500000000000012060166051017342 0ustar piotrpiotreric-6.0.8/eric/Dictionaries/words.dic0000644000175000017500000000004612060166051016676 0ustar piotrpiotr detlev offenbachs Eric5 IDE unappliederic-6.0.8/eric/Graphics/0000755000175000017500000000000012557365404014220 5ustar piotrpiotreric-6.0.8/eric/Graphics/ModuleItem.py0000644000175000017500000001437712451233373016642 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a module item. """ from __future__ import unicode_literals from PyQt5.QtGui import QFont from PyQt5.QtWidgets import QGraphicsSimpleTextItem, QStyle from .UMLItem import UMLModel, UMLItem class ModuleModel(UMLModel): """ Class implementing the module model. """ def __init__(self, name, classlist=[]): """ Constructor @param name the module name (string) @param classlist list of class names (list of strings) """ super(ModuleModel, self).__init__(name) self.classlist = classlist def addClass(self, classname): """ Public method to add a class to the module model. @param classname class name to be added (string) """ self.classlist.append(classname) def getClasses(self): """ Public method to retrieve the classes of the module. @return list of class names (list of strings) """ return self.classlist[:] class ModuleItem(UMLItem): """ Class implementing a module item. """ ItemType = "module" def __init__(self, model=None, x=0, y=0, rounded=False, parent=None, scene=None): """ Constructor @param model module model containing the module data (ModuleModel) @param x x-coordinate (integer) @param y y-coordinate (integer) @keyparam rounded flag indicating a rounded corner (boolean) @keyparam parent reference to the parent object (QGraphicsItem) @keyparam scene reference to the scene object (QGraphicsScene) """ UMLItem.__init__(self, model, x, y, rounded, parent) scene.addItem(self) if self.model: self.__createTexts() self.__calculateSize() def __createTexts(self): """ Private method to create the text items of the module item. """ if self.model is None: return boldFont = QFont(self.font) boldFont.setBold(True) classes = self.model.getClasses() x = self.margin + self.rect().x() y = self.margin + self.rect().y() self.header = QGraphicsSimpleTextItem(self) self.header.setFont(boldFont) self.header.setText(self.model.getName()) self.header.setPos(x, y) y += self.header.boundingRect().height() + self.margin if classes: txt = "\n".join(classes) else: txt = " " self.classes = QGraphicsSimpleTextItem(self) self.classes.setFont(self.font) self.classes.setText(txt) self.classes.setPos(x, y) def __calculateSize(self): """ Private method to calculate the size of the module item. """ if self.model is None: return width = self.header.boundingRect().width() height = self.header.boundingRect().height() if self.classes: width = max(width, self.classes.boundingRect().width()) height = height + self.classes.boundingRect().height() self.setSize(width + 2 * self.margin, height + 2 * self.margin) def setModel(self, model): """ Public method to set the module model. @param model module model containing the module data (ModuleModel) """ self.scene().removeItem(self.header) self.header = None if self.classes: self.scene().removeItem(self.classes) self.meths = None self.model = model self.__createTexts() self.__calculateSize() def paint(self, painter, option, widget=None): """ Public method to paint the item in local coordinates. @param painter reference to the painter object (QPainter) @param option style options (QStyleOptionGraphicsItem) @param widget optional reference to the widget painted on (QWidget) """ pen = self.pen() if (option.state & QStyle.State_Selected) == \ QStyle.State(QStyle.State_Selected): pen.setWidth(2) else: pen.setWidth(1) painter.setPen(pen) painter.setBrush(self.brush()) painter.setFont(self.font) offsetX = self.rect().x() offsetY = self.rect().y() w = self.rect().width() h = self.rect().height() painter.drawRect(offsetX, offsetY, w, h) y = self.margin + self.header.boundingRect().height() painter.drawLine(offsetX, offsetY + y, offsetX + w - 1, offsetY + y) self.adjustAssociations() def buildItemDataString(self): """ Public method to build a string to persist the specific item data. This string must start with ", " and should be built like "attribute=value" with pairs separated by ", ". value must not contain ", " or newlines. @return persistence data (string) """ entries = [ "name={0}".format(self.model.getName()), ] classes = self.model.getClasses() if classes: entries.append("classes={0}".format("||".join(classes))) return ", " + ", ".join(entries) def parseItemDataString(self, version, data): """ Public method to parse the given persistence data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ parts = data.split(", ") if len(parts) < 1: return False name = "" classes = [] for part in parts: key, value = part.split("=", 1) if key == "name": name = value.strip() elif key == "classes": classes = value.strip().split("||") else: return False self.model = ModuleModel(name, classes) self.__createTexts() self.__calculateSize() return True eric-6.0.8/eric/Graphics/UMLClassDiagramBuilder.py0000644000175000017500000002675312451233373021016 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog showing a UML like class diagram. """ from __future__ import unicode_literals try: # Py3 from itertools import zip_longest except ImportError: from itertools import izip_longest as zip_longest # __IGNORE_WARNING__ from PyQt5.QtWidgets import QGraphicsTextItem import Utilities import Preferences from .UMLDiagramBuilder import UMLDiagramBuilder class UMLClassDiagramBuilder(UMLDiagramBuilder): """ Class implementing a builder for UML like class diagrams. """ def __init__(self, dialog, view, project, file, noAttrs=False): """ Constructor @param dialog reference to the UML dialog (UMLDialog) @param view reference to the view object (UMLGraphicsView) @param project reference to the project object (Project) @param file file name of a python module to be shown (string) @keyparam noAttrs flag indicating, that no attributes should be shown (boolean) """ super(UMLClassDiagramBuilder, self).__init__(dialog, view, project) self.setObjectName("UMLClassDiagramBuilder") self.file = file self.noAttrs = noAttrs def initialize(self): """ Public method to initialize the object. """ pname = self.project.getProjectName() if pname and self.project.isProjectSource(self.file): name = self.tr("Class Diagram {0}: {1}").format( pname, self.project.getRelativePath(self.file)) else: name = self.tr("Class Diagram: {0}").format(self.file) self.umlView.setDiagramName(name) def __getCurrentShape(self, name): """ Private method to get the named shape. @param name name of the shape (string) @return shape (QGraphicsItem) """ return self.allClasses.get(name) def buildDiagram(self): """ Public method to build the class shapes of the class diagram. The algorithm is borrowed from Boa Constructor. """ import Utilities.ModuleParser self.allClasses = {} self.allModules = {} try: extensions = Preferences.getPython("PythonExtensions") + \ Preferences.getPython("Python3Extensions") + ['.rb'] module = Utilities.ModuleParser.readModule( self.file, extensions=extensions, caching=False) except ImportError: ct = QGraphicsTextItem(None) ct.setHtml( self.tr("The module '{0}' could not be found.") .format(self.file)) self.scene.addItem(ct) return if self.file not in self.allModules: self.allModules[self.file] = [] routes = [] nodes = [] todo = [module.createHierarchy()] classesFound = False while todo: hierarchy = todo[0] for className in hierarchy: classesFound = True cw = self.__getCurrentShape(className) if not cw and className.find('.') >= 0: cw = self.__getCurrentShape(className.split('.')[-1]) if cw: self.allClasses[className] = cw if className not in self.allModules[self.file]: self.allModules[self.file].append(className) if cw and cw.noAttrs != self.noAttrs: cw = None if cw and not (cw.external and (className in module.classes or className in module.modules)): if cw.scene() != self.scene: self.scene.addItem(cw) cw.setPos(10, 10) if className not in nodes: nodes.append(className) else: if className in module.classes: # this is a local class (defined in this module) self.__addLocalClass( className, module.classes[className], 0, 0) elif className in module.modules: # this is a local module (defined in this module) self.__addLocalClass( className, module.modules[className], 0, 0, True) else: self.__addExternalClass(className, 0, 0) nodes.append(className) if hierarchy.get(className): todo.append(hierarchy.get(className)) children = list(hierarchy.get(className).keys()) for child in children: if (className, child) not in routes: routes.append((className, child)) del todo[0] if classesFound: self.__arrangeClasses(nodes, routes[:]) self.__createAssociations(routes) self.umlView.autoAdjustSceneSize(limit=True) else: ct = QGraphicsTextItem(None) ct.setHtml(self.tr( "The module '{0}' does not contain any classes.") .format(self.file)) self.scene.addItem(ct) def __arrangeClasses(self, nodes, routes, whiteSpaceFactor=1.2): """ Private method to arrange the shapes on the canvas. The algorithm is borrowed from Boa Constructor. @param nodes list of nodes to arrange @param routes list of routes @param whiteSpaceFactor factor to increase whitespace between items (float) """ from . import GraphicsUtilities generations = GraphicsUtilities.sort(nodes, routes) # calculate width and height of all elements sizes = [] for generation in generations: sizes.append([]) for child in generation: sizes[-1].append( self.__getCurrentShape(child).sceneBoundingRect()) # calculate total width and total height width = 0 height = 0 widths = [] heights = [] for generation in sizes: currentWidth = 0 currentHeight = 0 for rect in generation: if rect.bottom() > currentHeight: currentHeight = rect.bottom() currentWidth = currentWidth + rect.right() # update totals if currentWidth > width: width = currentWidth height = height + currentHeight # store generation info widths.append(currentWidth) heights.append(currentHeight) # add in some whitespace width = width * whiteSpaceFactor ## rawHeight = height height = height * whiteSpaceFactor - 20 ## verticalWhiteSpace = max( ## (height - rawHeight) / (len(generations) - 1.0 or 2.0), ## 40.0 ## ) verticalWhiteSpace = 40.0 sceneRect = self.umlView.sceneRect() width += 50.0 height += 50.0 swidth = width < sceneRect.width() and sceneRect.width() or width sheight = height < sceneRect.height() and sceneRect.height() or height self.umlView.setSceneSize(swidth, sheight) # distribute each generation across the width and the # generations across height y = 10.0 for currentWidth, currentHeight, generation in \ zip_longest(widths, heights, generations): x = 10.0 # whiteSpace is the space between any two elements whiteSpace = (width - currentWidth - 20) / \ (len(generation) - 1.0 or 2.0) for className in generation: cw = self.__getCurrentShape(className) cw.setPos(x, y) rect = cw.sceneBoundingRect() x = x + rect.width() + whiteSpace y = y + currentHeight + verticalWhiteSpace def __addLocalClass(self, className, _class, x, y, isRbModule=False): """ Private method to add a class defined in the module. @param className name of the class to be as a dictionary key (string) @param _class class to be shown (ModuleParser.Class) @param x x-coordinate (float) @param y y-coordinate (float) @param isRbModule flag indicating a Ruby module (boolean) """ from .ClassItem import ClassItem, ClassModel meths = sorted(_class.methods.keys()) attrs = sorted(_class.attributes.keys()) name = _class.name if isRbModule: name = "{0} (Module)".format(name) cl = ClassModel(name, meths[:], attrs[:]) cw = ClassItem(cl, False, x, y, noAttrs=self.noAttrs, scene=self.scene) cw.setId(self.umlView.getItemId()) self.allClasses[className] = cw if _class.name not in self.allModules[self.file]: self.allModules[self.file].append(_class.name) def __addExternalClass(self, _class, x, y): """ Private method to add a class defined outside the module. If the canvas is too small to take the shape, it is enlarged. @param _class class to be shown (string) @param x x-coordinate (float) @param y y-coordinate (float) """ from .ClassItem import ClassItem, ClassModel cl = ClassModel(_class) cw = ClassItem(cl, True, x, y, noAttrs=self.noAttrs, scene=self.scene) cw.setId(self.umlView.getItemId()) self.allClasses[_class] = cw if _class not in self.allModules[self.file]: self.allModules[self.file].append(_class) def __createAssociations(self, routes): """ Private method to generate the associations between the class shapes. @param routes list of relationsships """ from .AssociationItem import AssociationItem, Generalisation for route in routes: if len(route) > 1: assoc = AssociationItem( self.__getCurrentShape(route[1]), self.__getCurrentShape(route[0]), Generalisation, topToBottom=True) self.scene.addItem(assoc) def getPersistenceData(self): """ Public method to get a string for data to be persisted. @return persisted data string (string) """ return "file={0}, no_attributes={1}".format(self.file, self.noAttrs) def parsePersistenceData(self, version, data): """ Public method to parse persisted data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ parts = data.split(", ") if len(parts) != 2 or \ not parts[0].startswith("file=") or \ not parts[1].startswith("no_attributes="): return False self.file = parts[0].split("=", 1)[1].strip() self.noAttrs = Utilities.toBool(parts[1].split("=", 1)[1].strip()) self.initialize() return True eric-6.0.8/eric/Graphics/ImportsDiagramBuilder.py0000644000175000017500000002425512451233373021023 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog showing an imports diagram of a package. """ from __future__ import unicode_literals import glob import os from PyQt5.QtWidgets import QApplication, QGraphicsTextItem from E5Gui.E5ProgressDialog import E5ProgressDialog from .UMLDiagramBuilder import UMLDiagramBuilder import Utilities import Preferences class ImportsDiagramBuilder(UMLDiagramBuilder): """ Class implementing a builder for imports diagrams of a package. Note: Only package internal imports are shown in order to maintain some readability. """ def __init__(self, dialog, view, project, package, showExternalImports=False): """ Constructor @param dialog reference to the UML dialog (UMLDialog) @param view reference to the view object (UMLGraphicsView) @param project reference to the project object (Project) @param package name of a python package to show the import relationships (string) @keyparam showExternalImports flag indicating to show exports from outside the package (boolean) """ super(ImportsDiagramBuilder, self).__init__(dialog, view, project) self.setObjectName("ImportsDiagram") self.showExternalImports = showExternalImports self.packagePath = Utilities.normabspath(package) def initialize(self): """ Public method to initialize the object. """ self.package = os.path.splitdrive(self.packagePath)[1].replace( os.sep, '.')[1:] hasInit = True ppath = self.packagePath while hasInit: ppath = os.path.dirname(ppath) hasInit = len(glob.glob(os.path.join(ppath, '__init__.*'))) > 0 self.shortPackage = self.packagePath.replace(ppath, '').replace( os.sep, '.')[1:] pname = self.project.getProjectName() if pname: name = self.tr("Imports Diagramm {0}: {1}").format( pname, self.project.getRelativePath(self.packagePath)) else: name = self.tr("Imports Diagramm: {0}").format( self.packagePath) self.umlView.setDiagramName(name) def __buildModulesDict(self): """ Private method to build a dictionary of modules contained in the package. @return dictionary of modules contained in the package. """ import Utilities.ModuleParser extensions = Preferences.getPython("PythonExtensions") + \ Preferences.getPython("Python3Extensions") moduleDict = {} modules = [] for ext in Preferences.getPython("PythonExtensions") + \ Preferences.getPython("Python3Extensions"): modules.extend(glob.glob(Utilities.normjoinpath( self.packagePath, '*{0}'.format(ext)))) tot = len(modules) progress = E5ProgressDialog( self.tr("Parsing modules..."), None, 0, tot, self.tr("%v/%m Modules"), self.parent()) progress.setWindowTitle(self.tr("Imports Diagramm")) try: prog = 0 progress.show() QApplication.processEvents() for module in modules: progress.setValue(prog) QApplication.processEvents() prog = prog + 1 try: mod = Utilities.ModuleParser.readModule( module, extensions=extensions, caching=False) except ImportError: continue else: name = mod.name if name.startswith(self.package): name = name[len(self.package) + 1:] moduleDict[name] = mod finally: progress.setValue(tot) progress.deleteLater() return moduleDict def buildDiagram(self): """ Public method to build the modules shapes of the diagram. """ initlist = glob.glob(os.path.join(self.packagePath, '__init__.*')) if len(initlist) == 0: ct = QGraphicsTextItem(None) ct.setHtml( self.tr( "The directory '{0}' is not a Python package.") .format(self.package)) self.scene.addItem(ct) return shapes = {} p = 10 y = 10 maxHeight = 0 sceneRect = self.umlView.sceneRect() modules = self.__buildModulesDict() sortedkeys = sorted(modules.keys()) externalMods = [] packageList = self.shortPackage.split('.') packageListLen = len(packageList) for module in sortedkeys: impLst = [] for i in modules[module].imports: if i.startswith(self.package): n = i[len(self.package) + 1:] else: n = i if i in modules: impLst.append(n) elif self.showExternalImports: impLst.append(n) if n not in externalMods: externalMods.append(n) for i in list(modules[module].from_imports.keys()): if i.startswith('.'): dots = len(i) - len(i.lstrip('.')) if dots == 1: n = i[1:] i = n else: if self.showExternalImports: n = '.'.join( packageList[:packageListLen - dots + 1] + [i[dots:]]) else: n = i elif i.startswith(self.package): n = i[len(self.package) + 1:] else: n = i if i in modules: impLst.append(n) elif self.showExternalImports: impLst.append(n) if n not in externalMods: externalMods.append(n) classNames = [] for cls in list(modules[module].classes.keys()): className = modules[module].classes[cls].name if className not in classNames: classNames.append(className) shape = self.__addModule(module, classNames, 0.0, 0.0) shapeRect = shape.sceneBoundingRect() shapes[module] = (shape, impLst) pn = p + shapeRect.width() + 10 maxHeight = max(maxHeight, shapeRect.height()) if pn > sceneRect.width(): p = 10 y += maxHeight + 10 maxHeight = shapeRect.height() shape.setPos(p, y) p += shapeRect.width() + 10 else: shape.setPos(p, y) p = pn for module in externalMods: shape = self.__addModule(module, [], 0.0, 0.0) shapeRect = shape.sceneBoundingRect() shapes[module] = (shape, []) pn = p + shapeRect.width() + 10 maxHeight = max(maxHeight, shapeRect.height()) if pn > sceneRect.width(): p = 10 y += maxHeight + 10 maxHeight = shapeRect.height() shape.setPos(p, y) p += shapeRect.width() + 10 else: shape.setPos(p, y) p = pn rect = self.umlView._getDiagramRect(10) sceneRect = self.umlView.sceneRect() if rect.width() > sceneRect.width(): sceneRect.setWidth(rect.width()) if rect.height() > sceneRect.height(): sceneRect.setHeight(rect.height()) self.umlView.setSceneSize(sceneRect.width(), sceneRect.height()) self.__createAssociations(shapes) self.umlView.autoAdjustSceneSize(limit=True) def __addModule(self, name, classes, x, y): """ Private method to add a module to the diagram. @param name module name to be shown (string) @param classes list of class names contained in the module (list of strings) @param x x-coordinate (float) @param y y-coordinate (float) @return reference to the imports item (ModuleItem) """ from .ModuleItem import ModuleItem, ModuleModel classes.sort() impM = ModuleModel(name, classes) impW = ModuleItem(impM, x, y, scene=self.scene) impW.setId(self.umlView.getItemId()) return impW def __createAssociations(self, shapes): """ Private method to generate the associations between the module shapes. @param shapes list of shapes """ from .AssociationItem import AssociationItem, Imports for module in list(shapes.keys()): for rel in shapes[module][1]: assoc = AssociationItem( shapes[module][0], shapes[rel][0], Imports) self.scene.addItem(assoc) def getPersistenceData(self): """ Public method to get a string for data to be persisted. @return persisted data string (string) """ return "package={0}, show_external={1}".format( self.packagePath, self.showExternalImports) def parsePersistenceData(self, version, data): """ Public method to parse persisted data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ parts = data.split(", ") if len(parts) != 2 or \ not parts[0].startswith("package=") or \ not parts[1].startswith("show_external="): return False self.packagePath = parts[0].split("=", 1)[1].strip() self.showExternalImports = Utilities.toBool( parts[1].split("=", 1)[1].strip()) self.initialize() return True eric-6.0.8/eric/Graphics/__init__.py0000644000175000017500000000034012451233373016316 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Package implementing various graphical representations. This package implements various graphical representations. """ eric-6.0.8/eric/Graphics/UMLSceneSizeDialog.py0000644000175000017500000000315012451233373020147 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog to set the scene sizes. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_UMLSceneSizeDialog import Ui_UMLSceneSizeDialog class UMLSceneSizeDialog(QDialog, Ui_UMLSceneSizeDialog): """ Class implementing a dialog to set the scene sizes. """ def __init__(self, w, h, minW, minH, parent=None, name=None): """ Constructor @param w current width of scene (integer) @param h current height of scene (integer) @param minW minimum width allowed (integer) @param minH minimum height allowed (integer) @param parent parent widget of this dialog (QWidget) @param name name of this widget (string) """ super(UMLSceneSizeDialog, self).__init__(parent) if name: self.setObjectName(name) self.setupUi(self) self.widthSpinBox.setValue(w) self.heightSpinBox.setValue(h) self.widthSpinBox.setMinimum(minW) self.heightSpinBox.setMinimum(minH) self.widthSpinBox.selectAll() self.widthSpinBox.setFocus() msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getData(self): """ Public method to retrieve the entered data. @return tuple giving the selected width and height (integer, integer) """ return (self.widthSpinBox.value(), self.heightSpinBox.value()) eric-6.0.8/eric/Graphics/PackageItem.py0000644000175000017500000001633512451233373016744 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a package item. """ from __future__ import unicode_literals from PyQt5.QtGui import QFont from PyQt5.QtWidgets import QGraphicsSimpleTextItem, QStyle from .UMLItem import UMLModel, UMLItem import Utilities class PackageModel(UMLModel): """ Class implementing the package model. """ def __init__(self, name, moduleslist=[]): """ Constructor @param name package name (string) @param moduleslist list of module names (list of strings) """ super(PackageModel, self).__init__(name) self.moduleslist = moduleslist def addModule(self, modulename): """ Public method to add a module to the package model. @param modulename module name to be added (string) """ self.moduleslist.append(modulename) def getModules(self): """ Public method to retrieve the modules of the package. @return list of module names (list of strings) """ return self.moduleslist[:] class PackageItem(UMLItem): """ Class implementing a package item. """ ItemType = "package" def __init__(self, model=None, x=0, y=0, rounded=False, noModules=False, parent=None, scene=None): """ Constructor @param model package model containing the package data (PackageModel) @param x x-coordinate (integer) @param y y-coordinate (integer) @param rounded flag indicating a rounded corner (boolean) @keyparam noModules flag indicating, that no module names should be shown (boolean) @keyparam parent reference to the parent object (QGraphicsItem) @keyparam scene reference to the scene object (QGraphicsScene) """ UMLItem.__init__(self, model, x, y, rounded, parent) self.noModules = noModules scene.addItem(self) if self.model: self.__createTexts() self.__calculateSize() def __createTexts(self): """ Private method to create the text items of the class item. """ if self.model is None: return boldFont = QFont(self.font) boldFont.setBold(True) modules = self.model.getModules() x = self.margin + self.rect().x() y = self.margin + self.rect().y() self.header = QGraphicsSimpleTextItem(self) self.header.setFont(boldFont) self.header.setText(self.model.getName()) self.header.setPos(x, y) y += self.header.boundingRect().height() + self.margin if not self.noModules: if modules: txt = "\n".join(modules) else: txt = " " self.modules = QGraphicsSimpleTextItem(self) self.modules.setFont(self.font) self.modules.setText(txt) self.modules.setPos(x, y) else: self.modules = None def __calculateSize(self): """ Private method to calculate the size of the package widget. """ if self.model is None: return width = self.header.boundingRect().width() height = self.header.boundingRect().height() if self.modules: width = max(width, self.modules.boundingRect().width()) height = height + self.modules.boundingRect().height() latchW = width / 3.0 latchH = min(15.0, latchW) self.setSize(width + 2 * self.margin, height + latchH + 2 * self.margin) x = self.margin + self.rect().x() y = self.margin + self.rect().y() + latchH self.header.setPos(x, y) y += self.header.boundingRect().height() + self.margin if self.modules: self.modules.setPos(x, y) def setModel(self, model): """ Public method to set the package model. @param model package model containing the package data (PackageModel) """ self.scene().removeItem(self.header) self.header = None if self.modules: self.scene().removeItem(self.modules) self.modules = None self.model = model self.__createTexts() self.__calculateSize() def paint(self, painter, option, widget=None): """ Public method to paint the item in local coordinates. @param painter reference to the painter object (QPainter) @param option style options (QStyleOptionGraphicsItem) @param widget optional reference to the widget painted on (QWidget) """ pen = self.pen() if (option.state & QStyle.State_Selected) == \ QStyle.State(QStyle.State_Selected): pen.setWidth(2) else: pen.setWidth(1) offsetX = self.rect().x() offsetY = self.rect().y() w = self.rect().width() latchW = w / 3.0 latchH = min(15.0, latchW) h = self.rect().height() - latchH + 1 painter.setPen(pen) painter.setBrush(self.brush()) painter.setFont(self.font) painter.drawRect(offsetX, offsetY, latchW, latchH) painter.drawRect(offsetX, offsetY + latchH, w, h) y = self.margin + self.header.boundingRect().height() + latchH painter.drawLine(offsetX, offsetY + y, offsetX + w - 1, offsetY + y) self.adjustAssociations() def buildItemDataString(self): """ Public method to build a string to persist the specific item data. This string must start with ", " and should be built like "attribute=value" with pairs separated by ", ". value must not contain ", " or newlines. @return persistence data (string) """ entries = [ "no_modules={0}".format(self.noModules), "name={0}".format(self.model.getName()), ] modules = self.model.getModules() if modules: entries.append("modules={0}".format("||".join(modules))) return ", " + ", ".join(entries) def parseItemDataString(self, version, data): """ Public method to parse the given persistence data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ parts = data.split(", ") if len(parts) < 2: return False name = "" modules = [] for part in parts: key, value = part.split("=", 1) if key == "no_modules": self.external = Utilities.toBool(value.strip()) elif key == "name": name = value.strip() elif key == "modules": modules = value.strip().split("||") else: return False self.model = PackageModel(name, modules) self.__createTexts() self.__calculateSize() return True eric-6.0.8/eric/Graphics/UMLDialog.py0000644000175000017500000003375412451233373016353 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog showing UML like diagrams. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QFileInfo from PyQt5.QtWidgets import QAction, QToolBar, QGraphicsScene from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5MainWindow import E5MainWindow import UI.Config import UI.PixmapCache class UMLDialog(E5MainWindow): """ Class implementing a dialog showing UML like diagrams. """ NoDiagram = 255 ClassDiagram = 0 PackageDiagram = 1 ImportsDiagram = 2 ApplicationDiagram = 3 FileVersions = ["1.0"] def __init__(self, diagramType, project, path="", parent=None, initBuilder=True, **kwargs): """ Constructor @param diagramType type of the diagram (one of ApplicationDiagram, ClassDiagram, ImportsDiagram, NoDiagram, PackageDiagram) @param project reference to the project object (Project) @param path file or directory path to build the diagram from (string) @param parent parent widget of the dialog (QWidget) @keyparam initBuilder flag indicating to initialize the diagram builder (boolean) @keyparam kwargs diagram specific data """ super(UMLDialog, self).__init__(parent) self.setObjectName("UMLDialog") self.__diagramType = diagramType self.__project = project from .UMLGraphicsView import UMLGraphicsView self.scene = QGraphicsScene(0.0, 0.0, 800.0, 600.0) self.umlView = UMLGraphicsView(self.scene, parent=self) self.builder = self.__diagramBuilder( self.__diagramType, path, **kwargs) if self.builder and initBuilder: self.builder.initialize() self.__fileName = "" self.__initActions() self.__initToolBars() self.setCentralWidget(self.umlView) self.umlView.relayout.connect(self.__relayout) self.setWindowTitle(self.__diagramTypeString()) def __initActions(self): """ Private slot to initialize the actions. """ self.closeAct = \ QAction(UI.PixmapCache.getIcon("close.png"), self.tr("Close"), self) self.closeAct.triggered.connect(self.close) self.openAct = \ QAction(UI.PixmapCache.getIcon("open.png"), self.tr("Load"), self) self.openAct.triggered.connect(self.load) self.saveAct = \ QAction(UI.PixmapCache.getIcon("fileSave.png"), self.tr("Save"), self) self.saveAct.triggered.connect(self.__save) self.saveAsAct = \ QAction(UI.PixmapCache.getIcon("fileSaveAs.png"), self.tr("Save As..."), self) self.saveAsAct.triggered.connect(self.__saveAs) self.saveImageAct = \ QAction(UI.PixmapCache.getIcon("fileSavePixmap.png"), self.tr("Save as Image"), self) self.saveImageAct.triggered.connect(self.umlView.saveImage) self.printAct = \ QAction(UI.PixmapCache.getIcon("print.png"), self.tr("Print"), self) self.printAct.triggered.connect(self.umlView.printDiagram) self.printPreviewAct = \ QAction(UI.PixmapCache.getIcon("printPreview.png"), self.tr("Print Preview"), self) self.printPreviewAct.triggered.connect( self.umlView.printPreviewDiagram) def __initToolBars(self): """ Private slot to initialize the toolbars. """ self.windowToolBar = QToolBar(self.tr("Window"), self) self.windowToolBar.setIconSize(UI.Config.ToolBarIconSize) self.windowToolBar.addAction(self.closeAct) self.fileToolBar = QToolBar(self.tr("File"), self) self.fileToolBar.setIconSize(UI.Config.ToolBarIconSize) self.fileToolBar.addAction(self.openAct) self.fileToolBar.addSeparator() self.fileToolBar.addAction(self.saveAct) self.fileToolBar.addAction(self.saveAsAct) self.fileToolBar.addAction(self.saveImageAct) self.fileToolBar.addSeparator() self.fileToolBar.addAction(self.printPreviewAct) self.fileToolBar.addAction(self.printAct) self.umlToolBar = self.umlView.initToolBar() self.addToolBar(Qt.TopToolBarArea, self.fileToolBar) self.addToolBar(Qt.TopToolBarArea, self.windowToolBar) self.addToolBar(Qt.TopToolBarArea, self.umlToolBar) def show(self, fromFile=False): """ Public method to show the dialog. @keyparam fromFile flag indicating, that the diagram was loaded from file (boolean) """ if not fromFile and self.builder: self.builder.buildDiagram() super(UMLDialog, self).show() def __relayout(self): """ Private method to relayout the diagram. """ if self.builder: self.builder.buildDiagram() def __diagramBuilder(self, diagramType, path, **kwargs): """ Private method to instantiate a diagram builder object. @param diagramType type of the diagram (one of ApplicationDiagram, ClassDiagram, ImportsDiagram, PackageDiagram) @param path file or directory path to build the diagram from (string) @keyparam kwargs diagram specific data @return reference to the instantiated diagram builder @exception ValueError raised to indicate an illegal diagram type """ if diagramType == UMLDialog.ClassDiagram: from .UMLClassDiagramBuilder import UMLClassDiagramBuilder return UMLClassDiagramBuilder( self, self.umlView, self.__project, path, **kwargs) elif diagramType == UMLDialog.PackageDiagram: from .PackageDiagramBuilder import PackageDiagramBuilder return PackageDiagramBuilder( self, self.umlView, self.__project, path, **kwargs) elif diagramType == UMLDialog.ImportsDiagram: from .ImportsDiagramBuilder import ImportsDiagramBuilder return ImportsDiagramBuilder( self, self.umlView, self.__project, path, **kwargs) elif diagramType == UMLDialog.ApplicationDiagram: from .ApplicationDiagramBuilder import ApplicationDiagramBuilder return ApplicationDiagramBuilder( self, self.umlView, self.__project, **kwargs) elif diagramType == UMLDialog.NoDiagram: return None else: raise ValueError(self.tr( "Illegal diagram type '{0}' given.").format(diagramType)) def __diagramTypeString(self): """ Private method to generate a readable string for the diagram type. @return readable type string (string) """ if self.__diagramType == UMLDialog.ClassDiagram: return "Class Diagram" elif self.__diagramType == UMLDialog.PackageDiagram: return "Package Diagram" elif self.__diagramType == UMLDialog.ImportsDiagram: return "Imports Diagram" elif self.__diagramType == UMLDialog.ApplicationDiagram: return "Application Diagram" else: return "Illegal Diagram Type" def __save(self): """ Private slot to save the diagram with the current name. """ self.__saveAs(self.__fileName) @pyqtSlot() def __saveAs(self, filename=""): """ Private slot to save the diagram. @param filename name of the file to write to (string) """ if not filename: fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Diagram"), "", self.tr("Eric Graphics File (*.e5g);;All Files (*)"), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fname: return ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Diagram"), self.tr("

The file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return filename = fname lines = [ "version: 1.0", "diagram_type: {0} ({1})".format( self.__diagramType, self.__diagramTypeString()), "scene_size: {0};{1}".format(self.scene.width(), self.scene.height()), ] persistenceData = self.builder.getPersistenceData() if persistenceData: lines.append("builder_data: {0}".format(persistenceData)) lines.extend(self.umlView.getPersistenceData()) try: f = open(filename, "w", encoding="utf-8") f.write("\n".join(lines)) f.close() except (IOError, OSError) as err: E5MessageBox.critical( self, self.tr("Save Diagram"), self.tr( """

The file {0} could not be saved.

""" """

Reason: {1}

""").format(filename, str(err))) return self.__fileName = filename def load(self): """ Public method to load a diagram from a file. @return flag indicating success (boolean) """ filename = E5FileDialog.getOpenFileName( self, self.tr("Load Diagram"), "", self.tr("Eric Graphics File (*.e5g);;All Files (*)")) if not filename: # Cancelled by user return False try: f = open(filename, "r", encoding="utf-8") data = f.read() f.close() except (IOError, OSError) as err: E5MessageBox.critical( self, self.tr("Load Diagram"), self.tr( """

The file {0} could not be read.

""" """

Reason: {1}

""").format(filename, str(err))) return False lines = data.splitlines() if len(lines) < 3: self.__showInvalidDataMessage(filename) return False try: # step 1: check version linenum = 0 key, value = lines[linenum].split(": ", 1) if key.strip() != "version" or \ value.strip() not in UMLDialog.FileVersions: self.__showInvalidDataMessage(filename, linenum) return False else: version = value # step 2: extract diagram type linenum += 1 key, value = lines[linenum].split(": ", 1) if key.strip() != "diagram_type": self.__showInvalidDataMessage(filename, linenum) return False try: self.__diagramType = int(value.strip().split(None, 1)[0]) except ValueError: self.__showInvalidDataMessage(filename, linenum) return False self.scene.clear() self.builder = self.__diagramBuilder(self.__diagramType, "") # step 3: extract scene size linenum += 1 key, value = lines[linenum].split(": ", 1) if key.strip() != "scene_size": self.__showInvalidDataMessage(filename, linenum) return False try: width, height = [float(v.strip()) for v in value.split(";")] except ValueError: self.__showInvalidDataMessage(filename, linenum) return False self.umlView.setSceneSize(width, height) # step 4: extract builder data if available linenum += 1 key, value = lines[linenum].split(": ", 1) if key.strip() == "builder_data": ok = self.builder.parsePersistenceData(version, value) if not ok: self.__showInvalidDataMessage(filename, linenum) return False linenum += 1 # step 5: extract the graphics items ok, vlinenum = self.umlView.parsePersistenceData( version, lines[linenum:]) if not ok: self.__showInvalidDataMessage(filename, linenum + vlinenum) return False except IndexError: self.__showInvalidDataMessage(filename) return False # everything worked fine, so remember the file name self.__fileName = filename return True def __showInvalidDataMessage(self, filename, linenum=-1): """ Private slot to show a message dialog indicating an invalid data file. @param filename name of the file containing the invalid data (string) @param linenum number of the invalid line (integer) """ if linenum < 0: msg = self.tr("""

The file {0} does not contain""" """ valid data.

""").format(filename) else: msg = self.tr("""

The file {0} does not contain""" """ valid data.

Invalid line: {1}

""" ).format(filename, linenum + 1) E5MessageBox.critical(self, self.tr("Load Diagram"), msg) eric-6.0.8/eric/Graphics/GraphicsUtilities.py0000644000175000017500000000720212451233373020217 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing some graphical utility functions. """ from __future__ import unicode_literals class RecursionError(OverflowError, ValueError): """ Unable to calculate result because of recursive structure. """ pass def sort(nodes, routes, noRecursion=False): """ Function to sort widgets topographically. Passed a list of nodes and a list of source, dest routes, it attempts to create a list of stages, where each sub list is one stage in a process. The algorithm was taken from Boa Constructor. @param nodes list of nodes to be sorted @param routes list of routes between the nodes @param noRecursion flag indicating, if recursion errors should be raised @exception RecursionError a recursion error was detected @return list of stages """ children, parents = _buildChildrenLists(routes) # first stage is those nodes having no incoming routes... stage = [] stages = [stage] taken = [] for node in nodes: if not parents.get(node): stage.append(node) if nodes and not stage: # there is no element, which does not depend on some other element! stage.append(nodes[0]) taken.extend(stage) nodes = list(filter(lambda x, l=stage: x not in l, nodes)) while nodes: previousStageChildren = [] nodelen = len(nodes) # second stage are those nodes, which are direct children of the # first stage for node in stage: for child in children.get(node, []): if child not in previousStageChildren and child not in taken: previousStageChildren.append(child) elif child in taken and noRecursion: raise RecursionError((child, node)) # unless they are children of other direct children... stage = previousStageChildren removes = [] for current in stage: currentParents = parents.get(current, []) for parent in currentParents: if parent in stage and parent != current: # might wind up removing current if current not in parents.get(parent, []): # is not mutually dependant removes.append(current) for remove in removes: while remove in stage: stage.remove(remove) stages.append(stage) taken.extend(stage) nodes = list(filter(lambda x, l=stage: x not in l, nodes)) if nodelen == len(nodes): if noRecursion: raise RecursionError(nodes) else: stages.append(nodes[:]) nodes = [] return stages def _buildChildrenLists(routes): """ Function to build up parent - child relationships. Taken from Boa Constructor. @param routes list of routes between nodes @return dictionary of child and dictionary of parent relationships """ childrenTable = {} parentTable = {} for sourceID, destinationID in routes: currentChildren = childrenTable.get(sourceID, []) currentParents = parentTable.get(destinationID, []) if destinationID not in currentChildren: currentChildren.append(destinationID) if sourceID not in currentParents: currentParents.append(sourceID) childrenTable[sourceID] = currentChildren parentTable[destinationID] = currentParents return childrenTable, parentTable eric-6.0.8/eric/Graphics/AssociationItem.py0000644000175000017500000004554212451233373017667 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a graphics item for an association between two items. """ from __future__ import unicode_literals from PyQt5.QtCore import QPointF, QRectF, QLineF from PyQt5.QtWidgets import QGraphicsItem from E5Graphics.E5ArrowItem import E5ArrowItem, NormalArrow, WideArrow import Utilities Normal = 0 Generalisation = 1 Imports = 2 NoRegion = 0 West = 1 North = 2 East = 3 South = 4 NorthWest = 5 NorthEast = 6 SouthEast = 7 SouthWest = 8 Center = 9 class AssociationItem(E5ArrowItem): """ Class implementing a graphics item for an association between two items. The association is drawn as an arrow starting at the first items and ending at the second. """ def __init__(self, itemA, itemB, type=Normal, topToBottom=False, parent=None): """ Constructor @param itemA first widget of the association @param itemB second widget of the association @param type type of the association. This must be one of
  • Normal (default)
  • Generalisation
  • Imports
@keyparam topToBottom flag indicating to draw the association from item A top to item B bottom (boolean) @keyparam parent reference to the parent object (QGraphicsItem) """ if type == Normal: arrowType = NormalArrow arrowFilled = True elif type == Imports: arrowType = NormalArrow arrowFilled = True elif type == Generalisation: arrowType = WideArrow arrowFilled = False E5ArrowItem.__init__(self, QPointF(0, 0), QPointF(100, 100), arrowFilled, arrowType, parent) self.setFlag(QGraphicsItem.ItemIsMovable, False) self.setFlag(QGraphicsItem.ItemIsSelectable, False) if topToBottom: self.calculateEndingPoints = \ self.__calculateEndingPoints_topToBottom else: ## self.calculateEndingPoints = self.__calculateEndingPoints_center self.calculateEndingPoints = self.__calculateEndingPoints_rectangle self.itemA = itemA self.itemB = itemB self.assocType = type self.topToBottom = topToBottom self.regionA = NoRegion self.regionB = NoRegion self.calculateEndingPoints() self.itemA.addAssociation(self) self.itemB.addAssociation(self) def __mapRectFromItem(self, item): """ Private method to map item's rectangle to this item's coordinate system. @param item reference to the item to be mapped (QGraphicsRectItem) @return item's rectangle in local coordinates (QRectF) """ rect = item.rect() tl = self.mapFromItem(item, rect.topLeft()) return QRectF(tl.x(), tl.y(), rect.width(), rect.height()) def __calculateEndingPoints_topToBottom(self): """ Private method to calculate the ending points of the association item. The ending points are calculated from the top center of the lower item to the bottom center of the upper item. """ if self.itemA is None or self.itemB is None: return self.prepareGeometryChange() rectA = self.__mapRectFromItem(self.itemA) rectB = self.__mapRectFromItem(self.itemB) midA = QPointF(rectA.x() + rectA.width() / 2.0, rectA.y() + rectA.height() / 2.0) midB = QPointF(rectB.x() + rectB.width() / 2.0, rectB.y() + rectB.height() / 2.0) if midA.y() > midB.y(): startP = QPointF(rectA.x() + rectA.width() / 2.0, rectA.y()) endP = QPointF(rectB.x() + rectB.width() / 2.0, rectB.y() + rectB.height()) else: startP = QPointF(rectA.x() + rectA.width() / 2.0, rectA.y() + rectA.height()) endP = QPointF(rectB.x() + rectB.width() / 2.0, rectB.y()) self.setPoints(startP.x(), startP.y(), endP.x(), endP.y()) def __calculateEndingPoints_center(self): """ Private method to calculate the ending points of the association item. The ending points are calculated from the centers of the two associated items. """ if self.itemA is None or self.itemB is None: return self.prepareGeometryChange() rectA = self.__mapRectFromItem(self.itemA) rectB = self.__mapRectFromItem(self.itemB) midA = QPointF(rectA.x() + rectA.width() / 2.0, rectA.y() + rectA.height() / 2.0) midB = QPointF(rectB.x() + rectB.width() / 2.0, rectB.y() + rectB.height() / 2.0) startP = self.__findRectIntersectionPoint(self.itemA, midA, midB) endP = self.__findRectIntersectionPoint(self.itemB, midB, midA) if startP.x() != -1 and startP.y() != -1 and \ endP.x() != -1 and endP.y() != -1: self.setPoints(startP.x(), startP.y(), endP.x(), endP.y()) def __calculateEndingPoints_rectangle(self): r""" Private method to calculate the ending points of the association item. The ending points are calculated by the following method. For each item the diagram is divided in four Regions by its diagonals as indicated below
                   \  Region 2  /
                    \          /
                     |--------|
                     | \    / |
                     |  \  /  |
                     |   \/   |
            Region 1 |   /\   | Region 3
                     |  /  \  |
                     | /    \ |
                     |--------|
                    /          \
                   /  Region 4  \
        
Each diagonal is defined by two corners of the bounding rectangle To calculate the start point we have to find out in which region (defined by itemA's diagonals) is itemB's TopLeft corner (lets call it region M). After that the start point will be the middle point of rectangle's side contained in region M. To calculate the end point we repeat the above but in the opposite direction (from itemB to itemA) """ if self.itemA is None or self.itemB is None: return self.prepareGeometryChange() rectA = self.__mapRectFromItem(self.itemA) rectB = self.__mapRectFromItem(self.itemB) xA = rectA.x() + rectA.width() / 2.0 yA = rectA.y() + rectA.height() / 2.0 xB = rectB.x() + rectB.width() / 2.0 yB = rectB.y() + rectB.height() / 2.0 # find itemA region rc = QRectF(xA, yA, rectA.width(), rectA.height()) self.regionA = self.__findPointRegion(rc, xB, yB) # move some regions to the standard ones if self.regionA == NorthWest: self.regionA = North elif self.regionA == NorthEast: self.regionA = East elif self.regionA == SouthEast: self.regionA = South elif self.regionA == SouthWest: self.regionA = West elif self.regionA == Center: self.regionA = West self.__updateEndPoint(self.regionA, True) # now do the same for itemB rc = QRectF(xB, yB, rectB.width(), rectB.height()) self.regionB = self.__findPointRegion(rc, xA, yA) # move some regions to the standard ones if self.regionB == NorthWest: self.regionB = North elif self.regionB == NorthEast: self.regionB = East elif self.regionB == SouthEast: self.regionB = South elif self.regionB == SouthWest: self.regionB = West elif self.regionB == Center: self.regionB = West self.__updateEndPoint(self.regionB, False) def __findPointRegion(self, rect, posX, posY): """ Private method to find out, which region of rectangle rect contains the point (PosX, PosY) and returns the region number. @param rect rectangle to calculate the region for (QRectF) @param posX x position of point (float) @param posY y position of point (float) @return the calculated region number
West = Region 1
North = Region 2
East = Region 3
South = Region 4
NorthWest = On diagonal 2 between Region 1 and 2
NorthEast = On diagonal 1 between Region 2 and 3
SouthEast = On diagonal 2 between Region 3 and 4
SouthWest = On diagonal 1 between Region4 and 1
Center = On diagonal 1 and On diagonal 2 (the center)
""" w = rect.width() h = rect.height() x = rect.x() y = rect.y() slope2 = w / h slope1 = -slope2 b1 = x + w / 2.0 - y * slope1 b2 = x + w / 2.0 - y * slope2 eval1 = slope1 * posY + b1 eval2 = slope2 * posY + b2 result = NoRegion # inside region 1 if eval1 > posX and eval2 > posX: result = West #inside region 2 elif eval1 > posX and eval2 < posX: result = North # inside region 3 elif eval1 < posX and eval2 < posX: result = East # inside region 4 elif eval1 < posX and eval2 > posX: result = South # inside region 5 elif eval1 == posX and eval2 < posX: result = NorthWest # inside region 6 elif eval1 < posX and eval2 == posX: result = NorthEast # inside region 7 elif eval1 == posX and eval2 > posX: result = SouthEast # inside region 8 elif eval1 > posX and eval2 == posX: result = SouthWest # inside region 9 elif eval1 == posX and eval2 == posX: result = Center return result def __updateEndPoint(self, region, isWidgetA): """ Private method to update an endpoint. @param region the region for the endpoint (integer) @param isWidgetA flag indicating update for itemA is done (boolean) """ if region == NoRegion: return if isWidgetA: rect = self.__mapRectFromItem(self.itemA) else: rect = self.__mapRectFromItem(self.itemB) x = rect.x() y = rect.y() ww = rect.width() wh = rect.height() ch = wh / 2.0 cw = ww / 2.0 if region == West: px = x py = y + ch elif region == North: px = x + cw py = y elif region == East: px = x + ww py = y + ch elif region == South: px = x + cw py = y + wh elif region == Center: px = x + cw py = y + wh if isWidgetA: self.setStartPoint(px, py) else: self.setEndPoint(px, py) def __findRectIntersectionPoint(self, item, p1, p2): """ Private method to find the intersetion point of a line with a rectangle. @param item item to check against @param p1 first point of the line (QPointF) @param p2 second point of the line (QPointF) @return the intersection point (QPointF) """ rect = self.__mapRectFromItem(item) lines = [ QLineF(rect.topLeft(), rect.topRight()), QLineF(rect.topLeft(), rect.bottomLeft()), QLineF(rect.bottomRight(), rect.bottomLeft()), QLineF(rect.bottomRight(), rect.topRight()) ] intersectLine = QLineF(p1, p2) intersectPoint = QPointF(0, 0) for line in lines: if intersectLine.intersect(line, intersectPoint) == \ QLineF.BoundedIntersection: return intersectPoint return QPointF(-1.0, -1.0) def __findIntersection(self, p1, p2, p3, p4): """ Private method to calculate the intersection point of two lines. The first line is determined by the points p1 and p2, the second line by p3 and p4. If the intersection point is not contained in the segment p1p2, then it returns (-1.0, -1.0). For the function's internal calculations remember:
QT coordinates start with the point (0,0) as the topleft corner and x-values increase from left to right and y-values increase from top to bottom; it means the visible area is quadrant I in the regular XY coordinate system
            Quadrant II     |   Quadrant I
           -----------------|-----------------
            Quadrant III    |   Quadrant IV
        
In order for the linear function calculations to work in this method we must switch x and y values (x values become y values and viceversa) @param p1 first point of first line (QPointF) @param p2 second point of first line (QPointF) @param p3 first point of second line (QPointF) @param p4 second point of second line (QPointF) @return the intersection point (QPointF) """ x1 = p1.y() y1 = p1.x() x2 = p2.y() y2 = p2.x() x3 = p3.y() y3 = p3.x() x4 = p4.y() y4 = p4.x() # line 1 is the line between (x1, y1) and (x2, y2) # line 2 is the line between (x3, y3) and (x4, y4) no_line1 = True # it is false, if line 1 is a linear function no_line2 = True # it is false, if line 2 is a linear function slope1 = 0.0 slope2 = 0.0 b1 = 0.0 b2 = 0.0 if x2 != x1: slope1 = (y2 - y1) / (x2 - x1) b1 = y1 - slope1 * x1 no_line1 = False if x4 != x3: slope2 = (y4 - y3) / (x4 - x3) b2 = y3 - slope2 * x3 no_line2 = False pt = QPointF() # if either line is not a function if no_line1 and no_line2: # if the lines are not the same one if x1 != x3: return QPointF(-1.0, -1.0) # if the lines are the same ones if y3 <= y4: if y3 <= y1 and y1 <= y4: return QPointF(y1, x1) else: return QPointF(y2, x2) else: if y4 <= y1 and y1 <= y3: return QPointF(y1, x1) else: return QPointF(y2, x2) elif no_line1: pt.setX(slope2 * x1 + b2) pt.setY(x1) if y1 >= y2: if not (y2 <= pt.x() and pt.x() <= y1): pt.setX(-1.0) pt.setY(-1.0) else: if not (y1 <= pt.x() and pt.x() <= y2): pt.setX(-1.0) pt.setY(-1.0) return pt elif no_line2: pt.setX(slope1 * x3 + b1) pt.setY(x3) if y3 >= y4: if not (y4 <= pt.x() and pt.x() <= y3): pt.setX(-1.0) pt.setY(-1.0) else: if not (y3 <= pt.x() and pt.x() <= y4): pt.setX(-1.0) pt.setY(-1.0) return pt if slope1 == slope2: pt.setX(-1.0) pt.setY(-1.0) return pt pt.setY((b2 - b1) / (slope1 - slope2)) pt.setX(slope1 * pt.y() + b1) # the intersection point must be inside the segment (x1, y1) (x2, y2) if x2 >= x1 and y2 >= y1: if not ((x1 <= pt.y() and pt.y() <= x2) and (y1 <= pt.x() and pt.x() <= y2)): pt.setX(-1.0) pt.setY(-1.0) elif x2 < x1 and y2 >= y1: if not ((x2 <= pt.y() and pt.y() <= x1) and (y1 <= pt.x() and pt.x() <= y2)): pt.setX(-1.0) pt.setY(-1.0) elif x2 >= x1 and y2 < y1: if not ((x1 <= pt.y() and pt.y() <= x2) and (y2 <= pt.x() and pt.x() <= y1)): pt.setX(-1.0) pt.setY(-1.0) else: if not ((x2 <= pt.y() and pt.y() <= x1) and (y2 <= pt.x() and pt.x() <= y1)): pt.setX(-1.0) pt.setY(-1.0) return pt def widgetMoved(self): """ Public method to recalculate the association after a widget was moved. """ self.calculateEndingPoints() def unassociate(self): """ Public method to unassociate from the widgets. """ self.itemA.removeAssociation(self) self.itemB.removeAssociation(self) def buildAssociationItemDataString(self): """ Public method to build a string to persist the specific item data. This string should be built like "attribute=value" with pairs separated by ", ". value must not contain ", " or newlines. @return persistence data (string) """ entries = [ "src={0}".format(self.itemA.getId()), "dst={0}".format(self.itemB.getId()), "type={0}".format(self.assocType), "topToBottom={0}".format(self.topToBottom) ] return ", ".join(entries) @classmethod def parseAssociationItemDataString(cls, data): """ Class method to parse the given persistence data. @param data persisted data to be parsed (string) @return tuple with the IDs of the source and destination items, the association type and a flag indicating to associate from top to bottom (integer, integer, integer, boolean) """ src = -1 dst = -1 assocType = Normal topToBottom = False for entry in data.split(", "): if "=" in entry: key, value = entry.split("=", 1) if key == "src": src = int(value) elif key == "dst": dst = int(value) elif key == "type": assocType = int(value) elif key == "topToBottom": topToBottom = Utilities.toBool(value) return src, dst, assocType, topToBottom eric-6.0.8/eric/Graphics/ApplicationDiagramBuilder.py0000644000175000017500000002560112451233373021625 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog showing an imports diagram of the application. """ from __future__ import unicode_literals import os import glob from PyQt5.QtWidgets import QApplication from E5Gui import E5MessageBox from E5Gui.E5ProgressDialog import E5ProgressDialog from .UMLDiagramBuilder import UMLDiagramBuilder import Utilities import Preferences class ApplicationDiagramBuilder(UMLDiagramBuilder): """ Class implementing a builder for imports diagrams of the application. """ def __init__(self, dialog, view, project, noModules=False): """ Constructor @param dialog reference to the UML dialog (UMLDialog) @param view reference to the view object (UMLGraphicsView) @param project reference to the project object (Project) @keyparam noModules flag indicating, that no module names should be shown (boolean) """ super(ApplicationDiagramBuilder, self).__init__(dialog, view, project) self.setObjectName("ApplicationDiagram") self.noModules = noModules self.umlView.setDiagramName( self.tr("Application Diagram {0}").format( self.project.getProjectName())) def __buildModulesDict(self): """ Private method to build a dictionary of modules contained in the application. @return dictionary of modules contained in the application. """ import Utilities.ModuleParser extensions = Preferences.getPython("PythonExtensions") + \ Preferences.getPython("Python3Extensions") + ['.rb'] moduleDict = {} mods = self.project.pdata["SOURCES"] modules = [] for module in mods: modules.append(Utilities.normabsjoinpath( self.project.ppath, module)) tot = len(modules) progress = E5ProgressDialog( self.tr("Parsing modules..."), None, 0, tot, self.tr("%v/%m Modules"), self.parent()) progress.setWindowTitle(self.tr("Application Diagram")) try: prog = 0 progress.show() QApplication.processEvents() for module in modules: progress.setValue(prog) QApplication.processEvents() prog += 1 if module.endswith("__init__.py"): continue try: mod = Utilities.ModuleParser.readModule( module, extensions=extensions, caching=False) except ImportError: continue else: name = mod.name moduleDict[name] = mod finally: progress.setValue(tot) progress.deleteLater() return moduleDict def buildDiagram(self): """ Public method to build the packages shapes of the diagram. """ project = os.path.splitdrive(self.project.getProjectPath())[1]\ .replace(os.sep, '.')[1:] packages = {} shapes = {} p = 10 y = 10 maxHeight = 0 sceneRect = self.umlView.sceneRect() modules = self.__buildModulesDict() sortedkeys = sorted(modules.keys()) # step 1: build a dictionary of packages for module in sortedkeys: li = module.split('.') package = '.'.join(li[:-1]) if package in packages: packages[package][0].append(li[-1]) else: packages[package] = ([li[-1]], []) # step 2: assign modules to dictionaries and update import relationship for module in sortedkeys: li = module.split('.') package = '.'.join(li[:-1]) impLst = [] for i in modules[module].imports: if i in modules: impLst.append(i) else: if i.find('.') == -1: n = "{0}.{1}".format(modules[module].package, i) if n in modules: impLst.append(n) else: n = "{0}.{1}".format(project, i) if n in modules: impLst.append(n) elif n in packages: n = "{0}.<>".format(n) impLst.append(n) else: n = "{0}.{1}".format(project, i) if n in modules: impLst.append(n) for i in list(modules[module].from_imports.keys()): if i.startswith('.'): dots = len(i) - len(i.lstrip('.')) if dots == 1: i = i[1:] elif dots > 1: packagePath = os.path.dirname(modules[module].file) hasInit = True ppath = packagePath while hasInit: ppath = os.path.dirname(ppath) hasInit = len(glob.glob(os.path.join( ppath, '__init__.*'))) > 0 shortPackage = packagePath.replace(ppath, '')\ .replace(os.sep, '.')[1:] packageList = shortPackage.split('.')[1:] packageListLen = len(packageList) i = '.'.join( packageList[:packageListLen - dots + 1] + [i[dots:]]) if i in modules: impLst.append(i) else: if i.find('.') == -1: n = "{0}.{1}".format(modules[module].package, i) if n in modules: impLst.append(n) else: n = "{0}.{1}".format(project, i) if n in modules: impLst.append(n) elif n in packages: n = "{0}.<>".format(n) impLst.append(n) else: n = "{0}.{1}".format(project, i) if n in modules: impLst.append(n) for imp in impLst: impPackage = '.'.join(imp.split('.')[:-1]) if impPackage not in packages[package][1] and \ not impPackage == package: packages[package][1].append(impPackage) sortedkeys = sorted(packages.keys()) for package in sortedkeys: if package: relPackage = package.replace(project, '') if relPackage and relPackage[0] == '.': relPackage = relPackage[1:] else: relPackage = self.tr("<>") else: relPackage = self.tr("<>") shape = self.__addPackage( relPackage, packages[package][0], 0.0, 0.0) shapeRect = shape.sceneBoundingRect() shapes[package] = (shape, packages[package][1]) pn = p + shapeRect.width() + 10 maxHeight = max(maxHeight, shapeRect.height()) if pn > sceneRect.width(): p = 10 y += maxHeight + 10 maxHeight = shapeRect.height() shape.setPos(p, y) p += shapeRect.width() + 10 else: shape.setPos(p, y) p = pn rect = self.umlView._getDiagramRect(10) sceneRect = self.umlView.sceneRect() if rect.width() > sceneRect.width(): sceneRect.setWidth(rect.width()) if rect.height() > sceneRect.height(): sceneRect.setHeight(rect.height()) self.umlView.setSceneSize(sceneRect.width(), sceneRect.height()) self.__createAssociations(shapes) self.umlView.autoAdjustSceneSize(limit=True) def __addPackage(self, name, modules, x, y): """ Private method to add a package to the diagram. @param name package name to be shown (string) @param modules list of module names contained in the package (list of strings) @param x x-coordinate (float) @param y y-coordinate (float) @return reference to the package item (PackageItem) """ from .PackageItem import PackageItem, PackageModel modules.sort() pm = PackageModel(name, modules) pw = PackageItem(pm, x, y, noModules=self.noModules, scene=self.scene) pw.setId(self.umlView.getItemId()) return pw def __createAssociations(self, shapes): """ Private method to generate the associations between the package shapes. @param shapes list of shapes """ from .AssociationItem import AssociationItem, Imports for package in shapes: for rel in shapes[package][1]: assoc = AssociationItem( shapes[package][0], shapes[rel][0], Imports) self.scene.addItem(assoc) def getPersistenceData(self): """ Public method to get a string for data to be persisted. @return persisted data string (string) """ return "project={0}, no_modules={1}".format( self.project.getProjectFile(), self.noModules) def parsePersistenceData(self, version, data): """ Public method to parse persisted data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ parts = data.split(", ") if len(parts) != 2 or \ not parts[0].startswith("project=") or \ not parts[1].startswith("no_modules="): return False projectFile = parts[0].split("=", 1)[1].strip() if projectFile != self.project.getProjectFile(): res = E5MessageBox.yesNo( None, self.tr("Load Diagram"), self.tr( """

The diagram belongs to the project {0}.""" """ Shall this project be opened?

""").format( projectFile)) if res: self.project.openProject(projectFile) self.noModules = Utilities.toBool(parts[1].split("=", 1)[1].strip()) self.initialize() return True eric-6.0.8/eric/Graphics/UMLItem.py0000644000175000017500000001603712451233373016045 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing the UMLItem base class. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QSizeF from PyQt5.QtWidgets import QGraphicsItem, QGraphicsRectItem, QStyle import Preferences class UMLModel(object): """ Class implementing the UMLModel base class. """ def __init__(self, name): """ Constructor @param name package name (string) """ self.name = name def getName(self): """ Public method to retrieve the model name. @return model name (string) """ return self.name class UMLItem(QGraphicsRectItem): """ Class implementing the UMLItem base class. """ ItemType = "UMLItem" def __init__(self, model=None, x=0, y=0, rounded=False, parent=None): """ Constructor @param model UML model containing the item data (UMLModel) @param x x-coordinate (integer) @param y y-coordinate (integer) @param rounded flag indicating a rounded corner (boolean) @keyparam parent reference to the parent object (QGraphicsItem) """ super(UMLItem, self).__init__(parent) self.model = model self.font = Preferences.getGraphics("Font") self.margin = 5 self.associations = [] self.shouldAdjustAssociations = False self.__id = -1 self.setRect(x, y, 60, 30) if rounded: p = self.pen() p.setCapStyle(Qt.RoundCap) p.setJoinStyle(Qt.RoundJoin) self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) try: self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) except AttributeError: # only available for Qt 4.6.0 and newer pass def getName(self): """ Public method to retrieve the item name. @return item name (string) """ if self.model: return self.model.name else: return "" def setSize(self, width, height): """ Public method to set the rectangles size. @param width width of the rectangle (float) @param height height of the rectangle (float) """ rect = self.rect() rect.setSize(QSizeF(width, height)) self.setRect(rect) def addAssociation(self, assoc): """ Public method to add an association to this widget. @param assoc association to be added (AssociationWidget) """ if assoc and assoc not in self.associations: self.associations.append(assoc) def removeAssociation(self, assoc): """ Public method to remove an association to this widget. @param assoc association to be removed (AssociationWidget) """ if assoc and assoc in self.associations: self.associations.remove(assoc) def removeAssociations(self): """ Public method to remove all associations of this widget. """ for assoc in self.associations[:]: assoc.unassociate() assoc.hide() del assoc def adjustAssociations(self): """ Public method to adjust the associations to widget movements. """ if self.shouldAdjustAssociations: for assoc in self.associations: assoc.widgetMoved() self.shouldAdjustAssociations = False def moveBy(self, dx, dy): """ Public overriden method to move the widget relative. @param dx relative movement in x-direction (float) @param dy relative movement in y-direction (float) """ super(UMLItem, self).moveBy(dx, dy) self.adjustAssociations() def setPos(self, x, y): """ Public overriden method to set the items position. @param x absolute x-position (float) @param y absolute y-position (float) """ super(UMLItem, self).setPos(x, y) self.adjustAssociations() def itemChange(self, change, value): """ Public method called when an items state changes. @param change the item's change (QGraphicsItem.GraphicsItemChange) @param value the value of the change @return adjusted values """ if change == QGraphicsItem.ItemPositionChange: # 1. remember to adjust associations self.shouldAdjustAssociations = True # 2. ensure the new position is inside the scene rect = self.scene().sceneRect() if not rect.contains(value): # keep the item inside the scene value.setX(min(rect.right(), max(value.x(), rect.left()))) value.setY(min(rect.bottom(), max(value.y(), rect.top()))) return value return QGraphicsItem.itemChange(self, change, value) def paint(self, painter, option, widget=None): """ Public method to paint the item in local coordinates. @param painter reference to the painter object (QPainter) @param option style options (QStyleOptionGraphicsItem) @param widget optional reference to the widget painted on (QWidget) """ pen = self.pen() if (option.state & QStyle.State_Selected) == \ QStyle.State(QStyle.State_Selected): pen.setWidth(2) else: pen.setWidth(1) painter.setPen(pen) painter.setBrush(self.brush()) painter.drawRect(self.rect()) self.adjustAssociations() def setId(self, id): """ Public method to assign an ID to the item. @param id assigned ID (integer) """ self.__id = id def getId(self): """ Public method to get the item ID. @return ID of the item (integer) """ return self.__id def getItemType(self): """ Public method to get the item's type. @return item type (string) """ return self.ItemType def buildItemDataString(self): """ Public method to build a string to persist the specific item data. This string must start with ", " and should be built like "attribute=value" with pairs separated by ", ". value must not contain ", " or newlines. @return persistence data (string) """ return "" def parseItemDataString(self, version, data): """ Public method to parse the given persistence data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ return True eric-6.0.8/eric/Graphics/UMLGraphicsView.py0000644000175000017500000006636712451233373017555 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a subclass of E5GraphicsView for our diagrams. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QSignalMapper, QFileInfo, QEvent, \ QRectF, qVersion from PyQt5.QtWidgets import QGraphicsView, QAction, QToolBar, QDialog from PyQt5.QtPrintSupport import QPrinter, QPrintDialog from E5Graphics.E5GraphicsView import E5GraphicsView from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5ZoomWidget import E5ZoomWidget from .UMLItem import UMLItem import UI.Config import UI.PixmapCache import Preferences class UMLGraphicsView(E5GraphicsView): """ Class implementing a specialized E5GraphicsView for our diagrams. @signal relayout() emitted to indicate a relayout of the diagram is requested """ relayout = pyqtSignal() def __init__(self, scene, parent=None): """ Constructor @param scene reference to the scene object (QGraphicsScene) @param parent parent widget of the view (QWidget) """ E5GraphicsView.__init__(self, scene, parent) self.setObjectName("UMLGraphicsView") self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.diagramName = "Unnamed" self.__itemId = -1 self.border = 10 self.deltaSize = 100.0 self.__zoomWidget = E5ZoomWidget( UI.PixmapCache.getPixmap("zoomOut.png"), UI.PixmapCache.getPixmap("zoomIn.png"), UI.PixmapCache.getPixmap("zoomReset.png"), self) parent.statusBar().addPermanentWidget(self.__zoomWidget) self.__zoomWidget.setMapping( E5GraphicsView.ZoomLevels, E5GraphicsView.ZoomLevelDefault) self.__zoomWidget.valueChanged.connect(self.setZoom) self.zoomValueChanged.connect(self.__zoomWidget.setValue) self.__initActions() scene.changed.connect(self.__sceneChanged) self.grabGesture(Qt.PinchGesture) def __initActions(self): """ Private method to initialize the view actions. """ self.alignMapper = QSignalMapper(self) self.alignMapper.mapped[int].connect(self.__alignShapes) self.deleteShapeAct = \ QAction(UI.PixmapCache.getIcon("deleteShape.png"), self.tr("Delete shapes"), self) self.deleteShapeAct.triggered.connect(self.__deleteShape) self.incWidthAct = \ QAction(UI.PixmapCache.getIcon("sceneWidthInc.png"), self.tr("Increase width by {0} points").format( self.deltaSize), self) self.incWidthAct.triggered.connect(self.__incWidth) self.incHeightAct = \ QAction(UI.PixmapCache.getIcon("sceneHeightInc.png"), self.tr("Increase height by {0} points").format( self.deltaSize), self) self.incHeightAct.triggered.connect(self.__incHeight) self.decWidthAct = \ QAction(UI.PixmapCache.getIcon("sceneWidthDec.png"), self.tr("Decrease width by {0} points").format( self.deltaSize), self) self.decWidthAct.triggered.connect(self.__decWidth) self.decHeightAct = \ QAction(UI.PixmapCache.getIcon("sceneHeightDec.png"), self.tr("Decrease height by {0} points").format( self.deltaSize), self) self.decHeightAct.triggered.connect(self.__decHeight) self.setSizeAct = \ QAction(UI.PixmapCache.getIcon("sceneSize.png"), self.tr("Set size"), self) self.setSizeAct.triggered.connect(self.__setSize) self.rescanAct = \ QAction(UI.PixmapCache.getIcon("rescan.png"), self.tr("Re-Scan"), self) self.rescanAct.triggered.connect(self.__rescan) self.relayoutAct = \ QAction(UI.PixmapCache.getIcon("relayout.png"), self.tr("Re-Layout"), self) self.relayoutAct.triggered.connect(self.__relayout) self.alignLeftAct = \ QAction(UI.PixmapCache.getIcon("shapesAlignLeft.png"), self.tr("Align Left"), self) self.alignMapper.setMapping(self.alignLeftAct, Qt.AlignLeft) self.alignLeftAct.triggered.connect(self.alignMapper.map) self.alignHCenterAct = \ QAction(UI.PixmapCache.getIcon("shapesAlignHCenter.png"), self.tr("Align Center Horizontal"), self) self.alignMapper.setMapping(self.alignHCenterAct, Qt.AlignHCenter) self.alignHCenterAct.triggered.connect(self.alignMapper.map) self.alignRightAct = \ QAction(UI.PixmapCache.getIcon("shapesAlignRight.png"), self.tr("Align Right"), self) self.alignMapper.setMapping(self.alignRightAct, Qt.AlignRight) self.alignRightAct.triggered.connect(self.alignMapper.map) self.alignTopAct = \ QAction(UI.PixmapCache.getIcon("shapesAlignTop.png"), self.tr("Align Top"), self) self.alignMapper.setMapping(self.alignTopAct, Qt.AlignTop) self.alignTopAct.triggered.connect(self.alignMapper.map) self.alignVCenterAct = \ QAction(UI.PixmapCache.getIcon("shapesAlignVCenter.png"), self.tr("Align Center Vertical"), self) self.alignMapper.setMapping(self.alignVCenterAct, Qt.AlignVCenter) self.alignVCenterAct.triggered.connect(self.alignMapper.map) self.alignBottomAct = \ QAction(UI.PixmapCache.getIcon("shapesAlignBottom.png"), self.tr("Align Bottom"), self) self.alignMapper.setMapping(self.alignBottomAct, Qt.AlignBottom) self.alignBottomAct.triggered.connect(self.alignMapper.map) def __checkSizeActions(self): """ Private slot to set the enabled state of the size actions. """ diagramSize = self._getDiagramSize(10) sceneRect = self.scene().sceneRect() if (sceneRect.width() - self.deltaSize) < diagramSize.width(): self.decWidthAct.setEnabled(False) else: self.decWidthAct.setEnabled(True) if (sceneRect.height() - self.deltaSize) < diagramSize.height(): self.decHeightAct.setEnabled(False) else: self.decHeightAct.setEnabled(True) def __sceneChanged(self, areas): """ Private slot called when the scene changes. @param areas list of rectangles that contain changes (list of QRectF) """ if len(self.scene().selectedItems()) > 0: self.deleteShapeAct.setEnabled(True) else: self.deleteShapeAct.setEnabled(False) sceneRect = self.scene().sceneRect() newWidth = width = sceneRect.width() newHeight = height = sceneRect.height() rect = self.scene().itemsBoundingRect() # calculate with 10 pixel border on each side if sceneRect.right() - 10 < rect.right(): newWidth = rect.right() + 10 if sceneRect.bottom() - 10 < rect.bottom(): newHeight = rect.bottom() + 10 if newHeight != height or newWidth != width: self.setSceneSize(newWidth, newHeight) self.__checkSizeActions() def initToolBar(self): """ Public method to populate a toolbar with our actions. @return the populated toolBar (QToolBar) """ toolBar = QToolBar(self.tr("Graphics"), self) toolBar.setIconSize(UI.Config.ToolBarIconSize) toolBar.addAction(self.deleteShapeAct) toolBar.addSeparator() toolBar.addAction(self.alignLeftAct) toolBar.addAction(self.alignHCenterAct) toolBar.addAction(self.alignRightAct) toolBar.addAction(self.alignTopAct) toolBar.addAction(self.alignVCenterAct) toolBar.addAction(self.alignBottomAct) toolBar.addSeparator() toolBar.addAction(self.incWidthAct) toolBar.addAction(self.incHeightAct) toolBar.addAction(self.decWidthAct) toolBar.addAction(self.decHeightAct) toolBar.addAction(self.setSizeAct) toolBar.addSeparator() toolBar.addAction(self.rescanAct) toolBar.addAction(self.relayoutAct) return toolBar def filteredItems(self, items, itemType=UMLItem): """ Public method to filter a list of items. @param items list of items as returned by the scene object (QGraphicsItem) @param itemType type to be filtered (class) @return list of interesting collision items (QGraphicsItem) """ return [itm for itm in items if isinstance(itm, itemType)] def selectItems(self, items): """ Public method to select the given items. @param items list of items to be selected (list of QGraphicsItemItem) """ # step 1: deselect all items self.unselectItems() # step 2: select all given items for itm in items: if isinstance(itm, UMLItem): itm.setSelected(True) def selectItem(self, item): """ Public method to select an item. @param item item to be selected (QGraphicsItemItem) """ if isinstance(item, UMLItem): item.setSelected(not item.isSelected()) def __deleteShape(self): """ Private method to delete the selected shapes from the display. """ for item in self.scene().selectedItems(): item.removeAssociations() item.setSelected(False) self.scene().removeItem(item) del item def __incWidth(self): """ Private method to handle the increase width context menu entry. """ self.resizeScene(self.deltaSize, True) self.__checkSizeActions() def __incHeight(self): """ Private method to handle the increase height context menu entry. """ self.resizeScene(self.deltaSize, False) self.__checkSizeActions() def __decWidth(self): """ Private method to handle the decrease width context menu entry. """ self.resizeScene(-self.deltaSize, True) self.__checkSizeActions() def __decHeight(self): """ Private method to handle the decrease height context menu entry. """ self.resizeScene(-self.deltaSize, False) self.__checkSizeActions() def __setSize(self): """ Private method to handle the set size context menu entry. """ from .UMLSceneSizeDialog import UMLSceneSizeDialog rect = self._getDiagramRect(10) sceneRect = self.scene().sceneRect() dlg = UMLSceneSizeDialog(sceneRect.width(), sceneRect.height(), rect.width(), rect.height(), self) if dlg.exec_() == QDialog.Accepted: width, height = dlg.getData() self.setSceneSize(width, height) self.__checkSizeActions() def autoAdjustSceneSize(self, limit=False): """ Public method to adjust the scene size to the diagram size. @param limit flag indicating to limit the scene to the initial size (boolean) """ super(UMLGraphicsView, self).autoAdjustSceneSize(limit=limit) self.__checkSizeActions() def saveImage(self): """ Public method to handle the save context menu entry. """ fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Diagram"), "", self.tr("Portable Network Graphics (*.png);;" "Scalable Vector Graphics (*.svg)"), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fname: ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Diagram"), self.tr("

The file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return success = super(UMLGraphicsView, self).saveImage( fname, QFileInfo(fname).suffix().upper()) if not success: E5MessageBox.critical( self, self.tr("Save Diagram"), self.tr( """

The file {0} could not be saved.

""") .format(fname)) def __relayout(self): """ Private slot to handle the re-layout context menu entry. """ self.__itemId = -1 self.scene().clear() self.relayout.emit() def __rescan(self): """ Private slot to handle the re-scan context menu entry. """ # 1. save positions of all items and names of selected items itemPositions = {} selectedItems = [] for item in self.filteredItems(self.scene().items(), UMLItem): name = item.getName() if name: itemPositions[name] = (item.x(), item.y()) if item.isSelected(): selectedItems.append(name) # 2. save # 2. re-layout the diagram self.__relayout() # 3. move known items to the saved positions for item in self.filteredItems(self.scene().items(), UMLItem): name = item.getName() if name in itemPositions: item.setPos(*itemPositions[name]) if name in selectedItems: item.setSelected(True) def printDiagram(self): """ Public slot called to print the diagram. """ printer = QPrinter(mode=QPrinter.ScreenResolution) printer.setFullPage(True) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printer.setPageMargins( Preferences.getPrinter("LeftMargin") * 10, Preferences.getPrinter("TopMargin") * 10, Preferences.getPrinter("RightMargin") * 10, Preferences.getPrinter("BottomMargin") * 10, QPrinter.Millimeter ) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) printDialog = QPrintDialog(printer, self) if printDialog.exec_(): super(UMLGraphicsView, self).printDiagram( printer, self.diagramName) def printPreviewDiagram(self): """ Public slot called to show a print preview of the diagram. """ from PyQt5.QtPrintSupport import QPrintPreviewDialog printer = QPrinter(mode=QPrinter.ScreenResolution) printer.setFullPage(True) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printer.setPageMargins( Preferences.getPrinter("LeftMargin") * 10, Preferences.getPrinter("TopMargin") * 10, Preferences.getPrinter("RightMargin") * 10, Preferences.getPrinter("BottomMargin") * 10, QPrinter.Millimeter ) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) preview = QPrintPreviewDialog(printer, self) preview.paintRequested[QPrinter].connect(self.__printPreviewPrint) preview.exec_() def __printPreviewPrint(self, printer): """ Private slot to generate a print preview. @param printer reference to the printer object (QPrinter) """ super(UMLGraphicsView, self).printDiagram(printer, self.diagramName) def setDiagramName(self, name): """ Public slot to set the diagram name. @param name diagram name (string) """ self.diagramName = name def __alignShapes(self, alignment): """ Private slot to align the selected shapes. @param alignment alignment type (Qt.AlignmentFlag) """ # step 1: get all selected items items = self.scene().selectedItems() if len(items) <= 1: return # step 2: find the index of the item to align in relation to amount = None for i, item in enumerate(items): rect = item.sceneBoundingRect() if alignment == Qt.AlignLeft: if amount is None or rect.x() < amount: amount = rect.x() index = i elif alignment == Qt.AlignRight: if amount is None or rect.x() + rect.width() > amount: amount = rect.x() + rect.width() index = i elif alignment == Qt.AlignHCenter: if amount is None or rect.width() > amount: amount = rect.width() index = i elif alignment == Qt.AlignTop: if amount is None or rect.y() < amount: amount = rect.y() index = i elif alignment == Qt.AlignBottom: if amount is None or rect.y() + rect.height() > amount: amount = rect.y() + rect.height() index = i elif alignment == Qt.AlignVCenter: if amount is None or rect.height() > amount: amount = rect.height() index = i rect = items[index].sceneBoundingRect() # step 3: move the other items for i, item in enumerate(items): if i == index: continue itemrect = item.sceneBoundingRect() xOffset = yOffset = 0 if alignment == Qt.AlignLeft: xOffset = rect.x() - itemrect.x() elif alignment == Qt.AlignRight: xOffset = (rect.x() + rect.width()) - \ (itemrect.x() + itemrect.width()) elif alignment == Qt.AlignHCenter: xOffset = (rect.x() + rect.width() // 2) - \ (itemrect.x() + itemrect.width() // 2) elif alignment == Qt.AlignTop: yOffset = rect.y() - itemrect.y() elif alignment == Qt.AlignBottom: yOffset = (rect.y() + rect.height()) - \ (itemrect.y() + itemrect.height()) elif alignment == Qt.AlignVCenter: yOffset = (rect.y() + rect.height() // 2) - \ (itemrect.y() + itemrect.height() // 2) item.moveBy(xOffset, yOffset) self.scene().update() def __itemsBoundingRect(self, items): """ Private method to calculate the bounding rectangle of the given items. @param items list of items to operate on (list of UMLItem) @return bounding rectangle (QRectF) """ rect = self.scene().sceneRect() right = rect.left() bottom = rect.top() left = rect.right() top = rect.bottom() for item in items: rect = item.sceneBoundingRect() left = min(rect.left(), left) right = max(rect.right(), right) top = min(rect.top(), top) bottom = max(rect.bottom(), bottom) return QRectF(left, top, right - left, bottom - top) def keyPressEvent(self, evt): """ Protected method handling key press events. @param evt reference to the key event (QKeyEvent) """ key = evt.key() if key in [Qt.Key_Up, Qt.Key_Down, Qt.Key_Left, Qt.Key_Right]: items = self.filteredItems(self.scene().selectedItems()) if items: if evt.modifiers() & Qt.ControlModifier: stepSize = 50 else: stepSize = 5 if key == Qt.Key_Up: dx = 0 dy = -stepSize elif key == Qt.Key_Down: dx = 0 dy = stepSize elif key == Qt.Key_Left: dx = -stepSize dy = 0 else: dx = stepSize dy = 0 for item in items: item.moveBy(dx, dy) evt.accept() return super(UMLGraphicsView, self).keyPressEvent(evt) def wheelEvent(self, evt): """ Protected method to handle wheel events. @param evt reference to the wheel event (QWheelEvent) """ if evt.modifiers() & Qt.ControlModifier: if qVersion() >= "5.0.0": delta = evt.angleDelta().y() else: delta = evt.delta() if delta < 0: self.zoomOut() else: self.zoomIn() evt.accept() return super(UMLGraphicsView, self).wheelEvent(evt) def event(self, evt): """ Public method handling events. @param evt reference to the event (QEvent) @return flag indicating, if the event was handled (boolean) """ if evt.type() == QEvent.Gesture: self.gestureEvent(evt) return True return super(UMLGraphicsView, self).event(evt) def gestureEvent(self, evt): """ Protected method handling gesture events. @param evt reference to the gesture event (QGestureEvent """ pinch = evt.gesture(Qt.PinchGesture) if pinch: if pinch.state() == Qt.GestureStarted: pinch.setScaleFactor(self.zoom() / 100.0) else: self.setZoom(int(pinch.scaleFactor() * 100)) evt.accept() def getItemId(self): """ Public method to get the ID to be assigned to an item. @return item ID (integer) """ self.__itemId += 1 return self.__itemId def findItem(self, id): """ Public method to find an UML item based on the ID. @param id of the item to search for (integer) @return item found (UMLItem) or None """ for item in self.scene().items(): try: if item.getId() == id: return item except AttributeError: continue return None def findItemByName(self, name): """ Public method to find an UML item based on its name. @param name name to look for (string) @return item found (UMLItem) or None """ for item in self.scene().items(): try: if item.getName() == name: return item except AttributeError: continue return None def getPersistenceData(self): """ Public method to get a list of data to be persisted. @return list of data to be persisted (list of strings) """ lines = [ "diagram_name: {0}".format(self.diagramName), ] for item in self.filteredItems(self.scene().items(), UMLItem): lines.append("item: id={0}, x={1}, y={2}, item_type={3}{4}".format( item.getId(), item.x(), item.y(), item.getItemType(), item.buildItemDataString())) from .AssociationItem import AssociationItem for item in self.filteredItems(self.scene().items(), AssociationItem): lines.append("association: {0}".format( item.buildAssociationItemDataString())) return lines def parsePersistenceData(self, version, data): """ Public method to parse persisted data. @param version version of the data (string) @param data persisted data to be parsed (list of string) @return tuple of flag indicating success (boolean) and faulty line number (integer) """ umlItems = {} if not data[0].startswith("diagram_name:"): return False, 0 self.diagramName = data[0].split(": ", 1)[1].strip() from .ClassItem import ClassItem from .ModuleItem import ModuleItem from .PackageItem import PackageItem from .AssociationItem import AssociationItem linenum = 0 for line in data[1:]: linenum += 1 if not line.startswith(("item:", "association:")): return False, linenum key, value = line.split(": ", 1) if key == "item": id, x, y, itemType, itemData = value.split(", ", 4) try: id = int(id.split("=", 1)[1].strip()) x = float(x.split("=", 1)[1].strip()) y = float(y.split("=", 1)[1].strip()) itemType = itemType.split("=", 1)[1].strip() if itemType == ClassItem.ItemType: itm = ClassItem(x=x, y=y, scene=self.scene()) elif itemType == ModuleItem.ItemType: itm = ModuleItem(x=x, y=y, scene=self.scene()) elif itemType == PackageItem.ItemType: itm = PackageItem(x=x, y=y, scene=self.scene()) itm.setId(id) umlItems[id] = itm if not itm.parseItemDataString(version, itemData): return False, linenum except ValueError: return False, linenum elif key == "association": srcId, dstId, assocType, topToBottom = \ AssociationItem.parseAssociationItemDataString( value.strip()) assoc = AssociationItem(umlItems[srcId], umlItems[dstId], assocType, topToBottom) self.scene().addItem(assoc) return True, -1 eric-6.0.8/eric/Graphics/ClassItem.py0000644000175000017500000002152612451233373016454 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing an UML like class item. """ from __future__ import unicode_literals from PyQt5.QtGui import QFont from PyQt5.QtWidgets import QGraphicsSimpleTextItem, QStyle from .UMLItem import UMLModel, UMLItem import Utilities class ClassModel(UMLModel): """ Class implementing the class model. """ def __init__(self, name, methods=[], attributes=[]): """ Constructor @param name the class name (string) @param methods list of method names of the class (list of strings) @param attributes list of attribute names of the class (list of strings) """ super(ClassModel, self).__init__(name) self.methods = methods self.attributes = attributes def addMethod(self, method): """ Public method to add a method to the class model. @param method method name to be added (string) """ self.methods.append(method) def addAttribute(self, attribute): """ Public method to add an attribute to the class model. @param attribute attribute name to be added (string) """ self.attributes.append(attribute) def getMethods(self): """ Public method to retrieve the methods of the class. @return list of class methods (list of strings) """ return self.methods[:] def getAttributes(self): """ Public method to retrieve the attributes of the class. @return list of class attributes (list of strings) """ return self.attributes[:] class ClassItem(UMLItem): """ Class implementing an UML like class item. """ ItemType = "class" def __init__(self, model=None, external=False, x=0, y=0, rounded=False, noAttrs=False, parent=None, scene=None): """ Constructor @param model class model containing the class data (ClassModel) @param external flag indicating a class defined outside our scope (boolean) @param x x-coordinate (integer) @param y y-coordinate (integer) @keyparam rounded flag indicating a rounded corner (boolean) @keyparam noAttrs flag indicating, that no attributes should be shown (boolean) @keyparam parent reference to the parent object (QGraphicsItem) @keyparam scene reference to the scene object (QGraphicsScene) """ UMLItem.__init__(self, model, x, y, rounded, parent) self.external = external self.noAttrs = noAttrs scene.addItem(self) if self.model: self.__createTexts() self.__calculateSize() def __createTexts(self): """ Private method to create the text items of the class item. """ if self.model is None: return boldFont = QFont(self.font) boldFont.setBold(True) attrs = self.model.getAttributes() meths = self.model.getMethods() x = self.margin + self.rect().x() y = self.margin + self.rect().y() self.header = QGraphicsSimpleTextItem(self) self.header.setFont(boldFont) self.header.setText(self.model.getName()) self.header.setPos(x, y) y += self.header.boundingRect().height() + self.margin if not self.noAttrs and not self.external: if attrs: txt = "\n".join(attrs) else: txt = " " self.attrs = QGraphicsSimpleTextItem(self) self.attrs.setFont(self.font) self.attrs.setText(txt) self.attrs.setPos(x, y) y += self.attrs.boundingRect().height() + self.margin else: self.attrs = None if meths: txt = "\n".join(meths) else: txt = " " self.meths = QGraphicsSimpleTextItem(self) self.meths.setFont(self.font) self.meths.setText(txt) self.meths.setPos(x, y) def __calculateSize(self): """ Private method to calculate the size of the class item. """ if self.model is None: return width = self.header.boundingRect().width() height = self.header.boundingRect().height() if self.attrs: width = max(width, self.attrs.boundingRect().width()) height = height + self.attrs.boundingRect().height() + self.margin if self.meths: width = max(width, self.meths.boundingRect().width()) height = height + self.meths.boundingRect().height() self.setSize(width + 2 * self.margin, height + 2 * self.margin) def setModel(self, model): """ Public method to set the class model. @param model class model containing the class data (ClassModel) """ self.scene().removeItem(self.header) self.header = None if self.attrs: self.scene().removeItem(self.attrs) self.attrs = None if self.meths: self.scene().removeItem(self.meths) self.meths = None self.model = model self.__createTexts() self.__calculateSize() def paint(self, painter, option, widget=None): """ Public method to paint the item in local coordinates. @param painter reference to the painter object (QPainter) @param option style options (QStyleOptionGraphicsItem) @param widget optional reference to the widget painted on (QWidget) """ pen = self.pen() if (option.state & QStyle.State_Selected) == \ QStyle.State(QStyle.State_Selected): pen.setWidth(2) else: pen.setWidth(1) painter.setPen(pen) painter.setBrush(self.brush()) painter.setFont(self.font) offsetX = self.rect().x() offsetY = self.rect().y() w = self.rect().width() h = self.rect().height() painter.drawRect(offsetX, offsetY, w, h) y = self.margin + self.header.boundingRect().height() painter.drawLine(offsetX, offsetY + y, offsetX + w - 1, offsetY + y) if self.attrs: y += self.margin + self.attrs.boundingRect().height() painter.drawLine(offsetX, offsetY + y, offsetX + w - 1, offsetY + y) self.adjustAssociations() def isExternal(self): """ Public method returning the external state. @return external state (boolean) """ return self.external def buildItemDataString(self): """ Public method to build a string to persist the specific item data. This string must start with ", " and should be built like "attribute=value" with pairs separated by ", ". value must not contain ", " or newlines. @return persistence data (string) """ entries = [ "is_external={0}".format(self.external), "no_attributes={0}".format(self.noAttrs), "name={0}".format(self.model.getName()), ] attributes = self.model.getAttributes() if attributes: entries.append("attributes={0}".format("||".join(attributes))) methods = self.model.getMethods() if methods: entries.append("methods={0}".format("||".join(methods))) return ", " + ", ".join(entries) def parseItemDataString(self, version, data): """ Public method to parse the given persistence data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ parts = data.split(", ") if len(parts) < 3: return False name = "" attributes = [] methods = [] for part in parts: key, value = part.split("=", 1) if key == "is_external": self.external = Utilities.toBool(value.strip()) elif key == "no_attributes": self.noAttrs = Utilities.toBool(value.strip()) elif key == "name": name = value.strip() elif key == "attributes": attributes = value.strip().split("||") elif key == "methods": methods = value.strip().split("||") else: return False self.model = ClassModel(name, methods, attributes) self.__createTexts() self.__calculateSize() return True eric-6.0.8/eric/Graphics/PackageDiagramBuilder.py0000644000175000017500000004257012451233373020721 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog showing a UML like class diagram of a package. """ from __future__ import unicode_literals import glob import os.path try: # Py3 from itertools import zip_longest except ImportError: from itertools import izip_longest as zip_longest # __IGNORE_WARNING__ from PyQt5.QtWidgets import QApplication, QGraphicsTextItem from E5Gui.E5ProgressDialog import E5ProgressDialog from .UMLDiagramBuilder import UMLDiagramBuilder import Utilities import Preferences class PackageDiagramBuilder(UMLDiagramBuilder): """ Class implementing a builder for UML like class diagrams of a package. """ def __init__(self, dialog, view, project, package, noAttrs=False): """ Constructor @param dialog reference to the UML dialog (UMLDialog) @param view reference to the view object (UMLGraphicsView) @param project reference to the project object (Project) @param package name of a python package to be shown (string) @keyparam noAttrs flag indicating, that no attributes should be shown (boolean) """ super(PackageDiagramBuilder, self).__init__(dialog, view, project) self.setObjectName("PackageDiagram") self.package = Utilities.normabspath(package) self.noAttrs = noAttrs def initialize(self): """ Public method to initialize the object. """ pname = self.project.getProjectName() if pname: name = self.tr("Package Diagram {0}: {1}").format( pname, self.project.getRelativePath(self.package)) else: name = self.tr("Package Diagram: {0}").format(self.package) self.umlView.setDiagramName(name) def __getCurrentShape(self, name): """ Private method to get the named shape. @param name name of the shape (string) @return shape (QCanvasItem) """ return self.allClasses.get(name) def __buildModulesDict(self): """ Private method to build a dictionary of modules contained in the package. @return dictionary of modules contained in the package. """ import Utilities.ModuleParser supportedExt = \ ['*{0}'.format(ext) for ext in Preferences.getPython("PythonExtensions")] + \ ['*{0}'.format(ext) for ext in Preferences.getPython("Python3Extensions")] + \ ['*.rb'] extensions = Preferences.getPython("PythonExtensions") + \ Preferences.getPython("Python3Extensions") + ['.rb'] moduleDict = {} modules = [] for ext in supportedExt: modules.extend(glob.glob( Utilities.normjoinpath(self.package, ext))) tot = len(modules) progress = E5ProgressDialog( self.tr("Parsing modules..."), None, 0, tot, self.tr("%v/%m Modules"), self.parent()) progress.setWindowTitle(self.tr("Package Diagram")) try: prog = 0 progress.show() QApplication.processEvents() for module in modules: progress.setValue(prog) QApplication.processEvents() prog += 1 try: mod = Utilities.ModuleParser.readModule( module, extensions=extensions, caching=False) except ImportError: continue else: name = mod.name if name.startswith(self.package): name = name[len(self.package) + 1:] moduleDict[name] = mod finally: progress.setValue(tot) progress.deleteLater() return moduleDict def __buildSubpackagesDict(self): """ Private method to build a dictionary of sub-packages contained in this package. @return dictionary of sub-packages contained in this package """ import Utilities.ModuleParser supportedExt = \ ['*{0}'.format(ext) for ext in Preferences.getPython("PythonExtensions")] + \ ['*{0}'.format(ext) for ext in Preferences.getPython("Python3Extensions")] + \ ['*.rb'] extensions = Preferences.getPython("PythonExtensions") + \ Preferences.getPython("Python3Extensions") + ['.rb'] subpackagesDict = {} subpackagesList = [] for subpackage in os.listdir(self.package): subpackagePath = os.path.join(self.package, subpackage) if os.path.isdir(subpackagePath) and \ subpackage != "__pycache__" and \ len(glob.glob(os.path.join(subpackagePath, "__init__.*"))) != 0: subpackagesList.append(subpackagePath) tot = 0 for ext in supportedExt: for subpackage in subpackagesList: tot += len(glob.glob(Utilities.normjoinpath(subpackage, ext))) progress = E5ProgressDialog( self.tr("Parsing modules..."), None, 0, tot, self.tr("%v/%m Modules"), self.parent()) progress.setWindowTitle(self.tr("Package Diagram")) try: prog = 0 progress.show() QApplication.processEvents() for subpackage in subpackagesList: packageName = os.path.basename(subpackage) subpackagesDict[packageName] = [] modules = [] for ext in supportedExt: modules.extend(glob.glob( Utilities.normjoinpath(subpackage, ext))) for module in modules: progress.setValue(prog) QApplication.processEvents() prog += 1 try: mod = Utilities.ModuleParser.readModule( module, extensions=extensions, caching=False) except ImportError: continue else: name = mod.name if "." in name: name = name.rsplit(".", 1)[1] subpackagesDict[packageName].append(name) subpackagesDict[packageName].sort() # move __init__ to the front if "__init__" in subpackagesDict[packageName]: subpackagesDict[packageName].remove("__init__") subpackagesDict[packageName].insert(0, "__init__") finally: progress.setValue(tot) progress.deleteLater() return subpackagesDict def buildDiagram(self): """ Public method to build the class shapes of the package diagram. The algorithm is borrowed from Boa Constructor. """ self.allClasses = {} initlist = glob.glob(os.path.join(self.package, '__init__.*')) if len(initlist) == 0: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr("The directory '{0}' is not a package.") .format(self.package)) return modules = self.__buildModulesDict() if not modules: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr( "The package '{0}' does not contain any modules.") .format(self.package)) return # step 1: build all classes found in the modules classesFound = False for modName in list(modules.keys()): module = modules[modName] for cls in list(module.classes.keys()): classesFound = True self.__addLocalClass(cls, module.classes[cls], 0, 0) if not classesFound: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr( "The package '{0}' does not contain any classes.") .format(self.package)) return # step 2: build the class hierarchies routes = [] nodes = [] for modName in list(modules.keys()): module = modules[modName] todo = [module.createHierarchy()] while todo: hierarchy = todo[0] for className in list(hierarchy.keys()): cw = self.__getCurrentShape(className) if not cw and className.find('.') >= 0: cw = self.__getCurrentShape(className.split('.')[-1]) if cw: self.allClasses[className] = cw if cw and cw.noAttrs != self.noAttrs: cw = None if cw and not (cw.external and (className in module.classes or className in module.modules) ): if className not in nodes: nodes.append(className) else: if className in module.classes: # this is a local class (defined in this module) self.__addLocalClass( className, module.classes[className], 0, 0) elif className in module.modules: # this is a local module (defined in this module) self.__addLocalClass( className, module.modules[className], 0, 0, True) else: self.__addExternalClass(className, 0, 0) nodes.append(className) if hierarchy.get(className): todo.append(hierarchy.get(className)) children = list(hierarchy.get(className).keys()) for child in children: if (className, child) not in routes: routes.append((className, child)) del todo[0] # step 3: build the subpackages subpackages = self.__buildSubpackagesDict() for subpackage in sorted(subpackages.keys()): self.__addPackage(subpackage, subpackages[subpackage], 0, 0) nodes.append(subpackage) self.__arrangeClasses(nodes, routes[:]) self.__createAssociations(routes) self.umlView.autoAdjustSceneSize(limit=True) def __arrangeClasses(self, nodes, routes, whiteSpaceFactor=1.2): """ Private method to arrange the shapes on the canvas. The algorithm is borrowed from Boa Constructor. @param nodes list of nodes to arrange @param routes list of routes @param whiteSpaceFactor factor to increase whitespace between items (float) """ from . import GraphicsUtilities generations = GraphicsUtilities.sort(nodes, routes) # calculate width and height of all elements sizes = [] for generation in generations: sizes.append([]) for child in generation: sizes[-1].append( self.__getCurrentShape(child).sceneBoundingRect()) # calculate total width and total height width = 0 height = 0 widths = [] heights = [] for generation in sizes: currentWidth = 0 currentHeight = 0 for rect in generation: if rect.bottom() > currentHeight: currentHeight = rect.bottom() currentWidth = currentWidth + rect.right() # update totals if currentWidth > width: width = currentWidth height = height + currentHeight # store generation info widths.append(currentWidth) heights.append(currentHeight) # add in some whitespace width = width * whiteSpaceFactor ## rawHeight = height height = height * whiteSpaceFactor - 20 ## verticalWhiteSpace = max( ## (height - rawHeight) / (len(generations) - 1.0 or 2.0), ## 40.0 ## ) verticalWhiteSpace = 40.0 sceneRect = self.umlView.sceneRect() width += 50.0 height += 50.0 swidth = width < sceneRect.width() and sceneRect.width() or width sheight = height < sceneRect.height() and sceneRect.height() or height self.umlView.setSceneSize(swidth, sheight) # distribute each generation across the width and the # generations across height y = 10.0 for currentWidth, currentHeight, generation in \ zip_longest(widths, heights, generations): x = 10.0 # whiteSpace is the space between any two elements whiteSpace = (width - currentWidth - 20) / \ (len(generation) - 1.0 or 2.0) for className in generation: cw = self.__getCurrentShape(className) cw.setPos(x, y) rect = cw.sceneBoundingRect() x = x + rect.width() + whiteSpace y = y + currentHeight + verticalWhiteSpace def __addLocalClass(self, className, _class, x, y, isRbModule=False): """ Private method to add a class defined in the module. @param className name of the class to be as a dictionary key (string) @param _class class to be shown (ModuleParser.Class) @param x x-coordinate (float) @param y y-coordinate (float) @param isRbModule flag indicating a Ruby module (boolean) """ from .ClassItem import ClassItem, ClassModel meths = sorted(_class.methods.keys()) attrs = sorted(_class.attributes.keys()) name = _class.name if isRbModule: name = "{0} (Module)".format(name) cl = ClassModel(name, meths[:], attrs[:]) cw = ClassItem(cl, False, x, y, noAttrs=self.noAttrs, scene=self.scene) cw.setId(self.umlView.getItemId()) self.allClasses[className] = cw def __addExternalClass(self, _class, x, y): """ Private method to add a class defined outside the module. If the canvas is too small to take the shape, it is enlarged. @param _class class to be shown (string) @param x x-coordinate (float) @param y y-coordinate (float) """ from .ClassItem import ClassItem, ClassModel cl = ClassModel(_class) cw = ClassItem(cl, True, x, y, noAttrs=self.noAttrs, scene=self.scene) cw.setId(self.umlView.getItemId()) self.allClasses[_class] = cw def __addPackage(self, name, modules, x, y): """ Private method to add a package to the diagram. @param name package name to be shown (string) @param modules list of module names contained in the package (list of strings) @param x x-coordinate (float) @param y y-coordinate (float) """ from .PackageItem import PackageItem, PackageModel pm = PackageModel(name, modules) pw = PackageItem(pm, x, y, scene=self.scene) pw.setId(self.umlView.getItemId()) self.allClasses[name] = pw def __createAssociations(self, routes): """ Private method to generate the associations between the class shapes. @param routes list of relationsships """ from .AssociationItem import AssociationItem, Generalisation for route in routes: if len(route) > 1: assoc = AssociationItem( self.__getCurrentShape(route[1]), self.__getCurrentShape(route[0]), Generalisation, topToBottom=True) self.scene.addItem(assoc) def getPersistenceData(self): """ Public method to get a string for data to be persisted. @return persisted data string (string) """ return "package={0}, no_attributes={1}".format( self.package, self.noAttrs) def parsePersistenceData(self, version, data): """ Public method to parse persisted data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ parts = data.split(", ") if len(parts) != 2 or \ not parts[0].startswith("package=") or \ not parts[1].startswith("no_attributes="): return False self.package = parts[0].split("=", 1)[1].strip() self.noAttrs = Utilities.toBool(parts[1].split("=", 1)[1].strip()) self.initialize() return True eric-6.0.8/eric/Graphics/UMLSceneSizeDialog.ui0000644000175000017500000000522612060166052020135 0ustar piotrpiotr UMLSceneSizeDialog 0 0 314 103 Set Size true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Height (in pixels): Width (in pixels): Select the height of the diagram 100 100000 Select the width of the diagram 100 100000 qPixmapFromMimeSource buttonBox accepted() UMLSceneSizeDialog accept() 24 73 24 93 buttonBox rejected() UMLSceneSizeDialog reject() 79 75 79 94 eric-6.0.8/eric/Graphics/SvgDiagram.py0000644000175000017500000003136312451233373016614 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing a dialog showing a SVG graphic. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QSize, QEvent, qVersion from PyQt5.QtGui import QPalette, QPainter, QFont, QColor from PyQt5.QtWidgets import QSizePolicy, QScrollArea, QAction, QMenu, QToolBar from PyQt5.QtPrintSupport import QPrinter, QPrintDialog from PyQt5.QtSvg import QSvgWidget from E5Gui.E5MainWindow import E5MainWindow from E5Gui.E5ZoomWidget import E5ZoomWidget import UI.Config import Preferences class SvgDiagram(E5MainWindow): """ Class implementing a dialog showing a SVG graphic. """ ZoomLevels = [ 1, 3, 5, 7, 9, 10, 20, 30, 50, 67, 80, 90, 100, 110, 120, 133, 150, 170, 200, 240, 300, 400, 500, 600, 700, 800, 900, 1000, ] ZoomLevelDefault = 100 def __init__(self, svgFile, parent=None, name=None): """ Constructor @param svgFile filename of a SVG graphics file to show (string) @param parent parent widget of the view (QWidget) @param name name of the view widget (string) """ super(SvgDiagram, self).__init__(parent) if name: self.setObjectName(name) else: self.setObjectName("SvgDiagram") self.setWindowTitle(self.tr("SVG-Viewer")) self.svgWidget = QSvgWidget() self.svgWidget.setObjectName("svgWidget") self.svgWidget.setBackgroundRole(QPalette.Base) self.svgWidget.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.svgView = QScrollArea() self.svgView.setObjectName("svgView") self.svgView.setBackgroundRole(QPalette.Dark) self.svgView.setWidget(self.svgWidget) self.setCentralWidget(self.svgView) self.__zoomWidget = E5ZoomWidget( UI.PixmapCache.getPixmap("zoomOut.png"), UI.PixmapCache.getPixmap("zoomIn.png"), UI.PixmapCache.getPixmap("zoomReset.png"), self) self.statusBar().addPermanentWidget(self.__zoomWidget) self.__zoomWidget.setMapping( SvgDiagram.ZoomLevels, SvgDiagram.ZoomLevelDefault) self.__zoomWidget.valueChanged.connect(self.__doZoom) # polish up the dialog self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint())) self.zoom = 1.0 self.svgFile = svgFile self.svgWidget.load(self.svgFile) self.svgWidget.resize(self.svgWidget.renderer().defaultSize()) self.__initActions() self.__initContextMenu() self.__initToolBars() self.grabGesture(Qt.PinchGesture) def __initActions(self): """ Private method to initialize the view actions. """ self.closeAct = \ QAction(UI.PixmapCache.getIcon("close.png"), self.tr("Close"), self) self.closeAct.triggered.connect(self.close) self.printAct = \ QAction(UI.PixmapCache.getIcon("print.png"), self.tr("Print"), self) self.printAct.triggered.connect(self.__printDiagram) self.printPreviewAct = \ QAction(UI.PixmapCache.getIcon("printPreview.png"), self.tr("Print Preview"), self) self.printPreviewAct.triggered.connect(self.__printPreviewDiagram) def __initContextMenu(self): """ Private method to initialize the context menu. """ self.__menu = QMenu(self) self.__menu.addAction(self.closeAct) self.__menu.addSeparator() self.__menu.addAction(self.printPreviewAct) self.__menu.addAction(self.printAct) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) def __showContextMenu(self, coord): """ Private slot to show the context menu of the listview. @param coord the position of the mouse pointer (QPoint) """ self.__menu.popup(self.mapToGlobal(coord)) def __initToolBars(self): """ Private method to populate the toolbars with our actions. """ self.windowToolBar = QToolBar(self.tr("Window"), self) self.windowToolBar.setIconSize(UI.Config.ToolBarIconSize) self.windowToolBar.addAction(self.closeAct) self.graphicsToolBar = QToolBar(self.tr("Graphics"), self) self.graphicsToolBar.setIconSize(UI.Config.ToolBarIconSize) self.graphicsToolBar.addAction(self.printPreviewAct) self.graphicsToolBar.addAction(self.printAct) self.addToolBar(Qt.TopToolBarArea, self.windowToolBar) self.addToolBar(Qt.TopToolBarArea, self.graphicsToolBar) def getDiagramName(self): """ Public method to retrieve a name for the diagram. @return name for the diagram """ return self.svgFile def wheelEvent(self, evt): """ Protected method to handle wheel events. @param evt reference to the wheel event (QWheelEvent) """ if evt.modifiers() & Qt.ControlModifier: if qVersion() >= "5.0.0": delta = evt.angleDelta().y() else: delta = evt.delta() if delta < 0: self.__zoomOut() else: self.__zoomIn() evt.accept() return super(SvgDiagram, self).wheelEvent(evt) def event(self, evt): """ Public method handling events. @param evt reference to the event (QEvent) @return flag indicating, if the event was handled (boolean) """ if evt.type() == QEvent.Gesture: self.gestureEvent(evt) return True return super(SvgDiagram, self).event(evt) def gestureEvent(self, evt): """ Protected method handling gesture events. @param evt reference to the gesture event (QGestureEvent """ pinch = evt.gesture(Qt.PinchGesture) if pinch: if pinch.state() == Qt.GestureStarted: pinch.setScaleFactor(self.__zoom() / 100) else: self.__doZoom(int(pinch.scaleFactor() * 100)) evt.accept() ########################################################################### ## Private menu handling methods below. ########################################################################### def __adjustScrollBar(self, scrollBar, factor): """ Private method to adjust a scrollbar by a certain factor. @param scrollBar reference to the scrollbar object (QScrollBar) @param factor factor to adjust by (float) """ scrollBar.setValue( int(factor * scrollBar.value() + ((factor - 1) * scrollBar.pageStep() / 2))) def __levelForZoom(self, zoom): """ Private method determining the zoom level index given a zoom factor. @param zoom zoom factor (integer) @return index of zoom factor (integer) """ try: index = SvgDiagram.ZoomLevels.index(zoom) except ValueError: for index in range(len(SvgDiagram.ZoomLevels)): if zoom <= SvgDiagram.ZoomLevels[index]: break return index def __doZoom(self, value): """ Private method to set the zoom value in percent. @param value zoom value in percent (integer) """ oldValue = self.__zoom() if value != oldValue: self.svgWidget.resize(value / 100 * self.svgWidget.sizeHint()) factor = value / oldValue self.__adjustScrollBar(self.svgView.horizontalScrollBar(), factor) self.__adjustScrollBar(self.svgView.verticalScrollBar(), factor) self.__zoomWidget.setValue(value) def __zoomIn(self): """ Private method to zoom into the SVG. """ index = self.__levelForZoom(self.__zoom()) if index < len(SvgDiagram.ZoomLevels) - 1: self.__doZoom(SvgDiagram.ZoomLevels[index + 1]) def __zoomOut(self): """ Private method to zoom out of the SVG. """ index = self.__levelForZoom(self.__zoom()) if index > 0: self.__doZoom(SvgDiagram.ZoomLevels[index - 1]) def __zoomReset(self): """ Private method to reset the zoom value. """ self.__doZoom(SvgDiagram.ZoomLevels[SvgDiagram.ZoomLevelDefault]) def __zoom(self): """ Private method to get the current zoom factor in percent. @return current zoom factor in percent (integer) """ return int(self.svgWidget.width() / self.svgWidget.sizeHint().width() * 100.0) def __printDiagram(self): """ Private slot called to print the diagram. """ printer = QPrinter(mode=QPrinter.ScreenResolution) printer.setFullPage(True) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) printDialog = QPrintDialog(printer, self) if printDialog.exec_(): self.__print(printer) def __printPreviewDiagram(self): """ Private slot called to show a print preview of the diagram. """ from PyQt5.QtPrintSupport import QPrintPreviewDialog printer = QPrinter(mode=QPrinter.ScreenResolution) printer.setFullPage(True) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printer.setPageMargins( Preferences.getPrinter("LeftMargin") * 10, Preferences.getPrinter("TopMargin") * 10, Preferences.getPrinter("RightMargin") * 10, Preferences.getPrinter("BottomMargin") * 10, QPrinter.Millimeter ) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) preview = QPrintPreviewDialog(printer, self) preview.paintRequested[QPrinter].connect(self.__print) preview.exec_() def __print(self, printer): """ Private slot to the actual printing. @param printer reference to the printer object (QPrinter) """ painter = QPainter() painter.begin(printer) # calculate margin and width of printout font = QFont("times", 10) painter.setFont(font) fm = painter.fontMetrics() fontHeight = fm.lineSpacing() marginX = printer.pageRect().x() - printer.paperRect().x() marginX = Preferences.getPrinter("LeftMargin") * \ int(printer.resolution() / 2.54) - marginX marginY = printer.pageRect().y() - printer.paperRect().y() marginY = Preferences.getPrinter("TopMargin") * \ int(printer.resolution() / 2.54) - marginY width = printer.width() - marginX - \ Preferences.getPrinter("RightMargin") * \ int(printer.resolution() / 2.54) height = printer.height() - fontHeight - 4 - marginY - \ Preferences.getPrinter("BottomMargin") * \ int(printer.resolution() / 2.54) # write a foot note s = self.tr("Diagram: {0}").format(self.getDiagramName()) tc = QColor(50, 50, 50) painter.setPen(tc) painter.drawRect(marginX, marginY, width, height) painter.drawLine(marginX, marginY + height + 2, marginX + width, marginY + height + 2) painter.setFont(font) painter.drawText(marginX, marginY + height + 4, width, fontHeight, Qt.AlignRight, s) # render the diagram painter.setViewport(marginX, marginY, width, height) self.svgWidget.renderer().render(painter) painter.end() eric-6.0.8/eric/Graphics/UMLDiagramBuilder.py0000644000175000017500000000344512451233373020021 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing the UML diagram builder base class. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject class UMLDiagramBuilder(QObject): """ Class implementing the UML diagram builder base class. """ def __init__(self, dialog, view, project): """ Constructor @param dialog reference to the UML dialog (UMLDialog) @param view reference to the view object (UMLGraphicsView) @param project reference to the project object (Project) """ super(UMLDiagramBuilder, self).__init__(dialog) self.umlView = view self.scene = self.umlView.scene() self.project = project def initialize(self): """ Public method to initialize the object. """ return def buildDiagram(self): """ Public method to build the diagram. This class must be implemented in subclasses. @exception NotImplementedError raised to indicate that this class must be subclassed """ raise NotImplementedError( "Method 'buildDiagram' must be implemented in subclasses.") def getPersistenceData(self): """ Public method to get a string for data to be persisted. @return persisted data string (string) """ return "" def parsePersistenceData(self, version, data): """ Public method to parse persisted data. @param version version of the data (string) @param data persisted data to be parsed (string) @return flag indicating success (boolean) """ return True eric-6.0.8/eric/Graphics/PixmapDiagram.py0000644000175000017500000003370612451233373017316 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog showing a pixmap. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QSize, QEvent, qVersion from PyQt5.QtGui import QPalette, QImage, QPixmap, QPainter, QFont, QColor from PyQt5.QtWidgets import QLabel, QSizePolicy, QScrollArea, QAction, QMenu, \ QToolBar from PyQt5.QtPrintSupport import QPrinter, QPrintDialog from E5Gui import E5MessageBox from E5Gui.E5MainWindow import E5MainWindow from E5Gui.E5ZoomWidget import E5ZoomWidget import UI.Config import Preferences class PixmapDiagram(E5MainWindow): """ Class implementing a dialog showing a pixmap. """ ZoomLevels = [ 1, 3, 5, 7, 9, 10, 20, 30, 50, 67, 80, 90, 100, 110, 120, 133, 150, 170, 200, 240, 300, 400, 500, 600, 700, 800, 900, 1000, ] ZoomLevelDefault = 100 def __init__(self, pixmap, parent=None, name=None): """ Constructor @param pixmap filename of a graphics file to show (string) @param parent parent widget of the view (QWidget) @param name name of the view widget (string) """ super(PixmapDiagram, self).__init__(parent) if name: self.setObjectName(name) else: self.setObjectName("PixmapDiagram") self.setWindowTitle(self.tr("Pixmap-Viewer")) self.pixmapLabel = QLabel() self.pixmapLabel.setObjectName("pixmapLabel") self.pixmapLabel.setBackgroundRole(QPalette.Base) self.pixmapLabel.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Ignored) self.pixmapLabel.setScaledContents(True) self.pixmapView = QScrollArea() self.pixmapView.setObjectName("pixmapView") self.pixmapView.setBackgroundRole(QPalette.Dark) self.pixmapView.setWidget(self.pixmapLabel) self.setCentralWidget(self.pixmapView) self.__zoomWidget = E5ZoomWidget( UI.PixmapCache.getPixmap("zoomOut.png"), UI.PixmapCache.getPixmap("zoomIn.png"), UI.PixmapCache.getPixmap("zoomReset.png"), self) self.statusBar().addPermanentWidget(self.__zoomWidget) self.__zoomWidget.setMapping( PixmapDiagram.ZoomLevels, PixmapDiagram.ZoomLevelDefault) self.__zoomWidget.valueChanged.connect(self.__doZoom) # polish up the dialog self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint())) self.pixmapfile = pixmap self.status = self.__showPixmap(self.pixmapfile) self.__initActions() self.__initContextMenu() self.__initToolBars() self.grabGesture(Qt.PinchGesture) def __initActions(self): """ Private method to initialize the view actions. """ self.closeAct = \ QAction(UI.PixmapCache.getIcon("close.png"), self.tr("Close"), self) self.closeAct.triggered.connect(self.close) self.printAct = \ QAction(UI.PixmapCache.getIcon("print.png"), self.tr("Print"), self) self.printAct.triggered.connect(self.__printDiagram) self.printPreviewAct = \ QAction(UI.PixmapCache.getIcon("printPreview.png"), self.tr("Print Preview"), self) self.printPreviewAct.triggered.connect(self.__printPreviewDiagram) def __initContextMenu(self): """ Private method to initialize the context menu. """ self.__menu = QMenu(self) self.__menu.addAction(self.closeAct) self.__menu.addSeparator() self.__menu.addAction(self.printPreviewAct) self.__menu.addAction(self.printAct) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) def __showContextMenu(self, coord): """ Private slot to show the context menu of the listview. @param coord the position of the mouse pointer (QPoint) """ self.__menu.popup(self.mapToGlobal(coord)) def __initToolBars(self): """ Private method to populate the toolbars with our actions. """ self.windowToolBar = QToolBar(self.tr("Window"), self) self.windowToolBar.setIconSize(UI.Config.ToolBarIconSize) self.windowToolBar.addAction(self.closeAct) self.graphicsToolBar = QToolBar(self.tr("Graphics"), self) self.graphicsToolBar.setIconSize(UI.Config.ToolBarIconSize) self.graphicsToolBar.addAction(self.printPreviewAct) self.graphicsToolBar.addAction(self.printAct) self.addToolBar(Qt.TopToolBarArea, self.windowToolBar) self.addToolBar(Qt.TopToolBarArea, self.graphicsToolBar) def __showPixmap(self, filename): """ Private method to show a file. @param filename name of the file to be shown (string) @return flag indicating success (boolean) """ image = QImage(filename) if image.isNull(): E5MessageBox.warning( self, self.tr("Pixmap-Viewer"), self.tr( """

The file {0} cannot be displayed.""" """ The format is not supported.

""").format(filename)) return False self.pixmapLabel.setPixmap(QPixmap.fromImage(image)) self.pixmapLabel.adjustSize() return True def getDiagramName(self): """ Public method to retrieve a name for the diagram. @return name for the diagram """ return self.pixmapfile def getStatus(self): """ Public method to retrieve the status of the canvas. @return flag indicating a successful pixmap loading (boolean) """ return self.status def wheelEvent(self, evt): """ Protected method to handle wheel events. @param evt reference to the wheel event (QWheelEvent) """ if evt.modifiers() & Qt.ControlModifier: if qVersion() >= "5.0.0": delta = evt.angleDelta().y() else: delta = evt.delta() if delta < 0: self.__zoomOut() else: self.__zoomIn() evt.accept() return super(PixmapDiagram, self).wheelEvent(evt) def event(self, evt): """ Public method handling events. @param evt reference to the event (QEvent) @return flag indicating, if the event was handled (boolean) """ if evt.type() == QEvent.Gesture: self.gestureEvent(evt) return True return super(PixmapDiagram, self).event(evt) def gestureEvent(self, evt): """ Protected method handling gesture events. @param evt reference to the gesture event (QGestureEvent """ pinch = evt.gesture(Qt.PinchGesture) if pinch: if pinch.state() == Qt.GestureStarted: pinch.setScaleFactor(self.__zoom() / 100) else: self.__doZoom(int(pinch.scaleFactor() * 100)) evt.accept() ########################################################################### ## Private menu handling methods below. ########################################################################### def __adjustScrollBar(self, scrollBar, factor): """ Private method to adjust a scrollbar by a certain factor. @param scrollBar reference to the scrollbar object (QScrollBar) @param factor factor to adjust by (float) """ scrollBar.setValue(int(factor * scrollBar.value() + ((factor - 1) * scrollBar.pageStep() / 2))) def __levelForZoom(self, zoom): """ Private method determining the zoom level index given a zoom factor. @param zoom zoom factor (integer) @return index of zoom factor (integer) """ try: index = PixmapDiagram.ZoomLevels.index(zoom) except ValueError: for index in range(len(PixmapDiagram.ZoomLevels)): if zoom <= PixmapDiagram.ZoomLevels[index]: break return index def __doZoom(self, value): """ Private method to set the zoom value in percent. @param value zoom value in percent (integer) """ oldValue = self.__zoom() if value != oldValue: self.pixmapLabel.resize( value / 100 * self.pixmapLabel.pixmap().size()) factor = value / oldValue self.__adjustScrollBar( self.pixmapView.horizontalScrollBar(), factor) self.__adjustScrollBar( self.pixmapView.verticalScrollBar(), factor) self.__zoomWidget.setValue(value) def __zoomIn(self): """ Private method to zoom into the pixmap. """ index = self.__levelForZoom(self.__zoom()) if index < len(PixmapDiagram.ZoomLevels) - 1: self.__doZoom(PixmapDiagram.ZoomLevels[index + 1]) def __zoomOut(self): """ Private method to zoom out of the pixmap. """ index = self.__levelForZoom(self.__zoom()) if index > 0: self.__doZoom(PixmapDiagram.ZoomLevels[index - 1]) def __zoomReset(self): """ Private method to reset the zoom value. """ self.__doZoom(PixmapDiagram.ZoomLevels[PixmapDiagram.ZoomLevelDefault]) def __zoom(self): """ Private method to get the current zoom factor in percent. @return current zoom factor in percent (integer) """ return int(self.pixmapLabel.width() / self.pixmapLabel.pixmap().width() * 100.0) def __printDiagram(self): """ Private slot called to print the diagram. """ printer = QPrinter(mode=QPrinter.ScreenResolution) printer.setFullPage(True) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printer.setPrinterName(Preferences.getPrinter("PrinterName")) printDialog = QPrintDialog(printer, self) if printDialog.exec_(): self.__print(printer) def __printPreviewDiagram(self): """ Private slot called to show a print preview of the diagram. """ from PyQt5.QtPrintSupport import QPrintPreviewDialog printer = QPrinter(mode=QPrinter.ScreenResolution) printer.setFullPage(True) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printer.setPageMargins( Preferences.getPrinter("LeftMargin") * 10, Preferences.getPrinter("TopMargin") * 10, Preferences.getPrinter("RightMargin") * 10, Preferences.getPrinter("BottomMargin") * 10, QPrinter.Millimeter ) printer.setPrinterName(Preferences.getPrinter("PrinterName")) preview = QPrintPreviewDialog(printer, self) preview.paintRequested[QPrinter].connect(self.__print) preview.exec_() def __print(self, printer): """ Private slot to the actual printing. @param printer reference to the printer object (QPrinter) """ painter = QPainter() painter.begin(printer) # calculate margin and width of printout font = QFont("times", 10) painter.setFont(font) fm = painter.fontMetrics() fontHeight = fm.lineSpacing() marginX = printer.pageRect().x() - printer.paperRect().x() marginX = Preferences.getPrinter("LeftMargin") * \ int(printer.resolution() / 2.54) - marginX marginY = printer.pageRect().y() - printer.paperRect().y() marginY = Preferences.getPrinter("TopMargin") * \ int(printer.resolution() / 2.54) - marginY width = printer.width() - marginX - \ Preferences.getPrinter("RightMargin") * \ int(printer.resolution() / 2.54) height = printer.height() - fontHeight - 4 - marginY - \ Preferences.getPrinter("BottomMargin") * \ int(printer.resolution() / 2.54) # write a foot note s = self.tr("Diagram: {0}").format(self.getDiagramName()) tc = QColor(50, 50, 50) painter.setPen(tc) painter.drawRect(marginX, marginY, width, height) painter.drawLine(marginX, marginY + height + 2, marginX + width, marginY + height + 2) painter.setFont(font) painter.drawText(marginX, marginY + height + 4, width, fontHeight, Qt.AlignRight, s) # render the diagram size = self.pixmapLabel.pixmap().size() size.scale(QSize(width - 10, height - 10), # 5 px inner margin Qt.KeepAspectRatio) painter.setViewport(marginX + 5, marginY + 5, size.width(), size.height()) painter.setWindow(self.pixmapLabel.pixmap().rect()) painter.drawPixmap(0, 0, self.pixmapLabel.pixmap()) painter.end() eric-6.0.8/eric/eric6_webbrowser.py0000644000175000017500000000507712451233373016304 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Eric6 Web Browser. This is the main Python script that performs the necessary initialization of the web browser and starts the Qt event loop. This is a standalone version of the integrated helpviewer. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass try: import sip sip.setdestroyonexit(False) except AttributeError: pass import sys import os for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break # make ThirdParty package available as a packages repository sys.path.insert(2, os.path.join(os.path.dirname(__file__), "ThirdParty", "Pygments")) import Globals from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from Helpviewer.HelpWindow import HelpWindow searchWord = None for arg in reversed(argv): if arg.startswith("--search="): searchWord = argv[1].split("=", 1)[1] argv.remove(arg) elif arg.startswith("--"): argv.remove(arg) try: home = argv[1] except IndexError: home = "" help = HelpWindow(home, '.', None, 'help viewer', searchWord=searchWord) return help def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ("--search=word", "search for the given word") ] appinfo = AppInfo.makeAppInfo(sys.argv, "eric6 Web Browser", "file", "web browser", options) if not Globals.checkBlacklistedVersions(): sys.exit(100) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget, installErrorHandler=True) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/eric6_trpreviewer.py0000644000175000017500000000465212455012201016464 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Eric6 TR Previewer. This is the main Python script that performs the necessary initialization of the tr previewer and starts the Qt event loop. This is a standalone version of the integrated tr previewer. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break from E5Gui.E5Application import E5Application from Tools.TRSingleApplication import TRSingleApplicationClient from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from Tools.TRPreviewer import TRPreviewer if len(argv) > 1: files = argv[1:] else: files = [] previewer = TRPreviewer(files, None, 'TRPreviewer') return previewer def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ] appinfo = AppInfo.makeAppInfo(sys.argv, "Eric6 TR Previewer", "file", "TR file previewer", options) # set the library paths for plugins Startup.setLibraryPaths() app = E5Application(sys.argv) client = TRSingleApplicationClient() res = client.connect() if res > 0: if len(sys.argv) > 1: client.processArgs(sys.argv[1:]) sys.exit(0) elif res < 0: print("eric6_trpreviewer: {0}".format(client.errstr())) sys.exit(res) else: res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget, app=app) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/eric6_webbrowser.pyw0000644000175000017500000000030412451233400016446 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_webbrowser import main main() eric-6.0.8/eric/default.e4k0000644000175000017500000023603712371442127014514 0ustar piotrpiotr project_new project_open project_close project_save project_save_as project_add_file project_add_directory project_add_translation project_search_new_files project_properties project_user_properties project_filetype_associatios project_lexer_associatios project_debugger_properties project_debugger_properties_load project_debugger_properties_save project_debugger_properties_delete project_debugger_properties_resets project_load_session project_save_session project_delete_session project_code_metrics project_code_coverage project_profile_data project_application_diagram project_plugin_pkglist project_plugin_archive project_plugin_sarchive packagers_cxfreeze doc_eric6_api doc_eric6_doc project_check_pep8 project_check_syntax project_check_indentations quit Ctrl+Q new_window Ctrl+Shift+N edit_profile debug_profile project_viewer project_viewer_activate Alt+Shift+P multi_project_viewer multi_project_viewer_activate Alt+Shift+M debug_viewer debug_viewer_activate Alt+Shift+D interpreter_shell interprter_shell_activate Alt+Shift+S terminal terminal_activate Alt+Shift+R file_browser file_browser_activate Alt+Shift+F log_viewer log_viewer_activate Alt+Shift+G task_viewer task_viewer_activate Alt+Shift+T template_viewer template_viewer_activate Alt+Shift+A vertical_toolbox horizontal_toolbox left_sidebar bottom_sidebar cooperation_viewer cooperation_viewer_activate Alt+Shift+O symbols_viewer symbols_viewer_activate Alt+Shift+Y numbers_viewer numbers_viewer_activate Alt+Shift+B whatsThis Shift+F1 helpviewer F1 qt4_documentation pyqt4_documentation python3_documentation python2_documentation eric_documentation pyside_documentation show_versions check_updates show_downloadable_versions report_bug request_feature unittest unittest_restart unittest_rerun_failed unittest_script unittest_project qt_designer4 qt_linguist4 ui_previewer tr_previewer diff_files compare_files sql_browser mini_editor web_browser icon_editor preferences export_preferences import_preferences reload_apis show_external_tools view_profiles configure_toolbars keyboard_shortcuts export_keyboard_shortcuts import_keyboard_shortcuts viewmanager_activate Alt+Shift+E view_next_tab Ctrl+Alt+Tab view_previous_tab Ctrl+Alt+Shift+Tab switch_tabs Ctrl+1 plugin_infos plugin_install plugin_deinstall plugin_repository about_eric about_qt wizards_e5messagebox wizards_python_re wizards_qcolordialog wizards_qfiledialog wizards_qfontdialog wizards_qinputdialog wizards_qmessagebox wizards_qregexp dbg_run_script F2 dbg_run_project Shift+F2 dbg_coverage_script dbg_coverage_project dbg_profile_script dbg_profile_project dbg_debug_script F5 dbg_debug_project Shift+F5 dbg_restart_script F4 dbg_stop_script Shift+F10 dbg_continue F6 dbg_continue_to_cursor Shift+F6 dbg_single_step F7 dbg_step_over F8 dbg_step_out F9 dbg_stop F10 dbg_evaluate dbg_execute dbg_variables_filter dbg_exceptions_filter dbg_ignored_exceptions dbg_toggle_breakpoint Shift+F11 dbg_edit_breakpoint Shift+F12 dbg_next_breakpoint Ctrl+Shift+PgDown dbg_previous_breakpoint Ctrl+Shift+PgUp dbg_clear_breakpoint Ctrl+Shift+C vm_edit_undo Ctrl+Z Alt+Backspace vm_edit_redo Ctrl+Shift+Z vm_edit_revert Ctrl+Y vm_edit_cut Ctrl+X Shift+Del vm_edit_copy Ctrl+C Ctrl+Ins vm_edit_paste Ctrl+V Shift+Ins vm_edit_clear Alt+Shift+C vm_edit_join_lines Ctrl+J vm_edit_indent Ctrl+I vm_edit_unindent Ctrl+Shift+I vm_edit_smart_indent Ctrl+Alt+I vm_edit_comment Ctrl+M vm_edit_uncomment Ctrl+Alt+M vm_edit_toggle_comment Ctrl+Shift+M vm_edit_stream_comment vm_edit_box_comment vm_edit_select_to_brace Ctrl+E vm_edit_select_all Ctrl+A vm_edit_deselect_all Ctrl+Alt+A vm_edit_convert_eol vm_edit_shorten_empty_lines vm_edit_autocomplete Ctrl+Space vm_edit_autocomplete_from_document Ctrl+Shift+Space vm_edit_autocomplete_from_api Ctrl+Alt+Space vm_edit_autocomplete_from_all Alt+Shift+Space vm_edit_calltip Alt+Space vm_edit_move_left_char Left vm_edit_move_right_char Right vm_edit_move_up_line Up vm_edit_move_down_line Down vm_edit_move_left_word_part Alt+Left vm_edit_move_right_word_part Alt+Right vm_edit_move_left_word Ctrl+Left vm_edit_move_right_word Ctrl+Right vm_edit_move_first_visible_char Home vm_edit_move_start_line Alt+Home vm_edit_move_end_line End vm_edit_scroll_down_line Ctrl+Down vm_edit_scroll_up_line Ctrl+Up vm_edit_move_up_para Alt+Up vm_edit_move_down_para Alt+Down vm_edit_move_up_page PgUp vm_edit_move_down_page PgDown vm_edit_move_start_text Ctrl+Home vm_edit_move_end_text Ctrl+End vm_edit_indent_one_level Tab vm_edit_unindent_one_level Shift+Tab vm_edit_extend_selection_left_char Shift+Left vm_edit_extend_selection_right_char Shift+Right vm_edit_extend_selection_up_line Shift+Up vm_edit_extend_selection_down_line Shift+Down vm_edit_extend_selection_left_word_part Alt+Shift+Left vm_edit_extend_selection_right_word_part Alt+Shift+Right vm_edit_extend_selection_left_word Ctrl+Shift+Left vm_edit_extend_selection_right_word Ctrl+Shift+Right vm_edit_extend_selection_first_visible_char Shift+Home vm_edit_extend_selection_end_line Shift+End vm_edit_extend_selection_up_para Alt+Shift+Up vm_edit_extend_selection_down_para Alt+Shift+Down vm_edit_extend_selection_up_page Shift+PgUp vm_edit_extend_selection_down_page Shift+PgDown vm_edit_extend_selection_start_text Ctrl+Shift+Home vm_edit_extend_selection_end_text Ctrl+Shift+End vm_edit_delete_previous_char Backspace Shift+Backspace vm_edit_delet_previous_char_not_line_start vm_edit_delete_current_char Del vm_edit_delete_word_left Ctrl+Backspace vm_edit_delete_word_right Ctrl+Del vm_edit_delete_line_left Ctrl+Shift+Backspace vm_edit_delete_line_right Ctrl+Shift+Del vm_edit_insert_line Return Enter vm_edit_insert_line_below Shift+Return Shift+Enter vm_edit_delete_current_line Ctrl+Shift+L vm_edit_duplicate_current_line Ctrl+D vm_edit_swap_current_previous_line Ctrl+T vm_edit_cut_current_line Alt+Shift+L vm_edit_copy_current_line Ctrl+Shift+T vm_edit_toggle_insert_overtype Ins vm_edit_convert_selection_lower Alt+Shift+U vm_edit_convert_selection_upper Ctrl+Shift+U vm_edit_move_end_displayed_line Alt+End vm_edit_extend_selection_end_displayed_line vm_edit_formfeed vm_edit_escape Esc vm_edit_extend_rect_selection_down_line Ctrl+Alt+Down vm_edit_extend_rect_selection_up_line Ctrl+Alt+Up vm_edit_extend_rect_selection_left_char Ctrl+Alt+Left vm_edit_extend_rect_selection_right_char Ctrl+Alt+Right vm_edit_extend_rect_selection_first_visible_char Alt+Shift+Home vm_edit_extend_rect_selection_end_line Alt+Shift+End vm_edit_extend_rect_selection_up_page Alt+Shift+PgUp vm_edit_extend_rect_selection_down_page Alt+Shift+PgDown vm_edit_duplicate_current_selection Ctrl+Shift+D vm_edit_scroll_start_text vm_edit_scroll_end_text vm_edit_scroll_vertically_center vm_edit_move_end_next_word vm_edit_select_end_next_word vm_edit_move_end_previous_word vm_edit_select_end_previous_word vm_edit_move_start_document_line vm_edit_extend_selection_start_document_line vm_edit_select_rect_start_line vm_edit_extend_selection_start_display_line vm_edit_move_start_display_document_line vm_edit_extend_selection_start_display_document_line vm_edit_move_first_visible_char_document_line vm_edit_extend_selection_first_visible_char_document_line vm_edit_end_start_display_document_line vm_edit_extend_selection_end_display_document_line vm_edit_stuttered_move_up_page vm_edit_stuttered_extend_selection_up_page vm_edit_stuttered_move_down_page vm_edit_stuttered_extend_selection_down_page vm_edit_delete_right_end_next_word vm_edit_move_selection_up_one_line vm_edit_move_selection_down_one_line vm_file_new Ctrl+N vm_file_open Ctrl+O vm_file_close Ctrl+W vm_file_close_all vm_file_save Ctrl+S vm_file_save_as Ctrl+Shift+S vm_file_save_all vm_file_print Ctrl+P vm_file_print_preview vm_file_search_file Ctrl+Alt+F vm_search Ctrl+F vm_search_next F3 vm_search_previous Shift+F3 vm_clear_search_markers Ctrl+3 vm_search_replace Ctrl+R vm_quicksearch Ctrl+Shift+K vm_quicksearch_backwards Ctrl+Shift+J vm_quicksearch_extend Ctrl+Shift+H vm_search_goto_line Ctrl+G vm_search_goto_brace Ctrl+L vm_search_goto_last_edit_location Ctrl+Shift+G vm_search_goto_previous_method_or_class Ctrl+Shift+Up vm_search_goto_next_method_or_class Ctrl+Shift+Down vm_search_in_files Ctrl+Shift+F vm_replace_in_files Ctrl+Shift+R vm_view_zoom_in Ctrl++ Zoom In vm_view_zoom_out Ctrl+- Zoom Out vm_view_zoom_reset Ctrl+0 vm_view_zoom Ctrl+# vm_view_toggle_all_folds vm_view_toggle_all_folds_children vm_view_toggle_current_fold vm_view_unhighlight vm_view_split_view vm_view_arrange_horizontally vm_view_remove_split vm_next_split Ctrl+Alt+N vm_previous_split Ctrl+Alt+P vm_preview vm_macro_start_recording vm_macro_stop_recording vm_macro_run vm_macro_delete vm_macro_load vm_macro_save vm_bookmark_toggle Ctrl+Alt+T vm_bookmark_next Ctrl+PgDown Ctrl+Shift+, vm_bookmark_previous Ctrl+PgUp vm_bookmark_clear Ctrl+Alt+C vm_syntaxerror_goto vm_syntaxerror_clear vm_warning_next vm_warning_previous vm_warnings_clear vm_uncovered_next vm_uncovered_previous vm_task_next vm_task_previous vm_spelling_spellcheck Shift+F7 vm_spelling_autospellcheck subversion_new subversion_update Meta+Alt+U subversion_commit Meta+Alt+O subversion_add subversion_remove subversion_log subversion_log_browser Meta+Alt+G subversion_diff Meta+Alt+D subversion_extendeddiff subversion_urldiff subversion_status Meta+Alt+S subversion_tag subversion_export subversion_options subversion_revert subversion_merge Meta+Alt+M subversion_switch subversion_resolve subversion_cleanup subversion_command subversion_list_tags subversion_list_branches subversion_contents subversion_property_set subversion_property_list subversion_property_delete subversion_relocate subversion_repo_browser subversion_configure refactoring_rename refactoring_rename_local refactoring_rename_module refactoring_change_occurrences refactoring_extract_method refactoring_extract_variable refactoring_inline refactoring_move_method refactoring_move_module refactoring_use_function refactoring_introduce_factory_method refactoring_introduce_parameter_method refactoring_organize_imports refactoring_expand_star_imports refactoring_relative_to_absolute_imports refactoring_froms_to_imports refactoring_organize_imports refactoring_restructure refactoring_change_method_signature refactoring_inline_argument_default refactoring_transform_module_to_package refactoring_encapsulate_attribute refactoring_local_variable_to_attribute refactoring_method_to_methodobject refactoring_undo refactoring_redo refactoring_show_project_undo_history refactoring_show_project_redo_history refactoring_show_file_undo_history refactoring_show_file_redo_history refactoring_clear_history refactoring_find_occurrences refactoring_find_definition refactoring_find_implementations refactoring_edit_config refactoring_help refactoring_analyze_all refactoring_update_configuration subversion_new subversion_update Meta+Alt+U subversion_commit Meta+Alt+O subversion_add subversion_remove subversion_log subversion_log_browser Meta+Alt+G subversion_diff Meta+Alt+D subversion_extendeddiff subversion_urldiff subversion_status Meta+Alt+S subversion_repoinfo subversion_tag subversion_export subversion_options subversion_revert subversion_merge Meta+Alt+M subversion_switch subversion_resolve subversion_cleanup subversion_command subversion_list_tags subversion_list_branches subversion_contents subversion_property_set subversion_property_list subversion_property_delete subversion_relocate subversion_repo_browser subversion_configure mercurial_new mercurial_incoming Meta+Alt+I mercurial_pull Meta+Alt+P mercurial_update Meta+Alt+U mercurial_commit Meta+Alt+O mercurial_outgoing mercurial_push Meta+Alt+H mercurial_push_forced subversion_export mercurial_add mercurial_remove mercurial_log mercurial_log_browser Meta+Alt+G mercurial_diff Meta+Alt+D mercurial_extendeddiff mercurial_status Meta+Alt+S mercurial_heads mercurial_parents mercurial_tip mercurial_revert mercurial_merge Meta+Alt+M mercurial_resolve mercurial_tag mercurial_list_tags mercurial_list_branches mercurial_branch mercurial_push_branch mercurial_close_branch mercurial_show_branch mercurial_switch mercurial_cleanup mercurial_command mercurial_options mercurial_configure mercurial_user_configure mercurial_repo_configure mercurial_show_config mercurial_show_paths mercurial_verify mercurial_recover mercurial_identify mercurial_create ignore mercurial_bundle mercurial_preview_bundle mercurial_identify_bundle mercurial_unbundle mercurial_bisect_good mercurial_bisect_bad mercurial_bisect_skip mercurial_bisect_reset mercurial_backout mercurial_rollback mercurial_serve mercurial_import mercurial_import mercurial_rebase mercurial_rebase_continue mercurial_rebase_abort mercurial_gpg_list mercurial_gpg_verify mercurial_gpg_sign mercurial_purge mercurial_purge_all mercurial_purge_list mercurial_purge_all_list mercurial_queues_new mercurial_queues_refresh mercurial_queues_refresh_message mercurial_queues_show mercurial_queues_show_message mercurial_queues_list mercurial_queues_finish_applied mercurial_queues_rename mercurial_queues_delete mercurial_queues_fold mercurial_queues_push_next mercurial_queues_push_all mercurial_queues_push_until mercurial_queues_pop_current mercurial_queues_pop_all mercurial_queues_pop_until mercurial_queues_goto mercurial_queues_push_next_force mercurial_queues_push_all_force mercurial_queues_push_until_force mercurial_queues_pop_current_force mercurial_queues_pop_all_force mercurial_queues_pop_until_force mercurial_queues_goto_force mercurial_queues_guards_define mercurial_queues_guards_drop_all mercurial_queues_guards_list mercurial_queues_guards_list_all mercurial_queues_guards_set_active mercurial_queues_guards_deactivate mercurial_queues_guards_identify_active mercurial_queues_create_queue mercurial_queues_rename_queue mercurial_queues_delete_queue mercurial_queues_purge_queue mercurial_queues_activate_queue mercurial_queues_list_queues mercurial_list_bookmarks mercurial_define_bookmark mercurial_delete_bookmark mercurial_rename_bookmark mercurial_move_bookmark mercurial_incoming_bookmarks mercurial_pull_bookmark mercurial_outgoing_bookmarks mercurial_push_bookmark mercurial_fetch Meta+Alt+F mercurial_transplant Meta+Alt+T mercurial_transplant_continue help_file_new_tab Ctrl+T help_file_new_window Ctrl+N help_file_open Ctrl+O help_file_open_tab Ctrl+Shift+O help_file_save_as Ctrl+Shift+S help_file_import_bookmarks help_file_export_bookmarks help_file_print Ctrl+P help_file_print_pdf help_file_print_preview help_file_close Ctrl+W help_file_close_all help_file_private_browsing help_file_quit Ctrl+Q help_go_backward Alt+Left Backspace help_go_foreward Alt+Right Shift+Backspace help_go_home Ctrl+Home help_go_reload Ctrl+R F5 help_go_stop Ctrl+. Esc help_edit_copy Ctrl+C help_edit_find Ctrl+F help_edit_find_next F3 help_edit_find_previous Shift+F3 help_bookmarks_manage Ctrl+Shift+B help_bookmark_add Ctrl+D help_bookmark_show_all help_bookmark_all_tabs help_help_whats_this Shift+F1 help_help_about help_help_about_qt help_view_zoom_in Ctrl++ Zoom In help_view_zoom_out Ctrl+- Zoom Out help_view_zoom_reset Ctrl+0 help_view_zoom_text_only help_show_page_source Ctrl+U help_view_full_scree F11 help_view_next_tab Ctrl+Alt+Tab help_view_previous_tab Ctrl+Alt+Shift+Tab help_switch_tabs Ctrl+1 help_preferences help_accepted_languages help_cookies help_offline_storage help_sync_toc help_show_toc help_show_index help_show_search help_qthelp_documents help_qthelp_filters help_qthelp_reindex help_clear_private_data help_clear_icons_db help_search_engines help_manage_passwords help_adblock help_manage_certificates help_tools_network_monitor help_show_downloads help_rss_feeds Ctrl+Shift+F help_siteinfo Ctrl+Shift+I eric-6.0.8/eric/UI/0000755000175000017500000000000012557365404012775 5ustar piotrpiotreric-6.0.8/eric/UI/NotificationWidget.py0000644000175000017500000001022312451233373017127 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a Notification widget. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QTimer, QPoint from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import QWidget from .Ui_NotificationWidget import Ui_NotificationWidget import Globals class NotificationWidget(QWidget, Ui_NotificationWidget): """ Class implementing a Notification widget. """ def __init__(self, parent=None, setPosition=False): """ Constructor @param parent reference to the parent widget (QWidget) @param setPosition flag indicating to set the display position interactively (boolean) """ super(NotificationWidget, self).__init__(parent) self.setupUi(self) self.__timeout = 5000 self.__icon = QPixmap() self.__heading = "" self.__text = "" self.__dragPosition = QPoint() self.__settingPosition = setPosition flags = Qt.Tool | \ Qt.FramelessWindowHint | \ Qt.WindowStaysOnTopHint | \ Qt.X11BypassWindowManagerHint if Globals.isWindowsPlatform(): flags |= Qt.ToolTip self.setWindowFlags(flags) self.frame.layout().setAlignment( self.verticalLayout, Qt.AlignLeft | Qt.AlignVCenter) self.__timer = QTimer(self) self.__timer.setSingleShot(True) self.__timer.timeout.connect(self.close) if self.__settingPosition: self.setCursor(Qt.OpenHandCursor) def setPixmap(self, icon): """ Public method to set the icon for the notification. @param icon icon to be used (QPixmap) """ self.__icon = QPixmap(icon) def setHeading(self, heading): """ Public method to set the heading for the notification. @param heading heading to be used (string) """ self.__heading = heading def setText(self, text): """ Public method to set the text for the notification. @param text text to be used (string) """ self.__text = text def setTimeout(self, timeout): """ Public method to set the timeout for the notification. @param timeout timeout to be used in seconds (integer) """ self.__timeout = timeout * 1000 def show(self): """ Public method to show the notification. """ self.icon.setPixmap(self.__icon) self.heading.setText(self.__heading) self.text.setText(self.__text) if not self.__settingPosition: self.__timer.stop() self.__timer.setInterval(self.__timeout) self.__timer.start() super(NotificationWidget, self).show() sh = self.sizeHint() self.resize(max(self.width(), sh.width()), sh.height()) def mousePressEvent(self, evt): """ Protected method to handle presses of a mouse button. @param evt reference to the mouse event (QMouseEvent) """ if not self.__settingPosition: self.close() return if evt.button() == Qt.LeftButton: self.__dragPosition = \ evt.globalPos() - self.frameGeometry().topLeft() self.setCursor(Qt.ClosedHandCursor) evt.accept() def mouseReleaseEvent(self, evt): """ Protected method to handle releases of a mouse button. @param evt reference to the mouse event (QMouseEvent) """ if self.__settingPosition and evt.button() == Qt.LeftButton: self.setCursor(Qt.OpenHandCursor) def mouseMoveEvent(self, evt): """ Protected method to handle dragging the window. @param evt reference to the mouse event (QMouseEvent) """ if evt.buttons() & Qt.LeftButton: self.move(evt.globalPos() - self.__dragPosition) evt.accept() eric-6.0.8/eric/UI/FindFileDialog.ui0000644000175000017500000003412412354034200016116 0ustar piotrpiotr FindFileDialog 0 0 600 750 Find in Files Find &text: findtextCombo 0 0 Enter the search text or regular expression true QComboBox::InsertAtTop false Replace te&xt: findtextCombo 0 0 Enter the replacement text or regular expression true QComboBox::InsertAtTop false Select to match case sensitive &Match upper/lower case Select to match whole words only Whole &word Select if the searchtext is a regular expression Regular &Expression Select to open the first occurence automatically Feeling Like File type Search in source files &Sources true Search in resources &Resources Search in forms &Forms Search in interfaces &Interfaces Qt::Horizontal Select to filter the files by a given filename pattern Fi&lter false 0 0 Enter the filename wildcards separated by ';' 0 0 Find in Search in files of the current project &Project true Search in files of a directory tree to be entered below &Directory tree false 0 0 Enter the directory to search in true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLength false Select the directory via a directory selection dialog Search in open files only &Open files only 0 0 Shows the progress of the search action 0 Qt::Horizontal %v/%m Files 0 3 true true 2 File/Line Text Press to apply the selected replacements Replace Qt::Horizontal QDialogButtonBox::Close E5SqueezeLabelPath QLabel
E5Gui/E5SqueezeLabels.h
findtextCombo replacetextCombo caseCheckBox wordCheckBox regexpCheckBox feelLikeCheckBox sourcesCheckBox formsCheckBox resourcesCheckBox interfacesCheckBox filterCheckBox filterEdit projectButton dirButton dirCombo dirSelectButton openFilesButton findList replaceButton buttonBox buttonBox rejected() FindFileDialog close() 49 740 34 660 filterCheckBox toggled(bool) filterEdit setEnabled(bool) 53 195 191 196 dirButton toggled(bool) dirCombo setEnabled(bool) 577 151 545 183 dirButton toggled(bool) dirSelectButton setEnabled(bool) 515 146 563 175
eric-6.0.8/eric/UI/AuthenticationDialog.py0000644000175000017500000000442012451233373017436 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the authentication dialog for the help browser. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog, QStyle from .Ui_AuthenticationDialog import Ui_AuthenticationDialog class AuthenticationDialog(QDialog, Ui_AuthenticationDialog): """ Class implementing the authentication dialog for the help browser. """ def __init__(self, info, username, showSave=False, saveIt=False, parent=None): """ Constructor @param info information to be shown (string) @param username username as supplied by subversion (string) @param showSave flag to indicate to show the save checkbox (boolean) @param saveIt flag indicating the value for the save checkbox (boolean) @param parent reference to the parent widget (QWidget) """ super(AuthenticationDialog, self).__init__(parent) self.setupUi(self) self.infoLabel.setText(info) self.usernameEdit.setText(username) self.saveCheckBox.setVisible(showSave) self.saveCheckBox.setChecked(saveIt) self.iconLabel.setText("") self.iconLabel.setPixmap( self.style().standardIcon(QStyle.SP_MessageBoxQuestion).pixmap( 32, 32)) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def setData(self, username, password): """ Public method to set the login data. @param username username (string) @param password password (string) """ self.usernameEdit.setText(username) self.passwordEdit.setText(password) def getData(self): """ Public method to retrieve the login data. @return tuple of two string values (username, password) """ return (self.usernameEdit.text(), self.passwordEdit.text()) def shallSave(self): """ Public method to check, if the login data shall be saved. @return flag indicating that the login data shall be saved (boolean) """ return self.saveCheckBox.isChecked() eric-6.0.8/eric/UI/EmailDialog.py0000644000175000017500000003400712537064320015511 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Module implementing a dialog to send bug reports. """ from __future__ import unicode_literals import os import mimetypes import smtplib import socket from PyQt5.QtCore import Qt, pyqtSlot, qVersion from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QHeaderView, QLineEdit, QDialog, QInputDialog, \ QApplication, QDialogButtonBox, QTreeWidgetItem from E5Gui import E5MessageBox, E5FileDialog from .Ui_EmailDialog import Ui_EmailDialog from .Info import BugAddress, FeatureAddress import Preferences import Utilities from base64 import b64encode as _bencode from email import encoders from email.mime.text import MIMEText from email.mime.image import MIMEImage from email.mime.audio import MIMEAudio from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from email.header import Header ############################################################ ## This code is to work around a bug in the Python email ## ## package for Image and Audio mime messages. ## ############################################################ def _encode_base64(msg): """ Function to encode the message's payload in Base64. Note: It adds an appropriate Content-Transfer-Encoding header. @param msg reference to the message object (email.Message) """ orig = msg.get_payload() encdata = str(_bencode(orig), "ASCII") msg.set_payload(encdata) msg['Content-Transfer-Encoding'] = 'base64' encoders.encode_base64 = _encode_base64 # WORK AROUND: implement our corrected encoder class EmailDialog(QDialog, Ui_EmailDialog): """ Class implementing a dialog to send bug reports. """ def __init__(self, mode="bug", parent=None): """ Constructor @param mode mode of this dialog (string, "bug" or "feature") @param parent parent widget of this dialog (QWidget) """ super(EmailDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.__mode = mode if self.__mode == "feature": self.setWindowTitle(self.tr("Send feature request")) self.msgLabel.setText(self.tr( "Enter your &feature request below." " Version information is added automatically.")) self.__toAddress = FeatureAddress else: # default is bug self.msgLabel.setText(self.tr( "Enter your &bug description below." " Version information is added automatically.")) self.__toAddress = BugAddress self.sendButton = self.buttonBox.addButton( self.tr("Send"), QDialogButtonBox.ActionRole) self.sendButton.setEnabled(False) self.sendButton.setDefault(True) height = self.height() self.mainSplitter.setSizes([int(0.7 * height), int(0.3 * height)]) self.attachments.headerItem().setText( self.attachments.columnCount(), "") if qVersion() >= "5.0.0": self.attachments.header().setSectionResizeMode( QHeaderView.Interactive) else: self.attachments.header().setResizeMode(QHeaderView.Interactive) sig = Preferences.getUser("Signature") if sig: self.message.setPlainText(sig) cursor = self.message.textCursor() cursor.setPosition(0) self.message.setTextCursor(cursor) self.message.ensureCursorVisible() self.__deleteFiles = [] def keyPressEvent(self, ev): """ Protected method to handle the user pressing the escape key. @param ev key event (QKeyEvent) """ if ev.key() == Qt.Key_Escape: res = E5MessageBox.yesNo( self, self.tr("Close dialog"), self.tr("""Do you really want to close the dialog?""")) if res: self.reject() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.sendButton: self.on_sendButton_clicked() def on_buttonBox_rejected(self): """ Private slot to handle the rejected signal of the button box. """ res = E5MessageBox.yesNo( self, self.tr("Close dialog"), self.tr("""Do you really want to close the dialog?""")) if res: self.reject() @pyqtSlot() def on_sendButton_clicked(self): """ Private slot to send the email message. """ if self.attachments.topLevelItemCount(): msg = self.__createMultipartMail() else: msg = self.__createSimpleMail() ok = self.__sendmail(msg) if ok: for f in self.__deleteFiles: try: os.remove(f) except OSError: pass self.accept() def __encodedText(self, txt): """ Private method to create a MIMEText message with correct encoding. @param txt text to be put into the MIMEText object (string) @return MIMEText object """ try: txt.encode("us-ascii") return MIMEText(txt) except UnicodeEncodeError: coding = Preferences.getSystem("StringEncoding") return MIMEText(txt.encode(coding), _charset=coding) def __encodedHeader(self, txt): """ Private method to create a correctly encoded mail header. @param txt header text to encode (string) @return encoded header (email.header.Header) """ try: txt.encode("us-ascii") return Header(txt) except UnicodeEncodeError: coding = Preferences.getSystem("StringEncoding") return Header(txt, coding) def __createSimpleMail(self): """ Private method to create a simple mail message. @return string containing the mail message """ msgtext = "{0}\r\n----\r\n{1}----\r\n{2}----\r\n{3}".format( self.message.toPlainText(), Utilities.generateVersionInfo("\r\n"), Utilities.generatePluginsVersionInfo("\r\n"), Utilities.generateDistroInfo("\r\n")) msg = self.__encodedText(msgtext) msg['From'] = Preferences.getUser("Email") msg['To'] = self.__toAddress subject = '[eric6] {0}'.format(self.subject.text()) msg['Subject'] = self.__encodedHeader(subject) return msg.as_string() def __createMultipartMail(self): """ Private method to create a multipart mail message. @return string containing the mail message """ mpPreamble = ("This is a MIME-encoded message with attachments. " "If you see this message, your mail client is not " "capable of displaying the attachments.") msgtext = "{0}\r\n----\r\n{1}----\r\n{2}----\r\n{3}".format( self.message.toPlainText(), Utilities.generateVersionInfo("\r\n"), Utilities.generatePluginsVersionInfo("\r\n"), Utilities.generateDistroInfo("\r\n")) # first part of multipart mail explains format msg = MIMEMultipart() msg['From'] = Preferences.getUser("Email") msg['To'] = self.__toAddress subject = '[eric6] {0}'.format(self.subject.text()) msg['Subject'] = self.__encodedHeader(subject) msg.preamble = mpPreamble msg.epilogue = '' # second part is intended to be read att = self.__encodedText(msgtext) msg.attach(att) # next parts contain the attachments for index in range(self.attachments.topLevelItemCount()): itm = self.attachments.topLevelItem(index) maintype, subtype = itm.text(1).split('/', 1) fname = itm.text(0) name = os.path.basename(fname) if maintype == 'text': txt = open(fname, 'r', encoding="utf-8").read() try: txt.encode("us-ascii") att = MIMEText(txt, _subtype=subtype) except UnicodeEncodeError: att = MIMEText( txt.encode("utf-8"), _subtype=subtype, _charset="utf-8") elif maintype == 'image': att = MIMEImage(open(fname, 'rb').read(), _subtype=subtype) elif maintype == 'audio': att = MIMEAudio(open(fname, 'rb').read(), _subtype=subtype) else: att = MIMEApplication(open(fname, 'rb').read()) att.add_header('Content-Disposition', 'attachment', filename=name) msg.attach(att) return msg.as_string() def __sendmail(self, msg): """ Private method to actually send the message. @param msg the message to be sent (string) @return flag indicating success (boolean) """ try: server = smtplib.SMTP(Preferences.getUser("MailServer"), Preferences.getUser("MailServerPort")) if Preferences.getUser("MailServerUseTLS"): server.starttls() if Preferences.getUser("MailServerAuthentication"): # mail server needs authentication password = Preferences.getUser("MailServerPassword") if not password: password, ok = QInputDialog.getText( self, self.tr("Mail Server Password"), self.tr("Enter your mail server password"), QLineEdit.Password) if not ok: # abort return False try: server.login(Preferences.getUser("MailServerUser"), password) except (smtplib.SMTPException, socket.error) as e: if isinstance(e, smtplib.SMTPResponseException): errorStr = e.smtp_error.decode() elif isinstance(e, socket.error): errorStr = e[1] else: errorStr = str(e) res = E5MessageBox.retryAbort( self, self.tr("Send bug report"), self.tr( """

Authentication failed.
Reason: {0}

""") .format(errorStr), E5MessageBox.Critical) if res: return self.__sendmail(msg) else: return False QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() server.sendmail(Preferences.getUser("Email"), self.__toAddress, msg) server.quit() QApplication.restoreOverrideCursor() except (smtplib.SMTPException, socket.error) as e: QApplication.restoreOverrideCursor() if isinstance(e, smtplib.SMTPResponseException): errorStr = e.smtp_error.decode() elif isinstance(e, socket.error): errorStr = e[1] else: errorStr = str(e) res = E5MessageBox.retryAbort( self, self.tr("Send bug report"), self.tr( """

Message could not be sent.
Reason: {0}

""") .format(errorStr), E5MessageBox.Critical) if res: return self.__sendmail(msg) else: return False return True @pyqtSlot() def on_addButton_clicked(self): """ Private slot to handle the Add... button. """ fname = E5FileDialog.getOpenFileName( self, self.tr("Attach file")) if fname: self.attachFile(fname, False) def attachFile(self, fname, deleteFile): """ Public method to add an attachment. @param fname name of the file to be attached (string) @param deleteFile flag indicating to delete the file after it has been sent (boolean) """ type = mimetypes.guess_type(fname)[0] if not type: type = "application/octet-stream" QTreeWidgetItem(self.attachments, [fname, type]) self.attachments.header().resizeSections(QHeaderView.ResizeToContents) self.attachments.header().setStretchLastSection(True) if deleteFile: self.__deleteFiles.append(fname) @pyqtSlot() def on_deleteButton_clicked(self): """ Private slot to handle the Delete button. """ itm = self.attachments.currentItem() if itm is not None: itm = self.attachments.takeTopLevelItem( self.attachments.indexOfTopLevelItem(itm)) del itm def on_subject_textChanged(self, txt): """ Private slot to handle the textChanged signal of the subject edit. @param txt changed text (string) """ self.sendButton.setEnabled( self.subject.text() != "" and self.message.toPlainText() != "") def on_message_textChanged(self): """ Private slot to handle the textChanged signal of the message edit. """ self.sendButton.setEnabled( self.subject.text() != "" and self.message.toPlainText() != "") eric-6.0.8/eric/UI/SearchWidget.py0000644000175000017500000001371012451233373015712 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing the search box for the shell, terminal and log viewer. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt from PyQt5.QtWidgets import QWidget, QSpacerItem, QSizePolicy from .Ui_SearchWidget import Ui_SearchWidget import UI.PixmapCache class SearchWidget(QWidget, Ui_SearchWidget): """ Class implementing the search box for the shell, terminal and log viewer. @signal searchNext(text, caseSensitive, wholeWord) emitted when the user pressed the next button (string, boolean, boolean) @signal searchPrevious(text, caseSensitive, wholeWord) emitted when the user pressed the previous button (string, boolean, boolean) """ searchNext = pyqtSignal(str, bool, bool) searchPrevious = pyqtSignal(str, bool, bool) def __init__(self, mainWindow, parent=None, spacer=True): """ Constructor @param mainWindow reference to the main window (QWidget) @param parent reference to the parent widget (QWidget) @param spacer flag indicating to add a vertical spacer to the main layout (boolean) """ super(SearchWidget, self).__init__(parent) self.setupUi(self) if spacer: spacerItem = QSpacerItem( 20, 1, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) else: # change the size policy of the search combo if the spacer is not # wanted, i.e. it is below the to be searched widget sizePolicy = self.findtextCombo.sizePolicy() sizePolicy.setHorizontalPolicy(QSizePolicy.Expanding) self.findtextCombo.setSizePolicy(sizePolicy) self.__mainWindow = mainWindow self.__findBackwards = True self.closeButton.setIcon(UI.PixmapCache.getIcon("close.png")) self.findPrevButton.setIcon(UI.PixmapCache.getIcon("1leftarrow.png")) self.findNextButton.setIcon(UI.PixmapCache.getIcon("1rightarrow.png")) self.findHistory = [] self.findtextCombo.setCompleter(None) self.findtextCombo.lineEdit().returnPressed.connect( self.__findByReturnPressed) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_closeButton_clicked(self): """ Private slot to close the widget. """ self.close() def keyPressEvent(self, event): """ Protected slot to handle key press events. @param event reference to the key press event (QKeyEvent) """ if event.key() == Qt.Key_Escape: self.__mainWindow.setFocus(Qt.ActiveWindowFocusReason) event.accept() self.close() @pyqtSlot() def on_findNextButton_clicked(self): """ Private slot to find the next occurrence. """ txt = self.findtextCombo.currentText() self.__findBackwards = False # This moves any previous occurrence of this statement to the head # of the list and updates the combobox if txt in self.findHistory: self.findHistory.remove(txt) self.findHistory.insert(0, txt) self.findtextCombo.clear() self.findtextCombo.addItems(self.findHistory) self.searchNext.emit( txt, self.caseCheckBox.isChecked(), self.wordCheckBox.isChecked()) @pyqtSlot() def on_findPrevButton_clicked(self): """ Private slot to find the previous occurrence. """ txt = self.findtextCombo.currentText() self.__findBackwards = True # This moves any previous occurrence of this statement to the head # of the list and updates the combobox if txt in self.findHistory: self.findHistory.remove(txt) self.findHistory.insert(0, txt) self.findtextCombo.clear() self.findtextCombo.addItems(self.findHistory) self.searchPrevious.emit( txt, self.caseCheckBox.isChecked(), self.wordCheckBox.isChecked()) @pyqtSlot(str) def on_findtextCombo_editTextChanged(self, txt): """ Private slot to enable/disable the find buttons. @param txt text of the combobox (string) """ self.__setSearchButtons(txt != "") def __setSearchButtons(self, enabled): """ Private slot to set the state of the search buttons. @param enabled flag indicating the state (boolean) """ self.findPrevButton.setEnabled(enabled) self.findNextButton.setEnabled(enabled) def __findByReturnPressed(self): """ Private slot to handle the returnPressed signal of the findtext combobox. """ if self.__findBackwards: self.on_findPrevButton_clicked() else: self.on_findNextButton_clicked() def showFind(self, txt=""): """ Public method to display this widget. @param txt text to be shown in the combo (string) """ self.findtextCombo.clear() self.findtextCombo.addItems(self.findHistory) self.findtextCombo.setEditText(txt) self.findtextCombo.setFocus() self.__setSearchButtons(txt != "") self.show() def searchStringFound(self, found): """ Public slot to indicate that the search string was found. @param found flag indicating success (boolean) """ if found: self.statusLabel.clear() else: txt = self.findtextCombo.currentText() self.statusLabel.setText( self.tr("'{0}' was not found.").format(txt)) eric-6.0.8/eric/UI/ErrorLogDialog.py0000644000175000017500000000430212537064320016210 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to display an error log. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtWidgets import QDialog, QStyle from .Ui_ErrorLogDialog import Ui_ErrorLogDialog class ErrorLogDialog(QDialog, Ui_ErrorLogDialog): """ Class implementing a dialog to display an error log. """ def __init__(self, logFile, showMode, parent=None): """ Constructor @param logFile name of the log file containing the error info (string) @param showMode flag indicating to just show the error log message (boolean) @param parent reference to the parent widget (QWidget) """ super(ErrorLogDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) pixmap = self.style().standardIcon(QStyle.SP_MessageBoxQuestion)\ .pixmap(32, 32) self.icon.setPixmap(pixmap) if showMode: self.icon.hide() self.label.hide() self.deleteButton.setText(self.tr("Delete")) self.keepButton.setText(self.tr("Close")) self.setWindowTitle(self.tr("Error Log")) self.__ui = parent self.__logFile = logFile try: f = open(logFile, "r", encoding="utf-8") txt = f.read() f.close() self.logEdit.setPlainText(txt) except IOError: pass @pyqtSlot() def on_emailButton_clicked(self): """ Private slot to send an email. """ self.accept() self.__ui.showEmailDialog( "bug", attachFile=self.__logFile, deleteAttachFile=True) @pyqtSlot() def on_deleteButton_clicked(self): """ Private slot to delete the log file. """ if os.path.exists(self.__logFile): os.remove(self.__logFile) self.accept() @pyqtSlot() def on_keepButton_clicked(self): """ Private slot to just do nothing. """ self.accept() eric-6.0.8/eric/UI/DiffDialog.py0000644000175000017500000004710112451233373015332 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog to compare two files. """ from __future__ import unicode_literals import os import time from PyQt5.QtCore import QFileInfo, QEvent, pyqtSlot from PyQt5.QtGui import QColor, QBrush, QTextCursor from PyQt5.QtWidgets import QWidget, QApplication, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5MainWindow import E5MainWindow from .Ui_DiffDialog import Ui_DiffDialog import Utilities import Preferences import UI.PixmapCache from difflib import SequenceMatcher # This function is copied from python 2.3 and slightly modified. # The header lines contain a tab after the filename. def unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n'): """ Compare two sequences of lines; generate the delta as a unified diff. Unified diffs are a compact way of showing line changes and a few lines of context. The number of context lines is set by 'n' which defaults to three. By default, the diff control lines (those with ---, +++, or @@) are created with a trailing newline. This is helpful so that inputs created from file.readlines() result in diffs that are suitable for file.writelines() since both the inputs and outputs have trailing newlines. For inputs that do not have trailing newlines, set the lineterm argument to "" so that the output will be uniformly newline free. The unidiff format normally has a header for filenames and modification times. Any or all of these may be specified using strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. The modification times are normally expressed in the format returned by time.ctime(). Example:
    >>> for line in unified_diff('one two three four'.split(),
    ...             'zero one tree four'.split(), 'Original', 'Current',
    ...             'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:20:52 2003',
    ...             lineterm=''):
    ...     print line
    --- Original Sat Jan 26 23:30:50 1991
    +++ Current Fri Jun 06 10:20:52 2003
    @@ -1,4 +1,4 @@
    +zero
     one
    -two
    -three
    +tree
     four
    
@param a first sequence of lines (list of strings) @param b second sequence of lines (list of strings) @param fromfile filename of the first file (string) @param tofile filename of the second file (string) @param fromfiledate modification time of the first file (string) @param tofiledate modification time of the second file (string) @param n number of lines of context (integer) @param lineterm line termination string (string) @return a generator yielding lines of differences """ started = False for group in SequenceMatcher(None, a, b).get_grouped_opcodes(n): if not started: yield '--- {0}\t{1}{2}'.format(fromfile, fromfiledate, lineterm) yield '+++ {0}\t{1}{2}'.format(tofile, tofiledate, lineterm) started = True i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4] yield "@@ -{0:d},{1:d} +{2:d},{3:d} @@{4}".format( i1 + 1, i2 - i1, j1 + 1, j2 - j1, lineterm) for tag, i1, i2, j1, j2 in group: if tag == 'equal': for line in a[i1:i2]: yield ' ' + line continue if tag == 'replace' or tag == 'delete': for line in a[i1:i2]: yield '-' + line if tag == 'replace' or tag == 'insert': for line in b[j1:j2]: yield '+' + line # This function is copied from python 2.3 and slightly modified. # The header lines contain a tab after the filename. def context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n'): r""" Compare two sequences of lines; generate the delta as a context diff. Context diffs are a compact way of showing line changes and a few lines of context. The number of context lines is set by 'n' which defaults to three. By default, the diff control lines (those with *** or ---) are created with a trailing newline. This is helpful so that inputs created from file.readlines() result in diffs that are suitable for file.writelines() since both the inputs and outputs have trailing newlines. For inputs that do not have trailing newlines, set the lineterm argument to "" so that the output will be uniformly newline free. The context diff format normally has a header for filenames and modification times. Any or all of these may be specified using strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. The modification times are normally expressed in the format returned by time.ctime(). If not specified, the strings default to blanks. Example:
    >>> print ''.join(
    ...       context_diff('one\ntwo\nthree\nfour\n'.splitlines(1),
    ...       'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current',
    ...       'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:22:46 2003')),
    *** Original Sat Jan 26 23:30:50 1991
    --- Current Fri Jun 06 10:22:46 2003
    ***************
    *** 1,4 ****
      one
    ! two
    ! three
      four
    --- 1,4 ----
    + zero
      one
    ! tree
      four
    
@param a first sequence of lines (list of strings) @param b second sequence of lines (list of strings) @param fromfile filename of the first file (string) @param tofile filename of the second file (string) @param fromfiledate modification time of the first file (string) @param tofiledate modification time of the second file (string) @param n number of lines of context (integer) @param lineterm line termination string (string) @return a generator yielding lines of differences """ started = False prefixmap = {'insert': '+ ', 'delete': '- ', 'replace': '! ', 'equal': ' '} for group in SequenceMatcher(None, a, b).get_grouped_opcodes(n): if not started: yield '*** {0}\t{1}{2}'.format(fromfile, fromfiledate, lineterm) yield '--- {0}\t{1}{2}'.format(tofile, tofiledate, lineterm) started = True yield '***************{0}'.format(lineterm) if group[-1][2] - group[0][1] >= 2: yield '*** {0:d},{1:d} ****{2}'.format( group[0][1] + 1, group[-1][2], lineterm) else: yield '*** {0:d} ****{1}'.format(group[-1][2], lineterm) visiblechanges = [e for e in group if e[0] in ('replace', 'delete')] if visiblechanges: for tag, i1, i2, _, _ in group: if tag != 'insert': for line in a[i1:i2]: yield prefixmap[tag] + line if group[-1][4] - group[0][3] >= 2: yield '--- {0:d},{1:d} ----{2}'.format( group[0][3] + 1, group[-1][4], lineterm) else: yield '--- {0:d} ----{1}'.format(group[-1][4], lineterm) visiblechanges = [e for e in group if e[0] in ('replace', 'insert')] if visiblechanges: for tag, _, _, j1, j2 in group: if tag != 'delete': for line in b[j1:j2]: yield prefixmap[tag] + line class DiffDialog(QWidget, Ui_DiffDialog): """ Class implementing a dialog to compare two files. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(DiffDialog, self).__init__(parent) self.setupUi(self) self.file1Button.setIcon(UI.PixmapCache.getIcon("open.png")) self.file2Button.setIcon(UI.PixmapCache.getIcon("open.png")) self.file1Completer = E5FileCompleter(self.file1Edit) self.file2Completer = E5FileCompleter(self.file2Edit) self.diffButton = self.buttonBox.addButton( self.tr("Compare"), QDialogButtonBox.ActionRole) self.diffButton.setToolTip( self.tr("Press to perform the comparison of the two files")) self.saveButton = self.buttonBox.addButton( self.tr("Save"), QDialogButtonBox.ActionRole) self.saveButton.setToolTip( self.tr("Save the output to a patch file")) self.diffButton.setEnabled(False) self.saveButton.setEnabled(False) self.diffButton.setDefault(True) self.filename1 = '' self.filename2 = '' self.updateInterval = 20 # update every 20 lines font = Preferences.getEditorOtherFonts("MonospacedFont") self.contents.setFontFamily(font.family()) self.contents.setFontPointSize(font.pointSize()) self.cNormalFormat = self.contents.currentCharFormat() self.cAddedFormat = self.contents.currentCharFormat() self.cAddedFormat.setBackground(QBrush(QColor(190, 237, 190))) self.cRemovedFormat = self.contents.currentCharFormat() self.cRemovedFormat.setBackground(QBrush(QColor(237, 190, 190))) self.cReplacedFormat = self.contents.currentCharFormat() self.cReplacedFormat.setBackground(QBrush(QColor(190, 190, 237))) self.cLineNoFormat = self.contents.currentCharFormat() self.cLineNoFormat.setBackground(QBrush(QColor(255, 220, 168))) # connect some of our widgets explicitly self.file1Edit.textChanged.connect(self.__fileChanged) self.file2Edit.textChanged.connect(self.__fileChanged) def show(self, filename=None): """ Public slot to show the dialog. @param filename name of a file to use as the first file (string) """ if filename: self.file1Edit.setText(filename) super(DiffDialog, self).show() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.diffButton: self.on_diffButton_clicked() elif button == self.saveButton: self.on_saveButton_clicked() @pyqtSlot() def on_saveButton_clicked(self): """ Private slot to handle the Save button press. It saves the diff shown in the dialog to a file in the local filesystem. """ dname, fname = Utilities.splitPath(self.filename2) if fname != '.': fname = "{0}.diff".format(self.filename2) else: fname = dname fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Diff"), fname, self.tr("Patch Files (*.diff)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fname: return ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Diff"), self.tr("

The patch file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) try: f = open(fname, "w", encoding="utf-8") txt = self.contents.toPlainText() try: f.write(txt) except UnicodeError: pass f.close() except IOError as why: E5MessageBox.critical( self, self.tr('Save Diff'), self.tr( '

The patch file {0} could not be saved.
' 'Reason: {1}

').format(fname, str(why))) @pyqtSlot() def on_diffButton_clicked(self): """ Private slot to handle the Compare button press. """ self.filename1 = Utilities.toNativeSeparators(self.file1Edit.text()) try: filemtime1 = time.ctime(os.stat(self.filename1).st_mtime) except IOError: filemtime1 = "" try: f1 = open(self.filename1, "r", encoding="utf-8") lines1 = f1.readlines() f1.close() except IOError: E5MessageBox.critical( self, self.tr("Compare Files"), self.tr( """

The file {0} could not be read.

""") .format(self.filename1)) return self.filename2 = Utilities.toNativeSeparators(self.file2Edit.text()) try: filemtime2 = time.ctime(os.stat(self.filename2).st_mtime) except IOError: filemtime2 = "" try: f2 = open(self.filename2, "r", encoding="utf-8") lines2 = f2.readlines() f2.close() except IOError: E5MessageBox.critical( self, self.tr("Compare Files"), self.tr( """

The file {0} could not be read.

""") .format(self.filename2)) return self.contents.clear() self.saveButton.setEnabled(False) if self.unifiedRadioButton.isChecked(): self.__generateUnifiedDiff( lines1, lines2, self.filename1, self.filename2, filemtime1, filemtime2) else: self.__generateContextDiff( lines1, lines2, self.filename1, self.filename2, filemtime1, filemtime2) tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() self.saveButton.setEnabled(True) def __appendText(self, txt, format): """ Private method to append text to the end of the contents pane. @param txt text to insert (string) @param format text format to be used (QTextCharFormat) """ tc = self.contents.textCursor() tc.movePosition(QTextCursor.End) self.contents.setTextCursor(tc) self.contents.setCurrentCharFormat(format) self.contents.insertPlainText(txt) def __generateUnifiedDiff(self, a, b, fromfile, tofile, fromfiledate, tofiledate): """ Private slot to generate a unified diff output. @param a first sequence of lines (list of strings) @param b second sequence of lines (list of strings) @param fromfile filename of the first file (string) @param tofile filename of the second file (string) @param fromfiledate modification time of the first file (string) @param tofiledate modification time of the second file (string) """ paras = 0 for line in unified_diff(a, b, fromfile, tofile, fromfiledate, tofiledate): if line.startswith('+') or line.startswith('>'): format = self.cAddedFormat elif line.startswith('-') or line.startswith('<'): format = self.cRemovedFormat elif line.startswith('@@'): format = self.cLineNoFormat else: format = self.cNormalFormat self.__appendText(line, format) paras += 1 if not (paras % self.updateInterval): QApplication.processEvents() if paras == 0: self.__appendText( self.tr('There is no difference.'), self.cNormalFormat) def __generateContextDiff(self, a, b, fromfile, tofile, fromfiledate, tofiledate): """ Private slot to generate a context diff output. @param a first sequence of lines (list of strings) @param b second sequence of lines (list of strings) @param fromfile filename of the first file (string) @param tofile filename of the second file (string) @param fromfiledate modification time of the first file (string) @param tofiledate modification time of the second file (string) """ paras = 0 for line in context_diff(a, b, fromfile, tofile, fromfiledate, tofiledate): if line.startswith('+ '): format = self.cAddedFormat elif line.startswith('- '): format = self.cRemovedFormat elif line.startswith('! '): format = self.cReplacedFormat elif (line.startswith('*** ') or line.startswith('--- ')) and \ paras > 1: format = self.cLineNoFormat else: format = self.cNormalFormat self.__appendText(line, format) paras += 1 if not (paras % self.updateInterval): QApplication.processEvents() if paras == 0: self.__appendText( self.tr('There is no difference.'), self.cNormalFormat) def __fileChanged(self): """ Private slot to enable/disable the Compare button. """ if not self.file1Edit.text() or \ not self.file2Edit.text(): self.diffButton.setEnabled(False) else: self.diffButton.setEnabled(True) def __selectFile(self, lineEdit): """ Private slot to display a file selection dialog. @param lineEdit field for the display of the selected filename (QLineEdit) """ filename = E5FileDialog.getOpenFileName( self, self.tr("Select file to compare"), lineEdit.text(), "") if filename: lineEdit.setText(Utilities.toNativeSeparators(filename)) @pyqtSlot() def on_file1Button_clicked(self): """ Private slot to handle the file 1 file selection button press. """ self.__selectFile(self.file1Edit) @pyqtSlot() def on_file2Button_clicked(self): """ Private slot to handle the file 2 file selection button press. """ self.__selectFile(self.file2Edit) class DiffWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(DiffWindow, self).__init__(parent) self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw = DiffDialog(self) self.cw.installEventFilter(self) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) def eventFilter(self, obj, event): """ Public method to filter events. @param obj reference to the object the event is meant for (QObject) @param event reference to the event object (QEvent) @return flag indicating, whether the event was handled (boolean) """ if event.type() == QEvent.Close: QApplication.exit() return True return False eric-6.0.8/eric/UI/Previewer.py0000644000175000017500000001537712451233373015324 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a previewer widget for HTML, Markdown and ReST files. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QStackedWidget import Preferences class Previewer(QStackedWidget): """ Class implementing a previewer widget containing a stack of specialized previewers. """ def __init__(self, viewmanager, splitter, parent=None): """ Constructor @param viewmanager reference to the viewmanager object (ViewManager) @param splitter reference to the embedding splitter (QSplitter) @param parent reference to the parent widget (QWidget) """ super(Previewer, self).__init__(parent) self.__vm = viewmanager self.__splitter = splitter self.__firstShow = True self.__htmlPreviewer = None self.__qssPreviewer = None # Don't update too often because the UI might become sluggish self.__typingTimer = QTimer() self.__typingTimer.setInterval(500) # 500ms self.__typingTimer.timeout.connect(self.__processEditor) self.__vm.editorChangedEd.connect(self.__editorChanged) self.__vm.editorLanguageChanged.connect(self.__editorLanguageChanged) self.__vm.editorTextChanged.connect(self.__editorTextChanged) self.__vm.previewStateChanged.connect(self.__previewStateChanged) self.__splitter.splitterMoved.connect(self.__splitterMoved) self.hide() def show(self): """ Public method to show the preview widget. """ super(Previewer, self).show() if self.__firstShow: self.__splitter.restoreState( Preferences.getUI("PreviewSplitterState")) self.__firstShow = False self.__typingTimer.start() def hide(self): """ Public method to hide the preview widget. """ super(Previewer, self).hide() self.__typingTimer.stop() def shutdown(self): """ Public method to perform shutdown actions. """ self.__typingTimer.stop() self.__htmlPreviewer and self.__htmlPreviewer.shutdown() def __splitterMoved(self): """ Private slot to handle the movement of the embedding splitter's handle. """ state = self.__splitter.saveState() Preferences.setUI("PreviewSplitterState", state) def __editorChanged(self, editor): """ Private slot to handle a change of the current editor. @param editor reference to the editor (Editor) """ if editor is None: self.hide() return if Preferences.getUI("ShowFilePreview") and \ self.__isPreviewable(editor): self.show() self.__processEditor() else: self.hide() def __editorLanguageChanged(self, editor): """ Private slot to handle a change of the current editor's language. @param editor reference to the editor (Editor) """ self.__editorChanged(editor) def __editorTextChanged(self, editor): """ Private slot to handle changes of an editor's text. @param editor reference to the editor (Editor) """ if self.isVisible(): self.__typingTimer.stop() self.__typingTimer.start() def __previewStateChanged(self, on): """ Private slot to toggle the display of the preview. @param on flag indicating to show a preview (boolean) """ editor = self.__vm.activeWindow() if on and editor and self.__isPreviewable(editor): self.show() else: self.hide() def __isPreviewable(self, editor): """ Private method to check, if a preview can be shown for the given editor. @param editor reference to an editor (Editor) @return flag indicating if a preview can be shown (boolean) """ if editor: if editor.getFileName() is not None: extension = os.path.normcase( os.path.splitext(editor.getFileName())[1][1:]) return extension in \ Preferences.getEditor("PreviewHtmlFileNameExtensions") + \ Preferences.getEditor( "PreviewMarkdownFileNameExtensions") + \ Preferences.getEditor("PreviewRestFileNameExtensions") + \ Preferences.getEditor("PreviewQssFileNameExtensions") elif editor.getLanguage() in ["HTML", "QSS"]: return True return False def __processEditor(self): """ Private slot to schedule the processing of the current editor's text. """ self.__typingTimer.stop() editor = self.__vm.activeWindow() if editor is not None: fn = editor.getFileName() if fn: extension = os.path.normcase(os.path.splitext(fn)[1][1:]) else: extension = "" if extension in \ Preferences.getEditor("PreviewHtmlFileNameExtensions") or \ editor.getLanguage() == "HTML": language = "HTML" elif extension in \ Preferences.getEditor("PreviewMarkdownFileNameExtensions"): language = "Markdown" elif extension in \ Preferences.getEditor("PreviewRestFileNameExtensions"): language = "ReST" elif extension in \ Preferences.getEditor("PreviewQssFileNameExtensions"): language = "QSS" else: language = "" if language in ["HTML", "Markdown", "ReST"]: if self.__htmlPreviewer is None: from .Previewers.PreviewerHTML import PreviewerHTML self.__htmlPreviewer = PreviewerHTML() self.addWidget(self.__htmlPreviewer) self.setCurrentWidget(self.__htmlPreviewer) self.__htmlPreviewer.processEditor(editor) elif language == "QSS": if self.__qssPreviewer is None: from .Previewers.PreviewerQSS import PreviewerQSS self.__qssPreviewer = PreviewerQSS() self.addWidget(self.__qssPreviewer) self.setCurrentWidget(self.__qssPreviewer) self.__qssPreviewer.processEditor(editor) eric-6.0.8/eric/UI/NotificationWidget.ui0000644000175000017500000000504012316034124017106 0ustar piotrpiotr NotificationWidget 0 0 400 80 0 QFrame::StyledPanel QFrame::Raised 4 48 48 0 0 335 0 75 true 335 0 Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true eric-6.0.8/eric/UI/BrowserModel.py0000644000175000017500000016611012471662770015761 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the browser model. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os import sys import fnmatch import json from PyQt5.QtCore import QDir, QModelIndex, QAbstractItemModel, \ QFileSystemWatcher, Qt, QProcess, QCoreApplication from PyQt5.QtGui import QImageReader, QFont from PyQt5.QtWidgets import QApplication import UI.PixmapCache import Preferences import Utilities BrowserItemRoot = 0 BrowserItemDirectory = 1 BrowserItemSysPath = 2 BrowserItemFile = 3 BrowserItemClass = 4 BrowserItemMethod = 5 BrowserItemAttributes = 6 BrowserItemAttribute = 7 BrowserItemCoding = 8 class BrowserModel(QAbstractItemModel): """ Class implementing the browser model. """ def __init__(self, parent=None, nopopulate=False): """ Constructor @param parent reference to parent object (QObject) @keyparam nopopulate flag indicating to not populate the model (boolean) """ super(BrowserModel, self).__init__(parent) self.progDir = None self.watchedItems = {} self.watcher = QFileSystemWatcher(self) self.watcher.directoryChanged.connect(self.directoryChanged) self.__sysPathInterpreter = "" self.__sysPathItem = None if not nopopulate: rootData = QCoreApplication.translate("BrowserModel", "Name") self.rootItem = BrowserItem(None, rootData) self.__populateModel() def columnCount(self, parent=QModelIndex()): """ Public method to get the number of columns. @param parent index of parent item (QModelIndex) @return number of columns (integer) """ if parent.isValid(): item = parent.internalPointer() else: item = self.rootItem return item.columnCount() + 1 def data(self, index, role): """ Public method to get data of an item. @param index index of the data to retrieve (QModelIndex) @param role role of data (Qt.ItemDataRole) @return requested data """ if not index.isValid(): return None if role == Qt.DisplayRole: item = index.internalPointer() if index.column() < item.columnCount(): return item.data(index.column()) elif index.column() == item.columnCount() and \ index.column() < self.columnCount(self.parent(index)): # This is for the case where an item under a multi-column # parent doesn't have a value for all the columns return "" elif role == Qt.DecorationRole: if index.column() == 0: return index.internalPointer().getIcon() elif role == Qt.FontRole: item = index.internalPointer() if item.isSymlink(): font = QFont(QApplication.font("QTreeView")) font.setItalic(True) return font return None def flags(self, index): """ Public method to get the item flags. @param index index of the data to retrieve (QModelIndex) @return requested flags (Qt.ItemFlags) """ if not index.isValid(): return Qt.ItemIsEnabled return Qt.ItemIsEnabled | Qt.ItemIsSelectable def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get the header data. @param section number of section to get data for (integer) @param orientation header orientation (Qt.Orientation) @param role role of data (Qt.ItemDataRole) @return requested header data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: if section >= self.rootItem.columnCount(): return "" else: return self.rootItem.data(section) return None def index(self, row, column, parent=QModelIndex()): """ Public method to create an index. @param row row number of the new index (integer) @param column column number of the new index (integer) @param parent index of parent item (QModelIndex) @return index object (QModelIndex) """ # The model/view framework considers negative values out-of-bounds, # however in python they work when indexing into lists. So make sure # we return an invalid index for out-of-bounds row/col if row < 0 or column < 0 or \ row >= self.rowCount(parent) or column >= self.columnCount(parent): return QModelIndex() if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() try: if not parentItem.isPopulated(): self.populateItem(parentItem) childItem = parentItem.child(row) except IndexError: childItem = None if childItem: return self.createIndex(row, column, childItem) else: return QModelIndex() def parent(self, index): """ Public method to get the index of the parent object. @param index index of the item (QModelIndex) @return index of parent item (QModelIndex) """ if not index.isValid(): return QModelIndex() childItem = index.internalPointer() parentItem = childItem.parent() if parentItem == self.rootItem: return QModelIndex() return self.createIndex(parentItem.row(), 0, parentItem) def rowCount(self, parent=QModelIndex()): """ Public method to get the number of rows. @param parent index of parent item (QModelIndex) @return number of rows (integer) """ # Only the first column should have children if parent.column() > 0: return 0 if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() if not parentItem.isPopulated(): # lazy population self.populateItem(parentItem) return parentItem.childCount() def hasChildren(self, parent=QModelIndex()): """ Public method to check for the presence of child items. We always return True for normal items in order to do lazy population of the tree. @param parent index of parent item (QModelIndex) @return flag indicating the presence of child items (boolean) """ # Only the first column should have children if parent.column() > 0: return 0 if not parent.isValid(): return self.rootItem.childCount() > 0 if parent.internalPointer().isLazyPopulated(): return True else: return parent.internalPointer().childCount() > 0 def clear(self): """ Public method to clear the model. """ self.beginResetModel() self.rootItem.removeChildren() self.endResetModel() def item(self, index): """ Public method to get a reference to an item. @param index index of the data to retrieve (QModelIndex) @return requested item reference (BrowserItem) """ if not index.isValid(): return None return index.internalPointer() def _addWatchedItem(self, itm): """ Protected method to watch an item. @param itm item to be watched (BrowserDirectoryItem) """ if isinstance(itm, BrowserDirectoryItem): dirName = itm.dirName() if dirName != "" and \ not dirName.startswith("//") and \ not dirName.startswith("\\\\"): if dirName not in self.watcher.directories(): self.watcher.addPath(dirName) if dirName in self.watchedItems: if itm not in self.watchedItems[dirName]: self.watchedItems[dirName].append(itm) else: self.watchedItems[dirName] = [itm] def _removeWatchedItem(self, itm): """ Protected method to remove a watched item. @param itm item to be removed (BrowserDirectoryItem) """ if isinstance(itm, BrowserDirectoryItem): dirName = itm.dirName() if dirName in self.watchedItems: if itm in self.watchedItems[dirName]: self.watchedItems[dirName].remove(itm) if len(self.watchedItems[dirName]) == 0: del self.watchedItems[dirName] self.watcher.removePath(dirName) def directoryChanged(self, path): """ Public slot to handle the directoryChanged signal of the watcher. @param path path of the directory (string) """ if path not in self.watchedItems: # just ignore the situation we don't have a reference to the item return if Preferences.getUI("BrowsersListHiddenFiles"): filter = QDir.Filters( QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot) else: filter = QDir.Filters(QDir.AllEntries | QDir.NoDot | QDir.NoDotDot) for itm in self.watchedItems[path]: oldCnt = itm.childCount() qdir = QDir(itm.dirName()) entryInfoList = qdir.entryInfoList(filter) # step 1: check for new entries children = itm.children() for f in entryInfoList: fpath = Utilities.toNativeSeparators(f.absoluteFilePath()) childFound = False for child in children: if child.name() == fpath: childFound = True children.remove(child) break if childFound: continue cnt = itm.childCount() self.beginInsertRows( self.createIndex(itm.row(), 0, itm), cnt, cnt) if f.isDir(): node = BrowserDirectoryItem( itm, Utilities.toNativeSeparators(f.absoluteFilePath()), False) else: node = BrowserFileItem( itm, Utilities.toNativeSeparators(f.absoluteFilePath())) self._addItem(node, itm) self.endInsertRows() # step 2: check for removed entries if len(entryInfoList) != itm.childCount(): for row in range(oldCnt - 1, -1, -1): child = itm.child(row) childname = Utilities.fromNativeSeparators(child.name()) entryFound = False for f in entryInfoList: if f.absoluteFilePath() == childname: entryFound = True entryInfoList.remove(f) break if entryFound: continue self._removeWatchedItem(child) self.beginRemoveRows( self.createIndex(itm.row(), 0, itm), row, row) itm.removeChild(child) self.endRemoveRows() def __populateModel(self): """ Private method to populate the browser model. """ self.toplevelDirs = [] tdp = Preferences.Prefs.settings.value('BrowserModel/ToplevelDirs') if tdp: self.toplevelDirs = tdp else: self.toplevelDirs.append( Utilities.toNativeSeparators(QDir.homePath())) for d in QDir.drives(): self.toplevelDirs.append(Utilities.toNativeSeparators( d.absoluteFilePath())) for d in self.toplevelDirs: itm = BrowserDirectoryItem(self.rootItem, d) self._addItem(itm, self.rootItem) def interpreterChanged(self, interpreter): """ Public method to handle a change of the debug client's interpreter. @param interpreter interpreter of the debug client (string) """ if interpreter and "python" in interpreter.lower(): if interpreter.endswith("w.exe"): interpreter = interpreter.replace("w.exe", ".exe") if self.__sysPathInterpreter != interpreter: self.__sysPathInterpreter = interpreter # step 1: remove sys.path entry if self.__sysPathItem is not None: self.beginRemoveRows( QModelIndex(), self.__sysPathItem.row(), self.__sysPathItem.row()) self.rootItem.removeChild(self.__sysPathItem) self.endRemoveRows() self.__sysPathItem = None if self.__sysPathInterpreter: # step 2: add a new one self.__sysPathItem = BrowserSysPathItem(self.rootItem) self.addItem(self.__sysPathItem) else: # remove sys.path entry if self.__sysPathItem is not None: self.beginRemoveRows( QModelIndex(), self.__sysPathItem.row(), self.__sysPathItem.row()) self.rootItem.removeChild(self.__sysPathItem) self.endRemoveRows() self.__sysPathItem = None self.__sysPathInterpreter = "" def programChange(self, dirname): """ Public method to change the entry for the directory of file being debugged. @param dirname name of the directory containing the file (string) """ if self.progDir: if dirname == self.progDir.dirName(): return # remove old entry self._removeWatchedItem(self.progDir) self.beginRemoveRows( QModelIndex(), self.progDir.row(), self.progDir.row()) self.rootItem.removeChild(self.progDir) self.endRemoveRows() self.progDir = None itm = BrowserDirectoryItem(self.rootItem, dirname) self.addItem(itm) self.progDir = itm def addTopLevelDir(self, dirname): """ Public method to add a new toplevel directory. @param dirname name of the new toplevel directory (string) """ if dirname not in self.toplevelDirs: itm = BrowserDirectoryItem(self.rootItem, dirname) self.addItem(itm) self.toplevelDirs.append(itm.dirName()) def removeToplevelDir(self, index): """ Public method to remove a toplevel directory. @param index index of the toplevel directory to be removed (QModelIndex) """ if not index.isValid(): return item = index.internalPointer() self.beginRemoveRows(index.parent(), index.row(), index.row()) self.rootItem.removeChild(item) self.endRemoveRows() self.toplevelDirs.remove(item.dirName()) self._removeWatchedItem(item) def saveToplevelDirs(self): """ Public slot to save the toplevel directories. """ Preferences.Prefs.settings.setValue( 'BrowserModel/ToplevelDirs', self.toplevelDirs) def _addItem(self, itm, parentItem): """ Protected slot to add an item. @param itm reference to item to add (BrowserItem) @param parentItem reference to item to add to (BrowserItem) """ parentItem.appendChild(itm) def addItem(self, itm, parent=QModelIndex()): """ Public slot to add an item. @param itm item to add (BrowserItem) @param parent index of parent item (QModelIndex) """ if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() cnt = parentItem.childCount() self.beginInsertRows(parent, cnt, cnt) self._addItem(itm, parentItem) self.endInsertRows() def populateItem(self, parentItem, repopulate=False): """ Public method to populate an item's subtree. @param parentItem reference to the item to be populated @param repopulate flag indicating a repopulation (boolean) """ if parentItem.type() == BrowserItemDirectory: self.populateDirectoryItem(parentItem, repopulate) elif parentItem.type() == BrowserItemSysPath: self.populateSysPathItem(parentItem, repopulate) elif parentItem.type() == BrowserItemFile: self.populateFileItem(parentItem, repopulate) elif parentItem.type() == BrowserItemClass: self.populateClassItem(parentItem, repopulate) elif parentItem.type() == BrowserItemMethod: self.populateMethodItem(parentItem, repopulate) elif parentItem.type() == BrowserItemAttributes: self.populateClassAttributesItem(parentItem, repopulate) def populateDirectoryItem(self, parentItem, repopulate=False): """ Public method to populate a directory item's subtree. @param parentItem reference to the directory item to be populated @param repopulate flag indicating a repopulation (boolean) """ self._addWatchedItem(parentItem) qdir = QDir(parentItem.dirName()) if Preferences.getUI("BrowsersListHiddenFiles"): filter = QDir.Filters( QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot) else: filter = QDir.Filters(QDir.AllEntries | QDir.NoDot | QDir.NoDotDot) entryInfoList = qdir.entryInfoList(filter) if len(entryInfoList) > 0: if repopulate: self.beginInsertRows( self.createIndex(parentItem.row(), 0, parentItem), 0, len(entryInfoList) - 1) for f in entryInfoList: if f.isDir(): node = BrowserDirectoryItem( parentItem, Utilities.toNativeSeparators(f.absoluteFilePath()), False) else: fileFilters = \ Preferences.getUI("BrowsersFileFilters").split(";") if fileFilters: fn = f.fileName() if any([fnmatch.fnmatch(fn, ff.strip()) for ff in fileFilters]): continue node = BrowserFileItem( parentItem, Utilities.toNativeSeparators(f.absoluteFilePath())) self._addItem(node, parentItem) if repopulate: self.endInsertRows() def populateSysPathItem(self, parentItem, repopulate=False): """ Public method to populate a sys.path item's subtree. @param parentItem reference to the sys.path item to be populated @param repopulate flag indicating a repopulation (boolean) """ if self.__sysPathInterpreter: script = "import sys, json; print(json.dumps(sys.path))" proc = QProcess() proc.start(self.__sysPathInterpreter, ["-c", script]) finished = proc.waitForFinished(3000) if finished: procOutput = str(proc.readAllStandardOutput(), Preferences.getSystem("IOEncoding"), 'replace') syspath = [p for p in json.loads(procOutput) if p] if len(syspath) > 0: if repopulate: self.beginInsertRows( self.createIndex(parentItem.row(), 0, parentItem), 0, len(syspath) - 1) for p in syspath: if os.path.isdir(p): node = BrowserDirectoryItem(parentItem, p) else: node = BrowserFileItem(parentItem, p) self._addItem(node, parentItem) if repopulate: self.endInsertRows() else: proc.kill() def populateFileItem(self, parentItem, repopulate=False): """ Public method to populate a file item's subtree. @param parentItem reference to the file item to be populated @param repopulate flag indicating a repopulation (boolean) """ import Utilities.ClassBrowsers moduleName = parentItem.moduleName() fileName = parentItem.fileName() try: dict = Utilities.ClassBrowsers.readmodule( moduleName, [parentItem.dirName()], parentItem.isPython2File() or parentItem.isPython3File()) except ImportError: return keys = list(dict.keys()) if len(keys) > 0: if repopulate: self.beginInsertRows( self.createIndex(parentItem.row(), 0, parentItem), 0, len(keys) - 1) for key in keys: if key.startswith("@@"): # special treatment done later continue cl = dict[key] try: if cl.module == moduleName: node = BrowserClassItem(parentItem, cl, fileName) self._addItem(node, parentItem) except AttributeError: pass if "@@Coding@@" in keys: node = BrowserCodingItem( parentItem, QCoreApplication.translate("BrowserModel", "Coding: {0}") .format(dict["@@Coding@@"].coding)) self._addItem(node, parentItem) if "@@Globals@@" in keys: node = BrowserClassAttributesItem( parentItem, dict["@@Globals@@"].globals, QCoreApplication.translate("BrowserModel", "Globals")) self._addItem(node, parentItem) if repopulate: self.endInsertRows() parentItem._populated = True def populateClassItem(self, parentItem, repopulate=False): """ Public method to populate a class item's subtree. @param parentItem reference to the class item to be populated @param repopulate flag indicating a repopulation (boolean) """ cl = parentItem.classObject() file_ = parentItem.fileName() if cl is None: return # build sorted list of names keys = [] for name in list(cl.classes.keys()): keys.append((name, 'c')) for name in list(cl.methods.keys()): keys.append((name, 'm')) if len(keys) > 0: if repopulate: self.beginInsertRows( self.createIndex(parentItem.row(), 0, parentItem), 0, len(keys) - 1) for key, kind in keys: if kind == 'c': node = BrowserClassItem(parentItem, cl.classes[key], file_) elif kind == 'm': node = BrowserMethodItem(parentItem, cl.methods[key], file_) self._addItem(node, parentItem) if repopulate: self.endInsertRows() if len(cl.attributes): node = BrowserClassAttributesItem( parentItem, cl.attributes, QCoreApplication.translate("BrowserModel", "Attributes")) if repopulate: self.addItem( node, self.createIndex(parentItem.row(), 0, parentItem)) else: self._addItem(node, parentItem) if len(cl.globals): node = BrowserClassAttributesItem( parentItem, cl.globals, QCoreApplication.translate("BrowserModel", "Class Attributes"), True) if repopulate: self.addItem( node, self.createIndex(parentItem.row(), 0, parentItem)) else: self._addItem(node, parentItem) def populateMethodItem(self, parentItem, repopulate=False): """ Public method to populate a method item's subtree. @param parentItem reference to the method item to be populated @param repopulate flag indicating a repopulation (boolean) """ fn = parentItem.functionObject() file_ = parentItem.fileName() if fn is None: return # build sorted list of names keys = [] for name in list(fn.classes.keys()): keys.append((name, 'c')) for name in list(fn.methods.keys()): keys.append((name, 'm')) if len(keys) > 0: if repopulate: self.beginInsertRows( self.createIndex(parentItem.row(), 0, parentItem), 0, len(keys) - 1) for key, kind in keys: if kind == 'c': node = BrowserClassItem(parentItem, fn.classes[key], file_) elif kind == 'm': node = BrowserMethodItem(parentItem, fn.methods[key], file_) self._addItem(node, parentItem) if repopulate: self.endInsertRows() def populateClassAttributesItem(self, parentItem, repopulate=False): """ Public method to populate a class attributes item's subtree. @param parentItem reference to the class attributes item to be populated @param repopulate flag indicating a repopulation (boolean) """ classAttributes = parentItem.isClassAttributes() attributes = parentItem.attributes() if not attributes: return keys = list(attributes.keys()) if len(keys) > 0: if repopulate: self.beginInsertRows( self.createIndex(parentItem.row(), 0, parentItem), 0, len(keys) - 1) for key in keys: node = BrowserClassAttributeItem(parentItem, attributes[key], classAttributes) self._addItem(node, parentItem) if repopulate: self.endInsertRows() class BrowserItem(object): """ Class implementing the data structure for browser items. """ def __init__(self, parent, data): """ Constructor @param parent reference to the parent item @param data single data of the item """ self.childItems = [] self.parentItem = parent self.itemData = [data] self.type_ = BrowserItemRoot self.icon = UI.PixmapCache.getIcon("empty.png") self._populated = True self._lazyPopulation = False self.symlink = False def appendChild(self, child): """ Public method to add a child to this item. @param child reference to the child item to add (BrowserItem) """ self.childItems.append(child) self._populated = True def removeChild(self, child): """ Public method to remove a child. @param child reference to the child to remove (BrowserItem) """ self.childItems.remove(child) def removeChildren(self): """ Public method to remove all children. """ self.childItems = [] def child(self, row): """ Public method to get a child id. @param row number of child to get the id of (integer) @return reference to the child item (BrowserItem) """ return self.childItems[row] def children(self): """ Public method to get the ids of all child items. @return references to all child items (list of BrowserItem) """ return self.childItems[:] def childCount(self): """ Public method to get the number of available child items. @return number of child items (integer) """ return len(self.childItems) def columnCount(self): """ Public method to get the number of available data items. @return number of data items (integer) """ return len(self.itemData) def data(self, column): """ Public method to get a specific data item. @param column number of the requested data item (integer) @return stored data item """ try: return self.itemData[column] except IndexError: return "" def parent(self): """ Public method to get the reference to the parent item. @return reference to the parent item """ return self.parentItem def row(self): """ Public method to get the row number of this item. @return row number (integer) """ return self.parentItem.childItems.index(self) def type(self): """ Public method to get the item type. @return type of the item """ return self.type_ def isPublic(self): """ Public method returning the public visibility status. @return flag indicating public visibility (boolean) """ return True def getIcon(self): """ Public method to get the items icon. @return the icon (QIcon) """ return self.icon def isPopulated(self): """ Public method to chek, if this item is populated. @return population status (boolean) """ return self._populated def isLazyPopulated(self): """ Public method to check, if this item should be populated lazyly. @return lazy population flag (boolean) """ return self._lazyPopulation def lessThan(self, other, column, order): """ Public method to check, if the item is less than the other one. @param other reference to item to compare against (BrowserItem) @param column column number to use for the comparison (integer) @param order sort order (Qt.SortOrder) (for special sorting) @return true, if this item is less than other (boolean) """ try: return self.itemData[column] < other.itemData[column] except IndexError: return False def isSymlink(self): """ Public method to check, if the items is a symbolic link. @return flag indicating a symbolic link (boolean) """ return self.symlink class BrowserDirectoryItem(BrowserItem): """ Class implementing the data structure for browser directory items. """ def __init__(self, parent, dinfo, full=True): """ Constructor @param parent parent item @param dinfo dinfo is the string for the directory (string) @param full flag indicating full pathname should be displayed (boolean) """ self._dirName = os.path.abspath(dinfo) if full: dn = self._dirName else: dn = os.path.basename(self._dirName) BrowserItem.__init__(self, parent, dn) self.type_ = BrowserItemDirectory if os.path.lexists(self._dirName) and os.path.islink(self._dirName): self.symlink = True self.icon = UI.PixmapCache.getSymlinkIcon("dirClosed.png") else: self.icon = UI.PixmapCache.getIcon("dirClosed.png") self._populated = False self._lazyPopulation = True def setName(self, dinfo, full=True): """ Public method to set the directory name. @param dinfo dinfo is the string for the directory (string) @param full flag indicating full pathname should be displayed (boolean) """ self._dirName = os.path.abspath(dinfo) if full: dn = self._dirName else: dn = os.path.basename(self._dirName) self.itemData[0] = dn def dirName(self): """ Public method returning the directory name. @return directory name (string) """ return self._dirName def name(self): """ Public method to return the name of the item. @return name of the item (string) """ return self._dirName def lessThan(self, other, column, order): """ Public method to check, if the item is less than the other one. @param other reference to item to compare against (BrowserItem) @param column column number to use for the comparison (integer) @param order sort order (Qt.SortOrder) (for special sorting) @return true, if this item is less than other (boolean) """ if issubclass(other.__class__, BrowserFileItem): if Preferences.getUI("BrowsersListFoldersFirst"): return order == Qt.AscendingOrder return BrowserItem.lessThan(self, other, column, order) class BrowserSysPathItem(BrowserItem): """ Class implementing the data structure for browser sys.path items. """ def __init__(self, parent): """ Constructor @param parent parent item """ BrowserItem.__init__(self, parent, "sys.path") self.type_ = BrowserItemSysPath self.icon = UI.PixmapCache.getIcon("filePython.png") self._populated = False self._lazyPopulation = True def name(self): """ Public method to return the name of the item. @return name of the item (string) """ return "sys.path" class BrowserFileItem(BrowserItem): """ Class implementing the data structure for browser file items. """ def __init__(self, parent, finfo, full=True, sourceLanguage=""): """ Constructor @param parent parent item @param finfo the string for the file (string) @param full flag indicating full pathname should be displayed (boolean) @param sourceLanguage source code language of the project (string) """ BrowserItem.__init__(self, parent, os.path.basename(finfo)) self.type_ = BrowserItemFile self.fileext = os.path.splitext(finfo)[1].lower() self._filename = os.path.abspath(finfo) self._dirName = os.path.dirname(finfo) self.sourceLanguage = sourceLanguage self._moduleName = '' pixName = "" if self.isPython2File(): if self.fileext == '.py': pixName = "filePython.png" else: pixName = "filePython2.png" self._populated = False self._lazyPopulation = True self._moduleName = os.path.basename(finfo) elif self.isPython3File(): pixName = "filePython.png" self._populated = False self._lazyPopulation = True self._moduleName = os.path.basename(finfo) elif self.isRubyFile(): pixName = "fileRuby.png" self._populated = False self._lazyPopulation = True self._moduleName = os.path.basename(finfo) elif self.isDesignerFile(): pixName = "fileDesigner.png" elif self.isLinguistFile(): if self.fileext == '.ts': pixName = "fileLinguist.png" else: pixName = "fileLinguist2.png" elif self.isResourcesFile(): pixName = "fileResource.png" elif self.isProjectFile(): pixName = "fileProject.png" elif self.isMultiProjectFile(): pixName = "fileMultiProject.png" elif self.isIdlFile(): pixName = "fileIDL.png" self._populated = False self._lazyPopulation = True self._moduleName = os.path.basename(finfo) elif self.isSvgFile(): pixName = "fileSvg.png" elif self.isPixmapFile(): pixName = "filePixmap.png" elif self.isDFile(): pixName = "fileD.png" elif self.isJavaScriptFile(): pixName = "fileJavascript.png" self._populated = False self._lazyPopulation = sys.version_info[0] == 3 self._moduleName = os.path.basename(finfo) else: pixName = "fileMisc.png" if os.path.lexists(self._filename) and os.path.islink(self._filename): self.symlink = True self.icon = UI.PixmapCache.getSymlinkIcon(pixName) else: self.icon = UI.PixmapCache.getIcon(pixName) def setName(self, finfo, full=True): """ Public method to set the directory name. @param finfo the string for the file (string) @param full flag indicating full pathname should be displayed (boolean) """ self._filename = os.path.abspath(finfo) self.itemData[0] = os.path.basename(finfo) if self.isPython2File() or self.isPython3File() or \ self.isRubyFile() or self.isIdlFile(): self._dirName = os.path.dirname(finfo) self._moduleName = os.path.basename(finfo) def fileName(self): """ Public method returning the filename. @return filename (string) """ return self._filename def name(self): """ Public method to return the name of the item. @return name of the item (string) """ return self._filename def fileExt(self): """ Public method returning the file extension. @return file extension (string) """ return self.fileext def dirName(self): """ Public method returning the directory name. @return directory name (string) """ return self._dirName def moduleName(self): """ Public method returning the module name. @return module name (string) """ return self._moduleName def isPython2File(self): """ Public method to check, if this file is a Python script. @return flag indicating a Python file (boolean) """ return self.fileext in Preferences.getPython("PythonExtensions") or \ (self.fileext == "" and self.sourceLanguage in ["Python", "Python2"]) def isPython3File(self): """ Public method to check, if this file is a Python3 script. @return flag indicating a Python file (boolean) """ return self.fileext in Preferences.getPython("Python3Extensions") or \ (self.fileext == "" and self.sourceLanguage == "Python3") def isRubyFile(self): """ Public method to check, if this file is a Ruby script. @return flag indicating a Ruby file (boolean) """ return self.fileext == '.rb' or \ (self.fileext == "" and self.sourceLanguage == "Ruby") def isDesignerFile(self): """ Public method to check, if this file is a Qt-Designer file. @return flag indicating a Qt-Designer file (boolean) """ return self.fileext == '.ui' def isLinguistFile(self): """ Public method to check, if this file is a Qt-Linguist file. @return flag indicating a Qt-Linguist file (boolean) """ return self.fileext in ['.ts', '.qm'] def isResourcesFile(self): """ Public method to check, if this file is a Qt-Resources file. @return flag indicating a Qt-Resources file (boolean) """ return self.fileext == '.qrc' def isProjectFile(self): """ Public method to check, if this file is an eric project file. @return flag indicating an eric project file (boolean) """ return self.fileext in ['.e4p'] def isMultiProjectFile(self): """ Public method to check, if this file is an eric multi project file. @return flag indicating an eric project file (boolean) """ return self.fileext in ['.e4m', '.e5m'] def isIdlFile(self): """ Public method to check, if this file is a CORBA IDL file. @return flag indicating a CORBA IDL file (boolean) """ return self.fileext == '.idl' def isJavaScriptFile(self): """ Public method to check, if this file is a JavaScript file. @return flag indicating a JavaScript file (boolean) """ return self.fileext == '.js' def isPixmapFile(self): """ Public method to check, if this file is a pixmap file. @return flag indicating a pixmap file (boolean) """ return self.fileext[1:] in QImageReader.supportedImageFormats() def isSvgFile(self): """ Public method to check, if this file is a SVG file. @return flag indicating a SVG file (boolean) """ return self.fileext == '.svg' def isDFile(self): """ Public method to check, if this file is a D file. @return flag indicating a D file (boolean) """ return self.fileext in ['.d', '.di'] or \ (self.fileext == "" and self.sourceLanguage == "D") def lessThan(self, other, column, order): """ Public method to check, if the item is less than the other one. @param other reference to item to compare against (BrowserItem) @param column column number to use for the comparison (integer) @param order sort order (Qt.SortOrder) (for special sorting) @return true, if this item is less than other (boolean) """ if not issubclass(other.__class__, BrowserFileItem): if Preferences.getUI("BrowsersListFoldersFirst"): return order == Qt.DescendingOrder if issubclass(other.__class__, BrowserFileItem): sinit = os.path.basename(self._filename).startswith('__init__.py') oinit = \ os.path.basename(other.fileName()).startswith('__init__.py') if sinit and not oinit: return order == Qt.AscendingOrder if not sinit and oinit: return order == Qt.DescendingOrder return BrowserItem.lessThan(self, other, column, order) class BrowserClassItem(BrowserItem): """ Class implementing the data structure for browser class items. """ def __init__(self, parent, cl, filename): """ Constructor @param parent parent item @param cl Class object to be shown @param filename filename of the file defining this class """ name = cl.name if hasattr(cl, 'super') and cl.super: supers = [] for sup in cl.super: try: sname = sup.name if sup.module != cl.module: sname = "{0}.{1}".format(sup.module, sname) except AttributeError: sname = sup supers.append(sname) name = name + "({0})".format(", ".join(supers)) BrowserItem.__init__(self, parent, name) self.type_ = BrowserItemClass self._name = name self._classObject = cl self._filename = filename import Utilities.ClassBrowsers.ClbrBaseClasses self.isfunction = isinstance( self._classObject, Utilities.ClassBrowsers.ClbrBaseClasses.Function) self.ismodule = isinstance( self._classObject, Utilities.ClassBrowsers.ClbrBaseClasses.Module) if self.isfunction: if cl.isPrivate(): self.icon = UI.PixmapCache.getIcon("method_private.png") elif cl.isProtected(): self.icon = UI.PixmapCache.getIcon("method_protected.png") else: self.icon = UI.PixmapCache.getIcon("method.png") self.itemData[0] = "{0}({1})".format( name, ", ".join(self._classObject.parameters)) if self._classObject.annotation: self.itemData[0] = "{0} {1}".format( self.itemData[0], self._classObject.annotation) # if no defaults are wanted # ....format(name, # ", ".join([e.split('=')[0].strip() \ # for e in self._classObject.parameters])) elif self.ismodule: self.icon = UI.PixmapCache.getIcon("module.png") else: if cl.isPrivate(): self.icon = UI.PixmapCache.getIcon("class_private.png") elif cl.isProtected(): self.icon = UI.PixmapCache.getIcon("class_protected.png") else: self.icon = UI.PixmapCache.getIcon("class.png") if self._classObject and \ (self._classObject.methods or self._classObject.classes or self._classObject.attributes): self._populated = False self._lazyPopulation = True def name(self): """ Public method to return the name of the item. @return name of the item (string) """ return '{0}@@{1}'.format(self._filename, self.lineno()) def fileName(self): """ Public method returning the filename. @return filename (string) """ return self._filename def classObject(self): """ Public method returning the class object. @return reference to the class object """ return self._classObject def lineno(self): """ Public method returning the line number defining this object. @return line number defining the object (integer) """ return self._classObject.lineno def boundaries(self): """ Public method returning the boundaries of the method definition. @return tuple with start end end line number (integer, integer) """ return (self._classObject.lineno, self._classObject.endlineno) def lessThan(self, other, column, order): """ Public method to check, if the item is less than the other one. @param other reference to item to compare against (BrowserItem) @param column column number to use for the comparison (integer) @param order sort order (Qt.SortOrder) (for special sorting) @return true, if this item is less than other (boolean) """ if issubclass(other.__class__, BrowserCodingItem) or \ issubclass(other.__class__, BrowserClassAttributesItem): return order == Qt.DescendingOrder if Preferences.getUI("BrowsersListContentsByOccurrence") and \ column == 0: if order == Qt.AscendingOrder: return self.lineno() < other.lineno() else: return self.lineno() > other.lineno() return BrowserItem.lessThan(self, other, column, order) def isPublic(self): """ Public method returning the public visibility status. @return flag indicating public visibility (boolean) """ return self._classObject.isPublic() class BrowserMethodItem(BrowserItem): """ Class implementing the data structure for browser method items. """ def __init__(self, parent, fn, filename): """ Constructor @param parent parent item @param fn Function object to be shown @param filename filename of the file defining this class (string) """ name = fn.name BrowserItem.__init__(self, parent, name) import Utilities.ClassBrowsers.ClbrBaseClasses self.type_ = BrowserItemMethod self._name = name self._functionObject = fn self._filename = filename if self._functionObject.modifier == \ Utilities.ClassBrowsers.ClbrBaseClasses.Function.Static: self.icon = UI.PixmapCache.getIcon("method_static.png") elif self._functionObject.modifier == \ Utilities.ClassBrowsers.ClbrBaseClasses.Function.Class: self.icon = UI.PixmapCache.getIcon("method_class.png") elif self._functionObject.isPrivate(): self.icon = UI.PixmapCache.getIcon("method_private.png") elif self._functionObject.isProtected(): self.icon = UI.PixmapCache.getIcon("method_protected.png") else: self.icon = UI.PixmapCache.getIcon("method.png") self.itemData[0] = "{0}({1})".format( name, ", ".join(self._functionObject.parameters)) if self._functionObject.annotation: self.itemData[0] = "{0} {1}".format( self.itemData[0], self._functionObject.annotation) # if no defaults are wanted # ....format(name, # ", ".join([e.split('=')[0].strip() # for e in self._functionObject.parameters])) if self._functionObject and \ (self._functionObject.methods or self._functionObject.classes): self._populated = False self._lazyPopulation = True def name(self): """ Public method to return the name of the item. @return name of the item (string) """ return '{0}@@{1}'.format(self._filename, self.lineno()) def fileName(self): """ Public method returning the filename. @return filename (string) """ return self._filename def functionObject(self): """ Public method returning the function object. @return reference to the function object """ return self._functionObject def lineno(self): """ Public method returning the line number defining this object. @return line number defining the object (integer) """ return self._functionObject.lineno def boundaries(self): """ Public method returning the boundaries of the method definition. @return tuple with start end end line number (integer, integer) """ return (self._functionObject.lineno, self._functionObject.endlineno) def lessThan(self, other, column, order): """ Public method to check, if the item is less than the other one. @param other reference to item to compare against (BrowserItem) @param column column number to use for the comparison (integer) @param order sort order (Qt.SortOrder) (for special sorting) @return true, if this item is less than other (boolean) """ if issubclass(other.__class__, BrowserMethodItem): if self._name.startswith('__init__'): return order == Qt.AscendingOrder if other._name.startswith('__init__'): return order == Qt.DescendingOrder elif issubclass(other.__class__, BrowserClassAttributesItem): return order == Qt.DescendingOrder if Preferences.getUI("BrowsersListContentsByOccurrence") and \ column == 0: if order == Qt.AscendingOrder: return self.lineno() < other.lineno() else: return self.lineno() > other.lineno() return BrowserItem.lessThan(self, other, column, order) def isPublic(self): """ Public method returning the public visibility status. @return flag indicating public visibility (boolean) """ return self._functionObject.isPublic() class BrowserClassAttributesItem(BrowserItem): """ Class implementing the data structure for browser class attributes items. """ def __init__(self, parent, attributes, text, isClass=False): """ Constructor @param parent parent item @param attributes list of attributes @param text text to be shown by this item (string) @param isClass flag indicating class attributes (boolean) """ BrowserItem.__init__(self, parent, text) self.type_ = BrowserItemAttributes self._attributes = attributes.copy() self._populated = False self._lazyPopulation = True if isClass: self.icon = UI.PixmapCache.getIcon("attributes_class.png") else: self.icon = UI.PixmapCache.getIcon("attributes.png") self.__isClass = isClass def name(self): """ Public method to return the name of the item. @return name of the item (string) """ return '{0}@@{1}'.format(self.parentItem.name(), self.data(0)) def attributes(self): """ Public method returning the attribute list. @return reference to the list of attributes """ return self._attributes def isClassAttributes(self): """ Public method returning the attributes type. @return flag indicating class attributes (boolean) """ return self.__isClass def lessThan(self, other, column, order): """ Public method to check, if the item is less than the other one. @param other reference to item to compare against (BrowserItem) @param column column number to use for the comparison (integer) @param order sort order (Qt.SortOrder) (for special sorting) @return true, if this item is less than other (boolean) """ if issubclass(other.__class__, BrowserCodingItem): return order == Qt.DescendingOrder elif issubclass(other.__class__, BrowserClassItem) or \ issubclass(other.__class__, BrowserMethodItem): return order == Qt.AscendingOrder return BrowserItem.lessThan(self, other, column, order) class BrowserClassAttributeItem(BrowserItem): """ Class implementing the data structure for browser class attribute items. """ def __init__(self, parent, attribute, isClass=False): """ Constructor @param parent parent item @param attribute reference to the attribute object @param isClass flag indicating a class attribute (boolean) """ BrowserItem.__init__(self, parent, attribute.name) self.type_ = BrowserItemAttribute self._attributeObject = attribute self.__public = attribute.isPublic() if isClass: self.icon = UI.PixmapCache.getIcon("attribute_class.png") elif attribute.isPrivate(): self.icon = UI.PixmapCache.getIcon("attribute_private.png") elif attribute.isProtected(): self.icon = UI.PixmapCache.getIcon("attribute_protected.png") else: self.icon = UI.PixmapCache.getIcon("attribute.png") def isPublic(self): """ Public method returning the public visibility status. @return flag indicating public visibility (boolean) """ return self.__public def attributeObject(self): """ Public method returning the class object. @return reference to the class object """ return self._attributeObject def fileName(self): """ Public method returning the filename. @return filename (string) """ return self._attributeObject.file def lineno(self): """ Public method returning the line number defining this object. @return line number defining the object (integer) """ return self._attributeObject.lineno def linenos(self): """ Public method returning the line numbers this object is assigned to. @return line number the object is assigned to (list of integers) """ return self._attributeObject.linenos[:] def lessThan(self, other, column, order): """ Public method to check, if the item is less than the other one. @param other reference to item to compare against (BrowserItem) @param column column number to use for the comparison (integer) @param order sort order (Qt.SortOrder) (for special sorting) @return true, if this item is less than other (boolean) """ if Preferences.getUI("BrowsersListContentsByOccurrence") and \ column == 0: if order == Qt.AscendingOrder: return self.lineno() < other.lineno() else: return self.lineno() > other.lineno() return BrowserItem.lessThan(self, other, column, order) class BrowserCodingItem(BrowserItem): """ Class implementing the data structure for browser coding items. """ def __init__(self, parent, text): """ Constructor @param parent parent item @param text text to be shown by this item (string) """ BrowserItem.__init__(self, parent, text) self.type_ = BrowserItemCoding self.icon = UI.PixmapCache.getIcon("textencoding.png") def lessThan(self, other, column, order): """ Public method to check, if the item is less than the other one. @param other reference to item to compare against (BrowserItem) @param column column number to use for the comparison (integer) @param order sort order (Qt.SortOrder) (for special sorting) @return true, if this item is less than other (boolean) """ if issubclass(other.__class__, BrowserClassItem) or \ issubclass(other.__class__, BrowserClassAttributesItem): return order == Qt.AscendingOrder return BrowserItem.lessThan(self, other, column, order) eric-6.0.8/eric/UI/EmailDialog.ui0000644000175000017500000001301512060166053015467 0ustar piotrpiotr EmailDialog 0 0 600 547 Send bug report true Qt::Vertical Message &Subject: subject Enter the subject message 0 0 QTextEdit::FixedColumnWidth 70 8 false 0 0 Attachments 0 0 true false Name Type Press to add an attachment &Add... Alt+A Delete the selected entry from the list of attachments &Delete Alt+D Qt::Vertical QSizePolicy::Expanding 20 16 Qt::Horizontal QDialogButtonBox::Close qPixmapFromMimeSource subject message addButton attachments deleteButton eric-6.0.8/eric/UI/Previewers/0000755000175000017500000000000012557365404015130 5ustar piotrpiotreric-6.0.8/eric/UI/Previewers/PreviewerQSS.py0000644000175000017500000000571712451233373020043 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a previewer widget for Qt style sheet files. """ from __future__ import unicode_literals import os from PyQt5.QtCore import qVersion from PyQt5.QtWidgets import QWidget, QMenu, QLabel, QHeaderView, \ QListWidgetItem from .Ui_PreviewerQSS import Ui_PreviewerQSS import Preferences import UI.PixmapCache class PreviewerQSS(QWidget, Ui_PreviewerQSS): """ Class implementing a previewer widget for Qt style sheet files. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(PreviewerQSS, self).__init__(parent) self.setupUi(self) # menu for the tool button self.__toolButtonMenu = QMenu(self) self.__toolButtonMenu.addAction(self.tr("Action 1")) self.__toolButtonMenu.addSeparator() self.__toolButtonMenu.addAction(self.tr("Action 2")) self.toolButton.setMenu(self.__toolButtonMenu) # a MDI window self.__mdi = self.mdiArea.addSubWindow(QLabel(self.tr("MDI"))) self.__mdi.resize(160, 80) # tree and table widgets if qVersion() >= "5.0.0": self.tree.header().setSectionResizeMode( QHeaderView.ResizeToContents) self.table.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) else: self.tree.header().setResizeMode( QHeaderView.ResizeToContents) self.table.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.tree.topLevelItem(0).setExpanded(True) # icon list widget for iconName, labelText in ( ("filePython.png", self.tr("Python")), ("fileRuby.png", self.tr("Ruby")), ("fileJavascript.png", self.tr("JavaScript")), ): self.iconsListWidget.addItem(QListWidgetItem( UI.PixmapCache.getIcon(iconName), labelText)) def processEditor(self, editor=None): """ Public slot to process an editor's text. @param editor editor to be processed (Editor) """ if editor is not None: fn = editor.getFileName() if fn: extension = os.path.normcase(os.path.splitext(fn)[1][1:]) else: extension = "" if extension in \ Preferences.getEditor("PreviewQssFileNameExtensions"): styleSheet = editor.text() if styleSheet: self.scrollAreaWidgetContents.setStyleSheet(styleSheet) else: self.scrollAreaWidgetContents.setStyleSheet("") self.toolButton.menu().setStyleSheet( self.scrollAreaWidgetContents.styleSheet()) eric-6.0.8/eric/UI/Previewers/PreviewerHTML.py0000644000175000017500000003576512451233373020147 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a previewer widget for HTML, Markdown and ReST files. """ from __future__ import unicode_literals import os import threading import re from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QUrl, QSize, QThread from PyQt5.QtWidgets import QWidget from PyQt5.QtWebKitWidgets import QWebPage from E5Gui.E5Application import e5App from .Ui_PreviewerHTML import Ui_PreviewerHTML import Utilities import Preferences class PreviewerHTML(QWidget, Ui_PreviewerHTML): """ Class implementing a previewer widget for HTML, Markdown and ReST files. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(PreviewerHTML, self).__init__(parent) self.setupUi(self) self.jsCheckBox.setChecked( Preferences.getUI("ShowFilePreviewJS")) self.ssiCheckBox.setChecked( Preferences.getUI("ShowFilePreviewSSI")) self.previewView.page().setLinkDelegationPolicy( QWebPage.DelegateAllLinks) self.__scrollBarPositions = {} self.__vScrollBarAtEnd = {} self.__hScrollBarAtEnd = {} self.__processingThread = PreviewProcessingThread() self.__processingThread.htmlReady.connect(self.__setHtml) self.__previewedPath = None self.__previewedEditor = None def shutdown(self): """ Public method to perform shutdown actions. """ self.__processingThread.wait() @pyqtSlot(bool) def on_jsCheckBox_clicked(self, checked): """ Private slot to enable/disable JavaScript. @param checked state of the checkbox (boolean) """ Preferences.setUI("ShowFilePreviewJS", checked) self.__setJavaScriptEnabled(checked) def __setJavaScriptEnabled(self, enable): """ Private method to enable/disable JavaScript. @param enable flag indicating the enable state (boolean) """ self.jsCheckBox.setChecked(enable) settings = self.previewView.settings() settings.setAttribute(settings.JavascriptEnabled, enable) self.processEditor() @pyqtSlot(bool) def on_ssiCheckBox_clicked(self, checked): """ Private slot to enable/disable SSI. @param checked state of the checkbox (boolean) """ Preferences.setUI("ShowFilePreviewSSI", checked) self.processEditor() def processEditor(self, editor=None): """ Public slot to process an editor's text. @param editor editor to be processed (Editor) """ if editor is None: editor = self.__previewedEditor else: self.__previewedEditor = editor if editor is not None: fn = editor.getFileName() if fn: extension = os.path.normcase(os.path.splitext(fn)[1][1:]) else: extension = "" if extension in \ Preferences.getEditor("PreviewHtmlFileNameExtensions") or \ editor.getLanguage() == "HTML": language = "HTML" elif extension in \ Preferences.getEditor("PreviewMarkdownFileNameExtensions"): language = "Markdown" elif extension in \ Preferences.getEditor("PreviewRestFileNameExtensions"): language = "ReST" else: self.__setHtml(fn, self.tr( "

No preview available for this type of file.

")) return if fn: project = e5App().getObject("Project") if project.isProjectFile(fn): rootPath = project.getProjectPath() else: rootPath = os.path.dirname(os.path.abspath(fn)) else: rootPath = "" self.__processingThread.process( fn, language, editor.text(), self.ssiCheckBox.isChecked(), rootPath) def __setHtml(self, filePath, html): """ Private method to set the HTML to the view and restore the scroll bars positions. @param filePath file path of the previewed editor (string) @param html processed HTML text ready to be shown (string) """ self.__saveScrollBarPositions() self.__previewedPath = Utilities.normcasepath( Utilities.fromNativeSeparators(filePath)) self.previewView.page().mainFrame().contentsSizeChanged.connect( self.__restoreScrollBarPositions) self.previewView.setHtml(html, baseUrl=QUrl.fromLocalFile(filePath)) @pyqtSlot(str) def on_previewView_titleChanged(self, title): """ Private slot to handle a change of the title. @param title new title (string) """ if title: self.titleLabel.setText(self.tr("Preview - {0}").format(title)) else: self.titleLabel.setText(self.tr("Preview")) def __saveScrollBarPositions(self): """ Private method to save scroll bar positions for a previewed editor. """ frame = self.previewView.page().mainFrame() if frame.contentsSize() == QSize(0, 0): return # no valid data, nothing to save pos = frame.scrollPosition() self.__scrollBarPositions[self.__previewedPath] = pos self.__hScrollBarAtEnd[self.__previewedPath] = \ frame.scrollBarMaximum(Qt.Horizontal) == pos.x() self.__vScrollBarAtEnd[self.__previewedPath] = \ frame.scrollBarMaximum(Qt.Vertical) == pos.y() def __restoreScrollBarPositions(self): """ Private method to restore scroll bar positions for a previewed editor. """ try: self.previewView.page().mainFrame().contentsSizeChanged.disconnect( self.__restoreScrollBarPositions) except TypeError: # not connected, simply ignore it pass if self.__previewedPath not in self.__scrollBarPositions: return frame = self.previewView.page().mainFrame() frame.setScrollPosition( self.__scrollBarPositions[self.__previewedPath]) if self.__hScrollBarAtEnd[self.__previewedPath]: frame.setScrollBarValue( Qt.Horizontal, frame.scrollBarMaximum(Qt.Horizontal)) if self.__vScrollBarAtEnd[self.__previewedPath]: frame.setScrollBarValue( Qt.Vertical, frame.scrollBarMaximum(Qt.Vertical)) @pyqtSlot(QUrl) def on_previewView_linkClicked(self, url): """ Private slot handling the clicking of a link. @param url url of the clicked link (QUrl) """ e5App().getObject("UserInterface").launchHelpViewer(url.toString()) class PreviewProcessingThread(QThread): """ Class implementing a thread to process some text into HTML usable by the previewer view. @signal htmlReady(str,str) emitted with the file name and processed HTML to signal the availability of the processed HTML """ htmlReady = pyqtSignal(str, str) def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(PreviewProcessingThread, self).__init__() self.__lock = threading.Lock() def process(self, filePath, language, text, ssiEnabled, rootPath): """ Public method to convert the given text to HTML. @param filePath file path of the text (string) @param language language of the text (string) @param text text to be processed (string) @param ssiEnabled flag indicating to do some (limited) SSI processing (boolean) @param rootPath root path to be used for SSI processing (str) """ with self.__lock: self.__filePath = filePath self.__language = language self.__text = text self.__ssiEnabled = ssiEnabled self.__rootPath = rootPath self.__haveData = True if not self.isRunning(): self.start(QThread.LowPriority) def run(self): """ Public thread method to convert the stored data. """ while True: # exits with break with self.__lock: filePath = self.__filePath language = self.__language text = self.__text ssiEnabled = self.__ssiEnabled rootPath = self.__rootPath self.__haveData = False html = self.__getHtml(language, text, ssiEnabled, filePath, rootPath) with self.__lock: if not self.__haveData: self.htmlReady.emit(filePath, html) break # else - next iteration def __getHtml(self, language, text, ssiEnabled, filePath, rootPath): """ Private method to process the given text depending upon the given language. @param language language of the text (string) @param text to be processed (string) @param ssiEnabled flag indicating to do some (limited) SSI processing (boolean) @param filePath file path of the text (string) @param rootPath root path to be used for SSI processing (str) @return processed HTML text (string) """ if language == "HTML": if ssiEnabled: return self.__processSSI(text, filePath, rootPath) else: return text elif language == "Markdown": return self.__convertMarkdown(text) elif language == "ReST": return self.__convertReST(text) else: return self.tr( "

No preview available for this type of file.

") def __processSSI(self, txt, filename, root): """ Private method to process the given text for SSI statements. Note: Only a limited subset of SSI statements are supported. @param txt text to be processed (string) @param filename name of the file associated with the given text (string) @param root directory of the document root (string) @return processed HTML (string) """ if not filename: return txt # SSI include incRe = re.compile( r"""""", re.IGNORECASE) baseDir = os.path.dirname(os.path.abspath(filename)) docRoot = root if root != "" else baseDir while True: incMatch = incRe.search(txt) if incMatch is None: break if incMatch.group(1) == "virtual": incFile = Utilities.normjoinpath(docRoot, incMatch.group(2)) elif incMatch.group(1) == "file": incFile = Utilities.normjoinpath(baseDir, incMatch.group(2)) else: incFile = "" if os.path.exists(incFile): try: f = open(incFile, "r") incTxt = f.read() f.close() except (IOError, OSError): # remove SSI include incTxt = "" else: # remove SSI include incTxt = "" txt = txt[:incMatch.start(0)] + incTxt + txt[incMatch.end(0):] return txt def __convertReST(self, text): """ Private method to convert ReST text into HTML. @param text text to be processed (string) @return processed HTML (string) """ try: import docutils.core # __IGNORE_EXCEPTION__ __IGNORE_WARNING__ except ImportError: return self.tr( """
""") return docutils.core.publish_string(text, writer_name='html')\ .decode("utf-8") def __convertMarkdown(self, text): """ Private method to convert Markdown text into HTML. @param text text to be processed (string) @return processed HTML (string) """ try: import markdown # __IGNORE_EXCEPTION__ __IGNORE_WARNING__ except ImportError: return self.tr( """

Markdown preview requires the python-markdown """ """package.
Install it with your package manager or see """ """""" """installation instructions.

""") try: import mdx_mathjax # __IGNORE_EXCEPTION__ __IGNORE_WARNING__ except ImportError: #mathjax doesn't require import statement if installed as extension pass extensions = ['fenced_code', 'nl2br', 'extra'] # version 2.0 supports only extension names, not instances if markdown.version_info[0] > 2 or \ (markdown.version_info[0] == 2 and markdown.version_info[1] > 0): class _StrikeThroughExtension(markdown.Extension): """ Class is placed here, because it depends on imported markdown, and markdown import is lazy. (see http://achinghead.com/ python-markdown-adding-insert-delete.html this page for details) """ DEL_RE = r'(~~)(.*?)~~' def extendMarkdown(self, md, md_globals): # Create the del pattern del_tag = markdown.inlinepatterns.SimpleTagPattern( self.DEL_RE, 'del') # Insert del pattern into markdown parser md.inlinePatterns.add('del', del_tag, '>not_strong') extensions.append(_StrikeThroughExtension()) try: return markdown.markdown(text, extensions + ['mathjax']) except (ImportError, ValueError): # markdown raises ValueError or ImportError, depends on version # It is not clear, how to distinguish missing mathjax from other # errors. So keep going without mathjax. return markdown.markdown(text, extensions) eric-6.0.8/eric/UI/Previewers/PreviewerQSS.ui0000644000175000017500000007507712316567527020051 0ustar piotrpiotr PreviewerQSS 0 0 500 600 12 75 true Preview Style Qt::AlignCenter Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOn true 0 0 463 538 0 true Tab 1 RadioButton CheckBox true 0 0 PushButton 0 0 ToolButton QToolButton::InstantPopup 10 1234567890 Label with <a href="http://google.com">link</a> 20 10 0 0 1 2 3 0 0 true 1 2 3 Line edit Password QLineEdit::Password CommandLinkButton Qt::Horizontal 40 20 Qt::Horizontal Qt::Vertical 30 Qt::Vertical QSlider::TicksAbove 0 0 30 Qt::Horizontal QSlider::TicksAbove true Qt::Horizontal 0 20 Qt::Vertical 20 0 Tab 2 true QAbstractItemView::ExtendedSelection I1 :/images/battery.png:/images/battery.png I2 :/images/image-sunset.png:/images/image-sunset.png I3 :/images/user.png:/images/user.png I4 I5 I6 I7 I8 I9 I10 I11 I12 I14 I15 I16 I17 I18 I19 I20 true QAbstractItemView::ExtendedSelection QListView::IconMode true true true true true R1 R2 R3 C1 C2 1,1 1,2 2,1 2,2 3,1 ItemIsSelectable|ItemIsDragEnabled|ItemIsUserCheckable 2,3 ItemIsSelectable|ItemIsDragEnabled|ItemIsUserCheckable true QAbstractItemView::ExtendedSelection true true C1 C2 R1 C1 Checked X1 Checked C2 PartiallyChecked X2 PartiallyChecked C3 X3 ItemIsSelectable|ItemIsDragEnabled|ItemIsUserCheckable R2 ItemIsSelectable|ItemIsDragEnabled|ItemIsUserCheckable Tab 3 true <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Text </span><span style=" font-size:10pt; font-weight:600;">browser</span><span style=" font-size:10pt;"> </span><span style=" font-size:10pt; font-style:italic;">with</span><span style=" font-size:10pt;"> </span><span style=" font-size:10pt; text-decoration: underline;">some</span><span style=" font-size:10pt;"> </span><span style=" font-size:10pt; font-weight:600; font-style:italic;">text </span><span style=" font-size:10pt;">and </span><a href="http://google.com"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">links</span></a></p></body></html> false <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Text edit</span></p></body></html> 1 0 GroupBox true 0 0 399 275 1 0 QFrame::StyledPanel QFrame::Raised Frame Qt::Vertical 20 46 0 0 0 69 203 Toolbox1 0 0 100 30 Toolbox2 1 1 Dock widget 0 2 eric-6.0.8/eric/UI/Previewers/__init__.py0000644000175000017500000000023612451233374017233 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Package containing the various previewer modules. """ eric-6.0.8/eric/UI/Previewers/PreviewerHTML.ui0000644000175000017500000000353612316317575020132 0ustar piotrpiotr PreviewerHTML 0 0 400 400 true Qt::NoTextInteraction 0 0 Qt::NoContextMenu about:blank Select to enable JavaScript for HTML previews Enable JavaScript Select to enable support for Server Side Includes Enable Server Side Includes QWebView QWidget
QtWebKitWidgets/QWebView
eric-6.0.8/eric/UI/PixmapCache.py0000644000175000017500000000721412451233374015526 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a pixmap cache for icons. """ from __future__ import unicode_literals import os from PyQt5.QtCore import Qt, QSize from PyQt5.QtGui import QPixmap, QIcon, QPainter class PixmapCache(object): """ Class implementing a pixmap cache for icons. """ def __init__(self): """ Constructor """ self.pixmapCache = {} self.searchPath = [] def getPixmap(self, key): """ Public method to retrieve a pixmap. @param key name of the wanted pixmap (string) @return the requested pixmap (QPixmap) """ if key: try: return self.pixmapCache[key] except KeyError: if not os.path.isabs(key): for path in self.searchPath: pm = QPixmap(path + "/" + key) if not pm.isNull(): break else: pm = QPixmap() else: pm = QPixmap(key) self.pixmapCache[key] = pm return self.pixmapCache[key] return QPixmap() def addSearchPath(self, path): """ Public method to add a path to the search path. @param path path to add (string) """ if path not in self.searchPath: self.searchPath.append(path) pixCache = PixmapCache() def getPixmap(key, cache=pixCache): """ Module function to retrieve a pixmap. @param key name of the wanted pixmap (string) @param cache reference to the pixmap cache object (PixmapCache) @return the requested pixmap (QPixmap) """ return cache.getPixmap(key) def getIcon(key, cache=pixCache): """ Module function to retrieve an icon. @param key name of the wanted icon (string) @param cache reference to the pixmap cache object (PixmapCache) @return the requested icon (QIcon) """ return QIcon(cache.getPixmap(key)) def getSymlinkIcon(key, cache=pixCache): """ Module function to retrieve a symbolic link icon. @param key name of the wanted icon (string) @param cache reference to the pixmap cache object (PixmapCache) @return the requested icon (QIcon) """ pix1 = QPixmap(cache.getPixmap(key)) pix2 = cache.getPixmap("symlink.png") painter = QPainter(pix1) painter.drawPixmap(0, 10, pix2) painter.end() return QIcon(pix1) def getCombinedIcon(keys, cache=pixCache): """ Module function to retrieve a symbolic link icon. @param keys list of names of icons (string) @param cache reference to the pixmap cache object (PixmapCache) @return the requested icon (QIcon) """ height = width = 0 pixmaps = [] for key in keys: pix = cache.getPixmap(key) if not pix.isNull(): height = max(height, pix.height()) width = max(width, pix.width()) pixmaps.append(pix) if pixmaps: pix = QPixmap(len(pixmaps) * width, height) pix.fill(Qt.transparent) painter = QPainter(pix) x = 0 for pixmap in pixmaps: painter.drawPixmap(x, 0, pixmap.scaled(QSize(width, height))) x += width painter.end() icon = QIcon(pix) else: icon = QIcon() return icon def addSearchPath(path, cache=pixCache): """ Module function to add a path to the search path. @param path path to add (string) @param cache reference to the pixmap cache object (PixmapCache) """ cache.addSearchPath(path) eric-6.0.8/eric/UI/SplashScreen.py0000644000175000017500000000432212451233374015733 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing a splashscreen for eric6. """ from __future__ import unicode_literals import os.path import logging from PyQt5.QtCore import Qt from PyQt5.QtGui import QPixmap, QColor from PyQt5.QtWidgets import QApplication, QSplashScreen from eric6config import getConfig class SplashScreen(QSplashScreen): """ Class implementing a splashscreen for eric6. """ def __init__(self): """ Constructor """ ericPic = QPixmap( os.path.join(getConfig('ericPixDir'), 'ericSplash.png')) self.labelAlignment = Qt.Alignment( Qt.AlignBottom | Qt.AlignRight | Qt.AlignAbsolute) super(SplashScreen, self).__init__(ericPic) self.show() QApplication.flush() def showMessage(self, msg): """ Public method to show a message in the bottom part of the splashscreen. @param msg message to be shown (string) """ logging.debug(msg) super(SplashScreen, self).showMessage( msg, self.labelAlignment, QColor(Qt.white)) QApplication.processEvents() def clearMessage(self): """ Public method to clear the message shown. """ super(SplashScreen, self).clearMessage() QApplication.processEvents() class NoneSplashScreen(object): """ Class implementing a "None" splashscreen for eric6. This class implements the same interface as the real splashscreen, but simply does nothing. """ def __init__(self): """ Constructor """ pass def showMessage(self, msg): """ Public method to show a message in the bottom part of the splashscreen. @param msg message to be shown (string) """ logging.debug(msg) def clearMessage(self): """ Public method to clear the message shown. """ pass def finish(self, widget): """ Public method to finish the splash screen. @param widget widget to wait for (QWidget) """ pass eric-6.0.8/eric/UI/LogView.py0000644000175000017500000002024312451233374014715 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the log viewer widget and the log widget. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtGui import QBrush, QTextCursor, QTextDocument from PyQt5.QtWidgets import QTextEdit, QApplication, QMenu, QWidget, \ QHBoxLayout from E5Gui.E5Application import e5App import UI.PixmapCache import Preferences class LogViewer(QWidget): """ Class implementing the containing widget for the log viewer. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(LogViewer, self).__init__(parent) self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__logViewer = LogViewerEdit(self) from .SearchWidget import SearchWidget self.__searchWidget = SearchWidget(self.__logViewer, self) self.__searchWidget.hide() self.__layout = QHBoxLayout(self) self.__layout.setContentsMargins(1, 1, 1, 1) self.__layout.addWidget(self.__logViewer) self.__layout.addWidget(self.__searchWidget) self.__searchWidget.searchNext.connect(self.__logViewer.searchNext) self.__searchWidget.searchPrevious.connect(self.__logViewer.searchPrev) self.__logViewer.searchStringFound.connect( self.__searchWidget.searchStringFound) def appendToStdout(self, txt): """ Public slot to appand text to the "stdout" tab. @param txt text to be appended (string) """ self.__logViewer.appendToStdout(txt) def appendToStderr(self, txt): """ Public slot to appand text to the "stderr" tab. @param txt text to be appended (string) """ self.__logViewer.appendToStderr(txt) def preferencesChanged(self): """ Public slot to handle a change of the preferences. """ self.__logViewer.preferencesChanged() def showFind(self, txt=""): """ Public method to display the search widget. @param txt text to be shown in the combo (string) """ self.__searchWidget.showFind(txt) class LogViewerEdit(QTextEdit): """ Class providing a specialized text edit for displaying logging information. @signal searchStringFound(found) emitted to indicate the search result (boolean) """ searchStringFound = pyqtSignal(bool) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(LogViewerEdit, self).__init__(parent) self.setAcceptRichText(False) self.setLineWrapMode(QTextEdit.NoWrap) self.setReadOnly(True) self.__mainWindow = parent self.__lastSearch = () # create the context menu self.__menu = QMenu(self) self.__menu.addAction(self.tr('Clear'), self.clear) self.__menu.addAction(self.tr('Copy'), self.copy) self.__menu.addSeparator() self.__menu.addAction(self.tr('Find'), self.__find) self.__menu.addSeparator() self.__menu.addAction(self.tr('Select All'), self.selectAll) self.__menu.addSeparator() self.__menu.addAction(self.tr("Configure..."), self.__configure) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__handleShowContextMenu) self.cNormalFormat = self.currentCharFormat() self.cErrorFormat = self.currentCharFormat() self.cErrorFormat.setForeground( QBrush(Preferences.getUI("LogStdErrColour"))) def __handleShowContextMenu(self, coord): """ Private slot to show the context menu. @param coord the position of the mouse pointer (QPoint) """ coord = self.mapToGlobal(coord) self.__menu.popup(coord) def __appendText(self, txt, error=False): """ Private method to append text to the end. @param txt text to insert (string) @param error flag indicating to insert error text (boolean) """ tc = self.textCursor() tc.movePosition(QTextCursor.End) self.setTextCursor(tc) if error: self.setCurrentCharFormat(self.cErrorFormat) else: self.setCurrentCharFormat(self.cNormalFormat) self.insertPlainText(txt) self.ensureCursorVisible() def appendToStdout(self, txt): """ Public slot to appand text to the "stdout" tab. @param txt text to be appended (string) """ self.__appendText(txt, error=False) QApplication.processEvents() def appendToStderr(self, txt): """ Public slot to appand text to the "stderr" tab. @param txt text to be appended (string) """ self.__appendText(txt, error=True) QApplication.processEvents() def preferencesChanged(self): """ Public slot to handle a change of the preferences. """ self.cErrorFormat.setForeground( QBrush(Preferences.getUI("LogStdErrColour"))) def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences("interfacePage") def __find(self): """ Private slot to show the find widget. """ txt = self.textCursor().selectedText() self.__mainWindow.showFind(txt) def searchNext(self, txt, caseSensitive, wholeWord): """ Public method to search the next occurrence of the given text. @param txt text to search for (string) @param caseSensitive flag indicating case sensitivity (boolean) @param wholeWord flag indicating a search for the whole word (boolean) """ self.__lastSearch = (txt, caseSensitive, wholeWord) flags = QTextDocument.FindFlags() if caseSensitive: flags |= QTextDocument.FindCaseSensitively if wholeWord: flags |= QTextDocument.FindWholeWords ok = self.find(txt, flags) self.searchStringFound.emit(ok) def searchPrev(self, txt, caseSensitive, wholeWord): """ Public method to search the previous occurrence of the given text. @param txt text to search for (string) @param caseSensitive flag indicating case sensitivity (boolean) @param wholeWord flag indicating a search for the whole word (boolean) """ self.__lastSearch = (txt, caseSensitive, wholeWord) flags = QTextDocument.FindFlags(QTextDocument.FindBackward) if caseSensitive: flags |= QTextDocument.FindCaseSensitively if wholeWord: flags |= QTextDocument.FindWholeWords ok = self.find(txt, flags) self.searchStringFound.emit(ok) def keyPressEvent(self, evt): """ Protected method handling key press events. @param evt key press event (QKeyEvent) """ if evt.modifiers() == Qt.ControlModifier: if evt.key() == Qt.Key_F: self.__find() evt.accept() return elif evt.key() == Qt.Key_C: self.copy() evt.accept() return elif evt.key() == Qt.Key_A: self.selectAll() evt.accept() return elif evt.modifiers() == Qt.NoModifier: if evt.key() == Qt.Key_F3 and self.__lastSearch: self.searchNext(*self.__lastSearch) evt.accept() return elif evt.modifiers() == Qt.ShiftModifier and self.__lastSearch: if evt.key() == Qt.Key_F3 and self.__lastSearch: self.searchPrev(*self.__lastSearch) evt.accept() return eric-6.0.8/eric/UI/__init__.py0000644000175000017500000000051112451233374015074 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Package implementing the main user interface and general purpose dialogs. This package contains the main user interface and some general purpose dialogs as well as dialogs not fitting the other more specific categories. """ eric-6.0.8/eric/UI/FindFileNameDialog.py0000644000175000017500000002215112451233374016742 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog to search for files. """ from __future__ import unicode_literals import os import sys from PyQt5.QtCore import pyqtSignal, pyqtSlot from PyQt5.QtWidgets import QWidget, QHeaderView, QApplication, \ QDialogButtonBox, QTreeWidgetItem from E5Gui.E5Completers import E5DirCompleter from E5Gui import E5FileDialog from .Ui_FindFileNameDialog import Ui_FindFileNameDialog from Utilities import direntries import Utilities import UI.PixmapCache class FindFileNameDialog(QWidget, Ui_FindFileNameDialog): """ Class implementing a dialog to search for files. The occurrences found are displayed in a QTreeWidget showing the filename and the pathname. The file will be opened upon a double click onto the respective entry of the list. @signal sourceFile(str) emitted to open a file in the editor @signal designerFile(str) emitted to open a Qt-Designer file """ sourceFile = pyqtSignal(str) designerFile = pyqtSignal(str) def __init__(self, project, parent=None): """ Constructor @param project reference to the project object @param parent parent widget of this dialog (QWidget) """ super(FindFileNameDialog, self).__init__(parent) self.setupUi(self) self.searchDirButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.searchDirCompleter = E5DirCompleter(self.searchDirEdit) self.fileList.headerItem().setText(self.fileList.columnCount(), "") self.stopButton = self.buttonBox.addButton( self.tr("Stop"), QDialogButtonBox.ActionRole) self.stopButton.setToolTip(self.tr("Press to stop the search")) self.stopButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Open).setToolTip( self.tr("Opens the selected file")) self.buttonBox.button(QDialogButtonBox.Open).setEnabled(False) self.project = project self.extsepLabel.setText(os.extsep) self.shouldStop = False def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.stopButton: self.shouldStop = True elif button == self.buttonBox.button(QDialogButtonBox.Open): self.__openFile() def __openFile(self, itm=None): """ Private slot to open a file. It emits the signal sourceFile or designerFile depending on the file extension. @param itm item to be opened (QTreeWidgetItem) """ if itm is None: itm = self.fileList.currentItem() if itm is not None: fileName = itm.text(0) filePath = itm.text(1) if fileName.endswith('.ui'): self.designerFile.emit(os.path.join(filePath, fileName)) else: self.sourceFile.emit(os.path.join(filePath, fileName)) def __searchFile(self): """ Private slot to handle the search. """ fileName = self.fileNameEdit.text() if not fileName: self.fileList.clear() return fileExt = self.fileExtEdit.text() if not fileExt and Utilities.isWindowsPlatform(): self.fileList.clear() return patternFormat = fileExt and "{0}{1}{2}" or "{0}*{1}{2}" fileNamePattern = patternFormat.format( fileName, os.extsep, fileExt and fileExt or '*') searchPaths = [] if self.searchDirCheckBox.isChecked() and \ self.searchDirEdit.text() != "": searchPaths.append(self.searchDirEdit.text()) if self.projectCheckBox.isChecked(): searchPaths.append(self.project.ppath) if self.syspathCheckBox.isChecked(): searchPaths.extend(sys.path) found = False self.fileList.clear() locations = {} self.shouldStop = False self.stopButton.setEnabled(True) QApplication.processEvents() for path in searchPaths: if os.path.isdir(path): files = direntries(path, True, fileNamePattern, False, self.checkStop) if files: found = True for file in files: fp, fn = os.path.split(file) if fn in locations: if fp in locations[fn]: continue else: locations[fn].append(fp) else: locations[fn] = [fp] QTreeWidgetItem(self.fileList, [fn, fp]) QApplication.processEvents() del locations self.stopButton.setEnabled(False) self.fileList.header().resizeSections(QHeaderView.ResizeToContents) self.fileList.header().setStretchLastSection(True) if found: self.fileList.setCurrentItem(self.fileList.topLevelItem(0)) def checkStop(self): """ Public method to check, if the search should be stopped. @return flag indicating the search should be stopped (boolean) """ QApplication.processEvents() return self.shouldStop def on_fileNameEdit_textChanged(self, text): """ Private slot to handle the textChanged signal of the file name edit. @param text (ignored) """ self.__searchFile() def on_fileExtEdit_textChanged(self, text): """ Private slot to handle the textChanged signal of the file extension edit. @param text (ignored) """ self.__searchFile() def on_searchDirEdit_textChanged(self, text): """ Private slot to handle the textChanged signal of the search directory edit. @param text text of the search dir edit (string) """ self.searchDirCheckBox.setEnabled(text != "") if self.searchDirCheckBox.isChecked(): self.__searchFile() @pyqtSlot() def on_searchDirButton_clicked(self): """ Private slot to handle the clicked signal of the search directory selection button. """ searchDir = E5FileDialog.getExistingDirectory( None, self.tr("Select search directory"), self.searchDirEdit.text(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if searchDir: self.searchDirEdit.setText(Utilities.toNativeSeparators(searchDir)) def on_searchDirCheckBox_toggled(self, checked): """ Private slot to handle the toggled signal of the search directory checkbox. @param checked flag indicating the state of the checkbox (boolean) """ if self.searchDirEdit.text(): self.__searchFile() def on_projectCheckBox_toggled(self, checked): """ Private slot to handle the toggled signal of the project checkbox. @param checked flag indicating the state of the checkbox (boolean) """ self.__searchFile() def on_syspathCheckBox_toggled(self, checked): """ Private slot to handle the toggled signal of the sys.path checkbox. @param checked flag indicating the state of the checkbox (boolean) """ self.__searchFile() def on_fileList_itemActivated(self, itm, column): """ Private slot to handle the double click on a file item. It emits the signal sourceFile or designerFile depending on the file extension. @param itm the double clicked listview item (QTreeWidgetItem) @param column column that was double clicked (integer) (ignored) """ self.__openFile(itm) @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_fileList_currentItemChanged(self, current, previous): """ Private slot handling a change of the current item. @param current current item (QTreeWidgetItem) @param previous prevoius current item (QTreeWidgetItem) """ self.buttonBox.button(QDialogButtonBox.Open).setEnabled( current is not None) def show(self): """ Public method to enable/disable the project checkbox. """ if self.project and self.project.isOpen(): self.projectCheckBox.setEnabled(True) self.projectCheckBox.setChecked(True) else: self.projectCheckBox.setEnabled(False) self.projectCheckBox.setChecked(False) self.fileNameEdit.selectAll() self.fileNameEdit.setFocus() super(FindFileNameDialog, self).show() eric-6.0.8/eric/UI/DiffDialog.ui0000644000175000017500000001113712263310204015305 0ustar piotrpiotr DiffDialog 0 0 750 600 File Differences File &1: file1Edit Enter the name of the first file Press to select the file via a file selection dialog File &2: file1Edit Enter the name of the second file Press to select the file via a file selection dialog Select to generate a unified diff &Unified Diff Alt+U true Select to generate a context diff Co&ntext Diff Alt+N Qt::Horizontal QSizePolicy::Expanding 40 20 QTextEdit::NoWrap true 8 false Qt::Horizontal QDialogButtonBox::Close file1Edit file1Button file2Edit file2Button unifiedRadioButton contextRadioButton buttonBox rejected() DiffDialog close() 80 578 82 594 eric-6.0.8/eric/UI/FindFileNameDialog.ui0000644000175000017500000001146012263310403016716 0ustar piotrpiotr FindFileNameDialog 0 0 599 478 Find File Enter filename (? matches any single character, * matches everything) 9 0 Enter file name to search for . 1 0 Enter file extension to search for false Enabled to include the entered directory into the search Search Path: Enter the directory, the file should be searched in Press to select the directory, the file should be searched in Select to search in the project path Search in &project Alt+P Select to search in sys.path Search in &sys.path Alt+S false true Filename Path Qt::Horizontal QDialogButtonBox::Close|QDialogButtonBox::Open fileNameEdit fileExtEdit searchDirEdit searchDirButton searchDirCheckBox projectCheckBox syspathCheckBox fileList buttonBox rejected() FindFileNameDialog close() 40 458 41 477 eric-6.0.8/eric/UI/UserInterface.py0000644000175000017500000075452512510742760016121 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the main user interface. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os import sys import logging from PyQt5.QtCore import pyqtSlot, QTimer, QFile, QFileInfo, pyqtSignal, \ PYQT_VERSION_STR, QDate, QIODevice, qVersion, QProcess, QSize, QUrl, \ QObject, Qt from PyQt5.QtGui import QKeySequence, QDesktopServices from PyQt5.QtWidgets import QSizePolicy, QWidget, QWhatsThis, QToolBar, \ QDialog, QSplitter, QApplication, QMenu, QVBoxLayout, QDockWidget, \ QAction, QLabel from PyQt5.Qsci import QSCINTILLA_VERSION_STR from PyQt5.QtNetwork import QNetworkProxyFactory, QNetworkAccessManager, \ QNetworkRequest, QNetworkReply from .Info import Version, BugAddress, Program, FeatureAddress from . import Config from E5Gui.E5SingleApplication import E5SingleApplicationServer from E5Gui.E5Action import E5Action, createActionGroup from E5Gui.E5ToolBarManager import E5ToolBarManager from E5Gui import E5MessageBox, E5FileDialog, E5ErrorMessage from E5Gui.E5Application import e5App from E5Gui.E5MainWindow import E5MainWindow from E5Gui.E5ZoomWidget import E5ZoomWidget from E5Gui.E5ProgressDialog import E5ProgressDialog from E5Gui.E5ClickableLabel import E5ClickableLabel import Preferences import Utilities import UI.PixmapCache from E5Network.E5NetworkProxyFactory import E5NetworkProxyFactory, \ proxyAuthenticationRequired try: from E5Network.E5SslErrorHandler import E5SslErrorHandler SSL_AVAILABLE = True except ImportError: SSL_AVAILABLE = False from eric6config import getConfig class Redirector(QObject): """ Helper class used to redirect stdout and stderr to the log window. @signal appendStderr(str) emitted to write data to stderr logger @signal appendStdout(str) emitted to write data to stdout logger """ appendStderr = pyqtSignal(str) appendStdout = pyqtSignal(str) def __init__(self, stderr): """ Constructor @param stderr flag indicating stderr is being redirected """ super(Redirector, self).__init__() self.stderr = stderr self.buffer = '' def __nWrite(self, n): """ Private method used to write data. @param n max number of bytes to write """ if n: line = self.buffer[:n] if self.stderr: self.appendStderr.emit(line) else: self.appendStdout.emit(line) self.buffer = self.buffer[n:] def __bufferedWrite(self): """ Private method returning number of characters to write. @return number of characters buffered or length of buffered line (integer) """ return self.buffer.rfind('\n') + 1 def flush(self): """ Public method used to flush the buffered data. """ self.__nWrite(len(self.buffer)) def write(self, s): """ Public method used to write data. @param s data to be written (it must support the str-method) """ self.buffer += str(s) self.__nWrite(self.__bufferedWrite()) class UserInterface(E5MainWindow): """ Class implementing the main user interface. @signal appendStderr(str) emitted to write data to stderr logger @signal appendStdout(str) emitted to write data to stdout logger @signal preferencesChanged() emitted after the preferences were changed @signal reloadAPIs() emitted to reload the api information @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The name of the menu and a reference to the menu are given. @signal masterPasswordChanged(str, str) emitted after the master password has been changed with the old and the new password """ appendStderr = pyqtSignal(str) appendStdout = pyqtSignal(str) preferencesChanged = pyqtSignal() reloadAPIs = pyqtSignal() showMenu = pyqtSignal(str, QMenu) masterPasswordChanged = pyqtSignal(str, str) maxFilePathLen = 100 maxMenuFilePathLen = 75 LeftSide = 1 BottomSide = 2 RightSide = 3 ErrorLogFileName = "eric6_error.log" def __init__(self, app, locale, splash, plugin, noOpenAtStartup, restartArguments): """ Constructor @param app reference to the application object (E5Application) @param locale locale to be used by the UI (string) @param splash reference to the splashscreen (UI.SplashScreen.SplashScreen) @param plugin filename of a plugin to be loaded (used for plugin development) @param noOpenAtStartup flag indicating that the open at startup option should not be executed (boolean) @param restartArguments list of command line parameters to be used for a restart (list of strings) """ super(UserInterface, self).__init__() self.__restartArgs = restartArguments[:] self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.maxEditorPathLen = Preferences.getUI("CaptionFilenameLength") self.locale = locale self.__noOpenAtStartup = noOpenAtStartup self.layout, self.embeddedShell, self.embeddedFileBrowser = \ Preferences.getUILayout() self.passiveMode = Preferences.getDebugger("PassiveDbgEnabled") g = Preferences.getGeometry("MainGeometry") if g.isEmpty(): s = QSize(1280, 1024) self.resize(s) else: self.restoreGeometry(g) self.__startup = True self.__proxyFactory = E5NetworkProxyFactory() QNetworkProxyFactory.setApplicationProxyFactory(self.__proxyFactory) self.capProject = "" self.capEditor = "" self.captionShowsFilename = Preferences.getUI("CaptionShowsFilename") QApplication.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__setWindowCaption() # load the view profiles self.profiles = Preferences.getUI("ViewProfiles2") # Generate the debug server object from Debugger.DebugServer import DebugServer debugServer = DebugServer() # Create the background service object from Utilities.BackgroundService import BackgroundService self.backgroundService = BackgroundService() # Generate an empty project object and multi project object from Project.Project import Project self.project = Project(self) from MultiProject.MultiProject import MultiProject self.multiProject = MultiProject(self.project, self) splash.showMessage(self.tr("Initializing Plugin Manager...")) # Initialize the Plugin Manager (Plugins are initialized later from PluginManager.PluginManager import PluginManager self.pluginManager = PluginManager(self, develPlugin=plugin) splash.showMessage(self.tr("Generating Main User Interface...")) # Create the main window now so that we can connect QActions to it. logging.debug("Creating Layout...") self.__createLayout(debugServer) self.__currentRightWidget = None self.__currentBottomWidget = None # Generate the debugger part of the ui logging.debug("Creating Debugger UI...") from Debugger.DebugUI import DebugUI self.debuggerUI = DebugUI(self, self.viewmanager, debugServer, self.debugViewer, self.project) self.debugViewer.setDebugger(self.debuggerUI) self.shell.setDebuggerUI(self.debuggerUI) # Generate the redirection helpers self.stdout = Redirector(False) self.stderr = Redirector(True) # set a few dialog members for dialogs created on demand self.programsDialog = None self.shortcutsDialog = None self.unittestDialog = None self.findFileNameDialog = None self.diffDlg = None self.compareDlg = None self.findFilesDialog = None self.replaceFilesDialog = None self.__notification = None # now setup the connections splash.showMessage(self.tr("Setting up connections...")) self.browser.sourceFile[str].connect( self.viewmanager.openSourceFile) self.browser.sourceFile[str, int].connect( self.viewmanager.openSourceFile) self.browser.sourceFile[str, int, str].connect( self.viewmanager.openSourceFile) self.browser.designerFile.connect(self.__designer) self.browser.linguistFile.connect(self.__linguist4) self.browser.projectFile.connect(self.project.openProject) self.browser.multiProjectFile.connect( self.multiProject.openMultiProject) self.browser.pixmapEditFile.connect(self.__editPixmap) self.browser.pixmapFile.connect(self.__showPixmap) self.browser.svgFile.connect(self.__showSvg) self.browser.unittestOpen.connect(self.__unittestScript) self.browser.trpreview.connect(self.__TRPreviewer) self.debugViewer.exceptionLogger.sourceFile.connect( self.viewmanager.openSourceFile) self.debugViewer.sourceFile.connect(self.viewmanager.showDebugSource) self.taskViewer.displayFile.connect(self.viewmanager.openSourceFile) self.projectBrowser.psBrowser.sourceFile[str].connect( self.viewmanager.openSourceFile) self.projectBrowser.psBrowser.sourceFile[str, int].connect( self.viewmanager.openSourceFile) self.projectBrowser.psBrowser.sourceFile[str, int, str].connect( self.viewmanager.openSourceFile) self.projectBrowser.psBrowser.closeSourceWindow.connect( self.viewmanager.closeWindow) self.projectBrowser.psBrowser.unittestOpen.connect( self.__unittestScript) self.projectBrowser.pfBrowser.designerFile.connect(self.__designer) self.projectBrowser.pfBrowser.sourceFile.connect( self.viewmanager.openSourceFile) self.projectBrowser.pfBrowser.uipreview.connect(self.__UIPreviewer) self.projectBrowser.pfBrowser.trpreview.connect(self.__TRPreviewer) self.projectBrowser.pfBrowser.closeSourceWindow.connect( self.viewmanager.closeWindow) self.projectBrowser.pfBrowser.appendStderr.connect(self.appendToStderr) self.projectBrowser.prBrowser.sourceFile.connect( self.viewmanager.openSourceFile) self.projectBrowser.prBrowser.closeSourceWindow.connect( self.viewmanager.closeWindow) self.projectBrowser.prBrowser.appendStderr.connect(self.appendToStderr) self.projectBrowser.ptBrowser.linguistFile.connect(self.__linguist4) self.projectBrowser.ptBrowser.sourceFile.connect( self.viewmanager.openSourceFile) self.projectBrowser.ptBrowser.trpreview[list].connect( self.__TRPreviewer) self.projectBrowser.ptBrowser.trpreview[list, bool].connect( self.__TRPreviewer) self.projectBrowser.ptBrowser.closeSourceWindow.connect( self.viewmanager.closeWindow) self.projectBrowser.ptBrowser.appendStdout.connect(self.appendToStdout) self.projectBrowser.ptBrowser.appendStderr.connect(self.appendToStderr) self.projectBrowser.piBrowser.sourceFile[str].connect( self.viewmanager.openSourceFile) self.projectBrowser.piBrowser.sourceFile[str, int].connect( self.viewmanager.openSourceFile) self.projectBrowser.piBrowser.closeSourceWindow.connect( self.viewmanager.closeWindow) self.projectBrowser.piBrowser.appendStdout.connect(self.appendToStdout) self.projectBrowser.piBrowser.appendStderr.connect(self.appendToStderr) self.projectBrowser.poBrowser.sourceFile.connect( self.viewmanager.openSourceFile) self.projectBrowser.poBrowser.closeSourceWindow.connect( self.viewmanager.closeWindow) self.projectBrowser.poBrowser.pixmapEditFile.connect(self.__editPixmap) self.projectBrowser.poBrowser.pixmapFile.connect(self.__showPixmap) self.projectBrowser.poBrowser.svgFile.connect(self.__showSvg) self.project.sourceFile.connect(self.viewmanager.openSourceFile) self.project.projectOpened.connect(self.viewmanager.projectOpened) self.project.projectClosed.connect(self.viewmanager.projectClosed) self.project.projectFileRenamed.connect( self.viewmanager.projectFileRenamed) self.project.lexerAssociationsChanged.connect( self.viewmanager.projectLexerAssociationsChanged) self.project.newProject.connect(self.__newProject) self.project.projectOpened.connect(self.__projectOpened) self.project.projectOpened.connect(self.__activateProjectBrowser) self.project.projectClosed.connect(self.__projectClosed) self.project.projectClosed.connect( self.backgroundService.preferencesOrProjectChanged) self.multiProject.multiProjectOpened.connect( self.__activateMultiProjectBrowser) self.debuggerUI.resetUI.connect(self.viewmanager.handleResetUI) self.debuggerUI.resetUI.connect(self.debugViewer.handleResetUI) self.debuggerUI.resetUI.connect(self.__debuggingDone) self.debuggerUI.debuggingStarted.connect( self.browser.handleProgramChange) self.debuggerUI.debuggingStarted.connect( self.debugViewer.exceptionLogger.debuggingStarted) self.debuggerUI.debuggingStarted.connect( self.debugViewer.handleDebuggingStarted) self.debuggerUI.debuggingStarted.connect(self.__programChange) self.debuggerUI.debuggingStarted.connect(self.__debuggingStarted) self.debuggerUI.compileForms.connect( self.projectBrowser.pfBrowser.compileChangedForms) self.debuggerUI.compileResources.connect( self.projectBrowser.prBrowser.compileChangedResources) self.debuggerUI.appendStdout.connect(self.appendToStdout) debugServer.passiveDebugStarted.connect( self.debugViewer.exceptionLogger.debuggingStarted) debugServer.passiveDebugStarted.connect( self.debugViewer.handleDebuggingStarted) debugServer.clientException.connect( self.debugViewer.exceptionLogger.addException) debugServer.clientLine.connect( self.debugViewer.breakpointViewer.highlightBreakpoint) debugServer.clientProcessStdout.connect(self.appendToStdout) debugServer.clientProcessStderr.connect(self.appendToStderr) debugServer.clientInterpreterChanged.connect( self.browser.handleInterpreterChanged) debugServer.appendStdout.connect(self.appendToStdout) self.stdout.appendStdout.connect(self.appendToStdout) self.stderr.appendStderr.connect(self.appendToStderr) self.preferencesChanged.connect(self.viewmanager.preferencesChanged) self.reloadAPIs.connect(self.viewmanager.getAPIsManager().reloadAPIs) self.preferencesChanged.connect(self.logViewer.preferencesChanged) self.appendStdout.connect(self.logViewer.appendToStdout) self.appendStderr.connect(self.logViewer.appendToStderr) self.preferencesChanged.connect(self.shell.handlePreferencesChanged) self.preferencesChanged.connect(self.project.handlePreferencesChanged) self.preferencesChanged.connect( self.projectBrowser.handlePreferencesChanged) self.preferencesChanged.connect( self.projectBrowser.psBrowser.handlePreferencesChanged) self.preferencesChanged.connect( self.projectBrowser.pfBrowser.handlePreferencesChanged) self.preferencesChanged.connect( self.projectBrowser.prBrowser.handlePreferencesChanged) self.preferencesChanged.connect( self.projectBrowser.ptBrowser.handlePreferencesChanged) self.preferencesChanged.connect( self.projectBrowser.piBrowser.handlePreferencesChanged) self.preferencesChanged.connect( self.projectBrowser.poBrowser.handlePreferencesChanged) self.preferencesChanged.connect(self.browser.handlePreferencesChanged) self.preferencesChanged.connect( self.taskViewer.handlePreferencesChanged) self.preferencesChanged.connect(self.pluginManager.preferencesChanged) self.preferencesChanged.connect(debugServer.preferencesChanged) self.preferencesChanged.connect(self.debugViewer.preferencesChanged) self.preferencesChanged.connect(self.cooperation.preferencesChanged) self.preferencesChanged.connect( self.backgroundService.preferencesOrProjectChanged) self.viewmanager.editorSaved.connect(self.project.repopulateItem) self.viewmanager.lastEditorClosed.connect(self.__lastEditorClosed) self.viewmanager.editorOpened.connect(self.__editorOpened) self.viewmanager.changeCaption.connect(self.__setWindowCaption) self.viewmanager.checkActions.connect(self.__checkActions) self.viewmanager.editorChanged.connect( self.projectBrowser.handleEditorChanged) self.viewmanager.editorLineChanged.connect( self.projectBrowser.handleEditorLineChanged) self.viewmanager.checkActions.connect( self.cooperation.checkEditorActions) self.shell.zoomValueChanged.connect(self.viewmanager.zoomValueChanged) self.cooperation.shareEditor.connect(self.viewmanager.shareEditor) self.cooperation.startEdit.connect(self.viewmanager.startSharedEdit) self.cooperation.sendEdit.connect(self.viewmanager.sendSharedEdit) self.cooperation.cancelEdit.connect(self.viewmanager.cancelSharedEdit) self.cooperation.connected.connect(self.viewmanager.shareConnected) self.cooperation.editorCommand.connect(self.viewmanager.receive) self.viewmanager.setCooperationClient(self.cooperation.getClient()) self.symbolsViewer.insertSymbol.connect(self.viewmanager.insertSymbol) self.numbersViewer.insertNumber.connect(self.viewmanager.insertNumber) self.irc.autoConnected.connect(self.__ircAutoConnected) # create the toolbar manager object self.toolbarManager = E5ToolBarManager(self, self) self.toolbarManager.setMainWindow(self) # Initialize the tool groups and list of started tools splash.showMessage(self.tr("Initializing Tools...")) self.toolGroups, self.currentToolGroup = Preferences.readToolGroups() self.toolProcs = [] self.__initExternalToolsActions() # create a dummy help window for shortcuts handling from Helpviewer.HelpWindow import HelpWindow self.dummyHelpViewer = \ HelpWindow(None, '.', None, 'help viewer', True, True) # register all relevant objects splash.showMessage(self.tr("Registering Objects...")) e5App().registerObject("UserInterface", self) e5App().registerObject("DebugUI", self.debuggerUI) e5App().registerObject("DebugServer", debugServer) e5App().registerObject("BackgroundService", self.backgroundService) e5App().registerObject("ViewManager", self.viewmanager) e5App().registerObject("Project", self.project) e5App().registerObject("ProjectBrowser", self.projectBrowser) e5App().registerObject("MultiProject", self.multiProject) e5App().registerObject("TaskViewer", self.taskViewer) e5App().registerObject("TemplateViewer", self.templateViewer) e5App().registerObject("Shell", self.shell) e5App().registerObject("DummyHelpViewer", self.dummyHelpViewer) e5App().registerObject("PluginManager", self.pluginManager) e5App().registerObject("ToolbarManager", self.toolbarManager) e5App().registerObject("Cooperation", self.cooperation) e5App().registerObject("IRC", self.irc) e5App().registerObject("Symbols", self.symbolsViewer) e5App().registerObject("Numbers", self.numbersViewer) # Initialize the actions, menus, toolbars and statusbar splash.showMessage(self.tr("Initializing Actions...")) self.__initActions() splash.showMessage(self.tr("Initializing Menus...")) self.__initMenus() splash.showMessage(self.tr("Initializing Toolbars...")) self.__initToolbars() splash.showMessage(self.tr("Initializing Statusbar...")) self.__initStatusbar() # connect the appFocusChanged signal after all actions are ready app.focusChanged.connect(self.viewmanager.appFocusChanged) # Initialize the instance variables. self.currentProg = None self.isProg = False self.utEditorOpen = False self.utProjectOpen = False self.inDragDrop = False self.setAcceptDrops(True) self.currentProfile = None self.shutdownCalled = False self.inCloseEevent = False # now redirect stdout and stderr # TODO: release - reenable redirection sys.stdout = self.stdout sys.stderr = self.stderr # now fire up the single application server if Preferences.getUI("SingleApplicationMode"): splash.showMessage( self.tr("Initializing Single Application Server...")) self.SAServer = E5SingleApplicationServer() else: self.SAServer = None # now finalize the plugin manager setup self.pluginManager.finalizeSetup() # now activate plugins having autoload set to True splash.showMessage(self.tr("Activating Plugins...")) self.pluginManager.activatePlugins() # now read the keyboard shortcuts for all the actions from Preferences import Shortcuts Shortcuts.readShortcuts() # restore toolbar manager state splash.showMessage(self.tr("Restoring Toolbarmanager...")) self.toolbarManager.restoreState( Preferences.getUI("ToolbarManagerState")) # now activate the initial view profile splash.showMessage(self.tr("Setting View Profile...")) self.__setEditProfile() # now read the saved tasks splash.showMessage(self.tr("Reading Tasks...")) self.__readTasks() # now read the saved templates splash.showMessage(self.tr("Reading Templates...")) self.templateViewer.readTemplates() # now start the debug client splash.showMessage(self.tr("Starting Debugger...")) debugServer.startClient(False) # attributes for the network objects self.__networkManager = QNetworkAccessManager(self) self.__networkManager.proxyAuthenticationRequired.connect( proxyAuthenticationRequired) if SSL_AVAILABLE: self.__sslErrorHandler = E5SslErrorHandler(self) self.__networkManager.sslErrors.connect(self.__sslErrors) self.__replies = [] # attribute for the help window self.helpWindow = None # list of web addresses serving the versions file self.__httpAlternatives = Preferences.getUI("VersionsUrls6") self.__inVersionCheck = False self.__versionCheckProgress = None # set spellchecker defaults from QScintilla.SpellChecker import SpellChecker SpellChecker.setDefaultLanguage( Preferences.getEditor("SpellCheckingDefaultLanguage")) # attribute for the last shown configuration page self.__lastConfigurationPageName = "" def __createLayout(self, debugServer): """ Private method to create the layout of the various windows. @param debugServer reference to the debug server object @exception ValueError raised to indicate an invalid layout type """ # Create the view manager depending on the configuration setting logging.debug("Creating Viewmanager...") import ViewManager self.viewmanager = \ ViewManager.factory(self, self, debugServer, self.pluginManager) leftWidget = QWidget() layout = QVBoxLayout() layout.setContentsMargins(1, 1, 1, 1) layout.setSpacing(1) layout.addWidget(self.viewmanager) layout.addWidget(self.viewmanager.searchWidget()) layout.addWidget(self.viewmanager.replaceWidget()) self.viewmanager.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Expanding) leftWidget.setLayout(layout) self.viewmanager.searchWidget().hide() self.viewmanager.replaceWidget().hide() splitter = QSplitter(Qt.Horizontal) splitter.addWidget(leftWidget) self.setCentralWidget(splitter) # Create previewer logging.debug("Creating Previewer...") from .Previewer import Previewer self.__previewer = Previewer(self.viewmanager, splitter) splitter.addWidget(self.__previewer) # Create layout with toolbox windows embedded in dock windows if self.layout == "Toolboxes": logging.debug("Creating toolboxes...") self.__createToolboxesLayout(debugServer) # Create layout with sidebar windows embedded in dock windows elif self.layout == "Sidebars": logging.debug("Creating sidebars...") self.__createSidebarsLayout(debugServer) else: raise ValueError("Wrong layout type given ({0})".format( self.layout)) logging.debug("Created Layout") def __createToolboxesLayout(self, debugServer): """ Private method to create the Toolboxes layout. @param debugServer reference to the debug server object """ from E5Gui.E5ToolBox import E5VerticalToolBox, E5HorizontalToolBox # Create the left toolbox self.lToolboxDock = self.__createDockWindow("lToolboxDock") self.lToolbox = E5VerticalToolBox(self.lToolboxDock) self.__setupDockWindow(self.lToolboxDock, Qt.LeftDockWidgetArea, self.lToolbox, self.tr("Left Toolbox")) # Create the horizontal toolbox self.hToolboxDock = self.__createDockWindow("hToolboxDock") self.hToolbox = E5HorizontalToolBox(self.hToolboxDock) self.__setupDockWindow(self.hToolboxDock, Qt.BottomDockWidgetArea, self.hToolbox, self.tr("Horizontal Toolbox")) # Create the right toolbox self.rToolboxDock = self.__createDockWindow("rToolboxDock") self.rToolbox = E5VerticalToolBox(self.rToolboxDock) self.__setupDockWindow(self.rToolboxDock, Qt.RightDockWidgetArea, self.rToolbox, self.tr("Right Toolbox")) # Create the project browser from Project.ProjectBrowser import ProjectBrowser self.projectBrowser = ProjectBrowser( self.project, None, embeddedBrowser=(self.embeddedFileBrowser == 2)) self.lToolbox.addItem(self.projectBrowser, UI.PixmapCache.getIcon("projectViewer.png"), self.tr("Project-Viewer")) # Create the multi project browser from MultiProject.MultiProjectBrowser import MultiProjectBrowser self.multiProjectBrowser = MultiProjectBrowser(self.multiProject) self.lToolbox.addItem(self.multiProjectBrowser, UI.PixmapCache.getIcon("multiProjectViewer.png"), self.tr("Multiproject-Viewer")) # Create the template viewer part of the user interface from Templates.TemplateViewer import TemplateViewer self.templateViewer = TemplateViewer(None, self.viewmanager) self.lToolbox.addItem(self.templateViewer, UI.PixmapCache.getIcon("templateViewer.png"), self.tr("Template-Viewer")) # Create the debug viewer maybe without the embedded shell from Debugger.DebugViewer import DebugViewer self.debugViewer = DebugViewer( debugServer, True, self.viewmanager, None, embeddedShell=self.embeddedShell, embeddedBrowser=(self.embeddedFileBrowser == 1)) self.rToolbox.addItem(self.debugViewer, UI.PixmapCache.getIcon("debugViewer.png"), self.tr("Debug-Viewer")) # Create the chat part of the user interface from Cooperation.ChatWidget import ChatWidget self.cooperation = ChatWidget(self) self.rToolbox.addItem(self.cooperation, UI.PixmapCache.getIcon("cooperation.png"), self.tr("Cooperation")) # Create the IRC part of the user interface from Network.IRC.IrcWidget import IrcWidget self.irc = IrcWidget(self) self.rToolbox.addItem(self.irc, UI.PixmapCache.getIcon("irc.png"), self.tr("IRC")) # Create the task viewer part of the user interface from Tasks.TaskViewer import TaskViewer self.taskViewer = TaskViewer(None, self.project) self.hToolbox.addItem(self.taskViewer, UI.PixmapCache.getIcon("task.png"), self.tr("Task-Viewer")) # Create the log viewer part of the user interface from .LogView import LogViewer self.logViewer = LogViewer() self.hToolbox.addItem(self.logViewer, UI.PixmapCache.getIcon("logViewer.png"), self.tr("Log-Viewer")) if self.embeddedShell: self.shell = self.debugViewer.shell else: # Create the shell from QScintilla.Shell import ShellAssembly self.shellAssembly = \ ShellAssembly(debugServer, self.viewmanager, True) self.shell = self.shellAssembly.shell() self.hToolbox.insertItem(0, self.shellAssembly, UI.PixmapCache.getIcon("shell.png"), self.tr("Shell")) if self.embeddedFileBrowser == 0: # separate window # Create the file browser from .Browser import Browser self.browser = Browser() self.lToolbox.addItem(self.browser, UI.PixmapCache.getIcon("browser.png"), self.tr("File-Browser")) elif self.embeddedFileBrowser == 1: # embedded in debug browser self.browser = self.debugViewer.browser else: # embedded in project browser self.browser = self.projectBrowser.fileBrowser # Create the symbols viewer from .SymbolsWidget import SymbolsWidget self.symbolsViewer = SymbolsWidget() self.lToolbox.addItem(self.symbolsViewer, UI.PixmapCache.getIcon("symbols.png"), self.tr("Symbols")) # Create the numbers viewer from .NumbersWidget import NumbersWidget self.numbersViewer = NumbersWidget() self.hToolbox.addItem(self.numbersViewer, UI.PixmapCache.getIcon("numbers.png"), self.tr("Numbers")) self.hToolbox.setCurrentIndex(0) def __createSidebarsLayout(self, debugServer): """ Private method to create the Sidebars layout. @param debugServer reference to the debug server object """ from E5Gui.E5SideBar import E5SideBar delay = Preferences.getUI("SidebarDelay") # Create the left sidebar self.leftSidebar = E5SideBar(E5SideBar.West, delay) # Create the bottom sidebar self.bottomSidebar = E5SideBar(E5SideBar.South, delay) # Create the right sidebar self.rightSidebar = E5SideBar(E5SideBar.East, delay) # Create the project browser logging.debug("Creating Project Browser...") from Project.ProjectBrowser import ProjectBrowser self.projectBrowser = ProjectBrowser( self.project, None, embeddedBrowser=(self.embeddedFileBrowser == 2)) self.leftSidebar.addTab( self.projectBrowser, UI.PixmapCache.getIcon("projectViewer.png"), self.tr("Project-Viewer")) # Create the multi project browser logging.debug("Creating Multiproject Browser...") from MultiProject.MultiProjectBrowser import MultiProjectBrowser self.multiProjectBrowser = MultiProjectBrowser(self.multiProject) self.leftSidebar.addTab( self.multiProjectBrowser, UI.PixmapCache.getIcon("multiProjectViewer.png"), self.tr("Multiproject-Viewer")) # Create the template viewer part of the user interface logging.debug("Creating Template Viewer...") from Templates.TemplateViewer import TemplateViewer self.templateViewer = TemplateViewer(None, self.viewmanager) self.leftSidebar.addTab( self.templateViewer, UI.PixmapCache.getIcon("templateViewer.png"), self.tr("Template-Viewer")) # Create the debug viewer maybe without the embedded shell logging.debug("Creating Debug Viewer...") from Debugger.DebugViewer import DebugViewer self.debugViewer = DebugViewer( debugServer, True, self.viewmanager, None, embeddedShell=self.embeddedShell, embeddedBrowser=(self.embeddedFileBrowser == 1)) self.rightSidebar.addTab( self.debugViewer, UI.PixmapCache.getIcon("debugViewer.png"), self.tr("Debug-Viewer")) # Create the chat part of the user interface logging.debug("Creating Chat Widget...") from Cooperation.ChatWidget import ChatWidget self.cooperation = ChatWidget(self) self.rightSidebar.addTab( self.cooperation, UI.PixmapCache.getIcon("cooperation.png"), self.tr("Cooperation")) # Create the IRC part of the user interface logging.debug("Creating IRC Widget...") from Network.IRC.IrcWidget import IrcWidget self.irc = IrcWidget(self) self.rightSidebar.addTab( self.irc, UI.PixmapCache.getIcon("irc.png"), self.tr("IRC")) # Create the task viewer part of the user interface logging.debug("Creating Task Viewer...") from Tasks.TaskViewer import TaskViewer self.taskViewer = TaskViewer(None, self.project) self.bottomSidebar.addTab(self.taskViewer, UI.PixmapCache.getIcon("task.png"), self.tr("Task-Viewer")) # Create the log viewer part of the user interface logging.debug("Creating Log Viewer...") from .LogView import LogViewer self.logViewer = LogViewer() self.bottomSidebar.addTab(self.logViewer, UI.PixmapCache.getIcon("logViewer.png"), self.tr("Log-Viewer")) if self.embeddedShell: self.shell = self.debugViewer.shell else: # Create the shell logging.debug("Creating Shell...") from QScintilla.Shell import ShellAssembly self.shellAssembly = \ ShellAssembly(debugServer, self.viewmanager, True) self.shell = self.shellAssembly.shell() self.bottomSidebar.insertTab(0, self.shellAssembly, UI.PixmapCache.getIcon("shell.png"), self.tr("Shell")) if self.embeddedFileBrowser == 0: # separate window # Create the file browser logging.debug("Creating File Browser...") from .Browser import Browser self.browser = Browser() self.leftSidebar.addTab(self.browser, UI.PixmapCache.getIcon("browser.png"), self.tr("File-Browser")) elif self.embeddedFileBrowser == 1: # embedded in debug browser self.browser = self.debugViewer.browser else: # embedded in project browser self.browser = self.projectBrowser.fileBrowser # Create the symbols viewer logging.debug("Creating Symbols Viewer...") from .SymbolsWidget import SymbolsWidget self.symbolsViewer = SymbolsWidget() self.leftSidebar.addTab(self.symbolsViewer, UI.PixmapCache.getIcon("symbols.png"), self.tr("Symbols")) # Create the numbers viewer logging.debug("Creating Numbers Viewer...") from .NumbersWidget import NumbersWidget self.numbersViewer = NumbersWidget() self.bottomSidebar.addTab(self.numbersViewer, UI.PixmapCache.getIcon("numbers.png"), self.tr("Numbers")) self.bottomSidebar.setCurrentIndex(0) # create the central widget logging.debug("Creating central widget...") cw = self.centralWidget() # save the current central widget self.leftSplitter = QSplitter(Qt.Horizontal) self.rightSplitter = QSplitter(Qt.Horizontal) self.verticalSplitter = QSplitter(Qt.Vertical) self.verticalSplitter.addWidget(cw) self.verticalSplitter.addWidget(self.bottomSidebar) self.rightSplitter.addWidget(self.verticalSplitter) self.rightSplitter.addWidget(self.rightSidebar) self.leftSplitter.addWidget(self.leftSidebar) self.leftSplitter.addWidget(self.rightSplitter) self.setCentralWidget(self.leftSplitter) self.leftSidebar.setSplitter(self.leftSplitter) self.rightSidebar.setSplitter(self.rightSplitter) self.bottomSidebar.setSplitter(self.verticalSplitter) def __configureDockareaCornerUsage(self): """ Private method to configure the usage of the dockarea corners. """ if Preferences.getUI("TopLeftByLeft"): self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea) else: self.setCorner(Qt.TopLeftCorner, Qt.TopDockWidgetArea) if Preferences.getUI("BottomLeftByLeft"): self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea) else: self.setCorner(Qt.BottomLeftCorner, Qt.BottomDockWidgetArea) if Preferences.getUI("TopRightByRight"): self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea) else: self.setCorner(Qt.TopRightCorner, Qt.TopDockWidgetArea) if Preferences.getUI("BottomRightByRight"): self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea) else: self.setCorner(Qt.BottomRightCorner, Qt.BottomDockWidgetArea) def addSideWidget(self, side, widget, icon, label): """ Public method to add a widget to the sides. @param side side to add the widget to (UserInterface.LeftSide, UserInterface.BottomSide) @param widget reference to the widget to add (QWidget) @param icon icon to be used (QIcon) @param label label text to be shown (string) """ assert side in [UserInterface.LeftSide, UserInterface.BottomSide] if self.layout == "Toolboxes": if side == UserInterface.LeftSide: self.lToolbox.addItem(widget, icon, label) elif side == UserInterface.BottomSide: self.hToolbox.addItem(widget, icon, label) elif side == UserInterface.RightSide: self.rToolbox.addItem(widget, icon, label) elif self.layout == "Sidebars": if side == UserInterface.LeftSide: self.leftSidebar.addTab(widget, icon, label) elif side == UserInterface.BottomSide: self.bottomSidebar.addTab(widget, icon, label) elif side == UserInterface.RightSide: self.rightSidebar.addTab(widget, icon, label) def removeSideWidget(self, widget): """ Public method to remove a widget added using addSideWidget(). @param widget reference to the widget to remove (QWidget) """ if self.layout == "Toolboxes": for container in [self.lToolbox, self.hToolbox, self.rToolbox]: index = container.indexOf(widget) if index != -1: container.removeItem(index) elif self.layout == "Sidebars": for container in [self.leftSidebar, self.bottomSidebar, self.rightSidebar]: index = container.indexOf(widget) if index != -1: container.removeTab(index) def showLogTab(self, tabname): """ Public method to show a particular Log-Viewer tab. @param tabname string naming the tab to be shown (string) """ if Preferences.getUI("LogViewerAutoRaise"): if self.layout == "Toolboxes": self.hToolboxDock.show() self.hToolbox.setCurrentWidget(self.logViewer) self.hToolboxDock.raise_() elif self.layout == "Sidebars": self.bottomSidebar.show() self.bottomSidebar.setCurrentWidget(self.logViewer) self.bottomSidebar.raise_() if self.bottomSidebar.isAutoHiding(): self.bottomSidebar.setFocus() def __openOnStartup(self, startupType=None): """ Private method to open the last file, project or multiproject. @param startupType type of startup requested (string, one of "Nothing", "File", "Project", "MultiProject" or "Session") """ startupTypeMapping = { "Nothing": 0, "File": 1, "Project": 2, "MultiProject": 3, "Session": 4, } if startupType is None: startup = Preferences.getUI("OpenOnStartup") else: try: startup = startupTypeMapping[startupType] except KeyError: startup = Preferences.getUI("OpenOnStartup") if startup == 0: # open nothing pass elif startup == 1: # open last file recent = self.viewmanager.getMostRecent() if recent is not None: self.viewmanager.openFiles(recent) elif startup == 2: # open last project recent = self.project.getMostRecent() if recent is not None: self.project.openProject(recent) elif startup == 3: # open last multiproject recent = self.multiProject.getMostRecent() if recent is not None: self.multiProject.openMultiProject(recent) elif startup == 4: # open from session file self.__readSession() def processArgs(self, args): """ Public method to process the command line args passed to the UI. @param args list of files to open
The args are processed one at a time. All arguments after a '--' option are considered debug arguments to the program for the debugger. All files named before the '--' option are opened in a text editor, unless the argument ends in .e4p, then it is opened as a project file. If it ends in .e4m or .e5m, it is opened as a multiproject. """ # no args, return if args is None: if not self.__noOpenAtStartup: self.__openOnStartup() return opens = 0 # holds space delimited list of command args, if any argsStr = None # flag indicating '--' options was found ddseen = False if Utilities.isWindowsPlatform(): argChars = ['-', '/'] else: argChars = ['-'] for arg in args: # handle a request to start with last session if arg == '--start-file': self.__openOnStartup("File") # ignore all further arguments return elif arg == '--start-multi': self.__openOnStartup("MultiProject") # ignore all further arguments return elif arg == '--start-project': self.__openOnStartup("Project") # ignore all further arguments return elif arg == '--start-session': self.__openOnStartup("Session") # ignore all further arguments return if arg == '--' and not ddseen: ddseen = True continue if arg[0] in argChars or ddseen: if argsStr is None: argsStr = arg else: argsStr = "{0} {1}".format(argsStr, arg) continue try: ext = os.path.splitext(arg)[1] ext = os.path.normcase(ext) except IndexError: ext = "" if ext in ['.e4p']: self.project.openProject(arg) opens += 1 elif ext in ['.e4m', '.e5m']: self.multiProject.openMultiProject(arg) opens += 1 else: self.viewmanager.openFiles(arg) opens += 1 # store away any args we had if argsStr is not None: self.debuggerUI.setArgvHistory(argsStr) if opens == 0: # no files, project or multiproject was given if not self.__noOpenAtStartup: self.__openOnStartup() def __createDockWindow(self, name): """ Private method to create a dock window with common properties. @param name object name of the new dock window (string) @return the generated dock window (QDockWindow) """ dock = QDockWidget() dock.setObjectName(name) dock.setFeatures( QDockWidget.DockWidgetFeatures(QDockWidget.AllDockWidgetFeatures)) return dock def __setupDockWindow(self, dock, where, widget, caption): """ Private method to configure the dock window created with __createDockWindow(). @param dock the dock window (QDockWindow) @param where dock area to be docked to (Qt.DockWidgetArea) @param widget widget to be shown in the dock window (QWidget) @param caption caption of the dock window (string) """ if caption is None: caption = "" self.addDockWidget(where, dock) dock.setWidget(widget) dock.setWindowTitle(caption) dock.show() def __setWindowCaption(self, editor=None, project=None): """ Private method to set the caption of the Main Window. @param editor filename to be displayed (string) @param project project name to be displayed (string) """ if editor is not None and self.captionShowsFilename: self.capEditor = \ Utilities.compactPath(editor, self.maxFilePathLen) if project is not None: self.capProject = project if self.passiveMode: if not self.capProject and not self.capEditor: self.setWindowTitle( self.tr("{0} - Passive Mode").format(Program)) elif self.capProject and not self.capEditor: self.setWindowTitle( self.tr("{0} - {1} - Passive Mode") .format(self.capProject, Program)) elif not self.capProject and self.capEditor: self.setWindowTitle( self.tr("{0} - {1} - Passive Mode") .format(self.capEditor, Program)) else: self.setWindowTitle( self.tr("{0} - {1} - {2} - Passive Mode") .format(self.capProject, self.capEditor, Program)) else: if not self.capProject and not self.capEditor: self.setWindowTitle(Program) elif self.capProject and not self.capEditor: self.setWindowTitle( "{0} - {1}".format(self.capProject, Program)) elif not self.capProject and self.capEditor: self.setWindowTitle( "{0} - {1}".format(self.capEditor, Program)) else: self.setWindowTitle("{0} - {1} - {2}".format( self.capProject, self.capEditor, Program)) def __initActions(self): """ Private method to define the user interface actions. """ self.actions = [] self.wizardsActions = [] self.exitAct = E5Action( self.tr('Quit'), UI.PixmapCache.getIcon("exit.png"), self.tr('&Quit'), QKeySequence(self.tr("Ctrl+Q", "File|Quit")), 0, self, 'quit') self.exitAct.setStatusTip(self.tr('Quit the IDE')) self.exitAct.setWhatsThis(self.tr( """Quit the IDE""" """

This quits the IDE. Any unsaved changes may be saved""" """ first. Any Python program being debugged will be stopped""" """ and the preferences will be written to disc.

""" )) self.exitAct.triggered.connect(self.__quit) self.exitAct.setMenuRole(QAction.QuitRole) self.actions.append(self.exitAct) self.newWindowAct = E5Action( self.tr('New Window'), UI.PixmapCache.getIcon("newWindow.png"), self.tr('New &Window'), QKeySequence(self.tr("Ctrl+Shift+N", "File|New Window")), 0, self, 'new_window') self.newWindowAct.setStatusTip(self.tr( 'Open a new eric6 instance')) self.newWindowAct.setWhatsThis(self.tr( """New Window""" """

This opens a new instance of the eric6 IDE.

""" )) self.newWindowAct.triggered.connect(self.__newWindow) self.actions.append(self.newWindowAct) self.newWindowAct.setEnabled( not Preferences.getUI("SingleApplicationMode")) self.viewProfileActGrp = createActionGroup(self, "viewprofiles", True) self.setEditProfileAct = E5Action( self.tr('Edit Profile'), UI.PixmapCache.getIcon("viewProfileEdit.png"), self.tr('Edit Profile'), 0, 0, self.viewProfileActGrp, 'edit_profile', True) self.setEditProfileAct.setStatusTip(self.tr( 'Activate the edit view profile')) self.setEditProfileAct.setWhatsThis(self.tr( """Edit Profile""" """

Activate the "Edit View Profile". Windows being shown,""" """ if this profile is active, may be configured with the""" """ "View Profile Configuration" dialog.

""" )) self.setEditProfileAct.triggered.connect(self.__setEditProfile) self.actions.append(self.setEditProfileAct) self.setDebugProfileAct = E5Action( self.tr('Debug Profile'), UI.PixmapCache.getIcon("viewProfileDebug.png"), self.tr('Debug Profile'), 0, 0, self.viewProfileActGrp, 'debug_profile', True) self.setDebugProfileAct.setStatusTip( self.tr('Activate the debug view profile')) self.setDebugProfileAct.setWhatsThis(self.tr( """Debug Profile""" """

Activate the "Debug View Profile". Windows being shown,""" """ if this profile is active, may be configured with the""" """ "View Profile Configuration" dialog.

""" )) self.setDebugProfileAct.triggered.connect(self.setDebugProfile) self.actions.append(self.setDebugProfileAct) self.pbActivateAct = E5Action( self.tr('Project-Viewer'), self.tr('&Project-Viewer'), QKeySequence(self.tr("Alt+Shift+P")), 0, self, 'project_viewer_activate') self.pbActivateAct.setStatusTip(self.tr( "Switch the input focus to the Project-Viewer window.")) self.pbActivateAct.setWhatsThis(self.tr( """Activate Project-Viewer""" """

This switches the input focus to the Project-Viewer""" """ window.

""" )) self.pbActivateAct.triggered.connect(self.__activateProjectBrowser) self.actions.append(self.pbActivateAct) self.addAction(self.pbActivateAct) self.mpbActivateAct = E5Action( self.tr('Multiproject-Viewer'), self.tr('&Multiproject-Viewer'), QKeySequence(self.tr("Alt+Shift+M")), 0, self, 'multi_project_viewer_activate') self.mpbActivateAct.setStatusTip(self.tr( "Switch the input focus to the Multiproject-Viewer window.")) self.mpbActivateAct.setWhatsThis(self.tr( """Activate Multiproject-Viewer""" """

This switches the input focus to the Multiproject-Viewer""" """ window.

""" )) self.mpbActivateAct.triggered.connect( self.__activateMultiProjectBrowser) self.actions.append(self.mpbActivateAct) self.addAction(self.mpbActivateAct) self.debugViewerActivateAct = E5Action( self.tr('Debug-Viewer'), self.tr('&Debug-Viewer'), QKeySequence(self.tr("Alt+Shift+D")), 0, self, 'debug_viewer_activate') self.debugViewerActivateAct.setStatusTip(self.tr( "Switch the input focus to the Debug-Viewer window.")) self.debugViewerActivateAct.setWhatsThis(self.tr( """Activate Debug-Viewer""" """

This switches the input focus to the Debug-Viewer""" """ window.

""" )) self.debugViewerActivateAct.triggered.connect( self.__activateDebugViewer) self.actions.append(self.debugViewerActivateAct) self.addAction(self.debugViewerActivateAct) self.shellActivateAct = E5Action( self.tr('Shell'), self.tr('&Shell'), QKeySequence(self.tr("Alt+Shift+S")), 0, self, 'interprter_shell_activate') self.shellActivateAct.setStatusTip(self.tr( "Switch the input focus to the Shell window.")) self.shellActivateAct.setWhatsThis(self.tr( """Activate Shell""" """

This switches the input focus to the Shell window.

""" )) self.shellActivateAct.triggered.connect(self.__activateShell) self.actions.append(self.shellActivateAct) self.addAction(self.shellActivateAct) self.browserActivateAct = E5Action( self.tr('File-Browser'), self.tr('&File-Browser'), QKeySequence(self.tr("Alt+Shift+F")), 0, self, 'file_browser_activate') self.browserActivateAct.setStatusTip(self.tr( "Switch the input focus to the File-Browser window.")) self.browserActivateAct.setWhatsThis(self.tr( """Activate File-Browser""" """

This switches the input focus to the File-Browser""" """ window.

""" )) self.browserActivateAct.triggered.connect(self.__activateBrowser) self.actions.append(self.browserActivateAct) self.addAction(self.browserActivateAct) self.logViewerActivateAct = E5Action( self.tr('Log-Viewer'), self.tr('Lo&g-Viewer'), QKeySequence(self.tr("Alt+Shift+G")), 0, self, 'log_viewer_activate') self.logViewerActivateAct.setStatusTip(self.tr( "Switch the input focus to the Log-Viewer window.")) self.logViewerActivateAct.setWhatsThis(self.tr( """Activate Log-Viewer""" """

This switches the input focus to the Log-Viewer""" """ window.

""" )) self.logViewerActivateAct.triggered.connect( self.__activateLogViewer) self.actions.append(self.logViewerActivateAct) self.addAction(self.logViewerActivateAct) self.taskViewerActivateAct = E5Action( self.tr('Task-Viewer'), self.tr('&Task-Viewer'), QKeySequence(self.tr("Alt+Shift+T")), 0, self, 'task_viewer_activate') self.taskViewerActivateAct.setStatusTip(self.tr( "Switch the input focus to the Task-Viewer window.")) self.taskViewerActivateAct.setWhatsThis(self.tr( """Activate Task-Viewer""" """

This switches the input focus to the Task-Viewer""" """ window.

""" )) self.taskViewerActivateAct.triggered.connect( self.__activateTaskViewer) self.actions.append(self.taskViewerActivateAct) self.addAction(self.taskViewerActivateAct) self.templateViewerActivateAct = E5Action( self.tr('Template-Viewer'), self.tr('Templ&ate-Viewer'), QKeySequence(self.tr("Alt+Shift+A")), 0, self, 'template_viewer_activate') self.templateViewerActivateAct.setStatusTip(self.tr( "Switch the input focus to the Template-Viewer window.")) self.templateViewerActivateAct.setWhatsThis(self.tr( """Activate Template-Viewer""" """

This switches the input focus to the Template-Viewer""" """ window.

""" )) self.templateViewerActivateAct.triggered.connect( self.__activateTemplateViewer) self.actions.append(self.templateViewerActivateAct) self.addAction(self.templateViewerActivateAct) self.ltAct = E5Action( self.tr('Left Toolbox'), self.tr('&Left Toolbox'), 0, 0, self, 'vertical_toolbox', True) self.ltAct.setStatusTip(self.tr('Toggle the Left Toolbox window')) self.ltAct.setWhatsThis(self.tr( """Toggle the Left Toolbox window""" """

If the Left Toolbox window is hidden then display it.""" """ If it is displayed then close it.

""" )) self.ltAct.triggered.connect(self.__toggleLeftToolbox) self.actions.append(self.ltAct) self.rtAct = E5Action( self.tr('Right Toolbox'), self.tr('&Right Toolbox'), 0, 0, self, 'vertical_toolbox', True) self.rtAct.setStatusTip(self.tr('Toggle the Right Toolbox window')) self.rtAct.setWhatsThis(self.tr( """Toggle the Right Toolbox window""" """

If the Right Toolbox window is hidden then display it.""" """ If it is displayed then close it.

""" )) self.rtAct.triggered.connect(self.__toggleRightToolbox) self.actions.append(self.rtAct) self.htAct = E5Action( self.tr('Horizontal Toolbox'), self.tr('&Horizontal Toolbox'), 0, 0, self, 'horizontal_toolbox', True) self.htAct.setStatusTip(self.tr( 'Toggle the Horizontal Toolbox window')) self.htAct.setWhatsThis(self.tr( """Toggle the Horizontal Toolbox window""" """

If the Horizontal Toolbox window is hidden then display""" """ it. If it is displayed then close it.

""" )) self.htAct.triggered.connect(self.__toggleHorizontalToolbox) self.actions.append(self.htAct) self.lsbAct = E5Action( self.tr('Left Sidebar'), self.tr('&Left Sidebar'), 0, 0, self, 'left_sidebar', True) self.lsbAct.setStatusTip(self.tr('Toggle the left sidebar window')) self.lsbAct.setWhatsThis(self.tr( """Toggle the left sidebar window""" """

If the left sidebar window is hidden then display it.""" """ If it is displayed then close it.

""" )) self.lsbAct.triggered.connect(self.__toggleLeftSidebar) self.actions.append(self.lsbAct) self.rsbAct = E5Action( self.tr('Right Sidebar'), self.tr('&Right Sidebar'), 0, 0, self, 'right_sidebar', True) self.rsbAct.setStatusTip(self.tr( 'Toggle the right sidebar window')) self.rsbAct.setWhatsThis(self.tr( """Toggle the right sidebar window""" """

If the right sidebar window is hidden then display it.""" """ If it is displayed then close it.

""" )) self.rsbAct.triggered.connect(self.__toggleRightSidebar) self.actions.append(self.rsbAct) self.bsbAct = E5Action( self.tr('Bottom Sidebar'), self.tr('&Bottom Sidebar'), 0, 0, self, 'bottom_sidebar', True) self.bsbAct.setStatusTip(self.tr( 'Toggle the bottom sidebar window')) self.bsbAct.setWhatsThis(self.tr( """Toggle the bottom sidebar window""" """

If the bottom sidebar window is hidden then display it.""" """ If it is displayed then close it.

""" )) self.bsbAct.triggered.connect(self.__toggleBottomSidebar) self.actions.append(self.bsbAct) self.cooperationViewerActivateAct = E5Action( self.tr('Cooperation-Viewer'), self.tr('Co&operation-Viewer'), QKeySequence(self.tr("Alt+Shift+O")), 0, self, 'cooperation_viewer_activate') self.cooperationViewerActivateAct.setStatusTip(self.tr( "Switch the input focus to the Cooperation-Viewer window.")) self.cooperationViewerActivateAct.setWhatsThis(self.tr( """Activate Cooperation-Viewer""" """

This switches the input focus to the Cooperation-Viewer""" """ window.

""" )) self.cooperationViewerActivateAct.triggered.connect( self.activateCooperationViewer) self.actions.append(self.cooperationViewerActivateAct) self.addAction(self.cooperationViewerActivateAct) self.ircActivateAct = E5Action( self.tr('IRC'), self.tr('&IRC'), QKeySequence(self.tr("Meta+Shift+I")), 0, self, 'irc_widget_activate') self.ircActivateAct.setStatusTip(self.tr( "Switch the input focus to the IRC window.")) self.ircActivateAct.setWhatsThis(self.tr( """Activate IRC""" """

This switches the input focus to the IRC window.

""" )) self.ircActivateAct.triggered.connect( self.__activateIRC) self.actions.append(self.ircActivateAct) self.addAction(self.ircActivateAct) self.symbolsViewerActivateAct = E5Action( self.tr('Symbols-Viewer'), self.tr('S&ymbols-Viewer'), QKeySequence(self.tr("Alt+Shift+Y")), 0, self, 'symbols_viewer_activate') self.symbolsViewerActivateAct.setStatusTip(self.tr( "Switch the input focus to the Symbols-Viewer window.")) self.symbolsViewerActivateAct.setWhatsThis(self.tr( """Activate Symbols-Viewer""" """

This switches the input focus to the Symbols-Viewer""" """ window.

""" )) self.symbolsViewerActivateAct.triggered.connect( self.__activateSymbolsViewer) self.actions.append(self.symbolsViewerActivateAct) self.addAction(self.symbolsViewerActivateAct) self.numbersViewerActivateAct = E5Action( self.tr('Numbers-Viewer'), self.tr('Num&bers-Viewer'), QKeySequence(self.tr("Alt+Shift+B")), 0, self, 'numbers_viewer_activate') self.numbersViewerActivateAct.setStatusTip(self.tr( "Switch the input focus to the Numbers-Viewer window.")) self.numbersViewerActivateAct.setWhatsThis(self.tr( """Activate Numbers-Viewer""" """

This switches the input focus to the Numbers-Viewer""" """ window.

""" )) self.numbersViewerActivateAct.triggered.connect( self.__activateNumbersViewer) self.actions.append(self.numbersViewerActivateAct) self.addAction(self.numbersViewerActivateAct) self.whatsThisAct = E5Action( self.tr('What\'s This?'), UI.PixmapCache.getIcon("whatsThis.png"), self.tr('&What\'s This?'), QKeySequence(self.tr("Shift+F1")), 0, self, 'whatsThis') self.whatsThisAct.setStatusTip(self.tr('Context sensitive help')) self.whatsThisAct.setWhatsThis(self.tr( """Display context sensitive help""" """

In What's This? mode, the mouse cursor shows an arrow with""" """ a question mark, and you can click on the interface elements""" """ to get a short description of what they do and how to use""" """ them. In dialogs, this feature can be accessed using the""" """ context help button in the titlebar.

""" )) self.whatsThisAct.triggered.connect(self.__whatsThis) self.actions.append(self.whatsThisAct) self.helpviewerAct = E5Action( self.tr('Helpviewer'), UI.PixmapCache.getIcon("help.png"), self.tr('&Helpviewer...'), QKeySequence(self.tr("F1")), 0, self, 'helpviewer') self.helpviewerAct.setStatusTip(self.tr( 'Open the helpviewer window')) self.helpviewerAct.setWhatsThis(self.tr( """Helpviewer""" """

Display the eric6 web browser. This window will show""" """ HTML help files and help from Qt help collections. It has""" """ the capability to navigate to links, set bookmarks, print""" """ the displayed help and some more features. You may use it to""" """ browse the internet as well

If called with a word""" """ selected, this word is search in the Qt help collection.

""" )) self.helpviewerAct.triggered.connect(self.__helpViewer) self.actions.append(self.helpviewerAct) self.__initQtDocActions() self.__initPythonDocActions() self.__initEricDocAction() self.__initPySideDocAction() self.versionAct = E5Action( self.tr('Show Versions'), self.tr('Show &Versions'), 0, 0, self, 'show_versions') self.versionAct.setStatusTip(self.tr( 'Display version information')) self.versionAct.setWhatsThis(self.tr( """Show Versions""" """

Display version information.

""" )) self.versionAct.triggered.connect(self.__showVersions) self.actions.append(self.versionAct) self.checkUpdateAct = E5Action( self.tr('Check for Updates'), self.tr('Check for &Updates...'), 0, 0, self, 'check_updates') self.checkUpdateAct.setStatusTip(self.tr('Check for Updates')) self.checkUpdateAct.setWhatsThis(self.tr( """Check for Updates...""" """

Checks the internet for updates of eric6.

""" )) self.checkUpdateAct.triggered.connect(self.performVersionCheck) self.actions.append(self.checkUpdateAct) self.showVersionsAct = E5Action( self.tr('Show downloadable versions'), self.tr('Show &downloadable versions...'), 0, 0, self, 'show_downloadable_versions') self.showVersionsAct.setStatusTip( self.tr('Show the versions available for download')) self.showVersionsAct.setWhatsThis(self.tr( """Show downloadable versions...""" """

Shows the eric6 versions available for download """ """from the internet.

""" )) self.showVersionsAct.triggered.connect( self.showAvailableVersionsInfo) self.actions.append(self.showVersionsAct) self.showErrorLogAct = E5Action( self.tr('Show Error Log'), self.tr('Show Error &Log...'), 0, 0, self, 'show_error_log') self.showErrorLogAct.setStatusTip(self.tr('Show Error Log')) self.showErrorLogAct.setWhatsThis(self.tr( """Show Error Log...""" """

Opens a dialog showing the most recent error log.

""" )) self.showErrorLogAct.triggered.connect(self.__showErrorLog) self.actions.append(self.showErrorLogAct) self.reportBugAct = E5Action( self.tr('Report Bug'), self.tr('Report &Bug...'), 0, 0, self, 'report_bug') self.reportBugAct.setStatusTip(self.tr('Report a bug')) self.reportBugAct.setWhatsThis(self.tr( """Report Bug...""" """

Opens a dialog to report a bug.

""" )) self.reportBugAct.triggered.connect(self.__reportBug) self.actions.append(self.reportBugAct) self.requestFeatureAct = E5Action( self.tr('Request Feature'), self.tr('Request &Feature...'), 0, 0, self, 'request_feature') self.requestFeatureAct.setStatusTip(self.tr( 'Send a feature request')) self.requestFeatureAct.setWhatsThis(self.tr( """Request Feature...""" """

Opens a dialog to send a feature request.

""" )) self.requestFeatureAct.triggered.connect(self.__requestFeature) self.actions.append(self.requestFeatureAct) self.utActGrp = createActionGroup(self) self.utDialogAct = E5Action( self.tr('Unittest'), UI.PixmapCache.getIcon("unittest.png"), self.tr('&Unittest...'), 0, 0, self.utActGrp, 'unittest') self.utDialogAct.setStatusTip(self.tr('Start unittest dialog')) self.utDialogAct.setWhatsThis(self.tr( """Unittest""" """

Perform unit tests. The dialog gives you the""" """ ability to select and run a unittest suite.

""" )) self.utDialogAct.triggered.connect(self.__unittest) self.actions.append(self.utDialogAct) self.utRestartAct = E5Action( self.tr('Unittest Restart'), UI.PixmapCache.getIcon("unittestRestart.png"), self.tr('&Restart Unittest...'), 0, 0, self.utActGrp, 'unittest_restart') self.utRestartAct.setStatusTip(self.tr('Restart last unittest')) self.utRestartAct.setWhatsThis(self.tr( """Restart Unittest""" """

Restart the unittest performed last.

""" )) self.utRestartAct.triggered.connect(self.__unittestRestart) self.utRestartAct.setEnabled(False) self.actions.append(self.utRestartAct) self.utRerunFailedAct = E5Action( self.tr('Unittest Rerun Failed'), UI.PixmapCache.getIcon("unittestRerunFailed.png"), self.tr('Rerun Failed Tests...'), 0, 0, self.utActGrp, 'unittest_rerun_failed') self.utRerunFailedAct.setStatusTip(self.tr( 'Rerun failed tests of the last run')) self.utRerunFailedAct.setWhatsThis(self.tr( """Rerun Failed Tests""" """

Rerun all tests that failed during the last unittest""" """ run.

""" )) self.utRerunFailedAct.triggered.connect(self.__unittestRerunFailed) self.utRerunFailedAct.setEnabled(False) self.actions.append(self.utRerunFailedAct) self.utScriptAct = E5Action( self.tr('Unittest Script'), UI.PixmapCache.getIcon("unittestScript.png"), self.tr('Unittest &Script...'), 0, 0, self.utActGrp, 'unittest_script') self.utScriptAct.setStatusTip(self.tr( 'Run unittest with current script')) self.utScriptAct.setWhatsThis(self.tr( """Unittest Script""" """

Run unittest with current script.

""" )) self.utScriptAct.triggered.connect(self.__unittestScript) self.utScriptAct.setEnabled(False) self.actions.append(self.utScriptAct) self.utProjectAct = E5Action( self.tr('Unittest Project'), UI.PixmapCache.getIcon("unittestProject.png"), self.tr('Unittest &Project...'), 0, 0, self.utActGrp, 'unittest_project') self.utProjectAct.setStatusTip(self.tr( 'Run unittest with current project')) self.utProjectAct.setWhatsThis(self.tr( """Unittest Project""" """

Run unittest with current project.

""" )) self.utProjectAct.triggered.connect(self.__unittestProject) self.utProjectAct.setEnabled(False) self.actions.append(self.utProjectAct) # check for Qt4/Qt5 designer and linguist if Utilities.isWindowsPlatform(): designerExe = os.path.join( Utilities.getQtBinariesPath(), "{0}.exe".format(Utilities.generateQtToolName("designer"))) elif Utilities.isMacPlatform(): designerExe = Utilities.getQtMacBundle("designer") else: designerExe = os.path.join( Utilities.getQtBinariesPath(), Utilities.generateQtToolName("designer")) if os.path.exists(designerExe): self.designer4Act = E5Action( self.tr('Qt-Designer'), UI.PixmapCache.getIcon("designer4.png"), self.tr('Qt-&Designer...'), 0, 0, self, 'qt_designer4') self.designer4Act.setStatusTip(self.tr('Start Qt-Designer')) self.designer4Act.setWhatsThis(self.tr( """Qt-Designer""" """

Start Qt-Designer.

""" )) self.designer4Act.triggered.connect(self.__designer4) self.actions.append(self.designer4Act) else: self.designer4Act = None if Utilities.isWindowsPlatform(): linguistExe = os.path.join( Utilities.getQtBinariesPath(), "{0}.exe".format(Utilities.generateQtToolName("linguist"))) elif Utilities.isMacPlatform(): linguistExe = Utilities.getQtMacBundle("linguist") else: linguistExe = os.path.join( Utilities.getQtBinariesPath(), Utilities.generateQtToolName("linguist")) if os.path.exists(linguistExe): self.linguist4Act = E5Action( self.tr('Qt-Linguist'), UI.PixmapCache.getIcon("linguist4.png"), self.tr('Qt-&Linguist...'), 0, 0, self, 'qt_linguist4') self.linguist4Act.setStatusTip(self.tr('Start Qt-Linguist')) self.linguist4Act.setWhatsThis(self.tr( """Qt-Linguist""" """

Start Qt-Linguist.

""" )) self.linguist4Act.triggered.connect(self.__linguist4) self.actions.append(self.linguist4Act) else: self.linguist4Act = None self.uipreviewerAct = E5Action( self.tr('UI Previewer'), UI.PixmapCache.getIcon("uiPreviewer.png"), self.tr('&UI Previewer...'), 0, 0, self, 'ui_previewer') self.uipreviewerAct.setStatusTip(self.tr('Start the UI Previewer')) self.uipreviewerAct.setWhatsThis(self.tr( """UI Previewer""" """

Start the UI Previewer.

""" )) self.uipreviewerAct.triggered.connect(self.__UIPreviewer) self.actions.append(self.uipreviewerAct) self.trpreviewerAct = E5Action( self.tr('Translations Previewer'), UI.PixmapCache.getIcon("trPreviewer.png"), self.tr('&Translations Previewer...'), 0, 0, self, 'tr_previewer') self.trpreviewerAct.setStatusTip(self.tr( 'Start the Translations Previewer')) self.trpreviewerAct.setWhatsThis(self.tr( """Translations Previewer""" """

Start the Translations Previewer.

""" )) self.trpreviewerAct.triggered.connect(self.__TRPreviewer) self.actions.append(self.trpreviewerAct) self.diffAct = E5Action( self.tr('Compare Files'), UI.PixmapCache.getIcon("diffFiles.png"), self.tr('&Compare Files...'), 0, 0, self, 'diff_files') self.diffAct.setStatusTip(self.tr('Compare two files')) self.diffAct.setWhatsThis(self.tr( """Compare Files""" """

Open a dialog to compare two files.

""" )) self.diffAct.triggered.connect(self.__compareFiles) self.actions.append(self.diffAct) self.compareAct = E5Action( self.tr('Compare Files side by side'), UI.PixmapCache.getIcon("compareFiles.png"), self.tr('Compare &Files side by side...'), 0, 0, self, 'compare_files') self.compareAct.setStatusTip(self.tr('Compare two files')) self.compareAct.setWhatsThis(self.tr( """Compare Files side by side""" """

Open a dialog to compare two files and show the result""" """ side by side.

""" )) self.compareAct.triggered.connect(self.__compareFilesSbs) self.actions.append(self.compareAct) self.sqlBrowserAct = E5Action( self.tr('SQL Browser'), UI.PixmapCache.getIcon("sqlBrowser.png"), self.tr('SQL &Browser...'), 0, 0, self, 'sql_browser') self.sqlBrowserAct.setStatusTip(self.tr('Browse a SQL database')) self.sqlBrowserAct.setWhatsThis(self.tr( """SQL Browser""" """

Browse a SQL database.

""" )) self.sqlBrowserAct.triggered.connect(self.__sqlBrowser) self.actions.append(self.sqlBrowserAct) self.miniEditorAct = E5Action( self.tr('Mini Editor'), UI.PixmapCache.getIcon("editor.png"), self.tr('Mini &Editor...'), 0, 0, self, 'mini_editor') self.miniEditorAct.setStatusTip(self.tr('Mini Editor')) self.miniEditorAct.setWhatsThis(self.tr( """Mini Editor""" """

Open a dialog with a simplified editor.

""" )) self.miniEditorAct.triggered.connect(self.__openMiniEditor) self.actions.append(self.miniEditorAct) self.webBrowserAct = E5Action( self.tr('eric6 Web Browser'), UI.PixmapCache.getIcon("ericWeb.png"), self.tr('eric6 &Web Browser...'), 0, 0, self, 'web_browser') self.webBrowserAct.setStatusTip(self.tr( 'Start the eric6 Web Browser')) self.webBrowserAct.setWhatsThis(self.tr( """eric6 Web Browser""" """

Browse the Internet with the eric6 Web Browser.

""" )) self.webBrowserAct.triggered.connect(self.__startWebBrowser) self.actions.append(self.webBrowserAct) self.iconEditorAct = E5Action( self.tr('Icon Editor'), UI.PixmapCache.getIcon("iconEditor.png"), self.tr('&Icon Editor...'), 0, 0, self, 'icon_editor') self.iconEditorAct.setStatusTip(self.tr( 'Start the eric6 Icon Editor')) self.iconEditorAct.setWhatsThis(self.tr( """Icon Editor""" """

Starts the eric6 Icon Editor for editing simple icons.

""" )) self.iconEditorAct.triggered.connect(self.__editPixmap) self.actions.append(self.iconEditorAct) self.snapshotAct = E5Action( self.tr('Snapshot'), UI.PixmapCache.getIcon("ericSnap.png"), self.tr('&Snapshot...'), 0, 0, self, 'snapshot') self.snapshotAct.setStatusTip(self.tr( 'Take snapshots of a screen region')) self.snapshotAct.setWhatsThis(self.tr( """Snapshot""" """

This opens a dialog to take snapshots of a screen""" """ region.

""" )) self.snapshotAct.triggered.connect(self.__snapshot) self.actions.append(self.snapshotAct) self.prefAct = E5Action( self.tr('Preferences'), UI.PixmapCache.getIcon("configure.png"), self.tr('&Preferences...'), 0, 0, self, 'preferences') self.prefAct.setStatusTip(self.tr( 'Set the prefered configuration')) self.prefAct.setWhatsThis(self.tr( """Preferences""" """

Set the configuration items of the application""" """ with your prefered values.

""" )) self.prefAct.triggered.connect(self.showPreferences) self.prefAct.setMenuRole(QAction.PreferencesRole) self.actions.append(self.prefAct) self.prefExportAct = E5Action( self.tr('Export Preferences'), UI.PixmapCache.getIcon("configureExport.png"), self.tr('E&xport Preferences...'), 0, 0, self, 'export_preferences') self.prefExportAct.setStatusTip(self.tr( 'Export the current configuration')) self.prefExportAct.setWhatsThis(self.tr( """Export Preferences""" """

Export the current configuration to a file.

""" )) self.prefExportAct.triggered.connect(self.__exportPreferences) self.actions.append(self.prefExportAct) self.prefImportAct = E5Action( self.tr('Import Preferences'), UI.PixmapCache.getIcon("configureImport.png"), self.tr('I&mport Preferences...'), 0, 0, self, 'import_preferences') self.prefImportAct.setStatusTip(self.tr( 'Import a previously exported configuration')) self.prefImportAct.setWhatsThis(self.tr( """Import Preferences""" """

Import a previously exported configuration.

""" )) self.prefImportAct.triggered.connect(self.__importPreferences) self.actions.append(self.prefImportAct) self.reloadAPIsAct = E5Action( self.tr('Reload APIs'), self.tr('Reload &APIs'), 0, 0, self, 'reload_apis') self.reloadAPIsAct.setStatusTip(self.tr( 'Reload the API information')) self.reloadAPIsAct.setWhatsThis(self.tr( """Reload APIs""" """

Reload the API information.

""" )) self.reloadAPIsAct.triggered.connect(self.__reloadAPIs) self.actions.append(self.reloadAPIsAct) self.showExternalToolsAct = E5Action( self.tr('Show external tools'), UI.PixmapCache.getIcon("showPrograms.png"), self.tr('Show external &tools'), 0, 0, self, 'show_external_tools') self.showExternalToolsAct.setStatusTip(self.tr( 'Show external tools')) self.showExternalToolsAct.setWhatsThis(self.tr( """Show external tools""" """

Opens a dialog to show the path and versions of all""" """ extenal tools used by eric6.

""" )) self.showExternalToolsAct.triggered.connect( self.__showExternalTools) self.actions.append(self.showExternalToolsAct) self.configViewProfilesAct = E5Action( self.tr('View Profiles'), UI.PixmapCache.getIcon("configureViewProfiles.png"), self.tr('&View Profiles...'), 0, 0, self, 'view_profiles') self.configViewProfilesAct.setStatusTip(self.tr( 'Configure view profiles')) self.configViewProfilesAct.setWhatsThis(self.tr( """View Profiles""" """

Configure the view profiles. With this dialog you may""" """ set the visibility of the various windows for the""" """ predetermined view profiles.

""" )) self.configViewProfilesAct.triggered.connect( self.__configViewProfiles) self.actions.append(self.configViewProfilesAct) self.configToolBarsAct = E5Action( self.tr('Toolbars'), UI.PixmapCache.getIcon("toolbarsConfigure.png"), self.tr('Tool&bars...'), 0, 0, self, 'configure_toolbars') self.configToolBarsAct.setStatusTip(self.tr('Configure toolbars')) self.configToolBarsAct.setWhatsThis(self.tr( """Toolbars""" """

Configure the toolbars. With this dialog you may""" """ change the actions shown on the various toolbars and""" """ define your own toolbars.

""" )) self.configToolBarsAct.triggered.connect(self.__configToolBars) self.actions.append(self.configToolBarsAct) self.shortcutsAct = E5Action( self.tr('Keyboard Shortcuts'), UI.PixmapCache.getIcon("configureShortcuts.png"), self.tr('Keyboard &Shortcuts...'), 0, 0, self, 'keyboard_shortcuts') self.shortcutsAct.setStatusTip(self.tr( 'Set the keyboard shortcuts')) self.shortcutsAct.setWhatsThis(self.tr( """Keyboard Shortcuts""" """

Set the keyboard shortcuts of the application""" """ with your prefered values.

""" )) self.shortcutsAct.triggered.connect(self.__configShortcuts) self.actions.append(self.shortcutsAct) self.exportShortcutsAct = E5Action( self.tr('Export Keyboard Shortcuts'), UI.PixmapCache.getIcon("exportShortcuts.png"), self.tr('&Export Keyboard Shortcuts...'), 0, 0, self, 'export_keyboard_shortcuts') self.exportShortcutsAct.setStatusTip(self.tr( 'Export the keyboard shortcuts')) self.exportShortcutsAct.setWhatsThis(self.tr( """Export Keyboard Shortcuts""" """

Export the keyboard shortcuts of the application.

""" )) self.exportShortcutsAct.triggered.connect(self.__exportShortcuts) self.actions.append(self.exportShortcutsAct) self.importShortcutsAct = E5Action( self.tr('Import Keyboard Shortcuts'), UI.PixmapCache.getIcon("importShortcuts.png"), self.tr('&Import Keyboard Shortcuts...'), 0, 0, self, 'import_keyboard_shortcuts') self.importShortcutsAct.setStatusTip(self.tr( 'Import the keyboard shortcuts')) self.importShortcutsAct.setWhatsThis(self.tr( """Import Keyboard Shortcuts""" """

Import the keyboard shortcuts of the application.

""" )) self.importShortcutsAct.triggered.connect(self.__importShortcuts) self.actions.append(self.importShortcutsAct) if SSL_AVAILABLE: self.certificatesAct = E5Action( self.tr('Manage SSL Certificates'), UI.PixmapCache.getIcon("certificates.png"), self.tr('Manage SSL Certificates...'), 0, 0, self, 'manage_ssl_certificates') self.certificatesAct.setStatusTip(self.tr( 'Manage the saved SSL certificates')) self.certificatesAct.setWhatsThis(self.tr( """Manage SSL Certificates...""" """

Opens a dialog to manage the saved SSL certificates.""" """

""" )) self.certificatesAct.triggered.connect( self.__showCertificatesDialog) self.actions.append(self.certificatesAct) self.editMessageFilterAct = E5Action( self.tr('Edit Message Filters'), UI.PixmapCache.getIcon("warning.png"), self.tr('Edit Message Filters...'), 0, 0, self, 'manage_message_filters') self.editMessageFilterAct.setStatusTip(self.tr( 'Edit the message filters used to suppress unwanted messages')) self.editMessageFilterAct.setWhatsThis(self.tr( """Edit Message Filters""" """

Opens a dialog to edit the message filters used to""" """ suppress unwanted messages been shown in an error""" """ window.

""" )) self.editMessageFilterAct.triggered.connect( E5ErrorMessage.editMessageFilters) self.actions.append(self.editMessageFilterAct) self.viewmanagerActivateAct = E5Action( self.tr('Activate current editor'), self.tr('Activate current editor'), QKeySequence(self.tr("Alt+Shift+E")), 0, self, 'viewmanager_activate', 1) self.viewmanagerActivateAct.triggered.connect( self.__activateViewmanager) self.actions.append(self.viewmanagerActivateAct) self.addAction(self.viewmanagerActivateAct) self.nextTabAct = E5Action( self.tr('Show next'), self.tr('Show next'), QKeySequence(self.tr('Ctrl+Alt+Tab')), 0, self, 'view_next_tab') self.nextTabAct.triggered.connect(self.__showNext) self.actions.append(self.nextTabAct) self.addAction(self.nextTabAct) self.prevTabAct = E5Action( self.tr('Show previous'), self.tr('Show previous'), QKeySequence(self.tr('Shift+Ctrl+Alt+Tab')), 0, self, 'view_previous_tab') self.prevTabAct.triggered.connect(self.__showPrevious) self.actions.append(self.prevTabAct) self.addAction(self.prevTabAct) self.switchTabAct = E5Action( self.tr('Switch between tabs'), self.tr('Switch between tabs'), QKeySequence(self.tr('Ctrl+1')), 0, self, 'switch_tabs') self.switchTabAct.triggered.connect(self.__switchTab) self.actions.append(self.switchTabAct) self.addAction(self.switchTabAct) self.pluginInfoAct = E5Action( self.tr('Plugin Infos'), UI.PixmapCache.getIcon("plugin.png"), self.tr('&Plugin Infos...'), 0, 0, self, 'plugin_infos') self.pluginInfoAct.setStatusTip(self.tr('Show Plugin Infos')) self.pluginInfoAct.setWhatsThis(self.tr( """Plugin Infos...""" """

This opens a dialog, that show some information about""" """ loaded plugins.

""" )) self.pluginInfoAct.triggered.connect(self.__showPluginInfo) self.actions.append(self.pluginInfoAct) self.pluginInstallAct = E5Action( self.tr('Install Plugins'), UI.PixmapCache.getIcon("pluginInstall.png"), self.tr('&Install Plugins...'), 0, 0, self, 'plugin_install') self.pluginInstallAct.setStatusTip(self.tr('Install Plugins')) self.pluginInstallAct.setWhatsThis(self.tr( """Install Plugins...""" """

This opens a dialog to install or update plugins.

""" )) self.pluginInstallAct.triggered.connect(self.__installPlugins) self.actions.append(self.pluginInstallAct) self.pluginDeinstallAct = E5Action( self.tr('Uninstall Plugin'), UI.PixmapCache.getIcon("pluginUninstall.png"), self.tr('&Uninstall Plugin...'), 0, 0, self, 'plugin_deinstall') self.pluginDeinstallAct.setStatusTip(self.tr('Uninstall Plugin')) self.pluginDeinstallAct.setWhatsThis(self.tr( """Uninstall Plugin...""" """

This opens a dialog to uninstall a plugin.

""" )) self.pluginDeinstallAct.triggered.connect(self.__deinstallPlugin) self.actions.append(self.pluginDeinstallAct) self.pluginRepoAct = E5Action( self.tr('Plugin Repository'), UI.PixmapCache.getIcon("pluginRepository.png"), self.tr('Plugin &Repository...'), 0, 0, self, 'plugin_repository') self.pluginRepoAct.setStatusTip(self.tr( 'Show Plugins available for download')) self.pluginRepoAct.setWhatsThis(self.tr( """Plugin Repository...""" """

This opens a dialog, that shows a list of plugins """ """available on the Internet.

""" )) self.pluginRepoAct.triggered.connect(self.showPluginsAvailable) self.actions.append(self.pluginRepoAct) # initialize viewmanager actions self.viewmanager.initActions() # initialize debugger actions self.debuggerUI.initActions() # initialize project actions self.project.initActions() # initialize multi project actions self.multiProject.initActions() def __initQtDocActions(self): """ Private slot to initialize the action to show the Qt documentation. """ self.qt4DocAct = E5Action( self.tr('Qt4 Documentation'), self.tr('Qt&4 Documentation'), 0, 0, self, 'qt4_documentation') self.qt4DocAct.setStatusTip(self.tr('Open Qt4 Documentation')) self.qt4DocAct.setWhatsThis(self.tr( """Qt4 Documentation""" """

Display the Qt4 Documentation. Dependent upon your""" """ settings, this will either show the help in Eric's internal""" """ help viewer, or execute a web browser or Qt Assistant.

""" )) self.qt4DocAct.triggered.connect(self.__showQt4Doc) self.actions.append(self.qt4DocAct) self.qt5DocAct = E5Action( self.tr('Qt5 Documentation'), self.tr('Qt&5 Documentation'), 0, 0, self, 'qt5_documentation') self.qt5DocAct.setStatusTip(self.tr('Open Qt5 Documentation')) self.qt5DocAct.setWhatsThis(self.tr( """Qt5 Documentation""" """

Display the Qt5 Documentation. Dependent upon your""" """ settings, this will either show the help in Eric's internal""" """ help viewer, or execute a web browser or Qt Assistant.

""" )) self.qt5DocAct.triggered.connect(self.__showQt5Doc) self.actions.append(self.qt5DocAct) try: import PyQt4 # __IGNORE_WARNING__ self.pyqt4DocAct = E5Action( self.tr('PyQt4 Documentation'), self.tr('PyQt&4 Documentation'), 0, 0, self, 'pyqt4_documentation') self.pyqt4DocAct.setStatusTip(self.tr('Open PyQt4 Documentation')) self.pyqt4DocAct.setWhatsThis(self.tr( """PyQt4 Documentation""" """

Display the PyQt4 Documentation. Dependent upon your""" """ settings, this will either show the help in Eric's""" """ internal help viewer, or execute a web browser or""" """ Qt Assistant.

""" )) self.pyqt4DocAct.triggered.connect(self.__showPyQt4Doc) self.actions.append(self.pyqt4DocAct) except ImportError: self.pyqt4DocAct = None try: import PyQt5 # __IGNORE_WARNING__ self.pyqt5DocAct = E5Action( self.tr('PyQt5 Documentation'), self.tr('PyQt&5 Documentation'), 0, 0, self, 'pyqt5_documentation') self.pyqt5DocAct.setStatusTip(self.tr( 'Open PyQt5 Documentation')) self.pyqt5DocAct.setWhatsThis(self.tr( """PyQt5 Documentation""" """

Display the PyQt5 Documentation. Dependent upon your""" """ settings, this will either show the help in Eric's""" """ internal help viewer, or execute a web browser or""" """ Qt Assistant.

""" )) self.pyqt5DocAct.triggered.connect(self.__showPyQt5Doc) self.actions.append(self.pyqt5DocAct) except ImportError: self.pyqt5DocAct = None def __initPythonDocActions(self): """ Private slot to initialize the actions to show the Python documentation. """ self.pythonDocAct = E5Action( self.tr('Python 3 Documentation'), self.tr('Python &3 Documentation'), 0, 0, self, 'python3_documentation') self.pythonDocAct.setStatusTip(self.tr( 'Open Python 3 Documentation')) self.pythonDocAct.setWhatsThis(self.tr( """Python 3 Documentation""" """

Display the Python 3 documentation. If no documentation""" """ directory is configured, the location of the Python 3""" """ documentation is assumed to be the doc directory underneath""" """ the location of the Python 3 executable on Windows and""" """ /usr/share/doc/packages/python/html on Unix. Set""" """ PYTHON3DOCDIR in your environment to override this.

""" )) self.pythonDocAct.triggered.connect(self.__showPythonDoc) self.actions.append(self.pythonDocAct) self.python2DocAct = E5Action( self.tr('Python 2 Documentation'), self.tr('Python &2 Documentation'), 0, 0, self, 'python2_documentation') self.python2DocAct.setStatusTip(self.tr( 'Open Python 2 Documentation')) self.python2DocAct.setWhatsThis(self.tr( """Python 2 Documentation""" """

Display the Python 2 documentation. If no documentation""" """ directory is configured, the location of the Python 2""" """ documentation is assumed to be the doc directory underneath""" """ the location of the configured Python 2 executable on""" """ Windows and""" """ /usr/share/doc/packages/python/html/python-docs-html""" """ on Unix. Set PYTHON2DOCDIR in your environment to override""" """ this.

""" )) self.python2DocAct.triggered.connect(self.__showPython2Doc) self.actions.append(self.python2DocAct) def __initEricDocAction(self): """ Private slot to initialize the action to show the eric6 documentation. """ self.ericDocAct = E5Action( self.tr("Eric API Documentation"), self.tr('&Eric API Documentation'), 0, 0, self, 'eric_documentation') self.ericDocAct.setStatusTip(self.tr( "Open Eric API Documentation")) self.ericDocAct.setWhatsThis(self.tr( """Eric API Documentation""" """

Display the Eric API documentation. The location for the""" """ documentation is the Documentation/Source subdirectory of""" """ the eric6 installation directory.

""" )) self.ericDocAct.triggered.connect(self.__showEricDoc) self.actions.append(self.ericDocAct) def __initPySideDocAction(self): """ Private slot to initialize the action to show the PySide documentation. """ pyside2, pyside3 = Utilities.checkPyside() if pyside2 or pyside3: self.pysideDocAct = E5Action( self.tr('PySide Documentation'), self.tr('Py&Side Documentation'), 0, 0, self, 'pyside_documentation') self.pysideDocAct.setStatusTip(self.tr( 'Open PySide Documentation')) self.pysideDocAct.setWhatsThis(self.tr( """PySide Documentation""" """

Display the PySide Documentation. Dependent upon your""" """ settings, this will either show the help in Eric's""" """ internal help viewer, or execute a web browser or""" """ Qt Assistant.

""" )) self.pysideDocAct.triggered.connect(self.__showPySideDoc) self.actions.append(self.pysideDocAct) else: self.pysideDocAct = None def __initMenus(self): """ Private slot to create the menus. """ self.__menus = {} mb = self.menuBar() self.__menus["file"] = self.viewmanager.initFileMenu() mb.addMenu(self.__menus["file"]) self.__menus["file"].addSeparator() self.__menus["file"].addAction(self.exitAct) act = self.__menus["file"].actions()[0] sep = self.__menus["file"].insertSeparator(act) self.__menus["file"].insertAction(sep, self.newWindowAct) self.__menus["file"].aboutToShow.connect(self.__showFileMenu) self.__menus["edit"] = self.viewmanager.initEditMenu() mb.addMenu(self.__menus["edit"]) self.__menus["view"] = self.viewmanager.initViewMenu() mb.addMenu(self.__menus["view"]) self.__menus["start"], self.__menus["debug"] = \ self.debuggerUI.initMenus() mb.addMenu(self.__menus["start"]) mb.addMenu(self.__menus["debug"]) self.__menus["unittest"] = QMenu(self.tr('&Unittest'), self) self.__menus["unittest"].setTearOffEnabled(True) mb.addMenu(self.__menus["unittest"]) self.__menus["unittest"].addAction(self.utDialogAct) self.__menus["unittest"].addSeparator() self.__menus["unittest"].addAction(self.utRestartAct) self.__menus["unittest"].addAction(self.utRerunFailedAct) self.__menus["unittest"].addSeparator() self.__menus["unittest"].addAction(self.utScriptAct) self.__menus["unittest"].addAction(self.utProjectAct) self.__menus["multiproject"] = self.multiProject.initMenu() mb.addMenu(self.__menus["multiproject"]) self.__menus["project"] = self.project.initMenu() mb.addMenu(self.__menus["project"]) self.__menus["extras"] = QMenu(self.tr('E&xtras'), self) self.__menus["extras"].setTearOffEnabled(True) self.__menus["extras"].aboutToShow.connect(self.__showExtrasMenu) mb.addMenu(self.__menus["extras"]) self.viewmanager.addToExtrasMenu(self.__menus["extras"]) self.__menus["wizards"] = QMenu(self.tr('Wi&zards'), self) self.__menus["wizards"].setTearOffEnabled(True) self.__menus["wizards"].aboutToShow.connect(self.__showWizardsMenu) self.wizardsMenuAct = self.__menus["extras"].addMenu( self.__menus["wizards"]) self.wizardsMenuAct.setEnabled(False) self.__menus["macros"] = self.viewmanager.initMacroMenu() self.__menus["extras"].addMenu(self.__menus["macros"]) self.__menus["tools"] = QMenu(self.tr('&Tools'), self) self.__menus["tools"].aboutToShow.connect(self.__showToolsMenu) self.__menus["tools"].triggered.connect(self.__toolExecute) self.toolGroupsMenu = QMenu(self.tr("Select Tool Group"), self) self.toolGroupsMenu.aboutToShow.connect(self.__showToolGroupsMenu) self.toolGroupsMenu.triggered.connect(self.__toolGroupSelected) self.toolGroupsMenuTriggered = False self.__menus["extras"].addMenu(self.__menus["tools"]) self.__menus["settings"] = QMenu(self.tr('Se&ttings'), self) mb.addMenu(self.__menus["settings"]) self.__menus["settings"].setTearOffEnabled(True) self.__menus["settings"].addAction(self.prefAct) self.__menus["settings"].addAction(self.prefExportAct) self.__menus["settings"].addAction(self.prefImportAct) self.__menus["settings"].addSeparator() self.__menus["settings"].addAction(self.reloadAPIsAct) self.__menus["settings"].addSeparator() self.__menus["settings"].addAction(self.configViewProfilesAct) self.__menus["settings"].addAction(self.configToolBarsAct) self.__menus["settings"].addSeparator() self.__menus["settings"].addAction(self.shortcutsAct) self.__menus["settings"].addAction(self.exportShortcutsAct) self.__menus["settings"].addAction(self.importShortcutsAct) self.__menus["settings"].addSeparator() self.__menus["settings"].addAction(self.showExternalToolsAct) if SSL_AVAILABLE: self.__menus["settings"].addSeparator() self.__menus["settings"].addAction(self.certificatesAct) self.__menus["settings"].addSeparator() self.__menus["settings"].addAction(self.editMessageFilterAct) self.__menus["window"] = QMenu(self.tr('&Window'), self) mb.addMenu(self.__menus["window"]) self.__menus["window"].setTearOffEnabled(True) self.__menus["window"].aboutToShow.connect(self.__showWindowMenu) self.__menus["subwindow"] = QMenu(self.tr("&Windows"), self.__menus["window"]) self.__menus["subwindow"].setTearOffEnabled(True) # left side self.__menus["subwindow"].addAction(self.pbActivateAct) self.__menus["subwindow"].addAction(self.mpbActivateAct) self.__menus["subwindow"].addAction(self.templateViewerActivateAct) self.__menus["subwindow"].addAction(self.browserActivateAct) self.__menus["subwindow"].addAction(self.symbolsViewerActivateAct) # bottom side self.__menus["subwindow"].addAction(self.shellActivateAct) self.__menus["subwindow"].addAction(self.taskViewerActivateAct) self.__menus["subwindow"].addAction(self.logViewerActivateAct) self.__menus["subwindow"].addAction(self.numbersViewerActivateAct) # right side self.__menus["subwindow"].addAction(self.debugViewerActivateAct) self.__menus["subwindow"].addAction(self.cooperationViewerActivateAct) self.__menus["subwindow"].addAction(self.ircActivateAct) self.__menus["toolbars"] = \ QMenu(self.tr("&Toolbars"), self.__menus["window"]) self.__menus["toolbars"].setTearOffEnabled(True) self.__menus["toolbars"].aboutToShow.connect(self.__showToolbarsMenu) self.__menus["toolbars"].triggered.connect(self.__TBMenuTriggered) self.__showWindowMenu() # to initialize these actions self.__menus["bookmarks"] = self.viewmanager.initBookmarkMenu() mb.addMenu(self.__menus["bookmarks"]) self.__menus["bookmarks"].setTearOffEnabled(True) self.__menus["plugins"] = QMenu(self.tr('P&lugins'), self) mb.addMenu(self.__menus["plugins"]) self.__menus["plugins"].setTearOffEnabled(True) self.__menus["plugins"].addAction(self.pluginInfoAct) self.__menus["plugins"].addAction(self.pluginInstallAct) self.__menus["plugins"].addAction(self.pluginDeinstallAct) self.__menus["plugins"].addSeparator() self.__menus["plugins"].addAction(self.pluginRepoAct) self.__menus["plugins"].addSeparator() self.__menus["plugins"].addAction( self.tr("Configure..."), self.__pluginsConfigure) mb.addSeparator() self.__menus["help"] = QMenu(self.tr('&Help'), self) mb.addMenu(self.__menus["help"]) self.__menus["help"].setTearOffEnabled(True) self.__menus["help"].addAction(self.helpviewerAct) self.__menus["help"].addSeparator() self.__menus["help"].addAction(self.ericDocAct) self.__menus["help"].addAction(self.pythonDocAct) self.__menus["help"].addAction(self.python2DocAct) self.__menus["help"].addAction(self.qt4DocAct) self.__menus["help"].addAction(self.qt5DocAct) if self.pyqt4DocAct is not None: self.__menus["help"].addAction(self.pyqt4DocAct) if self.pyqt5DocAct is not None: self.__menus["help"].addAction(self.pyqt5DocAct) if self.pysideDocAct is not None: self.__menus["help"].addAction(self.pysideDocAct) self.__menus["help"].addSeparator() self.__menus["help"].addAction(self.versionAct) self.__menus["help"].addSeparator() self.__menus["help"].addAction(self.checkUpdateAct) self.__menus["help"].addAction(self.showVersionsAct) self.__menus["help"].addSeparator() self.__menus["help"].addAction(self.showErrorLogAct) self.__menus["help"].addAction(self.reportBugAct) self.__menus["help"].addAction(self.requestFeatureAct) self.__menus["help"].addSeparator() self.__menus["help"].addAction(self.whatsThisAct) self.__menus["help"].aboutToShow.connect(self.__showHelpMenu) def getToolBarIconSize(self): """ Public method to get the toolbar icon size. @return toolbar icon size (QSize) """ return Config.ToolBarIconSize def __initToolbars(self): """ Private slot to create the toolbars. """ filetb = self.viewmanager.initFileToolbar(self.toolbarManager) edittb = self.viewmanager.initEditToolbar(self.toolbarManager) searchtb, quicksearchtb = self.viewmanager.initSearchToolbars( self.toolbarManager) viewtb = self.viewmanager.initViewToolbar(self.toolbarManager) starttb, debugtb = self.debuggerUI.initToolbars(self.toolbarManager) multiprojecttb = self.multiProject.initToolbar(self.toolbarManager) projecttb = self.project.initToolbar(self.toolbarManager) toolstb = QToolBar(self.tr("Tools"), self) unittesttb = QToolBar(self.tr("Unittest"), self) bookmarktb = self.viewmanager.initBookmarkToolbar(self.toolbarManager) spellingtb = self.viewmanager.initSpellingToolbar(self.toolbarManager) settingstb = QToolBar(self.tr("Settings"), self) helptb = QToolBar(self.tr("Help"), self) profilestb = QToolBar(self.tr("Profiles"), self) pluginstb = QToolBar(self.tr("Plugins"), self) toolstb.setIconSize(Config.ToolBarIconSize) unittesttb.setIconSize(Config.ToolBarIconSize) settingstb.setIconSize(Config.ToolBarIconSize) helptb.setIconSize(Config.ToolBarIconSize) profilestb.setIconSize(Config.ToolBarIconSize) pluginstb.setIconSize(Config.ToolBarIconSize) toolstb.setObjectName("ToolsToolbar") unittesttb.setObjectName("UnittestToolbar") settingstb.setObjectName("SettingsToolbar") helptb.setObjectName("HelpToolbar") profilestb.setObjectName("ProfilesToolbar") pluginstb.setObjectName("PluginsToolbar") toolstb.setToolTip(self.tr("Tools")) unittesttb.setToolTip(self.tr("Unittest")) settingstb.setToolTip(self.tr("Settings")) helptb.setToolTip(self.tr("Help")) profilestb.setToolTip(self.tr("Profiles")) pluginstb.setToolTip(self.tr("Plugins")) filetb.addSeparator() filetb.addAction(self.exitAct) act = filetb.actions()[0] sep = filetb.insertSeparator(act) filetb.insertAction(sep, self.newWindowAct) self.toolbarManager.addToolBar(filetb, filetb.windowTitle()) # setup the unittest toolbar unittesttb.addAction(self.utDialogAct) unittesttb.addSeparator() unittesttb.addAction(self.utRestartAct) unittesttb.addAction(self.utRerunFailedAct) unittesttb.addSeparator() unittesttb.addAction(self.utScriptAct) unittesttb.addAction(self.utProjectAct) self.toolbarManager.addToolBar(unittesttb, unittesttb.windowTitle()) # setup the tools toolbar if self.designer4Act is not None: toolstb.addAction(self.designer4Act) if self.linguist4Act is not None: toolstb.addAction(self.linguist4Act) toolstb.addAction(self.uipreviewerAct) toolstb.addAction(self.trpreviewerAct) toolstb.addSeparator() toolstb.addAction(self.diffAct) toolstb.addAction(self.compareAct) toolstb.addSeparator() toolstb.addAction(self.sqlBrowserAct) toolstb.addSeparator() toolstb.addAction(self.miniEditorAct) toolstb.addAction(self.iconEditorAct) toolstb.addAction(self.snapshotAct) toolstb.addSeparator() toolstb.addAction(self.webBrowserAct) self.toolbarManager.addToolBar(toolstb, toolstb.windowTitle()) # setup the settings toolbar settingstb.addAction(self.prefAct) settingstb.addAction(self.configViewProfilesAct) settingstb.addAction(self.configToolBarsAct) settingstb.addAction(self.shortcutsAct) settingstb.addAction(self.showExternalToolsAct) self.toolbarManager.addToolBar(settingstb, settingstb.windowTitle()) self.toolbarManager.addAction( self.exportShortcutsAct, settingstb.windowTitle()) self.toolbarManager.addAction( self.importShortcutsAct, settingstb.windowTitle()) # setup the help toolbar helptb.addAction(self.whatsThisAct) self.toolbarManager.addToolBar(helptb, helptb.windowTitle()) self.toolbarManager.addAction(self.helpviewerAct, helptb.windowTitle()) # setup the view profiles toolbar profilestb.addActions(self.viewProfileActGrp.actions()) self.toolbarManager.addToolBar(profilestb, profilestb.windowTitle()) # setup the plugins toolbar pluginstb.addAction(self.pluginInfoAct) pluginstb.addAction(self.pluginInstallAct) pluginstb.addAction(self.pluginDeinstallAct) pluginstb.addSeparator() pluginstb.addAction(self.pluginRepoAct) self.toolbarManager.addToolBar(pluginstb, pluginstb.windowTitle()) # add the various toolbars self.addToolBar(filetb) self.addToolBar(edittb) self.addToolBar(searchtb) self.addToolBar(quicksearchtb) self.addToolBar(viewtb) self.addToolBar(starttb) self.addToolBar(debugtb) self.addToolBar(multiprojecttb) self.addToolBar(projecttb) self.addToolBar(Qt.RightToolBarArea, settingstb) self.addToolBar(Qt.RightToolBarArea, toolstb) self.addToolBar(helptb) self.addToolBar(bookmarktb) self.addToolBar(spellingtb) self.addToolBar(unittesttb) self.addToolBar(profilestb) self.addToolBar(pluginstb) # hide toolbars not wanted in the initial layout searchtb.hide() quicksearchtb.hide() viewtb.hide() debugtb.hide() multiprojecttb.hide() helptb.hide() spellingtb.hide() unittesttb.hide() pluginstb.hide() # just add new toolbars to the end of the list self.__toolbars = {} self.__toolbars["file"] = [filetb.windowTitle(), filetb] self.__toolbars["edit"] = [edittb.windowTitle(), edittb] self.__toolbars["search"] = [searchtb.windowTitle(), searchtb] self.__toolbars["view"] = [viewtb.windowTitle(), viewtb] self.__toolbars["start"] = [starttb.windowTitle(), starttb] self.__toolbars["debug"] = [debugtb.windowTitle(), debugtb] self.__toolbars["project"] = [projecttb.windowTitle(), projecttb] self.__toolbars["tools"] = [toolstb.windowTitle(), toolstb] self.__toolbars["help"] = [helptb.windowTitle(), helptb] self.__toolbars["settings"] = [settingstb.windowTitle(), settingstb] self.__toolbars["bookmarks"] = [bookmarktb.windowTitle(), bookmarktb] self.__toolbars["unittest"] = [unittesttb.windowTitle(), unittesttb] self.__toolbars["view_profiles"] = [profilestb.windowTitle(), profilestb] self.__toolbars["plugins"] = [pluginstb.windowTitle(), pluginstb] self.__toolbars["quicksearch"] = [quicksearchtb.windowTitle(), quicksearchtb] self.__toolbars["multiproject"] = [multiprojecttb.windowTitle(), multiprojecttb] self.__toolbars["spelling"] = [spellingtb.windowTitle(), spellingtb] def __initDebugToolbarsLayout(self): """ Private slot to initialize the toolbars layout for the debug profile. """ # Step 1: set the edit profile to be sure self.__setEditProfile() # Step 2: switch to debug profile and do the layout initSize = self.size() self.setDebugProfile() self.__toolbars["project"][1].hide() self.__toolbars["debug"][1].show() self.resize(initSize) # Step 3: switch back to edit profile self.__setEditProfile() def __initStatusbar(self): """ Private slot to set up the status bar. """ self.__statusBar = self.statusBar() self.__statusBar.setSizeGripEnabled(True) self.sbLanguage = E5ClickableLabel(self.__statusBar) self.__statusBar.addPermanentWidget(self.sbLanguage) self.sbLanguage.setWhatsThis(self.tr( """

This part of the status bar displays the""" """ current editors language.

""" )) self.sbEncoding = E5ClickableLabel(self.__statusBar) self.__statusBar.addPermanentWidget(self.sbEncoding) self.sbEncoding.setWhatsThis(self.tr( """

This part of the status bar displays the""" """ current editors encoding.

""" )) self.sbEol = E5ClickableLabel(self.__statusBar) self.__statusBar.addPermanentWidget(self.sbEol) self.sbEol.setWhatsThis(self.tr( """

This part of the status bar displays the""" """ current editors eol setting.

""" )) self.sbWritable = QLabel(self.__statusBar) self.__statusBar.addPermanentWidget(self.sbWritable) self.sbWritable.setWhatsThis(self.tr( """

This part of the status bar displays an indication of the""" """ current editors files writability.

""" )) self.sbLine = QLabel(self.__statusBar) self.__statusBar.addPermanentWidget(self.sbLine) self.sbLine.setWhatsThis(self.tr( """

This part of the status bar displays the line number of""" """ the current editor.

""" )) self.sbPos = QLabel(self.__statusBar) self.__statusBar.addPermanentWidget(self.sbPos) self.sbPos.setWhatsThis(self.tr( """

This part of the status bar displays the cursor position""" """ of the current editor.

""" )) self.sbZoom = E5ZoomWidget( UI.PixmapCache.getPixmap("zoomOut.png"), UI.PixmapCache.getPixmap("zoomIn.png"), UI.PixmapCache.getPixmap("zoomReset.png"), self.__statusBar) self.__statusBar.addPermanentWidget(self.sbZoom) self.sbZoom.setWhatsThis(self.tr( """

This part of the status bar allows zooming the current""" """ editor, shell or terminal.

""" )) self.viewmanager.setSbInfo( self.sbLine, self.sbPos, self.sbWritable, self.sbEncoding, self.sbLanguage, self.sbEol, self.sbZoom) from VCS.StatusMonitorLed import StatusMonitorLed self.sbVcsMonitorLed = StatusMonitorLed(self.project, self.__statusBar) self.__statusBar.addPermanentWidget(self.sbVcsMonitorLed) def __initExternalToolsActions(self): """ Private slot to create actions for the configured external tools. """ self.toolGroupActions = {} for toolGroup in self.toolGroups: category = self.tr("External Tools/{0}").format(toolGroup[0]) for tool in toolGroup[1]: if tool['menutext'] != '--': act = QAction(UI.PixmapCache.getIcon(tool['icon']), tool['menutext'], self) act.setObjectName("{0}@@{1}".format(toolGroup[0], tool['menutext'])) act.triggered.connect(self.__toolActionTriggered) self.toolGroupActions[act.objectName()] = act self.toolbarManager.addAction(act, category) def __updateExternalToolsActions(self): """ Private method to update the external tools actions for the current tool group. """ toolGroup = self.toolGroups[self.currentToolGroup] groupkey = "{0}@@".format(toolGroup[0]) groupActionKeys = [] # step 1: get actions for this group for key in self.toolGroupActions: if key.startswith(groupkey): groupActionKeys.append(key) # step 2: build keys for all actions i.a.w. current configuration ckeys = [] for tool in toolGroup[1]: if tool['menutext'] != '--': ckeys.append("{0}@@{1}".format(toolGroup[0], tool['menutext'])) # step 3: remove all actions not configured any more for key in groupActionKeys: if key not in ckeys: self.toolbarManager.removeAction(self.toolGroupActions[key]) self.toolGroupActions[key].triggered.disconnect( self.__toolActionTriggered) del self.toolGroupActions[key] # step 4: add all newly configured tools category = self.tr("External Tools/{0}").format(toolGroup[0]) for tool in toolGroup[1]: if tool['menutext'] != '--': key = "{0}@@{1}".format(toolGroup[0], tool['menutext']) if key not in groupActionKeys: act = QAction(UI.PixmapCache.getIcon(tool['icon']), tool['menutext'], self) act.setObjectName(key) act.triggered.connect(self.__toolActionTriggered) self.toolGroupActions[key] = act self.toolbarManager.addAction(act, category) def __showFileMenu(self): """ Private slot to display the File menu. """ self.showMenu.emit("File", self.__menus["file"]) def __showExtrasMenu(self): """ Private slot to display the Extras menu. """ self.showMenu.emit("Extras", self.__menus["extras"]) def __showWizardsMenu(self): """ Private slot to display the Wizards menu. """ self.showMenu.emit("Wizards", self.__menus["wizards"]) def __showHelpMenu(self): """ Private slot to display the Help menu. """ self.checkUpdateAct.setEnabled(not self.__inVersionCheck) self.showVersionsAct.setEnabled(not self.__inVersionCheck) self.showErrorLogAct.setEnabled(self.__hasErrorLog()) self.showMenu.emit("Help", self.__menus["help"]) def __showSettingsMenu(self): """ Private slot to show the Settings menu. """ self.editMessageFilterAct.setEnabled( E5ErrorMessage.messageHandlerInstalled()) self.showMenu.emit("Settings", self.__menus["settings"]) def __showNext(self): """ Private slot used to show the next tab or file. """ fwidget = QApplication.focusWidget() while fwidget and not hasattr(fwidget, 'nextTab'): fwidget = fwidget.parent() if fwidget: fwidget.nextTab() def __showPrevious(self): """ Private slot used to show the previous tab or file. """ fwidget = QApplication.focusWidget() while fwidget and not hasattr(fwidget, 'prevTab'): fwidget = fwidget.parent() if fwidget: fwidget.prevTab() def __switchTab(self): """ Private slot used to switch between the current and the previous current tab. """ fwidget = QApplication.focusWidget() while fwidget and not hasattr(fwidget, 'switchTab'): fwidget = fwidget.parent() if fwidget: fwidget.switchTab() def __whatsThis(self): """ Private slot called in to enter Whats This mode. """ QWhatsThis.enterWhatsThisMode() def __showVersions(self): """ Private slot to handle the Versions dialog. """ try: import sipconfig sip_version_str = sipconfig.Configuration().sip_version_str except ImportError: sip_version_str = "sip version not available" versionText = self.tr( """

Version Numbers

""" """""") versionText += """"""\ .format(sys.version.split()[0]) versionText += """"""\ .format(qVersion()) versionText += """"""\ .format(PYQT_VERSION_STR) versionText += """"""\ .format(sip_version_str) versionText += """"""\ .format(QSCINTILLA_VERSION_STR) try: from PyQt5.QtWebKit import qWebKitVersion versionText += """"""\ .format(qWebKitVersion()) except ImportError: pass versionText += """"""\ .format(Program, Version) versionText += self.tr("""
Python{0}
Qt{0}
PyQt{0}
sip{0}
QScintilla{0}
WebKit{0}
{0}{1}
""") E5MessageBox.about(self, Program, versionText) def __reportBug(self): """ Private slot to handle the Report Bug dialog. """ self.showEmailDialog("bug") def __requestFeature(self): """ Private slot to handle the Feature Request dialog. """ self.showEmailDialog("feature") def showEmailDialog(self, mode, attachFile=None, deleteAttachFile=False): """ Public slot to show the email dialog in a given mode. @param mode mode of the email dialog (string, "bug" or "feature") @param attachFile name of a file to attach to the email (string) @param deleteAttachFile flag indicating to delete the attached file after it has been sent (boolean) """ if Preferences.getUser("UseSystemEmailClient"): self.__showSystemEmailClient(mode, attachFile, deleteAttachFile) else: if Preferences.getUser("Email") == "" or \ Preferences.getUser("MailServer") == "": E5MessageBox.critical( self, self.tr("Report Bug"), self.tr( """Email address or mail server address is empty.""" """ Please configure your Email settings in the""" """ Preferences Dialog.""")) self.showPreferences("emailPage") return from .EmailDialog import EmailDialog self.dlg = EmailDialog(mode=mode) if attachFile is not None: self.dlg.attachFile(attachFile, deleteAttachFile) self.dlg.show() def __showSystemEmailClient(self, mode, attachFile=None, deleteAttachFile=False): """ Private slot to show the system email dialog. @param mode mode of the email dialog (string, "bug" or "feature") @param attachFile name of a file to put into the body of the email (string) @param deleteAttachFile flag indicating to delete the file after it has been read (boolean) """ if mode == "feature": address = FeatureAddress else: address = BugAddress subject = "[eric6] " if attachFile is not None: f = open(attachFile, "r", encoding="utf-8") body = f.read() f.close() if deleteAttachFile: os.remove(attachFile) else: body = "\r\n----\r\n{0}----\r\n{1}----\r\n{2}".format( Utilities.generateVersionInfo("\r\n"), Utilities.generatePluginsVersionInfo("\r\n"), Utilities.generateDistroInfo("\r\n")) url = QUrl("mailto:{0}".format(address)) if qVersion() >= "5.0.0": from PyQt5.QtCore import QUrlQuery urlQuery = QUrlQuery(url) urlQuery.addQueryItem("subject", subject) urlQuery.addQueryItem("body", body) url.setQuery(urlQuery) else: url.addQueryItem("subject", subject) url.addQueryItem("body", body) QDesktopServices.openUrl(url) def checkForErrorLog(self): """ Public method to check for the presence of an error log and ask the user, what to do with it. """ if Preferences.getUI("CheckErrorLog"): logFile = os.path.join(Utilities.getConfigDir(), self.ErrorLogFileName) if os.path.exists(logFile): from .ErrorLogDialog import ErrorLogDialog dlg = ErrorLogDialog(logFile, False, self) dlg.exec_() def __hasErrorLog(self): """ Private method to check, if an error log file exists. @return flag indicating the existence of an error log file (boolean) """ logFile = os.path.join(Utilities.getConfigDir(), self.ErrorLogFileName) return os.path.exists(logFile) def __showErrorLog(self): """ Private slot to show the most recent error log message. """ logFile = os.path.join(Utilities.getConfigDir(), self.ErrorLogFileName) if os.path.exists(logFile): from .ErrorLogDialog import ErrorLogDialog dlg = ErrorLogDialog(logFile, True, self) dlg.show() def __compareFiles(self): """ Private slot to handle the Compare Files dialog. """ aw = self.viewmanager.activeWindow() fn = aw and aw.getFileName() or None if self.diffDlg is None: from .DiffDialog import DiffDialog self.diffDlg = DiffDialog() self.diffDlg.show(fn) def __compareFilesSbs(self): """ Private slot to handle the Compare Files dialog. """ aw = self.viewmanager.activeWindow() fn = aw and aw.getFileName() or None if self.compareDlg is None: from .CompareDialog import CompareDialog self.compareDlg = CompareDialog() self.compareDlg.show(fn) def __openMiniEditor(self): """ Private slot to show a mini editor window. """ from QScintilla.MiniEditor import MiniEditor editor = MiniEditor(parent=self) editor.show() def addE5Actions(self, actions, type): """ Public method to add actions to the list of actions. @param actions list of actions to be added (list of E5Action) @param type string denoting the action set to get. It must be one of "ui" or "wizards". """ if type == 'ui': self.actions.extend(actions) elif type == 'wizards': self.wizardsActions.extend(actions) def removeE5Actions(self, actions, type='ui'): """ Public method to remove actions from the list of actions. @param actions list of actions (list of E5Action) @param type string denoting the action set to get. It must be one of "ui" or "wizards". """ for act in actions: try: if type == 'ui': self.actions.remove(act) elif type == 'wizards': self.wizardsActions.remove(act) except ValueError: pass def getActions(self, type): """ Public method to get a list of all actions. @param type string denoting the action set to get. It must be one of "ui" or "wizards". @return list of all actions (list of E5Action) """ if type == 'ui': return self.actions[:] elif type == 'wizards': return self.wizardsActions[:] else: return [] def getMenuAction(self, menuName, actionName): """ Public method to get a reference to an action of a menu. @param menuName name of the menu to search in (string) @param actionName object name of the action to search for (string) @return reference to the menu action (QAction) """ try: menu = self.__menus[menuName] except KeyError: return None for act in menu.actions(): if act.objectName() == actionName: return act return None def getMenuBarAction(self, menuName): """ Public method to get a reference to an action of the main menu. @param menuName name of the menu to search in (string) @return reference to the menu bar action (QAction) """ try: menu = self.__menus[menuName] except KeyError: return None return menu.menuAction() def getMenu(self, name): """ Public method to get a reference to a specific menu. @param name name of the menu (string) @return reference to the menu (QMenu) """ try: return self.__menus[name] except KeyError: return None def registerToolbar(self, name, text, toolbar): """ Public method to register a toolbar. This method must be called in order to make a toolbar manageable by the UserInterface object. @param name name of the toolbar (string). This is used as the key into the dictionary of toolbar references. @param text user visible text for the toolbar entry (string) @param toolbar reference to the toolbar to be registered (QToolBar) @exception KeyError raised, if a toolbar with the given name was already registered """ if name in self.__toolbars: raise KeyError("Toolbar '{0}' already registered.".format(name)) self.__toolbars[name] = [text, toolbar] def reregisterToolbar(self, name, text): """ Public method to change the visible text for the named toolbar. @param name name of the toolbar to be changed (string) @param text new user visible text for the toolbar entry (string) """ if name in self.__toolbars: self.__toolbars[name][0] = text def unregisterToolbar(self, name): """ Public method to unregister a toolbar. @param name name of the toolbar (string). """ if name in self.__toolbars: del self.__toolbars[name] def getToolbar(self, name): """ Public method to get a reference to a specific toolbar. @param name name of the toolbar (string) @return reference to the toolbar entry (tuple of string and QToolBar) """ try: return self.__toolbars[name] except KeyError: return None def getLocale(self): """ Public method to get the locale of the IDE. @return locale of the IDE (string or None) """ return self.locale def __quit(self): """ Private method to quit the application. """ if self.__shutdown(): e5App().closeAllWindows() def __restart(self): """ Private method to restart the application. """ res = E5MessageBox.yesNo( self, self.tr("Restart application"), self.tr( """The application needs to be restarted. Do it now?"""), yesDefault=True) if res and self.__shutdown(): e5App().closeAllWindows() program = sys.executable eric6 = os.path.join(getConfig("ericDir"), "eric6.py") args = [eric6] args.append("--start-session") args.extend(self.__restartArgs) QProcess.startDetached(program, args) def __newWindow(self): """ Private slot to start a new instance of eric6. """ if not Preferences.getUI("SingleApplicationMode"): # start eric6 without any arguments program = sys.executable eric6 = os.path.join(getConfig("ericDir"), "eric6.py") args = [eric6] QProcess.startDetached(program, args) def __showToolsMenu(self): """ Private slot to display the Tools menu. """ self.__menus["tools"].clear() self.__menus["tools"].addMenu(self.toolGroupsMenu) act = self.__menus["tools"].addAction( self.tr("Configure Tool Groups ..."), self.__toolGroupsConfiguration) act.setData(-1) act = self.__menus["tools"].addAction( self.tr("Configure current Tool Group ..."), self.__toolsConfiguration) act.setData(-2) self.__menus["tools"].addSeparator() if self.currentToolGroup == -1: act.setEnabled(False) # add the default entries if self.designer4Act is not None: self.__menus["tools"].addAction(self.designer4Act) if self.linguist4Act is not None: self.__menus["tools"].addAction(self.linguist4Act) self.__menus["tools"].addAction(self.uipreviewerAct) self.__menus["tools"].addAction(self.trpreviewerAct) self.__menus["tools"].addAction(self.diffAct) self.__menus["tools"].addAction(self.compareAct) self.__menus["tools"].addAction(self.sqlBrowserAct) self.__menus["tools"].addAction(self.miniEditorAct) self.__menus["tools"].addAction(self.iconEditorAct) self.__menus["tools"].addAction(self.snapshotAct) self.__menus["tools"].addAction(self.webBrowserAct) elif self.currentToolGroup == -2: act.setEnabled(False) # add the plugin entries self.showMenu.emit("Tools", self.__menus["tools"]) else: # add the configurable entries idx = 0 try: for tool in self.toolGroups[self.currentToolGroup][1]: if tool['menutext'] == '--': self.__menus["tools"].addSeparator() else: act = self.__menus["tools"].addAction( UI.PixmapCache.getIcon(tool['icon']), tool['menutext']) act.setData(idx) idx += 1 except IndexError: # the current tool group might have been deleted pass def __showToolGroupsMenu(self): """ Private slot to display the Tool Groups menu. """ self.toolGroupsMenu.clear() # add the default entry act = self.toolGroupsMenu.addAction(self.tr("&Builtin Tools")) act.setData(-1) if self.currentToolGroup == -1: font = act.font() font.setBold(True) act.setFont(font) # add the plugins entry act = self.toolGroupsMenu.addAction(self.tr("&Plugin Tools")) act.setData(-2) if self.currentToolGroup == -2: font = act.font() font.setBold(True) act.setFont(font) # add the configurable tool groups idx = 0 for toolGroup in self.toolGroups: act = self.toolGroupsMenu.addAction(toolGroup[0]) act.setData(idx) if self.currentToolGroup == idx: font = act.font() font.setBold(True) act.setFont(font) idx += 1 def __toolGroupSelected(self, act): """ Private slot to set the current tool group. @param act reference to the action that was triggered (QAction) """ self.toolGroupsMenuTriggered = True idx = act.data() if idx is not None: self.currentToolGroup = idx def __showWindowMenu(self): """ Private slot to display the Window menu. """ self.__menus["window"].clear() self.__menus["window"].addActions(self.viewProfileActGrp.actions()) self.__menus["window"].addSeparator() if self.layout == "Toolboxes": self.__menus["window"].addAction(self.ltAct) self.ltAct.setChecked(not self.lToolboxDock.isHidden()) self.__menus["window"].addAction(self.rtAct) self.rtAct.setChecked(not self.lToolboxDock.isHidden()) self.__menus["window"].addAction(self.htAct) self.htAct.setChecked(not self.hToolboxDock.isHidden()) elif self.layout == "Sidebars": self.__menus["window"].addAction(self.lsbAct) self.lsbAct.setChecked(not self.leftSidebar.isHidden()) self.__menus["window"].addAction(self.rsbAct) self.rsbAct.setChecked(not self.rightSidebar.isHidden()) self.__menus["window"].addAction(self.bsbAct) self.bsbAct.setChecked(not self.bottomSidebar.isHidden()) # Insert menu entry for sub-windows self.__menus["window"].addSeparator() self.__menus["window"].addMenu(self.__menus["subwindow"]) # Insert menu entry for toolbar settings self.__menus["window"].addSeparator() self.__menus["window"].addMenu(self.__menus["toolbars"]) # Now do any Source Viewer related stuff. self.viewmanager.showWindowMenu(self.__menus["window"]) self.showMenu.emit("Window", self.__menus["window"]) def __showSubWindowMenu(self): """ Private slot to display the Window menu of the Window menu. """ self.showMenu.emit("Subwindows", self.__menus["subwindow"]) def __showToolbarsMenu(self): """ Private slot to display the Toolbars menu. """ self.__menus["toolbars"].clear() tbList = [] for name, (text, tb) in list(self.__toolbars.items()): tbList.append((text, tb, name)) tbList.sort() for text, tb, name in tbList: act = self.__menus["toolbars"].addAction(text) act.setCheckable(True) act.setData(name) act.setChecked(not tb.isHidden()) self.__menus["toolbars"].addSeparator() self.__toolbarsShowAllAct = \ self.__menus["toolbars"].addAction(self.tr("&Show all")) self.__toolbarsHideAllAct = \ self.__menus["toolbars"].addAction(self.tr("&Hide all")) def __TBMenuTriggered(self, act): """ Private method to handle the toggle of a toolbar. @param act reference to the action that was triggered (QAction) """ if act == self.__toolbarsShowAllAct: for text, tb in list(self.__toolbars.values()): tb.show() if self.__menus["toolbars"].isTearOffMenuVisible(): self.__showToolbarsMenu() elif act == self.__toolbarsHideAllAct: for text, tb in list(self.__toolbars.values()): tb.hide() if self.__menus["toolbars"].isTearOffMenuVisible(): self.__showToolbarsMenu() else: name = act.data() if name: tb = self.__toolbars[name][1] if act.isChecked(): tb.show() else: tb.hide() def __saveCurrentViewProfile(self, save): """ Private slot to save the window geometries of the active profile. @param save flag indicating that the current profile should be saved (boolean) """ if self.currentProfile and save: # step 1: save the window geometries of the active profile if self.layout in ["Toolboxes", "Sidebars"]: state = self.saveState() self.profiles[self.currentProfile][0] = state if self.layout == "Sidebars": state = self.leftSplitter.saveState() self.profiles[self.currentProfile][2][0] = state state = self.verticalSplitter.saveState() self.profiles[self.currentProfile][2][1] = state state = self.leftSidebar.saveState() self.profiles[self.currentProfile][2][2] = state state = self.bottomSidebar.saveState() self.profiles[self.currentProfile][2][3] = state state = self.rightSplitter.saveState() self.profiles[self.currentProfile][2][4] = state state = self.rightSidebar.saveState() self.profiles[self.currentProfile][2][5] = state # step 2: save the visibility of the windows of the active profile if self.layout == "Toolboxes": self.profiles[self.currentProfile][1][0] = \ self.lToolboxDock.isVisible() self.profiles[self.currentProfile][1][1] = \ self.hToolboxDock.isVisible() self.profiles[self.currentProfile][1][2] = \ self.rToolboxDock.isVisible() elif self.layout == "Sidebars": self.profiles[self.currentProfile][1][0] = \ self.leftSidebar.isVisible() self.profiles[self.currentProfile][1][1] = \ self.bottomSidebar.isVisible() self.profiles[self.currentProfile][1][2] = \ self.rightSidebar.isVisible() Preferences.setUI("ViewProfiles2", self.profiles) def __activateViewProfile(self, name, save=True): """ Private slot to activate a view profile. @param name name of the profile to be activated (string) @param save flag indicating that the current profile should be saved (boolean) """ if self.currentProfile != name or not save: # step 1: save the active profile self.__saveCurrentViewProfile(save) # step 2: set the window geometries of the new profile if self.layout in ["Toolboxes", "Sidebars"]: state = self.profiles[name][0] if not state.isEmpty(): self.restoreState(state) if self.layout == "Sidebars": state = self.profiles[name][2][0] if not state.isEmpty(): self.leftSplitter.restoreState(state) state = self.profiles[name][2][1] if not state.isEmpty(): self.verticalSplitter.restoreState(state) state = self.profiles[name][2][2] if not state.isEmpty(): self.leftSidebar.restoreState(state) state = self.profiles[name][2][3] if not state.isEmpty(): self.bottomSidebar.restoreState(state) state = self.profiles[name][2][4] if not state.isEmpty(): self.rightSplitter.restoreState(state) state = self.profiles[name][2][5] if not state.isEmpty(): self.rightSidebar.restoreState(state) self.__configureDockareaCornerUsage() # step 3: activate the windows of the new profile if self.layout == "Toolboxes": self.lToolboxDock.setVisible(self.profiles[name][1][0]) self.hToolboxDock.setVisible(self.profiles[name][1][1]) self.rToolboxDock.setVisible(self.profiles[name][1][2]) elif self.layout == "Sidebars": self.leftSidebar.setVisible(self.profiles[name][1][0]) self.bottomSidebar.setVisible(self.profiles[name][1][1]) self.rightSidebar.setVisible(self.profiles[name][1][2]) # step 4: remember the new profile self.currentProfile = name # step 5: make sure that cursor of the shell is visible self.shell.ensureCursorVisible() # step 6: make sure, that the toolbars and window menu are # shown correctly if self.__menus["toolbars"].isTearOffMenuVisible(): self.__showToolbarsMenu() if self.__menus["window"].isTearOffMenuVisible(): self.__showWindowMenu() def __debuggingStarted(self): """ Private slot to handle the start of a debugging session. """ self.setDebugProfile() if self.layout == "Toolboxes": self.__currentRightWidget = self.rToolbox.currentWidget() self.rToolbox.setCurrentWidget(self.debugViewer) if not self.embeddedShell: self.__currentBottomWidget = self.hToolbox.currentWidget() self.hToolbox.setCurrentWidget(self.shellAssembly) elif self.layout == "Sidebars": self.__currentRightWidget = self.rightSidebar.currentWidget() self.rightSidebar.setCurrentWidget(self.debugViewer) if not self.embeddedShell: self.__currentBottomWidget = self.bottomSidebar.currentWidget() self.bottomSidebar.setCurrentWidget(self.shellAssembly) def __debuggingDone(self): """ Private slot to handle the end of a debugging session. """ self.__setEditProfile() if self.layout == "Toolboxes": if self.__currentRightWidget: self.rToolbox.setCurrentWidget(self.__currentRightWidget) if self.__currentBottomWidget: self.hToolbox.setCurrentWidget(self.__currentBottomWidget) elif self.layout == "Sidebars": if self.__currentRightWidget: self.rightSidebar.setCurrentWidget(self.__currentRightWidget) if self.__currentBottomWidget: self.bottomSidebar.setCurrentWidget(self.__currentBottomWidget) self.__currentRightWidget = None self.__currentBottomWidget = None self.__activateViewmanager() @pyqtSlot() def __setEditProfile(self, save=True): """ Private slot to activate the edit view profile. @param save flag indicating that the current profile should be saved (boolean) """ self.__activateViewProfile("edit", save) self.setEditProfileAct.setChecked(True) @pyqtSlot() def setDebugProfile(self, save=True): """ Public slot to activate the debug view profile. @param save flag indicating that the current profile should be saved (boolean) """ self.viewmanager.searchWidget().hide() self.viewmanager.replaceWidget().hide() self.__activateViewProfile("debug", save) self.setDebugProfileAct.setChecked(True) def getViewProfile(self): """ Public method to get the current view profile. @return the name of the current view profile (string) """ return self.currentProfile def __activateProjectBrowser(self): """ Private slot to handle the activation of the project browser. """ if self.layout == "Toolboxes": self.lToolboxDock.show() self.lToolbox.setCurrentWidget(self.projectBrowser) elif self.layout == "Sidebars": self.leftSidebar.show() self.leftSidebar.setCurrentWidget(self.projectBrowser) else: self.projectBrowser.show() self.projectBrowser.currentWidget().setFocus( Qt.ActiveWindowFocusReason) def __activateMultiProjectBrowser(self): """ Private slot to handle the activation of the project browser. """ if self.layout == "Toolboxes": self.lToolboxDock.show() self.lToolbox.setCurrentWidget(self.multiProjectBrowser) elif self.layout == "Sidebars": self.leftSidebar.show() self.leftSidebar.setCurrentWidget(self.multiProjectBrowser) else: self.multiProjectBrowser.show() self.multiProjectBrowser.setFocus(Qt.ActiveWindowFocusReason) def __activateDebugViewer(self): """ Private slot to handle the activation of the debug viewer. """ if self.layout == "Toolboxes": self.rToolboxDock.show() self.rToolbox.setCurrentWidget(self.debugViewer) elif self.layout == "Sidebars": self.rightSidebar.show() self.rightSidebar.setCurrentWidget(self.debugViewer) else: self.debugViewer.show() self.debugViewer.currentWidget().setFocus(Qt.ActiveWindowFocusReason) def __activateShell(self): """ Private slot to handle the activation of the Shell window. """ if self.embeddedShell: # embedded in debug browser if self.layout == "Toolboxes": self.rToolboxDock.show() self.rToolbox.setCurrentWidget(self.debugViewer) elif self.layout == "Sidebars": self.rightSidebar.show() self.rightSidebar.setCurrentWidget(self.debugViewer) else: self.debugViewer.show() self.debugViewer.setCurrentWidget(self.shellAssembly) else: # separate window if self.layout == "Toolboxes": self.hToolboxDock.show() self.hToolbox.setCurrentWidget(self.shellAssembly) elif self.layout == "Sidebars": self.bottomSidebar.show() self.bottomSidebar.setCurrentWidget(self.shellAssembly) else: self.shell.show() self.shell.setFocus(Qt.ActiveWindowFocusReason) def __activateLogViewer(self): """ Private slot to handle the activation of the Log Viewer. """ if self.layout == "Toolboxes": self.hToolboxDock.show() self.hToolbox.setCurrentWidget(self.logViewer) elif self.layout == "Sidebars": self.bottomSidebar.show() self.bottomSidebar.setCurrentWidget(self.logViewer) else: self.logViewer.show() self.logViewer.setFocus(Qt.ActiveWindowFocusReason) def __activateTaskViewer(self): """ Private slot to handle the activation of the Task Viewer. """ if self.layout == "Toolboxes": self.hToolboxDock.show() self.hToolbox.setCurrentWidget(self.taskViewer) elif self.layout == "Sidebars": self.bottomSidebar.show() self.bottomSidebar.setCurrentWidget(self.taskViewer) else: self.taskViewer.show() self.taskViewer.setFocus(Qt.ActiveWindowFocusReason) def __activateTemplateViewer(self): """ Private slot to handle the activation of the Template Viewer. """ if self.layout == "Toolboxes": self.lToolboxDock.show() self.lToolbox.setCurrentWidget(self.templateViewer) elif self.layout == "Sidebars": self.leftSidebar.show() self.leftSidebar.setCurrentWidget(self.templateViewer) else: self.templateViewer.show() self.templateViewer.setFocus(Qt.ActiveWindowFocusReason) def __activateBrowser(self): """ Private slot to handle the activation of the file browser. """ if self.embeddedFileBrowser == 0: # separate window if self.layout == "Toolboxes": self.lToolboxDock.show() self.lToolbox.setCurrentWidget(self.browser) elif self.layout == "Sidebars": self.leftSidebar.show() self.leftSidebar.setCurrentWidget(self.browser) else: self.browser.show() elif self.embeddedFileBrowser == 1: # embedded in debug browser if self.layout == "Toolboxes": self.rToolboxDock.show() self.rToolbox.setCurrentWidget(self.debugViewer) elif self.layout == "Sidebars": self.rightSidebar.show() self.rightSidebar.setCurrentWidget(self.debugViewer) else: self.debugViewer.show() self.debugViewer.setCurrentWidget(self.browser) else: # embedded in project browser if self.layout == "Toolboxes": self.lToolboxDock.show() self.lToolbox.setCurrentWidget(self.projectBrowser) elif self.layout == "Sidebars": self.leftSidebar.show() self.leftSidebar.setCurrentWidget(self.projectBrowser) else: self.projectBrowser.show() self.projectBrowser.setCurrentWidget(self.browser) self.browser.setFocus(Qt.ActiveWindowFocusReason) def __toggleLeftToolbox(self): """ Private slot to handle the toggle of the Left Toolbox window. """ hasFocus = self.lToolbox.currentWidget().hasFocus() shown = self.__toggleWindow(self.lToolboxDock) if shown: self.lToolbox.currentWidget().setFocus(Qt.ActiveWindowFocusReason) else: if hasFocus: self.__activateViewmanager() def __toggleRightToolbox(self): """ Private slot to handle the toggle of the Right Toolbox window. """ hasFocus = self.rToolbox.currentWidget().hasFocus() shown = self.__toggleWindow(self.rToolboxDock) if shown: self.rToolbox.currentWidget().setFocus(Qt.ActiveWindowFocusReason) else: if hasFocus: self.__activateViewmanager() def __toggleHorizontalToolbox(self): """ Private slot to handle the toggle of the Horizontal Toolbox window. """ hasFocus = self.hToolbox.currentWidget().hasFocus() shown = self.__toggleWindow(self.hToolboxDock) if shown: self.hToolbox.currentWidget().setFocus(Qt.ActiveWindowFocusReason) else: if hasFocus: self.__activateViewmanager() def __toggleLeftSidebar(self): """ Private slot to handle the toggle of the left sidebar window. """ hasFocus = self.leftSidebar.currentWidget().hasFocus() shown = self.__toggleWindow(self.leftSidebar) if shown: self.leftSidebar.currentWidget().setFocus( Qt.ActiveWindowFocusReason) else: if hasFocus: self.__activateViewmanager() def __toggleRightSidebar(self): """ Private slot to handle the toggle of the right sidebar window. """ hasFocus = self.rightSidebar.currentWidget().hasFocus() shown = self.__toggleWindow(self.rightSidebar) if shown: self.rightSidebar.currentWidget().setFocus( Qt.ActiveWindowFocusReason) else: if hasFocus: self.__activateViewmanager() def __toggleBottomSidebar(self): """ Private slot to handle the toggle of the bottom sidebar window. """ hasFocus = self.bottomSidebar.currentWidget().hasFocus() shown = self.__toggleWindow(self.bottomSidebar) if shown: self.bottomSidebar.currentWidget().setFocus( Qt.ActiveWindowFocusReason) else: if hasFocus: self.__activateViewmanager() def activateCooperationViewer(self): """ Public slot to handle the activation of the cooperation window. """ if self.layout == "Toolboxes": self.rToolboxDock.show() self.rToolbox.setCurrentWidget(self.cooperation) elif self.layout == "Sidebars": self.rightSidebar.show() self.rightSidebar.setCurrentWidget(self.cooperation) else: self.cooperation.show() self.cooperation.setFocus(Qt.ActiveWindowFocusReason) def __activateIRC(self): """ Private slot to handle the activation of the IRC window. """ if self.layout == "Toolboxes": self.rToolboxDock.show() self.rToolbox.setCurrentWidget(self.irc) elif self.layout == "Sidebars": self.rightSidebar.show() self.rightSidebar.setCurrentWidget(self.irc) else: self.irc.show() self.irc.setFocus(Qt.ActiveWindowFocusReason) def __activateSymbolsViewer(self): """ Private slot to handle the activation of the Symbols Viewer. """ if self.layout == "Toolboxes": self.lToolboxDock.show() self.lToolbox.setCurrentWidget(self.symbolsViewer) elif self.layout == "Sidebars": self.leftSidebar.show() self.leftSidebar.setCurrentWidget(self.symbolsViewer) else: self.symbolsViewer.show() self.symbolsViewer.setFocus(Qt.ActiveWindowFocusReason) def __activateNumbersViewer(self): """ Private slot to handle the activation of the Numbers Viewer. """ if self.layout == "Toolboxes": self.hToolboxDock.show() self.hToolboxDock.setCurrentWidget(self.numbersViewer) elif self.layout == "Sidebars": self.bottomSidebar.show() self.bottomSidebar.setCurrentWidget(self.numbersViewer) else: self.numbersViewer.show() self.numbersViewer.setFocus(Qt.ActiveWindowFocusReason) def __activateViewmanager(self): """ Private slot to handle the activation of the current editor. """ aw = self.viewmanager.activeWindow() if aw is not None: aw.setFocus(Qt.ActiveWindowFocusReason) def __toggleWindow(self, w): """ Private method to toggle a workspace editor window. @param w reference to the workspace editor window @return flag indicating, if the window was shown (boolean) """ if w.isHidden(): w.show() return True else: w.hide() return False def __toolsConfiguration(self): """ Private slot to handle the tools configuration menu entry. """ from Preferences.ToolConfigurationDialog import ToolConfigurationDialog dlg = ToolConfigurationDialog( self.toolGroups[self.currentToolGroup][1], self) if dlg.exec_() == QDialog.Accepted: self.toolGroups[self.currentToolGroup][1] = dlg.getToollist() self.__updateExternalToolsActions() def __toolGroupsConfiguration(self): """ Private slot to handle the tool groups configuration menu entry. """ from Preferences.ToolGroupConfigurationDialog import \ ToolGroupConfigurationDialog dlg = ToolGroupConfigurationDialog( self.toolGroups, self.currentToolGroup, self) if dlg.exec_() == QDialog.Accepted: self.toolGroups, self.currentToolGroup = dlg.getToolGroups() def __createUnitTestDialog(self): """ Private slot to generate the unit test dialog on demand. """ if self.unittestDialog is None: from PyUnit.UnittestDialog import UnittestDialog self.unittestDialog = UnittestDialog( None, self.debuggerUI.debugServer, self, fromEric=True) self.unittestDialog.unittestFile.connect( self.viewmanager.setFileLine) self.unittestDialog.unittestStopped.connect(self.__unittestStopped) def __unittestStopped(self): """ Private slot to handle the end of a unit test run. """ self.utRerunFailedAct.setEnabled(self.unittestDialog.hasFailedTests()) self.utRestartAct.setEnabled(True) def __unittest(self): """ Private slot for displaying the unittest dialog. """ self.__createUnitTestDialog() self.unittestDialog.show() self.unittestDialog.raise_() @pyqtSlot() @pyqtSlot(str) def __unittestScript(self, prog=None): """ Private slot for displaying the unittest dialog and run the current script. @param prog the python program to be opened """ if prog is None: aw = self.viewmanager.activeWindow() fn = aw.getFileName() tfn = Utilities.getTestFileName(fn) if os.path.exists(tfn): prog = tfn else: prog = fn self.__createUnitTestDialog() self.unittestDialog.insertProg(prog) self.unittestDialog.show() self.unittestDialog.raise_() self.utRestartAct.setEnabled(False) self.utRerunFailedAct.setEnabled(False) def __unittestProject(self): """ Private slot for displaying the unittest dialog and run the current project. """ fn = self.project.getMainScript(True) if fn: tfn = Utilities.getTestFileName(fn) if os.path.exists(tfn): prog = tfn else: prog = fn else: E5MessageBox.critical( self, self.tr("Unittest Project"), self.tr( "There is no main script defined for the" " current project. Aborting")) return self.__createUnitTestDialog() self.unittestDialog.insertProg(prog) self.unittestDialog.show() self.unittestDialog.raise_() self.utRestartAct.setEnabled(False) self.utRerunFailedAct.setEnabled(False) def __unittestRestart(self): """ Private slot to display the unittest dialog and rerun the last unit test. """ self.__createUnitTestDialog() self.unittestDialog.show() self.unittestDialog.raise_() self.unittestDialog.on_startButton_clicked() def __unittestRerunFailed(self): """ Private slot to display the unittest dialog and rerun all failed tests of the last run. """ self.__createUnitTestDialog() self.unittestDialog.show() self.unittestDialog.raise_() self.unittestDialog.on_startButton_clicked(failedOnly=True) def __designer(self, fn=None, version=0): """ Private slot to start the Qt-Designer executable. @param fn filename of the form to be opened @param version indication for the requested version (Qt 4) (integer) """ if fn is not None and version == 0: # determine version from file, if not specified try: f = open(fn, "r", encoding="utf-8") found = False while not found: uiLine = f.readline() found = uiLine.lower().startswith("The file {0} does not exist or' ' is zero length.

') .format(fn)) return except EnvironmentError: E5MessageBox.critical( self, self.tr('Problem'), self.tr( '

The file {0} does not exist or' ' is zero length.

') .format(fn)) return if Utilities.isMacPlatform(): designer, args = Utilities.prepareQtMacBundle( "designer", version, args) else: if version == 4: designer = os.path.join( Utilities.getQtBinariesPath(), Utilities.generateQtToolName("designer")) if Utilities.isWindowsPlatform(): designer += '.exe' proc = QProcess() if not proc.startDetached(designer, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start Qt-Designer.
' 'Ensure that it is available as {0}.

' ).format(designer)) def __designer4(self): """ Private slot to start the Qt-Designer 4 executable. """ self.__designer(version=4) def __linguist(self, fn=None, version=0): """ Private slot to start the Qt-Linguist executable. @param fn filename of the translation file to be opened @param version indication for the requested version (Qt 4) (integer) """ if version < 4: E5MessageBox.information( self, self.tr("Qt 3 support"), self.tr("""Qt v.3 is not supported by eric6.""")) return args = [] if fn is not None: fn = fn.replace('.qm', '.ts') try: if os.path.isfile(fn) and os.path.getsize(fn) and \ fn not in args: args.append(fn) else: E5MessageBox.critical( self, self.tr('Problem'), self.tr( '

The file {0} does not exist or' ' is zero length.

') .format(fn)) return except EnvironmentError: E5MessageBox.critical( self, self.tr('Problem'), self.tr( '

The file {0} does not exist or' ' is zero length.

') .format(fn)) return if Utilities.isMacPlatform(): linguist, args = Utilities.prepareQtMacBundle( "linguist", version, args) else: if version == 4: linguist = os.path.join( Utilities.getQtBinariesPath(), Utilities.generateQtToolName("linguist")) if Utilities.isWindowsPlatform(): linguist += '.exe' proc = QProcess() if not proc.startDetached(linguist, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start Qt-Linguist.
' 'Ensure that it is available as {0}.

' ).format(linguist)) @pyqtSlot() @pyqtSlot(str) def __linguist4(self, fn=None): """ Private slot to start the Qt-Linguist 4 executable. @param fn filename of the translation file to be opened """ self.__linguist(fn, version=4) def __assistant(self, home=None, version=0): """ Private slot to start the Qt-Assistant executable. @param home full pathname of a file to display (string) @param version indication for the requested version (Qt 4) (integer) """ if version < 4: E5MessageBox.information( self, self.tr("Qt 3 support"), self.tr("""Qt v.3 is not supported by eric6.""")) return args = [] if home: if version == 4: args.append('-showUrl') args.append(home) if Utilities.isMacPlatform(): assistant, args = Utilities.prepareQtMacBundle( "assistant", version, args) else: if version == 4: assistant = os.path.join( Utilities.getQtBinariesPath(), Utilities.generateQtToolName("assistant")) if Utilities.isWindowsPlatform(): assistant += '.exe' proc = QProcess() if not proc.startDetached(assistant, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start Qt-Assistant.
' 'Ensure that it is available as {0}.

' ).format(assistant)) def __assistant4(self): """ Private slot to start the Qt-Assistant 4 executable. """ self.__assistant(version=4) def __startWebBrowser(self): """ Private slot to start the eric6 web browser. """ self.launchHelpViewer("") def __customViewer(self, home=None): """ Private slot to start a custom viewer. @param home full pathname of a file to display (string) """ customViewer = Preferences.getHelp("CustomViewer") if not customViewer: E5MessageBox.information( self, self.tr("Help"), self.tr( """Currently no custom viewer is selected.""" """ Please use the preferences dialog to specify one.""")) return proc = QProcess() args = [] if home: args.append(home) if not proc.startDetached(customViewer, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start custom viewer.
' 'Ensure that it is available as {0}.

' ).format(customViewer)) def __chmViewer(self, home=None): """ Private slot to start the win help viewer to show *.chm files. @param home full pathname of a file to display (string) """ if home: proc = QProcess() args = [] args.append(home) if not proc.startDetached("hh", args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start the help viewer.
' 'Ensure that it is available as hh.

' )) @pyqtSlot() @pyqtSlot(str) def __UIPreviewer(self, fn=None): """ Private slot to start the UI Previewer executable. @param fn filename of the form to be previewed (string) """ proc = QProcess() viewer = os.path.join(getConfig("ericDir"), "eric6_uipreviewer.py") args = [] args.append(viewer) if fn is not None: try: if os.path.isfile(fn) and os.path.getsize(fn): args.append(fn) else: E5MessageBox.critical( self, self.tr('Problem'), self.tr( '

The file {0} does not exist or' ' is zero length.

') .format(fn)) return except EnvironmentError: E5MessageBox.critical( self, self.tr('Problem'), self.tr( '

The file {0} does not exist or' ' is zero length.

') .format(fn)) return if not os.path.isfile(viewer) or \ not proc.startDetached(sys.executable, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start UI Previewer.
' 'Ensure that it is available as {0}.

' ).format(viewer)) @pyqtSlot() @pyqtSlot(str) @pyqtSlot(str, bool) def __TRPreviewer(self, fileNames=None, ignore=False): """ Private slot to start the Translation Previewer executable. @param fileNames filenames of forms and/or translations to be previewed (list of strings) @param ignore flag indicating non existing files should be ignored (boolean) """ proc = QProcess() viewer = os.path.join(getConfig("ericDir"), "eric6_trpreviewer.py") args = [] args.append(viewer) if fileNames is not None: for fn in fileNames: try: if os.path.isfile(fn) and os.path.getsize(fn): args.append(fn) else: if not ignore: E5MessageBox.critical( self, self.tr('Problem'), self.tr( '

The file {0} does not exist or' ' is zero length.

') .format(fn)) return except EnvironmentError: if not ignore: E5MessageBox.critical( self, self.tr('Problem'), self.tr( '

The file {0} does not exist or' ' is zero length.

') .format(fn)) return if not os.path.isfile(viewer) or \ not proc.startDetached(sys.executable, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start Translation Previewer.
' 'Ensure that it is available as {0}.

' ).format(viewer)) def __sqlBrowser(self): """ Private slot to start the SQL browser tool. """ proc = QProcess() browser = os.path.join(getConfig("ericDir"), "eric6_sqlbrowser.py") args = [] args.append(browser) if not os.path.isfile(browser) or \ not proc.startDetached(sys.executable, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start SQL Browser.
' 'Ensure that it is available as {0}.

' ).format(browser)) @pyqtSlot() @pyqtSlot(str) def __editPixmap(self, fn=""): """ Private slot to show a pixmap in a dialog. @param fn filename of the file to show (string) """ from IconEditor.IconEditorWindow import IconEditorWindow dlg = IconEditorWindow(fn, self, fromEric=True, project=self.project) dlg.show() @pyqtSlot() @pyqtSlot(str) def __showPixmap(self, fn): """ Private slot to show a pixmap in a dialog. @param fn filename of the file to show (string) """ from Graphics.PixmapDiagram import PixmapDiagram dlg = PixmapDiagram(fn, self) if dlg.getStatus(): dlg.show() @pyqtSlot() @pyqtSlot(str) def __showSvg(self, fn): """ Private slot to show a SVG file in a dialog. @param fn filename of the file to show (string) """ from Graphics.SvgDiagram import SvgDiagram dlg = SvgDiagram(fn, self) dlg.show() def __snapshot(self): """ Private slot to start the snapshot tool. """ proc = QProcess() snap = os.path.join(getConfig("ericDir"), "eric6_snap.py") args = [] args.append(snap) if not os.path.isfile(snap) or \ not proc.startDetached(sys.executable, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start Snapshot tool.
' 'Ensure that it is available as {0}.

' ).format(snap)) def __toolActionTriggered(self): """ Private slot called by external tools toolbar actions. """ act = self.sender() toolGroupName, toolMenuText = act.objectName().split('@@', 1) for toolGroup in self.toolGroups: if toolGroup[0] == toolGroupName: for tool in toolGroup[1]: if tool['menutext'] == toolMenuText: self.__startToolProcess(tool) return E5MessageBox.information( self, self.tr("External Tools"), self.tr( """No tool entry found for external tool '{0}' """ """in tool group '{1}'.""") .format(toolMenuText, toolGroupName)) return E5MessageBox.information( self, self.tr("External Tools"), self.tr("""No toolgroup entry '{0}' found.""") .format(toolGroupName) ) def __toolExecute(self, act): """ Private slot to execute a particular tool. @param act reference to the action that was triggered (QAction) """ if self.toolGroupsMenuTriggered: # ignore actions triggered from the select tool group submenu self.toolGroupsMenuTriggered = False return if self.currentToolGroup < 0: # it was a built in or plugin tool, don't handle it here return idx = act.data() if idx is not None and idx >= 0: tool = self.toolGroups[self.currentToolGroup][1][idx] self.__startToolProcess(tool) def __startToolProcess(self, tool): """ Private slot to start an external tool process. @param tool list of tool entries """ proc = QProcess() procData = (None,) program = tool['executable'] args = [] argv = Utilities.parseOptionString(tool['arguments']) args.extend(argv) t = self.tr("Starting process '{0} {1}'.\n")\ .format(program, tool['arguments']) self.appendToStdout(t) proc.finished.connect(self.__toolFinished) if tool['redirect'] != 'no': proc.readyReadStandardOutput.connect(self.__processToolStdout) proc.readyReadStandardError.connect(self.__processToolStderr) if tool['redirect'] in ["insert", "replaceSelection"]: aw = self.viewmanager.activeWindow() procData = (aw, tool['redirect'], []) if aw is not None: aw.beginUndoAction() proc.start(program, args) if not proc.waitForStarted(): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

Could not start the tool entry {0}.
' 'Ensure that it is available as {1}.

') .format(tool['menutext'], tool['executable'])) else: self.toolProcs.append((program, proc, procData)) if tool['redirect'] == 'no': proc.closeReadChannel(QProcess.StandardOutput) proc.closeReadChannel(QProcess.StandardError) proc.closeWriteChannel() def __processToolStdout(self): """ Private slot to handle the readyReadStdout signal of a tool process. """ ioEncoding = Preferences.getSystem("IOEncoding") # loop through all running tool processes for program, toolProc, toolProcData in self.toolProcs: toolProc.setReadChannel(QProcess.StandardOutput) if toolProcData[0] is None or \ toolProcData[1] not in ["insert", "replaceSelection"]: # not connected to an editor or wrong mode while toolProc.canReadLine(): output = str(toolProc.readLine(), ioEncoding, 'replace') s = "{0} - {1}".format(program, output) self.appendToStdout(s) else: if toolProcData[1] == "insert": text = str(toolProc.readAll(), ioEncoding, 'replace') toolProcData[0].insert(text) elif toolProcData[1] == "replaceSelection": text = str(toolProc.readAll(), ioEncoding, 'replace') toolProcData[2].append(text) def __processToolStderr(self): """ Private slot to handle the readyReadStderr signal of a tool process. """ ioEncoding = Preferences.getSystem("IOEncoding") # loop through all running tool processes for program, toolProc, toolProcData in self.toolProcs: toolProc.setReadChannel(QProcess.StandardError) while toolProc.canReadLine(): error = str(toolProc.readLine(), ioEncoding, 'replace') s = "{0} - {1}".format(program, error) self.appendToStderr(s) def __toolFinished(self, exitCode, exitStatus): """ Private slot to handle the finished signal of a tool process. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ exitedProcs = [] # loop through all running tool processes for program, toolProc, toolProcData in self.toolProcs: if toolProc.state() == QProcess.NotRunning: exitedProcs.append((program, toolProc, toolProcData)) if toolProcData[0] is not None: if toolProcData[1] == "replaceSelection": text = ''.join(toolProcData[2]) toolProcData[0].replace(text) toolProcData[0].endUndoAction() # now delete the exited procs from the list of running processes for proc in exitedProcs: self.toolProcs.remove(proc) t = self.tr("Process '{0}' has exited.\n").format(proc[0]) self.appendToStdout(t) def __showPythonDoc(self): """ Private slot to show the Python 3 documentation. """ pythonDocDir = Preferences.getHelp("PythonDocDir") if not pythonDocDir: if Utilities.isWindowsPlatform(): pythonDocDir = Utilities.getEnvironmentEntry( "PYTHON3DOCDIR", os.path.join(os.path.dirname(sys.executable), "doc")) else: pythonDocDir = Utilities.getEnvironmentEntry( "PYTHON3DOCDIR", '/usr/share/doc/packages/python3/html') if not pythonDocDir.startswith("http://") and \ not pythonDocDir.startswith("https://"): if pythonDocDir.startswith("file://"): pythonDocDir = pythonDocDir[7:] if not os.path.splitext(pythonDocDir)[1]: home = Utilities.normjoinpath(pythonDocDir, 'index.html') if Utilities.isWindowsPlatform() and not os.path.exists(home): pyversion = sys.hexversion >> 16 vers = "{0:d}{1:d}".format((pyversion >> 8) & 0xff, pyversion & 0xff) home = os.path.join( pythonDocDir, "python{0}.chm".format(vers)) else: home = pythonDocDir if not os.path.exists(home): E5MessageBox.warning( self, self.tr("Documentation Missing"), self.tr("""

The documentation starting point""" """ "{0}" could not be found.

""") .format(home)) return if not home.endswith(".chm"): if Utilities.isWindowsPlatform(): home = "file:///" + Utilities.fromNativeSeparators(home) else: home = "file://" + home else: home = pythonDocDir if home.endswith(".chm"): self.__chmViewer(home) else: hvType = Preferences.getHelp("HelpViewerType") if hvType == 1: self.launchHelpViewer(home) elif hvType == 2: self.__assistant(home, version=4) elif hvType == 3: self.__webBrowser(home) else: self.__customViewer(home) def __showPython2Doc(self): """ Private slot to show the Python 2 documentation. """ pythonDocDir = Preferences.getHelp("Python2DocDir") executable = Preferences.getDebugger("PythonInterpreter") if not pythonDocDir: if Utilities.isWindowsPlatform(): if executable: default = os.path.join(os.path.dirname(executable), "doc") else: default = "" pythonDocDir = \ Utilities.getEnvironmentEntry("PYTHON2DOCDIR", default) else: pythonDocDir = Utilities.getEnvironmentEntry( "PYTHON2DOCDIR", '/usr/share/doc/packages/python/html') if not pythonDocDir.startswith("http://") and \ not pythonDocDir.startswith("https://"): if pythonDocDir.startswith("file://"): pythonDocDir = pythonDocDir[7:] if not os.path.splitext(pythonDocDir)[1]: home = Utilities.normjoinpath(pythonDocDir, 'index.html') else: home = pythonDocDir if not os.path.exists(home): E5MessageBox.warning( self, self.tr("Documentation Missing"), self.tr("""

The documentation starting point""" """ "{0}" could not be found.

""") .format(home)) return if not home.endswith(".chm"): if Utilities.isWindowsPlatform(): home = "file:///" + Utilities.fromNativeSeparators(home) else: home = "file://" + home else: home = pythonDocDir if home.endswith(".chm"): self.__chmViewer(home) else: hvType = Preferences.getHelp("HelpViewerType") if hvType == 1: self.launchHelpViewer(home) elif hvType == 2: self.__assistant(home, version=4) elif hvType == 3: self.__webBrowser(home) else: self.__customViewer(home) def __showQt4Doc(self): """ Private slot to show the Qt4 documentation. """ self.__showQtDoc(4) def __showQt5Doc(self): """ Private slot to show the Qt5 documentation. """ self.__showQtDoc(5) def __showQtDoc(self, version): """ Private method to show the Qt documentation. @param version Qt version to show documentation for (integer) """ assert version in [4, 5] if version == 4: qtDocDir = Preferences.getQt4DocDir() elif version == 5: qtDocDir = Preferences.getQt5DocDir() if qtDocDir.startswith("qthelp://"): if not os.path.splitext(qtDocDir)[1]: home = qtDocDir + "/index.html" else: home = qtDocDir elif qtDocDir.startswith("http://") or qtDocDir.startswith("https://"): home = qtDocDir else: if qtDocDir.startswith("file://"): qtDocDir = qtDocDir[7:] if not os.path.splitext(qtDocDir)[1]: home = Utilities.normjoinpath(qtDocDir, 'index.html') else: home = qtDocDir if not os.path.exists(home): E5MessageBox.warning( self, self.tr("Documentation Missing"), self.tr("""

The documentation starting point""" """ "{0}" could not be found.

""") .format(home)) return if Utilities.isWindowsPlatform(): home = "file:///" + Utilities.fromNativeSeparators(home) else: home = "file://" + home hvType = Preferences.getHelp("HelpViewerType") if hvType == 1: self.launchHelpViewer(home) elif hvType == 2: self.__assistant(home, version=4) elif hvType == 3: self.__webBrowser(home) else: self.__customViewer(home) def __showPyQt4Doc(self): """ Private slot to show the PyQt4 documentation. """ pyqt4DocDir = Preferences.getHelp("PyQt4DocDir") if not pyqt4DocDir: pyqt4DocDir = Utilities.getEnvironmentEntry("PYQT4DOCDIR", None) if not pyqt4DocDir: E5MessageBox.warning( self, self.tr("Documentation"), self.tr("""

The PyQt4 documentation starting point""" """ has not been configured.

""")) return if not pyqt4DocDir.startswith("http://") and \ not pyqt4DocDir.startswith("https://"): home = "" if pyqt4DocDir: if pyqt4DocDir.startswith("file://"): pyqt4DocDir = pyqt4DocDir[7:] if not os.path.splitext(pyqt4DocDir)[1]: possibleHomes = [ Utilities.normjoinpath(pyqt4DocDir, 'index.html'), Utilities.normjoinpath(pyqt4DocDir, 'classes.html'), ] for possibleHome in possibleHomes: if os.path.exists(possibleHome): home = possibleHome break else: home = pyqt4DocDir if not home or not os.path.exists(home): E5MessageBox.warning( self, self.tr("Documentation Missing"), self.tr("""

The documentation starting point""" """ "{0}" could not be found.

""") .format(home)) return if Utilities.isWindowsPlatform(): home = "file:///" + Utilities.fromNativeSeparators(home) else: home = "file://" + home else: home = pyqt4DocDir hvType = Preferences.getHelp("HelpViewerType") if hvType == 1: self.launchHelpViewer(home) elif hvType == 2: self.__assistant(home, version=4) elif hvType == 3: self.__webBrowser(home) else: self.__customViewer(home) def __showPyQt5Doc(self): """ Private slot to show the PyQt5 documentation. """ pyqt5DocDir = Preferences.getHelp("PyQt5DocDir") if not pyqt5DocDir: pyqt5DocDir = Utilities.getEnvironmentEntry("PYQT5DOCDIR", None) if not pyqt5DocDir: E5MessageBox.warning( self, self.tr("Documentation"), self.tr("""

The PyQt5 documentation starting point""" """ has not been configured.

""")) return if not pyqt5DocDir.startswith("http://") and \ not pyqt5DocDir.startswith("https://"): home = "" if pyqt5DocDir: if pyqt5DocDir.startswith("file://"): pyqt5DocDir = pyqt5DocDir[7:] if not os.path.splitext(pyqt5DocDir)[1]: possibleHomes = [ Utilities.normjoinpath( pyqt5DocDir, 'index.html'), Utilities.normjoinpath( pyqt5DocDir, 'class_reference.html'), ] for possibleHome in possibleHomes: if os.path.exists(possibleHome): home = possibleHome break else: home = pyqt5DocDir if not home or not os.path.exists(home): E5MessageBox.warning( self, self.tr("Documentation Missing"), self.tr("""

The documentation starting point""" """ "{0}" could not be found.

""") .format(home)) return if Utilities.isWindowsPlatform(): home = "file:///" + Utilities.fromNativeSeparators(home) else: home = "file://" + home else: home = pyqt5DocDir hvType = Preferences.getHelp("HelpViewerType") if hvType == 1: self.launchHelpViewer(home) elif hvType == 2: self.__assistant(home, version=4) elif hvType == 3: self.__webBrowser(home) else: self.__customViewer(home) def __showEricDoc(self): """ Private slot to show the Eric documentation. """ home = Utilities.normjoinpath( getConfig('ericDocDir'), "Source", "index.html") if not home.startswith("http://") and \ not home.startswith("https://") and \ not home.startswith("qthelp://"): if not os.path.exists(home): E5MessageBox.warning( self, self.tr("Documentation Missing"), self.tr("""

The documentation starting point""" """ "{0}" could not be found.

""") .format(home)) return if Utilities.isWindowsPlatform(): home = "file:///" + Utilities.fromNativeSeparators(home) else: home = "file://" + home hvType = Preferences.getHelp("HelpViewerType") if hvType == 1: self.launchHelpViewer(home) elif hvType == 2: self.__assistant(home, version=4) elif hvType == 3: self.__webBrowser(home) else: self.__customViewer(home) def __showPySideDoc(self): """ Private slot to show the PySide documentation. """ pysideDocDir = Preferences.getHelp("PySideDocDir") if not pysideDocDir: pysideDocDir = Utilities.getEnvironmentEntry("PYSIDEDOCDIR", None) if not pysideDocDir: E5MessageBox.warning( self, self.tr("Documentation"), self.tr("""

The PySide documentation starting point""" """ has not been configured.

""")) return if not pysideDocDir.startswith("http://") and \ not pysideDocDir.startswith("https://"): if pysideDocDir.startswith("file://"): pysideDocDir = pysideDocDir[7:] if not os.path.splitext(pysideDocDir)[1]: home = Utilities.normjoinpath(pysideDocDir, 'index.html') else: home = pysideDocDir if not os.path.exists(home): E5MessageBox.warning( self, self.tr("Documentation Missing"), self.tr("""

The documentation starting point""" """ "{0}" could not be found.

""") .format(home)) return if Utilities.isWindowsPlatform(): home = "file:///" + Utilities.fromNativeSeparators(home) else: home = "file://" + home else: home = pysideDocDir hvType = Preferences.getHelp("HelpViewerType") if hvType == 1: self.launchHelpViewer(home) elif hvType == 2: self.__assistant(home, version=4) elif hvType == 3: self.__webBrowser(home) else: self.__customViewer(home) def launchHelpViewer(self, home, searchWord=None, useSingle=False): """ Public slot to start the help viewer. @param home filename of file to be shown (string) @keyparam searchWord word to search for (string) @keyparam useSingle flag indicating to use a single browser window (boolean) """ if len(home) > 0: homeUrl = QUrl(home) if not homeUrl.scheme(): home = QUrl.fromLocalFile(home).toString() if not (useSingle or Preferences.getHelp("SingleHelpWindow")) or \ self.helpWindow is None: from Helpviewer.HelpWindow import HelpWindow help = HelpWindow(home, '.', None, 'help viewer', True, searchWord=searchWord) if QApplication.desktop().width() > 400 and \ QApplication.desktop().height() > 500: help.show() else: help.showMaximized() if useSingle or Preferences.getHelp("SingleHelpWindow"): self.helpWindow = help self.helpWindow.helpClosed.connect(self.__helpClosed) self.preferencesChanged.connect( self.helpWindow.preferencesChanged) self.masterPasswordChanged.connect( self.helpWindow.masterPasswordChanged) elif searchWord is not None: self.helpWindow.search(searchWord) self.helpWindow.raise_() else: self.helpWindow.newTab(home) self.helpWindow.raise_() def __helpClosed(self): """ Private slot to handle the helpClosed signal of the help window. """ if Preferences.getHelp("SingleHelpWindow"): self.preferencesChanged.disconnect( self.helpWindow.preferencesChanged) self.masterPasswordChanged.disconnect( self.helpWindow.masterPasswordChanged) self.helpWindow = None def __helpViewer(self): """ Private slot to start an empty help viewer. """ searchWord = self.viewmanager.textForFind(False) if searchWord == "": searchWord = None self.launchHelpViewer("", searchWord=searchWord) def __webBrowser(self, home=""): """ Private slot to start the eric6 web browser. @param home full pathname of a file to display (string) """ started = QDesktopServices.openUrl(QUrl(home)) if not started: E5MessageBox.critical( self, self.tr('Open Browser'), self.tr('Could not start a web browser')) def getHelpViewer(self, preview=False): """ Public method to get a reference to the help window instance. @keyparam preview flag indicating to get a help window for preview (boolean) @return reference to the help window instance (HelpWindow) """ if self.helpWindow is None: self.launchHelpViewer("", useSingle=True) self.helpWindow.raise_() return self.helpWindow @pyqtSlot() @pyqtSlot(str) def showPreferences(self, pageName=None): """ Public slot to set the preferences. @param pageName name of the configuration page to show (string) """ from Preferences.ConfigurationDialog import ConfigurationDialog dlg = ConfigurationDialog(self, 'Configuration') dlg.preferencesChanged.connect(self.__preferencesChanged) dlg.masterPasswordChanged.connect(self.__masterPasswordChanged) dlg.show() if pageName is not None: dlg.showConfigurationPageByName(pageName) elif self.__lastConfigurationPageName: dlg.showConfigurationPageByName(self.__lastConfigurationPageName) else: dlg.showConfigurationPageByName("empty") dlg.exec_() QApplication.processEvents() if dlg.result() == QDialog.Accepted: dlg.setPreferences() Preferences.syncPreferences() self.__preferencesChanged() self.__lastConfigurationPageName = dlg.getConfigurationPageName() def __exportPreferences(self): """ Private slot to export the current preferences. """ Preferences.exportPreferences() def __importPreferences(self): """ Private slot to import preferences. """ Preferences.importPreferences() self.__preferencesChanged() def __preferencesChanged(self): """ Private slot to handle a change of the preferences. """ self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) if Preferences.getUI("SingleApplicationMode"): if self.SAServer is None: self.SAServer = E5SingleApplicationServer() else: if self.SAServer is not None: self.SAServer.shutdown() self.SAServer = None self.newWindowAct.setEnabled( not Preferences.getUI("SingleApplicationMode")) self.maxEditorPathLen = Preferences.getUI("CaptionFilenameLength") self.captionShowsFilename = Preferences.getUI("CaptionShowsFilename") if not self.captionShowsFilename: self.__setWindowCaption(editor="") else: aw = self.viewmanager.activeWindow() fn = aw and aw.getFileName() or None if fn: self.__setWindowCaption(editor=fn) else: self.__setWindowCaption(editor="") self.__httpAlternatives = Preferences.getUI("VersionsUrls6") self.performVersionCheck(False) self.__configureDockareaCornerUsage() from QScintilla.SpellChecker import SpellChecker SpellChecker.setDefaultLanguage( Preferences.getEditor("SpellCheckingDefaultLanguage")) if self.layout == "Sidebars": delay = Preferences.getUI("SidebarDelay") self.leftSidebar.setDelay(delay) self.bottomSidebar.setDelay(delay) self.rightSidebar.setDelay(delay) self.preferencesChanged.emit() def __masterPasswordChanged(self, oldPassword, newPassword): """ Private slot to handle the change of the master password. @param oldPassword current master password (string) @param newPassword new master password (string) """ self.masterPasswordChanged.emit(oldPassword, newPassword) Preferences.convertPasswords(oldPassword, newPassword) if self.helpWindow is None: from Helpviewer.Passwords.PasswordManager import PasswordManager pwManager = PasswordManager() pwManager.masterPasswordChanged(oldPassword, newPassword) Utilities.crypto.changeRememberedMaster(newPassword) def __reloadAPIs(self): """ Private slot to reload the api information. """ self.reloadAPIs.emit() def __showExternalTools(self): """ Private slot to display a dialog show a list of external tools used by eric6. """ if self.programsDialog is None: from Preferences.ProgramsDialog import ProgramsDialog self.programsDialog = ProgramsDialog(self) self.programsDialog.show() def __configViewProfiles(self): """ Private slot to configure the various view profiles. """ from Preferences.ViewProfileDialog import ViewProfileDialog dlg = ViewProfileDialog( self.layout, self.profiles['edit'][1], self.profiles['debug'][1]) if dlg.exec_() == QDialog.Accepted: edit, debug = dlg.getVisibilities() self.profiles['edit'][1] = edit self.profiles['debug'][1] = debug Preferences.setUI("ViewProfiles2", self.profiles) if self.currentProfile == "edit": self.__setEditProfile(False) elif self.currentProfile == "debug": self.setDebugProfile(False) def __configToolBars(self): """ Private slot to configure the various toolbars. """ from E5Gui.E5ToolBarDialog import E5ToolBarDialog dlg = E5ToolBarDialog(self.toolbarManager) if dlg.exec_() == QDialog.Accepted: Preferences.setUI( "ToolbarManagerState", self.toolbarManager.saveState()) def __configShortcuts(self): """ Private slot to configure the keyboard shortcuts. """ if self.shortcutsDialog is None: from Preferences.ShortcutsDialog import ShortcutsDialog self.shortcutsDialog = ShortcutsDialog(self, 'Shortcuts') self.shortcutsDialog.populate() self.shortcutsDialog.show() def __exportShortcuts(self): """ Private slot to export the keyboard shortcuts. """ fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( None, self.tr("Export Keyboard Shortcuts"), "", self.tr("Keyboard shortcut file (*.e4k)"), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fn: return ext = QFileInfo(fn).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fn += ex from Preferences import Shortcuts Shortcuts.exportShortcuts(fn) def __importShortcuts(self): """ Private slot to import the keyboard shortcuts. """ fn = E5FileDialog.getOpenFileName( None, self.tr("Import Keyboard Shortcuts"), "", self.tr("Keyboard shortcut file (*.e4k)")) if fn: from Preferences import Shortcuts Shortcuts.importShortcuts(fn) def __showCertificatesDialog(self): """ Private slot to show the certificates management dialog. """ from E5Network.E5SslCertificatesDialog import E5SslCertificatesDialog dlg = E5SslCertificatesDialog(self) dlg.exec_() def __newProject(self): """ Private slot to handle the NewProject signal. """ self.__setWindowCaption(project=self.project.name) def __projectOpened(self): """ Private slot to handle the projectOpened signal. """ from Debugger.DebugClientCapabilities import HasUnittest self.__setWindowCaption(project=self.project.name) cap = e5App().getObject("DebugServer")\ .getClientCapabilities(self.project.pdata["PROGLANGUAGE"][0]) self.utProjectAct.setEnabled(cap & HasUnittest) self.utProjectOpen = cap & HasUnittest def __projectClosed(self): """ Private slot to handle the projectClosed signal. """ self.__setWindowCaption(project="") self.utProjectAct.setEnabled(False) if not self.utEditorOpen: self.utRestartAct.setEnabled(False) self.utRerunFailedAct.setEnabled(False) self.utProjectOpen = False def __programChange(self, fn): """ Private slot to handle the programChange signal. This primarily is here to set the currentProg variable. @param fn filename to be set as current prog (string) """ # Delete the old program if there was one. if self.currentProg is not None: del self.currentProg self.currentProg = os.path.normpath(fn) def __lastEditorClosed(self): """ Private slot to handle the lastEditorClosed signal. """ self.wizardsMenuAct.setEnabled(False) self.utScriptAct.setEnabled(False) self.utEditorOpen = False if not self.utProjectOpen: self.utRestartAct.setEnabled(False) self.utRerunFailedAct.setEnabled(False) self.__setWindowCaption(editor="") def __editorOpened(self, fn): """ Private slot to handle the editorOpened signal. @param fn filename of the opened editor (string) """ self.wizardsMenuAct.setEnabled( len(self.__menus["wizards"].actions()) > 0) if fn and str(fn) != "None": dbs = e5App().getObject("DebugServer") for language in dbs.getSupportedLanguages(): exts = dbs.getExtensions(language) if fn.endswith(exts): from Debugger.DebugClientCapabilities import HasUnittest cap = dbs.getClientCapabilities(language) self.utScriptAct.setEnabled(cap & HasUnittest) self.utEditorOpen = cap & HasUnittest return if self.viewmanager.getOpenEditor(fn).isPyFile(): self.utScriptAct.setEnabled(True) self.utEditorOpen = True def __checkActions(self, editor): """ Private slot to check some actions for their enable/disable status. @param editor editor window """ if editor: fn = editor.getFileName() else: fn = None if fn: dbs = e5App().getObject("DebugServer") for language in dbs.getSupportedLanguages(): exts = dbs.getExtensions(language) if fn.endswith(exts): from Debugger.DebugClientCapabilities import HasUnittest cap = dbs.getClientCapabilities(language) self.utScriptAct.setEnabled(cap & HasUnittest) self.utEditorOpen = cap & HasUnittest return if editor.isPyFile(): self.utScriptAct.setEnabled(True) self.utEditorOpen = True return self.utScriptAct.setEnabled(False) def __writeTasks(self): """ Private slot to write the tasks data to an XML file (.e4t). """ fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e4t") f = QFile(fn) ok = f.open(QIODevice.WriteOnly) if not ok: E5MessageBox.critical( self, self.tr("Save tasks"), self.tr( "

The tasks file {0} could not be written.

") .format(fn)) return from E5XML.TasksWriter import TasksWriter TasksWriter(f, False).writeXML() f.close() def __readTasks(self): """ Private slot to read in the tasks file (.e4t). """ fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e4t") if not os.path.exists(fn): return f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.TasksReader import TasksReader reader = TasksReader(f, viewer=self.taskViewer) reader.readXML() f.close() else: E5MessageBox.critical( self, self.tr("Read tasks"), self.tr( "

The tasks file {0} could not be read.

") .format(fn)) def __writeSession(self): """ Private slot to write the session data to an XML file (.e5s). """ fn = os.path.join(Utilities.getConfigDir(), "eric6session.e5s") f = QFile(fn) if f.open(QIODevice.WriteOnly): from E5XML.SessionWriter import SessionWriter SessionWriter(f, None).writeXML() f.close() else: E5MessageBox.critical( self, self.tr("Save session"), self.tr( "

The session file {0} could not be written.

") .format(fn)) def __readSession(self): """ Private slot to read in the session file (.e5s or .e4s). """ fn = os.path.join(Utilities.getConfigDir(), "eric6session.e5s") if not os.path.exists(fn): fn = os.path.join(Utilities.getConfigDir(), "eric6session.e4s") if not os.path.exists(fn): E5MessageBox.critical( self, self.tr("Read session"), self.tr( "

The session file {0} could not" " be read.

") .format(fn)) return f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.SessionReader import SessionReader reader = SessionReader(f, True) reader.readXML() f.close() else: E5MessageBox.critical( self, self.tr("Read session"), self.tr( "

The session file {0} could not be read.

") .format(fn)) def showFindFileByNameDialog(self): """ Public slot to show the Find File by Name dialog. """ if self.findFileNameDialog is None: from .FindFileNameDialog import FindFileNameDialog self.findFileNameDialog = FindFileNameDialog(self.project) self.findFileNameDialog.sourceFile.connect( self.viewmanager.openSourceFile) self.findFileNameDialog.designerFile.connect(self.__designer) self.findFileNameDialog.show() self.findFileNameDialog.raise_() self.findFileNameDialog.activateWindow() def showFindFilesDialog(self, txt="", searchDir="", openFiles=False): """ Public slot to show the Find In Files dialog. @keyparam txt text to search for (string) @keyparam searchDir directory to search in (string) @keyparam openFiles flag indicating to operate on open files (boolean) """ if self.findFilesDialog is None: from .FindFileDialog import FindFileDialog self.findFilesDialog = FindFileDialog(self.project) self.findFilesDialog.sourceFile.connect( self.viewmanager.openSourceFile) self.findFilesDialog.designerFile.connect(self.__designer) if searchDir: self.findFilesDialog.setSearchDirectory(searchDir) self.findFilesDialog.show(txt) if openFiles: self.findFilesDialog.setOpenFiles() self.findFilesDialog.raise_() self.findFilesDialog.activateWindow() def showReplaceFilesDialog(self, txt="", searchDir="", openFiles=False): """ Public slot to show the Find & Replace In Files dialog. @keyparam txt text to search for (string) @keyparam searchDir directory to search in (string) @keyparam openFiles flag indicating to operate on open files (boolean) """ if self.replaceFilesDialog is None: from .FindFileDialog import FindFileDialog self.replaceFilesDialog = \ FindFileDialog(self.project, replaceMode=True) self.replaceFilesDialog.sourceFile.connect( self.viewmanager.openSourceFile) self.replaceFilesDialog.designerFile.connect(self.__designer) if searchDir: self.replaceFilesDialog.setSearchDirectory(searchDir) self.replaceFilesDialog.show(txt) if openFiles: self.replaceFilesDialog.setOpenFiles() self.replaceFilesDialog.raise_() self.replaceFilesDialog.activateWindow() ########################################################## ## Below are slots to handle StdOut and StdErr ########################################################## def appendToStdout(self, s): """ Public slot to append text to the stdout log viewer tab. @param s output to be appended (string) """ self.showLogTab("stdout") self.appendStdout.emit(s) def appendToStderr(self, s): """ Public slot to append text to the stderr log viewer tab. @param s output to be appended (string) """ self.showLogTab("stderr") self.appendStderr.emit(s) ########################################################## ## Below are slots needed by the plugin menu ########################################################## def __showPluginInfo(self): """ Private slot to show the plugin info dialog. """ from PluginManager.PluginInfoDialog import PluginInfoDialog self.__pluginInfoDialog = PluginInfoDialog(self.pluginManager, self) self.__pluginInfoDialog.show() @pyqtSlot() def __installPlugins(self, pluginFileNames=[]): """ Private slot to show a dialog to install a new plugin. @param pluginFileNames list of plugin files suggested for installation list of strings """ from PluginManager.PluginInstallDialog import PluginInstallDialog dlg = PluginInstallDialog(self.pluginManager, pluginFileNames, self) dlg.exec_() if dlg.restartNeeded(): self.__restart() def __deinstallPlugin(self): """ Private slot to show a dialog to uninstall a plugin. """ from PluginManager.PluginUninstallDialog import PluginUninstallDialog dlg = PluginUninstallDialog(self.pluginManager, self) dlg.exec_() def showPluginsAvailable(self): """ Public slot to show the plugins available for download. """ from PluginManager.PluginRepositoryDialog import PluginRepositoryDialog dlg = PluginRepositoryDialog(self) res = dlg.exec_() if res == (QDialog.Accepted + 1): self.__installPlugins(dlg.getDownloadedPlugins()) def __pluginsConfigure(self): """ Private slot to show the plugin manager configuration page. """ self.showPreferences("pluginManagerPage") def checkPluginUpdatesAvailable(self): """ Public method to check the availability of updates of plug-ins. """ self.pluginManager.checkPluginUpdatesAvailable() ################################################################# ## Drag and Drop Support ################################################################# def dragEnterEvent(self, event): """ Protected method to handle the drag enter event. @param event the drag enter event (QDragEnterEvent) """ self.inDragDrop = event.mimeData().hasUrls() if self.inDragDrop: event.acceptProposedAction() def dragMoveEvent(self, event): """ Protected method to handle the drag move event. @param event the drag move event (QDragMoveEvent) """ if self.inDragDrop: event.acceptProposedAction() def dragLeaveEvent(self, event): """ Protected method to handle the drag leave event. @param event the drag leave event (QDragLeaveEvent) """ if self.inDragDrop: self.inDragDrop = False def dropEvent(self, event): """ Protected method to handle the drop event. @param event the drop event (QDropEvent) """ if event.mimeData().hasUrls(): event.acceptProposedAction() for url in event.mimeData().urls(): fname = url.toLocalFile() if fname: if QFileInfo(fname).isFile(): self.viewmanager.openSourceFile(fname) else: E5MessageBox.information( self, self.tr("Drop Error"), self.tr("""

{0} is not a file.

""") .format(fname)) self.inDragDrop = False ########################################################## ## Below are methods needed for shutting down the IDE ########################################################## def closeEvent(self, event): """ Protected event handler for the close event. This event handler saves the preferences. @param event close event (QCloseEvent) """ if self.__shutdown(): event.accept() if not self.inCloseEevent: self.inCloseEevent = True QTimer.singleShot(0, e5App().closeAllWindows) else: event.ignore() def __shutdown(self): """ Private method to perform all necessary steps to close down the IDE. @return flag indicating success """ if self.shutdownCalled: return True if self.helpWindow is not None: if not self.helpWindow.shutdown(): return False if not self.irc.shutdown(): return False self.__writeSession() if not self.project.closeProject(): return False if not self.multiProject.closeMultiProject(): return False if not self.viewmanager.closeViewManager(): return False self.__previewer.shutdown() self.shell.closeShell() self.__writeTasks() self.templateViewer.save() if not self.debuggerUI.shutdownServer(): return False self.debuggerUI.shutdown() self.backgroundService.shutdown() self.cooperation.shutdown() self.pluginManager.doShutdown() if self.layout == "Sidebars": self.leftSidebar.shutdown() self.bottomSidebar.shutdown() self.rightSidebar.shutdown() if self.SAServer is not None: self.SAServer.shutdown() self.SAServer = None Preferences.setGeometry("MainMaximized", self.isMaximized()) if not self.isMaximized(): Preferences.setGeometry("MainGeometry", self.saveGeometry()) self.browser.saveToplevelDirs() Preferences.setUI( "ToolbarManagerState", self.toolbarManager.saveState()) self.__saveCurrentViewProfile(True) Preferences.saveToolGroups(self.toolGroups, self.currentToolGroup) Preferences.syncPreferences() self.shutdownCalled = True return True ############################################## ## Below are methods to check for new versions ############################################## def showAvailableVersionsInfo(self): """ Public method to show the eric6 versions available for download. """ self.performVersionCheck(manual=True, showVersions=True) @pyqtSlot() def performVersionCheck(self, manual=True, alternative=0, showVersions=False): """ Public method to check the internet for an eric6 update. @param manual flag indicating an invocation via the menu (boolean) @param alternative index of server to download from (integer) @keyparam showVersions flag indicating the show versions mode (boolean) """ if not manual: if Version.startswith("@@"): return else: period = Preferences.getUI("PerformVersionCheck") if period == 0: return elif period in [2, 3, 4]: lastCheck = Preferences.Prefs.settings.value( "Updates/LastCheckDate", QDate(1970, 1, 1)) if lastCheck.isValid(): now = QDate.currentDate() if period == 2 and lastCheck.day() == now.day(): # daily return elif period == 3 and lastCheck.daysTo(now) < 7: # weekly return elif period == 4 and (lastCheck.daysTo(now) < lastCheck.daysInMonth()): # monthly return self.__inVersionCheck = True self.manualUpdatesCheck = manual self.showAvailableVersions = showVersions self.httpAlternative = alternative url = QUrl(self.__httpAlternatives[alternative]) self.__versionCheckCanceled = False if manual: if self.__versionCheckProgress is None: self.__versionCheckProgress = E5ProgressDialog( "", self.tr("&Cancel"), 0, len(self.__httpAlternatives), self.tr("%v/%m"), self) self.__versionCheckProgress.setWindowTitle( self.tr("Version Check")) self.__versionCheckProgress.setMinimumDuration(0) self.__versionCheckProgress.canceled.connect( self.__versionsDownloadCanceled) self.__versionCheckProgress.setLabelText( self.tr("Trying host {0}").format(url.host())) self.__versionCheckProgress.setValue(alternative) request = QNetworkRequest(url) request.setAttribute(QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) reply = self.__networkManager.get(request) reply.finished.connect(self.__versionsDownloadDone) self.__replies.append(reply) @pyqtSlot() def __versionsDownloadDone(self): """ Private slot called, after the versions file has been downloaded from the internet. """ if self.__versionCheckCanceled: self.__inVersionCheck = False if self.__versionCheckProgress is not None: self.__versionCheckProgress.reset() self.__versionCheckProgress = None return reply = self.sender() # This is a hack because sometimes reply is not a QNetworkReply if not isinstance(reply, QNetworkReply): if reply in self.__replies: self.__replies.remove(reply) return reply.deleteLater() if reply in self.__replies: self.__replies.remove(reply) if reply.error() == QNetworkReply.NoError: ioEncoding = Preferences.getSystem("IOEncoding") versions = str(reply.readAll(), ioEncoding, 'replace').splitlines() reply.close() if reply.error() != QNetworkReply.NoError or \ len(versions) == 0 or \ versions[0].startswith("<"): # network error or an error page self.httpAlternative += 1 if self.httpAlternative >= len(self.__httpAlternatives): self.__inVersionCheck = False if self.__versionCheckProgress is not None: self.__versionCheckProgress.reset() self.__versionCheckProgress = None firstFailure = Preferences.Prefs.settings.value( "Updates/FirstFailedCheckDate", QDate.currentDate()) failedDuration = firstFailure.daysTo(QDate.currentDate()) Preferences.Prefs.settings.setValue( "Updates/FirstFailedCheckDate", firstFailure) if self.manualUpdatesCheck: E5MessageBox.warning( self, self.tr("Error getting versions information"), self.tr("""The versions information could not be""" """ downloaded.""" """ Please go online and try again.""")) elif failedDuration > 7: E5MessageBox.warning( self, self.tr("Error getting versions information"), self.tr("""The versions information could not be""" """ downloaded for the last 7 days.""" """ Please go online and try again.""")) return else: self.performVersionCheck(self.manualUpdatesCheck, self.httpAlternative, self.showAvailableVersions) return self.__inVersionCheck = False if self.__versionCheckProgress is not None: self.__versionCheckProgress.reset() self.__versionCheckProgress = None self.__updateVersionsUrls(versions) if self.showAvailableVersions: self.__showAvailableVersionInfos(versions) else: Preferences.Prefs.settings.remove("Updates/FirstFailedCheckDate") Preferences.Prefs.settings.setValue( "Updates/LastCheckDate", QDate.currentDate()) self.__versionCheckResult(versions) def __updateVersionsUrls(self, versions): """ Private method to update the URLs from which to retrieve the versions file. @param versions contents of the downloaded versions file (list of strings) """ if len(versions) > 5 and versions[4] == "---": line = 5 urls = [] while line < len(versions): urls.append(versions[line]) line += 1 Preferences.setUI("VersionsUrls6", urls) def __versionCheckResult(self, versions): """ Private method to show the result of the version check action. @param versions contents of the downloaded versions file (list of strings) """ url = "" try: if "-snapshot-" in Version: # check snapshot version if versions[2][0] == "6" and versions[2] > Version: res = E5MessageBox.yesNo( self, self.tr("Update available"), self.tr( """The update to {0} of eric6 is""" """ available at {1}. Would you like to""" """ get it?""") .format(versions[2], versions[3]), yesDefault=True) url = res and versions[3] or '' elif versions[0] > Version: res = E5MessageBox.yesNo( self, self.tr("Update available"), self.tr( """The update to {0} of eric6 is""" """ available at {1}. Would you like to""" """ get it?""") .format(versions[0], versions[1]), yesDefault=True) url = res and versions[1] or '' else: if self.manualUpdatesCheck: E5MessageBox.information( self, self.tr("Eric6 is up to date"), self.tr( """You are using the latest version of""" """ eric6""")) else: # check release version if versions[0] > Version: res = E5MessageBox.yesNo( self, self.tr("Update available"), self.tr( """The update to {0} of eric6 is""" """ available at {1}. Would you like""" """ to get it?""") .format(versions[0], versions[1]), yesDefault=True) url = res and versions[1] or '' else: if self.manualUpdatesCheck: E5MessageBox.information( self, self.tr("Eric6 is up to date"), self.tr( """You are using the latest version of""" """ eric6""")) except IndexError: E5MessageBox.warning( self, self.tr("Error during updates check"), self.tr("""Could not perform updates check.""")) if url: QDesktopServices.openUrl(QUrl(url)) @pyqtSlot() def __versionsDownloadCanceled(self): """ Private slot called to cancel the version check. """ if self.__replies: self.__versionCheckCanceled = True self.__replies[-1].abort() def __showAvailableVersionInfos(self, versions): """ Private method to show the versions available for download. @param versions contents of the downloaded versions file (list of strings) """ versionText = self.tr( """

Available versions

""" """""") line = 0 while line < len(versions): if versions[line] == "---": break versionText += """""".format( versions[line], versions[line + 1], 'sourceforge' in versions[line + 1] and "SourceForge" or versions[line + 1]) line += 2 versionText += self.tr("""
{0}{2}""" \ """
""") E5MessageBox.about(self, Program, versionText) def __sslErrors(self, reply, errors): """ Private slot to handle SSL errors. @param reply reference to the reply object (QNetworkReply) @param errors list of SSL errors (list of QSslError) """ ignored = self.__sslErrorHandler.sslErrorsReply(reply, errors)[0] if ignored == E5SslErrorHandler.NotIgnored: self.__downloadCancelled = True ####################################### ## Below are methods for various checks ####################################### def checkConfigurationStatus(self): """ Public method to check, if eric6 has been configured. If it is not, the configuration dialog is shown. """ if not Preferences.isConfigured(): self.__initDebugToolbarsLayout() E5MessageBox.information( self, self.tr("First time usage"), self.tr("""eric6 has not been configured yet. """ """The configuration dialog will be started.""")) self.showPreferences() def checkProjectsWorkspace(self): """ Public method to check, if a projects workspace has been configured. If it has not, a dialog is shown. """ if not Preferences.isConfigured(): # eric hasn't been configured at all self.checkConfigurationStatus() workspace = Preferences.getMultiProject("Workspace") if workspace == "": default = Utilities.getHomeDir() workspace = E5FileDialog.getExistingDirectory( None, self.tr("Select Workspace Directory"), default, E5FileDialog.Options(E5FileDialog.Option(0))) Preferences.setMultiProject("Workspace", workspace) def versionIsNewer(self, required, snapshot=None): """ Public method to check, if the eric6 version is good compared to the required version. @param required required version (string) @param snapshot required snapshot version (string) @return flag indicating, that the version is newer than the required one (boolean) """ if Version.startswith("@@"): # development version, always newer return True if "-snapshot-" in Version: # check snapshot version if snapshot is None: return True else: vers = Version.split("-snapshot-")[1] return vers.split()[0] > snapshot return Version.split()[0] > required ################################# ## Below are some utility methods ################################# def __getFloatingGeometry(self, w): """ Private method to get the geometry of a floating windows. @param w reference to the widget to be saved (QWidget) @return list giving the widget's geometry and its visibility """ s = w.size() p = w.pos() return [p.x(), p.y(), s.width(), s.height(), not w.isHidden()] ############################ ## some event handlers below ############################ def showEvent(self, evt): """ Protected method to handle the show event. @param evt reference to the show event (QShowEvent) """ if self.__startup: if Preferences.getGeometry("MainMaximized"): self.setWindowState(Qt.WindowStates(Qt.WindowMaximized)) self.__startup = False ########################################## ## Support for desktop notifications below ########################################## def showNotification(self, icon, heading, text): """ Public method to show a desktop notification. @param icon icon to be shown in the notification (QPixmap) @param heading heading of the notification (string) @param text text of the notification (string) """ if Preferences.getUI("NotificationsEnabled"): if self.__notification is None: from .NotificationWidget import NotificationWidget self.__notification = NotificationWidget(parent=self) self.__notification.setPixmap(icon) self.__notification.setHeading(heading) self.__notification.setText(text) self.__notification.setTimeout( Preferences.getUI("NotificationTimeout")) self.__notification.move(Preferences.getUI("NotificationPosition")) self.__notification.show() def notificationsEnabled(self): """ Public method to check, if notifications are enabled. @return flag indicating, if notifications are enabled (boolean) """ return Preferences.getUI("NotificationsEnabled") ######################### ## Support for IRC below ######################### def autoConnectIrc(self): """ Public method to initiate the IRC auto connection. """ self.irc.autoConnect() def __ircAutoConnected(self): """ Private slot handling the automatic connection of the IRC client. """ self.__activateIRC() eric-6.0.8/eric/UI/DeleteFilesConfirmationDialog.ui0000644000175000017500000000265712060166053021210 0ustar piotrpiotr DeleteFilesConfirmationDialog 0 0 458 288 true Dummy Qt::AlignVCenter Qt::NoFocus QAbstractItemView::NoSelection Qt::Horizontal QDialogButtonBox::No|QDialogButtonBox::Yes qPixmapFromMimeSource filesList eric-6.0.8/eric/UI/Info.py0000644000175000017500000000102512557365404014240 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module defining some informational strings. """ from __future__ import unicode_literals Program = 'eric6' Version = '6.0.8 (rev. 4554a48fb757)' Copyright = 'Copyright (c) 2002 - 2015 Detlev Offenbach' \ ' ' BugAddress = 'eric-bugs@eric-ide.python-projects.org' FeatureAddress = 'eric-featurerequest@eric-ide.python-projects.org' Homepage = "http://eric-ide.python-projects.org/index.html" eric-6.0.8/eric/UI/ErrorLogDialog.ui0000644000175000017500000000475512060166053016206 0ustar piotrpiotr ErrorLogDialog 0 0 500 350 Error Log Found true 0 0 <b>An error log file was found. What should be done with it?</b> true Press to send an email Send Bug Email true Press to ignore the error and delete the log file Ignore and Delete Press to ignore the error but keep the log file Ignore but Keep logEdit emailButton deleteButton keepButton eric-6.0.8/eric/UI/SearchWidget.ui0000644000175000017500000000614312354034223015674 0ustar piotrpiotr SearchWidget 0 0 274 142 Find 0 Press to close the window Find: 0 0 200 0 true QComboBox::InsertAtTop false Match case Whole word Press to find the previous occurrence Press to find the next occurrence true findtextCombo caseCheckBox wordCheckBox findPrevButton findNextButton closeButton eric-6.0.8/eric/UI/SymbolsWidget.ui0000644000175000017500000000547012342407570016127 0ustar piotrpiotr SymbolsWidget 0 0 268 300 Symbols 0 4 0 0 0 0 Select the table to be shown true QAbstractItemView::SingleSelection QAbstractItemView::SelectRows Qt::ElideNone QAbstractItemView::ScrollPerPixel false Qt::Horizontal 120 20 Symbol code: Enter the symbol code 65535 32 tableCombo symbolsTable symbolSpinBox eric-6.0.8/eric/UI/Config.py0000644000175000017500000000034512451233374014547 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module defining common data to be used by all windows.. """ from PyQt5.QtCore import QSize ToolBarIconSize = QSize(20, 18) eric-6.0.8/eric/UI/FindFileDialog.py0000644000175000017500000006355612537064320016155 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a dialog to search for text in files. """ from __future__ import unicode_literals import os import re from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QDialog, QApplication, QMenu, QDialogButtonBox, \ QTreeWidgetItem from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog from .Ui_FindFileDialog import Ui_FindFileDialog import Utilities import Preferences import UI.PixmapCache class FindFileDialog(QDialog, Ui_FindFileDialog): """ Class implementing a dialog to search for text in files. The occurrences found are displayed in a QTreeWidget showing the filename, the linenumber and the found text. The file will be opened upon a double click onto the respective entry of the list. @signal sourceFile(str, int, str, int, int) emitted to open a source file at a line @signal designerFile(str) emitted to open a Qt-Designer file """ sourceFile = pyqtSignal(str, int, str, int, int) designerFile = pyqtSignal(str) lineRole = Qt.UserRole + 1 startRole = Qt.UserRole + 2 endRole = Qt.UserRole + 3 replaceRole = Qt.UserRole + 4 md5Role = Qt.UserRole + 5 def __init__(self, project, replaceMode=False, parent=None): """ Constructor @param project reference to the project object @param replaceMode flag indicating the replace dialog mode (boolean) @param parent parent widget of this dialog (QWidget) """ super(FindFileDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.dirSelectButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.__replaceMode = replaceMode self.stopButton = \ self.buttonBox.addButton(self.tr("Stop"), QDialogButtonBox.ActionRole) self.stopButton.setEnabled(False) self.findButton = \ self.buttonBox.addButton(self.tr("Find"), QDialogButtonBox.ActionRole) self.findButton.setEnabled(False) self.findButton.setDefault(True) if self.__replaceMode: self.replaceButton.setEnabled(False) self.setWindowTitle(self.tr("Replace in Files")) else: self.replaceLabel.hide() self.replacetextCombo.hide() self.replaceButton.hide() self.findProgressLabel.setMaximumWidth(550) self.findtextCombo.setCompleter(None) self.replacetextCombo.setCompleter(None) self.searchHistory = Preferences.toList( Preferences.Prefs.settings.value( "FindFileDialog/SearchHistory")) self.replaceHistory = Preferences.toList( Preferences.Prefs.settings.value( "FindFileDialog/ReplaceHistory")) self.dirHistory = Preferences.toList( Preferences.Prefs.settings.value( "FindFileDialog/DirectoryHistory")) self.findtextCombo.addItems(self.searchHistory) self.replacetextCombo.addItems(self.replaceHistory) self.dirCombo.addItems(self.dirHistory) self.project = project self.findList.headerItem().setText(self.findList.columnCount(), "") self.findList.header().setSortIndicator(0, Qt.AscendingOrder) self.__section0Size = self.findList.header().sectionSize(0) self.findList.setExpandsOnDoubleClick(False) if self.__replaceMode: font = Preferences.getEditorOtherFonts("MonospacedFont") self.findList.setFont(font) # Qt Designer form files self.filterForms = r'.*\.ui$' self.formsExt = ['*.ui'] # Corba interface files self.filterInterfaces = r'.*\.idl$' self.interfacesExt = ['*.idl'] # Qt resources files self.filterResources = r'.*\.qrc$' self.resourcesExt = ['*.qrc'] self.__cancelSearch = False self.__lastFileItem = None self.__populating = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__contextMenuRequested) def __createItem(self, file, line, text, start, end, replTxt="", md5=""): """ Private method to create an entry in the file list. @param file filename of file (string) @param line line number (integer) @param text text found (string) @param start start position of match (integer) @param end end position of match (integer) @param replTxt text with replacements applied (string) @keyparam md5 MD5 hash of the file (string) """ if self.__lastFileItem is None: # It's a new file self.__lastFileItem = QTreeWidgetItem(self.findList, [file]) self.__lastFileItem.setFirstColumnSpanned(True) self.__lastFileItem.setExpanded(True) if self.__replaceMode: self.__lastFileItem.setFlags( self.__lastFileItem.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate)) # Qt bug: # item is not user checkable if setFirstColumnSpanned # is True (< 4.5.0) self.__lastFileItem.setData(0, self.md5Role, md5) itm = QTreeWidgetItem(self.__lastFileItem) itm.setTextAlignment(0, Qt.AlignRight) itm.setData(0, Qt.DisplayRole, line) itm.setData(1, Qt.DisplayRole, text) itm.setData(0, self.lineRole, line) itm.setData(0, self.startRole, start) itm.setData(0, self.endRole, end) itm.setData(0, self.replaceRole, replTxt) if self.__replaceMode: itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable)) itm.setCheckState(0, Qt.Checked) self.replaceButton.setEnabled(True) def show(self, txt=""): """ Public method to enable/disable the project button. @param txt text to be shown in the searchtext combo (string) """ if self.project and self.project.isOpen(): self.projectButton.setEnabled(True) else: self.projectButton.setEnabled(False) self.dirButton.setChecked(True) self.findtextCombo.setEditText(txt) self.findtextCombo.lineEdit().selectAll() self.findtextCombo.setFocus() if self.__replaceMode: self.findList.clear() self.replacetextCombo.setEditText("") super(FindFileDialog, self).show() def on_findtextCombo_editTextChanged(self, text): """ Private slot to handle the editTextChanged signal of the find text combo. @param text (ignored) """ self.__enableFindButton() def on_replacetextCombo_editTextChanged(self, text): """ Private slot to handle the editTextChanged signal of the replace text combo. @param text (ignored) """ self.__enableFindButton() def on_dirCombo_editTextChanged(self, text): """ Private slot to handle the textChanged signal of the directory combo box. @param text (ignored) """ self.__enableFindButton() @pyqtSlot() def on_projectButton_clicked(self): """ Private slot to handle the selection of the project radio button. """ self.__enableFindButton() @pyqtSlot() def on_dirButton_clicked(self): """ Private slot to handle the selection of the project radio button. """ self.__enableFindButton() @pyqtSlot() def on_filterCheckBox_clicked(self): """ Private slot to handle the selection of the file filter check box. """ self.__enableFindButton() @pyqtSlot(str) def on_filterEdit_textEdited(self, text): """ Private slot to handle the textChanged signal of the file filter edit. @param text (ignored) """ self.__enableFindButton() def __enableFindButton(self): """ Private slot called to enable the find button. """ if self.findtextCombo.currentText() == "" or \ (self.__replaceMode and self.replacetextCombo.currentText() == "") or \ (self.dirButton.isChecked() and (self.dirCombo.currentText() == "" or not os.path.exists(os.path.abspath( self.dirCombo.currentText())))) or \ (self.filterCheckBox.isChecked() and self.filterEdit.text() == ""): self.findButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) else: self.findButton.setEnabled(True) self.findButton.setDefault(True) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.findButton: self.__doSearch() elif button == self.stopButton: self.__stopSearch() def __stripEol(self, txt): """ Private method to strip the eol part. @param txt line of text that should be treated (string) @return text with eol stripped (string) """ return txt.replace("\r", "").replace("\n", "") def __stopSearch(self): """ Private slot to handle the stop button being pressed. """ self.__cancelSearch = True def __doSearch(self): """ Private slot to handle the find button being pressed. """ if self.__replaceMode and \ not e5App().getObject("ViewManager").checkAllDirty(): return self.__cancelSearch = False if self.filterCheckBox.isChecked(): fileFilter = self.filterEdit.text() fileFilterList = \ ["^{0}$".format(filter.replace(".", "\.").replace("*", ".*")) for filter in fileFilter.split(";")] filterRe = re.compile("|".join(fileFilterList)) if self.projectButton.isChecked(): if self.filterCheckBox.isChecked(): files = [self.project.getRelativePath(file) for file in self.__getFileList( self.project.getProjectPath(), filterRe)] else: files = [] if self.sourcesCheckBox.isChecked(): files += self.project.pdata["SOURCES"] if self.formsCheckBox.isChecked(): files += self.project.pdata["FORMS"] if self.interfacesCheckBox.isChecked(): files += self.project.pdata["INTERFACES"] if self.resourcesCheckBox.isChecked(): files += self.project.pdata["RESOURCES"] elif self.dirButton.isChecked(): if not self.filterCheckBox.isChecked(): filters = [] if self.sourcesCheckBox.isChecked(): filters.extend( ["^{0}$".format( assoc.replace(".", "\.").replace("*", ".*")) for assoc in list( Preferences.getEditorLexerAssocs().keys()) if assoc not in self.formsExt + self.interfacesExt]) if self.formsCheckBox.isChecked(): filters.append(self.filterForms) if self.interfacesCheckBox.isChecked(): filters.append(self.filterInterfaces) if self.resourcesCheckBox.isChecked(): filters.append(self.filterResources) filterString = "|".join(filters) filterRe = re.compile(filterString) files = self.__getFileList( os.path.abspath(self.dirCombo.currentText()), filterRe) elif self.openFilesButton.isChecked(): vm = e5App().getObject("ViewManager") vm.checkAllDirty() files = vm.getOpenFilenames() self.findList.clear() QApplication.processEvents() QApplication.processEvents() self.findProgress.setMaximum(len(files)) # retrieve the values reg = self.regexpCheckBox.isChecked() wo = self.wordCheckBox.isChecked() cs = self.caseCheckBox.isChecked() ct = self.findtextCombo.currentText() if reg: txt = ct else: txt = re.escape(ct) if wo: txt = "\\b{0}\\b".format(txt) flags = re.UNICODE | re.LOCALE if not cs: flags |= re.IGNORECASE try: search = re.compile(txt, flags) except re.error as why: E5MessageBox.critical( self, self.tr("Invalid search expression"), self.tr("""

The search expression is not valid.

""" """

Error: {0}

""").format(str(why))) self.stopButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) return # reset the findtextCombo if ct in self.searchHistory: self.searchHistory.remove(ct) self.searchHistory.insert(0, ct) self.findtextCombo.clear() self.findtextCombo.addItems(self.searchHistory) Preferences.Prefs.settings.setValue( "FindFileDialog/SearchHistory", self.searchHistory[:30]) if self.__replaceMode: replTxt = self.replacetextCombo.currentText() if replTxt in self.replaceHistory: self.replaceHistory.remove(replTxt) self.replaceHistory.insert(0, replTxt) self.replacetextCombo.clear() self.replacetextCombo.addItems(self.replaceHistory) Preferences.Prefs.settings.setValue( "FindFileDialog/ReplaceHistory", self.replaceHistory[:30]) if self.dirButton.isChecked(): searchDir = self.dirCombo.currentText() if searchDir in self.dirHistory: self.dirHistory.remove(searchDir) self.dirHistory.insert(0, searchDir) self.dirCombo.clear() self.dirCombo.addItems(self.dirHistory) Preferences.Prefs.settings.setValue( "FindFileDialog/DirectoryHistory", self.dirHistory[:30]) # set the button states self.stopButton.setEnabled(True) self.stopButton.setDefault(True) self.findButton.setEnabled(False) # now go through all the files self.__populating = True self.findList.setUpdatesEnabled(False) progress = 0 breakSearch = False occurrences = 0 fileOccurrences = 0 for file in files: self.__lastFileItem = None found = False if self.__cancelSearch or breakSearch: break self.findProgressLabel.setPath(file) if self.projectButton.isChecked(): fn = os.path.join(self.project.ppath, file) else: fn = file # read the file and split it into textlines try: text, encoding, hash = Utilities.readEncodedFileWithHash(fn) lines = text.splitlines(True) except (UnicodeError, IOError): progress += 1 self.findProgress.setValue(progress) continue # now perform the search and display the lines found count = 0 for line in lines: if self.__cancelSearch: break count += 1 contains = search.search(line) if contains: occurrences += 1 found = True start = contains.start() end = contains.end() if self.__replaceMode: rline = search.sub(replTxt, line) else: rline = "" line = self.__stripEol(line) if len(line) > 1024: line = "{0} ...".format(line[:1024]) if self.__replaceMode: if len(rline) > 1024: rline = "{0} ...".format(line[:1024]) line = "- {0}\n+ {1}".format( line, self.__stripEol(rline)) self.__createItem(file, count, line, start, end, rline, hash) if self.feelLikeCheckBox.isChecked(): fn = os.path.join(self.project.ppath, file) self.sourceFile.emit(fn, count, "", start, end) QApplication.processEvents() breakSearch = True break QApplication.processEvents() if found: fileOccurrences += 1 progress += 1 self.findProgress.setValue(progress) if not files: self.findProgress.setMaximum(1) self.findProgress.setValue(1) resultFormat = self.tr("{0} / {1}", "occurrences / files") self.findProgressLabel.setPath(resultFormat.format( self.tr("%n occurrence(s)", "", occurrences), self.tr("%n file(s)", "", fileOccurrences))) self.findList.setUpdatesEnabled(True) self.findList.sortItems(self.findList.sortColumn(), self.findList.header().sortIndicatorOrder()) self.findList.resizeColumnToContents(1) if self.__replaceMode: self.findList.header().resizeSection(0, self.__section0Size + 30) self.findList.header().setStretchLastSection(True) self.__populating = False self.stopButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) if breakSearch: self.close() def on_findList_itemDoubleClicked(self, itm, column): """ Private slot to handle the double click on a file item. It emits the signal sourceFile or designerFile depending on the file extension. @param itm the double clicked tree item (QTreeWidgetItem) @param column column that was double clicked (integer) (ignored) """ if itm.parent(): file = itm.parent().text(0) line = itm.data(0, self.lineRole) start = itm.data(0, self.startRole) end = itm.data(0, self.endRole) else: file = itm.text(0) line = 1 start = 0 end = 0 if self.project: fn = os.path.join(self.project.ppath, file) else: fn = file if fn.endswith('.ui'): self.designerFile.emit(fn) else: self.sourceFile.emit(fn, line, "", start, end) @pyqtSlot() def on_dirSelectButton_clicked(self): """ Private slot to display a directory selection dialog. """ directory = E5FileDialog.getExistingDirectory( self, self.tr("Select directory"), self.dirCombo.currentText(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.dirCombo.setEditText(Utilities.toNativeSeparators(directory)) def __getFileList(self, path, filterRe): """ Private method to get a list of files to search. @param path the root directory to search in (string) @param filterRe regular expression defining the filter criteria (regexp object) @return list of files to be processed (list of strings) """ path = os.path.abspath(path) files = [] for dirname, _, names in os.walk(path): files.extend([os.path.join(dirname, f) for f in names if re.match(filterRe, f)] ) return files def setSearchDirectory(self, searchDir): """ Public slot to set the name of the directory to search in. @param searchDir name of the directory to search in (string) """ self.dirButton.setChecked(True) self.dirCombo.setEditText(Utilities.toNativeSeparators(searchDir)) def setOpenFiles(self): """ Public slot to set the mode to search in open files. """ self.openFilesButton.setChecked(True) @pyqtSlot() def on_replaceButton_clicked(self): """ Private slot to perform the requested replace actions. """ self.findProgress.setMaximum(self.findList.topLevelItemCount()) self.findProgress.setValue(0) progress = 0 for index in range(self.findList.topLevelItemCount()): itm = self.findList.topLevelItem(index) if itm.checkState(0) in [Qt.PartiallyChecked, Qt.Checked]: file = itm.text(0) origHash = itm.data(0, self.md5Role) self.findProgressLabel.setPath(file) if self.projectButton.isChecked(): fn = os.path.join(self.project.ppath, file) else: fn = file # read the file and split it into textlines try: text, encoding, hash = \ Utilities.readEncodedFileWithHash(fn) lines = text.splitlines(True) except (UnicodeError, IOError) as err: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """

Could not read the file {0}.""" """ Skipping it.

Reason: {1}

""") .format(fn, str(err)) ) progress += 1 self.findProgress.setValue(progress) continue # Check the original and the current hash. Skip the file, # if hashes are different. if origHash != hash: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """

The current and the original hash of the""" """ file {0} are different. Skipping it.""" """

Hash 1: {1}

Hash 2: {2}

""") .format(fn, origHash, hash) ) progress += 1 self.findProgress.setValue(progress) continue # replace the lines authorized by the user for cindex in range(itm.childCount()): citm = itm.child(cindex) if citm.checkState(0) == Qt.Checked: line = citm.data(0, self.lineRole) rline = citm.data(0, self.replaceRole) lines[line - 1] = rline # write the file txt = "".join(lines) try: Utilities.writeEncodedFile(fn, txt, encoding) except (IOError, Utilities.CodingError, UnicodeError) as err: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """

Could not save the file {0}.""" """ Skipping it.

Reason: {1}

""") .format(fn, str(err)) ) progress += 1 self.findProgress.setValue(progress) self.findProgressLabel.setPath("") self.findList.clear() self.replaceButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) def __contextMenuRequested(self, pos): """ Private slot to handle the context menu request. @param pos position the context menu shall be shown (QPoint) """ menu = QMenu(self) menu.addAction(self.tr("Open"), self.__openFile) menu.addAction(self.tr("Copy Path to Clipboard"), self.__copyToClipboard) menu.exec_(QCursor.pos()) def __openFile(self): """ Private slot to open the currently selected entry. """ itm = self.findList.selectedItems()[0] self.on_findList_itemDoubleClicked(itm, 0) def __copyToClipboard(self): """ Private method to copy the path of an entry to the clipboard. """ itm = self.findList.selectedItems()[0] if itm.parent(): fn = itm.parent().text(0) else: fn = itm.text(0) cb = QApplication.clipboard() cb.setText(fn) eric-6.0.8/eric/UI/CompareDialog.py0000644000175000017500000004463512451233374016062 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog to compare two files and show the result side by side. """ from __future__ import unicode_literals try: basestring # __IGNORE_WARNING__ except NameError: basestring = str import re from difflib import _mdiff, IS_CHARACTER_JUNK from PyQt5.QtCore import QTimer, QEvent, pyqtSlot from PyQt5.QtGui import QColor, QFontMetrics, QBrush, QTextCursor from PyQt5.QtWidgets import QWidget, QApplication, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5MainWindow import E5MainWindow import UI.PixmapCache from .Ui_CompareDialog import Ui_CompareDialog import Utilities import Preferences def sbsdiff(a, b, linenumberwidth=4): """ Compare two sequences of lines; generate the delta for display side by side. @param a first sequence of lines (list of strings) @param b second sequence of lines (list of strings) @param linenumberwidth width (in characters) of the linenumbers (integer) @return a generator yielding tuples of differences. The tuple is composed of strings as follows.
  • opcode -- one of e, d, i, r for equal, delete, insert, replace
  • lineno a -- linenumber of sequence a
  • line a -- line of sequence a
  • lineno b -- linenumber of sequence b
  • line b -- line of sequence b
""" def removeMarkers(line): """ Internal function to remove all diff markers. @param line line to work on (string) @return line without diff markers (string) """ return line\ .replace('\0+', "")\ .replace('\0-', "")\ .replace('\0^', "")\ .replace('\1', "") linenumberformat = "{{0:{0:d}d}}".format(linenumberwidth) emptylineno = ' ' * linenumberwidth for (ln1, l1), (ln2, l2), flag in _mdiff(a, b, None, None, IS_CHARACTER_JUNK): if not flag: yield ('e', linenumberformat.format(ln1), l1, linenumberformat.format(ln2), l2) continue if ln2 == "" and l2 == "\n": yield ('d', linenumberformat.format(ln1), removeMarkers(l1), emptylineno, '\n') continue if ln1 == "" and l1 == "\n": yield ('i', emptylineno, '\n', linenumberformat.format(ln2), removeMarkers(l2)) continue yield ('r', linenumberformat.format(ln1), l1, linenumberformat.format(ln2), l2) class CompareDialog(QWidget, Ui_CompareDialog): """ Class implementing a dialog to compare two files and show the result side by side. """ def __init__(self, files=[], parent=None): """ Constructor @param files list of files to compare and their label (list of two tuples of two strings) @param parent parent widget (QWidget) """ super(CompareDialog, self).__init__(parent) self.setupUi(self) self.file1Button.setIcon(UI.PixmapCache.getIcon("open.png")) self.file2Button.setIcon(UI.PixmapCache.getIcon("open.png")) self.file1Completer = E5FileCompleter(self.file1Edit) self.file2Completer = E5FileCompleter(self.file2Edit) self.diffButton = self.buttonBox.addButton( self.tr("Compare"), QDialogButtonBox.ActionRole) self.diffButton.setToolTip( self.tr("Press to perform the comparison of the two files")) self.diffButton.setEnabled(False) self.diffButton.setDefault(True) self.firstButton.setIcon(UI.PixmapCache.getIcon("2uparrow.png")) self.upButton.setIcon(UI.PixmapCache.getIcon("1uparrow.png")) self.downButton.setIcon(UI.PixmapCache.getIcon("1downarrow.png")) self.lastButton.setIcon(UI.PixmapCache.getIcon("2downarrow.png")) self.totalLabel.setText(self.tr('Total: {0}').format(0)) self.changedLabel.setText(self.tr('Changed: {0}').format(0)) self.addedLabel.setText(self.tr('Added: {0}').format(0)) self.deletedLabel.setText(self.tr('Deleted: {0}').format(0)) self.updateInterval = 20 # update every 20 lines self.vsb1 = self.contents_1.verticalScrollBar() self.hsb1 = self.contents_1.horizontalScrollBar() self.vsb2 = self.contents_2.verticalScrollBar() self.hsb2 = self.contents_2.horizontalScrollBar() self.on_synchronizeCheckBox_toggled(True) font = Preferences.getEditorOtherFonts("MonospacedFont") self.contents_1.setFontFamily(font.family()) self.contents_1.setFontPointSize(font.pointSize()) self.contents_2.setFontFamily(font.family()) self.contents_2.setFontPointSize(font.pointSize()) self.fontHeight = QFontMetrics(self.contents_1.currentFont()).height() self.cNormalFormat = self.contents_1.currentCharFormat() self.cInsertedFormat = self.contents_1.currentCharFormat() self.cInsertedFormat.setBackground(QBrush(QColor(190, 237, 190))) self.cDeletedFormat = self.contents_1.currentCharFormat() self.cDeletedFormat.setBackground(QBrush(QColor(237, 190, 190))) self.cReplacedFormat = self.contents_1.currentCharFormat() self.cReplacedFormat.setBackground(QBrush(QColor(190, 190, 237))) # connect some of our widgets explicitly self.file1Edit.textChanged.connect(self.__fileChanged) self.file2Edit.textChanged.connect(self.__fileChanged) self.vsb1.valueChanged.connect(self.__scrollBarMoved) self.vsb1.valueChanged.connect(self.vsb2.setValue) self.vsb2.valueChanged.connect(self.vsb1.setValue) self.diffParas = [] self.currentDiffPos = -1 self.markerPattern = "\0\+|\0\^|\0\-" if len(files) == 2: self.filesGroup.hide() self.file1Edit.setText(files[0][1]) self.file2Edit.setText(files[1][1]) self.file1Label.setText(files[0][0]) self.file2Label.setText(files[1][0]) self.diffButton.hide() QTimer.singleShot(0, self.on_diffButton_clicked) else: self.file1Label.hide() self.file2Label.hide() def show(self, filename=None): """ Public slot to show the dialog. @param filename name of a file to use as the first file (string) """ if filename: self.file1Edit.setText(filename) super(CompareDialog, self).show() def __appendText(self, pane, linenumber, line, format, interLine=False): """ Private method to append text to the end of the contents pane. @param pane text edit widget to append text to (QTextedit) @param linenumber number of line to insert (string) @param line text to insert (string) @param format text format to be used (QTextCharFormat) @param interLine flag indicating interline changes (boolean) """ tc = pane.textCursor() tc.movePosition(QTextCursor.End) pane.setTextCursor(tc) pane.setCurrentCharFormat(format) if interLine: pane.insertPlainText("{0} ".format(linenumber)) for txt in re.split(self.markerPattern, line): if txt: if txt.count('\1'): txt1, txt = txt.split('\1', 1) tc = pane.textCursor() tc.movePosition(QTextCursor.End) pane.setTextCursor(tc) pane.setCurrentCharFormat(format) pane.insertPlainText(txt1) tc = pane.textCursor() tc.movePosition(QTextCursor.End) pane.setTextCursor(tc) pane.setCurrentCharFormat(self.cNormalFormat) pane.insertPlainText(txt) else: pane.insertPlainText("{0} {1}".format(linenumber, line)) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.diffButton: self.on_diffButton_clicked() @pyqtSlot() def on_diffButton_clicked(self): """ Private slot to handle the Compare button press. """ filename1 = Utilities.toNativeSeparators(self.file1Edit.text()) try: f1 = open(filename1, "r", encoding="utf-8") lines1 = f1.readlines() f1.close() except IOError: E5MessageBox.critical( self, self.tr("Compare Files"), self.tr( """

The file {0} could not be read.

""") .format(filename1)) return filename2 = Utilities.toNativeSeparators(self.file2Edit.text()) try: f2 = open(filename2, "r", encoding="utf-8") lines2 = f2.readlines() f2.close() except IOError: E5MessageBox.critical( self, self.tr("Compare Files"), self.tr( """

The file {0} could not be read.

""") .format(filename2)) return self.__compare(lines1, lines2) def compare(self, lines1, lines2, name1="", name2=""): """ Public method to compare two lists of text. @param lines1 text to compare against (string or list of strings) @param lines2 text to compare (string or list of strings) @keyparam name1 name to be shown for the first text (string) @keyparam name2 name to be shown for the second text (string) """ if name1 == "" or name2 == "": self.filesGroup.hide() else: self.file1Button.hide() self.file2Button.hide() self.file1Edit.setText(name1) self.file1Edit.setReadOnly(True) self.file2Edit.setText(name2) self.file2Edit.setReadOnly(True) self.diffButton.setEnabled(False) self.diffButton.hide() if isinstance(lines1, basestring): lines1 = lines1.splitlines(True) if isinstance(lines2, basestring): lines2 = lines2.splitlines(True) self.__compare(lines1, lines2) def __compare(self, lines1, lines2): """ Private method to compare two lists of text. @param lines1 text to compare against (list of strings) @param lines2 text to compare (list of strings) """ self.contents_1.clear() self.contents_2.clear() # counters for changes added = 0 deleted = 0 changed = 0 paras = 1 self.diffParas = [] self.currentDiffPos = -1 oldOpcode = '' for opcode, ln1, l1, ln2, l2 in sbsdiff(lines1, lines2): if opcode in 'idr': if oldOpcode != opcode: oldOpcode = opcode self.diffParas.append(paras) # update counters if opcode == 'i': added += 1 elif opcode == 'd': deleted += 1 elif opcode == 'r': changed += 1 if opcode == 'i': format1 = self.cNormalFormat format2 = self.cInsertedFormat elif opcode == 'd': format1 = self.cDeletedFormat format2 = self.cNormalFormat elif opcode == 'r': if ln1.strip(): format1 = self.cReplacedFormat else: format1 = self.cNormalFormat if ln2.strip(): format2 = self.cReplacedFormat else: format2 = self.cNormalFormat else: oldOpcode = '' format1 = self.cNormalFormat format2 = self.cNormalFormat self.__appendText(self.contents_1, ln1, l1, format1, opcode == 'r') self.__appendText(self.contents_2, ln2, l2, format2, opcode == 'r') paras += 1 if not (paras % self.updateInterval): QApplication.processEvents() self.vsb1.setValue(0) self.vsb2.setValue(0) self.firstButton.setEnabled(False) self.upButton.setEnabled(False) self.downButton.setEnabled( len(self.diffParas) > 0 and (self.vsb1.isVisible() or self.vsb2.isVisible())) self.lastButton.setEnabled( len(self.diffParas) > 0 and (self.vsb1.isVisible() or self.vsb2.isVisible())) self.totalLabel.setText(self.tr('Total: {0}') .format(added + deleted + changed)) self.changedLabel.setText(self.tr('Changed: {0}').format(changed)) self.addedLabel.setText(self.tr('Added: {0}').format(added)) self.deletedLabel.setText(self.tr('Deleted: {0}').format(deleted)) def __moveTextToCurrentDiffPos(self): """ Private slot to move the text display to the current diff position. """ if 0 <= self.currentDiffPos < len(self.diffParas): value = (self.diffParas[self.currentDiffPos] - 1) * self.fontHeight self.vsb1.setValue(value) self.vsb2.setValue(value) def __scrollBarMoved(self, value): """ Private slot to enable the buttons and set the current diff position depending on scrollbar position. @param value scrollbar position (integer) """ tPos = value / self.fontHeight + 1 bPos = (value + self.vsb1.pageStep()) / self.fontHeight + 1 self.currentDiffPos = -1 if self.diffParas: self.firstButton.setEnabled(tPos > self.diffParas[0]) self.upButton.setEnabled(tPos > self.diffParas[0]) self.downButton.setEnabled(bPos < self.diffParas[-1]) self.lastButton.setEnabled(bPos < self.diffParas[-1]) if tPos >= self.diffParas[0]: for diffPos in self.diffParas: self.currentDiffPos += 1 if tPos <= diffPos: break @pyqtSlot() def on_upButton_clicked(self): """ Private slot to go to the previous difference. """ self.currentDiffPos -= 1 self.__moveTextToCurrentDiffPos() @pyqtSlot() def on_downButton_clicked(self): """ Private slot to go to the next difference. """ self.currentDiffPos += 1 self.__moveTextToCurrentDiffPos() @pyqtSlot() def on_firstButton_clicked(self): """ Private slot to go to the first difference. """ self.currentDiffPos = 0 self.__moveTextToCurrentDiffPos() @pyqtSlot() def on_lastButton_clicked(self): """ Private slot to go to the last difference. """ self.currentDiffPos = len(self.diffParas) - 1 self.__moveTextToCurrentDiffPos() def __fileChanged(self): """ Private slot to enable/disable the Compare button. """ if not self.file1Edit.text() or \ not self.file2Edit.text(): self.diffButton.setEnabled(False) else: self.diffButton.setEnabled(True) def __selectFile(self, lineEdit): """ Private slot to display a file selection dialog. @param lineEdit field for the display of the selected filename (QLineEdit) """ filename = E5FileDialog.getOpenFileName( self, self.tr("Select file to compare"), lineEdit.text(), "") if filename: lineEdit.setText(Utilities.toNativeSeparators(filename)) @pyqtSlot() def on_file1Button_clicked(self): """ Private slot to handle the file 1 file selection button press. """ self.__selectFile(self.file1Edit) @pyqtSlot() def on_file2Button_clicked(self): """ Private slot to handle the file 2 file selection button press. """ self.__selectFile(self.file2Edit) @pyqtSlot(bool) def on_synchronizeCheckBox_toggled(self, sync): """ Private slot to connect or disconnect the scrollbars of the displays. @param sync flag indicating synchronisation status (boolean) """ if sync: self.hsb2.setValue(self.hsb1.value()) self.hsb1.valueChanged.connect(self.hsb2.setValue) self.hsb2.valueChanged.connect(self.hsb1.setValue) else: self.hsb1.valueChanged.disconnect(self.hsb2.setValue) self.hsb2.valueChanged.disconnect(self.hsb1.setValue) class CompareWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, files=[], parent=None): """ Constructor @param files list of files to compare and their label (list of two tuples of two strings) @param parent reference to the parent widget (QWidget) """ super(CompareWindow, self).__init__(parent) self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw = CompareDialog(files, self) self.cw.installEventFilter(self) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) def eventFilter(self, obj, event): """ Public method to filter events. @param obj reference to the object the event is meant for (QObject) @param event reference to the event object (QEvent) @return flag indicating, whether the event was handled (boolean) """ if event.type() == QEvent.Close: QApplication.exit() return True return False eric-6.0.8/eric/UI/CompareDialog.ui0000644000175000017500000002111512263310076016027 0ustar piotrpiotr CompareDialog 0 0 950 600 File Comparison true 0 0 0 0 File &1: file1Edit Enter the name of the first file Press to select the file via a file selection dialog File &2: file1Edit Enter the name of the second file Press to select the file via a file selection dialog true true Qt::NoFocus QTextEdit::NoWrap true 8 false Qt::Vertical 20 101 false Press to move to the first difference false Press to move to the previous difference false Press to move to the next difference false Press to move to the last difference Qt::Vertical 20 101 Qt::NoFocus QTextEdit::NoWrap true 8 false Select, if the horizontal scrollbars should be synchronized &Synchronize horizontal scrollbars Alt+S true QFrame::Panel QFrame::Sunken QFrame::Panel QFrame::Sunken QFrame::Panel QFrame::Sunken QFrame::Panel QFrame::Sunken Qt::Horizontal QDialogButtonBox::Close file1Edit file1Button file2Edit file2Button synchronizeCheckBox firstButton upButton downButton lastButton buttonBox rejected() CompareDialog close() 102 580 104 599 eric-6.0.8/eric/UI/DeleteFilesConfirmationDialog.py0000644000175000017500000000330012451233374021212 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing a dialog to confirm deletion of multiple files. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog, QDialogButtonBox from .Ui_DeleteFilesConfirmationDialog import Ui_DeleteFilesConfirmationDialog class DeleteFilesConfirmationDialog(QDialog, Ui_DeleteFilesConfirmationDialog): """ Class implementing a dialog to confirm deletion of multiple files. """ def __init__(self, parent, caption, message, files): """ Constructor @param parent parent of this dialog (QWidget) @param caption window title for the dialog (string) @param message message to be shown (string) @param files list of filenames to be shown (list of strings) """ super(DeleteFilesConfirmationDialog, self).__init__(parent) self.setupUi(self) self.setModal(True) self.buttonBox.button(QDialogButtonBox.Yes).setAutoDefault(False) self.buttonBox.button(QDialogButtonBox.No).setDefault(True) self.buttonBox.button(QDialogButtonBox.No).setFocus() self.setWindowTitle(caption) self.message.setText(message) self.filesList.addItems(files) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Yes): self.accept() elif button == self.buttonBox.button(QDialogButtonBox.No): self.reject() eric-6.0.8/eric/UI/BrowserSortFilterProxyModel.py0000644000175000017500000000726212451233374021033 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the browser sort filter proxy model. """ from __future__ import unicode_literals from PyQt5.QtCore import QModelIndex, QSortFilterProxyModel import Preferences class BrowserSortFilterProxyModel(QSortFilterProxyModel): """ Class implementing the browser sort filter proxy model. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(BrowserSortFilterProxyModel, self).__init__(parent) self.hideNonPublic = Preferences.getUI("BrowsersHideNonPublic") def sort(self, column, order): """ Public method to sort the items. @param column column number to sort on (integer) @param order sort order for the sort (Qt.SortOrder) """ self.__sortColumn = column self.__sortOrder = order super(BrowserSortFilterProxyModel, self).sort(column, order) def lessThan(self, left, right): """ Public method used to sort the displayed items. It implements a special sorting function that takes into account, if folders should be shown first, and that __init__ is always the first method of a class. @param left index of left item (QModelIndex) @param right index of right item (QModelIndex) @return true, if left is less than right (boolean) """ le = left.model() and left.model().item(left) or None ri = right.model() and right.model().item(right) or None if le and ri: return le.lessThan(ri, self.__sortColumn, self.__sortOrder) return False def item(self, index): """ Public method to get a reference to an item. @param index index of the data to retrieve (QModelIndex) @return requested item reference (BrowserItem) """ if not index.isValid(): return None sindex = self.mapToSource(index) return self.sourceModel().item(sindex) def hasChildren(self, parent=QModelIndex()): """ Public method to check for the presence of child items. We always return True for normal items in order to do lazy population of the tree. @param parent index of parent item (QModelIndex) @return flag indicating the presence of child items (boolean) """ sindex = self.mapToSource(parent) return self.sourceModel().hasChildren(sindex) def filterAcceptsRow(self, source_row, source_parent): """ Public method to filter rows. It implements a filter to suppress the display of non public classes, methods and attributes. @param source_row row number (in the source model) of item (integer) @param source_parent index of parent item (in the source model) of item (QModelIndex) @return flag indicating, if the item should be shown (boolean) """ if self.hideNonPublic: sindex = self.sourceModel().index(source_row, 0, source_parent) return self.sourceModel().item(sindex).isPublic() else: return True def preferencesChanged(self): """ Public slot called to handle a change of the preferences settings. """ hideNonPublic = Preferences.getUI("BrowsersHideNonPublic") if self.hideNonPublic != hideNonPublic: self.hideNonPublic = hideNonPublic self.invalidateFilter() eric-6.0.8/eric/UI/NumbersWidget.ui0000644000175000017500000002335412263274750016117 0ustar piotrpiotr NumbersWidget 0 0 749 160 Numbers Formats 0 0 0 0 Binary 2 2 2 2 Press to import the selected binary number Enter the binary number 64 Press to send the binary number to the current editor Octal 2 2 2 2 Press to import the selected octal number Enter the octal number 24 Press to send the octal number to the current editor Decimal 2 2 2 2 Press to import the selected decimal number Enter the decimal number 22 Press to send the decimal number to the current editor Hexadecimal 2 2 2 2 Press to import the selected hex number Enter the hex number 16 Press to send the hex number to the current editor QAbstractItemView::AllEditTriggers false false false QAbstractItemView::ScrollPerPixel QAbstractItemView::ScrollPerPixel false false false Input Format: Select the input format true Qt::AlignCenter Bitsize: Select the bit size true Qt::AlignCenter Press to swap the current byte order Swap byte order Qt::Vertical 62 13 E5TextSpinBox QSpinBox
E5Gui/E5TextSpinBox.h
binInButton binEdit binOutButton octInButton octEdit octOutButton decInButton decEdit decOutButton hexInButton hexEdit hexOutButton binTable formatBox sizeBox byteOrderButton
eric-6.0.8/eric/UI/SymbolsWidget.py0000644000175000017500000006020612451233374016140 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a widget to select a symbol in various formats. """ from __future__ import unicode_literals import sys import unicodedata try: # Py3 import html.entities as html_entities except (ImportError): chr = unichr # __IGNORE_WARNING__ import htmlentitydefs as html_entities # __IGNORE_WARNING__ from PyQt5.QtCore import pyqtSlot, pyqtSignal, QAbstractTableModel, \ QModelIndex, Qt, qVersion, QItemSelectionModel from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QWidget, QHeaderView, QAbstractItemView from .Ui_SymbolsWidget import Ui_SymbolsWidget import UI.PixmapCache import Preferences class SymbolsModel(QAbstractTableModel): """ Class implementing the model for the symbols widget. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(SymbolsModel, self).__init__(parent) self.__headerData = [ self.tr("Code"), self.tr("Char"), self.tr("Hex"), self.tr("HTML"), self.tr("Name"), ] self.__tables = [ # first last display name (0x0, 0x1f, self.tr("Control Characters")), (0x20, 0x7f, self.tr("Basic Latin")), (0x80, 0xff, self.tr("Latin-1 Supplement")), (0x100, 0x17f, self.tr("Latin Extended-A")), (0x180, 0x24f, self.tr("Latin Extended-B")), (0x250, 0x2af, self.tr("IPA Extensions")), (0x2b0, 0x2ff, self.tr("Spacing Modifier Letters")), (0x300, 0x36f, self.tr("Combining Diacritical Marks")), (0x370, 0x3ff, self.tr("Greek and Coptic")), (0x400, 0x4ff, self.tr("Cyrillic")), (0x500, 0x52f, self.tr("Cyrillic Supplement")), (0x530, 0x58f, self.tr("Armenian")), (0x590, 0x5ff, self.tr("Hebrew")), (0x600, 0x6ff, self.tr("Arabic")), (0x700, 0x74f, self.tr("Syriac")), (0x780, 0x7bf, self.tr("Thaana")), (0x7c0, 0x7ff, self.tr("N'Ko")), (0x800, 0x83f, self.tr("Samaritan")), (0x840, 0x85f, self.tr("Mandaic")), (0x8a0, 0x8ff, self.tr("Arabic Extended-A")), (0x900, 0x97f, self.tr("Devanagari")), (0x980, 0x9ff, self.tr("Bengali")), (0xa00, 0xa7f, self.tr("Gurmukhi")), (0xa80, 0xaff, self.tr("Gujarati")), (0xb00, 0xb7f, self.tr("Oriya")), (0xb80, 0xbff, self.tr("Tamil")), (0xc00, 0xc7f, self.tr("Telugu")), (0xc80, 0xcff, self.tr("Kannada")), (0xd00, 0xd7f, self.tr("Malayalam")), (0xd80, 0xdff, self.tr("Sinhala")), (0xe00, 0xe7f, self.tr("Thai")), (0xe80, 0xeff, self.tr("Lao")), (0xf00, 0xfff, self.tr("Tibetan")), (0x1000, 0x109f, self.tr("Myanmar")), (0x10a0, 0x10ff, self.tr("Georgian")), (0x1100, 0x11ff, self.tr("Hangul Jamo")), (0x1200, 0x137f, self.tr("Ethiopic")), (0x1380, 0x139f, self.tr("Ethiopic Supplement")), (0x13a0, 0x13ff, self.tr("Cherokee")), (0x1400, 0x167f, self.tr("Unified Canadian Aboriginal Syllabics")), (0x1680, 0x169f, self.tr("Ogham")), (0x16a0, 0x16ff, self.tr("Runic")), (0x1700, 0x171f, self.tr("Tagalog")), (0x1720, 0x173f, self.tr("Hanunoo")), (0x1740, 0x175f, self.tr("Buhid")), (0x1760, 0x177f, self.tr("Tagbanwa")), (0x1780, 0x17ff, self.tr("Khmer")), (0x1800, 0x18af, self.tr("Mongolian")), (0x18b0, 0x18ff, self.tr("Unified Canadian Aboriginal Syllabics Extended")), (0x1900, 0x194f, self.tr("Limbu")), (0x1950, 0x197f, self.tr("Tai Le")), (0x19e0, 0x19ff, self.tr("Khmer Symbols")), (0x1a00, 0x1a1f, self.tr("Buginese")), (0x1a20, 0x1aaf, self.tr("Tai Tham")), (0x1b00, 0x1b7f, self.tr("Balinese")), (0x1b80, 0x1bbf, self.tr("Sundanese")), (0x1bc0, 0x1bff, self.tr("Batak")), (0x1c00, 0x1c4f, self.tr("Lepcha")), (0x1c50, 0x1c7f, self.tr("Ol Chiki")), (0x1cc0, 0x1ccf, self.tr("Sundanese Supplement")), (0x1cd0, 0x1cff, self.tr("Vedic Extensions")), (0x1d00, 0x1d7f, self.tr("Phonetic Extensions")), (0x1d80, 0x1dbf, self.tr("Phonetic Extensions Supplement")), (0x1dc0, 0x1dff, self.tr("Combining Diacritical Marks Supplement")), (0x1e00, 0x1eff, self.tr("Latin Extended Additional")), (0x1f00, 0x1fff, self.tr("Greek Extended")), (0x2000, 0x206f, self.tr("General Punctuation")), (0x2070, 0x209f, self.tr("Superscripts and Subscripts")), (0x20a0, 0x20cf, self.tr("Currency Symbols")), (0x20d0, 0x20ff, self.tr("Combining Diacritical Marks")), (0x2100, 0x214f, self.tr("Letterlike Symbols")), (0x2150, 0x218f, self.tr("Number Forms")), (0x2190, 0x21ff, self.tr("Arcolumns")), (0x2200, 0x22ff, self.tr("Mathematical Operators")), (0x2300, 0x23ff, self.tr("Miscellaneous Technical")), (0x2400, 0x243f, self.tr("Control Pictures")), (0x2440, 0x245f, self.tr("Optical Character Recognition")), (0x2460, 0x24ff, self.tr("Enclosed Alphanumerics")), (0x2500, 0x257f, self.tr("Box Drawing")), (0x2580, 0x259f, self.tr("Block Elements")), (0x25A0, 0x25ff, self.tr("Geometric Shapes")), (0x2600, 0x26ff, self.tr("Miscellaneous Symbols")), (0x2700, 0x27bf, self.tr("Dingbats")), (0x27c0, 0x27ef, self.tr("Miscellaneous Mathematical Symbols-A")), (0x27f0, 0x27ff, self.tr("Supplement Arcolumns-A")), (0x2800, 0x28ff, self.tr("Braille Patterns")), (0x2900, 0x297f, self.tr("Supplement Arcolumns-B")), (0x2980, 0x29ff, self.tr("Miscellaneous Mathematical Symbols-B")), (0x2a00, 0x2aff, self.tr("Supplemental Mathematical Operators")), (0x2b00, 0x2bff, self.tr("Miscellaneous Symbols and Arcolumns")), (0x2c00, 0x2c5f, self.tr("Glagolitic")), (0x2c60, 0x2c7f, self.tr("Latin Extended-C")), (0x2c80, 0x2cff, self.tr("Coptic")), (0x2d00, 0x2d2f, self.tr("Georgian Supplement")), (0x2d30, 0x2d7f, self.tr("Tifinagh")), (0x2d80, 0x2ddf, self.tr("Ethiopic Extended")), (0x2de0, 0x2dff, self.tr("Cyrillic Extended-A")), (0x2e00, 0x2e7f, self.tr("Supplemental Punctuation")), (0x2e80, 0x2eff, self.tr("CJK Radicals Supplement")), (0x2f00, 0x2fdf, self.tr("KangXi Radicals")), (0x2ff0, 0x2fff, self.tr("Ideographic Description Chars")), (0x3000, 0x303f, self.tr("CJK Symbols and Punctuation")), (0x3040, 0x309f, self.tr("Hiragana")), (0x30a0, 0x30ff, self.tr("Katakana")), (0x3100, 0x312f, self.tr("Bopomofo")), (0x3130, 0x318f, self.tr("Hangul Compatibility Jamo")), (0x3190, 0x319f, self.tr("Kanbun")), (0x31a0, 0x31bf, self.tr("Bopomofo Extended")), (0x31c0, 0x31ef, self.tr("CJK Strokes")), (0x31f0, 0x31ff, self.tr("Katakana Phonetic Extensions")), (0x3200, 0x32ff, self.tr("Enclosed CJK Letters and Months")), (0x3300, 0x33ff, self.tr("CJK Compatibility")), (0x3400, 0x4dbf, self.tr("CJK Unified Ideogr. Ext. A")), (0x4dc0, 0x4dff, self.tr("Yijing Hexagram Symbols")), (0x4e00, 0x9fff, self.tr("CJK Unified Ideographs")), (0xa000, 0xa48f, self.tr("Yi Syllables")), (0xa490, 0xa4cf, self.tr("Yi Radicals")), (0xa4d0, 0xa4ff, self.tr("Lisu")), (0xa500, 0xa63f, self.tr("Vai")), (0xa640, 0xa69f, self.tr("Cyrillic Extended-B")), (0xa6a0, 0xa6ff, self.tr("Bamum")), (0xa700, 0xa71f, self.tr("Modifier Tone Letters")), (0xa720, 0xa7ff, self.tr("Latin Extended-D")), (0xa800, 0xa82f, self.tr("Syloti Nagri")), (0xa830, 0xa83f, self.tr("Common Indic Number Forms")), (0xa840, 0xa87f, self.tr("Phags-pa")), (0xa880, 0xa8df, self.tr("Saurashtra")), (0xa8e0, 0xa8ff, self.tr("Devanagari Extended")), (0xa900, 0xa92f, self.tr("Kayah Li")), (0xa930, 0xa95f, self.tr("Rejang")), (0xa960, 0xa97f, self.tr("Hangul Jamo Extended-A")), (0xa980, 0xa9df, self.tr("Javanese")), (0xaa00, 0xaa5f, self.tr("Cham")), (0xaa60, 0xaa7f, self.tr("Myanmar Extended-A")), (0xaa80, 0xaadf, self.tr("Tai Viet")), (0xaae0, 0xaaff, self.tr("Meetei Mayek Extensions")), (0xab00, 0xab2f, self.tr("Ethiopic Extended-A")), (0xabc0, 0xabff, self.tr("Meetei Mayek")), (0xac00, 0xd7af, self.tr("Hangul Syllables")), (0xd7b0, 0xd7ff, self.tr("Hangul Jamo Extended-B")), (0xd800, 0xdb7f, self.tr("High Surrogates")), (0xdb80, 0xdbff, self.tr("High Private Use Surrogates")), (0xdc00, 0xdfff, self.tr("Low Surrogates")), (0xe000, 0xf8ff, self.tr("Private Use")), (0xf900, 0xfaff, self.tr("CJK Compatibility Ideographs")), (0xfb00, 0xfb4f, self.tr("Alphabetic Presentation Forms")), (0xfb50, 0xfdff, self.tr("Arabic Presentation Forms-A")), (0xfe00, 0xfe0f, self.tr("Variation Selectors")), (0xfe10, 0xfe1f, self.tr("Vertical Forms")), (0xfe20, 0xfe2f, self.tr("Combining Half Marks")), (0xfe30, 0xfe4f, self.tr("CJK Compatibility Forms")), (0xfe50, 0xfe6f, self.tr("Small Form Variants")), (0xfe70, 0xfeff, self.tr("Arabic Presentation Forms-B")), (0xff00, 0xffef, self.tr("Half- and Fullwidth Forms")), (0xfff0, 0xffff, self.tr("Specials")), ] if sys.maxunicode > 0xffff: self.__tables.extend([ (0x10000, 0x1007f, self.tr("Linear B Syllabary")), (0x10080, 0x100ff, self.tr("Linear B Ideograms")), (0x10100, 0x1013f, self.tr("Aegean Numbers")), (0x10140, 0x1018f, self.tr("Ancient Greek Numbers")), (0x10190, 0x101cf, self.tr("Ancient Symbols")), (0x101d0, 0x101ff, self.tr("Phaistos Disc")), (0x10280, 0x1029f, self.tr("Lycian")), (0x102a0, 0x102df, self.tr("Carian")), (0x10300, 0x1032f, self.tr("Old Italic")), (0x10330, 0x1034f, self.tr("Gothic")), (0x10380, 0x1039f, self.tr("Ugaritic")), (0x103a0, 0x103df, self.tr("Old Persian")), (0x10400, 0x1044f, self.tr("Deseret")), (0x10450, 0x1047f, self.tr("Shavian")), (0x10480, 0x104af, self.tr("Osmanya")), (0x10800, 0x1083f, self.tr("Cypriot Syllabary")), (0x10840, 0x1085f, self.tr("Imperial Aramaic")), (0x10900, 0x1091f, self.tr("Phoenician")), (0x10920, 0x1093f, self.tr("Lydian")), (0x10980, 0x1099f, self.tr("Meroitic Hieroglyphs")), (0x109a0, 0x109ff, self.tr("Meroitic Cursive")), (0x10a00, 0x10a5f, self.tr("Kharoshthi")), (0x10a60, 0x10a7f, self.tr("Old South Arabian")), (0x10b00, 0x10b3f, self.tr("Avestan")), (0x10b40, 0x10b5f, self.tr("Inscriptional Parthian")), (0x10b60, 0x10b7f, self.tr("Inscriptional Pahlavi")), (0x10c00, 0x10c4f, self.tr("Old Turkic")), (0x10e60, 0x10e7f, self.tr("Rumi Numeral Symbols")), (0x11000, 0x1107f, self.tr("Brahmi")), (0x11080, 0x110cf, self.tr("Kaithi")), (0x110d0, 0x110ff, self.tr("Sora Sompeng")), (0x11100, 0x1114f, self.tr("Chakma")), (0x11180, 0x111df, self.tr("Sharada")), (0x11680, 0x116cf, self.tr("Takri")), (0x12000, 0x123ff, self.tr("Cuneiform")), (0x12400, 0x1247f, self.tr("Cuneiform Numbers and Punctuation")), (0x13000, 0x1342f, self.tr("Egyptian Hieroglyphs")), (0x16800, 0x16a3f, self.tr("Bamum Supplement")), (0x16f00, 0x16f9f, self.tr("Miao")), (0x1b000, 0x1b0ff, self.tr("Kana Supplement")), (0x1d000, 0x1d0ff, self.tr("Byzantine Musical Symbols")), (0x1d100, 0x1d1ff, self.tr("Musical Symbols")), (0x1d200, 0x1d24f, self.tr("Ancient Greek Musical Notation")), (0x1d300, 0x1d35f, self.tr("Tai Xuan Jing Symbols")), (0x1d360, 0x1d37f, self.tr("Counting Rod Numerals")), (0x1d400, 0x1d7ff, self.tr("Mathematical Alphanumeric Symbols")), (0x1ee00, 0x1eeff, self.tr("Arabic Mathematical Alphabetic Symbols")), (0x1f000, 0x1f02f, self.tr("Mahjong Tiles")), (0x1f030, 0x1f09f, self.tr("Domino Tiles")), (0x1f0a0, 0x1f0ff, self.tr("Playing Cards")), (0x1f100, 0x1f1ff, self.tr("Enclosed Alphanumeric Supplement")), (0x1f200, 0x1f2ff, self.tr("Enclosed Ideographic Supplement")), (0x1f300, 0x1f5ff, self.tr("Miscellaneous Symbols And Pictographs")), (0x1f600, 0x1f64f, self.tr("Emoticons")), (0x1f680, 0x1f6ff, self.tr("Transport And Map Symbols")), (0x1f700, 0x1f77f, self.tr("Alchemical Symbols")), (0x20000, 0x2a6df, self.tr("CJK Unified Ideogr. Ext. B")), (0x2a700, 0x2b73f, self.tr("CJK Unified Ideographs Extension C")), (0x2b740, 0x2b81f, self.tr("CJK Unified Ideographs Extension D")), (0x2f800, 0x2fa1f, self.tr("CJK Compatapility Ideogr. Suppl.")), (0xe0000, 0xe007f, self.tr("Tags")), (0xe0100, 0xe01ef, self.tr("Variation Selectors Supplement")), (0xf0000, 0xfffff, self.tr("Supplementary Private Use Area-A")), (0x100000, 0x10ffff, self.tr("Supplementary Private Use Area-B")), ]) self.__currentTableIndex = 0 def getTableNames(self): """ Public method to get a list of table names. @return list of table names (list of strings) """ return [table[2] for table in self.__tables] def getTableBoundaries(self, index): """ Public method to get the first and last character position of the given table. @param index index of the character table (integer) @return first and last character position (integer, integer) """ return self.__tables[index][0], self.__tables[index][1] def getTableIndex(self): """ Public method to get the current table index. @return current table index (integer) """ return self.__currentTableIndex def selectTable(self, index): """ Public method to select the shown character table. @param index index of the character table (integer) """ self.beginResetModel() self.__currentTableIndex = index self.endResetModel() def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get header data from the model. @param section section number (integer) @param orientation orientation (Qt.Orientation) @param role role of the data to retrieve (integer) @return requested data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.__headerData[section] return QAbstractTableModel.headerData(self, section, orientation, role) def data(self, index, role=Qt.DisplayRole): """ Public method to get data from the model. @param index index to get data for (QModelIndex) @param role role of the data to retrieve (integer) @return requested data """ id = self.__tables[self.__currentTableIndex][0] + index.row() if role == Qt.DisplayRole: col = index.column() if col == 0: return str(id) elif col == 1: return chr(id) elif col == 2: return "0x{0:04x}".format(id) elif col == 3: if id in html_entities.codepoint2name: return "&{0};".format(html_entities.codepoint2name[id]) elif col == 4: return unicodedata.name(chr(id), '').title() if role == Qt.BackgroundColorRole: if index.column() == 0: return QColor(Qt.lightGray) if role == Qt.TextColorRole: char = chr(id) if self.__isDigit(char): return QColor(Qt.darkBlue) elif self.__isLetter(char): return QColor(Qt.darkGreen) elif self.__isMark(char): return QColor(Qt.darkRed) elif self.__isSymbol(char): return QColor(Qt.black) elif self.__isPunct(char): return QColor(Qt.darkMagenta) else: return QColor(Qt.darkGray) if role == Qt.TextAlignmentRole: if index.column() in [0, 1, 3]: return Qt.AlignHCenter return None def columnCount(self, parent): """ Public method to get the number of columns of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.column() > 0: return 0 else: return len(self.__headerData) def rowCount(self, parent): """ Public method to get the number of rows of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.isValid(): return 0 else: first, last = self.__tables[self.__currentTableIndex][:2] return last - first + 1 def __isDigit(self, char): """ Private method to check, if a character is a digit. @param char character to test (one character string) @return flag indicating a digit (boolean) """ return unicodedata.category(char) == "Nd" def __isLetter(self, char): """ Private method to check, if a character is a letter. @param char character to test (one character string) @return flag indicating a letter (boolean) """ return unicodedata.category(char) in ["Lu", "Ll", "Lt", "Lm", "Lo"] def __isMark(self, char): """ Private method to check, if a character is a mark character. @param char character to test (one character string) @return flag indicating a mark character (boolean) """ return unicodedata.category(char) in ["Mn", "Mc", "Me"] def __isSymbol(self, char): """ Private method to check, if a character is a symbol. @param char character to test (one character string) @return flag indicating a symbol (boolean) """ return unicodedata.category(char) in ["Sm", "Sc", "Sk", "So"] def __isPunct(self, char): """ Private method to check, if a character is a punctuation character. @param char character to test (one character string) @return flag indicating a punctuation character (boolean) """ return unicodedata.category(char) in ["Pc", "Pd", "Ps", "Pe", "Pi", "Pf", "Po"] class SymbolsWidget(QWidget, Ui_SymbolsWidget): """ Class implementing a widget to select a symbol in various formats. @signal insertSymbol(str) emitted after the user has selected a symbol """ insertSymbol = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(SymbolsWidget, self).__init__(parent) self.setupUi(self) self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__model = SymbolsModel(self) self.symbolsTable.setModel(self.__model) self.symbolsTable.selectionModel().currentRowChanged.connect( self.__currentRowChanged) if qVersion() >= "5.0.0": self.symbolsTable.horizontalHeader().setSectionResizeMode( QHeaderView.Fixed) else: self.symbolsTable.horizontalHeader().setResizeMode( QHeaderView.Fixed) fm = self.fontMetrics() em = fm.width("M") self.symbolsTable.horizontalHeader().resizeSection(0, em * 5) self.symbolsTable.horizontalHeader().resizeSection(1, em * 5) self.symbolsTable.horizontalHeader().resizeSection(2, em * 6) self.symbolsTable.horizontalHeader().resizeSection(3, em * 8) self.symbolsTable.horizontalHeader().resizeSection(4, em * 85) self.symbolsTable.verticalHeader().setDefaultSectionSize( fm.height() + 4) tableIndex = int( Preferences.Prefs.settings.value("Symbols/CurrentTable", 1)) self.tableCombo.addItems(self.__model.getTableNames()) self.tableCombo.setCurrentIndex(tableIndex) index = self.__model.index( int(Preferences.Prefs.settings.value("Symbols/Top", 0)), 0) self.symbolsTable.scrollTo(index, QAbstractItemView.PositionAtTop) self.symbolsTable.selectionModel().setCurrentIndex( index, QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows) @pyqtSlot(QModelIndex) def on_symbolsTable_activated(self, index): """ Private slot to signal the selection of a symbol. @param index index of the selected symbol (QModelIndex) """ txt = self.__model.data(index) if txt: self.insertSymbol.emit(txt) @pyqtSlot() def on_symbolSpinBox_editingFinished(self): """ Private slot to move the table to the entered symbol id. """ id = self.symbolSpinBox.value() first, last = self.__model.getTableBoundaries( self.__model.getTableIndex()) row = id - first self.symbolsTable.selectRow(row) self.symbolsTable.scrollTo( self.__model.index(row, 0), QAbstractItemView.PositionAtCenter) @pyqtSlot(int) def on_tableCombo_currentIndexChanged(self, index): """ Private slot to select the current character table. @param index index of the character table (integer) """ self.symbolsTable.setUpdatesEnabled(False) self.__model.selectTable(index) self.symbolsTable.setUpdatesEnabled(True) first, last = self.__model.getTableBoundaries(index) self.symbolSpinBox.setMinimum(first) self.symbolSpinBox.setMaximum(last) Preferences.Prefs.settings.setValue("Symbols/CurrentTable", index) def __currentRowChanged(self, current, previous): """ Private slot recording the currently selected row. @param current current index (QModelIndex) @param previous previous current index (QModelIndex) """ Preferences.Prefs.settings.setValue("Symbols/Top", current.row()) self.symbolSpinBox.setValue(int( self.__model.data(self.__model.index(current.row(), 0)))) eric-6.0.8/eric/UI/Browser.py0000644000175000017500000006222312451233374014770 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing a browser with class browsing capabilities. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QModelIndex, pyqtSignal, QUrl, Qt, qVersion, \ QCoreApplication, QItemSelectionModel from PyQt5.QtGui import QDesktopServices from PyQt5.QtWidgets import QTreeView, QApplication, QMenu, QAbstractItemView from E5Gui.E5Application import e5App from E5Gui import E5FileDialog from .BrowserModel import BrowserModel, BrowserDirectoryItem, \ BrowserFileItem, BrowserClassItem, BrowserMethodItem, \ BrowserClassAttributeItem from .BrowserSortFilterProxyModel import BrowserSortFilterProxyModel import UI.PixmapCache import Preferences import Utilities import Utilities.MimeTypes class Browser(QTreeView): """ Class used to display a file system tree. Via the context menu that is displayed by a right click the user can select various actions on the selected file. @signal sourceFile(str, int = 0, str = "") emitted to open a Python file at a line @signal designerFile(str) emitted to open a Qt-Designer file @signal linguistFile(str) emitted to open a Qt-Linguist (*.ts) file @signal trpreview(list of str, bool = False) emitted to preview a Qt-Linguist (*.qm) file @signal projectFile(str) emitted to open an eric4/5 project file @signal multiProjectFile(str) emitted to open an eric4/5 multi project file @signal pixmapFile(str) emitted to open a pixmap file @signal pixmapEditFile(str) emitted to edit a pixmap file @signal svgFile(str) emitted to open a SVG file @signal unittestOpen(str) emitted to open a Python file for a unittest """ sourceFile = pyqtSignal((str, ), (str, int), (str, int, str)) designerFile = pyqtSignal(str) linguistFile = pyqtSignal(str) trpreview = pyqtSignal((list, ), (list, bool)) projectFile = pyqtSignal(str) multiProjectFile = pyqtSignal(str) pixmapFile = pyqtSignal(str) pixmapEditFile = pyqtSignal(str) svgFile = pyqtSignal(str) unittestOpen = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(Browser, self).__init__(parent) self.setWindowTitle(QCoreApplication.translate('Browser', 'File-Browser')) self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__embeddedBrowser = Preferences.getUI("LayoutFileBrowserEmbedded") self.__model = BrowserModel() self.__sortModel = BrowserSortFilterProxyModel() self.__sortModel.setSourceModel(self.__model) self.setModel(self.__sortModel) self.selectedItemsFilter = [BrowserFileItem] self._activating = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._contextMenuRequested) self.activated.connect(self._openItem) self.expanded.connect(self._resizeColumns) self.collapsed.connect(self._resizeColumns) self.setWhatsThis(QCoreApplication.translate( 'Browser', """The Browser Window""" """

This allows you to easily navigate the hierarchy of""" """ directories and files on your system, identify the Python""" """ programs and open them up in a Source Viewer window. The""" """ window displays several separate hierarchies.

""" """

The first hierarchy is only shown if you have opened a""" """ program for debugging and its root is the directory""" """ containing that program. Usually all of the separate files""" """ that make up a Python application are held in the same""" """ directory, so this hierarchy gives you easy access to most""" """ of what you will need.

""" """

The next hierarchy is used to easily navigate the""" """ directories that are specified in the Python""" """ sys.path variable.

""" """

The remaining hierarchies allow you navigate your system""" """ as a whole. On a UNIX system there will be a hierarchy with""" """ / at its root and another with the user home""" """ directory. On a Windows system there will be a hierarchy for""" """ each drive on the""" """ system.

""" """

Python programs (i.e. those with a .py file name""" """ suffix) are identified in the hierarchies with a Python""" """ icon. The right mouse button will popup a menu which lets""" """ you open the file in a Source Viewer window, open the file""" """ for debugging or use it for a unittest run.

""" """

The context menu of a class, function or method allows you""" """ to open the file defining this class, function or method and""" """ will ensure, that the correct source line is visible.

""" """

Qt-Designer files (i.e. those with a .ui file""" """ name suffix) are shown with a Designer icon. The context""" """ menu of these files allows you to start Qt-Designer with""" """ that file.

""" """

Qt-Linguist files (i.e. those with a .ts file""" """ name suffix) are shown with a Linguist icon. The context""" """ menu of these files allows you to start Qt-Linguist with""" """ that file.

""" )) self.__createPopupMenus() self._init() # perform common initialization tasks def _init(self): """ Protected method to perform initialization tasks common to this base class and all derived classes. """ self.setRootIsDecorated(True) self.setAlternatingRowColors(True) header = self.header() header.setSortIndicator(0, Qt.AscendingOrder) header.setSortIndicatorShown(True) if qVersion() >= "5.0.0": header.setSectionsClickable(True) else: header.setClickable(True) self.setSortingEnabled(True) self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.header().setStretchLastSection(True) self.headerSize0 = 0 self.layoutDisplay() def layoutDisplay(self): """ Public slot to perform a layout operation. """ self._resizeColumns(QModelIndex()) self._resort() def _resizeColumns(self, index): """ Protected slot to resize the view when items get expanded or collapsed. @param index index of item (QModelIndex) """ w = max(100, self.sizeHintForColumn(0)) if w != self.headerSize0: self.header().resizeSection(0, w) self.headerSize0 = w def _resort(self): """ Protected slot to resort the tree. """ self.model().sort(self.header().sortIndicatorSection(), self.header().sortIndicatorOrder()) def __createPopupMenus(self): """ Private method to generate the various popup menus. """ # create the popup menu for source files self.sourceMenu = QMenu(self) self.sourceMenu.addAction( QCoreApplication.translate('Browser', 'Open'), self._openItem) self.unittestAct = self.sourceMenu.addAction( QCoreApplication.translate('Browser', 'Run unittest...'), self.handleUnittest) self.sourceMenu.addAction( QCoreApplication.translate('Browser', 'Copy Path to Clipboard'), self._copyToClipboard) # create the popup menu for general use self.menu = QMenu(self) self.menu.addAction( QCoreApplication.translate('Browser', 'Open'), self._openItem) self.editPixmapAct = self.menu.addAction( QCoreApplication.translate('Browser', 'Open in Icon Editor'), self._editPixmap) self.menu.addAction( QCoreApplication.translate('Browser', 'Copy Path to Clipboard'), self._copyToClipboard) if self.__embeddedBrowser in [1, 2]: self.menu.addSeparator() self.menu.addAction( QCoreApplication.translate('Browser', 'Configure...'), self.__configure) # create the menu for multiple selected files self.multiMenu = QMenu(self) self.multiMenu.addAction( QCoreApplication.translate('Browser', 'Open'), self._openItem) if self.__embeddedBrowser in [1, 2]: self.multiMenu.addSeparator() self.multiMenu.addAction( QCoreApplication.translate('Browser', 'Configure...'), self.__configure) # create the directory menu self.dirMenu = QMenu(self) self.dirMenu.addAction( QCoreApplication.translate('Browser', 'New toplevel directory...'), self.__newToplevelDir) self.addAsTopLevelAct = self.dirMenu.addAction( QCoreApplication.translate('Browser', 'Add as toplevel directory'), self.__addAsToplevelDir) self.removeFromToplevelAct = self.dirMenu.addAction( QCoreApplication.translate('Browser', 'Remove from toplevel'), self.__removeToplevel) self.dirMenu.addSeparator() self.dirMenu.addAction( QCoreApplication.translate('Browser', 'Refresh directory'), self.__refreshDirectory) self.dirMenu.addSeparator() self.dirMenu.addAction( QCoreApplication.translate('Browser', 'Find in this directory'), self.__findInDirectory) self.dirMenu.addAction( QCoreApplication.translate( 'Browser', 'Find&&Replace in this directory'), self.__replaceInDirectory) self.dirMenu.addAction( QCoreApplication.translate('Browser', 'Copy Path to Clipboard'), self._copyToClipboard) if self.__embeddedBrowser in [1, 2]: self.dirMenu.addSeparator() self.dirMenu.addAction( QCoreApplication.translate('Browser', 'Configure...'), self.__configure) # create the attribute menu self.gotoMenu = QMenu(self.tr("Goto"), self) self.gotoMenu.aboutToShow.connect(self._showGotoMenu) self.gotoMenu.triggered.connect(self._gotoAttribute) self.attributeMenu = QMenu(self) self.attributeMenu.addAction( QCoreApplication.translate('Browser', 'New toplevel directory...'), self.__newToplevelDir) self.attributeMenu.addSeparator() self.attributeMenu.addMenu(self.gotoMenu) if self.__embeddedBrowser in [1, 2]: self.attributeMenu.addSeparator() self.attributeMenu.addAction( QCoreApplication.translate('Browser', 'Configure...'), self.__configure) # create the background menu self.backMenu = QMenu(self) self.backMenu.addAction( QCoreApplication.translate('Browser', 'New toplevel directory...'), self.__newToplevelDir) if self.__embeddedBrowser in [1, 2]: self.backMenu.addSeparator() self.backMenu.addAction( QCoreApplication.translate('Browser', 'Configure...'), self.__configure) def mouseDoubleClickEvent(self, mouseEvent): """ Protected method of QAbstractItemView. Reimplemented to disable expanding/collapsing of items when double-clicking. Instead the double-clicked entry is opened. @param mouseEvent the mouse event (QMouseEvent) """ index = self.indexAt(mouseEvent.pos()) if index.isValid(): self._openItem() def _contextMenuRequested(self, coord): """ Protected slot to show the context menu of the listview. @param coord the position of the mouse pointer (QPoint) """ categories = self.getSelectedItemsCountCategorized( [BrowserDirectoryItem, BrowserFileItem, BrowserClassItem, BrowserMethodItem]) cnt = categories["sum"] bfcnt = categories[str(BrowserFileItem)] if cnt > 1 and cnt == bfcnt: self.multiMenu.popup(self.mapToGlobal(coord)) else: index = self.indexAt(coord) if index.isValid(): self.setCurrentIndex(index) flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) self.selectionModel().select(index, flags) itm = self.model().item(index) coord = self.mapToGlobal(coord) if isinstance(itm, BrowserFileItem): if itm.isPython3File(): if itm.fileName().endswith('.py'): self.unittestAct.setEnabled(True) else: self.unittestAct.setEnabled(False) self.sourceMenu.popup(coord) else: self.editPixmapAct.setVisible(itm.isPixmapFile()) self.menu.popup(coord) elif isinstance(itm, BrowserClassItem) or \ isinstance(itm, BrowserMethodItem): self.menu.popup(coord) elif isinstance(itm, BrowserClassAttributeItem): self.attributeMenu.popup(coord) elif isinstance(itm, BrowserDirectoryItem): if not index.parent().isValid(): self.removeFromToplevelAct.setEnabled(True) self.addAsTopLevelAct.setEnabled(False) else: self.removeFromToplevelAct.setEnabled(False) self.addAsTopLevelAct.setEnabled(True) self.dirMenu.popup(coord) else: self.backMenu.popup(coord) else: self.backMenu.popup(self.mapToGlobal(coord)) def _showGotoMenu(self): """ Protected slot to prepare the goto submenu of the attribute menu. """ self.gotoMenu.clear() itm = self.model().item(self.currentIndex()) linenos = itm.linenos() fileName = itm.fileName() for lineno in sorted(linenos): act = self.gotoMenu.addAction( self.tr("Line {0}".format(lineno))) act.setData([fileName, lineno]) def _gotoAttribute(self, act): """ Protected slot to handle the selection of the goto menu. @param act reference to the action (E5Action) """ fileName, lineno = act.data() self.sourceFile[str, int].emit(fileName, lineno) def handlePreferencesChanged(self): """ Public slot used to handle the preferencesChanged signal. """ self.model().preferencesChanged() self._resort() def _openItem(self): """ Protected slot to handle the open popup menu entry. """ itmList = self.getSelectedItems( [BrowserFileItem, BrowserClassItem, BrowserMethodItem, BrowserClassAttributeItem]) if not self._activating: self._activating = True for itm in itmList: if isinstance(itm, BrowserFileItem): if itm.isPython2File(): self.sourceFile[str].emit(itm.fileName()) elif itm.isPython3File(): self.sourceFile[str].emit(itm.fileName()) elif itm.isRubyFile(): self.sourceFile[str, int, str].emit( itm.fileName(), -1, "Ruby") elif itm.isDFile(): self.sourceFile[str, int, str].emit( itm.fileName(), -1, "D") elif itm.isDesignerFile(): self.designerFile.emit(itm.fileName()) elif itm.isLinguistFile(): if itm.fileExt() == '.ts': self.linguistFile.emit(itm.fileName()) else: self.trpreview.emit([itm.fileName()]) elif itm.isProjectFile(): self.projectFile.emit(itm.fileName()) elif itm.isMultiProjectFile(): self.multiProjectFile.emit(itm.fileName()) elif itm.isIdlFile(): self.sourceFile[str].emit(itm.fileName()) elif itm.isResourcesFile(): self.sourceFile[str].emit(itm.fileName()) elif itm.isSvgFile(): self.svgFile.emit(itm.fileName()) elif itm.isPixmapFile(): self.pixmapFile.emit(itm.fileName()) else: if Utilities.MimeTypes.isTextFile(itm.fileName()): self.sourceFile[str].emit(itm.fileName()) else: QDesktopServices.openUrl(QUrl(itm.fileName())) elif isinstance(itm, BrowserClassItem): self.sourceFile[str, int].emit( itm.fileName(), itm.classObject().lineno) elif isinstance(itm, BrowserMethodItem): self.sourceFile[str, int].emit( itm.fileName(), itm.functionObject().lineno) elif isinstance(itm, BrowserClassAttributeItem): self.sourceFile[str, int].emit( itm.fileName(), itm.attributeObject().lineno) self._activating = False def _editPixmap(self): """ Protected slot to handle the open in icon editor popup menu entry. """ itmList = self.getSelectedItems([BrowserFileItem]) for itm in itmList: if isinstance(itm, BrowserFileItem): if itm.isPixmapFile(): self.pixmapEditFile.emit(itm.fileName()) def _copyToClipboard(self): """ Protected method to copy the text shown for an entry to the clipboard. """ itm = self.model().item(self.currentIndex()) try: fn = itm.fileName() except AttributeError: try: fn = itm.dirName() except AttributeError: fn = "" if fn: cb = QApplication.clipboard() cb.setText(fn) def handleUnittest(self): """ Public slot to handle the unittest popup menu entry. """ try: index = self.currentIndex() itm = self.model().item(index) pyfn = itm.fileName() except AttributeError: pyfn = None if pyfn is not None: self.unittestOpen.emit(pyfn) def __newToplevelDir(self): """ Private slot to handle the New toplevel directory popup menu entry. """ dname = E5FileDialog.getExistingDirectory( None, QCoreApplication.translate('Browser', "New toplevel directory"), "", E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if dname: dname = os.path.abspath(Utilities.toNativeSeparators(dname)) self.__model.addTopLevelDir(dname) def __removeToplevel(self): """ Private slot to handle the Remove from toplevel popup menu entry. """ index = self.currentIndex() sindex = self.model().mapToSource(index) self.__model.removeToplevelDir(sindex) def __addAsToplevelDir(self): """ Private slot to handle the Add as toplevel directory popup menu entry. """ index = self.currentIndex() dname = self.model().item(index).dirName() self.__model.addTopLevelDir(dname) def __refreshDirectory(self): """ Private slot to refresh a directory entry. """ index = self.currentIndex() refreshDir = self.model().item(index).dirName() self.__model.directoryChanged(refreshDir) def __findInDirectory(self): """ Private slot to handle the Find in directory popup menu entry. """ index = self.currentIndex() searchDir = self.model().item(index).dirName() e5App().getObject("UserInterface")\ .showFindFilesDialog(searchDir=searchDir) def __replaceInDirectory(self): """ Private slot to handle the Find&Replace in directory popup menu entry. """ index = self.currentIndex() searchDir = self.model().item(index).dirName() e5App().getObject("UserInterface")\ .showReplaceFilesDialog(searchDir=searchDir) def handleProgramChange(self, fn): """ Public slot to handle the programChange signal. @param fn file name (string) """ self.__model.programChange(os.path.dirname(fn)) def handleInterpreterChanged(self, interpreter): """ Public slot to handle a change of the debug client's interpreter. @param interpreter interpreter of the debug client (string) """ self.__model.interpreterChanged(interpreter) def wantedItem(self, itm, filter=None): """ Public method to check type of an item. @param itm the item to check (BrowserItem) @param filter list of classes to check against @return flag indicating item is a valid type (boolean) """ if filter is None: filter = self.selectedItemsFilter for typ in filter: if isinstance(itm, typ): return True return False def getSelectedItems(self, filter=None): """ Public method to get the selected items. @param filter list of classes to check against @return list of selected items (list of BroweserItem) """ selectedItems = [] indexes = self.selectedIndexes() for index in indexes: if index.column() == 0: itm = self.model().item(index) if self.wantedItem(itm, filter): selectedItems.append(itm) return selectedItems def getSelectedItemsCount(self, filter=None): """ Public method to get the count of items selected. @param filter list of classes to check against @return count of items selected (integer) """ count = 0 indexes = self.selectedIndexes() for index in indexes: if index.column() == 0: itm = self.model().item(index) if self.wantedItem(itm, filter): count += 1 return count def getSelectedItemsCountCategorized(self, filter=None): """ Public method to get a categorized count of selected items. @param filter list of classes to check against @return a dictionary containing the counts of items belonging to the individual filter classes. The keys of the dictionary are the string representation of the classes given in the filter (i.e. str(filterClass)). The dictionary contains an additional entry with key "sum", that stores the sum of all selected entries fulfilling the filter criteria. """ if filter is None: filter = self.selectedItemsFilter categories = {} categories["sum"] = 0 for typ in filter: categories[str(typ)] = 0 indexes = self.selectedIndexes() for index in indexes: if index.column() == 0: itm = self.model().item(index) for typ in filter: if isinstance(itm, typ): categories["sum"] += 1 categories[str(typ)] += 1 return categories def saveToplevelDirs(self): """ Public slot to save the toplevel directories. """ self.__model.saveToplevelDirs() def __configure(self): """ Private method to open the configuration dialog. """ if self.__embeddedBrowser == 1: e5App().getObject("UserInterface")\ .showPreferences("debuggerGeneralPage") elif self.__embeddedBrowser == 2: e5App().getObject("UserInterface")\ .showPreferences("projectBrowserPage") eric-6.0.8/eric/UI/AuthenticationDialog.ui0000644000175000017500000000732412060166053017425 0ustar piotrpiotr AuthenticationDialog 0 0 400 154 0 0 Authentication Required true Icon 0 0 Info true Username: Enter username Password: Enter password QLineEdit::Password Select to save the login data Save login data Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok usernameEdit passwordEdit saveCheckBox buttonBox buttonBox accepted() AuthenticationDialog accept() 29 111 23 117 buttonBox rejected() AuthenticationDialog reject() 87 111 81 117 eric-6.0.8/eric/UI/NumbersWidget.py0000644000175000017500000003401012451233374016115 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a widget to show numbers in different formats. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QAbstractTableModel, \ qVersion from PyQt5.QtWidgets import QWidget, QHeaderView from E5Gui.E5Application import e5App from .Ui_NumbersWidget import Ui_NumbersWidget import UI.PixmapCache class BinaryModel(QAbstractTableModel): """ Class implementing a model for entering binary numbers. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(BinaryModel, self).__init__(parent) self.__bits = 0 self.__value = 0 def rowCount(self, parent): """ Public method to get the number of rows of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ return 1 def columnCount(self, parent): """ Public method to get the number of columns of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ return self.__bits def data(self, index, role=Qt.DisplayRole): """ Public method to get data from the model. @param index index to get data for (QModelIndex) @param role role of the data to retrieve (integer) @return requested data """ if role == Qt.CheckStateRole: return (self.__value >> (self.__bits - index.column() - 1)) & 1 elif role == Qt.DisplayRole: return "" return None def flags(self, index): """ Public method to get flags from the model. @param index index to get flags for (QModelIndex) @return flags (Qt.ItemFlags) """ return Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsSelectable def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get header data from the model. @param section section number (integer) @param orientation orientation (Qt.Orientation) @param role role of the data to retrieve (integer) @return requested data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: return str(self.__bits - section - 1) return QAbstractTableModel.headerData(self, section, orientation, role) def setBits(self, bits): """ Public slot to set the number of bits. @param bits number of bits to show (integer) """ self.beginResetModel() self.__bits = bits self.endResetModel() def setValue(self, value): """ Public slot to set the value to show. @param value value to show (integer) """ self.beginResetModel() self.__value = value self.endResetModel() def setBitsAndValue(self, bits, value): """ Public slot to set the number of bits and the value to show. @param bits number of bits to show (integer) @param value value to show (integer) """ self.__bits = bits self.__value = value self.beginResetModel() self.endResetModel() def getValue(self): """ Public slot to get the current value. @return current value of the model (integer) """ return self.__value def setData(self, index, value, role=Qt.EditRole): """ Public method to set the data of a node cell. @param index index of the node cell (QModelIndex) @param value value to be set @param role role of the data (integer) @return flag indicating success (boolean) """ if role == Qt.CheckStateRole: if value == Qt.Checked and not self.data(index, Qt.CheckStateRole): # that seems like a hack; Qt 4.6 always sends Qt.Checked self.__value |= (1 << self.__bits - index.column() - 1) else: self.__value &= ~(1 << self.__bits - index.column() - 1) self.dataChanged.emit(index, index) return True return False class NumbersWidget(QWidget, Ui_NumbersWidget): """ Class implementing a widget to show numbers in different formats. @signal insertNumber(str) emitted after the user has entered a number and selected the number format """ insertNumber = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(NumbersWidget, self).__init__(parent) self.setupUi(self) self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__badNumberSheet = "background-color: #ffa0a0;" self.binInButton.setIcon(UI.PixmapCache.getIcon("2downarrow.png")) self.binOutButton.setIcon(UI.PixmapCache.getIcon("2uparrow.png")) self.octInButton.setIcon(UI.PixmapCache.getIcon("2downarrow.png")) self.octOutButton.setIcon(UI.PixmapCache.getIcon("2uparrow.png")) self.decInButton.setIcon(UI.PixmapCache.getIcon("2downarrow.png")) self.decOutButton.setIcon(UI.PixmapCache.getIcon("2uparrow.png")) self.hexInButton.setIcon(UI.PixmapCache.getIcon("2downarrow.png")) self.hexOutButton.setIcon(UI.PixmapCache.getIcon("2uparrow.png")) self.formatBox.addItem(self.tr("Auto"), 0) self.formatBox.addItem(self.tr("Dec"), 10) self.formatBox.addItem(self.tr("Hex"), 16) self.formatBox.addItem(self.tr("Oct"), 8) self.formatBox.addItem(self.tr("Bin"), 2) self.sizeBox.addItem("8", 8) self.sizeBox.addItem("16", 16) self.sizeBox.addItem("32", 32) self.sizeBox.addItem("64", 64) self.__input = 0 self.__inputValid = True self.__bytes = 1 self.__model = BinaryModel(self) self.binTable.setModel(self.__model) if qVersion() >= "5.0.0": self.binTable.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) else: self.binTable.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.__model.setBitsAndValue(self.__bytes * 8, self.__input) self.__model.dataChanged.connect(self.__binModelDataChanged) def __formatNumbers(self, format): """ Private method to format the various number inputs. @param format number format indicator (integer) """ self.__block(True) self.binEdit.setStyleSheet("") self.octEdit.setStyleSheet("") self.decEdit.setStyleSheet("") self.hexEdit.setStyleSheet("") # determine byte count bytes = 8 tmp = self.__input for i in range(8): c = (tmp & 0xff00000000000000) >> 7 * 8 if c != 0 and self.__input >= 0: break if c != 0xff and self.__input < 0: break tmp <<= 8 bytes -= 1 if bytes == 0: bytes = 1 self.__bytes = bytes bytesIn = self.sizeBox.itemData(self.sizeBox.currentIndex()) // 8 if bytesIn and bytes > bytesIn: self.sizeBox.setStyleSheet(self.__badNumberSheet) else: self.sizeBox.setStyleSheet("") # octal if format != 8: self.octEdit.setText("{0:0{1}o}".format(self.__input, bytesIn * 3)) # decimal if format != 10: self.decEdit.setText("{0:d}".format(self.__input)) # hexadecimal if format != 16: self.hexEdit.setText("{0:0{1}x}".format(self.__input, bytesIn * 2)) # octal if format != 8: self.octEdit.setText("{0:0{1}o}".format(self.__input, bytesIn * 3)) # binary if format != 2: num = "{0:0{1}b}".format(self.__input, bytesIn * 8) self.binEdit.setText(num) self.__model.setBitsAndValue(len(self.binEdit.text()), self.__input) self.__block(False) def __block(self, b): """ Private slot to block some signals. @param b flah indicating the blocking state (boolean) """ self.hexEdit.blockSignals(b) self.decEdit.blockSignals(b) self.octEdit.blockSignals(b) self.binEdit.blockSignals(b) self.binTable.blockSignals(b) @pyqtSlot(int) def on_sizeBox_valueChanged(self, value): """ Private slot handling a change of the bit size. @param value selected bit size (integer) """ self.__formatNumbers(10) @pyqtSlot() def on_byteOrderButton_clicked(self): """ Private slot to swap the byte order. """ bytesIn = self.sizeBox.itemData(self.sizeBox.currentIndex()) // 8 if bytesIn == 0: bytesIn = self.__bytes tmp1 = self.__input tmp2 = 0 for i in range(bytesIn): tmp2 <<= 8 tmp2 |= tmp1 & 0xff tmp1 >>= 8 self.__input = tmp2 self.__formatNumbers(0) @pyqtSlot() def on_binInButton_clicked(self): """ Private slot to retrieve a binary number from the current editor. """ number = e5App().getObject("ViewManager").getNumber() if number == "": return self.binEdit.setText(number) self.binEdit.setFocus() @pyqtSlot(str) def on_binEdit_textChanged(self, txt): """ Private slot to handle input of a binary number. @param txt text entered (string) """ try: self.__input = int(txt, 2) self.__inputValid = True except ValueError: self.__inputValid = False if self.__inputValid: self.__formatNumbers(2) else: self.binEdit.setStyleSheet(self.__badNumberSheet) @pyqtSlot() def on_binOutButton_clicked(self): """ Private slot to send a binary number. """ self.insertNumber.emit(self.binEdit.text()) def __binModelDataChanged(self, start, end): """ Private slot to handle a change of the binary model value by the user. @param start start index (QModelIndex) @param end end index (QModelIndex) """ val = self.__model.getValue() bytesIn = self.sizeBox.itemData(self.sizeBox.currentIndex()) // 8 num = "{0:0{1}b}".format(val, bytesIn * 8) self.binEdit.setText(num) @pyqtSlot() def on_octInButton_clicked(self): """ Private slot to retrieve an octal number from the current editor. """ number = e5App().getObject("ViewManager").getNumber() if number == "": return self.octEdit.setText(number) self.octEdit.setFocus() @pyqtSlot(str) def on_octEdit_textChanged(self, txt): """ Private slot to handle input of an octal number. @param txt text entered (string) """ try: self.__input = int(txt, 8) self.__inputValid = True except ValueError: self.__inputValid = False if self.__inputValid: self.__formatNumbers(8) else: self.octEdit.setStyleSheet(self.__badNumberSheet) @pyqtSlot() def on_octOutButton_clicked(self): """ Private slot to send an octal number. """ self.insertNumber.emit(self.octEdit.text()) @pyqtSlot() def on_decInButton_clicked(self): """ Private slot to retrieve a decimal number from the current editor. """ number = e5App().getObject("ViewManager").getNumber() if number == "": return self.decEdit.setText(number) self.decEdit.setFocus() @pyqtSlot(str) def on_decEdit_textChanged(self, txt): """ Private slot to handle input of a decimal number. @param txt text entered (string) """ try: self.__input = int(txt, 10) self.__inputValid = True except ValueError: self.__inputValid = False if self.__inputValid: self.__formatNumbers(10) else: self.decEdit.setStyleSheet(self.__badNumberSheet) @pyqtSlot() def on_decOutButton_clicked(self): """ Private slot to send a decimal number. """ self.insertNumber.emit(self.decEdit.text()) @pyqtSlot() def on_hexInButton_clicked(self): """ Private slot to retrieve a hexadecimal number from the current editor. """ number = e5App().getObject("ViewManager").getNumber() if number == "": return self.hexEdit.setText(number) self.hexEdit.setFocus() @pyqtSlot(str) def on_hexEdit_textChanged(self, txt): """ Private slot to handle input of a hexadecimal number. @param txt text entered (string) """ try: self.__input = int(txt, 16) self.__inputValid = True except ValueError: self.__inputValid = False if self.__inputValid: self.__formatNumbers(16) else: self.hexEdit.setStyleSheet(self.__badNumberSheet) @pyqtSlot() def on_hexOutButton_clicked(self): """ Private slot to send a hexadecimal number. """ self.insertNumber.emit(self.hexEdit.text()) eric-6.0.8/eric/eric6_plugininstall.py0000644000175000017500000000333612451233374017005 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Eric6 Plugin Installer. This is the main Python script to install eric6 plugins from outside of the IDE. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from PluginManager.PluginInstallDialog import PluginInstallWindow return PluginInstallWindow(argv[1:]) def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ("", "names of plugins to install") ] appinfo = AppInfo.makeAppInfo(sys.argv, "Eric6 Plugin Installer", "", "Plugin installation utility for eric6", options) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/Globals/0000755000175000017500000000000012557365360014044 5ustar piotrpiotreric-6.0.8/eric/Globals/AppInfo.py0000644000175000017500000000211212451233374015736 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a function to generate an application info. """ from __future__ import unicode_literals from UI.Info import Version def makeAppInfo(argv, name, arg, description, options=[]): """ Module function to generate a dictionary describing the application. @param argv list of commandline parameters (list of strings) @param name name of the application (string) @param arg commandline arguments (string) @param description text describing the application (string) @param options list of additional commandline options (list of tuples of two strings (commandline option, option description)). The options --version, --help and -h are always present and must not be repeated in this list. @return dictionary describing the application """ return { "bin": argv[0], "arg": arg, "name": name, "description": description, "version": Version, "options": options } eric-6.0.8/eric/Globals/__init__.py0000644000175000017500000002106112520643724016146 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module defining common data to be used by all modules. """ from __future__ import unicode_literals import sys import os from PyQt5.QtCore import QDir, QLibraryInfo, QByteArray # names of the various settings objects settingsNameOrganization = "Eric6" settingsNameGlobal = "eric6" settingsNameRecent = "eric6recent" # key names of the various recent entries recentNameMultiProject = "MultiProjects" recentNameProject = "Projects" recentNameFiles = "Files" recentNameHosts = "Hosts6" configDir = None def isWindowsPlatform(): """ Function to check, if this is a Windows platform. @return flag indicating Windows platform (boolean) """ return sys.platform.startswith("win") def isMacPlatform(): """ Function to check, if this is a Mac platform. @return flag indicating Mac platform (boolean) """ return sys.platform == "darwin" def isLinuxPlatform(): """ Function to check, if this is a Linux platform. @return flag indicating Linux platform (boolean) """ return sys.platform.startswith("linux") def checkBlacklistedVersions(): """ Module functions to check for blacklisted versions of the prerequisites. @return flag indicating good versions were found (boolean) """ from install import BlackLists, PlatformsBlackLists # determine the platform dependent black list if isWindowsPlatform(): PlatformBlackLists = PlatformsBlackLists["windows"] elif isLinuxPlatform(): PlatformBlackLists = PlatformsBlackLists["linux"] else: PlatformBlackLists = PlatformsBlackLists["mac"] # check version of sip try: import sipconfig sipVersion = sipconfig.Configuration().sip_version_str # always assume, that snapshots are good if "snapshot" not in sipVersion: # check for blacklisted versions for vers in BlackLists["sip"] + PlatformBlackLists["sip"]: if vers == sipVersion: print( 'Sorry, sip version {0} is not compatible with eric6.' .format(vers)) print('Please install another version.') return False except ImportError: pass # check version of PyQt from PyQt5.QtCore import PYQT_VERSION_STR pyqtVersion = PYQT_VERSION_STR # always assume, that snapshots are good if "snapshot" not in pyqtVersion: # check for blacklisted versions pyqtVariant = "PyQt{0}".format(pyqtVersion[0]) for vers in BlackLists[pyqtVariant] + PlatformBlackLists[pyqtVariant]: if vers == pyqtVersion: print('Sorry, PyQt version {0} is not compatible with eric6.' .format(vers)) print('Please install another version.') return False # check version of QScintilla from PyQt5.Qsci import QSCINTILLA_VERSION_STR scintillaVersion = QSCINTILLA_VERSION_STR # always assume, that snapshots are new enough if "snapshot" not in scintillaVersion: # check for blacklisted versions for vers in BlackLists["QScintilla2"] + \ PlatformBlackLists["QScintilla2"]: if vers == scintillaVersion: print( 'Sorry, QScintilla2 version {0} is not compatible' ' with eric6.'.format(vers)) print('Please install another version.') return False return True def getConfigDir(): """ Module function to get the name of the directory storing the config data. @return directory name of the config dir (string) """ if configDir is not None and os.path.exists(configDir): hp = configDir else: if isWindowsPlatform(): cdn = "_eric6" else: cdn = ".eric6" hp = QDir.homePath() dn = QDir(hp) dn.mkdir(cdn) hp += "/" + cdn return QDir.toNativeSeparators(hp) def setConfigDir(d): """ Module function to set the name of the directory storing the config data. @param d name of an existing directory (string) """ global configDir configDir = os.path.expanduser(d) def getPythonModulesDirectory(): """ Function to determine the path to Python's modules directory. @return path to the Python modules directory (string) """ import distutils.sysconfig return distutils.sysconfig.get_python_lib(True) def getPyQt5ModulesDirectory(): """ Function to determine the path to PyQt5's (or PyQt4's) modules directory. @return path to the PyQt5/PyQt4 modules directory (string) """ import distutils.sysconfig for pyqt in ["PyQt5", "PyQt4"]: pyqtPath = os.path.join(distutils.sysconfig.get_python_lib(True), pyqt) if os.path.exists(pyqtPath): return pyqtPath return "" def getQtBinariesPath(): """ Module function to get the path of the Qt binaries. @return path of the Qt binaries (string) """ path = "" if isWindowsPlatform(): # check for PyQt5 installer first (designer is test object) modDir = getPyQt5ModulesDirectory() if os.path.exists(os.path.join(modDir, "bin", "designer.exe")): path = os.path.join(modDir, "bin") elif os.path.exists(os.path.join(modDir, "designer.exe")): path = modDir if not path: path = QLibraryInfo.location(QLibraryInfo.BinariesPath) if not os.path.exists(path): path = "" return QDir.toNativeSeparators(path) ############################################################################### ## functions for searching a Python2/3 interpreter ############################################################################### def findPythonInterpreters(pyVersion): """ Module function for searching a Python interpreter. @param pyVersion major Python version @return list of interpreters found (list of strings) """ if pyVersion == 2: winPathList = ["C:\\Python25", "C:\\Python26", "C:\\Python27", "C:\\Python28"] posixVersionsList = ["2.5", "2.6", "2.7", "2.8"] else: winPathList = ["C:\\Python3{0}".format(x) for x in range(5)] posixVersionsList = ["3.{0}".format(x) for x in range(5)] posixPathList = ["/usr/bin", "/usr/local/bin"] interpreters = [] if isWindowsPlatform(): # search the interpreters on Windows platforms for path in winPathList: exeList = [ "python.exe", "python{0}.{1}.exe".format(path[-2], path[-1]), ] for exe in exeList: interpreter = os.path.join(path, exe) if os.path.isfile(interpreter): interpreters.append(interpreter) else: # search interpreters on Posix and Mac platforms for path in posixPathList: for version in posixVersionsList: interpreter = os.path.join(path, "python{0}".format(version)) if os.path.isfile(interpreter): interpreters.append(interpreter) return interpreters ############################################################################### ## functions for converting QSetting return types to valid types ############################################################################### def toBool(value): """ Module function to convert a value to bool. @param value value to be converted @return converted data """ if value in ["true", "1", "True"]: return True elif value in ["false", "0", "False"]: return False else: return bool(value) def toList(value): """ Module function to convert a value to a list. @param value value to be converted @return converted data """ if value is None: return [] elif not isinstance(value, list): return [value] else: return value def toByteArray(value): """ Module function to convert a value to a byte array. @param value value to be converted @return converted data """ if value is None: return QByteArray() else: return value def toDict(value): """ Module function to convert a value to a dictionary. @param value value to be converted @return converted data """ if value is None: return {} else: return value eric-6.0.8/eric/eric6_iconeditor.py0000644000175000017500000000362612451233374016261 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Eric6 Icon Editor. This is the main Python script that performs the necessary initialization of the icon editor and starts the Qt event loop. This is a standalone version of the integrated icon editor. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from IconEditor.IconEditorWindow import IconEditorWindow try: fileName = argv[1] except IndexError: fileName = "" editor = IconEditorWindow(fileName, None) return editor def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ("", "name of file to edit") ] appinfo = AppInfo.makeAppInfo(sys.argv, "Eric6 Icon Editor", "", "Little tool to edit icon files.", options) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/MultiProject/0000755000175000017500000000000012557365404015101 5ustar piotrpiotreric-6.0.8/eric/MultiProject/MultiProject.py0000644000175000017500000007640012451233374020074 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the multi project management functionality. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QFileInfo, QFile, \ QIODevice, QObject from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QMenu, QApplication, QDialog, QToolBar from Globals import recentNameMultiProject from E5Gui.E5Action import E5Action, createActionGroup from E5Gui import E5FileDialog, E5MessageBox import UI.PixmapCache import Preferences import Utilities class MultiProject(QObject): """ Class implementing the project management functionality. @signal dirty(bool) emitted when the dirty state changes @signal newMultiProject() emitted after a new multi project was generated @signal multiProjectOpened() emitted after a multi project file was read @signal multiProjectClosed() emitted after a multi project was closed @signal multiProjectPropertiesChanged() emitted after the multi project properties were changed @signal showMenu(string, QMenu) emitted when a menu is about to be shown. The name of the menu and a reference to the menu are given. @signal projectDataChanged(project data dict) emitted after a project entry has been changed @signal projectAdded(project data dict) emitted after a project entry has been added @signal projectRemoved(project data dict) emitted after a project entry has been removed @signal projectOpened(filename) emitted after the project has been opened """ dirty = pyqtSignal(bool) newMultiProject = pyqtSignal() multiProjectOpened = pyqtSignal() multiProjectClosed = pyqtSignal() multiProjectPropertiesChanged = pyqtSignal() showMenu = pyqtSignal(str, QMenu) projectDataChanged = pyqtSignal(dict) projectAdded = pyqtSignal(dict) projectRemoved = pyqtSignal(dict) projectOpened = pyqtSignal(str) def __init__(self, project, parent=None, filename=None): """ Constructor @param project reference to the project object (Project.Project) @param parent parent widget (usually the ui object) (QWidget) @param filename optional filename of a multi project file to open (string) """ super(MultiProject, self).__init__(parent) self.ui = parent self.projectObject = project self.__initData() self.recent = [] self.__loadRecent() if filename is not None: self.openMultiProject(filename) def __initData(self): """ Private method to initialize the multi project data part. """ self.loaded = False # flag for the loaded status self.__dirty = False # dirty flag self.pfile = "" # name of the multi project file self.ppath = "" # name of the multi project directory self.description = "" # description of the multi project self.name = "" self.opened = False self.projects = [] # list of project info; each info entry is a dictionary # 'name' : name of the project # 'file' : project file name # 'master' : flag indicating the master # project # 'description' : description of the project # 'category' : name of the group # 'uid' : unique identifier self.categories = [] def __loadRecent(self): """ Private method to load the recently opened multi project filenames. """ self.recent = [] Preferences.Prefs.rsettings.sync() rp = Preferences.Prefs.rsettings.value(recentNameMultiProject) if rp is not None: for f in rp: if QFileInfo(f).exists(): self.recent.append(f) def __saveRecent(self): """ Private method to save the list of recently opened filenames. """ Preferences.Prefs.rsettings.setValue( recentNameMultiProject, self.recent) Preferences.Prefs.rsettings.sync() def getMostRecent(self): """ Public method to get the most recently opened multiproject. @return path of the most recently opened multiproject (string) """ if len(self.recent): return self.recent[0] else: return None def setDirty(self, b): """ Public method to set the dirty state. It emits the signal dirty(int). @param b dirty state (boolean) """ self.__dirty = b self.saveAct.setEnabled(b) self.dirty.emit(bool(b)) def isDirty(self): """ Public method to return the dirty state. @return dirty state (boolean) """ return self.__dirty def isOpen(self): """ Public method to return the opened state. @return open state (boolean) """ return self.opened def getMultiProjectPath(self): """ Public method to get the multi project path. @return multi project path (string) """ return self.ppath def getMultiProjectFile(self): """ Public method to get the path of the multi project file. @return path of the multi project file (string) """ return self.pfile def __checkFilesExist(self): """ Private method to check, if the files in a list exist. The project files are checked for existance in the filesystem. Non existant projects are removed from the list and the dirty state of the multi project is changed accordingly. """ removelist = [] for project in self.projects: if not os.path.exists(project['file']): removelist.append(project) if removelist: for project in removelist: self.projects.remove(project) self.setDirty(True) def __extractCategories(self): """ Private slot to extract the categories used in the project definitions. """ for project in self.projects: if project['category'] and \ project['category'] not in self.categories: self.categories.append(project['category']) def getCategories(self): """ Public method to get the list of defined categories. @return list of categories (list of string) """ return [c for c in self.categories if c] def __readMultiProject(self, fn): """ Private method to read in a multi project (.e4m, .e5m) file. @param fn filename of the multi project file to be read (string) @return flag indicating success """ f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.MultiProjectReader import MultiProjectReader reader = MultiProjectReader(f, self) reader.readXML() f.close() if reader.hasError(): return False else: QApplication.restoreOverrideCursor() E5MessageBox.critical( self.ui, self.tr("Read multiproject file"), self.tr( "

The multiproject file {0} could not be" " read.

").format(fn)) return False self.pfile = os.path.abspath(fn) self.ppath = os.path.abspath(os.path.dirname(fn)) self.__extractCategories() # insert filename into list of recently opened multi projects self.__syncRecent() self.name = os.path.splitext(os.path.basename(fn))[0] # check, if the files of the multi project still exist self.__checkFilesExist() return True def __writeMultiProject(self, fn=None): """ Private method to save the multi project infos to a multi project file. @param fn optional filename of the multi project file to be written. If fn is None, the filename stored in the multi project object is used. This is the 'save' action. If fn is given, this filename is used instead of the one in the multi project object. This is the 'save as' action. @return flag indicating success """ if fn is None: fn = self.pfile f = QFile(fn) if f.open(QIODevice.WriteOnly): from E5XML.MultiProjectWriter import MultiProjectWriter MultiProjectWriter( f, self, os.path.splitext(os.path.basename(fn))[0])\ .writeXML() res = True else: E5MessageBox.critical( self.ui, self.tr("Save multiproject file"), self.tr( "

The multiproject file {0} could not be " "written.

").format(fn)) res = False if res: self.pfile = os.path.abspath(fn) self.ppath = os.path.abspath(os.path.dirname(fn)) self.name = os.path.splitext(os.path.basename(fn))[0] self.setDirty(False) # insert filename into list of recently opened projects self.__syncRecent() return res @pyqtSlot() def addProject(self, startdir=None): """ Public slot used to add files to the project. @param startdir start directory for the selection dialog (string) """ from .AddProjectDialog import AddProjectDialog if not startdir: startdir = self.ppath if not startdir: startdir = Preferences.getMultiProject("Workspace") dlg = AddProjectDialog(self.ui, startdir=startdir, categories=self.categories) if dlg.exec_() == QDialog.Accepted: name, filename, isMaster, description, category, uid = \ dlg.getData() # step 1: check, if project was already added for project in self.projects: if project['file'] == filename: return # step 2: check, if master should be changed if isMaster: for project in self.projects: if project['master']: project['master'] = False self.projectDataChanged.emit(project) self.setDirty(True) break # step 3: add the project entry project = { 'name': name, 'file': filename, 'master': isMaster, 'description': description, 'category': category, 'uid': uid, } self.projects.append(project) if category not in self.categories: self.categories.append(category) self.projectAdded.emit(project) self.setDirty(True) def changeProjectProperties(self, pro): """ Public method to change the data of a project entry. @param pro dictionary with the project data (string) """ # step 1: check, if master should be changed if pro['master']: for project in self.projects: if project['master']: if project['uid'] != pro['uid']: project['master'] = False self.projectDataChanged.emit(project) self.setDirty(True) break # step 2: change the entry for project in self.projects: if project['uid'] == pro['uid']: # project UID is not changeable via interface project['file'] = pro['file'] project['name'] = pro['name'] project['master'] = pro['master'] project['description'] = pro['description'] project['category'] = pro['category'] if project['category'] not in self.categories: self.categories.append(project['category']) self.projectDataChanged.emit(project) self.setDirty(True) def getProjects(self): """ Public method to get all project entries. @return list of all project entries (list of dictionaries) """ return self.projects def getProject(self, fn): """ Public method to get a reference to a project entry. @param fn filename of the project (string) @return dictionary containing the project data """ for project in self.projects: if project['file'] == fn: return project return None def removeProject(self, fn): """ Public slot to remove a project from the multi project. @param fn filename of the project to be removed from the multi project (string) """ for project in self.projects: if project['file'] == fn: self.projects.remove(project) self.projectRemoved.emit(project) self.setDirty(True) break def __newMultiProject(self): """ Private slot to build a new multi project. This method displays the new multi project dialog and initializes the multi project object with the data entered. """ if not self.checkDirty(): return from .PropertiesDialog import PropertiesDialog dlg = PropertiesDialog(self, True) if dlg.exec_() == QDialog.Accepted: self.closeMultiProject() dlg.storeData() self.opened = True self.setDirty(True) self.closeAct.setEnabled(True) self.saveasAct.setEnabled(True) self.addProjectAct.setEnabled(True) self.propsAct.setEnabled(True) self.newMultiProject.emit() def __showProperties(self): """ Private slot to display the properties dialog. """ from .PropertiesDialog import PropertiesDialog dlg = PropertiesDialog(self, False) if dlg.exec_() == QDialog.Accepted: dlg.storeData() self.setDirty(True) self.multiProjectPropertiesChanged.emit() @pyqtSlot() @pyqtSlot(str) def openMultiProject(self, fn=None, openMaster=True): """ Public slot to open a multi project. @param fn optional filename of the multi project file to be read (string) @param openMaster flag indicating, that the master project should be opened depending on the configuration (boolean) """ if not self.checkDirty(): return if fn is None: fn = E5FileDialog.getOpenFileName( self.parent(), self.tr("Open multiproject"), Preferences.getMultiProject("Workspace") or Utilities.getHomeDir(), self.tr("Multiproject Files (*.e5m *.e4m)")) if fn == "": fn = None QApplication.processEvents() if fn is not None: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.closeMultiProject() if self.__readMultiProject(fn): self.opened = True QApplication.restoreOverrideCursor() QApplication.processEvents() self.closeAct.setEnabled(True) self.saveasAct.setEnabled(True) self.addProjectAct.setEnabled(True) self.propsAct.setEnabled(True) self.multiProjectOpened.emit() if openMaster and Preferences.getMultiProject( "OpenMasterAutomatically"): self.__openMasterProject(False) else: QApplication.restoreOverrideCursor() def saveMultiProject(self): """ Public slot to save the current multi project. @return flag indicating success (boolean) """ if self.isDirty(): if len(self.pfile) > 0: if self.pfile.endswith(".e4m"): self.pfile = self.pfile.replace(".e4m", ".e5m") self.__syncRecent() ok = self.__writeMultiProject() else: ok = self.saveMultiProjectAs() else: ok = True return ok def saveMultiProjectAs(self): """ Public slot to save the current multi project to a different file. @return flag indicating success (boolean) """ defaultFilter = self.tr("Multiproject Files (*.e5m)") if self.ppath: defaultPath = self.ppath else: defaultPath = Preferences.getMultiProject("Workspace") or \ Utilities.getHomeDir() fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self.parent(), self.tr("Save multiproject as"), defaultPath, self.tr("Multiproject Files (*.e5m)"), defaultFilter, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fn: ext = QFileInfo(fn).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fn += ex if QFileInfo(fn).exists(): res = E5MessageBox.yesNo( self.parent(), self.tr("Save File"), self.tr("

The file {0} already exists." " Overwrite it?

").format(fn), icon=E5MessageBox.Warning) if not res: return False self.name = QFileInfo(fn).baseName() self.__writeMultiProject(fn) self.multiProjectClosed.emit() self.multiProjectOpened.emit() return True else: return False def checkDirty(self): """ Public method to check the dirty status and open a message window. @return flag indicating whether this operation was successful (boolean) """ if self.isDirty(): res = E5MessageBox.okToClearData( self.parent(), self.tr("Close Multiproject"), self.tr("The current multiproject has unsaved changes."), self.saveMultiProject) if res: self.setDirty(False) return res return True def closeMultiProject(self): """ Public slot to close the current multi project. @return flag indicating success (boolean) """ # save the list of recently opened projects self.__saveRecent() if not self.isOpen(): return True if not self.checkDirty(): return False # now close the current project, if it belongs to the multi project pfile = self.projectObject.getProjectFile() if pfile: for project in self.projects: if project['file'] == pfile: if not self.projectObject.closeProject(): return False break self.__initData() self.closeAct.setEnabled(False) self.saveasAct.setEnabled(False) self.saveAct.setEnabled(False) self.addProjectAct.setEnabled(False) self.propsAct.setEnabled(False) self.multiProjectClosed.emit() return True def initActions(self): """ Public slot to initialize the multi project related actions. """ self.actions = [] self.actGrp1 = createActionGroup(self) act = E5Action( self.tr('New multiproject'), UI.PixmapCache.getIcon("multiProjectNew.png"), self.tr('&New...'), 0, 0, self.actGrp1, 'multi_project_new') act.setStatusTip(self.tr('Generate a new multiproject')) act.setWhatsThis(self.tr( """New...""" """

This opens a dialog for entering the info for a""" """ new multiproject.

""" )) act.triggered.connect(self.__newMultiProject) self.actions.append(act) act = E5Action( self.tr('Open multiproject'), UI.PixmapCache.getIcon("multiProjectOpen.png"), self.tr('&Open...'), 0, 0, self.actGrp1, 'multi_project_open') act.setStatusTip(self.tr('Open an existing multiproject')) act.setWhatsThis(self.tr( """Open...""" """

This opens an existing multiproject.

""" )) act.triggered.connect(self.openMultiProject) self.actions.append(act) self.closeAct = E5Action( self.tr('Close multiproject'), UI.PixmapCache.getIcon("multiProjectClose.png"), self.tr('&Close'), 0, 0, self, 'multi_project_close') self.closeAct.setStatusTip(self.tr( 'Close the current multiproject')) self.closeAct.setWhatsThis(self.tr( """Close""" """

This closes the current multiproject.

""" )) self.closeAct.triggered.connect(self.closeMultiProject) self.actions.append(self.closeAct) self.saveAct = E5Action( self.tr('Save multiproject'), UI.PixmapCache.getIcon("multiProjectSave.png"), self.tr('&Save'), 0, 0, self, 'multi_project_save') self.saveAct.setStatusTip(self.tr('Save the current multiproject')) self.saveAct.setWhatsThis(self.tr( """Save""" """

This saves the current multiproject.

""" )) self.saveAct.triggered.connect(self.saveMultiProject) self.actions.append(self.saveAct) self.saveasAct = E5Action( self.tr('Save multiproject as'), UI.PixmapCache.getIcon("multiProjectSaveAs.png"), self.tr('Save &as...'), 0, 0, self, 'multi_project_save_as') self.saveasAct.setStatusTip(self.tr( 'Save the current multiproject to a new file')) self.saveasAct.setWhatsThis(self.tr( """Save as""" """

This saves the current multiproject to a new file.

""" )) self.saveasAct.triggered.connect(self.saveMultiProjectAs) self.actions.append(self.saveasAct) self.addProjectAct = E5Action( self.tr('Add project to multiproject'), UI.PixmapCache.getIcon("fileProject.png"), self.tr('Add &project...'), 0, 0, self, 'multi_project_add_project') self.addProjectAct.setStatusTip(self.tr( 'Add a project to the current multiproject')) self.addProjectAct.setWhatsThis(self.tr( """Add project...""" """

This opens a dialog for adding a project""" """ to the current multiproject.

""" )) self.addProjectAct.triggered.connect(self.addProject) self.actions.append(self.addProjectAct) self.propsAct = E5Action( self.tr('Multiproject properties'), UI.PixmapCache.getIcon("multiProjectProps.png"), self.tr('&Properties...'), 0, 0, self, 'multi_project_properties') self.propsAct.setStatusTip(self.tr( 'Show the multiproject properties')) self.propsAct.setWhatsThis(self.tr( """Properties...""" """

This shows a dialog to edit the multiproject""" """ properties.

""" )) self.propsAct.triggered.connect(self.__showProperties) self.actions.append(self.propsAct) self.closeAct.setEnabled(False) self.saveAct.setEnabled(False) self.saveasAct.setEnabled(False) self.addProjectAct.setEnabled(False) self.propsAct.setEnabled(False) def initMenu(self): """ Public slot to initialize the multi project menu. @return the menu generated (QMenu) """ menu = QMenu(self.tr('&Multiproject'), self.parent()) self.recentMenu = QMenu(self.tr('Open &Recent Multiprojects'), menu) self.__menus = { "Main": menu, "Recent": self.recentMenu, } # connect the aboutToShow signals self.recentMenu.aboutToShow.connect(self.__showContextMenuRecent) self.recentMenu.triggered.connect(self.__openRecent) menu.aboutToShow.connect(self.__showMenu) # build the main menu menu.setTearOffEnabled(True) menu.addActions(self.actGrp1.actions()) self.menuRecentAct = menu.addMenu(self.recentMenu) menu.addSeparator() menu.addAction(self.closeAct) menu.addSeparator() menu.addAction(self.saveAct) menu.addAction(self.saveasAct) menu.addSeparator() menu.addAction(self.addProjectAct) menu.addSeparator() menu.addAction(self.propsAct) self.menu = menu return menu def initToolbar(self, toolbarManager): """ Public slot to initialize the multi project toolbar. @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) @return the toolbar generated (QToolBar) """ tb = QToolBar(self.tr("Multiproject"), self.ui) tb.setIconSize(UI.Config.ToolBarIconSize) tb.setObjectName("MultiProjectToolbar") tb.setToolTip(self.tr('Multiproject')) tb.addActions(self.actGrp1.actions()) tb.addAction(self.closeAct) tb.addSeparator() tb.addAction(self.saveAct) tb.addAction(self.saveasAct) toolbarManager.addToolBar(tb, tb.windowTitle()) toolbarManager.addAction(self.addProjectAct, tb.windowTitle()) toolbarManager.addAction(self.propsAct, tb.windowTitle()) return tb def __showMenu(self): """ Private method to set up the multi project menu. """ self.menuRecentAct.setEnabled(len(self.recent) > 0) self.showMenu.emit("Main", self.__menus["Main"]) def __syncRecent(self): """ Private method to synchronize the list of recently opened multi projects with the central store. """ for recent in self.recent[:]: if Utilities.samepath(self.pfile, recent): self.recent.remove(recent) self.recent.insert(0, self.pfile) maxRecent = Preferences.getProject("RecentNumber") if len(self.recent) > maxRecent: self.recent = self.recent[:maxRecent] self.__saveRecent() def __showContextMenuRecent(self): """ Private method to set up the recent multi projects menu. """ self.__loadRecent() self.recentMenu.clear() idx = 1 for rp in self.recent: if idx < 10: formatStr = '&{0:d}. {1}' else: formatStr = '{0:d}. {1}' act = self.recentMenu.addAction( formatStr.format( idx, Utilities.compactPath(rp, self.ui.maxMenuFilePathLen))) act.setData(rp) act.setEnabled(QFileInfo(rp).exists()) idx += 1 self.recentMenu.addSeparator() self.recentMenu.addAction(self.tr('&Clear'), self.__clearRecent) def __openRecent(self, act): """ Private method to open a multi project from the list of rencently opened multi projects. @param act reference to the action that triggered (QAction) """ file = act.data() if file: self.openMultiProject(file) def __clearRecent(self): """ Private method to clear the recent multi projects menu. """ self.recent = [] def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ return self.actions[:] def addE5Actions(self, actions): """ Public method to add actions to the list of actions. @param actions list of actions (list of E5Action) """ self.actions.extend(actions) def removeE5Actions(self, actions): """ Public method to remove actions from the list of actions. @param actions list of actions (list of E5Action) """ for act in actions: try: self.actions.remove(act) except ValueError: pass def getMenu(self, menuName): """ Public method to get a reference to the main menu or a submenu. @param menuName name of the menu (string) @return reference to the requested menu (QMenu) or None """ try: return self.__menus[menuName] except KeyError: return None def openProject(self, filename): """ Public slot to open a project. @param filename filename of the project file (string) """ self.projectObject.openProject(filename) self.projectOpened.emit(filename) def __openMasterProject(self, reopen=True): """ Private slot to open the master project. @param reopen flag indicating, that the master project should be reopened, if it has been opened already (boolean) """ for project in self.projects: if project['master']: if reopen or \ not self.projectObject.isOpen() or \ self.projectObject.getProjectFile() != project['file']: self.openProject(project['file']) return def getMasterProjectFile(self): """ Public method to get the filename of the master project. @return name of the master project file (string) """ for project in self.projects: if project['master']: return project['file'] return None def getDependantProjectFiles(self): """ Public method to get the filenames of the dependent projects. @return names of the dependent project files (list of strings) """ files = [] for project in self.projects: if not project['master']: files.append(project['file']) return files eric-6.0.8/eric/MultiProject/AddProjectDialog.ui0000644000175000017500000001103712264256373020600 0ustar piotrpiotr AddProjectDialog 0 0 569 378 Add Project true &Name: nameEdit Enter the name of the project Project&file: filenameEdit Enter the name of the project file Select the project file via a file selection dialog &Description: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop descriptionEdit Enter a short description for the project true false &Category: categoryComboBox Select a project category true Select to make this project the main project Is &main project Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok nameEdit filenameEdit fileButton descriptionEdit categoryComboBox masterCheckBox buttonBox buttonBox accepted() AddProjectDialog accept() 248 254 157 274 buttonBox rejected() AddProjectDialog reject() 316 260 286 274 eric-6.0.8/eric/MultiProject/__init__.py0000644000175000017500000000102312471662770017207 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Package implementing the multi project management module of eric6. The multi project management module consists of the main part, which is used for reading and writing of eric6 multi project files (*.e5m) and for performing all operations on the multi project. It is accompanied by various UI related modules implementing different dialogs and a browser for the display of projects belonging to the current multi project. """ eric-6.0.8/eric/MultiProject/AddProjectDialog.py0000644000175000017500000001065612451233374020613 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the add project dialog. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5FileDialog from .Ui_AddProjectDialog import Ui_AddProjectDialog import Utilities import UI.PixmapCache class AddProjectDialog(QDialog, Ui_AddProjectDialog): """ Class implementing the add project dialog. """ def __init__(self, parent=None, startdir=None, project=None, categories=None): """ Constructor @param parent parent widget of this dialog (QWidget) @param startdir start directory for the selection dialog (string) @param project dictionary containing project data @param categories list of already used categories (list of string) """ super(AddProjectDialog, self).__init__(parent) self.setupUi(self) self.fileButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.fileCompleter = E5FileCompleter(self.filenameEdit) if categories: self.categoryComboBox.addItem("") self.categoryComboBox.addItems(sorted(categories)) self.startdir = startdir self.uid = "" self.__okButton = self.buttonBox.button(QDialogButtonBox.Ok) self.__okButton.setEnabled(False) if project is not None: self.setWindowTitle(self.tr("Project Properties")) self.nameEdit.setText(project['name']) self.filenameEdit.setText(project['file']) self.descriptionEdit.setPlainText(project['description']) self.masterCheckBox.setChecked(project['master']) index = self.categoryComboBox.findText(project['category']) if index == -1: index = 0 self.categoryComboBox.setCurrentIndex(index) self.uid = project["uid"] @pyqtSlot() def on_fileButton_clicked(self): """ Private slot to display a file selection dialog. """ startdir = self.filenameEdit.text() if startdir or self.startdir is not None: if not startdir: startdir = self.startdir projectFile = E5FileDialog.getOpenFileName( self, self.tr("Add Project"), startdir, self.tr("Project Files (*.e4p)")) if projectFile: self.filenameEdit.setText( Utilities.toNativeSeparators(projectFile)) def getData(self): """ Public slot to retrieve the dialogs data. @return tuple of five values (string, string, boolean, string, string) giving the project name, the name of the project file, a flag telling whether the project shall be the main project, a short description for the project and the project category """ if not self.uid: # new project entry from PyQt5.QtCore import QUuid self.uid = QUuid.createUuid().toString() filename = Utilities.toNativeSeparators(self.filenameEdit.text()) if not os.path.isabs(filename): filename = Utilities.toNativeSeparators( os.path.join(self.startdir, filename)) return (self.nameEdit.text(), filename, self.masterCheckBox.isChecked(), self.descriptionEdit.toPlainText(), self.categoryComboBox.currentText(), self.uid) @pyqtSlot(str) def on_nameEdit_textChanged(self, txt): """ Private slot called when the project name has changed. @param txt text of the edit (string) """ self.__updateUi() @pyqtSlot(str) def on_filenameEdit_textChanged(self, txt): """ Private slot called when the project filename has changed. @param txt text of the edit (string) """ self.__updateUi() def __updateUi(self): """ Private method to update the dialog. """ self.__okButton.setEnabled(self.nameEdit.text() != "" and self.filenameEdit.text() != "") eric-6.0.8/eric/MultiProject/MultiProjectBrowser.py0000644000175000017500000002571212451233374021440 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the multi project browser. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QDialog, QMenu from E5Gui.E5Application import e5App import UI.PixmapCache class MultiProjectBrowser(QTreeWidget): """ Class implementing the multi project browser. """ def __init__(self, multiProject, parent=None): """ Constructor @param multiProject reference to the multi project object @param parent parent widget (QWidget) """ super(MultiProjectBrowser, self).__init__(parent) self.multiProject = multiProject self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.setAlternatingRowColors(True) self.setHeaderHidden(True) self.setItemsExpandable(False) self.setRootIsDecorated(False) self.setSortingEnabled(True) self.__openingProject = False self.multiProject.newMultiProject.connect( self.__newMultiProject) self.multiProject.multiProjectOpened.connect( self.__multiProjectOpened) self.multiProject.multiProjectClosed.connect( self.__multiProjectClosed) self.multiProject.projectDataChanged.connect( self.__projectDataChanged) self.multiProject.projectAdded.connect( self.__projectAdded) self.multiProject.projectRemoved.connect( self.__projectRemoved) self.multiProject.projectOpened.connect( self.__projectOpened) self.__createPopupMenu() self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__contextMenuRequested) self.itemActivated.connect(self.__openItem) self.setEnabled(False) ########################################################################### ## Slot handling methods below ########################################################################### def __newMultiProject(self): """ Private slot to handle the creation of a new multi project. """ self.clear() self.setEnabled(True) def __multiProjectOpened(self): """ Private slot to handle the opening of a multi project. """ for project in self.multiProject.getProjects(): self.__addProject(project) self.sortItems(0, Qt.AscendingOrder) self.setEnabled(True) def __multiProjectClosed(self): """ Private slot to handle the closing of a multi project. """ self.clear() self.setEnabled(False) def __projectAdded(self, project): """ Private slot to handle the addition of a project to the multi project. @param project reference to the project data dictionary """ self.__addProject(project) self.sortItems(0, Qt.AscendingOrder) def __projectRemoved(self, project): """ Private slot to handle the removal of a project from the multi project. @param project reference to the project data dictionary """ itm = self.__findProjectItem(project) if itm: parent = itm.parent() parent.removeChild(itm) del itm if parent.childCount() == 0: top = self.takeTopLevelItem(self.indexOfTopLevelItem(parent)) del top def __projectDataChanged(self, project): """ Private slot to handle the change of a project of the multi project. @param project reference to the project data dictionary """ itm = self.__findProjectItem(project) if itm: parent = itm.parent() if parent.text(0) != project["category"]: self.__projectRemoved(project) self.__addProject(project) else: self.__setItemData(itm, project) self.sortItems(0, Qt.AscendingOrder) def __projectOpened(self, projectfile): """ Private slot to handle the opening of a project. @param projectfile file name of the opened project file (string) """ project = { 'name': "", 'file': projectfile, 'master': False, 'description': "", 'category': "", } itm = self.__findProjectItem(project) if itm: itm.setSelected(True) def __contextMenuRequested(self, coord): """ Private slot to show the context menu. @param coord the position of the mouse pointer (QPoint) """ itm = self.itemAt(coord) if itm is None or itm.parent() is None: self.__backMenu.popup(self.mapToGlobal(coord)) else: self.__menu.popup(self.mapToGlobal(coord)) def __openItem(self, itm=None): """ Private slot to open a project. @param itm reference to the project item to be opened (QTreeWidgetItem) """ if itm is None: itm = self.currentItem() if itm is None or itm.parent() is None: return if not self.__openingProject: filename = itm.data(0, Qt.UserRole) if filename: self.__openingProject = True self.multiProject.openProject(filename) self.__openingProject = False ########################################################################### ## Private methods below ########################################################################### def __findCategoryItem(self, category): """ Private method to find the item for a category. @param category category to search for (string) @return reference to the category item or None, if there is no such item (QTreeWidgetItem or None) """ if category == "": category = self.tr("Not categorized") for index in range(self.topLevelItemCount()): itm = self.topLevelItem(index) if itm.text(0) == category: return itm return None def __addProject(self, project): """ Private method to add a project to the list. @param project reference to the project data dictionary """ parent = self.__findCategoryItem(project['category']) if parent is None: if project['category']: parent = QTreeWidgetItem(self, [project['category']]) else: parent = QTreeWidgetItem(self, [self.tr("Not categorized")]) parent.setExpanded(True) itm = QTreeWidgetItem(parent) self.__setItemData(itm, project) def __setItemData(self, itm, project): """ Private method to set the data of a project item. @param itm reference to the item to be set (QTreeWidgetItem) @param project reference to the project data dictionary """ itm.setText(0, project['name']) if project['master']: itm.setIcon(0, UI.PixmapCache.getIcon("masterProject.png")) else: itm.setIcon(0, UI.PixmapCache.getIcon("empty.png")) itm.setToolTip(0, project['file']) itm.setData(0, Qt.UserRole, project['file']) def __findProjectItem(self, project): """ Private method to search a specific project item. @param project reference to the project data dictionary @return reference to the item (QTreeWidgetItem) or None """ for topIndex in range(self.topLevelItemCount()): topItm = self.topLevelItem(topIndex) for childIndex in range(topItm.childCount()): itm = topItm.child(childIndex) data = itm.data(0, Qt.UserRole) if data == project['file']: return itm return None def __removeProject(self): """ Private method to handle the Remove context menu entry. """ itm = self.currentItem() if itm is not None and itm.parent() is not None: filename = itm.data(0, Qt.UserRole) if filename: self.multiProject.removeProject(filename) def __showProjectProperties(self): """ Private method to show the data of a project entry. """ itm = self.currentItem() if itm is not None and itm.parent() is not None: filename = itm.data(0, Qt.UserRole) if filename: project = self.multiProject.getProject(filename) if project is not None: from .AddProjectDialog import AddProjectDialog dlg = AddProjectDialog( self, project=project, categories=self.multiProject.getCategories()) if dlg.exec_() == QDialog.Accepted: (name, filename, isMaster, description, category, uid) = dlg.getData() project = { 'name': name, 'file': filename, 'master': isMaster, 'description': description, 'category': category, 'uid': uid, } self.multiProject.changeProjectProperties(project) def __addNewProject(self): """ Private method to add a new project entry. """ self.multiProject.addProject() def __createPopupMenu(self): """ Private method to create the popup menu. """ self.__menu = QMenu(self) self.__menu.addAction(self.tr("Open"), self.__openItem) self.__menu.addAction(self.tr("Remove"), self.__removeProject) self.__menu.addAction(self.tr("Properties"), self.__showProjectProperties) self.__menu.addSeparator() self.__menu.addAction(self.tr("Add Project..."), self.__addNewProject) self.__menu.addSeparator() self.__menu.addAction(self.tr("Configure..."), self.__configure) self.__backMenu = QMenu(self) self.__backMenu.addAction(self.tr("Add Project..."), self.__addNewProject) self.__backMenu.addSeparator() self.__backMenu.addAction(self.tr("Configure..."), self.__configure) def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences("multiProjectPage") eric-6.0.8/eric/MultiProject/PropertiesDialog.ui0000644000175000017500000000503412060166053020702 0ustar piotrpiotr PropertiesDialog 0 0 530 227 Multiproject Properties true &Description: Qt::AlignTop descriptionEdit Enter description <b>Description</b> <p>Enter a short description for the multiproject.</p> true false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok descriptionEdit buttonBox buttonBox accepted() PropertiesDialog accept() 248 254 157 274 buttonBox rejected() PropertiesDialog reject() 316 260 286 274 eric-6.0.8/eric/MultiProject/PropertiesDialog.py0000644000175000017500000000226312451233374020723 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the multi project properties dialog. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_PropertiesDialog import Ui_PropertiesDialog class PropertiesDialog(QDialog, Ui_PropertiesDialog): """ Class implementing the multi project properties dialog. """ def __init__(self, multiProject, new=True, parent=None): """ Constructor @param multiProject reference to the multi project object @param new flag indicating the generation of a new multi project @param parent parent widget of this dialog (QWidget) """ super(PropertiesDialog, self).__init__(parent) self.setupUi(self) self.multiProject = multiProject self.newMultiProject = new if not new: self.descriptionEdit.setPlainText(self.multiProject.description) def storeData(self): """ Public method to store the entered/modified data. """ self.multiProject.description = self.descriptionEdit.toPlainText() eric-6.0.8/eric/eric6_uipreviewer.pyw0000644000175000017500000000030512451233400016634 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_uipreviewer import main main() eric-6.0.8/eric/eric6_unittest.pyw0000644000175000017500000000030212451233400016142 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_unittest import main main() eric-6.0.8/eric/PyUnit/0000755000175000017500000000000012557365404013710 5ustar piotrpiotreric-6.0.8/eric/PyUnit/__init__.py0000644000175000017500000000065512451233374016020 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Package implementing an interface to the pyunit unittest package. The package consist of a single dialog, which may be called as a standalone version using the eric6_unittest script or from within the eric6 IDE. If it is called from within eric6, it has the additional function to open a source file that failed a test. """ eric-6.0.8/eric/PyUnit/UnittestStacktraceDialog.ui0000644000175000017500000000314012060166053021175 0ustar piotrpiotr UnittestStacktraceDialog 0 0 600 250 true false Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() UnittestStacktraceDialog accept() 33 235 33 249 buttonBox rejected() UnittestStacktraceDialog reject() 94 226 95 249 eric-6.0.8/eric/PyUnit/UnittestDialog.py0000644000175000017500000007070212451233374017220 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the UI to the pyunit package. """ from __future__ import unicode_literals import unittest import sys import time import re import os from PyQt5.QtCore import pyqtSignal, QEvent, Qt, pyqtSlot from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QWidget, QDialog, QApplication, QDialogButtonBox, \ QListWidgetItem from E5Gui.E5Application import e5App from E5Gui.E5Completers import E5FileCompleter from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5MainWindow import E5MainWindow from .Ui_UnittestDialog import Ui_UnittestDialog import UI.PixmapCache import Utilities import Preferences class UnittestDialog(QWidget, Ui_UnittestDialog): """ Class implementing the UI to the pyunit package. @signal unittestFile(str, int, int) emitted to show the source of a unittest file @signal unittestStopped() emitted after a unit test was run """ unittestFile = pyqtSignal(str, int, int) unittestStopped = pyqtSignal() def __init__(self, prog=None, dbs=None, ui=None, fromEric=False, parent=None, name=None): """ Constructor @param prog filename of the program to open @param dbs reference to the debug server object. It is an indication whether we were called from within the eric6 IDE @param ui reference to the UI object @param fromEric flag indicating an instantiation from within the eric IDE (boolean) @param parent parent widget of this dialog (QWidget) @param name name of this dialog (string) """ super(UnittestDialog, self).__init__(parent) if name: self.setObjectName(name) self.setupUi(self) self.fileDialogButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.startButton = self.buttonBox.addButton( self.tr("Start"), QDialogButtonBox.ActionRole) self.startButton.setToolTip(self.tr( "Start the selected testsuite")) self.startButton.setWhatsThis(self.tr( """Start Test""" """

This button starts the selected testsuite.

""")) self.startFailedButton = self.buttonBox.addButton( self.tr("Rerun Failed"), QDialogButtonBox.ActionRole) self.startFailedButton.setToolTip( self.tr("Reruns failed tests of the selected testsuite")) self.startFailedButton.setWhatsThis(self.tr( """Rerun Failed""" """

This button reruns all failed tests of the selected""" """ testsuite.

""")) self.stopButton = self.buttonBox.addButton( self.tr("Stop"), QDialogButtonBox.ActionRole) self.stopButton.setToolTip(self.tr("Stop the running unittest")) self.stopButton.setWhatsThis(self.tr( """Stop Test""" """

This button stops a running unittest.

""")) self.stopButton.setEnabled(False) self.startButton.setDefault(True) self.startFailedButton.setEnabled(False) self.dbs = dbs self.__fromEric = fromEric self.setWindowFlags( self.windowFlags() | Qt.WindowFlags( Qt.WindowContextHelpButtonHint)) self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.setWindowTitle(self.tr("Unittest")) if dbs: self.ui = ui else: self.localCheckBox.hide() self.__setProgressColor("green") self.progressLed.setDarkFactor(150) self.progressLed.off() self.testSuiteCompleter = E5FileCompleter(self.testsuiteComboBox) self.fileHistory = [] self.testNameHistory = [] self.running = False self.savedModulelist = None self.savedSysPath = sys.path if prog: self.insertProg(prog) self.rxPatterns = [ self.tr("^Failure: "), self.tr("^Error: "), ] self.__failedTests = [] # now connect the debug server signals if called from the eric6 IDE if self.dbs: self.dbs.utPrepared.connect(self.__UTPrepared) self.dbs.utFinished.connect(self.__setStoppedMode) self.dbs.utStartTest.connect(self.testStarted) self.dbs.utStopTest.connect(self.testFinished) self.dbs.utTestFailed.connect(self.testFailed) self.dbs.utTestErrored.connect(self.testErrored) self.dbs.utTestSkipped.connect(self.testSkipped) self.dbs.utTestFailedExpected.connect(self.testFailedExpected) self.dbs.utTestSucceededUnexpected.connect( self.testSucceededUnexpected) def keyPressEvent(self, evt): """ Protected slot to handle key press events. @param evt key press event to handle (QKeyEvent) """ if evt.key() == Qt.Key_Escape and self.__fromEric: self.close() def __setProgressColor(self, color): """ Private methode to set the color of the progress color label. @param color colour to be shown (string) """ self.progressLed.setColor(QColor(color)) def insertProg(self, prog): """ Public slot to insert the filename prog into the testsuiteComboBox object. @param prog filename to be inserted (string) """ # prepend the selected file to the testsuite combobox if prog is None: prog = "" if prog in self.fileHistory: self.fileHistory.remove(prog) self.fileHistory.insert(0, prog) self.testsuiteComboBox.clear() self.testsuiteComboBox.addItems(self.fileHistory) def insertTestName(self, testName): """ Public slot to insert a test name into the testComboBox object. @param testName name of the test to be inserted (string) """ # prepend the selected file to the testsuite combobox if testName is None: testName = "" if testName in self.testNameHistory: self.testNameHistory.remove(testName) self.testNameHistory.insert(0, testName) self.testComboBox.clear() self.testComboBox.addItems(self.testNameHistory) @pyqtSlot() def on_fileDialogButton_clicked(self): """ Private slot to open a file dialog. """ if self.dbs: py2Extensions = \ ' '.join(["*{0}".format(ext) for ext in self.dbs.getExtensions('Python2')]) py3Extensions = \ ' '.join(["*{0}".format(ext) for ext in self.dbs.getExtensions('Python3')]) filter = self.tr( "Python3 Files ({1});;Python2 Files ({0});;All Files (*)")\ .format(py2Extensions, py3Extensions) else: filter = self.tr("Python Files (*.py);;All Files (*)") prog = E5FileDialog.getOpenFileName( self, "", self.testsuiteComboBox.currentText(), filter) if not prog: return self.insertProg(Utilities.toNativeSeparators(prog)) @pyqtSlot(str) def on_testsuiteComboBox_editTextChanged(self, txt): """ Private slot to handle changes of the test file name. @param txt name of the test file (string) """ if self.dbs: exts = self.dbs.getExtensions("Python2") flags = Utilities.extractFlagsFromFile(txt) if txt.endswith(exts) or \ ("FileType" in flags and flags["FileType"] in ["Python", "Python2"]): self.coverageCheckBox.setChecked(False) self.coverageCheckBox.setEnabled(False) self.localCheckBox.setChecked(False) self.localCheckBox.setEnabled(False) return self.coverageCheckBox.setEnabled(True) self.localCheckBox.setEnabled(True) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.startButton: self.on_startButton_clicked() elif button == self.stopButton: self.on_stopButton_clicked() elif button == self.startFailedButton: self.on_startButton_clicked(failedOnly=True) @pyqtSlot() def on_startButton_clicked(self, failedOnly=False): """ Private slot to start the test. @keyparam failedOnly flag indicating to run only failed tests (boolean) """ if self.running: return prog = self.testsuiteComboBox.currentText() if not prog: E5MessageBox.critical( self, self.tr("Unittest"), self.tr("You must enter a test suite file.")) return # prepend the selected file to the testsuite combobox self.insertProg(prog) self.sbLabel.setText(self.tr("Preparing Testsuite")) QApplication.processEvents() testFunctionName = self.testComboBox.currentText() if testFunctionName: self.insertTestName(testFunctionName) else: testFunctionName = "suite" # build the module name from the filename without extension self.testName = os.path.splitext(os.path.basename(prog))[0] if self.dbs and not self.localCheckBox.isChecked(): # we are cooperating with the eric6 IDE project = e5App().getObject("Project") if project.isOpen() and project.isProjectSource(prog): mainScript = project.getMainScript(True) clientType = project.getProjectLanguage() else: mainScript = os.path.abspath(prog) flags = Utilities.extractFlagsFromFile(mainScript) if mainScript.endswith( tuple(Preferences.getPython("PythonExtensions"))) or \ ("FileType" in flags and flags["FileType"] in ["Python", "Python2"]): clientType = "Python2" else: clientType = "" if failedOnly and self.__failedTests: failed = [t.split(".", 1)[1] for t in self.__failedTests] else: failed = [] self.__failedTests = [] self.dbs.remoteUTPrepare( prog, self.testName, testFunctionName, failed, self.coverageCheckBox.isChecked(), mainScript, self.coverageEraseCheckBox.isChecked(), clientType=clientType) else: # we are running as an application or in local mode sys.path = [os.path.dirname(os.path.abspath(prog))] + \ self.savedSysPath # clean up list of imported modules to force a reimport upon # running the test if self.savedModulelist: for modname in list(sys.modules.keys()): if modname not in self.savedModulelist: # delete it del(sys.modules[modname]) self.savedModulelist = sys.modules.copy() # now try to generate the testsuite try: module = __import__(self.testName) try: if failedOnly and self.__failedTests: test = unittest.defaultTestLoader.loadTestsFromNames( [t.split(".", 1)[1] for t in self.__failedTests], module) else: test = unittest.defaultTestLoader.loadTestsFromName( testFunctionName, module) except AttributeError: test = unittest.defaultTestLoader.loadTestsFromModule( module) except: exc_type, exc_value, exc_tb = sys.exc_info() E5MessageBox.critical( self, self.tr("Unittest"), self.tr( "

Unable to run test {0}.
" "{1}
{2}

") .format(self.testName, str(exc_type), str(exc_value))) return # now set up the coverage stuff if self.coverageCheckBox.isChecked(): if self.dbs: # we are cooperating with the eric6 IDE project = e5App().getObject("Project") if project.isOpen() and project.isProjectSource(prog): mainScript = project.getMainScript(True) if not mainScript: mainScript = os.path.abspath(prog) else: mainScript = os.path.abspath(prog) else: mainScript = os.path.abspath(prog) from DebugClients.Python3.coverage import coverage cover = coverage( data_file="{0}.coverage".format( os.path.splitext(mainScript)[0])) cover.use_cache(True) if self.coverageEraseCheckBox.isChecked(): cover.erase() else: cover = None self.testResult = QtTestResult(self) self.totalTests = test.countTestCases() self.__failedTests = [] self.__setRunningMode() if cover: cover.start() test.run(self.testResult) if cover: cover.stop() cover.save() self.__setStoppedMode() sys.path = self.savedSysPath def __UTPrepared(self, nrTests, exc_type, exc_value): """ Private slot to handle the utPrepared signal. If the unittest suite was loaded successfully, we ask the client to run the test suite. @param nrTests number of tests contained in the test suite (integer) @param exc_type type of exception occured during preparation (string) @param exc_value value of exception occured during preparation (string) """ if nrTests == 0: E5MessageBox.critical( self, self.tr("Unittest"), self.tr( "

Unable to run test {0}.
{1}
{2}

") .format(self.testName, exc_type, exc_value)) return self.totalTests = nrTests self.__setRunningMode() self.dbs.remoteUTRun() @pyqtSlot() def on_stopButton_clicked(self): """ Private slot to stop the test. """ if self.dbs and not self.localCheckBox.isChecked(): self.dbs.remoteUTStop() elif self.testResult: self.testResult.stop() def on_errorsListWidget_currentTextChanged(self, text): """ Private slot to handle the highlighted signal. @param text current text (string) """ if text: for pattern in self.rxPatterns: text = re.sub(pattern, "", text) itm = self.testsListWidget.findItems( text, Qt.MatchFlags(Qt.MatchExactly))[0] self.testsListWidget.setCurrentItem(itm) self.testsListWidget.scrollToItem(itm) def __setRunningMode(self): """ Private method to set the GUI in running mode. """ self.running = True # reset counters and error infos self.runCount = 0 self.failCount = 0 self.errorCount = 0 self.skippedCount = 0 self.expectedFailureCount = 0 self.unexpectedSuccessCount = 0 self.remainingCount = self.totalTests # reset the GUI self.progressCounterRunCount.setText(str(self.runCount)) self.progressCounterRemCount.setText(str(self.remainingCount)) self.progressCounterFailureCount.setText(str(self.failCount)) self.progressCounterErrorCount.setText(str(self.errorCount)) self.progressCounterSkippedCount.setText(str(self.skippedCount)) self.progressCounterExpectedFailureCount.setText( str(self.expectedFailureCount)) self.progressCounterUnexpectedSuccessCount.setText( str(self.unexpectedSuccessCount)) self.errorsListWidget.clear() self.testsListWidget.clear() self.progressProgressBar.setRange(0, self.totalTests) self.__setProgressColor("green") self.progressProgressBar.reset() self.stopButton.setEnabled(True) self.startButton.setEnabled(False) self.stopButton.setDefault(True) self.sbLabel.setText(self.tr("Running")) self.progressLed.on() QApplication.processEvents() self.startTime = time.time() def __setStoppedMode(self): """ Private method to set the GUI in stopped mode. """ self.stopTime = time.time() self.timeTaken = float(self.stopTime - self.startTime) self.running = False self.startButton.setEnabled(True) self.startFailedButton.setEnabled(bool(self.__failedTests)) self.stopButton.setEnabled(False) if self.__failedTests: self.startFailedButton.setDefault(True) self.startButton.setDefault(False) else: self.startFailedButton.setDefault(False) self.startButton.setDefault(True) if self.runCount == 1: self.sbLabel.setText( self.tr("Ran {0} test in {1:.3f}s") .format(self.runCount, self.timeTaken)) else: self.sbLabel.setText( self.tr("Ran {0} tests in {1:.3f}s") .format(self.runCount, self.timeTaken)) self.progressLed.off() self.unittestStopped.emit() def testFailed(self, test, exc, id): """ Public method called if a test fails. @param test name of the test (string) @param exc string representation of the exception (string) @param id id of the test (string) """ self.failCount += 1 self.progressCounterFailureCount.setText(str(self.failCount)) itm = QListWidgetItem(self.tr("Failure: {0}").format(test)) itm.setData(Qt.UserRole, (test, exc)) self.errorsListWidget.insertItem(0, itm) self.__failedTests.append(id) def testErrored(self, test, exc, id): """ Public method called if a test errors. @param test name of the test (string) @param exc string representation of the exception (string) @param id id of the test (string) """ self.errorCount += 1 self.progressCounterErrorCount.setText(str(self.errorCount)) itm = QListWidgetItem(self.tr("Error: {0}").format(test)) itm.setData(Qt.UserRole, (test, exc)) self.errorsListWidget.insertItem(0, itm) self.__failedTests.append(id) def testSkipped(self, test, reason, id): """ Public method called if a test was skipped. @param test name of the test (string) @param reason reason for skipping the test (string) @param id id of the test (string) """ self.skippedCount += 1 self.progressCounterSkippedCount.setText(str(self.skippedCount)) itm = QListWidgetItem(self.tr(" Skipped: {0}").format(reason)) itm.setForeground(Qt.blue) self.testsListWidget.insertItem(1, itm) def testFailedExpected(self, test, exc, id): """ Public method called if a test fails expectedly. @param test name of the test (string) @param exc string representation of the exception (string) @param id id of the test (string) """ self.expectedFailureCount += 1 self.progressCounterExpectedFailureCount.setText( str(self.expectedFailureCount)) itm = QListWidgetItem(self.tr(" Expected Failure")) itm.setForeground(Qt.blue) self.testsListWidget.insertItem(1, itm) def testSucceededUnexpected(self, test, id): """ Public method called if a test succeeds unexpectedly. @param test name of the test (string) @param id id of the test (string) """ self.unexpectedSuccessCount += 1 self.progressCounterUnexpectedSuccessCount.setText( str(self.unexpectedSuccessCount)) itm = QListWidgetItem(self.tr(" Unexpected Success")) itm.setForeground(Qt.red) self.testsListWidget.insertItem(1, itm) def testStarted(self, test, doc): """ Public method called if a test is about to be run. @param test name of the started test (string) @param doc documentation of the started test (string) """ if doc: self.testsListWidget.insertItem(0, " {0}".format(doc)) self.testsListWidget.insertItem(0, test) if self.dbs is None or self.localCheckBox.isChecked(): QApplication.processEvents() def testFinished(self): """ Public method called if a test has finished. Note: It is also called if it has already failed or errored. """ # update the counters self.remainingCount -= 1 self.runCount += 1 self.progressCounterRunCount.setText(str(self.runCount)) self.progressCounterRemCount.setText(str(self.remainingCount)) # update the progressbar if self.errorCount: self.__setProgressColor("red") elif self.failCount: self.__setProgressColor("orange") self.progressProgressBar.setValue(self.runCount) def on_errorsListWidget_itemDoubleClicked(self, lbitem): """ Private slot called by doubleclicking an errorlist entry. It will popup a dialog showing the stacktrace. If called from eric, an additional button is displayed to show the python source in an eric source viewer (in erics main window. @param lbitem the listbox item that was double clicked """ self.errListIndex = self.errorsListWidget.row(lbitem) text = lbitem.text() self.on_errorsListWidget_currentTextChanged(text) # get the error info test, tracebackText = lbitem.data(Qt.UserRole) # now build the dialog from .Ui_UnittestStacktraceDialog import Ui_UnittestStacktraceDialog self.dlg = QDialog() ui = Ui_UnittestStacktraceDialog() ui.setupUi(self.dlg) self.dlg.traceback = ui.traceback ui.showButton = ui.buttonBox.addButton( self.tr("Show Source"), QDialogButtonBox.ActionRole) ui.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.dlg.setWindowTitle(text) ui.testLabel.setText(test) ui.traceback.setPlainText(tracebackText) # one more button if called from eric if self.dbs: ui.showButton.clicked.connect(self.__showSource) else: ui.showButton.hide() # and now fire it up self.dlg.show() self.dlg.exec_() def __showSource(self): """ Private slot to show the source of a traceback in an eric6 editor. """ if not self.dbs: return # get the error info tracebackLines = self.dlg.traceback.toPlainText().splitlines() # find the last entry matching the pattern for index in range(len(tracebackLines) - 1, -1, -1): fmatch = re.search(r'File "(.*?)", line (\d*?),.*', tracebackLines[index]) if fmatch: break if fmatch: fn, ln = fmatch.group(1, 2) self.unittestFile.emit(fn, int(ln), 1) def hasFailedTests(self): """ Public method to check, if there are failed tests from the last run. @return flag indicating the presence of failed tests (boolean) """ return bool(self.__failedTests) class QtTestResult(unittest.TestResult): """ A TestResult derivative to work with a graphical GUI. For more details see pyunit.py of the standard python distribution. """ def __init__(self, parent): """ Constructor @param parent The parent widget. """ super(QtTestResult, self).__init__() self.parent = parent def addFailure(self, test, err): """ Public method called if a test failed. @param test reference to the test object @param err error traceback """ super(QtTestResult, self).addFailure(test, err) tracebackLines = self._exc_info_to_string(err, test) self.parent.testFailed(str(test), tracebackLines, test.id()) def addError(self, test, err): """ Public method called if a test errored. @param test reference to the test object @param err error traceback """ super(QtTestResult, self).addError(test, err) tracebackLines = self._exc_info_to_string(err, test) self.parent.testErrored(str(test), tracebackLines, test.id()) def addSkip(self, test, reason): """ Public method called if a test was skipped. @param test reference to the test object @param reason reason for skipping the test (string) """ super(QtTestResult, self).addSkip(test, reason) self.parent.testSkipped(str(test), reason, test.id()) def addExpectedFailure(self, test, err): """ Public method called if a test failed expected. @param test reference to the test object @param err error traceback """ super(QtTestResult, self).addExpectedFailure(test, err) tracebackLines = self._exc_info_to_string(err, test) self.parent.testFailedExpected(str(test), tracebackLines, test.id()) def addUnexpectedSuccess(self, test): """ Public method called if a test succeeded expectedly. @param test reference to the test object """ super(QtTestResult, self).addUnexpectedSuccess(test) self.parent.testSucceededUnexpected(str(test), test.id()) def startTest(self, test): """ Public method called at the start of a test. @param test Reference to the test object """ super(QtTestResult, self).startTest(test) self.parent.testStarted(str(test), test.shortDescription()) def stopTest(self, test): """ Public method called at the end of a test. @param test Reference to the test object """ super(QtTestResult, self).stopTest(test) self.parent.testFinished() class UnittestWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, prog=None, parent=None): """ Constructor @param prog filename of the program to open @param parent reference to the parent widget (QWidget) """ super(UnittestWindow, self).__init__(parent) self.cw = UnittestDialog(prog=prog, parent=self) self.cw.installEventFilter(self) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) def eventFilter(self, obj, event): """ Public method to filter events. @param obj reference to the object the event is meant for (QObject) @param event reference to the event object (QEvent) @return flag indicating, whether the event was handled (boolean) """ if event.type() == QEvent.Close: QApplication.exit() return True return False eric-6.0.8/eric/PyUnit/UnittestDialog.ui0000644000175000017500000003364712354032755017216 0ustar piotrpiotr UnittestDialog 0 0 650 700 Unittest Enter the test name. Leave empty to use the default name "suite". <b>Testname</b><p>Enter the name of the test to be performed. This name must follow the rules given by Python's unittest module. If this field is empty, the default name of "suite" will be used.</p> true 0 0 Enter name of file defining the testsuite <b>Testsuite</b> <p>Enter the name of the file defining the testsuite. It should have a method with a name given below. If no name is given, the suite() method will be tried. If no such method can be found, the module will be inspected for proper test cases.</p> true QComboBox::InsertAtTop false Enter &test name: testComboBox Enter test &filename: testsuiteComboBox Open a file selection dialog Select whether you want to run the test locally Run &local Select whether coverage data should be collected C&ollect coverage data false Select whether old coverage data should be erased &Erase coverage data Progress: Qt::Horizontal 371 20 0 Qt::Horizontal %v/%m Tests Run: Number of tests run 0 Remaining: Number of tests to be run 0 Qt::Horizontal 40 20 Failures: Number of test failures 0 Errors: Number of test errors 0 Skipped: Number of tests skipped 0 Expected Failures: Number of tests with expected failure 0 Unexpected Successes: Number of tests with unexpected success 0 Qt::Horizontal QSizePolicy::Expanding 20 20 Tests performed: Failures and errors: Failures and Errors list <b>Failures and Errors list</b> <p>This list shows all failed and errored tests. Double clicking on an entry will show the respective traceback.</p> Qt::Horizontal QDialogButtonBox::Close 0 0 Idle Qt::Horizontal QSizePolicy::Expanding 20 20 E5Led QFrame
E5Gui/E5Led.h
1
testsuiteComboBox fileDialogButton testComboBox localCheckBox coverageCheckBox coverageEraseCheckBox testsListWidget errorsListWidget coverageCheckBox toggled(bool) coverageEraseCheckBox setEnabled(bool) 405 107 604 107 buttonBox accepted() UnittestDialog close() 58 618 72 667 buttonBox rejected() UnittestDialog close() 148 623 148 668
eric-6.0.8/eric/eric6_snap.py0000644000175000017500000000311112451233374015050 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Eric6 Snap. This is the main Python script that performs the necessary initialization of the snapshot module and starts the Qt event loop. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from Snapshot.SnapWidget import SnapWidget return SnapWidget() def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ] appinfo = AppInfo.makeAppInfo( sys.argv, "Eric6 Snap", "", "Simple utility to do snapshots of the screen.", options) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/eric6_re.pyw0000644000175000017500000000027412451233400014701 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_re import main main() eric-6.0.8/eric/Toolbox/0000755000175000017500000000000012557365360014107 5ustar piotrpiotreric-6.0.8/eric/Toolbox/PyQt4ImportHook.py0000644000175000017500000000505612451233374017454 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing an import hook converting PyQt5 imports to PyQt4 imports. """ import sys try: if "--pyqt4" in sys.argv: sys.argv.remove("--pyqt4") # fake a failed PyQt5 import raise ImportError import PyQt5 # __IGNORE_WARNING__ except ImportError: import importlib class PyQt4Importer(object): """ Class implementing an importer converting PyQt5 imports to PyQt4 imports. """ def __init__(self): """ Constructor """ self.__path = None def find_module(self, fullname, path=None): """ Public method returning the module loader. @param fullname name of the module to be loaded (string) @param path path to resolve the module name (string) @return module loader object """ if fullname.startswith("PyQt5"): self.__path = path return self return None def load_module(self, fullname): """ Public method to load a module. @param fullname name of the module to be loaded (string) @return reference to the loaded module (module) """ if fullname in ["PyQt5.QtWidgets", "PyQt5.QtPrintSupport"]: newname = "PyQt4.QtGui" elif fullname in ["PyQt5.QtWebKitWidgets"]: newname = "PyQt4.QtWebKit" else: newname = fullname.replace("PyQt5", "PyQt4") module = importlib.import_module(newname) sys.modules[fullname] = module if fullname == "PyQt5.QtCore": import PyQt4.QtGui module.qInstallMessageHandler = module.qInstallMsgHandler module.QItemSelectionModel = PyQt4.QtGui.QItemSelectionModel module.QItemSelection = PyQt4.QtGui.QItemSelection module.QSortFilterProxyModel = \ PyQt4.QtGui.QSortFilterProxyModel module.QAbstractProxyModel = PyQt4.QtGui.QAbstractProxyModel module.QStringListModel = PyQt4.QtGui.QStringListModel return module sys.meta_path.insert(0, PyQt4Importer()) if sys.version_info[0] == 2: import sip sip.setapi('QString', 2) sip.setapi('QVariant', 2) sip.setapi('QTextStream', 2) eric-6.0.8/eric/Toolbox/SingleApplication.py0000644000175000017500000001202612451233374020057 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing the single application server and client. """ from __future__ import unicode_literals from PyQt5.QtNetwork import QLocalServer, QLocalSocket class SingleApplicationServer(QLocalServer): """ Class implementing the single application server base class. """ def __init__(self, name): """ Constructor @param name name this server is listening to (string) """ super(SingleApplicationServer, self).__init__() res = self.listen(name) if not res: # maybe it crashed last time self.removeServer(name) self.listen(name) self.newConnection.connect(self.__newConnection) self.qsock = None def __newConnection(self): """ Private slot to handle a new connection. """ sock = self.nextPendingConnection() # If we already have a connection, refuse this one. It will be closed # automatically. if self.qsock is not None: return self.qsock = sock self.qsock.readyRead.connect(self.__parseLine) self.qsock.disconnected.connect(self.__disconnected) def __parseLine(self): """ Private method to handle data from the client. """ while self.qsock and self.qsock.canReadLine(): line = bytes(self.qsock.readLine()).decode() ## print(line) ##debug eoc = line.find('<') + 1 boc = line.find('>') if boc >= 0 and eoc > boc: # handle the command sent by the client. cmd = line[boc:eoc] params = line[eoc:-1] self.handleCommand(cmd, params) def __disconnected(self): """ Private method to handle the closure of the socket. """ self.qsock = None def shutdown(self): """ Public method used to shut down the server. """ if self.qsock is not None: self.qsock.readyRead.disconnect(self.__parseLine) self.qsock.disconnected.disconnect(self.__disconnected) self.qsock = None self.close() def handleCommand(self, cmd, params): """ Public slot to handle the command sent by the client. Note: This method must be overridden by subclasses. @param cmd commandstring (string) @param params parameterstring (string) @exception RuntimeError raised to indicate that this method must be implemented by a subclass """ raise RuntimeError("'handleCommand' must be overridden") class SingleApplicationClient(object): """ Class implementing the single application client base class. """ def __init__(self, name): """ Constructor @param name name of the local server to connect to (string) """ self.name = name self.connected = False def connect(self): """ Public method to connect the single application client to its server. @return value indicating success or an error number. Value is one of:
0No application is running
1Application is already running
""" self.sock = QLocalSocket() self.sock.connectToServer(self.name) if self.sock.waitForConnected(10000): self.connected = True return 1 else: err = self.sock.error() if err == QLocalSocket.ServerNotFoundError: return 0 else: return -err def disconnect(self): """ Public method to disconnect from the Single Appliocation server. """ self.sock.disconnectFromServer() self.connected = False def processArgs(self, args): """ Public method to process the command line args passed to the UI. Note: This method must be overridden by subclasses. @param args command line args (list of strings) @exception RuntimeError raised to indicate that this method must be implemented by a subclass """ raise RuntimeError("'processArgs' must be overridden") def sendCommand(self, cmd): """ Public method to send the command to the application server. @param cmd command to be sent (string) """ if self.connected: self.sock.write(cmd) self.sock.flush() def errstr(self): """ Public method to return a meaningful error string for the last error. @return error string for the last error (string) """ return self.sock.errorString() eric-6.0.8/eric/Toolbox/__init__.py0000644000175000017500000000023012451233374016203 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Package implementing general purpose tools. """ eric-6.0.8/eric/Toolbox/Startup.py0000644000175000017500000001741312455012201016105 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing some startup helper funcions. """ from __future__ import unicode_literals import os import sys from PyQt5.QtCore import QTranslator, QLocale, QLibraryInfo, QDir, \ QTextCodec, qVersion from PyQt5.QtWidgets import QApplication from E5Gui.E5Application import E5Application import Globals import UI.PixmapCache from eric6config import getConfig def usage(appinfo, optlen=12): """ Module function to show the usage information. @param appinfo dictionary describing the application @param optlen length of the field for the commandline option (integer) """ options = [ ("--version", "show the program's version number and exit"), ("-h, --help", "show this help message and exit") ] options.extend(appinfo["options"]) print("""\n""" """Usage: {bin} [OPTIONS] {arg}\n""" """\n""" """{name} - {description}\n""" """\n""" """Options:""".format(**appinfo)) for opt in options: print(" {0} {1}".format(opt[0].ljust(optlen), opt[1])) sys.exit(0) def version(appinfo): """ Module function to show the version information. @param appinfo dictionary describing the application """ print("""\n""" """{name} {version}\n""" """\n""" """{description}\n""" """\n""" """Copyright (c) 2002 - 2015 Detlev Offenbach""" """ \n""" """This is free software; see LICENSE.GPL3 for copying""" """ conditions.\n""" """There is NO warranty; not even for MERCHANTABILITY or FITNESS""" """ FOR A\n""" """PARTICULAR PURPOSE.""".format(**appinfo)) sys.exit(0) def handleArgs(argv, appinfo): """ Module function to handle the always present commandline options. @param argv list of commandline parameters (list of strings) @param appinfo dictionary describing the application @return index of the '--' option (integer). This is used to tell the application, that all additional options don't belong to the application. """ ddindex = 30000 # arbitrarily large number args = { "--version": version, "--help": usage, "-h": usage } if '--' in argv: ddindex = argv.index("--") for a in args: if a in argv and argv.index(a) < ddindex: args[a](appinfo) return ddindex def loadTranslatorForLocale(dirs, tn): """ Module function to find and load a specific translation. @param dirs Searchpath for the translations. (list of strings) @param tn The translation to be loaded. (string) @return Tuple of a status flag and the loaded translator (int, QTranslator) """ trans = QTranslator(None) for dir in dirs: loaded = trans.load(tn, dir) if loaded: return (trans, True) print("Warning: translation file '" + tn + "'could not be loaded.") print("Using default.") return (None, False) def initializeResourceSearchPath(): """ Module function to initialize the default mime source factory. """ import Preferences defaultIconPaths = [ os.path.join(getConfig('ericIconDir'), "default"), os.path.join(getConfig('ericIconDir'), "default", "languages"), ] iconPaths = Preferences.getIcons("Path") for iconPath in iconPaths: if iconPath: UI.PixmapCache.addSearchPath(iconPath) for defaultIconPath in defaultIconPaths: if defaultIconPath not in iconPaths: UI.PixmapCache.addSearchPath(defaultIconPath) def setLibraryPaths(): """ Module function to set the Qt library paths correctly for windows systems. """ if Globals.isWindowsPlatform(): libPath = os.path.join(Globals.getPyQt5ModulesDirectory(), "plugins") if os.path.exists(libPath): libPath = QDir.fromNativeSeparators(libPath) libraryPaths = QApplication.libraryPaths() if libPath not in libraryPaths: libraryPaths.insert(0, libPath) QApplication.setLibraryPaths(libraryPaths) # the translator must not be deleted, therefore we save them here loaded_translators = {} def loadTranslators(qtTransDir, app, translationFiles=()): """ Module function to load all required translations. @param qtTransDir directory of the Qt translations files (string) @param app reference to the application object (QApplication) @param translationFiles tuple of additional translations to be loaded (tuple of strings) @return the requested locale (string) """ import Preferences global loaded_translators if qVersion() < "5.0.0": # set the default encoding for tr() QTextCodec.setCodecForTr(QTextCodec.codecForName("utf-8")) translations = ("qt", "eric6") + translationFiles loc = Preferences.getUILanguage() if loc is None: return if loc == "System": loc = QLocale.system().name() if loc != "C": dirs = [getConfig('ericTranslationsDir'), Globals.getConfigDir()] if qtTransDir is not None: dirs.append(qtTransDir) loca = loc for tf in ["{0}_{1}".format(tr, loc) for tr in translations]: translator, ok = loadTranslatorForLocale(dirs, tf) loaded_translators[tf] = translator if ok: app.installTranslator(translator) else: if tf.startswith("eric6"): loca = None loc = loca else: loc = None return loc def simpleAppStartup(argv, appinfo, mwFactory, quitOnLastWindowClosed=True, app=None, raiseIt=True, installErrorHandler=False): """ Module function to start up an application that doesn't need a specialized start up. This function is used by all of eric6's helper programs. @param argv list of commandline parameters (list of strings) @param appinfo dictionary describing the application @param mwFactory factory function generating the main widget. This function must accept the following parameter.
argv
list of commandline parameters (list of strings)
@keyparam quitOnLastWindowClosed flag indicating to quit the application, if the last window was closed (boolean) @keyparam app reference to the application object (QApplication or None) @keyparam raiseIt flag indicating to raise the generated application window (boolean) @keyparam installErrorHandler flag indicating to install an error handler dialog (boolean) @return exit result (integer) """ handleArgs(argv, appinfo) if app is None: # set the library paths for plugins setLibraryPaths() app = E5Application(argv) app.setQuitOnLastWindowClosed(quitOnLastWindowClosed) # the following code depends upon a valid application object import Preferences initializeResourceSearchPath() QApplication.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) qt4TransDir = Preferences.getQt4TranslationsDir() if not qt4TransDir: qt4TransDir = QLibraryInfo.location(QLibraryInfo.TranslationsPath) loadTranslators(qt4TransDir, app) w = mwFactory(argv) if quitOnLastWindowClosed: app.lastWindowClosed.connect(app.quit) w.show() if raiseIt: w.raise_() if installErrorHandler: # generate a graphical error handler from E5Gui import E5ErrorMessage eMsg = E5ErrorMessage.qtHandler() eMsg.setMinimumSize(600, 400) return app.exec_() eric-6.0.8/eric/eric6_editor.pyw0000644000175000017500000000030012451233400015547 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_editor import main main() eric-6.0.8/eric/install-i18n.py0000644000175000017500000000612612451233374015253 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # # This is the install script for eric6's translation files. """ Installation script for the eric6 IDE translation files. """ from __future__ import unicode_literals import sys import os import shutil import glob from PyQt5.QtCore import QDir try: from eric6config import getConfig except ImportError: print("The eric6 IDE doesn't seem to be installed. Aborting.") sys.exit(1) def getConfigDir(): """ Global function to get the name of the directory storing the config data. @return directory name of the config dir (string) """ if sys.platform.startswith("win"): cdn = "_eric6" else: cdn = ".eric6" hp = QDir.homePath() dn = QDir(hp) dn.mkdir(cdn) hp += "/" + cdn try: return QDir.toNativeSeparators(hp) except AttributeError: return QDir.toNativeSeparators(hp) # Define the globals. progName = None configDir = getConfigDir() privateInstall = False def usage(rcode=2): """ Display a usage message and exit. @param rcode return code passed back to the calling process (integer) """ global progName, configDir print() print("Usage:") print(" {0} [-hp]".format(progName)) print("where:") print(" -h display this help message") print(" -p install into the private area ({0})".format( configDir)) sys.exit(rcode) def installTranslations(): """ Install the translation files into the right place. """ global privateInstall, configDir if privateInstall: targetDir = configDir else: targetDir = getConfig('ericTranslationsDir') try: for fn in glob.glob(os.path.join('eric', 'i18n', '*.qm')): shutil.copy2(fn, targetDir) os.chmod(os.path.join(targetDir, os.path.basename(fn)), 0o644) except IOError as msg: sys.stderr.write( 'IOError: {0}\nTry install-i18n as root.\n'.format(msg)) except OSError as msg: sys.stderr.write( 'OSError: {0}\nTry install-i18n with admin rights.\n'.format(msg)) def main(argv): """ The main function of the script. @param argv list of command line arguments (list of strings) """ import getopt # Parse the command line. global progName, privateInstall progName = os.path.basename(argv[0]) try: optlist, args = getopt.getopt(argv[1:], "hp") except getopt.GetoptError: usage() global platBinDir for opt, arg in optlist: if opt == "-h": usage(0) elif opt == "-p": privateInstall = 1 installTranslations() if __name__ == "__main__": try: main(sys.argv) except SystemExit: raise except: print("""An internal error occured. Please report all the output of""" """ the program,\nincluding the following traceback, to""" """ eric-bugs@eric-ide.python-projects.org.\n""") raise eric-6.0.8/eric/Examples/0000755000175000017500000000000012451233406014223 5ustar piotrpiotreric-6.0.8/eric/Examples/hallo.py0000644000175000017500000000020412451233374015674 0ustar piotrpiotr#!/usr/bin/env python import sys def main(): print("Hello World!") sys.exit(0) if __name__ == "__main__": main() eric-6.0.8/eric/Examples/modpython_dbg.py0000644000175000017500000000033012451233374017432 0ustar piotrpiotrfrom mod_python import apache apache.initDebugger('/Path/To/modpython_dbg.py') def handler(req): req.content_type = "text/plain" req.send_http_header() req.write("Hello World!\n") return apache.OK eric-6.0.8/eric/Examples/modpython.py0000644000175000017500000000024612451233374016624 0ustar piotrpiotrfrom mod_python import apache def handler(req): req.content_type = "text/plain" req.send_http_header() req.write("Hello World!\n") return apache.OK eric-6.0.8/eric/Examples/rhallo.py0000644000175000017500000000044612451233374016066 0ustar piotrpiotr#!/usr/bin/env python import sys import eric6dbgstub def main(): print("Hello World!") sys.exit(0) if __name__ == "__main__": if eric6dbgstub.initDebugger("standard"): # or if eric6dbgstub.initDebugger("threads"): eric6dbgstub.debugger.startDebugger() main() eric-6.0.8/eric/E5Gui/0000755000175000017500000000000012557365404013376 5ustar piotrpiotreric-6.0.8/eric/E5Gui/E5Completers.py0000644000175000017500000000661612451233374016261 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing various kinds of completers. """ from __future__ import unicode_literals from PyQt5.QtCore import QDir, Qt, QStringListModel from PyQt5.QtWidgets import QCompleter, QFileSystemModel from Globals import isWindowsPlatform class E5FileCompleter(QCompleter): """ Class implementing a completer for file names. """ def __init__(self, parent=None, completionMode=QCompleter.PopupCompletion, showHidden=False): """ Constructor @param parent parent widget of the completer (QWidget) @keyparam completionMode completion mode of the completer (QCompleter.CompletionMode) @keyparam showHidden flag indicating to show hidden entries as well (boolean) """ super(E5FileCompleter, self).__init__(parent) self.__model = QFileSystemModel(self) if showHidden: self.__model.setFilter( QDir.Filters(QDir.Dirs | QDir.Files | QDir.Drives | QDir.AllDirs | QDir.Hidden)) else: self.__model.setFilter(QDir.Filters( QDir.Dirs | QDir.Files | QDir.Drives | QDir.AllDirs)) self.setModel(self.__model) self.setCompletionMode(completionMode) if isWindowsPlatform(): self.setCaseSensitivity(Qt.CaseInsensitive) if parent: parent.setCompleter(self) class E5DirCompleter(QCompleter): """ Class implementing a completer for directory names. """ def __init__(self, parent=None, completionMode=QCompleter.PopupCompletion, showHidden=False): """ Constructor @param parent parent widget of the completer (QWidget) @keyparam completionMode completion mode of the completer (QCompleter.CompletionMode) @keyparam showHidden flag indicating to show hidden entries as well (boolean) """ super(E5DirCompleter, self).__init__(parent) self.__model = QFileSystemModel(self) if showHidden: self.__model.setFilter( QDir.Filters(QDir.Drives | QDir.AllDirs | QDir.Hidden)) else: self.__model.setFilter( QDir.Filters(QDir.Drives | QDir.AllDirs)) self.setModel(self.__model) self.setCompletionMode(completionMode) if isWindowsPlatform(): self.setCaseSensitivity(Qt.CaseInsensitive) if parent: parent.setCompleter(self) class E5StringListCompleter(QCompleter): """ Class implementing a completer for string lists. """ def __init__(self, parent=None, strings=[], completionMode=QCompleter.PopupCompletion): """ Constructor @param parent parent widget of the completer (QWidget) @param strings list of string to load into the completer (list of strings) @keyparam completionMode completion mode of the completer (QCompleter.CompletionMode) """ super(E5StringListCompleter, self).__init__(parent) self.__model = QStringListModel(strings, parent) self.setModel(self.__model) self.setCompletionMode(completionMode) if parent: parent.setCompleter(self) eric-6.0.8/eric/E5Gui/E5PassivePopup.py0000644000175000017500000001423712451233374016600 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing dialog-like popup that displays messages without interrupting the user. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QTimer, QPoint, QRect from PyQt5.QtWidgets import QFrame, QVBoxLayout, QApplication class E5PassivePopup(QFrame): """ Class implementing dialog-like popup that displays messages without interrupting the user. """ Boxed = 0 Custom = 128 clicked = pyqtSignal((), (QPoint, )) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5PassivePopup, self).__init__(None) self.__popupStyle = DEFAULT_POPUP_TYPE self.__msgView = None self.__topLayout = None self.__hideDelay = DEFAULT_POPUP_TIME self.__hideTimer = QTimer(self) self.__autoDelete = False self.__fixedPosition = QPoint() self.setWindowFlags(POPUP_FLAGS) self.setFrameStyle(QFrame.Box | QFrame.Plain) self.setLineWidth(2) self.__hideTimer.timeout.connect(self.hide) self.clicked.connect(self.hide) def setView(self, child): """ Public method to set the message view. @param child reference to the widget to set as the message view (QWidget) """ self.__msgView = child self.__topLayout = QVBoxLayout(self) self.__topLayout.addWidget(self.__msgView) self.__topLayout.activate() def view(self): """ Public method to get a reference to the message view. @return reference to the message view (QWidget) """ return self.__msgView def setVisible(self, visible): """ Public method to show or hide the popup. @param visible flag indicating the visibility status (boolean) """ if not visible: super(E5PassivePopup, self).setVisible(visible) return if self.size() != self.sizeHint(): self.resize(self.sizeHint()) if self.__fixedPosition.isNull(): self.__positionSelf() else: self.move(self.__fixedPosition) super(E5PassivePopup, self).setVisible(True) delay = self.__hideDelay if delay < 0: delay = DEFAULT_POPUP_TIME if delay > 0: self.__hideTimer.start(delay) def show(self, p=None): """ Public slot to show the popup. @param p position for the popup (QPoint) """ if p is not None: self.__fixedPosition = p super(E5PassivePopup, self).show() def setTimeout(self, delay): """ Public method to set the delay for the popup is removed automatically. Setting the delay to 0 disables the timeout. If you're doing this, you may want to connect the clicked() signal to the hide() slot. Setting the delay to -1 makes it use the default value. @param delay value for the delay in milliseconds (integer) """ self.__hideDelay = delay if self.__hideTimer.isActive(): if delay: if delay == -1: delay = DEFAULT_POPUP_TIME self.__hideTimer.start(delay) else: self.__hideTimer.stop() def timeout(self): """ Public method to get the delay before the popup is removed automatically. @return the delay before the popup is removed automatically (integer) """ return self.__hideDelay def mouseReleaseEvent(self, evt): """ Protected method to handle a mouse release event. @param evt reference to the mouse event (QMouseEvent) """ self.clicked.emit() self.clicked.emit(evt.pos()) def hideEvent(self, evt): """ Protected method to handle the hide event. @param evt reference to the hide event (QHideEvent) """ self.__hideTimer.stop() def __defaultArea(self): """ Private method to determine the default rectangle to be passed to moveNear(). @return default rectangle (QRect) """ return QRect(100, 100, 200, 200) def __positionSelf(self): """ Private method to position the popup. """ self.__moveNear(self.__defaultArea()) def __moveNear(self, target): """ Private method to move the popup to be adjacent to the specified rectangle. @param target rectangle to be placed at (QRect) """ pos = self.__calculateNearbyPoint(target) self.move(pos.x(), pos.y()) def __calculateNearbyPoint(self, target): """ Private method to calculate the position to place the popup near the specified rectangle. @param target rectangle to be placed at (QRect) @return position to place the popup (QPoint) """ pos = target.topLeft() x = pos.x() y = pos.y() w = self.minimumSizeHint().width() h = self.minimumSizeHint().height() r = QApplication.desktop().screenGeometry( QPoint(x + w // 2, y + h // 2)) if x < r.center().x(): x += target.width() else: x -= w # It's apparently trying to go off screen, so display it ALL at the # bottom. if (y + h) > r.bottom(): y = r.bottom() - h if (x + w) > r.right(): x = r.right() - w if y < r.top(): y = r.top() if x < r.left(): x = r.left() return QPoint(x, y) DEFAULT_POPUP_TYPE = E5PassivePopup.Boxed DEFAULT_POPUP_TIME = 6 * 1000 POPUP_FLAGS = Qt.WindowFlags( Qt.Tool | Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) eric-6.0.8/eric/E5Gui/E5MapWidget.py0000644000175000017500000002464612451233374016030 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2014 - 2015 Detlev Offenbach # """ Module implementing a base class for showing a document map. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QSize, QRect, QCoreApplication, qVersion from PyQt5.QtGui import QColor, QBrush, QPainter from PyQt5.QtWidgets import QWidget, QAbstractScrollArea class E5MapWidget(QWidget): """ Class implementing a base class for showing a document map. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5MapWidget, self).__init__(parent) self.setAttribute(Qt.WA_OpaquePaintEvent) self.__width = 14 self.__lineBorder = 1 self.__lineHeight = 2 self.__backgroundColor = QColor("#e7e7e7") self.__setSliderColor() self._master = None self.__enabled = False if parent is not None and isinstance(parent, QAbstractScrollArea): self.setMaster(parent) def __setSliderColor(self): """ Private method to set the slider color depending upon the background color. """ if self.__backgroundColor.toHsv().value() < 128: # dark background, use white slider self.__sliderColor = Qt.white else: # light background, use black slider self.__sliderColor = Qt.black def __updateMasterViewportWidth(self): """ Private method to update the master's viewport width. """ if self._master: if self.__enabled: width = self.__width else: width = 0 self._master.setViewportMargins(0, 0, width, 0) def setMaster(self, master): """ Public method to set the map master widget. @param master map master widget (QAbstractScrollArea) """ self._master = master self._master.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self._master.verticalScrollBar().valueChanged.connect(self.repaint) self.__updateMasterViewportWidth() def setWidth(self, width): """ Public method to set the widget width. @param width widget width (integer) """ if width != self.__width: self.__width = max(6, width) # minimum width 6 pixels self.__updateMasterViewportWidth() self.update() def width(self): """ Public method to get the widget's width. @return widget width (integer) """ return self.__width def setLineDimensions(self, border, height): """ Public method to set the line (indicator) dimensions. @param border border width on each side in x-direction (integer) @param height height of the line in pixels (integer) """ if border != self.__lineBorder or height != self.__lineHeight: self.__lineBorder = max(1, border) # min border 1 pixel self.__lineHeight = max(1, height) # min height 1 pixel self.update() def lineDimensions(self): """ Public method to get the line (indicator) dimensions. @return tuple with border width (integer) and line height (integer) """ return self.__lineBorder, self.__lineHeight def setEnabled(self, enable): """ Public method to set the enabled state. @param enable flag indicating the enabled state (boolean) """ if enable != self.__enabled: self.__enabled = enable self.setVisible(enable) self.__updateMasterViewportWidth() def isEnabled(self): """ Public method to check the enabled state. @return flag indicating the enabled state (boolean) """ return self.__enabled def setBackgroundColor(self, color): """ Public method to set the widget background color. @param color color for the background (QColor) """ if color != self.__backgroundColor: self.__backgroundColor = color self.__setSliderColor() self.update() def backgroundColor(self): """ Public method to get the background color. @return background color (QColor) """ return QColor(self.__backgroundColor) def sizeHint(self): """ Public method to give an indication about the preferred size. @return preferred size (QSize) """ return QSize(self.__width, 0) def paintEvent(self, event): """ Protected method to handle a paint event. @param event paint event (QPaintEvent) """ # step 1: fill the whole painting area painter = QPainter(self) painter.fillRect(event.rect(), self.__backgroundColor) # step 2: paint the indicators self._paintIt(painter) # step 3: paint the slider if self._master: penColor = self.__sliderColor painter.setPen(penColor) brushColor = Qt.transparent painter.setBrush(QBrush(brushColor)) painter.drawRect(self.__generateSliderRange( self._master.verticalScrollBar())) def _paintIt(self, painter): """ Protected method for painting the widget's indicators. Note: This method should be implemented by subclasses. @param painter reference to the painter object (QPainter) """ pass def mousePressEvent(self, event): """ Protected method to handle a mouse button press. @param event reference to the mouse event (QMouseEvent) """ if event.button() == Qt.LeftButton and self._master: vsb = self._master.verticalScrollBar() value = self.position2Value(event.pos().y() - 1) vsb.setValue(value - 0.5 * vsb.pageStep()) # center on page self.__mousePressPos = None def mouseMoveEvent(self, event): """ Protected method to handle a mouse moves. @param event reference to the mouse event (QMouseEvent) """ if event.buttons() & Qt.LeftButton and self._master: vsb = self._master.verticalScrollBar() value = self.position2Value(event.pos().y() - 1) vsb.setValue(value - 0.5 * vsb.pageStep()) # center on page def wheelEvent(self, event): """ Protected slot handling mouse wheel events. @param event reference to the wheel event (QWheelEvent) """ if qVersion() >= "5.0.0": isVertical = event.angleDelta().x() == 0 else: isVertical = event.orientation() == Qt.Vertical if self._master and \ event.modifiers() == Qt.NoModifier and \ isVertical: QCoreApplication.sendEvent(self._master.verticalScrollBar(), event) def calculateGeometry(self): """ Public method to recalculate the map widget's geometry. """ if self._master: cr = self._master.contentsRect() vsb = self._master.verticalScrollBar() if vsb.isVisible(): vsbw = vsb.contentsRect().width() else: vsbw = 0 left, top, right, bottom = self._master.getContentsMargins() if right > vsbw: vsbw = 0 self.setGeometry(QRect(cr.right() - self.__width - vsbw, cr.top(), self.__width, cr.height())) def scaleFactor(self, slider=False): """ Public method to determine the scrollbar's scale factor. @param slider flag indicating to calculate the result for the slider (boolean) @return scale factor (float) """ if self._master: delta = 0 if slider else 2 vsb = self._master.verticalScrollBar() posHeight = vsb.height() - delta - 1 valHeight = vsb.maximum() - vsb.minimum() + vsb.pageStep() return float(posHeight) / valHeight else: return 1.0 def value2Position(self, value, slider=False): """ Public method to convert a scrollbar value into a position. @param value value to convert (integer) @param slider flag indicating to calculate the result for the slider (boolean) @return position (integer) """ if self._master: offset = 0 if slider else 1 vsb = self._master.verticalScrollBar() return (value - vsb.minimum()) * self.scaleFactor(slider) + offset else: return value def position2Value(self, position, slider=False): """ Public method to convert a position into a scrollbar value. @param position scrollbar position to convert (integer) @param slider flag indicating to calculate the result for the slider (boolean) @return scrollbar value (integer) """ if self._master: offset = 0 if slider else 1 vsb = self._master.verticalScrollBar() return vsb.minimum() + max( 0, (position - offset) / self.scaleFactor(slider)) else: return position def generateIndicatorRect(self, position): """ Public method to generate an indicator rectangle. @param position indicator position (integer) @return indicator rectangle (QRect) """ return QRect(self.__lineBorder, position - self.__lineHeight // 2, self.__width - self.__lineBorder, self.__lineHeight) def __generateSliderRange(self, scrollbar): """ Private method to generate the slider rectangle. @param scrollbar reference to the vertical scrollbar (QScrollBar) @return slider rectangle (QRect) """ pos1 = self.value2Position(scrollbar.value(), slider=True) pos2 = self.value2Position(scrollbar.value() + scrollbar.pageStep(), slider=True) return QRect(0, pos1, self.__width - 1, pos2 - pos1) eric-6.0.8/eric/E5Gui/E5ToolBarManager.py0000644000175000017500000006011112554667477017012 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing a toolbar manager class. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject, QByteArray, QDataStream, QIODevice from PyQt5.QtWidgets import QToolBar import Utilities class E5ToolBarManager(QObject): """ Class implementing a toolbar manager. """ VersionMarker = 0xffff ToolBarMarker = 0xfefe CustomToolBarMarker = 0xfdfd def __init__(self, ui=None, parent=None): """ Constructor @param ui reference to the user interface object (UI.UserInterface) @param parent reference to the parent object (QObject) """ super(E5ToolBarManager, self).__init__(parent) self.__mainWindow = None self.__ui = ui self.__toolBars = {} # maps toolbar IDs to actions self.__toolBarsWithSeparators = {} # maps toolbar IDs to actions incl. separators self.__defaultToolBars = {} # maps default toolbar IDs to actions self.__customToolBars = [] # list of custom toolbars self.__allToolBars = {} # maps toolbar IDs to toolbars self.__categoryToActions = {} # maps categories to actions self.__actionToCategory = {} # maps action IDs to categories self.__allActions = {} # maps action IDs to actions self.__actionToToolBars = {} # maps action IDs to toolbars self.__widgetActions = {} # maps widget action IDs to toolbars self.__allWidgetActions = {} # maps widget action IDs to widget actions ###################################################### ## Private methods ###################################################### def __toolBarByName(self, name): """ Private slot to get a toolbar by its object name. @param name object name of the toolbar (string) @return reference to the toolbar (QToolBar) """ for toolBar in list(self.__allToolBars.values()): if toolBar.objectName() == name: return toolBar return None def __findAction(self, name): """ Private method to find an action by name. @param name name of the action to search for (string) @return reference to the action (QAction) """ # check objectName() first for action in list(self.__allActions.values()): if action.objectName() == name: return action # check text() next for action in list(self.__allActions.values()): if action.text() == name: return action return None def __findDefaultToolBar(self, name): """ Private method to find a default toolbar by name. @param name name of the default toolbar to search for (string) @return reference to the default toolbar (QToolBar) """ # check objectName() first for tbID in self.__defaultToolBars: tb = self.__allToolBars[tbID] if tb.objectName() == name: return tb # check windowTitle() next for tbID in self.__defaultToolBars: tb = self.__allToolBars[tbID] if tb.windowTitle() == name: return tb return None ###################################################### ## Public methods ###################################################### def setMainWindow(self, mainWindow): """ Public method to set the reference to the main window. @param mainWindow reference to the main window (QMainWindow) """ self.__mainWindow = mainWindow def mainWindow(self): """ Public method to get the reference to the main window. @return reference to the main window (QMainWindow) """ return self.__mainWindow def addToolBar(self, toolBar, category): """ Public method to add a toolbar to be managed. @param toolBar reference to the toolbar to be managed (QToolBar) @param category category for the toolbar (string) """ if toolBar is None: return newActions = [] newActionsWithSeparators = [] actions = toolBar.actions() for action in actions: actID = id(action) self.addAction(action, category) if actID in self.__widgetActions: self.__widgetActions[actID] = toolBar newActionsWithSeparators.append(action) if action.isSeparator(): action = None else: if toolBar not in self.__actionToToolBars[actID]: self.__actionToToolBars[actID].append(toolBar) newActions.append(action) tbID = id(toolBar) self.__defaultToolBars[tbID] = newActions self.__toolBars[tbID] = newActions self.__toolBarsWithSeparators[tbID] = newActionsWithSeparators self.__allToolBars[tbID] = toolBar def removeToolBar(self, toolBar): """ Public method to remove a toolbar added with addToolBar(). @param toolBar reference to the toolbar to be removed (QToolBar) """ if toolBar is None: return tbID = id(toolBar) if tbID not in self.__defaultToolBars: return defaultActions = self.__defaultToolBars[tbID][:] self.setToolBar(toolBar, []) for action in defaultActions: self.removeAction(action) del self.__defaultToolBars[tbID] del self.__toolBars[tbID] del self.__toolBarsWithSeparators[tbID] del self.__allToolBars[tbID] for action in defaultActions: if action is None: toolBar.addSeparator() else: toolBar.addAction(action) def setToolBars(self, toolBars): """ Public method to set the actions of several toolbars. @param toolBars dictionary with toolbar id as key and a list of actions as value """ for key, actions in list(toolBars.items()): tb = self.__allToolBars[key] self.setToolBar(tb, actions) def setToolBar(self, toolBar, actions): """ Public method to set the actions of a toolbar. @param toolBar reference to the toolbar to configure (QToolBar) @param actions list of actions to be set (list of QAction) """ if toolBar is None: return tbID = id(toolBar) if tbID not in self.__toolBars: return if self.__toolBars[tbID] == actions: return # step 1: check list of actions toRemove = {} newActions = [] for action in actions: if action is None or \ (action not in newActions and id(action) in self.__allActions): newActions.append(action) oldTB = self.toolBarWidgetAction(action) if oldTB is not None and oldTB != toolBar: if id(oldTB) not in toRemove: toRemove[id(oldTB)] = [] toRemove[id(oldTB)].append(action) self.removeWidgetActions(toRemove) # step 2: remove all toolbar actions for action in self.__toolBarsWithSeparators[tbID]: if self.toolBarWidgetAction(action) == tbID: self.__widgetActions[id(action)] = None toolBar.removeAction(action) if action.isSeparator(): del action else: self.__actionToToolBars[id(action)].remove(toolBar) # __IGNORE_WARNING__ # step 3: set the actions as requested newActionsWithSeparators = [] for action in newActions: newAction = None if action is None: newAction = toolBar.addSeparator() elif id(action) in self.__allActions: toolBar.addAction(action) newAction = action self.__actionToToolBars[id(action)].append(toolBar) if id(action) in self.__widgetActions: self.__widgetActions[id(action)] = toolBar else: continue newActionsWithSeparators.append(newAction) if toolBar.isVisible(): toolBar.hide() toolBar.show() self.__toolBars[tbID] = newActions self.__toolBarsWithSeparators[tbID] = newActionsWithSeparators def resetToolBar(self, toolBar): """ Public method to reset a toolbar to its default state. @param toolBar reference to the toolbar to configure (QToolBar) """ if not self.isDefaultToolBar(): return self.setToolBar(toolBar, self.__defaultToolBars[id(toolBar)]) def resetAllToolBars(self): """ Public method to reset all toolbars to their default state. """ self.setToolBars(self.__defaultToolBars) for toolBar in self.__customToolBars[:]: self.deleteToolBar(toolBar) def defaultToolBars(self): """ Public method to get all toolbars added with addToolBar(). @return list of all default toolbars (list of QToolBar) """ return list(self.__defaultToolBars.values()) def isDefaultToolBar(self, toolBar): """ Public method to check, if a toolbar was added with addToolBar(). @param toolBar reference to the toolbar to be checked (QToolBar) @return flag indicating an added toolbar (boolean) """ return toolBar is not None and \ id(toolBar) in self.__defaultToolBars def createToolBar(self, title, name=""): """ Public method to create a custom toolbar. @param title title to be used for the toolbar (string) @param name optional name for the new toolbar (string) @return reference to the created toolbar (QToolBar) """ if self.__mainWindow is None: return None toolBar = QToolBar(title, self.__mainWindow) toolBar.setToolTip(title) if not name: index = 1 customPrefix = "__CustomPrefix__" name = "{0}{1:d}".format(customPrefix, index) while self.__toolBarByName(name) is not None: index += 1 name = "{0}{1:d}".format(customPrefix, index) toolBar.setObjectName(name) self.__mainWindow.addToolBar(toolBar) tbID = id(toolBar) self.__customToolBars.append(toolBar) self.__allToolBars[tbID] = toolBar self.__toolBars[tbID] = [] self.__toolBarsWithSeparators[tbID] = [] if self.__ui is not None: toolBar.setIconSize(self.__ui.getToolBarIconSize()) self.__ui.registerToolbar(name, title, toolBar) return toolBar def deleteToolBar(self, toolBar): """ Public method to remove a custom toolbar created with createToolBar(). @param toolBar reference to the toolbar to be managed (QToolBar) """ if toolBar is None: return tbID = id(toolBar) if tbID not in self.__toolBars: return if tbID in self.__defaultToolBars: return if self.__ui is not None: self.__ui.unregisterToolbar(toolBar.objectName()) self.setToolBar(toolBar, []) del self.__allToolBars[tbID] del self.__toolBars[tbID] del self.__toolBarsWithSeparators[tbID] self.__customToolBars.remove(toolBar) self.__mainWindow.removeToolBar(toolBar) del toolBar def renameToolBar(self, toolBar, title): """ Public method to give a toolbar a new title. @param toolBar reference to the toolbar to be managed (QToolBar) @param title title to be used for the toolbar (string) """ if toolBar is None: return toolBar.setWindowTitle(title) if self.__ui is not None: self.__ui.reregisterToolbar(toolBar.objectName(), title) def toolBars(self): """ Public method to get all toolbars. @return list of all toolbars (list of QToolBar) """ return list(self.__allToolBars.values()) def addAction(self, action, category): """ Public method to add an action to be managed. @param action reference to the action to be managed (QAction) @param category category for the toolbar (string) """ if action is None: return if action.isSeparator(): return if id(action) in self.__allActions: return if action.metaObject().className() == "QWidgetAction": self.__widgetActions[id(action)] = None self.__allWidgetActions[id(action)] = action self.__allActions[id(action)] = action if category not in self.__categoryToActions: self.__categoryToActions[category] = [] self.__categoryToActions[category].append(action) self.__actionToCategory[id(action)] = category self.__actionToToolBars[id(action)] = [] def removeAction(self, action): """ Public method to remove an action from the manager. @param action reference to the action to be removed (QAction) """ aID = id(action) if aID not in self.__allActions: return toolBars = self.__actionToToolBars[aID] for toolBar in toolBars: tbID = id(toolBar) self.__toolBars[tbID].remove(action) self.__toolBarsWithSeparators[tbID].remove(action) toolBar.removeAction(action) if toolBar.isVisible(): toolBar.hide() toolBar.show() for tbID in self.__defaultToolBars: if action in self.__defaultToolBars[tbID]: self.__defaultToolBars[tbID].remove(action) del self.__allActions[aID] if aID in self.__widgetActions: del self.__widgetActions[aID] del self.__allWidgetActions[aID] del self.__actionToCategory[aID] del self.__actionToToolBars[aID] for category in self.__categoryToActions: if action in self.__categoryToActions[category]: self.__categoryToActions[category].remove(action) def saveState(self, version=0): """ Public method to save the state of the toolbar manager. @param version version number stored with the data (integer) @return saved state as a byte array (QByteArray) """ data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) stream.writeUInt16(E5ToolBarManager.VersionMarker) stream.writeUInt16(version) # save default toolbars stream.writeUInt16(E5ToolBarManager.ToolBarMarker) stream.writeUInt16(len(self.__defaultToolBars)) for tbID in self.__defaultToolBars: tb = self.__allToolBars[tbID] if tb.objectName(): stream.writeString(tb.objectName().encode("utf-8")) else: stream.writeString(tb.windowTitle().encode("utf-8")) stream.writeUInt16(len(self.__toolBars[tbID])) for action in self.__toolBars[tbID]: if action is not None: if action.objectName(): stream.writeString(action.objectName().encode("utf-8")) else: stream.writeString(action.text().encode("utf-8")) else: stream.writeString("".encode("utf-8")) # save the custom toolbars stream.writeUInt16(E5ToolBarManager.CustomToolBarMarker) stream.writeUInt16(len(self.__toolBars) - len(self.__defaultToolBars)) for tbID in self.__toolBars: if tbID not in self.__defaultToolBars: tb = self.__allToolBars[tbID] stream.writeString(tb.objectName().encode("utf-8")) stream.writeString(tb.windowTitle().encode("utf-8")) stream.writeUInt16(len(self.__toolBars[tbID])) for action in self.__toolBars[tbID]: if action is not None: if action.objectName(): stream.writeString(action.objectName() .encode("utf-8")) else: stream.writeString(action.text().encode("utf-8")) else: stream.writeString("".encode("utf-8")) return data def restoreState(self, state, version=0): """ Public method to restore the state of the toolbar manager. @param state byte array containing the saved state (QByteArray) @param version version number stored with the data (integer) @return flag indicating success (boolean) """ if state.isEmpty(): return False data = QByteArray(state) stream = QDataStream(data, QIODevice.ReadOnly) stream.setVersion(QDataStream.Qt_4_6) marker = stream.readUInt16() vers = stream.readUInt16() if marker != E5ToolBarManager.VersionMarker or vers != version: return False tmarker = stream.readUInt16() if tmarker != E5ToolBarManager.ToolBarMarker: return False toolBarCount = stream.readUInt16() for i in range(toolBarCount): objectName = Utilities.readStringFromStream(stream) actionCount = stream.readUInt16() actions = [] for j in range(actionCount): actionName = Utilities.readStringFromStream(stream) if actionName: action = self.__findAction(actionName) if action is not None: actions.append(action) else: actions.append(None) toolBar = self.__findDefaultToolBar(objectName) if toolBar is not None: self.setToolBar(toolBar, actions) cmarker = stream.readUInt16() if cmarker != E5ToolBarManager.CustomToolBarMarker: return False oldCustomToolBars = self.__customToolBars[:] toolBarCount = stream.readUInt16() for i in range(toolBarCount): objectName = Utilities.readStringFromStream(stream) toolBarTitle = Utilities.readStringFromStream(stream) actionCount = stream.readUInt16() actions = [] for j in range(actionCount): actionName = Utilities.readStringFromStream(stream) if actionName: action = self.__findAction(actionName) if action is not None: actions.append(action) else: actions.append(None) toolBar = self.__toolBarByName(objectName) if toolBar is not None: toolBar.setWindowTitle(toolBarTitle) oldCustomToolBars.remove(toolBar) else: toolBar = self.createToolBar(toolBarTitle, objectName) if toolBar is not None: toolBar.setObjectName(objectName) self.setToolBar(toolBar, actions) for tb in oldCustomToolBars: self.deleteToolBar(tb) return True def toolBarWidgetAction(self, action): """ Public method to get the toolbar for a widget action. @param action widget action to check for (QAction) @return reference to the toolbar containing action (QToolBar) """ aID = id(action) if aID in self.__widgetActions: return self.__widgetActions[aID] return None def removeWidgetActions(self, actions): """ Public method to remove widget actions. @param actions dictionary with toolbar id as key and a list of widget actions as value """ for tbID in list(actions.keys())[:]: toolBar = self.__allToolBars[tbID] newActions = self.__toolBars[tbID][:] newActionsWithSeparators = self.__toolBarsWithSeparators[tbID][:] removedActions = [] for action in actions[tbID]: if action in newActions and \ self.toolBarWidgetAction(action) == toolBar: newActions.remove(action) newActionsWithSeparators.remove(action) removedActions.append(action) self.__toolBars[tbID] = newActions self.__toolBarsWithSeparators[tbID] = newActionsWithSeparators for action in removedActions: self.__widgetActions[id(action)] = None self.__actionToToolBars[id(action)].remove(toolBar) toolBar.removeAction(action) def isWidgetAction(self, action): """ Public method to check, if action is a widget action. @param action reference to the action to be checked (QAction) @return flag indicating a widget action (boolean) """ return id(action) in self.__allWidgetActions def categories(self): """ Public method to get the list of categories. @return list of categories (list of string) """ return list(self.__categoryToActions.keys()) def categoryActions(self, category): """ Public method to get the actions belonging to a category. @param category category for the toolbar (string) @return list of actions (list of QAction) """ if category not in self.__categoryToActions: return [] return self.__categoryToActions[category][:] def actionById(self, aID): """ Public method to get an action given its id. @param aID id of the action object (integer) @return reference to the action (QAction) """ if aID not in self.__allActions: return None return self.__allActions[aID] def toolBarById(self, tbID): """ Public method to get a toolbar given its id. @param tbID id of the toolbar object (integer) @return reference to the toolbar (QToolBar) """ if tbID not in self.__allToolBars: return None return self.__allToolBars[tbID] def toolBarActions(self, tbID): """ Public method to get a toolbar's actions given its id. @param tbID id of the toolbar object (integer) @return list of actions (list of QAction) """ if tbID not in self.__toolBars: return [] return self.__toolBars[tbID][:] def toolBarsActions(self): """ Public method to get all toolbars and their actions. @return reference to dictionary of toolbar IDs as key and list of actions as values """ return self.__toolBars def defaultToolBarActions(self, tbID): """ Public method to get a default toolbar's actions given its id. @param tbID id of the default toolbar object (integer) @return list of actions (list of QAction) """ if tbID not in self.__defaultToolBars: return [] return self.__defaultToolBars[tbID][:] eric-6.0.8/eric/E5Gui/E5ToolBarDialog.py0000644000175000017500000005040312451233374016617 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing a toolbar configuration dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem, \ QInputDialog, QLineEdit, QListWidgetItem, QAbstractButton from E5Gui import E5MessageBox from .Ui_E5ToolBarDialog import Ui_E5ToolBarDialog import UI.PixmapCache class E5ToolBarItem(object): """ Class storing data belonging to a toolbar entry of the toolbar dialog. """ def __init__(self, toolBarId, actionIDs, default): """ Constructor @param toolBarId id of the toolbar object (integer) @param actionIDs list of action IDs belonging to the toolbar (list of integer) @param default flag indicating a default toolbar (boolean) """ self.toolBarId = toolBarId self.actionIDs = actionIDs[:] self.isDefault = default self.title = "" self.isChanged = False class E5ToolBarDialog(QDialog, Ui_E5ToolBarDialog): """ Class implementing a toolbar configuration dialog. """ ActionIdRole = Qt.UserRole WidgetActionRole = Qt.UserRole + 1 def __init__(self, toolBarManager, parent=None): """ Constructor @param toolBarManager reference to a toolbar manager object (E5ToolBarManager) @param parent reference to the parent widget (QWidget) """ super(E5ToolBarDialog, self).__init__(parent) self.setupUi(self) self.__manager = toolBarManager self.__toolbarItems = {} # maps toolbar item IDs to toolbar items self.__currentToolBarItem = None self.__removedToolBarIDs = [] # remember custom toolbars to be deleted self.__widgetActionToToolBarItemID = {} # maps widget action IDs to toolbar item IDs self.__toolBarItemToWidgetActionID = {} # maps toolbar item IDs to widget action IDs self.upButton.setIcon(UI.PixmapCache.getIcon("1uparrow.png")) self.downButton.setIcon(UI.PixmapCache.getIcon("1downarrow.png")) self.leftButton.setIcon(UI.PixmapCache.getIcon("1leftarrow.png")) self.rightButton.setIcon(UI.PixmapCache.getIcon("1rightarrow.png")) self.__restoreDefaultsButton = \ self.buttonBox.button(QDialogButtonBox.RestoreDefaults) self.__resetButton = self.buttonBox.button(QDialogButtonBox.Reset) self.actionsTree.header().hide() self.__separatorText = self.tr("--Separator--") itm = QTreeWidgetItem(self.actionsTree, [self.__separatorText]) self.actionsTree.setCurrentItem(itm) for category in sorted(self.__manager.categories()): categoryItem = QTreeWidgetItem(self.actionsTree, [category]) for action in self.__manager.categoryActions(category): item = QTreeWidgetItem(categoryItem) item.setText(0, action.text()) item.setIcon(0, action.icon()) item.setTextAlignment(0, Qt.AlignLeft | Qt.AlignVCenter) item.setData(0, E5ToolBarDialog.ActionIdRole, int(id(action))) item.setData(0, E5ToolBarDialog.WidgetActionRole, False) if self.__manager.isWidgetAction(action): item.setData(0, E5ToolBarDialog.WidgetActionRole, True) item.setData(0, Qt.TextColorRole, QColor(Qt.blue)) self.__widgetActionToToolBarItemID[id(action)] = None categoryItem.setExpanded(True) for tbID, actions in list(self.__manager.toolBarsActions().items()): tb = self.__manager.toolBarById(tbID) default = self.__manager.isDefaultToolBar(tb) tbItem = E5ToolBarItem(tbID, [], default) self.__toolbarItems[id(tbItem)] = tbItem self.__toolBarItemToWidgetActionID[id(tbItem)] = [] actionIDs = [] for action in actions: if action is None: actionIDs.append(None) else: aID = id(action) actionIDs.append(aID) if aID in self.__widgetActionToToolBarItemID: self.__widgetActionToToolBarItemID[aID] = id(tbItem) self.__toolBarItemToWidgetActionID[id(tbItem)]\ .append(aID) tbItem.actionIDs = actionIDs self.toolbarComboBox.addItem(tb.windowTitle(), int(id(tbItem))) if default: self.toolbarComboBox.setItemData( self.toolbarComboBox.count() - 1, QColor(Qt.darkGreen), Qt.ForegroundRole) self.toolbarComboBox.model().sort(0) self.toolbarComboBox.currentIndexChanged[int].connect( self.__toolbarComboBox_currentIndexChanged) self.toolbarComboBox.setCurrentIndex(0) @pyqtSlot() def on_newButton_clicked(self): """ Private slot to create a new toolbar. """ name, ok = QInputDialog.getText( self, self.tr("New Toolbar"), self.tr("Toolbar Name:"), QLineEdit.Normal) if ok and name: if self.toolbarComboBox.findText(name) != -1: # toolbar with this name already exists E5MessageBox.critical( self, self.tr("New Toolbar"), self.tr( """A toolbar with the name {0} already""" """ exists.""") .format(name)) return tbItem = E5ToolBarItem(None, [], False) tbItem.title = name tbItem.isChanged = True self.__toolbarItems[id(tbItem)] = tbItem self.__toolBarItemToWidgetActionID[id(tbItem)] = [] self.toolbarComboBox.addItem(name, int(id(tbItem))) self.toolbarComboBox.model().sort(0) self.toolbarComboBox.setCurrentIndex( self.toolbarComboBox.findText(name)) @pyqtSlot() def on_removeButton_clicked(self): """ Private slot to remove a custom toolbar. """ name = self.toolbarComboBox.currentText() res = E5MessageBox.yesNo( self, self.tr("Remove Toolbar"), self.tr( """Should the toolbar {0} really be removed?""") .format(name)) if res: index = self.toolbarComboBox.currentIndex() tbItemID = self.toolbarComboBox.itemData(index) tbItem = self.__toolbarItems[tbItemID] if tbItem.toolBarId is not None and \ tbItem.toolBarId not in self.__removedToolBarIDs: self.__removedToolBarIDs.append(tbItem.toolBarId) del self.__toolbarItems[tbItemID] for widgetActionID in self.__toolBarItemToWidgetActionID[tbItemID]: self.__widgetActionToToolBarItemID[widgetActionID] = None del self.__toolBarItemToWidgetActionID[tbItemID] self.toolbarComboBox.removeItem(index) @pyqtSlot() def on_renameButton_clicked(self): """ Private slot to rename a custom toolbar. """ oldName = self.toolbarComboBox.currentText() newName, ok = QInputDialog.getText( self, self.tr("Rename Toolbar"), self.tr("New Toolbar Name:"), QLineEdit.Normal, oldName) if ok and newName: if oldName == newName: return if self.toolbarComboBox.findText(newName) != -1: # toolbar with this name already exists E5MessageBox.critical( self, self.tr("Rename Toolbar"), self.tr( """A toolbar with the name {0} already""" """ exists.""") .format(newName)) return index = self.toolbarComboBox.currentIndex() self.toolbarComboBox.setItemText(index, newName) tbItem = \ self.__toolbarItems[self.toolbarComboBox.itemData(index)] tbItem.title = newName tbItem.isChanged = True def __setupButtons(self): """ Private slot to set the buttons state. """ index = self.toolbarComboBox.currentIndex() if index > -1: itemID = self.toolbarComboBox.itemData(index) self.__currentToolBarItem = self.__toolbarItems[itemID] self.renameButton.setEnabled( not self.__currentToolBarItem.isDefault) self.removeButton.setEnabled( not self.__currentToolBarItem.isDefault) self.__restoreDefaultsButton.setEnabled( self.__currentToolBarItem.isDefault) self.__resetButton.setEnabled( self.__currentToolBarItem.toolBarId is not None) row = self.toolbarActionsList.currentRow() self.upButton.setEnabled(row > 0) self.downButton.setEnabled(row < self.toolbarActionsList.count() - 1) self.leftButton.setEnabled(self.toolbarActionsList.count() > 0) rightEnable = self.actionsTree.currentItem().parent() is not None or \ self.actionsTree.currentItem().text(0) == self.__separatorText self.rightButton.setEnabled(rightEnable) @pyqtSlot(int) def __toolbarComboBox_currentIndexChanged(self, index): """ Private slot called upon a selection of the current toolbar. @param index index of the new current toolbar (integer) """ itemID = self.toolbarComboBox.itemData(index) self.__currentToolBarItem = self.__toolbarItems[itemID] self.toolbarActionsList.clear() for actionID in self.__currentToolBarItem.actionIDs: item = QListWidgetItem(self.toolbarActionsList) if actionID is None: item.setText(self.__separatorText) else: action = self.__manager.actionById(actionID) item.setText(action.text()) item.setIcon(action.icon()) item.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter) item.setData(E5ToolBarDialog.ActionIdRole, int(id(action))) item.setData(E5ToolBarDialog.WidgetActionRole, False) if self.__manager.isWidgetAction(action): item.setData(E5ToolBarDialog.WidgetActionRole, True) item.setData(Qt.TextColorRole, QColor(Qt.blue)) self.toolbarActionsList.setCurrentRow(0) self.__setupButtons() @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_actionsTree_currentItemChanged(self, current, previous): """ Private slot called, when the currently selected action changes. @param current reference to the current item (QTreeWidgetItem) @param previous reference to the previous current item (QTreeWidgetItem) """ self.__setupButtons() @pyqtSlot(QListWidgetItem, QListWidgetItem) def on_toolbarActionsList_currentItemChanged(self, current, previous): """ Private slot to handle a change of the current item. @param current reference to the current item (QListWidgetItem) @param previous reference to the previous current item (QListWidgetItem) """ self.__setupButtons() @pyqtSlot() def on_upButton_clicked(self): """ Private slot used to move an action up in the list. """ row = self.toolbarActionsList.currentRow() if row == 0: # we're already at the top return actionID = self.__currentToolBarItem.actionIDs.pop(row) self.__currentToolBarItem.actionIDs.insert(row - 1, actionID) self.__currentToolBarItem.isChanged = True itm = self.toolbarActionsList.takeItem(row) self.toolbarActionsList.insertItem(row - 1, itm) self.toolbarActionsList.setCurrentItem(itm) self.__setupButtons() @pyqtSlot() def on_downButton_clicked(self): """ Private slot used to move an action down in the list. """ row = self.toolbarActionsList.currentRow() if row == self.toolbarActionsList.count() - 1: # we're already at the end return actionID = self.__currentToolBarItem.actionIDs.pop(row) self.__currentToolBarItem.actionIDs.insert(row + 1, actionID) self.__currentToolBarItem.isChanged = True itm = self.toolbarActionsList.takeItem(row) self.toolbarActionsList.insertItem(row + 1, itm) self.toolbarActionsList.setCurrentItem(itm) self.__setupButtons() @pyqtSlot() def on_leftButton_clicked(self): """ Private slot to delete an action from the list. """ row = self.toolbarActionsList.currentRow() actionID = self.__currentToolBarItem.actionIDs.pop(row) self.__currentToolBarItem.isChanged = True if actionID in self.__widgetActionToToolBarItemID: self.__widgetActionToToolBarItemID[actionID] = None self.__toolBarItemToWidgetActionID[id(self.__currentToolBarItem)]\ .remove(actionID) itm = self.toolbarActionsList.takeItem(row) del itm self.toolbarActionsList.setCurrentRow(row) self.__setupButtons() @pyqtSlot() def on_rightButton_clicked(self): """ Private slot to add an action to the list. """ row = self.toolbarActionsList.currentRow() + 1 item = QListWidgetItem() if self.actionsTree.currentItem().text(0) == self.__separatorText: item.setText(self.__separatorText) actionID = None else: actionID = self.actionsTree.currentItem()\ .data(0, E5ToolBarDialog.ActionIdRole) action = self.__manager.actionById(actionID) item.setText(action.text()) item.setIcon(action.icon()) item.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter) item.setData(E5ToolBarDialog.ActionIdRole, int(id(action))) item.setData(E5ToolBarDialog.WidgetActionRole, False) if self.__manager.isWidgetAction(action): item.setData(E5ToolBarDialog.WidgetActionRole, True) item.setData(Qt.TextColorRole, QColor(Qt.blue)) oldTbItemID = self.__widgetActionToToolBarItemID[actionID] if oldTbItemID is not None: self.__toolbarItems[oldTbItemID].actionIDs.remove(actionID) self.__toolbarItems[oldTbItemID].isChanged = True self.__toolBarItemToWidgetActionID[oldTbItemID]\ .remove(actionID) self.__widgetActionToToolBarItemID[actionID] = \ id(self.__currentToolBarItem) self.__toolBarItemToWidgetActionID[ id(self.__currentToolBarItem)].append(actionID) self.toolbarActionsList.insertItem(row, item) self.__currentToolBarItem.actionIDs.insert(row, actionID) self.__currentToolBarItem.isChanged = True self.toolbarActionsList.setCurrentRow(row) self.__setupButtons() @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot called, when a button of the button box was clicked. @param button reference to the button clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Cancel): self.reject() elif button == self.buttonBox.button(QDialogButtonBox.Apply): self.__saveToolBars() self.__setupButtons() elif button == self.buttonBox.button(QDialogButtonBox.Ok): self.__saveToolBars() self.accept() elif button == self.buttonBox.button(QDialogButtonBox.Reset): self.__resetCurrentToolbar() self.__setupButtons() elif button == self.buttonBox.button(QDialogButtonBox.RestoreDefaults): self.__restoreCurrentToolbarToDefault() self.__setupButtons() def __saveToolBars(self): """ Private method to save the configured toolbars. @exception RuntimeError raised to indicate an invalid action """ # step 1: remove toolbars marked for deletion for tbID in self.__removedToolBarIDs: tb = self.__manager.toolBarById(tbID) self.__manager.deleteToolBar(tb) self.__removedToolBarIDs = [] # step 2: save configured toolbars for tbItem in list(self.__toolbarItems.values()): if not tbItem.isChanged: continue if tbItem.toolBarId is None: # new custom toolbar tb = self.__manager.createToolBar(tbItem.title) tbItem.toolBarId = id(tb) else: tb = self.__manager.toolBarById(tbItem.toolBarId) if not tbItem.isDefault and tbItem.title: self.__manager.renameToolBar(tb, tbItem.title) actions = [] for actionID in tbItem.actionIDs: if actionID is None: actions.append(None) else: action = self.__manager.actionById(actionID) if action is None: raise RuntimeError( "No such action, id: 0x{0:x}".format(actionID)) actions.append(action) self.__manager.setToolBar(tb, actions) tbItem.isChanged = False def __restoreCurrentToolbar(self, actions): """ Private methdo to restore the current toolbar to the given list of actions. @param actions list of actions to set for the current toolbar (list of QAction) """ tbItemID = id(self.__currentToolBarItem) for widgetActionID in self.__toolBarItemToWidgetActionID[tbItemID]: self.__widgetActionToToolBarItemID[widgetActionID] = None self.__toolBarItemToWidgetActionID[tbItemID] = [] self.__currentToolBarItem.actionIDs = [] for action in actions: if action is None: self.__currentToolBarItem.actionIDs.append(None) else: actionID = id(action) self.__currentToolBarItem.actionIDs.append(actionID) if actionID in self.__widgetActionToToolBarItemID: oldTbItemID = self.__widgetActionToToolBarItemID[actionID] if oldTbItemID is not None: self.__toolbarItems[oldTbItemID].actionIDs.remove( actionID) self.__toolbarItems[oldTbItemID].isChanged = True self.__toolBarItemToWidgetActionID[oldTbItemID].remove( actionID) self.__widgetActionToToolBarItemID[actionID] = tbItemID self.__toolBarItemToWidgetActionID[tbItemID].append( actionID) self.__toolbarComboBox_currentIndexChanged( self.toolbarComboBox.currentIndex()) def __resetCurrentToolbar(self): """ Private method to revert all changes made to the current toolbar. """ tbID = self.__currentToolBarItem.toolBarId actions = self.__manager.toolBarActions(tbID) self.__restoreCurrentToolbar(actions) self.__currentToolBarItem.isChanged = False def __restoreCurrentToolbarToDefault(self): """ Private method to set the current toolbar to its default configuration. """ if not self.__currentToolBarItem.isDefault: return tbID = self.__currentToolBarItem.toolBarId actions = self.__manager.defaultToolBarActions(tbID) self.__restoreCurrentToolbar(actions) self.__currentToolBarItem.isChanged = True eric-6.0.8/eric/E5Gui/E5SqueezeLabels.py0000644000175000017500000001020712451233374016677 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing labels that squeeze their contents to fit the size of the label. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QLabel from Utilities import compactPath class E5SqueezeLabel(QLabel): """ Class implementing a label that squeezes its contents to fit its size. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent Widget (QWidget) """ super(E5SqueezeLabel, self).__init__(parent) self.__text = '' self.__elided = '' def paintEvent(self, event): """ Protected method called when some painting is required. @param event reference to the paint event (QPaintEvent) """ fm = self.fontMetrics() if fm.width(self.__text) > self.contentsRect().width(): self.__elided = fm.elidedText( self.text(), Qt.ElideMiddle, self.width()) super(E5SqueezeLabel, self).setText(self.__elided) else: super(E5SqueezeLabel, self).setText(self.__text) super(E5SqueezeLabel, self).paintEvent(event) def setText(self, txt): """ Public method to set the label's text. @param txt the text to be shown (string) """ self.__text = txt super(E5SqueezeLabel, self).setText(self.__text) class E5SqueezeLabelPath(QLabel): """ Class implementing a label showing a file path compacted to fit its size. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent Widget (QWidget) """ super(E5SqueezeLabelPath, self).__init__(parent) self.__path = '' self.__surrounding = "{0}" def setSurrounding(self, surrounding): """ Public method to set the surrounding of the path string. @param surrounding the a string containg placeholders for the path (string) """ self.__surrounding = surrounding super(E5SqueezeLabelPath, self).setText( self.__surrounding.format(self.__path)) def setPath(self, path): """ Public method to set the path of the label. @param path path to be shown (string) """ self.__path = path super(E5SqueezeLabelPath, self).setText( self.__surrounding.format(self.__path)) def setTextPath(self, surrounding, path): """ Public method to set the surrounding and the path of the label. @param surrounding the a string containg placeholders for the path (string) @param path path to be shown (string) """ self.__surrounding = surrounding self.__path = path super(E5SqueezeLabelPath, self).setText( self.__surrounding.format(self.__path)) def paintEvent(self, event): """ Protected method called when some painting is required. @param event reference to the paint event (QPaintEvent) """ fm = self.fontMetrics() if (fm.width(self.__surrounding.format(self.__path)) > self.contentsRect().width()): super(E5SqueezeLabelPath, self).setText( self.__surrounding.format(compactPath(self.__path, self.contentsRect().width(), self.length)) ) else: super(E5SqueezeLabelPath, self).setText( self.__surrounding.format(self.__path)) super(E5SqueezeLabelPath, self).paintEvent(event) def length(self, txt): """ Public method to return the length of a text in pixels. @param txt text to calculate the length for after wrapped (string) @return length of the wrapped text in pixels (integer) """ return self.fontMetrics().width(self.__surrounding.format(txt)) eric-6.0.8/eric/E5Gui/E5ErrorMessageFilterDialog.py0000644000175000017500000000453112451233374021022 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a dialog to manage the list of messages to be ignored. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QSortFilterProxyModel, QStringListModel from PyQt5.QtWidgets import QDialog, QInputDialog, QLineEdit from .Ui_E5ErrorMessageFilterDialog import Ui_E5ErrorMessageFilterDialog class E5ErrorMessageFilterDialog(QDialog, Ui_E5ErrorMessageFilterDialog): """ Class implementing a dialog to manage the list of messages to be ignored. """ def __init__(self, messageFilters, parent=None): """ Constructor @param messageFilters list of message filters to be edited (list of strings) @param parent reference to the parent widget (QWidget) """ super(E5ErrorMessageFilterDialog, self).__init__(parent) self.setupUi(self) self.__model = QStringListModel(messageFilters, self) self.__model.sort(0) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.__proxyModel.setSourceModel(self.__model) self.filterList.setModel(self.__proxyModel) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.removeButton.clicked.connect(self.filterList.removeSelected) self.removeAllButton.clicked.connect(self.filterList.removeAll) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add an entry to the list. """ filter, ok = QInputDialog.getText( self, self.tr("Error Messages Filter"), self.tr("Enter message filter to add to the list:"), QLineEdit.Normal) if ok and filter != "" and filter not in self.__model.stringList(): self.__model.insertRow(self.__model.rowCount()) self.__model.setData( self.__model.index(self.__model.rowCount() - 1), filter) self.__model.sort(0) def getFilters(self): """ Public method to get the list of message filters. @return error message filters (list of strings) """ return self.__model.stringList()[:] eric-6.0.8/eric/E5Gui/E5TableView.py0000644000175000017500000000352312451233374016020 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing specialized table views. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QItemSelectionModel from PyQt5.QtWidgets import QTableView class E5TableView(QTableView): """ Class implementing a table view supporting removal of entries. """ def keyPressEvent(self, evt): """ Protected method implementing special key handling. @param evt reference to the event (QKeyEvent) """ if evt.key() in [Qt.Key_Delete, Qt.Key_Backspace] and \ self.model() is not None: self.removeSelected() evt.setAccepted(True) else: super(E5TableView, self).keyPressEvent(evt) def removeSelected(self): """ Public method to remove the selected entries. """ if self.model() is None or self.selectionModel() is None: # no models available return row = 0 selectedRows = self.selectionModel().selectedRows() for selectedRow in reversed(selectedRows): row = selectedRow.row() self.model().removeRow(row, self.rootIndex()) idx = self.model().index(row, 0, self.rootIndex()) if not idx.isValid(): idx = self.model().index(row - 1, 0, self.rootIndex()) self.selectionModel().select( idx, QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows) self.setCurrentIndex(idx) def removeAll(self): """ Public method to clear the view. """ if self.model() is not None: self.model().removeRows(0, self.model().rowCount(self.rootIndex()), self.rootIndex()) eric-6.0.8/eric/E5Gui/__init__.py0000644000175000017500000000033412451233374015500 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Package implementing some special GUI elements. They extend or ammend the standard elements as found in QtGui. """ eric-6.0.8/eric/E5Gui/E5ProgressDialog.py0000644000175000017500000000353712451233374017067 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a progress dialog allowing a customized progress bar label. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QProgressBar, QProgressDialog class E5ProgressDialog(QProgressDialog): """ Class implementing a progress dialog allowing a customized progress bar label. """ def __init__(self, labelText, cancelButtonText, minimum, maximum, format=None, parent=None, flags=Qt.WindowFlags()): """ Constructor @param labelText text of the dialog label (string) @param cancelButtonText text of the cancel button (string) @param minimum minimum value (integer) @param maximum maximum value (integer) @keyparam format label format of the progress bar (string) @keyparam parent reference to the parent widget (QWidget) @keyparam flags window flags of the dialog (Qt.WindowFlags) """ super(E5ProgressDialog, self).__init__( labelText, cancelButtonText, minimum, maximum, parent, flags) self.__progressBar = QProgressBar(self) self.__progressBar.setMinimum(minimum) self.__progressBar.setMaximum(maximum) if format: self.__progressBar.setFormat(format) self.setBar(self.__progressBar) def format(self): """ Public method to get the progress bar format. @return progress bar format (string) """ return self.__progressBar.format() def setFormat(self, format): """ Public method to set the progress bar format. @param format progress bar format (string) """ self.__progressBar.setFormat(format) eric-6.0.8/eric/E5Gui/E5LineEditButton.py0000644000175000017500000000550512451233374017031 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a button class to be used with E5LineEdit. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QPoint, QPointF from PyQt5.QtGui import QPainter, QPainterPath from PyQt5.QtWidgets import QAbstractButton class E5LineEditButton(QAbstractButton): """ Class implementing a button to be used with E5LineEdit. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5LineEditButton, self).__init__(parent) self.__menu = None self.__image = None self.setFocusPolicy(Qt.NoFocus) self.setCursor(Qt.ArrowCursor) self.setMinimumSize(16, 16) self.clicked.connect(self.__clicked) def setMenu(self, menu): """ Public method to set the button menu. @param menu reference to the menu (QMenu) """ self.__menu = menu self.update() def menu(self): """ Public method to get a reference to the menu. @return reference to the associated menu (QMenu) """ return self.__menu def setIcon(self, icon): """ Public method to set the button icon. @param icon icon to be set (QIcon) """ if icon.isNull(): self.__image = None else: self.__image = icon.pixmap(16, 16).toImage() super(E5LineEditButton, self).setIcon(icon) def __clicked(self): """ Private slot to handle a button click. """ if self.__menu: pos = self.mapToGlobal(QPoint(0, self.height())) self.__menu.exec_(pos) def paintEvent(self, evt): """ Protected method handling a paint event. @param evt reference to the paint event (QPaintEvent) """ painter = QPainter(self) if self.__image is not None and not self.__image.isNull(): x = (self.width() - self.__image.width()) // 2 - 1 y = (self.height() - self.__image.height()) // 2 - 1 painter.drawImage(x, y, self.__image) if self.__menu is not None: triagPath = QPainterPath() startPos = QPointF(self.width() - 5, self.height() - 3) triagPath.moveTo(startPos) triagPath.lineTo(startPos.x() + 4, startPos.y()) triagPath.lineTo(startPos.x() + 2, startPos.y() + 2) triagPath.closeSubpath() painter.setPen(Qt.black) painter.setBrush(Qt.black) painter.setRenderHint(QPainter.Antialiasing, False) painter.drawPath(triagPath) eric-6.0.8/eric/E5Gui/E5ComboBox.py0000644000175000017500000000364312451233374015651 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing combobox classes using the eric6 line edits. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QComboBox class E5ComboBox(QComboBox): """ Class implementing a combobox using the eric6 line edit. """ def __init__(self, parent=None, inactiveText=""): """ Constructor @param parent reference to the parent widget (QWidget) @param inactiveText text to be shown on inactivity (string) """ super(E5ComboBox, self).__init__(parent) self.setMinimumHeight(24) from .E5LineEdit import E5LineEdit self.__lineedit = E5LineEdit(self, inactiveText) self.setLineEdit(self.__lineedit) self.setMinimumHeight(self.__lineedit.minimumHeight() + 3) def inactiveText(self): """ Public method to get the inactive text. @return inactive text (string) """ return self.__lineedit.inactiveText() def setInactiveText(self, inactiveText): """ Public method to set the inactive text. @param inactiveText text to be shown on inactivity (string) """ self.__lineedit.setInactiveText() class E5ClearableComboBox(E5ComboBox): """ Class implementing a combobox using the eric6 line edit. """ def __init__(self, parent=None, inactiveText=""): """ Constructor @param parent reference to the parent widget (QWidget) @param inactiveText text to be shown on inactivity (string) """ super(E5ClearableComboBox, self).__init__(parent, inactiveText) from .E5LineEdit import E5ClearableLineEdit self.__lineedit = E5ClearableLineEdit(self, inactiveText) self.setLineEdit(self.__lineedit) eric-6.0.8/eric/E5Gui/E5ZoomWidget.py0000644000175000017500000002227012451233374016226 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a zoom widget for the status bar. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, pyqtSignal from PyQt5.QtWidgets import QWidget from .Ui_E5ZoomWidget import Ui_E5ZoomWidget class E5ZoomWidget(QWidget, Ui_E5ZoomWidget): """ Class implementing a zoom widget for the status bar. """ valueChanged = pyqtSignal(int) def __init__(self, outPix, inPix, resetPix, parent=None): """ Constructor @param outPix pixmap for the zoom out button (QPixmap) @param inPix pixmap for the zoom in button (QPixmap) @param resetPix pixmap for the zoom reset button (QPixmap) @param parent reference to the parent widget (QWidget) """ super(E5ZoomWidget, self).__init__(parent) self.setupUi(self) self.zoomOutLabel.setPixmap(outPix.scaled(16, 16)) self.zoomInLabel.setPixmap(inPix.scaled(16, 16)) self.zoomResetLabel.setPixmap(resetPix.scaled(16, 16)) self.zoomOutLabel.clicked.connect(self.__zoomOut) self.zoomInLabel.clicked.connect(self.__zoomIn) self.zoomResetLabel.clicked.connect(self.__zoomReset) self.slider.valueChanged.connect(self._sliderValueChanged) self.__default = 0 self.__percent = False # mapped slider self.__mapped = False self.__mapping = [] self.__setValueLabelWidth() @pyqtSlot(int) def on_slider_sliderMoved(self, value): """ Private slot to handle changes of the zoom value. @param value value of the slider (integer) """ if self.__mapped: self.valueChanged.emit(self.__mapping[value]) else: self.valueChanged.emit(value) def setValue(self, value): """ Public slot to set the value. @param value new zoom value (integer) """ self.slider.setValue(self.__indexForValue(value)) def value(self): """ Public method to get the current value. @return current zoom value (integer) """ if self.__mapped: return self.__mapping[self.slider.value()] else: return self.slider.value() def setMinimum(self, minimum): """ Public method to set the minimum value. @param minimum new minimum value (integer) """ if not self.__mapped: self.slider.setMinimum(minimum) self.__setValueLabelWidth() def minimum(self): """ Public method to get the minimum value. @return minimum value (integer) """ if self.__mapped: return self.__mapping[0] else: return self.slider.minimum() def setMaximum(self, maximum): """ Public method to set the maximum value. @param maximum new maximum value (integer) """ if not self.__mapped: self.slider.setMaximum(maximum) self.__setValueLabelWidth() def maximum(self): """ Public method to get the maximum value. @return maximum value (integer) """ if self.__mapped: return self.__mapping[-1] else: return self.slider.maximum() def setSingleStep(self, value): """ Public method to set the single step value. @param value value for the single step (integer) """ self.slider.setSingleStep(value) def singleStep(self): """ Public method to get the single step value. @return single step value (integer) """ return self.slider.singleStep() def setPageStep(self, value): """ Public method to set the page step value. @param value page step value (integer) """ self.slider.setPageStep(value) def pageStep(self): """ Public method to get the page step value. @return page step value (integer) """ return self.slider.pageStep() def setDefault(self, value): """ Public method to set the default zoom value. @param value default zoom value (integer) """ self.__default = self.__indexForValue(value) def default(self): """ Public method to get the default zoom value. @return default zoom value (integer) """ if self.__mapped: return self.__mapping[self.__default] else: return self.__default def setPercent(self, on): """ Public method to set the percent mode of the widget. @param on flag indicating percent mode (boolean) """ self.__percent = on self.__setValueLabelWidth() def isPercent(self): """ Public method to get the percent mode. @return flag indicating percent mode (boolean) """ return self.__percent def setMapping(self, mapping, default, percent=True): """ Public method to set a zoom level mapping. When zoom level mapping is activated, the slider covers values from 0 to the max. index of the mapping list. The default value is the value of the default zoom level. If percent is given, the zoom level is shown as a percent value. @param mapping list of mapping values (list of integer) @param default index of the default value (integer) @keyparam percent flag indicating to show zoom value in percent (boolean) """ if mapping: self.__mapping = mapping[:] self.__mapped = True self.slider.setMinimum(0) self.slider.setMaximum(len(self.__mapping) - 1) self.__default = self.__indexForValue(default) self.__percent = percent self.slider.setValue(self.__default) else: # switch back to default values self.__mapping = [] self.__mapped = False self.slider.setMinimum(-10) self.slider.setMaximum(20) self.__default = 0 self.__percent = False self.slider.setValue(0) self.__setValueLabelWidth() def mapping(self): """ Public method to get the current mapping. @return tuple of the mapping and the default index (list of integer, integer) """ return self.__mapping[:], self.__default def isMapped(self): """ Public method to check for a mapped zoom widget. @return flag indicating a mapped zoom widget (boolean) """ return self.__mapped def __zoomReset(self): """ Private slot to reset the value. """ self.slider.setValue(self.__default) self.valueChanged.emit(self.value()) def __zoomOut(self): """ Private slot to zoom out one step. """ self.slider.setValue(self.slider.value() - self.slider.singleStep()) self.valueChanged.emit(self.value()) def __zoomIn(self): """ Private slot to zoom in one step. """ self.slider.setValue(self.slider.value() + self.slider.singleStep()) self.valueChanged.emit(self.value()) def _sliderValueChanged(self, value): """ Protected slot to handle changes of the slider value. @param value slider value (integer) """ if self.__mapped: val = self.__mapping[value] else: val = value fmtStr = "{0}%" if self.__percent else "{0}" self.valueLabel.setText(fmtStr.format(val)) def __setValueLabelWidth(self): """ Private slot to determine the width of the zoom value label. """ if self.__mapped: labelLen = max([len(str(v)) for v in self.__mapping]) else: labelLen = max( len(str(self.slider.maximum())), len(str(self.slider.minimum())) ) fmtStr = "{0}%" if self.__percent else "{0}" label = fmtStr.format("0" * labelLen) width = self.valueLabel.fontMetrics().width(label) self.valueLabel.setMinimumWidth(width) self.valueLabel.setMaximumWidth(width) def __indexForValue(self, value): """ Private method to get the nearest index for a given value. @param value value to get the index for (integer) @return index into the mapping list or the unchanged value, if mapping is not set (integer) """ if self.__mapped: try: index = self.__mapping.index(value) except ValueError: for index in range(len(self.__mapping)): if value <= self.__mapping[index]: break else: index = value return index eric-6.0.8/eric/E5Gui/E5ClickableLabel.py0000644000175000017500000000277412451233374016756 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a clickable label. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QPoint from PyQt5.QtWidgets import QLabel class E5ClickableLabel(QLabel): """ Class implementing a clickable label. @signal clicked(QPoint) emitted upon a click on the label with the left button @signal middleClicked(QPoint) emitted upon a click on the label with the middle button or CTRL and left button """ clicked = pyqtSignal(QPoint) middleClicked = pyqtSignal(QPoint) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5ClickableLabel, self).__init__(parent) def mouseReleaseEvent(self, evt): """ Protected method handling mouse release events. @param evt mouse event (QMouseEvent) """ if evt.button() == Qt.LeftButton and self.rect().contains(evt.pos()): if evt.modifiers() == Qt.ControlModifier: self.middleClicked.emit(evt.globalPos()) else: self.clicked.emit(evt.globalPos()) elif evt.button() == Qt.MidButton and \ self.rect().contains(evt.pos()): self.middleClicked.emit(evt.globalPos()) else: super(E5ClickableLabel, self).mouseReleaseEvent(evt) eric-6.0.8/eric/E5Gui/E5TextSpinBox.py0000644000175000017500000000417412451233374016370 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a spinbox with textual entries. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QSpinBox class E5TextSpinBox(QSpinBox): """ Class implementing a spinbox with textual entries. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5TextSpinBox, self).__init__(parent) self.__items = [] self.setMinimum(0) self.setMaximum(0) def addItem(self, txt, data=None): """ Public method to add an item with item data. @param txt text to be shown (string) @param data associated data """ self.__items.append((txt, data)) self.setMaximum(len(self.__items) - 1) def itemData(self, index): """ Public method to retrieve the data associated with an item. @param index index of the item (integer) @return associated data """ try: return self.__items[index][1] except IndexError: return None def currentIndex(self): """ Public method to retrieve the current index. @return current index (integer) """ return self.value() def textFromValue(self, value): """ Public method to convert a value to text. @param value value to be converted (integer) @return text for the given value (string) """ try: return self.__items[value][0] except IndexError: return "" def valueFromText(self, txt): """ Public method to convert a text to a value. @param txt text to be converted (string) @return value for the given text (integer) """ for index in range(len(self.__items)): if self.__items[index][0] == txt: return index return self.minimum() eric-6.0.8/eric/E5Gui/E5ErrorMessage.py0000644000175000017500000001514312520643724016536 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a specialized error message dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import qInstallMessageHandler, QCoreApplication, \ QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QThread, \ QMetaObject, Qt, Q_ARG, QSettings from PyQt5.QtWidgets import QErrorMessage, qApp, QDialog import Globals import Utilities __msgHandlerDialog = None __origMsgHandler = None class E5ErrorMessage(QErrorMessage): """ Class implementing a specialized error message dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5ErrorMessage, self).__init__(parent) self.settings = QSettings( QSettings.IniFormat, QSettings.UserScope, Globals.settingsNameOrganization, "eric6messagefilters") self.__defaultFilters = [ "QFont::", "QCocoaMenu::removeMenuItem", "QCocoaMenu::insertNative", ",type id:" ] def __filterMessage(self, message): """ Private method to filter messages. @param message message to be checked (string) @return flag indicating that the message should be filtered out (boolean) """ for filter in Globals.toList(self.settings.value( "MessageFilters", self.__defaultFilters)): if filter in message: return True return False def showMessage(self, message, msgType=""): """ Public method to show a message. @param message error message to be shown (string) @param msgType type of the error message (string) """ if not self.__filterMessage(message): if msgType: super(E5ErrorMessage, self).showMessage(message, msgType) else: super(E5ErrorMessage, self).showMessage(message) def editMessageFilters(self): """ Public method to edit the list of message filters. """ from .E5ErrorMessageFilterDialog import E5ErrorMessageFilterDialog dlg = E5ErrorMessageFilterDialog( self.settings.value("MessageFilters", self.__defaultFilters)) if dlg.exec_() == QDialog.Accepted: filters = dlg.getFilters() self.settings.setValue("MessageFilters", filters) def messageHandler(msgType, *args): """ Module function handling messages. @param msgType type of the message (integer, QtMsgType) @param args message handler arguments, for PyQt4 message to be shown (bytes), for PyQt5 context information (QMessageLogContext) and message to be shown (bytes) """ if len(args) == 2: context = args[0] message = args[1] else: message = args[0] if __msgHandlerDialog: try: if msgType == QtDebugMsg: messageType = QCoreApplication.translate( "E5ErrorMessage", "Debug Message:") elif msgType == QtWarningMsg: messageType = QCoreApplication.translate( "E5ErrorMessage", "Warning:") elif msgType == QtCriticalMsg: messageType = QCoreApplication.translate( "E5ErrorMessage", "Critical:") elif msgType == QtFatalMsg: messageType = QCoreApplication.translate( "E5ErrorMessage", "Fatal Error:") if isinstance(message, bytes): message = Utilities.decodeBytes(message) message = message.replace("\r\n", "
")\ .replace("\n", "
")\ .replace("\r", "
") if len(args) == 2: msg = "

{0}

{1}

File: {2}

" \ "

Line: {3}

Function: {4}

".format( messageType, Utilities.html_uencode(message), context.file, context.line, context.function) else: msg = "

{0}

{1}

".format( messageType, Utilities.html_uencode(message)) if QThread.currentThread() == qApp.thread(): __msgHandlerDialog.showMessage(msg) else: QMetaObject.invokeMethod( __msgHandlerDialog, "showMessage", Qt.QueuedConnection, Q_ARG(str, msg)) return except RuntimeError: pass elif __origMsgHandler: __origMsgHandler(msgType, message) return if msgType == QtDebugMsg: messageType = QCoreApplication.translate( "E5ErrorMessage", "Debug Message") elif msgType == QtWarningMsg: messageType = QCoreApplication.translate( "E5ErrorMessage", "Warning") elif msgType == QtCriticalMsg: messageType = QCoreApplication.translate( "E5ErrorMessage", "Critical") elif msgType == QtFatalMsg: messageType = QCoreApplication.translate( "E5ErrorMessage", "Fatal Error") if isinstance(message, bytes): message = message.decode() if len(args) == 2: print("{0}: {1} in {2} at line {3} ({4})".format( messageType, message, context.file, context.line, context.function)) else: print("{0}: {1}".format(messageType, message)) def qtHandler(): """ Module function to install an E5ErrorMessage dialog as the global message handler. @return reference to the message handler dialog (E5ErrorMessage) """ global __msgHandlerDialog, __origMsgHandler if __msgHandlerDialog is None: # Install an E5ErrorMessage dialog as the global message handler. __msgHandlerDialog = E5ErrorMessage() __origMsgHandler = qInstallMessageHandler(messageHandler) return __msgHandlerDialog def editMessageFilters(): """ Module function to edit the list of message filters. """ if __msgHandlerDialog: __msgHandlerDialog.editMessageFilters() else: print(QCoreApplication.translate( "E5ErrorMessage", "No message handler installed.")) def messageHandlerInstalled(): """ Module function to check, if a message handler was installed. @return flag indicating an installed message handler (boolean) """ return __msgHandlerDialog is not None eric-6.0.8/eric/E5Gui/E5MessageBox.py0000644000175000017500000002562112451233374016176 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing QMessageBox replacements and more convenience function. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QMessageBox, QApplication ############################################################################### ## Mappings to standard QMessageBox ## ############################################################################### # QMessageBox.Icon NoIcon = QMessageBox.NoIcon Critical = QMessageBox.Critical Information = QMessageBox.Information Question = QMessageBox.Question Warning = QMessageBox.Warning StandardButtons = QMessageBox.StandardButtons # QMessageBox.StandardButton Abort = QMessageBox.Abort Apply = QMessageBox.Apply Cancel = QMessageBox.Cancel Close = QMessageBox.Close Discard = QMessageBox.Discard Help = QMessageBox.Help Ignore = QMessageBox.Ignore No = QMessageBox.No NoToAll = QMessageBox.NoToAll Ok = QMessageBox.Ok Open = QMessageBox.Open Reset = QMessageBox.Reset RestoreDefaults = QMessageBox.RestoreDefaults Retry = QMessageBox.Retry Save = QMessageBox.Save SaveAll = QMessageBox.SaveAll Yes = QMessageBox.Yes YesToAll = QMessageBox.YesToAll NoButton = QMessageBox.NoButton # QMessageBox.ButtonRole AcceptRole = QMessageBox.AcceptRole ActionRole = QMessageBox.ActionRole ApplyRole = QMessageBox.ApplyRole DestructiveRole = QMessageBox.DestructiveRole InvalidRole = QMessageBox.InvalidRole HelpRole = QMessageBox.HelpRole NoRole = QMessageBox.NoRole RejectRole = QMessageBox.RejectRole ResetRole = QMessageBox.ResetRole YesRole = QMessageBox.YesRole ############################################################################### ## Replacement for the QMessageBox class ## ############################################################################### class E5MessageBox(QMessageBox): """ Class implementing a replacement for QMessageBox. """ def __init__(self, icon, title, text, modal=False, buttons=QMessageBox.StandardButtons(QMessageBox.NoButton), parent=None): """ Constructor @param icon type of icon to be shown (QMessageBox.Icon) @param title caption of the message box (string) @param text text to be shown by the message box (string) @keyparam modal flag indicating a modal dialog (boolean) @keyparam buttons set of standard buttons to generate (StandardButtons) @keyparam parent parent widget of the message box (QWidget) """ super(E5MessageBox, self).__init__(parent) self.setIcon(icon) if modal: if parent is not None: self.setWindowModality(Qt.WindowModal) else: self.setWindowModality(Qt.ApplicationModal) else: self.setWindowModality(Qt.NonModal) if title == "": self.setWindowTitle("{0}".format( QApplication.applicationName())) else: self.setWindowTitle("{0} - {1}".format( QApplication.applicationName(), title)) self.setText(text) self.setStandardButtons(buttons) ############################################################################### ## Replacements for QMessageBox static methods ## ############################################################################### def __messageBox(parent, title, text, icon, buttons=QMessageBox.Ok, defaultButton=QMessageBox.NoButton, textFormat=Qt.AutoText): """ Private module function to show a modal message box. @param parent parent widget of the message box (QWidget) @param title caption of the message box (string) @param text text to be shown by the message box (string) @param icon type of icon to be shown (QMessageBox.Icon) @param buttons flags indicating which buttons to show (QMessageBox.StandardButtons) @param defaultButton flag indicating the default button (QMessageBox.StandardButton) @param textFormat format of the text (Qt.TextFormat) @return button pressed by the user (QMessageBox.StandardButton) """ messageBox = QMessageBox(parent) messageBox.setIcon(icon) if parent is not None: messageBox.setWindowModality(Qt.WindowModal) if title == "": messageBox.setWindowTitle("{0}".format( QApplication.applicationName())) else: messageBox.setWindowTitle("{0} - {1}".format( QApplication.applicationName(), title)) messageBox.setTextFormat(textFormat) messageBox.setText(text) messageBox.setStandardButtons(buttons) messageBox.setDefaultButton(defaultButton) messageBox.exec_() clickedButton = messageBox.clickedButton() if clickedButton is None: return QMessageBox.NoButton else: return messageBox.standardButton(clickedButton) # the about functions are here for consistancy about = QMessageBox.about aboutQt = QMessageBox.aboutQt def critical(parent, title, text, buttons=QMessageBox.Ok, defaultButton=QMessageBox.NoButton): """ Function to show a modal critical message box. @param parent parent widget of the message box (QWidget) @param title caption of the message box (string) @param text text to be shown by the message box (string) @param buttons flags indicating which buttons to show (QMessageBox.StandardButtons) @param defaultButton flag indicating the default button (QMessageBox.StandardButton) @return button pressed by the user (QMessageBox.StandardButton) """ return __messageBox(parent, title, text, QMessageBox.Critical, buttons, defaultButton) def information(parent, title, text, buttons=QMessageBox.Ok, defaultButton=QMessageBox.NoButton): """ Function to show a modal information message box. @param parent parent widget of the message box (QWidget) @param title caption of the message box (string) @param text text to be shown by the message box (string) @param buttons flags indicating which buttons to show (QMessageBox.StandardButtons) @param defaultButton flag indicating the default button (QMessageBox.StandardButton) @return button pressed by the user (QMessageBox.StandardButton) """ return __messageBox(parent, title, text, QMessageBox.Information, buttons, defaultButton) def question(parent, title, text, buttons=QMessageBox.Ok, defaultButton=QMessageBox.NoButton): """ Function to show a modal question message box. @param parent parent widget of the message box (QWidget) @param title caption of the message box (string) @param text text to be shown by the message box (string) @param buttons flags indicating which buttons to show (QMessageBox.StandardButtons) @param defaultButton flag indicating the default button (QMessageBox.StandardButton) @return button pressed by the user (QMessageBox.StandardButton) """ return __messageBox(parent, title, text, QMessageBox.Question, buttons, defaultButton) def warning(parent, title, text, buttons=QMessageBox.Ok, defaultButton=QMessageBox.NoButton): """ Function to show a modal warning message box. @param parent parent widget of the message box (QWidget) @param title caption of the message box (string) @param text text to be shown by the message box (string) @param buttons flags indicating which buttons to show (QMessageBox.StandardButtons) @param defaultButton flag indicating the default button (QMessageBox.StandardButton) @return button pressed by the user (QMessageBox.StandardButton) """ return __messageBox(parent, title, text, QMessageBox.Warning, buttons, defaultButton) ############################################################################### ## Additional convenience functions ## ############################################################################### def yesNo(parent, title, text, icon=Question, yesDefault=False, textFormat=Qt.AutoText): """ Function to show a model yes/no message box. @param parent parent widget of the message box (QWidget) @param title caption of the message box (string) @param text text to be shown by the message box (string) @keyparam icon icon for the dialog (Critical, Information, Question or Warning) @keyparam yesDefault flag indicating that the Yes button should be the default button (boolean) @param textFormat format of the text (Qt.TextFormat) @return flag indicating the selection of the Yes button (boolean) """ assert icon in [Critical, Information, Question, Warning] res = __messageBox( parent, title, text, icon, QMessageBox.StandardButtons(QMessageBox.Yes | QMessageBox.No), yesDefault and QMessageBox.Yes or QMessageBox.No, textFormat) return res == QMessageBox.Yes def retryAbort(parent, title, text, icon=Question, textFormat=Qt.AutoText): """ Function to show a model abort/retry message box. @param parent parent widget of the message box (QWidget) @param title caption of the message box (string) @param text text to be shown by the message box (string) @keyparam icon icon for the dialog (Critical, Information, Question or Warning) @param textFormat format of the text (Qt.TextFormat) @return flag indicating the selection of the Retry button (boolean) """ assert icon in [Critical, Information, Question, Warning] res = __messageBox( parent, title, text, icon, QMessageBox.StandardButtons(QMessageBox.Retry | QMessageBox.Abort), QMessageBox.Retry, textFormat) return res == QMessageBox.Retry def okToClearData(parent, title, text, saveFunc, textFormat=Qt.AutoText): """ Function to show a model message box to ask for clearing the data. @param parent parent widget of the message box (QWidget) @param title caption of the message box (string) @param text text to be shown by the message box (string) @param saveFunc reference to a function performing the save action. It must be a parameterless function returning a flag indicating success. @param textFormat format of the text (Qt.TextFormat) @return flag indicating that it is ok to clear the data (boolean) """ res = __messageBox( parent, title, text, QMessageBox.Warning, QMessageBox.StandardButtons( QMessageBox.Abort | QMessageBox.Discard | QMessageBox.Save), QMessageBox.Save, textFormat) if res == QMessageBox.Abort: return False if res == QMessageBox.Save: return saveFunc() return True eric-6.0.8/eric/E5Gui/E5ModelMenu.py0000644000175000017500000003212312451233374016021 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a menu populated from a QAbstractItemModel. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, qVersion, Qt, QModelIndex, QPoint from PyQt5.QtGui import QFontMetrics, QDrag, QPixmap from PyQt5.QtWidgets import QMenu, QAction, QApplication import UI.PixmapCache class E5ModelMenu(QMenu): """ Class implementing a menu populated from a QAbstractItemModel. @signal activated(QModelIndex) emitted when an action has been triggered """ activated = pyqtSignal(QModelIndex) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5ModelMenu, self).__init__(parent) self.__maxRows = -1 self.__firstSeparator = -1 self.__maxWidth = -1 self.__statusBarTextRole = 0 self.__separatorRole = 0 self.__model = None self.__root = QModelIndex() self.__dragStartPosition = QPoint() self.setAcceptDrops(True) self._mouseButton = Qt.NoButton self._keyboardModifiers = Qt.KeyboardModifiers(Qt.NoModifier) self.__dropRow = -1 self.__dropIndex = None self.aboutToShow.connect(self.__aboutToShow) self.triggered.connect(self.__actionTriggered) def prePopulated(self): """ Public method to add any actions before the tree. @return flag indicating if any actions were added """ return False def postPopulated(self): """ Public method to add any actions after the tree. """ pass def setModel(self, model): """ Public method to set the model for the menu. @param model reference to the model (QAbstractItemModel) """ self.__model = model def model(self): """ Public method to get a reference to the model. @return reference to the model (QAbstractItemModel) """ return self.__model def setMaxRows(self, rows): """ Public method to set the maximum number of entries to show. @param rows maximum number of entries to show (integer) """ self.__maxRows = rows def maxRows(self): """ Public method to get the maximum number of entries to show. @return maximum number of entries to show (integer) """ return self.__maxRows def setFirstSeparator(self, offset): """ Public method to set the first separator. @param offset row number of the first separator (integer) """ self.__firstSeparator = offset def firstSeparator(self): """ Public method to get the first separator. @return row number of the first separator (integer) """ return self.__firstSeparator def setRootIndex(self, index): """ Public method to set the index of the root item. @param index index of the root item (QModelIndex) """ self.__root = index def rootIndex(self): """ Public method to get the index of the root item. @return index of the root item (QModelIndex) """ return self.__root def setStatusBarTextRole(self, role): """ Public method to set the role of the status bar text. @param role role of the status bar text (integer) """ self.__statusBarTextRole = role def statusBarTextRole(self): """ Public method to get the role of the status bar text. @return role of the status bar text (integer) """ return self.__statusBarTextRole def setSeparatorRole(self, role): """ Public method to set the role of the separator. @param role role of the separator (integer) """ self.__separatorRole = role def separatorRole(self): """ Public method to get the role of the separator. @return role of the separator (integer) """ return self.__separatorRole def __aboutToShow(self): """ Private slot to show the menu. """ self.clear() if self.prePopulated(): self.addSeparator() max_ = self.__maxRows if max_ != -1: max_ += self.__firstSeparator self.createMenu(self.__root, max_, self, self) self.postPopulated() def createBaseMenu(self): """ Public method to get the menu that is used to populate sub menu's. @return reference to the menu (E5ModelMenu) """ return E5ModelMenu(self) def createMenu(self, parent, max_, parentMenu=None, menu=None): """ Public method to put all the children of a parent into a menu of a given length. @param parent index of the parent item (QModelIndex) @param max_ maximum number of entries (integer) @param parentMenu reference to the parent menu (QMenu) @param menu reference to the menu to be populated (QMenu) """ if menu is None: v = parent title = parent.data() modelMenu = self.createBaseMenu() # triggered goes all the way up the menu structure modelMenu.triggered.disconnect(modelMenu.__actionTriggered) modelMenu.setTitle(title) icon = parent.data(Qt.DecorationRole) if icon == NotImplemented or icon is None: icon = UI.PixmapCache.getIcon("defaultIcon.png") modelMenu.setIcon(icon) if parentMenu is not None: parentMenu.addMenu(modelMenu).setData(v) modelMenu.setRootIndex(parent) modelMenu.setModel(self.__model) return if self.__model is None: return end = self.__model.rowCount(parent) if max_ != -1: end = min(max_, end) for i in range(end): idx = self.__model.index(i, 0, parent) if self.__model.hasChildren(idx): self.createMenu(idx, -1, menu) else: if self.__separatorRole != 0 and \ idx.data(self.__separatorRole): self.addSeparator() else: menu.addAction(self.__makeAction(idx)) if menu == self and i == self.__firstSeparator - 1: self.addSeparator() def __makeAction(self, idx): """ Private method to create an action. @param idx index of the item to create an action for (QModelIndex) @return reference to the created action (QAction) """ icon = idx.data(Qt.DecorationRole) if icon == NotImplemented or icon is None: icon = UI.PixmapCache.getIcon("defaultIcon.png") action = self.makeAction(icon, idx.data(), self) action.setStatusTip(idx.data(self.__statusBarTextRole)) v = idx action.setData(v) return action def makeAction(self, icon, text, parent): """ Public method to create an action. @param icon icon of the action (QIcon) @param text text of the action (string) @param parent reference to the parent object (QObject) @return reference to the created action (QAction) """ fm = QFontMetrics(self.font()) if self.__maxWidth == -1: self.__maxWidth = fm.width('m') * 30 smallText = fm.elidedText(text, Qt.ElideMiddle, self.__maxWidth) return QAction(icon, smallText, parent) def __actionTriggered(self, action): """ Private slot to handle the triggering of an action. @param action reference to the action that was triggered (QAction) """ idx = self.index(action) if idx.isValid(): self.activated[QModelIndex].emit(idx) def index(self, action): """ Public method to get the index of an action. @param action reference to the action to get the index for (QAction) @return index of the action (QModelIndex) """ if action is None: return QModelIndex() idx = action.data() if idx is None: return QModelIndex() if not isinstance(idx, QModelIndex): return QModelIndex() return idx def dragEnterEvent(self, evt): """ Protected method to handle drag enter events. @param evt reference to the event (QDragEnterEvent) """ if self.__model is not None: mimeTypes = self.__model.mimeTypes() for mimeType in mimeTypes: if evt.mimeData().hasFormat(mimeType): evt.acceptProposedAction() super(E5ModelMenu, self).dragEnterEvent(evt) def dropEvent(self, evt): """ Protected method to handle drop events. @param evt reference to the event (QDropEvent) """ if self.__model is not None: act = self.actionAt(evt.pos()) parentIndex = self.__root if act is None: row = self.__model.rowCount(self.__root) else: idx = self.index(act) if not idx.isValid(): super(E5ModelMenu, self).dropEvent(evt) return row = idx.row() if self.__model.hasChildren(idx): parentIndex = idx row = self.__model.rowCount(idx) self.__dropRow = row self.__dropIndex = parentIndex evt.acceptProposedAction() self.__model.dropMimeData(evt.mimeData(), evt.dropAction(), row, 0, parentIndex) self.close() super(E5ModelMenu, self).dropEvent(evt) def mousePressEvent(self, evt): """ Protected method handling mouse press events. @param evt reference to the event object (QMouseEvent) """ if evt.button() == Qt.LeftButton: self.__dragStartPosition = evt.pos() super(E5ModelMenu, self).mousePressEvent(evt) def mouseMoveEvent(self, evt): """ Protected method to handle mouse move events. @param evt reference to the event (QMouseEvent) """ if self.__model is None: super(E5ModelMenu, self).mouseMoveEvent(evt) return if not (evt.buttons() & Qt.LeftButton): super(E5ModelMenu, self).mouseMoveEvent(evt) return manhattanLength = (evt.pos() - self.__dragStartPosition).manhattanLength() if manhattanLength <= QApplication.startDragDistance(): super(E5ModelMenu, self).mouseMoveEvent(evt) return act = self.actionAt(self.__dragStartPosition) if act is None: super(E5ModelMenu, self).mouseMoveEvent(evt) return idx = self.index(act) if not idx.isValid(): super(E5ModelMenu, self).mouseMoveEvent(evt) return drag = QDrag(self) drag.setMimeData(self.__model.mimeData([idx])) actionRect = self.actionGeometry(act) if qVersion() >= "5.0.0": drag.setPixmap(self.grab(actionRect)) else: drag.setPixmap(QPixmap.grabWidget(self, actionRect)) if drag.exec_() == Qt.MoveAction: row = idx.row() if self.__dropIndex == idx.parent() and self.__dropRow <= row: row += 1 self.__model.removeRow(row, self.__root) if not self.isAncestorOf(drag.target()): self.close() else: self.aboutToShow.emit() def mouseReleaseEvent(self, evt): """ Protected method handling mouse release events. @param evt reference to the event object (QMouseEvent) """ self._mouseButton = evt.button() self._keyboardModifiers = evt.modifiers() super(E5ModelMenu, self).mouseReleaseEvent(evt) def resetFlags(self): """ Public method to reset the saved internal state. """ self._mouseButton = Qt.NoButton self._keyboardModifiers = Qt.KeyboardModifiers(Qt.NoModifier) def removeEntry(self, idx): """ Public method to remove a menu entry. @param idx index of the entry to be removed (QModelIndex) """ row = idx.row() self.__model.removeRow(row, self.__root) self.aboutToShow.emit() eric-6.0.8/eric/E5Gui/E5ToolBarDialog.ui0000644000175000017500000001522612060166052016602 0ustar piotrpiotr E5ToolBarDialog 0 0 600 500 Configure Toolbars true &Toolbar: toolbarComboBox 0 0 Select the toolbar to configure Press to create a new toolbar &New Press to remove the selected toolbar &Remove Press to rename the selected toolbar R&ename Qt::Horizontal Actions: Current Toolbar Actions: Select the action to add to the current toolbar true false Qt::Vertical 20 40 Select the action to work on <b>Current Toolbar Actions</b><p>This list shows the actions of the selected toolbar. Select an action and use the up or down button to change the order of actions or the left button to delete it. To add an action to the toolbar, select it in the list of available actions and press the right button.</p> 0 Press to move the selected action up. Press to delete the selected action from the toolbar Press to add the selected action to the toolbar Press to move the selected action down. Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset|QDialogButtonBox::RestoreDefaults toolbarComboBox newButton removeButton renameButton actionsTree toolbarActionsList upButton downButton rightButton leftButton buttonBox eric-6.0.8/eric/E5Gui/E5ListView.py0000644000175000017500000000351512451233374015705 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing specialized list views. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QItemSelectionModel from PyQt5.QtWidgets import QListView class E5ListView(QListView): """ Class implementing a list view supporting removal of entries. """ def keyPressEvent(self, evt): """ Protected method implementing special key handling. @param evt reference to the event (QKeyEvent) """ if evt.key() in [Qt.Key_Delete, Qt.Key_Backspace] and \ self.model() is not None: self.removeSelected() evt.setAccepted(True) else: super(E5ListView, self).keyPressEvent(evt) def removeSelected(self): """ Public method to remove the selected entries. """ if self.model() is None or self.selectionModel() is None: # no models available return row = 0 selectedRows = self.selectionModel().selectedRows() for selectedRow in reversed(selectedRows): row = selectedRow.row() self.model().removeRow(row, self.rootIndex()) idx = self.model().index(row, 0, self.rootIndex()) if not idx.isValid(): idx = self.model().index(row - 1, 0, self.rootIndex()) self.selectionModel().select( idx, QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows) self.setCurrentIndex(idx) def removeAll(self): """ Public method to clear the view. """ if self.model() is not None: self.model().removeRows(0, self.model().rowCount(self.rootIndex()), self.rootIndex()) eric-6.0.8/eric/E5Gui/E5MainWindow.py0000644000175000017500000000410612451233374016210 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a main window class with styling support. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QMainWindow, QStyleFactory, QApplication from .E5Application import e5App from . import E5MessageBox class E5MainWindow(QMainWindow): """ Class implementing a main window with styling support. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5MainWindow, self).__init__(parent) self.defaultStyleName = QApplication.style().objectName() def setStyle(self, styleName, styleSheetFile): """ Public method to set the style of the interface. @param styleName name of the style to set (string) @param styleSheetFile name of a style sheet file to read to overwrite defaults of the given style (string) """ # step 1: set the style style = None if styleName != "System" and styleName in QStyleFactory.keys(): style = QStyleFactory.create(styleName) if style is None: style = QStyleFactory.create(self.defaultStyleName) if style is not None: QApplication.setStyle(style) # step 2: set a style sheet if styleSheetFile: try: f = open(styleSheetFile, "r", encoding="utf-8") styleSheet = f.read() f.close() except (IOError, OSError) as msg: E5MessageBox.warning( self, self.tr("Loading Style Sheet"), self.tr( """

The Qt Style Sheet file {0} could""" """ not be read.
Reason: {1}

""") .format(styleSheetFile, str(msg))) return else: styleSheet = "" e5App().setStyleSheet(styleSheet) eric-6.0.8/eric/E5Gui/E5TreeView.py0000644000175000017500000000303012451233374015661 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing specialized tree views. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QTreeView class E5TreeView(QTreeView): """ Class implementing a tree view supporting removal of entries. """ def keyPressEvent(self, evt): """ Protected method implementing special key handling. @param evt reference to the event (QKeyEvent) """ if evt.key() in [Qt.Key_Delete, Qt.Key_Backspace] and \ self.model() is not None: self.removeSelected() evt.setAccepted(True) else: super(E5TreeView, self).keyPressEvent(evt) def removeSelected(self): """ Public method to remove the selected entries. """ if self.model() is None or \ self.selectionModel() is None or \ not self.selectionModel().hasSelection(): # no models available or nothing selected return selectedRows = self.selectionModel().selectedRows() for idx in reversed(sorted(selectedRows)): self.model().removeRow(idx.row(), idx.parent()) def removeAll(self): """ Public method to clear the view. """ if self.model() is not None: self.model().removeRows(0, self.model().rowCount(self.rootIndex()), self.rootIndex()) eric-6.0.8/eric/E5Gui/E5PasswordMeter.py0000644000175000017500000000552612451233374016742 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing a custom widget indicating the strength of a password. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QProgressBar from Utilities.PasswordChecker import PasswordChecker class E5PasswordMeter(QProgressBar): """ Class implementing a custom widget indicating the strength of a password. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5PasswordMeter, self).__init__(parent) super(E5PasswordMeter, self).setTextVisible(False) super(E5PasswordMeter, self).setMaximum(100) self.__increment = 100 // (PasswordChecker.Complexity_VeryStrong + 1) self.__indicatorColors = [ "#ff0000", # red "#ff8800", # orange "#ffff00", # yellow "#ccff00", # yellow green "#00ff00", # green ] self.__noIndicator = "#ffffff" self.__styleSheetTemplate = \ "QProgressBar {{"\ " border: 2px solid black;" \ " border-radius: 5px;" \ " text-align: center; }}" \ "QProgressBar::chunk:horizontal {{" \ " background-color: {0}; }}" self.setStyleSheet( self.__styleSheetTemplate.format(self.__noIndicator)) def checkPasswordStrength(self, password): """ Public slot to check the password strength and update the progress bar accordingly. @param password password to be checked (string) """ strength = PasswordChecker().checkPassword(password) self.setStyleSheet(self.__styleSheetTemplate.format( self.__indicatorColors[strength])) super(E5PasswordMeter, self).setValue( (strength + 1) * self.__increment) def setValue(self, value): """ Public method to set the value. Overwritten to do nothing. @param value value (integer) """ pass def setMaximum(self, value): """ Public method to set the maximum value. Overwritten to do nothing. @param value maximum value (integer) """ pass def setMinimum(self, value): """ Public method to set the minimal value. Overwritten to do nothing. @param value minimum value (integer) """ pass if __name__ == "__main__": import sys from PyQt5.QtWidgets import QApplication app = QApplication(sys.argv) meter = E5PasswordMeter() meter.show() meter.checkPasswordStrength("Blah2+") app.exec_() eric-6.0.8/eric/E5Gui/E5ModelToolBar.py0000644000175000017500000002217712451233374016467 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a tool bar populated from a QAbstractItemModel. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, qVersion, Qt, QModelIndex, QPoint, QEvent from PyQt5.QtGui import QDrag, QPixmap, QIcon from PyQt5.QtWidgets import QApplication, QToolBar, QToolButton class E5ModelToolBar(QToolBar): """ Class implementing a tool bar populated from a QAbstractItemModel. @signal activated(QModelIndex) emitted when an action has been triggered """ activated = pyqtSignal(QModelIndex) def __init__(self, title=None, parent=None): """ Constructor @param title title for the tool bar (string) @param parent reference to the parent widget (QWidget) """ if title is not None: super(E5ModelToolBar, self).__init__(title, parent) else: super(E5ModelToolBar, self).__init__(parent) self.__model = None self.__root = QModelIndex() self.__dragStartPosition = QPoint() if self.isVisible(): self._build() self.setAcceptDrops(True) self._mouseButton = Qt.NoButton self._keyboardModifiers = Qt.KeyboardModifiers(Qt.NoModifier) self.__dropRow = -1 self.__dropIndex = None def setModel(self, model): """ Public method to set the model for the tool bar. @param model reference to the model (QAbstractItemModel) """ if self.__model is not None: self.__model.modelReset.disconnect(self._build) self.__model.rowsInserted[QModelIndex, int, int].disconnect( self._build) self.__model.rowsRemoved[QModelIndex, int, int].disconnect( self._build) self.__model.dataChanged.disconnect( self._build) self.__model = model if self.__model is not None: self.__model.modelReset.connect(self._build) self.__model.rowsInserted[QModelIndex, int, int].connect( self._build) self.__model.rowsRemoved[QModelIndex, int, int].connect( self._build) self.__model.dataChanged.connect( self._build) def model(self): """ Public method to get a reference to the model. @return reference to the model (QAbstractItemModel) """ return self.__model def setRootIndex(self, idx): """ Public method to set the root index. @param idx index to be set as the root index (QModelIndex) """ self.__root = idx def rootIndex(self): """ Public method to get the root index. @return root index (QModelIndex) """ return self.__root def _build(self): """ Protected slot to build the tool bar. """ assert self.__model is not None self.clear() for i in range(self.__model.rowCount(self.__root)): idx = self.__model.index(i, 0, self.__root) title = idx.data(Qt.DisplayRole) icon = idx.data(Qt.DecorationRole) if icon == NotImplemented or icon is None: icon = QIcon() folder = self.__model.hasChildren(idx) act = self.addAction(icon, title) act.setData(idx) button = self.widgetForAction(act) button.installEventFilter(self) if folder: menu = self._createMenu() menu.setModel(self.__model) menu.setRootIndex(idx) act.setMenu(menu) button.setPopupMode(QToolButton.InstantPopup) button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) def index(self, action): """ Public method to get the index of an action. @param action reference to the action to get the index for (QAction) @return index of the action (QModelIndex) """ if action is None: return QModelIndex() idx = action.data() if idx is None: return QModelIndex() if not isinstance(idx, QModelIndex): return QModelIndex() return idx def _createMenu(self): """ Protected method to create the menu for a tool bar action. @return menu for a tool bar action (E5ModelMenu) """ from .E5ModelMenu import E5ModelMenu return E5ModelMenu(self) def eventFilter(self, obj, evt): """ Public method to handle event for other objects. @param obj reference to the object (QObject) @param evt reference to the event (QEvent) @return flag indicating that the event should be filtered out (boolean) """ if evt.type() == QEvent.MouseButtonRelease: self._mouseButton = evt.button() self._keyboardModifiers = evt.modifiers() act = obj.defaultAction() idx = self.index(act) if idx.isValid(): self.activated[QModelIndex].emit(idx) elif evt.type() == QEvent.MouseButtonPress: if evt.buttons() & Qt.LeftButton: self.__dragStartPosition = self.mapFromGlobal(evt.globalPos()) return False def dragEnterEvent(self, evt): """ Protected method to handle drag enter events. @param evt reference to the event (QDragEnterEvent) """ if self.__model is not None: mimeTypes = self.__model.mimeTypes() for mimeType in mimeTypes: if evt.mimeData().hasFormat(mimeType): evt.acceptProposedAction() super(E5ModelToolBar, self).dragEnterEvent(evt) def dropEvent(self, evt): """ Protected method to handle drop events. @param evt reference to the event (QDropEvent) """ if self.__model is not None: act = self.actionAt(evt.pos()) parentIndex = self.__root if act is None: row = self.__model.rowCount(self.__root) else: idx = self.index(act) assert idx.isValid() row = idx.row() if self.__model.hasChildren(idx): parentIndex = idx row = self.__model.rowCount(idx) self.__dropRow = row self.__dropIndex = parentIndex evt.acceptProposedAction() self.__model.dropMimeData(evt.mimeData(), evt.dropAction(), row, 0, parentIndex) super(E5ModelToolBar, self).dropEvent(evt) def mouseMoveEvent(self, evt): """ Protected method to handle mouse move events. @param evt reference to the event (QMouseEvent) """ if self.__model is None: super(E5ModelToolBar, self).mouseMoveEvent(evt) return if not (evt.buttons() & Qt.LeftButton): super(E5ModelToolBar, self).mouseMoveEvent(evt) return manhattanLength = (evt.pos() - self.__dragStartPosition).manhattanLength() if manhattanLength <= QApplication.startDragDistance(): super(E5ModelToolBar, self).mouseMoveEvent(evt) return act = self.actionAt(self.__dragStartPosition) if act is None: super(E5ModelToolBar, self).mouseMoveEvent(evt) return idx = self.index(act) assert idx.isValid() drag = QDrag(self) drag.setMimeData(self.__model.mimeData([idx])) actionRect = self.actionGeometry(act) if qVersion() >= "5.0.0": drag.setPixmap(self.grab(actionRect)) else: drag.setPixmap(QPixmap.grabWidget(self, actionRect)) if drag.exec_() == Qt.MoveAction: row = idx.row() if self.__dropIndex == idx.parent() and self.__dropRow <= row: row += 1 self.__model.removeRow(row, self.__root) def hideEvent(self, evt): """ Protected method to handle hide events. @param evt reference to the hide event (QHideEvent) """ self.clear() super(E5ModelToolBar, self).hideEvent(evt) def showEvent(self, evt): """ Protected method to handle show events. @param evt reference to the hide event (QHideEvent) """ if len(self.actions()) == 0: self._build() super(E5ModelToolBar, self).showEvent(evt) def resetFlags(self): """ Public method to reset the saved internal state. """ self._mouseButton = Qt.NoButton self._keyboardModifiers = Qt.KeyboardModifiers(Qt.NoModifier) eric-6.0.8/eric/E5Gui/E5TreeWidget.py0000644000175000017500000002175112451233374016204 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing specialized tree views. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView class E5TreeWidget(QTreeWidget): """ Class implementing an extended tree widget. @signal itemControlClicked(QTreeWidgetItem) emitted after a Ctrl-Click on an item @signal itemMiddleButtonClicked(QTreeWidgetItem) emitted after a click of the middle button on an item """ ItemsCollapsed = 0 ItemsExpanded = 1 itemControlClicked = pyqtSignal(QTreeWidgetItem) itemMiddleButtonClicked = pyqtSignal(QTreeWidgetItem) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5TreeWidget, self).__init__(parent) self.__refreshAllItemsNeeded = True self.__allTreeItems = [] self.__showMode = E5TreeWidget.ItemsCollapsed self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.itemChanged.connect(self.__scheduleRefresh) def setDefaultItemShowMode(self, mode): """ Public method to set the default item show mode. @param mode default mode (ItemsCollapsed, ItemsExpanded) """ assert mode in [E5TreeWidget.ItemsCollapsed, E5TreeWidget.ItemsExpanded] self.__showMode = mode def allItems(self): """ Public method to get a list of all items. @return list of all items (list of QTreeWidgetItem) """ if self.__refreshAllItemsNeeded: self.__allTreeItems = [] self.__iterateAllItems(None) self.__refreshAllItemsNeeded = False return self.__allTreeItems def appendToParentItem(self, parent, item): """ Public method to append an item to a parent item. @param parent text of the parent item (string) or the parent item (QTreeWidgetItem) @param item item to be appended (QTreeWidgetItem) @return flag indicating success (boolean) @exception RuntimeError raised to indicate an illegal type for the parent """ if isinstance(parent, QTreeWidgetItem): if parent is None or parent.treeWidget() != self: return False parentItem = parent elif isinstance(parent, str): lst = self.findItems(parent, Qt.MatchExactly) if not lst: return False parentItem = lst[0] if parentItem is None: return False else: raise RuntimeError("illegal type for parent") self.__allTreeItems.append(item) parentItem.addChild(item) return True def prependToParentItem(self, parent, item): """ Public method to prepend an item to a parent item. @param parent text of the parent item (string) or the parent item (QTreeWidgetItem) @param item item to be prepended (QTreeWidgetItem) @return flag indicating success (boolean) @exception RuntimeError raised to indicate an illegal type for the parent """ if isinstance(parent, QTreeWidgetItem): if parent is None or parent.treeWidget() != self: return False parentItem = parent elif isinstance(parent, str): lst = self.findItems(parent, Qt.MatchExactly) if not lst: return False parentItem = lst[0] if parentItem is None: return False else: raise RuntimeError("illegal type for parent") self.__allTreeItems.append(item) parentItem.insertChild(0, item) return True def addTopLevelItem(self, item): """ Public method to add a top level item. @param item item to be added as a top level item (QTreeWidgetItem) """ self.__allTreeItems.append(item) super(E5TreeWidget, self).addTopLevelItem(item) def addTopLevelItems(self, items): """ Public method to add a list of top level items. @param items items to be added as top level items (list of QTreeWidgetItem) """ self.__allTreeItems.extend(items) super(E5TreeWidget, self).addTopLevelItems(items) def insertTopLevelItem(self, index, item): """ Public method to insert a top level item. @param index index for the insertion (integer) @param item item to be inserted as a top level item (QTreeWidgetItem) """ self.__allTreeItems.append(item) super(E5TreeWidget, self).insertTopLevelItem(index, item) def insertTopLevelItems(self, index, items): """ Public method to insert a list of top level items. @param index index for the insertion (integer) @param items items to be inserted as top level items (list of QTreeWidgetItem) """ self.__allTreeItems.extend(items) super(E5TreeWidget, self).insertTopLevelItems(index, items) def deleteItem(self, item): """ Public method to delete an item. @param item item to be deleted (QTreeWidgetItem) """ if item in self.__allTreeItems: self.__allTreeItems.remove(item) self.__refreshAllItemsNeeded = True del item def deleteItems(self, items): """ Public method to delete a list of items. @param items items to be deleted (list of QTreeWidgetItem) """ for item in items: self.deleteItem(item) def filterString(self, filter): """ Public slot to set a new filter. @param filter filter to be set (string) """ self.expandAll() allItems = self.allItems() if filter: lFilter = filter.lower() for itm in allItems: itm.setHidden(lFilter not in itm.text(0).lower()) itm.setExpanded(True) for index in range(self.topLevelItemCount()): self.topLevelItem(index).setHidden(False) firstItm = self.topLevelItem(0) belowItm = self.itemBelow(firstItm) topLvlIndex = 0 while firstItm: if lFilter in firstItm.text(0).lower(): firstItm.setHidden(False) elif not firstItm.parent() and not belowItm: firstItm.setHidden(True) elif not belowItm: break elif not firstItm.parent() and not belowItm.parent(): firstItm.setHidden(True) topLvlIndex += 1 firstItm = self.topLevelItem(topLvlIndex) belowItm = self.itemBelow(firstItm) else: for itm in allItems: itm.setHidden(False) for index in range(self.topLevelItemCount()): self.topLevelItem(index).setHidden(False) if self.__showMode == E5TreeWidget.ItemsCollapsed: self.collapseAll() def clear(self): """ Public slot to clear the tree. """ self.__allTreeItems = [] super(E5TreeWidget, self).clear() def __scheduleRefresh(self): """ Private slot to schedule a refresh of the tree. """ self.__refreshAllItemsNeeded = True def mousePressEvent(self, evt): """ Protected method handling mouse press events. @param evt mouse press event (QMouseEvent) """ if evt.modifiers() == Qt.ControlModifier and \ evt.buttons() == Qt.LeftButton: self.itemControlClicked.emit(self.itemAt(evt.pos())) return elif evt.buttons() == Qt.MidButton: self.itemMiddleButtonClicked.emit(self.itemAt(evt.pos())) return else: super(E5TreeWidget, self).mousePressEvent(evt) def __iterateAllItems(self, parent): """ Private method to iterate over the child items of the parent. @param parent parent item to iterate (QTreeWidgetItem) """ if parent: count = parent.childCount() else: count = self.topLevelItemCount() for index in range(count): if parent: itm = parent.child(index) else: itm = self.topLevelItem(index) if itm.childCount() == 0: self.__allTreeItems.append(itm) self.__iterateAllItems(itm) eric-6.0.8/eric/E5Gui/E5ErrorMessageFilterDialog.ui0000644000175000017500000001232112155056252021002 0ustar piotrpiotr E5ErrorMessageFilterDialog 0 0 500 350 Error Messages Filter true 0 0 0 300 0 Enter search term for message Qt::Horizontal 40 20 Qt::Vertical 20 40 Press to add filter to the list &Add... false Qt::Horizontal Press to remove the selected entries &Remove false Press to remove all entries R&emove All false true QAbstractItemView::ExtendedSelection Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
E5ListView QListView
E5Gui/E5ListView.h
searchEdit filterList addButton removeButton removeAllButton buttonBox buttonBox accepted() E5ErrorMessageFilterDialog accept() 227 329 157 274 buttonBox rejected() E5ErrorMessageFilterDialog reject() 295 335 286 274
eric-6.0.8/eric/E5Gui/E5Application.py0000644000175000017500000001003712451233374016377 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Class implementing a specialized application class. """ from __future__ import unicode_literals from PyQt5.QtCore import QCoreApplication from PyQt5.QtWidgets import QApplication class E5Application(QApplication): """ Eric application class with an object registry. """ def __init__(self, argv): """ Constructor @param argv command line arguments """ super(E5Application, self).__init__(argv) self.__objectRegistry = {} self.__pluginObjectRegistry = {} def registerObject(self, name, object): """ Public method to register an object in the object registry. @param name name of the object (string) @param object reference to the object @exception KeyError raised when the given name is already in use """ if name in self.__objectRegistry: raise KeyError('Object "{0}" already registered.'.format(name)) else: self.__objectRegistry[name] = object def getObject(self, name): """ Public method to get a reference to a registered object. @param name name of the object (string) @return reference to the registered object @exception KeyError raised when the given name is not known """ if name in self.__objectRegistry: return self.__objectRegistry[name] else: raise KeyError('Object "{0}" is not registered.'.format(name)) def registerPluginObject(self, name, object, pluginType=None): """ Public method to register a plugin object in the object registry. @param name name of the plugin object (string) @param object reference to the plugin object @keyparam pluginType type of the plugin object (string) @exception KeyError raised when the given name is already in use """ if name in self.__pluginObjectRegistry: raise KeyError( 'Pluginobject "{0}" already registered.'.format(name)) else: self.__pluginObjectRegistry[name] = (object, pluginType) def unregisterPluginObject(self, name): """ Public method to unregister a plugin object in the object registry. @param name name of the plugin object (string) """ if name in self.__pluginObjectRegistry: del self.__pluginObjectRegistry[name] def getPluginObject(self, name): """ Public method to get a reference to a registered plugin object. @param name name of the plugin object (string) @return reference to the registered plugin object @exception KeyError raised when the given name is not known """ if name in self.__pluginObjectRegistry: return self.__pluginObjectRegistry[name][0] else: raise KeyError( 'Pluginobject "{0}" is not registered.'.format(name)) def getPluginObjects(self): """ Public method to get a list of (name, reference) pairs of all registered plugin objects. @return list of (name, reference) pairs """ objects = [] for name in self.__pluginObjectRegistry: objects.append((name, self.__pluginObjectRegistry[name][0])) return objects def getPluginObjectType(self, name): """ Public method to get the type of a registered plugin object. @param name name of the plugin object (string) @return type of the plugin object (string) @exception KeyError raised when the given name is not known """ if name in self.__pluginObjectRegistry: return self.__pluginObjectRegistry[name][1] else: raise KeyError( 'Pluginobject "{0}" is not registered.'.format(name)) e5App = QCoreApplication.instance eric-6.0.8/eric/E5Gui/E5TreeSortFilterProxyModel.py0000644000175000017500000000333112451233374021073 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a modified QSortFilterProxyModel. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QModelIndex, QSortFilterProxyModel class E5TreeSortFilterProxyModel(QSortFilterProxyModel): """ Class implementing a modified QSortFilterProxyModel. It always accepts the root nodes in the tree so filtering is only done on the children. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(E5TreeSortFilterProxyModel, self).__init__(parent) self.setFilterCaseSensitivity(Qt.CaseInsensitive) def filterAcceptsRow(self, sourceRow, sourceParent): """ Public method to determine, if the row is acceptable. @param sourceRow row number in the source model (integer) @param sourceParent index of the source item (QModelIndex) @return flag indicating acceptance (boolean) """ idx = self.sourceModel().index(sourceRow, 0, sourceParent) if self.sourceModel().hasChildren(idx): return True return QSortFilterProxyModel.filterAcceptsRow( self, sourceRow, sourceParent) def hasChildren(self, parent=QModelIndex()): """ Public method to check, if a parent node has some children. @param parent index of the parent node (QModelIndex) @return flag indicating the presence of children (boolean) """ sindex = self.mapToSource(parent) return self.sourceModel().hasChildren(sindex) eric-6.0.8/eric/E5Gui/E5Led.py0000644000175000017500000002271512451233374014646 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing a LED widget. It was inspired by KLed. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QSize, QPoint from PyQt5.QtGui import QColor, QRadialGradient, QPalette, QPainter, QBrush from PyQt5.QtWidgets import QWidget E5LedRectangular = 0 E5LedCircular = 1 class E5Led(QWidget): """ Class implementing a LED widget. """ def __init__(self, parent=None, color=None, shape=E5LedCircular, rectRatio=1): """ Constructor @param parent reference to parent widget (QWidget) @param color color of the LED (QColor) @param shape shape of the LED (E5LedCircular, E5LedRectangular) @param rectRatio ratio width to height, if shape is rectangular (float) """ super(E5Led, self).__init__(parent) if color is None: color = QColor("green") self.__led_on = True self.__dark_factor = 300 self.__offcolor = color.darker(self.__dark_factor) self.__led_color = color self.__framedLed = True self.__shape = shape self.__rectRatio = rectRatio self.setColor(color) def paintEvent(self, evt): """ Protected slot handling the paint event. @param evt paint event object (QPaintEvent) @exception TypeError The E5Led has an unsupported shape type. """ if self.__shape == E5LedCircular: self.__paintRound() elif self.__shape == E5LedRectangular: self.__paintRectangular() else: raise TypeError("Unsupported shape type for E5Led.") def __getBestRoundSize(self): """ Private method to calculate the width of the LED. @return new width of the LED (integer) """ width = min(self.width(), self.height()) width -= 2 # leave one pixel border return width > -1 and width or 0 def __paintRound(self): """ Private method to paint a round raised LED. """ # Initialize coordinates, width and height of the LED width = self.__getBestRoundSize() # Calculate the gradient for the LED wh = width / 2 color = self.__led_on and self.__led_color or self.__offcolor gradient = QRadialGradient(wh, wh, wh, 0.8 * wh, 0.8 * wh) gradient.setColorAt(0.0, color.lighter(200)) gradient.setColorAt(0.6, color) if self.__framedLed: gradient.setColorAt(0.9, color.darker()) gradient.setColorAt(1.0, self.palette().color(QPalette.Dark)) else: gradient.setColorAt(1.0, color.darker()) # now do the drawing paint = QPainter(self) paint.setRenderHint(QPainter.Antialiasing, True) paint.setBrush(QBrush(gradient)) paint.setPen(Qt.NoPen) paint.drawEllipse(1, 1, width, width) paint.end() def __paintRectangular(self): """ Private method to paint a rectangular raised LED. """ # Initialize coordinates, width and height of the LED width = self.height() * self.__rectRatio left = max(0, int((self.width() - width) / 2) - 1) right = min(int((self.width() + width) / 2), self.width()) height = self.height() # now do the drawing painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) color = self.__led_on and self.__led_color or self.__offcolor painter.setPen(color.lighter(200)) painter.drawLine(left, 0, left, height - 1) painter.drawLine(left + 1, 0, right - 1, 0) if self.__framedLed: painter.setPen(self.palette().color(QPalette.Dark)) else: painter.setPen(color.darker()) painter.drawLine(left + 1, height - 1, right - 1, height - 1) painter.drawLine(right - 1, 1, right - 1, height - 1) painter.fillRect(left + 1, 1, right - 2, height - 2, QBrush(color)) painter.end() def isOn(self): """ Public method to return the LED state. @return flag indicating the light state (boolean) """ return self.__led_on def shape(self): """ Public method to return the LED shape. @return LED shape (E5LedCircular, E5LedRectangular) """ return self.__shape def ratio(self): """ Public method to return the LED rectangular ratio [= width / height]. @return LED rectangular ratio (float) """ return self.__rectRatio def color(self): """ Public method to return the LED color. @return color of the LED (QColor) """ return self.__led_color def setOn(self, state): """ Public method to set the LED to on. @param state new state of the LED (boolean) """ if self.__led_on != state: self.__led_on = state self.update() def setShape(self, shape): """ Public method to set the LED shape. @param shape new LED shape (E5LedCircular, E5LedRectangular) """ if self.__shape != shape: self.__shape = shape self.update() def setRatio(self, ratio): """ Public method to set the LED rectangular ratio (width / height). @param ratio new LED rectangular ratio (float) """ if self.__rectRatio != ratio: self.__rectRatio = ratio self.update() def setColor(self, color): """ Public method to set the LED color. @param color color for the LED (QColor) """ if self.__led_color != color: self.__led_color = color self.__offcolor = color.darker(self.__dark_factor) self.update() def setDarkFactor(self, darkfactor): """ Public method to set the dark factor. @param darkfactor value to set for the dark factor (integer) """ if self.__dark_factor != darkfactor: self.__dark_factor = darkfactor self.__offcolor = self.__led_color.darker(darkfactor) self.update() def darkFactor(self): """ Public method to return the dark factor. @return the current dark factor (integer) """ return self.__dark_factor def toggle(self): """ Public slot to toggle the LED state. """ self.setOn(not self.__led_on) def on(self): """ Public slot to set the LED to on. """ self.setOn(True) def off(self): """ Public slot to set the LED to off. """ self.setOn(False) def setFramed(self, framed): """ Public slot to set the __framedLed attribute. @param framed flag indicating the framed state (boolean) """ if self.__framedLed != framed: self.__framedLed = framed self.__off_map = None self.__on_map = None self.update() def isFramed(self): """ Public method to return the framed state. @return flag indicating the current framed state (boolean) """ return self.__framedLed def sizeHint(self): """ Public method to give a hint about our desired size. @return size hint (QSize) """ return QSize(18, 18) def minimumSizeHint(self): """ Public method to give a hint about our minimum size. @return size hint (QSize) """ return QSize(18, 18) class E5ClickableLed(E5Led): """ Class implementing a clickable LED widget. @signal clicked(QPoint) emitted upon a click on the LED with the left button @signal middleClicked(QPoint) emitted upon a click on the LED with the middle button or CTRL and left button """ clicked = pyqtSignal(QPoint) middleClicked = pyqtSignal(QPoint) def __init__(self, parent=None, color=None, shape=E5LedCircular, rectRatio=1): """ Constructor @param parent reference to parent widget (QWidget) @param color color of the LED (QColor) @param shape shape of the LED (E5LedCircular, E5LedRectangular) @param rectRatio ratio width to height, if shape is rectangular (float) """ super(E5ClickableLed, self).__init__(parent, color, shape, rectRatio) def mouseReleaseEvent(self, evt): """ Protected method handling mouse release events. @param evt mouse event (QMouseEvent) """ if evt.button() == Qt.LeftButton and self.rect().contains(evt.pos()): if evt.modifiers() == Qt.ControlModifier: self.middleClicked.emit(evt.globalPos()) else: self.clicked.emit(evt.globalPos()) elif evt.button() == Qt.MidButton and \ self.rect().contains(evt.pos()): self.middleClicked.emit(evt.globalPos()) else: super(E5ClickableLed, self).mouseReleaseEvent(evt) eric-6.0.8/eric/E5Gui/E5FileDialog.py0000644000175000017500000002037612451233374016142 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing alternative functions for the QFileDialog static methods to cope with distributor's usage of KDE wrapper dialogs for Qt file dialogs. """ from __future__ import unicode_literals from PyQt5.QtCore import PYQT_VERSION_STR from PyQt5.QtWidgets import QFileDialog import Globals Options = QFileDialog.Options Option = QFileDialog.Option ShowDirsOnly = QFileDialog.ShowDirsOnly DontResolveSymlinks = QFileDialog.DontResolveSymlinks DontConfirmOverwrite = QFileDialog.DontConfirmOverwrite DontUseNativeDialog = QFileDialog.DontUseNativeDialog ReadOnly = QFileDialog.ReadOnly HideNameFilterDetails = QFileDialog.HideNameFilterDetails DontUseSheet = QFileDialog.DontUseSheet def __reorderFilter(filter, initialFilter=""): """ Private function to reorder the file filter to cope with a KDE issue introduced by distributor's usage of KDE file dialogs. @param filter Qt file filter (string) @param initialFilter initial filter (string) @return the rearranged Qt file filter (string) """ if initialFilter and not Globals.isMacPlatform(): fileFilters = filter.split(';;') if len(fileFilters) < 10 and initialFilter in fileFilters: fileFilters.remove(initialFilter) fileFilters.insert(0, initialFilter) return ";;".join(fileFilters) else: return filter def getOpenFileName(parent=None, caption="", directory="", filter="", options=QFileDialog.Options()): """ Module function to get the name of a file for opening it. @param parent parent widget of the dialog (QWidget) @param caption window title of the dialog (string) @param directory working directory of the dialog (string) @param filter filter string for the dialog (string) @param options various options for the dialog (QFileDialog.Options) @return name of file to be opened (string) """ if Globals.isLinuxPlatform(): options |= QFileDialog.DontUseNativeDialog if PYQT_VERSION_STR >= "5.0.0": return QFileDialog.getOpenFileName( parent, caption, directory, filter, "", options)[0] else: return QFileDialog.getOpenFileName( parent, caption, directory, filter, options) def getOpenFileNameAndFilter(parent=None, caption="", directory="", filter="", initialFilter="", options=QFileDialog.Options()): """ Module function to get the name of a file for opening it and the selected file name filter. @param parent parent widget of the dialog (QWidget) @param caption window title of the dialog (string) @param directory working directory of the dialog (string) @param filter filter string for the dialog (string) @param initialFilter initial filter for the dialog (string) @param options various options for the dialog (QFileDialog.Options) @return name of file to be opened and selected filter (string, string) """ if Globals.isLinuxPlatform(): options |= QFileDialog.DontUseNativeDialog newfilter = __reorderFilter(filter, initialFilter) if PYQT_VERSION_STR >= "5.0.0": return QFileDialog.getOpenFileName( parent, caption, directory, newfilter, initialFilter, options) else: return QFileDialog.getOpenFileNameAndFilter( parent, caption, directory, newfilter, initialFilter, options) def getOpenFileNames(parent=None, caption="", directory="", filter="", options=QFileDialog.Options()): """ Module function to get a list of names of files for opening. @param parent parent widget of the dialog (QWidget) @param caption window title of the dialog (string) @param directory working directory of the dialog (string) @param filter filter string for the dialog (string) @param options various options for the dialog (QFileDialog.Options) @return list of file names to be opened (list of string) """ if Globals.isLinuxPlatform(): options |= QFileDialog.DontUseNativeDialog if PYQT_VERSION_STR >= "5.0.0": return QFileDialog.getOpenFileNames( parent, caption, directory, filter, "", options)[0] else: return QFileDialog.getOpenFileNames( parent, caption, directory, filter, options) def getOpenFileNamesAndFilter(parent=None, caption="", directory="", filter="", initialFilter="", options=QFileDialog.Options()): """ Module function to get a list of names of files for opening and the selected file name filter. @param parent parent widget of the dialog (QWidget) @param caption window title of the dialog (string) @param directory working directory of the dialog (string) @param filter filter string for the dialog (string) @param initialFilter initial filter for the dialog (string) @param options various options for the dialog (QFileDialog.Options) @return list of file names to be opened and selected filter (list of string, string) """ if Globals.isLinuxPlatform(): options |= QFileDialog.DontUseNativeDialog newfilter = __reorderFilter(filter, initialFilter) if PYQT_VERSION_STR >= "5.0.0": return QFileDialog.getOpenFileNames( parent, caption, directory, newfilter, initialFilter, options) else: return QFileDialog.getOpenFileNamesAndFilter( parent, caption, directory, newfilter, initialFilter, options) def getSaveFileName(parent=None, caption="", directory="", filter="", options=QFileDialog.Options()): """ Module function to get the name of a file for saving it. @param parent parent widget of the dialog (QWidget) @param caption window title of the dialog (string) @param directory working directory of the dialog (string) @param filter filter string for the dialog (string) @param options various options for the dialog (QFileDialog.Options) @return name of file to be saved (string) """ if Globals.isLinuxPlatform(): options |= QFileDialog.DontUseNativeDialog if PYQT_VERSION_STR >= "5.0.0": return QFileDialog.getSaveFileName( parent, caption, directory, filter, "", options)[0] else: return QFileDialog.getSaveFileName( parent, caption, directory, filter, options) def getSaveFileNameAndFilter(parent=None, caption="", directory="", filter="", initialFilter="", options=QFileDialog.Options()): """ Module function to get the name of a file for saving it and the selected file name filter. @param parent parent widget of the dialog (QWidget) @param caption window title of the dialog (string) @param directory working directory of the dialog (string) @param filter filter string for the dialog (string) @param initialFilter initial filter for the dialog (string) @param options various options for the dialog (QFileDialog.Options) @return name of file to be saved and selected filter (string, string) """ if Globals.isLinuxPlatform(): options |= QFileDialog.DontUseNativeDialog newfilter = __reorderFilter(filter, initialFilter) if PYQT_VERSION_STR >= "5.0.0": return QFileDialog.getSaveFileName( parent, caption, directory, newfilter, initialFilter, options) else: return QFileDialog.getSaveFileNameAndFilter( parent, caption, directory, newfilter, initialFilter, options) def getExistingDirectory(parent=None, caption="", directory="", options=QFileDialog.ShowDirsOnly): """ Module function to get the name of a directory. @param parent parent widget of the dialog (QWidget) @param caption window title of the dialog (string) @param directory working directory of the dialog (string) @param options various options for the dialog (QFileDialog.Options) @return name of selected directory (string) """ if Globals.isLinuxPlatform(): options |= QFileDialog.DontUseNativeDialog return QFileDialog.getExistingDirectory(parent, caption, directory, options) eric-6.0.8/eric/E5Gui/E5LineEdit.py0000644000175000017500000002457212451233374015642 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing specialized line edits. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QEvent, qVersion from PyQt5.QtGui import QPainter, QPalette from PyQt5.QtWidgets import QLineEdit, QStyle, QWidget, QHBoxLayout, \ QBoxLayout, QLayout, QApplication, QSpacerItem, QSizePolicy if qVersion() >= "5.0.0": from PyQt5.QtWidgets import QStyleOptionFrame else: from PyQt5.QtWidgets import QStyleOptionFrameV2 as QStyleOptionFrame import UI.PixmapCache class E5LineEditSideWidget(QWidget): """ Class implementing the side widgets for the line edit class. """ sizeHintChanged = pyqtSignal() def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5LineEditSideWidget, self).__init__(parent) def event(self, evt): """ Public method to handle events. @param evt reference to the event (QEvent) @return flag indicating, whether the event was recognized (boolean) """ if evt.type() == QEvent.LayoutRequest: self.sizeHintChanged.emit() return QWidget.event(self, evt) class E5LineEdit(QLineEdit): """ Class implementing a line edit widget showing some inactive text. """ LeftSide = 0 RightSide = 1 def __init__(self, parent=None, inactiveText=""): """ Constructor @param parent reference to the parent widget (QWidget) @param inactiveText text to be shown on inactivity (string) """ super(E5LineEdit, self).__init__(parent) self.setMinimumHeight(22) if qVersion() < "4.7.0": self.__inactiveText = inactiveText else: self.setPlaceholderText(inactiveText) self.__mainLayout = QHBoxLayout(self) self.__mainLayout.setContentsMargins(0, 0, 0, 0) self.__mainLayout.setSpacing(0) self.__leftMargin = 0 self.__leftWidget = E5LineEditSideWidget(self) self.__leftWidget.resize(0, 0) self.__leftLayout = QHBoxLayout(self.__leftWidget) self.__leftLayout.setContentsMargins(0, 0, 2, 0) if QApplication.isRightToLeft(): self.__leftLayout.setDirection(QBoxLayout.RightToLeft) else: self.__leftLayout.setDirection(QBoxLayout.LeftToRight) self.__leftLayout.setSizeConstraint(QLayout.SetFixedSize) self.__rightWidget = E5LineEditSideWidget(self) self.__rightWidget.resize(0, 0) self.__rightLayout = QHBoxLayout(self.__rightWidget) self.__rightLayout.setContentsMargins(0, 0, 2, 0) if self.isRightToLeft(): self.__rightLayout.setDirection(QBoxLayout.RightToLeft) else: self.__rightLayout.setDirection(QBoxLayout.LeftToRight) horizontalSpacer = QSpacerItem( 0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum) self.__mainLayout.addWidget( self.__leftWidget, 0, Qt.AlignVCenter | Qt.AlignLeft) self.__mainLayout.addItem(horizontalSpacer) self.__mainLayout.addWidget( self.__rightWidget, 0, Qt.AlignVCenter | Qt.AlignRight) if self.isRightToLeft(): self.__mainLayout.setDirection(QBoxLayout.RightToLeft) else: self.__mainLayout.setDirection(QBoxLayout.LeftToRight) self.setWidgetSpacing(3) self.__leftWidget.sizeHintChanged.connect(self._updateTextMargins) self.__rightWidget.sizeHintChanged.connect(self._updateTextMargins) def setLeftMargin(self, margin): """ Public method to set the left margin. @param margin left margin in pixel (integer) """ self.__leftMargin = margin def leftMargin(self): """ Public method to get the size of the left margin. @return left margin in pixel (integer) """ return self.__leftMargin def event(self, evt): """ Public method to handle events. @param evt reference to the event (QEvent) @return flag indicating, whether the event was recognized (boolean) """ if evt.type() == QEvent.LayoutDirectionChange: if self.isRightToLeft(): self.__mainLayout.setDirection(QBoxLayout.RightToLeft) self.__leftLayout.setDirection(QBoxLayout.RightToLeft) self.__rightLayout.setDirection(QBoxLayout.RightToLeft) else: self.__mainLayout.setDirection(QBoxLayout.LeftToRight) self.__leftLayout.setDirection(QBoxLayout.LeftToRight) self.__rightLayout.setDirection(QBoxLayout.LeftToRight) return QLineEdit.event(self, evt) def paintEvent(self, evt): """ Protected method handling a paint event. @param evt reference to the paint event (QPaintEvent) """ super(E5LineEdit, self).paintEvent(evt) if qVersion() < "4.7.0": if not self.text() and \ self.__inactiveText and \ not self.hasFocus(): panel = QStyleOptionFrame() self.initStyleOption(panel) textRect = self.style().subElementRect( QStyle.SE_LineEditContents, panel, self) textRect.adjust(2, 0, 0, 0) left = self.textMargin(self.LeftSide) right = self.textMargin(self.RightSide) textRect.adjust(left, 0, -right, 0) painter = QPainter(self) painter.setPen(self.palette().brush( QPalette.Disabled, QPalette.Text).color()) painter.drawText( textRect, Qt.AlignLeft | Qt.AlignVCenter, self.__inactiveText) def _updateTextMargins(self): """ Protected slot to update the text margins. """ if self.__leftMargin == 0: left = self.__leftWidget.sizeHint().width() else: left = self.__leftMargin right = self.__rightWidget.sizeHint().width() top = 0 bottom = 0 self.setTextMargins(left, top, right, bottom) def addWidget(self, widget, position): """ Public method to add a widget to a side. @param widget reference to the widget to add (QWidget) @param position position to add to (E5LineEdit.LeftSide, E5LineEdit.RightSide) """ if widget is None: return if self.isRightToLeft(): if position == self.LeftSide: position = self.RightSide else: position = self.LeftSide if position == self.LeftSide: self.__leftLayout.addWidget(widget) else: self.__rightLayout.insertWidget(1, widget) def removeWidget(self, widget): """ Public method to remove a widget from a side. @param widget reference to the widget to remove (QWidget) """ if widget is None: return self.__leftLayout.removeWidget(widget) self.__rightLayout.removeWidget(widget) widget.hide() def widgetSpacing(self): """ Public method to get the side widget spacing. @return side widget spacing (integer) """ return self.__leftLayout.spacing() def setWidgetSpacing(self, spacing): """ Public method to set the side widget spacing. @param spacing side widget spacing (integer) """ self.__leftLayout.setSpacing(spacing) self.__rightLayout.setSpacing(spacing) self._updateTextMargins() def textMargin(self, position): """ Public method to get the text margin for a side. @param position side to get margin for (E5LineEdit.LeftSide, E5LineEdit.RightSide) @return text margin (integer) """ spacing = self.__rightLayout.spacing() w = 0 if position == self.LeftSide: w = self.__leftWidget.sizeHint().width() else: w = self.__rightWidget.sizeHint().width() if w == 0: return 0 return w + spacing * 2 def inactiveText(self): """ Public method to get the inactive text. @return inactive text (string) """ if qVersion() < "4.7.0": return self.__inactiveText else: return self.placeholderText() def setInactiveText(self, inactiveText): """ Public method to set the inactive text. @param inactiveText text to be shown on inactivity (string) """ if qVersion() < "4.7.0": self.__inactiveText = inactiveText self.update() else: self.setPlaceholderText(inactiveText) class E5ClearableLineEdit(E5LineEdit): """ Class implementing a line edit widget showing some inactive text and a clear button, if it has some contents. """ def __init__(self, parent=None, inactiveText="", side=E5LineEdit.RightSide): """ Constructor @param parent reference to the parent widget (QWidget) @keyparam inactiveText text to be shown on inactivity (string) @keyparam side side the clear button should be shown at (E5LineEdit.RightSide, E5LineEdit.LeftSide) """ assert side in [E5LineEdit.RightSide, E5LineEdit.LeftSide] super(E5ClearableLineEdit, self).__init__(parent, inactiveText) from E5Gui.E5LineEditButton import E5LineEditButton self.__clearButton = E5LineEditButton(self) self.__clearButton.setIcon(UI.PixmapCache.getIcon("clearLeft.png")) self.addWidget(self.__clearButton, side) self.__clearButton.setVisible(False) self.__clearButton.clicked.connect(self.clear) self.textChanged.connect(self.__textChanged) def __textChanged(self, txt): """ Private slot to handle changes of the text. @param txt text (string) """ self.__clearButton.setVisible(txt != "") eric-6.0.8/eric/E5Gui/E5TabWidget.py0000644000175000017500000002704312557123133016011 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing a TabWidget class substituting QTabWidget. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QPoint, QMimeData, QByteArray, pyqtSignal, \ qVersion from PyQt5.QtGui import QDrag, QMovie from PyQt5.QtWidgets import QTabWidget, QTabBar, QApplication, QStyle, QLabel class E5WheelTabBar(QTabBar): """ Class implementing a tab bar class substituting QTabBar to support wheel events. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5WheelTabBar, self).__init__(parent) self._tabWidget = parent def wheelEvent(self, event): """ Protected slot to support wheel events. @param event reference to the wheel event (QWheelEvent) """ try: if qVersion() >= "5.0.0": delta = event.angleDelta().y() else: delta = event.delta() if delta > 0: self._tabWidget.prevTab() else: self._tabWidget.nextTab() event.accept() except AttributeError: pass class E5DnDTabBar(E5WheelTabBar): """ Class implementing a tab bar class substituting QTabBar. @signal tabMoveRequested(int, int) emitted to signal a tab move request giving the old and new index position """ tabMoveRequested = pyqtSignal(int, int) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ E5WheelTabBar.__init__(self, parent) self.setAcceptDrops(True) self.__dragStartPos = QPoint() def mousePressEvent(self, event): """ Protected method to handle mouse press events. @param event reference to the mouse press event (QMouseEvent) """ if event.button() == Qt.LeftButton: self.__dragStartPos = QPoint(event.pos()) E5WheelTabBar.mousePressEvent(self, event) def mouseMoveEvent(self, event): """ Protected method to handle mouse move events. @param event reference to the mouse move event (QMouseEvent) """ if event.buttons() == Qt.MouseButtons(Qt.LeftButton) and \ (event.pos() - self.__dragStartPos).manhattanLength() > \ QApplication.startDragDistance(): drag = QDrag(self) mimeData = QMimeData() index = self.tabAt(event.pos()) mimeData.setText(self.tabText(index)) mimeData.setData("action", b"tab-reordering") mimeData.setData("tabbar-id", str(id(self)).encode("utf-8")) drag.setMimeData(mimeData) drag.exec_() E5WheelTabBar.mouseMoveEvent(self, event) def dragEnterEvent(self, event): """ Protected method to handle drag enter events. @param event reference to the drag enter event (QDragEnterEvent) """ mimeData = event.mimeData() formats = mimeData.formats() if "action" in formats and \ mimeData.data("action") == b"tab-reordering" and \ "tabbar-id" in formats and \ int(mimeData.data("tabbar-id")) == id(self): event.acceptProposedAction() E5WheelTabBar.dragEnterEvent(self, event) def dropEvent(self, event): """ Protected method to handle drop events. @param event reference to the drop event (QDropEvent) """ fromIndex = self.tabAt(self.__dragStartPos) toIndex = self.tabAt(event.pos()) if fromIndex != toIndex: self.tabMoveRequested.emit(fromIndex, toIndex) event.acceptProposedAction() E5WheelTabBar.dropEvent(self, event) class E5TabWidget(QTabWidget): """ Class implementing a tab widget class substituting QTabWidget. It provides slots to show the previous and next tab and give them the input focus and it allows to have a context menu for the tabs. @signal customTabContextMenuRequested(const QPoint & point, int index) emitted when a context menu for a tab is requested """ customTabContextMenuRequested = pyqtSignal(QPoint, int) def __init__(self, parent=None, dnd=False): """ Constructor @param parent reference to the parent widget (QWidget) @keyparam dnd flag indicating the support for Drag & Drop (boolean) """ super(E5TabWidget, self).__init__(parent) if dnd: if not hasattr(self, 'setMovable'): self.__tabBar = E5DnDTabBar(self) self.__tabBar.tabMoveRequested.connect(self.moveTab) self.setTabBar(self.__tabBar) else: self.__tabBar = E5WheelTabBar(self) self.setTabBar(self.__tabBar) self.setMovable(True) else: self.__tabBar = E5WheelTabBar(self) self.setTabBar(self.__tabBar) self.__lastCurrentIndex = -1 self.__currentIndex = -1 self.currentChanged.connect(self.__currentChanged) def setCustomTabBar(self, dnd, tabBar): """ Public method to set a custom tab bar. @param dnd flag indicating the support for Drag & Drop (boolean) @param tabBar reference to the tab bar to set (QTabBar) """ self.__tabBar = tabBar self.setTabBar(self.__tabBar) if dnd: if isinstance(tabBar, E5DnDTabBar): self.__tabBar.tabMoveRequested.connect(self.moveTab) else: self.setMovable(True) def __currentChanged(self, index): """ Private slot to handle the currentChanged signal. @param index index of the current tab """ if index == -1: self.__lastCurrentIndex = -1 else: self.__lastCurrentIndex = self.__currentIndex self.__currentIndex = index def switchTab(self): """ Public slot used to switch between the current and the previous current tab. """ if self.__lastCurrentIndex == -1 or self.__currentIndex == -1: return self.setCurrentIndex(self.__lastCurrentIndex) self.currentWidget().setFocus() def nextTab(self): """ Public slot used to show the next tab. """ ind = self.currentIndex() + 1 if ind == self.count(): ind = 0 self.setCurrentIndex(ind) self.currentWidget().setFocus() def prevTab(self): """ Public slot used to show the previous tab. """ ind = self.currentIndex() - 1 if ind == -1: ind = self.count() - 1 self.setCurrentIndex(ind) self.currentWidget().setFocus() def setTabContextMenuPolicy(self, policy): """ Public method to set the context menu policy of the tab. @param policy context menu policy to set (Qt.ContextMenuPolicy) """ self.tabBar().setContextMenuPolicy(policy) if policy == Qt.CustomContextMenu: self.tabBar().customContextMenuRequested.connect( self.__handleTabCustomContextMenuRequested) else: self.tabBar().customContextMenuRequested.disconnect( self.__handleTabCustomContextMenuRequested) def __handleTabCustomContextMenuRequested(self, point): """ Private slot to handle the context menu request for the tabbar. @param point point the context menu was requested (QPoint) """ _tabbar = self.tabBar() for index in range(_tabbar.count()): rect = _tabbar.tabRect(index) if rect.contains(point): self.customTabContextMenuRequested.emit( _tabbar.mapToParent(point), index) return self.customTabContextMenuRequested.emit(_tabbar.mapToParent(point), -1) def selectTab(self, pos): """ Public method to get the index of a tab given a position. @param pos position determining the tab index (QPoint) @return index of the tab (integer) """ _tabbar = self.tabBar() for index in range(_tabbar.count()): rect = _tabbar.tabRect(index) if rect.contains(pos): return index return -1 def moveTab(self, curIndex, newIndex): """ Public method to move a tab to a new index. @param curIndex index of tab to be moved (integer) @param newIndex index the tab should be moved to (integer) """ # step 1: save the tab data of tab to be moved toolTip = self.tabToolTip(curIndex) text = self.tabText(curIndex) icon = self.tabIcon(curIndex) whatsThis = self.tabWhatsThis(curIndex) widget = self.widget(curIndex) curWidget = self.currentWidget() # step 2: move the tab self.removeTab(curIndex) self.insertTab(newIndex, widget, icon, text) # step 3: set the tab data again self.setTabToolTip(newIndex, toolTip) self.setTabWhatsThis(newIndex, whatsThis) # step 4: set current widget self.setCurrentWidget(curWidget) def __freeSide(self): """ Private method to determine the free side of a tab. @return free side (QTabBar.ButtonPosition) """ side = self.__tabBar.style().styleHint( QStyle.SH_TabBar_CloseButtonPosition, None, None, None) if side == QTabBar.LeftSide: side = QTabBar.RightSide else: side = QTabBar.LeftSide return side def animationLabel(self, index, animationFile, speed=100): """ Public slot to set an animated icon. @param index tab index (integer) @param animationFile name of the file containing the animation (string) @param speed animation speed of the icon in percent of the original icon's speed (integer) @return reference to the created label (QLabel) """ if index == -1: return None if hasattr(self.__tabBar, 'setTabButton'): side = self.__freeSide() animation = QLabel(self) if animationFile and not animation.movie(): movie = QMovie(animationFile, QByteArray(), animation) movie.setSpeed(speed) animation.setMovie(movie) movie.start() self.__tabBar.setTabButton(index, side, None) self.__tabBar.setTabButton(index, side, animation) return animation else: return None def resetAnimation(self, index): """ Public slot to reset an animated icon. @param index tab index (integer) """ if index == -1: return if hasattr(self.__tabBar, 'tabButton'): side = self.__freeSide() animation = self.__tabBar.tabButton(index, side) if animation is not None: animation.movie().stop() self.__tabBar.setTabButton(index, side, None) del animation eric-6.0.8/eric/E5Gui/E5Action.py0000644000175000017500000001574512451233374015364 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing an Action class extending QAction. This extension is necessary in order to support alternate keyboard shortcuts. """ from __future__ import unicode_literals from PyQt5.QtGui import QIcon, QKeySequence from PyQt5.QtWidgets import QAction, QActionGroup, qApp class ArgumentsError(RuntimeError): """ Class implementing an exception, which is raised, if the wrong number of arguments are given. """ def __init__(self, error): """ Constructor @param error error message of the exception (string) """ self.errorMessage = str(error) def __repr__(self): """ Special method returning a representation of the exception. @return string representing the error message """ return str(self.errorMessage) def __str__(self): """ Special method returning a string representation of the exception. @return string representing the error message """ return str(self.errorMessage) class E5Action(QAction): """ Class implementing an Action class extending QAction. """ def __init__(self, *args): """ Constructor @param args argument list of the constructor. This list is one of
  • text (string), icon (QIcon), menu text (string), accelarator (QKeySequence), alternative accelerator (QKeySequence), parent (QObject), name (string), toggle (boolean)
  • text (string), icon (QIcon), menu text (string), accelarator (QKeySequence), alternative accelerator (QKeySequence), parent (QObject), name (string)
  • text (string), menu text (string), accelarator (QKeySequence), alternative accelerator (QKeySequence), parent (QObject), name (string), toggle (boolean)
  • text (string), menu text (string), accelarator (QKeySequence), alternative accelerator (QKeySequence), parent (QObject), name (string)
@exception ArgumentsError raised to indicate invalid arguments """ if isinstance(args[1], QIcon): icon = args[1] incr = 1 else: icon = None incr = 0 if len(args) < 6 + incr: raise ArgumentsError( "Not enough arguments, {0:d} expected, got {1:d}".format( 6 + incr, len(args))) elif len(args) > 7 + incr: raise ArgumentsError( "Too many arguments, max. {0:d} expected, got {1:d}".format( 7 + incr, len(args))) parent = args[4 + incr] super(E5Action, self).__init__(parent) name = args[5 + incr] if name: self.setObjectName(name) if args[1 + incr]: self.setText(args[1 + incr]) if args[0]: self.setIconText(args[0]) if args[2 + incr]: self.setShortcut(QKeySequence(args[2 + incr])) if args[3 + incr]: self.setAlternateShortcut(QKeySequence(args[3 + incr])) if icon: self.setIcon(icon) if len(args) == 7 + incr: self.setCheckable(args[6 + incr]) self.__ammendToolTip() def setAlternateShortcut(self, shortcut, removeEmpty=False): """ Public slot to set the alternative keyboard shortcut. @param shortcut the alternative accelerator (QKeySequence) @param removeEmpty flag indicating to remove the alternate shortcut, if it is empty (boolean) """ if not shortcut.isEmpty(): shortcuts = self.shortcuts() if len(shortcuts) > 0: if len(shortcuts) == 1: shortcuts.append(shortcut) else: shortcuts[1] = shortcut self.setShortcuts(shortcuts) elif removeEmpty: shortcuts = self.shortcuts() if len(shortcuts) == 2: del shortcuts[1] self.setShortcuts(shortcuts) def alternateShortcut(self): """ Public method to retrieve the alternative keyboard shortcut. @return the alternative accelerator (QKeySequence) """ shortcuts = self.shortcuts() if len(shortcuts) < 2: return QKeySequence() else: return shortcuts[1] def setShortcut(self, shortcut): """ Public slot to set the keyboard shortcut. @param shortcut the accelerator (QKeySequence) """ super(E5Action, self).setShortcut(shortcut) self.__ammendToolTip() def setShortcuts(self, shortcuts): """ Public slot to set the list of keyboard shortcuts. @param shortcuts list of keyboard accelerators (list of QKeySequence) or key for a platform dependent list of accelerators (QKeySequence.StandardKey) """ super(E5Action, self).setShortcuts(shortcuts) self.__ammendToolTip() def setIconText(self, text): """ Public slot to set the icon text of the action. @param text new icon text (string) """ super(E5Action, self).setIconText(text) self.__ammendToolTip() def __ammendToolTip(self): """ Private slot to add the primary keyboard accelerator to the tooltip. """ shortcut = self.shortcut().toString(QKeySequence.NativeText) if shortcut: if qApp.isLeftToRight(): fmt = "{0} ({1})" else: fmt = "({1}) {0}" self.setToolTip(fmt.format(self.iconText(), shortcut)) def addActions(target, actions): """ Module function to add a list of actions to a widget. @param target reference to the target widget (QWidget) @param actions list of actions to be added to the target. A None indicates a separator (list of QActions) """ if target is None: return for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def createActionGroup(parent, name=None, exclusive=False): """ Module function to create an action group. @param parent parent object of the action group (QObject) @param name name of the action group object (string) @param exclusive flag indicating an exclusive action group (boolean) @return reference to the created action group (QActionGroup) """ actGrp = QActionGroup(parent) if name: actGrp.setObjectName(name) actGrp.setExclusive(exclusive) return actGrp eric-6.0.8/eric/E5Gui/E5ToolBox.py0000644000175000017500000000547312451233374015532 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing a horizontal and a vertical toolbox class. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QToolBox, QTabWidget from .E5TabWidget import E5TabWidget class E5VerticalToolBox(QToolBox): """ Class implementing a ToolBox class substituting QToolBox to support wheel events. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5VerticalToolBox, self).__init__(parent) class E5HorizontalToolBox(E5TabWidget): """ Class implementing a vertical QToolBox like widget. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ E5TabWidget.__init__(self, parent) self.setTabPosition(QTabWidget.West) self.setUsesScrollButtons(True) def addItem(self, widget, icon, text): """ Public method to add a widget to the toolbox. @param widget reference to the widget to be added (QWidget) @param icon the icon to be shown (QIcon) @param text the text to be shown (string) @return index of the added widget (integer) """ index = self.addTab(widget, icon, "") self.setTabToolTip(index, text) return index def insertItem(self, index, widget, icon, text): """ Public method to add a widget to the toolbox. @param index position at which the widget should be inserted (integer) @param widget reference to the widget to be added (QWidget) @param icon the icon to be shown (QIcon) @param text the text to be shown (string) @return index of the added widget (integer) """ index = self.insertTab(index, widget, icon, "") self.setTabToolTip(index, text) return index def removeItem(self, index): """ Public method to remove a widget from the toolbox. @param index index of the widget to remove (integer) """ self.removeTab(index) def setItemToolTip(self, index, toolTip): """ Public method to set the tooltip of an item. @param index index of the item (integer) @param toolTip tooltip text to be set (string) """ self.setTabToolTip(index, toolTip) def setItemEnabled(self, index, enabled): """ Public method to set the enabled state of an item. @param index index of the item (integer) @param enabled flag indicating the enabled state (boolean) """ self.setTabEnabled(index, enabled) eric-6.0.8/eric/E5Gui/E5SideBar.py0000644000175000017500000005656412451233374015464 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing a sidebar class. """ from __future__ import unicode_literals from PyQt5.QtCore import QEvent, QSize, Qt, QByteArray, QDataStream, \ QIODevice, QTimer, qVersion from PyQt5.QtWidgets import QTabBar, QWidget, QStackedWidget, QBoxLayout, \ QToolButton, QSizePolicy from E5Gui.E5Application import e5App import UI.PixmapCache class E5SideBar(QWidget): """ Class implementing a sidebar with a widget area, that is hidden or shown, if the current tab is clicked again. """ Version = 1 North = 0 East = 1 South = 2 West = 3 def __init__(self, orientation=None, delay=200, parent=None): """ Constructor @param orientation orientation of the sidebar widget (North, East, South, West) @param delay value for the expand/shrink delay in milliseconds (integer) @param parent parent widget (QWidget) """ super(E5SideBar, self).__init__(parent) self.__tabBar = QTabBar() self.__tabBar.setDrawBase(True) self.__tabBar.setShape(QTabBar.RoundedNorth) self.__tabBar.setUsesScrollButtons(True) self.__tabBar.setDrawBase(False) self.__stackedWidget = QStackedWidget(self) self.__stackedWidget.setContentsMargins(0, 0, 0, 0) self.__autoHideButton = QToolButton() self.__autoHideButton.setCheckable(True) self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOff.png")) self.__autoHideButton.setChecked(True) self.__autoHideButton.setToolTip( self.tr("Deselect to activate automatic collapsing")) self.barLayout = QBoxLayout(QBoxLayout.LeftToRight) self.barLayout.setContentsMargins(0, 0, 0, 0) self.layout = QBoxLayout(QBoxLayout.TopToBottom) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.barLayout.addWidget(self.__autoHideButton) self.barLayout.addWidget(self.__tabBar) self.layout.addLayout(self.barLayout) self.layout.addWidget(self.__stackedWidget) self.setLayout(self.layout) # initialize the delay timer self.__actionMethod = None self.__delayTimer = QTimer(self) self.__delayTimer.setSingleShot(True) self.__delayTimer.setInterval(delay) self.__delayTimer.timeout.connect(self.__delayedAction) self.__minimized = False self.__minSize = 0 self.__maxSize = 0 self.__bigSize = QSize() self.splitter = None self.splitterSizes = [] self.__hasFocus = False # flag storing if this widget or any child has the focus self.__autoHide = False self.__tabBar.installEventFilter(self) self.__orientation = E5SideBar.North if orientation is None: orientation = E5SideBar.North self.setOrientation(orientation) self.__tabBar.currentChanged[int].connect( self.__stackedWidget.setCurrentIndex) e5App().focusChanged[QWidget, QWidget].connect(self.__appFocusChanged) self.__autoHideButton.toggled[bool].connect(self.__autoHideToggled) def setSplitter(self, splitter): """ Public method to set the splitter managing the sidebar. @param splitter reference to the splitter (QSplitter) """ self.splitter = splitter self.splitter.splitterMoved.connect(self.__splitterMoved) self.splitter.setChildrenCollapsible(False) index = self.splitter.indexOf(self) self.splitter.setCollapsible(index, False) def __splitterMoved(self, pos, index): """ Private slot to react on splitter moves. @param pos new position of the splitter handle (integer) @param index index of the splitter handle (integer) """ if self.splitter: self.splitterSizes = self.splitter.sizes() def __delayedAction(self): """ Private slot to handle the firing of the delay timer. """ if self.__actionMethod is not None: self.__actionMethod() def setDelay(self, delay): """ Public method to set the delay value for the expand/shrink delay in milliseconds. @param delay value for the expand/shrink delay in milliseconds (integer) """ self.__delayTimer.setInterval(delay) def delay(self): """ Public method to get the delay value for the expand/shrink delay in milliseconds. @return value for the expand/shrink delay in milliseconds (integer) """ return self.__delayTimer.interval() def __cancelDelayTimer(self): """ Private method to cancel the current delay timer. """ self.__delayTimer.stop() self.__actionMethod = None def shrink(self): """ Public method to record a shrink request. """ self.__delayTimer.stop() self.__actionMethod = self.__shrinkIt self.__delayTimer.start() def __shrinkIt(self): """ Private method to shrink the sidebar. """ self.__minimized = True self.__bigSize = self.size() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() self.__maxSize = self.maximumHeight() else: self.__minSize = self.minimumSizeHint().width() self.__maxSize = self.maximumWidth() if self.splitter: self.splitterSizes = self.splitter.sizes() self.__stackedWidget.hide() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.setFixedHeight(self.__tabBar.minimumSizeHint().height()) else: self.setFixedWidth(self.__tabBar.minimumSizeHint().width()) self.__actionMethod = None def expand(self): """ Public method to record a expand request. """ self.__delayTimer.stop() self.__actionMethod = self.__expandIt self.__delayTimer.start() def __expandIt(self): """ Private method to expand the sidebar. """ self.__minimized = False self.__stackedWidget.show() self.resize(self.__bigSize) if self.__orientation in [E5SideBar.North, E5SideBar.South]: minSize = max(self.__minSize, self.minimumSizeHint().height()) self.setMinimumHeight(minSize) self.setMaximumHeight(self.__maxSize) else: minSize = max(self.__minSize, self.minimumSizeHint().width()) self.setMinimumWidth(minSize) self.setMaximumWidth(self.__maxSize) if self.splitter: self.splitter.setSizes(self.splitterSizes) self.__actionMethod = None def isMinimized(self): """ Public method to check the minimized state. @return flag indicating the minimized state (boolean) """ return self.__minimized def isAutoHiding(self): """ Public method to check, if the auto hide function is active. @return flag indicating the state of auto hiding (boolean) """ return self.__autoHide def eventFilter(self, obj, evt): """ Public method to handle some events for the tabbar. @param obj reference to the object (QObject) @param evt reference to the event object (QEvent) @return flag indicating, if the event was handled (boolean) """ if obj == self.__tabBar: if evt.type() == QEvent.MouseButtonPress: pos = evt.pos() for i in range(self.__tabBar.count()): if self.__tabBar.tabRect(i).contains(pos): break if i == self.__tabBar.currentIndex(): if self.isMinimized(): self.expand() else: self.shrink() return True elif self.isMinimized(): self.expand() elif evt.type() == QEvent.Wheel: if qVersion() >= "5.0.0": delta = evt.angleDelta().y() else: delta = evt.delta() if delta > 0: self.prevTab() else: self.nextTab() return True return QWidget.eventFilter(self, obj, evt) def addTab(self, widget, iconOrLabel, label=None): """ Public method to add a tab to the sidebar. @param widget reference to the widget to add (QWidget) @param iconOrLabel reference to the icon or the label text of the tab (QIcon, string) @param label the labeltext of the tab (string) (only to be used, if the second parameter is a QIcon) """ if label: index = self.__tabBar.addTab(iconOrLabel, label) self.__tabBar.setTabToolTip(index, label) else: index = self.__tabBar.addTab(iconOrLabel) self.__tabBar.setTabToolTip(index, iconOrLabel) self.__stackedWidget.addWidget(widget) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def insertTab(self, index, widget, iconOrLabel, label=None): """ Public method to insert a tab into the sidebar. @param index the index to insert the tab at (integer) @param widget reference to the widget to insert (QWidget) @param iconOrLabel reference to the icon or the labeltext of the tab (QIcon, string) @param label the labeltext of the tab (string) (only to be used, if the second parameter is a QIcon) """ if label: index = self.__tabBar.insertTab(index, iconOrLabel, label) self.__tabBar.setTabToolTip(index, label) else: index = self.__tabBar.insertTab(index, iconOrLabel) self.__tabBar.setTabToolTip(index, iconOrLabel) self.__stackedWidget.insertWidget(index, widget) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def removeTab(self, index): """ Public method to remove a tab. @param index the index of the tab to remove (integer) """ self.__stackedWidget.removeWidget(self.__stackedWidget.widget(index)) self.__tabBar.removeTab(index) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def clear(self): """ Public method to remove all tabs. """ while self.count() > 0: self.removeTab(0) def prevTab(self): """ Public slot used to show the previous tab. """ ind = self.currentIndex() - 1 if ind == -1: ind = self.count() - 1 self.setCurrentIndex(ind) self.currentWidget().setFocus() def nextTab(self): """ Public slot used to show the next tab. """ ind = self.currentIndex() + 1 if ind == self.count(): ind = 0 self.setCurrentIndex(ind) self.currentWidget().setFocus() def count(self): """ Public method to get the number of tabs. @return number of tabs in the sidebar (integer) """ return self.__tabBar.count() def currentIndex(self): """ Public method to get the index of the current tab. @return index of the current tab (integer) """ return self.__stackedWidget.currentIndex() def setCurrentIndex(self, index): """ Public slot to set the current index. @param index the index to set as the current index (integer) """ self.__tabBar.setCurrentIndex(index) self.__stackedWidget.setCurrentIndex(index) if self.isMinimized(): self.expand() def currentWidget(self): """ Public method to get a reference to the current widget. @return reference to the current widget (QWidget) """ return self.__stackedWidget.currentWidget() def setCurrentWidget(self, widget): """ Public slot to set the current widget. @param widget reference to the widget to become the current widget (QWidget) """ self.__stackedWidget.setCurrentWidget(widget) self.__tabBar.setCurrentIndex(self.__stackedWidget.currentIndex()) if self.isMinimized(): self.expand() def indexOf(self, widget): """ Public method to get the index of the given widget. @param widget reference to the widget to get the index of (QWidget) @return index of the given widget (integer) """ return self.__stackedWidget.indexOf(widget) def isTabEnabled(self, index): """ Public method to check, if a tab is enabled. @param index index of the tab to check (integer) @return flag indicating the enabled state (boolean) """ return self.__tabBar.isTabEnabled(index) def setTabEnabled(self, index, enabled): """ Public method to set the enabled state of a tab. @param index index of the tab to set (integer) @param enabled enabled state to set (boolean) """ self.__tabBar.setTabEnabled(index, enabled) def orientation(self): """ Public method to get the orientation of the sidebar. @return orientation of the sidebar (North, East, South, West) """ return self.__orientation def setOrientation(self, orient): """ Public method to set the orientation of the sidebar. @param orient orientation of the sidebar (North, East, South, West) """ if orient == E5SideBar.North: self.__tabBar.setShape(QTabBar.RoundedNorth) self.__tabBar.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred) self.barLayout.setDirection(QBoxLayout.LeftToRight) self.layout.setDirection(QBoxLayout.TopToBottom) self.layout.setAlignment(self.barLayout, Qt.AlignLeft) elif orient == E5SideBar.East: self.__tabBar.setShape(QTabBar.RoundedEast) self.__tabBar.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Expanding) self.barLayout.setDirection(QBoxLayout.TopToBottom) self.layout.setDirection(QBoxLayout.RightToLeft) self.layout.setAlignment(self.barLayout, Qt.AlignTop) elif orient == E5SideBar.South: self.__tabBar.setShape(QTabBar.RoundedSouth) self.__tabBar.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred) self.barLayout.setDirection(QBoxLayout.LeftToRight) self.layout.setDirection(QBoxLayout.BottomToTop) self.layout.setAlignment(self.barLayout, Qt.AlignLeft) elif orient == E5SideBar.West: self.__tabBar.setShape(QTabBar.RoundedWest) self.__tabBar.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Expanding) self.barLayout.setDirection(QBoxLayout.TopToBottom) self.layout.setDirection(QBoxLayout.LeftToRight) self.layout.setAlignment(self.barLayout, Qt.AlignTop) self.__orientation = orient def tabIcon(self, index): """ Public method to get the icon of a tab. @param index index of the tab (integer) @return icon of the tab (QIcon) """ return self.__tabBar.tabIcon(index) def setTabIcon(self, index, icon): """ Public method to set the icon of a tab. @param index index of the tab (integer) @param icon icon to be set (QIcon) """ self.__tabBar.setTabIcon(index, icon) def tabText(self, index): """ Public method to get the text of a tab. @param index index of the tab (integer) @return text of the tab (string) """ return self.__tabBar.tabText(index) def setTabText(self, index, text): """ Public method to set the text of a tab. @param index index of the tab (integer) @param text text to set (string) """ self.__tabBar.setTabText(index, text) def tabToolTip(self, index): """ Public method to get the tooltip text of a tab. @param index index of the tab (integer) @return tooltip text of the tab (string) """ return self.__tabBar.tabToolTip(index) def setTabToolTip(self, index, tip): """ Public method to set the tooltip text of a tab. @param index index of the tab (integer) @param tip tooltip text to set (string) """ self.__tabBar.setTabToolTip(index, tip) def tabWhatsThis(self, index): """ Public method to get the WhatsThis text of a tab. @param index index of the tab (integer) @return WhatsThis text of the tab (string) """ return self.__tabBar.tabWhatsThis(index) def setTabWhatsThis(self, index, text): """ Public method to set the WhatsThis text of a tab. @param index index of the tab (integer) @param text WhatsThis text to set (string) """ self.__tabBar.setTabWhatsThis(index, text) def widget(self, index): """ Public method to get a reference to the widget associated with a tab. @param index index of the tab (integer) @return reference to the widget (QWidget) """ return self.__stackedWidget.widget(index) def saveState(self): """ Public method to save the state of the sidebar. @return saved state as a byte array (QByteArray) """ if len(self.splitterSizes) == 0: if self.splitter: self.splitterSizes = self.splitter.sizes() self.__bigSize = self.size() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() self.__maxSize = self.maximumHeight() else: self.__minSize = self.minimumSizeHint().width() self.__maxSize = self.maximumWidth() data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) stream.writeUInt16(self.Version) stream.writeBool(self.__minimized) stream << self.__bigSize stream.writeUInt16(self.__minSize) stream.writeUInt16(self.__maxSize) stream.writeUInt16(len(self.splitterSizes)) for size in self.splitterSizes: stream.writeUInt16(size) stream.writeBool(self.__autoHide) return data def restoreState(self, state): """ Public method to restore the state of the sidebar. @param state byte array containing the saved state (QByteArray) @return flag indicating success (boolean) """ if state.isEmpty(): return False if self.__orientation in [E5SideBar.North, E5SideBar.South]: minSize = self.layout.minimumSize().height() maxSize = self.maximumHeight() else: minSize = self.layout.minimumSize().width() maxSize = self.maximumWidth() data = QByteArray(state) stream = QDataStream(data, QIODevice.ReadOnly) stream.setVersion(QDataStream.Qt_4_6) stream.readUInt16() # version minimized = stream.readBool() if minimized and not self.__minimized: self.shrink() stream >> self.__bigSize self.__minSize = max(stream.readUInt16(), minSize) self.__maxSize = max(stream.readUInt16(), maxSize) count = stream.readUInt16() self.splitterSizes = [] for i in range(count): self.splitterSizes.append(stream.readUInt16()) self.__autoHide = stream.readBool() self.__autoHideButton.setChecked(not self.__autoHide) if not minimized: self.expand() return True ####################################################################### ## methods below implement the autohide functionality ####################################################################### def __autoHideToggled(self, checked): """ Private slot to handle the toggling of the autohide button. @param checked flag indicating the checked state of the button (boolean) """ self.__autoHide = not checked if self.__autoHide: self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOn.png")) else: self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOff.png")) def __appFocusChanged(self, old, now): """ Private slot to handle a change of the focus. @param old reference to the widget, that lost focus (QWidget or None) @param now reference to the widget having the focus (QWidget or None) """ self.__hasFocus = self.isAncestorOf(now) if self.__autoHide and not self.__hasFocus and not self.isMinimized(): self.shrink() elif self.__autoHide and self.__hasFocus and self.isMinimized(): self.expand() def enterEvent(self, event): """ Protected method to handle the mouse entering this widget. @param event reference to the event (QEvent) """ if self.__autoHide and self.isMinimized(): self.expand() else: self.__cancelDelayTimer() def leaveEvent(self, event): """ Protected method to handle the mouse leaving this widget. @param event reference to the event (QEvent) """ if self.__autoHide and not self.__hasFocus and not self.isMinimized(): self.shrink() else: self.__cancelDelayTimer() def shutdown(self): """ Public method to shut down the object. This method does some preparations so the object can be deleted properly. It disconnects from the focusChanged signal in order to avoid trouble later on. """ e5App().focusChanged[QWidget, QWidget].disconnect( self.__appFocusChanged) eric-6.0.8/eric/E5Gui/E5SingleApplication.py0000644000175000017500000001124312451233374017541 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implementing the single application server and client. """ from __future__ import unicode_literals import os from E5Gui.E5Application import e5App from Toolbox.SingleApplication import SingleApplicationClient, \ SingleApplicationServer import Utilities ########################################################################### # define some module global stuff ########################################################################### SAFile = "eric6" # define the protocol tokens SAOpenFile = '>OpenFile<' SAOpenProject = '>OpenProject<' SAArguments = '>Arguments<' class E5SingleApplicationServer(SingleApplicationServer): """ Class implementing the single application server embedded within the IDE. """ def __init__(self): """ Constructor """ SingleApplicationServer.__init__(self, SAFile) def handleCommand(self, cmd, params): """ Public slot to handle the command sent by the client. @param cmd commandstring (string) @param params parameterstring (string) """ if cmd == SAOpenFile: self.__saOpenFile(params) return if cmd == SAOpenProject: self.__saOpenProject(params) return if cmd == SAArguments: self.__saArguments(params) return def __saOpenFile(self, fname): """ Private method used to handle the "Open File" command. @param fname filename to be opened (string) """ e5App().getObject("ViewManager").openSourceFile(fname) def __saOpenProject(self, pfname): """ Private method used to handle the "Open Project" command. @param pfname filename of the project to be opened (string) """ e5App().getObject("Project").openProject(pfname) def __saArguments(self, argsStr): """ Private method used to handle the "Arguments" command. @param argsStr space delimited list of command args(string) """ e5App().getObject("DebugUI").setArgvHistory(argsStr) class E5SingleApplicationClient(SingleApplicationClient): """ Class implementing the single application client of the IDE. """ def __init__(self): """ Constructor """ SingleApplicationClient.__init__(self, SAFile) def processArgs(self, args): """ Public method to process the command line args passed to the UI. @param args list of files to open """ # no args, return if args is None: return # holds space delimited list of command args, if any argsStr = None # flag indicating '--' options was found ddseen = False if Utilities.isWindowsPlatform(): argChars = ['-', '/'] else: argChars = ['-'] for arg in args: if arg == '--' and not ddseen: ddseen = True continue if arg[0] in argChars or ddseen: if argsStr is None: argsStr = arg else: argsStr = "{0} {1}".format(argsStr, arg) continue ext = os.path.splitext(arg)[1] ext = os.path.normcase(ext) if ext in ['.e4p']: self.__openProject(arg) else: self.__openFile(arg) # send any args we had if argsStr is not None: self.__sendArguments(argsStr) self.disconnect() def __openFile(self, fname): """ Private method to open a file in the application server. @param fname name of file to be opened (string) """ cmd = "{0}{1}\n".format(SAOpenFile, Utilities.normabspath(fname)) self.sendCommand(cmd) def __openProject(self, pfname): """ Private method to open a project in the application server. @param pfname name of the projectfile to be opened (string) """ cmd = "{0}{1}\n".format(SAOpenProject, Utilities.normabspath(pfname)) self.sendCommand(cmd) def __sendArguments(self, argsStr): """ Private method to set the command arguments in the application server. @param argsStr space delimited list of command args (string) """ cmd = "{0}{1}\n".format(SAArguments, argsStr) self.sendCommand(cmd) eric-6.0.8/eric/E5Gui/E5ZoomWidget.ui0000644000175000017500000001061012074312216016200 0ustar piotrpiotr E5ZoomWidget 0 0 242 21 0 0 0 0 0 0 0 16 16777215 16 0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 16 16 16 16 Zoom out 0 0 160 16 160 16 Qt::NoFocus Drag to zoom -10 20 Qt::Horizontal QSlider::NoTicks 0 0 16 16 16 16 Zoom in 0 0 16 16 16 16 Zoom reset E5ClickableLabel QLabel
E5Gui/E5ClickableLabel.h
eric-6.0.8/eric/README-passive-debugging.txt0000644000175000017500000000462512371443731017560 0ustar piotrpiotrREADME for passive mode debugging eric6 provides the capability to debug programms using the passive mode. In this mode it is possible to start the debugger separate from the IDE. This may be done on a different computer as well. If the debugger is started on a remote machine, it is your responsibility to ensure, that the paths to the script to be debugged are identical on both machines. In order to enable passive mode debugging in the IDE choose the debugger tab of the preferences dialog and enable the passive mode debugging checkbox. You may change the default port as well. Please be aware that you have to tell the debugger the port, if it is different to the default value of 42424. On the remote computer you have to have the debugger scripts installed. Use DebugClient.py to debug normal scripts or DebugClientThreads.py to debug multi threaded scripts. The debuggers know about the following commandline switches. -h -- this specifies the hostname of the machine running the IDE. -p -- this specifies the portnumber of the IDE. -w -- this specifies the working directory to be used for the script to be debugged. -t -- this enables tracing into the Python library -n -- this disables the redirection of stdin, stdout and stderr -e -- this disables reporting of exceptions --fork-child -- this tells the debugger to follow the child when forking --fork-parent -- this tells the debugger to follow the parent when forking The commandline parameters have to be followed by '--' (double dash), the script to be debugged and its commandline parameters. Example:: python DebugClient -h somehost -- myscript.py param1 After the execution of the debugger command, it connects to the IDE and tells it the filename of the script being debugged. The IDE will try to load it and the script will stop at the first line. After that you may set breakpoints, step through your script and use all the debugging functions. Note: The port and hostname may alternatively be set through the environment variables ERICPORT and ERICHOST. Please send bug reports, feature requests or contributions to eric bugs address or using the buildt in bug reporting dialog. eric-6.0.8/eric/eric6_snap.pyw0000644000175000017500000000027612451233400015236 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_snap import main main() eric-6.0.8/eric/eric6_tray.pyw0000644000175000017500000000027612451233400015254 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_tray import main main() eric-6.0.8/eric/eric6_re.py0000644000175000017500000000345012451233374014523 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Eric6 Re. This is the main Python script that performs the necessary initialization of the PyRegExp wizard module and starts the Qt event loop. This is a standalone version of the integrated PyRegExp wizard. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from Plugins.WizardPlugins.PyRegExpWizard.PyRegExpWizardDialog import \ PyRegExpWizardWindow return PyRegExpWizardWindow() def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ] appinfo = AppInfo.makeAppInfo(sys.argv, "Eric6 RE", "", "Regexp editor for the Python re module", options) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/eric6.e4p0000644000175000017500000033232512405352366014105 0ustar piotrpiotr en_US Dictionaries/words.dic Dictionaries/excludes.dic df7daa8781250f7664e6ecaeaf1361fa2efd39ee Python3 PyQt5 eric6 is an integrated development environment for the Python and Ruby language. It uses the PyQt5 bindings and the QScintilla2 editor widget. 6.0.x Detlev Offenbach detlev@die-offenbachs.de i18n/eric6_%language%.ts __init__.py Preferences/__init__.py ViewManager/__init__.py Helpviewer/HelpWindow.py Helpviewer/__init__.py UI/PixmapCache.py UI/__init__.py Utilities/__init__.py UI/Info.py Tools/UIPreviewer.py Tools/__init__.py Tools/TRSingleApplication.py Tools/TRPreviewer.py PyUnit/UnittestDialog.py PyUnit/__init__.py DebugClients/Python/__init__.py DebugClients/__init__.py Utilities/ModuleParser.py Utilities/ClassBrowsers/idlclbr.py Utilities/ClassBrowsers/pyclbr.py Utilities/ClassBrowsers/ClbrBaseClasses.py Utilities/ClassBrowsers/rbclbr.py Utilities/ClassBrowsers/__init__.py DocumentationTools/APIGenerator.py DocumentationTools/__init__.py DocumentationTools/TemplatesListsStyle.py DocumentationTools/ModuleDocumentor.py DocumentationTools/TemplatesListsStyleCSS.py DocumentationTools/IndexGenerator.py DebugClients/Ruby/DebugProtocol.rb DebugClients/Ruby/AsyncFile.rb DebugClients/Ruby/DebugClientCapabilities.rb DebugClients/Ruby/Debuggee.rb DebugClients/Ruby/DebugClient.rb DebugClients/Ruby/DebugQuit.rb DebugClients/Ruby/Completer.rb DebugClients/Ruby/DebugClientBaseModule.rb DebugClients/Ruby/Config.rb DebugClients/Ruby/__init__.rb DebugClients/Ruby/AsyncIO.rb patch_modpython.py UI/DiffDialog.py UI/CompareDialog.py DebugClients/Python/DebugProtocol.py DebugClients/Python/PyProfile.py DebugClients/Python/FlexCompleter.py DebugClients/Python/getpass.py DebugClients/Python/DCTestResult.py DebugClients/Python/AsyncFile.py DebugClients/Python/AsyncIO.py DebugClients/Python/DebugClientCapabilities.py DebugClients/Python/DebugBase.py DebugClients/Python/DebugClientBase.py DebugClients/Python/DebugClientThreads.py DebugClients/Python/DebugThread.py DebugClients/Python/DebugClient.py Debugger/DebugServer.py Debugger/Config.py Debugger/__init__.py Debugger/EditBreakpointDialog.py Debugger/EditWatchpointDialog.py Debugger/ExceptionsFilterDialog.py Debugger/StartDialog.py Debugger/VariableDetailDialog.py Debugger/VariablesFilterDialog.py Debugger/BreakPointViewer.py Debugger/BreakPointModel.py Debugger/DebugUI.py Debugger/WatchPointViewer.py Debugger/WatchPointModel.py UI/Config.py Debugger/DebugViewer.py Debugger/ExceptionLogger.py Debugger/VariablesViewer.py Preferences/ConfigurationDialog.py Preferences/ConfigurationPages/__init__.py Preferences/PreferencesLexer.py Preferences/ViewProfileDialog.py Preferences/ShortcutsDialog.py Preferences/Shortcuts.py Preferences/ShortcutDialog.py UI/Browser.py Preferences/ToolConfigurationDialog.py UI/DeleteFilesConfirmationDialog.py UI/EmailDialog.py UI/FindFileDialog.py UI/FindFileNameDialog.py UI/LogView.py UI/SplashScreen.py DataViews/__init__.py DataViews/CodeMetrics.py DataViews/CodeMetricsDialog.py DataViews/PyCoverageDialog.py DataViews/PyProfileDialog.py Tasks/TaskPropertiesDialog.py Tasks/TaskViewer.py Templates/TemplateViewer.py Templates/TemplateMultipleVariablesDialog.py Templates/TemplatePropertiesDialog.py Templates/TemplateSingleVariableDialog.py Tasks/__init__.py Templates/__init__.py UI/BrowserModel.py UI/BrowserSortFilterProxyModel.py install-i18n.py Project/AddFileDialog.py Project/AddFoundFilesDialog.py Project/AddLanguageDialog.py Project/PropertiesDialog.py Project/__init__.py Project/AddDirectoryDialog.py Project/FiletypeAssociationDialog.py Project/DebuggerPropertiesDialog.py VCS/RepositoryInfoDialog.py VCS/CommandOptionsDialog.py VCS/__init__.py Project/Project.py UI/UserInterface.py ViewManager/ViewManager.py Project/ProjectBrowserModel.py Project/ProjectBrowserSortFilterProxyModel.py Project/ProjectBrowser.py Project/ProjectBaseBrowser.py Project/ProjectSourcesBrowser.py Project/ProjectFormsBrowser.py Project/ProjectTranslationsBrowser.py Project/ProjectInterfacesBrowser.py Project/ProjectOthersBrowser.py VCS/VersionControl.py VCS/ProjectBrowserHelper.py VCS/ProjectHelper.py ViewManager/BookmarkedFilesDialog.py QScintilla/__init__.py QScintilla/GotoDialog.py QScintilla/ZoomDialog.py install.py uninstall.py Graphics/PixmapDiagram.py Graphics/__init__.py Graphics/GraphicsUtilities.py Project/ProjectResourcesBrowser.py Preferences/ToolGroupConfigurationDialog.py VCS/StatusMonitorThread.py DocumentationTools/Config.py Preferences/ConfigurationPages/CorbaPage.py Preferences/ConfigurationPages/ApplicationPage.py Preferences/ConfigurationPages/EmailPage.py Preferences/ConfigurationPages/IconsPage.py Preferences/ConfigurationPages/IconsPreviewDialog.py Preferences/ConfigurationPages/PrinterPage.py Preferences/ConfigurationPages/PythonPage.py Preferences/ConfigurationPages/QtPage.py Preferences/ConfigurationPages/ShellPage.py Preferences/ConfigurationPages/TasksPage.py Preferences/ConfigurationPages/TemplatesPage.py Preferences/ConfigurationPages/VcsPage.py Preferences/ConfigurationPages/ViewmanagerPage.py Preferences/ConfigurationPages/HelpDocumentationPage.py Preferences/ConfigurationPages/HelpViewersPage.py Preferences/ConfigurationPages/ProjectBrowserPage.py Preferences/ConfigurationPages/ProjectPage.py Preferences/ConfigurationPages/DebuggerPythonPage.py Preferences/ConfigurationPages/DebuggerRubyPage.py Preferences/ConfigurationPages/EditorAPIsPage.py Preferences/ConfigurationPages/EditorAutocompletionPage.py Preferences/ConfigurationPages/EditorCalltipsPage.py Preferences/ConfigurationPages/EditorGeneralPage.py Preferences/ConfigurationPages/EditorHighlightersPage.py Preferences/ConfigurationPages/EditorHighlightingStylesPage.py Tasks/TaskFilterConfigDialog.py QScintilla/Printer.py QScintilla/QsciScintillaCompat.py QScintilla/Editor.py QScintilla/Shell.py Tools/TrayStarter.py Globals/__init__.py Preferences/ConfigurationPages/ConfigurationPageBase.py Project/TranslationPropertiesDialog.py Project/UserPropertiesDialog.py Preferences/ConfigurationPages/GraphicsPage.py QScintilla/APIsManager.py Graphics/AssociationItem.py Graphics/ClassItem.py Graphics/UMLGraphicsView.py Graphics/UMLItem.py Graphics/UMLSceneSizeDialog.py Graphics/UMLDialog.py Graphics/PackageItem.py Graphics/ModuleItem.py Debugger/DebuggerInterfacePython.py Debugger/DebuggerInterfaceRuby.py Debugger/DebuggerInterfaceNone.py Debugger/DebugClientCapabilities.py Debugger/DebugProtocol.py Preferences/ProgramsDialog.py Project/CreateDialogCodeDialog.py Project/NewDialogClassDialog.py Preferences/ConfigurationPages/EditorTypingPage.py QScintilla/Lexers/__init__.py QScintilla/Lexers/Lexer.py QScintilla/Lexers/LexerBash.py QScintilla/Lexers/LexerBatch.py QScintilla/Lexers/LexerCPP.py QScintilla/Lexers/LexerCSS.py QScintilla/Lexers/LexerCSharp.py QScintilla/Lexers/LexerD.py QScintilla/Lexers/LexerDiff.py QScintilla/Lexers/LexerHTML.py QScintilla/Lexers/LexerIDL.py QScintilla/Lexers/LexerJava.py QScintilla/Lexers/LexerJavaScript.py QScintilla/Lexers/LexerLua.py QScintilla/Lexers/LexerMakefile.py QScintilla/Lexers/LexerPOV.py QScintilla/Lexers/LexerPerl.py QScintilla/Lexers/LexerProperties.py QScintilla/Lexers/LexerPython.py QScintilla/Lexers/LexerRuby.py QScintilla/Lexers/LexerSQL.py QScintilla/Lexers/LexerTeX.py QScintilla/TypingCompleters/__init__.py QScintilla/TypingCompleters/CompleterBase.py QScintilla/TypingCompleters/CompleterPython.py QScintilla/Lexers/LexerVHDL.py QScintilla/Lexers/LexerCMake.py QScintilla/TypingCompleters/CompleterRuby.py VCS/StatusMonitorLed.py PluginManager/__init__.py PluginManager/PluginManager.py PluginManager/PluginExceptions.py Plugins/__init__.py Plugins/PluginAbout.py Plugins/PluginVmTabview.py Plugins/PluginVmListspace.py PluginManager/PluginInfoDialog.py PluginManager/PluginDetailsDialog.py Plugins/PluginTabnanny.py Plugins/PluginSyntaxChecker.py Plugins/PluginEricapi.py Plugins/PluginEricdoc.py Plugins/DocumentationPlugins/__init__.py Plugins/DocumentationPlugins/Ericdoc/__init__.py Plugins/DocumentationPlugins/Ericapi/__init__.py Plugins/DocumentationPlugins/Ericapi/EricapiConfigDialog.py Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.py Plugins/DocumentationPlugins/Ericapi/EricapiExecDialog.py Plugins/DocumentationPlugins/Ericdoc/EricdocExecDialog.py PluginManager/PluginInstallDialog.py PluginManager/PluginUninstallDialog.py Plugins/VcsPlugins/__init__.py Plugins/PluginVcsSubversion.py Plugins/PluginVcsPySvn.py Plugins/VcsPlugins/vcsSubversion/subversion.py Plugins/VcsPlugins/vcsSubversion/__init__.py Plugins/VcsPlugins/vcsSubversion/ProjectHelper.py Plugins/VcsPlugins/vcsSubversion/ProjectBrowserHelper.py Plugins/VcsPlugins/vcsSubversion/SvnDialog.py Plugins/VcsPlugins/vcsSubversion/SvnNewProjectOptionsDialog.py Plugins/VcsPlugins/vcsSubversion/Config.py Plugins/VcsPlugins/vcsSubversion/SvnCommitDialog.py Plugins/VcsPlugins/vcsSubversion/SvnTagDialog.py Plugins/VcsPlugins/vcsSubversion/SvnSwitchDialog.py Plugins/VcsPlugins/vcsSubversion/SvnMergeDialog.py Plugins/VcsPlugins/vcsSubversion/SvnOptionsDialog.py Plugins/VcsPlugins/vcsSubversion/SvnCommandDialog.py Plugins/VcsPlugins/vcsSubversion/SvnTagBranchListDialog.py Plugins/VcsPlugins/vcsSubversion/SvnCopyDialog.py Plugins/VcsPlugins/vcsSubversion/SvnRevisionSelectionDialog.py Plugins/VcsPlugins/vcsSubversion/SvnStatusDialog.py Plugins/VcsPlugins/vcsSubversion/SvnDiffDialog.py Plugins/VcsPlugins/vcsSubversion/SvnLogDialog.py Plugins/VcsPlugins/vcsSubversion/SvnPropSetDialog.py Plugins/VcsPlugins/vcsSubversion/SvnPropListDialog.py Plugins/VcsPlugins/vcsSubversion/SvnBlameDialog.py Plugins/VcsPlugins/vcsSubversion/SvnStatusMonitorThread.py Plugins/VcsPlugins/vcsSubversion/SvnUrlSelectionDialog.py Plugins/VcsPlugins/vcsPySvn/subversion.py Plugins/VcsPlugins/vcsPySvn/__init__.py Plugins/VcsPlugins/vcsPySvn/SvnStatusMonitorThread.py Plugins/VcsPlugins/vcsPySvn/ProjectBrowserHelper.py Plugins/VcsPlugins/vcsPySvn/ProjectHelper.py Plugins/VcsPlugins/vcsPySvn/SvnLoginDialog.py Plugins/VcsPlugins/vcsPySvn/SvnDialog.py Plugins/VcsPlugins/vcsPySvn/SvnNewProjectOptionsDialog.py Plugins/VcsPlugins/vcsPySvn/SvnOptionsDialog.py Plugins/VcsPlugins/vcsPySvn/Config.py Plugins/VcsPlugins/vcsPySvn/SvnCommitDialog.py Plugins/VcsPlugins/vcsPySvn/SvnTagDialog.py Plugins/VcsPlugins/vcsPySvn/SvnSwitchDialog.py Plugins/VcsPlugins/vcsPySvn/SvnMergeDialog.py Plugins/VcsPlugins/vcsPySvn/SvnDialogMixin.py Plugins/VcsPlugins/vcsPySvn/SvnPropSetDialog.py Plugins/VcsPlugins/vcsPySvn/SvnCopyDialog.py Plugins/VcsPlugins/vcsPySvn/SvnPropDelDialog.py Plugins/VcsPlugins/vcsPySvn/SvnRevisionSelectionDialog.py Plugins/VcsPlugins/vcsPySvn/SvnPropListDialog.py Plugins/VcsPlugins/vcsPySvn/SvnTagBranchListDialog.py Plugins/VcsPlugins/vcsPySvn/SvnLogDialog.py Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.py Plugins/VcsPlugins/vcsPySvn/SvnUtilities.py Plugins/VcsPlugins/vcsPySvn/SvnConst.py Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py Plugins/VcsPlugins/vcsPySvn/SvnBlameDialog.py Plugins/VcsPlugins/vcsPySvn/SvnCommandDialog.py Plugins/VcsPlugins/vcsPySvn/SvnInfoDialog.py Plugins/VcsPlugins/vcsPySvn/SvnRelocateDialog.py Plugins/VcsPlugins/vcsPySvn/SvnUrlSelectionDialog.py Plugins/AboutPlugin/__init__.py Plugins/AboutPlugin/AboutDialog.py Plugins/CheckerPlugins/__init__.py Plugins/CheckerPlugins/Tabnanny/__init__.py Plugins/CheckerPlugins/SyntaxChecker/__init__.py Plugins/CheckerPlugins/Tabnanny/Tabnanny.py Plugins/CheckerPlugins/Tabnanny/TabnannyDialog.py Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py Plugins/ViewManagerPlugins/__init__.py Plugins/ViewManagerPlugins/Tabview/__init__.py Plugins/ViewManagerPlugins/Listspace/__init__.py Plugins/ViewManagerPlugins/Tabview/Tabview.py Plugins/ViewManagerPlugins/Listspace/Listspace.py Plugins/WizardPlugins/__init__.py Plugins/WizardPlugins/ColorDialogWizard/ColorDialogWizardDialog.py Plugins/WizardPlugins/ColorDialogWizard/__init__.py Plugins/PluginWizardQColorDialog.py Plugins/WizardPlugins/FileDialogWizard/FileDialogWizardDialog.py Plugins/WizardPlugins/FileDialogWizard/__init__.py Plugins/PluginWizardQFileDialog.py Plugins/WizardPlugins/FontDialogWizard/FontDialogWizardDialog.py Plugins/WizardPlugins/FontDialogWizard/__init__.py Plugins/PluginWizardQFontDialog.py Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.py Plugins/WizardPlugins/InputDialogWizard/__init__.py Plugins/PluginWizardQInputDialog.py Plugins/WizardPlugins/MessageBoxWizard/MessageBoxWizardDialog.py Plugins/WizardPlugins/MessageBoxWizard/__init__.py Plugins/PluginWizardQMessageBox.py Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardDialog.py Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardCharactersDialog.py Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardRepeatDialog.py Plugins/WizardPlugins/QRegExpWizard/__init__.py Plugins/WizardPlugins/PyRegExpWizard/__init__.py Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardCharactersDialog.py Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardRepeatDialog.py Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.py Plugins/PluginWizardQRegExp.py Plugins/PluginWizardPyRegExp.py Project/NewPythonPackageDialog.py QScintilla/Exporters/__init__.py QScintilla/Exporters/ExporterHTML.py QScintilla/Exporters/ExporterBase.py Preferences/ConfigurationPages/EditorExportersPage.py QScintilla/Exporters/ExporterRTF.py QScintilla/Exporters/ExporterPDF.py QScintilla/Exporters/ExporterTEX.py DebugClients/Python/DebugConfig.py Preferences/ConfigurationPages/PluginManagerPage.py PluginManager/PluginRepositoryDialog.py Plugins/VcsPlugins/vcsPySvn/SvnRepoBrowserDialog.py Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.py Plugins/VcsPlugins/vcsPySvn/SvnLogBrowserDialog.py Plugins/VcsPlugins/vcsSubversion/SvnLogBrowserDialog.py Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.py Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/__init__.py Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/__init__.py Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.py Plugins/VcsPlugins/vcsSubversion/SvnUtilities.py QScintilla/MiniEditor.py MultiProject/__init__.py MultiProject/MultiProject.py MultiProject/PropertiesDialog.py MultiProject/AddProjectDialog.py MultiProject/MultiProjectBrowser.py Preferences/ConfigurationPages/MultiProjectPage.py QScintilla/Lexers/LexerTCL.py Graphics/SvgDiagram.py Project/ProjectBrowserFlags.py Preferences/ConfigurationPages/EditorFilePage.py Preferences/ConfigurationPages/EditorSearchPage.py Plugins/VcsPlugins/vcsSubversion/SvnRelocateDialog.py Helpviewer/HelpBrowserWV.py UI/AuthenticationDialog.py QScintilla/ShellHistoryDialog.py Preferences/ConfigurationPages/HelpAppearancePage.py Preferences/ConfigurationPages/EditorAutocompletionQScintillaPage.py Preferences/ConfigurationPages/EditorCalltipsQScintillaPage.py Preferences/ConfigurationPages/EditorPropertiesPage.py Preferences/ConfigurationPages/EditorStylesPage.py Preferences/ConfigurationPages/DebuggerGeneralPage.py Preferences/ConfigurationPages/InterfacePage.py QScintilla/Lexers/LexerPascal.py QScintilla/Lexers/LexerFortran.py QScintilla/Lexers/LexerFortran77.py QScintilla/Lexers/LexerXML.py QScintilla/Lexers/LexerPostScript.py QScintilla/Lexers/LexerYAML.py QScintilla/SearchReplaceWidget.py ThirdParty/__init__.py ThirdParty/CharDet/__init__.py ThirdParty/CharDet/chardet/gb2312freq.py ThirdParty/CharDet/chardet/langthaimodel.py ThirdParty/CharDet/chardet/escsm.py ThirdParty/CharDet/chardet/sjisprober.py ThirdParty/CharDet/chardet/mbcsgroupprober.py ThirdParty/CharDet/chardet/jpcntx.py ThirdParty/CharDet/chardet/big5freq.py ThirdParty/CharDet/chardet/euckrfreq.py ThirdParty/CharDet/chardet/jisfreq.py ThirdParty/CharDet/chardet/langcyrillicmodel.py ThirdParty/CharDet/chardet/universaldetector.py ThirdParty/CharDet/chardet/sbcsgroupprober.py ThirdParty/CharDet/chardet/chardistribution.py ThirdParty/CharDet/chardet/langgreekmodel.py ThirdParty/CharDet/chardet/codingstatemachine.py ThirdParty/CharDet/chardet/hebrewprober.py ThirdParty/CharDet/chardet/langbulgarianmodel.py ThirdParty/CharDet/chardet/big5prober.py ThirdParty/CharDet/chardet/euctwprober.py ThirdParty/CharDet/chardet/euckrprober.py ThirdParty/CharDet/chardet/constants.py ThirdParty/CharDet/chardet/euctwfreq.py ThirdParty/CharDet/chardet/langhungarianmodel.py ThirdParty/CharDet/chardet/latin1prober.py ThirdParty/CharDet/chardet/utf8prober.py ThirdParty/CharDet/chardet/escprober.py ThirdParty/CharDet/chardet/sbcharsetprober.py ThirdParty/CharDet/chardet/charsetprober.py ThirdParty/CharDet/chardet/charsetgroupprober.py ThirdParty/CharDet/chardet/mbcssm.py ThirdParty/CharDet/chardet/gb2312prober.py ThirdParty/CharDet/chardet/__init__.py ThirdParty/CharDet/chardet/langhebrewmodel.py ThirdParty/CharDet/chardet/mbcharsetprober.py ThirdParty/CharDet/chardet/eucjpprober.py ThirdParty/CharDet/chardet/chardetect.py ThirdParty/CharDet/chardet/compat.py ThirdParty/CharDet/chardet/cp949prober.py Preferences/ConfigurationPages/NetworkPage.py QScintilla/Lexers/LexerContainer.py QScintilla/Lexers/LexerPygments.py QScintilla/SpellChecker.py Preferences/ConfigurationPages/EditorSpellCheckingPage.py QScintilla/SpellCheckingDialog.py Project/SpellingPropertiesDialog.py Project/LexerAssociationDialog.py ThirdParty/Pygments/__init__.py ThirdParty/Pygments/pygments/style.py ThirdParty/Pygments/pygments/scanner.py ThirdParty/Pygments/pygments/cmdline.py ThirdParty/Pygments/pygments/filter.py ThirdParty/Pygments/pygments/console.py ThirdParty/Pygments/pygments/unistring.py ThirdParty/Pygments/pygments/lexer.py ThirdParty/Pygments/pygments/token.py ThirdParty/Pygments/pygments/util.py ThirdParty/Pygments/pygments/formatter.py ThirdParty/Pygments/pygments/__init__.py ThirdParty/Pygments/pygments/plugin.py ThirdParty/Pygments/pygments/filters/__init__.py ThirdParty/Pygments/pygments/lexers/agile.py ThirdParty/Pygments/pygments/lexers/_mapping.py ThirdParty/Pygments/pygments/lexers/functional.py ThirdParty/Pygments/pygments/lexers/compiled.py ThirdParty/Pygments/pygments/lexers/_clbuiltins.py ThirdParty/Pygments/pygments/lexers/other.py ThirdParty/Pygments/pygments/lexers/math.py ThirdParty/Pygments/pygments/lexers/special.py ThirdParty/Pygments/pygments/lexers/text.py ThirdParty/Pygments/pygments/lexers/asm.py ThirdParty/Pygments/pygments/lexers/_vimbuiltins.py ThirdParty/Pygments/pygments/lexers/_phpbuiltins.py ThirdParty/Pygments/pygments/lexers/web.py ThirdParty/Pygments/pygments/lexers/templates.py ThirdParty/Pygments/pygments/lexers/dotnet.py ThirdParty/Pygments/pygments/lexers/_luabuiltins.py ThirdParty/Pygments/pygments/lexers/__init__.py ThirdParty/Pygments/pygments/formatters/_mapping.py ThirdParty/Pygments/pygments/formatters/terminal.py ThirdParty/Pygments/pygments/formatters/other.py ThirdParty/Pygments/pygments/formatters/bbcode.py ThirdParty/Pygments/pygments/formatters/terminal256.py ThirdParty/Pygments/pygments/formatters/img.py ThirdParty/Pygments/pygments/formatters/rtf.py ThirdParty/Pygments/pygments/formatters/svg.py ThirdParty/Pygments/pygments/formatters/html.py ThirdParty/Pygments/pygments/formatters/__init__.py ThirdParty/Pygments/pygments/formatters/latex.py ThirdParty/Pygments/pygments/styles/native.py ThirdParty/Pygments/pygments/styles/bw.py ThirdParty/Pygments/pygments/styles/vs.py ThirdParty/Pygments/pygments/styles/emacs.py ThirdParty/Pygments/pygments/styles/colorful.py ThirdParty/Pygments/pygments/styles/pastie.py ThirdParty/Pygments/pygments/styles/murphy.py ThirdParty/Pygments/pygments/styles/perldoc.py ThirdParty/Pygments/pygments/styles/manni.py ThirdParty/Pygments/pygments/styles/borland.py ThirdParty/Pygments/pygments/styles/trac.py ThirdParty/Pygments/pygments/styles/default.py ThirdParty/Pygments/pygments/styles/vim.py ThirdParty/Pygments/pygments/styles/autumn.py ThirdParty/Pygments/pygments/styles/__init__.py ThirdParty/Pygments/pygments/styles/fruity.py ThirdParty/Pygments/pygments/styles/friendly.py ThirdParty/Pygments/pygments/styles/tango.py DocumentationTools/QtHelpGenerator.py Helpviewer/HelpTocWidget.py Helpviewer/QtHelpDocumentationDialog.py Helpviewer/QtHelpFiltersDialog.py Helpviewer/HelpIndexWidget.py Helpviewer/HelpTopicDialog.py Helpviewer/HelpSearchWidget.py Helpviewer/HelpDocsInstaller.py DebugClients/Python/coverage/data.py DebugClients/Python/coverage/cmdline.py DebugClients/Python/coverage/collector.py DebugClients/Python/coverage/misc.py DebugClients/Python/coverage/control.py DebugClients/Python/coverage/__init__.py Debugger/DebuggerInterfacePython3.py Preferences/ConfigurationPages/DebuggerPython3Page.py DebugClients/Python3/AsyncFile.py DebugClients/Python3/__init__.py DebugClients/Python3/DebugProtocol.py DebugClients/Python3/AsyncIO.py DebugClients/Python3/DebugClientCapabilities.py DebugClients/Python3/DebugConfig.py DebugClients/Python3/getpass.py DebugClients/Python3/DebugBase.py DebugClients/Python3/DebugClientBase.py DebugClients/Python3/DebugClient.py DebugClients/Python3/FlexCompleter.py DebugClients/Python3/PyProfile.py DebugClients/Python3/DebugThread.py DebugClients/Python3/DebugClientThreads.py DebugClients/Python3/DCTestResult.py Helpviewer/HelpWebSearchWidget.py Helpviewer/HelpClearPrivateDataDialog.py Helpviewer/HelpLanguagesDialog.py DebugClients/Python/coverage/html.py DebugClients/Python/coverage/report.py DebugClients/Python/coverage/templite.py DebugClients/Python/coverage/codeunit.py DebugClients/Python/coverage/summary.py DebugClients/Python/coverage/files.py DebugClients/Python/coverage/annotate.py DebugClients/Python/coverage/parser.py DebugClients/Python/coverage/execfile.py Helpviewer/CookieJar/__init__.py Helpviewer/CookieJar/CookiesExceptionsDialog.py Helpviewer/CookieJar/CookieModel.py Helpviewer/CookieJar/CookiesDialog.py Helpviewer/CookieJar/CookieJar.py Helpviewer/CookieJar/CookiesConfigurationDialog.py Helpviewer/CookieJar/CookieExceptionsModel.py Helpviewer/CookieJar/CookieDetailsDialog.py Helpviewer/OpenSearch/__init__.py Helpviewer/OpenSearch/OpenSearchEngineAction.py Helpviewer/OpenSearch/OpenSearchManager.py Helpviewer/OpenSearch/OpenSearchEngine.py Helpviewer/OpenSearch/OpenSearchReader.py Helpviewer/OpenSearch/OpenSearchWriter.py Helpviewer/OpenSearch/OpenSearchDialog.py Helpviewer/OpenSearch/OpenSearchEngineModel.py SqlBrowser/__init__.py SqlBrowser/SqlConnectionWidget.py SqlBrowser/SqlBrowserWidget.py SqlBrowser/SqlBrowser.py SqlBrowser/SqlConnectionDialog.py Helpviewer/Bookmarks/__init__.py Helpviewer/Bookmarks/BookmarkNode.py Helpviewer/Bookmarks/XbelWriter.py Helpviewer/Bookmarks/XbelReader.py Helpviewer/Bookmarks/BookmarksModel.py Utilities/AutoSaver.py Helpviewer/Bookmarks/BookmarksManager.py Helpviewer/Bookmarks/BookmarksMenu.py Helpviewer/Bookmarks/BookmarksToolBar.py Helpviewer/Bookmarks/AddBookmarkDialog.py Helpviewer/Bookmarks/BookmarksDialog.py Preferences/ConfigurationPages/HelpWebBrowserPage.py Helpviewer/JavaScriptResources.py Helpviewer/SearchWidget.py Helpviewer/History/__init__.py Helpviewer/History/HistoryManager.py Helpviewer/History/HistoryModel.py Helpviewer/History/HistoryFilterModel.py Helpviewer/History/HistoryTreeModel.py Helpviewer/History/HistoryMenu.py Helpviewer/History/HistoryDialog.py Helpviewer/History/HistoryCompleter.py IconEditor/__init__.py IconEditor/IconSizeDialog.py IconEditor/cursors/cursors_rc.py IconEditor/cursors/__init__.py IconEditor/IconEditorGrid.py IconEditor/IconEditorWindow.py IconEditor/IconEditorPalette.py DebugClients/Python/coverage/backward.py DebugClients/Python3/coverage/__init__.py DebugClients/Python3/coverage/annotate.py DebugClients/Python3/coverage/backward.py DebugClients/Python3/coverage/cmdline.py DebugClients/Python3/coverage/codeunit.py DebugClients/Python3/coverage/collector.py DebugClients/Python3/coverage/control.py DebugClients/Python3/coverage/data.py DebugClients/Python3/coverage/execfile.py DebugClients/Python3/coverage/files.py DebugClients/Python3/coverage/html.py DebugClients/Python3/coverage/misc.py DebugClients/Python3/coverage/parser.py DebugClients/Python3/coverage/report.py DebugClients/Python3/coverage/summary.py DebugClients/Python3/coverage/templite.py ThirdParty/Pygments/pygments/lexers/parsers.py Helpviewer/Passwords/__init__.py Helpviewer/Passwords/PasswordManager.py Helpviewer/Passwords/PasswordModel.py Helpviewer/Passwords/PasswordsDialog.py Utilities/uic.py Helpviewer/Network/__init__.py Helpviewer/Network/SchemeAccessHandler.py Helpviewer/Network/NetworkReply.py Helpviewer/Network/NetworkProtocolUnknownErrorReply.py Helpviewer/Network/NetworkDiskCache.py Helpviewer/Network/NetworkAccessManagerProxy.py Helpviewer/Network/NetworkAccessManager.py Helpviewer/Network/QtHelpAccessHandler.py Helpviewer/Network/AboutAccessHandler.py Helpviewer/AdBlock/__init__.py Helpviewer/AdBlock/AdBlockSubscription.py Helpviewer/AdBlock/AdBlockRule.py Helpviewer/AdBlock/AdBlockBlockedNetworkReply.py Helpviewer/AdBlock/AdBlockManager.py Helpviewer/AdBlock/AdBlockAccessHandler.py Helpviewer/AdBlock/AdBlockDialog.py Helpviewer/AdBlock/AdBlockNetwork.py Helpviewer/AdBlock/AdBlockPage.py compileUiFiles.py Helpviewer/OpenSearch/OpenSearchEditDialog.py DebugClients/Python3/coverage/bytecode.py DebugClients/Python3/coverage/xmlreport.py DebugClients/Python3/coverage/phystokens.py DebugClients/Python3/coverage/results.py DebugClients/Python/coverage/bytecode.py DebugClients/Python/coverage/xmlreport.py DebugClients/Python/coverage/phystokens.py DebugClients/Python/coverage/results.py E5XML/ProjectWriter.py E5XML/SessionWriter.py E5XML/ShortcutsWriter.py E5XML/DebuggerPropertiesWriter.py E5XML/TemplatesWriter.py E5XML/Config.py E5XML/__init__.py E5XML/TasksWriter.py E5XML/UserProjectWriter.py E5XML/MultiProjectWriter.py E5XML/HighlightingStylesWriter.py E5Graphics/__init__.py E5Graphics/E5ArrowItem.py E5Graphics/E5GraphicsView.py E5Network/__init__.py E5Network/E5NetworkMonitor.py E5Network/E5NetworkHeaderDetailsDialog.py E5Gui/__init__.py E5Gui/E5ToolBarDialog.py E5Gui/E5Action.py E5Gui/E5Application.py E5Gui/E5Completers.py E5Gui/E5Led.py E5Gui/E5LineEdit.py E5Gui/E5ListView.py E5Gui/E5ModelMenu.py E5Gui/E5ModelToolBar.py E5Gui/E5SideBar.py E5Gui/E5SingleApplication.py E5Gui/E5SqueezeLabels.py E5Gui/E5TabWidget.py E5Gui/E5TableView.py E5Gui/E5ToolBarManager.py E5Gui/E5ToolBox.py E5Gui/E5TreeSortFilterProxyModel.py E5Gui/E5TreeView.py Preferences/ConfigurationPages/EditorKeywordsPage.py Cooperation/__init__.py Cooperation/Connection.py Cooperation/ChatWidget.py Cooperation/CooperationClient.py Cooperation/CooperationServer.py Preferences/ConfigurationPages/CooperationPage.py Plugins/PluginVcsMercurial.py Plugins/VcsPlugins/vcsMercurial/__init__.py Plugins/VcsPlugins/vcsMercurial/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/hg.py Plugins/VcsPlugins/vcsMercurial/HgOptionsDialog.py Plugins/VcsPlugins/vcsMercurial/HgDialog.py Plugins/VcsPlugins/vcsMercurial/ProjectBrowserHelper.py Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.py Plugins/VcsPlugins/vcsMercurial/Config.py Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py Plugins/VcsPlugins/vcsMercurial/HgUtilities.py Plugins/VcsPlugins/vcsMercurial/HgCopyDialog.py Plugins/VcsPlugins/vcsMercurial/HgLogDialog.py Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.py Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/__init__.py Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.py Plugins/VcsPlugins/vcsMercurial/HgStatusMonitorThread.py Plugins/VcsPlugins/vcsMercurial/HgStatusDialog.py Plugins/VcsPlugins/vcsMercurial/HgAnnotateDialog.py Plugins/VcsPlugins/vcsMercurial/HgTagDialog.py Plugins/VcsPlugins/vcsMercurial/HgTagBranchListDialog.py Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.py Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.py Plugins/VcsPlugins/vcsMercurial/HgCommandDialog.py Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.py Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.py E5Network/E5NetworkProxyFactory.py Helpviewer/Network/FtpAccessHandler.py Helpviewer/Network/FtpReply.py Plugins/VcsPlugins/vcsMercurial/HgServeDialog.py Helpviewer/OfflineStorage/OfflineStorageConfigDialog.py Helpviewer/OfflineStorage/__init__.py Helpviewer/OfflineStorage/WebDatabasesModel.py Helpviewer/OfflineStorage/WebDatabasesDialog.py UI/SymbolsWidget.py UI/NumbersWidget.py E5Gui/E5TextSpinBox.py Helpviewer/UserAgent/__init__.py Helpviewer/UserAgent/UserAgentMenu.py E5Gui/E5FileDialog.py QScintilla/Exporters/ExporterODT.py E5Gui/E5MessageBox.py Plugins/WizardPlugins/E5MessageBoxWizard/__init__.py Plugins/WizardPlugins/E5MessageBoxWizard/E5MessageBoxWizardDialog.py Plugins/PluginWizardE5MessageBox.py E5XML/XMLStreamWriterBase.py E5XML/XMLStreamReaderBase.py E5XML/PluginRepositoryReader.py E5XML/TasksReader.py E5XML/TemplatesReader.py E5XML/HighlightingStylesReader.py E5XML/ShortcutsReader.py E5XML/SessionReader.py E5XML/MultiProjectReader.py E5XML/UserProjectReader.py E5XML/DebuggerPropertiesReader.py E5XML/ProjectReader.py E5Gui/E5PassivePopup.py Helpviewer/HelpTabBar.py Helpviewer/HelpSnap.py Helpviewer/HelpTabWidget.py E5Gui/E5LineEditButton.py Helpviewer/UrlBar/__init__.py Helpviewer/UrlBar/UrlBar.py Helpviewer/UrlBar/FavIconLabel.py Helpviewer/UrlBar/StackedUrlBar.py Helpviewer/UrlBar/SslLabel.py Helpviewer/UrlBar/BookmarkInfoDialog.py Helpviewer/Download/__init__.py Helpviewer/Download/DownloadItem.py Helpviewer/Download/DownloadUtilities.py Helpviewer/Download/DownloadManager.py Helpviewer/Download/DownloadModel.py ThirdParty/Pygments/pygments/lexers/_asybuiltins.py ThirdParty/Pygments/pygments/styles/monokai.py Preferences/ConfigurationPages/TrayStarterPage.py ThirdParty/Pygments/pygments/lexers/hdl.py Helpviewer/VirusTotalApi.py Preferences/ConfigurationPages/HelpVirusTotalPage.py Helpviewer/Download/DownloadAskActionDialog.py QScintilla/Lexers/LexerMatlab.py QScintilla/Lexers/LexerOctave.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/__init__.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/queues.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesNewPatchDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesRenamePatchDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesFoldDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesHeaderDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListGuardsDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListAllGuardsDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesDefineGuardsDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesGuardsSelectionDialog.py Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesQueueManagementDialog.py Plugins/VcsPlugins/vcsMercurial/FetchExtension/__init__.py Plugins/VcsPlugins/vcsMercurial/FetchExtension/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/FetchExtension/fetch.py Plugins/VcsPlugins/vcsMercurial/FetchExtension/HgFetchDialog.py Plugins/VcsPlugins/vcsMercurial/PurgeExtension/__init__.py Plugins/VcsPlugins/vcsMercurial/PurgeExtension/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/PurgeExtension/purge.py Plugins/VcsPlugins/vcsMercurial/PurgeExtension/HgPurgeListDialog.py Plugins/VcsPlugins/vcsMercurial/GpgExtension/__init__.py Plugins/VcsPlugins/vcsMercurial/GpgExtension/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/GpgExtension/gpg.py Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignaturesDialog.py Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignDialog.py Plugins/VcsPlugins/vcsMercurial/TransplantExtension/__init__.py Plugins/VcsPlugins/vcsMercurial/TransplantExtension/transplant.py Plugins/VcsPlugins/vcsMercurial/TransplantExtension/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/TransplantExtension/TransplantDialog.py Plugins/VcsPlugins/vcsMercurial/HgExtension.py Plugins/VcsPlugins/vcsMercurial/HgExtensionProjectHelper.py Plugins/VcsPlugins/vcsMercurial/RebaseExtension/__init__.py Plugins/VcsPlugins/vcsMercurial/RebaseExtension/rebase.py Plugins/VcsPlugins/vcsMercurial/RebaseExtension/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/RebaseExtension/HgRebaseDialog.py Utilities/PasswordChecker.py E5Gui/E5PasswordMeter.py Preferences/ConfigurationPages/MasterPasswordEntryDialog.py Utilities/crypto/__init__.py Utilities/crypto/py3AES.py Utilities/crypto/py3PBKDF2.py Preferences/ConfigurationPages/SecurityPage.py Plugins/VcsPlugins/vcsMercurial/HgClient.py Plugins/VcsPlugins/vcsMercurial/HgMultiRevisionSelectionDialog.py Plugins/VcsPlugins/vcsMercurial/HgImportDialog.py Plugins/VcsPlugins/vcsMercurial/HgExportDialog.py Plugins/VcsPlugins/vcsMercurial/HgClientPromptDialog.py Preferences/ConfigurationPages/EditorSyntaxPage.py QScintilla/EditorAssembly.py Helpviewer/Feeds/FeedsDialog.py Helpviewer/Feeds/__init__.py Helpviewer/Feeds/FeedsManager.py Helpviewer/Feeds/FeedEditDialog.py Helpviewer/SiteInfo/__init__.py Helpviewer/SiteInfo/SiteInfoDialog.py Helpviewer/UserAgent/UserAgentsDialog.py Helpviewer/UserAgent/UserAgentModel.py Helpviewer/UserAgent/UserAgentManager.py Plugins/VcsPlugins/vcsMercurial/HgPhaseDialog.py Helpviewer/PageScreenDialog.py Helpviewer/Sync/__init__.py Helpviewer/Sync/SyncHandler.py Helpviewer/Sync/SyncManager.py Helpviewer/Sync/SyncAssistantDialog.py Helpviewer/Sync/SyncDataPage.py Helpviewer/Sync/SyncHostTypePage.py Helpviewer/Sync/SyncFtpSettingsPage.py Helpviewer/Sync/SyncCheckPage.py Helpviewer/Sync/FtpSyncHandler.py Helpviewer/Sync/SyncGlobals.py Helpviewer/WebPlugins/__init__.py Helpviewer/WebPlugins/WebPluginInterface.py Helpviewer/WebPlugins/WebPluginFactory.py Helpviewer/WebPlugins/ClickToFlash/__init__.py Helpviewer/WebPlugins/ClickToFlash/ClickToFlashPlugin.py Helpviewer/WebPlugins/ClickToFlash/ClickToFlash.py Helpviewer/WebPlugins/ClickToFlash/ClickToFlashWhitelistDialog.py Plugins/VcsPlugins/vcsMercurial/HgGraftDialog.py Helpviewer/data/__init__.py Helpviewer/data/icons_rc.py Helpviewer/data/html_rc.py Helpviewer/SpeedDial/__init__.py Helpviewer/SpeedDial/SpeedDial.py Helpviewer/data/javascript_rc.py Helpviewer/SpeedDial/PageThumbnailer.py Helpviewer/UrlBar/BookmarkActionSelectionDialog.py Helpviewer/Network/EricAccessHandler.py Helpviewer/Sync/SyncEncryptionPage.py Helpviewer/Passwords/PasswordWriter.py Helpviewer/Passwords/PasswordReader.py Helpviewer/Passwords/LoginForm.py Helpviewer/UserAgent/UserAgentWriter.py Helpviewer/UserAgent/UserAgentReader.py Helpviewer/ClosedTabsManager.py Helpviewer/Sync/SyncDirectorySettingsPage.py Helpviewer/Sync/DirectorySyncHandler.py Helpviewer/SpeedDial/Page.py Helpviewer/SpeedDial/SpeedDialWriter.py Helpviewer/SpeedDial/SpeedDialReader.py ThirdParty/Pygments/pygments/lexers/sql.py ThirdParty/Pygments/pygments/lexers/_postgres_builtins.py ThirdParty/Pygments/pygments/lexers/jvm.py ThirdParty/Pygments/pygments/lexers/_scilab_builtins.py ThirdParty/Pygments/pygments/lexers/shell.py ThirdParty/Pygments/pygments/styles/rrt.py Helpviewer/Bookmarks/BookmarksImportDialog.py Helpviewer/Bookmarks/BookmarksImporters/__init__.py Helpviewer/Bookmarks/BookmarksImporters/XbelImporter.py Helpviewer/Bookmarks/BookmarksImporters/HtmlImporter.py Helpviewer/Bookmarks/BookmarksImporters/BookmarksImporter.py Helpviewer/Bookmarks/BookmarksImporters/ChromeImporter.py Helpviewer/Bookmarks/BookmarksImporters/OperaImporter.py Helpviewer/Bookmarks/BookmarksImporters/FirefoxImporter.py Helpviewer/Bookmarks/BookmarksImporters/IExplorerImporter.py Utilities/binplistlib.py Helpviewer/Bookmarks/BookmarksImporters/SafariImporter.py UI/ErrorLogDialog.py Helpviewer/Bookmarks/NsHtmlWriter.py Helpviewer/Bookmarks/NsHtmlReader.py Helpviewer/Bookmarks/BookmarkPropertiesDialog.py Snapshot/__init__.py Snapshot/SnapWidget.py Snapshot/SnapshotRegionGrabber.py Snapshot/SnapshotPreview.py Snapshot/SnapshotTimer.py Snapshot/SnapshotFreehandGrabber.py Tasks/Task.py Tasks/TaskFilter.py UI/SearchWidget.py Plugins/VcsPlugins/vcsPySvn/SvnChangeListsDialog.py Plugins/VcsPlugins/vcsSubversion/SvnChangeListsDialog.py Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.py Plugins/VcsPlugins/vcsMercurial/HgRemoveSubrepositoriesDialog.py Helpviewer/Network/SendRefererWhitelistDialog.py Helpviewer/PersonalInformationManager/__init__.py Helpviewer/PersonalInformationManager/PersonalDataDialog.py Helpviewer/PersonalInformationManager/PersonalInformationManager.py Helpviewer/GreaseMonkey/__init__.py Helpviewer/GreaseMonkey/GreaseMonkeyJavaScript.py Helpviewer/Network/EmptyNetworkReply.py Helpviewer/GreaseMonkey/GreaseMonkeyManager.py Helpviewer/Network/FollowRedirectReply.py Helpviewer/GreaseMonkey/GreaseMonkeyUrlMatcher.py Helpviewer/GreaseMonkey/GreaseMonkeyScript.py Helpviewer/GreaseMonkey/GreaseMonkeyDownloader.py Helpviewer/HelpUtilities.py Helpviewer/GreaseMonkey/GreaseMonkeyAddScriptDialog.py Helpviewer/GreaseMonkey/GreaseMonkeyConfiguration/__init__.py Helpviewer/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListDelegate.py Helpviewer/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListWidget.py Helpviewer/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationDialog.py Helpviewer/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationScriptInfoDialog.py E5Gui/E5ClickableLabel.py Helpviewer/AdBlock/AdBlockIcon.py E5Gui/E5TreeWidget.py Helpviewer/AdBlock/AdBlockTreeWidget.py Helpviewer/AdBlock/AdBlockExceptionsDialog.py Graphics/UMLDiagramBuilder.py Graphics/UMLClassDiagramBuilder.py Graphics/PackageDiagramBuilder.py Graphics/ImportsDiagramBuilder.py Graphics/ApplicationDiagramBuilder.py Utilities/FtpUtilities.py Helpviewer/Network/FileReply.py Helpviewer/Network/FileAccessHandler.py E5Network/E5Ftp.py E5Network/E5UrlInfo.py Globals/AppInfo.py Toolbox/__init__.py Toolbox/SingleApplication.py Toolbox/Startup.py Preferences/ConfigurationPages/HelpInterfacePage.py E5Gui/E5MainWindow.py Debugger/CallTraceViewer.py UI/NotificationWidget.py Preferences/ConfigurationPages/NotificationsPage.py QScintilla/SpellingDictionaryEditDialog.py E5Gui/E5ComboBox.py Network/__init__.py Network/IRC/__init__.py Network/IRC/IrcNetworkManager.py Network/IRC/IrcChannelWidget.py Network/IRC/IrcNetworkWidget.py Network/IRC/IrcWidget.py Network/IRC/IrcUtilities.py Preferences/ConfigurationPages/IrcPage.py Network/IRC/IrcNetworkListDialog.py Network/IRC/IrcNetworkEditDialog.py Network/IRC/IrcChannelEditDialog.py Network/IRC/IrcServerEditDialog.py Network/IRC/IrcIdentitiesEditDialog.py Network/IRC/IrcMessageEdit.py E5Gui/E5ZoomWidget.py E5Network/E5SslErrorHandler.py E5Network/E5SslCertificatesDialog.py UI/Previewer.py ThirdParty/Pygments/pygments/lexers/_robotframeworklexer.py ThirdParty/Pygments/pygments/lexers/foxpro.py ThirdParty/Pygments/pygments/lexers/_lassobuiltins.py ThirdParty/Pygments/pygments/lexers/_sourcemodbuiltins.py ThirdParty/Pygments/pygments/lexers/_stan_builtins.py ThirdParty/Pygments/pygments/lexers/_openedgebuiltins.py ThirdParty/Pygments/pygments/lexers/dalvik.py E5Network/E5SslCertificatesInfoWidget.py E5Network/E5SslCertificatesInfoDialog.py E5Network/E5SslInfoWidget.py QScintilla/SortOptionsDialog.py Debugger/CallStackViewer.py Examples/hallo.py Examples/modpython.py Examples/modpython_dbg.py Examples/rhallo.py E5Gui/E5ErrorMessage.py Helpviewer/Network/NoCacheHostsDialog.py E5Gui/E5ErrorMessageFilterDialog.py Plugins/PluginWizardQRegularExpression.py Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardDialog.py Plugins/WizardPlugins/QRegularExpressionWizard/__init__.py Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardCharactersDialog.py Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardRepeatDialog.py Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardServer.py Utilities/ClassBrowsers/jsclbr.py ThirdParty/Jasy/__init__.py ThirdParty/Jasy/jasy/__init__.py ThirdParty/Jasy/jasy/core/__init__.py ThirdParty/Jasy/jasy/core/Console.py ThirdParty/Jasy/jasy/js/__init__.py ThirdParty/Jasy/jasy/js/util/__init__.py ThirdParty/Jasy/jasy/js/api/Comment.py ThirdParty/Jasy/jasy/js/api/__init__.py ThirdParty/Jasy/jasy/js/parse/VanillaBuilder.py ThirdParty/Jasy/jasy/js/parse/__init__.py ThirdParty/Jasy/jasy/js/parse/Node.py ThirdParty/Jasy/jasy/js/parse/Parser.py ThirdParty/Jasy/jasy/js/tokenize/Tokenizer.py ThirdParty/Jasy/jasy/js/tokenize/__init__.py ThirdParty/Jasy/jasy/js/tokenize/Lang.py Plugins/VcsPlugins/vcsMercurial/HgSummaryDialog.py Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.py Plugins/CheckerPlugins/CodeStyleChecker/__init__.py Plugins/CheckerPlugins/CodeStyleChecker/pep8.py Plugins/CheckerPlugins/CodeStyleChecker/DocStyleChecker.py Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.py Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.py Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleFixer.py Plugins/CheckerPlugins/CodeStyleChecker/NamingStyleChecker.py Plugins/PluginCodeStyleChecker.py Helpviewer/Bookmarks/DefaultBookmarks_rc.py Helpviewer/OpenSearch/DefaultSearchEngines/__init__.py Helpviewer/OpenSearch/DefaultSearchEngines/DefaultSearchEngines_rc.py Helpviewer/UserAgent/UserAgentDefaults_rc.py E5Gui/E5ProgressDialog.py Plugins/VcsPlugins/vcsMercurial/HgRepoConfigDataDialog.py Plugins/VcsPlugins/vcsMercurial/HgUserConfigDataDialog.py Plugins/VcsPlugins/vcsMercurial/ShelveExtension/__init__.py Plugins/VcsPlugins/vcsMercurial/ShelveExtension/shelve.py Plugins/VcsPlugins/vcsMercurial/ShelveExtension/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveDataDialog.py Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgUnshelveDataDialog.py Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveBrowserDialog.py Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelvesSelectionDialog.py Plugins/VcsPlugins/vcsMercurial/HgExtensionProjectBrowserHelper.py Plugins/VcsPlugins/vcsMercurial/ShelveExtension/ProjectBrowserHelper.py Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/__init__.py Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/largefiles.py Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectHelper.py Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.py Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectBrowserHelper.py Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.py E5Gui/E5MapWidget.py QScintilla/EditorMarkerMap.py Plugins/VcsPlugins/vcsMercurial/HgBranchInputDialog.py UI/Previewers/__init__.py UI/Previewers/PreviewerHTML.py UI/Previewers/PreviewerQSS.py QScintilla/Lexers/LexerQSS.py DebugClients/Python/coverage/config.py DebugClients/Python/coverage/debug.py DebugClients/Python/coverage/version.py DebugClients/Python/coverage/__main__.py DebugClients/Python3/coverage/config.py DebugClients/Python3/coverage/debug.py DebugClients/Python3/coverage/version.py DebugClients/Python3/coverage/__main__.py Utilities/BackgroundClient.py Utilities/BackgroundService.py Utilities/compatibility_fixes.py Utilities/PySideImporter.py Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py Plugins/CheckerPlugins/CodeStyleChecker/translations.py Plugins/CheckerPlugins/SyntaxChecker/pyflakes/__init__.py Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py Plugins/CheckerPlugins/SyntaxChecker/pyflakes/messages.py Plugins/CheckerPlugins/SyntaxChecker/pyflakes/translations.py Plugins/CheckerPlugins/SyntaxChecker/jsCheckSyntax.py QScintilla/Lexers/LexerPO.py Plugins/VcsPlugins/vcsMercurial/HgBookmarkDialog.py Plugins/VcsPlugins/vcsMercurial/HgBookmarkRenameDialog.py Plugins/VcsPlugins/vcsMercurial/HgBookmarksInOutDialog.py Plugins/VcsPlugins/vcsMercurial/HgBookmarksListDialog.py Plugins/VcsPlugins/vcsMercurial/HgConflictsListDialog.py cleanupSource.py Utilities/MimeTypes.py ThirdParty/Send2Trash/__init__.py ThirdParty/Send2Trash/send2trash/plat_win.py ThirdParty/Send2Trash/send2trash/__init__.py ThirdParty/Send2Trash/send2trash/plat_osx.py ThirdParty/Send2Trash/send2trash/plat_other.py ThirdParty/Send2Trash/send2trash/compat.py ThirdParty/Send2Trash/send2trash/plat_gio.py QScintilla/Lexers/LexerCoffeeScript.py eric6.py eric6.pyw eric6_api.py eric6_compare.py eric6_compare.pyw eric6_configure.py eric6_configure.pyw eric6_diff.py eric6_diff.pyw eric6_doc.py eric6_editor.py eric6_editor.pyw eric6_iconeditor.py eric6_iconeditor.pyw eric6_plugininstall.py eric6_plugininstall.pyw eric6_pluginrepository.py eric6_pluginrepository.pyw eric6_pluginuninstall.py eric6_pluginuninstall.pyw eric6_qregexp.py eric6_qregexp.pyw eric6_qregularexpression.py eric6_qregularexpression.pyw eric6_re.py eric6_re.pyw eric6_snap.py eric6_snap.pyw eric6_sqlbrowser.py eric6_sqlbrowser.pyw eric6_tray.py eric6_tray.pyw eric6_trpreviewer.py eric6_trpreviewer.pyw eric6_uipreviewer.py eric6_uipreviewer.pyw eric6_unittest.py eric6_unittest.pyw eric6_webbrowser.py eric6_webbrowser.pyw eric6config.py DebugClients/Python/eric6dbgstub.py DebugClients/Python3/eric6dbgstub.py Toolbox/PyQt4ImportHook.py
PyUnit/UnittestDialog.ui
PyUnit/UnittestStacktraceDialog.ui
UI/DiffDialog.ui
UI/CompareDialog.ui
Debugger/EditBreakpointDialog.ui
Debugger/EditWatchpointDialog.ui
Debugger/ExceptionsFilterDialog.ui
Debugger/StartDebugDialog.ui
Debugger/StartCoverageDialog.ui
Debugger/StartRunDialog.ui
Debugger/StartProfileDialog.ui
Debugger/VariableDetailDialog.ui
Debugger/VariablesFilterDialog.ui
Preferences/ConfigurationPages/ProjectPage.ui
Preferences/ConfigurationPages/VcsPage.ui
Preferences/ConfigurationPages/PrinterPage.ui
Preferences/ConfigurationPages/TemplatesPage.ui
Preferences/ConfigurationPages/PythonPage.ui
Preferences/ConfigurationPages/EmailPage.ui
Preferences/ConfigurationPages/CorbaPage.ui
Preferences/ConfigurationPages/ShellPage.ui
Preferences/ConfigurationPages/ApplicationPage.ui
Preferences/ConfigurationPages/TasksPage.ui
Preferences/ConfigurationPages/ViewmanagerPage.ui
Preferences/ConfigurationPages/QtPage.ui
Preferences/ConfigurationPages/IconsPage.ui
Preferences/ConfigurationPages/HelpViewersPage.ui
Preferences/ConfigurationPages/HelpDocumentationPage.ui
Preferences/ConfigurationPages/DebuggerRubyPage.ui
Preferences/ConfigurationPages/DebuggerPythonPage.ui
Preferences/ConfigurationPages/EditorCalltipsPage.ui
Preferences/ConfigurationPages/EditorGeneralPage.ui
Preferences/ConfigurationPages/EditorAutocompletionPage.ui
Preferences/ConfigurationPages/EditorAPIsPage.ui
Preferences/ConfigurationPages/EditorHighlightersPage.ui
Preferences/ConfigurationPages/EditorHighlightingStylesPage.ui
Preferences/ShortcutsDialog.ui
Preferences/ShortcutDialog.ui
Preferences/ToolConfigurationDialog.ui
UI/DeleteFilesConfirmationDialog.ui
UI/EmailDialog.ui
UI/FindFileDialog.ui
UI/FindFileNameDialog.ui
DataViews/CodeMetricsDialog.ui
DataViews/PyCoverageDialog.ui
DataViews/PyProfileDialog.ui
Tasks/TaskPropertiesDialog.ui
Templates/TemplatePropertiesDialog.ui
Templates/TemplateSingleVariableDialog.ui
Project/AddFileDialog.ui
Project/AddFoundFilesDialog.ui
Project/AddLanguageDialog.ui
Project/PropertiesDialog.ui
Project/AddDirectoryDialog.ui
Project/FiletypeAssociationDialog.ui
Project/DebuggerPropertiesDialog.ui
VCS/RepositoryInfoDialog.ui
VCS/CommandOptionsDialog.ui
ViewManager/BookmarkedFilesDialog.ui
QScintilla/GotoDialog.ui
QScintilla/ZoomDialog.ui
Preferences/ToolGroupConfigurationDialog.ui
Preferences/ConfigurationPages/ProjectBrowserPage.ui
Preferences/ConfigurationPages/IconsPreviewDialog.ui
Tasks/TaskFilterConfigDialog.ui
Project/TranslationPropertiesDialog.ui
Project/UserPropertiesDialog.ui
Preferences/ConfigurationPages/GraphicsPage.ui
Graphics/UMLSceneSizeDialog.ui
Preferences/ProgramsDialog.ui
Project/CreateDialogCodeDialog.ui
Project/NewDialogClassDialog.ui
Preferences/ConfigurationPages/EditorTypingPage.ui
PluginManager/PluginInfoDialog.ui
PluginManager/PluginDetailsDialog.ui
Plugins/DocumentationPlugins/Ericapi/EricapiConfigDialog.ui
Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.ui
Plugins/DocumentationPlugins/Ericapi/EricapiExecDialog.ui
Plugins/DocumentationPlugins/Ericdoc/EricdocExecDialog.ui
PluginManager/PluginInstallDialog.ui
PluginManager/PluginUninstallDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnNewProjectOptionsDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnCommitDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnTagDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnSwitchDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnMergeDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnOptionsDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnCommandDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnTagBranchListDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnCopyDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnPropListDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnPropSetDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnStatusDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnRevisionSelectionDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnLogDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnDiffDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnBlameDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnUrlSelectionDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnLoginDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnNewProjectOptionsDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnOptionsDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnCommitDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnTagDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnSwitchDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnMergeDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnPropSetDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnCopyDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnPropDelDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnRevisionSelectionDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnPropListDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnTagBranchListDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnLogDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnBlameDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnCommandDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnRelocateDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnUrlSelectionDialog.ui
Plugins/AboutPlugin/AboutDialog.ui
Plugins/CheckerPlugins/Tabnanny/TabnannyDialog.ui
Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.ui
Plugins/WizardPlugins/ColorDialogWizard/ColorDialogWizardDialog.ui
Plugins/WizardPlugins/FileDialogWizard/FileDialogWizardDialog.ui
Plugins/WizardPlugins/FontDialogWizard/FontDialogWizardDialog.ui
Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.ui
Plugins/WizardPlugins/MessageBoxWizard/MessageBoxWizardDialog.ui
Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardDialog.ui
Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardCharactersDialog.ui
Plugins/WizardPlugins/QRegExpWizard/QRegExpWizardRepeatDialog.ui
Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardCharactersDialog.ui
Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardRepeatDialog.ui
Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.ui
Project/NewPythonPackageDialog.ui
Preferences/ConfigurationPages/EditorExportersPage.ui
Preferences/ConfigurationPages/PluginManagerPage.ui
PluginManager/PluginRepositoryDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnRepoBrowserDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnLogBrowserDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnLogBrowserDialog.ui
Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.ui
Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.ui
MultiProject/PropertiesDialog.ui
MultiProject/AddProjectDialog.ui
Preferences/ConfigurationPages/MultiProjectPage.ui
Preferences/ConfigurationPages/EditorFilePage.ui
Preferences/ConfigurationPages/EditorSearchPage.ui
Plugins/VcsPlugins/vcsSubversion/SvnRelocateDialog.ui
UI/AuthenticationDialog.ui
QScintilla/ShellHistoryDialog.ui
Preferences/ConfigurationPages/HelpAppearancePage.ui
Preferences/ConfigurationPages/EditorAutocompletionQScintillaPage.ui
Preferences/ConfigurationPages/EditorCalltipsQScintillaPage.ui
Preferences/ConfigurationPages/EditorPropertiesPage.ui
Preferences/ConfigurationPages/EditorStylesPage.ui
Preferences/ConfigurationPages/DebuggerGeneralPage.ui
Preferences/ConfigurationPages/InterfacePage.ui
QScintilla/ReplaceWidget.ui
QScintilla/SearchWidget.ui
Preferences/ViewProfileToolboxesDialog.ui
Preferences/ConfigurationPages/NetworkPage.ui
Preferences/ConfigurationPages/EditorSpellCheckingPage.ui
QScintilla/SpellCheckingDialog.ui
Project/SpellingPropertiesDialog.ui
Preferences/ViewProfileSidebarsDialog.ui
Project/LexerAssociationDialog.ui
Helpviewer/QtHelpDocumentationDialog.ui
Helpviewer/QtHelpFiltersDialog.ui
Helpviewer/HelpTopicDialog.ui
Preferences/ConfigurationPages/DebuggerPython3Page.ui
Helpviewer/HelpClearPrivateDataDialog.ui
Helpviewer/HelpLanguagesDialog.ui
Helpviewer/CookieJar/CookiesExceptionsDialog.ui
Helpviewer/CookieJar/CookiesDialog.ui
Helpviewer/CookieJar/CookiesConfigurationDialog.ui
Helpviewer/CookieJar/CookieDetailsDialog.ui
Helpviewer/OpenSearch/OpenSearchDialog.ui
SqlBrowser/SqlBrowserWidget.ui
SqlBrowser/SqlConnectionDialog.ui
Helpviewer/Bookmarks/AddBookmarkDialog.ui
Helpviewer/Bookmarks/BookmarksDialog.ui
Preferences/ConfigurationPages/HelpWebBrowserPage.ui
Helpviewer/SearchWidget.ui
Helpviewer/History/HistoryDialog.ui
IconEditor/IconSizeDialog.ui
Helpviewer/Passwords/PasswordsDialog.ui
Helpviewer/AdBlock/AdBlockDialog.ui
Helpviewer/OpenSearch/OpenSearchEditDialog.ui
E5Network/E5NetworkMonitor.ui
E5Network/E5NetworkHeaderDetailsDialog.ui
E5Gui/E5ToolBarDialog.ui
Preferences/ConfigurationPages/EditorKeywordsPage.ui
Cooperation/ChatWidget.ui
Preferences/ConfigurationPages/CooperationPage.ui
Plugins/VcsPlugins/vcsMercurial/HgOptionsDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgNewProjectOptionsDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgCopyDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgLogDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.ui
Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.ui
Plugins/VcsPlugins/vcsMercurial/HgMergeDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgStatusDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgAnnotateDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgTagDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgTagBranchListDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgRevisionsSelectionDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgRevisionSelectionDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgCommandDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgBundleDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgBackoutDialog.ui
Helpviewer/OfflineStorage/OfflineStorageConfigDialog.ui
Helpviewer/OfflineStorage/WebDatabasesDialog.ui
UI/SymbolsWidget.ui
UI/NumbersWidget.ui
Plugins/WizardPlugins/E5MessageBoxWizard/E5MessageBoxWizardDialog.ui
Helpviewer/UrlBar/BookmarkInfoDialog.ui
Helpviewer/Download/DownloadItem.ui
Helpviewer/Download/DownloadManager.ui
Preferences/ConfigurationPages/TrayStarterPage.ui
Preferences/ConfigurationPages/HelpVirusTotalPage.ui
Helpviewer/Download/DownloadAskActionDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesNewPatchDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesRenamePatchDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesFoldDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesHeaderDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListGuardsDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListAllGuardsDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesDefineGuardsDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesGuardsSelectionDialog.ui
Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesQueueManagementDialog.ui
Plugins/VcsPlugins/vcsMercurial/FetchExtension/HgFetchDialog.ui
Plugins/VcsPlugins/vcsMercurial/PurgeExtension/HgPurgeListDialog.ui
Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignaturesDialog.ui
Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignDialog.ui
Plugins/VcsPlugins/vcsMercurial/TransplantExtension/TransplantDialog.ui
Plugins/VcsPlugins/vcsMercurial/RebaseExtension/HgRebaseDialog.ui
Preferences/ConfigurationPages/MasterPasswordEntryDialog.ui
Preferences/ConfigurationPages/SecurityPage.ui
Plugins/VcsPlugins/vcsMercurial/HgMultiRevisionSelectionDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgImportDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgExportDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgClientPromptDialog.ui
Preferences/ConfigurationPages/EditorSyntaxPage.ui
Helpviewer/Feeds/FeedsDialog.ui
Helpviewer/Feeds/FeedsManager.ui
Helpviewer/Feeds/FeedEditDialog.ui
Helpviewer/SiteInfo/SiteInfoDialog.ui
Helpviewer/UserAgent/UserAgentsDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgPhaseDialog.ui
Helpviewer/PageScreenDialog.ui
Helpviewer/Sync/SyncDataPage.ui
Helpviewer/Sync/SyncHostTypePage.ui
Helpviewer/Sync/SyncFtpSettingsPage.ui
Helpviewer/Sync/SyncCheckPage.ui
Helpviewer/WebPlugins/ClickToFlash/ClickToFlash.ui
Helpviewer/WebPlugins/ClickToFlash/ClickToFlashWhitelistDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgGraftDialog.ui
Helpviewer/UrlBar/BookmarkActionSelectionDialog.ui
Helpviewer/Sync/SyncEncryptionPage.ui
Helpviewer/Sync/SyncDirectorySettingsPage.ui
Helpviewer/Bookmarks/BookmarksImportDialog.ui
UI/ErrorLogDialog.ui
Helpviewer/Bookmarks/BookmarkPropertiesDialog.ui
Snapshot/SnapWidget.ui
UI/SearchWidget.ui
Helpviewer/SiteInfo/SiteInfoNoSslDialog.ui
Plugins/VcsPlugins/vcsPySvn/SvnChangeListsDialog.ui
Plugins/VcsPlugins/vcsSubversion/SvnChangeListsDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgAddSubrepositoryDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgRemoveSubrepositoriesDialog.ui
Helpviewer/Network/SendRefererWhitelistDialog.ui
Helpviewer/PersonalInformationManager/PersonalDataDialog.ui
Helpviewer/GreaseMonkey/GreaseMonkeyAddScriptDialog.ui
Helpviewer/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationDialog.ui
Helpviewer/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationScriptInfoDialog.ui
Helpviewer/AdBlock/AdBlockExceptionsDialog.ui
Preferences/ConfigurationPages/HelpInterfacePage.ui
Debugger/CallTraceViewer.ui
UI/NotificationWidget.ui
Preferences/ConfigurationPages/NotificationsPage.ui
QScintilla/SpellingDictionaryEditDialog.ui
Network/IRC/IrcChannelWidget.ui
Network/IRC/IrcWidget.ui
Network/IRC/IrcNetworkWidget.ui
Preferences/ConfigurationPages/IrcPage.ui
Network/IRC/IrcNetworkListDialog.ui
Network/IRC/IrcNetworkEditDialog.ui
Network/IRC/IrcChannelEditDialog.ui
Network/IRC/IrcServerEditDialog.ui
Network/IRC/IrcIdentitiesEditDialog.ui
E5Gui/E5ZoomWidget.ui
E5Network/E5SslCertificatesDialog.ui
E5Network/E5SslCertificatesInfoDialog.ui
E5Network/E5SslCertificatesInfoWidget.ui
QScintilla/SortOptionsDialog.ui
Helpviewer/Network/NoCacheHostsDialog.ui
E5Gui/E5ErrorMessageFilterDialog.ui
Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardDialog.ui
Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardCharactersDialog.ui
Plugins/WizardPlugins/QRegularExpressionWizard/QRegularExpressionWizardRepeatDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgSummaryDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgArchiveDialog.ui
Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.ui
Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.ui
Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgRepoConfigDataDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgUserConfigDataDialog.ui
Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveDataDialog.ui
Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgUnshelveDataDialog.ui
Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveBrowserDialog.ui
Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelvesSelectionDialog.ui
Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfConvertDataDialog.ui
Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgBranchInputDialog.ui
UI/Previewers/PreviewerHTML.ui
UI/Previewers/PreviewerQSS.ui
Plugins/VcsPlugins/vcsMercurial/HgBookmarkDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgBookmarkRenameDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgBookmarksInOutDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgBookmarksListDialog.ui
Plugins/VcsPlugins/vcsMercurial/HgConflictsListDialog.ui
i18n/eric6_cs.qm i18n/eric6_cs.ts i18n/eric6_de.qm i18n/eric6_de.ts i18n/eric6_en.qm i18n/eric6_en.ts i18n/eric6_es.qm i18n/eric6_es.ts i18n/eric6_fr.qm i18n/eric6_fr.ts i18n/eric6_it.qm i18n/eric6_it.ts i18n/eric6_ru.qm i18n/eric6_ru.ts i18n/eric6_tr.qm i18n/eric6_tr.ts i18n/eric6_zh_CN.GB2312.qm i18n/eric6_zh_CN.GB2312.ts i18n/eric6_pt.qm i18n/eric6_pt.ts IconEditor/cursors/cursors.qrc Helpviewer/data/icons.qrc Helpviewer/data/html.qrc Helpviewer/data/javascript.qrc Helpviewer/Bookmarks/DefaultBookmarks.qrc Helpviewer/OpenSearch/DefaultSearchEngines/DefaultSearchEngines.qrc Helpviewer/UserAgent/UserAgentDefaults.qrc THANKS pylint.rc README-i18n.txt README-passive-debugging.txt README default.e4k Plugins/ViewManagerPlugins/Listspace/preview.png Plugins/ViewManagerPlugins/Tabview/preview.png Plugins/VcsPlugins/vcsPySvn/icons/pysvn.png Plugins/VcsPlugins/vcsSubversion/icons/subversion.png Plugins/VcsPlugins/vcsPySvn/icons/preferences-subversion.png Plugins/VcsPlugins/vcsSubversion/icons/preferences-subversion.png changelog APIs/Ruby/Ruby-1.8.7.api APIs/Python/zope-3.3.1.api LICENSE.GPL3 ThirdParty/CharDet/docs ThirdParty/CharDet/LICENSE Dictionaries APIs/Python/zope-2.11.2.api APIs/Python/zope-2.10.7.api ThirdParty/Pygments/pygments/LICENSE ThirdParty/Pygments/pygments/CHANGES ThirdParty/Pygments/pygments/AUTHORS ThirdParty/Pygments/pygments/PKG-INFO DebugClients/Python/coverage/htmlfiles IconEditor/cursors/aim-cursor.xpm IconEditor/cursors/colorpicker-cursor.xpm IconEditor/cursors/eraser-cursor.xpm IconEditor/cursors/fill-cursor.xpm IconEditor/cursors/paintbrush-cursor.xpm DebugClients/Python/coverage/doc DebugClients/Python3/coverage/doc DebugClients/Python3/coverage/htmlfiles Plugins/VcsPlugins/vcsMercurial/icons/mercurial.png Plugins/VcsPlugins/vcsMercurial/icons/preferences-mercurial.png .hgignore Plugins/VcsPlugins/vcsMercurial/icons/startServer.png Plugins/VcsPlugins/vcsMercurial/icons/stopServer.png Plugins/VcsPlugins/vcsMercurial/styles/logBrowserBookmark.style Plugins/VcsPlugins/vcsMercurial/styles/logDialogBookmark.style README-MacOSX.txt default_Mac.e4k Plugins/VcsPlugins/vcsMercurial/styles/logBrowserBookmarkPhase.style Plugins/VcsPlugins/vcsMercurial/styles/logDialogBookmarkPhase.style Helpviewer/data/icons/ericWeb16.png Helpviewer/data/icons/ericWeb32.png Helpviewer/data/html/startPage.html Helpviewer/data/html/adblockPage.html Helpviewer/data/icons/adBlockPlus16.png Helpviewer/data/icons/adBlockPlus64.png Helpviewer/data/html/notFoundPage.html Helpviewer/data/html/speeddialPage.html Helpviewer/data/icons/box-border-small.png Helpviewer/data/icons/brokenPage.png Helpviewer/data/icons/close.png Helpviewer/data/icons/edit.png Helpviewer/data/icons/loading.gif Helpviewer/data/icons/plus.png Helpviewer/data/icons/reload.png Helpviewer/data/icons/setting.png Helpviewer/data/javascript/jquery-ui.js Helpviewer/data/javascript/jquery.js icons CSSs DTDs DesignerTemplates pixmaps Documentation/mod_python.odt Documentation/mod_python.pdf Styles CodeTemplates Documentation/Help APIs/Ruby/Ruby-1.8.7.bas APIs/Ruby/Ruby-1.9.1.api APIs/Ruby/Ruby-1.9.1.bas APIs/Python3/QScintilla2.bas ThirdParty/Jasy/jasy/license.md Helpviewer/Bookmarks/DefaultBookmarks.xbel Helpviewer/UserAgent/UserAgentDefaults.xml Helpviewer/OpenSearch/DefaultSearchEngines/Yahoo.xml Helpviewer/OpenSearch/DefaultSearchEngines/YouTube.xml Helpviewer/OpenSearch/DefaultSearchEngines/Amazoncom.xml Helpviewer/OpenSearch/DefaultSearchEngines/Bing.xml Helpviewer/OpenSearch/DefaultSearchEngines/DeEn_Beolingus.xml Helpviewer/OpenSearch/DefaultSearchEngines/Facebook.xml Helpviewer/OpenSearch/DefaultSearchEngines/Google_Im_Feeling_Lucky.xml Helpviewer/OpenSearch/DefaultSearchEngines/Google.xml Helpviewer/OpenSearch/DefaultSearchEngines/LEO_DeuEng.xml Helpviewer/OpenSearch/DefaultSearchEngines/LinuxMagazin.xml Helpviewer/OpenSearch/DefaultSearchEngines/Reddit.xml Helpviewer/OpenSearch/DefaultSearchEngines/Wikia_en.xml Helpviewer/OpenSearch/DefaultSearchEngines/Wikia.xml Helpviewer/OpenSearch/DefaultSearchEngines/Wikipedia.xml Helpviewer/OpenSearch/DefaultSearchEngines/Wiktionary.xml APIs/QSS/qss.api ThirdParty/Send2Trash/LICENSE eric6.e4p eric6config.linux eric6_webbrowser.desktop eric6.appdata.xml eric6.desktop APIs/Python3/eric6.api APIs/Python3/eric6.bas APIs/Ruby/eric6.api APIs/Ruby/eric6.bas Documentation/eric6-plugin.odt Documentation/eric6-plugin.pdf Documentation/Source APIs/Python3/PyQt5.bas APIs/Python3/PyQt4.bas Plugins/VcsPlugins/vcsMercurial/templates/logBrowserBookmarkPhase.tmpl Plugins/VcsPlugins/vcsMercurial/templates/logDialogBookmarkPhase.tmpl README-eric6-doc.txt Helpviewer/OpenSearch/DefaultSearchEngines/DuckDuckGo.xml eric6.py Mercurial add checkout commit diff export global history log remove status tag update ERIC4API ignoreDirectories CSSs DTDs DesignerTemplates Documentation Examples ThirdParty corbatests i18n icons pixmaps tests unittests Styles CodeTemplates .ropeproject patches Dictionaries coverage .eric5project _eric5project _ropeproject .hg _hg .directory .issues data pyflakes .eric6project _eric6project ignoreFilePatterns Ui_* languages Ruby Python3 outputFile APIs/%L/eric6.api useRecursion True ERIC4DOC CFBgColor #4fa4ff CFColor #ffffff Level1HeaderBgColor #4fa4ff Level1HeaderColor #ffffff Level2HeaderBgColor #00557f Level2HeaderColor #ffffff LinkColor #aa5500 cssFile CSSs/default.css ignoreDirectories CSSs DTDs DesignerTemplates Documentation Examples ThirdParty corbatests i18n icons pixmaps tests unittests rb_tests Styles CodeTemplates .ropeproject patches Dictionaries coverage .eric5project _eric5project _ropeproject .hg _hg .directory .issues pyflakes .eric6project _eric6project ignoreFilePatterns Ui_* *_rc.py outputDirectory Documentation/Source qtHelpEnabled True qtHelpFilterAttributes eric6:ide:6.0 qtHelpFilterName eric6 qtHelpNamespace org.eric6.ide.60 qtHelpOutputDirectory Documentation/Help qtHelpTitle The eric6 IDE qtHelpVirtualFolder eric6 sourceExtensions useRecursion True Pep8Checker DocstringType eric ExcludeFiles */ThirdParty/*, */coverage/*, */Ui_*.py, */Examples/*, */*_rc.py,*/pep8.py,*/pyflakes/checker.py ExcludeMessages N802, N803, N807, N808, N821, W293, E265 FixCodes FixIssues False HangClosing False IncludeMessages MaxLineLength 79 NoFixCodes E501 RepeatMessages True ShowIgnored False SyntaxChecker ExcludeFiles */coverage/*, */ThirdParty/*, */Examples/* Tabnanny ExcludeFiles */coverage/*, */ThirdParty/*, */Examples/* CodeMetrics ExcludeFiles */ThirdParty/*, */coverage/*, Ui_*.py
eric-6.0.8/eric/Cooperation/0000755000175000017500000000000012557365404014742 5ustar piotrpiotreric-6.0.8/eric/Cooperation/ChatWidget.py0000644000175000017500000006104512451233374017336 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the chat dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal, QDateTime, QPoint, QFileInfo from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QWidget, QListWidgetItem, QMenu, QApplication from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog from Globals import recentNameHosts from .CooperationClient import CooperationClient from .Ui_ChatWidget import Ui_ChatWidget import Preferences import Utilities import UI.PixmapCache class ChatWidget(QWidget, Ui_ChatWidget): """ Class implementing the chat dialog. @signal connected(connected) emitted to signal a change of the connected state (bool) @signal editorCommand(hash, filename, message) emitted when an editor command has been received (string, string, string) @signal shareEditor(share) emitted to signal a share is requested (bool) @signal startEdit() emitted to start a shared edit session @signal sendEdit() emitted to send a shared edit session @signal cancelEdit() emitted to cancel a shared edit session """ connected = pyqtSignal(bool) editorCommand = pyqtSignal(str, str, str) shareEditor = pyqtSignal(bool) startEdit = pyqtSignal() sendEdit = pyqtSignal() cancelEdit = pyqtSignal() def __init__(self, ui, port=-1, parent=None): """ Constructor @param ui reference to the user interface object (UserInterface) @param port port to be used for the cooperation server (integer) @param parent reference to the parent widget (QWidget) """ super(ChatWidget, self).__init__(parent) self.setupUi(self) self.shareButton.setIcon( UI.PixmapCache.getIcon("sharedEditDisconnected.png")) self.startEditButton.setIcon( UI.PixmapCache.getIcon("sharedEditStart.png")) self.sendEditButton.setIcon( UI.PixmapCache.getIcon("sharedEditSend.png")) self.cancelEditButton.setIcon( UI.PixmapCache.getIcon("sharedEditCancel.png")) self.__ui = ui self.__client = CooperationClient(self) self.__myNickName = self.__client.nickName() self.__initChatMenu() self.__initUsersMenu() self.messageEdit.returnPressed.connect(self.__handleMessage) self.sendButton.clicked.connect(self.__handleMessage) self.__client.newMessage.connect(self.appendMessage) self.__client.newParticipant.connect(self.__newParticipant) self.__client.participantLeft.connect(self.__participantLeft) self.__client.connectionError.connect(self.__showErrorMessage) self.__client.cannotConnect.connect(self.__initialConnectionRefused) self.__client.editorCommand.connect(self.__editorCommandMessage) self.serverButton.setText(self.tr("Start Server")) self.serverLed.setColor(QColor(Qt.red)) if port == -1: port = Preferences.getCooperation("ServerPort") self.serverPortSpin.setValue(port) self.__setConnected(False) if Preferences.getCooperation("AutoStartServer"): self.on_serverButton_clicked() self.recent = [] self.__loadHostsHistory() def __loadHostsHistory(self): """ Private method to load the recently connected hosts. """ self.__recent = [] Preferences.Prefs.rsettings.sync() rh = Preferences.Prefs.rsettings.value(recentNameHosts) if rh is not None: self.__recent = rh[:20] self.hostEdit.clear() self.hostEdit.addItems(self.__recent) self.hostEdit.clearEditText() def __saveHostsHistory(self): """ Private method to save the list of recently connected hosts. """ Preferences.Prefs.rsettings.setValue(recentNameHosts, self.__recent) Preferences.Prefs.rsettings.sync() def __setHostsHistory(self, host): """ Private method to remember the given host as the most recent entry. @param host host entry to remember (string) """ if host in self.__recent: self.__recent.remove(host) self.__recent.insert(0, host) self.__saveHostsHistory() self.hostEdit.clear() self.hostEdit.addItems(self.__recent) def __clearHostsHistory(self): """ Private slot to clear the hosts history. """ self.__recent = [] self.__saveHostsHistory() self.hostEdit.clear() self.hostEdit.addItems(self.__recent) def __handleMessage(self): """ Private slot handling the Return key pressed in the message edit. """ text = self.messageEdit.text() if text == "": return if text.startswith("/"): self.__showErrorMessage( self.tr("! Unknown command: {0}\n") .format(text.split()[0])) else: self.__client.sendMessage(text) self.appendMessage(self.__myNickName, text) self.messageEdit.clear() def __newParticipant(self, nick): """ Private slot handling a new participant joining. @param nick nick name of the new participant (string) """ if nick == "": return color = self.chatEdit.textColor() self.chatEdit.setTextColor(Qt.gray) self.chatEdit.append( QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate) + ":") self.chatEdit.append(self.tr("* {0} has joined.\n").format(nick)) self.chatEdit.setTextColor(color) QListWidgetItem( UI.PixmapCache.getIcon( "chatUser{0}.png".format(1 + self.usersList.count() % 6)), nick, self.usersList) if not self.__connected: self.__setConnected(True) if not self.isVisible(): self.__ui.showNotification( UI.PixmapCache.getPixmap("cooperation48.png"), self.tr("New User"), self.tr("{0} has joined.") .format(nick)) def __participantLeft(self, nick): """ Private slot handling a participant leaving the session. @param nick nick name of the participant (string) """ if nick == "": return items = self.usersList.findItems(nick, Qt.MatchExactly) for item in items: self.usersList.takeItem(self.usersList.row(item)) del item color = self.chatEdit.textColor() self.chatEdit.setTextColor(Qt.gray) self.chatEdit.append( QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate) + ":") self.chatEdit.append(self.tr("* {0} has left.\n").format(nick)) self.chatEdit.setTextColor(color) if not self.__client.hasConnections(): self.__setConnected(False) if not self.isVisible(): self.__ui.showNotification( UI.PixmapCache.getPixmap("cooperation48.png"), self.tr("User Left"), self.tr("{0} has left.") .format(nick)) def appendMessage(self, from_, message): """ Public slot to append a message to the display. @param from_ originator of the message (string) @param message message to be appended (string) """ if from_ == "" or message == "": return self.chatEdit.append( QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate) + " <" + from_ + ">:") self.chatEdit.append(message + "\n") bar = self.chatEdit.verticalScrollBar() bar.setValue(bar.maximum()) if not self.isVisible(): self.__ui.showNotification( UI.PixmapCache.getPixmap("cooperation48.png"), self.tr("Message from <{0}>").format(from_), message) @pyqtSlot(str) def on_hostEdit_editTextChanged(self, host): """ Private slot handling the entry of a host to connect to. @param host host to connect to (string) """ if not self.__connected: self.connectButton.setEnabled(host != "") def __getConnectionParameters(self): """ Private method to determine the connection parameters. @return tuple with hostname and port (string, integer) """ hostEntry = self.hostEdit.currentText() if "@" in hostEntry: host, port = hostEntry.split("@") try: port = int(port) except ValueError: port = Preferences.getCooperation("ServerPort") self.hostEdit.setEditText("{0}@{1}".format(host, port)) else: host = hostEntry port = Preferences.getCooperation("ServerPort") self.hostEdit.setEditText("{0}@{1}".format(host, port)) return host, port @pyqtSlot() def on_connectButton_clicked(self): """ Private slot initiating the connection. """ if not self.__connected: host, port = self.__getConnectionParameters() self.__setHostsHistory(self.hostEdit.currentText()) if not self.__client.isListening(): self.on_serverButton_clicked() if self.__client.isListening(): self.__client.connectToHost(host, port) self.__setConnected(True) else: self.__client.disconnectConnections() self.__setConnected(False) @pyqtSlot() def on_clearHostsButton_clicked(self): """ Private slot to clear the hosts list. """ self.__clearHostsHistory() @pyqtSlot() def on_serverButton_clicked(self): """ Private slot to start the server. """ if self.__client.isListening(): self.__client.close() self.serverButton.setText(self.tr("Start Server")) self.serverPortSpin.setEnabled(True) if (self.serverPortSpin.value() != Preferences.getCooperation("ServerPort")): self.serverPortSpin.setValue( Preferences.getCooperation("ServerPort")) self.serverLed.setColor(QColor(Qt.red)) else: res, port = self.__client.startListening( self.serverPortSpin.value()) if res: self.serverButton.setText(self.tr("Stop Server")) self.serverPortSpin.setValue(port) self.serverPortSpin.setEnabled(False) self.serverLed.setColor(QColor(Qt.green)) else: self.__showErrorMessage( self.tr("! Server Error: {0}\n").format( self.__client.errorString()) ) def __setConnected(self, connected): """ Private slot to set the connected state. @param connected new connected state (boolean) """ if connected: self.connectButton.setText(self.tr("Disconnect")) self.connectButton.setEnabled(True) self.connectionLed.setColor(QColor(Qt.green)) else: self.connectButton.setText(self.tr("Connect")) self.connectButton.setEnabled(self.hostEdit.currentText() != "") self.connectionLed.setColor(QColor(Qt.red)) self.on_cancelEditButton_clicked() self.shareButton.setChecked(False) self.on_shareButton_clicked(False) self.__connected = connected self.hostEdit.setEnabled(not connected) self.serverButton.setEnabled(not connected) self.sharingGroup.setEnabled(connected) if connected: vm = e5App().getObject("ViewManager") aw = vm.activeWindow() if aw: self.checkEditorActions(aw) def __showErrorMessage(self, message): """ Private slot to show an error message. @param message error message to show (string) """ color = self.chatEdit.textColor() self.chatEdit.setTextColor(Qt.red) self.chatEdit.append( QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate) + ":") self.chatEdit.append(message + "\n") self.chatEdit.setTextColor(color) def __initialConnectionRefused(self): """ Private slot to handle the refusal of the initial connection. """ self.__setConnected(False) def preferencesChanged(self): """ Public slot to handle a change of preferences. """ if not self.__client.isListening(): self.serverPortSpin.setValue( Preferences.getCooperation("ServerPort")) if Preferences.getCooperation("AutoStartServer"): self.on_serverButton_clicked() def getClient(self): """ Public method to get a reference to the cooperation client. @return reference to the cooperation client (CooperationClient) """ return self.__client def __editorCommandMessage(self, hash, fileName, message): """ Private slot to handle editor command messages from the client. @param hash hash of the project (string) @param fileName project relative file name of the editor (string) @param message command message (string) """ self.editorCommand.emit(hash, fileName, message) from QScintilla.Editor import Editor if message.startswith(Editor.StartEditToken + Editor.Separator) or \ message.startswith(Editor.EndEditToken + Editor.Separator): vm = e5App().getObject("ViewManager") aw = vm.activeWindow() if aw: self.checkEditorActions(aw) @pyqtSlot(bool) def on_shareButton_clicked(self, checked): """ Private slot to share the current editor. @param checked flag indicating the button state (boolean) """ if checked: self.shareButton.setIcon( UI.PixmapCache.getIcon("sharedEditConnected.png")) else: self.shareButton.setIcon( UI.PixmapCache.getIcon("sharedEditDisconnected.png")) self.startEditButton.setEnabled(checked) self.shareEditor.emit(checked) @pyqtSlot(bool) def on_startEditButton_clicked(self, checked): """ Private slot to start a shared edit session. @param checked flag indicating the button state (boolean) """ if checked: self.sendEditButton.setEnabled(True) self.cancelEditButton.setEnabled(True) self.shareButton.setEnabled(False) self.startEditButton.setEnabled(False) self.startEdit.emit() @pyqtSlot() def on_sendEditButton_clicked(self): """ Private slot to end a shared edit session and send the changes. """ self.sendEditButton.setEnabled(False) self.cancelEditButton.setEnabled(False) self.shareButton.setEnabled(True) self.startEditButton.setEnabled(True) self.startEditButton.setChecked(False) self.sendEdit.emit() @pyqtSlot() def on_cancelEditButton_clicked(self): """ Private slot to cancel a shared edit session. """ self.sendEditButton.setEnabled(False) self.cancelEditButton.setEnabled(False) self.shareButton.setEnabled(True) self.startEditButton.setEnabled(True) self.startEditButton.setChecked(False) self.cancelEdit.emit() def checkEditorActions(self, editor): """ Public slot to set action according to an editor's state. @param editor reference to the editor (Editor) """ shareable, sharing, editing, remoteEditing = editor.getSharingStatus() self.shareButton.setChecked(sharing) if sharing: self.shareButton.setIcon( UI.PixmapCache.getIcon("sharedEditConnected.png")) else: self.shareButton.setIcon( UI.PixmapCache.getIcon("sharedEditDisconnected.png")) self.startEditButton.setChecked(editing) self.shareButton.setEnabled(shareable and not editing) self.startEditButton.setEnabled( sharing and not editing and not remoteEditing) self.sendEditButton.setEnabled(editing) self.cancelEditButton.setEnabled(editing) def __initChatMenu(self): """ Private slot to initialize the chat edit context menu. """ self.__chatMenu = QMenu(self) self.__copyChatAct = \ self.__chatMenu.addAction( UI.PixmapCache.getIcon("editCopy.png"), self.tr("Copy"), self.__copyChat) self.__chatMenu.addSeparator() self.__cutAllChatAct = \ self.__chatMenu.addAction( UI.PixmapCache.getIcon("editCut.png"), self.tr("Cut all"), self.__cutAllChat) self.__copyAllChatAct = \ self.__chatMenu.addAction( UI.PixmapCache.getIcon("editCopy.png"), self.tr("Copy all"), self.__copyAllChat) self.__chatMenu.addSeparator() self.__clearChatAct = \ self.__chatMenu.addAction( UI.PixmapCache.getIcon("editDelete.png"), self.tr("Clear"), self.__clearChat) self.__chatMenu.addSeparator() self.__saveChatAct = \ self.__chatMenu.addAction( UI.PixmapCache.getIcon("fileSave.png"), self.tr("Save"), self.__saveChat) self.on_chatEdit_copyAvailable(False) @pyqtSlot(bool) def on_chatEdit_copyAvailable(self, yes): """ Private slot to react to text selection/deselection of the chat edit. @param yes flag signaling the availability of selected text (boolean) """ self.__copyChatAct.setEnabled(yes) @pyqtSlot(QPoint) def on_chatEdit_customContextMenuRequested(self, pos): """ Private slot to show the context menu for the chat. @param pos the position of the mouse pointer (QPoint) """ enable = self.chatEdit.toPlainText() != "" self.__saveChatAct.setEnabled(enable) self.__copyAllChatAct.setEnabled(enable) self.__cutAllChatAct.setEnabled(enable) self.__chatMenu.popup(self.chatEdit.mapToGlobal(pos)) def __clearChat(self): """ Private slot to clear the contents of the chat display. """ self.chatEdit.clear() def __saveChat(self): """ Private slot to save the contents of the chat display. """ txt = self.chatEdit.toPlainText() if txt: fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Chat"), "", self.tr("Text Files (*.txt);;All Files (*)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fname: ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Chat"), self.tr("

The file {0} already exists." " Overwrite it?

").format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) try: f = open(fname, "w", encoding="utf-8") f.write(txt) f.close() except IOError as err: E5MessageBox.critical( self, self.tr("Error saving Chat"), self.tr("""

The chat contents could not be""" """ written to {0}

""" """

Reason: {1}

""") .format( fname, str(err))) def __copyChat(self): """ Private slot to copy the contents of the chat display to the clipboard. """ self.chatEdit.copy() def __copyAllChat(self): """ Private slot to copy the contents of the chat display to the clipboard. """ txt = self.chatEdit.toPlainText() if txt: cb = QApplication.clipboard() cb.setText(txt) def __cutAllChat(self): """ Private slot to cut the contents of the chat display to the clipboard. """ txt = self.chatEdit.toPlainText() if txt: cb = QApplication.clipboard() cb.setText(txt) self.chatEdit.clear() def __initUsersMenu(self): """ Private slot to initialize the users list context menu. """ self.__usersMenu = QMenu(self) self.__kickUserAct = \ self.__usersMenu.addAction( UI.PixmapCache.getIcon("chatKickUser.png"), self.tr("Kick User"), self.__kickUser) self.__banUserAct = \ self.__usersMenu.addAction( UI.PixmapCache.getIcon("chatBanUser.png"), self.tr("Ban User"), self.__banUser) self.__banKickUserAct = \ self.__usersMenu.addAction( UI.PixmapCache.getIcon("chatBanKickUser.png"), self.tr("Ban and Kick User"), self.__banKickUser) @pyqtSlot(QPoint) def on_usersList_customContextMenuRequested(self, pos): """ Private slot to show the context menu for the users list. @param pos the position of the mouse pointer (QPoint) """ itm = self.usersList.itemAt(pos) self.__kickUserAct.setEnabled(itm is not None) self.__banUserAct.setEnabled(itm is not None) self.__banKickUserAct.setEnabled(itm is not None) self.__usersMenu.popup(self.usersList.mapToGlobal(pos)) def __kickUser(self): """ Private slot to disconnect a user. """ itm = self.usersList.currentItem() self.__client.kickUser(itm.text()) color = self.chatEdit.textColor() self.chatEdit.setTextColor(Qt.darkYellow) self.chatEdit.append( QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate) + ":") self.chatEdit.append(self.tr("* {0} has been kicked.\n").format( itm.text().split("@")[0])) self.chatEdit.setTextColor(color) def __banUser(self): """ Private slot to ban a user. """ itm = self.usersList.currentItem() self.__client.banUser(itm.text()) color = self.chatEdit.textColor() self.chatEdit.setTextColor(Qt.darkYellow) self.chatEdit.append( QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate) + ":") self.chatEdit.append(self.tr("* {0} has been banned.\n").format( itm.text().split("@")[0])) self.chatEdit.setTextColor(color) def __banKickUser(self): """ Private slot to ban and kick a user. """ itm = self.usersList.currentItem() self.__client.banKickUser(itm.text()) color = self.chatEdit.textColor() self.chatEdit.setTextColor(Qt.darkYellow) self.chatEdit.append( QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate) + ":") self.chatEdit.append( self.tr("* {0} has been banned and kicked.\n") .format(itm.text().split("@")[0])) self.chatEdit.setTextColor(color) def shutdown(self): """ Public method to shut down the cooperation system. """ self.__client.disconnectConnections() self.__setConnected(False) eric-6.0.8/eric/Cooperation/ChatWidget.ui0000644000175000017500000002403212263273046017317 0ustar piotrpiotr ChatWidget 0 0 300 600 Chat 0 0 0 0 0 1 Users Qt::NoFocus Qt::CustomContextMenu 0 2 Chat Qt::NoFocus Qt::CustomContextMenu true Enter the text to send Press to send the text above Send false Share Editor Qt::Horizontal 76 20 false Press to toggle the shared status of the current editor true false Press to start a shared edit true false Press to end the edit and send the changes false Press to cancel the shared edit Qt::Horizontal 75 20 Connection Host: 0 0 Enter the host and port to connect to in the form "host@port" true QComboBox::InsertAtTop QComboBox::AdjustToMinimumContentsLength Press to clear the hosts list Clear false 0 0 false Shows the connection status Server Port: Enter the server port 1025 65535 1 42000 0 0 false Shows the status of the server E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
E5Led QWidget
E5Gui/E5Led.h
1
E5ClearableComboBox QComboBox
E5Gui/E5ComboBox.h
serverButton serverPortSpin hostEdit connectButton clearHostsButton shareButton startEditButton sendEditButton cancelEditButton messageEdit sendButton
eric-6.0.8/eric/Cooperation/Connection.py0000644000175000017500000003703212554665654017427 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a class representing a peer connection. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import pyqtSignal, QTimer, QTime, QByteArray from PyQt5.QtNetwork import QTcpSocket, QHostInfo from E5Gui import E5MessageBox from E5Gui.E5Application import e5App import Preferences MaxBufferSize = 1024 * 1024 TransferTimeout = 30 * 1000 PongTimeout = 60 * 1000 PingInterval = 5 * 1000 SeparatorToken = '|||' class Connection(QTcpSocket): """ Class representing a peer connection. @signal readyForUse() emitted when the connection is ready for use @signal newMessage(user, message) emitted after a new message has arrived (string, string) @signal getParticipants() emitted after a get participants message has arrived @signal participants(participants) emitted after the list of participants has arrived (list of strings of "host:port") """ WaitingForGreeting = 0 ReadingGreeting = 1 ReadyForUse = 2 PlainText = 0 Ping = 1 Pong = 2 Greeting = 3 GetParticipants = 4 Participants = 5 Editor = 6 Undefined = 99 ProtocolMessage = "MESSAGE" ProtocolPing = "PING" ProtocolPong = "PONG" ProtocolGreeting = "GREETING" ProtocolGetParticipants = "GET_PARTICIPANTS" ProtocolParticipants = "PARTICIPANTS" ProtocolEditor = "EDITOR" readyForUse = pyqtSignal() newMessage = pyqtSignal(str, str) getParticipants = pyqtSignal() participants = pyqtSignal(list) editorCommand = pyqtSignal(str, str, str) rejected = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent referenec to the parent object (QObject) """ super(Connection, self).__init__(parent) self.__greetingMessage = self.tr("undefined") self.__username = self.tr("unknown") self.__serverPort = 0 self.__state = Connection.WaitingForGreeting self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = -1 self.__transferTimerId = 0 self.__isGreetingMessageSent = False self.__pingTimer = QTimer(self) self.__pingTimer.setInterval(PingInterval) self.__pongTime = QTime() self.__buffer = QByteArray() self.__client = None self.readyRead.connect(self.__processReadyRead) self.disconnected.connect(self.__disconnected) self.__pingTimer.timeout.connect(self.__sendPing) self.connected.connect(self.__sendGreetingMessage) def name(self): """ Public method to get the connection name. @return connection name (string) """ return self.__username def serverPort(self): """ Public method to get the server port. @return server port (integer) """ return self.__serverPort def setClient(self, client): """ Public method to set the reference to the cooperation client. @param client reference to the cooperation client (CooperationClient) """ self.__client = client def setGreetingMessage(self, message, serverPort): """ Public method to set the greeting message. @param message greeting message (string) @param serverPort port number to include in the message (integer) """ self.__greetingMessage = "{0}:{1}".format(message, serverPort) def sendMessage(self, message): """ Public method to send a message. @param message message to be sent (string) @return flag indicating a successful send (boolean) """ if message == "": return False msg = QByteArray(message.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolMessage, SeparatorToken, msg.size()) .encode("utf-8")) + msg return self.write(data) == data.size() def timerEvent(self, evt): """ Protected method to handle timer events. @param evt reference to the timer event (QTimerEvent) """ if evt.timerId() == self.__transferTimerId: self.abort() self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 def __processReadyRead(self): """ Private slot to handle the readyRead signal. """ if self.__state == Connection.WaitingForGreeting: if not self.__readProtocolHeader(): return if self.__currentDataType != Connection.Greeting: self.abort() return self.__state = Connection.ReadingGreeting if self.__state == Connection.ReadingGreeting: if not self.__hasEnoughData(): return self.__buffer = QByteArray( self.read(self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return try: user, serverPort = \ str(self.__buffer, encoding="utf-8").split(":") except ValueError: self.abort() return self.__serverPort = int(serverPort) hostInfo = QHostInfo.fromName(self.peerAddress().toString()) self.__username = "{0}@{1}@{2}".format( user, hostInfo.hostName(), self.peerPort() ) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() if not self.isValid(): self.abort() return bannedName = "{0}@{1}".format( user, hostInfo.hostName(), ) Preferences.syncPreferences() if bannedName in Preferences.getCooperation("BannedUsers"): self.rejected.emit(self.tr( "* Connection attempted by banned user '{0}'.") .format(bannedName)) self.abort() return if self.__serverPort != self.peerPort() and \ not Preferences.getCooperation("AutoAcceptConnections"): # don't ask for reverse connections or # if we shall accept automatically res = E5MessageBox.yesNo( None, self.tr("New Connection"), self.tr("""

Accept connection from """ """{0}@{1}?

""").format( user, hostInfo.hostName()), yesDefault=True) if not res: self.abort() return if self.__client is not None: chatWidget = self.__client.chatWidget() if chatWidget is not None and not chatWidget.isVisible(): e5App().getObject( "UserInterface").activateCooperationViewer() if not self.__isGreetingMessageSent: self.__sendGreetingMessage() self.__pingTimer.start() self.__pongTime.start() self.__state = Connection.ReadyForUse self.readyForUse.emit() while self.bytesAvailable(): if self.__currentDataType == Connection.Undefined: if not self.__readProtocolHeader(): return if not self.__hasEnoughData(): return self.__processData() def __sendPing(self): """ Private slot to send a ping message. """ if self.__pongTime.elapsed() > PongTimeout: self.abort() return self.write("{0}{1}1{1}p".format( Connection.ProtocolPing, SeparatorToken)) def __sendGreetingMessage(self): """ Private slot to send a greeting message. """ greeting = QByteArray(self.__greetingMessage.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolGreeting, SeparatorToken, greeting.size()) .encode("utf-8")) + greeting if self.write(data) == data.size(): self.__isGreetingMessageSent = True def __readDataIntoBuffer(self, maxSize=MaxBufferSize): """ Private method to read some data into the buffer. @param maxSize maximum size of data to read (integer) @return size of data read (integer) """ if maxSize > MaxBufferSize: return 0 numBytesBeforeRead = self.__buffer.size() if numBytesBeforeRead == MaxBufferSize: self.abort() return 0 while self.bytesAvailable() and self.__buffer.size() < maxSize: self.__buffer.append(self.read(1)) if self.__buffer.endsWith(SeparatorToken): break return self.__buffer.size() - numBytesBeforeRead def __dataLengthForCurrentDataType(self): """ Private method to get the data length for the current data type. @return data length (integer) """ if self.bytesAvailable() <= 0 or \ self.__readDataIntoBuffer() <= 0 or \ not self.__buffer.endsWith(SeparatorToken): return 0 self.__buffer.chop(len(SeparatorToken)) number = self.__buffer.toInt()[0] self.__buffer.clear() return number def __readProtocolHeader(self): """ Private method to read the protocol header. @return flag indicating a successful read (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__readDataIntoBuffer() <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False self.__buffer.chop(len(SeparatorToken)) if self.__buffer == Connection.ProtocolPing: self.__currentDataType = Connection.Ping elif self.__buffer == Connection.ProtocolPong: self.__currentDataType = Connection.Pong elif self.__buffer == Connection.ProtocolMessage: self.__currentDataType = Connection.PlainText elif self.__buffer == Connection.ProtocolGreeting: self.__currentDataType = Connection.Greeting elif self.__buffer == Connection.ProtocolGetParticipants: self.__currentDataType = Connection.GetParticipants elif self.__buffer == Connection.ProtocolParticipants: self.__currentDataType = Connection.Participants elif self.__buffer == Connection.ProtocolEditor: self.__currentDataType = Connection.Editor else: self.__currentDataType = Connection.Undefined self.abort() return False self.__buffer.clear() self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() return True def __hasEnoughData(self): """ Private method to check, if enough data is available. @return flag indicating availability of enough data (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__numBytesForCurrentDataType <= 0: self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() if self.bytesAvailable() < self.__numBytesForCurrentDataType or \ self.__numBytesForCurrentDataType <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False return True def __processData(self): """ Private method to process the received data. """ self.__buffer = QByteArray( self.read(self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return if self.__currentDataType == Connection.PlainText: self.newMessage.emit( self.__username, str(self.__buffer, encoding="utf-8")) elif self.__currentDataType == Connection.Ping: self.write("{0}{1}1{1}p".format( Connection.ProtocolPong, SeparatorToken)) elif self.__currentDataType == Connection.Pong: self.__pongTime.restart() elif self.__currentDataType == Connection.GetParticipants: self.getParticipants.emit() elif self.__currentDataType == Connection.Participants: msg = str(self.__buffer, encoding="utf-8") if msg == "": participantsList = [] else: participantsList = msg.split(SeparatorToken) self.participants.emit(participantsList[:]) elif self.__currentDataType == Connection.Editor: hash, fn, msg = \ str(self.__buffer, encoding="utf-8").split(SeparatorToken) self.editorCommand.emit(hash, fn, msg) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() def sendGetParticipants(self): """ Public method to request a list of participants. """ self.write( "{0}{1}1{1}l".format( Connection.ProtocolGetParticipants, SeparatorToken) ) def sendParticipants(self, participants): """ Public method to send the list of participants. @param participants list of participants (list of strings of "host:port") """ if participants: message = SeparatorToken.join(participants) else: message = "" msg = QByteArray(message.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolParticipants, SeparatorToken, msg.size()) .encode("utf-8")) + msg self.write(data) def sendEditorCommand(self, projectHash, filename, message): """ Public method to send an editor command. @param projectHash hash of the project (string) @param filename project relative universal file name of the sending editor (string) @param message editor command to be sent (string) """ msg = QByteArray("{0}{1}{2}{1}{3}".format( projectHash, SeparatorToken, filename, message).encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolEditor, SeparatorToken, msg.size()) .encode("utf-8")) + msg self.write(data) def __disconnected(self): """ Private slot to handle the connection being dropped. """ self.__pingTimer.stop() if self.__state == Connection.WaitingForGreeting: self.rejected.emit(self.tr( "* Connection to {0}:{1} refused.").format( self.peerName(), self.peerPort())) eric-6.0.8/eric/Cooperation/__init__.py0000644000175000017500000000024512451233374017045 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Package containing the modules dealing with cooperation. """ eric-6.0.8/eric/Cooperation/CooperationServer.py0000644000175000017500000000401112451233374020752 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the cooperation server. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal from PyQt5.QtNetwork import QTcpServer from .Connection import Connection import Preferences class CooperationServer(QTcpServer): """ Class implementing the cooperation server. @signal newConnection(connection) emitted after a new connection was received (Connection) """ newConnection = pyqtSignal(Connection) def __init__(self, address, parent=None): """ Constructor @param address address the server should listen on (QHostAddress) @param parent reference to the parent object (QObject) """ super(CooperationServer, self).__init__(parent) self.__address = address def incomingConnection(self, socketDescriptor): """ Public method handling an incoming connection. @param socketDescriptor native socket descriptor (integer) """ connection = Connection(self) connection.setSocketDescriptor(socketDescriptor) self.newConnection.emit(connection) def startListening(self, port=-1, findFreePort=False): """ Public method to start listening for new connections. @param port port to listen on (integer) @param findFreePort flag indicating to search for a free port depending on the configuration (boolean) @return tuple giving a flag indicating success (boolean) and the port the server listens on """ res = self.listen(self.__address, port) if findFreePort and Preferences.getCooperation("TryOtherPorts"): endPort = port + Preferences.getCooperation("MaxPortsToTry") while not res and port < endPort: port += 1 res = self.listen(self.__address, port) return res, port eric-6.0.8/eric/Cooperation/CooperationClient.py0000644000175000017500000003410412451233374020730 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the client of the cooperation package. """ from __future__ import unicode_literals import collections from PyQt5.QtCore import QObject, pyqtSignal, QProcess, QRegExp from PyQt5.QtNetwork import QHostInfo, QHostAddress, QAbstractSocket, \ QNetworkInterface from .CooperationServer import CooperationServer from .Connection import Connection import Preferences class CooperationClient(QObject): """ Class implementing the client of the cooperation package. @signal newMessage(user, message) emitted after a new message has arrived (string, string) @signal newParticipant(nickname) emitted after a new participant joined (string) @signal participantLeft(nickname) emitted after a participant left (string) @signal connectionError(message) emitted when a connection error occurs (string) @signal cannotConnect() emitted, if the initial connection fails @signal editorCommand(hash, filename, message) emitted when an editor command has been received (string, string, string) """ newMessage = pyqtSignal(str, str) newParticipant = pyqtSignal(str) participantLeft = pyqtSignal(str) connectionError = pyqtSignal(str) cannotConnect = pyqtSignal() editorCommand = pyqtSignal(str, str, str) def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(CooperationClient, self).__init__(parent) self.__chatWidget = parent self.__servers = [] for networkInterface in QNetworkInterface.allInterfaces(): for addressEntry in networkInterface.addressEntries(): address = addressEntry.ip() # fix scope of link local addresses if address.toString().lower().startswith("fe80"): address.setScopeId(networkInterface.humanReadableName()) server = CooperationServer(address, self) server.newConnection.connect(self.__newConnection) self.__servers.append(server) self.__peers = collections.defaultdict(list) self.__initialConnection = None envVariables = ["USERNAME.*", "USER.*", "USERDOMAIN.*", "HOSTNAME.*", "DOMAINNAME.*"] environment = QProcess.systemEnvironment() found = False for envVariable in envVariables: for env in environment: if QRegExp(envVariable).exactMatch(env): envList = env.split("=") if len(envList) == 2: self.__username = envList[1].strip() found = True break if found: break if self.__username == "": self.__username = self.tr("unknown") self.__listening = False self.__serversErrorString = "" def chatWidget(self): """ Public method to get a reference to the chat widget. @return reference to the chat widget (ChatWidget) """ return self.__chatWidget def sendMessage(self, message): """ Public method to send a message. @param message message to be sent (string) """ if message == "": return for connectionList in self.__peers.values(): for connection in connectionList: connection.sendMessage(message) def nickName(self): """ Public method to get the nick name. @return nick name (string) """ return "{0}@{1}@{2}".format( self.__username, QHostInfo.localHostName(), self.__servers[0].serverPort() ) def hasConnection(self, senderIp, senderPort=-1): """ Public method to check for an existing connection. @param senderIp address of the sender (QHostAddress) @param senderPort port of the sender (integer) @return flag indicating an existing connection (boolean) """ if senderPort == -1: return senderIp in self.__peers if senderIp not in self.__peers: return False for connection in self.__peers[senderIp]: if connection.peerPort() == senderPort: return True return False def hasConnections(self): """ Public method to check, if there are any connections established. @return flag indicating the presence of connections (boolean) """ for connectionList in self.__peers.values(): if connectionList: return True return False def removeConnection(self, connection): """ Public method to remove a connection. @param connection reference to the connection to be removed (Connection) """ if connection.peerAddress() in self.__peers and \ connection in self.__peers[connection.peerAddress()]: self.__peers[connection.peerAddress()].remove(connection) nick = connection.name() if nick != "": self.participantLeft.emit(nick) if connection.isValid(): connection.abort() def disconnectConnections(self): """ Public slot to disconnect from the chat network. """ for connectionList in self.__peers.values(): while connectionList: self.removeConnection(connectionList[0]) def __newConnection(self, connection): """ Private slot to handle a new connection. @param connection reference to the new connection (Connection) """ connection.setParent(self) connection.setClient(self) connection.setGreetingMessage(self.__username, self.__servers[0].serverPort()) connection.error.connect(self.__connectionError) connection.disconnected.connect(self.__disconnected) connection.readyForUse.connect(self.__readyForUse) connection.rejected.connect(self.__connectionRejected) def __connectionRejected(self, msg): """ Private slot to handle the rejection of a connection. @param msg error message (string) """ self.connectionError.emit(msg) def __connectionError(self, socketError): """ Private slot to handle a connection error. @param socketError reference to the error object (QAbstractSocket.SocketError) """ connection = self.sender() if socketError != QAbstractSocket.RemoteHostClosedError: if connection.peerPort() != 0: msg = "* {0}:{1}\n{2}\n".format( connection.peerAddress().toString(), connection.peerPort(), connection.errorString() ) else: msg = "* {0}\n".format(connection.errorString()) self.connectionError.emit(msg) if connection == self.__initialConnection: self.cannotConnect.emit() self.removeConnection(connection) def __disconnected(self): """ Private slot to handle the disconnection of a chat client. """ connection = self.sender() self.removeConnection(connection) def __readyForUse(self): """ Private slot to handle a connection getting ready for use. """ connection = self.sender() if self.hasConnection(connection.peerAddress(), connection.peerPort()): return connection.newMessage.connect(self.newMessage) connection.getParticipants.connect(self.__getParticipants) connection.editorCommand.connect(self.editorCommand) self.__peers[connection.peerAddress()].append(connection) nick = connection.name() if nick != "": self.newParticipant.emit(nick) if connection == self.__initialConnection: connection.sendGetParticipants() self.__initialConnection = None def connectToHost(self, host, port): """ Public method to connect to a host. @param host host to connect to (string) @param port port to connect to (integer) """ self.__initialConnection = Connection(self) self.__newConnection(self.__initialConnection) self.__initialConnection.participants.connect( self.__processParticipants) self.__initialConnection.connectToHost(host, port) def __getParticipants(self): """ Private slot to handle the request for a list of participants. """ reqConnection = self.sender() participants = [] for connectionList in self.__peers.values(): for connection in connectionList: if connection != reqConnection: participants.append("{0}@{1}".format( connection.peerAddress().toString(), connection.serverPort())) reqConnection.sendParticipants(participants) def __processParticipants(self, participants): """ Private slot to handle the receipt of a list of participants. @param participants list of participants (list of strings of "host:port") """ for participant in participants: host, port = participant.split("@") port = int(port) if port == 0: msg = self.tr("Illegal address: {0}@{1}\n").format( host, port) self.connectionError.emit(msg) else: if not self.hasConnection(QHostAddress(host), port): connection = Connection(self) self.__newConnection(connection) connection.connectToHost(host, port) def sendEditorCommand(self, projectHash, filename, message): """ Public method to send an editor command. @param projectHash hash of the project (string) @param filename project relative universal file name of the sending editor (string) @param message editor command to be sent (string) """ for connectionList in self.__peers.values(): for connection in connectionList: connection.sendEditorCommand(projectHash, filename, message) def __findConnections(self, nick): """ Private method to get a list of connection given a nick name. @param nick nick name in the format of self.nickName() (string) @return list of references to the connection objects (list of Connection) """ if "@" not in nick: # nick given in wrong format return [] user, host, port = nick.split("@") senderIp = QHostAddress(host) if senderIp not in self.__peers: return [] return self.__peers[senderIp][:] def kickUser(self, nick): """ Public method to kick a user by its nick name. @param nick nick name in the format of self.nickName() (string) """ for connection in self.__findConnections(nick): connection.abort() def banUser(self, nick): """ Public method to ban a user by its nick name. @param nick nick name in the format of self.nickName() (string) """ Preferences.syncPreferences() user = nick.rsplit("@")[0] bannedUsers = Preferences.getCooperation("BannedUsers")[:] if user not in bannedUsers: bannedUsers.append(user) Preferences.setCooperation("BannedUsers", bannedUsers) def banKickUser(self, nick): """ Public method to ban and kick a user by its nick name. @param nick nick name in the format of self.nickName() (string) """ self.banUser(nick) self.kickUser(nick) def startListening(self, port=-1): """ Public method to start listening for new connections. @param port port to listen on (integer) @return tuple giving a flag indicating success (boolean) and the port the server listens on """ if self.__servers: # do first server and determine free port res, port = self.__servers[0].startListening(port, True) if res and len(self.__servers) > 1: for server in self.__servers[1:]: res, port = server.startListening(port, False) if not res: self.__serversErrorString = server.errorString() else: self.__serversErrorString = self.__servers[0].errorString() else: res = False self.__serversErrorString = self.tr("No servers present.") if res: self.__serversErrorString = "" self.__listening = res return res, port def isListening(self): """ Public method to check, if the client is listening for connections. @return flag indicating the listening state (boolean) """ return self.__listening def close(self): """ Public method to close all connections and stop listening. """ for server in self.__servers: server.close() self.__listening = False def errorString(self): """ Public method to get a human readable error message about the last server error. @return human readable error message about the last server error (string) """ return self.__serversErrorString eric-6.0.8/eric/README-i18n.txt0000644000175000017500000000150112371442452014721 0ustar piotrpiotrREADME for the eric6 IDE's translations Installation of translations Translations of the eric6 IDE are available as separate downloads. There are two ways to install them. The first possibility is to install them together with eric6. In order to do that, simply extract the downloaded archives into the same place as the eric6 archive and follow the installation instructions of the eric6 README. The second possibility is to install them separately. Extract the downloaded archives and execute the install-i18n.py script (type python install-i18n.py -h for some help). This way you can make the translations available to everybody or just to the user executing the installation command (if using the -p switch). eric-6.0.8/eric/__init__.py0000644000175000017500000000044512451233374014565 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2003 - 2015 Detlev Offenbach # """ Package implementing the eric6 Python IDE (version 6.0). To get more information about eric6 please see the eric web site. """ eric-6.0.8/eric/i18n/0000755000175000017500000000000012557365406013241 5ustar piotrpiotreric-6.0.8/eric/README0000644000175000017500000002425112550434210013325 0ustar piotrpiotrREADME for the eric6 IDE Installation Installing eric6 is a simple process. Just execute the install.py script (type python install.py -h for some help). Please note that the installation has to be performed using the administrators account (i.e. root on linux). This installs a wrapper script called eric6 in the standard executable directory. If you want to uninstall the package just execute the uninstall.py script. This gets rid of all installed files. In this case please send an email to the below mentioned address and tell me your reason. This might give me a hint on how to improve eric6. eric6 may be used with any combination of Python 3 or 2, Qt5 or Qt4 and PyQt5 or PyQt4. If the required packages (Qt5/4, QScintilla2, sip and PyQt5/4) are not installed, please get them and install them in the following order (order is important). 1. Install Qt5 (or Qt4) (from The Qt Company) 2. Build and install QScintilla2 (from Riverbank Computing) 3. Build and install sip (from Riverbank Computing) 4. Build and install PyQt5 (or PyQt4) (from Riverbank Computing) 5. Build and install QScintilla2 Python bindings (part of the QScintilla2 package) 6. Install eric6 If you want to use the interfaces to other supported software packages, you may install them in any order and at any time. Please note, that the QScintilla2 Python bindings have to be rebuild, if the PyQt5 package gets updated. If this step is omitted, a bunch of strange errors will occur. Installation on Windows® Installing eric6 on Windows® is even easier. Just download the PyQt5 installer from Riverbank Computing and use it to install PyQt5. This includes all the required Qt5 libraries and tools as well as QScintilla. Once this installation is completed install eric6. Installation of translations Translations of the eric6 IDE are available as separate downloads. There are two ways to install them. The first possibility is to install them together with eric6. In order to do that, simply extract the downloaded archives into the same place as the eric6 archive and follow the installation instructions above. The second possibility is to install them separately. Extract the downloaded archives and execute the install-i18n.py script (type python install-i18n.py -h for some help). This way you can make the translations available to everybody or just to the user executing the installation command (if using the -p switch). Running Just call up eric6, which will start the IDE. Use the "what is"-help (arrow with ?) to get some help. The eric web site provides some documents describing certain aspects of eric. To start the unit test module in a standalone variant simply call up eric6_unittest. This will show the same dialog (though with a little bit less functionality) as if started from within eric6. The web browser can be started as a standalone program by executing the eric6_webbrowser script. Please note, the first time you start eric6 it will recognize, that it hasn't been configured yet and will show the configuration dialog. Please take your time and go through all the configuration items. However, every configuration option has a meaningful default value. Running from the sources If you want to run eric6 from within the source tree you have to execute the compileUiFiles.py script once after a fresh checkout from the source repository or when new dialogs have been added. Thereafter just execute the eric6.py script. Tray starter eric6 comes with a little utility called "eric6_tray". This embeds an icon in the system tray, which contains a context menu to start eric6 and all it's utilities. Double clicking this icon starts the eric6 IDE. Autocompletion/Calltips eric6 provides an interface to the QScintilla auto-completion and calltips functionality. QScintilla2 comes with API files for Python and itself. PyQt4 and PyQt5 contain API files as well. These are installed by default, if the correct installation order (see above) is followed. An API file for eric6 is installed in the same place. In order to use autocompletion and calltips in eric6 please configure these functions in the "Preferences Dialog" on the "Editor -> APIs", "Editor -> Autocompletion" and "Editor -> Calltips" pages. Remote Debugger In order to enable the remote debugger start eric6, open the preferences dialog and configure the settings on the debugger pages. The remote login must be possible without any further interaction (i.e. no password prompt). If the remote setup differs from the local one you must configure the Python interpreter and the Debug Client to be used in the Preferences dialog. eric6 includes two different versions of the debug client. DebugClient.py is the traditional debugger and DebugClientThreads.py is a multithreading variant of the debug client. Please copy all needed files to a place accessible through the Python path of the remote machine and set the entries of the a.m. configuration tab accordingly. Passive Debugging Passive debugging mode allows the startup of the debugger from outside of the IDE. The IDE waits for a connection attempt. For further details see the file README-passive-debugging.txt Plug-in System eric6 contains a plug-in system, that is used to extend eric6's functionality. Some plug-ins are part of eric6. Additional plug-ins are available via the Internet. Please use the built-in plug-in repository dialog to get a list of available (official) plug-ins and to download them. For more details about the plug-in system please see the documentation area. Interfaces to additional software packages At the moment eric6 provides interfaces to the following software packages. Qt-Designer This is part of the Qt distribution and is used to generate user interfaces. Qt-Linguist This is part of the Qt distribution and is used to generate translations. Qt-Assistant This is part of the Qt distribution and may be used to display help files. Mercurial This is a distributed version control system available from . It is the one used by eric6 itself. Subversion This is a version control system available from . eric6 supports two different Subversion interfaces. One is using the svn command line tool, the other is using the PySvn Python interface . The selection is done automatically depending on the installed software. The PySvn interface is prefered. This automatism can be overridden an a per project basis using the "User Properties" dialog. coverage.py This is a tool to check Python code coverage. A slightly modified version is part of the eric6 distribution. The original version is available from tabnanny This is a tool to check Python code for white-space related problems. It is part of the standard Python installation. profile This is part of the standard Python distribution and is used to profile Python source code. Internationalization eric6 and its tools are prepared to show the UI in different languages, which can be configured via the preferences dialog. The Qt and QScintilla translations are searched in the translations directory given in the preferences dialog (Qt page). If the translations cannot be found, some part of the MMI might show English texts even if you have selected something else. If you are missing eric6 translations for your language and are willing to volunteer for this work please send me an email naming the country code and I will send you the respective Qt-Linguist file. Window Layout eric6 provides different window layouts. In these layouts, the shell window and the file browser may be embedded or be separat windows. Source code documentation eric6 has a built in source code documentation generator, which is usable via the commandline as well. For further details please see the file README-eric6-doc.txt License eric6 (and the others) is released under the conditions of the GPL. See separate license file for more details. Third party software included in eric6 is released under their respective license and contained in the eric6 distribution for convenience. Bugs and other reports Please send bug reports, feature requests or contributions to eric bugs address. After the IDE is installed you can use the "Report Bug..." entry of the Help menu, which will send an email to # """ Eric6 Editor. This is the main Python script that performs the necessary initialization of the MiniEditor module and starts the Qt event loop. This is a standalone version of the integrated MiniEditor module. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys import os for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break # make ThirdParty package available as a packages repository sys.path.insert(2, os.path.join(os.path.dirname(__file__), "ThirdParty", "Pygments")) from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from QScintilla.MiniEditor import MiniEditor if len(argv) > 1: return MiniEditor(argv[1]) else: return MiniEditor() def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ("", "name of file to edit") ] appinfo = AppInfo.makeAppInfo(sys.argv, "Eric6 Editor", "", "Simplified version of the eric6 editor", options) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/eric6_webbrowser.desktop0000644000175000017500000000071012456712102017307 0ustar piotrpiotr[Desktop Entry] Version=1.0 Type=Application Exec=eric6_webbrowser@MARKER@ MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https; Icon=ericWeb@MARKER@ Terminal=false Name=eric6 Web Browser@PY_MARKER@ Name[de]=eric6 Web Browser@PY_MARKER@ Comment=Web Browser for PyQt5 Comment[de]=Web Browser für PyQt5 GenericName=Web Browser GenericName[de]=Web Browser Categories=Qt;Python;Network;WebBrowser; StartupNotify=true eric-6.0.8/eric/VCS/0000755000175000017500000000000012557365404013113 5ustar piotrpiotreric-6.0.8/eric/VCS/RepositoryInfoDialog.ui0000644000175000017500000000332012060166053017547 0ustar piotrpiotr VcsRepositoryInfoDialog 0 0 590 437 Repository Information true true Qt::Horizontal QDialogButtonBox::Close qPixmapFromMimeSource buttonBox accepted() VcsRepositoryInfoDialog accept() 48 419 50 437 buttonBox rejected() VcsRepositoryInfoDialog reject() 226 422 233 440 eric-6.0.8/eric/VCS/ProjectBrowserHelper.py0000644000175000017500000003467212451233374017604 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the base class of the VCS project browser helper. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QDialog from E5Gui.E5Application import e5App from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog from Project.ProjectBrowserModel import ProjectBrowserSimpleDirectoryItem, \ ProjectBrowserFileItem, ProjectBrowserDirectoryItem import Preferences class VcsProjectBrowserHelper(QObject): """ Class implementing the base class of the VCS project browser helper. """ def __init__(self, vcsObject, browserObject, projectObject, isTranslationsBrowser, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param browserObject reference to the project browser object @param projectObject reference to the project object @param isTranslationsBrowser flag indicating, the helper is requested for the translations browser (this needs some special treatment) @param parent parent widget (QWidget) @param name name of this object (string) """ super(VcsProjectBrowserHelper, self).__init__(parent) if name: self.setObjectName(name) self.vcs = vcsObject self.browser = browserObject self.isTranslationsBrowser = isTranslationsBrowser self.project = projectObject def addVCSMenus(self, mainMenu, multiMenu, backMenu, dirMenu, dirMultiMenu): """ Public method to add the VCS entries to the various project browser menus. @param mainMenu reference to the main menu (QPopupMenu) @param multiMenu reference to the multiple selection menu (QPopupMenu) @param backMenu reference to the background menu (QPopupMenu) @param dirMenu reference to the directory menu (QPopupMenu) @param dirMultiMenu reference to the multiple selection directory menu (QPopupMenu) """ self._addVCSMenu(mainMenu) self._addVCSMenuMulti(multiMenu) self._addVCSMenuBack(backMenu) self._addVCSMenuDir(dirMenu) self._addVCSMenuDirMulti(dirMultiMenu) def showContextMenu(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the file status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def showContextMenuMulti(self, menu, standardItems): """ Public slot called before the context menu (multiple selections) is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the files status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def showContextMenuDir(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the directory status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def showContextMenuDirMulti(self, menu, standardItems): """ Public slot called before the context menu is shown. It enables/disables the VCS menu entries depending on the overall VCS status and the directory status. @param menu reference to the menu to be shown @param standardItems array of standard items that need activation/deactivation depending on the overall VCS status @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') ########################################################################### ## General menu handling methods below ########################################################################### def _VCSUpdate(self): """ Protected slot called by the context menu to update a file from the VCS repository. """ if self.isTranslationsBrowser: names = [itm.dirName() for itm in self.browser.getSelectedItems( [ProjectBrowserSimpleDirectoryItem])] if not names: names = [itm.fileName() for itm in self.browser.getSelectedItems( [ProjectBrowserFileItem])] else: names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) self.vcs.vcsUpdate(names) def _VCSCommit(self): """ Protected slot called by the context menu to commit the changes to the VCS repository. """ if self.isTranslationsBrowser: names = [itm.dirName() for itm in self.browser.getSelectedItems( [ProjectBrowserSimpleDirectoryItem])] if not names: names = [itm.fileName() for itm in self.browser.getSelectedItems( [ProjectBrowserFileItem])] else: names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) if Preferences.getVCS("AutoSaveFiles"): vm = e5App().getObject("ViewManager") for name in names: vm.saveEditor(name) self.vcs.vcsCommit(names, '') def _VCSAdd(self): """ Protected slot called by the context menu to add the selected file to the VCS repository. """ if self.isTranslationsBrowser: items = self.browser.getSelectedItems( [ProjectBrowserSimpleDirectoryItem]) if items: names = [itm.dirName() for itm in items] qnames = [] else: items = self.browser.getSelectedItems([ProjectBrowserFileItem]) names = [] qnames = [] for itm in items: name = itm.fileName() if name.endswith('.qm'): qnames.append(name) else: names.append(name) else: names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) qnames = [] if not len(names + qnames): return if len(names + qnames) == 1: if names: self.vcs.vcsAdd(names[0], os.path.isdir(names[0])) else: if self.vcs.canDetectBinaries: self.vcs.vcsAdd(qnames) else: self.vcs.vcsAddBinary(qnames) else: if self.vcs.canDetectBinaries: self.vcs.vcsAdd(names + qnames) else: self.vcs.vcsAdd(names) if len(qnames): self.vcs.vcsAddBinary(qnames) for fn in names + qnames: self._updateVCSStatus(fn) def _VCSAddTree(self): """ Protected slot called by the context menu. It is used to add the selected directory tree to the VCS repository. """ names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) self.vcs.vcsAddTree(names) for fn in names: self._updateVCSStatus(fn) def _VCSRemove(self): """ Protected slot called by the context menu to remove the selected file from the VCS repository. """ if self.isTranslationsBrowser: items = self.browser.getSelectedItems( [ProjectBrowserSimpleDirectoryItem]) if items: return # not supported isRemoveDirs = False items = self.browser.getSelectedItems([ProjectBrowserFileItem]) names = [itm.fileName() for itm in items] dlg = DeleteFilesConfirmationDialog( self.parent(), self.tr("Remove from repository (and disk)"), self.tr( "Do you really want to remove these translation files from" " the repository (and disk)?"), names) else: items = self.browser.getSelectedItems() isRemoveDirs = len(items) == \ self.browser.getSelectedItemsCount( [ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem]) if isRemoveDirs: names = [itm.dirName() for itm in items] else: names = [itm.fileName() for itm in items] files = [self.browser.project.getRelativePath(name) for name in names] dlg = DeleteFilesConfirmationDialog( self.parent(), self.tr("Remove from repository (and disk)"), self.tr( "Do you really want to remove these files/directories" " from the repository (and disk)?"), files) if dlg.exec_() == QDialog.Accepted: status = self.vcs.vcsRemove(names) if status: if isRemoveDirs: self.browser._removeDir() # remove directories from Project else: self.browser._removeFile() # remove file(s) from project def _VCSLog(self): """ Protected slot called by the context menu to show the VCS log of a file/directory. """ itm = self.browser.currentItem() try: fn = itm.fileName() except AttributeError: fn = itm.dirName() self.vcs.vcsLog(fn) def _VCSLogBrowser(self): """ Protected slot called by the context menu to show the log browser for a file. """ itm = self.browser.currentItem() try: fn = itm.fileName() isFile = True except AttributeError: fn = itm.dirName() isFile = False self.vcs.vcsLogBrowser(fn, isFile=isFile) def _VCSDiff(self): """ Protected slot called by the context menu to show the difference of a file/directory to the repository. """ names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) self.vcs.vcsDiff(names) def _VCSStatus(self): """ Protected slot called by the context menu to show the status of a file. """ if self.isTranslationsBrowser: items = self.browser.getSelectedItems( [ProjectBrowserSimpleDirectoryItem]) if items: names = [itm.dirName() for itm in items] else: items = self.browser.getSelectedItems([ProjectBrowserFileItem]) names = [itm.fileName() for itm in items] else: names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) self.vcs.vcsStatus(names) def _VCSRevert(self): """ Protected slot called by the context menu to revert changes made to a file. """ names = [] for itm in self.browser.getSelectedItems(): try: name = itm.fileName() except AttributeError: name = itm.dirName() names.append(name) self.vcs.vcsRevert(names) def _VCSMerge(self): """ Protected slot called by the context menu to merge changes into to a file. """ itm = self.browser.currentItem() try: name = itm.fileName() except AttributeError: name = itm.dirName() self.vcs.vcsMerge(name) def _VCSInfoDisplay(self): """ Protected slot called to show some vcs information. """ from .RepositoryInfoDialog import VcsRepositoryInfoDialog info = self.vcs.vcsRepositoryInfos(self.project.ppath) dlg = VcsRepositoryInfoDialog(None, info) dlg.exec_() def _updateVCSStatus(self, name): """ Protected method to update the VCS status of an item. @param name filename or directoryname of the item to be updated (string) """ self.project.getModel().updateVCSStatus(name) eric-6.0.8/eric/VCS/CommandOptionsDialog.ui0000644000175000017500000002456212230462130017513 0ustar piotrpiotr VcsCommandOptionsDialog 0 0 531 413 VCS Command Options <b>VCS Command Options Dialog</b> <p>Enter the options for the different VCS commands. The "Global Options" entry applies to all VCS commands.</p> true &History Options: historyEdit &Add Options: addEdit &Remove Options: removeEdit &Tag Options: tagEdit Enter the options for the commit command. <b>Commit Options</b> <p>Enter the options for the commit command.</p> Enter the options for the history command. <b>History Options</b> <p>Enter the options for the history command.</p> Enter the options for the diff command. <b>Diff Options</b> <p>Enter the options for the diff command.</p> Enter the options for the update command. <b>Update Options</b> <p>Enter the options for the update command.</p> Enter the options for the log command. <b>Log Options</b> <p>Enter the options for the log command.</p> Enter the options for the tag command. <b>Tag Options</b> <p>Enter the options for the tag command.</p> Enter the options for the status command. <b>Status Options</b> <p>Enter the options for the status command.</p> &Diff Options: diffEdit &Global Options: globalEdit Enter the options for the export command. <b>Export Options</b> <p>Enter the options for the export command.</p> Enter the options for the add command. <b>Add Options</b> <p>Enter the options for the add command.</p> &Log Options: logEdit &StatusOptions: statusEdit Enter the options for the remove command. <b>Remove Options</b> <p>Enter the options for the remove command.</p> Enter the options for the checkout command. <b>Checkout Options</b> <p>Enter the options for the checkout command.</p> Co&mmit Options: commitEdit &Export Options: exportEdit Check&out Options: checkoutEdit &Update Options: updateEdit Enter the global options. <b>Global Options</b> <p>Enter the global options.</p> Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok qPixmapFromMimeSource globalEdit commitEdit checkoutEdit updateEdit addEdit removeEdit diffEdit logEdit historyEdit statusEdit tagEdit exportEdit buttonBox accepted() VcsCommandOptionsDialog accept() 120 390 120 411 buttonBox rejected() VcsCommandOptionsDialog reject() 191 390 193 410 eric-6.0.8/eric/VCS/RepositoryInfoDialog.py0000644000175000017500000000142312451233374017571 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Module implemting a dialog to show repository information. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_RepositoryInfoDialog import Ui_VcsRepositoryInfoDialog class VcsRepositoryInfoDialog(QDialog, Ui_VcsRepositoryInfoDialog): """ Class implemting a dialog to show repository information. """ def __init__(self, parent, info): """ Constructor @param parent reference to the parent widget (QWidget) @param info info data to show (string) """ super(VcsRepositoryInfoDialog, self).__init__(parent) self.setupUi(self) self.infoBrowser.setHtml(info) eric-6.0.8/eric/VCS/StatusMonitorLed.py0000644000175000017500000001343012451233374016737 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a LED to indicate the status of the VCS status monitor thread. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QInputDialog, QMenu from E5Gui.E5Led import E5ClickableLed, E5LedRectangular import Preferences class StatusMonitorLed(E5ClickableLed): """ Class implementing a LED to indicate the status of the VCS status monitor thread. """ def __init__(self, project, parent): """ Constructor @param project reference to the project object (Project.Project) @param parent reference to the parent object (QWidget) """ super(StatusMonitorLed, self).__init__( parent, shape=E5LedRectangular, rectRatio=1.0) self.__vcsClean = True self.project = project self.vcsMonitorLedColors = { "off": QColor(Qt.lightGray), "ok": QColor(Qt.green), "nok": QColor(Qt.red), "op": QColor(Qt.yellow), "send": QColor(Qt.blue), "wait": QColor(Qt.cyan), "timeout": QColor(Qt.darkRed) } self.__on = False self.setWhatsThis(self.tr( """

This LED indicates the operating""" """ status of the VCS monitor thread (off = monitoring off,""" """ green = monitoring on and ok, red = monitoring on, but""" """ not ok, yellow = checking VCS status). A status description""" """ is given in the tooltip.

""" )) self.setToolTip( self.tr("Repository status checking is switched off") ) self.setColor(self.vcsMonitorLedColors["off"]) # define a context menu self.__menu = QMenu(self) self.__checkAct = self.__menu.addAction( self.tr("Check status"), self.__checkStatus) self.__intervalAct = self.__menu.addAction( self.tr("Set interval..."), self.__setInterval) self.__menu.addSeparator() self.__onAct = self.__menu.addAction( self.tr("Switch on"), self.__switchOn) self.__offAct = self.__menu.addAction( self.tr("Switch off"), self.__switchOff) self.__checkActions() # connect signals to our slots self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._showContextMenu) self.project.vcsStatusMonitorStatus.connect( self.__projectVcsMonitorStatus) self.project.getModel().vcsStateChanged.connect(self.__vcsStateChanged) self.clicked.connect(self.__ledClicked) def __checkActions(self): """ Private method to set the enabled status of the context menu actions. """ if self.project.pudata["VCSSTATUSMONITORINTERVAL"]: vcsStatusMonitorInterval = \ self.project.pudata["VCSSTATUSMONITORINTERVAL"][0] else: vcsStatusMonitorInterval = \ Preferences.getVCS("StatusMonitorInterval") self.__checkAct.setEnabled(self.__on) self.__intervalAct.setEnabled(self.__on) self.__onAct.setEnabled( (not self.__on) and vcsStatusMonitorInterval > 0) self.__offAct.setEnabled(self.__on) def __projectVcsMonitorStatus(self, status, statusMsg): """ Private method to receive the status monitor status. @param status status of the monitoring thread (string, ok, nok or off) @param statusMsg explanotory text for the signaled status (string) """ self.setColor(self.vcsMonitorLedColors[status]) self.setToolTip(statusMsg) self.__on = status != 'off' def _showContextMenu(self, coord): """ Protected slot to show the context menu. @param coord the position of the mouse pointer (QPoint) """ if not self.project.isOpen(): return self.__checkActions() self.__menu.popup(self.mapToGlobal(coord)) def __checkStatus(self): """ Private slot to initiate a new status check. """ self.project.checkVCSStatus() def __setInterval(self): """ Private slot to change the status check interval. """ interval, ok = QInputDialog.getInt( None, self.tr("VCS Status Monitor"), self.tr("Enter monitor interval [s]"), self.project.getStatusMonitorInterval(), 0, 3600, 1) if ok: self.project.setStatusMonitorInterval(interval) def __switchOn(self): """ Private slot to switch the status monitor thread to On. """ self.project.startStatusMonitor() def __switchOff(self): """ Private slot to switch the status monitor thread to Off. """ self.project.stopStatusMonitor() def __vcsStateChanged(self, state): """ Private slot to handle a change in the vcs state. @param state new vcs state (string) """ self.__vcsClean = state == " " def __ledClicked(self, pos): """ Private slot to react upon clicks on the LED. @param pos position of the click (QPoint) """ if self.__on: vcs = self.project.getVcs() if vcs: if self.__vcsClean: # call log browser dialog vcs.vcsLogBrowser(self.project.getProjectPath()) else: # call status dialog vcs.vcsStatus(self.project.getProjectPath()) eric-6.0.8/eric/VCS/ProjectHelper.py0000644000175000017500000005050112451233374016225 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2005 - 2015 Detlev Offenbach # """ Module implementing the base class of the VCS project helper. """ from __future__ import unicode_literals import os import shutil import copy from PyQt5.QtCore import pyqtSlot, QDir, QFileInfo, QObject from PyQt5.QtWidgets import QDialog, QInputDialog from E5Gui.E5Action import E5Action from E5Gui import E5MessageBox from E5Gui.E5Application import e5App import Preferences class VcsProjectHelper(QObject): """ Class implementing the base class of the VCS project helper. """ def __init__(self, vcsObject, projectObject, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param projectObject reference to the project object @param parent parent widget (QWidget) @param name name of this object (string) """ super(VcsProjectHelper, self).__init__(parent) if name: self.setObjectName(name) self.vcs = vcsObject self.project = projectObject self.actions = [] self.vcsAddAct = None self.initActions() def setObjects(self, vcsObject, projectObject): """ Public method to set references to the vcs and project objects. @param vcsObject reference to the vcs object @param projectObject reference to the project object """ self.vcs = vcsObject self.project = projectObject def initActions(self): """ Public method to generate the action objects. """ self.vcsNewAct = E5Action( self.tr('New from repository'), self.tr('&New from repository...'), 0, 0, self, 'vcs_new') self.vcsNewAct.setStatusTip(self.tr( 'Create a new project from the VCS repository' )) self.vcsNewAct.setWhatsThis(self.tr( """New from repository""" """

This creates a new local project from the VCS""" """ repository.

""" )) self.vcsNewAct.triggered.connect(self._vcsCheckout) self.actions.append(self.vcsNewAct) self.vcsExportAct = E5Action( self.tr('Export from repository'), self.tr('&Export from repository...'), 0, 0, self, 'vcs_export') self.vcsExportAct.setStatusTip(self.tr( 'Export a project from the repository' )) self.vcsExportAct.setWhatsThis(self.tr( """Export from repository""" """

This exports a project from the repository.

""" )) self.vcsExportAct.triggered.connect(self._vcsExport) self.actions.append(self.vcsExportAct) self.vcsAddAct = E5Action( self.tr('Add to repository'), self.tr('&Add to repository...'), 0, 0, self, 'vcs_add') self.vcsAddAct.setStatusTip(self.tr( 'Add the local project to the VCS repository' )) self.vcsAddAct.setWhatsThis(self.tr( """Add to repository""" """

This adds (imports) the local project to the VCS""" """ repository.

""" )) self.vcsAddAct.triggered.connect(self._vcsImport) self.actions.append(self.vcsAddAct) def initMenu(self, menu): """ Public method to generate the VCS menu. @param menu reference to the menu to be populated (QMenu) """ menu.clear() menu.addAction(self.vcsNewAct) menu.addAction(self.vcsExportAct) menu.addSeparator() menu.addAction(self.vcsAddAct) menu.addSeparator() def showMenu(self): """ Public slot called before the vcs menu is shown. """ if self.vcsAddAct: self.vcsAddAct.setEnabled(self.project.isOpen()) @pyqtSlot() def _vcsCheckout(self, export=False): """ Protected slot used to create a local project from the repository. @param export flag indicating whether an export or a checkout should be performed """ if not self.project.checkDirty(): return vcsSystemsDict = e5App().getObject("PluginManager")\ .getPluginDisplayStrings("version_control") if not vcsSystemsDict: # no version control system found return vcsSystemsDisplay = [] keys = sorted(vcsSystemsDict.keys()) for key in keys: vcsSystemsDisplay.append(vcsSystemsDict[key]) vcsSelected, ok = QInputDialog.getItem( None, self.tr("New Project"), self.tr("Select version control system for the project"), vcsSystemsDisplay, 0, False) if not ok: return for vcsSystem, vcsSystemDisplay in list(vcsSystemsDict.items()): if vcsSystemDisplay == vcsSelected: break if not self.project.closeProject(): return self.project.pdata["VCS"] = [vcsSystem] self.project.vcs = self.project.initVCS(vcsSystem) if self.project.vcs is not None: vcsdlg = self.project.vcs.vcsNewProjectOptionsDialog() if vcsdlg.exec_() == QDialog.Accepted: projectdir, vcsDataDict = vcsdlg.getData() self.project.pdata["VCS"] = [vcsSystem] self.project.vcs = self.project.initVCS(vcsSystem) # edit VCS command options if self.project.vcs.vcsSupportCommandOptions(): vcores = E5MessageBox.yesNo( self.parent(), self.tr("New Project"), self.tr( """Would you like to edit the VCS command""" """ options?""")) else: vcores = False if vcores: from .CommandOptionsDialog import VcsCommandOptionsDialog codlg = VcsCommandOptionsDialog(self.project.vcs) if codlg.exec_() == QDialog.Accepted: self.project.vcs.vcsSetOptions(codlg.getOptions()) # create the project directory if it doesn't exist already if not os.path.isdir(projectdir): try: os.makedirs(projectdir) except EnvironmentError: E5MessageBox.critical( self.parent(), self.tr("Create project directory"), self.tr( "

The project directory {0} could not" " be created.

").format(projectdir)) self.project.pdata["VCS"] = ['None'] self.project.vcs = self.project.initVCS() return # create the project from the VCS self.project.vcs.vcsSetDataFromDict(vcsDataDict) if export: ok = self.project.vcs.vcsExport(vcsDataDict, projectdir) else: ok = self.project.vcs.vcsCheckout(vcsDataDict, projectdir, False) if ok: projectdir = os.path.normpath(projectdir) filters = ["*.e4p"] d = QDir(projectdir) plist = d.entryInfoList(filters) if len(plist): if len(plist) == 1: self.project.openProject( plist[0].absoluteFilePath()) self.project.newProject.emit() else: pfilenamelist = d.entryList(filters) pfilename, ok = QInputDialog.getItem( None, self.tr("New project from repository"), self.tr("Select a project file to open."), pfilenamelist, 0, False) if ok: self.project.openProject( QFileInfo(d, pfilename).absoluteFilePath()) self.project.newProject.emit() if export: self.project.pdata["VCS"] = ['None'] self.project.vcs = self.project.initVCS() self.project.setDirty(True) self.project.saveProject() else: res = E5MessageBox.yesNo( self.parent(), self.tr("New project from repository"), self.tr( "The project retrieved from the repository" " does not contain an eric project file" " (*.e4p). Create it?"), yesDefault=True) if res: self.project.ppath = projectdir self.project.opened = True from Project.PropertiesDialog import \ PropertiesDialog dlg = PropertiesDialog(self.project, False) if dlg.exec_() == QDialog.Accepted: dlg.storeData() self.project.initFileTypes() self.project.setDirty(True) try: ms = os.path.join( self.project.ppath, self.project.pdata["MAINSCRIPT"][0]) if os.path.exists(ms): self.project.appendFile(ms) except IndexError: ms = "" self.project.newProjectAddFiles(ms) self.project.createProjectManagementDir() self.project.saveProject() self.project.openProject(self.project.pfile) if not export: res = E5MessageBox.yesNo( self.parent(), self.tr( "New project from repository"), self.tr( "Shall the project file be added" " to the repository?"), yesDefault=True) if res: self.project.vcs.vcsAdd( self.project.pfile) else: E5MessageBox.critical( self.parent(), self.tr("New project from repository"), self.tr( """The project could not be retrieved from""" """ the repository.""")) self.project.pdata["VCS"] = ['None'] self.project.vcs = self.project.initVCS() else: self.project.pdata["VCS"] = ['None'] self.project.vcs = self.project.initVCS() def _vcsExport(self): """ Protected slot used to export a project from the repository. """ self._vcsCheckout(True) def _vcsImport(self): """ Protected slot used to import the local project into the repository. NOTE: This does not necessarily make the local project a vcs controlled project. You may have to checkout the project from the repository in order to accomplish that. """ def revertChanges(): """ Local function to revert the changes made to the project object. """ self.project.pdata["VCS"] = pdata_vcs[:] self.project.pdata["VCSOPTIONS"] = copy.deepcopy(pdata_vcsoptions) self.project.pdata["VCSOTHERDATA"] = copy.deepcopy(pdata_vcsother) self.project.vcs = vcs self.project.vcsProjectHelper = vcsHelper self.project.vcsBasicHelper = vcs is None self.initMenu(self.project.vcsMenu) self.project.setDirty(True) self.project.saveProject() pdata_vcs = self.project.pdata["VCS"][:] pdata_vcsoptions = copy.deepcopy(self.project.pdata["VCSOPTIONS"]) pdata_vcsother = copy.deepcopy(self.project.pdata["VCSOTHERDATA"]) vcs = self.project.vcs vcsHelper = self.project.vcsProjectHelper vcsSystemsDict = e5App().getObject("PluginManager")\ .getPluginDisplayStrings("version_control") if not vcsSystemsDict: # no version control system found return vcsSystemsDisplay = [] keys = sorted(list(vcsSystemsDict.keys())) for key in keys: vcsSystemsDisplay.append(vcsSystemsDict[key]) vcsSelected, ok = QInputDialog.getItem( None, self.tr("Import Project"), self.tr("Select version control system for the project"), vcsSystemsDisplay, 0, False) if not ok: return for vcsSystem, vcsSystemDisplay in list(vcsSystemsDict.items()): if vcsSystemDisplay == vcsSelected: break self.project.pdata["VCS"] = [vcsSystem] self.project.vcs = self.project.initVCS(vcsSystem) if self.project.vcs is not None: vcsdlg = self.project.vcs.vcsOptionsDialog(self.project, self.project.name, 1) if vcsdlg.exec_() == QDialog.Accepted: vcsDataDict = vcsdlg.getData() # edit VCS command options if self.project.vcs.vcsSupportCommandOptions(): vcores = E5MessageBox.yesNo( self.parent(), self.tr("Import Project"), self.tr( """Would you like to edit the VCS command""" """ options?""")) else: vcores = False if vcores: from .CommandOptionsDialog import VcsCommandOptionsDialog codlg = VcsCommandOptionsDialog(self.project.vcs) if codlg.exec_() == QDialog.Accepted: self.project.vcs.vcsSetOptions(codlg.getOptions()) self.project.setDirty(True) self.project.vcs.vcsSetDataFromDict(vcsDataDict) self.project.saveProject() isVcsControlled = self.project.vcs.vcsImport( vcsDataDict, self.project.ppath)[0] if isVcsControlled: # reopen the project self.project.openProject(self.project.pfile) else: # revert the changes to the local project # because the project dir is not a VCS directory revertChanges() else: # revert the changes because user cancelled revertChanges() def _vcsUpdate(self): """ Protected slot used to update the local project from the repository. """ shouldReopen = self.vcs.vcsUpdate(self.project.ppath) if shouldReopen: res = E5MessageBox.yesNo( self.parent(), self.tr("Update"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def _vcsCommit(self): """ Protected slot used to commit changes to the local project to the repository. """ if Preferences.getVCS("AutoSaveProject"): self.project.saveProject() if Preferences.getVCS("AutoSaveFiles"): self.project.saveAllScripts() self.vcs.vcsCommit(self.project.ppath, '') def _vcsRemove(self): """ Protected slot used to remove the local project from the repository. Depending on the parameters set in the vcs object the project may be removed from the local disk as well. """ res = E5MessageBox.yesNo( self.parent(), self.tr("Remove project from repository"), self.tr( "Dou you really want to remove this project from" " the repository (and disk)?")) if res: self.vcs.vcsRemove(self.project.ppath, True) self._vcsCommit() if not os.path.exists(self.project.pfile): ppath = self.project.ppath self.setDirty(False) self.project.closeProject() shutil.rmtree(ppath, True) def _vcsCommandOptions(self): """ Protected slot to edit the VCS command options. """ if self.vcs.vcsSupportCommandOptions(): from .CommandOptionsDialog import VcsCommandOptionsDialog codlg = VcsCommandOptionsDialog(self.vcs) if codlg.exec_() == QDialog.Accepted: self.vcs.vcsSetOptions(codlg.getOptions()) self.project.setDirty(True) def _vcsLog(self): """ Protected slot used to show the log of the local project. """ self.vcs.vcsLog(self.project.ppath) def _vcsLogBrowser(self): """ Protected slot used to show the log of the local project with a log browser dialog. """ self.vcs.vcsLogBrowser(self.project.ppath) def _vcsDiff(self): """ Protected slot used to show the difference of the local project to the repository. """ self.vcs.vcsDiff(self.project.ppath) def _vcsStatus(self): """ Protected slot used to show the status of the local project. """ self.vcs.vcsStatus(self.project.ppath) def _vcsTag(self): """ Protected slot used to tag the local project in the repository. """ self.vcs.vcsTag(self.project.ppath) def _vcsRevert(self): """ Protected slot used to revert changes made to the local project. """ self.vcs.vcsRevert(self.project.ppath) def _vcsSwitch(self): """ Protected slot used to switch the local project to another tag/branch. """ shouldReopen = self.vcs.vcsSwitch(self.project.ppath) if shouldReopen: res = E5MessageBox.yesNo( self.parent(), self.tr("Switch"), self.tr("""The project should be reread. Do this now?"""), yesDefault=True) if res: self.project.reopenProject() def _vcsMerge(self): """ Protected slot used to merge changes of a tag/revision into the local project. """ self.vcs.vcsMerge(self.project.ppath) def _vcsCleanup(self): """ Protected slot used to cleanup the local project. """ self.vcs.vcsCleanup(self.project.ppath) def _vcsCommand(self): """ Protected slot used to execute an arbitrary vcs command. """ self.vcs.vcsCommandLine(self.project.ppath) def _vcsInfoDisplay(self): """ Protected slot called to show some vcs information. """ from .RepositoryInfoDialog import VcsRepositoryInfoDialog info = self.vcs.vcsRepositoryInfos(self.project.ppath) dlg = VcsRepositoryInfoDialog(None, info) dlg.exec_() eric-6.0.8/eric/VCS/__init__.py0000644000175000017500000000411512451233374015216 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the general part of the interface to version control systems. The general part of the VCS interface defines classes to implement common dialogs. These are a dialog to enter command options, a dialog to display some repository information and an abstract base class. The individual interfaces (i.e. CVS) have to be subclasses of this base class. """ from __future__ import unicode_literals from E5Gui.E5Application import e5App ###################################################################### ## Below is the factory function to instantiate the appropriate ## vcs object depending on the project settings. ###################################################################### def factory(vcs): """ Modul factory function to generate the right vcs object. @param vcs name of the VCS system to be used (string) @return the instantiated VCS object """ pluginManager = e5App().getObject("PluginManager") if pluginManager is None: # that should not happen vc = None vc = pluginManager.getPluginObject("version_control", vcs, maybeActive=True) if vc is None: # try alternative vcs interfaces assuming, that there is a common # indicator for the alternatives found = False for indicator, vcsData in \ pluginManager.getVcsSystemIndicators().items(): for vcsSystem, vcsSystemDisplay in vcsData: if vcsSystem == vcs: found = True break if found: if len(vcsData) > 1: for vcsSystem, vcsSystemDisplay in vcsData: if vcsSystem != vcs: vc = pluginManager.getPluginObject( "version_control", vcsSystem, maybeActive=True) if vc is not None: break break return vc eric-6.0.8/eric/VCS/VersionControl.py0000644000175000017500000007230012451233374016446 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing an abstract base class to be subclassed by all specific VCS interfaces. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QObject, QThread, QMutex, QProcess, \ Qt, pyqtSignal from PyQt5.QtWidgets import QApplication from E5Gui import E5MessageBox import Preferences class VersionControl(QObject): """ Class implementing an abstract base class to be subclassed by all specific VCS interfaces. It defines the vcs interface to be implemented by subclasses and the common methods. @signal vcsStatusMonitorData(list of str) emitted to update the VCS status @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of the monitoring thread (ok, nok, op, off) and a status message @signal vcsStatusChanged() emitted to indicate a change of the overall VCS status """ vcsStatusMonitorData = pyqtSignal(list) vcsStatusMonitorStatus = pyqtSignal(str, str) vcsStatusChanged = pyqtSignal() canBeCommitted = 1 # Indicates that a file/directory is in the vcs. canBeAdded = 2 # Indicates that a file/directory is not in vcs. def __init__(self, parent=None, name=None): """ Constructor @param parent parent widget (QWidget) @param name name of this object (string) """ super(VersionControl, self).__init__(parent) if name: self.setObjectName(name) self.defaultOptions = { 'global': [''], 'commit': [''], 'checkout': [''], 'update': [''], 'add': [''], 'remove': [''], 'diff': [''], 'log': [''], 'history': [''], 'status': [''], 'tag': [''], 'export': [''] } self.interestingDataKeys = [] self.options = {} self.otherData = {} self.canDetectBinaries = True self.autoCommit = False self.statusMonitorThread = None self.vcsExecutionMutex = QMutex() def vcsShutdown(self): """ Public method used to shutdown the vcs interface. @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsExists(self): """ Public method used to test for the presence of the vcs. @ireturn tuple of flag indicating the existence and a string giving an error message in case of failure @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsInit(self, vcsDir, noDialog=False): """ Public method used to initialize the vcs. @param vcsDir name of the VCS directory (string) @param noDialog flag indicating quiet operations (boolean) @ireturn flag indicating success (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsConvertProject(self, vcsDataDict, project): """ Public method to convert an uncontrolled project to a version controlled project. @param vcsDataDict dictionary of data required for the conversion @param project reference to the project object @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsImport(self, vcsDataDict, projectDir, noDialog=False): """ Public method used to import the project into the vcs. @param vcsDataDict dictionary of data required for the import @param projectDir project directory (string) @param noDialog flag indicating quiet operations @ireturn flag indicating an execution without errors (boolean) and a flag indicating the version controll status (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsCheckout(self, vcsDataDict, projectDir, noDialog=False): """ Public method used to check the project out of the vcs. @param vcsDataDict dictionary of data required for the checkout @param projectDir project directory to create (string) @param noDialog flag indicating quiet operations @ireturn flag indicating an execution without errors (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsExport(self, vcsDataDict, projectDir): """ Public method used to export a directory from the vcs. @param vcsDataDict dictionary of data required for the export @param projectDir project directory to create (string) @ireturn flag indicating an execution without errors (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsCommit(self, name, message, noDialog=False): """ Public method used to make the change of a file/directory permanent in the vcs. @param name file/directory name to be committed (string) @param message message for this operation (string) @param noDialog flag indicating quiet operations (boolean) @ireturn flag indicating success (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsUpdate(self, name, noDialog=False): """ Public method used to update a file/directory in the vcs. @param name file/directory name to be updated (string) @param noDialog flag indicating quiet operations (boolean) @ireturn flag indicating, that the update contained an add or delete (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsAdd(self, name, isDir=False, noDialog=False): """ Public method used to add a file/directory in the vcs. @param name file/directory name to be added (string) @param isDir flag indicating name is a directory (boolean) @param noDialog flag indicating quiet operations (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsAddBinary(self, name, isDir=False): """ Public method used to add a file/directory in binary mode in the vcs. @param name file/directory name to be added (string) @param isDir flag indicating name is a directory (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsAddTree(self, path): """ Public method to add a directory tree rooted at path in the vcs. @param path root directory of the tree to be added (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsRemove(self, name, project=False, noDialog=False): """ Public method used to add a file/directory in the vcs. @param name file/directory name to be removed (string) @param project flag indicating deletion of a project tree (boolean) @param noDialog flag indicating quiet operations @ireturn flag indicating success (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsMove(self, name, project, target=None, noDialog=False): """ Public method used to move a file/directory. @param name file/directory name to be moved (string) @param project reference to the project object @param target new name of the file/directory (string) @param noDialog flag indicating quiet operations @ireturn flag indicating successfull operation (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsLog(self, name): """ Public method used to view the log of a file/directory in the vcs. @param name file/directory name to show the log for (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsLogBrowser(self, name, isFile=False): """ Public method used to view the log of a file/directory in the vcs with a log browser dialog. @param name file/directory name to show the log for (string) @keyparam isFile flag indicating log for a file is to be shown (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsDiff(self, name): """ Public method used to view the diff of a file/directory in the vcs. @param name file/directory name to be diffed (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsHistory(self, name): """ Public method used to view the history of a file/directory in the vcs. @param name file/directory name to show the history for (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsStatus(self, name): """ Public method used to view the status of a file/directory in the vcs. @param name file/directory name to show the status for (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsTag(self, name): """ Public method used to set the tag of a file/directory in the vcs. @param name file/directory name to be tagged (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsRevert(self, name): """ Public method used to revert changes made to a file/directory. @param name file/directory name to be reverted (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsSwitch(self, name): """ Public method used to switch a directory to a different tag/branch. @param name directory name to be switched (string) @ireturn flag indicating, that the switch contained an add or delete (boolean) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsMerge(self, name): """ Public method used to merge a tag/branch into the local project. @param name file/directory name to be merged (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsRegisteredState(self, name): """ Public method used to get the registered state of a file in the vcs. @param name filename to check (string) @ireturn a combination of canBeCommited and canBeAdded or 0 in order to signal an error @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsAllRegisteredStates(self, names, dname): """ Public method used to get the registered states of a number of files in the vcs. @param names dictionary with all filenames to be checked as keys @param dname directory to check in (string) @ireturn the received dictionary completed with a combination of canBeCommited and canBeAdded or None in order to signal an error @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsName(self): """ Public method returning the name of the vcs. @ireturn name of the vcs (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsCleanup(self, name): """ Public method used to cleanup the local copy. @param name directory name to be cleaned up (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsCommandLine(self, name): """ Public method used to execute arbitrary vcs commands. @param name directory name of the working directory (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsOptionsDialog(self, project, archive, editable=False, parent=None): """ Public method to get a dialog to enter repository info. @param project reference to the project object @param archive name of the project in the repository (string) @param editable flag indicating that the project name is editable (boolean) @param parent parent widget (QWidget) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsNewProjectOptionsDialog(self, parent=None): """ Public method to get a dialog to enter repository info for getting a new project. @param parent parent widget (QWidget) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsRepositoryInfos(self, ppath): """ Public method to retrieve information about the repository. @param ppath local path to get the repository infos (string) @ireturn string with ready formated info for display (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsGetProjectBrowserHelper(self, browser, project, isTranslationsBrowser=False): """ Public method to instanciate a helper object for the different project browsers. @param browser reference to the project browser object @param project reference to the project object @param isTranslationsBrowser flag indicating, the helper is requested for the translations browser (this needs some special treatment) @ireturn the project browser helper object @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def vcsGetProjectHelper(self, project): """ Public method to instanciate a helper object for the project. @param project reference to the project object @ireturn the project helper object @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') ##################################################################### ## methods above need to be implemented by a subclass ##################################################################### def clearStatusCache(self): """ Public method to clear the status cache. """ pass def vcsInitConfig(self, project): """ Public method to initialize the VCS configuration. This method could ensure, that certain files or directories are exclude from being version controlled. @param project reference to the project (Project) """ pass def vcsSupportCommandOptions(self): """ Public method to signal the support of user settable command options. @return flag indicating the support of user settable command options (boolean) """ return True def vcsDefaultOptions(self): """ Public method used to retrieve the default options for the vcs. @return a dictionary with the vcs operations as key and the respective options as values. The key 'global' must contain the global options. The other keys must be 'commit', 'update', 'add', 'remove', 'diff', 'log', 'history', 'tag', 'status' and 'export'. """ return self.defaultOptions def vcsSetOptions(self, options): """ Public method used to set the options for the vcs. @param options a dictionary of option strings with keys as defined by the default options """ if self.vcsSupportCommandOptions(): for key in options: try: self.options[key] = options[key] except KeyError: pass def vcsGetOptions(self): """ Public method used to retrieve the options of the vcs. @return a dictionary of option strings that can be passed to vcsSetOptions. """ if self.vcsSupportCommandOptions(): return self.options else: return self.defaultOptions def vcsSetOtherData(self, data): """ Public method used to set vcs specific data. @param data a dictionary of vcs specific data """ for key in data: try: self.otherData[key] = data[key] except KeyError: pass def vcsGetOtherData(self): """ Public method used to retrieve vcs specific data. @return a dictionary of vcs specific data """ return self.otherData def vcsSetData(self, key, value): """ Public method used to set an entry in the otherData dictionary. @param key the key of the data (string) @param value the value of the data """ if key in self.interestingDataKeys: self.otherData[key] = value def vcsSetDataFromDict(self, dict): """ Public method used to set entries in the otherData dictionary. @param dict dictionary to pick entries from """ for key in self.interestingDataKeys: if key in dict: self.otherData[key] = dict[key] ##################################################################### ## below are some utility methods ##################################################################### def startSynchronizedProcess(self, proc, program, arguments, workingDir=None): """ Public method to start a synchroneous process. This method starts a process and waits for its end while still serving the Qt event loop. @param proc process to start (QProcess) @param program path of the executable to start (string) @param arguments list of arguments for the process (list of strings) @param workingDir working directory for the process (string) @return flag indicating normal exit (boolean) """ if proc is None: return if workingDir: proc.setWorkingDirectory(workingDir) proc.start(program, arguments) procStarted = proc.waitForStarted(5000) if not procStarted: E5MessageBox.critical( None, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format(program)) return False else: while proc.state() == QProcess.Running: QApplication.processEvents() QThread.msleep(300) QApplication.processEvents() return (proc.exitStatus() == QProcess.NormalExit) and \ (proc.exitCode() == 0) def splitPath(self, name): """ Public method splitting name into a directory part and a file part. @param name path name (string) @return a tuple of 2 strings (dirname, filename). """ if os.path.isdir(name): dn = os.path.abspath(name) fn = "." else: dn, fn = os.path.split(name) return (dn, fn) def splitPathList(self, names): """ Public method splitting the list of names into a common directory part and a file list. @param names list of paths (list of strings) @return a tuple of string and list of strings (dirname, filenamelist) """ dname = os.path.commonprefix(names) if dname: if not dname.endswith(os.sep): dname = os.path.dirname(dname) + os.sep fnames = [n.replace(dname, '') for n in names] dname = os.path.dirname(dname) return (dname, fnames) else: return ("/", names) def addArguments(self, args, argslist): """ Public method to add an argument list to the already present arguments. @param args current arguments list (list of strings) @param argslist list of arguments (list of strings) """ for arg in argslist: if arg != '': args.append(arg) ########################################################################### ## VCS status monitor thread related methods ########################################################################### def __statusMonitorStatus(self, status, statusMsg): """ Private method to receive the status monitor status. It simply reemits the received status. @param status status of the monitoring thread (string, ok, nok or off) @param statusMsg explanotory text for the signaled status (string) """ self.vcsStatusMonitorStatus.emit(status, statusMsg) QApplication.flush() def __statusMonitorData(self, statusList): """ Private method to receive the status monitor status. It simply reemits the received status list. @param statusList list of status records (list of strings) """ self.vcsStatusMonitorData.emit(statusList) QApplication.flush() def startStatusMonitor(self, project): """ Public method to start the VCS status monitor thread. @param project reference to the project object @return reference to the monitor thread (QThread) """ if project.pudata["VCSSTATUSMONITORINTERVAL"]: vcsStatusMonitorInterval = project.pudata[ "VCSSTATUSMONITORINTERVAL"][0] else: vcsStatusMonitorInterval = Preferences.getVCS( "StatusMonitorInterval") if vcsStatusMonitorInterval > 0: self.statusMonitorThread = self._createStatusMonitorThread( vcsStatusMonitorInterval, project) if self.statusMonitorThread is not None: self.statusMonitorThread.vcsStatusMonitorData.connect( self.__statusMonitorData, Qt.QueuedConnection) self.statusMonitorThread.vcsStatusMonitorStatus.connect( self.__statusMonitorStatus, Qt.QueuedConnection) self.statusMonitorThread.setAutoUpdate( Preferences.getVCS("AutoUpdate")) self.statusMonitorThread.start() else: self.statusMonitorThread = None return self.statusMonitorThread def stopStatusMonitor(self): """ Public method to stop the VCS status monitor thread. """ if self.statusMonitorThread is not None: self.__statusMonitorData(["--RESET--"]) self.statusMonitorThread.vcsStatusMonitorData.disconnect( self.__statusMonitorData) self.statusMonitorThread.vcsStatusMonitorStatus.disconnect( self.__statusMonitorStatus) self.statusMonitorThread.stop() self.statusMonitorThread.wait(10000) if not self.statusMonitorThread.isFinished(): self.statusMonitorThread.terminate() self.statusMonitorThread.wait(10000) self.statusMonitorThread = None self.__statusMonitorStatus( "off", self.tr("Repository status checking is switched off")) def setStatusMonitorInterval(self, interval, project): """ Public method to change the monitor interval. @param interval new interval in seconds (integer) @param project reference to the project object """ if self.statusMonitorThread is not None: if interval == 0: self.stopStatusMonitor() else: self.statusMonitorThread.setInterval(interval) else: self.startStatusMonitor(project) def getStatusMonitorInterval(self): """ Public method to get the monitor interval. @return interval in seconds (integer) """ if self.statusMonitorThread is not None: return self.statusMonitorThread.getInterval() else: return 0 def setStatusMonitorAutoUpdate(self, auto): """ Public method to enable the auto update function. @param auto status of the auto update function (boolean) """ if self.statusMonitorThread is not None: self.statusMonitorThread.setAutoUpdate(auto) def getStatusMonitorAutoUpdate(self): """ Public method to retrieve the status of the auto update function. @return status of the auto update function (boolean) """ if self.statusMonitorThread is not None: return self.statusMonitorThread.getAutoUpdate() else: return False def checkVCSStatus(self): """ Public method to wake up the VCS status monitor thread. """ self.vcsStatusChanged.emit() if self.statusMonitorThread is not None: self.statusMonitorThread.checkStatus() def clearStatusMonitorCachedState(self, name): """ Public method to clear the cached VCS state of a file/directory. @param name name of the entry to be cleared (string) """ if self.statusMonitorThread is not None: self.statusMonitorThread.clearCachedState(name) def _createStatusMonitorThread(self, interval, project): """ Protected method to create an instance of the VCS status monitor thread. Note: This method should be overwritten in subclasses in order to support VCS status monitoring. @param interval check interval for the monitor thread in seconds (integer) @param project reference to the project object @return reference to the monitor thread (QThread) """ return None eric-6.0.8/eric/VCS/CommandOptionsDialog.py0000644000175000017500000000643112451233374017534 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # """ Module implementing the VCS command options dialog. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_CommandOptionsDialog import Ui_VcsCommandOptionsDialog import Utilities class VcsCommandOptionsDialog(QDialog, Ui_VcsCommandOptionsDialog): """ Class implementing the VCS command options dialog. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(VcsCommandOptionsDialog, self).__init__(parent) self.setupUi(self) if Utilities.isWindowsPlatform(): self.optionChars = ['-', '/'] else: self.optionChars = ['-'] opt = vcs.vcsGetOptions() self.globalEdit.setText(" ".join(opt['global'])) self.commitEdit.setText(" ".join(opt['commit'])) self.checkoutEdit.setText(" ".join(opt['checkout'])) self.updateEdit.setText(" ".join(opt['update'])) self.addEdit.setText(" ".join(opt['add'])) self.removeEdit.setText(" ".join(opt['remove'])) self.diffEdit.setText(" ".join(opt['diff'])) self.logEdit.setText(" ".join(opt['log'])) self.historyEdit.setText(" ".join(opt['history'])) self.statusEdit.setText(" ".join(opt['status'])) self.tagEdit.setText(" ".join(opt['tag'])) self.exportEdit.setText(" ".join(opt['export'])) # modify the what's this help for widget in [self.globalEdit, self.commitEdit, self.checkoutEdit, self.updateEdit, self.addEdit, self.removeEdit, self.diffEdit, self.logEdit, self.historyEdit, self.statusEdit, self.tagEdit, self.exportEdit]: t = widget.whatsThis() if t: t += Utilities.getPercentReplacementHelp() widget.setWhatsThis(t) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def getOptions(self): """ Public method used to retrieve the entered options. @return dictionary of strings giving the options for each supported vcs command """ opt = {} opt['global'] = Utilities.parseOptionString(self.globalEdit.text()) opt['commit'] = Utilities.parseOptionString(self.commitEdit.text()) opt['checkout'] = Utilities.parseOptionString(self.checkoutEdit.text()) opt['update'] = Utilities.parseOptionString(self.updateEdit.text()) opt['add'] = Utilities.parseOptionString(self.addEdit.text()) opt['remove'] = Utilities.parseOptionString(self.removeEdit.text()) opt['diff'] = Utilities.parseOptionString(self.diffEdit.text()) opt['log'] = Utilities.parseOptionString(self.logEdit.text()) opt['history'] = Utilities.parseOptionString(self.historyEdit.text()) opt['status'] = Utilities.parseOptionString(self.statusEdit.text()) opt['tag'] = Utilities.parseOptionString(self.tagEdit.text()) opt['export'] = Utilities.parseOptionString(self.exportEdit.text()) return opt eric-6.0.8/eric/VCS/StatusMonitorThread.py0000644000175000017500000001504212451233374017443 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2006 - 2015 Detlev Offenbach # """ Module implementing the VCS status monitor thread base class. """ from __future__ import unicode_literals from PyQt5.QtCore import QThread, QMutex, QWaitCondition, pyqtSignal class VcsStatusMonitorThread(QThread): """ Class implementing the VCS status monitor thread base class. @signal vcsStatusMonitorData(list of str) emitted to update the VCS status @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of the monitoring thread (ok, nok, op) and a status message """ vcsStatusMonitorData = pyqtSignal(list) vcsStatusMonitorStatus = pyqtSignal(str, str) def __init__(self, interval, project, vcs, parent=None): """ Constructor @param interval new interval in seconds (integer) @param project reference to the project object (Project) @param vcs reference to the version control object @param parent reference to the parent object (QObject) """ super(VcsStatusMonitorThread, self).__init__(parent) self.setObjectName("VcsStatusMonitorThread") self.setTerminationEnabled(True) self.projectDir = project.getProjectPath() self.project = project self.vcs = vcs self.interval = interval self.autoUpdate = False self.statusList = [] self.reportedStates = {} self.shouldUpdate = False self.monitorMutex = QMutex() self.monitorCondition = QWaitCondition() self.__stopIt = False def run(self): """ Public method implementing the tasks action. """ while not self.__stopIt: # perform the checking task self.statusList = [] self.vcsStatusMonitorStatus.emit( "wait", self.tr("Waiting for lock")) try: locked = self.vcs.vcsExecutionMutex.tryLock(5000) except TypeError: locked = self.vcs.vcsExecutionMutex.tryLock() if locked: try: self.vcsStatusMonitorStatus.emit( "op", self.tr("Checking repository status")) res, statusMsg = self._performMonitor() finally: self.vcs.vcsExecutionMutex.unlock() if res: status = "ok" else: status = "nok" self.vcsStatusMonitorStatus.emit( "send", self.tr("Sending data")) self.vcsStatusMonitorData.emit(self.statusList) self.vcsStatusMonitorStatus.emit(status, statusMsg) else: self.vcsStatusMonitorStatus.emit( "timeout", self.tr("Timed out waiting for lock")) if self.autoUpdate and self.shouldUpdate: self.vcs.vcsUpdate(self.projectDir, True) continue # check again self.shouldUpdate = False # wait until interval has expired checking for a stop condition self.monitorMutex.lock() if not self.__stopIt: self.monitorCondition.wait( self.monitorMutex, self.interval * 1000) self.monitorMutex.unlock() self._shutdown() self.exit() def setInterval(self, interval): """ Public method to change the monitor interval. @param interval new interval in seconds (integer) """ locked = self.monitorMutex.tryLock() self.interval = interval self.monitorCondition.wakeAll() if locked: self.monitorMutex.unlock() def getInterval(self): """ Public method to get the monitor interval. @return interval in seconds (integer) """ return self.interval def setAutoUpdate(self, auto): """ Public method to enable the auto update function. @param auto status of the auto update function (boolean) """ self.autoUpdate = auto def getAutoUpdate(self): """ Public method to retrieve the status of the auto update function. @return status of the auto update function (boolean) """ return self.autoUpdate def checkStatus(self): """ Public method to wake up the status monitor thread. """ locked = self.monitorMutex.tryLock() self.monitorCondition.wakeAll() if locked: self.monitorMutex.unlock() def stop(self): """ Public method to stop the monitor thread. """ locked = self.monitorMutex.tryLock() self.__stopIt = True self.monitorCondition.wakeAll() if locked: self.monitorMutex.unlock() def clearCachedState(self, name): """ Public method to clear the cached VCS state of a file/directory. @param name name of the entry to be cleared (string) """ key = self.project.getRelativePath(name) try: del self.reportedStates[key] except KeyError: pass def _performMonitor(self): """ Protected method implementing the real monitoring action. This method must be overridden and populate the statusList member variable with a list of strings giving the status in the first column and the path relative to the project directory starting with the third column. The allowed status flags are:
  • "A" path was added but not yet comitted
  • "M" path has local changes
  • "O" path was removed
  • "R" path was deleted and then re-added
  • "U" path needs an update
  • "Z" path contains a conflict
  • " " path is back at normal
@ireturn tuple of flag indicating successful operation (boolean) and a status message in case of non successful operation (string) @exception RuntimeError to indicate that this method must be implemented by a subclass """ raise RuntimeError('Not implemented') def _shutdown(self): """ Protected method performing shutdown actions. The default implementation does nothing. """ pass eric-6.0.8/eric/E5Network/0000755000175000017500000000000012557365404014303 5ustar piotrpiotreric-6.0.8/eric/E5Network/E5NetworkHeaderDetailsDialog.ui0000644000175000017500000000430612060166052022212 0ustar piotrpiotr E5NetworkHeaderDetailsDialog 0 0 500 350 Header Details true Name: true Value: true true Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() E5NetworkHeaderDetailsDialog accept() 248 254 157 274 buttonBox rejected() E5NetworkHeaderDetailsDialog reject() 316 260 286 274 eric-6.0.8/eric/E5Network/E5SslCertificatesInfoWidget.ui0000644000175000017500000002475412474634043022113 0ustar piotrpiotr E5SslCertificatesInfoWidget 0 0 500 455 0 0 <h2>Certificate Information</h2> Certificate Chain: 0 0 This certificated has been blacklisted. <b>Issued for:</b> Common Name (CN): 0 0 Organization (O): 0 0 Organizational Unit (OU): 0 0 Serialnumber: 0 0 Qt::Vertical 20 10 <b>Issued by:</b> Common Name (CN): 0 0 Organization (O): 0 0 Organizational Unit (OU): 0 0 Qt::Vertical 20 9 <b>Validity:</b> Issued on: 0 0 Expires on: 0 0 This certificate is not valid yet or has expired. Qt::Vertical 20 10 <b>Fingerprints:</b> SHA1-Fingerprint: 0 0 MD5-Fingerprint: 0 0 eric-6.0.8/eric/E5Network/E5SslCertificatesInfoWidget.py0000644000175000017500000002041112451233374022105 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a widget to show SSL certificate infos. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import pyqtSlot, QCryptographicHash, QDateTime, qVersion from PyQt5.QtWidgets import QWidget from PyQt5.QtNetwork import QSslCertificate from .Ui_E5SslCertificatesInfoWidget import Ui_E5SslCertificatesInfoWidget import Utilities class E5SslCertificatesInfoWidget(QWidget, Ui_E5SslCertificatesInfoWidget): """ Class implementing a widget to show SSL certificate infos. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5SslCertificatesInfoWidget, self).__init__(parent) self.setupUi(self) self.__chain = [] def showCertificateChain(self, certificateChain): """ Public method to show the SSL certificates of a certificate chain. @param certificateChain list od SSL certificates (list of QSslCertificate) """ self.chainLabel.show() self.chainComboBox.show() self.chainComboBox.clear() self.__chain = certificateChain[:] for cert in self.__chain: if qVersion() >= "5.0.0": name = ", ".join(cert.subjectInfo(QSslCertificate.CommonName)) else: name = cert.subjectInfo(QSslCertificate.CommonName) if not name: if qVersion() >= "5.0.0": name = ", ".join( cert.subjectInfo(QSslCertificate.Organization)) else: name = cert.subjectInfo(QSslCertificate.Organization) if not name: name = cert.serialNumber() self.chainComboBox.addItem(name) self.on_chainComboBox_activated(0) def showCertificate(self, certificate): """ Public method to show the SSL certificate information. @param certificate reference to the SSL certificate (QSslCertificate) """ self.chainLabel.hide() self.chainComboBox.hide() self.chainComboBox.clear() self.__chain = [] self.__showCertificate(certificate) def __showCertificate(self, certificate): """ Private method to show the SSL certificate information. @param certificate reference to the SSL certificate (QSslCertificate) """ self.blacklistedLabel.setVisible(False) self.blacklistedLabel.setStyleSheet( "QLabel { color : white; background-color : red; }") self.expiredLabel.setVisible(False) self.expiredLabel.setStyleSheet( "QLabel { color : white; background-color : red; }") if qVersion() >= "5.0.0": self.subjectCommonNameLabel.setText(self.__certificateString( ", ".join(certificate.subjectInfo( QSslCertificate.CommonName)))) self.subjectOrganizationLabel.setText(self.__certificateString( ", ".join(certificate.subjectInfo( QSslCertificate.Organization)))) self.subjectOrganizationalUnitLabel.setText( self.__certificateString(", ".join( certificate.subjectInfo( QSslCertificate.OrganizationalUnitName)))) self.issuerCommonNameLabel.setText(self.__certificateString( ", ".join(certificate.issuerInfo(QSslCertificate.CommonName)))) self.issuerOrganizationLabel.setText(self.__certificateString( ", ".join(certificate.issuerInfo( QSslCertificate.Organization)))) self.issuerOrganizationalUnitLabel.setText( self.__certificateString(", ".join( certificate.issuerInfo( QSslCertificate.OrganizationalUnitName)))) else: self.subjectCommonNameLabel.setText(self.__certificateString( certificate.subjectInfo(QSslCertificate.CommonName))) self.subjectOrganizationLabel.setText(self.__certificateString( certificate.subjectInfo(QSslCertificate.Organization))) self.subjectOrganizationalUnitLabel.setText( self.__certificateString(certificate.subjectInfo( QSslCertificate.OrganizationalUnitName))) self.issuerCommonNameLabel.setText(self.__certificateString( certificate.issuerInfo(QSslCertificate.CommonName))) self.issuerOrganizationLabel.setText(self.__certificateString( certificate.issuerInfo(QSslCertificate.Organization))) self.issuerOrganizationalUnitLabel.setText( self.__certificateString(certificate.issuerInfo( QSslCertificate.OrganizationalUnitName))) self.serialNumberLabel.setText(self.__serialNumber(certificate)) self.effectiveLabel.setText( certificate.effectiveDate().toString("yyyy-MM-dd")) self.expiresLabel.setText( certificate.expiryDate().toString("yyyy-MM-dd")) self.sha1Label.setText(self.__formatHexString( str(certificate.digest(QCryptographicHash.Sha1).toHex(), encoding="ascii"))) self.md5Label.setText(self.__formatHexString( str(certificate.digest(QCryptographicHash.Md5).toHex(), encoding="ascii"))) if (qVersion() >= "5.0.0" and certificate.isBlacklisted()) or \ (qVersion() < "5.0.0" and not certificate.isValid()): # something is wrong; indicate it to the user if self.__hasExpired(certificate.effectiveDate(), certificate.expiryDate()): self.expiredLabel.setVisible(True) else: self.blacklistedLabel.setVisible(True) def __certificateString(self, txt): """ Private method to prepare some text for display. @param txt text to be displayed (string) @return prepared text (string) """ if txt is None or txt == "": return self.tr("") return Utilities.decodeString(txt) def __serialNumber(self, cert): """ Private slot to format the certificate serial number. @param cert reference to the SSL certificate (QSslCertificate) @return formated serial number (string) """ serial = cert.serialNumber() if serial == "": return self.tr("") if ':' in serial: return str(serial, encoding="ascii").upper() else: hexString = hex(int(serial))[2:] return self.__formatHexString(hexString) def __formatHexString(self, hexString): """ Private method to format a hex string for display. @param hexString hex string to be formatted (string) @return formatted string (string) """ hexString = hexString.upper() if len(hexString) % 2 == 1: hexString = '0' + hexString hexList = [] while hexString: hexList.append(hexString[:2]) hexString = hexString[2:] return ':'.join(hexList) def __hasExpired(self, effectiveDate, expiryDate): """ Private method to check for a certificate expiration. @param effectiveDate date the certificate becomes effective (QDateTime) @param expiryDate date the certificate expires (QDateTime) @return flag indicating the expiration status (boolean) """ now = QDateTime.currentDateTime() return now < effectiveDate or now >= expiryDate @pyqtSlot(int) def on_chainComboBox_activated(self, index): """ Private slot to show the certificate info for the selected entry. @param index number of the certificate in the certificate chain (integer) """ self.__showCertificate(self.__chain[index]) eric-6.0.8/eric/E5Network/E5NetworkHeaderDetailsDialog.py0000644000175000017500000000215412537064320022230 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a dialog to show the data of a response or reply header. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QDialog from .Ui_E5NetworkHeaderDetailsDialog import Ui_E5NetworkHeaderDetailsDialog class E5NetworkHeaderDetailsDialog(QDialog, Ui_E5NetworkHeaderDetailsDialog): """ Class implementing a dialog to show the data of a response or reply header. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QWidget) """ super(E5NetworkHeaderDetailsDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) def setData(self, name, value): """ Public method to set the data to display. @param name name of the header (string) @param value value of the header (string) """ self.nameEdit.setText(name) self.valueEdit.setPlainText(value) eric-6.0.8/eric/E5Network/E5UrlInfo.py0000644000175000017500000001463212451233374016424 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a class replacing QUrlInfo. """ from __future__ import unicode_literals from PyQt5.QtCore import QDateTime class E5UrlInfo(object): """ Class implementing a replacement for QUrlInfo. """ ReadOwner = 0o0400 WriteOwner = 0o0200 ExeOwner = 0o0100 ReadGroup = 0o0040 WriteGroup = 0o0020 ExeGroup = 0o0010 ReadOther = 0o0004 WriteOther = 0o0002 ExeOther = 0o0001 def __init__(self): """ Constructor """ self.__valid = False self.__permissions = 0 self.__size = 0 self.__isDir = False self.__isFile = True self.__isSymlink = False self.__isWritable = True self.__isReadable = True self.__isExecutable = False self.__name = "" self.__owner = "" self.__group = "" self.__lastModified = QDateTime() self.__lastRead = QDateTime() def isValid(self): """ Public method to check the validity of the object. @return flag indicating validity (boolean) """ return self.__valid def setName(self, name): """ Public method to set the name. @param name name to be set (string) """ self.__name = name self.__valid = True def setPermissions(self, permissions): """ Public method to set the permissions. @param permissions permissions to be set (integer) """ self.__permissions = permissions self.__valid = True def setDir(self, isDir): """ Public method to indicate a directory. @param isDir flag indicating a directory (boolean) """ self.__isDir = isDir self.__valid = True def setFile(self, isFile): """ Public method to indicate a file. @param isFile flag indicating a file (boolean) """ self.__isFile = isFile self.__valid = True def setSymLink(self, isSymLink): """ Public method to indicate a symbolic link. @param isSymLink flag indicating a symbolic link (boolean) """ self.__isSymLink = isSymLink self.__valid = True def setOwner(self, owner): """ Public method to set the owner. @param owner owner to be set (string) """ self.__owner = owner self.__valid = True def setGroup(self, group): """ Public method to set the group. @param group group to be set (string) """ self.__group = group self.__valid = True def setSize(self, size): """ Public method to set the size. @param size size to be set (integer) """ self.__size = size self.__valid = True def setWritable(self, isWritable): """ Public method to a writable entry. @param isWritable flag indicating a writable entry (boolean) """ self.__isWritable = isWritable self.__valid = True def setReadable(self, isReadable): """ Public method to a readable entry. @param isReadable flag indicating a readable entry (boolean) """ self.__isReadable = isReadable self.__valid = True def setLastModified(self, dt): """ Public method to set the last modified date and time. @param dt date and time to set (QDateTime) """ self.__lastModified = QDateTime(dt) self.__valid = True def setLastRead(self, dt): """ Public method to set the last read date and time. @param dt date and time to set (QDateTime) """ self.__lastRead = QDateTime(dt) self.__valid = True def name(self): """ Public method to get the name. @return name (string) """ return self.__name def permissions(self): """ Public method to get the permissions. @return permissions (integer) """ return self.__permissions def owner(self): """ Public method to get the owner. @return owner (string) """ return self.__owner def group(self): """ Public method to get the group. @return group (string) """ return self.__group def size(self): """ Public method to get the size. @return size (integer) """ return self.__size def lastModified(self): """ Public method to get the last modified date and time. @return last modified date and time (QDateTime) """ return QDateTime(self.__lastModified) def lastRead(self): """ Public method to get the last read date and time. @return last read date and time (QDateTime) """ return QDateTime(self.__lastRead) def isDir(self): """ Public method to test, if the entry is a directory. @return flag indicating a directory (boolean) """ return self.__isDir def isFile(self): """ Public method to test, if the entry is a file. @return flag indicating a file (boolean) """ return self.__isFile def isSymLink(self): """ Public method to test, if the entry is a symbolic link. @return flag indicating a symbolic link (boolean) """ return self.__isSymlink def isWritable(self): """ Public method to test, if the entry is writable. @return flag indicating writable (boolean) """ return self.__isWritable def isReadable(self): """ Public method to test, if the entry is readable. @return flag indicating readable (boolean) """ return self.__isReadable def isExecutable(self): """ Public method to test, if the entry is executable. @return flag indicating executable (boolean) """ return self.__isExecutable eric-6.0.8/eric/E5Network/E5SslInfoWidget.py0000644000175000017500000001737112451233374017572 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a widget to show SSL information. """ from __future__ import unicode_literals from PyQt5.QtCore import qVersion, Qt, QUrl, QPoint from PyQt5.QtWidgets import QMenu, QGridLayout, QLabel, QSizePolicy from PyQt5.QtNetwork import QSsl, QSslConfiguration, QSslCertificate import UI.PixmapCache import Utilities class E5SslInfoWidget(QMenu): """ Class implementing a widget to show SSL certificate infos. """ def __init__(self, url, configuration, parent=None): """ Constructor @param url URL to show SSL info for (QUrl) @param configuration SSL configuration (QSslConfiguration) @param parent reference to the parent widget (QWidget) """ super(E5SslInfoWidget, self).__init__(parent) self.__url = QUrl(url) self.__configuration = QSslConfiguration(configuration) self.setMinimumWidth(400) certList = self.__configuration.peerCertificateChain() if certList: cert = certList[0] else: cert = QSslCertificate() layout = QGridLayout(self) rows = 0 ########################################## ## Identity Information ########################################## imageLabel = QLabel(self) layout.addWidget(imageLabel, rows, 0, Qt.AlignCenter) label = QLabel(self) label.setWordWrap(True) label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) label.setText(self.tr("Identity")) font = label.font() font.setBold(True) label.setFont(font) layout.addWidget(label, rows, 1) rows += 1 label = QLabel(self) label.setWordWrap(True) if cert.isNull(): label.setText(self.tr( "Warning: this site is NOT carrying a certificate.")) imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32.png")) else: if qVersion() >= "5.0.0": valid = not cert.isBlacklisted() else: valid = cert.isValid() if valid: if qVersion() >= "5.0.0": txt = ", ".join( cert.issuerInfo(QSslCertificate.CommonName)) else: txt = cert.issuerInfo(QSslCertificate.CommonName) label.setText(self.tr( "The certificate for this site is valid" " and has been verified by:\n{0}").format( Utilities.decodeString(txt))) imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityHigh32.png")) else: label.setText(self.tr( "The certificate for this site is NOT valid.")) imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityLow32.png")) layout.addWidget(label, rows, 1) rows += 1 label = QLabel(self) label.setWordWrap(True) label.setText( '' + self.tr("Certificate Information") + "") label.linkActivated.connect(self.__showCertificateInfos) layout.addWidget(label, rows, 1) rows += 1 ########################################## ## Identity Information ########################################## imageLabel = QLabel(self) layout.addWidget(imageLabel, rows, 0, Qt.AlignCenter) label = QLabel(self) label.setWordWrap(True) label.setText(self.tr("Encryption")) font = label.font() font.setBold(True) label.setFont(font) layout.addWidget(label, rows, 1) rows += 1 cipher = self.__configuration.sessionCipher() if cipher.isNull(): label = QLabel(self) label.setWordWrap(True) label.setText(self.tr( 'Your connection to "{0}" is NOT encrypted.\n').format( self.__url.host())) layout.addWidget(label, rows, 1) imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32.png")) rows += 1 else: label = QLabel(self) label.setWordWrap(True) label.setText(self.tr( 'Your connection to "{0}" is encrypted.').format( self.__url.host())) layout.addWidget(label, rows, 1) proto = cipher.protocol() if proto == QSsl.SslV3: sslVersion = "SSL 3.0" imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityHigh32.png")) elif proto == QSsl.TlsV1SslV3: sslVersion = "TLS 1.0/SSL 3.0" imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityHigh32.png")) elif proto == QSsl.SslV2: sslVersion = "SSL 2.0" imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityLow32.png")) else: sslVersion = self.tr("unknown") imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityLow32.png")) if qVersion() >= "5.0.0": if proto == QSsl.TlsV1_0: sslVersion = "TLS 1.0" imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityHigh32.png")) elif proto == QSsl.TlsV1_1: sslVersion = "TLS 1.1" imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityHigh32.png")) elif proto == QSsl.TlsV1_2: sslVersion = "TLS 1.2" imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityHigh32.png")) else: if proto == QSsl.TlsV1: sslVersion = "TLS 1.0" imageLabel.setPixmap( UI.PixmapCache.getPixmap("securityHigh32.png")) rows += 1 label = QLabel(self) label.setWordWrap(True) label.setText(self.tr( "It uses protocol: {0}").format(sslVersion)) layout.addWidget(label, rows, 1) rows += 1 label = QLabel(self) label.setWordWrap(True) label.setText(self.tr( "It is encrypted using {0} at {1} bits, " "with {2} for message authentication and " "{3} as key exchange mechanism.\n\n").format( cipher.encryptionMethod(), cipher.usedBits(), cipher.authenticationMethod(), cipher.keyExchangeMethod())) layout.addWidget(label, rows, 1) rows += 1 def showAt(self, pos): """ Public method to show the widget. @param pos position to show at (QPoint) """ self.adjustSize() xpos = pos.x() - self.width() if xpos < 0: xpos = 10 p = QPoint(xpos, pos.y() + 10) self.move(p) self.show() def __showCertificateInfos(self): """ Private slot to show certificate information. """ from .E5SslCertificatesInfoDialog import E5SslCertificatesInfoDialog dlg = E5SslCertificatesInfoDialog( self.__configuration.peerCertificateChain()) dlg.exec_() def accept(self): """ Public method to accept the widget. """ self.close() eric-6.0.8/eric/E5Network/E5SslCertificatesInfoDialog.py0000644000175000017500000000157612451233374022074 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to show SSL certificate infos. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_E5SslCertificatesInfoDialog import Ui_E5SslCertificatesInfoDialog class E5SslCertificatesInfoDialog(QDialog, Ui_E5SslCertificatesInfoDialog): """ Class implementing a dialog to show SSL certificate infos. """ def __init__(self, certificateChain, parent=None): """ Constructor @param certificateChain SSL certificate chain (list of QSslCertificate) @param parent reference to the parent widget (QWidget) """ super(E5SslCertificatesInfoDialog, self).__init__(parent) self.setupUi(self) self.sslWidget.showCertificateChain(certificateChain) eric-6.0.8/eric/E5Network/__init__.py0000644000175000017500000000024712451233374016410 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Package implementing some special network related objects. """ eric-6.0.8/eric/E5Network/E5NetworkMonitor.py0000644000175000017500000003262512537064320020047 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a network monitor dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex, QUrl, \ QSortFilterProxyModel from PyQt5.QtGui import QStandardItemModel from PyQt5.QtWidgets import QDialog from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager from .Ui_E5NetworkMonitor import Ui_E5NetworkMonitor class E5NetworkRequest(object): """ Class for storing all data related to a specific request. """ def __init__(self): """ Constructor """ self.op = -1 self.request = None self.reply = None self.response = "" self.length = 0 self.contentType = "" self.info = "" self.replyHeaders = [] # list of tuple of two items class E5NetworkMonitor(QDialog, Ui_E5NetworkMonitor): """ Class implementing a network monitor dialog. """ _monitor = None @classmethod def instance(cls, networkAccessManager): """ Class method to get a reference to our singleton. @param networkAccessManager reference to the network access manager (QNetworkAccessManager) @return reference to the network monitor singleton (E5NetworkMonitor) """ if cls._monitor is None: cls._monitor = E5NetworkMonitor(networkAccessManager) return cls._monitor @classmethod def closeMonitor(cls): """ Class method to close the monitor dialog. """ if cls._monitor is not None: cls._monitor.close() def __init__(self, networkAccessManager, parent=None): """ Constructor @param networkAccessManager reference to the network access manager (QNetworkAccessManager) @param parent reference to the parent widget (QWidget) """ super(E5NetworkMonitor, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.__requestHeaders = QStandardItemModel(self) self.__requestHeaders.setHorizontalHeaderLabels( [self.tr("Name"), self.tr("Value")]) self.requestHeadersList.setModel(self.__requestHeaders) self.requestHeadersList.horizontalHeader().setStretchLastSection(True) self.requestHeadersList.doubleClicked.connect(self.__showHeaderDetails) self.__replyHeaders = QStandardItemModel(self) self.__replyHeaders.setHorizontalHeaderLabels( [self.tr("Name"), self.tr("Value")]) self.responseHeadersList.setModel(self.__replyHeaders) self.responseHeadersList.horizontalHeader().setStretchLastSection(True) self.responseHeadersList.doubleClicked.connect( self.__showHeaderDetails) self.requestsList.horizontalHeader().setStretchLastSection(True) self.requestsList.verticalHeader().setMinimumSectionSize(-1) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setFilterKeyColumn(-1) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.removeButton.clicked.connect(self.requestsList.removeSelected) self.removeAllButton.clicked.connect(self.requestsList.removeAll) self.__model = E5RequestModel(networkAccessManager, self) self.__proxyModel.setSourceModel(self.__model) self.requestsList.setModel(self.__proxyModel) self.__proxyModel.rowsInserted.connect( self.requestsList.scrollToBottom) self.requestsList.selectionModel()\ .currentChanged[QModelIndex, QModelIndex]\ .connect(self.__currentChanged) fm = self.fontMetrics() em = fm.width("m") self.requestsList.horizontalHeader().resizeSection(0, em * 5) self.requestsList.horizontalHeader().resizeSection(1, em * 20) self.requestsList.horizontalHeader().resizeSection(3, em * 5) self.requestsList.horizontalHeader().resizeSection(4, em * 15) self.__headersDlg = None def closeEvent(self, evt): """ Protected method called upon closing the dialog. @param evt reference to the close event object (QCloseEvent) """ self.__class__._monitor = None super(E5NetworkMonitor, self).closeEvent(evt) def reject(self): """ Public slot to close the dialog with a Reject status. """ self.__class__._monitor = None super(E5NetworkMonitor, self).reject() def __currentChanged(self, current, previous): """ Private slot to handle a change of the current index. @param current new current index (QModelIndex) @param previous old current index (QModelIndex) """ self.__requestHeaders.setRowCount(0) self.__replyHeaders.setRowCount(0) if not current.isValid(): return row = self.__proxyModel.mapToSource(current).row() req = self.__model.requests[row].request for header in req.rawHeaderList(): self.__requestHeaders.insertRows(0, 1, QModelIndex()) self.__requestHeaders.setData( self.__requestHeaders.index(0, 0), str(header, "utf-8")) self.__requestHeaders.setData( self.__requestHeaders.index(0, 1), str(req.rawHeader(header), "utf-8")) self.__requestHeaders.item(0, 0).setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.__requestHeaders.item(0, 1).setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled) for header in self.__model.requests[row].replyHeaders: self.__replyHeaders.insertRows(0, 1, QModelIndex()) self.__replyHeaders.setData( self.__replyHeaders.index(0, 0), header[0]) self.__replyHeaders.setData( self.__replyHeaders.index(0, 1), header[1]) self.__replyHeaders.item(0, 0).setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.__replyHeaders.item(0, 1).setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled) def __showHeaderDetails(self, index): """ Private slot to show a dialog with the header details. @param index index of the entry to show (QModelIndex) """ if not index.isValid(): return headerList = self.sender() if headerList is None: return row = index.row() name = headerList.model().data(headerList.model().index(row, 0)) value = headerList.model().data(headerList.model().index(row, 1)) if self.__headersDlg is None: from .E5NetworkHeaderDetailsDialog import \ E5NetworkHeaderDetailsDialog self.__headersDlg = E5NetworkHeaderDetailsDialog(self) self.__headersDlg.setData(name, value) self.__headersDlg.show() class E5RequestModel(QAbstractTableModel): """ Class implementing a model storing request objects. """ def __init__(self, networkAccessManager, parent=None): """ Constructor @param networkAccessManager reference to the network access manager (QNetworkAccessManager) @param parent reference to the parent object (QObject) """ super(E5RequestModel, self).__init__(parent) self.__headerData = [ self.tr("Method"), self.tr("Address"), self.tr("Response"), self.tr("Length"), self.tr("Content Type"), self.tr("Info"), ] self.__operations = { QNetworkAccessManager.HeadOperation: "HEAD", QNetworkAccessManager.GetOperation: "GET", QNetworkAccessManager.PutOperation: "PUT", QNetworkAccessManager.PostOperation: "POST", } self.requests = [] networkAccessManager.requestCreated.connect(self.__requestCreated) def __requestCreated(self, operation, request, reply): """ Private slot handling the creation of a network request. @param operation network operation (QNetworkAccessManager.Operation) @param request reference to the request object (QNetworkRequest) @param reply reference to the reply object(QNetworkReply) """ req = E5NetworkRequest() req.op = operation req.request = QNetworkRequest(request) req.reply = reply self.__addRequest(req) def __addRequest(self, req): """ Private method to add a request object to the model. @param req reference to the request object (E5NetworkRequest) """ self.beginInsertRows( QModelIndex(), len(self.requests), len(self.requests)) self.requests.append(req) req.reply.finished.connect(self.__addReply) self.endInsertRows() def __addReply(self): """ Private slot to add the reply data to the model. """ reply = self.sender() if reply is None: return offset = len(self.requests) - 1 while offset >= 0: if self.requests[offset].reply is reply: break offset -= 1 if offset < 0: return # save the reply header data for header in reply.rawHeaderList(): self.requests[offset].replyHeaders.append(( str(header, "utf-8"), str(reply.rawHeader(header), "utf-8"))) # save reply info to be displayed status = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) or 0 reason = \ reply.attribute(QNetworkRequest.HttpReasonPhraseAttribute) or "" self.requests[offset].response = "{0:d} {1}".format(status, reason) self.requests[offset].length = \ reply.header(QNetworkRequest.ContentLengthHeader) self.requests[offset].contentType = \ reply.header(QNetworkRequest.ContentTypeHeader) if status == 302: target = reply.attribute( QNetworkRequest.RedirectionTargetAttribute) or QUrl() self.requests[offset].info = \ self.tr("Redirect: {0}").format(target.toString()) def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get header data from the model. @param section section number (integer) @param orientation orientation (Qt.Orientation) @param role role of the data to retrieve (integer) @return requested data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.__headerData[section] return QAbstractTableModel.headerData(self, section, orientation, role) def data(self, index, role=Qt.DisplayRole): """ Public method to get data from the model. @param index index to get data for (QModelIndex) @param role role of the data to retrieve (integer) @return requested data """ if index.row() < 0 or index.row() >= len(self.requests): return None if role == Qt.DisplayRole or role == Qt.EditRole: col = index.column() if col == 0: try: return self.__operations[self.requests[index.row()].op] except KeyError: return self.tr("Unknown") elif col == 1: return self.requests[index.row()].request.url().toEncoded() elif col == 2: return self.requests[index.row()].response elif col == 3: return self.requests[index.row()].length elif col == 4: return self.requests[index.row()].contentType elif col == 5: return self.requests[index.row()].info return None def columnCount(self, parent): """ Public method to get the number of columns of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.column() > 0: return 0 else: return len(self.__headerData) def rowCount(self, parent): """ Public method to get the number of rows of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.isValid(): return 0 else: return len(self.requests) def removeRows(self, row, count, parent): """ Public method to remove entries from the model. @param row start row (integer) @param count number of rows to remove (integer) @param parent parent index (QModelIndex) @return flag indicating success (boolean) """ if parent.isValid(): return False lastRow = row + count - 1 self.beginRemoveRows(parent, row, lastRow) del self.requests[row:lastRow + 1] self.endRemoveRows() return True eric-6.0.8/eric/E5Network/E5NetworkProxyFactory.py0000644000175000017500000001546712451233374021100 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a network proxy factory. """ from __future__ import unicode_literals import os from PyQt5.QtCore import QUrl, QCoreApplication from PyQt5.QtWidgets import QDialog from PyQt5.QtNetwork import QNetworkProxyFactory, QNetworkProxy, \ QNetworkProxyQuery from E5Gui import E5MessageBox import Preferences import Globals import Utilities def schemeFromProxyType(proxyType): """ Module function to determine the scheme name from the proxy type. @param proxyType type of the proxy (QNetworkProxy.ProxyType) @return scheme (string, one of Http, Https, Ftp) """ scheme = "" if proxyType == QNetworkProxy.HttpProxy: scheme = "Http" elif proxyType == QNetworkProxy.HttpCachingProxy: scheme = "Https" elif proxyType == QNetworkProxy.FtpCachingProxy: scheme = "Ftp" elif proxyType == QNetworkProxy.NoProxy: scheme = "NoProxy" return scheme def proxyAuthenticationRequired(proxy, auth): """ Module slot to handle a proxy authentication request. @param proxy reference to the proxy object (QNetworkProxy) @param auth reference to the authenticator object (QAuthenticator) """ info = QCoreApplication.translate( "E5NetworkProxyFactory", "Connect to proxy '{0}' using:")\ .format(Utilities.html_encode(proxy.hostName())) from UI.AuthenticationDialog import AuthenticationDialog dlg = AuthenticationDialog(info, proxy.user(), True) dlg.setData(proxy.user(), proxy.password()) if dlg.exec_() == QDialog.Accepted: username, password = dlg.getData() auth.setUser(username) auth.setPassword(password) if dlg.shallSave(): scheme = schemeFromProxyType(proxy.type()) if scheme and scheme != "NoProxy": Preferences.setUI("ProxyUser/{0}".format(scheme), username) Preferences.setUI("ProxyPassword/{0}".format(scheme), password) proxy.setUser(username) proxy.setPassword(password) class E5NetworkProxyFactory(QNetworkProxyFactory): """ Class implementing a network proxy factory. """ def __init__(self): """ Constructor """ super(E5NetworkProxyFactory, self).__init__() def queryProxy(self, query): """ Public method to determine a proxy for a given query. @param query reference to the query object (QNetworkProxyQuery) @return list of proxies in order of preference (list of QNetworkProxy) """ if query.queryType() == QNetworkProxyQuery.UrlRequest and \ query.protocolTag() in ["http", "https", "ftp"] and \ Preferences.getUI("UseProxy"): if Preferences.getUI("UseSystemProxy"): proxyList = QNetworkProxyFactory.systemProxyForQuery(query) if not Globals.isWindowsPlatform() and \ len(proxyList) == 1 and \ proxyList[0].type() == QNetworkProxy.NoProxy: # try it the Python way # scan the environment for variables named _proxy # scan over whole environment to make this case insensitive for name, value in os.environ.items(): name = name.lower() if value and name[-6:] == '_proxy' and \ name[:-6] == query.protocolTag().lower(): url = QUrl(value) if url.scheme() == "http": proxyType = QNetworkProxy.HttpProxy elif url.scheme() == "https": proxyType = QNetworkProxy.HttpCachingProxy elif url.scheme() == "ftp": proxyType = QNetworkProxy.FtpCachingProxy else: proxyType = QNetworkProxy.HttpProxy proxy = QNetworkProxy( proxyType, url.host(), url.port(), url.userName(), url.password()) proxyList = [proxy] break if proxyList: scheme = schemeFromProxyType(proxyList[0].type()) if scheme == "": scheme = "Http" if scheme != "NoProxy": proxyList[0].setUser( Preferences.getUI("ProxyUser/{0}".format(scheme))) proxyList[0].setPassword( Preferences.getUI( "ProxyPassword/{0}".format(scheme))) return proxyList else: return [QNetworkProxy(QNetworkProxy.NoProxy)] else: if Preferences.getUI("UseHttpProxyForAll"): protocolKey = "Http" else: protocolKey = query.protocolTag().capitalize() host = Preferences.getUI("ProxyHost/{0}".format(protocolKey)) if not host: E5MessageBox.critical( None, QCoreApplication.translate( "E5NetworkProxyFactory", "Proxy Configuration Error"), QCoreApplication.translate( "E5NetworkProxyFactory", """Proxy usage was activated""" """ but no proxy host for protocol""" """ '{0}' configured.""").format(protocolKey)) return [QNetworkProxy(QNetworkProxy.DefaultProxy)] else: if protocolKey in ["Http", "Https", "Ftp"]: if query.protocolTag() == "ftp": proxyType = QNetworkProxy.FtpCachingProxy elif query.protocolTag() == "https": proxyType = QNetworkProxy.HttpCachingProxy else: proxyType = QNetworkProxy.HttpProxy proxy = QNetworkProxy( proxyType, host, Preferences.getUI("ProxyPort/" + protocolKey), Preferences.getUI("ProxyUser/" + protocolKey), Preferences.getUI("ProxyPassword/" + protocolKey)) else: proxy = QNetworkProxy(QNetworkProxy.DefaultProxy) return [proxy, QNetworkProxy(QNetworkProxy.DefaultProxy)] else: return [QNetworkProxy(QNetworkProxy.NoProxy)] eric-6.0.8/eric/E5Network/E5NetworkMonitor.ui0000644000175000017500000001446212060166052020027 0ustar piotrpiotr E5NetworkMonitor 0 0 800 600 Network Monitor true Network Requests Qt::Horizontal 40 20 0 350 0 Enter search term for requests true QAbstractItemView::SelectRows false false Press to remove the selected requests &Remove false Press to remove all requests Remove &All false Qt::Horizontal 40 20 Qt::Horizontal Request Headers true false false Response Headers true false false Qt::Horizontal QDialogButtonBox::Close E5ClearableLineEdit QLineEdit
E5Gui/E5LineEdit.h
E5TableView QTableView
E5Gui/E5TableView.h
searchEdit requestsList removeButton removeAllButton requestHeadersList responseHeadersList buttonBox buttonBox accepted() E5NetworkMonitor accept() 252 595 157 274 buttonBox rejected() E5NetworkMonitor reject() 320 595 286 274
eric-6.0.8/eric/E5Network/E5SslErrorHandler.py0000644000175000017500000002216712555122461020120 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2013 - 2015 Detlev Offenbach # """ Module implementing a SSL error handler. """ from __future__ import unicode_literals from PyQt5.QtCore import qVersion, QObject, QByteArray from PyQt5.QtNetwork import QSslCertificate, QSslConfiguration, QSslSocket, \ QSslError, QSsl from E5Gui import E5MessageBox import Preferences import Utilities import Globals class E5SslErrorHandler(QObject): """ Class implementing a handler for SSL errors. It also initializes the default SSL configuration with certificates permanently accepted by the user already. """ NotIgnored = 0 SystemIgnored = 1 UserIgnored = 2 def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(E5SslErrorHandler, self).__init__(parent) caList = self.__getSystemCaCertificates() if Preferences.Prefs.settings.contains("Help/CaCertificatesDict"): # port old entries stored under 'Help' certificateDict = Globals.toDict( Preferences.Prefs.settings.value("Help/CaCertificatesDict")) Preferences.Prefs.settings.setValue( "Ssl/CaCertificatesDict", certificateDict) Preferences.Prefs.settings.remove("Help/CaCertificatesDict") else: certificateDict = Globals.toDict( Preferences.Prefs.settings.value("Ssl/CaCertificatesDict")) for server in certificateDict: for cert in QSslCertificate.fromData(certificateDict[server]): if cert not in caList: caList.append(cert) sslCfg = QSslConfiguration.defaultConfiguration() sslCfg.setCaCertificates(caList) sslCfg.setProtocol(QSsl.AnyProtocol) try: sslCfg.setSslOption(QSsl.SslOptionDisableCompression, True) except AttributeError: pass QSslConfiguration.setDefaultConfiguration(sslCfg) def sslErrorsReplySlot(self, reply, errors): """ Public slot to handle SSL errors for a network reply. @param reply reference to the reply object (QNetworkReply) @param errors list of SSL errors (list of QSslError) """ self.sslErrorsReply(reply, errors) def sslErrorsReply(self, reply, errors): """ Public slot to handle SSL errors for a network reply. @param reply reference to the reply object (QNetworkReply) @param errors list of SSL errors (list of QSslError) @return tuple indicating to ignore the SSL errors (one of NotIgnored, SystemIgnored or UserIgnored) and indicating a change of the default SSL configuration (boolean) """ url = reply.url() ignore, defaultChanged = self.sslErrors(errors, url.host(), url.port()) if ignore: if defaultChanged: reply.setSslConfiguration( QSslConfiguration.defaultConfiguration()) reply.ignoreSslErrors() else: reply.abort() return ignore, defaultChanged def sslErrors(self, errors, server, port=-1): """ Public method to handle SSL errors. @param errors list of SSL errors (list of QSslError) @param server name of the server (string) @keyparam port value of the port (integer) @return tuple indicating to ignore the SSL errors (one of NotIgnored, SystemIgnored or UserIgnored) and indicating a change of the default SSL configuration (boolean) """ caMerge = {} certificateDict = Globals.toDict( Preferences.Prefs.settings.value("Ssl/CaCertificatesDict")) for caServer in certificateDict: caMerge[caServer] = QSslCertificate.fromData( certificateDict[caServer]) caNew = [] errorStrings = [] if port != -1: server += ":{0:d}".format(port) if errors: for err in errors: if err.error() == QSslError.NoError: continue if server in caMerge and err.certificate() in caMerge[server]: continue errorStrings.append(err.errorString()) if not err.certificate().isNull(): cert = err.certificate() if cert not in caNew: caNew.append(cert) if not errorStrings: return E5SslErrorHandler.SystemIgnored, False errorString = '.
  • '.join(errorStrings) ret = E5MessageBox.yesNo( None, self.tr("SSL Errors"), self.tr("""

    SSL Errors for
    {0}""" """

    • {1}

    """ """

    Do you want to ignore these errors?

    """) .format(server, errorString), icon=E5MessageBox.Warning) if ret: caRet = False if len(caNew) > 0: certinfos = [] for cert in caNew: certinfos.append(self.__certToString(cert)) caRet = E5MessageBox.yesNo( None, self.tr("Certificates"), self.tr( """

    Certificates:
    {0}
    """ """Do you want to accept all these certificates?""" """

    """) .format("".join(certinfos))) if caRet: if server not in caMerge: caMerge[server] = [] for cert in caNew: caMerge[server].append(cert) sslCfg = QSslConfiguration.defaultConfiguration() caList = sslCfg.caCertificates() for cert in caNew: caList.append(cert) sslCfg.setCaCertificates(caList) sslCfg.setProtocol(QSsl.AnyProtocol) QSslConfiguration.setDefaultConfiguration(sslCfg) certificateDict = {} for server in caMerge: pems = QByteArray() for cert in caMerge[server]: pems.append(cert.toPem() + b'\n') certificateDict[server] = pems Preferences.Prefs.settings.setValue( "Ssl/CaCertificatesDict", certificateDict) return E5SslErrorHandler.UserIgnored, caRet else: return E5SslErrorHandler.NotIgnored, False def __certToString(self, cert): """ Private method to convert a certificate to a formatted string. @param cert certificate to convert (QSslCertificate) @return formatted string (string) """ result = "

    " if qVersion() >= "5.0.0": result += self.tr("Name: {0}")\ .format(Utilities.html_encode(Utilities.decodeString( ", ".join(cert.subjectInfo(QSslCertificate.CommonName))))) result += self.tr("
    Organization: {0}")\ .format(Utilities.html_encode(Utilities.decodeString( ", ".join(cert.subjectInfo( QSslCertificate.Organization))))) result += self.tr("
    Issuer: {0}")\ .format(Utilities.html_encode(Utilities.decodeString( ", ".join(cert.issuerInfo(QSslCertificate.CommonName))))) else: result += self.tr("Name: {0}")\ .format(Utilities.html_encode(Utilities.decodeString( cert.subjectInfo(QSslCertificate.CommonName)))) result += self.tr("
    Organization: {0}")\ .format(Utilities.html_encode(Utilities.decodeString( cert.subjectInfo(QSslCertificate.Organization)))) result += self.tr("
    Issuer: {0}")\ .format(Utilities.html_encode(Utilities.decodeString( cert.issuerInfo(QSslCertificate.CommonName)))) result += self.tr( "
    Not valid before: {0}
    Valid Until: {1}")\ .format(Utilities.html_encode( cert.effectiveDate().toString("yyyy-MM-dd")), Utilities.html_encode( cert.expiryDate().toString("yyyy-MM-dd"))) result += "

    " return result def __getSystemCaCertificates(self): """ Private method to get the list of system certificates. @return list of system certificates (list of QSslCertificate) """ caList = QSslCertificate.fromData(Globals.toByteArray( Preferences.Prefs.settings.value("Ssl/SystemCertificates"))) if not caList: caList = QSslSocket.systemCaCertificates() return caList eric-6.0.8/eric/E5Network/E5SslCertificatesDialog.ui0000644000175000017500000002012712076313362021235 0ustar piotrpiotr E5SslCertificatesDialog 0 0 760 440 SSL Certificate Manager true 0 &Servers You have saved certificates identifying these servers: Certificate name Server Expiry Date false Press to view the selected certificate &View... Press to import a certificate &Import... false Press to export the selected certificate &Export... false Press to delete the selected certificate &Delete... Qt::Horizontal 40 20 Certificate &Authorities You have saved certificates identifying these certification authorities: Certificate name Expiry Date false Press to view the selected certificate &View... Press to import a certificate &Import... false Press to export the selected certificate &Export... false Press to delete the selected certificate &Delete... Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Close certificatesWidget serversCertificatesTree serversViewButton serversImportButton serversExportButton serversDeleteButton caCertificatesTree caViewButton caImportButton caExportButton caDeleteButton buttonBox buttonBox accepted() E5SslCertificatesDialog accept() 248 254 157 274 buttonBox rejected() E5SslCertificatesDialog reject() 316 260 286 274 eric-6.0.8/eric/E5Network/E5Ftp.py0000644000175000017500000003222712451233374015577 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing an extension to the Python FTP class to support FTP proxies. """ from __future__ import unicode_literals import ftplib from socket import _GLOBAL_DEFAULT_TIMEOUT class E5FtpProxyError(ftplib.Error): """ Class to signal an error related to proxy configuration. The error message starts with a three digit error code followed by a space and the error string. Supported error codes are:
    • 910: proxy error; the second number gives the category of the proxy error. The original response from the proxy is appended in the next line.
    • 930: proxy error; the second number gives the category of the proxy error. The original response from the proxy is appended in the next line.
    • 940: proxy error; the second number gives the category of the proxy error. The original response from the proxy is appended in the next line.
    • 950: proxy error; the second number gives the category of the proxy error. The original response from the proxy is appended in the next line.
    • 990: proxy usage is enabled but no proxy host given
    • 991: proxy usage is enabled but no proxy user given
    • 992: proxy usage is enabled but no proxy password given
    """ pass class E5FtpProxyType(object): """ Class defining the supported FTP proxy types. """ NoProxy = 0 # no proxy NonAuthorizing = 1 # non authorizing proxy UserAtServer = 2 # proxy login first, than user@remote.host Site = 3 # proxy login first, than use SITE command Open = 4 # proxy login first, than use OPEN command UserAtProxyuserAtServer = 5 # one login for both ProxyuserAtServer = 6 # proxy login with remote host given, than normal remote login AuthResp = 7 # authenticate to proxy with AUTH and RESP commands Bluecoat = 8 # bluecoat proxy class E5Ftp(ftplib.FTP): """ Class implementing an extension to the Python FTP class to support FTP proxies. """ def __init__(self, host="", user="", password="", acct="", proxyType=E5FtpProxyType.NoProxy, proxyHost="", proxyPort=ftplib.FTP_PORT, proxyUser="", proxyPassword="", proxyAccount="", timeout=_GLOBAL_DEFAULT_TIMEOUT): """ Constructor @param host name of the FTP host (string) @param user user name for login to FTP host (string) @param password password for login to FTP host (string) @param acct account for login to FTP host (string) @param proxyType type of the FTP proxy (integer 0 to 8) @param proxyHost name of the FTP proxy (string) @param proxyPort port of the FTP proxy (integer) @param proxyUser user name for login to the proxy (string) @param proxyPassword password for login to the proxy (string) @param proxyAccount accounting info for the proxy (string) @param timeout timeout in seconds for blocking operations (integer) """ super(E5Ftp, self).__init__() self.__timeout = timeout self.__proxyType = proxyType self.__proxyHost = proxyHost self.__proxyPort = proxyPort self.__proxyUser = proxyUser self.__proxyPassword = proxyPassword self.__proxyAccount = proxyAccount self.__host = host self.__port = ftplib.FTP_PORT self.__user = user self.__password = password self.__acct = acct if host: self.connect(host) if user: self.login(user, password, acct) def setProxy(self, proxyType=E5FtpProxyType.NoProxy, proxyHost="", proxyPort=ftplib.FTP_PORT, proxyUser="", proxyPassword="", proxyAccount=""): """ Public method to set the proxy configuration. @param proxyType type of the FTP proxy (integer 0 to 8) @param proxyHost name of the FTP proxy (string) @param proxyPort port of the FTP proxy (integer) @param proxyUser user name for login to the proxy (string) @param proxyPassword password for login to the proxy (string) @param proxyAccount accounting info for the proxy (string) """ self.__proxyType = proxyType self.__proxyHost = proxyHost self.__proxyPort = proxyPort self.__proxyUser = proxyUser self.__proxyPassword = proxyPassword self.__proxyAccount = proxyAccount def setProxyAuthentication(self, proxyUser="", proxyPassword="", proxyAccount=""): """ Public method to set the proxy authentication info. @param proxyUser user name for login to the proxy (string) @param proxyPassword password for login to the proxy (string) @param proxyAccount accounting info for the proxy (string) """ self.__proxyUser = proxyUser self.__proxyPassword = proxyPassword self.__proxyAccount = proxyAccount def connect(self, host="", port=0, timeout=-999): """ Public method to connect to the given FTP server. This extended method connects to the proxy instead of the given host, if a proxy is to be used. It throws an exception, if the proxy data is incomplete. @param host name of the FTP host (string) @param port port of the FTP host (integer) @param timeout timeout in seconds for blocking operations (integer) @return welcome message of the server (string) @exception E5FtpProxyError raised to indicate a proxy related issue """ if host: self.__host = host if port: self.__port = port if timeout != -999: self.__timeout = timeout if self.__proxyType != E5FtpProxyType.NoProxy: if not self.__proxyHost: raise E5FtpProxyError( "990 Proxy usage requested, but no proxy host given.") return super(E5Ftp, self).connect( self.__proxyHost, self.__proxyPort, self.__timeout) else: return super(E5Ftp, self).connect( self.__host, self.__port, self.__timeout) def login(self, user="", password="", acct=""): """ Public method to login to the FTP server. This extended method respects the FTP proxy configuration. There are many different FTP proxy products available. But unfortunately there is no standard for how o traverse a FTP proxy. The lis below shows the sequence of commands used.
    userUsername for remote host
    passPassword for remote host
    pruserUsername for FTP proxy
    prpassPassword for FTP proxy
    remote.hostHostname of the remote FTP server
    E5FtpProxyType.NoProxy:
    USER user
    PASS pass
    E5FtpProxyType.NonAuthorizing:
    USER user@remote.host
    PASS pass
    E5FtpProxyType.UserAtServer:
    USER pruser
    PASS prpass
    USER user@remote.host
    PASS pass
    E5FtpProxyType.Site:
    USER pruser
    PASS prpass
    SITE remote.site
    USER user
    PASS pass
    E5FtpProxyType.Open:
    USER pruser
    PASS prpass
    OPEN remote.site
    USER user
    PASS pass
    E5FtpProxyType.UserAtProxyuserAtServer:
    USER user@pruser@remote.host
    PASS pass@prpass
    E5FtpProxyType.ProxyuserAtServer:
    USER pruser@remote.host
    PASS prpass
    USER user
    PASS pass
    E5FtpProxyType.AuthResp:
    USER user@remote.host
    PASS pass
    AUTH pruser
    RESP prpass
    E5FtpProxyType.Bluecoat:
    USER user@remote.host pruser
    PASS pass
    ACCT prpass
    @param user username for the remote host (string) @param password password for the remote host (string) @param acct accounting information for the remote host (string) @return response sent by the remote host (string) @exception E5FtpProxyError raised to indicate a proxy related issue """ if not user: user = "anonymous" if not password: # make sure it is a string password = "" if not acct: # make sure it is a string acct = "" if user == "anonymous" and password in {'', '-'}: password += "anonymous@" if self.__proxyType != E5FtpProxyType.NoProxy: if self.__proxyType != E5FtpProxyType.NonAuthorizing: # check, if a valid proxy configuration is known if not self.__proxyUser: raise E5FtpProxyError( "991 Proxy usage requested, but no proxy user given") if not self.__proxyPassword: raise E5FtpProxyError( "992 Proxy usage requested, but no proxy password" " given") if self.__proxyType in [E5FtpProxyType.NonAuthorizing, E5FtpProxyType.AuthResp, E5FtpProxyType.Bluecoat]: user += "@" + self.__host if self.__proxyType == E5FtpProxyType.Bluecoat: user += " " + self.__proxyUser acct = self.__proxyPassword elif self.__proxyType == E5FtpProxyType.UserAtProxyuserAtServer: user = "{0}@{1}@{2}".format( user, self.__proxyUser, self.__host) password = "{0}@{1}".format(password, self.__proxyPassword) else: pruser = self.__proxyUser if self.__proxyType == E5FtpProxyType.UserAtServer: user += "@" + self.__host elif self.__proxyType == E5FtpProxyType.ProxyuserAtServer: pruser += "@" + self.__host # authenticate to the proxy first presp = self.sendcmd("USER " + pruser) if presp[0] == "3": presp = self.sendcmd("PASS " + self.__proxyPassword) if presp[0] == "3" and self.__proxyAccount: presp = self.sendcmd("ACCT " + self.__proxyAccount) if presp[0] != "2": raise E5FtpProxyError( "9{0}0 Error authorizing at proxy\n{1}".format( presp[0], presp)) if self.__proxyType == E5FtpProxyType.Site: # send SITE command presp = self.sendcmd("SITE " + self.__host) if presp[0] != "2": raise E5FtpProxyError( "9{0}0 Error sending SITE command\n{1}".format( presp[0], presp)) elif self.__proxyType == E5FtpProxyType.Open: # send OPEN command presp = self.sendcmd("OPEN " + self.__host) if presp[0] != "2": raise E5FtpProxyError( "9{0}0 Error sending OPEN command\n{1}".format( presp[0], presp)) # authenticate to the remote host or combined to proxy and remote host resp = self.sendcmd("USER " + user) if resp[0] == "3": resp = self.sendcmd("PASS " + password) if resp[0] == "3": resp = self.sendcmd("ACCT " + acct) if resp[0] != "2": raise ftplib.error_reply(resp) if self.__proxyType == E5FtpProxyType.AuthResp: # authorize to the FTP proxy presp = self.sendcmd("AUTH " + self.__proxyUser) if presp[0] == "3": presp = self.sendcmd("RESP " + self.__proxyPassword) if presp[0] != "2": raise E5FtpProxyError( "9{0}0 Error authorizing at proxy\n{1}".format( presp[0], presp)) return resp eric-6.0.8/eric/E5Network/E5SslCertificatesDialog.py0000644000175000017500000005032412520643724021254 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to show and edit all certificates. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QByteArray, QFile, QFileInfo, \ QIODevice, qVersion from PyQt5.QtWidgets import QDialog, QTreeWidgetItem try: from PyQt5.QtNetwork import QSslCertificate, QSslSocket, \ QSslConfiguration, QSsl except ImportError: pass from E5Gui import E5MessageBox, E5FileDialog from .Ui_E5SslCertificatesDialog import Ui_E5SslCertificatesDialog import Preferences import Utilities import UI.PixmapCache import Globals class E5SslCertificatesDialog(QDialog, Ui_E5SslCertificatesDialog): """ Class implementing a dialog to show and edit all certificates. """ CertRole = Qt.UserRole + 1 def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(E5SslCertificatesDialog, self).__init__(parent) self.setupUi(self) self.serversViewButton.setIcon( UI.PixmapCache.getIcon("certificates.png")) self.serversDeleteButton.setIcon( UI.PixmapCache.getIcon("certificateDelete.png")) self.serversExportButton.setIcon( UI.PixmapCache.getIcon("certificateExport.png")) self.serversImportButton.setIcon( UI.PixmapCache.getIcon("certificateImport.png")) self.caViewButton.setIcon( UI.PixmapCache.getIcon("certificates.png")) self.caDeleteButton.setIcon( UI.PixmapCache.getIcon("certificateDelete.png")) self.caExportButton.setIcon( UI.PixmapCache.getIcon("certificateExport.png")) self.caImportButton.setIcon( UI.PixmapCache.getIcon("certificateImport.png")) self.__populateServerCertificatesTree() self.__populateCaCertificatesTree() def __populateServerCertificatesTree(self): """ Private slot to populate the server certificates tree. """ certificateDict = Globals.toDict( Preferences.Prefs.settings.value("Ssl/CaCertificatesDict")) for server in certificateDict: for cert in QSslCertificate.fromData(certificateDict[server]): self.__createServerCertificateEntry(server, cert) self.serversCertificatesTree.expandAll() for i in range(self.serversCertificatesTree.columnCount()): self.serversCertificatesTree.resizeColumnToContents(i) def __createServerCertificateEntry(self, server, cert): """ Private method to create a server certificate entry. @param server server name of the certificate (string) @param cert certificate to insert (QSslCertificate) """ # step 1: extract the info to be shown if qVersion() >= "5.0.0": organisation = Utilities.decodeString( ", ".join(cert.subjectInfo(QSslCertificate.Organization))) commonName = Utilities.decodeString( ", ".join(cert.subjectInfo(QSslCertificate.CommonName))) else: organisation = Utilities.decodeString( cert.subjectInfo(QSslCertificate.Organization)) commonName = Utilities.decodeString( cert.subjectInfo(QSslCertificate.CommonName)) if organisation is None or organisation == "": organisation = self.tr("(Unknown)") if commonName is None or commonName == "": commonName = self.tr("(Unknown common name)") expiryDate = cert.expiryDate().toString("yyyy-MM-dd") # step 2: create the entry items = self.serversCertificatesTree.findItems( organisation, Qt.MatchFixedString | Qt.MatchCaseSensitive) if len(items) == 0: parent = QTreeWidgetItem( self.serversCertificatesTree, [organisation]) else: parent = items[0] itm = QTreeWidgetItem(parent, [commonName, server, expiryDate]) itm.setData(0, self.CertRole, cert.toPem()) @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_serversCertificatesTree_currentItemChanged(self, current, previous): """ Private slot handling a change of the current item in the server certificates list. @param current new current item (QTreeWidgetItem) @param previous previous current item (QTreeWidgetItem) """ enable = current is not None and current.parent() is not None self.serversViewButton.setEnabled(enable) self.serversDeleteButton.setEnabled(enable) self.serversExportButton.setEnabled(enable) @pyqtSlot() def on_serversViewButton_clicked(self): """ Private slot to show data of the selected server certificate. """ try: from E5Network.E5SslCertificatesInfoDialog import \ E5SslCertificatesInfoDialog cert = QSslCertificate.fromData( self.serversCertificatesTree.currentItem().data( 0, self.CertRole)) dlg = E5SslCertificatesInfoDialog(cert, self) dlg.exec_() except ImportError: pass @pyqtSlot() def on_serversDeleteButton_clicked(self): """ Private slot to delete the selected server certificate. """ itm = self.serversCertificatesTree.currentItem() res = E5MessageBox.yesNo( self, self.tr("Delete Server Certificate"), self.tr("""

    Shall the server certificate really be""" """ deleted?

    {0}

    """ """

    If the server certificate is deleted, the""" """ normal security checks will be reinstantiated""" """ and the server has to present a valid""" """ certificate.

    """) .format(itm.text(0))) if res: server = itm.text(1) cert = self.serversCertificatesTree.currentItem().data( 0, self.CertRole) # delete the selected entry and its parent entry, # if it was the only one parent = itm.parent() parent.takeChild(parent.indexOfChild(itm)) if parent.childCount() == 0: self.serversCertificatesTree.takeTopLevelItem( self.serversCertificatesTree.indexOfTopLevelItem(parent)) # delete the certificate from the user certificate store certificateDict = Globals.toDict( Preferences.Prefs.settings.value("Ssl/CaCertificatesDict")) if server in certificateDict: certs = QSslCertificate.fromData(certificateDict[server]) if cert in certs: certs.remove(cert) if certs: pems = QByteArray() for cert in certs: pems.append(cert.toPem() + '\n') certificateDict[server] = pems else: del certificateDict[server] Preferences.Prefs.settings.setValue( "Ssl/CaCertificatesDict", certificateDict) # delete the certificate from the default certificates self.__updateDefaultConfiguration() @pyqtSlot() def on_serversImportButton_clicked(self): """ Private slot to import server certificates. """ certs = self.__importCertificate() if certs: server = "*" certificateDict = Globals.toDict( Preferences.Prefs.settings.value("Ssl/CaCertificatesDict")) if server in certificateDict: sCerts = QSslCertificate.fromData(certificateDict[server]) else: sCerts = [] pems = QByteArray() for cert in certs: if cert in sCerts: if qVersion() >= "5.0.0": commonStr = ", ".join( cert.subjectInfo(QSslCertificate.CommonName)) else: commonStr = cert.subjectInfo( QSslCertificate.CommonName) E5MessageBox.warning( self, self.tr("Import Certificate"), self.tr( """

    The certificate {0} already exists.""" """ Skipping.

    """) .format(Utilities.decodeString(commonStr))) else: pems.append(cert.toPem() + '\n') if server not in certificateDict: certificateDict[server] = QByteArray() certificateDict[server].append(pems) Preferences.Prefs.settings.setValue( "Ssl/CaCertificatesDict", certificateDict) self.serversCertificatesTree.clear() self.__populateServerCertificatesTree() self.__updateDefaultConfiguration() @pyqtSlot() def on_serversExportButton_clicked(self): """ Private slot to export the selected server certificate. """ cert = self.serversCertificatesTree.currentItem().data( 0, self.CertRole) fname = self.serversCertificatesTree.currentItem().text(0)\ .replace(" ", "").replace("\t", "") self.__exportCertificate(fname, cert) def __updateDefaultConfiguration(self): """ Private method to update the default SSL configuration. """ caList = self.__getSystemCaCertificates() certificateDict = Globals.toDict( Preferences.Prefs.settings.value("Ssl/CaCertificatesDict")) for server in certificateDict: for cert in QSslCertificate.fromData(certificateDict[server]): if cert not in caList: caList.append(cert) sslCfg = QSslConfiguration.defaultConfiguration() sslCfg.setCaCertificates(caList) QSslConfiguration.setDefaultConfiguration(sslCfg) def __getSystemCaCertificates(self): """ Private method to get the list of system certificates. @return list of system certificates (list of QSslCertificate) """ caList = QSslCertificate.fromData(Globals.toByteArray( Preferences.Prefs.settings.value("Help/SystemCertificates"))) if not caList: caList = QSslSocket.systemCaCertificates() return caList def __populateCaCertificatesTree(self): """ Private slot to populate the CA certificates tree. """ for cert in self.__getSystemCaCertificates(): self.__createCaCertificateEntry(cert) self.caCertificatesTree.expandAll() for i in range(self.caCertificatesTree.columnCount()): self.caCertificatesTree.resizeColumnToContents(i) self.caCertificatesTree.sortItems(0, Qt.AscendingOrder) def __createCaCertificateEntry(self, cert): """ Private method to create a CA certificate entry. @param cert certificate to insert (QSslCertificate) """ # step 1: extract the info to be shown if qVersion() >= "5.0.0": organisation = Utilities.decodeString( ", ".join(cert.subjectInfo(QSslCertificate.Organization))) commonName = Utilities.decodeString( ", ".join(cert.subjectInfo(QSslCertificate.CommonName))) else: organisation = Utilities.decodeString( cert.subjectInfo(QSslCertificate.Organization)) commonName = Utilities.decodeString( cert.subjectInfo(QSslCertificate.CommonName)) if organisation is None or organisation == "": organisation = self.tr("(Unknown)") if commonName is None or commonName == "": commonName = self.tr("(Unknown common name)") expiryDate = cert.expiryDate().toString("yyyy-MM-dd") # step 2: create the entry items = self.caCertificatesTree.findItems( organisation, Qt.MatchFixedString | Qt.MatchCaseSensitive) if len(items) == 0: parent = QTreeWidgetItem(self.caCertificatesTree, [organisation]) else: parent = items[0] itm = QTreeWidgetItem(parent, [commonName, expiryDate]) itm.setData(0, self.CertRole, cert.toPem()) @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_caCertificatesTree_currentItemChanged(self, current, previous): """ Private slot handling a change of the current item in the CA certificates list. @param current new current item (QTreeWidgetItem) @param previous previous current item (QTreeWidgetItem) """ enable = current is not None and current.parent() is not None self.caViewButton.setEnabled(enable) self.caDeleteButton.setEnabled(enable) self.caExportButton.setEnabled(enable) @pyqtSlot() def on_caViewButton_clicked(self): """ Private slot to show data of the selected CA certificate. """ try: from E5Network.E5SslCertificatesInfoDialog import \ E5SslCertificatesInfoDialog cert = QSslCertificate.fromData( self.caCertificatesTree.currentItem().data(0, self.CertRole)) dlg = E5SslCertificatesInfoDialog(cert, self) dlg.exec_() except ImportError: pass @pyqtSlot() def on_caDeleteButton_clicked(self): """ Private slot to delete the selected CA certificate. """ itm = self.caCertificatesTree.currentItem() res = E5MessageBox.yesNo( self, self.tr("Delete CA Certificate"), self.tr( """

    Shall the CA certificate really be deleted?

    """ """

    {0}

    """ """

    If the CA certificate is deleted, the browser""" """ will not trust any certificate issued by this CA.

    """) .format(itm.text(0))) if res: cert = self.caCertificatesTree.currentItem().data(0, self.CertRole) # delete the selected entry and its parent entry, # if it was the only one parent = itm.parent() parent.takeChild(parent.indexOfChild(itm)) if parent.childCount() == 0: self.caCertificatesTree.takeTopLevelItem( self.caCertificatesTree.indexOfTopLevelItem(parent)) # delete the certificate from the CA certificate store caCerts = self.__getSystemCaCertificates() if cert in caCerts: caCerts.remove(cert) pems = QByteArray() for cert in caCerts: pems.append(cert.toPem() + '\n') Preferences.Prefs.settings.setValue( "Help/SystemCertificates", pems) # delete the certificate from the default certificates self.__updateDefaultConfiguration() @pyqtSlot() def on_caImportButton_clicked(self): """ Private slot to import server certificates. """ certs = self.__importCertificate() if certs: caCerts = self.__getSystemCaCertificates() for cert in certs: if cert in caCerts: if qVersion() >= "5.0.0": commonStr = ", ".join( cert.subjectInfo(QSslCertificate.CommonName)) else: commonStr = cert.subjectInfo( QSslCertificate.CommonName) E5MessageBox.warning( self, self.tr("Import Certificate"), self.tr( """

    The certificate {0} already exists.""" """ Skipping.

    """) .format(Utilities.decodeString(commonStr))) else: caCerts.append(cert) pems = QByteArray() for cert in caCerts: pems.append(cert.toPem() + '\n') Preferences.Prefs.settings.setValue( "Help/SystemCertificates", pems) self.caCertificatesTree.clear() self.__populateCaCertificatesTree() self.__updateDefaultConfiguration() @pyqtSlot() def on_caExportButton_clicked(self): """ Private slot to export the selected CA certificate. """ cert = self.caCertificatesTree.currentItem().data(0, self.CertRole) fname = self.caCertificatesTree.currentItem().text(0)\ .replace(" ", "").replace("\t", "") self.__exportCertificate(fname, cert) def __exportCertificate(self, name, cert): """ Private slot to export a certificate. @param name default file name without extension (string) @param cert certificate to be exported (QSslCertificate) """ if cert is not None: fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Export Certificate"), name, self.tr("Certificate File (PEM) (*.pem);;" "Certificate File (DER) (*.der)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fname: ext = QFileInfo(fname).suffix() if not ext or ext not in ["pem", "der"]: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Export Certificate"), self.tr("

    The file {0} already exists." " Overwrite it?

    ").format(fname), icon=E5MessageBox.Warning) if not res: return f = QFile(fname) if not f.open(QIODevice.WriteOnly): E5MessageBox.critical( self, self.tr("Export Certificate"), self.tr( """

    The certificate could not be written""" """ to file {0}

    Error: {1}

    """) .format(fname, f.errorString())) return if fname.endswith(".pem"): crt = cert.toPem() else: crt = cert.toDer() f.write(crt) f.close() def __importCertificate(self): """ Private method to read a certificate. @return certificates read (list of QSslCertificate) """ fname = E5FileDialog.getOpenFileName( self, self.tr("Import Certificate"), "", self.tr("Certificate Files (*.pem *.crt *.der *.cer *.ca);;" "All Files (*)")) if fname: f = QFile(fname) if not f.open(QIODevice.ReadOnly): E5MessageBox.critical( self, self.tr("Export Certificate"), self.tr( """

    The certificate could not be read from file""" """ {0}

    Error: {1}

    """) .format(fname, f.errorString())) return [] crt = f.readAll() f.close() cert = QSslCertificate.fromData(crt, QSsl.Pem) if not cert: cert = QSslCertificate.fromData(crt, QSsl.Der) return cert return [] eric-6.0.8/eric/E5Network/E5SslCertificatesInfoDialog.ui0000644000175000017500000000353512112406752022052 0ustar piotrpiotr E5SslCertificatesInfoDialog 0 0 556 486 SSL Certificate Info true Qt::Horizontal QDialogButtonBox::Close E5SslCertificatesInfoWidget QWidget
    E5Network/E5SslCertificatesInfoWidget.h
    1
    buttonBox accepted() E5SslCertificatesInfoDialog accept() 248 254 157 274 buttonBox rejected() E5SslCertificatesInfoDialog reject() 316 260 286 274
    eric-6.0.8/eric/PluginManager/0000755000175000017500000000000012557365404015211 5ustar piotrpiotreric-6.0.8/eric/PluginManager/PluginRepositoryDialog.py0000644000175000017500000007520612451233374022244 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog showing the available plugins. """ from __future__ import unicode_literals import sys import os import zipfile import glob from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QFile, QIODevice, QUrl, \ QProcess, QPoint from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QAbstractButton, \ QTreeWidgetItem, QDialog, QVBoxLayout, QMenu from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, \ QNetworkReply from .Ui_PluginRepositoryDialog import Ui_PluginRepositoryDialog from E5Gui import E5MessageBox from E5Gui.E5MainWindow import E5MainWindow from E5Gui.E5Application import e5App from E5Network.E5NetworkProxyFactory import proxyAuthenticationRequired try: from E5Network.E5SslErrorHandler import E5SslErrorHandler SSL_AVAILABLE = True except ImportError: SSL_AVAILABLE = False import Utilities import Preferences import UI.PixmapCache from eric6config import getConfig class PluginRepositoryWidget(QWidget, Ui_PluginRepositoryDialog): """ Class implementing a dialog showing the available plugins. @signal closeAndInstall() emitted when the Close & Install button is pressed """ closeAndInstall = pyqtSignal() DescrRole = Qt.UserRole UrlRole = Qt.UserRole + 1 FilenameRole = Qt.UserRole + 2 AuthorRole = Qt.UserRole + 3 PluginStatusUpToDate = 0 PluginStatusNew = 1 PluginStatusLocalUpdate = 2 PluginStatusRemoteUpdate = 3 def __init__(self, parent=None, external=False): """ Constructor @param parent parent of this dialog (QWidget) @param external flag indicating an instatiation as a main window (boolean) """ super(PluginRepositoryWidget, self).__init__(parent) self.setupUi(self) self.__updateButton = self.buttonBox.addButton( self.tr("Update"), QDialogButtonBox.ActionRole) self.__downloadButton = self.buttonBox.addButton( self.tr("Download"), QDialogButtonBox.ActionRole) self.__downloadButton.setEnabled(False) self.__downloadInstallButton = self.buttonBox.addButton( self.tr("Download && Install"), QDialogButtonBox.ActionRole) self.__downloadInstallButton.setEnabled(False) self.__downloadCancelButton = self.buttonBox.addButton( self.tr("Cancel"), QDialogButtonBox.ActionRole) self.__installButton = \ self.buttonBox.addButton(self.tr("Close && Install"), QDialogButtonBox.ActionRole) self.__downloadCancelButton.setEnabled(False) self.__installButton.setEnabled(False) self.repositoryUrlEdit.setText( Preferences.getUI("PluginRepositoryUrl6")) self.repositoryList.headerItem().setText( self.repositoryList.columnCount(), "") self.repositoryList.header().setSortIndicator(0, Qt.AscendingOrder) self.__pluginContextMenu = QMenu(self) self.__hideAct = self.__pluginContextMenu.addAction( self.tr("Hide"), self.__hidePlugin) self.__hideSelectedAct = self.__pluginContextMenu.addAction( self.tr("Hide Selected"), self.__hideSelectedPlugins) self.__pluginContextMenu.addSeparator() self.__showAllAct = self.__pluginContextMenu.addAction( self.tr("Show All"), self.__showAllPlugins) self.__pluginContextMenu.addSeparator() self.__pluginContextMenu.addAction( self.tr("Cleanup Downloads"), self.__cleanupDownloads) self.pluginRepositoryFile = \ os.path.join(Utilities.getConfigDir(), "PluginRepository") self.__external = external # attributes for the network objects self.__networkManager = QNetworkAccessManager(self) self.__networkManager.proxyAuthenticationRequired.connect( proxyAuthenticationRequired) if SSL_AVAILABLE: self.__sslErrorHandler = E5SslErrorHandler(self) self.__networkManager.sslErrors.connect(self.__sslErrors) self.__replies = [] self.__doneMethod = None self.__inDownload = False self.__pluginsToDownload = [] self.__pluginsDownloaded = [] self.__isDownloadInstall = False self.__allDownloadedOk = False self.__hiddenPlugins = Preferences.getPluginManager("HiddenPlugins") self.__populateList() @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot to handle the click of a button of the button box. @param button reference to the button pressed (QAbstractButton) """ if button == self.__updateButton: self.__updateList() elif button == self.__downloadButton: self.__isDownloadInstall = False self.__downloadPlugins() elif button == self.__downloadInstallButton: self.__isDownloadInstall = True self.__allDownloadedOk = True self.__downloadPlugins() elif button == self.__downloadCancelButton: self.__downloadCancel() elif button == self.__installButton: self.__closeAndInstall() def __formatDescription(self, lines): """ Private method to format the description. @param lines lines of the description (list of strings) @return formatted description (string) """ # remove empty line at start and end newlines = lines[:] if len(newlines) and newlines[0] == '': del newlines[0] if len(newlines) and newlines[-1] == '': del newlines[-1] # replace empty lines by newline character index = 0 while index < len(newlines): if newlines[index] == '': newlines[index] = '\n' index += 1 # join lines by a blank return ' '.join(newlines) @pyqtSlot(QPoint) def on_repositoryList_customContextMenuRequested(self, pos): """ Private slot to show the context menu. @param pos position to show the menu (QPoint) """ self.__hideAct.setEnabled( self.repositoryList.currentItem() is not None and len(self.__selectedItems()) == 1) self.__hideSelectedAct.setEnabled( len(self.__selectedItems()) > 1) self.__showAllAct.setEnabled(bool(self.__hasHiddenPlugins())) self.__pluginContextMenu.popup(self.repositoryList.mapToGlobal(pos)) @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_repositoryList_currentItemChanged(self, current, previous): """ Private slot to handle the change of the current item. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the old current item (QTreeWidgetItem) """ if self.__repositoryMissing or current is None: return self.urlEdit.setText( current.data(0, PluginRepositoryWidget.UrlRole) or "") self.descriptionEdit.setPlainText( current.data(0, PluginRepositoryWidget.DescrRole) and self.__formatDescription( current.data(0, PluginRepositoryWidget.DescrRole)) or "") self.authorEdit.setText( current.data(0, PluginRepositoryWidget.AuthorRole) or "") def __selectedItems(self): """ Private method to get all selected items without the toplevel ones. @return list of selected items (list) """ ql = self.repositoryList.selectedItems() for index in range(self.repositoryList.topLevelItemCount()): ti = self.repositoryList.topLevelItem(index) if ti in ql: ql.remove(ti) return ql @pyqtSlot() def on_repositoryList_itemSelectionChanged(self): """ Private slot to handle a change of the selection. """ self.__downloadButton.setEnabled(len(self.__selectedItems())) self.__downloadInstallButton.setEnabled(len(self.__selectedItems())) self.__installButton.setEnabled(len(self.__selectedItems())) def __updateList(self): """ Private slot to download a new list and display the contents. """ url = self.repositoryUrlEdit.text() self.__downloadFile(url, self.pluginRepositoryFile, self.__downloadRepositoryFileDone) def __downloadRepositoryFileDone(self, status, filename): """ Private method called after the repository file was downloaded. @param status flaging indicating a successful download (boolean) @param filename full path of the downloaded file (string) """ self.__populateList() def __downloadPluginDone(self, status, filename): """ Private method called, when the download of a plugin is finished. @param status flag indicating a successful download (boolean) @param filename full path of the downloaded file (string) """ if status: self.__pluginsDownloaded.append(filename) if self.__isDownloadInstall: self.__allDownloadedOk &= status del self.__pluginsToDownload[0] if len(self.__pluginsToDownload): self.__downloadPlugin() else: self.__downloadPluginsDone() def __downloadPlugin(self): """ Private method to download the next plugin. """ self.__downloadFile(self.__pluginsToDownload[0][0], self.__pluginsToDownload[0][1], self.__downloadPluginDone) def __downloadPlugins(self): """ Private slot to download the selected plugins. """ self.__pluginsDownloaded = [] self.__pluginsToDownload = [] self.__downloadButton.setEnabled(False) self.__downloadInstallButton.setEnabled(False) self.__installButton.setEnabled(False) for itm in self.repositoryList.selectedItems(): if itm not in [self.__stableItem, self.__unstableItem, self.__unknownItem]: url = itm.data(0, PluginRepositoryWidget.UrlRole) filename = os.path.join( Preferences.getPluginManager("DownloadPath"), itm.data(0, PluginRepositoryWidget.FilenameRole)) self.__pluginsToDownload.append((url, filename)) self.__downloadPlugin() def __downloadPluginsDone(self): """ Private method called, when the download of the plugins is finished. """ self.__downloadButton.setEnabled(len(self.__selectedItems())) self.__downloadInstallButton.setEnabled(len(self.__selectedItems())) self.__installButton.setEnabled(True) self.__doneMethod = None if not self.__external: ui = e5App().getObject("UserInterface") else: ui = None if ui and ui.notificationsEnabled(): ui.showNotification( UI.PixmapCache.getPixmap("plugin48.png"), self.tr("Download Plugin Files"), self.tr("""The requested plugins were downloaded.""")) if self.__isDownloadInstall: self.closeAndInstall.emit() else: if ui is None or not ui.notificationsEnabled(): E5MessageBox.information( self, self.tr("Download Plugin Files"), self.tr("""The requested plugins were downloaded.""")) self.downloadProgress.setValue(0) # repopulate the list to update the refresh icons self.__populateList() def __resortRepositoryList(self): """ Private method to resort the tree. """ self.repositoryList.sortItems( self.repositoryList.sortColumn(), self.repositoryList.header().sortIndicatorOrder()) def __populateList(self): """ Private method to populate the list of available plugins. """ self.repositoryList.clear() self.__stableItem = None self.__unstableItem = None self.__unknownItem = None self.downloadProgress.setValue(0) self.__doneMethod = None if os.path.exists(self.pluginRepositoryFile): self.__repositoryMissing = False f = QFile(self.pluginRepositoryFile) if f.open(QIODevice.ReadOnly): from E5XML.PluginRepositoryReader import PluginRepositoryReader reader = PluginRepositoryReader(f, self.addEntry) reader.readXML() self.repositoryList.resizeColumnToContents(0) self.repositoryList.resizeColumnToContents(1) self.repositoryList.resizeColumnToContents(2) self.__resortRepositoryList() url = Preferences.getUI("PluginRepositoryUrl6") if url != self.repositoryUrlEdit.text(): self.repositoryUrlEdit.setText(url) E5MessageBox.warning( self, self.tr("Plugins Repository URL Changed"), self.tr( """The URL of the Plugins Repository has""" """ changed. Select the "Update" button to get""" """ the new repository file.""")) else: E5MessageBox.critical( self, self.tr("Read plugins repository file"), self.tr("

    The plugins repository file {0} " "could not be read. Select Update

    ") .format(self.pluginRepositoryFile)) else: self.__repositoryMissing = True QTreeWidgetItem( self.repositoryList, ["", self.tr( "No plugin repository file available.\nSelect Update.") ]) self.repositoryList.resizeColumnToContents(1) def __downloadFile(self, url, filename, doneMethod=None): """ Private slot to download the given file. @param url URL for the download (string) @param filename local name of the file (string) @param doneMethod method to be called when done """ self.__updateButton.setEnabled(False) self.__downloadButton.setEnabled(False) self.__downloadInstallButton.setEnabled(False) self.__downloadCancelButton.setEnabled(True) self.statusLabel.setText(url) self.__doneMethod = doneMethod self.__downloadURL = url self.__downloadFileName = filename self.__downloadIODevice = QFile(self.__downloadFileName + ".tmp") self.__downloadCancelled = False request = QNetworkRequest(QUrl(url)) request.setAttribute(QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) reply = self.__networkManager.get(request) reply.finished.connect(self.__downloadFileDone) reply.downloadProgress.connect(self.__downloadProgress) self.__replies.append(reply) def __downloadFileDone(self): """ Private method called, after the file has been downloaded from the internet. """ self.__updateButton.setEnabled(True) self.__downloadCancelButton.setEnabled(False) self.statusLabel.setText(" ") ok = True reply = self.sender() if reply in self.__replies: self.__replies.remove(reply) if reply.error() != QNetworkReply.NoError: ok = False if not self.__downloadCancelled: E5MessageBox.warning( self, self.tr("Error downloading file"), self.tr( """

    Could not download the requested file""" """ from {0}.

    Error: {1}

    """ ).format(self.__downloadURL, reply.errorString()) ) self.downloadProgress.setValue(0) self.__downloadURL = None self.__downloadIODevice.remove() self.__downloadIODevice = None if self.repositoryList.topLevelItemCount(): if self.repositoryList.currentItem() is None: self.repositoryList.setCurrentItem( self.repositoryList.topLevelItem(0)) else: self.__downloadButton.setEnabled( len(self.__selectedItems())) self.__downloadInstallButton.setEnabled( len(self.__selectedItems())) return self.__downloadIODevice.open(QIODevice.WriteOnly) self.__downloadIODevice.write(reply.readAll()) self.__downloadIODevice.close() if QFile.exists(self.__downloadFileName): QFile.remove(self.__downloadFileName) self.__downloadIODevice.rename(self.__downloadFileName) self.__downloadIODevice = None self.__downloadURL = None if self.__doneMethod is not None: self.__doneMethod(ok, self.__downloadFileName) def __downloadCancel(self): """ Private slot to cancel the current download. """ if self.__replies: reply = self.__replies[0] self.__downloadCancelled = True self.__pluginsToDownload = [] reply.abort() def __downloadProgress(self, done, total): """ Private slot to show the download progress. @param done number of bytes downloaded so far (integer) @param total total bytes to be downloaded (integer) """ if total: self.downloadProgress.setMaximum(total) self.downloadProgress.setValue(done) def addEntry(self, name, short, description, url, author, version, filename, status): """ Public method to add an entry to the list. @param name data for the name field (string) @param short data for the short field (string) @param description data for the description field (list of strings) @param url data for the url field (string) @param author data for the author field (string) @param version data for the version field (string) @param filename data for the filename field (string) @param status status of the plugin (string [stable, unstable, unknown]) """ pluginName = filename.rsplit("-", 1)[0] if pluginName in self.__hiddenPlugins: return if status == "stable": if self.__stableItem is None: self.__stableItem = \ QTreeWidgetItem(self.repositoryList, [self.tr("Stable")]) self.__stableItem.setExpanded(True) parent = self.__stableItem elif status == "unstable": if self.__unstableItem is None: self.__unstableItem = \ QTreeWidgetItem(self.repositoryList, [self.tr("Unstable")]) self.__unstableItem.setExpanded(True) parent = self.__unstableItem else: if self.__unknownItem is None: self.__unknownItem = \ QTreeWidgetItem(self.repositoryList, [self.tr("Unknown")]) self.__unknownItem.setExpanded(True) parent = self.__unknownItem itm = QTreeWidgetItem(parent, [name, version, short]) itm.setData(0, PluginRepositoryWidget.UrlRole, url) itm.setData(0, PluginRepositoryWidget.FilenameRole, filename) itm.setData(0, PluginRepositoryWidget.AuthorRole, author) itm.setData(0, PluginRepositoryWidget.DescrRole, description) updateStatus = self.__updateStatus(filename, version) if updateStatus == PluginRepositoryWidget.PluginStatusUpToDate: itm.setIcon(1, UI.PixmapCache.getIcon("empty.png")) itm.setToolTip(1, self.tr("up-to-date")) elif updateStatus == PluginRepositoryWidget.PluginStatusNew: itm.setIcon(1, UI.PixmapCache.getIcon("download.png")) itm.setToolTip(1, self.tr("new download available")) elif updateStatus == PluginRepositoryWidget.PluginStatusLocalUpdate: itm.setIcon(1, UI.PixmapCache.getIcon("updateLocal.png")) itm.setToolTip(1, self.tr("update installable")) elif updateStatus == PluginRepositoryWidget.PluginStatusRemoteUpdate: itm.setIcon(1, UI.PixmapCache.getIcon("updateRemote.png")) itm.setToolTip(1, self.tr("updated download available")) def __updateStatus(self, filename, version): """ Private method to check, if the given archive update status. @param filename data for the filename field (string) @param version data for the version field (string) @return plug-in update status (integer, one of PluginStatusNew, PluginStatusUpToDate, PluginStatusLocalUpdate, PluginStatusRemoteUpdate) """ archive = os.path.join(Preferences.getPluginManager("DownloadPath"), filename) # check, if it is an update (i.e. we already have archives # with the same pattern) archivesPattern = archive.rsplit('-', 1)[0] + "-*.zip" if len(glob.glob(archivesPattern)) == 0: return PluginRepositoryWidget.PluginStatusNew # check, if the archive exists if not os.path.exists(archive): return PluginRepositoryWidget.PluginStatusRemoteUpdate # check, if the archive is a valid zip file if not zipfile.is_zipfile(archive): return PluginRepositoryWidget.PluginStatusRemoteUpdate zip = zipfile.ZipFile(archive, "r") try: aversion = zip.read("VERSION").decode("utf-8") except KeyError: aversion = "" zip.close() if aversion == version: if not self.__external: # Check against installed/loaded plug-ins pluginManager = e5App().getObject("PluginManager") pluginName = filename.rsplit('-', 1)[0] pluginDetails = pluginManager.getPluginDetails(pluginName) if pluginDetails is None or pluginDetails["version"] < version: return PluginRepositoryWidget.PluginStatusLocalUpdate return PluginRepositoryWidget.PluginStatusUpToDate else: return PluginRepositoryWidget.PluginStatusRemoteUpdate def __sslErrors(self, reply, errors): """ Private slot to handle SSL errors. @param reply reference to the reply object (QNetworkReply) @param errors list of SSL errors (list of QSslError) """ ignored = self.__sslErrorHandler.sslErrorsReply(reply, errors)[0] if ignored == E5SslErrorHandler.NotIgnored: self.__downloadCancelled = True def getDownloadedPlugins(self): """ Public method to get the list of recently downloaded plugin files. @return list of plugin filenames (list of strings) """ return self.__pluginsDownloaded @pyqtSlot(bool) def on_repositoryUrlEditButton_toggled(self, checked): """ Private slot to set the read only status of the repository URL line edit. @param checked state of the push button (boolean) """ self.repositoryUrlEdit.setReadOnly(not checked) def __closeAndInstall(self): """ Private method to close the dialog and invoke the install dialog. """ if not self.__pluginsDownloaded and self.__selectedItems(): for itm in self.__selectedItems(): filename = os.path.join( Preferences.getPluginManager("DownloadPath"), itm.data(0, PluginRepositoryWidget.FilenameRole)) self.__pluginsDownloaded.append(filename) self.closeAndInstall.emit() def __hidePlugin(self): """ Private slot to hide the current plug-in. """ itm = self.__selectedItems()[0] pluginName = (itm.data(0, PluginRepositoryWidget.FilenameRole) .rsplit("-", 1)[0]) self.__updateHiddenPluginsList([pluginName]) def __hideSelectedPlugins(self): """ Private slot to hide all selected plug-ins. """ hideList = [] for itm in self.__selectedItems(): pluginName = (itm.data(0, PluginRepositoryWidget.FilenameRole) .rsplit("-", 1)[0]) hideList.append(pluginName) self.__updateHiddenPluginsList(hideList) def __showAllPlugins(self): """ Private slot to show all plug-ins. """ self.__hiddenPlugins = [] self.__updateHiddenPluginsList([]) def __hasHiddenPlugins(self): """ Private method to check, if there are any hidden plug-ins. @return flag indicating the presence of hidden plug-ins (boolean) """ return bool(self.__hiddenPlugins) def __updateHiddenPluginsList(self, hideList): """ Private method to store the list of hidden plug-ins to the settings. @param hideList list of plug-ins to add to the list of hidden ones (list of string) """ if hideList: self.__hiddenPlugins.extend( [p for p in hideList if p not in self.__hiddenPlugins]) Preferences.setPluginManager("HiddenPlugins", self.__hiddenPlugins) self.__populateList() def __cleanupDownloads(self): """ Private slot to cleanup the plug-in downloads area. """ downloadPath = Preferences.getPluginManager("DownloadPath") downloads = {} # plug-in name as key, file name as value # step 1: extract plug-ins and downloaded files for pluginFile in os.listdir(downloadPath): if not os.path.isfile(os.path.join(downloadPath, pluginFile)): continue pluginName = pluginFile.rsplit("-", 1)[0] if pluginName not in downloads: downloads[pluginName] = [] downloads[pluginName].append(pluginFile) # step 2: delete old entries for pluginName in downloads: downloads[pluginName].sort() if pluginName in self.__hiddenPlugins and \ not Preferences.getPluginManager("KeepHidden"): removeFiles = downloads[pluginName] else: removeFiles = downloads[pluginName][ :-Preferences.getPluginManager("KeepGenerations")] for removeFile in removeFiles: try: os.remove(os.path.join(downloadPath, removeFile)) except (IOError, OSError) as err: E5MessageBox.critical( self, self.tr("Cleanup of Plugin Downloads"), self.tr("""

    The plugin download {0} could""" """ not be deleted.

    Reason: {1}

    """) .format(removeFile, str(err))) class PluginRepositoryDialog(QDialog): """ Class for the dialog variant. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(PluginRepositoryDialog, self).__init__(parent) self.setSizeGripEnabled(True) self.__layout = QVBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.__layout) self.cw = PluginRepositoryWidget(self) size = self.cw.size() self.__layout.addWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.cw.buttonBox.accepted.connect(self.accept) self.cw.buttonBox.rejected.connect(self.reject) self.cw.closeAndInstall.connect(self.__closeAndInstall) def __closeAndInstall(self): """ Private slot to handle the closeAndInstall signal. """ self.done(QDialog.Accepted + 1) def getDownloadedPlugins(self): """ Public method to get the list of recently downloaded plugin files. @return list of plugin filenames (list of strings) """ return self.cw.getDownloadedPlugins() class PluginRepositoryWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(PluginRepositoryWindow, self).__init__(parent) self.cw = PluginRepositoryWidget(self, external=True) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw.buttonBox.accepted.connect(self.close) self.cw.buttonBox.rejected.connect(self.close) self.cw.closeAndInstall.connect(self.__startPluginInstall) def __startPluginInstall(self): """ Private slot to start the eric6 plugin installation dialog. """ proc = QProcess() applPath = os.path.join(getConfig("ericDir"), "eric6_plugininstall.py") args = [] args.append(applPath) args += self.cw.getDownloadedPlugins() if not os.path.isfile(applPath) or \ not proc.startDetached(sys.executable, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '

    Could not start the process.
    ' 'Ensure that it is available as {0}.

    ' ).format(applPath), self.tr('OK')) self.close() eric-6.0.8/eric/PluginManager/PluginUninstallDialog.py0000644000175000017500000002137012451233374022027 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing a dialog for plugin deinstallation. """ from __future__ import unicode_literals import sys import os import imp import shutil import glob from PyQt5.QtCore import pyqtSlot, pyqtSignal from PyQt5.QtWidgets import QWidget, QDialog, QDialogButtonBox, QVBoxLayout from E5Gui import E5MessageBox from E5Gui.E5MainWindow import E5MainWindow from E5Gui.E5Application import e5App from .Ui_PluginUninstallDialog import Ui_PluginUninstallDialog import Preferences import UI.PixmapCache class PluginUninstallWidget(QWidget, Ui_PluginUninstallDialog): """ Class implementing a dialog for plugin deinstallation. """ accepted = pyqtSignal() def __init__(self, pluginManager, parent=None): """ Constructor @param pluginManager reference to the plugin manager object @param parent parent of this dialog (QWidget) """ super(PluginUninstallWidget, self).__init__(parent) self.setupUi(self) if pluginManager is None: # started as external plugin deinstaller from .PluginManager import PluginManager self.__pluginManager = PluginManager(doLoadPlugins=False) self.__external = True else: self.__pluginManager = pluginManager self.__external = False self.pluginDirectoryCombo.addItem( self.tr("User plugins directory"), self.__pluginManager.getPluginDir("user")) globalDir = self.__pluginManager.getPluginDir("global") if globalDir is not None and os.access(globalDir, os.W_OK): self.pluginDirectoryCombo.addItem( self.tr("Global plugins directory"), globalDir) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot(int) def on_pluginDirectoryCombo_currentIndexChanged(self, index): """ Private slot to populate the plugin name combo upon a change of the plugin area. @param index index of the selected item (integer) """ pluginDirectory = self.pluginDirectoryCombo.itemData(index) pluginNames = sorted(self.__pluginManager.getPluginModules( pluginDirectory)) self.pluginNameCombo.clear() for pluginName in pluginNames: fname = "{0}.py".format(os.path.join(pluginDirectory, pluginName)) self.pluginNameCombo.addItem(pluginName, fname) self.buttonBox.button(QDialogButtonBox.Ok)\ .setEnabled(self.pluginNameCombo.currentText() != "") @pyqtSlot() def on_buttonBox_accepted(self): """ Private slot to handle the accepted signal of the button box. """ if self.__uninstallPlugin(): self.accepted.emit() def __uninstallPlugin(self): """ Private slot to uninstall the selected plugin. @return flag indicating success (boolean) """ pluginDirectory = self.pluginDirectoryCombo\ .itemData(self.pluginDirectoryCombo.currentIndex()) pluginName = self.pluginNameCombo.currentText() pluginFile = self.pluginNameCombo\ .itemData(self.pluginNameCombo.currentIndex()) if not self.__pluginManager.unloadPlugin(pluginName): E5MessageBox.critical( self, self.tr("Plugin Uninstallation"), self.tr( """

    The plugin {0} could not be unloaded.""" """ Aborting...

    """).format(pluginName)) return False if pluginDirectory not in sys.path: sys.path.insert(2, pluginDirectory) module = imp.load_source(pluginName, pluginFile) if not hasattr(module, "packageName"): E5MessageBox.critical( self, self.tr("Plugin Uninstallation"), self.tr( """

    The plugin {0} has no 'packageName'""" """ attribute. Aborting...

    """).format(pluginName)) return False package = getattr(module, "packageName") if package is None: package = "None" packageDir = "" else: packageDir = os.path.join(pluginDirectory, package) if hasattr(module, "prepareUninstall"): module.prepareUninstall() internalPackages = [] if hasattr(module, "internalPackages"): # it is a comma separated string internalPackages = [p.strip() for p in module.internalPackages.split(",")] del module # clean sys.modules self.__pluginManager.removePluginFromSysModules( pluginName, package, internalPackages) try: if packageDir and os.path.exists(packageDir): shutil.rmtree(packageDir) fnameo = "{0}o".format(pluginFile) if os.path.exists(fnameo): os.remove(fnameo) fnamec = "{0}c".format(pluginFile) if os.path.exists(fnamec): os.remove(fnamec) pluginDirCache = os.path.join( os.path.dirname(pluginFile), "__pycache__") if os.path.exists(pluginDirCache): pluginFileName = os.path.splitext( os.path.basename(pluginFile))[0] for fnameo in glob.glob(os.path.join( pluginDirCache, "{0}*.pyo".format(pluginFileName))): os.remove(fnameo) for fnamec in glob.glob(os.path.join( pluginDirCache, "{0}*.pyc".format(pluginFileName))): os.remove(fnamec) os.remove(pluginFile) except OSError as err: E5MessageBox.critical( self, self.tr("Plugin Uninstallation"), self.tr( """

    The plugin package {0} could not be""" """ removed. Aborting...

    """ """

    Reason: {1}

    """).format(packageDir, str(err))) return False if not self.__external: ui = e5App().getObject("UserInterface") if ui.notificationsEnabled(): ui.showNotification( UI.PixmapCache.getPixmap("plugin48.png"), self.tr("Plugin Uninstallation"), self.tr( """

    The plugin {0} was uninstalled""" """ successfully from {1}.

    """) .format(pluginName, pluginDirectory)) return True E5MessageBox.information( self, self.tr("Plugin Uninstallation"), self.tr( """

    The plugin {0} was uninstalled successfully""" """ from {1}.

    """) .format(pluginName, pluginDirectory)) return True class PluginUninstallDialog(QDialog): """ Class for the dialog variant. """ def __init__(self, pluginManager, parent=None): """ Constructor @param pluginManager reference to the plugin manager object @param parent reference to the parent widget (QWidget) """ super(PluginUninstallDialog, self).__init__(parent) self.setSizeGripEnabled(True) self.__layout = QVBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.__layout) self.cw = PluginUninstallWidget(pluginManager, self) size = self.cw.size() self.__layout.addWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.cw.buttonBox.accepted.connect(self.accept) self.cw.buttonBox.rejected.connect(self.reject) class PluginUninstallWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(PluginUninstallWindow, self).__init__(parent) self.cw = PluginUninstallWidget(None, self) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw.buttonBox.accepted.connect(self.close) self.cw.buttonBox.rejected.connect(self.close) eric-6.0.8/eric/PluginManager/PluginDetailsDialog.py0000644000175000017500000000353412537064320021443 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Plugin Details Dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtWidgets import QDialog from .Ui_PluginDetailsDialog import Ui_PluginDetailsDialog class PluginDetailsDialog(QDialog, Ui_PluginDetailsDialog): """ Class implementing the Plugin Details Dialog. """ def __init__(self, details, parent=None): """ Constructor @param details dictionary containing the info to be displayed @param parent parent of this dialog (QWidget) """ super(PluginDetailsDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.__autoactivate = details["autoactivate"] self.__active = details["active"] self.moduleNameEdit.setText(details["moduleName"]) self.moduleFileNameEdit.setText(details["moduleFileName"]) self.pluginNameEdit.setText(details["pluginName"]) self.versionEdit.setText(details["version"]) self.authorEdit.setText(details["author"]) self.descriptionEdit.setText(details["description"]) self.errorEdit.setText(details["error"]) self.autoactivateCheckBox.setChecked(details["autoactivate"]) self.activeCheckBox.setChecked(details["active"]) @pyqtSlot() def on_activeCheckBox_clicked(self): """ Private slot called, when the activeCheckBox was clicked. """ self.activeCheckBox.setChecked(self.__active) @pyqtSlot() def on_autoactivateCheckBox_clicked(self): """ Private slot called, when the autoactivateCheckBox was clicked. """ self.autoactivateCheckBox.setChecked(self.__autoactivate) eric-6.0.8/eric/PluginManager/PluginInfoDialog.ui0000644000175000017500000000610312060166053020726 0ustar piotrpiotr PluginInfoDialog 0 0 800 600 Loaded Plugins true Double-Click an entry to show detailed info. Plugins with an error are shown in red. true <b>Plugin List</b><p>This lists all loaded plugins. Double-clicking an entry shows more detailed information in a separate dialog.</p> false false true true Module Name Version Autoactivate Active Description Qt::Horizontal QDialogButtonBox::Close pluginList buttonBox buttonBox accepted() PluginInfoDialog accept() 308 454 157 274 buttonBox rejected() PluginInfoDialog reject() 376 460 286 274 eric-6.0.8/eric/PluginManager/PluginInfoDialog.py0000644000175000017500000001212012537064320020740 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Plugin Info Dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtGui import QBrush from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QHeaderView, QMenu from .Ui_PluginInfoDialog import Ui_PluginInfoDialog class PluginInfoDialog(QDialog, Ui_PluginInfoDialog): """ Class implementing the Plugin Info Dialog. """ def __init__(self, pluginManager, parent=None): """ Constructor @param pluginManager reference to the plugin manager object @param parent parent of this dialog (QWidget) """ super(PluginInfoDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.pm = pluginManager self.__autoActivateColumn = 3 self.__activeColumn = 4 self.pluginList.headerItem().setText(self.pluginList.columnCount(), "") # populate the list self.__populateList() self.pluginList.sortByColumn(0, Qt.AscendingOrder) self.__menu = QMenu(self) self.__menu.addAction(self.tr('Show details'), self.__showDetails) self.__activateAct = self.__menu.addAction( self.tr('Activate'), self.__activatePlugin) self.__deactivateAct = self.__menu.addAction( self.tr('Deactivate'), self.__deactivatePlugin) self.pluginList.setContextMenuPolicy(Qt.CustomContextMenu) self.pluginList.customContextMenuRequested.connect( self.__showContextMenu) def __populateList(self): """ Private method to (re)populate the list of plugins. """ self.pluginList.clear() for info in self.pm.getPluginInfos(): self.__createEntry(info) self.pluginList.sortItems( self.pluginList.sortColumn(), self.pluginList.header().sortIndicatorOrder()) def __createEntry(self, info): """ Private method to create a list entry based on the provided info. @param info tuple giving the info for the entry """ infoList = [ info[0], info[1], info[2], (info[3] and self.tr("Yes") or self.tr("No")), (info[4] and self.tr("Yes") or self.tr("No")), info[5] ] itm = QTreeWidgetItem(self.pluginList, infoList) if info[6]: # plugin error for col in range(self.pluginList.columnCount()): itm.setForeground(col, QBrush(Qt.red)) itm.setTextAlignment(self.__autoActivateColumn, Qt.AlignHCenter) itm.setTextAlignment(self.__activeColumn, Qt.AlignHCenter) self.pluginList.header().resizeSections(QHeaderView.ResizeToContents) self.pluginList.header().setStretchLastSection(True) def __showContextMenu(self, coord): """ Private slot to show the context menu of the listview. @param coord the position of the mouse pointer (QPoint) """ itm = self.pluginList.itemAt(coord) if itm is not None: autoactivate = (itm.text(self.__autoActivateColumn) == self.tr("Yes")) if itm.text(self.__activeColumn) == self.tr("Yes"): self.__activateAct.setEnabled(False) self.__deactivateAct.setEnabled(autoactivate) else: self.__activateAct.setEnabled(autoactivate) self.__deactivateAct.setEnabled(False) self.__menu.popup(self.mapToGlobal(coord)) @pyqtSlot(QTreeWidgetItem, int) def on_pluginList_itemActivated(self, item, column): """ Private slot to show details about a plugin. @param item reference to the selected item (QTreeWidgetItem) @param column column number (integer) """ moduleName = item.text(0) details = self.pm.getPluginDetails(moduleName) if details is None: pass else: from .PluginDetailsDialog import PluginDetailsDialog dlg = PluginDetailsDialog(details, self) dlg.show() def __showDetails(self): """ Private slot to handle the "Show details" context menu action. """ itm = self.pluginList.currentItem() self.on_pluginList_itemActivated(itm, 0) def __activatePlugin(self): """ Private slot to handle the "Deactivate" context menu action. """ itm = self.pluginList.currentItem() moduleName = itm.text(0) self.pm.activatePlugin(moduleName) # repopulate the list self.__populateList() def __deactivatePlugin(self): """ Private slot to handle the "Activate" context menu action. """ itm = self.pluginList.currentItem() moduleName = itm.text(0) self.pm.deactivatePlugin(moduleName) # repopulate the list self.__populateList() eric-6.0.8/eric/PluginManager/PluginUninstallDialog.ui0000644000175000017500000000313512310372720022004 0ustar piotrpiotr PluginUninstallDialog 0 0 400 131 Plugin Uninstallation Plugin directory: Select the plugin area containing the plugin to uninstall Plugin: Select the plugin to uninstall Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok pluginDirectoryCombo pluginNameCombo buttonBox eric-6.0.8/eric/PluginManager/PluginRepositoryDialog.ui0000644000175000017500000001370012264525224022220 0ustar piotrpiotr PluginRepositoryDialog 0 0 800 675 Plugin Repository true 0 7 Qt::CustomContextMenu QAbstractItemView::ExtendedSelection false false true true Name Version Short Description Description: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 3 Qt::NoFocus Displays the description of the selected plugin true Author: Qt::NoFocus Displays the author of the selected plugin true URL: Qt::NoFocus Displays the download URL of the selected plugin true Qt::Horizontal Shows the progress of the current download 0 Repository URL: Shows the repository URL true Press to edit the plugin repository URL Edit URL true Qt::Horizontal QDialogButtonBox::Close repositoryList buttonBox repositoryUrlEdit repositoryUrlEditButton eric-6.0.8/eric/PluginManager/PluginManager.py0000644000175000017500000014206212451233374020312 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Plugin Manager. """ from __future__ import unicode_literals, print_function import os import sys import imp import zipfile from PyQt5.QtCore import pyqtSignal, QObject, QDate, QFile, QFileInfo, QUrl, \ QIODevice from PyQt5.QtGui import QPixmap from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, \ QNetworkReply from E5Gui import E5MessageBox from E5Network.E5NetworkProxyFactory import proxyAuthenticationRequired try: from E5Network.E5SslErrorHandler import E5SslErrorHandler SSL_AVAILABLE = True except ImportError: SSL_AVAILABLE = False from .PluginExceptions import PluginPathError, PluginModulesError, \ PluginLoadError, PluginActivationError, PluginModuleFormatError, \ PluginClassFormatError, PluginPy2IncompatibleError import UI.PixmapCache import Utilities import Preferences from eric6config import getConfig class PluginManager(QObject): """ Class implementing the Plugin Manager. @signal shutdown() emitted at shutdown of the IDE @signal pluginAboutToBeActivated(modulName, pluginObject) emitted just before a plugin is activated @signal pluginActivated(moduleName, pluginObject) emitted just after a plugin was activated @signal allPlugginsActivated() emitted at startup after all plugins have been activated @signal pluginAboutToBeDeactivated(moduleName, pluginObject) emitted just before a plugin is deactivated @signal pluginDeactivated(moduleName, pluginObject) emitted just after a plugin was deactivated """ shutdown = pyqtSignal() pluginAboutToBeActivated = pyqtSignal(str, object) pluginActivated = pyqtSignal(str, object) allPlugginsActivated = pyqtSignal() pluginAboutToBeDeactivated = pyqtSignal(str, object) pluginDeactivated = pyqtSignal(str, object) def __init__(self, parent=None, doLoadPlugins=True, develPlugin=None): """ Constructor The Plugin Manager deals with three different plugin directories. The first is the one, that is part of eric6 (eric6/Plugins). The second one is the global plugin directory called 'eric6plugins', which is located inside the site-packages directory. The last one is the user plugin directory located inside the .eric6 directory of the users home directory. @param parent reference to the parent object (QObject) @keyparam doLoadPlugins flag indicating, that plugins should be loaded (boolean) @keyparam develPlugin filename of a plugin to be loaded for development (string) @exception PluginPathError raised to indicate an invalid plug-in path """ super(PluginManager, self).__init__(parent) self.__ui = parent self.__develPluginFile = develPlugin self.__develPluginName = None self.__inactivePluginsKey = "PluginManager/InactivePlugins" self.pluginDirs = { "eric6": os.path.join(getConfig('ericDir'), "Plugins"), "global": os.path.join(Utilities.getPythonModulesDirectory(), "eric6plugins"), "user": os.path.join(Utilities.getConfigDir(), "eric6plugins"), } self.__priorityOrder = ["eric6", "global", "user"] self.__defaultDownloadDir = os.path.join( Utilities.getConfigDir(), "Downloads") self.__activePlugins = {} self.__inactivePlugins = {} self.__onDemandActivePlugins = {} self.__onDemandInactivePlugins = {} self.__activeModules = {} self.__inactiveModules = {} self.__onDemandActiveModules = {} self.__onDemandInactiveModules = {} self.__failedModules = {} self.__foundCoreModules = [] self.__foundGlobalModules = [] self.__foundUserModules = [] self.__modulesCount = 0 pdirsExist, msg = self.__pluginDirectoriesExist() if not pdirsExist: raise PluginPathError(msg) if doLoadPlugins: if not self.__pluginModulesExist(): raise PluginModulesError self.__insertPluginsPaths() self.__loadPlugins() self.__checkPluginsDownloadDirectory() self.pluginRepositoryFile = \ os.path.join(Utilities.getConfigDir(), "PluginRepository") # attributes for the network objects self.__networkManager = QNetworkAccessManager(self) self.__networkManager.proxyAuthenticationRequired.connect( proxyAuthenticationRequired) if SSL_AVAILABLE: self.__sslErrorHandler = E5SslErrorHandler(self) self.__networkManager.sslErrors.connect(self.__sslErrors) self.__replies = [] def finalizeSetup(self): """ Public method to finalize the setup of the plugin manager. """ for module in list(self.__onDemandInactiveModules.values()) + \ list(self.__onDemandActiveModules.values()): if hasattr(module, "moduleSetup"): module.moduleSetup() def getPluginDir(self, key): """ Public method to get the path of a plugin directory. @param key key of the plug-in directory (string) @return path of the requested plugin directory (string) """ if key not in ["global", "user"]: return None else: try: return self.pluginDirs[key] except KeyError: return None def __pluginDirectoriesExist(self): """ Private method to check, if the plugin folders exist. If the plugin folders don't exist, they are created (if possible). @return tuple of a flag indicating existence of any of the plugin directories (boolean) and a message (string) """ if self.__develPluginFile: path = Utilities.splitPath(self.__develPluginFile)[0] fname = os.path.join(path, "__init__.py") if not os.path.exists(fname): try: f = open(fname, "w") f.close() except IOError: return ( False, self.tr("Could not create a package for {0}.") .format(self.__develPluginFile)) if Preferences.getPluginManager("ActivateExternal"): fname = os.path.join(self.pluginDirs["user"], "__init__.py") if not os.path.exists(fname): if not os.path.exists(self.pluginDirs["user"]): os.mkdir(self.pluginDirs["user"], 0o755) try: f = open(fname, "w") f.close() except IOError: del self.pluginDirs["user"] if not os.path.exists(self.pluginDirs["global"]) and \ os.access(Utilities.getPythonModulesDirectory(), os.W_OK): # create the global plugins directory os.mkdir(self.pluginDirs["global"], 0o755) fname = os.path.join(self.pluginDirs["global"], "__init__.py") f = open(fname, "w", encoding="utf-8") f.write('# -*- coding: utf-8 -*-' + "\n") f.write("\n") f.write('"""' + "\n") f.write('Package containing the global plugins.' + "\n") f.write('"""' + "\n") f.close() if not os.path.exists(self.pluginDirs["global"]): del self.pluginDirs["global"] else: del self.pluginDirs["user"] del self.pluginDirs["global"] if not os.path.exists(self.pluginDirs["eric6"]): return ( False, self.tr( "The internal plugin directory {0}" " does not exits.").format(self.pluginDirs["eric6"])) return (True, "") def __pluginModulesExist(self): """ Private method to check, if there are plugins available. @return flag indicating the availability of plugins (boolean) """ if self.__develPluginFile and \ not os.path.exists(self.__develPluginFile): return False self.__foundCoreModules = self.getPluginModules( self.pluginDirs["eric6"]) if "global" in self.pluginDirs: self.__foundGlobalModules = \ self.getPluginModules(self.pluginDirs["global"]) if "user" in self.pluginDirs: self.__foundUserModules = \ self.getPluginModules(self.pluginDirs["user"]) return len(self.__foundCoreModules + self.__foundGlobalModules + self.__foundUserModules) > 0 def getPluginModules(self, pluginPath): """ Public method to get a list of plugin modules. @param pluginPath name of the path to search (string) @return list of plugin module names (list of string) """ pluginFiles = [f[:-3] for f in os.listdir(pluginPath) if self.isValidPluginName(f)] return pluginFiles[:] def isValidPluginName(self, pluginName): """ Public methode to check, if a file name is a valid plugin name. Plugin modules must start with "Plugin" and have the extension ".py". @param pluginName name of the file to be checked (string) @return flag indicating a valid plugin name (boolean) """ return pluginName.startswith("Plugin") and pluginName.endswith(".py") def __insertPluginsPaths(self): """ Private method to insert the valid plugin paths intos the search path. """ for key in self.__priorityOrder: if key in self.pluginDirs: if not self.pluginDirs[key] in sys.path: sys.path.insert(2, self.pluginDirs[key]) UI.PixmapCache.addSearchPath(self.pluginDirs[key]) if self.__develPluginFile: path = Utilities.splitPath(self.__develPluginFile)[0] if path not in sys.path: sys.path.insert(2, path) UI.PixmapCache.addSearchPath(path) def __loadPlugins(self): """ Private method to load the plugins found. """ develPluginName = "" if self.__develPluginFile: develPluginPath, develPluginName = \ Utilities.splitPath(self.__develPluginFile) if self.isValidPluginName(develPluginName): develPluginName = develPluginName[:-3] for pluginName in self.__foundCoreModules: # global and user plugins have priority if pluginName not in self.__foundGlobalModules and \ pluginName not in self.__foundUserModules and \ pluginName != develPluginName: self.loadPlugin(pluginName, self.pluginDirs["eric6"]) for pluginName in self.__foundGlobalModules: # user plugins have priority if pluginName not in self.__foundUserModules and \ pluginName != develPluginName: self.loadPlugin(pluginName, self.pluginDirs["global"]) for pluginName in self.__foundUserModules: if pluginName != develPluginName: self.loadPlugin(pluginName, self.pluginDirs["user"]) if develPluginName: self.loadPlugin(develPluginName, develPluginPath) self.__develPluginName = develPluginName def loadPlugin(self, name, directory, reload_=False): """ Public method to load a plugin module. Initially all modules are inactive. Modules that are requested on demand are sorted out and are added to the on demand list. Some basic validity checks are performed as well. Modules failing these checks are added to the failed modules list. @param name name of the module to be loaded (string) @param directory name of the plugin directory (string) @param reload_ flag indicating to reload the module (boolean) @exception PluginLoadError raised to indicate an issue loading the plug-in """ try: fname = "{0}.py".format(os.path.join(directory, name)) module = imp.load_source(name, fname) if not hasattr(module, "autoactivate"): module.error = self.tr( "Module is missing the 'autoactivate' attribute.") self.__failedModules[name] = module raise PluginLoadError(name) if sys.version_info[0] < 3: if not hasattr(module, "python2Compatible"): module.error = self.tr( "Module is missing the Python2 compatibility flag." " Please update.") compatible = False elif not getattr(module, "python2Compatible"): module.error = self.tr( "Module is not Python2 compatible.") compatible = False else: compatible = True if not compatible: self.__failedModules[name] = module raise PluginPy2IncompatibleError(name) if getattr(module, "autoactivate"): self.__inactiveModules[name] = module else: if not hasattr(module, "pluginType") or \ not hasattr(module, "pluginTypename"): module.error = \ self.tr("Module is missing the 'pluginType' " "and/or 'pluginTypename' attributes.") self.__failedModules[name] = module raise PluginLoadError(name) else: self.__onDemandInactiveModules[name] = module module.eric6PluginModuleName = name module.eric6PluginModuleFilename = fname self.__modulesCount += 1 if reload_: imp.reload(module) except PluginLoadError: print("Error loading plug-in module:", name) except PluginPy2IncompatibleError: print("Error loading plug-in module:", name) print("The plug-in is not Python2 compatible.") except Exception as err: module = imp.new_module(name) module.error = self.tr( "Module failed to load. Error: {0}").format(str(err)) self.__failedModules[name] = module print("Error loading plug-in module:", name) print(str(err)) def unloadPlugin(self, name): """ Public method to unload a plugin module. @param name name of the module to be unloaded (string) @return flag indicating success (boolean) """ if name in self.__onDemandActiveModules: # cannot unload an ondemand plugin, that is in use return False if name in self.__activeModules: self.deactivatePlugin(name) if name in self.__inactiveModules: try: del self.__inactivePlugins[name] except KeyError: pass del self.__inactiveModules[name] elif name in self.__onDemandInactiveModules: try: del self.__onDemandInactivePlugins[name] except KeyError: pass del self.__onDemandInactiveModules[name] elif name in self.__failedModules: del self.__failedModules[name] self.__modulesCount -= 1 return True def removePluginFromSysModules(self, pluginName, package, internalPackages): """ Public method to remove a plugin and all related modules from sys.modules. @param pluginName name of the plugin module (string) @param package name of the plugin package (string) @param internalPackages list of intenal packages (list of string) @return flag indicating the plugin module was found in sys.modules (boolean) """ packages = [package] + internalPackages found = False if not package: package = "__None__" for moduleName in list(sys.modules.keys())[:]: if moduleName == pluginName or \ moduleName.split(".")[0] in packages: found = True del sys.modules[moduleName] return found def initOnDemandPlugins(self): """ Public method to create plugin objects for all on demand plugins. Note: The plugins are not activated. """ names = sorted(self.__onDemandInactiveModules.keys()) for name in names: self.initOnDemandPlugin(name) def initOnDemandPlugin(self, name): """ Public method to create a plugin object for the named on demand plugin. Note: The plug-in is not activated. @param name name of the plug-in (string) @exception PluginActivationError raised to indicate an issue during the plug-in activation """ try: try: module = self.__onDemandInactiveModules[name] except KeyError: return if not self.__canActivatePlugin(module): raise PluginActivationError(module.eric6PluginModuleName) version = getattr(module, "version") className = getattr(module, "className") pluginClass = getattr(module, className) pluginObject = None if name not in self.__onDemandInactivePlugins: pluginObject = pluginClass(self.__ui) pluginObject.eric6PluginModule = module pluginObject.eric6PluginName = className pluginObject.eric6PluginVersion = version self.__onDemandInactivePlugins[name] = pluginObject except PluginActivationError: return def activatePlugins(self): """ Public method to activate all plugins having the "autoactivate" attribute set to True. """ savedInactiveList = Preferences.Prefs.settings.value( self.__inactivePluginsKey) if self.__develPluginName is not None and \ savedInactiveList is not None and \ self.__develPluginName in savedInactiveList: savedInactiveList.remove(self.__develPluginName) names = sorted(self.__inactiveModules.keys()) for name in names: if savedInactiveList is None or name not in savedInactiveList: self.activatePlugin(name) self.allPlugginsActivated.emit() def activatePlugin(self, name, onDemand=False): """ Public method to activate a plugin. @param name name of the module to be activated @keyparam onDemand flag indicating activation of an on demand plugin (boolean) @return reference to the initialized plugin object @exception PluginActivationError raised to indicate an issue during the plug-in activation """ try: try: if onDemand: module = self.__onDemandInactiveModules[name] else: module = self.__inactiveModules[name] except KeyError: return None if not self.__canActivatePlugin(module): raise PluginActivationError(module.eric6PluginModuleName) version = getattr(module, "version") className = getattr(module, "className") pluginClass = getattr(module, className) pluginObject = None if onDemand and name in self.__onDemandInactivePlugins: pluginObject = self.__onDemandInactivePlugins[name] elif not onDemand and name in self.__inactivePlugins: pluginObject = self.__inactivePlugins[name] else: pluginObject = pluginClass(self.__ui) self.pluginAboutToBeActivated.emit(name, pluginObject) try: obj, ok = pluginObject.activate() except TypeError: module.error = self.tr( "Incompatible plugin activation method.") obj = None ok = True except Exception as err: module.error = str(err) obj = None ok = False if not ok: return None self.pluginActivated.emit(name, pluginObject) pluginObject.eric6PluginModule = module pluginObject.eric6PluginName = className pluginObject.eric6PluginVersion = version if onDemand: self.__onDemandInactiveModules.pop(name) try: self.__onDemandInactivePlugins.pop(name) except KeyError: pass self.__onDemandActivePlugins[name] = pluginObject self.__onDemandActiveModules[name] = module else: self.__inactiveModules.pop(name) try: self.__inactivePlugins.pop(name) except KeyError: pass self.__activePlugins[name] = pluginObject self.__activeModules[name] = module return obj except PluginActivationError: return None def __canActivatePlugin(self, module): """ Private method to check, if a plugin can be activated. @param module reference to the module to be activated @return flag indicating, if the module satisfies all requirements for being activated (boolean) @exception PluginModuleFormatError raised to indicate an invalid plug-in module format @exception PluginClassFormatError raised to indicate an invalid plug-in class format """ try: if not hasattr(module, "version"): raise PluginModuleFormatError( module.eric6PluginModuleName, "version") if not hasattr(module, "className"): raise PluginModuleFormatError( module.eric6PluginModuleName, "className") className = getattr(module, "className") if not hasattr(module, className): raise PluginModuleFormatError( module.eric6PluginModuleName, className) pluginClass = getattr(module, className) if not hasattr(pluginClass, "__init__"): raise PluginClassFormatError( module.eric6PluginModuleName, className, "__init__") if not hasattr(pluginClass, "activate"): raise PluginClassFormatError( module.eric6PluginModuleName, className, "activate") if not hasattr(pluginClass, "deactivate"): raise PluginClassFormatError( module.eric6PluginModuleName, className, "deactivate") return True except PluginModuleFormatError as e: print(repr(e)) return False except PluginClassFormatError as e: print(repr(e)) return False def deactivatePlugin(self, name, onDemand=False): """ Public method to deactivate a plugin. @param name name of the module to be deactivated @keyparam onDemand flag indicating deactivation of an on demand plugin (boolean) """ try: if onDemand: module = self.__onDemandActiveModules[name] else: module = self.__activeModules[name] except KeyError: return if self.__canDeactivatePlugin(module): pluginObject = None if onDemand and name in self.__onDemandActivePlugins: pluginObject = self.__onDemandActivePlugins[name] elif not onDemand and name in self.__activePlugins: pluginObject = self.__activePlugins[name] if pluginObject: self.pluginAboutToBeDeactivated.emit(name, pluginObject) pluginObject.deactivate() self.pluginDeactivated.emit(name, pluginObject) if onDemand: self.__onDemandActiveModules.pop(name) self.__onDemandActivePlugins.pop(name) self.__onDemandInactivePlugins[name] = pluginObject self.__onDemandInactiveModules[name] = module else: self.__activeModules.pop(name) try: self.__activePlugins.pop(name) except KeyError: pass self.__inactivePlugins[name] = pluginObject self.__inactiveModules[name] = module def __canDeactivatePlugin(self, module): """ Private method to check, if a plugin can be deactivated. @param module reference to the module to be deactivated @return flag indicating, if the module satisfies all requirements for being deactivated (boolean) """ return getattr(module, "deactivateable", True) def getPluginObject(self, type_, typename, maybeActive=False): """ Public method to activate an ondemand plugin given by type and typename. @param type_ type of the plugin to be activated (string) @param typename name of the plugin within the type category (string) @keyparam maybeActive flag indicating, that the plugin may be active already (boolean) @return reference to the initialized plugin object """ for name, module in list(self.__onDemandInactiveModules.items()): if getattr(module, "pluginType") == type_ and \ getattr(module, "pluginTypename") == typename: return self.activatePlugin(name, onDemand=True) if maybeActive: for name, module in list(self.__onDemandActiveModules.items()): if getattr(module, "pluginType") == type_ and \ getattr(module, "pluginTypename") == typename: self.deactivatePlugin(name, onDemand=True) return self.activatePlugin(name, onDemand=True) return None def getPluginInfos(self): """ Public method to get infos about all loaded plugins. @return list of tuples giving module name (string), plugin name (string), version (string), autoactivate (boolean), active (boolean), short description (string), error flag (boolean) """ infos = [] for name in list(self.__activeModules.keys()): pname, shortDesc, error, version = \ self.__getShortInfo(self.__activeModules[name]) infos.append((name, pname, version, True, True, shortDesc, error)) for name in list(self.__inactiveModules.keys()): pname, shortDesc, error, version = \ self.__getShortInfo(self.__inactiveModules[name]) infos.append( (name, pname, version, True, False, shortDesc, error)) for name in list(self.__onDemandActiveModules.keys()): pname, shortDesc, error, version = \ self.__getShortInfo(self.__onDemandActiveModules[name]) infos.append( (name, pname, version, False, True, shortDesc, error)) for name in list(self.__onDemandInactiveModules.keys()): pname, shortDesc, error, version = \ self.__getShortInfo(self.__onDemandInactiveModules[name]) infos.append( (name, pname, version, False, False, shortDesc, error)) for name in list(self.__failedModules.keys()): pname, shortDesc, error, version = \ self.__getShortInfo(self.__failedModules[name]) infos.append( (name, pname, version, False, False, shortDesc, error)) return infos def __getShortInfo(self, module): """ Private method to extract the short info from a module. @param module module to extract short info from @return short info as a tuple giving plugin name (string), short description (string), error flag (boolean) and version (string) """ name = getattr(module, "name", "") shortDesc = getattr(module, "shortDescription", "") version = getattr(module, "version", "") error = getattr(module, "error", "") != "" return name, shortDesc, error, version def getPluginDetails(self, name): """ Public method to get detailed information about a plugin. @param name name of the module to get detailed infos about (string) @return details of the plugin as a dictionary """ details = {} autoactivate = True active = True if name in self.__activeModules: module = self.__activeModules[name] elif name in self.__inactiveModules: module = self.__inactiveModules[name] active = False elif name in self.__onDemandActiveModules: module = self.__onDemandActiveModules[name] autoactivate = False elif name in self.__onDemandInactiveModules: module = self.__onDemandInactiveModules[name] autoactivate = False active = False elif name in self.__failedModules: module = self.__failedModules[name] autoactivate = False active = False else: # should not happen return None details["moduleName"] = name details["moduleFileName"] = getattr( module, "eric6PluginModuleFilename", "") details["pluginName"] = getattr(module, "name", "") details["version"] = getattr(module, "version", "") details["author"] = getattr(module, "author", "") details["description"] = getattr(module, "longDescription", "") details["autoactivate"] = autoactivate details["active"] = active details["error"] = getattr(module, "error", "") return details def doShutdown(self): """ Public method called to perform actions upon shutdown of the IDE. """ names = [] for name in list(self.__inactiveModules.keys()): names.append(name) Preferences.Prefs.settings.setValue(self.__inactivePluginsKey, names) self.shutdown.emit() def getPluginDisplayStrings(self, type_): """ Public method to get the display strings of all plugins of a specific type. @param type_ type of the plugins (string) @return dictionary with name as key and display string as value (dictionary of string) """ pluginDict = {} for name, module in \ list(self.__onDemandActiveModules.items()) + \ list(self.__onDemandInactiveModules.items()): if getattr(module, "pluginType") == type_ and \ getattr(module, "error", "") == "": plugin_name = getattr(module, "pluginTypename") if hasattr(module, "displayString"): try: disp = module.displayString() except TypeError: disp = getattr(module, "displayString") if disp != "": pluginDict[plugin_name] = disp else: pluginDict[plugin_name] = plugin_name return pluginDict def getPluginPreviewPixmap(self, type_, name): """ Public method to get a preview pixmap of a plugin of a specific type. @param type_ type of the plugin (string) @param name name of the plugin type (string) @return preview pixmap (QPixmap) """ for modname, module in \ list(self.__onDemandActiveModules.items()) + \ list(self.__onDemandInactiveModules.items()): if getattr(module, "pluginType") == type_ and \ getattr(module, "pluginTypename") == name: if hasattr(module, "previewPix"): return module.previewPix() else: return QPixmap() return QPixmap() def getPluginApiFiles(self, language): """ Public method to get the list of API files installed by a plugin. @param language language of the requested API files (string) @return list of API filenames (list of string) """ apis = [] for module in list(self.__activeModules.values()) + \ list(self.__onDemandActiveModules.values()): if hasattr(module, "apiFiles"): apis.extend(module.apiFiles(language)) return apis def getPluginExeDisplayData(self): """ Public method to get data to display information about a plugins external tool. @return list of dictionaries containing the data. Each dictionary must either contain data for the determination or the data to be displayed.
    A dictionary of the first form must have the following entries:
    • programEntry - indicator for this dictionary form (boolean), always True
    • header - string to be diplayed as a header (string)
    • exe - the executable (string)
    • versionCommand - commandline parameter for the exe (string)
    • versionStartsWith - indicator for the output line containing the version (string)
    • versionPosition - number of element containing the version (integer)
    • version - version to be used as default (string)
    • versionCleanup - tuple of two integers giving string positions start and stop for the version string (tuple of integers)
    A dictionary of the second form must have the following entries:
    • programEntry - indicator for this dictionary form (boolean), always False
    • header - string to be diplayed as a header (string)
    • text - entry text to be shown (string)
    • version - version text to be shown (string)
    """ infos = [] for module in list(self.__activeModules.values()) + \ list(self.__inactiveModules.values()): if hasattr(module, "exeDisplayDataList"): infos.extend(module.exeDisplayDataList()) elif hasattr(module, "exeDisplayData"): infos.append(module.exeDisplayData()) for module in list(self.__onDemandActiveModules.values()) + \ list(self.__onDemandInactiveModules.values()): if hasattr(module, "exeDisplayDataList"): infos.extend(module.exeDisplayDataList()) elif hasattr(module, "exeDisplayData"): infos.append(module.exeDisplayData()) return infos def getPluginConfigData(self): """ Public method to get the config data of all active, non on-demand plugins used by the configuration dialog. Plugins supporting this functionality must provide the plugin module function 'getConfigData' returning a dictionary with unique keys of lists with the following list contents:
    display string
    string shown in the selection area of the configuration page. This should be a localized string
    pixmap name
    filename of the pixmap to be shown next to the display string
    page creation function
    plugin module function to be called to create the configuration page. The page must be subclasses from Preferences.ConfigurationPages.ConfigurationPageBase and must implement a method called 'save' to save the settings. A parent entry will be created in the selection list, if this value is None.
    parent key
    dictionary key of the parent entry or None, if this defines a toplevel entry.
    reference to configuration page
    This will be used by the configuration dialog and must always be None
    @return plug-in configuration data """ configData = {} for module in list(self.__activeModules.values()) + \ list(self.__onDemandActiveModules.values()) + \ list(self.__onDemandInactiveModules.values()): if hasattr(module, 'getConfigData'): configData.update(module.getConfigData()) return configData def isPluginLoaded(self, pluginName): """ Public method to check, if a certain plugin is loaded. @param pluginName name of the plugin to check for (string) @return flag indicating, if the plugin is loaded (boolean) """ return pluginName in self.__activeModules or \ pluginName in self.__inactiveModules or \ pluginName in self.__onDemandActiveModules or \ pluginName in self.__onDemandInactiveModules def isPluginActive(self, pluginName): """ Public method to check, if a certain plugin is active. @param pluginName name of the plugin to check for (string) @return flag indicating, if the plugin is active (boolean) """ return pluginName in self.__activeModules or \ pluginName in self.__onDemandActiveModules ########################################################################### ## Specialized plugin module handling methods below ########################################################################### ########################################################################### ## VCS related methods below ########################################################################### def getVcsSystemIndicators(self): """ Public method to get the Vcs System indicators. Plugins supporting this functionality must support the module function getVcsSystemIndicator returning a dictionary with indicator as key and a tuple with the vcs name (string) and vcs display string (string). @return dictionary with indicator as key and a list of tuples as values. Each tuple contains the vcs name (string) and vcs display string (string). """ vcsDict = {} for name, module in \ list(self.__onDemandActiveModules.items()) + \ list(self.__onDemandInactiveModules.items()): if getattr(module, "pluginType") == "version_control": if hasattr(module, "getVcsSystemIndicator"): res = module.getVcsSystemIndicator() for indicator, vcsData in list(res.items()): if indicator in vcsDict: vcsDict[indicator].append(vcsData) else: vcsDict[indicator] = [vcsData] return vcsDict def deactivateVcsPlugins(self): """ Public method to deactivated all activated VCS plugins. """ for name, module in list(self.__onDemandActiveModules.items()): if getattr(module, "pluginType") == "version_control": self.deactivatePlugin(name, True) ######################################################################## ## Methods creation of the plug-ins download directory ######################################################################## def __checkPluginsDownloadDirectory(self): """ Private slot to check for the existence of the plugins download directory. """ downloadDir = Preferences.getPluginManager("DownloadPath") if not downloadDir: downloadDir = self.__defaultDownloadDir if not os.path.exists(downloadDir): try: os.mkdir(downloadDir, 0o755) except (OSError, IOError) as err: # try again with (possibly) new default downloadDir = self.__defaultDownloadDir if not os.path.exists(downloadDir): try: os.mkdir(downloadDir, 0o755) except (OSError, IOError) as err: E5MessageBox.critical( self.__ui, self.tr("Plugin Manager Error"), self.tr( """

    The plugin download directory""" """ {0} could not be created. Please""" """ configure it via the configuration""" """ dialog.

    Reason: {1}

    """) .format(downloadDir, str(err))) downloadDir = "" Preferences.setPluginManager("DownloadPath", downloadDir) def preferencesChanged(self): """ Public slot to react to changes in configuration. """ self.__checkPluginsDownloadDirectory() ######################################################################## ## Methods for automatic plug-in update check below ######################################################################## def checkPluginUpdatesAvailable(self): """ Public method to check the availability of updates of plug-ins. """ period = Preferences.getPluginManager("UpdatesCheckInterval") if period == 0: return elif period in [1, 2, 3]: lastModified = QFileInfo(self.pluginRepositoryFile).lastModified() if lastModified.isValid() and lastModified.date().isValid(): lastModifiedDate = lastModified.date() now = QDate.currentDate() if period == 1 and lastModifiedDate.day() == now.day(): # daily return elif period == 2 and lastModifiedDate.daysTo(now) < 7: # weekly return elif period == 3 and \ (lastModifiedDate.daysTo(now) < lastModifiedDate.daysInMonth()): # monthly return self.__updateAvailable = False request = QNetworkRequest( QUrl(Preferences.getUI("PluginRepositoryUrl6"))) request.setAttribute(QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) reply = self.__networkManager.get(request) reply.finished.connect(self.__downloadRepositoryFileDone) self.__replies.append(reply) def __downloadRepositoryFileDone(self): """ Private method called after the repository file was downloaded. """ reply = self.sender() if reply in self.__replies: self.__replies.remove(reply) if reply.error() != QNetworkReply.NoError: E5MessageBox.warning( None, self.tr("Error downloading file"), self.tr( """

    Could not download the requested file""" """ from {0}.

    Error: {1}

    """ ).format(Preferences.getUI("PluginRepositoryUrl6"), reply.errorString()) ) return ioDevice = QFile(self.pluginRepositoryFile + ".tmp") ioDevice.open(QIODevice.WriteOnly) ioDevice.write(reply.readAll()) ioDevice.close() if QFile.exists(self.pluginRepositoryFile): QFile.remove(self.pluginRepositoryFile) ioDevice.rename(self.pluginRepositoryFile) if os.path.exists(self.pluginRepositoryFile): f = QFile(self.pluginRepositoryFile) if f.open(QIODevice.ReadOnly): # save current URL url = Preferences.getUI("PluginRepositoryUrl6") # read the repository file from E5XML.PluginRepositoryReader import PluginRepositoryReader reader = PluginRepositoryReader(f, self.checkPluginEntry) reader.readXML() if url != Preferences.getUI("PluginRepositoryUrl6"): # redo if it is a redirect self.checkPluginUpdatesAvailable() return if self.__updateAvailable: res = E5MessageBox.information( None, self.tr("New plugin versions available"), self.tr("

    There are new plug-ins or plug-in" " updates available. Use the plug-in" " repository dialog to get them.

    "), E5MessageBox.StandardButtons( E5MessageBox.Ignore | E5MessageBox.Open), E5MessageBox.Open) if res == E5MessageBox.Open: self.__ui.showPluginsAvailable() def checkPluginEntry(self, name, short, description, url, author, version, filename, status): """ Public method to check a plug-in's data for an update. @param name data for the name field (string) @param short data for the short field (string) @param description data for the description field (list of strings) @param url data for the url field (string) @param author data for the author field (string) @param version data for the version field (string) @param filename data for the filename field (string) @param status status of the plugin (string [stable, unstable, unknown]) """ # ignore hidden plug-ins pluginName = os.path.splitext(url.rsplit("/", 1)[1])[0] if pluginName in Preferences.getPluginManager("HiddenPlugins"): return archive = os.path.join(Preferences.getPluginManager("DownloadPath"), filename) # Check against installed/loaded plug-ins pluginDetails = self.getPluginDetails(pluginName) if pluginDetails is None: if not Preferences.getPluginManager("CheckInstalledOnly"): self.__updateAvailable = True return if pluginDetails["version"] < version: self.__updateAvailable = True return if not Preferences.getPluginManager("CheckInstalledOnly"): # Check against downloaded plugin archives # 1. Check, if the archive file exists if not os.path.exists(archive): self.__updateAvailable = True return # 2. Check, if the archive is a valid zip file if not zipfile.is_zipfile(archive): self.__updateAvailable = True return # 3. Check the version of the archive file zip = zipfile.ZipFile(archive, "r") try: aversion = zip.read("VERSION").decode("utf-8") except KeyError: aversion = "" zip.close() if aversion != version: self.__updateAvailable = True def __sslErrors(self, reply, errors): """ Private slot to handle SSL errors. @param reply reference to the reply object (QNetworkReply) @param errors list of SSL errors (list of QSslError) """ ignored = self.__sslErrorHandler.sslErrorsReply(reply, errors)[0] if ignored == E5SslErrorHandler.NotIgnored: self.__downloadCancelled = True eric-6.0.8/eric/PluginManager/__init__.py0000644000175000017500000000026212451233374017313 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Package containing the code for the Plugin Manager and related parts. """ eric-6.0.8/eric/PluginManager/PluginInstallDialog.ui0000644000175000017500000001224612240214201021433 0ustar piotrpiotr PluginInstallDialog 0 0 611 362 Plugin Installation 2 6 0 <b>Enter the plugin archives to install</b> true QAbstractItemView::ExtendedSelection true Add plugin ZIP-archives via a file selection dialog Add ... false Remove the selected entries from the list of plugin archives to be installed Remove Qt::Vertical 20 101 0 <b>Select the destination plugin directory</b> Select the destination plugin area Qt::Vertical 20 40 0 <b>Installation Summary</b> This shows the summary of the installation data true 0 %v/%m Files Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Close addArchivesButton archivesList removeArchivesButton destinationCombo summaryEdit buttonBox eric-6.0.8/eric/PluginManager/PluginInstallDialog.py0000644000175000017500000005612712451233375021475 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the Plugin installation dialog. """ from __future__ import unicode_literals import os import sys import shutil import zipfile import compileall import glob try: # Py3 import urllib.parse as parse except (ImportError): import urlparse as parse # __IGNORE_WARNING__ from PyQt5.QtCore import pyqtSlot, Qt, QDir, QFileInfo from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QAbstractButton, \ QApplication, QDialog, QVBoxLayout from E5Gui import E5FileDialog from E5Gui.E5MainWindow import E5MainWindow from .Ui_PluginInstallDialog import Ui_PluginInstallDialog import Utilities import Preferences from Utilities.uic import compileUiFiles class PluginInstallWidget(QWidget, Ui_PluginInstallDialog): """ Class implementing the Plugin installation dialog. """ def __init__(self, pluginManager, pluginFileNames, parent=None): """ Constructor @param pluginManager reference to the plugin manager object @param pluginFileNames list of plugin files suggested for installation (list of strings) @param parent parent of this dialog (QWidget) """ super(PluginInstallWidget, self).__init__(parent) self.setupUi(self) if pluginManager is None: # started as external plugin installer from .PluginManager import PluginManager self.__pluginManager = PluginManager(doLoadPlugins=False) self.__external = True else: self.__pluginManager = pluginManager self.__external = False self.__backButton = self.buttonBox.addButton( self.tr("< Back"), QDialogButtonBox.ActionRole) self.__nextButton = self.buttonBox.addButton( self.tr("Next >"), QDialogButtonBox.ActionRole) self.__finishButton = self.buttonBox.addButton( self.tr("Install"), QDialogButtonBox.ActionRole) self.__closeButton = self.buttonBox.button(QDialogButtonBox.Close) self.__cancelButton = self.buttonBox.button(QDialogButtonBox.Cancel) userDir = self.__pluginManager.getPluginDir("user") if userDir is not None: self.destinationCombo.addItem( self.tr("User plugins directory"), userDir) globalDir = self.__pluginManager.getPluginDir("global") if globalDir is not None and os.access(globalDir, os.W_OK): self.destinationCombo.addItem( self.tr("Global plugins directory"), globalDir) self.__installedDirs = [] self.__installedFiles = [] self.__restartNeeded = False downloadDir = QDir(Preferences.getPluginManager("DownloadPath")) for pluginFileName in pluginFileNames: fi = QFileInfo(pluginFileName) if fi.isRelative(): pluginFileName = QFileInfo( downloadDir, fi.fileName()).absoluteFilePath() self.archivesList.addItem(pluginFileName) self.archivesList.sortItems() self.__currentIndex = 0 self.__selectPage() def restartNeeded(self): """ Public method to check, if a restart of the IDE is required. @return flag indicating a restart is required (boolean) """ return self.__restartNeeded def __createArchivesList(self): """ Private method to create a list of plugin archive names. @return list of plugin archive names (list of strings) """ archivesList = [] for row in range(self.archivesList.count()): archivesList.append(self.archivesList.item(row).text()) return archivesList def __selectPage(self): """ Private method to show the right wizard page. """ self.wizard.setCurrentIndex(self.__currentIndex) if self.__currentIndex == 0: self.__backButton.setEnabled(False) self.__nextButton.setEnabled(self.archivesList.count() > 0) self.__finishButton.setEnabled(False) self.__closeButton.hide() self.__cancelButton.show() elif self.__currentIndex == 1: self.__backButton.setEnabled(True) self.__nextButton.setEnabled(self.destinationCombo.count() > 0) self.__finishButton.setEnabled(False) self.__closeButton.hide() self.__cancelButton.show() else: self.__backButton.setEnabled(True) self.__nextButton.setEnabled(False) self.__finishButton.setEnabled(True) self.__closeButton.hide() self.__cancelButton.show() msg = self.tr( "Plugin ZIP-Archives:\n{0}\n\nDestination:\n{1} ({2})")\ .format("\n".join(self.__createArchivesList()), self.destinationCombo.currentText(), self.destinationCombo.itemData( self.destinationCombo.currentIndex()) ) self.summaryEdit.setPlainText(msg) @pyqtSlot() def on_addArchivesButton_clicked(self): """ Private slot to select plugin ZIP-archives via a file selection dialog. """ dn = Preferences.getPluginManager("DownloadPath") archives = E5FileDialog.getOpenFileNames( self, self.tr("Select plugin ZIP-archives"), dn, self.tr("Plugin archive (*.zip)")) if archives: matchflags = Qt.MatchFixedString if not Utilities.isWindowsPlatform(): matchflags |= Qt.MatchCaseSensitive for archive in archives: if len(self.archivesList.findItems(archive, matchflags)) == 0: # entry not in list already self.archivesList.addItem(archive) self.archivesList.sortItems() self.__nextButton.setEnabled(self.archivesList.count() > 0) @pyqtSlot() def on_archivesList_itemSelectionChanged(self): """ Private slot called, when the selection of the archives list changes. """ self.removeArchivesButton.setEnabled( len(self.archivesList.selectedItems()) > 0) @pyqtSlot() def on_removeArchivesButton_clicked(self): """ Private slot to remove archives from the list. """ for archiveItem in self.archivesList.selectedItems(): itm = self.archivesList.takeItem( self.archivesList.row(archiveItem)) del itm self.__nextButton.setEnabled(self.archivesList.count() > 0) @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot to handle the click of a button of the button box. @param button reference to the button pressed (QAbstractButton) """ if button == self.__backButton: self.__currentIndex -= 1 self.__selectPage() elif button == self.__nextButton: self.__currentIndex += 1 self.__selectPage() elif button == self.__finishButton: self.__finishButton.setEnabled(False) self.__installPlugins() self.__closeButton.show() self.__cancelButton.hide() def __installPlugins(self): """ Private method to install the selected plugin archives. @return flag indicating success (boolean) """ res = True self.summaryEdit.clear() for archive in self.__createArchivesList(): self.summaryEdit.append( self.tr("Installing {0} ...").format(archive)) ok, msg, restart = self.__installPlugin(archive) res = res and ok if ok: self.summaryEdit.append(self.tr(" ok")) else: self.summaryEdit.append(msg) if restart: self.__restartNeeded = True self.summaryEdit.append("\n") if res: self.summaryEdit.append(self.tr( """The plugins were installed successfully.""")) else: self.summaryEdit.append(self.tr( """Some plugins could not be installed.""")) return res def __installPlugin(self, archiveFilename): """ Private slot to install the selected plugin. @param archiveFilename name of the plugin archive file (string) @return flag indicating success (boolean), error message upon failure (string) and flag indicating a restart of the IDE is required (boolean) """ installedPluginName = "" archive = archiveFilename destination = self.destinationCombo.itemData( self.destinationCombo.currentIndex()) # check if archive is a local url url = parse.urlparse(archive) if url[0].lower() == 'file': archive = url[2] # check, if the archive exists if not os.path.exists(archive): return False, \ self.tr( """

    The archive file {0} does not exist. """ """Aborting...

    """).format(archive), \ False # check, if the archive is a valid zip file if not zipfile.is_zipfile(archive): return False, \ self.tr( """

    The file {0} is not a valid plugin """ """ZIP-archive. Aborting...

    """).format(archive), \ False # check, if the destination is writeable if not os.access(destination, os.W_OK): return False, \ self.tr( """

    The destination directory {0} is not """ """writeable. Aborting...

    """).format(destination), \ False zip = zipfile.ZipFile(archive, "r") # check, if the archive contains a valid plugin pluginFound = False pluginFileName = "" for name in zip.namelist(): if self.__pluginManager.isValidPluginName(name): installedPluginName = name[:-3] pluginFound = True pluginFileName = name break if not pluginFound: return False, \ self.tr( """

    The file {0} is not a valid plugin """ """ZIP-archive. Aborting...

    """).format(archive), \ False # parse the plugin module's plugin header pluginSource = Utilities.decode(zip.read(pluginFileName))[0] packageName = "" internalPackages = [] needsRestart = False pyqtApi = 0 doCompile = True for line in pluginSource.splitlines(): if line.startswith("packageName"): tokens = line.split("=") if tokens[0].strip() == "packageName" and \ tokens[1].strip()[1:-1] != "__core__": if tokens[1].strip()[0] in ['"', "'"]: packageName = tokens[1].strip()[1:-1] else: if tokens[1].strip() == "None": packageName = "None" elif line.startswith("internalPackages"): tokens = line.split("=") token = tokens[1].strip()[1:-1] # it is a comma separated string internalPackages = [p.strip() for p in token.split(",")] elif line.startswith("needsRestart"): tokens = line.split("=") needsRestart = tokens[1].strip() == "True" elif line.startswith("pyqtApi"): tokens = line.split("=") try: pyqtApi = int(tokens[1].strip()) except ValueError: pass elif line.startswith("doNotCompile"): tokens = line.split("=") if tokens[1].strip() == "True": doCompile = False elif line.startswith("# End-Of-Header"): break if not packageName: return False, \ self.tr( """

    The plugin module {0} does not contain """ """a 'packageName' attribute. Aborting...

    """)\ .format(pluginFileName), \ False if pyqtApi < 2: return False, \ self.tr( """

    The plugin module {0} does not conform""" """ with the PyQt v2 API. Aborting...

    """)\ .format(pluginFileName), \ False # check, if it is a plugin, that collides with others if not os.path.exists(os.path.join(destination, pluginFileName)) and \ packageName != "None" and \ os.path.exists(os.path.join(destination, packageName)): return False, \ self.tr("""

    The plugin package {0} exists. """ """Aborting...

    """)\ .format(os.path.join(destination, packageName)), \ False if os.path.exists(os.path.join(destination, pluginFileName)) and \ packageName != "None" and \ not os.path.exists(os.path.join(destination, packageName)): return False, \ self.tr("""

    The plugin module {0} exists. """ """Aborting...

    """)\ .format(os.path.join(destination, pluginFileName)), \ False activatePlugin = False if not self.__external: activatePlugin = \ not self.__pluginManager.isPluginLoaded( installedPluginName) or \ (self.__pluginManager.isPluginLoaded(installedPluginName) and self.__pluginManager.isPluginActive(installedPluginName)) # try to unload a plugin with the same name self.__pluginManager.unloadPlugin(installedPluginName) # uninstall existing plugin first to get clean conditions self.__uninstallPackage(destination, pluginFileName, packageName) # clean sys.modules reload_ = self.__pluginManager.removePluginFromSysModules( installedPluginName, packageName, internalPackages) # now do the installation self.__installedDirs = [] self.__installedFiles = [] try: if packageName != "None": namelist = sorted(zip.namelist()) tot = len(namelist) prog = 0 self.progress.setMaximum(tot) QApplication.processEvents() for name in namelist: self.progress.setValue(prog) QApplication.processEvents() prog += 1 if name == pluginFileName or \ name.startswith("{0}/".format(packageName)) or \ name.startswith("{0}\\".format(packageName)): outname = name.replace("/", os.sep) outname = os.path.join(destination, outname) if outname.endswith("/") or outname.endswith("\\"): # it is a directory entry outname = outname[:-1] if not os.path.exists(outname): self.__makedirs(outname) else: # it is a file d = os.path.dirname(outname) if not os.path.exists(d): self.__makedirs(d) f = open(outname, "wb") f.write(zip.read(name)) f.close() self.__installedFiles.append(outname) self.progress.setValue(tot) # now compile user interface files compileUiFiles(os.path.join(destination, packageName), True) else: outname = os.path.join(destination, pluginFileName) f = open(outname, "w", encoding="utf-8") f.write(pluginSource) f.close() self.__installedFiles.append(outname) except os.error as why: self.__rollback() return False, \ self.tr( "Error installing plugin. Reason: {0}").format(str(why)), \ False except IOError as why: self.__rollback() return False, \ self.tr( "Error installing plugin. Reason: {0}").format(str(why)), \ False except OSError as why: self.__rollback() return False, \ self.tr( "Error installing plugin. Reason: {0}").format(str(why)), \ False except: sys.stderr.write("Unspecific exception installing plugin.\n") self.__rollback() return False, \ self.tr("Unspecific exception installing plugin."), \ False # now compile the plugins if doCompile: compileall.compile_dir( os.path.join(destination, packageName), quiet=True) compileall.compile_file( os.path.join(destination, pluginFileName), quiet=True) if not self.__external: # now load and activate the plugin self.__pluginManager.loadPlugin(installedPluginName, destination, reload_) if activatePlugin: self.__pluginManager.activatePlugin(installedPluginName) return True, "", needsRestart def __rollback(self): """ Private method to rollback a failed installation. """ for fname in self.__installedFiles: if os.path.exists(fname): os.remove(fname) for dname in self.__installedDirs: if os.path.exists(dname): shutil.rmtree(dname) def __makedirs(self, name, mode=0o777): """ Private method to create a directory and all intermediate ones. This is an extended version of the Python one in order to record the created directories. @param name name of the directory to create (string) @param mode permission to set for the new directory (integer) """ head, tail = os.path.split(name) if not tail: head, tail = os.path.split(head) if head and tail and not os.path.exists(head): self.__makedirs(head, mode) if tail == os.curdir: # xxx/newdir/. exists if xxx/newdir exists return os.mkdir(name, mode) self.__installedDirs.append(name) def __uninstallPackage(self, destination, pluginFileName, packageName): """ Private method to uninstall an already installed plugin to prepare the update. @param destination name of the plugin directory (string) @param pluginFileName name of the plugin file (string) @param packageName name of the plugin package (string) """ if packageName == "" or packageName == "None": packageDir = None else: packageDir = os.path.join(destination, packageName) pluginFile = os.path.join(destination, pluginFileName) try: if packageDir and os.path.exists(packageDir): shutil.rmtree(packageDir) fnameo = "{0}o".format(pluginFile) if os.path.exists(fnameo): os.remove(fnameo) fnamec = "{0}c".format(pluginFile) if os.path.exists(fnamec): os.remove(fnamec) pluginDirCache = os.path.join( os.path.dirname(pluginFile), "__pycache__") if os.path.exists(pluginDirCache): pluginFileName = os.path.splitext( os.path.basename(pluginFile))[0] for fnameo in glob.glob( os.path.join(pluginDirCache, "{0}*.pyo".format(pluginFileName))): os.remove(fnameo) for fnamec in glob.glob( os.path.join(pluginDirCache, "{0}*.pyc".format(pluginFileName))): os.remove(fnamec) os.remove(pluginFile) except (IOError, OSError, os.error): # ignore some exceptions pass class PluginInstallDialog(QDialog): """ Class for the dialog variant. """ def __init__(self, pluginManager, pluginFileNames, parent=None): """ Constructor @param pluginManager reference to the plugin manager object @param pluginFileNames list of plugin files suggested for installation (list of strings) @param parent reference to the parent widget (QWidget) """ super(PluginInstallDialog, self).__init__(parent) self.setSizeGripEnabled(True) self.__layout = QVBoxLayout(self) self.__layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.__layout) self.cw = PluginInstallWidget(pluginManager, pluginFileNames, self) size = self.cw.size() self.__layout.addWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.cw.buttonBox.accepted.connect(self.accept) self.cw.buttonBox.rejected.connect(self.reject) def restartNeeded(self): """ Public method to check, if a restart of the IDE is required. @return flag indicating a restart is required (boolean) """ return self.cw.restartNeeded() class PluginInstallWindow(E5MainWindow): """ Main window class for the standalone dialog. """ def __init__(self, pluginFileNames, parent=None): """ Constructor @param pluginFileNames list of plugin files suggested for installation (list of strings) @param parent reference to the parent widget (QWidget) """ super(PluginInstallWindow, self).__init__(parent) self.cw = PluginInstallWidget(None, pluginFileNames, self) size = self.cw.size() self.setCentralWidget(self.cw) self.resize(size) self.setWindowTitle(self.cw.windowTitle()) self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) self.cw.buttonBox.accepted.connect(self.close) self.cw.buttonBox.rejected.connect(self.close) eric-6.0.8/eric/PluginManager/PluginDetailsDialog.ui0000644000175000017500000001337512060166053021431 0ustar piotrpiotr PluginDetailsDialog 0 0 563 479 Plugin Details true Module name: true Module filename: true Qt::NoFocus Autoactivate Qt::NoFocus Active Qt::Horizontal 40 20 Plugin name: true Version: true Author: true Description: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 5 true Error: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 1 true Qt::Horizontal QDialogButtonBox::Close moduleNameEdit moduleFileNameEdit pluginNameEdit versionEdit authorEdit descriptionEdit errorEdit buttonBox buttonBox accepted() PluginDetailsDialog accept() 248 254 157 274 buttonBox rejected() PluginDetailsDialog reject() 316 260 286 274 eric-6.0.8/eric/PluginManager/PluginExceptions.py0000644000175000017500000001057212451233375021062 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2007 - 2015 Detlev Offenbach # """ Module implementing the exceptions raised by the plugin system. """ from __future__ import unicode_literals from PyQt5.QtCore import QCoreApplication class PluginError(Exception): """ Class defining a special error for the plugin classes. """ def __init__(self): """ Constructor """ self._errorMessage = QCoreApplication.translate( "PluginError", "Unspecific plugin error.") def __repr__(self): """ Special method returning a representation of the exception. @return string representing the error message """ return str(self._errorMessage) def __str__(self): """ Special method returning a string representation of the exception. @return string representing the error message """ return str(self._errorMessage) class PluginPathError(PluginError): """ Class defining an error raised, when the plugin paths were not found and could not be created. """ def __init__(self, msg=None): """ Constructor @param msg message to be used by the exception (string) """ if msg: self._errorMessage = msg else: self._errorMessage = QCoreApplication.translate( "PluginError", "Plugin paths not found or not creatable.") class PluginModulesError(PluginError): """ Class defining an error raised, when no plugin modules were found. """ def __init__(self): """ Constructor """ self._errorMessage = QCoreApplication.translate( "PluginError", "No plugin modules found.") class PluginLoadError(PluginError): """ Class defining an error raised, when there was an error during plugin loading. """ def __init__(self, name): """ Constructor @param name name of the plugin module (string) """ self._errorMessage = \ QCoreApplication.translate( "PluginError", "Error loading plugin module: {0}")\ .format(name) class PluginActivationError(PluginError): """ Class defining an error raised, when there was an error during plugin activation. """ def __init__(self, name): """ Constructor @param name name of the plugin module (string) """ self._errorMessage = \ QCoreApplication.translate( "PluginError", "Error activating plugin module: {0}")\ .format(name) class PluginModuleFormatError(PluginError): """ Class defining an error raised, when the plugin module is invalid. """ def __init__(self, name, missing): """ Constructor @param name name of the plugin module (string) @param missing description of the missing element (string) """ self._errorMessage = \ QCoreApplication.translate( "PluginError", "The plugin module {0} is missing {1}.")\ .format(name, missing) class PluginClassFormatError(PluginError): """ Class defining an error raised, when the plugin module's class is invalid. """ def __init__(self, name, class_, missing): """ Constructor @param name name of the plugin module (string) @param class_ name of the class not satisfying the requirements (string) @param missing description of the missing element (string) """ self._errorMessage = \ QCoreApplication.translate( "PluginError", "The plugin class {0} of module {1} is missing {2}.")\ .format(class_, name, missing) class PluginPy2IncompatibleError(PluginError): """ Class defining an error raised, when the plugin is incompatible with Python2. """ def __init__(self, name): """ Constructor @param name name of the plugin module (string) """ self._errorMessage = \ QCoreApplication.translate( "PluginError", "The plugin module {0} is not compatible with Python2.")\ .format(name) eric-6.0.8/eric/uninstall.py0000644000175000017500000001725712451233375015051 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2002 - 2015 Detlev Offenbach # # This is the uninstall script for eric6. """ Uninstallation script for the eric6 IDE and all eric6 related tools. """ from __future__ import unicode_literals import sys import os import shutil import glob import distutils.sysconfig # get a local eric6config.py out of the way if os.path.exists("eric6config.py"): os.rename("eric6config.py", "eric6config.py.orig") from eric6config import getConfig # Define the globals. progName = None pyModDir = None progLanguages = ["Python", "Ruby", "QSS"] includePythonVariant = False defaultMacAppBundleName = "eric6.app" defaultMacAppBundlePath = "/Applications" # Define file name markers for Python variants PythonMarkers = { 2: "_py2", 3: "_py3", } def exit(rcode=0): """ Exit the uninstall script. @param rcode result code to report back (integer) """ # restore the local eric6config.py if os.path.exists("eric6config.py.orig"): if os.path.exists("eric6config.py"): os.remove("eric6config.py") os.rename("eric6config.py.orig", "eric6config.py") def usage(rcode=2): """ Display a usage message and exit. @param rcode return code passed back to the calling process (integer) """ global progName print("Usage:") print(" {0} [-h]".format(progName)) print("where:") print(" -h display this help message") print(" -y remove executables with Python variant in name") exit(rcode) def initGlobals(): """ Set the values of globals that need more than a simple assignment. """ global pyModDir pyModDir = distutils.sysconfig.get_python_lib(True) def wrapperName(dname, wfile): """ Create the platform specific name for the wrapper script. @param dname name of the directory to place the wrapper into @param wfile basename (without extension) of the wrapper script @return the name of the wrapper script """ if sys.platform.startswith("win"): wname = dname + "\\" + wfile + ".bat" else: wname = dname + "/" + wfile return wname def uninstallEric(): """ Uninstall the eric files. """ global pyModDir # Remove the menu entry for Linux systems if sys.platform.startswith("linux") and os.getuid() == 0: if includePythonVariant: marker = PythonMarkers[sys.version_info.major] else: marker = "" for name in ["/usr/share/applications/eric6" + marker + ".desktop", "/usr/share/appdata/eric6" + marker + ".appdata.xml", "/usr/share/applications/eric6_webbrowser" + marker + ".desktop", "/usr/share/pixmaps/eric" + marker + ".png", "/usr/share/pixmaps/ericWeb" + marker + ".png"]: if os.path.exists(name): os.remove(name) # Remove the wrapper scripts rem_wnames = [ "eric6_api", "eric6_compare", "eric6_configure", "eric6_diff", "eric6_doc", "eric6_qregularexpression", "eric6_qregexp", "eric6_re", "eric6_trpreviewer", "eric6_uipreviewer", "eric6_unittest", "eric6", "eric6_tray", "eric6_editor", "eric6_plugininstall", "eric6_pluginuninstall", "eric6_pluginrepository", "eric6_sqlbrowser", "eric6_webbrowser", "eric6_iconeditor", "eric6_snap", ] if includePythonVariant: marker = PythonMarkers[sys.version_info.major] rem_wnames = [n + marker for n in rem_wnames] try: for rem_wname in rem_wnames: rwname = wrapperName(getConfig('bindir'), rem_wname) if os.path.exists(rwname): os.remove(rwname) # Cleanup our config file(s) for name in ['eric6config.py', 'eric6config.pyc', 'eric6.pth']: e5cfile = os.path.join(pyModDir, name) if os.path.exists(e5cfile): os.remove(e5cfile) e5cfile = os.path.join(pyModDir, "__pycache__", name) path, ext = os.path.splitext(e5cfile) for f in glob.glob("{0}.*{1}".format(path, ext)): os.remove(f) # Cleanup the install directories for name in ['ericExamplesDir', 'ericDocDir', 'ericDTDDir', 'ericCSSDir', 'ericIconDir', 'ericPixDir', 'ericTemplatesDir', 'ericCodeTemplatesDir', 'ericOthersDir', 'ericStylesDir', 'ericDir']: dirpath = getConfig(name) if os.path.exists(dirpath): shutil.rmtree(dirpath, True) # Cleanup translations for name in glob.glob( os.path.join(getConfig('ericTranslationsDir'), 'eric6_*.qm')): if os.path.exists(name): os.remove(name) # Cleanup API files apidir = getConfig('apidir') if apidir: for progLanguage in progLanguages: for name in getConfig('apis'): apiname = os.path.join(apidir, progLanguage.lower(), name) if os.path.exists(apiname): os.remove(apiname) for apiname in glob.glob( os.path.join(apidir, progLanguage.lower(), "*.bas")): if os.path.basename(apiname) != "eric6.bas": os.remove(apiname) if sys.platform == "darwin": # delete the Mac app bundle if os.path.exists("/Developer/Applications/Eric6"): shutil.rmtree("/Developer/Applications/Eric6") try: macAppBundlePath = getConfig("macAppBundlePath") macAppBundleName = getConfig("macAppBundleName") except AttributeError: macAppBundlePath = defaultMacAppBundlePath macAppBundleName = defaultMacAppBundleName for bundlePath in [os.path.join(defaultMacAppBundlePath, macAppBundleName), os.path.join(macAppBundlePath, macAppBundleName), ]: if os.path.exists(bundlePath): shutil.rmtree(bundlePath) except (IOError, OSError) as msg: sys.stderr.write( 'Error: {0}\nTry uninstall with admin rights.\n'.format(msg)) exit(7) def main(argv): """ The main function of the script. @param argv list of command line arguments """ import getopt global includePythonVariant initGlobals() # Parse the command line. global progName progName = os.path.basename(argv[0]) try: optlist, args = getopt.getopt(argv[1:], "hy") except getopt.GetoptError: usage() global platBinDir for opt, arg in optlist: if opt == "-h": usage(0) if opt == "-y": includePythonVariant = True try: uninstallEric() except IOError as msg: sys.stderr.write( 'IOError: {0}\nTry uninstall with admin rights.\n'.format(msg)) except OSError as msg: sys.stderr.write( 'OSError: {0}\nTry uninstall with admin rights.\n'.format(msg)) exit(0) if __name__ == "__main__": try: main(sys.argv) except SystemExit: raise except: print("""An internal error occured. Please report all the output of""" """ the program,\n""" """including the following traceback, to""" """ eric-bugs@eric-ide.python-projects.org.\n""") raise eric-6.0.8/eric/eric6_pluginuninstall.pyw0000644000175000017500000000031112451233400017513 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2011 - 2015 Detlev Offenbach # """ Module implementing the Windows entry point. """ from eric6_pluginuninstall import main main() eric-6.0.8/eric/eric6_qregexp.py0000644000175000017500000000345212451233375015573 0ustar piotrpiotr#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2004 - 2015 Detlev Offenbach # """ Eric6 QRegExp. This is the main Python script that performs the necessary initialization of the QRegExp wizard module and starts the Qt event loop. This is a standalone version of the integrated QRegExp wizard. """ from __future__ import unicode_literals import Toolbox.PyQt4ImportHook # __IGNORE_WARNING__ try: # Only for Py2 import Utilities.compatibility_fixes # __IGNORE_WARNING__ except (ImportError): pass import sys for arg in sys.argv: if arg.startswith("--config="): import Globals configDir = arg.replace("--config=", "") Globals.setConfigDir(configDir) sys.argv.remove(arg) break from Globals import AppInfo from Toolbox import Startup def createMainWidget(argv): """ Function to create the main widget. @param argv list of commandline parameters (list of strings) @return reference to the main widget (QWidget) """ from Plugins.WizardPlugins.QRegExpWizard.QRegExpWizardDialog import \ QRegExpWizardWindow return QRegExpWizardWindow() def main(): """ Main entry point into the application. """ options = [ ("--config=configDir", "use the given directory as the one containing the config files"), ] appinfo = AppInfo.makeAppInfo(sys.argv, "Eric6 QRegExp", "", "Regexp editor for Qt's QRegExp class", options) res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget) sys.exit(res) if __name__ == '__main__': main() eric-6.0.8/eric/Helpviewer/0000755000175000017500000000000012557365404014572 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/UrlBar/0000755000175000017500000000000012557365404015761 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/UrlBar/BookmarkInfoDialog.ui0000644000175000017500000000653412060166053022015 0ustar piotrpiotr BookmarkInfoDialog 0 0 350 135 Edit Bookmark true 10 0 0 Edit this Bookmark Qt::AlignCenter 0 0 Press to remove this bookmark Remove this Bookmark Title: Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok removeButton titleEdit buttonBox buttonBox accepted() BookmarkInfoDialog accept() 227 114 157 134 buttonBox rejected() BookmarkInfoDialog reject() 295 120 286 134 eric-6.0.8/eric/Helpviewer/UrlBar/BookmarkInfoDialog.py0000644000175000017500000000405012451233375022025 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a dialog to show some bookmark info. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QFont from PyQt5.QtWidgets import QDialog from .Ui_BookmarkInfoDialog import Ui_BookmarkInfoDialog import UI.PixmapCache class BookmarkInfoDialog(QDialog, Ui_BookmarkInfoDialog): """ Class implementing a dialog to show some bookmark info. """ def __init__(self, bookmark, parent=None): """ Constructor @param bookmark reference to the bookmark to be shown (Bookmark) @param parent reference to the parent widget (QWidget) """ super(BookmarkInfoDialog, self).__init__(parent) self.setupUi(self) self.__bookmark = bookmark self.icon.setPixmap(UI.PixmapCache.getPixmap("bookmark32.png")) font = QFont() font.setPointSize(font.pointSize() + 2) self.title.setFont(font) if bookmark is None: self.titleEdit.setEnabled(False) else: self.titleEdit.setText(bookmark.title) self.titleEdit.setFocus() msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_removeButton_clicked(self): """ Private slot to remove the current bookmark. """ import Helpviewer.HelpWindow Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\ .removeBookmark(self.__bookmark) self.close() def accept(self): """ Public slot handling the acceptance of the dialog. """ if self.__bookmark is not None and \ self.titleEdit.text() != self.__bookmark.title: import Helpviewer.HelpWindow Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\ .setTitle(self.__bookmark, self.titleEdit.text()) self.close() eric-6.0.8/eric/Helpviewer/UrlBar/BookmarkActionSelectionDialog.ui0000644000175000017500000000206312060166053024176 0ustar piotrpiotr BookmarkActionSelectionDialog 0 0 291 153 true Qt::AlignCenter <b>Add/Edit Bookmark</b> Qt::AlignCenter eric-6.0.8/eric/Helpviewer/UrlBar/StackedUrlBar.py0000644000175000017500000000372012451233375021015 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a widget to stack url bars. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QStackedWidget, QSizePolicy class StackedUrlBar(QStackedWidget): """ Class implementing a widget to stack url bars. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(StackedUrlBar, self).__init__(parent) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(6) sizePolicy.setVerticalStretch(0) self.setSizePolicy(sizePolicy) self.setMinimumSize(200, 22) def currentUrlBar(self): """ Public method to get a reference to the current url bar. @return reference to the current url bar (UrlBar) """ return self.urlBar(self.currentIndex()) def urlBar(self, index): """ Public method to get a reference to the url bar for a given index. @param index index of the url bar (integer) @return reference to the url bar for the given index (UrlBar) """ return self.widget(index) def moveBar(self, from_, to_): """ Public slot to move a url bar. @param from_ index of url bar to be moved (integer) @param to_ into to move the url bar to (integer) """ fromBar = self.widget(from_) self.removeWidget(fromBar) self.insertWidget(to_, fromBar) def urlBars(self): """ Public method to get a list of references to all url bars. @return list of references to url bars (list of UrlBar) """ li = [] for index in range(self.count()): li.append(self.widget(index)) return li eric-6.0.8/eric/Helpviewer/UrlBar/__init__.py0000644000175000017500000000022512451233375020063 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Package implementing the URL bar widget. """ eric-6.0.8/eric/Helpviewer/UrlBar/SslLabel.py0000644000175000017500000000355612451233375020037 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the label to show some SSL info. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, pyqtSignal, QPoint from PyQt5.QtWidgets import QLabel class SslLabel(QLabel): """ Class implementing the label to show some SSL info. """ clicked = pyqtSignal(QPoint) okStyle = "QLabel { color : white; background-color : green; }" nokStyle = "QLabel { color : white; background-color : red; }" def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(SslLabel, self).__init__(parent) self.setFocusPolicy(Qt.NoFocus) self.setCursor(Qt.ArrowCursor) def mouseReleaseEvent(self, evt): """ Protected method to handle mouse release events. @param evt reference to the mouse event (QMouseEvent) """ if evt.button() == Qt.LeftButton: self.clicked.emit(evt.globalPos()) else: super(SslLabel, self).mouseReleaseEvent(evt) def mouseDoubleClickEvent(self, evt): """ Protected method to handle mouse double click events. @param evt reference to the mouse event (QMouseEvent) """ if evt.button() == Qt.LeftButton: self.clicked.emit(evt.globalPos()) else: super(SslLabel, self).mouseDoubleClickEvent(evt) def setValidity(self, valid): """ Public method to set the validity indication. @param valid flag indicating the certificate validity (boolean) """ if valid: self.setStyleSheet(SslLabel.okStyle) else: self.setStyleSheet(SslLabel.nokStyle) eric-6.0.8/eric/Helpviewer/UrlBar/BookmarkActionSelectionDialog.py0000644000175000017500000000512712451233375024223 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to select the action to be performed on the bookmark. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from .Ui_BookmarkActionSelectionDialog import Ui_BookmarkActionSelectionDialog import UI.PixmapCache class BookmarkActionSelectionDialog(QDialog, Ui_BookmarkActionSelectionDialog): """ Class implementing a dialog to select the action to be performed on the bookmark. """ Undefined = -1 AddBookmark = 0 EditBookmark = 1 AddSpeeddial = 2 RemoveSpeeddial = 3 def __init__(self, url, parent=None): """ Constructor @param url URL to be worked on (QUrl) @param parent reference to the parent widget (QWidget) """ super(BookmarkActionSelectionDialog, self).__init__(parent) self.setupUi(self) self.__action = self.Undefined self.icon.setPixmap(UI.PixmapCache.getPixmap("bookmark32.png")) import Helpviewer.HelpWindow if Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\ .bookmarkForUrl(url) is None: self.__bmAction = self.AddBookmark self.bookmarkPushButton.setText(self.tr("Add Bookmark")) else: self.__bmAction = self.EditBookmark self.bookmarkPushButton.setText(self.tr("Edit Bookmark")) if Helpviewer.HelpWindow.HelpWindow.speedDial().pageForUrl(url).url: self.__sdAction = self.RemoveSpeeddial self.speeddialPushButton.setText( self.tr("Remove from Speed Dial")) else: self.__sdAction = self.AddSpeeddial self.speeddialPushButton.setText(self.tr("Add to Speed Dial")) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) @pyqtSlot() def on_bookmarkPushButton_clicked(self): """ Private slot handling selection of a bookmark action. """ self.__action = self.__bmAction self.accept() @pyqtSlot() def on_speeddialPushButton_clicked(self): """ Private slot handling selection of a speed dial action. """ self.__action = self.__sdAction self.accept() def getAction(self): """ Public method to get the selected action. @return reference to the associated action """ return self.__action eric-6.0.8/eric/Helpviewer/UrlBar/FavIconLabel.py0000644000175000017500000000606512451233375020621 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the label to show the web site icon. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import Qt, QPoint, QUrl, QMimeData from PyQt5.QtGui import QDrag, QPixmap from PyQt5.QtWidgets import QLabel, QApplication class FavIconLabel(QLabel): """ Class implementing the label to show the web site icon. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(FavIconLabel, self).__init__(parent) self.__browser = None self.__dragStartPos = QPoint() self.setFocusPolicy(Qt.NoFocus) self.setCursor(Qt.ArrowCursor) self.setMinimumSize(16, 16) self.resize(16, 16) self.__browserIconChanged() def __browserIconChanged(self): """ Private slot to set the icon. """ import Helpviewer.HelpWindow try: url = QUrl() if self.__browser: url = self.__browser.url() self.setPixmap( Helpviewer.HelpWindow.HelpWindow.icon(url).pixmap(16, 16)) except RuntimeError: pass def __clearIcon(self): """ Private slot to clear the icon. """ self.setPixmap(QPixmap()) def setBrowser(self, browser): """ Public method to set the browser connection. @param browser reference to the browser widegt (HelpBrowser) """ self.__browser = browser self.__browser.loadFinished.connect(self.__browserIconChanged) self.__browser.iconChanged.connect(self.__browserIconChanged) self.__browser.loadStarted.connect(self.__clearIcon) def mousePressEvent(self, evt): """ Protected method to handle mouse press events. @param evt reference to the mouse event (QMouseEvent) """ if evt.button() == Qt.LeftButton: self.__dragStartPos = evt.pos() super(FavIconLabel, self).mousePressEvent(evt) def mouseMoveEvent(self, evt): """ Protected method to handle mouse move events. @param evt reference to the mouse event (QMouseEvent) """ if evt.button() == Qt.LeftButton and \ (evt.pos() - self.__dragStartPos).manhattanLength() > \ QApplication.startDragDistance() and \ self.__browser is not None: drag = QDrag(self) mimeData = QMimeData() title = self.__browser.title() if title == "": title = str(self.__browser.url().toEncoded(), encoding="utf-8") mimeData.setText(title) mimeData.setUrls([self.__browser.url()]) p = self.pixmap() if p: drag.setPixmap(p) drag.setMimeData(mimeData) drag.exec_() eric-6.0.8/eric/Helpviewer/UrlBar/UrlBar.py0000644000175000017500000004245312554667500017531 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the URL bar widget. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import pyqtSlot, Qt, QPointF, QUrl, QDateTime, qVersion from PyQt5.QtGui import QColor, QPalette, QLinearGradient, QIcon from PyQt5.QtWidgets import QDialog, QApplication try: from PyQt5.QtNetwork import QSslCertificate # __IGNORE_EXCEPTION__ except ImportError: QSslCertificate = None # __IGNORE_WARNING__ from PyQt5.QtWebKit import QWebSettings from PyQt5.QtWebKitWidgets import QWebPage from E5Gui.E5LineEdit import E5LineEdit from E5Gui.E5LineEditButton import E5LineEditButton import Helpviewer.HelpWindow from .FavIconLabel import FavIconLabel from .SslLabel import SslLabel import UI.PixmapCache import Preferences import Utilities class UrlBar(E5LineEdit): """ Class implementing a line edit for entering URLs. """ def __init__(self, mainWindow, parent=None): """ Constructor @param mainWindow reference to the main window (HelpWindow) @param parent reference to the parent widget (HelpBrowser) """ E5LineEdit.__init__(self, parent) self.setInactiveText(self.tr("Enter the URL here.")) self.setWhatsThis(self.tr("Enter the URL here.")) self.__mw = mainWindow self.__browser = None self.__privateMode = QWebSettings.globalSettings().testAttribute( QWebSettings.PrivateBrowsingEnabled) self.__bmActiveIcon = UI.PixmapCache.getIcon("bookmark16.png") self.__bmInactiveIcon = QIcon( self.__bmActiveIcon.pixmap(16, 16, QIcon.Disabled)) self.__favicon = FavIconLabel(self) self.addWidget(self.__favicon, E5LineEdit.LeftSide) self.__sslLabel = SslLabel(self) self.addWidget(self.__sslLabel, E5LineEdit.LeftSide) self.__sslLabel.setVisible(False) self.__privacyButton = E5LineEditButton(self) self.__privacyButton.setIcon( UI.PixmapCache.getIcon("privateBrowsing.png")) self.addWidget(self.__privacyButton, E5LineEdit.RightSide) self.__privacyButton.setVisible(self.__privateMode) self.__rssButton = E5LineEditButton(self) self.__rssButton.setIcon(UI.PixmapCache.getIcon("rss16.png")) self.addWidget(self.__rssButton, E5LineEdit.RightSide) self.__rssButton.setVisible(False) self.__bookmarkButton = E5LineEditButton(self) self.addWidget(self.__bookmarkButton, E5LineEdit.RightSide) self.__bookmarkButton.setVisible(False) self.__clearButton = E5LineEditButton(self) self.__clearButton.setIcon(UI.PixmapCache.getIcon("clearLeft.png")) self.addWidget(self.__clearButton, E5LineEdit.RightSide) self.__clearButton.setVisible(False) self.__bookmarkButton.clicked.connect(self.__showBookmarkInfo) self.__privacyButton.clicked.connect(self.__privacyClicked) self.__rssButton.clicked.connect(self.__rssClicked) self.__clearButton.clicked.connect(self.clear) self.__mw.privacyChanged.connect(self.__privacyButton.setVisible) self.textChanged.connect(self.__textChanged) Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\ .entryChanged.connect(self.__bookmarkChanged) Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\ .entryAdded.connect(self.__bookmarkChanged) Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\ .entryRemoved.connect(self.__bookmarkChanged) Helpviewer.HelpWindow.HelpWindow.speedDial().pagesChanged.connect( self.__bookmarkChanged) def setBrowser(self, browser): """ Public method to set the browser connection. @param browser reference to the browser widegt (HelpBrowser) """ self.__browser = browser self.__favicon.setBrowser(browser) self.__browser.urlChanged.connect(self.__browserUrlChanged) self.__browser.loadProgress.connect(self.update) self.__browser.loadFinished.connect(self.__loadFinished) self.__browser.loadStarted.connect(self.__loadStarted) self.__sslLabel.clicked.connect(self.__browser.page().showSslInfo) def browser(self): """ Public method to get the associated browser. @return reference to the associated browser (HelpBrowser) """ return self.__browser def __browserUrlChanged(self, url): """ Private slot to handle a URL change of the associated browser. @param url new URL of the browser (QUrl) """ strUrl = url.toString() if strUrl in ["eric:speeddial", "eric:home", "about:blank"]: strUrl = "" if self.text() != strUrl: self.setText(strUrl) self.setCursorPosition(0) def __loadStarted(self): """ Private slot to perform actions before the page is loaded. """ self.__sslLabel.setVisible(False) self.__bookmarkButton.setVisible(False) def __checkBookmark(self): """ Private slot to check the current URL for the bookmarked state. """ manager = Helpviewer.HelpWindow.HelpWindow.bookmarksManager() if manager.bookmarkForUrl(self.__browser.url()) is not None: self.__bookmarkButton.setIcon(self.__bmActiveIcon) bookmarks = manager.bookmarksForUrl(self.__browser.url()) from Helpviewer.Bookmarks.BookmarkNode import BookmarkNode for bookmark in bookmarks: manager.setTimestamp(bookmark, BookmarkNode.TsVisited, QDateTime.currentDateTime()) elif Helpviewer.HelpWindow.HelpWindow.speedDial()\ .pageForUrl(self.__browser.url()).url != "": self.__bookmarkButton.setIcon(self.__bmActiveIcon) else: self.__bookmarkButton.setIcon(self.__bmInactiveIcon) def __loadFinished(self, ok): """ Private slot to set some data after the page was loaded. @param ok flag indicating a successful load (boolean) """ try: if self.__browser.url().scheme() in ["eric", "about"]: self.__bookmarkButton.setVisible(False) else: self.__checkBookmark() self.__bookmarkButton.setVisible(True) if ok: self.__rssButton.setVisible(self.__browser.checkRSS()) if ok and \ self.__browser.url().scheme() == "https" and \ QSslCertificate is not None: sslInfo = self.__browser.page().getSslCertificate() if sslInfo is not None: if qVersion() >= "5.0.0": org = Utilities.decodeString(", ".join( sslInfo.subjectInfo(QSslCertificate.Organization))) else: org = Utilities.decodeString( sslInfo.subjectInfo(QSslCertificate.Organization)) if org == "": if qVersion() >= "5.0.0": cn = Utilities.decodeString(", ".join( sslInfo.subjectInfo( QSslCertificate.CommonName))) else: cn = Utilities.decodeString( sslInfo.subjectInfo( QSslCertificate.CommonName)) if cn != "": org = cn.split(".", 1)[1] if org == "": org = self.tr("Unknown") self.__sslLabel.setText(" {0} ".format(org)) self.__sslLabel.setVisible(True) if qVersion() >= "5.0.0": valid = not sslInfo.isBlacklisted() else: valid = sslInfo.isValid() if valid: config = self.__browser.page().getSslConfiguration() if config is None or config.sessionCipher().isNull(): valid = False self.__sslLabel.setValidity(valid) return self.__sslLabel.setVisible(False) except RuntimeError: pass def setPrivateMode(self, on): """ Public method to set the private mode. @param on flag indicating the privacy state (boolean) """ self.__privateMode = on self.__privacyButton.setVisible(on) def __privacyClicked(self): """ Private slot to handle the click of the private mode button. """ self.__mw.setPrivateMode(False) def __textChanged(self, txt): """ Private slot to handle changes of the text. @param txt current text (string) """ self.__clearButton.setVisible(txt != "") def preferencesChanged(self): """ Public slot to handle a change of preferences. """ self.update() def __showBookmarkInfo(self): """ Private slot to show a dialog with some bookmark info. """ from .BookmarkActionSelectionDialog import \ BookmarkActionSelectionDialog url = self.__browser.url() dlg = BookmarkActionSelectionDialog(url) if dlg.exec_() == QDialog.Accepted: action = dlg.getAction() if action == BookmarkActionSelectionDialog.AddBookmark: self.__browser.addBookmark() elif action == BookmarkActionSelectionDialog.EditBookmark: bookmark = Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\ .bookmarkForUrl(url) from .BookmarkInfoDialog import BookmarkInfoDialog dlg = BookmarkInfoDialog(bookmark, self.__browser) dlg.exec_() elif action == BookmarkActionSelectionDialog.AddSpeeddial: Helpviewer.HelpWindow.HelpWindow.speedDial().addPage( url, self.__browser.title()) elif action == BookmarkActionSelectionDialog.RemoveSpeeddial: Helpviewer.HelpWindow.HelpWindow.speedDial().removePage(url) @pyqtSlot() def __bookmarkChanged(self): """ Private slot to handle bookmark or speed dial changes. """ self.__checkBookmark() def paintEvent(self, evt): """ Protected method handling a paint event. @param evt reference to the paint event (QPaintEvent) """ if self.__privateMode: backgroundColor = QColor(220, 220, 220) # light gray foregroundColor = Qt.black else: backgroundColor = QApplication.palette().color(QPalette.Base) foregroundColor = QApplication.palette().color(QPalette.Text) if self.__browser is not None: p = self.palette() progress = self.__browser.progress() if progress == 0 or progress == 100: if self.__browser.url().scheme() == "https": if QSslCertificate is not None: if self.__browser.page().hasValidSslInfo(): backgroundColor = Preferences.getHelp( "SaveUrlColor") else: backgroundColor = Preferences.getHelp("SaveUrlColor") p.setBrush(QPalette.Base, backgroundColor) p.setBrush(QPalette.Text, foregroundColor) else: if self.__browser.url().scheme() == "https": if QSslCertificate is not None: if self.__browser.page().hasValidSslInfo(): backgroundColor = Preferences.getHelp( "SaveUrlColor") else: backgroundColor = Preferences.getHelp("SaveUrlColor") highlight = QApplication.palette().color(QPalette.Highlight) r = (highlight.red() + 2 * backgroundColor.red()) // 3 g = (highlight.green() + 2 * backgroundColor.green()) // 3 b = (highlight.blue() + 2 * backgroundColor.blue()) // 3 loadingColor = QColor(r, g, b) if abs(loadingColor.lightness() - backgroundColor.lightness()) < 20: # special handling for special color schemes (e.g Gaia) r = (2 * highlight.red() + backgroundColor.red()) // 3 g = (2 * highlight.green() + backgroundColor.green()) // 3 b = (2 * highlight.blue() + backgroundColor.blue()) // 3 loadingColor = QColor(r, g, b) gradient = QLinearGradient( QPointF(0, 0), QPointF(self.width(), 0)) gradient.setColorAt(0, loadingColor) gradient.setColorAt(progress / 100.0 - 0.000001, loadingColor) gradient.setColorAt(progress / 100.0, backgroundColor) p.setBrush(QPalette.Base, gradient) self.setPalette(p) E5LineEdit.paintEvent(self, evt) def focusOutEvent(self, evt): """ Protected method to handle focus out event. @param evt reference to the focus event (QFocusEvent) """ if self.text() == "" and self.__browser is not None: self.__browserUrlChanged(self.__browser.url()) E5LineEdit.focusOutEvent(self, evt) def mousePressEvent(self, evt): """ Protected method called by a mouse press event. @param evt reference to the mouse event (QMouseEvent) """ if evt.button() == Qt.XButton1: self.__mw.currentBrowser().pageAction(QWebPage.Back).trigger() elif evt.button() == Qt.XButton2: self.__mw.currentBrowser().pageAction(QWebPage.Forward).trigger() else: super(UrlBar, self).mousePressEvent(evt) def mouseDoubleClickEvent(self, evt): """ Protected method to handle mouse double click events. @param evt reference to the mouse event (QMouseEvent) """ if evt.button() == Qt.LeftButton: self.selectAll() else: E5LineEdit.mouseDoubleClickEvent(self, evt) def keyPressEvent(self, evt): """ Protected method to handle key presses. @param evt reference to the key press event (QKeyEvent) """ if evt.key() == Qt.Key_Escape and self.__browser is not None: self.setText( str(self.__browser.url().toEncoded(), encoding="utf-8")) self.selectAll() return currentText = self.text().strip() if evt.key() in [Qt.Key_Enter, Qt.Key_Return] and \ not currentText.lower().startswith("http://"): append = "" if evt.modifiers() == Qt.KeyboardModifiers(Qt.ControlModifier): append = ".com" elif evt.modifiers() == Qt.KeyboardModifiers( Qt.ControlModifier | Qt.ShiftModifier): append = ".org" elif evt.modifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier): append = ".net" if append != "": url = QUrl("http://www." + currentText) host = url.host() if not host.lower().endswith(append): host += append url.setHost(host) self.setText(url.toString()) E5LineEdit.keyPressEvent(self, evt) def dragEnterEvent(self, evt): """ Protected method to handle drag enter events. @param evt reference to the drag enter event (QDragEnterEvent) """ mimeData = evt.mimeData() if mimeData.hasUrls() or mimeData.hasText(): evt.acceptProposedAction() E5LineEdit.dragEnterEvent(self, evt) def dropEvent(self, evt): """ Protected method to handle drop events. @param evt reference to the drop event (QDropEvent) """ mimeData = evt.mimeData() url = QUrl() if mimeData.hasUrls(): url = mimeData.urls()[0] elif mimeData.hasText(): url = QUrl.fromEncoded(mimeData.text().encode("utf-8"), QUrl.TolerantMode) if url.isEmpty() or not url.isValid(): E5LineEdit.dropEvent(self, evt) return self.setText(str(url.toEncoded(), encoding="utf-8")) self.selectAll() evt.acceptProposedAction() def __rssClicked(self): """ Private slot to handle clicking the RSS icon. """ from Helpviewer.Feeds.FeedsDialog import FeedsDialog feeds = self.__browser.getRSS() dlg = FeedsDialog(feeds, self.__browser) dlg.exec_() eric-6.0.8/eric/Helpviewer/PageScreenDialog.ui0000644000175000017500000000365212060166052020256 0ustar piotrpiotr PageScreenDialog 0 0 500 450 Page Screen true QFrame::NoFrame QFrame::Plain 0 true 0 0 482 403 0 Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Save scrollArea buttonBox eric-6.0.8/eric/Helpviewer/data/0000755000175000017500000000000012557365360015504 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/data/javascript.qrc0000644000175000017500000000021612060166053020343 0ustar piotrpiotr javascript/jquery-ui.js javascript/jquery.js eric-6.0.8/eric/Helpviewer/data/icons/0000755000175000017500000000000012060166053016602 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/data/icons/edit.png0000644000175000017500000000116312060166053020236 0ustar piotrpiotr‰PNG  IHDRóÿasBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<ðIDAT8¥’OkaÆ®ŠUŠíÍ ²‡ˆ‡BMÆ*^£H$r7N?>€¶2Í}¹\þ kàV‘L” üR˜û§KL—J¥V«µ¥ H&“w•Jå@­V{7 ^4›Í­áp¸Óh4zÁüàhM Y­VDd[D¶«ÕêQW˜ ɈÈ_5Mû±X,BÁ¿Ýn€þŠ?Q©‰¦i?—uήëž†Ñ ævg_×õC]×ÇÙâ†at\×=S·±$èåóùÓl6{çóùÀ÷ý=ß÷÷æóyÐÁ$›Í^åóùSÔa=’1‘H|åÖ[<g4}bŒ·žç¹¹\®_¯×;¦ivy¸ƒ±išÝz½ÞÉår}Ïó\dåiÀ{ ë8NºX,¾8??ÿ^(zÀ ,wÁªeCù_Î:Ðsÿd ]ÙÿmIEND®B`‚eric-6.0.8/eric/Helpviewer/data/icons/ericWeb32.png0000644000175000017500000000615112310120736021034 0ustar piotrpiotr‰PNG  IHDR szzôbKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEÞ xúà„ öIDATXÃ×i\ÕuÀñÿ}ïu¿^¦{ö¥GÌ"‰I£ ‰E€‰á$ˆ°ƒeJA"0Ø®€)ŒƒÄ؉1å8 HH$Hb˜Ñ>3šž}íémæu¿^Þ{7•8‰Ë„ûõÞ:çWçÔ½uàk¬M-¥váIN¼‘úÆz:[ųÏí•ÿóœ”Rîžý[ôO߸®z*îD8_îŸÓØ„ø:€öÉföniQW^~ç×/¶¿LöÛ·¬ÞÕ¼÷¼±ÑØeAót3oVº‚5¥s‹ ªüQ¯«${*@õÖE·>µiçëòÑ_os¾ õ𠜵r#ï>{7WÜñ$ïo{<`ÈšyqÓ\9™ø–Û#Vù\•õÅ¥sÔÚåu MMIÕk9]Ç_Eäß‘eâ\Œ¡<íÇZµØ¨ÿ'ÛŒ>þ——V íO%õ™»9kåFž~x½rÅO:rø-ß ûßÓÜbÜ’/¬NÖ ½bÑ‹«ë¨Xp6ñ#R̦ùð•‡ÅÊššñQõÐN‘i*dš¤f_<žhŸ@ýc‰ÿågÿŠ5þ usBìø¸ÇŽ\¿³£óž}×yÆw;·ìÑVÌшçÆE~ÜÏðG¿g²;,<‰)ÑÙkð­oüq³#a G’LweIÄ5¼ºÚ~,œ{¹a9âŠkÙþþ(;>ngrøµÐ=·ßö¢ÓÔô€kÎ’ÒÖ=Ͳ­µMîÇ>;".¸ú›hZŠ ¯jafP§øê‹±tI´õÆñDm>êÓ0L‰ËçÛÚ5˜Þ}ñ’Úÿ»[v=DwÏ)ñòŽõ+æÝyÿ³;.øöËV‰ÉvÅŒ'D*ÀJ[¸Š!Ts™÷£ùÈ'òìÞ2LI¼‹‰îu9•þ¡,ÒíbÑ ™S)/f!œy¥ü/Àûû~ÁŸ_ôCùÈsæ¥DÙ® 7ü !&]²çÍ7Nf Ϋfê@YÓáÌKÑ{ÜCotÿª…¸˜¤ßÒ´ ’Èd”S޲:¹ä¦aKiçA3 àÕØuè1V. ˆ­¿º­¸Ý£¾¡.½x~óoš±Ûw‹;ﻚwÒ )X®à÷)s,8ßÃÒåY¢¯dé{wáÕ)ÍÌòöïÄ–•`™QˆfñæÂÑ…k6m¦›×ŸÔV¯ÿ®¥üwÀ‡gd(+þRñ Ïiz1Ö_µ"±åqÓºjn~n5)ß&ã-\tÙTé'Òoõ2I:ÝGÛÖQ¦÷E9p`”³n)Åe ‘íÍ’H„%e6W52ÏÿvkbøÒÖÚß\yXÙi€ï=ýôc©3K.ÿ›MwH­A-ôqdÏÿþ‹f ½iâmÇ)¯N²jÍbÔáqÒýÚ¬E¤g–ðd„’F}ÍÃäÆMŠU ·–“fÊ^Õù ä=íQ€›ïÙ,…ÿxóùµDV>)Þi~ð¢@IÁ*kÊ¢ó½OhâUÆûzÈÏXÈx†ð¾# u$ &iÛ>Íè‡INF ¤iZ9KM`šÖ ÌŒd&-ä¬åª‡íMsŠÖýlÛ@ê‡W–±ëµû‘R~ñK)iüézï‘GÞ»oïŒ,¾hòx zu}z‹H0$s]Ô”+|²;BU©‡}Ÿe¹áÞK?ºŒò‚*|~Át$KowšÙB±x÷¦ cW®Ø€ ðƒkØøx3b¬ëzªŸÙ¿‚Û6­ [þíÑñ™î>$àøl–¯®À¶ ZÞdQ}1f|”cG%Egx¨,¼†Pñ%,jj ¿?ÊtÌ`t4#¿Žã8 hÝíCow´ÜóýÚ…¿S†ºoÉÃÀ+_T y¼G¹¤ªAþã‰=;zÿó¥%‰¨š´},¬àØÛ™øTâØEn_²„‘m“,;ÿajjëYuÞ<åT”ƒŸ S=·œ²ÒÆÂc¸UUVÕ—K;o)GõjÛ³ýÛÙû²õªtvóÇ>WÖ,4.8Ðqü&>ýPX3Q1qbœÈ`CÑ9Ô’¤ðÜjêΪbÙÞ²Ÿtdèçf’Pæ6ÉIJiI·"IǽÌ[r3ŠîEuë\uùb¦b†ÅälŽºúrLK"-‹¨a±´±Œ±˜AÚÌcf,qäÐ)gn}Y“ª½ÿƒ·þv@ØKëµ'¨:£QÊ`)–WÅå†ñˆ ’³Ðs’…k1mnΕ—518n j*RSX¶¸š’?.¿Nkœâ2m}qTŽÔTÝEÊyŠ»¼È*.+¸@‘²K;x`èÚyóWÛ‰ð^Òb z0Ò+«`£`ÎJb³yôÂJú#sQ]*½Ã ¢3Y„ª¶$Ž”ÔÍ rj$N[oOÀKJ Üáqc« †iQ*"Xtôï Ÿÿö µîP¹í;±ï ÂÇÇè 'ð:y<p4‡x"G6ã`IûQ]^>jâpw„¸‘ÃåRÁ‘T–úèˆâÖ.Zu"ŽÇ…âu£x4T —W# RVìÓ<o•Ë[X£ÝûÒ½zdJV5È’®1&'¢Ç!ãE>—¤3.ôr±”…‘È›Íb Æi뤪¢)%¥XRÒ>™Æ#!ŸÍƒ86(ºÕå">mEu )åÑ›Ë_¶þ¯3Ÿo{—pgGu#M›`&‡® ¼ªƒ°AERZî#7Q] ‹Í»{ðû],o¬Â:"&ouDMå™¶¯ Ew#Ÿ?Öuý£mÛæŒÚ¶mêºþ!ŸÏû÷Ùx²¬S  \išvY­VªÕꑦi—Àе,ëTD.ä[b:•J½ O…Ãá9€Rjø „’Éä¸ß￾G¸õ<ï"“É\ `¬”Ò”R0™LæÚó¼ àv…g4F£Ñ‹B¡ð¼×ë=ó'LÓüÚh4šñxü0{h‰w­V«·\.÷Ö]üñÕjõ´Ýnw;?àï Z¯×Êåòk¥”æñ]]×µZ­ö®T*}~Ò±XìÍl6û|Èf³ß:ÎÞºæ±a;Óéôíß–8¯T*ÍH$2¹\nè8Îã87¹\n,"‘ȰR©4ïuç{ˆÈ¡ëºgÅbñ|2™œˆˆ!"Æd29)‹ç®ëž‰È¡Ÿ "¦ˆ¼\Û˜±Ž™ÁúàÿÛ¶þ¿|R8Ž×ÈIEND®B`‚eric-6.0.8/eric/Helpviewer/data/icons/reload.png0000644000175000017500000000142612060166053020561 0ustar piotrpiotr‰PNG  IHDRóÿasBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<“IDAT8•‘½OAÅgá–»ó%ØFá‚ ‘,E8BQ”!¢£€£0%2DHüT–()LE® À z  FH$ޱã#·ÇÞÞî^ŠÄIÁ+gÞüôfe³Ù R¡8^\\„UU…ƒƒØØØx7??ÿejjêú>„sŽÆâœ7‹+++nooÛ—––*ccc.ÀÉÉI["‘pæææ>%“ÉoÃÃÃ?c¨…sޤ” ¥„³³3£\.G§§§k–e]©ªZPUõjhhèG&“é¨V«Ñõõõ÷žç!)%pÎQ c I)a{{»kkkë­iš€1öŽŽŽ$cŒ3ÆØññ1ßÝÝ™¦ š¦iét:.¥l&)%BÂù|¾K×uØÙÙ1MÓ É„mËËË]×avvöz||Üý›”Æ 333%xq~~þrqq±F])%ôöö:™LFÕuúúúʺ®ÆØŸ#6®ëÚ–e•NOOï"‘Hymm-Þßß_ÁË\.÷ÆqœÈÄÄDc\§”Šæîc\¼Ëf³†mÛ›››¯LÓ˲*‰D¢ä8ŽxðFß÷Q#ªçy¾çyµÑÑQmrròëÍÍ ¶m[éééñB¿lÛ®5¼¾ï?4D¡„iضí;!‡Gò})pY(ÂÝÝÝì±B€>®‹Å6¸TB¡Ðêþþþg!Dì_Æÿ©µµõ2¯þGx„Ь'6IEND®B`‚eric-6.0.8/eric/Helpviewer/data/icons/adBlockPlus64.png0000644000175000017500000002004612060166053021667 0ustar piotrpiotr‰PNG  IHDR@@ªiqÞsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÜ#/«Éå iTXtCommentCreated with GIMPd.e}IDATxÚÍ›i]×qß}îú–ÙÄ3®"ES %Ò‘DSŠ-‰‘­¤,[RÉñVrÊ©äK*R‰¿8I9râM’cK±UMI´ÅE$A D €(B"Aû:3f³¿íÞ{Nçùo0AívåVÝyoîöN÷éþw÷ÿô…s{ñÅùÿeûIÆþ4pàÀÞžžžŸ7ƼNDzû$k ªËιשּׁ¬<~óÍ7/ÿ¤”ç¦={öpûí·ðõ¯½2::zo­VûpE7c"@E‘+?þòãªúŠ¿¥ªëÏ‹s.Ïóü@£ÑøÜÔÔÔÞüæ7·.Ó?êöàƒ®}à’ãÇèܹsß\\\l¯6Úlµ´Õnk»ÓÑN¹gYæ÷<×,Ï5Ïs-ŠBó¢ðŸëŽgy¾v}§ÓÑv»­­VK[­–6[-]]]Õ………ö¹sç¾yüøñ=ðÀÉ•Æö²íÙ³gíûý÷ߟ>|øÝÓÓÓ{ŠF£¡í,ÓŽµ.sNs§Z¨ßm¹»r¿ÒæÖíÝë UÍU5sN3ç´c­kg™6 ]XX(¦§§÷>|øÝ÷ßz¥1þT]`ÿþý¼æ5¯`çε͛7¿¥^¯ÿ§JµzGš$ˆˆ®œ<Áâ±ã’5VA¸Ô ŒÈÚ/ ‚^´s\AýNµ¼FA•¸V£oûvíݺ U•v§C«ÙüÖêêê9{öìSwÝuWãò±þTðÝï~—[o½µëóõ‘‘‘·V«ÕÿV*ÿ,‰cDUWÏœ‘CŸþ3ÿÍçX™]êʳöÙý1Sþ¯Wˆî²ë×?£wC×þÚ‡¹þã¿EmËEDÚí6ívûéV«õ‡çÏŸßù¦7½iõò1ÿØ xî¹ç¸å–[ºÂ÷ŒŒŒÜ]­V/MÓ;’$QPVO’ƒŸþ‹ý==K3ô×PÁµaÍ€- ˆ ®P4WLÅ[„m(&$\îp˜T XuU¢,®vX黊þ»‰ë?öÔÇ·ª t:ét:ßj6›Ÿùä“}###¿R­VÿMš¦wÄqŒ:Çê™ÓúôŸ³òèWéYœ¥Eh¢$a* ‚m9Ô*Ö*ˆ`Rƒ©ˆŸÝLÑB¡ðóm"!HTq™Wõ †Å9Vÿ*Q®ÿØoR'ŽcDäadd$}òÉ'¸ë®»–~"XoBO=õTÿèèèû*•ÊG“$¹-ŠãX@›SSòâÿú$«;¦gqj(„‰Á„NÐŽÖ XP«˜H0¡ÈŠI½áÛ¦Ã$”`)§¦h”–b—+yæhZe¥g€úÛîæUŸøÕÑ1uª’gY–eÙ·[­Ö_OMMÝÿ–·¼eñ¹ƒ¹ÒÁ½{÷®Ý°{÷î¾M›6½/I’ÄqüÚ0 c´gÎñü'ÿˆ•G¢oyš¢ÀƆ°xEX'ˆ B¢j÷œÁ8ƒq`ˆCTó ðçÅ ÆùûÂ4ð÷†*BïÊ+>ÄOþíóç€(Šâ8Ž_›$ÉG6mÚô¾Ý»w÷Üzë­ìÝ»÷‡³€õ ÅO<Ñ;66öžZ­ö±$I^EQ%®VY:vL_øãÿ)«ýýíúz" ~Ö%‚H¼ßçJT7¨ïó÷sµ LÕÛm€ @ÐBQ§HäÏ+Š$ \®¨U4çË«9‹i/µwþ"7ýÞ¿ÕÞíÛ%k6)ò¼Õétžm4Ÿ™œœüòÛÞö¶åWJ–ÌåIN÷‚§Ÿ~º>::zwµZý$In‹¢¨U«Ì<¨/ýéŸÈüý_d ¹D_5"L‚Ä`Œ`Há÷01„©!ªA(ˆ2+‰V„0íž$SÄy°ŒªBX 0ÝsÄ‚ „¨bˆÒ€Þ4b ¹Äü—¿ÀKö'2ð F• aU’$¹­Z­þÆèèèÝO?ýtàöÛoY²´¦€;vð®w½«;óµÁÁÁ·V*•O$IrG†± C–ŽÕCŸþ”œûì§Ù[ú{R ^0±B`„ 6©!H bÊ=ñʨÂTÛÝ zÓê†0Œ äþ¹Æy%Eã]G J·2ô÷$lI•sŸý4G>ý)Y:vLM†aœ$É•J僃ƒo}â‰'jïz׻رcÇEؽ{7wÞy'÷Ýw_zã7¾µV«ýÇJ¥ò³išh{v–çÿûÿ¥¯|-©£·žà¸†bbB!¬L"`¡˜q5‚BØT×VŠy‡$”±N  ’ ¶©Ëµ l‚aAÅv”bÅa3§¦ÆK«δ„¾wßëÿßi²aét:´Z­o6?x饗v~àh—ØÆwÞy)|æ3ŸIÞð†7Ü]«Õþ}¥Rñq^•Ö¹sòÒÿþ$ÍGb°¹D_oêýY=¢‡5?Û˜Ø[ܪ °>"˜T¼r:Škƒéó?o—¦f\GÑÌc€3J~Áôy|°m‡Ë5Š Ø†+ñA°™ci¹Í|µê;þ7üî'¨lQDèt:Òn·¿Õh4þÛ¾}ûþØÇ>Öé‚}ÐþóŸÿ|í–[nyo­Vûý4MoOÒQ¥qæ ‡ÿâO¥ýä£ v–©G1dRš¾$†°b"ƒX¯)@r!¬5ã}ÜúãtJw©‚šøYx¥Ðñ…´‰»çüs4÷€ª9˜Pj‘Lsœ¶II‡Õé)–fç鹿ZâÞ^‚ ` °uxx¸qçwûÒ—¾”üã÷ صkWÿøøøûkµÚoV*•7$i*¢ª«§OÉÑ¿üŒ4„¾ÕEjˆORÂÔ ÷ÓÀx6øãAEA²®€¥Ï¦†°ºî˜Ác.„UŸ˜,Õ+͵S÷–#”ÑÅQFX0±÷$Q!D0­«§'Y^^‘Ú¶ ‰ûû5Œ"‘ÍÆ˜Ñν÷Þ{âMozSÛÔjµ·§iú‘$I^űAUWOŸ–cõ—4¿ö= óÔÄÇd)ãy‚¨¬2E€ o¹Ÿm)„©öúˆ!˜B\0…¤¦<·.">ª„iie©ñJè…È t¹0ñ.i ñyÂÒ­Çæøgÿ’ÆéÓ‚SâØ$IòÚ4M?R«ÕÞÞM… ðú(ŠnŠ¢(ÂåcÇ8þWÿ‡ÕG¤oqžZÆqZš$>Ý5„„~vÈ@µt‚äâqɼÏKî6U-]¦4)„ b_-š–6¨QÈ|.a"Á¡`w )Ÿoð–G@Í)nþË=ÈQýWôLl'Š¢¸(Š›€×qQ}"c@DÛ'OÊüß}‘á¢E=Ž #´ t9CãÒLC$ÂD1¡Ÿqq¾À *^h-4ÛÐt^qÉÅòX A ãCI€Ô Š¢+ÞÇÅx06ƒ¸@-hË¢Nq؆…HT1Ô£]œãÂß}‘ÖÏÝ%=×\£Æ‘¨(Š> 8Ë2QõÄ“‚„í&ý óôŽ `Ô›–Ïç ÂÁaÒ‰ ¢:¸²Ä5nz7wCAxÓ'/wëz‡¶lÁ ôAáo4õ²4ž/PÍ káfçqó h+G‚2®{s“´Šl¼3º WÄ«5@EËâlÚ6ùâ":=‹..Ð[)Î϶[”F‹ªj–eD!äy8ç¤Ë¿Å¡¯x@Rïoê»Ú¦þÖÛÙô_ÿ€x󖵺½8–åOý9ÙοǴg0•±·AÛäw~Ÿø–ŸYG„ød\[ tùnn ûì3äOîÂ>ˆ[mùz"58-0›F¨~è·©½óý\‰E´««äg§i¿t€•§v±úôN²¹úëIhÖøEçœäyaWb­]w¢ÏÙ¨÷¹0lT%ܶ•xó–K sÕF‚m[¡§mÌøJ°L[ƒA¡ÝPZ©_F’  •¦R#Ø8NxÓ„?w7ÙýA¾ëaôxqàTÈ3%*ôËØ°^'¼ö:*×^GÏ[åsþÏÿ˜|áœskòYkÉó\€À\‰•U§h\Ç—­PW]7ArÃu/çªÅmÇ oĵBܬC—” Ïc„‹¡H¬\¨µt«tš«­êÜš`Áæ­„ï¸Û‚é °óŠqä‹ÛÑKcçÎY\yÿzeô½ý]ô¾ý— z6x^Ç0w?ÃKP^ ‰}üV .ËI¶l'Üví•ËÊc˜ñ«áä ÙªWm â“²’ï*…l.-pàïïÇ9KÚ;ÀÆWÝÌðÄ5Ä•*›®Æ¿ ÷“½u†¢f ”õœ9ó§O2úÎ9êÃèßîwJî° ¢ =aÄÕÕYµÎªdçOSLY{†ˆàzú!м`åñKÐEÈõ<‘¥ 8ÁYˆÆ'GFQàTÉ—YÙû ==ŒÜò3„iŠŒŒ"Û&Ðï}i´Ð\SqmÅg 8Uˆdâg°j‘± µ[߈Ù:1‚Zæh6m¶p}ýWm$غÛWAŠzA±@ÑöJP§ž÷·fè*¢ýgT‰«½}H­ŽZËÊì Ó_ß ¹…¾²hJ ý3œ:T„TbL_B u¢‰›¨N\‹-1­óÓ­f¹£/Á®9¬s-œSœ*b•`ë±Q$MQ 9ÙýÏ0”w`ò ÙóƒƒIB°a3²a nfP‚Á4Xãñଃ0F®¾Æ'BêñAŒ¡½ºÊô³{9õàÿå:½€)|Âé›ì•è­6Ù 7ÝŠoRÍÏR¹ë牷MಠU¥h·)&'¡ÙòT ~eЋ hÛŠi;P%Úº Ù´E8 }áö|›Í ¡h.°xâÉè•8Áö_EgøzÌܳ¤ƒ¡¬QHN¶4Ý5°Yó9Y‚´ÂøëßÈUí#_ø3hÏRÌZ²Ž#7ޏeK%úÅ‚žŸ{'¼å<(A­ÃŠ EÁ‘]OÒ8rœ¬À³†w—¸Àå â«;‰Ôm%Ú0‚D1Î)Åü,îàw"GûÜ ícG°¯¹ í ظ‘èÕ7R<êC$lÇ+ÔY·`•e&Ÿý6ê,Q¥Nÿø8Õ¡aÂ8&è òÆ·Ò9}’âÄ §© R÷–¤ës— D¢è²üR±yÎÒÔ$§¿úeÂéÓ]Ží•0à–\ãWpdh˜hË8¦V:ùò}}½D7em\'ÃÚSë!¾z+ùUCØãã(Zê©,«ÞwæÌ /|ò!ÏP õ¯cüîfì¶7QBëýØW½‘œû‰¢2"E Oջآƒ- ¿ŠdE–ÑY]á±cœzôaìÓ»©µW LwaV^ž ^´€u(Y(Îz ¶l$Æ6ÏHÇÆÙü¯—8Љs£c˜J›ç¾,îÆNÜ„œØE_L)꼘¼Íè…cÄyF¶liÎO³ÚÓKcl‚´A®žÀÖkHc™"÷i°+ÜÚxsœ?tˆ¹CÉ[-lž“¯,Ñ:ŽÖ‘£Ø°¡µBT¸Kîû$Bëò€¬â‘QÂÍ£FØ¢ÀˆPݲ»Ê'p…÷KWnÃî|‚0 Á @qk³Ø6T§RtÈc1ËéÌÎâ–—p(*BÐßOÞ× ç°‡m+6/PÅ‹Ï}—éø2í¹yY ]Z"^\fÐ*õ(ô9„»X€þÀ<@}• Ñ–qÂAÔp CLœ¼¬SëPg±EŽÔêD7ÜL;HÚJÑvå̕ŋúÿ󕌰ÈqmKµV#$©V±…-RhK@P®««(ª®Lݽ5…ó³ôŸ@ÿ¯¼í Ùj2;;[LNNžœ™™y ŸŸ‘,--5’$‰£(Ú˜&ÉP¥R‘ VÓʶ 1¡=9E±´„+¬¯B_W(þÕá[[$LY›mšy¾‘$6(P´|2Sä>»3iIx¨ÃåŠÍÖ*.s¾I**Á«¼ÞZ%‚.Í¥ØÂA’^½ ÷ÜCÿ{ÞƒëëÓN§#gÏžÕC‡yæ™g|ì±Ç›€`vv6?räÈ\¥R!Š¢‘8Ž{z{ÅT*Z¸•ìì4ùÂ"Xw‘Û+Wj%ñ@ÚõAë—³%dÍ'3./A(êÆd]+Õ»5ˆQlÁšeØÜ·ÚiÙWáMÔ ¶Ì0•m ¿ÿý ¾÷ýêzûÈ­•Ó§NqàÀcßüæ7¸ï¾û:}úô t×gZ­V~ôèÑóI’´â8ÞÇñP_?RI©Ýp£U:“§Éæ.¬ ®V=mfÀõ#¹OB\îÛâ$4à³h\®?S—MQR —•%s¹!!hÙPtE®¸R„]Áý3»3ïÔQÙ>Á†|Á~[¯SXˉãÇå¹çž;òo|ã‹_ùÊW¾¶´´4‰ç¬›Ý Ø,ËòS§NÍ…a¸œ¦éXÇC½ýý"I¢=7¿Q¤yôùüL–ƒ×µRç…’ÐÏž+Ôwº‹3)QIKY ô”›íøõ=¨ïv@Ñ´ÞRY‹ï]X( ò*ŠítHǯfä×?Êð¯ÿºiJn­t…ê©§þæ‘GÙ¹²²2 ,-Àv-À‰ˆl§ÓÉΟ?¿Çñjš¦›*i:T­Õ$¨V¥vÝuU*Ò8tla¾d_çk=å,ë’—— T¶¾xA½9{ŽÀæ´$ô„sJQ\êë]Å8õîQäºfòŠbÛâÑQÆ~ó·º÷ƒjk5i·Z2yæ Ï?ÿüá§Ÿ~ú ;vìØ½¸¸xX‘ãù•‹@©×jµ:333 •J%‹¢hC%MûÒ8â¡!©l½Z£ži=J¾°à™ó²_h­Þî"²+Áò"ÃîùFëÏ©xÌpv]ü¶%”O²¥…u…/×6|Áã|ZŽ_Í–ßúÞû^ehHV™ššÊŸþù#{÷îýòã?þÄÜÜÜ©®ðªšwÓ°à²,qM F#›™™¹P©T\ÇC•J¥/ ‚ –êök4ˆ"i>C¾¼äëpü´»nX*­7yçtM@¤4yñ܃³ž,í Oèâ-W†8Õq8 •­ÛÙüÑÉÐ=T‡dùÂgÏžÍ8ptß¾}>öØcž?þô•„¿’ºJp~µyµ3777—$‰‰ãx0MÓ¾$ ƒ¨·Wzn|•ªuÒ™ž&_ZB ë/SO_rz%8Wæûî"%Ým‹wO”–×».uŽwkuÍšÜÅåm4ˆ¨l›`äÞ²ñÃQ[«ÉÊÂSSSÙ /¼ptïÞ½_Û±cÇ#ÓÓÓ§€i^.ü+) ›¥[À.//·fffæ¢(’(ІÒ4¨V«Æ$ õo£ŽöäÙâ’oP0¾')sƒ¸\¹æèC¦ŸYÕuQθgzÜÚqg=vx2D±ÖÇùÊě ¿ökØ4¥ÕlÊ™3gŠÙ³gÏ#;vìxxjjêx x ßåðò¶‚ï§×}aee¥1777†¡ ‚`Cš¦Ã}}}b’Dë×^‡ÁHkr’ÎÂüóë\Yú®•¬-¾j×Öz¼Ç;Ul×UºîÔÍé^M@uûµl¾÷WÙpÏ=êj5ò¢'Nð½ï}ïðÞ½{¿ºsçÎG¦§§wC]ð®øÚh§ï*Á®¬¬´.\¸0cŒé¨êÆ0 ‡‡††4¥¶}»A@{jŠöÌœOVº´šñMS—îÊÆ¦òµ™®•X«]HdÍ œúdÉ9¨_w=£¿ú!6¼ï}ho/…µ ,•Âg¯$ü£€Ë•Ð9þüœ1f%‚Ñ †%¨Õ´¶}»aHëÄq‹‹Øòý‡Â*…ó»u¿ÖïÖ*yynýù¼<_¨_¶@ï¶­lùÈGÙð÷£}ýšå¹¼øâ‹²ÿþÃ{öìùÛ]»v=Ѽ2ÎçßOøö i©*sssn÷îÝ;­µÖ9÷àºëo¸Aª:üž÷0tûíâ–—¯Ü/ëè+tîë%/ ]²dÙÛ‹lÞ¬20@«Ù’Còì³ÏÞ³gÏg¿ño잟Ÿ? ,—c-~ð?Ê+3NUsßL6??jçÎOc"ùÕ0 ¯Ùºm›éݸ‘x|\ƒ KIÓõ 7?hLòò7­JªÚZ«Y§#Ë‹‹œ¿sçÎ'WWWÏü¨Âÿ¨¯Îªª®YÂêêêäã?þhI†ï®Û²%LÓn‘¯üT7¯Pi·ÛLž9Sìß¿ÿè3Ï<ó•ÇüÑF£1õãÿã¼;¬¥% ªÒh4صk׃ƼsiiikOOO¨úÓ–~mÍRVVVŠãÇŸÜ·oß#»vízð2áó’w‡Ë-R wlllëë^÷º;ûûû_AÝ9§?ᳯ¨|cŒXkW_üÎw¾³{rrò$°ŒoÇÊþÉ^ž^woXöÕ V*&X÷.äOEøuÉYV&6+Àj‰ö?’Ù¯ßþºÉ ñÓC…/IEND®B`‚eric-6.0.8/eric/Helpviewer/data/icons/adBlockPlus16.png0000644000175000017500000000146012060166053021663 0ustar piotrpiotr‰PNG  IHDRóÿasBIT|dˆ pHYsMœÞöœWÒIDAT8m“Mh\U€¿sß›éÄ!ÌLLÆ*"¶©“D £bÁ,Ò5…RZl¥qWèÎÅt7‚.¥KË ÆEÝHJð'ñi¤†Â˜ÐÄPM›Wócà½äÝ÷î½.§±zVç8‡Ãw„{biiÉi­ïmÍf©T*²»çï.Z­–ÛºÐÀŸ¾ŒÁË΂µ§[ÏÑjµ\µZí@:ÉÌÌŒSÍ Ü÷íWx"tíõ1ëDðïWlßJ0ÆÕcNŸeddD:€ééiç5? wvŠlÆÃ÷?ë¡< V&µ$;Ö"=õ&µZMdbbÂu}úå«ß³™6cïž {º=‚m‹½]BYV¢‹£”:ô³/¿v=?|ƒ8!=ÆØBÀÎË'YÇ¡ÙßyáÇß(¼{‘+[ GŽÎß"þ=ôw_³ººŠ Ã% ²Báñ§ØÙÜ û‰*n»}žÏÞ8ÆÃŸ#ßßÀøé“<ýú6J½„aØX k‘¡o¸JëÒ8½ƒÃü© išòÌ[ç¸sc‘pùÒ4%×S 5gÌ]€î(Eq…k_¤{_?··q³|m–\߃¨b8Ž9òÎûüÔüâæ:Qá‡aH’¢G+X¥8Þ¼„rû µæçOš ¾z ?_DkÍø“ûDèCÚDQ„N ÞÀ+s-¦Î¿Ííëó”*Ch­9ñù7¯^aãú0;a~…†‡ˆ‰Š 5 ‹ h TCn‘qy)Žn |=?›o¦l,©Ÿ?¢h¤±x™›’”b–’»ÀÅÆÇÈɘ(Ìp< DÐ#¬'Õj§&×\Ó&²#Î޸ʈáÅ߯ÛÅêÀèÆæäñ&!ù ,67ÍÈI«½8ëÍ»ÿ`(Ždižhª®¬0 [ DMIJ8ØÄë<ßD³á† É4)Î”È›ŠŠ5kgg–¸5/Ü;‘ÅÉê {#=Sï¦|N¯Ûïø¼ª`¨ q?g€lZ)}<gCŒ6A‘’ˆC‹<Ž™RHgz‹¤¥«¬­®' 5 ¬ ’ #‚#—µTF%²— !$¾5Ç•ÉÊ!š$Ä’ÆÐ %½—Ày·Œ¹H»±³Û?Ñ«ÈèÍ«çìׯð+!ù ,67ËÈI«½8ëÍ»ÿ`(Ždižhª®¬0 [ DMIJ8ØÄë<ßD³á† É4)Î”È›ŠŠ5kgg–¸5/Ü;‘ÅÉê {#=Sï¦|N¯Ûïø<>Žä_ØZ*€gH…‡?‰ƒC~?‘z”•–—˜™L5nR'g !#<@]&«6®a°±Wj%ª<­W¢ 5 gC ± ƪÉ?¶Åy¶ zÔ5ÛÜzرÚyÓ¶Öy˫͕ÁÃç"!ù ,67ÌÈI«½8ëÍ»ÿ`(Ždižhª®¬0 [ DMIJ8ØÄë<ßD³á† É4)Î”È›ŠŠ5kgg–¸5/Ü;‘ÅÉê {#=Sï¦|N¯Ûïø<>Žä_ØZ*€gH…‡?‰ƒC~?‘z”•–—˜ 5 – <5 ”¢6Ÿ3R"œ§ 3j ®6_A!´5¶]!­§°n²¦®©n«"¡¢¤5H›ÆgҔϢ•´ß®•Ü<Þ”g–Üê™(!ù ,67ÌÈI«½8ëÍ»ÿ`(Ždižhª®¬0 [ DMIJ8ØÄë<ßD³á† É4)Î”È›ŠŠ5kgg–¸5/Ü;‘ÅÉê {#=Sï¦|N¯Ûï"D¢–@à+ <5 ‚6~?q{ˆ ‹j6?g•5—AŽˆ‘9lZ‡Š¢R‚„…†Ž}®²³´µL5³g¼QK"¹‚N“ •&˜!Ê_!Ä<Æ3Ègk©#ÄÚ¶Œ²£´Ì²è®æ´äâï'!ù ,67ÌÈI«½8ëÍ»ÿ`(Ždižhª®¬0 [ DMIJ8ØÄë<ßD³á~ˆD-и`C€‚WSD9ª­9{?J-!1ã};b[ig~Òµu0Ö’IÅÚ›æâ½#STVWXaL…‰Š‹ŒW5Žl5”CO{‘TœfiC˜=¥b§s <¢?y7¨Q ¹•ÁÂÃÄÅÆÇ»(Ê"³žD¤@m'·#Õ&×!Î'Û#Ì&ßȉáÂÝÄÙÃèåÑÅäâï%;eric-6.0.8/eric/Helpviewer/data/icons/plus.png0000644000175000017500000000166112060166053020277 0ustar piotrpiotr‰PNG  IHDRàw=øsRGB®Îé pHYs¯¯^‘VIDATHÇÝ•Mh\UÇ÷ã½—é4iZ“`Û€`Áš IˆPÊC»p“…bA+êB°¸² ndÐUK-H7"HŒ º E¤☊)¤’jmJ›´˜Ä±Ó™yóÞ›÷îuQ,äc1ÁnôìîÇ9¿{î¹ÿsá¿n¢™MýŸ>ÔÿÜ#/}8¾ðɣޔÁÁ®ÁÉ¡®Co<»ïÕ_·Èçóv³M”Oóî‘÷™-ÍÚ˜0‰(Ý^e߃›õ}ÿ^\½~1ŸÏop¸¶gŽo tt)^µÉù/Xœ-o|ÍXov‚\.·&³‡?ÚõCl¢ßj«ÙD3/¯ÎŒå&×ùm¸ÝL RcH­!lÄ ÅŒi®ÈMLj0XjqÚtJjìý$Æ$ÆêÉÝ Œ4$©I¶8;s¶· œë<§ùÞÓZh)ÑR&‰±}Iš6B¤ÄnŒÅö ~Þ=íi­­Ð»ÌOÔöìg¢øYÏ‘ÝG¯¬Ìý9÷Þ©ÇOQeŽÆOJ)‚)Y7cƒ0žòìñÞ׳J¨a)$Z*¶9Y¶ëí4øêÖØ;À3k£—F‡tôp£r…bXDj…R ”D É\`DÄHÓ+“B HZvŒQü²tÅE^a)(<¹áŠ‚(°—W~&0ejie%ÊH£pÔÝl”TxÊ£Eµ q©ÄU¾ûã"ó¥[T¬i§Ö¨Ò0éÆXcǧ.ëéìÁSmh©ð”‹‡‹FÑêdìÅåóÂʘ¡Î'l×…š¾з«‹Å•ŠBx•Ĥã›Nd¢Ì±©ËSÝâ  $‰«TßSûG²Z[2n–Ûõ¿Ä— çkž#g]¥´«®ÖìŒ:ºÛ»‰hœØøLßfådþ$ù|žÜ›¹{ µ€9c§ƒ$ÖŽÄÓ’º HL2{ó…Êck•ü²õ}ß÷Wþ™“M)Ù¢«q‹E)AdBRÓœ†šS²5T¢ ©’qQ\%i²W4ÀÀj½Œg"ê6‰Hí¿¬ïŠËQ\bKVt½ÛºÙ[ïx-÷¼Ý2`}?˜[þé-²P-aRM—ÞÓêà÷û÷çË{ðÐÔ™ K¿´{;ê‡wþöÒõ_Yx«p“ÿ½ý ö½u;ê~‰IEND®B`‚eric-6.0.8/eric/Helpviewer/data/icons/ericWeb16.png0000644000175000017500000000205412310121020021017 0ustar piotrpiotr‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEÞ ®µJ=¹IDAT8Ë]Ë[L[uàßÿœÓžvmiÁR„Ê@.Ç1gœf's/Šq,¦‰,sÉ67o^¢Ìˆ¸‡=x™ K4Ñ8†:¹:„k¡-Ð ¥í¡zJÛsóÉ¿÷àê¬öx°±ÐP¿i6UÕ?"æ«Í¬¼dÍe3‚syg¢§{6Èü¯ÿtîsŸãÙð>ÕN´ò»W:ˬ•ͯ/rõ­yåáLòñØôv„-’1ì9‚Ã%–ƒ-._¬Çõ;à0 9ÖõÒ%^o|nˆfm/Q{TÀ®_@iA¼SØ÷€Oˆ#¶#Å-hîØqþç^´µáÀéÛ½·rZÚ?v¸ýx0õç¶Qz’bRcÚ1‰¹¿ýð+@ÚÄÄ>¹±’¡Ál™JÚéSÕ7tž¥£±"(‘•ŠRäéNx„—xç7@ËéŒV”i£JîžsŠv‚¡/€¦wðõħoéŠm½®á)rÐÉÜ^Hû èòSpü©È²"eÈ¢o\{¾¼«ñ£…À¼2šýýïwÜ™‡š6®Žúeæb0›O#»ð„=#|¾ˆ²µµæ.k]žyÓÞÚq“ÐðXS˵‘oOˆmRö± ÑT‘Ó8V݃'jÚP]W‹Ñ‡”T+,ÆÒCæŽè^ÍôÄ\tßâmSDÅöLõõ›£~ž˜shD–}(P¿ä4áåÖ*Ü›t—LÎ{É’3DhZ¥¥”žú¢ŒùTÂccX 8_› 1h$‚8}•5y(‡”@cÄ«†Ö’…Í8a²³Š¬å¹T8°^äx0)QSd±==&–Dž†'Ç6ÇC¯g{РŨ£Ó’†£%ày±™áœÁHhf/ hU5Z!Äî䔌ÑC” ›¼€$Ë‚èµ`)‚Õµ d1“bª¤èýƒå3)·¦œdÐè2:-ÝØM¼ˆ¤5&^BC¥‡tZ ¯…WEð¤ÉÒì:´©ô€ûë#TU~!ÚõÊ÷&©×~¹"œL\ýÑ©·u蟴*oœ­#e¸ý clpŒ/+>èî<÷ÊÍJÅd8[][XàòDdοûï .ÿs)úÌù~ü ¹¾E1,ŽËIEND®B`‚eric-6.0.8/eric/Helpviewer/data/icons/setting.png0000644000175000017500000000217712060166053020774 0ustar piotrpiotr‰PNG  IHDRàw=øsRGB®ÎébKGDÿÿÿ ½§“ pHYs¯¯^‘tIMEÜ 0ösXûÿIDATHǽ•kL›uÆŸ·×ÁèèÊf;JÉ€zZÊŒ™`^7.’,Ù,Jä624Æ„ â@c_²¨‰AâRÖ€QÁ8¥ÈuB;ˆbYl JâV ‹\e©¶‰¼W¿ ! ŒnÑóùÎïüŸsžà?âQó***L™™™e¡¡¡©ÏÉü~ßÝUïZkmOÝå™¶ú±š²XÞ+Y\Z¤9Ž|>Ÿ07?'Ü::ÛøŠwÎYHþz,Ùš988(<¬zMM>õø õR©TÊ2Ä1Zív¾££ÃsçÎDÃ0v¶€MÈ®…bÿéðpEÇq`XA ·Ïñõ­[cÕE-’$yŽ$IbGPµÓlÄEEùvg11z0 ‘XŒ#Àòv ¢ õy6>áy·{,Ë€eY° ‹Â‚ôøøxéÖÆªªªÂƒ¤¥¥=¥×ÇEK¥2¸gÜ ,Ë V—^\\Ð[VV½¼|ÿ¹ë×_(„ HòÅSZ­–ÐjµèìêÆGׂeYì“Ë¥‹>º?dV÷ÌXdddÉkèA°y¢Á˜s÷Þ:»{`:v =&§¦Ðét ‘í“#££lÿ@K0‚¢Þ7'›LFCB~]Z‚X$BlL ZÛÛÁó<”J%‚À¬{V¨®¬vò<ß²ãý³¸ÍfÍKI9Þ¸²²ƒÁ€ì¬ ô:8¥…)É™\†ÕÕ¬{×™×-ùß3 S `Ûx@ (êo“˜Ífqsó—–Ëß~Ãeee )©)‚Ëå<ž{ƒ?pyy¯ýöIΑ$é‹ÅV…›fÝÝPRR¢8‘q¢izj:Çét"B.jš¿tÉvÓjµ^£iú6€9küEml¦ »ÊËËõ¦dCG[ëwÆññŸ¡R©À²,Î 6›­ëâ§+,à¦ï¿~¿/ûɧãFl¶†ˆùùH¤Ð4—³³099åÚ,îÙëêmH¯^í®>¬>|­¡á3ÉÚª"‘Ë!)9 ªƒª_JKß8¿) ‚èõzyÑ™üzµZsvzz Ð4¢¢¢q2Ý[y¾ªÀøV}÷"xó­Ò*Žãr›š¿z×»þàó«æûJ¥Z­ÅÅ…ŸÔÖ}àõzûö¢ù¶?8qÈ|¥ëÊÍáÃÃ7†}&C‚Æh4Ô'y{‹ýóÜÜÜ:ur$ —Ë~WѨ¨øÿ`™'’““GŸ£Ûb©yû±orc£­ ü`xÓèÈèA 1±Gs~êooë, v¨;}Ñ…/1 }6“=ÎfKÁõ?.Q£©ÇÞi{IEND®B`‚eric-6.0.8/eric/Helpviewer/data/icons/brokenPage.png0000644000175000017500000002026112060166053021366 0ustar piotrpiotr‰PNG  IHDR炽ÍßÉsRGB®ÎébKGDÿÿÿ ½§“ pHYsÝuÝu¬‡ÃƒtIMEÜ"26‚:Z IDATxÚí]isÛØ±= ÁU‹%yìñT>¤òÿJªR©TÅ›lÙ–Dq±r{&ç¦yÔÏŒcwW¹´ps»ûôéng»Ýn¡¦¦öÍYC?55§ššš‚SMMÁ©¦¦¦àTSSpª©©)8ÕÔÔœjj N555§šš‚SMMMÁ©¦¦¦àTSSpª©©)8ÕÔœjjj N5µÑ\ý¾]Ûn·Øn·X¯×X¯×(ËI’`»Ýb8¢Ýný\Y–áááëõ¾ïÃó<´Z-´Z-4›M8ŽÇqÀ|USpª 0n6¬×kE,ËÌ¿¢(ÌmA Óé< œ«Õ óùY–¡ÑhÀq4 ´Z-ø¾ Ðn·Ñjµàyž¬š‚ó‡åz½F–eX,HÓyžcµZÁq¸®‹v»Fã×,¤ÙlšïÎ_ ´Ûm¸®‹Ífc‚4Mqår‰f³‰0 ÑëõE¢(B†h6›úŸô'˜£¾þ\+Џ¿¿Gžçp¾ï# C´Z-ÂÍfƒÕj…Õj…Ífƒóós ‡Ã£_g:âóçÏØn·h4;ßn·X.—(ËEQ/ÍCa4áôôaª7UÏùý[žç¸¹¹Á—/_Ðh4†!NOOÑétÌíY–¡,K¬×kã½Ê²ÄjµB¿ßò!Ç1\×…ã8(ŠeYb»ÝÂqÆ6 t»]Àr¹ÄjµÂ‡ðñãGŒF#\]]!Š¢'{n5ç7¾E»»;|þüŽã`4íäyžc6›a¹\b³Ù`³Ù˜Ç“¢÷|Šñ¹V«ʲÄr¹|V;Žƒív‹<Ïáyžm(Š_¾|Át:ÅÙÙž={†0 ¤ Îï#|L&ÇÈóAÀu]Ø4yžï€Y.—X¯×`òÔld»Ý¢,K8ŽƒõzF£aØ`Þ’µ-Ë 9Ôét°\.±X,ðöí[Ìçs<{ö Ãá¾ï+Hœÿ{¶Ùl0›Ípww‡$Ià8Ž!fX"™Ïç(ŠÂn½^ÒF2¸OQÈóüIïc¹\b¹\(‰¢*°7 ãiÓ45¬îp8DžçxxxÀt:Åùù9.//Ñï÷•8Rpþï„°ëõãñŸ?FY–Þçzž‡ÍfcˆŸ,ËL8KP dI’<œiš"MSôû}ãåWYç´½öz½Fžç¦Œãû>\×EQøôéîïïñêÕ+<þ\K0 Îoß–Ë%nooq}}V«…Ñhd.ôf³‰f³i¼‘ëº;€#( r)Fà}šÍ&6›ÍQáäv»5†Ծïc»ÝbµZ=z- Vú6Z­’$Á?þñL§Süõ¯…ïû Pç·é1ÉÄÞÞÞ"Š"t:sQ·Û횥Ì)˲Äf³Ù…ã8¬ w£(2à:ÆHöø¾f³iÂjæ– ©™‡XÌ}›Í¦7\ÏóÌ}£(‚뺸¹¹AÇøÛßþ†Ñh¤ý¦YüW¶4Mñöí[Üßßc0 C¸v»mˆ éñÖëµ!|(¯ ‚À(yšÍ&Öë5’$A³Ù„ëºÈó|‡qÝg«Õ EQ ôû}¬ívk‚ޝI°J/Êú(Mðm·[A€Ñh„<Ïñ÷¿ÿ777к‚ó›±Ùl†ÿûßHÓ£ÑȰ°ëõÚ€?K¯è8ºÝ.:ŽÑ¼Ò»Ñƒm6**ˆø¼ÇR|;Ÿ$@·Û-â86a³ô¢›ÍÆ”pª$>—ëºèv»Øl6øç?ÿ‰7oÞ<¹ä£¦àüê6™LðîÝ;l·[ 4 “ϱŒAVVz'þkµZˆ¢h‡$ò}‡©mµZF~GO{l¨Í×_,|ô~®ë¢ÓéÌ0˜ï‘—d•üÛø|àº.¢(‚ã8xýú5Þ¼ysôûTÓœó«Ût:Å»wï°^¯ÑëõL~(= Éz$Þ&CCÇqŒ“€ñ¨ ‰©ð9–œJÓI’5’CX*ƒä{”žRŠø÷ñ=ó}3G¢qãýû÷hµZ¸ººÒR‹‚óµù|Ž·oßbµZa0ì\¸ôzüÞÖ³ÚÞÓu]„aˆ8Žñðð`„ïvDý~‡Ñ=&ç¤ð ÏsSR‘"x×uMy¤ê`¡§¤æÖu]ó;z_Yš¡pa±Xàõë×h4¸¼¼T±‚‚ó±,Ëpssƒ²,ÑëõÐl6±Z­ @yáË>IÖ%(eøéº.†Ã!Â0Dš¦†Me˜œ$ ºÝ.z½‚ 8ê}²ìaƒºÕjí= ]í\•-l?¬V+C QÙÔl6+a"I¼~ýžçáììLY\çïk«Õ ···˜L&èv»ð}ß„}60ù½ïû¶ Oª¶Û­ Œ²,wD OÉ9ééøÏó ûË÷Ê:+å„A`³Ù ŽcT :[ó›e™©ßò6‚>Ãb·Ûm>«)8¿ºm6<<<àææÆ\Èœ$JÌõzmBVJÖ…¥’!eûV’$(ËÝnA ,Ë£sÎ4Mñðð`BVæ‡ 1Ó4Åb±0‡5´ü{d¨îy\×}Tj¡@^Šõ)ô§çžL&¸¾¾Æ_þòø¾¯’‚óë[š¦xÿþ=Ç1ÍȬJÐI/JPÉÛ¥•y¨ã8X­VF“+…²,M˱á!K8žç¡ÛíÐP!ÛÒx_fKñ£þmœ¦ày’$AE¦‹%MS,—KE^¯ÏóðñãGt»]<þ\óϦŸÎm¹\âææÆ\Üd6) þL¯ÉÏiåÈ ç9þõ¯áÍ›7&Ï[.—&×,Š777¦,rLNõ_‡^Òfge~,£Ʋ [2Ë<8f³’$ëºèõzð}ßÈY÷}óæñÌj ίbÛíóù···FWJJÏG ÒK²†(sD‚˜ êV9¡,K£»u]A ÛíšþO2¨OúÏþO)‡¤TQ&•¢‚¯ßïA¾$¶xÿ Œ’I~jY–‚ÀLl b6›áÍ›7G+œœj­,K\__› S8› Œ$$ñÚ%¥{ ™¿° sI&‘=;;C†G½ï0 M7Š'#©»¥×$i”e™Qþ0O”á8µÂTɈá2ûVåôéÓ'ŒÇcõž ίã5ÙÃHð‚$1#)Eã²¶ÉnÙ@-CÆår‰ÓÓS\]]™@vŽðbïõzæy_“á­ì2á$?æ›´<Ï‘ç9Â04y*•C’ãx'd–Þ3IÜÝÝ!ŽãGäÐv»Åû÷ïQ…^\ ÎßfEQàÇðI1»”­É|Ô&…dèËQ–Áw»]#„—ÏuHXN²UÌq#åãW)¢g¾É™FY–!MÓ&™á¶|m†±Ì…“$Ál63ïBžçˆãØŒ6¹¾¾>º$ô£™–Rް<Ïñùóg£oµlÑ‹JRd4a4!;ÁTå%è IÚÈиn{•÷­óœdŒ{½€_»g8†ÓîTñ}ßNœžP55A²¼4xž‡0 åß!;p(¨h·Ûˆã777øå—_ôBSp>ÝÆã1ʲ4¡› iê”eYb0˜–1Y´ÃXæƒòñ¼/Ñáph„ÒÃÊ6.ÞVe’p¢ºˆ¹!'[Ê,Êõªj©öÄ{mh[![Ëøûf³‰ñxl¦ù©)8¶år‰étjˆ;”$ˆ€_ë‰l¿â¤ J)å“á!/ÔÕjeÂ?æ¦ùÁça>7ŸÏáû>F£ÑÞµ 3ŒÇc£îaÉ2$z(¨š)$sc{Zk¢,/Ƀ‹–ïÇÏ"MSÌf3§‚ói–$‰!1èe$sÊ‹d§Ó1Óä}m=*IÐÚ"ù{Ü )u¨VX–%â86“(œ`h+GdJ°É÷`VUï“J"ò²$DÝqžçþ†¹‹ÅÂLTSpEqw‰¬Û=šôžÝnwÇ#T™=<Ë&wêÀ _—a£§yˆ­m4FŸkßnw’TT¾w[~Èpž%¦F£aÀJR‹õT;ÿd›§‚óèv±Xì€P^Ô ÝH„dY†$IŒ²¦®k„µ0Øíe6ù#çú°´AÏtȤà ,ËG^[³êqöû–ßË¿ÅΩ¹m4&¤¶ >6Žc$I‚N§£-e ÎãXÚÙlV;™Ž¿oµZ(ЋŢv,¤­©µÃ^ ©â@Á'Çœ'''{±–)Yõš‡ÀhAUQ† “W«ÕÎ$x™Ã2ÒQë¦uÏÿ#šÖ9÷„´$GØ`lƒŠSç6›Y£°\.­T¨c;é­làл0Ÿå²œRp(ç¤ÈÀ^ñPõOÒ³Êï«V7È+ŽcdY†N§ó¨wÕηYBò<ÏìU½­‚ó ±ÎÇr6›™¼äOE;=—ÇÔí>NÉÚVy/¾†ØÌ펕ïÉú«Ir‰å5u^Sz¿:×´ —]`"æÊù8¾?8Y–éjõœûÞO†—œ†Çî ‚RÎuå>KÊðloÄÙƒ§òyx±Ö„9eUx+k§’¨©ïj?³=ªýÕ\P–RHzMŽó´…òsáa§bõœ{=޼¸9/‡Àd¸I€><<˜Ïn³²/ò8Žqwwg@Ì’Ã;êy)€¨¥)=OçÜwÛ!o~lj5¶²6Üh4E‘a·í×ÞàTSϹ—­•¢vŽí伨 RÞ±X Iôz½ðm>ŸãÓ§OFS*EíüLá€Í‚V…˜‡Ài3°röTÙzW»›¤ÊkV±ÓŒ lQ<•?œ| ïCÏOÏ©a­z΃ž“á$egrýïgF|—Ù27y5›Í9CdùYN9Ä*Ê9%Èí,u¡kµÁºo¢=Ã\Na |ð˜ƒQMÁY{ÁÓØ)AÏYªÒ³1Lít:¦UKeYÙ—É ›­\ò÷$VìÇBô¼²õÌ.È} ’È©¬íUmòÇ;»R¾W v¯a­Zm¾EưÕ^Ã./" Ý×ëµB¦Uz-¹¶À–ÊQÈpS†ˆÒSÉw_Œ D™ÏÕ±±UícÇE²fkwÛp퇢ÙZ†Ç6Àœjµ½/j9d«J3Jø¾¿3JR^øòñ6ÁC5’lK£JˆÒ6[s{ÈÓÈÉ ul°ÔyLûð²ïk‡Ñ|í4Mw"QþUÞXÁ©V Jz7 Ù¥ªÇöòôç̹âàe‰–-ÈÕzÌoy¡S€/óS¾<ÏÑï÷Í| iEQ˜Ù>u5ÒC,nÕN»”"€år¹3§W~.“Rõú²$¤{<5ç¬ÿPDÿ¡½BAn}® ¿ä`®õzwïÞáööÖlëõz¦††!NOOÍ&hv°q›;Jä8Kùå׉Å9΄äCs€öAs¬L¯*W—µa©7¶ŸCæ¸ršDÝ窞SÍg®Êiv/§”IOR…™¦)Þ½{899Á³gÏÐétÀŒ»´wžp¾«ïû¦Ï Ù¾€±µUë"lXµ+¥ªñ»ªKeX)Õ«z-F'$ˆèy%¦àT«½°‚ 0¥ ›@‘ç†qˆ\(Ûl6‘¦)®¯¯±Z­Ðét0 vö•ȉérÚÁýý½!…Ø&ü:Ú’ öå…6©S¼ª<¸î~U³ŽäkHí¯$¤$(mí0AÊC„Â5gmøÆ)uûB,yaËý&®ëb6›áêê À ×××hµZ ¸¸¸€ïû(Ër'd•!Ù]æ«rÔ$K1ûKÛ ÑU¹càö ૞ÇþLä@3ù’½Ýl6è÷ûæùyبçTp4žàÈ9«öT=9?3¤ ‚Àß9ú’Ìïåå%:Ž©‹Îçs³à–€¥a¯cÕƒ}¥”ª|Q*u¡ª Ð}&¶¸qu  pÖzÛíöóçùQ¢‚SÍA)Iz„}ùóÀù|Ž(Š øèa·Û­YðszzŠÑh„0 ‘ç9Æã±hÕT¼*R¦Jü~ÌÀ}·W²®öi×Ù6ÇÍfL$‰™,Oc9Á©a­‚ó`ÎÉ …+ªdo²LÂðt2™ Š"ÓO)–¦)>}ú„õz‹‹ , CUÍç±CHþlë€yÿªn–ºiûˆŸ:2É1Gc²¦9ŸÏÍÀë$ILþÎ’‚É|}߀l§šP»ÝÆr¹4@¥hû‰™œÎÎ1&¶—uJ®ö<ý~ß4sKp2L”µBÛsÚ!­¬)Ú%“}“ôl•OpíDZ–Êψj'æÉ\íÀî“ÍfƒÅba6d¯V+t»]§‚ó8RˆÛ¤?|ø`Sz¤§7<{ž÷h—¥çy˜L&h6›‡‚À¬u g“4=$sP•BÛ£× Ôª ]í|óéž·S%åŠ\ï`gl‹ãö3>. C§‚ó8ó}ar‡¬®çÐÖ½ÊaέV ¾ï?ÚFÆRÂd2AQˆ¢aà…aˆápÏóÌð+ÙѲÙlÐn·‘(\ùÇÁî±xˆø©#‰˜+òà¨c…¥WfdÀ¨( ³=[›¬œG3¶QÁ÷}¤ijÔ;”§ÉˆÍ‚Ú9!W t:!¸¼xR=3 ©ÂzjUy¤ÎõÛmœí ;žªŸ«H!¹¥›ìò!R‰á­Ü?J¥S†fR¾Ú2ýö“BìàgIE惷ۂoz$Ífs§]ŒË„dN(sE²œ„ wwÊ•û†µ¾ïc0 ÃG£.«ÀX7ãÈɺhéAå^™~¿(Šô¢SpŸw¶ÛíGœå¼ZfåŸ,_PGË“:Ùù|nJ‡º/ìåFö{“µE›’` ð«8)°N[»OCK`’ #´USäÃ04Œ­ã8F‚@/: kŸð¹.úý>:Ž™ $=s­V«µâQN ìßäý9• ª´Á=–ÒÃÚ¹â>Ïiç’|$´Ò4EÇ;ÓêºPäsr€×¾‰ UïÉr´Ûm3Že0 ßïk}S=çÓÁÙívÑï÷wNvéYØåÏFiŠÞÙCÉ®×uM(Hoj³¨æ`0Àùù¹yž:¶u_ŽXÕÌ,ÁQç©êösº®k†w‘u®kÔ¶=¼ü]«ÕÚñšggg¦@M=瓌óV©Þ±…åDY ¥Çd£4ײGt8Âq$I²£'m·Ûfmý¾±˜v—Ì>`VI÷äÐêCSÞÉ6ó°©b{yP~naš¶¹n·‹““eiÕsþ¶Ðv0˜ÜRÖë&¤iŠÅbñ¨ób±@·Û55L»¾X•«Uå‡Ç„•öt=†³¬¡RÓZ59&Yõœu ¶o‚¾ï%ÔÙٺݮ²´ê9ÿÿÆÆè‡‡‡½äì:"Þ¢(LžL0\öuÚæ«@o=T£¬ú=sP’BPÀ¼TŽEah.•Nöóï{/2œæÆ´~¿³³³GèÕœOöžÃáÃáY–=êÞ—ý‰U»Bäé)'X9 LŽ,©*ÓÈç®btùœÒ“Û›¨e*eurû4ÿ>öÒ…ÁöáÁCйæ|>7¹æp8T¯©aío·N§ƒ‹‹ “3ÙSôêXÓ*rEîÊdèË©}Óé···È²lç~vØ,gÕmζË,U½›ömRô¿ïïÙÇÛ·Ë=œišb0àêêJ½¦‚ó+}XÿQ휅P•0À¾ð«XLûâÏçfv뺘L&˜L&æu%_öåÁU‡ˆ]¢á.î„aiU·Œ×6.xŠã¾ïãùóç :iOÁùu™Û««+œœœb…ÞF ÐërŪÛå^OfŸæd2Át:­•ìI‚gŸG«jЮ:xH ±1<Ë2ÒV8²ÄSç…ùÜ,”e‰óós\]]éÄÍ9¿®9ŽƒÁ`€/^˜évRKÚ‹þ Íçst:DQ„4M1™LL­Õ&šxqK1<–`Š%l…Ý)"w’fY†8ŽM®Yçy«„ô¤<ˆØ@>ñòåK­k*8?rèüüY–™zÌëè)ªÚË䊄ªc>8¾$Ïs³ÁŒ²;[0_5CÈž¯k÷Ò[ó>ì;e¸N…S•W¶=d]ûe›N§ƒ/^`4i8«aíïÞ^^^âòòÒ9r"Krðס•zÜðE6› îïï1›ÍvFcÖõfV-’` ¤`§NXzÙªÉðuÞÓåJF­V ———xöì™ ÔsþþE.//±\.qwwgØU^¤ùH@Øëóª„ rKÇ‚ív{g1ïz½6ljÀ^‹`w£H&W‚‰ž›áí¾Õ U#Ll¶˜ª¨‹‹ ¼xñBÃYçÇÞöû}<þ›ÍãñØT^ôv(k{"9ý\‚€äL£ÑÀp84ã1Ù¨lï׬‘)'«ËUP€Y§ ÃWz·*PÊüÐfHɲrZº$äÎ;¼µõ½lr®ËåPë*у-@ w^­VhµZøé§ŸðâÅ #¦PSp~3t0˜‰www¦ [²«ô4TU…¸d|YŠá˜Læ ¼Ÿ 8Iì°ÄÃ|²Ê[óv;7µEó¶~—Kš^¾|‰««+3'IMÁùͱ¸Ýn¯^½‚ïûøôé“™‚ÎÛ¹Þ¤ôfT÷°­K‚ÏÞÖ%AÅéô$¢8‰ âh9%\·¼ÈÔÄ'''xñâÎÎÎLÝWMÁùÍzÑ ðòåKt»]\__ãááÁL>§°ø¯(œk ¨ÙÏç(ËÒL‚gŽY5û–À`ú%e§ª»ÅËCÂØ0ì }öì~úé'ôz=óþÕœÿ3yh†¸»»Ãíí­!‹dÉCê`éÍè-[­ÖNžÉq”žçÁó<¬×kCîp*s]â8FÇ;„“|N PŽå¶‡ÙMÞ¼‡| ‡C\\\¨·Tp~_ -Ëqc:b<c2™˜ý(Rn 81¾Óé˜å¹’ø‰¢Ýn‹Å€S ¤§&9ÅYºœB/K=G|r*ûéé)ƒñöj ÎïÊHÖ$I‚Ùl†ñxŒétjˆ™OJ¯Ç)ÜÊ›\Ef³¾|ùb¼ ­H¢gÎ+W½ó}ñ6î‹ FfÀ¶2± ÎïÖ{ru’$˜ÏçˆãØÔeMQÖ@ås1)(Œ e!RZE •†f"jˆÔ‹¨‡ŠŠ‰·ZíRTJjÇ•þOé§ ýKD/«ö.¾ßêeÞZž~™ÕÉ׎[kê~Šbµ¼õcΟ\‡ëbóçŸs.u;I¿alfG°G¹}Nº,t‰È<Û“®5 å3D‹‹¦~ì¹m6„Î=¯ÒÊÍf^ÄÞæÞGæ}l‰—ÊÓE¬v±›™‰+^ú­\4s* MŹ‘ûíÎo¿óÑÝ?º¶=2:Òl¶ÛR¿´y“03›ív:g÷å>ýŸýÏŸ}é•OÇe±Ï²RoCñ"&S[´Œ¸MkWâ(ƒÆ;¾ð¾ï-[6¶BUé°ä˜ã½·ž{åŽõg~üOyÚ´4‘z¾”´¥MÌi¦±ÛvÝÕ“£‡ÜÞj¶Ú4#Ylf»³™ÑS®¹úÛ_Œ-ËV81DL¥@SÄšiì¶o½fõ²ÎC7ÒyÉñB«Ùj/íõ©zÚþ'wŸ’iy¨ªA°èåön©g2 ¢ùÈñ€A|ñåön 2ˆ* h$sv‡ÊÈqâÀƒÃ¶å4©Èղ˦4 Ì­¨”“sHˆºÂ`E~#Ód 9ž(B®@!å?BB ÀVLýU0ú’€ÑªWGH°LHÐÌN ¯WÀÔ$¸^\ñG‹G¿ VB"Hx ¢7LABT½õ$„8²„0Î;#k`BWûNHh½¸êN=˜€Í*¦Œ !`á\hî £1“€a&A aeŽ®é½$ÄØÛ“À$ÀÜw`£† !k`—… ¡Æa>RDÂŒ½å+»x+™„{Ë÷ÍÚ)!Hˆ5% WsU)¨ïod°Ñ╳4 Rƒ‹û‘ 5„‚8¨ÿZÿNíAB“€T³Ñ ;q„KQ_’˜§ zÏÄq6% ´×¤ˆLìÄõ«§&az0—W%AkNh'aGa.lBÂŒ¿Rˆ¾#ƒ-"øX= S<ô×F£&aJˆr˜„Ø}c&oæ0 ¶×›LHˆXz/:¤“#0€b]B‚ÖÀ„„ ;q$l Á•y%!Ç: ˜¼40G!H¸*ÂJ LL‚ìÇ )"F_ëÝJæÊ<$ÌN'´“àEG!HÐð¡N¬î;050 PÕ #0 5 £/ \ÓƒI°q˜Ãh$T\üá0 5ø¢¶>0!!G`ª\®­Ì~ .Km}`B À\˜.„)!HÀ8J¬†èMh'$Ì̵ÑHè ‚¯š%*ˆú3qô`fæ+HЂ8¬†(¼˜LBö`:0 UBôæB‡ÑH€¸…+ó0g£‘ð0˜-éÀ$è8L&Ké³GBÓ…kÿ!aùoy'ŽÑ—*!¨QB#ðà‹)!H`¸üä$` aÔÀ$”ÛÜT+#°aþ÷}Ó³Éñ¦Þ{`jæU3ƒqÞwÔ3)Ónä8‰À¾8Ûí¦"0 Ì+,¿sçÖsXmöw¿ùéK4YLîüù¶éƒ¯?¿¤ž¶ñÔOï³\`^Þ–Gk>rs=“Sší&ûiB²˜4GÆÿ½büíO×Óþöè¯Â|®0S5ój>¿üúï>Wj‹"‹%7ŸþÀ=wïÜK3’Åàž»wîÍ»º*–Ôõïå×ïx.‚åâsïÞ;äY&>}åÕÿN¯_¹¬Ê¼oÏï×nØtæ~}×-IÖ=°ö‚O\µŒf%G›»n»ñ€k.{&ïèŽŒŽ¾\ß¶þ—Ü"²;u–g¼—‰©-í®¶3hޤ¿í'W¾ÿ›#ívc ×gÒȾDy¯™,Þ «7^´óÌÏ\»G,?#?ضn'¶,SË2^&6œì`¦Ô‹‹R‰âÍ\ÜH.Q†öuŸÿäªUé_.»àS×Ýûà®›>FÓ’£ÅÁ™™dÍ{.þÅ?òú×ð³!Ö‰|Ö‰àgÚ˜í:Ÿ§‘øf€—É 'G¨bf¥;—A™Ä QÓ‹4 Ú€!†H³¨\ €õŸË¯"uñ¼G™†âF`õ «åúÝK«¥WeIm[½Ìú~ÃÿQü¿ù1\×Ãì;Œ,PÎa»,ó”aCåÙPa‡«3Þà6¶yÍÆ µÃ|u–ZYÃe©œ^ÝÄjuÌa–CŠå‰Idy·,‰àçÓ,Bž‹ˆ`fæ&€·b^„WähZnê3ø4ƒ&™EÎ$rD0‰¨Yµ Dauù¾÷&WØà¹~/ö«ÎeȦežªì^¹•-|¿q̪rmÀëDóUågµ¿ÕŽ5ì7VkŸZ¹Ånƒç²N=ß«9_o¿zÚ¼ÞU´DqŽ)Í+CN[Ù6,k6_P?ÏþÕ1Ç÷ü{°Î¶¯Õ¹·OÙsëv¸z”ö«êm0x3Ÿ«!WXægòÔù,wâs¼A¼x±ÿíë‰!:ãUIEND®B`‚eric-6.0.8/eric/Helpviewer/data/javascript_rc.py0000644000175000017500000150117112451233375020707 0ustar piotrpiotr# -*- coding: utf-8 -*- # Resource object code # # Created: So. Juni 29 18:58:05 2014 # by: The Resource Compiler for PyQt (Qt v5.3.1) # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore qt_resource_data = b"\ \x00\x00\x24\x34\ \x00\ \x00\x86\x68\x78\x9c\xd5\x7d\xfb\x73\xdb\x38\xd2\xe0\xcf\xa7\xbf\ \x42\xe6\x5d\xb9\xc4\x88\x92\xa5\x64\x76\x76\x86\x0a\xa3\xf2\xd8\ \x9e\x8d\xeb\xcb\xeb\x62\x67\x67\xe7\x54\xba\x14\x1f\x90\xc4\x44\ \x16\xf5\x89\x54\x12\xaf\xa4\xff\xfd\xba\xd1\x00\x08\x90\xa0\x1f\ \xd9\xec\x55\x6d\xd5\xd4\x44\xc4\xb3\xd1\x68\xf4\x0b\xdd\xf0\xc9\ \x93\xa3\x56\xfb\x49\xfb\xd3\xff\xde\xb2\xcd\x6d\xfb\xc3\x65\x7b\ \xd8\xff\xa5\x3f\xfc\x19\xca\xb0\xf8\x2c\x5b\xdf\x6e\xd2\xf9\xa2\ \x68\x3f\x1d\x0c\x87\x5e\xfb\xf4\xc3\xf5\xcb\xb7\xef\xaf\xfa\xc5\ \xb7\xa2\xdd\x59\x14\xc5\xda\x3f\x39\xf9\xf4\xdf\xd8\x75\x9b\xf6\ \xe3\xec\xe6\x24\x8c\xb2\x6d\xe1\x62\xd7\xf3\x6d\xb8\x6c\x2f\xd3\ \x98\xad\x72\x96\xb4\xb7\xab\x84\x6d\xda\xc5\x82\xb5\x5f\x5f\x5e\ \xb7\xb3\x4d\xfb\x6f\xef\x5e\xb5\xff\xce\x36\x79\x9a\xad\xda\x4f\ \x65\xbb\xbc\x8f\x3d\x8d\x71\xfb\xd9\x66\x7e\x22\xaa\x05\x50\xa2\ \x3e\xc9\xe2\xbc\x2f\x1a\xe1\xd4\x1f\x2e\xa1\xf2\xa4\xd5\x99\x6d\ \x57\x71\x01\xc3\x76\x62\xef\x93\xbb\x93\x5f\xed\xcf\x9d\xd0\x8b\ \xdc\xdd\x97\x70\xd3\x4e\x82\xb0\xbf\xca\x12\xf6\x26\xbc\x61\xfd\ \x22\x7b\x95\x7d\x65\x9b\xb3\x30\x67\x1d\x77\x94\xce\x3a\x4e\xb8\ \x61\xa1\x13\x04\x41\xe2\xee\x22\x68\xb9\x86\xef\x55\xf1\x06\xda\ \x8f\x92\x20\xea\xaf\xa0\x13\x36\x3b\x0a\xfb\x8b\x0d\x9b\xed\xf7\ \x47\xc9\x7e\x1f\x35\x8c\x77\x14\x04\xce\x4d\xb8\x76\xdc\x0d\x2b\ \xb6\x9b\x55\x7b\x16\x2e\x73\x36\x0a\x83\xb8\xe3\xa4\x37\xf3\xc9\ \x36\x67\x50\x1b\xfc\x4f\xa7\x9b\x74\x9d\xa9\xe3\x4e\x06\xd3\x11\ \xb5\x3c\x3a\x0a\x8f\x8f\x97\x9d\xd0\x3d\xd0\x77\xe7\x24\x5d\xad\ \xb7\xc5\x3e\x67\x4b\x16\x17\xfb\x82\x7d\x2b\x10\xcc\x7d\xb4\x2d\ \x8a\x6c\xb5\xcf\xa2\x4f\x50\x7c\xd2\x2f\x58\x5e\x74\x12\x77\x0c\ \xc0\x25\x69\x1e\x46\x4b\x96\xf8\x0e\x2e\x26\x19\x4b\x70\x23\x3f\ \x72\xc5\xd0\x0a\x37\xf8\xb5\x13\x13\xc7\xf0\x5b\xac\x39\xef\xb8\ \xfd\x70\x95\x5c\xb1\xe5\x0c\x7e\xcd\xd2\x65\xc1\x36\x25\x7a\x65\ \x8f\x76\xdc\x8f\xb7\x9b\xb3\xab\xab\x4e\xb1\x48\x73\xcf\xf9\x92\ \xe6\x69\x94\x2e\xd3\xe2\xd6\x71\x01\x8b\xce\x22\x4d\x12\xb6\x72\ \xf6\xfb\xb8\xcf\xbe\xad\x37\x62\x9c\xbc\x4f\xe5\xbc\x93\x7b\x70\ \xfb\x4b\xb6\x9a\x17\x8b\x43\xdc\xdf\xa6\x01\xfe\x6f\xbf\xdf\x1d\ \x38\x9e\xf1\xa3\xff\x85\x48\xc5\xdd\xe1\x20\x05\x5b\x25\x1d\x2c\ \xf6\x76\xa2\xdc\x77\x88\x6c\x1d\xaf\xf5\x99\xdd\x9e\xc1\x5e\xf8\ \xbb\xd3\x57\xd7\xfe\xf0\x17\xef\xb7\xd3\xb3\xff\xba\x7a\x77\x7a\ \x76\xe1\xff\xe2\x9d\x9d\xbe\xbb\xfa\xf8\xea\xed\xd9\x7f\xf9\x4f\ \x07\xde\xd9\xdb\xd7\xaf\x4f\xa1\xc5\x2f\xf4\xeb\xcd\xb9\xff\xeb\ \x50\xfe\xfc\xf8\xea\xe2\xf7\x6b\xfd\xfb\xfd\xe5\xdf\x5e\x42\xc1\ \x33\x28\x78\x73\xfd\xfe\xed\x2b\x7f\xf8\x57\xef\xfc\xe2\xd5\xc5\ \xf5\x85\xff\xd3\xcf\xde\xf9\xdb\x3f\xde\xf8\x3f\x0d\xbc\x0b\x18\ \xe4\xd9\x5f\xe0\x9f\xeb\x8b\xf7\xfe\xf0\x99\x77\x71\x05\x33\x5e\ \xf8\x4f\xff\xea\xbd\x7c\xfb\xfa\xc2\x7f\xf6\xb3\x77\xf9\xe6\xea\ \xe2\xfd\xb5\xff\xd3\x5f\x3c\x3e\xc3\xb3\xbf\x7a\xaf\x2f\xde\x7c\ \xc0\x81\xdf\x7c\x78\xfd\xee\xf4\xfc\xe3\xe9\xf9\xb9\x3f\x1c\xfc\ \x55\x7e\x9e\x5f\x9c\x5d\xbe\x3e\x85\xe9\x86\x03\x55\x74\xf9\xf7\ \xcb\xf3\x0b\x28\x19\xca\x12\x31\xdf\xe0\x17\x59\xf0\xfa\xc3\xab\ \xeb\xcb\x77\xaf\xfe\x84\xb2\x9f\x65\xd9\xd5\x87\xdf\xae\xdf\x9f\ \x9e\x01\x4e\x06\xbf\x7a\xef\x4e\xff\x76\xf1\x91\x43\xfd\xec\x27\ \xfa\xf8\xf0\xce\x7f\xf6\xcc\x7b\x77\xf1\xfe\xf2\x2d\x00\xf0\xeb\ \xc0\xa3\x15\x3f\xfb\xd5\xbb\x7a\x79\x09\x90\x0e\x7f\xf6\x08\x8b\ \xcf\x9e\x7a\xd7\xa7\xbf\xf9\xbf\x7a\xd8\xe3\x17\xef\x8f\xcb\x37\ \x30\xce\x15\xe0\xea\x70\x70\x47\x71\x7f\xb6\x92\x1b\xb4\x5b\x6f\ \xb2\xf5\x69\x51\x6c\x7c\x5e\x8a\x5f\x48\x03\xf0\x33\x84\x42\xef\ \xe3\x2c\x8b\xb7\x39\xd5\xf1\x9f\x1e\x15\x28\xfa\xe2\xc7\x55\x90\ \x58\x71\xbb\x66\xd9\xac\x1d\x22\x3d\xad\xb6\x37\x11\xdb\x38\x63\ \x24\x9c\x3e\x0b\xe3\x85\x4e\x92\x74\xbc\x5b\x58\x37\xca\x59\x71\ \x9d\xde\x30\x60\x48\x7a\x8b\x18\xce\x07\x4d\x08\xc7\x3d\x3a\x3e\ \x8e\xfa\x71\xb8\x5c\x42\xe1\xc1\x83\x23\xe1\xfa\x7c\x58\x02\xae\ \x1f\xae\xd7\xcb\x5b\x22\xeb\x70\x33\xdf\xde\xe0\x99\x80\x76\x79\ \xbc\xc9\x96\xcb\x77\xfc\x8c\xf8\x95\xc9\x43\x3c\xdd\xfd\x68\x93\ \x7d\xcd\xd9\xa6\x7f\x93\xa7\xec\xf8\xf8\xa4\x93\x17\x61\x91\xc6\ \xfb\x0d\x5b\xc2\xbf\x5f\x98\x2b\x4e\x2a\x9f\x2b\xce\xf3\x8e\xb3\ \xce\xf2\x14\x47\x71\x5c\x77\xbf\x07\x2e\x9a\x67\xcb\x6d\xc1\xee\ \x6a\x46\xeb\x2f\x0f\x6a\xd3\xf1\x3c\xe9\xc8\x59\xf7\x72\xd8\xfd\ \x2c\xfd\xc6\x12\x09\x44\xe5\xf8\xaa\x29\xbc\xa1\xeb\x22\xec\xe1\ \xb6\xc8\xf6\xb4\xe4\x86\x2e\x19\x9c\xc2\xd9\x32\xfb\x8a\x5d\xba\ \x0d\x75\xbd\xdb\x3b\x6b\xbf\xf1\xe9\x80\x0d\xb0\xff\xee\x0c\xc4\ \x26\x3c\x64\x6d\xf7\x02\xd7\xfa\xf1\xd0\x09\x16\x7d\xc2\xb1\x78\ \xf7\x4e\x02\x1f\x26\xbe\x36\x06\xb2\x03\x92\x42\x0a\x72\xfd\xf0\ \xe0\xfd\xf3\x12\x04\xe2\x37\x8d\xd8\xdd\x1d\xf0\xba\x10\xe4\xc5\ \x27\x29\x2b\xca\x21\xa9\xb1\x03\xf4\x89\x0c\x91\x97\xd3\xa8\xee\ \x0e\x45\x09\x16\x80\xe4\x70\x47\xb3\x6c\xd3\x41\x1a\x8c\x46\x72\ \xda\xe3\xe3\x10\x6a\x60\x54\x39\xf9\x88\x64\x5a\x05\x52\x1c\x36\ \xc2\xb3\x25\x29\x04\xb8\x35\xff\x96\xa4\x23\xbf\xf9\x92\x1d\x1c\ \x03\x36\x27\x67\x97\xab\xa2\x13\x1a\x30\xba\xde\x70\xc0\x87\x3b\ \x4a\xf3\x37\xe1\x9b\x0e\xca\x9a\x08\xe6\x1f\xc8\x55\x45\x87\x50\ \xc9\xd4\x8e\x7b\x10\xe2\xad\x3d\x38\x78\x42\x60\x5d\x71\x09\x87\ \x3c\xbd\x2e\x69\xf8\xd2\xa3\x14\x98\x0b\xec\x72\xbe\x5d\xaf\xb3\ \x4d\xd1\x27\x91\x08\x27\x6c\x53\x8c\x1d\xed\xc3\xf1\x5b\xce\x4d\ \x06\x22\x36\xc9\xbe\xc2\x1a\xbb\x0e\x08\x8c\x5e\x75\x12\xc7\xd3\ \xb7\x00\x00\xdb\xb0\x2f\x00\xd9\x39\x9b\x85\xdb\x25\x02\x08\xc7\ \x9d\xad\x1e\x04\xd7\x76\xc5\x21\xb3\x4f\xe3\x12\x77\xe4\xec\x6a\ \xe2\xfc\x91\x26\xc5\xc2\xf1\x9c\x97\x0c\x75\x2b\x67\xea\x99\x4c\ \x4f\xc9\xe5\xa4\x33\xf3\xe6\xde\x8d\x47\x72\x0f\xfb\x32\x4f\x9b\ \x7d\xde\xa3\x6d\xf8\x7d\x99\x85\x1a\xdd\xcf\xe0\x10\x87\x49\x92\ \xae\xe6\x4e\x97\x13\x72\xb1\xd9\x32\xa4\xc6\x01\x6e\xcc\x8d\xdb\ \xdc\x2d\xca\x36\xa0\xa6\x51\xaf\xae\x84\xd2\xe8\xbd\xba\xa3\xf7\ \x0d\xf0\xc8\x74\x55\x9d\xf3\x20\xcf\x4b\x7b\x7e\x40\xe2\x64\x01\ \xa7\x24\x1a\x7c\x3c\x71\x5e\xb1\x59\x01\xa8\x78\x4f\x98\xf0\x27\ \xce\x75\xb6\x86\xef\xdf\x32\x50\x6c\x6e\x00\x35\x0b\xd0\xb9\x0c\ \x9d\xca\x4b\x83\x5d\xba\x5a\xb1\x0d\x1f\x82\x04\x48\xf9\xed\xf1\ \x9f\x84\x58\xad\x8e\x0a\xbc\x16\x08\x03\xa3\x63\xf9\xed\xf1\x9f\ \x7a\x47\xad\xe0\xc0\x25\xdb\xc4\xe1\x63\x39\xdd\x68\x1a\xa8\x6d\ \x98\xf1\x93\x3b\x0b\xb4\x93\x9b\x6a\x0d\x49\xba\x70\x25\x67\xa4\ \x53\x4b\x55\x70\xd1\x31\x76\xf9\x61\x5a\x78\x09\x71\xa0\x19\x50\ \xed\x1a\x0e\x15\x50\xa1\x00\x80\xc3\x54\x01\xc0\x9b\x73\x10\x84\ \x8c\x9c\x1d\x95\x32\x52\x03\x48\x75\x2c\x01\x82\xe1\xbf\x03\x24\ \xbe\xb3\x30\xa5\x82\x8c\x08\x5b\x2a\x65\xa8\xe2\x4d\x1c\x1f\x36\ \x6e\x97\x84\x45\x68\x88\x73\x2f\x51\x5a\x26\x68\x75\x58\x0d\xa5\ \xc9\xe4\xd9\x14\x0e\x19\x17\xb8\x78\x66\x0c\x9e\x28\xc0\x43\xdd\ \x5d\x30\x94\x98\x6b\x0f\xf0\xed\x14\x21\x9e\x37\xe4\x39\xc0\x9a\ \x3d\xf8\x8a\x6a\xdd\x39\x33\x0c\x54\x97\x96\xd6\xc7\x4b\x02\xc9\ \xa1\x04\x12\x3a\xa8\xc7\xbf\x00\x4e\x75\x7c\xcc\xe7\x4b\x68\x69\ \x55\xed\x22\x54\xbc\xb4\x1f\x65\xc9\xad\x87\xec\x14\xf4\x04\x58\ \xfd\xd9\x22\x5d\x26\xc0\x47\x55\x7d\x0c\x1a\x7a\xc1\x2e\x96\x0c\ \xbf\x3a\x4e\x92\x7e\x01\x58\x4b\x64\x45\xfd\xbc\xb8\x5d\x32\x6f\ \x77\x93\xae\x04\xdd\x39\xc3\xc1\x00\xd0\xea\x2d\xc4\x27\x8a\x37\ \xc7\x13\xa7\xd9\x1f\x78\x74\x40\x89\x7e\x07\x1c\xf1\x92\x0b\xaa\ \x31\xe0\xb8\x64\xb3\x19\xe8\x3e\xe2\x33\x08\x60\xcc\x91\x95\x5d\ \x06\x4e\xb6\xd2\x19\x66\xba\xe2\xa2\x63\xc3\x6e\x40\xf2\x89\xd5\ \xb8\x04\x24\x9a\x13\xeb\x65\x78\x0b\xa4\x95\xad\x98\x63\xee\x39\ \x2a\xe2\xeb\xe5\x16\x0e\xbf\xbf\x03\x50\x6b\x7b\x1e\x72\x85\x7e\ \x12\x4e\x51\x09\x2c\x32\x24\x54\x25\xab\x58\x1b\x66\x4d\x38\xeb\ \xe5\x23\xe4\x13\x36\x0d\xf4\x8f\xfd\x7e\x32\x1d\xe9\x05\xfd\xf5\ \x36\x07\x26\x0a\x23\xc3\x07\x90\xce\xc1\x43\x8a\xae\x4d\x0a\x27\ \xa2\x13\x69\x23\x45\x53\xd8\xd8\x56\xd8\x67\xb4\x1d\x20\x16\x35\ \xcb\xce\x55\xe0\x04\x83\x11\x7b\x1e\x09\xf1\x39\x62\xdd\xae\x1b\ \xf6\xb3\x35\x0e\x0c\x43\xc0\x84\xd0\x6f\x0a\x22\x0d\x7f\x0d\xa7\ \x42\x41\x54\x83\x7a\x09\x07\x27\x5b\x15\x21\x4c\x69\x57\x65\x4b\ \xea\xc8\x6e\x10\x80\x73\xf1\xfd\x4e\x48\x63\x30\xd4\x1a\x6a\x50\ \x98\x0e\x7f\xf6\x51\x49\x00\xbd\x15\x9b\xd1\x3c\x50\x7e\xf0\x16\ \x61\x7e\xc5\xd5\xa0\xca\xac\x80\x06\x6e\xd1\x71\x21\xad\x54\x21\ \xdd\x30\x33\x6d\xd3\x08\xc7\xe6\x1c\x7a\x89\x8c\x19\x24\x2a\x1f\ \x95\x73\x69\x5f\x7c\x20\x87\x1e\x91\xa6\x4d\x9d\x50\x75\x01\x04\ \xbf\x50\x52\x1e\x79\xc4\x08\x8b\x82\x21\x18\xcd\x54\x47\xdf\x03\ \xc9\x72\x92\x83\x97\xe6\x6f\x01\xa0\xd3\x6f\x69\xde\xc0\x26\xda\ \xe1\x0b\x5c\xe9\xf3\xa8\xab\x5a\x57\x5a\x7a\xcc\x03\x96\xaf\x99\ \xa2\x60\x2b\x96\xc3\x22\x7b\xf1\x16\xb8\xef\xd5\x8a\x08\x3a\xa6\ \x78\xc0\xe1\xbf\x0e\x39\x3f\xdc\x51\x6b\x74\x52\xf5\x86\xc0\x51\ \x9b\xb3\xe2\x3f\xd9\x29\x72\x42\x4b\xa8\xf8\x46\x22\xf4\x8d\xa0\ \xd6\xd7\x8f\x97\x2c\x5c\x9d\x03\x2f\x26\xf6\xf6\x39\xd0\x8a\x46\ \xda\xef\x40\x67\xac\xf2\xb8\xc4\xc1\xc0\x4b\x46\x1d\xdc\xe2\x78\ \xea\x1e\x05\xab\xed\x72\x39\x8a\xe1\xd0\x14\x9b\xdb\x5d\x84\x96\ \x56\x01\x98\x9a\x83\x18\x0d\x57\xc9\x12\x54\x78\x87\x98\x0b\x08\ \x8e\x38\x2c\x50\x9f\x71\x77\x87\xcf\xe8\x8b\x38\x30\x20\x24\x0e\ \xc1\x12\x20\x00\xe9\x4b\x0d\x47\xda\x6f\x0d\x02\x2f\x36\x75\xaf\ \xaa\xe8\xe2\x7e\x03\x97\x7b\x69\xd0\x39\x23\xec\x87\xd0\x9b\x60\ \xeb\xa9\x74\x36\xb8\x51\xc7\x79\x02\x0a\x0e\x97\x72\xc0\xb8\x3a\ \xb2\xba\x3a\x1c\xad\x86\xda\xdd\xb3\x20\xa0\xdd\x43\xa9\xf2\x2c\ \x49\xda\x8a\xbe\x1e\xc2\x8d\x24\x17\xf5\xbf\xf2\x4d\x31\x56\x84\ \x64\x4f\x2c\x28\xec\x03\xaf\x4d\x41\x62\xf4\xb9\x4b\xc8\x9b\x8d\ \x42\xb3\x6c\x38\x1d\xcd\x02\xd6\x75\x7a\x4e\x37\xe4\xca\x36\x74\ \x4d\x82\x78\x14\x03\xea\x68\xbb\x61\x0a\x25\x89\x27\xb3\x69\xd0\ \x52\x33\x2d\x4a\x19\x1c\x91\x0c\x5e\xa0\xe1\x3b\x42\x96\x16\x44\ \x9c\xe1\xee\xe8\x0b\x18\x76\x09\xe0\x02\xb5\x0c\x65\x04\x2b\xf3\ \x82\xac\x65\x12\x74\x34\x33\x6f\x09\xea\x4a\xb0\x62\x5f\xdb\x00\ \x92\xe4\x9e\x41\x24\x05\x06\x57\x20\x76\xc0\x27\x65\x95\x2b\xa7\ \x2b\xe5\x43\xa5\x75\xec\xed\xd0\xef\x96\xaf\xc3\x98\xf9\xcc\x23\ \xec\xa1\xbb\xcd\x0f\xc5\xc7\x05\xaa\xed\xef\x36\x0c\x2c\x14\xbf\ \x36\x5a\xbf\xd6\x66\xbf\x97\x1d\x7f\x03\xa5\xf2\x6c\x19\xe6\xc0\ \x83\xc0\x06\x01\x50\x44\x63\xb0\xe1\xf1\x5f\x64\x33\x34\x1c\xe2\ \xc8\xac\xab\x10\x24\x92\xaa\x81\x33\xb5\xa1\x42\x35\x4b\x90\xad\ \xe6\x40\x40\xa0\x99\x7b\xb3\xe0\x74\xb3\x09\x6f\x35\x20\x73\x3c\ \xd1\x44\x30\x0a\xd1\x60\x77\x82\x06\xcc\xdd\x19\x49\x70\xc4\x8e\ \x8f\x67\xd2\xa0\x94\x08\x12\x32\x08\x4f\x1e\x90\x37\x22\x2b\x99\ \xa2\x68\x00\x72\x04\xdd\xd4\xf5\x5b\x09\x52\x08\xf4\x4c\xfa\xf1\ \x22\xdc\x9c\x16\x60\xc1\x22\x1c\x1f\x15\xe3\x07\x31\xd7\xec\x4c\ \x99\x07\x82\x4a\xc8\x0b\x82\xda\xf7\x1c\x9d\x26\x69\xfe\xbb\x6c\ \x38\x9f\x24\x53\x77\x8c\xff\x17\xb0\xcc\x41\xb3\xf4\xe7\x38\x6d\ \x0a\xb2\x0a\x9a\xa7\xdc\xae\xdd\x2d\x82\x74\xa4\x0b\x9b\x83\x74\ \xb7\x3c\x64\xe2\xd1\x7c\x3c\x17\x04\x83\x9a\xda\x0e\xac\xf1\x8f\ \xe9\x0a\x4e\x84\xeb\x1b\x0d\x3d\x4e\x77\x9d\x84\x8e\xb5\x5b\x9e\ \xc5\xc5\x01\x37\xf0\x8f\xfa\xc1\x7b\x20\x5d\xf3\xc3\xab\x46\xd0\ \x48\x75\xa7\x91\xa3\x43\xbf\x1d\x0b\x55\x3a\x8e\x27\xe8\xdd\xdf\ \x29\xe7\x2c\xe1\xc1\x33\x66\xf2\xab\x64\xc5\x57\x17\xf3\x05\xf5\ \xcb\xb9\x68\x81\x23\x42\x20\xe9\x1f\x41\xd4\x89\x45\x89\x3c\x75\ \xad\xda\xb1\xd3\xab\xe9\xe3\x23\x8c\x78\xc6\x01\x78\x4b\xc5\x60\ \x64\x01\xc2\x49\xc2\x73\xda\xd3\x27\x21\x03\x5c\xf0\xbd\x3e\x99\ \x7b\x3a\x58\xda\x3e\x26\xfd\x84\x01\xbd\x67\xb7\x68\x48\x8f\x74\ \x9c\x76\xe4\xa7\x60\xa7\x1d\x87\xca\x1d\x59\x4e\x5b\x0b\x98\xa9\ \xc2\x66\x31\xbf\xa3\xfe\x0d\x2b\x42\xc4\x12\x52\xa6\xfc\xdd\xc7\ \x4d\xd3\x01\x47\x1f\xc9\xa4\x02\xed\x54\xe1\x5e\x1f\x17\x0a\x71\ \x7e\xb3\x48\x2c\x45\x2f\x34\xd0\xa2\xec\xff\x1a\x4a\x5c\x21\xc0\ \xce\x25\x95\xea\x75\x23\xad\xa0\xe3\x3e\x60\x14\x74\xa9\xe2\x25\ \x45\x1a\x4a\x37\x43\xe2\xc8\x3a\xce\xc8\xf4\x29\x14\x77\xeb\xb6\ \x1c\xd5\xbc\xbd\x4d\x7b\xe8\x91\x64\xda\x00\x07\x41\xb1\x4d\xde\ \x0d\xb1\xca\x83\xa0\xe1\x0a\x8d\x8a\x5b\x15\xae\x08\x56\xce\x52\ \xa0\x3b\x7f\x94\x6f\xd8\x24\x43\xf2\x6b\x69\x3e\x5e\xc1\x24\x49\ \x7d\x0d\xaa\x4e\x31\xa9\x8f\x87\x53\x60\x8a\x20\xac\x12\xe4\xba\ \xf1\x81\x08\x07\x2c\x1f\x49\xc5\x89\x61\xdf\xc2\xa6\x96\x75\x35\ \x33\x31\x26\x42\x8f\x88\x17\x85\x25\x15\x83\x8a\x89\xde\x97\xb2\ \x2f\x2f\x39\x34\x0e\x5d\xc1\x4c\x05\x60\x10\xd2\x88\x23\x5c\x63\ \x89\x7b\x83\x02\x26\xf1\xd8\x01\x5d\x84\x6f\x1a\x48\x6f\x6d\x5f\ \x9d\xa9\x7d\x67\xef\xde\x58\x32\x7e\x2b\xf4\xe2\xb5\xe2\xca\x02\ \xc8\xc9\xd5\xb4\xfb\xda\xea\x4b\xb8\x3d\xce\xbc\x5c\xe5\xb9\x7b\ \x5c\x67\xee\x20\x02\xc4\x09\x06\xe0\xdb\x55\xa1\xea\x7e\xa3\x86\ \xc3\x99\x2a\x32\xba\xb8\xcf\xf9\x2f\x47\xa7\x86\x19\x8d\xe9\x8e\ \x43\xdf\x5e\xd1\x05\x93\xc8\xbc\xf9\x4b\x82\x44\x5e\x39\x81\x62\ \x02\x40\xa5\xab\x70\xc9\x7b\xa0\x01\x0b\x74\x81\x3f\xf9\x2d\x86\ \xa4\x6c\x65\xc3\x82\x7e\x36\x02\x9d\xd8\x6c\x34\xe9\xf5\x10\x5e\ \x54\xbe\x2a\xe3\x41\xd1\xe1\x60\xb0\x0e\xc9\x04\x71\xe1\xf2\x02\ \xb0\x63\xc8\x58\x06\x46\x0c\x2b\x5d\x37\x1a\x4b\xe3\xd8\x02\x04\ \xf0\xcd\xc0\x0b\x96\x34\x17\xde\xcb\x77\xe4\xcb\x64\x49\x07\xc4\ \xe0\x3d\x76\xce\x6b\x74\x94\xfe\x47\x9b\x39\x7c\x05\xa2\xd5\x39\ \x43\x7f\x4c\xee\xc3\xef\xff\x21\x5a\x01\x8c\x42\x77\xfb\x94\x57\ \x6d\x21\xc9\xbf\x84\x05\x5c\x7a\xea\xfb\xdc\x7f\xbc\x5d\xeb\xba\ \x89\x68\x76\x28\x35\xc5\x8e\x03\x83\xf3\x96\x8e\xb7\x53\x22\x3e\ \x0e\x57\x31\x5b\xfa\x8e\xcf\x2f\x6e\x05\xdb\x74\xf0\xac\x14\x58\ \xe3\x0f\x41\xa0\x2c\xc3\x5b\x7f\x00\x67\x80\x77\xbe\xac\x48\x1c\ \x72\x36\x35\x89\x5f\xe5\xd9\xbe\x4b\x02\x97\x56\x52\xd8\xa7\x49\ \xce\xa1\x47\x07\x8d\x10\x31\x4c\x0c\xe8\xfd\x7c\xcf\x10\xc8\x9b\ \xe1\xb0\x02\x8d\x49\x55\xa4\x5f\x00\x97\x67\x85\x17\x6a\x5d\xba\ \x8e\x74\x9e\x9f\xe1\x98\x9c\xd2\x1d\x17\xd5\x17\x4d\xf8\x3d\xa2\ \x27\xba\xac\x8a\x6c\x7d\x79\x73\xc3\x92\x14\x58\xda\x3b\x38\x54\ \xe1\x3c\x24\xe4\x54\xd5\x48\xc2\x10\xf7\x62\x31\xb9\x41\x02\xad\ \xe7\x0f\x17\xdb\xad\xaa\xc4\x55\x63\x00\xd6\xaa\x77\x35\x68\x73\ \x11\x7b\xe3\x4d\xae\x68\x6e\xa9\x39\xf2\xb2\x0f\x6b\x68\x3b\xd2\ \x0a\x70\x1c\xbe\x3c\x10\x95\xa5\xd0\x01\x53\x00\xd0\xb1\x48\x63\ \x90\x95\x43\x6f\x2e\xad\x05\x9d\xf5\xf5\x89\x9a\x4a\xc9\x88\xfe\ \x1f\x42\xa5\x8a\x3c\x18\x47\x1d\x59\xe6\x82\xd9\x9e\xe5\xea\x5e\ \xca\x1c\x44\x5a\xbf\xbe\xf2\xdd\x1c\xcd\xf6\xfb\xf9\x7e\x7f\xa4\ \x41\x7a\x16\xae\x01\xc1\x60\xfd\xb8\x86\x4b\x87\xb7\x10\x68\x05\ \xe2\x7d\x0d\x9a\xf4\x91\x31\x05\xa7\x69\x3e\x66\xbd\xa9\xab\x63\ \x02\xcb\xf0\x76\x76\x13\x34\x5c\xd3\x56\xa6\xc1\xe9\x4d\xa5\x81\ \xe6\x2a\xaf\xc4\xc4\xc0\xe2\x7c\xbd\x46\x8d\xdd\x35\xb6\x43\x8e\ \x85\x8b\xb2\x6c\x1d\xdd\x1a\xeb\x65\xd0\xf0\x28\x28\x5d\x5c\x47\ \xf5\x3e\xb6\x2b\xa3\x91\x86\x30\xe0\xf3\xc6\xc9\x91\x1b\x54\xd5\ \xe5\xed\x47\x00\xb5\x59\xed\xf0\x3c\xae\xb3\x4e\x77\xaf\x71\x08\ \x20\x78\x38\x3e\x9a\xd1\xca\x34\xb7\x59\xd9\x0e\x8a\x0f\x23\x83\ \x88\x1f\xd2\x13\x48\x1d\xfb\xe9\xbc\x53\xe3\x53\x0d\x96\x42\x03\ \x84\x46\xd7\xed\xfa\xee\x8e\x25\x78\xee\xa8\x79\x2f\x12\xa2\x1f\ \x79\x9e\x71\xb6\xea\x79\x8e\x2a\x97\xf6\xad\x23\xb5\x96\xbe\xfc\ \xf1\x1a\x8e\xda\x8b\xe0\x57\xd8\x98\xa3\xb0\x4f\xa1\x37\x86\x62\ \xaa\x1f\x7b\x93\x2c\x15\xbd\xe8\xf4\xb8\x09\xe7\xd8\x52\xb1\xe8\ \xda\xe5\xe3\x77\x91\xb6\x65\xda\xa0\x46\xd9\x36\xa6\xe4\x95\xe4\ \x2e\xa2\x0b\x0c\x38\xfd\xda\x12\x85\xa6\x52\x9f\x4f\xe2\xf9\xc3\ \xda\xc0\xb2\x4e\x1d\x92\xed\x7e\x17\x7d\x18\x9d\x1f\x43\x21\xf7\ \x6f\x8a\x62\x06\x22\x54\x4b\x9c\xb9\x20\xb0\x61\x4c\x54\xe2\x39\ \x7d\xfc\xf1\x26\x0d\x78\x64\xcc\x9d\xad\xcb\x90\xaf\xb6\x29\xc6\ \xca\xcd\xb7\xdd\x90\xbd\x0e\x8b\x45\xff\x26\xfc\xd6\xe1\x3f\xc2\ \x28\xb7\xee\x70\x1f\x24\x28\xfb\x47\x2f\xa4\x7f\x5d\xef\xfe\xc6\ \x7f\x8a\xc6\x7f\xba\xee\x0b\x43\x19\xef\x4b\x45\xa6\x94\xb3\x44\ \x82\x4d\x56\x80\xd1\x48\x76\xe2\xd8\xae\x58\xde\x8a\xe6\x6c\xe5\ \x88\x22\x5b\xb9\x90\x57\xb6\xc9\xf9\xc1\x77\x2b\xea\xaf\xa9\xfd\ \x5e\x65\x9b\x02\xcd\x92\xff\x68\x05\x58\x2e\x22\xbf\x53\x09\x8e\ \xb3\x0d\x23\x15\x58\x2b\xe4\x28\xac\x95\x36\xe9\xcb\xe8\x6c\xd6\ \x55\xdf\x5c\x4c\x0c\xca\xad\x1a\xcc\xdb\x59\x1c\x60\xd8\x50\x73\ \x82\xd1\xad\xe9\x75\xe6\x3b\x74\x11\xe7\x78\x21\xbf\x0a\x42\xb2\ \xc7\x4b\xb4\x15\x8b\x8b\x3f\x52\xa9\xa8\xc8\x6b\xb5\x1b\x1e\x74\ \x45\x25\xdb\x0d\x0c\x29\x6f\x49\xe9\xeb\x54\x56\x26\xa0\x2f\xbe\ \x5d\x5d\xdc\xac\x8b\x5b\x9f\xbb\xbe\xc0\x5a\x8b\xd9\xbb\x65\x18\ \xb3\x45\xb6\x84\x0d\xb9\x4a\xff\xc9\x44\x5b\x5e\xf5\x92\x2d\xd7\ \x46\xe9\x7c\x93\x0a\x07\x9d\xb7\xe0\xde\x7e\xf9\xc1\x1b\xfa\x8e\ \x34\xea\x1c\x2f\x2d\xd8\x4d\xee\x3b\x2f\xda\x4f\x70\x79\x61\x9c\ \xc2\x9c\xd4\x76\x5d\xce\x27\x4a\x90\x0f\x6c\x24\x90\x74\x9f\x46\ \xf0\xd1\xef\x2b\xd8\xeb\xb4\x48\xbf\xe0\x10\x4f\x07\xb2\x70\xcd\ \x58\x42\x9f\xd9\x9a\xf9\x4e\x42\x12\x02\x58\x48\xb6\x64\x1b\x6e\ \x4e\x38\xe9\x0a\xa3\x2a\x01\x65\x8e\x0c\x2e\x1a\x5e\x3c\xb3\x7a\ \xb7\x4a\xc3\x42\x1e\x66\x62\x42\x02\xc1\x68\x11\xc7\x0b\x86\x8e\ \x15\x43\x51\x96\x4e\x09\xdc\xf3\x9e\xda\x73\x38\x4e\xbc\x15\x6c\ \xf1\x86\xe5\x0b\xe9\xd7\x9b\x61\x74\x08\x28\xaa\x34\x0d\xc7\x8f\ \x74\x5c\x87\x7d\xdc\x66\xf4\x80\x7c\x73\xf6\xfb\x13\xbc\x66\xdc\ \xf3\x63\xa6\x87\x52\xf1\x1e\x78\x47\x8b\x3f\xe8\xf2\x92\x0f\x49\ \xf1\x71\xe9\x6a\x09\x70\xee\x39\x04\x3d\x50\x69\x97\xf7\x74\x15\ \x97\xd7\xd0\x59\x28\xbd\xb4\x78\x7e\x4d\x1e\x18\x8b\xa4\xb2\x8e\ \xc1\x96\x2f\x85\x2b\xf2\x3e\x07\xa0\xee\x82\xd3\x71\xd4\xd6\x7e\ \xd7\x5d\x76\x5c\xb5\x73\x4a\x7c\x96\x06\x89\x86\x63\x43\xd4\x0b\ \x8f\xaa\x72\x3f\x84\x75\x24\xf7\x86\xa3\xf0\x45\x30\x18\x85\xbd\ \x9e\xab\x21\x25\x14\x48\xb1\xcd\xdc\xc3\x1a\xe7\x41\x6e\x2d\xba\ \x56\x46\xaf\x4b\x4b\xf3\x62\xd5\x5c\x5d\x91\xe9\xda\x9c\x44\x77\ \x38\xb6\x1c\x3b\x8e\xf8\xad\x60\x3b\xa9\xf9\xdc\x35\x9f\x52\x53\ \x90\x66\x83\x5c\x90\xd0\x0b\xa2\xc5\xb3\x08\x64\x6a\xde\x81\xcb\ \x6a\x4d\xd4\x71\x78\xf6\x7b\xa3\x98\x3b\x9f\xd0\x22\xc3\xd8\xce\ \xca\x35\x3a\x6d\x98\x38\x14\x97\x88\xfc\x8e\xf0\xa8\xc7\xfc\x92\ \xd4\x63\xe2\x52\x47\xb3\xd9\xca\x78\x47\xcb\x75\x66\xa2\xdd\x71\ \x54\xf7\x2c\x08\xd0\x45\x19\x24\x66\x98\x91\xb2\x8d\xcb\xde\x4a\ \x3f\xb1\x8d\x80\x03\x28\x60\x28\xf2\xfa\x6e\xb4\x10\x53\x44\x4d\ \x59\x78\x50\x66\xc2\x56\x4a\x6c\xed\xbc\x18\xe3\x38\x91\xb0\x9f\ \x38\x7a\x58\xb9\x65\xad\xd8\x3b\x08\x14\x2c\x33\x52\xde\x09\xa6\ \x99\x01\x13\xb9\xd1\x80\xf3\x23\xe6\x10\xcd\x41\xac\x50\xcf\xc9\ \x8b\x6a\xf2\xdf\x37\xd9\x0d\xed\x82\x69\x9e\xd9\xd5\x10\x8c\x2c\ \xc0\x8b\x17\x93\x47\x96\x0e\xc9\x91\x3e\xeb\x99\xe4\x9a\x5a\x95\ \xd8\x77\x19\xb8\x91\x4b\x7e\x42\x92\x23\xd0\x2f\x42\x48\xea\x94\ \x7e\x82\x18\x79\x2f\x15\xa2\xc7\x03\xb6\x49\x1f\x80\xaa\x5f\xf3\ \x40\x3b\x55\xa8\x87\x23\x07\xda\x3c\x46\x85\x6c\xac\x33\x3d\x0d\ \x6f\x15\xc6\x27\x5a\xed\x50\xdb\xd2\x0a\xfa\xf0\xdd\x23\x6d\x8e\ \x40\xc0\x02\xaf\x85\x2c\xdc\x68\x86\x05\x66\x3b\x2c\x39\xe8\x48\ \xa8\x84\xa0\x7a\x65\xe8\xa9\x00\x01\xea\x25\xfe\x82\xe6\x7e\xee\ \x28\x51\xf7\x5b\x25\x00\xde\x8e\xfb\xb5\xfc\x1d\x87\x4c\xa8\xbb\ \xbd\x2a\x84\x1e\xae\x4e\xa8\xb7\xbd\xca\x2a\x0f\x1e\x9d\x46\x61\ \xf4\x00\x19\x12\x1a\xdf\x0a\x34\x79\x32\x32\xb6\x6c\xf0\x5e\x94\ \xc8\x26\xd2\x2b\x25\xd5\x04\x73\x35\xd0\x03\x68\x06\xfd\x5a\x32\ \xba\x27\xac\xb6\x47\xa0\x03\x01\x7c\xbd\xea\x4f\x51\xf5\x27\x06\ \x69\x08\xd5\x47\xda\x84\x61\xf2\x69\x9b\x0b\x58\x91\xf4\x05\x91\ \x95\x0d\xc5\x54\x49\x76\xa3\xa0\xda\xa1\x85\xe2\xd7\xe8\x02\x4b\ \x3b\x3c\x0a\x41\x47\x88\xd1\x42\xd0\x17\xb4\x39\x08\x65\x80\xb6\ \x8a\x47\x1e\x57\x9b\x43\xa1\x80\x52\x1f\x63\x91\x26\xe5\x95\x20\ \x1d\x0c\x4d\x53\xc3\x40\xfd\xbe\xa6\xfe\xc9\x65\xc2\xea\xce\xca\ \x52\xca\xde\x91\x6b\x24\xa6\xd9\x71\x30\x46\xcf\x11\xe1\x4f\x54\ \x03\x5a\x80\xe8\x5e\x80\x2e\x9c\x9c\xf1\xc2\xa0\xa1\xe9\xc8\x5e\ \xee\xa9\x69\x0e\x7c\x4e\xa1\xf4\x95\x92\x45\x27\x56\x51\x59\x99\ \xf7\x2d\x95\xd6\x69\x5b\x35\xaf\x1f\x17\x59\xe5\x95\x33\xd2\xfc\ \xa4\xf1\xd9\xa7\x97\x91\xd9\xc6\xec\xff\x87\x17\xd6\x27\x97\x8d\ \xeb\x73\xcb\x20\x74\x35\x99\xf2\x4e\xe8\x6c\x86\xef\x79\x4b\x9a\ \xf9\x62\xa3\x2a\x0d\x80\xaf\xcf\xd1\x2a\x3e\x0a\x9c\x97\xd7\xaf\ \x5f\x89\xfb\x2f\x19\x9b\xf6\x56\x63\x50\x7a\xc7\xaa\x6a\xa6\x2e\ \x8e\x29\x76\xd1\x0b\x85\xcd\xbf\x4d\x5f\x86\xa8\x87\xca\x76\x40\ \xc0\x39\xdb\x7c\xa9\xf3\x54\x21\xcd\x9b\x39\x2e\x89\x40\xd4\xb2\ \xe2\xc0\x54\x90\x35\x35\x2b\x46\x35\x2b\x96\x6a\x56\xd9\x62\x12\ \x4f\x35\x18\x43\x10\x2c\x5f\xf0\x7a\x1b\xc0\x64\x0a\x46\x2e\xae\ \x85\x7c\x06\xc3\x29\x49\x6e\xc2\x15\x9c\xe8\x8d\x6b\x7e\xca\x93\ \x22\x34\x06\xa3\xee\xf8\x18\xa3\x78\x00\xec\xdf\xd8\x22\xfc\x92\ \x66\xdb\x0d\x06\x7a\x18\xbd\x01\x01\x78\x44\x09\xaf\xb9\x0a\xa7\ \x20\x06\x00\x66\xf6\x9c\xab\xe9\xca\xbb\x2b\xf6\xdc\xaa\xed\xf7\ \xa8\xb2\xa2\x90\x0a\x37\x56\xcb\x22\x58\x4d\x33\x3e\x14\x3a\xe2\ \xfa\x81\x9c\x50\xb6\x3b\x8d\x72\x29\x33\xb3\x15\x6a\x6c\xb2\xe5\ \x75\xd6\xd1\xe5\x86\xf2\xd1\x02\xe0\xaa\x0d\x74\x76\x6d\x85\x41\ \x75\x8a\x9a\x7e\x23\xd2\x4a\x44\x14\xb1\x5e\xe5\xc5\x81\xa9\x12\ \xd5\x8e\xc0\x23\x4f\x80\x3a\xb8\xe6\x29\x40\x49\xd4\xb5\x0e\xa0\ \x87\xf8\x4a\x17\xcd\xf3\xa8\x5f\xb3\x21\x5d\x6b\x6f\x15\xc6\x19\ \xc4\xf5\x83\x66\x34\xe8\xaa\x31\xd1\x04\x1d\x71\x75\x1c\x75\x7f\ \x43\x6a\xd6\x60\x7e\xde\xfa\x37\x80\xd2\x33\x41\x69\xc0\x18\x0a\ \xf6\xbb\x50\xc6\x63\xa7\xa5\x07\xec\xb1\x18\xc3\x28\xd8\xbb\xe1\ \xc4\x16\x77\xe2\xec\x1f\x56\x9c\x21\xd4\xff\x1e\x60\x4c\xac\x51\ \x94\xa5\xb6\x81\x89\xe6\x92\x55\x98\xee\xb8\x56\x58\xd0\x40\xb0\ \xb5\x6e\x18\xa3\xd7\x32\xa6\x76\x15\x22\x92\xce\x57\xb0\x03\xb2\ \xaf\x6e\x9f\xc2\xdc\xa1\xe9\x7d\xf0\xfc\x10\x80\xba\x15\x78\xb4\ \x3d\xa9\xf7\x40\xdc\x3d\x02\x0f\xbc\x79\xd3\x28\xbd\x7b\x11\xf1\ \x15\xa9\xb2\xc4\x43\x33\x40\x3f\x08\xa2\x0a\x2a\x0e\xb1\x74\xfc\ \x57\xa5\xc7\x77\xca\x97\x56\xe8\x1e\xfe\x35\x16\x2e\x99\x30\xfa\ \x8a\x2a\x76\x37\x16\x01\xe7\xbc\x15\x8a\x83\x52\x36\x45\xa6\x02\ \x9e\x25\x93\xb9\x13\x53\xc0\x7c\x95\xc7\x8c\xff\xad\x61\x7c\xe0\ \x6f\x95\xe1\x91\x4b\xf3\xd1\x51\x57\x88\xac\xde\x18\x4c\x2c\x19\ \x45\xa0\x26\xec\x62\xad\x7e\x12\x4d\x85\x59\x19\xf3\x02\x1e\xec\ \x2b\xf0\xa4\xfc\x79\x39\xfa\x40\xdf\x65\xfc\x1b\xa3\x5e\x30\xdb\ \x08\x43\x9b\xd9\x5d\xca\xb5\xe6\x77\x9c\xcc\x82\x60\x38\x76\x56\ \x60\x26\x39\xbe\x83\xfa\xbc\x33\xe5\xda\xfa\x51\x00\xdb\x7d\x94\ \x90\x57\x58\xa4\x12\xd4\x3a\x03\x44\x18\x7b\x62\x4a\x46\xe9\xf9\ \x60\x37\x69\x2f\xb9\x5d\x85\x37\x69\xec\x8c\x6d\x23\x69\x61\x2a\ \x2d\xe6\xfa\x94\x14\x46\x4a\x40\x92\x6e\x28\x37\x2e\x20\xf8\x78\ \x96\x9e\xef\x6c\xd7\x4e\x4d\x10\x2b\x2f\x27\xcc\xb9\x26\x44\x38\ \x52\x7b\x33\xd1\x74\x05\x76\x44\x0e\x48\x72\xa5\x13\x20\xdc\x40\ \x47\x1e\xc5\x1b\x8b\x73\x17\x41\xe1\xe7\x5a\xf0\xe1\x02\x5b\xd9\ \x94\x48\xde\x5c\x84\xeb\x7c\xe4\x8b\x8b\x4b\x93\x9f\x3b\x75\xaa\ \x07\xa6\x72\x3c\x50\xc5\x32\x95\x2e\x4d\x75\xcd\xee\xd0\x5c\xef\ \xd5\x57\x6c\xd7\x44\xe6\xfd\x88\x72\xd5\xa1\xc7\xbe\x72\xac\x0d\ \x0c\xdf\x7d\xc2\xb1\x56\x2d\xa1\xba\x39\xe4\x43\x33\x83\xe8\x80\ \x9c\x35\x1a\x2a\x35\xf7\x56\x5c\xba\xdc\x48\xe5\x4c\x74\x7b\x05\ \xdd\x42\xe9\x0d\x46\x87\x92\xe1\x1e\x69\x8e\x04\x61\x9a\x93\xb1\ \x49\xe5\xb1\xe1\x5d\xe8\xea\x0e\x00\x25\x09\x03\x33\x5b\x6b\x3c\ \xf0\x6d\xad\x34\xde\xe8\x72\xaf\x40\x54\x7a\x3a\xcc\x89\xb1\x38\ \xd6\xbd\x1f\x3f\x60\x5a\x10\x4e\x2e\xf7\x37\x50\x42\xad\x05\xbb\ \x98\x54\xbb\xdf\xff\x65\x30\xf0\x8c\x08\x89\x8f\x98\x9c\x81\xbe\ \xa3\x83\x70\x94\x0a\x2a\xa5\x52\x2f\xaa\xba\x02\x3d\x11\x93\x64\ \x0f\x32\x92\x1b\x2b\x6d\x02\xe3\x5a\xf4\xc3\xba\xb3\x23\x77\x9c\ \x8f\xee\xcb\x83\x19\x65\x2c\x1d\x5b\x41\x79\x27\x32\xae\xd9\xf8\ \xb1\x8c\x4c\x95\x86\xf7\xd5\x95\xdb\xe8\x33\x57\x96\x86\xdf\xaa\ \x0d\x94\x2f\xb2\xaf\x9a\xfb\x3b\x6a\x36\xce\x4a\xae\x5b\xb5\xce\ \x22\xdd\x3a\x4b\x58\x69\x9f\x71\xe7\x6c\x68\x31\xd1\x2c\x23\x98\ \x17\x26\x5c\xa7\xbb\x67\xa6\x6c\x5b\x34\x4d\xf1\xb0\xf1\x83\xc1\ \xe1\xa0\x0c\x6f\xed\x8c\x49\xcb\xca\xe0\xdc\x5a\x82\x9b\x45\x2c\ \x18\xf5\x46\xd2\x9f\xa5\xa9\x75\xbf\x8f\xb4\xfd\x16\x13\x50\x85\ \xf1\x61\x05\x44\x58\x99\x34\x6b\xa7\xe2\xc5\xf3\x76\xe2\x8a\x8d\ \x63\xaa\x25\x09\xd2\xb8\x40\x2b\xbf\x3f\xae\xb2\xdf\x11\x04\xbc\ \xff\x34\x88\x53\xf3\x6e\x71\x37\xd6\x58\xac\xac\x5a\x0e\x6c\x67\ \x86\xb2\xb5\x4a\x68\xae\x6f\xeb\xc0\x57\xe2\x72\xad\x47\x79\x1d\ \xf5\x4e\x07\xe3\x02\x25\x67\x9b\x34\x5c\xf2\x3b\xc5\x5a\x5e\xaa\ \xb4\x7e\x79\xbf\xfc\x34\xa7\xfb\xe8\x4e\x28\x72\xfb\xf0\xfa\x13\ \x74\x33\xb0\x35\x31\x01\x32\x08\x79\x74\x2a\xcf\xc8\xb4\xa5\x4b\ \xb0\xa0\x83\xee\x7b\xd4\x22\x48\x34\x8a\xc0\xdf\x90\xff\x93\x46\ \xf8\xec\xc3\xde\x49\x13\x07\x18\x89\xe3\xb8\xc0\xc2\x30\x5b\x29\ \xe4\x59\x42\x2c\xc7\x9b\xe8\xfd\xfe\xa4\xd3\xef\xba\x93\x5e\xf0\ \x71\x8a\x3f\x4e\x38\xd9\x33\x37\xa6\x84\x4b\x68\xfb\x99\xdd\xee\ \xf7\x6c\x32\x9c\x76\x9d\xc9\x14\x33\xea\x03\xa7\x4b\xc5\x08\x72\ \x39\xd2\x18\xdb\xf8\x6c\xf2\x74\xca\xf3\x2f\x8e\xe2\xf2\x35\x02\ \x6a\x2c\x86\xe4\x5f\x38\x8a\x62\x54\x71\xff\x13\xc8\xf7\x8e\x73\ \x8c\x01\xe9\xad\x22\xe3\x29\x32\x3f\x08\x75\x51\x3d\xc1\x99\xc0\ \x78\x0c\xde\xca\xb8\xef\x98\x27\x09\xe8\xca\x47\x13\x9c\x9a\xcc\ \x26\xbf\x73\x1c\x44\x5d\xed\x14\x68\x5e\x27\x32\x04\xc4\xe5\x90\ \xd1\x11\x1d\xed\x98\xf3\xd5\xd0\x8f\x2c\x29\x6f\x1e\x84\x34\xc5\ \x22\x98\x77\x43\x31\x5a\x8a\x57\x29\xd0\xfd\x73\x90\x42\x99\x68\ \xf9\x29\xd0\xa5\x1b\x85\x81\x62\xa3\xa5\xa5\x1c\x47\x1c\x7d\x82\ \xc9\x3f\xbd\x48\x8f\x8f\xe1\x9f\xe7\x9f\x8f\x8f\xa3\xee\xf2\xc5\ \x9c\xff\xf3\x7c\x61\xa4\x91\x3f\x40\x6b\x93\x4d\xe8\x4a\x9e\xea\ \x7e\xcf\x36\xa5\x5e\xb5\xdf\xb7\xec\x63\x1d\x95\x63\x19\x9c\x44\ \xc3\x05\xa5\x78\xc8\x0b\xe8\xb1\xc3\x91\x00\x9a\xe5\x42\x3c\xb6\ \xf0\x22\xbc\xaf\xc5\xf8\x93\x3f\x7f\x7e\xf7\x16\x9d\x3c\x05\x2a\ \xee\xdd\xdd\xe2\x39\x10\x7c\xfa\xfc\x9e\x2d\xc3\x81\x66\x4d\x03\ \xc9\x26\xcf\x3f\xd7\x88\x4d\x60\xcd\x42\x73\x49\x25\xd5\xd5\x46\ \x4a\x5d\xfb\xe6\x87\xe2\xff\x34\xaf\x0b\x47\xe7\xde\xc1\x4a\x7f\ \x4b\x8d\x64\xbc\x50\xfe\xc3\x11\xe2\x52\x6e\x31\x3e\x90\xa3\x8e\ \x2f\xfa\x07\xff\x8e\xdc\x3c\x0e\x97\xe7\xd2\x20\x40\x45\xb1\xd4\ \x26\x55\xbb\x97\x20\x6b\xfe\x89\x14\x62\xb4\x44\x83\x2e\x32\xef\ \x29\x75\x62\x54\x9b\x1c\xc3\x7e\xe1\x83\x26\x7c\x87\xf7\xfb\x10\ \x13\x30\xd0\xe2\x18\x3f\xf5\x87\x3e\xf0\x8d\x8e\x51\xe2\xd6\xf0\ \xcd\x2d\x8b\x7f\x03\xb6\xd5\x89\x3c\x79\xfa\xa3\x11\x2f\x19\x00\ \x1f\x59\x6c\x81\x05\xaf\x16\xfc\x4b\x06\x74\x37\xea\x6d\x78\x06\ \xf6\x30\x66\x0a\xcf\xb0\xdb\x20\x30\x64\x2e\x39\x46\x4d\xfa\xb0\ \x0f\x98\xd1\x43\xa8\x06\xf6\xb1\xdf\xe3\x17\x58\x7d\xe8\x69\x40\ \xa6\xdf\x08\x56\x43\x08\x4b\x05\xd7\x3d\x9b\xed\x84\x15\x2a\xcc\ \xf2\x28\x18\xe0\x76\xbf\x18\xe8\x36\xa7\xc8\x34\x6b\x58\xec\x03\ \xa6\x2e\x2d\x95\xea\xdc\x9c\x7b\x5a\x26\x27\x14\xf9\x84\x1b\x98\ \x5f\x5c\x1a\xd7\xdd\xe5\xb5\x30\x02\x5e\x6a\xb9\x63\x36\x43\x37\ \x8c\x08\xaa\x3b\xa3\x7f\x54\x00\xaa\xd6\x05\x7f\xe7\x60\xa2\xc5\ \xa0\xab\x07\xc1\x15\x8f\x3a\x1f\x4f\x8c\x26\x53\xdf\xf8\x24\x0c\ \x1a\x02\xd9\x72\x5e\x26\x53\x2e\x95\x15\x85\x69\x03\xe0\xb9\xa7\ \x54\xd5\x90\xdf\xba\x84\x01\xb3\x84\xb3\xa8\xa4\x9b\x20\xe9\x30\ \x4c\xcb\x05\xa1\x37\x2b\xdb\xcd\xb1\xdd\x1c\x55\x7e\x6c\xb4\x08\ \x44\xe4\xc3\x6c\x32\x9f\x7a\x5a\x94\x0d\xf2\x0d\x60\xcf\x0b\xf2\ \xa1\x00\xed\x2d\x6a\xd1\x1e\x52\xf1\x99\x24\x7a\x22\x4e\xd9\x8e\ \x7b\x70\xdc\x71\xa5\x80\x72\x74\x16\xd2\xf3\x81\x3a\x64\xa5\x85\ \x57\x56\xf6\x57\x59\x41\x0f\x06\xd5\xec\x1e\x4b\x95\xa6\x91\x3b\ \xae\xb7\x98\xba\x07\x2b\x84\x86\xe0\x14\x40\xd6\xcb\xea\xb9\x44\ \x64\x97\xa8\x04\x16\xbd\x0b\x0f\x70\xab\xdd\xfc\x1e\x94\x82\x6c\ \xae\x4f\x1f\xf4\x5f\x5a\x22\xd7\x01\xc4\xbb\x56\xf8\x86\x48\x9d\ \x18\x62\x20\x00\xb4\x2f\xaa\x9a\x5d\x44\x88\xe1\xfa\x5c\xa9\xb2\ \x25\xfc\xa5\x8c\xa6\xd0\x10\xfd\x90\x54\x42\xab\x74\xeb\x93\x62\ \x58\x7c\x4e\x55\x46\x14\x8d\x0b\x10\x47\x68\x6f\x3e\xaf\x39\x00\ \x47\x51\xb7\xeb\x6a\x6f\x26\x8c\xe2\xe7\xf2\x85\x2e\xfe\x5a\x02\ \xbe\x9e\x10\x98\x7e\x41\xe9\x0f\x14\x5a\x0e\x8d\x86\x4f\x00\xc4\ \xac\x13\x79\x43\x5a\x47\xc9\x16\xea\x5c\x83\xf7\x40\xfd\xb7\x62\ \x58\x06\xf4\xc8\xc1\x48\x53\x50\x69\xdb\xe0\x58\xfe\x18\x42\x42\ \x6f\x5f\xe8\xed\xbe\x9f\x66\xc4\xc6\x37\x31\x09\x6e\x95\x94\x6c\ \x40\x63\x12\x33\xa4\x8b\x99\xc6\x24\xe6\x9c\x49\xcc\xa6\x98\x44\ \x3f\x2f\xdb\x2d\xb0\xdd\x42\x32\x89\x54\x32\x89\xf9\x64\x51\x63\ \x12\x29\xcf\x5e\x17\x4c\x22\xad\x33\x89\x9d\xf5\x0c\xa6\x55\xbc\ \xa5\x36\xa4\xa5\x0f\xc6\x58\xa5\xbb\x97\x96\xb8\x4a\xa7\x35\xdf\ \x01\x41\x84\xcf\x9b\x20\x1e\x66\xfa\xc9\x51\x18\xc2\x47\x79\x00\ \x31\xf8\x94\x04\xa3\x5f\x83\xe9\x68\x81\x95\xd0\x65\xae\x90\x3a\ \x5a\x3c\x9f\x8f\x16\x40\xa2\xbb\x94\xa3\x12\xb8\xce\x28\x25\x6c\ \x55\x62\xc8\xd0\x37\x28\x8e\x1d\x2d\x24\xf5\xd2\x95\xc8\x75\xe3\ \x6f\x2d\xe0\x93\x45\xf2\x61\xa3\x81\xc7\x1d\x7c\x03\xee\x6c\x1b\ \xe0\x93\x18\x4a\xfe\x29\x81\x56\x4d\xd0\xa8\x79\xd0\x8e\x8f\xf5\ \x68\x13\xb7\xee\xad\x2b\x95\x18\x33\x78\xa7\xea\x3a\x6a\xf4\xd5\ \x6b\xda\x92\xf2\xd7\xa3\xc2\xd9\x89\xfb\x72\x6d\xa6\x13\x5e\x59\ \x30\x66\x8c\x8b\x56\xac\x1c\xfd\x56\xef\xbd\x6b\xcb\x7b\x2d\xad\ \x1f\xf1\x94\xd4\x38\x69\xf0\x8f\x8b\x7a\x8f\x26\x71\x7d\xfa\x97\ \x5e\xab\x45\x4a\xe5\xbb\x00\x7b\x5b\xbe\x7a\xd6\xc1\x3c\x3b\xda\ \x14\x59\xfe\x52\x5c\xca\x1d\x18\x96\x48\x94\xc5\x74\xaf\x42\xd7\ \x2b\x98\x79\x9b\xad\x03\x7e\x17\x52\xba\xa3\x54\x9a\xd9\x36\x2f\ \xb2\x1b\x81\x01\xb3\x50\x6a\x2d\xa5\xa5\xe7\x3e\xa8\x95\xfe\x8a\ \x1a\xf7\x74\xd2\x4d\x4b\xeb\x01\x9e\x3f\x56\x75\x0f\x22\x73\xb5\ \x87\xfb\xde\xe9\x7d\xd3\x97\x7f\x7f\x6b\x85\x9e\x07\xb4\xa5\x5d\ \xb9\x0b\x4a\x7d\xbb\xee\x1f\x4f\x6c\xe7\x7d\x03\xaa\x7d\xae\xa8\ \x8d\xd5\xe8\x2b\x8b\x12\x17\x92\x1d\x8f\x8e\x0c\xa5\x44\xd2\x53\ \xbd\x9a\x00\xc7\x5c\x64\xfd\x16\xc0\xa2\x50\x4a\x6a\x37\x1a\x8e\ \x8c\xaf\x60\x27\x80\xae\xea\xb0\xb3\xa0\x55\xde\x6e\x56\x9e\x5a\ \x8b\x2a\xc7\x4a\xe5\x48\xba\x6e\x19\xd8\xc2\xf0\x65\xa0\x4a\xbb\ \x18\x6b\x28\x63\xa7\xdd\xa8\x97\xdc\xef\xb4\x46\x5e\x8a\xf8\x00\ \x31\x25\x2e\x0d\xcb\x47\x91\xd5\xbb\x5b\xca\x39\x7f\xf0\xb6\xeb\ \xc4\x88\xd1\x97\x4f\xfa\x1d\xa1\x32\x0c\x58\xb5\xa5\x2e\x00\xab\ \x98\xab\x0b\xf4\xfd\x5e\xfd\x36\xd6\xa4\x3f\x7e\xd8\x71\x7b\xea\ \x8e\x21\xaa\x79\xe6\xe5\x93\x91\xf8\xb6\x17\x3e\xdb\x88\x57\x0e\ \x0f\x69\x2f\xde\x69\x94\x5d\xdc\xd1\x5c\x5e\x66\x23\x4c\xf4\xd3\ \x02\x92\xa0\xe6\x87\xcc\xc0\x9f\x1e\x7b\x0c\x48\xf4\x94\x24\xf4\ \x68\x11\x48\x20\x5c\x0e\x91\x41\x53\xf8\x68\x9d\x4e\x9a\xf2\x5c\ \xd0\x63\x4d\x4a\x21\x36\xa6\x70\xdd\x91\x39\x25\x39\x8d\x8d\x81\ \x5d\x93\x76\xfb\xb4\xaf\xa0\xaf\x99\xad\xc8\x38\x33\x6f\x12\x8d\ \x53\x56\xca\x27\xae\x93\x1b\x21\xe3\x56\x76\xc7\x90\xdd\x31\x60\ \x77\x3c\x31\xb9\x7e\x0f\x6b\x92\xb9\x57\x65\x0d\x6c\xaa\xbf\x91\ \xe2\xaa\x2c\x39\xd3\x05\x52\xbb\x02\x61\x55\xd6\xe3\x0a\xaa\x8d\ \xc4\x15\x62\x05\x88\x86\x09\xbd\xc8\x98\x5d\x05\x5e\x1b\xed\x47\ \x71\xc0\xe8\x91\xb0\xb6\xe5\x32\xa6\x06\x49\xc3\x65\x0c\xab\x5d\ \xc6\xb4\x2a\xb7\xaf\x0d\xb7\x31\xf6\x09\x82\x01\x0f\xbf\x74\xeb\ \x10\x95\x8f\x9f\x0c\xeb\x50\x18\xa1\x81\x38\x4e\xed\x0e\xb8\x01\ \x8a\xd8\x0e\xc5\xb0\x82\x97\x8a\xd2\x71\x54\x43\x67\x3c\x45\x24\ \x0f\x2f\x7e\x02\xdd\x8f\x3f\xd9\x56\x6a\xd3\x55\xc7\xc6\xc4\x02\ \x43\xe9\x39\x5d\xd2\xb3\x80\x20\xe7\x9c\xa9\x67\x49\xf6\xd1\x0d\ \x72\x19\xe6\xd8\x48\x14\xb1\x41\x14\x9a\xd6\x35\x57\xd6\x90\x2b\ \xcd\x7a\xa3\xf6\xe1\x30\x22\x57\x56\x49\x8f\x8b\x5e\x6b\xe6\x3e\ \x8f\x10\x15\x5a\xd9\x0c\x34\x0c\x73\x78\xae\xe1\xb0\x8a\xeb\x5a\ \x4b\x2f\x93\x1b\x6c\xcb\x07\x30\xa1\x92\x0f\x6d\x19\x81\x09\x8c\ \x0c\x6f\x1e\x1b\xe1\xd7\xab\xa9\xb2\x11\x55\x46\x16\xe9\x03\xe2\ \x19\xee\xa4\xc5\x86\x6e\x3a\x35\xca\xf5\x5b\xd8\x9c\x15\x0b\x34\ \x92\xc1\x23\xff\xfd\xc7\xe1\xa0\xf4\x18\x8a\xeb\xb5\xa8\x30\xc6\ \xfd\x02\xf7\xb7\x6a\xe6\x5b\x24\x6d\x8a\x71\xa2\x7e\x6b\x79\x46\ \x3a\x99\x4e\x04\xa8\x1a\x87\x05\x2a\xf5\xa3\xf2\x4a\x3c\x5e\xe2\ \x8b\xa9\x96\xfb\x70\x2c\xef\xb8\x35\x83\x6f\x14\xaa\x4c\x20\x19\ \x7a\x4e\x87\x69\xbf\x47\x68\x64\xd6\x24\xde\x84\x50\xda\xe4\xb8\ \x2c\xac\x0d\x56\x79\xe6\x14\x3f\xf5\xc7\x6a\x43\x7e\xb5\xcb\x9f\ \xef\x1c\x48\x0f\x44\xc5\x22\xa1\x8d\x50\x57\xf6\xfc\xb5\x33\x30\ \xe5\x6c\x13\x91\xaa\x43\x97\x4e\xc2\xd0\x6b\x6e\x26\xee\xa1\x24\ \xab\xa9\xe7\x15\x54\x12\x3d\x3c\x95\x8b\x52\x6b\x84\x47\xdb\xf5\ \xca\x2c\x94\x5a\x03\xe1\x62\x95\x0b\xd5\x01\xc5\x1c\x36\x87\xbf\ \x11\x69\xe6\x80\xba\xc2\x65\x5e\x93\x9f\x52\xbd\x71\x2b\xa3\x09\ \xad\x3b\x68\x1a\x4d\xa8\x67\xb5\xe1\xa4\x0a\x57\xbe\x03\x00\xc4\ \x6b\x4f\xe0\xa8\x59\xc4\xea\xc5\x2c\xf5\x60\x96\xf6\x50\x64\xdb\ \x11\xa1\xe5\x69\xce\xaf\x51\xf1\x6d\x80\x30\xa0\xc8\x9a\x6e\xc8\ \x59\x2c\x60\x14\x7e\x0d\xa7\xf8\x4c\x37\xff\xd3\x27\x1c\x51\x29\ \xc0\x60\x58\xd3\xe5\xcd\x82\xb8\x5e\xa4\x7b\x07\x3d\xfa\x86\xf7\ \x26\x8f\xf6\x5d\xdd\x35\x7b\xbd\x76\x61\xd6\x0b\xfb\x7c\x80\x86\ \xc1\x71\x93\x1b\x86\x46\x63\x2b\x2c\x2f\x5a\xb4\xe8\x1c\xde\x33\ \x22\x15\xf5\x8e\xce\xad\x06\xb8\x16\x32\xbe\x9a\x86\xa8\x0d\x4f\ \x2e\x6f\xdd\xb9\x50\x4b\x0e\xd5\x1d\x16\x46\xba\x85\x5e\xd1\xa1\ \x8b\x19\xe9\x96\xd7\x6a\x4a\x0b\x55\x49\x77\x2d\x2f\x4a\x7b\xb0\ \xdf\x1e\x68\xae\x07\xa2\x5b\x84\x6f\xa5\xb5\x57\x9b\x9e\x44\xae\ \xd8\x74\x4b\x4e\x86\x1e\x53\x3a\xa2\x2d\x68\x6c\xc5\x63\x70\x0f\ \x36\x47\x4e\x3d\x60\x4a\x0a\xdb\x4a\xbc\x94\x08\x9b\x97\xae\x05\ \x7b\xad\xf9\xae\x17\xbe\x73\x5c\xdc\x60\x7c\x4a\x62\x3c\xf0\x01\ \x47\xa1\xc5\xd3\xdb\xa4\x2b\xea\x20\xce\xdf\x8e\xb2\xc2\x78\x68\ \x57\x25\x26\x4b\xdf\x17\xce\x57\xe8\x39\x6e\x58\x18\xbd\x66\xef\ \x52\x9c\xd6\x40\xf0\x22\x81\xb6\x07\x8e\x82\x48\xac\x0c\x73\x20\ \xfa\x32\x13\xcb\x74\x0a\xb3\xd3\x84\xfa\xa3\x0d\xc6\x65\x8f\x91\ \xb2\x25\x33\x2d\xdc\xda\xa2\x7b\x15\x70\xf5\x14\x20\xe2\xb3\x02\ \xb8\x7a\x90\xbd\xbe\xcf\x3a\x06\xee\x1a\x92\x38\xf3\xbd\x63\x12\ \x85\x09\xfd\x5f\x03\x59\x6d\x1e\x0a\x7c\x2d\x35\xb2\x76\x0c\xc5\ \xa1\x15\xec\xcf\x84\xa7\x26\x2e\xa8\x31\xd9\x9d\x5e\x8b\x60\xe3\ \xcc\xf2\x41\xfd\xae\x35\x2c\x29\xb8\x6a\xf9\x45\x35\x08\x6b\xdc\ \xc7\x90\xb4\x92\x69\x68\x9e\x20\x43\xc4\xea\xf5\xca\xb1\x43\xf9\ \xdb\x5a\x8a\xdc\x3d\xf7\x80\x3c\x20\x5e\xcb\xb3\x0b\x94\x8a\xe1\ \x9a\xe5\xda\x94\xa6\x82\x61\x1b\x42\x1e\x6c\xbc\x75\xaf\x54\x51\ \xf8\xbb\x63\xe4\x4e\xf1\xaa\xc9\xc0\x08\xbe\x94\x14\x7d\x67\x3c\ \xa8\xd7\xd0\xa7\x39\x92\xd3\x4b\x9a\x81\x1d\xab\x24\x36\xbf\x1a\ \xa4\x7f\xa7\x10\xab\x09\x2f\xaf\x73\xd7\x2c\xb5\x49\x4a\x8f\x8e\ \xc1\x10\xf5\x50\x3d\x3a\x12\xb4\xcb\x8d\xd0\x08\xd1\x55\x95\x58\ \xe4\x97\x3a\xf9\xbf\xca\x73\xb6\xa7\x89\xf7\x22\xae\xed\x7f\x89\ \x97\x14\x0c\x88\x5d\x15\xec\x50\x29\x47\x3f\x57\x58\x2b\x2d\x65\ \x16\xf9\xcf\x79\xcc\x5a\xe5\xfd\xf9\xa3\xd2\x0d\x56\xdf\xfc\x1a\ \xe3\x2c\x47\x68\xe4\x95\xd6\xd6\x86\x07\x49\xb6\xb4\x6c\x51\x95\ \xdd\x57\xe7\xd3\x38\x7c\xeb\x01\xf3\xe9\x1c\xc0\xad\xe7\x4b\xcb\ \xe5\xc5\x63\xf5\x6a\x8f\x4c\xc7\xa0\xbf\x44\x22\xff\x82\x03\xff\ \x42\x5b\x42\xff\xec\x3d\x0a\x2d\xd6\xd6\xa6\x9f\xcc\x04\xf4\xe1\ \x74\x2d\x90\x66\x59\x85\xf8\x63\x2b\xe6\x1f\xa2\x28\xd7\x21\x29\ \xf7\x41\xf8\x7e\xc0\x3a\xa4\x0b\xf2\xbe\x85\x34\x1d\x89\x03\xf9\ \xe3\xcc\xac\x94\x7a\x10\xfd\x51\xe4\x4a\xb3\x51\xca\x4f\x8c\x2d\ \xd4\x95\xb0\xf1\xd0\xef\x0d\xf5\x18\x9b\x46\x65\xed\xe8\xde\xbc\ \xc1\xef\x56\xd7\xc6\xb5\x62\xbf\xd6\xdb\x63\xc1\x49\x07\xf5\xa2\ \x3d\x32\x17\xf7\x24\x15\x7f\x3a\x4b\x53\xa3\x0c\xd5\x20\xaa\x85\ \x31\xe9\xec\xf5\x49\xd8\xb5\x33\xd8\x27\x61\xaf\x53\xaa\x5d\x79\ \x38\x0b\x37\xa9\xbc\x19\x33\x30\x43\x7f\x57\x6a\x3c\xf0\x6d\xfa\ \x8c\xa8\xec\xdd\xa9\x70\xf8\x0c\x7a\xc7\x46\xce\xd8\x93\x50\xa8\ \x21\x51\x3d\x58\xca\x90\x28\x76\xf8\xa9\xc6\xb6\x80\xd6\x8f\x5e\ \x01\xa9\x37\xc6\x12\x44\xba\xd7\x93\x50\x68\x81\x66\x8a\x6c\x53\ \xa8\x69\x99\x9f\xfa\x9f\x4f\x7e\xf7\x28\xb7\x0f\x59\x84\xbd\xde\ \x0e\xb7\x8d\x3a\xca\x0b\xe4\xea\xe3\x0e\x14\xa1\x38\x93\xcf\x33\ \xf0\xc0\x5b\x7a\x8d\x41\x19\x38\x95\x67\x1f\x34\x6d\x5d\x93\x95\ \x65\x2e\xa6\xf9\x3e\x45\x69\x33\x3f\xaf\xf6\x41\x68\x67\x81\xa5\ \xb4\x21\x1a\xb0\xcc\x73\xfc\xd3\x32\x05\x66\xeb\xd6\xc6\x1a\x4e\ \xdd\x79\x7d\x86\xa1\x6d\x06\x61\x64\xdf\xbd\x86\x17\xb5\xb1\x9e\ \x5a\xd7\xf0\xf4\xbb\xd7\x50\x9f\xe1\x99\x75\x0d\xcf\x1a\xd6\x40\ \xcf\x28\xe0\x8b\x5f\xee\x4e\x74\x33\x1e\xdb\xe8\x72\x21\xb7\xc9\ \xb6\xf8\xb7\xe7\xe6\xbd\x56\xbd\x85\x7b\x42\xfd\x11\x79\x4f\xd4\ \xcf\x51\x1d\x86\xf1\x11\x0c\xf0\xe0\x8d\xd8\xef\x1b\x1a\x5b\x57\ \x3c\x9e\xfb\x8f\x1a\x1d\x3a\xf4\x14\xac\xfe\xbc\xab\xfd\x1e\xcd\ \xea\x68\xf8\x87\x81\x06\x11\xb6\x6c\x34\x50\x58\x18\x94\x58\x18\ \x4c\x47\xf5\xbd\x06\x2c\xcc\x1e\x41\xf1\xfb\x7d\x53\x6b\x2b\x6d\ \x8d\x67\xfe\xe3\xc6\x87\x1e\x3d\x05\xae\x3f\xeb\x6a\xbf\xe5\xdf\ \x28\xe4\x82\x50\x6d\x7d\x05\xb9\x8f\x35\x3d\xba\x8f\x94\x8b\x3f\ \x50\x2c\x92\x4c\x6c\x42\xce\xe3\xed\xae\xff\x0f\x4b\x69\x96\x8f\ \x07\x1e\x07\x27\x6e\x4b\x2a\x2f\x38\xf1\x87\xfb\xc7\x71\xd5\xe7\ \x4d\x1a\x9c\x99\xdd\x04\x2a\x42\x5a\xf3\x96\x63\x8c\x0f\xe8\x84\ \xbf\xb1\x59\xb6\x61\xd6\xcc\x58\xa2\x85\x32\x93\x55\x46\x90\xab\ \xd1\xb4\x71\x31\xff\xf6\x2a\x8d\x96\x18\xf6\x20\x6d\x9e\x2d\xde\ \xaf\x06\xfa\xc7\xb8\xdb\xd5\x3f\x7d\xd2\x26\xe9\xf8\x78\x73\xa3\ \xe9\x88\x2c\xb7\xbe\xfd\xfd\xe4\x79\x10\xcc\x64\x4b\xfc\xab\x31\ \xb5\x70\xe1\x23\x7c\xde\x7a\xc0\xef\xa2\x31\x5f\xb0\xa2\xef\xf2\ \x89\xca\x5c\x4d\x0a\xac\x27\xc5\x76\x32\x1d\x89\x27\x5f\xb5\xc4\ \x2b\xcb\x9b\x3e\xf2\x5d\x20\xf3\x6f\xaa\xe8\xf7\x46\x91\x86\x59\ \xfd\xa6\x7d\x54\x1b\x9e\x6e\x29\xcd\xd7\x6d\x1a\x6f\x2c\x76\xc6\ \xdf\x96\xa3\xb1\xca\x94\x43\x75\xb9\xad\x8a\xf0\x0f\x1f\x05\xf4\ \x88\xa4\xcc\x2a\xae\xd4\xc9\x27\xde\x2c\x95\x2d\x47\x5a\xb0\xff\ \x72\xaa\xa3\x96\xc3\x69\x49\x77\xe4\xe5\xb3\x4d\x76\xf3\x76\x5b\ \xe4\x29\x26\xd2\x1d\x45\x2a\x93\x4a\xff\x6b\x94\x34\xb1\xba\x50\ \x03\xda\x64\xa8\x2f\xe1\x5f\x6e\xe4\x35\xda\x9d\x9a\x3e\x1e\x4f\ \xd5\xc2\x3f\x9a\x57\xad\x10\x38\xa9\x66\xcd\xd5\xe3\xd7\xc4\x5b\ \x51\x77\x44\xfc\x72\x46\x5e\x1f\x8d\x13\x8a\x6d\xbc\xf2\x65\x29\ \x97\xa7\x07\xdc\xbf\x5a\xba\x8a\xac\x2d\x56\x2e\xee\x9e\x1c\x75\ \x1b\x35\xb9\xbb\x88\x47\x32\xdd\x8b\x66\xfe\x67\xc0\xbc\x96\x6d\ \x66\x24\xc8\x07\x46\x6f\x3c\x26\x6e\xc2\x06\x2e\xc7\xd3\xce\x02\ \xaf\x8c\x36\x52\x7f\xb5\x09\xce\x89\x8d\x4c\xe6\xb6\xab\xd7\xc3\ \x41\xfb\xb3\xa1\x75\xa0\xf8\x5f\xb5\x7c\xec\x8c\x72\xab\xbe\x6f\ \x42\x8a\x6d\x7d\x08\x52\x1b\xf6\xef\x1e\xe8\xf4\x9c\xe0\xfb\x21\ \xac\x06\x22\x12\x4e\x1e\x11\xa8\xf2\x78\x00\x79\xf4\xca\x77\x6e\ \xd6\xc3\xa0\xc2\x5c\x63\x83\x8b\xf1\x17\xcf\xc0\x34\xb4\x3f\x89\ \x56\x6f\x2a\x19\xb9\xf1\xe0\x99\x99\x00\x6c\x3e\x6b\x66\x69\xae\ \xbd\xd9\xad\xbf\x5c\xe6\xd6\x06\x91\xef\x93\xd5\xdb\x4a\xe6\x3e\ \x76\x1c\xdf\x32\x52\xe5\x25\x2c\xf3\x61\x27\xca\x98\x27\xef\xfd\ \x7b\x3c\xe2\xe1\x52\x3a\x83\xaa\x1c\x80\xa4\x19\x3e\xc0\x50\x8f\ \x2a\x72\x25\x0f\xc0\xbf\x2e\x2a\xc3\xb1\xf9\x5f\x17\x8d\x39\xf2\ \xd5\x76\x59\xde\x88\xe0\x03\xd6\xc6\x33\x1f\x09\x8f\xa4\xe0\xb2\ \x42\xd3\x10\x05\xf2\xaf\x26\x83\x3f\xe8\x95\xbf\x6a\xa2\xb7\x56\ \xa8\x84\x3a\x22\xf3\x47\xa3\xa7\x2a\xc5\x02\x33\x37\x90\xde\x28\ \xab\xfd\xed\x21\x7c\x27\xa3\xfe\xd6\xac\x68\x66\x7f\x69\x36\x50\ \x2f\xe7\x68\x04\xd3\xe1\x99\x6c\x04\x4d\x73\xfc\xac\xf4\xb0\x89\ \x6c\x77\x19\x33\x62\x3c\x1a\x1d\x99\x21\xb5\x49\x67\x32\x75\xcb\ \xa0\x89\x48\xb9\x22\xbd\xaa\xbf\x01\xdd\xad\x95\x22\x8f\x94\x77\ \xad\xd7\x69\x24\x72\x7b\x8c\xd0\x46\x2f\x67\xf8\x62\xb9\x1f\x8e\ \xd5\x5f\xb6\xa5\xc4\x7a\x7c\x4d\x56\x65\xea\x73\x49\x25\x45\xbc\ \xb7\xfb\x42\xef\x99\xfb\x0e\xbd\xa1\xee\x54\x9e\x5c\xff\x7f\x2f\ \x2e\x80\x20\ \x00\x01\x6e\xac\ \x2f\ \x2a\x21\x20\x6a\x51\x75\x65\x72\x79\x20\x76\x31\x2e\x37\x2e\x31\ \x20\x6a\x71\x75\x65\x72\x79\x2e\x63\x6f\x6d\x20\x7c\x20\x6a\x71\ \x75\x65\x72\x79\x2e\x6f\x72\x67\x2f\x6c\x69\x63\x65\x6e\x73\x65\ \x20\x2a\x2f\x0a\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x29\x7b\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x63\x79\x28\x61\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x69\x73\x57\x69\x6e\ \x64\x6f\x77\x28\x61\x29\x3f\x61\x3a\x61\x2e\x6e\x6f\x64\x65\x54\ \x79\x70\x65\x3d\x3d\x3d\x39\x3f\x61\x2e\x64\x65\x66\x61\x75\x6c\ \x74\x56\x69\x65\x77\x7c\x7c\x61\x2e\x70\x61\x72\x65\x6e\x74\x57\ \x69\x6e\x64\x6f\x77\x3a\x21\x31\x7d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x20\x63\x76\x28\x61\x29\x7b\x69\x66\x28\x21\x63\x6b\x5b\x61\ \x5d\x29\x7b\x76\x61\x72\x20\x62\x3d\x63\x2e\x62\x6f\x64\x79\x2c\ \x64\x3d\x66\x28\x22\x3c\x22\x2b\x61\x2b\x22\x3e\x22\x29\x2e\x61\ \x70\x70\x65\x6e\x64\x54\x6f\x28\x62\x29\x2c\x65\x3d\x64\x2e\x63\ \x73\x73\x28\x22\x64\x69\x73\x70\x6c\x61\x79\x22\x29\x3b\x64\x2e\ \x72\x65\x6d\x6f\x76\x65\x28\x29\x3b\x69\x66\x28\x65\x3d\x3d\x3d\ \x22\x6e\x6f\x6e\x65\x22\x7c\x7c\x65\x3d\x3d\x3d\x22\x22\x29\x7b\ \x63\x6c\x7c\x7c\x28\x63\x6c\x3d\x63\x2e\x63\x72\x65\x61\x74\x65\ \x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x69\x66\x72\x61\x6d\x65\x22\ \x29\x2c\x63\x6c\x2e\x66\x72\x61\x6d\x65\x42\x6f\x72\x64\x65\x72\ \x3d\x63\x6c\x2e\x77\x69\x64\x74\x68\x3d\x63\x6c\x2e\x68\x65\x69\ \x67\x68\x74\x3d\x30\x29\x2c\x62\x2e\x61\x70\x70\x65\x6e\x64\x43\ \x68\x69\x6c\x64\x28\x63\x6c\x29\x3b\x69\x66\x28\x21\x63\x6d\x7c\ \x7c\x21\x63\x6c\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\ \x6e\x74\x29\x63\x6d\x3d\x28\x63\x6c\x2e\x63\x6f\x6e\x74\x65\x6e\ \x74\x57\x69\x6e\x64\x6f\x77\x7c\x7c\x63\x6c\x2e\x63\x6f\x6e\x74\ \x65\x6e\x74\x44\x6f\x63\x75\x6d\x65\x6e\x74\x29\x2e\x64\x6f\x63\ \x75\x6d\x65\x6e\x74\x2c\x63\x6d\x2e\x77\x72\x69\x74\x65\x28\x28\ \x63\x2e\x63\x6f\x6d\x70\x61\x74\x4d\x6f\x64\x65\x3d\x3d\x3d\x22\ \x43\x53\x53\x31\x43\x6f\x6d\x70\x61\x74\x22\x3f\x22\x3c\x21\x64\ \x6f\x63\x74\x79\x70\x65\x20\x68\x74\x6d\x6c\x3e\x22\x3a\x22\x22\ \x29\x2b\x22\x3c\x68\x74\x6d\x6c\x3e\x3c\x62\x6f\x64\x79\x3e\x22\ \x29\x2c\x63\x6d\x2e\x63\x6c\x6f\x73\x65\x28\x29\x3b\x64\x3d\x63\ \x6d\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\ \x61\x29\x2c\x63\x6d\x2e\x62\x6f\x64\x79\x2e\x61\x70\x70\x65\x6e\ \x64\x43\x68\x69\x6c\x64\x28\x64\x29\x2c\x65\x3d\x66\x2e\x63\x73\ \x73\x28\x64\x2c\x22\x64\x69\x73\x70\x6c\x61\x79\x22\x29\x2c\x62\ \x2e\x72\x65\x6d\x6f\x76\x65\x43\x68\x69\x6c\x64\x28\x63\x6c\x29\ \x7d\x63\x6b\x5b\x61\x5d\x3d\x65\x7d\x72\x65\x74\x75\x72\x6e\x20\ \x63\x6b\x5b\x61\x5d\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x63\ \x75\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x7b\x7d\x3b\ \x66\x2e\x65\x61\x63\x68\x28\x63\x71\x2e\x63\x6f\x6e\x63\x61\x74\ \x2e\x61\x70\x70\x6c\x79\x28\x5b\x5d\x2c\x63\x71\x2e\x73\x6c\x69\ \x63\x65\x28\x30\x2c\x62\x29\x29\x2c\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x63\x5b\x74\x68\x69\x73\x5d\x3d\x61\x7d\x29\x3b\ \x72\x65\x74\x75\x72\x6e\x20\x63\x7d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x20\x63\x74\x28\x29\x7b\x63\x72\x3d\x62\x7d\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x20\x63\x73\x28\x29\x7b\x73\x65\x74\x54\x69\x6d\ \x65\x6f\x75\x74\x28\x63\x74\x2c\x30\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x63\x72\x3d\x66\x2e\x6e\x6f\x77\x28\x29\x7d\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x20\x63\x6a\x28\x29\x7b\x74\x72\x79\x7b\x72\ \x65\x74\x75\x72\x6e\x20\x6e\x65\x77\x20\x61\x2e\x41\x63\x74\x69\ \x76\x65\x58\x4f\x62\x6a\x65\x63\x74\x28\x22\x4d\x69\x63\x72\x6f\ \x73\x6f\x66\x74\x2e\x58\x4d\x4c\x48\x54\x54\x50\x22\x29\x7d\x63\ \x61\x74\x63\x68\x28\x62\x29\x7b\x7d\x7d\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x20\x63\x69\x28\x29\x7b\x74\x72\x79\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x6e\x65\x77\x20\x61\x2e\x58\x4d\x4c\x48\x74\x74\x70\ \x52\x65\x71\x75\x65\x73\x74\x7d\x63\x61\x74\x63\x68\x28\x62\x29\ \x7b\x7d\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x63\x63\x28\x61\ \x2c\x63\x29\x7b\x61\x2e\x64\x61\x74\x61\x46\x69\x6c\x74\x65\x72\ \x26\x26\x28\x63\x3d\x61\x2e\x64\x61\x74\x61\x46\x69\x6c\x74\x65\ \x72\x28\x63\x2c\x61\x2e\x64\x61\x74\x61\x54\x79\x70\x65\x29\x29\ \x3b\x76\x61\x72\x20\x64\x3d\x61\x2e\x64\x61\x74\x61\x54\x79\x70\ \x65\x73\x2c\x65\x3d\x7b\x7d\x2c\x67\x2c\x68\x2c\x69\x3d\x64\x2e\ \x6c\x65\x6e\x67\x74\x68\x2c\x6a\x2c\x6b\x3d\x64\x5b\x30\x5d\x2c\ \x6c\x2c\x6d\x2c\x6e\x2c\x6f\x2c\x70\x3b\x66\x6f\x72\x28\x67\x3d\ \x31\x3b\x67\x3c\x69\x3b\x67\x2b\x2b\x29\x7b\x69\x66\x28\x67\x3d\ \x3d\x3d\x31\x29\x66\x6f\x72\x28\x68\x20\x69\x6e\x20\x61\x2e\x63\ \x6f\x6e\x76\x65\x72\x74\x65\x72\x73\x29\x74\x79\x70\x65\x6f\x66\ \x20\x68\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x28\x65\ \x5b\x68\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\ \x5d\x3d\x61\x2e\x63\x6f\x6e\x76\x65\x72\x74\x65\x72\x73\x5b\x68\ \x5d\x29\x3b\x6c\x3d\x6b\x2c\x6b\x3d\x64\x5b\x67\x5d\x3b\x69\x66\ \x28\x6b\x3d\x3d\x3d\x22\x2a\x22\x29\x6b\x3d\x6c\x3b\x65\x6c\x73\ \x65\x20\x69\x66\x28\x6c\x21\x3d\x3d\x22\x2a\x22\x26\x26\x6c\x21\ \x3d\x3d\x6b\x29\x7b\x6d\x3d\x6c\x2b\x22\x20\x22\x2b\x6b\x2c\x6e\ \x3d\x65\x5b\x6d\x5d\x7c\x7c\x65\x5b\x22\x2a\x20\x22\x2b\x6b\x5d\ \x3b\x69\x66\x28\x21\x6e\x29\x7b\x70\x3d\x62\x3b\x66\x6f\x72\x28\ \x6f\x20\x69\x6e\x20\x65\x29\x7b\x6a\x3d\x6f\x2e\x73\x70\x6c\x69\ \x74\x28\x22\x20\x22\x29\x3b\x69\x66\x28\x6a\x5b\x30\x5d\x3d\x3d\ \x3d\x6c\x7c\x7c\x6a\x5b\x30\x5d\x3d\x3d\x3d\x22\x2a\x22\x29\x7b\ \x70\x3d\x65\x5b\x6a\x5b\x31\x5d\x2b\x22\x20\x22\x2b\x6b\x5d\x3b\ \x69\x66\x28\x70\x29\x7b\x6f\x3d\x65\x5b\x6f\x5d\x2c\x6f\x3d\x3d\ \x3d\x21\x30\x3f\x6e\x3d\x70\x3a\x70\x3d\x3d\x3d\x21\x30\x26\x26\ \x28\x6e\x3d\x6f\x29\x3b\x62\x72\x65\x61\x6b\x7d\x7d\x7d\x7d\x21\ \x6e\x26\x26\x21\x70\x26\x26\x66\x2e\x65\x72\x72\x6f\x72\x28\x22\ \x4e\x6f\x20\x63\x6f\x6e\x76\x65\x72\x73\x69\x6f\x6e\x20\x66\x72\ \x6f\x6d\x20\x22\x2b\x6d\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x22\ \x20\x22\x2c\x22\x20\x74\x6f\x20\x22\x29\x29\x2c\x6e\x21\x3d\x3d\ \x21\x30\x26\x26\x28\x63\x3d\x6e\x3f\x6e\x28\x63\x29\x3a\x70\x28\ \x6f\x28\x63\x29\x29\x29\x7d\x7d\x72\x65\x74\x75\x72\x6e\x20\x63\ \x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x63\x62\x28\x61\x2c\x63\ \x2c\x64\x29\x7b\x76\x61\x72\x20\x65\x3d\x61\x2e\x63\x6f\x6e\x74\ \x65\x6e\x74\x73\x2c\x66\x3d\x61\x2e\x64\x61\x74\x61\x54\x79\x70\ \x65\x73\x2c\x67\x3d\x61\x2e\x72\x65\x73\x70\x6f\x6e\x73\x65\x46\ \x69\x65\x6c\x64\x73\x2c\x68\x2c\x69\x2c\x6a\x2c\x6b\x3b\x66\x6f\ \x72\x28\x69\x20\x69\x6e\x20\x67\x29\x69\x20\x69\x6e\x20\x64\x26\ \x26\x28\x63\x5b\x67\x5b\x69\x5d\x5d\x3d\x64\x5b\x69\x5d\x29\x3b\ \x77\x68\x69\x6c\x65\x28\x66\x5b\x30\x5d\x3d\x3d\x3d\x22\x2a\x22\ \x29\x66\x2e\x73\x68\x69\x66\x74\x28\x29\x2c\x68\x3d\x3d\x3d\x62\ \x26\x26\x28\x68\x3d\x61\x2e\x6d\x69\x6d\x65\x54\x79\x70\x65\x7c\ \x7c\x63\x2e\x67\x65\x74\x52\x65\x73\x70\x6f\x6e\x73\x65\x48\x65\ \x61\x64\x65\x72\x28\x22\x63\x6f\x6e\x74\x65\x6e\x74\x2d\x74\x79\ \x70\x65\x22\x29\x29\x3b\x69\x66\x28\x68\x29\x66\x6f\x72\x28\x69\ \x20\x69\x6e\x20\x65\x29\x69\x66\x28\x65\x5b\x69\x5d\x26\x26\x65\ \x5b\x69\x5d\x2e\x74\x65\x73\x74\x28\x68\x29\x29\x7b\x66\x2e\x75\ \x6e\x73\x68\x69\x66\x74\x28\x69\x29\x3b\x62\x72\x65\x61\x6b\x7d\ \x69\x66\x28\x66\x5b\x30\x5d\x69\x6e\x20\x64\x29\x6a\x3d\x66\x5b\ \x30\x5d\x3b\x65\x6c\x73\x65\x7b\x66\x6f\x72\x28\x69\x20\x69\x6e\ \x20\x64\x29\x7b\x69\x66\x28\x21\x66\x5b\x30\x5d\x7c\x7c\x61\x2e\ \x63\x6f\x6e\x76\x65\x72\x74\x65\x72\x73\x5b\x69\x2b\x22\x20\x22\ \x2b\x66\x5b\x30\x5d\x5d\x29\x7b\x6a\x3d\x69\x3b\x62\x72\x65\x61\ \x6b\x7d\x6b\x7c\x7c\x28\x6b\x3d\x69\x29\x7d\x6a\x3d\x6a\x7c\x7c\ \x6b\x7d\x69\x66\x28\x6a\x29\x7b\x6a\x21\x3d\x3d\x66\x5b\x30\x5d\ \x26\x26\x66\x2e\x75\x6e\x73\x68\x69\x66\x74\x28\x6a\x29\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x64\x5b\x6a\x5d\x7d\x7d\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x20\x63\x61\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\ \x7b\x69\x66\x28\x66\x2e\x69\x73\x41\x72\x72\x61\x79\x28\x62\x29\ \x29\x66\x2e\x65\x61\x63\x68\x28\x62\x2c\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x62\x2c\x65\x29\x7b\x63\x7c\x7c\x62\x45\x2e\x74\x65\ \x73\x74\x28\x61\x29\x3f\x64\x28\x61\x2c\x65\x29\x3a\x63\x61\x28\ \x61\x2b\x22\x5b\x22\x2b\x28\x74\x79\x70\x65\x6f\x66\x20\x65\x3d\ \x3d\x22\x6f\x62\x6a\x65\x63\x74\x22\x7c\x7c\x66\x2e\x69\x73\x41\ \x72\x72\x61\x79\x28\x65\x29\x3f\x62\x3a\x22\x22\x29\x2b\x22\x5d\ \x22\x2c\x65\x2c\x63\x2c\x64\x29\x7d\x29\x3b\x65\x6c\x73\x65\x20\ \x69\x66\x28\x21\x63\x26\x26\x62\x21\x3d\x6e\x75\x6c\x6c\x26\x26\ \x74\x79\x70\x65\x6f\x66\x20\x62\x3d\x3d\x22\x6f\x62\x6a\x65\x63\ \x74\x22\x29\x66\x6f\x72\x28\x76\x61\x72\x20\x65\x20\x69\x6e\x20\ \x62\x29\x63\x61\x28\x61\x2b\x22\x5b\x22\x2b\x65\x2b\x22\x5d\x22\ \x2c\x62\x5b\x65\x5d\x2c\x63\x2c\x64\x29\x3b\x65\x6c\x73\x65\x20\ \x64\x28\x61\x2c\x62\x29\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\ \x62\x5f\x28\x61\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x2c\x65\x2c\ \x67\x3d\x66\x2e\x61\x6a\x61\x78\x53\x65\x74\x74\x69\x6e\x67\x73\ \x2e\x66\x6c\x61\x74\x4f\x70\x74\x69\x6f\x6e\x73\x7c\x7c\x7b\x7d\ \x3b\x66\x6f\x72\x28\x64\x20\x69\x6e\x20\x63\x29\x63\x5b\x64\x5d\ \x21\x3d\x3d\x62\x26\x26\x28\x28\x67\x5b\x64\x5d\x3f\x61\x3a\x65\ \x7c\x7c\x28\x65\x3d\x7b\x7d\x29\x29\x5b\x64\x5d\x3d\x63\x5b\x64\ \x5d\x29\x3b\x65\x26\x26\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x21\ \x30\x2c\x61\x2c\x65\x29\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\ \x62\x24\x28\x61\x2c\x63\x2c\x64\x2c\x65\x2c\x66\x2c\x67\x29\x7b\ \x66\x3d\x66\x7c\x7c\x63\x2e\x64\x61\x74\x61\x54\x79\x70\x65\x73\ \x5b\x30\x5d\x2c\x67\x3d\x67\x7c\x7c\x7b\x7d\x2c\x67\x5b\x66\x5d\ \x3d\x21\x30\x3b\x76\x61\x72\x20\x68\x3d\x61\x5b\x66\x5d\x2c\x69\ \x3d\x30\x2c\x6a\x3d\x68\x3f\x68\x2e\x6c\x65\x6e\x67\x74\x68\x3a\ \x30\x2c\x6b\x3d\x61\x3d\x3d\x3d\x62\x54\x2c\x6c\x3b\x66\x6f\x72\ \x28\x3b\x69\x3c\x6a\x26\x26\x28\x6b\x7c\x7c\x21\x6c\x29\x3b\x69\ \x2b\x2b\x29\x6c\x3d\x68\x5b\x69\x5d\x28\x63\x2c\x64\x2c\x65\x29\ \x2c\x74\x79\x70\x65\x6f\x66\x20\x6c\x3d\x3d\x22\x73\x74\x72\x69\ \x6e\x67\x22\x26\x26\x28\x21\x6b\x7c\x7c\x67\x5b\x6c\x5d\x3f\x6c\ \x3d\x62\x3a\x28\x63\x2e\x64\x61\x74\x61\x54\x79\x70\x65\x73\x2e\ \x75\x6e\x73\x68\x69\x66\x74\x28\x6c\x29\x2c\x6c\x3d\x62\x24\x28\ \x61\x2c\x63\x2c\x64\x2c\x65\x2c\x6c\x2c\x67\x29\x29\x29\x3b\x28\ \x6b\x7c\x7c\x21\x6c\x29\x26\x26\x21\x67\x5b\x22\x2a\x22\x5d\x26\ \x26\x28\x6c\x3d\x62\x24\x28\x61\x2c\x63\x2c\x64\x2c\x65\x2c\x22\ \x2a\x22\x2c\x67\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x6c\x7d\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x62\x5a\x28\x61\x29\x7b\x72\ \x65\x74\x75\x72\x6e\x20\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\ \x2c\x63\x29\x7b\x74\x79\x70\x65\x6f\x66\x20\x62\x21\x3d\x22\x73\ \x74\x72\x69\x6e\x67\x22\x26\x26\x28\x63\x3d\x62\x2c\x62\x3d\x22\ \x2a\x22\x29\x3b\x69\x66\x28\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x63\x29\x29\x7b\x76\x61\x72\x20\x64\x3d\x62\x2e\ \x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x2e\x73\x70\ \x6c\x69\x74\x28\x62\x50\x29\x2c\x65\x3d\x30\x2c\x67\x3d\x64\x2e\ \x6c\x65\x6e\x67\x74\x68\x2c\x68\x2c\x69\x2c\x6a\x3b\x66\x6f\x72\ \x28\x3b\x65\x3c\x67\x3b\x65\x2b\x2b\x29\x68\x3d\x64\x5b\x65\x5d\ \x2c\x6a\x3d\x2f\x5e\x5c\x2b\x2f\x2e\x74\x65\x73\x74\x28\x68\x29\ \x2c\x6a\x26\x26\x28\x68\x3d\x68\x2e\x73\x75\x62\x73\x74\x72\x28\ \x31\x29\x7c\x7c\x22\x2a\x22\x29\x2c\x69\x3d\x61\x5b\x68\x5d\x3d\ \x61\x5b\x68\x5d\x7c\x7c\x5b\x5d\x2c\x69\x5b\x6a\x3f\x22\x75\x6e\ \x73\x68\x69\x66\x74\x22\x3a\x22\x70\x75\x73\x68\x22\x5d\x28\x63\ \x29\x7d\x7d\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x62\x43\x28\ \x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x62\x3d\x3d\ \x3d\x22\x77\x69\x64\x74\x68\x22\x3f\x61\x2e\x6f\x66\x66\x73\x65\ \x74\x57\x69\x64\x74\x68\x3a\x61\x2e\x6f\x66\x66\x73\x65\x74\x48\ \x65\x69\x67\x68\x74\x2c\x65\x3d\x62\x3d\x3d\x3d\x22\x77\x69\x64\ \x74\x68\x22\x3f\x62\x78\x3a\x62\x79\x2c\x67\x3d\x30\x2c\x68\x3d\ \x65\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x69\x66\x28\x64\x3e\x30\x29\ \x7b\x69\x66\x28\x63\x21\x3d\x3d\x22\x62\x6f\x72\x64\x65\x72\x22\ \x29\x66\x6f\x72\x28\x3b\x67\x3c\x68\x3b\x67\x2b\x2b\x29\x63\x7c\ \x7c\x28\x64\x2d\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\ \x66\x2e\x63\x73\x73\x28\x61\x2c\x22\x70\x61\x64\x64\x69\x6e\x67\ \x22\x2b\x65\x5b\x67\x5d\x29\x29\x7c\x7c\x30\x29\x2c\x63\x3d\x3d\ \x3d\x22\x6d\x61\x72\x67\x69\x6e\x22\x3f\x64\x2b\x3d\x70\x61\x72\ \x73\x65\x46\x6c\x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\x61\x2c\ \x63\x2b\x65\x5b\x67\x5d\x29\x29\x7c\x7c\x30\x3a\x64\x2d\x3d\x70\ \x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\ \x61\x2c\x22\x62\x6f\x72\x64\x65\x72\x22\x2b\x65\x5b\x67\x5d\x2b\ \x22\x57\x69\x64\x74\x68\x22\x29\x29\x7c\x7c\x30\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x64\x2b\x22\x70\x78\x22\x7d\x64\x3d\x62\x7a\x28\ \x61\x2c\x62\x2c\x62\x29\x3b\x69\x66\x28\x64\x3c\x30\x7c\x7c\x64\ \x3d\x3d\x6e\x75\x6c\x6c\x29\x64\x3d\x61\x2e\x73\x74\x79\x6c\x65\ \x5b\x62\x5d\x7c\x7c\x30\x3b\x64\x3d\x70\x61\x72\x73\x65\x46\x6c\ \x6f\x61\x74\x28\x64\x29\x7c\x7c\x30\x3b\x69\x66\x28\x63\x29\x66\ \x6f\x72\x28\x3b\x67\x3c\x68\x3b\x67\x2b\x2b\x29\x64\x2b\x3d\x70\ \x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\ \x61\x2c\x22\x70\x61\x64\x64\x69\x6e\x67\x22\x2b\x65\x5b\x67\x5d\ \x29\x29\x7c\x7c\x30\x2c\x63\x21\x3d\x3d\x22\x70\x61\x64\x64\x69\ \x6e\x67\x22\x26\x26\x28\x64\x2b\x3d\x70\x61\x72\x73\x65\x46\x6c\ \x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\x61\x2c\x22\x62\x6f\x72\ \x64\x65\x72\x22\x2b\x65\x5b\x67\x5d\x2b\x22\x57\x69\x64\x74\x68\ \x22\x29\x29\x7c\x7c\x30\x29\x2c\x63\x3d\x3d\x3d\x22\x6d\x61\x72\ \x67\x69\x6e\x22\x26\x26\x28\x64\x2b\x3d\x70\x61\x72\x73\x65\x46\ \x6c\x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\x61\x2c\x63\x2b\x65\ \x5b\x67\x5d\x29\x29\x7c\x7c\x30\x29\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x64\x2b\x22\x70\x78\x22\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x20\x62\x70\x28\x61\x2c\x62\x29\x7b\x62\x2e\x73\x72\x63\x3f\x66\ \x2e\x61\x6a\x61\x78\x28\x7b\x75\x72\x6c\x3a\x62\x2e\x73\x72\x63\ \x2c\x61\x73\x79\x6e\x63\x3a\x21\x31\x2c\x64\x61\x74\x61\x54\x79\ \x70\x65\x3a\x22\x73\x63\x72\x69\x70\x74\x22\x7d\x29\x3a\x66\x2e\ \x67\x6c\x6f\x62\x61\x6c\x45\x76\x61\x6c\x28\x28\x62\x2e\x74\x65\ \x78\x74\x7c\x7c\x62\x2e\x74\x65\x78\x74\x43\x6f\x6e\x74\x65\x6e\ \x74\x7c\x7c\x62\x2e\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c\x7c\x7c\ \x22\x22\x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x62\x66\x2c\x22\ \x2f\x2a\x24\x30\x2a\x2f\x22\x29\x29\x2c\x62\x2e\x70\x61\x72\x65\ \x6e\x74\x4e\x6f\x64\x65\x26\x26\x62\x2e\x70\x61\x72\x65\x6e\x74\ \x4e\x6f\x64\x65\x2e\x72\x65\x6d\x6f\x76\x65\x43\x68\x69\x6c\x64\ \x28\x62\x29\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x62\x6f\x28\ \x61\x29\x7b\x76\x61\x72\x20\x62\x3d\x63\x2e\x63\x72\x65\x61\x74\ \x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x64\x69\x76\x22\x29\x3b\ \x62\x68\x2e\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64\x28\x62\ \x29\x2c\x62\x2e\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c\x3d\x61\x2e\ \x6f\x75\x74\x65\x72\x48\x54\x4d\x4c\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x62\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x7d\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x20\x62\x6e\x28\x61\x29\x7b\x76\x61\x72\ \x20\x62\x3d\x28\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x7c\x7c\ \x22\x22\x29\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\ \x29\x3b\x62\x3d\x3d\x3d\x22\x69\x6e\x70\x75\x74\x22\x3f\x62\x6d\ \x28\x61\x29\x3a\x62\x21\x3d\x3d\x22\x73\x63\x72\x69\x70\x74\x22\ \x26\x26\x74\x79\x70\x65\x6f\x66\x20\x61\x2e\x67\x65\x74\x45\x6c\ \x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x21\ \x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\x22\x26\x26\x66\x2e\ \x67\x72\x65\x70\x28\x61\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\ \x74\x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\x69\x6e\x70\ \x75\x74\x22\x29\x2c\x62\x6d\x29\x7d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x20\x62\x6d\x28\x61\x29\x7b\x69\x66\x28\x61\x2e\x74\x79\x70\ \x65\x3d\x3d\x3d\x22\x63\x68\x65\x63\x6b\x62\x6f\x78\x22\x7c\x7c\ \x61\x2e\x74\x79\x70\x65\x3d\x3d\x3d\x22\x72\x61\x64\x69\x6f\x22\ \x29\x61\x2e\x64\x65\x66\x61\x75\x6c\x74\x43\x68\x65\x63\x6b\x65\ \x64\x3d\x61\x2e\x63\x68\x65\x63\x6b\x65\x64\x7d\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x20\x62\x6c\x28\x61\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x74\x79\x70\x65\x6f\x66\x20\x61\x2e\x67\x65\x74\x45\x6c\ \x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x21\ \x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\x22\x3f\x61\x2e\x67\ \x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\ \x61\x6d\x65\x28\x22\x2a\x22\x29\x3a\x74\x79\x70\x65\x6f\x66\x20\ \x61\x2e\x71\x75\x65\x72\x79\x53\x65\x6c\x65\x63\x74\x6f\x72\x41\ \x6c\x6c\x21\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\x22\x3f\ \x61\x2e\x71\x75\x65\x72\x79\x53\x65\x6c\x65\x63\x74\x6f\x72\x41\ \x6c\x6c\x28\x22\x2a\x22\x29\x3a\x5b\x5d\x7d\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x20\x62\x6b\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\ \x63\x3b\x69\x66\x28\x62\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\ \x3d\x3d\x31\x29\x7b\x62\x2e\x63\x6c\x65\x61\x72\x41\x74\x74\x72\ \x69\x62\x75\x74\x65\x73\x26\x26\x62\x2e\x63\x6c\x65\x61\x72\x41\ \x74\x74\x72\x69\x62\x75\x74\x65\x73\x28\x29\x2c\x62\x2e\x6d\x65\ \x72\x67\x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x73\x26\x26\x62\ \x2e\x6d\x65\x72\x67\x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x73\ \x28\x61\x29\x2c\x63\x3d\x62\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\ \x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3b\x69\ \x66\x28\x63\x3d\x3d\x3d\x22\x6f\x62\x6a\x65\x63\x74\x22\x29\x62\ \x2e\x6f\x75\x74\x65\x72\x48\x54\x4d\x4c\x3d\x61\x2e\x6f\x75\x74\ \x65\x72\x48\x54\x4d\x4c\x3b\x65\x6c\x73\x65\x20\x69\x66\x28\x63\ \x21\x3d\x3d\x22\x69\x6e\x70\x75\x74\x22\x7c\x7c\x61\x2e\x74\x79\ \x70\x65\x21\x3d\x3d\x22\x63\x68\x65\x63\x6b\x62\x6f\x78\x22\x26\ \x26\x61\x2e\x74\x79\x70\x65\x21\x3d\x3d\x22\x72\x61\x64\x69\x6f\ \x22\x29\x7b\x69\x66\x28\x63\x3d\x3d\x3d\x22\x6f\x70\x74\x69\x6f\ \x6e\x22\x29\x62\x2e\x73\x65\x6c\x65\x63\x74\x65\x64\x3d\x61\x2e\ \x64\x65\x66\x61\x75\x6c\x74\x53\x65\x6c\x65\x63\x74\x65\x64\x3b\ \x65\x6c\x73\x65\x20\x69\x66\x28\x63\x3d\x3d\x3d\x22\x69\x6e\x70\ \x75\x74\x22\x7c\x7c\x63\x3d\x3d\x3d\x22\x74\x65\x78\x74\x61\x72\ \x65\x61\x22\x29\x62\x2e\x64\x65\x66\x61\x75\x6c\x74\x56\x61\x6c\ \x75\x65\x3d\x61\x2e\x64\x65\x66\x61\x75\x6c\x74\x56\x61\x6c\x75\ \x65\x7d\x65\x6c\x73\x65\x20\x61\x2e\x63\x68\x65\x63\x6b\x65\x64\ \x26\x26\x28\x62\x2e\x64\x65\x66\x61\x75\x6c\x74\x43\x68\x65\x63\ \x6b\x65\x64\x3d\x62\x2e\x63\x68\x65\x63\x6b\x65\x64\x3d\x61\x2e\ \x63\x68\x65\x63\x6b\x65\x64\x29\x2c\x62\x2e\x76\x61\x6c\x75\x65\ \x21\x3d\x3d\x61\x2e\x76\x61\x6c\x75\x65\x26\x26\x28\x62\x2e\x76\ \x61\x6c\x75\x65\x3d\x61\x2e\x76\x61\x6c\x75\x65\x29\x3b\x62\x2e\ \x72\x65\x6d\x6f\x76\x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\ \x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x29\x7d\x7d\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x20\x62\x6a\x28\x61\x2c\x62\x29\x7b\x69\x66\x28\ \x62\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\x26\ \x21\x21\x66\x2e\x68\x61\x73\x44\x61\x74\x61\x28\x61\x29\x29\x7b\ \x76\x61\x72\x20\x63\x2c\x64\x2c\x65\x2c\x67\x3d\x66\x2e\x5f\x64\ \x61\x74\x61\x28\x61\x29\x2c\x68\x3d\x66\x2e\x5f\x64\x61\x74\x61\ \x28\x62\x2c\x67\x29\x2c\x69\x3d\x67\x2e\x65\x76\x65\x6e\x74\x73\ \x3b\x69\x66\x28\x69\x29\x7b\x64\x65\x6c\x65\x74\x65\x20\x68\x2e\ \x68\x61\x6e\x64\x6c\x65\x2c\x68\x2e\x65\x76\x65\x6e\x74\x73\x3d\ \x7b\x7d\x3b\x66\x6f\x72\x28\x63\x20\x69\x6e\x20\x69\x29\x66\x6f\ \x72\x28\x64\x3d\x30\x2c\x65\x3d\x69\x5b\x63\x5d\x2e\x6c\x65\x6e\ \x67\x74\x68\x3b\x64\x3c\x65\x3b\x64\x2b\x2b\x29\x66\x2e\x65\x76\ \x65\x6e\x74\x2e\x61\x64\x64\x28\x62\x2c\x63\x2b\x28\x69\x5b\x63\ \x5d\x5b\x64\x5d\x2e\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x3f\x22\ \x2e\x22\x3a\x22\x22\x29\x2b\x69\x5b\x63\x5d\x5b\x64\x5d\x2e\x6e\ \x61\x6d\x65\x73\x70\x61\x63\x65\x2c\x69\x5b\x63\x5d\x5b\x64\x5d\ \x2c\x69\x5b\x63\x5d\x5b\x64\x5d\x2e\x64\x61\x74\x61\x29\x7d\x68\ \x2e\x64\x61\x74\x61\x26\x26\x28\x68\x2e\x64\x61\x74\x61\x3d\x66\ \x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x7d\x2c\x68\x2e\x64\x61\x74\ \x61\x29\x29\x7d\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x62\x69\ \x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x6e\ \x6f\x64\x65\x4e\x61\x6d\x65\x28\x61\x2c\x22\x74\x61\x62\x6c\x65\ \x22\x29\x3f\x61\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\ \x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\x74\x62\x6f\x64\x79\ \x22\x29\x5b\x30\x5d\x7c\x7c\x61\x2e\x61\x70\x70\x65\x6e\x64\x43\ \x68\x69\x6c\x64\x28\x61\x2e\x6f\x77\x6e\x65\x72\x44\x6f\x63\x75\ \x6d\x65\x6e\x74\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\ \x6e\x74\x28\x22\x74\x62\x6f\x64\x79\x22\x29\x29\x3a\x61\x7d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x20\x55\x28\x61\x29\x7b\x76\x61\x72\ \x20\x62\x3d\x56\x2e\x73\x70\x6c\x69\x74\x28\x22\x7c\x22\x29\x2c\ \x63\x3d\x61\x2e\x63\x72\x65\x61\x74\x65\x44\x6f\x63\x75\x6d\x65\ \x6e\x74\x46\x72\x61\x67\x6d\x65\x6e\x74\x28\x29\x3b\x69\x66\x28\ \x63\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x29\ \x77\x68\x69\x6c\x65\x28\x62\x2e\x6c\x65\x6e\x67\x74\x68\x29\x63\ \x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x62\ \x2e\x70\x6f\x70\x28\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x63\ \x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x54\x28\x61\x2c\x62\x2c\ \x63\x29\x7b\x62\x3d\x62\x7c\x7c\x30\x3b\x69\x66\x28\x66\x2e\x69\ \x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\x29\x72\x65\x74\ \x75\x72\x6e\x20\x66\x2e\x67\x72\x65\x70\x28\x61\x2c\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x2c\x64\x29\x7b\x76\x61\x72\x20\x65\ \x3d\x21\x21\x62\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x64\x2c\x61\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x65\x3d\x3d\x3d\x63\x7d\x29\x3b\ \x69\x66\x28\x62\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x29\x72\x65\ \x74\x75\x72\x6e\x20\x66\x2e\x67\x72\x65\x70\x28\x61\x2c\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x64\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x61\x3d\x3d\x3d\x62\x3d\x3d\x3d\x63\x7d\x29\x3b\x69\ \x66\x28\x74\x79\x70\x65\x6f\x66\x20\x62\x3d\x3d\x22\x73\x74\x72\ \x69\x6e\x67\x22\x29\x7b\x76\x61\x72\x20\x64\x3d\x66\x2e\x67\x72\ \x65\x70\x28\x61\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x6e\x6f\x64\x65\x54\x79\ \x70\x65\x3d\x3d\x3d\x31\x7d\x29\x3b\x69\x66\x28\x4f\x2e\x74\x65\ \x73\x74\x28\x62\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x66\ \x69\x6c\x74\x65\x72\x28\x62\x2c\x64\x2c\x21\x63\x29\x3b\x62\x3d\ \x66\x2e\x66\x69\x6c\x74\x65\x72\x28\x62\x2c\x64\x29\x7d\x72\x65\ \x74\x75\x72\x6e\x20\x66\x2e\x67\x72\x65\x70\x28\x61\x2c\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x64\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x66\x2e\x69\x6e\x41\x72\x72\x61\x79\x28\x61\x2c\x62\ \x29\x3e\x3d\x30\x3d\x3d\x3d\x63\x7d\x29\x7d\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x20\x53\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\ \x61\x7c\x7c\x21\x61\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\ \x7c\x7c\x61\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x2e\x6e\ \x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x31\x7d\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x20\x4b\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\ \x21\x30\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x4a\x28\x29\x7b\ \x72\x65\x74\x75\x72\x6e\x21\x31\x7d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x20\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\ \x3d\x62\x2b\x22\x64\x65\x66\x65\x72\x22\x2c\x65\x3d\x62\x2b\x22\ \x71\x75\x65\x75\x65\x22\x2c\x67\x3d\x62\x2b\x22\x6d\x61\x72\x6b\ \x22\x2c\x68\x3d\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\x64\x29\ \x3b\x68\x26\x26\x28\x63\x3d\x3d\x3d\x22\x71\x75\x65\x75\x65\x22\ \x7c\x7c\x21\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\x65\x29\x29\ \x26\x26\x28\x63\x3d\x3d\x3d\x22\x6d\x61\x72\x6b\x22\x7c\x7c\x21\ \x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\x67\x29\x29\x26\x26\x73\ \x65\x74\x54\x69\x6d\x65\x6f\x75\x74\x28\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x29\x7b\x21\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\ \x65\x29\x26\x26\x21\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\x67\ \x29\x26\x26\x28\x66\x2e\x72\x65\x6d\x6f\x76\x65\x44\x61\x74\x61\ \x28\x61\x2c\x64\x2c\x21\x30\x29\x2c\x68\x2e\x66\x69\x72\x65\x28\ \x29\x29\x7d\x2c\x30\x29\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\ \x6d\x28\x61\x29\x7b\x66\x6f\x72\x28\x76\x61\x72\x20\x62\x20\x69\ \x6e\x20\x61\x29\x7b\x69\x66\x28\x62\x3d\x3d\x3d\x22\x64\x61\x74\ \x61\x22\x26\x26\x66\x2e\x69\x73\x45\x6d\x70\x74\x79\x4f\x62\x6a\ \x65\x63\x74\x28\x61\x5b\x62\x5d\x29\x29\x63\x6f\x6e\x74\x69\x6e\ \x75\x65\x3b\x69\x66\x28\x62\x21\x3d\x3d\x22\x74\x6f\x4a\x53\x4f\ \x4e\x22\x29\x72\x65\x74\x75\x72\x6e\x21\x31\x7d\x72\x65\x74\x75\ \x72\x6e\x21\x30\x7d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x6c\x28\ \x61\x2c\x63\x2c\x64\x29\x7b\x69\x66\x28\x64\x3d\x3d\x3d\x62\x26\ \x26\x61\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\ \x7b\x76\x61\x72\x20\x65\x3d\x22\x64\x61\x74\x61\x2d\x22\x2b\x63\ \x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x6b\x2c\x22\x2d\x24\x31\x22\ \x29\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3b\ \x64\x3d\x61\x2e\x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\ \x28\x65\x29\x3b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x64\x3d\ \x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x29\x7b\x74\x72\x79\x7b\x64\ \x3d\x64\x3d\x3d\x3d\x22\x74\x72\x75\x65\x22\x3f\x21\x30\x3a\x64\ \x3d\x3d\x3d\x22\x66\x61\x6c\x73\x65\x22\x3f\x21\x31\x3a\x64\x3d\ \x3d\x3d\x22\x6e\x75\x6c\x6c\x22\x3f\x6e\x75\x6c\x6c\x3a\x66\x2e\ \x69\x73\x4e\x75\x6d\x65\x72\x69\x63\x28\x64\x29\x3f\x70\x61\x72\ \x73\x65\x46\x6c\x6f\x61\x74\x28\x64\x29\x3a\x6a\x2e\x74\x65\x73\ \x74\x28\x64\x29\x3f\x66\x2e\x70\x61\x72\x73\x65\x4a\x53\x4f\x4e\ \x28\x64\x29\x3a\x64\x7d\x63\x61\x74\x63\x68\x28\x67\x29\x7b\x7d\ \x66\x2e\x64\x61\x74\x61\x28\x61\x2c\x63\x2c\x64\x29\x7d\x65\x6c\ \x73\x65\x20\x64\x3d\x62\x7d\x72\x65\x74\x75\x72\x6e\x20\x64\x7d\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x68\x28\x61\x29\x7b\x76\x61\ \x72\x20\x62\x3d\x67\x5b\x61\x5d\x3d\x7b\x7d\x2c\x63\x2c\x64\x3b\ \x61\x3d\x61\x2e\x73\x70\x6c\x69\x74\x28\x2f\x5c\x73\x2b\x2f\x29\ \x3b\x66\x6f\x72\x28\x63\x3d\x30\x2c\x64\x3d\x61\x2e\x6c\x65\x6e\ \x67\x74\x68\x3b\x63\x3c\x64\x3b\x63\x2b\x2b\x29\x62\x5b\x61\x5b\ \x63\x5d\x5d\x3d\x21\x30\x3b\x72\x65\x74\x75\x72\x6e\x20\x62\x7d\ \x76\x61\x72\x20\x63\x3d\x61\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\ \x2c\x64\x3d\x61\x2e\x6e\x61\x76\x69\x67\x61\x74\x6f\x72\x2c\x65\ \x3d\x61\x2e\x6c\x6f\x63\x61\x74\x69\x6f\x6e\x2c\x66\x3d\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x20\x4a\x28\x29\x7b\x69\x66\x28\x21\x65\x2e\x69\x73\x52\x65\ \x61\x64\x79\x29\x7b\x74\x72\x79\x7b\x63\x2e\x64\x6f\x63\x75\x6d\ \x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2e\x64\x6f\x53\x63\x72\ \x6f\x6c\x6c\x28\x22\x6c\x65\x66\x74\x22\x29\x7d\x63\x61\x74\x63\ \x68\x28\x61\x29\x7b\x73\x65\x74\x54\x69\x6d\x65\x6f\x75\x74\x28\ \x4a\x2c\x31\x29\x3b\x72\x65\x74\x75\x72\x6e\x7d\x65\x2e\x72\x65\ \x61\x64\x79\x28\x29\x7d\x7d\x76\x61\x72\x20\x65\x3d\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x6e\x65\x77\x20\x65\x2e\x66\x6e\x2e\x69\x6e\x69\x74\x28\ \x61\x2c\x62\x2c\x68\x29\x7d\x2c\x66\x3d\x61\x2e\x6a\x51\x75\x65\ \x72\x79\x2c\x67\x3d\x61\x2e\x24\x2c\x68\x2c\x69\x3d\x2f\x5e\x28\ \x3f\x3a\x5b\x5e\x23\x3c\x5d\x2a\x28\x3c\x5b\x5c\x77\x5c\x57\x5d\ \x2b\x3e\x29\x5b\x5e\x3e\x5d\x2a\x24\x7c\x23\x28\x5b\x5c\x77\x5c\ \x2d\x5d\x2a\x29\x24\x29\x2f\x2c\x6a\x3d\x2f\x5c\x53\x2f\x2c\x6b\ \x3d\x2f\x5e\x5c\x73\x2b\x2f\x2c\x6c\x3d\x2f\x5c\x73\x2b\x24\x2f\ \x2c\x6d\x3d\x2f\x5e\x3c\x28\x5c\x77\x2b\x29\x5c\x73\x2a\x5c\x2f\ \x3f\x3e\x28\x3f\x3a\x3c\x5c\x2f\x5c\x31\x3e\x29\x3f\x24\x2f\x2c\ \x6e\x3d\x2f\x5e\x5b\x5c\x5d\x2c\x3a\x7b\x7d\x5c\x73\x5d\x2a\x24\ \x2f\x2c\x6f\x3d\x2f\x5c\x5c\x28\x3f\x3a\x5b\x22\x5c\x5c\x5c\x2f\ \x62\x66\x6e\x72\x74\x5d\x7c\x75\x5b\x30\x2d\x39\x61\x2d\x66\x41\ \x2d\x46\x5d\x7b\x34\x7d\x29\x2f\x67\x2c\x70\x3d\x2f\x22\x5b\x5e\ \x22\x5c\x5c\x5c\x6e\x5c\x72\x5d\x2a\x22\x7c\x74\x72\x75\x65\x7c\ \x66\x61\x6c\x73\x65\x7c\x6e\x75\x6c\x6c\x7c\x2d\x3f\x5c\x64\x2b\ \x28\x3f\x3a\x5c\x2e\x5c\x64\x2a\x29\x3f\x28\x3f\x3a\x5b\x65\x45\ \x5d\x5b\x2b\x5c\x2d\x5d\x3f\x5c\x64\x2b\x29\x3f\x2f\x67\x2c\x71\ \x3d\x2f\x28\x3f\x3a\x5e\x7c\x3a\x7c\x2c\x29\x28\x3f\x3a\x5c\x73\ \x2a\x5c\x5b\x29\x2b\x2f\x67\x2c\x72\x3d\x2f\x28\x77\x65\x62\x6b\ \x69\x74\x29\x5b\x20\x5c\x2f\x5d\x28\x5b\x5c\x77\x2e\x5d\x2b\x29\ \x2f\x2c\x73\x3d\x2f\x28\x6f\x70\x65\x72\x61\x29\x28\x3f\x3a\x2e\ \x2a\x76\x65\x72\x73\x69\x6f\x6e\x29\x3f\x5b\x20\x5c\x2f\x5d\x28\ \x5b\x5c\x77\x2e\x5d\x2b\x29\x2f\x2c\x74\x3d\x2f\x28\x6d\x73\x69\ \x65\x29\x20\x28\x5b\x5c\x77\x2e\x5d\x2b\x29\x2f\x2c\x75\x3d\x2f\ \x28\x6d\x6f\x7a\x69\x6c\x6c\x61\x29\x28\x3f\x3a\x2e\x2a\x3f\x20\ \x72\x76\x3a\x28\x5b\x5c\x77\x2e\x5d\x2b\x29\x29\x3f\x2f\x2c\x76\ \x3d\x2f\x2d\x28\x5b\x61\x2d\x7a\x5d\x7c\x5b\x30\x2d\x39\x5d\x29\ \x2f\x69\x67\x2c\x77\x3d\x2f\x5e\x2d\x6d\x73\x2d\x2f\x2c\x78\x3d\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\ \x74\x75\x72\x6e\x28\x62\x2b\x22\x22\x29\x2e\x74\x6f\x55\x70\x70\ \x65\x72\x43\x61\x73\x65\x28\x29\x7d\x2c\x79\x3d\x64\x2e\x75\x73\ \x65\x72\x41\x67\x65\x6e\x74\x2c\x7a\x2c\x41\x2c\x42\x2c\x43\x3d\ \x4f\x62\x6a\x65\x63\x74\x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\x65\ \x2e\x74\x6f\x53\x74\x72\x69\x6e\x67\x2c\x44\x3d\x4f\x62\x6a\x65\ \x63\x74\x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\x65\x2e\x68\x61\x73\ \x4f\x77\x6e\x50\x72\x6f\x70\x65\x72\x74\x79\x2c\x45\x3d\x41\x72\ \x72\x61\x79\x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\x65\x2e\x70\x75\ \x73\x68\x2c\x46\x3d\x41\x72\x72\x61\x79\x2e\x70\x72\x6f\x74\x6f\ \x74\x79\x70\x65\x2e\x73\x6c\x69\x63\x65\x2c\x47\x3d\x53\x74\x72\ \x69\x6e\x67\x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\x65\x2e\x74\x72\ \x69\x6d\x2c\x48\x3d\x41\x72\x72\x61\x79\x2e\x70\x72\x6f\x74\x6f\ \x74\x79\x70\x65\x2e\x69\x6e\x64\x65\x78\x4f\x66\x2c\x49\x3d\x7b\ \x7d\x3b\x65\x2e\x66\x6e\x3d\x65\x2e\x70\x72\x6f\x74\x6f\x74\x79\ \x70\x65\x3d\x7b\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x3a\ \x65\x2c\x69\x6e\x69\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x64\x2c\x66\x29\x7b\x76\x61\x72\x20\x67\x2c\x68\x2c\x6a\ \x2c\x6b\x3b\x69\x66\x28\x21\x61\x29\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x3b\x69\x66\x28\x61\x2e\x6e\x6f\x64\x65\x54\x79\ \x70\x65\x29\x7b\x74\x68\x69\x73\x2e\x63\x6f\x6e\x74\x65\x78\x74\ \x3d\x74\x68\x69\x73\x5b\x30\x5d\x3d\x61\x2c\x74\x68\x69\x73\x2e\ \x6c\x65\x6e\x67\x74\x68\x3d\x31\x3b\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x7d\x69\x66\x28\x61\x3d\x3d\x3d\x22\x62\x6f\x64\ \x79\x22\x26\x26\x21\x64\x26\x26\x63\x2e\x62\x6f\x64\x79\x29\x7b\ \x74\x68\x69\x73\x2e\x63\x6f\x6e\x74\x65\x78\x74\x3d\x63\x2c\x74\ \x68\x69\x73\x5b\x30\x5d\x3d\x63\x2e\x62\x6f\x64\x79\x2c\x74\x68\ \x69\x73\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x3d\x61\x2c\x74\x68\ \x69\x73\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x31\x3b\x72\x65\x74\x75\ \x72\x6e\x20\x74\x68\x69\x73\x7d\x69\x66\x28\x74\x79\x70\x65\x6f\ \x66\x20\x61\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x29\x7b\x61\ \x2e\x63\x68\x61\x72\x41\x74\x28\x30\x29\x21\x3d\x3d\x22\x3c\x22\ \x7c\x7c\x61\x2e\x63\x68\x61\x72\x41\x74\x28\x61\x2e\x6c\x65\x6e\ \x67\x74\x68\x2d\x31\x29\x21\x3d\x3d\x22\x3e\x22\x7c\x7c\x61\x2e\ \x6c\x65\x6e\x67\x74\x68\x3c\x33\x3f\x67\x3d\x69\x2e\x65\x78\x65\ \x63\x28\x61\x29\x3a\x67\x3d\x5b\x6e\x75\x6c\x6c\x2c\x61\x2c\x6e\ \x75\x6c\x6c\x5d\x3b\x69\x66\x28\x67\x26\x26\x28\x67\x5b\x31\x5d\ \x7c\x7c\x21\x64\x29\x29\x7b\x69\x66\x28\x67\x5b\x31\x5d\x29\x7b\ \x64\x3d\x64\x20\x69\x6e\x73\x74\x61\x6e\x63\x65\x6f\x66\x20\x65\ \x3f\x64\x5b\x30\x5d\x3a\x64\x2c\x6b\x3d\x64\x3f\x64\x2e\x6f\x77\ \x6e\x65\x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x7c\x7c\x64\x3a\x63\ \x2c\x6a\x3d\x6d\x2e\x65\x78\x65\x63\x28\x61\x29\x2c\x6a\x3f\x65\ \x2e\x69\x73\x50\x6c\x61\x69\x6e\x4f\x62\x6a\x65\x63\x74\x28\x64\ \x29\x3f\x28\x61\x3d\x5b\x63\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\ \x65\x6d\x65\x6e\x74\x28\x6a\x5b\x31\x5d\x29\x5d\x2c\x65\x2e\x66\ \x6e\x2e\x61\x74\x74\x72\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x64\x2c\ \x21\x30\x29\x29\x3a\x61\x3d\x5b\x6b\x2e\x63\x72\x65\x61\x74\x65\ \x45\x6c\x65\x6d\x65\x6e\x74\x28\x6a\x5b\x31\x5d\x29\x5d\x3a\x28\ \x6a\x3d\x65\x2e\x62\x75\x69\x6c\x64\x46\x72\x61\x67\x6d\x65\x6e\ \x74\x28\x5b\x67\x5b\x31\x5d\x5d\x2c\x5b\x6b\x5d\x29\x2c\x61\x3d\ \x28\x6a\x2e\x63\x61\x63\x68\x65\x61\x62\x6c\x65\x3f\x65\x2e\x63\ \x6c\x6f\x6e\x65\x28\x6a\x2e\x66\x72\x61\x67\x6d\x65\x6e\x74\x29\ \x3a\x6a\x2e\x66\x72\x61\x67\x6d\x65\x6e\x74\x29\x2e\x63\x68\x69\ \x6c\x64\x4e\x6f\x64\x65\x73\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\ \x65\x2e\x6d\x65\x72\x67\x65\x28\x74\x68\x69\x73\x2c\x61\x29\x7d\ \x68\x3d\x63\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\ \x49\x64\x28\x67\x5b\x32\x5d\x29\x3b\x69\x66\x28\x68\x26\x26\x68\ \x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x29\x7b\x69\x66\x28\ \x68\x2e\x69\x64\x21\x3d\x3d\x67\x5b\x32\x5d\x29\x72\x65\x74\x75\ \x72\x6e\x20\x66\x2e\x66\x69\x6e\x64\x28\x61\x29\x3b\x74\x68\x69\ \x73\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x31\x2c\x74\x68\x69\x73\x5b\ \x30\x5d\x3d\x68\x7d\x74\x68\x69\x73\x2e\x63\x6f\x6e\x74\x65\x78\ \x74\x3d\x63\x2c\x74\x68\x69\x73\x2e\x73\x65\x6c\x65\x63\x74\x6f\ \x72\x3d\x61\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\ \x72\x65\x74\x75\x72\x6e\x21\x64\x7c\x7c\x64\x2e\x6a\x71\x75\x65\ \x72\x79\x3f\x28\x64\x7c\x7c\x66\x29\x2e\x66\x69\x6e\x64\x28\x61\ \x29\x3a\x74\x68\x69\x73\x2e\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\ \x6f\x72\x28\x64\x29\x2e\x66\x69\x6e\x64\x28\x61\x29\x7d\x69\x66\ \x28\x65\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x29\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x72\x65\x61\x64\x79\x28\ \x61\x29\x3b\x61\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x21\x3d\x3d\ \x62\x26\x26\x28\x74\x68\x69\x73\x2e\x73\x65\x6c\x65\x63\x74\x6f\ \x72\x3d\x61\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x2c\x74\x68\x69\ \x73\x2e\x63\x6f\x6e\x74\x65\x78\x74\x3d\x61\x2e\x63\x6f\x6e\x74\ \x65\x78\x74\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x65\x2e\x6d\x61\ \x6b\x65\x41\x72\x72\x61\x79\x28\x61\x2c\x74\x68\x69\x73\x29\x7d\ \x2c\x73\x65\x6c\x65\x63\x74\x6f\x72\x3a\x22\x22\x2c\x6a\x71\x75\ \x65\x72\x79\x3a\x22\x31\x2e\x37\x2e\x31\x22\x2c\x6c\x65\x6e\x67\ \x74\x68\x3a\x30\x2c\x73\x69\x7a\x65\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\ \x2e\x6c\x65\x6e\x67\x74\x68\x7d\x2c\x74\x6f\x41\x72\x72\x61\x79\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x46\x2e\x63\x61\x6c\x6c\x28\x74\x68\x69\x73\x2c\x30\ \x29\x7d\x2c\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x3d\x3d\x6e\x75\x6c\ \x6c\x3f\x74\x68\x69\x73\x2e\x74\x6f\x41\x72\x72\x61\x79\x28\x29\ \x3a\x61\x3c\x30\x3f\x74\x68\x69\x73\x5b\x74\x68\x69\x73\x2e\x6c\ \x65\x6e\x67\x74\x68\x2b\x61\x5d\x3a\x74\x68\x69\x73\x5b\x61\x5d\ \x7d\x2c\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\ \x64\x3d\x74\x68\x69\x73\x2e\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\ \x6f\x72\x28\x29\x3b\x65\x2e\x69\x73\x41\x72\x72\x61\x79\x28\x61\ \x29\x3f\x45\x2e\x61\x70\x70\x6c\x79\x28\x64\x2c\x61\x29\x3a\x65\ \x2e\x6d\x65\x72\x67\x65\x28\x64\x2c\x61\x29\x2c\x64\x2e\x70\x72\ \x65\x76\x4f\x62\x6a\x65\x63\x74\x3d\x74\x68\x69\x73\x2c\x64\x2e\ \x63\x6f\x6e\x74\x65\x78\x74\x3d\x74\x68\x69\x73\x2e\x63\x6f\x6e\ \x74\x65\x78\x74\x2c\x62\x3d\x3d\x3d\x22\x66\x69\x6e\x64\x22\x3f\ \x64\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x3d\x74\x68\x69\x73\x2e\ \x73\x65\x6c\x65\x63\x74\x6f\x72\x2b\x28\x74\x68\x69\x73\x2e\x73\ \x65\x6c\x65\x63\x74\x6f\x72\x3f\x22\x20\x22\x3a\x22\x22\x29\x2b\ \x63\x3a\x62\x26\x26\x28\x64\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\ \x3d\x74\x68\x69\x73\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x2b\x22\ \x2e\x22\x2b\x62\x2b\x22\x28\x22\x2b\x63\x2b\x22\x29\x22\x29\x3b\ \x72\x65\x74\x75\x72\x6e\x20\x64\x7d\x2c\x65\x61\x63\x68\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x65\x2e\x65\x61\x63\x68\x28\x74\x68\x69\x73\x2c\ \x61\x2c\x62\x29\x7d\x2c\x72\x65\x61\x64\x79\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x65\x2e\x62\x69\x6e\x64\x52\x65\ \x61\x64\x79\x28\x29\x2c\x41\x2e\x61\x64\x64\x28\x61\x29\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x65\x71\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x61\x3d\x2b\x61\x3b\ \x72\x65\x74\x75\x72\x6e\x20\x61\x3d\x3d\x3d\x2d\x31\x3f\x74\x68\ \x69\x73\x2e\x73\x6c\x69\x63\x65\x28\x61\x29\x3a\x74\x68\x69\x73\ \x2e\x73\x6c\x69\x63\x65\x28\x61\x2c\x61\x2b\x31\x29\x7d\x2c\x66\ \x69\x72\x73\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\ \x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x71\x28\x30\ \x29\x7d\x2c\x6c\x61\x73\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\ \x71\x28\x2d\x31\x29\x7d\x2c\x73\x6c\x69\x63\x65\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x2e\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x28\x46\x2e\ \x61\x70\x70\x6c\x79\x28\x74\x68\x69\x73\x2c\x61\x72\x67\x75\x6d\ \x65\x6e\x74\x73\x29\x2c\x22\x73\x6c\x69\x63\x65\x22\x2c\x46\x2e\ \x63\x61\x6c\x6c\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x2e\ \x6a\x6f\x69\x6e\x28\x22\x2c\x22\x29\x29\x7d\x2c\x6d\x61\x70\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x74\x68\x69\x73\x2e\x70\x75\x73\x68\x53\x74\x61\x63\ \x6b\x28\x65\x2e\x6d\x61\x70\x28\x74\x68\x69\x73\x2c\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x62\x2c\x63\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x61\x2e\x63\x61\x6c\x6c\x28\x62\x2c\x63\x2c\x62\x29\x7d\ \x29\x29\x7d\x2c\x65\x6e\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x70\ \x72\x65\x76\x4f\x62\x6a\x65\x63\x74\x7c\x7c\x74\x68\x69\x73\x2e\ \x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x6e\x75\x6c\x6c\ \x29\x7d\x2c\x70\x75\x73\x68\x3a\x45\x2c\x73\x6f\x72\x74\x3a\x5b\ \x5d\x2e\x73\x6f\x72\x74\x2c\x73\x70\x6c\x69\x63\x65\x3a\x5b\x5d\ \x2e\x73\x70\x6c\x69\x63\x65\x7d\x2c\x65\x2e\x66\x6e\x2e\x69\x6e\ \x69\x74\x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\x65\x3d\x65\x2e\x66\ \x6e\x2c\x65\x2e\x65\x78\x74\x65\x6e\x64\x3d\x65\x2e\x66\x6e\x2e\ \x65\x78\x74\x65\x6e\x64\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x76\x61\x72\x20\x61\x2c\x63\x2c\x64\x2c\x66\x2c\x67\x2c\ \x68\x2c\x69\x3d\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x5b\x30\x5d\ \x7c\x7c\x7b\x7d\x2c\x6a\x3d\x31\x2c\x6b\x3d\x61\x72\x67\x75\x6d\ \x65\x6e\x74\x73\x2e\x6c\x65\x6e\x67\x74\x68\x2c\x6c\x3d\x21\x31\ \x3b\x74\x79\x70\x65\x6f\x66\x20\x69\x3d\x3d\x22\x62\x6f\x6f\x6c\ \x65\x61\x6e\x22\x26\x26\x28\x6c\x3d\x69\x2c\x69\x3d\x61\x72\x67\ \x75\x6d\x65\x6e\x74\x73\x5b\x31\x5d\x7c\x7c\x7b\x7d\x2c\x6a\x3d\ \x32\x29\x2c\x74\x79\x70\x65\x6f\x66\x20\x69\x21\x3d\x22\x6f\x62\ \x6a\x65\x63\x74\x22\x26\x26\x21\x65\x2e\x69\x73\x46\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x69\x29\x26\x26\x28\x69\x3d\x7b\x7d\x29\x2c\ \x6b\x3d\x3d\x3d\x6a\x26\x26\x28\x69\x3d\x74\x68\x69\x73\x2c\x2d\ \x2d\x6a\x29\x3b\x66\x6f\x72\x28\x3b\x6a\x3c\x6b\x3b\x6a\x2b\x2b\ \x29\x69\x66\x28\x28\x61\x3d\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\ \x5b\x6a\x5d\x29\x21\x3d\x6e\x75\x6c\x6c\x29\x66\x6f\x72\x28\x63\ \x20\x69\x6e\x20\x61\x29\x7b\x64\x3d\x69\x5b\x63\x5d\x2c\x66\x3d\ \x61\x5b\x63\x5d\x3b\x69\x66\x28\x69\x3d\x3d\x3d\x66\x29\x63\x6f\ \x6e\x74\x69\x6e\x75\x65\x3b\x6c\x26\x26\x66\x26\x26\x28\x65\x2e\ \x69\x73\x50\x6c\x61\x69\x6e\x4f\x62\x6a\x65\x63\x74\x28\x66\x29\ \x7c\x7c\x28\x67\x3d\x65\x2e\x69\x73\x41\x72\x72\x61\x79\x28\x66\ \x29\x29\x29\x3f\x28\x67\x3f\x28\x67\x3d\x21\x31\x2c\x68\x3d\x64\ \x26\x26\x65\x2e\x69\x73\x41\x72\x72\x61\x79\x28\x64\x29\x3f\x64\ \x3a\x5b\x5d\x29\x3a\x68\x3d\x64\x26\x26\x65\x2e\x69\x73\x50\x6c\ \x61\x69\x6e\x4f\x62\x6a\x65\x63\x74\x28\x64\x29\x3f\x64\x3a\x7b\ \x7d\x2c\x69\x5b\x63\x5d\x3d\x65\x2e\x65\x78\x74\x65\x6e\x64\x28\ \x6c\x2c\x68\x2c\x66\x29\x29\x3a\x66\x21\x3d\x3d\x62\x26\x26\x28\ \x69\x5b\x63\x5d\x3d\x66\x29\x7d\x72\x65\x74\x75\x72\x6e\x20\x69\ \x7d\x2c\x65\x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x6e\x6f\x43\x6f\ \x6e\x66\x6c\x69\x63\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x62\x29\x7b\x61\x2e\x24\x3d\x3d\x3d\x65\x26\x26\x28\x61\x2e\x24\ \x3d\x67\x29\x2c\x62\x26\x26\x61\x2e\x6a\x51\x75\x65\x72\x79\x3d\ \x3d\x3d\x65\x26\x26\x28\x61\x2e\x6a\x51\x75\x65\x72\x79\x3d\x66\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x65\x7d\x2c\x69\x73\x52\x65\ \x61\x64\x79\x3a\x21\x31\x2c\x72\x65\x61\x64\x79\x57\x61\x69\x74\ \x3a\x31\x2c\x68\x6f\x6c\x64\x52\x65\x61\x64\x79\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x61\x3f\x65\x2e\x72\x65\x61\ \x64\x79\x57\x61\x69\x74\x2b\x2b\x3a\x65\x2e\x72\x65\x61\x64\x79\ \x28\x21\x30\x29\x7d\x2c\x72\x65\x61\x64\x79\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\x28\x61\x3d\x3d\x3d\x21\ \x30\x26\x26\x21\x2d\x2d\x65\x2e\x72\x65\x61\x64\x79\x57\x61\x69\ \x74\x7c\x7c\x61\x21\x3d\x3d\x21\x30\x26\x26\x21\x65\x2e\x69\x73\ \x52\x65\x61\x64\x79\x29\x7b\x69\x66\x28\x21\x63\x2e\x62\x6f\x64\ \x79\x29\x72\x65\x74\x75\x72\x6e\x20\x73\x65\x74\x54\x69\x6d\x65\ \x6f\x75\x74\x28\x65\x2e\x72\x65\x61\x64\x79\x2c\x31\x29\x3b\x65\ \x2e\x69\x73\x52\x65\x61\x64\x79\x3d\x21\x30\x3b\x69\x66\x28\x61\ \x21\x3d\x3d\x21\x30\x26\x26\x2d\x2d\x65\x2e\x72\x65\x61\x64\x79\ \x57\x61\x69\x74\x3e\x30\x29\x72\x65\x74\x75\x72\x6e\x3b\x41\x2e\ \x66\x69\x72\x65\x57\x69\x74\x68\x28\x63\x2c\x5b\x65\x5d\x29\x2c\ \x65\x2e\x66\x6e\x2e\x74\x72\x69\x67\x67\x65\x72\x26\x26\x65\x28\ \x63\x29\x2e\x74\x72\x69\x67\x67\x65\x72\x28\x22\x72\x65\x61\x64\ \x79\x22\x29\x2e\x6f\x66\x66\x28\x22\x72\x65\x61\x64\x79\x22\x29\ \x7d\x7d\x2c\x62\x69\x6e\x64\x52\x65\x61\x64\x79\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x21\x41\x29\x7b\x41\ \x3d\x65\x2e\x43\x61\x6c\x6c\x62\x61\x63\x6b\x73\x28\x22\x6f\x6e\ \x63\x65\x20\x6d\x65\x6d\x6f\x72\x79\x22\x29\x3b\x69\x66\x28\x63\ \x2e\x72\x65\x61\x64\x79\x53\x74\x61\x74\x65\x3d\x3d\x3d\x22\x63\ \x6f\x6d\x70\x6c\x65\x74\x65\x22\x29\x72\x65\x74\x75\x72\x6e\x20\ \x73\x65\x74\x54\x69\x6d\x65\x6f\x75\x74\x28\x65\x2e\x72\x65\x61\ \x64\x79\x2c\x31\x29\x3b\x69\x66\x28\x63\x2e\x61\x64\x64\x45\x76\ \x65\x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72\x29\x63\x2e\x61\x64\ \x64\x45\x76\x65\x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72\x28\x22\ \x44\x4f\x4d\x43\x6f\x6e\x74\x65\x6e\x74\x4c\x6f\x61\x64\x65\x64\ \x22\x2c\x42\x2c\x21\x31\x29\x2c\x61\x2e\x61\x64\x64\x45\x76\x65\ \x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72\x28\x22\x6c\x6f\x61\x64\ \x22\x2c\x65\x2e\x72\x65\x61\x64\x79\x2c\x21\x31\x29\x3b\x65\x6c\ \x73\x65\x20\x69\x66\x28\x63\x2e\x61\x74\x74\x61\x63\x68\x45\x76\ \x65\x6e\x74\x29\x7b\x63\x2e\x61\x74\x74\x61\x63\x68\x45\x76\x65\ \x6e\x74\x28\x22\x6f\x6e\x72\x65\x61\x64\x79\x73\x74\x61\x74\x65\ \x63\x68\x61\x6e\x67\x65\x22\x2c\x42\x29\x2c\x61\x2e\x61\x74\x74\ \x61\x63\x68\x45\x76\x65\x6e\x74\x28\x22\x6f\x6e\x6c\x6f\x61\x64\ \x22\x2c\x65\x2e\x72\x65\x61\x64\x79\x29\x3b\x76\x61\x72\x20\x62\ \x3d\x21\x31\x3b\x74\x72\x79\x7b\x62\x3d\x61\x2e\x66\x72\x61\x6d\ \x65\x45\x6c\x65\x6d\x65\x6e\x74\x3d\x3d\x6e\x75\x6c\x6c\x7d\x63\ \x61\x74\x63\x68\x28\x64\x29\x7b\x7d\x63\x2e\x64\x6f\x63\x75\x6d\ \x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2e\x64\x6f\x53\x63\x72\ \x6f\x6c\x6c\x26\x26\x62\x26\x26\x4a\x28\x29\x7d\x7d\x7d\x2c\x69\ \x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x65\x2e\x74\ \x79\x70\x65\x28\x61\x29\x3d\x3d\x3d\x22\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x22\x7d\x2c\x69\x73\x41\x72\x72\x61\x79\x3a\x41\x72\x72\ \x61\x79\x2e\x69\x73\x41\x72\x72\x61\x79\x7c\x7c\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x65\ \x2e\x74\x79\x70\x65\x28\x61\x29\x3d\x3d\x3d\x22\x61\x72\x72\x61\ \x79\x22\x7d\x2c\x69\x73\x57\x69\x6e\x64\x6f\x77\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\ \x61\x26\x26\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x6f\x62\ \x6a\x65\x63\x74\x22\x26\x26\x22\x73\x65\x74\x49\x6e\x74\x65\x72\ \x76\x61\x6c\x22\x69\x6e\x20\x61\x7d\x2c\x69\x73\x4e\x75\x6d\x65\ \x72\x69\x63\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\ \x72\x65\x74\x75\x72\x6e\x21\x69\x73\x4e\x61\x4e\x28\x70\x61\x72\ \x73\x65\x46\x6c\x6f\x61\x74\x28\x61\x29\x29\x26\x26\x69\x73\x46\ \x69\x6e\x69\x74\x65\x28\x61\x29\x7d\x2c\x74\x79\x70\x65\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x61\x3d\x3d\x6e\x75\x6c\x6c\x3f\x53\x74\x72\x69\x6e\x67\ \x28\x61\x29\x3a\x49\x5b\x43\x2e\x63\x61\x6c\x6c\x28\x61\x29\x5d\ \x7c\x7c\x22\x6f\x62\x6a\x65\x63\x74\x22\x7d\x2c\x69\x73\x50\x6c\ \x61\x69\x6e\x4f\x62\x6a\x65\x63\x74\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x29\x7b\x69\x66\x28\x21\x61\x7c\x7c\x65\x2e\x74\ \x79\x70\x65\x28\x61\x29\x21\x3d\x3d\x22\x6f\x62\x6a\x65\x63\x74\ \x22\x7c\x7c\x61\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x7c\x7c\x65\ \x2e\x69\x73\x57\x69\x6e\x64\x6f\x77\x28\x61\x29\x29\x72\x65\x74\ \x75\x72\x6e\x21\x31\x3b\x74\x72\x79\x7b\x69\x66\x28\x61\x2e\x63\ \x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x26\x26\x21\x44\x2e\x63\ \x61\x6c\x6c\x28\x61\x2c\x22\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\ \x6f\x72\x22\x29\x26\x26\x21\x44\x2e\x63\x61\x6c\x6c\x28\x61\x2e\ \x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x2e\x70\x72\x6f\x74\ \x6f\x74\x79\x70\x65\x2c\x22\x69\x73\x50\x72\x6f\x74\x6f\x74\x79\ \x70\x65\x4f\x66\x22\x29\x29\x72\x65\x74\x75\x72\x6e\x21\x31\x7d\ \x63\x61\x74\x63\x68\x28\x63\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\ \x31\x7d\x76\x61\x72\x20\x64\x3b\x66\x6f\x72\x28\x64\x20\x69\x6e\ \x20\x61\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x64\x3d\x3d\x3d\x62\ \x7c\x7c\x44\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x64\x29\x7d\x2c\x69\ \x73\x45\x6d\x70\x74\x79\x4f\x62\x6a\x65\x63\x74\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x66\x6f\x72\x28\x76\x61\x72\ \x20\x62\x20\x69\x6e\x20\x61\x29\x72\x65\x74\x75\x72\x6e\x21\x31\ \x3b\x72\x65\x74\x75\x72\x6e\x21\x30\x7d\x2c\x65\x72\x72\x6f\x72\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x74\x68\x72\ \x6f\x77\x20\x6e\x65\x77\x20\x45\x72\x72\x6f\x72\x28\x61\x29\x7d\ \x2c\x70\x61\x72\x73\x65\x4a\x53\x4f\x4e\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x62\x29\x7b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\ \x20\x62\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x7c\x7c\x21\x62\ \x29\x72\x65\x74\x75\x72\x6e\x20\x6e\x75\x6c\x6c\x3b\x62\x3d\x65\ \x2e\x74\x72\x69\x6d\x28\x62\x29\x3b\x69\x66\x28\x61\x2e\x4a\x53\ \x4f\x4e\x26\x26\x61\x2e\x4a\x53\x4f\x4e\x2e\x70\x61\x72\x73\x65\ \x29\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x4a\x53\x4f\x4e\x2e\x70\ \x61\x72\x73\x65\x28\x62\x29\x3b\x69\x66\x28\x6e\x2e\x74\x65\x73\ \x74\x28\x62\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x6f\x2c\x22\x40\ \x22\x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x70\x2c\x22\x5d\x22\ \x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x71\x2c\x22\x22\x29\x29\ \x29\x72\x65\x74\x75\x72\x6e\x28\x6e\x65\x77\x20\x46\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x22\x72\x65\x74\x75\x72\x6e\x20\x22\x2b\x62\ \x29\x29\x28\x29\x3b\x65\x2e\x65\x72\x72\x6f\x72\x28\x22\x49\x6e\ \x76\x61\x6c\x69\x64\x20\x4a\x53\x4f\x4e\x3a\x20\x22\x2b\x62\x29\ \x7d\x2c\x70\x61\x72\x73\x65\x58\x4d\x4c\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x63\x29\x7b\x76\x61\x72\x20\x64\x2c\x66\x3b\x74\ \x72\x79\x7b\x61\x2e\x44\x4f\x4d\x50\x61\x72\x73\x65\x72\x3f\x28\ \x66\x3d\x6e\x65\x77\x20\x44\x4f\x4d\x50\x61\x72\x73\x65\x72\x2c\ \x64\x3d\x66\x2e\x70\x61\x72\x73\x65\x46\x72\x6f\x6d\x53\x74\x72\ \x69\x6e\x67\x28\x63\x2c\x22\x74\x65\x78\x74\x2f\x78\x6d\x6c\x22\ \x29\x29\x3a\x28\x64\x3d\x6e\x65\x77\x20\x41\x63\x74\x69\x76\x65\ \x58\x4f\x62\x6a\x65\x63\x74\x28\x22\x4d\x69\x63\x72\x6f\x73\x6f\ \x66\x74\x2e\x58\x4d\x4c\x44\x4f\x4d\x22\x29\x2c\x64\x2e\x61\x73\ \x79\x6e\x63\x3d\x22\x66\x61\x6c\x73\x65\x22\x2c\x64\x2e\x6c\x6f\ \x61\x64\x58\x4d\x4c\x28\x63\x29\x29\x7d\x63\x61\x74\x63\x68\x28\ \x67\x29\x7b\x64\x3d\x62\x7d\x28\x21\x64\x7c\x7c\x21\x64\x2e\x64\ \x6f\x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x7c\x7c\ \x64\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\ \x61\x67\x4e\x61\x6d\x65\x28\x22\x70\x61\x72\x73\x65\x72\x65\x72\ \x72\x6f\x72\x22\x29\x2e\x6c\x65\x6e\x67\x74\x68\x29\x26\x26\x65\ \x2e\x65\x72\x72\x6f\x72\x28\x22\x49\x6e\x76\x61\x6c\x69\x64\x20\ \x58\x4d\x4c\x3a\x20\x22\x2b\x63\x29\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x64\x7d\x2c\x6e\x6f\x6f\x70\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x7d\x2c\x67\x6c\x6f\x62\x61\x6c\x45\x76\x61\x6c\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\x7b\x62\x26\x26\ \x6a\x2e\x74\x65\x73\x74\x28\x62\x29\x26\x26\x28\x61\x2e\x65\x78\ \x65\x63\x53\x63\x72\x69\x70\x74\x7c\x7c\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x62\x29\x7b\x61\x2e\x65\x76\x61\x6c\x2e\x63\x61\x6c\ \x6c\x28\x61\x2c\x62\x29\x7d\x29\x28\x62\x29\x7d\x2c\x63\x61\x6d\ \x65\x6c\x43\x61\x73\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x72\x65\x70\x6c\ \x61\x63\x65\x28\x77\x2c\x22\x6d\x73\x2d\x22\x29\x2e\x72\x65\x70\ \x6c\x61\x63\x65\x28\x76\x2c\x78\x29\x7d\x2c\x6e\x6f\x64\x65\x4e\ \x61\x6d\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x6e\x6f\x64\x65\x4e\ \x61\x6d\x65\x26\x26\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\ \x74\x6f\x55\x70\x70\x65\x72\x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\ \x62\x2e\x74\x6f\x55\x70\x70\x65\x72\x43\x61\x73\x65\x28\x29\x7d\ \x2c\x65\x61\x63\x68\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x63\x2c\x64\x29\x7b\x76\x61\x72\x20\x66\x2c\x67\x3d\x30\x2c\ \x68\x3d\x61\x2e\x6c\x65\x6e\x67\x74\x68\x2c\x69\x3d\x68\x3d\x3d\ \x3d\x62\x7c\x7c\x65\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x3b\x69\x66\x28\x64\x29\x7b\x69\x66\x28\x69\x29\x7b\ \x66\x6f\x72\x28\x66\x20\x69\x6e\x20\x61\x29\x69\x66\x28\x63\x2e\ \x61\x70\x70\x6c\x79\x28\x61\x5b\x66\x5d\x2c\x64\x29\x3d\x3d\x3d\ \x21\x31\x29\x62\x72\x65\x61\x6b\x7d\x65\x6c\x73\x65\x20\x66\x6f\ \x72\x28\x3b\x67\x3c\x68\x3b\x29\x69\x66\x28\x63\x2e\x61\x70\x70\ \x6c\x79\x28\x61\x5b\x67\x2b\x2b\x5d\x2c\x64\x29\x3d\x3d\x3d\x21\ \x31\x29\x62\x72\x65\x61\x6b\x7d\x65\x6c\x73\x65\x20\x69\x66\x28\ \x69\x29\x7b\x66\x6f\x72\x28\x66\x20\x69\x6e\x20\x61\x29\x69\x66\ \x28\x63\x2e\x63\x61\x6c\x6c\x28\x61\x5b\x66\x5d\x2c\x66\x2c\x61\ \x5b\x66\x5d\x29\x3d\x3d\x3d\x21\x31\x29\x62\x72\x65\x61\x6b\x7d\ \x65\x6c\x73\x65\x20\x66\x6f\x72\x28\x3b\x67\x3c\x68\x3b\x29\x69\ \x66\x28\x63\x2e\x63\x61\x6c\x6c\x28\x61\x5b\x67\x5d\x2c\x67\x2c\ \x61\x5b\x67\x2b\x2b\x5d\x29\x3d\x3d\x3d\x21\x31\x29\x62\x72\x65\ \x61\x6b\x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x7d\x2c\x74\x72\x69\ \x6d\x3a\x47\x3f\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\ \x72\x65\x74\x75\x72\x6e\x20\x61\x3d\x3d\x6e\x75\x6c\x6c\x3f\x22\ \x22\x3a\x47\x2e\x63\x61\x6c\x6c\x28\x61\x29\x7d\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\ \x61\x3d\x3d\x6e\x75\x6c\x6c\x3f\x22\x22\x3a\x28\x61\x2b\x22\x22\ \x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x6b\x2c\x22\x22\x29\x2e\ \x72\x65\x70\x6c\x61\x63\x65\x28\x6c\x2c\x22\x22\x29\x7d\x2c\x6d\ \x61\x6b\x65\x41\x72\x72\x61\x79\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x62\x7c\x7c\ \x5b\x5d\x3b\x69\x66\x28\x61\x21\x3d\x6e\x75\x6c\x6c\x29\x7b\x76\ \x61\x72\x20\x64\x3d\x65\x2e\x74\x79\x70\x65\x28\x61\x29\x3b\x61\ \x2e\x6c\x65\x6e\x67\x74\x68\x3d\x3d\x6e\x75\x6c\x6c\x7c\x7c\x64\ \x3d\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x7c\x7c\x64\x3d\x3d\ \x3d\x22\x66\x75\x6e\x63\x74\x69\x6f\x6e\x22\x7c\x7c\x64\x3d\x3d\ \x3d\x22\x72\x65\x67\x65\x78\x70\x22\x7c\x7c\x65\x2e\x69\x73\x57\ \x69\x6e\x64\x6f\x77\x28\x61\x29\x3f\x45\x2e\x63\x61\x6c\x6c\x28\ \x63\x2c\x61\x29\x3a\x65\x2e\x6d\x65\x72\x67\x65\x28\x63\x2c\x61\ \x29\x7d\x72\x65\x74\x75\x72\x6e\x20\x63\x7d\x2c\x69\x6e\x41\x72\ \x72\x61\x79\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\ \x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3b\x69\x66\x28\x62\x29\x7b\ \x69\x66\x28\x48\x29\x72\x65\x74\x75\x72\x6e\x20\x48\x2e\x63\x61\ \x6c\x6c\x28\x62\x2c\x61\x2c\x63\x29\x3b\x64\x3d\x62\x2e\x6c\x65\ \x6e\x67\x74\x68\x2c\x63\x3d\x63\x3f\x63\x3c\x30\x3f\x4d\x61\x74\ \x68\x2e\x6d\x61\x78\x28\x30\x2c\x64\x2b\x63\x29\x3a\x63\x3a\x30\ \x3b\x66\x6f\x72\x28\x3b\x63\x3c\x64\x3b\x63\x2b\x2b\x29\x69\x66\ \x28\x63\x20\x69\x6e\x20\x62\x26\x26\x62\x5b\x63\x5d\x3d\x3d\x3d\ \x61\x29\x72\x65\x74\x75\x72\x6e\x20\x63\x7d\x72\x65\x74\x75\x72\ \x6e\x2d\x31\x7d\x2c\x6d\x65\x72\x67\x65\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x61\ \x2e\x6c\x65\x6e\x67\x74\x68\x2c\x65\x3d\x30\x3b\x69\x66\x28\x74\ \x79\x70\x65\x6f\x66\x20\x63\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x3d\ \x22\x6e\x75\x6d\x62\x65\x72\x22\x29\x66\x6f\x72\x28\x76\x61\x72\ \x20\x66\x3d\x63\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x65\x3c\x66\x3b\ \x65\x2b\x2b\x29\x61\x5b\x64\x2b\x2b\x5d\x3d\x63\x5b\x65\x5d\x3b\ \x65\x6c\x73\x65\x20\x77\x68\x69\x6c\x65\x28\x63\x5b\x65\x5d\x21\ \x3d\x3d\x62\x29\x61\x5b\x64\x2b\x2b\x5d\x3d\x63\x5b\x65\x2b\x2b\ \x5d\x3b\x61\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x64\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x61\x7d\x2c\x67\x72\x65\x70\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\ \x64\x3d\x5b\x5d\x2c\x65\x3b\x63\x3d\x21\x21\x63\x3b\x66\x6f\x72\ \x28\x76\x61\x72\x20\x66\x3d\x30\x2c\x67\x3d\x61\x2e\x6c\x65\x6e\ \x67\x74\x68\x3b\x66\x3c\x67\x3b\x66\x2b\x2b\x29\x65\x3d\x21\x21\ \x62\x28\x61\x5b\x66\x5d\x2c\x66\x29\x2c\x63\x21\x3d\x3d\x65\x26\ \x26\x64\x2e\x70\x75\x73\x68\x28\x61\x5b\x66\x5d\x29\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x64\x7d\x2c\x6d\x61\x70\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x63\x2c\x64\x29\x7b\x76\x61\x72\x20\ \x66\x2c\x67\x2c\x68\x3d\x5b\x5d\x2c\x69\x3d\x30\x2c\x6a\x3d\x61\ \x2e\x6c\x65\x6e\x67\x74\x68\x2c\x6b\x3d\x61\x20\x69\x6e\x73\x74\ \x61\x6e\x63\x65\x6f\x66\x20\x65\x7c\x7c\x6a\x21\x3d\x3d\x62\x26\ \x26\x74\x79\x70\x65\x6f\x66\x20\x6a\x3d\x3d\x22\x6e\x75\x6d\x62\ \x65\x72\x22\x26\x26\x28\x6a\x3e\x30\x26\x26\x61\x5b\x30\x5d\x26\ \x26\x61\x5b\x6a\x2d\x31\x5d\x7c\x7c\x6a\x3d\x3d\x3d\x30\x7c\x7c\ \x65\x2e\x69\x73\x41\x72\x72\x61\x79\x28\x61\x29\x29\x3b\x69\x66\ \x28\x6b\x29\x66\x6f\x72\x28\x3b\x69\x3c\x6a\x3b\x69\x2b\x2b\x29\ \x66\x3d\x63\x28\x61\x5b\x69\x5d\x2c\x69\x2c\x64\x29\x2c\x66\x21\ \x3d\x6e\x75\x6c\x6c\x26\x26\x28\x68\x5b\x68\x2e\x6c\x65\x6e\x67\ \x74\x68\x5d\x3d\x66\x29\x3b\x65\x6c\x73\x65\x20\x66\x6f\x72\x28\ \x67\x20\x69\x6e\x20\x61\x29\x66\x3d\x63\x28\x61\x5b\x67\x5d\x2c\ \x67\x2c\x64\x29\x2c\x66\x21\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x68\ \x5b\x68\x2e\x6c\x65\x6e\x67\x74\x68\x5d\x3d\x66\x29\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x68\x2e\x63\x6f\x6e\x63\x61\x74\x2e\x61\x70\ \x70\x6c\x79\x28\x5b\x5d\x2c\x68\x29\x7d\x2c\x67\x75\x69\x64\x3a\ \x31\x2c\x70\x72\x6f\x78\x79\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x2c\x63\x29\x7b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\ \x63\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x29\x7b\x76\x61\x72\ \x20\x64\x3d\x61\x5b\x63\x5d\x3b\x63\x3d\x61\x2c\x61\x3d\x64\x7d\ \x69\x66\x28\x21\x65\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x62\x3b\x76\x61\x72\ \x20\x66\x3d\x46\x2e\x63\x61\x6c\x6c\x28\x61\x72\x67\x75\x6d\x65\ \x6e\x74\x73\x2c\x32\x29\x2c\x67\x3d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x61\x70\x70\ \x6c\x79\x28\x63\x2c\x66\x2e\x63\x6f\x6e\x63\x61\x74\x28\x46\x2e\ \x63\x61\x6c\x6c\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x29\ \x29\x7d\x3b\x67\x2e\x67\x75\x69\x64\x3d\x61\x2e\x67\x75\x69\x64\ \x3d\x61\x2e\x67\x75\x69\x64\x7c\x7c\x67\x2e\x67\x75\x69\x64\x7c\ \x7c\x65\x2e\x67\x75\x69\x64\x2b\x2b\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x67\x7d\x2c\x61\x63\x63\x65\x73\x73\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x63\x2c\x64\x2c\x66\x2c\x67\x2c\x68\x29\ \x7b\x76\x61\x72\x20\x69\x3d\x61\x2e\x6c\x65\x6e\x67\x74\x68\x3b\ \x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x63\x3d\x3d\x22\x6f\x62\ \x6a\x65\x63\x74\x22\x29\x7b\x66\x6f\x72\x28\x76\x61\x72\x20\x6a\ \x20\x69\x6e\x20\x63\x29\x65\x2e\x61\x63\x63\x65\x73\x73\x28\x61\ \x2c\x6a\x2c\x63\x5b\x6a\x5d\x2c\x66\x2c\x67\x2c\x64\x29\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x61\x7d\x69\x66\x28\x64\x21\x3d\x3d\x62\ \x29\x7b\x66\x3d\x21\x68\x26\x26\x66\x26\x26\x65\x2e\x69\x73\x46\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x64\x29\x3b\x66\x6f\x72\x28\x76\ \x61\x72\x20\x6b\x3d\x30\x3b\x6b\x3c\x69\x3b\x6b\x2b\x2b\x29\x67\ \x28\x61\x5b\x6b\x5d\x2c\x63\x2c\x66\x3f\x64\x2e\x63\x61\x6c\x6c\ \x28\x61\x5b\x6b\x5d\x2c\x6b\x2c\x67\x28\x61\x5b\x6b\x5d\x2c\x63\ \x29\x29\x3a\x64\x2c\x68\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x61\ \x7d\x72\x65\x74\x75\x72\x6e\x20\x69\x3f\x67\x28\x61\x5b\x30\x5d\ \x2c\x63\x29\x3a\x62\x7d\x2c\x6e\x6f\x77\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x28\x6e\x65\x77\ \x20\x44\x61\x74\x65\x29\x2e\x67\x65\x74\x54\x69\x6d\x65\x28\x29\ \x7d\x2c\x75\x61\x4d\x61\x74\x63\x68\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x29\x7b\x61\x3d\x61\x2e\x74\x6f\x4c\x6f\x77\x65\ \x72\x43\x61\x73\x65\x28\x29\x3b\x76\x61\x72\x20\x62\x3d\x72\x2e\ \x65\x78\x65\x63\x28\x61\x29\x7c\x7c\x73\x2e\x65\x78\x65\x63\x28\ \x61\x29\x7c\x7c\x74\x2e\x65\x78\x65\x63\x28\x61\x29\x7c\x7c\x61\ \x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x22\x63\x6f\x6d\x70\x61\x74\ \x69\x62\x6c\x65\x22\x29\x3c\x30\x26\x26\x75\x2e\x65\x78\x65\x63\ \x28\x61\x29\x7c\x7c\x5b\x5d\x3b\x72\x65\x74\x75\x72\x6e\x7b\x62\ \x72\x6f\x77\x73\x65\x72\x3a\x62\x5b\x31\x5d\x7c\x7c\x22\x22\x2c\ \x76\x65\x72\x73\x69\x6f\x6e\x3a\x62\x5b\x32\x5d\x7c\x7c\x22\x30\ \x22\x7d\x7d\x2c\x73\x75\x62\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x61\x28\x62\x2c\ \x63\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x6e\x65\x77\x20\x61\x2e\ \x66\x6e\x2e\x69\x6e\x69\x74\x28\x62\x2c\x63\x29\x7d\x65\x2e\x65\ \x78\x74\x65\x6e\x64\x28\x21\x30\x2c\x61\x2c\x74\x68\x69\x73\x29\ \x2c\x61\x2e\x73\x75\x70\x65\x72\x63\x6c\x61\x73\x73\x3d\x74\x68\ \x69\x73\x2c\x61\x2e\x66\x6e\x3d\x61\x2e\x70\x72\x6f\x74\x6f\x74\ \x79\x70\x65\x3d\x74\x68\x69\x73\x28\x29\x2c\x61\x2e\x66\x6e\x2e\ \x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x3d\x61\x2c\x61\x2e\ \x73\x75\x62\x3d\x74\x68\x69\x73\x2e\x73\x75\x62\x2c\x61\x2e\x66\ \x6e\x2e\x69\x6e\x69\x74\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x64\x2c\x66\x29\x7b\x66\x26\x26\x66\x20\x69\x6e\x73\x74\x61\x6e\ \x63\x65\x6f\x66\x20\x65\x26\x26\x21\x28\x66\x20\x69\x6e\x73\x74\ \x61\x6e\x63\x65\x6f\x66\x20\x61\x29\x26\x26\x28\x66\x3d\x61\x28\ \x66\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x65\x2e\x66\x6e\x2e\ \x69\x6e\x69\x74\x2e\x63\x61\x6c\x6c\x28\x74\x68\x69\x73\x2c\x64\ \x2c\x66\x2c\x62\x29\x7d\x2c\x61\x2e\x66\x6e\x2e\x69\x6e\x69\x74\ \x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\x65\x3d\x61\x2e\x66\x6e\x3b\ \x76\x61\x72\x20\x62\x3d\x61\x28\x63\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x61\x7d\x2c\x62\x72\x6f\x77\x73\x65\x72\x3a\x7b\x7d\x7d\ \x29\x2c\x65\x2e\x65\x61\x63\x68\x28\x22\x42\x6f\x6f\x6c\x65\x61\ \x6e\x20\x4e\x75\x6d\x62\x65\x72\x20\x53\x74\x72\x69\x6e\x67\x20\ \x46\x75\x6e\x63\x74\x69\x6f\x6e\x20\x41\x72\x72\x61\x79\x20\x44\ \x61\x74\x65\x20\x52\x65\x67\x45\x78\x70\x20\x4f\x62\x6a\x65\x63\ \x74\x22\x2e\x73\x70\x6c\x69\x74\x28\x22\x20\x22\x29\x2c\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x49\x5b\x22\x5b\ \x6f\x62\x6a\x65\x63\x74\x20\x22\x2b\x62\x2b\x22\x5d\x22\x5d\x3d\ \x62\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x7d\ \x29\x2c\x7a\x3d\x65\x2e\x75\x61\x4d\x61\x74\x63\x68\x28\x79\x29\ \x2c\x7a\x2e\x62\x72\x6f\x77\x73\x65\x72\x26\x26\x28\x65\x2e\x62\ \x72\x6f\x77\x73\x65\x72\x5b\x7a\x2e\x62\x72\x6f\x77\x73\x65\x72\ \x5d\x3d\x21\x30\x2c\x65\x2e\x62\x72\x6f\x77\x73\x65\x72\x2e\x76\ \x65\x72\x73\x69\x6f\x6e\x3d\x7a\x2e\x76\x65\x72\x73\x69\x6f\x6e\ \x29\x2c\x65\x2e\x62\x72\x6f\x77\x73\x65\x72\x2e\x77\x65\x62\x6b\ \x69\x74\x26\x26\x28\x65\x2e\x62\x72\x6f\x77\x73\x65\x72\x2e\x73\ \x61\x66\x61\x72\x69\x3d\x21\x30\x29\x2c\x6a\x2e\x74\x65\x73\x74\ \x28\x22\xc2\xa0\x22\x29\x26\x26\x28\x6b\x3d\x2f\x5e\x5b\x5c\x73\ \x5c\x78\x41\x30\x5d\x2b\x2f\x2c\x6c\x3d\x2f\x5b\x5c\x73\x5c\x78\ \x41\x30\x5d\x2b\x24\x2f\x29\x2c\x68\x3d\x65\x28\x63\x29\x2c\x63\ \x2e\x61\x64\x64\x45\x76\x65\x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\ \x72\x3f\x42\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x63\ \x2e\x72\x65\x6d\x6f\x76\x65\x45\x76\x65\x6e\x74\x4c\x69\x73\x74\ \x65\x6e\x65\x72\x28\x22\x44\x4f\x4d\x43\x6f\x6e\x74\x65\x6e\x74\ \x4c\x6f\x61\x64\x65\x64\x22\x2c\x42\x2c\x21\x31\x29\x2c\x65\x2e\ \x72\x65\x61\x64\x79\x28\x29\x7d\x3a\x63\x2e\x61\x74\x74\x61\x63\ \x68\x45\x76\x65\x6e\x74\x26\x26\x28\x42\x3d\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x63\x2e\x72\x65\x61\x64\x79\x53\x74\x61\ \x74\x65\x3d\x3d\x3d\x22\x63\x6f\x6d\x70\x6c\x65\x74\x65\x22\x26\ \x26\x28\x63\x2e\x64\x65\x74\x61\x63\x68\x45\x76\x65\x6e\x74\x28\ \x22\x6f\x6e\x72\x65\x61\x64\x79\x73\x74\x61\x74\x65\x63\x68\x61\ \x6e\x67\x65\x22\x2c\x42\x29\x2c\x65\x2e\x72\x65\x61\x64\x79\x28\ \x29\x29\x7d\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x65\x7d\x28\x29\ \x2c\x67\x3d\x7b\x7d\x3b\x66\x2e\x43\x61\x6c\x6c\x62\x61\x63\x6b\ \x73\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x61\x3d\ \x61\x3f\x67\x5b\x61\x5d\x7c\x7c\x68\x28\x61\x29\x3a\x7b\x7d\x3b\ \x76\x61\x72\x20\x63\x3d\x5b\x5d\x2c\x64\x3d\x5b\x5d\x2c\x65\x2c\ \x69\x2c\x6a\x2c\x6b\x2c\x6c\x2c\x6d\x3d\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x62\x29\x7b\x76\x61\x72\x20\x64\x2c\x65\x2c\x67\x2c\ \x68\x2c\x69\x3b\x66\x6f\x72\x28\x64\x3d\x30\x2c\x65\x3d\x62\x2e\ \x6c\x65\x6e\x67\x74\x68\x3b\x64\x3c\x65\x3b\x64\x2b\x2b\x29\x67\ \x3d\x62\x5b\x64\x5d\x2c\x68\x3d\x66\x2e\x74\x79\x70\x65\x28\x67\ \x29\x2c\x68\x3d\x3d\x3d\x22\x61\x72\x72\x61\x79\x22\x3f\x6d\x28\ \x67\x29\x3a\x68\x3d\x3d\x3d\x22\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x22\x26\x26\x28\x21\x61\x2e\x75\x6e\x69\x71\x75\x65\x7c\x7c\x21\ \x6f\x2e\x68\x61\x73\x28\x67\x29\x29\x26\x26\x63\x2e\x70\x75\x73\ \x68\x28\x67\x29\x7d\x2c\x6e\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x62\x2c\x66\x29\x7b\x66\x3d\x66\x7c\x7c\x5b\x5d\x2c\x65\x3d\ \x21\x61\x2e\x6d\x65\x6d\x6f\x72\x79\x7c\x7c\x5b\x62\x2c\x66\x5d\ \x2c\x69\x3d\x21\x30\x2c\x6c\x3d\x6a\x7c\x7c\x30\x2c\x6a\x3d\x30\ \x2c\x6b\x3d\x63\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x66\x6f\x72\x28\ \x3b\x63\x26\x26\x6c\x3c\x6b\x3b\x6c\x2b\x2b\x29\x69\x66\x28\x63\ \x5b\x6c\x5d\x2e\x61\x70\x70\x6c\x79\x28\x62\x2c\x66\x29\x3d\x3d\ \x3d\x21\x31\x26\x26\x61\x2e\x73\x74\x6f\x70\x4f\x6e\x46\x61\x6c\ \x73\x65\x29\x7b\x65\x3d\x21\x30\x3b\x62\x72\x65\x61\x6b\x7d\x69\ \x3d\x21\x31\x2c\x63\x26\x26\x28\x61\x2e\x6f\x6e\x63\x65\x3f\x65\ \x3d\x3d\x3d\x21\x30\x3f\x6f\x2e\x64\x69\x73\x61\x62\x6c\x65\x28\ \x29\x3a\x63\x3d\x5b\x5d\x3a\x64\x26\x26\x64\x2e\x6c\x65\x6e\x67\ \x74\x68\x26\x26\x28\x65\x3d\x64\x2e\x73\x68\x69\x66\x74\x28\x29\ \x2c\x6f\x2e\x66\x69\x72\x65\x57\x69\x74\x68\x28\x65\x5b\x30\x5d\ \x2c\x65\x5b\x31\x5d\x29\x29\x29\x7d\x2c\x6f\x3d\x7b\x61\x64\x64\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x63\ \x29\x7b\x76\x61\x72\x20\x61\x3d\x63\x2e\x6c\x65\x6e\x67\x74\x68\ \x3b\x6d\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x2c\x69\x3f\ \x6b\x3d\x63\x2e\x6c\x65\x6e\x67\x74\x68\x3a\x65\x26\x26\x65\x21\ \x3d\x3d\x21\x30\x26\x26\x28\x6a\x3d\x61\x2c\x6e\x28\x65\x5b\x30\ \x5d\x2c\x65\x5b\x31\x5d\x29\x29\x7d\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x7d\x2c\x72\x65\x6d\x6f\x76\x65\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x63\x29\x7b\x76\x61\ \x72\x20\x62\x3d\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2c\x64\x3d\ \x30\x2c\x65\x3d\x62\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x66\x6f\x72\ \x28\x3b\x64\x3c\x65\x3b\x64\x2b\x2b\x29\x66\x6f\x72\x28\x76\x61\ \x72\x20\x66\x3d\x30\x3b\x66\x3c\x63\x2e\x6c\x65\x6e\x67\x74\x68\ \x3b\x66\x2b\x2b\x29\x69\x66\x28\x62\x5b\x64\x5d\x3d\x3d\x3d\x63\ \x5b\x66\x5d\x29\x7b\x69\x26\x26\x66\x3c\x3d\x6b\x26\x26\x28\x6b\ \x2d\x2d\x2c\x66\x3c\x3d\x6c\x26\x26\x6c\x2d\x2d\x29\x2c\x63\x2e\ \x73\x70\x6c\x69\x63\x65\x28\x66\x2d\x2d\x2c\x31\x29\x3b\x69\x66\ \x28\x61\x2e\x75\x6e\x69\x71\x75\x65\x29\x62\x72\x65\x61\x6b\x7d\ \x7d\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x68\x61\ \x73\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\ \x28\x63\x29\x7b\x76\x61\x72\x20\x62\x3d\x30\x2c\x64\x3d\x63\x2e\ \x6c\x65\x6e\x67\x74\x68\x3b\x66\x6f\x72\x28\x3b\x62\x3c\x64\x3b\ \x62\x2b\x2b\x29\x69\x66\x28\x61\x3d\x3d\x3d\x63\x5b\x62\x5d\x29\ \x72\x65\x74\x75\x72\x6e\x21\x30\x7d\x72\x65\x74\x75\x72\x6e\x21\ \x31\x7d\x2c\x65\x6d\x70\x74\x79\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x63\x3d\x5b\x5d\x3b\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x7d\x2c\x64\x69\x73\x61\x62\x6c\x65\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x63\x3d\x64\x3d\x65\x3d\x62\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x64\x69\ \x73\x61\x62\x6c\x65\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x21\x63\x7d\x2c\x6c\x6f\x63\x6b\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x64\x3d\x62\x2c\ \x28\x21\x65\x7c\x7c\x65\x3d\x3d\x3d\x21\x30\x29\x26\x26\x6f\x2e\ \x64\x69\x73\x61\x62\x6c\x65\x28\x29\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x74\x68\x69\x73\x7d\x2c\x6c\x6f\x63\x6b\x65\x64\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\ \x64\x7d\x2c\x66\x69\x72\x65\x57\x69\x74\x68\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x62\x2c\x63\x29\x7b\x64\x26\x26\x28\x69\x3f\ \x61\x2e\x6f\x6e\x63\x65\x7c\x7c\x64\x2e\x70\x75\x73\x68\x28\x5b\ \x62\x2c\x63\x5d\x29\x3a\x28\x21\x61\x2e\x6f\x6e\x63\x65\x7c\x7c\ \x21\x65\x29\x26\x26\x6e\x28\x62\x2c\x63\x29\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x66\x69\x72\x65\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x6f\x2e\x66\x69\x72\x65\ \x57\x69\x74\x68\x28\x74\x68\x69\x73\x2c\x61\x72\x67\x75\x6d\x65\ \x6e\x74\x73\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\ \x7d\x2c\x66\x69\x72\x65\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\x21\x65\x7d\x7d\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x6f\x7d\x3b\x76\x61\x72\x20\x69\x3d\x5b\ \x5d\x2e\x73\x6c\x69\x63\x65\x3b\x66\x2e\x65\x78\x74\x65\x6e\x64\ \x28\x7b\x44\x65\x66\x65\x72\x72\x65\x64\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x3d\x66\x2e\x43\ \x61\x6c\x6c\x62\x61\x63\x6b\x73\x28\x22\x6f\x6e\x63\x65\x20\x6d\ \x65\x6d\x6f\x72\x79\x22\x29\x2c\x63\x3d\x66\x2e\x43\x61\x6c\x6c\ \x62\x61\x63\x6b\x73\x28\x22\x6f\x6e\x63\x65\x20\x6d\x65\x6d\x6f\ \x72\x79\x22\x29\x2c\x64\x3d\x66\x2e\x43\x61\x6c\x6c\x62\x61\x63\ \x6b\x73\x28\x22\x6d\x65\x6d\x6f\x72\x79\x22\x29\x2c\x65\x3d\x22\ \x70\x65\x6e\x64\x69\x6e\x67\x22\x2c\x67\x3d\x7b\x72\x65\x73\x6f\ \x6c\x76\x65\x3a\x62\x2c\x72\x65\x6a\x65\x63\x74\x3a\x63\x2c\x6e\ \x6f\x74\x69\x66\x79\x3a\x64\x7d\x2c\x68\x3d\x7b\x64\x6f\x6e\x65\ \x3a\x62\x2e\x61\x64\x64\x2c\x66\x61\x69\x6c\x3a\x63\x2e\x61\x64\ \x64\x2c\x70\x72\x6f\x67\x72\x65\x73\x73\x3a\x64\x2e\x61\x64\x64\ \x2c\x73\x74\x61\x74\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x65\x7d\x2c\x69\x73\x52\x65\ \x73\x6f\x6c\x76\x65\x64\x3a\x62\x2e\x66\x69\x72\x65\x64\x2c\x69\ \x73\x52\x65\x6a\x65\x63\x74\x65\x64\x3a\x63\x2e\x66\x69\x72\x65\ \x64\x2c\x74\x68\x65\x6e\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x62\x2c\x63\x29\x7b\x69\x2e\x64\x6f\x6e\x65\x28\x61\x29\ \x2e\x66\x61\x69\x6c\x28\x62\x29\x2e\x70\x72\x6f\x67\x72\x65\x73\ \x73\x28\x63\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\ \x7d\x2c\x61\x6c\x77\x61\x79\x73\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x69\x2e\x64\x6f\x6e\x65\x2e\x61\x70\x70\x6c\x79\ \x28\x69\x2c\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x2e\x66\x61\ \x69\x6c\x2e\x61\x70\x70\x6c\x79\x28\x69\x2c\x61\x72\x67\x75\x6d\ \x65\x6e\x74\x73\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x7d\x2c\x70\x69\x70\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x2c\x62\x2c\x63\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\ \x2e\x44\x65\x66\x65\x72\x72\x65\x64\x28\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x64\x29\x7b\x66\x2e\x65\x61\x63\x68\x28\x7b\x64\x6f\ \x6e\x65\x3a\x5b\x61\x2c\x22\x72\x65\x73\x6f\x6c\x76\x65\x22\x5d\ \x2c\x66\x61\x69\x6c\x3a\x5b\x62\x2c\x22\x72\x65\x6a\x65\x63\x74\ \x22\x5d\x2c\x70\x72\x6f\x67\x72\x65\x73\x73\x3a\x5b\x63\x2c\x22\ \x6e\x6f\x74\x69\x66\x79\x22\x5d\x7d\x2c\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x62\x5b\ \x30\x5d\x2c\x65\x3d\x62\x5b\x31\x5d\x2c\x67\x3b\x66\x2e\x69\x73\ \x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x63\x29\x3f\x69\x5b\x61\x5d\ \x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x67\x3d\x63\x2e\ \x61\x70\x70\x6c\x79\x28\x74\x68\x69\x73\x2c\x61\x72\x67\x75\x6d\ \x65\x6e\x74\x73\x29\x2c\x67\x26\x26\x66\x2e\x69\x73\x46\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x67\x2e\x70\x72\x6f\x6d\x69\x73\x65\x29\ \x3f\x67\x2e\x70\x72\x6f\x6d\x69\x73\x65\x28\x29\x2e\x74\x68\x65\ \x6e\x28\x64\x2e\x72\x65\x73\x6f\x6c\x76\x65\x2c\x64\x2e\x72\x65\ \x6a\x65\x63\x74\x2c\x64\x2e\x6e\x6f\x74\x69\x66\x79\x29\x3a\x64\ \x5b\x65\x2b\x22\x57\x69\x74\x68\x22\x5d\x28\x74\x68\x69\x73\x3d\ \x3d\x3d\x69\x3f\x64\x3a\x74\x68\x69\x73\x2c\x5b\x67\x5d\x29\x7d\ \x29\x3a\x69\x5b\x61\x5d\x28\x64\x5b\x65\x5d\x29\x7d\x29\x7d\x29\ \x2e\x70\x72\x6f\x6d\x69\x73\x65\x28\x29\x7d\x2c\x70\x72\x6f\x6d\ \x69\x73\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\ \x69\x66\x28\x61\x3d\x3d\x6e\x75\x6c\x6c\x29\x61\x3d\x68\x3b\x65\ \x6c\x73\x65\x20\x66\x6f\x72\x28\x76\x61\x72\x20\x62\x20\x69\x6e\ \x20\x68\x29\x61\x5b\x62\x5d\x3d\x68\x5b\x62\x5d\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x61\x7d\x7d\x2c\x69\x3d\x68\x2e\x70\x72\x6f\x6d\ \x69\x73\x65\x28\x7b\x7d\x29\x2c\x6a\x3b\x66\x6f\x72\x28\x6a\x20\ \x69\x6e\x20\x67\x29\x69\x5b\x6a\x5d\x3d\x67\x5b\x6a\x5d\x2e\x66\ \x69\x72\x65\x2c\x69\x5b\x6a\x2b\x22\x57\x69\x74\x68\x22\x5d\x3d\ \x67\x5b\x6a\x5d\x2e\x66\x69\x72\x65\x57\x69\x74\x68\x3b\x69\x2e\ \x64\x6f\x6e\x65\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\ \x65\x3d\x22\x72\x65\x73\x6f\x6c\x76\x65\x64\x22\x7d\x2c\x63\x2e\ \x64\x69\x73\x61\x62\x6c\x65\x2c\x64\x2e\x6c\x6f\x63\x6b\x29\x2e\ \x66\x61\x69\x6c\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\ \x65\x3d\x22\x72\x65\x6a\x65\x63\x74\x65\x64\x22\x7d\x2c\x62\x2e\ \x64\x69\x73\x61\x62\x6c\x65\x2c\x64\x2e\x6c\x6f\x63\x6b\x29\x2c\ \x61\x26\x26\x61\x2e\x63\x61\x6c\x6c\x28\x69\x2c\x69\x29\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x69\x7d\x2c\x77\x68\x65\x6e\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x20\x6d\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\x7b\x65\x5b\x61\x5d\x3d\ \x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2e\x6c\x65\x6e\x67\x74\x68\ \x3e\x31\x3f\x69\x2e\x63\x61\x6c\x6c\x28\x61\x72\x67\x75\x6d\x65\ \x6e\x74\x73\x2c\x30\x29\x3a\x62\x2c\x6a\x2e\x6e\x6f\x74\x69\x66\ \x79\x57\x69\x74\x68\x28\x6b\x2c\x65\x29\x7d\x7d\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x20\x6c\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\ \x20\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x63\x29\x7b\x62\x5b\x61\ \x5d\x3d\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2e\x6c\x65\x6e\x67\ \x74\x68\x3e\x31\x3f\x69\x2e\x63\x61\x6c\x6c\x28\x61\x72\x67\x75\ \x6d\x65\x6e\x74\x73\x2c\x30\x29\x3a\x63\x2c\x2d\x2d\x67\x7c\x7c\ \x6a\x2e\x72\x65\x73\x6f\x6c\x76\x65\x57\x69\x74\x68\x28\x6a\x2c\ \x62\x29\x7d\x7d\x76\x61\x72\x20\x62\x3d\x69\x2e\x63\x61\x6c\x6c\ \x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2c\x30\x29\x2c\x63\x3d\ \x30\x2c\x64\x3d\x62\x2e\x6c\x65\x6e\x67\x74\x68\x2c\x65\x3d\x41\ \x72\x72\x61\x79\x28\x64\x29\x2c\x67\x3d\x64\x2c\x68\x3d\x64\x2c\ \x6a\x3d\x64\x3c\x3d\x31\x26\x26\x61\x26\x26\x66\x2e\x69\x73\x46\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2e\x70\x72\x6f\x6d\x69\x73\ \x65\x29\x3f\x61\x3a\x66\x2e\x44\x65\x66\x65\x72\x72\x65\x64\x28\ \x29\x2c\x6b\x3d\x6a\x2e\x70\x72\x6f\x6d\x69\x73\x65\x28\x29\x3b\ \x69\x66\x28\x64\x3e\x31\x29\x7b\x66\x6f\x72\x28\x3b\x63\x3c\x64\ \x3b\x63\x2b\x2b\x29\x62\x5b\x63\x5d\x26\x26\x62\x5b\x63\x5d\x2e\ \x70\x72\x6f\x6d\x69\x73\x65\x26\x26\x66\x2e\x69\x73\x46\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x62\x5b\x63\x5d\x2e\x70\x72\x6f\x6d\x69\ \x73\x65\x29\x3f\x62\x5b\x63\x5d\x2e\x70\x72\x6f\x6d\x69\x73\x65\ \x28\x29\x2e\x74\x68\x65\x6e\x28\x6c\x28\x63\x29\x2c\x6a\x2e\x72\ \x65\x6a\x65\x63\x74\x2c\x6d\x28\x63\x29\x29\x3a\x2d\x2d\x67\x3b\ \x67\x7c\x7c\x6a\x2e\x72\x65\x73\x6f\x6c\x76\x65\x57\x69\x74\x68\ \x28\x6a\x2c\x62\x29\x7d\x65\x6c\x73\x65\x20\x6a\x21\x3d\x3d\x61\ \x26\x26\x6a\x2e\x72\x65\x73\x6f\x6c\x76\x65\x57\x69\x74\x68\x28\ \x6a\x2c\x64\x3f\x5b\x61\x5d\x3a\x5b\x5d\x29\x3b\x72\x65\x74\x75\ \x72\x6e\x20\x6b\x7d\x7d\x29\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\ \x74\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\ \x20\x62\x2c\x64\x2c\x65\x2c\x67\x2c\x68\x2c\x69\x2c\x6a\x2c\x6b\ \x2c\x6c\x2c\x6d\x2c\x6e\x2c\x6f\x2c\x70\x2c\x71\x3d\x63\x2e\x63\ \x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x64\x69\ \x76\x22\x29\x2c\x72\x3d\x63\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\ \x45\x6c\x65\x6d\x65\x6e\x74\x3b\x71\x2e\x73\x65\x74\x41\x74\x74\ \x72\x69\x62\x75\x74\x65\x28\x22\x63\x6c\x61\x73\x73\x4e\x61\x6d\ \x65\x22\x2c\x22\x74\x22\x29\x2c\x71\x2e\x69\x6e\x6e\x65\x72\x48\ \x54\x4d\x4c\x3d\x22\x20\x20\x20\x3c\x6c\x69\x6e\x6b\x2f\x3e\x3c\ \x74\x61\x62\x6c\x65\x3e\x3c\x2f\x74\x61\x62\x6c\x65\x3e\x3c\x61\ \x20\x68\x72\x65\x66\x3d\x27\x2f\x61\x27\x20\x73\x74\x79\x6c\x65\ \x3d\x27\x74\x6f\x70\x3a\x31\x70\x78\x3b\x66\x6c\x6f\x61\x74\x3a\ \x6c\x65\x66\x74\x3b\x6f\x70\x61\x63\x69\x74\x79\x3a\x2e\x35\x35\ \x3b\x27\x3e\x61\x3c\x2f\x61\x3e\x3c\x69\x6e\x70\x75\x74\x20\x74\ \x79\x70\x65\x3d\x27\x63\x68\x65\x63\x6b\x62\x6f\x78\x27\x2f\x3e\ \x22\x2c\x64\x3d\x71\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\ \x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\x2a\x22\x29\x2c\ \x65\x3d\x71\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\ \x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\x61\x22\x29\x5b\x30\x5d\ \x3b\x69\x66\x28\x21\x64\x7c\x7c\x21\x64\x2e\x6c\x65\x6e\x67\x74\ \x68\x7c\x7c\x21\x65\x29\x72\x65\x74\x75\x72\x6e\x7b\x7d\x3b\x67\ \x3d\x63\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\ \x28\x22\x73\x65\x6c\x65\x63\x74\x22\x29\x2c\x68\x3d\x67\x2e\x61\ \x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64\x28\x63\x2e\x63\x72\x65\ \x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x6f\x70\x74\x69\ \x6f\x6e\x22\x29\x29\x2c\x69\x3d\x71\x2e\x67\x65\x74\x45\x6c\x65\ \x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\ \x69\x6e\x70\x75\x74\x22\x29\x5b\x30\x5d\x2c\x62\x3d\x7b\x6c\x65\ \x61\x64\x69\x6e\x67\x57\x68\x69\x74\x65\x73\x70\x61\x63\x65\x3a\ \x71\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x3d\x3d\x3d\x33\x2c\x74\x62\x6f\x64\x79\x3a\ \x21\x71\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\ \x54\x61\x67\x4e\x61\x6d\x65\x28\x22\x74\x62\x6f\x64\x79\x22\x29\ \x2e\x6c\x65\x6e\x67\x74\x68\x2c\x68\x74\x6d\x6c\x53\x65\x72\x69\ \x61\x6c\x69\x7a\x65\x3a\x21\x21\x71\x2e\x67\x65\x74\x45\x6c\x65\ \x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\ \x6c\x69\x6e\x6b\x22\x29\x2e\x6c\x65\x6e\x67\x74\x68\x2c\x73\x74\ \x79\x6c\x65\x3a\x2f\x74\x6f\x70\x2f\x2e\x74\x65\x73\x74\x28\x65\ \x2e\x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\x73\ \x74\x79\x6c\x65\x22\x29\x29\x2c\x68\x72\x65\x66\x4e\x6f\x72\x6d\ \x61\x6c\x69\x7a\x65\x64\x3a\x65\x2e\x67\x65\x74\x41\x74\x74\x72\ \x69\x62\x75\x74\x65\x28\x22\x68\x72\x65\x66\x22\x29\x3d\x3d\x3d\ \x22\x2f\x61\x22\x2c\x6f\x70\x61\x63\x69\x74\x79\x3a\x2f\x5e\x30\ \x2e\x35\x35\x2f\x2e\x74\x65\x73\x74\x28\x65\x2e\x73\x74\x79\x6c\ \x65\x2e\x6f\x70\x61\x63\x69\x74\x79\x29\x2c\x63\x73\x73\x46\x6c\ \x6f\x61\x74\x3a\x21\x21\x65\x2e\x73\x74\x79\x6c\x65\x2e\x63\x73\ \x73\x46\x6c\x6f\x61\x74\x2c\x63\x68\x65\x63\x6b\x4f\x6e\x3a\x69\ \x2e\x76\x61\x6c\x75\x65\x3d\x3d\x3d\x22\x6f\x6e\x22\x2c\x6f\x70\ \x74\x53\x65\x6c\x65\x63\x74\x65\x64\x3a\x68\x2e\x73\x65\x6c\x65\ \x63\x74\x65\x64\x2c\x67\x65\x74\x53\x65\x74\x41\x74\x74\x72\x69\ \x62\x75\x74\x65\x3a\x71\x2e\x63\x6c\x61\x73\x73\x4e\x61\x6d\x65\ \x21\x3d\x3d\x22\x74\x22\x2c\x65\x6e\x63\x74\x79\x70\x65\x3a\x21\ \x21\x63\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\ \x28\x22\x66\x6f\x72\x6d\x22\x29\x2e\x65\x6e\x63\x74\x79\x70\x65\ \x2c\x68\x74\x6d\x6c\x35\x43\x6c\x6f\x6e\x65\x3a\x63\x2e\x63\x72\ \x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x6e\x61\x76\ \x22\x29\x2e\x63\x6c\x6f\x6e\x65\x4e\x6f\x64\x65\x28\x21\x30\x29\ \x2e\x6f\x75\x74\x65\x72\x48\x54\x4d\x4c\x21\x3d\x3d\x22\x3c\x3a\ \x6e\x61\x76\x3e\x3c\x2f\x3a\x6e\x61\x76\x3e\x22\x2c\x73\x75\x62\ \x6d\x69\x74\x42\x75\x62\x62\x6c\x65\x73\x3a\x21\x30\x2c\x63\x68\ \x61\x6e\x67\x65\x42\x75\x62\x62\x6c\x65\x73\x3a\x21\x30\x2c\x66\ \x6f\x63\x75\x73\x69\x6e\x42\x75\x62\x62\x6c\x65\x73\x3a\x21\x31\ \x2c\x64\x65\x6c\x65\x74\x65\x45\x78\x70\x61\x6e\x64\x6f\x3a\x21\ \x30\x2c\x6e\x6f\x43\x6c\x6f\x6e\x65\x45\x76\x65\x6e\x74\x3a\x21\ \x30\x2c\x69\x6e\x6c\x69\x6e\x65\x42\x6c\x6f\x63\x6b\x4e\x65\x65\ \x64\x73\x4c\x61\x79\x6f\x75\x74\x3a\x21\x31\x2c\x73\x68\x72\x69\ \x6e\x6b\x57\x72\x61\x70\x42\x6c\x6f\x63\x6b\x73\x3a\x21\x31\x2c\ \x72\x65\x6c\x69\x61\x62\x6c\x65\x4d\x61\x72\x67\x69\x6e\x52\x69\ \x67\x68\x74\x3a\x21\x30\x7d\x2c\x69\x2e\x63\x68\x65\x63\x6b\x65\ \x64\x3d\x21\x30\x2c\x62\x2e\x6e\x6f\x43\x6c\x6f\x6e\x65\x43\x68\ \x65\x63\x6b\x65\x64\x3d\x69\x2e\x63\x6c\x6f\x6e\x65\x4e\x6f\x64\ \x65\x28\x21\x30\x29\x2e\x63\x68\x65\x63\x6b\x65\x64\x2c\x67\x2e\ \x64\x69\x73\x61\x62\x6c\x65\x64\x3d\x21\x30\x2c\x62\x2e\x6f\x70\ \x74\x44\x69\x73\x61\x62\x6c\x65\x64\x3d\x21\x68\x2e\x64\x69\x73\ \x61\x62\x6c\x65\x64\x3b\x74\x72\x79\x7b\x64\x65\x6c\x65\x74\x65\ \x20\x71\x2e\x74\x65\x73\x74\x7d\x63\x61\x74\x63\x68\x28\x73\x29\ \x7b\x62\x2e\x64\x65\x6c\x65\x74\x65\x45\x78\x70\x61\x6e\x64\x6f\ \x3d\x21\x31\x7d\x21\x71\x2e\x61\x64\x64\x45\x76\x65\x6e\x74\x4c\ \x69\x73\x74\x65\x6e\x65\x72\x26\x26\x71\x2e\x61\x74\x74\x61\x63\ \x68\x45\x76\x65\x6e\x74\x26\x26\x71\x2e\x66\x69\x72\x65\x45\x76\ \x65\x6e\x74\x26\x26\x28\x71\x2e\x61\x74\x74\x61\x63\x68\x45\x76\ \x65\x6e\x74\x28\x22\x6f\x6e\x63\x6c\x69\x63\x6b\x22\x2c\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x62\x2e\x6e\x6f\x43\x6c\x6f\ \x6e\x65\x45\x76\x65\x6e\x74\x3d\x21\x31\x7d\x29\x2c\x71\x2e\x63\ \x6c\x6f\x6e\x65\x4e\x6f\x64\x65\x28\x21\x30\x29\x2e\x66\x69\x72\ \x65\x45\x76\x65\x6e\x74\x28\x22\x6f\x6e\x63\x6c\x69\x63\x6b\x22\ \x29\x29\x2c\x69\x3d\x63\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\ \x6d\x65\x6e\x74\x28\x22\x69\x6e\x70\x75\x74\x22\x29\x2c\x69\x2e\ \x76\x61\x6c\x75\x65\x3d\x22\x74\x22\x2c\x69\x2e\x73\x65\x74\x41\ \x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\x74\x79\x70\x65\x22\x2c\ \x22\x72\x61\x64\x69\x6f\x22\x29\x2c\x62\x2e\x72\x61\x64\x69\x6f\ \x56\x61\x6c\x75\x65\x3d\x69\x2e\x76\x61\x6c\x75\x65\x3d\x3d\x3d\ \x22\x74\x22\x2c\x69\x2e\x73\x65\x74\x41\x74\x74\x72\x69\x62\x75\ \x74\x65\x28\x22\x63\x68\x65\x63\x6b\x65\x64\x22\x2c\x22\x63\x68\ \x65\x63\x6b\x65\x64\x22\x29\x2c\x71\x2e\x61\x70\x70\x65\x6e\x64\ \x43\x68\x69\x6c\x64\x28\x69\x29\x2c\x6b\x3d\x63\x2e\x63\x72\x65\ \x61\x74\x65\x44\x6f\x63\x75\x6d\x65\x6e\x74\x46\x72\x61\x67\x6d\ \x65\x6e\x74\x28\x29\x2c\x6b\x2e\x61\x70\x70\x65\x6e\x64\x43\x68\ \x69\x6c\x64\x28\x71\x2e\x6c\x61\x73\x74\x43\x68\x69\x6c\x64\x29\ \x2c\x62\x2e\x63\x68\x65\x63\x6b\x43\x6c\x6f\x6e\x65\x3d\x6b\x2e\ \x63\x6c\x6f\x6e\x65\x4e\x6f\x64\x65\x28\x21\x30\x29\x2e\x63\x6c\ \x6f\x6e\x65\x4e\x6f\x64\x65\x28\x21\x30\x29\x2e\x6c\x61\x73\x74\ \x43\x68\x69\x6c\x64\x2e\x63\x68\x65\x63\x6b\x65\x64\x2c\x62\x2e\ \x61\x70\x70\x65\x6e\x64\x43\x68\x65\x63\x6b\x65\x64\x3d\x69\x2e\ \x63\x68\x65\x63\x6b\x65\x64\x2c\x6b\x2e\x72\x65\x6d\x6f\x76\x65\ \x43\x68\x69\x6c\x64\x28\x69\x29\x2c\x6b\x2e\x61\x70\x70\x65\x6e\ \x64\x43\x68\x69\x6c\x64\x28\x71\x29\x2c\x71\x2e\x69\x6e\x6e\x65\ \x72\x48\x54\x4d\x4c\x3d\x22\x22\x2c\x61\x2e\x67\x65\x74\x43\x6f\ \x6d\x70\x75\x74\x65\x64\x53\x74\x79\x6c\x65\x26\x26\x28\x6a\x3d\ \x63\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\ \x22\x64\x69\x76\x22\x29\x2c\x6a\x2e\x73\x74\x79\x6c\x65\x2e\x77\ \x69\x64\x74\x68\x3d\x22\x30\x22\x2c\x6a\x2e\x73\x74\x79\x6c\x65\ \x2e\x6d\x61\x72\x67\x69\x6e\x52\x69\x67\x68\x74\x3d\x22\x30\x22\ \x2c\x71\x2e\x73\x74\x79\x6c\x65\x2e\x77\x69\x64\x74\x68\x3d\x22\ \x32\x70\x78\x22\x2c\x71\x2e\x61\x70\x70\x65\x6e\x64\x43\x68\x69\ \x6c\x64\x28\x6a\x29\x2c\x62\x2e\x72\x65\x6c\x69\x61\x62\x6c\x65\ \x4d\x61\x72\x67\x69\x6e\x52\x69\x67\x68\x74\x3d\x28\x70\x61\x72\ \x73\x65\x49\x6e\x74\x28\x28\x61\x2e\x67\x65\x74\x43\x6f\x6d\x70\ \x75\x74\x65\x64\x53\x74\x79\x6c\x65\x28\x6a\x2c\x6e\x75\x6c\x6c\ \x29\x7c\x7c\x7b\x6d\x61\x72\x67\x69\x6e\x52\x69\x67\x68\x74\x3a\ \x30\x7d\x29\x2e\x6d\x61\x72\x67\x69\x6e\x52\x69\x67\x68\x74\x2c\ \x31\x30\x29\x7c\x7c\x30\x29\x3d\x3d\x3d\x30\x29\x3b\x69\x66\x28\ \x71\x2e\x61\x74\x74\x61\x63\x68\x45\x76\x65\x6e\x74\x29\x66\x6f\ \x72\x28\x6f\x20\x69\x6e\x7b\x73\x75\x62\x6d\x69\x74\x3a\x31\x2c\ \x63\x68\x61\x6e\x67\x65\x3a\x31\x2c\x66\x6f\x63\x75\x73\x69\x6e\ \x3a\x31\x7d\x29\x6e\x3d\x22\x6f\x6e\x22\x2b\x6f\x2c\x70\x3d\x6e\ \x20\x69\x6e\x20\x71\x2c\x70\x7c\x7c\x28\x71\x2e\x73\x65\x74\x41\ \x74\x74\x72\x69\x62\x75\x74\x65\x28\x6e\x2c\x22\x72\x65\x74\x75\ \x72\x6e\x3b\x22\x29\x2c\x70\x3d\x74\x79\x70\x65\x6f\x66\x20\x71\ \x5b\x6e\x5d\x3d\x3d\x22\x66\x75\x6e\x63\x74\x69\x6f\x6e\x22\x29\ \x2c\x62\x5b\x6f\x2b\x22\x42\x75\x62\x62\x6c\x65\x73\x22\x5d\x3d\ \x70\x3b\x6b\x2e\x72\x65\x6d\x6f\x76\x65\x43\x68\x69\x6c\x64\x28\ \x71\x29\x2c\x6b\x3d\x67\x3d\x68\x3d\x6a\x3d\x71\x3d\x69\x3d\x6e\ \x75\x6c\x6c\x2c\x66\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\ \x7b\x76\x61\x72\x20\x61\x2c\x64\x2c\x65\x2c\x67\x2c\x68\x2c\x69\ \x2c\x6a\x2c\x6b\x2c\x6d\x2c\x6e\x2c\x6f\x2c\x72\x3d\x63\x2e\x67\ \x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\ \x61\x6d\x65\x28\x22\x62\x6f\x64\x79\x22\x29\x5b\x30\x5d\x3b\x21\ \x72\x7c\x7c\x28\x6a\x3d\x31\x2c\x6b\x3d\x22\x70\x6f\x73\x69\x74\ \x69\x6f\x6e\x3a\x61\x62\x73\x6f\x6c\x75\x74\x65\x3b\x74\x6f\x70\ \x3a\x30\x3b\x6c\x65\x66\x74\x3a\x30\x3b\x77\x69\x64\x74\x68\x3a\ \x31\x70\x78\x3b\x68\x65\x69\x67\x68\x74\x3a\x31\x70\x78\x3b\x6d\ \x61\x72\x67\x69\x6e\x3a\x30\x3b\x22\x2c\x6d\x3d\x22\x76\x69\x73\ \x69\x62\x69\x6c\x69\x74\x79\x3a\x68\x69\x64\x64\x65\x6e\x3b\x62\ \x6f\x72\x64\x65\x72\x3a\x30\x3b\x22\x2c\x6e\x3d\x22\x73\x74\x79\ \x6c\x65\x3d\x27\x22\x2b\x6b\x2b\x22\x62\x6f\x72\x64\x65\x72\x3a\ \x35\x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x23\x30\x30\x30\x3b\x70\ \x61\x64\x64\x69\x6e\x67\x3a\x30\x3b\x27\x22\x2c\x6f\x3d\x22\x3c\ \x64\x69\x76\x20\x22\x2b\x6e\x2b\x22\x3e\x3c\x64\x69\x76\x3e\x3c\ \x2f\x64\x69\x76\x3e\x3c\x2f\x64\x69\x76\x3e\x22\x2b\x22\x3c\x74\ \x61\x62\x6c\x65\x20\x22\x2b\x6e\x2b\x22\x20\x63\x65\x6c\x6c\x70\ \x61\x64\x64\x69\x6e\x67\x3d\x27\x30\x27\x20\x63\x65\x6c\x6c\x73\ \x70\x61\x63\x69\x6e\x67\x3d\x27\x30\x27\x3e\x22\x2b\x22\x3c\x74\ \x72\x3e\x3c\x74\x64\x3e\x3c\x2f\x74\x64\x3e\x3c\x2f\x74\x72\x3e\ \x3c\x2f\x74\x61\x62\x6c\x65\x3e\x22\x2c\x61\x3d\x63\x2e\x63\x72\ \x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x64\x69\x76\ \x22\x29\x2c\x61\x2e\x73\x74\x79\x6c\x65\x2e\x63\x73\x73\x54\x65\ \x78\x74\x3d\x6d\x2b\x22\x77\x69\x64\x74\x68\x3a\x30\x3b\x68\x65\ \x69\x67\x68\x74\x3a\x30\x3b\x70\x6f\x73\x69\x74\x69\x6f\x6e\x3a\ \x73\x74\x61\x74\x69\x63\x3b\x74\x6f\x70\x3a\x30\x3b\x6d\x61\x72\ \x67\x69\x6e\x2d\x74\x6f\x70\x3a\x22\x2b\x6a\x2b\x22\x70\x78\x22\ \x2c\x72\x2e\x69\x6e\x73\x65\x72\x74\x42\x65\x66\x6f\x72\x65\x28\ \x61\x2c\x72\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x29\x2c\ \x71\x3d\x63\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\ \x74\x28\x22\x64\x69\x76\x22\x29\x2c\x61\x2e\x61\x70\x70\x65\x6e\ \x64\x43\x68\x69\x6c\x64\x28\x71\x29\x2c\x71\x2e\x69\x6e\x6e\x65\ \x72\x48\x54\x4d\x4c\x3d\x22\x3c\x74\x61\x62\x6c\x65\x3e\x3c\x74\ \x72\x3e\x3c\x74\x64\x20\x73\x74\x79\x6c\x65\x3d\x27\x70\x61\x64\ \x64\x69\x6e\x67\x3a\x30\x3b\x62\x6f\x72\x64\x65\x72\x3a\x30\x3b\ \x64\x69\x73\x70\x6c\x61\x79\x3a\x6e\x6f\x6e\x65\x27\x3e\x3c\x2f\ \x74\x64\x3e\x3c\x74\x64\x3e\x74\x3c\x2f\x74\x64\x3e\x3c\x2f\x74\ \x72\x3e\x3c\x2f\x74\x61\x62\x6c\x65\x3e\x22\x2c\x6c\x3d\x71\x2e\ \x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\ \x4e\x61\x6d\x65\x28\x22\x74\x64\x22\x29\x2c\x70\x3d\x6c\x5b\x30\ \x5d\x2e\x6f\x66\x66\x73\x65\x74\x48\x65\x69\x67\x68\x74\x3d\x3d\ \x3d\x30\x2c\x6c\x5b\x30\x5d\x2e\x73\x74\x79\x6c\x65\x2e\x64\x69\ \x73\x70\x6c\x61\x79\x3d\x22\x22\x2c\x6c\x5b\x31\x5d\x2e\x73\x74\ \x79\x6c\x65\x2e\x64\x69\x73\x70\x6c\x61\x79\x3d\x22\x6e\x6f\x6e\ \x65\x22\x2c\x62\x2e\x72\x65\x6c\x69\x61\x62\x6c\x65\x48\x69\x64\ \x64\x65\x6e\x4f\x66\x66\x73\x65\x74\x73\x3d\x70\x26\x26\x6c\x5b\ \x30\x5d\x2e\x6f\x66\x66\x73\x65\x74\x48\x65\x69\x67\x68\x74\x3d\ \x3d\x3d\x30\x2c\x71\x2e\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c\x3d\ \x22\x22\x2c\x71\x2e\x73\x74\x79\x6c\x65\x2e\x77\x69\x64\x74\x68\ \x3d\x71\x2e\x73\x74\x79\x6c\x65\x2e\x70\x61\x64\x64\x69\x6e\x67\ \x4c\x65\x66\x74\x3d\x22\x31\x70\x78\x22\x2c\x66\x2e\x62\x6f\x78\ \x4d\x6f\x64\x65\x6c\x3d\x62\x2e\x62\x6f\x78\x4d\x6f\x64\x65\x6c\ \x3d\x71\x2e\x6f\x66\x66\x73\x65\x74\x57\x69\x64\x74\x68\x3d\x3d\ \x3d\x32\x2c\x74\x79\x70\x65\x6f\x66\x20\x71\x2e\x73\x74\x79\x6c\ \x65\x2e\x7a\x6f\x6f\x6d\x21\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\ \x65\x64\x22\x26\x26\x28\x71\x2e\x73\x74\x79\x6c\x65\x2e\x64\x69\ \x73\x70\x6c\x61\x79\x3d\x22\x69\x6e\x6c\x69\x6e\x65\x22\x2c\x71\ \x2e\x73\x74\x79\x6c\x65\x2e\x7a\x6f\x6f\x6d\x3d\x31\x2c\x62\x2e\ \x69\x6e\x6c\x69\x6e\x65\x42\x6c\x6f\x63\x6b\x4e\x65\x65\x64\x73\ \x4c\x61\x79\x6f\x75\x74\x3d\x71\x2e\x6f\x66\x66\x73\x65\x74\x57\ \x69\x64\x74\x68\x3d\x3d\x3d\x32\x2c\x71\x2e\x73\x74\x79\x6c\x65\ \x2e\x64\x69\x73\x70\x6c\x61\x79\x3d\x22\x22\x2c\x71\x2e\x69\x6e\ \x6e\x65\x72\x48\x54\x4d\x4c\x3d\x22\x3c\x64\x69\x76\x20\x73\x74\ \x79\x6c\x65\x3d\x27\x77\x69\x64\x74\x68\x3a\x34\x70\x78\x3b\x27\ \x3e\x3c\x2f\x64\x69\x76\x3e\x22\x2c\x62\x2e\x73\x68\x72\x69\x6e\ \x6b\x57\x72\x61\x70\x42\x6c\x6f\x63\x6b\x73\x3d\x71\x2e\x6f\x66\ \x66\x73\x65\x74\x57\x69\x64\x74\x68\x21\x3d\x3d\x32\x29\x2c\x71\ \x2e\x73\x74\x79\x6c\x65\x2e\x63\x73\x73\x54\x65\x78\x74\x3d\x6b\ \x2b\x6d\x2c\x71\x2e\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c\x3d\x6f\ \x2c\x64\x3d\x71\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x2c\ \x65\x3d\x64\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x2c\x68\ \x3d\x64\x2e\x6e\x65\x78\x74\x53\x69\x62\x6c\x69\x6e\x67\x2e\x66\ \x69\x72\x73\x74\x43\x68\x69\x6c\x64\x2e\x66\x69\x72\x73\x74\x43\ \x68\x69\x6c\x64\x2c\x69\x3d\x7b\x64\x6f\x65\x73\x4e\x6f\x74\x41\ \x64\x64\x42\x6f\x72\x64\x65\x72\x3a\x65\x2e\x6f\x66\x66\x73\x65\ \x74\x54\x6f\x70\x21\x3d\x3d\x35\x2c\x64\x6f\x65\x73\x41\x64\x64\ \x42\x6f\x72\x64\x65\x72\x46\x6f\x72\x54\x61\x62\x6c\x65\x41\x6e\ \x64\x43\x65\x6c\x6c\x73\x3a\x68\x2e\x6f\x66\x66\x73\x65\x74\x54\ \x6f\x70\x3d\x3d\x3d\x35\x7d\x2c\x65\x2e\x73\x74\x79\x6c\x65\x2e\ \x70\x6f\x73\x69\x74\x69\x6f\x6e\x3d\x22\x66\x69\x78\x65\x64\x22\ \x2c\x65\x2e\x73\x74\x79\x6c\x65\x2e\x74\x6f\x70\x3d\x22\x32\x30\ \x70\x78\x22\x2c\x69\x2e\x66\x69\x78\x65\x64\x50\x6f\x73\x69\x74\ \x69\x6f\x6e\x3d\x65\x2e\x6f\x66\x66\x73\x65\x74\x54\x6f\x70\x3d\ \x3d\x3d\x32\x30\x7c\x7c\x65\x2e\x6f\x66\x66\x73\x65\x74\x54\x6f\ \x70\x3d\x3d\x3d\x31\x35\x2c\x65\x2e\x73\x74\x79\x6c\x65\x2e\x70\ \x6f\x73\x69\x74\x69\x6f\x6e\x3d\x65\x2e\x73\x74\x79\x6c\x65\x2e\ \x74\x6f\x70\x3d\x22\x22\x2c\x64\x2e\x73\x74\x79\x6c\x65\x2e\x6f\ \x76\x65\x72\x66\x6c\x6f\x77\x3d\x22\x68\x69\x64\x64\x65\x6e\x22\ \x2c\x64\x2e\x73\x74\x79\x6c\x65\x2e\x70\x6f\x73\x69\x74\x69\x6f\ \x6e\x3d\x22\x72\x65\x6c\x61\x74\x69\x76\x65\x22\x2c\x69\x2e\x73\ \x75\x62\x74\x72\x61\x63\x74\x73\x42\x6f\x72\x64\x65\x72\x46\x6f\ \x72\x4f\x76\x65\x72\x66\x6c\x6f\x77\x4e\x6f\x74\x56\x69\x73\x69\ \x62\x6c\x65\x3d\x65\x2e\x6f\x66\x66\x73\x65\x74\x54\x6f\x70\x3d\ \x3d\x3d\x2d\x35\x2c\x69\x2e\x64\x6f\x65\x73\x4e\x6f\x74\x49\x6e\ \x63\x6c\x75\x64\x65\x4d\x61\x72\x67\x69\x6e\x49\x6e\x42\x6f\x64\ \x79\x4f\x66\x66\x73\x65\x74\x3d\x72\x2e\x6f\x66\x66\x73\x65\x74\ \x54\x6f\x70\x21\x3d\x3d\x6a\x2c\x72\x2e\x72\x65\x6d\x6f\x76\x65\ \x43\x68\x69\x6c\x64\x28\x61\x29\x2c\x71\x3d\x61\x3d\x6e\x75\x6c\ \x6c\x2c\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x62\x2c\x69\x29\x29\ \x7d\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x62\x7d\x28\x29\x3b\x76\ \x61\x72\x20\x6a\x3d\x2f\x5e\x28\x3f\x3a\x5c\x7b\x2e\x2a\x5c\x7d\ \x7c\x5c\x5b\x2e\x2a\x5c\x5d\x29\x24\x2f\x2c\x6b\x3d\x2f\x28\x5b\ \x41\x2d\x5a\x5d\x29\x2f\x67\x3b\x66\x2e\x65\x78\x74\x65\x6e\x64\ \x28\x7b\x63\x61\x63\x68\x65\x3a\x7b\x7d\x2c\x75\x75\x69\x64\x3a\ \x30\x2c\x65\x78\x70\x61\x6e\x64\x6f\x3a\x22\x6a\x51\x75\x65\x72\ \x79\x22\x2b\x28\x66\x2e\x66\x6e\x2e\x6a\x71\x75\x65\x72\x79\x2b\ \x4d\x61\x74\x68\x2e\x72\x61\x6e\x64\x6f\x6d\x28\x29\x29\x2e\x72\ \x65\x70\x6c\x61\x63\x65\x28\x2f\x5c\x44\x2f\x67\x2c\x22\x22\x29\ \x2c\x6e\x6f\x44\x61\x74\x61\x3a\x7b\x65\x6d\x62\x65\x64\x3a\x21\ \x30\x2c\x6f\x62\x6a\x65\x63\x74\x3a\x22\x63\x6c\x73\x69\x64\x3a\ \x44\x32\x37\x43\x44\x42\x36\x45\x2d\x41\x45\x36\x44\x2d\x31\x31\ \x63\x66\x2d\x39\x36\x42\x38\x2d\x34\x34\x34\x35\x35\x33\x35\x34\ \x30\x30\x30\x30\x22\x2c\x61\x70\x70\x6c\x65\x74\x3a\x21\x30\x7d\ \x2c\x68\x61\x73\x44\x61\x74\x61\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x29\x7b\x61\x3d\x61\x2e\x6e\x6f\x64\x65\x54\x79\x70\ \x65\x3f\x66\x2e\x63\x61\x63\x68\x65\x5b\x61\x5b\x66\x2e\x65\x78\ \x70\x61\x6e\x64\x6f\x5d\x5d\x3a\x61\x5b\x66\x2e\x65\x78\x70\x61\ \x6e\x64\x6f\x5d\x3b\x72\x65\x74\x75\x72\x6e\x21\x21\x61\x26\x26\ \x21\x6d\x28\x61\x29\x7d\x2c\x64\x61\x74\x61\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x63\x2c\x64\x2c\x65\x29\x7b\x69\x66\ \x28\x21\x21\x66\x2e\x61\x63\x63\x65\x70\x74\x44\x61\x74\x61\x28\ \x61\x29\x29\x7b\x76\x61\x72\x20\x67\x2c\x68\x2c\x69\x2c\x6a\x3d\ \x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x2c\x6b\x3d\x74\x79\x70\x65\ \x6f\x66\x20\x63\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x2c\x6c\ \x3d\x61\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x2c\x6d\x3d\x6c\x3f\ \x66\x2e\x63\x61\x63\x68\x65\x3a\x61\x2c\x6e\x3d\x6c\x3f\x61\x5b\ \x6a\x5d\x3a\x61\x5b\x6a\x5d\x26\x26\x6a\x2c\x6f\x3d\x63\x3d\x3d\ \x3d\x22\x65\x76\x65\x6e\x74\x73\x22\x3b\x69\x66\x28\x28\x21\x6e\ \x7c\x7c\x21\x6d\x5b\x6e\x5d\x7c\x7c\x21\x6f\x26\x26\x21\x65\x26\ \x26\x21\x6d\x5b\x6e\x5d\x2e\x64\x61\x74\x61\x29\x26\x26\x6b\x26\ \x26\x64\x3d\x3d\x3d\x62\x29\x72\x65\x74\x75\x72\x6e\x3b\x6e\x7c\ \x7c\x28\x6c\x3f\x61\x5b\x6a\x5d\x3d\x6e\x3d\x2b\x2b\x66\x2e\x75\ \x75\x69\x64\x3a\x6e\x3d\x6a\x29\x2c\x6d\x5b\x6e\x5d\x7c\x7c\x28\ \x6d\x5b\x6e\x5d\x3d\x7b\x7d\x2c\x6c\x7c\x7c\x28\x6d\x5b\x6e\x5d\ \x2e\x74\x6f\x4a\x53\x4f\x4e\x3d\x66\x2e\x6e\x6f\x6f\x70\x29\x29\ \x3b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x63\x3d\x3d\x22\x6f\ \x62\x6a\x65\x63\x74\x22\x7c\x7c\x74\x79\x70\x65\x6f\x66\x20\x63\ \x3d\x3d\x22\x66\x75\x6e\x63\x74\x69\x6f\x6e\x22\x29\x65\x3f\x6d\ \x5b\x6e\x5d\x3d\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x6d\x5b\x6e\ \x5d\x2c\x63\x29\x3a\x6d\x5b\x6e\x5d\x2e\x64\x61\x74\x61\x3d\x66\ \x2e\x65\x78\x74\x65\x6e\x64\x28\x6d\x5b\x6e\x5d\x2e\x64\x61\x74\ \x61\x2c\x63\x29\x3b\x67\x3d\x68\x3d\x6d\x5b\x6e\x5d\x2c\x65\x7c\ \x7c\x28\x68\x2e\x64\x61\x74\x61\x7c\x7c\x28\x68\x2e\x64\x61\x74\ \x61\x3d\x7b\x7d\x29\x2c\x68\x3d\x68\x2e\x64\x61\x74\x61\x29\x2c\ \x64\x21\x3d\x3d\x62\x26\x26\x28\x68\x5b\x66\x2e\x63\x61\x6d\x65\ \x6c\x43\x61\x73\x65\x28\x63\x29\x5d\x3d\x64\x29\x3b\x69\x66\x28\ \x6f\x26\x26\x21\x68\x5b\x63\x5d\x29\x72\x65\x74\x75\x72\x6e\x20\ \x67\x2e\x65\x76\x65\x6e\x74\x73\x3b\x6b\x3f\x28\x69\x3d\x68\x5b\ \x63\x5d\x2c\x69\x3d\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x69\x3d\x68\ \x5b\x66\x2e\x63\x61\x6d\x65\x6c\x43\x61\x73\x65\x28\x63\x29\x5d\ \x29\x29\x3a\x69\x3d\x68\x3b\x72\x65\x74\x75\x72\x6e\x20\x69\x7d\ \x7d\x2c\x72\x65\x6d\x6f\x76\x65\x44\x61\x74\x61\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x69\x66\x28\ \x21\x21\x66\x2e\x61\x63\x63\x65\x70\x74\x44\x61\x74\x61\x28\x61\ \x29\x29\x7b\x76\x61\x72\x20\x64\x2c\x65\x2c\x67\x2c\x68\x3d\x66\ \x2e\x65\x78\x70\x61\x6e\x64\x6f\x2c\x69\x3d\x61\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x2c\x6a\x3d\x69\x3f\x66\x2e\x63\x61\x63\x68\ \x65\x3a\x61\x2c\x6b\x3d\x69\x3f\x61\x5b\x68\x5d\x3a\x68\x3b\x69\ \x66\x28\x21\x6a\x5b\x6b\x5d\x29\x72\x65\x74\x75\x72\x6e\x3b\x69\ \x66\x28\x62\x29\x7b\x64\x3d\x63\x3f\x6a\x5b\x6b\x5d\x3a\x6a\x5b\ \x6b\x5d\x2e\x64\x61\x74\x61\x3b\x69\x66\x28\x64\x29\x7b\x66\x2e\ \x69\x73\x41\x72\x72\x61\x79\x28\x62\x29\x7c\x7c\x28\x62\x20\x69\ \x6e\x20\x64\x3f\x62\x3d\x5b\x62\x5d\x3a\x28\x62\x3d\x66\x2e\x63\ \x61\x6d\x65\x6c\x43\x61\x73\x65\x28\x62\x29\x2c\x62\x20\x69\x6e\ \x20\x64\x3f\x62\x3d\x5b\x62\x5d\x3a\x62\x3d\x62\x2e\x73\x70\x6c\ \x69\x74\x28\x22\x20\x22\x29\x29\x29\x3b\x66\x6f\x72\x28\x65\x3d\ \x30\x2c\x67\x3d\x62\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x65\x3c\x67\ \x3b\x65\x2b\x2b\x29\x64\x65\x6c\x65\x74\x65\x20\x64\x5b\x62\x5b\ \x65\x5d\x5d\x3b\x69\x66\x28\x21\x28\x63\x3f\x6d\x3a\x66\x2e\x69\ \x73\x45\x6d\x70\x74\x79\x4f\x62\x6a\x65\x63\x74\x29\x28\x64\x29\ \x29\x72\x65\x74\x75\x72\x6e\x7d\x7d\x69\x66\x28\x21\x63\x29\x7b\ \x64\x65\x6c\x65\x74\x65\x20\x6a\x5b\x6b\x5d\x2e\x64\x61\x74\x61\ \x3b\x69\x66\x28\x21\x6d\x28\x6a\x5b\x6b\x5d\x29\x29\x72\x65\x74\ \x75\x72\x6e\x7d\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x64\x65\ \x6c\x65\x74\x65\x45\x78\x70\x61\x6e\x64\x6f\x7c\x7c\x21\x6a\x2e\ \x73\x65\x74\x49\x6e\x74\x65\x72\x76\x61\x6c\x3f\x64\x65\x6c\x65\ \x74\x65\x20\x6a\x5b\x6b\x5d\x3a\x6a\x5b\x6b\x5d\x3d\x6e\x75\x6c\ \x6c\x2c\x69\x26\x26\x28\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\ \x64\x65\x6c\x65\x74\x65\x45\x78\x70\x61\x6e\x64\x6f\x3f\x64\x65\ \x6c\x65\x74\x65\x20\x61\x5b\x68\x5d\x3a\x61\x2e\x72\x65\x6d\x6f\ \x76\x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x3f\x61\x2e\x72\x65\ \x6d\x6f\x76\x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x68\x29\ \x3a\x61\x5b\x68\x5d\x3d\x6e\x75\x6c\x6c\x29\x7d\x7d\x2c\x5f\x64\ \x61\x74\x61\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\ \x2c\x63\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x64\x61\x74\ \x61\x28\x61\x2c\x62\x2c\x63\x2c\x21\x30\x29\x7d\x2c\x61\x63\x63\ \x65\x70\x74\x44\x61\x74\x61\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x69\x66\x28\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\ \x65\x29\x7b\x76\x61\x72\x20\x62\x3d\x66\x2e\x6e\x6f\x44\x61\x74\ \x61\x5b\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\ \x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x5d\x3b\x69\x66\x28\x62\ \x29\x72\x65\x74\x75\x72\x6e\x20\x62\x21\x3d\x3d\x21\x30\x26\x26\ \x61\x2e\x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\ \x63\x6c\x61\x73\x73\x69\x64\x22\x29\x3d\x3d\x3d\x62\x7d\x72\x65\ \x74\x75\x72\x6e\x21\x30\x7d\x7d\x29\x2c\x66\x2e\x66\x6e\x2e\x65\ \x78\x74\x65\x6e\x64\x28\x7b\x64\x61\x74\x61\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x2c\ \x65\x2c\x67\x2c\x68\x3d\x6e\x75\x6c\x6c\x3b\x69\x66\x28\x74\x79\ \x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\ \x65\x64\x22\x29\x7b\x69\x66\x28\x74\x68\x69\x73\x2e\x6c\x65\x6e\ \x67\x74\x68\x29\x7b\x68\x3d\x66\x2e\x64\x61\x74\x61\x28\x74\x68\ \x69\x73\x5b\x30\x5d\x29\x3b\x69\x66\x28\x74\x68\x69\x73\x5b\x30\ \x5d\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\x26\ \x21\x66\x2e\x5f\x64\x61\x74\x61\x28\x74\x68\x69\x73\x5b\x30\x5d\ \x2c\x22\x70\x61\x72\x73\x65\x64\x41\x74\x74\x72\x73\x22\x29\x29\ \x7b\x65\x3d\x74\x68\x69\x73\x5b\x30\x5d\x2e\x61\x74\x74\x72\x69\ \x62\x75\x74\x65\x73\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\x69\x3d\ \x30\x2c\x6a\x3d\x65\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x69\x3c\x6a\ \x3b\x69\x2b\x2b\x29\x67\x3d\x65\x5b\x69\x5d\x2e\x6e\x61\x6d\x65\ \x2c\x67\x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x22\x64\x61\x74\x61\ \x2d\x22\x29\x3d\x3d\x3d\x30\x26\x26\x28\x67\x3d\x66\x2e\x63\x61\ \x6d\x65\x6c\x43\x61\x73\x65\x28\x67\x2e\x73\x75\x62\x73\x74\x72\ \x69\x6e\x67\x28\x35\x29\x29\x2c\x6c\x28\x74\x68\x69\x73\x5b\x30\ \x5d\x2c\x67\x2c\x68\x5b\x67\x5d\x29\x29\x3b\x66\x2e\x5f\x64\x61\ \x74\x61\x28\x74\x68\x69\x73\x5b\x30\x5d\x2c\x22\x70\x61\x72\x73\ \x65\x64\x41\x74\x74\x72\x73\x22\x2c\x21\x30\x29\x7d\x7d\x72\x65\ \x74\x75\x72\x6e\x20\x68\x7d\x69\x66\x28\x74\x79\x70\x65\x6f\x66\ \x20\x61\x3d\x3d\x22\x6f\x62\x6a\x65\x63\x74\x22\x29\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\x2e\x64\x61\x74\x61\x28\ \x74\x68\x69\x73\x2c\x61\x29\x7d\x29\x3b\x64\x3d\x61\x2e\x73\x70\ \x6c\x69\x74\x28\x22\x2e\x22\x29\x2c\x64\x5b\x31\x5d\x3d\x64\x5b\ \x31\x5d\x3f\x22\x2e\x22\x2b\x64\x5b\x31\x5d\x3a\x22\x22\x3b\x69\ \x66\x28\x63\x3d\x3d\x3d\x62\x29\x7b\x68\x3d\x74\x68\x69\x73\x2e\ \x74\x72\x69\x67\x67\x65\x72\x48\x61\x6e\x64\x6c\x65\x72\x28\x22\ \x67\x65\x74\x44\x61\x74\x61\x22\x2b\x64\x5b\x31\x5d\x2b\x22\x21\ \x22\x2c\x5b\x64\x5b\x30\x5d\x5d\x29\x2c\x68\x3d\x3d\x3d\x62\x26\ \x26\x74\x68\x69\x73\x2e\x6c\x65\x6e\x67\x74\x68\x26\x26\x28\x68\ \x3d\x66\x2e\x64\x61\x74\x61\x28\x74\x68\x69\x73\x5b\x30\x5d\x2c\ \x61\x29\x2c\x68\x3d\x6c\x28\x74\x68\x69\x73\x5b\x30\x5d\x2c\x61\ \x2c\x68\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x68\x3d\x3d\x3d\ \x62\x26\x26\x64\x5b\x31\x5d\x3f\x74\x68\x69\x73\x2e\x64\x61\x74\ \x61\x28\x64\x5b\x30\x5d\x29\x3a\x68\x7d\x72\x65\x74\x75\x72\x6e\ \x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x62\x3d\x66\x28\x74\x68\ \x69\x73\x29\x2c\x65\x3d\x5b\x64\x5b\x30\x5d\x2c\x63\x5d\x3b\x62\ \x2e\x74\x72\x69\x67\x67\x65\x72\x48\x61\x6e\x64\x6c\x65\x72\x28\ \x22\x73\x65\x74\x44\x61\x74\x61\x22\x2b\x64\x5b\x31\x5d\x2b\x22\ \x21\x22\x2c\x65\x29\x2c\x66\x2e\x64\x61\x74\x61\x28\x74\x68\x69\ \x73\x2c\x61\x2c\x63\x29\x2c\x62\x2e\x74\x72\x69\x67\x67\x65\x72\ \x48\x61\x6e\x64\x6c\x65\x72\x28\x22\x63\x68\x61\x6e\x67\x65\x44\ \x61\x74\x61\x22\x2b\x64\x5b\x31\x5d\x2b\x22\x21\x22\x2c\x65\x29\ \x7d\x29\x7d\x2c\x72\x65\x6d\x6f\x76\x65\x44\x61\x74\x61\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x29\x7b\x66\x2e\x72\x65\x6d\x6f\x76\x65\x44\ \x61\x74\x61\x28\x74\x68\x69\x73\x2c\x61\x29\x7d\x29\x7d\x7d\x29\ \x2c\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x5f\x6d\x61\x72\x6b\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x61\ \x26\x26\x28\x62\x3d\x28\x62\x7c\x7c\x22\x66\x78\x22\x29\x2b\x22\ \x6d\x61\x72\x6b\x22\x2c\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\ \x62\x2c\x28\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\x62\x29\x7c\ \x7c\x30\x29\x2b\x31\x29\x29\x7d\x2c\x5f\x75\x6e\x6d\x61\x72\x6b\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\ \x7b\x61\x21\x3d\x3d\x21\x30\x26\x26\x28\x63\x3d\x62\x2c\x62\x3d\ \x61\x2c\x61\x3d\x21\x31\x29\x3b\x69\x66\x28\x62\x29\x7b\x63\x3d\ \x63\x7c\x7c\x22\x66\x78\x22\x3b\x76\x61\x72\x20\x64\x3d\x63\x2b\ \x22\x6d\x61\x72\x6b\x22\x2c\x65\x3d\x61\x3f\x30\x3a\x28\x66\x2e\ \x5f\x64\x61\x74\x61\x28\x62\x2c\x64\x29\x7c\x7c\x31\x29\x2d\x31\ \x3b\x65\x3f\x66\x2e\x5f\x64\x61\x74\x61\x28\x62\x2c\x64\x2c\x65\ \x29\x3a\x28\x66\x2e\x72\x65\x6d\x6f\x76\x65\x44\x61\x74\x61\x28\ \x62\x2c\x64\x2c\x21\x30\x29\x2c\x6e\x28\x62\x2c\x63\x2c\x22\x6d\ \x61\x72\x6b\x22\x29\x29\x7d\x7d\x2c\x71\x75\x65\x75\x65\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\ \x61\x72\x20\x64\x3b\x69\x66\x28\x61\x29\x7b\x62\x3d\x28\x62\x7c\ \x7c\x22\x66\x78\x22\x29\x2b\x22\x71\x75\x65\x75\x65\x22\x2c\x64\ \x3d\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\x62\x29\x2c\x63\x26\ \x26\x28\x21\x64\x7c\x7c\x66\x2e\x69\x73\x41\x72\x72\x61\x79\x28\ \x63\x29\x3f\x64\x3d\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\x62\ \x2c\x66\x2e\x6d\x61\x6b\x65\x41\x72\x72\x61\x79\x28\x63\x29\x29\ \x3a\x64\x2e\x70\x75\x73\x68\x28\x63\x29\x29\x3b\x72\x65\x74\x75\ \x72\x6e\x20\x64\x7c\x7c\x5b\x5d\x7d\x7d\x2c\x64\x65\x71\x75\x65\ \x75\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\ \x7b\x62\x3d\x62\x7c\x7c\x22\x66\x78\x22\x3b\x76\x61\x72\x20\x63\ \x3d\x66\x2e\x71\x75\x65\x75\x65\x28\x61\x2c\x62\x29\x2c\x64\x3d\ \x63\x2e\x73\x68\x69\x66\x74\x28\x29\x2c\x65\x3d\x7b\x7d\x3b\x64\ \x3d\x3d\x3d\x22\x69\x6e\x70\x72\x6f\x67\x72\x65\x73\x73\x22\x26\ \x26\x28\x64\x3d\x63\x2e\x73\x68\x69\x66\x74\x28\x29\x29\x2c\x64\ \x26\x26\x28\x62\x3d\x3d\x3d\x22\x66\x78\x22\x26\x26\x63\x2e\x75\ \x6e\x73\x68\x69\x66\x74\x28\x22\x69\x6e\x70\x72\x6f\x67\x72\x65\ \x73\x73\x22\x29\x2c\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\x2c\x62\ \x2b\x22\x2e\x72\x75\x6e\x22\x2c\x65\x29\x2c\x64\x2e\x63\x61\x6c\ \x6c\x28\x61\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\ \x2e\x64\x65\x71\x75\x65\x75\x65\x28\x61\x2c\x62\x29\x7d\x2c\x65\ \x29\x29\x2c\x63\x2e\x6c\x65\x6e\x67\x74\x68\x7c\x7c\x28\x66\x2e\ \x72\x65\x6d\x6f\x76\x65\x44\x61\x74\x61\x28\x61\x2c\x62\x2b\x22\ \x71\x75\x65\x75\x65\x20\x22\x2b\x62\x2b\x22\x2e\x72\x75\x6e\x22\ \x2c\x21\x30\x29\x2c\x6e\x28\x61\x2c\x62\x2c\x22\x71\x75\x65\x75\ \x65\x22\x29\x29\x7d\x7d\x29\x2c\x66\x2e\x66\x6e\x2e\x65\x78\x74\ \x65\x6e\x64\x28\x7b\x71\x75\x65\x75\x65\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x74\x79\x70\x65\x6f\x66\x20\ \x61\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x28\x63\x3d\ \x61\x2c\x61\x3d\x22\x66\x78\x22\x29\x3b\x69\x66\x28\x63\x3d\x3d\ \x3d\x62\x29\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x71\x75\x65\x75\ \x65\x28\x74\x68\x69\x73\x5b\x30\x5d\x2c\x61\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x62\x3d\x66\ \x2e\x71\x75\x65\x75\x65\x28\x74\x68\x69\x73\x2c\x61\x2c\x63\x29\ \x3b\x61\x3d\x3d\x3d\x22\x66\x78\x22\x26\x26\x62\x5b\x30\x5d\x21\ \x3d\x3d\x22\x69\x6e\x70\x72\x6f\x67\x72\x65\x73\x73\x22\x26\x26\ \x66\x2e\x64\x65\x71\x75\x65\x75\x65\x28\x74\x68\x69\x73\x2c\x61\ \x29\x7d\x29\x7d\x2c\x64\x65\x71\x75\x65\x75\x65\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x29\x7b\x66\x2e\x64\x65\x71\x75\x65\x75\x65\x28\x74\ \x68\x69\x73\x2c\x61\x29\x7d\x29\x7d\x2c\x64\x65\x6c\x61\x79\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x61\x3d\ \x66\x2e\x66\x78\x3f\x66\x2e\x66\x78\x2e\x73\x70\x65\x65\x64\x73\ \x5b\x61\x5d\x7c\x7c\x61\x3a\x61\x2c\x62\x3d\x62\x7c\x7c\x22\x66\ \x78\x22\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x71\ \x75\x65\x75\x65\x28\x62\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x73\x65\x74\x54\x69\ \x6d\x65\x6f\x75\x74\x28\x62\x2c\x61\x29\x3b\x63\x2e\x73\x74\x6f\ \x70\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x63\x6c\x65\ \x61\x72\x54\x69\x6d\x65\x6f\x75\x74\x28\x64\x29\x7d\x7d\x29\x7d\ \x2c\x63\x6c\x65\x61\x72\x51\x75\x65\x75\x65\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x2e\x71\x75\x65\x75\x65\x28\x61\x7c\x7c\x22\x66\x78\ \x22\x2c\x5b\x5d\x29\x7d\x2c\x70\x72\x6f\x6d\x69\x73\x65\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x20\x6d\x28\x29\x7b\x2d\x2d\x68\x7c\x7c\x64\ \x2e\x72\x65\x73\x6f\x6c\x76\x65\x57\x69\x74\x68\x28\x65\x2c\x5b\ \x65\x5d\x29\x7d\x74\x79\x70\x65\x6f\x66\x20\x61\x21\x3d\x22\x73\ \x74\x72\x69\x6e\x67\x22\x26\x26\x28\x63\x3d\x61\x2c\x61\x3d\x62\ \x29\x2c\x61\x3d\x61\x7c\x7c\x22\x66\x78\x22\x3b\x76\x61\x72\x20\ \x64\x3d\x66\x2e\x44\x65\x66\x65\x72\x72\x65\x64\x28\x29\x2c\x65\ \x3d\x74\x68\x69\x73\x2c\x67\x3d\x65\x2e\x6c\x65\x6e\x67\x74\x68\ \x2c\x68\x3d\x31\x2c\x69\x3d\x61\x2b\x22\x64\x65\x66\x65\x72\x22\ \x2c\x6a\x3d\x61\x2b\x22\x71\x75\x65\x75\x65\x22\x2c\x6b\x3d\x61\ \x2b\x22\x6d\x61\x72\x6b\x22\x2c\x6c\x3b\x77\x68\x69\x6c\x65\x28\ \x67\x2d\x2d\x29\x69\x66\x28\x6c\x3d\x66\x2e\x64\x61\x74\x61\x28\ \x65\x5b\x67\x5d\x2c\x69\x2c\x62\x2c\x21\x30\x29\x7c\x7c\x28\x66\ \x2e\x64\x61\x74\x61\x28\x65\x5b\x67\x5d\x2c\x6a\x2c\x62\x2c\x21\ \x30\x29\x7c\x7c\x66\x2e\x64\x61\x74\x61\x28\x65\x5b\x67\x5d\x2c\ \x6b\x2c\x62\x2c\x21\x30\x29\x29\x26\x26\x66\x2e\x64\x61\x74\x61\ \x28\x65\x5b\x67\x5d\x2c\x69\x2c\x66\x2e\x43\x61\x6c\x6c\x62\x61\ \x63\x6b\x73\x28\x22\x6f\x6e\x63\x65\x20\x6d\x65\x6d\x6f\x72\x79\ \x22\x29\x2c\x21\x30\x29\x29\x68\x2b\x2b\x2c\x6c\x2e\x61\x64\x64\ \x28\x6d\x29\x3b\x6d\x28\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x64\ \x2e\x70\x72\x6f\x6d\x69\x73\x65\x28\x29\x7d\x7d\x29\x3b\x76\x61\ \x72\x20\x6f\x3d\x2f\x5b\x5c\x6e\x5c\x74\x5c\x72\x5d\x2f\x67\x2c\ \x70\x3d\x2f\x5c\x73\x2b\x2f\x2c\x71\x3d\x2f\x5c\x72\x2f\x67\x2c\ \x72\x3d\x2f\x5e\x28\x3f\x3a\x62\x75\x74\x74\x6f\x6e\x7c\x69\x6e\ \x70\x75\x74\x29\x24\x2f\x69\x2c\x73\x3d\x2f\x5e\x28\x3f\x3a\x62\ \x75\x74\x74\x6f\x6e\x7c\x69\x6e\x70\x75\x74\x7c\x6f\x62\x6a\x65\ \x63\x74\x7c\x73\x65\x6c\x65\x63\x74\x7c\x74\x65\x78\x74\x61\x72\ \x65\x61\x29\x24\x2f\x69\x2c\x74\x3d\x2f\x5e\x61\x28\x3f\x3a\x72\ \x65\x61\x29\x3f\x24\x2f\x69\x2c\x75\x3d\x2f\x5e\x28\x3f\x3a\x61\ \x75\x74\x6f\x66\x6f\x63\x75\x73\x7c\x61\x75\x74\x6f\x70\x6c\x61\ \x79\x7c\x61\x73\x79\x6e\x63\x7c\x63\x68\x65\x63\x6b\x65\x64\x7c\ \x63\x6f\x6e\x74\x72\x6f\x6c\x73\x7c\x64\x65\x66\x65\x72\x7c\x64\ \x69\x73\x61\x62\x6c\x65\x64\x7c\x68\x69\x64\x64\x65\x6e\x7c\x6c\ \x6f\x6f\x70\x7c\x6d\x75\x6c\x74\x69\x70\x6c\x65\x7c\x6f\x70\x65\ \x6e\x7c\x72\x65\x61\x64\x6f\x6e\x6c\x79\x7c\x72\x65\x71\x75\x69\ \x72\x65\x64\x7c\x73\x63\x6f\x70\x65\x64\x7c\x73\x65\x6c\x65\x63\ \x74\x65\x64\x29\x24\x2f\x69\x2c\x76\x3d\x66\x2e\x73\x75\x70\x70\ \x6f\x72\x74\x2e\x67\x65\x74\x53\x65\x74\x41\x74\x74\x72\x69\x62\ \x75\x74\x65\x2c\x77\x2c\x78\x2c\x79\x3b\x66\x2e\x66\x6e\x2e\x65\ \x78\x74\x65\x6e\x64\x28\x7b\x61\x74\x74\x72\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\ \x20\x66\x2e\x61\x63\x63\x65\x73\x73\x28\x74\x68\x69\x73\x2c\x61\ \x2c\x62\x2c\x21\x30\x2c\x66\x2e\x61\x74\x74\x72\x29\x7d\x2c\x72\ \x65\x6d\x6f\x76\x65\x41\x74\x74\x72\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x66\x2e\x72\x65\x6d\x6f\x76\x65\x41\x74\x74\x72\x28\x74\ \x68\x69\x73\x2c\x61\x29\x7d\x29\x7d\x2c\x70\x72\x6f\x70\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x66\x2e\x61\x63\x63\x65\x73\x73\x28\x74\x68\x69\ \x73\x2c\x61\x2c\x62\x2c\x21\x30\x2c\x66\x2e\x70\x72\x6f\x70\x29\ \x7d\x2c\x72\x65\x6d\x6f\x76\x65\x50\x72\x6f\x70\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x61\x3d\x66\x2e\x70\x72\x6f\ \x70\x46\x69\x78\x5b\x61\x5d\x7c\x7c\x61\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x29\x7b\x74\x72\x79\x7b\x74\x68\x69\x73\x5b\ \x61\x5d\x3d\x62\x2c\x64\x65\x6c\x65\x74\x65\x20\x74\x68\x69\x73\ \x5b\x61\x5d\x7d\x63\x61\x74\x63\x68\x28\x63\x29\x7b\x7d\x7d\x29\ \x7d\x2c\x61\x64\x64\x43\x6c\x61\x73\x73\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x2c\x63\x2c\x64\ \x2c\x65\x2c\x67\x2c\x68\x2c\x69\x3b\x69\x66\x28\x66\x2e\x69\x73\ \x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x29\x72\x65\x74\x75\ \x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x62\x29\x7b\x66\x28\x74\x68\x69\x73\x29\ \x2e\x61\x64\x64\x43\x6c\x61\x73\x73\x28\x61\x2e\x63\x61\x6c\x6c\ \x28\x74\x68\x69\x73\x2c\x62\x2c\x74\x68\x69\x73\x2e\x63\x6c\x61\ \x73\x73\x4e\x61\x6d\x65\x29\x29\x7d\x29\x3b\x69\x66\x28\x61\x26\ \x26\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x73\x74\x72\x69\ \x6e\x67\x22\x29\x7b\x62\x3d\x61\x2e\x73\x70\x6c\x69\x74\x28\x70\ \x29\x3b\x66\x6f\x72\x28\x63\x3d\x30\x2c\x64\x3d\x74\x68\x69\x73\ \x2e\x6c\x65\x6e\x67\x74\x68\x3b\x63\x3c\x64\x3b\x63\x2b\x2b\x29\ \x7b\x65\x3d\x74\x68\x69\x73\x5b\x63\x5d\x3b\x69\x66\x28\x65\x2e\ \x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\x69\x66\x28\ \x21\x65\x2e\x63\x6c\x61\x73\x73\x4e\x61\x6d\x65\x26\x26\x62\x2e\ \x6c\x65\x6e\x67\x74\x68\x3d\x3d\x3d\x31\x29\x65\x2e\x63\x6c\x61\ \x73\x73\x4e\x61\x6d\x65\x3d\x61\x3b\x65\x6c\x73\x65\x7b\x67\x3d\ \x22\x20\x22\x2b\x65\x2e\x63\x6c\x61\x73\x73\x4e\x61\x6d\x65\x2b\ \x22\x20\x22\x3b\x66\x6f\x72\x28\x68\x3d\x30\x2c\x69\x3d\x62\x2e\ \x6c\x65\x6e\x67\x74\x68\x3b\x68\x3c\x69\x3b\x68\x2b\x2b\x29\x7e\ \x67\x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x22\x20\x22\x2b\x62\x5b\ \x68\x5d\x2b\x22\x20\x22\x29\x7c\x7c\x28\x67\x2b\x3d\x62\x5b\x68\ \x5d\x2b\x22\x20\x22\x29\x3b\x65\x2e\x63\x6c\x61\x73\x73\x4e\x61\ \x6d\x65\x3d\x66\x2e\x74\x72\x69\x6d\x28\x67\x29\x7d\x7d\x7d\x72\ \x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x72\x65\x6d\x6f\ \x76\x65\x43\x6c\x61\x73\x73\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x76\x61\x72\x20\x63\x2c\x64\x2c\x65\x2c\x67\x2c\ \x68\x2c\x69\x2c\x6a\x3b\x69\x66\x28\x66\x2e\x69\x73\x46\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x29\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x62\x29\x7b\x66\x28\x74\x68\x69\x73\x29\x2e\x72\x65\ \x6d\x6f\x76\x65\x43\x6c\x61\x73\x73\x28\x61\x2e\x63\x61\x6c\x6c\ \x28\x74\x68\x69\x73\x2c\x62\x2c\x74\x68\x69\x73\x2e\x63\x6c\x61\ \x73\x73\x4e\x61\x6d\x65\x29\x29\x7d\x29\x3b\x69\x66\x28\x61\x26\ \x26\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x73\x74\x72\x69\ \x6e\x67\x22\x7c\x7c\x61\x3d\x3d\x3d\x62\x29\x7b\x63\x3d\x28\x61\ \x7c\x7c\x22\x22\x29\x2e\x73\x70\x6c\x69\x74\x28\x70\x29\x3b\x66\ \x6f\x72\x28\x64\x3d\x30\x2c\x65\x3d\x74\x68\x69\x73\x2e\x6c\x65\ \x6e\x67\x74\x68\x3b\x64\x3c\x65\x3b\x64\x2b\x2b\x29\x7b\x67\x3d\ \x74\x68\x69\x73\x5b\x64\x5d\x3b\x69\x66\x28\x67\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\x26\x67\x2e\x63\x6c\x61\ \x73\x73\x4e\x61\x6d\x65\x29\x69\x66\x28\x61\x29\x7b\x68\x3d\x28\ \x22\x20\x22\x2b\x67\x2e\x63\x6c\x61\x73\x73\x4e\x61\x6d\x65\x2b\ \x22\x20\x22\x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x6f\x2c\x22\ \x20\x22\x29\x3b\x66\x6f\x72\x28\x69\x3d\x30\x2c\x6a\x3d\x63\x2e\ \x6c\x65\x6e\x67\x74\x68\x3b\x69\x3c\x6a\x3b\x69\x2b\x2b\x29\x68\ \x3d\x68\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x22\x20\x22\x2b\x63\ \x5b\x69\x5d\x2b\x22\x20\x22\x2c\x22\x20\x22\x29\x3b\x67\x2e\x63\ \x6c\x61\x73\x73\x4e\x61\x6d\x65\x3d\x66\x2e\x74\x72\x69\x6d\x28\ \x68\x29\x7d\x65\x6c\x73\x65\x20\x67\x2e\x63\x6c\x61\x73\x73\x4e\ \x61\x6d\x65\x3d\x22\x22\x7d\x7d\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x7d\x2c\x74\x6f\x67\x67\x6c\x65\x43\x6c\x61\x73\x73\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\ \x61\x72\x20\x63\x3d\x74\x79\x70\x65\x6f\x66\x20\x61\x2c\x64\x3d\ \x74\x79\x70\x65\x6f\x66\x20\x62\x3d\x3d\x22\x62\x6f\x6f\x6c\x65\ \x61\x6e\x22\x3b\x69\x66\x28\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\ \x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x63\x29\x7b\x66\x28\x74\x68\x69\x73\x29\x2e\x74\x6f\x67\x67\ \x6c\x65\x43\x6c\x61\x73\x73\x28\x61\x2e\x63\x61\x6c\x6c\x28\x74\ \x68\x69\x73\x2c\x63\x2c\x74\x68\x69\x73\x2e\x63\x6c\x61\x73\x73\ \x4e\x61\x6d\x65\x2c\x62\x29\x2c\x62\x29\x7d\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x63\x3d\x3d\x3d\ \x22\x73\x74\x72\x69\x6e\x67\x22\x29\x7b\x76\x61\x72\x20\x65\x2c\ \x67\x3d\x30\x2c\x68\x3d\x66\x28\x74\x68\x69\x73\x29\x2c\x69\x3d\ \x62\x2c\x6a\x3d\x61\x2e\x73\x70\x6c\x69\x74\x28\x70\x29\x3b\x77\ \x68\x69\x6c\x65\x28\x65\x3d\x6a\x5b\x67\x2b\x2b\x5d\x29\x69\x3d\ \x64\x3f\x69\x3a\x21\x68\x2e\x68\x61\x73\x43\x6c\x61\x73\x73\x28\ \x65\x29\x2c\x68\x5b\x69\x3f\x22\x61\x64\x64\x43\x6c\x61\x73\x73\ \x22\x3a\x22\x72\x65\x6d\x6f\x76\x65\x43\x6c\x61\x73\x73\x22\x5d\ \x28\x65\x29\x7d\x65\x6c\x73\x65\x20\x69\x66\x28\x63\x3d\x3d\x3d\ \x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\x22\x7c\x7c\x63\x3d\x3d\ \x3d\x22\x62\x6f\x6f\x6c\x65\x61\x6e\x22\x29\x74\x68\x69\x73\x2e\ \x63\x6c\x61\x73\x73\x4e\x61\x6d\x65\x26\x26\x66\x2e\x5f\x64\x61\ \x74\x61\x28\x74\x68\x69\x73\x2c\x22\x5f\x5f\x63\x6c\x61\x73\x73\ \x4e\x61\x6d\x65\x5f\x5f\x22\x2c\x74\x68\x69\x73\x2e\x63\x6c\x61\ \x73\x73\x4e\x61\x6d\x65\x29\x2c\x74\x68\x69\x73\x2e\x63\x6c\x61\ \x73\x73\x4e\x61\x6d\x65\x3d\x74\x68\x69\x73\x2e\x63\x6c\x61\x73\ \x73\x4e\x61\x6d\x65\x7c\x7c\x61\x3d\x3d\x3d\x21\x31\x3f\x22\x22\ \x3a\x66\x2e\x5f\x64\x61\x74\x61\x28\x74\x68\x69\x73\x2c\x22\x5f\ \x5f\x63\x6c\x61\x73\x73\x4e\x61\x6d\x65\x5f\x5f\x22\x29\x7c\x7c\ \x22\x22\x7d\x29\x7d\x2c\x68\x61\x73\x43\x6c\x61\x73\x73\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\ \x3d\x22\x20\x22\x2b\x61\x2b\x22\x20\x22\x2c\x63\x3d\x30\x2c\x64\ \x3d\x74\x68\x69\x73\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x66\x6f\x72\ \x28\x3b\x63\x3c\x64\x3b\x63\x2b\x2b\x29\x69\x66\x28\x74\x68\x69\ \x73\x5b\x63\x5d\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\ \x31\x26\x26\x28\x22\x20\x22\x2b\x74\x68\x69\x73\x5b\x63\x5d\x2e\ \x63\x6c\x61\x73\x73\x4e\x61\x6d\x65\x2b\x22\x20\x22\x29\x2e\x72\ \x65\x70\x6c\x61\x63\x65\x28\x6f\x2c\x22\x20\x22\x29\x2e\x69\x6e\ \x64\x65\x78\x4f\x66\x28\x62\x29\x3e\x2d\x31\x29\x72\x65\x74\x75\ \x72\x6e\x21\x30\x3b\x72\x65\x74\x75\x72\x6e\x21\x31\x7d\x2c\x76\ \x61\x6c\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\ \x61\x72\x20\x63\x2c\x64\x2c\x65\x2c\x67\x3d\x74\x68\x69\x73\x5b\ \x30\x5d\x3b\x7b\x69\x66\x28\x21\x21\x61\x72\x67\x75\x6d\x65\x6e\ \x74\x73\x2e\x6c\x65\x6e\x67\x74\x68\x29\x7b\x65\x3d\x66\x2e\x69\ \x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x64\x29\x7b\x76\x61\x72\x20\x67\x3d\ \x66\x28\x74\x68\x69\x73\x29\x2c\x68\x3b\x69\x66\x28\x74\x68\x69\ \x73\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\x7b\ \x65\x3f\x68\x3d\x61\x2e\x63\x61\x6c\x6c\x28\x74\x68\x69\x73\x2c\ \x64\x2c\x67\x2e\x76\x61\x6c\x28\x29\x29\x3a\x68\x3d\x61\x2c\x68\ \x3d\x3d\x6e\x75\x6c\x6c\x3f\x68\x3d\x22\x22\x3a\x74\x79\x70\x65\ \x6f\x66\x20\x68\x3d\x3d\x22\x6e\x75\x6d\x62\x65\x72\x22\x3f\x68\ \x2b\x3d\x22\x22\x3a\x66\x2e\x69\x73\x41\x72\x72\x61\x79\x28\x68\ \x29\x26\x26\x28\x68\x3d\x66\x2e\x6d\x61\x70\x28\x68\x2c\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\ \x20\x61\x3d\x3d\x6e\x75\x6c\x6c\x3f\x22\x22\x3a\x61\x2b\x22\x22\ \x7d\x29\x29\x2c\x63\x3d\x66\x2e\x76\x61\x6c\x48\x6f\x6f\x6b\x73\ \x5b\x74\x68\x69\x73\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\ \x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x5d\x7c\x7c\x66\ \x2e\x76\x61\x6c\x48\x6f\x6f\x6b\x73\x5b\x74\x68\x69\x73\x2e\x74\ \x79\x70\x65\x5d\x3b\x69\x66\x28\x21\x63\x7c\x7c\x21\x28\x22\x73\ \x65\x74\x22\x69\x6e\x20\x63\x29\x7c\x7c\x63\x2e\x73\x65\x74\x28\ \x74\x68\x69\x73\x2c\x68\x2c\x22\x76\x61\x6c\x75\x65\x22\x29\x3d\ \x3d\x3d\x62\x29\x74\x68\x69\x73\x2e\x76\x61\x6c\x75\x65\x3d\x68\ \x7d\x7d\x29\x7d\x69\x66\x28\x67\x29\x7b\x63\x3d\x66\x2e\x76\x61\ \x6c\x48\x6f\x6f\x6b\x73\x5b\x67\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\ \x65\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x5d\ \x7c\x7c\x66\x2e\x76\x61\x6c\x48\x6f\x6f\x6b\x73\x5b\x67\x2e\x74\ \x79\x70\x65\x5d\x3b\x69\x66\x28\x63\x26\x26\x22\x67\x65\x74\x22\ \x69\x6e\x20\x63\x26\x26\x28\x64\x3d\x63\x2e\x67\x65\x74\x28\x67\ \x2c\x22\x76\x61\x6c\x75\x65\x22\x29\x29\x21\x3d\x3d\x62\x29\x72\ \x65\x74\x75\x72\x6e\x20\x64\x3b\x64\x3d\x67\x2e\x76\x61\x6c\x75\ \x65\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x79\x70\x65\x6f\x66\x20\ \x64\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x3f\x64\x2e\x72\x65\ \x70\x6c\x61\x63\x65\x28\x71\x2c\x22\x22\x29\x3a\x64\x3d\x3d\x6e\ \x75\x6c\x6c\x3f\x22\x22\x3a\x64\x7d\x7d\x7d\x7d\x29\x2c\x66\x2e\ \x65\x78\x74\x65\x6e\x64\x28\x7b\x76\x61\x6c\x48\x6f\x6f\x6b\x73\ \x3a\x7b\x6f\x70\x74\x69\x6f\x6e\x3a\x7b\x67\x65\x74\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x3d\ \x61\x2e\x61\x74\x74\x72\x69\x62\x75\x74\x65\x73\x2e\x76\x61\x6c\ \x75\x65\x3b\x72\x65\x74\x75\x72\x6e\x21\x62\x7c\x7c\x62\x2e\x73\ \x70\x65\x63\x69\x66\x69\x65\x64\x3f\x61\x2e\x76\x61\x6c\x75\x65\ \x3a\x61\x2e\x74\x65\x78\x74\x7d\x7d\x2c\x73\x65\x6c\x65\x63\x74\ \x3a\x7b\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x7b\x76\x61\x72\x20\x62\x2c\x63\x2c\x64\x2c\x65\x2c\x67\x3d\ \x61\x2e\x73\x65\x6c\x65\x63\x74\x65\x64\x49\x6e\x64\x65\x78\x2c\ \x68\x3d\x5b\x5d\x2c\x69\x3d\x61\x2e\x6f\x70\x74\x69\x6f\x6e\x73\ \x2c\x6a\x3d\x61\x2e\x74\x79\x70\x65\x3d\x3d\x3d\x22\x73\x65\x6c\ \x65\x63\x74\x2d\x6f\x6e\x65\x22\x3b\x69\x66\x28\x67\x3c\x30\x29\ \x72\x65\x74\x75\x72\x6e\x20\x6e\x75\x6c\x6c\x3b\x63\x3d\x6a\x3f\ \x67\x3a\x30\x2c\x64\x3d\x6a\x3f\x67\x2b\x31\x3a\x69\x2e\x6c\x65\ \x6e\x67\x74\x68\x3b\x66\x6f\x72\x28\x3b\x63\x3c\x64\x3b\x63\x2b\ \x2b\x29\x7b\x65\x3d\x69\x5b\x63\x5d\x3b\x69\x66\x28\x65\x2e\x73\ \x65\x6c\x65\x63\x74\x65\x64\x26\x26\x28\x66\x2e\x73\x75\x70\x70\ \x6f\x72\x74\x2e\x6f\x70\x74\x44\x69\x73\x61\x62\x6c\x65\x64\x3f\ \x21\x65\x2e\x64\x69\x73\x61\x62\x6c\x65\x64\x3a\x65\x2e\x67\x65\ \x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\x64\x69\x73\x61\ \x62\x6c\x65\x64\x22\x29\x3d\x3d\x3d\x6e\x75\x6c\x6c\x29\x26\x26\ \x28\x21\x65\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x2e\x64\ \x69\x73\x61\x62\x6c\x65\x64\x7c\x7c\x21\x66\x2e\x6e\x6f\x64\x65\ \x4e\x61\x6d\x65\x28\x65\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\ \x65\x2c\x22\x6f\x70\x74\x67\x72\x6f\x75\x70\x22\x29\x29\x29\x7b\ \x62\x3d\x66\x28\x65\x29\x2e\x76\x61\x6c\x28\x29\x3b\x69\x66\x28\ \x6a\x29\x72\x65\x74\x75\x72\x6e\x20\x62\x3b\x68\x2e\x70\x75\x73\ \x68\x28\x62\x29\x7d\x7d\x69\x66\x28\x6a\x26\x26\x21\x68\x2e\x6c\ \x65\x6e\x67\x74\x68\x26\x26\x69\x2e\x6c\x65\x6e\x67\x74\x68\x29\ \x72\x65\x74\x75\x72\x6e\x20\x66\x28\x69\x5b\x67\x5d\x29\x2e\x76\ \x61\x6c\x28\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x68\x7d\x2c\x73\ \x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\ \x7b\x76\x61\x72\x20\x63\x3d\x66\x2e\x6d\x61\x6b\x65\x41\x72\x72\ \x61\x79\x28\x62\x29\x3b\x66\x28\x61\x29\x2e\x66\x69\x6e\x64\x28\ \x22\x6f\x70\x74\x69\x6f\x6e\x22\x29\x2e\x65\x61\x63\x68\x28\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x74\x68\x69\x73\x2e\x73\ \x65\x6c\x65\x63\x74\x65\x64\x3d\x66\x2e\x69\x6e\x41\x72\x72\x61\ \x79\x28\x66\x28\x74\x68\x69\x73\x29\x2e\x76\x61\x6c\x28\x29\x2c\ \x63\x29\x3e\x3d\x30\x7d\x29\x2c\x63\x2e\x6c\x65\x6e\x67\x74\x68\ \x7c\x7c\x28\x61\x2e\x73\x65\x6c\x65\x63\x74\x65\x64\x49\x6e\x64\ \x65\x78\x3d\x2d\x31\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x63\x7d\ \x7d\x7d\x2c\x61\x74\x74\x72\x46\x6e\x3a\x7b\x76\x61\x6c\x3a\x21\ \x30\x2c\x63\x73\x73\x3a\x21\x30\x2c\x68\x74\x6d\x6c\x3a\x21\x30\ \x2c\x74\x65\x78\x74\x3a\x21\x30\x2c\x64\x61\x74\x61\x3a\x21\x30\ \x2c\x77\x69\x64\x74\x68\x3a\x21\x30\x2c\x68\x65\x69\x67\x68\x74\ \x3a\x21\x30\x2c\x6f\x66\x66\x73\x65\x74\x3a\x21\x30\x7d\x2c\x61\ \x74\x74\x72\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\ \x2c\x64\x2c\x65\x29\x7b\x76\x61\x72\x20\x67\x2c\x68\x2c\x69\x2c\ \x6a\x3d\x61\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3b\x69\x66\x28\ \x21\x21\x61\x26\x26\x6a\x21\x3d\x3d\x33\x26\x26\x6a\x21\x3d\x3d\ \x38\x26\x26\x6a\x21\x3d\x3d\x32\x29\x7b\x69\x66\x28\x65\x26\x26\ \x63\x20\x69\x6e\x20\x66\x2e\x61\x74\x74\x72\x46\x6e\x29\x72\x65\ \x74\x75\x72\x6e\x20\x66\x28\x61\x29\x5b\x63\x5d\x28\x64\x29\x3b\ \x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x61\x2e\x67\x65\x74\x41\ \x74\x74\x72\x69\x62\x75\x74\x65\x3d\x3d\x22\x75\x6e\x64\x65\x66\ \x69\x6e\x65\x64\x22\x29\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x70\ \x72\x6f\x70\x28\x61\x2c\x63\x2c\x64\x29\x3b\x69\x3d\x6a\x21\x3d\ \x3d\x31\x7c\x7c\x21\x66\x2e\x69\x73\x58\x4d\x4c\x44\x6f\x63\x28\ \x61\x29\x2c\x69\x26\x26\x28\x63\x3d\x63\x2e\x74\x6f\x4c\x6f\x77\ \x65\x72\x43\x61\x73\x65\x28\x29\x2c\x68\x3d\x66\x2e\x61\x74\x74\ \x72\x48\x6f\x6f\x6b\x73\x5b\x63\x5d\x7c\x7c\x28\x75\x2e\x74\x65\ \x73\x74\x28\x63\x29\x3f\x78\x3a\x77\x29\x29\x3b\x69\x66\x28\x64\ \x21\x3d\x3d\x62\x29\x7b\x69\x66\x28\x64\x3d\x3d\x3d\x6e\x75\x6c\ \x6c\x29\x7b\x66\x2e\x72\x65\x6d\x6f\x76\x65\x41\x74\x74\x72\x28\ \x61\x2c\x63\x29\x3b\x72\x65\x74\x75\x72\x6e\x7d\x69\x66\x28\x68\ \x26\x26\x22\x73\x65\x74\x22\x69\x6e\x20\x68\x26\x26\x69\x26\x26\ \x28\x67\x3d\x68\x2e\x73\x65\x74\x28\x61\x2c\x64\x2c\x63\x29\x29\ \x21\x3d\x3d\x62\x29\x72\x65\x74\x75\x72\x6e\x20\x67\x3b\x61\x2e\ \x73\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x63\x2c\x22\ \x22\x2b\x64\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x64\x7d\x69\x66\ \x28\x68\x26\x26\x22\x67\x65\x74\x22\x69\x6e\x20\x68\x26\x26\x69\ \x26\x26\x28\x67\x3d\x68\x2e\x67\x65\x74\x28\x61\x2c\x63\x29\x29\ \x21\x3d\x3d\x6e\x75\x6c\x6c\x29\x72\x65\x74\x75\x72\x6e\x20\x67\ \x3b\x67\x3d\x61\x2e\x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\ \x65\x28\x63\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x67\x3d\x3d\x3d\ \x6e\x75\x6c\x6c\x3f\x62\x3a\x67\x7d\x7d\x2c\x72\x65\x6d\x6f\x76\ \x65\x41\x74\x74\x72\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x2c\x64\x2c\x65\x2c\x67\x2c\ \x68\x3d\x30\x3b\x69\x66\x28\x62\x26\x26\x61\x2e\x6e\x6f\x64\x65\ \x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\x7b\x64\x3d\x62\x2e\x74\x6f\ \x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x2e\x73\x70\x6c\x69\ \x74\x28\x70\x29\x2c\x67\x3d\x64\x2e\x6c\x65\x6e\x67\x74\x68\x3b\ \x66\x6f\x72\x28\x3b\x68\x3c\x67\x3b\x68\x2b\x2b\x29\x65\x3d\x64\ \x5b\x68\x5d\x2c\x65\x26\x26\x28\x63\x3d\x66\x2e\x70\x72\x6f\x70\ \x46\x69\x78\x5b\x65\x5d\x7c\x7c\x65\x2c\x66\x2e\x61\x74\x74\x72\ \x28\x61\x2c\x65\x2c\x22\x22\x29\x2c\x61\x2e\x72\x65\x6d\x6f\x76\ \x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x76\x3f\x65\x3a\x63\ \x29\x2c\x75\x2e\x74\x65\x73\x74\x28\x65\x29\x26\x26\x63\x20\x69\ \x6e\x20\x61\x26\x26\x28\x61\x5b\x63\x5d\x3d\x21\x31\x29\x29\x7d\ \x7d\x2c\x61\x74\x74\x72\x48\x6f\x6f\x6b\x73\x3a\x7b\x74\x79\x70\ \x65\x3a\x7b\x73\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x62\x29\x7b\x69\x66\x28\x72\x2e\x74\x65\x73\x74\x28\x61\ \x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x26\x26\x61\x2e\x70\x61\ \x72\x65\x6e\x74\x4e\x6f\x64\x65\x29\x66\x2e\x65\x72\x72\x6f\x72\ \x28\x22\x74\x79\x70\x65\x20\x70\x72\x6f\x70\x65\x72\x74\x79\x20\ \x63\x61\x6e\x27\x74\x20\x62\x65\x20\x63\x68\x61\x6e\x67\x65\x64\ \x22\x29\x3b\x65\x6c\x73\x65\x20\x69\x66\x28\x21\x66\x2e\x73\x75\ \x70\x70\x6f\x72\x74\x2e\x72\x61\x64\x69\x6f\x56\x61\x6c\x75\x65\ \x26\x26\x62\x3d\x3d\x3d\x22\x72\x61\x64\x69\x6f\x22\x26\x26\x66\ \x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x28\x61\x2c\x22\x69\x6e\x70\ \x75\x74\x22\x29\x29\x7b\x76\x61\x72\x20\x63\x3d\x61\x2e\x76\x61\ \x6c\x75\x65\x3b\x61\x2e\x73\x65\x74\x41\x74\x74\x72\x69\x62\x75\ \x74\x65\x28\x22\x74\x79\x70\x65\x22\x2c\x62\x29\x2c\x63\x26\x26\ \x28\x61\x2e\x76\x61\x6c\x75\x65\x3d\x63\x29\x3b\x72\x65\x74\x75\ \x72\x6e\x20\x62\x7d\x7d\x7d\x2c\x76\x61\x6c\x75\x65\x3a\x7b\x67\ \x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\ \x7b\x69\x66\x28\x77\x26\x26\x66\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\ \x65\x28\x61\x2c\x22\x62\x75\x74\x74\x6f\x6e\x22\x29\x29\x72\x65\ \x74\x75\x72\x6e\x20\x77\x2e\x67\x65\x74\x28\x61\x2c\x62\x29\x3b\ \x72\x65\x74\x75\x72\x6e\x20\x62\x20\x69\x6e\x20\x61\x3f\x61\x2e\ \x76\x61\x6c\x75\x65\x3a\x6e\x75\x6c\x6c\x7d\x2c\x73\x65\x74\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\ \x69\x66\x28\x77\x26\x26\x66\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\ \x28\x61\x2c\x22\x62\x75\x74\x74\x6f\x6e\x22\x29\x29\x72\x65\x74\ \x75\x72\x6e\x20\x77\x2e\x73\x65\x74\x28\x61\x2c\x62\x2c\x63\x29\ \x3b\x61\x2e\x76\x61\x6c\x75\x65\x3d\x62\x7d\x7d\x7d\x2c\x70\x72\ \x6f\x70\x46\x69\x78\x3a\x7b\x74\x61\x62\x69\x6e\x64\x65\x78\x3a\ \x22\x74\x61\x62\x49\x6e\x64\x65\x78\x22\x2c\x72\x65\x61\x64\x6f\ \x6e\x6c\x79\x3a\x22\x72\x65\x61\x64\x4f\x6e\x6c\x79\x22\x2c\x22\ \x66\x6f\x72\x22\x3a\x22\x68\x74\x6d\x6c\x46\x6f\x72\x22\x2c\x22\ \x63\x6c\x61\x73\x73\x22\x3a\x22\x63\x6c\x61\x73\x73\x4e\x61\x6d\ \x65\x22\x2c\x6d\x61\x78\x6c\x65\x6e\x67\x74\x68\x3a\x22\x6d\x61\ \x78\x4c\x65\x6e\x67\x74\x68\x22\x2c\x63\x65\x6c\x6c\x73\x70\x61\ \x63\x69\x6e\x67\x3a\x22\x63\x65\x6c\x6c\x53\x70\x61\x63\x69\x6e\ \x67\x22\x2c\x63\x65\x6c\x6c\x70\x61\x64\x64\x69\x6e\x67\x3a\x22\ \x63\x65\x6c\x6c\x50\x61\x64\x64\x69\x6e\x67\x22\x2c\x72\x6f\x77\ \x73\x70\x61\x6e\x3a\x22\x72\x6f\x77\x53\x70\x61\x6e\x22\x2c\x63\ \x6f\x6c\x73\x70\x61\x6e\x3a\x22\x63\x6f\x6c\x53\x70\x61\x6e\x22\ \x2c\x75\x73\x65\x6d\x61\x70\x3a\x22\x75\x73\x65\x4d\x61\x70\x22\ \x2c\x66\x72\x61\x6d\x65\x62\x6f\x72\x64\x65\x72\x3a\x22\x66\x72\ \x61\x6d\x65\x42\x6f\x72\x64\x65\x72\x22\x2c\x63\x6f\x6e\x74\x65\ \x6e\x74\x65\x64\x69\x74\x61\x62\x6c\x65\x3a\x22\x63\x6f\x6e\x74\ \x65\x6e\x74\x45\x64\x69\x74\x61\x62\x6c\x65\x22\x7d\x2c\x70\x72\ \x6f\x70\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x2c\ \x64\x29\x7b\x76\x61\x72\x20\x65\x2c\x67\x2c\x68\x2c\x69\x3d\x61\ \x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3b\x69\x66\x28\x21\x21\x61\ \x26\x26\x69\x21\x3d\x3d\x33\x26\x26\x69\x21\x3d\x3d\x38\x26\x26\ \x69\x21\x3d\x3d\x32\x29\x7b\x68\x3d\x69\x21\x3d\x3d\x31\x7c\x7c\ \x21\x66\x2e\x69\x73\x58\x4d\x4c\x44\x6f\x63\x28\x61\x29\x2c\x68\ \x26\x26\x28\x63\x3d\x66\x2e\x70\x72\x6f\x70\x46\x69\x78\x5b\x63\ \x5d\x7c\x7c\x63\x2c\x67\x3d\x66\x2e\x70\x72\x6f\x70\x48\x6f\x6f\ \x6b\x73\x5b\x63\x5d\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x64\x21\ \x3d\x3d\x62\x3f\x67\x26\x26\x22\x73\x65\x74\x22\x69\x6e\x20\x67\ \x26\x26\x28\x65\x3d\x67\x2e\x73\x65\x74\x28\x61\x2c\x64\x2c\x63\ \x29\x29\x21\x3d\x3d\x62\x3f\x65\x3a\x61\x5b\x63\x5d\x3d\x64\x3a\ \x67\x26\x26\x22\x67\x65\x74\x22\x69\x6e\x20\x67\x26\x26\x28\x65\ \x3d\x67\x2e\x67\x65\x74\x28\x61\x2c\x63\x29\x29\x21\x3d\x3d\x6e\ \x75\x6c\x6c\x3f\x65\x3a\x61\x5b\x63\x5d\x7d\x7d\x2c\x70\x72\x6f\ \x70\x48\x6f\x6f\x6b\x73\x3a\x7b\x74\x61\x62\x49\x6e\x64\x65\x78\ \x3a\x7b\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x7b\x76\x61\x72\x20\x63\x3d\x61\x2e\x67\x65\x74\x41\x74\x74\ \x72\x69\x62\x75\x74\x65\x4e\x6f\x64\x65\x28\x22\x74\x61\x62\x69\ \x6e\x64\x65\x78\x22\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x63\x26\ \x26\x63\x2e\x73\x70\x65\x63\x69\x66\x69\x65\x64\x3f\x70\x61\x72\ \x73\x65\x49\x6e\x74\x28\x63\x2e\x76\x61\x6c\x75\x65\x2c\x31\x30\ \x29\x3a\x73\x2e\x74\x65\x73\x74\x28\x61\x2e\x6e\x6f\x64\x65\x4e\ \x61\x6d\x65\x29\x7c\x7c\x74\x2e\x74\x65\x73\x74\x28\x61\x2e\x6e\ \x6f\x64\x65\x4e\x61\x6d\x65\x29\x26\x26\x61\x2e\x68\x72\x65\x66\ \x3f\x30\x3a\x62\x7d\x7d\x7d\x7d\x29\x2c\x66\x2e\x61\x74\x74\x72\ \x48\x6f\x6f\x6b\x73\x2e\x74\x61\x62\x69\x6e\x64\x65\x78\x3d\x66\ \x2e\x70\x72\x6f\x70\x48\x6f\x6f\x6b\x73\x2e\x74\x61\x62\x49\x6e\ \x64\x65\x78\x2c\x78\x3d\x7b\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x2c\x65\ \x3d\x66\x2e\x70\x72\x6f\x70\x28\x61\x2c\x63\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x65\x3d\x3d\x3d\x21\x30\x7c\x7c\x74\x79\x70\x65\ \x6f\x66\x20\x65\x21\x3d\x22\x62\x6f\x6f\x6c\x65\x61\x6e\x22\x26\ \x26\x28\x64\x3d\x61\x2e\x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\ \x74\x65\x4e\x6f\x64\x65\x28\x63\x29\x29\x26\x26\x64\x2e\x6e\x6f\ \x64\x65\x56\x61\x6c\x75\x65\x21\x3d\x3d\x21\x31\x3f\x63\x2e\x74\ \x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3a\x62\x7d\x2c\ \x73\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\ \x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3b\x62\x3d\x3d\x3d\x21\x31\ \x3f\x66\x2e\x72\x65\x6d\x6f\x76\x65\x41\x74\x74\x72\x28\x61\x2c\ \x63\x29\x3a\x28\x64\x3d\x66\x2e\x70\x72\x6f\x70\x46\x69\x78\x5b\ \x63\x5d\x7c\x7c\x63\x2c\x64\x20\x69\x6e\x20\x61\x26\x26\x28\x61\ \x5b\x64\x5d\x3d\x21\x30\x29\x2c\x61\x2e\x73\x65\x74\x41\x74\x74\ \x72\x69\x62\x75\x74\x65\x28\x63\x2c\x63\x2e\x74\x6f\x4c\x6f\x77\ \x65\x72\x43\x61\x73\x65\x28\x29\x29\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x63\x7d\x7d\x2c\x76\x7c\x7c\x28\x79\x3d\x7b\x6e\x61\x6d\ \x65\x3a\x21\x30\x2c\x69\x64\x3a\x21\x30\x7d\x2c\x77\x3d\x66\x2e\ \x76\x61\x6c\x48\x6f\x6f\x6b\x73\x2e\x62\x75\x74\x74\x6f\x6e\x3d\ \x7b\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x63\x29\x7b\x76\x61\x72\x20\x64\x3b\x64\x3d\x61\x2e\x67\x65\x74\ \x41\x74\x74\x72\x69\x62\x75\x74\x65\x4e\x6f\x64\x65\x28\x63\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x64\x26\x26\x28\x79\x5b\x63\x5d\ \x3f\x64\x2e\x6e\x6f\x64\x65\x56\x61\x6c\x75\x65\x21\x3d\x3d\x22\ \x22\x3a\x64\x2e\x73\x70\x65\x63\x69\x66\x69\x65\x64\x29\x3f\x64\ \x2e\x6e\x6f\x64\x65\x56\x61\x6c\x75\x65\x3a\x62\x7d\x2c\x73\x65\ \x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x64\ \x29\x7b\x76\x61\x72\x20\x65\x3d\x61\x2e\x67\x65\x74\x41\x74\x74\ \x72\x69\x62\x75\x74\x65\x4e\x6f\x64\x65\x28\x64\x29\x3b\x65\x7c\ \x7c\x28\x65\x3d\x63\x2e\x63\x72\x65\x61\x74\x65\x41\x74\x74\x72\ \x69\x62\x75\x74\x65\x28\x64\x29\x2c\x61\x2e\x73\x65\x74\x41\x74\ \x74\x72\x69\x62\x75\x74\x65\x4e\x6f\x64\x65\x28\x65\x29\x29\x3b\ \x72\x65\x74\x75\x72\x6e\x20\x65\x2e\x6e\x6f\x64\x65\x56\x61\x6c\ \x75\x65\x3d\x62\x2b\x22\x22\x7d\x7d\x2c\x66\x2e\x61\x74\x74\x72\ \x48\x6f\x6f\x6b\x73\x2e\x74\x61\x62\x69\x6e\x64\x65\x78\x2e\x73\ \x65\x74\x3d\x77\x2e\x73\x65\x74\x2c\x66\x2e\x65\x61\x63\x68\x28\ \x5b\x22\x77\x69\x64\x74\x68\x22\x2c\x22\x68\x65\x69\x67\x68\x74\ \x22\x5d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\ \x7b\x66\x2e\x61\x74\x74\x72\x48\x6f\x6f\x6b\x73\x5b\x62\x5d\x3d\ \x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x66\x2e\x61\x74\x74\x72\x48\ \x6f\x6f\x6b\x73\x5b\x62\x5d\x2c\x7b\x73\x65\x74\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x69\x66\x28\x63\x3d\ \x3d\x3d\x22\x22\x29\x7b\x61\x2e\x73\x65\x74\x41\x74\x74\x72\x69\ \x62\x75\x74\x65\x28\x62\x2c\x22\x61\x75\x74\x6f\x22\x29\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x63\x7d\x7d\x7d\x29\x7d\x29\x2c\x66\x2e\ \x61\x74\x74\x72\x48\x6f\x6f\x6b\x73\x2e\x63\x6f\x6e\x74\x65\x6e\ \x74\x65\x64\x69\x74\x61\x62\x6c\x65\x3d\x7b\x67\x65\x74\x3a\x77\ \x2e\x67\x65\x74\x2c\x73\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x62\x3d\x3d\x3d\x22\x22\x26\ \x26\x28\x62\x3d\x22\x66\x61\x6c\x73\x65\x22\x29\x2c\x77\x2e\x73\ \x65\x74\x28\x61\x2c\x62\x2c\x63\x29\x7d\x7d\x29\x2c\x66\x2e\x73\ \x75\x70\x70\x6f\x72\x74\x2e\x68\x72\x65\x66\x4e\x6f\x72\x6d\x61\ \x6c\x69\x7a\x65\x64\x7c\x7c\x66\x2e\x65\x61\x63\x68\x28\x5b\x22\ \x68\x72\x65\x66\x22\x2c\x22\x73\x72\x63\x22\x2c\x22\x77\x69\x64\ \x74\x68\x22\x2c\x22\x68\x65\x69\x67\x68\x74\x22\x5d\x2c\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x66\x2e\x61\x74\ \x74\x72\x48\x6f\x6f\x6b\x73\x5b\x63\x5d\x3d\x66\x2e\x65\x78\x74\ \x65\x6e\x64\x28\x66\x2e\x61\x74\x74\x72\x48\x6f\x6f\x6b\x73\x5b\ \x63\x5d\x2c\x7b\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x76\x61\x72\x20\x64\x3d\x61\x2e\x67\x65\x74\x41\ \x74\x74\x72\x69\x62\x75\x74\x65\x28\x63\x2c\x32\x29\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x64\x3d\x3d\x3d\x6e\x75\x6c\x6c\x3f\x62\x3a\ \x64\x7d\x7d\x29\x7d\x29\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\ \x2e\x73\x74\x79\x6c\x65\x7c\x7c\x28\x66\x2e\x61\x74\x74\x72\x48\ \x6f\x6f\x6b\x73\x2e\x73\x74\x79\x6c\x65\x3d\x7b\x67\x65\x74\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x61\x2e\x73\x74\x79\x6c\x65\x2e\x63\x73\x73\x54\x65\ \x78\x74\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\ \x7c\x7c\x62\x7d\x2c\x73\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\ \x73\x74\x79\x6c\x65\x2e\x63\x73\x73\x54\x65\x78\x74\x3d\x22\x22\ \x2b\x62\x7d\x7d\x29\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\ \x6f\x70\x74\x53\x65\x6c\x65\x63\x74\x65\x64\x7c\x7c\x28\x66\x2e\ \x70\x72\x6f\x70\x48\x6f\x6f\x6b\x73\x2e\x73\x65\x6c\x65\x63\x74\ \x65\x64\x3d\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x66\x2e\x70\x72\ \x6f\x70\x48\x6f\x6f\x6b\x73\x2e\x73\x65\x6c\x65\x63\x74\x65\x64\ \x2c\x7b\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x7b\x76\x61\x72\x20\x62\x3d\x61\x2e\x70\x61\x72\x65\x6e\x74\ \x4e\x6f\x64\x65\x3b\x62\x26\x26\x28\x62\x2e\x73\x65\x6c\x65\x63\ \x74\x65\x64\x49\x6e\x64\x65\x78\x2c\x62\x2e\x70\x61\x72\x65\x6e\ \x74\x4e\x6f\x64\x65\x26\x26\x62\x2e\x70\x61\x72\x65\x6e\x74\x4e\ \x6f\x64\x65\x2e\x73\x65\x6c\x65\x63\x74\x65\x64\x49\x6e\x64\x65\ \x78\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x6e\x75\x6c\x6c\x7d\x7d\ \x29\x29\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x65\x6e\x63\ \x74\x79\x70\x65\x7c\x7c\x28\x66\x2e\x70\x72\x6f\x70\x46\x69\x78\ \x2e\x65\x6e\x63\x74\x79\x70\x65\x3d\x22\x65\x6e\x63\x6f\x64\x69\ \x6e\x67\x22\x29\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x63\ \x68\x65\x63\x6b\x4f\x6e\x7c\x7c\x66\x2e\x65\x61\x63\x68\x28\x5b\ \x22\x72\x61\x64\x69\x6f\x22\x2c\x22\x63\x68\x65\x63\x6b\x62\x6f\ \x78\x22\x5d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\ \x2e\x76\x61\x6c\x48\x6f\x6f\x6b\x73\x5b\x74\x68\x69\x73\x5d\x3d\ \x7b\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x67\x65\x74\x41\x74\x74\ \x72\x69\x62\x75\x74\x65\x28\x22\x76\x61\x6c\x75\x65\x22\x29\x3d\ \x3d\x3d\x6e\x75\x6c\x6c\x3f\x22\x6f\x6e\x22\x3a\x61\x2e\x76\x61\ \x6c\x75\x65\x7d\x7d\x7d\x29\x2c\x66\x2e\x65\x61\x63\x68\x28\x5b\ \x22\x72\x61\x64\x69\x6f\x22\x2c\x22\x63\x68\x65\x63\x6b\x62\x6f\ \x78\x22\x5d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\ \x2e\x76\x61\x6c\x48\x6f\x6f\x6b\x73\x5b\x74\x68\x69\x73\x5d\x3d\ \x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x66\x2e\x76\x61\x6c\x48\x6f\ \x6f\x6b\x73\x5b\x74\x68\x69\x73\x5d\x2c\x7b\x73\x65\x74\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x69\x66\x28\ \x66\x2e\x69\x73\x41\x72\x72\x61\x79\x28\x62\x29\x29\x72\x65\x74\ \x75\x72\x6e\x20\x61\x2e\x63\x68\x65\x63\x6b\x65\x64\x3d\x66\x2e\ \x69\x6e\x41\x72\x72\x61\x79\x28\x66\x28\x61\x29\x2e\x76\x61\x6c\ \x28\x29\x2c\x62\x29\x3e\x3d\x30\x7d\x7d\x29\x7d\x29\x3b\x76\x61\ \x72\x20\x7a\x3d\x2f\x5e\x28\x3f\x3a\x74\x65\x78\x74\x61\x72\x65\ \x61\x7c\x69\x6e\x70\x75\x74\x7c\x73\x65\x6c\x65\x63\x74\x29\x24\ \x2f\x69\x2c\x41\x3d\x2f\x5e\x28\x5b\x5e\x5c\x2e\x5d\x2a\x29\x3f\ \x28\x3f\x3a\x5c\x2e\x28\x2e\x2b\x29\x29\x3f\x24\x2f\x2c\x42\x3d\ \x2f\x5c\x62\x68\x6f\x76\x65\x72\x28\x5c\x2e\x5c\x53\x2b\x29\x3f\ \x5c\x62\x2f\x2c\x43\x3d\x2f\x5e\x6b\x65\x79\x2f\x2c\x44\x3d\x2f\ \x5e\x28\x3f\x3a\x6d\x6f\x75\x73\x65\x7c\x63\x6f\x6e\x74\x65\x78\ \x74\x6d\x65\x6e\x75\x29\x7c\x63\x6c\x69\x63\x6b\x2f\x2c\x45\x3d\ \x2f\x5e\x28\x3f\x3a\x66\x6f\x63\x75\x73\x69\x6e\x66\x6f\x63\x75\ \x73\x7c\x66\x6f\x63\x75\x73\x6f\x75\x74\x62\x6c\x75\x72\x29\x24\ \x2f\x2c\x46\x3d\x2f\x5e\x28\x5c\x77\x2a\x29\x28\x3f\x3a\x23\x28\ \x5b\x5c\x77\x5c\x2d\x5d\x2b\x29\x29\x3f\x28\x3f\x3a\x5c\x2e\x28\ \x5b\x5c\x77\x5c\x2d\x5d\x2b\x29\x29\x3f\x24\x2f\x2c\x47\x3d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\ \x3d\x46\x2e\x65\x78\x65\x63\x28\x61\x29\x3b\x62\x26\x26\x28\x62\ \x5b\x31\x5d\x3d\x28\x62\x5b\x31\x5d\x7c\x7c\x22\x22\x29\x2e\x74\ \x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x2c\x62\x5b\x33\ \x5d\x3d\x62\x5b\x33\x5d\x26\x26\x6e\x65\x77\x20\x52\x65\x67\x45\ \x78\x70\x28\x22\x28\x3f\x3a\x5e\x7c\x5c\x5c\x73\x29\x22\x2b\x62\ \x5b\x33\x5d\x2b\x22\x28\x3f\x3a\x5c\x5c\x73\x7c\x24\x29\x22\x29\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x62\x7d\x2c\x48\x3d\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\ \x63\x3d\x61\x2e\x61\x74\x74\x72\x69\x62\x75\x74\x65\x73\x7c\x7c\ \x7b\x7d\x3b\x72\x65\x74\x75\x72\x6e\x28\x21\x62\x5b\x31\x5d\x7c\ \x7c\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\ \x77\x65\x72\x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\x62\x5b\x31\x5d\ \x29\x26\x26\x28\x21\x62\x5b\x32\x5d\x7c\x7c\x28\x63\x2e\x69\x64\ \x7c\x7c\x7b\x7d\x29\x2e\x76\x61\x6c\x75\x65\x3d\x3d\x3d\x62\x5b\ \x32\x5d\x29\x26\x26\x28\x21\x62\x5b\x33\x5d\x7c\x7c\x62\x5b\x33\ \x5d\x2e\x74\x65\x73\x74\x28\x28\x63\x5b\x22\x63\x6c\x61\x73\x73\ \x22\x5d\x7c\x7c\x7b\x7d\x29\x2e\x76\x61\x6c\x75\x65\x29\x29\x7d\ \x2c\x49\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\ \x65\x74\x75\x72\x6e\x20\x66\x2e\x65\x76\x65\x6e\x74\x2e\x73\x70\ \x65\x63\x69\x61\x6c\x2e\x68\x6f\x76\x65\x72\x3f\x61\x3a\x61\x2e\ \x72\x65\x70\x6c\x61\x63\x65\x28\x42\x2c\x22\x6d\x6f\x75\x73\x65\ \x65\x6e\x74\x65\x72\x24\x31\x20\x6d\x6f\x75\x73\x65\x6c\x65\x61\ \x76\x65\x24\x31\x22\x29\x7d\x3b\x0a\x66\x2e\x65\x76\x65\x6e\x74\ \x3d\x7b\x61\x64\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x63\x2c\x64\x2c\x65\x2c\x67\x29\x7b\x76\x61\x72\x20\x68\x2c\ \x69\x2c\x6a\x2c\x6b\x2c\x6c\x2c\x6d\x2c\x6e\x2c\x6f\x2c\x70\x2c\ \x71\x2c\x72\x2c\x73\x3b\x69\x66\x28\x21\x28\x61\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x3d\x3d\x3d\x33\x7c\x7c\x61\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x3d\x3d\x3d\x38\x7c\x7c\x21\x63\x7c\x7c\x21\ \x64\x7c\x7c\x21\x28\x68\x3d\x66\x2e\x5f\x64\x61\x74\x61\x28\x61\ \x29\x29\x29\x29\x7b\x64\x2e\x68\x61\x6e\x64\x6c\x65\x72\x26\x26\ \x28\x70\x3d\x64\x2c\x64\x3d\x70\x2e\x68\x61\x6e\x64\x6c\x65\x72\ \x29\x2c\x64\x2e\x67\x75\x69\x64\x7c\x7c\x28\x64\x2e\x67\x75\x69\ \x64\x3d\x66\x2e\x67\x75\x69\x64\x2b\x2b\x29\x2c\x6a\x3d\x68\x2e\ \x65\x76\x65\x6e\x74\x73\x2c\x6a\x7c\x7c\x28\x68\x2e\x65\x76\x65\ \x6e\x74\x73\x3d\x6a\x3d\x7b\x7d\x29\x2c\x69\x3d\x68\x2e\x68\x61\ \x6e\x64\x6c\x65\x2c\x69\x7c\x7c\x28\x68\x2e\x68\x61\x6e\x64\x6c\ \x65\x3d\x69\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\ \x72\x65\x74\x75\x72\x6e\x20\x74\x79\x70\x65\x6f\x66\x20\x66\x21\ \x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\x22\x26\x26\x28\x21\ \x61\x7c\x7c\x66\x2e\x65\x76\x65\x6e\x74\x2e\x74\x72\x69\x67\x67\ \x65\x72\x65\x64\x21\x3d\x3d\x61\x2e\x74\x79\x70\x65\x29\x3f\x66\ \x2e\x65\x76\x65\x6e\x74\x2e\x64\x69\x73\x70\x61\x74\x63\x68\x2e\ \x61\x70\x70\x6c\x79\x28\x69\x2e\x65\x6c\x65\x6d\x2c\x61\x72\x67\ \x75\x6d\x65\x6e\x74\x73\x29\x3a\x62\x7d\x2c\x69\x2e\x65\x6c\x65\ \x6d\x3d\x61\x29\x2c\x63\x3d\x66\x2e\x74\x72\x69\x6d\x28\x49\x28\ \x63\x29\x29\x2e\x73\x70\x6c\x69\x74\x28\x22\x20\x22\x29\x3b\x66\ \x6f\x72\x28\x6b\x3d\x30\x3b\x6b\x3c\x63\x2e\x6c\x65\x6e\x67\x74\ \x68\x3b\x6b\x2b\x2b\x29\x7b\x6c\x3d\x41\x2e\x65\x78\x65\x63\x28\ \x63\x5b\x6b\x5d\x29\x7c\x7c\x5b\x5d\x2c\x6d\x3d\x6c\x5b\x31\x5d\ \x2c\x6e\x3d\x28\x6c\x5b\x32\x5d\x7c\x7c\x22\x22\x29\x2e\x73\x70\ \x6c\x69\x74\x28\x22\x2e\x22\x29\x2e\x73\x6f\x72\x74\x28\x29\x2c\ \x73\x3d\x66\x2e\x65\x76\x65\x6e\x74\x2e\x73\x70\x65\x63\x69\x61\ \x6c\x5b\x6d\x5d\x7c\x7c\x7b\x7d\x2c\x6d\x3d\x28\x67\x3f\x73\x2e\ \x64\x65\x6c\x65\x67\x61\x74\x65\x54\x79\x70\x65\x3a\x73\x2e\x62\ \x69\x6e\x64\x54\x79\x70\x65\x29\x7c\x7c\x6d\x2c\x73\x3d\x66\x2e\ \x65\x76\x65\x6e\x74\x2e\x73\x70\x65\x63\x69\x61\x6c\x5b\x6d\x5d\ \x7c\x7c\x7b\x7d\x2c\x6f\x3d\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\ \x7b\x74\x79\x70\x65\x3a\x6d\x2c\x6f\x72\x69\x67\x54\x79\x70\x65\ \x3a\x6c\x5b\x31\x5d\x2c\x64\x61\x74\x61\x3a\x65\x2c\x68\x61\x6e\ \x64\x6c\x65\x72\x3a\x64\x2c\x67\x75\x69\x64\x3a\x64\x2e\x67\x75\ \x69\x64\x2c\x73\x65\x6c\x65\x63\x74\x6f\x72\x3a\x67\x2c\x71\x75\ \x69\x63\x6b\x3a\x47\x28\x67\x29\x2c\x6e\x61\x6d\x65\x73\x70\x61\ \x63\x65\x3a\x6e\x2e\x6a\x6f\x69\x6e\x28\x22\x2e\x22\x29\x7d\x2c\ \x70\x29\x2c\x72\x3d\x6a\x5b\x6d\x5d\x3b\x69\x66\x28\x21\x72\x29\ \x7b\x72\x3d\x6a\x5b\x6d\x5d\x3d\x5b\x5d\x2c\x72\x2e\x64\x65\x6c\ \x65\x67\x61\x74\x65\x43\x6f\x75\x6e\x74\x3d\x30\x3b\x69\x66\x28\ \x21\x73\x2e\x73\x65\x74\x75\x70\x7c\x7c\x73\x2e\x73\x65\x74\x75\ \x70\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x65\x2c\x6e\x2c\x69\x29\x3d\ \x3d\x3d\x21\x31\x29\x61\x2e\x61\x64\x64\x45\x76\x65\x6e\x74\x4c\ \x69\x73\x74\x65\x6e\x65\x72\x3f\x61\x2e\x61\x64\x64\x45\x76\x65\ \x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72\x28\x6d\x2c\x69\x2c\x21\ \x31\x29\x3a\x61\x2e\x61\x74\x74\x61\x63\x68\x45\x76\x65\x6e\x74\ \x26\x26\x61\x2e\x61\x74\x74\x61\x63\x68\x45\x76\x65\x6e\x74\x28\ \x22\x6f\x6e\x22\x2b\x6d\x2c\x69\x29\x7d\x73\x2e\x61\x64\x64\x26\ \x26\x28\x73\x2e\x61\x64\x64\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x6f\ \x29\x2c\x6f\x2e\x68\x61\x6e\x64\x6c\x65\x72\x2e\x67\x75\x69\x64\ \x7c\x7c\x28\x6f\x2e\x68\x61\x6e\x64\x6c\x65\x72\x2e\x67\x75\x69\ \x64\x3d\x64\x2e\x67\x75\x69\x64\x29\x29\x2c\x67\x3f\x72\x2e\x73\ \x70\x6c\x69\x63\x65\x28\x72\x2e\x64\x65\x6c\x65\x67\x61\x74\x65\ \x43\x6f\x75\x6e\x74\x2b\x2b\x2c\x30\x2c\x6f\x29\x3a\x72\x2e\x70\ \x75\x73\x68\x28\x6f\x29\x2c\x66\x2e\x65\x76\x65\x6e\x74\x2e\x67\ \x6c\x6f\x62\x61\x6c\x5b\x6d\x5d\x3d\x21\x30\x7d\x61\x3d\x6e\x75\ \x6c\x6c\x7d\x7d\x2c\x67\x6c\x6f\x62\x61\x6c\x3a\x7b\x7d\x2c\x72\ \x65\x6d\x6f\x76\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x62\x2c\x63\x2c\x64\x2c\x65\x29\x7b\x76\x61\x72\x20\x67\x3d\ \x66\x2e\x68\x61\x73\x44\x61\x74\x61\x28\x61\x29\x26\x26\x66\x2e\ \x5f\x64\x61\x74\x61\x28\x61\x29\x2c\x68\x2c\x69\x2c\x6a\x2c\x6b\ \x2c\x6c\x2c\x6d\x2c\x6e\x2c\x6f\x2c\x70\x2c\x71\x2c\x72\x2c\x73\ \x3b\x69\x66\x28\x21\x21\x67\x26\x26\x21\x21\x28\x6f\x3d\x67\x2e\ \x65\x76\x65\x6e\x74\x73\x29\x29\x7b\x62\x3d\x66\x2e\x74\x72\x69\ \x6d\x28\x49\x28\x62\x7c\x7c\x22\x22\x29\x29\x2e\x73\x70\x6c\x69\ \x74\x28\x22\x20\x22\x29\x3b\x66\x6f\x72\x28\x68\x3d\x30\x3b\x68\ \x3c\x62\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x68\x2b\x2b\x29\x7b\x69\ \x3d\x41\x2e\x65\x78\x65\x63\x28\x62\x5b\x68\x5d\x29\x7c\x7c\x5b\ \x5d\x2c\x6a\x3d\x6b\x3d\x69\x5b\x31\x5d\x2c\x6c\x3d\x69\x5b\x32\ \x5d\x3b\x69\x66\x28\x21\x6a\x29\x7b\x66\x6f\x72\x28\x6a\x20\x69\ \x6e\x20\x6f\x29\x66\x2e\x65\x76\x65\x6e\x74\x2e\x72\x65\x6d\x6f\ \x76\x65\x28\x61\x2c\x6a\x2b\x62\x5b\x68\x5d\x2c\x63\x2c\x64\x2c\ \x21\x30\x29\x3b\x63\x6f\x6e\x74\x69\x6e\x75\x65\x7d\x70\x3d\x66\ \x2e\x65\x76\x65\x6e\x74\x2e\x73\x70\x65\x63\x69\x61\x6c\x5b\x6a\ \x5d\x7c\x7c\x7b\x7d\x2c\x6a\x3d\x28\x64\x3f\x70\x2e\x64\x65\x6c\ \x65\x67\x61\x74\x65\x54\x79\x70\x65\x3a\x70\x2e\x62\x69\x6e\x64\ \x54\x79\x70\x65\x29\x7c\x7c\x6a\x2c\x72\x3d\x6f\x5b\x6a\x5d\x7c\ \x7c\x5b\x5d\x2c\x6d\x3d\x72\x2e\x6c\x65\x6e\x67\x74\x68\x2c\x6c\ \x3d\x6c\x3f\x6e\x65\x77\x20\x52\x65\x67\x45\x78\x70\x28\x22\x28\ \x5e\x7c\x5c\x5c\x2e\x29\x22\x2b\x6c\x2e\x73\x70\x6c\x69\x74\x28\ \x22\x2e\x22\x29\x2e\x73\x6f\x72\x74\x28\x29\x2e\x6a\x6f\x69\x6e\ \x28\x22\x5c\x5c\x2e\x28\x3f\x3a\x2e\x2a\x5c\x5c\x2e\x29\x3f\x22\ \x29\x2b\x22\x28\x5c\x5c\x2e\x7c\x24\x29\x22\x29\x3a\x6e\x75\x6c\ \x6c\x3b\x66\x6f\x72\x28\x6e\x3d\x30\x3b\x6e\x3c\x72\x2e\x6c\x65\ \x6e\x67\x74\x68\x3b\x6e\x2b\x2b\x29\x73\x3d\x72\x5b\x6e\x5d\x2c\ \x28\x65\x7c\x7c\x6b\x3d\x3d\x3d\x73\x2e\x6f\x72\x69\x67\x54\x79\ \x70\x65\x29\x26\x26\x28\x21\x63\x7c\x7c\x63\x2e\x67\x75\x69\x64\ \x3d\x3d\x3d\x73\x2e\x67\x75\x69\x64\x29\x26\x26\x28\x21\x6c\x7c\ \x7c\x6c\x2e\x74\x65\x73\x74\x28\x73\x2e\x6e\x61\x6d\x65\x73\x70\ \x61\x63\x65\x29\x29\x26\x26\x28\x21\x64\x7c\x7c\x64\x3d\x3d\x3d\ \x73\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x7c\x7c\x64\x3d\x3d\x3d\ \x22\x2a\x2a\x22\x26\x26\x73\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\ \x29\x26\x26\x28\x72\x2e\x73\x70\x6c\x69\x63\x65\x28\x6e\x2d\x2d\ \x2c\x31\x29\x2c\x73\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x26\x26\ \x72\x2e\x64\x65\x6c\x65\x67\x61\x74\x65\x43\x6f\x75\x6e\x74\x2d\ \x2d\x2c\x70\x2e\x72\x65\x6d\x6f\x76\x65\x26\x26\x70\x2e\x72\x65\ \x6d\x6f\x76\x65\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x73\x29\x29\x3b\ \x72\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x3d\x3d\x30\x26\x26\x6d\x21\ \x3d\x3d\x72\x2e\x6c\x65\x6e\x67\x74\x68\x26\x26\x28\x28\x21\x70\ \x2e\x74\x65\x61\x72\x64\x6f\x77\x6e\x7c\x7c\x70\x2e\x74\x65\x61\ \x72\x64\x6f\x77\x6e\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x6c\x29\x3d\ \x3d\x3d\x21\x31\x29\x26\x26\x66\x2e\x72\x65\x6d\x6f\x76\x65\x45\ \x76\x65\x6e\x74\x28\x61\x2c\x6a\x2c\x67\x2e\x68\x61\x6e\x64\x6c\ \x65\x29\x2c\x64\x65\x6c\x65\x74\x65\x20\x6f\x5b\x6a\x5d\x29\x7d\ \x66\x2e\x69\x73\x45\x6d\x70\x74\x79\x4f\x62\x6a\x65\x63\x74\x28\ \x6f\x29\x26\x26\x28\x71\x3d\x67\x2e\x68\x61\x6e\x64\x6c\x65\x2c\ \x71\x26\x26\x28\x71\x2e\x65\x6c\x65\x6d\x3d\x6e\x75\x6c\x6c\x29\ \x2c\x66\x2e\x72\x65\x6d\x6f\x76\x65\x44\x61\x74\x61\x28\x61\x2c\ \x5b\x22\x65\x76\x65\x6e\x74\x73\x22\x2c\x22\x68\x61\x6e\x64\x6c\ \x65\x22\x5d\x2c\x21\x30\x29\x29\x7d\x7d\x2c\x63\x75\x73\x74\x6f\ \x6d\x45\x76\x65\x6e\x74\x3a\x7b\x67\x65\x74\x44\x61\x74\x61\x3a\ \x21\x30\x2c\x73\x65\x74\x44\x61\x74\x61\x3a\x21\x30\x2c\x63\x68\ \x61\x6e\x67\x65\x44\x61\x74\x61\x3a\x21\x30\x7d\x2c\x74\x72\x69\ \x67\x67\x65\x72\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x63\x2c\ \x64\x2c\x65\x2c\x67\x29\x7b\x69\x66\x28\x21\x65\x7c\x7c\x65\x2e\ \x6e\x6f\x64\x65\x54\x79\x70\x65\x21\x3d\x3d\x33\x26\x26\x65\x2e\ \x6e\x6f\x64\x65\x54\x79\x70\x65\x21\x3d\x3d\x38\x29\x7b\x76\x61\ \x72\x20\x68\x3d\x63\x2e\x74\x79\x70\x65\x7c\x7c\x63\x2c\x69\x3d\ \x5b\x5d\x2c\x6a\x2c\x6b\x2c\x6c\x2c\x6d\x2c\x6e\x2c\x6f\x2c\x70\ \x2c\x71\x2c\x72\x2c\x73\x3b\x69\x66\x28\x45\x2e\x74\x65\x73\x74\ \x28\x68\x2b\x66\x2e\x65\x76\x65\x6e\x74\x2e\x74\x72\x69\x67\x67\ \x65\x72\x65\x64\x29\x29\x72\x65\x74\x75\x72\x6e\x3b\x68\x2e\x69\ \x6e\x64\x65\x78\x4f\x66\x28\x22\x21\x22\x29\x3e\x3d\x30\x26\x26\ \x28\x68\x3d\x68\x2e\x73\x6c\x69\x63\x65\x28\x30\x2c\x2d\x31\x29\ \x2c\x6b\x3d\x21\x30\x29\x2c\x68\x2e\x69\x6e\x64\x65\x78\x4f\x66\ \x28\x22\x2e\x22\x29\x3e\x3d\x30\x26\x26\x28\x69\x3d\x68\x2e\x73\ \x70\x6c\x69\x74\x28\x22\x2e\x22\x29\x2c\x68\x3d\x69\x2e\x73\x68\ \x69\x66\x74\x28\x29\x2c\x69\x2e\x73\x6f\x72\x74\x28\x29\x29\x3b\ \x69\x66\x28\x28\x21\x65\x7c\x7c\x66\x2e\x65\x76\x65\x6e\x74\x2e\ \x63\x75\x73\x74\x6f\x6d\x45\x76\x65\x6e\x74\x5b\x68\x5d\x29\x26\ \x26\x21\x66\x2e\x65\x76\x65\x6e\x74\x2e\x67\x6c\x6f\x62\x61\x6c\ \x5b\x68\x5d\x29\x72\x65\x74\x75\x72\x6e\x3b\x63\x3d\x74\x79\x70\ \x65\x6f\x66\x20\x63\x3d\x3d\x22\x6f\x62\x6a\x65\x63\x74\x22\x3f\ \x63\x5b\x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x5d\x3f\x63\x3a\x6e\ \x65\x77\x20\x66\x2e\x45\x76\x65\x6e\x74\x28\x68\x2c\x63\x29\x3a\ \x6e\x65\x77\x20\x66\x2e\x45\x76\x65\x6e\x74\x28\x68\x29\x2c\x63\ \x2e\x74\x79\x70\x65\x3d\x68\x2c\x63\x2e\x69\x73\x54\x72\x69\x67\ \x67\x65\x72\x3d\x21\x30\x2c\x63\x2e\x65\x78\x63\x6c\x75\x73\x69\ \x76\x65\x3d\x6b\x2c\x63\x2e\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\ \x3d\x69\x2e\x6a\x6f\x69\x6e\x28\x22\x2e\x22\x29\x2c\x63\x2e\x6e\ \x61\x6d\x65\x73\x70\x61\x63\x65\x5f\x72\x65\x3d\x63\x2e\x6e\x61\ \x6d\x65\x73\x70\x61\x63\x65\x3f\x6e\x65\x77\x20\x52\x65\x67\x45\ \x78\x70\x28\x22\x28\x5e\x7c\x5c\x5c\x2e\x29\x22\x2b\x69\x2e\x6a\ \x6f\x69\x6e\x28\x22\x5c\x5c\x2e\x28\x3f\x3a\x2e\x2a\x5c\x5c\x2e\ \x29\x3f\x22\x29\x2b\x22\x28\x5c\x5c\x2e\x7c\x24\x29\x22\x29\x3a\ \x6e\x75\x6c\x6c\x2c\x6f\x3d\x68\x2e\x69\x6e\x64\x65\x78\x4f\x66\ \x28\x22\x3a\x22\x29\x3c\x30\x3f\x22\x6f\x6e\x22\x2b\x68\x3a\x22\ \x22\x3b\x69\x66\x28\x21\x65\x29\x7b\x6a\x3d\x66\x2e\x63\x61\x63\ \x68\x65\x3b\x66\x6f\x72\x28\x6c\x20\x69\x6e\x20\x6a\x29\x6a\x5b\ \x6c\x5d\x2e\x65\x76\x65\x6e\x74\x73\x26\x26\x6a\x5b\x6c\x5d\x2e\ \x65\x76\x65\x6e\x74\x73\x5b\x68\x5d\x26\x26\x66\x2e\x65\x76\x65\ \x6e\x74\x2e\x74\x72\x69\x67\x67\x65\x72\x28\x63\x2c\x64\x2c\x6a\ \x5b\x6c\x5d\x2e\x68\x61\x6e\x64\x6c\x65\x2e\x65\x6c\x65\x6d\x2c\ \x21\x30\x29\x3b\x72\x65\x74\x75\x72\x6e\x7d\x63\x2e\x72\x65\x73\ \x75\x6c\x74\x3d\x62\x2c\x63\x2e\x74\x61\x72\x67\x65\x74\x7c\x7c\ \x28\x63\x2e\x74\x61\x72\x67\x65\x74\x3d\x65\x29\x2c\x64\x3d\x64\ \x21\x3d\x6e\x75\x6c\x6c\x3f\x66\x2e\x6d\x61\x6b\x65\x41\x72\x72\ \x61\x79\x28\x64\x29\x3a\x5b\x5d\x2c\x64\x2e\x75\x6e\x73\x68\x69\ \x66\x74\x28\x63\x29\x2c\x70\x3d\x66\x2e\x65\x76\x65\x6e\x74\x2e\ \x73\x70\x65\x63\x69\x61\x6c\x5b\x68\x5d\x7c\x7c\x7b\x7d\x3b\x69\ \x66\x28\x70\x2e\x74\x72\x69\x67\x67\x65\x72\x26\x26\x70\x2e\x74\ \x72\x69\x67\x67\x65\x72\x2e\x61\x70\x70\x6c\x79\x28\x65\x2c\x64\ \x29\x3d\x3d\x3d\x21\x31\x29\x72\x65\x74\x75\x72\x6e\x3b\x72\x3d\ \x5b\x5b\x65\x2c\x70\x2e\x62\x69\x6e\x64\x54\x79\x70\x65\x7c\x7c\ \x68\x5d\x5d\x3b\x69\x66\x28\x21\x67\x26\x26\x21\x70\x2e\x6e\x6f\ \x42\x75\x62\x62\x6c\x65\x26\x26\x21\x66\x2e\x69\x73\x57\x69\x6e\ \x64\x6f\x77\x28\x65\x29\x29\x7b\x73\x3d\x70\x2e\x64\x65\x6c\x65\ \x67\x61\x74\x65\x54\x79\x70\x65\x7c\x7c\x68\x2c\x6d\x3d\x45\x2e\ \x74\x65\x73\x74\x28\x73\x2b\x68\x29\x3f\x65\x3a\x65\x2e\x70\x61\ \x72\x65\x6e\x74\x4e\x6f\x64\x65\x2c\x6e\x3d\x6e\x75\x6c\x6c\x3b\ \x66\x6f\x72\x28\x3b\x6d\x3b\x6d\x3d\x6d\x2e\x70\x61\x72\x65\x6e\ \x74\x4e\x6f\x64\x65\x29\x72\x2e\x70\x75\x73\x68\x28\x5b\x6d\x2c\ \x73\x5d\x29\x2c\x6e\x3d\x6d\x3b\x6e\x26\x26\x6e\x3d\x3d\x3d\x65\ \x2e\x6f\x77\x6e\x65\x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x26\x26\ \x72\x2e\x70\x75\x73\x68\x28\x5b\x6e\x2e\x64\x65\x66\x61\x75\x6c\ \x74\x56\x69\x65\x77\x7c\x7c\x6e\x2e\x70\x61\x72\x65\x6e\x74\x57\ \x69\x6e\x64\x6f\x77\x7c\x7c\x61\x2c\x73\x5d\x29\x7d\x66\x6f\x72\ \x28\x6c\x3d\x30\x3b\x6c\x3c\x72\x2e\x6c\x65\x6e\x67\x74\x68\x26\ \x26\x21\x63\x2e\x69\x73\x50\x72\x6f\x70\x61\x67\x61\x74\x69\x6f\ \x6e\x53\x74\x6f\x70\x70\x65\x64\x28\x29\x3b\x6c\x2b\x2b\x29\x6d\ \x3d\x72\x5b\x6c\x5d\x5b\x30\x5d\x2c\x63\x2e\x74\x79\x70\x65\x3d\ \x72\x5b\x6c\x5d\x5b\x31\x5d\x2c\x71\x3d\x28\x66\x2e\x5f\x64\x61\ \x74\x61\x28\x6d\x2c\x22\x65\x76\x65\x6e\x74\x73\x22\x29\x7c\x7c\ \x7b\x7d\x29\x5b\x63\x2e\x74\x79\x70\x65\x5d\x26\x26\x66\x2e\x5f\ \x64\x61\x74\x61\x28\x6d\x2c\x22\x68\x61\x6e\x64\x6c\x65\x22\x29\ \x2c\x71\x26\x26\x71\x2e\x61\x70\x70\x6c\x79\x28\x6d\x2c\x64\x29\ \x2c\x71\x3d\x6f\x26\x26\x6d\x5b\x6f\x5d\x2c\x71\x26\x26\x66\x2e\ \x61\x63\x63\x65\x70\x74\x44\x61\x74\x61\x28\x6d\x29\x26\x26\x71\ \x2e\x61\x70\x70\x6c\x79\x28\x6d\x2c\x64\x29\x3d\x3d\x3d\x21\x31\ \x26\x26\x63\x2e\x70\x72\x65\x76\x65\x6e\x74\x44\x65\x66\x61\x75\ \x6c\x74\x28\x29\x3b\x63\x2e\x74\x79\x70\x65\x3d\x68\x2c\x21\x67\ \x26\x26\x21\x63\x2e\x69\x73\x44\x65\x66\x61\x75\x6c\x74\x50\x72\ \x65\x76\x65\x6e\x74\x65\x64\x28\x29\x26\x26\x28\x21\x70\x2e\x5f\ \x64\x65\x66\x61\x75\x6c\x74\x7c\x7c\x70\x2e\x5f\x64\x65\x66\x61\ \x75\x6c\x74\x2e\x61\x70\x70\x6c\x79\x28\x65\x2e\x6f\x77\x6e\x65\ \x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x2c\x64\x29\x3d\x3d\x3d\x21\ \x31\x29\x26\x26\x28\x68\x21\x3d\x3d\x22\x63\x6c\x69\x63\x6b\x22\ \x7c\x7c\x21\x66\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x28\x65\x2c\ \x22\x61\x22\x29\x29\x26\x26\x66\x2e\x61\x63\x63\x65\x70\x74\x44\ \x61\x74\x61\x28\x65\x29\x26\x26\x6f\x26\x26\x65\x5b\x68\x5d\x26\ \x26\x28\x68\x21\x3d\x3d\x22\x66\x6f\x63\x75\x73\x22\x26\x26\x68\ \x21\x3d\x3d\x22\x62\x6c\x75\x72\x22\x7c\x7c\x63\x2e\x74\x61\x72\ \x67\x65\x74\x2e\x6f\x66\x66\x73\x65\x74\x57\x69\x64\x74\x68\x21\ \x3d\x3d\x30\x29\x26\x26\x21\x66\x2e\x69\x73\x57\x69\x6e\x64\x6f\ \x77\x28\x65\x29\x26\x26\x28\x6e\x3d\x65\x5b\x6f\x5d\x2c\x6e\x26\ \x26\x28\x65\x5b\x6f\x5d\x3d\x6e\x75\x6c\x6c\x29\x2c\x66\x2e\x65\ \x76\x65\x6e\x74\x2e\x74\x72\x69\x67\x67\x65\x72\x65\x64\x3d\x68\ \x2c\x65\x5b\x68\x5d\x28\x29\x2c\x66\x2e\x65\x76\x65\x6e\x74\x2e\ \x74\x72\x69\x67\x67\x65\x72\x65\x64\x3d\x62\x2c\x6e\x26\x26\x28\ \x65\x5b\x6f\x5d\x3d\x6e\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\ \x63\x2e\x72\x65\x73\x75\x6c\x74\x7d\x7d\x2c\x64\x69\x73\x70\x61\ \x74\x63\x68\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x63\x29\x7b\ \x63\x3d\x66\x2e\x65\x76\x65\x6e\x74\x2e\x66\x69\x78\x28\x63\x7c\ \x7c\x61\x2e\x65\x76\x65\x6e\x74\x29\x3b\x76\x61\x72\x20\x64\x3d\ \x28\x66\x2e\x5f\x64\x61\x74\x61\x28\x74\x68\x69\x73\x2c\x22\x65\ \x76\x65\x6e\x74\x73\x22\x29\x7c\x7c\x7b\x7d\x29\x5b\x63\x2e\x74\ \x79\x70\x65\x5d\x7c\x7c\x5b\x5d\x2c\x65\x3d\x64\x2e\x64\x65\x6c\ \x65\x67\x61\x74\x65\x43\x6f\x75\x6e\x74\x2c\x67\x3d\x5b\x5d\x2e\ \x73\x6c\x69\x63\x65\x2e\x63\x61\x6c\x6c\x28\x61\x72\x67\x75\x6d\ \x65\x6e\x74\x73\x2c\x30\x29\x2c\x68\x3d\x21\x63\x2e\x65\x78\x63\ \x6c\x75\x73\x69\x76\x65\x26\x26\x21\x63\x2e\x6e\x61\x6d\x65\x73\ \x70\x61\x63\x65\x2c\x69\x3d\x5b\x5d\x2c\x6a\x2c\x6b\x2c\x6c\x2c\ \x6d\x2c\x6e\x2c\x6f\x2c\x70\x2c\x71\x2c\x72\x2c\x73\x2c\x74\x3b\ \x67\x5b\x30\x5d\x3d\x63\x2c\x63\x2e\x64\x65\x6c\x65\x67\x61\x74\ \x65\x54\x61\x72\x67\x65\x74\x3d\x74\x68\x69\x73\x3b\x69\x66\x28\ \x65\x26\x26\x21\x63\x2e\x74\x61\x72\x67\x65\x74\x2e\x64\x69\x73\ \x61\x62\x6c\x65\x64\x26\x26\x28\x21\x63\x2e\x62\x75\x74\x74\x6f\ \x6e\x7c\x7c\x63\x2e\x74\x79\x70\x65\x21\x3d\x3d\x22\x63\x6c\x69\ \x63\x6b\x22\x29\x29\x7b\x6d\x3d\x66\x28\x74\x68\x69\x73\x29\x2c\ \x6d\x2e\x63\x6f\x6e\x74\x65\x78\x74\x3d\x74\x68\x69\x73\x2e\x6f\ \x77\x6e\x65\x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x7c\x7c\x74\x68\ \x69\x73\x3b\x66\x6f\x72\x28\x6c\x3d\x63\x2e\x74\x61\x72\x67\x65\ \x74\x3b\x6c\x21\x3d\x74\x68\x69\x73\x3b\x6c\x3d\x6c\x2e\x70\x61\ \x72\x65\x6e\x74\x4e\x6f\x64\x65\x7c\x7c\x74\x68\x69\x73\x29\x7b\ \x6f\x3d\x7b\x7d\x2c\x71\x3d\x5b\x5d\x2c\x6d\x5b\x30\x5d\x3d\x6c\ \x3b\x66\x6f\x72\x28\x6a\x3d\x30\x3b\x6a\x3c\x65\x3b\x6a\x2b\x2b\ \x29\x72\x3d\x64\x5b\x6a\x5d\x2c\x73\x3d\x72\x2e\x73\x65\x6c\x65\ \x63\x74\x6f\x72\x2c\x6f\x5b\x73\x5d\x3d\x3d\x3d\x62\x26\x26\x28\ \x6f\x5b\x73\x5d\x3d\x72\x2e\x71\x75\x69\x63\x6b\x3f\x48\x28\x6c\ \x2c\x72\x2e\x71\x75\x69\x63\x6b\x29\x3a\x6d\x2e\x69\x73\x28\x73\ \x29\x29\x2c\x6f\x5b\x73\x5d\x26\x26\x71\x2e\x70\x75\x73\x68\x28\ \x72\x29\x3b\x71\x2e\x6c\x65\x6e\x67\x74\x68\x26\x26\x69\x2e\x70\ \x75\x73\x68\x28\x7b\x65\x6c\x65\x6d\x3a\x6c\x2c\x6d\x61\x74\x63\ \x68\x65\x73\x3a\x71\x7d\x29\x7d\x7d\x64\x2e\x6c\x65\x6e\x67\x74\ \x68\x3e\x65\x26\x26\x69\x2e\x70\x75\x73\x68\x28\x7b\x65\x6c\x65\ \x6d\x3a\x74\x68\x69\x73\x2c\x6d\x61\x74\x63\x68\x65\x73\x3a\x64\ \x2e\x73\x6c\x69\x63\x65\x28\x65\x29\x7d\x29\x3b\x66\x6f\x72\x28\ \x6a\x3d\x30\x3b\x6a\x3c\x69\x2e\x6c\x65\x6e\x67\x74\x68\x26\x26\ \x21\x63\x2e\x69\x73\x50\x72\x6f\x70\x61\x67\x61\x74\x69\x6f\x6e\ \x53\x74\x6f\x70\x70\x65\x64\x28\x29\x3b\x6a\x2b\x2b\x29\x7b\x70\ \x3d\x69\x5b\x6a\x5d\x2c\x63\x2e\x63\x75\x72\x72\x65\x6e\x74\x54\ \x61\x72\x67\x65\x74\x3d\x70\x2e\x65\x6c\x65\x6d\x3b\x66\x6f\x72\ \x28\x6b\x3d\x30\x3b\x6b\x3c\x70\x2e\x6d\x61\x74\x63\x68\x65\x73\ \x2e\x6c\x65\x6e\x67\x74\x68\x26\x26\x21\x63\x2e\x69\x73\x49\x6d\ \x6d\x65\x64\x69\x61\x74\x65\x50\x72\x6f\x70\x61\x67\x61\x74\x69\ \x6f\x6e\x53\x74\x6f\x70\x70\x65\x64\x28\x29\x3b\x6b\x2b\x2b\x29\ \x7b\x72\x3d\x70\x2e\x6d\x61\x74\x63\x68\x65\x73\x5b\x6b\x5d\x3b\ \x69\x66\x28\x68\x7c\x7c\x21\x63\x2e\x6e\x61\x6d\x65\x73\x70\x61\ \x63\x65\x26\x26\x21\x72\x2e\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\ \x7c\x7c\x63\x2e\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x5f\x72\x65\ \x26\x26\x63\x2e\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x5f\x72\x65\ \x2e\x74\x65\x73\x74\x28\x72\x2e\x6e\x61\x6d\x65\x73\x70\x61\x63\ \x65\x29\x29\x63\x2e\x64\x61\x74\x61\x3d\x72\x2e\x64\x61\x74\x61\ \x2c\x63\x2e\x68\x61\x6e\x64\x6c\x65\x4f\x62\x6a\x3d\x72\x2c\x6e\ \x3d\x28\x28\x66\x2e\x65\x76\x65\x6e\x74\x2e\x73\x70\x65\x63\x69\ \x61\x6c\x5b\x72\x2e\x6f\x72\x69\x67\x54\x79\x70\x65\x5d\x7c\x7c\ \x7b\x7d\x29\x2e\x68\x61\x6e\x64\x6c\x65\x7c\x7c\x72\x2e\x68\x61\ \x6e\x64\x6c\x65\x72\x29\x2e\x61\x70\x70\x6c\x79\x28\x70\x2e\x65\ \x6c\x65\x6d\x2c\x67\x29\x2c\x6e\x21\x3d\x3d\x62\x26\x26\x28\x63\ \x2e\x72\x65\x73\x75\x6c\x74\x3d\x6e\x2c\x6e\x3d\x3d\x3d\x21\x31\ \x26\x26\x28\x63\x2e\x70\x72\x65\x76\x65\x6e\x74\x44\x65\x66\x61\ \x75\x6c\x74\x28\x29\x2c\x63\x2e\x73\x74\x6f\x70\x50\x72\x6f\x70\ \x61\x67\x61\x74\x69\x6f\x6e\x28\x29\x29\x29\x7d\x7d\x72\x65\x74\ \x75\x72\x6e\x20\x63\x2e\x72\x65\x73\x75\x6c\x74\x7d\x2c\x70\x72\ \x6f\x70\x73\x3a\x22\x61\x74\x74\x72\x43\x68\x61\x6e\x67\x65\x20\ \x61\x74\x74\x72\x4e\x61\x6d\x65\x20\x72\x65\x6c\x61\x74\x65\x64\ \x4e\x6f\x64\x65\x20\x73\x72\x63\x45\x6c\x65\x6d\x65\x6e\x74\x20\ \x61\x6c\x74\x4b\x65\x79\x20\x62\x75\x62\x62\x6c\x65\x73\x20\x63\ \x61\x6e\x63\x65\x6c\x61\x62\x6c\x65\x20\x63\x74\x72\x6c\x4b\x65\ \x79\x20\x63\x75\x72\x72\x65\x6e\x74\x54\x61\x72\x67\x65\x74\x20\ \x65\x76\x65\x6e\x74\x50\x68\x61\x73\x65\x20\x6d\x65\x74\x61\x4b\ \x65\x79\x20\x72\x65\x6c\x61\x74\x65\x64\x54\x61\x72\x67\x65\x74\ \x20\x73\x68\x69\x66\x74\x4b\x65\x79\x20\x74\x61\x72\x67\x65\x74\ \x20\x74\x69\x6d\x65\x53\x74\x61\x6d\x70\x20\x76\x69\x65\x77\x20\ \x77\x68\x69\x63\x68\x22\x2e\x73\x70\x6c\x69\x74\x28\x22\x20\x22\ \x29\x2c\x66\x69\x78\x48\x6f\x6f\x6b\x73\x3a\x7b\x7d\x2c\x6b\x65\ \x79\x48\x6f\x6f\x6b\x73\x3a\x7b\x70\x72\x6f\x70\x73\x3a\x22\x63\ \x68\x61\x72\x20\x63\x68\x61\x72\x43\x6f\x64\x65\x20\x6b\x65\x79\ \x20\x6b\x65\x79\x43\x6f\x64\x65\x22\x2e\x73\x70\x6c\x69\x74\x28\ \x22\x20\x22\x29\x2c\x66\x69\x6c\x74\x65\x72\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x61\x2e\x77\x68\x69\x63\ \x68\x3d\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x61\x2e\x77\x68\x69\x63\ \x68\x3d\x62\x2e\x63\x68\x61\x72\x43\x6f\x64\x65\x21\x3d\x6e\x75\ \x6c\x6c\x3f\x62\x2e\x63\x68\x61\x72\x43\x6f\x64\x65\x3a\x62\x2e\ \x6b\x65\x79\x43\x6f\x64\x65\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\ \x61\x7d\x7d\x2c\x6d\x6f\x75\x73\x65\x48\x6f\x6f\x6b\x73\x3a\x7b\ \x70\x72\x6f\x70\x73\x3a\x22\x62\x75\x74\x74\x6f\x6e\x20\x62\x75\ \x74\x74\x6f\x6e\x73\x20\x63\x6c\x69\x65\x6e\x74\x58\x20\x63\x6c\ \x69\x65\x6e\x74\x59\x20\x66\x72\x6f\x6d\x45\x6c\x65\x6d\x65\x6e\ \x74\x20\x6f\x66\x66\x73\x65\x74\x58\x20\x6f\x66\x66\x73\x65\x74\ \x59\x20\x70\x61\x67\x65\x58\x20\x70\x61\x67\x65\x59\x20\x73\x63\ \x72\x65\x65\x6e\x58\x20\x73\x63\x72\x65\x65\x6e\x59\x20\x74\x6f\ \x45\x6c\x65\x6d\x65\x6e\x74\x22\x2e\x73\x70\x6c\x69\x74\x28\x22\ \x20\x22\x29\x2c\x66\x69\x6c\x74\x65\x72\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x64\x29\x7b\x76\x61\x72\x20\x65\x2c\x66\ \x2c\x67\x2c\x68\x3d\x64\x2e\x62\x75\x74\x74\x6f\x6e\x2c\x69\x3d\ \x64\x2e\x66\x72\x6f\x6d\x45\x6c\x65\x6d\x65\x6e\x74\x3b\x61\x2e\ \x70\x61\x67\x65\x58\x3d\x3d\x6e\x75\x6c\x6c\x26\x26\x64\x2e\x63\ \x6c\x69\x65\x6e\x74\x58\x21\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x65\ \x3d\x61\x2e\x74\x61\x72\x67\x65\x74\x2e\x6f\x77\x6e\x65\x72\x44\ \x6f\x63\x75\x6d\x65\x6e\x74\x7c\x7c\x63\x2c\x66\x3d\x65\x2e\x64\ \x6f\x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2c\x67\ \x3d\x65\x2e\x62\x6f\x64\x79\x2c\x61\x2e\x70\x61\x67\x65\x58\x3d\ \x64\x2e\x63\x6c\x69\x65\x6e\x74\x58\x2b\x28\x66\x26\x26\x66\x2e\ \x73\x63\x72\x6f\x6c\x6c\x4c\x65\x66\x74\x7c\x7c\x67\x26\x26\x67\ \x2e\x73\x63\x72\x6f\x6c\x6c\x4c\x65\x66\x74\x7c\x7c\x30\x29\x2d\ \x28\x66\x26\x26\x66\x2e\x63\x6c\x69\x65\x6e\x74\x4c\x65\x66\x74\ \x7c\x7c\x67\x26\x26\x67\x2e\x63\x6c\x69\x65\x6e\x74\x4c\x65\x66\ \x74\x7c\x7c\x30\x29\x2c\x61\x2e\x70\x61\x67\x65\x59\x3d\x64\x2e\ \x63\x6c\x69\x65\x6e\x74\x59\x2b\x28\x66\x26\x26\x66\x2e\x73\x63\ \x72\x6f\x6c\x6c\x54\x6f\x70\x7c\x7c\x67\x26\x26\x67\x2e\x73\x63\ \x72\x6f\x6c\x6c\x54\x6f\x70\x7c\x7c\x30\x29\x2d\x28\x66\x26\x26\ \x66\x2e\x63\x6c\x69\x65\x6e\x74\x54\x6f\x70\x7c\x7c\x67\x26\x26\ \x67\x2e\x63\x6c\x69\x65\x6e\x74\x54\x6f\x70\x7c\x7c\x30\x29\x29\ \x2c\x21\x61\x2e\x72\x65\x6c\x61\x74\x65\x64\x54\x61\x72\x67\x65\ \x74\x26\x26\x69\x26\x26\x28\x61\x2e\x72\x65\x6c\x61\x74\x65\x64\ \x54\x61\x72\x67\x65\x74\x3d\x69\x3d\x3d\x3d\x61\x2e\x74\x61\x72\ \x67\x65\x74\x3f\x64\x2e\x74\x6f\x45\x6c\x65\x6d\x65\x6e\x74\x3a\ \x69\x29\x2c\x21\x61\x2e\x77\x68\x69\x63\x68\x26\x26\x68\x21\x3d\ \x3d\x62\x26\x26\x28\x61\x2e\x77\x68\x69\x63\x68\x3d\x68\x26\x31\ \x3f\x31\x3a\x68\x26\x32\x3f\x33\x3a\x68\x26\x34\x3f\x32\x3a\x30\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x7d\x7d\x2c\x66\x69\x78\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\x28\ \x61\x5b\x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x5d\x29\x72\x65\x74\ \x75\x72\x6e\x20\x61\x3b\x76\x61\x72\x20\x64\x2c\x65\x2c\x67\x3d\ \x61\x2c\x68\x3d\x66\x2e\x65\x76\x65\x6e\x74\x2e\x66\x69\x78\x48\ \x6f\x6f\x6b\x73\x5b\x61\x2e\x74\x79\x70\x65\x5d\x7c\x7c\x7b\x7d\ \x2c\x69\x3d\x68\x2e\x70\x72\x6f\x70\x73\x3f\x74\x68\x69\x73\x2e\ \x70\x72\x6f\x70\x73\x2e\x63\x6f\x6e\x63\x61\x74\x28\x68\x2e\x70\ \x72\x6f\x70\x73\x29\x3a\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x73\ \x3b\x61\x3d\x66\x2e\x45\x76\x65\x6e\x74\x28\x67\x29\x3b\x66\x6f\ \x72\x28\x64\x3d\x69\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x64\x3b\x29\ \x65\x3d\x69\x5b\x2d\x2d\x64\x5d\x2c\x61\x5b\x65\x5d\x3d\x67\x5b\ \x65\x5d\x3b\x61\x2e\x74\x61\x72\x67\x65\x74\x7c\x7c\x28\x61\x2e\ \x74\x61\x72\x67\x65\x74\x3d\x67\x2e\x73\x72\x63\x45\x6c\x65\x6d\ \x65\x6e\x74\x7c\x7c\x63\x29\x2c\x61\x2e\x74\x61\x72\x67\x65\x74\ \x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x33\x26\x26\x28\ \x61\x2e\x74\x61\x72\x67\x65\x74\x3d\x61\x2e\x74\x61\x72\x67\x65\ \x74\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x29\x2c\x61\x2e\ \x6d\x65\x74\x61\x4b\x65\x79\x3d\x3d\x3d\x62\x26\x26\x28\x61\x2e\ \x6d\x65\x74\x61\x4b\x65\x79\x3d\x61\x2e\x63\x74\x72\x6c\x4b\x65\ \x79\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x68\x2e\x66\x69\x6c\x74\ \x65\x72\x3f\x68\x2e\x66\x69\x6c\x74\x65\x72\x28\x61\x2c\x67\x29\ \x3a\x61\x7d\x2c\x73\x70\x65\x63\x69\x61\x6c\x3a\x7b\x72\x65\x61\ \x64\x79\x3a\x7b\x73\x65\x74\x75\x70\x3a\x66\x2e\x62\x69\x6e\x64\ \x52\x65\x61\x64\x79\x7d\x2c\x6c\x6f\x61\x64\x3a\x7b\x6e\x6f\x42\ \x75\x62\x62\x6c\x65\x3a\x21\x30\x7d\x2c\x66\x6f\x63\x75\x73\x3a\ \x7b\x64\x65\x6c\x65\x67\x61\x74\x65\x54\x79\x70\x65\x3a\x22\x66\ \x6f\x63\x75\x73\x69\x6e\x22\x7d\x2c\x62\x6c\x75\x72\x3a\x7b\x64\ \x65\x6c\x65\x67\x61\x74\x65\x54\x79\x70\x65\x3a\x22\x66\x6f\x63\ \x75\x73\x6f\x75\x74\x22\x7d\x2c\x62\x65\x66\x6f\x72\x65\x75\x6e\ \x6c\x6f\x61\x64\x3a\x7b\x73\x65\x74\x75\x70\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x66\x2e\x69\x73\ \x57\x69\x6e\x64\x6f\x77\x28\x74\x68\x69\x73\x29\x26\x26\x28\x74\ \x68\x69\x73\x2e\x6f\x6e\x62\x65\x66\x6f\x72\x65\x75\x6e\x6c\x6f\ \x61\x64\x3d\x63\x29\x7d\x2c\x74\x65\x61\x72\x64\x6f\x77\x6e\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x74\x68\ \x69\x73\x2e\x6f\x6e\x62\x65\x66\x6f\x72\x65\x75\x6e\x6c\x6f\x61\ \x64\x3d\x3d\x3d\x62\x26\x26\x28\x74\x68\x69\x73\x2e\x6f\x6e\x62\ \x65\x66\x6f\x72\x65\x75\x6e\x6c\x6f\x61\x64\x3d\x6e\x75\x6c\x6c\ \x29\x7d\x7d\x7d\x2c\x73\x69\x6d\x75\x6c\x61\x74\x65\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\x7b\ \x76\x61\x72\x20\x65\x3d\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x6e\ \x65\x77\x20\x66\x2e\x45\x76\x65\x6e\x74\x2c\x63\x2c\x7b\x74\x79\ \x70\x65\x3a\x61\x2c\x69\x73\x53\x69\x6d\x75\x6c\x61\x74\x65\x64\ \x3a\x21\x30\x2c\x6f\x72\x69\x67\x69\x6e\x61\x6c\x45\x76\x65\x6e\ \x74\x3a\x7b\x7d\x7d\x29\x3b\x64\x3f\x66\x2e\x65\x76\x65\x6e\x74\ \x2e\x74\x72\x69\x67\x67\x65\x72\x28\x65\x2c\x6e\x75\x6c\x6c\x2c\ \x62\x29\x3a\x66\x2e\x65\x76\x65\x6e\x74\x2e\x64\x69\x73\x70\x61\ \x74\x63\x68\x2e\x63\x61\x6c\x6c\x28\x62\x2c\x65\x29\x2c\x65\x2e\ \x69\x73\x44\x65\x66\x61\x75\x6c\x74\x50\x72\x65\x76\x65\x6e\x74\ \x65\x64\x28\x29\x26\x26\x63\x2e\x70\x72\x65\x76\x65\x6e\x74\x44\ \x65\x66\x61\x75\x6c\x74\x28\x29\x7d\x7d\x2c\x66\x2e\x65\x76\x65\ \x6e\x74\x2e\x68\x61\x6e\x64\x6c\x65\x3d\x66\x2e\x65\x76\x65\x6e\ \x74\x2e\x64\x69\x73\x70\x61\x74\x63\x68\x2c\x66\x2e\x72\x65\x6d\ \x6f\x76\x65\x45\x76\x65\x6e\x74\x3d\x63\x2e\x72\x65\x6d\x6f\x76\ \x65\x45\x76\x65\x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72\x3f\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x61\ \x2e\x72\x65\x6d\x6f\x76\x65\x45\x76\x65\x6e\x74\x4c\x69\x73\x74\ \x65\x6e\x65\x72\x26\x26\x61\x2e\x72\x65\x6d\x6f\x76\x65\x45\x76\ \x65\x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72\x28\x62\x2c\x63\x2c\ \x21\x31\x29\x7d\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x2c\x63\x29\x7b\x61\x2e\x64\x65\x74\x61\x63\x68\x45\x76\x65\ \x6e\x74\x26\x26\x61\x2e\x64\x65\x74\x61\x63\x68\x45\x76\x65\x6e\ \x74\x28\x22\x6f\x6e\x22\x2b\x62\x2c\x63\x29\x7d\x2c\x66\x2e\x45\ \x76\x65\x6e\x74\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x29\x7b\x69\x66\x28\x21\x28\x74\x68\x69\x73\x20\x69\x6e\x73\ \x74\x61\x6e\x63\x65\x6f\x66\x20\x66\x2e\x45\x76\x65\x6e\x74\x29\ \x29\x72\x65\x74\x75\x72\x6e\x20\x6e\x65\x77\x20\x66\x2e\x45\x76\ \x65\x6e\x74\x28\x61\x2c\x62\x29\x3b\x61\x26\x26\x61\x2e\x74\x79\ \x70\x65\x3f\x28\x74\x68\x69\x73\x2e\x6f\x72\x69\x67\x69\x6e\x61\ \x6c\x45\x76\x65\x6e\x74\x3d\x61\x2c\x74\x68\x69\x73\x2e\x74\x79\ \x70\x65\x3d\x61\x2e\x74\x79\x70\x65\x2c\x74\x68\x69\x73\x2e\x69\ \x73\x44\x65\x66\x61\x75\x6c\x74\x50\x72\x65\x76\x65\x6e\x74\x65\ \x64\x3d\x61\x2e\x64\x65\x66\x61\x75\x6c\x74\x50\x72\x65\x76\x65\ \x6e\x74\x65\x64\x7c\x7c\x61\x2e\x72\x65\x74\x75\x72\x6e\x56\x61\ \x6c\x75\x65\x3d\x3d\x3d\x21\x31\x7c\x7c\x61\x2e\x67\x65\x74\x50\ \x72\x65\x76\x65\x6e\x74\x44\x65\x66\x61\x75\x6c\x74\x26\x26\x61\ \x2e\x67\x65\x74\x50\x72\x65\x76\x65\x6e\x74\x44\x65\x66\x61\x75\ \x6c\x74\x28\x29\x3f\x4b\x3a\x4a\x29\x3a\x74\x68\x69\x73\x2e\x74\ \x79\x70\x65\x3d\x61\x2c\x62\x26\x26\x66\x2e\x65\x78\x74\x65\x6e\ \x64\x28\x74\x68\x69\x73\x2c\x62\x29\x2c\x74\x68\x69\x73\x2e\x74\ \x69\x6d\x65\x53\x74\x61\x6d\x70\x3d\x61\x26\x26\x61\x2e\x74\x69\ \x6d\x65\x53\x74\x61\x6d\x70\x7c\x7c\x66\x2e\x6e\x6f\x77\x28\x29\ \x2c\x74\x68\x69\x73\x5b\x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x5d\ \x3d\x21\x30\x7d\x2c\x66\x2e\x45\x76\x65\x6e\x74\x2e\x70\x72\x6f\ \x74\x6f\x74\x79\x70\x65\x3d\x7b\x70\x72\x65\x76\x65\x6e\x74\x44\ \x65\x66\x61\x75\x6c\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x74\x68\x69\x73\x2e\x69\x73\x44\x65\x66\x61\x75\x6c\x74\ \x50\x72\x65\x76\x65\x6e\x74\x65\x64\x3d\x4b\x3b\x76\x61\x72\x20\ \x61\x3d\x74\x68\x69\x73\x2e\x6f\x72\x69\x67\x69\x6e\x61\x6c\x45\ \x76\x65\x6e\x74\x3b\x21\x61\x7c\x7c\x28\x61\x2e\x70\x72\x65\x76\ \x65\x6e\x74\x44\x65\x66\x61\x75\x6c\x74\x3f\x61\x2e\x70\x72\x65\ \x76\x65\x6e\x74\x44\x65\x66\x61\x75\x6c\x74\x28\x29\x3a\x61\x2e\ \x72\x65\x74\x75\x72\x6e\x56\x61\x6c\x75\x65\x3d\x21\x31\x29\x7d\ \x2c\x73\x74\x6f\x70\x50\x72\x6f\x70\x61\x67\x61\x74\x69\x6f\x6e\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x74\x68\x69\x73\ \x2e\x69\x73\x50\x72\x6f\x70\x61\x67\x61\x74\x69\x6f\x6e\x53\x74\ \x6f\x70\x70\x65\x64\x3d\x4b\x3b\x76\x61\x72\x20\x61\x3d\x74\x68\ \x69\x73\x2e\x6f\x72\x69\x67\x69\x6e\x61\x6c\x45\x76\x65\x6e\x74\ \x3b\x21\x61\x7c\x7c\x28\x61\x2e\x73\x74\x6f\x70\x50\x72\x6f\x70\ \x61\x67\x61\x74\x69\x6f\x6e\x26\x26\x61\x2e\x73\x74\x6f\x70\x50\ \x72\x6f\x70\x61\x67\x61\x74\x69\x6f\x6e\x28\x29\x2c\x61\x2e\x63\ \x61\x6e\x63\x65\x6c\x42\x75\x62\x62\x6c\x65\x3d\x21\x30\x29\x7d\ \x2c\x73\x74\x6f\x70\x49\x6d\x6d\x65\x64\x69\x61\x74\x65\x50\x72\ \x6f\x70\x61\x67\x61\x74\x69\x6f\x6e\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x29\x7b\x74\x68\x69\x73\x2e\x69\x73\x49\x6d\x6d\x65\ \x64\x69\x61\x74\x65\x50\x72\x6f\x70\x61\x67\x61\x74\x69\x6f\x6e\ \x53\x74\x6f\x70\x70\x65\x64\x3d\x4b\x2c\x74\x68\x69\x73\x2e\x73\ \x74\x6f\x70\x50\x72\x6f\x70\x61\x67\x61\x74\x69\x6f\x6e\x28\x29\ \x7d\x2c\x69\x73\x44\x65\x66\x61\x75\x6c\x74\x50\x72\x65\x76\x65\ \x6e\x74\x65\x64\x3a\x4a\x2c\x69\x73\x50\x72\x6f\x70\x61\x67\x61\ \x74\x69\x6f\x6e\x53\x74\x6f\x70\x70\x65\x64\x3a\x4a\x2c\x69\x73\ \x49\x6d\x6d\x65\x64\x69\x61\x74\x65\x50\x72\x6f\x70\x61\x67\x61\ \x74\x69\x6f\x6e\x53\x74\x6f\x70\x70\x65\x64\x3a\x4a\x7d\x2c\x66\ \x2e\x65\x61\x63\x68\x28\x7b\x6d\x6f\x75\x73\x65\x65\x6e\x74\x65\ \x72\x3a\x22\x6d\x6f\x75\x73\x65\x6f\x76\x65\x72\x22\x2c\x6d\x6f\ \x75\x73\x65\x6c\x65\x61\x76\x65\x3a\x22\x6d\x6f\x75\x73\x65\x6f\ \x75\x74\x22\x7d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x29\x7b\x66\x2e\x65\x76\x65\x6e\x74\x2e\x73\x70\x65\x63\x69\ \x61\x6c\x5b\x61\x5d\x3d\x7b\x64\x65\x6c\x65\x67\x61\x74\x65\x54\ \x79\x70\x65\x3a\x62\x2c\x62\x69\x6e\x64\x54\x79\x70\x65\x3a\x62\ \x2c\x68\x61\x6e\x64\x6c\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x76\x61\x72\x20\x63\x3d\x74\x68\x69\x73\x2c\x64\ \x3d\x61\x2e\x72\x65\x6c\x61\x74\x65\x64\x54\x61\x72\x67\x65\x74\ \x2c\x65\x3d\x61\x2e\x68\x61\x6e\x64\x6c\x65\x4f\x62\x6a\x2c\x67\ \x3d\x65\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x2c\x68\x3b\x69\x66\ \x28\x21\x64\x7c\x7c\x64\x21\x3d\x3d\x63\x26\x26\x21\x66\x2e\x63\ \x6f\x6e\x74\x61\x69\x6e\x73\x28\x63\x2c\x64\x29\x29\x61\x2e\x74\ \x79\x70\x65\x3d\x65\x2e\x6f\x72\x69\x67\x54\x79\x70\x65\x2c\x68\ \x3d\x65\x2e\x68\x61\x6e\x64\x6c\x65\x72\x2e\x61\x70\x70\x6c\x79\ \x28\x74\x68\x69\x73\x2c\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\ \x2c\x61\x2e\x74\x79\x70\x65\x3d\x62\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x68\x7d\x7d\x7d\x29\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\ \x2e\x73\x75\x62\x6d\x69\x74\x42\x75\x62\x62\x6c\x65\x73\x7c\x7c\ \x28\x66\x2e\x65\x76\x65\x6e\x74\x2e\x73\x70\x65\x63\x69\x61\x6c\ \x2e\x73\x75\x62\x6d\x69\x74\x3d\x7b\x73\x65\x74\x75\x70\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x66\x2e\x6e\ \x6f\x64\x65\x4e\x61\x6d\x65\x28\x74\x68\x69\x73\x2c\x22\x66\x6f\ \x72\x6d\x22\x29\x29\x72\x65\x74\x75\x72\x6e\x21\x31\x3b\x66\x2e\ \x65\x76\x65\x6e\x74\x2e\x61\x64\x64\x28\x74\x68\x69\x73\x2c\x22\ \x63\x6c\x69\x63\x6b\x2e\x5f\x73\x75\x62\x6d\x69\x74\x20\x6b\x65\ \x79\x70\x72\x65\x73\x73\x2e\x5f\x73\x75\x62\x6d\x69\x74\x22\x2c\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\ \x63\x3d\x61\x2e\x74\x61\x72\x67\x65\x74\x2c\x64\x3d\x66\x2e\x6e\ \x6f\x64\x65\x4e\x61\x6d\x65\x28\x63\x2c\x22\x69\x6e\x70\x75\x74\ \x22\x29\x7c\x7c\x66\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x28\x63\ \x2c\x22\x62\x75\x74\x74\x6f\x6e\x22\x29\x3f\x63\x2e\x66\x6f\x72\ \x6d\x3a\x62\x3b\x64\x26\x26\x21\x64\x2e\x5f\x73\x75\x62\x6d\x69\ \x74\x5f\x61\x74\x74\x61\x63\x68\x65\x64\x26\x26\x28\x66\x2e\x65\ \x76\x65\x6e\x74\x2e\x61\x64\x64\x28\x64\x2c\x22\x73\x75\x62\x6d\ \x69\x74\x2e\x5f\x73\x75\x62\x6d\x69\x74\x22\x2c\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x74\x68\x69\x73\x2e\x70\x61\x72\ \x65\x6e\x74\x4e\x6f\x64\x65\x26\x26\x21\x61\x2e\x69\x73\x54\x72\ \x69\x67\x67\x65\x72\x26\x26\x66\x2e\x65\x76\x65\x6e\x74\x2e\x73\ \x69\x6d\x75\x6c\x61\x74\x65\x28\x22\x73\x75\x62\x6d\x69\x74\x22\ \x2c\x74\x68\x69\x73\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\ \x2c\x61\x2c\x21\x30\x29\x7d\x29\x2c\x64\x2e\x5f\x73\x75\x62\x6d\ \x69\x74\x5f\x61\x74\x74\x61\x63\x68\x65\x64\x3d\x21\x30\x29\x7d\ \x29\x7d\x2c\x74\x65\x61\x72\x64\x6f\x77\x6e\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x66\x2e\x6e\x6f\x64\x65\ \x4e\x61\x6d\x65\x28\x74\x68\x69\x73\x2c\x22\x66\x6f\x72\x6d\x22\ \x29\x29\x72\x65\x74\x75\x72\x6e\x21\x31\x3b\x66\x2e\x65\x76\x65\ \x6e\x74\x2e\x72\x65\x6d\x6f\x76\x65\x28\x74\x68\x69\x73\x2c\x22\ \x2e\x5f\x73\x75\x62\x6d\x69\x74\x22\x29\x7d\x7d\x29\x2c\x66\x2e\ \x73\x75\x70\x70\x6f\x72\x74\x2e\x63\x68\x61\x6e\x67\x65\x42\x75\ \x62\x62\x6c\x65\x73\x7c\x7c\x28\x66\x2e\x65\x76\x65\x6e\x74\x2e\ \x73\x70\x65\x63\x69\x61\x6c\x2e\x63\x68\x61\x6e\x67\x65\x3d\x7b\ \x73\x65\x74\x75\x70\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\ \x7b\x69\x66\x28\x7a\x2e\x74\x65\x73\x74\x28\x74\x68\x69\x73\x2e\ \x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x29\x7b\x69\x66\x28\x74\x68\ \x69\x73\x2e\x74\x79\x70\x65\x3d\x3d\x3d\x22\x63\x68\x65\x63\x6b\ \x62\x6f\x78\x22\x7c\x7c\x74\x68\x69\x73\x2e\x74\x79\x70\x65\x3d\ \x3d\x3d\x22\x72\x61\x64\x69\x6f\x22\x29\x66\x2e\x65\x76\x65\x6e\ \x74\x2e\x61\x64\x64\x28\x74\x68\x69\x73\x2c\x22\x70\x72\x6f\x70\ \x65\x72\x74\x79\x63\x68\x61\x6e\x67\x65\x2e\x5f\x63\x68\x61\x6e\ \x67\x65\x22\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\ \x61\x2e\x6f\x72\x69\x67\x69\x6e\x61\x6c\x45\x76\x65\x6e\x74\x2e\ \x70\x72\x6f\x70\x65\x72\x74\x79\x4e\x61\x6d\x65\x3d\x3d\x3d\x22\ \x63\x68\x65\x63\x6b\x65\x64\x22\x26\x26\x28\x74\x68\x69\x73\x2e\ \x5f\x6a\x75\x73\x74\x5f\x63\x68\x61\x6e\x67\x65\x64\x3d\x21\x30\ \x29\x7d\x29\x2c\x66\x2e\x65\x76\x65\x6e\x74\x2e\x61\x64\x64\x28\ \x74\x68\x69\x73\x2c\x22\x63\x6c\x69\x63\x6b\x2e\x5f\x63\x68\x61\ \x6e\x67\x65\x22\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x74\x68\x69\x73\x2e\x5f\x6a\x75\x73\x74\x5f\x63\x68\x61\x6e\ \x67\x65\x64\x26\x26\x21\x61\x2e\x69\x73\x54\x72\x69\x67\x67\x65\ \x72\x26\x26\x28\x74\x68\x69\x73\x2e\x5f\x6a\x75\x73\x74\x5f\x63\ \x68\x61\x6e\x67\x65\x64\x3d\x21\x31\x2c\x66\x2e\x65\x76\x65\x6e\ \x74\x2e\x73\x69\x6d\x75\x6c\x61\x74\x65\x28\x22\x63\x68\x61\x6e\ \x67\x65\x22\x2c\x74\x68\x69\x73\x2c\x61\x2c\x21\x30\x29\x29\x7d\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x21\x31\x7d\x66\x2e\x65\x76\x65\ \x6e\x74\x2e\x61\x64\x64\x28\x74\x68\x69\x73\x2c\x22\x62\x65\x66\ \x6f\x72\x65\x61\x63\x74\x69\x76\x61\x74\x65\x2e\x5f\x63\x68\x61\ \x6e\x67\x65\x22\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x76\x61\x72\x20\x62\x3d\x61\x2e\x74\x61\x72\x67\x65\x74\x3b\ \x7a\x2e\x74\x65\x73\x74\x28\x62\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\ \x65\x29\x26\x26\x21\x62\x2e\x5f\x63\x68\x61\x6e\x67\x65\x5f\x61\ \x74\x74\x61\x63\x68\x65\x64\x26\x26\x28\x66\x2e\x65\x76\x65\x6e\ \x74\x2e\x61\x64\x64\x28\x62\x2c\x22\x63\x68\x61\x6e\x67\x65\x2e\ \x5f\x63\x68\x61\x6e\x67\x65\x22\x2c\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x29\x7b\x74\x68\x69\x73\x2e\x70\x61\x72\x65\x6e\x74\ \x4e\x6f\x64\x65\x26\x26\x21\x61\x2e\x69\x73\x53\x69\x6d\x75\x6c\ \x61\x74\x65\x64\x26\x26\x21\x61\x2e\x69\x73\x54\x72\x69\x67\x67\ \x65\x72\x26\x26\x66\x2e\x65\x76\x65\x6e\x74\x2e\x73\x69\x6d\x75\ \x6c\x61\x74\x65\x28\x22\x63\x68\x61\x6e\x67\x65\x22\x2c\x74\x68\ \x69\x73\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x2c\x61\x2c\ \x21\x30\x29\x7d\x29\x2c\x62\x2e\x5f\x63\x68\x61\x6e\x67\x65\x5f\ \x61\x74\x74\x61\x63\x68\x65\x64\x3d\x21\x30\x29\x7d\x29\x7d\x2c\ \x68\x61\x6e\x64\x6c\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x29\x7b\x76\x61\x72\x20\x62\x3d\x61\x2e\x74\x61\x72\x67\x65\ \x74\x3b\x69\x66\x28\x74\x68\x69\x73\x21\x3d\x3d\x62\x7c\x7c\x61\ \x2e\x69\x73\x53\x69\x6d\x75\x6c\x61\x74\x65\x64\x7c\x7c\x61\x2e\ \x69\x73\x54\x72\x69\x67\x67\x65\x72\x7c\x7c\x62\x2e\x74\x79\x70\ \x65\x21\x3d\x3d\x22\x72\x61\x64\x69\x6f\x22\x26\x26\x62\x2e\x74\ \x79\x70\x65\x21\x3d\x3d\x22\x63\x68\x65\x63\x6b\x62\x6f\x78\x22\ \x29\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x68\x61\x6e\x64\x6c\x65\ \x4f\x62\x6a\x2e\x68\x61\x6e\x64\x6c\x65\x72\x2e\x61\x70\x70\x6c\ \x79\x28\x74\x68\x69\x73\x2c\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\ \x29\x7d\x2c\x74\x65\x61\x72\x64\x6f\x77\x6e\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x29\x7b\x66\x2e\x65\x76\x65\x6e\x74\x2e\x72\ \x65\x6d\x6f\x76\x65\x28\x74\x68\x69\x73\x2c\x22\x2e\x5f\x63\x68\ \x61\x6e\x67\x65\x22\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x7a\x2e\ \x74\x65\x73\x74\x28\x74\x68\x69\x73\x2e\x6e\x6f\x64\x65\x4e\x61\ \x6d\x65\x29\x7d\x7d\x29\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\ \x2e\x66\x6f\x63\x75\x73\x69\x6e\x42\x75\x62\x62\x6c\x65\x73\x7c\ \x7c\x66\x2e\x65\x61\x63\x68\x28\x7b\x66\x6f\x63\x75\x73\x3a\x22\ \x66\x6f\x63\x75\x73\x69\x6e\x22\x2c\x62\x6c\x75\x72\x3a\x22\x66\ \x6f\x63\x75\x73\x6f\x75\x74\x22\x7d\x2c\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x64\x3d\x30\x2c\ \x65\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x66\x2e\ \x65\x76\x65\x6e\x74\x2e\x73\x69\x6d\x75\x6c\x61\x74\x65\x28\x62\ \x2c\x61\x2e\x74\x61\x72\x67\x65\x74\x2c\x66\x2e\x65\x76\x65\x6e\ \x74\x2e\x66\x69\x78\x28\x61\x29\x2c\x21\x30\x29\x7d\x3b\x66\x2e\ \x65\x76\x65\x6e\x74\x2e\x73\x70\x65\x63\x69\x61\x6c\x5b\x62\x5d\ \x3d\x7b\x73\x65\x74\x75\x70\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x64\x2b\x2b\x3d\x3d\x3d\x30\x26\x26\x63\x2e\x61\x64\ \x64\x45\x76\x65\x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72\x28\x61\ \x2c\x65\x2c\x21\x30\x29\x7d\x2c\x74\x65\x61\x72\x64\x6f\x77\x6e\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x2d\x2d\x64\x3d\ \x3d\x3d\x30\x26\x26\x63\x2e\x72\x65\x6d\x6f\x76\x65\x45\x76\x65\ \x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72\x28\x61\x2c\x65\x2c\x21\ \x30\x29\x7d\x7d\x7d\x29\x2c\x66\x2e\x66\x6e\x2e\x65\x78\x74\x65\ \x6e\x64\x28\x7b\x6f\x6e\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x63\x2c\x64\x2c\x65\x2c\x67\x29\x7b\x76\x61\x72\x20\x68\ \x2c\x69\x3b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\ \x22\x6f\x62\x6a\x65\x63\x74\x22\x29\x7b\x74\x79\x70\x65\x6f\x66\ \x20\x63\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x28\x64\ \x3d\x63\x2c\x63\x3d\x62\x29\x3b\x66\x6f\x72\x28\x69\x20\x69\x6e\ \x20\x61\x29\x74\x68\x69\x73\x2e\x6f\x6e\x28\x69\x2c\x63\x2c\x64\ \x2c\x61\x5b\x69\x5d\x2c\x67\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x7d\x64\x3d\x3d\x6e\x75\x6c\x6c\x26\x26\x65\x3d\ \x3d\x6e\x75\x6c\x6c\x3f\x28\x65\x3d\x63\x2c\x64\x3d\x63\x3d\x62\ \x29\x3a\x65\x3d\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x74\x79\x70\x65\ \x6f\x66\x20\x63\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x3f\x28\ \x65\x3d\x64\x2c\x64\x3d\x62\x29\x3a\x28\x65\x3d\x64\x2c\x64\x3d\ \x63\x2c\x63\x3d\x62\x29\x29\x3b\x69\x66\x28\x65\x3d\x3d\x3d\x21\ \x31\x29\x65\x3d\x4a\x3b\x65\x6c\x73\x65\x20\x69\x66\x28\x21\x65\ \x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x3b\x67\x3d\x3d\ \x3d\x31\x26\x26\x28\x68\x3d\x65\x2c\x65\x3d\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x66\x28\x29\x2e\x6f\x66\x66\x28\x61\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x68\x2e\x61\x70\x70\x6c\x79\ \x28\x74\x68\x69\x73\x2c\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\ \x7d\x2c\x65\x2e\x67\x75\x69\x64\x3d\x68\x2e\x67\x75\x69\x64\x7c\ \x7c\x28\x68\x2e\x67\x75\x69\x64\x3d\x66\x2e\x67\x75\x69\x64\x2b\ \x2b\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\ \x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\ \x66\x2e\x65\x76\x65\x6e\x74\x2e\x61\x64\x64\x28\x74\x68\x69\x73\ \x2c\x61\x2c\x65\x2c\x64\x2c\x63\x29\x7d\x29\x7d\x2c\x6f\x6e\x65\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\ \x64\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x6f\ \x6e\x2e\x63\x61\x6c\x6c\x28\x74\x68\x69\x73\x2c\x61\x2c\x62\x2c\ \x63\x2c\x64\x2c\x31\x29\x7d\x2c\x6f\x66\x66\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x63\x2c\x64\x29\x7b\x69\x66\x28\x61\ \x26\x26\x61\x2e\x70\x72\x65\x76\x65\x6e\x74\x44\x65\x66\x61\x75\ \x6c\x74\x26\x26\x61\x2e\x68\x61\x6e\x64\x6c\x65\x4f\x62\x6a\x29\ \x7b\x76\x61\x72\x20\x65\x3d\x61\x2e\x68\x61\x6e\x64\x6c\x65\x4f\ \x62\x6a\x3b\x66\x28\x61\x2e\x64\x65\x6c\x65\x67\x61\x74\x65\x54\ \x61\x72\x67\x65\x74\x29\x2e\x6f\x66\x66\x28\x65\x2e\x6e\x61\x6d\ \x65\x73\x70\x61\x63\x65\x3f\x65\x2e\x74\x79\x70\x65\x2b\x22\x2e\ \x22\x2b\x65\x2e\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x3a\x65\x2e\ \x74\x79\x70\x65\x2c\x65\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x2c\ \x65\x2e\x68\x61\x6e\x64\x6c\x65\x72\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x74\x68\x69\x73\x7d\x69\x66\x28\x74\x79\x70\x65\x6f\x66\ \x20\x61\x3d\x3d\x22\x6f\x62\x6a\x65\x63\x74\x22\x29\x7b\x66\x6f\ \x72\x28\x76\x61\x72\x20\x67\x20\x69\x6e\x20\x61\x29\x74\x68\x69\ \x73\x2e\x6f\x66\x66\x28\x67\x2c\x63\x2c\x61\x5b\x67\x5d\x29\x3b\ \x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x69\x66\x28\x63\ \x3d\x3d\x3d\x21\x31\x7c\x7c\x74\x79\x70\x65\x6f\x66\x20\x63\x3d\ \x3d\x22\x66\x75\x6e\x63\x74\x69\x6f\x6e\x22\x29\x64\x3d\x63\x2c\ \x63\x3d\x62\x3b\x64\x3d\x3d\x3d\x21\x31\x26\x26\x28\x64\x3d\x4a\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\ \x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\x2e\ \x65\x76\x65\x6e\x74\x2e\x72\x65\x6d\x6f\x76\x65\x28\x74\x68\x69\ \x73\x2c\x61\x2c\x64\x2c\x63\x29\x7d\x29\x7d\x2c\x62\x69\x6e\x64\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x6f\x6e\x28\ \x61\x2c\x6e\x75\x6c\x6c\x2c\x62\x2c\x63\x29\x7d\x2c\x75\x6e\x62\ \x69\x6e\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x6f\x66\ \x66\x28\x61\x2c\x6e\x75\x6c\x6c\x2c\x62\x29\x7d\x2c\x6c\x69\x76\ \x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\ \x29\x7b\x66\x28\x74\x68\x69\x73\x2e\x63\x6f\x6e\x74\x65\x78\x74\ \x29\x2e\x6f\x6e\x28\x61\x2c\x74\x68\x69\x73\x2e\x73\x65\x6c\x65\ \x63\x74\x6f\x72\x2c\x62\x2c\x63\x29\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x74\x68\x69\x73\x7d\x2c\x64\x69\x65\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x66\x28\x74\x68\x69\x73\x2e\ \x63\x6f\x6e\x74\x65\x78\x74\x29\x2e\x6f\x66\x66\x28\x61\x2c\x74\ \x68\x69\x73\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x7c\x7c\x22\x2a\ \x2a\x22\x2c\x62\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x7d\x2c\x64\x65\x6c\x65\x67\x61\x74\x65\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\x7b\x72\x65\ \x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x6f\x6e\x28\x62\x2c\x61\ \x2c\x63\x2c\x64\x29\x7d\x2c\x75\x6e\x64\x65\x6c\x65\x67\x61\x74\ \x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x72\x67\x75\x6d\x65\x6e\ \x74\x73\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x3d\x31\x3f\x74\x68\x69\ \x73\x2e\x6f\x66\x66\x28\x61\x2c\x22\x2a\x2a\x22\x29\x3a\x74\x68\ \x69\x73\x2e\x6f\x66\x66\x28\x62\x2c\x61\x2c\x63\x29\x7d\x2c\x74\ \x72\x69\x67\x67\x65\x72\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\ \x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\ \x7b\x66\x2e\x65\x76\x65\x6e\x74\x2e\x74\x72\x69\x67\x67\x65\x72\ \x28\x61\x2c\x62\x2c\x74\x68\x69\x73\x29\x7d\x29\x7d\x2c\x74\x72\ \x69\x67\x67\x65\x72\x48\x61\x6e\x64\x6c\x65\x72\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x69\x66\x28\x74\x68\ \x69\x73\x5b\x30\x5d\x29\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x65\ \x76\x65\x6e\x74\x2e\x74\x72\x69\x67\x67\x65\x72\x28\x61\x2c\x62\ \x2c\x74\x68\x69\x73\x5b\x30\x5d\x2c\x21\x30\x29\x7d\x2c\x74\x6f\ \x67\x67\x6c\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x76\x61\x72\x20\x62\x3d\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\ \x2c\x63\x3d\x61\x2e\x67\x75\x69\x64\x7c\x7c\x66\x2e\x67\x75\x69\ \x64\x2b\x2b\x2c\x64\x3d\x30\x2c\x65\x3d\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x63\x29\x7b\x76\x61\x72\x20\x65\x3d\x28\x66\x2e\x5f\ \x64\x61\x74\x61\x28\x74\x68\x69\x73\x2c\x22\x6c\x61\x73\x74\x54\ \x6f\x67\x67\x6c\x65\x22\x2b\x61\x2e\x67\x75\x69\x64\x29\x7c\x7c\ \x30\x29\x25\x64\x3b\x66\x2e\x5f\x64\x61\x74\x61\x28\x74\x68\x69\ \x73\x2c\x22\x6c\x61\x73\x74\x54\x6f\x67\x67\x6c\x65\x22\x2b\x61\ \x2e\x67\x75\x69\x64\x2c\x65\x2b\x31\x29\x2c\x63\x2e\x70\x72\x65\ \x76\x65\x6e\x74\x44\x65\x66\x61\x75\x6c\x74\x28\x29\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x62\x5b\x65\x5d\x2e\x61\x70\x70\x6c\x79\x28\ \x74\x68\x69\x73\x2c\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x7c\ \x7c\x21\x31\x7d\x3b\x65\x2e\x67\x75\x69\x64\x3d\x63\x3b\x77\x68\ \x69\x6c\x65\x28\x64\x3c\x62\x2e\x6c\x65\x6e\x67\x74\x68\x29\x62\ \x5b\x64\x2b\x2b\x5d\x2e\x67\x75\x69\x64\x3d\x63\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x63\x6c\x69\x63\x6b\x28\x65\ \x29\x7d\x2c\x68\x6f\x76\x65\x72\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\ \x69\x73\x2e\x6d\x6f\x75\x73\x65\x65\x6e\x74\x65\x72\x28\x61\x29\ \x2e\x6d\x6f\x75\x73\x65\x6c\x65\x61\x76\x65\x28\x62\x7c\x7c\x61\ \x29\x7d\x7d\x29\x2c\x66\x2e\x65\x61\x63\x68\x28\x22\x62\x6c\x75\ \x72\x20\x66\x6f\x63\x75\x73\x20\x66\x6f\x63\x75\x73\x69\x6e\x20\ \x66\x6f\x63\x75\x73\x6f\x75\x74\x20\x6c\x6f\x61\x64\x20\x72\x65\ \x73\x69\x7a\x65\x20\x73\x63\x72\x6f\x6c\x6c\x20\x75\x6e\x6c\x6f\ \x61\x64\x20\x63\x6c\x69\x63\x6b\x20\x64\x62\x6c\x63\x6c\x69\x63\ \x6b\x20\x6d\x6f\x75\x73\x65\x64\x6f\x77\x6e\x20\x6d\x6f\x75\x73\ \x65\x75\x70\x20\x6d\x6f\x75\x73\x65\x6d\x6f\x76\x65\x20\x6d\x6f\ \x75\x73\x65\x6f\x76\x65\x72\x20\x6d\x6f\x75\x73\x65\x6f\x75\x74\ \x20\x6d\x6f\x75\x73\x65\x65\x6e\x74\x65\x72\x20\x6d\x6f\x75\x73\ \x65\x6c\x65\x61\x76\x65\x20\x63\x68\x61\x6e\x67\x65\x20\x73\x65\ \x6c\x65\x63\x74\x20\x73\x75\x62\x6d\x69\x74\x20\x6b\x65\x79\x64\ \x6f\x77\x6e\x20\x6b\x65\x79\x70\x72\x65\x73\x73\x20\x6b\x65\x79\ \x75\x70\x20\x65\x72\x72\x6f\x72\x20\x63\x6f\x6e\x74\x65\x78\x74\ \x6d\x65\x6e\x75\x22\x2e\x73\x70\x6c\x69\x74\x28\x22\x20\x22\x29\ \x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x66\ \x2e\x66\x6e\x5b\x62\x5d\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x63\x29\x7b\x63\x3d\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x63\ \x3d\x61\x2c\x61\x3d\x6e\x75\x6c\x6c\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2e\x6c\x65\x6e\x67\ \x74\x68\x3e\x30\x3f\x74\x68\x69\x73\x2e\x6f\x6e\x28\x62\x2c\x6e\ \x75\x6c\x6c\x2c\x61\x2c\x63\x29\x3a\x74\x68\x69\x73\x2e\x74\x72\ \x69\x67\x67\x65\x72\x28\x62\x29\x7d\x2c\x66\x2e\x61\x74\x74\x72\ \x46\x6e\x26\x26\x28\x66\x2e\x61\x74\x74\x72\x46\x6e\x5b\x62\x5d\ \x3d\x21\x30\x29\x2c\x43\x2e\x74\x65\x73\x74\x28\x62\x29\x26\x26\ \x28\x66\x2e\x65\x76\x65\x6e\x74\x2e\x66\x69\x78\x48\x6f\x6f\x6b\ \x73\x5b\x62\x5d\x3d\x66\x2e\x65\x76\x65\x6e\x74\x2e\x6b\x65\x79\ \x48\x6f\x6f\x6b\x73\x29\x2c\x44\x2e\x74\x65\x73\x74\x28\x62\x29\ \x26\x26\x28\x66\x2e\x65\x76\x65\x6e\x74\x2e\x66\x69\x78\x48\x6f\ \x6f\x6b\x73\x5b\x62\x5d\x3d\x66\x2e\x65\x76\x65\x6e\x74\x2e\x6d\ \x6f\x75\x73\x65\x48\x6f\x6f\x6b\x73\x29\x7d\x29\x2c\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x20\x78\x28\x61\x2c\x62\x2c\x63\x2c\x65\x2c\x66\x2c\x67\x29\x7b\ \x66\x6f\x72\x28\x76\x61\x72\x20\x68\x3d\x30\x2c\x69\x3d\x65\x2e\ \x6c\x65\x6e\x67\x74\x68\x3b\x68\x3c\x69\x3b\x68\x2b\x2b\x29\x7b\ \x76\x61\x72\x20\x6a\x3d\x65\x5b\x68\x5d\x3b\x69\x66\x28\x6a\x29\ \x7b\x76\x61\x72\x20\x6b\x3d\x21\x31\x3b\x6a\x3d\x6a\x5b\x61\x5d\ \x3b\x77\x68\x69\x6c\x65\x28\x6a\x29\x7b\x69\x66\x28\x6a\x5b\x64\ \x5d\x3d\x3d\x3d\x63\x29\x7b\x6b\x3d\x65\x5b\x6a\x2e\x73\x69\x7a\ \x73\x65\x74\x5d\x3b\x62\x72\x65\x61\x6b\x7d\x69\x66\x28\x6a\x2e\ \x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\x7b\x67\x7c\ \x7c\x28\x6a\x5b\x64\x5d\x3d\x63\x2c\x6a\x2e\x73\x69\x7a\x73\x65\ \x74\x3d\x68\x29\x3b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x62\ \x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x29\x7b\x69\x66\x28\x6a\ \x3d\x3d\x3d\x62\x29\x7b\x6b\x3d\x21\x30\x3b\x62\x72\x65\x61\x6b\ \x7d\x7d\x65\x6c\x73\x65\x20\x69\x66\x28\x6d\x2e\x66\x69\x6c\x74\ \x65\x72\x28\x62\x2c\x5b\x6a\x5d\x29\x2e\x6c\x65\x6e\x67\x74\x68\ \x3e\x30\x29\x7b\x6b\x3d\x6a\x3b\x62\x72\x65\x61\x6b\x7d\x7d\x6a\ \x3d\x6a\x5b\x61\x5d\x7d\x65\x5b\x68\x5d\x3d\x6b\x7d\x7d\x7d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x20\x77\x28\x61\x2c\x62\x2c\x63\x2c\ \x65\x2c\x66\x2c\x67\x29\x7b\x66\x6f\x72\x28\x76\x61\x72\x20\x68\ \x3d\x30\x2c\x69\x3d\x65\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x68\x3c\ \x69\x3b\x68\x2b\x2b\x29\x7b\x76\x61\x72\x20\x6a\x3d\x65\x5b\x68\ \x5d\x3b\x69\x66\x28\x6a\x29\x7b\x76\x61\x72\x20\x6b\x3d\x21\x31\ \x3b\x6a\x3d\x6a\x5b\x61\x5d\x3b\x77\x68\x69\x6c\x65\x28\x6a\x29\ \x7b\x69\x66\x28\x6a\x5b\x64\x5d\x3d\x3d\x3d\x63\x29\x7b\x6b\x3d\ \x65\x5b\x6a\x2e\x73\x69\x7a\x73\x65\x74\x5d\x3b\x62\x72\x65\x61\ \x6b\x7d\x6a\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\ \x26\x26\x21\x67\x26\x26\x28\x6a\x5b\x64\x5d\x3d\x63\x2c\x6a\x2e\ \x73\x69\x7a\x73\x65\x74\x3d\x68\x29\x3b\x69\x66\x28\x6a\x2e\x6e\ \x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\ \x61\x73\x65\x28\x29\x3d\x3d\x3d\x62\x29\x7b\x6b\x3d\x6a\x3b\x62\ \x72\x65\x61\x6b\x7d\x6a\x3d\x6a\x5b\x61\x5d\x7d\x65\x5b\x68\x5d\ \x3d\x6b\x7d\x7d\x7d\x76\x61\x72\x20\x61\x3d\x2f\x28\x28\x3f\x3a\ \x5c\x28\x28\x3f\x3a\x5c\x28\x5b\x5e\x28\x29\x5d\x2b\x5c\x29\x7c\ \x5b\x5e\x28\x29\x5d\x2b\x29\x2b\x5c\x29\x7c\x5c\x5b\x28\x3f\x3a\ \x5c\x5b\x5b\x5e\x5c\x5b\x5c\x5d\x5d\x2a\x5c\x5d\x7c\x5b\x27\x22\ \x5d\x5b\x5e\x27\x22\x5d\x2a\x5b\x27\x22\x5d\x7c\x5b\x5e\x5c\x5b\ \x5c\x5d\x27\x22\x5d\x2b\x29\x2b\x5c\x5d\x7c\x5c\x5c\x2e\x7c\x5b\ \x5e\x20\x3e\x2b\x7e\x2c\x28\x5c\x5b\x5c\x5c\x5d\x2b\x29\x2b\x7c\ \x5b\x3e\x2b\x7e\x5d\x29\x28\x5c\x73\x2a\x2c\x5c\x73\x2a\x29\x3f\ \x28\x28\x3f\x3a\x2e\x7c\x5c\x72\x7c\x5c\x6e\x29\x2a\x29\x2f\x67\ \x2c\x64\x3d\x22\x73\x69\x7a\x63\x61\x63\x68\x65\x22\x2b\x28\x4d\ \x61\x74\x68\x2e\x72\x61\x6e\x64\x6f\x6d\x28\x29\x2b\x22\x22\x29\ \x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x22\x2e\x22\x2c\x22\x22\x29\ \x2c\x65\x3d\x30\x2c\x67\x3d\x4f\x62\x6a\x65\x63\x74\x2e\x70\x72\ \x6f\x74\x6f\x74\x79\x70\x65\x2e\x74\x6f\x53\x74\x72\x69\x6e\x67\ \x2c\x68\x3d\x21\x31\x2c\x69\x3d\x21\x30\x2c\x6a\x3d\x2f\x5c\x5c\ \x2f\x67\x2c\x6b\x3d\x2f\x5c\x72\x5c\x6e\x2f\x67\x2c\x6c\x3d\x2f\ \x5c\x57\x2f\x3b\x5b\x30\x2c\x30\x5d\x2e\x73\x6f\x72\x74\x28\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x3d\x21\x31\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x30\x7d\x29\x3b\x76\x61\x72\x20\x6d\x3d\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x2c\x64\x2c\x65\x2c\x66\ \x29\x7b\x65\x3d\x65\x7c\x7c\x5b\x5d\x2c\x64\x3d\x64\x7c\x7c\x63\ \x3b\x76\x61\x72\x20\x68\x3d\x64\x3b\x69\x66\x28\x64\x2e\x6e\x6f\ \x64\x65\x54\x79\x70\x65\x21\x3d\x3d\x31\x26\x26\x64\x2e\x6e\x6f\ \x64\x65\x54\x79\x70\x65\x21\x3d\x3d\x39\x29\x72\x65\x74\x75\x72\ \x6e\x5b\x5d\x3b\x69\x66\x28\x21\x62\x7c\x7c\x74\x79\x70\x65\x6f\ \x66\x20\x62\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x29\x72\x65\ \x74\x75\x72\x6e\x20\x65\x3b\x76\x61\x72\x20\x69\x2c\x6a\x2c\x6b\ \x2c\x6c\x2c\x6e\x2c\x71\x2c\x72\x2c\x74\x2c\x75\x3d\x21\x30\x2c\ \x76\x3d\x6d\x2e\x69\x73\x58\x4d\x4c\x28\x64\x29\x2c\x77\x3d\x5b\ \x5d\x2c\x78\x3d\x62\x3b\x64\x6f\x7b\x61\x2e\x65\x78\x65\x63\x28\ \x22\x22\x29\x2c\x69\x3d\x61\x2e\x65\x78\x65\x63\x28\x78\x29\x3b\ \x69\x66\x28\x69\x29\x7b\x78\x3d\x69\x5b\x33\x5d\x2c\x77\x2e\x70\ \x75\x73\x68\x28\x69\x5b\x31\x5d\x29\x3b\x69\x66\x28\x69\x5b\x32\ \x5d\x29\x7b\x6c\x3d\x69\x5b\x33\x5d\x3b\x62\x72\x65\x61\x6b\x7d\ \x7d\x7d\x77\x68\x69\x6c\x65\x28\x69\x29\x3b\x69\x66\x28\x77\x2e\ \x6c\x65\x6e\x67\x74\x68\x3e\x31\x26\x26\x70\x2e\x65\x78\x65\x63\ \x28\x62\x29\x29\x69\x66\x28\x77\x2e\x6c\x65\x6e\x67\x74\x68\x3d\ \x3d\x3d\x32\x26\x26\x6f\x2e\x72\x65\x6c\x61\x74\x69\x76\x65\x5b\ \x77\x5b\x30\x5d\x5d\x29\x6a\x3d\x79\x28\x77\x5b\x30\x5d\x2b\x77\ \x5b\x31\x5d\x2c\x64\x2c\x66\x29\x3b\x65\x6c\x73\x65\x7b\x6a\x3d\ \x6f\x2e\x72\x65\x6c\x61\x74\x69\x76\x65\x5b\x77\x5b\x30\x5d\x5d\ \x3f\x5b\x64\x5d\x3a\x6d\x28\x77\x2e\x73\x68\x69\x66\x74\x28\x29\ \x2c\x64\x29\x3b\x77\x68\x69\x6c\x65\x28\x77\x2e\x6c\x65\x6e\x67\ \x74\x68\x29\x62\x3d\x77\x2e\x73\x68\x69\x66\x74\x28\x29\x2c\x6f\ \x2e\x72\x65\x6c\x61\x74\x69\x76\x65\x5b\x62\x5d\x26\x26\x28\x62\ \x2b\x3d\x77\x2e\x73\x68\x69\x66\x74\x28\x29\x29\x2c\x6a\x3d\x79\ \x28\x62\x2c\x6a\x2c\x66\x29\x7d\x65\x6c\x73\x65\x7b\x21\x66\x26\ \x26\x77\x2e\x6c\x65\x6e\x67\x74\x68\x3e\x31\x26\x26\x64\x2e\x6e\ \x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x39\x26\x26\x21\x76\x26\ \x26\x6f\x2e\x6d\x61\x74\x63\x68\x2e\x49\x44\x2e\x74\x65\x73\x74\ \x28\x77\x5b\x30\x5d\x29\x26\x26\x21\x6f\x2e\x6d\x61\x74\x63\x68\ \x2e\x49\x44\x2e\x74\x65\x73\x74\x28\x77\x5b\x77\x2e\x6c\x65\x6e\ \x67\x74\x68\x2d\x31\x5d\x29\x26\x26\x28\x6e\x3d\x6d\x2e\x66\x69\ \x6e\x64\x28\x77\x2e\x73\x68\x69\x66\x74\x28\x29\x2c\x64\x2c\x76\ \x29\x2c\x64\x3d\x6e\x2e\x65\x78\x70\x72\x3f\x6d\x2e\x66\x69\x6c\ \x74\x65\x72\x28\x6e\x2e\x65\x78\x70\x72\x2c\x6e\x2e\x73\x65\x74\ \x29\x5b\x30\x5d\x3a\x6e\x2e\x73\x65\x74\x5b\x30\x5d\x29\x3b\x69\ \x66\x28\x64\x29\x7b\x6e\x3d\x66\x3f\x7b\x65\x78\x70\x72\x3a\x77\ \x2e\x70\x6f\x70\x28\x29\x2c\x73\x65\x74\x3a\x73\x28\x66\x29\x7d\ \x3a\x6d\x2e\x66\x69\x6e\x64\x28\x77\x2e\x70\x6f\x70\x28\x29\x2c\ \x77\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x3d\x3d\x31\x26\x26\x28\x77\ \x5b\x30\x5d\x3d\x3d\x3d\x22\x7e\x22\x7c\x7c\x77\x5b\x30\x5d\x3d\ \x3d\x3d\x22\x2b\x22\x29\x26\x26\x64\x2e\x70\x61\x72\x65\x6e\x74\ \x4e\x6f\x64\x65\x3f\x64\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\ \x65\x3a\x64\x2c\x76\x29\x2c\x6a\x3d\x6e\x2e\x65\x78\x70\x72\x3f\ \x6d\x2e\x66\x69\x6c\x74\x65\x72\x28\x6e\x2e\x65\x78\x70\x72\x2c\ \x6e\x2e\x73\x65\x74\x29\x3a\x6e\x2e\x73\x65\x74\x2c\x77\x2e\x6c\ \x65\x6e\x67\x74\x68\x3e\x30\x3f\x6b\x3d\x73\x28\x6a\x29\x3a\x75\ \x3d\x21\x31\x3b\x77\x68\x69\x6c\x65\x28\x77\x2e\x6c\x65\x6e\x67\ \x74\x68\x29\x71\x3d\x77\x2e\x70\x6f\x70\x28\x29\x2c\x72\x3d\x71\ \x2c\x6f\x2e\x72\x65\x6c\x61\x74\x69\x76\x65\x5b\x71\x5d\x3f\x72\ \x3d\x77\x2e\x70\x6f\x70\x28\x29\x3a\x71\x3d\x22\x22\x2c\x72\x3d\ \x3d\x6e\x75\x6c\x6c\x26\x26\x28\x72\x3d\x64\x29\x2c\x6f\x2e\x72\ \x65\x6c\x61\x74\x69\x76\x65\x5b\x71\x5d\x28\x6b\x2c\x72\x2c\x76\ \x29\x7d\x65\x6c\x73\x65\x20\x6b\x3d\x77\x3d\x5b\x5d\x7d\x6b\x7c\ \x7c\x28\x6b\x3d\x6a\x29\x2c\x6b\x7c\x7c\x6d\x2e\x65\x72\x72\x6f\ \x72\x28\x71\x7c\x7c\x62\x29\x3b\x69\x66\x28\x67\x2e\x63\x61\x6c\ \x6c\x28\x6b\x29\x3d\x3d\x3d\x22\x5b\x6f\x62\x6a\x65\x63\x74\x20\ \x41\x72\x72\x61\x79\x5d\x22\x29\x69\x66\x28\x21\x75\x29\x65\x2e\ \x70\x75\x73\x68\x2e\x61\x70\x70\x6c\x79\x28\x65\x2c\x6b\x29\x3b\ \x65\x6c\x73\x65\x20\x69\x66\x28\x64\x26\x26\x64\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\x66\x6f\x72\x28\x74\x3d\ \x30\x3b\x6b\x5b\x74\x5d\x21\x3d\x6e\x75\x6c\x6c\x3b\x74\x2b\x2b\ \x29\x6b\x5b\x74\x5d\x26\x26\x28\x6b\x5b\x74\x5d\x3d\x3d\x3d\x21\ \x30\x7c\x7c\x6b\x5b\x74\x5d\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\ \x3d\x3d\x3d\x31\x26\x26\x6d\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\ \x28\x64\x2c\x6b\x5b\x74\x5d\x29\x29\x26\x26\x65\x2e\x70\x75\x73\ \x68\x28\x6a\x5b\x74\x5d\x29\x3b\x65\x6c\x73\x65\x20\x66\x6f\x72\ \x28\x74\x3d\x30\x3b\x6b\x5b\x74\x5d\x21\x3d\x6e\x75\x6c\x6c\x3b\ \x74\x2b\x2b\x29\x6b\x5b\x74\x5d\x26\x26\x6b\x5b\x74\x5d\x2e\x6e\ \x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\x26\x65\x2e\x70\ \x75\x73\x68\x28\x6a\x5b\x74\x5d\x29\x3b\x65\x6c\x73\x65\x20\x73\ \x28\x6b\x2c\x65\x29\x3b\x6c\x26\x26\x28\x6d\x28\x6c\x2c\x68\x2c\ \x65\x2c\x66\x29\x2c\x6d\x2e\x75\x6e\x69\x71\x75\x65\x53\x6f\x72\ \x74\x28\x65\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x65\x7d\x3b\ \x6d\x2e\x75\x6e\x69\x71\x75\x65\x53\x6f\x72\x74\x3d\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\x28\x75\x29\x7b\x68\ \x3d\x69\x2c\x61\x2e\x73\x6f\x72\x74\x28\x75\x29\x3b\x69\x66\x28\ \x68\x29\x66\x6f\x72\x28\x76\x61\x72\x20\x62\x3d\x31\x3b\x62\x3c\ \x61\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x62\x2b\x2b\x29\x61\x5b\x62\ \x5d\x3d\x3d\x3d\x61\x5b\x62\x2d\x31\x5d\x26\x26\x61\x2e\x73\x70\ \x6c\x69\x63\x65\x28\x62\x2d\x2d\x2c\x31\x29\x7d\x72\x65\x74\x75\ \x72\x6e\x20\x61\x7d\x2c\x6d\x2e\x6d\x61\x74\x63\x68\x65\x73\x3d\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\ \x74\x75\x72\x6e\x20\x6d\x28\x61\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\ \x6c\x6c\x2c\x62\x29\x7d\x2c\x6d\x2e\x6d\x61\x74\x63\x68\x65\x73\ \x53\x65\x6c\x65\x63\x74\x6f\x72\x3d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x6d\x28\ \x62\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x2c\x5b\x61\x5d\x29\ \x2e\x6c\x65\x6e\x67\x74\x68\x3e\x30\x7d\x2c\x6d\x2e\x66\x69\x6e\ \x64\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\ \x29\x7b\x76\x61\x72\x20\x64\x2c\x65\x2c\x66\x2c\x67\x2c\x68\x2c\ \x69\x3b\x69\x66\x28\x21\x61\x29\x72\x65\x74\x75\x72\x6e\x5b\x5d\ \x3b\x66\x6f\x72\x28\x65\x3d\x30\x2c\x66\x3d\x6f\x2e\x6f\x72\x64\ \x65\x72\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x65\x3c\x66\x3b\x65\x2b\ \x2b\x29\x7b\x68\x3d\x6f\x2e\x6f\x72\x64\x65\x72\x5b\x65\x5d\x3b\ \x69\x66\x28\x67\x3d\x6f\x2e\x6c\x65\x66\x74\x4d\x61\x74\x63\x68\ \x5b\x68\x5d\x2e\x65\x78\x65\x63\x28\x61\x29\x29\x7b\x69\x3d\x67\ \x5b\x31\x5d\x2c\x67\x2e\x73\x70\x6c\x69\x63\x65\x28\x31\x2c\x31\ \x29\x3b\x69\x66\x28\x69\x2e\x73\x75\x62\x73\x74\x72\x28\x69\x2e\ \x6c\x65\x6e\x67\x74\x68\x2d\x31\x29\x21\x3d\x3d\x22\x5c\x5c\x22\ \x29\x7b\x67\x5b\x31\x5d\x3d\x28\x67\x5b\x31\x5d\x7c\x7c\x22\x22\ \x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x6a\x2c\x22\x22\x29\x2c\ \x64\x3d\x6f\x2e\x66\x69\x6e\x64\x5b\x68\x5d\x28\x67\x2c\x62\x2c\ \x63\x29\x3b\x69\x66\x28\x64\x21\x3d\x6e\x75\x6c\x6c\x29\x7b\x61\ \x3d\x61\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x6f\x2e\x6d\x61\x74\ \x63\x68\x5b\x68\x5d\x2c\x22\x22\x29\x3b\x62\x72\x65\x61\x6b\x7d\ \x7d\x7d\x7d\x64\x7c\x7c\x28\x64\x3d\x74\x79\x70\x65\x6f\x66\x20\ \x62\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\ \x61\x67\x4e\x61\x6d\x65\x21\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\ \x65\x64\x22\x3f\x62\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\ \x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\x2a\x22\x29\x3a\ \x5b\x5d\x29\x3b\x72\x65\x74\x75\x72\x6e\x7b\x73\x65\x74\x3a\x64\ \x2c\x65\x78\x70\x72\x3a\x61\x7d\x7d\x2c\x6d\x2e\x66\x69\x6c\x74\ \x65\x72\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x2c\ \x64\x2c\x65\x29\x7b\x76\x61\x72\x20\x66\x2c\x67\x2c\x68\x2c\x69\ \x2c\x6a\x2c\x6b\x2c\x6c\x2c\x6e\x2c\x70\x2c\x71\x3d\x61\x2c\x72\ \x3d\x5b\x5d\x2c\x73\x3d\x63\x2c\x74\x3d\x63\x26\x26\x63\x5b\x30\ \x5d\x26\x26\x6d\x2e\x69\x73\x58\x4d\x4c\x28\x63\x5b\x30\x5d\x29\ \x3b\x77\x68\x69\x6c\x65\x28\x61\x26\x26\x63\x2e\x6c\x65\x6e\x67\ \x74\x68\x29\x7b\x66\x6f\x72\x28\x68\x20\x69\x6e\x20\x6f\x2e\x66\ \x69\x6c\x74\x65\x72\x29\x69\x66\x28\x28\x66\x3d\x6f\x2e\x6c\x65\ \x66\x74\x4d\x61\x74\x63\x68\x5b\x68\x5d\x2e\x65\x78\x65\x63\x28\ \x61\x29\x29\x21\x3d\x6e\x75\x6c\x6c\x26\x26\x66\x5b\x32\x5d\x29\ \x7b\x6b\x3d\x6f\x2e\x66\x69\x6c\x74\x65\x72\x5b\x68\x5d\x2c\x6c\ \x3d\x66\x5b\x31\x5d\x2c\x67\x3d\x21\x31\x2c\x66\x2e\x73\x70\x6c\ \x69\x63\x65\x28\x31\x2c\x31\x29\x3b\x69\x66\x28\x6c\x2e\x73\x75\ \x62\x73\x74\x72\x28\x6c\x2e\x6c\x65\x6e\x67\x74\x68\x2d\x31\x29\ \x3d\x3d\x3d\x22\x5c\x5c\x22\x29\x63\x6f\x6e\x74\x69\x6e\x75\x65\ \x3b\x73\x3d\x3d\x3d\x72\x26\x26\x28\x72\x3d\x5b\x5d\x29\x3b\x69\ \x66\x28\x6f\x2e\x70\x72\x65\x46\x69\x6c\x74\x65\x72\x5b\x68\x5d\ \x29\x7b\x66\x3d\x6f\x2e\x70\x72\x65\x46\x69\x6c\x74\x65\x72\x5b\ \x68\x5d\x28\x66\x2c\x73\x2c\x64\x2c\x72\x2c\x65\x2c\x74\x29\x3b\ \x69\x66\x28\x21\x66\x29\x67\x3d\x69\x3d\x21\x30\x3b\x65\x6c\x73\ \x65\x20\x69\x66\x28\x66\x3d\x3d\x3d\x21\x30\x29\x63\x6f\x6e\x74\ \x69\x6e\x75\x65\x7d\x69\x66\x28\x66\x29\x66\x6f\x72\x28\x6e\x3d\ \x30\x3b\x28\x6a\x3d\x73\x5b\x6e\x5d\x29\x21\x3d\x6e\x75\x6c\x6c\ \x3b\x6e\x2b\x2b\x29\x6a\x26\x26\x28\x69\x3d\x6b\x28\x6a\x2c\x66\ \x2c\x6e\x2c\x73\x29\x2c\x70\x3d\x65\x5e\x69\x2c\x64\x26\x26\x69\ \x21\x3d\x6e\x75\x6c\x6c\x3f\x70\x3f\x67\x3d\x21\x30\x3a\x73\x5b\ \x6e\x5d\x3d\x21\x31\x3a\x70\x26\x26\x28\x72\x2e\x70\x75\x73\x68\ \x28\x6a\x29\x2c\x67\x3d\x21\x30\x29\x29\x3b\x69\x66\x28\x69\x21\ \x3d\x3d\x62\x29\x7b\x64\x7c\x7c\x28\x73\x3d\x72\x29\x2c\x61\x3d\ \x61\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x6f\x2e\x6d\x61\x74\x63\ \x68\x5b\x68\x5d\x2c\x22\x22\x29\x3b\x69\x66\x28\x21\x67\x29\x72\ \x65\x74\x75\x72\x6e\x5b\x5d\x3b\x62\x72\x65\x61\x6b\x7d\x7d\x69\ \x66\x28\x61\x3d\x3d\x3d\x71\x29\x69\x66\x28\x67\x3d\x3d\x6e\x75\ \x6c\x6c\x29\x6d\x2e\x65\x72\x72\x6f\x72\x28\x61\x29\x3b\x65\x6c\ \x73\x65\x20\x62\x72\x65\x61\x6b\x3b\x71\x3d\x61\x7d\x72\x65\x74\ \x75\x72\x6e\x20\x73\x7d\x2c\x6d\x2e\x65\x72\x72\x6f\x72\x3d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x74\x68\x72\x6f\x77\ \x20\x6e\x65\x77\x20\x45\x72\x72\x6f\x72\x28\x22\x53\x79\x6e\x74\ \x61\x78\x20\x65\x72\x72\x6f\x72\x2c\x20\x75\x6e\x72\x65\x63\x6f\ \x67\x6e\x69\x7a\x65\x64\x20\x65\x78\x70\x72\x65\x73\x73\x69\x6f\ \x6e\x3a\x20\x22\x2b\x61\x29\x7d\x3b\x76\x61\x72\x20\x6e\x3d\x6d\ \x2e\x67\x65\x74\x54\x65\x78\x74\x3d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x2c\x63\x2c\x64\x3d\x61\ \x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x2c\x65\x3d\x22\x22\x3b\x69\ \x66\x28\x64\x29\x7b\x69\x66\x28\x64\x3d\x3d\x3d\x31\x7c\x7c\x64\ \x3d\x3d\x3d\x39\x29\x7b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\ \x61\x2e\x74\x65\x78\x74\x43\x6f\x6e\x74\x65\x6e\x74\x3d\x3d\x22\ \x73\x74\x72\x69\x6e\x67\x22\x29\x72\x65\x74\x75\x72\x6e\x20\x61\ \x2e\x74\x65\x78\x74\x43\x6f\x6e\x74\x65\x6e\x74\x3b\x69\x66\x28\ \x74\x79\x70\x65\x6f\x66\x20\x61\x2e\x69\x6e\x6e\x65\x72\x54\x65\ \x78\x74\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x29\x72\x65\x74\ \x75\x72\x6e\x20\x61\x2e\x69\x6e\x6e\x65\x72\x54\x65\x78\x74\x2e\ \x72\x65\x70\x6c\x61\x63\x65\x28\x6b\x2c\x22\x22\x29\x3b\x66\x6f\ \x72\x28\x61\x3d\x61\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\ \x3b\x61\x3b\x61\x3d\x61\x2e\x6e\x65\x78\x74\x53\x69\x62\x6c\x69\ \x6e\x67\x29\x65\x2b\x3d\x6e\x28\x61\x29\x7d\x65\x6c\x73\x65\x20\ \x69\x66\x28\x64\x3d\x3d\x3d\x33\x7c\x7c\x64\x3d\x3d\x3d\x34\x29\ \x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x6e\x6f\x64\x65\x56\x61\x6c\ \x75\x65\x7d\x65\x6c\x73\x65\x20\x66\x6f\x72\x28\x62\x3d\x30\x3b\ \x63\x3d\x61\x5b\x62\x5d\x3b\x62\x2b\x2b\x29\x63\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x21\x3d\x3d\x38\x26\x26\x28\x65\x2b\x3d\x6e\ \x28\x63\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x65\x7d\x2c\x6f\ \x3d\x6d\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x73\x3d\x7b\x6f\x72\ \x64\x65\x72\x3a\x5b\x22\x49\x44\x22\x2c\x22\x4e\x41\x4d\x45\x22\ \x2c\x22\x54\x41\x47\x22\x5d\x2c\x6d\x61\x74\x63\x68\x3a\x7b\x49\ \x44\x3a\x2f\x23\x28\x28\x3f\x3a\x5b\x5c\x77\x5c\x75\x30\x30\x63\ \x30\x2d\x5c\x75\x46\x46\x46\x46\x5c\x2d\x5d\x7c\x5c\x5c\x2e\x29\ \x2b\x29\x2f\x2c\x43\x4c\x41\x53\x53\x3a\x2f\x5c\x2e\x28\x28\x3f\ \x3a\x5b\x5c\x77\x5c\x75\x30\x30\x63\x30\x2d\x5c\x75\x46\x46\x46\ \x46\x5c\x2d\x5d\x7c\x5c\x5c\x2e\x29\x2b\x29\x2f\x2c\x4e\x41\x4d\ \x45\x3a\x2f\x5c\x5b\x6e\x61\x6d\x65\x3d\x5b\x27\x22\x5d\x2a\x28\ \x28\x3f\x3a\x5b\x5c\x77\x5c\x75\x30\x30\x63\x30\x2d\x5c\x75\x46\ \x46\x46\x46\x5c\x2d\x5d\x7c\x5c\x5c\x2e\x29\x2b\x29\x5b\x27\x22\ \x5d\x2a\x5c\x5d\x2f\x2c\x41\x54\x54\x52\x3a\x2f\x5c\x5b\x5c\x73\ \x2a\x28\x28\x3f\x3a\x5b\x5c\x77\x5c\x75\x30\x30\x63\x30\x2d\x5c\ \x75\x46\x46\x46\x46\x5c\x2d\x5d\x7c\x5c\x5c\x2e\x29\x2b\x29\x5c\ \x73\x2a\x28\x3f\x3a\x28\x5c\x53\x3f\x3d\x29\x5c\x73\x2a\x28\x3f\ \x3a\x28\x5b\x27\x22\x5d\x29\x28\x2e\x2a\x3f\x29\x5c\x33\x7c\x28\ \x23\x3f\x28\x3f\x3a\x5b\x5c\x77\x5c\x75\x30\x30\x63\x30\x2d\x5c\ \x75\x46\x46\x46\x46\x5c\x2d\x5d\x7c\x5c\x5c\x2e\x29\x2a\x29\x7c\ \x29\x7c\x29\x5c\x73\x2a\x5c\x5d\x2f\x2c\x54\x41\x47\x3a\x2f\x5e\ \x28\x28\x3f\x3a\x5b\x5c\x77\x5c\x75\x30\x30\x63\x30\x2d\x5c\x75\ \x46\x46\x46\x46\x5c\x2a\x5c\x2d\x5d\x7c\x5c\x5c\x2e\x29\x2b\x29\ \x2f\x2c\x43\x48\x49\x4c\x44\x3a\x2f\x3a\x28\x6f\x6e\x6c\x79\x7c\ \x6e\x74\x68\x7c\x6c\x61\x73\x74\x7c\x66\x69\x72\x73\x74\x29\x2d\ \x63\x68\x69\x6c\x64\x28\x3f\x3a\x5c\x28\x5c\x73\x2a\x28\x65\x76\ \x65\x6e\x7c\x6f\x64\x64\x7c\x28\x3f\x3a\x5b\x2b\x5c\x2d\x5d\x3f\ \x5c\x64\x2b\x7c\x28\x3f\x3a\x5b\x2b\x5c\x2d\x5d\x3f\x5c\x64\x2a\ \x29\x3f\x6e\x5c\x73\x2a\x28\x3f\x3a\x5b\x2b\x5c\x2d\x5d\x5c\x73\ \x2a\x5c\x64\x2b\x29\x3f\x29\x29\x5c\x73\x2a\x5c\x29\x29\x3f\x2f\ \x2c\x50\x4f\x53\x3a\x2f\x3a\x28\x6e\x74\x68\x7c\x65\x71\x7c\x67\ \x74\x7c\x6c\x74\x7c\x66\x69\x72\x73\x74\x7c\x6c\x61\x73\x74\x7c\ \x65\x76\x65\x6e\x7c\x6f\x64\x64\x29\x28\x3f\x3a\x5c\x28\x28\x5c\ \x64\x2a\x29\x5c\x29\x29\x3f\x28\x3f\x3d\x5b\x5e\x5c\x2d\x5d\x7c\ \x24\x29\x2f\x2c\x50\x53\x45\x55\x44\x4f\x3a\x2f\x3a\x28\x28\x3f\ \x3a\x5b\x5c\x77\x5c\x75\x30\x30\x63\x30\x2d\x5c\x75\x46\x46\x46\ \x46\x5c\x2d\x5d\x7c\x5c\x5c\x2e\x29\x2b\x29\x28\x3f\x3a\x5c\x28\ \x28\x5b\x27\x22\x5d\x3f\x29\x28\x28\x3f\x3a\x5c\x28\x5b\x5e\x5c\ \x29\x5d\x2b\x5c\x29\x7c\x5b\x5e\x5c\x28\x5c\x29\x5d\x2a\x29\x2b\ \x29\x5c\x32\x5c\x29\x29\x3f\x2f\x7d\x2c\x6c\x65\x66\x74\x4d\x61\ \x74\x63\x68\x3a\x7b\x7d\x2c\x61\x74\x74\x72\x4d\x61\x70\x3a\x7b\ \x22\x63\x6c\x61\x73\x73\x22\x3a\x22\x63\x6c\x61\x73\x73\x4e\x61\ \x6d\x65\x22\x2c\x22\x66\x6f\x72\x22\x3a\x22\x68\x74\x6d\x6c\x46\ \x6f\x72\x22\x7d\x2c\x61\x74\x74\x72\x48\x61\x6e\x64\x6c\x65\x3a\ \x7b\x68\x72\x65\x66\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x67\x65\x74\x41\x74\ \x74\x72\x69\x62\x75\x74\x65\x28\x22\x68\x72\x65\x66\x22\x29\x7d\ \x2c\x74\x79\x70\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x67\x65\x74\x41\x74\ \x74\x72\x69\x62\x75\x74\x65\x28\x22\x74\x79\x70\x65\x22\x29\x7d\ \x7d\x2c\x72\x65\x6c\x61\x74\x69\x76\x65\x3a\x7b\x22\x2b\x22\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\ \x72\x20\x63\x3d\x74\x79\x70\x65\x6f\x66\x20\x62\x3d\x3d\x22\x73\ \x74\x72\x69\x6e\x67\x22\x2c\x64\x3d\x63\x26\x26\x21\x6c\x2e\x74\ \x65\x73\x74\x28\x62\x29\x2c\x65\x3d\x63\x26\x26\x21\x64\x3b\x64\ \x26\x26\x28\x62\x3d\x62\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\ \x73\x65\x28\x29\x29\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\x66\x3d\ \x30\x2c\x67\x3d\x61\x2e\x6c\x65\x6e\x67\x74\x68\x2c\x68\x3b\x66\ \x3c\x67\x3b\x66\x2b\x2b\x29\x69\x66\x28\x68\x3d\x61\x5b\x66\x5d\ \x29\x7b\x77\x68\x69\x6c\x65\x28\x28\x68\x3d\x68\x2e\x70\x72\x65\ \x76\x69\x6f\x75\x73\x53\x69\x62\x6c\x69\x6e\x67\x29\x26\x26\x68\ \x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x21\x3d\x3d\x31\x29\x3b\x61\ \x5b\x66\x5d\x3d\x65\x7c\x7c\x68\x26\x26\x68\x2e\x6e\x6f\x64\x65\ \x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\ \x28\x29\x3d\x3d\x3d\x62\x3f\x68\x7c\x7c\x21\x31\x3a\x68\x3d\x3d\ \x3d\x62\x7d\x65\x26\x26\x6d\x2e\x66\x69\x6c\x74\x65\x72\x28\x62\ \x2c\x61\x2c\x21\x30\x29\x7d\x2c\x22\x3e\x22\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x2c\ \x64\x3d\x74\x79\x70\x65\x6f\x66\x20\x62\x3d\x3d\x22\x73\x74\x72\ \x69\x6e\x67\x22\x2c\x65\x3d\x30\x2c\x66\x3d\x61\x2e\x6c\x65\x6e\ \x67\x74\x68\x3b\x69\x66\x28\x64\x26\x26\x21\x6c\x2e\x74\x65\x73\ \x74\x28\x62\x29\x29\x7b\x62\x3d\x62\x2e\x74\x6f\x4c\x6f\x77\x65\ \x72\x43\x61\x73\x65\x28\x29\x3b\x66\x6f\x72\x28\x3b\x65\x3c\x66\ \x3b\x65\x2b\x2b\x29\x7b\x63\x3d\x61\x5b\x65\x5d\x3b\x69\x66\x28\ \x63\x29\x7b\x76\x61\x72\x20\x67\x3d\x63\x2e\x70\x61\x72\x65\x6e\ \x74\x4e\x6f\x64\x65\x3b\x61\x5b\x65\x5d\x3d\x67\x2e\x6e\x6f\x64\ \x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\ \x65\x28\x29\x3d\x3d\x3d\x62\x3f\x67\x3a\x21\x31\x7d\x7d\x7d\x65\ \x6c\x73\x65\x7b\x66\x6f\x72\x28\x3b\x65\x3c\x66\x3b\x65\x2b\x2b\ \x29\x63\x3d\x61\x5b\x65\x5d\x2c\x63\x26\x26\x28\x61\x5b\x65\x5d\ \x3d\x64\x3f\x63\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x3a\ \x63\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x3d\x3d\x3d\x62\ \x29\x3b\x64\x26\x26\x6d\x2e\x66\x69\x6c\x74\x65\x72\x28\x62\x2c\ \x61\x2c\x21\x30\x29\x7d\x7d\x2c\x22\x22\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\ \x2c\x66\x3d\x65\x2b\x2b\x2c\x67\x3d\x78\x3b\x74\x79\x70\x65\x6f\ \x66\x20\x62\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x21\ \x6c\x2e\x74\x65\x73\x74\x28\x62\x29\x26\x26\x28\x62\x3d\x62\x2e\ \x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x2c\x64\x3d\ \x62\x2c\x67\x3d\x77\x29\x2c\x67\x28\x22\x70\x61\x72\x65\x6e\x74\ \x4e\x6f\x64\x65\x22\x2c\x62\x2c\x66\x2c\x61\x2c\x64\x2c\x63\x29\ \x7d\x2c\x22\x7e\x22\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x2c\x66\x3d\x65\x2b\ \x2b\x2c\x67\x3d\x78\x3b\x74\x79\x70\x65\x6f\x66\x20\x62\x3d\x3d\ \x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x21\x6c\x2e\x74\x65\x73\ \x74\x28\x62\x29\x26\x26\x28\x62\x3d\x62\x2e\x74\x6f\x4c\x6f\x77\ \x65\x72\x43\x61\x73\x65\x28\x29\x2c\x64\x3d\x62\x2c\x67\x3d\x77\ \x29\x2c\x67\x28\x22\x70\x72\x65\x76\x69\x6f\x75\x73\x53\x69\x62\ \x6c\x69\x6e\x67\x22\x2c\x62\x2c\x66\x2c\x61\x2c\x64\x2c\x63\x29\ \x7d\x7d\x2c\x66\x69\x6e\x64\x3a\x7b\x49\x44\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x69\x66\x28\x74\ \x79\x70\x65\x6f\x66\x20\x62\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\ \x6e\x74\x42\x79\x49\x64\x21\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\ \x65\x64\x22\x26\x26\x21\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x62\ \x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\x49\x64\x28\ \x61\x5b\x31\x5d\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x64\x26\x26\ \x64\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x3f\x5b\x64\x5d\ \x3a\x5b\x5d\x7d\x7d\x2c\x4e\x41\x4d\x45\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x69\x66\x28\x74\x79\x70\x65\ \x6f\x66\x20\x62\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\ \x42\x79\x4e\x61\x6d\x65\x21\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\ \x65\x64\x22\x29\x7b\x76\x61\x72\x20\x63\x3d\x5b\x5d\x2c\x64\x3d\ \x62\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x4e\ \x61\x6d\x65\x28\x61\x5b\x31\x5d\x29\x3b\x66\x6f\x72\x28\x76\x61\ \x72\x20\x65\x3d\x30\x2c\x66\x3d\x64\x2e\x6c\x65\x6e\x67\x74\x68\ \x3b\x65\x3c\x66\x3b\x65\x2b\x2b\x29\x64\x5b\x65\x5d\x2e\x67\x65\ \x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\x6e\x61\x6d\x65\ \x22\x29\x3d\x3d\x3d\x61\x5b\x31\x5d\x26\x26\x63\x2e\x70\x75\x73\ \x68\x28\x64\x5b\x65\x5d\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x63\ \x2e\x6c\x65\x6e\x67\x74\x68\x3d\x3d\x3d\x30\x3f\x6e\x75\x6c\x6c\ \x3a\x63\x7d\x7d\x2c\x54\x41\x47\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x62\x29\x7b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\ \x20\x62\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\ \x54\x61\x67\x4e\x61\x6d\x65\x21\x3d\x22\x75\x6e\x64\x65\x66\x69\ \x6e\x65\x64\x22\x29\x72\x65\x74\x75\x72\x6e\x20\x62\x2e\x67\x65\ \x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\x61\ \x6d\x65\x28\x61\x5b\x31\x5d\x29\x7d\x7d\x2c\x70\x72\x65\x46\x69\ \x6c\x74\x65\x72\x3a\x7b\x43\x4c\x41\x53\x53\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x2c\x65\x2c\x66\ \x29\x7b\x61\x3d\x22\x20\x22\x2b\x61\x5b\x31\x5d\x2e\x72\x65\x70\ \x6c\x61\x63\x65\x28\x6a\x2c\x22\x22\x29\x2b\x22\x20\x22\x3b\x69\ \x66\x28\x66\x29\x72\x65\x74\x75\x72\x6e\x20\x61\x3b\x66\x6f\x72\ \x28\x76\x61\x72\x20\x67\x3d\x30\x2c\x68\x3b\x28\x68\x3d\x62\x5b\ \x67\x5d\x29\x21\x3d\x6e\x75\x6c\x6c\x3b\x67\x2b\x2b\x29\x68\x26\ \x26\x28\x65\x5e\x28\x68\x2e\x63\x6c\x61\x73\x73\x4e\x61\x6d\x65\ \x26\x26\x28\x22\x20\x22\x2b\x68\x2e\x63\x6c\x61\x73\x73\x4e\x61\ \x6d\x65\x2b\x22\x20\x22\x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\ \x2f\x5b\x5c\x74\x5c\x6e\x5c\x72\x5d\x2f\x67\x2c\x22\x20\x22\x29\ \x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x61\x29\x3e\x3d\x30\x29\x3f\ \x63\x7c\x7c\x64\x2e\x70\x75\x73\x68\x28\x68\x29\x3a\x63\x26\x26\ \x28\x62\x5b\x67\x5d\x3d\x21\x31\x29\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x21\x31\x7d\x2c\x49\x44\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x5b\x31\x5d\x2e\ \x72\x65\x70\x6c\x61\x63\x65\x28\x6a\x2c\x22\x22\x29\x7d\x2c\x54\ \x41\x47\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x5b\x31\x5d\x2e\x72\x65\x70\ \x6c\x61\x63\x65\x28\x6a\x2c\x22\x22\x29\x2e\x74\x6f\x4c\x6f\x77\ \x65\x72\x43\x61\x73\x65\x28\x29\x7d\x2c\x43\x48\x49\x4c\x44\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\x28\x61\ \x5b\x31\x5d\x3d\x3d\x3d\x22\x6e\x74\x68\x22\x29\x7b\x61\x5b\x32\ \x5d\x7c\x7c\x6d\x2e\x65\x72\x72\x6f\x72\x28\x61\x5b\x30\x5d\x29\ \x2c\x61\x5b\x32\x5d\x3d\x61\x5b\x32\x5d\x2e\x72\x65\x70\x6c\x61\ \x63\x65\x28\x2f\x5e\x5c\x2b\x7c\x5c\x73\x2a\x2f\x67\x2c\x22\x22\ \x29\x3b\x76\x61\x72\x20\x62\x3d\x2f\x28\x2d\x3f\x29\x28\x5c\x64\ \x2a\x29\x28\x3f\x3a\x6e\x28\x5b\x2b\x5c\x2d\x5d\x3f\x5c\x64\x2a\ \x29\x29\x3f\x2f\x2e\x65\x78\x65\x63\x28\x61\x5b\x32\x5d\x3d\x3d\ \x3d\x22\x65\x76\x65\x6e\x22\x26\x26\x22\x32\x6e\x22\x7c\x7c\x61\ \x5b\x32\x5d\x3d\x3d\x3d\x22\x6f\x64\x64\x22\x26\x26\x22\x32\x6e\ \x2b\x31\x22\x7c\x7c\x21\x2f\x5c\x44\x2f\x2e\x74\x65\x73\x74\x28\ \x61\x5b\x32\x5d\x29\x26\x26\x22\x30\x6e\x2b\x22\x2b\x61\x5b\x32\ \x5d\x7c\x7c\x61\x5b\x32\x5d\x29\x3b\x61\x5b\x32\x5d\x3d\x62\x5b\ \x31\x5d\x2b\x28\x62\x5b\x32\x5d\x7c\x7c\x31\x29\x2d\x30\x2c\x61\ \x5b\x33\x5d\x3d\x62\x5b\x33\x5d\x2d\x30\x7d\x65\x6c\x73\x65\x20\ \x61\x5b\x32\x5d\x26\x26\x6d\x2e\x65\x72\x72\x6f\x72\x28\x61\x5b\ \x30\x5d\x29\x3b\x61\x5b\x30\x5d\x3d\x65\x2b\x2b\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x61\x7d\x2c\x41\x54\x54\x52\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x2c\x65\x2c\x66\ \x29\x7b\x76\x61\x72\x20\x67\x3d\x61\x5b\x31\x5d\x3d\x61\x5b\x31\ \x5d\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x6a\x2c\x22\x22\x29\x3b\ \x21\x66\x26\x26\x6f\x2e\x61\x74\x74\x72\x4d\x61\x70\x5b\x67\x5d\ \x26\x26\x28\x61\x5b\x31\x5d\x3d\x6f\x2e\x61\x74\x74\x72\x4d\x61\ \x70\x5b\x67\x5d\x29\x2c\x61\x5b\x34\x5d\x3d\x28\x61\x5b\x34\x5d\ \x7c\x7c\x61\x5b\x35\x5d\x7c\x7c\x22\x22\x29\x2e\x72\x65\x70\x6c\ \x61\x63\x65\x28\x6a\x2c\x22\x22\x29\x2c\x61\x5b\x32\x5d\x3d\x3d\ \x3d\x22\x7e\x3d\x22\x26\x26\x28\x61\x5b\x34\x5d\x3d\x22\x20\x22\ \x2b\x61\x5b\x34\x5d\x2b\x22\x20\x22\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x61\x7d\x2c\x50\x53\x45\x55\x44\x4f\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x62\x2c\x63\x2c\x64\x2c\x65\x2c\x66\x29\x7b\ \x69\x66\x28\x62\x5b\x31\x5d\x3d\x3d\x3d\x22\x6e\x6f\x74\x22\x29\ \x69\x66\x28\x28\x61\x2e\x65\x78\x65\x63\x28\x62\x5b\x33\x5d\x29\ \x7c\x7c\x22\x22\x29\x2e\x6c\x65\x6e\x67\x74\x68\x3e\x31\x7c\x7c\ \x2f\x5e\x5c\x77\x2f\x2e\x74\x65\x73\x74\x28\x62\x5b\x33\x5d\x29\ \x29\x62\x5b\x33\x5d\x3d\x6d\x28\x62\x5b\x33\x5d\x2c\x6e\x75\x6c\ \x6c\x2c\x6e\x75\x6c\x6c\x2c\x63\x29\x3b\x65\x6c\x73\x65\x7b\x76\ \x61\x72\x20\x67\x3d\x6d\x2e\x66\x69\x6c\x74\x65\x72\x28\x62\x5b\ \x33\x5d\x2c\x63\x2c\x64\x2c\x21\x30\x5e\x66\x29\x3b\x64\x7c\x7c\ \x65\x2e\x70\x75\x73\x68\x2e\x61\x70\x70\x6c\x79\x28\x65\x2c\x67\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x21\x31\x7d\x65\x6c\x73\x65\x20\ \x69\x66\x28\x6f\x2e\x6d\x61\x74\x63\x68\x2e\x50\x4f\x53\x2e\x74\ \x65\x73\x74\x28\x62\x5b\x30\x5d\x29\x7c\x7c\x6f\x2e\x6d\x61\x74\ \x63\x68\x2e\x43\x48\x49\x4c\x44\x2e\x74\x65\x73\x74\x28\x62\x5b\ \x30\x5d\x29\x29\x72\x65\x74\x75\x72\x6e\x21\x30\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x62\x7d\x2c\x50\x4f\x53\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x61\x2e\x75\x6e\x73\x68\x69\x66\x74\ \x28\x21\x30\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x7d\x7d\x2c\ \x66\x69\x6c\x74\x65\x72\x73\x3a\x7b\x65\x6e\x61\x62\x6c\x65\x64\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x61\x2e\x64\x69\x73\x61\x62\x6c\x65\x64\x3d\x3d\ \x3d\x21\x31\x26\x26\x61\x2e\x74\x79\x70\x65\x21\x3d\x3d\x22\x68\ \x69\x64\x64\x65\x6e\x22\x7d\x2c\x64\x69\x73\x61\x62\x6c\x65\x64\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x61\x2e\x64\x69\x73\x61\x62\x6c\x65\x64\x3d\x3d\ \x3d\x21\x30\x7d\x2c\x63\x68\x65\x63\x6b\x65\x64\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\ \x61\x2e\x63\x68\x65\x63\x6b\x65\x64\x3d\x3d\x3d\x21\x30\x7d\x2c\ \x73\x65\x6c\x65\x63\x74\x65\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x29\x7b\x61\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\ \x65\x26\x26\x61\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x2e\ \x73\x65\x6c\x65\x63\x74\x65\x64\x49\x6e\x64\x65\x78\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x61\x2e\x73\x65\x6c\x65\x63\x74\x65\x64\x3d\ \x3d\x3d\x21\x30\x7d\x2c\x70\x61\x72\x65\x6e\x74\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\ \x21\x61\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x7d\x2c\x65\ \x6d\x70\x74\x79\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x21\x61\x2e\x66\x69\x72\x73\x74\x43\ \x68\x69\x6c\x64\x7d\x2c\x68\x61\x73\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x72\x65\x74\x75\x72\x6e\ \x21\x21\x6d\x28\x63\x5b\x33\x5d\x2c\x61\x29\x2e\x6c\x65\x6e\x67\ \x74\x68\x7d\x2c\x68\x65\x61\x64\x65\x72\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x2f\x68\x5c\ \x64\x2f\x69\x2e\x74\x65\x73\x74\x28\x61\x2e\x6e\x6f\x64\x65\x4e\ \x61\x6d\x65\x29\x7d\x2c\x74\x65\x78\x74\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x3d\x61\x2e\x67\ \x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\x74\x79\x70\ \x65\x22\x29\x2c\x63\x3d\x61\x2e\x74\x79\x70\x65\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\ \x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\x22\ \x69\x6e\x70\x75\x74\x22\x26\x26\x22\x74\x65\x78\x74\x22\x3d\x3d\ \x3d\x63\x26\x26\x28\x62\x3d\x3d\x3d\x63\x7c\x7c\x62\x3d\x3d\x3d\ \x6e\x75\x6c\x6c\x29\x7d\x2c\x72\x61\x64\x69\x6f\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\ \x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\ \x65\x72\x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\x22\x69\x6e\x70\x75\ \x74\x22\x26\x26\x22\x72\x61\x64\x69\x6f\x22\x3d\x3d\x3d\x61\x2e\ \x74\x79\x70\x65\x7d\x2c\x63\x68\x65\x63\x6b\x62\x6f\x78\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\ \x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\x22\x69\x6e\ \x70\x75\x74\x22\x26\x26\x22\x63\x68\x65\x63\x6b\x62\x6f\x78\x22\ \x3d\x3d\x3d\x61\x2e\x74\x79\x70\x65\x7d\x2c\x66\x69\x6c\x65\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\ \x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\x22\x69\ \x6e\x70\x75\x74\x22\x26\x26\x22\x66\x69\x6c\x65\x22\x3d\x3d\x3d\ \x61\x2e\x74\x79\x70\x65\x7d\x2c\x70\x61\x73\x73\x77\x6f\x72\x64\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\ \x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\x22\ \x69\x6e\x70\x75\x74\x22\x26\x26\x22\x70\x61\x73\x73\x77\x6f\x72\ \x64\x22\x3d\x3d\x3d\x61\x2e\x74\x79\x70\x65\x7d\x2c\x73\x75\x62\ \x6d\x69\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\ \x76\x61\x72\x20\x62\x3d\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\ \x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3b\x72\ \x65\x74\x75\x72\x6e\x28\x62\x3d\x3d\x3d\x22\x69\x6e\x70\x75\x74\ \x22\x7c\x7c\x62\x3d\x3d\x3d\x22\x62\x75\x74\x74\x6f\x6e\x22\x29\ \x26\x26\x22\x73\x75\x62\x6d\x69\x74\x22\x3d\x3d\x3d\x61\x2e\x74\ \x79\x70\x65\x7d\x2c\x69\x6d\x61\x67\x65\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\ \x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\x65\x72\ \x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\x22\x69\x6e\x70\x75\x74\x22\ \x26\x26\x22\x69\x6d\x61\x67\x65\x22\x3d\x3d\x3d\x61\x2e\x74\x79\ \x70\x65\x7d\x2c\x72\x65\x73\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x3d\x61\x2e\x6e\x6f\ \x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\ \x73\x65\x28\x29\x3b\x72\x65\x74\x75\x72\x6e\x28\x62\x3d\x3d\x3d\ \x22\x69\x6e\x70\x75\x74\x22\x7c\x7c\x62\x3d\x3d\x3d\x22\x62\x75\ \x74\x74\x6f\x6e\x22\x29\x26\x26\x22\x72\x65\x73\x65\x74\x22\x3d\ \x3d\x3d\x61\x2e\x74\x79\x70\x65\x7d\x2c\x62\x75\x74\x74\x6f\x6e\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\ \x20\x62\x3d\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\ \x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3b\x72\x65\x74\x75\ \x72\x6e\x20\x62\x3d\x3d\x3d\x22\x69\x6e\x70\x75\x74\x22\x26\x26\ \x22\x62\x75\x74\x74\x6f\x6e\x22\x3d\x3d\x3d\x61\x2e\x74\x79\x70\ \x65\x7c\x7c\x62\x3d\x3d\x3d\x22\x62\x75\x74\x74\x6f\x6e\x22\x7d\ \x2c\x69\x6e\x70\x75\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x2f\x69\x6e\x70\x75\x74\x7c\ \x73\x65\x6c\x65\x63\x74\x7c\x74\x65\x78\x74\x61\x72\x65\x61\x7c\ \x62\x75\x74\x74\x6f\x6e\x2f\x69\x2e\x74\x65\x73\x74\x28\x61\x2e\ \x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x7d\x2c\x66\x6f\x63\x75\x73\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x61\x3d\x3d\x3d\x61\x2e\x6f\x77\x6e\x65\x72\x44\ \x6f\x63\x75\x6d\x65\x6e\x74\x2e\x61\x63\x74\x69\x76\x65\x45\x6c\ \x65\x6d\x65\x6e\x74\x7d\x7d\x2c\x73\x65\x74\x46\x69\x6c\x74\x65\ \x72\x73\x3a\x7b\x66\x69\x72\x73\x74\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x62\ \x3d\x3d\x3d\x30\x7d\x2c\x6c\x61\x73\x74\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x62\x3d\x3d\x3d\x64\x2e\x6c\x65\x6e\x67\x74\x68\ \x2d\x31\x7d\x2c\x65\x76\x65\x6e\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x62\x25\ \x32\x3d\x3d\x3d\x30\x7d\x2c\x6f\x64\x64\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\ \x62\x25\x32\x3d\x3d\x3d\x31\x7d\x2c\x6c\x74\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x62\x3c\x63\x5b\x33\x5d\x2d\x30\x7d\x2c\x67\x74\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\ \x72\x65\x74\x75\x72\x6e\x20\x62\x3e\x63\x5b\x33\x5d\x2d\x30\x7d\ \x2c\x6e\x74\x68\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x2c\x63\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x63\x5b\x33\x5d\ \x2d\x30\x3d\x3d\x3d\x62\x7d\x2c\x65\x71\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x63\x5b\x33\x5d\x2d\x30\x3d\x3d\x3d\x62\x7d\x7d\x2c\x66\ \x69\x6c\x74\x65\x72\x3a\x7b\x50\x53\x45\x55\x44\x4f\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\x7b\ \x76\x61\x72\x20\x65\x3d\x62\x5b\x31\x5d\x2c\x66\x3d\x6f\x2e\x66\ \x69\x6c\x74\x65\x72\x73\x5b\x65\x5d\x3b\x69\x66\x28\x66\x29\x72\ \x65\x74\x75\x72\x6e\x20\x66\x28\x61\x2c\x63\x2c\x62\x2c\x64\x29\ \x3b\x69\x66\x28\x65\x3d\x3d\x3d\x22\x63\x6f\x6e\x74\x61\x69\x6e\ \x73\x22\x29\x72\x65\x74\x75\x72\x6e\x28\x61\x2e\x74\x65\x78\x74\ \x43\x6f\x6e\x74\x65\x6e\x74\x7c\x7c\x61\x2e\x69\x6e\x6e\x65\x72\ \x54\x65\x78\x74\x7c\x7c\x6e\x28\x5b\x61\x5d\x29\x7c\x7c\x22\x22\ \x29\x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x62\x5b\x33\x5d\x29\x3e\ \x3d\x30\x3b\x69\x66\x28\x65\x3d\x3d\x3d\x22\x6e\x6f\x74\x22\x29\ \x7b\x76\x61\x72\x20\x67\x3d\x62\x5b\x33\x5d\x3b\x66\x6f\x72\x28\ \x76\x61\x72\x20\x68\x3d\x30\x2c\x69\x3d\x67\x2e\x6c\x65\x6e\x67\ \x74\x68\x3b\x68\x3c\x69\x3b\x68\x2b\x2b\x29\x69\x66\x28\x67\x5b\ \x68\x5d\x3d\x3d\x3d\x61\x29\x72\x65\x74\x75\x72\x6e\x21\x31\x3b\ \x72\x65\x74\x75\x72\x6e\x21\x30\x7d\x6d\x2e\x65\x72\x72\x6f\x72\ \x28\x65\x29\x7d\x2c\x43\x48\x49\x4c\x44\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x2c\x65\ \x2c\x66\x2c\x67\x2c\x68\x2c\x69\x2c\x6a\x2c\x6b\x3d\x62\x5b\x31\ \x5d\x2c\x6c\x3d\x61\x3b\x73\x77\x69\x74\x63\x68\x28\x6b\x29\x7b\ \x63\x61\x73\x65\x22\x6f\x6e\x6c\x79\x22\x3a\x63\x61\x73\x65\x22\ \x66\x69\x72\x73\x74\x22\x3a\x77\x68\x69\x6c\x65\x28\x6c\x3d\x6c\ \x2e\x70\x72\x65\x76\x69\x6f\x75\x73\x53\x69\x62\x6c\x69\x6e\x67\ \x29\x69\x66\x28\x6c\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\ \x3d\x31\x29\x72\x65\x74\x75\x72\x6e\x21\x31\x3b\x69\x66\x28\x6b\ \x3d\x3d\x3d\x22\x66\x69\x72\x73\x74\x22\x29\x72\x65\x74\x75\x72\ \x6e\x21\x30\x3b\x6c\x3d\x61\x3b\x63\x61\x73\x65\x22\x6c\x61\x73\ \x74\x22\x3a\x77\x68\x69\x6c\x65\x28\x6c\x3d\x6c\x2e\x6e\x65\x78\ \x74\x53\x69\x62\x6c\x69\x6e\x67\x29\x69\x66\x28\x6c\x2e\x6e\x6f\ \x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\x72\x65\x74\x75\x72\ \x6e\x21\x31\x3b\x72\x65\x74\x75\x72\x6e\x21\x30\x3b\x63\x61\x73\ \x65\x22\x6e\x74\x68\x22\x3a\x63\x3d\x62\x5b\x32\x5d\x2c\x65\x3d\ \x62\x5b\x33\x5d\x3b\x69\x66\x28\x63\x3d\x3d\x3d\x31\x26\x26\x65\ \x3d\x3d\x3d\x30\x29\x72\x65\x74\x75\x72\x6e\x21\x30\x3b\x66\x3d\ \x62\x5b\x30\x5d\x2c\x67\x3d\x61\x2e\x70\x61\x72\x65\x6e\x74\x4e\ \x6f\x64\x65\x3b\x69\x66\x28\x67\x26\x26\x28\x67\x5b\x64\x5d\x21\ \x3d\x3d\x66\x7c\x7c\x21\x61\x2e\x6e\x6f\x64\x65\x49\x6e\x64\x65\ \x78\x29\x29\x7b\x69\x3d\x30\x3b\x66\x6f\x72\x28\x6c\x3d\x67\x2e\ \x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x3b\x6c\x3b\x6c\x3d\x6c\ \x2e\x6e\x65\x78\x74\x53\x69\x62\x6c\x69\x6e\x67\x29\x6c\x2e\x6e\ \x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\x26\x28\x6c\x2e\ \x6e\x6f\x64\x65\x49\x6e\x64\x65\x78\x3d\x2b\x2b\x69\x29\x3b\x67\ \x5b\x64\x5d\x3d\x66\x7d\x6a\x3d\x61\x2e\x6e\x6f\x64\x65\x49\x6e\ \x64\x65\x78\x2d\x65\x3b\x72\x65\x74\x75\x72\x6e\x20\x63\x3d\x3d\ \x3d\x30\x3f\x6a\x3d\x3d\x3d\x30\x3a\x6a\x25\x63\x3d\x3d\x3d\x30\ \x26\x26\x6a\x2f\x63\x3e\x3d\x30\x7d\x7d\x2c\x49\x44\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x61\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\ \x31\x26\x26\x61\x2e\x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\ \x65\x28\x22\x69\x64\x22\x29\x3d\x3d\x3d\x62\x7d\x2c\x54\x41\x47\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\ \x65\x74\x75\x72\x6e\x20\x62\x3d\x3d\x3d\x22\x2a\x22\x26\x26\x61\ \x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x7c\x7c\x21\ \x21\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x26\x26\x61\x2e\x6e\ \x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\ \x61\x73\x65\x28\x29\x3d\x3d\x3d\x62\x7d\x2c\x43\x4c\x41\x53\x53\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\ \x65\x74\x75\x72\x6e\x28\x22\x20\x22\x2b\x28\x61\x2e\x63\x6c\x61\ \x73\x73\x4e\x61\x6d\x65\x7c\x7c\x61\x2e\x67\x65\x74\x41\x74\x74\ \x72\x69\x62\x75\x74\x65\x28\x22\x63\x6c\x61\x73\x73\x22\x29\x29\ \x2b\x22\x20\x22\x29\x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x62\x29\ \x3e\x2d\x31\x7d\x2c\x41\x54\x54\x52\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x62\x5b\ \x31\x5d\x2c\x64\x3d\x6d\x2e\x61\x74\x74\x72\x3f\x6d\x2e\x61\x74\ \x74\x72\x28\x61\x2c\x63\x29\x3a\x6f\x2e\x61\x74\x74\x72\x48\x61\ \x6e\x64\x6c\x65\x5b\x63\x5d\x3f\x6f\x2e\x61\x74\x74\x72\x48\x61\ \x6e\x64\x6c\x65\x5b\x63\x5d\x28\x61\x29\x3a\x61\x5b\x63\x5d\x21\ \x3d\x6e\x75\x6c\x6c\x3f\x61\x5b\x63\x5d\x3a\x61\x2e\x67\x65\x74\ \x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x63\x29\x2c\x65\x3d\x64\ \x2b\x22\x22\x2c\x66\x3d\x62\x5b\x32\x5d\x2c\x67\x3d\x62\x5b\x34\ \x5d\x3b\x72\x65\x74\x75\x72\x6e\x20\x64\x3d\x3d\x6e\x75\x6c\x6c\ \x3f\x66\x3d\x3d\x3d\x22\x21\x3d\x22\x3a\x21\x66\x26\x26\x6d\x2e\ \x61\x74\x74\x72\x3f\x64\x21\x3d\x6e\x75\x6c\x6c\x3a\x66\x3d\x3d\ \x3d\x22\x3d\x22\x3f\x65\x3d\x3d\x3d\x67\x3a\x66\x3d\x3d\x3d\x22\ \x2a\x3d\x22\x3f\x65\x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x67\x29\ \x3e\x3d\x30\x3a\x66\x3d\x3d\x3d\x22\x7e\x3d\x22\x3f\x28\x22\x20\ \x22\x2b\x65\x2b\x22\x20\x22\x29\x2e\x69\x6e\x64\x65\x78\x4f\x66\ \x28\x67\x29\x3e\x3d\x30\x3a\x67\x3f\x66\x3d\x3d\x3d\x22\x21\x3d\ \x22\x3f\x65\x21\x3d\x3d\x67\x3a\x66\x3d\x3d\x3d\x22\x5e\x3d\x22\ \x3f\x65\x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x67\x29\x3d\x3d\x3d\ \x30\x3a\x66\x3d\x3d\x3d\x22\x24\x3d\x22\x3f\x65\x2e\x73\x75\x62\ \x73\x74\x72\x28\x65\x2e\x6c\x65\x6e\x67\x74\x68\x2d\x67\x2e\x6c\ \x65\x6e\x67\x74\x68\x29\x3d\x3d\x3d\x67\x3a\x66\x3d\x3d\x3d\x22\ \x7c\x3d\x22\x3f\x65\x3d\x3d\x3d\x67\x7c\x7c\x65\x2e\x73\x75\x62\ \x73\x74\x72\x28\x30\x2c\x67\x2e\x6c\x65\x6e\x67\x74\x68\x2b\x31\ \x29\x3d\x3d\x3d\x67\x2b\x22\x2d\x22\x3a\x21\x31\x3a\x65\x26\x26\ \x64\x21\x3d\x3d\x21\x31\x7d\x2c\x50\x4f\x53\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\x7b\x76\x61\ \x72\x20\x65\x3d\x62\x5b\x32\x5d\x2c\x66\x3d\x6f\x2e\x73\x65\x74\ \x46\x69\x6c\x74\x65\x72\x73\x5b\x65\x5d\x3b\x69\x66\x28\x66\x29\ \x72\x65\x74\x75\x72\x6e\x20\x66\x28\x61\x2c\x63\x2c\x62\x2c\x64\ \x29\x7d\x7d\x7d\x2c\x70\x3d\x6f\x2e\x6d\x61\x74\x63\x68\x2e\x50\ \x4f\x53\x2c\x71\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x22\x5c\x5c\x22\x2b\x28\x62\ \x2d\x30\x2b\x31\x29\x7d\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\x72\ \x20\x69\x6e\x20\x6f\x2e\x6d\x61\x74\x63\x68\x29\x6f\x2e\x6d\x61\ \x74\x63\x68\x5b\x72\x5d\x3d\x6e\x65\x77\x20\x52\x65\x67\x45\x78\ \x70\x28\x6f\x2e\x6d\x61\x74\x63\x68\x5b\x72\x5d\x2e\x73\x6f\x75\ \x72\x63\x65\x2b\x2f\x28\x3f\x21\x5b\x5e\x5c\x5b\x5d\x2a\x5c\x5d\ \x29\x28\x3f\x21\x5b\x5e\x5c\x28\x5d\x2a\x5c\x29\x29\x2f\x2e\x73\ \x6f\x75\x72\x63\x65\x29\x2c\x6f\x2e\x6c\x65\x66\x74\x4d\x61\x74\ \x63\x68\x5b\x72\x5d\x3d\x6e\x65\x77\x20\x52\x65\x67\x45\x78\x70\ \x28\x2f\x28\x5e\x28\x3f\x3a\x2e\x7c\x5c\x72\x7c\x5c\x6e\x29\x2a\ \x3f\x29\x2f\x2e\x73\x6f\x75\x72\x63\x65\x2b\x6f\x2e\x6d\x61\x74\ \x63\x68\x5b\x72\x5d\x2e\x73\x6f\x75\x72\x63\x65\x2e\x72\x65\x70\ \x6c\x61\x63\x65\x28\x2f\x5c\x5c\x28\x5c\x64\x2b\x29\x2f\x67\x2c\ \x71\x29\x29\x3b\x76\x61\x72\x20\x73\x3d\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x29\x7b\x61\x3d\x41\x72\x72\x61\x79\x2e\ \x70\x72\x6f\x74\x6f\x74\x79\x70\x65\x2e\x73\x6c\x69\x63\x65\x2e\ \x63\x61\x6c\x6c\x28\x61\x2c\x30\x29\x3b\x69\x66\x28\x62\x29\x7b\ \x62\x2e\x70\x75\x73\x68\x2e\x61\x70\x70\x6c\x79\x28\x62\x2c\x61\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x62\x7d\x72\x65\x74\x75\x72\ \x6e\x20\x61\x7d\x3b\x74\x72\x79\x7b\x41\x72\x72\x61\x79\x2e\x70\ \x72\x6f\x74\x6f\x74\x79\x70\x65\x2e\x73\x6c\x69\x63\x65\x2e\x63\ \x61\x6c\x6c\x28\x63\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\x45\x6c\ \x65\x6d\x65\x6e\x74\x2e\x63\x68\x69\x6c\x64\x4e\x6f\x64\x65\x73\ \x2c\x30\x29\x5b\x30\x5d\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x7d\ \x63\x61\x74\x63\x68\x28\x74\x29\x7b\x73\x3d\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x30\ \x2c\x64\x3d\x62\x7c\x7c\x5b\x5d\x3b\x69\x66\x28\x67\x2e\x63\x61\ \x6c\x6c\x28\x61\x29\x3d\x3d\x3d\x22\x5b\x6f\x62\x6a\x65\x63\x74\ \x20\x41\x72\x72\x61\x79\x5d\x22\x29\x41\x72\x72\x61\x79\x2e\x70\ \x72\x6f\x74\x6f\x74\x79\x70\x65\x2e\x70\x75\x73\x68\x2e\x61\x70\ \x70\x6c\x79\x28\x64\x2c\x61\x29\x3b\x65\x6c\x73\x65\x20\x69\x66\ \x28\x74\x79\x70\x65\x6f\x66\x20\x61\x2e\x6c\x65\x6e\x67\x74\x68\ \x3d\x3d\x22\x6e\x75\x6d\x62\x65\x72\x22\x29\x66\x6f\x72\x28\x76\ \x61\x72\x20\x65\x3d\x61\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x63\x3c\ \x65\x3b\x63\x2b\x2b\x29\x64\x2e\x70\x75\x73\x68\x28\x61\x5b\x63\ \x5d\x29\x3b\x65\x6c\x73\x65\x20\x66\x6f\x72\x28\x3b\x61\x5b\x63\ \x5d\x3b\x63\x2b\x2b\x29\x64\x2e\x70\x75\x73\x68\x28\x61\x5b\x63\ \x5d\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x64\x7d\x7d\x76\x61\x72\ \x20\x75\x2c\x76\x3b\x63\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\x45\ \x6c\x65\x6d\x65\x6e\x74\x2e\x63\x6f\x6d\x70\x61\x72\x65\x44\x6f\ \x63\x75\x6d\x65\x6e\x74\x50\x6f\x73\x69\x74\x69\x6f\x6e\x3f\x75\ \x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x69\ \x66\x28\x61\x3d\x3d\x3d\x62\x29\x7b\x68\x3d\x21\x30\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x30\x7d\x69\x66\x28\x21\x61\x2e\x63\x6f\x6d\ \x70\x61\x72\x65\x44\x6f\x63\x75\x6d\x65\x6e\x74\x50\x6f\x73\x69\ \x74\x69\x6f\x6e\x7c\x7c\x21\x62\x2e\x63\x6f\x6d\x70\x61\x72\x65\ \x44\x6f\x63\x75\x6d\x65\x6e\x74\x50\x6f\x73\x69\x74\x69\x6f\x6e\ \x29\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x63\x6f\x6d\x70\x61\x72\ \x65\x44\x6f\x63\x75\x6d\x65\x6e\x74\x50\x6f\x73\x69\x74\x69\x6f\ \x6e\x3f\x2d\x31\x3a\x31\x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\ \x63\x6f\x6d\x70\x61\x72\x65\x44\x6f\x63\x75\x6d\x65\x6e\x74\x50\ \x6f\x73\x69\x74\x69\x6f\x6e\x28\x62\x29\x26\x34\x3f\x2d\x31\x3a\ \x31\x7d\x3a\x28\x75\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x62\x29\x7b\x69\x66\x28\x61\x3d\x3d\x3d\x62\x29\x7b\x68\x3d\ \x21\x30\x3b\x72\x65\x74\x75\x72\x6e\x20\x30\x7d\x69\x66\x28\x61\ \x2e\x73\x6f\x75\x72\x63\x65\x49\x6e\x64\x65\x78\x26\x26\x62\x2e\ \x73\x6f\x75\x72\x63\x65\x49\x6e\x64\x65\x78\x29\x72\x65\x74\x75\ \x72\x6e\x20\x61\x2e\x73\x6f\x75\x72\x63\x65\x49\x6e\x64\x65\x78\ \x2d\x62\x2e\x73\x6f\x75\x72\x63\x65\x49\x6e\x64\x65\x78\x3b\x76\ \x61\x72\x20\x63\x2c\x64\x2c\x65\x3d\x5b\x5d\x2c\x66\x3d\x5b\x5d\ \x2c\x67\x3d\x61\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x2c\ \x69\x3d\x62\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x2c\x6a\ \x3d\x67\x3b\x69\x66\x28\x67\x3d\x3d\x3d\x69\x29\x72\x65\x74\x75\ \x72\x6e\x20\x76\x28\x61\x2c\x62\x29\x3b\x69\x66\x28\x21\x67\x29\ \x72\x65\x74\x75\x72\x6e\x2d\x31\x3b\x69\x66\x28\x21\x69\x29\x72\ \x65\x74\x75\x72\x6e\x20\x31\x3b\x77\x68\x69\x6c\x65\x28\x6a\x29\ \x65\x2e\x75\x6e\x73\x68\x69\x66\x74\x28\x6a\x29\x2c\x6a\x3d\x6a\ \x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x3b\x6a\x3d\x69\x3b\ \x77\x68\x69\x6c\x65\x28\x6a\x29\x66\x2e\x75\x6e\x73\x68\x69\x66\ \x74\x28\x6a\x29\x2c\x6a\x3d\x6a\x2e\x70\x61\x72\x65\x6e\x74\x4e\ \x6f\x64\x65\x3b\x63\x3d\x65\x2e\x6c\x65\x6e\x67\x74\x68\x2c\x64\ \x3d\x66\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x66\x6f\x72\x28\x76\x61\ \x72\x20\x6b\x3d\x30\x3b\x6b\x3c\x63\x26\x26\x6b\x3c\x64\x3b\x6b\ \x2b\x2b\x29\x69\x66\x28\x65\x5b\x6b\x5d\x21\x3d\x3d\x66\x5b\x6b\ \x5d\x29\x72\x65\x74\x75\x72\x6e\x20\x76\x28\x65\x5b\x6b\x5d\x2c\ \x66\x5b\x6b\x5d\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x6b\x3d\x3d\ \x3d\x63\x3f\x76\x28\x61\x2c\x66\x5b\x6b\x5d\x2c\x2d\x31\x29\x3a\ \x76\x28\x65\x5b\x6b\x5d\x2c\x62\x2c\x31\x29\x7d\x2c\x76\x3d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x69\ \x66\x28\x61\x3d\x3d\x3d\x62\x29\x72\x65\x74\x75\x72\x6e\x20\x63\ \x3b\x76\x61\x72\x20\x64\x3d\x61\x2e\x6e\x65\x78\x74\x53\x69\x62\ \x6c\x69\x6e\x67\x3b\x77\x68\x69\x6c\x65\x28\x64\x29\x7b\x69\x66\ \x28\x64\x3d\x3d\x3d\x62\x29\x72\x65\x74\x75\x72\x6e\x2d\x31\x3b\ \x64\x3d\x64\x2e\x6e\x65\x78\x74\x53\x69\x62\x6c\x69\x6e\x67\x7d\ \x72\x65\x74\x75\x72\x6e\x20\x31\x7d\x29\x2c\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x61\x3d\x63\x2e\x63\x72\ \x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x64\x69\x76\ \x22\x29\x2c\x64\x3d\x22\x73\x63\x72\x69\x70\x74\x22\x2b\x28\x6e\ \x65\x77\x20\x44\x61\x74\x65\x29\x2e\x67\x65\x74\x54\x69\x6d\x65\ \x28\x29\x2c\x65\x3d\x63\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\x45\ \x6c\x65\x6d\x65\x6e\x74\x3b\x61\x2e\x69\x6e\x6e\x65\x72\x48\x54\ \x4d\x4c\x3d\x22\x3c\x61\x20\x6e\x61\x6d\x65\x3d\x27\x22\x2b\x64\ \x2b\x22\x27\x2f\x3e\x22\x2c\x65\x2e\x69\x6e\x73\x65\x72\x74\x42\ \x65\x66\x6f\x72\x65\x28\x61\x2c\x65\x2e\x66\x69\x72\x73\x74\x43\ \x68\x69\x6c\x64\x29\x2c\x63\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\ \x6e\x74\x42\x79\x49\x64\x28\x64\x29\x26\x26\x28\x6f\x2e\x66\x69\ \x6e\x64\x2e\x49\x44\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x63\x2c\x64\x29\x7b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\ \x63\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\x49\x64\ \x21\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\x22\x26\x26\x21\ \x64\x29\x7b\x76\x61\x72\x20\x65\x3d\x63\x2e\x67\x65\x74\x45\x6c\ \x65\x6d\x65\x6e\x74\x42\x79\x49\x64\x28\x61\x5b\x31\x5d\x29\x3b\ \x72\x65\x74\x75\x72\x6e\x20\x65\x3f\x65\x2e\x69\x64\x3d\x3d\x3d\ \x61\x5b\x31\x5d\x7c\x7c\x74\x79\x70\x65\x6f\x66\x20\x65\x2e\x67\ \x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x4e\x6f\x64\x65\x21\ \x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\x22\x26\x26\x65\x2e\ \x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x4e\x6f\x64\x65\ \x28\x22\x69\x64\x22\x29\x2e\x6e\x6f\x64\x65\x56\x61\x6c\x75\x65\ \x3d\x3d\x3d\x61\x5b\x31\x5d\x3f\x5b\x65\x5d\x3a\x62\x3a\x5b\x5d\ \x7d\x7d\x2c\x6f\x2e\x66\x69\x6c\x74\x65\x72\x2e\x49\x44\x3d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\ \x20\x63\x3d\x74\x79\x70\x65\x6f\x66\x20\x61\x2e\x67\x65\x74\x41\ \x74\x74\x72\x69\x62\x75\x74\x65\x4e\x6f\x64\x65\x21\x3d\x22\x75\ \x6e\x64\x65\x66\x69\x6e\x65\x64\x22\x26\x26\x61\x2e\x67\x65\x74\ \x41\x74\x74\x72\x69\x62\x75\x74\x65\x4e\x6f\x64\x65\x28\x22\x69\ \x64\x22\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\x26\x63\x26\x26\x63\x2e\ \x6e\x6f\x64\x65\x56\x61\x6c\x75\x65\x3d\x3d\x3d\x62\x7d\x29\x2c\ \x65\x2e\x72\x65\x6d\x6f\x76\x65\x43\x68\x69\x6c\x64\x28\x61\x29\ \x2c\x65\x3d\x61\x3d\x6e\x75\x6c\x6c\x7d\x28\x29\x2c\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x61\x3d\x63\x2e\ \x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x64\ \x69\x76\x22\x29\x3b\x61\x2e\x61\x70\x70\x65\x6e\x64\x43\x68\x69\ \x6c\x64\x28\x63\x2e\x63\x72\x65\x61\x74\x65\x43\x6f\x6d\x6d\x65\ \x6e\x74\x28\x22\x22\x29\x29\x2c\x61\x2e\x67\x65\x74\x45\x6c\x65\ \x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\ \x2a\x22\x29\x2e\x6c\x65\x6e\x67\x74\x68\x3e\x30\x26\x26\x28\x6f\ \x2e\x66\x69\x6e\x64\x2e\x54\x41\x47\x3d\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x62\x2e\ \x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\ \x4e\x61\x6d\x65\x28\x61\x5b\x31\x5d\x29\x3b\x69\x66\x28\x61\x5b\ \x31\x5d\x3d\x3d\x3d\x22\x2a\x22\x29\x7b\x76\x61\x72\x20\x64\x3d\ \x5b\x5d\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\x65\x3d\x30\x3b\x63\ \x5b\x65\x5d\x3b\x65\x2b\x2b\x29\x63\x5b\x65\x5d\x2e\x6e\x6f\x64\ \x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\x26\x64\x2e\x70\x75\x73\ \x68\x28\x63\x5b\x65\x5d\x29\x3b\x63\x3d\x64\x7d\x72\x65\x74\x75\ \x72\x6e\x20\x63\x7d\x29\x2c\x61\x2e\x69\x6e\x6e\x65\x72\x48\x54\ \x4d\x4c\x3d\x22\x3c\x61\x20\x68\x72\x65\x66\x3d\x27\x23\x27\x3e\ \x3c\x2f\x61\x3e\x22\x2c\x61\x2e\x66\x69\x72\x73\x74\x43\x68\x69\ \x6c\x64\x26\x26\x74\x79\x70\x65\x6f\x66\x20\x61\x2e\x66\x69\x72\ \x73\x74\x43\x68\x69\x6c\x64\x2e\x67\x65\x74\x41\x74\x74\x72\x69\ \x62\x75\x74\x65\x21\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\ \x22\x26\x26\x61\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x2e\ \x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\x68\x72\ \x65\x66\x22\x29\x21\x3d\x3d\x22\x23\x22\x26\x26\x28\x6f\x2e\x61\ \x74\x74\x72\x48\x61\x6e\x64\x6c\x65\x2e\x68\x72\x65\x66\x3d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x61\x2e\x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\ \x28\x22\x68\x72\x65\x66\x22\x2c\x32\x29\x7d\x29\x2c\x61\x3d\x6e\ \x75\x6c\x6c\x7d\x28\x29\x2c\x63\x2e\x71\x75\x65\x72\x79\x53\x65\ \x6c\x65\x63\x74\x6f\x72\x41\x6c\x6c\x26\x26\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x61\x3d\x6d\x2c\x62\x3d\ \x63\x2e\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\ \x22\x64\x69\x76\x22\x29\x2c\x64\x3d\x22\x5f\x5f\x73\x69\x7a\x7a\ \x6c\x65\x5f\x5f\x22\x3b\x62\x2e\x69\x6e\x6e\x65\x72\x48\x54\x4d\ \x4c\x3d\x22\x3c\x70\x20\x63\x6c\x61\x73\x73\x3d\x27\x54\x45\x53\ \x54\x27\x3e\x3c\x2f\x70\x3e\x22\x3b\x69\x66\x28\x21\x62\x2e\x71\ \x75\x65\x72\x79\x53\x65\x6c\x65\x63\x74\x6f\x72\x41\x6c\x6c\x7c\ \x7c\x62\x2e\x71\x75\x65\x72\x79\x53\x65\x6c\x65\x63\x74\x6f\x72\ \x41\x6c\x6c\x28\x22\x2e\x54\x45\x53\x54\x22\x29\x2e\x6c\x65\x6e\ \x67\x74\x68\x21\x3d\x3d\x30\x29\x7b\x6d\x3d\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x62\x2c\x65\x2c\x66\x2c\x67\x29\x7b\x65\x3d\x65\ \x7c\x7c\x63\x3b\x69\x66\x28\x21\x67\x26\x26\x21\x6d\x2e\x69\x73\ \x58\x4d\x4c\x28\x65\x29\x29\x7b\x76\x61\x72\x20\x68\x3d\x2f\x5e\ \x28\x5c\x77\x2b\x24\x29\x7c\x5e\x5c\x2e\x28\x5b\x5c\x77\x5c\x2d\ \x5d\x2b\x24\x29\x7c\x5e\x23\x28\x5b\x5c\x77\x5c\x2d\x5d\x2b\x24\ \x29\x2f\x2e\x65\x78\x65\x63\x28\x62\x29\x3b\x69\x66\x28\x68\x26\ \x26\x28\x65\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\ \x7c\x7c\x65\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x39\ \x29\x29\x7b\x69\x66\x28\x68\x5b\x31\x5d\x29\x72\x65\x74\x75\x72\ \x6e\x20\x73\x28\x65\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\ \x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x62\x29\x2c\x66\x29\ \x3b\x69\x66\x28\x68\x5b\x32\x5d\x26\x26\x6f\x2e\x66\x69\x6e\x64\ \x2e\x43\x4c\x41\x53\x53\x26\x26\x65\x2e\x67\x65\x74\x45\x6c\x65\ \x6d\x65\x6e\x74\x73\x42\x79\x43\x6c\x61\x73\x73\x4e\x61\x6d\x65\ \x29\x72\x65\x74\x75\x72\x6e\x20\x73\x28\x65\x2e\x67\x65\x74\x45\ \x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x43\x6c\x61\x73\x73\x4e\x61\ \x6d\x65\x28\x68\x5b\x32\x5d\x29\x2c\x66\x29\x7d\x69\x66\x28\x65\ \x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x39\x29\x7b\x69\ \x66\x28\x62\x3d\x3d\x3d\x22\x62\x6f\x64\x79\x22\x26\x26\x65\x2e\ \x62\x6f\x64\x79\x29\x72\x65\x74\x75\x72\x6e\x20\x73\x28\x5b\x65\ \x2e\x62\x6f\x64\x79\x5d\x2c\x66\x29\x3b\x69\x66\x28\x68\x26\x26\ \x68\x5b\x33\x5d\x29\x7b\x76\x61\x72\x20\x69\x3d\x65\x2e\x67\x65\ \x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\x49\x64\x28\x68\x5b\x33\ \x5d\x29\x3b\x69\x66\x28\x21\x69\x7c\x7c\x21\x69\x2e\x70\x61\x72\ \x65\x6e\x74\x4e\x6f\x64\x65\x29\x72\x65\x74\x75\x72\x6e\x20\x73\ \x28\x5b\x5d\x2c\x66\x29\x3b\x69\x66\x28\x69\x2e\x69\x64\x3d\x3d\ \x3d\x68\x5b\x33\x5d\x29\x72\x65\x74\x75\x72\x6e\x20\x73\x28\x5b\ \x69\x5d\x2c\x66\x29\x7d\x74\x72\x79\x7b\x72\x65\x74\x75\x72\x6e\ \x20\x73\x28\x65\x2e\x71\x75\x65\x72\x79\x53\x65\x6c\x65\x63\x74\ \x6f\x72\x41\x6c\x6c\x28\x62\x29\x2c\x66\x29\x7d\x63\x61\x74\x63\ \x68\x28\x6a\x29\x7b\x7d\x7d\x65\x6c\x73\x65\x20\x69\x66\x28\x65\ \x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\x26\x65\ \x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\x65\ \x72\x43\x61\x73\x65\x28\x29\x21\x3d\x3d\x22\x6f\x62\x6a\x65\x63\ \x74\x22\x29\x7b\x76\x61\x72\x20\x6b\x3d\x65\x2c\x6c\x3d\x65\x2e\ \x67\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\x69\x64\ \x22\x29\x2c\x6e\x3d\x6c\x7c\x7c\x64\x2c\x70\x3d\x65\x2e\x70\x61\ \x72\x65\x6e\x74\x4e\x6f\x64\x65\x2c\x71\x3d\x2f\x5e\x5c\x73\x2a\ \x5b\x2b\x7e\x5d\x2f\x2e\x74\x65\x73\x74\x28\x62\x29\x3b\x6c\x3f\ \x6e\x3d\x6e\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x2f\x27\x2f\x67\ \x2c\x22\x5c\x5c\x24\x26\x22\x29\x3a\x65\x2e\x73\x65\x74\x41\x74\ \x74\x72\x69\x62\x75\x74\x65\x28\x22\x69\x64\x22\x2c\x6e\x29\x2c\ \x71\x26\x26\x70\x26\x26\x28\x65\x3d\x65\x2e\x70\x61\x72\x65\x6e\ \x74\x4e\x6f\x64\x65\x29\x3b\x74\x72\x79\x7b\x69\x66\x28\x21\x71\ \x7c\x7c\x70\x29\x72\x65\x74\x75\x72\x6e\x20\x73\x28\x65\x2e\x71\ \x75\x65\x72\x79\x53\x65\x6c\x65\x63\x74\x6f\x72\x41\x6c\x6c\x28\ \x22\x5b\x69\x64\x3d\x27\x22\x2b\x6e\x2b\x22\x27\x5d\x20\x22\x2b\ \x62\x29\x2c\x66\x29\x7d\x63\x61\x74\x63\x68\x28\x72\x29\x7b\x7d\ \x66\x69\x6e\x61\x6c\x6c\x79\x7b\x6c\x7c\x7c\x6b\x2e\x72\x65\x6d\ \x6f\x76\x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x22\x69\x64\ \x22\x29\x7d\x7d\x7d\x72\x65\x74\x75\x72\x6e\x20\x61\x28\x62\x2c\ \x65\x2c\x66\x2c\x67\x29\x7d\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\ \x65\x20\x69\x6e\x20\x61\x29\x6d\x5b\x65\x5d\x3d\x61\x5b\x65\x5d\ \x3b\x62\x3d\x6e\x75\x6c\x6c\x7d\x7d\x28\x29\x2c\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x61\x3d\x63\x2e\x64\ \x6f\x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2c\x62\ \x3d\x61\x2e\x6d\x61\x74\x63\x68\x65\x73\x53\x65\x6c\x65\x63\x74\ \x6f\x72\x7c\x7c\x61\x2e\x6d\x6f\x7a\x4d\x61\x74\x63\x68\x65\x73\ \x53\x65\x6c\x65\x63\x74\x6f\x72\x7c\x7c\x61\x2e\x77\x65\x62\x6b\ \x69\x74\x4d\x61\x74\x63\x68\x65\x73\x53\x65\x6c\x65\x63\x74\x6f\ \x72\x7c\x7c\x61\x2e\x6d\x73\x4d\x61\x74\x63\x68\x65\x73\x53\x65\ \x6c\x65\x63\x74\x6f\x72\x3b\x69\x66\x28\x62\x29\x7b\x76\x61\x72\ \x20\x64\x3d\x21\x62\x2e\x63\x61\x6c\x6c\x28\x63\x2e\x63\x72\x65\ \x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x64\x69\x76\x22\ \x29\x2c\x22\x64\x69\x76\x22\x29\x2c\x65\x3d\x21\x31\x3b\x74\x72\ \x79\x7b\x62\x2e\x63\x61\x6c\x6c\x28\x63\x2e\x64\x6f\x63\x75\x6d\ \x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2c\x22\x5b\x74\x65\x73\ \x74\x21\x3d\x27\x27\x5d\x3a\x73\x69\x7a\x7a\x6c\x65\x22\x29\x7d\ \x63\x61\x74\x63\x68\x28\x66\x29\x7b\x65\x3d\x21\x30\x7d\x6d\x2e\ \x6d\x61\x74\x63\x68\x65\x73\x53\x65\x6c\x65\x63\x74\x6f\x72\x3d\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x63\x3d\ \x63\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x2f\x5c\x3d\x5c\x73\x2a\ \x28\x5b\x5e\x27\x22\x5c\x5d\x5d\x2a\x29\x5c\x73\x2a\x5c\x5d\x2f\ \x67\x2c\x22\x3d\x27\x24\x31\x27\x5d\x22\x29\x3b\x69\x66\x28\x21\ \x6d\x2e\x69\x73\x58\x4d\x4c\x28\x61\x29\x29\x74\x72\x79\x7b\x69\ \x66\x28\x65\x7c\x7c\x21\x6f\x2e\x6d\x61\x74\x63\x68\x2e\x50\x53\ \x45\x55\x44\x4f\x2e\x74\x65\x73\x74\x28\x63\x29\x26\x26\x21\x2f\ \x21\x3d\x2f\x2e\x74\x65\x73\x74\x28\x63\x29\x29\x7b\x76\x61\x72\ \x20\x66\x3d\x62\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x63\x29\x3b\x69\ \x66\x28\x66\x7c\x7c\x21\x64\x7c\x7c\x61\x2e\x64\x6f\x63\x75\x6d\ \x65\x6e\x74\x26\x26\x61\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\ \x6e\x6f\x64\x65\x54\x79\x70\x65\x21\x3d\x3d\x31\x31\x29\x72\x65\ \x74\x75\x72\x6e\x20\x66\x7d\x7d\x63\x61\x74\x63\x68\x28\x67\x29\ \x7b\x7d\x72\x65\x74\x75\x72\x6e\x20\x6d\x28\x63\x2c\x6e\x75\x6c\ \x6c\x2c\x6e\x75\x6c\x6c\x2c\x5b\x61\x5d\x29\x2e\x6c\x65\x6e\x67\ \x74\x68\x3e\x30\x7d\x7d\x7d\x28\x29\x2c\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x61\x3d\x63\x2e\x63\x72\x65\ \x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x64\x69\x76\x22\ \x29\x3b\x61\x2e\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c\x3d\x22\x3c\ \x64\x69\x76\x20\x63\x6c\x61\x73\x73\x3d\x27\x74\x65\x73\x74\x20\ \x65\x27\x3e\x3c\x2f\x64\x69\x76\x3e\x3c\x64\x69\x76\x20\x63\x6c\ \x61\x73\x73\x3d\x27\x74\x65\x73\x74\x27\x3e\x3c\x2f\x64\x69\x76\ \x3e\x22\x3b\x69\x66\x28\x21\x21\x61\x2e\x67\x65\x74\x45\x6c\x65\ \x6d\x65\x6e\x74\x73\x42\x79\x43\x6c\x61\x73\x73\x4e\x61\x6d\x65\ \x26\x26\x61\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\ \x79\x43\x6c\x61\x73\x73\x4e\x61\x6d\x65\x28\x22\x65\x22\x29\x2e\ \x6c\x65\x6e\x67\x74\x68\x21\x3d\x3d\x30\x29\x7b\x61\x2e\x6c\x61\ \x73\x74\x43\x68\x69\x6c\x64\x2e\x63\x6c\x61\x73\x73\x4e\x61\x6d\ \x65\x3d\x22\x65\x22\x3b\x69\x66\x28\x61\x2e\x67\x65\x74\x45\x6c\ \x65\x6d\x65\x6e\x74\x73\x42\x79\x43\x6c\x61\x73\x73\x4e\x61\x6d\ \x65\x28\x22\x65\x22\x29\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x3d\x3d\ \x31\x29\x72\x65\x74\x75\x72\x6e\x3b\x6f\x2e\x6f\x72\x64\x65\x72\ \x2e\x73\x70\x6c\x69\x63\x65\x28\x31\x2c\x30\x2c\x22\x43\x4c\x41\ \x53\x53\x22\x29\x2c\x6f\x2e\x66\x69\x6e\x64\x2e\x43\x4c\x41\x53\ \x53\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\ \x29\x7b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x62\x2e\x67\x65\ \x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x43\x6c\x61\x73\x73\ \x4e\x61\x6d\x65\x21\x3d\x22\x75\x6e\x64\x65\x66\x69\x6e\x65\x64\ \x22\x26\x26\x21\x63\x29\x72\x65\x74\x75\x72\x6e\x20\x62\x2e\x67\ \x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x43\x6c\x61\x73\ \x73\x4e\x61\x6d\x65\x28\x61\x5b\x31\x5d\x29\x7d\x2c\x61\x3d\x6e\ \x75\x6c\x6c\x7d\x7d\x28\x29\x2c\x63\x2e\x64\x6f\x63\x75\x6d\x65\ \x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2e\x63\x6f\x6e\x74\x61\x69\ \x6e\x73\x3f\x6d\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\x3d\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x61\x21\x3d\x3d\x62\x26\x26\x28\x61\x2e\x63\x6f\x6e\ \x74\x61\x69\x6e\x73\x3f\x61\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\ \x28\x62\x29\x3a\x21\x30\x29\x7d\x3a\x63\x2e\x64\x6f\x63\x75\x6d\ \x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2e\x63\x6f\x6d\x70\x61\ \x72\x65\x44\x6f\x63\x75\x6d\x65\x6e\x74\x50\x6f\x73\x69\x74\x69\ \x6f\x6e\x3f\x6d\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\x3d\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x21\x21\x28\x61\x2e\x63\x6f\x6d\x70\x61\x72\x65\x44\x6f\ \x63\x75\x6d\x65\x6e\x74\x50\x6f\x73\x69\x74\x69\x6f\x6e\x28\x62\ \x29\x26\x31\x36\x29\x7d\x3a\x6d\x2e\x63\x6f\x6e\x74\x61\x69\x6e\ \x73\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x21\x31\x7d\x2c\x6d\x2e\x69\x73\x58\x4d\x4c\x3d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\ \x3d\x28\x61\x3f\x61\x2e\x6f\x77\x6e\x65\x72\x44\x6f\x63\x75\x6d\ \x65\x6e\x74\x7c\x7c\x61\x3a\x30\x29\x2e\x64\x6f\x63\x75\x6d\x65\ \x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x62\x3f\x62\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x21\x3d\x3d\ \x22\x48\x54\x4d\x4c\x22\x3a\x21\x31\x7d\x3b\x76\x61\x72\x20\x79\ \x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\ \x7b\x76\x61\x72\x20\x64\x2c\x65\x3d\x5b\x5d\x2c\x66\x3d\x22\x22\ \x2c\x67\x3d\x62\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3f\x5b\x62\ \x5d\x3a\x62\x3b\x77\x68\x69\x6c\x65\x28\x64\x3d\x6f\x2e\x6d\x61\ \x74\x63\x68\x2e\x50\x53\x45\x55\x44\x4f\x2e\x65\x78\x65\x63\x28\ \x61\x29\x29\x66\x2b\x3d\x64\x5b\x30\x5d\x2c\x61\x3d\x61\x2e\x72\ \x65\x70\x6c\x61\x63\x65\x28\x6f\x2e\x6d\x61\x74\x63\x68\x2e\x50\ \x53\x45\x55\x44\x4f\x2c\x22\x22\x29\x3b\x61\x3d\x6f\x2e\x72\x65\ \x6c\x61\x74\x69\x76\x65\x5b\x61\x5d\x3f\x61\x2b\x22\x2a\x22\x3a\ \x61\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\x68\x3d\x30\x2c\x69\x3d\ \x67\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x68\x3c\x69\x3b\x68\x2b\x2b\ \x29\x6d\x28\x61\x2c\x67\x5b\x68\x5d\x2c\x65\x2c\x63\x29\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x6d\x2e\x66\x69\x6c\x74\x65\x72\x28\x66\ \x2c\x65\x29\x7d\x3b\x6d\x2e\x61\x74\x74\x72\x3d\x66\x2e\x61\x74\ \x74\x72\x2c\x6d\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x73\x2e\x61\ \x74\x74\x72\x4d\x61\x70\x3d\x7b\x7d\x2c\x66\x2e\x66\x69\x6e\x64\ \x3d\x6d\x2c\x66\x2e\x65\x78\x70\x72\x3d\x6d\x2e\x73\x65\x6c\x65\ \x63\x74\x6f\x72\x73\x2c\x66\x2e\x65\x78\x70\x72\x5b\x22\x3a\x22\ \x5d\x3d\x66\x2e\x65\x78\x70\x72\x2e\x66\x69\x6c\x74\x65\x72\x73\ \x2c\x66\x2e\x75\x6e\x69\x71\x75\x65\x3d\x6d\x2e\x75\x6e\x69\x71\ \x75\x65\x53\x6f\x72\x74\x2c\x66\x2e\x74\x65\x78\x74\x3d\x6d\x2e\ \x67\x65\x74\x54\x65\x78\x74\x2c\x66\x2e\x69\x73\x58\x4d\x4c\x44\ \x6f\x63\x3d\x6d\x2e\x69\x73\x58\x4d\x4c\x2c\x66\x2e\x63\x6f\x6e\ \x74\x61\x69\x6e\x73\x3d\x6d\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\ \x7d\x28\x29\x3b\x76\x61\x72\x20\x4c\x3d\x2f\x55\x6e\x74\x69\x6c\ \x24\x2f\x2c\x4d\x3d\x2f\x5e\x28\x3f\x3a\x70\x61\x72\x65\x6e\x74\ \x73\x7c\x70\x72\x65\x76\x55\x6e\x74\x69\x6c\x7c\x70\x72\x65\x76\ \x41\x6c\x6c\x29\x2f\x2c\x4e\x3d\x2f\x2c\x2f\x2c\x4f\x3d\x2f\x5e\ \x2e\x5b\x5e\x3a\x23\x5c\x5b\x5c\x2e\x2c\x5d\x2a\x24\x2f\x2c\x50\ \x3d\x41\x72\x72\x61\x79\x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\x65\ \x2e\x73\x6c\x69\x63\x65\x2c\x51\x3d\x66\x2e\x65\x78\x70\x72\x2e\ \x6d\x61\x74\x63\x68\x2e\x50\x4f\x53\x2c\x52\x3d\x7b\x63\x68\x69\ \x6c\x64\x72\x65\x6e\x3a\x21\x30\x2c\x63\x6f\x6e\x74\x65\x6e\x74\ \x73\x3a\x21\x30\x2c\x6e\x65\x78\x74\x3a\x21\x30\x2c\x70\x72\x65\ \x76\x3a\x21\x30\x7d\x3b\x66\x2e\x66\x6e\x2e\x65\x78\x74\x65\x6e\ \x64\x28\x7b\x66\x69\x6e\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x76\x61\x72\x20\x62\x3d\x74\x68\x69\x73\x2c\x63\ \x2c\x64\x3b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x61\x21\x3d\ \x22\x73\x74\x72\x69\x6e\x67\x22\x29\x72\x65\x74\x75\x72\x6e\x20\ \x66\x28\x61\x29\x2e\x66\x69\x6c\x74\x65\x72\x28\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x29\x7b\x66\x6f\x72\x28\x63\x3d\x30\x2c\x64\ \x3d\x62\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x63\x3c\x64\x3b\x63\x2b\ \x2b\x29\x69\x66\x28\x66\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\x28\ \x62\x5b\x63\x5d\x2c\x74\x68\x69\x73\x29\x29\x72\x65\x74\x75\x72\ \x6e\x21\x30\x7d\x29\x3b\x76\x61\x72\x20\x65\x3d\x74\x68\x69\x73\ \x2e\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x28\x22\x22\x2c\x22\x66\ \x69\x6e\x64\x22\x2c\x61\x29\x2c\x67\x2c\x68\x2c\x69\x3b\x66\x6f\ \x72\x28\x63\x3d\x30\x2c\x64\x3d\x74\x68\x69\x73\x2e\x6c\x65\x6e\ \x67\x74\x68\x3b\x63\x3c\x64\x3b\x63\x2b\x2b\x29\x7b\x67\x3d\x65\ \x2e\x6c\x65\x6e\x67\x74\x68\x2c\x66\x2e\x66\x69\x6e\x64\x28\x61\ \x2c\x74\x68\x69\x73\x5b\x63\x5d\x2c\x65\x29\x3b\x69\x66\x28\x63\ \x3e\x30\x29\x66\x6f\x72\x28\x68\x3d\x67\x3b\x68\x3c\x65\x2e\x6c\ \x65\x6e\x67\x74\x68\x3b\x68\x2b\x2b\x29\x66\x6f\x72\x28\x69\x3d\ \x30\x3b\x69\x3c\x67\x3b\x69\x2b\x2b\x29\x69\x66\x28\x65\x5b\x69\ \x5d\x3d\x3d\x3d\x65\x5b\x68\x5d\x29\x7b\x65\x2e\x73\x70\x6c\x69\ \x63\x65\x28\x68\x2d\x2d\x2c\x31\x29\x3b\x62\x72\x65\x61\x6b\x7d\ \x7d\x72\x65\x74\x75\x72\x6e\x20\x65\x7d\x2c\x68\x61\x73\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\ \x3d\x66\x28\x61\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x2e\x66\x69\x6c\x74\x65\x72\x28\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x66\x6f\x72\x28\x76\x61\x72\x20\x61\x3d\x30\x2c\ \x63\x3d\x62\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x61\x3c\x63\x3b\x61\ \x2b\x2b\x29\x69\x66\x28\x66\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\ \x28\x74\x68\x69\x73\x2c\x62\x5b\x61\x5d\x29\x29\x72\x65\x74\x75\ \x72\x6e\x21\x30\x7d\x29\x7d\x2c\x6e\x6f\x74\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x2e\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x28\x54\x28\ \x74\x68\x69\x73\x2c\x61\x2c\x21\x31\x29\x2c\x22\x6e\x6f\x74\x22\ \x2c\x61\x29\x7d\x2c\x66\x69\x6c\x74\x65\x72\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x2e\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x28\x54\x28\ \x74\x68\x69\x73\x2c\x61\x2c\x21\x30\x29\x2c\x22\x66\x69\x6c\x74\ \x65\x72\x22\x2c\x61\x29\x7d\x2c\x69\x73\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\x21\x61\ \x26\x26\x28\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x73\x74\ \x72\x69\x6e\x67\x22\x3f\x51\x2e\x74\x65\x73\x74\x28\x61\x29\x3f\ \x66\x28\x61\x2c\x74\x68\x69\x73\x2e\x63\x6f\x6e\x74\x65\x78\x74\ \x29\x2e\x69\x6e\x64\x65\x78\x28\x74\x68\x69\x73\x5b\x30\x5d\x29\ \x3e\x3d\x30\x3a\x66\x2e\x66\x69\x6c\x74\x65\x72\x28\x61\x2c\x74\ \x68\x69\x73\x29\x2e\x6c\x65\x6e\x67\x74\x68\x3e\x30\x3a\x74\x68\ \x69\x73\x2e\x66\x69\x6c\x74\x65\x72\x28\x61\x29\x2e\x6c\x65\x6e\ \x67\x74\x68\x3e\x30\x29\x7d\x2c\x63\x6c\x6f\x73\x65\x73\x74\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\ \x72\x20\x63\x3d\x5b\x5d\x2c\x64\x2c\x65\x2c\x67\x3d\x74\x68\x69\ \x73\x5b\x30\x5d\x3b\x69\x66\x28\x66\x2e\x69\x73\x41\x72\x72\x61\ \x79\x28\x61\x29\x29\x7b\x76\x61\x72\x20\x68\x3d\x31\x3b\x77\x68\ \x69\x6c\x65\x28\x67\x26\x26\x67\x2e\x6f\x77\x6e\x65\x72\x44\x6f\ \x63\x75\x6d\x65\x6e\x74\x26\x26\x67\x21\x3d\x3d\x62\x29\x7b\x66\ \x6f\x72\x28\x64\x3d\x30\x3b\x64\x3c\x61\x2e\x6c\x65\x6e\x67\x74\ \x68\x3b\x64\x2b\x2b\x29\x66\x28\x67\x29\x2e\x69\x73\x28\x61\x5b\ \x64\x5d\x29\x26\x26\x63\x2e\x70\x75\x73\x68\x28\x7b\x73\x65\x6c\ \x65\x63\x74\x6f\x72\x3a\x61\x5b\x64\x5d\x2c\x65\x6c\x65\x6d\x3a\ \x67\x2c\x6c\x65\x76\x65\x6c\x3a\x68\x7d\x29\x3b\x67\x3d\x67\x2e\ \x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x2c\x68\x2b\x2b\x7d\x72\ \x65\x74\x75\x72\x6e\x20\x63\x7d\x76\x61\x72\x20\x69\x3d\x51\x2e\ \x74\x65\x73\x74\x28\x61\x29\x7c\x7c\x74\x79\x70\x65\x6f\x66\x20\ \x61\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x3f\x66\x28\x61\x2c\ \x62\x7c\x7c\x74\x68\x69\x73\x2e\x63\x6f\x6e\x74\x65\x78\x74\x29\ \x3a\x30\x3b\x66\x6f\x72\x28\x64\x3d\x30\x2c\x65\x3d\x74\x68\x69\ \x73\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x64\x3c\x65\x3b\x64\x2b\x2b\ \x29\x7b\x67\x3d\x74\x68\x69\x73\x5b\x64\x5d\x3b\x77\x68\x69\x6c\ \x65\x28\x67\x29\x7b\x69\x66\x28\x69\x3f\x69\x2e\x69\x6e\x64\x65\ \x78\x28\x67\x29\x3e\x2d\x31\x3a\x66\x2e\x66\x69\x6e\x64\x2e\x6d\ \x61\x74\x63\x68\x65\x73\x53\x65\x6c\x65\x63\x74\x6f\x72\x28\x67\ \x2c\x61\x29\x29\x7b\x63\x2e\x70\x75\x73\x68\x28\x67\x29\x3b\x62\ \x72\x65\x61\x6b\x7d\x67\x3d\x67\x2e\x70\x61\x72\x65\x6e\x74\x4e\ \x6f\x64\x65\x3b\x69\x66\x28\x21\x67\x7c\x7c\x21\x67\x2e\x6f\x77\ \x6e\x65\x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x7c\x7c\x67\x3d\x3d\ \x3d\x62\x7c\x7c\x67\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\ \x3d\x31\x31\x29\x62\x72\x65\x61\x6b\x7d\x7d\x63\x3d\x63\x2e\x6c\ \x65\x6e\x67\x74\x68\x3e\x31\x3f\x66\x2e\x75\x6e\x69\x71\x75\x65\ \x28\x63\x29\x3a\x63\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x2e\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x28\x63\x2c\x22\x63\ \x6c\x6f\x73\x65\x73\x74\x22\x2c\x61\x29\x7d\x2c\x69\x6e\x64\x65\ \x78\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\ \x28\x21\x61\x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x5b\ \x30\x5d\x26\x26\x74\x68\x69\x73\x5b\x30\x5d\x2e\x70\x61\x72\x65\ \x6e\x74\x4e\x6f\x64\x65\x3f\x74\x68\x69\x73\x2e\x70\x72\x65\x76\ \x41\x6c\x6c\x28\x29\x2e\x6c\x65\x6e\x67\x74\x68\x3a\x2d\x31\x3b\ \x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x73\x74\ \x72\x69\x6e\x67\x22\x29\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x69\ \x6e\x41\x72\x72\x61\x79\x28\x74\x68\x69\x73\x5b\x30\x5d\x2c\x66\ \x28\x61\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x69\x6e\ \x41\x72\x72\x61\x79\x28\x61\x2e\x6a\x71\x75\x65\x72\x79\x3f\x61\ \x5b\x30\x5d\x3a\x61\x2c\x74\x68\x69\x73\x29\x7d\x2c\x61\x64\x64\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\ \x61\x72\x20\x63\x3d\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\ \x73\x74\x72\x69\x6e\x67\x22\x3f\x66\x28\x61\x2c\x62\x29\x3a\x66\ \x2e\x6d\x61\x6b\x65\x41\x72\x72\x61\x79\x28\x61\x26\x26\x61\x2e\ \x6e\x6f\x64\x65\x54\x79\x70\x65\x3f\x5b\x61\x5d\x3a\x61\x29\x2c\ \x64\x3d\x66\x2e\x6d\x65\x72\x67\x65\x28\x74\x68\x69\x73\x2e\x67\ \x65\x74\x28\x29\x2c\x63\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x2e\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x28\x53\x28\ \x63\x5b\x30\x5d\x29\x7c\x7c\x53\x28\x64\x5b\x30\x5d\x29\x3f\x64\ \x3a\x66\x2e\x75\x6e\x69\x71\x75\x65\x28\x64\x29\x29\x7d\x2c\x61\ \x6e\x64\x53\x65\x6c\x66\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x61\x64\ \x64\x28\x74\x68\x69\x73\x2e\x70\x72\x65\x76\x4f\x62\x6a\x65\x63\ \x74\x29\x7d\x7d\x29\x2c\x66\x2e\x65\x61\x63\x68\x28\x7b\x70\x61\ \x72\x65\x6e\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x76\x61\x72\x20\x62\x3d\x61\x2e\x70\x61\x72\x65\x6e\x74\x4e\ \x6f\x64\x65\x3b\x72\x65\x74\x75\x72\x6e\x20\x62\x26\x26\x62\x2e\ \x6e\x6f\x64\x65\x54\x79\x70\x65\x21\x3d\x3d\x31\x31\x3f\x62\x3a\ \x6e\x75\x6c\x6c\x7d\x2c\x70\x61\x72\x65\x6e\x74\x73\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\ \x20\x66\x2e\x64\x69\x72\x28\x61\x2c\x22\x70\x61\x72\x65\x6e\x74\ \x4e\x6f\x64\x65\x22\x29\x7d\x2c\x70\x61\x72\x65\x6e\x74\x73\x55\ \x6e\x74\x69\x6c\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x2c\x63\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x64\x69\ \x72\x28\x61\x2c\x22\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x22\ \x2c\x63\x29\x7d\x2c\x6e\x65\x78\x74\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x6e\ \x74\x68\x28\x61\x2c\x32\x2c\x22\x6e\x65\x78\x74\x53\x69\x62\x6c\ \x69\x6e\x67\x22\x29\x7d\x2c\x70\x72\x65\x76\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\ \x2e\x6e\x74\x68\x28\x61\x2c\x32\x2c\x22\x70\x72\x65\x76\x69\x6f\ \x75\x73\x53\x69\x62\x6c\x69\x6e\x67\x22\x29\x7d\x2c\x6e\x65\x78\ \x74\x41\x6c\x6c\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x64\x69\x72\x28\x61\x2c\ \x22\x6e\x65\x78\x74\x53\x69\x62\x6c\x69\x6e\x67\x22\x29\x7d\x2c\ \x70\x72\x65\x76\x41\x6c\x6c\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x64\x69\x72\ \x28\x61\x2c\x22\x70\x72\x65\x76\x69\x6f\x75\x73\x53\x69\x62\x6c\ \x69\x6e\x67\x22\x29\x7d\x2c\x6e\x65\x78\x74\x55\x6e\x74\x69\x6c\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x64\x69\x72\x28\x61\x2c\ \x22\x6e\x65\x78\x74\x53\x69\x62\x6c\x69\x6e\x67\x22\x2c\x63\x29\ \x7d\x2c\x70\x72\x65\x76\x55\x6e\x74\x69\x6c\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x66\x2e\x64\x69\x72\x28\x61\x2c\x22\x70\x72\x65\x76\ \x69\x6f\x75\x73\x53\x69\x62\x6c\x69\x6e\x67\x22\x2c\x63\x29\x7d\ \x2c\x73\x69\x62\x6c\x69\x6e\x67\x73\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x73\ \x69\x62\x6c\x69\x6e\x67\x28\x61\x2e\x70\x61\x72\x65\x6e\x74\x4e\ \x6f\x64\x65\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x2c\x61\ \x29\x7d\x2c\x63\x68\x69\x6c\x64\x72\x65\x6e\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\ \x2e\x73\x69\x62\x6c\x69\x6e\x67\x28\x61\x2e\x66\x69\x72\x73\x74\ \x43\x68\x69\x6c\x64\x29\x7d\x2c\x63\x6f\x6e\x74\x65\x6e\x74\x73\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x66\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x28\x61\ \x2c\x22\x69\x66\x72\x61\x6d\x65\x22\x29\x3f\x61\x2e\x63\x6f\x6e\ \x74\x65\x6e\x74\x44\x6f\x63\x75\x6d\x65\x6e\x74\x7c\x7c\x61\x2e\ \x63\x6f\x6e\x74\x65\x6e\x74\x57\x69\x6e\x64\x6f\x77\x2e\x64\x6f\ \x63\x75\x6d\x65\x6e\x74\x3a\x66\x2e\x6d\x61\x6b\x65\x41\x72\x72\ \x61\x79\x28\x61\x2e\x63\x68\x69\x6c\x64\x4e\x6f\x64\x65\x73\x29\ \x7d\x7d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\ \x7b\x66\x2e\x66\x6e\x5b\x61\x5d\x3d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x63\x2c\x64\x29\x7b\x76\x61\x72\x20\x65\x3d\x66\x2e\x6d\ \x61\x70\x28\x74\x68\x69\x73\x2c\x62\x2c\x63\x29\x3b\x4c\x2e\x74\ \x65\x73\x74\x28\x61\x29\x7c\x7c\x28\x64\x3d\x63\x29\x2c\x64\x26\ \x26\x74\x79\x70\x65\x6f\x66\x20\x64\x3d\x3d\x22\x73\x74\x72\x69\ \x6e\x67\x22\x26\x26\x28\x65\x3d\x66\x2e\x66\x69\x6c\x74\x65\x72\ \x28\x64\x2c\x65\x29\x29\x2c\x65\x3d\x74\x68\x69\x73\x2e\x6c\x65\ \x6e\x67\x74\x68\x3e\x31\x26\x26\x21\x52\x5b\x61\x5d\x3f\x66\x2e\ \x75\x6e\x69\x71\x75\x65\x28\x65\x29\x3a\x65\x2c\x28\x74\x68\x69\ \x73\x2e\x6c\x65\x6e\x67\x74\x68\x3e\x31\x7c\x7c\x4e\x2e\x74\x65\ \x73\x74\x28\x64\x29\x29\x26\x26\x4d\x2e\x74\x65\x73\x74\x28\x61\ \x29\x26\x26\x28\x65\x3d\x65\x2e\x72\x65\x76\x65\x72\x73\x65\x28\ \x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x70\ \x75\x73\x68\x53\x74\x61\x63\x6b\x28\x65\x2c\x61\x2c\x50\x2e\x63\ \x61\x6c\x6c\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x2e\x6a\ \x6f\x69\x6e\x28\x22\x2c\x22\x29\x29\x7d\x7d\x29\x2c\x66\x2e\x65\ \x78\x74\x65\x6e\x64\x28\x7b\x66\x69\x6c\x74\x65\x72\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x63\x26\ \x26\x28\x61\x3d\x22\x3a\x6e\x6f\x74\x28\x22\x2b\x61\x2b\x22\x29\ \x22\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x62\x2e\x6c\x65\x6e\x67\ \x74\x68\x3d\x3d\x3d\x31\x3f\x66\x2e\x66\x69\x6e\x64\x2e\x6d\x61\ \x74\x63\x68\x65\x73\x53\x65\x6c\x65\x63\x74\x6f\x72\x28\x62\x5b\ \x30\x5d\x2c\x61\x29\x3f\x5b\x62\x5b\x30\x5d\x5d\x3a\x5b\x5d\x3a\ \x66\x2e\x66\x69\x6e\x64\x2e\x6d\x61\x74\x63\x68\x65\x73\x28\x61\ \x2c\x62\x29\x7d\x2c\x64\x69\x72\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x63\x2c\x64\x29\x7b\x76\x61\x72\x20\x65\x3d\x5b\ \x5d\x2c\x67\x3d\x61\x5b\x63\x5d\x3b\x77\x68\x69\x6c\x65\x28\x67\ \x26\x26\x67\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x21\x3d\x3d\x39\ \x26\x26\x28\x64\x3d\x3d\x3d\x62\x7c\x7c\x67\x2e\x6e\x6f\x64\x65\ \x54\x79\x70\x65\x21\x3d\x3d\x31\x7c\x7c\x21\x66\x28\x67\x29\x2e\ \x69\x73\x28\x64\x29\x29\x29\x67\x2e\x6e\x6f\x64\x65\x54\x79\x70\ \x65\x3d\x3d\x3d\x31\x26\x26\x65\x2e\x70\x75\x73\x68\x28\x67\x29\ \x2c\x67\x3d\x67\x5b\x63\x5d\x3b\x72\x65\x74\x75\x72\x6e\x20\x65\ \x7d\x2c\x6e\x74\x68\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x62\x2c\x63\x2c\x64\x29\x7b\x62\x3d\x62\x7c\x7c\x31\x3b\x76\ \x61\x72\x20\x65\x3d\x30\x3b\x66\x6f\x72\x28\x3b\x61\x3b\x61\x3d\ \x61\x5b\x63\x5d\x29\x69\x66\x28\x61\x2e\x6e\x6f\x64\x65\x54\x79\ \x70\x65\x3d\x3d\x3d\x31\x26\x26\x2b\x2b\x65\x3d\x3d\x3d\x62\x29\ \x62\x72\x65\x61\x6b\x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x7d\x2c\ \x73\x69\x62\x6c\x69\x6e\x67\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x5b\x5d\x3b\x66\ \x6f\x72\x28\x3b\x61\x3b\x61\x3d\x61\x2e\x6e\x65\x78\x74\x53\x69\ \x62\x6c\x69\x6e\x67\x29\x61\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\ \x3d\x3d\x3d\x31\x26\x26\x61\x21\x3d\x3d\x62\x26\x26\x63\x2e\x70\ \x75\x73\x68\x28\x61\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x63\x7d\ \x7d\x29\x3b\x76\x61\x72\x20\x56\x3d\x22\x61\x62\x62\x72\x7c\x61\ \x72\x74\x69\x63\x6c\x65\x7c\x61\x73\x69\x64\x65\x7c\x61\x75\x64\ \x69\x6f\x7c\x63\x61\x6e\x76\x61\x73\x7c\x64\x61\x74\x61\x6c\x69\ \x73\x74\x7c\x64\x65\x74\x61\x69\x6c\x73\x7c\x66\x69\x67\x63\x61\ \x70\x74\x69\x6f\x6e\x7c\x66\x69\x67\x75\x72\x65\x7c\x66\x6f\x6f\ \x74\x65\x72\x7c\x68\x65\x61\x64\x65\x72\x7c\x68\x67\x72\x6f\x75\ \x70\x7c\x6d\x61\x72\x6b\x7c\x6d\x65\x74\x65\x72\x7c\x6e\x61\x76\ \x7c\x6f\x75\x74\x70\x75\x74\x7c\x70\x72\x6f\x67\x72\x65\x73\x73\ \x7c\x73\x65\x63\x74\x69\x6f\x6e\x7c\x73\x75\x6d\x6d\x61\x72\x79\ \x7c\x74\x69\x6d\x65\x7c\x76\x69\x64\x65\x6f\x22\x2c\x57\x3d\x2f\ \x20\x6a\x51\x75\x65\x72\x79\x5c\x64\x2b\x3d\x22\x28\x3f\x3a\x5c\ \x64\x2b\x7c\x6e\x75\x6c\x6c\x29\x22\x2f\x67\x2c\x58\x3d\x2f\x5e\ \x5c\x73\x2b\x2f\x2c\x59\x3d\x2f\x3c\x28\x3f\x21\x61\x72\x65\x61\ \x7c\x62\x72\x7c\x63\x6f\x6c\x7c\x65\x6d\x62\x65\x64\x7c\x68\x72\ \x7c\x69\x6d\x67\x7c\x69\x6e\x70\x75\x74\x7c\x6c\x69\x6e\x6b\x7c\ \x6d\x65\x74\x61\x7c\x70\x61\x72\x61\x6d\x29\x28\x28\x5b\x5c\x77\ \x3a\x5d\x2b\x29\x5b\x5e\x3e\x5d\x2a\x29\x5c\x2f\x3e\x2f\x69\x67\ \x2c\x5a\x3d\x2f\x3c\x28\x5b\x5c\x77\x3a\x5d\x2b\x29\x2f\x2c\x24\ \x3d\x2f\x3c\x74\x62\x6f\x64\x79\x2f\x69\x2c\x5f\x3d\x2f\x3c\x7c\ \x26\x23\x3f\x5c\x77\x2b\x3b\x2f\x2c\x62\x61\x3d\x2f\x3c\x28\x3f\ \x3a\x73\x63\x72\x69\x70\x74\x7c\x73\x74\x79\x6c\x65\x29\x2f\x69\ \x2c\x62\x62\x3d\x2f\x3c\x28\x3f\x3a\x73\x63\x72\x69\x70\x74\x7c\ \x6f\x62\x6a\x65\x63\x74\x7c\x65\x6d\x62\x65\x64\x7c\x6f\x70\x74\ \x69\x6f\x6e\x7c\x73\x74\x79\x6c\x65\x29\x2f\x69\x2c\x62\x63\x3d\ \x6e\x65\x77\x20\x52\x65\x67\x45\x78\x70\x28\x22\x3c\x28\x3f\x3a\ \x22\x2b\x56\x2b\x22\x29\x22\x2c\x22\x69\x22\x29\x2c\x62\x64\x3d\ \x2f\x63\x68\x65\x63\x6b\x65\x64\x5c\x73\x2a\x28\x3f\x3a\x5b\x5e\ \x3d\x5d\x7c\x3d\x5c\x73\x2a\x2e\x63\x68\x65\x63\x6b\x65\x64\x2e\ \x29\x2f\x69\x2c\x62\x65\x3d\x2f\x5c\x2f\x28\x6a\x61\x76\x61\x7c\ \x65\x63\x6d\x61\x29\x73\x63\x72\x69\x70\x74\x2f\x69\x2c\x62\x66\ \x3d\x2f\x5e\x5c\x73\x2a\x3c\x21\x28\x3f\x3a\x5c\x5b\x43\x44\x41\ \x54\x41\x5c\x5b\x7c\x5c\x2d\x5c\x2d\x29\x2f\x2c\x62\x67\x3d\x7b\ \x6f\x70\x74\x69\x6f\x6e\x3a\x5b\x31\x2c\x22\x3c\x73\x65\x6c\x65\ \x63\x74\x20\x6d\x75\x6c\x74\x69\x70\x6c\x65\x3d\x27\x6d\x75\x6c\ \x74\x69\x70\x6c\x65\x27\x3e\x22\x2c\x22\x3c\x2f\x73\x65\x6c\x65\ \x63\x74\x3e\x22\x5d\x2c\x6c\x65\x67\x65\x6e\x64\x3a\x5b\x31\x2c\ \x22\x3c\x66\x69\x65\x6c\x64\x73\x65\x74\x3e\x22\x2c\x22\x3c\x2f\ \x66\x69\x65\x6c\x64\x73\x65\x74\x3e\x22\x5d\x2c\x74\x68\x65\x61\ \x64\x3a\x5b\x31\x2c\x22\x3c\x74\x61\x62\x6c\x65\x3e\x22\x2c\x22\ \x3c\x2f\x74\x61\x62\x6c\x65\x3e\x22\x5d\x2c\x74\x72\x3a\x5b\x32\ \x2c\x22\x3c\x74\x61\x62\x6c\x65\x3e\x3c\x74\x62\x6f\x64\x79\x3e\ \x22\x2c\x22\x3c\x2f\x74\x62\x6f\x64\x79\x3e\x3c\x2f\x74\x61\x62\ \x6c\x65\x3e\x22\x5d\x2c\x74\x64\x3a\x5b\x33\x2c\x22\x3c\x74\x61\ \x62\x6c\x65\x3e\x3c\x74\x62\x6f\x64\x79\x3e\x3c\x74\x72\x3e\x22\ \x2c\x22\x3c\x2f\x74\x72\x3e\x3c\x2f\x74\x62\x6f\x64\x79\x3e\x3c\ \x2f\x74\x61\x62\x6c\x65\x3e\x22\x5d\x2c\x63\x6f\x6c\x3a\x5b\x32\ \x2c\x22\x3c\x74\x61\x62\x6c\x65\x3e\x3c\x74\x62\x6f\x64\x79\x3e\ \x3c\x2f\x74\x62\x6f\x64\x79\x3e\x3c\x63\x6f\x6c\x67\x72\x6f\x75\ \x70\x3e\x22\x2c\x22\x3c\x2f\x63\x6f\x6c\x67\x72\x6f\x75\x70\x3e\ \x3c\x2f\x74\x61\x62\x6c\x65\x3e\x22\x5d\x2c\x61\x72\x65\x61\x3a\ \x5b\x31\x2c\x22\x3c\x6d\x61\x70\x3e\x22\x2c\x22\x3c\x2f\x6d\x61\ \x70\x3e\x22\x5d\x2c\x5f\x64\x65\x66\x61\x75\x6c\x74\x3a\x5b\x30\ \x2c\x22\x22\x2c\x22\x22\x5d\x7d\x2c\x62\x68\x3d\x55\x28\x63\x29\ \x3b\x62\x67\x2e\x6f\x70\x74\x67\x72\x6f\x75\x70\x3d\x62\x67\x2e\ \x6f\x70\x74\x69\x6f\x6e\x2c\x62\x67\x2e\x74\x62\x6f\x64\x79\x3d\ \x62\x67\x2e\x74\x66\x6f\x6f\x74\x3d\x62\x67\x2e\x63\x6f\x6c\x67\ \x72\x6f\x75\x70\x3d\x62\x67\x2e\x63\x61\x70\x74\x69\x6f\x6e\x3d\ \x62\x67\x2e\x74\x68\x65\x61\x64\x2c\x62\x67\x2e\x74\x68\x3d\x62\ \x67\x2e\x74\x64\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x68\ \x74\x6d\x6c\x53\x65\x72\x69\x61\x6c\x69\x7a\x65\x7c\x7c\x28\x62\ \x67\x2e\x5f\x64\x65\x66\x61\x75\x6c\x74\x3d\x5b\x31\x2c\x22\x64\ \x69\x76\x3c\x64\x69\x76\x3e\x22\x2c\x22\x3c\x2f\x64\x69\x76\x3e\ \x22\x5d\x29\x2c\x66\x2e\x66\x6e\x2e\x65\x78\x74\x65\x6e\x64\x28\ \x7b\x74\x65\x78\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x7b\x69\x66\x28\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\ \x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\ \x29\x7b\x76\x61\x72\x20\x63\x3d\x66\x28\x74\x68\x69\x73\x29\x3b\ \x63\x2e\x74\x65\x78\x74\x28\x61\x2e\x63\x61\x6c\x6c\x28\x74\x68\ \x69\x73\x2c\x62\x2c\x63\x2e\x74\x65\x78\x74\x28\x29\x29\x29\x7d\ \x29\x3b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x61\x21\x3d\x22\ \x6f\x62\x6a\x65\x63\x74\x22\x26\x26\x61\x21\x3d\x3d\x62\x29\x72\ \x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x6d\x70\x74\x79\ \x28\x29\x2e\x61\x70\x70\x65\x6e\x64\x28\x28\x74\x68\x69\x73\x5b\ \x30\x5d\x26\x26\x74\x68\x69\x73\x5b\x30\x5d\x2e\x6f\x77\x6e\x65\ \x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x7c\x7c\x63\x29\x2e\x63\x72\ \x65\x61\x74\x65\x54\x65\x78\x74\x4e\x6f\x64\x65\x28\x61\x29\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x74\x65\x78\x74\x28\x74\ \x68\x69\x73\x29\x7d\x2c\x77\x72\x61\x70\x41\x6c\x6c\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\x28\x66\x2e\x69\ \x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x29\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\x7b\x66\x28\x74\x68\x69\x73\ \x29\x2e\x77\x72\x61\x70\x41\x6c\x6c\x28\x61\x2e\x63\x61\x6c\x6c\ \x28\x74\x68\x69\x73\x2c\x62\x29\x29\x7d\x29\x3b\x69\x66\x28\x74\ \x68\x69\x73\x5b\x30\x5d\x29\x7b\x76\x61\x72\x20\x62\x3d\x66\x28\ \x61\x2c\x74\x68\x69\x73\x5b\x30\x5d\x2e\x6f\x77\x6e\x65\x72\x44\ \x6f\x63\x75\x6d\x65\x6e\x74\x29\x2e\x65\x71\x28\x30\x29\x2e\x63\ \x6c\x6f\x6e\x65\x28\x21\x30\x29\x3b\x74\x68\x69\x73\x5b\x30\x5d\ \x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x26\x26\x62\x2e\x69\ \x6e\x73\x65\x72\x74\x42\x65\x66\x6f\x72\x65\x28\x74\x68\x69\x73\ \x5b\x30\x5d\x29\x2c\x62\x2e\x6d\x61\x70\x28\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x61\x3d\x74\x68\x69\x73\ \x3b\x77\x68\x69\x6c\x65\x28\x61\x2e\x66\x69\x72\x73\x74\x43\x68\ \x69\x6c\x64\x26\x26\x61\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\ \x64\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\x61\ \x3d\x61\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x61\x7d\x29\x2e\x61\x70\x70\x65\x6e\x64\x28\ \x74\x68\x69\x73\x29\x7d\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x7d\x2c\x77\x72\x61\x70\x49\x6e\x6e\x65\x72\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\x28\x66\x2e\x69\x73\ \x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x29\x72\x65\x74\x75\ \x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x62\x29\x7b\x66\x28\x74\x68\x69\x73\x29\ \x2e\x77\x72\x61\x70\x49\x6e\x6e\x65\x72\x28\x61\x2e\x63\x61\x6c\ \x6c\x28\x74\x68\x69\x73\x2c\x62\x29\x29\x7d\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x62\x3d\x66\ \x28\x74\x68\x69\x73\x29\x2c\x63\x3d\x62\x2e\x63\x6f\x6e\x74\x65\ \x6e\x74\x73\x28\x29\x3b\x63\x2e\x6c\x65\x6e\x67\x74\x68\x3f\x63\ \x2e\x77\x72\x61\x70\x41\x6c\x6c\x28\x61\x29\x3a\x62\x2e\x61\x70\ \x70\x65\x6e\x64\x28\x61\x29\x7d\x29\x7d\x2c\x77\x72\x61\x70\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\ \x62\x3d\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\ \x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x63\x29\x7b\x66\ \x28\x74\x68\x69\x73\x29\x2e\x77\x72\x61\x70\x41\x6c\x6c\x28\x62\ \x3f\x61\x2e\x63\x61\x6c\x6c\x28\x74\x68\x69\x73\x2c\x63\x29\x3a\ \x61\x29\x7d\x29\x7d\x2c\x75\x6e\x77\x72\x61\x70\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x2e\x70\x61\x72\x65\x6e\x74\x28\x29\x2e\x65\x61\x63\ \x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\x2e\x6e\ \x6f\x64\x65\x4e\x61\x6d\x65\x28\x74\x68\x69\x73\x2c\x22\x62\x6f\ \x64\x79\x22\x29\x7c\x7c\x66\x28\x74\x68\x69\x73\x29\x2e\x72\x65\ \x70\x6c\x61\x63\x65\x57\x69\x74\x68\x28\x74\x68\x69\x73\x2e\x63\ \x68\x69\x6c\x64\x4e\x6f\x64\x65\x73\x29\x7d\x29\x2e\x65\x6e\x64\ \x28\x29\x7d\x2c\x61\x70\x70\x65\x6e\x64\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x2e\x64\x6f\x6d\x4d\x61\x6e\x69\x70\x28\x61\x72\x67\x75\x6d\ \x65\x6e\x74\x73\x2c\x21\x30\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x74\x68\x69\x73\x2e\x6e\x6f\x64\x65\x54\x79\x70\ \x65\x3d\x3d\x3d\x31\x26\x26\x74\x68\x69\x73\x2e\x61\x70\x70\x65\ \x6e\x64\x43\x68\x69\x6c\x64\x28\x61\x29\x7d\x29\x7d\x2c\x70\x72\ \x65\x70\x65\x6e\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x64\x6f\x6d\ \x4d\x61\x6e\x69\x70\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2c\ \x21\x30\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x74\ \x68\x69\x73\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\ \x26\x26\x74\x68\x69\x73\x2e\x69\x6e\x73\x65\x72\x74\x42\x65\x66\ \x6f\x72\x65\x28\x61\x2c\x74\x68\x69\x73\x2e\x66\x69\x72\x73\x74\ \x43\x68\x69\x6c\x64\x29\x7d\x29\x7d\x2c\x62\x65\x66\x6f\x72\x65\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x74\ \x68\x69\x73\x5b\x30\x5d\x26\x26\x74\x68\x69\x73\x5b\x30\x5d\x2e\ \x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x29\x72\x65\x74\x75\x72\ \x6e\x20\x74\x68\x69\x73\x2e\x64\x6f\x6d\x4d\x61\x6e\x69\x70\x28\ \x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2c\x21\x31\x2c\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x74\x68\x69\x73\x2e\x70\x61\ \x72\x65\x6e\x74\x4e\x6f\x64\x65\x2e\x69\x6e\x73\x65\x72\x74\x42\ \x65\x66\x6f\x72\x65\x28\x61\x2c\x74\x68\x69\x73\x29\x7d\x29\x3b\ \x69\x66\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2e\x6c\x65\x6e\ \x67\x74\x68\x29\x7b\x76\x61\x72\x20\x61\x3d\x66\x2e\x63\x6c\x65\ \x61\x6e\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x3b\x61\x2e\ \x70\x75\x73\x68\x2e\x61\x70\x70\x6c\x79\x28\x61\x2c\x74\x68\x69\ \x73\x2e\x74\x6f\x41\x72\x72\x61\x79\x28\x29\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x70\x75\x73\x68\x53\x74\x61\ \x63\x6b\x28\x61\x2c\x22\x62\x65\x66\x6f\x72\x65\x22\x2c\x61\x72\ \x67\x75\x6d\x65\x6e\x74\x73\x29\x7d\x7d\x2c\x61\x66\x74\x65\x72\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x74\ \x68\x69\x73\x5b\x30\x5d\x26\x26\x74\x68\x69\x73\x5b\x30\x5d\x2e\ \x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x29\x72\x65\x74\x75\x72\ \x6e\x20\x74\x68\x69\x73\x2e\x64\x6f\x6d\x4d\x61\x6e\x69\x70\x28\ \x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2c\x21\x31\x2c\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x74\x68\x69\x73\x2e\x70\x61\ \x72\x65\x6e\x74\x4e\x6f\x64\x65\x2e\x69\x6e\x73\x65\x72\x74\x42\ \x65\x66\x6f\x72\x65\x28\x61\x2c\x74\x68\x69\x73\x2e\x6e\x65\x78\ \x74\x53\x69\x62\x6c\x69\x6e\x67\x29\x7d\x29\x3b\x69\x66\x28\x61\ \x72\x67\x75\x6d\x65\x6e\x74\x73\x2e\x6c\x65\x6e\x67\x74\x68\x29\ \x7b\x76\x61\x72\x20\x61\x3d\x74\x68\x69\x73\x2e\x70\x75\x73\x68\ \x53\x74\x61\x63\x6b\x28\x74\x68\x69\x73\x2c\x22\x61\x66\x74\x65\ \x72\x22\x2c\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x3b\x61\x2e\ \x70\x75\x73\x68\x2e\x61\x70\x70\x6c\x79\x28\x61\x2c\x66\x2e\x63\ \x6c\x65\x61\x6e\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x7d\x7d\x2c\x72\x65\x6d\x6f\ \x76\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\ \x7b\x66\x6f\x72\x28\x76\x61\x72\x20\x63\x3d\x30\x2c\x64\x3b\x28\ \x64\x3d\x74\x68\x69\x73\x5b\x63\x5d\x29\x21\x3d\x6e\x75\x6c\x6c\ \x3b\x63\x2b\x2b\x29\x69\x66\x28\x21\x61\x7c\x7c\x66\x2e\x66\x69\ \x6c\x74\x65\x72\x28\x61\x2c\x5b\x64\x5d\x29\x2e\x6c\x65\x6e\x67\ \x74\x68\x29\x21\x62\x26\x26\x64\x2e\x6e\x6f\x64\x65\x54\x79\x70\ \x65\x3d\x3d\x3d\x31\x26\x26\x28\x66\x2e\x63\x6c\x65\x61\x6e\x44\ \x61\x74\x61\x28\x64\x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\ \x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\x2a\x22\x29\x29\ \x2c\x66\x2e\x63\x6c\x65\x61\x6e\x44\x61\x74\x61\x28\x5b\x64\x5d\ \x29\x29\x2c\x64\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x26\ \x26\x64\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x2e\x72\x65\ \x6d\x6f\x76\x65\x43\x68\x69\x6c\x64\x28\x64\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x65\x6d\x70\x74\x79\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x0a\x7b\x66\x6f\x72\x28\ \x76\x61\x72\x20\x61\x3d\x30\x2c\x62\x3b\x28\x62\x3d\x74\x68\x69\ \x73\x5b\x61\x5d\x29\x21\x3d\x6e\x75\x6c\x6c\x3b\x61\x2b\x2b\x29\ \x7b\x62\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x26\ \x26\x66\x2e\x63\x6c\x65\x61\x6e\x44\x61\x74\x61\x28\x62\x2e\x67\ \x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\ \x61\x6d\x65\x28\x22\x2a\x22\x29\x29\x3b\x77\x68\x69\x6c\x65\x28\ \x62\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x29\x62\x2e\x72\ \x65\x6d\x6f\x76\x65\x43\x68\x69\x6c\x64\x28\x62\x2e\x66\x69\x72\ \x73\x74\x43\x68\x69\x6c\x64\x29\x7d\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x7d\x2c\x63\x6c\x6f\x6e\x65\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x61\x3d\x61\x3d\x3d\x6e\ \x75\x6c\x6c\x3f\x21\x31\x3a\x61\x2c\x62\x3d\x62\x3d\x3d\x6e\x75\ \x6c\x6c\x3f\x61\x3a\x62\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\ \x69\x73\x2e\x6d\x61\x70\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x63\x6c\x6f\x6e\x65\ \x28\x74\x68\x69\x73\x2c\x61\x2c\x62\x29\x7d\x29\x7d\x2c\x68\x74\ \x6d\x6c\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\ \x66\x28\x61\x3d\x3d\x3d\x62\x29\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x5b\x30\x5d\x26\x26\x74\x68\x69\x73\x5b\x30\x5d\x2e\ \x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x3f\x74\x68\x69\ \x73\x5b\x30\x5d\x2e\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c\x2e\x72\ \x65\x70\x6c\x61\x63\x65\x28\x57\x2c\x22\x22\x29\x3a\x6e\x75\x6c\ \x6c\x3b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\ \x73\x74\x72\x69\x6e\x67\x22\x26\x26\x21\x62\x61\x2e\x74\x65\x73\ \x74\x28\x61\x29\x26\x26\x28\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\ \x2e\x6c\x65\x61\x64\x69\x6e\x67\x57\x68\x69\x74\x65\x73\x70\x61\ \x63\x65\x7c\x7c\x21\x58\x2e\x74\x65\x73\x74\x28\x61\x29\x29\x26\ \x26\x21\x62\x67\x5b\x28\x5a\x2e\x65\x78\x65\x63\x28\x61\x29\x7c\ \x7c\x5b\x22\x22\x2c\x22\x22\x5d\x29\x5b\x31\x5d\x2e\x74\x6f\x4c\ \x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x5d\x29\x7b\x61\x3d\x61\ \x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x59\x2c\x22\x3c\x24\x31\x3e\ \x3c\x2f\x24\x32\x3e\x22\x29\x3b\x74\x72\x79\x7b\x66\x6f\x72\x28\ \x76\x61\x72\x20\x63\x3d\x30\x2c\x64\x3d\x74\x68\x69\x73\x2e\x6c\ \x65\x6e\x67\x74\x68\x3b\x63\x3c\x64\x3b\x63\x2b\x2b\x29\x74\x68\ \x69\x73\x5b\x63\x5d\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\ \x3d\x31\x26\x26\x28\x66\x2e\x63\x6c\x65\x61\x6e\x44\x61\x74\x61\ \x28\x74\x68\x69\x73\x5b\x63\x5d\x2e\x67\x65\x74\x45\x6c\x65\x6d\ \x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\x28\x22\x2a\ \x22\x29\x29\x2c\x74\x68\x69\x73\x5b\x63\x5d\x2e\x69\x6e\x6e\x65\ \x72\x48\x54\x4d\x4c\x3d\x61\x29\x7d\x63\x61\x74\x63\x68\x28\x65\ \x29\x7b\x74\x68\x69\x73\x2e\x65\x6d\x70\x74\x79\x28\x29\x2e\x61\ \x70\x70\x65\x6e\x64\x28\x61\x29\x7d\x7d\x65\x6c\x73\x65\x20\x66\ \x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x3f\x74\ \x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x66\x28\x74\x68\x69\ \x73\x29\x3b\x63\x2e\x68\x74\x6d\x6c\x28\x61\x2e\x63\x61\x6c\x6c\ \x28\x74\x68\x69\x73\x2c\x62\x2c\x63\x2e\x68\x74\x6d\x6c\x28\x29\ \x29\x29\x7d\x29\x3a\x74\x68\x69\x73\x2e\x65\x6d\x70\x74\x79\x28\ \x29\x2e\x61\x70\x70\x65\x6e\x64\x28\x61\x29\x3b\x72\x65\x74\x75\ \x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x72\x65\x70\x6c\x61\x63\x65\ \x57\x69\x74\x68\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x69\x66\x28\x74\x68\x69\x73\x5b\x30\x5d\x26\x26\x74\x68\x69\ \x73\x5b\x30\x5d\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x29\ \x7b\x69\x66\x28\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\ \x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\ \x7b\x76\x61\x72\x20\x63\x3d\x66\x28\x74\x68\x69\x73\x29\x2c\x64\ \x3d\x63\x2e\x68\x74\x6d\x6c\x28\x29\x3b\x63\x2e\x72\x65\x70\x6c\ \x61\x63\x65\x57\x69\x74\x68\x28\x61\x2e\x63\x61\x6c\x6c\x28\x74\ \x68\x69\x73\x2c\x62\x2c\x64\x29\x29\x7d\x29\x3b\x74\x79\x70\x65\ \x6f\x66\x20\x61\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\ \x28\x61\x3d\x66\x28\x61\x29\x2e\x64\x65\x74\x61\x63\x68\x28\x29\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\ \x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x76\x61\ \x72\x20\x62\x3d\x74\x68\x69\x73\x2e\x6e\x65\x78\x74\x53\x69\x62\ \x6c\x69\x6e\x67\x2c\x63\x3d\x74\x68\x69\x73\x2e\x70\x61\x72\x65\ \x6e\x74\x4e\x6f\x64\x65\x3b\x66\x28\x74\x68\x69\x73\x29\x2e\x72\ \x65\x6d\x6f\x76\x65\x28\x29\x2c\x62\x3f\x66\x28\x62\x29\x2e\x62\ \x65\x66\x6f\x72\x65\x28\x61\x29\x3a\x66\x28\x63\x29\x2e\x61\x70\ \x70\x65\x6e\x64\x28\x61\x29\x7d\x29\x7d\x72\x65\x74\x75\x72\x6e\ \x20\x74\x68\x69\x73\x2e\x6c\x65\x6e\x67\x74\x68\x3f\x74\x68\x69\ \x73\x2e\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x28\x66\x28\x66\x2e\ \x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x3f\x61\x28\ \x29\x3a\x61\x29\x2c\x22\x72\x65\x70\x6c\x61\x63\x65\x57\x69\x74\ \x68\x22\x2c\x61\x29\x3a\x74\x68\x69\x73\x7d\x2c\x64\x65\x74\x61\ \x63\x68\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\ \x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x72\x65\x6d\x6f\x76\ \x65\x28\x61\x2c\x21\x30\x29\x7d\x2c\x64\x6f\x6d\x4d\x61\x6e\x69\ \x70\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x2c\x64\ \x29\x7b\x76\x61\x72\x20\x65\x2c\x67\x2c\x68\x2c\x69\x2c\x6a\x3d\ \x61\x5b\x30\x5d\x2c\x6b\x3d\x5b\x5d\x3b\x69\x66\x28\x21\x66\x2e\ \x73\x75\x70\x70\x6f\x72\x74\x2e\x63\x68\x65\x63\x6b\x43\x6c\x6f\ \x6e\x65\x26\x26\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2e\x6c\x65\ \x6e\x67\x74\x68\x3d\x3d\x3d\x33\x26\x26\x74\x79\x70\x65\x6f\x66\ \x20\x6a\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x62\x64\ \x2e\x74\x65\x73\x74\x28\x6a\x29\x29\x72\x65\x74\x75\x72\x6e\x20\ \x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x29\x7b\x66\x28\x74\x68\x69\x73\x29\x2e\x64\x6f\x6d\ \x4d\x61\x6e\x69\x70\x28\x61\x2c\x63\x2c\x64\x2c\x21\x30\x29\x7d\ \x29\x3b\x69\x66\x28\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x6a\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\ \x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x65\ \x29\x7b\x76\x61\x72\x20\x67\x3d\x66\x28\x74\x68\x69\x73\x29\x3b\ \x61\x5b\x30\x5d\x3d\x6a\x2e\x63\x61\x6c\x6c\x28\x74\x68\x69\x73\ \x2c\x65\x2c\x63\x3f\x67\x2e\x68\x74\x6d\x6c\x28\x29\x3a\x62\x29\ \x2c\x67\x2e\x64\x6f\x6d\x4d\x61\x6e\x69\x70\x28\x61\x2c\x63\x2c\ \x64\x29\x7d\x29\x3b\x69\x66\x28\x74\x68\x69\x73\x5b\x30\x5d\x29\ \x7b\x69\x3d\x6a\x26\x26\x6a\x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\ \x64\x65\x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x70\x61\x72\ \x65\x6e\x74\x4e\x6f\x64\x65\x26\x26\x69\x26\x26\x69\x2e\x6e\x6f\ \x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\x31\x26\x26\x69\x2e\x63\ \x68\x69\x6c\x64\x4e\x6f\x64\x65\x73\x2e\x6c\x65\x6e\x67\x74\x68\ \x3d\x3d\x3d\x74\x68\x69\x73\x2e\x6c\x65\x6e\x67\x74\x68\x3f\x65\ \x3d\x7b\x66\x72\x61\x67\x6d\x65\x6e\x74\x3a\x69\x7d\x3a\x65\x3d\ \x66\x2e\x62\x75\x69\x6c\x64\x46\x72\x61\x67\x6d\x65\x6e\x74\x28\ \x61\x2c\x74\x68\x69\x73\x2c\x6b\x29\x2c\x68\x3d\x65\x2e\x66\x72\ \x61\x67\x6d\x65\x6e\x74\x2c\x68\x2e\x63\x68\x69\x6c\x64\x4e\x6f\ \x64\x65\x73\x2e\x6c\x65\x6e\x67\x74\x68\x3d\x3d\x3d\x31\x3f\x67\ \x3d\x68\x3d\x68\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x3a\ \x67\x3d\x68\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x3b\x69\ \x66\x28\x67\x29\x7b\x63\x3d\x63\x26\x26\x66\x2e\x6e\x6f\x64\x65\ \x4e\x61\x6d\x65\x28\x67\x2c\x22\x74\x72\x22\x29\x3b\x66\x6f\x72\ \x28\x76\x61\x72\x20\x6c\x3d\x30\x2c\x6d\x3d\x74\x68\x69\x73\x2e\ \x6c\x65\x6e\x67\x74\x68\x2c\x6e\x3d\x6d\x2d\x31\x3b\x6c\x3c\x6d\ \x3b\x6c\x2b\x2b\x29\x64\x2e\x63\x61\x6c\x6c\x28\x63\x3f\x62\x69\ \x28\x74\x68\x69\x73\x5b\x6c\x5d\x2c\x67\x29\x3a\x74\x68\x69\x73\ \x5b\x6c\x5d\x2c\x65\x2e\x63\x61\x63\x68\x65\x61\x62\x6c\x65\x7c\ \x7c\x6d\x3e\x31\x26\x26\x6c\x3c\x6e\x3f\x66\x2e\x63\x6c\x6f\x6e\ \x65\x28\x68\x2c\x21\x30\x2c\x21\x30\x29\x3a\x68\x29\x7d\x6b\x2e\ \x6c\x65\x6e\x67\x74\x68\x26\x26\x66\x2e\x65\x61\x63\x68\x28\x6b\ \x2c\x62\x70\x29\x7d\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\ \x7d\x7d\x29\x2c\x66\x2e\x62\x75\x69\x6c\x64\x46\x72\x61\x67\x6d\ \x65\x6e\x74\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\ \x2c\x64\x29\x7b\x76\x61\x72\x20\x65\x2c\x67\x2c\x68\x2c\x69\x2c\ \x6a\x3d\x61\x5b\x30\x5d\x3b\x62\x26\x26\x62\x5b\x30\x5d\x26\x26\ \x28\x69\x3d\x62\x5b\x30\x5d\x2e\x6f\x77\x6e\x65\x72\x44\x6f\x63\ \x75\x6d\x65\x6e\x74\x7c\x7c\x62\x5b\x30\x5d\x29\x2c\x69\x2e\x63\ \x72\x65\x61\x74\x65\x44\x6f\x63\x75\x6d\x65\x6e\x74\x46\x72\x61\ \x67\x6d\x65\x6e\x74\x7c\x7c\x28\x69\x3d\x63\x29\x2c\x61\x2e\x6c\ \x65\x6e\x67\x74\x68\x3d\x3d\x3d\x31\x26\x26\x74\x79\x70\x65\x6f\ \x66\x20\x6a\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x6a\ \x2e\x6c\x65\x6e\x67\x74\x68\x3c\x35\x31\x32\x26\x26\x69\x3d\x3d\ \x3d\x63\x26\x26\x6a\x2e\x63\x68\x61\x72\x41\x74\x28\x30\x29\x3d\ \x3d\x3d\x22\x3c\x22\x26\x26\x21\x62\x62\x2e\x74\x65\x73\x74\x28\ \x6a\x29\x26\x26\x28\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x63\ \x68\x65\x63\x6b\x43\x6c\x6f\x6e\x65\x7c\x7c\x21\x62\x64\x2e\x74\ \x65\x73\x74\x28\x6a\x29\x29\x26\x26\x28\x66\x2e\x73\x75\x70\x70\ \x6f\x72\x74\x2e\x68\x74\x6d\x6c\x35\x43\x6c\x6f\x6e\x65\x7c\x7c\ \x21\x62\x63\x2e\x74\x65\x73\x74\x28\x6a\x29\x29\x26\x26\x28\x67\ \x3d\x21\x30\x2c\x68\x3d\x66\x2e\x66\x72\x61\x67\x6d\x65\x6e\x74\ \x73\x5b\x6a\x5d\x2c\x68\x26\x26\x68\x21\x3d\x3d\x31\x26\x26\x28\ \x65\x3d\x68\x29\x29\x2c\x65\x7c\x7c\x28\x65\x3d\x69\x2e\x63\x72\ \x65\x61\x74\x65\x44\x6f\x63\x75\x6d\x65\x6e\x74\x46\x72\x61\x67\ \x6d\x65\x6e\x74\x28\x29\x2c\x66\x2e\x63\x6c\x65\x61\x6e\x28\x61\ \x2c\x69\x2c\x65\x2c\x64\x29\x29\x2c\x67\x26\x26\x28\x66\x2e\x66\ \x72\x61\x67\x6d\x65\x6e\x74\x73\x5b\x6a\x5d\x3d\x68\x3f\x65\x3a\ \x31\x29\x3b\x72\x65\x74\x75\x72\x6e\x7b\x66\x72\x61\x67\x6d\x65\ \x6e\x74\x3a\x65\x2c\x63\x61\x63\x68\x65\x61\x62\x6c\x65\x3a\x67\ \x7d\x7d\x2c\x66\x2e\x66\x72\x61\x67\x6d\x65\x6e\x74\x73\x3d\x7b\ \x7d\x2c\x66\x2e\x65\x61\x63\x68\x28\x7b\x61\x70\x70\x65\x6e\x64\ \x54\x6f\x3a\x22\x61\x70\x70\x65\x6e\x64\x22\x2c\x70\x72\x65\x70\ \x65\x6e\x64\x54\x6f\x3a\x22\x70\x72\x65\x70\x65\x6e\x64\x22\x2c\ \x69\x6e\x73\x65\x72\x74\x42\x65\x66\x6f\x72\x65\x3a\x22\x62\x65\ \x66\x6f\x72\x65\x22\x2c\x69\x6e\x73\x65\x72\x74\x41\x66\x74\x65\ \x72\x3a\x22\x61\x66\x74\x65\x72\x22\x2c\x72\x65\x70\x6c\x61\x63\ \x65\x41\x6c\x6c\x3a\x22\x72\x65\x70\x6c\x61\x63\x65\x57\x69\x74\ \x68\x22\x7d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\ \x29\x7b\x66\x2e\x66\x6e\x5b\x61\x5d\x3d\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x5b\x5d\x2c\x65\ \x3d\x66\x28\x63\x29\x2c\x67\x3d\x74\x68\x69\x73\x2e\x6c\x65\x6e\ \x67\x74\x68\x3d\x3d\x3d\x31\x26\x26\x74\x68\x69\x73\x5b\x30\x5d\ \x2e\x70\x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x3b\x69\x66\x28\x67\ \x26\x26\x67\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\ \x31\x26\x26\x67\x2e\x63\x68\x69\x6c\x64\x4e\x6f\x64\x65\x73\x2e\ \x6c\x65\x6e\x67\x74\x68\x3d\x3d\x3d\x31\x26\x26\x65\x2e\x6c\x65\ \x6e\x67\x74\x68\x3d\x3d\x3d\x31\x29\x7b\x65\x5b\x62\x5d\x28\x74\ \x68\x69\x73\x5b\x30\x5d\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x7d\x66\x6f\x72\x28\x76\x61\x72\x20\x68\x3d\x30\x2c\ \x69\x3d\x65\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x68\x3c\x69\x3b\x68\ \x2b\x2b\x29\x7b\x76\x61\x72\x20\x6a\x3d\x28\x68\x3e\x30\x3f\x74\ \x68\x69\x73\x2e\x63\x6c\x6f\x6e\x65\x28\x21\x30\x29\x3a\x74\x68\ \x69\x73\x29\x2e\x67\x65\x74\x28\x29\x3b\x66\x28\x65\x5b\x68\x5d\ \x29\x5b\x62\x5d\x28\x6a\x29\x2c\x64\x3d\x64\x2e\x63\x6f\x6e\x63\ \x61\x74\x28\x6a\x29\x7d\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x2e\x70\x75\x73\x68\x53\x74\x61\x63\x6b\x28\x64\x2c\x61\x2c\ \x65\x2e\x73\x65\x6c\x65\x63\x74\x6f\x72\x29\x7d\x7d\x29\x2c\x66\ \x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x63\x6c\x6f\x6e\x65\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\ \x61\x72\x20\x64\x2c\x65\x2c\x67\x2c\x68\x3d\x66\x2e\x73\x75\x70\ \x70\x6f\x72\x74\x2e\x68\x74\x6d\x6c\x35\x43\x6c\x6f\x6e\x65\x7c\ \x7c\x21\x62\x63\x2e\x74\x65\x73\x74\x28\x22\x3c\x22\x2b\x61\x2e\ \x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x3f\x61\x2e\x63\x6c\x6f\x6e\ \x65\x4e\x6f\x64\x65\x28\x21\x30\x29\x3a\x62\x6f\x28\x61\x29\x3b\ \x69\x66\x28\x28\x21\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x6e\ \x6f\x43\x6c\x6f\x6e\x65\x45\x76\x65\x6e\x74\x7c\x7c\x21\x66\x2e\ \x73\x75\x70\x70\x6f\x72\x74\x2e\x6e\x6f\x43\x6c\x6f\x6e\x65\x43\ \x68\x65\x63\x6b\x65\x64\x29\x26\x26\x28\x61\x2e\x6e\x6f\x64\x65\ \x54\x79\x70\x65\x3d\x3d\x3d\x31\x7c\x7c\x61\x2e\x6e\x6f\x64\x65\ \x54\x79\x70\x65\x3d\x3d\x3d\x31\x31\x29\x26\x26\x21\x66\x2e\x69\ \x73\x58\x4d\x4c\x44\x6f\x63\x28\x61\x29\x29\x7b\x62\x6b\x28\x61\ \x2c\x68\x29\x2c\x64\x3d\x62\x6c\x28\x61\x29\x2c\x65\x3d\x62\x6c\ \x28\x68\x29\x3b\x66\x6f\x72\x28\x67\x3d\x30\x3b\x64\x5b\x67\x5d\ \x3b\x2b\x2b\x67\x29\x65\x5b\x67\x5d\x26\x26\x62\x6b\x28\x64\x5b\ \x67\x5d\x2c\x65\x5b\x67\x5d\x29\x7d\x69\x66\x28\x62\x29\x7b\x62\ \x6a\x28\x61\x2c\x68\x29\x3b\x69\x66\x28\x63\x29\x7b\x64\x3d\x62\ \x6c\x28\x61\x29\x2c\x65\x3d\x62\x6c\x28\x68\x29\x3b\x66\x6f\x72\ \x28\x67\x3d\x30\x3b\x64\x5b\x67\x5d\x3b\x2b\x2b\x67\x29\x62\x6a\ \x28\x64\x5b\x67\x5d\x2c\x65\x5b\x67\x5d\x29\x7d\x7d\x64\x3d\x65\ \x3d\x6e\x75\x6c\x6c\x3b\x72\x65\x74\x75\x72\x6e\x20\x68\x7d\x2c\ \x63\x6c\x65\x61\x6e\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x62\x2c\x64\x2c\x65\x29\x7b\x76\x61\x72\x20\x67\x3b\x62\x3d\ \x62\x7c\x7c\x63\x2c\x74\x79\x70\x65\x6f\x66\x20\x62\x2e\x63\x72\ \x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x3d\x3d\x22\x75\x6e\ \x64\x65\x66\x69\x6e\x65\x64\x22\x26\x26\x28\x62\x3d\x62\x2e\x6f\ \x77\x6e\x65\x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x7c\x7c\x62\x5b\ \x30\x5d\x26\x26\x62\x5b\x30\x5d\x2e\x6f\x77\x6e\x65\x72\x44\x6f\ \x63\x75\x6d\x65\x6e\x74\x7c\x7c\x63\x29\x3b\x76\x61\x72\x20\x68\ \x3d\x5b\x5d\x2c\x69\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\x6a\x3d\ \x30\x2c\x6b\x3b\x28\x6b\x3d\x61\x5b\x6a\x5d\x29\x21\x3d\x6e\x75\ \x6c\x6c\x3b\x6a\x2b\x2b\x29\x7b\x74\x79\x70\x65\x6f\x66\x20\x6b\ \x3d\x3d\x22\x6e\x75\x6d\x62\x65\x72\x22\x26\x26\x28\x6b\x2b\x3d\ \x22\x22\x29\x3b\x69\x66\x28\x21\x6b\x29\x63\x6f\x6e\x74\x69\x6e\ \x75\x65\x3b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\x6b\x3d\x3d\ \x22\x73\x74\x72\x69\x6e\x67\x22\x29\x69\x66\x28\x21\x5f\x2e\x74\ \x65\x73\x74\x28\x6b\x29\x29\x6b\x3d\x62\x2e\x63\x72\x65\x61\x74\ \x65\x54\x65\x78\x74\x4e\x6f\x64\x65\x28\x6b\x29\x3b\x65\x6c\x73\ \x65\x7b\x6b\x3d\x6b\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x59\x2c\ \x22\x3c\x24\x31\x3e\x3c\x2f\x24\x32\x3e\x22\x29\x3b\x76\x61\x72\ \x20\x6c\x3d\x28\x5a\x2e\x65\x78\x65\x63\x28\x6b\x29\x7c\x7c\x5b\ \x22\x22\x2c\x22\x22\x5d\x29\x5b\x31\x5d\x2e\x74\x6f\x4c\x6f\x77\ \x65\x72\x43\x61\x73\x65\x28\x29\x2c\x6d\x3d\x62\x67\x5b\x6c\x5d\ \x7c\x7c\x62\x67\x2e\x5f\x64\x65\x66\x61\x75\x6c\x74\x2c\x6e\x3d\ \x6d\x5b\x30\x5d\x2c\x6f\x3d\x62\x2e\x63\x72\x65\x61\x74\x65\x45\ \x6c\x65\x6d\x65\x6e\x74\x28\x22\x64\x69\x76\x22\x29\x3b\x62\x3d\ \x3d\x3d\x63\x3f\x62\x68\x2e\x61\x70\x70\x65\x6e\x64\x43\x68\x69\ \x6c\x64\x28\x6f\x29\x3a\x55\x28\x62\x29\x2e\x61\x70\x70\x65\x6e\ \x64\x43\x68\x69\x6c\x64\x28\x6f\x29\x2c\x6f\x2e\x69\x6e\x6e\x65\ \x72\x48\x54\x4d\x4c\x3d\x6d\x5b\x31\x5d\x2b\x6b\x2b\x6d\x5b\x32\ \x5d\x3b\x77\x68\x69\x6c\x65\x28\x6e\x2d\x2d\x29\x6f\x3d\x6f\x2e\ \x6c\x61\x73\x74\x43\x68\x69\x6c\x64\x3b\x69\x66\x28\x21\x66\x2e\ \x73\x75\x70\x70\x6f\x72\x74\x2e\x74\x62\x6f\x64\x79\x29\x7b\x76\ \x61\x72\x20\x70\x3d\x24\x2e\x74\x65\x73\x74\x28\x6b\x29\x2c\x71\ \x3d\x6c\x3d\x3d\x3d\x22\x74\x61\x62\x6c\x65\x22\x26\x26\x21\x70\ \x3f\x6f\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x26\x26\x6f\ \x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x2e\x63\x68\x69\x6c\ \x64\x4e\x6f\x64\x65\x73\x3a\x6d\x5b\x31\x5d\x3d\x3d\x3d\x22\x3c\ \x74\x61\x62\x6c\x65\x3e\x22\x26\x26\x21\x70\x3f\x6f\x2e\x63\x68\ \x69\x6c\x64\x4e\x6f\x64\x65\x73\x3a\x5b\x5d\x3b\x66\x6f\x72\x28\ \x69\x3d\x71\x2e\x6c\x65\x6e\x67\x74\x68\x2d\x31\x3b\x69\x3e\x3d\ \x30\x3b\x2d\x2d\x69\x29\x66\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\ \x28\x71\x5b\x69\x5d\x2c\x22\x74\x62\x6f\x64\x79\x22\x29\x26\x26\ \x21\x71\x5b\x69\x5d\x2e\x63\x68\x69\x6c\x64\x4e\x6f\x64\x65\x73\ \x2e\x6c\x65\x6e\x67\x74\x68\x26\x26\x71\x5b\x69\x5d\x2e\x70\x61\ \x72\x65\x6e\x74\x4e\x6f\x64\x65\x2e\x72\x65\x6d\x6f\x76\x65\x43\ \x68\x69\x6c\x64\x28\x71\x5b\x69\x5d\x29\x7d\x21\x66\x2e\x73\x75\ \x70\x70\x6f\x72\x74\x2e\x6c\x65\x61\x64\x69\x6e\x67\x57\x68\x69\ \x74\x65\x73\x70\x61\x63\x65\x26\x26\x58\x2e\x74\x65\x73\x74\x28\ \x6b\x29\x26\x26\x6f\x2e\x69\x6e\x73\x65\x72\x74\x42\x65\x66\x6f\ \x72\x65\x28\x62\x2e\x63\x72\x65\x61\x74\x65\x54\x65\x78\x74\x4e\ \x6f\x64\x65\x28\x58\x2e\x65\x78\x65\x63\x28\x6b\x29\x5b\x30\x5d\ \x29\x2c\x6f\x2e\x66\x69\x72\x73\x74\x43\x68\x69\x6c\x64\x29\x2c\ \x6b\x3d\x6f\x2e\x63\x68\x69\x6c\x64\x4e\x6f\x64\x65\x73\x7d\x76\ \x61\x72\x20\x72\x3b\x69\x66\x28\x21\x66\x2e\x73\x75\x70\x70\x6f\ \x72\x74\x2e\x61\x70\x70\x65\x6e\x64\x43\x68\x65\x63\x6b\x65\x64\ \x29\x69\x66\x28\x6b\x5b\x30\x5d\x26\x26\x74\x79\x70\x65\x6f\x66\ \x20\x28\x72\x3d\x6b\x2e\x6c\x65\x6e\x67\x74\x68\x29\x3d\x3d\x22\ \x6e\x75\x6d\x62\x65\x72\x22\x29\x66\x6f\x72\x28\x69\x3d\x30\x3b\ \x69\x3c\x72\x3b\x69\x2b\x2b\x29\x62\x6e\x28\x6b\x5b\x69\x5d\x29\ \x3b\x65\x6c\x73\x65\x20\x62\x6e\x28\x6b\x29\x3b\x6b\x2e\x6e\x6f\ \x64\x65\x54\x79\x70\x65\x3f\x68\x2e\x70\x75\x73\x68\x28\x6b\x29\ \x3a\x68\x3d\x66\x2e\x6d\x65\x72\x67\x65\x28\x68\x2c\x6b\x29\x7d\ \x69\x66\x28\x64\x29\x7b\x67\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\x61\x2e\x74\x79\x70\ \x65\x7c\x7c\x62\x65\x2e\x74\x65\x73\x74\x28\x61\x2e\x74\x79\x70\ \x65\x29\x7d\x3b\x66\x6f\x72\x28\x6a\x3d\x30\x3b\x68\x5b\x6a\x5d\ \x3b\x6a\x2b\x2b\x29\x69\x66\x28\x65\x26\x26\x66\x2e\x6e\x6f\x64\ \x65\x4e\x61\x6d\x65\x28\x68\x5b\x6a\x5d\x2c\x22\x73\x63\x72\x69\ \x70\x74\x22\x29\x26\x26\x28\x21\x68\x5b\x6a\x5d\x2e\x74\x79\x70\ \x65\x7c\x7c\x68\x5b\x6a\x5d\x2e\x74\x79\x70\x65\x2e\x74\x6f\x4c\ \x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x3d\x3d\x3d\x22\x74\x65\ \x78\x74\x2f\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x22\x29\x29\ \x65\x2e\x70\x75\x73\x68\x28\x68\x5b\x6a\x5d\x2e\x70\x61\x72\x65\ \x6e\x74\x4e\x6f\x64\x65\x3f\x68\x5b\x6a\x5d\x2e\x70\x61\x72\x65\ \x6e\x74\x4e\x6f\x64\x65\x2e\x72\x65\x6d\x6f\x76\x65\x43\x68\x69\ \x6c\x64\x28\x68\x5b\x6a\x5d\x29\x3a\x68\x5b\x6a\x5d\x29\x3b\x65\ \x6c\x73\x65\x7b\x69\x66\x28\x68\x5b\x6a\x5d\x2e\x6e\x6f\x64\x65\ \x54\x79\x70\x65\x3d\x3d\x3d\x31\x29\x7b\x76\x61\x72\x20\x73\x3d\ \x66\x2e\x67\x72\x65\x70\x28\x68\x5b\x6a\x5d\x2e\x67\x65\x74\x45\ \x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\x61\x6d\x65\ \x28\x22\x73\x63\x72\x69\x70\x74\x22\x29\x2c\x67\x29\x3b\x68\x2e\ \x73\x70\x6c\x69\x63\x65\x2e\x61\x70\x70\x6c\x79\x28\x68\x2c\x5b\ \x6a\x2b\x31\x2c\x30\x5d\x2e\x63\x6f\x6e\x63\x61\x74\x28\x73\x29\ \x29\x7d\x64\x2e\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64\x28\ \x68\x5b\x6a\x5d\x29\x7d\x7d\x72\x65\x74\x75\x72\x6e\x20\x68\x7d\ \x2c\x63\x6c\x65\x61\x6e\x44\x61\x74\x61\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x2c\x63\x2c\x64\ \x3d\x66\x2e\x63\x61\x63\x68\x65\x2c\x65\x3d\x66\x2e\x65\x76\x65\ \x6e\x74\x2e\x73\x70\x65\x63\x69\x61\x6c\x2c\x67\x3d\x66\x2e\x73\ \x75\x70\x70\x6f\x72\x74\x2e\x64\x65\x6c\x65\x74\x65\x45\x78\x70\ \x61\x6e\x64\x6f\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\x68\x3d\x30\ \x2c\x69\x3b\x28\x69\x3d\x61\x5b\x68\x5d\x29\x21\x3d\x6e\x75\x6c\ \x6c\x3b\x68\x2b\x2b\x29\x7b\x69\x66\x28\x69\x2e\x6e\x6f\x64\x65\ \x4e\x61\x6d\x65\x26\x26\x66\x2e\x6e\x6f\x44\x61\x74\x61\x5b\x69\ \x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x2e\x74\x6f\x4c\x6f\x77\x65\ \x72\x43\x61\x73\x65\x28\x29\x5d\x29\x63\x6f\x6e\x74\x69\x6e\x75\ \x65\x3b\x63\x3d\x69\x5b\x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x5d\ \x3b\x69\x66\x28\x63\x29\x7b\x62\x3d\x64\x5b\x63\x5d\x3b\x69\x66\ \x28\x62\x26\x26\x62\x2e\x65\x76\x65\x6e\x74\x73\x29\x7b\x66\x6f\ \x72\x28\x76\x61\x72\x20\x6a\x20\x69\x6e\x20\x62\x2e\x65\x76\x65\ \x6e\x74\x73\x29\x65\x5b\x6a\x5d\x3f\x66\x2e\x65\x76\x65\x6e\x74\ \x2e\x72\x65\x6d\x6f\x76\x65\x28\x69\x2c\x6a\x29\x3a\x66\x2e\x72\ \x65\x6d\x6f\x76\x65\x45\x76\x65\x6e\x74\x28\x69\x2c\x6a\x2c\x62\ \x2e\x68\x61\x6e\x64\x6c\x65\x29\x3b\x62\x2e\x68\x61\x6e\x64\x6c\ \x65\x26\x26\x28\x62\x2e\x68\x61\x6e\x64\x6c\x65\x2e\x65\x6c\x65\ \x6d\x3d\x6e\x75\x6c\x6c\x29\x7d\x67\x3f\x64\x65\x6c\x65\x74\x65\ \x20\x69\x5b\x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x5d\x3a\x69\x2e\ \x72\x65\x6d\x6f\x76\x65\x41\x74\x74\x72\x69\x62\x75\x74\x65\x26\ \x26\x69\x2e\x72\x65\x6d\x6f\x76\x65\x41\x74\x74\x72\x69\x62\x75\ \x74\x65\x28\x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x29\x2c\x64\x65\ \x6c\x65\x74\x65\x20\x64\x5b\x63\x5d\x7d\x7d\x7d\x7d\x29\x3b\x76\ \x61\x72\x20\x62\x71\x3d\x2f\x61\x6c\x70\x68\x61\x5c\x28\x5b\x5e\ \x29\x5d\x2a\x5c\x29\x2f\x69\x2c\x62\x72\x3d\x2f\x6f\x70\x61\x63\ \x69\x74\x79\x3d\x28\x5b\x5e\x29\x5d\x2a\x29\x2f\x2c\x62\x73\x3d\ \x2f\x28\x5b\x41\x2d\x5a\x5d\x7c\x5e\x6d\x73\x29\x2f\x67\x2c\x62\ \x74\x3d\x2f\x5e\x2d\x3f\x5c\x64\x2b\x28\x3f\x3a\x70\x78\x29\x3f\ \x24\x2f\x69\x2c\x62\x75\x3d\x2f\x5e\x2d\x3f\x5c\x64\x2f\x2c\x62\ \x76\x3d\x2f\x5e\x28\x5b\x5c\x2d\x2b\x5d\x29\x3d\x28\x5b\x5c\x2d\ \x2b\x2e\x5c\x64\x65\x5d\x2b\x29\x2f\x2c\x62\x77\x3d\x7b\x70\x6f\ \x73\x69\x74\x69\x6f\x6e\x3a\x22\x61\x62\x73\x6f\x6c\x75\x74\x65\ \x22\x2c\x76\x69\x73\x69\x62\x69\x6c\x69\x74\x79\x3a\x22\x68\x69\ \x64\x64\x65\x6e\x22\x2c\x64\x69\x73\x70\x6c\x61\x79\x3a\x22\x62\ \x6c\x6f\x63\x6b\x22\x7d\x2c\x62\x78\x3d\x5b\x22\x4c\x65\x66\x74\ \x22\x2c\x22\x52\x69\x67\x68\x74\x22\x5d\x2c\x62\x79\x3d\x5b\x22\ \x54\x6f\x70\x22\x2c\x22\x42\x6f\x74\x74\x6f\x6d\x22\x5d\x2c\x62\ \x7a\x2c\x62\x41\x2c\x62\x42\x3b\x66\x2e\x66\x6e\x2e\x63\x73\x73\ \x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x69\ \x66\x28\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x2e\x6c\x65\x6e\x67\ \x74\x68\x3d\x3d\x3d\x32\x26\x26\x63\x3d\x3d\x3d\x62\x29\x72\x65\ \x74\x75\x72\x6e\x20\x74\x68\x69\x73\x3b\x72\x65\x74\x75\x72\x6e\ \x20\x66\x2e\x61\x63\x63\x65\x73\x73\x28\x74\x68\x69\x73\x2c\x61\ \x2c\x63\x2c\x21\x30\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x63\x2c\x64\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x64\x21\x3d\ \x3d\x62\x3f\x66\x2e\x73\x74\x79\x6c\x65\x28\x61\x2c\x63\x2c\x64\ \x29\x3a\x66\x2e\x63\x73\x73\x28\x61\x2c\x63\x29\x7d\x29\x7d\x2c\ \x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x63\x73\x73\x48\x6f\x6f\ \x6b\x73\x3a\x7b\x6f\x70\x61\x63\x69\x74\x79\x3a\x7b\x67\x65\x74\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x69\ \x66\x28\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x62\x7a\x28\x61\x2c\ \x22\x6f\x70\x61\x63\x69\x74\x79\x22\x2c\x22\x6f\x70\x61\x63\x69\ \x74\x79\x22\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x63\x3d\x3d\x3d\ \x22\x22\x3f\x22\x31\x22\x3a\x63\x7d\x72\x65\x74\x75\x72\x6e\x20\ \x61\x2e\x73\x74\x79\x6c\x65\x2e\x6f\x70\x61\x63\x69\x74\x79\x7d\ \x7d\x7d\x2c\x63\x73\x73\x4e\x75\x6d\x62\x65\x72\x3a\x7b\x66\x69\ \x6c\x6c\x4f\x70\x61\x63\x69\x74\x79\x3a\x21\x30\x2c\x66\x6f\x6e\ \x74\x57\x65\x69\x67\x68\x74\x3a\x21\x30\x2c\x6c\x69\x6e\x65\x48\ \x65\x69\x67\x68\x74\x3a\x21\x30\x2c\x6f\x70\x61\x63\x69\x74\x79\ \x3a\x21\x30\x2c\x6f\x72\x70\x68\x61\x6e\x73\x3a\x21\x30\x2c\x77\ \x69\x64\x6f\x77\x73\x3a\x21\x30\x2c\x7a\x49\x6e\x64\x65\x78\x3a\ \x21\x30\x2c\x7a\x6f\x6f\x6d\x3a\x21\x30\x7d\x2c\x63\x73\x73\x50\ \x72\x6f\x70\x73\x3a\x7b\x22\x66\x6c\x6f\x61\x74\x22\x3a\x66\x2e\ \x73\x75\x70\x70\x6f\x72\x74\x2e\x63\x73\x73\x46\x6c\x6f\x61\x74\ \x3f\x22\x63\x73\x73\x46\x6c\x6f\x61\x74\x22\x3a\x22\x73\x74\x79\ \x6c\x65\x46\x6c\x6f\x61\x74\x22\x7d\x2c\x73\x74\x79\x6c\x65\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x2c\x64\x2c\x65\ \x29\x7b\x69\x66\x28\x21\x21\x61\x26\x26\x61\x2e\x6e\x6f\x64\x65\ \x54\x79\x70\x65\x21\x3d\x3d\x33\x26\x26\x61\x2e\x6e\x6f\x64\x65\ \x54\x79\x70\x65\x21\x3d\x3d\x38\x26\x26\x21\x21\x61\x2e\x73\x74\ \x79\x6c\x65\x29\x7b\x76\x61\x72\x20\x67\x2c\x68\x2c\x69\x3d\x66\ \x2e\x63\x61\x6d\x65\x6c\x43\x61\x73\x65\x28\x63\x29\x2c\x6a\x3d\ \x61\x2e\x73\x74\x79\x6c\x65\x2c\x6b\x3d\x66\x2e\x63\x73\x73\x48\ \x6f\x6f\x6b\x73\x5b\x69\x5d\x3b\x63\x3d\x66\x2e\x63\x73\x73\x50\ \x72\x6f\x70\x73\x5b\x69\x5d\x7c\x7c\x69\x3b\x69\x66\x28\x64\x3d\ \x3d\x3d\x62\x29\x7b\x69\x66\x28\x6b\x26\x26\x22\x67\x65\x74\x22\ \x69\x6e\x20\x6b\x26\x26\x28\x67\x3d\x6b\x2e\x67\x65\x74\x28\x61\ \x2c\x21\x31\x2c\x65\x29\x29\x21\x3d\x3d\x62\x29\x72\x65\x74\x75\ \x72\x6e\x20\x67\x3b\x72\x65\x74\x75\x72\x6e\x20\x6a\x5b\x63\x5d\ \x7d\x68\x3d\x74\x79\x70\x65\x6f\x66\x20\x64\x2c\x68\x3d\x3d\x3d\ \x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x28\x67\x3d\x62\x76\x2e\ \x65\x78\x65\x63\x28\x64\x29\x29\x26\x26\x28\x64\x3d\x2b\x28\x67\ \x5b\x31\x5d\x2b\x31\x29\x2a\x2b\x67\x5b\x32\x5d\x2b\x70\x61\x72\ \x73\x65\x46\x6c\x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\x61\x2c\ \x63\x29\x29\x2c\x68\x3d\x22\x6e\x75\x6d\x62\x65\x72\x22\x29\x3b\ \x69\x66\x28\x64\x3d\x3d\x6e\x75\x6c\x6c\x7c\x7c\x68\x3d\x3d\x3d\ \x22\x6e\x75\x6d\x62\x65\x72\x22\x26\x26\x69\x73\x4e\x61\x4e\x28\ \x64\x29\x29\x72\x65\x74\x75\x72\x6e\x3b\x68\x3d\x3d\x3d\x22\x6e\ \x75\x6d\x62\x65\x72\x22\x26\x26\x21\x66\x2e\x63\x73\x73\x4e\x75\ \x6d\x62\x65\x72\x5b\x69\x5d\x26\x26\x28\x64\x2b\x3d\x22\x70\x78\ \x22\x29\x3b\x69\x66\x28\x21\x6b\x7c\x7c\x21\x28\x22\x73\x65\x74\ \x22\x69\x6e\x20\x6b\x29\x7c\x7c\x28\x64\x3d\x6b\x2e\x73\x65\x74\ \x28\x61\x2c\x64\x29\x29\x21\x3d\x3d\x62\x29\x74\x72\x79\x7b\x6a\ \x5b\x63\x5d\x3d\x64\x7d\x63\x61\x74\x63\x68\x28\x6c\x29\x7b\x7d\ \x7d\x7d\x2c\x63\x73\x73\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x63\x2c\x64\x29\x7b\x76\x61\x72\x20\x65\x2c\x67\x3b\x63\ \x3d\x66\x2e\x63\x61\x6d\x65\x6c\x43\x61\x73\x65\x28\x63\x29\x2c\ \x67\x3d\x66\x2e\x63\x73\x73\x48\x6f\x6f\x6b\x73\x5b\x63\x5d\x2c\ \x63\x3d\x66\x2e\x63\x73\x73\x50\x72\x6f\x70\x73\x5b\x63\x5d\x7c\ \x7c\x63\x2c\x63\x3d\x3d\x3d\x22\x63\x73\x73\x46\x6c\x6f\x61\x74\ \x22\x26\x26\x28\x63\x3d\x22\x66\x6c\x6f\x61\x74\x22\x29\x3b\x69\ \x66\x28\x67\x26\x26\x22\x67\x65\x74\x22\x69\x6e\x20\x67\x26\x26\ \x28\x65\x3d\x67\x2e\x67\x65\x74\x28\x61\x2c\x21\x30\x2c\x64\x29\ \x29\x21\x3d\x3d\x62\x29\x72\x65\x74\x75\x72\x6e\x20\x65\x3b\x69\ \x66\x28\x62\x7a\x29\x72\x65\x74\x75\x72\x6e\x20\x62\x7a\x28\x61\ \x2c\x63\x29\x7d\x2c\x73\x77\x61\x70\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\ \x7b\x7d\x3b\x66\x6f\x72\x28\x76\x61\x72\x20\x65\x20\x69\x6e\x20\ \x62\x29\x64\x5b\x65\x5d\x3d\x61\x2e\x73\x74\x79\x6c\x65\x5b\x65\ \x5d\x2c\x61\x2e\x73\x74\x79\x6c\x65\x5b\x65\x5d\x3d\x62\x5b\x65\ \x5d\x3b\x63\x2e\x63\x61\x6c\x6c\x28\x61\x29\x3b\x66\x6f\x72\x28\ \x65\x20\x69\x6e\x20\x62\x29\x61\x2e\x73\x74\x79\x6c\x65\x5b\x65\ \x5d\x3d\x64\x5b\x65\x5d\x7d\x7d\x29\x2c\x66\x2e\x63\x75\x72\x43\ \x53\x53\x3d\x66\x2e\x63\x73\x73\x2c\x66\x2e\x65\x61\x63\x68\x28\ \x5b\x22\x68\x65\x69\x67\x68\x74\x22\x2c\x22\x77\x69\x64\x74\x68\ \x22\x5d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\ \x7b\x66\x2e\x63\x73\x73\x48\x6f\x6f\x6b\x73\x5b\x62\x5d\x3d\x7b\ \x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\ \x2c\x64\x29\x7b\x76\x61\x72\x20\x65\x3b\x69\x66\x28\x63\x29\x7b\ \x69\x66\x28\x61\x2e\x6f\x66\x66\x73\x65\x74\x57\x69\x64\x74\x68\ \x21\x3d\x3d\x30\x29\x72\x65\x74\x75\x72\x6e\x20\x62\x43\x28\x61\ \x2c\x62\x2c\x64\x29\x3b\x66\x2e\x73\x77\x61\x70\x28\x61\x2c\x62\ \x77\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x65\x3d\x62\ \x43\x28\x61\x2c\x62\x2c\x64\x29\x7d\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x65\x7d\x7d\x2c\x73\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x29\x7b\x69\x66\x28\x21\x62\x74\x2e\x74\ \x65\x73\x74\x28\x62\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x62\x3b\ \x62\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\x62\x29\x3b\ \x69\x66\x28\x62\x3e\x3d\x30\x29\x72\x65\x74\x75\x72\x6e\x20\x62\ \x2b\x22\x70\x78\x22\x7d\x7d\x7d\x29\x2c\x66\x2e\x73\x75\x70\x70\ \x6f\x72\x74\x2e\x6f\x70\x61\x63\x69\x74\x79\x7c\x7c\x28\x66\x2e\ \x63\x73\x73\x48\x6f\x6f\x6b\x73\x2e\x6f\x70\x61\x63\x69\x74\x79\ \x3d\x7b\x67\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x62\x72\x2e\x74\x65\ \x73\x74\x28\x28\x62\x26\x26\x61\x2e\x63\x75\x72\x72\x65\x6e\x74\ \x53\x74\x79\x6c\x65\x3f\x61\x2e\x63\x75\x72\x72\x65\x6e\x74\x53\ \x74\x79\x6c\x65\x2e\x66\x69\x6c\x74\x65\x72\x3a\x61\x2e\x73\x74\ \x79\x6c\x65\x2e\x66\x69\x6c\x74\x65\x72\x29\x7c\x7c\x22\x22\x29\ \x3f\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\x52\x65\x67\x45\ \x78\x70\x2e\x24\x31\x29\x2f\x31\x30\x30\x2b\x22\x22\x3a\x62\x3f\ \x22\x31\x22\x3a\x22\x22\x7d\x2c\x73\x65\x74\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\ \x61\x2e\x73\x74\x79\x6c\x65\x2c\x64\x3d\x61\x2e\x63\x75\x72\x72\ \x65\x6e\x74\x53\x74\x79\x6c\x65\x2c\x65\x3d\x66\x2e\x69\x73\x4e\ \x75\x6d\x65\x72\x69\x63\x28\x62\x29\x3f\x22\x61\x6c\x70\x68\x61\ \x28\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x2b\x62\x2a\x31\x30\x30\ \x2b\x22\x29\x22\x3a\x22\x22\x2c\x67\x3d\x64\x26\x26\x64\x2e\x66\ \x69\x6c\x74\x65\x72\x7c\x7c\x63\x2e\x66\x69\x6c\x74\x65\x72\x7c\ \x7c\x22\x22\x3b\x63\x2e\x7a\x6f\x6f\x6d\x3d\x31\x3b\x69\x66\x28\ \x62\x3e\x3d\x31\x26\x26\x66\x2e\x74\x72\x69\x6d\x28\x67\x2e\x72\ \x65\x70\x6c\x61\x63\x65\x28\x62\x71\x2c\x22\x22\x29\x29\x3d\x3d\ \x3d\x22\x22\x29\x7b\x63\x2e\x72\x65\x6d\x6f\x76\x65\x41\x74\x74\ \x72\x69\x62\x75\x74\x65\x28\x22\x66\x69\x6c\x74\x65\x72\x22\x29\ \x3b\x69\x66\x28\x64\x26\x26\x21\x64\x2e\x66\x69\x6c\x74\x65\x72\ \x29\x72\x65\x74\x75\x72\x6e\x7d\x63\x2e\x66\x69\x6c\x74\x65\x72\ \x3d\x62\x71\x2e\x74\x65\x73\x74\x28\x67\x29\x3f\x67\x2e\x72\x65\ \x70\x6c\x61\x63\x65\x28\x62\x71\x2c\x65\x29\x3a\x67\x2b\x22\x20\ \x22\x2b\x65\x7d\x7d\x29\x2c\x66\x28\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x72\x65\ \x6c\x69\x61\x62\x6c\x65\x4d\x61\x72\x67\x69\x6e\x52\x69\x67\x68\ \x74\x7c\x7c\x28\x66\x2e\x63\x73\x73\x48\x6f\x6f\x6b\x73\x2e\x6d\ \x61\x72\x67\x69\x6e\x52\x69\x67\x68\x74\x3d\x7b\x67\x65\x74\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\ \x72\x20\x63\x3b\x66\x2e\x73\x77\x61\x70\x28\x61\x2c\x7b\x64\x69\ \x73\x70\x6c\x61\x79\x3a\x22\x69\x6e\x6c\x69\x6e\x65\x2d\x62\x6c\ \x6f\x63\x6b\x22\x7d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\ \x7b\x62\x3f\x63\x3d\x62\x7a\x28\x61\x2c\x22\x6d\x61\x72\x67\x69\ \x6e\x2d\x72\x69\x67\x68\x74\x22\x2c\x22\x6d\x61\x72\x67\x69\x6e\ \x52\x69\x67\x68\x74\x22\x29\x3a\x63\x3d\x61\x2e\x73\x74\x79\x6c\ \x65\x2e\x6d\x61\x72\x67\x69\x6e\x52\x69\x67\x68\x74\x7d\x29\x3b\ \x72\x65\x74\x75\x72\x6e\x20\x63\x7d\x7d\x29\x7d\x29\x2c\x63\x2e\ \x64\x65\x66\x61\x75\x6c\x74\x56\x69\x65\x77\x26\x26\x63\x2e\x64\ \x65\x66\x61\x75\x6c\x74\x56\x69\x65\x77\x2e\x67\x65\x74\x43\x6f\ \x6d\x70\x75\x74\x65\x64\x53\x74\x79\x6c\x65\x26\x26\x28\x62\x41\ \x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\ \x61\x72\x20\x63\x2c\x64\x2c\x65\x3b\x62\x3d\x62\x2e\x72\x65\x70\ \x6c\x61\x63\x65\x28\x62\x73\x2c\x22\x2d\x24\x31\x22\x29\x2e\x74\ \x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x2c\x28\x64\x3d\ \x61\x2e\x6f\x77\x6e\x65\x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x2e\ \x64\x65\x66\x61\x75\x6c\x74\x56\x69\x65\x77\x29\x26\x26\x28\x65\ \x3d\x64\x2e\x67\x65\x74\x43\x6f\x6d\x70\x75\x74\x65\x64\x53\x74\ \x79\x6c\x65\x28\x61\x2c\x6e\x75\x6c\x6c\x29\x29\x26\x26\x28\x63\ \x3d\x65\x2e\x67\x65\x74\x50\x72\x6f\x70\x65\x72\x74\x79\x56\x61\ \x6c\x75\x65\x28\x62\x29\x2c\x63\x3d\x3d\x3d\x22\x22\x26\x26\x21\ \x66\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\x28\x61\x2e\x6f\x77\x6e\ \x65\x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x64\x6f\x63\x75\x6d\ \x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2c\x61\x29\x26\x26\x28\ \x63\x3d\x66\x2e\x73\x74\x79\x6c\x65\x28\x61\x2c\x62\x29\x29\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x63\x7d\x29\x2c\x63\x2e\x64\x6f\ \x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2e\x63\x75\ \x72\x72\x65\x6e\x74\x53\x74\x79\x6c\x65\x26\x26\x28\x62\x42\x3d\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\ \x72\x20\x63\x2c\x64\x2c\x65\x2c\x66\x3d\x61\x2e\x63\x75\x72\x72\ \x65\x6e\x74\x53\x74\x79\x6c\x65\x26\x26\x61\x2e\x63\x75\x72\x72\ \x65\x6e\x74\x53\x74\x79\x6c\x65\x5b\x62\x5d\x2c\x67\x3d\x61\x2e\ \x73\x74\x79\x6c\x65\x3b\x66\x3d\x3d\x3d\x6e\x75\x6c\x6c\x26\x26\ \x67\x26\x26\x28\x65\x3d\x67\x5b\x62\x5d\x29\x26\x26\x28\x66\x3d\ \x65\x29\x2c\x21\x62\x74\x2e\x74\x65\x73\x74\x28\x66\x29\x26\x26\ \x62\x75\x2e\x74\x65\x73\x74\x28\x66\x29\x26\x26\x28\x63\x3d\x67\ \x2e\x6c\x65\x66\x74\x2c\x64\x3d\x61\x2e\x72\x75\x6e\x74\x69\x6d\ \x65\x53\x74\x79\x6c\x65\x26\x26\x61\x2e\x72\x75\x6e\x74\x69\x6d\ \x65\x53\x74\x79\x6c\x65\x2e\x6c\x65\x66\x74\x2c\x64\x26\x26\x28\ \x61\x2e\x72\x75\x6e\x74\x69\x6d\x65\x53\x74\x79\x6c\x65\x2e\x6c\ \x65\x66\x74\x3d\x61\x2e\x63\x75\x72\x72\x65\x6e\x74\x53\x74\x79\ \x6c\x65\x2e\x6c\x65\x66\x74\x29\x2c\x67\x2e\x6c\x65\x66\x74\x3d\ \x62\x3d\x3d\x3d\x22\x66\x6f\x6e\x74\x53\x69\x7a\x65\x22\x3f\x22\ \x31\x65\x6d\x22\x3a\x66\x7c\x7c\x30\x2c\x66\x3d\x67\x2e\x70\x69\ \x78\x65\x6c\x4c\x65\x66\x74\x2b\x22\x70\x78\x22\x2c\x67\x2e\x6c\ \x65\x66\x74\x3d\x63\x2c\x64\x26\x26\x28\x61\x2e\x72\x75\x6e\x74\ \x69\x6d\x65\x53\x74\x79\x6c\x65\x2e\x6c\x65\x66\x74\x3d\x64\x29\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x66\x3d\x3d\x3d\x22\x22\x3f\ \x22\x61\x75\x74\x6f\x22\x3a\x66\x7d\x29\x2c\x62\x7a\x3d\x62\x41\ \x7c\x7c\x62\x42\x2c\x66\x2e\x65\x78\x70\x72\x26\x26\x66\x2e\x65\ \x78\x70\x72\x2e\x66\x69\x6c\x74\x65\x72\x73\x26\x26\x28\x66\x2e\ \x65\x78\x70\x72\x2e\x66\x69\x6c\x74\x65\x72\x73\x2e\x68\x69\x64\ \x64\x65\x6e\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\ \x76\x61\x72\x20\x62\x3d\x61\x2e\x6f\x66\x66\x73\x65\x74\x57\x69\ \x64\x74\x68\x2c\x63\x3d\x61\x2e\x6f\x66\x66\x73\x65\x74\x48\x65\ \x69\x67\x68\x74\x3b\x72\x65\x74\x75\x72\x6e\x20\x62\x3d\x3d\x3d\ \x30\x26\x26\x63\x3d\x3d\x3d\x30\x7c\x7c\x21\x66\x2e\x73\x75\x70\ \x70\x6f\x72\x74\x2e\x72\x65\x6c\x69\x61\x62\x6c\x65\x48\x69\x64\ \x64\x65\x6e\x4f\x66\x66\x73\x65\x74\x73\x26\x26\x28\x61\x2e\x73\ \x74\x79\x6c\x65\x26\x26\x61\x2e\x73\x74\x79\x6c\x65\x2e\x64\x69\ \x73\x70\x6c\x61\x79\x7c\x7c\x66\x2e\x63\x73\x73\x28\x61\x2c\x22\ \x64\x69\x73\x70\x6c\x61\x79\x22\x29\x29\x3d\x3d\x3d\x22\x6e\x6f\ \x6e\x65\x22\x7d\x2c\x66\x2e\x65\x78\x70\x72\x2e\x66\x69\x6c\x74\ \x65\x72\x73\x2e\x76\x69\x73\x69\x62\x6c\x65\x3d\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\x66\ \x2e\x65\x78\x70\x72\x2e\x66\x69\x6c\x74\x65\x72\x73\x2e\x68\x69\ \x64\x64\x65\x6e\x28\x61\x29\x7d\x29\x3b\x76\x61\x72\x20\x62\x44\ \x3d\x2f\x25\x32\x30\x2f\x67\x2c\x62\x45\x3d\x2f\x5c\x5b\x5c\x5d\ \x24\x2f\x2c\x62\x46\x3d\x2f\x5c\x72\x3f\x5c\x6e\x2f\x67\x2c\x62\ \x47\x3d\x2f\x23\x2e\x2a\x24\x2f\x2c\x62\x48\x3d\x2f\x5e\x28\x2e\ \x2a\x3f\x29\x3a\x5b\x20\x5c\x74\x5d\x2a\x28\x5b\x5e\x5c\x72\x5c\ \x6e\x5d\x2a\x29\x5c\x72\x3f\x24\x2f\x6d\x67\x2c\x62\x49\x3d\x2f\ \x5e\x28\x3f\x3a\x63\x6f\x6c\x6f\x72\x7c\x64\x61\x74\x65\x7c\x64\ \x61\x74\x65\x74\x69\x6d\x65\x7c\x64\x61\x74\x65\x74\x69\x6d\x65\ \x2d\x6c\x6f\x63\x61\x6c\x7c\x65\x6d\x61\x69\x6c\x7c\x68\x69\x64\ \x64\x65\x6e\x7c\x6d\x6f\x6e\x74\x68\x7c\x6e\x75\x6d\x62\x65\x72\ \x7c\x70\x61\x73\x73\x77\x6f\x72\x64\x7c\x72\x61\x6e\x67\x65\x7c\ \x73\x65\x61\x72\x63\x68\x7c\x74\x65\x6c\x7c\x74\x65\x78\x74\x7c\ \x74\x69\x6d\x65\x7c\x75\x72\x6c\x7c\x77\x65\x65\x6b\x29\x24\x2f\ \x69\x2c\x62\x4a\x3d\x2f\x5e\x28\x3f\x3a\x61\x62\x6f\x75\x74\x7c\ \x61\x70\x70\x7c\x61\x70\x70\x5c\x2d\x73\x74\x6f\x72\x61\x67\x65\ \x7c\x2e\x2b\x5c\x2d\x65\x78\x74\x65\x6e\x73\x69\x6f\x6e\x7c\x66\ \x69\x6c\x65\x7c\x72\x65\x73\x7c\x77\x69\x64\x67\x65\x74\x29\x3a\ \x24\x2f\x2c\x62\x4b\x3d\x2f\x5e\x28\x3f\x3a\x47\x45\x54\x7c\x48\ \x45\x41\x44\x29\x24\x2f\x2c\x62\x4c\x3d\x2f\x5e\x5c\x2f\x5c\x2f\ \x2f\x2c\x62\x4d\x3d\x2f\x5c\x3f\x2f\x2c\x62\x4e\x3d\x2f\x3c\x73\ \x63\x72\x69\x70\x74\x5c\x62\x5b\x5e\x3c\x5d\x2a\x28\x3f\x3a\x28\ \x3f\x21\x3c\x5c\x2f\x73\x63\x72\x69\x70\x74\x3e\x29\x3c\x5b\x5e\ \x3c\x5d\x2a\x29\x2a\x3c\x5c\x2f\x73\x63\x72\x69\x70\x74\x3e\x2f\ \x67\x69\x2c\x62\x4f\x3d\x2f\x5e\x28\x3f\x3a\x73\x65\x6c\x65\x63\ \x74\x7c\x74\x65\x78\x74\x61\x72\x65\x61\x29\x2f\x69\x2c\x62\x50\ \x3d\x2f\x5c\x73\x2b\x2f\x2c\x62\x51\x3d\x2f\x28\x5b\x3f\x26\x5d\ \x29\x5f\x3d\x5b\x5e\x26\x5d\x2a\x2f\x2c\x62\x52\x3d\x2f\x5e\x28\ \x5b\x5c\x77\x5c\x2b\x5c\x2e\x5c\x2d\x5d\x2b\x3a\x29\x28\x3f\x3a\ \x5c\x2f\x5c\x2f\x28\x5b\x5e\x5c\x2f\x3f\x23\x3a\x5d\x2a\x29\x28\ \x3f\x3a\x3a\x28\x5c\x64\x2b\x29\x29\x3f\x29\x3f\x2f\x2c\x62\x53\ \x3d\x66\x2e\x66\x6e\x2e\x6c\x6f\x61\x64\x2c\x62\x54\x3d\x7b\x7d\ \x2c\x62\x55\x3d\x7b\x7d\x2c\x62\x56\x2c\x62\x57\x2c\x62\x58\x3d\ \x5b\x22\x2a\x2f\x22\x5d\x2b\x5b\x22\x2a\x22\x5d\x3b\x74\x72\x79\ \x7b\x62\x56\x3d\x65\x2e\x68\x72\x65\x66\x7d\x63\x61\x74\x63\x68\ \x28\x62\x59\x29\x7b\x62\x56\x3d\x63\x2e\x63\x72\x65\x61\x74\x65\ \x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x61\x22\x29\x2c\x62\x56\x2e\ \x68\x72\x65\x66\x3d\x22\x22\x2c\x62\x56\x3d\x62\x56\x2e\x68\x72\ \x65\x66\x7d\x62\x57\x3d\x62\x52\x2e\x65\x78\x65\x63\x28\x62\x56\ \x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x29\x7c\ \x7c\x5b\x5d\x2c\x66\x2e\x66\x6e\x2e\x65\x78\x74\x65\x6e\x64\x28\ \x7b\x6c\x6f\x61\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x63\x2c\x64\x29\x7b\x69\x66\x28\x74\x79\x70\x65\x6f\x66\x20\ \x61\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x62\x53\x29\ \x72\x65\x74\x75\x72\x6e\x20\x62\x53\x2e\x61\x70\x70\x6c\x79\x28\ \x74\x68\x69\x73\x2c\x61\x72\x67\x75\x6d\x65\x6e\x74\x73\x29\x3b\ \x69\x66\x28\x21\x74\x68\x69\x73\x2e\x6c\x65\x6e\x67\x74\x68\x29\ \x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x3b\x76\x61\x72\x20\ \x65\x3d\x61\x2e\x69\x6e\x64\x65\x78\x4f\x66\x28\x22\x20\x22\x29\ \x3b\x69\x66\x28\x65\x3e\x3d\x30\x29\x7b\x76\x61\x72\x20\x67\x3d\ \x61\x2e\x73\x6c\x69\x63\x65\x28\x65\x2c\x61\x2e\x6c\x65\x6e\x67\ \x74\x68\x29\x3b\x61\x3d\x61\x2e\x73\x6c\x69\x63\x65\x28\x30\x2c\ \x65\x29\x7d\x76\x61\x72\x20\x68\x3d\x22\x47\x45\x54\x22\x3b\x63\ \x26\x26\x28\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x63\x29\x3f\x28\x64\x3d\x63\x2c\x63\x3d\x62\x29\x3a\x74\x79\x70\ \x65\x6f\x66\x20\x63\x3d\x3d\x22\x6f\x62\x6a\x65\x63\x74\x22\x26\ \x26\x28\x63\x3d\x66\x2e\x70\x61\x72\x61\x6d\x28\x63\x2c\x66\x2e\ \x61\x6a\x61\x78\x53\x65\x74\x74\x69\x6e\x67\x73\x2e\x74\x72\x61\ \x64\x69\x74\x69\x6f\x6e\x61\x6c\x29\x2c\x68\x3d\x22\x50\x4f\x53\ \x54\x22\x29\x29\x3b\x76\x61\x72\x20\x69\x3d\x74\x68\x69\x73\x3b\ \x66\x2e\x61\x6a\x61\x78\x28\x7b\x75\x72\x6c\x3a\x61\x2c\x74\x79\ \x70\x65\x3a\x68\x2c\x64\x61\x74\x61\x54\x79\x70\x65\x3a\x22\x68\ \x74\x6d\x6c\x22\x2c\x64\x61\x74\x61\x3a\x63\x2c\x63\x6f\x6d\x70\ \x6c\x65\x74\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x2c\x63\x29\x7b\x63\x3d\x61\x2e\x72\x65\x73\x70\x6f\x6e\x73\ \x65\x54\x65\x78\x74\x2c\x61\x2e\x69\x73\x52\x65\x73\x6f\x6c\x76\ \x65\x64\x28\x29\x26\x26\x28\x61\x2e\x64\x6f\x6e\x65\x28\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x63\x3d\x61\x7d\x29\x2c\ \x69\x2e\x68\x74\x6d\x6c\x28\x67\x3f\x66\x28\x22\x3c\x64\x69\x76\ \x3e\x22\x29\x2e\x61\x70\x70\x65\x6e\x64\x28\x63\x2e\x72\x65\x70\ \x6c\x61\x63\x65\x28\x62\x4e\x2c\x22\x22\x29\x29\x2e\x66\x69\x6e\ \x64\x28\x67\x29\x3a\x63\x29\x29\x2c\x64\x26\x26\x69\x2e\x65\x61\ \x63\x68\x28\x64\x2c\x5b\x63\x2c\x62\x2c\x61\x5d\x29\x7d\x7d\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x73\x65\ \x72\x69\x61\x6c\x69\x7a\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x70\x61\x72\x61\ \x6d\x28\x74\x68\x69\x73\x2e\x73\x65\x72\x69\x61\x6c\x69\x7a\x65\ \x41\x72\x72\x61\x79\x28\x29\x29\x7d\x2c\x73\x65\x72\x69\x61\x6c\ \x69\x7a\x65\x41\x72\x72\x61\x79\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\ \x6d\x61\x70\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x72\ \x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\x65\ \x6e\x74\x73\x3f\x66\x2e\x6d\x61\x6b\x65\x41\x72\x72\x61\x79\x28\ \x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\x65\x6e\x74\x73\x29\x3a\x74\ \x68\x69\x73\x7d\x29\x2e\x66\x69\x6c\x74\x65\x72\x28\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x2e\x6e\x61\x6d\x65\x26\x26\x21\x74\x68\x69\x73\x2e\ \x64\x69\x73\x61\x62\x6c\x65\x64\x26\x26\x28\x74\x68\x69\x73\x2e\ \x63\x68\x65\x63\x6b\x65\x64\x7c\x7c\x62\x4f\x2e\x74\x65\x73\x74\ \x28\x74\x68\x69\x73\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x7c\ \x7c\x62\x49\x2e\x74\x65\x73\x74\x28\x74\x68\x69\x73\x2e\x74\x79\ \x70\x65\x29\x29\x7d\x29\x2e\x6d\x61\x70\x28\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x66\ \x28\x74\x68\x69\x73\x29\x2e\x76\x61\x6c\x28\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x63\x3d\x3d\x6e\x75\x6c\x6c\x3f\x6e\x75\x6c\x6c\ \x3a\x66\x2e\x69\x73\x41\x72\x72\x61\x79\x28\x63\x29\x3f\x66\x2e\ \x6d\x61\x70\x28\x63\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x63\x29\x7b\x72\x65\x74\x75\x72\x6e\x7b\x6e\x61\x6d\x65\x3a\ \x62\x2e\x6e\x61\x6d\x65\x2c\x76\x61\x6c\x75\x65\x3a\x61\x2e\x72\ \x65\x70\x6c\x61\x63\x65\x28\x62\x46\x2c\x22\x5c\x72\x5c\x6e\x22\ \x29\x7d\x7d\x29\x3a\x7b\x6e\x61\x6d\x65\x3a\x62\x2e\x6e\x61\x6d\ \x65\x2c\x76\x61\x6c\x75\x65\x3a\x63\x2e\x72\x65\x70\x6c\x61\x63\ \x65\x28\x62\x46\x2c\x22\x5c\x72\x5c\x6e\x22\x29\x7d\x7d\x29\x2e\ \x67\x65\x74\x28\x29\x7d\x7d\x29\x2c\x66\x2e\x65\x61\x63\x68\x28\ \x22\x61\x6a\x61\x78\x53\x74\x61\x72\x74\x20\x61\x6a\x61\x78\x53\ \x74\x6f\x70\x20\x61\x6a\x61\x78\x43\x6f\x6d\x70\x6c\x65\x74\x65\ \x20\x61\x6a\x61\x78\x45\x72\x72\x6f\x72\x20\x61\x6a\x61\x78\x53\ \x75\x63\x63\x65\x73\x73\x20\x61\x6a\x61\x78\x53\x65\x6e\x64\x22\ \x2e\x73\x70\x6c\x69\x74\x28\x22\x20\x22\x29\x2c\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x66\x2e\x66\x6e\x5b\x62\ \x5d\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\ \x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x6f\x6e\x28\x62\x2c\x61\ \x29\x7d\x7d\x29\x2c\x66\x2e\x65\x61\x63\x68\x28\x5b\x22\x67\x65\ \x74\x22\x2c\x22\x70\x6f\x73\x74\x22\x5d\x2c\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x66\x5b\x63\x5d\x3d\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x64\x2c\x65\x2c\x67\x29\x7b\ \x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x64\x29\x26\ \x26\x28\x67\x3d\x67\x7c\x7c\x65\x2c\x65\x3d\x64\x2c\x64\x3d\x62\ \x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x61\x6a\x61\x78\x28\ \x7b\x74\x79\x70\x65\x3a\x63\x2c\x75\x72\x6c\x3a\x61\x2c\x64\x61\ \x74\x61\x3a\x64\x2c\x73\x75\x63\x63\x65\x73\x73\x3a\x65\x2c\x64\ \x61\x74\x61\x54\x79\x70\x65\x3a\x67\x7d\x29\x7d\x7d\x29\x2c\x66\ \x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x67\x65\x74\x53\x63\x72\x69\ \x70\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\ \x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x67\x65\x74\x28\x61\x2c\ \x62\x2c\x63\x2c\x22\x73\x63\x72\x69\x70\x74\x22\x29\x7d\x2c\x67\ \x65\x74\x4a\x53\x4f\x4e\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x62\x2c\x63\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\ \x67\x65\x74\x28\x61\x2c\x62\x2c\x63\x2c\x22\x6a\x73\x6f\x6e\x22\ \x29\x7d\x2c\x61\x6a\x61\x78\x53\x65\x74\x75\x70\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x62\x3f\x62\x5f\x28\ \x61\x2c\x66\x2e\x61\x6a\x61\x78\x53\x65\x74\x74\x69\x6e\x67\x73\ \x29\x3a\x28\x62\x3d\x61\x2c\x61\x3d\x66\x2e\x61\x6a\x61\x78\x53\ \x65\x74\x74\x69\x6e\x67\x73\x29\x2c\x62\x5f\x28\x61\x2c\x62\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x7d\x2c\x61\x6a\x61\x78\x53\ \x65\x74\x74\x69\x6e\x67\x73\x3a\x7b\x75\x72\x6c\x3a\x62\x56\x2c\ \x69\x73\x4c\x6f\x63\x61\x6c\x3a\x62\x4a\x2e\x74\x65\x73\x74\x28\ \x62\x57\x5b\x31\x5d\x29\x2c\x67\x6c\x6f\x62\x61\x6c\x3a\x21\x30\ \x2c\x74\x79\x70\x65\x3a\x22\x47\x45\x54\x22\x2c\x63\x6f\x6e\x74\ \x65\x6e\x74\x54\x79\x70\x65\x3a\x22\x61\x70\x70\x6c\x69\x63\x61\ \x74\x69\x6f\x6e\x2f\x78\x2d\x77\x77\x77\x2d\x66\x6f\x72\x6d\x2d\ \x75\x72\x6c\x65\x6e\x63\x6f\x64\x65\x64\x22\x2c\x70\x72\x6f\x63\ \x65\x73\x73\x44\x61\x74\x61\x3a\x21\x30\x2c\x61\x73\x79\x6e\x63\ \x3a\x21\x30\x2c\x61\x63\x63\x65\x70\x74\x73\x3a\x7b\x78\x6d\x6c\ \x3a\x22\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\x2f\x78\x6d\ \x6c\x2c\x20\x74\x65\x78\x74\x2f\x78\x6d\x6c\x22\x2c\x68\x74\x6d\ \x6c\x3a\x22\x74\x65\x78\x74\x2f\x68\x74\x6d\x6c\x22\x2c\x74\x65\ \x78\x74\x3a\x22\x74\x65\x78\x74\x2f\x70\x6c\x61\x69\x6e\x22\x2c\ \x6a\x73\x6f\x6e\x3a\x22\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\ \x6e\x2f\x6a\x73\x6f\x6e\x2c\x20\x74\x65\x78\x74\x2f\x6a\x61\x76\ \x61\x73\x63\x72\x69\x70\x74\x22\x2c\x22\x2a\x22\x3a\x62\x58\x7d\ \x2c\x63\x6f\x6e\x74\x65\x6e\x74\x73\x3a\x7b\x78\x6d\x6c\x3a\x2f\ \x78\x6d\x6c\x2f\x2c\x68\x74\x6d\x6c\x3a\x2f\x68\x74\x6d\x6c\x2f\ \x2c\x6a\x73\x6f\x6e\x3a\x2f\x6a\x73\x6f\x6e\x2f\x7d\x2c\x72\x65\ \x73\x70\x6f\x6e\x73\x65\x46\x69\x65\x6c\x64\x73\x3a\x7b\x78\x6d\ \x6c\x3a\x22\x72\x65\x73\x70\x6f\x6e\x73\x65\x58\x4d\x4c\x22\x2c\ \x74\x65\x78\x74\x3a\x22\x72\x65\x73\x70\x6f\x6e\x73\x65\x54\x65\ \x78\x74\x22\x7d\x2c\x63\x6f\x6e\x76\x65\x72\x74\x65\x72\x73\x3a\ \x7b\x22\x2a\x20\x74\x65\x78\x74\x22\x3a\x61\x2e\x53\x74\x72\x69\ \x6e\x67\x2c\x22\x74\x65\x78\x74\x20\x68\x74\x6d\x6c\x22\x3a\x21\ \x30\x2c\x22\x74\x65\x78\x74\x20\x6a\x73\x6f\x6e\x22\x3a\x66\x2e\ \x70\x61\x72\x73\x65\x4a\x53\x4f\x4e\x2c\x22\x74\x65\x78\x74\x20\ \x78\x6d\x6c\x22\x3a\x66\x2e\x70\x61\x72\x73\x65\x58\x4d\x4c\x7d\ \x2c\x66\x6c\x61\x74\x4f\x70\x74\x69\x6f\x6e\x73\x3a\x7b\x63\x6f\ \x6e\x74\x65\x78\x74\x3a\x21\x30\x2c\x75\x72\x6c\x3a\x21\x30\x7d\ \x7d\x2c\x61\x6a\x61\x78\x50\x72\x65\x66\x69\x6c\x74\x65\x72\x3a\ \x62\x5a\x28\x62\x54\x29\x2c\x61\x6a\x61\x78\x54\x72\x61\x6e\x73\ \x70\x6f\x72\x74\x3a\x62\x5a\x28\x62\x55\x29\x2c\x61\x6a\x61\x78\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x20\x77\x28\x61\x2c\x63\x2c\x6c\x2c\ \x6d\x29\x7b\x69\x66\x28\x73\x21\x3d\x3d\x32\x29\x7b\x73\x3d\x32\ \x2c\x71\x26\x26\x63\x6c\x65\x61\x72\x54\x69\x6d\x65\x6f\x75\x74\ \x28\x71\x29\x2c\x70\x3d\x62\x2c\x6e\x3d\x6d\x7c\x7c\x22\x22\x2c\ \x76\x2e\x72\x65\x61\x64\x79\x53\x74\x61\x74\x65\x3d\x61\x3e\x30\ \x3f\x34\x3a\x30\x3b\x76\x61\x72\x20\x6f\x2c\x72\x2c\x75\x2c\x77\ \x3d\x63\x2c\x78\x3d\x6c\x3f\x63\x62\x28\x64\x2c\x76\x2c\x6c\x29\ \x3a\x62\x2c\x79\x2c\x7a\x3b\x69\x66\x28\x61\x3e\x3d\x32\x30\x30\ \x26\x26\x61\x3c\x33\x30\x30\x7c\x7c\x61\x3d\x3d\x3d\x33\x30\x34\ \x29\x7b\x69\x66\x28\x64\x2e\x69\x66\x4d\x6f\x64\x69\x66\x69\x65\ \x64\x29\x7b\x69\x66\x28\x79\x3d\x76\x2e\x67\x65\x74\x52\x65\x73\ \x70\x6f\x6e\x73\x65\x48\x65\x61\x64\x65\x72\x28\x22\x4c\x61\x73\ \x74\x2d\x4d\x6f\x64\x69\x66\x69\x65\x64\x22\x29\x29\x66\x2e\x6c\ \x61\x73\x74\x4d\x6f\x64\x69\x66\x69\x65\x64\x5b\x6b\x5d\x3d\x79\ \x3b\x69\x66\x28\x7a\x3d\x76\x2e\x67\x65\x74\x52\x65\x73\x70\x6f\ \x6e\x73\x65\x48\x65\x61\x64\x65\x72\x28\x22\x45\x74\x61\x67\x22\ \x29\x29\x66\x2e\x65\x74\x61\x67\x5b\x6b\x5d\x3d\x7a\x7d\x69\x66\ \x28\x61\x3d\x3d\x3d\x33\x30\x34\x29\x77\x3d\x22\x6e\x6f\x74\x6d\ \x6f\x64\x69\x66\x69\x65\x64\x22\x2c\x6f\x3d\x21\x30\x3b\x65\x6c\ \x73\x65\x20\x74\x72\x79\x7b\x72\x3d\x63\x63\x28\x64\x2c\x78\x29\ \x2c\x77\x3d\x22\x73\x75\x63\x63\x65\x73\x73\x22\x2c\x6f\x3d\x21\ \x30\x7d\x63\x61\x74\x63\x68\x28\x41\x29\x7b\x77\x3d\x22\x70\x61\ \x72\x73\x65\x72\x65\x72\x72\x6f\x72\x22\x2c\x75\x3d\x41\x7d\x7d\ \x65\x6c\x73\x65\x7b\x75\x3d\x77\x3b\x69\x66\x28\x21\x77\x7c\x7c\ \x61\x29\x77\x3d\x22\x65\x72\x72\x6f\x72\x22\x2c\x61\x3c\x30\x26\ \x26\x28\x61\x3d\x30\x29\x7d\x76\x2e\x73\x74\x61\x74\x75\x73\x3d\ \x61\x2c\x76\x2e\x73\x74\x61\x74\x75\x73\x54\x65\x78\x74\x3d\x22\ \x22\x2b\x28\x63\x7c\x7c\x77\x29\x2c\x6f\x3f\x68\x2e\x72\x65\x73\ \x6f\x6c\x76\x65\x57\x69\x74\x68\x28\x65\x2c\x5b\x72\x2c\x77\x2c\ \x76\x5d\x29\x3a\x68\x2e\x72\x65\x6a\x65\x63\x74\x57\x69\x74\x68\ \x28\x65\x2c\x5b\x76\x2c\x77\x2c\x75\x5d\x29\x2c\x76\x2e\x73\x74\ \x61\x74\x75\x73\x43\x6f\x64\x65\x28\x6a\x29\x2c\x6a\x3d\x62\x2c\ \x74\x26\x26\x67\x2e\x74\x72\x69\x67\x67\x65\x72\x28\x22\x61\x6a\ \x61\x78\x22\x2b\x28\x6f\x3f\x22\x53\x75\x63\x63\x65\x73\x73\x22\ \x3a\x22\x45\x72\x72\x6f\x72\x22\x29\x2c\x5b\x76\x2c\x64\x2c\x6f\ \x3f\x72\x3a\x75\x5d\x29\x2c\x69\x2e\x66\x69\x72\x65\x57\x69\x74\ \x68\x28\x65\x2c\x5b\x76\x2c\x77\x5d\x29\x2c\x74\x26\x26\x28\x67\ \x2e\x74\x72\x69\x67\x67\x65\x72\x28\x22\x61\x6a\x61\x78\x43\x6f\ \x6d\x70\x6c\x65\x74\x65\x22\x2c\x5b\x76\x2c\x64\x5d\x29\x2c\x2d\ \x2d\x66\x2e\x61\x63\x74\x69\x76\x65\x7c\x7c\x66\x2e\x65\x76\x65\ \x6e\x74\x2e\x74\x72\x69\x67\x67\x65\x72\x28\x22\x61\x6a\x61\x78\ \x53\x74\x6f\x70\x22\x29\x29\x7d\x7d\x74\x79\x70\x65\x6f\x66\x20\ \x61\x3d\x3d\x22\x6f\x62\x6a\x65\x63\x74\x22\x26\x26\x28\x63\x3d\ \x61\x2c\x61\x3d\x62\x29\x2c\x63\x3d\x63\x7c\x7c\x7b\x7d\x3b\x76\ \x61\x72\x20\x64\x3d\x66\x2e\x61\x6a\x61\x78\x53\x65\x74\x75\x70\ \x28\x7b\x7d\x2c\x63\x29\x2c\x65\x3d\x64\x2e\x63\x6f\x6e\x74\x65\ \x78\x74\x7c\x7c\x64\x2c\x67\x3d\x65\x21\x3d\x3d\x64\x26\x26\x28\ \x65\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x7c\x7c\x65\x20\x69\x6e\ \x73\x74\x61\x6e\x63\x65\x6f\x66\x20\x66\x29\x3f\x66\x28\x65\x29\ \x3a\x66\x2e\x65\x76\x65\x6e\x74\x2c\x68\x3d\x66\x2e\x44\x65\x66\ \x65\x72\x72\x65\x64\x28\x29\x2c\x69\x3d\x66\x2e\x43\x61\x6c\x6c\ \x62\x61\x63\x6b\x73\x28\x22\x6f\x6e\x63\x65\x20\x6d\x65\x6d\x6f\ \x72\x79\x22\x29\x2c\x6a\x3d\x64\x2e\x73\x74\x61\x74\x75\x73\x43\ \x6f\x64\x65\x7c\x7c\x7b\x7d\x2c\x6b\x2c\x6c\x3d\x7b\x7d\x2c\x6d\ \x3d\x7b\x7d\x2c\x6e\x2c\x6f\x2c\x70\x2c\x71\x2c\x72\x2c\x73\x3d\ \x30\x2c\x74\x2c\x75\x2c\x76\x3d\x7b\x72\x65\x61\x64\x79\x53\x74\ \x61\x74\x65\x3a\x30\x2c\x73\x65\x74\x52\x65\x71\x75\x65\x73\x74\ \x48\x65\x61\x64\x65\x72\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x62\x29\x7b\x69\x66\x28\x21\x73\x29\x7b\x76\x61\x72\x20\ \x63\x3d\x61\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\ \x29\x3b\x61\x3d\x6d\x5b\x63\x5d\x3d\x6d\x5b\x63\x5d\x7c\x7c\x61\ \x2c\x6c\x5b\x61\x5d\x3d\x62\x7d\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x7d\x2c\x67\x65\x74\x41\x6c\x6c\x52\x65\x73\x70\x6f\ \x6e\x73\x65\x48\x65\x61\x64\x65\x72\x73\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x73\x3d\x3d\ \x3d\x32\x3f\x6e\x3a\x6e\x75\x6c\x6c\x7d\x2c\x67\x65\x74\x52\x65\ \x73\x70\x6f\x6e\x73\x65\x48\x65\x61\x64\x65\x72\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x63\x3b\x69\ \x66\x28\x73\x3d\x3d\x3d\x32\x29\x7b\x69\x66\x28\x21\x6f\x29\x7b\ \x6f\x3d\x7b\x7d\x3b\x77\x68\x69\x6c\x65\x28\x63\x3d\x62\x48\x2e\ \x65\x78\x65\x63\x28\x6e\x29\x29\x6f\x5b\x63\x5b\x31\x5d\x2e\x74\ \x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x5d\x3d\x63\x5b\ \x32\x5d\x7d\x63\x3d\x6f\x5b\x61\x2e\x74\x6f\x4c\x6f\x77\x65\x72\ \x43\x61\x73\x65\x28\x29\x5d\x7d\x72\x65\x74\x75\x72\x6e\x20\x63\ \x3d\x3d\x3d\x62\x3f\x6e\x75\x6c\x6c\x3a\x63\x7d\x2c\x6f\x76\x65\ \x72\x72\x69\x64\x65\x4d\x69\x6d\x65\x54\x79\x70\x65\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x73\x7c\x7c\x28\x64\x2e\ \x6d\x69\x6d\x65\x54\x79\x70\x65\x3d\x61\x29\x3b\x72\x65\x74\x75\ \x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x61\x62\x6f\x72\x74\x3a\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x61\x3d\x61\x7c\x7c\ \x22\x61\x62\x6f\x72\x74\x22\x2c\x70\x26\x26\x70\x2e\x61\x62\x6f\ \x72\x74\x28\x61\x29\x2c\x77\x28\x30\x2c\x61\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x7d\x3b\x68\x2e\x70\x72\x6f\ \x6d\x69\x73\x65\x28\x76\x29\x2c\x76\x2e\x73\x75\x63\x63\x65\x73\ \x73\x3d\x76\x2e\x64\x6f\x6e\x65\x2c\x76\x2e\x65\x72\x72\x6f\x72\ \x3d\x76\x2e\x66\x61\x69\x6c\x2c\x76\x2e\x63\x6f\x6d\x70\x6c\x65\ \x74\x65\x3d\x69\x2e\x61\x64\x64\x2c\x76\x2e\x73\x74\x61\x74\x75\ \x73\x43\x6f\x64\x65\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x7b\x69\x66\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x3b\x69\x66\ \x28\x73\x3c\x32\x29\x66\x6f\x72\x28\x62\x20\x69\x6e\x20\x61\x29\ \x6a\x5b\x62\x5d\x3d\x5b\x6a\x5b\x62\x5d\x2c\x61\x5b\x62\x5d\x5d\ \x3b\x65\x6c\x73\x65\x20\x62\x3d\x61\x5b\x76\x2e\x73\x74\x61\x74\ \x75\x73\x5d\x2c\x76\x2e\x74\x68\x65\x6e\x28\x62\x2c\x62\x29\x7d\ \x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x64\x2e\x75\ \x72\x6c\x3d\x28\x28\x61\x7c\x7c\x64\x2e\x75\x72\x6c\x29\x2b\x22\ \x22\x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x62\x47\x2c\x22\x22\ \x29\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\x62\x4c\x2c\x62\x57\x5b\ \x31\x5d\x2b\x22\x2f\x2f\x22\x29\x2c\x64\x2e\x64\x61\x74\x61\x54\ \x79\x70\x65\x73\x3d\x66\x2e\x74\x72\x69\x6d\x28\x64\x2e\x64\x61\ \x74\x61\x54\x79\x70\x65\x7c\x7c\x22\x2a\x22\x29\x2e\x74\x6f\x4c\ \x6f\x77\x65\x72\x43\x61\x73\x65\x28\x29\x2e\x73\x70\x6c\x69\x74\ \x28\x62\x50\x29\x2c\x64\x2e\x63\x72\x6f\x73\x73\x44\x6f\x6d\x61\ \x69\x6e\x3d\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x72\x3d\x62\x52\x2e\ \x65\x78\x65\x63\x28\x64\x2e\x75\x72\x6c\x2e\x74\x6f\x4c\x6f\x77\ \x65\x72\x43\x61\x73\x65\x28\x29\x29\x2c\x64\x2e\x63\x72\x6f\x73\ \x73\x44\x6f\x6d\x61\x69\x6e\x3d\x21\x28\x21\x72\x7c\x7c\x72\x5b\ \x31\x5d\x3d\x3d\x62\x57\x5b\x31\x5d\x26\x26\x72\x5b\x32\x5d\x3d\ \x3d\x62\x57\x5b\x32\x5d\x26\x26\x28\x72\x5b\x33\x5d\x7c\x7c\x28\ \x72\x5b\x31\x5d\x3d\x3d\x3d\x22\x68\x74\x74\x70\x3a\x22\x3f\x38\ \x30\x3a\x34\x34\x33\x29\x29\x3d\x3d\x28\x62\x57\x5b\x33\x5d\x7c\ \x7c\x28\x62\x57\x5b\x31\x5d\x3d\x3d\x3d\x22\x68\x74\x74\x70\x3a\ \x22\x3f\x38\x30\x3a\x34\x34\x33\x29\x29\x29\x29\x2c\x64\x2e\x64\ \x61\x74\x61\x26\x26\x64\x2e\x70\x72\x6f\x63\x65\x73\x73\x44\x61\ \x74\x61\x26\x26\x74\x79\x70\x65\x6f\x66\x20\x64\x2e\x64\x61\x74\ \x61\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x28\x64\x2e\ \x64\x61\x74\x61\x3d\x66\x2e\x70\x61\x72\x61\x6d\x28\x64\x2e\x64\ \x61\x74\x61\x2c\x64\x2e\x74\x72\x61\x64\x69\x74\x69\x6f\x6e\x61\ \x6c\x29\x29\x2c\x62\x24\x28\x62\x54\x2c\x64\x2c\x63\x2c\x76\x29\ \x3b\x69\x66\x28\x73\x3d\x3d\x3d\x32\x29\x72\x65\x74\x75\x72\x6e\ \x21\x31\x3b\x74\x3d\x64\x2e\x67\x6c\x6f\x62\x61\x6c\x2c\x64\x2e\ \x74\x79\x70\x65\x3d\x64\x2e\x74\x79\x70\x65\x2e\x74\x6f\x55\x70\ \x70\x65\x72\x43\x61\x73\x65\x28\x29\x2c\x64\x2e\x68\x61\x73\x43\ \x6f\x6e\x74\x65\x6e\x74\x3d\x21\x62\x4b\x2e\x74\x65\x73\x74\x28\ \x64\x2e\x74\x79\x70\x65\x29\x2c\x74\x26\x26\x66\x2e\x61\x63\x74\ \x69\x76\x65\x2b\x2b\x3d\x3d\x3d\x30\x26\x26\x66\x2e\x65\x76\x65\ \x6e\x74\x2e\x74\x72\x69\x67\x67\x65\x72\x28\x22\x61\x6a\x61\x78\ \x53\x74\x61\x72\x74\x22\x29\x3b\x69\x66\x28\x21\x64\x2e\x68\x61\ \x73\x43\x6f\x6e\x74\x65\x6e\x74\x29\x7b\x64\x2e\x64\x61\x74\x61\ \x26\x26\x28\x64\x2e\x75\x72\x6c\x2b\x3d\x28\x62\x4d\x2e\x74\x65\ \x73\x74\x28\x64\x2e\x75\x72\x6c\x29\x3f\x22\x26\x22\x3a\x22\x3f\ \x22\x29\x2b\x64\x2e\x64\x61\x74\x61\x2c\x64\x65\x6c\x65\x74\x65\ \x20\x64\x2e\x64\x61\x74\x61\x29\x2c\x6b\x3d\x64\x2e\x75\x72\x6c\ \x3b\x69\x66\x28\x64\x2e\x63\x61\x63\x68\x65\x3d\x3d\x3d\x21\x31\ \x29\x7b\x76\x61\x72\x20\x78\x3d\x66\x2e\x6e\x6f\x77\x28\x29\x2c\ \x79\x3d\x64\x2e\x75\x72\x6c\x2e\x72\x65\x70\x6c\x61\x63\x65\x28\ \x62\x51\x2c\x22\x24\x31\x5f\x3d\x22\x2b\x78\x29\x3b\x64\x2e\x75\ \x72\x6c\x3d\x79\x2b\x28\x79\x3d\x3d\x3d\x64\x2e\x75\x72\x6c\x3f\ \x28\x62\x4d\x2e\x74\x65\x73\x74\x28\x64\x2e\x75\x72\x6c\x29\x3f\ \x22\x26\x22\x3a\x22\x3f\x22\x29\x2b\x22\x5f\x3d\x22\x2b\x78\x3a\ \x22\x22\x29\x7d\x7d\x28\x64\x2e\x64\x61\x74\x61\x26\x26\x64\x2e\ \x68\x61\x73\x43\x6f\x6e\x74\x65\x6e\x74\x26\x26\x64\x2e\x63\x6f\ \x6e\x74\x65\x6e\x74\x54\x79\x70\x65\x21\x3d\x3d\x21\x31\x7c\x7c\ \x63\x2e\x63\x6f\x6e\x74\x65\x6e\x74\x54\x79\x70\x65\x29\x26\x26\ \x76\x2e\x73\x65\x74\x52\x65\x71\x75\x65\x73\x74\x48\x65\x61\x64\ \x65\x72\x28\x22\x43\x6f\x6e\x74\x65\x6e\x74\x2d\x54\x79\x70\x65\ \x22\x2c\x64\x2e\x63\x6f\x6e\x74\x65\x6e\x74\x54\x79\x70\x65\x29\ \x2c\x64\x2e\x69\x66\x4d\x6f\x64\x69\x66\x69\x65\x64\x26\x26\x28\ \x6b\x3d\x6b\x7c\x7c\x64\x2e\x75\x72\x6c\x2c\x66\x2e\x6c\x61\x73\ \x74\x4d\x6f\x64\x69\x66\x69\x65\x64\x5b\x6b\x5d\x26\x26\x76\x2e\ \x73\x65\x74\x52\x65\x71\x75\x65\x73\x74\x48\x65\x61\x64\x65\x72\ \x28\x22\x49\x66\x2d\x4d\x6f\x64\x69\x66\x69\x65\x64\x2d\x53\x69\ \x6e\x63\x65\x22\x2c\x66\x2e\x6c\x61\x73\x74\x4d\x6f\x64\x69\x66\ \x69\x65\x64\x5b\x6b\x5d\x29\x2c\x66\x2e\x65\x74\x61\x67\x5b\x6b\ \x5d\x26\x26\x76\x2e\x73\x65\x74\x52\x65\x71\x75\x65\x73\x74\x48\ \x65\x61\x64\x65\x72\x28\x22\x49\x66\x2d\x4e\x6f\x6e\x65\x2d\x4d\ \x61\x74\x63\x68\x22\x2c\x66\x2e\x65\x74\x61\x67\x5b\x6b\x5d\x29\ \x29\x2c\x76\x2e\x73\x65\x74\x52\x65\x71\x75\x65\x73\x74\x48\x65\ \x61\x64\x65\x72\x28\x22\x41\x63\x63\x65\x70\x74\x22\x2c\x64\x2e\ \x64\x61\x74\x61\x54\x79\x70\x65\x73\x5b\x30\x5d\x26\x26\x64\x2e\ \x61\x63\x63\x65\x70\x74\x73\x5b\x64\x2e\x64\x61\x74\x61\x54\x79\ \x70\x65\x73\x5b\x30\x5d\x5d\x3f\x64\x2e\x61\x63\x63\x65\x70\x74\ \x73\x5b\x64\x2e\x64\x61\x74\x61\x54\x79\x70\x65\x73\x5b\x30\x5d\ \x5d\x2b\x28\x64\x2e\x64\x61\x74\x61\x54\x79\x70\x65\x73\x5b\x30\ \x5d\x21\x3d\x3d\x22\x2a\x22\x3f\x22\x2c\x20\x22\x2b\x62\x58\x2b\ \x22\x3b\x20\x71\x3d\x30\x2e\x30\x31\x22\x3a\x22\x22\x29\x3a\x64\ \x2e\x61\x63\x63\x65\x70\x74\x73\x5b\x22\x2a\x22\x5d\x29\x3b\x66\ \x6f\x72\x28\x75\x20\x69\x6e\x20\x64\x2e\x68\x65\x61\x64\x65\x72\ \x73\x29\x76\x2e\x73\x65\x74\x52\x65\x71\x75\x65\x73\x74\x48\x65\ \x61\x64\x65\x72\x28\x75\x2c\x64\x2e\x68\x65\x61\x64\x65\x72\x73\ \x5b\x75\x5d\x29\x3b\x69\x66\x28\x64\x2e\x62\x65\x66\x6f\x72\x65\ \x53\x65\x6e\x64\x26\x26\x28\x64\x2e\x62\x65\x66\x6f\x72\x65\x53\ \x65\x6e\x64\x2e\x63\x61\x6c\x6c\x28\x65\x2c\x76\x2c\x64\x29\x3d\ \x3d\x3d\x21\x31\x7c\x7c\x73\x3d\x3d\x3d\x32\x29\x29\x7b\x76\x2e\ \x61\x62\x6f\x72\x74\x28\x29\x3b\x72\x65\x74\x75\x72\x6e\x21\x31\ \x7d\x66\x6f\x72\x28\x75\x20\x69\x6e\x7b\x73\x75\x63\x63\x65\x73\ \x73\x3a\x31\x2c\x65\x72\x72\x6f\x72\x3a\x31\x2c\x63\x6f\x6d\x70\ \x6c\x65\x74\x65\x3a\x31\x7d\x29\x76\x5b\x75\x5d\x28\x64\x5b\x75\ \x5d\x29\x3b\x70\x3d\x62\x24\x28\x62\x55\x2c\x64\x2c\x63\x2c\x76\ \x29\x3b\x69\x66\x28\x21\x70\x29\x77\x28\x2d\x31\x2c\x22\x4e\x6f\ \x20\x54\x72\x61\x6e\x73\x70\x6f\x72\x74\x22\x29\x3b\x65\x6c\x73\ \x65\x7b\x76\x2e\x72\x65\x61\x64\x79\x53\x74\x61\x74\x65\x3d\x31\ \x2c\x74\x26\x26\x67\x2e\x74\x72\x69\x67\x67\x65\x72\x28\x22\x61\ \x6a\x61\x78\x53\x65\x6e\x64\x22\x2c\x5b\x76\x2c\x64\x5d\x29\x2c\ \x64\x2e\x61\x73\x79\x6e\x63\x26\x26\x64\x2e\x74\x69\x6d\x65\x6f\ \x75\x74\x3e\x30\x26\x26\x28\x71\x3d\x73\x65\x74\x54\x69\x6d\x65\ \x6f\x75\x74\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x76\ \x2e\x61\x62\x6f\x72\x74\x28\x22\x74\x69\x6d\x65\x6f\x75\x74\x22\ \x29\x7d\x2c\x64\x2e\x74\x69\x6d\x65\x6f\x75\x74\x29\x29\x3b\x74\ \x72\x79\x7b\x73\x3d\x31\x2c\x70\x2e\x73\x65\x6e\x64\x28\x6c\x2c\ \x77\x29\x7d\x63\x61\x74\x63\x68\x28\x7a\x29\x7b\x69\x66\x28\x73\ \x3c\x32\x29\x77\x28\x2d\x31\x2c\x7a\x29\x3b\x65\x6c\x73\x65\x20\ \x74\x68\x72\x6f\x77\x20\x7a\x7d\x7d\x72\x65\x74\x75\x72\x6e\x20\ \x76\x7d\x2c\x70\x61\x72\x61\x6d\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x5b\x5d\x2c\ \x65\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\ \x62\x3d\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\ \x29\x3f\x62\x28\x29\x3a\x62\x2c\x64\x5b\x64\x2e\x6c\x65\x6e\x67\ \x74\x68\x5d\x3d\x65\x6e\x63\x6f\x64\x65\x55\x52\x49\x43\x6f\x6d\ \x70\x6f\x6e\x65\x6e\x74\x28\x61\x29\x2b\x22\x3d\x22\x2b\x65\x6e\ \x63\x6f\x64\x65\x55\x52\x49\x43\x6f\x6d\x70\x6f\x6e\x65\x6e\x74\ \x28\x62\x29\x7d\x3b\x63\x3d\x3d\x3d\x62\x26\x26\x28\x63\x3d\x66\ \x2e\x61\x6a\x61\x78\x53\x65\x74\x74\x69\x6e\x67\x73\x2e\x74\x72\ \x61\x64\x69\x74\x69\x6f\x6e\x61\x6c\x29\x3b\x69\x66\x28\x66\x2e\ \x69\x73\x41\x72\x72\x61\x79\x28\x61\x29\x7c\x7c\x61\x2e\x6a\x71\ \x75\x65\x72\x79\x26\x26\x21\x66\x2e\x69\x73\x50\x6c\x61\x69\x6e\ \x4f\x62\x6a\x65\x63\x74\x28\x61\x29\x29\x66\x2e\x65\x61\x63\x68\ \x28\x61\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x65\x28\ \x74\x68\x69\x73\x2e\x6e\x61\x6d\x65\x2c\x74\x68\x69\x73\x2e\x76\ \x61\x6c\x75\x65\x29\x7d\x29\x3b\x65\x6c\x73\x65\x20\x66\x6f\x72\ \x28\x76\x61\x72\x20\x67\x20\x69\x6e\x20\x61\x29\x63\x61\x28\x67\ \x2c\x61\x5b\x67\x5d\x2c\x63\x2c\x65\x29\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x64\x2e\x6a\x6f\x69\x6e\x28\x22\x26\x22\x29\x2e\x72\x65\ \x70\x6c\x61\x63\x65\x28\x62\x44\x2c\x22\x2b\x22\x29\x7d\x7d\x29\ \x2c\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x61\x63\x74\x69\x76\ \x65\x3a\x30\x2c\x6c\x61\x73\x74\x4d\x6f\x64\x69\x66\x69\x65\x64\ \x3a\x7b\x7d\x2c\x65\x74\x61\x67\x3a\x7b\x7d\x7d\x29\x3b\x76\x61\ \x72\x20\x63\x64\x3d\x66\x2e\x6e\x6f\x77\x28\x29\x2c\x63\x65\x3d\ \x2f\x28\x5c\x3d\x29\x5c\x3f\x28\x26\x7c\x24\x29\x7c\x5c\x3f\x5c\ \x3f\x2f\x69\x3b\x66\x2e\x61\x6a\x61\x78\x53\x65\x74\x75\x70\x28\ \x7b\x6a\x73\x6f\x6e\x70\x3a\x22\x63\x61\x6c\x6c\x62\x61\x63\x6b\ \x22\x2c\x6a\x73\x6f\x6e\x70\x43\x61\x6c\x6c\x62\x61\x63\x6b\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\ \x6e\x20\x66\x2e\x65\x78\x70\x61\x6e\x64\x6f\x2b\x22\x5f\x22\x2b\ \x63\x64\x2b\x2b\x7d\x7d\x29\x2c\x66\x2e\x61\x6a\x61\x78\x50\x72\ \x65\x66\x69\x6c\x74\x65\x72\x28\x22\x6a\x73\x6f\x6e\x20\x6a\x73\ \x6f\x6e\x70\x22\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x2c\ \x63\x2c\x64\x29\x7b\x76\x61\x72\x20\x65\x3d\x62\x2e\x63\x6f\x6e\ \x74\x65\x6e\x74\x54\x79\x70\x65\x3d\x3d\x3d\x22\x61\x70\x70\x6c\ \x69\x63\x61\x74\x69\x6f\x6e\x2f\x78\x2d\x77\x77\x77\x2d\x66\x6f\ \x72\x6d\x2d\x75\x72\x6c\x65\x6e\x63\x6f\x64\x65\x64\x22\x26\x26\ \x74\x79\x70\x65\x6f\x66\x20\x62\x2e\x64\x61\x74\x61\x3d\x3d\x22\ \x73\x74\x72\x69\x6e\x67\x22\x3b\x69\x66\x28\x62\x2e\x64\x61\x74\ \x61\x54\x79\x70\x65\x73\x5b\x30\x5d\x3d\x3d\x3d\x22\x6a\x73\x6f\ \x6e\x70\x22\x7c\x7c\x62\x2e\x6a\x73\x6f\x6e\x70\x21\x3d\x3d\x21\ \x31\x26\x26\x28\x63\x65\x2e\x74\x65\x73\x74\x28\x62\x2e\x75\x72\ \x6c\x29\x7c\x7c\x65\x26\x26\x63\x65\x2e\x74\x65\x73\x74\x28\x62\ \x2e\x64\x61\x74\x61\x29\x29\x29\x7b\x76\x61\x72\x20\x67\x2c\x68\ \x3d\x62\x2e\x6a\x73\x6f\x6e\x70\x43\x61\x6c\x6c\x62\x61\x63\x6b\ \x3d\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x2e\ \x6a\x73\x6f\x6e\x70\x43\x61\x6c\x6c\x62\x61\x63\x6b\x29\x3f\x62\ \x2e\x6a\x73\x6f\x6e\x70\x43\x61\x6c\x6c\x62\x61\x63\x6b\x28\x29\ \x3a\x62\x2e\x6a\x73\x6f\x6e\x70\x43\x61\x6c\x6c\x62\x61\x63\x6b\ \x2c\x69\x3d\x61\x5b\x68\x5d\x2c\x6a\x3d\x62\x2e\x75\x72\x6c\x2c\ \x6b\x3d\x62\x2e\x64\x61\x74\x61\x2c\x6c\x3d\x22\x24\x31\x22\x2b\ \x68\x2b\x22\x24\x32\x22\x3b\x62\x2e\x6a\x73\x6f\x6e\x70\x21\x3d\ \x3d\x21\x31\x26\x26\x28\x6a\x3d\x6a\x2e\x72\x65\x70\x6c\x61\x63\ \x65\x28\x63\x65\x2c\x6c\x29\x2c\x62\x2e\x75\x72\x6c\x3d\x3d\x3d\ \x6a\x26\x26\x28\x65\x26\x26\x28\x6b\x3d\x6b\x2e\x72\x65\x70\x6c\ \x61\x63\x65\x28\x63\x65\x2c\x6c\x29\x29\x2c\x62\x2e\x64\x61\x74\ \x61\x3d\x3d\x3d\x6b\x26\x26\x28\x6a\x2b\x3d\x28\x2f\x5c\x3f\x2f\ \x2e\x74\x65\x73\x74\x28\x6a\x29\x3f\x22\x26\x22\x3a\x22\x3f\x22\ \x29\x2b\x62\x2e\x6a\x73\x6f\x6e\x70\x2b\x22\x3d\x22\x2b\x68\x29\ \x29\x29\x2c\x62\x2e\x75\x72\x6c\x3d\x6a\x2c\x62\x2e\x64\x61\x74\ \x61\x3d\x6b\x2c\x61\x5b\x68\x5d\x3d\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x29\x7b\x67\x3d\x5b\x61\x5d\x7d\x2c\x64\x2e\x61\x6c\ \x77\x61\x79\x73\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\ \x61\x5b\x68\x5d\x3d\x69\x2c\x67\x26\x26\x66\x2e\x69\x73\x46\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x69\x29\x26\x26\x61\x5b\x68\x5d\x28\ \x67\x5b\x30\x5d\x29\x7d\x29\x2c\x62\x2e\x63\x6f\x6e\x76\x65\x72\ \x74\x65\x72\x73\x5b\x22\x73\x63\x72\x69\x70\x74\x20\x6a\x73\x6f\ \x6e\x22\x5d\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x67\ \x7c\x7c\x66\x2e\x65\x72\x72\x6f\x72\x28\x68\x2b\x22\x20\x77\x61\ \x73\x20\x6e\x6f\x74\x20\x63\x61\x6c\x6c\x65\x64\x22\x29\x3b\x72\ \x65\x74\x75\x72\x6e\x20\x67\x5b\x30\x5d\x7d\x2c\x62\x2e\x64\x61\ \x74\x61\x54\x79\x70\x65\x73\x5b\x30\x5d\x3d\x22\x6a\x73\x6f\x6e\ \x22\x3b\x72\x65\x74\x75\x72\x6e\x22\x73\x63\x72\x69\x70\x74\x22\ \x7d\x7d\x29\x2c\x66\x2e\x61\x6a\x61\x78\x53\x65\x74\x75\x70\x28\ \x7b\x61\x63\x63\x65\x70\x74\x73\x3a\x7b\x73\x63\x72\x69\x70\x74\ \x3a\x22\x74\x65\x78\x74\x2f\x6a\x61\x76\x61\x73\x63\x72\x69\x70\ \x74\x2c\x20\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\x2f\x6a\ \x61\x76\x61\x73\x63\x72\x69\x70\x74\x2c\x20\x61\x70\x70\x6c\x69\ \x63\x61\x74\x69\x6f\x6e\x2f\x65\x63\x6d\x61\x73\x63\x72\x69\x70\ \x74\x2c\x20\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\x2f\x78\ \x2d\x65\x63\x6d\x61\x73\x63\x72\x69\x70\x74\x22\x7d\x2c\x63\x6f\ \x6e\x74\x65\x6e\x74\x73\x3a\x7b\x73\x63\x72\x69\x70\x74\x3a\x2f\ \x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x7c\x65\x63\x6d\x61\x73\ \x63\x72\x69\x70\x74\x2f\x7d\x2c\x63\x6f\x6e\x76\x65\x72\x74\x65\ \x72\x73\x3a\x7b\x22\x74\x65\x78\x74\x20\x73\x63\x72\x69\x70\x74\ \x22\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x66\x2e\ \x67\x6c\x6f\x62\x61\x6c\x45\x76\x61\x6c\x28\x61\x29\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x61\x7d\x7d\x7d\x29\x2c\x66\x2e\x61\x6a\x61\ \x78\x50\x72\x65\x66\x69\x6c\x74\x65\x72\x28\x22\x73\x63\x72\x69\ \x70\x74\x22\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\ \x61\x2e\x63\x61\x63\x68\x65\x3d\x3d\x3d\x62\x26\x26\x28\x61\x2e\ \x63\x61\x63\x68\x65\x3d\x21\x31\x29\x2c\x61\x2e\x63\x72\x6f\x73\ \x73\x44\x6f\x6d\x61\x69\x6e\x26\x26\x28\x61\x2e\x74\x79\x70\x65\ \x3d\x22\x47\x45\x54\x22\x2c\x61\x2e\x67\x6c\x6f\x62\x61\x6c\x3d\ \x21\x31\x29\x7d\x29\x2c\x66\x2e\x61\x6a\x61\x78\x54\x72\x61\x6e\ \x73\x70\x6f\x72\x74\x28\x22\x73\x63\x72\x69\x70\x74\x22\x2c\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x69\x66\x28\x61\x2e\ \x63\x72\x6f\x73\x73\x44\x6f\x6d\x61\x69\x6e\x29\x7b\x76\x61\x72\ \x20\x64\x2c\x65\x3d\x63\x2e\x68\x65\x61\x64\x7c\x7c\x63\x2e\x67\ \x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\x67\x4e\ \x61\x6d\x65\x28\x22\x68\x65\x61\x64\x22\x29\x5b\x30\x5d\x7c\x7c\ \x63\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\ \x74\x3b\x72\x65\x74\x75\x72\x6e\x7b\x73\x65\x6e\x64\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x66\x2c\x67\x29\x7b\x64\x3d\x63\x2e\ \x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74\x28\x22\x73\ \x63\x72\x69\x70\x74\x22\x29\x2c\x64\x2e\x61\x73\x79\x6e\x63\x3d\ \x22\x61\x73\x79\x6e\x63\x22\x2c\x61\x2e\x73\x63\x72\x69\x70\x74\ \x43\x68\x61\x72\x73\x65\x74\x26\x26\x28\x64\x2e\x63\x68\x61\x72\ \x73\x65\x74\x3d\x61\x2e\x73\x63\x72\x69\x70\x74\x43\x68\x61\x72\ \x73\x65\x74\x29\x2c\x64\x2e\x73\x72\x63\x3d\x61\x2e\x75\x72\x6c\ \x2c\x64\x2e\x6f\x6e\x6c\x6f\x61\x64\x3d\x64\x2e\x6f\x6e\x72\x65\ \x61\x64\x79\x73\x74\x61\x74\x65\x63\x68\x61\x6e\x67\x65\x3d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x69\x66\x28\ \x63\x7c\x7c\x21\x64\x2e\x72\x65\x61\x64\x79\x53\x74\x61\x74\x65\ \x7c\x7c\x2f\x6c\x6f\x61\x64\x65\x64\x7c\x63\x6f\x6d\x70\x6c\x65\ \x74\x65\x2f\x2e\x74\x65\x73\x74\x28\x64\x2e\x72\x65\x61\x64\x79\ \x53\x74\x61\x74\x65\x29\x29\x64\x2e\x6f\x6e\x6c\x6f\x61\x64\x3d\ \x64\x2e\x6f\x6e\x72\x65\x61\x64\x79\x73\x74\x61\x74\x65\x63\x68\ \x61\x6e\x67\x65\x3d\x6e\x75\x6c\x6c\x2c\x65\x26\x26\x64\x2e\x70\ \x61\x72\x65\x6e\x74\x4e\x6f\x64\x65\x26\x26\x65\x2e\x72\x65\x6d\ \x6f\x76\x65\x43\x68\x69\x6c\x64\x28\x64\x29\x2c\x64\x3d\x62\x2c\ \x63\x7c\x7c\x67\x28\x32\x30\x30\x2c\x22\x73\x75\x63\x63\x65\x73\ \x73\x22\x29\x7d\x2c\x65\x2e\x69\x6e\x73\x65\x72\x74\x42\x65\x66\ \x6f\x72\x65\x28\x64\x2c\x65\x2e\x66\x69\x72\x73\x74\x43\x68\x69\ \x6c\x64\x29\x7d\x2c\x61\x62\x6f\x72\x74\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x64\x26\x26\x64\x2e\x6f\x6e\x6c\x6f\x61\ \x64\x28\x30\x2c\x31\x29\x7d\x7d\x7d\x7d\x29\x3b\x76\x61\x72\x20\ \x63\x66\x3d\x61\x2e\x41\x63\x74\x69\x76\x65\x58\x4f\x62\x6a\x65\ \x63\x74\x3f\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\x6f\ \x72\x28\x76\x61\x72\x20\x61\x20\x69\x6e\x20\x63\x68\x29\x63\x68\ \x5b\x61\x5d\x28\x30\x2c\x31\x29\x7d\x3a\x21\x31\x2c\x63\x67\x3d\ \x30\x2c\x63\x68\x3b\x66\x2e\x61\x6a\x61\x78\x53\x65\x74\x74\x69\ \x6e\x67\x73\x2e\x78\x68\x72\x3d\x61\x2e\x41\x63\x74\x69\x76\x65\ \x58\x4f\x62\x6a\x65\x63\x74\x3f\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x21\x74\x68\x69\x73\x2e\x69\ \x73\x4c\x6f\x63\x61\x6c\x26\x26\x63\x69\x28\x29\x7c\x7c\x63\x6a\ \x28\x29\x7d\x3a\x63\x69\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x29\x7b\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x66\x2e\x73\x75\ \x70\x70\x6f\x72\x74\x2c\x7b\x61\x6a\x61\x78\x3a\x21\x21\x61\x2c\ \x63\x6f\x72\x73\x3a\x21\x21\x61\x26\x26\x22\x77\x69\x74\x68\x43\ \x72\x65\x64\x65\x6e\x74\x69\x61\x6c\x73\x22\x69\x6e\x20\x61\x7d\ \x29\x7d\x28\x66\x2e\x61\x6a\x61\x78\x53\x65\x74\x74\x69\x6e\x67\ \x73\x2e\x78\x68\x72\x28\x29\x29\x2c\x66\x2e\x73\x75\x70\x70\x6f\ \x72\x74\x2e\x61\x6a\x61\x78\x26\x26\x66\x2e\x61\x6a\x61\x78\x54\ \x72\x61\x6e\x73\x70\x6f\x72\x74\x28\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x63\x29\x7b\x69\x66\x28\x21\x63\x2e\x63\x72\x6f\x73\x73\ \x44\x6f\x6d\x61\x69\x6e\x7c\x7c\x66\x2e\x73\x75\x70\x70\x6f\x72\ \x74\x2e\x63\x6f\x72\x73\x29\x7b\x76\x61\x72\x20\x64\x3b\x72\x65\ \x74\x75\x72\x6e\x7b\x73\x65\x6e\x64\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x65\x2c\x67\x29\x7b\x76\x61\x72\x20\x68\x3d\x63\x2e\ \x78\x68\x72\x28\x29\x2c\x69\x2c\x6a\x3b\x63\x2e\x75\x73\x65\x72\ \x6e\x61\x6d\x65\x3f\x68\x2e\x6f\x70\x65\x6e\x28\x63\x2e\x74\x79\ \x70\x65\x2c\x63\x2e\x75\x72\x6c\x2c\x63\x2e\x61\x73\x79\x6e\x63\ \x2c\x63\x2e\x75\x73\x65\x72\x6e\x61\x6d\x65\x2c\x63\x2e\x70\x61\ \x73\x73\x77\x6f\x72\x64\x29\x3a\x68\x2e\x6f\x70\x65\x6e\x28\x63\ \x2e\x74\x79\x70\x65\x2c\x63\x2e\x75\x72\x6c\x2c\x63\x2e\x61\x73\ \x79\x6e\x63\x29\x3b\x69\x66\x28\x63\x2e\x78\x68\x72\x46\x69\x65\ \x6c\x64\x73\x29\x66\x6f\x72\x28\x6a\x20\x69\x6e\x20\x63\x2e\x78\ \x68\x72\x46\x69\x65\x6c\x64\x73\x29\x68\x5b\x6a\x5d\x3d\x63\x2e\ \x78\x68\x72\x46\x69\x65\x6c\x64\x73\x5b\x6a\x5d\x3b\x63\x2e\x6d\ \x69\x6d\x65\x54\x79\x70\x65\x26\x26\x68\x2e\x6f\x76\x65\x72\x72\ \x69\x64\x65\x4d\x69\x6d\x65\x54\x79\x70\x65\x26\x26\x68\x2e\x6f\ \x76\x65\x72\x72\x69\x64\x65\x4d\x69\x6d\x65\x54\x79\x70\x65\x28\ \x63\x2e\x6d\x69\x6d\x65\x54\x79\x70\x65\x29\x2c\x21\x63\x2e\x63\ \x72\x6f\x73\x73\x44\x6f\x6d\x61\x69\x6e\x26\x26\x21\x65\x5b\x22\ \x58\x2d\x52\x65\x71\x75\x65\x73\x74\x65\x64\x2d\x57\x69\x74\x68\ \x22\x5d\x26\x26\x28\x65\x5b\x22\x58\x2d\x52\x65\x71\x75\x65\x73\ \x74\x65\x64\x2d\x57\x69\x74\x68\x22\x5d\x3d\x22\x58\x4d\x4c\x48\ \x74\x74\x70\x52\x65\x71\x75\x65\x73\x74\x22\x29\x3b\x74\x72\x79\ \x7b\x66\x6f\x72\x28\x6a\x20\x69\x6e\x20\x65\x29\x68\x2e\x73\x65\ \x74\x52\x65\x71\x75\x65\x73\x74\x48\x65\x61\x64\x65\x72\x28\x6a\ \x2c\x65\x5b\x6a\x5d\x29\x7d\x63\x61\x74\x63\x68\x28\x6b\x29\x7b\ \x7d\x68\x2e\x73\x65\x6e\x64\x28\x63\x2e\x68\x61\x73\x43\x6f\x6e\ \x74\x65\x6e\x74\x26\x26\x63\x2e\x64\x61\x74\x61\x7c\x7c\x6e\x75\ \x6c\x6c\x29\x2c\x64\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x65\x29\x7b\x76\x61\x72\x20\x6a\x2c\x6b\x2c\x6c\x2c\x6d\x2c\ \x6e\x3b\x74\x72\x79\x7b\x69\x66\x28\x64\x26\x26\x28\x65\x7c\x7c\ \x68\x2e\x72\x65\x61\x64\x79\x53\x74\x61\x74\x65\x3d\x3d\x3d\x34\ \x29\x29\x7b\x64\x3d\x62\x2c\x69\x26\x26\x28\x68\x2e\x6f\x6e\x72\ \x65\x61\x64\x79\x73\x74\x61\x74\x65\x63\x68\x61\x6e\x67\x65\x3d\ \x66\x2e\x6e\x6f\x6f\x70\x2c\x63\x66\x26\x26\x64\x65\x6c\x65\x74\ \x65\x20\x63\x68\x5b\x69\x5d\x29\x3b\x69\x66\x28\x65\x29\x68\x2e\ \x72\x65\x61\x64\x79\x53\x74\x61\x74\x65\x21\x3d\x3d\x34\x26\x26\ \x68\x2e\x61\x62\x6f\x72\x74\x28\x29\x3b\x65\x6c\x73\x65\x7b\x6a\ \x3d\x68\x2e\x73\x74\x61\x74\x75\x73\x2c\x6c\x3d\x68\x2e\x67\x65\ \x74\x41\x6c\x6c\x52\x65\x73\x70\x6f\x6e\x73\x65\x48\x65\x61\x64\ \x65\x72\x73\x28\x29\x2c\x6d\x3d\x7b\x7d\x2c\x6e\x3d\x68\x2e\x72\ \x65\x73\x70\x6f\x6e\x73\x65\x58\x4d\x4c\x2c\x6e\x26\x26\x6e\x2e\ \x64\x6f\x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x26\ \x26\x28\x6d\x2e\x78\x6d\x6c\x3d\x6e\x29\x2c\x6d\x2e\x74\x65\x78\ \x74\x3d\x68\x2e\x72\x65\x73\x70\x6f\x6e\x73\x65\x54\x65\x78\x74\ \x3b\x74\x72\x79\x7b\x6b\x3d\x68\x2e\x73\x74\x61\x74\x75\x73\x54\ \x65\x78\x74\x7d\x63\x61\x74\x63\x68\x28\x6f\x29\x7b\x6b\x3d\x22\ \x22\x7d\x21\x6a\x26\x26\x63\x2e\x69\x73\x4c\x6f\x63\x61\x6c\x26\ \x26\x21\x63\x2e\x63\x72\x6f\x73\x73\x44\x6f\x6d\x61\x69\x6e\x3f\ \x6a\x3d\x6d\x2e\x74\x65\x78\x74\x3f\x32\x30\x30\x3a\x34\x30\x34\ \x3a\x6a\x3d\x3d\x3d\x31\x32\x32\x33\x26\x26\x28\x6a\x3d\x32\x30\ \x34\x29\x7d\x7d\x7d\x63\x61\x74\x63\x68\x28\x70\x29\x7b\x65\x7c\ \x7c\x67\x28\x2d\x31\x2c\x70\x29\x7d\x6d\x26\x26\x67\x28\x6a\x2c\ \x6b\x2c\x6d\x2c\x6c\x29\x7d\x2c\x21\x63\x2e\x61\x73\x79\x6e\x63\ \x7c\x7c\x68\x2e\x72\x65\x61\x64\x79\x53\x74\x61\x74\x65\x3d\x3d\ \x3d\x34\x3f\x64\x28\x29\x3a\x28\x69\x3d\x2b\x2b\x63\x67\x2c\x63\ \x66\x26\x26\x28\x63\x68\x7c\x7c\x28\x63\x68\x3d\x7b\x7d\x2c\x66\ \x28\x61\x29\x2e\x75\x6e\x6c\x6f\x61\x64\x28\x63\x66\x29\x29\x2c\ \x63\x68\x5b\x69\x5d\x3d\x64\x29\x2c\x68\x2e\x6f\x6e\x72\x65\x61\ \x64\x79\x73\x74\x61\x74\x65\x63\x68\x61\x6e\x67\x65\x3d\x64\x29\ \x7d\x2c\x61\x62\x6f\x72\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x64\x26\x26\x64\x28\x30\x2c\x31\x29\x7d\x7d\x7d\x7d\ \x29\x3b\x76\x61\x72\x20\x63\x6b\x3d\x7b\x7d\x2c\x63\x6c\x2c\x63\ \x6d\x2c\x63\x6e\x3d\x2f\x5e\x28\x3f\x3a\x74\x6f\x67\x67\x6c\x65\ \x7c\x73\x68\x6f\x77\x7c\x68\x69\x64\x65\x29\x24\x2f\x2c\x63\x6f\ \x3d\x2f\x5e\x28\x5b\x2b\x5c\x2d\x5d\x3d\x29\x3f\x28\x5b\x5c\x64\ \x2b\x2e\x5c\x2d\x5d\x2b\x29\x28\x5b\x61\x2d\x7a\x25\x5d\x2a\x29\ \x24\x2f\x69\x2c\x63\x70\x2c\x63\x71\x3d\x5b\x5b\x22\x68\x65\x69\ \x67\x68\x74\x22\x2c\x22\x6d\x61\x72\x67\x69\x6e\x54\x6f\x70\x22\ \x2c\x22\x6d\x61\x72\x67\x69\x6e\x42\x6f\x74\x74\x6f\x6d\x22\x2c\ \x22\x70\x61\x64\x64\x69\x6e\x67\x54\x6f\x70\x22\x2c\x22\x70\x61\ \x64\x64\x69\x6e\x67\x42\x6f\x74\x74\x6f\x6d\x22\x5d\x2c\x5b\x22\ \x77\x69\x64\x74\x68\x22\x2c\x22\x6d\x61\x72\x67\x69\x6e\x4c\x65\ \x66\x74\x22\x2c\x22\x6d\x61\x72\x67\x69\x6e\x52\x69\x67\x68\x74\ \x22\x2c\x22\x70\x61\x64\x64\x69\x6e\x67\x4c\x65\x66\x74\x22\x2c\ \x22\x70\x61\x64\x64\x69\x6e\x67\x52\x69\x67\x68\x74\x22\x5d\x2c\ \x5b\x22\x6f\x70\x61\x63\x69\x74\x79\x22\x5d\x5d\x2c\x63\x72\x3b\ \x66\x2e\x66\x6e\x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x73\x68\x6f\ \x77\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\ \x29\x7b\x76\x61\x72\x20\x64\x2c\x65\x3b\x69\x66\x28\x61\x7c\x7c\ \x61\x3d\x3d\x3d\x30\x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\ \x73\x2e\x61\x6e\x69\x6d\x61\x74\x65\x28\x63\x75\x28\x22\x73\x68\ \x6f\x77\x22\x2c\x33\x29\x2c\x61\x2c\x62\x2c\x63\x29\x3b\x66\x6f\ \x72\x28\x76\x61\x72\x20\x67\x3d\x30\x2c\x68\x3d\x74\x68\x69\x73\ \x2e\x6c\x65\x6e\x67\x74\x68\x3b\x67\x3c\x68\x3b\x67\x2b\x2b\x29\ \x64\x3d\x74\x68\x69\x73\x5b\x67\x5d\x2c\x64\x2e\x73\x74\x79\x6c\ \x65\x26\x26\x28\x65\x3d\x64\x2e\x73\x74\x79\x6c\x65\x2e\x64\x69\ \x73\x70\x6c\x61\x79\x2c\x21\x66\x2e\x5f\x64\x61\x74\x61\x28\x64\ \x2c\x22\x6f\x6c\x64\x64\x69\x73\x70\x6c\x61\x79\x22\x29\x26\x26\ \x65\x3d\x3d\x3d\x22\x6e\x6f\x6e\x65\x22\x26\x26\x28\x65\x3d\x64\ \x2e\x73\x74\x79\x6c\x65\x2e\x64\x69\x73\x70\x6c\x61\x79\x3d\x22\ \x22\x29\x2c\x65\x3d\x3d\x3d\x22\x22\x26\x26\x66\x2e\x63\x73\x73\ \x28\x64\x2c\x22\x64\x69\x73\x70\x6c\x61\x79\x22\x29\x3d\x3d\x3d\ \x22\x6e\x6f\x6e\x65\x22\x26\x26\x66\x2e\x5f\x64\x61\x74\x61\x28\ \x64\x2c\x22\x6f\x6c\x64\x64\x69\x73\x70\x6c\x61\x79\x22\x2c\x63\ \x76\x28\x64\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x29\x29\x3b\ \x66\x6f\x72\x28\x67\x3d\x30\x3b\x67\x3c\x68\x3b\x67\x2b\x2b\x29\ \x7b\x64\x3d\x74\x68\x69\x73\x5b\x67\x5d\x3b\x69\x66\x28\x64\x2e\ \x73\x74\x79\x6c\x65\x29\x7b\x65\x3d\x64\x2e\x73\x74\x79\x6c\x65\ \x2e\x64\x69\x73\x70\x6c\x61\x79\x3b\x69\x66\x28\x65\x3d\x3d\x3d\ \x22\x22\x7c\x7c\x65\x3d\x3d\x3d\x22\x6e\x6f\x6e\x65\x22\x29\x64\ \x2e\x73\x74\x79\x6c\x65\x2e\x64\x69\x73\x70\x6c\x61\x79\x3d\x66\ \x2e\x5f\x64\x61\x74\x61\x28\x64\x2c\x22\x6f\x6c\x64\x64\x69\x73\ \x70\x6c\x61\x79\x22\x29\x7c\x7c\x22\x22\x7d\x7d\x72\x65\x74\x75\ \x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x68\x69\x64\x65\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x69\x66\ \x28\x61\x7c\x7c\x61\x3d\x3d\x3d\x30\x29\x72\x65\x74\x75\x72\x6e\ \x20\x74\x68\x69\x73\x2e\x61\x6e\x69\x6d\x61\x74\x65\x28\x63\x75\ \x28\x22\x68\x69\x64\x65\x22\x2c\x33\x29\x2c\x61\x2c\x62\x2c\x63\ \x29\x3b\x76\x61\x72\x20\x64\x2c\x65\x2c\x67\x3d\x30\x2c\x68\x3d\ \x74\x68\x69\x73\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x66\x6f\x72\x28\ \x3b\x67\x3c\x68\x3b\x67\x2b\x2b\x29\x64\x3d\x74\x68\x69\x73\x5b\ \x67\x5d\x2c\x64\x2e\x73\x74\x79\x6c\x65\x26\x26\x28\x65\x3d\x66\ \x2e\x63\x73\x73\x28\x64\x2c\x22\x64\x69\x73\x70\x6c\x61\x79\x22\ \x29\x2c\x65\x21\x3d\x3d\x22\x6e\x6f\x6e\x65\x22\x26\x26\x21\x66\ \x2e\x5f\x64\x61\x74\x61\x28\x64\x2c\x22\x6f\x6c\x64\x64\x69\x73\ \x70\x6c\x61\x79\x22\x29\x26\x26\x66\x2e\x5f\x64\x61\x74\x61\x28\ \x64\x2c\x22\x6f\x6c\x64\x64\x69\x73\x70\x6c\x61\x79\x22\x2c\x65\ \x29\x29\x3b\x66\x6f\x72\x28\x67\x3d\x30\x3b\x67\x3c\x68\x3b\x67\ \x2b\x2b\x29\x74\x68\x69\x73\x5b\x67\x5d\x2e\x73\x74\x79\x6c\x65\ \x26\x26\x28\x74\x68\x69\x73\x5b\x67\x5d\x2e\x73\x74\x79\x6c\x65\ \x2e\x64\x69\x73\x70\x6c\x61\x79\x3d\x22\x6e\x6f\x6e\x65\x22\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x7d\x2c\x5f\x74\ \x6f\x67\x67\x6c\x65\x3a\x66\x2e\x66\x6e\x2e\x74\x6f\x67\x67\x6c\ \x65\x2c\x74\x6f\x67\x67\x6c\x65\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x74\ \x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x62\x6f\x6f\x6c\x65\x61\ \x6e\x22\x3b\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x29\x26\x26\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x62\x29\x3f\x74\x68\x69\x73\x2e\x5f\x74\x6f\x67\x67\x6c\x65\ \x2e\x61\x70\x70\x6c\x79\x28\x74\x68\x69\x73\x2c\x61\x72\x67\x75\ \x6d\x65\x6e\x74\x73\x29\x3a\x61\x3d\x3d\x6e\x75\x6c\x6c\x7c\x7c\ \x64\x3f\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\x20\x62\x3d\x64\x3f\x61\ \x3a\x66\x28\x74\x68\x69\x73\x29\x2e\x69\x73\x28\x22\x3a\x68\x69\ \x64\x64\x65\x6e\x22\x29\x3b\x66\x28\x74\x68\x69\x73\x29\x5b\x62\ \x3f\x22\x73\x68\x6f\x77\x22\x3a\x22\x68\x69\x64\x65\x22\x5d\x28\ \x29\x7d\x29\x3a\x74\x68\x69\x73\x2e\x61\x6e\x69\x6d\x61\x74\x65\ \x28\x63\x75\x28\x22\x74\x6f\x67\x67\x6c\x65\x22\x2c\x33\x29\x2c\ \x61\x2c\x62\x2c\x63\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\ \x69\x73\x7d\x2c\x66\x61\x64\x65\x54\x6f\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\x7b\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x66\x69\x6c\x74\x65\x72\x28\ \x22\x3a\x68\x69\x64\x64\x65\x6e\x22\x29\x2e\x63\x73\x73\x28\x22\ \x6f\x70\x61\x63\x69\x74\x79\x22\x2c\x30\x29\x2e\x73\x68\x6f\x77\ \x28\x29\x2e\x65\x6e\x64\x28\x29\x2e\x61\x6e\x69\x6d\x61\x74\x65\ \x28\x7b\x6f\x70\x61\x63\x69\x74\x79\x3a\x62\x7d\x2c\x61\x2c\x63\ \x2c\x64\x29\x7d\x2c\x61\x6e\x69\x6d\x61\x74\x65\x3a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\x7b\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x20\x67\x28\x29\x7b\x65\x2e\x71\x75\ \x65\x75\x65\x3d\x3d\x3d\x21\x31\x26\x26\x66\x2e\x5f\x6d\x61\x72\ \x6b\x28\x74\x68\x69\x73\x29\x3b\x76\x61\x72\x20\x62\x3d\x66\x2e\ \x65\x78\x74\x65\x6e\x64\x28\x7b\x7d\x2c\x65\x29\x2c\x63\x3d\x74\ \x68\x69\x73\x2e\x6e\x6f\x64\x65\x54\x79\x70\x65\x3d\x3d\x3d\x31\ \x2c\x64\x3d\x63\x26\x26\x66\x28\x74\x68\x69\x73\x29\x2e\x69\x73\ \x28\x22\x3a\x68\x69\x64\x64\x65\x6e\x22\x29\x2c\x67\x2c\x68\x2c\ \x69\x2c\x6a\x2c\x6b\x2c\x6c\x2c\x6d\x2c\x6e\x2c\x6f\x3b\x62\x2e\ \x61\x6e\x69\x6d\x61\x74\x65\x64\x50\x72\x6f\x70\x65\x72\x74\x69\ \x65\x73\x3d\x7b\x7d\x3b\x66\x6f\x72\x28\x69\x20\x69\x6e\x20\x61\ \x29\x7b\x67\x3d\x66\x2e\x63\x61\x6d\x65\x6c\x43\x61\x73\x65\x28\ \x69\x29\x2c\x69\x21\x3d\x3d\x67\x26\x26\x28\x61\x5b\x67\x5d\x3d\ \x61\x5b\x69\x5d\x2c\x64\x65\x6c\x65\x74\x65\x20\x61\x5b\x69\x5d\ \x29\x2c\x68\x3d\x61\x5b\x67\x5d\x2c\x66\x2e\x69\x73\x41\x72\x72\ \x61\x79\x28\x68\x29\x3f\x28\x62\x2e\x61\x6e\x69\x6d\x61\x74\x65\ \x64\x50\x72\x6f\x70\x65\x72\x74\x69\x65\x73\x5b\x67\x5d\x3d\x68\ \x5b\x31\x5d\x2c\x68\x3d\x61\x5b\x67\x5d\x3d\x68\x5b\x30\x5d\x29\ \x3a\x62\x2e\x61\x6e\x69\x6d\x61\x74\x65\x64\x50\x72\x6f\x70\x65\ \x72\x74\x69\x65\x73\x5b\x67\x5d\x3d\x62\x2e\x73\x70\x65\x63\x69\ \x61\x6c\x45\x61\x73\x69\x6e\x67\x26\x26\x62\x2e\x73\x70\x65\x63\ \x69\x61\x6c\x45\x61\x73\x69\x6e\x67\x5b\x67\x5d\x7c\x7c\x62\x2e\ \x65\x61\x73\x69\x6e\x67\x7c\x7c\x22\x73\x77\x69\x6e\x67\x22\x3b\ \x69\x66\x28\x68\x3d\x3d\x3d\x22\x68\x69\x64\x65\x22\x26\x26\x64\ \x7c\x7c\x68\x3d\x3d\x3d\x22\x73\x68\x6f\x77\x22\x26\x26\x21\x64\ \x29\x72\x65\x74\x75\x72\x6e\x20\x62\x2e\x63\x6f\x6d\x70\x6c\x65\ \x74\x65\x2e\x63\x61\x6c\x6c\x28\x74\x68\x69\x73\x29\x3b\x63\x26\ \x26\x28\x67\x3d\x3d\x3d\x22\x68\x65\x69\x67\x68\x74\x22\x7c\x7c\ \x67\x3d\x3d\x3d\x22\x77\x69\x64\x74\x68\x22\x29\x26\x26\x28\x62\ \x2e\x6f\x76\x65\x72\x66\x6c\x6f\x77\x3d\x5b\x74\x68\x69\x73\x2e\ \x73\x74\x79\x6c\x65\x2e\x6f\x76\x65\x72\x66\x6c\x6f\x77\x2c\x74\ \x68\x69\x73\x2e\x73\x74\x79\x6c\x65\x2e\x6f\x76\x65\x72\x66\x6c\ \x6f\x77\x58\x2c\x74\x68\x69\x73\x2e\x73\x74\x79\x6c\x65\x2e\x6f\ \x76\x65\x72\x66\x6c\x6f\x77\x59\x5d\x2c\x66\x2e\x63\x73\x73\x28\ \x74\x68\x69\x73\x2c\x22\x64\x69\x73\x70\x6c\x61\x79\x22\x29\x3d\ \x3d\x3d\x22\x69\x6e\x6c\x69\x6e\x65\x22\x26\x26\x66\x2e\x63\x73\ \x73\x28\x74\x68\x69\x73\x2c\x22\x66\x6c\x6f\x61\x74\x22\x29\x3d\ \x3d\x3d\x22\x6e\x6f\x6e\x65\x22\x26\x26\x28\x21\x66\x2e\x73\x75\ \x70\x70\x6f\x72\x74\x2e\x69\x6e\x6c\x69\x6e\x65\x42\x6c\x6f\x63\ \x6b\x4e\x65\x65\x64\x73\x4c\x61\x79\x6f\x75\x74\x7c\x7c\x63\x76\ \x28\x74\x68\x69\x73\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x3d\ \x3d\x3d\x22\x69\x6e\x6c\x69\x6e\x65\x22\x3f\x74\x68\x69\x73\x2e\ \x73\x74\x79\x6c\x65\x2e\x64\x69\x73\x70\x6c\x61\x79\x3d\x22\x69\ \x6e\x6c\x69\x6e\x65\x2d\x62\x6c\x6f\x63\x6b\x22\x3a\x74\x68\x69\ \x73\x2e\x73\x74\x79\x6c\x65\x2e\x7a\x6f\x6f\x6d\x3d\x31\x29\x29\ \x7d\x62\x2e\x6f\x76\x65\x72\x66\x6c\x6f\x77\x21\x3d\x6e\x75\x6c\ \x6c\x26\x26\x28\x74\x68\x69\x73\x2e\x73\x74\x79\x6c\x65\x2e\x6f\ \x76\x65\x72\x66\x6c\x6f\x77\x3d\x22\x68\x69\x64\x64\x65\x6e\x22\ \x29\x3b\x66\x6f\x72\x28\x69\x20\x69\x6e\x20\x61\x29\x6a\x3d\x6e\ \x65\x77\x20\x66\x2e\x66\x78\x28\x74\x68\x69\x73\x2c\x62\x2c\x69\ \x29\x2c\x68\x3d\x61\x5b\x69\x5d\x2c\x63\x6e\x2e\x74\x65\x73\x74\ \x28\x68\x29\x3f\x28\x6f\x3d\x66\x2e\x5f\x64\x61\x74\x61\x28\x74\ \x68\x69\x73\x2c\x22\x74\x6f\x67\x67\x6c\x65\x22\x2b\x69\x29\x7c\ \x7c\x28\x68\x3d\x3d\x3d\x22\x74\x6f\x67\x67\x6c\x65\x22\x3f\x64\ \x3f\x22\x73\x68\x6f\x77\x22\x3a\x22\x68\x69\x64\x65\x22\x3a\x30\ \x29\x2c\x6f\x3f\x28\x66\x2e\x5f\x64\x61\x74\x61\x28\x74\x68\x69\ \x73\x2c\x22\x74\x6f\x67\x67\x6c\x65\x22\x2b\x69\x2c\x6f\x3d\x3d\ \x3d\x22\x73\x68\x6f\x77\x22\x3f\x22\x68\x69\x64\x65\x22\x3a\x22\ \x73\x68\x6f\x77\x22\x29\x2c\x6a\x5b\x6f\x5d\x28\x29\x29\x3a\x6a\ \x5b\x68\x5d\x28\x29\x29\x3a\x28\x6b\x3d\x63\x6f\x2e\x65\x78\x65\ \x63\x28\x68\x29\x2c\x6c\x3d\x6a\x2e\x63\x75\x72\x28\x29\x2c\x6b\ \x3f\x28\x6d\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\x6b\ \x5b\x32\x5d\x29\x2c\x6e\x3d\x6b\x5b\x33\x5d\x7c\x7c\x28\x66\x2e\ \x63\x73\x73\x4e\x75\x6d\x62\x65\x72\x5b\x69\x5d\x3f\x22\x22\x3a\ \x22\x70\x78\x22\x29\x2c\x6e\x21\x3d\x3d\x22\x70\x78\x22\x26\x26\ \x28\x66\x2e\x73\x74\x79\x6c\x65\x28\x74\x68\x69\x73\x2c\x69\x2c\ \x28\x6d\x7c\x7c\x31\x29\x2b\x6e\x29\x2c\x6c\x3d\x28\x6d\x7c\x7c\ \x31\x29\x2f\x6a\x2e\x63\x75\x72\x28\x29\x2a\x6c\x2c\x66\x2e\x73\ \x74\x79\x6c\x65\x28\x74\x68\x69\x73\x2c\x69\x2c\x6c\x2b\x6e\x29\ \x29\x2c\x6b\x5b\x31\x5d\x26\x26\x28\x6d\x3d\x28\x6b\x5b\x31\x5d\ \x3d\x3d\x3d\x22\x2d\x3d\x22\x3f\x2d\x31\x3a\x31\x29\x2a\x6d\x2b\ \x6c\x29\x2c\x6a\x2e\x63\x75\x73\x74\x6f\x6d\x28\x6c\x2c\x6d\x2c\ \x6e\x29\x29\x3a\x6a\x2e\x63\x75\x73\x74\x6f\x6d\x28\x6c\x2c\x68\ \x2c\x22\x22\x29\x29\x3b\x72\x65\x74\x75\x72\x6e\x21\x30\x7d\x76\ \x61\x72\x20\x65\x3d\x66\x2e\x73\x70\x65\x65\x64\x28\x62\x2c\x63\ \x2c\x64\x29\x3b\x69\x66\x28\x66\x2e\x69\x73\x45\x6d\x70\x74\x79\ \x4f\x62\x6a\x65\x63\x74\x28\x61\x29\x29\x72\x65\x74\x75\x72\x6e\ \x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x65\x2e\x63\x6f\x6d\ \x70\x6c\x65\x74\x65\x2c\x5b\x21\x31\x5d\x29\x3b\x61\x3d\x66\x2e\ \x65\x78\x74\x65\x6e\x64\x28\x7b\x7d\x2c\x61\x29\x3b\x72\x65\x74\ \x75\x72\x6e\x20\x65\x2e\x71\x75\x65\x75\x65\x3d\x3d\x3d\x21\x31\ \x3f\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x67\x29\x3a\x74\x68\ \x69\x73\x2e\x71\x75\x65\x75\x65\x28\x65\x2e\x71\x75\x65\x75\x65\ \x2c\x67\x29\x7d\x2c\x73\x74\x6f\x70\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x63\x2c\x64\x29\x7b\x74\x79\x70\x65\x6f\x66\ \x20\x61\x21\x3d\x22\x73\x74\x72\x69\x6e\x67\x22\x26\x26\x28\x64\ \x3d\x63\x2c\x63\x3d\x61\x2c\x61\x3d\x62\x29\x2c\x63\x26\x26\x61\ \x21\x3d\x3d\x21\x31\x26\x26\x74\x68\x69\x73\x2e\x71\x75\x65\x75\ \x65\x28\x61\x7c\x7c\x22\x66\x78\x22\x2c\x5b\x5d\x29\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\x28\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x20\x68\x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\ \x65\x3d\x62\x5b\x63\x5d\x3b\x66\x2e\x72\x65\x6d\x6f\x76\x65\x44\ \x61\x74\x61\x28\x61\x2c\x63\x2c\x21\x30\x29\x2c\x65\x2e\x73\x74\ \x6f\x70\x28\x64\x29\x7d\x76\x61\x72\x20\x62\x2c\x63\x3d\x21\x31\ \x2c\x65\x3d\x66\x2e\x74\x69\x6d\x65\x72\x73\x2c\x67\x3d\x66\x2e\ \x5f\x64\x61\x74\x61\x28\x74\x68\x69\x73\x29\x3b\x64\x7c\x7c\x66\ \x2e\x5f\x75\x6e\x6d\x61\x72\x6b\x28\x21\x30\x2c\x74\x68\x69\x73\ \x29\x3b\x69\x66\x28\x61\x3d\x3d\x6e\x75\x6c\x6c\x29\x66\x6f\x72\ \x28\x62\x20\x69\x6e\x20\x67\x29\x67\x5b\x62\x5d\x26\x26\x67\x5b\ \x62\x5d\x2e\x73\x74\x6f\x70\x26\x26\x62\x2e\x69\x6e\x64\x65\x78\ \x4f\x66\x28\x22\x2e\x72\x75\x6e\x22\x29\x3d\x3d\x3d\x62\x2e\x6c\ \x65\x6e\x67\x74\x68\x2d\x34\x26\x26\x68\x28\x74\x68\x69\x73\x2c\ \x67\x2c\x62\x29\x3b\x65\x6c\x73\x65\x20\x67\x5b\x62\x3d\x61\x2b\ \x22\x2e\x72\x75\x6e\x22\x5d\x26\x26\x67\x5b\x62\x5d\x2e\x73\x74\ \x6f\x70\x26\x26\x68\x28\x74\x68\x69\x73\x2c\x67\x2c\x62\x29\x3b\ \x66\x6f\x72\x28\x62\x3d\x65\x2e\x6c\x65\x6e\x67\x74\x68\x3b\x62\ \x2d\x2d\x3b\x29\x65\x5b\x62\x5d\x2e\x65\x6c\x65\x6d\x3d\x3d\x3d\ \x74\x68\x69\x73\x26\x26\x28\x61\x3d\x3d\x6e\x75\x6c\x6c\x7c\x7c\ \x65\x5b\x62\x5d\x2e\x71\x75\x65\x75\x65\x3d\x3d\x3d\x61\x29\x26\ \x26\x28\x64\x3f\x65\x5b\x62\x5d\x28\x21\x30\x29\x3a\x65\x5b\x62\ \x5d\x2e\x73\x61\x76\x65\x53\x74\x61\x74\x65\x28\x29\x2c\x63\x3d\ \x21\x30\x2c\x65\x2e\x73\x70\x6c\x69\x63\x65\x28\x62\x2c\x31\x29\ \x29\x3b\x28\x21\x64\x7c\x7c\x21\x63\x29\x26\x26\x66\x2e\x64\x65\ \x71\x75\x65\x75\x65\x28\x74\x68\x69\x73\x2c\x61\x29\x7d\x29\x7d\ \x7d\x29\x2c\x66\x2e\x65\x61\x63\x68\x28\x7b\x73\x6c\x69\x64\x65\ \x44\x6f\x77\x6e\x3a\x63\x75\x28\x22\x73\x68\x6f\x77\x22\x2c\x31\ \x29\x2c\x73\x6c\x69\x64\x65\x55\x70\x3a\x63\x75\x28\x22\x68\x69\ \x64\x65\x22\x2c\x31\x29\x2c\x73\x6c\x69\x64\x65\x54\x6f\x67\x67\ \x6c\x65\x3a\x63\x75\x28\x22\x74\x6f\x67\x67\x6c\x65\x22\x2c\x31\ \x29\x2c\x66\x61\x64\x65\x49\x6e\x3a\x7b\x6f\x70\x61\x63\x69\x74\ \x79\x3a\x22\x73\x68\x6f\x77\x22\x7d\x2c\x66\x61\x64\x65\x4f\x75\ \x74\x3a\x7b\x6f\x70\x61\x63\x69\x74\x79\x3a\x22\x68\x69\x64\x65\ \x22\x7d\x2c\x66\x61\x64\x65\x54\x6f\x67\x67\x6c\x65\x3a\x7b\x6f\ \x70\x61\x63\x69\x74\x79\x3a\x22\x74\x6f\x67\x67\x6c\x65\x22\x7d\ \x7d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\ \x66\x2e\x66\x6e\x5b\x61\x5d\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x2c\x63\x2c\x64\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\ \x68\x69\x73\x2e\x61\x6e\x69\x6d\x61\x74\x65\x28\x62\x2c\x61\x2c\ \x63\x2c\x64\x29\x7d\x7d\x29\x2c\x66\x2e\x65\x78\x74\x65\x6e\x64\ \x28\x7b\x73\x70\x65\x65\x64\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x61\x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x61\x26\ \x26\x74\x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x6f\x62\x6a\x65\ \x63\x74\x22\x3f\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\x7d\x2c\ \x61\x29\x3a\x7b\x63\x6f\x6d\x70\x6c\x65\x74\x65\x3a\x63\x7c\x7c\ \x21\x63\x26\x26\x62\x7c\x7c\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x26\x26\x61\x2c\x64\x75\x72\x61\x74\x69\ \x6f\x6e\x3a\x61\x2c\x65\x61\x73\x69\x6e\x67\x3a\x63\x26\x26\x62\ \x7c\x7c\x62\x26\x26\x21\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x62\x29\x26\x26\x62\x7d\x3b\x64\x2e\x64\x75\x72\x61\ \x74\x69\x6f\x6e\x3d\x66\x2e\x66\x78\x2e\x6f\x66\x66\x3f\x30\x3a\ \x74\x79\x70\x65\x6f\x66\x20\x64\x2e\x64\x75\x72\x61\x74\x69\x6f\ \x6e\x3d\x3d\x22\x6e\x75\x6d\x62\x65\x72\x22\x3f\x64\x2e\x64\x75\ \x72\x61\x74\x69\x6f\x6e\x3a\x64\x2e\x64\x75\x72\x61\x74\x69\x6f\ \x6e\x20\x69\x6e\x20\x66\x2e\x66\x78\x2e\x73\x70\x65\x65\x64\x73\ \x3f\x66\x2e\x66\x78\x2e\x73\x70\x65\x65\x64\x73\x5b\x64\x2e\x64\ \x75\x72\x61\x74\x69\x6f\x6e\x5d\x3a\x66\x2e\x66\x78\x2e\x73\x70\ \x65\x65\x64\x73\x2e\x5f\x64\x65\x66\x61\x75\x6c\x74\x3b\x69\x66\ \x28\x64\x2e\x71\x75\x65\x75\x65\x3d\x3d\x6e\x75\x6c\x6c\x7c\x7c\ \x64\x2e\x71\x75\x65\x75\x65\x3d\x3d\x3d\x21\x30\x29\x64\x2e\x71\ \x75\x65\x75\x65\x3d\x22\x66\x78\x22\x3b\x64\x2e\x6f\x6c\x64\x3d\ \x64\x2e\x63\x6f\x6d\x70\x6c\x65\x74\x65\x2c\x64\x2e\x63\x6f\x6d\ \x70\x6c\x65\x74\x65\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x29\x7b\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x64\ \x2e\x6f\x6c\x64\x29\x26\x26\x64\x2e\x6f\x6c\x64\x2e\x63\x61\x6c\ \x6c\x28\x74\x68\x69\x73\x29\x2c\x64\x2e\x71\x75\x65\x75\x65\x3f\ \x66\x2e\x64\x65\x71\x75\x65\x75\x65\x28\x74\x68\x69\x73\x2c\x64\ \x2e\x71\x75\x65\x75\x65\x29\x3a\x61\x21\x3d\x3d\x21\x31\x26\x26\ \x66\x2e\x5f\x75\x6e\x6d\x61\x72\x6b\x28\x74\x68\x69\x73\x29\x7d\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x64\x7d\x2c\x65\x61\x73\x69\x6e\ \x67\x3a\x7b\x6c\x69\x6e\x65\x61\x72\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\x29\x7b\x72\x65\x74\x75\ \x72\x6e\x20\x63\x2b\x64\x2a\x61\x7d\x2c\x73\x77\x69\x6e\x67\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x62\x2c\x63\x2c\x64\ \x29\x7b\x72\x65\x74\x75\x72\x6e\x28\x2d\x4d\x61\x74\x68\x2e\x63\ \x6f\x73\x28\x61\x2a\x4d\x61\x74\x68\x2e\x50\x49\x29\x2f\x32\x2b\ \x2e\x35\x29\x2a\x64\x2b\x63\x7d\x7d\x2c\x74\x69\x6d\x65\x72\x73\ \x3a\x5b\x5d\x2c\x66\x78\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x62\x2c\x63\x29\x7b\x74\x68\x69\x73\x2e\x6f\x70\x74\x69\ \x6f\x6e\x73\x3d\x62\x2c\x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\x3d\ \x61\x2c\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x3d\x63\x2c\x62\x2e\ \x6f\x72\x69\x67\x3d\x62\x2e\x6f\x72\x69\x67\x7c\x7c\x7b\x7d\x7d\ \x7d\x29\x2c\x66\x2e\x66\x78\x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\ \x65\x3d\x7b\x75\x70\x64\x61\x74\x65\x3a\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x28\x29\x7b\x74\x68\x69\x73\x2e\x6f\x70\x74\x69\x6f\x6e\ \x73\x2e\x73\x74\x65\x70\x26\x26\x74\x68\x69\x73\x2e\x6f\x70\x74\ \x69\x6f\x6e\x73\x2e\x73\x74\x65\x70\x2e\x63\x61\x6c\x6c\x28\x74\ \x68\x69\x73\x2e\x65\x6c\x65\x6d\x2c\x74\x68\x69\x73\x2e\x6e\x6f\ \x77\x2c\x74\x68\x69\x73\x29\x2c\x28\x66\x2e\x66\x78\x2e\x73\x74\ \x65\x70\x5b\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x5d\x7c\x7c\x66\ \x2e\x66\x78\x2e\x73\x74\x65\x70\x2e\x5f\x64\x65\x66\x61\x75\x6c\ \x74\x29\x28\x74\x68\x69\x73\x29\x7d\x2c\x63\x75\x72\x3a\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x69\x66\x28\x74\x68\x69\x73\ \x2e\x65\x6c\x65\x6d\x5b\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x5d\ \x21\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x21\x74\x68\x69\x73\x2e\x65\ \x6c\x65\x6d\x2e\x73\x74\x79\x6c\x65\x7c\x7c\x74\x68\x69\x73\x2e\ \x65\x6c\x65\x6d\x2e\x73\x74\x79\x6c\x65\x5b\x74\x68\x69\x73\x2e\ \x70\x72\x6f\x70\x5d\x3d\x3d\x6e\x75\x6c\x6c\x29\x29\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\x5b\x74\x68\ \x69\x73\x2e\x70\x72\x6f\x70\x5d\x3b\x76\x61\x72\x20\x61\x2c\x62\ \x3d\x66\x2e\x63\x73\x73\x28\x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\ \x2c\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x29\x3b\x72\x65\x74\x75\ \x72\x6e\x20\x69\x73\x4e\x61\x4e\x28\x61\x3d\x70\x61\x72\x73\x65\ \x46\x6c\x6f\x61\x74\x28\x62\x29\x29\x3f\x21\x62\x7c\x7c\x62\x3d\ \x3d\x3d\x22\x61\x75\x74\x6f\x22\x3f\x30\x3a\x62\x3a\x61\x7d\x2c\ \x63\x75\x73\x74\x6f\x6d\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x61\x2c\x63\x2c\x64\x29\x7b\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\ \x68\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x65\x2e\x73\x74\ \x65\x70\x28\x61\x29\x7d\x76\x61\x72\x20\x65\x3d\x74\x68\x69\x73\ \x2c\x67\x3d\x66\x2e\x66\x78\x3b\x74\x68\x69\x73\x2e\x73\x74\x61\ \x72\x74\x54\x69\x6d\x65\x3d\x63\x72\x7c\x7c\x63\x73\x28\x29\x2c\ \x74\x68\x69\x73\x2e\x65\x6e\x64\x3d\x63\x2c\x74\x68\x69\x73\x2e\ \x6e\x6f\x77\x3d\x74\x68\x69\x73\x2e\x73\x74\x61\x72\x74\x3d\x61\ \x2c\x74\x68\x69\x73\x2e\x70\x6f\x73\x3d\x74\x68\x69\x73\x2e\x73\ \x74\x61\x74\x65\x3d\x30\x2c\x74\x68\x69\x73\x2e\x75\x6e\x69\x74\ \x3d\x64\x7c\x7c\x74\x68\x69\x73\x2e\x75\x6e\x69\x74\x7c\x7c\x28\ \x66\x2e\x63\x73\x73\x4e\x75\x6d\x62\x65\x72\x5b\x74\x68\x69\x73\ \x2e\x70\x72\x6f\x70\x5d\x3f\x22\x22\x3a\x22\x70\x78\x22\x29\x2c\ \x68\x2e\x71\x75\x65\x75\x65\x3d\x74\x68\x69\x73\x2e\x6f\x70\x74\ \x69\x6f\x6e\x73\x2e\x71\x75\x65\x75\x65\x2c\x68\x2e\x65\x6c\x65\ \x6d\x3d\x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\x2c\x68\x2e\x73\x61\ \x76\x65\x53\x74\x61\x74\x65\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x29\x7b\x65\x2e\x6f\x70\x74\x69\x6f\x6e\x73\x2e\x68\x69\x64\ \x65\x26\x26\x66\x2e\x5f\x64\x61\x74\x61\x28\x65\x2e\x65\x6c\x65\ \x6d\x2c\x22\x66\x78\x73\x68\x6f\x77\x22\x2b\x65\x2e\x70\x72\x6f\ \x70\x29\x3d\x3d\x3d\x62\x26\x26\x66\x2e\x5f\x64\x61\x74\x61\x28\ \x65\x2e\x65\x6c\x65\x6d\x2c\x22\x66\x78\x73\x68\x6f\x77\x22\x2b\ \x65\x2e\x70\x72\x6f\x70\x2c\x65\x2e\x73\x74\x61\x72\x74\x29\x7d\ \x2c\x68\x28\x29\x26\x26\x66\x2e\x74\x69\x6d\x65\x72\x73\x2e\x70\ \x75\x73\x68\x28\x68\x29\x26\x26\x21\x63\x70\x26\x26\x28\x63\x70\ \x3d\x73\x65\x74\x49\x6e\x74\x65\x72\x76\x61\x6c\x28\x67\x2e\x74\ \x69\x63\x6b\x2c\x67\x2e\x69\x6e\x74\x65\x72\x76\x61\x6c\x29\x29\ \x7d\x2c\x73\x68\x6f\x77\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x76\x61\x72\x20\x61\x3d\x66\x2e\x5f\x64\x61\x74\x61\x28\ \x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\x2c\x22\x66\x78\x73\x68\x6f\ \x77\x22\x2b\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x29\x3b\x74\x68\ \x69\x73\x2e\x6f\x70\x74\x69\x6f\x6e\x73\x2e\x6f\x72\x69\x67\x5b\ \x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x5d\x3d\x61\x7c\x7c\x66\x2e\ \x73\x74\x79\x6c\x65\x28\x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\x2c\ \x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x29\x2c\x74\x68\x69\x73\x2e\ \x6f\x70\x74\x69\x6f\x6e\x73\x2e\x73\x68\x6f\x77\x3d\x21\x30\x2c\ \x61\x21\x3d\x3d\x62\x3f\x74\x68\x69\x73\x2e\x63\x75\x73\x74\x6f\ \x6d\x28\x74\x68\x69\x73\x2e\x63\x75\x72\x28\x29\x2c\x61\x29\x3a\ \x74\x68\x69\x73\x2e\x63\x75\x73\x74\x6f\x6d\x28\x74\x68\x69\x73\ \x2e\x70\x72\x6f\x70\x3d\x3d\x3d\x22\x77\x69\x64\x74\x68\x22\x7c\ \x7c\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x3d\x3d\x3d\x22\x68\x65\ \x69\x67\x68\x74\x22\x3f\x31\x3a\x30\x2c\x74\x68\x69\x73\x2e\x63\ \x75\x72\x28\x29\x29\x2c\x66\x28\x74\x68\x69\x73\x2e\x65\x6c\x65\ \x6d\x29\x2e\x73\x68\x6f\x77\x28\x29\x7d\x2c\x68\x69\x64\x65\x3a\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x74\x68\x69\x73\x2e\ \x6f\x70\x74\x69\x6f\x6e\x73\x2e\x6f\x72\x69\x67\x5b\x74\x68\x69\ \x73\x2e\x70\x72\x6f\x70\x5d\x3d\x66\x2e\x5f\x64\x61\x74\x61\x28\ \x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\x2c\x22\x66\x78\x73\x68\x6f\ \x77\x22\x2b\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x29\x7c\x7c\x66\ \x2e\x73\x74\x79\x6c\x65\x28\x74\x68\x69\x73\x2e\x65\x6c\x65\x6d\ \x2c\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x29\x2c\x74\x68\x69\x73\ \x2e\x6f\x70\x74\x69\x6f\x6e\x73\x2e\x68\x69\x64\x65\x3d\x21\x30\ \x2c\x74\x68\x69\x73\x2e\x63\x75\x73\x74\x6f\x6d\x28\x74\x68\x69\ \x73\x2e\x63\x75\x72\x28\x29\x2c\x30\x29\x7d\x2c\x73\x74\x65\x70\ \x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\ \x20\x62\x2c\x63\x2c\x64\x2c\x65\x3d\x63\x72\x7c\x7c\x63\x73\x28\ \x29\x2c\x67\x3d\x21\x30\x2c\x68\x3d\x74\x68\x69\x73\x2e\x65\x6c\ \x65\x6d\x2c\x69\x3d\x74\x68\x69\x73\x2e\x6f\x70\x74\x69\x6f\x6e\ \x73\x3b\x69\x66\x28\x61\x7c\x7c\x65\x3e\x3d\x69\x2e\x64\x75\x72\ \x61\x74\x69\x6f\x6e\x2b\x74\x68\x69\x73\x2e\x73\x74\x61\x72\x74\ \x54\x69\x6d\x65\x29\x7b\x74\x68\x69\x73\x2e\x6e\x6f\x77\x3d\x74\ \x68\x69\x73\x2e\x65\x6e\x64\x2c\x74\x68\x69\x73\x2e\x70\x6f\x73\ \x3d\x74\x68\x69\x73\x2e\x73\x74\x61\x74\x65\x3d\x31\x2c\x74\x68\ \x69\x73\x2e\x75\x70\x64\x61\x74\x65\x28\x29\x2c\x69\x2e\x61\x6e\ \x69\x6d\x61\x74\x65\x64\x50\x72\x6f\x70\x65\x72\x74\x69\x65\x73\ \x5b\x74\x68\x69\x73\x2e\x70\x72\x6f\x70\x5d\x3d\x21\x30\x3b\x66\ \x6f\x72\x28\x62\x20\x69\x6e\x20\x69\x2e\x61\x6e\x69\x6d\x61\x74\ \x65\x64\x50\x72\x6f\x70\x65\x72\x74\x69\x65\x73\x29\x69\x2e\x61\ \x6e\x69\x6d\x61\x74\x65\x64\x50\x72\x6f\x70\x65\x72\x74\x69\x65\ \x73\x5b\x62\x5d\x21\x3d\x3d\x21\x30\x26\x26\x28\x67\x3d\x21\x31\ \x29\x3b\x69\x66\x28\x67\x29\x7b\x69\x2e\x6f\x76\x65\x72\x66\x6c\ \x6f\x77\x21\x3d\x6e\x75\x6c\x6c\x26\x26\x21\x66\x2e\x73\x75\x70\ \x70\x6f\x72\x74\x2e\x73\x68\x72\x69\x6e\x6b\x57\x72\x61\x70\x42\ \x6c\x6f\x63\x6b\x73\x26\x26\x66\x2e\x65\x61\x63\x68\x28\x5b\x22\ \x22\x2c\x22\x58\x22\x2c\x22\x59\x22\x5d\x2c\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x2c\x62\x29\x7b\x68\x2e\x73\x74\x79\x6c\x65\ \x5b\x22\x6f\x76\x65\x72\x66\x6c\x6f\x77\x22\x2b\x62\x5d\x3d\x69\ \x2e\x6f\x76\x65\x72\x66\x6c\x6f\x77\x5b\x61\x5d\x7d\x29\x2c\x69\ \x2e\x68\x69\x64\x65\x26\x26\x66\x28\x68\x29\x2e\x68\x69\x64\x65\ \x28\x29\x3b\x69\x66\x28\x69\x2e\x68\x69\x64\x65\x7c\x7c\x69\x2e\ \x73\x68\x6f\x77\x29\x66\x6f\x72\x28\x62\x20\x69\x6e\x20\x69\x2e\ \x61\x6e\x69\x6d\x61\x74\x65\x64\x50\x72\x6f\x70\x65\x72\x74\x69\ \x65\x73\x29\x66\x2e\x73\x74\x79\x6c\x65\x28\x68\x2c\x62\x2c\x69\ \x2e\x6f\x72\x69\x67\x5b\x62\x5d\x29\x2c\x66\x2e\x72\x65\x6d\x6f\ \x76\x65\x44\x61\x74\x61\x28\x68\x2c\x22\x66\x78\x73\x68\x6f\x77\ \x22\x2b\x62\x2c\x21\x30\x29\x2c\x66\x2e\x72\x65\x6d\x6f\x76\x65\ \x44\x61\x74\x61\x28\x68\x2c\x22\x74\x6f\x67\x67\x6c\x65\x22\x2b\ \x62\x2c\x21\x30\x29\x3b\x64\x3d\x69\x2e\x63\x6f\x6d\x70\x6c\x65\ \x74\x65\x2c\x64\x26\x26\x28\x69\x2e\x63\x6f\x6d\x70\x6c\x65\x74\ \x65\x3d\x21\x31\x2c\x64\x2e\x63\x61\x6c\x6c\x28\x68\x29\x29\x7d\ \x72\x65\x74\x75\x72\x6e\x21\x31\x7d\x69\x2e\x64\x75\x72\x61\x74\ \x69\x6f\x6e\x3d\x3d\x49\x6e\x66\x69\x6e\x69\x74\x79\x3f\x74\x68\ \x69\x73\x2e\x6e\x6f\x77\x3d\x65\x3a\x28\x63\x3d\x65\x2d\x74\x68\ \x69\x73\x2e\x73\x74\x61\x72\x74\x54\x69\x6d\x65\x2c\x74\x68\x69\ \x73\x2e\x73\x74\x61\x74\x65\x3d\x63\x2f\x69\x2e\x64\x75\x72\x61\ \x74\x69\x6f\x6e\x2c\x74\x68\x69\x73\x2e\x70\x6f\x73\x3d\x66\x2e\ \x65\x61\x73\x69\x6e\x67\x5b\x69\x2e\x61\x6e\x69\x6d\x61\x74\x65\ \x64\x50\x72\x6f\x70\x65\x72\x74\x69\x65\x73\x5b\x74\x68\x69\x73\ \x2e\x70\x72\x6f\x70\x5d\x5d\x28\x74\x68\x69\x73\x2e\x73\x74\x61\ \x74\x65\x2c\x63\x2c\x30\x2c\x31\x2c\x69\x2e\x64\x75\x72\x61\x74\ \x69\x6f\x6e\x29\x2c\x74\x68\x69\x73\x2e\x6e\x6f\x77\x3d\x74\x68\ \x69\x73\x2e\x73\x74\x61\x72\x74\x2b\x28\x74\x68\x69\x73\x2e\x65\ \x6e\x64\x2d\x74\x68\x69\x73\x2e\x73\x74\x61\x72\x74\x29\x2a\x74\ \x68\x69\x73\x2e\x70\x6f\x73\x29\x2c\x74\x68\x69\x73\x2e\x75\x70\ \x64\x61\x74\x65\x28\x29\x3b\x72\x65\x74\x75\x72\x6e\x21\x30\x7d\ \x7d\x2c\x66\x2e\x65\x78\x74\x65\x6e\x64\x28\x66\x2e\x66\x78\x2c\ \x7b\x74\x69\x63\x6b\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\ \x7b\x76\x61\x72\x20\x61\x2c\x62\x3d\x66\x2e\x74\x69\x6d\x65\x72\ \x73\x2c\x63\x3d\x30\x3b\x66\x6f\x72\x28\x3b\x63\x3c\x62\x2e\x6c\ \x65\x6e\x67\x74\x68\x3b\x63\x2b\x2b\x29\x61\x3d\x62\x5b\x63\x5d\ \x2c\x21\x61\x28\x29\x26\x26\x62\x5b\x63\x5d\x3d\x3d\x3d\x61\x26\ \x26\x62\x2e\x73\x70\x6c\x69\x63\x65\x28\x63\x2d\x2d\x2c\x31\x29\ \x3b\x62\x2e\x6c\x65\x6e\x67\x74\x68\x7c\x7c\x66\x2e\x66\x78\x2e\ \x73\x74\x6f\x70\x28\x29\x7d\x2c\x69\x6e\x74\x65\x72\x76\x61\x6c\ \x3a\x31\x33\x2c\x73\x74\x6f\x70\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x63\x6c\x65\x61\x72\x49\x6e\x74\x65\x72\x76\x61\ \x6c\x28\x63\x70\x29\x2c\x63\x70\x3d\x6e\x75\x6c\x6c\x7d\x2c\x73\ \x70\x65\x65\x64\x73\x3a\x7b\x73\x6c\x6f\x77\x3a\x36\x30\x30\x2c\ \x66\x61\x73\x74\x3a\x32\x30\x30\x2c\x5f\x64\x65\x66\x61\x75\x6c\ \x74\x3a\x34\x30\x30\x7d\x2c\x73\x74\x65\x70\x3a\x7b\x6f\x70\x61\ \x63\x69\x74\x79\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\ \x7b\x66\x2e\x73\x74\x79\x6c\x65\x28\x61\x2e\x65\x6c\x65\x6d\x2c\ \x22\x6f\x70\x61\x63\x69\x74\x79\x22\x2c\x61\x2e\x6e\x6f\x77\x29\ \x7d\x2c\x5f\x64\x65\x66\x61\x75\x6c\x74\x3a\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x61\x2e\x65\x6c\x65\x6d\x2e\x73\x74\ \x79\x6c\x65\x26\x26\x61\x2e\x65\x6c\x65\x6d\x2e\x73\x74\x79\x6c\ \x65\x5b\x61\x2e\x70\x72\x6f\x70\x5d\x21\x3d\x6e\x75\x6c\x6c\x3f\ \x61\x2e\x65\x6c\x65\x6d\x2e\x73\x74\x79\x6c\x65\x5b\x61\x2e\x70\ \x72\x6f\x70\x5d\x3d\x61\x2e\x6e\x6f\x77\x2b\x61\x2e\x75\x6e\x69\ \x74\x3a\x61\x2e\x65\x6c\x65\x6d\x5b\x61\x2e\x70\x72\x6f\x70\x5d\ \x3d\x61\x2e\x6e\x6f\x77\x7d\x7d\x7d\x29\x2c\x66\x2e\x65\x61\x63\ \x68\x28\x5b\x22\x77\x69\x64\x74\x68\x22\x2c\x22\x68\x65\x69\x67\ \x68\x74\x22\x5d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x62\x29\x7b\x66\x2e\x66\x78\x2e\x73\x74\x65\x70\x5b\x62\x5d\x3d\ \x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x66\x2e\x73\x74\ \x79\x6c\x65\x28\x61\x2e\x65\x6c\x65\x6d\x2c\x62\x2c\x4d\x61\x74\ \x68\x2e\x6d\x61\x78\x28\x30\x2c\x61\x2e\x6e\x6f\x77\x29\x2b\x61\ \x2e\x75\x6e\x69\x74\x29\x7d\x7d\x29\x2c\x66\x2e\x65\x78\x70\x72\ \x26\x26\x66\x2e\x65\x78\x70\x72\x2e\x66\x69\x6c\x74\x65\x72\x73\ \x26\x26\x28\x66\x2e\x65\x78\x70\x72\x2e\x66\x69\x6c\x74\x65\x72\ \x73\x2e\x61\x6e\x69\x6d\x61\x74\x65\x64\x3d\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\ \x67\x72\x65\x70\x28\x66\x2e\x74\x69\x6d\x65\x72\x73\x2c\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\x7b\x72\x65\x74\x75\x72\x6e\ \x20\x61\x3d\x3d\x3d\x62\x2e\x65\x6c\x65\x6d\x7d\x29\x2e\x6c\x65\ \x6e\x67\x74\x68\x7d\x29\x3b\x76\x61\x72\x20\x63\x77\x3d\x2f\x5e\ \x74\x28\x3f\x3a\x61\x62\x6c\x65\x7c\x64\x7c\x68\x29\x24\x2f\x69\ \x2c\x63\x78\x3d\x2f\x5e\x28\x3f\x3a\x62\x6f\x64\x79\x7c\x68\x74\ \x6d\x6c\x29\x24\x2f\x69\x3b\x22\x67\x65\x74\x42\x6f\x75\x6e\x64\ \x69\x6e\x67\x43\x6c\x69\x65\x6e\x74\x52\x65\x63\x74\x22\x69\x6e\ \x20\x63\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\ \x6e\x74\x3f\x66\x2e\x66\x6e\x2e\x6f\x66\x66\x73\x65\x74\x3d\x66\ \x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\ \x3d\x74\x68\x69\x73\x5b\x30\x5d\x2c\x63\x3b\x69\x66\x28\x61\x29\ \x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\x68\ \x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\x7b\x66\x2e\x6f\ \x66\x66\x73\x65\x74\x2e\x73\x65\x74\x4f\x66\x66\x73\x65\x74\x28\ \x74\x68\x69\x73\x2c\x61\x2c\x62\x29\x7d\x29\x3b\x69\x66\x28\x21\ \x62\x7c\x7c\x21\x62\x2e\x6f\x77\x6e\x65\x72\x44\x6f\x63\x75\x6d\ \x65\x6e\x74\x29\x72\x65\x74\x75\x72\x6e\x20\x6e\x75\x6c\x6c\x3b\ \x69\x66\x28\x62\x3d\x3d\x3d\x62\x2e\x6f\x77\x6e\x65\x72\x44\x6f\ \x63\x75\x6d\x65\x6e\x74\x2e\x62\x6f\x64\x79\x29\x72\x65\x74\x75\ \x72\x6e\x20\x66\x2e\x6f\x66\x66\x73\x65\x74\x2e\x62\x6f\x64\x79\ \x4f\x66\x66\x73\x65\x74\x28\x62\x29\x3b\x74\x72\x79\x7b\x63\x3d\ \x62\x2e\x67\x65\x74\x42\x6f\x75\x6e\x64\x69\x6e\x67\x43\x6c\x69\ \x65\x6e\x74\x52\x65\x63\x74\x28\x29\x7d\x63\x61\x74\x63\x68\x28\ \x64\x29\x7b\x7d\x76\x61\x72\x20\x65\x3d\x62\x2e\x6f\x77\x6e\x65\ \x72\x44\x6f\x63\x75\x6d\x65\x6e\x74\x2c\x67\x3d\x65\x2e\x64\x6f\ \x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x3b\x69\x66\ \x28\x21\x63\x7c\x7c\x21\x66\x2e\x63\x6f\x6e\x74\x61\x69\x6e\x73\ \x28\x67\x2c\x62\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x63\x3f\x7b\ \x74\x6f\x70\x3a\x63\x2e\x74\x6f\x70\x2c\x6c\x65\x66\x74\x3a\x63\ \x2e\x6c\x65\x66\x74\x7d\x3a\x7b\x74\x6f\x70\x3a\x30\x2c\x6c\x65\ \x66\x74\x3a\x30\x7d\x3b\x76\x61\x72\x20\x68\x3d\x65\x2e\x62\x6f\ \x64\x79\x2c\x69\x3d\x63\x79\x28\x65\x29\x2c\x6a\x3d\x67\x2e\x63\ \x6c\x69\x65\x6e\x74\x54\x6f\x70\x7c\x7c\x68\x2e\x63\x6c\x69\x65\ \x6e\x74\x54\x6f\x70\x7c\x7c\x30\x2c\x6b\x3d\x67\x2e\x63\x6c\x69\ \x65\x6e\x74\x4c\x65\x66\x74\x7c\x7c\x68\x2e\x63\x6c\x69\x65\x6e\ \x74\x4c\x65\x66\x74\x7c\x7c\x30\x2c\x6c\x3d\x69\x2e\x70\x61\x67\ \x65\x59\x4f\x66\x66\x73\x65\x74\x7c\x7c\x66\x2e\x73\x75\x70\x70\ \x6f\x72\x74\x2e\x62\x6f\x78\x4d\x6f\x64\x65\x6c\x26\x26\x67\x2e\ \x73\x63\x72\x6f\x6c\x6c\x54\x6f\x70\x7c\x7c\x68\x2e\x73\x63\x72\ \x6f\x6c\x6c\x54\x6f\x70\x2c\x6d\x3d\x69\x2e\x70\x61\x67\x65\x58\ \x4f\x66\x66\x73\x65\x74\x7c\x7c\x66\x2e\x73\x75\x70\x70\x6f\x72\ \x74\x2e\x62\x6f\x78\x4d\x6f\x64\x65\x6c\x26\x26\x67\x2e\x73\x63\ \x72\x6f\x6c\x6c\x4c\x65\x66\x74\x7c\x7c\x68\x2e\x73\x63\x72\x6f\ \x6c\x6c\x4c\x65\x66\x74\x2c\x6e\x3d\x63\x2e\x74\x6f\x70\x2b\x6c\ \x2d\x6a\x2c\x6f\x3d\x63\x2e\x6c\x65\x66\x74\x2b\x6d\x2d\x6b\x3b\ \x72\x65\x74\x75\x72\x6e\x7b\x74\x6f\x70\x3a\x6e\x2c\x6c\x65\x66\ \x74\x3a\x6f\x7d\x7d\x3a\x66\x2e\x66\x6e\x2e\x6f\x66\x66\x73\x65\ \x74\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\ \x72\x20\x62\x3d\x74\x68\x69\x73\x5b\x30\x5d\x3b\x69\x66\x28\x61\ \x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x65\x61\x63\ \x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\x7b\x66\x2e\ \x6f\x66\x66\x73\x65\x74\x2e\x73\x65\x74\x4f\x66\x66\x73\x65\x74\ \x28\x74\x68\x69\x73\x2c\x61\x2c\x62\x29\x7d\x29\x3b\x69\x66\x28\ \x21\x62\x7c\x7c\x21\x62\x2e\x6f\x77\x6e\x65\x72\x44\x6f\x63\x75\ \x6d\x65\x6e\x74\x29\x72\x65\x74\x75\x72\x6e\x20\x6e\x75\x6c\x6c\ \x3b\x69\x66\x28\x62\x3d\x3d\x3d\x62\x2e\x6f\x77\x6e\x65\x72\x44\ \x6f\x63\x75\x6d\x65\x6e\x74\x2e\x62\x6f\x64\x79\x29\x72\x65\x74\ \x75\x72\x6e\x20\x66\x2e\x6f\x66\x66\x73\x65\x74\x2e\x62\x6f\x64\ \x79\x4f\x66\x66\x73\x65\x74\x28\x62\x29\x3b\x76\x61\x72\x20\x63\ \x2c\x64\x3d\x62\x2e\x6f\x66\x66\x73\x65\x74\x50\x61\x72\x65\x6e\ \x74\x2c\x65\x3d\x62\x2c\x67\x3d\x62\x2e\x6f\x77\x6e\x65\x72\x44\ \x6f\x63\x75\x6d\x65\x6e\x74\x2c\x68\x3d\x67\x2e\x64\x6f\x63\x75\ \x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x2c\x69\x3d\x67\x2e\ \x62\x6f\x64\x79\x2c\x6a\x3d\x67\x2e\x64\x65\x66\x61\x75\x6c\x74\ \x56\x69\x65\x77\x2c\x6b\x3d\x6a\x3f\x6a\x2e\x67\x65\x74\x43\x6f\ \x6d\x70\x75\x74\x65\x64\x53\x74\x79\x6c\x65\x28\x62\x2c\x6e\x75\ \x6c\x6c\x29\x3a\x62\x2e\x63\x75\x72\x72\x65\x6e\x74\x53\x74\x79\ \x6c\x65\x2c\x6c\x3d\x62\x2e\x6f\x66\x66\x73\x65\x74\x54\x6f\x70\ \x2c\x6d\x3d\x62\x2e\x6f\x66\x66\x73\x65\x74\x4c\x65\x66\x74\x3b\ \x77\x68\x69\x6c\x65\x28\x28\x62\x3d\x62\x2e\x70\x61\x72\x65\x6e\ \x74\x4e\x6f\x64\x65\x29\x26\x26\x62\x21\x3d\x3d\x69\x26\x26\x62\ \x21\x3d\x3d\x68\x29\x7b\x69\x66\x28\x66\x2e\x73\x75\x70\x70\x6f\ \x72\x74\x2e\x66\x69\x78\x65\x64\x50\x6f\x73\x69\x74\x69\x6f\x6e\ \x26\x26\x6b\x2e\x70\x6f\x73\x69\x74\x69\x6f\x6e\x3d\x3d\x3d\x22\ \x66\x69\x78\x65\x64\x22\x29\x62\x72\x65\x61\x6b\x3b\x63\x3d\x6a\ \x3f\x6a\x2e\x67\x65\x74\x43\x6f\x6d\x70\x75\x74\x65\x64\x53\x74\ \x79\x6c\x65\x28\x62\x2c\x6e\x75\x6c\x6c\x29\x3a\x62\x2e\x63\x75\ \x72\x72\x65\x6e\x74\x53\x74\x79\x6c\x65\x2c\x6c\x2d\x3d\x62\x2e\ \x73\x63\x72\x6f\x6c\x6c\x54\x6f\x70\x2c\x6d\x2d\x3d\x62\x2e\x73\ \x63\x72\x6f\x6c\x6c\x4c\x65\x66\x74\x2c\x62\x3d\x3d\x3d\x64\x26\ \x26\x28\x6c\x2b\x3d\x62\x2e\x6f\x66\x66\x73\x65\x74\x54\x6f\x70\ \x2c\x6d\x2b\x3d\x62\x2e\x6f\x66\x66\x73\x65\x74\x4c\x65\x66\x74\ \x2c\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x64\x6f\x65\x73\x4e\ \x6f\x74\x41\x64\x64\x42\x6f\x72\x64\x65\x72\x26\x26\x28\x21\x66\ \x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x64\x6f\x65\x73\x41\x64\x64\ \x42\x6f\x72\x64\x65\x72\x46\x6f\x72\x54\x61\x62\x6c\x65\x41\x6e\ \x64\x43\x65\x6c\x6c\x73\x7c\x7c\x21\x63\x77\x2e\x74\x65\x73\x74\ \x28\x62\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x29\x26\x26\x28\ \x6c\x2b\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\x63\x2e\ \x62\x6f\x72\x64\x65\x72\x54\x6f\x70\x57\x69\x64\x74\x68\x29\x7c\ \x7c\x30\x2c\x6d\x2b\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\ \x28\x63\x2e\x62\x6f\x72\x64\x65\x72\x4c\x65\x66\x74\x57\x69\x64\ \x74\x68\x29\x7c\x7c\x30\x29\x2c\x65\x3d\x64\x2c\x64\x3d\x62\x2e\ \x6f\x66\x66\x73\x65\x74\x50\x61\x72\x65\x6e\x74\x29\x2c\x66\x2e\ \x73\x75\x70\x70\x6f\x72\x74\x2e\x73\x75\x62\x74\x72\x61\x63\x74\ \x73\x42\x6f\x72\x64\x65\x72\x46\x6f\x72\x4f\x76\x65\x72\x66\x6c\ \x6f\x77\x4e\x6f\x74\x56\x69\x73\x69\x62\x6c\x65\x26\x26\x63\x2e\ \x6f\x76\x65\x72\x66\x6c\x6f\x77\x21\x3d\x3d\x22\x76\x69\x73\x69\ \x62\x6c\x65\x22\x26\x26\x28\x6c\x2b\x3d\x70\x61\x72\x73\x65\x46\ \x6c\x6f\x61\x74\x28\x63\x2e\x62\x6f\x72\x64\x65\x72\x54\x6f\x70\ \x57\x69\x64\x74\x68\x29\x7c\x7c\x30\x2c\x6d\x2b\x3d\x70\x61\x72\ \x73\x65\x46\x6c\x6f\x61\x74\x28\x63\x2e\x62\x6f\x72\x64\x65\x72\ \x4c\x65\x66\x74\x57\x69\x64\x74\x68\x29\x7c\x7c\x30\x29\x2c\x6b\ \x3d\x63\x7d\x69\x66\x28\x6b\x2e\x70\x6f\x73\x69\x74\x69\x6f\x6e\ \x3d\x3d\x3d\x22\x72\x65\x6c\x61\x74\x69\x76\x65\x22\x7c\x7c\x6b\ \x2e\x70\x6f\x73\x69\x74\x69\x6f\x6e\x3d\x3d\x3d\x22\x73\x74\x61\ \x74\x69\x63\x22\x29\x6c\x2b\x3d\x69\x2e\x6f\x66\x66\x73\x65\x74\ \x54\x6f\x70\x2c\x6d\x2b\x3d\x69\x2e\x6f\x66\x66\x73\x65\x74\x4c\ \x65\x66\x74\x3b\x66\x2e\x73\x75\x70\x70\x6f\x72\x74\x2e\x66\x69\ \x78\x65\x64\x50\x6f\x73\x69\x74\x69\x6f\x6e\x26\x26\x6b\x2e\x70\ \x6f\x73\x69\x74\x69\x6f\x6e\x3d\x3d\x3d\x22\x66\x69\x78\x65\x64\ \x22\x26\x26\x28\x6c\x2b\x3d\x4d\x61\x74\x68\x2e\x6d\x61\x78\x28\ \x68\x2e\x73\x63\x72\x6f\x6c\x6c\x54\x6f\x70\x2c\x69\x2e\x73\x63\ \x72\x6f\x6c\x6c\x54\x6f\x70\x29\x2c\x6d\x2b\x3d\x4d\x61\x74\x68\ \x2e\x6d\x61\x78\x28\x68\x2e\x73\x63\x72\x6f\x6c\x6c\x4c\x65\x66\ \x74\x2c\x69\x2e\x73\x63\x72\x6f\x6c\x6c\x4c\x65\x66\x74\x29\x29\ \x3b\x72\x65\x74\x75\x72\x6e\x7b\x74\x6f\x70\x3a\x6c\x2c\x6c\x65\ \x66\x74\x3a\x6d\x7d\x7d\x2c\x66\x2e\x6f\x66\x66\x73\x65\x74\x3d\ \x7b\x62\x6f\x64\x79\x4f\x66\x66\x73\x65\x74\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x3d\x61\x2e\ \x6f\x66\x66\x73\x65\x74\x54\x6f\x70\x2c\x63\x3d\x61\x2e\x6f\x66\ \x66\x73\x65\x74\x4c\x65\x66\x74\x3b\x66\x2e\x73\x75\x70\x70\x6f\ \x72\x74\x2e\x64\x6f\x65\x73\x4e\x6f\x74\x49\x6e\x63\x6c\x75\x64\ \x65\x4d\x61\x72\x67\x69\x6e\x49\x6e\x42\x6f\x64\x79\x4f\x66\x66\ \x73\x65\x74\x26\x26\x28\x62\x2b\x3d\x70\x61\x72\x73\x65\x46\x6c\ \x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\x61\x2c\x22\x6d\x61\x72\ \x67\x69\x6e\x54\x6f\x70\x22\x29\x29\x7c\x7c\x30\x2c\x63\x2b\x3d\ \x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\x66\x2e\x63\x73\x73\ \x28\x61\x2c\x22\x6d\x61\x72\x67\x69\x6e\x4c\x65\x66\x74\x22\x29\ \x29\x7c\x7c\x30\x29\x3b\x72\x65\x74\x75\x72\x6e\x7b\x74\x6f\x70\ \x3a\x62\x2c\x6c\x65\x66\x74\x3a\x63\x7d\x7d\x2c\x73\x65\x74\x4f\ \x66\x66\x73\x65\x74\x3a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\ \x2c\x62\x2c\x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x66\x2e\x63\x73\ \x73\x28\x61\x2c\x22\x70\x6f\x73\x69\x74\x69\x6f\x6e\x22\x29\x3b\ \x64\x3d\x3d\x3d\x22\x73\x74\x61\x74\x69\x63\x22\x26\x26\x28\x61\ \x2e\x73\x74\x79\x6c\x65\x2e\x70\x6f\x73\x69\x74\x69\x6f\x6e\x3d\ \x22\x72\x65\x6c\x61\x74\x69\x76\x65\x22\x29\x3b\x76\x61\x72\x20\ \x65\x3d\x66\x28\x61\x29\x2c\x67\x3d\x65\x2e\x6f\x66\x66\x73\x65\ \x74\x28\x29\x2c\x68\x3d\x66\x2e\x63\x73\x73\x28\x61\x2c\x22\x74\ \x6f\x70\x22\x29\x2c\x69\x3d\x66\x2e\x63\x73\x73\x28\x61\x2c\x22\ \x6c\x65\x66\x74\x22\x29\x2c\x6a\x3d\x28\x64\x3d\x3d\x3d\x22\x61\ \x62\x73\x6f\x6c\x75\x74\x65\x22\x7c\x7c\x64\x3d\x3d\x3d\x22\x66\ \x69\x78\x65\x64\x22\x29\x26\x26\x66\x2e\x69\x6e\x41\x72\x72\x61\ \x79\x28\x22\x61\x75\x74\x6f\x22\x2c\x5b\x68\x2c\x69\x5d\x29\x3e\ \x2d\x31\x2c\x6b\x3d\x7b\x7d\x2c\x6c\x3d\x7b\x7d\x2c\x6d\x2c\x6e\ \x3b\x6a\x3f\x28\x6c\x3d\x65\x2e\x70\x6f\x73\x69\x74\x69\x6f\x6e\ \x28\x29\x2c\x6d\x3d\x6c\x2e\x74\x6f\x70\x2c\x6e\x3d\x6c\x2e\x6c\ \x65\x66\x74\x29\x3a\x28\x6d\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\ \x61\x74\x28\x68\x29\x7c\x7c\x30\x2c\x6e\x3d\x70\x61\x72\x73\x65\ \x46\x6c\x6f\x61\x74\x28\x69\x29\x7c\x7c\x30\x29\x2c\x66\x2e\x69\ \x73\x46\x75\x6e\x63\x74\x69\x6f\x6e\x28\x62\x29\x26\x26\x28\x62\ \x3d\x62\x2e\x63\x61\x6c\x6c\x28\x61\x2c\x63\x2c\x67\x29\x29\x2c\ \x62\x2e\x74\x6f\x70\x21\x3d\x6e\x75\x6c\x6c\x26\x26\x28\x6b\x2e\ \x74\x6f\x70\x3d\x62\x2e\x74\x6f\x70\x2d\x67\x2e\x74\x6f\x70\x2b\ \x6d\x29\x2c\x62\x2e\x6c\x65\x66\x74\x21\x3d\x6e\x75\x6c\x6c\x26\ \x26\x28\x6b\x2e\x6c\x65\x66\x74\x3d\x62\x2e\x6c\x65\x66\x74\x2d\ \x67\x2e\x6c\x65\x66\x74\x2b\x6e\x29\x2c\x22\x75\x73\x69\x6e\x67\ \x22\x69\x6e\x20\x62\x3f\x62\x2e\x75\x73\x69\x6e\x67\x2e\x63\x61\ \x6c\x6c\x28\x61\x2c\x6b\x29\x3a\x65\x2e\x63\x73\x73\x28\x6b\x29\ \x7d\x7d\x2c\x66\x2e\x66\x6e\x2e\x65\x78\x74\x65\x6e\x64\x28\x7b\ \x70\x6f\x73\x69\x74\x69\x6f\x6e\x3a\x66\x75\x6e\x63\x74\x69\x6f\ \x6e\x28\x29\x7b\x69\x66\x28\x21\x74\x68\x69\x73\x5b\x30\x5d\x29\ \x72\x65\x74\x75\x72\x6e\x20\x6e\x75\x6c\x6c\x3b\x76\x61\x72\x20\ \x61\x3d\x74\x68\x69\x73\x5b\x30\x5d\x2c\x62\x3d\x74\x68\x69\x73\ \x2e\x6f\x66\x66\x73\x65\x74\x50\x61\x72\x65\x6e\x74\x28\x29\x2c\ \x63\x3d\x74\x68\x69\x73\x2e\x6f\x66\x66\x73\x65\x74\x28\x29\x2c\ \x64\x3d\x63\x78\x2e\x74\x65\x73\x74\x28\x62\x5b\x30\x5d\x2e\x6e\ \x6f\x64\x65\x4e\x61\x6d\x65\x29\x3f\x7b\x74\x6f\x70\x3a\x30\x2c\ \x6c\x65\x66\x74\x3a\x30\x7d\x3a\x62\x2e\x6f\x66\x66\x73\x65\x74\ \x28\x29\x3b\x63\x2e\x74\x6f\x70\x2d\x3d\x70\x61\x72\x73\x65\x46\ \x6c\x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\x61\x2c\x22\x6d\x61\ \x72\x67\x69\x6e\x54\x6f\x70\x22\x29\x29\x7c\x7c\x30\x2c\x63\x2e\ \x6c\x65\x66\x74\x2d\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\ \x28\x66\x2e\x63\x73\x73\x28\x61\x2c\x22\x6d\x61\x72\x67\x69\x6e\ \x4c\x65\x66\x74\x22\x29\x29\x7c\x7c\x30\x2c\x64\x2e\x74\x6f\x70\ \x2b\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\x66\x2e\x63\ \x73\x73\x28\x62\x5b\x30\x5d\x2c\x22\x62\x6f\x72\x64\x65\x72\x54\ \x6f\x70\x57\x69\x64\x74\x68\x22\x29\x29\x7c\x7c\x30\x2c\x64\x2e\ \x6c\x65\x66\x74\x2b\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\ \x28\x66\x2e\x63\x73\x73\x28\x62\x5b\x30\x5d\x2c\x22\x62\x6f\x72\ \x64\x65\x72\x4c\x65\x66\x74\x57\x69\x64\x74\x68\x22\x29\x29\x7c\ \x7c\x30\x3b\x72\x65\x74\x75\x72\x6e\x7b\x74\x6f\x70\x3a\x63\x2e\ \x74\x6f\x70\x2d\x64\x2e\x74\x6f\x70\x2c\x6c\x65\x66\x74\x3a\x63\ \x2e\x6c\x65\x66\x74\x2d\x64\x2e\x6c\x65\x66\x74\x7d\x7d\x2c\x6f\ \x66\x66\x73\x65\x74\x50\x61\x72\x65\x6e\x74\x3a\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x74\x68\ \x69\x73\x2e\x6d\x61\x70\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\ \x29\x7b\x76\x61\x72\x20\x61\x3d\x74\x68\x69\x73\x2e\x6f\x66\x66\ \x73\x65\x74\x50\x61\x72\x65\x6e\x74\x7c\x7c\x63\x2e\x62\x6f\x64\ \x79\x3b\x77\x68\x69\x6c\x65\x28\x61\x26\x26\x21\x63\x78\x2e\x74\ \x65\x73\x74\x28\x61\x2e\x6e\x6f\x64\x65\x4e\x61\x6d\x65\x29\x26\ \x26\x66\x2e\x63\x73\x73\x28\x61\x2c\x22\x70\x6f\x73\x69\x74\x69\ \x6f\x6e\x22\x29\x3d\x3d\x3d\x22\x73\x74\x61\x74\x69\x63\x22\x29\ \x61\x3d\x61\x2e\x6f\x66\x66\x73\x65\x74\x50\x61\x72\x65\x6e\x74\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x61\x7d\x29\x7d\x7d\x29\x2c\x66\ \x2e\x65\x61\x63\x68\x28\x5b\x22\x4c\x65\x66\x74\x22\x2c\x22\x54\ \x6f\x70\x22\x5d\x2c\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\ \x63\x29\x7b\x76\x61\x72\x20\x64\x3d\x22\x73\x63\x72\x6f\x6c\x6c\ \x22\x2b\x63\x3b\x66\x2e\x66\x6e\x5b\x64\x5d\x3d\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x28\x63\x29\x7b\x76\x61\x72\x20\x65\x2c\x67\x3b\ \x69\x66\x28\x63\x3d\x3d\x3d\x62\x29\x7b\x65\x3d\x74\x68\x69\x73\ \x5b\x30\x5d\x3b\x69\x66\x28\x21\x65\x29\x72\x65\x74\x75\x72\x6e\ \x20\x6e\x75\x6c\x6c\x3b\x67\x3d\x63\x79\x28\x65\x29\x3b\x72\x65\ \x74\x75\x72\x6e\x20\x67\x3f\x22\x70\x61\x67\x65\x58\x4f\x66\x66\ \x73\x65\x74\x22\x69\x6e\x20\x67\x3f\x67\x5b\x61\x3f\x22\x70\x61\ \x67\x65\x59\x4f\x66\x66\x73\x65\x74\x22\x3a\x22\x70\x61\x67\x65\ \x58\x4f\x66\x66\x73\x65\x74\x22\x5d\x3a\x66\x2e\x73\x75\x70\x70\ \x6f\x72\x74\x2e\x62\x6f\x78\x4d\x6f\x64\x65\x6c\x26\x26\x67\x2e\ \x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x64\x6f\x63\x75\x6d\x65\x6e\ \x74\x45\x6c\x65\x6d\x65\x6e\x74\x5b\x64\x5d\x7c\x7c\x67\x2e\x64\ \x6f\x63\x75\x6d\x65\x6e\x74\x2e\x62\x6f\x64\x79\x5b\x64\x5d\x3a\ \x65\x5b\x64\x5d\x7d\x72\x65\x74\x75\x72\x6e\x20\x74\x68\x69\x73\ \x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\ \x7b\x67\x3d\x63\x79\x28\x74\x68\x69\x73\x29\x2c\x67\x3f\x67\x2e\ \x73\x63\x72\x6f\x6c\x6c\x54\x6f\x28\x61\x3f\x66\x28\x67\x29\x2e\ \x73\x63\x72\x6f\x6c\x6c\x4c\x65\x66\x74\x28\x29\x3a\x63\x2c\x61\ \x3f\x63\x3a\x66\x28\x67\x29\x2e\x73\x63\x72\x6f\x6c\x6c\x54\x6f\ \x70\x28\x29\x29\x3a\x74\x68\x69\x73\x5b\x64\x5d\x3d\x63\x7d\x29\ \x7d\x7d\x29\x2c\x66\x2e\x65\x61\x63\x68\x28\x5b\x22\x48\x65\x69\ \x67\x68\x74\x22\x2c\x22\x57\x69\x64\x74\x68\x22\x5d\x2c\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x28\x61\x2c\x63\x29\x7b\x76\x61\x72\x20\ \x64\x3d\x63\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\x28\ \x29\x3b\x66\x2e\x66\x6e\x5b\x22\x69\x6e\x6e\x65\x72\x22\x2b\x63\ \x5d\x3d\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x7b\x76\x61\x72\ \x20\x61\x3d\x74\x68\x69\x73\x5b\x30\x5d\x3b\x72\x65\x74\x75\x72\ \x6e\x20\x61\x3f\x61\x2e\x73\x74\x79\x6c\x65\x3f\x70\x61\x72\x73\ \x65\x46\x6c\x6f\x61\x74\x28\x66\x2e\x63\x73\x73\x28\x61\x2c\x64\ \x2c\x22\x70\x61\x64\x64\x69\x6e\x67\x22\x29\x29\x3a\x74\x68\x69\ \x73\x5b\x64\x5d\x28\x29\x3a\x6e\x75\x6c\x6c\x7d\x2c\x66\x2e\x66\ \x6e\x5b\x22\x6f\x75\x74\x65\x72\x22\x2b\x63\x5d\x3d\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x62\x3d\x74\ \x68\x69\x73\x5b\x30\x5d\x3b\x72\x65\x74\x75\x72\x6e\x20\x62\x3f\ \x62\x2e\x73\x74\x79\x6c\x65\x3f\x70\x61\x72\x73\x65\x46\x6c\x6f\ \x61\x74\x28\x66\x2e\x63\x73\x73\x28\x62\x2c\x64\x2c\x61\x3f\x22\ \x6d\x61\x72\x67\x69\x6e\x22\x3a\x22\x62\x6f\x72\x64\x65\x72\x22\ \x29\x29\x3a\x74\x68\x69\x73\x5b\x64\x5d\x28\x29\x3a\x6e\x75\x6c\ \x6c\x7d\x2c\x66\x2e\x66\x6e\x5b\x64\x5d\x3d\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x7b\x76\x61\x72\x20\x65\x3d\x74\x68\x69\ \x73\x5b\x30\x5d\x3b\x69\x66\x28\x21\x65\x29\x72\x65\x74\x75\x72\ \x6e\x20\x61\x3d\x3d\x6e\x75\x6c\x6c\x3f\x6e\x75\x6c\x6c\x3a\x74\ \x68\x69\x73\x3b\x69\x66\x28\x66\x2e\x69\x73\x46\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x61\x29\x29\x72\x65\x74\x75\x72\x6e\x20\x74\x68\ \x69\x73\x2e\x65\x61\x63\x68\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e\ \x28\x62\x29\x7b\x76\x61\x72\x20\x63\x3d\x66\x28\x74\x68\x69\x73\ \x29\x3b\x63\x5b\x64\x5d\x28\x61\x2e\x63\x61\x6c\x6c\x28\x74\x68\ \x69\x73\x2c\x62\x2c\x63\x5b\x64\x5d\x28\x29\x29\x29\x7d\x29\x3b\ \x69\x66\x28\x66\x2e\x69\x73\x57\x69\x6e\x64\x6f\x77\x28\x65\x29\ \x29\x7b\x76\x61\x72\x20\x67\x3d\x65\x2e\x64\x6f\x63\x75\x6d\x65\ \x6e\x74\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\x45\x6c\x65\x6d\x65\ \x6e\x74\x5b\x22\x63\x6c\x69\x65\x6e\x74\x22\x2b\x63\x5d\x2c\x68\ \x3d\x65\x2e\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x62\x6f\x64\x79\ \x3b\x72\x65\x74\x75\x72\x6e\x20\x65\x2e\x64\x6f\x63\x75\x6d\x65\ \x6e\x74\x2e\x63\x6f\x6d\x70\x61\x74\x4d\x6f\x64\x65\x3d\x3d\x3d\ \x22\x43\x53\x53\x31\x43\x6f\x6d\x70\x61\x74\x22\x26\x26\x67\x7c\ \x7c\x68\x26\x26\x68\x5b\x22\x63\x6c\x69\x65\x6e\x74\x22\x2b\x63\ \x5d\x7c\x7c\x67\x7d\x69\x66\x28\x65\x2e\x6e\x6f\x64\x65\x54\x79\ \x70\x65\x3d\x3d\x3d\x39\x29\x72\x65\x74\x75\x72\x6e\x20\x4d\x61\ \x74\x68\x2e\x6d\x61\x78\x28\x65\x2e\x64\x6f\x63\x75\x6d\x65\x6e\ \x74\x45\x6c\x65\x6d\x65\x6e\x74\x5b\x22\x63\x6c\x69\x65\x6e\x74\ \x22\x2b\x63\x5d\x2c\x65\x2e\x62\x6f\x64\x79\x5b\x22\x73\x63\x72\ \x6f\x6c\x6c\x22\x2b\x63\x5d\x2c\x65\x2e\x64\x6f\x63\x75\x6d\x65\ \x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x5b\x22\x73\x63\x72\x6f\x6c\ \x6c\x22\x2b\x63\x5d\x2c\x65\x2e\x62\x6f\x64\x79\x5b\x22\x6f\x66\ \x66\x73\x65\x74\x22\x2b\x63\x5d\x2c\x65\x2e\x64\x6f\x63\x75\x6d\ \x65\x6e\x74\x45\x6c\x65\x6d\x65\x6e\x74\x5b\x22\x6f\x66\x66\x73\ \x65\x74\x22\x2b\x63\x5d\x29\x3b\x69\x66\x28\x61\x3d\x3d\x3d\x62\ \x29\x7b\x76\x61\x72\x20\x69\x3d\x66\x2e\x63\x73\x73\x28\x65\x2c\ \x64\x29\x2c\x6a\x3d\x70\x61\x72\x73\x65\x46\x6c\x6f\x61\x74\x28\ \x69\x29\x3b\x72\x65\x74\x75\x72\x6e\x20\x66\x2e\x69\x73\x4e\x75\ \x6d\x65\x72\x69\x63\x28\x6a\x29\x3f\x6a\x3a\x69\x7d\x72\x65\x74\ \x75\x72\x6e\x20\x74\x68\x69\x73\x2e\x63\x73\x73\x28\x64\x2c\x74\ \x79\x70\x65\x6f\x66\x20\x61\x3d\x3d\x22\x73\x74\x72\x69\x6e\x67\ \x22\x3f\x61\x3a\x61\x2b\x22\x70\x78\x22\x29\x7d\x7d\x29\x2c\x61\ \x2e\x6a\x51\x75\x65\x72\x79\x3d\x61\x2e\x24\x3d\x66\x2c\x74\x79\ \x70\x65\x6f\x66\x20\x64\x65\x66\x69\x6e\x65\x3d\x3d\x22\x66\x75\ \x6e\x63\x74\x69\x6f\x6e\x22\x26\x26\x64\x65\x66\x69\x6e\x65\x2e\ \x61\x6d\x64\x26\x26\x64\x65\x66\x69\x6e\x65\x2e\x61\x6d\x64\x2e\ \x6a\x51\x75\x65\x72\x79\x26\x26\x64\x65\x66\x69\x6e\x65\x28\x22\ \x6a\x71\x75\x65\x72\x79\x22\x2c\x5b\x5d\x2c\x66\x75\x6e\x63\x74\ \x69\x6f\x6e\x28\x29\x7b\x72\x65\x74\x75\x72\x6e\x20\x66\x7d\x29\ \x7d\x29\x28\x77\x69\x6e\x64\x6f\x77\x29\x3b\ " qt_resource_name = b"\ \x00\x0a\ \x08\x94\x81\xf4\ \x00\x6a\ \x00\x61\x00\x76\x00\x61\x00\x73\x00\x63\x00\x72\x00\x69\x00\x70\x00\x74\ \x00\x0c\ \x06\x7a\xfc\x33\ \x00\x6a\ \x00\x71\x00\x75\x00\x65\x00\x72\x00\x79\x00\x2d\x00\x75\x00\x69\x00\x2e\x00\x6a\x00\x73\ \x00\x09\ \x0b\xc9\x66\x13\ \x00\x6a\ \x00\x71\x00\x75\x00\x65\x00\x72\x00\x79\x00\x2e\x00\x6a\x00\x73\ " qt_resource_struct = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\ \x00\x00\x00\x1a\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x00\x38\x00\x00\x00\x00\x00\x01\x00\x00\x24\x38\ " def qInitResources(): QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) def qCleanupResources(): QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) qInitResources() eric-6.0.8/eric/Helpviewer/data/icons_rc.py0000644000175000017500000037441312451233375017662 0ustar piotrpiotr# -*- coding: utf-8 -*- # Resource object code # # Created: So. Juni 29 18:58:04 2014 # by: The Resource Compiler for PyQt (Qt v5.3.1) # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore qt_resource_data = b"\ \x00\x00\x03\xb1\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x18\x00\x00\x00\x18\x08\x06\x00\x00\x00\xe0\x77\x3d\xf8\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\x1b\xaf\x01\x5e\x1a\ \x91\x1c\x00\x00\x03\x56\x49\x44\x41\x54\x48\xc7\xdd\x95\x4d\x68\ \x5c\x55\x14\xc7\x7f\xf7\xe3\xbd\x97\xe9\x34\x69\x5a\x93\x60\xdb\ \x80\x60\xc1\x12\x9a\x20\x0d\x49\x88\x50\xca\x43\xbb\x70\x93\x85\ \x62\x41\x2b\xea\x42\xb0\xb8\xb2\x20\x08\x6e\x64\xd0\x55\x4b\x2d\ \x48\x37\x22\x48\x10\x8c\x20\xba\x09\x45\xa4\x12\xe2\x98\x8a\x29\ \x1a\xa4\x92\x6a\x6d\x4a\x9b\xb4\x19\x9d\x98\xc4\xb1\xd3\x99\x79\ \xf3\xde\x9b\xf7\xee\x75\x51\x2c\xe4\x63\x31\xc1\x6e\xf4\xec\xee\ \xc7\x39\xbf\x7b\xee\xb9\xff\x73\xe1\xbf\x6e\xa2\x99\x4d\xfd\x9f\ \x3e\xd4\xff\xdc\x23\x2f\x7d\x38\xbe\xf0\xc9\xa3\x8e\x94\xc1\xc1\ \xae\xc1\xc9\xa1\xae\x43\x6f\x3c\xbb\xef\xd5\x5f\xb7\x04\xc8\xe7\ \xf3\x76\xb3\x4d\x1f\x94\x4f\xf3\xee\x91\xf7\x99\x2d\xcd\x90\xda\ \x98\x30\x89\x28\xdd\x5e\x65\xdf\x9d\x83\x9b\x06\xf5\x7d\xff\x5e\ \x5c\xbd\x7e\x31\x9f\xcf\x6f\x70\xb8\xb6\x67\x8e\x6f\x0a\x13\x74\ \x74\x08\x04\x29\x5e\xb5\x8d\xc9\xf9\x2f\x58\x9c\x2d\x6f\x16\x7c\ \xcd\x58\x6f\x76\x82\x5c\x2e\xb7\x26\xb3\x87\x3f\xda\xf5\x43\x6c\ \xa2\x81\xdf\x6a\xab\x08\x04\xd9\x44\x33\x2f\xaf\xce\x8c\xe5\x26\ \x06\xd7\xf9\x6d\xb8\x01\xdd\x4c\x0d\x52\x63\x48\xad\x21\x6c\xc4\ \x08\xa0\xc5\x1a\x8c\x69\xae\xc8\x4d\x01\x4c\x6a\x30\x58\x6a\x71\ \x08\x08\xda\x74\x4a\x6a\xec\xfd\x03\x24\xc6\x24\xc6\x1a\xea\xc9\ \xdd\x0c\x8c\x34\x24\xa9\x49\xb6\x04\x38\x3b\x73\xb6\xb7\x20\x0b\ \x9c\xeb\x3c\x07\xa7\xf9\xde\xd3\x5a\x68\x29\xd1\x52\x26\x89\xb1\ \x7d\x49\x9a\x12\x36\x42\xa4\x10\xc4\x6e\x8c\xc5\xf6\x0d\x7e\xde\ \x3d\xed\x69\xad\x1d\xad\xd0\x12\xbb\xcc\x4f\xd4\xf6\xec\x67\xa2\ \xf8\x59\xcf\x91\xdd\x47\xaf\xac\x01\xcc\xfd\x39\xf7\xde\xa9\xc7\ \x4f\x51\x11\x65\x8e\xc6\x4f\x0f\x4a\x29\x11\xc2\x82\x00\x29\x04\ \x59\x37\x63\x83\x30\x10\x00\x9e\xf2\xec\xf1\xde\xd7\xb3\x4a\xa8\ \x61\x29\x24\x5a\x2a\xb6\x39\x59\xb6\xeb\xed\x34\x08\xf8\xea\xd6\ \xd8\x3b\xc0\x33\x6b\x00\xa3\x97\x46\x87\x0f\x74\xf4\x70\xa3\x72\ \x85\x62\x58\x44\x6a\x85\x52\xa0\x94\x44\x0b\xc9\x5c\x60\x44\xc3\ \x84\x48\x01\xd3\x2b\x93\x42\x0b\x05\x48\x5a\x9d\x76\x8c\x51\xfc\ \xb2\x74\x8d\x1b\xc5\x45\x5e\x1c\x1a\x61\x29\x28\x3c\xb9\xe1\x8a\ \x82\x28\xb0\x97\x57\x7e\x26\x30\x65\x6a\x69\x1d\x65\x25\xca\x48\ \x1c\xa3\x70\xd4\xdd\x6c\x94\x54\x78\xca\xa3\x45\xb5\xa0\x71\xa9\ \xc4\x55\xbe\xfb\xe3\x22\xf3\xa5\x5b\x54\xc2\x90\xac\x69\xa7\xd6\ \xa8\xd2\x30\xe9\xc6\x1a\x58\x63\xc7\xa7\x16\x2e\x1c\xeb\xe9\xec\ \xc1\x53\x6d\x68\xa9\xf0\x94\x8b\x87\x8b\x46\xd1\xea\x64\xec\xc5\ \xe5\xf3\xc2\xca\x98\xa1\xce\x27\x6c\x10\xd7\x85\x12\x9a\xbe\x07\ \x0e\xd0\xb7\xab\x17\x8b\xc5\x95\x8a\x42\x78\x95\xc4\xa4\xe3\x9b\ \x01\x4e\x64\xa2\xcc\xb1\xa9\xcb\x53\x14\xdd\xe2\x0c\x02\x90\x20\ \x24\x89\xab\x54\xdf\x53\xfb\x47\xb2\x5a\x5b\x32\x6e\x96\xdb\xf5\ \xbf\xc4\x97\x0b\xe7\x6b\x9e\x23\x67\x5d\xa5\xb4\xab\x14\xae\xd6\ \xec\x8c\x3a\x06\xba\xdb\xbb\x89\x68\x9c\xd8\xf8\x4c\xdf\x66\xe5\ \x64\xfe\x24\xf9\x7c\x9e\xdc\x9b\xb9\x7b\x0a\xb5\x80\x39\x63\xa7\ \x83\x24\x18\xd6\x8e\xc4\xd3\x92\xba\x09\x48\x4c\x32\x7b\xf3\x85\ \xca\x63\x6b\x95\xfc\xb2\xf5\x7d\x1f\xdf\xf7\x57\xfe\x99\x93\x4d\ \x29\xd9\xa2\xab\x71\x15\x8b\x45\x29\x41\x64\x42\x52\xd3\x9c\x86\ \x9a\x53\xb2\x35\x54\xa2\x0a\xa9\x13\x92\x71\x15\x51\x5c\x25\x69\ \xb2\x57\x34\x05\xc0\xc0\x6a\xbd\x8c\x67\x22\xea\x8d\x06\x36\x89\ \x48\xed\xbf\x00\xac\xef\x8a\x1f\xcb\x51\x5c\x62\x16\x4b\x15\x56\ \x74\x8d\xbd\xdb\xba\xd9\x5b\xef\x1e\x78\x2d\xf7\xbc\xdd\x32\x60\ \x7d\x3f\x07\x98\x5b\xfe\x1a\xe9\x2d\xb2\x50\x2d\x61\x52\x4d\x97\ \xde\x8d\xd3\xea\xe0\xf7\xfb\xf7\xe7\xcb\x1c\x19\x7b\xf0\xd0\x1d\ \xd4\x99\x0b\x4b\xbf\x0f\xb4\x7b\x3b\xea\x87\x77\x1e\xfe\xf6\xd2\ \xf5\x1f\x5f\x59\x78\xab\x70\x93\xff\xbd\xfd\x0d\xf6\xbd\x75\x1d\ \x3b\xea\x7e\x89\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \ \x00\x00\x04\x7f\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x18\x00\x00\x00\x18\x08\x06\x00\x00\x00\xe0\x77\x3d\xf8\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\x1b\xaf\x01\ \x5e\x1a\x91\x1c\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x01\x0a\ \x17\x02\x30\xf6\x73\x58\xfb\x00\x00\x03\xff\x49\x44\x41\x54\x48\ \xc7\xbd\x95\x6b\x4c\x9b\x75\x14\xc6\x9f\xb7\xd7\xc1\xe8\xe8\xca\ \x66\x3b\x4a\xc9\x80\x7a\x03\x5a\xca\x8c\x81\x99\x60\x5e\x37\x2e\ \x92\x2c\xd9\x07\x2c\x4a\xe4\x36\x32\x34\xc6\x84\x0c\xe2\x40\x12\ \x63\x5f\xb2\xa8\x89\x41\xe2\x52\xd6\x80\x51\xc1\x38\xa5\xc8\x75\ \x1b\x42\x3b\x88\x62\x59\x02\x6c\x0c\x07\x04\x4a\xe2\x56\x20\x8b\ \x5c\x02\x65\xa9\xb6\x89\xbc\x57\xbf\xa0\x21\x0a\x8c\x6e\xd1\xf3\ \xf9\x7f\xce\xef\xfc\x9f\x73\x9e\x1c\xe0\x3f\x0e\xe2\x51\xf3\x2a\ \x2a\x2a\x4c\x99\x99\x99\x65\xa1\xa1\xa1\xa9\x1c\xcf\xc9\xfc\x7e\ \xdf\xdd\x55\xef\x5a\x6b\x6d\x4f\xdd\xe5\x99\xb6\x19\xfa\xb1\x9a\ \xb2\x58\xde\x2b\x59\x5c\x5a\xa4\x39\x8e\x15\x7c\x3e\x9f\x30\x37\ \x3f\x27\xdc\x1e\x1f\x13\x3a\x3a\xdb\xf8\x8a\x77\xce\x59\x01\x48\ \xfe\x7a\x2c\xd9\x9a\x39\x38\x38\x28\x3c\xac\x7a\x4d\x4d\x8d\x3e\ \xf5\xf8\x0b\xf5\x52\xa9\x54\xca\x32\x1c\xc4\x12\x31\x5a\xed\x76\ \xbe\xa3\xa3\xc3\x73\xe7\xce\x44\x0f\xc3\x30\x76\x00\xc2\xb6\x80\ \x4d\xc8\xae\x00\x85\x62\xff\xe9\xf0\x70\x45\x08\xc7\x71\x60\x58\ \x1a\x04\x41\xa0\xb7\xcf\xf1\xf5\xad\x5b\x63\xd5\x14\x45\x2d\x92\ \x24\x79\x8e\x24\x49\x62\x47\x00\x00\x50\x14\xb5\xd3\x6c\xc4\x45\ \x45\xf9\x76\x8f\x67\x1e\x31\x31\x7a\x30\x0c\x03\x91\x58\x8c\x23\ \x1a\x8d\x1b\xc0\xf2\x76\x09\xa2\x20\xf5\x0f\x79\x36\x3e\xe1\x79\ \xb7\x7b\x06\x2c\xcb\x80\x65\x59\xb0\x0c\x8b\xc2\xc2\x82\xf4\xf8\ \xf8\x78\xe9\xd6\xc6\xaa\xaa\xaa\xc2\x83\x06\xa4\xa5\xa5\x3d\xa5\ \xd7\xc7\x45\x4b\xa5\x32\xb8\x67\xdc\x20\x08\x02\x2c\xcb\x20\x56\ \x1f\x97\x5e\x5c\x5c\xd0\x5b\x56\x56\x16\xbd\xbc\x7c\xff\xb9\xeb\ \xd7\x9d\x5f\x28\x0e\x84\x8d\x05\x0b\x20\x48\xf2\xc5\x53\x5a\xad\ \x96\xd0\x6a\xb5\xe8\xec\xea\xc6\x47\x1f\xd7\x82\x65\x59\xec\x93\ \xcb\x11\xa5\x8b\x3e\x19\xba\x3f\x64\x56\x1f\xf7\xcc\x58\x64\x64\ \x64\xc9\x90\x6b\xe8\x41\xb0\x00\x79\xa2\xc1\x98\x73\xf7\xde\x1c\ \x3a\xbb\x7b\x60\x3a\x76\x0c\x3d\x0e\x07\x26\xa7\xa6\x00\x01\xd0\ \xe9\x74\x08\x0b\x0b\x0b\x91\xed\x93\x11\x23\xa3\xa3\x6c\x7f\xff\ \x40\x4b\x30\x00\x82\xa2\xde\x37\x27\x9b\x4c\x46\x43\x42\x02\x7e\ \x5d\x5a\x82\x58\x24\x42\x6c\x4c\x0c\x5a\xdb\xdb\xc1\xf3\x3c\x94\ \x4a\x25\x08\x82\xc0\xac\x7b\x56\xa8\xae\xac\x76\xf2\x3c\xdf\xb2\ \xe3\x16\xfd\xb3\xb8\xcd\x66\xcd\x4b\x49\x39\xde\xb8\xb2\xb2\x02\ \x83\xc1\x80\xec\xac\x0c\xf4\x3a\x1c\x38\x1a\xa5\x85\x29\xc9\x08\ \x99\x5c\x86\xd5\xd5\x15\xac\x7b\xd7\x99\xd7\x2d\xf9\xdf\x33\x0c\ \x53\x0d\x60\x05\xdb\x78\x40\xa0\x28\xea\x6f\x93\x98\xcd\x66\x71\ \x73\xf3\x97\x96\xcb\xdf\x7e\xc3\x65\x65\x65\x09\x29\xa9\x29\x82\ \xcb\xe5\x12\x3c\x9e\x7b\xc2\x8f\x83\x3f\x70\x79\x79\xaf\xfd\xf6\ \x12\x49\xce\x91\x24\xe9\x12\x8b\xc5\x56\x00\x85\x9b\x66\xdd\xdd\ \x07\x00\x50\x52\x52\xa2\x38\x91\x71\xa2\x69\x7a\x6a\x3a\xc7\xe9\ \x74\x22\x42\x15\x01\x9d\x2e\x1a\x6a\x8d\x9a\xbf\x74\xc9\x76\xd3\ \x6a\xb5\x5e\xa3\x69\xfa\x36\x80\x39\x00\x6b\x00\xfc\x14\x45\x6d\ \x6c\xa6\x0b\xbb\x02\xca\xcb\xcb\xf5\xa6\x64\x43\x47\x5b\xeb\x77\ \xc6\xf1\xf1\x9f\xa1\x52\xa9\xc0\xb2\x2c\xce\x14\x17\x09\x36\x9b\ \xad\xeb\xe2\xa7\x17\x2b\x01\x2c\x00\xe0\x1e\xa6\xef\xbf\x00\x7e\ \xbf\x2f\xfb\xc9\xa7\xe3\x46\x6c\xb6\x86\x88\xf9\xf9\x05\x48\xa4\ \x12\xd0\x34\x8d\x97\xb3\xb3\x30\x39\x39\xe5\xda\x2c\xee\xd9\xeb\ \xea\x6d\x05\x48\xaf\x5e\xed\xae\x3e\xac\x3e\x7c\xad\xa1\xe1\x33\ \xc9\xda\xaa\x17\x22\x91\x08\x1c\xcb\x21\x29\x39\x09\xaa\x83\xaa\ \x5f\x4a\x4b\xdf\x38\xbf\x29\x09\x82\x02\xe8\xf5\x7a\x79\xd1\x99\ \xfc\x7a\xb5\x5a\x73\x76\x7a\x7a\x1a\x07\x14\x0a\xd0\x1b\x34\x02\ \x81\x00\xa2\xa2\xa2\x90\x71\x32\xdd\x5b\x79\xbe\xaa\x12\xc0\xf8\ \x56\x7d\xf7\x12\x22\x00\x78\xf3\xad\xd2\x2a\x8e\xe3\x72\x9b\x9a\ \xbf\x7a\xd7\xbb\xfe\xe0\x15\xf3\xab\xe6\xfb\x4a\xa5\x12\x5a\xad\ \x16\xc5\xc5\x85\x1b\x9f\xd4\xd6\x7d\xe0\xf5\x7a\xfb\xf6\xa2\xf9\ \xb6\x3f\x38\x14\x71\xc8\x7c\xa5\xeb\xca\xcd\xe1\x1b\xc3\x8d\xc3\ \x37\x86\x7d\x26\x43\x82\xc6\x68\x34\xd4\x27\x1a\x12\x79\x7b\x8b\ \xfd\xf3\xdc\xdc\xdc\x3a\x00\x75\x8f\x72\x9d\x24\x00\x20\x97\xcb\ \x7e\x57\x1f\xd1\xa8\x01\xa8\x01\xf8\xff\x60\x99\x27\x92\x93\x93\ \x04\x47\x9f\xa3\xdb\x62\xa9\x79\xfb\xb1\x6f\x72\x63\xa3\xad\x20\ \xfc\x60\x78\xd3\xe8\xc8\xe8\x08\x41\x10\x0b\x31\xb1\x47\x73\x7e\ \x1a\x1c\xea\x6f\x6f\xeb\x2c\x0b\x76\xa8\x3b\x1d\x7d\xd1\x85\x0f\ \x2f\x14\x31\x0c\x7d\x36\x10\x08\x10\x13\x13\x93\x3d\x03\xce\x81\ \x66\x00\x4b\xc1\x0e\xf5\x7f\x8f\x3f\x01\x2e\x51\xa3\xa9\xc7\xde\ \x69\x7b\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x04\x2c\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ \x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ \xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x2e\x23\x00\x00\ \x2e\x23\x01\x78\xa5\x3f\x76\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ \xde\x03\x0c\x12\x06\x08\xae\xb5\x4a\x3d\x00\x00\x03\xb9\x49\x44\ \x41\x54\x38\xcb\x5d\xcb\x5b\x4c\x5b\x75\x00\x07\xe0\xdf\xff\x9c\ \xd3\x9e\x76\x6d\x69\xc1\x52\x84\xca\x40\x2e\x16\xc7\x9d\x31\x67\ \x9c\x66\x03\x27\x73\x2f\x8a\x71\x2c\x12\x12\x12\x1f\xa6\x89\x2c\ \x73\xc9\x36\x37\x13\x6f\x0f\x5e\xa2\xcc\x88\x0f\xb8\x87\x3d\x78\ \x99\x09\x09\x4b\x34\xd1\x38\x86\x3a\xb9\x3a\x04\x06\x1d\x84\x6b\ \xa1\x2d\xd0\x0b\xa5\xed\xa1\x17\x7a\x4a\xdb\x73\xf3\xc9\x17\xbf\ \xf7\x8f\xe0\x7f\xea\x00\xac\xf6\x78\xb0\x7f\xb1\x10\x00\xd0\x07\ \x50\xbf\x9d\x69\x36\x15\x55\xd5\x3f\x22\xe6\xab\xcd\xac\xbc\x64\ \xcd\x65\x33\x82\x73\x79\x67\xa2\xa7\x7b\x36\xc8\xfc\x17\xaf\xff\ \x74\x15\xee\x73\x9f\xe3\xd9\xf0\x3e\xd5\x4e\xb4\xf2\xbb\x57\x3a\ \xcb\xac\x95\xcd\xaf\x2f\x14\x72\xf5\xad\x79\xe5\x15\xe1\x4c\xf2\ \xf1\xd8\xf4\x10\x76\x84\x2d\x18\x92\x31\xec\x39\x82\xc3\x25\x96\ \x83\x2d\x04\x00\x2e\x5f\xac\xc7\xf5\x1e\x3b\x00\xe0\x30\xa0\x39\ \xd6\xf5\xd2\x25\x5e\x6f\x7c\x7f\x6e\x88\x66\x6d\x2f\x04\x51\x7b\ \x54\xc0\xae\x5f\x40\x69\x41\x03\xbc\x53\x03\xd8\x18\xf7\x80\x4f\ \x88\x23\xb6\x23\xc5\x2d\x14\x00\x68\xee\xd8\x71\xfe\xe7\x5e\xb4\ \xb5\xe1\xc0\xe9\xdb\xbd\xb7\x72\x5a\xda\x3f\x76\xb8\xfd\x78\x30\ \xf5\x9d\x1c\xe7\xb6\x51\x7a\x92\x81\x62\x52\x63\xda\x31\x89\xb9\ \xbf\xfd\xf0\x2b\x40\xda\xc4\xc4\x3e\xb9\xb1\x92\xa1\x15\x1f\x8f\ \xc1\x6c\x99\x4a\xda\x1a\xe9\x12\x53\xd5\x37\x74\x9e\xa5\xa3\xb1\ \x22\x28\x91\x1c\x95\x8a\x11\x52\xe4\xe9\x4e\x03\x16\x07\x78\x84\ \x97\x05\x78\xe7\x37\x40\xcb\xe9\x8c\x56\x94\x69\xa3\x4a\xee\x9e\ \x73\x8a\x76\x82\xa1\x2f\x80\xa6\x77\xf0\xf5\xc4\xa7\x6f\xe9\x8a\ \x6d\xbd\xae\xe1\x11\x29\x15\x72\xd0\xc9\x1d\x0e\x12\x05\x04\xdc\ \x5e\x48\xfb\x09\xe8\xf2\x53\x70\xfc\xa9\xc8\x8f\xb2\x22\x65\xc8\ \xa2\x6f\x5c\x7b\xbe\xbc\xab\xf1\xa3\x15\x85\x00\xc0\xbc\x32\x9a\ \xfd\xfd\xef\x77\xdc\x81\x99\x87\x9a\x02\x36\xc2\xae\x8e\xfa\x90\ \x65\x12\x11\xe6\x62\x30\x9b\x4f\x23\xbb\xf0\x14\x84\x3d\x23\x7c\ \xbe\x10\x88\xb2\xb5\xb5\xe6\x2e\x6b\x5d\x9e\x79\xd3\xde\xda\x71\ \x93\xd0\x00\xf0\x58\x53\xcb\xb5\x8d\x91\x6f\x4f\x1d\x88\x6d\x52\ \xf6\xb1\x20\xd1\x54\x18\x91\x10\xd3\x38\x56\xdd\x83\x27\x6a\xda\ \x50\x5d\x57\x8b\xd1\x87\x01\x94\x54\x14\x2b\x12\x2c\xc6\xd2\x43\ \xe6\x8e\xe8\x5e\xcd\xf4\xc4\x1f\x17\x5c\x74\xdf\xe2\x6d\x53\x44\ \xc5\xf6\x4c\xf5\xf5\x9b\xa3\x7e\x9e\x98\x73\x68\x44\x96\x7d\x28\ \x50\xbf\x08\xe4\x34\xe1\xe5\xd6\x2a\xdc\x9b\x74\x81\x97\x15\x4c\ \xce\x7b\xc9\x92\x33\x44\x68\x8d\x5a\xa5\xa5\x94\x13\x14\x9e\xfa\ \x81\xa2\x8c\xf9\x15\x54\xc2\x63\x63\x58\x0d\x38\x5f\x1a\x9b\x0b\ \x31\x68\x24\x82\x38\x7d\x1c\x95\x35\x79\x90\x28\x1a\x87\x8f\x94\ \x40\x9d\x63\xc4\x1e\xab\x86\xd6\x92\x85\xcd\x9d\x38\x61\xb2\xb3\ \x8a\xac\xe5\xb9\x8d\x54\x38\xb0\x5e\xe4\x78\x30\x02\x29\x1e\x05\ \x51\x53\x90\x64\x05\xb1\x3d\x3d\x26\x96\x44\xc5\xbe\x16\x86\x27\ \x18\xc7\x36\xc7\x43\xaf\x67\x90\x7b\xd0\x0c\xc5\xa8\x03\xa3\xd3\ \x92\x86\xa3\x25\xe0\x79\xb1\x99\xe1\x9c\xc1\x48\x68\x66\x05\x11\ \x2f\x0f\x0d\x14\x68\x55\x04\x1a\x35\x03\x5a\x21\xc4\xee\xe4\x94\ \x8c\xd1\x43\x12\x94\x0a\x9b\xbc\x80\x24\xcb\x82\xe8\xb5\x60\x29\ \x82\xd5\xb5\x20\x64\x31\x93\x62\xaa\xa4\xe8\xfd\x1d\x83\xe5\x33\ \x29\x8f\xb7\xa6\x12\x9c\x64\xd0\xe8\x32\x3a\x2d\x1f\xdd\xd8\x4d\ \xbc\x1d\x88\xa4\x35\x26\x5e\x42\x43\xa5\x05\x87\x74\x5a\x0c\xaf\ \x85\x11\x57\x13\x45\xf0\xa4\xc9\xd2\xec\x3a\xb4\xa9\xf4\x10\x01\ \x80\xfb\xeb\x23\x54\x55\x7e\x21\x9d\xda\xf5\xca\xf7\x06\x26\xa9\ \xd7\x7e\xb9\x22\x9c\x4c\x5c\xfd\xd1\xa9\xb7\x75\xe8\x9f\xb4\x2a\ \x6f\x9c\xad\x23\x65\x16\x13\xb8\xfd\x0c\xee\x8e\xaf\x63\x6c\x70\ \x11\x8c\x2f\x3c\x4b\x85\x62\xc7\x19\xcf\xea\x2d\x7c\xf9\xd5\x7b\ \x68\xef\x1f\x93\x18\x0a\xd0\xab\x21\xb5\x7b\x40\x14\xe5\xf2\x85\ \x13\x67\x7e\x4d\x46\xf7\xd3\xe7\xc6\x1d\x1c\x5e\x6d\xb0\x60\x76\ \x4b\xc4\x6e\x28\x01\x46\x10\x97\x52\xf1\x54\xa7\x7f\xed\xc3\x04\ \x01\x00\x87\xeb\x2e\xb8\x40\x1c\xdb\xae\x05\xc4\xc2\x22\x3c\x3e\ \x2b\x3e\xe8\xee\x02\x00\x3c\xf7\xca\xcd\x4a\xc5\x64\x38\x5b\x5d\ \x5b\x58\xe0\xf2\x44\x64\xce\xbf\xfb\x17\xef\x0e\x0d\x2e\xff\x73\ \x29\xfa\xcc\xf9\x7e\xfc\x0b\x0b\xb9\xbe\x45\x31\x2c\x8e\xcb\x00\ \x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x0b\x2d\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\xb0\x00\x00\x00\x7f\x08\x06\x00\x00\x00\x4f\x09\x48\x3f\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\ \x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x02\x18\ \x13\x26\x10\x86\x4c\xd4\x8d\x00\x00\x0a\xad\x49\x44\x41\x54\x78\ \xda\xed\x9d\x7d\x8c\x1d\x55\x19\xc6\x9f\xf7\x9d\x33\xf7\x63\xb7\ \x1f\x6e\xb7\xdd\xb5\x95\xc6\xd6\xc0\xd6\xd6\x6a\xa2\x25\x01\x12\ \x04\x34\x90\x28\x84\x10\x44\x4c\xd0\x04\x63\x24\x8a\x46\x08\x06\ \x48\x34\x86\xc6\xe0\x3f\xc6\x36\x01\xb5\x2a\xa8\x21\x36\x18\x35\ \x40\x88\x04\x0d\x92\x6a\x88\x46\x0b\x28\x51\x12\x15\x0a\xc5\x02\ \x02\x02\x05\x04\xba\xed\xde\xbd\xf3\x71\x5e\xff\x98\x99\x7b\xe7\ \xde\xdd\x6d\x31\xa1\xdd\x1e\xf2\xfc\x9a\xec\xbd\xf7\xcc\x99\x33\ \x67\xde\xf3\xce\xdb\xe7\x9c\x39\x73\x46\xb0\xf9\x62\x4c\x24\xfb\ \x44\x44\x60\x66\x80\x88\x08\x00\x03\x04\x66\x02\xa0\x9f\x56\xfd\ \x06\xaa\x4f\xcc\xf7\xbb\xc8\x8d\xaa\x3c\xc0\xac\x97\x6e\xc5\x06\ \xf4\x8e\x37\x1f\xe5\xfe\xa8\xf6\xaf\xbe\xd7\xb7\xcf\x53\xe6\x82\ \xcc\x57\xc6\x82\x79\x01\x41\x59\x66\x45\x59\x0f\xe9\xfd\xb4\x81\ \x73\xb5\x21\x23\xf4\xce\x1b\xd6\x2b\x4b\x16\x38\x9c\x1d\xa1\xfc\ \x61\x9b\x0e\xec\x53\x1d\x7f\xc8\xce\xc3\x75\x9b\xb7\xdc\x5a\x79\ \x83\xb6\x34\xc0\x8e\xd0\x1e\xc3\xed\x32\x4f\x59\x73\xea\x5c\xb5\ \xf9\xe0\xf1\xac\x57\xa7\xa2\x5c\xab\x9f\xe2\xc0\xa7\x88\x95\x7e\ \x69\xb5\xa6\x32\x37\x99\x3e\x29\x28\x8c\x20\x65\x21\x52\x5a\x45\ \x00\x20\x95\x86\x66\x22\x6a\x88\xd4\x8b\xa8\x87\x8a\x8a\x89\xb7\ \x5a\xed\x04\x52\x54\x4a\x6a\xc7\x95\xfe\x4f\xe9\xa7\x19\x0c\xfd\ \x4b\x44\x06\x2f\x01\xab\xf6\x2e\x1a\xbe\xdf\xea\x65\xde\x5a\x9e\ \x7e\x99\xd5\xc9\xd7\x8e\x5b\x6b\xea\x7e\x8a\x00\x62\xb5\xbc\xf5\ \x63\x1e\xce\xc5\x16\xb8\x5c\x87\xeb\x62\xf3\xe7\x9f\x73\x2e\x75\ \x3b\x49\xbf\x61\x07\x6c\x66\x47\xb0\x47\xb9\x7d\x4e\xba\x2c\x74\ \x89\xc8\x3c\xdb\x0f\x93\xae\x35\x1b\x0d\xe5\x33\x18\x44\x8b\x8b\ \xa6\x7e\xec\xb9\x6d\x36\x84\xce\x3d\xaf\xd2\x1d\xca\xcd\x66\x5e\ \xc4\x14\xde\x14\xe6\x15\xde\x47\xe6\x7d\x6c\x89\x97\xca\xd3\x45\ \xac\x76\xb1\x9b\x99\x89\x2b\x9d\x5e\xfa\xad\x5c\x34\x73\x2a\x0d\ \x4d\xc5\xb9\x04\x91\xfb\xed\xce\x6f\xbf\xf3\xd1\xdd\x3f\xba\xb6\ \x3d\x32\x3a\xd2\x6c\xb6\xdb\x52\xbf\xb4\x08\x79\x93\x30\x33\x9b\ \xed\x76\x3a\x67\x9d\xf7\xe5\x1f\x3e\xfd\x9f\xfd\xcf\x9f\x7d\xe9\ \x95\x4f\xc7\x12\x65\xb1\xcf\xb2\x06\x52\x6f\x43\xf1\x1c\x22\x26\ \x13\x53\x5b\xb4\x8c\xb8\x10\x11\x4d\x10\x6b\x57\xe2\x28\x83\xc6\ \x3b\xbe\xf0\xbe\xef\x2d\x5b\x36\xb6\x42\x55\xe9\xb0\xe4\x98\xe3\ \xbd\xb7\x0f\x9e\x7b\xe5\x8e\xf5\x67\x7e\xfc\x4f\x0e\x79\xda\xb4\ \x34\x8f\x91\x7a\x00\xbe\x94\xb4\xa5\x03\x03\x02\x11\x4d\xcc\x69\ \xa6\xb1\xdb\x76\xdd\xd5\x93\xa3\x87\x1e\xdc\xde\x6a\xb6\xda\x34\ \x23\x59\x6c\x66\xbb\xb3\x9d\x99\xd1\x53\xae\xb9\xfa\x1b\xdb\x5f\ \x8c\x2d\xcb\x1a\x56\x38\x31\x44\x4c\xa5\x40\x53\xc4\x9a\x69\xec\ \xb6\x6f\xbd\x66\xf5\xb2\xce\x43\x37\xd2\x79\xc9\xf1\x42\xab\xd9\ \x6a\x2f\xed\x3c\x74\xe3\xf6\xad\xd7\xae\xce\x24\x76\xa9\x34\xb4\ \x54\xd5\xe2\x00\x88\x99\x49\xaa\xce\x75\xd0\x6c\x8d\x4c\xdf\xbf\ \x2d\x6e\xb5\xe3\x81\x50\x6e\xd2\x98\x9e\x7e\x6d\xb2\xd9\x1e\xcb\ \x0c\x12\x19\x8c\x92\x82\xbc\xe9\x08\xc4\x04\x96\x9f\xb0\x6e\xf3\ \xe3\xfb\x9f\xfd\xfb\xb8\x8a\x25\xd5\xb6\x38\x8e\xe3\xd1\xe9\xfb\ \xb7\x75\xa4\x79\x19\x80\xd9\x18\x69\x2a\x80\x38\x03\x24\x97\x58\ \x33\x44\xf1\xf7\x2f\xdf\xf4\x9d\x56\xab\xdd\xaa\xf7\x47\x73\x2f\ \x23\x99\xd7\xb1\xa5\xcb\x27\x56\x9f\x73\xee\xa5\x2b\x68\x66\x72\ \xb4\xd9\xfb\xc4\x63\xcb\x93\x5c\x0f\x39\xf5\xaf\x46\x6a\x33\x02\ \x78\x00\x68\xb5\xda\xad\x7f\xed\xba\xf5\xb4\x77\x9f\x7d\xc9\x1f\ \x33\x8b\x72\x27\x99\x39\x98\x49\xa2\xce\x25\x1a\x37\x96\x2f\x1f\ \x1b\xab\x17\x94\x7b\x19\x49\x32\xff\x8e\xf3\x2f\xbc\x6c\x3d\xcd\ \x4a\x8e\x15\x27\x9d\xb8\x61\xdd\x49\x27\x6e\xc0\x63\xfb\x9e\xb9\ \xef\xa9\x7f\xde\x3b\xe2\xd4\x0e\x56\xdb\x1e\xd8\x75\xd3\x17\x13\ \x8d\xff\xdc\x40\x96\xc5\x96\x7b\xcd\x24\x8e\x52\x38\x77\xfb\x0d\ \x5b\xd7\xd5\x47\x1b\xbc\x49\x23\xf3\x3a\x76\xfe\x85\x9f\xa3\xf3\ \x92\x45\x61\xc3\xbb\xd6\x7e\x68\x6c\xf5\xe6\xd4\x9b\x34\xaa\x34\ \x55\x95\xdb\x6f\xd8\xba\x2e\x81\x73\xa9\x45\x91\xe6\xa2\x9a\x8b\ \xc6\xfb\x1f\xb9\xed\xaa\x01\xe1\xbc\x64\x22\x1b\x1d\x5d\x3a\x49\ \x33\x92\x45\x1d\x81\x38\xf0\xdc\xe6\x89\x13\xde\xfb\x4a\x3d\x6d\ \x6a\xfd\xda\xc9\x1c\x1a\xe7\x1a\xa9\x7a\x88\x66\x88\xa2\xa9\x4d\ \xa7\xed\xab\x67\x3a\xf0\xda\x4b\x93\x67\x9d\x7d\xf1\x4a\x9a\x90\ \x2c\x26\x67\x7c\xf8\xa2\x55\xcf\x3e\xf5\x8f\xa9\x7a\xda\xfe\x27\ \x77\x9f\x92\x69\x14\x79\xa8\xaa\x41\x15\xb0\xe8\xe5\x17\xf6\x6e\ \xa9\x67\x32\x20\xa2\xf9\xc8\xf1\x80\x41\x06\x7c\xf1\xe5\x17\xf6\ \x6e\x11\x20\x32\x88\x2a\x20\x0a\x68\x24\x73\x76\x02\x87\xca\xc8\ \x71\xe2\xc0\x83\xc3\xb6\xe5\x34\xa9\xc8\x00\xd5\xb2\xcb\xa6\x34\ \x13\x09\xcc\xad\x15\x10\xa8\x07\x94\x93\x73\x48\x88\xba\xc2\x60\ \x45\x04\x7e\x23\xd3\x64\x09\x39\x9e\x28\x42\xae\x40\x21\xe5\x3f\ \x42\x42\x0a\xc0\x56\x4c\xfd\x55\x30\xfa\x92\x80\xd1\xaa\x57\x47\ \x48\xb0\x0e\x4c\x48\xd0\x0e\xcc\x4e\x1c\x09\xaf\x17\x57\x8f\xc0\ \xd4\x10\x24\xb8\x5e\x5c\xf1\x47\x8b\x47\xbf\x09\x09\x56\x42\x08\ \x07\x22\x48\x78\x0a\xa2\x37\x0e\x4c\x05\x41\x42\x54\x10\xbd\xf5\ \x24\x84\x9d\x38\x12\xb2\x84\x30\xce\x3b\x23\x81\x6b\x60\x42\x02\ \x14\x11\x00\x00\x57\xfb\x4e\x48\x68\xbd\xb8\xea\x4e\x1c\x3d\x98\ \x04\x18\x80\xcd\x2a\x07\xa6\x8c\x20\x21\x06\x60\xe1\x5c\x08\x12\ \x68\x00\xee\x0d\xa3\x31\x00\x93\x80\x61\x04\x26\x41\x0b\x61\x65\ \x1f\x8e\x04\xae\x81\xe9\xbd\x24\xc4\xd8\xdb\x93\x10\x14\xc0\x24\ \xc0\x08\xdc\x77\x60\xa3\x86\x20\x21\x6b\x60\x01\x97\x85\x20\xa1\ \xc6\x61\x3e\x52\x44\xc2\x8c\xbd\xe5\x2b\xbb\x78\x2b\x99\x84\x19\ \x7b\xcb\xf7\xcd\x15\x13\xda\x29\x21\x48\x88\x11\x18\x06\x35\x18\ \x25\x04\x09\x57\x03\x73\x55\x29\x12\xa8\xef\x02\x00\x6f\x64\x90\ \xb0\xd1\xe2\x95\xb3\x34\x04\x09\x52\x04\x83\x8b\xfb\x91\xa0\x35\ \x84\x82\x9d\x38\x12\xa8\xff\x5a\xff\x4e\x1c\xed\x41\x42\x93\x10\ \x80\x54\xb3\xd1\x18\x81\x09\x3b\x71\x84\x1c\x4b\x05\x51\x5f\x9d\ \x92\x01\x98\x04\xa7\x20\x7a\xcf\xc4\x71\x36\x25\x09\xb4\x13\xd7\ \x7f\xa4\x88\x1e\x4c\x02\xec\xc4\xf5\x1f\xab\xa7\x08\x26\x61\x7a\ \x30\x97\x57\x25\x41\x6b\x08\x4e\x68\x27\x61\x47\x61\x2e\x6c\x42\ \xc2\x8c\xbf\x52\x88\x08\xbe\x23\x83\x04\x2d\x22\xf8\x58\x3d\x09\ \x53\x3c\xf4\xd7\x46\xa3\x00\x26\x61\x4a\x88\x72\x18\x8d\x11\x98\ \x84\xd8\x7d\x63\x04\x26\x6f\x01\x0f\xe6\x30\x1a\x09\xb6\x07\xd7\ \x9b\x0f\x4c\x48\x88\x11\x58\x7a\x2f\x3a\xa4\x0f\x93\x00\x23\x30\ \x80\x62\x5d\x08\x42\x82\xd6\xc0\x84\x84\x0a\x3b\x71\x24\x6c\x09\ \xc1\x95\x79\x08\x25\x04\x21\xc7\x3a\x00\x0b\x1d\x98\xbc\x15\x34\ \x30\x47\x21\x48\xb8\x2a\xc2\x4a\x0d\x4c\x19\x4c\x82\xec\xc7\x09\ \x1f\x29\x22\x81\x46\x5f\xeb\xdd\x4a\xe6\xca\x3c\x24\xcc\x4e\x1c\ \x27\xb4\x93\xe0\x45\x04\x47\x21\x48\xd0\xf0\xa1\x4e\x12\xac\x06\ \xee\x3b\x30\x35\x30\x09\x50\x03\x17\x8f\xd5\x0b\x23\x30\x09\x35\ \x02\x0b\x1c\xa3\x2f\x09\x5c\x03\xd3\x83\x49\xb0\x71\x98\xc3\x68\ \x24\x54\x11\x5c\xfc\xe1\x30\x1a\x09\x35\xf8\xa2\xb6\x3e\x30\x21\ \x21\x47\x60\xaa\x08\x12\x5c\x04\xae\xad\x0f\xcc\x7e\x1c\x09\x2e\ \x00\x4b\x6d\x7d\x60\x42\xc2\x0c\xc0\x5c\x1f\x98\x04\x2e\x84\x29\ \x21\x48\xc0\x9d\x38\x4a\x08\x12\xac\x86\xe8\x4d\x68\x27\x24\xcc\ \x08\xcc\xb5\xd1\x48\xe8\x0a\x82\xaf\x9a\x25\x81\x2a\x88\xfa\x33\ \x71\xf4\x60\x12\x66\x14\xe6\x2b\x06\x48\xd0\x1a\x82\x9d\x38\x12\ \xac\x86\x28\xbc\x98\x0e\x4c\x42\xf6\x60\x3a\x30\x09\x55\x42\xf4\ \xe6\x42\x18\x87\xd1\x48\x80\x01\xb8\x17\x81\x85\x2b\xf3\x90\x00\ \x03\x30\x67\xa3\x91\xf0\x03\x30\x1d\x98\x04\x2d\x81\xe9\xc0\x24\ \xe8\x38\x4c\x07\x26\x01\x4b\x08\xe9\x8d\x03\xb3\x17\x47\x42\xd3\ \x10\x85\x17\x6b\xff\x17\x21\x61\xf9\x6f\x79\x27\x8e\xd1\x97\x04\ \x2a\x21\x00\xa8\x51\x42\x90\x10\x23\xf0\xe0\x8b\x0e\x29\x21\x48\ \x60\x11\xb8\xfc\xe4\x13\x19\x24\x60\x0d\x61\xd4\xc0\x24\x94\x0e\ \xdb\xdc\x54\x2b\x23\xb0\x61\xfe\xf7\x7d\xd3\xb3\xc9\xf1\xa6\x18\ \x00\x00\xde\x7b\x03\x60\x6a\xe6\x55\x01\x33\x83\x9d\x71\xde\x15\ \x77\xd4\x33\x29\x90\xd3\x6e\xe4\x38\x89\xc0\x03\xbe\x38\xdb\xed\ \xa6\x22\x30\x11\x81\x0a\xcc\x2b\x2c\xbf\x73\xe7\xd6\x73\x06\x1c\ \x58\x6d\xf6\x77\xbf\xf9\xe9\x4b\x34\x1f\x59\x4c\xee\xfc\xf9\xb6\ \xe9\x83\xaf\x3f\xbf\xa4\x9e\xb6\xf1\xd4\x4f\xef\x14\xb3\x5c\x60\ \x5e\x15\xde\x04\x96\x47\x6b\x3e\x72\x73\x3d\x93\x53\x1c\x9a\xed\ \x26\xfb\x69\x42\xb2\x98\x34\x47\xc6\xff\xbd\x62\xfc\xed\x4f\xd7\ \xd3\xfe\xf6\xe8\x13\xaf\xc2\x7c\xae\x30\x53\x35\xf3\x6a\x3e\xbf\ \xfc\xfa\xef\x3e\x57\x6a\x8b\x22\x02\x8b\x25\x1b\x37\x9f\xfe\xc0\ \x3d\x77\xef\xdc\x4b\x33\x92\xc5\xe0\x9e\xbb\x77\xee\xcd\xbb\x07\ \xba\x2a\x96\xd4\xf5\xef\xe5\xd7\xef\x78\x2e\x82\xe5\xe2\x73\xef\ \x14\xde\x3b\xe4\x59\x26\x3e\x7d\xe5\xd5\xff\x4e\xaf\x1a\x5f\xb9\ \xac\xca\xbc\x6f\xcf\xef\xd7\x6e\xd8\x74\xe6\x1f\x7e\x7d\xd7\x2d\ \x49\xd6\x3d\xb0\xf6\x82\x4f\x5c\xb5\x8c\x66\x25\x47\x9b\xbb\x6e\ \xbb\xf1\x80\x6b\x2e\x7b\x26\xef\x1e\xe8\x8e\x8c\x8e\xbe\x5c\xdf\ \xb6\xfe\x03\x97\xdc\x22\xb2\x3b\x75\x96\x67\x11\xbc\x97\x89\xa9\ \x2d\xed\xae\xb6\x1a\x33\x68\x8e\xa4\x1a\xbf\xed\x27\x57\xbe\xff\ \x9b\x23\xed\x76\x63\xa0\xd7\x67\xd2\xc8\x3c\x46\xbd\x97\x96\x07\ \x22\xf0\xce\x07\x39\x4a\xa3\x0d\x2a\xc8\x55\x6c\xd6\x29\x0e\xd5\ \x23\x2f\x00\x9c\x7e\xee\x15\x77\xac\x39\xe3\x92\xdd\xb1\xa5\xaf\ \x8d\xa0\x3b\xd3\xb4\x6e\xe2\x44\xc4\x9c\x4f\x33\xa7\x9a\x64\x16\ \x75\xee\xdb\xb7\xe2\x5b\xe7\x4c\xbd\xfe\x95\x46\xdc\x70\x75\x39\ \xd1\x88\x90\x20\xe2\xc8\x1a\x59\x1c\x92\x24\xc9\xbe\xba\xed\xc7\ \x7b\x04\x79\x27\x46\x9a\xc4\x96\x65\x02\x58\xb4\x64\xe5\x1a\x15\ \x31\x81\xa8\x18\x14\x7f\x7d\xfc\xa9\x74\x74\x7c\xe3\xc3\x6b\x97\ \x4e\x9f\x1a\xc7\x71\x44\xd3\x91\xc5\xe6\xf4\x8f\x7e\xe9\x8e\x9b\ \x7f\xf5\xc8\x2f\x6f\xbd\x7b\xd7\x8b\xb1\xe5\x87\x9a\xc8\x92\x18\ \x69\x06\x33\x2f\x13\x53\x5b\x62\x00\x9a\x8b\x73\x99\x38\xd7\x41\ \xa3\x9d\xaa\x5b\x62\x88\x96\xec\xf8\xec\x49\x5f\x5b\x39\x3e\xbe\ \x44\x79\xaf\x99\x2c\x02\xde\x0c\xab\x37\x5e\xb4\xf3\xcc\xcf\x5c\ \xbb\x47\x2c\x3f\x18\x23\x3f\xd8\xb6\x6e\x27\xb6\x2c\x53\xcb\x32\ \x00\x5e\x26\x36\x9c\xec\x60\xa6\x00\xd4\x8b\x8b\x52\x89\xe2\x0e\ \x1a\xcd\x5c\xdc\x48\x2e\x51\x1b\x86\xf6\x75\x9f\xff\xe4\xaa\x55\ \xe9\x5f\x2e\xbb\xe0\x53\xd7\xdd\xfb\xe0\xae\x9b\x3e\x46\xd3\x92\ \xa3\xc5\xc1\x99\x99\x64\xcd\x7b\x2e\xfe\xc5\x03\x0f\x3f\xf2\xfa\ \xd7\x7f\xf0\xb3\x17\x21\xd6\x89\x7c\xd6\x89\xe0\x67\xda\x98\xed\ \x3a\x9f\xa7\x91\xf8\x1c\x66\x1e\x80\x97\xc9\x0d\x27\x47\x06\xa8\ \x00\x62\x66\xa5\x13\x3b\x97\x41\x1a\x99\xc4\x8d\x0c\x51\xd3\x8b\ \x34\x0c\xda\x80\x21\x86\x48\x04\xb3\xa8\x5c\xa0\x15\x80\xf5\x9f\ \xcb\xaf\x22\x75\xf1\xbc\x47\x99\x86\xe2\x46\x60\xf5\x09\xab\xe5\ \x1b\xfa\xdd\x4b\xab\xa5\x57\x65\x49\x6d\x5b\xbd\xcc\xfa\x7e\xc3\ \xff\x51\xfc\xbf\xf9\x31\x5c\xd7\xc3\xec\x3b\x8c\x2c\x50\xce\x61\ \xbb\x2c\xf3\x94\x61\x43\xe5\xd9\x50\x61\x87\xab\x33\xde\xe0\x36\ \x1b\xb6\x79\xcd\xc6\x0b\xb5\xc3\x7c\x75\x96\x5a\x59\xc3\x65\x1e\ \xa9\x9c\x5e\xdd\xc4\x6a\x75\xcc\x61\x96\x43\x90\x8a\xe5\x89\x02\ \x49\x64\x79\xb7\x81\x2c\x89\xe0\x13\xe7\xd3\x2c\x42\x9e\x8b\x88\ \x07\x60\x66\xe6\x9d\x01\x26\x80\xb7\x62\x5e\x84\x57\xe4\x68\x5a\ \x6e\x0e\xea\x33\xf8\x34\x83\x26\x99\x45\xce\x24\x72\x06\x44\x30\ \x89\x00\xa8\x59\xb5\xa0\x44\x61\x75\x11\x81\xf9\xbe\x1f\xf7\x26\ \x57\xd8\xe0\xb9\x0e\x7e\x2f\xf6\x17\xab\xce\x65\xc8\xa6\x65\x9e\ \xaa\xec\x5e\xb9\x95\x2d\x7c\xbf\x71\xcc\xaa\x72\x6d\xc0\xeb\x44\ \x00\xf3\x55\x19\xe5\x67\xb5\xbf\xd5\x8e\x35\xec\x37\x56\x6b\x9f\ \x5a\xb9\xc5\x6e\x83\xe7\x8d\xb2\x4e\x3d\xdf\xab\x39\x5f\x6f\xbf\ \x7a\xda\xbc\xde\x55\xb4\x44\x71\x8e\x06\x29\xcd\x2b\x43\x4e\x5b\ \xd9\x01\x03\x36\x2c\x6b\x36\x5f\x1d\x50\x3f\xcf\xfe\xd5\x31\xc7\ \xf7\x06\xfc\x7b\xb0\xce\x03\xb6\xaf\xd5\xb9\xb7\x4f\xd9\x0e\x73\ \xeb\x76\xb8\x7a\x94\xf6\xab\xea\x6d\x30\x11\x78\x33\x9f\xab\x21\ \x57\x58\xe6\x90\x67\x11\xf2\xd4\xf9\x2c\x77\xe2\x73\x08\xbc\x41\ \xbc\x15\x05\x78\x11\xb1\xff\x01\xed\xeb\x89\x21\x3a\xe3\x55\x01\ \x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x02\x73\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ \x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ \x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\ \x01\x42\x28\x9b\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ \x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ \x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xf0\x49\x44\ \x41\x54\x38\x8d\xa5\x92\x4f\x6b\x1a\x61\x10\xc6\x7f\xae\x8a\x55\ \x8a\xed\xcd\x20\x14\xb2\x87\x88\x87\x42\x4d\x3c\x49\x3d\xec\x25\ \x64\x03\x7b\xc9\xc1\xdc\x3c\xf5\xb0\xb7\xc6\x9b\x5f\x20\x1f\x40\ \xea\xb9\x9f\xc0\xe0\xa9\x37\x21\x14\x12\x59\x58\xd8\x84\x42\xa1\ \xe0\x69\x89\x60\x4c\x2f\x49\xb5\xa8\xc4\x3f\xd3\x43\xde\xb5\x26\ \x48\x28\x74\xe0\x85\x79\x67\x9e\x79\x98\x99\x67\x42\x22\xc2\xff\ \x58\xe4\x99\x5c\x1a\x78\xa9\xfc\xdf\x40\x6f\x2d\x4a\x44\x56\xdf\ \x2b\x11\xd1\x45\x24\x6d\x59\xd6\x01\x70\x03\xdc\x58\x96\x75\x20\ \x22\x69\x11\xd9\x54\x98\x65\xcd\xa3\x62\xdb\xb6\x77\x43\xa1\x90\ \x97\x4a\xa5\x8e\x63\xb1\xd8\x09\x70\x09\x5c\xc6\x62\xb1\x93\x54\ \x2a\x75\x1c\x0e\x87\x1d\xdb\xb6\x77\x57\x49\x42\x2b\x3b\xd8\x8c\ \x46\xa3\x9f\x67\xb3\x59\x52\xb5\x3e\x01\xc6\x2a\x17\x07\x5e\x00\ \xa3\x48\x24\x72\x37\x9d\x4e\x3f\x00\x3e\x80\xb6\x32\xcd\x7d\xb9\ \x5c\xfe\x02\x0c\x81\x6b\xe0\x56\x91\x4c\x94\x7f\x0d\xfc\x52\x98\ \xfb\xa7\x4b\x4c\x97\x4a\xa5\x9d\x56\xab\xb5\xa5\x0a\x48\x26\x93\ \x77\x95\x4a\xe5\x1b\x40\xad\x56\x7b\x37\x18\x0c\x5e\x03\x34\x9b\ \xcd\xad\xe1\x70\xb8\xd3\x68\x34\x00\x7a\xc1\xfc\x19\xe0\x02\x68\ \x01\x4d\xa0\x59\xad\x56\x8f\x44\x64\x5b\x44\xb6\xab\xd5\xea\x51\ \x10\x57\x98\x0b\x11\xc9\x88\xc8\x5f\x19\x35\x4d\xfb\xb1\x58\x2c\ \x42\xc1\xbf\xdd\x6e\x0f\x80\xfe\x8a\x3f\x51\xa9\x89\xa6\x69\x3f\ \x97\x75\x81\xce\xae\xeb\x9e\x19\x86\xd1\x09\xe6\x76\x1c\x67\x5f\ \xd7\xf5\x43\x5d\xd7\x0f\x1d\xc7\xd9\x0f\xe2\x86\x61\x74\x5c\xd7\ \x3d\x53\xb7\xb1\x24\xe8\xe5\xf3\xf9\xd3\x6c\x36\x7b\x15\x00\xe7\ \xf3\xf9\xc0\xf7\xfd\x3d\xdf\xf7\xf7\xe6\xf3\x79\xd0\xc1\x24\x9b\ \xcd\x5e\xe5\xf3\xf9\x53\xd4\x61\x3d\x92\x31\x91\x48\x7c\x1c\x8f\ \x03\xe5\xd6\x5b\x3c\x1e\x67\x34\x1a\x7d\x62\x8d\x8c\xb7\x9e\xe7\ \xb9\xb9\x5c\xae\x5f\xaf\xd7\x3b\xa6\x69\x76\x79\xb8\x83\xb1\x69\ \x9a\xdd\x7a\xbd\xde\xc9\xe5\x72\x7d\xcf\xf3\x5c\x1e\x64\xe5\x69\ \x07\x00\x1b\xc0\x7b\xa0\xeb\x38\x4e\xba\x58\x2c\xbe\x05\x38\x3f\ \x3f\xff\x5e\x28\x14\x7a\xc0\x1b\xa0\x1d\x2c\x77\x1d\xc1\xaa\x65\ \x00\x43\xf9\x5f\x81\xce\x3a\xd0\x73\x04\xff\x64\x7f\x00\x19\x1e\ \x09\x5d\x0e\xd9\xff\x6d\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\ \x60\x82\ \x00\x00\x02\x4a\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ \x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ \x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\ \x01\x42\x28\x9b\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ \x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ \x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xc7\x49\x44\ \x41\x54\x38\x8d\xa5\x93\xcd\x6a\x1a\x61\x14\x86\x1f\x33\x0e\x05\ \x4d\x47\xda\x88\x64\x53\x14\x83\x43\x76\xc6\x95\x4c\x5d\xb9\x33\ \x05\x17\xdd\x64\x99\x45\x2e\x20\xbd\x82\x76\x51\x7a\x03\xbd\x82\ \x76\x93\x95\x0c\x82\x8b\xe2\x76\x32\xe8\x6a\x04\x85\x04\xa2\xd0\ \xa2\x14\x84\x80\xc5\x9f\x5a\xb5\xf0\xa5\xa7\x1b\x2d\x93\xa1\x29\ \x14\x0f\x9c\xcd\x39\xe7\x79\x39\x3f\xdf\x17\x12\x11\xb6\xb1\x9d\ \xad\xe8\x07\x04\x12\x40\x1a\x88\xfa\x62\x51\xe0\x60\x9d\xfb\xa7\ \xc0\x7e\x3e\x9f\x3f\xd6\x75\xfd\xa3\x6d\xdb\xe6\x1a\x8c\xda\xb6\ \x6d\xea\xba\xfe\x21\x9f\xcf\x1f\x03\xfb\xf7\x08\x11\xd9\x78\xc2\ \xb2\xac\x53\xa0\x0b\x5c\x69\x9a\x76\x59\xad\x56\x8f\xaa\xd5\xea\ \x91\xa6\x69\x97\xc0\x15\xd0\xb5\x2c\xeb\x54\x44\x12\x1b\x2e\xe4\ \x5b\x62\x3a\x95\x4a\xbd\x1f\x0c\x06\x4f\x00\x01\x1e\x85\xc3\xe1\ \x39\x80\x52\x6a\x17\xf8\x09\x84\x92\xc9\xe4\xb8\xdf\xef\xbf\x02\ \xbe\x04\x47\xb8\xf5\x3c\xef\x22\x93\xc9\x5c\x03\x0b\x60\xac\x94\ \xd2\x94\x52\x1a\x30\x06\x16\x99\x4c\xe6\xda\xf3\xbc\x0b\xe0\x76\ \x03\x85\x02\x67\x34\x46\xa3\xd1\x8b\x42\xa1\xf0\xbc\xd7\xeb\x3d\ \xf3\x27\x4c\xd3\xfc\xda\x68\x34\x9a\xf1\x78\xfc\x13\x30\x7b\x68\ \x89\x77\xad\x56\xab\xb7\x5c\x2e\xf7\xd6\x5d\xfc\xf1\xd5\x6a\xf5\ \xb4\xdd\x6e\x77\x81\x3b\x3f\xe0\xef\x20\x5a\xaf\xd7\x0f\xca\xe5\ \xf2\x6b\xa5\x94\x02\xe6\x01\xf1\x5d\x5d\xd7\xb5\x5a\xad\xf6\xae\ \x54\x2a\x7d\x06\x7e\x04\x05\xd2\xb1\x58\xec\xcd\x6c\x36\xfb\x05\ \x7c\x07\xc8\x66\xb3\xdf\x00\x3a\x9d\xce\xde\xba\xe6\xb1\x61\x18\ \x3b\xd3\xe9\xf4\xed\xdf\x96\x38\xaf\x54\x2a\xcd\x48\x24\x32\x04\ \x16\xb9\x5c\x6e\xe8\x38\xce\x8d\xe3\x38\x37\xb9\x5c\x6e\x08\x2c\ \x22\x91\xc8\xb0\x52\xa9\x34\xef\x75\xe7\x7b\x07\x88\xc8\xa1\xeb\ \xba\x67\xc5\x62\xf1\x7c\x32\x99\x9c\x88\x88\x21\x22\xc6\x64\x32\ \x39\x29\x16\x8b\xe7\xae\xeb\x9e\x89\xc8\xa1\x9f\x09\x0a\x20\x22\ \xa6\x88\xbc\x5c\xc3\x9b\x98\xb1\x8e\x99\xc1\xfa\xe0\x19\xff\xdb\ \xb6\xfe\x8d\xbf\x01\x7c\x52\x08\x38\x8e\xd7\x1d\xc8\x00\x00\x00\ \x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x03\x30\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ \x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ \x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0e\x4d\x00\x00\x0e\x9c\ \x01\xde\xf6\x9c\x57\x00\x00\x02\xd2\x49\x44\x41\x54\x38\x8d\x6d\ \x93\x4d\x68\x5c\x55\x14\x80\xbf\x73\xdf\x9b\xe9\xc4\x21\xcc\x4c\ \x4c\xc6\x2a\x22\xb6\xa9\x93\x44\x0c\xa3\x62\xc1\x2c\x14\x9d\xd2\ \x12\x35\x85\x52\x5a\x11\x6c\xa5\x1b\x71\x57\xe8\xce\xc5\x74\x37\ \x82\x2e\xa5\x4b\x05\xcb\x20\xc6\x45\xdd\x48\x4a\xf0\x27\xf1\x07\ \x69\xa4\x86\xc2\x98\xd0\xc4\x50\x14\x1a\x4d\x9b\x57\xf3\x63\xe0\ \xbd\xe4\xdd\xf7\xee\xbd\x2e\x06\xa7\xb1\x7a\x56\xe7\x1c\x38\x1f\ \x87\xc3\x77\x84\x7b\x62\x69\x69\xc9\x69\xad\xef\x6d\x03\x90\xcd\ \x66\xa9\x54\x2a\xb2\xbb\xe7\xef\x2e\x5a\xad\x96\xdb\xba\xd0\xc0\ \x9f\xbe\x8c\x12\xc1\xcb\x08\xce\x82\xb5\x0e\xa7\x1c\x5b\xcf\x8f\ \xd1\x6a\xb5\x5c\xb5\x5a\xed\x40\x3a\xc9\xcc\xcc\x8c\x53\xcd\x0b\ \xdc\xf7\xed\x57\x78\x22\x74\xed\xf5\x31\xeb\x16\x44\xf0\xef\x57\ \x6c\xdf\x4a\x30\xc6\x12\xd5\x0e\x63\x4e\x9f\x65\x64\x64\x44\x3a\ \x80\xe9\xe9\x69\xe7\x35\x3f\xa0\x77\x76\x8a\x6c\xc6\xc3\xf7\x05\ \x3f\xeb\xa1\x3c\x01\x0b\x56\x1c\x26\xb5\x24\x3b\x16\x9d\x1a\xd6\ \x0e\x1e\x22\x3d\xf5\x26\xb5\x5a\x4d\x64\x62\x62\xc2\x75\x7d\xfa\ \x11\xe5\xab\xdf\xb3\x99\x11\x36\x8d\x63\xef\x9e\x0c\x7b\xba\x3d\ \x82\x6d\x8b\x00\xbd\x5d\x42\x12\x59\x56\xa2\x04\x8b\xa3\x94\x3a\ \xf4\xb3\x2f\x12\xbf\x76\x06\x15\x04\x01\x3d\x3f\x7c\x83\x38\x21\ \x1e\x3d\xc6\xd8\x42\xc0\xce\xcb\x27\x59\x13\xc7\xa1\xd9\xdf\x79\ \xe1\xc7\xdf\x28\xbc\x7b\x91\x2b\x5b\x09\x47\x17\x02\x8e\xce\xdf\ \x22\x7f\xfe\x3d\xf4\x77\x5f\xb3\xba\xba\x8a\x0a\xc3\x10\x25\xa0\ \xb2\x42\xe1\xf1\xa7\xd8\xd9\xdc\xa0\xfb\x89\x2a\x6e\xbb\x7d\x9e\ \xcf\xde\x38\xc6\xc3\x07\x9f\x23\xdf\xdf\x0f\xc0\xf8\xe9\x93\x3c\ \xfd\xfa\x19\x36\x4a\xbd\x84\x61\xd8\x06\x58\x0b\x6b\x91\xa1\x6f\ \xb8\x4a\xeb\xd2\x38\xbd\x83\xc3\xfc\xa9\x0c\x69\x9a\xf2\xcc\x5b\ \xe7\xb8\x73\x63\x91\x70\xf9\x0f\xd2\x34\x25\xd7\x53\x20\x35\x06\ \x67\xcc\x5d\x80\x01\xee\x28\x45\x71\x7f\x85\x6b\x1f\x5f\xa4\x7b\ \x5f\x3f\xb7\xb7\x1c\x71\x1c\xb3\x7c\x6d\x96\x5c\xdf\x83\xa8\x62\ \x81\x38\x8e\x39\xf2\xce\xfb\xfc\xd4\xfc\x90\xe2\xe6\x3a\x51\x14\ \xe1\x87\x61\x48\x92\x18\xa2\x47\x2b\x58\xa5\x38\xde\xbc\x84\x01\ \x72\xfb\x0f\xa0\xb5\xe6\xe7\x4f\x9a\x0c\xbe\x7a\x0a\x3f\x5f\x44\ \x6b\xcd\xf8\x93\xfb\x18\x44\xe8\x43\xda\x1b\x44\x51\x84\x4e\x0c\ \xde\xc0\x10\x2b\x73\x2d\xa6\xce\xbf\xcd\xed\xeb\xf3\x94\x2a\x43\ \x68\xad\x39\xf1\xf9\x14\x37\xaf\x5e\x61\xe3\xfa\x3c\x5a\x6b\x4a\ \x0a\xf2\x16\x92\x24\x25\x8a\x22\xa4\x5e\xaf\xbb\x07\xa6\x26\xc9\ \x2d\x2d\xe0\x7b\x8a\x03\x39\x9f\x65\xe7\x40\x14\x4a\xb5\x45\xe9\ \x51\x0a\x27\x8e\x20\x4a\x29\x88\xa3\xa8\x60\xee\x91\x01\x56\x6a\ \xa3\x6d\x91\xea\xf5\xba\x2b\x7f\x39\x49\x75\xe5\x17\x24\x01\x25\ \x42\xae\xe0\x63\x22\x07\x80\x97\x17\xe2\xbf\x0c\xd6\x39\x5c\xc6\ \xd1\x7a\x68\x80\xd5\xc3\x2f\xd1\x68\x34\xa4\xa3\x72\xbd\x5e\x77\ \xe5\x2f\x2e\x33\xf8\xeb\x02\x9e\x08\xa2\xa4\x6d\xa2\x03\xac\xc3\ \xe2\x48\x8d\x63\xb1\x7f\x88\xe0\xc8\x2b\x34\x1a\x8d\xbb\x2a\xef\ \x86\x94\x26\x27\x78\x6c\x71\x0e\x2f\xeb\xe1\x2c\xe0\x40\x7c\x30\ \xb1\xe1\xc6\xd0\x30\xeb\xa3\x63\x9d\xe1\xff\x00\xfe\x81\x04\x41\ \xf0\xbf\xef\x5c\x2e\x97\xff\x35\x0c\xf0\x37\x5c\xfc\x53\xd5\x3a\ \x96\xb0\xec\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x20\x26\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\ \x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x02\x15\ \x0e\x23\x2f\xab\xc9\xe5\x0b\x00\x00\x00\x1d\x69\x54\x58\x74\x43\ \x6f\x6d\x6d\x65\x6e\x74\x00\x00\x00\x00\x00\x43\x72\x65\x61\x74\ \x65\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\x64\x2e\x65\x07\ \x00\x00\x1f\x7d\x49\x44\x41\x54\x78\xda\xcd\x9b\x69\x90\x5d\xd7\ \x71\xdf\x7f\x7d\xee\xfa\x96\xd9\x07\xc4\x00\x33\x18\x02\x03\xae\ \x22\x45\x53\x0b\x25\xd2\x91\x44\x53\x8a\x2d\x89\x91\x17\xad\xa4\ \x2c\x5b\x52\x12\xc9\xf1\x56\x72\xca\xa9\xe4\x4b\x2a\x1f\x52\x89\ \xbf\x38\x49\x39\x72\xe2\x4d\x92\x63\x4b\xb1\x55\x12\x4d\x49\xb4\ \xc5\x45\x24\x41\x10\xa0\x44\x09\x80\x28\x42\x22\x41\x12\xfb\x3a\ \x33\x00\x66\x06\xb3\xbf\xed\xde\x7b\x4e\xe7\xc3\xb9\x6f\x30\x00\ \x41\xed\x76\xe5\x56\xdd\x79\x6f\xee\xf6\x4e\xf7\xe9\xfe\x77\xf7\ \xff\xf4\x85\x1f\x73\x7b\xf1\xc5\x17\xf9\xff\x65\xfb\x49\xc6\x12\ \xfe\x34\x06\x70\xe0\xc0\x81\xde\x9e\x9e\x9e\x9f\x37\xc6\xbc\x4e\ \x44\x7a\x01\xfb\x8f\x24\x6b\xa0\xaa\xcb\xce\xb9\xef\xac\xac\xac\ \x3c\x7e\xf3\xcd\x37\x2f\xff\xa4\x0f\x94\x1f\xe7\xa6\x3d\x7b\xf6\ \x70\xfb\xed\xb7\x03\xf0\xf5\xaf\x7f\xbd\x32\x3a\x3a\x7a\x6f\xad\ \x56\xfb\x70\x14\x45\x37\x1b\x63\x22\x40\x45\x04\x91\x2b\x3f\xfe\ \xf2\xe3\xaa\xfa\x8a\xbf\xa5\xaa\xeb\xcf\x8b\x73\x2e\xcf\xf3\xfc\ \x40\xa3\xd1\xf8\xdc\xd4\xd4\xd4\x17\xde\xfc\xe6\x37\xb7\x2e\x1f\ \xd3\x3f\xea\xf6\xe0\x83\x0f\xae\x7d\x7f\xe0\x81\x07\x92\xe3\xc7\ \x8f\x7f\xe8\xdc\xb9\x73\xdf\x5c\x5c\x5c\x6c\xaf\x36\x1a\xda\x6c\ \xb5\xb4\xd5\x6e\x6b\xbb\xd3\xd1\x4e\xb9\x67\x59\xe6\xf7\x3c\xd7\ \x2c\xcf\x35\xcf\x73\x2d\x8a\x42\xf3\xa2\xf0\x9f\xeb\x8e\x67\x79\ \xbe\x76\x7d\xa7\xd3\xd1\x76\xbb\xad\xad\x56\x4b\x5b\xad\x96\x36\ \x5b\x2d\x5d\x5d\x5d\xd5\x85\x85\x85\xf6\xb9\x73\xe7\xbe\x79\xfc\ \xf8\xf1\x0f\x3d\xf0\xc0\x03\xc9\x95\xc6\xf6\x8f\xb2\xed\xd9\xb3\ \x67\xed\xfb\xfd\xf7\xdf\x9f\x1e\x3e\x7c\xf8\xdd\xd3\xd3\xd3\x7b\ \x16\x16\x16\x8a\x46\xa3\xa1\xed\x2c\xd3\x8e\xb5\x2e\x73\x4e\x73\ \xa7\x5a\xa8\xdf\x6d\xb9\xbb\x72\xbf\xd2\xe6\xd6\xed\xdd\xeb\x0b\ \x55\xcd\x55\x35\x73\x4e\x33\xe7\xb4\x63\xad\x6b\x67\x99\x36\x1a\ \x0d\x5d\x58\x58\x28\xa6\xa7\xa7\xf7\x1c\x3e\x7c\xf8\xdd\xf7\xdf\ \x7f\x7f\x7a\xa5\x31\xfe\x54\x5d\x60\xff\xfe\xfd\xbc\xe6\x35\xaf\ \x01\x60\xe7\xce\x9d\xb5\xcd\x9b\x37\xbf\xa5\x5e\xaf\xff\xa7\x4a\ \xb5\x7a\x47\x9a\x24\x88\x88\xae\x9c\x3c\xc1\xe2\xb1\xe3\x92\x35\ \x56\x41\x04\xb8\xd4\x0d\x8c\xc8\xda\x2f\x0a\x82\x5e\xb4\x73\x7f\ \x5c\x41\xfd\x1f\x7f\x4e\xb5\xbc\x46\x41\x95\xb8\x56\xa3\x6f\xfb\ \x76\xed\xdd\xba\x0d\x55\x95\x76\xa7\x43\xab\xd9\xfc\xd6\xea\xea\ \xea\x7f\x39\x7b\xf6\xec\x53\x77\xdd\x75\x57\xe3\xf2\xb1\xfe\x54\ \x14\xf0\xdd\xef\x7e\x97\x5b\x6f\xbd\xb5\xeb\xf3\xf5\x91\x91\x91\ \xb7\x56\xab\xd5\xff\x90\x56\x2a\xff\x2c\x89\x63\x44\x55\x57\xcf\ \x9c\x91\x43\x9f\xfe\x33\x0e\xff\xcd\xe7\x58\x99\x5d\xea\xca\xb3\ \xf6\xd9\xfd\x31\x53\xfe\xaf\x57\x18\x88\x00\xee\xb2\xeb\xd7\x3f\ \xa3\x77\x43\x1f\xd7\xfe\xda\x87\xb9\xfe\xe3\xbf\x45\x6d\xcb\x16\ \x45\x44\xda\xed\x36\xed\x76\xfb\xe9\x56\xab\xf5\x87\xe7\xcf\x9f\ \xdf\xf9\xa6\x37\xbd\x69\xf5\xf2\x31\xff\xd8\x0a\x78\xee\xb9\xe7\ \x00\xb8\xe5\x96\x5b\xba\xc2\xf7\x8c\x8c\x8c\xdc\x5d\xad\x56\x7f\ \x2f\x4d\xd3\x3b\x92\x24\x51\x50\x56\x4f\x9d\x92\x83\x9f\xfe\x14\ \x8b\x0f\xfd\x3d\x3d\x4b\x33\xf4\xd7\x13\x50\xc1\xb5\x1d\x61\xcd\ \x80\x03\x2d\x20\x88\x04\x13\x09\xae\x50\x34\x57\x4c\xc5\x5b\x84\ \x6d\x28\x26\x11\x24\x14\x5c\xee\x70\x05\x98\x00\x54\xa0\x58\x75\ \x04\x55\x03\xa2\x2c\xae\x76\x58\xe9\xbb\x8a\xfe\xbb\x7f\x89\xeb\ \x3f\xf6\x1b\xd4\xc7\xb7\xaa\x0a\x74\x3a\x1d\xe9\x74\x3a\xdf\x6a\ \x36\x9b\x9f\x3c\x77\xee\xdc\xc3\x6f\x7e\xf3\x9b\x57\xae\x34\xfe\ \x9f\x28\x0c\x3e\xf9\xe4\x93\x7d\x23\x23\x23\xbf\x52\xad\x56\xff\ \x4d\x9a\xa6\x77\xc4\x71\x8c\x3a\xc7\xea\x99\xd3\x1c\xfa\xf4\x9f\ \xb3\xf2\xe8\x57\xe9\x59\x9c\xa5\x1e\x45\x68\x0e\xa2\x10\x24\x01\ \x61\x2a\xa0\x82\x6d\x39\xd4\x2a\xd6\x2a\x88\x60\x52\x83\xa9\x88\ \x9f\xdd\x4c\xd1\x42\xa1\xf0\xf3\x6d\x22\x21\x48\x05\x54\x71\x99\ \x57\x1e\x02\xf5\x20\x86\xc5\x39\x56\x1e\xff\x2a\x07\x51\xae\xff\ \xd8\x6f\x52\x1f\x1f\x27\x8e\x63\x44\xe4\x0e\x11\x61\x64\x64\x24\ \x7d\xf2\xc9\x27\x1f\xb8\xeb\xae\xbb\x96\x7e\x22\x17\x58\x6f\x42\ \x4f\x3d\xf5\x54\xff\xe8\xe8\xe8\xfb\x2a\x95\xca\x47\x93\x24\xb9\ \x2d\x8a\xe3\x58\x40\x9b\x53\x53\xf2\xe2\xff\xfa\x24\xab\x3b\x1e\ \xa6\x67\x71\x81\x6a\x28\x84\x89\xc1\x84\x02\x4e\xd0\x8e\x12\xd6\ \x0d\x58\x50\xab\x98\x48\x30\xa1\x17\xc8\x15\x8a\x49\xbd\xe1\xdb\ \xa6\xc3\x24\x06\x13\x94\x16\x60\x15\x29\xa7\xa6\x68\x94\x96\x62\ \x14\x97\x2b\x79\xe6\x68\x5a\x65\xa5\x67\x80\xfa\xdb\xee\xe6\x55\ \x9f\xf8\x04\xd5\xd1\x31\x75\xaa\x92\x67\x59\x96\x65\xd9\xb7\x5b\ \xad\xd6\x5f\x4f\x4d\x4d\xdd\xff\x96\xb7\xbc\x65\xf1\x07\xb9\x83\ \xb9\xd2\xc1\xbd\x7b\xf7\xae\xdd\xb0\x7b\xf7\xee\xbe\x4d\x9b\x36\ \xbd\x2f\x49\x92\x8f\xc4\x71\xfc\xda\x30\x0c\x63\x13\x04\xb4\x67\ \xce\xf1\xfc\x27\xff\x88\x95\x47\x1e\xa2\x6f\x79\x81\x9a\x11\xa2\ \xc0\x10\xc6\x86\xb0\x12\x78\x45\x58\x10\x27\x88\x13\x0c\x42\x18\ \x1b\xa2\x6a\xf7\x9c\xc1\x38\x83\x71\x10\x60\x88\x12\x43\x54\xf3\ \x0a\x0c\xf0\xe7\xc5\x09\xc6\xf9\xfb\xc2\x34\xf0\xf7\x07\x86\x2a\ \x42\xef\xca\x02\x2b\x8f\x3e\xc4\x81\x4f\xfe\x11\xed\xf3\xe7\x08\ \xc2\x80\x28\x8a\xe2\x38\x8e\x5f\x9b\x24\xc9\x47\x36\x6d\xda\xf4\ \xbe\xdd\xbb\x77\xf7\x01\xdc\x7a\xeb\xad\xec\xdd\xbb\xf7\x87\xb3\ \x80\xf5\x09\xc5\x13\x4f\x3c\xd1\x3b\x36\x36\xf6\x9e\x5a\xad\xf6\ \xb1\x24\x49\x5e\x1b\x45\x51\x25\xae\x56\x59\x3a\x76\x4c\x5f\xf8\ \xe3\xff\x29\xab\x0f\xfd\x03\xfd\xed\x15\xfa\x7a\x22\x0c\x7e\xd6\ \x25\x10\x82\x48\xbc\xdf\xe7\x4a\x54\x37\xa8\x13\xef\xf3\x81\xf7\ \x73\xb5\x0a\x0e\x4c\xd5\xc3\x9b\x6d\x80\x09\x81\x40\xd0\x42\x51\ \xa7\x48\xe4\xcf\x15\x2b\x8a\x24\xa0\x06\x5c\xae\xa8\x55\x34\x00\ \xe7\x1c\xcb\xab\x39\x8b\x69\x2f\xb5\x77\xfe\x22\x37\xfd\xde\xbf\ \xd5\xde\xed\xdb\x25\x6b\x36\x29\xf2\xbc\xd5\xe9\x74\x9e\x6d\x34\ \x1a\x9f\x99\x9c\x9c\xfc\xf2\xdb\xde\xf6\xb6\xe5\x57\x4a\x96\xcc\ \xe5\x49\x4e\xf7\x82\xa7\x9f\x7e\xba\x3e\x3a\x3a\x7a\x77\xb5\x5a\ \xfd\x8d\x24\x49\x6e\x8b\xa2\xa8\x12\x55\xab\xcc\x1f\x3c\xa8\x2f\ \xfd\xe9\x9f\xc8\xfc\xfd\x5f\x64\xa0\xb9\x44\x5f\x35\x22\x4c\x02\ \x82\xc4\x60\x8c\x60\x1c\x48\xe1\xf7\x30\x31\x84\xa9\x21\xaa\x08\ \x41\x28\x88\x03\x32\x10\x2b\x04\x89\x10\x56\x84\x30\xed\x9e\x13\ \x24\x53\xc4\x79\xb0\x8c\xaa\x42\x58\x09\x30\xdd\x73\x16\xc4\x82\ \x09\x84\xa8\x62\x88\xd2\x80\xde\x34\x62\xa0\xb9\xc4\xfc\x97\xbf\ \xc0\x4b\x7f\xf6\x27\x32\x7f\xf0\xa0\x46\x95\x0a\x61\x14\x55\x92\ \x24\xb9\xad\x5a\xad\xfe\xc6\xe8\xe8\xe8\xdd\x4f\x3f\xfd\x74\x1d\ \xe0\xf6\xdb\x6f\x7f\x59\xb2\xb4\xa6\x80\x1d\x3b\x76\xf0\xae\x77\ \xbd\xab\x3b\xf3\xb5\xc1\xc1\xc1\xb7\x56\x2a\x95\x4f\x24\x49\x72\ \x47\x18\x86\xb1\x09\x43\x96\x8e\x1e\xd5\x43\x9f\xfe\x94\x9c\xfb\ \xec\xa7\xd9\x12\x5b\xfa\x7b\x52\x0c\x5e\x30\xb1\x42\x60\x84\x20\ \x36\x04\xa9\x21\x48\x0c\x62\x05\xca\x3d\x10\xf1\xca\xa8\x1b\xc2\ \x54\x10\xdb\xdd\x0d\x81\x7a\xd3\x8f\xea\x86\x30\x11\x8c\x0a\xe4\ \xfe\xb9\xc6\x79\x25\x45\x15\xe3\x5d\x47\x04\x0a\x4a\xb7\x32\xf4\ \xf7\x24\x6c\x49\x95\x73\x9f\xfd\x34\x47\x3e\xfd\x29\x59\x3a\x76\ \x4c\x4d\x10\x10\x86\x61\x9c\x24\xc9\x1d\x95\x4a\xe5\x13\x83\x83\ \x83\x6f\x7d\xe2\x89\x27\x6a\x00\xef\x7a\xd7\xbb\xd8\xb1\x63\xc7\ \x45\x17\xd8\xbd\x7b\x37\x00\x77\xde\x79\x27\x00\xf7\xdd\x77\x5f\ \x7a\xe3\x8d\x37\xbe\xb5\x56\xab\xfd\xc7\x4a\xa5\xf2\xb3\x69\x9a\ \x02\x68\x7b\x76\x96\xe7\xff\xfb\xff\x90\xa5\xaf\x7c\x81\x2d\xa9\ \xa3\xb7\x9e\xe0\x1c\xb8\x86\x62\x62\x81\x42\x08\x13\x21\xac\x1b\ \x4c\x22\x60\xa1\x98\x71\x04\x35\x0f\x82\x12\x42\xd8\x13\x10\x54\ \x05\xd7\x56\x8a\x79\x87\x24\x94\xb1\x4e\x09\x07\x0c\x92\x0a\xb6\ \xa9\x14\xcb\x16\xb5\x20\x06\x6c\x1b\x82\x61\x41\x02\xc5\x76\x94\ \x62\xc5\x61\x33\x07\x81\x0f\xa7\xa6\x06\xc6\x08\x4b\xab\x1d\xce\ \xb4\x84\xbe\x77\xdf\xc3\xab\x7f\xff\xdf\x69\xb2\x61\x18\x10\xe9\ \x74\x3a\xb4\x5a\xad\x6f\x36\x1a\x8d\x3f\x78\xe9\xa5\x97\x76\x7e\ \xe0\x03\x1f\x68\x97\xd8\xc6\x9d\x77\xde\x79\x29\x06\x7c\xe6\x33\ \x9f\x49\xde\xf0\x86\x37\xdc\x5d\xab\xd5\xfe\x7d\xa5\x52\xf1\x71\ \x5e\x95\xd6\xb9\x73\xf2\xd2\xff\xfe\x24\xcd\x47\x1e\x62\xb0\xb9\ \x44\x5f\x6f\xea\xfd\x59\x3d\xa2\x87\x35\x3f\xdb\x02\x98\xd8\x5b\ \x01\x16\xdc\xaa\x12\x0d\x1a\xb0\x3e\x22\x98\x54\xbc\x72\x3a\x8a\ \x6b\x83\xe9\xf3\x3f\x6f\x97\x1c\xa6\x66\x90\x08\x5c\x47\xd1\xcc\ \x63\x80\x33\x4a\x7e\xc1\x11\xf4\x79\x7c\xb0\x6d\x87\xcb\x14\x35\ \x8a\x0a\xd8\x86\x2b\xf1\x41\xb0\x99\x63\x69\xb9\xcd\x7c\xb5\x8f\ \xea\x3b\xfe\x05\x37\xfc\xee\x27\xa8\x6c\x1c\x51\x44\xe8\x74\x3a\ \xd2\x6e\xb7\xbf\xd5\x68\x34\xfe\xdb\xbe\x7d\xfb\x1e\xfe\xd8\xc7\ \x3e\xd6\xe9\x82\x7d\xd0\x15\xfe\xf3\x9f\xff\x7c\xed\x96\x5b\x6e\ \x79\x6f\xad\x56\xfb\xfd\x34\x4d\x6f\x4f\xd2\x04\x51\xa5\x71\xe6\ \x0c\x87\xff\xe2\x4f\xa5\xfd\xe4\xa3\x0c\x76\x96\xa9\x47\x31\x64\ \x52\x9a\xbe\x10\x24\x86\xb0\x62\x08\x22\x83\x58\xaf\x10\x29\x40\ \x72\x21\xac\x05\x04\x35\xe3\x7d\xdc\xfa\xe3\x74\x4a\x77\xa9\x1b\ \x82\x9a\xf8\x90\x59\x78\xa5\xd0\xf1\x85\xb4\x89\xbb\xe7\xfc\x73\ \x34\xf7\x80\xaa\x39\x98\x50\x08\x6a\x06\x91\x12\x4c\x73\x0f\x9c\ \xb6\x05\x49\x12\x12\x49\x87\xd5\xe9\x29\x96\x66\xe7\xe9\xb9\xe6\ \x5a\xe2\xde\x5e\x82\x20\x10\x60\x0b\xb0\x75\x78\x78\xb8\x71\xe7\ \x9d\x77\x1e\xfb\xd2\x97\xbe\x94\x7f\xfc\xe3\x1f\xf7\x0a\xd8\xb5\ \x6b\x57\xff\xf8\xf8\xf8\xfb\x6b\xb5\xda\x6f\x56\x2a\x95\x37\x24\ \x69\x2a\xa2\xaa\xab\xa7\x4f\xc9\xd1\xbf\xfc\x8c\x34\x1f\x7f\x84\ \xbe\xd5\x45\x6a\x12\x10\x88\x4f\x52\xc2\xd4\x20\x81\xf7\xd3\xc0\ \x78\x7f\x36\xf8\xe3\x41\x45\x08\x02\x41\xb2\xae\x80\xa5\xcf\xa6\ \x86\xb0\xba\xee\x98\xc1\x03\x63\x2e\x84\x55\x7f\x9f\x98\x12\x2c\ \xd5\x2b\xcd\xb5\x14\x53\xf7\x96\x23\x94\xd1\xc5\x51\x46\x19\x90\ \x58\x30\xb1\xf7\x24\x51\x21\x44\x30\xad\x16\xab\xa7\x27\x59\x5e\ \x5e\x91\xda\xb6\x09\x89\xfb\xfb\x35\x8c\x22\x11\x91\xcd\xc6\x98\ \xd1\x81\x81\x81\xce\xbd\xf7\xde\x7b\xe2\x4d\x6f\x7a\x53\xdb\x00\ \xd4\x6a\xb5\xb7\xa7\x69\xfa\x91\x24\x49\x5e\x1b\xc5\xb1\x41\x55\ \x57\x4f\x9f\x96\x63\x7f\xf5\x97\x34\xbf\xf6\x10\x3d\x0b\xf3\xd4\ \xc4\xc7\x64\x29\xe3\x79\x10\x1b\x82\xa8\x1c\xac\x05\x32\x45\x80\ \x20\x16\x6f\x11\x15\x03\xb9\x9f\x6d\x29\x04\x03\x84\xa9\x10\xf6\ \xfa\x88\x21\x19\x98\x42\x90\x5c\x30\x85\x10\xa4\xa6\x3c\xb7\x2e\ \x22\x14\x3e\xaa\x84\x69\x69\x65\xa9\xf1\x4a\xe8\x00\x85\x07\xc8\ \xa0\x74\xb9\x30\xf1\x2e\x69\x0a\xf1\x79\xc2\xd2\x02\xad\xc7\x1e\ \xe6\xf8\x67\xff\x92\xc6\xe9\xd3\x82\x53\x8d\xe2\xd8\x24\x49\xf2\ \xda\x34\x4d\x3f\x52\xab\xd5\xde\xde\x4d\x85\x0d\xf0\xfa\x28\x8a\ \x6e\x8a\xa2\x28\x0e\xc2\x90\xe5\x63\xc7\x38\xfe\x57\xff\x87\xd5\ \x47\x1e\xa4\x6f\x71\x9e\x5a\x1a\x12\xc6\x81\x0f\x71\x5a\x9a\x24\ \x3e\xdd\x35\x81\x1f\x84\x84\x7e\x76\xc8\x40\xb5\x74\x8f\x14\x82\ \xe4\xe2\x71\xc9\xbc\xcf\x4b\xee\x05\x36\x55\x01\x2d\x5d\xa6\x34\ \x7f\x29\x84\x20\x02\x62\x5f\x2d\x9a\x96\x81\x36\xa8\x51\xc8\x7c\ \x2e\x61\x22\xc1\xa1\x60\x9d\x77\x0d\x29\x9f\x6f\xf0\x96\x47\x40\ \xcd\x29\x6e\xfe\x02\xcb\x0f\x3d\xc8\x51\x07\x13\x1f\xfd\x57\xf4\ \x4c\x6c\x27\x8a\xa2\xb8\x28\x8a\x9b\x80\xd7\x03\x7f\x17\x02\x71\ \x51\x14\x7d\x22\x12\x19\x63\x40\x44\xdb\x27\x4f\xca\xfc\xdf\x7d\ \x91\xe1\xa2\x45\x3d\x8e\x09\x23\x1f\x8f\x8d\x08\xb4\x0a\x74\x39\ \x43\xe3\xd2\x4c\x43\x90\x24\xc2\x44\x31\x14\xa1\x9f\x71\x01\x71\ \xbe\xc0\x09\x2a\x5e\x68\x2d\x1c\x34\xdb\xd0\x74\x5e\x71\xc9\xc5\ \xf2\x58\x0a\x41\x0b\x01\xe3\x43\x1b\x49\x80\xd4\x0c\x8a\xa2\x2b\ \xde\xc7\xc5\x78\x1c\x30\x36\x83\xb8\x40\x2d\x68\xcb\xa2\x4e\x71\ \x01\xd8\x86\x85\x48\x90\x54\x10\x15\x02\x31\xd4\xa3\x00\x5d\x9c\ \xe3\xc2\xdf\x7d\x91\xd6\xcf\xdd\x25\x3d\xd7\x5c\xa3\xc6\x18\x11\ \x91\xa8\x28\x8a\x3e\x20\x0e\x81\x38\xcb\x32\x51\xf5\xc4\x93\x82\ \x84\xed\x26\xfd\x0b\xf3\xf4\x8e\x0c\x60\xd4\x9b\x96\xcf\xe7\x0b\ \xc2\xc1\x61\xd2\x89\x09\xa2\x81\x3a\xb8\xb2\xc4\x35\x19\x6e\x7a\ \x1a\x37\x77\x01\x43\x41\x90\x78\xd3\x27\x2f\x77\xeb\x08\x7a\x87\ \x08\xb6\x6c\xc1\x0c\xf4\x41\xe1\x6f\x34\xf5\xb2\x34\x9e\x2f\x50\ \xcd\x20\x6b\xe1\x66\xe7\x71\xf3\x0b\x68\x2b\x47\x82\x32\x1d\xae\ \x7b\x73\x93\xb4\x8a\x6c\xbc\x0e\x33\xba\x09\x57\x14\xc4\xab\x0e\ \x35\x40\x00\x45\xcb\xe2\x6c\x81\xda\x36\xf9\xe2\x22\x3a\x3d\x8b\ \x2e\x2e\xd0\x5b\x8d\x29\xce\xcf\x13\xb6\x5b\x94\x46\x8b\xaa\x6a\ \x96\x65\x02\x44\x21\x10\xe4\x79\x1e\x38\xe7\xa4\xcb\xbf\xc5\x81\ \xa1\xaf\x16\x78\x40\x52\xef\x6f\xea\x14\xbb\xda\xa6\xfe\xd6\xdb\ \xd9\xf4\x5f\xff\x80\x78\xf3\x96\xb5\xba\xbd\x38\x7f\x96\xe5\x4f\ \xfd\x39\xd9\xce\xbf\xc7\xb4\x67\x30\x95\x08\xb1\x06\xb7\x02\x18\ \x41\xdb\x16\xee\xb8\x85\xe4\x77\x7e\x9f\xf8\x96\x9f\x59\x47\x84\ \xf8\x64\x5c\x5b\x0d\x74\xf9\x02\x6e\x6e\x0a\xfb\xec\x33\xe4\x4f\ \xee\xc2\x1e\x3e\x88\x5b\x6d\xf9\x7a\x22\x35\x38\x2d\x30\x9b\x46\ \xa8\x7e\xe8\xb7\xa9\xbd\xf3\xfd\x5c\x89\x45\xb4\xab\xab\xe4\x67\ \xa7\x69\xbf\x74\x80\x95\xa7\x76\xb1\xfa\xf4\x4e\xb2\xb9\x19\xfa\ \xeb\x01\x49\x68\xd6\xf8\x45\xe7\x9c\xe4\x79\x1e\x00\x61\x57\x01\ \x62\xad\x5d\x77\x81\xa2\x0e\xcf\xd9\xa8\xf7\xb9\x30\x16\x6c\x54\ \x25\xdc\xb6\x95\x78\xf3\x96\x4b\x0a\x09\x73\xd5\x46\x82\x6d\x5b\ \xa1\xa7\x17\x6d\xcc\xf8\x4a\xb0\x4c\x5b\x83\x41\xa1\xdd\x50\x5a\ \x81\x12\xa9\x12\x5f\x46\x92\xa0\x20\x95\x1a\xa6\x52\x23\xd8\x38\ \x4e\x78\xd3\x1d\x84\x3f\x77\x37\xd9\xfd\x7f\x41\xbe\xeb\x61\xf4\ \x78\x03\x71\xe0\x54\xc8\x33\x25\x2a\xf4\x15\xcb\xd8\xb0\x5e\x27\ \xbc\xf6\x3a\x2a\xd7\x5e\x47\xcf\x5b\x7f\x81\xe5\x1d\x0f\x73\xfe\ \xcf\xff\x98\x7c\xe1\x19\x9c\x73\x6b\xf2\x59\x6b\xc9\xf3\x5c\x80\ \xc0\x5c\x89\x95\x55\xa7\x68\x07\x5c\xc7\x97\xad\x18\x50\x57\x10\ \x5d\x37\x41\x72\xc3\x75\x2f\xe7\xaa\xc5\x10\x6d\x1b\xc7\x0c\x6f\ \xc4\xb5\x42\xdc\xac\x43\x97\x94\xa0\xcf\x63\x84\x8b\xa1\x48\x15\ \x17\xac\x11\x5c\xa8\xb5\x74\x1a\xab\x74\x9a\xab\x14\xad\x16\xea\ \xdc\x9a\x60\xc1\xe6\xad\x84\xef\xb8\x07\x19\xdb\x82\xe9\x0d\xb0\ \xf3\x8a\x9d\x71\xe4\x8b\x0e\xdb\xd1\x4b\x18\x63\xe7\x1c\xce\x59\ \x5c\x79\xff\x7a\x65\xf4\xbd\xfd\x5d\xf4\xbe\xfd\x97\x09\x7a\x36\ \x78\x17\x5e\xc7\x30\x77\x3f\xc3\x4b\x14\x50\x5e\x20\x02\x12\x81\ \x89\x7d\xfc\x56\x0b\x2e\xcb\x49\xb6\x6c\x27\xdc\x76\xed\x95\xcb\ \xca\x8d\x63\x98\xf1\xab\xe1\xe4\x0b\x04\xd9\xaa\x0f\x57\x6d\xa0\ \xe2\x93\x1f\xb2\x92\xef\x2a\x85\x6c\x2e\x2d\x70\xe0\xef\xef\xc7\ \x39\x4b\xda\x3b\xc0\xc6\x57\xdd\xcc\xf0\xc4\x35\xc4\x95\x2a\x12\ \x04\x04\x9b\xae\xc6\x8d\xbf\x0a\xf7\x9d\x93\x04\xbd\x0e\x75\x86\ \xa2\x66\x20\x94\xf5\x9c\x39\xf3\xa7\x4f\x32\x7f\xfa\x14\xce\x39\ \xea\xc3\x1b\xe8\xdf\x3c\x4a\xb5\x7f\x00\x63\x0c\x26\xad\x30\xf0\ \xcb\xef\x66\xe1\xe1\x87\x20\x0a\xd7\x94\xbc\x5e\x11\x21\x50\x6a\ \xd1\xa1\x5a\x2a\xc3\xf8\x8c\x4b\x82\x92\xd4\xb4\x8a\xd3\x80\x78\ \x6c\x2b\xe9\xd8\x38\x00\xce\x5a\xb2\x56\x8b\xb8\x52\xc1\x04\x01\ \xe1\xc6\x51\xc2\xf1\x71\x8a\x81\x3a\x2c\xad\x22\x2a\xb0\x02\xb4\ \x15\x6d\xe3\x51\x7e\x9d\xa1\xe5\x8b\x0b\x5c\xf8\xca\xe7\x20\xcf\ \x28\xf2\x80\xe5\xdb\x6f\xc3\xdc\xf3\x51\x46\x5e\xfd\x7a\x7f\x41\ \x94\x90\x0f\x6e\x01\x35\x44\x69\xc9\x2b\x24\xc6\x87\xdb\x35\x4b\ \x75\x4c\x7f\xeb\x29\x0e\x7f\xf9\xf3\x34\xe6\xe6\x49\x37\x6f\x63\ \xeb\x3f\x7f\x07\xd7\xbf\xf3\x9d\xf4\x8f\x6c\x46\x44\xa8\x4c\x5c\ \x43\xb4\x6d\x2b\x54\x52\xaf\x00\xbd\x68\x39\x6b\x0a\x58\xf3\xff\ \x2e\x07\x6b\x3d\x45\xe5\x72\xc5\x00\x06\x87\xd9\x34\x42\xb2\x75\ \x1b\x51\x5f\x3f\x00\x59\xb3\xc9\xd9\x03\xcf\x33\x34\x31\x41\x7d\ \xc3\x55\x44\x3d\x75\xc2\x4d\xe3\x14\xb5\x21\xf4\xdc\x39\x1c\xea\ \x79\x81\x58\x7c\x9c\x0f\x29\x99\x62\xaf\x87\x48\x0b\xb6\x15\x33\ \x24\x45\x46\x73\x36\x23\x7b\x21\xc6\x4e\x4f\x52\xdc\xf4\x3a\x42\ \xe3\x73\x80\x4e\x1c\x11\x05\xa0\x2d\x87\x16\x0e\xd7\xe3\xc0\xae\ \x77\x57\x25\x9a\x9b\xa3\xff\xe8\x11\xa2\xc9\xb3\x74\x4e\x9c\xe2\ \x82\x38\xe6\xc6\xc7\xe8\x1f\xd9\xbc\xce\xa5\xc6\xd0\xb4\xba\x26\ \x63\x17\x07\x5e\xa6\x80\xf5\x2c\xb5\xb3\x0a\xae\x54\x88\x58\xc2\ \xed\xdb\x09\xb7\x8c\x23\x71\xe4\x15\xb0\xba\xc2\xe4\x53\x4f\x42\ \x91\x53\xe9\xeb\x27\x4a\x53\xcc\xc6\x51\x18\x1e\xc3\x1d\x3a\x84\ \xb1\x0e\x8d\xd5\xc7\x65\x2b\x10\xc0\x3a\x92\x9b\x00\x65\xb4\x2a\ \xd4\x9c\x21\x6f\xa5\xac\xf6\x0e\x10\x26\xd5\x35\x23\x51\x55\x5a\ \x8b\xe7\x09\x70\xb8\x0e\x3e\xee\x77\x4a\xee\xb0\x0b\xa2\x0a\x3d\ \x61\xc4\xd5\xd5\x1a\x59\xb5\xce\xaa\x16\x64\xe7\x4f\x53\x4c\x9d\ \x59\x7b\x86\x88\xe0\x7a\xfa\x21\x8a\xbc\x60\xe5\xf1\x4b\x14\xd0\ \x45\xc8\xf5\x3c\x91\x04\xa5\x0b\x38\xc1\x59\x88\xc6\x27\x08\x47\ \x46\x51\x13\xe0\x54\xc9\x97\x16\x59\xd9\xfb\x14\x0b\x3d\x3d\x8c\ \xdc\xf2\x33\x84\x69\x8a\x8c\x8c\x22\xdb\x26\xd0\xef\x7d\x1d\x69\ \xb4\xd0\x1c\x5c\x53\x71\x6d\xc5\x15\x0e\x67\x1d\x0a\x38\x55\x88\ \x12\x64\xe2\x67\xb0\x6a\x91\xb1\x0a\xb5\x5b\xdf\x88\xd9\x3a\x81\ \x31\x82\x05\x5a\x17\xe6\x68\x1f\x3c\x44\x3d\x2b\x90\x44\x20\x14\ \x24\x16\x54\xbc\x1a\x7d\xa4\x72\x88\x58\xc2\xc8\x4b\xd2\x53\x80\ \x86\x29\xf5\x4a\xa5\xbc\xc6\x21\x41\x40\x3b\xeb\x90\xd8\xe2\xe2\ \x04\x5c\xee\x02\x97\xad\xbf\x79\x0c\x08\x40\x4a\x53\xd4\xb0\x4a\ \x3c\xba\x95\x70\x70\x08\x44\xc8\xda\x6d\x9a\x67\x27\x89\x8e\xbd\ \x48\x3e\x36\x81\x6d\xb6\x70\x7d\xfd\x04\x57\x6d\x24\xd8\xba\x15\ \xdb\x57\x41\x8a\x16\x7a\x41\xb1\x40\xd1\xf6\x4a\x50\xa7\x9e\xf7\ \xb7\x05\x66\xe8\x2a\xa2\x8f\xfd\x67\x54\x14\x89\xab\x04\xbd\x7d\ \x48\xad\x8e\x5a\xcb\xca\xec\x0c\xd3\x5f\xdf\x05\x07\x8f\x20\xb9\ \x85\xbe\xb2\x68\x4a\x14\x0d\xfd\x33\x9c\x3a\x54\x1d\x84\x01\x54\ \x62\x4c\x5f\x42\xa0\x75\xa2\x89\x9b\xa8\x4e\x5c\x8b\x2d\x31\xc2\ \x04\x01\xad\xf3\xd3\x04\xad\x66\xb9\x18\xa3\x2f\x07\xc1\xae\x39\ \xac\x73\x2d\x9c\x53\x9c\x2a\x62\x95\x60\xeb\x16\xc2\xb1\x51\x24\ \x4d\x51\xa0\x39\x7f\x81\xd9\xfd\xcf\x30\x94\x77\x60\xf2\x0c\x8d\ \xd9\xf3\x04\x83\x83\x04\x49\x42\xb0\x61\x33\xb2\x61\x0b\x6e\x66\ \x1e\x50\x82\x01\xc1\x34\x58\xe3\xf1\x1c\xe0\xac\x83\x30\x46\xae\ \xbe\xc6\x27\x42\xea\xf1\x41\x8c\xa1\xbd\xba\xca\xf4\xb3\x7b\x39\ \xf5\xe0\xff\xe5\x3a\xbd\x80\x29\x7c\x14\xc2\xe9\x1a\x9b\xec\x95\ \xe8\xad\x36\x1c\xd9\x0c\x37\xdd\x8a\x1b\x6f\x52\x7f\xcd\xcf\x52\ \xb9\xeb\xe7\x89\xb7\x4d\xe0\xb2\x0c\x55\xa5\x68\xb7\x29\x26\x27\ \xa1\xd9\xf2\x18\x54\x0a\x7e\x65\x17\xd0\x8b\x20\x68\xdb\x8a\x69\ \x3b\x50\x25\xda\xba\x0d\xd9\xb4\x19\x17\x45\x38\xa0\x7d\xe1\x02\ \x17\xf6\x7c\x9b\xcd\x0d\xa1\x68\x2e\xb0\x78\xe2\x08\xc9\xe8\x18\ \x95\x38\xc1\xf6\x5f\x45\x67\xf8\x7a\xcc\xdc\xb3\xa4\x83\xa1\x1f\ \xac\x51\x48\x1c\x4e\x1c\xb6\x34\xdd\x35\xb0\x59\xf3\x39\x1f\x59\ \x82\xb4\xc2\xf8\xeb\xdf\xc8\x55\xed\x0f\x23\x5f\xf8\x33\x68\xcf\ \x52\xcc\x5a\xb2\x8e\x23\x37\x8e\xb8\x65\x4b\x25\xfa\xc5\x82\x9e\ \x9f\x7b\x27\xbc\xe5\x17\x3c\x28\x18\x03\x81\x41\xad\xc3\x8a\xa0\ \x45\xc1\x91\x5d\x4f\xd2\x38\x72\x9c\x81\xac\xc0\x18\xb3\x86\x77\ \x97\xb8\xc0\xe5\x18\x20\xe2\xab\x3b\x89\x05\xd4\x10\x8f\x6d\x25\ \xda\x30\x82\x44\x31\xce\x29\xc5\xfc\x2c\xee\xe0\x77\x08\x22\x47\ \xfb\xdc\x0c\xed\x63\x47\xb0\xaf\xb9\x0d\xed\x1b\x20\xd8\xb8\x91\ \xe8\xd5\x37\x52\x3c\xea\x17\x43\x24\x16\x6c\xc7\x2b\xd4\x59\xb7\ \x06\x60\x9d\x95\x65\x26\x9f\xfd\x36\xea\x2c\x51\xa5\x4e\xff\xf8\ \x38\xd5\xa1\x61\xc2\x38\x26\xe8\x1d\xa0\xf2\xc6\xb7\xd2\x39\x7d\ \x92\xe2\xc4\x17\xa0\xa7\x8d\xa9\x0b\x52\xf7\x96\xa4\xeb\x73\x97\ \x20\x44\xa2\xe8\xb2\xfc\x52\xb1\x79\xce\xd2\xd4\x24\xa7\xbf\xfa\ \x65\xc2\xe9\xd3\x04\x5d\x8e\xed\x95\x30\xe0\x12\x96\x5c\x00\xe3\ \x57\x70\x64\x68\x98\x68\xcb\x38\xa6\x56\x03\x11\x3a\x8d\x06\xf9\ \xf2\x12\x7d\x7d\xbd\x44\x1b\x37\x12\x65\x06\x1a\x6d\x5c\x27\xc3\ \xda\x02\x53\xeb\x21\xbe\x7a\x2b\xf9\x55\x43\xd8\xe3\x17\x10\xe3\ \x28\x5a\xea\xa9\x2c\xab\xde\x77\x81\xe6\xcc\x0c\x2f\x7c\xf2\x0f\ \x21\xcf\x50\x0c\xf5\x1b\xaf\x63\xfc\x17\xee\x66\xec\xb6\x37\x51\ \x19\x18\x42\xeb\xfd\xd8\x57\xbd\x91\x9c\xfb\x89\xa2\x32\x22\x45\ \x0a\x81\x4f\xd5\xbb\x02\xd8\xa2\x83\x2d\x0a\xbf\x8a\x64\x1d\x45\ \x96\xd1\x59\x5d\xe1\xc2\xb1\x63\x9c\x7a\xf4\x61\xec\xd3\xbb\xa9\ \xb5\x57\x09\x4c\x77\x61\x56\x5e\x9e\x09\x5e\xb4\x80\x75\x28\x59\ \x28\xce\x7a\x1f\x0b\xb6\x6c\x81\x24\xc6\x15\x05\x36\xcf\x48\xc7\ \xc6\xd9\xfc\xaf\x7f\x97\x38\x8a\x89\x73\x07\xa3\x63\x98\x4a\x15\ \x9b\xe7\xbe\x2c\xee\x1f\xc6\x4e\xdc\x84\x9c\xd8\x45\x18\x19\x5f\ \x4c\x19\x8f\x29\xea\xbc\x1b\x98\xbc\xcd\xe8\x85\x63\xc4\x79\x46\ \xb6\x6c\x69\xce\x4f\xb3\xda\xd3\x4b\x63\x6c\x82\xb4\x7f\x08\x15\ \x41\xae\x9e\xc0\xd6\x6b\x48\x63\x99\x22\xf7\x69\xb0\x2b\xdc\xda\ \x78\x9d\x73\x9c\x3f\x74\x88\xb9\x43\x07\xc9\x5b\x2d\x6c\x9e\x93\ \xaf\x2c\xd1\x3a\x7f\x8e\xd6\x91\xa3\xd8\x17\x0f\xb0\xa1\xb5\x42\ \x54\xb8\x4b\x00\xee\xfb\x24\x42\xeb\xf2\x80\x02\xac\x1a\xe2\x91\ \x51\xc2\xcd\xa3\x10\x46\xd8\xa2\xc0\x88\x50\xdd\xb2\x15\x19\xbb\ \x1a\x05\x12\xca\x04\x27\x08\x70\x85\xf7\x4b\x57\xef\x87\x9b\x6e\ \xc3\xee\x7c\x82\x30\x0d\xc1\x81\x0b\x40\x71\x6b\xb3\x17\x18\xd8\ \x36\x54\xa7\x52\x74\xc8\x8d\x63\x31\xcb\xe9\xcc\xce\xe2\x96\x97\ \x70\x28\x2a\x42\xd0\xdf\x4f\xde\xd7\x0f\x0b\xe7\xb0\x1d\x87\x6d\ \x2b\x36\x2f\x05\x50\xc5\x15\x05\x8b\xcf\x7d\x97\xe9\x7f\xf8\x32\ \xed\xb9\x79\x04\x07\x59\x0b\x5d\x5a\x22\x5e\x5c\x66\xd0\x2a\xf5\ \x28\xf4\x39\x84\xbb\x58\x80\xfe\xc0\x3c\x40\x7d\x11\x08\x95\x0a\ \xd1\x96\x71\xc2\x81\x41\xd4\x18\x70\x0e\x09\x43\x4c\x9c\xbc\xac\ \x1c\x53\xeb\x50\x67\xb1\x45\x8e\xd4\xea\x44\x37\xdc\x4c\x3b\x48\ \x08\xda\x4a\xd1\x76\xe5\xcc\x95\xc5\x8b\xfa\xff\xf3\x95\x8c\xb0\ \xc8\x71\x6d\x4b\xb5\x56\x23\x19\x1e\x24\xa9\x56\xb1\x85\x2d\x81\ \x52\x68\x4b\x40\x50\xae\xab\xab\x28\xaa\xae\x4c\xdd\xbd\x35\x85\ \xf3\xb3\xf4\x9f\x3c\x44\x7e\x76\x06\x11\x43\x10\x08\x91\x18\xe2\ \x20\xc0\x04\x1e\x17\xf2\x2b\xb4\xdd\x7c\xff\x3c\x40\x14\x8d\x04\ \x19\x1e\x24\x9a\x98\x40\x92\xc4\x87\x94\x4e\x87\x4e\xa3\x41\xd1\ \x69\xaf\xa5\xb5\xdd\x94\x2c\x8c\x63\xa2\x6a\x95\x30\x4e\x90\x28\ \x26\xda\xb8\x89\xc6\xa6\xab\x29\xa6\x8f\x53\x34\x2c\xb6\xe3\x13\ \x21\xd7\x15\x40\x05\x1b\x0d\x92\x4b\x86\xf4\x0b\xe6\xc6\xed\x04\ \xaf\x7d\x1d\x66\xc3\x46\x5c\x91\xfb\x59\x6a\xb7\x69\xcd\x5c\xa0\ \x12\x58\xbf\x86\x10\x2b\x1a\x5c\x54\xa2\xaa\xa3\x16\x1b\x92\x9e\ \x14\xd7\xaa\x50\xb4\xf0\x8a\x2e\x93\x2d\x4f\x9f\xfb\xda\x06\xb9\ \x72\xdf\xd1\x95\xf3\x00\xa7\x38\x0c\x3a\x38\x4c\xb0\x6d\x3b\x1a\ \x04\x88\x31\xcc\x1d\x3f\xc6\x81\xaf\x7c\x89\x33\xdf\xde\x43\x10\ \x45\x65\xd7\x12\x60\x2c\xc3\x37\xdc\xc4\x0d\xef\xf8\x45\x46\x6f\ \x7d\x0d\x61\x10\xe2\x92\x94\xe2\xf5\xb7\x11\xee\x38\xe9\x31\x40\ \xf4\x62\xd1\x55\x14\x04\x83\x43\xa4\xbf\xf5\x7b\x04\xce\x41\x5a\ \xc7\x8c\x8f\x23\xc3\x1b\x21\xad\xe0\xac\xc5\xda\x82\xe5\xa9\xd3\ \x98\x95\x65\x30\x0e\xeb\xc0\xe6\x65\x1e\xe0\x1c\xea\x9c\x27\x69\ \x0a\xbf\xe4\x6e\x33\xc5\xa9\x40\xd0\x5d\x49\x2e\x6b\x1a\x51\xac\ \x5b\x17\x71\xbb\xe4\xc9\xf7\x77\x01\xc5\x3a\x43\x30\xb8\x91\x74\ \xfc\x6a\x08\x02\xd4\x18\x96\x8f\x1d\x41\x9f\xfe\x06\x63\x07\x5e\ \x24\x4a\x22\x44\xfc\xb2\x95\x09\x1c\x79\x7b\x85\xec\xba\xeb\xc9\ \xae\xbb\x1e\x93\xa6\x90\x26\xc4\x6f\xbc\x03\xbb\xf3\x7e\x9c\x71\ \x68\x54\x9a\xb0\x75\xa8\x75\x50\xad\x11\xfe\xec\x5d\x17\xa3\x4f\ \x18\xfa\x38\x0e\x20\x86\xce\xf2\x32\x87\xbe\xf4\x79\x36\x6b\x93\ \xce\xbc\xc5\x15\x96\x3c\xb5\xd8\xce\xc5\x38\xae\xce\xe1\xda\x8e\ \x7c\xd9\xe1\x56\x1d\x92\x1a\x24\x2e\x59\x6a\x05\x9b\xf9\x88\x63\ \xf3\x2e\xea\xcb\x95\x5d\xe0\x65\xc5\x90\x31\xc8\x60\x1f\xf1\xab\ \x6e\x24\xac\x54\x10\x63\xc8\x0b\x8b\x9e\x3a\x4d\xcf\xd9\x29\x7a\ \x13\x25\xaa\x94\xa1\xa9\x80\x30\x14\x16\xcf\x4e\xc1\xd4\x24\xb6\ \xd5\xf2\x1d\x40\x71\x42\xe5\xda\xeb\x59\xee\x1d\xc0\x2e\x2c\x63\ \x33\x8b\x77\xeb\x92\x08\x15\x83\x24\xe9\x25\x21\x49\xfd\x09\x16\ \xcf\x4e\x73\x7a\xc7\x43\x98\x3d\xbb\x30\x2b\x6d\xcf\x1d\x5a\x45\ \x52\xf5\x33\x2c\xdd\xe7\x08\x9a\x80\x54\xbc\x7b\x38\xa7\x90\x7b\ \xf3\x77\xae\x24\x72\xe4\xe5\xed\x38\x3f\x44\x31\x24\xb8\x34\xa5\ \x55\xad\x32\x73\xf2\x24\x26\x8c\x68\x2c\xcc\xb3\x7a\xf0\x30\x49\ \xab\x45\x1c\x19\x8c\x94\x99\x65\x01\xd2\x86\xb8\xdd\x24\x3f\x7a\ \x8c\xb9\x17\x0f\xb0\xda\x69\x21\x4e\x61\x65\x85\x4e\xcf\x26\x8a\ \xce\x24\xed\xc5\x06\x8b\xd3\x53\xe4\x27\x8e\xe1\xda\xed\x75\xf8\ \xe1\xf3\xfa\xac\xb9\x42\x67\x71\x81\xa5\x93\x27\x59\xdc\xbf\x1f\ \x79\xe1\x79\xc6\x16\xe6\x30\x56\x3d\x00\x2b\x58\x2d\x58\x99\x9f\ \xc5\x1e\x3d\x8a\xeb\xb4\x21\x2f\xe8\x2c\x2c\x80\x2d\x20\x04\xd7\ \x71\xd8\xac\xeb\x6e\xde\xfc\xdd\xba\xe8\xe6\x09\xce\x2b\x58\x00\ \x5d\x98\x28\x19\x91\x70\x60\x40\x64\xe3\x26\x8e\x7c\xf9\x4b\xb4\ \x1f\x7f\x1c\x4c\x80\x74\x9a\x0c\x9c\x99\x64\x28\x2f\x70\xa1\xff\ \x91\xf2\x79\x88\x40\x12\x05\x2c\xbc\xf0\x1c\x53\x4b\x0b\x74\x7a\ \x7b\x11\x20\xca\x2d\xa3\x33\xa7\x49\x43\xa1\x79\xfa\x04\x67\xff\ \xf6\xaf\x29\x1e\xec\x87\x52\xfb\xdd\x2e\x10\xcd\x14\x8a\x0e\xd2\ \x69\x22\xf3\xf3\xc4\x73\xb3\x0c\xda\x0e\x3d\x71\x0c\x45\xd7\x94\ \x85\xf6\xec\x3c\xb3\x0f\xfd\x03\x2b\xcf\x7c\x1b\xb5\x16\x93\x2b\ \x23\x33\x53\xf4\x2c\x37\x90\x42\x71\xca\x25\xd5\xa2\x07\x42\xa8\ \xde\x7c\x23\xe1\xe0\x20\x65\x25\x24\xeb\xfa\xb5\xbc\x02\xf2\x3c\ \x6f\x34\x9b\xcd\x22\xcb\x32\xc2\x38\x96\x74\xeb\x36\xbd\xea\x97\ \x7e\x59\x2e\x7c\xee\xaf\x59\x7d\x7a\x0f\x0a\x54\x42\x88\xd2\x18\ \x09\x23\x0a\x27\x18\xd5\x72\x61\x04\x34\x12\x82\x28\x20\xba\x30\ \x43\x38\x79\x86\x5c\x9d\x27\x22\x82\x80\x70\xb8\x4a\x14\x85\x54\ \x96\x2e\xd0\x3a\x3b\x8d\x5a\xbb\x56\x6e\xfb\x16\x19\xd0\xa6\x12\ \x8a\xef\x30\xa9\x06\x21\xbd\x69\x48\xad\xc7\x87\xda\xa2\xed\x28\ \xda\xe5\xd2\x57\xd6\x24\x98\x79\x1e\xf3\xbd\x67\xfc\xac\xb6\x15\ \x4d\x13\x5c\x12\x43\xee\x85\x27\xf4\x5c\x86\x53\x87\x4a\x40\x65\ \xfb\x35\x6c\xb8\xe7\x5e\xd2\x6d\x13\x8a\x73\x92\x65\x19\xcd\x66\ \xb3\xc8\xf3\xbc\xd1\x55\x80\xce\xcc\xcc\xbc\x34\x39\x39\x79\x32\ \x4d\xd3\x9e\x8d\x41\x10\x56\x47\x46\xd8\xf4\xde\xf7\x91\x0a\xcc\ \xdd\x77\x1f\xed\x93\xc7\x11\x57\x78\x9a\x1c\xc5\xaa\x2f\x35\x05\ \xf1\x09\x46\xee\x4d\xa1\x1e\x84\xf4\xf4\x44\x7e\xcd\x4f\x7d\x4d\ \x61\xc4\x40\xa6\xf4\x07\x01\x83\x3d\x35\x24\xe8\x22\xb2\x10\x94\ \x3d\x9e\x36\x2a\x01\xca\x74\x13\x16\xf5\xb3\x2e\x42\xd1\x2d\xd2\ \x14\x12\x23\x6c\xae\xa4\x8c\x06\x09\xaa\x50\xc4\xd6\x27\x6d\x65\ \x5f\xa1\xba\x6e\x06\xeb\xd0\x20\x22\xdd\x3a\xc1\xf0\xfb\x3e\x40\ \xff\xaf\xbc\x07\xed\x1f\xa0\xd9\x6a\x32\x3b\x3b\x5b\x4c\x4e\x4e\ \x9e\x9c\x99\x99\x79\x09\x9f\x9f\x91\x2c\x2d\x2d\x35\x92\x24\x89\ \xa3\x28\xda\x98\x26\xc9\x50\xa5\x52\x91\xa0\x56\xd3\xca\xb6\x09\ \x31\x81\xa1\x3d\x39\x45\xb1\xb4\x84\x2b\xac\xaf\x0f\x42\x5f\x57\ \x28\xfe\x07\xd5\xe1\x5b\x5b\x04\x24\x12\x4c\x59\x9b\x14\x6d\x8f\ \xc2\x9a\x79\xbe\x91\x08\x24\x36\x28\x50\xb4\x7c\x32\x53\xe4\x3e\ \xbb\x33\x69\x49\x78\xa8\xc3\xe5\x8a\xcd\x1d\xd6\x2a\x2e\x73\xbe\ \x49\x2a\x2a\xc1\xab\xbc\xde\x5a\x1f\x02\x25\x04\x82\x2e\xcd\xa5\ \xd8\xc2\x41\x10\x92\x5e\xbd\x9d\x0d\xf7\xdc\x43\xff\x7b\xde\x83\ \xeb\xeb\xd3\x4e\xa7\x23\x67\xcf\x9e\xd5\x43\x87\x0e\x1d\x79\xe6\ \x99\x67\x1e\x7c\xec\xb1\xc7\x1e\x9b\x9d\x9d\x9d\x0f\x80\x60\x76\ \x76\x36\x3f\x72\xe4\xc8\x5c\xa5\x52\x21\x8a\xa2\x91\x38\x8e\x07\ \x7b\x7a\x7b\xc5\x54\x2a\x5a\x9d\xb8\x06\x11\x95\xec\xec\x34\xf9\ \xc2\x22\x58\x77\x91\xdb\x2b\x57\x6a\x25\x10\x14\xf1\x40\xda\xf5\ \x41\xeb\x97\xb3\x25\x64\xcd\x27\x11\x0f\x33\x2e\x2f\x41\x28\xea\ \xc6\x64\x5d\x2b\xd5\xbb\x35\x88\x1a\x01\x51\x6c\xc1\x9a\x65\xd8\ \xdc\xb7\xda\x69\xd9\x57\xe1\x4d\x1d\xd4\x09\xb6\xcc\x0f\x30\x01\ \x95\x6d\x13\x0c\xbf\xff\xfd\x0c\xbe\xf7\xfd\xea\x7a\xfb\xc8\xad\ \x95\xd3\xa7\x4e\x71\xe0\xc0\x81\x63\xdf\xfc\xe6\x37\x1f\xb8\xef\ \xbe\xfb\x1e\x3a\x7d\xfa\xf4\x19\xa0\x15\x74\xd7\x67\x5a\xad\x56\ \x7e\xf4\xe8\xd1\xf3\x49\x92\xb4\xe2\x38\xde\x14\xc7\xf1\x50\x5f\ \x7f\x3f\x52\x49\xa9\xdd\x70\xa3\x18\x55\x3a\x93\xa7\xc9\xe6\x2e\ \xac\x09\xae\x56\x3d\x6d\x66\xc0\x18\xf5\x1d\x23\xb9\x4f\x42\x5c\ \xee\xdb\xe2\x24\x34\xe0\xb3\x68\x5c\xae\x14\x1d\x3f\x53\x12\x97\ \x4d\x51\x52\x0a\x97\x95\x25\x73\xb9\x0e\x21\x21\x68\xd9\x03\x50\ \x74\x1c\x45\xae\xb8\x52\x19\x84\x5d\xc1\xfd\x33\xbb\x33\xef\xd4\ \x51\xd9\x3e\xc1\x86\x0f\x7c\x90\xc1\x0f\x7e\x08\x5b\xaf\x53\x58\ \xcb\x89\xe3\xc7\xe5\xb9\xe7\x9e\x3b\xf2\x8d\x6f\x7c\xe3\x8b\x5f\ \xf9\xca\x57\xbe\xb6\xb4\xb4\x34\x89\xe7\xac\x9b\xdd\x06\x09\x07\ \xd8\x2c\xcb\xf2\x53\xa7\x4e\xcd\x85\x61\xb8\x9c\xa6\xe9\x58\x1c\ \xc7\x43\xbd\xfd\xfd\x22\x49\xa2\x3d\x37\xbf\x1a\x51\xa4\x79\xf4\ \x18\xf9\xfc\x05\x4c\x14\x96\x83\xd7\xb5\x19\x52\xe7\x85\x92\xd0\ \xcf\x9e\x2b\xd4\x77\x7f\xba\x8b\x33\x29\x51\x49\x4b\x59\x20\xf4\ \x94\x9b\xed\xf8\xf5\x3d\xc2\x12\xa8\x9d\xef\x1d\x76\x40\xd1\xb4\ \xde\x52\x02\x59\x8b\xef\x5d\x58\x28\x0a\x8f\xf2\x2a\x8a\xed\x74\ \x48\xc7\xaf\x66\xe4\xd7\x3f\xca\xf0\xaf\xff\xba\x16\x69\x4a\x6e\ \xad\x74\x85\x7f\xea\xa9\xa7\xfe\xe6\x91\x47\x1e\xd9\xb9\xb2\xb2\ \x32\x09\x2c\x02\x2d\xc0\x76\x2d\xc0\x89\x88\x05\x6c\xa7\xd3\xc9\ \xce\x9f\x3f\xbf\x14\xc7\xf1\x6a\x9a\xa6\x9b\x2a\x69\x3a\x54\xad\ \xd5\x24\xa8\x56\xa5\x76\xdd\x75\x1a\x55\x2a\xd2\x38\x74\x90\x6c\ \x61\xbe\x64\x5f\x14\xe7\x04\x6b\x3d\xe5\x2c\xeb\x92\x0f\x97\x97\ \xa0\x54\xb6\xbe\x11\x78\x41\xbd\x39\x7b\x8e\xc0\xe6\x1e\xb4\x24\ \xf4\x1c\x84\x73\x4a\x51\x5c\xea\xeb\x5d\xc5\x38\xf5\xee\x51\xe4\ \xba\x66\xf2\x8a\x62\xdb\x1d\xe2\xd1\x51\xc6\x7e\xf3\xb7\x19\xba\ \xf7\x83\x6a\x6b\x35\x69\xb7\x5a\x32\x79\xe6\x0c\xcf\x3f\xff\xfc\ \xe1\xa7\x9f\x7e\xfa\x0b\x3b\x76\xec\xd8\xbd\xb8\xb8\x78\x1a\x58\ \x14\x91\x06\x90\xe3\xf9\x95\x8b\x15\x40\xa9\x04\xd7\x6a\xb5\x3a\ \x33\x33\x33\x0b\x95\x4a\x25\x8b\xa2\x68\x43\x25\x4d\xfb\xd2\x38\ \x0e\xe2\xa1\x21\xa9\x6c\xbd\x5a\xa3\x9e\x1e\x69\x1e\x3d\x4a\xbe\ \xb0\xe0\x99\xf3\xb2\x5f\x68\xad\xde\xee\x22\xb2\x2b\xc1\xf2\x22\ \xc3\xee\xf9\x46\xeb\xcf\xa9\x78\xcc\x70\x76\x5d\xfc\xb6\x25\x06\ \x94\x4f\xb2\xa5\x85\x75\x85\x2f\xd7\x36\x7c\xc1\xe3\x7c\x5a\x9d\ \x8e\x5f\xcd\x96\xdf\xfa\x1d\x06\xde\xfb\x5e\x65\x68\x48\x56\x17\ \x17\x99\x9a\x9a\xca\x9f\x7f\xfe\xf9\x23\x7b\xf7\xee\xfd\xf2\xe3\ \x8f\x3f\xfe\xc4\xdc\xdc\xdc\xa9\xae\xf0\xaa\x9a\x77\xd3\xb0\xe0\ \xb2\x2c\x71\x4d\x09\x8d\x46\x23\x9b\x99\x99\xb9\x50\xa9\x54\x5c\ \x1c\xc7\x43\x95\x4a\xa5\x2f\x0a\x82\x20\x1d\x1a\x96\xea\xf6\x6b\ \x34\x88\x22\x69\x9d\x3e\x43\xbe\xbc\xe4\xeb\x70\xfc\xb4\xbb\x6e\ \x58\x2a\x0f\xad\x37\x79\xe7\x74\x4d\x40\xa4\x34\x79\xf1\xdc\x83\ \xb3\x9e\x2c\xed\x0a\x4f\xe8\xc3\xa2\x2d\x13\x1c\x57\x86\x38\xd5\ \x12\x14\x71\x38\x0c\x95\xad\xdb\xd9\xfc\xd1\x7f\xc9\xd0\x3d\x1f\ \x54\x06\x87\x64\xf9\xc2\x1c\x67\xcf\x9e\xcd\x0e\x1c\x38\x70\x74\ \xdf\xbe\x7d\x0f\x3e\xf6\xd8\x63\x8f\x9e\x3f\x7f\xfe\xf4\x95\x84\ \xbf\x92\x02\xba\x4a\x70\x7e\xb5\x79\xb5\x33\x37\x37\x37\x97\x24\ \x89\x89\xe3\x78\x30\x4d\xd3\xbe\x24\x0c\x83\xa8\xb7\x57\x7a\x6e\ \x7c\x95\xaa\x75\xd2\x99\x9e\x26\x5f\x5a\x42\x0b\xeb\x05\x2f\x53\ \x4f\x5f\x72\x7a\x25\x38\x57\xe6\xfb\xee\x22\x25\xdd\x6d\x8b\x77\ \x0e\x4f\x94\x96\xd7\xbb\x2e\x75\x8e\x77\x07\x6b\x75\xcd\x9a\xdc\ \xc5\xe5\x6d\x34\x88\xa8\x6c\x9b\x60\xe4\xde\x0f\xb2\xf1\xc3\x1f\ \x51\x5b\xab\xc9\xca\xc2\x02\x53\x53\x53\xd9\x0b\x2f\xbc\x70\x74\ \xef\xde\xbd\x5f\xdb\xb1\x63\xc7\x23\xd3\xd3\xd3\xa7\x80\x05\x11\ \x69\x5e\x2e\xfc\x2b\x29\xa0\x9b\xa5\x5b\xc0\x2e\x2f\x2f\xb7\x66\ \x66\x66\xe6\xa2\x28\x92\x28\x8a\x86\xd2\x34\x1d\xa8\x56\xab\xc6\ \x24\x09\xf5\x1b\x6f\x14\xa3\x8e\xf6\xe4\x14\xd9\xe2\x92\x6f\x50\ \x30\xbe\x27\x00\x29\x73\x83\x12\xb8\x5c\xb9\xe6\xe8\x43\xa6\x9f\ \x59\xd5\x75\x16\x51\xce\xb8\x67\x7a\xdc\xda\x71\x67\x3d\x76\x78\ \x32\x44\xb1\xd6\xc7\xf9\xca\xc4\x04\x9b\xee\xb9\x97\x0d\xbf\xf6\ \x6b\xd8\x34\xa5\xd5\x6c\xca\x99\x33\x67\x8a\x03\x07\x0e\x1c\xd9\ \xb3\x67\xcf\x23\x3b\x76\xec\x78\x78\x6a\x6a\xea\x78\x09\x78\x0d\ \xdf\xe5\xf0\xf2\xb6\x82\xef\xa7\x00\xd7\x7d\x7f\x61\x65\x65\xa5\ \x31\x37\x37\x37\x17\x86\xa1\x0b\x82\x60\x43\x9a\xa6\xc3\x7d\x7d\ \x7d\x62\x92\x44\xeb\xd7\x5e\x87\xc1\x48\x6b\x72\x92\xce\xc2\xfc\ \x1a\xf3\xeb\x5c\x59\xfa\xae\x95\x18\xac\x2d\xbe\x6a\xd7\x15\xd6\ \x7a\x11\xbc\xc7\x3b\x55\x6c\xd7\x55\xba\xee\xd4\xcd\xe9\x9d\x17\ \x5e\x4d\x40\x75\xfb\xb5\x6c\xbe\xf7\x57\xd9\x70\xcf\x3d\xea\x6a\ \x35\xf2\xa2\x90\x13\x27\x4e\xf0\xbd\xef\x7d\xef\xf0\xde\xbd\x7b\ \xbf\xba\x73\xe7\xce\x47\xa6\xa7\xa7\x8f\x77\x43\x5d\x17\xf0\xae\ \xf8\x1a\xda\x0f\x68\xa7\xef\x2a\xc1\xae\xac\xac\xb4\x2e\x5c\xb8\ \x30\x63\x8c\xe9\xa8\xea\xc6\x30\x0c\x87\x87\x86\x86\x90\x34\xa5\ \xb6\x7d\xbb\x04\x41\x40\x7b\x6a\x8a\xf6\xcc\x9c\x4f\x56\xba\xb4\ \x9a\xf1\x4d\x53\x97\x08\xee\xca\xc6\xa6\xf2\xb5\x99\xae\x95\x58\ \xab\x17\x5d\x48\x64\xcd\x0d\x9c\xfa\x64\xc9\x39\xa8\x5f\x77\x3d\ \xa3\xbf\xfa\x21\x36\xbc\xef\x7d\x68\x6f\x2f\x85\xb5\x1c\x3c\x78\ \x50\x9e\x7d\xf6\xd9\x43\xfb\xf6\xed\xbb\x7f\xf7\xee\xdd\x5f\x9b\ \x9e\x9e\x3e\x09\x2c\x95\xc2\x67\xaf\x24\xfc\x0f\xa3\x80\xcb\x95\ \xd0\x39\x7f\xfe\xfc\x9c\x31\x66\x25\x08\x82\xd1\x20\x08\x86\x07\ \x07\x07\x25\xa8\xd5\xb4\xb6\x7d\xbb\x04\x61\x48\xeb\xc4\x71\x1a\ \x8b\x8b\xd8\xf2\xfd\x87\xc2\x2a\x85\xf3\xbb\x75\x17\xbf\x17\xd6\ \xef\xd6\x2a\x79\x79\x6e\xfd\xf9\xbc\x3c\x5f\xa8\x5f\x10\xb6\x40\ \xef\xb6\xad\x6c\xf9\xc8\x47\xd9\xf0\x81\xf7\xa3\x7d\xfd\x9a\xe5\ \xb9\xbc\xf8\xe2\x8b\xb2\x7f\xff\xfe\xc3\x7b\xf6\xec\xf9\xdb\x5d\ \xbb\x76\x3d\xd1\x05\xbc\x32\xce\xe7\xdf\x4f\xf8\x1f\xf6\x8d\x11\ \x05\x0a\x11\x69\xa9\x2a\x73\x73\x73\x6e\xf7\xee\xdd\x3b\xad\xb5\ \xd6\x39\xf7\x11\xe0\xba\xeb\x6f\xb8\x41\xaa\x03\x03\x3a\xfc\x9e\ \xf7\x30\x74\xfb\xed\xe2\x96\x97\xaf\xdc\x8f\x2f\xeb\x8f\xe8\x2b\ \x74\xee\xeb\x25\x2f\x0d\x5d\xb2\x64\xd9\xdb\x8b\x6c\xde\xac\x32\ \x30\x40\xab\xd9\x92\x43\x07\x0f\xf2\xec\xb3\xcf\x1e\xde\xb3\x67\ \xcf\x67\xbf\xf1\x8d\x6f\xec\x9e\x9f\x9f\x3f\x0d\x2c\x97\x63\x2d\ \x7e\x90\xf0\x3f\xca\x2b\x33\x4e\x55\x73\x11\xdf\x4c\x36\x3f\x3f\ \x7f\x6a\xe7\xce\x9d\x4f\x1a\x63\x22\x11\xf9\xd5\x30\x0c\xaf\xd9\ \xba\x6d\x9b\xe9\xdd\xb8\x91\x78\x7c\x5c\x83\x20\x90\x4b\x49\xd3\ \xf5\x0b\x37\x3f\x68\x4c\xf2\xf2\x37\xad\x4a\xaa\xda\x5a\xab\x59\ \xa7\x23\xcb\x8b\x8b\x9c\x3c\x71\xc2\xed\xdf\xbf\xff\xe8\xbe\x7d\ \xfb\x3e\xbf\x73\xe7\xce\x27\x57\x57\x57\xcf\xfc\xa8\xc2\xff\xa8\ \xaf\xce\xaa\xaa\xae\x59\xc2\xea\xea\xea\xe4\xe3\x8f\x3f\xfe\x68\ \x10\x04\x49\x18\x86\xef\x06\xae\x19\xdb\xb2\x25\x4c\xd3\x6e\x91\ \xaf\xfc\x54\x37\xaf\x50\x69\xb7\xdb\x4c\x9e\x39\x53\xec\xdf\xbf\ \xff\xe8\x33\xcf\x3c\xf3\x95\xc7\x1f\x7f\xfc\xd1\x46\xa3\x31\xf5\ \xe3\x08\xff\xe3\xbc\x3b\xac\xa5\x25\xa0\xaa\xd2\x68\x34\xd8\xb5\ \x6b\xd7\x83\xc6\x18\x03\xbc\x73\x69\x69\x69\x6b\x4f\x4f\x4f\xa8\ \xfa\xd3\x96\x7e\x6d\xcd\x52\x56\x56\x56\x8a\xe3\xc7\x8f\x9f\xdc\ \xb7\x6f\xdf\x23\xbb\x76\xed\x7a\xf0\x32\xe1\xf3\x7f\x92\x77\x87\ \xcb\x2d\x06\x52\xa0\x77\x6c\x6c\x6c\xeb\xeb\x5e\xf7\xba\x3b\xfb\ \xfb\xfb\x5f\x15\x04\x41\xdd\x39\xa7\x3f\xe1\xb3\xaf\xa8\x7c\x63\ \x8c\x58\x6b\x57\x17\x17\x17\x5f\xfc\xce\x77\xbe\xb3\x7b\x72\x72\ \xf2\x24\xb0\x8c\x6f\xc7\xca\xfe\xc9\x5e\x9e\x5e\x77\x6f\x58\xf6\ \x81\xd5\x81\x1e\xa0\x56\x2a\x26\x58\xf7\x2e\xe4\x4f\x45\xf8\x75\ \xc9\x59\x56\x26\x36\x2b\xc0\x6a\x89\xf6\x3f\x92\xd9\xaf\xdf\xfe\ \x1f\xba\xc9\xa0\xf1\xd3\x43\x85\x2f\x00\x00\x00\x00\x49\x45\x4e\ \x44\xae\x42\x60\x82\ \x00\x00\x20\xb1\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\xe7\x00\x00\x00\x82\x08\x06\x00\x00\x00\xbd\xcd\xdf\xc9\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\xdd\x75\x00\x00\xdd\x75\x01\ \xac\x87\xc3\x83\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x02\x18\ \x12\x22\x32\x36\x82\x3a\x5a\x00\x00\x20\x00\x49\x44\x41\x54\x78\ \xda\xed\x5d\x69\x73\xdb\xd8\xb1\x3d\x20\x01\x02\x04\xc1\x55\x8b\ \x25\x79\xec\xf1\x54\x3e\xa4\xf2\xff\x7f\x4a\xaa\x52\xa9\x54\xc5\ \x9b\x6c\xd9\x96\x44\x71\x01\xb1\x72\x7b\x1f\x26\xe7\xa6\x79\x05\ \x90\xd4\x1b\xcf\x8c\x63\x77\x57\xb9\xb4\x70\x15\x8d\x73\xbb\xfb\ \xf4\xe9\x6e\x67\xbb\xdd\x6e\xa1\xa6\xa6\xf6\xcd\x59\x43\x3f\x02\ \x35\x35\x05\xa7\x9a\x9a\x9a\x82\x53\x4d\x4d\xc1\xa9\xa6\xa6\xa6\ \xe0\x54\x53\x53\x70\xaa\xa9\xa9\x29\x38\xd5\xd4\xd4\x14\x9c\x6a\ \x6a\x0a\x4e\x35\x35\x35\x05\xa7\x9a\x9a\x82\x53\x4d\x4d\x4d\xc1\ \xa9\xa6\xa6\xa6\xe0\x54\x53\x53\x70\xaa\xa9\xa9\x29\x38\xd5\xd4\ \x14\x9c\x6a\x6a\x6a\x0a\x4e\x35\xb5\x1f\xd1\x5c\xfd\x08\xbe\x5d\ \xdb\x6e\xb7\xd8\x6e\xb7\x58\xaf\xd7\x58\xaf\xd7\x28\xcb\x12\x49\ \x92\x60\xbb\xdd\x62\x38\x1c\xa2\xdd\x6e\x1f\xfd\x5c\x59\x96\xe1\ \xe1\xe1\x01\xeb\xf5\x1a\xbe\xef\xc3\xf3\x3c\xb4\x5a\x2d\xb4\x5a\ \x2d\x34\x9b\x4d\x38\x8e\x03\xc7\x71\x00\xc0\x7c\x55\x53\x70\xaa\ \x09\x30\x6e\x36\x1b\xac\xd7\x6b\x14\x45\x81\x2c\xcb\xcc\xbf\xa2\ \x28\xcc\x6d\x41\x10\xa0\xd3\xe9\x3c\x09\x9c\xab\xd5\x0a\xf3\xf9\ \x1c\x59\x96\xa1\xd1\x68\xc0\x71\x1c\x34\x1a\x0d\xb4\x5a\x2d\xf8\ \xbe\x8f\x20\x08\xd0\x6e\xb7\xd1\x6a\xb5\xe0\x79\x9e\x01\xac\x9a\ \x82\xf3\x87\x07\xe5\x7a\xbd\x46\x96\x65\x58\x2c\x16\x48\xd3\x14\ \x79\x9e\x63\xb5\x5a\xc1\x71\x1c\xb8\xae\x8b\x76\xbb\x8d\x46\xe3\ \xd7\x2c\xa4\xd9\x6c\x9a\xef\x8f\xce\x5f\x1a\x0d\xb4\xdb\x6d\xb8\ \xae\x8b\xcd\x66\x63\x0e\x82\x34\x4d\x71\x7f\x7f\x8f\xe5\x72\x89\ \x66\xb3\x89\x30\x0c\xd1\xeb\xf5\x10\x45\x11\xa2\x28\x42\x18\x86\ \x68\x36\x9b\xfa\x9f\xf4\x27\x98\xa3\x03\xbe\xfe\x5c\x2b\x8a\x02\ \x0f\x0f\x0f\xb8\xbf\xbf\x47\x9e\xe7\x70\x1c\x07\xbe\xef\x23\x0c\ \x43\xb4\x5a\x2d\x03\xc2\xcd\x66\x83\xd5\x6a\x85\xd5\x6a\x85\xcd\ \x66\x83\xf3\xf3\x73\x0c\x87\xc3\xa3\x5f\x67\x3a\x9d\xe2\xf3\xe7\ \xcf\xd8\x6e\xb7\x68\x34\x1a\x3b\x00\xdf\x6e\xb7\x58\x2e\x97\x28\ \xcb\x12\x45\x51\x18\x2f\xcd\x43\x61\x34\x1a\xe1\xf4\xf4\x14\x61\ \x18\xaa\x37\x55\xcf\xf9\xfd\x5b\x9e\xe7\xb8\xb9\xb9\xc1\x97\x2f\ \x5f\xd0\x68\x34\x10\x86\x21\x4e\x4f\x4f\xd1\xe9\x74\xcc\xed\x59\ \x96\xa1\x2c\x4b\xac\xd7\x6b\xe3\xbd\xca\xb2\xc4\x6a\xb5\x42\xbf\ \xdf\x7f\xf2\x21\x10\xc7\x31\x5c\xd7\x85\xe3\x38\x28\x8a\x02\x65\ \x59\x62\xbb\xdd\xc2\x71\x1c\x13\xc6\x36\x1a\x0d\x74\xbb\x5d\x00\ \xc0\x72\xb9\xc4\x6a\xb5\xc2\x87\x0f\x1f\xf0\xf1\xe3\x47\x8c\x46\ \x23\x5c\x5d\x5d\x21\x8a\xa2\x27\x7b\x6e\x35\x05\xe7\x37\x1f\xbe\ \x16\x45\x81\xbb\xbb\x3b\x7c\xfe\xfc\x19\x8e\xe3\x60\x34\x1a\xed\ \xe4\x8f\x79\x9e\x63\x36\x9b\x61\xb9\x5c\x62\xb3\xd9\x60\xb3\xd9\ \x98\xc7\x93\x14\xa2\xf7\x7c\x8a\xf1\xb9\x56\xab\x15\xca\xb2\xc4\ \x72\xb9\x7c\x14\x56\x3b\x8e\x83\xed\x76\x8b\x3c\xcf\xe1\x79\x9e\ \x01\x6d\x10\x04\x28\x8a\x02\x5f\xbe\x7c\xc1\x74\x3a\xc5\xd9\xd9\ \x19\x9e\x3d\x7b\x86\x30\x0c\x15\xa4\x0a\xce\xef\x23\x7c\x9d\x4c\ \x26\x18\x8f\xc7\xc8\xf3\x1c\x41\x10\xc0\x75\x5d\xc3\x98\x12\x34\ \x79\x9e\xef\x00\x8f\x80\x59\x2e\x97\x58\xaf\xd7\x60\x16\xf2\xd4\ \x6c\x64\xbb\xdd\xa2\x2c\x4b\x38\x8e\x83\xf5\x7a\x8d\x46\xa3\x61\ \xd8\x60\x19\xde\x92\xb5\x2d\xcb\x12\x00\x0c\x39\xd4\xe9\x74\xb0\ \x5c\x2e\xb1\x58\x2c\xf0\xf6\xed\x5b\xcc\xe7\x73\x3c\x7b\xf6\x0c\ \xc3\xe1\x10\xbe\xef\x2b\x48\x15\x9c\xff\x7b\xb6\xd9\x6c\x30\x9b\ \xcd\x70\x77\x77\x87\x24\x49\xe0\x38\x8e\x21\x66\x58\x22\x99\xcf\ \xe7\x28\x8a\xc2\x00\x6e\xbd\x5e\x1b\xd2\x46\x32\xb8\x04\x4f\x51\ \x14\xc8\xf3\xfc\x49\xef\x63\xb9\x5c\x62\xb9\x5c\x1a\x8f\x28\x89\ \xa2\x2a\xb0\x37\x1a\x0d\xe3\x69\xd3\x34\x35\xac\xee\x70\x38\x44\ \x9e\xe7\x78\x78\x78\xc0\x74\x3a\xc5\xf9\xf9\x39\x2e\x2f\x2f\xd1\ \xef\xf7\x95\x38\x52\x70\xfe\xef\x84\xb0\xeb\xf5\x1a\xe3\xf1\x18\ \x9f\x3f\x7f\x46\x59\x96\x08\xc3\x10\x9e\xe7\x19\x00\x7a\x9e\x87\ \xcd\x66\x63\x88\x9f\x2c\xcb\x4c\x38\x4b\x50\x12\xa0\x12\x64\x49\ \x92\x3c\x19\x9c\x69\x9a\x22\x4d\x53\xf4\xfb\x7d\xe3\x8d\xe5\x57\ \x59\xe7\xb4\xbd\xf6\x7a\xbd\x46\x9e\xe7\xa6\x8c\xe3\xfb\x3e\x5c\ \xd7\x45\x51\x14\xf8\xf4\xe9\x13\xee\xef\xef\xf1\xea\xd5\x2b\x3c\ \x7f\xfe\x5c\x4b\x30\x0a\xce\x6f\xdf\x96\xcb\x25\x6e\x6f\x6f\x71\ \x7d\x7d\x8d\x56\xab\x85\xd1\x68\x64\x2e\xf4\x66\xb3\x89\x66\xb3\ \x69\xbc\x91\xeb\xba\x3b\x80\x23\x28\x09\x72\x29\x46\xe0\x7d\x9a\ \xcd\x26\x36\x9b\xcd\x51\xe1\xe4\x76\xbb\x35\xc2\x03\x86\xd4\xbe\ \xef\x63\xbb\xdd\x62\xb5\x5a\x3d\x7a\x2d\x09\x56\x19\xfa\x36\x1a\ \x8d\x1d\x0f\x1e\x04\x01\x5a\xad\x16\x92\x24\xc1\x3f\xfe\xf1\x0f\ \x4c\xa7\x53\xfc\xf5\xaf\x7f\x85\xef\xfb\x0a\x50\x05\xe7\xb7\xe9\ \x31\xc9\xc4\xde\xde\xde\x22\x8a\x22\x74\x3a\x1d\x73\x51\xb7\xdb\ \xed\x9d\x9a\xa5\xcc\x29\xcb\xb2\xc4\x66\xb3\xd9\x01\x85\xe3\x38\ \x06\xac\x0c\x77\xa3\x28\x32\xe0\x3a\xc6\x48\xf6\xf8\xbe\x8f\x66\ \xb3\x69\xc2\x6a\xe6\x96\x0c\xa9\x99\x87\x12\x58\xcc\x7d\x9b\xcd\ \xa6\x01\x37\x19\x5c\xcf\xf3\xcc\x7d\xa3\x28\x82\xeb\xba\xb8\xb9\ \xb9\x41\x1c\xc7\xf8\xdb\xdf\xfe\x86\xd1\x68\xa4\x00\xfd\x8d\xa6\ \x59\xfc\x57\xb6\x34\x4d\xf1\xf6\xed\x5b\xdc\xdf\xdf\x63\x30\x18\ \x20\x0c\x43\x03\xb8\x76\xbb\x6d\x88\x20\xe9\xf1\xd6\xeb\xb5\x21\ \x7c\x28\xaf\x0b\x82\xc0\x28\x79\x9a\xcd\x26\xd6\xeb\x35\x92\x24\ \x41\xb3\xd9\x84\xeb\xba\xc8\xf3\x7c\x87\x71\xdd\x67\xab\xd5\x0a\ \x45\x51\x20\x08\x02\xf4\xfb\x7d\x03\xac\xed\x76\x6b\x08\x1f\x82\ \x8e\xaf\x49\xb0\x4a\x2f\xca\xfa\x28\x81\x4d\xf0\x6d\xb7\x5b\x04\ \x41\x80\xd1\x68\x84\x3c\xcf\xf1\xf7\xbf\xff\x1d\x37\x37\x37\xd0\ \x12\xba\x82\xf3\x9b\xb1\xd9\x6c\x86\x7f\xff\xfb\xdf\x48\xd3\x14\ \xa3\xd1\xc8\xb0\xb0\xeb\xf5\xda\x80\x90\x3f\x4b\xaf\xe8\x38\x0e\ \xba\xdd\x2e\x3a\x9d\x8e\xd1\xbc\xd2\xbb\xd1\x83\x6d\x36\x1b\x03\ \x2a\x2a\x88\xf8\xbc\xc7\x90\x52\x7c\x1d\x3b\x9f\x24\x40\xb7\xdb\ \x2d\xe2\x38\x36\x61\xb3\xf4\xa2\x9b\xcd\xc6\x94\x70\xaa\x08\x24\ \x3e\x97\xeb\xba\xe8\x76\xbb\xd8\x6c\x36\xf8\xe7\x3f\xff\x89\x37\ \x6f\xde\x3c\xb9\xe4\xa3\xa6\xe0\xfc\xea\x36\x99\x4c\xf0\xee\xdd\ \x3b\x6c\xb7\x5b\x0c\x06\x03\x34\x1a\x0d\x93\xcf\xb1\x8c\x41\x56\ \x56\x7a\x27\xfe\x6b\xb5\x5a\x88\xa2\x68\x87\x24\xf2\x7d\x7f\x87\ \xa9\x6d\xb5\x5a\x46\x7e\x47\x4f\x7b\x6c\xa8\xcd\xd7\x5f\x2c\x16\ \x06\x7c\xf4\x7e\xae\xeb\xa2\xd3\xe9\x18\x8f\xcc\x30\x98\xef\x91\ \x00\x97\x64\x95\xfc\xdb\xf8\x7c\x00\xe0\xba\x2e\xa2\x28\x82\xe3\ \x38\x78\xfd\xfa\x35\xde\xbc\x79\x73\xf4\xfb\x54\xd3\x9c\xf3\xab\ \xdb\x74\x3a\xc5\xbb\x77\xef\xb0\x5e\xaf\xd1\xeb\xf5\x4c\x7e\x28\ \x3d\x0c\xc9\x1b\x7a\x24\xde\x26\x43\x43\xc7\x71\x8c\x17\x93\x1e\ \x16\x80\xf1\xa8\x0c\x89\xa9\xf0\x39\x96\x9c\x4a\xd3\x14\x49\x92\ \x18\x35\x92\x04\x1e\x43\x58\x2a\x83\xe4\x7b\x94\x9e\x52\x8a\x1f\ \xf8\xf7\xf1\x3d\xf3\x7d\x33\x47\x8d\xa2\x08\x71\x1c\xe3\xfd\xfb\ \xf7\x68\xb5\x5a\xb8\xba\xba\xd2\x52\x8b\x82\xf3\x8f\xb5\xf9\x7c\ \x8e\xb7\x6f\xdf\x62\xb5\x5a\x61\x30\x18\xec\x5c\xb8\xf4\x7a\xfc\ \xde\xd6\xb3\xda\xde\xd3\x75\x5d\x84\x61\x88\x38\x8e\xf1\xf0\xf0\ \x60\x84\xef\x00\x76\x44\x01\xfd\x7e\x7f\x87\xd1\x3d\x26\xe7\xa4\ \xf0\x20\xcf\x73\x53\x52\x91\x22\x78\xd7\x75\x4d\x79\xa4\xea\x60\ \xa1\xa7\xa4\xe6\xd6\x75\x5d\xf3\x3b\x7a\x5f\x59\x9a\xa1\x70\x61\ \xb1\x58\xe0\xf5\xeb\xd7\x68\x34\x1a\xb8\xbc\xbc\x54\xb1\x82\x82\ \xf3\x8f\xb1\x2c\xcb\x70\x73\x73\x83\xb2\x2c\xd1\xeb\xf5\xd0\x6c\ \x36\xb1\x5a\xad\x0c\x40\x79\xe1\xcb\x3e\x49\xd6\x01\x25\x28\x65\ \xf8\xe9\xba\x2e\x86\xc3\x21\xc2\x30\x44\x9a\xa6\x86\x4d\x65\x98\ \x9c\x24\x09\xba\xdd\x2e\x7a\xbd\x1e\x82\x20\x38\xea\x7d\xb2\xec\ \x61\x83\xba\xd5\x6a\xed\x90\x3d\x0c\x5d\xed\x5c\x95\x2d\x6c\x14\ \x3f\xac\x56\x2b\x43\x0c\x51\xd9\xd4\x6c\x36\x2b\x05\x0e\x61\x18\ \x22\x49\x12\xbc\x7e\xfd\x1a\x9e\xe7\xe1\xec\xec\x4c\x59\x5c\x05\ \xe7\xef\x6b\xab\xd5\x0a\xb7\xb7\xb7\x98\x4c\x26\xe8\x76\xbb\xf0\ \x7d\xdf\x84\x7d\x36\x30\xf9\xbd\xef\xfb\x06\x10\xb6\x0c\x4f\xaa\ \x81\xb6\xdb\xad\x09\x0d\x09\x8c\xb2\x2c\x77\x44\x0a\x4f\xc9\x39\ \xe9\xe9\xf8\x18\xcf\xf3\x0c\xfb\xcb\xf7\xca\x3a\x2b\xe5\x84\x41\ \x10\x60\xb3\xd9\x20\x8e\x63\x03\x54\x09\x3a\x5b\xf3\x9b\x65\x99\ \xa9\xdf\xf2\x36\x82\x3e\x08\x02\xc3\x62\xb7\xdb\x6d\x13\x3e\xab\ \x29\x38\xbf\xba\x6d\x36\x1b\x3c\x3c\x3c\xe0\xe6\xe6\xc6\x5c\xc8\ \x04\x9c\x24\x4a\x08\xcc\xf5\x7a\x6d\x42\x56\x19\x4a\xd6\x85\xa5\ \x92\x21\x65\xfb\x56\x92\x24\x28\xcb\x12\xdd\x6e\x17\x41\x10\xa0\ \x2c\xcb\xa3\x73\xce\x34\x4d\xf1\xf0\xf0\x60\x42\x56\xe6\x87\x0c\ \x31\xd3\x34\xc5\x62\xb1\x30\x87\x03\x35\xb4\xfc\x7b\x64\xa8\xee\ \x79\x1e\x5c\xd7\x7d\x54\x6a\xa1\x40\x5e\x8a\xf5\x29\xf4\xa7\xe7\ \x9e\x4c\x26\xb8\xbe\xbe\xc6\x5f\xfe\xf2\x17\xf8\xbe\xaf\x17\x92\ \x82\xf3\xeb\x5b\x9a\xa6\x78\xff\xfe\x3d\x1c\xc7\x31\xcd\xc8\xac\ \x13\x4a\xd0\x49\x2f\x4a\x50\xc9\xdb\xa5\x07\x95\x79\xa8\xe3\x38\ \x58\xad\x56\x46\x93\x2b\x0f\x85\xb2\x2c\x4d\x17\xcb\xb1\xe1\x21\ \x4b\x38\x9e\xe7\xa1\xdb\xed\x1a\xd0\x50\x1c\x21\xdb\xd2\x78\x5f\ \x19\x66\x4b\xf1\x01\xa3\x03\xfe\x6d\x9c\xa6\xe0\x79\x1e\x92\x24\ \x41\x14\x45\xa6\x8b\x25\x4d\x53\x2c\x97\x4b\x14\x45\x81\x5e\xaf\ \x07\xcf\xf3\xf0\xf1\xe3\x47\x74\xbb\x5d\x3c\x7f\xfe\x5c\xf3\xcf\ \x03\xa6\x9f\xce\x13\x6d\xb9\x5c\xe2\xe6\xe6\xc6\x5c\xdc\x64\x36\ \x29\x20\x90\x0a\x1f\xfe\x4c\xaf\xc9\x90\xcf\x0e\x69\xe5\xc8\x90\ \x20\x08\x90\xe7\x39\xfe\xf5\xaf\x7f\xe1\xcd\x9b\x37\x26\xcf\x5b\ \x2e\x97\x26\xd7\x2c\x8a\x02\x37\x37\x37\xa6\x2c\x72\x4c\x08\x4e\ \xf5\x11\x5f\x87\x5e\xd2\x66\x67\x65\x7e\x2c\xa3\x02\x19\xc6\xb2\ \x09\x5b\x32\xcb\x3c\x38\x66\xb3\x19\x92\x24\x81\xeb\xba\xe8\xf5\ \x7a\xf0\x7d\xdf\xc8\x0e\x59\xf7\x7d\xf3\xe6\x8d\xf1\xcc\x6a\x0a\ \xce\xaf\x62\xdb\xed\x16\xf3\xf9\x1c\xb7\xb7\xb7\x46\x57\x4a\x00\ \x4a\xcf\x47\xa0\xd2\x4b\xb2\x86\x28\x73\x44\x82\x98\x0a\x1d\xea\ \x56\x39\x19\xa1\x2c\x4b\xa3\xbb\x75\x5d\x17\x41\x10\xa0\xdb\xed\ \x9a\xfe\x4f\x32\xa8\x4f\xfa\xcf\xfe\x4f\x29\x87\xa4\x54\x51\x14\ \x26\x0f\x95\xa2\x03\x82\xaf\xdf\xef\x1b\x41\xbe\x24\xb6\x78\xff\ \x20\x08\x8c\x92\x49\x7e\x06\x04\x6a\x59\x96\x08\x82\xc0\x4c\x6c\ \xa0\x90\x62\x36\x9b\xe1\xcd\x9b\x37\x47\x2b\x9c\x14\x9c\x6a\x07\ \xad\x2c\x4b\x5c\x5f\x5f\x9b\x0b\x53\x12\x38\x04\x9b\x14\x0d\x10\ \x8c\x24\x81\x24\xf1\xc3\x9a\x25\xa5\x7b\x0c\x1b\x99\xbf\x11\xb0\ \x0c\x73\x49\x26\x91\x01\x3d\x3b\x3b\x43\x18\x86\x47\xbd\xef\x30\ \x0c\x4d\x37\x8a\x04\x27\x23\x01\xa9\xbb\xa5\xd7\x24\x69\x94\x65\ \x99\x51\xfe\x30\x4f\x94\xe1\x38\xb5\xc2\x54\x0f\xc9\x88\x81\xe1\ \x32\xfb\x56\xe5\x81\xf4\xe9\xd3\x27\x8c\xc7\x63\xf5\x9e\x0a\xce\ \xaf\xe3\x35\xd9\xc3\x48\x90\xf0\x82\x24\x31\x23\x81\x29\x45\xe3\ \xb2\xb6\xc9\x6e\x14\xd9\x40\x2d\x43\xc6\xe5\x72\x89\xd3\xd3\x53\ \x5c\x5d\x5d\x99\x03\x40\x76\x8e\xf0\x62\xef\xf5\x7a\xe6\x79\x0e\ \x19\x5f\x93\xe1\xad\xec\x32\xe1\x24\x3f\xe6\x9b\xb4\x3c\xcf\x91\ \xe7\x39\xc2\x30\x34\x79\x2a\x95\x43\x92\x8d\x8d\xe3\x78\x27\x64\ \x96\xde\x33\x49\x12\xdc\xdd\xdd\x21\x8e\xe3\x47\xe4\xd0\x76\xbb\ \xc5\xfb\xf7\xef\x51\x14\x85\x5e\x5c\x0a\xce\xdf\x66\x45\x51\xe0\ \xc3\x87\x0f\xf0\x3c\x6f\x87\x95\x94\xa1\xac\xac\x5d\x52\x82\x77\ \x76\x76\x66\x66\xee\x10\xa8\x12\xc4\x36\x19\x44\x90\x0f\x87\x43\ \x5c\x5d\x5d\x21\x0c\x43\x23\x84\x97\x9e\x4d\xd6\x4b\x0f\x31\xcb\ \xf4\x9e\xbe\xef\x9b\xfc\x95\xa0\xa7\x28\x9e\xb5\x4b\xe9\xa9\xe9\ \x2d\xa9\x30\x92\xa3\x4c\x38\xb2\x93\x7f\x0b\xa3\x03\xcf\xf3\xcc\ \x81\x25\x6b\xa1\x2c\xd5\x70\x34\x27\xd9\xdb\xbb\xbb\x3b\xf5\x9e\ \x0a\xce\xdf\xe6\x35\xef\xef\xef\x91\xa6\xa9\x01\x89\x04\x98\x0c\ \xe5\x64\x3e\x49\x31\xbb\x94\xad\xc9\x7c\xd4\x26\x85\x64\xe8\xcb\ \x51\x96\x14\xc1\x77\xbb\x5d\x23\x84\x97\xcf\x75\x48\x58\x4e\x10\ \xb2\x55\xcc\x71\x1c\x23\xe5\xe3\x57\x29\xa2\x67\xbe\xc9\x99\x46\ \x59\x96\x21\x4d\xd3\x1d\x26\x99\xe1\xb6\x7c\x6d\x86\xb1\xcc\x85\ \x93\x24\xc1\x6c\x36\x33\xef\x81\x07\x42\x9e\xe7\x88\xe3\xd8\x8c\ \x36\xb9\xbe\xbe\x3e\xba\x24\xf4\xa3\x99\x96\x52\x8e\xb0\x3c\xcf\ \xf1\xf9\xf3\x67\xa3\x6f\xb5\x07\x6c\xd1\x8b\x4a\x52\x64\x34\x1a\ \x61\x34\x1a\x19\x21\x3b\xc1\x54\xe5\x25\xe8\x09\x49\xda\xc8\xd0\ \xb8\x6e\x1a\x7b\x95\xf7\xad\xf3\x9c\x64\x8c\x7b\xbd\x1e\x80\x5f\ \xbb\x67\x38\x86\xd3\xee\x54\xf1\x7d\xdf\x10\x4e\x9c\x9e\x50\x35\ \x35\x41\xb2\xbc\x14\x34\x78\x9e\x87\x30\x0c\x0d\x08\xe5\xdf\x21\ \x3b\x70\x28\xa8\x68\xb7\xdb\x88\xe3\x18\x37\x37\x37\xf8\xe5\x97\ \x5f\xf4\x42\x53\x70\x3e\xdd\xc6\xe3\x31\xca\xb2\x34\xa1\x9b\x0c\ \x69\x19\xea\x11\x94\x65\x59\x62\x30\x18\x98\x96\x31\x59\x13\xb4\ \xc3\x58\xe6\x83\xf2\xf1\xbc\x2f\x19\xd1\xe1\x70\x68\x84\x03\xd2\ \xc3\xca\x36\x2e\xde\x56\x65\x92\x70\xa2\xba\x88\xb9\x21\x1f\x27\ \x5b\xca\x08\x2c\xca\xf5\xaa\x6a\xa9\xf6\xc4\x04\x7b\x6d\x04\x19\ \x68\x5b\x90\x21\x5b\xcb\xf8\xfb\x66\xb3\x89\xf1\x78\x6c\xa6\xf9\ \xa9\x29\x38\x8f\xb6\xe5\x72\x89\xe9\x74\x6a\x88\x18\x3b\x94\x24\ \x88\x80\x5f\xeb\x89\x6c\xbf\xe2\xa4\x02\x09\x4a\x29\xe5\x93\xe1\ \x21\x2f\xd4\xd5\x6a\x65\xc2\x3f\xe6\xa6\x1c\xf9\xc1\xe7\x61\x3e\ \x37\x9f\xcf\xe1\xfb\x3e\x46\xa3\xd1\xde\xb5\x0c\x14\x33\x8c\xc7\ \x63\xa3\xee\x61\x1e\xc9\x32\x8d\x24\x7a\x28\x1e\xa8\x9a\x29\x24\ \x73\x63\x7b\x5a\x03\x6b\xa2\x2c\x2f\xc9\x83\x8b\x1e\x96\x07\x03\ \xef\xc7\xcf\x22\x4d\x53\xcc\x66\x33\x05\xa7\x82\xf3\x69\x96\x24\ \x89\x21\x31\xe8\x65\x24\x73\xca\x8b\x8f\x17\x64\xa7\xd3\x31\xd3\ \x0f\xe4\x7d\x6d\x3d\x2a\x81\x49\xd0\xda\x22\x00\xf9\x7b\x1b\xdc\ \x00\x0c\x29\x75\xa8\x56\x58\x96\x25\xe2\x38\x36\x93\x10\x28\x9c\ \x60\x68\x2b\x47\x64\x4a\xb0\xc9\xf7\x60\x13\x56\x55\xef\x93\x4a\ \x22\x19\xf2\xb2\x24\x44\xdd\x71\x9e\xe7\x8f\xfe\x1e\x86\xb9\x8b\ \xc5\xc2\x4c\x07\x54\x53\x70\x1e\x45\x04\x71\x77\x89\x14\xac\xdb\ \x3d\x9a\xf4\x9e\xdd\x6e\x77\xc7\x23\x54\x99\x3d\x3c\xcb\x26\x77\ \xea\xc0\x20\x5f\x97\x61\xa3\x1c\xa7\x79\x88\xad\x6d\x34\x1a\x46\ \x9f\x6b\xdf\x6e\x77\x92\x54\x81\x54\xbe\x77\x5b\x7e\xc8\x70\x9e\ \x25\xa6\x46\xa3\x61\xc0\x4a\x52\x8b\xf5\x54\x3b\xff\x64\x9b\x1a\ \x0f\x10\x05\xa7\x82\xf3\xe8\x90\x76\xb1\x58\xec\x80\x50\x5e\xd4\ \x0c\xdd\x48\x84\x64\x59\x86\x24\x49\x8c\xb2\xa6\xae\x6b\x84\x17\ \xb5\x14\x30\xd8\xed\x65\x36\xf9\x23\xe7\xfa\xb0\xb4\x41\xcf\x74\ \xc8\xa4\xe0\xa0\x2c\xcb\x47\x5e\x5b\x02\xb3\xea\x71\xf6\xfb\x96\ \xdf\xcb\xbf\xc5\xce\x7f\xa9\xb9\x6d\x34\x1a\x26\xa4\xb6\x0f\x20\ \x3e\x36\x8e\x63\x24\x49\x82\x4e\xa7\xa3\x2d\x65\x0a\xce\xe3\x58\ \xda\xd9\x6c\x56\x3b\x99\x8e\xbf\x6f\xb5\x5a\x28\x8a\x02\x8b\xc5\ \xa2\x76\x2c\xa4\xad\xa9\xb5\xc3\x5e\x09\x06\xa9\x0e\xe2\x01\x40\ \xc1\x03\x27\xc7\x13\x9c\x27\x27\x27\x7b\x17\x1a\xb1\x96\x29\x01\ \x59\xf5\x9a\x87\xc0\x68\x13\x41\x55\x51\x86\x0c\x93\x57\xab\xd5\ \xce\x24\x78\x99\xc3\x32\xd2\x90\x51\x04\xeb\xa6\x75\xcf\xff\x23\ \x9a\xd6\x39\xf7\x84\xb4\x24\x47\xd8\x60\x6c\x83\x8a\x53\xe7\x36\ \x9b\x8d\x59\xa3\xb0\x5c\x2e\x1f\xad\x54\xa8\x63\x3b\xe9\xad\x6c\ \xe0\xd0\xbb\x30\x9f\xe5\x18\x10\xb2\x9c\x52\x08\x70\x28\xe7\xa4\ \xc8\xc0\x5e\xf1\x50\xf5\x4f\x1e\x16\xd2\xb3\xca\xef\xab\x56\x37\ \xc8\x03\x2b\x8e\x63\x64\x59\x86\x4e\xa7\xf3\xa8\x77\xd5\xce\xb7\ \x59\x42\xf2\x3c\xcf\xec\x0f\x55\xbd\xad\x82\xf3\xa0\xb1\xce\xc7\ \x10\x72\x36\x9b\x99\xbc\x90\xe4\x4f\x14\x45\x3b\x3d\x97\xc7\xd4\ \x1e\xed\x3e\x4e\xc9\xda\x56\x79\x2f\xbe\x17\x86\xd8\xcc\xed\x8e\ \x95\xef\xc9\xfa\xab\x3c\x54\xec\x49\x0c\x12\x78\x75\x1e\xb6\xee\ \xbe\x76\x6e\x2c\x95\x42\x55\x73\x92\x6c\x80\x93\xe1\x1d\x8f\xc7\ \x0a\x4e\x05\xe7\x61\xa3\xe8\x9b\x5a\xd4\x24\x49\x90\x24\x89\x99\ \xc7\xc3\x56\x28\x76\x76\xc8\x30\xd4\xf6\x40\xc7\x90\x43\x12\x9c\ \x9c\xc7\x23\x81\x49\xa5\x0e\x43\xd4\x56\xab\x65\x46\x69\x1e\x0b\ \xce\xaa\x39\xb4\x76\xfe\x67\x7b\x4c\x09\xa8\xaa\xb1\x98\xf6\xdf\ \x49\x4f\xbf\xef\xb0\xb1\xc5\x0c\x14\xc6\xb3\x3d\x4e\xe5\x7c\x0a\ \xce\xa3\x3c\x27\xdb\xb2\x9a\xcd\x26\xe6\xf3\x39\xa6\xd3\xa9\xb9\ \xa8\xb3\x2c\x33\xa1\x23\x2f\x44\x2e\x2e\x4a\xd3\x74\x2f\x41\x23\ \x01\xc2\xb2\x03\xc3\x57\xa9\x0a\xda\x6c\x36\xe6\x90\x90\x35\x43\ \xb2\xb6\x87\x1a\x96\x7d\xdf\x37\xf3\x8d\x6c\x60\xd9\xef\xa9\x6e\ \xa9\x91\x0d\xc4\xba\xbf\xc7\x0e\x5b\x6d\xe2\xa8\xaa\x74\xc4\xe7\ \x25\xa3\x4b\xc9\x9f\x9a\x12\x42\x7b\x73\x35\xb9\x5c\x56\xf6\x69\ \xb2\x57\x91\x6a\x97\xd5\x6a\xb5\x33\x11\x81\x42\xf2\x63\x58\x54\ \x79\xf1\x4a\xe5\x8c\xdc\x40\x2d\xa7\x0e\x48\x80\x1e\x22\x4e\x78\ \x1f\x4e\x4e\x60\x08\x5e\xa5\x65\xb5\x01\x54\x57\x4a\xa9\xf2\x86\ \xb6\xf7\x94\xf9\xad\x24\xc1\xc8\x2e\xcb\x75\x86\x72\x76\xee\x7a\ \xbd\x36\x4d\xd8\x4a\x0a\xa9\xe7\xdc\xcb\xd4\x12\x60\x32\xbf\xea\ \x74\x3a\xc8\xb2\x0c\xd3\xe9\xd4\xf4\x60\xb2\x6f\x11\xf8\x6f\xf9\ \xe0\x18\x0f\x53\xf7\x7b\x09\x5a\xe6\xb3\x92\xc1\xb5\xef\x53\x47\ \x3e\x49\x72\x89\xe5\x1e\x12\x35\x75\x5e\x53\x7a\xbf\x3a\x16\xd7\ \x06\xb4\x0c\x97\x1f\x5d\x60\x22\x1c\xe6\xca\x06\xf9\x38\xbe\x3f\ \x1e\x38\x59\x96\xe9\x10\x6a\xf5\x9c\xfb\x8d\xde\x4f\x86\x97\x9c\ \x86\xc7\xee\x0b\x82\x52\xce\x75\xe5\x3e\x4b\xca\xf0\x6c\x6f\xc4\ \x10\xd9\x06\x83\x9d\xa7\xf2\x79\x78\xb1\xd6\x01\x84\x39\x65\x55\ \x78\x2b\x6b\xa7\x92\xa8\xa9\x12\xef\x1f\x6a\x3f\xb3\x3d\xaa\xfd\ \xd5\x5c\x50\x96\x52\x48\x7a\x4d\x8e\xf3\xb4\x85\x0f\xf2\x73\xe1\ \x61\xa7\x62\x04\xf5\x9c\x7b\x3d\x8e\xbc\xb8\x39\x2f\x87\xc0\x64\ \xb8\x49\x80\x3e\x3c\x3c\x98\x1c\xcf\x6e\xb3\xb2\x2f\xf2\x38\x8e\ \x71\x77\x77\x67\x40\xcc\x92\x08\xc3\x3b\xea\x79\x29\x80\xa8\x1a\ \xa5\x29\x3d\x4f\x9d\xe7\xdc\x77\xdb\x21\x6f\x7e\x6c\x1e\x6a\x1b\ \x35\xb6\xb2\x36\xdc\x68\x34\x10\x45\x91\x61\xb7\xed\xd7\x90\xde\ \x9d\xe0\x54\x53\xcf\xb9\x97\xad\x95\xa2\x76\x8e\xed\x90\xe4\x8f\ \xbc\xa8\x09\x52\xde\x7f\xb1\x58\x20\x49\x12\xf4\x7a\xbd\x9d\xf0\ \x6d\x3e\x9f\xe3\xd3\xa7\x4f\x46\x53\x2a\x45\xed\x1c\xfc\x4c\xe1\ \x80\xcd\x82\x56\x85\x98\x87\xc0\x69\x33\xb0\x72\xf6\x90\x54\x17\ \xd9\x7a\x57\xbb\x9b\xa4\xca\x6b\x56\xb1\xd3\x8c\x0a\x6c\x51\x3c\ \x95\x3f\x9c\x7c\x20\xef\x43\xcf\x4f\xcf\xa9\x61\xad\x7a\xce\x83\ \x9e\x93\xe1\x24\x65\x67\x72\xfd\x00\xef\x67\x13\x46\x7c\x1c\x97\ \x06\xd9\x17\x32\x37\x79\x35\x9b\xcd\x9d\x39\x43\x64\x7f\xf9\x18\ \x59\x4e\x39\xc4\x2a\x1f\xca\x39\x25\xc8\xed\x1d\x2c\x75\xa1\x6b\ \x9d\x17\xb5\xc1\xba\x6f\xa2\x3d\xc3\x5c\x4e\x61\xa0\x7c\xf0\x98\ \x83\x51\x4d\xc1\x59\x7b\xc1\xd3\xd8\x29\x41\xcf\x59\x15\xaa\xd2\ \xb3\x31\x4c\xed\x74\x3a\xa6\x55\x4b\x12\x1e\x65\x59\x1a\xd9\x9d\ \x9d\x97\xc9\x0b\x9b\xad\x5c\xf2\xf7\x24\x56\xec\x7f\xc7\x12\x42\ \xf4\xbc\xb2\xf5\xcc\x2e\x7f\xc8\x7d\xa0\x92\xc8\xa9\x02\xac\xed\ \x55\x6d\xf2\xc7\x06\x3b\xbb\x52\x18\xbe\x57\x1d\x0a\x76\x08\xaf\ \x61\xad\x5a\x6d\xbe\x45\x0f\xc6\xb0\xd5\x5e\xc3\x2e\x2f\x22\x0a\ \xdd\xd7\xeb\xb5\x19\x07\x42\xa6\x55\x7a\x2d\xb9\xb6\xc0\x96\xca\ \x51\x06\xc8\x70\x53\x86\x88\xd2\x53\xc9\x10\x77\x5f\x07\x8c\x0d\ \x44\x99\xcf\xd5\xb1\xb1\x55\xed\x63\xc7\x10\x45\xb2\x66\x6b\x77\ \xdb\x70\xed\x03\x87\xa2\xd9\x1e\x5a\x86\xc7\x36\xc0\x15\x9c\x6a\ \xb5\x17\x1e\xbd\x19\x2f\x6a\x39\x64\xab\x4a\x33\x4a\x00\xf8\xbe\ \xbf\x33\x4a\x52\x5e\xf8\xf2\xf1\x36\xc1\x43\x35\x92\x6c\x4b\xa3\ \x4a\x88\xd2\x36\x5b\x73\x7b\xc8\xd3\xc8\xc9\x09\x75\x13\x19\x6c\ \xb0\xd4\x79\x4c\xfb\xf0\xb2\xef\x6b\x87\xd1\x7c\xed\x34\x4d\x77\ \x08\x22\x02\x51\xfe\x9d\x55\xde\x58\xc1\xa9\x56\x09\x4a\x7a\x37\ \x0a\xd9\xa5\xaa\xc7\xf6\x1a\xf2\xf4\xe7\xcc\x1e\x0e\xb9\xe2\xe0\ \x65\x0e\x89\x96\x1d\x2d\x14\x1e\xc8\xd5\x7a\xcc\x6f\x79\xa1\x53\ \x80\x2f\xf3\x53\xbe\x8f\x3c\xcf\xd1\xef\xf7\xcd\x7c\x20\x69\x45\ \x51\x98\xd9\x3e\x75\x35\xd2\x43\x2c\x6e\xd5\x4e\x17\xbb\x94\x22\ \x0f\x80\xe5\x72\xb9\x33\xa7\x57\x7e\x2e\x1c\x93\x52\xf5\xfa\xb2\ \x24\xa4\x7b\x3c\x35\xe7\xac\xff\x50\x44\xff\xa1\xbd\x42\x41\x6e\ \x7d\xae\x0a\xbf\xe4\x60\xae\xf5\x7a\x8d\x77\xef\xde\xe1\xf6\xf6\ \xd6\x6c\x19\xeb\xf5\x7a\xa6\x86\x19\x86\x21\x4e\x4f\x4f\xcd\x26\ \x68\x76\x90\xb0\x71\x9b\x3b\x4a\xe4\x38\x4b\xf9\x1a\x14\xe5\xd7\ \x89\xc5\x39\xce\x84\xe4\x14\x43\x73\x1b\x80\xf6\x41\x73\xac\x4c\ \xaf\x2a\x57\x97\xb5\x61\xa9\x37\xb6\x9f\x43\xe6\xb8\x72\x9a\x44\ \xdd\xe7\xaa\x9e\x53\xcd\x18\x67\xae\xca\x69\x03\x76\x2f\xa7\x94\ \x9d\x49\x4f\x52\x14\x85\x99\x00\x90\xa6\x29\xde\xbd\x7b\x07\x00\ \x38\x39\x39\xc1\xb3\x67\xcf\xd0\xe9\x74\x00\xc0\x8c\xbb\xb4\x77\ \x9e\x70\xbe\xab\xef\xfb\xa6\x18\xcf\x0b\xd9\xbe\x80\x0f\xb1\xb5\ \x55\xeb\x22\x6c\x8f\x58\xb5\x2b\xa5\xaa\xf1\xbb\xaa\x4b\x65\x1f\ \x58\x29\xd5\xab\x7a\x2d\x46\x27\x24\x88\xe8\x79\x25\x19\xa6\xe0\ \x54\xab\xbd\xb0\x82\x20\x30\xa5\x0d\x9b\x40\x91\x13\xe7\x18\x86\ \x71\x17\x88\x5c\x28\xdb\x6c\x36\x91\xa6\x29\xae\xaf\xaf\xb1\x5a\ \xad\xd0\xe9\x74\x30\x18\x0c\x76\xf6\x95\xc8\x89\xe9\x72\xda\xc1\ \xfd\xfd\xbd\x21\x85\xd8\x26\x06\xfc\x3a\xda\x92\x13\x0d\xf6\xe5\ \x85\x36\xa9\x53\x05\xbc\xaa\x3c\xb8\xee\x7e\x55\xb3\x8e\xe4\x6b\ \x48\xed\xaf\x24\xa4\x24\x28\x6d\xed\x30\x41\xca\x43\x84\xc2\x7f\ \x35\x05\x67\x6d\xf8\xc6\x29\x75\xfb\x42\x2c\x79\x61\xcb\xfd\x26\ \xae\xeb\x62\x36\x9b\xe1\xea\xea\x0a\xc0\x7f\x05\x09\xd7\xd7\xd7\ \x68\xb5\x5a\x18\x0c\x06\xb8\xb8\xb8\x80\xef\xfb\x28\xcb\x72\x27\ \x64\x95\x21\x1e\xd9\x5d\xe6\xab\x72\xd4\x24\x4b\x31\xfb\x06\x4b\ \xdb\x0d\xd1\x55\xb9\x63\x1d\xe0\xf6\x09\xe0\xab\x9e\xc7\xfe\x4c\ \xe4\x40\x33\xf9\x19\x92\xbd\xdd\x6c\x36\xe8\xf7\xfb\xe6\xf9\x79\ \xd8\xa8\xe7\x54\x70\x1e\x34\x9e\xe0\x14\x03\xc8\x39\xab\xf6\x54\ \x3d\x39\x15\x8f\x3f\x33\xa4\x0d\x82\xc0\x14\xdf\x39\xfa\x92\xcc\ \xef\xe5\xe5\x25\x3a\x9d\x8e\xa9\x8b\xce\xe7\x73\xb3\xe0\x96\x80\ \xa5\x17\x61\xaf\x63\xd5\x04\x83\x7d\xa5\x94\xaa\x7c\x51\x1e\x2a\ \x75\xa1\xaa\x0d\xd0\x7d\x26\x0f\x01\xb6\xb8\x71\x75\xa0\x0d\x70\ \xd6\x7a\xdb\xed\xf6\x0e\xf3\x9d\xe7\xf9\x51\x07\xa2\x82\x53\xcd\ \x90\x41\x04\x29\x49\x17\x7a\x84\x7d\xf9\x16\xf3\xc0\xf9\x7c\x8e\ \x28\x8a\x0c\xf8\xe8\x61\xb7\xdb\xad\x59\xf0\x73\x7a\x7a\x8a\xd1\ \x68\x84\x30\x0c\x91\xe7\x39\xc6\xe3\xb1\x01\x68\xd5\x54\xbc\x2a\ \x52\xa6\x4a\xfc\x7e\xcc\x04\xc0\x7d\xb7\x57\x81\xb2\xae\xf6\x69\ \xd7\x7f\xd9\x36\xc7\xcd\x66\x00\x4c\x14\x90\x24\x89\x99\x2c\x4f\ \x63\x03\x39\xc1\xa9\x61\xad\x82\xf3\x60\xce\xc9\x0b\x85\x2b\x15\ \xaa\x64\x6f\x12\x14\xb2\x4c\xc2\xf0\x74\x32\x99\x20\x8a\x22\xd3\ \x4f\x29\x81\x96\xa6\x29\x3e\x7d\xfa\x84\xf5\x7a\x8d\x8b\x8b\x0b\ \x2c\x16\x0b\x43\x0e\x55\xcd\xe7\xb1\x43\x48\xfe\x6c\xeb\x80\x79\ \xff\xaa\x6e\x96\xba\x69\x07\xfb\x88\x9f\x3a\x32\xc9\x06\x31\x47\ \x63\xb2\xa6\x39\x9f\xcf\xcd\xc0\xeb\x24\x49\x4c\xfe\xce\x92\x12\ \x07\x82\xc9\x7c\x7d\xdf\x80\x6c\x05\xa7\x9a\x01\x50\xbb\xdd\xc6\ \x72\xb9\x34\x40\xa5\x68\xfb\x18\x89\x99\x9c\xce\xce\x31\x26\xb6\ \x16\x97\x75\x4a\x0e\xae\xf6\x3c\x0f\xfd\x7e\xdf\x34\x73\x4b\x70\ \x32\x4c\x94\xb5\x42\xdb\x73\xda\x21\xad\xac\x29\xda\x25\x93\x7d\ \x93\xf4\x6c\x95\x4f\x15\x70\xed\xc7\xb1\x96\xca\xcf\x88\x6a\x27\ \xe6\xc9\x5c\xed\xc0\xee\x93\xcd\x66\x83\xc5\x62\x61\x36\x64\xaf\ \x56\x2b\x74\xbb\x5d\x05\xa7\x82\xf3\x38\x52\x88\xdb\xa4\x3f\x7c\ \xf8\x60\x18\x53\x7a\xa4\xa7\x18\x37\x3c\x7b\x9e\xf7\x68\x97\xa5\ \xe7\x79\x98\x4c\x26\x68\x36\x9b\x18\x0e\x87\x08\x82\xc0\xac\x75\ \xa0\x07\x67\x93\x34\x3d\x24\x73\x50\x02\x95\x42\x06\xdb\xa3\xd7\ \x0d\xd4\xaa\x0a\x5d\xed\x7c\xf3\x18\xe9\x9e\x14\xb7\x53\x1d\x25\ \xe5\x8a\x5c\xef\x60\x13\x67\x6c\x8b\xe3\xf6\x33\x3e\x2e\x0c\x43\ \x05\xa7\x82\xf3\x38\xf3\x7d\x1f\x61\x18\x1a\x72\x87\x1e\xac\xae\ \xe7\xd0\xd6\xbd\xca\x61\xce\xad\x56\x0b\xbe\xef\x3f\xda\x46\xc6\ \x52\xc2\x64\x32\x41\x51\x14\x88\xa2\x08\x61\x18\x1a\xe0\x85\x61\ \x88\xe1\x70\x08\xcf\xf3\xcc\xf0\x2b\xd9\xd1\xb2\xd9\x6c\xd0\x6e\ \xb7\x1f\x91\x28\x5c\xf9\xc7\x03\xc1\xee\x16\xb1\x81\x78\x88\xf8\ \xa9\x23\x89\x98\x2b\xf2\xe0\xa8\x63\x85\xa5\x57\x66\x64\xc0\x03\ \xa8\x28\x0a\xb3\x3d\x5b\x9b\xac\x15\x9c\x47\x33\xb6\x51\x14\xc1\ \xf7\x7d\xa4\x69\x6a\xd4\x3b\x94\xa7\xc9\x12\x88\xcd\x82\xda\x39\ \x21\x57\x0d\x74\x3a\x9d\x1d\x21\xb8\xbc\x78\x19\x06\x52\x3d\x33\ \x1a\x8d\x0c\xa9\xc2\x7a\x6a\x55\x79\xa4\xce\xc3\xb5\xdb\x6d\x9c\ \x9d\x9d\xed\x0c\x1c\x3b\x04\x9e\xaa\x9f\xab\x48\x21\xb9\xa5\x9b\ \xec\xf2\x21\x52\x89\xe1\xad\xdc\x3f\x4a\xa5\x53\x18\x86\x66\x52\ \xbe\xda\x7f\x0e\x32\xfd\x08\xf6\x93\x42\xec\xe0\x67\x49\x45\xe6\ \x83\x14\xb7\xdb\x82\x6f\x7a\x08\x12\x24\xcd\x66\x73\xa7\x5d\x8c\ \xcb\x84\x64\x4e\x28\x73\x45\xb2\x9d\x9c\x84\x20\x77\x77\xca\x95\ \x81\xfb\x0e\x05\x86\xb5\xbe\xef\x63\x30\x18\x20\x0c\xc3\x47\xa3\ \x2e\xab\xc0\x58\x37\xe3\xc8\x06\x1c\xc9\x1b\x19\xba\x1e\x03\x68\ \xe9\x41\xe5\x5e\x99\x7e\xbf\x8f\x28\x8a\xf4\xa2\x53\x70\x1e\x9f\ \x77\xb6\xdb\xed\x47\x03\x9c\xe5\xbc\x5a\x00\x66\xe5\x9f\x2c\x5f\ \x50\x47\xcb\x90\x93\x3a\xd9\xf9\x7c\x6e\x4a\x06\x87\xba\x2f\xec\ \xe5\x46\xf6\x7b\x93\xb5\x45\x9b\x10\x92\x60\xa0\xf0\x81\xab\x1b\ \x38\x29\xb0\x4e\x5b\xbb\x4f\x43\x4b\x60\x92\x20\x23\x01\xb4\x0f\ \x90\x55\x53\xe4\xc3\x30\x34\x8c\xad\xe3\x38\x18\x8d\x46\x08\x82\ \x40\x2f\x3a\x0d\x6b\x9f\xf0\x01\xb9\x2e\xfa\xfd\x3e\x3a\x9d\x8e\ \x99\x0b\x24\x3d\x13\x73\xad\x56\xab\xb5\x13\xe2\x51\x90\x4e\x19\ \xa0\xec\xdf\xe4\xfd\x39\x95\xa0\xaa\xb4\xc1\x3d\x96\xd2\xc3\xda\ \xb9\xe2\x3e\xcf\x69\xe7\x92\x7c\x7f\x24\xb4\xd2\x34\x45\x1c\xc7\ \x3b\xd3\x1d\xea\xba\x50\xe4\x73\x72\x80\xd7\xbe\x89\x0a\x55\xef\ \xc9\x16\x72\xb4\xdb\x6d\x33\x8e\x65\x30\x18\xa0\xdf\xef\x6b\x7d\ \x53\x3d\xe7\xd3\xc1\xd9\xed\x76\xd1\xef\xf7\x77\x4e\x76\xe9\x59\ \xd8\xe5\xcf\x46\x69\x8a\xde\xd9\x43\xc9\xae\x12\xd7\x75\x4d\x28\ \x48\x6f\x6a\xb3\xa8\x04\xe6\x60\x30\xc0\xf9\xf9\xb9\x79\x9e\x3a\ \xb6\x75\x5f\x8e\x58\xd5\xcc\x2c\xc1\x51\xe7\xa9\xea\xf6\x73\xba\ \xae\x6b\x86\x77\x91\x75\xae\x6b\xd4\xb6\x3d\xbc\xfc\x5d\xab\xd5\ \xda\xf1\x9a\x67\x67\x67\xa6\x19\x40\x4d\x3d\xe7\x93\x8c\xf3\x56\ \xa9\xde\xb1\x1b\x85\xe5\x44\x02\x59\x0b\xa5\xc7\x64\xa3\x34\xd7\ \x05\xb2\x47\x74\x38\x1c\xc2\x71\x1c\x24\x49\xb2\xa3\x27\x6d\xb7\ \xdb\x66\x6d\xfd\xbe\xb1\x98\x76\x97\xcc\x3e\x60\x56\x49\xf7\xe4\ \xd0\xea\x43\x53\xde\xc9\x36\xf3\xb0\xa9\x62\x7b\x0f\x79\x50\x7e\ \x6e\x61\x18\x9a\xb6\xb9\x6e\xb7\x8b\x93\x93\x13\x65\x69\xd5\x73\ \xfe\xb6\xd0\x76\x30\x18\x98\xdc\x52\xd6\x0e\xeb\x26\x02\xa4\x69\ \x8a\xc5\x62\xf1\x08\xa8\x04\xf3\x62\xb1\x40\xb7\xdb\x35\x35\x4c\ \xbb\xbe\x58\x95\xab\x55\xe5\x87\xc7\x84\x95\xf6\x74\x3d\x86\xb3\ \xac\xa1\x52\xd3\x5a\x35\x05\x81\x39\x26\x81\x59\xf5\x9c\x75\xa0\ \xb6\x6f\x0f\x82\x00\xbe\xef\x1b\x25\xd4\xd9\xd9\x19\xba\xdd\xae\ \xb2\xb4\xea\x39\xff\xff\xc6\xc6\xe8\x87\x87\x87\xbd\x13\xe4\xec\ \x3a\x22\x19\xde\xa2\x28\x4c\x01\x9e\x4c\x30\x19\x5c\xf6\x75\xda\ \x13\xe6\xab\x40\x6f\x7f\x3d\x54\xa3\xac\xfa\x3d\x73\x50\x92\x42\ \x14\x02\x50\x18\xc0\xbc\x54\x8e\x45\x61\x68\x2e\x95\x4e\xf6\xf3\ \xef\x7b\x2f\x32\x9c\xe6\xc6\xb4\x7e\xbf\x8f\xb3\xb3\xb3\x47\x13\ \xe8\xd5\x14\x9c\x4f\xf6\x9e\xc3\xe1\x10\xc3\xe1\x10\x59\x96\x3d\ \xea\xde\x97\xfd\x89\x55\xbb\x42\xe4\x18\x0f\xe9\x1d\x29\x04\x27\ \x58\x39\x20\x4c\x8e\x2c\xa9\x2a\xd3\xc8\xe7\xae\x62\x74\xf9\x9c\ \xd2\x93\xdb\x9b\xa8\x65\x1f\x2a\x65\x75\x72\xfb\x34\xff\x3e\xf6\ \x8f\xd2\x0e\x85\xc1\xf6\xe1\xc1\x43\x8a\xb9\xe6\x7c\x3e\x37\xb9\ \xe6\x70\x38\x54\xaf\xa9\x61\xed\x6f\xb7\x4e\xa7\x83\x8b\x8b\x0b\ \x93\x33\xd9\x53\xf4\xea\x58\xd3\x2a\x72\x45\xee\xca\x64\xe8\xcb\ \xa9\x7d\xd3\xe9\x14\xb7\xb7\xb7\xc8\xb2\x6c\xe7\x7e\x76\xd8\x2c\ \x67\x16\xd5\x6d\xce\xb6\xcb\x2c\x55\xbd\x9b\xf6\x6d\x52\xf4\xbf\ \xef\xef\xd9\xc7\x16\xdb\xb7\xcb\x3d\x9c\x69\x9a\x62\x30\x18\xe0\ \xea\xea\x4a\xbd\xa6\x82\xf3\x2b\x7d\x58\xff\x51\xed\x9c\x9d\x9d\ \x19\x85\x50\x95\x30\xc0\xbe\xf0\xab\x58\x4c\xfb\xe2\x9d\xcf\xe7\ \x66\x76\x90\xeb\xba\x98\x4c\x26\x98\x4c\x26\xe6\x75\x8f\x25\x5f\ \xf6\xe5\xc1\x55\x87\x88\x5d\xa2\xe1\x2e\x15\xee\x84\x61\x1f\x69\ \x1d\x19\x55\xb7\x8c\xd7\x36\x2e\x78\x8a\xe3\x18\xbe\xef\xe3\xf9\ \xf3\xe7\x18\x0c\x06\x3a\x69\x4f\xc1\xf9\x75\x99\xdb\xab\xab\x2b\ \x9c\x9c\x9c\x18\x62\x85\xde\x46\x0a\xd0\xeb\x72\xc5\xaa\xdb\xe5\ \x5e\x4f\x00\x66\x9f\xe6\x64\x32\xc1\x74\x3a\xad\x95\xec\x49\x82\ \x67\x9f\x47\xab\x6a\xd0\xae\x3a\x78\x48\x0a\xb1\x31\x3c\xcb\x32\ \x13\xd2\x56\x1d\x38\xb2\xc4\x53\xe7\x85\xf9\xdc\x2c\x9d\x94\x65\ \x89\xf3\xf3\x73\x5c\x5d\x5d\xe9\xc4\x03\xcd\x39\xbf\xae\x39\x8e\ \x83\xc1\x60\x80\x17\x2f\x5e\x98\xe9\x76\x52\x0f\x4b\x90\xda\x8b\ \x90\x0e\x8d\xfe\xa0\xcd\xe7\x73\x74\x3a\x1d\x44\x51\x84\x34\x4d\ \x31\x99\x4c\x4c\xad\xd5\x26\x9a\x78\x71\x4b\x31\x3c\x7f\x96\x1a\ \x60\x8a\x25\x6c\x01\x85\xdd\x29\x22\x77\x92\x66\x59\x86\x38\x8e\ \x4d\xae\x59\xe7\x79\xab\x84\xf4\x04\xa4\x3c\x88\xd8\x40\x3e\x1c\ \x0e\xf1\xf2\xe5\x4b\xad\x6b\x2a\x38\x7f\x3f\x72\xe8\xfc\xfc\x1c\ \x59\x96\x99\x7a\x9d\xcc\xeb\xe8\x29\xaa\xda\xcb\xe4\x8a\x84\xaa\ \x1c\x90\x63\x3e\x38\xbe\x24\xcf\x73\xb3\xc1\x8c\xb2\x3b\x5b\x30\ \x5f\x35\x43\xc8\x9e\xaf\x6b\xf7\x7f\xd2\x5b\xf3\x3e\xec\x3b\x65\ \xb8\x4e\x85\x53\x95\x57\xb6\x3d\x64\x5d\xfb\x19\x8d\x65\x9b\x4e\ \xa7\x83\x17\x2f\x5e\x60\x34\x1a\x69\x38\xab\x61\xed\xef\x1b\xde\ \x5e\x5e\x5e\xe2\xf2\xf2\xd2\x10\x39\x72\x22\x1f\x4b\x12\x72\xf0\ \xd7\xa1\x95\x7a\x04\x8d\xdc\xf0\x1c\x45\x11\x36\x9b\x0d\xee\xef\ \xef\x31\x9b\xcd\x76\x46\x63\xd6\xf5\x66\x56\x2d\x18\x92\x60\xa0\ \xa4\x90\x60\xa7\x4e\x58\x7a\xd9\xaa\xc9\xf0\x75\xde\xd3\x0e\x8f\ \xe5\x4a\x05\x1e\x46\xad\x56\x0b\x97\x97\x97\x78\xf6\xec\x99\x0a\ \x0e\xd4\x73\xfe\xfe\x16\x45\x11\x2e\x2f\x2f\xb1\x5c\x2e\x71\x77\ \x77\x67\xd8\x55\x5e\xa4\x1c\xf9\x48\x40\xd8\xeb\xf3\xaa\x84\x0c\ \x72\x0f\x4b\x1c\xc7\x08\x82\x00\xed\x76\x7b\x67\x31\xef\x7a\xbd\ \x36\x6c\x6a\x9d\x00\xc0\x5e\x8b\x60\x77\xa3\x48\x26\x57\x82\x89\ \x9e\x9b\xe1\xed\xbe\xd5\x0c\x55\x23\x4c\x6c\xb6\x98\xaa\xa8\x8b\ \x8b\x0b\xbc\x78\xf1\x42\xc3\x59\x05\xe7\x1f\xc7\xde\xf6\xfb\x7d\ \x3c\x7f\xfe\x1c\x9b\xcd\x06\xe3\xf1\xd8\x00\x54\x5e\xf4\x76\x28\ \x6b\x7b\x22\x39\xfd\x5c\x82\x80\xe4\x4c\xa3\xd1\xc0\x70\x38\x34\ \xe3\x31\xd9\xa8\x6c\xef\xd7\xac\x1b\x91\x29\x27\xab\xcb\x55\x0f\ \x12\x50\x3c\x48\x38\xc6\x53\x4e\x34\xd8\x37\xd8\x4b\x7e\x6f\xb3\ \xb6\x8c\x1c\x2e\x2e\x2e\xf0\xea\xd5\x2b\x93\x37\xab\x29\x38\xff\ \x10\xe3\x78\x11\x5e\x90\xd3\xe9\xd4\xe4\xa2\xcc\x4f\xab\x98\xd6\ \xaa\x19\x40\x72\x4d\x81\x2c\xcc\x73\x4d\x03\xf5\xad\xfb\xf2\x3d\ \xf9\x7b\x12\x46\xb2\x83\xc6\x16\x34\xb0\xfe\xc8\x81\x63\x0c\x41\ \xa9\x05\xae\x0a\x93\x09\xf8\x7d\xa0\x64\x33\xf9\xc5\xc5\x05\x7e\ \xfe\xf9\x67\x6d\xa4\x56\x70\xfe\x39\xec\xad\xeb\xba\x38\x39\x39\ \x31\x60\x9d\x4c\x26\xc8\xb2\xcc\x5c\xdc\x12\x6c\x75\xc3\xb6\xaa\ \x04\x0a\xd2\xdb\x25\x49\x82\xa2\x28\x10\x04\xc1\x8e\x16\xd6\x9e\ \x97\x6b\xb3\xaf\x92\x99\xb5\x5f\x87\x92\x3d\x39\xd1\xa1\xd7\xeb\ \x21\xcf\x73\xcc\x66\xb3\x47\xcb\x82\xf7\xd5\x72\xe5\x7b\x27\x7b\ \x7d\x71\x71\x81\x5f\x7e\xf9\x05\xa3\xd1\x48\xdb\xc1\x14\x9c\x7f\ \x1e\x40\x9b\xcd\xa6\x61\x21\x1d\xc7\xd9\x19\x0d\x42\xaf\x65\x87\ \xaf\xb6\x07\xab\x1b\x21\xc2\x16\xad\x3c\xcf\x91\xa6\x29\x56\xab\ \x95\x11\x90\x57\xf5\x61\xca\x19\x47\x75\xf5\x4f\x2e\x48\xaa\xea\ \x15\xad\xda\xa2\xb6\x4f\xd8\x20\xbd\x32\x95\x53\x57\x57\x57\xf8\ \xf9\xe7\x9f\x31\x1c\x0e\x15\x98\x0a\xce\x6f\xc7\x83\xba\xae\x8b\ \x0f\x1f\x3e\x00\x80\x59\xa7\x20\xc3\x57\x7a\xb7\x2a\x50\xca\xfc\ \xd0\x66\x48\xc9\xb2\x72\x5a\xba\x24\x8f\xe4\xce\x16\x3b\xbc\xb5\ \xf5\xbd\x6c\x72\xae\xcb\x1b\xe5\x50\xeb\x2a\xd1\x83\x2d\x40\xa0\ \x77\x5e\xad\x56\x68\xb5\x5a\xf8\xe9\xa7\x9f\xf0\xe2\xc5\x0b\x23\ \xa6\x50\x53\x70\x7e\x33\x1e\x74\x30\x18\x98\x89\x01\x77\x77\x77\ \xa6\x09\x5b\xb2\xab\xf4\x34\x54\x15\x55\x85\xb8\x64\x7c\x59\x8a\ \xe1\x98\x4c\xe6\x9d\x12\x20\xbc\x9f\x0d\x38\x49\xec\xb0\xc4\xc3\ \x7c\xb2\xca\x5b\xf3\x76\x3b\x37\xb5\x45\xf3\xb6\x7e\x97\x4b\x9a\ \x5e\xbe\x7c\x89\xab\xab\x2b\x33\x27\x49\x4d\xc1\xf9\xcd\xb1\xb8\ \xdd\x6e\x17\xaf\x5e\xbd\x82\xef\xfb\xf8\xf4\xe9\x93\x99\x82\xce\ \xdb\xb9\xde\x8f\xa4\x8d\xf4\x66\x54\xf7\xb0\xad\x4b\x82\xcf\xde\ \xd6\x25\x41\xc5\xe9\xf4\x24\xa2\x38\x89\x81\x0d\xe2\x04\x68\x1d\ \x39\x25\x01\x5c\xb7\xbc\xc8\x16\xd4\x13\xc4\x27\x27\x27\x78\xf1\ \xe2\x05\xce\xce\xce\x4c\xdd\x57\x4d\xc1\xf9\xcd\x7a\xd1\x20\x08\ \xf0\xf2\xe5\x4b\x74\xbb\x5d\x5c\x5f\x5f\xe3\xe1\xe1\xc1\x4c\x3e\ \xa7\xb0\x1c\xf8\xaf\x28\x9c\x6b\x0a\xa8\xd9\x9d\xcf\xe7\x28\xcb\ \xd2\x4c\x82\x67\x8e\x59\x35\xfb\x96\xc0\x02\x60\xfa\x25\x65\x19\ \xa7\xaa\xbb\xc5\x06\x1e\x1f\xcb\x43\xc2\x16\x1c\xd8\x1d\x30\xec\ \x0b\x7d\xf6\xec\x19\x7e\xfa\xe9\x27\xf4\x7a\x3d\xf3\xfe\xd5\x14\ \x9c\xff\x33\x79\x68\x18\x86\xb8\xbb\xbb\xc3\xed\xed\xad\x21\x8b\ \x64\xc9\x43\xea\x60\xe9\xcd\xe8\x2d\x5b\xad\xd6\x4e\x9e\xc9\x71\ \x94\x9e\xe7\xc1\xf3\x3c\xac\xd7\x6b\x43\xee\x70\x2a\x1e\x73\x5d\ \x12\x3c\x72\xbd\xbd\x5c\xf6\x2b\xf3\x48\xae\x86\xb0\xf3\x49\x09\ \x48\xd9\xfb\x19\x04\x01\x9e\x3f\x7f\x6e\xd6\x19\xda\x64\x97\xda\ \x6f\xbc\x7e\xb6\x87\x96\x7e\xa8\x7d\x15\x23\x61\x12\xc7\x31\xc6\ \xe3\x31\xc6\xe3\xb1\x91\xe3\xc9\xc9\xef\x12\x50\xb2\x34\x42\xad\ \x2d\x67\xe1\xf2\xf7\x9c\x01\xb4\x5c\x2e\x11\x45\x11\xfa\xfd\x3e\ \xe2\x38\x46\x1c\xc7\x3b\x84\x93\x7c\x4e\x09\x50\x02\x8e\xe5\x13\ \xb6\x87\xd9\x4d\xde\xbc\x1f\x87\x7c\x0d\x87\x43\x5c\x5c\x5c\xa8\ \xb7\x54\x70\x7e\x5f\x20\x2d\xcb\x12\x71\x1c\x63\x3a\x9d\x62\x3c\ \x1e\x63\x32\x99\x98\xfd\x28\x52\x90\x6e\x0b\x12\x38\x31\xbe\xd3\ \xe9\x98\xe5\xb9\x92\xf8\x89\xa2\x08\xdd\x6e\x17\x8b\xc5\xc2\x80\ \x53\x0a\x1c\xa4\xa7\x26\x39\xc5\x59\xba\x9c\x42\x2f\x15\x4b\x04\ \x3d\x47\x7c\x72\x2a\xfb\xe9\xe9\x29\x06\x83\x81\xf1\xf6\x6a\x0a\ \xce\xef\xca\x48\xd6\x24\x49\x82\xd9\x6c\x86\xf1\x78\x8c\xe9\x74\ \x6a\x88\x1d\x99\x4f\x4a\xaf\xc7\x29\x05\xdc\x1b\xca\x11\x9b\x5c\ \x1d\x11\x45\x11\x66\xb3\x19\xbe\x7c\xf9\x62\xbc\xa0\xad\x48\xa2\ \x17\x67\xce\x2b\x57\xbd\xf3\x7d\xf1\x36\xee\x8b\x19\x0c\x06\x18\ \x8d\x46\x66\xc0\xb6\x32\xb1\x0a\xce\xef\xd6\x7b\x12\x08\x72\x08\ \x75\x92\x24\x98\xcf\xe7\x88\xe3\xd8\xd4\x1a\x65\x4d\x51\xd6\x40\ \xe5\x73\x31\x07\x3c\x3f\x3f\xc7\xc9\xc9\x09\x1e\x1e\x1e\xf0\xf1\ \xe3\xc7\x47\x3b\x3b\xeb\x86\x47\x4b\x21\x01\xc1\x1a\x04\x81\x09\ \x93\x39\x54\x5b\x41\xa9\x84\xd0\x0f\x05\x4c\x86\x9c\xec\x32\x69\ \xb7\xdb\x18\x0c\x06\xc8\xb2\xcc\xfc\x2b\x8a\x62\x67\x2a\x5e\xd5\ \x58\x90\x24\x49\xcc\xf3\x4f\x26\x13\x24\x49\xf2\x48\x91\x44\x0f\ \x5c\x35\xf8\xb9\xd5\x6a\x99\x36\xb2\x76\xbb\x6d\xbe\x72\x75\xa1\ \xdd\x55\xa3\xa6\xe0\xfc\x6e\x01\x6a\x97\x27\x24\x29\xc4\x92\x0a\ \xc7\x48\x32\xcc\x64\xfe\xc7\x55\x08\x12\xac\xac\x4d\xf2\x76\x32\ \xb4\xf4\xb8\xfc\x2a\xc3\x63\xce\x0b\xe2\x42\x26\xd6\x56\x29\xa0\ \x90\x80\x94\xde\x5b\x4d\xc1\xf9\xfd\xe7\x14\xc2\x93\xf1\xab\xad\ \x6d\x25\x88\x82\x20\xd8\x01\x24\xbf\x97\x8a\x1d\xdf\xf7\xcd\xf0\ \xea\x4e\xa7\x53\xd9\x3f\x4a\x86\x97\xa4\x10\x47\x70\x32\x7f\xad\ \xdb\x64\x66\x1f\x2e\xea\x3d\x15\x9c\xdf\x25\x20\x25\x30\xe5\xef\ \x25\x58\xab\xca\x1d\xf2\xab\xed\x81\x01\x18\x90\xf9\xbe\xbf\x33\ \xc9\xa0\x6a\xc0\x97\xf4\xa2\xf2\xeb\xa1\x7f\x0a\x4a\x05\xe7\x77\ \x6f\xb6\xa7\xb4\x5b\xbb\x6c\x45\x4f\x55\xd3\xb3\x3d\x7f\xc8\x1e\ \x0d\x52\xa5\xd9\xad\x92\xee\x55\xd5\x42\x25\xf9\xa4\xa0\x54\x70\ \xfe\x50\xde\x53\x76\xa1\x48\xb0\xd6\xad\x5c\xa8\x6b\xdb\xb2\x43\ \xcd\x2a\x26\xb6\x8a\xdd\xad\xdb\xbf\x62\x7b\x75\xbb\xab\x45\xed\ \x0f\xbc\x4e\xb4\x94\xf2\x6d\x91\x44\x75\x5b\xab\xeb\x06\x44\x57\ \x79\xc2\x7d\x80\xde\xf7\xb8\x3a\xb0\xab\x29\x38\xd5\x9e\x00\xe4\ \x63\x40\x54\x05\xcc\x7d\x80\x54\x53\x70\xaa\xa9\xa9\x1d\xc3\x4b\ \xe8\x47\xa0\xa6\xa6\xe0\x54\x53\x53\x53\x70\xaa\xa9\x29\x38\xd5\ \xd4\xd4\x14\x9c\x6a\x6a\x0a\x4e\x35\x35\x35\x05\xa7\x9a\x9a\x9a\ \x82\x53\x4d\x4d\xc1\xa9\xa6\xa6\xa6\xe0\x54\x53\x53\x70\xaa\xf2\ \xa6\xcf\x7c\x00\x00\x00\x25\x49\x44\x41\x54\xa9\xa9\x29\x38\xd5\ \xd4\xd4\x14\x9c\x6a\x6a\x0a\x4e\x35\x35\x35\x05\xa7\x9a\x9a\x82\ \x53\x4d\x4d\x4d\xc1\xa9\xa6\xf6\x23\xda\xff\x01\xb7\xbe\xbf\x34\ \x7c\xc5\x7a\x2d\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \ \x00\x00\x0c\x69\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ \xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x2e\x23\x00\x00\ \x2e\x23\x01\x78\xa5\x3f\x76\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ \xde\x03\x0c\x12\x05\x12\x78\xfa\xe0\x84\x00\x00\x0b\xf6\x49\x44\ \x41\x54\x58\xc3\x9d\xd7\x69\x90\x5c\xd5\x75\xc0\xf1\xff\x7d\xef\ \x75\xbf\x5e\xa6\x7b\xf6\xa5\x47\xcc\x22\x89\x19\x49\xa3\x05\x09\ \x89\x45\x80\x89\x01\xe1\x24\x88\xb0\x83\x65\x4a\x04\x41\x22\x30\ \xd8\xae\x80\x29\x8c\x01\x83\x08\x81\xc4\xd8\x89\x31\x01\x1b\x03\ \xe5\x38\x18\x0a\x01\x02\x04\x48\x48\x02\x8d\x24\x04\x48\x62\x98\ \xd1\x3e\x1b\x33\x9a\x9e\x7d\xed\xe9\x6d\xe6\x75\xbf\x5e\xde\x7b\ \x37\x1f\x08\x95\x38\x89\xcb\x84\xfb\xf5\xde\x3a\xe7\x57\xe7\xd4\ \xbd\x75\x8f\xe0\x6b\xac\x4d\x0f\x2d\xa5\x76\xe1\x49\x4e\x1c\xbc\ \x91\xfa\xc6\x1a\x7a\x3a\x5b\xc5\xb3\xcf\xed\x95\xff\xf3\x9c\x94\ \x52\x00\xee\x9e\xfd\x5b\xf4\x4f\xc3\x9f\xb8\xae\x1b\x7a\x2a\xee\ \x7f\x44\x38\x5f\xee\x9f\xd3\xd8\x84\xf8\x3a\x80\xf6\xc9\x66\xf6\ \x6e\x69\x51\x57\x5e\x7e\x15\xe7\xd7\x2f\xb6\xbf\x4c\xf6\xdb\xb7\ \x1e\xac\xde\xd5\xbc\xf7\xbc\xb1\xd1\xd8\x19\x65\x41\xf3\x74\x33\ \x6f\x56\xba\x82\x35\xa5\x8d\x73\x8b\x0a\xaa\xfc\x51\xaf\xab\x24\ \x7b\x2a\x40\xf5\xd6\x8d\x45\xb7\x3e\xb5\x69\xe7\xeb\xf2\xd1\x5f\ \x6f\x73\xbe\x12\xa0\xf5\xf0\x0b\x9c\xb5\x72\x23\xef\x3e\x7b\x37\ \x57\xdc\xf1\x24\x00\xef\x6f\x7b\x3c\x60\xc8\x9a\x79\x71\xd3\x5c\ \x39\x15\x99\xf8\x96\xdb\x23\x56\xf9\x5c\x95\xf5\xc5\xa5\x73\xd4\ \xda\xe5\x75\x0c\x4d\x4d\x49\xd5\x6b\x39\x5d\xc7\x5f\x45\xe4\xdf\ \x91\x65\xe2\x5c\x8c\xa1\x3c\xed\xc7\x5a\xb5\xd8\xa8\xff\x27\xdb\ \x0f\x8c\x3e\xfe\x97\x97\x56\x09\xed\x4f\x25\x7f\xf5\x99\xbb\x39\ \x6b\xe5\x46\x9e\x7e\x78\xbd\x72\xc5\x1d\x4f\x3a\x72\xf8\x2d\xdf\ \x0b\xfb\x0f\xdf\xd3\xdc\x62\xdc\x92\x2f\x1a\xac\x4e\xd6\x09\xbd\ \x62\xd1\x14\x8b\xab\xeb\xa8\x58\x70\x36\x1d\xf1\x23\x52\xcc\xa6\ \xf9\xf0\x95\x87\xc5\xca\x9a\x90\x9a\xf1\x16\x51\x10\xf5\xd0\x4e\ \x07\x8d\x91\x69\x2a\x64\x9a\xa4\x66\x5f\x01\x3c\x9e\x68\x9f\x40\ \xfd\x63\x89\xff\xe5\x67\xff\x8a\x35\xfe\x09\x75\x73\x42\xec\xf8\ \xb8\x9d\x1d\x1f\x1e\xc7\x8e\x1c\x5c\xbf\xb3\xa3\x7f\xf3\x9e\x7d\ \x9d\xd7\x9d\x79\xc6\x77\x02\x3b\xb7\xec\xd1\x56\xcc\xd1\x88\xe7\ \xc6\x45\x7e\xdc\xcf\xf0\x47\xbf\x67\xb2\x3b\x2c\x3c\x89\x29\xd1\ \xd9\x6b\xf0\xad\x6f\xfc\x15\x71\xb3\x0f\x23\x61\x20\x47\x92\x4c\ \x77\x65\x49\xc4\x35\xbc\xba\xda\x7e\x2c\x9c\x7b\xb9\x61\x39\xe2\ \x8f\x02\x8a\x6b\x06\xd9\xfe\xfe\x28\x3b\x3e\x6e\x67\x72\xf8\xb5\ \xd0\x3d\xb7\xdf\xf6\xa2\xd3\xd4\xf4\x80\x6b\xce\x92\xd2\xd6\x3d\ \xcd\xb2\xad\xb5\x4d\x1d\x1d\xee\x16\xc7\x3e\x3b\x22\x2e\xb8\xfa\ \x9b\x68\x5a\x8a\x0b\xaf\x6a\x61\x66\x50\xa7\xf8\xea\x12\x1a\x8b\ \x1b\xb1\x74\x49\xb4\xf5\x1d\x06\x0e\xc6\xf1\x44\x6d\x3e\xea\xd3\ \x30\x4c\x89\xcb\xe7\xdb\xda\x35\x98\xde\x7d\xf1\x92\xda\xff\xbb\ \x05\x5b\x76\x3d\x44\x77\xcf\x29\xf1\x1a\x9d\xf2\x8e\xf5\x2b\xe6\ \xdd\x79\xff\xb3\x3b\x1a\x2e\xf8\xf6\x02\xcb\x56\x9d\x89\xc9\x76\ \xc5\x8c\x27\x44\x2a\x9d\xc0\x4a\x5b\xb8\x8a\x21\x54\x73\x08\x99\ \xf7\xa3\x16\xf9\xc8\x27\xf2\xec\xde\x32\x4c\x49\xbc\x8b\x89\xee\ \x18\x75\x39\x95\xfe\xa1\x2c\xd2\xed\x62\xd1\x0a\x0d\x99\x53\x29\ \x2f\x0e\x66\x21\xc2\x9c\x79\xa5\xfc\x2f\xc0\xfb\xfb\x7e\xc1\x9f\ \x5f\xf4\x43\x00\xf9\xc8\x73\x1b\xe6\xa5\x44\xd9\xae\x0b\x37\xfc\ \xa0\x21\x26\x5d\xb2\xe7\xcd\x37\x15\x4e\x66\x09\xce\xab\x66\xea\ \x40\x17\x59\xd3\xe1\xcc\x4b\x16\xd1\x7b\xdc\x43\x6f\x74\x12\xff\ \xaa\x85\xb8\x16\x98\xa4\xdf\x8d\xd2\xb4\xa0\x92\xc8\x64\x94\x53\ \x8e\x8f\xb2\x15\x3a\xb9\xe4\x14\xa6\x61\x4b\x69\xe7\x05\x41\x33\ \x0c\xe0\xd5\x90\x7f\x00\xd8\x75\xe8\x31\x56\x2e\x0c\x01\x88\xad\ \xbf\xba\xad\xb8\xdd\xa3\xbe\xa1\x2e\xbd\x78\x7e\xf3\x6f\x9a\xb1\ \xdb\x77\x8b\x3b\xef\xbb\x9a\x77\xd2\x0b\x29\x58\xae\xe0\xf7\x29\ \x14\x04\x73\x2c\x38\xdf\xc3\xd2\xe5\x59\xa2\xaf\x64\xe9\x7b\x77\ \x12\xe1\xd5\x29\xcd\xcc\xf2\xf6\xef\xc3\x84\x96\x95\x60\x99\x51\ \x88\x66\xf1\xe6\x05\x16\xc2\xd1\x85\x6b\x36\x6d\xa6\x9b\xd7\x9f\ \x13\xd4\x56\xaf\xff\xae\xa5\xfc\x77\xc0\x87\x67\x64\x28\x2b\xfe\ \x0e\x52\x1e\xf1\x0c\xcf\x69\x7a\x31\xd6\x5f\xb5\x22\xb1\xe5\x03\ \x71\xd3\xba\x6a\x6e\x7e\x6e\x35\x29\xdf\x11\x26\xe3\x2d\x5c\x74\ \xd9\x02\x54\xe9\x27\xd2\x6f\x90\xf5\x14\x32\x10\x49\x11\x3a\xdd\ \x47\xdb\xd6\x51\xa6\xf7\x45\x39\x70\x60\x94\xb3\x6e\x29\xc5\x65\ \x0c\x91\xed\xcd\x92\x8d\x48\x84\x25\x65\x36\x9d\x57\x35\x32\xcf\ \xff\x76\x6b\x62\xf8\xd2\x1b\xd6\xda\xdf\x5c\x79\x1b\x7f\x00\x58\ \xd9\x69\x08\x80\xef\x3d\xfd\xf4\x63\xa9\x33\x4b\x2e\xff\x9b\x4d\ \x77\x48\xad\x41\x13\x2d\xf4\x71\x64\xcf\x00\xff\xfe\x8b\x66\x0a\ \xbd\x69\xe2\x6d\xc7\x29\xaf\x4e\xb2\x6a\xcd\x62\xd4\xe1\x71\xd2\ \xfd\x0e\xda\xac\x45\xa4\x67\x96\xf0\x64\x84\x92\x46\x1f\x7d\xcd\ \xc3\xe4\xc6\x4d\x8a\x55\x0b\xb7\x96\x93\x66\xca\x11\x5e\xd5\xf9\ \x20\xe4\x3d\xed\x51\x80\x9b\xef\xd9\x2c\x85\x10\xff\x05\x78\xf3\ \xf9\xb5\x44\x56\x3e\x29\xde\x69\x7e\xf0\xa2\x40\x49\xc1\x0f\x2a\ \x6b\xca\x9d\x18\x1d\xa2\xf3\xbd\x4f\x68\x7f\xe2\x55\xc6\xfb\x7a\ \xc8\xcf\x58\xc8\x78\x86\xf0\xbe\x23\x0c\x75\x24\x09\x06\x26\x69\ \xdb\x3e\xcd\xe8\x87\x49\x4e\x1c\x1c\x46\x0b\xa4\x69\x5a\x39\x4b\ \x4d\x60\x9a\xd6\x0f\x0c\xcc\x8c\x64\x26\x2d\xe4\xac\xe5\x16\xaa\ \x87\xed\x4d\x73\x8a\xd6\xfd\x6c\xdb\x40\xea\x87\x57\x96\xb1\xeb\ \xb5\xfb\x91\x52\x7e\xf1\x14\x4b\x29\x69\xfc\xe9\x06\x7a\xef\x7f\ \x91\x47\xde\xbb\x6f\xef\x8c\x2c\xbe\x68\xf2\x78\x0b\x7a\x75\x00\ \x7d\x7a\x14\x19\x8b\x12\x19\x48\x90\x30\x24\x73\x1a\x5d\xd4\x94\ \x2b\x7c\xb2\x3b\x42\x55\xa9\x1b\x05\x87\x7d\x9f\x65\xb9\xe1\xde\ \x4b\x18\x3f\xba\x8c\xf2\x82\x2a\x7c\x7e\xc1\x74\x24\x4b\x6f\x77\ \x1f\x9a\xd9\x42\xb1\x7f\x78\xf7\xa6\x0d\x63\x57\xae\xd8\x80\x09\ \xf0\xc2\x83\x6b\xd8\xf8\x78\x33\x00\x62\xac\xeb\x7a\xaa\x9f\xd9\ \x02\xbf\x82\x17\xdb\x36\xad\x0d\x5b\xfe\xed\xd1\xf1\x01\x99\xee\ \x3e\x24\x12\x1d\xe0\xf8\x6c\x96\xaf\xae\xc0\xb6\x0c\x5a\xde\x1b\ \x64\x51\x7d\x31\x66\x7c\x94\x63\x47\x25\x45\x67\x78\xa8\x2c\xbc\ \x86\x50\xf1\x25\x2c\x6a\x6a\xa0\xbf\x3f\xca\x74\xcc\x60\x74\x34\ \x81\x23\x05\x1e\xbf\x8e\xe3\x38\xa0\x68\x13\xdd\xed\x43\x6f\x77\ \xb4\xdc\xf3\xfd\xda\x85\xbf\x53\x86\xba\x6f\xc9\xc3\x8d\xc0\x2b\ \x5f\x54\xa0\x79\xbc\x47\xb9\xa4\xaa\x41\xfe\xe3\x89\x3d\x3b\x7a\ \x0f\xff\xf3\xa5\x25\x89\xa8\x9a\xb4\x7d\x2c\xac\x9d\xe0\xd8\xdb\ \x06\x99\x1c\x14\xf8\x54\x06\x07\xe2\xd8\x45\x6e\x16\x5f\xb2\x84\ \x91\x6d\x93\x2c\x3b\xff\x61\x6a\x6a\xeb\x59\x75\xde\x3c\x0e\x1f\ \x1d\xe5\x54\x7f\x94\x83\x9f\x0d\x53\x3d\xb7\x9c\xb2\xd2\x02\xc6\ \xc2\x63\xb8\x55\x55\x56\xd5\x97\x4b\x3b\x6f\x29\x47\x0e\xf5\x9d\ \x6a\xdb\xb3\xfd\x1c\xdb\xd9\x19\xfb\xb2\xf5\xaa\x74\x76\xf3\x8d\ \xc7\x3e\x57\xd6\x2c\x34\x2e\x38\xd0\x71\xfc\x1f\x26\x3e\xfd\x50\ \x58\x33\x51\x31\x71\x62\x9c\xc8\x60\x1c\x43\xd1\x39\xd4\x92\xa4\ \xf0\xdc\x6a\xea\xce\xaa\x62\x3c\x61\x12\x8a\x4b\xa4\xeb\x7b\x2c\ \x5b\xb5\x84\xf1\x69\x83\xb9\xa7\x57\x22\x5c\x6e\x4c\x07\xbc\x01\ \x0f\xe1\xfe\x08\xab\xcf\x9b\x8f\x2a\x1c\xdc\xba\x5b\x0c\x8d\xc4\ \x44\xd6\xb4\xe4\x92\x15\xb5\xa5\xf1\x19\xcf\x35\x33\xd1\xba\x57\ \x42\x8d\xeb\x72\x33\x91\xdd\x52\x8d\x35\xcd\x13\x7b\xee\xfe\x3b\ \x67\xf9\xc6\xeb\x9f\xb7\x0b\xaa\x4e\x0f\xef\x7f\x4f\x24\xa6\x66\ \x28\x52\xb3\x8c\x25\xdd\x04\xfd\x82\xb9\xc5\x92\x44\x77\x8c\xf1\ \xce\x29\x42\xc2\x21\x6b\xaf\x63\xcd\xda\x8b\xe9\x0a\x4f\xb3\x78\ \x49\x2d\xe5\x15\x41\x3c\xba\xc6\x6b\xdb\x4e\x32\x93\xb5\xc9\xda\ \x0e\x86\x99\xe7\xed\x0f\x7a\x88\xc4\xd3\x8c\x4d\x18\x08\x4d\x15\ \x81\x42\x9f\x2c\x2c\xf6\x95\xa6\x66\xad\x86\xc1\x8e\xfb\x5f\xfd\ \xfe\x4f\x76\xa2\x7e\xf6\xc6\x7e\xa4\x94\x0b\xba\xc6\x4e\x3e\xd9\ \xde\xb2\x9f\x74\x64\x90\xe8\xe7\x11\x66\x92\x50\xe6\x36\xc9\xc4\ \xb2\x18\x69\x1b\x49\x1e\xb7\x22\x49\xc7\xbd\xcc\x5b\x72\x33\x8a\ \xee\x45\x75\xeb\x5c\x75\xf9\x62\xa6\x12\x19\x62\x86\xc5\xe4\x6c\ \x8e\xba\xfa\x72\x4c\x4b\x22\x2d\x8b\xa8\x61\xb1\xb4\xb1\x8c\xb1\ \x98\x41\xda\xcc\x63\x66\x2c\x71\xe4\xd0\x29\x67\x6e\x7d\x59\x93\ \xaa\x9d\xbd\xff\x83\xb7\xfe\x76\x40\x01\xd8\x4b\xeb\xb5\x9d\x13\ \x27\xa8\x3a\xa3\x51\xca\x60\x29\x96\x57\xc5\xe5\x86\xf1\x88\x20\ \x9d\x92\x90\xb3\xd0\x73\x92\x12\x04\x85\x15\x6b\x31\x6d\x1f\x6e\ \x8f\xce\x95\x97\x35\x31\x38\x6e\xa0\x6a\x2a\x52\x53\x58\xb6\xb8\ \x9a\x92\x12\x3f\x2e\xbf\x4e\x6b\x7f\x9c\xe2\x32\x1f\x6d\x7d\x71\ \x54\x8f\x8e\xd4\x54\x14\xdd\x45\xc3\x8a\x79\x8a\xbb\xbc\xc8\x2a\ \x2e\x2b\xb8\x17\x40\x91\xb2\x4b\x3b\x78\x60\xe8\xda\x79\xf3\x57\ \xdb\x89\xf0\x5e\x11\xd2\x62\xa0\x7a\x30\xd2\x12\x2b\xab\x60\xa3\ \x60\xce\x4a\x62\xb3\x79\xf4\xc2\x4a\xfa\x23\x73\x51\x5d\x2a\xbd\ \xc3\x09\xa2\x33\x59\x84\xaa\x90\xb6\x24\x8e\x94\xd4\xcd\x09\x72\ \x6a\x24\x4e\x5b\x6f\x04\x4f\xc0\x4b\x4a\x0a\xdc\x01\x1d\xe1\x71\ \x63\xab\x0a\x86\x69\x51\x16\x2a\x22\x58\x12\x74\xf4\x02\xef\x0a\ \x9f\xff\xf6\xa0\x02\xb5\xee\x50\xb9\xed\x3b\xb1\xef\x0d\xc2\xc7\ \xc7\xe8\x09\x27\xf0\x3a\x79\x3c\x1e\x70\x34\x87\x78\x22\x47\x36\ \xe3\x60\x49\x08\x0f\xfb\x51\x5d\x5e\x3e\x6a\x1b\xe2\x70\x77\x84\ \xb8\x91\xc3\xe5\x52\xc1\x91\x54\x96\xfa\xe8\x1c\x88\xe2\xd6\x15\ \x2e\x5a\x75\x1a\x81\x22\x1f\x8e\xc7\x85\xe2\x75\xa3\x78\x34\x54\ \x8f\x0b\x97\x57\x23\x14\x0a\x52\x56\xec\xd3\x3c\x01\x6f\x95\xcb\ \x5b\x58\xa3\xdd\xfb\xd2\xbd\x7a\x64\x4a\x0f\x56\x35\x14\xc8\x92\ \xae\x31\x26\x27\xa2\x08\xc7\x21\xe3\x08\x90\x0e\x45\x3e\x15\x1c\ \x07\x97\x90\xa4\x33\x2e\xf4\x72\x1f\xb1\x94\x85\x91\xc8\x10\x9b\ \xcd\x62\x0c\xc6\x69\xeb\x9d\xa4\xaa\xa2\x10\x29\x25\x15\xa5\x05\ \x58\x52\xd2\x3e\x99\xc6\x23\x21\x9f\xcd\x83\x10\x38\x36\x28\xba\ \x1b\xd5\xe5\x22\x3e\x6d\x08\x45\x75\x09\x29\x9d\x02\xe5\xd1\x9b\ \x1e\xcb\x5f\xb6\xfe\xaf\x33\x9f\x6f\x7b\x97\x70\x67\x04\x47\x75\ \x23\x4d\x9b\x60\x26\x87\xae\x0b\xbc\xaa\x83\xb0\x41\x45\x52\x5a\ \xee\x23\x1a\x37\x51\x5d\x0a\x1e\x8f\x8b\xcd\xbb\x7b\xf0\xfb\x5d\ \x2c\x6f\xac\xc2\x01\x3a\x22\x26\x6f\x75\x44\x18\x4d\xe5\x99\xb6\ \x00\xaf\x0b\x45\x77\x23\x3c\x6e\xd0\x14\x14\x45\x92\xfb\xcf\x1b\ \x12\xf0\x29\xd8\x12\x5b\xf1\x89\x12\xe3\xe0\x4b\xef\x1e\x4d\x4e\ \x98\x4e\x62\x22\x67\x9b\xa3\xb3\xd2\x98\x91\x8e\x21\x1d\x47\x98\ \x8e\x4c\x1b\xc2\xd1\x14\xe1\x48\x5c\x96\x65\xcf\xd8\x39\x33\x4d\ \x26\xeb\x90\x73\x1c\xea\x43\x01\xee\x7a\xae\x85\x68\x2a\xc3\xe1\ \x51\x83\x13\xd3\x26\x8e\xdb\xcd\xa7\x63\x69\xbc\x01\x0f\x8a\x47\ \x47\x78\x34\x50\x24\x9a\x47\xc5\xb6\x6c\x8e\x1e\x1b\x64\x2c\x3c\ \xe1\xc4\xa6\xe2\x59\x4d\x53\x93\x2a\xc0\x8f\x36\xde\xd0\x57\xa0\ \x67\xce\x12\x96\x93\xd3\x35\x8f\xad\x8b\x6c\x4e\x08\xd5\x0c\xea\ \x5a\x3a\x18\xd0\x92\x5e\xaf\x16\x2b\x0a\x16\x0e\x4b\xd2\x71\x83\ \xe5\xe5\x9a\x37\x88\xab\xc0\xc3\xe1\x91\x59\x36\xac\x5d\xc8\x96\ \xa3\x11\x4e\xab\x2e\xe0\xd2\xa5\xd5\x14\x06\x74\x72\x8a\x4a\x56\ \x7e\x51\x35\xc7\x01\xcb\x16\x14\x79\x34\x1c\x33\xcf\xd4\x68\x0c\ \x3b\x95\xb2\x72\xc9\xcc\xc4\x48\x4f\xf3\xa3\xda\x1d\xdf\xbd\x8e\ \x6b\x6f\xb8\xf3\xf0\xe6\xcd\x3f\xbe\xcb\x91\xc1\x15\xf9\xac\xed\ \xc9\x18\x49\x19\x9d\x1c\x15\xaa\xc4\x2a\xf0\xea\xf9\xbc\x9d\x9b\ \x01\x91\x12\xb6\x11\x48\x84\xc7\x7e\xda\x9f\x2a\xa9\x2a\x2a\xf6\ \x71\x7a\x28\x40\xef\xb8\x41\x59\xb1\x07\xa1\x69\x7c\xa3\xa1\x94\ \x78\xd6\xe1\xbc\xac\xc3\xa9\x58\x9a\xf7\x8e\x8f\x93\xcf\xda\x54\ \x97\xf8\x10\xb3\xb3\x84\x13\x29\xb0\x1d\x7c\x2e\xb7\x2b\x93\x4c\ \xed\x82\x4f\x2c\xed\xd9\xdf\xbc\x41\x5f\xdf\x47\x62\xfe\xfc\x0b\ \x0f\x00\x07\xfe\xd4\x37\xfd\xc6\x35\x0b\x9a\xa6\x66\x72\x3f\x32\ \x53\x59\x99\x4d\x98\x22\x35\x92\x64\xe9\xd2\x10\x4d\xa1\x20\x42\ \x51\x40\x48\x6c\x45\x50\x51\xa8\xb3\x61\x75\x0d\x89\x64\x86\x13\ \x5d\xa3\xb4\x9e\x4a\xa3\x3a\xe0\x38\x8e\xc4\xc9\x8b\xb1\xd1\xe8\ \xcf\x01\xb4\xd7\x5f\xdf\xc4\xfc\xf9\x17\xca\x97\x5f\x7e\x80\xc1\ \xa1\x09\x91\x33\x2d\xf2\x66\x86\xf8\xf4\x08\xd2\xb2\x28\xf0\xea\ \xe4\x6d\x0b\x97\x92\x93\xc6\x4c\xa3\xd6\x54\x35\xf5\xb4\xd9\x97\ \x58\xd7\x66\x14\x86\x74\x45\x6a\x32\x97\x17\x9d\x43\x49\xdc\x85\ \x7e\x16\xa5\x73\x94\x78\xdd\x08\x55\xa5\x48\x57\x48\x9b\x79\x66\ \x67\x14\x8e\x9c\x8a\xe1\xb1\x2c\xf2\x8e\xb4\x15\x29\xd5\x89\xa1\ \xd8\xc3\xe9\xe8\x2f\xfb\xe6\x2e\xfd\x27\xf1\x95\x47\xb3\x7b\xbf\ \xfd\x67\xfc\xfc\xb5\xfd\x00\x1c\xde\xff\xf6\x4d\xcf\x6f\x9e\xfc\ \xfb\x8f\xa3\x05\x73\xa9\x08\x3a\xd2\xef\x51\x28\xf2\x71\xf5\xb9\ \xb5\x5c\xbf\xac\x0a\x97\x22\xc8\x58\x36\x3d\xe3\x06\xad\xdd\x13\ \xec\xf8\x38\x8c\x9a\xb3\x9d\xfc\x54\x54\x31\x7a\xc7\x5e\x71\x3a\ \x1e\xba\x29\x5b\x79\x1f\x89\xc9\x27\x1c\xf5\xab\x02\x0e\x76\x0c\ \xf2\xe0\xad\xeb\x90\x43\x23\xd4\x3d\xfa\xbb\x93\x37\xcf\x4f\xfd\ \xdb\xce\x9d\xfd\xae\xa0\xdf\x73\x7e\x7d\x43\xa5\x55\x5d\x1e\xb0\ \x6b\x4b\xbd\xca\xa2\x32\x1f\x39\xdb\x11\x03\xb1\x0c\x53\xf1\x94\ \x9c\x49\xe7\xad\xf0\xb8\x61\x8b\xc9\x98\x66\x86\x27\x9e\x1a\x39\ \xf9\xe0\xed\x29\x90\x99\xd4\x01\x59\x39\xff\x99\xaf\x37\x9c\x26\ \x22\x9d\x62\xfb\xb6\x21\x65\xfd\xad\x7f\x61\x9f\xd6\xf8\xe3\xb3\ \x5d\xe5\x55\x4f\xba\x6a\x2a\x16\xaf\x3a\xbb\xae\xf0\xbc\xa5\x21\ \xe2\x19\x8b\xf8\x4c\x86\x74\x32\x43\xb8\x77\x22\x3d\xde\x3d\x72\ \x58\xc4\x13\xf7\x9f\xf8\xf4\x81\x03\x25\xa1\x47\xd4\xd8\xf8\x23\ \xf6\x97\xb1\xfe\xdf\x00\x29\x25\x42\x5c\x03\x6c\xe5\x97\x2f\x49\ \xee\xba\xe9\x8b\x10\x85\x95\x77\xd7\xaa\xe5\xe5\xf5\x45\x35\x15\ \x42\x78\x74\xcc\xd9\x2c\xd9\xa9\x29\x29\x63\xc9\xa1\xd8\xc8\x13\ \x03\x00\x6b\xee\x3c\x46\xf3\xaf\x97\xb3\xf4\xd2\x13\x9c\xdc\xbd\ \x0c\x80\xff\x00\x1c\x7c\x06\xd9\x9b\xd6\x5b\xe7\x00\x00\x00\x00\ \x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x07\x84\ \x47\ \x49\x46\x38\x39\x61\x36\x00\x37\x00\xf3\x00\x00\xff\xff\xff\x00\ \x00\x00\x78\x78\x78\x1c\x1c\x1c\x0e\x0e\x0e\xd8\xd8\xd8\x54\x54\ \x54\xdc\xdc\xdc\xc4\xc4\xc4\x48\x48\x48\x8a\x8a\x8a\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\xff\x0b\x4e\ \x45\x54\x53\x43\x41\x50\x45\x32\x2e\x30\x03\x01\x00\x00\x00\x21\ \xfe\x1a\x43\x72\x65\x61\x74\x65\x64\x20\x77\x69\x74\x68\x20\x61\ \x6a\x61\x78\x6c\x6f\x61\x64\x2e\x69\x6e\x66\x6f\x00\x21\xf9\x04\ \x09\x0a\x00\x00\x00\x2c\x00\x00\x00\x00\x36\x00\x37\x00\x00\x04\ \xcc\x10\xc8\x49\xab\xbd\x38\xeb\xcd\xbb\xff\x60\x28\x8e\x64\x69\ \x9e\x25\x92\x10\x44\x82\xa0\xa7\xc2\xce\x84\x02\x93\x08\x4d\xbf\ \x77\xb8\xea\xac\x44\x2f\x04\xa4\x0d\x41\xc5\xd9\xf1\xf3\x03\x0a\ \x97\x9d\x5c\x91\x77\x2c\x18\x58\x86\x02\x46\xa6\xb3\x2d\x0b\x03\ \xda\x40\x7b\x51\x05\xa9\x16\xc1\x60\x20\x18\x5d\x75\x06\x93\x80\ \xd6\x26\x16\x4d\xe1\xd9\x40\x94\xc4\x8b\x45\x6f\x34\x71\x25\x73\ \x33\x75\x20\x07\x79\x2c\x03\x07\x27\x6a\x6c\x24\x07\x6f\x06\x8d\ \x50\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x1c\x8f\x87\x96\xa1\x1a\ \x85\x2c\xa2\x47\xa6\x04\xa8\x14\x8a\x04\x7b\x96\xae\xb0\x17\xb2\ \x97\xb5\x18\xaa\xac\x3d\xb9\xa5\x6b\xba\x43\xa4\x9f\xc2\xc3\xc4\ \xc5\xc6\xc7\xc8\x9b\xc1\x8e\xbe\x24\xbc\x72\x74\x23\xb7\x25\xd3\ \x20\xd5\xd2\x7f\x22\xcf\x84\xd1\x23\xcb\x72\xcd\xc9\x9e\xdf\xc5\ \xdb\xc5\xd7\xc3\xe8\xc2\xe6\xe5\xe1\xe2\xef\x3d\x11\x00\x21\xf9\ \x04\x09\x0a\x00\x00\x00\x2c\x00\x00\x00\x00\x36\x00\x37\x00\x00\ \x04\xce\x10\xc8\x49\xab\xbd\x38\xeb\xcd\xbb\xff\x60\x28\x8e\x64\ \x69\x9e\x68\xaa\x16\x06\x41\x18\x85\x5a\x16\x83\xeb\x0e\xb1\x2c\ \xb6\xb6\x6b\xe8\xa2\x5e\x0f\x18\x12\xda\x88\x20\x5e\xef\x87\xf4\ \x1c\x6a\xb6\xc1\xe1\x82\x48\xb8\x12\x88\xa6\xe4\xc0\x33\x4c\x2d\ \x0a\xa3\x62\x24\x18\x0c\x04\x26\x84\xd1\x95\x05\x09\x7a\x68\x92\ \x75\x9d\x08\x41\x6f\xa5\xf5\x11\x74\x27\x0c\xf2\x7a\x04\x21\x6f\ \x36\x71\x23\x73\x46\x75\x83\x66\x86\x23\x6a\x6b\x6d\x5a\x1a\x61\ \x42\x63\x92\x1c\x55\x57\x91\x97\x9c\x9d\x9e\x9f\xa0\xa1\x6e\x8c\ \x97\x65\x67\x1a\x84\x2e\x8d\x40\xa9\x04\xab\x14\x7d\x7f\x4d\xb1\ \x19\xb4\xb3\x3d\xb2\x17\xad\xaf\x32\xbb\xa8\xa4\x92\xa6\xbc\xa2\ \xc4\xc5\xc6\xc7\xc8\xc9\xca\x27\xc2\x29\xcd\x64\x70\xcc\xd1\x22\ \xb6\x25\xd5\x7c\xb8\x27\xd7\x1f\xbe\x26\xdd\x22\xcf\xcc\xc0\xcb\ \x9e\xe1\xc7\xdf\xc6\xdb\xc4\xea\xa2\xe8\xc6\xe6\xe4\xf1\x27\x11\ \x00\x21\xf9\x04\x09\x0a\x00\x00\x00\x2c\x00\x00\x00\x00\x36\x00\ \x37\x00\x00\x04\xce\x10\xc8\x49\xab\xbd\x38\xeb\xcd\xbb\xff\x60\ \x28\x8e\x64\x69\x9e\x68\xaa\xae\xac\x30\x0c\x02\x5b\x0a\x44\x4d\ \xc4\xb2\x38\xd8\xc4\x90\xeb\x3c\xdf\x0f\x44\xb3\xe1\x86\x1f\x17\ \x0c\x99\x2b\x18\x6a\x86\x02\x49\x79\x24\x15\x76\xb6\x81\x34\x54\ \xac\x55\x45\x4f\x1e\xc1\x00\xcc\x9a\xc4\xb6\x72\x4d\x48\x42\xd7\ \x44\xdd\x9b\x29\xcc\x23\xc3\x5f\x5f\xd1\x01\xbb\x3e\x30\x3b\x07\ \x61\x06\x7e\x7f\x85\x86\x87\x88\x89\x8a\x12\x08\x09\x35\x09\x08\ \x8b\x15\x0a\x68\x0a\x19\x54\x43\x08\x6e\x04\x91\x16\x71\x79\x29\ \x8e\x6e\x09\x17\x7c\x3d\x3f\x9b\x6f\x16\xa6\x6c\x2c\xa9\x04\x17\ \x9f\x3f\xa2\x68\xa4\xb1\x78\x99\x9b\x9d\x92\x94\x62\x96\x92\x13\ \x8d\x8f\xbb\xc0\xc5\xc6\xc7\xc8\xc9\x13\x98\x28\xcc\x70\x3c\xa0\ \x44\xd0\x23\xac\x27\xd5\x6a\xa7\x26\xd7\x5c\xd3\x26\xb2\x23\xce\ \xde\xb8\xca\x88\xe1\xc5\xdf\xc6\xdb\xc5\xea\xc0\xe8\xc6\xe6\xe4\ \xf1\x26\x11\x00\x21\xf9\x04\x09\x0a\x00\x00\x00\x2c\x00\x00\x00\ \x00\x36\x00\x37\x00\x00\x04\xcd\x10\xc8\x49\xab\xbd\x38\xeb\xcd\ \xbb\xff\x60\x28\x8e\x64\x69\x9e\x68\xaa\xae\xac\x30\x0c\x02\x5b\ \x0a\x44\x4d\xc4\xb2\x38\xd8\xc4\x90\xeb\x3c\xdf\x0f\x44\xb3\xe1\ \x86\x1f\x17\x0c\xc9\x34\x29\x8f\xce\x17\x94\xc8\x9b\x8a\x8a\x35\ \x6b\x67\x67\x13\x96\xb8\x35\x2f\x08\xdc\x3b\x91\xc5\xc9\xea\x09\ \x7b\x23\x3d\x53\xef\xa6\x7c\x4e\xaf\xdb\xef\xf8\xbc\xaa\x60\xa8\ \x19\x0a\x1a\x71\x3f\x05\x67\x80\x17\x6c\x5a\x29\x7d\x3c\x04\x06\ \x18\x67\x43\x8c\x36\x8f\x41\x91\x92\x04\x18\x88\x43\x8b\x3c\x8e\ \x99\x52\x48\x07\x67\x07\x7a\x13\x07\x8b\x06\xa4\xa5\xab\xac\xad\ \xae\x27\x08\x09\x35\x09\x08\xac\x0a\x92\x0a\x23\x82\x23\x08\x97\ \x04\xb5\x54\x46\x25\xb2\x97\x09\x21\x90\x24\xbe\x35\xc7\x95\xc9\ \xca\x21\x9a\x24\xc4\x92\xc6\xd0\xa0\x25\xbd\x97\xc0\x79\xb7\x8c\ \xb9\x48\xbb\x15\xb1\xb3\xdb\x3f\xd1\xab\xc8\xe8\xcd\xab\xe7\xec\ \xd7\xaf\xf0\x2b\x11\x00\x21\xf9\x04\x09\x0a\x00\x00\x00\x2c\x00\ \x00\x00\x00\x36\x00\x37\x00\x00\x04\xcb\x10\xc8\x49\xab\xbd\x38\ \xeb\xcd\xbb\xff\x60\x28\x8e\x64\x69\x9e\x68\xaa\xae\xac\x30\x0c\ \x02\x5b\x0a\x44\x4d\xc4\xb2\x38\xd8\xc4\x90\xeb\x3c\xdf\x0f\x44\ \xb3\xe1\x86\x1f\x17\x0c\xc9\x34\x29\x8f\xce\x17\x94\xc8\x9b\x8a\ \x8a\x35\x6b\x67\x67\x13\x96\xb8\x35\x2f\x08\xdc\x3b\x91\xc5\xc9\ \xea\x09\x7b\x23\x3d\x53\xef\xa6\x7c\x4e\xaf\xdb\xef\xf8\x3c\x3e\ \x8e\xe4\x5f\xd8\x5a\x2a\x80\x19\x67\x48\x85\x18\x87\x3f\x89\x16\ \x83\x43\x8d\x18\x7e\x3f\x91\x7a\x94\x95\x96\x97\x98\x99\x4c\x05\ \x06\x35\x06\x05\x6e\x52\x27\x05\x67\xa0\x21\x8f\x23\x9d\x3c\x04\ \x06\x40\x5d\x26\xab\x36\xae\x61\xb0\xb1\x04\x57\x6a\x25\xaa\x3c\ \xad\x57\xa2\x19\x08\x09\x35\x09\x08\x17\x07\x67\x07\x43\x0a\xb1\ \x0a\xc6\xaa\x06\xc9\x3f\x08\xb6\x04\xc5\x79\xc2\xb6\x09\x7a\xd4\ \x35\xdb\xdc\x7a\xd8\xb1\xda\x79\xd3\xb6\xd6\x79\xcb\xab\xcd\x95\ \xc1\xc3\xe7\x22\x11\x00\x21\xf9\x04\x09\x0a\x00\x00\x00\x2c\x00\ \x00\x00\x00\x36\x00\x37\x00\x00\x04\xcc\x10\xc8\x49\xab\xbd\x38\ \xeb\xcd\xbb\xff\x60\x28\x8e\x64\x69\x9e\x68\xaa\xae\xac\x30\x0c\ \x02\x5b\x0a\x44\x4d\xc4\xb2\x38\xd8\xc4\x90\xeb\x3c\xdf\x0f\x44\ \xb3\xe1\x86\x1f\x17\x0c\xc9\x34\x29\x8f\xce\x17\x94\xc8\x9b\x8a\ \x8a\x35\x6b\x67\x67\x13\x96\xb8\x35\x2f\x08\xdc\x3b\x91\xc5\xc9\ \xea\x09\x7b\x23\x3d\x53\xef\xa6\x7c\x4e\xaf\xdb\xef\xf8\x3c\x3e\ \x8e\xe4\x5f\xd8\x5a\x2a\x80\x19\x67\x48\x85\x18\x87\x3f\x89\x16\ \x83\x43\x8d\x18\x7e\x3f\x91\x7a\x94\x95\x96\x97\x98\x00\x08\x09\ \x35\x09\x08\x96\x0a\x3c\x35\x0a\x94\x08\xa2\x36\x9f\x33\x52\x22\ \x9c\xa7\x04\x09\x33\x6a\x20\xae\x36\x5f\x41\x21\xb4\x35\xb6\x5d\ \x21\xad\xa7\xb0\x6e\xb2\x1f\xa6\xae\xa9\x6e\xab\x22\xa1\xa2\xa4\ \x17\x05\x06\x35\x06\x05\x48\x9b\x9d\xc6\x15\x05\x67\xd2\x94\xcf\ \xa2\x06\x95\xb4\xdf\xae\x95\xdc\x3c\xde\x94\x07\x67\x07\x96\x07\ \xdc\x06\xea\x99\x28\x11\x00\x21\xf9\x04\x09\x0a\x00\x00\x00\x2c\ \x00\x00\x00\x00\x36\x00\x37\x00\x00\x04\xcc\x10\xc8\x49\xab\xbd\ \x38\xeb\xcd\xbb\xff\x60\x28\x8e\x64\x69\x9e\x68\xaa\xae\xac\x30\ \x0c\x02\x5b\x0a\x44\x4d\xc4\xb2\x38\xd8\xc4\x90\xeb\x3c\xdf\x0f\ \x44\xb3\xe1\x86\x1f\x17\x0c\xc9\x34\x29\x8f\xce\x17\x94\xc8\x9b\ \x8a\x8a\x35\x6b\x67\x67\x13\x96\xb8\x35\x2f\x08\xdc\x3b\x91\xc5\ \xc9\xea\x09\x7b\x23\x3d\x53\xef\xa6\x7c\x4e\xaf\xdb\xef\x22\x44\ \xa2\x96\x40\xe0\x2b\x0a\x3c\x35\x0a\x7f\x12\x08\x82\x36\x7e\x3f\ \x71\x16\x7b\x88\x04\x09\x8b\x6a\x16\x8f\x36\x3f\x67\x17\x95\x35\ \x97\x41\x17\x8e\x88\x91\x39\x6c\x5a\x87\x8f\x8a\xa2\x52\x19\x81\ \x82\x84\x85\x86\x8e\x7d\xae\xb2\xb3\xb4\xb5\x4c\x05\x06\x35\x06\ \x05\xb3\x05\x67\xbc\x51\x4b\x22\xb9\x82\x06\x4e\x93\x20\x95\x26\ \x98\x21\xca\x5f\x9d\x21\xc4\x3c\xc6\x33\xc8\x1f\x07\x67\x07\x6b\ \xa9\x23\x07\xc4\x06\xda\xb6\x1d\x8c\xb2\xa3\xb4\xcc\xb2\xe8\xae\ \xe6\xb4\xe4\xe2\xef\x27\x11\x00\x21\xf9\x04\x09\x0a\x00\x00\x00\ \x2c\x00\x00\x00\x00\x36\x00\x37\x00\x00\x04\xcc\x10\xc8\x49\xab\ \xbd\x38\xeb\xcd\xbb\xff\x60\x28\x8e\x64\x69\x9e\x68\xaa\xae\xac\ \x30\x0c\x02\x5b\x0a\x44\x4d\xc4\xb2\x38\xd8\xc4\x90\xeb\x3c\xdf\ \x0f\x44\xb3\xe1\x7e\x88\x44\x2d\x81\xd0\xb8\x60\x43\x80\x82\x57\ \x53\x44\x39\x08\xaa\xad\x39\x7b\x1d\x3f\x4a\x2d\x21\x31\xe3\x7d\ \x3b\x62\x5b\x69\x67\x13\x7e\xd2\xb5\x75\x30\x14\xd6\x92\x49\xc5\ \xda\x19\x9b\xe6\xe2\xbd\x23\x53\x54\x56\x57\x58\x61\x4c\x85\x89\ \x8a\x8b\x8c\x8d\x57\x05\x06\x35\x06\x05\x8e\x16\x05\x6c\x35\x03\ \x94\x43\x4f\x7b\x13\x91\x54\x06\x9c\x66\x18\x69\x43\x98\x3d\xa5\ \x62\xa7\x73\x17\xa0\x3c\xa2\x3f\x79\x37\x18\x07\xa8\x03\x07\x51\ \x9d\x1a\x07\xa0\x06\xb9\x95\xc1\xc2\xc3\xc4\xc5\xc6\xc7\x1d\xbb\ \x28\xca\x22\xb3\x9e\x44\xa4\x40\x6d\x27\xb7\x23\xd5\x26\xd7\x21\ \xce\x27\xdb\x23\xcc\x26\xdf\xc8\x89\xe1\xc2\xdd\xc4\xd9\xc3\xe8\ \xe5\xd1\xc5\xe4\xe2\xef\x25\x11\x00\x3b\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\ \x00\x00\x03\x16\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ \x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ \x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\ \x01\x42\x28\x9b\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ \x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ \x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x02\x93\x49\x44\ \x41\x54\x38\x8d\x95\x91\xbd\x4f\x1b\x41\x10\xc5\x67\xe1\x96\xbb\ \xf3\x25\xd8\x46\xe1\x82\x20\x91\x2c\x45\x38\x42\x51\x94\x02\x19\ \x21\x04\x1d\xa2\xa3\x80\xa3\x30\x05\x25\x12\x15\x32\x14\x44\x48\ \xfc\x05\x54\x96\x28\x29\x4c\x45\x0f\xae\xa0\xc0\x20\x0a\x7a\xa0\ \x20\x46\x48\x24\x0e\x8e\xb1\x8d\xe3\x23\xb7\xc7\xde\xde\xee\x5e\ \x8a\xc4\x16\x1f\x49\xc1\x2b\x67\xde\xfc\xf4\x66\x06\x65\xb3\xd9\ \x81\x20\x08\x52\x08\xa1\x38\x3c\x43\x41\x10\xe4\x11\x42\x69\xc5\ \xf7\xfd\x85\x91\x91\x91\x01\xc3\x30\xd4\xe7\x00\x08\x21\xd1\xc3\ \xc3\xc3\x05\x45\x4a\x19\x07\x80\x6a\xbd\x5e\x77\x9f\x03\xc0\x18\ \x87\xa4\x94\x71\x85\x52\x0a\x94\xd2\x27\xc3\xb9\x5c\x2e\xba\xb7\ \xb7\xf7\x2a\x16\x8b\xb9\xc9\x64\xb2\x64\x18\x86\xb8\xdf\x17\x42\ \xb8\x94\xd2\x76\x85\x73\x8e\x82\x20\x68\x36\x6a\xb5\x9a\x92\x4a\ \xa5\x3e\x5e\x5c\x5c\x84\x55\x55\x85\x83\x83\x03\xd8\xd8\xd8\x78\ \x37\x3f\x3f\xff\x65\x6a\x6a\xea\xfa\x3e\x84\x73\x8e\x14\xc6\x18\ \xe2\x9c\x37\x8b\x2b\x2b\x2b\x1f\x6e\x6f\x6f\xdb\x97\x96\x96\x2a\ \x63\x63\x63\x2e\x00\xc0\xc9\xc9\x49\x5b\x22\x91\x70\xe6\xe6\xe6\ \x3e\x25\x93\xc9\x6f\xc3\xc3\xc3\x3f\x01\x00\x18\x63\xa8\x85\x73\ \x8e\xa4\x94\x20\xa5\x84\xb3\xb3\x33\xa3\x5c\x2e\x47\xa7\xa7\xa7\ \x6b\x96\x65\x5d\xa9\xaa\x5a\x50\x55\xf5\x6a\x68\x68\xe8\x47\x26\ \x93\xe9\xa8\x56\xab\xd1\xf5\xf5\xf5\xf7\x9e\xe7\x21\x29\x25\x70\ \xce\x51\x0b\x63\x0c\x49\x29\x61\x7b\x7b\xbb\x6b\x6b\x6b\xeb\xad\ \x69\x9a\x80\x31\xf6\x8e\x8e\x8e\x24\x63\x8c\x33\xc6\xd8\xf1\xf1\ \x31\xdf\xdd\xdd\x8d\x99\xa6\x09\x9a\xa6\x69\xe9\x74\x3a\x2e\xa5\ \x6c\x26\x00\x29\x25\x10\x42\xc2\xf9\x7c\xbe\x4b\xd7\x75\xd8\xd9\ \xd9\x31\x4d\xd3\x0c\x1a\xc9\x84\x10\x6d\xcb\xcb\xcb\x15\x5d\xd7\ \x61\x76\x76\xf6\x7a\x7c\x7c\xdc\xfd\x9b\x00\x94\xc6\x0a\x33\x33\ \x33\x25\x00\x78\x71\x7e\x7e\xfe\x72\x71\x71\xb1\x18\x8d\x46\x5d\ \x29\x25\x00\x00\xf4\xf6\xf6\x3a\x99\x4c\x46\xd5\x75\x1d\xfa\xfa\ \xfa\xca\xba\xae\x13\xc6\xd8\x9f\x23\x36\x00\xae\xeb\xda\x96\x65\ \x95\x4e\x4f\x4f\xef\x22\x91\x48\x79\x6d\x6d\x2d\xde\xdf\xdf\x5f\ \xc1\x18\xcb\x5c\x2e\xf7\xc6\x71\x9c\xc8\xc4\xc4\x44\x05\x63\x5c\ \xa7\x94\x8a\xe6\x17\xee\x1f\x11\x63\x5c\x1e\x1c\x1c\xbc\xcb\x66\ \xb3\x86\x6d\xdb\x1d\x9b\x9b\x9b\xaf\x01\x00\x4c\xd3\x04\xcb\xb2\ \x2a\x89\x44\xa2\xe4\x38\x8e\x78\xf0\x46\xdf\xf7\x51\x23\xaa\xe7\ \x79\xbe\xe7\x79\xb5\xd1\xd1\x51\x6d\x72\x72\xf2\xeb\xcd\xcd\x0d\ \xb6\x6d\x5b\xe9\xe9\xe9\xf1\x11\x42\xbf\x6c\xdb\xae\x35\xbc\x00\ \x00\xbe\xef\x3f\x04\x34\x44\x08\xa1\x84\x90\xef\x9a\xa6\x69\x9d\ \x9d\x9d\xd8\xb6\xed\x3b\x21\x04\x87\x47\xf2\x7d\x1f\x29\x00\x70\ \x59\x28\x14\xc2\xdd\xdd\xdd\xec\xb1\x81\x10\x42\x01\x80\x3e\xae\ \x03\x00\x14\x8b\xc5\x36\x00\xb8\x54\x42\xa1\xd0\xea\xfe\xfe\xfe\ \x67\x21\x44\xec\x5f\xc6\xff\xa9\xb5\xb5\xf5\x32\x1c\x0e\xaf\xfe\ \x06\x47\x78\x84\x8a\xac\x27\x36\x0e\x00\x00\x00\x00\x49\x45\x4e\ \x44\xae\x42\x60\x82\ " qt_resource_name = b"\ \x00\x05\ \x00\x6f\xa6\x53\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x73\ \x00\x08\ \x03\xc6\x59\xa7\ \x00\x70\ \x00\x6c\x00\x75\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0b\ \x00\xbd\xc0\x27\ \x00\x73\ \x00\x65\x00\x74\x00\x74\x00\x69\x00\x6e\x00\x67\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0d\ \x0c\x56\x4d\x87\ \x00\x65\ \x00\x72\x00\x69\x00\x63\x00\x57\x00\x65\x00\x62\x00\x31\x00\x36\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x14\ \x0b\x6a\x55\xa7\ \x00\x62\ \x00\x6f\x00\x78\x00\x2d\x00\x62\x00\x6f\x00\x72\x00\x64\x00\x65\x00\x72\x00\x2d\x00\x73\x00\x6d\x00\x61\x00\x6c\x00\x6c\x00\x2e\ \x00\x70\x00\x6e\x00\x67\ \x00\x08\ \x0b\x07\x5a\x27\ \x00\x65\ \x00\x64\x00\x69\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x09\ \x06\x98\x83\x27\ \x00\x63\ \x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x11\ \x0c\x97\x94\x07\ \x00\x61\ \x00\x64\x00\x42\x00\x6c\x00\x6f\x00\x63\x00\x6b\x00\x50\x00\x6c\x00\x75\x00\x73\x00\x31\x00\x36\x00\x2e\x00\x70\x00\x6e\x00\x67\ \ \x00\x11\ \x0c\x49\x94\x07\ \x00\x61\ \x00\x64\x00\x42\x00\x6c\x00\x6f\x00\x63\x00\x6b\x00\x50\x00\x6c\x00\x75\x00\x73\x00\x36\x00\x34\x00\x2e\x00\x70\x00\x6e\x00\x67\ \ \x00\x0e\ \x05\x17\xcb\xe7\ \x00\x62\ \x00\x72\x00\x6f\x00\x6b\x00\x65\x00\x6e\x00\x50\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0d\ \x0c\x7a\x4d\x87\ \x00\x65\ \x00\x72\x00\x69\x00\x63\x00\x57\x00\x65\x00\x62\x00\x33\x00\x32\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0b\ \x00\xb0\xe2\x96\ \x00\x6c\ \x00\x6f\x00\x61\x00\x64\x00\x69\x00\x6e\x00\x67\x00\x2e\x00\x67\x00\x69\x00\x66\ \x00\x0a\ \x05\x78\x4f\x27\ \x00\x72\ \x00\x65\x00\x6c\x00\x6f\x00\x61\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ " qt_resource_struct = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x0c\x00\x00\x00\x02\ \x00\x00\x01\x50\x00\x00\x00\x00\x00\x01\x00\x00\x6c\xde\ \x00\x00\x00\x26\x00\x00\x00\x00\x00\x01\x00\x00\x03\xb5\ \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x01\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x3f\xbc\ \x00\x00\x01\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x74\x66\ \x00\x00\x00\xa6\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x10\ \x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x17\x99\ \x00\x00\x00\x62\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x68\ \x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x1f\x92\ \x00\x00\x00\x42\x00\x00\x00\x00\x00\x01\x00\x00\x08\x38\ \x00\x00\x01\x30\x00\x00\x00\x00\x00\x01\x00\x00\x60\x71\ \x00\x00\x00\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x5e\ " def qInitResources(): QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) def qCleanupResources(): QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) qInitResources() eric-6.0.8/eric/Helpviewer/data/__init__.py0000644000175000017500000000024012451233375017602 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Package defining some data used by the web browser. """ eric-6.0.8/eric/Helpviewer/data/html.qrc0000644000175000017500000000033012060166053017136 0ustar piotrpiotr html/startPage.html html/adblockPage.html html/notFoundPage.html html/speeddialPage.html eric-6.0.8/eric/Helpviewer/data/html_rc.py0000644000175000017500000012300412553751337017505 0ustar piotrpiotr# -*- coding: utf-8 -*- # Resource object code # # Created by: The Resource Compiler for PyQt5 (Qt v5.5.0) # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore qt_resource_data = b"\ \x00\x00\x0c\xfe\ \x3c\ \x21\x44\x4f\x43\x54\x59\x50\x45\x20\x68\x74\x6d\x6c\x3e\x0a\x3c\ \x68\x74\x6d\x6c\x3e\x0a\x3c\x68\x65\x61\x64\x3e\x0a\x3c\x6d\x65\ \x74\x61\x20\x63\x68\x61\x72\x73\x65\x74\x3d\x22\x75\x74\x66\x2d\ \x38\x22\x3e\x20\x0a\x3c\x6d\x65\x74\x61\x20\x68\x74\x74\x70\x2d\ \x65\x71\x75\x69\x76\x3d\x22\x63\x6f\x6e\x74\x65\x6e\x74\x2d\x74\ \x79\x70\x65\x22\x20\x63\x6f\x6e\x74\x65\x6e\x74\x3d\x22\x74\x65\ \x78\x74\x2f\x68\x74\x6d\x6c\x3b\x20\x63\x68\x61\x72\x73\x65\x74\ \x3d\x75\x74\x66\x2d\x38\x22\x3e\x0a\x3c\x74\x69\x74\x6c\x65\x3e\ \x3c\x2f\x74\x69\x74\x6c\x65\x3e\x0a\x3c\x6c\x69\x6e\x6b\x20\x72\ \x65\x6c\x3d\x22\x69\x63\x6f\x6e\x22\x20\x68\x72\x65\x66\x3d\x22\ \x40\x46\x41\x56\x49\x43\x4f\x4e\x40\x22\x20\x74\x79\x70\x65\x3d\ \x22\x69\x6d\x61\x67\x65\x2f\x78\x2d\x69\x63\x6f\x6e\x22\x20\x2f\ \x3e\x0a\x3c\x73\x74\x79\x6c\x65\x3e\x0a\x2a\x20\x7b\x0a\x20\x20\ \x20\x20\x6d\x61\x72\x67\x69\x6e\x3a\x20\x30\x3b\x0a\x20\x20\x20\ \x20\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x30\x3b\x0a\x20\x20\x20\ \x20\x66\x6f\x6e\x74\x2d\x66\x61\x6d\x69\x6c\x79\x3a\x20\x22\x44\ \x65\x6a\x61\x56\x75\x20\x53\x61\x6e\x73\x22\x3b\x0a\x7d\x0a\x0a\ \x62\x6f\x64\x79\x20\x7b\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\ \x72\x6f\x75\x6e\x64\x3a\x20\x2d\x77\x65\x62\x6b\x69\x74\x2d\x67\ \x72\x61\x64\x69\x65\x6e\x74\x28\x6c\x69\x6e\x65\x61\x72\x2c\x20\ \x6c\x65\x66\x74\x20\x74\x6f\x70\x2c\x20\x6c\x65\x66\x74\x20\x62\ \x6f\x74\x74\x6f\x6d\x2c\x20\x66\x72\x6f\x6d\x28\x23\x38\x35\x37\ \x38\x34\x41\x29\x2c\x20\x74\x6f\x28\x23\x46\x44\x46\x44\x46\x44\ \x29\x2c\x20\x63\x6f\x6c\x6f\x72\x2d\x73\x74\x6f\x70\x28\x30\x2e\ \x35\x2c\x20\x23\x46\x44\x46\x44\x46\x44\x29\x29\x3b\x0a\x20\x20\ \x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x2d\x72\x65\x70\ \x65\x61\x74\x3a\x20\x72\x65\x70\x65\x61\x74\x2d\x78\x3b\x0a\x20\ \x20\x20\x20\x6d\x61\x72\x67\x69\x6e\x2d\x74\x6f\x70\x3a\x20\x32\ \x30\x30\x70\x78\x3b\x0a\x7d\x0a\x0a\x23\x68\x65\x61\x64\x65\x72\ \x2c\x20\x23\x73\x65\x61\x72\x63\x68\x2c\x20\x23\x66\x6f\x6f\x74\ \x65\x72\x20\x7b\x0a\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3a\x20\ \x36\x30\x30\x70\x78\x3b\x0a\x20\x20\x20\x20\x6d\x61\x72\x67\x69\ \x6e\x3a\x20\x31\x30\x70\x78\x20\x61\x75\x74\x6f\x3b\x0a\x7d\x0a\ \x0a\x23\x68\x65\x61\x64\x65\x72\x2c\x20\x23\x73\x65\x61\x72\x63\ \x68\x20\x7b\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x72\ \x61\x64\x69\x75\x73\x3a\x20\x30\x2e\x38\x65\x6d\x3b\x0a\x20\x20\ \x20\x20\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x32\x35\x70\x78\x3b\ \x0a\x7d\x0a\x0a\x23\x68\x65\x61\x64\x65\x72\x20\x7b\x0a\x20\x20\ \x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x2d\x77\ \x65\x62\x6b\x69\x74\x2d\x67\x72\x61\x64\x69\x65\x6e\x74\x28\x6c\ \x69\x6e\x65\x61\x72\x2c\x20\x6c\x65\x66\x74\x20\x74\x6f\x70\x2c\ \x20\x6c\x65\x66\x74\x20\x62\x6f\x74\x74\x6f\x6d\x2c\x20\x66\x72\ \x6f\x6d\x28\x23\x44\x35\x37\x45\x33\x45\x29\x2c\x20\x74\x6f\x28\ \x23\x44\x35\x37\x45\x33\x45\x29\x2c\x20\x63\x6f\x6c\x6f\x72\x2d\ \x73\x74\x6f\x70\x28\x30\x2e\x35\x2c\x20\x23\x46\x46\x42\x41\x38\ \x39\x29\x29\x3b\x0a\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\x3a\ \x20\x32\x35\x70\x78\x3b\x0a\x7d\x0a\x0a\x23\x68\x65\x61\x64\x65\ \x72\x20\x68\x31\x20\x7b\x0a\x20\x20\x20\x20\x64\x69\x73\x70\x6c\ \x61\x79\x3a\x20\x69\x6e\x6c\x69\x6e\x65\x3b\x0a\x20\x20\x20\x20\ \x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x20\x31\x2e\x37\x65\x6d\ \x3b\x0a\x20\x20\x20\x20\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\ \x74\x3a\x20\x62\x6f\x6c\x64\x3b\x0a\x7d\x0a\x0a\x23\x68\x65\x61\ \x64\x65\x72\x20\x69\x6d\x67\x20\x7b\x0a\x20\x20\x20\x20\x64\x69\ \x73\x70\x6c\x61\x79\x3a\x20\x69\x6e\x6c\x69\x6e\x65\x3b\x0a\x20\ \x20\x20\x20\x66\x6c\x6f\x61\x74\x3a\x20\x72\x69\x67\x68\x74\x3b\ \x0a\x20\x20\x20\x20\x6d\x61\x72\x67\x69\x6e\x2d\x74\x6f\x70\x3a\ \x20\x2d\x35\x70\x78\x3b\x0a\x7d\x0a\x0a\x23\x73\x65\x61\x72\x63\ \x68\x20\x7b\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\ \x6e\x64\x3a\x20\x2d\x77\x65\x62\x6b\x69\x74\x2d\x67\x72\x61\x64\ \x69\x65\x6e\x74\x28\x6c\x69\x6e\x65\x61\x72\x2c\x20\x6c\x65\x66\ \x74\x20\x74\x6f\x70\x2c\x20\x72\x69\x67\x68\x74\x20\x74\x6f\x70\ \x2c\x20\x66\x72\x6f\x6d\x28\x23\x38\x35\x37\x38\x34\x41\x29\x2c\ \x20\x74\x6f\x28\x23\x38\x35\x37\x38\x34\x41\x29\x2c\x20\x63\x6f\ \x6c\x6f\x72\x2d\x73\x74\x6f\x70\x28\x30\x2e\x35\x2c\x20\x23\x43\ \x38\x43\x32\x41\x45\x29\x29\x3b\x0a\x20\x20\x20\x20\x68\x65\x69\ \x67\x68\x74\x3a\x20\x35\x30\x70\x78\x3b\x0a\x20\x20\x20\x20\x63\ \x6f\x6c\x6f\x72\x3a\x20\x23\x30\x30\x30\x3b\x0a\x20\x20\x20\x20\ \x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x20\x63\x65\x6e\x74\ \x65\x72\x3b\x0a\x20\x20\x20\x20\x70\x61\x64\x64\x69\x6e\x67\x2d\ \x74\x6f\x70\x3a\x20\x34\x30\x70\x78\x20\x21\x69\x6d\x70\x6f\x72\ \x74\x61\x6e\x74\x3b\x0a\x7d\x0a\x0a\x23\x73\x65\x61\x72\x63\x68\ \x20\x66\x69\x65\x6c\x64\x73\x65\x74\x20\x7b\x0a\x20\x20\x20\x20\ \x62\x6f\x72\x64\x65\x72\x3a\x20\x30\x3b\x0a\x7d\x0a\x0a\x23\x73\ \x65\x61\x72\x63\x68\x20\x69\x6e\x70\x75\x74\x5b\x74\x79\x70\x65\ \x3d\x74\x65\x78\x74\x5d\x20\x7b\x0a\x20\x20\x20\x20\x77\x69\x64\ \x74\x68\x3a\x20\x36\x35\x25\x3b\x0a\x7d\x0a\x0a\x23\x73\x65\x61\ \x72\x63\x68\x20\x69\x6e\x70\x75\x74\x5b\x74\x79\x70\x65\x3d\x73\ \x75\x62\x6d\x69\x74\x5d\x20\x7b\x0a\x20\x20\x20\x20\x77\x69\x64\ \x74\x68\x3a\x20\x32\x35\x25\x3b\x0a\x7d\x0a\x0a\x23\x66\x6f\x6f\ \x74\x65\x72\x20\x7b\x0a\x20\x20\x20\x20\x74\x65\x78\x74\x2d\x61\ \x6c\x69\x67\x6e\x3a\x20\x63\x65\x6e\x74\x65\x72\x3b\x0a\x20\x20\ \x20\x20\x63\x6f\x6c\x6f\x72\x3a\x20\x23\x39\x39\x39\x3b\x0a\x7d\ \x0a\x0a\x23\x66\x6f\x6f\x74\x65\x72\x20\x61\x20\x7b\x0a\x20\x20\ \x20\x20\x63\x6f\x6c\x6f\x72\x3a\x20\x23\x35\x35\x35\x3b\x0a\x20\ \x20\x20\x20\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\ \x6f\x6e\x3a\x20\x6e\x6f\x6e\x65\x3b\x0a\x7d\x0a\x0a\x23\x66\x6f\ \x6f\x74\x65\x72\x20\x61\x3a\x68\x6f\x76\x65\x72\x20\x7b\x0a\x20\ \x20\x20\x20\x74\x65\x78\x74\x2d\x64\x65\x63\x6f\x72\x61\x74\x69\ \x6f\x6e\x3a\x20\x75\x6e\x64\x65\x72\x6c\x69\x6e\x65\x3b\x0a\x7d\ \x0a\x20\x20\x20\x20\x3c\x2f\x73\x74\x79\x6c\x65\x3e\x0a\x20\x20\ \x20\x20\x3c\x73\x63\x72\x69\x70\x74\x20\x74\x79\x70\x65\x3d\x22\ \x74\x65\x78\x74\x2f\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x22\ \x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x66\x75\x6e\x63\x74\x69\ \x6f\x6e\x20\x75\x70\x64\x61\x74\x65\x28\x29\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x7b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x74\x69\x74\x6c\x65\ \x20\x3d\x20\x77\x69\x6e\x64\x6f\x77\x2e\x65\x72\x69\x63\x2e\x74\ \x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x27\x57\x65\x6c\x63\x6f\x6d\ \x65\x20\x74\x6f\x20\x65\x72\x69\x63\x36\x20\x57\x65\x62\x20\x42\ \x72\x6f\x77\x73\x65\x72\x21\x27\x29\x3b\x0a\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\ \x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\x49\x64\x28\x27\ \x68\x65\x61\x64\x65\x72\x54\x69\x74\x6c\x65\x27\x29\x2e\x69\x6e\ \x6e\x65\x72\x48\x54\x4d\x4c\x20\x3d\x20\x77\x69\x6e\x64\x6f\x77\ \x2e\x65\x72\x69\x63\x2e\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\ \x27\x65\x72\x69\x63\x36\x20\x57\x65\x62\x20\x42\x72\x6f\x77\x73\ \x65\x72\x27\x29\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x67\x65\x74\x45\x6c\ \x65\x6d\x65\x6e\x74\x42\x79\x49\x64\x28\x27\x73\x65\x61\x72\x63\ \x68\x42\x75\x74\x74\x6f\x6e\x27\x29\x2e\x76\x61\x6c\x75\x65\x20\ \x3d\x20\x77\x69\x6e\x64\x6f\x77\x2e\x65\x72\x69\x63\x2e\x74\x72\ \x61\x6e\x73\x6c\x61\x74\x65\x28\x27\x53\x65\x61\x72\x63\x68\x21\ \x27\x29\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x67\x65\x74\x45\x6c\x65\x6d\ \x65\x6e\x74\x42\x79\x49\x64\x28\x27\x66\x6f\x6f\x74\x65\x72\x27\ \x29\x2e\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c\x20\x3d\x20\x77\x69\ \x6e\x64\x6f\x77\x2e\x65\x72\x69\x63\x2e\x70\x72\x6f\x76\x69\x64\ \x65\x72\x53\x74\x72\x69\x6e\x67\x28\x29\x0a\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x2b\x20\x27\x20\x7c\x20\x27\x20\x2b\x20\x27\ \x3c\x61\x20\x68\x72\x65\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\ \x65\x72\x69\x63\x2d\x69\x64\x65\x2e\x70\x79\x74\x68\x6f\x6e\x2d\ \x70\x72\x6f\x6a\x65\x63\x74\x73\x2e\x6f\x72\x67\x2f\x22\x3e\x27\ \x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2b\x20\x77\x69\x6e\ \x64\x6f\x77\x2e\x65\x72\x69\x63\x2e\x74\x72\x61\x6e\x73\x6c\x61\ \x74\x65\x28\x27\x41\x62\x6f\x75\x74\x20\x65\x72\x69\x63\x36\x27\ \x29\x20\x2b\x20\x27\x3c\x2f\x61\x3e\x27\x3b\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x64\x6f\x63\x75\x6d\x65\x6e\x74\ \x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\x49\x64\x28\ \x27\x6c\x69\x6e\x65\x45\x64\x69\x74\x27\x29\x2e\x70\x6c\x61\x63\ \x65\x68\x6f\x6c\x64\x65\x72\x20\x3d\x20\x77\x69\x6e\x64\x6f\x77\ \x2e\x65\x72\x69\x63\x2e\x70\x72\x6f\x76\x69\x64\x65\x72\x53\x74\ \x72\x69\x6e\x67\x28\x29\x3b\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x2f\x2f\x20\x54\x72\x79\x20\x74\x6f\x20\x63\ \x68\x61\x6e\x67\x65\x20\x74\x68\x65\x20\x64\x69\x72\x65\x63\x74\ \x69\x6f\x6e\x20\x6f\x66\x20\x74\x68\x65\x20\x70\x61\x67\x65\x3a\ \x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x76\x61\ \x72\x20\x6e\x65\x77\x44\x69\x72\x20\x3d\x20\x77\x69\x6e\x64\x6f\ \x77\x2e\x65\x72\x69\x63\x2e\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\ \x28\x27\x51\x54\x5f\x4c\x41\x59\x4f\x55\x54\x5f\x44\x49\x52\x45\ \x43\x54\x49\x4f\x4e\x27\x29\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x6e\x65\x77\x44\x69\x72\x20\x3d\x20\x6e\x65\ \x77\x44\x69\x72\x2e\x74\x6f\x4c\x6f\x77\x65\x72\x43\x61\x73\x65\ \x28\x29\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x69\x66\x20\x28\x28\x6e\x65\x77\x44\x69\x72\x20\x21\x3d\x20\x27\ \x6c\x74\x72\x27\x29\x20\x26\x26\x20\x28\x6e\x65\x77\x44\x69\x72\ \x20\x21\x3d\x20\x27\x72\x74\x6c\x27\x29\x29\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6e\x65\x77\x44\ \x69\x72\x20\x3d\x20\x27\x6c\x74\x72\x27\x3b\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x64\x6f\x63\x75\x6d\x65\x6e\x74\ \x2e\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x73\x42\x79\x54\x61\ \x67\x4e\x61\x6d\x65\x28\x27\x62\x6f\x64\x79\x27\x29\x5b\x30\x5d\ \x2e\x73\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65\x28\x27\x64\ \x69\x72\x27\x2c\x20\x6e\x65\x77\x44\x69\x72\x29\x3b\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x7d\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x66\x6f\x72\x6d\x53\x75\ \x62\x6d\x69\x74\x74\x65\x64\x28\x29\x0a\x20\x20\x20\x20\x20\x20\ \x20\x20\x7b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x76\x61\x72\x20\x73\x74\x72\x69\x6e\x67\x20\x3d\x20\x6c\x69\x6e\ \x65\x45\x64\x69\x74\x2e\x76\x61\x6c\x75\x65\x3b\x0a\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x73\x74\ \x72\x69\x6e\x67\x2e\x6c\x65\x6e\x67\x74\x68\x20\x3d\x3d\x20\x30\ \x29\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x72\x65\x74\x75\x72\x6e\x3b\x0a\x0a\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x76\x61\x72\x20\x75\x72\x6c\x20\x3d\ \x20\x77\x69\x6e\x64\x6f\x77\x2e\x65\x72\x69\x63\x2e\x73\x65\x61\ \x72\x63\x68\x55\x72\x6c\x28\x73\x74\x72\x69\x6e\x67\x29\x3b\x0a\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x77\x69\x6e\x64\ \x6f\x77\x2e\x6c\x6f\x63\x61\x74\x69\x6f\x6e\x2e\x68\x72\x65\x66\ \x20\x3d\x20\x75\x72\x6c\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ \x7d\x0a\x20\x20\x20\x20\x3c\x2f\x73\x63\x72\x69\x70\x74\x3e\x0a\ \x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x20\x6f\x6e\ \x6c\x6f\x61\x64\x3d\x22\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x66\ \x6f\x72\x6d\x73\x5b\x30\x5d\x2e\x6c\x69\x6e\x65\x45\x64\x69\x74\ \x2e\x73\x65\x6c\x65\x63\x74\x28\x29\x3b\x20\x75\x70\x64\x61\x74\ \x65\x28\x29\x3b\x22\x3e\x0a\x20\x20\x20\x20\x3c\x64\x69\x76\x20\ \x69\x64\x3d\x22\x68\x65\x61\x64\x65\x72\x22\x3e\x0a\x20\x20\x20\ \x20\x20\x20\x20\x20\x3c\x68\x31\x20\x69\x64\x3d\x22\x68\x65\x61\ \x64\x65\x72\x54\x69\x74\x6c\x65\x22\x3e\x3c\x2f\x68\x31\x3e\x0a\ \x20\x20\x20\x20\x20\x20\x20\x20\x3c\x69\x6d\x67\x20\x73\x72\x63\ \x3d\x22\x40\x49\x4d\x41\x47\x45\x40\x22\x20\x77\x69\x64\x74\x68\ \x3d\x22\x33\x32\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x32\ \x22\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x64\x69\x76\x3e\x0a\x20\ \x20\x20\x20\x3c\x64\x69\x76\x20\x69\x64\x3d\x22\x73\x65\x61\x72\ \x63\x68\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x66\x6f\ \x72\x6d\x20\x61\x63\x74\x69\x6f\x6e\x3d\x22\x6a\x61\x76\x61\x73\ \x63\x72\x69\x70\x74\x3a\x66\x6f\x72\x6d\x53\x75\x62\x6d\x69\x74\ \x74\x65\x64\x28\x29\x3b\x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x3c\x66\x69\x65\x6c\x64\x73\x65\x74\x3e\x0a\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x3c\x69\x6e\x70\x75\x74\x20\x69\x64\x3d\x22\x6c\x69\x6e\x65\x45\ \x64\x69\x74\x22\x20\x6e\x61\x6d\x65\x3d\x22\x6c\x69\x6e\x65\x45\ \x64\x69\x74\x22\x20\x74\x79\x70\x65\x3d\x22\x74\x65\x78\x74\x22\ \x20\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x3c\x69\x6e\x70\x75\x74\x20\x69\x64\x3d\x22\x73\ \x65\x61\x72\x63\x68\x42\x75\x74\x74\x6f\x6e\x22\x20\x74\x79\x70\ \x65\x3d\x22\x73\x75\x62\x6d\x69\x74\x22\x20\x2f\x3e\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x2f\x66\x69\x65\x6c\ \x64\x73\x65\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x2f\ \x66\x6f\x72\x6d\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x64\x69\x76\x3e\ \x0a\x20\x20\x20\x20\x3c\x64\x69\x76\x20\x69\x64\x3d\x22\x66\x6f\ \x6f\x74\x65\x72\x22\x3e\x3c\x2f\x64\x69\x76\x3e\x0a\x3c\x2f\x62\ \x6f\x64\x79\x3e\x0a\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\ \x00\x00\x03\x7c\ \x3c\ \x21\x44\x4f\x43\x54\x59\x50\x45\x20\x68\x74\x6d\x6c\x3e\x0a\x3c\ \x68\x74\x6d\x6c\x3e\x0a\x3c\x68\x65\x61\x64\x3e\x0a\x3c\x6d\x65\ \x74\x61\x20\x63\x68\x61\x72\x73\x65\x74\x3d\x22\x75\x74\x66\x2d\ \x38\x22\x3e\x20\x0a\x3c\x6d\x65\x74\x61\x20\x68\x74\x74\x70\x2d\ \x65\x71\x75\x69\x76\x3d\x22\x63\x6f\x6e\x74\x65\x6e\x74\x2d\x74\ \x79\x70\x65\x22\x20\x63\x6f\x6e\x74\x65\x6e\x74\x3d\x22\x74\x65\ \x78\x74\x2f\x68\x74\x6d\x6c\x3b\x20\x63\x68\x61\x72\x73\x65\x74\ \x3d\x75\x74\x66\x2d\x38\x22\x3e\x0a\x3c\x74\x69\x74\x6c\x65\x3e\ \x40\x54\x49\x54\x4c\x45\x40\x3c\x2f\x74\x69\x74\x6c\x65\x3e\x0a\ \x3c\x6c\x69\x6e\x6b\x20\x72\x65\x6c\x3d\x22\x69\x63\x6f\x6e\x22\ \x20\x68\x72\x65\x66\x3d\x22\x40\x46\x41\x56\x49\x43\x4f\x4e\x40\ \x22\x20\x74\x79\x70\x65\x3d\x22\x69\x6d\x61\x67\x65\x2f\x78\x2d\ \x69\x63\x6f\x6e\x22\x20\x2f\x3e\x0a\x3c\x73\x74\x79\x6c\x65\x3e\ \x0a\x62\x6f\x64\x79\x20\x7b\x0a\x20\x20\x70\x61\x64\x64\x69\x6e\ \x67\x3a\x20\x33\x65\x6d\x20\x30\x65\x6d\x3b\x0a\x20\x20\x62\x61\ \x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x2d\x77\x65\x62\x6b\x69\ \x74\x2d\x67\x72\x61\x64\x69\x65\x6e\x74\x28\x6c\x69\x6e\x65\x61\ \x72\x2c\x20\x6c\x65\x66\x74\x20\x74\x6f\x70\x2c\x20\x6c\x65\x66\ \x74\x20\x62\x6f\x74\x74\x6f\x6d\x2c\x20\x66\x72\x6f\x6d\x28\x23\ \x38\x35\x37\x38\x34\x41\x29\x2c\x20\x74\x6f\x28\x23\x46\x44\x46\ \x44\x46\x44\x29\x2c\x20\x63\x6f\x6c\x6f\x72\x2d\x73\x74\x6f\x70\ \x28\x30\x2e\x35\x2c\x20\x23\x46\x44\x46\x44\x46\x44\x29\x29\x3b\ \x0a\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x2d\x72\x65\ \x70\x65\x61\x74\x3a\x20\x72\x65\x70\x65\x61\x74\x2d\x78\x3b\x0a\ \x7d\x0a\x23\x62\x6f\x78\x20\x7b\x0a\x20\x20\x62\x61\x63\x6b\x67\ \x72\x6f\x75\x6e\x64\x3a\x20\x77\x68\x69\x74\x65\x3b\x0a\x20\x20\ \x62\x6f\x72\x64\x65\x72\x3a\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\ \x64\x20\x23\x38\x35\x37\x38\x34\x41\x3b\x0a\x20\x20\x6d\x61\x78\ \x2d\x77\x69\x64\x74\x68\x3a\x20\x36\x30\x30\x70\x78\x3b\x0a\x20\ \x20\x68\x65\x69\x67\x68\x74\x3a\x20\x35\x30\x25\x3b\x0a\x20\x20\ \x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x34\x30\x70\x78\x3b\x0a\x20\ \x20\x70\x61\x64\x64\x69\x6e\x67\x2d\x62\x6f\x74\x74\x6f\x6d\x3a\ \x20\x31\x30\x70\x78\x3b\x0a\x20\x20\x6d\x61\x72\x67\x69\x6e\x3a\ \x20\x61\x75\x74\x6f\x3b\x0a\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\ \x72\x61\x64\x69\x75\x73\x3a\x20\x30\x2e\x38\x65\x6d\x3b\x0a\x20\ \x20\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x20\x63\x65\x6e\ \x74\x65\x72\x3b\x0a\x20\x20\x76\x65\x72\x74\x69\x63\x61\x6c\x2d\ \x61\x6c\x69\x67\x6e\x3a\x20\x6d\x69\x64\x64\x6c\x65\x3b\x0a\x20\ \x20\x6d\x61\x72\x67\x69\x6e\x3a\x20\x61\x75\x74\x6f\x3b\x0a\x7d\ \x0a\x68\x31\x20\x7b\x0a\x20\x20\x66\x6f\x6e\x74\x2d\x73\x69\x7a\ \x65\x3a\x20\x31\x33\x30\x25\x3b\x0a\x20\x20\x66\x6f\x6e\x74\x2d\ \x77\x65\x69\x67\x68\x74\x3a\x20\x62\x6f\x6c\x64\x3b\x0a\x20\x20\ \x62\x6f\x72\x64\x65\x72\x2d\x62\x6f\x74\x74\x6f\x6d\x3a\x20\x31\ \x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x23\x38\x35\x37\x38\x34\x41\ \x3b\x0a\x20\x20\x6d\x61\x72\x67\x69\x6e\x2d\x62\x6f\x74\x74\x6f\ \x6d\x3a\x20\x30\x70\x78\x3b\x0a\x7d\x0a\x3c\x2f\x73\x74\x79\x6c\ \x65\x3e\x0a\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\ \x3e\x0a\x20\x20\x3c\x64\x69\x76\x20\x69\x64\x3d\x22\x62\x6f\x78\ \x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6d\x67\x20\x73\x72\x63\x3d\ \x22\x40\x49\x4d\x41\x47\x45\x40\x22\x20\x77\x69\x64\x74\x68\x3d\ \x22\x36\x34\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x34\x22\ \x2f\x3e\x0a\x20\x20\x20\x20\x3c\x68\x31\x3e\x41\x64\x42\x6c\x6f\ \x63\x6b\x20\x50\x6c\x75\x73\x3c\x2f\x68\x31\x3e\x0a\x20\x20\x20\ \x20\x3c\x70\x3e\x40\x4d\x45\x53\x53\x41\x47\x45\x40\x3c\x2f\x70\ \x3e\x0a\x20\x20\x3c\x2f\x64\x69\x76\x3e\x0a\x3c\x2f\x62\x6f\x64\ \x79\x3e\x0a\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\ \x00\x00\x11\x60\ \x00\ \x00\x44\xb3\x78\x9c\xcd\x3c\x6b\x57\xdb\xc8\x92\xdf\xf9\x15\x3d\ \x22\x19\xc9\x13\xbf\x30\x90\x21\x18\x73\x4d\xc0\x99\x78\x97\x10\ \x16\x3b\x93\x99\xcd\xe6\xe4\x08\xab\xb1\xb5\x91\x25\x5d\x49\xe6\ \x71\x33\xfc\xf7\xad\xea\x87\xd4\xdd\x92\x6d\x20\xd9\x7b\xc6\x73\ \x66\xb0\xd5\x55\xd5\xf5\xae\xea\x87\xe6\xe0\xa7\x93\xf7\xc7\xe3\ \x3f\xcf\x07\x64\x96\xcd\x83\xc3\x8d\x03\xf9\x87\xba\x1e\xfc\x99\ \xd3\xcc\x85\x91\x2c\x6e\xd0\x7f\x2e\xfc\xeb\x9e\x35\x89\xc2\x8c\ \x86\x59\x23\xbb\x8b\xa9\x45\xc4\xaf\x9e\x95\xd1\xdb\xac\x85\xa8\ \x5d\x32\x99\xb9\x49\x4a\xb3\xde\x22\xbb\x6a\xec\x59\x40\x23\xf3\ \xb3\x80\x1e\xf6\x47\xc3\xf1\xa0\x31\x1e\x8e\x4f\x07\xfd\x83\x16\ \x7f\xb6\x71\x10\xf8\xe1\x57\x92\xd0\xa0\x67\xf9\x40\xcb\x22\xb3\ \x84\x5e\xf5\xac\xfe\x9b\xa3\xdf\x87\xc7\xef\xcf\xfa\x16\xc1\x79\ \x60\x70\xee\x4e\x69\xeb\xb6\xc1\x81\x5a\x80\x98\x66\x77\x01\x15\ \xa3\x6c\xf2\x49\x9a\x5a\x64\x4e\x3d\xdf\xed\x59\xe9\x24\xa1\x34\ \x84\xb9\x2f\x23\xef\x8e\x7c\xdb\x20\xf0\xb9\x74\x27\x5f\xa7\x49\ \xb4\x08\xbd\x7d\xd2\xb8\xa1\x97\x5f\xfd\xac\x31\x4d\x5c\xcf\x07\ \xfe\x1d\x60\x83\xba\x49\x9d\x04\xf4\x2a\x23\x59\x14\x8b\x6f\x97\ \x51\x96\x45\xf3\x3a\xb9\x4a\xa2\xb9\xb3\xb9\xb7\xfb\xeb\xde\xce\ \x51\xad\x0e\x00\xce\xe6\x9b\x13\xfc\x07\x7e\x4c\xa2\x20\x4a\x1a\ \x29\x20\x39\xed\xe6\x6e\x9d\xc8\x91\x5a\xd7\x98\xb6\x91\xd0\x98\ \xba\xd9\x3e\xe1\x7f\x1b\xb7\x1c\xe0\x0a\x54\xb8\x4f\xb6\xb6\xe3\ \xdb\x56\xa7\x13\xdf\x12\xeb\x2d\x0d\xae\x69\xe6\x4f\x5c\x72\x46\ \x17\xd4\xaa\x93\xfc\x41\x9d\x1c\x25\xbe\x1b\xd4\x49\xea\x86\x69\ \x23\xa5\x89\x7f\xc5\x69\x30\x1e\xf6\xc9\xe6\x6e\x67\x77\xf2\xf2\ \x65\x77\xe3\x9e\x0b\xfe\x8b\x10\x5d\x8a\xbb\x00\x14\x40\x0b\xe8\ \x04\x66\x0c\xa3\x90\x16\x1c\x34\x52\xff\x5f\x14\xd8\x68\xb7\x9f\ \xf3\x87\xa8\x91\xc6\x8c\xfa\xd3\x19\x72\xd7\x7c\xc9\x9f\xce\xdd\ \x64\xea\x87\xfb\xa4\x1d\xdf\xe2\x2c\x4d\xd7\xf3\xc4\x1c\x71\x94\ \xfa\x99\x1f\xc1\x98\x7b\x99\x46\xc1\x22\x13\xc4\x13\x46\x61\x0b\ \x11\x40\x45\xfc\x0b\x1b\xb8\xf1\xbd\x6c\xb6\x4f\x3a\x3b\xf2\x81\ \x9c\xac\x78\xa2\x9a\x6c\x91\x04\x4e\x7f\xf8\xee\xb7\x2f\xe7\xa7\ \x1f\x46\x7d\xa1\xdc\xc9\x22\x49\x51\xf0\x38\xf2\xc1\x0f\x13\x64\ \x69\x63\x63\x13\x1c\x75\xf2\x15\xfc\x20\x10\xac\x49\xa6\xdd\x45\ \x16\x71\x3c\x74\x98\x86\x1b\xf8\x53\x78\x3a\xa1\x1c\x35\xd7\xc4\ \x8d\xe0\xe3\x32\x0a\x3c\xa4\xa8\xd0\xf3\xfc\xeb\x26\x80\x27\x77\ \x25\xa1\xc1\x85\xdd\xcc\xbf\x96\x1a\x0d\x22\x34\x34\xfa\x90\x90\ \x24\x4a\x3c\xd0\xbd\x90\xb9\x50\x82\xb4\x8c\x18\x67\x6e\x2e\x64\ \x7d\xfd\xfe\x8f\xc6\xeb\xf7\x17\x27\x83\x8b\x7e\x0d\x30\x74\xfd\ \xef\x72\xfd\x2b\xac\xf9\xf3\xa9\x60\xca\xf3\xd3\x38\x70\xef\x40\ \x80\x20\x9a\x7c\xed\x56\xa8\x40\x43\x74\xd7\x18\x10\x85\x10\x06\ \x67\xaa\x03\x23\x12\xd3\x88\x85\xdb\x48\x23\xee\xfd\xfa\x9c\x5b\ \x23\x57\xd9\xfe\x2c\xba\xa6\x09\x69\x42\x84\x66\xf5\xf2\xe3\x49\ \x10\xa5\xb4\xe2\x39\x28\x36\x72\x3d\x53\x34\x3f\x44\xff\xc4\x19\ \xd2\xd8\x0d\x9b\x97\xd1\xed\x18\x13\x8a\x00\xe3\x5c\x15\x4c\xcd\ \xdd\xdb\xdc\x95\x3b\x39\xef\xcb\x04\x66\x12\xee\xed\x3d\xaf\x16\ \x7f\x89\xe7\x20\xb3\x60\xf5\x9b\xfd\x99\xef\x79\x34\xcc\x39\x63\ \x62\x69\x6c\x91\xad\x92\xc7\x17\x4f\x56\x1b\xe1\x55\xe7\xb9\xc2\ \xe2\x2b\x29\x5e\x65\x98\x1c\x9f\xbe\x1f\x0d\xc0\x73\xc2\x48\xe4\ \x9d\x52\x3a\x2a\xe6\x52\x05\xe1\x9e\x08\x3c\x41\x2a\x02\x0e\x7c\ \x8f\x64\x09\x64\x9b\xd8\x4d\x00\xa8\xab\x5b\x81\xa7\x10\x55\x52\ \x61\xb5\x6f\xaa\xd3\x8b\xe4\x34\x4d\xe8\x9d\x16\x0c\x98\x7b\x17\ \xe9\x3e\xd9\xe6\xbe\xcc\x88\xa0\x73\xfc\x28\x6d\xe9\x2e\xbb\x5a\ \x5b\x83\x93\xe1\xf8\xdf\xa9\x2c\x94\xf3\x7b\x75\xa5\x45\x86\xd4\ \xd6\xcb\x92\xb6\x5e\x3e\xc5\xb7\xda\x2b\x53\xf0\xc5\xe0\xf4\xfd\ \xd1\xc9\xbf\x53\x5f\x5c\xd6\xa7\x68\x6c\x87\x6b\x0c\xca\x02\xe2\ \x02\xe5\x46\xd9\xc7\xb6\xf7\x72\x79\xb5\x54\xf1\x72\xb7\x78\x8c\ \xf9\xb3\xc1\x55\x55\xd4\x11\xf1\x98\xd7\xb8\xf2\x73\xa6\x4a\x48\ \x43\xb9\x32\xb5\x2a\xd0\x79\x74\x15\xe8\xec\xb2\xdc\xad\x09\xf2\ \x90\xbc\xff\x20\xbe\x4d\xc2\xcd\xcb\x05\x34\x3f\x21\xa4\x56\xc8\ \xb6\xf1\x22\xd3\x8a\xa9\x44\xdd\xae\x54\xd0\xb6\xd4\x79\xf3\x2a\ \x4a\xe6\x63\xf7\xd2\xc8\xcc\x64\x7b\xb7\xfd\x23\x34\x2b\xaa\xa0\ \x32\x0b\xe3\xf4\x53\xd1\x15\x5a\x9f\x8d\xf8\xc8\x6b\x42\x65\x4f\ \x24\x35\x01\x9c\x43\x07\x9b\x3d\xa8\xb5\xd9\x7e\xa9\xe6\x99\xef\ \xef\x6f\x46\x83\xf1\x78\x78\xf6\xdb\xaa\x1e\x67\x13\x99\xf3\xc3\ \x69\xfa\x1a\x8c\xf3\x10\x1e\xc9\xee\x9e\x96\x0c\x3b\x85\x63\x83\ \x32\x25\xa7\xbb\x26\xef\x85\xda\x25\xef\xc5\x13\x95\xf7\xcd\xc1\ \xc9\xe0\x78\x60\xb4\x88\xbb\x86\xd7\xcb\x80\xdc\xca\x07\x62\xe8\ \x1e\x41\x0a\x28\xb6\x90\x0e\xb6\x0c\xf8\x95\x49\x22\x8a\xdd\x89\ \x9f\x81\xab\x6f\xf1\xdf\xff\x6a\xf8\xa1\x47\x6f\x31\xa6\xda\x25\ \x05\x35\xc5\x22\x45\x68\x4a\xf4\x66\x4c\x31\x15\x2e\xb8\x25\xbd\ \x4a\xa3\x11\x93\xc0\xbd\xa4\x66\x43\xd9\x29\x49\xb2\xb5\xaa\x4f\ \x30\xf9\xca\xa2\x69\x14\xeb\x61\xc5\x17\x1c\x0a\x1d\x41\x39\x1f\ \xe8\x54\x30\x27\x22\xf5\x49\xcc\xa9\xd9\x59\x58\xfd\xd5\xde\xf3\ \xf2\x14\x49\x74\x93\x3e\x40\x7e\x88\x7c\xd2\xd6\xcc\xae\x48\x24\ \xac\xb9\xb9\xb7\xb7\xb7\x74\x02\x35\xd5\x2c\xeb\xb5\x04\x9f\x7b\ \x66\xcf\xb9\xd5\xd1\x93\x8a\x52\xc6\x4c\x35\x56\x78\x89\x60\x00\ \xcb\x8d\xf4\x94\xf2\x6a\x60\x15\x5b\x25\xad\xe8\x39\xec\x57\xf9\ \xd8\x68\x62\x1b\x4a\xba\xce\x23\x51\x24\x50\x25\x07\x6b\x6e\xc2\ \x82\xd8\x2c\x4e\x52\xb6\xc6\x6e\x95\x13\x0a\x7f\xbf\xdf\x38\x68\ \xb1\xa5\xf3\xe1\x06\xac\xa1\x27\x89\x1f\x67\xea\x22\xfa\x7f\xdd\ \x6b\x97\x3f\xb5\x48\x9a\x4c\x60\x25\xfe\x1f\xff\xf5\x61\x70\xf1\ \x67\xdf\x3a\x04\x3c\x36\x70\xf8\x18\xbc\xc6\x87\xe1\x23\x50\x0f\ \x19\xd7\xd7\x6e\x42\xb0\xbf\x80\x24\xf8\x65\xf8\xee\xe8\xb7\x01\ \xe9\x11\xbb\x2f\x9e\x34\x20\x45\xf6\xed\x6e\x0e\xf8\xe1\xe2\x94\ \x0d\xc3\x5f\xf5\x31\xdb\x66\x60\x03\x7c\xc3\x41\x19\xc2\x56\x8f\ \x8d\x1c\x9d\x9f\x9f\xfe\xa9\x8e\x9c\x0d\x3e\x7e\x39\x97\xf3\xc1\ \x8f\x06\xfe\x28\x51\xfd\x92\x13\x60\x3f\x1b\xac\x75\x2c\x01\x5d\ \x0c\xde\xbd\xff\x5d\xe1\xa0\xc1\x1f\x54\x01\xa2\x64\x1a\x20\x6b\ \xae\x4a\x80\x6f\x06\xe3\xe3\xb7\x86\x5c\x8d\xe2\xa1\x8a\xf0\xee\ \xe8\x0f\x26\xc8\xe8\xcb\xc5\xfb\x8f\x00\xdd\x87\x3f\x4c\x98\x51\ \xbf\x00\x3a\x19\x1e\x9d\x7e\xf9\x38\x3c\x19\xbf\x45\x88\xd1\x49\ \x63\x34\xfc\xef\x01\x8c\xe7\x00\xd8\x05\x40\x74\x0c\x3d\x18\x6f\ \x6c\x89\x81\xab\x45\x38\xc1\x3a\x43\x68\x3a\x71\x63\xca\x56\x5d\ \x0e\xdb\xcc\xa9\x09\x17\x65\x8e\xc7\x16\x63\x3d\xfe\x17\x9a\x37\ \xf0\xf7\x09\x75\x5a\x56\x6b\x5a\x27\xf6\xcf\xff\x5c\x44\x59\xd7\ \x16\xe5\x6d\x05\xb8\xcd\xc1\x5d\xa8\x6d\x1a\x78\x42\xb3\x45\x12\ \x72\x68\xfe\xf4\xde\x60\x6e\x11\x3e\x85\x3d\xce\x18\x9b\xd4\x7a\ \x00\x7b\x9c\x31\x06\xfe\x3f\xf6\xe3\xf8\xe3\xdc\x7d\x80\x92\x0f\ \x65\x5f\xe5\x0c\x7e\xc2\x44\xf0\x5f\x53\x69\x2a\xfd\x0a\x20\xbb\ \x04\x24\x98\x00\xa8\x6a\x16\xa2\xf0\x82\xce\xa1\xe1\x3b\x0e\xfc\ \xc9\x57\x07\x32\x8c\xca\x46\xc2\x86\x20\x2d\x3a\xcf\xd8\x50\x93\ \x95\x57\x47\xee\x69\x95\x69\x0d\xc0\x57\xfe\x93\xde\x9d\x27\x34\ \x4d\x1d\x4d\xd7\xfe\x15\x71\x68\xf3\x2b\xbd\x3b\x8e\x3c\x50\x62\ \x8f\x6c\x6d\xab\xc3\xf8\x81\x19\x10\x9f\x7a\x8e\xc2\xbf\x22\xc3\ \x95\x1b\xa4\xb4\x18\xb9\xcf\xbf\x51\x78\x5e\x9e\xa0\xf3\xab\x39\ \xc1\x33\xc7\xde\xbc\x72\x3d\xfa\x9e\xf7\xb7\x76\x0d\x16\xab\x28\ \xf5\x23\xa7\x93\x76\x4d\x16\x4b\xcc\x1a\x85\x6f\x68\x36\x99\x31\ \xaf\xe3\x7a\x9d\xcc\xe8\xe4\xab\xa1\x5c\x8c\x2d\x51\x03\x46\x98\ \x89\x8b\xa9\x24\x74\x93\x7d\xa1\x1e\xf9\x87\x06\x88\x71\xcf\xb7\ \x17\x6c\xb2\x5f\x1a\xb9\xf6\x53\x1f\x5a\x60\xbb\x20\x87\x62\x33\ \x27\x3c\x85\x32\x83\x42\x83\x6d\xbe\x71\x38\x3f\x80\xf6\xa9\x44\ \xe5\x7e\x89\x7d\x61\x52\x8a\x16\x42\x87\x50\x25\x29\xeb\x95\xfd\ \x5a\x64\x8e\x95\x06\xd1\x8d\x55\xcf\x49\x20\xda\x33\xc7\x52\xa1\ \xad\x5a\x93\xbb\x19\x98\x61\xd9\xc4\xdc\xb1\x2a\x5d\x54\xcd\x4e\ \xba\x93\x76\x35\x4d\xc3\xc8\x07\x16\x2f\x02\x68\x32\xf3\x03\x0f\ \x3a\x49\xc7\x76\x91\x5f\x3f\x49\x33\xa7\xd6\x74\xb3\x2c\x71\x6c\ \xdc\x7c\xb6\xcb\xf8\x63\x11\xff\x6a\x4e\x29\x51\xc3\xbe\x41\x21\ \x88\xa5\x2d\x8f\x17\x19\x07\x92\x17\x70\x52\x88\x55\x33\x06\x38\ \x9b\x36\x6e\xb6\xef\xb7\x5a\xb6\x48\xb8\x42\xcf\xb8\x9f\x0b\xe4\ \xdd\x38\xa6\xa1\xe7\xd8\x07\x9e\x7f\x4d\x7c\xaf\x67\xa9\x0a\x25\ \xac\xb0\xf7\x2c\xd9\x1d\xb7\x9b\xaf\xba\xb2\xd9\x60\xab\xe9\x7c\ \x91\x70\xe5\xdf\x52\xaf\xcb\x1a\xde\x76\xd7\x26\x2f\x34\x56\xb4\ \x8f\x8d\xad\x46\xbb\xab\xec\xa8\x89\x6e\x8b\x7d\x97\x7d\xf7\x2b\ \xf8\x74\x95\x15\x81\xd8\x2a\xef\x5a\x87\xab\x89\xe7\x62\xa8\x2b\ \x4f\x0b\xcc\x0e\xe1\x1c\x63\x2e\xe9\x59\x22\xe8\xcc\x14\x73\x0d\ \x8d\x57\x6d\x2d\x79\x5c\x1c\xb3\x76\x04\xe0\xca\x0e\x00\xa3\x25\ \x17\x00\x68\xbb\x06\xc0\xb6\x75\x48\xd6\x10\xcf\xd8\x8a\x73\x12\ \xb8\xc8\x66\xbe\x04\x85\x6e\x27\x4b\xe0\x5f\x0f\x79\x63\xed\x09\ \x10\xdb\x27\x07\x2d\x78\x22\x9e\xae\xe4\x98\xf5\xbf\xca\x02\x96\ \x5b\x19\xa8\x83\x7b\x58\xe0\x91\xc1\x82\x72\x71\x84\xc7\x30\x56\ \x39\xf5\x16\x4c\xbc\x8e\xe7\x84\xd1\xcb\xb3\x82\x95\x73\xca\x3b\ \x8b\x1f\xc4\x2b\x8b\x11\x93\x5b\x1e\x46\x8f\xe5\x97\x31\x92\x73\ \xa4\xcd\x29\xd3\xa5\x98\x37\x4f\xbd\xe8\x40\x2c\xc1\x83\x5f\x95\ \x32\x72\x36\xf3\xd3\xf5\x8e\xc3\x57\x7b\x20\x8a\x46\xf7\x90\x90\ \x5c\x55\x6a\x3f\x06\x32\x81\xd2\x18\xce\xc3\x45\x6b\x31\xff\x39\ \x3c\x88\xa5\x0b\xe5\xbd\xfe\x7a\xb7\x56\x94\xc0\xb1\x72\x5d\x93\ \x3e\xdf\xf8\x25\xa8\x84\x63\xae\x04\x2d\x7d\xaf\x8f\xc9\x55\xd4\ \xb9\x02\x58\x07\x8c\x42\x13\x75\x1a\xa5\x8c\xa3\x85\xe3\xb5\x0a\ \x80\xe0\x3f\xe4\xff\xc5\xa4\xbb\xa2\xaa\xf0\xc2\x75\xe5\x07\xb0\ \xd6\xc2\xa2\x65\xbb\x41\x3c\x73\x1d\x91\xe7\x7a\xaf\xda\x35\xfb\ \x9e\xd7\x9e\x61\xa8\xe6\xff\x65\x75\x5f\xad\x4a\x9a\x72\xee\x0d\ \x64\x35\x2d\x95\xb1\x79\x12\x22\xdf\x08\xfb\xd2\xc4\x23\xc0\xf3\ \x04\x98\x9a\xba\x9c\x78\x97\x98\xf4\x44\x1c\x63\xd6\x89\x26\x8b\ \xd4\x59\x5a\xf6\x2e\xd8\x7e\x67\x65\xe1\xc3\xa2\xb4\xf8\x9e\x8a\ \x86\x49\xb1\x02\x59\xcb\x86\x8a\x39\xb0\x70\x2d\x96\x54\x2d\x9e\ \x9c\x35\xdb\x01\x19\x35\x97\xd6\xf5\xa5\x9c\xc2\x4a\x1a\x53\xea\ \xe1\x09\x54\x13\x45\x1d\xcf\x16\xf3\xcb\xd0\xf5\x79\x47\x5c\xad\ \x16\xc5\xc1\xcc\x06\xb3\x68\x06\x70\xad\xb2\x86\x49\x51\xd6\x41\ \x09\x1e\x58\x61\x8e\xb6\x9b\xd2\x6c\x10\x50\xfc\xfa\xfa\x6e\x08\ \xf5\x35\x3f\x1e\x03\x95\x14\x63\xe9\xeb\xbb\xb1\x3b\x3d\x73\xe7\ \xd4\xb1\xc1\x6d\xed\xda\xa7\x7c\xe2\xcf\xba\x8e\x5d\x20\x8e\x8d\ \x5c\x35\x2e\xd8\xe9\x53\xdb\xc0\x88\x60\x81\xee\x87\x6e\xc0\xbb\ \x00\x17\x31\x8f\x40\x8b\x3e\x44\x20\x2d\xdb\x31\xa5\xe8\xb0\xb8\ \x80\xc8\x39\xa8\x2b\x1a\x05\x1d\xbe\x49\xa2\xf9\x87\x94\x26\x43\ \x8c\x66\x47\x77\x3e\x66\x1e\x8b\xc5\xb4\x55\xab\x95\xc8\xf2\x0e\ \x47\x21\x2c\xb1\xd9\x40\x09\x5f\x97\x63\x32\x73\xc3\x29\xf5\x1e\ \x26\x06\x22\x14\xf9\xf5\x58\x74\xbd\x2b\xec\x52\x00\x63\x38\x72\ \x78\xc3\x57\xcb\xf4\xfe\xfa\x8b\x38\xaa\x7a\x7f\xea\xa9\x5c\xfe\ \xfc\xb3\xfa\xeb\x27\xee\xe5\xc4\x5c\x42\x14\x81\xb3\xdc\xac\x2c\ \x82\x34\xc3\x32\x9e\xe6\x53\xdc\x4c\x56\xb4\x50\x1d\x17\x6b\x56\ \x2c\xab\x3a\xeb\x52\x96\x5d\xd1\x6a\x97\x60\x97\xc5\x61\xb5\xed\ \xea\x65\x7b\xad\xa4\xc9\xe7\x1d\xe2\x89\xc6\x9b\x28\x41\x87\xad\ \xa6\x6b\x10\x51\x13\xe7\x3d\x5f\xe7\xe9\x52\xea\x35\xad\x62\xb1\ \x56\xb0\x20\xac\xeb\xb8\x41\x70\x0e\x6c\xa4\x4b\x97\xb1\x05\x40\ \x39\xdd\xa6\x2c\x65\xda\xee\x27\x59\xac\x59\xf4\x59\x9f\x4d\x6f\ \x66\x9d\x95\x00\xc6\x25\x81\x02\xcf\x7b\x88\x12\x06\x0b\x23\x40\ \xb0\x2c\xad\x56\xe4\x07\xe1\x60\x7b\xea\x4e\x66\x45\xd9\xf1\xab\ \x7c\x53\x56\x04\xd6\xde\x3c\xaa\x24\x68\x9c\x57\xd2\x58\x26\x87\ \xb1\xd8\x29\x93\x94\x95\xc6\x24\xb8\xb4\xf1\x36\x49\xa0\x66\x5e\ \x40\x40\x82\x74\xfb\xac\x8d\x34\x36\x4e\xb0\x99\xfc\x8b\x31\xae\ \x0e\x6b\xbb\x3e\x0c\x04\x26\x34\xf1\xb1\x4e\xb1\xc1\xae\xb2\x62\ \xbe\x57\xe3\x50\xac\x3c\x18\x17\x4b\x1c\xc6\xf3\xd0\xff\x80\x95\ \x3a\x57\x5f\x1d\x45\xfe\x92\x46\x8b\x64\x42\xcb\x4b\xfe\x6b\x35\ \xb3\x4d\x12\xea\x66\x54\x64\x11\x51\x4e\x0a\x46\xd0\xfa\x7a\xd2\ \x60\xfa\x87\xb4\x61\x0b\xa7\xa8\xaa\xe9\xcb\x88\x33\x7d\x2b\x4b\ \xd1\x25\x19\x49\xe1\xbd\x5c\xcd\x96\xd1\x76\x55\xca\xae\x41\x97\ \xf9\x5a\x9d\x14\x25\xbd\x0a\x28\x97\x8c\xc7\x94\x29\x1a\x7a\xdf\ \xd6\x0a\x06\xf8\xc2\x5b\xed\x2b\x00\x7e\xc5\x14\xa2\x7a\x98\x08\ \x7e\x18\xd2\x64\x0c\x8e\x8c\x5b\x6b\xda\xf6\xa1\x52\x56\x2b\xb6\ \x15\x2b\xb8\xed\x3c\x92\xdb\xce\x52\x53\xb3\xb6\x73\x35\xb0\x68\ \xbf\x11\x5c\xdd\x2d\xe1\xa7\x65\x67\x91\x47\x6b\xeb\x28\x30\x39\ \x00\xbf\xd8\xdd\xae\x90\x69\xfb\x91\x32\x6d\x2f\x93\x89\x5d\x13\ \x59\x07\xad\x09\xa5\xee\x53\xae\x10\xcb\xa4\xa1\x8b\xc5\xb7\xdf\ \x2b\x04\xdb\x79\xa4\x60\x3b\xcb\x04\xe3\x57\x14\xd6\x81\x1b\x92\ \x15\x5d\xfe\x0a\xc9\x4c\x1a\xa6\x64\xd8\x49\xa8\x89\x0b\x93\x07\ \xdf\x28\x3a\xc6\x94\xcb\x52\x5d\xf7\x89\xa3\xee\x8a\x31\x16\x38\ \x6b\xc6\x3b\x6b\xc6\xb7\xd7\x8c\xef\x68\x82\x2d\x69\x0b\xad\xbc\ \x5d\xb7\x6a\x1a\x05\xa0\x58\x91\xd1\xe1\x69\x75\x3e\xe7\xed\x2f\ \x6b\x56\x1c\xdf\x5b\x95\xcc\x7f\xd0\xf2\xc1\x57\xd7\x0d\x62\x87\ \x90\x2d\xb4\x16\xa1\x47\xaf\xfc\x10\x9a\xab\xf5\x4b\x99\xc7\xb7\ \xa5\xeb\x0b\x00\x56\xc6\x7f\x60\xc1\x0c\xe9\x0d\x39\x81\x98\x58\ \xda\x34\x01\x1d\x96\x0e\xc7\x91\xa8\xca\xa2\x14\x56\x68\x8c\xf5\ \x45\xdf\xab\xb3\x42\x0a\x58\x91\x10\xc7\x07\x92\xed\x2e\xf1\xc9\ \x01\x9f\xa1\x19\xd0\x70\x9a\xcd\xba\xe4\xc5\x8b\xca\x3e\x89\x1b\ \x8e\x81\x7e\xf2\x3f\x1b\x5d\xf7\x03\x2c\x80\x1f\xbc\x4f\xe0\x87\ \xd8\x14\x54\x6e\x6f\x68\xbb\xce\xeb\x16\x81\x6b\x16\x48\xc6\xb4\ \x69\x14\x50\x68\xd3\xa7\x72\x27\xf9\x05\xb1\x08\x39\xc4\x5d\x98\ \x17\x46\x91\x35\xc5\x5a\xf0\x75\x0f\xc7\x2b\x8b\xb4\x46\x34\x99\ \x2c\x57\x0a\xc4\xb3\x65\x69\xfd\xc3\xee\x6f\xa9\xd5\x75\x75\x3d\ \x55\x7b\xf9\xef\x69\xe6\xc1\x2f\x59\x20\x2b\x7e\xb9\x3c\x9c\x5d\ \x21\x8e\x6c\xf2\xf9\x2d\x74\x9b\x6b\x95\x75\x89\x5a\xdb\xfe\xcc\ \x91\x08\x66\x6f\xbe\xdc\xe5\x64\x17\xcc\xf3\xfc\x92\x6e\x59\x65\ \x43\xdf\x9e\xb1\x60\xd4\x52\xb6\x67\x4c\xfb\xb2\x8d\x97\x9c\x29\ \xbc\xcc\x0d\xbc\x80\x1b\xb7\xcb\xb6\x2e\x25\x11\x2e\x92\x8a\xaf\ \xee\xdf\x3c\x24\x29\x30\x03\x2c\x37\x84\xd8\xaa\xc0\x94\x6a\x9c\ \x77\xfe\xdd\x72\xe9\xe3\xf6\x6d\xd6\xb6\xbb\xd5\xba\xe0\xee\x8e\ \xda\x58\x96\x29\xff\x36\xfa\x78\x4a\xd0\x3f\x29\xe0\x4d\x4d\x15\ \x27\xd0\xbe\x67\xee\xf6\x41\x92\x82\x38\x98\x3b\x96\xb8\x04\xf1\ \xf1\xe8\xe2\xac\x6f\xd5\x6a\x7f\x5b\x2d\x2e\x7e\x44\x29\x78\x50\ \xf3\xc3\xd5\xc6\x9b\x1f\x4c\x20\x8a\xaf\xe2\x35\x20\x4c\x99\xda\ \xe6\xee\xaa\x8d\x1a\xbd\xa0\x3c\x69\x3f\x25\x9f\x52\x3f\x34\xc6\ \x77\x8b\xd4\xc3\x4c\x7e\x21\x49\x7f\x99\xe1\x13\x64\x9f\x5f\x7a\ \x56\x33\x0e\xa7\xd6\xe7\x6f\xe2\xd0\x91\x5d\x3f\xe4\x67\x91\xf6\ \x8b\xe2\x02\xcb\x0b\x3b\xbe\xbd\x97\xf7\x9a\xf4\x44\x6d\x57\xbd\ \xbd\x91\x1f\x29\x30\x52\x78\xa2\xa0\x5c\x86\x81\x24\x17\xdf\xda\ \xf5\xa5\x25\xd2\xf8\xd8\x9c\x35\x24\xf2\xce\xcd\x66\x4d\x76\x00\ \xea\x28\xf4\x5a\x64\xab\xb9\xbb\x53\x13\x74\xb5\x1d\x06\xf4\x0d\ \xc6\x02\x4b\xf8\x37\x7e\xe8\x45\x37\xb5\x26\x7b\x62\x1e\x63\xf3\ \x59\x34\x38\xfe\xa8\xe2\xbc\xfb\xa3\x20\xc9\xf8\xb9\x0a\xa2\x28\ \x71\x34\xf9\xb6\xdb\x65\x9c\xb7\x92\xbe\x82\xb4\x4e\x9e\x9d\xb6\ \x29\xcc\xdc\xbd\x7d\x2d\xfa\x3c\x85\x0e\x17\xb1\x95\xb3\x66\x9c\ \x8a\xe7\x48\x87\xfa\xc5\xa5\x9a\x46\x4e\x1d\x59\x82\x7f\x40\xb6\ \x34\x9c\xad\x32\x77\x52\xdb\x39\xd4\x2f\x39\x57\xaa\xd7\x58\x9b\ \x6a\x50\xa1\xaf\x08\x57\xa9\x17\x44\xb8\x3d\x4d\x0d\xb0\xce\xf2\ \x18\x74\xc6\x6d\x65\x10\xca\xab\x39\xb8\xa2\x25\xcb\xb4\x6e\x0b\ \xbc\x86\x28\xd5\x37\xa1\x7e\xe0\x28\x14\x5b\x39\xdf\x06\x12\xbf\ \x01\x98\x45\x31\x60\x3a\xc2\x55\x1a\x9c\xd4\x2f\x85\x75\x6b\x40\ \xa0\x63\xec\x96\x17\x98\x07\xd0\x2b\x68\x84\xda\xda\xb9\x4e\x85\ \x4a\x8a\xcb\x88\x4c\x2f\x12\x33\x57\x0c\x22\xe2\x5d\x6a\xfc\x5b\ \x94\x40\xf7\x9a\x8e\xc4\xbd\x4b\x2d\x2f\x98\x97\xd6\x30\x76\xcf\ \xa7\xc3\xf0\x22\xba\x81\x78\xbd\x76\x03\x55\x53\xda\xe5\xb5\x18\ \xdf\x37\x1c\x86\xfc\x94\x63\xe4\x8d\x40\xab\x12\xa3\x3a\xd7\x41\ \x19\x66\x99\x8b\x11\x77\x74\xa7\xab\xca\x78\x00\xcf\xc9\x2a\x71\ \xa0\x52\xd6\x72\x6b\xb5\xd4\x0c\x7d\x1c\x4d\xa7\x01\x2d\x6d\x2f\ \xb3\x73\x8c\x55\xc5\x6a\xa4\x60\x9b\xdb\x63\x7c\x6c\x3d\x76\x35\ \xde\x28\x58\x85\x99\x06\xbe\x47\x93\xdf\x71\x03\x74\xa4\xed\x6c\ \x70\xe4\xa6\xe7\xa7\x78\x86\x8d\x27\x36\xfc\xa6\x93\x72\x71\x89\ \xdd\xa2\x82\xa4\x88\xb7\xa5\xca\x98\x72\xd3\xbb\x84\xa6\x8d\xef\ \x93\xce\xf6\x56\x09\x79\x14\xf0\xee\xe2\xed\xf8\xdd\x69\x15\x09\ \xc5\x37\x54\x02\xd2\x26\xcf\x1c\x29\x2f\x96\x4b\xd7\xbb\xcb\xbb\ \x77\xa2\x58\x86\x35\x3f\x52\xb5\x76\x41\x32\xdf\x2c\x96\x83\x30\ \x0a\x73\xd8\x30\x6f\xe1\x7d\xd2\x52\xcd\x38\x89\x62\xc7\x16\xac\ \x41\x90\x30\xa5\xd4\x80\xad\x07\xc0\x32\xc5\x6d\xc8\xf0\x2b\x81\ \xfb\x10\x80\xfb\x12\xba\xa6\x4d\x6f\xcb\x3e\xe0\x88\xb5\xf1\xd2\ \x4a\xb6\x3e\xb1\x3c\xc7\x2b\xc6\xeb\x44\x81\x15\x4a\x43\x37\x57\ \xae\xef\xb6\xf8\x6b\xc1\x1b\x07\x78\x1f\x89\x5f\xd7\xcd\xef\xf0\ \x14\xf9\x41\x9c\xea\xf3\x61\xb7\xb8\x21\x60\x9c\x6a\x75\x1e\x7f\ \xb4\x5f\x45\xa1\x74\xa4\x9f\xaf\xb5\xe4\x99\x99\x8d\x67\x66\x36\ \x3f\x8f\x47\x0a\xca\xbd\xef\x27\x9e\xea\x5b\xbc\x75\xef\x59\x7d\ \xf9\xba\x86\x78\xb3\xd9\x92\xb7\x39\x70\x0e\x54\x84\x5b\x56\x83\ \xba\x4f\x2b\x8e\x10\x6c\x50\xbe\xbc\x7e\xcc\x2e\x72\xc2\x34\x6a\ \x56\x29\xe6\x3b\x3a\x39\x31\xa7\x02\x1a\x62\x26\x3e\xd5\x03\xee\ \x58\xe3\xa7\x3f\x3c\x1b\x8e\xc1\xb1\x1b\xa3\xe3\x8b\xe1\xf9\xb8\ \xbf\x22\x9f\x71\x1f\x94\x8d\x47\x42\x59\xe1\xd2\x54\xae\xa2\x18\ \xd7\x1e\x44\xb1\x13\xae\x35\x62\xaf\xda\x70\x4d\x2e\x2d\x2f\x69\ \x94\xb0\xdb\x31\x8e\xbe\x9a\x4e\xc0\x24\x49\xc6\x73\x8a\xde\xa0\ \xc9\x97\x64\x6c\x74\x7b\xa3\x79\xc3\x3d\x0d\xd7\x0f\x31\xe2\x01\ \x40\x06\xbf\x01\x94\xbf\x51\xd2\x6e\xee\xe9\x23\xc0\x77\xe6\x86\ \x13\xba\x0f\xfd\x8e\x3e\xb2\x88\x3d\x58\x04\xef\x13\xdd\x75\x60\ \xfd\x57\xda\x79\x62\x09\x63\x7d\x03\x2d\x3f\xc5\x29\xa6\xd4\x64\ \x11\x82\xec\x57\xc5\xed\xbf\xce\x53\xaf\xff\x3d\xe8\x82\x1f\xfc\ \xa8\xbe\xdf\x27\x38\xcd\x39\x52\x42\x4b\x71\x35\x36\x2c\xbc\x95\ \xbd\xf5\xa2\x8c\xc1\xa8\x72\xdb\x4a\x54\x7c\xeb\xb0\x3f\xfe\x63\ \xfc\xe5\xec\x02\x4a\xf2\xa8\x2f\xef\x56\x15\xf4\x8a\xfc\x62\x92\ \xe7\xaf\x71\xe8\xf4\xd9\x2a\x96\x71\x57\x14\xb4\xf3\x29\xcc\x51\ \xdc\x8b\x07\x05\x03\x90\x86\xc5\xef\x41\x21\x9a\x64\x4a\x84\x54\ \x82\xe6\xb3\xf0\xd5\xa9\x9e\x05\x6a\x87\x9e\xac\x67\xed\xe5\x77\ \xa4\x14\xa2\x68\x12\x1a\xf7\xac\x2d\x76\x23\x8d\x59\x9d\x27\x41\ \x8d\x0f\x48\x41\xf8\x3f\x4e\x60\x39\x8b\x17\x3e\x8c\xf7\xd6\x83\ \xa4\xad\x50\x66\xf5\x0d\xb9\x10\x16\x9a\x20\xbf\x87\x91\x2b\x2e\ \xea\xa9\x05\x45\x65\x50\xef\x55\x90\x93\x9f\xc3\xcb\x34\xee\xaa\ \x66\xd2\x70\xb9\xad\x46\x27\xec\x05\x82\xff\x0f\x5b\x8d\x20\xbf\ \xe5\x6f\x28\xac\xb4\x14\xe7\xab\xca\x50\x5b\x3b\xbb\xc2\x54\xdb\ \x2f\xdb\x85\xb1\x24\xd5\x87\x98\x0a\x7b\xa0\xa7\x9b\x4a\xbc\x85\ \xa6\x4b\x5b\x75\xf9\x4f\x4b\x05\x8f\xbd\xeb\x57\x51\x20\xcd\x2a\ \xa8\x31\xbc\x76\x0e\xa8\x13\xfc\x45\x19\xa2\x5d\xf6\xd3\xdb\xf8\ \xaa\xba\x5c\x9a\x56\x9b\x15\xef\x07\x56\x6b\x4d\xed\x1d\xf8\xd7\ \x83\x16\xef\x36\x0e\x5a\xfc\xff\x4d\xf2\x7f\x4d\x7f\x01\x23\ \x00\x00\x04\xcf\ \x3c\ \x21\x44\x4f\x43\x54\x59\x50\x45\x20\x68\x74\x6d\x6c\x3e\x0a\x3c\ \x68\x74\x6d\x6c\x3e\x0a\x3c\x68\x65\x61\x64\x3e\x0a\x3c\x6d\x65\ \x74\x61\x20\x63\x68\x61\x72\x73\x65\x74\x3d\x22\x75\x74\x66\x2d\ \x38\x22\x3e\x20\x0a\x3c\x6d\x65\x74\x61\x20\x68\x74\x74\x70\x2d\ \x65\x71\x75\x69\x76\x3d\x22\x63\x6f\x6e\x74\x65\x6e\x74\x2d\x74\ \x79\x70\x65\x22\x20\x63\x6f\x6e\x74\x65\x6e\x74\x3d\x22\x74\x65\ \x78\x74\x2f\x68\x74\x6d\x6c\x3b\x20\x63\x68\x61\x72\x73\x65\x74\ \x3d\x75\x74\x66\x2d\x38\x22\x3e\x0a\x3c\x74\x69\x74\x6c\x65\x3e\ \x40\x54\x49\x54\x4c\x45\x40\x3c\x2f\x74\x69\x74\x6c\x65\x3e\x0a\ \x3c\x6c\x69\x6e\x6b\x20\x72\x65\x6c\x3d\x22\x69\x63\x6f\x6e\x22\ \x20\x68\x72\x65\x66\x3d\x22\x64\x61\x74\x61\x3a\x69\x6d\x61\x67\ \x65\x2f\x70\x6e\x67\x3b\x62\x61\x73\x65\x36\x34\x2c\x40\x46\x41\ \x56\x49\x43\x4f\x4e\x40\x22\x20\x74\x79\x70\x65\x3d\x22\x69\x6d\ \x61\x67\x65\x2f\x78\x2d\x69\x63\x6f\x6e\x22\x20\x2f\x3e\x0a\x3c\ \x73\x74\x79\x6c\x65\x3e\x0a\x62\x6f\x64\x79\x20\x7b\x0a\x20\x20\ \x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x33\x65\x6d\x20\x30\x65\x6d\ \x3b\x0a\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\ \x2d\x77\x65\x62\x6b\x69\x74\x2d\x67\x72\x61\x64\x69\x65\x6e\x74\ \x28\x6c\x69\x6e\x65\x61\x72\x2c\x20\x6c\x65\x66\x74\x20\x74\x6f\ \x70\x2c\x20\x6c\x65\x66\x74\x20\x62\x6f\x74\x74\x6f\x6d\x2c\x20\ \x66\x72\x6f\x6d\x28\x23\x38\x35\x37\x38\x34\x41\x29\x2c\x20\x74\ \x6f\x28\x23\x46\x44\x46\x44\x46\x44\x29\x2c\x20\x63\x6f\x6c\x6f\ \x72\x2d\x73\x74\x6f\x70\x28\x30\x2e\x35\x2c\x20\x23\x46\x44\x46\ \x44\x46\x44\x29\x29\x3b\x0a\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\ \x75\x6e\x64\x2d\x72\x65\x70\x65\x61\x74\x3a\x20\x72\x65\x70\x65\ \x61\x74\x2d\x78\x3b\x0a\x7d\x0a\x69\x6d\x67\x20\x7b\x0a\x20\x20\ \x66\x6c\x6f\x61\x74\x3a\x20\x6c\x65\x66\x74\x3b\x0a\x20\x20\x6f\ \x70\x61\x63\x69\x74\x79\x3a\x20\x2e\x38\x3b\x0a\x7d\x0a\x23\x62\ \x6f\x78\x20\x7b\x0a\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\ \x64\x3a\x20\x77\x68\x69\x74\x65\x3b\x0a\x20\x20\x62\x6f\x72\x64\ \x65\x72\x3a\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x23\x38\ \x35\x37\x38\x34\x41\x3b\x0a\x20\x20\x77\x69\x64\x74\x68\x3a\x20\ \x36\x30\x30\x70\x78\x3b\x0a\x20\x20\x70\x61\x64\x64\x69\x6e\x67\ \x3a\x20\x36\x30\x70\x78\x3b\x0a\x20\x20\x6d\x61\x72\x67\x69\x6e\ \x3a\x20\x61\x75\x74\x6f\x3b\x0a\x20\x20\x62\x6f\x72\x64\x65\x72\ \x2d\x72\x61\x64\x69\x75\x73\x3a\x20\x30\x2e\x38\x65\x6d\x3b\x0a\ \x7d\x0a\x68\x31\x20\x7b\x0a\x20\x20\x66\x6f\x6e\x74\x2d\x73\x69\ \x7a\x65\x3a\x20\x31\x33\x30\x25\x3b\x0a\x20\x20\x66\x6f\x6e\x74\ \x2d\x77\x65\x69\x67\x68\x74\x3a\x20\x62\x6f\x6c\x64\x3b\x0a\x20\ \x20\x62\x6f\x72\x64\x65\x72\x2d\x62\x6f\x74\x74\x6f\x6d\x3a\x20\ \x31\x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x23\x38\x35\x37\x38\x34\ \x41\x3b\x0a\x20\x20\x6d\x61\x72\x67\x69\x6e\x2d\x6c\x65\x66\x74\ \x3a\x20\x36\x34\x70\x78\x3b\x0a\x7d\x0a\x68\x32\x20\x7b\x0a\x20\ \x20\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x20\x31\x30\x30\x25\ \x3b\x0a\x20\x20\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\ \x20\x6e\x6f\x72\x6d\x61\x6c\x3b\x0a\x20\x20\x62\x6f\x72\x64\x65\ \x72\x2d\x62\x6f\x74\x74\x6f\x6d\x3a\x20\x31\x70\x78\x20\x73\x6f\ \x6c\x69\x64\x20\x23\x38\x35\x37\x38\x34\x41\x3b\x0a\x20\x20\x6d\ \x61\x72\x67\x69\x6e\x2d\x6c\x65\x66\x74\x3a\x20\x36\x34\x70\x78\ \x3b\x0a\x7d\x0a\x75\x6c\x20\x7b\x0a\x20\x20\x66\x6f\x6e\x74\x2d\ \x73\x69\x7a\x65\x3a\x20\x31\x30\x30\x25\x3b\x0a\x20\x20\x70\x61\ \x64\x64\x69\x6e\x67\x2d\x6c\x65\x66\x74\x3a\x20\x36\x34\x70\x78\ \x3b\x0a\x20\x20\x6d\x61\x72\x67\x69\x6e\x3a\x20\x35\x70\x78\x20\ \x30\x3b\x0a\x7d\x0a\x3c\x2f\x73\x74\x79\x6c\x65\x3e\x0a\x3c\x2f\ \x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\x0a\x20\x20\x3c\ \x64\x69\x76\x20\x69\x64\x3d\x22\x62\x6f\x78\x22\x3e\x0a\x20\x20\ \x20\x20\x3c\x69\x6d\x67\x20\x73\x72\x63\x3d\x22\x64\x61\x74\x61\ \x3a\x69\x6d\x61\x67\x65\x2f\x70\x6e\x67\x3b\x62\x61\x73\x65\x36\ \x34\x2c\x40\x49\x4d\x41\x47\x45\x40\x22\x20\x77\x69\x64\x74\x68\ \x3d\x22\x34\x38\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x34\x38\ \x22\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x68\x31\x3e\x40\x48\x31\x40\ \x3c\x2f\x68\x31\x3e\x0a\x20\x20\x20\x20\x3c\x68\x32\x3e\x40\x48\ \x32\x40\x3c\x2f\x68\x32\x3e\x0a\x20\x20\x20\x20\x3c\x75\x6c\x3e\ \x0a\x20\x20\x20\x20\x20\x20\x3c\x6c\x69\x3e\x40\x4c\x49\x2d\x31\ \x40\x3c\x2f\x6c\x69\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x6c\x69\ \x3e\x40\x4c\x49\x2d\x32\x40\x3c\x2f\x6c\x69\x3e\x0a\x20\x20\x20\ \x20\x20\x20\x3c\x6c\x69\x3e\x40\x4c\x49\x2d\x33\x40\x3c\x2f\x6c\ \x69\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\x6c\x69\x3e\x40\x4c\x49\ \x2d\x34\x40\x3c\x2f\x6c\x69\x3e\x0a\x20\x20\x20\x20\x20\x20\x3c\ \x69\x6e\x70\x75\x74\x20\x74\x79\x70\x65\x3d\x22\x73\x75\x62\x6d\ \x69\x74\x22\x20\x69\x64\x3d\x22\x72\x65\x6c\x6f\x61\x64\x42\x75\ \x74\x74\x6f\x6e\x22\x20\x76\x61\x6c\x75\x65\x3d\x22\x40\x42\x55\ \x54\x54\x4f\x4e\x40\x22\x20\x6f\x6e\x63\x6c\x69\x63\x6b\x3d\x22\ \x77\x69\x6e\x64\x6f\x77\x2e\x6c\x6f\x63\x61\x74\x69\x6f\x6e\x2e\ \x72\x65\x6c\x6f\x61\x64\x28\x29\x22\x3e\x0a\x20\x20\x20\x20\x3c\ \x2f\x75\x6c\x3e\x0a\x20\x20\x3c\x2f\x64\x69\x76\x3e\x0a\x3c\x2f\ \x62\x6f\x64\x79\x3e\x0a\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\ " qt_resource_name = b"\ \x00\x04\ \x00\x06\xfb\x3c\ \x00\x68\ \x00\x74\x00\x6d\x00\x6c\ \x00\x0e\ \x08\x97\xc9\x7c\ \x00\x73\ \x00\x74\x00\x61\x00\x72\x00\x74\x00\x50\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ \x00\x10\ \x0b\xe9\x1d\x9c\ \x00\x61\ \x00\x64\x00\x62\x00\x6c\x00\x6f\x00\x63\x00\x6b\x00\x50\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ \x00\x12\ \x06\x3e\x39\x5c\ \x00\x73\ \x00\x70\x00\x65\x00\x65\x00\x64\x00\x64\x00\x69\x00\x61\x00\x6c\x00\x50\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x68\x00\x74\x00\x6d\ \x00\x6c\ \x00\x11\ \x01\xd8\x74\x9c\ \x00\x6e\ \x00\x6f\x00\x74\x00\x46\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x50\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ \ " qt_resource_struct = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\ \x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x21\xe6\ \x00\x00\x00\x56\x00\x01\x00\x00\x00\x01\x00\x00\x10\x82\ \x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\x0d\x02\ " def qInitResources(): QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) def qCleanupResources(): QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) qInitResources() eric-6.0.8/eric/Helpviewer/data/icons.qrc0000644000175000017500000000074212060166053017314 0ustar piotrpiotr icons/ericWeb16.png icons/ericWeb32.png icons/adBlockPlus16.png icons/adBlockPlus64.png icons/close.png icons/edit.png icons/loading.gif icons/plus.png icons/reload.png icons/setting.png icons/brokenPage.png icons/box-border-small.png eric-6.0.8/eric/Helpviewer/data/html/0000755000175000017500000000000012407306116016434 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/data/html/startPage.html0000644000175000017500000000637612553751315021277 0ustar piotrpiotr eric-6.0.8/eric/Helpviewer/data/html/notFoundPage.html0000644000175000017500000000231712060166053021715 0ustar piotrpiotr @TITLE@

    @H1@

    @H2@

    • @LI-1@
    • @LI-2@
    • @LI-3@
    • @LI-4@
    eric-6.0.8/eric/Helpviewer/data/html/speeddialPage.html0000644000175000017500000004226312407306116022060 0ustar piotrpiotr @SITE-TITLE@
    eric-6.0.8/eric/Helpviewer/data/html/adblockPage.html0000644000175000017500000000157412060166053021524 0ustar piotrpiotr @TITLE@

    AdBlock Plus

    @MESSAGE@

    eric-6.0.8/eric/Helpviewer/data/javascript/0000755000175000017500000000000012060166053017635 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/HelpTabWidget.py0000644000175000017500000011031712554665654017641 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing the central widget showing the web pages. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QWidget, QHBoxLayout, QMenu, QToolButton, QDialog from PyQt5.QtPrintSupport import QPrinter, QPrintDialog from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest from E5Gui.E5TabWidget import E5TabWidget from E5Gui import E5MessageBox from E5Gui.E5Application import e5App from .HelpBrowserWV import HelpBrowser import UI.PixmapCache import Utilities import Preferences from eric6config import getConfig class HelpTabWidget(E5TabWidget): """ Class implementing the central widget showing the web pages. @signal sourceChanged(HelpBrowser, QUrl) emitted after the URL of a browser has changed @signal titleChanged(HelpBrowser, str) emitted after the title of a browser has changed @signal showMessage(str) emitted to show a message in the main window status bar @signal browserClosed(QWidget) emitted after a browser was closed @signal browserZoomValueChanged(int) emitted to signal a change of the current browser's zoom level """ sourceChanged = pyqtSignal(HelpBrowser, QUrl) titleChanged = pyqtSignal(HelpBrowser, str) showMessage = pyqtSignal(str) browserClosed = pyqtSignal(QWidget) browserZoomValueChanged = pyqtSignal(int) def __init__(self, parent): """ Constructor @param parent reference to the parent widget (QWidget) """ E5TabWidget.__init__(self, parent, dnd=True) from .HelpTabBar import HelpTabBar self.__tabBar = HelpTabBar(self) self.setCustomTabBar(True, self.__tabBar) self.__mainWindow = parent self.setUsesScrollButtons(True) self.setDocumentMode(True) self.setElideMode(Qt.ElideNone) from .ClosedTabsManager import ClosedTabsManager self.__closedTabsManager = ClosedTabsManager(self) self.__closedTabsManager.closedTabAvailable.connect( self.__closedTabAvailable) from .UrlBar.StackedUrlBar import StackedUrlBar self.__stackedUrlBar = StackedUrlBar(self) self.__tabBar.tabMoved.connect(self.__stackedUrlBar.moveBar) self.__tabContextMenuIndex = -1 self.currentChanged[int].connect(self.__currentChanged) self.setTabContextMenuPolicy(Qt.CustomContextMenu) self.customTabContextMenuRequested.connect(self.__showContextMenu) self.__rightCornerWidget = QWidget(self) self.__rightCornerWidgetLayout = QHBoxLayout(self.__rightCornerWidget) self.__rightCornerWidgetLayout.setContentsMargins(0, 0, 0, 0) self.__rightCornerWidgetLayout.setSpacing(0) self.__navigationMenu = QMenu(self) self.__navigationMenu.aboutToShow.connect(self.__showNavigationMenu) self.__navigationMenu.triggered.connect(self.__navigationMenuTriggered) self.__navigationButton = QToolButton(self) self.__navigationButton.setIcon( UI.PixmapCache.getIcon("1downarrow.png")) self.__navigationButton.setToolTip( self.tr("Show a navigation menu")) self.__navigationButton.setPopupMode(QToolButton.InstantPopup) self.__navigationButton.setMenu(self.__navigationMenu) self.__navigationButton.setEnabled(False) self.__rightCornerWidgetLayout.addWidget(self.__navigationButton) self.__closedTabsMenu = QMenu(self) self.__closedTabsMenu.aboutToShow.connect( self.__aboutToShowClosedTabsMenu) self.__closedTabsButton = QToolButton(self) self.__closedTabsButton.setIcon(UI.PixmapCache.getIcon("trash.png")) self.__closedTabsButton.setToolTip( self.tr("Show a navigation menu for closed tabs")) self.__closedTabsButton.setPopupMode(QToolButton.InstantPopup) self.__closedTabsButton.setMenu(self.__closedTabsMenu) self.__closedTabsButton.setEnabled(False) self.__rightCornerWidgetLayout.addWidget(self.__closedTabsButton) self.__closeButton = QToolButton(self) self.__closeButton.setIcon(UI.PixmapCache.getIcon("close.png")) self.__closeButton.setToolTip( self.tr("Close the current help window")) self.__closeButton.setEnabled(False) self.__closeButton.clicked[bool].connect(self.closeBrowser) self.__rightCornerWidgetLayout.addWidget(self.__closeButton) if Preferences.getUI("SingleCloseButton") or \ not hasattr(self, 'setTabsClosable'): self.__closeButton.show() else: self.setTabsClosable(True) self.tabCloseRequested.connect(self.closeBrowserAt) self.__closeButton.hide() self.setCornerWidget(self.__rightCornerWidget, Qt.TopRightCorner) self.__newTabButton = QToolButton(self) self.__newTabButton.setIcon(UI.PixmapCache.getIcon("plus.png")) self.__newTabButton.setToolTip( self.tr("Open a new help window tab")) self.setCornerWidget(self.__newTabButton, Qt.TopLeftCorner) self.__newTabButton.clicked[bool].connect(self.newBrowser) self.__initTabContextMenu() self.__historyCompleter = None def __initTabContextMenu(self): """ Private method to create the tab context menu. """ self.__tabContextMenu = QMenu(self) self.tabContextNewAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("tabNew.png"), self.tr('New Tab'), self.newBrowser) self.__tabContextMenu.addSeparator() self.leftMenuAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("1leftarrow.png"), self.tr('Move Left'), self.__tabContextMenuMoveLeft) self.rightMenuAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("1rightarrow.png"), self.tr('Move Right'), self.__tabContextMenuMoveRight) self.__tabContextMenu.addSeparator() self.tabContextCloneAct = self.__tabContextMenu.addAction( self.tr("Duplicate Page"), self.__tabContextMenuClone) self.__tabContextMenu.addSeparator() self.tabContextCloseAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("tabClose.png"), self.tr('Close'), self.__tabContextMenuClose) self.tabContextCloseOthersAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("tabCloseOther.png"), self.tr("Close Others"), self.__tabContextMenuCloseOthers) self.__tabContextMenu.addAction( self.tr('Close All'), self.closeAllBrowsers) self.__tabContextMenu.addSeparator() self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("printPreview.png"), self.tr('Print Preview'), self.__tabContextMenuPrintPreview) self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("print.png"), self.tr('Print'), self.__tabContextMenuPrint) self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("printPdf.png"), self.tr('Print as PDF'), self.__tabContextMenuPrintPdf) self.__tabContextMenu.addSeparator() self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("reload.png"), self.tr('Reload All'), self.reloadAllBrowsers) self.__tabContextMenu.addSeparator() self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("addBookmark.png"), self.tr('Bookmark All Tabs'), self.__mainWindow.bookmarkAll) self.__tabBackContextMenu = QMenu(self) self.__tabBackContextMenu.addAction( self.tr('Close All'), self.closeAllBrowsers) self.__tabBackContextMenu.addAction( UI.PixmapCache.getIcon("reload.png"), self.tr('Reload All'), self.reloadAllBrowsers) self.__tabBackContextMenu.addAction( UI.PixmapCache.getIcon("addBookmark.png"), self.tr('Bookmark All Tabs'), self.__mainWindow.bookmarkAll) self.__tabBackContextMenu.addSeparator() self.__restoreClosedTabAct = self.__tabBackContextMenu.addAction( UI.PixmapCache.getIcon("trash.png"), self.tr('Restore Closed Tab'), self.restoreClosedTab) self.__restoreClosedTabAct.setEnabled(False) self.__restoreClosedTabAct.setData(0) def __showContextMenu(self, coord, index): """ Private slot to show the tab context menu. @param coord the position of the mouse pointer (QPoint) @param index index of the tab the menu is requested for (integer) """ coord = self.mapToGlobal(coord) if index == -1: self.__tabBackContextMenu.popup(coord) else: self.__tabContextMenuIndex = index self.leftMenuAct.setEnabled(index > 0) self.rightMenuAct.setEnabled(index < self.count() - 1) self.tabContextCloseOthersAct.setEnabled(self.count() > 1) self.__tabContextMenu.popup(coord) def __tabContextMenuMoveLeft(self): """ Private method to move a tab one position to the left. """ self.moveTab(self.__tabContextMenuIndex, self.__tabContextMenuIndex - 1) def __tabContextMenuMoveRight(self): """ Private method to move a tab one position to the right. """ self.moveTab(self.__tabContextMenuIndex, self.__tabContextMenuIndex + 1) def __tabContextMenuClone(self): """ Private method to clone the selected tab. """ idx = self.__tabContextMenuIndex if idx < 0: idx = self.currentIndex() if idx < 0 or idx > self.count(): return req = QNetworkRequest(self.widget(idx).url()) req.setRawHeader(b"X-Eric6-UserLoadAction", b"1") self.newBrowser(None, (req, QNetworkAccessManager.GetOperation, b"")) def __tabContextMenuClose(self): """ Private method to close the selected tab. """ self.closeBrowserAt(self.__tabContextMenuIndex) def __tabContextMenuCloseOthers(self): """ Private slot to close all other tabs. """ index = self.__tabContextMenuIndex for i in list(range(self.count() - 1, index, -1)) + \ list(range(index - 1, -1, -1)): self.closeBrowserAt(i) def __tabContextMenuPrint(self): """ Private method to print the selected tab. """ browser = self.widget(self.__tabContextMenuIndex) self.printBrowser(browser) def __tabContextMenuPrintPdf(self): """ Private method to print the selected tab as PDF. """ browser = self.widget(self.__tabContextMenuIndex) self.printBrowserPdf(browser) def __tabContextMenuPrintPreview(self): """ Private method to show a print preview of the selected tab. """ browser = self.widget(self.__tabContextMenuIndex) self.printPreviewBrowser(browser) def newBrowser(self, link=None, requestData=None, position=-1): """ Public method to create a new web browser tab. @param link link to be shown (string or QUrl) @param requestData tuple containing the request data (QNetworkRequest, QNetworkAccessManager.Operation, QByteArray) @keyparam position position to create the new tab at or -1 to add it to the end (integer) """ if link is None: linkName = "" elif isinstance(link, QUrl): linkName = link.toString() else: linkName = link from .UrlBar.UrlBar import UrlBar urlbar = UrlBar(self.__mainWindow, self) if self.__historyCompleter is None: import Helpviewer.HelpWindow from .History.HistoryCompleter import HistoryCompletionModel, \ HistoryCompleter self.__historyCompletionModel = HistoryCompletionModel(self) self.__historyCompletionModel.setSourceModel( Helpviewer.HelpWindow.HelpWindow.historyManager() .historyFilterModel()) self.__historyCompleter = HistoryCompleter( self.__historyCompletionModel, self) self.__historyCompleter.activated[str].connect(self.__pathSelected) urlbar.setCompleter(self.__historyCompleter) urlbar.returnPressed.connect(self.__lineEditReturnPressed) if position == -1: self.__stackedUrlBar.addWidget(urlbar) else: self.__stackedUrlBar.insertWidget(position, urlbar) browser = HelpBrowser(self.__mainWindow, self) urlbar.setBrowser(browser) browser.sourceChanged.connect(self.__sourceChanged) browser.titleChanged.connect(self.__titleChanged) browser.highlighted.connect(self.showMessage) browser.backwardAvailable.connect( self.__mainWindow.setBackwardAvailable) browser.forwardAvailable.connect(self.__mainWindow.setForwardAvailable) browser.loadStarted.connect(self.__loadStarted) browser.loadFinished.connect(self.__loadFinished) browser.iconChanged.connect(self.__iconChanged) browser.search.connect(self.newBrowser) browser.page().windowCloseRequested.connect( self.__windowCloseRequested) browser.page().printRequested.connect(self.__printRequested) browser.zoomValueChanged.connect(self.browserZoomValueChanged) if position == -1: index = self.addTab(browser, self.tr("...")) else: index = self.insertTab(position, browser, self.tr("...")) self.setCurrentIndex(index) self.__mainWindow.closeAct.setEnabled(True) self.__mainWindow.closeAllAct.setEnabled(True) self.__closeButton.setEnabled(True) self.__navigationButton.setEnabled(True) if not linkName and not requestData: if Preferences.getHelp("StartupBehavior") == 0: linkName = Preferences.getHelp("HomePage") elif Preferences.getHelp("StartupBehavior") == 1: linkName = "eric:speeddial" if linkName: browser.setSource(QUrl(linkName)) if not browser.documentTitle(): self.setTabText(index, self.__elide(linkName, Qt.ElideMiddle)) self.setTabToolTip(index, linkName) else: self.setTabText( index, self.__elide(browser.documentTitle().replace("&", "&&"))) self.setTabToolTip(index, browser.documentTitle()) elif requestData: browser.load(*requestData) def newBrowserAfter(self, browser, link=None, requestData=None): """ Public method to create a new web browser tab after a given one. @param browser reference to the browser to add after (HelpBrowser) @param link link to be shown (string or QUrl) @param requestData tuple containing the request data (QNetworkRequest, QNetworkAccessManager.Operation, QByteArray) """ if browser: position = self.indexOf(browser) + 1 else: position = -1 self.newBrowser(link, requestData, position) def __showNavigationMenu(self): """ Private slot to show the navigation button menu. """ self.__navigationMenu.clear() for index in range(self.count()): act = self.__navigationMenu.addAction( self.tabIcon(index), self.tabText(index)) act.setData(index) def __navigationMenuTriggered(self, act): """ Private slot called to handle the navigation button menu selection. @param act reference to the selected action (QAction) """ index = act.data() if index is not None: self.setCurrentIndex(index) def __windowCloseRequested(self): """ Private slot to handle the windowCloseRequested signal of a browser. """ page = self.sender() if page is None: return browser = page.view() if browser is None: return index = self.indexOf(browser) self.closeBrowserAt(index) def reloadAllBrowsers(self): """ Public slot to reload all browsers. """ for index in range(self.count()): browser = self.widget(index) browser and browser.reload() def closeBrowser(self): """ Public slot called to handle the close action. """ self.closeBrowserAt(self.currentIndex()) def closeAllBrowsers(self): """ Public slot called to handle the close all action. """ for index in range(self.count() - 1, -1, -1): self.closeBrowserAt(index) def closeBrowserAt(self, index): """ Public slot to close a browser based on its index. @param index index of browser to close (integer) """ urlbar = self.__stackedUrlBar.widget(index) self.__stackedUrlBar.removeWidget(urlbar) del urlbar browser = self.widget(index) if browser is None: return self.__closedTabsManager.recordBrowser(browser, index) browser.home() self.removeTab(index) self.browserClosed.emit(browser) del browser if self.count() == 0: self.newBrowser() else: self.currentChanged[int].emit(self.currentIndex()) def currentBrowser(self): """ Public method to get a reference to the current browser. @return reference to the current browser (HelpBrowser) """ return self.currentWidget() def browserAt(self, index): """ Public method to get a reference to the browser with the given index. @param index index of the browser to get (integer) @return reference to the indexed browser (HelpBrowser) """ return self.widget(index) def browsers(self): """ Public method to get a list of references to all browsers. @return list of references to browsers (list of HelpBrowser) """ li = [] for index in range(self.count()): li.append(self.widget(index)) return li @pyqtSlot() def printBrowser(self, browser=None): """ Public slot called to print the displayed page. @param browser reference to the browser to be printed (HelpBrowser) """ if browser is None: browser = self.currentBrowser() self.__printRequested(browser.page().mainFrame()) def __printRequested(self, frame): """ Private slot to handle a print request. @param frame reference to the frame to be printed (QWebFrame) """ printer = QPrinter(mode=QPrinter.HighResolution) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printer.setPageMargins( Preferences.getPrinter("LeftMargin") * 10, Preferences.getPrinter("TopMargin") * 10, Preferences.getPrinter("RightMargin") * 10, Preferences.getPrinter("BottomMargin") * 10, QPrinter.Millimeter ) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) printDialog = QPrintDialog(printer, self) if printDialog.exec_() == QDialog.Accepted: try: frame.print_(printer) except AttributeError: E5MessageBox.critical( self, self.tr("eric6 Web Browser"), self.tr( """

    Printing is not available due to a bug in""" """ PyQt5. Please upgrade.

    """)) return @pyqtSlot() def printBrowserPdf(self, browser=None): """ Public slot called to print the displayed page to PDF. @param browser reference to the browser to be printed (HelpBrowser) """ if browser is None: browser = self.currentBrowser() self.__printPdfRequested(browser.page().mainFrame()) def __printPdfRequested(self, frame): """ Private slot to handle a print to PDF request. @param frame reference to the frame to be printed (QWebFrame) """ printer = QPrinter(mode=QPrinter.HighResolution) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) printer.setOutputFormat(QPrinter.PdfFormat) name = frame.url().path().rsplit('/', 1)[-1] if name: name = name.rsplit('.', 1)[0] name += '.pdf' printer.setOutputFileName(name) printDialog = QPrintDialog(printer, self) if printDialog.exec_() == QDialog.Accepted: try: frame.print_(printer) except AttributeError: E5MessageBox.critical( self, self.tr("eric6 Web Browser"), self.tr( """

    Printing is not available due to a bug in""" """ PyQt5. Please upgrade.

    """)) return @pyqtSlot() def printPreviewBrowser(self, browser=None): """ Public slot called to show a print preview of the displayed file. @param browser reference to the browser to be printed (HelpBrowserWV) """ from PyQt5.QtPrintSupport import QPrintPreviewDialog if browser is None: browser = self.currentBrowser() printer = QPrinter(mode=QPrinter.HighResolution) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printer.setPageMargins( Preferences.getPrinter("LeftMargin") * 10, Preferences.getPrinter("TopMargin") * 10, Preferences.getPrinter("RightMargin") * 10, Preferences.getPrinter("BottomMargin") * 10, QPrinter.Millimeter ) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) self.__printPreviewBrowser = browser preview = QPrintPreviewDialog(printer, self) preview.paintRequested.connect(self.__printPreview) preview.exec_() def __printPreview(self, printer): """ Private slot to generate a print preview. @param printer reference to the printer object (QPrinter) """ try: self.__printPreviewBrowser.print_(printer) except AttributeError: E5MessageBox.critical( self, self.tr("eric6 Web Browser"), self.tr( """

    Printing is not available due to a bug in PyQt5.""" """Please upgrade.

    """)) return def __sourceChanged(self, url): """ Private slot to handle a change of a browsers source. @param url URL of the new site (QUrl) """ browser = self.sender() if browser is not None: self.sourceChanged.emit(browser, url) def __titleChanged(self, title): """ Private slot to handle a change of a browsers title. @param title new title (string) """ browser = self.sender() if browser is not None: index = self.indexOf(browser) if title == "": title = browser.url().toString() self.setTabText(index, self.__elide(title.replace("&", "&&"))) self.setTabToolTip(index, title) self.titleChanged.emit(browser, title) def __elide(self, txt, mode=Qt.ElideRight, length=40): """ Private method to elide some text. @param txt text to be elided (string) @keyparam mode elide mode (Qt.TextElideMode) @keyparam length amount of characters to be used (integer) @return the elided text (string) """ if mode == Qt.ElideNone or len(txt) < length: return txt elif mode == Qt.ElideLeft: return "...{0}".format(txt[-length:]) elif mode == Qt.ElideMiddle: return "{0}...{1}".format(txt[:length // 2], txt[-(length // 2):]) elif mode == Qt.ElideRight: return "{0}...".format(txt[:length]) else: # just in case return txt def preferencesChanged(self): """ Public slot to handle a change of preferences. """ for browser in self.browsers(): browser.preferencesChanged() for urlbar in self.__stackedUrlBar.urlBars(): urlbar.preferencesChanged() if Preferences.getUI("SingleCloseButton") or \ not hasattr(self, 'setTabsClosable'): if hasattr(self, 'setTabsClosable'): self.setTabsClosable(False) try: self.tabCloseRequested.disconnect(self.closeBrowserAt) except TypeError: pass self.__closeButton.show() else: self.setTabsClosable(True) self.tabCloseRequested.connect(self.closeBrowserAt) self.__closeButton.hide() def __loadStarted(self): """ Private method to handle the loadStarted signal. """ browser = self.sender() if browser is not None: index = self.indexOf(browser) anim = self.animationLabel( index, os.path.join(getConfig("ericPixDir"), "loading.gif"), 100) if not anim: loading = QIcon(os.path.join(getConfig("ericPixDir"), "loading.gif")) self.setTabIcon(index, loading) else: self.setTabIcon(index, QIcon()) self.setTabText(index, self.tr("Loading...")) self.setTabToolTip(index, self.tr("Loading...")) self.showMessage.emit(self.tr("Loading...")) self.__mainWindow.setLoadingActions(True) def __loadFinished(self, ok): """ Private method to handle the loadFinished signal. @param ok flag indicating the result (boolean) """ browser = self.sender() if not isinstance(browser, HelpBrowser): return if browser is not None: import Helpviewer.HelpWindow index = self.indexOf(browser) self.resetAnimation(index) self.setTabIcon( index, Helpviewer.HelpWindow.HelpWindow.icon(browser.url())) if ok: self.showMessage.emit(self.tr("Finished loading")) else: self.showMessage.emit(self.tr("Failed to load")) self.__mainWindow.setLoadingActions(False) def __iconChanged(self): """ Private slot to handle the icon change. """ browser = self.sender() if browser is not None: import Helpviewer.HelpWindow self.setTabIcon( self.indexOf(browser), Helpviewer.HelpWindow.HelpWindow.icon(browser.url())) Helpviewer.HelpWindow.HelpWindow.bookmarksManager()\ .iconChanged(browser.url()) def getSourceFileList(self): """ Public method to get a list of all opened source files. @return dictionary with tab id as key and host/namespace as value """ sourceList = {} for i in range(self.count()): browser = self.widget(i) if browser is not None and \ browser.source().isValid(): sourceList[i] = browser.source().host() return sourceList def shallShutDown(self): """ Public method to check, if the application should be shut down. @return flag indicating a shut down (boolean) """ if self.count() > 1 and Preferences.getHelp("WarnOnMultipleClose"): mb = E5MessageBox.E5MessageBox( E5MessageBox.Information, self.tr("Are you sure you want to close the window?"), self.tr("""Are you sure you want to close the window?\n""" """You have %n tab(s) open.""", "", self.count()), modal=True, parent=self) if self.__mainWindow.fromEric: quitButton = mb.addButton( self.tr("&Close"), E5MessageBox.AcceptRole) quitButton.setIcon(UI.PixmapCache.getIcon("close.png")) else: quitButton = mb.addButton( self.tr("&Quit"), E5MessageBox.AcceptRole) quitButton.setIcon(UI.PixmapCache.getIcon("exit.png")) closeTabButton = mb.addButton( self.tr("C&lose Current Tab"), E5MessageBox.AcceptRole) closeTabButton.setIcon(UI.PixmapCache.getIcon("tabClose.png")) mb.addButton(E5MessageBox.Cancel) mb.exec_() if mb.clickedButton() == quitButton: return True else: if mb.clickedButton() == closeTabButton: self.closeBrowser() return False return True def stackedUrlBar(self): """ Public method to get a reference to the stacked url bar. @return reference to the stacked url bar (StackedUrlBar) """ return self.__stackedUrlBar def currentUrlBar(self): """ Public method to get a reference to the current url bar. @return reference to the current url bar (UrlBar) """ return self.__stackedUrlBar.currentWidget() def __lineEditReturnPressed(self): """ Private slot to handle the entering of an URL. """ edit = self.sender() url = self.__guessUrlFromPath(edit.text()) request = QNetworkRequest(url) request.setRawHeader(b"X-Eric6-UserLoadAction", b"1") if e5App().keyboardModifiers() == Qt.AltModifier: self.newBrowser( None, (request, QNetworkAccessManager.GetOperation, b"")) else: self.currentBrowser().setSource( None, (request, QNetworkAccessManager.GetOperation, b"")) self.currentBrowser().setFocus() def __pathSelected(self, path): """ Private slot called when a URL is selected from the completer. @param path path to be shown (string) """ url = self.__guessUrlFromPath(path) self.currentBrowser().setSource(url) def __guessUrlFromPath(self, path): """ Private method to guess an URL given a path string. @param path path string to guess an URL for (string) @return guessed URL (QUrl) """ manager = self.__mainWindow.openSearchManager() path = Utilities.fromNativeSeparators(path) url = manager.convertKeywordSearchToUrl(path) if url.isValid(): return url try: url = QUrl.fromUserInput(path) except AttributeError: url = QUrl(path) if url.scheme() == "about" and \ url.path() == "home": url = QUrl("eric:home") if url.scheme() in ["s", "search"]: url = manager.currentEngine().searchUrl(url.path().strip()) if url.scheme() != "" and \ (url.host() != "" or url.path() != ""): return url urlString = Preferences.getHelp("DefaultScheme") + path.strip() url = QUrl.fromEncoded(urlString.encode("utf-8"), QUrl.TolerantMode) return url def __currentChanged(self, index): """ Private slot to handle an index change. @param index new index (integer) """ self.__stackedUrlBar.setCurrentIndex(index) browser = self.browserAt(index) if browser is not None: if browser.url() == "" and browser.hasFocus(): self.__stackedUrlBar.currentWidget.setFocus() elif browser.url() != "": browser.setFocus() def restoreClosedTab(self): """ Public slot to restore the most recently closed tab. """ if not self.canRestoreClosedTab(): return act = self.sender() tab = self.__closedTabsManager.getClosedTabAt(act.data()) self.newBrowser(tab.url.toString(), position=tab.position) def canRestoreClosedTab(self): """ Public method to check, if closed tabs can be restored. @return flag indicating that closed tabs can be restored (boolean) """ return self.__closedTabsManager.isClosedTabAvailable() def restoreAllClosedTabs(self): """ Public slot to restore all closed tabs. """ if not self.canRestoreClosedTab(): return for tab in self.__closedTabsManager.allClosedTabs(): self.newBrowser(tab.url.toString(), position=tab.position) self.__closedTabsManager.clearList() def clearClosedTabsList(self): """ Public slot to clear the list of closed tabs. """ self.__closedTabsManager.clearList() def __aboutToShowClosedTabsMenu(self): """ Private slot to populate the closed tabs menu. """ fm = self.__closedTabsMenu.fontMetrics() maxWidth = fm.width('m') * 40 self.__closedTabsMenu.clear() index = 0 for tab in self.__closedTabsManager.allClosedTabs(): title = fm.elidedText(tab.title, Qt.ElideRight, maxWidth) self.__closedTabsMenu.addAction( self.__mainWindow.icon(tab.url), title, self.restoreClosedTab).setData(index) index += 1 self.__closedTabsMenu.addSeparator() self.__closedTabsMenu.addAction( self.tr("Restore All Closed Tabs"), self.restoreAllClosedTabs) self.__closedTabsMenu.addAction( self.tr("Clear List"), self.clearClosedTabsList) def closedTabsManager(self): """ Public slot to get a reference to the closed tabs manager. @return reference to the closed tabs manager (ClosedTabsManager) """ return self.__closedTabsManager def __closedTabAvailable(self, avail): """ Private slot to handle changes of the availability of closed tabs. @param avail flag indicating the availability of closed tabs (boolean) """ self.__closedTabsButton.setEnabled(avail) self.__restoreClosedTabAct.setEnabled(avail) eric-6.0.8/eric/Helpviewer/QtHelpFiltersDialog.py0000644000175000017500000002204712451233375021011 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a dialog to manage the QtHelp filters. """ from __future__ import unicode_literals import sqlite3 from PyQt5.QtCore import pyqtSlot, Qt, QItemSelectionModel from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QListWidgetItem, \ QInputDialog, QLineEdit from PyQt5.QtHelp import QHelpEngineCore from E5Gui import E5MessageBox from .Ui_QtHelpFiltersDialog import Ui_QtHelpFiltersDialog class QtHelpFiltersDialog(QDialog, Ui_QtHelpFiltersDialog): """ Class implementing a dialog to manage the QtHelp filters. """ def __init__(self, engine, parent=None): """ Constructor @param engine reference to the help engine (QHelpEngine) @param parent reference to the parent widget (QWidget) """ super(QtHelpFiltersDialog, self).__init__(parent) self.setupUi(self) self.removeButton.setEnabled(False) self.removeAttributeButton.setEnabled(False) self.__engine = engine self.filtersList.clear() self.attributesList.clear() help = QHelpEngineCore(self.__engine.collectionFile()) help.setupData() self.__removedFilters = [] self.__filterMap = {} self.__filterMapBackup = {} self.__removedAttributes = [] for filter in help.customFilters(): atts = help.filterAttributes(filter) self.__filterMapBackup[filter] = atts if filter not in self.__filterMap: self.__filterMap[filter] = atts self.filtersList.addItems(sorted(self.__filterMap.keys())) for attr in help.filterAttributes(): QTreeWidgetItem(self.attributesList, [attr]) self.attributesList.sortItems(0, Qt.AscendingOrder) if self.__filterMap: self.filtersList.setCurrentRow(0) @pyqtSlot(QListWidgetItem, QListWidgetItem) def on_filtersList_currentItemChanged(self, current, previous): """ Private slot to update the attributes depending on the current filter. @param current reference to the current item (QListWidgetitem) @param previous reference to the previous current item (QListWidgetItem) """ checkedList = [] if current is not None: checkedList = self.__filterMap[current.text()] for index in range(0, self.attributesList.topLevelItemCount()): itm = self.attributesList.topLevelItem(index) if itm.text(0) in checkedList: itm.setCheckState(0, Qt.Checked) else: itm.setCheckState(0, Qt.Unchecked) @pyqtSlot() def on_filtersList_itemSelectionChanged(self): """ Private slot handling a change of selected filters. """ self.removeButton.setEnabled( len(self.filtersList.selectedItems()) > 0) @pyqtSlot(QTreeWidgetItem, int) def on_attributesList_itemChanged(self, item, column): """ Private slot to handle a change of an attribute. @param item reference to the changed item (QTreeWidgetItem) @param column column containing the change (integer) """ if self.filtersList.currentItem() is None: return filter = self.filtersList.currentItem().text() if filter not in self.__filterMap: return newAtts = [] for index in range(0, self.attributesList.topLevelItemCount()): itm = self.attributesList.topLevelItem(index) if itm.checkState(0) == Qt.Checked: newAtts.append(itm.text(0)) self.__filterMap[filter] = newAtts @pyqtSlot() def on_attributesList_itemSelectionChanged(self): """ Private slot handling the selection of attributes. """ self.removeAttributeButton.setEnabled( len(self.attributesList.selectedItems()) != 0) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add a new filter. """ filter, ok = QInputDialog.getText( None, self.tr("Add Filter"), self.tr("Filter name:"), QLineEdit.Normal) if not filter: return if filter not in self.__filterMap: self.__filterMap[filter] = [] self.filtersList.addItem(filter) itm = self.filtersList.findItems(filter, Qt.MatchCaseSensitive)[0] self.filtersList.setCurrentItem(itm) @pyqtSlot() def on_removeButton_clicked(self): """ Private slot to remove the selected filters. """ ok = E5MessageBox.yesNo( self, self.tr("Remove Filters"), self.tr( """Do you really want to remove the selected filters """ """from the database?""")) if not ok: return items = self.filtersList.selectedItems() for item in items: itm = self.filtersList.takeItem(self.filtersList.row(item)) if itm is None: continue del self.__filterMap[itm.text()] self.__removedFilters.append(itm.text()) del itm if self.filtersList.count(): self.filtersList.setCurrentRow( 0, QItemSelectionModel.ClearAndSelect) @pyqtSlot() def on_removeAttributeButton_clicked(self): """ Private slot to remove the selected filter attributes. """ ok = E5MessageBox.yesNo( self, self.tr("Remove Attributes"), self.tr( """Do you really want to remove the selected attributes """ """from the database?""")) if not ok: return items = self.attributesList.selectedItems() for item in items: itm = self.attributesList.takeTopLevelItem( self.attributesList.indexOfTopLevelItem(item)) if itm is None: continue attr = itm.text(0) self.__removedAttributes.append(attr) for filter in self.__filterMap: if attr in self.__filterMap[filter]: self.__filterMap[filter].remove(attr) del itm @pyqtSlot() def on_unusedAttributesButton_clicked(self): """ Private slot to select all unused attributes. """ # step 1: determine all used attributes attributes = set() for filter in self.__filterMap: attributes |= set(self.__filterMap[filter]) # step 2: select all unused attribute items self.attributesList.clearSelection() for row in range(self.attributesList.topLevelItemCount()): itm = self.attributesList.topLevelItem(row) if itm.text(0) not in attributes: itm.setSelected(True) def __removeAttributes(self): """ Private method to remove attributes from the Qt Help database. """ try: self.__db = sqlite3.connect(self.__engine.collectionFile()) except sqlite3.DatabaseError: pass # ignore database errors for attr in self.__removedAttributes: self.__db.execute( "DELETE FROM FilterAttributeTable WHERE Name = '{0}'" .format(attr)) self.__db.commit() self.__db.close() @pyqtSlot() def on_buttonBox_accepted(self): """ Private slot to update the database, if the dialog is accepted. """ filtersChanged = False if len(self.__filterMapBackup) != len(self.__filterMap): filtersChanged = True else: for filter in self.__filterMapBackup: if filter not in self.__filterMap: filtersChanged = True else: oldFilterAtts = self.__filterMapBackup[filter] newFilterAtts = self.__filterMap[filter] if len(oldFilterAtts) != len(newFilterAtts): filtersChanged = True else: for attr in oldFilterAtts: if attr not in newFilterAtts: filtersChanged = True break if filtersChanged: break if filtersChanged: for filter in self.__removedFilters: self.__engine.removeCustomFilter(filter) for filter in self.__filterMap: self.__engine.addCustomFilter(filter, self.__filterMap[filter]) if self.__removedAttributes: self.__removeAttributes() if filtersChanged or self.__removedAttributes: self.__engine.setupData() self.accept() eric-6.0.8/eric/Helpviewer/Passwords/0000755000175000017500000000000012557365404016557 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/Passwords/PasswordWriter.py0000644000175000017500000000773212451233375022133 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a class to write login data files. """ from __future__ import unicode_literals from PyQt5.QtCore import QXmlStreamWriter, QIODevice, QFile class PasswordWriter(QXmlStreamWriter): """ Class implementing a writer object to generate login data files. """ def __init__(self): """ Constructor """ super(PasswordWriter, self).__init__() self.setAutoFormatting(True) def write(self, fileNameOrDevice, logins, forms, nevers): """ Public method to write an login data file. @param fileNameOrDevice name of the file to write (string) or device to write to (QIODevice) @param logins dictionary with login data (user name, password) @param forms list of forms data (list of LoginForm) @param nevers list of URLs to never store data for (list of strings) @return flag indicating success (boolean) """ if isinstance(fileNameOrDevice, QIODevice): f = fileNameOrDevice else: f = QFile(fileNameOrDevice) if not f.open(QFile.WriteOnly): return False self.setDevice(f) return self.__write(logins, forms, nevers) def __write(self, logins, forms, nevers): """ Private method to write an login data file. @param logins dictionary with login data (user name, password) @param forms list of forms data (list of LoginForm) @param nevers list of URLs to never store data for (list of strings) @return flag indicating success (boolean) """ self.writeStartDocument() self.writeDTD("") self.writeStartElement("Password") self.writeAttribute("version", "1.0") if logins: self.__writeLogins(logins) if forms: self.__writeForms(forms) if nevers: self.__writeNevers(nevers) self.writeEndDocument() return True def __writeLogins(self, logins): """ Private method to write the login data. @param logins dictionary with login data (user name, password) """ self.writeStartElement("Logins") for key, login in logins.items(): self.writeEmptyElement("Login") self.writeAttribute("key", key) self.writeAttribute("user", login[0]) self.writeAttribute("password", login[1]) self.writeEndElement() def __writeForms(self, forms): """ Private method to write forms data. @param forms list of forms data (list of LoginForm) """ self.writeStartElement("Forms") for key, form in forms.items(): self.writeStartElement("Form") self.writeAttribute("key", key) self.writeAttribute("url", form.url.toString()) self.writeAttribute("name", str(form.name)) self.writeAttribute( "password", "yes" if form.hasAPassword else "no") if form.elements: self.writeStartElement("Elements") for element in form.elements: self.writeEmptyElement("Element") self.writeAttribute("name", element[0]) self.writeAttribute("value", element[1]) self.writeEndElement() self.writeEndElement() self.writeEndElement() def __writeNevers(self, nevers): """ Private method to write the URLs never to store login data for. @param nevers list of URLs to never store data for (list of strings) """ self.writeStartElement("Nevers") for never in nevers: self.writeEmptyElement("Never") self.writeAttribute("url", never) self.writeEndElement() eric-6.0.8/eric/Helpviewer/Passwords/PasswordModel.py0000644000175000017500000001062612451233375021713 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a model for password management. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QModelIndex, QAbstractTableModel class PasswordModel(QAbstractTableModel): """ Class implementing a model for password management. """ def __init__(self, manager, parent=None): """ Constructor @param manager reference to the password manager (PasswordManager) @param parent reference to the parent object (QObject) """ super(PasswordModel, self).__init__(parent) self.__manager = manager manager.changed.connect(self.__passwordsChanged) self.__headers = [ self.tr("Website"), self.tr("Username"), self.tr("Password") ] self.__showPasswords = False def setShowPasswords(self, on): """ Public methods to show passwords. @param on flag indicating if passwords shall be shown (boolean) """ self.__showPasswords = on self.beginResetModel() self.endResetModel() def showPasswords(self): """ Public method to indicate, if passwords shall be shown. @return flag indicating if passwords shall be shown (boolean) """ return self.__showPasswords def __passwordsChanged(self): """ Private slot handling a change of the registered passwords. """ self.beginResetModel() self.endResetModel() def removeRows(self, row, count, parent=QModelIndex()): """ Public method to remove entries from the model. @param row start row (integer) @param count number of rows to remove (integer) @param parent parent index (QModelIndex) @return flag indicating success (boolean) """ if parent.isValid(): return False if count <= 0: return False lastRow = row + count - 1 self.beginRemoveRows(parent, row, lastRow) siteList = self.__manager.allSiteNames() for index in range(row, lastRow + 1): self.__manager.removePassword(siteList[index]) # removeEngine emits changed() #self.endRemoveRows() return True def rowCount(self, parent=QModelIndex()): """ Public method to get the number of rows of the model. @param parent parent index (QModelIndex) @return number of rows (integer) """ if parent.isValid(): return 0 else: return self.__manager.sitesCount() def columnCount(self, parent=QModelIndex()): """ Public method to get the number of columns of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if self.__showPasswords: return 3 else: return 2 def data(self, index, role): """ Public method to get data from the model. @param index index to get data for (QModelIndex) @param role role of the data to retrieve (integer) @return requested data """ if index.row() >= self.__manager.sitesCount() or index.row() < 0: return None site = self.__manager.allSiteNames()[index.row()] siteInfo = self.__manager.siteInfo(site) if siteInfo is None: return None if role == Qt.DisplayRole: if index.column() == 0: return site elif index.column() in [1, 2]: return siteInfo[index.column() - 1] return None def headerData(self, section, orientation, role=Qt.DisplayRole): """ Public method to get the header data. @param section section number (integer) @param orientation header orientation (Qt.Orientation) @param role data role (integer) @return header data """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: try: return self.__headers[section] except IndexError: pass return None eric-6.0.8/eric/Helpviewer/Passwords/LoginForm.py0000644000175000017500000000154112451233375021020 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a data structure for login forms. """ from __future__ import unicode_literals from PyQt5.QtCore import QUrl class LoginForm(object): """ Class implementing a data structure for login forms. """ def __init__(self): """ Constructor """ self.url = QUrl() self.name = "" self.hasAPassword = False self.elements = [] # list of tuples of element name and value (string, string) self.elementTypes = {} # dict of element name as key and type as value def isValid(self): """ Public method to test for validity. @return flag indicating a valid form (boolean) """ return len(self.elements) > 0 eric-6.0.8/eric/Helpviewer/Passwords/__init__.py0000644000175000017500000000024412451233375020662 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Package implementing the password management interface. """ eric-6.0.8/eric/Helpviewer/Passwords/PasswordManager.py0000644000175000017500000005337712554665654022254 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the password manager. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal, QObject, QByteArray, QUrl, \ QCoreApplication, QXmlStreamReader, qVersion from PyQt5.QtWidgets import QApplication from PyQt5.QtNetwork import QNetworkRequest from PyQt5.QtWebKit import QWebSettings from PyQt5.QtWebKitWidgets import QWebPage from E5Gui import E5MessageBox from E5Gui.E5ProgressDialog import E5ProgressDialog from Utilities.AutoSaver import AutoSaver import Utilities import Utilities.crypto import Preferences class PasswordManager(QObject): """ Class implementing the password manager. @signal changed() emitted to indicate a change @signal passwordsSaved() emitted after the passwords were saved """ changed = pyqtSignal() passwordsSaved = pyqtSignal() SEPARATOR = "====================" FORMS = "=====FORMS=====" NEVER = "=====NEVER=====" def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(PasswordManager, self).__init__(parent) self.__logins = {} self.__loginForms = {} self.__never = [] self.__loaded = False self.__saveTimer = AutoSaver(self, self.save) self.changed.connect(self.__saveTimer.changeOccurred) def clear(self): """ Public slot to clear the saved passwords. """ if not self.__loaded: self.__load() self.__logins = {} self.__loginForms = {} self.__never = [] self.__saveTimer.changeOccurred() self.__saveTimer.saveIfNeccessary() self.changed.emit() def getLogin(self, url, realm): """ Public method to get the login credentials. @param url URL to get the credentials for (QUrl) @param realm realm to get the credentials for (string) @return tuple containing the user name (string) and password (string) """ if not self.__loaded: self.__load() key = self.__createKey(url, realm) try: return self.__logins[key][0], Utilities.crypto.pwConvert( self.__logins[key][1], encode=False) except KeyError: return "", "" def setLogin(self, url, realm, username, password): """ Public method to set the login credentials. @param url URL to set the credentials for (QUrl) @param realm realm to set the credentials for (string) @param username username for the login (string) @param password password for the login (string) """ if not self.__loaded: self.__load() key = self.__createKey(url, realm) self.__logins[key] = ( username, Utilities.crypto.pwConvert(password, encode=True) ) self.changed.emit() def __createKey(self, url, realm): """ Private method to create the key string for the login credentials. @param url URL to get the credentials for (QUrl) @param realm realm to get the credentials for (string) @return key string (string) """ authority = url.authority() if authority.startswith("@"): authority = authority[1:] if realm: key = "{0}://{1} ({2})".format( url.scheme(), authority, realm) else: key = "{0}://{1}".format(url.scheme(), authority) return key def getFileName(self): """ Public method to get the file name of the passwords file. @return name of the passwords file (string) """ return os.path.join(Utilities.getConfigDir(), "browser", "logins.xml") def save(self): """ Public slot to save the login entries to disk. """ if not self.__loaded: return from .PasswordWriter import PasswordWriter loginFile = self.getFileName() writer = PasswordWriter() if not writer.write( loginFile, self.__logins, self.__loginForms, self.__never): E5MessageBox.critical( None, self.tr("Saving login data"), self.tr( """

    Login data could not be saved to {0}

    """ ).format(loginFile)) else: self.passwordsSaved.emit() def __load(self): """ Private method to load the saved login credentials. """ loginFile = self.getFileName() if not os.path.exists(loginFile): self.__loadNonXml(os.path.splitext(loginFile)[0]) else: from .PasswordReader import PasswordReader reader = PasswordReader() self.__logins, self.__loginForms, self.__never = \ reader.read(loginFile) if reader.error() != QXmlStreamReader.NoError: E5MessageBox.warning( None, self.tr("Loading login data"), self.tr("""Error when loading login data on""" """ line {0}, column {1}:\n{2}""") .format(reader.lineNumber(), reader.columnNumber(), reader.errorString())) self.__loaded = True def __loadNonXml(self, loginFile): """ Private method to load non-XML password files. This method is to convert from the old, non-XML format to the new XML based format. @param loginFile name of the non-XML password file (string) """ if os.path.exists(loginFile): try: f = open(loginFile, "r", encoding="utf-8") lines = f.read() f.close() except IOError as err: E5MessageBox.critical( None, self.tr("Loading login data"), self.tr("""

    Login data could not be loaded """ """from {0}

    """ """

    Reason: {1}

    """) .format(loginFile, str(err))) return data = [] section = 0 # 0 = login data, 1 = forms data, 2 = never store info for line in lines.splitlines(): if line == self.FORMS: section = 1 continue elif line == self.NEVER: section = 2 continue if section == 0: if line != self.SEPARATOR: data.append(line) else: if len(data) != 3: E5MessageBox.critical( None, self.tr("Loading login data"), self.tr( """

    Login data could not be loaded """ """from {0}

    """ """

    Reason: Wrong input format

    """) .format(loginFile)) return self.__logins[data[0]] = (data[1], data[2]) data = [] elif section == 1: if line != self.SEPARATOR: data.append(line) else: from .LoginForm import LoginForm key = data[0] form = LoginForm() form.url = QUrl(data[1]) form.name = data[2] form.hasAPassword = data[3] == "True" for element in data[4:]: name, value = element.split(" = ", 1) form.elements.append((name, value)) self.__loginForms[key] = form data = [] elif section == 2: self.__never.append(line) os.remove(loginFile) self.__loaded = True # this does the conversion self.save() def reload(self): """ Public method to reload the login data. """ if not self.__loaded: return self.__load() def close(self): """ Public method to close the passwords manager. """ self.__saveTimer.saveIfNeccessary() def removePassword(self, site): """ Public method to remove a password entry. @param site web site name (string) """ if site in self.__logins: del self.__logins[site] if site in self.__loginForms: del self.__loginForms[site] self.changed.emit() def allSiteNames(self): """ Public method to get a list of all site names. @return sorted list of all site names (list of strings) """ if not self.__loaded: self.__load() return sorted(self.__logins.keys()) def sitesCount(self): """ Public method to get the number of available sites. @return number of sites (integer) """ if not self.__loaded: self.__load() return len(self.__logins) def siteInfo(self, site): """ Public method to get a reference to the named site. @param site web site name (string) @return tuple containing the user name (string) and password (string) """ if not self.__loaded: self.__load() if site not in self.__logins: return None return self.__logins[site][0], Utilities.crypto.pwConvert( self.__logins[site][1], encode=False) def post(self, request, data): """ Public method to check, if the data to be sent contains login data. @param request reference to the network request (QNetworkRequest) @param data data to be sent (QByteArray) """ # shall passwords be saved? if not Preferences.getUser("SavePasswords"): return # observe privacy if QWebSettings.globalSettings().testAttribute( QWebSettings.PrivateBrowsingEnabled): return if not self.__loaded: self.__load() # determine the url refererHeader = request.rawHeader(b"Referer") if refererHeader.isEmpty(): return url = QUrl.fromEncoded(refererHeader) url = self.__stripUrl(url) # check that url isn't in __never if url.toString() in self.__never: return # check the request type navType = request.attribute(QNetworkRequest.User + 101) if navType is None: return if navType != QWebPage.NavigationTypeFormSubmitted: return # determine the QWebPage webPage = request.attribute(QNetworkRequest.User + 100) if webPage is None: return # determine the requests content type contentTypeHeader = request.rawHeader(b"Content-Type") if contentTypeHeader.isEmpty(): return multipart = contentTypeHeader.startsWith(b"multipart/form-data") if multipart: boundary = contentTypeHeader.split(" ")[1].split("=")[1] else: boundary = None # find the matching form on the web page form = self.__findForm(webPage, data, boundary=boundary) if not form.isValid(): return form.url = QUrl(url) # check, if the form has a password if not form.hasAPassword: return # prompt, if the form has never be seen key = self.__createKey(url, "") if key not in self.__loginForms: mb = E5MessageBox.E5MessageBox( E5MessageBox.Question, self.tr("Save password"), self.tr( """Would you like to save this password?
    """ """To review passwords you have saved and remove them, """ """use the password management dialog of the Settings""" """ menu."""), modal=True) neverButton = mb.addButton( self.tr("Never for this site"), E5MessageBox.DestructiveRole) noButton = mb.addButton( self.tr("Not now"), E5MessageBox.RejectRole) mb.addButton(E5MessageBox.Yes) mb.exec_() if mb.clickedButton() == neverButton: self.__never.append(url.toString()) return elif mb.clickedButton() == noButton: return # extract user name and password user = "" password = "" for index in range(len(form.elements)): element = form.elements[index] type_ = form.elementTypes[element[0]] if user == "" and \ type_ == "text": user = element[1] elif password == "" and \ type_ == "password": password = element[1] form.elements[index] = (element[0], "--PASSWORD--") if user and password: self.__logins[key] = \ (user, Utilities.crypto.pwConvert(password, encode=True)) self.__loginForms[key] = form self.changed.emit() def __stripUrl(self, url): """ Private method to strip off all unneeded parts of a URL. @param url URL to be stripped (QUrl) @return stripped URL (QUrl) """ cleanUrl = QUrl(url) if qVersion() >= "5.0.0": cleanUrl.setQuery("") else: cleanUrl.setQueryItems([]) cleanUrl.setUserInfo("") authority = cleanUrl.authority() if authority.startswith("@"): authority = authority[1:] cleanUrl = QUrl("{0}://{1}{2}".format( cleanUrl.scheme(), authority, cleanUrl.path())) cleanUrl.setFragment("") return cleanUrl def __findForm(self, webPage, data, boundary=None): """ Private method to find the form used for logging in. @param webPage reference to the web page (QWebPage) @param data data to be sent (QByteArray) @keyparam boundary boundary string (QByteArray) for multipart encoded data, None for urlencoded data @return parsed form (LoginForm) """ from .LoginForm import LoginForm form = LoginForm() if boundary is not None: args = self.__extractMultipartQueryItems(data, boundary) else: if qVersion() >= "5.0.0": from PyQt5.QtCore import QUrlQuery argsUrl = QUrl.fromEncoded( QByteArray(b"foo://bar.com/?" + QUrl.fromPercentEncoding( data.replace(b"+", b"%20")).encode("utf-8"))) encodedArgs = QUrlQuery(argsUrl).queryItems() else: argsUrl = QUrl.fromEncoded( QByteArray(b"foo://bar.com/?" + data.replace(b"+", b"%20")) ) encodedArgs = argsUrl.queryItems() args = set() for arg in encodedArgs: key = arg[0] value = arg[1] args.add((key, value)) # extract the forms from Helpviewer.JavaScriptResources import parseForms_js lst = webPage.mainFrame().evaluateJavaScript(parseForms_js) for map in lst: formHasPasswords = False formName = map["name"] formIndex = map["index"] if isinstance(formIndex, float) and formIndex.is_integer(): formIndex = int(formIndex) elements = map["elements"] formElements = set() formElementTypes = {} deadElements = set() for elementMap in elements: try: name = elementMap["name"] value = elementMap["value"] type_ = elementMap["type"] except KeyError: continue if type_ == "password": formHasPasswords = True t = (name, value) try: if elementMap["autocomplete"] == "off": deadElements.add(t) except KeyError: pass if name: formElements.add(t) formElementTypes[name] = type_ if formElements.intersection(args) == args: form.hasAPassword = formHasPasswords if not formName: form.name = formIndex else: form.name = formName args.difference_update(deadElements) for elt in deadElements: if elt[0] in formElementTypes: del formElementTypes[elt[0]] form.elements = list(args) form.elementTypes = formElementTypes break return form def __extractMultipartQueryItems(self, data, boundary): """ Private method to extract the query items for a post operation. @param data data to be sent (QByteArray) @param boundary boundary string (QByteArray) @return set of name, value pairs (set of tuple of string, string) """ args = set() dataStr = bytes(data).decode() boundaryStr = bytes(boundary).decode() parts = dataStr.split(boundaryStr + "\r\n") for part in parts: if part.startswith("Content-Disposition"): lines = part.split("\r\n") name = lines[0].split("=")[1][1:-1] value = lines[2] args.add((name, value)) return args def fill(self, page): """ Public slot to fill login forms with saved data. @param page reference to the web page (QWebPage) """ if page is None or page.mainFrame() is None: return if not self.__loaded: self.__load() url = page.mainFrame().url() url = self.__stripUrl(url) key = self.__createKey(url, "") if key not in self.__loginForms or \ key not in self.__logins: return form = self.__loginForms[key] if form.url != url: return if form.name == "": formName = "0" else: try: formName = "{0:d}".format(int(form.name)) except ValueError: formName = '"{0}"'.format(form.name) for element in form.elements: name = element[0] value = element[1] disabled = page.mainFrame().evaluateJavaScript( 'document.forms[{0}].elements["{1}"].disabled'.format( formName, name)) if disabled: continue readOnly = page.mainFrame().evaluateJavaScript( 'document.forms[{0}].elements["{1}"].readOnly'.format( formName, name)) if readOnly: continue type_ = page.mainFrame().evaluateJavaScript( 'document.forms[{0}].elements["{1}"].type'.format( formName, name)) if type_ == "" or \ type_ in ["hidden", "reset", "submit"]: continue if type_ == "password": value = Utilities.crypto.pwConvert( self.__logins[key][1], encode=False) setType = type_ == "checkbox" and "checked" or "value" value = value.replace("\\", "\\\\") value = value.replace('"', '\\"') javascript = \ 'document.forms[{0}].elements["{1}"].{2}="{3}";'.format( formName, name, setType, value) page.mainFrame().evaluateJavaScript(javascript) def masterPasswordChanged(self, oldPassword, newPassword): """ Public slot to handle the change of the master password. @param oldPassword current master password (string) @param newPassword new master password (string) """ if not self.__loaded: self.__load() progress = E5ProgressDialog( self.tr("Re-encoding saved passwords..."), None, 0, len(self.__logins), self.tr("%v/%m Passwords"), QApplication.activeModalWidget()) progress.setMinimumDuration(0) progress.setWindowTitle(self.tr("Passwords")) count = 0 for key in self.__logins: progress.setValue(count) QCoreApplication.processEvents() username, hash = self.__logins[key] hash = Utilities.crypto.pwRecode(hash, oldPassword, newPassword) self.__logins[key] = (username, hash) count += 1 progress.setValue(len(self.__logins)) QCoreApplication.processEvents() self.changed.emit() eric-6.0.8/eric/Helpviewer/Passwords/PasswordsDialog.ui0000644000175000017500000001213512060166052022210 0ustar piotrpiotr PasswordsDialog 0 0 500 350 Saved Passwords true Qt::Horizontal 40 20 0 0 0 300 0 Enter search term true QAbstractItemView::SelectRows Qt::ElideMiddle false true Press to remove the selected entries &Remove false Press to remove all entries Remove &All false Qt::Horizontal 208 20 Press to toggle the display of passwords Qt::Horizontal QDialogButtonBox::Close E5ClearableLineEdit QLineEdit
    E5Gui/E5LineEdit.h
    E5TableView QTableView
    E5Gui/E5TableView.h
    searchEdit passwordsTable removeButton removeAllButton passwordsButton buttonBox buttonBox accepted() PasswordsDialog accept() 237 340 157 274 buttonBox rejected() PasswordsDialog reject() 325 340 286 274
    eric-6.0.8/eric/Helpviewer/Passwords/PasswordsDialog.py0000644000175000017500000000672212451233375022237 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a dialog to show all saved logins. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QSortFilterProxyModel from PyQt5.QtGui import QFont, QFontMetrics from PyQt5.QtWidgets import QDialog from E5Gui import E5MessageBox from .Ui_PasswordsDialog import Ui_PasswordsDialog class PasswordsDialog(QDialog, Ui_PasswordsDialog): """ Class implementing a dialog to show all saved logins. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(PasswordsDialog, self).__init__(parent) self.setupUi(self) self.__showPasswordsText = self.tr("Show Passwords") self.__hidePasswordsText = self.tr("Hide Passwords") self.passwordsButton.setText(self.__showPasswordsText) self.removeButton.clicked.connect( self.passwordsTable.removeSelected) self.removeAllButton.clicked.connect(self.passwordsTable.removeAll) import Helpviewer.HelpWindow from .PasswordModel import PasswordModel self.passwordsTable.verticalHeader().hide() self.__passwordModel = PasswordModel( Helpviewer.HelpWindow.HelpWindow.passwordManager(), self) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setSourceModel(self.__passwordModel) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.passwordsTable.setModel(self.__proxyModel) fm = QFontMetrics(QFont()) height = fm.height() + fm.height() // 3 self.passwordsTable.verticalHeader().setDefaultSectionSize(height) self.passwordsTable.verticalHeader().setMinimumSectionSize(-1) self.__calculateHeaderSizes() def __calculateHeaderSizes(self): """ Private method to calculate the section sizes of the horizontal header. """ fm = QFontMetrics(QFont()) for section in range(self.__passwordModel.columnCount()): header = self.passwordsTable.horizontalHeader()\ .sectionSizeHint(section) if section == 0: header = fm.width("averagebiglongsitename") elif section == 1: header = fm.width("averagelongusername") elif section == 2: header = fm.width("averagelongpassword") buffer = fm.width("mm") header += buffer self.passwordsTable.horizontalHeader()\ .resizeSection(section, header) self.passwordsTable.horizontalHeader().setStretchLastSection(True) @pyqtSlot() def on_passwordsButton_clicked(self): """ Private slot to switch the password display mode. """ if self.__passwordModel.showPasswords(): self.__passwordModel.setShowPasswords(False) self.passwordsButton.setText(self.__showPasswordsText) else: res = E5MessageBox.yesNo( self, self.tr("Saved Passwords"), self.tr("""Do you really want to show passwords?""")) if res: self.__passwordModel.setShowPasswords(True) self.passwordsButton.setText(self.__hidePasswordsText) self.__calculateHeaderSizes() eric-6.0.8/eric/Helpviewer/Passwords/PasswordReader.py0000644000175000017500000001342512451233375022055 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a class to read login data files. """ from __future__ import unicode_literals from PyQt5.QtCore import QXmlStreamReader, QIODevice, QFile, \ QCoreApplication, QUrl class PasswordReader(QXmlStreamReader): """ Class implementing a reader object for login data files. """ def __init__(self): """ Constructor """ super(PasswordReader, self).__init__() def read(self, fileNameOrDevice): """ Public method to read a login data file. @param fileNameOrDevice name of the file to read (string) or reference to the device to read (QIODevice) @return tuple containing the logins, forms and never URLs """ self.__logins = {} self.__loginForms = {} self.__never = [] if isinstance(fileNameOrDevice, QIODevice): self.setDevice(fileNameOrDevice) else: f = QFile(fileNameOrDevice) if not f.exists(): return self.__logins, self.__loginForms, self.__never f.open(QFile.ReadOnly) self.setDevice(f) while not self.atEnd(): self.readNext() if self.isStartElement(): version = self.attributes().value("version") if self.name() == "Password" and \ (not version or version == "1.0"): self.__readPasswords() else: self.raiseError(QCoreApplication.translate( "PasswordReader", "The file is not a Passwords version 1.0 file.")) return self.__logins, self.__loginForms, self.__never def __readPasswords(self): """ Private method to read and parse the login data file. """ if not self.isStartElement() and self.name() != "Password": return while not self.atEnd(): self.readNext() if self.isEndElement(): break if self.isStartElement(): if self.name() == "Logins": self.__readLogins() elif self.name() == "Forms": self.__readForms() elif self.name() == "Nevers": self.__readNevers() else: self.__skipUnknownElement() def __readLogins(self): """ Private method to read the login information. """ if not self.isStartElement() and self.name() != "Logins": return while not self.atEnd(): self.readNext() if self.isEndElement(): if self.name() == "Login": continue else: break if self.isStartElement(): if self.name() == "Login": attributes = self.attributes() key = attributes.value("key") user = attributes.value("user") password = attributes.value("password") self.__logins[key] = (user, password) else: self.__skipUnknownElement() def __readForms(self): """ Private method to read the forms information. """ if not self.isStartElement() and self.name() != "Forms": return while not self.atEnd(): self.readNext() if self.isStartElement(): if self.name() == "Form": from .LoginForm import LoginForm attributes = self.attributes() key = attributes.value("key") form = LoginForm() form.url = QUrl(attributes.value("url")) form.name = attributes.value("name") form.hasAPassword = attributes.value("password") == "yes" elif self.name() == "Elements": continue elif self.name() == "Element": attributes = self.attributes() name = attributes.value("name") value = attributes.value("value") form.elements.append((name, value)) else: self.__skipUnknownElement() if self.isEndElement(): if self.name() == "Form": self.__loginForms[key] = form continue elif self.name() in ["Elements", "Element"]: continue else: break def __readNevers(self): """ Private method to read the never URLs. """ if not self.isStartElement() and self.name() != "Nevers": return while not self.atEnd(): self.readNext() if self.isEndElement(): if self.name() == "Never": continue else: break if self.isStartElement(): if self.name() == "Never": self.__never.append(self.attributes().value("url")) else: self.__skipUnknownElement() def __skipUnknownElement(self): """ Private method to skip over all unknown elements. """ if not self.isStartElement(): return while not self.atEnd(): self.readNext() if self.isEndElement(): break if self.isStartElement(): self.__skipUnknownElement() eric-6.0.8/eric/Helpviewer/CookieJar/0000755000175000017500000000000012557365404016440 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/CookieJar/CookieExceptionsModel.py0000644000175000017500000001743312451233375023250 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the cookie exceptions model. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QAbstractTableModel, QSize, QModelIndex from PyQt5.QtGui import QFont, QFontMetrics class CookieExceptionsModel(QAbstractTableModel): """ Class implementing the cookie exceptions model. """ def __init__(self, cookieJar, parent=None): """ Constructor @param cookieJar reference to the cookie jar (CookieJar) @param parent reference to the parent object (QObject) """ super(CookieExceptionsModel, self).__init__(parent) self.__cookieJar = cookieJar self.__allowedCookies = self.__cookieJar.allowedCookies() self.__blockedCookies = self.__cookieJar.blockedCookies() self.__sessionCookies = self.__cookieJar.allowForSessionCookies() self.__headers = [ self.tr("Website"), self.tr("Status"), ] def headerData(self, section, orientation, role): """ Public method to get header data from the model. @param section section number (integer) @param orientation orientation (Qt.Orientation) @param role role of the data to retrieve (integer) @return requested data """ if role == Qt.SizeHintRole: fm = QFontMetrics(QFont()) height = fm.height() + fm.height() // 3 width = \ fm.width(self.headerData(section, orientation, Qt.DisplayRole)) return QSize(width, height) if orientation == Qt.Horizontal and role == Qt.DisplayRole: try: return self.__headers[section] except IndexError: return None return QAbstractTableModel.headerData(self, section, orientation, role) def data(self, index, role): """ Public method to get data from the model. @param index index to get data for (QModelIndex) @param role role of the data to retrieve (integer) @return requested data """ if index.row() < 0 or index.row() >= self.rowCount(): return None if role in (Qt.DisplayRole, Qt.EditRole): row = index.row() if row < len(self.__allowedCookies): if index.column() == 0: return self.__allowedCookies[row] elif index.column() == 1: return self.tr("Allow") else: return None row -= len(self.__allowedCookies) if row < len(self.__blockedCookies): if index.column() == 0: return self.__blockedCookies[row] elif index.column() == 1: return self.tr("Block") else: return None row -= len(self.__blockedCookies) if row < len(self.__sessionCookies): if index.column() == 0: return self.__sessionCookies[row] elif index.column() == 1: return self.tr("Allow For Session") else: return None return None return None def columnCount(self, parent=QModelIndex()): """ Public method to get the number of columns of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.isValid(): return 0 else: return len(self.__headers) def rowCount(self, parent=QModelIndex()): """ Public method to get the number of rows of the model. @param parent parent index (QModelIndex) @return number of rows (integer) """ if parent.isValid() or self.__cookieJar is None: return 0 else: return len(self.__allowedCookies) + \ len(self.__blockedCookies) + \ len(self.__sessionCookies) def removeRows(self, row, count, parent=QModelIndex()): """ Public method to remove entries from the model. @param row start row (integer) @param count number of rows to remove (integer) @param parent parent index (QModelIndex) @return flag indicating success (boolean) """ if parent.isValid() or self.__cookieJar is None: return False lastRow = row + count - 1 self.beginRemoveRows(parent, row, lastRow) for i in range(lastRow, row - 1, -1): rowToRemove = i if rowToRemove < len(self.__allowedCookies): del self.__allowedCookies[rowToRemove] continue rowToRemove -= len(self.__allowedCookies) if rowToRemove < len(self.__blockedCookies): del self.__blockedCookies[rowToRemove] continue rowToRemove -= len(self.__blockedCookies) if rowToRemove < len(self.__sessionCookies): del self.__sessionCookies[rowToRemove] continue self.__cookieJar.setAllowedCookies(self.__allowedCookies) self.__cookieJar.setBlockedCookies(self.__blockedCookies) self.__cookieJar.setAllowForSessionCookies(self.__sessionCookies) self.endRemoveRows() return True def addRule(self, host, rule): """ Public method to add an exception rule. @param host name of the host to add a rule for (string) @param rule type of rule to add (CookieJar.Allow, CookieJar.Block or CookieJar.AllowForSession) """ if not host: return from .CookieJar import CookieJar if rule == CookieJar.Allow: self.__addHost( host, self.__allowedCookies, self.__blockedCookies, self.__sessionCookies) return elif rule == CookieJar.Block: self.__addHost( host, self.__blockedCookies, self.__allowedCookies, self.__sessionCookies) return elif rule == CookieJar.AllowForSession: self.__addHost( host, self.__sessionCookies, self.__allowedCookies, self.__blockedCookies) return def __addHost(self, host, addList, removeList1, removeList2): """ Private method to add a host to an exception list. @param host name of the host to add (string) @param addList reference to the list to add it to (list of strings) @param removeList1 reference to first list to remove it from (list of strings) @param removeList2 reference to second list to remove it from (list of strings) """ if host not in addList: addList.append(host) if host in removeList1: removeList1.remove(host) if host in removeList2: removeList2.remove(host) # Avoid to have similar rules (with or without leading dot) # e.g. python-projects.org and .python-projects.org if host.startswith("."): otherRule = host[1:] else: otherRule = '.' + host if otherRule in addList: addList.removeOne(otherRule) if otherRule in removeList1: removeList1.remove(otherRule) if otherRule in removeList2: removeList2.remove(otherRule) self.beginResetModel() self.endResetModel() eric-6.0.8/eric/Helpviewer/CookieJar/CookieJar.py0000644000175000017500000003774112554466637020703 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a QNetworkCookieJar subclass with various accept policies. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal, QByteArray, QDataStream, QIODevice, \ QSettings, QDateTime from PyQt5.QtNetwork import QNetworkCookieJar, QNetworkCookie from PyQt5.QtWebKit import QWebSettings from Utilities.AutoSaver import AutoSaver import Utilities import Preferences class CookieJar(QNetworkCookieJar): """ Class implementing a QNetworkCookieJar subclass with various accept policies. @signal cookiesChanged() emitted after the cookies have been changed """ cookiesChanged = pyqtSignal() JAR_VERSION = 23 AcceptAlways = 0 AcceptNever = 1 AcceptOnlyFromSitesNavigatedTo = 2 KeepUntilExpire = 0 KeepUntilExit = 1 KeepUntilTimeLimit = 2 Allow = 0 Block = 1 AllowForSession = 2 def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(CookieJar, self).__init__(parent) self.__loaded = False self.__acceptCookies = self.AcceptOnlyFromSitesNavigatedTo self.__saveTimer = AutoSaver(self, self.save) self.__cookiesFile = os.path.join(Utilities.getConfigDir(), "browser", "cookies.ini") def saveCookies(self, cookiesList): """ Public method to save the cookies. @param cookiesList list of cookies to be saved @return saved cookies as a byte array (QByteArray) """ data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) stream.writeUInt16(self.JAR_VERSION) stream.writeUInt32(len(cookiesList)) for cookie in cookiesList: stream << cookie.toRawForm() return data def loadCookies(self, cookies): """ Public method to restore the saved cookies. @param cookies byte array containing the saved cookies (QByteArray) @return list of cookies """ if cookies.isEmpty(): return [] cookiesList = [] data = QByteArray(cookies) stream = QDataStream(data, QIODevice.ReadOnly) stream.setVersion(QDataStream.Qt_4_6) version = stream.readUInt16() if version != self.JAR_VERSION: return [] stream.readUInt32() # number of cookies rawCookie = QByteArray() while not stream.atEnd(): stream >> rawCookie newCookies = QNetworkCookie.parseCookies(rawCookie) for newCookie in newCookies: cookiesList.append(newCookie) return cookiesList def close(self): """ Public slot to close the cookie jar. """ if self.__loaded and self.__keepCookies == self.KeepUntilExit: self.clear() self.__saveTimer.saveIfNeccessary() def clear(self): """ Public method to clear all cookies. """ if not self.__loaded: self.load() self.setAllCookies([]) self.__saveTimer.changeOccurred() self.cookiesChanged.emit() def load(self): """ Public method to load the cookies. """ if self.__loaded: return cookieSettings = QSettings(self.__cookiesFile, QSettings.IniFormat) # load cookies cookies = cookieSettings.value("Cookies") if cookies: cookiesList = self.loadCookies(cookies) else: cookiesList = [] self.setAllCookies(cookiesList) # load exceptions self.__exceptionsBlock = Preferences.toList( cookieSettings.value("Exceptions/block")) self.__exceptionsAllow = Preferences.toList( cookieSettings.value("Exceptions/allow")) self.__exceptionsAllowForSession = Preferences.toList( cookieSettings.value("Exceptions/allowForSession")) self.__exceptionsBlock.sort() self.__exceptionsAllow.sort() self.__exceptionsAllowForSession.sort() self.__acceptCookies = Preferences.getHelp("AcceptCookies") self.__keepCookies = Preferences.getHelp("KeepCookiesUntil") if self.__keepCookies == self.KeepUntilExit: self.setAllCookies([]) self.__filterTrackingCookies = Preferences.toBool( Preferences.getHelp("FilterTrackingCookies")) self.__loaded = True self.cookiesChanged.emit() def save(self): """ Public method to save the cookies. """ if not self.__loaded: return self.__purgeOldCookies() cookieSettings = QSettings(self.__cookiesFile, QSettings.IniFormat) cookiesList = self.allCookies() for index in range(len(cookiesList) - 1, -1, -1): if cookiesList[index].isSessionCookie(): del cookiesList[index] cookies = self.saveCookies(cookiesList) cookieSettings.setValue("Cookies", cookies) cookieSettings.setValue("Exceptions/block", self.__exceptionsBlock) cookieSettings.setValue("Exceptions/allow", self.__exceptionsAllow) cookieSettings.setValue("Exceptions/allowForSession", self.__exceptionsAllowForSession) Preferences.setHelp("AcceptCookies", self.__acceptCookies) Preferences.setHelp("KeepCookiesUntil", self.__keepCookies) Preferences.setHelp("FilterTrackingCookies", self.__filterTrackingCookies) def __purgeOldCookies(self): """ Private method to purge old cookies. """ cookies = self.allCookies() if len(cookies) == 0: return oldCount = len(cookies) now = QDateTime.currentDateTime() for index in range(len(cookies) - 1, -1, -1): if not cookies[index].isSessionCookie() and \ cookies[index].expirationDate() < now: del cookies[index] if oldCount == len(cookies): return self.setAllCookies(cookies) self.cookiesChanged.emit() def cookiesForUrl(self, url): """ Public method to get the cookies for a URL. @param url URL to get cookies for (QUrl) @return list of cookies (list of QNetworkCookie) """ if not self.__loaded: self.load() globalSettings = QWebSettings.globalSettings() if globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled): return [] return QNetworkCookieJar.cookiesForUrl(self, url) def setCookiesFromUrl(self, cookieList, url): """ Public method to set cookies for a URL. @param cookieList list of cookies to set (list of QNetworkCookie) @param url url to set cookies for (QUrl) @return flag indicating cookies were set (boolean) """ if not self.__loaded: self.load() globalSettings = QWebSettings.globalSettings() if globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled): return False host = url.host() eBlock = self.__isOnDomainList(self.__exceptionsBlock, host) eAllow = not eBlock and \ self.__isOnDomainList(self.__exceptionsAllow, host) eAllowSession = not eBlock and \ not eAllow and \ self.__isOnDomainList( self.__exceptionsAllowForSession, host) addedCookies = False acceptInitially = self.__acceptCookies != self.AcceptNever if (acceptInitially and not eBlock) or \ (not acceptInitially and (eAllow or eAllowSession)): # url domain == cookie domain soon = QDateTime.currentDateTime() soon = soon.addDays(90) for cookie in cookieList: lst = [] if not (self.__filterTrackingCookies and cookie.name().startsWith(b"__utm")): if eAllowSession: cookie.setExpirationDate(QDateTime()) if self.__keepCookies == self.KeepUntilTimeLimit and \ not cookie.isSessionCookie and \ cookie.expirationDate() > soon: cookie.setExpirationDate(soon) lst.append(cookie) if QNetworkCookieJar.setCookiesFromUrl(self, lst, url): addedCookies = True elif self.__acceptCookies == self.AcceptAlways: # force it in if wanted cookies = self.allCookies() for ocookie in cookies[:]: # does the cookie exist already? if cookie.name() == ocookie.name() and \ cookie.domain() == ocookie.domain() and \ cookie.path() == ocookie.path(): # found a match cookies.remove(ocookie) cookies.append(cookie) self.setAllCookies(cookies) addedCookies = True if addedCookies: self.__saveTimer.changeOccurred() self.cookiesChanged.emit() return addedCookies def acceptPolicy(self): """ Public method to get the accept policy. @return current accept policy """ if not self.__loaded: self.load() return self.__acceptCookies def setAcceptPolicy(self, policy): """ Public method to set the accept policy. @param policy accept policy to be set """ if not self.__loaded: self.load() if policy > self.AcceptOnlyFromSitesNavigatedTo: return if policy == self.__acceptCookies: return self.__acceptCookies = policy self.__saveTimer.changeOccurred() def keepPolicy(self): """ Public method to get the keep policy. @return keep policy """ if not self.__loaded: self.load() return self.__keepCookies def setKeepPolicy(self, policy): """ Public method to set the keep policy. @param policy keep policy to be set """ if not self.__loaded: self.load() if policy > self.KeepUntilTimeLimit: return if policy == self.__keepCookies: return self.__keepCookies = policy self.__saveTimer.changeOccurred() def blockedCookies(self): """ Public method to return the blocked cookies. @return list of blocked cookies (list of strings) """ if not self.__loaded: self.load() return self.__exceptionsBlock def allowedCookies(self): """ Public method to return the allowed cookies. @return list of allowed cookies (list of strings) """ if not self.__loaded: self.load() return self.__exceptionsAllow def allowForSessionCookies(self): """ Public method to return the allowed session cookies. @return list of allowed session cookies (list of strings) """ if not self.__loaded: self.load() return self.__exceptionsAllowForSession def setBlockedCookies(self, list_): """ Public method to set the list of blocked cookies. @param list_ list of blocked cookies (list of strings) """ if not self.__loaded: self.load() self.__exceptionsBlock = list_[:] self.__exceptionsBlock.sort() self.__applyRules() self.__saveTimer.changeOccurred() def setAllowedCookies(self, list_): """ Public method to set the list of allowed cookies. @param list_ list of allowed cookies (list of strings) """ if not self.__loaded: self.load() self.__exceptionsAllow = list_[:] self.__exceptionsAllow.sort() self.__applyRules() self.__saveTimer.changeOccurred() def setAllowForSessionCookies(self, list_): """ Public method to set the list of allowed session cookies. @param list_ list of allowed session cookies (list of strings) """ if not self.__loaded: self.load() self.__exceptionsAllowForSession = list_[:] self.__exceptionsAllowForSession.sort() self.__applyRules() self.__saveTimer.changeOccurred() def filterTrackingCookies(self): """ Public method to get the filter tracking cookies flag. @return filter tracking cookies flag (boolean) """ return self.__filterTrackingCookies def setFilterTrackingCookies(self, filterTrackingCookies): """ Public method to set the filter tracking cookies flag. @param filterTrackingCookies filter tracking cookies flag (boolean) """ self.__filterTrackingCookies = filterTrackingCookies def __isOnDomainList(self, rules, domain): """ Private method to check, if either the rule matches the domain exactly or the domain ends with ".rule". @param rules list of rules (list of strings) @param domain domain name to check (string) @return flag indicating a match (boolean) """ for rule in rules: if rule.startswith("."): if domain.endswith(rule): return True withoutDot = rule[1:] if domain == withoutDot: return True else: domainEnding = domain[-(len(rule) + 1):] if domainEnding and \ domainEnding[0] == "." and \ domain.endswith(rule): return True if rule == domain: return True return False def __applyRules(self): """ Private method to apply the cookie rules. """ cookiesList = self.allCookies() changed = False for index in range(len(cookiesList) - 1, -1, -1): cookie = cookiesList[index] if self.__isOnDomainList(self.__exceptionsBlock, cookie.domain()): del cookiesList[index] changed = True elif self.__isOnDomainList(self.__exceptionsAllowForSession, cookie.domain()): cookie.setExpirationDate(QDateTime()) changed = True if changed: self.setAllCookies(cookiesList) self.__saveTimer.changeOccurred() self.cookiesChanged.emit() def cookies(self): """ Public method to get the cookies of the cookie jar. @return list of all cookies (list of QNetworkCookie) """ if not self.__loaded: self.load() return self.allCookies() def setCookies(self, cookies): """ Public method to set all cookies. @param cookies list of cookies to be set (list of QNetworkCookie) """ if not self.__loaded: self.load() self.setAllCookies(cookies) self.__saveTimer.changeOccurred() self.cookiesChanged.emit() eric-6.0.8/eric/Helpviewer/CookieJar/CookiesExceptionsDialog.py0000644000175000017500000000777212451233375023577 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a dialog for the configuration of cookie exceptions. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, QSortFilterProxyModel from PyQt5.QtGui import QFont, QFontMetrics from PyQt5.QtWidgets import QDialog, QCompleter from .CookieExceptionsModel import CookieExceptionsModel from .CookieModel import CookieModel from .Ui_CookiesExceptionsDialog import Ui_CookiesExceptionsDialog class CookiesExceptionsDialog(QDialog, Ui_CookiesExceptionsDialog): """ Class implementing a dialog for the configuration of cookie exceptions. """ def __init__(self, cookieJar, parent=None): """ Constructor @param cookieJar reference to the cookie jar (CookieJar) @param parent reference to the parent widget (QWidget) """ super(CookiesExceptionsDialog, self).__init__(parent) self.setupUi(self) self.__cookieJar = cookieJar self.removeButton.clicked.connect( self.exceptionsTable.removeSelected) self.removeAllButton.clicked.connect( self.exceptionsTable.removeAll) self.exceptionsTable.verticalHeader().hide() self.__exceptionsModel = CookieExceptionsModel(cookieJar) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setSourceModel(self.__exceptionsModel) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.exceptionsTable.setModel(self.__proxyModel) cookieModel = CookieModel(cookieJar, self) self.domainEdit.setCompleter(QCompleter(cookieModel, self.domainEdit)) f = QFont() f.setPointSize(10) fm = QFontMetrics(f) height = fm.height() + fm.height() // 3 self.exceptionsTable.verticalHeader().setDefaultSectionSize(height) self.exceptionsTable.verticalHeader().setMinimumSectionSize(-1) for section in range(self.__exceptionsModel.columnCount()): header = self.exceptionsTable.horizontalHeader()\ .sectionSizeHint(section) if section == 0: header = fm.width("averagebiglonghost.averagedomain.info") elif section == 1: header = fm.width(self.tr("Allow For Session")) buffer = fm.width("mm") header += buffer self.exceptionsTable.horizontalHeader()\ .resizeSection(section, header) def setDomainName(self, domain): """ Public method to set the domain to be displayed. @param domain domain name to be displayed (string) """ self.domainEdit.setText(domain) @pyqtSlot(str) def on_domainEdit_textChanged(self, txt): """ Private slot to handle a change of the domain edit text. @param txt current text of the edit (string) """ enabled = txt != "" self.blockButton.setEnabled(enabled) self.allowButton.setEnabled(enabled) self.allowForSessionButton.setEnabled(enabled) @pyqtSlot() def on_blockButton_clicked(self): """ Private slot to block cookies of a domain. """ from .CookieJar import CookieJar self.__exceptionsModel.addRule(self.domainEdit.text(), CookieJar.Block) @pyqtSlot() def on_allowForSessionButton_clicked(self): """ Private slot to allow cookies of a domain for the current session only. """ from .CookieJar import CookieJar self.__exceptionsModel.addRule(self.domainEdit.text(), CookieJar.AllowForSession) @pyqtSlot() def on_allowButton_clicked(self): """ Private slot to allow cookies of a domain. """ from .CookieJar import CookieJar self.__exceptionsModel.addRule(self.domainEdit.text(), CookieJar.Allow) eric-6.0.8/eric/Helpviewer/CookieJar/CookiesConfigurationDialog.ui0000644000175000017500000001267612310372720024241 0ustar piotrpiotr CookiesConfigurationDialog 0 0 500 152 Configure cookies true <b>Configure cookies</b> QFrame::HLine QFrame::Sunken Qt::Horizontal &Accept Cookies: acceptCombo 0 0 Select the accept policy Always Never Only from sites you navigate to Show a dialog to configure exceptions &Exceptions... &Keep until: keepUntilCombo 0 0 Select the keep policy They expire I exit the application At most 90 days Show a dialog listing all cookies &Show Cookies... Select to filter tracking cookies &Filter Tracking Cookies Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok acceptCombo exceptionsButton keepUntilCombo cookiesButton filterTrackingCookiesCheckbox buttonBox buttonBox accepted() CookiesConfigurationDialog accept() 248 254 157 274 buttonBox rejected() CookiesConfigurationDialog reject() 316 260 286 274 eric-6.0.8/eric/Helpviewer/CookieJar/CookieModel.py0000644000175000017500000001115012451233375021174 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the cookie model. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QAbstractTableModel, QSize, QModelIndex from PyQt5.QtGui import QFont, QFontMetrics class CookieModel(QAbstractTableModel): """ Class implementing the cookie model. """ def __init__(self, cookieJar, parent=None): """ Constructor @param cookieJar reference to the cookie jar (CookieJar) @param parent reference to the parent object (QObject) """ super(CookieModel, self).__init__(parent) self.__headers = [ self.tr("Website"), self.tr("Name"), self.tr("Path"), self.tr("Secure"), self.tr("Expires"), self.tr("Contents"), ] self.__cookieJar = cookieJar self.__cookieJar.cookiesChanged.connect(self.__cookiesChanged) self.__cookieJar.load() def headerData(self, section, orientation, role): """ Public method to get header data from the model. @param section section number (integer) @param orientation orientation (Qt.Orientation) @param role role of the data to retrieve (integer) @return requested data """ if role == Qt.SizeHintRole: fm = QFontMetrics(QFont()) height = fm.height() + fm.height() // 3 width = \ fm.width(self.headerData(section, orientation, Qt.DisplayRole)) return QSize(width, height) if orientation == Qt.Horizontal: if role == Qt.DisplayRole: try: return self.__headers[section] except IndexError: return None return None return QAbstractTableModel.headerData(self, section, orientation, role) def data(self, index, role): """ Public method to get data from the model. @param index index to get data for (QModelIndex) @param role role of the data to retrieve (integer) @return requested data """ lst = [] if self.__cookieJar is not None: lst = self.__cookieJar.cookies() if index.row() < 0 or index.row() >= len(lst): return None if role in (Qt.DisplayRole, Qt.EditRole): cookie = lst[index.row()] col = index.column() if col == 0: return cookie.domain() elif col == 1: return bytes(cookie.name()).decode() elif col == 2: return cookie.path() elif col == 3: return cookie.isSecure() elif col == 4: return cookie.expirationDate() elif col == 5: return cookie.value() else: return None return None def columnCount(self, parent=QModelIndex()): """ Public method to get the number of columns of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.isValid(): return 0 else: return len(self.__headers) def rowCount(self, parent=QModelIndex()): """ Public method to get the number of rows of the model. @param parent parent index (QModelIndex) @return number of columns (integer) """ if parent.isValid() or self.__cookieJar is None: return 0 else: return len(self.__cookieJar.cookies()) def removeRows(self, row, count, parent=QModelIndex()): """ Public method to remove entries from the model. @param row start row (integer) @param count number of rows to remove (integer) @param parent parent index (QModelIndex) @return flag indicating success (boolean) """ if parent.isValid() or self.__cookieJar is None: return False lastRow = row + count - 1 self.beginRemoveRows(parent, row, lastRow) lst = self.__cookieJar.cookies() del lst[row:lastRow + 1] self.__cookieJar.setCookies(lst) self.endRemoveRows() return True def __cookiesChanged(self): """ Private slot handling changes of the cookies list in the cookie jar. """ self.beginResetModel() self.endResetModel() eric-6.0.8/eric/Helpviewer/CookieJar/CookiesDialog.ui0000644000175000017500000001171212060166052021500 0ustar piotrpiotr CookiesDialog 0 0 500 350 Cookies true Qt::Horizontal 40 20 0 300 0 Enter search term for cookies true QAbstractItemView::SelectRows Qt::ElideMiddle false true Press to remove the selected entries &Remove false Press to remove all entries Remove &All false Press to open the cookies exceptions dialog to add a new rule Add R&ule... false Qt::Horizontal 208 20 Qt::Horizontal QDialogButtonBox::Close E5ClearableLineEdit QLineEdit
    E5Gui/E5LineEdit.h
    E5TableView QTableView
    E5Gui/E5TableView.h
    searchEdit cookiesTable removeButton removeAllButton addButton buttonBox buttonBox accepted() CookiesDialog accept() 228 274 157 274 buttonBox rejected() CookiesDialog reject() 316 260 286 274
    eric-6.0.8/eric/Helpviewer/CookieJar/__init__.py0000644000175000017500000000025712451233375020547 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Package implementing a cookie jar and related dialogs with models. """ eric-6.0.8/eric/Helpviewer/CookieJar/CookieDetailsDialog.py0000644000175000017500000000267312537064320022650 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a dialog showing the cookie data. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QDialog from .Ui_CookieDetailsDialog import Ui_CookieDetailsDialog class CookieDetailsDialog(QDialog, Ui_CookieDetailsDialog): """ Class implementing a dialog showing the cookie data. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QWidget) """ super(CookieDetailsDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) def setData(self, domain, name, path, secure, expires, value): """ Public method to set the data to be shown. @param domain domain of the cookie (string) @param name name of the cookie (string) @param path path of the cookie (string) @param secure flag indicating a secure cookie (boolean) @param expires expiration time of the cookie (string) @param value value of the cookie (string) """ self.domainEdit.setText(domain) self.nameEdit.setText(name) self.pathEdit.setText(path) self.secureCheckBox.setChecked(secure) self.expirationEdit.setText(expires) self.valueEdit.setPlainText(value) eric-6.0.8/eric/Helpviewer/CookieJar/CookieDetailsDialog.ui0000644000175000017500000001013012060166052022614 0ustar piotrpiotr CookieDetailsDialog 0 0 400 300 Cookie Details true Domain: true Name: true Path: true Secure: false Expires: true Contents: true Qt::Horizontal QDialogButtonBox::Close domainEdit nameEdit pathEdit secureCheckBox expirationEdit valueEdit buttonBox buttonBox accepted() CookieDetailsDialog accept() 248 254 157 274 buttonBox rejected() CookieDetailsDialog reject() 316 260 286 274 eric-6.0.8/eric/Helpviewer/CookieJar/CookiesDialog.py0000644000175000017500000001206512451233375021524 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a dialog to show all cookies. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QDateTime, QByteArray, \ QSortFilterProxyModel from PyQt5.QtGui import QFont, QFontMetrics from PyQt5.QtWidgets import QDialog from .CookieModel import CookieModel from .Ui_CookiesDialog import Ui_CookiesDialog class CookiesDialog(QDialog, Ui_CookiesDialog): """ Class implementing a dialog to show all cookies. """ def __init__(self, cookieJar, parent=None): """ Constructor @param cookieJar reference to the cookie jar (CookieJar) @param parent reference to the parent widget (QWidget) """ super(CookiesDialog, self).__init__(parent) self.setupUi(self) self.addButton.setEnabled(False) self.__cookieJar = cookieJar self.removeButton.clicked.connect(self.cookiesTable.removeSelected) self.removeAllButton.clicked.connect(self.cookiesTable.removeAll) self.cookiesTable.verticalHeader().hide() model = CookieModel(cookieJar, self) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setSourceModel(model) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.cookiesTable.setModel(self.__proxyModel) self.cookiesTable.doubleClicked.connect(self.__showCookieDetails) self.cookiesTable.selectionModel().selectionChanged.connect( self.__tableSelectionChanged) self.cookiesTable.model().modelReset.connect(self.__tableModelReset) fm = QFontMetrics(QFont()) height = fm.height() + fm.height() // 3 self.cookiesTable.verticalHeader().setDefaultSectionSize(height) self.cookiesTable.verticalHeader().setMinimumSectionSize(-1) for section in range(model.columnCount()): header = self.cookiesTable.horizontalHeader()\ .sectionSizeHint(section) if section == 0: header = fm.width("averagebiglonghost.averagedomain.info") elif section == 1: header = fm.width("_session_id") elif section == 4: header = fm.width( QDateTime.currentDateTime().toString(Qt.LocalDate)) buffer = fm.width("mm") header += buffer self.cookiesTable.horizontalHeader().resizeSection(section, header) self.cookiesTable.horizontalHeader().setStretchLastSection(True) self.cookiesTable.model().sort( self.cookiesTable.horizontalHeader().sortIndicatorSection(), Qt.AscendingOrder) self.__detailsDialog = None def __showCookieDetails(self, index): """ Private slot to show a dialog with the cookie details. @param index index of the entry to show (QModelIndex) """ if not index.isValid(): return cookiesTable = self.sender() if cookiesTable is None: return model = cookiesTable.model() row = index.row() domain = model.data(model.index(row, 0)) name = model.data(model.index(row, 1)) path = model.data(model.index(row, 2)) secure = model.data(model.index(row, 3)) expires = model.data(model.index(row, 4)).toString("yyyy-MM-dd hh:mm") value = bytes( QByteArray.fromPercentEncoding( model.data(model.index(row, 5)))).decode() if self.__detailsDialog is None: from .CookieDetailsDialog import CookieDetailsDialog self.__detailsDialog = CookieDetailsDialog(self) self.__detailsDialog.setData(domain, name, path, secure, expires, value) self.__detailsDialog.show() @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add a new exception. """ selection = self.cookiesTable.selectionModel().selectedRows() if len(selection) == 0: return from .CookiesExceptionsDialog import CookiesExceptionsDialog firstSelected = selection[0] domainSelection = firstSelected.sibling(firstSelected.row(), 0) domain = self.__proxyModel.data(domainSelection, Qt.DisplayRole) dlg = CookiesExceptionsDialog(self.__cookieJar, self) dlg.setDomainName(domain) dlg.exec_() def __tableSelectionChanged(self, selected, deselected): """ Private slot to handle a change of selected items. @param selected selected indexes (QItemSelection) @param deselected deselected indexes (QItemSelection) """ self.addButton.setEnabled(len(selected.indexes()) > 0) def __tableModelReset(self): """ Private slot to handle a reset of the cookies table. """ self.addButton.setEnabled(False) eric-6.0.8/eric/Helpviewer/CookieJar/CookiesExceptionsDialog.ui0000644000175000017500000002014112060166052023536 0ustar piotrpiotr CookiesExceptionsDialog 0 0 500 450 Cookie Exceptions true New Exception &Domain: domainEdit Enter the domain name Qt::Horizontal 81 25 false Press to always reject cookies for the domain &Block false false Press to accept cookies for the domain for the current session Allow For &Session false false Press to always accept cookies for the domain Allo&w false Exceptions Qt::Horizontal 40 20 0 300 0 Enter search term for exceptions true QAbstractItemView::SelectRows Qt::ElideMiddle false true false Press to remove the selected entries &Remove false Press to remove all entries Remove &All false Qt::Horizontal 286 20 Qt::Horizontal QDialogButtonBox::Close E5ClearableLineEdit QLineEdit
    E5Gui/E5LineEdit.h
    E5TableView QTableView
    E5Gui/E5TableView.h
    domainEdit blockButton allowForSessionButton allowButton searchEdit exceptionsTable removeButton removeAllButton buttonBox buttonBox accepted() CookiesExceptionsDialog accept() 227 429 157 274 buttonBox rejected() CookiesExceptionsDialog reject() 295 435 286 274
    eric-6.0.8/eric/Helpviewer/CookieJar/CookiesConfigurationDialog.py0000644000175000017500000000645312451233375024260 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the cookies configuration dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QDialog from .CookieJar import CookieJar from .Ui_CookiesConfigurationDialog import Ui_CookiesConfigurationDialog class CookiesConfigurationDialog(QDialog, Ui_CookiesConfigurationDialog): """ Class implementing the cookies configuration dialog. """ def __init__(self, parent): """ Constructor @param parent reference to the parent object (QWidget) """ super(CookiesConfigurationDialog, self).__init__(parent) self.setupUi(self) self.__mw = parent jar = self.__mw.cookieJar() acceptPolicy = jar.acceptPolicy() if acceptPolicy == CookieJar.AcceptAlways: self.acceptCombo.setCurrentIndex(0) elif acceptPolicy == CookieJar.AcceptNever: self.acceptCombo.setCurrentIndex(1) elif acceptPolicy == CookieJar.AcceptOnlyFromSitesNavigatedTo: self.acceptCombo.setCurrentIndex(2) keepPolicy = jar.keepPolicy() if keepPolicy == CookieJar.KeepUntilExpire: self.keepUntilCombo.setCurrentIndex(0) elif keepPolicy == CookieJar.KeepUntilExit: self.keepUntilCombo.setCurrentIndex(1) elif keepPolicy == CookieJar.KeepUntilTimeLimit: self.keepUntilCombo.setCurrentIndex(2) self.filterTrackingCookiesCheckbox.setChecked( jar.filterTrackingCookies()) msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) def accept(self): """ Public slot to accept the dialog. """ acceptSelection = self.acceptCombo.currentIndex() if acceptSelection == 0: acceptPolicy = CookieJar.AcceptAlways elif acceptSelection == 1: acceptPolicy = CookieJar.AcceptNever elif acceptSelection == 2: acceptPolicy = CookieJar.AcceptOnlyFromSitesNavigatedTo keepSelection = self.keepUntilCombo.currentIndex() if keepSelection == 0: keepPolicy = CookieJar.KeepUntilExpire elif keepSelection == 1: keepPolicy = CookieJar.KeepUntilExit elif keepSelection == 2: keepPolicy = CookieJar.KeepUntilTimeLimit jar = self.__mw.cookieJar() jar.setAcceptPolicy(acceptPolicy) jar.setKeepPolicy(keepPolicy) jar.setFilterTrackingCookies( self.filterTrackingCookiesCheckbox.isChecked()) super(CookiesConfigurationDialog, self).accept() @pyqtSlot() def on_exceptionsButton_clicked(self): """ Private slot to show the cookies exceptions dialog. """ from .CookiesExceptionsDialog import CookiesExceptionsDialog dlg = CookiesExceptionsDialog(self.__mw.cookieJar()) dlg.exec_() @pyqtSlot() def on_cookiesButton_clicked(self): """ Private slot to show the cookies dialog. """ from .CookiesDialog import CookiesDialog dlg = CookiesDialog(self.__mw.cookieJar()) dlg.exec_() eric-6.0.8/eric/Helpviewer/AdBlock/0000755000175000017500000000000012557365404016071 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/AdBlock/AdBlockDialog.py0000644000175000017500000003062012537064320021052 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the AdBlock configuration dialog. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QTimer, QCoreApplication from PyQt5.QtWidgets import QDialog, QMenu, QToolButton from E5Gui import E5MessageBox from .Ui_AdBlockDialog import Ui_AdBlockDialog import UI.PixmapCache import Preferences class AdBlockDialog(QDialog, Ui_AdBlockDialog): """ Class implementing the AdBlock configuration dialog. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QWidget) """ super(AdBlockDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.iconLabel.setPixmap(UI.PixmapCache.getPixmap("adBlockPlus48.png")) self.updateSpinBox.setValue(Preferences.getHelp("AdBlockUpdatePeriod")) self.searchEdit.setInactiveText(self.tr("Search...")) import Helpviewer.HelpWindow self.__manager = Helpviewer.HelpWindow.HelpWindow.adBlockManager() self.adBlockGroup.setChecked(self.__manager.isEnabled()) self.__manager.requiredSubscriptionLoaded.connect(self.addSubscription) self.__currentTreeWidget = None self.__currentSubscription = None self.__loaded = False menu = QMenu(self) menu.aboutToShow.connect(self.__aboutToShowActionMenu) self.actionButton.setMenu(menu) self.actionButton.setIcon(UI.PixmapCache.getIcon("adBlockAction.png")) self.actionButton.setPopupMode(QToolButton.InstantPopup) self.__load() self.buttonBox.setFocus() def __loadSubscriptions(self): """ Private slot to load the AdBlock subscription rules. """ for index in range(self.subscriptionsTabWidget.count()): tree = self.subscriptionsTabWidget.widget(index) tree.refresh() def __load(self): """ Private slot to populate the tab widget with subscriptions. """ if self.__loaded or not self.adBlockGroup.isChecked(): return from .AdBlockTreeWidget import AdBlockTreeWidget for subscription in self.__manager.subscriptions(): tree = AdBlockTreeWidget(subscription, self.subscriptionsTabWidget) if subscription.isEnabled(): icon = UI.PixmapCache.getIcon("adBlockPlus.png") else: icon = UI.PixmapCache.getIcon("adBlockPlusDisabled.png") self.subscriptionsTabWidget.addTab( tree, icon, subscription.title()) self.__loaded = True QCoreApplication.processEvents() QTimer.singleShot(50, self.__loadSubscriptions) def addSubscription(self, subscription, refresh=True): """ Public slot adding a subscription to the list. @param subscription reference to the subscription to be added (AdBlockSubscription) @param refresh flag indicating to refresh the tree (boolean) """ from .AdBlockTreeWidget import AdBlockTreeWidget tree = AdBlockTreeWidget(subscription, self.subscriptionsTabWidget) index = self.subscriptionsTabWidget.insertTab( self.subscriptionsTabWidget.count() - 1, tree, subscription.title()) self.subscriptionsTabWidget.setCurrentIndex(index) QCoreApplication.processEvents() if refresh: tree.refresh() self.__setSubscriptionEnabled(subscription, True) def __aboutToShowActionMenu(self): """ Private slot to show the actions menu. """ subscriptionEditable = self.__currentSubscription and \ self.__currentSubscription.canEditRules() subscriptionRemovable = self.__currentSubscription and \ self.__currentSubscription.canBeRemoved() subscriptionEnabled = self.__currentSubscription and \ self.__currentSubscription.isEnabled() menu = self.actionButton.menu() menu.clear() menu.addAction(self.tr("Add Rule"), self.__addCustomRule)\ .setEnabled(subscriptionEditable) menu.addAction(self.tr("Remove Rule"), self.__removeCustomRule)\ .setEnabled(subscriptionEditable) menu.addSeparator() menu.addAction( self.tr("Browse Subscriptions..."), self.__browseSubscriptions) menu.addAction( self.tr("Remove Subscription"), self.__removeSubscription)\ .setEnabled(subscriptionRemovable) if self.__currentSubscription: menu.addSeparator() if subscriptionEnabled: txt = self.tr("Disable Subscription") else: txt = self.tr("Enable Subscription") menu.addAction(txt, self.__switchSubscriptionEnabled) menu.addSeparator() menu.addAction( self.tr("Update Subscription"), self.__updateSubscription)\ .setEnabled(not subscriptionEditable) menu.addAction( self.tr("Update All Subscriptions"), self.__updateAllSubscriptions) menu.addSeparator() menu.addAction(self.tr("Learn more about writing rules..."), self.__learnAboutWritingFilters) def addCustomRule(self, filter): """ Public slot to add a custom AdBlock rule. @param filter filter to be added (string) """ self.subscriptionsTabWidget.setCurrentIndex( self.subscriptionsTabWidget.count() - 1) self.__currentTreeWidget.addRule(filter) def __addCustomRule(self): """ Private slot to add a custom AdBlock rule. """ self.__currentTreeWidget.addRule() def __removeCustomRule(self): """ Private slot to remove a custom AdBlock rule. """ self.__currentTreeWidget.removeRule() def __updateSubscription(self): """ Private slot to update the selected subscription. """ self.__currentSubscription.updateNow() def __updateAllSubscriptions(self): """ Private slot to update all subscriptions. """ self.__manager.updateAllSubscriptions() def __browseSubscriptions(self): """ Private slot to browse the list of available AdBlock subscriptions. """ import Helpviewer.HelpWindow mw = Helpviewer.HelpWindow.HelpWindow.mainWindow() mw.newTab("http://adblockplus.org/en/subscriptions") mw.raise_() def __learnAboutWritingFilters(self): """ Private slot to show the web page about how to write filters. """ import Helpviewer.HelpWindow mw = Helpviewer.HelpWindow.HelpWindow.mainWindow() mw.newTab("http://adblockplus.org/en/filters") mw.raise_() def __removeSubscription(self): """ Private slot to remove the selected subscription. """ requiresTitles = [] requiresSubscriptions = \ self.__manager.getRequiresSubscriptions(self.__currentSubscription) for subscription in requiresSubscriptions: requiresTitles.append(subscription.title()) if requiresTitles: message = self.tr( "

    Do you really want to remove subscription" " {0} and all subscriptions requiring it?

    " "
    • {1}
    ").format( self.__currentSubscription.title(), "
  • ".join(requiresTitles)) else: message = self.tr( "

    Do you really want to remove subscription" " {0}?

    ").format(self.__currentSubscription.title()) res = E5MessageBox.yesNo( self, self.tr("Remove Subscription"), message) if res: removeSubscription = self.__currentSubscription removeTrees = [self.__currentTreeWidget] for index in range(self.subscriptionsTabWidget.count()): tree = self.subscriptionsTabWidget.widget(index) if tree.subscription() in requiresSubscriptions: removeTrees.append(tree) for tree in removeTrees: self.subscriptionsTabWidget.removeTab( self.subscriptionsTabWidget.indexOf(tree)) self.__manager.removeSubscription(removeSubscription) def __switchSubscriptionEnabled(self): """ Private slot to switch the enabled state of the selected subscription. """ newState = not self.__currentSubscription.isEnabled() self.__setSubscriptionEnabled(self.__currentSubscription, newState) def __setSubscriptionEnabled(self, subscription, enable): """ Private slot to set the enabled state of a subscription. @param subscription subscription to set the state for (AdBlockSubscription) @param enable state to set to (boolean) """ if enable: # enable required one as well sub = self.__manager.subscription(subscription.requiresLocation()) requiresSubscriptions = [] if sub is None else [sub] icon = UI.PixmapCache.getIcon("adBlockPlus.png") else: # disable dependent ones as well requiresSubscriptions = \ self.__manager.getRequiresSubscriptions(subscription) icon = UI.PixmapCache.getIcon("adBlockPlusDisabled.png") requiresSubscriptions.append(subscription) for sub in requiresSubscriptions: sub.setEnabled(enable) for index in range(self.subscriptionsTabWidget.count()): tree = self.subscriptionsTabWidget.widget(index) if tree.subscription() in requiresSubscriptions: self.subscriptionsTabWidget.setTabIcon( self.subscriptionsTabWidget.indexOf(tree), icon) @pyqtSlot(int) def on_updateSpinBox_valueChanged(self, value): """ Private slot to handle changes of the update period. @param value update period (integer) """ if value != Preferences.getHelp("AdBlockUpdatePeriod"): Preferences.setHelp("AdBlockUpdatePeriod", value) import Helpviewer.HelpWindow manager = Helpviewer.HelpWindow.HelpWindow.adBlockManager() for subscription in manager.subscriptions(): subscription.checkForUpdate() @pyqtSlot(int) def on_subscriptionsTabWidget_currentChanged(self, index): """ Private slot handling the selection of another tab. @param index index of the new current tab (integer) """ if index != -1: self.__currentTreeWidget = \ self.subscriptionsTabWidget.widget(index) self.__currentSubscription = \ self.__currentTreeWidget.subscription() @pyqtSlot(str) def on_searchEdit_textChanged(self, filter): """ Private slot to set a new filter on the current widget. @param filter filter to be set (string) """ if self.__currentTreeWidget and self.adBlockGroup.isChecked(): self.__currentTreeWidget.filterString(filter) @pyqtSlot(bool) def on_adBlockGroup_toggled(self, state): """ Private slot handling the enabling/disabling of AdBlock. @param state state of the toggle (boolean) """ self.__manager.setEnabled(state) if state: self.__load() def showRule(self, rule): """ Public slot to show the given rule. @param rule rule to be shown (AdBlockRule) """ if rule is None: return subscription = rule.subscription() if subscription is None: return for index in range(self.subscriptionsTabWidget.count()): tree = self.subscriptionsTabWidget.widget(index) if subscription == tree.subscription(): tree.showRule(rule) self.subscriptionsTabWidget.setCurrentIndex(index) self.raise_() break eric-6.0.8/eric/Helpviewer/AdBlock/AdBlockNetwork.py0000644000175000017500000000561012554466447021324 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing the network block class. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject, QUrl from PyQt5.QtNetwork import QNetworkRequest from .AdBlockBlockedNetworkReply import AdBlockBlockedNetworkReply class AdBlockNetwork(QObject): """ Class implementing a network block. """ def block(self, request): """ Public method to check for a network block. @param request reference to the request object (QNetworkRequest) @return reply object (QNetworkReply) or None """ url = request.url() urlString = bytes(url.toEncoded()).decode() urlDomain = url.host() urlScheme = url.scheme() refererHost = QUrl.fromEncoded(request.rawHeader(b"Referer")).host() import Helpviewer.HelpWindow manager = Helpviewer.HelpWindow.HelpWindow.adBlockManager() if not manager.isEnabled() or \ not self.canRunOnScheme(urlScheme) or \ manager.isHostExcepted(urlDomain) or \ manager.isHostExcepted(refererHost): return None for subscription in manager.subscriptions(): if subscription.isEnabled(): blockedRule = subscription.match(request, urlDomain, urlString) if blockedRule: webPage = request.attribute(QNetworkRequest.User + 100) if webPage is not None: if not self.__canBeBlocked(webPage.url()): return None webPage.addAdBlockRule(blockedRule, url) reply = AdBlockBlockedNetworkReply( request, subscription, blockedRule, self) return reply return None def canRunOnScheme(self, scheme): """ Public method to check, if AdBlock can be performed on the scheme. @param scheme scheme to check (string) @return flag indicating, that AdBlock can be performed (boolean) """ return scheme not in ["data", "eric", "qthelp", "qrc", "file", "abp"] def __canBeBlocked(self, url): """ Private method to check, if an URL can be blocked. @param url URL to be checked (QUrl) @return flag indicating, that the URL can be blocked (boolean) """ import Helpviewer.HelpWindow manager = Helpviewer.HelpWindow.HelpWindow.adBlockManager() if manager.isHostExcepted(url.host()): return False for subscription in manager.subscriptions(): if subscription.isEnabled() and \ subscription.adBlockDisabledForUrl(url): return False return True eric-6.0.8/eric/Helpviewer/AdBlock/AdBlockPage.py0000644000175000017500000000565212451233375020541 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a class to apply AdBlock rules to a web page. """ from __future__ import unicode_literals from PyQt5.QtCore import QObject, QUrl class AdBlockPage(QObject): """ Class to apply AdBlock rules to a web page. """ def hideBlockedPageEntries(self, page): """ Public method to apply AdBlock rules to a web page. @param page reference to the web page (HelpWebPage) """ if page is None or page.mainFrame() is None: return import Helpviewer.HelpWindow manager = Helpviewer.HelpWindow.HelpWindow.adBlockManager() if not manager.isEnabled(): return docElement = page.mainFrame().documentElement() for entry in page.getAdBlockedPageEntries(): urlString = entry.urlString() if urlString.endswith((".js", ".css")): continue urlEnd = "" pos = urlString.rfind("/") if pos >= 0: urlEnd = urlString[pos + 1:] if urlString.endswith("/"): urlEnd = urlString[:-1] selector = \ 'img[src$="{0}"], iframe[src$="{0}"], embed[src$="{0}"]'\ .format(urlEnd) elements = docElement.findAll(selector) for element in elements: src = element.attribute("src") src = src.replace("../", "") if src in urlString: element.setStyleProperty("display", "none") # apply domain specific element hiding rules elementHiding = manager.elementHidingRulesForDomain(page.url()) if not elementHiding: return elementHiding += "{display: none !important;}\n" bodyElement = docElement.findFirst("body") bodyElement.appendInside( '

    {2}

    {3} {4}
    """ class FtpReply(QNetworkReply): """ Class implementing a network reply for FTP resources. """ def __init__(self, url, accessHandler, parent=None): """ Constructor @param url requested FTP URL (QUrl) @param accessHandler reference to the access handler (FtpAccessHandler) @param parent reference to the parent object (QObject) """ super(FtpReply, self).__init__(parent) self.__manager = parent self.__handler = accessHandler self.__ftp = E5Ftp() self.__items = [] self.__content = QByteArray() self.__units = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] self.__dirLineParser = FtpDirLineParser() self.__fileBytesReceived = 0 if url.path() == "": url.setPath("/") self.setUrl(url) # do proxy setup if not Preferences.getUI("UseProxy"): proxyType = E5FtpProxyType.NoProxy else: proxyType = Preferences.getUI("ProxyType/Ftp") if proxyType != E5FtpProxyType.NoProxy: self.__ftp.setProxy( proxyType, Preferences.getUI("ProxyHost/Ftp"), Preferences.getUI("ProxyPort/Ftp")) if proxyType != E5FtpProxyType.NonAuthorizing: self.__ftp.setProxyAuthentication( Preferences.getUI("ProxyUser/Ftp"), Preferences.getUI("ProxyPassword/Ftp"), Preferences.getUI("ProxyAccount/Ftp")) QTimer.singleShot(0, self.__doFtpCommands) def abort(self): """ Public slot to abort the operation. """ # do nothing pass def bytesAvailable(self): """ Public method to determined the bytes available for being read. @return bytes available (integer) """ return self.__content.size() def isSequential(self): """ Public method to check for sequential access. @return flag indicating sequential access (boolean) """ return True def readData(self, maxlen): """ Public method to retrieve data from the reply object. @param maxlen maximum number of bytes to read (integer) @return string containing the data (bytes) """ if self.__content.size(): len_ = min(maxlen, self.__content.size()) buffer = bytes(self.__content[:len_]) self.__content.remove(0, len_) return buffer def __doFtpCommands(self): """ Private slot doing the sequence of FTP commands to get the requested result. """ retry = True try: username = self.url().userName() password = self.url().password() byAuth = False while retry: try: self.__ftp.connect(self.url().host(), self.url().port(ftplib.FTP_PORT), timeout=10) except E5FtpProxyError as err: self.setError(QNetworkReply.ProxyNotFoundError, str(err)) self.error.emit(QNetworkReply.ProxyNotFoundError) self.finished.emit() ok, retry = self.__doFtpLogin(username, password, byAuth) if not ok and retry: auth = self.__handler.getAuthenticator(self.url().host()) if auth and not auth.isNull() and auth.user(): username = auth.user() password = auth.password() byAuth = True else: retry = False if ok: self.__ftp.retrlines("LIST " + self.url().path(), self.__dirCallback) if len(self.__items) == 1 and \ self.__items[0].isFile(): self.__fileBytesReceived = 0 self.__setContent() self.__ftp.retrbinary( "RETR " + self.url().path(), self.__retrCallback) self.__content.append(512 * b' ') self.readyRead.emit() else: self.__setListContent() self.__ftp.quit() except ftplib.all_errors as err: if isinstance(err, socket.gaierror): errCode = QNetworkReply.HostNotFoundError elif isinstance(err, socket.error) and \ err.errno == errno.ECONNREFUSED: errCode = QNetworkReply.ConnectionRefusedError else: errCode = QNetworkReply.ProtocolFailure self.setError(errCode, str(err)) self.error.emit(errCode) self.finished.emit() def __doFtpLogin(self, username, password, byAuth=False): """ Private method to do the FTP login with asking for a username and password, if the login fails with an error 530. @param username user name to use for the login (string) @param password password to use for the login (string) @param byAuth flag indicating that the login data was provided by an authenticator (boolean) @return tuple of two flags indicating a successful login and if the login should be retried (boolean, boolean) """ try: self.__ftp.login(username, password) return True, False except E5FtpProxyError as err: code = str(err)[:3] if code[1] == "5": # could be a 530, check second line lines = str(err).splitlines() if lines[1][:3] == "530": if "usage" in "\n".join(lines[1:].lower()): # found a not supported proxy self.setError( QNetworkReply.ProxyConnectionRefusedError, self.tr("The proxy type seems to be wrong." " If it is not in the list of" " supported proxy types please report" " it with the instructions given by" " the proxy.\n{0}").format( "\n".join(lines[1:]))) self.error.emit( QNetworkReply.ProxyConnectionRefusedError) return False, False else: from UI.AuthenticationDialog import \ AuthenticationDialog info = self.tr( "Connect to proxy '{0}' using:")\ .format(Utilities.html_encode( Preferences.getUI("ProxyHost/Ftp"))) dlg = AuthenticationDialog( info, Preferences.getUI("ProxyUser/Ftp"), True) dlg.setData(Preferences.getUI("ProxyUser/Ftp"), Preferences.getUI("ProxyPassword/Ftp")) if dlg.exec_() == QDialog.Accepted: username, password = dlg.getData() if dlg.shallSave(): Preferences.setUI("ProxyUser/Ftp", username) Preferences.setUI( "ProxyPassword/Ftp", password) self.__ftp.setProxyAuthentication(username, password) return False, True return False, False except (ftplib.error_perm, ftplib.error_temp) as err: code = err.args[0].strip()[:3] if code in ["530", "421"]: # error 530 -> Login incorrect # error 421 -> Login may be incorrect (reported by some # proxies) if byAuth: self.__handler.setAuthenticator(self.url().host(), None) auth = None else: auth = self.__handler.getAuthenticator(self.url().host()) if not auth or auth.isNull() or not auth.user(): auth = QAuthenticator() self.__manager.authenticationRequired.emit(self, auth) if not auth.isNull(): if auth.user(): self.__handler.setAuthenticator(self.url().host(), auth) return False, True return False, False return False, True else: raise def __dirCallback(self, line): """ Private slot handling the receipt of directory listings. @param line the received line of the directory listing (string) """ try: urlInfo = self.__dirLineParser.parseLine(line) except FtpDirLineParserError: # silently ignore parser errors urlInfo = None if urlInfo: self.__items.append(urlInfo) QCoreApplication.processEvents() def __retrCallback(self, data): """ Private slot handling the reception of data. @param data data received from the FTP server (bytes) """ self.__content += QByteArray(data) self.__fileBytesReceived += len(data) self.downloadProgress.emit( self.__fileBytesReceived, self.__items[0].size()) self.readyRead.emit() QCoreApplication.processEvents() def __setContent(self): """ Private method to finish the setup of the data. """ mtype, encoding = mimetypes.guess_type(self.url().toString()) self.open(QIODevice.ReadOnly | QIODevice.Unbuffered) self.setHeader(QNetworkRequest.ContentLengthHeader, self.__items[0].size()) if mtype: self.setHeader(QNetworkRequest.ContentTypeHeader, mtype) self.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, 200) self.setAttribute(QNetworkRequest.HttpReasonPhraseAttribute, "Ok") self.metaDataChanged.emit() def __cssLinkClass(self, icon, size=32): """ Private method to generate a link class with an icon. @param icon icon to be included (QIcon) @param size size of the icon to be generated (integer) @return CSS class string (string) """ cssString = \ """a.{{0}} {{{{\n"""\ """ padding-left: {0}px;\n"""\ """ background: transparent url(data:image/png;base64,{1})"""\ """ no-repeat center left;\n"""\ """ font-weight: bold;\n"""\ """}}}}\n""" pixmap = icon.pixmap(size, size) imageBuffer = QBuffer() imageBuffer.open(QIODevice.ReadWrite) if not pixmap.save(imageBuffer, "PNG"): # write a blank pixmap on error pixmap = QPixmap(size, size) pixmap.fill(Qt.transparent) imageBuffer.buffer().clear() pixmap.save(imageBuffer, "PNG") return cssString.format( size + 4, str(imageBuffer.buffer().toBase64(), encoding="ascii")) def __setListContent(self): """ Private method to prepare the content for the reader. """ u = self.url() if not u.path().endswith("/"): u.setPath(u.path() + "/") baseUrl = self.url().toString() basePath = u.path() linkClasses = {} iconSize = QWebSettings.globalSettings().fontSize( QWebSettings.DefaultFontSize) parent = u.resolved(QUrl("..")) if parent.isParentOf(u): icon = UI.PixmapCache.getIcon("up.png") linkClasses["link_parent"] = \ self.__cssLinkClass(icon, iconSize).format("link_parent") parentStr = self.tr( """

    """ """Change to parent directory

    """ ).format(parent.toString()) else: parentStr = "" row = \ """ """\ """{3}"""\ """{4}"""\ """{5}"""\ """\n""" table = self.tr( """ """ """Name""" """Size""" """Last modified""" """\n""" ) i = 0 for item in self.__items: name = item.name() if item.isDir() and not name.endswith("/"): name += "/" child = u.resolved(QUrl(name.replace(":", "%3A"))) if item.isFile(): size = item.size() unit = 0 while size: newSize = size // 1024 if newSize and unit < len(self.__units): size = newSize unit += 1 else: break sizeStr = self.tr("{0} {1}", "size unit")\ .format(size, self.__units[unit]) linkClass = "link_file" if linkClass not in linkClasses: icon = UI.PixmapCache.getIcon("fileMisc.png") linkClasses[linkClass] = \ self.__cssLinkClass(icon, iconSize).format(linkClass) else: sizeStr = "" linkClass = "link_dir" if linkClass not in linkClasses: icon = UI.PixmapCache.getIcon("dirClosed.png") linkClasses[linkClass] = \ self.__cssLinkClass(icon, iconSize).format(linkClass) table += row.format( i == 0 and "odd" or "even", linkClass, child.toString(), Utilities.html_encode(item.name()), sizeStr, item.lastModified().toString("yyyy-MM-dd hh:mm"), ) i = 1 - i content = ftpListPage_html.format( Utilities.html_encode(baseUrl), "".join(linkClasses.values()), self.tr("Listing of {0}").format(basePath), parentStr, table ) self.__content = QByteArray(content.encode("utf8")) self.__content.append(512 * b' ') self.open(QIODevice.ReadOnly | QIODevice.Unbuffered) self.setHeader( QNetworkRequest.ContentTypeHeader, "text/html; charset=UTF-8") self.setHeader( QNetworkRequest.ContentLengthHeader, self.__content.size()) self.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, 200) self.setAttribute(QNetworkRequest.HttpReasonPhraseAttribute, "Ok") self.metaDataChanged.emit() self.downloadProgress.emit( self.__content.size(), self.__content.size()) self.readyRead.emit() eric-6.0.8/eric/Helpviewer/Network/FileReply.py0000644000175000017500000002126712451233375020472 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a network reply class for directory resources. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import Qt, QByteArray, QTimer, QDir, QIODevice, QUrl, QBuffer from PyQt5.QtGui import QPixmap from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest from PyQt5.QtWebKit import QWebSettings import UI.PixmapCache import Utilities dirListPage_html = """\ {0}

    {2}

    {3} {4}
    """ class FileReply(QNetworkReply): """ Class implementing a network reply for directory resources. """ def __init__(self, url, parent=None): """ Constructor @param url requested FTP URL (QUrl) @param parent reference to the parent object (QObject) """ super(FileReply, self).__init__(parent) self.__content = QByteArray() self.__units = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] if url.path() == "": url.setPath("/") self.setUrl(url) QTimer.singleShot(0, self.__loadDirectory) def abort(self): """ Public slot to abort the operation. """ # do nothing pass def bytesAvailable(self): """ Public method to determined the bytes available for being read. @return bytes available (integer) """ return self.__content.size() def isSequential(self): """ Public method to check for sequential access. @return flag indicating sequential access (boolean) """ return True def readData(self, maxlen): """ Public method to retrieve data from the reply object. @param maxlen maximum number of bytes to read (integer) @return string containing the data (bytes) """ if self.__content.size(): len_ = min(maxlen, self.__content.size()) buffer = bytes(self.__content[:len_]) self.__content.remove(0, len_) return buffer def __cssLinkClass(self, icon, size=32): """ Private method to generate a link class with an icon. @param icon icon to be included (QIcon) @param size size of the icon to be generated (integer) @return CSS class string (string) """ cssString = \ """a.{{0}} {{{{\n"""\ """ padding-left: {0}px;\n"""\ """ background: transparent url(data:image/png;base64,{1})"""\ """ no-repeat center left;\n"""\ """ font-weight: bold;\n"""\ """}}}}\n""" pixmap = icon.pixmap(size, size) imageBuffer = QBuffer() imageBuffer.open(QIODevice.ReadWrite) if not pixmap.save(imageBuffer, "PNG"): # write a blank pixmap on error pixmap = QPixmap(size, size) pixmap.fill(Qt.transparent) imageBuffer.buffer().clear() pixmap.save(imageBuffer, "PNG") return cssString.format( size + 4, str(imageBuffer.buffer().toBase64(), encoding="ascii")) def __loadDirectory(self): """ Private slot loading the directory and preparing the listing page. """ dir = QDir(self.url().toLocalFile()) dirItems = dir.entryInfoList( QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot, QDir.Name | QDir.DirsFirst) u = self.url() if not u.path().endswith("/"): u.setPath(u.path() + "/") baseUrl = self.url().toString() basePath = u.path() linkClasses = {} iconSize = QWebSettings.globalSettings().fontSize( QWebSettings.DefaultFontSize) parent = u.resolved(QUrl("..")) if parent.isParentOf(u): icon = UI.PixmapCache.getIcon("up.png") linkClasses["link_parent"] = \ self.__cssLinkClass(icon, iconSize).format("link_parent") parentStr = self.tr( """

    """ """Change to parent directory

    """ ).format(parent.toString()) else: parentStr = "" row = \ """ """\ """{3}"""\ """{4}"""\ """{5}"""\ """\n""" table = self.tr( """ """ """Name""" """Size""" """Last modified""" """\n""" ) i = 0 for item in dirItems: name = item.fileName() if item.isDir() and not name.endswith("/"): name += "/" child = u.resolved(QUrl(name.replace(":", "%3A"))) if item.isFile(): size = item.size() unit = 0 while size: newSize = size // 1024 if newSize and unit < len(self.__units): size = newSize unit += 1 else: break sizeStr = self.tr("{0} {1}", "size unit")\ .format(size, self.__units[unit]) linkClass = "link_file" if linkClass not in linkClasses: icon = UI.PixmapCache.getIcon("fileMisc.png") linkClasses[linkClass] = \ self.__cssLinkClass(icon, iconSize).format(linkClass) else: sizeStr = "" linkClass = "link_dir" if linkClass not in linkClasses: icon = UI.PixmapCache.getIcon("dirClosed.png") linkClasses[linkClass] = \ self.__cssLinkClass(icon, iconSize).format(linkClass) table += row.format( i == 0 and "odd" or "even", linkClass, child.toString(), Utilities.html_encode(item.fileName()), sizeStr, item.lastModified().toString("yyyy-MM-dd hh:mm"), ) i = 1 - i content = dirListPage_html.format( Utilities.html_encode(baseUrl), "".join(linkClasses.values()), self.tr("Listing of {0}").format(basePath), parentStr, table ) self.__content = QByteArray(content.encode("utf8")) self.__content.append(512 * b' ') self.open(QIODevice.ReadOnly | QIODevice.Unbuffered) self.setHeader( QNetworkRequest.ContentTypeHeader, "text/html; charset=UTF-8") self.setHeader( QNetworkRequest.ContentLengthHeader, self.__content.size()) self.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, 200) self.setAttribute(QNetworkRequest.HttpReasonPhraseAttribute, "Ok") self.metaDataChanged.emit() self.downloadProgress.emit( self.__content.size(), self.__content.size()) self.readyRead.emit() self.finished.emit() eric-6.0.8/eric/Helpviewer/Network/NetworkDiskCache.py0000644000175000017500000000152112451233375021756 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a disk cache respecting privacy. """ from __future__ import unicode_literals from PyQt5.QtWebKit import QWebSettings from PyQt5.QtNetwork import QNetworkDiskCache class NetworkDiskCache(QNetworkDiskCache): """ Class implementing a disk cache respecting privacy. """ def prepare(self, metaData): """ Public method to prepare the disk cache file. @param metaData meta data for a URL (QNetworkCacheMetaData) @return reference to the IO device (QIODevice) """ if QWebSettings.globalSettings().testAttribute( QWebSettings.PrivateBrowsingEnabled): return None return QNetworkDiskCache.prepare(self, metaData) eric-6.0.8/eric/Helpviewer/Network/__init__.py0000644000175000017500000000023012451233375020321 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Package containing network related modules. """ eric-6.0.8/eric/Helpviewer/Network/NoCacheHostsDialog.py0000644000175000017500000000435612451233376022241 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to manage the list of hosts not to be cached. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QSortFilterProxyModel, QStringListModel from PyQt5.QtWidgets import QDialog, QInputDialog, QLineEdit from .Ui_NoCacheHostsDialog import Ui_NoCacheHostsDialog import Preferences class NoCacheHostsDialog(QDialog, Ui_NoCacheHostsDialog): """ Class implementing a dialog to manage the list of hosts not to be cached. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(NoCacheHostsDialog, self).__init__(parent) self.setupUi(self) self.__model = QStringListModel( Preferences.getHelp("NoCacheHosts"), self) self.__model.sort(0) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.__proxyModel.setSourceModel(self.__model) self.noCacheList.setModel(self.__proxyModel) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.removeButton.clicked.connect(self.noCacheList.removeSelected) self.removeAllButton.clicked.connect(self.noCacheList.removeAll) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add an entry to the list. """ host, ok = QInputDialog.getText( self, self.tr("Not Cached Hosts"), self.tr("Enter host name to add to the list:"), QLineEdit.Normal) if ok and host != "" and host not in self.__model.stringList(): self.__model.insertRow(self.__model.rowCount()) self.__model.setData( self.__model.index(self.__model.rowCount() - 1), host) self.__model.sort(0) def accept(self): """ Public method to accept the dialog data. """ Preferences.setHelp("NoCacheHosts", self.__model.stringList()) super(NoCacheHostsDialog, self).accept() eric-6.0.8/eric/Helpviewer/Network/NetworkProtocolUnknownErrorReply.py0000644000175000017500000000271112451233376025352 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a QNetworkReply subclass reporting an unknown protocol error. """ from __future__ import unicode_literals from PyQt5.QtCore import QTimer from PyQt5.QtNetwork import QNetworkReply class NetworkProtocolUnknownErrorReply(QNetworkReply): """ Class implementing a QNetworkReply subclass reporting an unknown protocol error. """ def __init__(self, protocol, parent=None): """ Constructor @param protocol protocol name (string) @param parent reference to the parent object (QObject) """ super(NetworkProtocolUnknownErrorReply, self).__init__(parent) self.setError( QNetworkReply.ProtocolUnknownError, self.tr("Protocol '{0}' not supported.").format(protocol)) QTimer.singleShot(0, self.__fireSignals) def __fireSignals(self): """ Private method to send some signals to end the connection. """ self.error.emit(QNetworkReply.ProtocolUnknownError) self.finished.emit() def abort(self): """ Public slot to abort the operation. """ # do nothing pass def bytesAvailable(self): """ Public method to determined the bytes available for being read. @return bytes available (integer) """ return 0 eric-6.0.8/eric/Helpviewer/Network/EmptyNetworkReply.py0000644000175000017500000000237212451233376022260 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a network reply class for an empty reply (i.e. request was handle other way). """ from __future__ import unicode_literals from PyQt5.QtCore import QTimer from PyQt5.QtNetwork import QNetworkReply, QNetworkAccessManager class EmptyNetworkReply(QNetworkReply): """ Class implementing an empty network reply. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(EmptyNetworkReply, self).__init__(parent) self.setOperation(QNetworkAccessManager.GetOperation) self.setError(QNetworkReply.OperationCanceledError, "eric6:No Error") QTimer.singleShot(0, lambda: self.finished.emit()) def abort(self): """ Public slot to abort the operation. """ # do nothing pass def readData(self, maxlen): """ Public method to retrieve data from the reply object. @param maxlen maximum number of bytes to read (integer) @return string containing the data (bytes) """ return bytes() eric-6.0.8/eric/Helpviewer/Network/FileAccessHandler.py0000644000175000017500000000303512451233376022070 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a scheme access handler for file. """ from __future__ import unicode_literals from PyQt5.QtCore import QFileInfo from PyQt5.QtNetwork import QNetworkAccessManager from .SchemeAccessHandler import SchemeAccessHandler class FileAccessHandler(SchemeAccessHandler): """ Class implementing a scheme access handler for FTP. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(FileAccessHandler, self).__init__(parent) def createRequest(self, op, request, outgoingData=None): """ Public method to create a request. @param op the operation to be performed (QNetworkAccessManager.Operation) @param request reference to the request object (QNetworkRequest) @param outgoingData reference to an IODevice containing data to be sent (QIODevice) @return reference to the created reply object (QNetworkReply) """ if op == QNetworkAccessManager.GetOperation: fileInfo = QFileInfo(request.url().toLocalFile()) if not fileInfo.isDir() or \ not fileInfo.isReadable() or \ not fileInfo.exists(): return None from .FileReply import FileReply return FileReply(request.url(), self.parent()) else: return None eric-6.0.8/eric/Helpviewer/Network/FollowRedirectReply.py0000644000175000017500000000613212451233376022532 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a network reply delegate allowing to check redirects. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, QObject from PyQt5.QtNetwork import QNetworkRequest class FollowRedirectReply(QObject): """ Class implementing a network reply delegate allowing to check redirects. """ finished = pyqtSignal() def __init__(self, url, manager, maxRedirects=5): """ Constructor @param url URL to get (QUrl) @param manager reference to the network access manager (QNetworkAccessManager) @keyparam maxRedirects maximum allowed redirects (integer) """ super(FollowRedirectReply, self).__init__() self.__manager = manager self.__maxRedirects = maxRedirects self.__redirectCount = 0 self.__reply = self.__manager.get(QNetworkRequest(url)) self.__reply.finished.connect(self.__replyFinished) def reply(self): """ Public method to get the reply object. @return reference to the reply object (QNetworkReply) """ return self.__reply def originalUrl(self): """ Public method to get the original URL. @return original URL (QUrl) """ return self.__reply.request().url() def url(self): """ Public method to get the final URL (after redirects). @return final URL (QUrl) """ return self.__reply.url() def error(self): """ Public method to get the error information. @return error code (QNetworkReply.NetworkError) """ return self.__reply.error() def errorString(self): """ Public method to get the error message. @return error message (string) """ return self.__reply.errorString() def readAll(self): """ Public method to read all received data. @return received raw data (QByteArray) """ return self.__reply.readAll() def close(self): """ Public method to close the data stream. """ self.__reply.close() def __replyFinished(self): """ Private slot handling the receipt of the requested data. """ replyStatus = self.__reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) if (replyStatus != 301 and replyStatus != 302) or \ self.__redirectCount == self.__maxRedirects: self.finished.emit() return self.__redirectCount += 1 redirectUrl = self.__reply.attribute( QNetworkRequest.RedirectionTargetAttribute) self.__reply.close() self.__reply.deleteLater() self.__reply = None self.__reply = self.__manager.get(QNetworkRequest(redirectUrl)) self.__reply.finished.connect(self.__replyFinished) eric-6.0.8/eric/Helpviewer/Network/AboutAccessHandler.py0000644000175000017500000000203012451233376022255 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a scheme access handler for about schemes. """ from __future__ import unicode_literals from .SchemeAccessHandler import SchemeAccessHandler class AboutAccessHandler(SchemeAccessHandler): """ Class implementing a scheme access handler for about schemes. """ def createRequest(self, op, request, outgoingData=None): """ Public method to create a request. @param op the operation to be performed (QNetworkAccessManager.Operation) @param request reference to the request object (QNetworkRequest) @param outgoingData reference to an IODevice containing data to be sent (QIODevice) @return reference to the created reply object (QNetworkReply) """ from .NetworkProtocolUnknownErrorReply import \ NetworkProtocolUnknownErrorReply return NetworkProtocolUnknownErrorReply("about", self.parent()) eric-6.0.8/eric/Helpviewer/Network/NetworkAccessManagerProxy.py0000644000175000017500000000570512451233376023707 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a network access manager proxy for web pages. """ from __future__ import unicode_literals from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest try: from PyQt5.QtNetwork import QSslError # __IGNORE_EXCEPTION__ __IGNORE_WARNING__ SSL_AVAILABLE = True except ImportError: SSL_AVAILABLE = False class NetworkAccessManagerProxy(QNetworkAccessManager): """ Class implementing a network access manager proxy for web pages. """ primaryManager = None def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(NetworkAccessManagerProxy, self).__init__(parent) self.__webPage = None def setWebPage(self, page): """ Public method to set the reference to a web page. @param page reference to the web page object (HelpWebPage) """ assert page is not None self.__webPage = page def setPrimaryNetworkAccessManager(self, manager): """ Public method to set the primary network access manager. @param manager reference to the network access manager object (QNetworkAccessManager) """ assert manager is not None if self.__class__.primaryManager is None: self.__class__.primaryManager = manager self.setCookieJar(self.__class__.primaryManager.cookieJar()) # do not steal ownership self.cookieJar().setParent(self.__class__.primaryManager) if SSL_AVAILABLE: self.sslErrors.connect(self.__class__.primaryManager.sslErrors) self.proxyAuthenticationRequired.connect( self.__class__.primaryManager.proxyAuthenticationRequired) self.authenticationRequired.connect( self.__class__.primaryManager.authenticationRequired) self.finished.connect(self.__class__.primaryManager.finished) def createRequest(self, op, request, outgoingData=None): """ Public method to create a request. @param op the operation to be performed (QNetworkAccessManager.Operation) @param request reference to the request object (QNetworkRequest) @param outgoingData reference to an IODevice containing data to be sent (QIODevice) @return reference to the created reply object (QNetworkReply) """ if self.primaryManager is not None: pageRequest = QNetworkRequest(request) if self.__webPage is not None: self.__webPage.populateNetworkRequest(pageRequest) return self.primaryManager.createRequest( op, pageRequest, outgoingData) else: return QNetworkAccessManager.createRequest( self, op, request, outgoingData) eric-6.0.8/eric/Helpviewer/Network/FtpAccessHandler.py0000644000175000017500000000571612451233376021752 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a scheme access handler for FTP. """ from __future__ import unicode_literals from PyQt5.QtNetwork import QNetworkAccessManager from .SchemeAccessHandler import SchemeAccessHandler class FtpAccessHandler(SchemeAccessHandler): """ Class implementing a scheme access handler for FTP. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(FtpAccessHandler, self).__init__(parent) self.__authenticatorCache = {} self.__proxyAuthenticator = None def createRequest(self, op, request, outgoingData=None): """ Public method to create a request. @param op the operation to be performed (QNetworkAccessManager.Operation) @param request reference to the request object (QNetworkRequest) @param outgoingData reference to an IODevice containing data to be sent (QIODevice) @return reference to the created reply object (QNetworkReply) """ if op == QNetworkAccessManager.GetOperation: from .FtpReply import FtpReply return FtpReply(request.url(), self, self.parent()) else: return None def setAuthenticator(self, realm, authenticator): """ Public method to add or change an authenticator in our cache. @param realm name of the realm the authenticator belongs to (string) @param authenticator authenticator to add to the cache (QAuthenticator). If it is None, the entry will be deleted from the cache. """ if realm: if authenticator: self.__authenticatorCache[realm] = authenticator else: if realm in self.__authenticatorCache: del self.__authenticatorCache[realm] def getAuthenticator(self, realm): """ Public method to get an authenticator for the given realm. @param realm name of the realm to get the authenticator for (string) @return authenticator for the given realm (QAuthenticator) or None """ if realm in self.__authenticatorCache: return self.__authenticatorCache[realm] else: return None def setProxyAuthenticator(self, authenticator): """ Public method to add or change the authenticator for the FTP proxy. @param authenticator authenticator for the FTP proxy (QAuthenticator) """ self.__proxyAuthenticator = authenticator def getProxyAuthenticator(self): """ Public method to get the authenticator for the FTP proxy. @return authenticator for the FTP proxy (QAuthenticator) """ return self.__proxyAuthenticator eric-6.0.8/eric/Helpviewer/Network/SendRefererWhitelistDialog.py0000644000175000017500000000445012451233376024014 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to manage the Send Referer whitelist. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QSortFilterProxyModel, QStringListModel from PyQt5.QtWidgets import QDialog, QInputDialog, QLineEdit from .Ui_SendRefererWhitelistDialog import Ui_SendRefererWhitelistDialog import Preferences class SendRefererWhitelistDialog(QDialog, Ui_SendRefererWhitelistDialog): """ Class implementing a dialog to manage the Send Referer whitelist. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(SendRefererWhitelistDialog, self).__init__(parent) self.setupUi(self) self.__model = QStringListModel( Preferences.getHelp("SendRefererWhitelist"), self) self.__model.sort(0) self.__proxyModel = QSortFilterProxyModel(self) self.__proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.__proxyModel.setSourceModel(self.__model) self.whitelist.setModel(self.__proxyModel) self.searchEdit.textChanged.connect( self.__proxyModel.setFilterFixedString) self.removeButton.clicked.connect(self.whitelist.removeSelected) self.removeAllButton.clicked.connect(self.whitelist.removeAll) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add an entry to the whitelist. """ host, ok = QInputDialog.getText( self, self.tr("Send Referer Whitelist"), self.tr("Enter host name to add to the whitelist:"), QLineEdit.Normal) if ok and host != "" and host not in self.__model.stringList(): self.__model.insertRow(self.__model.rowCount()) self.__model.setData( self.__model.index(self.__model.rowCount() - 1), host) self.__model.sort(0) def accept(self): """ Public method to accept the dialog data. """ Preferences.setHelp("SendRefererWhitelist", self.__model.stringList()) super(SendRefererWhitelistDialog, self).accept() eric-6.0.8/eric/Helpviewer/Network/SendRefererWhitelistDialog.ui0000644000175000017500000001232112060166052023765 0ustar piotrpiotr SendRefererWhitelistDialog 0 0 500 350 Send Referer Whitelist true 0 0 0 300 0 Enter search term for hosts Qt::Horizontal 40 20 Qt::Vertical 20 40 Press to add site to the whitelist &Add... false Qt::Horizontal Press to remove the selected entries &Remove false Press to remove all entries R&emove All false true QAbstractItemView::ExtendedSelection Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok E5ClearableLineEdit QLineEdit
    E5Gui/E5LineEdit.h
    E5ListView QListView
    E5Gui/E5ListView.h
    searchEdit whitelist addButton removeButton removeAllButton buttonBox buttonBox accepted() SendRefererWhitelistDialog accept() 227 329 157 274 buttonBox rejected() SendRefererWhitelistDialog reject() 295 335 286 274
    eric-6.0.8/eric/Helpviewer/Network/EricAccessHandler.py0000644000175000017500000001142212554665654022106 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a scheme access handler for Python resources. """ from __future__ import unicode_literals from PyQt5.QtCore import QFile, QByteArray import Utilities from .SchemeAccessHandler import SchemeAccessHandler class EricAccessHandler(SchemeAccessHandler): """ Class implementing a scheme access handler for Python resources. """ _homePage = None _speedDialPage = None def createRequest(self, op, request, outgoingData=None): """ Public method to create a request. @param op the operation to be performed (QNetworkAccessManager.Operation) @param request reference to the request object (QNetworkRequest) @param outgoingData reference to an IODevice containing data to be sent (QIODevice) @return reference to the created reply object (QNetworkReply) """ from .NetworkReply import NetworkReply from .NetworkProtocolUnknownErrorReply import \ NetworkProtocolUnknownErrorReply if request.url().toString() == "eric:home": return NetworkReply(request, self.__createHomePage(), "text/html", self.parent()) elif request.url().toString() == "eric:speeddial": return NetworkReply(request, self.__createSpeedDialPage(), "text/html", self.parent()) return NetworkProtocolUnknownErrorReply("eric", self.parent()) def __createHomePage(self): """ Private method to create the Home page. @return prepared home page (QByteArray) """ if self._homePage is None: htmlFile = QFile(":/html/startPage.html") htmlFile.open(QFile.ReadOnly) html = htmlFile.readAll() html.replace("@IMAGE@", b"qrc:icons/ericWeb32.png") html.replace("@FAVICON@", b"qrc:icons/ericWeb16.png") self._homePage = html return QByteArray(self._homePage) def __createSpeedDialPage(self): """ Private method to create the Speeddial page. @return prepared speeddial page (QByteArray) """ if self._speedDialPage is None: htmlFile = QFile(":/html/speeddialPage.html") htmlFile.open(QFile.ReadOnly) html = bytes(htmlFile.readAll()).decode() html = ( html.replace("@FAVICON@", "qrc:icons/ericWeb16.png") .replace("@IMG_PLUS@", "qrc:icons/plus.png") .replace("@IMG_CLOSE@", "qrc:icons/close.png") .replace("@IMG_EDIT@", "qrc:icons/edit.png") .replace("@IMG_RELOAD@", "qrc:icons/reload.png") .replace("@IMG_SETTINGS@", "qrc:icons/setting.png") .replace("@LOADING-IMG@", "qrc:icons/loading.gif") .replace("@BOX-BORDER@", "qrc:icons/box-border-small.png") .replace("@JQUERY@", "qrc:javascript/jquery.js") .replace("@JQUERY-UI@", "qrc:javascript/jquery-ui.js") .replace("@SITE-TITLE@", self.tr("Speed Dial")) .replace("@URL@", self.tr("URL")) .replace("@TITLE@", self.tr("Title")) .replace("@APPLY@", self.tr("Apply")) .replace("@CLOSE@", self.tr("Close")) .replace("@NEW-PAGE@", self.tr("New Page")) .replace("@TITLE-EDIT@", self.tr("Edit")) .replace("@TITLE-REMOVE@", self.tr("Remove")) .replace("@TITLE-RELOAD@", self.tr("Reload")) .replace("@TITLE-WARN@", self.tr("Are you sure to remove this speed dial?")) .replace("@TITLE-FETCHTITLE@", self.tr("Load title from page")) .replace("@SETTINGS-TITLE@", self.tr("Speed Dial Settings")) .replace("@ADD-TITLE@", self.tr("Add New Page")) .replace("@TXT_NRROWS@", self.tr("Maximum pages in a row:")) .replace("@TXT_SDSIZE@", self.tr("Change size of pages:")) ) self._speedDialPage = Utilities.html_uencode(html) import Helpviewer.HelpWindow html = QByteArray(self._speedDialPage.encode("utf-8")) dial = Helpviewer.HelpWindow.HelpWindow.speedDial() html.replace("@INITIAL-SCRIPT@", dial.initialScript().encode("utf-8")) html.replace("@ROW-PAGES@", str(dial.pagesInRow()).encode("utf-8")) html.replace("@SD-SIZE@", str(dial.sdSize()).encode("utf-8")) return html eric-6.0.8/eric/Helpviewer/Network/NetworkAccessManager.py0000644000175000017500000002472212554467641022655 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a QNetworkAccessManager subclass. """ from __future__ import unicode_literals import os from PyQt5.QtCore import pyqtSignal, QByteArray, qVersion from PyQt5.QtWidgets import QDialog from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, \ QNetworkReply from E5Network.E5NetworkProxyFactory import E5NetworkProxyFactory, \ proxyAuthenticationRequired try: from PyQt5.QtNetwork import QSslSocket from E5Network.E5SslErrorHandler import E5SslErrorHandler SSL_AVAILABLE = True except ImportError: SSL_AVAILABLE = False import Preferences import Utilities class NetworkAccessManager(QNetworkAccessManager): """ Class implementing a QNetworkAccessManager subclass. @signal requestCreated emitted after the request has been created passing the operation, a reference to the network request and a reference to the network reply (QNetworkAccessManager.Operation, QNetworkRequest, QNetworkReply) """ requestCreated = pyqtSignal( QNetworkAccessManager.Operation, QNetworkRequest, QNetworkReply) def __init__(self, engine, parent=None): """ Constructor @param engine reference to the help engine (QHelpEngine) @param parent reference to the parent object (QObject) """ super(NetworkAccessManager, self).__init__(parent) self.__adblockNetwork = None self.__schemeHandlers = {} # dictionary of scheme handlers self.__proxyFactory = E5NetworkProxyFactory() self.setProxyFactory(self.__proxyFactory) self.__setDiskCache() self.languagesChanged() if SSL_AVAILABLE: self.__sslErrorHandler = E5SslErrorHandler(self) self.sslErrors.connect(self.__sslErrorHandler.sslErrorsReplySlot) self.proxyAuthenticationRequired.connect(proxyAuthenticationRequired) self.authenticationRequired.connect(self.__authenticationRequired) self.__doNotTrack = Preferences.getHelp("DoNotTrack") self.__sendReferer = Preferences.getHelp("SendReferer") # register scheme handlers if engine: from .QtHelpAccessHandler import QtHelpAccessHandler self.setSchemeHandler("qthelp", QtHelpAccessHandler(engine, self)) from .EricAccessHandler import EricAccessHandler self.setSchemeHandler("eric", EricAccessHandler(self)) from .AboutAccessHandler import AboutAccessHandler self.setSchemeHandler("about", AboutAccessHandler(self)) from Helpviewer.AdBlock.AdBlockAccessHandler import \ AdBlockAccessHandler self.setSchemeHandler("abp", AdBlockAccessHandler(self)) from .FtpAccessHandler import FtpAccessHandler self.setSchemeHandler("ftp", FtpAccessHandler(self)) from .FileAccessHandler import FileAccessHandler self.setSchemeHandler("file", FileAccessHandler(self)) def setSchemeHandler(self, scheme, handler): """ Public method to register a scheme handler. @param scheme access scheme (string) @param handler reference to the scheme handler object (SchemeAccessHandler) """ self.__schemeHandlers[scheme] = handler def createRequest(self, op, request, outgoingData=None): """ Public method to create a request. @param op the operation to be performed (QNetworkAccessManager.Operation) @param request reference to the request object (QNetworkRequest) @param outgoingData reference to an IODevice containing data to be sent (QIODevice) @return reference to the created reply object (QNetworkReply) """ scheme = request.url().scheme() if scheme == "https" and \ (not SSL_AVAILABLE or not QSslSocket.supportsSsl()): from .NetworkProtocolUnknownErrorReply import \ NetworkProtocolUnknownErrorReply return NetworkProtocolUnknownErrorReply(scheme, self) import Helpviewer.HelpWindow if op == QNetworkAccessManager.PostOperation and \ outgoingData is not None: outgoingDataByteArray = outgoingData.peek(1024 * 1024) Helpviewer.HelpWindow.HelpWindow.passwordManager().post( request, outgoingDataByteArray) reply = None if scheme in self.__schemeHandlers: reply = self.__schemeHandlers[scheme]\ .createRequest(op, request, outgoingData) if reply is not None: return reply # give GreaseMonkey the chance to create a request reply = Helpviewer.HelpWindow.HelpWindow.greaseMonkeyManager()\ .createRequest(op, request, outgoingData) if reply is not None: return reply req = QNetworkRequest(request) if req.rawHeader(b"X-Eric6-UserLoadAction") == QByteArray(b"1"): req.setRawHeader(b"X-Eric6-UserLoadAction", QByteArray()) req.setAttribute(QNetworkRequest.User + 200, "") else: req.setAttribute( QNetworkRequest.User + 200, req.rawHeader(b"Referer")) if hasattr(QNetworkRequest, 'HttpPipeliningAllowedAttribute'): req.setAttribute( QNetworkRequest.HttpPipeliningAllowedAttribute, True) if not self.__acceptLanguage.isEmpty(): req.setRawHeader(b"Accept-Language", self.__acceptLanguage) # AdBlock code if op == QNetworkAccessManager.GetOperation: if self.__adblockNetwork is None: self.__adblockNetwork = \ Helpviewer.HelpWindow.HelpWindow.adBlockManager().network() reply = self.__adblockNetwork.block(req) if reply is not None: reply.setParent(self) return reply # set cache policy if op == QNetworkAccessManager.GetOperation: urlHost = req.url().host() for host in Preferences.getHelp("NoCacheHosts"): if host in urlHost: req.setAttribute( QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) break else: req.setAttribute( QNetworkRequest.CacheLoadControlAttribute, Preferences.getHelp("CachePolicy")) else: req.setAttribute( QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) # Do Not Track feature if self.__doNotTrack: req.setRawHeader(b"DNT", b"1") req.setRawHeader(b"X-Do-Not-Track", b"1") # Send referer header? if not self.__sendReferer and \ req.url().host() not in Preferences.getHelp("SendRefererWhitelist"): req.setRawHeader(b"Referer", b"") reply = QNetworkAccessManager.createRequest( self, op, req, outgoingData) self.requestCreated.emit(op, req, reply) return reply def __authenticationRequired(self, reply, auth): """ Private slot to handle an authentication request. @param reply reference to the reply object (QNetworkReply) @param auth reference to the authenticator object (QAuthenticator) """ urlRoot = "{0}://{1}"\ .format(reply.url().scheme(), reply.url().authority()) realm = auth.realm() if not realm and 'realm' in auth.options(): realm = auth.option("realm") if realm: info = self.tr("Enter username and password for '{0}', " "realm '{1}'").format(urlRoot, realm) else: info = self.tr("Enter username and password for '{0}'")\ .format(urlRoot) from UI.AuthenticationDialog import AuthenticationDialog import Helpviewer.HelpWindow dlg = AuthenticationDialog(info, auth.user(), Preferences.getUser("SavePasswords"), Preferences.getUser("SavePasswords")) if Preferences.getUser("SavePasswords"): username, password = \ Helpviewer.HelpWindow.HelpWindow.passwordManager().getLogin( reply.url(), realm) if username: dlg.setData(username, password) if dlg.exec_() == QDialog.Accepted: username, password = dlg.getData() auth.setUser(username) auth.setPassword(password) if Preferences.getUser("SavePasswords"): Helpviewer.HelpWindow.HelpWindow.passwordManager().setLogin( reply.url(), realm, username, password) def preferencesChanged(self): """ Public slot to signal a change of preferences. """ self.__setDiskCache() self.__doNotTrack = Preferences.getHelp("DoNotTrack") self.__sendReferer = Preferences.getHelp("SendReferer") def languagesChanged(self): """ Public slot to (re-)load the list of accepted languages. """ from Helpviewer.HelpLanguagesDialog import HelpLanguagesDialog languages = Preferences.toList( Preferences.Prefs.settings.value( "Help/AcceptLanguages", HelpLanguagesDialog.defaultAcceptLanguages())) self.__acceptLanguage = HelpLanguagesDialog.httpString(languages) def __setDiskCache(self): """ Private method to set the disk cache. """ if Preferences.getHelp("DiskCacheEnabled"): from PyQt5.QtWebKit import qWebKitVersion from .NetworkDiskCache import NetworkDiskCache diskCache = NetworkDiskCache(self) location = os.path.join( Utilities.getConfigDir(), "browser", 'cache', "{0}-Qt{1}".format(qWebKitVersion(), qVersion())) size = Preferences.getHelp("DiskCacheSize") * 1024 * 1024 diskCache.setCacheDirectory(location) diskCache.setMaximumCacheSize(size) else: diskCache = None self.setCache(diskCache) eric-6.0.8/eric/Helpviewer/Network/QtHelpAccessHandler.py0000644000175000017500000000774212451233376022417 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a scheme access handler for QtHelp. """ from __future__ import unicode_literals import mimetypes import os from PyQt5.QtCore import QByteArray from .SchemeAccessHandler import SchemeAccessHandler from .NetworkReply import NetworkReply QtDocPath = "qthelp://com.trolltech." ExtensionMap = { ".bmp": "image/bmp", ".css": "text/css", ".gif": "image/gif", ".html": "text/html", ".htm": "text/html", ".ico": "image/x-icon", ".jpeg": "image/jpeg", ".jpg": "image/jpeg", ".js": "application/x-javascript", ".mng": "video/x-mng", ".pbm": "image/x-portable-bitmap", ".pgm": "image/x-portable-graymap", ".pdf": "application/pdf", ".png": "image/png", ".ppm": "image/x-portable-pixmap", ".rss": "application/rss+xml", ".svg": "image/svg+xml", ".svgz": "image/svg+xml", ".text": "text/plain", ".tif": "image/tiff", ".tiff": "image/tiff", ".txt": "text/plain", ".xbm": "image/x-xbitmap", ".xml": "text/xml", ".xpm": "image/x-xpm", ".xsl": "text/xsl", ".xhtml": "application/xhtml+xml", ".wml": "text/vnd.wap.wml", ".wmlc": "application/vnd.wap.wmlc", } class QtHelpAccessHandler(SchemeAccessHandler): """ Class implementing a scheme access handler for QtHelp. """ def __init__(self, engine, parent=None): """ Constructor @param engine reference to the help engine (QHelpEngine) @param parent reference to the parent object (QObject) """ SchemeAccessHandler.__init__(self, parent) self.__engine = engine def __mimeFromUrl(self, url): """ Private method to guess the mime type given an URL. @param url URL to guess the mime type from (QUrl) @return mime type for the given URL (string) """ path = url.path() ext = os.path.splitext(path)[1].lower() if ext in ExtensionMap: return ExtensionMap[ext] else: return "application/octet-stream" def createRequest(self, op, request, outgoingData=None): """ Public method to create a request. @param op the operation to be performed (QNetworkAccessManager.Operation) @param request reference to the request object (QNetworkRequest) @param outgoingData reference to an IODevice containing data to be sent (QIODevice) @return reference to the created reply object (QNetworkReply) """ url = request.url() strUrl = url.toString() # For some reason the url to load is already wrong (passed from webkit) # though the css file and the references inside should work that way. # One possible problem might be that the css is loaded at the same # level as the html, thus a path inside the css like # (../images/foo.png) might cd out of the virtual folder if not self.__engine.findFile(url).isValid(): if strUrl.startswith(QtDocPath): newUrl = request.url() if not newUrl.path().startswith("/qdoc/"): newUrl.setPath("qdoc" + newUrl.path()) url = newUrl strUrl = url.toString() mimeType = mimetypes.guess_type(strUrl)[0] if mimeType is None: # do our own (limited) guessing mimeType = self.__mimeFromUrl(url) if self.__engine.findFile(url).isValid(): data = self.__engine.fileData(url) else: data = QByteArray(self.tr( """Error 404...""" """


    """ """

    The page could not be found


    """ """

    '{0}'

    """).format(strUrl).encode("utf-8")) return NetworkReply(request, data, mimeType, self.parent()) eric-6.0.8/eric/Helpviewer/HelpTabBar.py0000644000175000017500000001256612451233376017115 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2015 Detlev Offenbach # """ Module implementing a specialized tab bar for the web browser. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QPoint, QTimer, QEvent from PyQt5.QtWidgets import QFrame, QLabel from E5Gui.E5TabWidget import E5WheelTabBar from E5Gui.E5PassivePopup import E5PassivePopup import Preferences class HelpTabBar(E5WheelTabBar): """ Class implementing the tab bar of the web browser. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (HelpTabWidget) """ E5WheelTabBar.__init__(self, parent) self.__tabWidget = parent self.__previewPopup = None self.__currentTabPreviewIndex = -1 self.setMouseTracking(True) def __showTabPreview(self): """ Private slot to show the tab preview. """ indexedBrowser = self.__tabWidget.browserAt( self.__currentTabPreviewIndex) currentBrowser = self.__tabWidget.currentBrowser() if indexedBrowser is None or currentBrowser is None: return # no previews during load if indexedBrowser.progress() != 0: return w = self.tabSizeHint(self.__currentTabPreviewIndex).width() h = int(w * currentBrowser.height() / currentBrowser.width()) self.__previewPopup = E5PassivePopup(self) self.__previewPopup.setFrameShape(QFrame.StyledPanel) self.__previewPopup.setFrameShadow(QFrame.Plain) self.__previewPopup.setFixedSize(w, h) from .HelpSnap import renderTabPreview label = QLabel() label.setPixmap(renderTabPreview(indexedBrowser.page(), w, h)) self.__previewPopup.setView(label) self.__previewPopup.layout().setAlignment(Qt.AlignTop) self.__previewPopup.layout().setContentsMargins(0, 0, 0, 0) tr = self.tabRect(self.__currentTabPreviewIndex) pos = QPoint(tr.x(), tr.y() + tr.height()) self.__previewPopup.show(self.mapToGlobal(pos)) def mouseMoveEvent(self, evt): """ Protected method to handle mouse move events. @param evt reference to the mouse move event (QMouseEvent) """ if self.count() == 1: return E5WheelTabBar.mouseMoveEvent(self, evt) if Preferences.getHelp("ShowPreview"): # Find the tab under the mouse i = 0 tabIndex = -1 while i < self.count() and tabIndex == -1: if self.tabRect(i).contains(evt.pos()): tabIndex = i i += 1 # If found and not the current tab then show tab preview if tabIndex != -1 and \ tabIndex != self.currentIndex() and \ self.__currentTabPreviewIndex != tabIndex and \ evt.buttons() == Qt.NoButton: self.__currentTabPreviewIndex = tabIndex QTimer.singleShot(200, self.__showTabPreview) # If current tab or not found then hide previous tab preview if tabIndex == self.currentIndex() or \ tabIndex == -1: if self.__previewPopup is not None: self.__previewPopup.hide() self.__currentTabPreviewIndex = -1 def leaveEvent(self, evt): """ Protected method to handle leave events. @param evt reference to the leave event (QEvent) """ if Preferences.getHelp("ShowPreview"): # If leave tabwidget then hide previous tab preview if self.__previewPopup is not None: self.__previewPopup.hide() self.__currentTabPreviewIndex = -1 E5WheelTabBar.leaveEvent(self, evt) def mousePressEvent(self, evt): """ Protected method to handle mouse press events. @param evt reference to the mouse press event (QMouseEvent) """ if Preferences.getHelp("ShowPreview"): if self.__previewPopup is not None: self.__previewPopup.hide() self.__currentTabPreviewIndex = -1 E5WheelTabBar.mousePressEvent(self, evt) def event(self, evt): """ Public method to handle event. This event handler just handles the tooltip event and passes the handling of all others to the superclass. @param evt reference to the event to be handled (QEvent) @return flag indicating, if the event was handled (boolean) """ if evt.type() == QEvent.ToolTip and \ Preferences.getHelp("ShowPreview"): # suppress tool tips if we are showing previews evt.setAccepted(True) return True return E5WheelTabBar.event(self, evt) def tabRemoved(self, index): """ Public slot to handle the removal of a tab. @param index index of the removed tab (integer) """ if Preferences.getHelp("ShowPreview"): if self.__previewPopup is not None: self.__previewPopup.hide() self.__currentTabPreviewIndex = -1 eric-6.0.8/eric/Helpviewer/PersonalInformationManager/0000755000175000017500000000000012557365404022056 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/PersonalInformationManager/PersonalDataDialog.py0000644000175000017500000000576112451233376026131 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a dialog to enter personal data. """ from __future__ import unicode_literals from PyQt5.QtWidgets import QDialog from .Ui_PersonalDataDialog import Ui_PersonalDataDialog import UI.PixmapCache import Preferences class PersonalDataDialog(QDialog, Ui_PersonalDataDialog): """ Class implementing a dialog to enter personal data. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(PersonalDataDialog, self).__init__(parent) self.setupUi(self) self.iconLabel.setPixmap(UI.PixmapCache.getPixmap("pim48.png")) self.firstnameEdit.setText(Preferences.getHelp("PimFirstName")) self.lastnameEdit.setText(Preferences.getHelp("PimLastName")) self.fullnameEdit.setText(Preferences.getHelp("PimFullName")) self.emailEdit.setText(Preferences.getHelp("PimEmail")) self.phoneEdit.setText(Preferences.getHelp("PimPhone")) self.mobileEdit.setText(Preferences.getHelp("PimMobile")) self.addressEdit.setText(Preferences.getHelp("PimAddress")) self.cityEdit.setText(Preferences.getHelp("PimCity")) self.zipEdit.setText(Preferences.getHelp("PimZip")) self.stateEdit.setText(Preferences.getHelp("PimState")) self.countryEdit.setText(Preferences.getHelp("PimCountry")) self.homepageEdit.setText(Preferences.getHelp("PimHomePage")) self.special1Edit.setText(Preferences.getHelp("PimSpecial1")) self.special2Edit.setText(Preferences.getHelp("PimSpecial2")) self.special3Edit.setText(Preferences.getHelp("PimSpecial3")) self.special4Edit.setText(Preferences.getHelp("PimSpecial4")) def storeData(self): """ Public method to store the entered personal information. """ Preferences.setHelp("PimFirstName", self.firstnameEdit.text()) Preferences.setHelp("PimLastName", self.lastnameEdit.text()) Preferences.setHelp("PimFullName", self.fullnameEdit.text()) Preferences.setHelp("PimEmail", self.emailEdit.text()) Preferences.setHelp("PimPhone", self.phoneEdit.text()) Preferences.setHelp("PimMobile", self.mobileEdit.text()) Preferences.setHelp("PimAddress", self.addressEdit.text()) Preferences.setHelp("PimCity", self.cityEdit.text()) Preferences.setHelp("PimZip", self.zipEdit.text()) Preferences.setHelp("PimState", self.stateEdit.text()) Preferences.setHelp("PimCountry", self.countryEdit.text()) Preferences.setHelp("PimHomePage", self.homepageEdit.text()) Preferences.setHelp("PimSpecial1", self.special1Edit.text()) Preferences.setHelp("PimSpecial2", self.special2Edit.text()) Preferences.setHelp("PimSpecial3", self.special3Edit.text()) Preferences.setHelp("PimSpecial4", self.special4Edit.text()) eric-6.0.8/eric/Helpviewer/PersonalInformationManager/PersonalDataDialog.ui0000644000175000017500000002536512060166052026110 0ustar piotrpiotr PersonalDataDialog 0 0 600 400 Personal Information true Qt::Horizontal 40 20 48 48 Icon <h2>Personal Information</h2> Qt::Horizontal 40 20 Your personal information that will be used on webpages. Qt::AlignCenter true First Name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter ZIP Code: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Last Name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter State/Region: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Full Name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Country: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter E-mail: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Home Page: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Phone: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Custom 1: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Mobile Phone: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Custom 2: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Address: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Custom 3: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter City: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Custom 4: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <b>Note:</b> Press Ctrl+ENTER to autofill form fields for which personal entries were found. true Qt::Vertical 20 31 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok firstnameEdit lastnameEdit fullnameEdit emailEdit phoneEdit mobileEdit addressEdit cityEdit zipEdit stateEdit countryEdit homepageEdit special1Edit special2Edit special3Edit special4Edit buttonBox buttonBox accepted() PersonalDataDialog accept() 248 254 157 274 buttonBox rejected() PersonalDataDialog reject() 316 260 286 274 eric-6.0.8/eric/Helpviewer/PersonalInformationManager/__init__.py0000644000175000017500000000027712451233376024170 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Package implementing the personal information manager for the completion of forms. """ eric-6.0.8/eric/Helpviewer/PersonalInformationManager/PersonalInformationManager.py0000644000175000017500000002171712451233376027717 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a personal information manager used to complete form fields. """ from __future__ import unicode_literals from PyQt5.QtCore import Qt, QObject from PyQt5.QtWidgets import QDialog, QMenu import Preferences import UI.PixmapCache class PersonalInformationManager(QObject): """ Class implementing the personal information manager used to complete form fields. """ FullName = 0 LastName = 1 FirstName = 2 Email = 3 Mobile = 4 Phone = 5 Address = 6 City = 7 Zip = 8 State = 9 Country = 10 HomePage = 11 Special1 = 12 Special2 = 13 Special3 = 14 Special4 = 15 Max = 16 Invalid = 256 def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(PersonalInformationManager, self).__init__(parent) self.__loaded = False self.__allInfo = {} self.__infoMatches = {} self.__translations = {} self.__view = None self.__element = None def __loadSettings(self): """ Private method to load the settings. """ self.__allInfo[self.FullName] = Preferences.getHelp("PimFullName") self.__allInfo[self.LastName] = Preferences.getHelp("PimLastName") self.__allInfo[self.FirstName] = Preferences.getHelp("PimFirstName") self.__allInfo[self.Email] = Preferences.getHelp("PimEmail") self.__allInfo[self.Mobile] = Preferences.getHelp("PimMobile") self.__allInfo[self.Phone] = Preferences.getHelp("PimPhone") self.__allInfo[self.Address] = Preferences.getHelp("PimAddress") self.__allInfo[self.City] = Preferences.getHelp("PimCity") self.__allInfo[self.Zip] = Preferences.getHelp("PimZip") self.__allInfo[self.State] = Preferences.getHelp("PimState") self.__allInfo[self.Country] = Preferences.getHelp("PimCountry") self.__allInfo[self.HomePage] = Preferences.getHelp("PimHomePage") self.__allInfo[self.Special1] = Preferences.getHelp("PimSpecial1") self.__allInfo[self.Special2] = Preferences.getHelp("PimSpecial2") self.__allInfo[self.Special3] = Preferences.getHelp("PimSpecial3") self.__allInfo[self.Special4] = Preferences.getHelp("PimSpecial4") self.__translations[self.FullName] = self.tr("Full Name") self.__translations[self.LastName] = self.tr("Last Name") self.__translations[self.FirstName] = self.tr("First Name") self.__translations[self.Email] = self.tr("E-mail") self.__translations[self.Mobile] = self.tr("Mobile") self.__translations[self.Phone] = self.tr("Phone") self.__translations[self.Address] = self.tr("Address") self.__translations[self.City] = self.tr("City") self.__translations[self.Zip] = self.tr("ZIP Code") self.__translations[self.State] = self.tr("State/Region") self.__translations[self.Country] = self.tr("Country") self.__translations[self.HomePage] = self.tr("Home Page") self.__translations[self.Special1] = self.tr("Custom 1") self.__translations[self.Special2] = self.tr("Custom 2") self.__translations[self.Special3] = self.tr("Custom 3") self.__translations[self.Special4] = self.tr("Custom 4") self.__infoMatches[self.FullName] = ["fullname", "realname"] self.__infoMatches[self.LastName] = ["lastname", "surname"] self.__infoMatches[self.FirstName] = ["firstname", "name"] self.__infoMatches[self.Email] = ["email", "e-mail", "mail"] self.__infoMatches[self.Mobile] = ["mobile", "mobilephone"] self.__infoMatches[self.Phone] = ["phone", "telephone"] self.__infoMatches[self.Address] = ["address"] self.__infoMatches[self.City] = ["city"] self.__infoMatches[self.Zip] = ["zip"] self.__infoMatches[self.State] = ["state", "region"] self.__infoMatches[self.Country] = ["country"] self.__infoMatches[self.HomePage] = ["homepage", "www"] self.__loaded = True def showConfigurationDialog(self): """ Public method to show the configuration dialog. """ from .PersonalDataDialog import PersonalDataDialog dlg = PersonalDataDialog() if dlg.exec_() == QDialog.Accepted: dlg.storeData() self.__loadSettings() def createSubMenu(self, menu, view, hitTestResult): """ Public method to create the personal information sub-menu. @param menu reference to the main menu (QMenu) @param view reference to the view (HelpBrowser) @param hitTestResult reference to the hit test result (QWebHitTestResult) """ self.__view = view self.__element = hitTestResult.element() if not hitTestResult.isContentEditable(): return if not self.__loaded: self.__loadSettings() submenu = QMenu(self.tr("Insert Personal Information"), menu) submenu.setIcon(UI.PixmapCache.getIcon("pim.png")) for key, info in sorted(self.__allInfo.items()): if info: act = submenu.addAction( self.__translations[key], self.__insertData) act.setData(info) submenu.addSeparator() submenu.addAction(self.tr("Edit Personal Information"), self.showConfigurationDialog) menu.addMenu(submenu) menu.addSeparator() def __insertData(self): """ Private slot to insert the selected personal information. """ act = self.sender() if not self.__element or self.__element.isNull() or act is None: return info = act.data() info = info.replace('"', '\\"') self.__element.evaluateJavaScript( 'var newVal = this.value.substring(0, this.selectionStart) +' ' "{0}" + this.value.substring(this.selectionEnd); this.value =' ' newVal;'.format(info)) def viewKeyPressEvent(self, view, evt): """ Protected method to handle key press events we are interested in. @param view reference to the view (HelpBrowser) @param evt reference to the key event (QKeyEvent) @return flag indicating handling of the event (boolean) """ if view is None: return False isEnter = evt.key() in [Qt.Key_Return, Qt.Key_Enter] if not isEnter or evt.modifiers() != Qt.ControlModifier: return False if not self.__loaded: self.__loadSettings() document = view.page().mainFrame().documentElement() elements = document.findAll('input[type="text"]') for element in elements: name = element.attribute("name") if name == "": continue match = self.__nameMatch(name) if match != self.Invalid: element.evaluateJavaScript( 'this.value = "{0}"'.format(self.__allInfo[match])) return True def __nameMatch(self, name): """ Private method to find the information entry for the given field. @param name name of the form field (string) @return value of the information entry (integer) """ for index in range(self.Max): if self.__allInfo[index]: for n in self.__infoMatches[index]: if name == n or n in name: return index return self.Invalid def connectPage(self, page): """ Public method to allow the personal information manager to connect to the page. @param page reference to the web page (HelpWebPage) """ page.loadFinished.connect(self.__pageLoadFinished) def __pageLoadFinished(self, ok): """ Private slot to handle the completion of a page load. @param ok flag indicating a successful load (boolean) """ page = self.sender() if page is None or not ok: return if not self.__loaded: self.__loadSettings() document = page.mainFrame().documentElement() elements = document.findAll('input[type="text"]') for element in elements: name = element.attribute("name") if name == "": continue match = self.__nameMatch(name) if match != self.Invalid: element.setStyleProperty( "-webkit-appearance", "none") element.setStyleProperty( "-webkit-box-shadow", "inset 0 0 2px 1px #0000EE") eric-6.0.8/eric/Helpviewer/QtHelpDocumentationDialog.ui0000644000175000017500000000646212266737272022213 0ustar piotrpiotr QtHelpDocumentationDialog 0 0 425 391 Manage QtHelp Documentation Database true Registered Documents true QAbstractItemView::ExtendedSelection true Press to select QtHelp documents to add to the database Add... Press to remove the selected documents from the database Remove Qt::Vertical 20 98 Qt::Horizontal QDialogButtonBox::Close documentsList addButton removeButton buttonBox buttonBox accepted() QtHelpDocumentationDialog accept() 248 254 157 274 buttonBox rejected() QtHelpDocumentationDialog reject() 316 260 286 274 eric-6.0.8/eric/Helpviewer/SpeedDial/0000755000175000017500000000000012557365360016425 5ustar piotrpiotreric-6.0.8/eric/Helpviewer/SpeedDial/SpeedDialReader.py0000644000175000017500000000776012451233376021760 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a class to read speed dial data files. """ from __future__ import unicode_literals from PyQt5.QtCore import QXmlStreamReader, QIODevice, QFile, QCoreApplication class SpeedDialReader(QXmlStreamReader): """ Class implementing a reader object for speed dial data files. """ def __init__(self): """ Constructor """ super(SpeedDialReader, self).__init__() def read(self, fileNameOrDevice): """ Public method to read a user agent file. @param fileNameOrDevice name of the file to read (string) or reference to the device to read (QIODevice) @return list of speed dial pages (list of Page), number of pages per row (integer) and size of the speed dial pages (integer) """ self.__pages = [] self.__pagesPerRow = 0 self.__sdSize = 0 if isinstance(fileNameOrDevice, QIODevice): self.setDevice(fileNameOrDevice) else: f = QFile(fileNameOrDevice) if not f.exists(): return self.__pages, self.__pagesPerRow, self.__sdSize opened = f.open(QFile.ReadOnly) if not opened: self.raiseError(QCoreApplication.translate( "SpeedDialReader", "The file {0} could not be opened. Error: {1}").format( fileNameOrDevice, f.errorString())) return self.__pages, self.__pagesPerRow, self.__sdSize self.setDevice(f) while not self.atEnd(): self.readNext() if self.isStartElement(): version = self.attributes().value("version") if self.name() == "SpeedDial" and \ (not version or version == "1.0"): self.__readSpeedDial() else: self.raiseError(QCoreApplication.translate( "SpeedDialReader", "The file is not a SpeedDial version 1.0 file.")) return self.__pages, self.__pagesPerRow, self.__sdSize def __readSpeedDial(self): """ Private method to read the speed dial data. """ if not self.isStartElement() and self.name() != "SpeedDial": return while not self.atEnd(): self.readNext() if self.isEndElement(): if self.name() in ["Pages", "Page"]: continue else: break if self.isStartElement(): if self.name() == "Pages": attributes = self.attributes() pagesPerRow = attributes.value("row") if pagesPerRow.isdigit(): self.__pagesPerRow = int(pagesPerRow) sdSize = attributes.value("size") if sdSize.isdigit(): self.__sdSize = int(sdSize) elif self.name() == "Page": attributes = self.attributes() url = attributes.value("url") title = attributes.value("title") if url: if not title: title = url from .Page import Page page = Page(url, title) self.__pages.append(page) else: self.__skipUnknownElement() def __skipUnknownElement(self): """ Private method to skip over all unknown elements. """ if not self.isStartElement(): return while not self.atEnd(): self.readNext() if self.isEndElement(): break if self.isStartElement(): self.__skipUnknownElement() eric-6.0.8/eric/Helpviewer/SpeedDial/Page.py0000644000175000017500000000172312451233376017650 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a structure to hold the data for a speed dial page. """ from __future__ import unicode_literals class Page(object): """ Class to hold the data for a speed dial page. """ def __init__(self, url="", title="", broken=False): """ Constructor @param url URL of the page (string) @param title title of the page (string) @param broken flag indicating a broken connection (boolean) """ self.url = url self.title = title self.broken = broken def __eq__(self, other): """ Special method implementing the equality operator. @param other reference to the other page object (Page) @return flag indicating equality (boolean) """ return self.title == other.title and \ self.url == other.url eric-6.0.8/eric/Helpviewer/SpeedDial/SpeedDialWriter.py0000644000175000017500000000446012451233376022024 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing a class to write speed dial data files. """ from __future__ import unicode_literals from PyQt5.QtCore import QXmlStreamWriter, QIODevice, QFile class SpeedDialWriter(QXmlStreamWriter): """ Class implementing a writer object to generate speed dial data files. """ def __init__(self): """ Constructor """ super(SpeedDialWriter, self).__init__() self.setAutoFormatting(True) def write(self, fileNameOrDevice, pages, pagesPerRow, speedDialSize): """ Public method to write a speed dial data file. @param fileNameOrDevice name of the file to write (string) or device to write to (QIODevice) @param pages list of speed dial pages (list of Page) @param pagesPerRow number of pages per row (integer) @param speedDialSize size of the speed dial pages (integer) @return flag indicating success (boolean) """ if isinstance(fileNameOrDevice, QIODevice): f = fileNameOrDevice else: f = QFile(fileNameOrDevice) if not f.open(QFile.WriteOnly): return False self.setDevice(f) return self.__write(pages, pagesPerRow, speedDialSize) def __write(self, pages, pagesPerRow, speedDialSize): """ Private method to write a speed dial file. @param pages list of speed dial pages (list of Page) @param pagesPerRow number of pages per row (integer) @param speedDialSize size of the speed dial pages (integer) @return flag indicating success (boolean) """ self.writeStartDocument() self.writeDTD("") self.writeStartElement("SpeedDial") self.writeAttribute("version", "1.0") self.writeStartElement("Pages") self.writeAttribute("row", str(pagesPerRow)) self.writeAttribute("size", str(speedDialSize)) for page in pages: self.writeEmptyElement("Page") self.writeAttribute("url", page.url) self.writeAttribute("title", page.title) self.writeEndDocument() return True eric-6.0.8/eric/Helpviewer/SpeedDial/__init__.py0000644000175000017500000000023712451233376020532 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Package implementing the speed dial functionality. """ eric-6.0.8/eric/Helpviewer/SpeedDial/PageThumbnailer.py0000644000175000017500000001001612451233376022036 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing an object to create a thumbnail image of a web site. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, QObject, QSize, Qt, QUrl from PyQt5.QtGui import QPixmap, QImage, QPainter from PyQt5.QtWebKitWidgets import QWebPage from ..Network.NetworkAccessManagerProxy import NetworkAccessManagerProxy class PageThumbnailer(QObject): """ Class implementing a thumbnail creator for web sites. @signal thumbnailCreated(QPixmap) emitted after the thumbnail has been created """ thumbnailCreated = pyqtSignal(QPixmap) def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(PageThumbnailer, self).__init__(parent) self.__page = QWebPage(self) self.__size = QSize(231, 130) self.__loadTitle = False self.__title = "" self.__url = QUrl() self.__proxy = NetworkAccessManagerProxy(self) import Helpviewer.HelpWindow self.__proxy.setPrimaryNetworkAccessManager( Helpviewer.HelpWindow.HelpWindow.networkAccessManager()) self.__page.setNetworkAccessManager(self.__proxy) self.__page.mainFrame().setScrollBarPolicy( Qt.Horizontal, Qt.ScrollBarAlwaysOff) self.__page.mainFrame().setScrollBarPolicy( Qt.Vertical, Qt.ScrollBarAlwaysOff) # Full HD # Every page should fit in this resolution self.__page.setViewportSize(QSize(1920, 1080)) def setSize(self, size): """ Public method to set the size of the image. @param size size of the image (QSize) """ if size.isValid(): self.__size = QSize(size) def setUrl(self, url): """ Public method to set the URL of the site to be thumbnailed. @param url URL of the web site (QUrl) """ if url.isValid(): self.__url = QUrl(url) def url(self): """ Public method to get the URL of the thumbnail. @return URL of the thumbnail (QUrl) """ return QUrl(self.__url) def loadTitle(self): """ Public method to check, if the title is loaded from the web site. @return flag indicating, that the title is loaded (boolean) """ return self.__loadTitle def setLoadTitle(self, load): """ Public method to set a flag indicating to load the title from the web site. @param load flag indicating to load the title (boolean) """ self.__loadTitle = load def title(self): """ Public method to get the title of the thumbnail. @return title of the thumbnail (string) """ return self.__title def start(self): """ Public method to start the thumbnailing action. """ self.__page.loadFinished.connect(self.__createThumbnail) self.__page.mainFrame().load(self.__url) def __createThumbnail(self, status): """ Private slot creating the thumbnail of the web site. @param status flag indicating a successful load of the web site (boolean) """ if not status: self.thumbnailCreated.emit(QPixmap()) return self.__title = self.__page.mainFrame().title() image = QImage(self.__page.viewportSize(), QImage.Format_ARGB32) painter = QPainter(image) self.__page.mainFrame().render(painter) painter.end() scaledImage = image.scaled(self.__size, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) self.thumbnailCreated.emit(QPixmap.fromImage(scaledImage)) eric-6.0.8/eric/Helpviewer/SpeedDial/SpeedDial.py0000644000175000017500000003251412451233376020630 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2015 Detlev Offenbach # """ Module implementing the speed dial. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import os from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QCryptographicHash, \ QByteArray, QUrl, qWarning from PyQt5.QtWebKitWidgets import QWebPage from E5Gui import E5MessageBox from Utilities.AutoSaver import AutoSaver import Utilities class SpeedDial(QObject): """ Class implementing the speed dial. @signal pagesChanged() emitted after the list of pages changed @signal speedDialSaved() emitted after the speed dial data was saved """ pagesChanged = pyqtSignal() speedDialSaved = pyqtSignal() def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super(SpeedDial, self).__init__(parent) self.__regenerateScript = True self.__webPages = [] self.__webFrames = [] self.__initialScript = "" self.__thumbnailsDirectory = "" self.__thumbnailers = [] self.__initialize() self.pagesChanged.connect(self.__pagesChanged) self.__saveTimer = AutoSaver(self, self.save) self.pagesChanged.connect(self.__saveTimer.changeOccurred) def addWebFrame(self, frame): """ Public method to add a web frame. @param frame reference to the frame to be added (QWebFrame) """ if frame not in self.__webFrames: self.__webFrames.append(frame) def addPage(self, url, title): """ Public method to add a page for the given data. @param url URL of the page (QUrl) @param title title of the page (string) """ if url.isEmpty(): return from .Page import Page page = Page(url.toString(), title) self.__webPages.append(page) self.pagesChanged.emit() def removePage(self, url): """ Public method to remove a page. @param url URL of the page (QUrl) """ page = self.pageForUrl(url) if not page.url: return self.removeImageForUrl(page.url) self.__webPages.remove(page) self.pagesChanged.emit() def __imageFileName(self, url): """ Private method to generate the image file name for a URL. @param url URL to generate the file name from (string) @return name of the image file (string) """ return os.path.join( self.__thumbnailsDirectory, str(QCryptographicHash.hash(QByteArray(url.encode("utf-8")), QCryptographicHash.Md5).toHex(), encoding="utf-8") + ".png") def initialScript(self): """ Public method to get the 'initial' JavaScript script. @return initial JavaScript script (string) """ if self.__regenerateScript: self.__regenerateScript = False self.__initialScript = "" for page in self.__webPages: if page.broken: imgSource = "qrc:icons/brokenPage.png" else: imgSource = self.__imageFileName(page.url) if not os.path.exists(imgSource): self.loadThumbnail(page.url) imgSource = "qrc:icons/loading.gif" if not page.url: imgSource = "" else: imgSource = QUrl.fromLocalFile(imgSource).toString() self.__initialScript += \ "addBox('{0}', '{1}', '{2}');\n".format( page.url, Utilities.html_uencode(page.title), imgSource) return self.__initialScript def getFileName(self): """ Public method to get the file name of the user agents file. @return name of the user agents file (string) """ return os.path.join( Utilities.getConfigDir(), "browser", "speedDial.xml") def __initialize(self): """ Private method to initialize the speed dial. """ self.__thumbnailsDirectory = os.path.join( Utilities.getConfigDir(), "browser", "thumbnails") # Create directory if it does not exist yet if not os.path.exists(self.__thumbnailsDirectory): os.makedirs(self.__thumbnailsDirectory) self.__load() def reload(self): """ Public method to reload the speed dial data. """ self.__load() def __load(self): """ Private method to load the speed dial configuration. """ allPages, pagesPerRow, speedDialSize = [], 0, 0 speedDialFile = self.getFileName() if os.path.exists(speedDialFile): from .SpeedDialReader import SpeedDialReader reader = SpeedDialReader() allPages, pagesPerRow, speedDialSize = reader.read(speedDialFile) self.__pagesPerRow = pagesPerRow if pagesPerRow else 4 self.__speedDialSize = speedDialSize if speedDialSize else 231 if allPages: self.__webPages = allPages self.pagesChanged.emit() else: allPages = \ 'url:"http://eric-ide.python-projects.org/"|'\ 'title:"Eric Web Site";'\ 'url:"http://www.riverbankcomputing.com/"|'\ 'title:"PyQt Web Site";'\ 'url:"http://www.qt.io/"|title:"Qt Web Site";'\ 'url:"http://blog.qt.digia.com/"|title:"Qt Blog";'\ 'url:"http://www.python.org"|title:"Python Language Website";'\ 'url:"http://www.google.com"|title:"Google";' self.changed(allPages) def save(self): """ Public method to save the speed dial configuration. """ from .SpeedDialWriter import SpeedDialWriter speedDialFile = self.getFileName() writer = SpeedDialWriter() if not writer.write(speedDialFile, self.__webPages, self.__pagesPerRow, self.__speedDialSize): E5MessageBox.critical( None, self.tr("Saving Speed Dial data"), self.tr( """

    Speed Dial data could not be saved to""" """ {0}

    """).format(speedDialFile)) else: self.speedDialSaved.emit() def close(self): """ Public method to close the user agents manager. """ self.__saveTimer.saveIfNeccessary() def pageForUrl(self, url): """ Public method to get the page for the given URL. @param url URL to be searched for (QUrl) @return page for the URL (Page) """ urlString = url.toString() for page in self.__webPages: if page.url == urlString: return page from .Page import Page return Page() def urlForShortcut(self, key): """ Public method to get the URL for the given shortcut key. @param key shortcut key (integer) @return URL for the key (QUrl) """ if key < 0 or len(self.__webPages) <= key: return QUrl() return QUrl.fromEncoded(self.__webPages[key].url.encode("utf-8")) @pyqtSlot(str) def changed(self, allPages): """ Public slot to react on changed pages. @param allPages string giving all pages (string) """ if not allPages: return entries = allPages.split('";') self.__webPages = [] from .Page import Page for entry in entries: if not entry: continue tmp = entry.split('"|') if len(tmp) == 2: broken = False elif len(tmp) == 3: broken = "brokenPage" in tmp[2][5:] else: continue page = Page(tmp[0][5:], tmp[1][7:], broken) self.__webPages.append(page) self.pagesChanged.emit() @pyqtSlot(str) @pyqtSlot(str, bool) def loadThumbnail(self, url, loadTitle=False): """ Public slot to load a thumbnail of the given URL. @param url URL of the thumbnail (string) @param loadTitle flag indicating to get the title for the thumbnail from the site (boolean) """ if not url: return from .PageThumbnailer import PageThumbnailer thumbnailer = PageThumbnailer(self) thumbnailer.setUrl(QUrl.fromEncoded(url.encode("utf-8"))) thumbnailer.setLoadTitle(loadTitle) thumbnailer.thumbnailCreated.connect(self.__thumbnailCreated) self.__thumbnailers.append(thumbnailer) thumbnailer.start() @pyqtSlot(str) def removeImageForUrl(self, url): """ Public slot to remove the image for a URL. @param url URL to remove the image for (string) """ fileName = self.__imageFileName(url) if os.path.exists(fileName): os.remove(fileName) @pyqtSlot(str, result=str) def urlFromUserInput(self, url): """ Public slot to get the URL from user input. @param url URL entered by the user (string) @return sanitized URL (string) """ return QUrl.fromUserInput(url).toString() @pyqtSlot(str, result=str) def unescapeTitle(self, title): """ Public slot to unescape the titel string. @param title escaped title (string) @return un-escaped title (string) """ return Utilities.html_udecode(title) @pyqtSlot(int) def setPagesInRow(self, count): """ Public slot to set the number of pages per row. @param count number of pages per row (integer) """ self.__pagesPerRow = count self.__saveTimer.changeOccurred() def pagesInRow(self): """ Public method to get the number of dials per row. @return number of dials per row (integer) """ return self.__pagesPerRow @pyqtSlot(int) def setSdSize(self, size): """ Public slot to set the size of the speed dial. @param size size of the speed dial (integer) """ self.__speedDialSize = size self.__saveTimer.changeOccurred() def sdSize(self): """ Public method to get the speed dial size. @return speed dial size (integer) """ return self.__speedDialSize def __thumbnailCreated(self, image): """ Private slot to handle the creation of a thumbnail image. @param image thumbnail image (QPixmap) """ from .PageThumbnailer import PageThumbnailer thumbnailer = self.sender() if not isinstance(thumbnailer, PageThumbnailer) or \ thumbnailer not in self.__thumbnailers: return loadTitle = thumbnailer.loadTitle() title = thumbnailer.title() url = thumbnailer.url().toString() fileName = self.__imageFileName(url) if image.isNull(): fileName = "qrc:icons/brokenPage.png" title = self.tr("Unable to load") loadTitle = True page = self.pageForUrl(thumbnailer.url()) page.broken = True else: if not image.save(fileName): qWarning( "SpeedDial.__thumbnailCreated: Cannot save thumbnail" " to {0}".format(fileName)) fileName = QUrl.fromLocalFile(fileName).toString() self.__regenerateScript = True for frame in self.__cleanFrames(): frame.evaluateJavaScript("setImageToUrl('{0}', '{1}');".format( url, fileName)) if loadTitle: frame.evaluateJavaScript("setTitleToUrl('{0}', '{1}');".format( url, Utilities.html_uencode(title))) thumbnailer.deleteLater() self.__thumbnailers.remove(thumbnailer) def __cleanFrames(self): """ Private method to clean all frames. @return list of speed dial frames (list of QWebFrame) """ frames = [] for frame in self.__webFrames[:]: if frame.url().toString() == "eric:speeddial": frames.append(frame) else: self.__webFrames.remove(frame) return frames def __pagesChanged(self): """ Private slot to react on a change of the pages configuration. """ # update all speed dial pages self.__regenerateScript = True for frame in self.__cleanFrames(): frame.page().triggerAction(QWebPage.Reload) eric-6.0.8/eric/Helpviewer/SearchWidget.ui0000644000175000017500000000576512354033425017505 0ustar piotrpiotr SearchWidget 0 0 718 25 Find 0 Press to close the window Find: 0 0 true QComboBox::InsertAtTop false Press to find the previous occurrence Press to find the next occurrence Match case Wrap around Highlight all Qt::Vertical 200 0 findtextCombo caseCheckBox wrapCheckBox highlightAllCheckBox findNextButton findPrevButton closeButton eric-6.0.8/eric/Helpviewer/HelpIndexWidget.py0000644000175000017500000001571312451233376020172 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2009 - 2015 Detlev Offenbach # """ Module implementing a window for showing the QtHelp index. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, Qt, QUrl, QEvent from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QMenu, \ QDialog class HelpIndexWidget(QWidget): """ Class implementing a window for showing the QtHelp index. @signal linkActivated(QUrl) emitted when an index entry is activated @signal linksActivated(links, keyword) emitted when an index entry referencing multiple targets is activated @signal escapePressed() emitted when the ESC key was pressed """ linkActivated = pyqtSignal(QUrl) linksActivated = pyqtSignal(dict, str) escapePressed = pyqtSignal() def __init__(self, engine, mainWindow, parent=None): """ Constructor @param engine reference to the help engine (QHelpEngine) @param mainWindow reference to the main window object (QMainWindow) @param parent reference to the parent widget (QWidget) """ super(HelpIndexWidget, self).__init__(parent) self.__engine = engine self.__mw = mainWindow self.__searchEdit = None self.__index = None self.__layout = QVBoxLayout(self) label = QLabel(self.tr("&Look for:")) self.__layout.addWidget(label) self.__searchEdit = QLineEdit() label.setBuddy(self.__searchEdit) self.__searchEdit.textChanged.connect(self.__filterIndices) self.__searchEdit.installEventFilter(self) self.__layout.addWidget(self.__searchEdit) self.__index = self.__engine.indexWidget() self.__index.installEventFilter(self) self.__engine.indexModel().indexCreationStarted.connect( self.__disableSearchEdit) self.__engine.indexModel().indexCreated.connect( self.__enableSearchEdit) self.__index.activated.connect(self.__activated) self.__searchEdit.returnPressed.connect( self.__index.activateCurrentItem) self.__layout.addWidget(self.__index) self.__index.viewport().installEventFilter(self) def __activated(self, idx): """ Private slot to handle the activation of a keyword entry. @param idx index of the activated entry (QModelIndex) """ model = self.__index.model() if model is not None: keyword = model.data(idx, Qt.DisplayRole) links = model.linksForKeyword(keyword) if len(links) == 1: self.linkActivated.emit(QUrl(links[list(links.keys())[0]])) else: self.linksActivated.emit(links, keyword) def __filterIndices(self, filter): """ Private slot to filter the indices according to the given filter. @param filter filter to be used (string) """ if '*' in filter: self.__index.filterIndices(filter, filter) else: self.__index.filterIndices(filter) def __enableSearchEdit(self): """ Private slot to enable the search edit. """ self.__searchEdit.setEnabled(True) self.__filterIndices(self.__searchEdit.text()) def __disableSearchEdit(self): """ Private slot to enable the search edit. """ self.__searchEdit.setEnabled(False) def focusInEvent(self, evt): """ Protected method handling focus in events. @param evt reference to the focus event object (QFocusEvent) """ if evt.reason() != Qt.MouseFocusReason: self.__searchEdit.selectAll() self.__searchEdit.setFocus() def eventFilter(self, watched, event): """ Public method called to filter the event queue. @param watched the QObject being watched (QObject) @param event the event that occurred (QEvent) @return flag indicating whether the event was handled (boolean) """ if self.__searchEdit and watched == self.__searchEdit and \ event.type() == QEvent.KeyPress: idx = self.__index.currentIndex() if event.key() == Qt.Key_Up: idx = self.__index.model().index( idx.row() - 1, idx.column(), idx.parent()) if idx.isValid(): self.__index.setCurrentIndex(idx) elif event.key() == Qt.Key_Down: idx = self.__index.model().index( idx.row() + 1, idx.column(), idx.parent()) if idx.isValid(): self.__index.setCurrentIndex(idx) elif event.key() == Qt.Key_Escape: self.escapePressed.emit() elif self.__index and watched == self.__index and \ event.type() == QEvent.ContextMenu: idx = self.__index.indexAt(event.pos()) if idx.isValid(): menu = QMenu() curTab = menu.addAction(self.tr("Open Link")) newTab = menu.addAction(self.tr("Open Link in New Tab")) menu.move(self.__index.mapToGlobal(event.pos())) act = menu.exec_() if act == curTab: self.__activated(idx) elif act == newTab: model = self.__index.model() if model is not None: keyword = model.data(idx, Qt.DisplayRole) links = model.linksForKeyword(keyword) if len(links) == 1: self.__mw.newTab(list(links.values())[0]) elif len(links) > 1: from .HelpTopicDialog import HelpTopicDialog dlg = HelpTopicDialog(self, keyword, links) if dlg.exec_() == QDialog.Accepted: self.__mw.newTab(dlg.link()) elif self.__index and watched == self.__index.viewport() and \ event.type() == QEvent.MouseButtonRelease: idx = self.__index.indexAt(event.pos()) if idx.isValid() and event.button() == Qt.MidButton: model = self.__index.model() if model is not None: keyword = model.data(idx, Qt.DisplayRole) links = model.linksForKeyword(keyword) if len(links) == 1: self.__mw.newTab(list(links.values())[0]) elif len(links) > 1: from .HelpTopicDialog import HelpTopicDialog dlg = HelpTopicDialog(self, keyword, links) if dlg.exec_() == QDialog.Accepted: self.__mw.newTab(dlg.link()) return QWidget.eventFilter(self, watched, event) eric-6.0.8/eric/Helpviewer/HelpBrowserWV.py0000644000175000017500000026471412554466772017702 0ustar piotrpiotr# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2015 Detlev Offenbach # """ Module implementing the helpbrowser using QWebView. """ from __future__ import unicode_literals try: str = unicode except NameError: pass from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QT_TRANSLATE_NOOP, \ QUrl, QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, \ QRect, QFile, QPoint, QByteArray, qVersion from PyQt5.QtGui import QDesktopServices, QClipboard, QMouseEvent, QColor, \ QPalette from PyQt5.QtWidgets import qApp, QStyle, QMenu, QApplication, QInputDialog, \ QLineEdit, QLabel, QToolTip, QFrame, QDialog from PyQt5.QtPrintSupport import QPrinter, QPrintDialog from PyQt5.QtWebKit import QWebSettings from PyQt5.QtWebKitWidgets import QWebView, QWebPage try: from PyQt5.QtWebKit import QWebElement except ImportError: pass from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest import sip from E5Gui import E5MessageBox, E5FileDialog import Preferences import UI.PixmapCache import Globals try: from PyQt5.QtNetwork import QSslCertificate SSL_AVAILABLE = True except ImportError: SSL_AVAILABLE = False ############################################################################### class JavaScriptExternalObject(QObject): """ Class implementing an external javascript object to add search providers. """ def __init__(self, mw, parent=None): """ Constructor @param mw reference to the main window 8HelpWindow) @param parent reference to the parent object (QObject) """ super(JavaScriptExternalObject, self).__init__(parent) self.__mw = mw @pyqtSlot(str) def AddSearchProvider(self, url): """ Public slot to add a search provider. @param url url of the XML file defining the search provider (string) """ self.__mw.openSearchManager().addEngine(QUrl(url)) class LinkedResource(object): """ Class defining a data structure for linked resources. """ def __init__(self): """ Constructor """ self.rel = "" self.type_ = "" self.href = "" self.title = "" ############################################################################### class JavaScriptEricObject(QObject): """ Class implementing an external javascript object to search via the startpage. """ # these must be in line with the strings used by the javascript part of # the start page translations = [ QT_TRANSLATE_NOOP("JavaScriptEricObject", "Welcome to eric6 Web Browser!"), QT_TRANSLATE_NOOP("JavaScriptEricObject", "eric6 Web Browser"), QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"), QT_TRANSLATE_NOOP("JavaScriptEricObject", "About eric6"), ] def __init__(self, mw, parent=None): """ Constructor @param mw reference to the main window 8HelpWindow) @param parent reference to the parent object (QObject) """ super(JavaScriptEricObject, self).__init__(parent) self.__mw = mw @pyqtSlot(str, result=str) def translate(self, trans): """ Public method to translate the given string. @param trans string to be translated (string) @return translation (string) """ if trans == "QT_LAYOUT_DIRECTION": # special handling to detect layout direction if qApp.isLeftToRight(): return "LTR" else: return "RTL" return self.tr(trans) @pyqtSlot(result=str) def providerString(self): """ Public method to get a string for the search provider. @return string for the search provider (string) """ return self.tr("Search results provided by {0}")\ .format(self.__mw.openSearchManager().currentEngineName()) @pyqtSlot(str, result=str) def searchUrl(self, searchStr): """ Public method to get the search URL for the given search term. @param searchStr search term (string) @return search URL (string) """ return bytes( self.__mw.openSearchManager().currentEngine() .searchUrl(searchStr).toEncoded()).decode() ############################################################################### class HelpWebPage(QWebPage): """ Class implementing an enhanced web page. """ _webPluginFactory = None def __init__(self, parent=None): """ Constructor @param parent parent widget of this window (QWidget) """ super(HelpWebPage, self).__init__(parent) self.setPluginFactory(self.webPluginFactory()) self.__lastRequest = None self.__lastRequestType = QWebPage.NavigationTypeOther import Helpviewer.HelpWindow from .Network.NetworkAccessManagerProxy import \ NetworkAccessManagerProxy self.__proxy = NetworkAccessManagerProxy(self) self.__proxy.setWebPage(self) self.__proxy.setPrimaryNetworkAccessManager( Helpviewer.HelpWindow.HelpWindow.networkAccessManager()) self.setNetworkAccessManager(self.__proxy) self.__sslConfiguration = None self.__proxy.finished.connect(self.__managerFinished) self.__adBlockedEntries = [] self.loadStarted.connect(self.__loadStarted) def acceptNavigationRequest(self, frame, request, type_): """ Public method to determine, if a request may be accepted. @param frame reference to the frame sending the request (QWebFrame) @param request reference to the request object (QNetworkRequest) @param type_ type of the navigation request (QWebPage.NavigationType) @return flag indicating acceptance (boolean) """ self.__lastRequest = request if self.__lastRequest.url() != request.url() or \ type_ != QWebPage.NavigationTypeOther: self.__lastRequestType = type_ scheme = request.url().scheme() if scheme == "mailto": QDesktopServices.openUrl(request.url()) return False if type_ == QWebPage.NavigationTypeFormResubmitted: res = E5MessageBox.yesNo( self.view(), self.tr("Resending POST request"), self.tr( """In order to display the site, the request along with""" """ all the data must be sent once again, which may lead""" """ to some unexpected behaviour of the site e.g. the""" """ same action might be performed once again. Do you""" """ want to continue anyway?"""), icon=E5MessageBox.Warning) if not res: return False return QWebPage.acceptNavigationRequest(self, frame, request, type_) def populateNetworkRequest(self, request): """ Public method to add data to a network request. @param request reference to the network request object (QNetworkRequest) """ try: request.setAttribute(QNetworkRequest.User + 100, self) if self.__lastRequest.url() == request.url(): request.setAttribute(QNetworkRequest.User + 101, self.__lastRequestType) if self.__lastRequestType == \ QWebPage.NavigationTypeLinkClicked: request.setRawHeader(b"X-Eric6-UserLoadAction", QByteArray(b"1")) except TypeError: pass def pageAttributeId(self): """ Public method to get the attribute id of the page attribute. @return attribute id of the page attribute (integer) """ return QNetworkRequest.User + 100 def supportsExtension(self, extension): """ Public method to check the support for an extension. @param extension extension to test for (QWebPage.Extension) @return flag indicating the support of extension (boolean) """ try: if extension in [QWebPage.ErrorPageExtension, QWebPage.ChooseMultipleFilesExtension]: return True except AttributeError: pass return QWebPage.supportsExtension(self, extension) def extension(self, extension, option, output): """ Public method to implement a specific extension. @param extension extension to be executed (QWebPage.Extension) @param option provides input to the extension (QWebPage.ExtensionOption) @param output stores the output results (QWebPage.ExtensionReturn) @return flag indicating a successful call of the extension (boolean) """ if extension == QWebPage.ChooseMultipleFilesExtension: info = sip.cast(option, QWebPage.ChooseMultipleFilesExtensionOption) files = sip.cast(output, QWebPage.ChooseMultipleFilesExtensionReturn) if info is None or files is None: return super(HelpWebPage, self).extension( extension, option, output) suggestedFileName = "" if info.suggestedFileNames: suggestedFileName = info.suggestedFileNames[0] files.fileNames = E5FileDialog.getOpenFileNames( None, self.tr("Select files to upload..."), suggestedFileName) return True if extension == QWebPage.ErrorPageExtension: info = sip.cast(option, QWebPage.ErrorPageExtensionOption) errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn) urlString = bytes(info.url.toEncoded()).decode() errorPage.baseUrl = info.url if info.domain == QWebPage.QtNetwork and \ info.error == QNetworkReply.ContentAccessDenied and \ info.errorString.startswith("AdBlockRule:"): if info.frame != info.frame.page().mainFrame(): # content in
  • ReStructuredText preview requires the""" """ python-docutils package.
    Install it with""" """ your package manager or see""" """
    """ """this page.